New SessionEnd plugin hook runs `claude-mailbox session-end`, which derives the session's auto-name from stdin and asks the daemon to delete the mailbox if it has no pending messages either direction. Renamed mailboxes are preserved (the auto-name no longer exists, so DELETE is a no-op). The daemon-side `SKIP_UPSERT_PATHS` prevents the request from auto-recreating the mailbox. Sweeper remains the safety net for sessions that exit ungracefully.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mailbox listings grew unbounded as old sessions ended without
unregistering. This adds two layers of cleanup, configurable via
mailbox.json or `serve` flags:
- Lazy filter: list responses (REST /v1/list, MCP list_mailboxes)
drop mailboxes idle longer than hideAfterMinutes (default 24h),
while always keeping the caller and any sender with messages
pending for them.
- Background sweep: startServer runs an initial prune on boot and
schedules an unref'd interval timer that hard-deletes mailboxes
idle longer than deleteAfterMinutes (default 7d) which have no
pending messages, and wipes their delivered history.
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>
Introduces @kuns/claude-mailbox under node/, a wire-compatible TypeScript
port of the .NET daemon that distributes via the public Gitea npm registry.
The .NET project stays in src/ClaudeMailbox/ untouched; users pick whichever
flavor they prefer.
- node/ project: fastify + @modelcontextprotocol/sdk StreamableHTTPServerTransport
+ better-sqlite3, schema and wire surface match the C# version (port 47822,
X-Mailbox header, MCP tool names, snake_case SQLite columns)
- Cross-platform autostart: Scheduled Task (Win, no admin) / Windows Service
(Win, --service) / launchd (mac) / systemd --user (linux)
- 9/9 vitest tests pass; end-to-end /health + send/check round-trip verified
- CI split: existing ci.yml/release.yml renamed to *-dotnet.yml with path
filters, new ci-node.yml and release-node.yml publish to Gitea npm registry
- install.ps1 / install.sh bootstrap one-liners at repo root; homebrew/
contains a tap formula template
- README install section reordered: npm path primary, dotnet publish secondary
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>