Expand description
Claude Code hook logic — all of it server-side.
These run behind marshal’s own plain-HTTP listener (http_listener),
not myko’s MCP endpoint: the hook command on every platform is a dumb
curl one-liner that POSTs Claude Code’s raw hook JSON and prints the
text/plain response back into the agent’s context.
curl -sS --max-time 5 -X POST \
"$URL/hook/session-start?host=$(hostname -s)&operator=$USER" \
--data-binary @- || trueNo client-side scripts, no jq/bash, no per-platform port — the register / fetch / ack / format work happens here, once, in Rust.
host / operator ride in the query string because the daemon is
remote and can’t know the client’s hostname or user; the curl
command expands them locally (the only platform-specific bit, $VAR
vs %VAR%). Everything else (session_id, cwd) is in the hook body.
Caller identity for the read/ack commands is carried by the commands’
asSession field (self-identify), since this internal context has no
WS client_id.
Structs§
- Hook
Outcome - A hook’s HTTP response body, plus any inbox ack that must be deferred until the response is confirmed written back to the caller.
Functions§
- ack_
surfaced - Ack the messages a hook surfaced, AFTER its response was written. Called by the listener on write success so a lost/timed-out response can’t lose messages (they stay unread and re-surface). Fail-loud: a failed ack is logged, not silently swallowed.
- dispatch
- Dispatch a POST to a
/hook/*path. ReturnsSome(outcome)for a known hook route — the listener writesoutcome.bodyas thetext/plainbody, then runsoutcome.deferred_ack— orNonefor an unknown path (→ 404).