From 6710073263c6f85acc8dd369f9c8ce4cd8fe5d3c Mon Sep 17 00:00:00 2001 From: zerob13 Date: Mon, 24 Nov 2025 13:47:02 +0800 Subject: [PATCH 1/2] fix: acp process env --- .../agent/acpProcessManager.ts | 173 +++++++----------- 1 file changed, 70 insertions(+), 103 deletions(-) diff --git a/src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts b/src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts index d76bfff11..b9d6b07d6 100644 --- a/src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts +++ b/src/main/presenter/llmProviderPresenter/agent/acpProcessManager.ts @@ -266,125 +266,92 @@ export class AcpProcessManager implements AgentProcessManager typeof arg === 'string' && arg.includes(cmd)) ) - // Define allowed environment variables whitelist for Node.js/UV commands - const allowedEnvVars = [ - 'PATH', - 'path', - 'Path', - 'npm_config_registry', - 'npm_config_cache', - 'npm_config_prefix', - 'npm_config_tmp', - 'NPM_CONFIG_REGISTRY', - 'NPM_CONFIG_CACHE', - 'NPM_CONFIG_PREFIX', - 'NPM_CONFIG_TMP', - 'ANTHROPIC_BASE_URL', - 'ANTHROPIC_AUTH_TOKEN', - 'ANTHROPIC_MODEL', - 'OPENAI_BASE_URL', - 'OPENAI_API_KEY' - ] - const HOME_DIR = app.getPath('home') const env: Record = {} + Object.entries(process.env).forEach(([key, value]) => { + if (value !== undefined && value !== '') { + env[key] = value + } + }) let pathKey = process.platform === 'win32' ? 'Path' : 'PATH' let pathValue = '' if (isNodeCommand) { - // Node.js/UV commands use whitelist processing - if (process.env) { - const existingPaths: string[] = [] - - // Collect all PATH-related values - Object.entries(process.env).forEach(([key, value]) => { - if (value !== undefined && value !== '') { - if (['PATH', 'Path', 'path'].includes(key)) { - existingPaths.push(value) - } else if (allowedEnvVars.includes(key) && !['PATH', 'Path', 'path'].includes(key)) { - env[key] = value - } + // Node.js/UV commands need full environment propagation similar to ACP init + const existingPaths: string[] = [] + const pathKeys = ['PATH', 'Path', 'path'] + pathKeys.forEach((key) => { + const value = env[key] + if (value) { + existingPaths.push(value) + } + }) + + // Get shell environment variables regardless of runtime choice + let shellEnv: Record = {} + try { + shellEnv = await getShellEnvironment() + console.info(`[ACP] Retrieved shell environment variables for agent ${agent.id}`) + Object.entries(shellEnv).forEach(([key, value]) => { + if (value !== undefined && value !== '' && !pathKeys.includes(key)) { + env[key] = value } }) + } catch (error) { + console.warn( + `[ACP] Failed to get shell environment variables for agent ${agent.id}, using fallback:`, + error + ) + } - // Get shell environment variables when not using builtin runtime - // This ensures nvm/n/fnm/volta paths are available - let shellEnv: Record = {} - if (!useBuiltinRuntime) { - try { - shellEnv = await getShellEnvironment() - console.info(`[ACP] Retrieved shell environment variables for agent ${agent.id}`) - - // Merge shell environment variables (except PATH which we handle separately) - Object.entries(shellEnv).forEach(([key, value]) => { - if (!['PATH', 'Path', 'path'].includes(key) && value) { - env[key] = value - } - }) - } catch (error) { - console.warn( - `[ACP] Failed to get shell environment variables for agent ${agent.id}, using fallback:`, - error - ) - } - } + // Get shell PATH if available (priority: shell PATH > existing PATH) + const shellPath = shellEnv.PATH || shellEnv.Path || shellEnv.path + if (shellPath) { + const shellPaths = shellPath.split(process.platform === 'win32' ? ';' : ':') + existingPaths.unshift(...shellPaths) + console.info(`[ACP] Using shell PATH for agent ${agent.id} (length: ${shellPath.length})`) + } - // Get shell PATH if available (priority: shell PATH > existing PATH) - const shellPath = shellEnv.PATH || shellEnv.Path - if (shellPath) { - // Use shell PATH as base, then merge existing paths - const shellPaths = shellPath.split(process.platform === 'win32' ? ';' : ':') - existingPaths.unshift(...shellPaths) - console.info(`[ACP] Using shell PATH for agent ${agent.id} (length: ${shellPath.length})`) - } + // Get default paths + const defaultPaths = this.runtimeHelper.getDefaultPaths(HOME_DIR) - // Get default paths - const defaultPaths = this.runtimeHelper.getDefaultPaths(HOME_DIR) - - // Merge all paths (priority: shell PATH > existing PATH > default paths) - const allPaths = [...existingPaths, ...defaultPaths] - // Add runtime paths only when using builtin runtime - if (useBuiltinRuntime) { - const uvRuntimePath = this.runtimeHelper.getUvRuntimePath() - const nodeRuntimePath = this.runtimeHelper.getNodeRuntimePath() - if (process.platform === 'win32') { - // Windows platform only adds node and uv paths - if (uvRuntimePath) { - allPaths.unshift(uvRuntimePath) - console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`) - } - if (nodeRuntimePath) { - allPaths.unshift(nodeRuntimePath) - console.info(`[ACP] Added Node runtime path to PATH: ${nodeRuntimePath}`) - } - } else { - // Other platforms priority: node > uv - if (uvRuntimePath) { - allPaths.unshift(uvRuntimePath) - console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`) - } - if (nodeRuntimePath) { - const nodeBinPath = path.join(nodeRuntimePath, 'bin') - allPaths.unshift(nodeBinPath) - console.info(`[ACP] Added Node bin path to PATH: ${nodeBinPath}`) - } + // Merge all paths (priority: shell PATH > existing PATH > default paths) + const allPaths = [...existingPaths, ...defaultPaths] + // Add runtime paths only when using builtin runtime + if (useBuiltinRuntime) { + const uvRuntimePath = this.runtimeHelper.getUvRuntimePath() + const nodeRuntimePath = this.runtimeHelper.getNodeRuntimePath() + if (process.platform === 'win32') { + // Windows platform only adds node and uv paths + if (uvRuntimePath) { + allPaths.unshift(uvRuntimePath) + console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`) + } + if (nodeRuntimePath) { + allPaths.unshift(nodeRuntimePath) + console.info(`[ACP] Added Node runtime path to PATH: ${nodeRuntimePath}`) + } + } else { + // Other platforms priority: node > uv + if (uvRuntimePath) { + allPaths.unshift(uvRuntimePath) + console.info(`[ACP] Added UV runtime path to PATH: ${uvRuntimePath}`) + } + if (nodeRuntimePath) { + const nodeBinPath = path.join(nodeRuntimePath, 'bin') + allPaths.unshift(nodeBinPath) + console.info(`[ACP] Added Node bin path to PATH: ${nodeBinPath}`) } } - - // Normalize and set PATH - const normalized = this.runtimeHelper.normalizePathEnv(allPaths) - pathKey = normalized.key - pathValue = normalized.value - env[pathKey] = pathValue } + + // Normalize and set PATH + const normalized = this.runtimeHelper.normalizePathEnv(allPaths) + pathKey = normalized.key + pathValue = normalized.value + env[pathKey] = pathValue } else { // Non Node.js/UV commands, preserve all system environment variables, only supplement PATH - Object.entries(process.env).forEach(([key, value]) => { - if (value !== undefined && value !== '') { - env[key] = value - } - }) - // Supplement PATH const existingPaths: string[] = [] if (env.PATH) { From 2686e428702f0f1f7485874430210dc8501f91a4 Mon Sep 17 00:00:00 2001 From: zerob13 Date: Mon, 24 Nov 2025 15:12:00 +0800 Subject: [PATCH 2/2] fix: react artifact failed after build #1116 --- electron-builder-macx64.yml | 3 +++ electron-builder.yml | 3 +++ src/renderer/src/components/artifacts/ReactArtifact.vue | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/electron-builder-macx64.yml b/electron-builder-macx64.yml index e69609be5..7f8361d4f 100644 --- a/electron-builder-macx64.yml +++ b/electron-builder-macx64.yml @@ -29,6 +29,9 @@ extraResources: - from: ./runtime/ to: app.asar.unpacked/runtime filter: ['**/*'] + - from: ./resources/cdn/ + to: app.asar.unpacked/resources/cdn + filter: ['**/*'] afterSign: scripts/notarize.js afterPack: scripts/afterPack.js electronLanguages: diff --git a/electron-builder.yml b/electron-builder.yml index ca9cc6c4d..dbe445af4 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -30,6 +30,9 @@ extraResources: - from: ./runtime/ to: app.asar.unpacked/runtime filter: ['**/*'] + - from: ./resources/cdn/ + to: app.asar.unpacked/resources/cdn + filter: ['**/*'] electronLanguages: - zh-CN - zh-TW diff --git a/src/renderer/src/components/artifacts/ReactArtifact.vue b/src/renderer/src/components/artifacts/ReactArtifact.vue index 1d5f9a5f5..8e04f95ae 100644 --- a/src/renderer/src/components/artifacts/ReactArtifact.vue +++ b/src/renderer/src/components/artifacts/ReactArtifact.vue @@ -4,7 +4,7 @@ ref="iframeRef" :srcdoc="htmlContent" class="w-full h-full min-h-[400px] html-iframe-wrapper" - sandbox="allow-scripts allow-same-origin" + sandbox="allow-scripts" >