diff --git a/CHANGELOG.md b/CHANGELOG.md index b61503485..859c74a48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ Docs: https://docs.clawd.bot ## 2026.1.23 +### Changes +- CLI: restart the gateway by default after `clawdbot update`; add `--no-restart` to skip it. + ### Fixes - Media: preserve PNG alpha when possible; fall back to JPEG when still over size cap. (#1491) Thanks @robbyczgw-cla. - Agents: treat plugin-only tool allowlists as opt-ins; keep core tools enabled. (#1467) diff --git a/docs/cli/update.md b/docs/cli/update.md index 8dafbbd87..328ca485d 100644 --- a/docs/cli/update.md +++ b/docs/cli/update.md @@ -1,5 +1,5 @@ --- -summary: "CLI reference for `clawdbot update` (safe-ish source update + optional gateway restart)" +summary: "CLI reference for `clawdbot update` (safe-ish source update + gateway auto-restart)" read_when: - You want to update a source checkout safely - You need to understand `--update` shorthand behavior @@ -20,14 +20,14 @@ clawdbot update wizard clawdbot update --channel beta clawdbot update --channel dev clawdbot update --tag beta -clawdbot update --restart +clawdbot update --no-restart clawdbot update --json clawdbot --update ``` ## Options -- `--restart`: restart the Gateway service after a successful update. +- `--no-restart`: skip restarting the Gateway service after a successful update. - `--channel `: set the update channel (git + npm; persisted in config). - `--tag `: override the npm dist-tag or version for this update only. - `--json`: print machine-readable `UpdateRunResult` JSON. @@ -52,7 +52,8 @@ Options: ## `update wizard` Interactive flow to pick an update channel and confirm whether to restart the Gateway -after updating. If you select `dev` without a git checkout, it offers to create one. +after updating (default is to restart). If you select `dev` without a git checkout, it +offers to create one. ## What it does diff --git a/docs/install/updating.md b/docs/install/updating.md index f0efcae2a..1d39fa6e4 100644 --- a/docs/install/updating.md +++ b/docs/install/updating.md @@ -7,7 +7,7 @@ read_when: # Updating -Clawdbot is moving fast (pre “1.0”). Treat updates like shipping infra: update → run checks → restart → verify. +Clawdbot is moving fast (pre “1.0”). Treat updates like shipping infra: update → run checks → restart (or use `clawdbot update`, which restarts) → verify. ## Recommended: re-run the website installer (upgrade in place) @@ -81,7 +81,7 @@ Notes: For **source installs** (git checkout), prefer: ```bash -clawdbot update --restart +clawdbot update ``` It runs a safe-ish update flow: @@ -89,6 +89,7 @@ It runs a safe-ish update flow: - Switches to the selected channel (tag or branch). - Fetches + rebases against the configured upstream (dev channel). - Installs deps, builds, builds the Control UI, and runs `clawdbot doctor`. +- Restarts the gateway by default (use `--no-restart` to skip). If you installed via **npm/pnpm** (no git metadata), `clawdbot update` will try to update via your package manager. If it can’t detect the install, use “Update (global install)” instead. diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index 2c7aca4f3..40347d3e2 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -415,7 +415,7 @@ describe("update-cli", () => { expect(defaultRuntime.exit).toHaveBeenCalledWith(1); }); - it("updateCommand restarts daemon when --restart is set", async () => { + it("updateCommand restarts daemon by default", async () => { const { runGatewayUpdate } = await import("../infra/update-runner.js"); const { runDaemonRestart } = await import("./daemon-cli.js"); const { updateCommand } = await import("./update-cli.js"); @@ -430,11 +430,30 @@ describe("update-cli", () => { vi.mocked(runGatewayUpdate).mockResolvedValue(mockResult); vi.mocked(runDaemonRestart).mockResolvedValue(true); - await updateCommand({ restart: true }); + await updateCommand({}); expect(runDaemonRestart).toHaveBeenCalled(); }); + it("updateCommand skips restart when --no-restart is set", async () => { + const { runGatewayUpdate } = await import("../infra/update-runner.js"); + const { runDaemonRestart } = await import("./daemon-cli.js"); + const { updateCommand } = await import("./update-cli.js"); + + const mockResult: UpdateRunResult = { + status: "ok", + mode: "git", + steps: [], + durationMs: 100, + }; + + vi.mocked(runGatewayUpdate).mockResolvedValue(mockResult); + + await updateCommand({ restart: false }); + + expect(runDaemonRestart).not.toHaveBeenCalled(); + }); + it("updateCommand skips success message when restart does not run", async () => { const { runGatewayUpdate } = await import("../infra/update-runner.js"); const { runDaemonRestart } = await import("./daemon-cli.js"); diff --git a/src/cli/update-cli.ts b/src/cli/update-cli.ts index 538d07c97..9e597e485 100644 --- a/src/cli/update-cli.ts +++ b/src/cli/update-cli.ts @@ -553,6 +553,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise { process.noDeprecation = true; process.env.NODE_NO_WARNINGS = "1"; const timeoutMs = opts.timeout ? Number.parseInt(opts.timeout, 10) * 1000 : undefined; + const shouldRestart = opts.restart !== false; if (timeoutMs !== undefined && (Number.isNaN(timeoutMs) || timeoutMs <= 0)) { defaultRuntime.error("--timeout must be a positive integer (seconds)"); @@ -898,7 +899,7 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise { } // Restart service if requested - if (opts.restart) { + if (shouldRestart) { if (!opts.json) { defaultRuntime.log(""); defaultRuntime.log(theme.heading("Restarting service...")); @@ -1068,7 +1069,7 @@ export async function updateWizardCommand(opts: UpdateWizardOptions = {}): Promi const restart = await confirm({ message: stylePromptMessage("Restart the gateway service after update?"), - initialValue: false, + initialValue: true, }); if (isCancel(restart)) { defaultRuntime.log(theme.muted("Update cancelled.")); @@ -1093,7 +1094,7 @@ export function registerUpdateCli(program: Command) { .command("update") .description("Update Clawdbot to the latest version") .option("--json", "Output result as JSON", false) - .option("--restart", "Restart the gateway service after a successful update", false) + .option("--no-restart", "Skip restarting the gateway service after a successful update") .option("--channel ", "Persist update channel (git + npm)") .option("--tag ", "Override npm dist-tag or version for this update") .option("--timeout ", "Timeout for each update step in seconds (default: 1200)") @@ -1104,7 +1105,7 @@ export function registerUpdateCli(program: Command) { ["clawdbot update --channel beta", "Switch to beta channel (git + npm)"], ["clawdbot update --channel dev", "Switch to dev channel (git + npm)"], ["clawdbot update --tag beta", "One-off update to a dist-tag or version"], - ["clawdbot update --restart", "Update and restart the service"], + ["clawdbot update --no-restart", "Update without restarting the service"], ["clawdbot update --json", "Output result as JSON"], ["clawdbot update --yes", "Non-interactive (accept downgrade prompts)"], ["clawdbot update wizard", "Interactive update wizard"],