feat(plugin): per-session mailbox identity + mailbox-update command
The hook now derives a unique mailbox name from the session_id supplied on hook stdin, so two parallel Claude Code sessions in the same project get distinct mailboxes (e.g. `claude-a8b3c1d2`, `claude-d4e5f6a7`) instead of colliding on a shared env value. An optional CLAUDE_MAILBOX_NAME base prefix flavors the names as `<base>-<sid>`. Adds: - `claude-mailbox session-announce` subcommand for the new SessionStart hook, which prints the current session's mailbox name to context - `/claude-mailbox:mailbox-update` slash command for `npm update` + daemon restart - stdin parsing helpers (parseHookStdin, deriveSessionName) with unit tests; the doctor no longer needs a mandatory name prompt
This commit is contained in:
@@ -10,8 +10,11 @@ import {
|
||||
applyInstall,
|
||||
applyUninstall,
|
||||
buildHookCommand,
|
||||
deriveSessionName,
|
||||
formatMessagesForHook,
|
||||
parseHookStdin,
|
||||
readSettings,
|
||||
readStdinIfPiped,
|
||||
settingsPathFor,
|
||||
writeSettings,
|
||||
type HookMessage,
|
||||
@@ -125,19 +128,36 @@ program
|
||||
}
|
||||
});
|
||||
|
||||
function resolveHookMailboxName(explicit: string | undefined): string | null {
|
||||
if (explicit && explicit.trim()) return explicit.trim();
|
||||
const stdin = parseHookStdin(readStdinIfPiped());
|
||||
const sid = stdin?.session_id?.trim();
|
||||
if (sid) {
|
||||
const base = (process.env["CLAUDE_MAILBOX_NAME"] ?? "").trim() || null;
|
||||
return deriveSessionName(sid, base);
|
||||
}
|
||||
const envName = (process.env["CLAUDE_MAILBOX_NAME"] ?? "").trim();
|
||||
return envName || null;
|
||||
}
|
||||
|
||||
program
|
||||
.command("check")
|
||||
.description(
|
||||
"Pull pending messages and mark delivered. In --hook mode the name can come from CLAUDE_MAILBOX_NAME.",
|
||||
"Pull pending messages and mark delivered. In --hook mode the name is auto-derived from the SessionStart/UserPromptSubmit stdin (session_id), optionally flavored by $CLAUDE_MAILBOX_NAME.",
|
||||
)
|
||||
.option(
|
||||
"--name <name>",
|
||||
"Explicit mailbox name. Overrides hook stdin and $CLAUDE_MAILBOX_NAME.",
|
||||
)
|
||||
.option("--name <name>", "Mailbox name (also sent as X-Mailbox). Falls back to $CLAUDE_MAILBOX_NAME.")
|
||||
.option("--url <url>", "Daemon base URL", DEFAULT_URL)
|
||||
.option(
|
||||
"--hook",
|
||||
"Hook mode: human-readable output, silent when no mailbox configured or daemon unreachable (exit 0). Emits a one-line setup hint when name is set but daemon is unreachable.",
|
||||
"Hook mode: human-readable output, silent when no mailbox configured or daemon unreachable. Emits a one-line setup hint when name resolves but daemon is unreachable.",
|
||||
)
|
||||
.action(async (opts: { name?: string; url: string; hook?: boolean }) => {
|
||||
const name = (opts.name ?? process.env["CLAUDE_MAILBOX_NAME"] ?? "").trim();
|
||||
const name = opts.hook
|
||||
? resolveHookMailboxName(opts.name)
|
||||
: (opts.name ?? process.env["CLAUDE_MAILBOX_NAME"] ?? "").trim() || null;
|
||||
if (!name) {
|
||||
if (opts.hook) return;
|
||||
console.error("Missing --name (or set CLAUDE_MAILBOX_NAME).");
|
||||
@@ -170,6 +190,23 @@ program
|
||||
}
|
||||
});
|
||||
|
||||
program
|
||||
.command("session-announce")
|
||||
.description(
|
||||
"SessionStart-hook helper: reads the hook stdin JSON, derives the session's mailbox name from session_id, and prints a one-line announcement to stdout so Claude sees its mailbox identity.",
|
||||
)
|
||||
.action(() => {
|
||||
const stdin = parseHookStdin(readStdinIfPiped());
|
||||
const sid = stdin?.session_id?.trim();
|
||||
if (!sid) return;
|
||||
const base = (process.env["CLAUDE_MAILBOX_NAME"] ?? "").trim() || null;
|
||||
const name = deriveSessionName(sid, base);
|
||||
process.stdout.write(
|
||||
`Claude-Mailbox: this session is mailbox \`${name}\`. ` +
|
||||
`Peers can send to it with: claude-mailbox send --from <peer> --to ${name} --body "..."\n`,
|
||||
);
|
||||
});
|
||||
|
||||
program
|
||||
.command("list")
|
||||
.description("List known mailboxes.")
|
||||
|
||||
Reference in New Issue
Block a user