fix(acp): uninstall before reinstall on npx agent upgrade

Plain `npm install -g <pkg>@<version>` over an existing install does not
reliably re-resolve platform-specific optionalDependencies, leaving the
native CLI binary missing or stale (e.g. 'Native CLI binary for darwin-x64
not found' after the claude-agent-sdk upgrade). The Upgrade button now
runs npm uninstall -g first as a best-effort step, forcing npm to rebuild
the dependency graph from scratch on the subsequent install. If the clean
upgrade fails midway, the DB and the Settings UI resync to the actual
on-disk state instead of showing a phantom version.
This commit is contained in:
xintaofei
2026-04-25 10:45:49 +08:00
parent 4f0684dd04
commit 5ae081e87a
5 changed files with 82 additions and 4 deletions

View File

@@ -3153,7 +3153,8 @@ export function AcpAgentSettings() {
const installedVersion = await acpPrepareNpxAgent(
agent.agent_type,
agent.registry_version,
taskId
taskId,
mode === "upgrade"
)
setAgents((prev) =>
prev.map((item) =>
@@ -3200,6 +3201,25 @@ export function AcpAgentSettings() {
description: message,
}
)
if (mode === "upgrade") {
// Clean upgrade may have removed the old install before failing —
// resync local state so the UI doesn't keep showing a phantom version.
try {
const detected = await acpDetectAgentLocalVersion(agent.agent_type)
setAgents((prev) =>
prev.map((item) =>
item.agent_type === agent.agent_type
? { ...item, installed_version: detected ?? null }
: item
)
)
} catch (detectErr) {
console.error(
"[Settings] failed to resync installed version after upgrade failure:",
detectErr
)
}
}
throw err
} finally {
busyActionRef.current.delete(agent.agent_type)

View File

@@ -202,11 +202,13 @@ export async function acpDetectAgentLocalVersion(
export async function acpPrepareNpxAgent(
agentType: AgentType,
registryVersion: string | null | undefined,
taskId: string
taskId: string,
cleanFirst: boolean = false
): Promise<string> {
return getTransport().call("acp_prepare_npx_agent", {
agentType,
registryVersion: registryVersion ?? null,
cleanFirst,
taskId,
})
}

View File

@@ -189,11 +189,13 @@ export async function acpDetectAgentLocalVersion(
export async function acpPrepareNpxAgent(
agentType: AgentType,
registryVersion: string | null | undefined,
taskId: string
taskId: string,
cleanFirst: boolean = false
): Promise<string> {
return invoke("acp_prepare_npx_agent", {
agentType,
registryVersion: registryVersion ?? null,
cleanFirst,
taskId,
})
}