pitroom 0.18.0 → 0.20.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pitroom",
3
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.18.0",
4
+ "version": "0.20.0",
5
5
  "author": {
6
6
  "name": "TahaAtas"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pitroom",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "A free pit crew for your expensive coding agent: delegate research, fixes, tests, reviews and parallel investigations to cheap worker agents running your own models, with verified answers, exact diffs and cost receipts.",
5
5
  "author": {
6
6
  "name": "TahaAtas"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.20.0
4
+
5
+ ### Notifications
6
+ - **A desktop notification when a background run has ended.** Off by default; `"notify": true` in the config (or `PITROOM_NOTIFY=1`). A run that went to the background (`--bg`, a crew, an MCP call) says `Pitroom ✔ research done` with its task, time and changed files; a failed, timed-out or stopped one says so. Runs that went well but took less than `notifyAfter` seconds (default 15) and audits are left out (a failure is always announced), and a crew says so once, when its last run ends, judged as a whole (from its earliest start, by its worst run). A worker process that is killed outright never gets to say so. macOS (`osascript`) and Linux (`notify-send`) are built in; `notifyCommand` runs your own command in a shell with the text in `PITROOM_NOTIFY_TITLE` / `PITROOM_NOTIFY_BODY` (ntfy, a chat webhook, a sound), which is also how to get one on Windows.
7
+
8
+ ### MCP
9
+ - **A live view for MCP clients.** A run that an MCP client starts and that is still going after a few seconds starts the dashboard (`pitroom dash --detach`, reused if it is up) and the "still running" result, also from `pitroom_wait`, carries its address with the instruction to open it in the app's own browser pane (the Claude Code and Codex apps have one), else to give it to the user. Before, only the skills told an agent about the dashboard, so an agent that used the MCP tools never mentioned it. A run that finishes quickly starts nothing; the system browser is never opened. The config's `"mcpDash": false` (or `PITROOM_MCP_DASH=0`) turns it off.
10
+
11
+ ### Stats
12
+ - **Rate limits no longer count against a worker.** Runs that failed on a rate limit or quota are left out of `pitroom history stats` and the dashboard's Stats (run counts, success rates, times, tokens) and shown apart as rate-limited: they say nothing about the worker's work, and on free models they made good workers look bad (in one history, 257 of 286 failures were rate limits). The config's `"countRateLimits": true` counts them as before.
13
+ - A run records why its worker failed (`failureKind`: `rate-limited`, `model-unavailable`, `auth`, `other`); older records are recognised by the hint Pitroom adds to a rate-limit error.
14
+
15
+ ### Fixes
16
+ - **Secret-looking files are recognised in any letter case.** `ID_RSA`, `.ENV`, `PROD.ENV`, `Credentials.json`, `SECRETS.YML`, `.NETRC` were not flagged (the check was case-sensitive for those names), though on macOS and Windows they are the same files as their lower-case spellings: a read run then ran in the project instead of a clean snapshot, and the heads-up did not mention them. Found by the worker that wrote the direct tests for `secrets.ts`.
17
+ - **A dashboard card could stay on its placeholder.** The page skipped every request while the browser said the page was hidden and waited for a `visibilitychange` that embedded browsers (the browser panes of the Claude Code and Codex apps) may never send; a card opened there showed grey boxes until the next poll, ten minutes later for a finished run. The first request is now always made; only the repeated ones are skipped while hidden.
18
+ - **An audit read the answer's paths as missing.** An answer is written for you, with the paths turned back into your project's (`/Users/me/proj/src/a.ts:3`); the auditor works in a clean snapshot of its own, where that path does not exist, and disputed it ("this path does not exist in this project"). The project's paths now reach the auditor relative to its working directory, and the prompt says so. In one history, 2 of 12 non-agreeing audits were this; re-auditing them: one now agrees, the other still disputes a real claim.
19
+
20
+ ### Docs and tests
21
+ - The README's reference parts are folded into accordions (the first screen shows about half as much text; headings and links are unchanged), and the PI-Desktop benchmark says what a later audit found: of its eight answers 3 agreed and 5 were marked partly right, mostly lists that leave things out.
22
+ - Direct tests for the git guard, slots and locks, secret detection, receipts, the run store and process spawning, the MCP resources and prompts, and the doctor checks, which were only covered through the CLI; most were written by Pitroom workers in isolated copies and reviewed. A flaky MCP HTTP test was fixed at its cause (a blocked event loop reused sockets the server had closed).
23
+ - `benchmarks/outcome-prediction`: what Pitroom's own history can predict (whether a run will fail, whether an answer will be audited as right). Result so far: failures are rate-limit bursts a worker's recent record explains, and the labels about answers are too few to learn from.
24
+
25
+ ## 0.19.0
26
+
27
+ ### Doctor
28
+ - `pitroom doctor` has a **Use** section: with no runs yet it says so and how to start ("ask your agent to use Pitroom", or `pitroom run "where is <something> defined?"`); afterwards it says how many runs there have been and when the last one was. Skills can be installed and an agent may still never think of Pitroom: this is the first thing a new user sees.
29
+
30
+ ### Fixes
31
+ - **`pitroom dash --detach` could not find a dash that was up.** The registry entry (`dash.json`) was deleted whenever the dash did not answer within 1.5 s, or when the file was read while the server was writing it; the command then reported "did not start" with the server running (seen as a flake on Windows and once on macOS). The entry is now removed only when its process is gone, and is written through a temp file.
32
+
33
+ ### Docs
34
+ - Cursor has its own entry in the Quick start (`pitroom install --mcp --client cursor`), with what is and is not verified: Cursor's documentation lists `~/.agents/skills` and `~/.claude/skills`, where `pitroom install` links the skills; we have not run it in a Cursor session, and a forum report says its CLI does not load `~/.agents/skills`.
35
+
3
36
  ## 0.18.0
4
37
 
5
38
  ### Windows
package/README.md CHANGED
@@ -103,6 +103,9 @@ In isolate mode nothing reaches your tree until you apply it.
103
103
 
104
104
  ### And more
105
105
 
106
+ <details>
107
+ <summary>12 more features</summary>
108
+
106
109
  - **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.
107
110
  - **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.
108
111
  - **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. Up to 20 workers run at once by default (`maxParallel`, 30 at most), the rest queue, and the fallback chain absorbs free-tier rate limits; parallel writers are refused.
@@ -116,6 +119,8 @@ In isolate mode nothing reaches your tree until you apply it.
116
119
  - **A live dashboard and a searchable history.** `pitroom dash` opens a local page of every run (the task, what the worker did step by step, its result and diff) with history and statistics, for the agent apps that show neither hooks nor a status line; `pitroom history` searches everything Pitroom ever ran. See [Dashboard](#dashboard).
117
120
  - **Small.** About 6,500 lines of TypeScript in the CLI, a ~210 KB CLI bundle (plus the ~1.9 MB of dashboard files it serves, with syntax highlighting for ten languages), zero runtime dependencies.
118
121
 
122
+ </details>
123
+
119
124
  ### How it stays safe
120
125
 
121
126
  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`, a file-reading tool that refuses `.env` and key files (OpenCode and Claude Code workers), 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. These safeguards reduce risk; they are not a security boundary (see [Responsibility](#responsibility) and [SECURITY.md](SECURITY.md)).
@@ -158,6 +163,9 @@ The screenshots below show sample data (an imaginary `shop-api` project), not a
158
163
 
159
164
  <p align="center"><img src="docs/dash-live.png" width="100%" alt="The Live tab: four running workers with timers and progress bars, then finished runs with approved and needs-fixes badges, step counts, tokens and savings"></p>
160
165
 
166
+ <details>
167
+ <summary>Cards, audits, history, Stats, and Stop/Discard</summary>
168
+
161
169
  **Click a card and it grows into a panel** with the task, what the worker did step by step (files read, searches, commands, edits, with times, failed ones marked), its result, the files and diff it changed, and the details (model, tokens, cost, fallbacks, reference check).
162
170
 
163
171
  <p align="center"><img src="docs/dash-card.png" width="100%" alt="An expanded run card: the task, a ten-step activity list, the result, five changed files with one opened to its highlighted diff, and the details"></p>
@@ -174,12 +182,19 @@ The screenshots below show sample data (an imaginary `shop-api` project), not a
174
182
 
175
183
  The dashboard is a React app built once into `dist/ui` and served as two static files, so the CLI still has no runtime dependencies. It follows your system's light or dark theme (a button switches it).
176
184
 
185
+ </details>
186
+
177
187
  ---
178
188
 
179
189
  ## Benchmarks
180
190
 
181
191
  Measured on a real, public repository: [PI-Desktop](https://github.com/vastsa/PI-Desktop) at commit `c2bfe35`, 2,349 tracked files and about 419,000 lines of TypeScript and Rust. Eight questions of the kind an agent asks before it changes code, run as one read-only crew (`pitroom crew`, at most four workers at a time) on OpenCode's free `muse-spark-1.3-contributor-free` model.
182
192
 
193
+ In short: on that repository eight questions took 156 s of wall clock, and the workers read 5.5 million tokens and handed the agent 7,684 (715× less); a later audit found some of the answers incomplete. On React, Django and Kubernetes, four free models matched `gpt-6-sol` on nine bounded questions, and in a planted-bug review test almost every model found almost every bug. The tables, and what they do not show, are below.
194
+
195
+ <details>
196
+ <summary>PI-Desktop: eight questions, token savings, answer quality and an isolated change</summary>
197
+
183
198
  | Question | Worker time | Tokens processed | Returned to the agent | Compression | Refs verified |
184
199
  |---|---|---|---|---|---|
185
200
  | Where is the plugin runtime, and which functions activate and deactivate a plugin? | 37 s | 405,380 | 767 | 529× | 10/11 |
@@ -196,8 +211,15 @@ Workers read 5.5 million tokens of code and docs (96 steps, 179 tool calls) and
196
211
 
197
212
  **Were the answers right?** Checked by hand against the repository: 46 key claims across all eight answers (the cited line and what it says) were all correct, and two completeness checks held (exactly 6 invoke and 3 event window channels; no tests in `config_sync_rpc.rs`). The i18n answer lists the 12 source files that import the package and leaves out 11 test and fixture files that do too, which the question did not ask about. Pitroom's own checker marks fewer references as verified than that: ¹ those two answers cite bare file names (`transcripts.rs:651`) that it cannot resolve to a path, and it counts them as unverified although the lines are right.
198
213
 
214
+ **An audit found more than the hand check did.** Each of the eight answers was later re-checked by a second free worker (`pitroom audit`, on `space-bunny`): 3 agreed and 5 were marked partly right. The disputes are about answers that are incomplete or slightly off, not about the lines they cite: lists that leave things out (session state: more places that write it; i18n: a second, deep-import style of consumer; RPC tests: 14 tests missing), counts that are off, and a few cited lines some lines away from the declaration. One was checked by hand and the auditor was right: the RPC `mod tests` block holds 59 tests, the answer said about 40. The others were not checked by hand, and an auditor is itself a free model that can be wrong. So treat a worker's list or count as a good first answer that your agent confirms when it matters, which is what `--audit` is for.
215
+
199
216
  **A change in an isolated copy:** "add a one-line comment above `resolveUpdateMode`" finished in 16 s and 4 steps (142,491 tokens). The patch was one file and one line, the comment matched the code, and your working tree is untouched until you apply.
200
217
 
218
+ </details>
219
+
220
+ <details>
221
+ <summary>Free models against <code>gpt-6-sol</code> on React, Django and Kubernetes</summary>
222
+
201
223
  **Free models against `gpt-6-sol`, on three large repositories.** The same kind of work on React (7,252 files), Django (7,091) and Kubernetes (31,353 files), at pinned commits. Nine bounded questions, three per repository: the file and line that define a function, how many files contain a word, and which files contain it. Every answer is checked against `git grep`, not by opinion: an exact `path:line` (half a point for the right file on the wrong line), an exact count, and for the lists an F1 score that punishes both missed and invented files. Each worker ran the nine questions once, read-only, with no fallback, so a model that cannot do it fails instead of being swapped for another.
202
224
 
203
225
  | Worker and model | Score | Median time | Median tokens |
@@ -219,6 +241,11 @@ Four free models matched `gpt-6-sol` on these questions. Every model found every
219
241
 
220
242
  Only workers that ran are in the table. Models that could not answer at all (a provider error, or the shared daily quota of OpenRouter's free tier) are left out, and so are the two `gpt-oss-20b` runs that ended in a provider error; a timeout is kept.
221
243
 
244
+ </details>
245
+
246
+ <details>
247
+ <summary>Does a review find a planted bug?</summary>
248
+
222
249
  **Does a review find a planted bug?** A bug was changed into real code (an inverted check, a swapped `&&`/`||`, a flipped `return`) in React, Django, Kubernetes and Pitroom itself, committed as a bare "tidy", and `pitroom review` was asked to review the commit. 29 packages (14 with the bug alone, 15 with the bug and three comment-only edits around it). A review counts as a find when a Critical or Important finding names the changed file and either cites a line within 5 or names the changed identifier or its function; "exact line" is the strict version (within 3).
223
250
 
224
251
  | Worker and model | Bug found | Exact line | Reviews | Mean time | Slowest |
@@ -233,6 +260,8 @@ Only workers that ran are in the table. Models that could not answer at all (a p
233
260
 
234
261
  Almost every model found almost every bug, so this test separates them on speed and precision, not on whether they can review: `muse-spark` described the right bug but often quoted a wrong line number (57% exact), and `gpt-6-sol` and `muse-spark` were the fastest by a wide margin. Only three models finished all 29: the other four are scored on the reviews that ran before a provider limit (the free tier's usage limit, and the Codex plan's, which `gpt-6-sol` reached), and the rest are left out, not counted as misses, so their rows rest on 9 to 14 reviews. Every change is only 2 to 5 lines, which is easy; there is no false-alarm rate (the comment-only "clean" packages turned out to contain comments that were really wrong, so they cannot show one); and React, Django and Kubernetes may be in a model's training data. The harness and every raw review are in [`benchmarks/review-bugs`](benchmarks/review-bugs).
235
262
 
263
+ </details>
264
+
236
265
  **What this does not show**
237
266
  - One run per question and model: there is no variance here. The questions are bounded lookups that `grep` can answer, so they do not show how a model handles design questions or large edits, and four free models and `gpt-6-sol` all scoring 100% says the test is easy at the top, not that they are equal.
238
267
  - An open-ended task ("find up to five spelling mistakes in `docs/`") did not finish: it was stopped after 19 minutes and 57 tool calls. Give workers bounded tasks.
@@ -282,7 +311,16 @@ gemini extensions install https://github.com/ATASTECH/pitroom
282
311
  npm i -g pitroom
283
312
  ```
284
313
 
285
- **Any agent that speaks MCP (Cursor, Claude Desktop, and the three above too)**
314
+ **Cursor**
315
+
316
+ ```bash
317
+ npm i -g pitroom
318
+ pitroom install --mcp --client cursor
319
+ ```
320
+
321
+ <sub>This adds `pitroom mcp` to `~/.cursor/mcp.json` and leaves the other servers in that file alone; restart Cursor if it does not show up. Cursor gets the ten MCP tools described below. The skills are linked into `~/.agents/skills` and `~/.claude/skills` (`--no-skills` skips that), and [Cursor's documentation](https://cursor.com/docs/skills) lists both as places it loads skills from; we have not run that in a Cursor session, and a Cursor forum report says its CLI (`cursor-agent`) does not load `~/.agents/skills`. `pitroom install --mcp --dry-run` shows what it would change first.</sub>
322
+
323
+ **Any agent that speaks MCP (Claude Desktop, and the ones above too)**
286
324
 
287
325
  Pitroom is also an [MCP](https://modelcontextprotocol.io) server on stdio: ten tools instead of shell commands and skills (`pitroom_run`, `pitroom_wait`, `pitroom_show`, `pitroom_info`, `pitroom_review`, `pitroom_audit`, `pitroom_apply`, `pitroom_discard`, `pitroom_revert`, `pitroom_stop`), the runs as resources, and four prompts. The tool definitions sit in the client's context for the whole session, so they are kept small: about 1.9k tokens. It is listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as `io.github.ATASTECH/pitroom`, so clients that browse the registry can find it. After `npm i -g pitroom`, let Pitroom register itself in the clients it finds (Claude Code, Codex, Gemini CLI, Cursor, Claude Desktop):
288
326
 
@@ -308,12 +346,18 @@ or, for Cursor (`~/.cursor/mcp.json`), Claude Desktop (`claude_desktop_config.js
308
346
 
309
347
  Each tool runs the matching `pitroom` command, so every rule of the CLI applies unchanged (permission profiles, git guard, isolation, read snapshots). A run is waited for up to `waitSeconds` (default 50), then comes back as "still running" with its id for `pitroom_wait`; keep it below your client's tool timeout. The server works in the directory it is started in: the client's for stdio, or the one `-d DIR` names (Claude Desktop starts it elsewhere, so give it `"args": ["mcp", "-d", "/path/to/project"]`); the tools' `dir` argument picks another per call.
310
348
 
349
+ <details>
350
+ <summary>More about the MCP server: progress, cancellation, resources, prompts, HTTP</summary>
351
+
352
+ - **A live view.** A run that is still going after a few seconds starts the dashboard (if it is not already up) and the result carries its address: "Live view of every run: http://127.0.0.1:7878/". The server's instructions tell the agent to open it in its app's own browser pane (the Claude Code and Codex apps have one) or else give it to the user; the system browser is not opened. A run that finishes quickly starts nothing. `"mcpDash": false` in the config (or `PITROOM_MCP_DASH=0`) turns it off.
311
353
  - **Progress.** While a call waits for a run, a client that sent a progress token gets a `notifications/progress` every few seconds ("running · read · 12s · 3 steps, 2 tool calls · last: …"), and a client that resets its timeout when progress comes in (the protocol allows it; not every client does) does not give up on a long run. **Cancelling** a `pitroom_run`, `pitroom_review` or `pitroom_audit` call stops the run it started (a cancelled `pitroom_wait` only stops waiting).
312
354
  - **Resources.** The latest runs are listed as `pitroom://run/<id>` (the report) and, for runs that changed files, `pitroom://run/<id>/patch` (the exact diff), so a client can attach one to a conversation. A client can **subscribe** to a run (`resources/subscribe`) and is told when it changes state (`notifications/resources/updated`), and every client is told when the newest run changes (`notifications/resources/list_changed`), so it need not poll; over HTTP these arrive on the session's event stream (a GET).
313
355
  - **Prompts.** `research`, `implement`, `review` and `crew` say how to use Pitroom for that job (in Claude Code they appear as `/mcp__pitroom__research`, …), and every skill is a prompt of the same name (`using-pitroom`, `pitroom-research`, …), so a client without skills gets the same guidance. The server's instructions tell the agent to use the skills alongside the tools.
314
356
  - **More than runs:** `pitroom_run` takes `tasks` (independent tasks in parallel, one worker each) and `continue` (a follow-up in the same worker session); `pitroom_info` reports without changing anything, by `topic`: `runs`, `history` (find an earlier answer before asking again), `stats` and `models` (pick a worker), `savings`, `cooldown`, `config`, `doctor`; `pitroom_stop` with `cooldowns` tries rate-limited models again.
315
357
  - **Over HTTP.** `pitroom mcp --http [--port N]` (default 7117) serves the same tools at `http://127.0.0.1:7117/mcp` for clients that connect to a URL, for example `claude mcp add --transport http pitroom http://127.0.0.1:7117/mcp --header "Authorization: Bearer $(cat ~/.local/state/pitroom/mcp-token)"` (the command is printed when it starts). It is a local service: it listens on 127.0.0.1 only, needs the bearer token (made on first start, kept at `<state dir>/mcp-token` with owner-only permissions, or set with `PITROOM_MCP_TOKEN`), and refuses a Host or Origin that is not local, so a web page cannot use it. Anyone who has the token can run workers as you, so keep it private. It works in the directory it was started in (printed when it starts; `-d DIR` for another). Each client has its own session; a call that asks for progress is answered as an event stream. Ending a session or stopping the server ends the waiting, not the runs: collect them with `pitroom_wait` or the CLI. `pitroom install --mcp` registers the stdio command, which needs no token and no running process.
316
358
 
359
+ </details>
360
+
317
361
  **Any other agent (a plain shell) or just the CLI**
318
362
 
319
363
  ```bash
@@ -401,6 +445,9 @@ Long jobs: `--bg` returns immediately; `pitroom wait <id>` blocks for up to 9 mi
401
445
 
402
446
  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.
403
447
 
448
+ <details>
449
+ <summary>The workflow, step by step</summary>
450
+
404
451
  <p align="center"><img src="docs/workflow.svg" width="100%" alt="Workflow: brainstorming, then a plan with a worker tier per task, then for every task a worker implements in an isolated copy, another model reviews, fix rounds repeat until approved, and your agent applies, tests and commits; then a whole-branch review and finishing."></p>
405
452
 
406
453
  | Step | Skill | Command |
@@ -418,6 +465,8 @@ A review package holds the diff under review with 10 lines of context, and the r
418
465
 
419
466
  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.
420
467
 
468
+ </details>
469
+
421
470
  ---
422
471
 
423
472
  ## Audits
@@ -431,11 +480,16 @@ pitroom run --audit "…" # re-check this run's answer when it finishes (
431
480
 
432
481
  or set `"audit": 0.1` in the config (or `PITROOM_AUDIT=0.1`) to have about one read run in ten audited, in the background, without your agent asking. The same run is always in or out of the sample.
433
482
 
483
+ <details>
484
+ <summary>Cost, limits and where the verdict shows</summary>
485
+
434
486
  - **Cost:** off by default. An audit is a read run of the auditor, so about the rate times the worker's own tokens, on the `audit` tier (else `cheap`, i.e. a free model if that is your cheap tier). It never delays the run or fails it.
435
487
  - **Never itself:** the auditor is never the worker and model that gave the answer; with no other worker configured nothing is audited (`pitroom doctor` says so). Only read runs are audited: a change has `pitroom review`.
436
488
  - **Where it shows:** the answer's card and `pitroom show` carry the verdict and the disputed claims; the Stats tab counts, per worker, how many audited answers were confirmed. Audits are not counted as runs and save nothing.
437
489
  - **A sample, not a guarantee.** The auditor is a model too: it can share a blind spot, and a few audits say little about a worker. Treat `DISAGREE` as a reason to look, and `AGREE` as one more signal.
438
490
 
491
+ </details>
492
+
439
493
  ## Crews
440
494
 
441
495
  A real crew over this repository, four questions at once on a free OpenCode Zen model:
@@ -478,6 +532,9 @@ For changes, `pitroom crew -i …` gives every worker its own isolated copy of y
478
532
 
479
533
  ## Skills
480
534
 
535
+ <details>
536
+ <summary>The 14 skills</summary>
537
+
481
538
  | Skill | Your agent uses it to |
482
539
  |---|---|
483
540
  | `using-pitroom` | see what Pitroom offers and when it pays off (injected at session start by the plugin; optional) |
@@ -495,6 +552,8 @@ For changes, `pitroom crew -i …` gives every worker its own isolated copy of y
495
552
  | `pitroom-implement` | get a one-off change made in an isolated copy |
496
553
  | `pitroom-crew` | split independent work across parallel workers and merge the results |
497
554
 
555
+ </details>
556
+
498
557
  ---
499
558
 
500
559
  ## Commands
@@ -531,6 +590,9 @@ Exit codes: `0` ok · `1` worker failed · `2` usage · `3` refused/setup · `4`
531
590
 
532
591
  ### History
533
592
 
593
+ <details>
594
+ <summary>Searching the history</summary>
595
+
534
596
  Every finished run is also written to a SQLite database (`history.db` in Pitroom's state directory; Node's built-in `node:sqlite`, nothing to install). It keeps the task, worker and model, time, tokens, savings, the steps the worker took, its answer and the diff, and it is searchable:
535
597
 
536
598
  ```bash
@@ -541,8 +603,13 @@ pitroom history stats --since 30d # runs, success rate, average time and to
541
603
 
542
604
  While a run runs, its raw event stream is a plain file (the simplest thing that survives a crash). When it ends, the stream is compressed, and the stderr log is kept only for runs that did not succeed. `pitroom clean` removes old run directories but the history keeps them: `pitroom show <run>` still prints their report, steps, and patch. Runs from before the history existed are taken in by `pitroom history import` (it also runs on the first `pitroom history` and `pitroom dash`). The files remain the source: the database can be deleted and rebuilt with `history import` for the runs still on disk.
543
605
 
606
+ </details>
607
+
544
608
  ### Seeing Pitroom at work
545
609
 
610
+ <details>
611
+ <summary>The status line and hook cards (and what the apps show instead)</summary>
612
+
546
613
  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`:
547
614
 
548
615
  ```json
@@ -559,6 +626,8 @@ The Claude Code and Codex **apps** show neither hook messages nor a status line.
559
626
  - `pitroom dash --detach` prints the address of a live dashboard with three tabs: **Live** (every running and recent run as an animated card; click one for the task, what the worker did step by step, its result, the diff and the details), **History** (search and filter everything Pitroom ever ran; every run opens as the same card) and **Stats** (success rate, time, tokens and savings per worker and model). It is read-only, listens on `127.0.0.1` only and stops itself after an hour without a request (`pitroom dash --stop` ends it sooner). Open it in a browser or in the app's own browser pane. The skills tell the agent to start it and give you the address when it runs workers in the background.
560
627
  - `pitroom watch -g NAME --brief` prints one card line when a worker starts and one when it ends. In Claude Code, the agent runs it through the Monitor tool and the lines appear in the app; in Codex the command's output block fills as it goes.
561
628
 
629
+ </details>
630
+
562
631
  ---
563
632
 
564
633
  ## How it works
@@ -597,6 +666,9 @@ pitroom run -m nvidia/z-ai/glm-5.3 "…" # another model on th
597
666
 
598
667
  ### Models, costs and effort
599
668
 
669
+ <details>
670
+ <summary>Models, costs and effort levels</summary>
671
+
600
672
  `pitroom models` lists what each worker offers (Codex from its own model cache, Claude Code's aliases, OpenCode's `opencode models`, Gemini CLI's built-in names), the reasoning-effort levels each model accepts, what you say it costs and what your own runs used:
601
673
 
602
674
  ```text
@@ -610,6 +682,8 @@ Pitroom cannot know vendor prices and does not fetch them, so a cost is what you
610
682
 
611
683
  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). A model that says "rate limited" (a daily quota used up, an overloaded provider) is remembered for the time its message gives, or a guess: the next runs skip it while a fallback is left, so they do not each wait for it to fail. `pitroom cooldown` lists what is skipped and until when, `--clear` tries it again, and `doctor` shows it too.
612
684
 
685
+ </details>
686
+
613
687
  ---
614
688
 
615
689
  ## Configuration
@@ -634,6 +708,9 @@ Fallbacks cross backends (e.g. `"fallback": ["codex:#low", "opencode"]`): a work
634
708
 
635
709
  Or put defaults in `~/.config/pitroom/config.json` (flags and env still win); `pitroom config` shows every effective value and where it came from. `pitroom init` proposes a starter config from the worker CLIs and OpenCode models you have (a fallback chain of your free models, tiers when more than one CLI is installed) and writes it only with `--yes`; it never picks your model for you. `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:
636
710
 
711
+ <details>
712
+ <summary>config.json: an example and what each setting does</summary>
713
+
637
714
  ```json
638
715
  {
639
716
  "worker": "opencode",
@@ -653,6 +730,11 @@ Or put defaults in `~/.config/pitroom/config.json` (flags and env still win); `p
653
730
  - `tiers`: `cheap`, `standard` and `capable` name the workers for plan tasks and `--tier`; an optional `review` tier names who reviews a run (by default another worker than the implementer's, `standard` first).
654
731
  - `audit`: the chance (0 to 1, default 0 = off) that a finished read run is re-checked in the background, see [Audits](#audits). The `audit` tier (else `cheap`) names who does it.
655
732
  - `costs`: your relative cost per `worker:model`, only compared with each other; `maxParallel`: workers at once (default 20, at most 30).
733
+ - `notify`: a desktop notification when a run that went to the background (`--bg`, a crew, an MCP call) has ended, so a long job does not have to be watched (default `false`; `PITROOM_NOTIFY=1`). Runs that went well but took less than `notifyAfter` seconds (default 15; `PITROOM_NOTIFY_AFTER`) and audits are not announced (a failure always is), and a crew says so once, when its last run ends, judged as a whole. A worker process that is killed outright never gets to say so. The built-in notifier uses `osascript` on macOS and `notify-send` on Linux (none for Windows yet); `notifyCommand` runs a command of your own instead, in a shell, with the text in `PITROOM_NOTIFY_TITLE` and `PITROOM_NOTIFY_BODY` (and `PITROOM_NOTIFY_RUN`, `PITROOM_NOTIFY_STATE`): for example `"notifyCommand": "curl -s -d \"$PITROOM_NOTIFY_BODY\" ntfy.sh/my-topic"`.
734
+ - `mcpDash`: whether a run that an MCP client starts, and that is still going after a few seconds, also starts the dashboard and returns its address (default `true`; `PITROOM_MCP_DASH=0` or `"mcpDash": false` turns it off), see [the MCP server](#1-install-pick-your-agent).
735
+ - `countRateLimits`: whether runs that failed on a rate limit or quota count in `pitroom history stats` and the dashboard's Stats (default `false`: they are left out of the run counts, success rates, times and tokens and shown apart as rate-limited, since they say nothing about the worker's work; `true` counts them as not ok).
736
+
737
+ </details>
656
738
 
657
739
 
658
740
  ---