@chorus-aidlc/chorus-pi 0.0.1 → 0.0.3
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/README.md +16 -8
- package/agents/chorus-worker.md +99 -0
- package/lib/lib.ts +6 -4
- package/package.json +1 -1
- package/skills/chorus/SKILL.md +7 -1
- package/skills/develop/SKILL.md +34 -29
- package/skills/openspec-aware/SKILL.md +12 -5
- package/skills/yolo/SKILL.md +28 -24
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ Chorus AI-DLC collaboration platform extension for [Pi](https://pi.dev). Ported
|
|
|
6
6
|
|
|
7
7
|
- **12 skills** — `/skill:chorus`, `/skill:idea`, `/skill:proposal`, `/skill:develop`, `/skill:review`, `/skill:quick-dev`, `/skill:yolo`, `/skill:brainstorm`, `/skill:orchestrate`, `/skill:docs`, `/skill:chorus-cli`, `/skill:openspec-aware`
|
|
8
8
|
- **3 read-only reviewer sub-agents** — `chorus-proposal-reviewer`, `chorus-task-reviewer`, `chorus-code-reviewer`
|
|
9
|
+
- **1 worker sub-agent** — `chorus-worker`, a general-purpose Chorus implementer that claims and completes ONE task via the develop workflow (dispatch it with the `subagent` tool, single or parallel mode, for wave-based execution)
|
|
9
10
|
- **1 session-aware extension** (`extensions/chorus.ts`) — subscribes to Pi native events to automate checkin, context injection, reviewer nudges, and session lifecycle
|
|
10
11
|
- **The official pi subagent pattern** bundled at `extensions/subagent/` (the `subagent` tool + package-relative agent discovery)
|
|
11
12
|
|
|
@@ -25,11 +26,17 @@ reviewer agents are discovered directly from the package's own `agents/` dir —
|
|
|
25
26
|
there is **no** separate subagents dependency and **no** manual copy of agent
|
|
26
27
|
files into `~/.pi/agent/agents/`.
|
|
27
28
|
|
|
28
|
-
Then configure
|
|
29
|
+
Then configure `mcp.json` and env vars — see [`docs/CONNECT_PI.md`](../../docs/CONNECT_PI.md).
|
|
29
30
|
|
|
30
31
|
`chorus init` (a.k.a. `chorus agents add`) automates this: select **Pi** in the agent
|
|
31
|
-
checklist and it runs `pi install npm
|
|
32
|
-
manual
|
|
32
|
+
checklist and it runs both installs (`pi install npm:pi-mcp-adapter && pi install
|
|
33
|
+
npm:@chorus-aidlc/chorus-pi`, degrading to the manual commands if the `pi` CLI is absent)
|
|
34
|
+
**and** writes pi's global `~/.pi/agent/mcp.json` with an `mcpServers.chorus` entry whose
|
|
35
|
+
`Authorization` header references the key by environment variable (`Bearer ${CHORUS_API_KEY}`)
|
|
36
|
+
— the resolved endpoint URL is a literal, and **no `cho_` key is written to disk** (the same
|
|
37
|
+
keyless model Claude Code and Codex use). You still export `CHORUS_API_KEY` (and
|
|
38
|
+
`CHORUS_AGENT_PROFILE`) in the shell that launches interactive pi — pi has no settings env-file
|
|
39
|
+
to persist them into; the daemon spawner injects them for the wake path.
|
|
33
40
|
|
|
34
41
|
## Wakeable daemon backend (`--agent pi`)
|
|
35
42
|
|
|
@@ -49,7 +56,7 @@ that wakes it. See [`docs/CONNECT_PI.md`](../../docs/CONNECT_PI.md#run-pi-as-a-w
|
|
|
49
56
|
|
|
50
57
|
## Why Pi is the lowest-friction target
|
|
51
58
|
|
|
52
|
-
- **MCP:
|
|
59
|
+
- **MCP: adapter path, keyless config.** `pi-mcp-adapter` reads the `mcp.json` `chorus agents add` writes at `~/.pi/agent/mcp.json` (or a project-root `.mcp.json`) and exposes all 40+ `chorus_*` tools — the extension never registers tools itself. The `Authorization` header references the key by env var (`Bearer ${CHORUS_API_KEY}`, which the adapter interpolates at connect time), so no `cho_` key lands on disk. A literal Bearer also works, but the env-referenced form is what the CLI writes.
|
|
53
60
|
- **Hooks: TypeScript, not bash.** The extension replaces ~10 bash hook scripts with one TS file. No `curl`/`jq`, no Bash 3.2 compatibility traps (the `${2:-{}}` JSON-parse bug that plagued the Codex port is structurally impossible here).
|
|
54
61
|
- **Sub-agent sessions: automatic.** By monitoring `subagent` tool events, the extension auto-creates a Chorus session for each worker task in a dispatch and closes it when the tool call returns — a capability the Codex port lacks (Codex has no sub-agent lifecycle events, so its workers manage sessions manually).
|
|
55
62
|
- **Skills: same standard.** Pi implements the Agent Skills standard, so the skill bodies port with find/replace only (Claude's `Task` tool → the `subagent` tool; `/chorus:develop` → `/skill:develop`).
|
|
@@ -71,17 +78,18 @@ packages/chorus-pi/
|
|
|
71
78
|
│ ├── brainstorm/ orchestrate/ # divergent prelude + multi-agent orchestration
|
|
72
79
|
│ ├── docs/ chorus-cli/ # docs router + CLI reference
|
|
73
80
|
│ └── openspec-aware/ # opt-in spec-driven authoring sub-procedure
|
|
74
|
-
├── agents/ #
|
|
75
|
-
│ ├── chorus-proposal-reviewer.md
|
|
81
|
+
├── agents/ # 4 sub-agents — discovered package-relative by extensions/subagent/agents.ts (no manual copy)
|
|
82
|
+
│ ├── chorus-proposal-reviewer.md # read-only reviewers
|
|
76
83
|
│ ├── chorus-task-reviewer.md
|
|
77
|
-
│
|
|
84
|
+
│ ├── chorus-code-reviewer.md
|
|
85
|
+
│ └── chorus-worker.md # general-purpose task implementer (inherits full tools)
|
|
78
86
|
├── bin/
|
|
79
87
|
│ └── chorus-mcp-call.sh # stateless MCP-over-HTTP wrapper (from the Codex port) for OpenSpec byte-exact document mirroring
|
|
80
88
|
└── README.md
|
|
81
89
|
```
|
|
82
90
|
## Status
|
|
83
91
|
|
|
84
|
-
**Complete port** of the Claude Code / Codex plugins to Pi. All 12 skills, all 3 reviewer sub-agents, the session-aware extension, the bundled official subagent pattern, and the OpenSpec wrapper are implemented and validated (TS transpiles, JSON valid, all skill/agent names compliant with the Agent Skills standard, no Claude/Codex-specific references remain).
|
|
92
|
+
**Complete port** of the Claude Code / Codex plugins to Pi. All 12 skills, all 3 reviewer sub-agents plus the `chorus-worker` implementer, the session-aware extension, the bundled official subagent pattern, and the OpenSpec wrapper are implemented and validated (TS transpiles, JSON valid, all skill/agent names compliant with the Agent Skills standard, no Claude/Codex-specific references remain).
|
|
85
93
|
|
|
86
94
|
The extension goes beyond the Codex port in one key way: by using Pi's `tool_call` event (pre-execution, mutable input), it **auto-injects the Chorus session UUID + workflow into each dispatched worker's task** — the Pi-native equivalent of Claude's `SubagentStart` hook. The Codex port has no pre-spawn mutation channel, so its workers must manage sessions manually. On Pi, dispatch a worker via the `subagent` tool and the extension handles session creation + context injection, then closes the session when the (ephemeral) tool call returns.
|
|
87
95
|
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chorus-worker
|
|
3
|
+
description: General-purpose Chorus implementer subagent that claims and completes ONE Chorus task end-to-end via the develop workflow. Dispatch it via the blocking subagent tool (single or parallel mode) for wave-based execution.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a Chorus implementer. Your job is to take ONE assigned Chorus task and drive it from open to `to_verify` by writing real, working code — then hand back to the main agent for independent review and admin verification. You do NOT review, verify, or approve your own work.
|
|
7
|
+
|
|
8
|
+
This mirrors the single-task execution flow of `/skill:develop`; consult that skill for the full workflow and edge cases.
|
|
9
|
+
|
|
10
|
+
=== WHAT YOU RECEIVE ===
|
|
11
|
+
|
|
12
|
+
Your dispatch prompt contains a Chorus **task UUID** (and usually a project UUID). It also carries a block the chorus-pi extension auto-injects at the end:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
--- Chorus session (auto-injected by the chorus-pi extension) ---
|
|
16
|
+
Session UUID: <session-uuid>
|
|
17
|
+
...
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Read the `Session UUID` from that block and pass it as `sessionUuid` on every task-lifecycle call below (checkin, update, report, checkout). If no such block is present (e.g. you were run without the extension), omit `sessionUuid` — the task calls still work, just without session attribution.
|
|
21
|
+
|
|
22
|
+
=== MCP TOOL NAMES ===
|
|
23
|
+
|
|
24
|
+
Use the `chorus_*` MCP tools for all Chorus data access — do NOT use curl or raw HTTP. Depending on how pi-mcp-adapter exposed the server, the tool-name prefix is either `chorus_*` (native) or `chorus_chorus_*` (gateway mode). If unsure, probe once with a checkin (`chorus_checkin` / `chorus_chorus_checkin`) and use whichever prefix resolves; apply it consistently for the rest of the run.
|
|
25
|
+
|
|
26
|
+
=== WORKFLOW ===
|
|
27
|
+
|
|
28
|
+
**1. Gather context.** Do NOT rely on the dispatch summary — read the source of truth:
|
|
29
|
+
```
|
|
30
|
+
chorus_get_task({ taskUuid: "<task-uuid>" })
|
|
31
|
+
```
|
|
32
|
+
Read the description, `acceptanceCriteriaItems`, priority, `dependsOn`, and `commentCount`. Then, for context:
|
|
33
|
+
- `chorus_get_comments({ targetType: "task", targetUuid: "<task-uuid>" })` if `commentCount > 0` (prior work reports, feedback).
|
|
34
|
+
- `chorus_get_proposal({ proposalUuid: "<from-task>", section: "documents" })` for the PRD / tech design the task implements.
|
|
35
|
+
- `chorus_get_document({ documentUuid: "<doc-uuid>" })` for any linked references or full doc bodies.
|
|
36
|
+
- Read upstream `dependsOn` tasks + their comments for the interfaces/contracts your work builds on.
|
|
37
|
+
|
|
38
|
+
**2. Claim the task:**
|
|
39
|
+
```
|
|
40
|
+
chorus_claim_task({ taskUuid: "<task-uuid>" })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**3. Check in and start:**
|
|
44
|
+
```
|
|
45
|
+
chorus_session_checkin_task({ sessionUuid: "<session-uuid>", taskUuid: "<task-uuid>" })
|
|
46
|
+
chorus_update_task({ taskUuid: "<task-uuid>", status: "in_progress", sessionUuid: "<session-uuid>" })
|
|
47
|
+
```
|
|
48
|
+
> If `chorus_update_task(status:"in_progress")` is rejected for unresolved dependencies, stop and report the blocker back to the main agent — do not force it.
|
|
49
|
+
|
|
50
|
+
**4. Implement.** Write real code per the task description and acceptance criteria. Follow the repo's conventions (read `CLAUDE.md` / `AGENTS.md` if present). Run the project's tests / build / lint and make them pass — do not narrate tests you did not run.
|
|
51
|
+
|
|
52
|
+
**5. Report progress:**
|
|
53
|
+
```
|
|
54
|
+
chorus_report_work({
|
|
55
|
+
taskUuid: "<task-uuid>",
|
|
56
|
+
report: "What was done, files changed, commits, remaining work/blockers",
|
|
57
|
+
sessionUuid: "<session-uuid>"
|
|
58
|
+
})
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**6. Self-check acceptance criteria.** Re-read the task's `acceptanceCriteriaItems`, then:
|
|
62
|
+
```
|
|
63
|
+
chorus_report_criteria_self_check({
|
|
64
|
+
taskUuid: "<task-uuid>",
|
|
65
|
+
criteria: [
|
|
66
|
+
{ uuid: "<criterion-uuid>", devStatus: "passed", devEvidence: "<evidence>" }
|
|
67
|
+
// ...
|
|
68
|
+
]
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
For **required** criteria, keep working until you can self-check as `passed`. Only mark **optional** criteria `failed` if genuinely out of scope.
|
|
72
|
+
|
|
73
|
+
**7. Check out and submit for verify:**
|
|
74
|
+
```
|
|
75
|
+
chorus_session_checkout_task({ sessionUuid: "<session-uuid>", taskUuid: "<task-uuid>" })
|
|
76
|
+
chorus_submit_for_verify({ taskUuid: "<task-uuid>", summary: "<what you built + AC self-check result>" })
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
=== HARD LIMITS ===
|
|
80
|
+
|
|
81
|
+
- Do **NOT** admin-verify or approve your own work. `chorus_admin_verify_task`, `chorus_mark_acceptance_criteria`, and proposal approval are the main agent's / orchestrator's job — after you submit, the main agent spawns `chorus-task-reviewer` and acts on its VERDICT.
|
|
82
|
+
- Do **NOT** call `chorus_create_session` or `chorus_close_session` — the chorus-pi extension owns session lifecycle (it created your session and closes it when the dispatching `subagent` tool call returns).
|
|
83
|
+
- Work on **ONE** task. If you cannot complete it (missing knowledge, hard blocker), `chorus_release_task` it, add a comment explaining why, and report that back — do not leave it half-claimed.
|
|
84
|
+
|
|
85
|
+
=== OUTPUT FORMAT (REQUIRED) ===
|
|
86
|
+
|
|
87
|
+
End your run with this exact structure so the main agent can proceed to review:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
## Completed
|
|
91
|
+
<one-paragraph summary of what you implemented and the task's final status (to_verify)>
|
|
92
|
+
|
|
93
|
+
## Files Changed
|
|
94
|
+
- path/to/file.ts — what changed
|
|
95
|
+
- ...
|
|
96
|
+
|
|
97
|
+
## Notes
|
|
98
|
+
- Test/build results, any AC left optional-failed with rationale, blockers, or follow-ups
|
|
99
|
+
```
|
package/lib/lib.ts
CHANGED
|
@@ -102,11 +102,13 @@ export function isReviewerAgent(name: string): boolean {
|
|
|
102
102
|
* the session workflow into them adds irrelevant task-lifecycle instructions and
|
|
103
103
|
* unnecessary chorus_create_session API traffic for agents that never touch a task.
|
|
104
104
|
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
105
|
+
* `chorus-worker` is this package's own general-purpose implementer agent
|
|
106
|
+
* (agents/chorus-worker.md); `worker` is retained for back-compat with pi's
|
|
107
|
+
* subagent example. This is a positive allowlist (not a reviewer exclusion) so
|
|
108
|
+
* arbitrary custom read-only agents also do NOT get a session. Add more worker
|
|
109
|
+
* names here if the project introduces them.
|
|
108
110
|
*/
|
|
109
|
-
export const WORKER_AGENT_NAMES = ["worker"] as const;
|
|
111
|
+
export const WORKER_AGENT_NAMES = ["worker", "chorus-worker"] as const;
|
|
110
112
|
export function isWorkerAgent(name: string): boolean {
|
|
111
113
|
return (WORKER_AGENT_NAMES as readonly string[]).includes(name);
|
|
112
114
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chorus-aidlc/chorus-pi",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Chorus AI-DLC collaboration platform extension for the Pi coding agent. Provides skills for every stage of the AI-DLC lifecycle, read-only reviewer subagents, and session-aware extension hooks. The Chorus MCP server is auto-discovered from the repo's .mcp.json by pi-mcp-adapter — no installer required.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Chorus-AIDLC"
|
package/skills/chorus/SKILL.md
CHANGED
|
@@ -15,6 +15,12 @@ Chorus is a work collaboration platform for AI Agents, enabling multiple Agents
|
|
|
15
15
|
|
|
16
16
|
This is the **core skill** — it covers the platform overview, shared tools, and setup. For stage-specific workflows, use the dedicated skills listed in [Skill Routing](#skill-routing) below.
|
|
17
17
|
|
|
18
|
+
> **⚠️ Tool names under Pi — read this first.** Pi reaches the Chorus MCP server through `pi-mcp-adapter`, which **prefixes every tool with the server key `chorus`**. Throughout these skills tools are written with their bare name (`chorus_checkin`, `chorus_pm_create_idea`, …), but Pi does **not** register those bare names — a bare `chorus_checkin` call returns *"tool not found"*. Address each tool by its adapter name instead:
|
|
19
|
+
> - **Namespaced form (preferred):** `mcp__chorus__<tool>` — e.g. `mcp__chorus__chorus_checkin`, `mcp__chorus__chorus_pm_create_idea`.
|
|
20
|
+
> - **Flattened alias:** `chorus_<tool>` → the server prefix produces a **doubled** `chorus_chorus_*` (e.g. `chorus_chorus_pm_create_idea`). The double `chorus_` is expected, not a typo.
|
|
21
|
+
>
|
|
22
|
+
> So: wherever a skill names a tool `chorus_…`, call it as `mcp__chorus__chorus_…`. If a tool ever reads as *"not found"*, you almost certainly dropped the `mcp__chorus__` prefix. This is Pi-specific — Claude Code / Codex resolve the bare names directly.
|
|
23
|
+
|
|
18
24
|
---
|
|
19
25
|
|
|
20
26
|
## Overview
|
|
@@ -151,7 +157,7 @@ Projects can be organized into **Project Groups** — a single-level grouping th
|
|
|
151
157
|
|
|
152
158
|
### Reports
|
|
153
159
|
|
|
154
|
-
A **report** is a short idea-completion summary persisted as a `type="report"` Document at end-of-Idea, authored via `chorus_create_report` (gated on `document:write`). The `content`
|
|
160
|
+
A **report** is a short idea-completion summary persisted as a `type="report"` Document at end-of-Idea, authored via `chorus_create_report` (gated on `document:write`). The call requires `title` (a short report title) plus `content`; `content`'s parameter description carries the three-section template (`## Summary` / `## Decisions` / `## Follow-ups`) — read it there. `/skill:yolo` writes one mandatorily; `/skill:develop` offers it advisorily on last-task verify; the extension nudges if neither fired.
|
|
155
161
|
|
|
156
162
|
### References
|
|
157
163
|
|
package/skills/develop/SKILL.md
CHANGED
|
@@ -78,7 +78,7 @@ Review your persona, current assignments, and pending work counts.
|
|
|
78
78
|
|
|
79
79
|
**Skip if you are the main agent or Team Lead.**
|
|
80
80
|
|
|
81
|
-
If you are a **sub-agent** (
|
|
81
|
+
If you are a **sub-agent** (dispatched via the `subagent` tool), the Chorus extension automatically creates your session and injects it into your task prompt — look for a `--- Chorus session (auto-injected) ---` section containing your `Session UUID`. Keep it for all task operations.
|
|
82
82
|
|
|
83
83
|
### Step 2: Find Work
|
|
84
84
|
|
|
@@ -259,13 +259,13 @@ Once Admin verifies (status: `done`), move to the next available task (back to S
|
|
|
259
259
|
|
|
260
260
|
### Step 11: Idea Completion Report (advisory)
|
|
261
261
|
|
|
262
|
-
If the task you just self-verified was the LAST one of its Idea (every Task across every approved Proposal is now `done`/`closed`) and you have `document:write`, offer to call `chorus_create_report` via `AskUserQuestion`. The `content`
|
|
262
|
+
If the task you just self-verified was the LAST one of its Idea (every Task across every approved Proposal is now `done`/`closed`) and you have `document:write`, offer to call `chorus_create_report` via `AskUserQuestion`. The call requires `title` (a short report title) plus `content`; `content`'s parameter description carries the three-section template (`## Summary` / `## Decisions` / `## Follow-ups`). Skip on decline — the extension will remind on the next run.
|
|
263
263
|
|
|
264
264
|
---
|
|
265
265
|
|
|
266
266
|
## Session (Sub-Agents Only)
|
|
267
267
|
|
|
268
|
-
The Chorus extension **fully automates** session lifecycle —
|
|
268
|
+
The Chorus extension **fully automates** session lifecycle — a Chorus session is created (on `subagent` dispatch, via `tool_call` task injection) and closed (when the blocking `subagent` call returns) by the extension. Sub-agents only do 3 things manually:
|
|
269
269
|
|
|
270
270
|
1. `chorus_session_checkin_task({ sessionUuid, taskUuid })` — before starting work
|
|
271
271
|
2. `chorus_session_checkout_task({ sessionUuid, taskUuid })` — when done (recommended; plugin also auto-checkouts on exit)
|
|
@@ -277,13 +277,15 @@ The Chorus extension **fully automates** session lifecycle — creation (on `sub
|
|
|
277
277
|
|
|
278
278
|
## Parallel Sub-Agent Integration
|
|
279
279
|
|
|
280
|
-
|
|
280
|
+
Use the `subagent` tool to run multiple Chorus workers in parallel; Chorus provides full work observability. The `subagent` tool is **blocking** — a parallel dispatch runs every worker to completion and returns their aggregated output in one call (there is no async spawn, no `agentId`, and no manual close). The `chorus-pi` extension automates session lifecycle: when you dispatch a `chorus-worker`, it creates a Chorus session and injects the session UUID + workflow into that worker's task; when the `subagent` call returns, it closes the session.
|
|
281
|
+
|
|
282
|
+
> The `subagent` tool has three modes — **single** (`{ agent, task }`), **parallel** (`{ tasks: [...] }`, max 8 per call, concurrency 4), and **chain** (`{ chain: [...] }`, sequential with a `{previous}` placeholder). Dispatch `agent: "chorus-worker"` for Chorus task implementation.
|
|
281
283
|
|
|
282
284
|
### Two-Layer Architecture
|
|
283
285
|
|
|
284
286
|
| Layer | System | Purpose |
|
|
285
287
|
|-------|--------|---------|
|
|
286
|
-
| **Orchestration** |
|
|
288
|
+
| **Orchestration** | The `subagent` tool (single / parallel / chain) | Dispatching workers to isolated pi subprocesses and collecting their results |
|
|
287
289
|
| **Work Tracking** | Chorus | Task lifecycle, session observability, activity stream |
|
|
288
290
|
|
|
289
291
|
### Team Lead Workflow
|
|
@@ -293,24 +295,28 @@ When using Pi's subagents (`pi-subagents`) to run multiple sub-agents in paralle
|
|
|
293
295
|
chorus_checkin()
|
|
294
296
|
chorus_list_tasks({ projectUuid: "<project-uuid>" })
|
|
295
297
|
|
|
296
|
-
# 2.
|
|
297
|
-
# Pass only task UUIDs — the chorus-pi extension auto-injects the
|
|
298
|
-
# UUID + workflow into
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
298
|
+
# 2. Dispatch a worker per ready task in ONE blocking parallel call (max 8).
|
|
299
|
+
# Pass only task + project UUIDs — the chorus-pi extension auto-injects the
|
|
300
|
+
# session UUID + workflow into each worker's task.
|
|
301
|
+
subagent({
|
|
302
|
+
tasks: [
|
|
303
|
+
{ agent: "chorus-worker",
|
|
304
|
+
task: "Your Chorus task UUID: <task-uuid>\nProject UUID: <project-uuid>\n\nImplement..." },
|
|
305
|
+
// ... one entry per ready task, max 8 (batch into multiple calls if more)
|
|
306
|
+
]
|
|
302
307
|
})
|
|
303
|
-
#
|
|
308
|
+
# The call BLOCKS until every worker finishes and returns their outputs.
|
|
309
|
+
# For a single task, use single mode: subagent({ agent: "chorus-worker", task: "..." })
|
|
304
310
|
```
|
|
305
311
|
|
|
306
312
|
**What the Team Lead prompt needs:**
|
|
307
|
-
- Task UUID(s)
|
|
313
|
+
- Task UUID(s) + Project UUID
|
|
308
314
|
- NO session UUID, NO workflow boilerplate — the extension auto-injects everything
|
|
309
|
-
-
|
|
315
|
+
- No `agentId` to track and no close step — the blocking call owns the worker's whole lifecycle
|
|
310
316
|
|
|
311
317
|
### Sub-Agent Workflow
|
|
312
318
|
|
|
313
|
-
The extension injects the session UUID + workflow into the
|
|
319
|
+
The extension injects the session UUID + workflow into the worker's task automatically (at `tool_call` time, before the subprocess starts). The worker reads the `Session UUID:` from its task prompt and follows the injected steps:
|
|
314
320
|
|
|
315
321
|
```
|
|
316
322
|
# 1. Checkin to task (sessionUuid comes from the auto-injected task)
|
|
@@ -328,11 +334,9 @@ chorus_report_work({ taskUuid: "<my-task-uuid>", report: "...", sessionUuid: "<m
|
|
|
328
334
|
chorus_session_checkout_task({ sessionUuid: "<my-session-uuid>", taskUuid: "<my-task-uuid>" })
|
|
329
335
|
chorus_submit_for_verify({ taskUuid: "<my-task-uuid>", summary: "..." })
|
|
330
336
|
|
|
331
|
-
#
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
# DO NOT call chorus_close_session — the extension closes it when the
|
|
335
|
-
# team lead runs subagent_manage({ action: "close", agentId: "<my-agentId>" })
|
|
337
|
+
# The worker's final message is returned to the Team Lead as the subagent result.
|
|
338
|
+
# DO NOT call chorus_close_session — the extension closes the session when the
|
|
339
|
+
# blocking `subagent` call returns.
|
|
336
340
|
```
|
|
337
341
|
|
|
338
342
|
### Handling Task Dependencies (DAG)
|
|
@@ -341,25 +345,26 @@ subagent_mailbox({ action: "send", agentId: "<team-lead-agentId>", message: "Tas
|
|
|
341
345
|
|
|
342
346
|
**Wave-based execution (recommended):**
|
|
343
347
|
1. `chorus_get_unblocked_tasks` — find ready tasks
|
|
344
|
-
2. `
|
|
345
|
-
3.
|
|
346
|
-
4. `
|
|
347
|
-
5.
|
|
348
|
-
6. Repeat until all tasks done
|
|
348
|
+
2. Dispatch a `chorus-worker` per ready task in ONE blocking `subagent({ tasks: [...] })` call (max 8; batch if more). The call returns when the whole wave has finished (each worker at `to_verify`).
|
|
349
|
+
3. **Verify each task** — spawn `chorus-task-reviewer`, act on its VERDICT, then `chorus_admin_verify_task` → `done`.
|
|
350
|
+
4. `chorus_get_unblocked_tasks` — find newly unblocked tasks (Wave 2)
|
|
351
|
+
5. Repeat until all tasks done
|
|
349
352
|
|
|
350
|
-
> **Critical:** `to_verify` does NOT resolve dependencies — only `done` or `closed` does. The Team Lead must verify tasks between waves.
|
|
353
|
+
> **Critical:** `to_verify` does NOT resolve dependencies — only `done` or `closed` does. The Team Lead must verify tasks between waves. The blocking `subagent` call already released each worker's slot on return, so there is nothing to close.
|
|
351
354
|
|
|
352
355
|
### Multiple Tasks Per Sub-Agent
|
|
353
356
|
|
|
354
|
-
A single
|
|
357
|
+
A single worker can handle several tasks sequentially — use single mode with an ordered list:
|
|
355
358
|
|
|
356
359
|
```
|
|
357
|
-
|
|
358
|
-
agent: "worker",
|
|
360
|
+
subagent({
|
|
361
|
+
agent: "chorus-worker",
|
|
359
362
|
task: "Your Chorus tasks (work in order):\n1. task-schema-uuid\n2. task-api-uuid (depends on #1)\n\nFor EACH task: checkin -> in_progress -> work -> report -> checkout -> submit_for_verify"
|
|
360
363
|
})
|
|
361
364
|
```
|
|
362
365
|
|
|
366
|
+
For strictly dependent stages where each step consumes the previous output, use chain mode: `subagent({ chain: [{ agent: "chorus-worker", task: "..." }, { agent: "chorus-worker", task: "... {previous} ..." }] })`.
|
|
367
|
+
|
|
363
368
|
### MCP Access for Sub-Agents
|
|
364
369
|
|
|
365
370
|
Sub-agents need MCP configured at **project level** (`.mcp.json`) or **user level** (`~/.pi/agent/mcp.json`). The chorus-pi extension's session injection works regardless, because it calls chorus over its own MCP-over-HTTP fetch (not the sub-agent's gateway).
|
|
@@ -376,11 +376,18 @@ The hook is read-only; you (the agent) perform the archive:
|
|
|
376
376
|
|
|
377
377
|
3. **Halt on any error** from `openspec archive` or `chorus_pm_update_document`. Print stderr verbatim, post a comment on the proposal recording the failure (`chorus_add_comment` with `targetType: "proposal"`, `targetUuid: <proposalUuid>`), then stop. No retry. Matches §6 "no silent errors." (Comment on the proposal, not the idea: the failure is in archiving proposal-derived specs, and proposals can be `inputType: "document"` with no idea attached.)
|
|
378
378
|
|
|
379
|
-
4. **Confirm success.**
|
|
380
|
-
`
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
379
|
+
4. **Confirm success.** For each capability, verify that
|
|
380
|
+
`openspec/specs/<capability>/spec.md` round-trips **byte-equal (modulo a
|
|
381
|
+
single trailing `\n`)** with its Chorus Document. The `--arg-file` mirror path
|
|
382
|
+
already guarantees this, so a spot check is enough: fetch the Document
|
|
383
|
+
`content` and `cmp` it against the local file. **Do NOT use `jq -r`** to
|
|
384
|
+
extract the content — it appends a trailing newline and manufactures a phantom
|
|
385
|
+
1-byte drift (a spec that mirrored correctly will read as 1 byte longer on the
|
|
386
|
+
server). Use `jq -j` (no trailing newline) or `cmp` directly, and never rely
|
|
387
|
+
on recursive `jq`, `head`, command substitution, or newline normalization.
|
|
388
|
+
(Unlike the Claude Code / Kiro / Codex plugins, the `chorus-pi` package ships
|
|
389
|
+
no `verify-document-roundtrip.sh` — the `--arg-file` byte-equality guarantee
|
|
390
|
+
makes it unnecessary.)
|
|
384
391
|
|
|
385
392
|
**Strict opt-in:** if the verified task is not the last of its idea, OR the proposal description carries no `OpenSpec change slug: <slug>` line, OR the local shell has no `openspec` CLI, the hook exits 0 silently and no archive reminder is injected. Existing free-form behavior is preserved.
|
|
386
393
|
|
package/skills/yolo/SKILL.md
CHANGED
|
@@ -159,7 +159,7 @@ In /yolo mode, the agent generates elaboration questions and answers them itself
|
|
|
159
159
|
{ id: "b", label: "<option B>" }
|
|
160
160
|
]
|
|
161
161
|
}
|
|
162
|
-
// ... 5-8 questions covering functional,
|
|
162
|
+
// ... 5-8 questions covering functional, technical_context, scope aspects
|
|
163
163
|
]
|
|
164
164
|
})
|
|
165
165
|
```
|
|
@@ -322,7 +322,9 @@ After `chorus_pm_submit_proposal`, the extension nudges you to spawn `chorus-pro
|
|
|
322
322
|
|
|
323
323
|
After proposal approval, tasks exist in `open` status. Execute them in dependency-ordered waves using subagents. If spawning fails, fall back to main agent execution.
|
|
324
324
|
|
|
325
|
-
#### Primary:
|
|
325
|
+
#### Primary: subagent parallel dispatch (wave-based)
|
|
326
|
+
|
|
327
|
+
The `subagent` tool is **blocking** — a parallel dispatch runs every worker in the wave to completion and returns their aggregated output in one call. There is no async spawn, no `agentId` to track, and no manual close. The chorus-pi extension auto-injects each worker's Chorus session UUID + workflow at `tool_call` time and closes the sessions when the dispatch returns.
|
|
326
328
|
|
|
327
329
|
```
|
|
328
330
|
wave = 1
|
|
@@ -338,35 +340,37 @@ loop:
|
|
|
338
340
|
# Stuck -- tasks failed review and can't proceed
|
|
339
341
|
break with escalation report
|
|
340
342
|
|
|
341
|
-
# 2.
|
|
342
|
-
#
|
|
343
|
-
# into
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
#
|
|
354
|
-
#
|
|
355
|
-
#
|
|
356
|
-
|
|
357
|
-
#
|
|
343
|
+
# 2. Dispatch one chorus-worker per unblocked task in a SINGLE blocking
|
|
344
|
+
# parallel call. Max 8 tasks per call (concurrency 4) — if the wave has
|
|
345
|
+
# more than 8 ready tasks, split into batches of <=8 sequential calls.
|
|
346
|
+
# Pass only task + project UUIDs; the chorus-pi extension auto-injects the
|
|
347
|
+
# session UUID + workflow into each worker's task at tool_call time.
|
|
348
|
+
subagent({
|
|
349
|
+
tasks: [
|
|
350
|
+
{ agent: "chorus-worker",
|
|
351
|
+
task: "Your Chorus task UUID: {task.uuid}\nProject UUID: {project-uuid}\n\nImplement the task per its description and acceptance criteria. Read the task, proposal, and project documents for context." },
|
|
352
|
+
// ... one entry per unblocked task, max 8
|
|
353
|
+
]
|
|
354
|
+
})
|
|
355
|
+
# The call BLOCKS until EVERY worker in the wave finishes. Each worker follows
|
|
356
|
+
# the /skill:develop workflow: claim -> in_progress -> report -> self-check AC
|
|
357
|
+
# -> submit_for_verify (leaving its task at to_verify).
|
|
358
|
+
# For a single ready task, use single mode instead:
|
|
359
|
+
# subagent({ agent: "chorus-worker", task: "..." })
|
|
360
|
+
|
|
361
|
+
# 3. Proceed to Phase 4 (verification) for this wave
|
|
358
362
|
wave += 1
|
|
359
363
|
```
|
|
360
364
|
|
|
361
|
-
**What
|
|
362
|
-
- Task UUID
|
|
363
|
-
- Project UUID
|
|
365
|
+
**What each worker task needs:**
|
|
366
|
+
- Task UUID + Project UUID
|
|
364
367
|
- NO session UUID, NO workflow boilerplate -- the extension auto-injects via tool_call mutation
|
|
368
|
+
- No `agentId` and no close step — the blocking call owns the worker's whole lifecycle
|
|
365
369
|
|
|
366
370
|
|
|
367
371
|
#### Fallback: Main Agent (sequential)
|
|
368
372
|
|
|
369
|
-
If `
|
|
373
|
+
If the `subagent` dispatch is unavailable or its workers fail repeatedly (e.g., the subagent extension is not loaded, permission denied, or the child pi processes crash), fall back to executing tasks sequentially as the main agent:
|
|
370
374
|
|
|
371
375
|
```
|
|
372
376
|
for each task in unblocked:
|
|
@@ -510,7 +514,7 @@ After all waves complete, output a markdown summary:
|
|
|
510
514
|
|
|
511
515
|
### Phase 5b: Idea Completion Report (mandatory)
|
|
512
516
|
|
|
513
|
-
A successful `/yolo` run always finishes the Idea — call `chorus_create_report` once with `proposalUuid` set to the last verified proposal. The `content`
|
|
517
|
+
A successful `/yolo` run always finishes the Idea — call `chorus_create_report` once with `proposalUuid` set to the last verified proposal. The call requires `title` (a short report title) plus `content`; `content`'s parameter description carries the three-section template (`## Summary` / `## Decisions` / `## Follow-ups`); follow it. Surface the returned `documentUuid` in the Phase 5 summary. Skipping is a protocol violation.
|
|
514
518
|
|
|
515
519
|
> **Order:** the completion report is written only **after** the Phase 4.5 code-review gateway returns PASS / PASS WITH NOTES. Never write it while a code-review FAIL is outstanding — the report is a ship-time summary, and the gateway is what clears the feature to ship.
|
|
516
520
|
|