From 307e15b05b704b26aa54183471ad4a7f37387ce5 Mon Sep 17 00:00:00 2001 From: Mika Kuns Date: Wed, 20 May 2026 16:41:24 +0200 Subject: [PATCH] fix(hook): suppress peer list when daemon is unreachable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fold daemonError into SessionAnnounceOptions so the helper owns the mutually-exclusive choice between peer list and daemon-down hint. Before this fix, a session-announce against an unreachable daemon emitted both "No other mailboxes seen within the last 60 minutes (0 total registered)." (misleading — the daemon was never asked) AND the daemon-unreachable hint. Now only the hint appears when the daemon is down. Co-Authored-By: Claude Opus 4.7 (1M context) --- node/src/cli.ts | 2 +- node/src/hook.ts | 9 +++++++-- node/tests/hook.test.ts | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/node/src/cli.ts b/node/src/cli.ts index 0068a4c..aad3bdc 100644 --- a/node/src/cli.ts +++ b/node/src/cli.ts @@ -260,8 +260,8 @@ program windowMinutes: opts.peerWindowMinutes, maxPeers: opts.maxPeers, watcherCommand: `claude-mailbox watch --block --name ${name}`, + daemonError: daemonError ?? undefined, }); - if (daemonError) lines.push("", daemonError); lines.push(""); process.stdout.write(lines.join("\n")); }); diff --git a/node/src/hook.ts b/node/src/hook.ts index a399ba9..f26c8b0 100644 --- a/node/src/hook.ts +++ b/node/src/hook.ts @@ -123,10 +123,11 @@ export interface SessionAnnounceOptions { windowMinutes: number; maxPeers: number; watcherCommand?: string; + daemonError?: string; } export function buildSessionAnnounceLines(opts: SessionAnnounceOptions): string[] { - const { name, peers, windowMinutes, maxPeers, watcherCommand } = opts; + const { name, peers, windowMinutes, maxPeers, watcherCommand, daemonError } = opts; const lines = [ `Claude-Mailbox: your mailbox name this session is \`${name}\`.`, `The name is auto-derived as -. You can rename it (e.g. to tag your working area) with mcp__mailbox__rename(current_name="${name}", new_name="--"); after that, use the new name everywhere.`, @@ -151,7 +152,11 @@ export function buildSessionAnnounceLines(opts: SessionAnnounceOptions): string[ ` - exit code 2 → daemon unreachable; wait ~5 s, then relaunch.`, ); } - lines.push("", ...formatActivePeerList(peers, name, { windowMinutes, maxPeers })); + if (daemonError) { + lines.push("", daemonError); + } else { + lines.push("", ...formatActivePeerList(peers, name, { windowMinutes, maxPeers })); + } return lines; } diff --git a/node/tests/hook.test.ts b/node/tests/hook.test.ts index 285a087..e036b20 100644 --- a/node/tests/hook.test.ts +++ b/node/tests/hook.test.ts @@ -402,6 +402,20 @@ describe("buildSessionAnnounceLines", () => { expect(out).not.toContain("watch --block"); expect(out).not.toContain("run_in_background"); }); + + it("replaces the peer list with the daemonError hint when daemon is unreachable", () => { + const out = buildSessionAnnounceLines({ + name: "alice-abc12345", + peers: [], + windowMinutes: 60, + maxPeers: 10, + daemonError: "[Claude-Mailbox] Daemon not reachable at http://127.0.0.1:1.", + }).join("\n"); + expect(out).toContain("Daemon not reachable"); + // The misleading "no peers" line must NOT appear when the daemon is down. + expect(out).not.toMatch(/No other mailboxes seen/); + expect(out).not.toMatch(/Active peers/); + }); }); describe("readSettings / writeSettings roundtrip", () => {