pitroom 0.22.0 → 0.23.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 +30 -0
- package/README.md +37 -4
- package/dist/lib.mjs +1234 -659
- package/dist/pitroom.mjs +1270 -495
- package/dist/ui/app.css +1 -1
- package/dist/ui/app.js +32 -30
- package/docs/backends.md +56 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/policies/gemini/shell.toml +4 -1
- package/policies/qwen/worker-defaults.json +9 -0
package/docs/backends.md
CHANGED
|
@@ -59,6 +59,8 @@ CLI's **own** mechanism, and never with flags that switch safety off
|
|
|
59
59
|
| **Codex** (`exec --json --ignore-user-config`) | `-c sandbox_mode="read-only"` (OS sandbox) | `-c sandbox_mode="workspace-write"` (writes only in the working dir, no network), `approval_policy="never"` | `exec resume <id>` | tokens only |
|
|
60
60
|
| **Claude Code** (`-p --output-format stream-json --verbose`) | `--safe-mode --restricted --strict-mcp-config`, `--permission-mode dontAsk`, tools `Read,Grep,Glob` only | same lockdown, tools `+Edit,Write,Bash`, `--disallowedTools Bash(git commit:*)`… | `--resume <id>` | `total_cost_usd` |
|
|
61
61
|
| **Gemini CLI** (`--prompt … --output-format stream-json`) | `--approval-mode plan` (the policy engine allows read tools only) | `auto_edit` + Pitroom's `--policy` rules (shell minus history-changing git) | by session id (`--resume <id>`) → `resume: 'by-id'` | tokens only |
|
|
62
|
+
| **Qwen Code** (`<prompt> --safe-mode --output-format stream-json`) | `--approval-mode plan` (edits, shell and reads outside the working directory declined) | `--approval-mode default` + `--allowed-tools Edit(./**) write_file(./**) notebook_edit(./**) run_shell_command`, shell minus history-changing git via `--exclude-tools` | `--resume <id>` | tokens only |
|
|
63
|
+
| **Kilo Code** (`kilo run --format json`) | OpenCode's read profile through `KILO_CONFIG_CONTENT` | OpenCode's write profile | `--session <id>` | reported |
|
|
62
64
|
|
|
63
65
|
Whatever the CLI, the core still applies the git guard, closes stdin (Codex and
|
|
64
66
|
Gemini otherwise read piped stdin into the prompt), sets `PWD` to the worker's
|
|
@@ -124,6 +126,60 @@ How a worker is started:
|
|
|
124
126
|
- **Resume**: `--resume` takes the session id that the stream's `init` event reports (checked live on 0.62: the follow-up remembered what the first run read), as well as an index or `latest` (which are not safe with parallel workers, so Pitroom never uses them). `--continue` therefore works (`resume: 'by-id'`). Sessions are kept per project folder, so a follow-up runs in the same folder as its parent, which Pitroom does anyway.
|
|
125
127
|
- **Sign-in**: a Google account sign-in (`oauth-personal`, Code Assist for individuals) is refused by Google for this client (`IneligibleTierError`); use an API key from Google AI Studio (`gemini` stores it, or set `GEMINI_API_KEY`).
|
|
126
128
|
|
|
129
|
+
## Qwen Code notes
|
|
130
|
+
|
|
131
|
+
Status: **beta**, checked against Qwen Code 0.25.0. The fixtures in `test/fixtures/qwen` were recorded from the real CLI, started with Pitroom's own command line, against a **scripted OpenAI-compatible endpoint** (a small local server that answers with prepared tool calls and text): the events, permission decisions, refusals and error output are the CLI's, the model is not. It has not yet been run against a real model provider.
|
|
132
|
+
|
|
133
|
+
What was checked that way:
|
|
134
|
+
|
|
135
|
+
- **Read** runs (`--approval-mode plan`): `read_file`, `grep_search` and `glob` work; `write_file`, `run_shell_command` and a read outside the working directory are declined.
|
|
136
|
+
- **Write / isolate** runs: edits and new files inside the working directory land; an edit or a new file outside it (the user's real checkout from an isolated copy, another folder, a `../` path) is declined; `git commit` and `rm -rf` are refused by Pitroom's deny rules; other shell commands run. End to end (`pitroom run -i -W qwen:…`): the changes come back as the isolated copy's patch and the user's tree is untouched.
|
|
137
|
+
- **`--continue`**: `--resume <session id>` (the id of the stream's `init` event) sends the earlier turns along.
|
|
138
|
+
- **Failures**: a bad key (401, `auth`), an unknown model (404, `model-unavailable`) and a used-up quota (429, `rate-limited`) are classified, did no work, and let the chain move on.
|
|
139
|
+
|
|
140
|
+
How a worker is started, and why:
|
|
141
|
+
|
|
142
|
+
- **Not `--approval-mode auto-edit`.** It approves an edit *anywhere on disk*: in a test an isolated run edited the user's real checkout and wrote to `/tmp`. `default` declines whatever is not allowed (a headless run cannot ask), and the allow rules name edits inside the working directory only (`./**` is relative to the CLI's cwd, which the core sets to the isolated copy or the project).
|
|
143
|
+
- **`--safe-mode`** keeps the user's QWEN.md, hooks, extensions, skills and MCP servers out, and turns off the **background memory extraction**: without it, every run ends with an extra request in which a subagent with `write_file` and `edit` writes "durable facts" from the run into `~/.qwen/memories` (user-wide) and the project's memory folder.
|
|
144
|
+
- **`--exclude-tools`**: even in plan mode Qwen Code runs `enter_worktree` (it made a git worktree and a branch in the project in a test), and it has subagents, memory, cron, messaging and goal tools. They are excluded in every mode, and `web_fetch` / `web_search` unless `--web`. An excluded tool the model calls anyway is declined, with a message the model sees.
|
|
145
|
+
- **The prompt is the first argument**: `--exclude-tools` and `--allowed-tools` take every following word, and Qwen Code reads no prompt after `--`. A prompt that starts with `-` gets a leading space.
|
|
146
|
+
- **`QWEN_CODE_SYSTEM_DEFAULTS_PATH`** points at `policies/qwen/worker-defaults.json`: no auto-update, no memory extraction, and `maxRetries: 0`, which removes the CLI's 10 × 60 s waits on a rate limit. Its other retry layer (7 tries with backoff) stays, so a used-up quota surfaces after about 80 s, not 10 minutes. These are *defaults*: the user's own settings win, and an enterprise system settings file is left alone. `QWEN_CODE_DISABLE_CRON=1` and `QWEN_DISABLE_AUTO_TITLE=1` are set too.
|
|
147
|
+
- **Sign-in and model** come from the user's `~/.qwen/settings.json` (`security.auth.selectedType`, `model.name`) and environment (`OPENAI_API_KEY`, `OPENAI_BASE_URL`, …); `-W qwen:<model>` passes `--model`. There is no effort option: `#level` is dropped. Cost is not reported (tokens only): give it a price with `workerPrices`.
|
|
148
|
+
|
|
149
|
+
What is **not** enforced, so do not rely on it:
|
|
150
|
+
|
|
151
|
+
- **Secret files.** `read_file` reads `.env` inside the working directory. What protects a read run is Pitroom's **read snapshot** (a directory with secret-looking files is read as a clean snapshot without them); edit runs rely on the worker being told not to read them.
|
|
152
|
+
- **The shell is not confined.** An allowed shell command can write outside the working directory, as with the other workers that have a shell; the git guard still holds, and the deny rules are prefix based.
|
|
153
|
+
|
|
154
|
+
## Kilo Code notes
|
|
155
|
+
|
|
156
|
+
Status: **beta**, checked against `@kilocode/cli` 7.8.8. Kilo Code's CLI is a fork of OpenCode: the same `run --format json` events, agents and permission rules, so the adapter reuses OpenCode's profiles and parser. Like the Qwen Code fixtures, `test/fixtures/kilo` was recorded from the real CLI, started with Pitroom's own command line, against a **scripted OpenAI-compatible endpoint**; not yet with a real provider.
|
|
157
|
+
|
|
158
|
+
What was checked that way, with a `kilo daemon` running:
|
|
159
|
+
|
|
160
|
+
- **Read** runs: `read` and `grep` work; the edit tools are not offered at all, and `bash`, a `.env` read and a read outside the project are refused by the profile.
|
|
161
|
+
- **Write / isolate**: edits and new files inside the project land; a write outside it and `git commit` are refused. End to end (`pitroom run -i -W kilo:…`), the change comes back as the isolated copy's patch and the user's tree is untouched.
|
|
162
|
+
- **`--continue`**: `--session <id>` sends the earlier turns along.
|
|
163
|
+
- **Failures**: an unknown model (`model-unavailable`), a bad key (`auth`) and a used-up quota (`rate-limited`, after about 80 s of the CLI's own retries) did no work, so the chain moves on.
|
|
164
|
+
|
|
165
|
+
How a worker is started, and why:
|
|
166
|
+
|
|
167
|
+
- **`KILO_CONFIG_CONTENT`**, not `OPENCODE_CONFIG_CONTENT`: Kilo reads its own variable (checked with `kilo debug config`). The profiles' scratch-folder rules point at Kilo's folders (`~/.local/share/kilo/…`, `$TMPDIR/kilo/…`), and the config sets `autoupdate: false`.
|
|
168
|
+
- **A private `XDG_STATE_HOME`** (`<pitroom home>/kilo-state`). `kilo run` has no `--standalone`: when the user's `kilo daemon` is up, it attaches to it (found through `~/.local/state/kilo/daemon.json`), and the daemon, started with its own environment, ignores the injected config, the git guard and `PITROOM_ACTIVE` (seen: "Agent not found: pitroom-read"; `--port` and `--pure` do not prevent it). With a state folder of its own the worker finds no daemon and starts a private server. Sign-in, config and sessions live in the data and config folders, which stay the user's.
|
|
169
|
+
- **`--log-level ERROR`** in capitals: Kilo rejects `error` and prints its help instead of running.
|
|
170
|
+
- Never `--auto` ("auto-approve permissions that are not explicitly denied"), never `--attach`.
|
|
171
|
+
|
|
172
|
+
## Hermes Agent: not supported yet
|
|
173
|
+
|
|
174
|
+
[Hermes Agent](https://pypi.org/project/hermes-agent/) (Nous Research; looked at 0.19.0 from PyPI) was considered and left out, because it lacks the controls every other worker gets from its own CLI:
|
|
175
|
+
|
|
176
|
+
- **No read-only mode.** Tools come in toolsets, and the `file` toolset holds `read_file` together with `write_file` and `patch`; single tools cannot be turned off, and there is no plan or approval mode for files.
|
|
177
|
+
- **Writes outside the working directory are allowed.** The file tools warn when a path resolves outside the workspace and write anyway.
|
|
178
|
+
- **Dangerous shell commands are auto-approved without a person.** In a non-interactive run that is not its messaging gateway, the approval check lets them through (`-z` bypasses approvals outright); a fail-closed path exists in the code, but not as a CLI switch.
|
|
179
|
+
- **No event stream.** `chat -q -Q` prints the final answer and the session id, nothing about steps, tool calls or tokens (`--usage-file` only works with `-z`).
|
|
180
|
+
|
|
181
|
+
Pitroom's own guards (the git guard, isolated copies, the read snapshot) would still apply, but not the CLI-level confinement the other workers have, so it would be the one worker that can write anywhere. `-W hermes` therefore says it is not supported yet. What would change that: a read-only (or per-tool) switch, file tools confined to the working directory, a fail-closed approval switch for headless runs, and a JSON event stream; or its Docker terminal backend with the project mounted, which would need Docker on the user's machine.
|
|
182
|
+
|
|
127
183
|
## Adding a worker
|
|
128
184
|
|
|
129
185
|
1. Create `src/backends/<id>/index.ts` exporting a `Backend`; keep CLI knowledge
|
package/gemini-extension.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pitroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "A free pit crew for your expensive coding agent: hand reading, fixes, tests and reviews to cheap worker agents and get back the answer, the exact diff and a receipt. Fourteen skills adapt a full development workflow. Needs the pitroom command (npm i -g pitroom).",
|
|
5
5
|
"contextFileName": "gemini-context.md"
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pitroom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"mcpName": "io.github.ATASTECH/pitroom",
|
|
5
5
|
"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, Claude Code or Gemini CLI workers, with receipts that prove the savings.",
|
|
6
6
|
"type": "module",
|