docs: document watch --block push delivery and bootstrap behavior
Adds a Push delivery (watch) section to the root README with exit-code table, cross-process semantics, and the active-vs-idle latency caveat that came out of the empirical Claude Code BashOutput test. Adds a brief reference + cross-link in node/README.md, and notes the SessionStart bootstrap behavior in plugin/README.md alongside the existing hook table. Adds /v1/watch to the REST surface table and the watch verb to the CLI listing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
README.md
31
README.md
@@ -150,6 +150,35 @@ and treat the messages as input with priority over the current plan.
|
||||
|
||||
---
|
||||
|
||||
## Push delivery (watch)
|
||||
|
||||
The `watch --block` subcommand turns mail delivery from pull (poll between turns) into push (the receiver reacts as soon as a peer sends). It's a long-poll that exits the moment one message arrives.
|
||||
|
||||
```
|
||||
claude-mailbox watch --block --name <mailbox> [--timeout 25] [--url <daemon>]
|
||||
```
|
||||
|
||||
Intended use: a Claude Code background bash task. The plugin's `SessionStart` hook now tells Claude to start one on its first turn, so peers can `mcp__mailbox__send` to it and Claude reacts mid-session via `BashOutput` — no user prompt needed. After every exit Claude relaunches the watcher in the background.
|
||||
|
||||
| Exit code | Meaning |
|
||||
|---|---|
|
||||
| `0` | One message delivered (or mailbox renamed — stdout disambiguates) |
|
||||
| `1` | Generic error (e.g. missing `--name`) |
|
||||
| `2` | Daemon unreachable |
|
||||
| `3` | Timeout reached with no message |
|
||||
|
||||
The CLI consumes exactly one message per cycle (single-delivery, FIFO winner across concurrent watchers on the same mailbox). Backlog drains one message per reconnect (~100 ms turnaround).
|
||||
|
||||
Cross-process semantics:
|
||||
- **Concurrent watchers on the same mailbox:** the first to register wins each individual message; others continue waiting.
|
||||
- **Rename mid-watch:** the open `watch` exits 0 with a `Mailbox renamed to '<new>'` notice; relaunch with the new `--name`.
|
||||
- **Daemon restart:** all watchers see exit 2; back off and retry.
|
||||
- **Session end:** Claude Code reaps background bash on exit; the `fetch` aborts and the daemon-side waiter is cleaned up.
|
||||
|
||||
**When push helps:** during active turns where the receiver is busy with tool calls — `BashOutput` notifications surface between tool calls, so peer messages arrive mid-turn. **When push degrades to pull:** when the receiver is idle between turns, BashOutput is buffered until the next user prompt, at which point the existing `UserPromptSubmit` poll hook delivers the same message. The two channels coexist.
|
||||
|
||||
---
|
||||
|
||||
## CLI
|
||||
|
||||
Any external process — scripts, UIs, manual debugging — can talk to a running daemon directly:
|
||||
@@ -158,6 +187,7 @@ Any external process — scripts, UIs, manual debugging — can talk to a runnin
|
||||
claude-mailbox send --from <mailbox> --to <mailbox> --body <text>
|
||||
claude-mailbox peek --name <mailbox>
|
||||
claude-mailbox check --name <mailbox> [--hook]
|
||||
claude-mailbox watch --block --name <mailbox> [--timeout 25]
|
||||
claude-mailbox list
|
||||
claude-mailbox status
|
||||
claude-mailbox session-announce # hook helper, reads stdin JSON
|
||||
@@ -177,6 +207,7 @@ All subcommands accept `--url <url>` to target a non-default daemon address.
|
||||
| `POST` | `/v1/send` | yes (sender) | body: `{ to, body }` |
|
||||
| `GET` | `/v1/peek?name=<mailbox>` | no | read-only status |
|
||||
| `POST` | `/v1/check-inbox?name=<mailbox>` | yes (must match `name`) | consume inbox |
|
||||
| `GET` | `/v1/watch?name=<mailbox>&timeout=<sec>` | yes (must match `name`) | long-poll one message: `200` + body / `204` timeout / `409 { reason: "renamed", to }` |
|
||||
| `GET` | `/v1/list` | optional (presence registers caller) | list all mailboxes |
|
||||
|
||||
---
|
||||
|
||||
Reference in New Issue
Block a user