greprag 5.6.0 → 5.6.2

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.
@@ -1,254 +0,0 @@
1
- # Agent Coordination
2
-
3
- How sessions delegate work — chips, agents, and the multi-tier orchestrator pattern. Companion to `/greprag` (inbox transport) and `~/.claude/CLAUDE.md` (the lean reference).
4
-
5
- ## Two tools, two purposes
6
-
7
- | Tool | What it spawns | Lands in | Parameters | When to use |
8
- |---|---|---|---|---|
9
- | `mcp__ccd_session__spawn_task` | Full Claude Code session ("chip") | Any cwd via `cwd:` param | title, prompt, tldr, cwd | Cross-project work; long-running coordination; user-visible chip UI |
10
- | `Agent` tool | Subagent instance | Current session's cwd | subagent_type, model, isolation, prompt, run_in_background | One-shot work inside this project; needs specific model/agent type |
11
-
12
- Picking between them:
13
-
14
- - **Cross-project? → `spawn_task`** (only it has `cwd`).
15
- - **In this project, one-shot, specific model? → `Agent`** with `isolation: "worktree"`.
16
- - **In this project, long campaign? → either** — chip if you want a persistent UI surface; Agent if it's a single delegation.
17
-
18
- ## Chip convention (every `spawn_task` call)
19
-
20
- A chip prompt = **Block 0.5 (project facts, optional)** + **Block 1 (worktree-first)** + the actual task + **Block 2 (report back via inbox)** + **Block 3 (stay listening for follow-up)**. Non-negotiable: 1/2/3. Without them the chip pollutes the main checkout (no isolation), the parent has no return channel, or the chip dies after one report and can't be redirected on follow-up. Block 0.5 is recommended but skip when the project has no seeded facts yet.
21
-
22
- ### Block 0.5 — Project facts (prepend; pull pattern)
23
-
24
- Before composing the chip prompt, the spawning agent pulls the target project's `chip-startup` facts and inlines them at the top of the prompt:
25
-
26
- ```bash
27
- greprag fact query --scope chip-startup --project <chip-project> --limit 10 --format markdown
28
- ```
29
-
30
- If the output is non-empty, wrap it in a `**Project Facts (do not re-discover)**` block at the very top of the prompt:
31
-
32
- ```
33
- **Project Facts (do not re-discover):**
34
-
35
- 1. <fact 1 verbatim>
36
- 2. <fact 2 verbatim>
37
- ...
38
-
39
- ---
40
- ```
41
-
42
- If the output is empty, skip the block entirely — don't inject placeholder text.
43
-
44
- **Why this exists.** Chips routinely burn 10–20 startup turns rediscovering project layout (where migrations live, which file owns the CLI dispatch, what the inbox storage shape is). Seeding those answers once and pulling them at spawn makes every future chip skip the search. Contribution side of the protocol — when to seed, scope naming, deliberate review — is in the `/greprag` skill § "Seeding learnings" (`~/.claude/skills/greprag/SKILL.md` or the package copy at `packages/cli/skill/SKILL.md`).
45
-
46
- ### Block 1 — Worktree-first (prepend to prompt)
47
-
48
- ```
49
- **Setup — do this FIRST, before anything else:**
50
-
51
- ```bash
52
- cd <chip-cwd>
53
- git worktree add .claude/worktrees/<slug> -b chip/<slug>
54
- cd .claude/worktrees/<slug>
55
- ```
56
-
57
- All edits, tests, and commits happen in the worktree. The main checkout stays untouched. Pick a slug that matches the chip's title (kebab-case, short — e.g. `discover-cli`, `doctor-merge-fix`).
58
-
59
- **Your parent's session id is `<parent-session-id>`** — record it; you'll need it in Block 2 to address the report-back so only the parent sees it, not every sibling chip watching the same project inbox.
60
- ```
61
-
62
- Fill `<parent-session-id>` with the orchestrator's own session UUID before sending the prompt. The SessionStart hook prints it as the first system-reminder of every session ("Your greprag session id: `<8-hex>`") — both the full UUID and the 8-hex short form are accepted by the address grammar. Never leave the placeholder unfilled, and never substitute the literal string `<parent-session-id>` into the chip prompt. The project-level fallback (`--to <handle>@greprag.com/<parent-project>`) is a legacy backstop for sessions that predate the SessionStart hook (vanishingly rare in current sessions); cross-project broadcasts pollute every sibling chip's inbox and force the parent to demux noise. Treat that as a bug, not a default. If you genuinely cannot find your session id in the SessionStart reminder, error out rather than broadcasting at the project level. adr: `C:/greprag/adr/address-grammar.md`
63
-
64
- Path convention: `<project>/.claude/worktrees/<slug>/` — same parent directory Claude Code Desktop uses for IDE-checkbox worktrees. One place to look for any active Claude worktree. Branch prefix `chip/` distinguishes agent-spawned from IDE-spawned (`claude/<auto-name>`), so `git branch` output shows provenance at a glance. `/clean-worktrees` skill cleans both.
65
-
66
- `spawn_task` does NOT auto-create worktrees — only the `Agent` tool does (via `isolation: "worktree"`). Chips run wherever you point them, so the worktree setup must be explicit in the prompt itself.
67
-
68
- **Chip cleanup discipline (HARD RULE — every chip prompt must enforce this).** Chips **commit and exit**. They do NOT run `git clean -fd`, `git reset --hard`, `git worktree remove` (any target), `git checkout <other-branch>`, raw `rm -rf` of directories, or any destructive shell command outside their own worktree's tracked files. If a chip needs to delete a file it created, use `git rm` and commit the deletion — never raw `rm`. The parent session owns post-merge worktree cleanup; chips never reach for it themselves. This rule exists because parallel worktrees share `.git`, a poorly-scoped cleanup command can wipe another worktree's working tree, and the main checkout has been observed to lose `packages/*/src/` files in this exact pattern. Spawning agents: include "Chip cleanup discipline" verbatim in Block 1 of every chip prompt.
69
-
70
- **`npm link` discipline.** If a chip needs to smoke-test a CLI build globally, run `npm link` from the main checkout's package dir (`cd <main>/packages/<pkg> && npm link`), NOT from the worktree. Linking from the worktree registers a global symlink that points INTO the worktree; after `git worktree remove` runs in /commit's Phase 4, the symlink dangles and the CLI breaks system-wide until reinstalled. The /commit skill's `guard-npm-links.sh` auto-recovers (re-points at main or unlinks), but the cleanest path is to never create the worktree-pointed symlink in the first place.
71
-
72
- ### Block 2 — Report back via greprag inbox (append to prompt)
73
-
74
- ```
75
- **When done (or stuck), report back via greprag inbox:**
76
-
77
- ```bash
78
- greprag send "<status>: <commit hash> on chip/<slug> — <one-line>" \
79
- --to <your-tenant-handle>@greprag.com/<parent-session-id> \
80
- --from-session <own-session-id> \
81
- --artifact commit:<hash> \
82
- --file <key-file-path>
83
- ```
84
-
85
- - `<status>`: `done` | `blocked` | `partial`
86
- - `<your-tenant-handle>`: parent's `@greprag.com` handle (e.g. `1834729` or a claimed alias like `travis`).
87
- - `<parent-session-id>`: filled in by the spawning session in Block 1 of this prompt. The full UUID or 8-hex short form both work. This trailing segment IS the target — only the parent's session-scoped watcher receives the message.
88
- - `<own-session-id>`: this chip's own session UUID. Denormalized onto the message so the parent can address replies back without re-discovering the chip's identity.
89
- - Body ≤280 chars where possible. If blocked, name the blocker explicitly.
90
- - Use `--artifact` and `--file` flags to back-reference the actual work (see `/greprag` skill).
91
-
92
- If `<parent-session-id>` is unknown (parent didn't pass one), send to the parent's project instead: `--to <handle>@greprag.com/<parent-project>` (no session suffix). That's an intentional project broadcast — every watcher in `<parent-project>` receives it, including the parent. Use sparingly; session-targeting is the default. adr: adr/address-grammar.md
93
-
94
- Send the report BEFORE exiting. The parent agent reads `greprag inbox` on its next turn and picks it up — no polling, no manual chasing.
95
- ```
96
-
97
- ### Block 3 — Stay listening for follow-up (append to prompt, runs after Block 2)
98
-
99
- ```
100
- **After sending the done report, stay reachable for follow-ups:**
101
-
102
- Arm a `Monitor` on your own inbox so any directive from main lands as an in-session event. Use the bash-wrapper form — the `while` loop auto-restarts the watcher if the inner SSE process dies (network blip, crash, fork failure). Run this under the **`Monitor`** tool with `persistent: true`:
103
-
104
- ```bash
105
- while true; do greprag inbox watch --session <own-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
106
- ```
107
-
108
- - `<own-session-id>` is the chip's own session UUID — find it in this session's SessionStart hook system-reminder ("Your greprag session id: `<8-hex>`"). Use the same value you passed as `--from-session` in Block 2. The session filter narrows the stream to messages aimed at this exact session plus broadcasts; sibling chips watching the same project no longer pollute this feed.
109
- - The `--project <own-project>` substitution exists only as a legacy backstop for sessions that predate the SessionStart hook. In current sessions the hook always fires; if the reminder isn't present, error out rather than broadcasting at the project level — project-scope makes every sibling watcher see your traffic and has been observed to cause silent cross-talk in production.
110
- - The chip then idles between events — no token burn, no polling. Each new inbox line = one notification.
111
- - Restart events go to stderr as `[wrapper] watcher exited…` — visible in the Monitor output file but not as a Monitor notification.
112
- - When the work is truly done and no follow-up is expected, call `TaskStop` on the Monitor task. Otherwise leave it armed until the session closes.
113
- - Do NOT drop the `while … done` wrapper. A bare `greprag inbox watch …` will silently end the Monitor task on any inner crash, and any directive sent in the gap is lost until the next user prompt.
114
- ```
115
-
116
- **Why not the Stop hook?** The greprag Stop hook ingests inbox messages between user prompts. A Mode B chip running autonomously may never hit a stop boundary; a Mode A chip waiting on a reply mid-task gets the reply only on the next manual interaction. Monitor delivers the reply as an in-session event the moment it lands — no hook lag, no missed directive.
117
-
118
- ## Reply listening (any session, not just chips)
119
-
120
- The chip Block 3 pattern generalizes. Any session that sends a message expecting a directive in response should arm a Monitor on its own inbox in the same turn — before the send if you can, so a fast reply doesn't slip past. Use the same bash-wrapper form shown in Block 3 (substitute `--project <own-project>` when no session identity is available), `persistent: true`. Same reasoning: the Stop hook is best-effort for session-end ingestion; Monitor is the only path that catches mid-task replies.
121
-
122
- **Session scoping is the default in v0.11.** The send-side address grammar — `<handle>@greprag.com/<session-uuid>` — makes the session the only segment, so messages land in exactly one inbox. Project-name addresses (`<handle>@greprag.com/<project>`) are intentional broadcasts, used only when the sender genuinely means "everyone in this project should hear this." A `--session` watcher still passes broadcasts through (by design, so tenant-wide announcements aren't lost), but with session-targeting as the dominant pattern those broadcasts are now rare and recognizable.
123
-
124
- ## Parent-side: watch for the report
125
-
126
- If you want the chip's report the instant it lands (not on next turn), start an SSE watcher in the background BEFORE spawning the chip:
127
-
128
- ```bash
129
- # default — single chip, session-scoped (bash wrapper auto-restarts on inner death)
130
- while true; do greprag inbox watch --session <parent-session-id> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
131
-
132
- # only for genuine multi-chip campaigns (N chips fanned out in parallel, want one merged stream)
133
- while true; do greprag inbox watch --project <parent-project> --json; echo "[wrapper] watcher exited, restarting in 1s" >&2; sleep 1; done
134
- ```
135
-
136
- `--session` is the default. Substitute `<parent-session-id>` from the orchestrator's own SessionStart system-reminder. The `--project` form is ONLY for the case where the parent is genuinely orchestrating multiple chips in parallel and wants every chip's reports on one merged stream (each chip still tags `--from-session <own-id>` for provenance). Do not reach for `--project` because you don't have your session id handy — the SessionStart hook puts it in your context at the top of every session.
137
-
138
- **Run it under the `Monitor` agent tool.** Monitor emits one notification per stdout line — the parent agent reacts the moment a message lands. **Do NOT use `Bash(run_in_background: true)` for this** — Bash background only notifies on process completion, and a watcher runs forever, so the parent agent gets no events at all until it manually checks the output file. Burned this lesson once already.
139
-
140
- Sub-1s delivery (verified 210ms in live test), auto-reconnects with cursor-based resume, no polling. Default to this whenever you're waiting on one or more chips. Full pattern: `~/.claude/skills/greprag/SKILL.md` § 5c.
141
-
142
- ## Parent-project name
143
-
144
- When spawning, include `<parent-project>` (your current project_name) in the report-back template so the chip knows where to send the report. Get it via `greprag status --json | jq -r '.project.project_name'` or `greprag project-id`.
145
-
146
- ## Two chip modes
147
-
148
- Both modes use the same Block 0.5 / 1 / 2 / 3 wrapper — the difference is what the chip does inside.
149
-
150
- ### Mode A — Ship chip (default)
151
-
152
- The chip lands in its worktree, does the work, commits checkpoints as progress, reports back via inbox, stays listening for follow-ups. Whether you watch the chip UI mid-flight or it runs end-to-end and inboxes a `done` is a function of how tight the spec is, not a separate mode. A chip that dispatches its own `Agent` sub-tasks mid-work (the "mission commander" pattern) is still Mode A — the Agent dispatch is a behavior the chip's prompt unlocks, not a peer mode.
153
-
154
- **Use when:** the work is "build X" or "fix Y" or "refactor Z" and the spec is clear enough to ship from. This is the workhorse — reach for it by default.
155
-
156
- **Operating guidelines:**
157
-
158
- 1. **All edits, tests, builds, commits happen in the worktree.** Never reach into the parent checkout.
159
- 2. **Checkpoint commits.** Each logical unit of work gets its own commit (matches the global "checkpoint after every fix/feature" rule). Don't batch a whole feature into one final commit.
160
- 3. **Verify before reporting done.** Build passes, tests pass, hand-verify the change does what the spec asked. `done` means demonstrably working, not "I wrote code."
161
- 4. **Never push.** Parent owns the push boundary.
162
- 5. **No destructive commands.** `git clean`, `git reset --hard`, `git worktree remove`, `git checkout <foreign-branch>`, raw `rm -rf` — all forbidden. Use `git rm` for tracked deletions only.
163
- 6. **Mid-flight ambiguity → surface it, don't guess.** Either the user types into the chip UI to redirect, OR the chip `greprag send`s a question to main and Monitors its own inbox for the reply.
164
- 7. **Done-report carries proof.** Pass commit hashes via `--artifact commit:<hash>` and key file paths via `--file <path>`. Not just prose.
165
-
166
- **Sub-Agent dispatch (still Mode A).** When a discrete sub-task fits a specialized agent (`Explore` for read-only search, `Plan` for design work, `general-purpose` for execution, `code-reviewer` for second opinion), the chip can call `Agent` directly. Pass `model: "haiku" | "sonnet" | "opus"` to scale cost to task. The chip evaluates the Agent's return value and either continues, dispatches another Agent, or inboxes back to main.
167
-
168
- This gives you a three-layer chain when sub-tasks span model tiers or operator chatter would pollute main's context:
169
-
170
- ```
171
- Main session (Opus) ← strategic orchestrator
172
- ↓ spawn_task(cwd: <target-project>, prompt: "...")
173
- Mode A chip (Opus) ← tactical commander in target project
174
- ↓ Agent(subagent_type, model, isolation: "worktree")
175
- Subagent (any model/type) ← field operator
176
- ↑ Agent returns to chip
177
- Chip evaluates, may spawn more Agents, may inbox up
178
- ↑ greprag send → <your-tenant-email>/<main-project>
179
- Main session reads inbox, gives next directive via greprag send
180
- ↓ <your-tenant-email>/<chip-project>
181
- Chip continues
182
- ```
183
-
184
- **What each layer owns:**
185
-
186
- - **Main** — strategy. Decides what gets delegated. Stays Opus; never burns context on routine sub-tasks.
187
- - **Chip** — tactical coordination inside a target project. Persists across multiple Agent rounds. Receives directives from main via inbox, dispatches operators, evaluates results, asks for clarification if needed. Picks model per sub-task.
188
- - **Agent / subagent** — execution. Specific subagent_type and model fit to the task. Returns once when done.
189
-
190
- **Communication channels:**
191
-
192
- - Main ↔ chip: greprag inbox (`<handle>@greprag.com/<parent-session-id>` ↔ `<handle>@greprag.com/<chip-session-id>`, falling back to `/<project>` only when a session id is unknown).
193
- - Chip ↔ subagent: direct return value from the `Agent` tool (no inbox needed — same session).
194
-
195
- Skip the layering when one Agent call would do — direct dispatch from main is simpler.
196
-
197
- ### Mode B — Discussion chip
198
-
199
- The chip lands NOT to ship code, but to be a context-rich conversation partner for design / architecture / debugging questions the orchestrator can't reason about well from grep snippets. The chip reads code as needed, proposes, receives push-back, iterates. Ships nothing without explicit go-ahead — often ships nothing at all and just produces a decision or a scoped follow-up chip prompt.
200
-
201
- **Detection signals — switch to Mode B when ANY of these fire:**
202
-
203
- 1. **You catch yourself extrapolating from partial reads.** "Based on these grep hits I think X" — the moment "I think" or "based on snippets" enters your reasoning about architecture, that's the signal. A chip with the repo loaded ground-truths this. Single biggest signal.
204
- 2. **The user's question is "how should this be shaped?" not "build X."** Design / architecture / "is this the right approach?" / "why is this code like this?" — Mode B. Implementation tasks — Mode A.
205
- 3. **The user wants to think out loud.** "Bounce something off you" / "thoughts?" / "talk me through this." They want a conversation, not a deliverable.
206
- 4. **The work will touch multiple subsystems and second-order effects are unknown.** Mode B chip explores the coupling, surfaces what main missed; then either main implements (light coupling) or a follow-up Mode A chip gets a tightened spec (heavy coupling).
207
-
208
- **Operating guidelines:**
209
-
210
- - Read code; don't commit.
211
- - The worktree is scratch space for proposed edits, not a place to ship from.
212
- - Propose in the chip UI; receive pushback; iterate.
213
- - Output is a decision: shipped (after explicit go-ahead → transitions into a Mode A finish), parked, or a scoped follow-up Mode A chip prompt.
214
- - Report-back captures the outcome, not a deliverable.
215
-
216
- **Chip prompts for Mode B look different from Mode A:**
217
-
218
- - Frame the open question, not a deliverable.
219
- - List the sub-questions the user has raised — give the chip the discussion thread, not a spec.
220
- - Explicitly say "This is a discussion chip, not a task chip. Read code. Propose. Don't ship without go-ahead."
221
- - Open with a "where do you want to start?" rather than a task list.
222
-
223
- **Why this beats arguing in main:** orchestrator runs on what it can grep + read in-context. Anything beyond that is plausible-sounding extrapolation. A chip with the repo loaded catches "this coupling exists" / "this billing dependency is non-obvious" / "you missed a callsite" — corrections the orchestrator can't surface itself.
224
-
225
- ### Picking the title, slug, model, and subagent_type
226
-
227
- - **Title** — ALWAYS prefix with `Chip: ` then the imperative action phrase. Format: `Chip: <verb-phrase>` (e.g. `Chip: Fix stale README badge`, `Chip: Wire Narrow C into core`, `Chip: GR5 collapse style prompts`). The `Chip: ` prefix is non-negotiable — it makes chip-spawned sessions instantly recognizable in the FleetView UI vs. IDE-checkbox-spawned `claude/` sessions and human-driven sessions. The verb phrase MUST NOT itself repeat "chip" — the prefix already marks it as one. Imperative verb phrase under ~50 chars after the prefix.
228
- - **Slug** — kebab-case, short, matches the post-prefix portion of the title. Becomes the worktree branch name (`chip/<slug>`) and the worktree directory (`<project>/.claude/worktrees/<slug>/`).
229
- - **Model at the chip layer** — defaults to whatever the FleetView/CCD runtime assigns (currently Opus). `spawn_task` has no model param.
230
- - **Model at the subagent layer** — pass `model: "sonnet"`/`"haiku"`/`"opus"` to the `Agent` tool. Default to the cheapest that fits the task.
231
- - **subagent_type** — `Explore` for read-only search, `Plan` for design work, `general-purpose` for execution, `code-reviewer` (if installed) for second opinion. Full list in the `Agent` tool description.
232
-
233
- ### Anti-patterns
234
-
235
- - **Chip running cleanup commands** — `git clean`, `git reset --hard`, `git worktree remove`, `git checkout` of foreign branches, raw `rm -rf`. Parallel worktrees share `.git`; a chip cleaning "itself" can hit main's working tree. Chips commit and exit; parent owns cleanup.
236
- - **Chip without Block 1** — pollutes parent checkout. Always include the worktree-setup block.
237
- - **Chip without Block 2** — parent has no way to know it landed. Always include the report-back block.
238
- - **Chip without Block 3** — chip dies after one report; parent can't redirect. Always include the reply-listening block.
239
- - **Sending an expected-reply message without arming Monitor** — Stop hook fires only between user prompts, so a mid-task reply is invisible. Arm `Monitor` on own inbox in the same turn as the `greprag send`.
240
- - **Spawn_task when Agent would do** — extra session, extra context, slower turnaround. Only reach for spawn_task when you need cross-project or persistence.
241
- - **Agent when spawn_task would do** — Agent can't change cwd, so cross-project delegation must go through spawn_task.
242
- - **Polling `greprag inbox` in a loop** — use `greprag inbox watch` under Monitor instead. SSE push, sub-1s latency, free.
243
-
244
- ## Future blocks (planned, not yet defined)
245
-
246
- - **Block 0 — Pre-spawn checklist.** Auto-fill parent-project name, generate slug from title, dry-run the worktree path for collisions. Reduces the boilerplate the spawning agent has to compose by hand.
247
-
248
- **Shipped:** session-scoped routing via the single-segment address grammar `<handle>@greprag.com/<target>` where `<target>` is a session UUID (normal) or a project name (intentional broadcast). v0.11 dropped the legacy `--session`/`--project` send flags and the 3-segment `email/project/session` address — the address itself now carries the target, so missing-target sends error loudly instead of silently broadcasting. adr: adr/address-grammar.md
249
-
250
- ## See also
251
-
252
- - `~/.claude/skills/greprag/SKILL.md` — inbox transport, watcher, retract, discover
253
- - `~/.claude/CLAUDE.md` § Chip Spawning — the lean reference (5 lines) pointing here
254
- - `~/.claude/CLAUDE.md` § Worktree env — sourcing `.env` from main repo when running in a worktree