pitroom 0.17.0 → 0.19.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.
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/CHANGELOG.md +28 -0
- package/README.md +23 -3
- package/dist/lib.mjs +1 -1
- package/dist/pitroom.mjs +354 -256
- package/dist/ui/app.js +27 -27
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
|
@@ -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.
|
|
4
|
+
"version": "0.19.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "TahaAtas"
|
|
7
7
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pitroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
### Doctor
|
|
6
|
+
- `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.
|
|
7
|
+
|
|
8
|
+
### Fixes
|
|
9
|
+
- **`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.
|
|
10
|
+
|
|
11
|
+
### Docs
|
|
12
|
+
- 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`.
|
|
13
|
+
|
|
14
|
+
## 0.18.0
|
|
15
|
+
|
|
16
|
+
### Windows
|
|
17
|
+
- 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.
|
|
18
|
+
- `pitroom install` makes a `pitroom.cmd` launcher; `pitroom doctor` starts it through a shell and warns that the git guard is not available.
|
|
19
|
+
- 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.
|
|
20
|
+
- A spawn that fails because the working directory is missing says so, instead of "<command> not found".
|
|
21
|
+
- `.gitattributes` checks out with LF everywhere.
|
|
22
|
+
|
|
23
|
+
### Dashboard
|
|
24
|
+
- **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.
|
|
25
|
+
- `pitroom stop` and the dashboard share one `stopRun`.
|
|
26
|
+
|
|
27
|
+
### Fixes
|
|
28
|
+
- 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).
|
|
29
|
+
- `pitroom dash --detach` waits up to 20 s for the server (it was 6 s) while it imports old runs into the history.
|
|
30
|
+
|
|
3
31
|
## 0.17.0
|
|
4
32
|
|
|
5
33
|
### Answer cache
|
package/README.md
CHANGED
|
@@ -150,7 +150,7 @@ Every run prints a receipt, and `pitroom savings` adds them up (`--card` writes
|
|
|
150
150
|
|
|
151
151
|
## Dashboard
|
|
152
152
|
|
|
153
|
-
`pitroom dash --detach` prints the address of a live page on `127.0.0.1` (
|
|
153
|
+
`pitroom dash --detach` prints the address of a live page on `127.0.0.1` (this machine only; it reads your runs and changes nothing but the two actions below). It is for the places where hook messages and status lines do not reach, such as the Claude Code and Codex apps: open it in a browser or in the app's own browser pane. The skills tell your agent to start it and give you the address when it runs workers in the background.
|
|
154
154
|
|
|
155
155
|
The screenshots below show sample data (an imaginary `shop-api` project), not a real one.
|
|
156
156
|
|
|
@@ -170,6 +170,8 @@ The screenshots below show sample data (an imaginary `shop-api` project), not a
|
|
|
170
170
|
|
|
171
171
|
<p align="center"><img src="docs/dash-history.png" width="49%" alt="The History tab: a search box, filters and every past run as a card"> <img src="docs/dash-stats.png" width="49%" alt="The Stats tab: totals, runs per day, and per worker and model its logo, success rate and how many of its audited answers another worker confirmed"></p>
|
|
172
172
|
|
|
173
|
+
**Stop and Discard.** A running card has a Stop button, and a finished `--isolate` card that is not applied yet has Discard (the same as `pitroom stop` and `pitroom discard`; the patch file stays). Each asks once more. Nothing else can be done from the page: it never starts a run and never applies a patch. A POST needs the secret the page was served with (it changes every time the dashboard starts) and the page's own origin, so a web page on another site cannot press them.
|
|
174
|
+
|
|
173
175
|
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).
|
|
174
176
|
|
|
175
177
|
---
|
|
@@ -241,6 +243,15 @@ To repeat it on your own repository: `pitroom crew -d <repo> -g bench "<question
|
|
|
241
243
|
|
|
242
244
|
---
|
|
243
245
|
|
|
246
|
+
## Platforms
|
|
247
|
+
|
|
248
|
+
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:
|
|
249
|
+
|
|
250
|
+
- **No git guard.** Pitroom's shim that blocks a worker's history changes and pushes is a `sh` script and is not available on Windows; `pitroom doctor` says so. Read-only runs are still limited by each worker CLI's own rules and `--isolate` keeps edits in a copy, so prefer `--isolate` and check the patch before `apply`.
|
|
251
|
+
- **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.
|
|
252
|
+
- **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`.
|
|
253
|
+
- 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`.
|
|
254
|
+
|
|
244
255
|
## Quick start
|
|
245
256
|
|
|
246
257
|
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) or [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).
|
|
@@ -271,9 +282,18 @@ gemini extensions install https://github.com/ATASTECH/pitroom
|
|
|
271
282
|
npm i -g pitroom
|
|
272
283
|
```
|
|
273
284
|
|
|
274
|
-
**
|
|
285
|
+
**Cursor**
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
npm i -g pitroom
|
|
289
|
+
pitroom install --mcp --client cursor
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
<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>
|
|
293
|
+
|
|
294
|
+
**Any agent that speaks MCP (Claude Desktop, and the ones above too)**
|
|
275
295
|
|
|
276
|
-
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. After `npm i -g pitroom`, let Pitroom register itself in the clients it finds (Claude Code, Codex, Gemini CLI, Cursor, Claude Desktop):
|
|
296
|
+
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):
|
|
277
297
|
|
|
278
298
|
```bash
|
|
279
299
|
pitroom install --mcp # also links the skills; add --no-skills to skip that
|
package/dist/lib.mjs
CHANGED
|
@@ -1384,7 +1384,7 @@ function verifyRefs(refs, dirs) {
|
|
|
1384
1384
|
if (direct) return [direct];
|
|
1385
1385
|
if (path7.isAbsolute(ref.file)) return [];
|
|
1386
1386
|
const wanted = ref.file.replace(/^(\.{1,2}\/)+/, "");
|
|
1387
|
-
return (byName().get(path7.basename(wanted)) ?? []).filter((f) => f.endsWith(`/${wanted}`) || path7.basename(f) === wanted).slice(0, 20);
|
|
1387
|
+
return (byName().get(path7.basename(wanted)) ?? []).filter((f) => f.split(path7.sep).join("/").endsWith(`/${wanted}`) || path7.basename(f) === wanted).slice(0, 20);
|
|
1388
1388
|
};
|
|
1389
1389
|
const check = (file, ref) => {
|
|
1390
1390
|
const lines = load(file);
|