Expand description
kranz hook-status — the command cursor CLI lifecycle hooks invoke
inside agent sessions (ticket
.kranz/tickets/agent-hooks-status-signals; the engine side is
kranz_engine::hook_status, which also records the verified cursor
hook surface this relays).
This is an INTERNAL plumbing command, never an operator surface: the
backend installs it into the session-private ~/.cursor/hooks.json as a
command hook on the mapped lifecycle events (sessionStart, stop,
sessionEnd, postToolUseFailure). The cursor CLI pipes the hook
payload JSON to stdin; the relay bounds the read, maps the payload to
a coarse kranz_engine::hook_status::HookSignal, and POSTs
{token, missionId, runId, signal, detail} to the loopback endpoint
named in the engine-written spec file.
Exit posture differs from kranz hook-guard ON PURPOSE: the guard is a
gate (exit 2 blocks), this relay is pure observability — EVERY failure
(unreadable spec, oversized/unparseable payload, unreachable endpoint,
rejected POST) exits 0 with a stderr note. Cursor hook semantics:
exit 2 would block the session’s action, and any other non-zero code
lands a hook-error notice in the transcript; neither is worth it for a
signal that is never mission state. The relay also runs with the
session’s already-cleared environment and reads nothing but the spec
file and stdin — no new credential or env channel (the spec’s per-run
capability token is the whole authority, and it can only write that
one run’s projection entry).
Functions§
- post_
signal - The real POST: JSON body to the spec’s loopback endpoint with a hard timeout. A non-2xx is an Err naming the status (the relay still exits 0 — the note is for the transcript/stderr, never for retry).
- run_
hook_ status - Run the relay: read the hook payload from
stdin, map it, POST the signal to the spec’s endpoint. Always returns 0 (see module docs);post_fnis the test seam scripting endpoint outcomes without a network.