manishkumar/reins/tree/main/mods/reins-status
reins-status
reins 프로젝트의 읽기 전용 Claude Code mod로, Claude Code 안에 hold 대기열을 표시합니다. 상태 표시줄의 개수와 함께 프롬프트 위 띠에서 보류된 모든 작업과 전체 입력을 보여 줍니다. 대기열에 답하지는 않으며, 승인은 계속 reins approve와 reins watch에서 수행합니다.
이 mod 소개
reins-status는 reins와 함께 제공되는 실험적 읽기 전용 Claude Code mod입니다. reins는 사람이 지켜보지 않는 Claude Code 에이전트를 로컬 우선 방식으로 관리하는 도구입니다. reins init --mod(먼저 npm install -g @manishky/reins 실행)로 설치하면 대화 옆에 /reins 패널을 열어 모든 hold와 전체 입력을 나열하고 상태 표시줄에 대기 중인 개수를 보여 줍니다. 승인 버튼은 의도적으로 제공하지 않습니다. 대기된 작업의 승인이나 거부는 계속 reins approve 또는 reins watch로 수행하므로, 이 mod는 관찰만 담당합니다.
부모 프로젝트는 Claude Code hooks를 사용해 위험한 작업을 나중에 승인하도록 보류하고, 명령이나 경로를 거부하며, 실행 중인 에이전트를 다음 도구 호출에서 유도하고, 반복되는 도구 루프에 경고를 보내고, 에이전트가 주장한 「완료」를 실제로 실행한 테스트와 빌드로 확인합니다. 모든 내용은 .reins/ 아래의 일반 파일과 로컬 SQLite 데이터베이스에 저장되며 네트워크 호출이나 계정이 필요하지 않습니다.
mod 제출물은 검증되었습니다. hooks 모듈(hooks/register.tsx)이 있는 .claude-plugin/plugin.json manifest가 포함되어 있고, 스캔도 성공적으로 끝나 .reins 디렉터리에 대한 파일 읽기 작업만 발견했습니다. README에는 Claude Code mod가 reins 자체의 PreToolUse hooks보다 위에서 실행된다는 점과 mod API가 early access라서 어느 릴리스에서든 바뀔 수 있다는 점도 적혀 있습니다.
설치
먼저 작성자의 README에서 marketplace와 플러그인 이름을 확인하세요. 저장소 구조에 따라 명령어가 달라질 수 있습니다.
claude plugin marketplace add manishkumar/reins claude plugin install reins-status
원문 / README
🐎 reins
Keep control of Claude Code agents you aren't watching
Hold risky actions for your approval · block what must never run · see every agent on one screen · nudge one mid-run
Install · First run · What it does · Before you rely on it · Commands
</div> <p align="center"> <img src="assets/cockpit-review-queue.svg" alt="reins watch after an overnight run: two held actions and a worked-around guard under NEEDS YOU, six agents listed with a looping one first, and the detail of a held terraform apply showing its rule, reason, session, how long it has waited and the full proposed command with the matched line lifted above it" width="960"> </p> <p align="center"><sub><code>reins watch</code> after an overnight run. Two actions are held for approval, one agent is looping, and the line that tripped the rule is lifted out of a nine-line command. Rendered by the cockpit's own renderer from a scripted scenario (<code>assets/cockpit-demo-frame.cjs</code>).</sub></p>Local-first. No daemon, no backend, no account. Nothing leaves your machine.
Why this exists
An agent works for hours while you do something else, or overnight. At some point it reaches a deploy, a publish or a push to main. Without reins you have two choices: let it run actions nobody approved, or stay at the terminal to answer every prompt.
reins gives you a third, built from Claude Code hooks. The risky action is parked, the agent carries on with other work, and you decide when you are back:
# the agent, at 02:14, nobody watching
⏺ Bash(npm publish)
[reins] ⏸ HELD npm publish
approve: reins approve ab12cd34 · see all: reins pending
# you, in the morning
$ reins pending
ab12cd34 7h 3b9f2a1c Bash npm publish [bash-npm-publish]
$ reins approve ab12cd34
✓ Approved ab12cd34 (Bash: npm publish)
The approval clears that exact call, once. It permits the retry and does not run anything itself: a still-running agent is told to retry, and a session that has ended needs resuming.
| When | What | Hardness | |---|---|---| | Before a tool runs | Hold: park the action in a queue until you approve it | Your call, later | | Before a tool runs | Guard: deny a command or path, or ask you at the prompt | Hard veto, or your call | | Any time | Cockpit: every agent and everything waiting on you, on one screen | Observe and decide | | During the run | Steer: add a one-line note the agent reads at its next tool call | Soft. The model weighs it | | After each tool | Loop alarm: warn when the same call repeats in a row | Warn | | When a turn ends | Claim check: compare "done" with the tests and builds the session ran | Report | | Always | Capture: every run in a SQLite file you own | Observe |
The story behind it: I Built a Tool to Steer Running AI Agents. It Taught Me Where Their Real Cost Is.
Install
npm install -g @manishky/reins
reins version
npm install -g github:manishkumar/reins works too. For a local checkout: git clone, then npm install && npm run build && npm link.
Requires Node ≥ 18. Capture needs SQLite, which is built in from Node 22.5. Steering, guards and holds work without it. See compatibility.
First run
cd your-project
reins init # creates .reins/ and merges the hooks into .claude/settings.json
Restart Claude Code in the project so it loads the hooks. reins init merges into your settings and never overwrites them. reins init --print prints the block instead, and reins init --local writes to settings.local.json.
Then add a rule for something you want to sign off, start any task in Claude Code, and open the cockpit in another terminal:
reins guard add bash "npm publish" --hold # park it for approval
reins watch # every agent, and everything waiting on you
Run reins doctor to check the setup: it reports the hooks, the Claude Code version, and whether a hook has run since the settings changed.
What it does
Hold: approval for the run nobody is watching
A hold rule parks the proposed action in a queue and lets the agent carry on with other work. The action does not run until you approve it.
reins guard add bash "git push" --hold # hold any push for approval
reins pending # what did the agents want to do?
# ab12cd34 7h 3b9f2a1c Bash git push origin main [bash-git-push]
reins approve ab12cd34 # clears that exact call, once
reins deny ab12cd34 --steer "open a PR instead of pushing to main"
An approval is bound to one proposal: the same input, from the same session and directory, one time. A changed retry parks again.
<p align="center"> <img src="assets/hold-queue.svg" alt="The full hold-queue loop: a hold rule parks the agent's npm install and shows you a one-line HELD notice with the approve command, reins pending lists it, reins approve signs it off, and the agent's retry runs at its next tool boundary" width="720"> </p>Transports, breach reporting and every caveat: docs/holds.md.
The cockpit: reins watch
One screen shows every agent in the repo and everything waiting on you. From it you approve or deny held actions and steer one agent or all of them. It is the control surface for unattended and headless runs and for several agents at once.
<p align="center"> <img src="assets/cockpit-agent.svg" alt="reins watch with a long-running agent selected: the detail pane shows what it was asked, its branch, its claim check verdict, the files it edited by directory, the commands it ran, and its trajectory newest first" width="960"> </p> <p align="center"><sub>A long-running agent, selected. The detail pane puts what it was asked beside what it edited and ran.</sub></p> <p align="center"> <img src="assets/cockpit-approve.svg" alt="reins watch approve dialog: 'Approve this exact call, once?' with the rule, reason, session, directory and the exact input, the matched line marked, and y to approve or esc to cancel" width="960"> </p> <p align="center"><sub>Approving. The dialog shows the whole input, marks the line the rule matched, and keeps <code>y</code> locked until you have scrolled to the end.</sub></p>- Looping agents are listed first, then agents with a held action, then the rest newest first.
- Approving in the cockpit runs the same code as
reins approve. The action is re-read when you pressy, and nothing is approved if it changed. - The selection never moves on its own, so a new hold cannot slide under your cursor.
- Nothing listens on a port.
reins watch --onceprints a plain snapshot for scripts.
Keys, layout and caveats: docs/watch.md.
Guard
A guard matches a Bash command, a file path or a tool name before the call runs. Besides hold, it can deny the call outright or ask you at the prompt:
reins guard add bash "psql.*production" # deny: the call does not run
reins guard add bash "git push" --ask # ask: Claude Code shows you its permission prompt
reins guard add bash "npm publish" --hold # hold: park it for your later approval
reins guard add path "infra/**" # block writes to paths
reins guard add tool "mcp__stripe__*" --ask # match MCP tools by name
reins guard list
A deny holds under --permission-mode bypassPermissions. reins ships a default denylist: recursive rm outside build and scratch directories, force pushes, git reset --hard, DROP/TRUNCATE, curl … | sh, and writes to .env* and .git/**. reins scan proposes rules from your repo's own manifests, and reins policy upgrade refreshes shipped rules while keeping yours.
Details, the measured false-positive rate, and reins audit --guards: docs/guards.md.
Steer
reins steer "<message>" queues a note for the next tool call. Two steers before that call both arrive. If the agent is already finishing and there is no next tool call, the Stop hook delivers the note, so a queued steer is not lost.
# terminal 1: the agent is mid-task and drifting
⏺ Edit(src/login/flow.ts)
# terminal 2: you, without ending the run
$ reins steer "focus on the token refresh path, leave the login flow alone"
✓ queued — lands at the agent's next tool call
# terminal 1: next tool call, same run, context intact
⏺ [reins — live steering from the developer] folded in
⏺ Edit(src/auth/refresh.ts)
Treat a steer as the detail you forgot to put in the prompt. A steer that contradicts the prompt is weighed down by the model. For a hard "never do X", use a guard.
With several agents in one repo, reins steer asks which one you mean, or takes --session <name>.
Details and caveats: docs/steering.md.
Loop alarm
When the agent runs the same tool with identical input three times in a row, reins adds a warning at that tool call and records the loop. Re-running npm test after each edit does not count; the same call with nothing in between does. reins loops lists the sessions, and "loopThreshold" in .reins/config.json tunes it.
Claim check and footprint
When a turn ends, reins compares what the session did with its own tool calls:
[reins] Claim check: the last test run failed (npm test). reins lastrun lists the calls.
The verdicts are failed, stale (files edited after the last run), unverified (edits and no run), unknown (a run whose result reins cannot see) and verified. It reports and never blocks. The footprint lists what a session edited and ran beside the prompt it was given, and leaves the comparison to you.
What it can and cannot see: docs/claim-check.md.
Capture and the report
reins lastrun # a readable account of the last run
reins sessions # recent sessions, by title and name
reins audit # every gate decision
reins report --open # one self-contained HTML file, no network requests
Runs are stored in .reins/runs.db, three tables you can query with SQL. REINS_NO_SQLITE=1 turns capture off; steering, guards and holds keep working.
More: docs/capture.md.
Inside Claude Code: the status mod (experimental)
reins init --mod installs a read-only Claude Code mod. /reins opens a pane beside the conversation with every hold and its full input. The status line shows the count. It has no approve button: approving stays in reins approve and reins watch.
Caveats: docs/mods.md.
Before you rely on it
These are the limits that decide whether reins fits your use. Each links to the full text.
- Guards are speed bumps, not a sandbox. They match the form of a command, not its intent. An agent blocked from
rm -rf foocan delete another way. For a determined or adversarial agent, use OS-level sandboxing. docs/guards.md - Steering lands at the next tool call, and the model weighs it. It is added spec, and it does not reverse the prompt. docs/steering.md
- A hold uses deny-and-queue by default. The
defertransport is opt-in, because Claude Code honors it only in print mode and only for a solo tool call. A held action that ran anyway is reported as a HOLD BREACH after the fact. docs/holds.md - A crashing hook fails open. A bug in reins never stops your agent, which also means a guard does not run if the hook itself errors. The hold gate is the exception: if parking fails, the call is denied.
- Claude Code older than 2.0.56 loads no hooks from a settings file that names
PostToolUseFailure.reins initleaves that hook out unless it can confirm your version, andreins doctortells you whether a hook has actually run. docs/compatibility.md - The claim check reads command text and exit status. A passing run is the agent's own run. It does not mean the tests cover the change. docs/claim-check.md
- The mod API is early access and can change in any Claude Code release. docs/mods.md
Local-first
reins makes zero network calls. No telemetry and no account. Your trajectories live in a SQLite file on your disk that you can read, query, back up or delete. The steering queue, the policy, the hold queue and the decisions are plain files under .reins/, so they work without the database.
Security / threat model
.reins/steering.txt is security-sensitive: write access to it equals steering access. Anything that can write that file can inject context into your running agent at its next tool call. reins creates .reins/ as 0700 (owner-only) and git-ignores it, but be deliberate:
- Do not let an untrusted or automated writer feed it. A CI job, a shared script, or any process you don't fully control writing to
.reins/steering.txtis a hijack path into your agent. Treat write access to that file as you'd treat write access to your prompts. - Steering is a soft channel — the model still weighs it and resists outright contradictions — so this is defense-in-depth, not a sole control. v1 ships no signing on the steering file; the mitigations are filesystem permissions (
0700) and not pointing untrusted writers at it. .reins/decided/is approval access. One-shot hold decisions — approvals and refusals — are files there; anything that can write them can pre-approve (or fake-refuse) a parked action. Same posture, same mitigations.
Guards, separately, are not a containment boundary (see what guards are and are not).
A Claude Code mod runs above reins. From Claude Code 2.1.287, a mod's tool.call hook runs before any PreToolUse command hook, reins included (measured in docs/mods-probe.md). A mod can rewrite a command before reins reads it, in which case reins matches, parks and approves the rewritten command, the one that would run. A mod can also answer a tool call itself, and then no PreToolUse hook runs and reins sees nothing. A mod is code you installed in your own Claude Code, so this is the same trust as any other local code. reins does not detect it.
A crashing hook fails open (the agent proceeds) so a bug in reins can never wedge your agent — which also means guards are best-effort if the hook itself errors.
Command reference
reins init [--print|--local] Set up .reins/ and wire (or print) the hooks
reins init --mod Also install the read-only status mod
reins init --failure-hook Write PostToolUseFailure when the Claude Code
version can't be read (needs 2.0.56+)
reins uninstall [--purge] Remove the hooks (--purge also drops .reins/)
reins doctor Diagnose your setup
reins steer "<msg>" [--replace] Queue steering for the next tool call (appends;
several live agents + a TTY → a picker asks which)
reins steer "<msg>" --session <id|name> Target one agent (id/prefix/name/mnemonic)
reins steer "<msg>" --broadcast Skip the picker; whichever agent moves next gets it
reins steer [--clear] Show / clear pending steering
reins name <session> "<label>" Name a session; --clear reverts to the auto mnemonic
reins guard list|add|remove|reset (add takes --ask to escalate, --hold to park)
reins scan [--accept] Propose rules for what THIS repo can destroy
reins policy upgrade [--apply] Refresh shipped rules, keeping yours and your edits
reins policy version Your policy generation vs the shipped one
reins pending List actions parked by hold rules
reins approve <id> Approve a parked action (one-shot, exact call)
reins deny <id> [--steer "..."] Refuse a parked action, optionally steer instead
reins audit [session] [--json] Every gate decision (deny/ask/hold/allow/breach/bypass)
reins audit --guards [--json] Were the guards right? Every denial ever recorded,
scored: stale rules, and vetoes worked around anyway
reins lastrun [session] Readable account of a run (id prefix or name)
reins sessions [-n N] List recent sessions (with names)
reins watch [-n SECS] [--once] [--quiet] Cockpit: approve/deny holds, steer agents
reins report [--open] [-o FILE] Self-contained local HTML report of all runs
reins loops Sessions where the agent looped
reins hook pre-tool|post-tool|post-tool-failure|stop (invoked by Claude Code, not you)
Documentation
| | |
|---|---|
| Steering | Delivery, the two caveats, several agents in one repo |
| Guards | Rules, --ask, the default denylist, what guards cannot do, audit --guards, scan, policy upgrade |
| Holds | The approval queue, transports, one-shot approvals, HOLD BREACH |
| The cockpit | reins watch: panes, keys, approving, narrow terminals |
| Claim check and footprint | Verdicts, and what the check can and cannot see |
| Capture and the report | lastrun, sessions, report, the SQLite schema |
| The status mod | The /reins pane inside Claude Code |
| Compatibility | Node versions, Claude Code versions, the PostToolUseFailure hook |
| How it works | The hooks, the files under .reins/, testing a hook by hand |
| SPEC.md | File formats and decision semantics, vendor-neutral |
Contributing
See CONTRIBUTING.md. Keep it small and sharp.
<div align="center">
MIT · no daemon, no backend, no account — just hooks, and files you own
</div>