peaks-cli 1.3.1 → 1.3.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 +6 -2
- package/bin/peaks.js +0 -0
- package/dist/src/cli/commands/core-artifact-commands.js +49 -11
- package/dist/src/cli/commands/gate-commands.js +28 -19
- package/dist/src/cli/commands/hook-handle.d.ts +17 -0
- package/dist/src/cli/commands/hook-handle.js +111 -0
- package/dist/src/cli/commands/hooks-commands.js +72 -21
- package/dist/src/cli/commands/progress-commands.js +9 -2
- package/dist/src/cli/commands/progress-start-spawn.js +30 -4
- package/dist/src/cli/commands/slice-commands.js +4 -2
- package/dist/src/cli/commands/statusline-commands.js +75 -17
- package/dist/src/cli/commands/sub-agent-commands.d.ts +5 -0
- package/dist/src/cli/commands/sub-agent-commands.js +488 -0
- package/dist/src/cli/commands/sub-agent-dispatch-guard.d.ts +55 -0
- package/dist/src/cli/commands/sub-agent-dispatch-guard.js +57 -0
- package/dist/src/cli/commands/workspace-commands.js +70 -14
- package/dist/src/cli/program.js +9 -0
- package/dist/src/hooks/pre-tool-use-sub-agent.d.ts +28 -0
- package/dist/src/hooks/pre-tool-use-sub-agent.js +105 -0
- package/dist/src/services/artifacts/artifact-prerequisites.d.ts +12 -0
- package/dist/src/services/artifacts/artifact-prerequisites.js +39 -8
- package/dist/src/services/artifacts/request-artifact-service.js +116 -76
- package/dist/src/services/config/config-types.d.ts +1 -1
- package/dist/src/services/context/artifact-meta.d.ts +72 -0
- package/dist/src/services/context/artifact-meta.js +105 -0
- package/dist/src/services/context/context-guard.d.ts +49 -0
- package/dist/src/services/context/context-guard.js +91 -0
- package/dist/src/services/context/dispatch-context-guard.d.ts +27 -0
- package/dist/src/services/context/dispatch-context-guard.js +192 -0
- package/dist/src/services/context/headroom-client.d.ts +34 -0
- package/dist/src/services/context/headroom-client.js +117 -0
- package/dist/src/services/context/shared-channel.d.ts +92 -0
- package/dist/src/services/context/shared-channel.js +285 -0
- package/dist/src/services/context/threshold.d.ts +35 -0
- package/dist/src/services/context/threshold.js +76 -0
- package/dist/src/services/dispatch/batch-counter.d.ts +27 -0
- package/dist/src/services/dispatch/batch-counter.js +85 -0
- package/dist/src/services/dispatch/dispatch-record-writer.d.ts +93 -0
- package/dist/src/services/dispatch/dispatch-record-writer.js +261 -0
- package/dist/src/services/dispatch/heartbeat-truncator.d.ts +26 -0
- package/dist/src/services/dispatch/heartbeat-truncator.js +13 -0
- package/dist/src/services/dispatch/leak-detector.d.ts +11 -0
- package/dist/src/services/dispatch/leak-detector.js +72 -0
- package/dist/src/services/dispatch/sub-agent-dispatcher.d.ts +127 -0
- package/dist/src/services/dispatch/sub-agent-dispatcher.js +98 -0
- package/dist/src/services/doctor/doctor-service.d.ts +62 -0
- package/dist/src/services/doctor/doctor-service.js +276 -1
- package/dist/src/services/ide/adapters/claude-code-adapter.d.ts +18 -0
- package/dist/src/services/ide/adapters/claude-code-adapter.js +53 -0
- package/dist/src/services/ide/adapters/trae-adapter.d.ts +34 -0
- package/dist/src/services/ide/adapters/trae-adapter.js +70 -0
- package/dist/src/services/ide/hook-protocol.d.ts +44 -0
- package/dist/src/services/ide/hook-protocol.js +71 -0
- package/dist/src/services/ide/hook-translator.d.ts +72 -0
- package/dist/src/services/ide/hook-translator.js +128 -0
- package/dist/src/services/ide/ide-detector.d.ts +10 -0
- package/dist/src/services/ide/ide-detector.js +19 -0
- package/dist/src/services/ide/ide-registry.d.ts +14 -0
- package/dist/src/services/ide/ide-registry.js +45 -0
- package/dist/src/services/ide/ide-types.d.ts +120 -0
- package/dist/src/services/ide/ide-types.js +2 -0
- package/dist/src/services/ide/shared/atomic-json.d.ts +15 -0
- package/dist/src/services/ide/shared/atomic-json.js +58 -0
- package/dist/src/services/ide/shared/safe-path.d.ts +11 -0
- package/dist/src/services/ide/shared/safe-path.js +29 -0
- package/dist/src/services/progress/progress-service.d.ts +1 -1
- package/dist/src/services/progress/progress-service.js +18 -14
- package/dist/src/services/security/safe-settings-path.d.ts +12 -0
- package/dist/src/services/security/safe-settings-path.js +104 -0
- package/dist/src/services/session/session-manager.d.ts +22 -1
- package/dist/src/services/session/session-manager.js +137 -28
- package/dist/src/services/signal/cancel-handler.d.ts +14 -0
- package/dist/src/services/signal/cancel-handler.js +76 -0
- package/dist/src/services/skill/resume-detector.d.ts +54 -0
- package/dist/src/services/skill/resume-detector.js +334 -0
- package/dist/src/services/skill/skill-scheduler.d.ts +40 -0
- package/dist/src/services/skill/skill-scheduler.js +53 -0
- package/dist/src/services/skills/hooks-settings-service.d.ts +47 -29
- package/dist/src/services/skills/hooks-settings-service.js +190 -144
- package/dist/src/services/skills/statusline-settings-service.d.ts +33 -6
- package/dist/src/services/skills/statusline-settings-service.js +31 -34
- package/dist/src/services/slice/slice-archive-service.d.ts +20 -0
- package/dist/src/services/slice/slice-archive-service.js +111 -0
- package/dist/src/services/slice/slice-check-service.js +20 -1
- package/dist/src/services/slice/slice-check-types.d.ts +9 -0
- package/dist/src/services/solo/batch-heartbeat-poller.d.ts +51 -0
- package/dist/src/services/solo/batch-heartbeat-poller.js +88 -0
- package/dist/src/services/solo/status-line-renderer.d.ts +34 -0
- package/dist/src/services/solo/status-line-renderer.js +55 -0
- package/dist/src/services/workspace/migrate-service.js +124 -2
- package/dist/src/services/workspace/migrate-types.d.ts +50 -7
- package/dist/src/services/workspace/reconcile-service.d.ts +69 -0
- package/dist/src/services/workspace/reconcile-service.js +267 -48
- package/dist/src/services/workspace/reconcile-types.d.ts +37 -0
- package/dist/src/services/workspace/workspace-service.js +29 -62
- package/dist/src/shared/version.d.ts +1 -1
- package/dist/src/shared/version.js +1 -1
- package/package.json +2 -1
- package/schemas/doctor-report.schema.json +2 -2
- package/skills/peaks-ide/SKILL.md +159 -0
- package/skills/peaks-qa/SKILL.md +58 -1
- package/skills/peaks-qa/references/qa-fanout-contract.md +150 -0
- package/skills/peaks-rd/SKILL.md +52 -9
- package/skills/peaks-solo/SKILL.md +83 -20
- package/skills/peaks-solo/references/context-governance.md +144 -0
- package/skills/peaks-solo/references/headroom-integration.md +107 -0
- package/skills/peaks-solo/references/runbook.md +3 -3
- package/skills/peaks-solo/references/sub-agent-dispatch.md +218 -0
- package/skills/peaks-solo/references/swarm-dispatch-contract.md +3 -37
- package/skills/peaks-txt/SKILL.md +19 -0
- package/skills/peaks-ui/SKILL.md +28 -1
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# sub-agent-dispatch.md — peaks sub-agent dispatch orchestrator contract
|
|
2
|
+
|
|
3
|
+
> **Slice**: 2026-06-07-sub-agent-dispatch-decouple (G3 + G6)
|
|
4
|
+
> **Audience**: SKILL.md authors and LLM readers of peaks-solo / peaks-rd / peaks-qa
|
|
5
|
+
> **Status**: stable
|
|
6
|
+
|
|
7
|
+
This reference is the orchestrator-side contract for sub-agent dispatch.
|
|
8
|
+
It explains why the peaks family uses `peaks sub-agent dispatch <role>` as
|
|
9
|
+
the canonical primitive, how the dispatch envelope flows back to the LLM,
|
|
10
|
+
and how the new G6 heartbeat channel keeps the user informed during the
|
|
11
|
+
batch-sync wait. Read this before writing or extending any peaks-*
|
|
12
|
+
SKILL.md that dispatches sub-agents.
|
|
13
|
+
|
|
14
|
+
## Why a CLI primitive (skill-first / CLI-auxiliary)
|
|
15
|
+
|
|
16
|
+
The peaks skill family is the **product**. The CLI is a thin atomic
|
|
17
|
+
the skills compose. For sub-agent dispatch the relationship is:
|
|
18
|
+
|
|
19
|
+
| Surface | Who owns | What it does | Who calls it |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| SKILL.md (主面) | peaks-solo, peaks-rd, peaks-qa | Tells the LLM when and why to dispatch a sub-agent; what prompt to pass; what artifacts to expect back | LLM (during normal Solo / RD / QA flow) |
|
|
22
|
+
| CLI (副 / 原子) | `peaks sub-agent dispatch` | Validates the role, looks up the current IDE's `subAgentDispatcher`, returns a per-IDE tool-call descriptor + writes a dispatch record | LLM (read from the SKILL.md) |
|
|
23
|
+
| Dispatcher 抽象 (per-IDE) | `src/services/dispatch/sub-agent-dispatcher.ts` | Encapsulates the IDE-private tool name (claude-code: `Task`, trae: UNVERIFIED placeholder) and arg shape | CLI (called by the CLI) |
|
|
24
|
+
|
|
25
|
+
This is the **inverse** of the prior shape: SKILL.md used to hardcode
|
|
26
|
+
`Task(subagent_type="general-purpose", ...)`, which made peaks-cli
|
|
27
|
+
depend on Claude Code's specific tool name. Adding a new IDE meant
|
|
28
|
+
editing every SKILL.md that mentioned sub-agents. With the new shape,
|
|
29
|
+
the only per-IDE thing in the dispatch chain is the dispatcher — SKILL.md
|
|
30
|
+
stays IDE-agnostic.
|
|
31
|
+
|
|
32
|
+
> **Red line**: do not invoke `peaks sub-agent dispatch` from your own
|
|
33
|
+
> shell. The CLI is a primitive the LLM composes. Users do not need it.
|
|
34
|
+
|
|
35
|
+
## Dispatch contract
|
|
36
|
+
|
|
37
|
+
**Command**:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
peaks sub-agent dispatch <role> --prompt <text> [--request-id <rid>] [--session-id <sid>] [--project <repo>] [--batch-id <uuid>] --json
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Envelope** (AC-8):
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"ok": true,
|
|
48
|
+
"command": "sub-agent.dispatch",
|
|
49
|
+
"data": {
|
|
50
|
+
"role": "rd",
|
|
51
|
+
"ide": "claude-code",
|
|
52
|
+
"prompt": "<complete prompt the LLM should pass through>",
|
|
53
|
+
"toolCall": {
|
|
54
|
+
"name": "Task",
|
|
55
|
+
"args": {
|
|
56
|
+
"subagent_type": "general-purpose",
|
|
57
|
+
"description": "rd for rid=002-2026-06-07-...",
|
|
58
|
+
"prompt": "..."
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"dispatchRecordPath": ".peaks/_sub_agents/2026-06-06-session-5b1095/dispatch-002-2026-06-07-...-...json",
|
|
62
|
+
"batchId": "<uuid>",
|
|
63
|
+
"dispatchedInBatch": 3
|
|
64
|
+
},
|
|
65
|
+
"warnings": [],
|
|
66
|
+
"nextActions": [
|
|
67
|
+
"Tool call is dry-run; LLM must execute the tool to actually dispatch the sub-agent.",
|
|
68
|
+
"After dispatching, the sub-agent should call `peaks sub-agent heartbeat --record <dispatchRecordPath>` periodically."
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**LLM side**: read `data.toolCall` (the `{name, args}` descriptor), look
|
|
74
|
+
up the tool by `name` in the current environment, and invoke it with
|
|
75
|
+
`args`. The CLI does not spawn anything. The IDE (Claude Code, Trae,
|
|
76
|
+
etc.) is the one that actually runs the sub-agent.
|
|
77
|
+
|
|
78
|
+
**Side effect**: the CLI writes a dispatch record to
|
|
79
|
+
`.peaks/_sub_agents/<sid>/dispatch-<rid>-<ts>.json` (R-2 path-guarded).
|
|
80
|
+
The record starts with `heartbeats: []`, `lastBeatAt: null`, `status: 'queued'`
|
|
81
|
+
and is updated by the heartbeat flow (§G6 below).
|
|
82
|
+
|
|
83
|
+
## Role model
|
|
84
|
+
|
|
85
|
+
`SubAgentRole` is a free-form string. The CLI **does not** enforce a
|
|
86
|
+
hard whitelist. Recommended roles:
|
|
87
|
+
|
|
88
|
+
- Top-level: `rd` | `qa` | `ui` | `txt` | `general-purpose`
|
|
89
|
+
- QA sub-roles: `qa-business` | `qa-perf` | `qa-security`
|
|
90
|
+
- Business sub-divisions: `qa-business-api` | `qa-business-frontend` |
|
|
91
|
+
`qa-business-regression` | ... (≤ 2 levels deep per RL-4)
|
|
92
|
+
- Promotable Worker (architecture预留, slice #009 不实际提升): `prd-business` |
|
|
93
|
+
`prd-technical` | `prd-ux` | `ui-visual` | `ui-flow` | `ui-component`
|
|
94
|
+
|
|
95
|
+
The only hard validation is: non-empty, ≤ 256 chars, no control
|
|
96
|
+
characters. Any other string is a convention, not a contract.
|
|
97
|
+
|
|
98
|
+
## Per-IDE dispatchers (G1)
|
|
99
|
+
|
|
100
|
+
| IDE | Tool name | Args shape | Status |
|
|
101
|
+
|---|---|---|---|
|
|
102
|
+
| `claude-code` | `Task` | `{subagent_type: "general-purpose", description, prompt}` | verified |
|
|
103
|
+
| `trae` | `Task` | byte-identical to claude-code by design | UNVERIFIED — pending real Trae dogfood |
|
|
104
|
+
| `null` (no IDE detected) | — | throws `IDE_NOT_SUPPORTED` | fallback |
|
|
105
|
+
|
|
106
|
+
Adding a new IDE means:
|
|
107
|
+
|
|
108
|
+
1. Add a new adapter to `src/services/ide/adapters/<id>-adapter.ts`.
|
|
109
|
+
2. Fill in `subAgentDispatcher: <yourDispatcher>` (implements
|
|
110
|
+
`SubAgentDispatcher`).
|
|
111
|
+
3. Register the adapter in `ide-registry.ts`.
|
|
112
|
+
|
|
113
|
+
SKILL.md and existing dispatcher implementations are untouched.
|
|
114
|
+
|
|
115
|
+
## G6 — heartbeat + dynamic progress (RL-13..RL-16)
|
|
116
|
+
|
|
117
|
+
Sub-agents run for 30 s to 2 min. During that wait, the LLM platform
|
|
118
|
+
provides no progress signal to the Dispatcher. Without a heartbeat
|
|
119
|
+
channel, the user sees a frozen terminal and reasonably assumes the
|
|
120
|
+
system is dead. G6 is the rule that says: **no**.
|
|
121
|
+
|
|
122
|
+
### The three-layer contract
|
|
123
|
+
|
|
124
|
+
| Layer | Who | What | Cadence |
|
|
125
|
+
|---|---|---|---|
|
|
126
|
+
| **Sub-agent writes** | The sub-agent itself | Calls `peaks sub-agent heartbeat --record <dispatchRecordPath> --status <state> --progress <pct> --note "<text>"` to append a heartbeat | 30 s default; SKILL.md can override via `heartbeatIntervalSec: 15` |
|
|
127
|
+
| **Dispatcher reads** | peaks-solo main loop, during the batch-sync wait | In-process async poller (`BatchHeartbeatPoller`) reads `heartbeats[]` + `lastBeatAt` from each record, emits a single-line status per G6.5 | 10 s (offset from 30 s to avoid jitter) |
|
|
128
|
+
| **User / CLI reads** | Anyone, anytime | `peaks sub-agent list --session-id <sid> --json` (G5 RL-10, future slice) | manual |
|
|
129
|
+
|
|
130
|
+
### Sub-agent prompt template (heartbeat-aware)
|
|
131
|
+
|
|
132
|
+
Every sub-agent prompt dispatched via `peaks sub-agent dispatch` should
|
|
133
|
+
include the heartbeat instruction so the LLM knows when and how to
|
|
134
|
+
report progress. The recommended paragraph (auto-generated by the CLI
|
|
135
|
+
and the SKILL.md heart of each Dispatcher) is:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
While running, call `peaks sub-agent heartbeat --record <dispatchRecordPath>
|
|
139
|
+
--status <state> --progress <pct> --note "<text>"` at least every 30 seconds
|
|
140
|
+
(the Dispatcher expects 30s cadence). On completion call
|
|
141
|
+
`--status done --progress 100 --note "completed"`. On failure,
|
|
142
|
+
`--status failed`. Do not skip heartbeats; the parent Dispatcher uses them
|
|
143
|
+
to keep the user informed during the wait.
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`heartbeatIntervalSec` is overridable per SKILL.md (5..600). Default 30.
|
|
147
|
+
|
|
148
|
+
### Status line shape (G6.5)
|
|
149
|
+
|
|
150
|
+
Single line, 80-120 chars:
|
|
151
|
+
|
|
152
|
+
```
|
|
153
|
+
[peaks-solo] swarm 3/3 running | rd-planning 45% (12s ago) | qa-test-cases 30% (5s ago) | ui-design 20% (2s ago)
|
|
154
|
+
[peaks-solo] swarm 3/3 running | rd-planning 70% (8s ago) | qa-test-cases 50% (3s ago) | ui-design 30% (6s ago)
|
|
155
|
+
...
|
|
156
|
+
[peaks-solo] swarm 3/3 done
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If a sub-agent has not written a heartbeat in 5 minutes, the poller
|
|
160
|
+
appends `⚠ stale` to that sub-agent's segment and marks
|
|
161
|
+
`status: 'stale'` on the record. **It does not cancel, kill, or send
|
|
162
|
+
SIGTERM** (RL-15). Stale is a user-visible warning, not a failure.
|
|
163
|
+
The user decides.
|
|
164
|
+
|
|
165
|
+
### Truncation (RL-16)
|
|
166
|
+
|
|
167
|
+
`heartbeats[]` is append-only for audit, but capped at 100 entries.
|
|
168
|
+
Past 100, the oldest are dropped and `truncated: true` is set. The
|
|
169
|
+
record JSON can otherwise balloon to MB on long-running sub-agents.
|
|
170
|
+
100 is the LLM-friendly limit — stale heartbeats are not informative
|
|
171
|
+
once the poller has read them.
|
|
172
|
+
|
|
173
|
+
### Acceptance criteria covered
|
|
174
|
+
|
|
175
|
+
- AC-33 `peaks sub-agent heartbeat` CLI primitive (implemented)
|
|
176
|
+
- AC-34 Dispatch record schema upgrade (`heartbeats[]` + `lastBeatAt` + `status` aggregate, backward-compat defaults)
|
|
177
|
+
- AC-35 peaks-solo main loop batch-sync poller (10 s cadence, 5 min stale)
|
|
178
|
+
- AC-36 SKILL.md fan-out sections include heartbeat instruction
|
|
179
|
+
- AC-37 G6 E2E dogfood (3 heartbeats, 101 → truncated, stale simulation)
|
|
180
|
+
|
|
181
|
+
## Acceptance criteria (overall G1-G6)
|
|
182
|
+
|
|
183
|
+
- AC-1..AC-5: dispatcher interface + 3 adapter impls (`claudeCodeSubAgentDispatcher`, `traeSubAgentDispatcher`, `nullSubAgentDispatcher`)
|
|
184
|
+
- AC-6: dispatcher unit tests
|
|
185
|
+
- AC-7..AC-9: dispatch CLI signature + envelope + steps
|
|
186
|
+
- AC-10: dispatch CLI unit tests
|
|
187
|
+
- AC-11 / AC-11b / AC-11c: E2E dogfood on the live repo
|
|
188
|
+
- AC-12: `peaks --help` byte-level delta is `+1` line (`sub-agent <cmd>`)
|
|
189
|
+
- AC-13..AC-19: SKILL.md fan-out rewrites (peaks-solo 5 spots, peaks-rd 2, peaks-qa 3-way, peaks-ui 1; this reference is the canonical contract)
|
|
190
|
+
- AC-22..AC-24: R-2 path guard, prompt size limit, atomic write
|
|
191
|
+
- AC-25..AC-32: G5 resource lifecycle (RL-1 batch counter, dispatch record schema, reducer dispose, slice archive, cancel dispose)
|
|
192
|
+
- AC-33..AC-37: G6 heartbeat CLI, schema, poller, status line, E2E
|
|
193
|
+
|
|
194
|
+
## How to apply
|
|
195
|
+
|
|
196
|
+
When writing a SKILL.md that fans out sub-agents:
|
|
197
|
+
|
|
198
|
+
1. Use `peaks sub-agent dispatch <role>` (never `Task(...)`).
|
|
199
|
+
2. Issue all dispatches in a single message; the LLM will fire all
|
|
200
|
+
returned toolCalls in parallel.
|
|
201
|
+
3. Pass `--request-id` and `--session-id` (or omit and let the CLI
|
|
202
|
+
resolve the active session).
|
|
203
|
+
4. The sub-agent prompt **must** include the heartbeat instruction
|
|
204
|
+
(30 s cadence; override via `heartbeatIntervalSec` if needed).
|
|
205
|
+
5. After the fan-out returns, the Dispatcher reducer reads the
|
|
206
|
+
dispatch record + the artifacts the sub-agents wrote, marks
|
|
207
|
+
`disposed: true` on each record, and advances the state machine.
|
|
208
|
+
6. The poller handles the 5-min stale case as a warning, never as a
|
|
209
|
+
failure. The user is the one who decides to cancel.
|
|
210
|
+
|
|
211
|
+
## Cross-reference
|
|
212
|
+
|
|
213
|
+
- PRD #009 G1-G6 (this slice's source of truth)
|
|
214
|
+
- RD request #009 in-scope files (implementation contract)
|
|
215
|
+
- `.peaks/memory/sub-agent-resource-lifecycle-red-line.md` (G5 red line)
|
|
216
|
+
- `.peaks/memory/sub-agent-heartbeat-progress-red-line.md` (G6 red line)
|
|
217
|
+
- `skills/peaks-solo/references/swarm-dispatch-contract.md` (predecessor contract)
|
|
218
|
+
- `skills/peaks-qa/references/qa-fanout-contract.md` (QA-specific fan-out)
|
|
@@ -6,41 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
The previous "Swarm" used `Skill(skill="peaks-rd")` calls. That is **single-stack and blocking** — there is no concurrency. Three sequential `Skill` calls run in order on the same main loop, not in parallel. The "parallel Agent calls" wording in the old SKILL.md was a v1.x illusion.
|
|
8
8
|
|
|
9
|
-
This contract
|
|
10
|
-
|
|
11
|
-
## 2. When to swarm (decision)
|
|
12
|
-
|
|
13
|
-
Solo runs the swarm only after `peaks request show <rid> --role prd` is in state `confirmed-by-user` or `handed-off`. Before that, there is nothing for the sub-agents to derive from.
|
|
14
|
-
|
|
15
|
-
Solo computes the **swarm plan** from three signals (see "Swarm gate" in the main SKILL.md):
|
|
16
|
-
|
|
17
|
-
1. `--type` from `peaks request init` (already on the PRD artefact).
|
|
18
|
-
2. `frontendOnly` from `.peaks/<session-id>/rd/project-scan.md` `## Project mode`.
|
|
19
|
-
3. Frontend keyword scan over the PRD body.
|
|
20
|
-
|
|
21
|
-
The plan is written to `.peaks/<session-id>/sc/swarm-plan.json` before any Task call, so SC and TXT can audit what was launched. Solo updates `.peaks/.active-skill.json` to `gate=swarm-fan-out` at this point.
|
|
22
|
-
|
|
23
|
-
| `--type` | Frontend signal | Plan |
|
|
24
|
-
|---|---|---|
|
|
25
|
-
| `feature` / `refactor` / `bugfix` | keyword hit OR `frontendOnly=true` | `[ui, rd-planning, qa-test-cases]` |
|
|
26
|
-
| `feature` / `refactor` / `bugfix` | no keyword hit AND `frontendOnly=false` | `[rd-planning, qa-test-cases]` |
|
|
27
|
-
| `config` / `docs` / `chore` | (any) | `[]` (swarm skipped, recorded in plan) |
|
|
28
|
-
|
|
29
|
-
In `assisted` and `strict` modes, Solo replaces signal (3) with a three-option `AskUserQuestion` (see "Mode-driven fan-out shape" in the main SKILL.md) and uses the user's choice as the plan.
|
|
30
|
-
|
|
31
|
-
## 3. Sub-agent invocation template
|
|
32
|
-
|
|
33
|
-
Solo emits one Task call per sub-agent in the plan, all in the same message:
|
|
34
|
-
|
|
35
|
-
```js
|
|
36
|
-
Task({
|
|
37
|
-
subagent_type: "general-purpose",
|
|
38
|
-
description: "<role> for rid=<rid>",
|
|
39
|
-
prompt: <see role-specific sections below>
|
|
40
|
-
})
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### 3.1 Common prompt header (all sub-agents)
|
|
9
|
+
This contract (slice #009) replaces the IDE-private sub-agent literal with the IDE-agnostic primitive `peaks sub-agent dispatch <role>`. The CLI returns a JSON `data.toolCall` descriptor; the LLM executes that tool in its own environment. SKILL.md is now free of IDE-private tool names and the same prompt works on every registered IDE. Real concurrent fan-out is achieved by Solo launching N dispatch calls in a single message and the platform scheduling the returned toolCalls concurrently.
|
|
44
10
|
|
|
45
11
|
```
|
|
46
12
|
You are a sub-agent invoked by peaks-solo. You are NOT the main Claude session.
|
|
@@ -158,7 +124,7 @@ no acceptance surface to plan tests for.
|
|
|
158
124
|
|
|
159
125
|
## 4. Reducer (Solo side)
|
|
160
126
|
|
|
161
|
-
After all sub-agent
|
|
127
|
+
After all sub-agent dispatch calls return and the LLM has invoked the toolCalls, Solo:
|
|
162
128
|
|
|
163
129
|
1. Restores presence ONCE (not per-agent):
|
|
164
130
|
```
|
|
@@ -176,7 +142,7 @@ If a sub-agent is misbehaving and writes to `.peaks/.active-skill.json` anyway,
|
|
|
176
142
|
|
|
177
143
|
## 6. Why not a `peaks-swarm` skill?
|
|
178
144
|
|
|
179
|
-
A skill cannot itself trigger sub-agents — the Skill tool runs in the main loop. The orchestrator (peaks-solo) has to be in the main loop and has to
|
|
145
|
+
A skill cannot itself trigger sub-agents — the Skill tool runs in the main loop. The orchestrator (peaks-solo) has to be in the main loop and has to call `peaks sub-agent dispatch` directly. Putting swarm logic into a separate skill would either re-introduce the "single-stack blocking" anti-pattern or require a custom slash command that bypasses the Skill tool. The current design keeps swarm control in peaks-solo where it belongs.
|
|
180
146
|
|
|
181
147
|
## 7. Tests / dogfood
|
|
182
148
|
|
|
@@ -15,6 +15,8 @@ Before any analysis or tool call, immediately run:
|
|
|
15
15
|
peaks skill presence:set peaks-txt --project <repo> --mode <mode> --gate startup
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
**When invoked as a sub-agent (peaks-solo swarm):** do NOT call `peaks skill presence:set` (Solo owns the active-skill marker) and do NOT spawn your own session. Use the parent's sid — read `.peaks/_runtime/session.json` or pass `--session-id <parent-sid>` to any session-creating CLI. The new `peaks session info --active` reads the canonical binding for you.
|
|
19
|
+
|
|
18
20
|
On the first presence:set in a project, ensure the out-of-band status bar is installed so the user can see at a glance that Peaks is orchestrating — it renders the active skill in Claude Code's terminal status line, independent of model output:
|
|
19
21
|
|
|
20
22
|
```bash
|
|
@@ -248,3 +250,20 @@ find .peaks/<id>/txt/ -type f | sort
|
|
|
248
250
|
Do not choose the refactor plan or install runtime resources. Use artifacts produced by other skills and CLI reports.
|
|
249
251
|
|
|
250
252
|
Reference: `references/context-capsule.md`.
|
|
253
|
+
|
|
254
|
+
## Sub-agent context governance (G8 + G9 — slice #010, TXT reducer view)
|
|
255
|
+
|
|
256
|
+
> peaks-txt is the TXT reducer; it sees the metadata-only view from G7 + the share entries from G8. The TXT handoff summarizes the slice at the slice-close gate. Detailed: `skills/peaks-solo/references/context-governance.md`.
|
|
257
|
+
|
|
258
|
+
### G8 — TXT reducer sees share entries on completion
|
|
259
|
+
|
|
260
|
+
When TXT reduces a batch, it consumes:
|
|
261
|
+
- The dispatch record's `artifactMetas[]` (G7.4.d) — paths + sizes + sha256s + summaries.
|
|
262
|
+
- The shared channel's entries (G8) — sibling sub-agent status (`<role>.completed`, `<role>.found-blocker`).
|
|
263
|
+
|
|
264
|
+
The TXT handoff summarizes the slice by listing the artifact metas + the share entries that arrived during the batch. Both are dispatcher-mediated (NOT inlined from the sub-agent prompt).
|
|
265
|
+
|
|
266
|
+
### G9 — TXT prompt size self-check
|
|
267
|
+
|
|
268
|
+
Same G9 threshold table. TXT handoff messages can grow large when the slice has many batches; use `--use-headroom` proactively for handoff prompts > 50%.
|
|
269
|
+
|
package/skills/peaks-ui/SKILL.md
CHANGED
|
@@ -28,8 +28,9 @@ UI's headed-browser inspection hits the same auth walls. The flow is identical t
|
|
|
28
28
|
|
|
29
29
|
## Sub-agent dispatch (when launched by peaks-solo swarm)
|
|
30
30
|
|
|
31
|
-
When this skill is launched as a sub-agent via `
|
|
31
|
+
When this skill is launched as a sub-agent via `peaks sub-agent dispatch <role>` (then the LLM executes the returned toolCall) from `peaks-solo`, the following sections of THIS skill are **suspended** for the sub-agent run:
|
|
32
32
|
|
|
33
|
+
- **Session id** — use the parent's sid (read `.peaks/_runtime/session.json` or pass `--session-id <parent-sid>` to any session-creating CLI). Do NOT spawn your own session. The new `peaks session info --active` reads the canonical binding for you.
|
|
33
34
|
- **Skill presence (MANDATORY first action)** — do NOT call `peaks skill presence:set peaks-ui`. The sub-agent must not overwrite `.peaks/.active-skill.json`; the main Solo loop owns that file. If you need to mark your own state, write a marker file at `.peaks/<session-id>/system/sub-agent-ui.json` and only that.
|
|
34
35
|
- **Workspace initialization** — Solo has already run `peaks workspace init` before fan-out. Do not re-run it.
|
|
35
36
|
- **Mode selection** — Solo has already chosen the mode.
|
|
@@ -354,3 +355,29 @@ Use `peaks capabilities --source access-repo --json` and `peaks capabilities --s
|
|
|
354
355
|
Do not own backend architecture, non-UI implementation, runtime hook installation, or final QA acceptance.
|
|
355
356
|
|
|
356
357
|
Reference: `references/workflow.md`.
|
|
358
|
+
|
|
359
|
+
## Sub-agent context governance (G7 + G7.7 + G8 + G9 — slice #010)
|
|
360
|
+
|
|
361
|
+
> UI sub-agents follow the same G7 metadata-only + G8.6 share protocol. UI artifacts (design drafts, component scaffolds) can be large binary-ish files; the 1MB artifact size limit (G7.3) applies. Detailed: `skills/peaks-solo/references/context-governance.md`.
|
|
362
|
+
|
|
363
|
+
### G7 — UI sub-agent protocol
|
|
364
|
+
|
|
365
|
+
1. Write design draft / component scaffold to `.peaks/_sub_agents/<sid>/artifacts/<rid>-ui-001.md` (path convention mandatory; size ≤ 1MB).
|
|
366
|
+
2. Call `peaks sub-agent dispatch --write-artifact <path>` to register ArtifactMeta.
|
|
367
|
+
3. Main LLM sees metadata-only view (~200 chars/UI sub-agent).
|
|
368
|
+
|
|
369
|
+
### G8.6 — UI sub-agent prompt template
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
You are sub-agent role ui, batch <batchId>.
|
|
373
|
+
|
|
374
|
+
PROTOCOL (mandatory):
|
|
375
|
+
1. On start: `peaks sub-agent shared-read --batch <batchId> --json`.
|
|
376
|
+
2. While running: write share entry `peaks sub-agent share --key "ui.design-blocker" --value {"reason": "..."}`.
|
|
377
|
+
3. On completion: `peaks sub-agent share --key "ui.completed" --value <artifact-meta>` BEFORE final heartbeat (RL-23).
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### G9 — UI prompt size self-check
|
|
381
|
+
|
|
382
|
+
Same as RD/QA. UI design descriptions can grow large; use `--use-headroom` proactively.
|
|
383
|
+
|