Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 22 additions & 34 deletions lib/daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -1320,44 +1320,32 @@ var ipc = createIPCServer(socketPath(), function (msg) {
return { ok: true };
}

// Production: fetch latest via npx, then spawn updated daemon
var { execSync: execSyncUpd, spawn: spawnUpd } = require("child_process");
// Production: install to global npm, then shut down so the process manager
// (systemd / clagentic-daemon.sh) restarts from the updated global install.
// This is the only reliable path — npx installs to a cache location that the
// restart wrapper does not consult, so npx-spawned daemons get replaced by the
// old global version on the next supervised restart.
var { execFileSync: execFileUpd } = require("child_process");
var updTag = config.updateChannel === "beta" ? "beta" : "latest";
var updDaemonScript;
var updOk = false;
try {
// npx downloads the package and puts a bin symlink; `which` prints its path
var binPath = execSyncUpd(
"npx --yes --package=clagentic-console@" + updTag + " -- which clagentic-console",
{ stdio: ["ignore", "pipe", "pipe"], timeout: 120000, encoding: "utf8" }
).trim();
// Resolve symlink to get the actual package directory
var realBin = fs.realpathSync(binPath);
updDaemonScript = path.join(path.dirname(realBin), "..", "lib", "daemon.js");
updDaemonScript = path.resolve(updDaemonScript);
console.log("[daemon] Resolved updated daemon:", updDaemonScript);
console.log("[daemon] Installing @clagentic/console@" + updTag + " globally...");
execFileUpd("npm", ["install", "-g", "@clagentic/console@" + updTag], {
stdio: ["ignore", "pipe", "pipe"],
timeout: 120000,
encoding: "utf8",
});
console.log("[daemon] Global install complete. Shutting down for supervised restart.");
updOk = true;
} catch (updErr) {
console.log("[daemon] npx resolve failed:", updErr.message);
// Fallback: restart with current code
updDaemonScript = path.join(__dirname, "daemon.js");
console.log("[daemon] Global install failed:", updErr.message);
relay.broadcastAll({ type: "update_failed", error: updErr.message });
return { ok: false, error: updErr.message };
}
if (updOk) {
updateHandoff = true;
setTimeout(function () { gracefulShutdown(); }, 100);
}
// Spawn new daemon process — it will retry if port is still in use
var { logPath: updLogPath, configPath: updConfigPath } = require("./config");
var updLogFd = fs.openSync(updLogPath(), "a");
var updChild = spawnUpd(process.execPath, [updDaemonScript], {
detached: true,
windowsHide: true,
stdio: ["ignore", updLogFd, updLogFd],
env: Object.assign({}, process.env, {
CLAGENTIC_CONFIG: updConfigPath(),
}),
});
updChild.unref();
fs.closeSync(updLogFd);
config.pid = updChild.pid;
saveConfig(config);
console.log("[daemon] Spawned new daemon (PID " + updChild.pid + "), shutting down...");
updateHandoff = true;
setTimeout(function () { gracefulShutdown(); }, 100);
return { ok: true };
}

Expand Down
Loading