fix(coding-agent): repair self-update detection
Fixes #3942 Fixes #3980 Fixes #3922
This commit is contained in:
@@ -7,10 +7,12 @@ import {
|
||||
getSelfUpdateCommand,
|
||||
getSelfUpdateUnavailableInstruction,
|
||||
PACKAGE_NAME,
|
||||
type SelfUpdateCommand,
|
||||
VERSION,
|
||||
} from "./config.js";
|
||||
import { DefaultPackageManager } from "./core/package-manager.js";
|
||||
import { SettingsManager } from "./core/settings-manager.js";
|
||||
import { shouldUseWindowsShell } from "./utils/child-process.js";
|
||||
import { getLatestPiVersion, isNewerPackageVersion } from "./utils/version-check.js";
|
||||
|
||||
export type PackageCommand = "install" | "remove" | "update" | "list";
|
||||
@@ -271,13 +273,9 @@ function updateTargetIncludesExtensions(target: UpdateTarget): boolean {
|
||||
return target.type === "all" || target.type === "extensions";
|
||||
}
|
||||
|
||||
function canSelfUpdate(): boolean {
|
||||
return getSelfUpdateCommand(PACKAGE_NAME) !== undefined;
|
||||
}
|
||||
|
||||
function printSelfUpdateUnavailable(): void {
|
||||
function printSelfUpdateUnavailable(npmCommand?: string[]): void {
|
||||
console.error(`error: ${APP_NAME} cannot self-update this installation.`);
|
||||
console.error(getSelfUpdateUnavailableInstruction(PACKAGE_NAME));
|
||||
console.error(getSelfUpdateUnavailableInstruction(PACKAGE_NAME, npmCommand));
|
||||
|
||||
const entrypoint = process.argv[1];
|
||||
if (entrypoint) {
|
||||
@@ -286,9 +284,7 @@ function printSelfUpdateUnavailable(): void {
|
||||
}
|
||||
}
|
||||
|
||||
function printSelfUpdateFallback(): void {
|
||||
const command = getSelfUpdateCommand(PACKAGE_NAME);
|
||||
if (!command) return;
|
||||
function printSelfUpdateFallback(command: SelfUpdateCommand): void {
|
||||
console.error(chalk.dim(`If this keeps failing, run this command yourself: ${command.display}`));
|
||||
}
|
||||
|
||||
@@ -312,19 +308,14 @@ async function shouldRunSelfUpdate(force: boolean): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
async function runSelfUpdate(): Promise<void> {
|
||||
const command = getSelfUpdateCommand(PACKAGE_NAME);
|
||||
if (!command) {
|
||||
throw new Error(
|
||||
`${APP_NAME} cannot self-update this installation. ${getSelfUpdateUnavailableInstruction(PACKAGE_NAME)}`,
|
||||
);
|
||||
}
|
||||
|
||||
async function runSelfUpdate(command: SelfUpdateCommand): Promise<void> {
|
||||
console.log(chalk.dim(`Updating ${APP_NAME} with ${command.display}...`));
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
// Windows package managers are commonly .cmd shims. Use the shell so Node can execute them;
|
||||
// command and args come from getSelfUpdateCommandForMethod(), not user input.
|
||||
const child = spawn(command.command, command.args, { stdio: "inherit", shell: process.platform === "win32" });
|
||||
// Windows package managers are commonly .cmd shims. Use the shell so Node can execute them.
|
||||
const child = spawn(command.command, command.args, {
|
||||
stdio: "inherit",
|
||||
shell: shouldUseWindowsShell(command.command),
|
||||
});
|
||||
child.on("error", (error) => {
|
||||
reject(error);
|
||||
});
|
||||
@@ -409,16 +400,12 @@ export async function handlePackageCommand(args: string[]): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.command === "update" && options.updateTarget?.type === "self" && !canSelfUpdate()) {
|
||||
printSelfUpdateUnavailable();
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
const cwd = process.cwd();
|
||||
const agentDir = getAgentDir();
|
||||
const settingsManager = SettingsManager.create(cwd, agentDir);
|
||||
reportSettingsErrors(settingsManager, "package command");
|
||||
const selfUpdateNpmCommand = settingsManager.getGlobalSettings().npmCommand;
|
||||
|
||||
const packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });
|
||||
|
||||
packageManager.setProgressCallback((event) => {
|
||||
@@ -493,24 +480,25 @@ export async function handlePackageCommand(args: string[]): Promise<boolean> {
|
||||
}
|
||||
}
|
||||
if (updateTargetIncludesSelf(target)) {
|
||||
if (canSelfUpdate()) {
|
||||
if (!(await shouldRunSelfUpdate(options.force))) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
await runSelfUpdate();
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : "Unknown package command error";
|
||||
console.error(chalk.red(`Error: ${message}`));
|
||||
printSelfUpdateFallback();
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
console.log(chalk.green(`Updated ${APP_NAME}`));
|
||||
} else {
|
||||
printSelfUpdateUnavailable();
|
||||
const selfUpdateCommand = getSelfUpdateCommand(PACKAGE_NAME, selfUpdateNpmCommand);
|
||||
if (!selfUpdateCommand) {
|
||||
printSelfUpdateUnavailable(selfUpdateNpmCommand);
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
if (!(await shouldRunSelfUpdate(options.force))) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
await runSelfUpdate(selfUpdateCommand);
|
||||
} catch (error: unknown) {
|
||||
const message = error instanceof Error ? error.message : "Unknown package command error";
|
||||
console.error(chalk.red(`Error: ${message}`));
|
||||
printSelfUpdateFallback(selfUpdateCommand);
|
||||
process.exitCode = 1;
|
||||
return true;
|
||||
}
|
||||
console.log(chalk.green(`Updated ${APP_NAME}`));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user