fix(client): CLI launcher recognises new heicode-sidecar binary name
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) <noreply@anthropic.com>
This commit is contained in:
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user