feat: enhance environment path handling with buildAugmentedPath function

This commit is contained in:
Bohdan Triapitsyn
2026-01-08 19:33:43 +02:00
parent 04d6a2b2bf
commit b9ed2217a6
3 changed files with 24 additions and 7 deletions
+7 -1
View File
@@ -1,7 +1,7 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import * as os from 'os'; import * as os from 'os';
import * as path from 'path'; import * as path from 'path';
import type { OpenCodeManager } from './opencode'; import { buildAugmentedPath, type OpenCodeManager } from './opencode';
import { createAgent, createCommand, deleteAgent, deleteCommand, getAgentSources, getCommandSources, updateAgent, updateCommand, type AgentScope, type CommandScope, AGENT_SCOPE, COMMAND_SCOPE, discoverSkills, getSkillSources, createSkill, updateSkill, deleteSkill, readSkillSupportingFile, writeSkillSupportingFile, deleteSkillSupportingFile, type SkillScope, SKILL_SCOPE } from './opencodeConfig'; import { createAgent, createCommand, deleteAgent, deleteCommand, getAgentSources, getCommandSources, updateAgent, updateCommand, type AgentScope, type CommandScope, AGENT_SCOPE, COMMAND_SCOPE, discoverSkills, getSkillSources, createSkill, updateSkill, deleteSkill, readSkillSupportingFile, writeSkillSupportingFile, deleteSkillSupportingFile, type SkillScope, SKILL_SCOPE } from './opencodeConfig';
import { removeProviderAuth } from './opencodeAuth'; import { removeProviderAuth } from './opencodeAuth';
import * as gitService from './gitService'; import * as gitService from './gitService';
@@ -602,6 +602,11 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
const shell = process.env.SHELL || (process.platform === 'win32' ? 'cmd.exe' : '/bin/sh'); const shell = process.env.SHELL || (process.platform === 'win32' ? 'cmd.exe' : '/bin/sh');
const shellFlag = process.platform === 'win32' ? '/c' : '-c'; const shellFlag = process.platform === 'win32' ? '/c' : '-c';
const augmentedEnv = {
...process.env,
PATH: buildAugmentedPath(),
};
const results: Array<{ const results: Array<{
command: string; command: string;
success: boolean; success: boolean;
@@ -620,6 +625,7 @@ export async function handleBridgeMessage(message: BridgeRequest, ctx?: BridgeCo
// Use async exec to not block the extension host event loop // Use async exec to not block the extension host event loop
const { stdout, stderr } = await execAsync(`${shell} ${shellFlag} "${cmd.replace(/"/g, '\\"')}"`, { const { stdout, stderr } = await execAsync(`${shell} ${shellFlag} "${cmd.replace(/"/g, '\\"')}"`, {
cwd: resolvedCwd, cwd: resolvedCwd,
env: augmentedEnv,
timeout: 300000, // 5 minutes per command timeout: 300000, // 5 minutes per command
}); });
results.push({ results.push({
+1 -1
View File
@@ -126,7 +126,7 @@ function getLoginShellPath(): string | null {
return null; return null;
} }
function buildAugmentedPath(): string { export function buildAugmentedPath(): string {
const augmented = new Set<string>(); const augmented = new Set<string>();
const loginPath = getLoginShellPath(); const loginPath = getLoginShellPath();
+16 -5
View File
@@ -989,18 +989,21 @@ function resolveBinaryFromPath(binaryName, searchPath) {
} }
function getOpencodeSpawnConfig() { function getOpencodeSpawnConfig() {
const envPath = buildAugmentedPath();
const resolvedEnv = { ...process.env, PATH: envPath };
if (OPENCODE_BINARY_ENV) { if (OPENCODE_BINARY_ENV) {
const explicit = resolveBinaryFromPath(OPENCODE_BINARY_ENV, process.env.PATH); const explicit = resolveBinaryFromPath(OPENCODE_BINARY_ENV, envPath);
if (explicit) { if (explicit) {
console.log(`Using OpenCode binary from OPENCODE_BINARY: ${explicit}`); console.log(`Using OpenCode binary from OPENCODE_BINARY: ${explicit}`);
return { command: explicit, env: undefined }; return { command: explicit, env: resolvedEnv };
} }
console.warn( console.warn(
`OPENCODE_BINARY path "${OPENCODE_BINARY_ENV}" not found. Falling back to search.` `OPENCODE_BINARY path "${OPENCODE_BINARY_ENV}" not found. Falling back to search.`
); );
} }
return { command: 'opencode', env: undefined }; return { command: 'opencode', env: resolvedEnv };
} }
const ENV_CONFIGURED_OPENCODE_PORT = (() => { const ENV_CONFIGURED_OPENCODE_PORT = (() => {
@@ -4127,7 +4130,12 @@ async function main(options = {}) {
// NOTE: This route supports background execution to avoid tying up browser connections. // NOTE: This route supports background execution to avoid tying up browser connections.
const execJobs = new Map(); const execJobs = new Map();
const EXEC_JOB_TTL_MS = 30 * 60 * 1000; const EXEC_JOB_TTL_MS = 30 * 60 * 1000;
const COMMAND_TIMEOUT_MS = 60000; const COMMAND_TIMEOUT_MS = (() => {
const raw = Number(process.env.OPENCHAMBER_FS_EXEC_TIMEOUT_MS);
if (Number.isFinite(raw) && raw > 0) return raw;
// `bun install` (common worktree setup cmd) often takes >60s.
return 5 * 60 * 1000;
})();
const pruneExecJobs = () => { const pruneExecJobs = () => {
const now = Date.now(); const now = Date.now();
@@ -4149,9 +4157,12 @@ async function main(options = {}) {
let stderr = ''; let stderr = '';
let timedOut = false; let timedOut = false;
const envPath = buildAugmentedPath();
const execEnv = { ...process.env, PATH: envPath };
const child = spawn(shell, [shellFlag, command], { const child = spawn(shell, [shellFlag, command], {
cwd: resolvedCwd, cwd: resolvedCwd,
env: process.env, env: execEnv,
stdio: ['ignore', 'pipe', 'pipe'], stdio: ['ignore', 'pipe', 'pipe'],
}); });