Expand description
ai-crew-sync context hook --binding <id> --event <event>.
The one thing lifecycle hooks run in authenticated mode. A hook is a short-lived process with no credential of its own; this helper reads the private binding record its conversation’s proxy wrote (0700 directory, 0600 file), performs the operation with that window’s session credential, and prints only what the host expects. The credential never reaches argv, stdout, a log or a tool result (ADR 0001).
Three rules the implementation exists to keep:
- Same window, never a sibling. The binding is looked up by the host’s conversation id. A missing or unusable binding is a quiet no-op, never a fallback to a shared session or another team — a hook that drained the wrong window’s inbox would be a silent data loss.
- A hook never fences its own proxy. It sends the epoch the proxy recorded and never registers, so it cannot bump the epoch and lock out the window it belongs to.
- Presence only, no reads that move a cursor. The events here
publish presence and read context; the Stop drain still runs in the
shell script, which is where its loop guard lives. Its reads go
through
--event call, one tool call as the bound window, so an exportedBUS_TOKEN/BUS_SESSIONcan never redirect them to a sibling window’s inbox.
Enums§
- Event
- Lifecycle events this helper knows. Anything else is a caller mistake worth naming rather than a silent success.
- Hook
Host - Which host’s hook contract to answer in (#229). The events are the same; what a host reads back from a hook differs.
- Resolution
- How the binding was resolved, so
statuscan explain a silent hook.
Constants§
- HOOK_
CALL_ TOOLS - The tools
--event callserves: exactly what the hook scripts call throughbus-call.sh. Anything else is refused before the binding is even read, soresume_sessionthrough a hook cannot rotate the proxy’s credential and print the new secret. - WATCH_
WAKE_ LABEL - The label a watcher announces as this window’s wake mechanism (#221).
The plugin runs the watcher only in Claude Code, as an
asyncRewakehook.
Functions§
- resolve_
binding - run
- Run one hook event. Returns what to print on stdout: the host’s JSON for
session_start, the tool’s structured content forcall, nothing for the presence events.callnames the tool and its arguments forEvent::Calland is ignored by every other event. - run_as
run, answering inhost’s hook contract.- watch
--event watch: block until something new is addressed to this window, then return the text to wake it with.Nonewhen the deadline passes, the binding is closed or missing, or a newer watcher took over. Starting takes the window over from any earlier watcher, keeping what that one had already woken the window for; a window watched for the first time starts from what is waiting now, which its session start already said. Every read-check-write of the state file holds the configuration lock, so a replaced watcher can never overwrite its successor’s claim.