From da218ebbe5d481c871c580c66acb085c81ed4c83 Mon Sep 17 00:00:00 2001 From: chenchen Date: Mon, 11 May 2026 21:13:43 +0800 Subject: [PATCH] fix(client): CLI launcher recognises new heicode-sidecar binary name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resolveBundledCliPathFromExecPath / resolveClaudeCliLauncher hardcoded startsWith('claude-sidecar') / startsWith('claude-server') checks. After the 3a358ba rebrand the bundled binary is heicode-sidecar-*.exe — the match fails, the function returns null, and resolveCliArgs falls back to the Windows --preload script branch which spawns the bun-compiled sidecar with arguments it doesn't understand. The process exits 2 silently (empty stderr), surfacing in the UI as: Error: CLI 进程启动失败。 CLI exited during startup with code 2. Symptom user report: pilac69779@codoteam.com freshly registered, OAuth login succeeded but every chat attempt failed at sidecar startup. Fix: accept both `heicode-` and legacy `claude-` prefixes for sidecar / server / cli binaries so MSI #15+ launchers work AND CLAUDE_CLI_PATH=/path/to/legacy/claude-sidecar still works. Co-Authored-By: Claude Opus 4.7 (1M context) --- cc-haha/src/utils/desktopBundledCli.ts | 29 +++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/cc-haha/src/utils/desktopBundledCli.ts b/cc-haha/src/utils/desktopBundledCli.ts index 0a462ac..5d19af1 100644 --- a/cc-haha/src/utils/desktopBundledCli.ts +++ b/cc-haha/src/utils/desktopBundledCli.ts @@ -7,19 +7,38 @@ export type ClaudeCliLauncher = { requiresAppRoot: boolean } +// The sidecar binary was renamed claude-sidecar → heicode-sidecar in +// commit 3a358ba (full Claude→Heicode rebrand). Keep recognising the legacy +// names so unbundled CLAUDE_CLI_PATH overrides and historical installers keep +// working, but new MSI builds ship `heicode-sidecar-*.exe` — without the +// heicode-* prefix below `resolveClaudeCliLauncher` returns null and the +// caller falls back to the `--preload` script branch, which doesn't work +// against a bun-compiled binary and silently exits with code 2 at startup. +const SIDECAR_PREFIXES = ['heicode-sidecar', 'claude-sidecar'] +const SERVER_PREFIXES = ['heicode-server', 'claude-server'] + +function startsWithAny(name: string, prefixes: readonly string[]): string | null { + for (const p of prefixes) { + if (name.startsWith(p)) return p + } + return null +} + export function resolveBundledCliPathFromExecPath( execPath: string = process.execPath, ): string | null { const execName = path.basename(execPath) - if (execName.startsWith('claude-sidecar')) { + if (startsWithAny(execName, SIDECAR_PREFIXES)) { return execPath } - if (execName.startsWith('claude-server')) { + const serverPrefix = startsWithAny(execName, SERVER_PREFIXES) + if (serverPrefix) { + const cliPrefix = serverPrefix.replace(/-server$/, '-cli') const bundledCliPath = path.join( path.dirname(execPath), - execName.replace(/^claude-server/, 'claude-cli'), + execName.replace(new RegExp(`^${serverPrefix}`), cliPrefix), ) return fs.existsSync(bundledCliPath) ? bundledCliPath : null } @@ -47,7 +66,7 @@ export function resolveClaudeCliLauncher(options?: { } const cliBaseName = path.basename(command) - if (cliBaseName.startsWith('claude-sidecar')) { + if (startsWithAny(cliBaseName, SIDECAR_PREFIXES)) { return { command, kind: 'sidecar', @@ -55,7 +74,7 @@ export function resolveClaudeCliLauncher(options?: { } } - if (cliBaseName.startsWith('claude-cli')) { + if (cliBaseName.startsWith('heicode-cli') || cliBaseName.startsWith('claude-cli')) { return { command, kind: 'binary',