fix: use npm install@latest and global concurrency guard

Address Greptile review:
- npm update -g can silently exit 0 without resolving major-version
  gaps; switch to npm install -g @getpaseo/cli@latest
- Move daemonUpdateInProgress from per-session instance to module-level
  variable so concurrent clients share the same guard
This commit is contained in:
Davy
2026-06-26 12:54:17 +07:00
committed by Mohamed Boudra
parent be8c2a54ce
commit 7f6403f517
+11 -8
View File
@@ -382,6 +382,9 @@ class SessionRequestError extends Error {
}
}
// Global guard — only one daemon update can run at a time across all sessions.
let daemonUpdateInProgress = false;
export interface SessionFileSystem {
isDirectory(path: string): Promise<boolean>;
}
@@ -586,7 +589,6 @@ export class Session {
private readonly daemonSession: DaemonSession;
private readonly workspaceScripts: WorkspaceScriptsService;
private readonly createAgentLifecycleDispatch: CreateAgentLifecycleDispatch;
private daemonUpdateInProgress = false;
constructor(options: SessionOptions) {
const {
@@ -1784,7 +1786,7 @@ export class Session {
private async handleDaemonUpdateRequest(
msg: Extract<SessionInboundMessage, { type: "daemon.update.request" }>,
): Promise<void> {
if (this.daemonUpdateInProgress) {
if (daemonUpdateInProgress) {
this.emit({
type: "rpc_error",
payload: {
@@ -1797,7 +1799,7 @@ export class Session {
return;
}
this.daemonUpdateInProgress = true;
daemonUpdateInProgress = true;
const previousVersion = this.daemonVersion ?? null;
const emitProgress = (phase: "starting" | "downloading" | "installing" | "complete") => {
@@ -1839,16 +1841,17 @@ export class Session {
if (!npmVersionOk) {
emitResponse(false, "npm is not available on this system", null);
this.daemonUpdateInProgress = false;
daemonUpdateInProgress = false;
return;
}
emitProgress("downloading");
// Run npm update -g @getpaseo/cli
// Install latest version globally — npm install -g @getpaseo/cli@latest
// is more reliable than npm update -g, especially across major versions.
const result = await new Promise<{ exitCode: number; stdout: string; stderr: string }>(
(fulfill) => {
const proc = spawn("npm", ["update", "-g", "@getpaseo/cli"], {
const proc = spawn("npm", ["install", "-g", "@getpaseo/cli@latest"], {
stdio: ["ignore", "pipe", "pipe"],
timeout: 300_000, // 5 minutes
});
@@ -1877,7 +1880,7 @@ export class Session {
"Daemon update failed",
);
emitResponse(false, errorMsg, null);
this.daemonUpdateInProgress = false;
daemonUpdateInProgress = false;
return;
}
@@ -1904,7 +1907,7 @@ export class Session {
this.sessionLogger.error({ err: error }, "Daemon update failed with exception");
emitResponse(false, error instanceof Error ? error.message : "Unknown error", null);
} finally {
this.daemonUpdateInProgress = false;
daemonUpdateInProgress = false;
}
}