🐛 fix(vscode): GUI 下解析 claude 绝对路径(含 ~/.local/bin 官方安装)
This commit is contained in:
@@ -19,6 +19,8 @@
|
||||
*/
|
||||
|
||||
import { spawn } from 'node:child_process'
|
||||
import * as path from 'node:path'
|
||||
import { resolveClaudeBin } from './claudeBin'
|
||||
|
||||
const DEFAULT_TIMEOUT_MS = 300_000
|
||||
const MAX_BUFFER_BYTES = 10 * 1024 * 1024
|
||||
@@ -206,7 +208,9 @@ function buildStreamJsonLine(prompt: string, images: ClaudeImage[]): string {
|
||||
* - CLAUDECODE / CLAUDE_CODE_ENTRYPOINT / CLAUDE_CODE_SESSION_ID / CLAUDE_CODE_SESSION:
|
||||
* 从父 Claude 会话继承会让子进程当成嵌套会话直接静默退出、零输出。
|
||||
*/
|
||||
function buildClaudeChildEnv(): NodeJS.ProcessEnv {
|
||||
const CLAUDE_MISSING_MSG = '未检测到 claude CLI,请确认已安装并在 PATH 中(常见位置 ~/.local/bin)'
|
||||
|
||||
function buildClaudeChildEnv(bin?: string): NodeJS.ProcessEnv {
|
||||
// 剔除所有 ANTHROPIC_* 是为了让 `--settings` profile 成为 provider/鉴权的唯一来源
|
||||
// (profile 没配则回落 ~/.claude 订阅 OAuth),避免宿主 env 残留的 BASE_URL/TOKEN
|
||||
// 覆盖 profile 导致 403。同时清除嵌套 Claude 会话标记,避免后台 `claude -p` 误判处于嵌套会话。
|
||||
@@ -224,6 +228,12 @@ function buildClaudeChildEnv(): NodeJS.ProcessEnv {
|
||||
continue
|
||||
out[k] = v
|
||||
}
|
||||
// claude 再 spawn 子工具时仍要能找到自己所在目录
|
||||
if (bin) {
|
||||
const dir = path.dirname(bin)
|
||||
const prev = out.PATH ?? ''
|
||||
out.PATH = prev ? `${dir}${path.delimiter}${prev}` : dir
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@@ -265,15 +275,19 @@ function spawnClaudeText(
|
||||
'json',
|
||||
]
|
||||
|
||||
const bin = resolveClaudeBin()
|
||||
if (!bin)
|
||||
return Promise.reject(new ClaudeError(CLAUDE_MISSING_MSG, ''))
|
||||
|
||||
return new Promise<ClaudeResult>((resolve, reject) => {
|
||||
let stdout = ''
|
||||
let stderr = ''
|
||||
let stdoutBytes = 0
|
||||
let settled = false
|
||||
|
||||
const child = spawn('claude', args, {
|
||||
const child = spawn(bin, args, {
|
||||
cwd,
|
||||
env: buildClaudeChildEnv(),
|
||||
env: buildClaudeChildEnv(bin),
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
})
|
||||
|
||||
@@ -295,10 +309,7 @@ function spawnClaudeText(
|
||||
clearTimeout(timer)
|
||||
const errCode = (err as NodeJS.ErrnoException).code
|
||||
if (errCode === 'ENOENT') {
|
||||
reject(new ClaudeError(
|
||||
'未检测到 claude CLI,请确认已安装并在 PATH 中',
|
||||
stderr,
|
||||
))
|
||||
reject(new ClaudeError(CLAUDE_MISSING_MSG, stderr))
|
||||
return
|
||||
}
|
||||
reject(new ClaudeError(
|
||||
@@ -385,15 +396,19 @@ function spawnClaudeStreamed(
|
||||
]
|
||||
const ndjson = buildStreamJsonLine(prompt, images)
|
||||
|
||||
const bin = resolveClaudeBin()
|
||||
if (!bin)
|
||||
return Promise.reject(new ClaudeError(CLAUDE_MISSING_MSG, ''))
|
||||
|
||||
return new Promise<ClaudeResult>((resolve, reject) => {
|
||||
let stdout = ''
|
||||
let stderr = ''
|
||||
let stdoutBytes = 0
|
||||
let settled = false
|
||||
|
||||
const child = spawn('claude', args, {
|
||||
const child = spawn(bin, args, {
|
||||
cwd,
|
||||
env: buildClaudeChildEnv(),
|
||||
env: buildClaudeChildEnv(bin),
|
||||
stdio: ['pipe', 'pipe', 'pipe'],
|
||||
})
|
||||
|
||||
@@ -415,10 +430,7 @@ function spawnClaudeStreamed(
|
||||
clearTimeout(timer)
|
||||
const errCode = (err as NodeJS.ErrnoException).code
|
||||
if (errCode === 'ENOENT') {
|
||||
reject(new ClaudeError(
|
||||
'未检测到 claude CLI,请确认已安装并在 PATH 中',
|
||||
stderr,
|
||||
))
|
||||
reject(new ClaudeError(CLAUDE_MISSING_MSG, stderr))
|
||||
return
|
||||
}
|
||||
reject(new ClaudeError(
|
||||
|
||||
Reference in New Issue
Block a user