pi-squad 0.1.0 → 0.5.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/README.md +288 -75
- package/package.json +7 -3
- package/src/agent-pool.ts +10 -1
- package/src/index.ts +563 -322
- package/src/panel/message-view.ts +140 -122
- package/src/panel/squad-panel.ts +94 -148
- package/src/panel/squad-widget.ts +192 -0
- package/src/panel/task-list.ts +38 -28
- package/src/planner.ts +1 -1
- package/src/protocol.ts +37 -0
- package/src/scheduler.ts +216 -5
- package/src/skills/supervisor/SKILL.md +111 -0
- package/src/skills/verification/SKILL.md +32 -0
- package/src/store.ts +29 -1
- package/src/types.ts +11 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pi-squad
|
|
2
2
|
|
|
3
|
-
Multi-agent collaboration extension for [pi](https://github.com/badlogic/pi-mono). Decomposes complex tasks into subtasks, assigns specialist agents, manages dependencies,
|
|
3
|
+
Multi-agent collaboration extension for [pi](https://github.com/badlogic/pi-mono). Decomposes complex tasks into subtasks, assigns specialist agents, manages dependencies, runs them in parallel with automatic QA rework loops — all with a live TUI widget, overlay panel, and slash commands.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -12,7 +12,7 @@ pi install npm:pi-squad
|
|
|
12
12
|
ln -sf /path/to/pi-squad/src ~/.pi/agent/extensions/squad
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
Pi auto-discovers extensions on startup. No build step.
|
|
15
|
+
Pi auto-discovers extensions on startup. No build step required.
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
@@ -22,7 +22,7 @@ Ask pi to do something complex. It calls the `squad` tool automatically:
|
|
|
22
22
|
> Build a REST API with authentication, tests, and documentation
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
Or be explicit:
|
|
25
|
+
The planner agent reads your codebase and creates a task breakdown automatically. Or be explicit:
|
|
26
26
|
|
|
27
27
|
```
|
|
28
28
|
> Use squad: goal="Build task API", tasks=[
|
|
@@ -34,35 +34,44 @@ Or be explicit:
|
|
|
34
34
|
|
|
35
35
|
### What Happens
|
|
36
36
|
|
|
37
|
-
1.
|
|
37
|
+
1. Planner analyzes the codebase and creates tasks (or uses your predefined tasks)
|
|
38
38
|
2. A **live widget** appears above the editor showing task status
|
|
39
|
-
3. Agents spawn as separate pi processes, work in parallel where
|
|
40
|
-
4.
|
|
39
|
+
3. Agents spawn as separate pi processes, work in parallel where dependencies allow
|
|
40
|
+
4. QA agents can trigger **automatic rework loops** when they find bugs
|
|
41
|
+
5. When complete, pi reports the summary — notifications don't pollute message history
|
|
42
|
+
6. Multiple squads can run concurrently across different projects
|
|
41
43
|
|
|
42
44
|
## User Interface
|
|
43
45
|
|
|
44
46
|
### Widget (above editor)
|
|
45
47
|
|
|
46
|
-
Always visible when a squad is active.
|
|
48
|
+
Always visible when a squad is active. Debounced updates with cache key to avoid flicker.
|
|
47
49
|
|
|
48
50
|
```
|
|
49
|
-
⏳ squad Build task API
|
|
50
|
-
✓ api (backend) Created CRUD REST API with validation
|
|
51
|
-
⏳ tests (qa) → bash npm test
|
|
51
|
+
⏳ squad Build task API 2/3 $0.58 3m12s ^q detail · /squad msg
|
|
52
|
+
✓ api (backend) 2m12s Created CRUD REST API with validation
|
|
53
|
+
⏳ tests (qa) 45s → bash npm test
|
|
52
54
|
◻ docs (docs) ← api
|
|
53
55
|
```
|
|
54
56
|
|
|
57
|
+
Features:
|
|
58
|
+
- Per-task elapsed time (warning color after 3 minutes)
|
|
59
|
+
- Live tool call preview for running tasks
|
|
60
|
+
- Stale detection — shows `⏳ idle` when agent has no output for 2+ minutes
|
|
61
|
+
- Responsive — caps visible tasks on small terminals, shows `+N more` overflow
|
|
62
|
+
- Completion duration for finished tasks
|
|
63
|
+
|
|
55
64
|
### Status Bar (footer)
|
|
56
65
|
|
|
57
66
|
```
|
|
58
|
-
⏳ squad
|
|
67
|
+
⏳ squad 2/3 $0.58
|
|
59
68
|
```
|
|
60
69
|
|
|
61
70
|
### Panel (Ctrl+Q)
|
|
62
71
|
|
|
63
|
-
|
|
72
|
+
Centered overlay panel with proper lifecycle management. Press `Ctrl+Q` to open/close.
|
|
64
73
|
|
|
65
|
-
**Task list
|
|
74
|
+
**Task list** with sticky summary at bottom:
|
|
66
75
|
```
|
|
67
76
|
╭─ squad: Build task API ─────────────────────╮
|
|
68
77
|
│ ▸ ✓ api (backend) 2m12s │
|
|
@@ -72,23 +81,26 @@ Side panel on wide screens, centered overlay on narrow screens. Press `Ctrl+Q` t
|
|
|
72
81
|
│ ── tests (live) ───────────────────── │
|
|
73
82
|
│ → bash npm test │
|
|
74
83
|
│ │
|
|
75
|
-
│
|
|
84
|
+
│ 2/3 · $0.58 · 3m │
|
|
76
85
|
├──────────────────────────────────────────────┤
|
|
77
|
-
│ ↑↓ nav ⏎ msgs m send p pause ^q
|
|
86
|
+
│ ↑↓ nav ⏎ msgs m send p pause ^q close │
|
|
78
87
|
╰──────────────────────────────────────────────╯
|
|
79
88
|
```
|
|
80
89
|
|
|
81
|
-
**Message view** (Enter on a task):
|
|
90
|
+
**Message view** (Enter on a task) — long text wraps instead of truncating:
|
|
82
91
|
```
|
|
83
92
|
╭─ tests · qa ⏳ ─────────────────────────────╮
|
|
84
93
|
│ 10:03 qa │
|
|
85
|
-
│ Starting test implementation
|
|
94
|
+
│ Starting test implementation. Will cover │
|
|
95
|
+
│ all CRUD endpoints, validation, and │
|
|
96
|
+
│ edge cases for empty input. │
|
|
86
97
|
│ 10:04 qa │
|
|
87
98
|
│ → write src/tasks.test.js │
|
|
88
99
|
│ 10:05 YOU │
|
|
89
100
|
│ Also test edge cases for empty input │
|
|
101
|
+
│ ─ 65% ─ 24 msgs ─ ↑↓ scroll │
|
|
90
102
|
├──────────────────────────────────────────────┤
|
|
91
|
-
│ ↑↓ scroll m send esc back ^q
|
|
103
|
+
│ ↑↓ scroll m send esc back ^q close │
|
|
92
104
|
╰──────────────────────────────────────────────╯
|
|
93
105
|
```
|
|
94
106
|
|
|
@@ -99,37 +111,111 @@ Side panel on wide screens, centered overlay on narrow screens. Press `Ctrl+Q` t
|
|
|
99
111
|
| `/squad` or `/squad select` | Pick a squad to view (interactive selector) |
|
|
100
112
|
| `/squad list` | List squads for current project |
|
|
101
113
|
| `/squad all` | List all squads across all projects |
|
|
114
|
+
| `/squad agents` | List, view, edit, enable/disable agents |
|
|
115
|
+
| `/squad agents <name>` | Quick view of a specific agent |
|
|
102
116
|
| `/squad msg [agent] text` | Send message to a running agent |
|
|
103
|
-
| `/squad widget` | Toggle live widget |
|
|
117
|
+
| `/squad widget` | Toggle live widget on/off |
|
|
104
118
|
| `/squad panel` | Toggle overlay panel |
|
|
105
119
|
| `/squad cancel` | Cancel running squad |
|
|
106
120
|
| `/squad clear` | Dismiss widget, deactivate view |
|
|
121
|
+
| `/squad cleanup` | Delete squad data (select one or all) |
|
|
122
|
+
| `/squad cleanup all` | Delete all squad data |
|
|
123
|
+
| `/squad enable` | Enable pi-squad (tools, widget, system prompt) |
|
|
124
|
+
| `/squad disable` | Disable pi-squad completely |
|
|
107
125
|
|
|
108
126
|
## Keyboard Shortcuts
|
|
109
127
|
|
|
110
128
|
| Key | Context | Action |
|
|
111
129
|
|---|---|---|
|
|
112
|
-
| `Ctrl+Q` |
|
|
113
|
-
| `
|
|
114
|
-
| `Ctrl+Q` | Panel focused (narrow) | Hide panel |
|
|
115
|
-
| `↑↓` | Panel | Navigate tasks / scroll messages |
|
|
130
|
+
| `Ctrl+Q` | Anywhere | Toggle squad panel overlay |
|
|
131
|
+
| `↑↓` or `jk` | Panel | Navigate tasks / scroll messages |
|
|
116
132
|
| `Enter` | Panel task list | View task messages |
|
|
117
133
|
| `Esc` | Panel message view | Back to task list |
|
|
118
134
|
| `m` | Panel | Send message to selected task's agent |
|
|
119
135
|
| `p` | Panel task list | Pause/resume task |
|
|
120
136
|
| `x` | Panel task list | Cancel task |
|
|
121
|
-
| `q` | Panel task list |
|
|
137
|
+
| `q` | Panel task list | Close panel |
|
|
122
138
|
|
|
123
139
|
## Tools (LLM-callable)
|
|
124
140
|
|
|
125
141
|
| Tool | Description |
|
|
126
142
|
|---|---|
|
|
127
143
|
| `squad` | Start a squad (non-blocking, returns immediately) |
|
|
128
|
-
| `squad_status` | Check progress,
|
|
144
|
+
| `squad_status` | Check progress, costs, task states |
|
|
129
145
|
| `squad_message` | Send message to a running agent via `steer()` |
|
|
130
|
-
| `squad_modify` | Add/
|
|
146
|
+
| `squad_modify` | Add/cancel/pause/resume tasks, or cancel/resume entire squad |
|
|
147
|
+
|
|
148
|
+
The main pi agent sees squad state in its system prompt automatically (`<squad_status>` block) and can relay messages, add tasks, or check status on your behalf. Squad notifications use `sendMessage({ display: true })` so they don't pollute the LLM's message history.
|
|
149
|
+
|
|
150
|
+
## Multiple Concurrent Squads
|
|
151
|
+
|
|
152
|
+
Multiple squads can run in parallel from the same pi session. Each squad has its own scheduler, agent pool, and disk state.
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
> Build the auth API → starts squad-1
|
|
156
|
+
> Build the dashboard UI → starts squad-2 (runs in parallel)
|
|
157
|
+
|
|
158
|
+
/squad list → see both, select which to view
|
|
159
|
+
/squad select → switch widget/panel focus
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
All squads run independently in the background. The widget/panel shows whichever squad you're focused on.
|
|
163
|
+
|
|
164
|
+
## QA Rework Loop
|
|
165
|
+
|
|
166
|
+
When a QA agent outputs `## Verdict: FAIL`, the scheduler automatically:
|
|
167
|
+
|
|
168
|
+
1. **Parses** the failure details from QA output
|
|
169
|
+
2. **Creates a rework task** for the original agent with QA feedback injected into its system prompt
|
|
170
|
+
3. **Creates a retest task** for QA, blocked until the rework completes
|
|
171
|
+
4. After fix, QA re-tests. If still failing, loops up to `maxRetries` (default: 2)
|
|
172
|
+
5. If retry limit exceeded, **escalates** to the main agent for human decision
|
|
173
|
+
|
|
174
|
+
### Example flow
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
auth (backend) ✓
|
|
178
|
+
→ qa-auth (qa) ✓ — found race condition bug
|
|
179
|
+
→ auth-fix-1 (backend) ✓ — fixed it [auto-created]
|
|
180
|
+
→ qa-auth-retest-1 (qa) ✓ — retested, found another issue
|
|
181
|
+
→ auth-fix-2 (backend) ✓ — fixed again [auto-created]
|
|
182
|
+
→ qa-auth-retest-2 (qa) ✓ — all tests pass ✓
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### What the rework agent sees
|
|
186
|
+
|
|
187
|
+
The rework agent's system prompt includes:
|
|
188
|
+
- Original task output (what was built)
|
|
189
|
+
- QA feedback (what failed, with specific issues)
|
|
190
|
+
- Instructions to make targeted fixes, not rewrite everything
|
|
131
191
|
|
|
132
|
-
|
|
192
|
+
### QA verdict format
|
|
193
|
+
|
|
194
|
+
QA agents should end their output with a structured verdict:
|
|
195
|
+
|
|
196
|
+
```markdown
|
|
197
|
+
## Verdict: PASS
|
|
198
|
+
All 42 tests passing. No issues found.
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
```markdown
|
|
202
|
+
## Verdict: FAIL
|
|
203
|
+
|
|
204
|
+
## Issues
|
|
205
|
+
1. **[src/auth.ts:45]** JWT expiry not enforced
|
|
206
|
+
- Expected: 401 for expired tokens
|
|
207
|
+
- Got: 200 (token accepted)
|
|
208
|
+
2. **[src/routes.ts:23]** Missing rate limit on /login
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Configuration
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
config: {
|
|
215
|
+
maxConcurrency: 3, // parallel agents (default: 2)
|
|
216
|
+
maxRetries: 2, // rework attempts before escalation (default: 2)
|
|
217
|
+
}
|
|
218
|
+
```
|
|
133
219
|
|
|
134
220
|
## Sending Messages to Agents
|
|
135
221
|
|
|
@@ -141,30 +227,50 @@ Three ways:
|
|
|
141
227
|
/squad msg backend Use postgres instead of SQLite
|
|
142
228
|
```
|
|
143
229
|
|
|
144
|
-
2. **`m` key** — press in the panel
|
|
230
|
+
2. **`m` key** — press in the panel, opens input dialog
|
|
145
231
|
|
|
146
232
|
3. **Natural chat** — tell pi, it relays automatically
|
|
147
233
|
```
|
|
148
234
|
> Tell the backend agent to use argon2 for password hashing
|
|
149
235
|
```
|
|
150
236
|
|
|
237
|
+
Messages are delivered in real-time via RPC `steer()` if the agent is running, or queued for delivery when the agent spawns.
|
|
238
|
+
|
|
151
239
|
## Agents
|
|
152
240
|
|
|
153
|
-
11
|
|
241
|
+
### 11 Bundled Agents
|
|
154
242
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
|
158
|
-
|
|
159
|
-
| **
|
|
160
|
-
| **
|
|
161
|
-
| **
|
|
162
|
-
| **
|
|
163
|
-
| **
|
|
164
|
-
| **
|
|
165
|
-
| **
|
|
166
|
-
| **
|
|
167
|
-
| **
|
|
243
|
+
On first run, copied to `~/.pi/squad/agents/` for editing.
|
|
244
|
+
|
|
245
|
+
| Agent | Specialty | Tags |
|
|
246
|
+
|---|---|---|
|
|
247
|
+
| **planner** | Task breakdown and planning | planning, architecture |
|
|
248
|
+
| **fullstack** | General-purpose coding | general, coding |
|
|
249
|
+
| **architect** | System design, architecture | architecture, design |
|
|
250
|
+
| **backend** | APIs, databases, server-side | api, server, database |
|
|
251
|
+
| **frontend** | UI/UX, React, CSS | react, ui, css |
|
|
252
|
+
| **debugger** | Root cause analysis | debugging, bugs |
|
|
253
|
+
| **qa** | Testing, verification | testing, qa, e2e |
|
|
254
|
+
| **security** | Security audits | security, audit |
|
|
255
|
+
| **docs** | Technical writing | documentation, readme |
|
|
256
|
+
| **researcher** | Code exploration, analysis | research, analysis |
|
|
257
|
+
| **devops** | CI/CD, infrastructure | ci-cd, docker |
|
|
258
|
+
|
|
259
|
+
### Agent Management
|
|
260
|
+
|
|
261
|
+
Use `/squad agents` for interactive management:
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
/squad agents — list all, select to view/edit
|
|
265
|
+
/squad agents backend — quick view of specific agent
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Actions available per agent:
|
|
269
|
+
- **View details** — name, role, model, tools, tags, prompt, file path
|
|
270
|
+
- **Edit in editor** — opens the agent JSON file
|
|
271
|
+
- **Change model** — set a specific model or use default
|
|
272
|
+
- **Toggle tools** — restrict to specific tools or enable all
|
|
273
|
+
- **Enable/Disable** — disabled agents are hidden from the planner
|
|
168
274
|
|
|
169
275
|
### Custom Agents
|
|
170
276
|
|
|
@@ -178,66 +284,173 @@ Create a JSON file in `~/.pi/squad/agents/` (global) or `{project}/.pi/squad/age
|
|
|
178
284
|
"model": "anthropic/claude-sonnet-4-20250514",
|
|
179
285
|
"tools": null,
|
|
180
286
|
"tags": ["ml", "pytorch", "data"],
|
|
181
|
-
"prompt": "You are an ML engineer specializing in PyTorch..."
|
|
287
|
+
"prompt": "You are an ML engineer specializing in PyTorch...",
|
|
288
|
+
"disabled": false
|
|
182
289
|
}
|
|
183
290
|
```
|
|
184
291
|
|
|
185
|
-
|
|
292
|
+
- `model`: `null` = pi default. Override with any model ID your provider supports.
|
|
293
|
+
- `tools`: `null` = all tools. Array like `["bash", "read", "write", "edit"]` to restrict.
|
|
294
|
+
- `tags`: Used by the planner to match agents to tasks automatically.
|
|
295
|
+
- `disabled`: `true` = hidden from planner, tasks assigned to this agent will fail.
|
|
296
|
+
- Project-local agents override global agents with the same name.
|
|
186
297
|
|
|
187
298
|
## How Agents Collaborate
|
|
188
299
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
300
|
+
### Chain Context (primary)
|
|
301
|
+
|
|
302
|
+
When task A completes, its **full output** is injected into task B's system prompt as a `# Completed Dependencies` section. Downstream agents read what was built and extend it — no need for explicit communication.
|
|
303
|
+
|
|
304
|
+
### Shared Filesystem
|
|
305
|
+
|
|
306
|
+
All agents work in the same project directory. Upstream agents create files, downstream agents read and modify them. Each agent is instructed to read files before writing to avoid conflicts.
|
|
194
307
|
|
|
195
|
-
|
|
308
|
+
### Sibling Awareness
|
|
196
309
|
|
|
197
|
-
|
|
310
|
+
When agents run in parallel, each sees the other's status and modified files in their system prompt:
|
|
198
311
|
|
|
199
312
|
```
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
313
|
+
# Sibling Tasks
|
|
314
|
+
- template-engine [in_progress] — fullstack — Create HTML templates
|
|
315
|
+
|
|
316
|
+
## Files Modified by Other Agents
|
|
317
|
+
**fullstack:** src/templateEngine.js, templates/post.html
|
|
318
|
+
⚠️ Coordinate with the owning agent before editing files listed above.
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### @Mention Routing
|
|
322
|
+
|
|
323
|
+
Agents can message each other in real-time:
|
|
324
|
+
|
|
208
325
|
```
|
|
326
|
+
Agent output: "@frontend what token format do you need?"
|
|
327
|
+
→ Router parses @mention
|
|
328
|
+
→ Delivers to running agent via steer()
|
|
329
|
+
→ Or queues for delivery when agent spawns
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Block Detection
|
|
209
333
|
|
|
210
|
-
|
|
334
|
+
If an agent says "I'm blocked" or "cannot proceed", the router detects it and escalates to the main agent.
|
|
211
335
|
|
|
212
|
-
|
|
336
|
+
## Session Resilience
|
|
213
337
|
|
|
214
|
-
|
|
338
|
+
### Crash Recovery
|
|
215
339
|
|
|
216
|
-
|
|
340
|
+
When a pi session crashes (tmux dies, SIGKILL, etc.):
|
|
341
|
+
- In-progress tasks are automatically **suspended** on next startup
|
|
342
|
+
- Squad is marked as **paused**
|
|
343
|
+
- Only squads with completed tasks trigger a notification
|
|
344
|
+
- Squads with zero progress are silently paused (no noise)
|
|
345
|
+
|
|
346
|
+
### Resume
|
|
347
|
+
|
|
348
|
+
Resume a paused squad across sessions:
|
|
217
349
|
|
|
218
350
|
```
|
|
219
|
-
|
|
220
|
-
└── squad "build-auth" └── squad "build-dashboard"
|
|
221
|
-
both stored in ~/.pi/squad/
|
|
222
|
-
filtered by cwd when listing
|
|
351
|
+
> Resume the squad
|
|
223
352
|
```
|
|
224
353
|
|
|
225
|
-
|
|
354
|
+
The agent calls `squad_modify({ action: "resume" })`, which:
|
|
355
|
+
1. Finds the latest paused squad for the project
|
|
356
|
+
2. Creates a fresh scheduler from disk state
|
|
357
|
+
3. Wires up event handlers for completion/failure/escalation
|
|
358
|
+
4. Restarts suspended tasks
|
|
359
|
+
|
|
360
|
+
All state lives on disk — squads are fully reconstructable from JSON files.
|
|
361
|
+
|
|
362
|
+
### Spawn Resilience
|
|
226
363
|
|
|
227
|
-
|
|
364
|
+
Child agent processes occasionally fail during startup (transient resource pressure). The scheduler automatically retries once after a 2-second delay. If the retry also fails, the task is marked failed with a diagnostic log including PID, exit code, stderr, and stdout line count.
|
|
228
365
|
|
|
229
366
|
## Governance
|
|
230
367
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
368
|
+
| Mechanism | What it does |
|
|
369
|
+
|---|---|
|
|
370
|
+
| **Dependency DAG** | Blocked tasks never spawn. Auto-unblock when deps complete. |
|
|
371
|
+
| **Concurrency control** | `maxConcurrency` limits parallel agents (default: 2) |
|
|
372
|
+
| **Health monitoring** | Idle warning (3m), stuck intervention (5m), loop detection (same tool 5x), 30m hard ceiling |
|
|
373
|
+
| **QA rework loop** | Auto-creates fix + retest tasks when QA fails (up to `maxRetries`) |
|
|
374
|
+
| **Spawn retry** | Retries once on transient startup failures, then fails with diagnostics |
|
|
375
|
+
| **File tracking** | Warns agents about files modified by other agents |
|
|
376
|
+
| **@mention routing** | Parsed from output, delivered via RPC `steer()` |
|
|
377
|
+
| **Escalation** | Blocked agents, stuck agents, retry limit, spawn failure → notify main agent |
|
|
378
|
+
| **Clean notifications** | Uses `sendMessage({ display: true })` — visible to user, not in LLM history |
|
|
379
|
+
|
|
380
|
+
## Data Layout
|
|
381
|
+
|
|
382
|
+
All state lives in `~/.pi/squad/`. No database, no daemon, no external services. Writes are atomic (temp file + rename). JSONL reads are fault-tolerant (skip corrupt lines from concurrent writes).
|
|
383
|
+
|
|
384
|
+
```
|
|
385
|
+
~/.pi/squad/
|
|
386
|
+
├── agents/ — agent definitions (user-editable)
|
|
387
|
+
│ ├── backend.json
|
|
388
|
+
│ ├── qa.json
|
|
389
|
+
│ └── ...
|
|
390
|
+
└── {squad-id}/ — one directory per squad
|
|
391
|
+
├── squad.json — goal, status, config, cwd
|
|
392
|
+
├── context.json — live state snapshot
|
|
393
|
+
├── knowledge/ — shared decisions/findings
|
|
394
|
+
│ ├── decisions.jsonl
|
|
395
|
+
│ └── findings.jsonl
|
|
396
|
+
└── {task-id}/ — one directory per task
|
|
397
|
+
├── task.json — status, agent, output, usage, retryOf, qaFeedback
|
|
398
|
+
└── messages.jsonl — full conversation log
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
## Architecture
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
src/
|
|
405
|
+
├── index.ts — extension entry: tools, commands, widget, panel, lifecycle
|
|
406
|
+
├── types.ts — Squad, Task, Agent, Message types
|
|
407
|
+
├── store.ts — JSON/JSONL file I/O with atomic writes, fault-tolerant reads
|
|
408
|
+
├── scheduler.ts — dependency DAG, concurrency, rework loop, spawn retry, task lifecycle
|
|
409
|
+
├── agent-pool.ts — pi RPC process spawn/steer/kill, diagnostic logging
|
|
410
|
+
├── protocol.ts — system prompt builder (7 sections + rework context)
|
|
411
|
+
├── router.ts — @mention parsing, cross-agent messaging
|
|
412
|
+
├── monitor.ts — health checks: idle/stuck/loop/ceiling
|
|
413
|
+
├── supervisor.ts — quality review, block analysis
|
|
414
|
+
├── planner.ts — one-shot goal decomposition via LLM
|
|
415
|
+
├── panel/
|
|
416
|
+
│ ├── squad-panel.ts — overlay component (ctx.ui.custom with done())
|
|
417
|
+
│ ├── squad-widget.ts — string[] widget with debounce and cache
|
|
418
|
+
│ ├── task-list.ts — task tree with status icons, elapsed time, sticky summary
|
|
419
|
+
│ └── message-view.ts — scrollable message log with word wrap, fixed-height layout
|
|
420
|
+
├── skills/
|
|
421
|
+
│ ├── supervisor/ — teaches main agent to supervise squads
|
|
422
|
+
│ ├── squad-protocol/ — communication rules for child agents
|
|
423
|
+
│ ├── collaboration/ — team interaction patterns
|
|
424
|
+
│ └── verification/ — verify-before-done + structured QA verdicts
|
|
425
|
+
└── agents/_defaults/ — 11 bundled agent definitions
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Test Results
|
|
429
|
+
|
|
430
|
+
### Simple (3 tasks, linear chain)
|
|
431
|
+
- URL shortener API: 3 tasks, 30 turns, $0.83, 4.5 minutes
|
|
432
|
+
- Backend → QA → Docs, all passing
|
|
433
|
+
|
|
434
|
+
### Medium (5 tasks, planner-decomposed)
|
|
435
|
+
- Quiz API: 5 tasks, 82 turns, $3.11, 14 minutes
|
|
436
|
+
- Planner auto-created: architect → backend → fullstack → QA + docs
|
|
437
|
+
- 111 vitest tests passing, 3,637 lines of code
|
|
438
|
+
|
|
439
|
+
### Complex with rework (5 original + 4 auto-rework = 9 tasks)
|
|
440
|
+
- Chat API with auth + rooms: 9 tasks, 176 turns, $4.60, 26 minutes
|
|
441
|
+
- QA found 2 bugs → 2 automatic rework cycles → both fixed and verified
|
|
442
|
+
- Dependency chain with parallel QA and rework loop
|
|
443
|
+
|
|
444
|
+
### Parallel squads (2 squads running simultaneously)
|
|
445
|
+
- Bookmarks API (2/2, $0.83) + Notes CLI (6/6 with 2 rework cycles, $1.17)
|
|
446
|
+
- Both ran concurrently from the same pi session
|
|
447
|
+
- Combined: 12 tasks, 101 turns, $2.00
|
|
236
448
|
|
|
237
449
|
## Requirements
|
|
238
450
|
|
|
239
|
-
- [pi](https://github.com/badlogic/pi-mono) coding agent
|
|
451
|
+
- [pi](https://github.com/badlogic/pi-mono) coding agent (v0.63.0+, recommended v0.64.0+)
|
|
240
452
|
- An API key configured in pi (Anthropic, OpenRouter, etc.)
|
|
453
|
+
- Node.js 18+
|
|
241
454
|
|
|
242
455
|
## License
|
|
243
456
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-squad",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Multi-agent collaboration extension for pi — task decomposition, dependency management, parallel execution, TUI panel",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"pi": {
|
|
7
|
-
"extensions": [
|
|
8
|
-
|
|
7
|
+
"extensions": [
|
|
8
|
+
"src/index.ts"
|
|
9
|
+
],
|
|
10
|
+
"skills": [
|
|
11
|
+
"src/skills/supervisor"
|
|
12
|
+
]
|
|
9
13
|
},
|
|
10
14
|
"files": [
|
|
11
15
|
"src",
|
package/src/agent-pool.ts
CHANGED
|
@@ -165,6 +165,7 @@ export class AgentPool {
|
|
|
165
165
|
|
|
166
166
|
// Spawn pi process — set env var to prevent recursive squad extension loading
|
|
167
167
|
const invocation = getPiInvocation(["--mode", "rpc", ...args]);
|
|
168
|
+
console.error(`[squad-pool] spawn ${agentDef.name}: ${invocation.command} ${invocation.args.slice(0, 3).join(" ")} ...`);
|
|
168
169
|
const proc = spawn(invocation.command, invocation.args, {
|
|
169
170
|
cwd,
|
|
170
171
|
stdio: ["pipe", "pipe", "pipe"],
|
|
@@ -199,6 +200,7 @@ export class AgentPool {
|
|
|
199
200
|
});
|
|
200
201
|
|
|
201
202
|
attachLineReader(proc.stdout!, (line) => {
|
|
203
|
+
stdoutLines++;
|
|
202
204
|
try {
|
|
203
205
|
const event = JSON.parse(line);
|
|
204
206
|
this.handleRpcEvent(agentProc, event);
|
|
@@ -208,7 +210,14 @@ export class AgentPool {
|
|
|
208
210
|
});
|
|
209
211
|
|
|
210
212
|
let agentEndEmitted = false;
|
|
211
|
-
|
|
213
|
+
let stdoutLines = 0;
|
|
214
|
+
proc.on("exit", (code, signal) => {
|
|
215
|
+
// Log diagnostic info for debugging spawn failures
|
|
216
|
+
if (code !== 0 && code !== null) {
|
|
217
|
+
console.error(`[squad-pool] ${agentDef.name} exited: code=${code} signal=${signal} pid=${proc.pid} stdoutLines=${stdoutLines} stderr=${stderr.slice(0, 300) || "(empty)"}`);
|
|
218
|
+
}
|
|
219
|
+
// Clean up agents map so getRunningAgents() doesn't count dead processes
|
|
220
|
+
this.agents.delete(taskId);
|
|
212
221
|
// Only emit if we haven't already emitted via RPC agent_end event
|
|
213
222
|
if (!agentEndEmitted) {
|
|
214
223
|
agentEndEmitted = true;
|