The previous skill assumed a happy-path environment and silently
broke on real installs. Hardened the flow:
- Always pass --@kuns:registry on every npm call, so the upgrade
survives an unreadable user .npmrc (e.g. roaming HOME on a
network share that npm can't access).
- Treat /health as the ground truth, not `claude-mailbox status`.
Status only reflects the autostart wrapper and silently lies
when the inner process crashed at boot.
- Capture state before changing anything (CLI version, autostart
state, port, daemon /health version) so failures can roll back
to "do nothing — old daemon keeps running".
- Detect the "daemon reachable but autostart NotInstalled" case
(manual foreground serve) and refuse to swap binaries from
under it.
- After restart, poll /health for up to 10s and verify the live
daemon's version matches LATEST; on timeout, dump the platform-
appropriate daemon log tail instead of just reporting "Stopped".
- Reorder: install first, then stop+start. Downtime is paid only
after the new binary is verified on disk.
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