pitroom 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/.claude-plugin/marketplace.json +18 -0
  2. package/.claude-plugin/plugin.json +22 -0
  3. package/.codex-plugin/plugin.json +29 -0
  4. package/CHANGELOG.md +85 -0
  5. package/LICENSE +21 -0
  6. package/README.md +471 -0
  7. package/dist/lib.mjs +1222 -0
  8. package/dist/pitroom.mjs +3685 -0
  9. package/docs/backends.md +113 -0
  10. package/hooks/hooks.json +28 -0
  11. package/hooks/session-start.mjs +42 -0
  12. package/package.json +60 -0
  13. package/skills/pitroom-brainstorming/SKILL.md +243 -0
  14. package/skills/pitroom-brainstorming/spec-document-reviewer-prompt.md +22 -0
  15. package/skills/pitroom-crew/SKILL.md +80 -0
  16. package/skills/pitroom-debugging/SKILL.md +287 -0
  17. package/skills/pitroom-debugging/condition-based-waiting-example.ts +170 -0
  18. package/skills/pitroom-debugging/condition-based-waiting.md +115 -0
  19. package/skills/pitroom-debugging/defense-in-depth.md +122 -0
  20. package/skills/pitroom-debugging/find-polluter.sh +72 -0
  21. package/skills/pitroom-debugging/root-cause-tracing.md +169 -0
  22. package/skills/pitroom-driven-development/SKILL.md +138 -0
  23. package/skills/pitroom-driven-development/implementer-prompt.md +68 -0
  24. package/skills/pitroom-driven-development/re-review-prompt.md +41 -0
  25. package/skills/pitroom-driven-development/task-reviewer-prompt.md +59 -0
  26. package/skills/pitroom-finishing/SKILL.md +226 -0
  27. package/skills/pitroom-implement/SKILL.md +42 -0
  28. package/skills/pitroom-receiving-review/SKILL.md +209 -0
  29. package/skills/pitroom-research/SKILL.md +35 -0
  30. package/skills/pitroom-review/SKILL.md +47 -0
  31. package/skills/pitroom-review/code-reviewer.md +38 -0
  32. package/skills/pitroom-tdd/SKILL.md +322 -0
  33. package/skills/pitroom-tdd/writing-good-tests.md +198 -0
  34. package/skills/pitroom-verification/SKILL.md +124 -0
  35. package/skills/pitroom-worktrees/SKILL.md +171 -0
  36. package/skills/pitroom-writing-plans/SKILL.md +183 -0
  37. package/skills/pitroom-writing-plans/plan-document-reviewer-prompt.md +23 -0
  38. package/skills/using-pitroom/SKILL.md +66 -0
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "pitroom",
3
+ "description": "Pitroom: cheap worker agents for your primary coding agent",
4
+ "owner": {
5
+ "name": "TahaAtas"
6
+ },
7
+ "plugins": [
8
+ {
9
+ "name": "pitroom",
10
+ "description": "Delegate research, fixes, tests and parallel investigations to cheap OpenCode, Codex or Claude Code workers, with verified answers, exact diffs and cost receipts.",
11
+ "version": "0.6.0",
12
+ "source": "./",
13
+ "author": {
14
+ "name": "TahaAtas"
15
+ }
16
+ }
17
+ ]
18
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "pitroom",
3
+ "description": "A free pit crew for your expensive coding agent: the superpowers development workflow, run by cheap workers. Delegate research, fixes, tests, reviews and whole plans from Claude Code, Codex or any agent to OpenCode, Codex or Claude Code workers, with receipts that prove the savings.",
4
+ "version": "0.6.0",
5
+ "author": {
6
+ "name": "TahaAtas"
7
+ },
8
+ "homepage": "https://github.com/ATASTECH/pitroom",
9
+ "repository": "https://github.com/ATASTECH/pitroom",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "claude-code",
13
+ "codex",
14
+ "cost",
15
+ "delegation",
16
+ "opencode",
17
+ "parallel",
18
+ "subagents",
19
+ "tokens",
20
+ "workers"
21
+ ]
22
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "pitroom",
3
+ "version": "0.6.0",
4
+ "description": "A free pit crew for your expensive coding agent: delegate research, fixes, tests and parallel investigations to cheap OpenCode, Codex or Claude Code workers, with verified answers, exact diffs and cost receipts.",
5
+ "author": {
6
+ "name": "TahaAtas"
7
+ },
8
+ "homepage": "https://github.com/ATASTECH/pitroom",
9
+ "repository": "https://github.com/ATASTECH/pitroom",
10
+ "license": "MIT",
11
+ "keywords": [
12
+ "claude-code",
13
+ "codex",
14
+ "cost",
15
+ "delegation",
16
+ "opencode",
17
+ "parallel",
18
+ "subagents",
19
+ "workers"
20
+ ],
21
+ "skills": "./skills/",
22
+ "hooks": {},
23
+ "interface": {
24
+ "displayName": "Pitroom",
25
+ "shortDescription": "Cheap OpenCode, Codex or Claude Code workers for research, fixes and parallel tasks",
26
+ "longDescription": "Pitroom lets the primary agent hand bounded work to OpenCode, Codex or Claude Code workers running the user's own free, paid or local models: read-only research, isolated code changes, second-opinion reviews and parallel crews, with per-run permission profiles, a git guard, verified file references, exact diffs and cost receipts.",
27
+ "category": "Developer Tools"
28
+ }
29
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,85 @@
1
+ # Changelog
2
+
3
+ ## 0.6.0
4
+
5
+ ### Workflow skills
6
+ Pitroom now ships a complete development workflow, adapted from [superpowers](https://github.com/obra/superpowers) so that its subagents are Pitroom workers (Credits in the README): `pitroom-brainstorming`, `pitroom-writing-plans`, `pitroom-driven-development`, `pitroom-worktrees`, `pitroom-review`, `pitroom-receiving-review`, `pitroom-finishing`, `pitroom-debugging`, `pitroom-tdd` and `pitroom-verification`, next to `pitroom-research`, `pitroom-implement` and `pitroom-crew`. `using-pitroom` is the bootstrap for all of them. `pitroom doctor` warns when superpowers is installed too.
7
+
8
+ ### Plan execution
9
+ - `pitroom run -i --plan PLAN --step N`: the worker gets the implementer rules, the plan's context and Global Constraints and exactly one task; its `STATUS:` line (DONE, DONE_WITH_CONCERNS, NEEDS_CONTEXT, BLOCKED) is recorded. Runs join the plan's group.
10
+ - `pitroom review <run>`: a read-only reviewer, by default on another backend, reads one package (brief, report, diff with context) and returns SPEC and QUALITY verdicts. Reviewing a follow-up is a scoped re-review (previous findings, fix report, only the fix diff). `pitroom review --range A..B [--plan PLAN]` reviews a branch with the plan and the notes from execution.
11
+ - `pitroom plan status PLAN` rebuilds a plan's progress from the run records; `pitroom plan note PLAN "…"` records completions, deferred findings and rulings outside the repo.
12
+ - Config `tiers` (`{"cheap": "opencode", "standard": "codex", "capable": "claude"}`) and `--tier NAME`; plan tasks pick their tier with a `**Worker:**` line.
13
+
14
+ ## 0.5.0
15
+
16
+ ### New workers
17
+ - **Codex CLI** (`-W codex`, `codex:<model>`, `codex:<model>#<effort>`): `codex exec --json` with Codex's OS sandbox (`read-only` for read, `workspace-write` for write/isolate), approvals off, `~/.codex/config.toml` ignored (its MCP servers would run outside the sandbox), resume by session id, model read from the session's rollout file. Verified on real runs: read (sandbox refused a write), isolate + follow-up + apply.
18
+ - **Claude Code** (`-W claude`, `claude:haiku`…): `claude -p --output-format stream-json` with `--safe-mode --restricted --strict-mcp-config`, `--permission-mode dontAsk` and an explicit tool allowlist (`Read,Grep,Glob` for read; `+Edit,Write,Bash` with git/destructive commands disallowed for write), `.env`/key files denied, resume by session id, cost reported. `doctor` checks the login and warns about Opus-class defaults. Verified on real runs (`claude:haiku`): the read worker was granted exactly `Glob, Grep, Read` with no user MCP servers or plugins; isolate + follow-up in the same session + apply.
19
+ - Gemini CLI is recognised as "soon".
20
+ - Config `models`: a default model per worker (`{"codex": "gpt-6.1-sol", "claude": "claude-sonnet-5-5"}`) for targets that name none, including fallbacks; a model in the target or `-m` wins. `pitroom config` and `doctor` show it.
21
+ - Fallback chains cross backends (e.g. Claude Code logged out → OpenCode); a group can mix workers.
22
+
23
+ ### Safety
24
+ - **Git guard layer 2** for every worker: git's own env config (`GIT_CONFIG_*`) installs a `reference-transaction` hook that refuses every ref update (commit, reset, branch/tag, stash, rebase, merge; `--no-verify` cannot skip it) and rewrites every push URL to an unreachable one. It holds where the PATH shim does not: login shells (Codex runs `zsh -lc`, macOS `path_helper` reorders PATH), absolute `/usr/bin/git`, scripts.
25
+
26
+ ### Fixes
27
+ - Worker CLIs that are Node scripts (npm installs of Codex, OpenCode) run on Pitroom's own Node 18+, not whatever `env node` finds first on PATH.
28
+ - Run records from before pluggable workers no longer crash `pitroom ls`.
29
+
30
+ ## 0.4.0
31
+
32
+ ### OpenCode v2
33
+ - The OpenCode adapter targets OpenCode v2 (`doctor` fails on v1 with an upgrade hint).
34
+ - **Security fix:** every run uses `opencode run --standalone`. Without it, v2 attaches to the shared background service and the per-run permission profile and git guard would not apply to the worker. Asserted by the contract tests for every mode.
35
+ - Removed v1-only `--dir`; message passed last; `--log-level error`.
36
+ - Profiles: `shell` gets the same rules as `bash`; v2's `execute` tool (browser automation, OpenCode API) is denied; v2 scratch directories allowed.
37
+ - Parser: v2 events (no `tokens.total`, `{type, message, status}` errors, `Permission denied: <tool>`); default model from `debug config` sources; model of a run from `session export`.
38
+ - `403 FreeTierError` from OpenCode Zen free models counts as `auth`, so the fallback chain moves on.
39
+ - Workers run with `OPENCODE_DISABLE_AUTOUPDATE=1`.
40
+ - **Security fix:** v2 takes its workspace from `$PWD`, not the process cwd, so a worker could edit the directory pitroom was launched from instead of its isolated copy (or its `-d DIR`). Every worker now gets `PWD` set to its directory; the fake OpenCode used in tests reproduces the behaviour and the isolate tests fail without the fix.
41
+ - Real v2 streams recorded as contract-test fixtures.
42
+
43
+ ### Crews (parallel workers)
44
+ - `pitroom crew [-i] -g NAME "task" …` starts several background workers as a group (`--task-file` with `---` separators).
45
+ - `pitroom watch [-g NAME] [--json]`: live table, or one JSON line per change (`queued`, `started`, `progress`, `fallback`, `done`…, `all-done`) for agents to follow.
46
+ - `pitroom wait` takes several runs or `-g NAME`, with `--any` and `--brief`; `status`, `ls`, `stop` and `apply` accept `-g NAME`. `apply -g` lands isolate patches in order and stops at the first conflict.
47
+ - Queue: at most `maxParallel` workers (default 4, `PITROOM_MAX_PARALLEL`) run at once; new state `queued`.
48
+ - Write lock: one `--write` run per repository; parallel changes use `--isolate`.
49
+
50
+ ### Isolation
51
+ - `--isolate` now runs in a standalone repository that reads your objects through `alternates`, instead of a linked `git worktree`: nothing is written into your repository (no dangling commit, no worktree registration), and no worker CLI can map the copy back to your checkout. Removing it is deleting a folder.
52
+
53
+ ### Skills and packaging
54
+ - The single skill became a pack: `using-pitroom` (when to delegate, which skill) plus `pitroom-research`, `pitroom-crew`, `pitroom-implement`, `pitroom-review`.
55
+ - Claude Code plugin (`.claude-plugin/`) with a SessionStart hook that injects `using-pitroom`; Codex plugin manifest (`.codex-plugin/`). `dist/` is committed so plugins work from a clone.
56
+ - `pitroom install` / `uninstall` replace `install-skill`: skills go to `~/.agents/skills` and `~/.claude/skills`, and a launcher to `~/.local/bin/pitroom` that picks a Node 18+ even when an older Node is first on PATH.
57
+ - `doctor` checks every skill, the launcher, and warns when the skills are installed both as links and as a plugin.
58
+
59
+ ### Internals
60
+ - CLI split into `src/cli.ts`, `src/cli/args.ts`, `src/cli/commands.ts`.
61
+ - Reference verification: a range inside a named function counts for that function; identifiers between two references are not guessed.
62
+
63
+ ## 0.3.0
64
+
65
+ - **Worker adapters**: the core (safety, snapshots, reference checks, receipts, fallback) no longer knows any particular CLI. Workers implement one `Backend` interface (`src/backends/types.ts`); OpenCode is the first adapter. Codex, Claude Code and Gemini CLI are designed for (see `docs/backends.md`) and will be added as adapters.
66
+ - **Targets** `backend[:model]` everywhere: `-W/--worker`, config `worker` and `fallback`, env `PITROOM_WORKER` / `PITROOM_FALLBACK`. Bare models still mean "the preferred worker's backend"; models containing `:` stay intact.
67
+ - Fallback chains may span backends; `--continue` stays on the backend that owns the session.
68
+ - Every worker runs through one process runner: closed stdin, git guard, recursion guard, timeouts.
69
+ - Adapter contract tests run automatically for every registered backend, against real recorded event streams.
70
+ - `doctor` shows the worker chain and how each worker enforces read-only runs.
71
+ - Breaking (pre-release): config `model`/`fallbackModels` → `worker`/`fallback`; `PITROOM_FALLBACK_MODELS` → `PITROOM_FALLBACK`; `PITROOM_OPENCODE` → `PITROOM_OPENCODE_BIN`.
72
+
73
+ ## 0.2.0
74
+
75
+ - **Reference verification**: every `path:line` in the worker's answer is checked against disk (file exists, line/range in bounds, the named symbol is nearby) and summarised as `refs: N/M verified`.
76
+ - **Model fallback chain**: `fallbackModels` (config) / `PITROOM_FALLBACK_MODELS` (env); on "model not found", rate-limit, quota or provider-unavailable errors before any work was done, the run retries on the next model. `--no-fallback` disables it. Attempts are recorded and shown.
77
+ - **Git guard**: a `git` shim first on the worker's PATH blocks commit/push/reset/checkout/stash/clean/rebase/merge, index changes, ref deletion and similar, including through `sh -c`, `env`, scripts and aliases. Git never waits for a password, editor or pager.
78
+ - **Config file**: `~/.config/pitroom/config.json` (`model`, `fallbackModels`, `timeout`, `primary`, `price`, `link`, `web`) and `pitroom config` to show effective values and their source.
79
+ - **Web off by default**: `webfetch`/`websearch` need `--web`.
80
+ - `pitroom doctor` checks the config, the git guard and fallback models, and suggests free models from your own OpenCode catalogue.
81
+ - Runs that never reached a model are no longer counted in `pitroom savings`.
82
+
83
+ ## 0.1.0
84
+
85
+ - First release: `pitroom run` in read / write / isolate modes, permission profiles injected per run, exact change tracking with revert/apply, background runs, receipts and `pitroom savings`, `pitroom doctor`, the `pitroom` skill.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 the Pitroom contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,471 @@
1
+ <div align="center">
2
+
3
+ # Pitroom
4
+
5
+ ### A free pit crew for your expensive coding agent
6
+
7
+ **Send the reading, fixes, tests and reviews to cheap workers. Keep the decisions.**
8
+
9
+ Model-agnostic · Verified answers · Receipts, not vibes · OpenCode / Codex / Claude Code workers
10
+
11
+ <br />
12
+
13
+ [![Release](https://img.shields.io/github/v/release/ATASTECH/pitroom?label=release)](https://github.com/ATASTECH/pitroom/releases/latest)
14
+ [![Downloads](https://img.shields.io/github/downloads/ATASTECH/pitroom/total?label=downloads)](https://github.com/ATASTECH/pitroom/releases)
15
+ [![Stars](https://img.shields.io/github/stars/ATASTECH/pitroom?style=flat&label=stars)](https://github.com/ATASTECH/pitroom/stargazers)
16
+ [![CI](https://github.com/ATASTECH/pitroom/actions/workflows/ci.yml/badge.svg)](https://github.com/ATASTECH/pitroom/actions/workflows/ci.yml)
17
+ [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
18
+
19
+ <br />
20
+
21
+ **[Quick start](#quick-start)** ·
22
+ [Workflow](#workflow) ·
23
+ [Skills](#skills) ·
24
+ [Commands](#commands) ·
25
+ [Workers](#workers) ·
26
+ [Write an adapter](docs/backends.md)
27
+
28
+ <br />
29
+
30
+ <img src="docs/pitroom-hero.png" alt="Pitroom — a free pit crew for your expensive coding agent. Orange Claw’d and a blue terminal-faced Codex pet work together at a coding terminal." width="94%" />
31
+
32
+ <br />
33
+
34
+ **Your agent decides · Cheap workers do the typing · A second model reviews**
35
+
36
+ </div>
37
+
38
+ > **Current version: 0.6.0.**
39
+
40
+ ---
41
+
42
+ ## Why Pitroom?
43
+
44
+ Claude Code, Codex and friends spend premium tokens *reading*: grepping, opening files, scanning code they'll never quote.
45
+
46
+ Pitroom goes one step further:
47
+
48
+ > **Your agent stays in the driver's seat. A pit crew of cheap workers does the legwork, and hands back only the answer, the exact diff and a receipt.**
49
+
50
+ <table>
51
+ <tr>
52
+
53
+ <td width="25%" valign="top">
54
+
55
+ ### Your model, not ours
56
+
57
+ No model is hardcoded.
58
+
59
+ Pitroom uses your worker CLI's default model: a free tier, a local MLX/Ollama model or a cheap paid one. Switch there and Pitroom follows.
60
+
61
+ </td>
62
+
63
+ <td width="25%" valign="top">
64
+
65
+ ### Any worker CLI
66
+
67
+ OpenCode, Codex CLI and Claude Code today, Gemini CLI soon.
68
+
69
+ One group can mix them, and a fallback chain can cross them ([how adapters work](docs/backends.md)).
70
+
71
+ </td>
72
+
73
+ <td width="25%" valign="top">
74
+
75
+ ### Verified answers
76
+
77
+ Every `path:line` a worker cites is checked on disk.
78
+
79
+ Your agent trusts what checks out and skips re-reading it.
80
+
81
+ </td>
82
+
83
+ <td width="25%" valign="top">
84
+
85
+ ### Safe by construction
86
+
87
+ No commit, push, reset or bulk delete. A git guard stops the tricks.
88
+
89
+ In isolate mode nothing reaches your tree until you apply it.
90
+
91
+ </td>
92
+
93
+ </tr>
94
+ </table>
95
+
96
+ ### And more
97
+
98
+ - **Receipts, not vibes.** Tokens the worker burned, tokens returned to your agent, compression ratio, and an estimate of what your primary model would have charged. `pitroom savings --card card.svg` makes a shareable card.
99
+ - **Self-healing worker chain.** Free models get rate-limited or retired. List fallback workers once (`fallback`) and a run that hits "model not found", 429 or quota errors moves to the next model automatically. Still no model hardcoded: the chain is yours.
100
+ - **A crew, not just one worker.** `pitroom crew` starts several workers at once, `pitroom watch --json` streams one line per change so your agent follows them live, `pitroom wait -g` collects every answer, `pitroom apply -g` lands isolated patches in order. A queue (`maxParallel`) keeps free tiers from rate-limiting you; parallel writers are refused.
101
+ - **Exact changes, even in a dirty tree.** Pitroom snapshots the working tree with a throwaway git index (your index, branches and stash are never touched), so it reports *only the worker's* edits and can undo exactly those: `pitroom revert <id>`.
102
+ - **Real isolation.** `--isolate` runs the worker in a private copy of your **current** state (its own repository, sharing your objects read-only), uncommitted and untracked files included, then hands you a patch: `pitroom apply <id>` (checked, refuses on conflict) or `pitroom discard <id>`.
103
+ - **Zero repo pollution.** No `.pitroom/` folder, no `.gitignore` edits, no branches. Records live in `~/.local/state/pitroom`.
104
+ - **Works with any agent.** Fourteen [Agent Skills](https://agentskills.io): the superpowers development workflow run by workers, plus delegation (`using-pitroom`, `pitroom-research`, `-crew`, `-implement`), a CLI, and a Claude Code / Codex plugin whose session-start hook loads the workflow. Claude Code, Codex, Gemini CLI, Cursor, or anything that can run a shell command.
105
+ - **Small.** About 4,400 lines of TypeScript, one ~135 KB bundled file, zero runtime dependencies.
106
+
107
+ ### How it stays safe
108
+
109
+ Each run gets the worker's own safety mechanism set to the mode (for OpenCode, a permission profile injected through `OPENCODE_CONFIG_CONTENT`): no commit/push/reset/checkout/stash/clean/rebase, no bulk deletes, no `sudo`, no `.env` or key files, no web tools unless you pass `--web`, no subagents, no recursive delegation. Only `allow`/`deny` rules, so a headless run never stalls on a prompt. A **git guard** on the worker's PATH also stops `sh -c "git push"`, `env git reset`, aliases and scripts from committing, pushing, resetting, stashing or touching your index. Your `opencode.json` is never touched.
110
+
111
+ ---
112
+
113
+ ## See it work
114
+
115
+ A real run on a free OpenCode Zen model: your agent reads ~554 tokens instead of 163,000.
116
+
117
+ ```text
118
+ $ pitroom run "Which function builds the read-only permission profile, and which bash commands does it allow?"
119
+ pitroom ✔ done · read · 30s · run 20260930-003902-3270
120
+ session ses_… · model opencode/muse-spark-1.3-contributor-free
121
+
122
+ SUMMARY: The read-only permission profile is built by `readProfile()` in src/profiles.ts:89.
123
+ Its bash allow-list is `READ_ONLY_BASH` in src/profiles.ts:29-46.
124
+ DETAILS:
125
+ - Allowed (src/profiles.ts:31-41): `git status*`:31, `git diff*`:32, … `rg *`:40, `wc *`:41.
126
+ - Explicit sub-denies: `rg *--pre*`:43, `git *--output*`:44, `git *--ext-diff*`:45.
127
+ FILES CHANGED: none
128
+
129
+ ── receipt: worker processed 163k tokens in 6 steps (7 tool calls) · worker cost $0.000
130
+ · returned ~554 tokens, 294× compression · est. saved $0.152 vs Claude Sonnet
131
+ ```
132
+
133
+ Every run prints a receipt, and `pitroom savings` adds them up:
134
+
135
+ <p align="center"><img src="docs/card.svg" width="520" alt="Pitroom savings card"></p>
136
+
137
+ ---
138
+
139
+ ## Quick start
140
+
141
+ <table>
142
+ <tr>
143
+
144
+ <td width="25%" valign="top">
145
+
146
+ ### 01
147
+
148
+ **Get it**
149
+
150
+ Clone the repository
151
+
152
+ </td>
153
+
154
+ <td width="25%" valign="top">
155
+
156
+ ### 02
157
+
158
+ **Link it**
159
+
160
+ `pitroom install`
161
+
162
+ </td>
163
+
164
+ <td width="25%" valign="top">
165
+
166
+ ### 03
167
+
168
+ **Check it**
169
+
170
+ `pitroom doctor --probe`
171
+
172
+ </td>
173
+
174
+ <td width="25%" valign="top">
175
+
176
+ ### 04
177
+
178
+ **Use it**
179
+
180
+ Ask your agent, or run `pitroom`
181
+
182
+ </td>
183
+
184
+ </tr>
185
+ </table>
186
+
187
+ Requires Node.js 18+ and at least one worker CLI: [OpenCode](https://opencode.ai) v2+ (the default worker), [Codex CLI](https://github.com/openai/codex) or [Claude Code](https://claude.com/claude-code).
188
+
189
+ ```bash
190
+ git clone https://github.com/ATASTECH/pitroom && cd pitroom
191
+ node dist/pitroom.mjs install # skills → ~/.agents/skills + ~/.claude/skills, launcher → ~/.local/bin/pitroom
192
+ pitroom doctor --probe # worker CLI, models, permissions, skills, one live round trip
193
+ ```
194
+
195
+ Or, in Claude Code, install it as a plugin (skills plus the session-start hook), from a clone or the repository:
196
+
197
+ ```text
198
+ /plugin marketplace add /path/to/pitroom
199
+ /plugin install pitroom@pitroom
200
+ ```
201
+
202
+ Use one or the other, not both (`doctor` warns if the skills load twice). Pitroom is a toolbox, not a procedure: your agent uses it when it helps, or you ask explicitly:
203
+
204
+ > Use pitroom to map how sessions are created and invalidated, then propose a fix.
205
+ > Split this into a pitroom crew: audit auth, billing and uploads for missing input validation.
206
+
207
+ ---
208
+
209
+ ## Modes
210
+
211
+ | | Flag | For | Your working tree |
212
+ |---|---|---|---|
213
+ | **read** | *(default)* | research, locating code, reviews | untouched; edit tools are denied |
214
+ | **isolate** | `-i` | code changes you want to review first | untouched until `pitroom apply` |
215
+ | **write** | `-w` | quick in-place edits | edited now; `pitroom revert` undoes exactly |
216
+
217
+ ```bash
218
+ pitroom run "Find every place we build SQL strings by hand; file:line and risk"
219
+ pitroom run -i --link node_modules --verify "npm test" "Fix the off-by-one in paginate() and add a test"
220
+ pitroom run -w "Rename getUserById to findUserById in src/ and fix imports"
221
+ pitroom run --continue last "Now handle the empty-page case too"
222
+ ```
223
+
224
+ Long jobs: `--bg` returns immediately; `pitroom wait <id>` blocks for up to 9 minutes (made for agents with 10-minute tool limits; exit code 75 means "call wait again").
225
+
226
+ ---
227
+
228
+ ## Workflow
229
+
230
+ Pitroom ships a full development methodology as skills, adapted from [superpowers](https://github.com/obra/superpowers) so that its subagents are cheap workers: your agent brainstorms and plans with you, then executes the plan task by task while workers do the typing and a second model does the reviewing.
231
+
232
+ ```text
233
+ pitroom-brainstorming ──► spec (docs/pitroom/specs/)
234
+ pitroom-writing-plans ──► plan (docs/pitroom/plans/), every task tagged with a worker tier
235
+ pitroom-driven-development, per task:
236
+ pitroom run -i --plan PLAN --step N implementer worker, isolated copy, TDD evidence, STATUS line
237
+ pitroom review <run> read-only reviewer on another backend: SPEC and QUALITY verdicts
238
+ pitroom run --continue <run> "…" fix rounds; the re-review sees only the fix diff
239
+ pitroom apply <run> · tests · commit the primary lands it; workers never commit
240
+ pitroom review --range main..HEAD --plan PLAN whole-branch review on the capable tier
241
+ pitroom-finishing ──► merge, PR or keep (asked, never automatic)
242
+ ```
243
+
244
+ A review package holds the diff under review with 10 lines of context, and the reviewer's CLI sends it to that worker's model provider. Pitroom does not filter it: secrets committed in a reviewed range go along as they are.
245
+
246
+ Tiers map plan tasks to workers: `"tiers": {"cheap": "opencode", "standard": "codex", "capable": "claude"}`. `pitroom plan status PLAN` rebuilds where a plan stands from the run records (it survives context compaction), and `pitroom plan note` keeps completions and rulings outside the repo.
247
+
248
+ ---
249
+
250
+ ## Crews
251
+
252
+ A real crew over this repository, four questions at once on a free OpenCode Zen model:
253
+
254
+ ```bash
255
+ pitroom crew -g v04-demo \
256
+ "Where does Pitroom enforce the maxParallel queue, and how does a waiting run react to pitroom stop? Cite file:line." \
257
+ "How does the git guard shim resolve git aliases? Cite file:line." \
258
+ "Which fields of OpenCode v2 events does the parser read for token usage, refused tool calls and errors? Cite file:line." \
259
+ "How does pitroom apply -g decide which patches to apply and in what order? Cite file:line."
260
+ pitroom watch -g v04-demo --json # what the primary agent follows, one line per change:
261
+ ```
262
+
263
+ ```text
264
+ {"event":"started","run":"20260930-102812-a65d","mode":"read","task":"Where does Pitroom enforce the maxParallel queue, and how d…"}
265
+ {"event":"progress","run":"20260930-102812-a65d","steps":3,"tools":4,"last":"grep SIGINT|SIGTERM|stop.*queued|stopped.*queued"}
266
+ {"event":"done","run":"20260930-102812-a563","time":"21s","worker":"opencode (default model)","summary":"The shim resolves `alias.<sub>` via `real git config --get` in a loop …","refs":"5/5"}
267
+ {"event":"all-done","runs":4,"ok":4,"failed":0}
268
+ ```
269
+
270
+ ```text
271
+ $ pitroom status -g v04-demo
272
+ RUN STATE MODE TIME STEPS WORKER NOW / RESULT
273
+ 20260930-102812-0c0d done read 30s 5 opencode (default model) Parser `src/backends/opencode/events.ts` reads …
274
+ 20260930-102812-7642 done read 27s 5 opencode (default model) `pitroom apply -g NAME` applies finished isolat…
275
+ 20260930-102812-a563 done read 21s 2 opencode (default model) The shim resolves `alias.<sub>` via `real git c…
276
+ 20260930-102812-a65d done read 39s 7 opencode (default model) maxParallel is enforced by file-based slots (`s…
277
+ ```
278
+
279
+ Humans get the same table live with `pitroom watch -g NAME`; `pitroom wait -g NAME --brief` prints one line per worker, `pitroom show <run>` the full answer.
280
+
281
+ For changes, `pitroom crew -i …` gives every worker its own isolated copy of your current state and `pitroom apply -g NAME` lands the patches in order, stopping at the first conflict. At most `maxParallel` workers (default 4) run at once, the rest queue; only one `--write` run per repository is allowed. `pitroom stop -g NAME` stops running and queued workers.
282
+
283
+ ---
284
+
285
+ ## Skills
286
+
287
+ | Skill | Your agent uses it to |
288
+ |---|---|
289
+ | `using-pitroom` | see what Pitroom offers and when it pays off (injected at session start by the plugin; optional) |
290
+ | `pitroom-brainstorming` | turn an idea into an approved design before any code |
291
+ | `pitroom-writing-plans` | write a task-by-task plan with a worker tier per task |
292
+ | `pitroom-driven-development` | execute a plan: worker per task, review on another model, fix loop, apply, commit |
293
+ | `pitroom-worktrees` | isolate its own branch for the work |
294
+ | `pitroom-tdd` | test first, for itself and the workers it briefs |
295
+ | `pitroom-debugging` | find root causes, with workers gathering the evidence |
296
+ | `pitroom-verification` | run the checks before claiming anything is done |
297
+ | `pitroom-review` | get a change, a fix round, a branch or a PR reviewed by another model |
298
+ | `pitroom-receiving-review` | weigh review findings with technical rigor |
299
+ | `pitroom-finishing` | merge, open a PR or keep the branch, as the user chooses |
300
+ | `pitroom-research` | find, map or explain code through a read-only worker |
301
+ | `pitroom-implement` | get a one-off change made in an isolated copy |
302
+ | `pitroom-crew` | split independent work across parallel workers and merge the results |
303
+
304
+ ---
305
+
306
+ ## Commands
307
+
308
+ ```text
309
+ pitroom run [-r|-w|-i] [-W WORKER] [-m MODEL] [-d DIR] [-f FILE]… [-t 30m] [--verify CMD] [--link a,b] [--bg] "task"
310
+ pitroom run --continue <run|last> "follow-up"
311
+ pitroom crew [-i] [-g NAME] "task 1" "task 2" … (or --task-file with --- separators)
312
+ pitroom run -i --plan PLAN --step N [--tier T] ["notes"]
313
+ pitroom review [run | --range A..B [--plan PLAN]] [--tier T | -W T] [--bg]
314
+ pitroom plan status PLAN [--json] · pitroom plan note PLAN "Task N: …"
315
+ pitroom status|wait|watch [run… | -g NAME] wait: --any --brief --timeout · watch: --json --interval
316
+ pitroom show [run] --patch --events --full --json
317
+ pitroom apply [run | -g NAME] · pitroom discard|revert [run] · pitroom stop [run | -g NAME]
318
+ pitroom ls [--running] [-g NAME] · pitroom clean [--days 14] [--yes]
319
+ pitroom savings [--since 7d|30d|all] [--card file.svg] [--badge]
320
+ pitroom statusline [--then CMD] · pitroom hook-card
321
+ pitroom doctor [--probe] · pitroom config · pitroom install [--copy] [--force] · pitroom uninstall
322
+ ```
323
+
324
+ Exit codes: `0` ok · `1` worker failed · `2` usage · `3` refused/setup · `4` timeout · `5` read-only violation · `6` verify failed · `75` still running.
325
+
326
+ ### Seeing Pitroom at work in Claude Code
327
+
328
+ Two settings make every delegation visible, whether or not the agent mentions it. A status line shows running workers and this week's savings (`--then` keeps your own status line first); a card appears after each `pitroom` command the agent runs, once per phase (started, finished with its result, applied). The plugin registers the card hook itself; with `pitroom install`, add both to `~/.claude/settings.json`:
329
+
330
+ ```json
331
+ {
332
+ "statusLine": { "type": "command", "command": "pitroom statusline --then 'your-own-statusline'" },
333
+ "hooks": {
334
+ "PostToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "pitroom hook-card", "timeout": 10 }] }]
335
+ }
336
+ }
337
+ ```
338
+
339
+ ---
340
+
341
+ ## How it works
342
+
343
+ ![Pitroom workflow: primary agent → Pitroom CLI → OpenCode, Codex or Claude Code workers → verified answer, exact diff and receipt returned to the primary agent.](docs/pitroom-flow.png)
344
+
345
+ ```text
346
+ primary agent ──(skill: "delegate?")──► pitroom run "task"
347
+ │ snapshot tree (throwaway index) [write]
348
+ │ isolated copy of current state [isolate]
349
+ │ worker adapter: mode → the CLI's own permissions
350
+ ▼
351
+ worker CLI, e.g. opencode run --standalone --format json (stdin closed, git guard, your default model)
352
+ │ NDJSON events
353
+ ▼
354
+ final answer · exact diff · receipt ──► primary agent verifies / applies
355
+ ```
356
+
357
+ Known headless footguns handled for every worker: `opencode run` blocks forever on an open stdin pipe; `ask` permissions stall headless runs; default output carries ANSI and banners; and in OpenCode v2 a plain `run` attaches to the shared background service, where per-run permissions and the git guard would not apply. Pitroom closes stdin, uses allow/deny-only profiles, parses `--format json` and always runs a private `--standalone` server.
358
+
359
+ ---
360
+
361
+ ## Workers
362
+
363
+ A worker is named by a target: `backend[:model]`.
364
+
365
+ ```bash
366
+ pitroom run "…" # preferred worker (config "worker", default opencode)
367
+ pitroom run -W opencode:opencode/space-bunny-free "…" # a specific backend and model
368
+ pitroom run -W 'codex:#low' "…" # Codex's default model, low reasoning effort
369
+ pitroom run -W claude:haiku "…" # Claude Code on a cheap model
370
+ pitroom run -m nvidia/z-ai/glm-5.3 "…" # another model on the preferred worker
371
+ ```
372
+
373
+ | Worker | Status | Read-only enforced by | Cost in receipts | Notes |
374
+ |---|---|---|---|---|
375
+ | OpenCode (v2+) | ✅ | per-run permission rules | reported | private `--standalone` server per run |
376
+ | Codex CLI | ✅ | OS sandbox (`read-only` / `workspace-write`) | tokens only | `codex login`; your `~/.codex/config.toml` is ignored for workers (its MCP servers run outside the sandbox); models take `#effort` |
377
+ | Claude Code | ✅ | tool allowlist (`--restricted --safe-mode`, `dontAsk`) | reported | `claude auth login`; its default is often Opus, so prefer `-W claude:haiku` |
378
+ | Gemini CLI | soon | approval mode + policy engine | | |
379
+
380
+ Fallbacks cross backends (e.g. `"fallback": ["codex:#low", "opencode"]`): a worker that is rate-limited, logged out or missing its model hands the task to the next. Follow-ups (`--continue`) always stay on the worker that owns the session. Writing an adapter: [docs/backends.md](docs/backends.md).
381
+
382
+ ---
383
+
384
+ ## Configuration
385
+
386
+ | Env | Default | |
387
+ |---|---|---|
388
+ | `PITROOM_WORKER` | `opencode` | Preferred worker target: `backend[:model]` |
389
+ | `PITROOM_MODEL` | the worker's default | Model for the preferred worker |
390
+ | `PITROOM_FALLBACK` | none | Comma-separated targets to fail over to on model/provider errors |
391
+ | `PITROOM_TIMEOUT` | `30m` | Per-run timeout |
392
+ | `PITROOM_MAX_PARALLEL` | `4` | Workers running at once; more queue |
393
+ | `PITROOM_PRIMARY` | `sonnet` | Pricing preset for the savings estimate: `sonnet`, `opus`, `haiku`, `gpt-5` |
394
+ | `PITROOM_PRICE` | | Custom primary price, USD per 1M tokens: `"in,out[,cachedIn]"` |
395
+ | `PITROOM_HOME` | `~/.local/state/pitroom` | Where run records and the ledger live |
396
+ | `PITROOM_<WORKER>_BIN` | on PATH | Path to a worker CLI, e.g. `PITROOM_OPENCODE_BIN` |
397
+
398
+ Or put defaults in `~/.config/pitroom/config.json` (flags and env still win); `pitroom config` shows every effective value and where it came from. `models` gives each worker a default model for targets that name none (`-W codex`, a `"codex"` fallback); a model in the target or `-m` still wins. `tiers` names workers for `--tier` and for plan tasks' `**Worker:**` lines:
399
+
400
+ ```json
401
+ {
402
+ "worker": "opencode",
403
+ "fallback": ["opencode:opencode/space-bunny-free", "codex"],
404
+ "models": { "codex": "gpt-6.1-sol", "claude": "claude-sonnet-5-5" },
405
+ "tiers": { "cheap": "opencode", "standard": "codex", "capable": "claude" },
406
+ "timeout": "20m",
407
+ "primary": "opus",
408
+ "link": ["node_modules"],
409
+ "maxParallel": 3
410
+ }
411
+ ```
412
+
413
+ ---
414
+
415
+ ## FAQ
416
+
417
+ **Where does my code go?** To whichever provider your worker's model uses. For private code, point the worker at a local model. `.env` files and private keys are blocked from the worker either way.
418
+
419
+ **How is "saved" computed?** It assumes your primary agent would have processed about the same tokens the worker did, priced at your primary's list prices (`PITROOM_PRIMARY` / `PITROOM_PRICE`), minus the worker's cost and the cost of reading the report. It is an estimate and is labelled as one.
420
+
421
+ **Can the worker break my repo?** It can't touch git history, refs or your index (permission profile + git guard), can't run bulk deletes, and write-mode edits are revertible with one command. The guard is not an OS sandbox: git called by absolute path from inside a script, or non-git tools, are outside its reach, which is why `--isolate` exists: nothing reaches your tree until you apply it.
422
+
423
+ **What if the worker fails?** Pitroom exits non-zero with the real cause (for example a default model that no longer exists) and your agent simply continues on its own. `pitroom doctor` diagnoses setup problems.
424
+
425
+ ---
426
+
427
+ ## Contributing
428
+
429
+ Issues and pull requests are welcome. Worker adapters are the easiest place to start: [docs/backends.md](docs/backends.md).
430
+
431
+ ```bash
432
+ npm install
433
+ npm test # end-to-end tests against a fake worker CLI + adapter contract tests on recorded real streams
434
+ npm run typecheck
435
+ ```
436
+
437
+ **[Report an issue](https://github.com/ATASTECH/pitroom/issues/new)** ·
438
+ [Open issues](https://github.com/ATASTECH/pitroom/issues)
439
+
440
+ ---
441
+
442
+ ## Credits
443
+
444
+ The workflow skills (brainstorming, planning, worker-driven development, review, debugging, TDD, verification, worktrees, finishing) are adapted from [superpowers](https://github.com/obra/superpowers)
445
+
446
+ ## License
447
+
448
+ Pitroom is licensed under the **MIT License**. See [LICENSE](LICENSE) for details.
449
+
450
+ ---
451
+
452
+ <div align="center">
453
+
454
+ ## Pitroom
455
+
456
+ ### A free pit crew for your expensive coding agent.
457
+
458
+ **Your agent decides · Cheap workers do the typing · A second model reviews**
459
+
460
+ <br />
461
+
462
+ **[Quick start](#quick-start)** ·
463
+ [Workflow](#workflow) ·
464
+ [Skills](#skills) ·
465
+ [Write an adapter](docs/backends.md)
466
+
467
+ <br /><br />
468
+
469
+ <sub>Model-agnostic · Verified answers · Receipts, not vibes</sub>
470
+
471
+ </div>