pitroom 0.6.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/marketplace.json +18 -0
- package/.claude-plugin/plugin.json +22 -0
- package/.codex-plugin/plugin.json +29 -0
- package/CHANGELOG.md +85 -0
- package/LICENSE +21 -0
- package/README.md +471 -0
- package/dist/lib.mjs +1222 -0
- package/dist/pitroom.mjs +3685 -0
- package/docs/backends.md +113 -0
- package/hooks/hooks.json +28 -0
- package/hooks/session-start.mjs +42 -0
- package/package.json +60 -0
- package/skills/pitroom-brainstorming/SKILL.md +243 -0
- package/skills/pitroom-brainstorming/spec-document-reviewer-prompt.md +22 -0
- package/skills/pitroom-crew/SKILL.md +80 -0
- package/skills/pitroom-debugging/SKILL.md +287 -0
- package/skills/pitroom-debugging/condition-based-waiting-example.ts +170 -0
- package/skills/pitroom-debugging/condition-based-waiting.md +115 -0
- package/skills/pitroom-debugging/defense-in-depth.md +122 -0
- package/skills/pitroom-debugging/find-polluter.sh +72 -0
- package/skills/pitroom-debugging/root-cause-tracing.md +169 -0
- package/skills/pitroom-driven-development/SKILL.md +138 -0
- package/skills/pitroom-driven-development/implementer-prompt.md +68 -0
- package/skills/pitroom-driven-development/re-review-prompt.md +41 -0
- package/skills/pitroom-driven-development/task-reviewer-prompt.md +59 -0
- package/skills/pitroom-finishing/SKILL.md +226 -0
- package/skills/pitroom-implement/SKILL.md +42 -0
- package/skills/pitroom-receiving-review/SKILL.md +209 -0
- package/skills/pitroom-research/SKILL.md +35 -0
- package/skills/pitroom-review/SKILL.md +47 -0
- package/skills/pitroom-review/code-reviewer.md +38 -0
- package/skills/pitroom-tdd/SKILL.md +322 -0
- package/skills/pitroom-tdd/writing-good-tests.md +198 -0
- package/skills/pitroom-verification/SKILL.md +124 -0
- package/skills/pitroom-worktrees/SKILL.md +171 -0
- package/skills/pitroom-writing-plans/SKILL.md +183 -0
- package/skills/pitroom-writing-plans/plan-document-reviewer-prompt.md +23 -0
- package/skills/using-pitroom/SKILL.md +66 -0
package/docs/backends.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Worker backends
|
|
2
|
+
|
|
3
|
+
Pitroom's core does everything that must be true for every worker: closed stdin,
|
|
4
|
+
the git guard on `PATH`, recursion guard, timeouts and signals, snapshots and
|
|
5
|
+
isolated copies, exact change tracking, reference verification, receipts and
|
|
6
|
+
the fallback chain. A **backend** only translates between Pitroom and one worker
|
|
7
|
+
CLI. That keeps adapters small (OpenCode is ~150 lines) and makes it impossible
|
|
8
|
+
for a new adapter to skip a safeguard.
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
src/
|
|
12
|
+
backends/
|
|
13
|
+
types.ts the Backend contract and shared types
|
|
14
|
+
index.ts registry
|
|
15
|
+
opencode/ the reference adapter
|
|
16
|
+
index.ts invocation, failure classification, models, doctor
|
|
17
|
+
events.ts `--format json` stream → ParsedRun
|
|
18
|
+
profiles.ts read / write permission profiles
|
|
19
|
+
core/ lifecycle, process runner, prompt, refs, receipts, report
|
|
20
|
+
vcs/ git snapshots, isolated copies, git guard
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## The contract
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
interface Backend {
|
|
27
|
+
id: string; // "opencode", used in targets: "opencode:provider/model"
|
|
28
|
+
name: string;
|
|
29
|
+
capabilities: {
|
|
30
|
+
readOnly: 'permission-rules' | 'os-sandbox' | 'tool-allowlist' | 'approval-mode';
|
|
31
|
+
resume: 'by-id' | 'none';
|
|
32
|
+
reportsCost: boolean;
|
|
33
|
+
attachFiles: boolean;
|
|
34
|
+
};
|
|
35
|
+
binary(): string; // PITROOM_<ID>_BIN > PATH > known install path
|
|
36
|
+
invocation(req: WorkerRequest): Invocation; // pure
|
|
37
|
+
parse(stdout: string): ParsedRun; // pure, tolerant of a torn last line
|
|
38
|
+
failure(run, stderr, exitCode): Failure | undefined; // kind drives the fallback chain
|
|
39
|
+
defaultModel?(): string | undefined;
|
|
40
|
+
resolveModel?(sessionId: string): string | undefined;
|
|
41
|
+
listModels?(): string[];
|
|
42
|
+
doctor(ctx): DoctorCheck[];
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`failure().kind` is `model-unavailable`, `rate-limited`, `auth` or `other`. Anything
|
|
47
|
+
but `other`, when the worker did no work, makes the core try the next target.
|
|
48
|
+
|
|
49
|
+
## Mapping Pitroom's modes
|
|
50
|
+
|
|
51
|
+
The core decides the mode; the adapter must make the CLI enforce it with the
|
|
52
|
+
CLI's **own** mechanism, and never with flags that switch safety off
|
|
53
|
+
(`--yolo`, `--dangerously-*`, `bypassPermissions`, `danger-full-access`,
|
|
54
|
+
`--auto`): the contract tests reject them.
|
|
55
|
+
|
|
56
|
+
| | read | write / isolate | resume | cost |
|
|
57
|
+
|---|---|---|---|---|
|
|
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
|
+
| **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
|
+
| **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 |
|
|
62
|
+
|
|
63
|
+
Whatever the CLI, the core still applies the git guard, closes stdin (Codex and
|
|
64
|
+
Gemini otherwise read piped stdin into the prompt), sets `PWD` to the worker's
|
|
65
|
+
directory, snapshots the tree and verifies references. `--isolate` runs in a
|
|
66
|
+
standalone repository that reads the user's objects through `alternates`
|
|
67
|
+
(not a `git worktree`), so no CLI can map it back to the user's checkout.
|
|
68
|
+
|
|
69
|
+
## OpenCode v2 notes
|
|
70
|
+
|
|
71
|
+
The OpenCode adapter targets OpenCode v2 (`doctor` fails on v1). What changed from v1, and why the adapter looks the way it does:
|
|
72
|
+
|
|
73
|
+
- **`--standalone` is a safety requirement.** A plain `opencode run` attaches to OpenCode's shared background service, which was started with its own environment. The per-run permission profile (`OPENCODE_CONFIG_CONTENT`), the git guard on `PATH` and `PITROOM_ACTIVE` would then never reach the worker. With `--standalone` each run gets a private server that inherits them; the contract tests assert the flag for every mode.
|
|
74
|
+
- **No `--dir`, and `$PWD` wins.** v2 takes its workspace from `$PWD`, not the process working directory. The core's process runner sets `PWD` to the worker's directory for every CLI; without it a worker started in an isolated copy edited the directory pitroom was launched from (found in a real crew run; the mock now reproduces it and the isolate tests fail without the fix).
|
|
75
|
+
- **Permissions**: v2 calls the shell tool `shell` (v1: `bash`); profiles set both keys to the same rules. The new `execute` tool reaches namespaced tools (browser automation, the OpenCode API itself) and is denied in both modes. `write`/`edit` take `path`.
|
|
76
|
+
- **Events**: `step_finish.tokens` has no `total` (summed from its parts); errors are `{type, message, status}`; a refused tool reports `Permission denied: <tool>`.
|
|
77
|
+
- **Models and sessions**: `debug config` lists config sources (the model is `{providerID, model}`), sessions are exported with `session export`, and model ids accept a `#variant` suffix.
|
|
78
|
+
- **Free tier**: OpenCode Zen free models can answer `403 FreeTierError` ("free tier can only be used from within OpenCode"). It is classified as `auth`, so the fallback chain moves on.
|
|
79
|
+
- **Auto-update**: workers run with `OPENCODE_DISABLE_AUTOUPDATE=1`, so a run never upgrades OpenCode underneath the user.
|
|
80
|
+
|
|
81
|
+
Recorded v2 streams live in `test/fixtures/opencode/{events,failures}/v2-*`; the v1 ones stay as parser regression tests.
|
|
82
|
+
|
|
83
|
+
## Codex notes
|
|
84
|
+
|
|
85
|
+
- **`--ignore-user-config`.** `~/.codex/config.toml` can define MCP servers, which run outside Codex's sandbox and could have side effects in a read-only run, and profiles that loosen the sandbox. Disabling servers one by one is not reliable (`-c mcp_servers.<name>.enabled=false` breaks on names containing dots or spaces), so workers ignore the file; auth still works. The model is the target's, or Codex's built-in default; `#effort` sets the reasoning effort (`codex:gpt-5.6-sol#low`, `codex:#low`).
|
|
86
|
+
- **Resume takes no `-s`/`-C`**, so the sandbox always goes through `-c sandbox_mode=…`; the tests assert it for new and resumed runs.
|
|
87
|
+
- **Login shells.** Codex runs commands through `zsh -lc`; macOS's `path_helper` and `~/.zprofile` reorder `PATH`, which hides the git-guard shim. The second guard layer (git's own env config: a `reference-transaction` hook and `pushInsteadOf`) holds regardless, for every worker.
|
|
88
|
+
- **Stream**: `item.completed` items of type `error` are warnings (deprecated settings, skills budget), not failures; failures are top-level `error` / `turn.failed`, whose message is a JSON API error. The JSON stream does not name the model, so it is read from the session's rollout file. Cost is not reported.
|
|
89
|
+
- **"Not supported when using Codex with a ChatGPT account"** comes back both for models the account cannot use and for models the installed Codex CLI is too old to know (seen with `gpt-6.1-sol` on 0.146, working on 0.159). It is `model-unavailable`, so the chain moves on, and the message suggests updating Codex.
|
|
90
|
+
- **Node**: `codex` is a Node script (`#!/usr/bin/env node`); Pitroom runs such CLIs on its own Node 18+, since agents' shells often have an older Node first on `PATH`.
|
|
91
|
+
|
|
92
|
+
## Claude Code notes
|
|
93
|
+
|
|
94
|
+
- **Lockdown** (see the table): `--safe-mode` keeps the user's CLAUDE.md, skills, plugins, hooks and MCP out; `--restricted` removes command-running tools unless listed, confines file tools to the working directory and refuses `bypassPermissions`; `--permission-mode dontAsk` denies anything outside the allowlist instead of prompting. The init event of a real run lists exactly `Glob, Grep, Read` for a read-only worker, no MCP servers, and only Claude Code's built-in plugins.
|
|
95
|
+
- **Not `--bare`**: it disables OAuth, which would break Claude subscriptions.
|
|
96
|
+
- **Argument order**: `--tools`, `--allowedTools` and `--disallowedTools` take lists; non-list options follow them and the prompt comes after `--`, so no list can swallow it.
|
|
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
|
+
- **Model**: the init event names it. The user's default is often an Opus-class model; `doctor` warns and suggests `-W claude:haiku`.
|
|
99
|
+
|
|
100
|
+
## Adding a worker
|
|
101
|
+
|
|
102
|
+
1. Create `src/backends/<id>/index.ts` exporting a `Backend`; keep CLI knowledge
|
|
103
|
+
(flags, event format, error wording, model listing) in that folder.
|
|
104
|
+
2. Register it in `src/backends/index.ts` (and drop the id from `PLANNED`).
|
|
105
|
+
3. Record real fixtures under `test/fixtures/<id>/`:
|
|
106
|
+
- `events/*.jsonl`: stdout of real runs (one read, one write), home paths replaced;
|
|
107
|
+
- `failures/<name>.stdout.jsonl` + `.stderr.log`: e.g. an unknown model;
|
|
108
|
+
- `expected.json`: session id, step count, token total, answer prefix, failure kinds.
|
|
109
|
+
4. `npm test`: `test/backends.test.mjs` runs the contract suite against every
|
|
110
|
+
registered backend automatically (capabilities, no bypass flags, read ≠ write,
|
|
111
|
+
prompt in argv, optional model/session/files, parsing, failure classification).
|
|
112
|
+
5. Add an end-to-end mock for the CLI if its behaviour differs materially, and a
|
|
113
|
+
row to the table above and to the README.
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "startup|clear|compact",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/session-start.mjs\"",
|
|
10
|
+
"async": false
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"PostToolUse": [
|
|
16
|
+
{
|
|
17
|
+
"matcher": "Bash",
|
|
18
|
+
"hooks": [
|
|
19
|
+
{
|
|
20
|
+
"type": "command",
|
|
21
|
+
"command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/pitroom.mjs\" hook-card",
|
|
22
|
+
"timeout": 10
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SessionStart hook: puts the `using-pitroom` skill into the primary agent's
|
|
3
|
+
// context, so it considers delegating before it starts reading and editing, and
|
|
4
|
+
// tells it the exact command to run even if `pitroom` is not on PATH.
|
|
5
|
+
// Dependency-free and fast: it only reads one file.
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
// Inside a Pitroom worker there is nothing to delegate to.
|
|
12
|
+
if (process.env.PITROOM_ACTIVE === '1') process.exit(0);
|
|
13
|
+
|
|
14
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
15
|
+
let skill = '';
|
|
16
|
+
try {
|
|
17
|
+
skill = fs.readFileSync(path.join(root, 'skills', 'using-pitroom', 'SKILL.md'), 'utf8');
|
|
18
|
+
} catch {
|
|
19
|
+
process.exit(0); // broken install: stay silent rather than break the session
|
|
20
|
+
}
|
|
21
|
+
const body = skill.replace(/^---\n[\s\S]*?\n---\n/, '').trim();
|
|
22
|
+
// Fallback when `pitroom` is not on PATH: the installed launcher (it picks a Node 18+),
|
|
23
|
+
// else this Node if it is new enough, else plain `node`.
|
|
24
|
+
const cli = path.join(root, 'dist', 'pitroom.mjs');
|
|
25
|
+
const launcher = path.join(os.homedir(), '.local', 'bin', 'pitroom');
|
|
26
|
+
const nodeOk = Number(process.versions.node.split('.')[0]) >= 18;
|
|
27
|
+
const fallback = fs.existsSync(launcher) ? `"${launcher}"` : `"${nodeOk ? process.execPath : 'node'}" "${cli}"`;
|
|
28
|
+
const command = fs.existsSync(cli) || fs.existsSync(launcher) ? `\`pitroom\`, or if that is not on PATH: \`${fallback}\`` : '`pitroom`';
|
|
29
|
+
|
|
30
|
+
const context = `<pitroom>
|
|
31
|
+
You have Pitroom: a development workflow as skills, and cheap worker agents that read, search, implement and review for you. Run it as ${command}.
|
|
32
|
+
It is optional: use it when it helps or when the user asks for it, otherwise work as you normally would. Below is the 'using-pitroom' skill, a menu of what it offers; load a pitroom-* skill with your Skill tool when you choose to use it.
|
|
33
|
+
|
|
34
|
+
${body}
|
|
35
|
+
</pitroom>`;
|
|
36
|
+
|
|
37
|
+
// Cursor reads additional_context; Claude Code reads hookSpecificOutput. Emit only one,
|
|
38
|
+
// because Claude Code would otherwise inject the text twice.
|
|
39
|
+
const out = process.env.CURSOR_PLUGIN_ROOT
|
|
40
|
+
? { additional_context: context }
|
|
41
|
+
: { hookSpecificOutput: { hookEventName: 'SessionStart', additionalContext: context } };
|
|
42
|
+
process.stdout.write(`${JSON.stringify(out)}\n`);
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pitroom",
|
|
3
|
+
"version": "0.6.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 or Claude Code workers, with receipts that prove the savings.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"author": "TahaAtas",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/ATASTECH/pitroom.git"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/ATASTECH/pitroom#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ATASTECH/pitroom/issues"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"pitroom": "dist/pitroom.mjs"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"skills",
|
|
21
|
+
"hooks",
|
|
22
|
+
".claude-plugin",
|
|
23
|
+
".codex-plugin",
|
|
24
|
+
"docs/backends.md",
|
|
25
|
+
"README.md",
|
|
26
|
+
"CHANGELOG.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "node scripts/build.mjs",
|
|
34
|
+
"typecheck": "tsc --noEmit",
|
|
35
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
36
|
+
"prepublishOnly": "npm run typecheck && npm test"
|
|
37
|
+
},
|
|
38
|
+
"keywords": [
|
|
39
|
+
"agent",
|
|
40
|
+
"agent-skills",
|
|
41
|
+
"claude-code",
|
|
42
|
+
"codex",
|
|
43
|
+
"cost",
|
|
44
|
+
"delegation",
|
|
45
|
+
"llm",
|
|
46
|
+
"opencode",
|
|
47
|
+
"subagent",
|
|
48
|
+
"tokens",
|
|
49
|
+
"workflow",
|
|
50
|
+
"code-review",
|
|
51
|
+
"tdd",
|
|
52
|
+
"planning"
|
|
53
|
+
],
|
|
54
|
+
"license": "MIT",
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/node": "^22.10.0",
|
|
57
|
+
"esbuild": "^0.25.0",
|
|
58
|
+
"typescript": "^5.7.0"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pitroom-brainstorming
|
|
3
|
+
description: Use when you or the user want a feature, component or behaviour change designed before it is built - explores intent, requirements and design with the user and gets approval before implementation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Brainstorming Ideas Into Designs
|
|
7
|
+
|
|
8
|
+
Help turn ideas into fully formed designs and specs through natural collaborative dialogue.
|
|
9
|
+
|
|
10
|
+
Start by classifying how much process the request needs, then work
|
|
11
|
+
through your path: understand the context, refine the idea, present a
|
|
12
|
+
design, and get your human partner's approval.
|
|
13
|
+
|
|
14
|
+
<HARD-GATE>
|
|
15
|
+
Do NOT invoke any implementation skill, write any code, scaffold any
|
|
16
|
+
project, or take any implementation action until you have told your
|
|
17
|
+
human partner what you intend and they have approved it. This applies
|
|
18
|
+
to EVERY task on EVERY path below — the ceremony scales with the task;
|
|
19
|
+
the approval gate never does.
|
|
20
|
+
</HARD-GATE>
|
|
21
|
+
|
|
22
|
+
## Three Paths
|
|
23
|
+
|
|
24
|
+
Before your first question, classify the request and say the
|
|
25
|
+
classification out loud — "this looks bounded, so I'll present a short
|
|
26
|
+
design here rather than write a spec" — so your human partner can
|
|
27
|
+
override it:
|
|
28
|
+
|
|
29
|
+
- **Spike** — a feasibility question ("can we...", "is it possible...",
|
|
30
|
+
"quick and dirty is fine") whose output is an answer, not code you
|
|
31
|
+
keep. Present the question and what you'll try in 2-3 sentences, get
|
|
32
|
+
a nod, then find out as cheaply as correctness allows. No design
|
|
33
|
+
doc, no spec file. Report findings as a recommendation; anything you
|
|
34
|
+
built stays labeled throwaway.
|
|
35
|
+
- **Bounded** — a well-scoped change to code that already exists in
|
|
36
|
+
this repo: a new flag, a small endpoint, a one-file fix.
|
|
37
|
+
Understanding the kind of app is not enough — bounded means the flow
|
|
38
|
+
you are changing is already here to read. If there is no existing
|
|
39
|
+
flow to change, the task is not bounded. Ask the clarifying
|
|
40
|
+
questions that matter, present a short design IN CHAT (a few
|
|
41
|
+
sentences to a few short paragraphs), and STOP. Implementation
|
|
42
|
+
starts only after your human partner says yes to that design — a
|
|
43
|
+
bounded task's approval is as hard a gate as an architectural
|
|
44
|
+
one. No spec file, no implementation plan document.
|
|
45
|
+
- **Architectural** — new projects, new subsystems, changes that
|
|
46
|
+
restructure how components fit together or alter interfaces others
|
|
47
|
+
depend on. Follow the full process: questions, approaches, sectioned
|
|
48
|
+
design, written spec, then the `pitroom-writing-plans` skill.
|
|
49
|
+
|
|
50
|
+
When in doubt between two paths, take the heavier one. The ratchet is
|
|
51
|
+
one-way: hidden complexity discovered mid-task upgrades the path —
|
|
52
|
+
stop, say so, and step up. Nothing downgrades mid-task.
|
|
53
|
+
|
|
54
|
+
## Anti-Pattern: "Too Simple To Need Approval"
|
|
55
|
+
|
|
56
|
+
Every path ends with your human partner approving your intent before
|
|
57
|
+
implementation. A todo list, a single-function utility, a config
|
|
58
|
+
change — the design may be two sentences in chat, but you MUST present
|
|
59
|
+
it and get approval. "Simple" tasks are where unexamined assumptions
|
|
60
|
+
cause the most wasted work. What scales with simplicity is the
|
|
61
|
+
artifact, never the approval.
|
|
62
|
+
|
|
63
|
+
This gate is for creative work: a feature, a component, a behaviour
|
|
64
|
+
change. A typo, a one-line fix the user spelled out, or a value the
|
|
65
|
+
user named is not creative work; `using-pitroom` leaves those to you
|
|
66
|
+
without this skill.
|
|
67
|
+
|
|
68
|
+
## Red Flags
|
|
69
|
+
|
|
70
|
+
| Thought | Reality |
|
|
71
|
+
|---------|---------|
|
|
72
|
+
| "This is too simple to need a design" | Simple means a short design, not no design. Two sentences in chat, then approval. |
|
|
73
|
+
| "I'll call it bounded and skip the spec" | Reaching for a label to skip work IS the doubt — take the heavier path. |
|
|
74
|
+
| "It's bounded and the design is obvious — I'll start while they read it" | The gate is the approval, not the design's length. Present, then stop until you hear yes. |
|
|
75
|
+
| "I understand this kind of app, so it's bounded" | Bounded measures the repo, not your familiarity. A new project has no existing flow — it is architectural. |
|
|
76
|
+
| "The spike works, so I'll keep the code" | A spike's output is an answer. Keeping the code is a new request — classify it. |
|
|
77
|
+
| "It grew, but I'm almost done — no need to re-classify" | Hidden complexity upgrades the path mid-task. Stop and say so. |
|
|
78
|
+
| "They approved the spike, so the follow-up change is approved too" | Each task gets its own classification and its own approval. |
|
|
79
|
+
|
|
80
|
+
## Checklist
|
|
81
|
+
|
|
82
|
+
Classify first, announce the path, then create a task for each item on
|
|
83
|
+
your path and complete them in order.
|
|
84
|
+
|
|
85
|
+
**Spike:**
|
|
86
|
+
1. **Explore project context** — enough to frame the probe — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
|
|
87
|
+
2. **Present question + probe plan** — 2-3 sentences
|
|
88
|
+
3. **Get approval** — a nod is enough
|
|
89
|
+
4. **Investigate** — as cheaply as correctness allows
|
|
90
|
+
5. **Report findings** — a recommendation; label anything built as throwaway
|
|
91
|
+
|
|
92
|
+
**Bounded:**
|
|
93
|
+
1. **Explore project context** — check files, docs, recent commits — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
|
|
94
|
+
2. **Ask clarifying questions** — one at a time, the ones that matter
|
|
95
|
+
3. **Present short design in chat** — approach, files touched, testing
|
|
96
|
+
4. **Get approval** — STOP and wait for an explicit yes; presenting the design and starting in the same breath is skipping the gate
|
|
97
|
+
5. **Implement** — proceed with the normal development workflow (TDD applies); no plan document
|
|
98
|
+
|
|
99
|
+
**Architectural:**
|
|
100
|
+
1. **Explore project context** — check files, docs, recent commits — let workers do the reading (`pitroom-research` for one area, `pitroom-crew` for several) and read their answers, not the files
|
|
101
|
+
2. **Ask clarifying questions** — one at a time, understand purpose/constraints/success criteria
|
|
102
|
+
3. **Propose 2-3 approaches** — with trade-offs and your recommendation
|
|
103
|
+
4. **Present design** — in sections scaled to their complexity, get user approval after each section
|
|
104
|
+
5. **Write design doc** — save to `docs/pitroom/specs/YYYY-MM-DD-<topic>-design.md` and commit
|
|
105
|
+
6. **Spec self-review** — quick inline check for placeholders, contradictions, ambiguity, scope (see below)
|
|
106
|
+
7. **User reviews written spec** — ask user to review the spec file before proceeding
|
|
107
|
+
8. **Transition to implementation** — invoke `pitroom-writing-plans` to create implementation plan
|
|
108
|
+
|
|
109
|
+
## Process Flow
|
|
110
|
+
|
|
111
|
+
```dot
|
|
112
|
+
digraph brainstorming {
|
|
113
|
+
"Classify: spike / bounded / architectural" [shape=diamond];
|
|
114
|
+
"Present question + probe (2-3 sentences)" [shape=box];
|
|
115
|
+
"Ask clarifying questions (bounded)" [shape=box];
|
|
116
|
+
"Present short design in chat" [shape=box];
|
|
117
|
+
"Human approves?" [shape=diamond];
|
|
118
|
+
"Investigate; report recommendation" [shape=doublecircle];
|
|
119
|
+
"Implement via normal workflow (no plan doc)" [shape=doublecircle];
|
|
120
|
+
"Explore project context" [shape=box];
|
|
121
|
+
"Ask clarifying questions" [shape=box];
|
|
122
|
+
"Propose 2-3 approaches" [shape=box];
|
|
123
|
+
"Present design sections" [shape=box];
|
|
124
|
+
"User approves design?" [shape=diamond];
|
|
125
|
+
"Write design doc" [shape=box];
|
|
126
|
+
"Spec self-review\n(fix inline)" [shape=box];
|
|
127
|
+
"User reviews spec?" [shape=diamond];
|
|
128
|
+
"Invoke pitroom-writing-plans" [shape=doublecircle];
|
|
129
|
+
"Hidden complexity? Upgrade path" [shape=box];
|
|
130
|
+
|
|
131
|
+
"Classify: spike / bounded / architectural" -> "Present question + probe (2-3 sentences)" [label="spike"];
|
|
132
|
+
"Classify: spike / bounded / architectural" -> "Ask clarifying questions (bounded)" [label="bounded"];
|
|
133
|
+
"Classify: spike / bounded / architectural" -> "Explore project context" [label="architectural"];
|
|
134
|
+
"Present question + probe (2-3 sentences)" -> "Human approves?";
|
|
135
|
+
"Ask clarifying questions (bounded)" -> "Present short design in chat";
|
|
136
|
+
"Present short design in chat" -> "Human approves?";
|
|
137
|
+
"Human approves?" -> "Investigate; report recommendation" [label="spike: yes"];
|
|
138
|
+
"Human approves?" -> "Implement via normal workflow (no plan doc)" [label="bounded: yes"];
|
|
139
|
+
"Hidden complexity? Upgrade path" -> "Classify: spike / bounded / architectural";
|
|
140
|
+
"Explore project context" -> "Ask clarifying questions";
|
|
141
|
+
"Ask clarifying questions" -> "Propose 2-3 approaches";
|
|
142
|
+
"Propose 2-3 approaches" -> "Present design sections";
|
|
143
|
+
"Present design sections" -> "User approves design?";
|
|
144
|
+
"User approves design?" -> "Present design sections" [label="no, revise"];
|
|
145
|
+
"User approves design?" -> "Write design doc" [label="yes"];
|
|
146
|
+
"Write design doc" -> "Spec self-review\n(fix inline)";
|
|
147
|
+
"Spec self-review\n(fix inline)" -> "User reviews spec?";
|
|
148
|
+
"User reviews spec?" -> "Write design doc" [label="changes requested"];
|
|
149
|
+
"User reviews spec?" -> "Invoke pitroom-writing-plans" [label="approved"];
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Terminal states are path-bound.** Architectural: the ONLY skill you
|
|
154
|
+
invoke after brainstorming is `pitroom-writing-plans` — never frontend-design,
|
|
155
|
+
mcp-builder, or any other implementation skill. Bounded: after
|
|
156
|
+
approval, implementation proceeds directly through the normal
|
|
157
|
+
development workflow; no plan document. Spike: the terminal state is a
|
|
158
|
+
reported recommendation.
|
|
159
|
+
|
|
160
|
+
## The Process
|
|
161
|
+
|
|
162
|
+
The subsections below serve the bounded and architectural paths (a
|
|
163
|
+
spike stops at "present the probe, get a nod"). Sections from
|
|
164
|
+
**Exploring approaches** onward are architectural-path depth — for
|
|
165
|
+
bounded work, context plus a few questions plus a short in-chat design
|
|
166
|
+
is the whole process.
|
|
167
|
+
|
|
168
|
+
**Understanding the idea:**
|
|
169
|
+
|
|
170
|
+
- Check out the current project state first (docs, recent commits); for code, ask a worker for a map (`pitroom-research`) instead of reading it yourself
|
|
171
|
+
- Before asking detailed questions, assess scope: if the request describes multiple independent subsystems (e.g., "build a platform with chat, file storage, billing, and analytics"), flag this immediately. Don't spend questions refining details of a project that needs to be decomposed first.
|
|
172
|
+
- If the project is too large for a single spec, help the user decompose into sub-projects: what are the independent pieces, how do they relate, what order should they be built? Then brainstorm the first sub-project through the normal design flow. Each sub-project gets its own spec → plan → implementation cycle.
|
|
173
|
+
- For appropriately-scoped projects, ask questions one at a time to refine the idea
|
|
174
|
+
- Prefer multiple choice questions when possible, but open-ended is fine too
|
|
175
|
+
- Only one question per message - if a topic needs more exploration, break it into multiple questions
|
|
176
|
+
- Focus on understanding: purpose, constraints, success criteria
|
|
177
|
+
|
|
178
|
+
**Exploring approaches:**
|
|
179
|
+
|
|
180
|
+
- Propose 2-3 different approaches with trade-offs
|
|
181
|
+
- Present options conversationally with your recommendation and reasoning
|
|
182
|
+
- Lead with your recommended option and explain why
|
|
183
|
+
- YAGNI ruthlessly - remove unnecessary features from every approach and design
|
|
184
|
+
|
|
185
|
+
**Presenting the design:**
|
|
186
|
+
|
|
187
|
+
- Once you believe you understand what you're building, present the design
|
|
188
|
+
- Scale each section to its complexity: a few sentences if straightforward, up to 200-300 words if nuanced
|
|
189
|
+
- Ask after each section whether it looks right so far
|
|
190
|
+
- Cover: architecture, components, data flow, error handling, testing
|
|
191
|
+
- Be ready to go back and clarify if something doesn't make sense
|
|
192
|
+
|
|
193
|
+
**Design for isolation and clarity:**
|
|
194
|
+
|
|
195
|
+
- Break the system into smaller units that each have one clear purpose, communicate through well-defined interfaces, and can be understood and tested independently
|
|
196
|
+
- For each unit, you should be able to answer: what does it do, how do you use it, and what does it depend on?
|
|
197
|
+
- Can someone understand what a unit does without reading its internals? Can you change the internals without breaking consumers? If not, the boundaries need work.
|
|
198
|
+
- Smaller, well-bounded units are also easier for you to work with - you reason better about code you can hold in context at once, and your edits are more reliable when files are focused. When a file grows large, that's often a signal that it's doing too much.
|
|
199
|
+
|
|
200
|
+
**Working in existing codebases:**
|
|
201
|
+
|
|
202
|
+
- Explore the current structure before proposing changes. Follow existing patterns.
|
|
203
|
+
- Where existing code has problems that affect the work (e.g., a file that's grown too large, unclear boundaries, tangled responsibilities), include targeted improvements as part of the design - the way a good developer improves code they're working in.
|
|
204
|
+
- Don't propose unrelated refactoring. Stay focused on what serves the current goal.
|
|
205
|
+
|
|
206
|
+
## After the Design (architectural path)
|
|
207
|
+
|
|
208
|
+
**Documentation:**
|
|
209
|
+
|
|
210
|
+
- Write the validated design (spec) to `docs/pitroom/specs/YYYY-MM-DD-<topic>-design.md`
|
|
211
|
+
- (User preferences for spec location override this default)
|
|
212
|
+
- Commit the design document to git
|
|
213
|
+
|
|
214
|
+
**Spec Self-Review:**
|
|
215
|
+
After writing the spec document, look at it with fresh eyes:
|
|
216
|
+
|
|
217
|
+
1. **Placeholder scan:** Any "TBD", "TODO", incomplete sections, or vague requirements? Fix them.
|
|
218
|
+
2. **Internal consistency:** Do any sections contradict each other? Does the architecture match the feature descriptions?
|
|
219
|
+
3. **Scope check:** Is this focused enough for a single implementation plan, or does it need decomposition?
|
|
220
|
+
4. **Ambiguity check:** Could any requirement be interpreted two different ways? If so, pick one and make it explicit.
|
|
221
|
+
|
|
222
|
+
**Second read (optional, for a long spec):** a read-only worker applies [spec-document-reviewer-prompt.md](spec-document-reviewer-prompt.md):
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
sed "s#{{SPEC_FILE}}#docs/pitroom/specs/<file>.md#" "<this skill's folder>/spec-document-reviewer-prompt.md" > "$TMPDIR/spec-review.md"
|
|
226
|
+
pitroom run --task-file "$TMPDIR/spec-review.md"
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Weigh its findings like any review (`pitroom-receiving-review`).
|
|
230
|
+
|
|
231
|
+
Fix any issues inline. No need to re-review — just fix and move on.
|
|
232
|
+
|
|
233
|
+
**User Review Gate:**
|
|
234
|
+
After the spec self-review (and the optional second read), ask the user to review the written spec before proceeding:
|
|
235
|
+
|
|
236
|
+
> "Spec written and committed to `<path>`. Please review it and let me know if you want to make any changes before we start writing out the implementation plan."
|
|
237
|
+
|
|
238
|
+
Wait for the user's response. If they request changes, make them and re-run the spec self-review. Only proceed once the user approves.
|
|
239
|
+
|
|
240
|
+
**Implementation:**
|
|
241
|
+
|
|
242
|
+
- Invoke `pitroom-writing-plans` to create a detailed implementation plan
|
|
243
|
+
- Do NOT invoke any other skill. `pitroom-writing-plans` is the next step.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
You are a spec document reviewer. Verify that this spec is complete and ready for implementation planning.
|
|
2
|
+
|
|
3
|
+
Spec to review: {{SPEC_FILE}}
|
|
4
|
+
|
|
5
|
+
## What to check
|
|
6
|
+
|
|
7
|
+
| Category | What to look for |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Completeness | TODOs, placeholders, "TBD", incomplete sections |
|
|
10
|
+
| Consistency | Internal contradictions, conflicting requirements |
|
|
11
|
+
| Clarity | Requirements ambiguous enough to make someone build the wrong thing |
|
|
12
|
+
| Scope | Focused enough for a single plan, not several independent subsystems |
|
|
13
|
+
| YAGNI | Unrequested features, over-engineering |
|
|
14
|
+
|
|
15
|
+
## Calibration
|
|
16
|
+
|
|
17
|
+
Only flag issues that would cause real problems during implementation planning: a missing section, a contradiction, a requirement that could be read two ways. Wording, style and "some sections are less detailed than others" are not issues. Approve unless there are serious gaps that would lead to a flawed plan.
|
|
18
|
+
|
|
19
|
+
## Answer
|
|
20
|
+
|
|
21
|
+
SUMMARY: STATUS: APPROVED, or SUMMARY: STATUS: ISSUES FOUND (N)
|
|
22
|
+
In DETAILS: each issue as "[Section]: issue - why it matters for planning", then RECOMMENDATIONS (advisory; they do not block approval).
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pitroom-crew
|
|
3
|
+
description: Use when facing two or more independent tasks - questions about different areas, unrelated bugs or failing test files, the same mechanical change in separate modules - to run Pitroom workers in parallel, watch them live and merge their results.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Running a Pitroom crew
|
|
7
|
+
|
|
8
|
+
Several workers at once, each with its own session (and, for changes, its own isolated copy of the project): one worker per independent problem domain. You split the work, watch, and merge.
|
|
9
|
+
|
|
10
|
+
## When to use
|
|
11
|
+
|
|
12
|
+
- Several questions about different areas of the code.
|
|
13
|
+
- Three or more test files failing with different root causes; subsystems broken independently.
|
|
14
|
+
- The same mechanical change in separate modules.
|
|
15
|
+
|
|
16
|
+
Don't use it when the failures are related (fixing one might fix the others: investigate them together first), when understanding needs the whole system, when you don't yet know what is broken (exploratory debugging: `pitroom-debugging`), or when workers would edit the same files. The tasks of a written plan run through `pitroom-driven-development`, which has its own rules for parallel tasks.
|
|
17
|
+
|
|
18
|
+
## 1. Split
|
|
19
|
+
|
|
20
|
+
Parts must be **independent**: no part needs another's result, and no two parts edit the same file. Two to five parts is the sweet spot; at most `maxParallel` workers (default 4) run at a time, the rest queue. Keep dependent or judgment-heavy parts for yourself.
|
|
21
|
+
|
|
22
|
+
## 2. Write focused briefs
|
|
23
|
+
|
|
24
|
+
Each worker sees only its brief, so each brief is:
|
|
25
|
+
1. **Focused:** one problem domain ("fix agent-tool-abort.test.ts", not "fix all the tests").
|
|
26
|
+
2. **Self-contained:** the error messages, test names and file paths it needs.
|
|
27
|
+
3. **Constrained:** what not to change ("do not change production code", "tests only").
|
|
28
|
+
4. **Specific about the answer:** "the root cause and what you changed", "file:line for each".
|
|
29
|
+
|
|
30
|
+
```text
|
|
31
|
+
Fix the 3 failing tests in src/agents/agent-tool-abort.test.ts:
|
|
32
|
+
1. "should abort tool with partial output capture" - expects 'interrupted at' in message
|
|
33
|
+
2. "should handle mixed completed and aborted tools" - fast tool aborted instead of completed
|
|
34
|
+
3. "should properly track pendingToolCount" - expects 3 results but gets 0
|
|
35
|
+
These look like timing issues. Find the real cause: replace arbitrary timeouts with
|
|
36
|
+
event-based waiting, or fix the abort implementation. Do NOT just increase timeouts.
|
|
37
|
+
Answer with the root cause and what you changed.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`pitroom-research` and `pitroom-implement` have more brief templates.
|
|
41
|
+
|
|
42
|
+
## 3. Start
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pitroom crew -g auth-audit \
|
|
46
|
+
"Map how sessions are created in src/auth; file:line for each step." \
|
|
47
|
+
"List every place that reads the session cookie outside src/auth; file:line." \
|
|
48
|
+
"Which tests cover session expiry? List files and what each asserts."
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Read-only by default. For changes add `-i` (each worker edits its own isolated copy): `pitroom crew -i -g lint-fix "Fix the lint errors in src/a" "Fix the lint errors in src/b"`. Never parallel `--write`; Pitroom refuses it.
|
|
52
|
+
|
|
53
|
+
## 4. Watch
|
|
54
|
+
|
|
55
|
+
Follow the group live without polling:
|
|
56
|
+
- `pitroom watch -g NAME --json`: one JSON line per change (`queued`, `started`, `progress`, `fallback`, `done`/`failed`, then `all-done`). Run it through your host's background or monitor facility so each line reaches you as it happens; it exits by itself when the group is done.
|
|
57
|
+
- No such facility: `pitroom wait -g NAME --timeout 540`, and call it again while it exits with 75.
|
|
58
|
+
- `pitroom status -g NAME`: one table snapshot.
|
|
59
|
+
- Tell the user they can see the same table live with `pitroom watch -g NAME` in a terminal.
|
|
60
|
+
|
|
61
|
+
While workers run, do the parts you kept for yourself.
|
|
62
|
+
|
|
63
|
+
## 5. Collect, verify and merge
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pitroom wait -g NAME --brief # one line per worker: state + SUMMARY
|
|
67
|
+
pitroom show <run> # the full report of the ones you need
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- Read each summary and understand what changed.
|
|
71
|
+
- Check for conflicts: did two workers touch the same code or contradict each other?
|
|
72
|
+
- Verify what you will rely on (`refs:` lines help), then combine the findings in your own words.
|
|
73
|
+
- For `-i` crews: review each patch (`pitroom review <run>` or `pitroom show <run> --patch`), then `pitroom apply -g NAME`. It applies in order and stops at the first conflict; fix that one with `pitroom run --continue <run> "…"` or by hand, then apply the rest.
|
|
74
|
+
- Run the full test suite yourself afterwards, and spot-check: workers make systematic errors.
|
|
75
|
+
|
|
76
|
+
## When things go wrong
|
|
77
|
+
|
|
78
|
+
- A worker failed or timed out: retry that part once with a sharper brief, or do it yourself.
|
|
79
|
+
- Rate limits: the fallback chain handles single failures; if many fail, lower `maxParallel` (config or `PITROOM_MAX_PARALLEL`).
|
|
80
|
+
- Stop everything: `pitroom stop -g NAME` (running and queued).
|