From f699dc3777595c90d00e82dc1b289f484d18c00e Mon Sep 17 00:00:00 2001 From: Kit Date: Sat, 10 Jan 2026 22:38:01 +0100 Subject: [PATCH 1/2] fix(cli): improve daemon restart feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - runDaemonRestart() now returns Promise indicating success - update command only shows success when restart actually happened - Fixes missing reasoningLevel type in compactEmbeddedPiSession 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Carl Ulsøe Christensen Co-Authored-By: Claude Opus 4.5 --- src/cli/daemon-cli.ts | 13 ++++++++++--- src/cli/update-cli.test.ts | 2 +- src/cli/update-cli.ts | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/cli/daemon-cli.ts b/src/cli/daemon-cli.ts index 55a8a1450..793b1ea5b 100644 --- a/src/cli/daemon-cli.ts +++ b/src/cli/daemon-cli.ts @@ -993,7 +993,12 @@ export async function runDaemonStop() { } } -export async function runDaemonRestart() { +/** + * Restart the gateway daemon service. + * @returns `true` if restart succeeded, `false` if the service was not loaded. + * Throws/exits on check or restart failures. + */ +export async function runDaemonRestart(): Promise { const service = resolveGatewayService(); let loaded = false; try { @@ -1001,20 +1006,22 @@ export async function runDaemonRestart() { } catch (err) { defaultRuntime.error(`Gateway service check failed: ${String(err)}`); defaultRuntime.exit(1); - return; + return false; } if (!loaded) { defaultRuntime.log(`Gateway service ${service.notLoadedText}.`); for (const hint of renderGatewayServiceStartHints()) { defaultRuntime.log(`Start with: ${hint}`); } - return; + return false; } try { await service.restart({ stdout: process.stdout }); + return true; } catch (err) { defaultRuntime.error(`Gateway restart failed: ${String(err)}`); defaultRuntime.exit(1); + return false; } } diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index cf555a6fd..a29d8b1ac 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -124,7 +124,7 @@ describe("update-cli", () => { }; vi.mocked(runGatewayUpdate).mockResolvedValue(mockResult); - vi.mocked(runDaemonRestart).mockResolvedValue(); + vi.mocked(runDaemonRestart).mockResolvedValue(true); await updateCommand({ restart: true }); diff --git a/src/cli/update-cli.ts b/src/cli/update-cli.ts index 8ae2872f5..8d6f0d4bb 100644 --- a/src/cli/update-cli.ts +++ b/src/cli/update-cli.ts @@ -156,8 +156,8 @@ export async function updateCommand(opts: UpdateCommandOptions): Promise { defaultRuntime.log(theme.heading("Restarting daemon...")); } try { - await runDaemonRestart(); - if (!opts.json) { + const restarted = await runDaemonRestart(); + if (!opts.json && restarted) { defaultRuntime.log(theme.success("Daemon restarted successfully.")); } } catch (err) { From fa61699f9a7483f7dbe39ef416dc55c708252393 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 10 Jan 2026 22:52:09 +0100 Subject: [PATCH 2/2] fix: polish restart feedback + stabilize tests (#685) (thanks @carlulsoe) --- CHANGELOG.md | 1 + src/auto-reply/reply.ts | 1 - src/cli/update-cli.test.ts | 27 +++++++++++++++++++++++++ src/commands/sandbox-explain.test.ts | 2 +- src/discord/monitor.tool-result.test.ts | 2 +- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f30f7a3..96053c509 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Docker: allow optional home volume + extra bind mounts in `docker-setup.sh`. (#679) — thanks @gabriel-trigo. ### Fixes +- CLI: avoid success message when daemon restart is skipped. (#685) — thanks @carlulsoe. - macOS: stabilize bridge tunnels, guard invoke senders on disconnect, and drain stdout/stderr to avoid deadlocks. (#676) — thanks @ngutman. - Agents/System: clarify sandboxed runtime in system prompt and surface elevated availability when sandboxed. - Auto-reply: prefer `RawBody` for command/directive parsing (WhatsApp + Discord) and prevent fallback runs from clobbering concurrent session updates. (#643) — thanks @mcinteerj. diff --git a/src/auto-reply/reply.ts b/src/auto-reply/reply.ts index b8d8b9a66..6f9be3111 100644 --- a/src/auto-reply/reply.ts +++ b/src/auto-reply/reply.ts @@ -589,7 +589,6 @@ export async function getReplyFromConfig( (agentCfg?.elevatedDefault as ElevatedLevel | undefined) ?? "on") : "off"; - const providerKey = sessionCtx.Provider?.trim().toLowerCase(); const resolvedBlockStreaming = opts?.disableBlockStreaming === true ? "off" diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index a29d8b1ac..8a5f3296e 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -131,6 +131,33 @@ describe("update-cli", () => { expect(runDaemonRestart).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"); + const { defaultRuntime } = await import("../runtime.js"); + const { updateCommand } = await import("./update-cli.js"); + + const mockResult: UpdateRunResult = { + status: "ok", + mode: "git", + steps: [], + durationMs: 100, + }; + + vi.mocked(runGatewayUpdate).mockResolvedValue(mockResult); + vi.mocked(runDaemonRestart).mockResolvedValue(false); + vi.mocked(defaultRuntime.log).mockClear(); + + await updateCommand({ restart: true }); + + const logLines = vi + .mocked(defaultRuntime.log) + .mock.calls.map((call) => String(call[0])); + expect( + logLines.some((line) => line.includes("Daemon restarted successfully.")), + ).toBe(false); + }); + it("updateCommand validates timeout option", async () => { const { defaultRuntime } = await import("../runtime.js"); const { updateCommand } = await import("./update-cli.js"); diff --git a/src/commands/sandbox-explain.test.ts b/src/commands/sandbox-explain.test.ts index 3fec0f172..d3e5ea2ee 100644 --- a/src/commands/sandbox-explain.test.ts +++ b/src/commands/sandbox-explain.test.ts @@ -42,5 +42,5 @@ describe("sandbox explain command", () => { expect(Array.isArray(parsed.fixIt)).toBe(true); expect(parsed.fixIt).toContain("agents.defaults.sandbox.mode=off"); expect(parsed.fixIt).toContain("tools.sandbox.tools.deny"); - }); + }, 15_000); }); diff --git a/src/discord/monitor.tool-result.test.ts b/src/discord/monitor.tool-result.test.ts index 5963a4d2d..7c36dd37b 100644 --- a/src/discord/monitor.tool-result.test.ts +++ b/src/discord/monitor.tool-result.test.ts @@ -118,7 +118,7 @@ describe("discord tool result dispatch", () => { expect(runtimeError).not.toHaveBeenCalled(); expect(sendMock).toHaveBeenCalledTimes(1); expect(sendMock.mock.calls[0]?.[1]).toMatch(/^PFX /); - }, 10000); + }, 15_000); it("caches channel info lookups between messages", async () => { const { createDiscordMessageHandler } = await import("./monitor.js");