pitroom 0.8.1 → 0.10.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/docs/backends.md CHANGED
@@ -58,7 +58,7 @@ CLI's **own** mechanism, and never with flags that switch safety off
58
58
  | **OpenCode v2** (`run --standalone --format json`) | permission profile: edit denied, shell allowlist, `execute` and web off | profile: edits on, history-changing git, bulk deletes and `execute` denied | `--session <id>` | reported |
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
- | **Gemini CLI** (soon; `-p -o stream-json`) | `--approval-mode plan` | `auto_edit` + policy engine rules | index/latest only → `resume: 'none'` | tokens only |
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) | index/latest only → `resume: 'none'` | tokens only |
62
62
 
63
63
  Whatever the CLI, the core still applies the git guard, closes stdin (Codex and
64
64
  Gemini otherwise read piped stdin into the prompt), sets `PWD` to the worker's
@@ -97,6 +97,33 @@ Recorded v2 streams live in `test/fixtures/opencode/{events,failures}/v2-*`; the
97
97
  - **Errors**: an API error arrives as an assistant message with `is_api_error_message` (e.g. `authentication_failed`, "OAuth session expired"); it is not counted as work, so the fallback chain can move on.
98
98
  - **Model**: the init event names it. The user's default is often an Opus-class model; `doctor` warns and suggests `-W claude:haiku`.
99
99
 
100
+ ## Gemini CLI notes
101
+
102
+ Status: **beta**, tried against Gemini CLI 0.62 with a Google AI Studio API key (`gemini-api-key`). Real runs are recorded under `test/fixtures/gemini` (a read run, an edit run, a retired model, a daily quota); the two older fixtures there (`read-flash`, `write-edit`) are constructed from the CLI's event types and cover a denied tool call.
103
+
104
+ What was checked live:
105
+
106
+ - **Read** runs (`--approval-mode plan`): files are read, and a write (`write_file`) is refused by the CLI ("Plan Mode").
107
+ - **Isolate / write** runs: edits land in the isolated copy only; the original is untouched. Shell commands matching `policies/gemini/shell.toml` (`git commit`, `git push`, `rm -rf`, `sudo`, other agents) are refused with Pitroom's message, others run.
108
+ - **Fallback**: a quota or retired-model failure is classified (`rate-limited`, `model-unavailable`) and the chain moves to the next worker.
109
+
110
+ What is **not** enforced, so do not rely on it:
111
+
112
+ - **Secret files.** `policies/gemini/base.toml` has deny rules for `.env`, `*.pem` and SSH keys, and the CLI loads them without errors, but in live tests Gemini 0.62 still read `server.pem` and `prod.env` (even a plain deny-all `read_file` rule was ignored). It does refuse a bare `.env`. The worker is also told not to read secrets, and Pitroom warns when secret-looking files sit in the directory: use `--isolate` (git-ignored files are left out) or a clean checkout.
113
+ - **Shell rules are prefix based** (an unusual spelling of a forbidden command may pass), and a shell `cat .env` is not caught. Use read mode (no shell) when that matters.
114
+ - **Web**: `no-web.toml` denies `google_web_search` and `web_fetch` unless `--web`; this was not verified live.
115
+
116
+ How a worker is started:
117
+
118
+ - **`--approval-mode plan`** is the read-only mode; write and isolate use `auto_edit`. Never `--yolo` (the contract tests reject it and the worker settings disable it).
119
+ - **`--policy policies/gemini/*.toml`**: `base.toml` (secret rules above, MCP refused), `no-web.toml`, and `shell.toml` for write and isolate (shell is allowed, since a headless run cannot answer "ask the user", minus the forbidden commands). Gemini's loader rejects a rule without `toolName` and any regex it thinks could be slow (nested quantifiers), which skips the whole file: `npm test` checks the patterns, and a live run with the file is the final check.
120
+ - **A private `GEMINI_CLI_HOME`** (`<pitroom home>/gemini-home`): its settings come from `policies/gemini/worker-settings.json` plus your sign-in method (`security.auth`), with links to your `oauth_creds.json`. Your hooks, MCP servers, skills and global `GEMINI.md` are therefore not loaded (hooks would run on every worker; a worker also starts with ~20k fewer tokens). An API key kept in the keychain keeps working. A system settings file would be the usual place, but Gemini CLI 0.62 ignores one that root does not own. `-e none` turns extensions off, and the MCP allow list names a server nothing has (an empty list means "no restriction" there).
121
+ - **Folder trust**: a headless run in a folder Gemini does not trust fails. Folders you trusted in Gemini stay trusted. `PITROOM_GEMINI_TRUST=1` adds `--skip-trust`, which also lets that folder's own `.gemini` settings (hooks included) load.
122
+ - **Stream**: `message` events carry the answer in `delta` chunks, merged per model turn; the answer is the text after the last tool call. `result.stats` gives tokens (`cached` is part of `input_tokens`), not dollars. Lines that are not JSON are skipped.
123
+ - **Models**: Gemini CLI cannot list models; the catalogue is its built-in names (`gemini-3.8-flash`, `gemini-3.5-flash`, `gemini-3.5-flash-lite`, …). The 2.5 models are no longer served to new API keys. Its own default (`auto`) may be a larger model, so pin a worker, e.g. `-W gemini:gemini-3.8-flash`. The free tier has a small daily quota per model. No effort option: `#level` is dropped.
124
+ - **Resume**: sessions are chosen by index or `latest` per project, which is not safe with parallel workers, so `--continue` is not supported (`resume: 'none'`).
125
+ - **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
+
100
127
  ## Adding a worker
101
128
 
102
129
  1. Create `src/backends/<id>/index.ts` exporting a `Backend`; keep CLI knowledge
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pitroom",
3
- "version": "0.8.1",
4
- "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.",
3
+ "version": "0.10.0",
4
+ "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.",
5
5
  "type": "module",
6
6
  "author": "TahaAtas",
7
7
  "repository": {
@@ -20,6 +20,7 @@
20
20
  "bin",
21
21
  "skills",
22
22
  "hooks",
23
+ "policies",
23
24
  ".claude-plugin",
24
25
  ".codex-plugin",
25
26
  "assets",
@@ -0,0 +1,27 @@
1
+ # Pitroom's rules for Gemini CLI workers, every mode. Passed with --policy: user tier, so they outrank the CLI's
2
+ # own defaults (priority 900 here is 4.900 there). The read-only mode itself is Gemini's `--approval-mode plan`.
3
+
4
+ # A worker is told not to read secrets; these rules are meant to make the file tools refuse too. Gemini CLI 0.62 loads
5
+ # them without errors but did not apply them to read_file in live tests (docs/backends.md), so they are a second line
6
+ # at best. Patterns must avoid nested quantifiers: Gemini's loader skips the whole file for a "ReDoS" regex.
7
+ [[rule]]
8
+ toolName = "read_file"
9
+ decision = "deny"
10
+ priority = 950
11
+ argsPattern = '(?:[\\/]|")[^\\/"]*\.env"|(?:[\\/]|")[^\\/"]*\.env\.[^\\/"]*"|(?:[\\/]|")[^\\/"]*\.pem"|(?:[\\/]|")id_(?:rsa|ed25519|ecdsa|dsa)[^\\/"]*"'
12
+ deny_message = "Pitroom: secret files (.env, keys) are not for workers."
13
+
14
+ [[rule]]
15
+ toolName = "read_many_files"
16
+ decision = "deny"
17
+ priority = 950
18
+ argsPattern = '\.env|\.pem|id_rsa|id_ed25519'
19
+ deny_message = "Pitroom: secret files (.env, keys) are not for workers."
20
+
21
+ # No other tool servers: MCP tools are refused (the system settings also allow no MCP server).
22
+ [[rule]]
23
+ toolName = "*"
24
+ mcpName = "*"
25
+ decision = "deny"
26
+ priority = 950
27
+ deny_message = "Pitroom: MCP tools are off for workers."
@@ -0,0 +1,6 @@
1
+ # Added unless the run asked for the web (--web): Gemini's plan mode would otherwise allow a web search.
2
+ [[rule]]
3
+ toolName = ["google_web_search", "web_fetch"]
4
+ decision = "deny"
5
+ priority = 950
6
+ deny_message = "Pitroom: the web is off for this run (use --web)."
@@ -0,0 +1,50 @@
1
+ # Added in write and isolate modes. Shell commands default to "ask the user", which a headless run cannot answer,
2
+ # so they are allowed here, minus history-changing git, bulk deletes and other agents (the git guard backs this up).
3
+ [[rule]]
4
+ toolName = "run_shell_command"
5
+ decision = "allow"
6
+ priority = 500
7
+
8
+ [[rule]]
9
+ toolName = "run_shell_command"
10
+ decision = "deny"
11
+ priority = 900
12
+ commandPrefix = [
13
+ "git commit",
14
+ "git push",
15
+ "git pull",
16
+ "git reset",
17
+ "git checkout",
18
+ "git restore",
19
+ "git clean",
20
+ "git stash",
21
+ "git rebase",
22
+ "git merge",
23
+ "git switch",
24
+ "git branch",
25
+ "git tag",
26
+ "git rm",
27
+ "git worktree",
28
+ "git update-ref",
29
+ "git config",
30
+ "git remote",
31
+ "git cherry-pick",
32
+ "git revert",
33
+ "git am",
34
+ "git add",
35
+ "rm -rf",
36
+ "rm -fr",
37
+ "sudo",
38
+ "chown",
39
+ "kill",
40
+ "pkill",
41
+ "killall",
42
+ "gh",
43
+ "npm publish",
44
+ "pitroom",
45
+ "opencode",
46
+ "claude",
47
+ "codex",
48
+ "gemini"
49
+ ]
50
+ deny_message = "Pitroom: history-changing git, destructive commands and other agents are not for workers."
@@ -0,0 +1,9 @@
1
+ {
2
+ "general": { "enableAutoUpdate": false, "enableAutoUpdateNotification": false, "checkpointing": { "enabled": false } },
3
+ "hooksConfig": { "enabled": false },
4
+ "mcp": { "allowed": ["pitroom-no-mcp-servers"] },
5
+ "skills": { "enabled": false },
6
+ "security": { "disableYoloMode": true, "disableAlwaysAllow": true },
7
+ "privacy": { "usageStatisticsEnabled": false },
8
+ "telemetry": { "enabled": false }
9
+ }
@@ -9,7 +9,7 @@ If you are a Pitroom worker, or were dispatched as a subagent for one specific t
9
9
 
10
10
  # Using Pitroom
11
11
 
12
- You are the primary agent: capable, expensive, and your context is precious. Pitroom gives you a development workflow as skills, and a crew of cheap worker agents (OpenCode, Codex, Claude Code, on whatever models the user configured) that read, search, implement and review for you. You decide, verify and answer.
12
+ You are the primary agent: capable, expensive, and your context is precious. Pitroom gives you a development workflow as skills, and a crew of cheap worker agents (OpenCode, Codex, Claude Code, Gemini CLI, on whatever models the user configured) that read, search, implement and review for you. You decide, verify and answer.
13
13
 
14
14
  ## Optional by design
15
15
 
@@ -55,7 +55,7 @@ Once you or the user pick a skill, follow it: its checklists and gates are how i
55
55
 
56
56
  Call `pitroom` (on PATH after `pitroom install`; otherwise the command in your session context). `pitroom doctor` diagnoses setup problems. Workers and models come from the user's config (`worker`, `fallback`, `models`, `tiers`); pick others only when the user or a plan says so (`--tier capable`, `-W codex`).
57
57
 
58
- Model and effort: tiers already name the workers. Before you pick anything else, run `pitroom models`: it lists what each worker offers (Codex, Claude Code, OpenCode), the effort levels each model accepts, what the user says it costs (`costs` in the config) and what it used so far. Take the cheapest model that fits the task, never a dearer one by habit: start on the `cheap` tier (OpenCode's free model) and move up only when the task needs it or a cheaper worker already failed. Set `--effort` from the task: `low` for lookups and mechanical edits, `medium` for ordinary changes, `high` for reviews and non-obvious bugs, `xhigh` or above only when the user asks or a lower level failed. More effort costs more tokens and time.
58
+ Model and effort: tiers already name the workers. Before you pick anything else, run `pitroom models`: it lists what each worker offers (Codex, Claude Code, OpenCode, Gemini CLI), the effort levels each model accepts, what the user says it costs (`costs` in the config) and what it used so far. Take the cheapest model that fits the task, never a dearer one by habit: start on the `cheap` tier (OpenCode's free model) and move up only when the task needs it or a cheaper worker already failed. Set `--effort` from the task: `low` for lookups and mechanical edits, `medium` for ordinary changes, `high` for reviews and non-obvious bugs, `xhigh` or above only when the user asks or a lower level failed. More effort costs more tokens and time.
59
59
 
60
60
  Workers can take minutes. Start long work with `--bg` and keep working; follow it with `pitroom watch --brief` (one card line per start and end) through your host's background or monitor facility, or call `pitroom wait --timeout 540` again while it exits 75. Never poll with `sleep`.
61
61