pitroom 0.25.0 → 0.27.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.25.0",
4
+ "version": "0.27.0",
5
5
  "author": {
6
6
  "name": "TahaAtas"
7
7
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pitroom",
3
- "version": "0.25.0",
3
+ "version": "0.27.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,47 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.27.0
4
+
5
+ ### Workers
6
+ - **Antigravity edits work again with agy 1.4.** agy 1.4 asks for a `write_file` grant before an edit in the workspace, `--mode accept-edits` or not, and a headless run cannot ask: every `-i` and `-w` run with Antigravity ended without an answer ("a tool required the write_file permission"). Edit runs now grant writes in their own workspace; read runs still may not write, and the workspace's secret files stay closed.
7
+ - **Antigravity is out of beta on macOS.** `scripts/check-worker.mjs` held in all eight checks with agy 1.4.7 there; on Linux and Windows, where it has not been run yet, it stays beta, and `pitroom doctor` says so there.
8
+ - **`node scripts/check-worker.mjs <worker>`** tries a worker CLI the way Pitroom uses it (a read, a follow-up, a read outside the project, a shell command, an isolated edit, a commit the git guard refuses, an unknown model) in a scratch repository with a Pitroom state folder of its own, and prints what held: for a platform a worker has not been tried on. It found the agy 1.4 change above.
9
+ - **`autoFallback`** (off by default): with no `fallback` list, a run falls back to the other workers your config already names (tiers, `models`, `worker`), the installed ones, cheapest first by `costs`, at most four. It never adds a model you did not name somewhere, nor the worker itself at another effort level; `pitroom doctor` shows the chain and says where it came from.
10
+
11
+ ### Reviews
12
+ - **A review's file:line is the file's again.** A review package shows the change as a diff, and a reviewer that reads files with a line-numbered tool saw the package's own line numbers: Claude Code cited those for a third of the references in its task reviews and half of those in its branch reviews (`browser-observation.ts:177-250` for a file of 75 lines), so the reference check failed answers that were right. Every line of a hunk in the package now starts with its line number in the file after the change (`+ 99| new`), and all three review templates say to cite those (the branch review's said nothing about it).
13
+ - **The reference check finds more of the files an answer means.** A path with a folder left out (`api-contracts/integrations.ts` for `packages/api-contracts/src/integrations.ts`) is matched when the folders written appear in the file's path in order, and a file only a dependency or the build output has (`streamableHttp.d.ts:73`, under `node_modules`) is looked for there when the project has none of that name; the lines and the symbol are still checked. On one machine's past answers, checked again against today's files, a quarter of OpenCode's failed references and a sixth of Claude's held up.
14
+
15
+ ### Windows
16
+ - **The git shim is a `git.exe` now**, built on the spot with the C# compiler that ships with Windows (.NET Framework 4). It hands its command line to `sh.exe` unread, so every argument arrives as written, an unquoted `& | < >` from PowerShell too (the `cmd /c` line a batch file is started with acted on those), and a program that starts git without a shell no longer skips the shim. Without a compiler, `git.cmd` stays the door, and `pitroom doctor` says so.
17
+
18
+ ### Docs and tests
19
+ - `benchmarks/outcome-prediction` again, on four weeks of runs (1,455), with two more labels: a review's verdict on a change, and whether an answer's references check out. Who answers predicts the latter well (AUC 0.85), but the label measures the reference checker too; failures are still about providers, and audit and review verdicts are still too few. No learned model yet.
20
+ - The review benchmark's harmless packages are reviewed in full: `big-pickle` raised no false alarm in 16, `nemotron-3-ultra` 4 and `mimo-v2.6-flash` 2.
21
+
22
+ ## 0.26.0
23
+
24
+ ### Workers
25
+ - **A limit part way no longer fails the run.** A worker that hit a plan's usage limit or a used-up quota after it had started (a Codex or Claude session limit, an Antigravity quota) failed the run, fallbacks or not: about a third of the runs that failed on a limit had a fallback that was never tried. Now the next worker takes the task over. An edit carries on in the same tree, told which files were already changed and to finish rather than start over; a read starts over. The run's cost is what both used, and the run's notes say who handed over.
26
+ - **Audits have fallbacks.** An audit ran on one auditor only, and lost the audit when that one was rate-limited. It now falls back to the other auditors (the audit and cheap tiers, the fallbacks, the worker), never to the worker it audits, at any effort level.
27
+ - **Cooldowns last as long as the limit.** "try again at 8:56 PM" and "resets 7:40pm (Europe/Istanbul)" are read as times of day (in the zone named, else the machine's), so an exhausted model is not tried again every 20 minutes until then. A used-up allowance with no time given (OpenCode's free usage limit) waits an hour instead of 20 minutes.
28
+ - **"usage limit" and "session limit" count as limits on every worker** (they did on Claude Code and Codex only).
29
+ - **`rankWorkers` ranks by the same kind of work.** A worker's record mixed its answers and its changes, though they part ways: in one machine's month of runs, `muse-spark` finished all 61 of its questions and 15 of its 19 changes, `space-bunny` 25 of 26 and 7 of 9. The chain is now ordered by the record of the run's kind (a question, a change or a review), and a change's record counts the reviews of it as its checks (spec met and nothing to fix), as an answer's counts its audits. The note says which record it used (`ranked by record on changes`).
30
+
31
+ ### Windows
32
+ - **Git from Scoop gets the git shim.** Scoop's `shims\git.exe` is a launcher far from Git for Windows' `sh.exe`, so the shim (layer 1) was left out and only git's own config guarded the worker. Pitroom now follows the launcher's `git.shim` to the real git.
33
+ - **`HEAD^` from PowerShell is `HEAD^` again.** Windows starts a batch file such as `git.cmd` through a `cmd /c` line, which removes a `^` and fills in a `%name%` that names a variable before the batch file runs: from PowerShell, `git show HEAD^` showed `HEAD`, and `--format=%cd%n` got the current folder, where git.exe would have got them as written. When Windows starts `git.cmd` itself, the shim now takes the arguments from that raw line; a `cmd /d /s /c` line, which may hold more than one command, keeps `%*`. An unquoted `& | < >` is still acted on by that `cmd /c` line, as for any batch file.
34
+
35
+ ### Savings
36
+ - **No finished run is missing from the savings ledger.** A run whose process was killed between its final record and its ledger line, and a worker that crashed, were never counted (about 1.5% of finished runs). `pitroom savings`, `pitroom history` and the dashboard now record the finished runs the ledger missed, each once.
37
+ - **A done run counts even when its CLI reported no steps** (some OpenCode reviews): it answered, so it is in "Finished". Runs that failed before reaching the model stay out, as before.
38
+ - **An estimated cost says so.** `pitroom history` has a COST column, and `pitroom savings --models` its cost: a cost the worker's CLI did not report (Codex, Gemini) and that was estimated from a price (your `workerPrices`, else the catalog's) reads `~$0.40`, a reported one `$0.40`, a free one `free`. `history --json` rows carry `cost` and `costEstimated`.
39
+ - **Prices from your agent**: `pitroom_info` has a `prices` topic: the primary's price the savings are measured against and the price each worker in use gets, or the `worker` named. `pitroom prices WORKER…` does the same on the command line, and now also prints the primary's price.
40
+
41
+ ### Docs and tests
42
+ - **The review benchmark measures false alarms.** 16 new packages make a change that cannot alter what the code does (a comparison mirrored, `i < n` to `n > i`, only where it is the same expression; Pitroom's own also in its committed `dist/`), looking like the planted bugs. `big-pickle` raised no false alarm in 13 reviews; `nemotron-3-ultra` raised 4 in 14 and `mimo-v2.6-flash` 2 in 13, each filing a change it called harmless as Important for style. The README's table has the new column. `test/bench-equiv.test.mjs` checks the rule: what it rejects, and that each mirrored expression gives the same value for thousands of inputs.
43
+ - The benchmark's scorer read a review with no Critical heading (it went straight to Important) as having no findings: a few found bugs were counted as misses (`nemotron-3-ultra` 97% to 100%, `muse-spark` 93% to 97%, `longcat` 83% to 86%).
44
+
3
45
  ## 0.25.0
4
46
 
5
47
  ### Dashboard
package/README.md CHANGED
@@ -72,7 +72,7 @@ Pitroom uses your worker CLI's default model: a free tier, a local MLX/Ollama mo
72
72
 
73
73
  ### Any worker CLI
74
74
 
75
- OpenCode, Codex CLI, Claude Code, Gemini CLI, Qwen Code, Kilo Code and Antigravity CLI (beta).
75
+ OpenCode, Codex CLI, Claude Code, Gemini CLI, Qwen Code, Kilo Code and Antigravity CLI (beta on Linux and Windows).
76
76
 
77
77
  One group can mix them, and a fallback chain can cross them ([how adapters work](docs/backends.md)).
78
78
 
@@ -107,7 +107,7 @@ In isolate mode nothing reaches your tree until you apply it.
107
107
  <summary>12 more features</summary>
108
108
 
109
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.
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.
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, also when a plan's usage limit stops a worker part way (the next one finishes the task). Still no model hardcoded: the chain is yours.
111
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.
112
112
  - **Faster, not only cheaper.** Workers run in the background and side by side (up to 20 at once) while your agent keeps working, so slow reading and review stop blocking it. In the [benchmark](#benchmarks), 470 s of worker time finished in 156 s of wall clock, about 3× faster than one question after another, and your agent's own context stayed small.
113
113
  - **Free first, dearer only when needed.** Runs and plan tasks start on the `cheap` tier, OpenCode's free model; `standard` (Codex) and `capable` (Claude Code) are for tasks that need them, and an optional `review` tier names who reviews. Gemini CLI with a free Google AI Studio key is one more cheap worker (small daily quota per model). `pitroom models` shows what each worker offers, the effort levels (`low` … `xhigh`) each model accepts, what you say it costs (`costs`) and what it used; `--effort` sets the level per run. Details: [Models, costs and effort](#models-costs-and-effort).
@@ -244,21 +244,23 @@ Only workers that ran are in the table. Models that could not answer at all (a p
244
244
  </details>
245
245
 
246
246
  <details>
247
- <summary>Does a review find a planted bug?</summary>
247
+ <summary>Does a review find a planted bug, and leave a harmless change alone?</summary>
248
248
 
249
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).
250
250
 
251
- | Worker and model | Bug found | Exact line | Reviews | Mean time | Slowest |
252
- |---|---|---|---|---|---|
253
- | OpenCode `space-bunny-free` | 100% | 100% | 29 of 29 | 2 min 19 s | 5 min 46 s |
254
- | OpenCode `nemotron-3-ultra-free` | 97% | 79% | 29 of 29 | 1 min 45 s | 3 min 29 s |
255
- | OpenCode `longcat-2.5-preview-free` | 83% | 83% | 29 of 29 | 2 min 53 s | 8 min (1 timed out) |
256
- | Codex `gpt-6-sol` | 100% | 100% | 9 of 29 | 38 s | 52 s |
257
- | OpenCode `muse-spark-1.3-contributor-free` | 100% | 57% | 14 of 29 | 48 s | 2 min 0 s |
258
- | OpenCode `big-pickle` | 100% | 92% | 13 of 29 | 2 min 28 s | 5 min 27 s |
259
- | OpenCode `mimo-v2.6-flash-free` | 100% | 100% | 10 of 29 | 4 min 6 s | 7 min 40 s |
251
+ **Does it leave a harmless change alone?** 16 more packages look the same (a comparison changed on one or two lines, the same "tidy" message) but cannot change what the code does: the two sides of a comparison are swapped and the operator mirrored (`i < n` becomes `n > i`), only where that is the same expression. A Critical or Important finding on one of them is a false alarm.
252
+
253
+ | Worker and model | Bug found | Exact line | False alarm | Reviews | Mean time | Slowest |
254
+ |---|---|---|---|---|---|---|
255
+ | OpenCode `nemotron-3-ultra-free` | 100% | 83% | 25% (4 of 16) | 29 + 16 | 1 min 30 s | 3 min 29 s |
256
+ | OpenCode `space-bunny-free` | 100% | 100% | - | 29 | 2 min 19 s | 5 min 46 s |
257
+ | Codex `gpt-6-sol` | 100% | 100% | - | 9 | 38 s | 52 s |
258
+ | OpenCode `big-pickle` | 97% | 90% | **0% (0 of 16)** | 29 + 16 | 1 min 45 s | 6 min 16 s |
259
+ | OpenCode `muse-spark-1.3-contributor-free` | 97% | 62% | - | 29 | 43 s | 2 min 0 s |
260
+ | OpenCode `mimo-v2.6-flash-free` | 90% | 90% | 13% (2 of 16) | 29 + 16 (4 timed out) | 4 min 36 s | 8 min 1 s |
261
+ | OpenCode `longcat-2.5-preview-free` | 86% | 86% | - | 29 (1 timed out) | 2 min 53 s | 8 min 0 s |
260
262
 
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).
263
+ Almost every model found almost every bug, so finding them does not separate the models; leaving the harmless change alone does. `big-pickle` never raised a false alarm. `nemotron-3-ultra` and `mimo-v2.6-flash` each said, in their own words, that the change altered nothing, and still filed it as Important ("a Yoda condition, inconsistent with the rest of the file"), where the review template puts style under Minor; an agent that acts on Important findings would have reverted a harmless commit. `muse-spark` described the right bug but often quoted a wrong line number (62% exact). The models with a dash were not available any more, or out of quota, when the harmless packages were added; Codex `gpt-6-sol` reached its plan's usage limit after 9 reviews, and the others' left-out reviews hit the free tier's limit, so they are not counted as misses. Every change is only 2 to 5 lines, which is easy; the harmless edits are all of one kind (a mirrored comparison); and React, Django and Kubernetes may be in a model's training data. The harness, the rule that keeps an edit harmless (and its test) and every raw review are in [`benchmarks/review-bugs`](benchmarks/review-bugs).
262
264
 
263
265
  </details>
264
266
 
@@ -276,14 +278,14 @@ To repeat it on your own repository: `pitroom crew -d <repo> -g bench "<question
276
278
 
277
279
  macOS and Linux are the main platforms. **Windows** runs the same test suite in CI (Windows Server, Node 22 and 24, with the fake workers; the worker CLIs themselves are not run there), with these differences:
278
280
 
279
- - **The git guard** is the same two layers as elsewhere, built on the `sh.exe` that Git for Windows ships: git's own config (a `reference-transaction` hook that refuses every ref update, and push URLs that go nowhere) is always on; the `git` shim (`git.cmd` for cmd.exe and PowerShell, `git` for Git Bash) adds friendly refusals and also blocks `add`, `restore`, `clean` and the rest. A worker that starts git without a shell (a plain `CreateProcess`) skips the shim, and is left with the config layer. `pitroom doctor` says which is in effect. It is verified in CI with Git for Windows, not yet with the worker CLIs on a real Windows machine.
281
+ - **The git guard** is the same two layers as elsewhere, built on the `sh.exe` that Git for Windows ships: git's own config (a `reference-transaction` hook that refuses every ref update, and push URLs that go nowhere) is always on; the `git` shim adds friendly refusals and also blocks `add`, `restore`, `clean` and the rest. Its doors are `git.exe`, a small launcher Pitroom builds with the C# compiler that ships with Windows (.NET Framework 4), for every program that starts git, with a shell or without one; `git` for Git Bash; and `git.cmd` where no compiler is found. `git.exe` hands its command line to `sh.exe` unread, so arguments arrive as written (`HEAD^`, `%cd%`, an unquoted `&`). Through `git.cmd` alone, a program that starts git without a shell skips the shim and is left with the config layer, and the `cmd /c` line Windows starts a batch file with still acts on an unquoted `& | < >` (a `^` and a `%name%` are kept: the shim reads the raw line). Git installed with Scoop works too (its `shims\git.exe` is followed to the real one, and so to its `sh.exe`). `pitroom doctor` says which is in effect. It is verified in CI with Git for Windows, not yet with the worker CLIs on a real Windows machine.
280
282
  - **The launcher is `pitroom.cmd`** (`%USERPROFILE%\.local\bin`), started with the Node that ran `pitroom install` or the one in `PITROOM_NODE`; it does not search for another Node.
281
283
  - **Line endings.** Pitroom compares and applies patches byte for byte. Keep `core.autocrlf` off (or an `eol=lf` in `.gitattributes`, as this repository has); a checkout converted to CRLF has not been tested with `apply`.
282
284
  - A read snapshot's files are not made read-only (Windows has no POSIX modes), and a `--verify` command runs in `cmd.exe`, which reports a missing command as `is not recognized`.
283
285
 
284
286
  ## Quick start
285
287
 
286
- You need Node.js 22.13+ and at least one worker CLI: [OpenCode](https://opencode.ai) v2+ (the default worker, with free models), [Codex CLI](https://github.com/openai/codex), [Claude Code](https://claude.com/claude-code) [Gemini CLI](https://github.com/google-gemini/gemini-cli) (beta; it needs an API key from [Google AI Studio](https://aistudio.google.com/apikey), a Google account sign-in no longer works for it) [Qwen Code](https://github.com/QwenLM/qwen-code) (beta; any OpenAI-compatible provider, a DashScope key, or a local model) [Kilo Code](https://kilo.ai)'s CLI (beta; `npm i -g @kilocode/cli`, its 500+ models and providers) or the [Antigravity CLI](https://antigravity.google) (beta; `agy`, signed in with your Google account).
288
+ You need Node.js 22.13+ and at least one worker CLI: [OpenCode](https://opencode.ai) v2+ (the default worker, with free models), [Codex CLI](https://github.com/openai/codex), [Claude Code](https://claude.com/claude-code) [Gemini CLI](https://github.com/google-gemini/gemini-cli) (beta; it needs an API key from [Google AI Studio](https://aistudio.google.com/apikey), a Google account sign-in no longer works for it) [Qwen Code](https://github.com/QwenLM/qwen-code) (beta; any OpenAI-compatible provider, a DashScope key, or a local model) [Kilo Code](https://kilo.ai)'s CLI (beta; `npm i -g @kilocode/cli`, its 500+ models and providers) or the [Antigravity CLI](https://antigravity.google) (`agy`, signed in with your Google account; beta on Linux and Windows).
287
289
 
288
290
  ### 1. Install: pick your agent
289
291
 
@@ -353,7 +355,7 @@ Each tool runs the matching `pitroom` command, so every rule of the CLI applies
353
355
  - **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).
354
356
  - **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).
355
357
  - **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.
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.
358
+ - **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`, `prices` (USD per 1M tokens of the primary and of each worker in use, or of the `worker` named), `cooldown`, `config`, `doctor`; `pitroom_stop` with `cooldowns` tries rate-limited models again.
357
359
  - **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.
358
360
 
359
361
  </details>
@@ -682,7 +684,7 @@ pitroom run -W claude:haiku "…" # Claude Code on a ch
682
684
  pitroom run -W gemini:gemini-3.8-flash "…" # Gemini CLI (beta; needs a Google AI Studio API key)
683
685
  pitroom run -W qwen:qwen3-coder-plus "…" # Qwen Code (beta; your provider from ~/.qwen/settings.json)
684
686
  pitroom run -W kilo:kilo/<model> "…" # Kilo Code's CLI (beta; any model from `kilo models`)
685
- pitroom run -i -W antigravity "…" # Antigravity CLI (beta; your Google account, models from `agy models`)
687
+ pitroom run -i -W antigravity "…" # Antigravity CLI (your Google account, models from `agy models`; beta on Linux and Windows)
686
688
  pitroom run -m nvidia/z-ai/glm-5.3 "…" # another model on the preferred worker
687
689
  ```
688
690
 
@@ -694,7 +696,7 @@ pitroom run -m nvidia/z-ai/glm-5.3 "…" # another model on th
694
696
  | Gemini CLI | beta | `--approval-mode plan` plus Pitroom's policy rules | tokens only | an API key from Google AI Studio (sign in with `gemini` or set `GEMINI_API_KEY`; Google account sign-in is refused by Google); workers run in a private Gemini home without your hooks, MCP servers and skills; secret-file rules are not enforced by Gemini 0.62, but a read run with secret-looking files reads a [clean snapshot](#modes) without them; pin a model, e.g. `-W gemini:gemini-3.8-flash`; `--continue` works (by session id; see [the notes](docs/backends.md#gemini-cli-notes)) |
695
697
  | Qwen Code | beta | `--approval-mode plan`; edits only inside the working directory, the rest declined | tokens only | checked against Qwen Code 0.25 with a scripted model, not yet with a real provider; uses your sign-in and model from `~/.qwen/settings.json` (any OpenAI-compatible provider, DashScope, a local model); `--safe-mode` keeps your QWEN.md, hooks, skills and MCP servers out and stops the CLI writing memories of the run; reads `.env` if asked, so a read run with secret-looking files reads a [clean snapshot](#modes); see [the notes](docs/backends.md#qwen-code-notes) |
696
698
  | Kilo Code | beta | per-run permission rules (OpenCode's profiles) | reported | the CLI of `@kilocode/cli` (an OpenCode fork): the same `pitroom-read`/`pitroom-write` profiles through `KILO_CONFIG_CONTENT`, your sign-in and providers as they are; workers use a private state folder so a running `kilo daemon` (which would ignore the profiles) is never attached to; checked against Kilo 7.8.8 with a scripted model, not yet with a real provider; see [the notes](docs/backends.md#kilo-code-notes) |
697
- | Antigravity CLI | beta | a read-only [snapshot](#modes) of its own for every read run (agy has no read-only mode for headless runs) | tokens only | checked against agy 1.3.5 (macOS); use `-i` for changes, not `-w` (its deny rules are patterns, a layer on top of the git guard and the isolated copy); runs with a home of its own per workspace (agy reads its settings only from `~/.gemini`), so its commands do not see your dotfiles; an answerless run (a refused command can end its turn with no answer and exit 0) is a failure; your Google account sign-in (the one Gemini CLI now refuses); shell in agy's terminal sandbox (macOS, Linux); no web access for these workers; give it a fallback, its quota is per account; see [the notes](docs/backends.md#antigravity-cli-notes) |
699
+ | Antigravity CLI | macOS; beta on Linux and Windows | a read-only [snapshot](#modes) of its own for every read run (agy has no read-only mode for headless runs) | tokens only | checked against agy 1.4.7 on macOS (`scripts/check-worker.mjs`), not yet on Linux or Windows; use `-i` for changes, not `-w` (its deny rules are patterns, a layer on top of the git guard and the isolated copy); runs with a home of its own per workspace (agy reads its settings only from `~/.gemini`), so its commands do not see your dotfiles; an answerless run (a refused command can end its turn with no answer and exit 0) is a failure; your Google account sign-in (the one Gemini CLI now refuses); shell in agy's terminal sandbox (macOS, Linux); no web access for these workers; give it a fallback, its quota is per account; see [the notes](docs/backends.md#antigravity-cli-notes) |
698
700
 
699
701
  ### Models, costs and effort
700
702
 
@@ -712,7 +714,7 @@ claude haiku low/medium/high/xhigh/max ? - -
712
714
 
713
715
  Pitroom knows no vendor prices of its own and, unless you turn on `priceFeed` (see the config notes), fetches none, so a cost is what you enter: `"costs": {"codex:gpt-6-sol": 1, "codex:gpt-6.1-sol": 2}` in the config, in any unit (they are only compared; dollar prices for the receipts of Codex and Gemini go in `workerPrices`, see the config notes). `pitroom doctor` then prints the cost of the models in use and says when you priced a cheaper one of the same worker. A target that names only an effort (`codex:#low`) uses the model from `models`; a Codex or Claude Code worker with no pinned model gets a warning, because it would run the vendor's own default, which can change and cost more. `--effort LEVEL` sets the level for one run; your agent picks model and level from `pitroom models` (cheapest that fits: `low` for lookups, `medium` for ordinary changes, `high` for reviews).
714
716
 
715
- 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.
717
+ 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. A limit can come part way, after the worker started (a Codex or Claude plan's usage limit, an Antigravity quota): the next worker then takes the task over instead of the run failing. An edit (`-i`, `-w`) carries on in the same tree, and the next worker is told which files the one before it already changed and to finish, not start over; a read starts over. What both used is the run's cost. An audit falls back to the other auditors (the audit and cheap tiers, the fallbacks, the worker), never to the worker it audits. 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 ("retry in 4h", "try again at 8:56 PM", "resets 7:40pm (Europe/Istanbul)"), or a guess (an overload 20 minutes, a used-up allowance an hour, a daily quota four hours): 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.
716
718
 
717
719
  </details>
718
720
 
@@ -763,12 +765,13 @@ Or put defaults in `~/.config/pitroom/config.json` (flags and env still win); `p
763
765
  - `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.
764
766
  - `costs`: your relative cost per `worker:model`, only compared with each other; `maxParallel`: workers at once (default 20, at most 30).
765
767
  - `workerPrices`: USD per 1M tokens of a worker model, for the CLIs that report no cost (Codex, Gemini): `"workerPrices": {"codex:gpt-6.1-sol": "1.25,10,0.125"}` is "in,out[,cachedIn]", keyed `backend:model` (the model that ran, else the one you asked for) or `backend` alone. Without one the receipt says `worker cost n/a` and the run counts as free in the savings, which overstates them (`pitroom doctor` warns); with one the cost is estimated from the tokens, shown as `~$0.016 (estimated from your workerPrices)`, kept in the ledger, history and dashboard, and taken off the savings. Pitroom knows no vendor prices and does not fetch them, so this is your number.
766
- - `priceFeed`: keep a price catalog up to date (default `false`; `PITROOM_PRICE_FEED=1`). The catalog is the public [models.dev](https://models.dev) list OpenCode also reads (USD per 1M tokens of about 8,000 models): at most once a day (`priceFeedHours`, default 24), in a background process after a run, never while a run waits, Pitroom sends a plain `GET` for that one file (`priceFeedUrl` / `PITROOM_PRICE_FEED_URL` to use a mirror, `priceFeedHours` / `PITROOM_PRICE_FEED_HOURS` for the interval) and keeps a trimmed copy (about 400 KB) in its state directory; a failed refresh keeps the old copy and is not retried for an hour. It is only a fallback: your `workerPrices` come first, and the receipt says which was used (`estimated from models.dev prices`). With it, `"primary": "<model id>"` can name any model of the catalog for the savings comparison (`"primary": "claude-opus-5-5"`), where without it only the four presets exist. `pitroom prices` shows the feed, the catalog and the price each worker in use gets; `pitroom prices --refresh` fetches now. What it sends: [PRIVACY.md](PRIVACY.md). The listed prices are API list prices: a worker on a subscription (Codex with a ChatGPT account) does not pay them, so for such a worker the estimate is what the same tokens would cost on the API.
768
+ - `priceFeed`: keep a price catalog up to date (default `false`; `PITROOM_PRICE_FEED=1`). The catalog is the public [models.dev](https://models.dev) list OpenCode also reads (USD per 1M tokens of about 8,000 models): at most once a day (`priceFeedHours`, default 24), in a background process after a run, never while a run waits, Pitroom sends a plain `GET` for that one file (`priceFeedUrl` / `PITROOM_PRICE_FEED_URL` to use a mirror, `priceFeedHours` / `PITROOM_PRICE_FEED_HOURS` for the interval) and keeps a trimmed copy (about 400 KB) in its state directory; a failed refresh keeps the old copy and is not retried for an hour. It is only a fallback: your `workerPrices` come first, and the receipt says which was used (`estimated from models.dev prices`). With it, `"primary": "<model id>"` can name any model of the catalog for the savings comparison (`"primary": "claude-opus-5-5"`), where without it only the four presets exist. `pitroom prices` shows the feed, the catalog, the primary's price and the price each worker in use gets (`pitroom prices codex:gpt-6.1-sol` the price of the one named); `pitroom prices --refresh` fetches now. What it sends: [PRIVACY.md](PRIVACY.md). The listed prices are API list prices: a worker on a subscription (Codex with a ChatGPT account) does not pay them, so for such a worker the estimate is what the same tokens would cost on the API.
767
769
  - `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"`.
768
770
  - `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).
769
771
  - `auditFix` and `auditFocus`: send a disputed answer back to its worker for one correction, and lean the audit sample to list and count questions and to disputed workers (both default `false`; `PITROOM_AUDIT_FIX`, `PITROOM_AUDIT_FOCUS`), see [Audits](#audits).
770
772
  - `budgetDaily`: what the workers may cost per day, in USD (as their CLIs report it, or estimated from `workerPrices` and the price catalog; audits and corrections included). Past 80% a run warns; once it is spent only workers that cost nothing still run (a price of `0`, or a worker whose recent runs all cost exactly 0), a run with none in its chain is refused (exit 3), and audits and corrections do not start. A run that is still going counts with what it has used so far; runs started at the same moment count from their first finished step, so a crew can still end a day a little over. `0` allows only free workers. Default: no budget (`PITROOM_BUDGET_DAILY`).
771
- - `rankWorkers`: order the worker and its fallbacks by their record of the last 30 days: the share of runs that ended well (rate limits left out), times the share of audited answers that were confirmed (with 3 or more). Only workers with 5 runs or more move, among the places such workers hold, in steps of 10%; a worker you name (`-W`, `-m`, a tier) is never reordered, and the run says when the first worker changed (default `false`; `PITROOM_RANK_WORKERS=1`).
773
+ - `rankWorkers`: order the worker and its fallbacks by their record of the last 30 days on the same kind of work (a question, a change or a review: a model can answer well and still leave changes unfinished): the share of runs that ended well (rate limits left out), times the share of checked work that held up, with 3 checks or more (for an answer its audits, for a change the reviews of it that found the spec met and nothing to fix). Only workers with 5 runs or more of that kind move, among the places such workers hold, in steps of 10%; a worker you name (`-W`, `-m`, a tier) is never reordered, and the run says when the first worker changed (default `false`; `PITROOM_RANK_WORKERS=1`).
774
+ - `autoFallback`: with no `fallback` of yours, fall back to the other workers your config already names (its `tiers`, its `models` and its `worker`), the ones installed here, cheapest first by `costs` (those without a cost after, in the order named), at most four; never the worker itself at another effort level (default `false`; `PITROOM_AUTO_FALLBACK=1`). Pitroom still picks no model you did not name: it only reuses your own choices. Your `fallback` list, when you have one, and `--no-fallback` win; `pitroom doctor` says when the chain came from it.
772
775
  - `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).
773
776
 
774
777
  </details>