Skip to content

Releases: ATASTECH/pitroom

v0.24.1

Choose a tag to compare

@ATASTECH ATASTECH released this 14 Oct 22:38

Workers

  • Antigravity: a task that names files outside the project no longer stops halfway. agy's file tools stay in the workspace, and a headless agy cannot ask for more, so a read outside it ("copy the components from /tmp/ui-source") was refused and ended the turn without an answer. The folders and files a task names by absolute path (or ~/…) that exist outside the workspace are now granted read-only (the sandbox mounts them read-only too), with every secret-looking file in them denied (found at any depth and in every folder; a folder too big to check, with a link leading out of it or nowhere, or with a folder that cannot be read, is not granted, and a named path counts where its links lead). Never the root or a top-level folder such as /tmp, your home itself or a folder above it, a folder holding the workspace or the project, a dot-folder in your home (~/.config and the like) or ~/Library, Pitroom's own state or a secret-looking file, and nothing on Windows (agy compares paths there without their drive letter); the secrets in your home stay denied. In a snapshot or an isolated copy the project's own paths in the task are turned into the copy's (links resolved, so /tmp/… and /private/tmp/… alike): the worker reads and edits its copy instead of being refused at the project.

v0.24.0

Choose a tag to compare

@ATASTECH ATASTECH released this 14 Oct 20:33

Workers

  • Antigravity CLI worker (beta): -W antigravity[:model], Google's agy, with the user's Google account sign-in (which Gemini CLI now refuses). Checked against agy 1.3.5 on macOS: a read, a follow-up, an isolated edit and the deny rules were run against the real CLI, and the fixtures are its recorded output. agy has no read-only mode for headless runs (--mode plan is reported to still write), so its read runs read a read-only snapshot of their own, made right before its attempt: never the project, and never the snapshot other read runs share, where a stray file would outlive the run (a new readOnly: 'snapshot' capability). What git sees newly changed there afterwards is a READ-ONLY VIOLATION, and the worker after it in the chain reads where it was meant to, never that snapshot; as a fallback it costs nothing until it runs, pruning keeps these snapshots apart from the shared one, and a follow-up whose snapshot was pruned gets it made again; if the snapshot cannot be made it is skipped, never run in the project; --in-place, reviews and folders outside git warn instead, and doctor --probe runs it in an empty folder. Its answers are cached under where they were read. Write and isolate runs use --mode accept-edits; shell commands run in agy's terminal sandbox (--sandbox: the workspace writable, .git read-only, no network).
    • A home of its own per workspace. agy reads its settings only from ~/.gemini/antigravity-cli/settings.json (ANTIGRAVITY_APP_DATA_DIR is ignored), so a worker runs with HOME set to <pitroom home>/antigravity-home/<id>, one per workspace, so that a follow-up finds its conversation; the sign-in is linked in (the keychain folder on macOS, the token file elsewhere), and homes unused for two weeks are removed. Its settings grant sandboxed commands (command(*): without a grant a headless agy refuses every command and ends the turn without an answer), let agy write its plan into its own folder (plan mode does), keep file tools in the workspace, mount the toolchains of your PATH under your home read-only (an nvm node, so npm test works in the sandbox), and deny: the workspace's secret files and the secrets in your home by absolute path (read_file rules take no patterns, and a relative one breaks the sandbox), the forbidden commands, MCP tools and the web (--web does not apply to these workers).
    • Deny rules in agy's own matching: a rule is a command prefix compared word by word after agy has split the line at &&, ;, | and taken off wrappers such as env -i and timeout 60, and a regex: rule compares word by word too, with backslashes dropped. So each forbidden command is denied as it is, by path (/usr/bin/git), behind git's global options (git -c x=y commit, git --no-pager push), and any recursive rm (rm src -rf, rm -r -f); sh -c, eval, find with -exec, -ok or -delete (agy does not look inside it, so it is refused outright), and xargs running a forbidden command. A line with {} in it is not split, and is matched whole: rules for that find xargs, find, git <subcommand> and rm -r anywhere in it. They are patterns, a layer on top and not a guarantee: other spellings can get past them, so the git guard (and .git, read-only in the sandbox) holds for git, and the snapshot or the isolated copy holds for your files; use -i for changes, not -w.
    • Its stream as agy writes it: {"event": …} with the payload under the event's name (result.response, result.usage, init.model), tool steps that end in state ERROR when refused, and result.denied_actions. --continue resumes by conversation id; agy starts a new conversation for an id it does not know and says so only on stderr, which the run now shows as a warning. A run without an answer is a failure, never an empty answer: a refused command can end agy's turn with SUCCESS, no answer and exit 0. A used-up quota exits 3 with an AGY_ERROR line (rate-limited, so the chain moves on), an unknown model exits 1 (model-unavailable), a missing sign-in is auth. A prompt the model's safety filter blocks (This request was blocked by Gemini's filters…, status SUCCESS) is a failure, not the answer. agy is added to the "other agents" every worker is denied.
  • A run's own snapshot no longer blames the worker for every file. A snapshot is a checkout without a commit, so git calls each of its files "added"; the check for what a worker wrote there counted them all, and every Antigravity read run came out a READ-ONLY VIOLATION (exit 5, answer not cached). Only what differs from the snapshot's index counts now.
  • A worker can add warnings of its own to a finished run (Antigravity's lost conversation).
  • One list of forbidden commands (src/backends/deny.ts) for Claude Code, Qwen Code and Antigravity, now with rm -r, rm -R and rm --recursive (OpenCode already denied them); a test keeps Gemini's rule file and OpenCode's profiles in step. Gemini's private home is now written atomically (retried, then written in place, while Windows holds the file open) and repairs a dangling sign-in link (a shared helper with Antigravity's).

v0.23.0

Choose a tag to compare

@ATASTECH ATASTECH released this 08 Oct 20:22

Answers

  • Complete lists and counts. Audits kept finding answers whose references were right but whose lists left items out and whose counts were off (on PI-Desktop, 5 of 8 answers were partly right, mostly for that; one counted "about 40" tests where there are 59). The worker contract asked for none of it and told the worker to be economical. A read worker is now told, when the task asks for all of something, a list or a count, to search the whole scope instead of stopping at the first hits, to give the full list or the exact count in DETAILS and say how it found it, and to say under OPEN ISSUES what it did not cover; "be economical" no longer applies to such a search. The answer format is unchanged.
  • The auditor gets one reply form. The audit's question was wrapped in the worker contract, so the auditor was also told to be economical (while asked to count again) and to end with the SUMMARY/DETAILS format (while asked to reply with AUDIT: and nothing else). It now gets the same rules without those two.

Audits

  • A disputed answer can be corrected ("auditFix": true, PITROOM_AUDIT_FIX=1; off by default). When an audit says PARTIAL or DISAGREE with disputed claims, the answer goes back to the worker that gave it, as a follow-up in its own session: check each disputed claim against the files (the auditor can be wrong too), answer again in full, and say which claims were accepted. One round: a correction is never sent back again. pitroom show and the card name the correction (── fix: …), and the correction says what it corrects.
  • A focused audit sample ("auditFocus": true, PITROOM_AUDIT_FOCUS=1; off by default). The audit rate is doubled for a question that asks for all of something, a list or a count, doubled again for a worker whose audited answers were confirmed less than half the time (3 audits or more in 30 days), and halved for one whose last 5 or more were all confirmed. --audit / --no-audit win; the run records the chance it got and why (auditFocus).

Evals

  • pitroom eval QUESTIONS.json [-W worker]… [--json]: your own questions about your own code, with known answers, put to each worker as read runs of one group (no fallback, no audit, no cached answer) and scored the way benchmarks/multi-repo scores: a definition 1 for the exact path:line (0.5 for the right file), a count only for the exact number, a list the F1 of its paths. A truth is written down or looked up with git grep when the eval starts, so it stays right as the code changes. Prints one line per answer and a table per worker (score, per kind, failures, median time and tokens).

Costs

  • A daily budget ("budgetDaily": 5, PITROOM_BUDGET_DAILY; none by default): what the workers may cost per day, as reported or estimated, 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 of them in its chain is refused (exit 3), and audits and corrections do not start. A run that is still going counts with its cost so far (reported, or estimated from your prices), read from its stream when the next run asks, so one long run, or a crew past its first steps, cannot let later runs start on a budget it has already spent; runs started at the same moment count from their first finished step.

Workers

  • Qwen Code worker (beta): -W qwen[:model], with the user's sign-in and model from ~/.qwen/settings.json (any OpenAI-compatible provider, DashScope, a local model). Read runs use plan mode; write and isolate runs approve edits only inside the working directory (auto-edit would approve them anywhere: in a test an isolated run edited the real checkout), with the shell minus history-changing git. --safe-mode keeps the user's QWEN.md, hooks, skills and MCP servers out and stops the CLI's background memory extraction, which otherwise writes what a run saw into ~/.qwen/memories; worktree, cron, memory, subagent and messaging tools are excluded (plan mode alone let enter_worktree make a branch). --continue works by session id. A used-up quota surfaces in about 80 s instead of after 10 × 60 s of retries. Checked against Qwen Code 0.25.0 with a scripted model endpoint (the fixtures are the real CLI's output); not yet with a real provider. See docs/backends.md.

  • Workers ranked by their record ("rankWorkers": true, PITROOM_RANK_WORKERS=1; off by default): the worker and its fallbacks are ordered by the share of their runs that ended well in the last 30 days (rate limits left out) times the share of their audited answers that were confirmed. 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.

  • Kilo Code worker (beta): -W kilo[:provider/model], the CLI of @kilocode/cli, an OpenCode fork. It gets OpenCode's per-run permission profiles through KILO_CONFIG_CONTENT (read runs: no edit tools, no shell, no secret files, nothing outside the project; write runs: no history-changing git, no bulk deletes), and a private state folder: with the user's kilo daemon up, kilo run would otherwise attach to it, and the daemon ignores the injected profiles and the git guard. Checked against Kilo 7.8.8 with a scripted model endpoint (the fixtures are the real CLI's output); not yet with a real provider. kilo is added to the "other agents" every worker is denied.

  • Hermes Agent is not a worker (yet). It was looked at and left out: no read-only mode, file tools that write outside the project, shell commands auto-approved in headless runs, and no event stream. -W hermes says so; docs/backends.md lists what would change it.

Dashboard

  • Crew actions. A crew's card has Stop all (its running and queued runs) and Discard all (its finished, unapplied isolated copies), each asking once more, and Retry command, which shows the pitroom run … -g CREW --bg commands that start its failed, timed-out or stopped runs again, to copy. The page still never starts a run itself.
  • Retry commands for Windows. On Windows a crew's Retry command is written for PowerShell: single quotes with '' inside, Windows paths as they are, and no -- before the task (Windows PowerShell 5.1 drops it), unless the task itself starts with -. Elsewhere they stay POSIX shell commands.

Tests

  • The audited-run UI test is skipped without Chrome, like the other UI tests (it failed on machines without one).

v0.22.0

Choose a tag to compare

@ATASTECH ATASTECH released this 06 Oct 22:44

Workers

  • --continue works with Gemini. It was refused ("cannot continue sessions") because Gemini CLI's --resume was known to take an index or latest, which is not safe with parallel workers. It takes the session id as well (checked live on 0.62: a follow-up remembered what the first run read), and the id is in the stream's first event, so Pitroom resumes by it like with the other workers: pitroom run --continue last "…", or continue in pitroom_run.

Dashboard

  • A crew is one card. On the Live tab, runs that share a group (two or more: pitroom run -g name, a pitroom_run with tasks) now show as one card: the group name, the workers that are in it (opencode ×3), how many runs, how many are running, done or need attention, a progress bar, the tokens and the estimated saving of the crew, and when it started. It opens onto its runs, which are the usual cards; a crew that is still working is open by itself. A group of one run, and runs without a group, stay plain cards; the group picker still lists one crew's runs flat. A crew with a run among the newest is returned whole, so "Show older runs" never leaves it with fewer runs than it has.

v0.21.0

Choose a tag to compare

@ATASTECH ATASTECH released this 06 Oct 20:06

Windows

  • A real git guard on Windows. Until now the guard (a worker may not commit, reset, push, git add, clean and so on) was a sh script and Windows had none. Now the ref and push guard (git's own env config with a reference-transaction hook) is on there too, and the git shim runs on the sh.exe that Git for Windows brings (git.cmd for cmd.exe and PowerShell, git for Git Bash). A worker that starts git without a shell skips the shim and is left with the config layer. The guard tests, which were skipped on Windows, run there now; pitroom doctor reports the shim as ready or says what is missing.

Costs

  • A price catalog that keeps itself up to date (opt-in). "priceFeed": true (or PITROOM_PRICE_FEED=1): at most once a day, in a background process after a run (a run never waits for it), Pitroom fetches the public models.dev price list (the one OpenCode reads; USD per 1M tokens of about 8,000 models) and keeps a trimmed copy (about 400 KB) in its state directory; a failed or implausible answer keeps the old copy and is not retried for an hour. It is a fallback behind your own workerPrices, and the receipt says which was used (estimated from models.dev prices). "primary" can then be any model id of the catalog for the savings comparison, so it no longer goes stale (before: four fixed presets). New command pitroom prices [--refresh] [--json], a doctor line, and settings priceFeedUrl and priceFeedHours. Off by default, because until now Pitroom's own code made no network request at all: PRIVACY.md says what the request carries (nothing about you; a plain GET) and what it shows (your IP address to models.dev).
  • Prices for the CLIs that report no cost. Codex and Gemini give tokens but no cost, so a run's worker cost was n/a and counted as free in the savings, which overstated them. The new config "workerPrices": {"codex:gpt-6.1-sol": "1.25,10,0.125"} (USD per 1M tokens, "in,out[,cachedIn]", keyed backend:model or backend) lets you say what they cost: the cost is then estimated from the tokens, shown as ~$0.016 (estimated from your workerPrices) in the receipt and marked estimated in the dashboard, kept in the ledger and history, and taken off the savings. A cost the CLI reported always wins. pitroom doctor warns about a worker in your chain that reports no cost and has no price. Pitroom still knows no vendor prices and fetches none: the numbers are yours.

v0.20.0

Choose a tag to compare

@ATASTECH ATASTECH released this 06 Oct 12:18

Notifications

  • 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.

MCP

  • 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.

Stats

  • 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.
  • 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.

Fixes

  • 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.
  • 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.
  • 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.

Docs and tests

  • 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.
  • 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).
  • 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.

v0.19.0

Choose a tag to compare

@ATASTECH ATASTECH released this 05 Oct 18:14
3a131d0

Doctor

  • 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.

Fixes

  • 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.

Docs

  • 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.

v0.18.0

Choose a tag to compare

@ATASTECH ATASTECH released this 05 Oct 13:39
bb01e8e

Windows

  • The test suite runs on windows-latest (Node 22 and 24) in CI. Ten tests that need sh, POSIX file modes or the git guard are skipped there.
  • pitroom install makes a pitroom.cmd launcher; pitroom doctor starts it through a shell and warns that the git guard is not available.
  • Fixes found by running there: a directory spelled RUNNER~1 and the same one spelled runneradmin were taken for two places (isolate runs started in a directory that did not exist), so paths are compared as the file system names them; a bare ipc.ts:12 reference was not matched to src\main\ipc.ts; the secret-looking files in a warning used backslashes; a missing --verify command (is not recognized) was shown as a failing test; statusline --then needs a shell that exists; the Tailwind build step used a symlink; run records could not be replaced while watch or the dashboard had them open (EPERM), so it retries.
  • A spawn that fails because the working directory is missing says so, instead of " not found".
  • .gitattributes checks out with LF everywhere.

Dashboard

  • Stop and Discard from the page. A running card has a Stop button and a finished, not yet applied --isolate card has Discard, each with a confirmation. These are the dashboard's first writes, and the only ones: it still never starts a run or applies a patch. POST /api/run/<id>/stop and /discard need the secret the page was served with (random per start, compared in constant time) in x-pitroom-token and the dash's own Origin; anything else is 403, a POST elsewhere is 403, another method 405. A run that cannot be stopped or discarded (not active, not isolate, already applied or discarded) is 409.
  • pitroom stop and the dashboard share one stopRun.

Fixes

  • A stop request is recorded in a file of its own (stop-requested in the run's folder), not only in meta.json: the run's process writes meta.json too, and its write could drop the flag, so a stopped run showed as "worker process exited unexpectedly" (found on Windows, where the process dies at once on the signal).
  • pitroom dash --detach waits up to 20 s for the server (it was 6 s) while it imports old runs into the history.

v0.17.0

Choose a tag to compare

@ATASTECH ATASTECH released this 05 Oct 00:28

Answer cache

  • The same read question on the same code gets the earlier answer back at once instead of a new worker run (pitroom ⟲ cached answer · … · no worker ran). The key is the question (whitespace does not count), where it was asked, the attached files' contents, where the worker reads (a clean snapshot or in place) and the project's exact state: HEAD and a tree of every working file, uncommitted and untracked included (made with git's own index, so unchanged files are not re-hashed). Only answers that held up are reused: a finished read run with an answer, every reference verified, nothing written, and no audit still running or disagreeing, for cacheDays (default 7; 0 turns it off; PITROOM_CACHE_DAYS). Follow-ups, web runs, plan tasks, reviews, audits, --audit, --verify, crews and changes are never cached; --fresh asks a worker anyway and its answer is reused from then on. Git-ignored files and the worker/model are not part of the key (documented; --fresh for those). With --bg --json the earlier run comes back already done, marked "cached": true.

MCP server

  • Smaller tool definitions. Ten tools instead of eighteen, nothing lost: parallel work is pitroom_run with tasks (was pitroom_crew), every report is pitroom_info with a topic (runs, history, stats, savings, models, cooldown, config (new), doctor; were seven tools), pitroom_show gives a running run's progress (was pitroom_status, and run now defaults to the latest), and pitroom_stop with cooldowns clears the cooldowns. Descriptions are shorter. The definitions sit in the client's context for the whole session: about 1.9k tokens now, 3.3k before. An option that does not go with a topic is an error that names the ones that do.
  • Run notifications. A client can subscribe to a run's resource (resources/subscribe on pitroom://run/<id> or its /patch) and is told when the run changes state (for /patch also when it changed more files) or is gone (notifications/resources/updated); every client is told when the newest run changes (notifications/resources/list_changed; runs starting within one check are one notification). Read from the run records every 2 s, only while a client can be told; at most 100 subscriptions per client. An event stream nobody uses (no request, no event for an hour) is closed with its session. Over HTTP a GET with Accept: text/event-stream opens the session's event stream, where these arrive (one stream per session, kept alive with comments); a client without one is told once it opens it. Few clients act on these yet; the tools work the same without them.

Fixes

  • pitroom review in a linked git worktree: the review package was written to the worktree's git directory, which lies outside the worktree, and a sandboxed reviewer (OpenCode) was refused reading it, so the review had nothing to review. There it now goes to <worktree>/.pitroom/ (added once to the repository's info/exclude, so git status stays clean) and is removed when the review ends. Found by having Pitroom review its own branches from a worktree.

MCP Registry

  • server.json describes Pitroom for the MCP Registry (io.github.ATASTECH/pitroom: the npm package, stdio, pitroom mcp), and package.json has the mcpName the registry checks. npm run bump keeps its version in step, and turns an ## Unreleased CHANGELOG section into the version's entry.

From real-world tests (Codex driving Pitroom over MCP)

  • --verify under an MCP client. An app that starts Pitroom often passes a bare PATH, and npm test was "command not found" (exit 127). The verify command now also finds the Node running Pitroom (npm and npx sit next to it) and the usual install places, after your own PATH; a command that still is not found is reported as "could not run (exit 127: command not found)" with what to do, not as a failing test.
  • A failed --verify is no longer shown as success. The report says ⚠ done · verify failed instead of ✔ done, an MCP result is an error (isError, as is a read-only violation), and the dashboard shows a warning icon on the card and lists the run under Needs attention.
  • Audits check the question, not only the references. The auditor must check every condition the question sets (scope, exclusions, "all", "only", counts), look for missing and extra items in a list and recount a count; AGREE needs all of them. In the tests an answer that listed 8 files outside the asked directory got AGREE from two of three auditors, because its references were valid.
  • Skills over MCP. An agent using the MCP tools did not think of Pitroom's skills. The server's instructions now name them and say to use the matching one, pitroom_run points to using-pitroom, and every skill is also a prompt of the same name (its text, with how the CLI commands in it map to the tools), for clients that have no skills.
  • pitroom review --range A..B shows the branch's own change, from where it left A, as a pull request does. When A had moved on since (another PR merged), the diff also showed A's newer commits as if the branch undid them.
  • An OpenCode model answering "Endpoint is unavailable" (HTTP 400) is treated as rate-limited: it cools down and the next worker runs (this already worked; it now has a test).

v0.16.0

Choose a tag to compare

@ATASTECH ATASTECH released this 04 Oct 19:01

MCP server

  • Progress notifications. A call that waits for a run reports how it is doing every few seconds (notifications/progress, when the client sent a progress token), so the agent sees what the worker is doing; 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.
  • Cancellation. A client that cancels pitroom_run, pitroom_crew, pitroom_review or pitroom_audit (notifications/cancelled) stops the run or group it started and gets no answer, as the protocol says; a cancelled pitroom_wait only stops waiting. A client that sends its requests and closes the pipe still gets the answers.
  • Resources. The latest runs are resources, pitroom://run/<id> (the report) and pitroom://run/<id>/patch (the exact diff), with resource templates; anything else is "not found" (-32002).
  • Prompts. research, implement, review and crew, with their arguments checked.
  • Nine new tools (18 in all): pitroom_crew (independent tasks in parallel as one group), pitroom_list, pitroom_history (search earlier answers), pitroom_stats, pitroom_savings, pitroom_models, pitroom_cooldown, pitroom_doctor and pitroom_revert (undo a write run); pitroom_run takes continue for a follow-up in the same worker session, and pitroom_apply can apply a group.
  • HTTP transport. pitroom mcp --http [--port N] serves the same server over Streamable HTTP at http://127.0.0.1:7117/mcp, for clients that connect to a URL. Local by construction: 127.0.0.1 only, a bearer token (generated on first start into <state dir>/mcp-token, mode 0600, or PITROOM_MCP_TOKEN; compared in constant time), and a Host or Origin that is not local is refused with 403 (DNS rebinding). Sessions per client (Mcp-Session-Id), so a cancel only touches the cancelling client's request even when two clients use the same request id; a call that sends a progress token is answered as an event stream. Ending a session (DELETE) or stopping the server ends the waiting, not the runs. When 64 sessions are open, the one unused longest makes room for a new one. Checked with the real Claude Code client (claude mcp add --transport http …, claude mcp list: connected).
  • pitroom mcp -d DIR (stdio or HTTP) works in that project, for clients such as Claude Desktop that start the server somewhere else; --port without --http is a usage error.
  • The server is split into protocol (mcp.ts), tools (mcp-tools.ts), resources and prompts (mcp-extras.ts) and what they share (mcp-support.ts).