Repository navigation
v0.2.0
Ships the hook from @nodrail/client 0.2.0.
What changed
Runs and steps for any agent framework, so gates and budgets work outside
Claude Code.
Breaking
- Starting a subagent in Claude Code (
Agent, andTask, its earlier name)
is now governed, as toolclaude-code, operationagent, resource type
agentwith the subagent's type as id. Without a rule that allows it, each
start waits for a person. Upgrading: add a rule that allowsclaude-code
agentfor the subagent types you use. Rule files with a rule for the
earlier resource (typetool, idAgent) no longer compile. - The Claude Code hook's run key is
NODRAIL_RUN, else<repo>/<branch>
pinned to the session by its first event, so switching branch doesn't
change the run. On the default branch, a detached HEAD or outside git it is
session:<id>. The repository is theoriginremote as host/owner/name,
with no credentials. Pins are kept in.git/nodrail/sessions.
Added
- A block says why when Cloud does: a gate tells the agent to run the steps
it waits for (such as QA or review) after the last change and try again; a
used-up budget and a paused agent are named too. createNodrail({ run }), orNODRAIL_RUN, sets the run calls belong to;
nodrail.inRun(key, work)sets it for one piece of work.nodrail.step(agent, work)records a step around an agent's work. Calls
made while it runs belong to it, through a framework's tool loop too, and
the verdict is read from the result withreceiptOf, or by your own
function passed as{ receipt }.authorize()takesrun: { key, step? }and sends it with the intent, so
the server can decide gates and budgets on the run's history. The run is not
part of the descriptor digest.client.step()records a step starting or
finishing.- The Claude Code hook sends each intent's run and step, and records
SubagentStartandSubagentStopas steps with the receipt block. Recording
a step never blocks the agent. - The Codex hook sends the run with each call. Codex doesn't say which
subagent makes a call, so every call is the main agent's. - A call that stops waiting for a person withdraws its request, so it leaves
Approvals instead of waiting there for someone to approve a call that will
never run.authorize()does it whenwaitMspasses or its newsignal
aborts, and the Claude Code and Codex hooks at their own deadline too. It is
best effort and takes at most 3 seconds; the call is blocked either way.
WithwaitMs: 0the request stays open, to be decided later.
client.withdraw(actionId)sends it by hand; it never allows anything.
Changed
- Receipts are read from the last 16 KB of a message only, and a block over
8 KB is no receipt, in the hook and inreceiptOfalike, as in Cloud.
Full history and upgrade notes: client changelog.
What's Changed
- feat: client 0.2.0 hook with run history and covered-call descriptions by @BuenClima in #8
Full Changelog: v0.1.5...v0.2.0