@melihmucuk/pi-crew 1.0.14 → 1.0.15
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 +19 -18
- package/agents/code-reviewer.md +52 -104
- package/agents/oracle.md +26 -52
- package/agents/planner.md +7 -7
- package/agents/quality-reviewer.md +90 -131
- package/agents/scout.md +3 -2
- package/agents/worker.md +8 -2
- package/extension/index.ts +8 -10
- package/extension/integration/tools/crew-abort.ts +5 -0
- package/extension/integration/tools/crew-done.ts +4 -0
- package/extension/integration/tools/crew-list.ts +3 -2
- package/extension/integration/tools/crew-respond.ts +3 -1
- package/extension/integration/tools/crew-spawn.ts +71 -72
- package/extension/integration.ts +0 -2
- package/extension/runtime/crew-runtime.ts +9 -9
- package/extension/runtime/subagent-registry.ts +2 -9
- package/extension/runtime/subagent-state.ts +35 -49
- package/package.json +11 -8
- package/prompts/pi-crew-plan.md +46 -37
- package/prompts/pi-crew-review.md +3 -1
- package/skills/pi-crew/SKILL.md +129 -0
- package/docs/architecture.md +0 -186
- package/extension/integration/register-command.ts +0 -59
package/docs/architecture.md
DELETED
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
# pi-crew Architecture
|
|
2
|
-
|
|
3
|
-
This document explains the technical architecture of `@melihmucuk/pi-crew`, focusing on what makes this extension unique.
|
|
4
|
-
|
|
5
|
-
For pi fundamentals, see pi docs: `extensions.md`, `sdk.md`, `session.md`. Project-level guardrails are in `AGENTS.md`.
|
|
6
|
-
|
|
7
|
-
## 1. What pi-crew adds
|
|
8
|
-
|
|
9
|
-
`pi-crew` is a non-blocking subagent orchestration extension. It lets one pi session delegate work to isolated subagent sessions without blocking the caller. Results are delivered back as `crew-result` custom messages.
|
|
10
|
-
|
|
11
|
-
Primary components:
|
|
12
|
-
|
|
13
|
-
- `extension/runtime/crew-runtime.ts` - Process-level singleton owning all subagent state
|
|
14
|
-
- `extension/runtime/subagent-registry.ts` - In-memory subagent registry
|
|
15
|
-
- `extension/runtime/delivery-coordinator.ts` - Owner-based result routing
|
|
16
|
-
- `extension/runtime/overflow-recovery.ts` - Context overflow retry tracking for subagent prompts
|
|
17
|
-
- `extension/bootstrap-session.ts` - Subagent session construction with extension filtering
|
|
18
|
-
- `extension/agent-discovery.ts` - Subagent definition discovery and validation
|
|
19
|
-
|
|
20
|
-
## 2. Core runtime components
|
|
21
|
-
|
|
22
|
-
### 2.1 CrewRuntime singleton
|
|
23
|
-
|
|
24
|
-
`CrewRuntime` is a process-level singleton that survives pi runtime replacement (`/resume`, `/new`, `/fork`, `/reload`). When pi discards an old extension instance and creates a new one, the new instance reconnects to the same `crewRuntime` and picks up existing subagent state.
|
|
25
|
-
|
|
26
|
-
Responsibilities:
|
|
27
|
-
|
|
28
|
-
- Create subagent state records
|
|
29
|
-
- Bootstrap isolated subagent sessions
|
|
30
|
-
- Run subagent prompt cycles with overflow recovery
|
|
31
|
-
- Transition subagents between states
|
|
32
|
-
- Deliver results to owner sessions
|
|
33
|
-
|
|
34
|
-
### 2.2 Delivery coordinator
|
|
35
|
-
|
|
36
|
-
Routes subagent results to the correct session at the correct time. Key behaviors:
|
|
37
|
-
|
|
38
|
-
- Tracks active session via `ActiveRuntimeBinding` (set on `session_start`, cleared on `session_shutdown`)
|
|
39
|
-
- Queues results when owner session is inactive
|
|
40
|
-
- Flushes queued results when owner session activates on any `session_start`; resume/fork are the important replacement paths because subagents survive runtime replacement within the same process
|
|
41
|
-
- Uses `triggerTurn: false/true` split to preserve ordering between `crew-result` and `crew-remaining`
|
|
42
|
-
|
|
43
|
-
Underlying delivery: see pi's `sendMessage({ deliverAs, triggerTurn })` in extensions.md.
|
|
44
|
-
|
|
45
|
-
`crew_list` uses the same idle/streaming delivery rules for its `crew-list-warning` custom message when active subagents exist. The warning is separate from tool output so the list remains a one-time snapshot while anti-polling guidance is delivered as a visible message.
|
|
46
|
-
|
|
47
|
-
### 2.3 Overflow recovery
|
|
48
|
-
|
|
49
|
-
Subagent prompt cycles are wrapped by overflow recovery tracking. The tracker observes `agent_end`, `compaction_start`, `compaction_end`, `auto_retry_start`, and `auto_retry_end` events to distinguish normal completion from context-overflow compaction and retry.
|
|
50
|
-
|
|
51
|
-
Outcomes:
|
|
52
|
-
|
|
53
|
-
- No overflow observed → prompt outcome is based on the final assistant message.
|
|
54
|
-
- Overflow compaction completes with retry and the retry reaches a terminal `agent_end` → recovered; prompt outcome is based on the final assistant message.
|
|
55
|
-
- Overflow handling times out, is cancelled, or compaction does not retry → failed; the subagent settles as `error` unless the final assistant message already reported an error.
|
|
56
|
-
|
|
57
|
-
### 2.4 Subagent registry
|
|
58
|
-
|
|
59
|
-
In-memory, process-scoped: `Map<subagentId, SubagentState>`
|
|
60
|
-
|
|
61
|
-
- Owner session filtering
|
|
62
|
-
- Runtime ID generation (`<name>-<hex>`)
|
|
63
|
-
|
|
64
|
-
Does not persist across process restarts. Subagent session files remain for post-hoc inspection.
|
|
65
|
-
|
|
66
|
-
## 3. Session bootstrapping
|
|
67
|
-
|
|
68
|
-
When `crew_spawn` executes:
|
|
69
|
-
|
|
70
|
-
1. Resolve subagent definition from discovery sources
|
|
71
|
-
2. Resolve model (fallback to caller session model if invalid)
|
|
72
|
-
3. Resolve tools, skills
|
|
73
|
-
4. Create `DefaultResourceLoader` with `extensionsOverride` that excludes `pi-crew`
|
|
74
|
-
5. Call `sessionManager.newSession({ parentSession })` for parent-child linkage
|
|
75
|
-
6. Create `AgentSession` with resolved configuration
|
|
76
|
-
7. Send task prompt asynchronously
|
|
77
|
-
|
|
78
|
-
**Extension filtering:** Subagent sessions must not load `pi-crew` again. Prevents recursive orchestration loops.
|
|
79
|
-
|
|
80
|
-
## 4. Delivery model
|
|
81
|
-
|
|
82
|
-
### 4.1 Owner-based routing
|
|
83
|
-
|
|
84
|
-
Results belong to the session that spawned the subagent. Owner identity uses `getSessionId()`, not file path (in-memory sessions have undefined paths).
|
|
85
|
-
|
|
86
|
-
### 4.2 Idle vs streaming
|
|
87
|
-
|
|
88
|
-
Check owner session state before delivery:
|
|
89
|
-
|
|
90
|
-
- **Idle (`isIdle() = true`):** Send with `triggerTurn: true`
|
|
91
|
-
- **Streaming (`isIdle() = false`):** Send with `deliverAs: "steer"` and `triggerTurn: true`
|
|
92
|
-
|
|
93
|
-
Critical: `deliverAs: "steer"` to an idle session leaves the message unprocessed (no active turn loop).
|
|
94
|
-
|
|
95
|
-
### 4.3 Deferred flush
|
|
96
|
-
|
|
97
|
-
Pending message flush after `session_start` is deferred to next macrotask. Synchronous delivery loses custom message persistence (pi-core emits `session_start` before reconnecting agent listener during resume). While a flush is scheduled, new deliveries for that owner are queued so ordering is preserved.
|
|
98
|
-
|
|
99
|
-
### 4.4 TTL cleanup
|
|
100
|
-
|
|
101
|
-
Pending messages older than 24 hours are discarded during `flushPending`.
|
|
102
|
-
|
|
103
|
-
## 5. Subagent state lifecycle
|
|
104
|
-
|
|
105
|
-
### 5.1 States
|
|
106
|
-
|
|
107
|
-
- `running` - Actively processing
|
|
108
|
-
- `waiting` - Interactive subagent awaiting `crew_respond` or `crew_done`
|
|
109
|
-
- `done` - Completed successfully
|
|
110
|
-
- `error` - Failed with error
|
|
111
|
-
- `aborted` - Cancelled
|
|
112
|
-
|
|
113
|
-
### 5.2 State transitions
|
|
114
|
-
|
|
115
|
-
After prompt cycle completion, inspect assistant stop reason:
|
|
116
|
-
|
|
117
|
-
- `stopReason: "error"` → status `error`
|
|
118
|
-
- `stopReason: "aborted"` → status `aborted`
|
|
119
|
-
- Normal completion + `interactive: true` → status `waiting`
|
|
120
|
-
- Normal completion + non-interactive → status `done`
|
|
121
|
-
|
|
122
|
-
### 5.3 Interactive subagents
|
|
123
|
-
|
|
124
|
-
`interactive: true` subagents enter `waiting` after each response. They accept follow-up messages via `crew_respond` until explicitly closed with `crew_done`. Closing does NOT emit a duplicate `crew-result`.
|
|
125
|
-
|
|
126
|
-
### 5.4 Tool completion behavior
|
|
127
|
-
|
|
128
|
-
`crew_respond` returns immediately and delivers the subagent response asynchronously. Successful `crew_abort` results terminate the current tool turn after aborting owned subagents.
|
|
129
|
-
|
|
130
|
-
## 6. Ownership and isolation
|
|
131
|
-
|
|
132
|
-
Invariants:
|
|
133
|
-
|
|
134
|
-
1. `crew_list`, `crew_abort`, `crew_respond`, `crew_done`, status widget: session-scoped. Only owner sees/controls.
|
|
135
|
-
2. `/pi-crew-abort`: cross-session emergency escape hatch.
|
|
136
|
-
3. `session_shutdown` always deactivates delivery binding. On replacement paths (`reload`, `new`, `resume`, `fork`), subagents continue running. On `quit`, the extension aborts all running subagents. `SIGINT` also aborts via a process hook, and `beforeExit` remains a fallback.
|
|
137
|
-
|
|
138
|
-
## 7. Subagent definition model
|
|
139
|
-
|
|
140
|
-
Discovery priority:
|
|
141
|
-
|
|
142
|
-
1. Project: `<cwd>/.pi/agents/*.md`
|
|
143
|
-
2. User global: `~/.pi/agent/agents/*.md`
|
|
144
|
-
3. Bundled: `agents/` in package
|
|
145
|
-
|
|
146
|
-
Higher priority wins. Same-name duplicates in same directory produce warning.
|
|
147
|
-
|
|
148
|
-
Frontmatter: `name`, `description`, `model`, `thinking`, `tools`, `skills`, `compaction`, `interactive`
|
|
149
|
-
|
|
150
|
-
Tools/skills semantics:
|
|
151
|
-
|
|
152
|
-
- **Omitted:** Use full supported allowlist
|
|
153
|
-
- **Empty list (`tools: []`):** Grant none
|
|
154
|
-
|
|
155
|
-
JSON overrides: `~/.pi/agent/pi-crew.json` (global), `<cwd>/.pi/pi-crew.json` (project). Project wins.
|
|
156
|
-
|
|
157
|
-
## 8. Behavioral invariants
|
|
158
|
-
|
|
159
|
-
1. Spawned subagent must not block caller session.
|
|
160
|
-
2. Results route to owning session (by ID), not currently active session.
|
|
161
|
-
3. Subagent sessions must not load `pi-crew`.
|
|
162
|
-
4. `crew_respond` returns immediately; result delivered asynchronously.
|
|
163
|
-
5. `crew_done` cleans up only; no duplicate result message.
|
|
164
|
-
6. Queued results flush when owner session becomes active.
|
|
165
|
-
7. `crew-result` messages appear before `crew-remaining` notes (ordering via `triggerTurn` split).
|
|
166
|
-
8. `crew-list-warning` is delivered as a separate custom message when `crew_list` is called while the owner has active subagents.
|
|
167
|
-
9. Pending messages preserved for inactive sessions; TTL (24h) prevents memory leak.
|
|
168
|
-
10. Active subagent state survives runtime replacement within same process.
|
|
169
|
-
11. Graceful quit aborts subagents through `session_shutdown.reason === "quit"`; replacement paths do not.
|
|
170
|
-
|
|
171
|
-
## 9. Reading guide
|
|
172
|
-
|
|
173
|
-
1. `README.md` - Product surface
|
|
174
|
-
2. `AGENTS.md` - Architecture guardrails
|
|
175
|
-
3. `extension/index.ts` - Session event wiring
|
|
176
|
-
4. `extension/runtime/crew-runtime.ts` - Orchestration, state transitions
|
|
177
|
-
5. `extension/runtime/delivery-coordinator.ts` - Owner routing, queueing
|
|
178
|
-
6. `extension/bootstrap-session.ts` - Session construction
|
|
179
|
-
7. `extension/agent-discovery.ts` - Definition validation
|
|
180
|
-
8. `extension/integration/` - Tools, command, renderers
|
|
181
|
-
|
|
182
|
-
## 10. Verification
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
npm run typecheck
|
|
186
|
-
```
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
-
import type { CrewRuntime } from "../runtime/crew-runtime.js";
|
|
3
|
-
|
|
4
|
-
export function registerCrewCommand(pi: ExtensionAPI, crew: CrewRuntime): void {
|
|
5
|
-
pi.registerCommand("pi-crew-abort", {
|
|
6
|
-
description: "Abort an active subagent",
|
|
7
|
-
|
|
8
|
-
getArgumentCompletions(argumentPrefix) {
|
|
9
|
-
const activeAgents = crew.getAbortableAgents();
|
|
10
|
-
if (activeAgents.length === 0) return null;
|
|
11
|
-
return activeAgents
|
|
12
|
-
.filter((agent) => agent.id.startsWith(argumentPrefix))
|
|
13
|
-
.map((agent) => ({
|
|
14
|
-
value: agent.id,
|
|
15
|
-
label: `${agent.id} (${agent.agentName})`,
|
|
16
|
-
}));
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
async handler(args, ctx) {
|
|
20
|
-
const trimmed = args.trim();
|
|
21
|
-
|
|
22
|
-
if (trimmed) {
|
|
23
|
-
const success = crew.abort(trimmed, { reason: "Aborted by user command" });
|
|
24
|
-
if (!success) {
|
|
25
|
-
ctx.ui.notify(`No active subagent with id "${trimmed}"`, "error");
|
|
26
|
-
} else {
|
|
27
|
-
ctx.ui.notify(`Subagent ${trimmed} aborted`, "info");
|
|
28
|
-
}
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const activeAgents = crew.getAbortableAgents();
|
|
33
|
-
if (activeAgents.length === 0) {
|
|
34
|
-
ctx.ui.notify("No active subagents", "info");
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const options = activeAgents.map((agent) => ({
|
|
39
|
-
id: agent.id,
|
|
40
|
-
label: `${agent.id} (${agent.agentName})`,
|
|
41
|
-
}));
|
|
42
|
-
const selected = await ctx.ui.select(
|
|
43
|
-
"Select subagent to abort",
|
|
44
|
-
options.map((option) => option.label),
|
|
45
|
-
);
|
|
46
|
-
if (!selected) return;
|
|
47
|
-
|
|
48
|
-
const selectedOption = options.find((option) => option.label === selected);
|
|
49
|
-
if (!selectedOption) return;
|
|
50
|
-
|
|
51
|
-
const success = crew.abort(selectedOption.id, { reason: "Aborted by user command" });
|
|
52
|
-
if (success) {
|
|
53
|
-
ctx.ui.notify(`Subagent ${selectedOption.id} aborted`, "info");
|
|
54
|
-
} else {
|
|
55
|
-
ctx.ui.notify(`Subagent ${selectedOption.id} already finished`, "error");
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
}
|