feat(naming)!: auto-derive mailbox name from project + runtime rename
Mailbox names are now built as <project>-<session-short>, where <project> is the sanitized git-repo basename (or cwd basename) — no more env-var prefix step. Sessions can re-tag themselves at runtime via the new mcp__mailbox__rename tool (POST /v1/rename), which transfers all pending messages to the new name in a single transaction. Peers using the old name re-discover via list_mailboxes. BREAKING: \$CLAUDE_MAILBOX_NAME is no longer read. Existing setups that relied on the env-var prefix should remove it from .claude/settings.json; the prefix now comes from the working directory automatically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,8 @@ describe("`check --hook` CLI behavior", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("exits 0 silently when no stdin, no --name, no env", () => {
|
||||
const r = runCli(["check", "--hook"], { env: { CLAUDE_MAILBOX_NAME: undefined } });
|
||||
it("exits 0 silently when no stdin and no --name", () => {
|
||||
const r = runCli(["check", "--hook"]);
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toBe("");
|
||||
expect(r.stderr).toBe("");
|
||||
@@ -44,18 +44,6 @@ describe("`check --hook` CLI behavior", () => {
|
||||
|
||||
it("derives session-id-based name from stdin and emits daemon hint when down", () => {
|
||||
const r = runCli(["check", "--hook", "--url", "http://127.0.0.1:1"], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toContain("[Claude-Mailbox] Daemon not reachable");
|
||||
});
|
||||
|
||||
it("uses base prefix from CLAUDE_MAILBOX_NAME when both env and stdin present", () => {
|
||||
// We can't directly assert the name from --hook output (it's only in the unreachable hint URL).
|
||||
// The hint always contains the URL we passed, so this just confirms the path runs without error.
|
||||
const r = runCli(["check", "--hook", "--url", "http://127.0.0.1:1"], {
|
||||
env: { CLAUDE_MAILBOX_NAME: "backend" },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
expect(r.status).toBe(0);
|
||||
@@ -65,7 +53,7 @@ describe("`check --hook` CLI behavior", () => {
|
||||
it("explicit --name overrides session-id derivation", () => {
|
||||
const r = runCli(
|
||||
["check", "--hook", "--name", "explicit", "--url", "http://127.0.0.1:1"],
|
||||
{ env: { CLAUDE_MAILBOX_NAME: "ignored" }, stdin: HOOK_STDIN },
|
||||
{ stdin: HOOK_STDIN },
|
||||
);
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toContain("[Claude-Mailbox] Daemon not reachable");
|
||||
@@ -73,7 +61,7 @@ describe("`check --hook` CLI behavior", () => {
|
||||
|
||||
it("uses CLAUDE_MAILBOX_URL env as default base URL when --url is not given", () => {
|
||||
const r = runCli(["check", "--hook"], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined, CLAUDE_MAILBOX_URL: "http://127.0.0.1:1" },
|
||||
env: { CLAUDE_MAILBOX_URL: "http://127.0.0.1:1" },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
expect(r.status).toBe(0);
|
||||
@@ -81,9 +69,9 @@ describe("`check --hook` CLI behavior", () => {
|
||||
});
|
||||
|
||||
it("non-hook mode errors out when no name resolved", () => {
|
||||
const r = runCli(["check"], { env: { CLAUDE_MAILBOX_NAME: undefined } });
|
||||
const r = runCli(["check"]);
|
||||
expect(r.status).not.toBe(0);
|
||||
expect(r.stderr).toContain("CLAUDE_MAILBOX_NAME");
|
||||
expect(r.stderr).toContain("Missing --name");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -96,38 +84,33 @@ describe("`session-announce` CLI behavior", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("prints the derived mailbox name from a SessionStart payload", () => {
|
||||
it("prints the derived mailbox name from a SessionStart payload (project-prefixed)", () => {
|
||||
// cwd "/tmp" is not a git repo → basename "tmp" → project prefix "tmp".
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toContain("`claude-abc12345`");
|
||||
// The exact prefix depends on the runtime cwd if git resolves; the deterministic
|
||||
// assertion is the session-short suffix and the announcement structure.
|
||||
expect(r.stdout).toMatch(/`[a-z0-9-]+-abc12345`/);
|
||||
expect(r.stdout).toContain("mcp__mailbox__send");
|
||||
expect(r.stdout).toContain(`from="claude-abc12345"`);
|
||||
expect(r.stdout).toMatch(/from="[a-z0-9-]+-abc12345"/);
|
||||
});
|
||||
|
||||
it("uses base prefix when set", () => {
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], {
|
||||
env: { CLAUDE_MAILBOX_NAME: "backend" },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
it("includes a hint about the rename tool", () => {
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], { stdin: HOOK_STDIN });
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toContain("`backend-abc12345`");
|
||||
expect(r.stdout).toContain("mcp__mailbox__rename");
|
||||
});
|
||||
|
||||
it("emits daemon-not-reachable hint when daemon is down", () => {
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined },
|
||||
stdin: HOOK_STDIN,
|
||||
});
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], { stdin: HOOK_STDIN });
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toContain("[Claude-Mailbox] Daemon not reachable");
|
||||
});
|
||||
|
||||
it("stays silent when no session_id in stdin", () => {
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined },
|
||||
stdin: JSON.stringify({ hook_event_name: "SessionStart" }),
|
||||
});
|
||||
expect(r.status).toBe(0);
|
||||
@@ -135,9 +118,7 @@ describe("`session-announce` CLI behavior", () => {
|
||||
});
|
||||
|
||||
it("stays silent when no stdin at all", () => {
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE], {
|
||||
env: { CLAUDE_MAILBOX_NAME: undefined },
|
||||
});
|
||||
const r = runCli(["session-announce", "--url", UNREACHABLE]);
|
||||
expect(r.status).toBe(0);
|
||||
expect(r.stdout).toBe("");
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user