pi-crew 0.8.14 → 0.9.1
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/CHANGELOG.md +366 -0
- package/README.md +112 -2
- package/docs/FEATURE_INTAKE.md +1 -1
- package/docs/HARNESS.md +20 -19
- package/docs/PROJECT_REVIEW.md +132 -133
- package/docs/PROJECT_REVIEW_FIXES.md +130 -131
- package/docs/actions-reference.md +127 -121
- package/docs/architecture.md +1 -1
- package/docs/code-review-2026-05-11.md +134 -134
- package/docs/commands-reference.md +108 -106
- package/docs/comparison-pi-subagents-vs-pi-crew.md +105 -105
- package/docs/deep-review-report.md +1 -1
- package/docs/dynamic-workflows.md +90 -0
- package/docs/fixes/BATCH_A_H1_H2.md +17 -17
- package/docs/fixes/bug-007-async-notifier-stale-ctx.md +23 -23
- package/docs/followup-plan-2026-05-12.md +135 -135
- package/docs/followup-review-2026-05-12.md +86 -86
- package/docs/followup-review-round3-2026-05-12.md +123 -123
- package/docs/goals.md +59 -0
- package/docs/implementation-plan-top3.md +4 -4
- package/docs/issue-29-analysis.md +2 -2
- package/docs/oh-my-pi-research.md +154 -154
- package/docs/optimization-plan.md +2 -0
- package/docs/perf/baseline-2026-05.md +9 -9
- package/docs/perf/final-report-2026-05.md +2 -2
- package/docs/perf/sprint-1-report.md +2 -2
- package/docs/perf/sprint-2-report.md +1 -1
- package/docs/perf/upgrade-plan-2026-05.md +72 -72
- package/docs/pi-crew-bugs.md +230 -230
- package/docs/pi-crew-investigation-report.md +102 -102
- package/docs/pi-crew-test-round5.md +4 -4
- package/docs/runtime-analysis-child-vs-live.md +57 -57
- package/docs/runtime-migration-in-process-analysis.md +97 -97
- package/package.json +2 -4
- package/skills/orchestration/SKILL.md +11 -11
- package/src/agents/agent-config.ts +4 -0
- package/src/config/config.ts +39 -0
- package/src/config/types.ts +11 -0
- package/src/extension/action-suggestions.ts +2 -1
- package/src/extension/async-notifier.ts +10 -0
- package/src/extension/help.ts +14 -0
- package/src/extension/registration/commands.ts +27 -0
- package/src/extension/team-tool/destructive-gate.ts +1 -1
- package/src/extension/team-tool/goal-wrap.ts +288 -0
- package/src/extension/team-tool/goal.ts +405 -0
- package/src/extension/team-tool/run.ts +103 -4
- package/src/extension/team-tool/workflow-manage.ts +194 -0
- package/src/extension/team-tool.ts +20 -0
- package/src/hooks/types.ts +3 -1
- package/src/runtime/async-runner.ts +27 -2
- package/src/runtime/background-runner.ts +68 -19
- package/src/runtime/child-pi.ts +9 -1
- package/src/runtime/completion-guard.ts +1 -1
- package/src/runtime/dynamic-workflow-context.ts +450 -0
- package/src/runtime/dynamic-workflow-runner.ts +180 -0
- package/src/runtime/global-worker-cap.ts +96 -0
- package/src/runtime/goal-evaluator.ts +294 -0
- package/src/runtime/goal-loop-runner.ts +612 -0
- package/src/runtime/goal-state-store.ts +209 -0
- package/src/runtime/iteration-hooks.ts +2 -1
- package/src/runtime/pi-args.ts +10 -2
- package/src/runtime/post-checks.ts +2 -1
- package/src/runtime/result-extractor.ts +32 -0
- package/src/runtime/team-runner.ts +11 -1
- package/src/runtime/verification-gates.ts +88 -5
- package/src/runtime/verification-integrity.ts +110 -0
- package/src/runtime/verification-worktree.ts +136 -0
- package/src/runtime/workspace-lock.ts +448 -0
- package/src/schema/config-schema.ts +26 -0
- package/src/schema/team-tool-schema.ts +39 -4
- package/src/state/atomic-write.ts +9 -0
- package/src/state/contracts.ts +14 -0
- package/src/state/crew-init.ts +18 -5
- package/src/state/event-log.ts +7 -1
- package/src/state/state-store.ts +2 -0
- package/src/state/types.ts +82 -0
- package/src/state/worker-atomic-writer.ts +190 -0
- package/src/utils/env-allowlist.ts +30 -0
- package/src/utils/redaction.ts +104 -24
- package/src/utils/safe-paths.ts +55 -14
- package/src/workflows/discover-workflows.ts +25 -1
- package/src/workflows/workflow-config.ts +13 -0
- package/src/worktree/cleanup.ts +2 -1
- package/src/worktree/worktree-manager.ts +4 -3
- package/teams/parallel-research.team.md +1 -1
- package/workflows/examples/hello.dwf.ts +24 -0
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Architecture Comparison: pi-subagents3 vs pi-crew
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Date: 2026-05-12
|
|
4
4
|
> Source: `@tintinweb/pi-subagents` v0.7.1 (6.082 LOC, 28 files) vs `pi-crew` v0.2.3 (35.809 LOC, ~200+ files)
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## 1.
|
|
8
|
+
## 1. Overview
|
|
9
9
|
|
|
10
|
-
|
|
|
10
|
+
| Criterion | pi-subagents3 | pi-crew |
|
|
11
11
|
|---|---|---|
|
|
12
|
-
| **
|
|
13
|
-
| **
|
|
14
|
-
| **
|
|
12
|
+
| **Author** | tintinweb | baphuongna |
|
|
13
|
+
| **Version** | 0.7.1 | 0.2.3 |
|
|
14
|
+
| **Goal** | Single subagent (Agent tool) — spawn, resume, steer | Team orchestration — multi-agent workflows, phases, parallel dispatch |
|
|
15
15
|
| **LOC** | ~6.000 | ~36.000 |
|
|
16
|
-
| **Entry point** | `src/index.ts` (1.885
|
|
17
|
-
| **
|
|
16
|
+
| **Entry point** | `src/index.ts` (1.885 lines — monolith) | `index.ts` → `register.ts` (668 lines) → modular registration |
|
|
17
|
+
| **Architecture** | Simple, direct, single-agent focus | Layered, event-driven, state-machine based |
|
|
18
18
|
| **Peer deps** | pi-ai ≥0.70.5, pi-coding-agent ≥0.70.5, pi-tui ≥0.70.5 | pi-coding-agent (runtime) |
|
|
19
19
|
| **Npm deps** | `@sinclair/typebox`, `croner`, `nanoid` | 0 (zero runtime dependencies) |
|
|
20
20
|
| **Test runner** | vitest | Node built-in `--experimental-strip-types` |
|
|
21
|
-
| **Subprocess model** | **In-process** (
|
|
21
|
+
| **Subprocess model** | **In-process** (reuses Pi SDK `createAgentSession`) | **Out-of-process** (spawn child Pi instance via `child-pi.ts`) |
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
## 2.
|
|
25
|
+
## 2. Core architecture
|
|
26
26
|
|
|
27
27
|
### 2.1 pi-subagents3 — In-process Agent Sessions
|
|
28
28
|
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
└──────────────────────────────────────────────┘
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
- Agent
|
|
50
|
-
-
|
|
51
|
-
- Tool filtering, extension binding, skill preloading
|
|
52
|
-
- Event subscription (`session.subscribe()`)
|
|
53
|
-
-
|
|
48
|
+
**Key characteristics:**
|
|
49
|
+
- Agent runs **in the same process** as the parent Pi session
|
|
50
|
+
- Uses `createAgentSession()` + `session.prompt()` — direct Pi SDK API
|
|
51
|
+
- Tool filtering, extension binding, skill preloading in-process
|
|
52
|
+
- Event subscription (`session.subscribe()`) to track turns, tool uses, streaming text
|
|
53
|
+
- A single huge `index.ts` file contains nearly all the logic
|
|
54
54
|
|
|
55
55
|
### 2.2 pi-crew — Out-of-process Child Workers
|
|
56
56
|
|
|
@@ -77,24 +77,24 @@
|
|
|
77
77
|
└─────────────────────────────────────────────────────────┘
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
- Worker
|
|
82
|
-
-
|
|
80
|
+
**Key characteristics:**
|
|
81
|
+
- Worker runs **in a separate process** — spawns `pi` CLI child process
|
|
82
|
+
- Communicates via JSON events on stdout (`--json-output` mode)
|
|
83
83
|
- State persistence: JSONL event log, manifest files, atomic writes
|
|
84
|
-
-
|
|
85
|
-
-
|
|
84
|
+
- Distributed architecture: team → workflow → phases → tasks → workers
|
|
85
|
+
- Full isolation: crash recovery, stuck detection, deadletter
|
|
86
86
|
|
|
87
87
|
---
|
|
88
88
|
|
|
89
|
-
## 3.
|
|
89
|
+
## 3. Detailed module-by-module comparison
|
|
90
90
|
|
|
91
91
|
### 3.1 Agent Execution
|
|
92
92
|
|
|
93
|
-
|
|
|
93
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
94
94
|
|---|---|---|
|
|
95
95
|
| **Runtime** | `createAgentSession()` in-process | `spawn("pi", [...])` child process |
|
|
96
|
-
| **Tool access** | Direct — `session.setActiveToolsByName()` |
|
|
97
|
-
| **Context sharing** | `buildParentContext()` — copy conversation |
|
|
96
|
+
| **Tool access** | Direct — `session.setActiveToolsByName()` | Limited by child Pi args |
|
|
97
|
+
| **Context sharing** | `buildParentContext()` — copy conversation | None (isolated by design) |
|
|
98
98
|
| **Steering** | `session.steer(message)` — immediate in-process | `child.stdin.write()` — JSON event |
|
|
99
99
|
| **Resume** | `resumeAgent(session, prompt)` — reuse session | Re-spawn child process |
|
|
100
100
|
| **Turn limits** | Soft limit → steer "wrap up" → hard abort | `--max-turns` CLI arg → child exit |
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
|
|
108
108
|
### 3.2 Agent Configuration
|
|
109
109
|
|
|
110
|
-
|
|
|
110
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
111
111
|
|---|---|---|
|
|
112
112
|
| **Built-in agents** | 3: general-purpose, Explore, Plan | 10: explorer, planner, executor, reviewer, verifier, analyst, critic, writer, security-reviewer, test-engineer |
|
|
113
113
|
| **Custom agents** | `.md` files in `.pi/agents/` or `~/.pi/agents/` | `.md` files in `agents/` (project) |
|
|
@@ -120,9 +120,9 @@
|
|
|
120
120
|
|
|
121
121
|
### 3.3 Memory / Persistence
|
|
122
122
|
|
|
123
|
-
|
|
|
123
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
124
124
|
|---|---|---|
|
|
125
|
-
| **Agent memory** | ✅ Persistent MEMORY.md per agent (user/project/local scope) | ❌
|
|
125
|
+
| **Agent memory** | ✅ Persistent MEMORY.md per agent (user/project/local scope) | ❌ No built-in agent memory |
|
|
126
126
|
| **Memory tools** | Injected dynamically based on write capability | N/A |
|
|
127
127
|
| **State persistence** | In-memory AgentRecord + JSON schedule store | Full state machine: manifest.json + events.jsonl + tasks.json |
|
|
128
128
|
| **Crash recovery** | Worktree prune on dispose | Detect interrupted runs, deadletter, stuck-blocked notifications |
|
|
@@ -131,9 +131,9 @@
|
|
|
131
131
|
|
|
132
132
|
### 3.4 Scheduling
|
|
133
133
|
|
|
134
|
-
|
|
|
134
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
135
135
|
|---|---|---|
|
|
136
|
-
| **Scheduling** | ✅ Full scheduler: cron (6-field), interval, one-shot | ❌
|
|
136
|
+
| **Scheduling** | ✅ Full scheduler: cron (6-field), interval, one-shot | ❌ No scheduling |
|
|
137
137
|
| **Cron engine** | `croner` library | N/A |
|
|
138
138
|
| **Persistence** | Session-scoped JSON with PID-locked store | N/A |
|
|
139
139
|
| **Queue bypass** | `bypassQueue: true` for scheduled fires | N/A |
|
|
@@ -142,7 +142,7 @@
|
|
|
142
142
|
|
|
143
143
|
### 3.5 Worktree Isolation
|
|
144
144
|
|
|
145
|
-
|
|
|
145
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
146
146
|
|---|---|---|
|
|
147
147
|
| **Worktree support** | ✅ `createWorktree()` / `cleanupWorktree()` | ✅ Full `worktree-manager.ts` (8.8 KB) |
|
|
148
148
|
| **Branch management** | Auto-branch, auto-commit changes | Branch freshness, reuse, file node_modules skip |
|
|
@@ -151,7 +151,7 @@
|
|
|
151
151
|
|
|
152
152
|
### 3.6 Cross-extension Communication
|
|
153
153
|
|
|
154
|
-
|
|
|
154
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
155
155
|
|---|---|---|
|
|
156
156
|
| **RPC protocol** | ✅ Event bus RPC: ping/spawn/stop | ✅ Event bus RPC: ping/spawn/status/cancel |
|
|
157
157
|
| **Protocol version** | v2 | Versioned |
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
|
|
161
161
|
### 3.7 UI / TUI
|
|
162
162
|
|
|
163
|
-
|
|
|
163
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
164
164
|
|---|---|---|
|
|
165
165
|
| **Agent widget** | `agent-widget.ts` (518 LOC) — overlay | `crew-widget.ts` (16 KB) — sidebar + dashboard |
|
|
166
166
|
| **Conversation viewer** | `conversation-viewer.ts` (243 LOC) | `transcript-viewer.ts` (13.9 KB) — JSONL-based |
|
|
@@ -169,11 +169,11 @@
|
|
|
169
169
|
| **Status bar** | Inline status in overlay | `powerbar-publisher.ts` (8.9 KB) |
|
|
170
170
|
| **Live sidebar** | N/A | `live-run-sidebar.ts` (8.6 KB) |
|
|
171
171
|
| **Notification render** | Custom `renderCall` / `renderResult` | `notification-router.ts` + `notification-sink.ts` |
|
|
172
|
-
| **Context % indicator** | ✅ Token count + context % (colored) + compaction count | ❌
|
|
172
|
+
| **Context % indicator** | ✅ Token count + context % (colored) + compaction count | ❌ No context indicator |
|
|
173
173
|
|
|
174
174
|
### 3.8 Settings / Configuration
|
|
175
175
|
|
|
176
|
-
|
|
|
176
|
+
| Aspect | pi-subagents3 | pi-crew |
|
|
177
177
|
|---|---|---|
|
|
178
178
|
| **Settings file** | `.pi/subagents.json` (project) + `~/.pi/agent/subagents.json` (global) | `config.ts` → `.pi/crew-config.json` + `defaults.ts` |
|
|
179
179
|
| **Runtime settings** | maxConcurrent, defaultMaxTurns, graceTurns, defaultJoinMode, schedulingEnabled | maxConcurrent, telemetry, notifications |
|
|
@@ -182,122 +182,122 @@
|
|
|
182
182
|
|
|
183
183
|
---
|
|
184
184
|
|
|
185
|
-
## 4.
|
|
185
|
+
## 4. Unique features
|
|
186
186
|
|
|
187
|
-
### pi-subagents3
|
|
187
|
+
### pi-subagents3 has but pi-crew doesn't:
|
|
188
188
|
|
|
189
189
|
1. **In-process agent sessions** — Zero subprocess overhead, direct Pi SDK access, shared event loop
|
|
190
|
-
2. **Persistent agent memory** — MEMORY.md per agent
|
|
191
|
-
3. **Soft turn limit + grace period** — Steer "wrap up"
|
|
192
|
-
4. **Scheduling** — Full cron/interval/one-shot scheduler
|
|
193
|
-
5. **Parent context inheritance** — `inheritContext`
|
|
194
|
-
6. **Append mode** — Agent
|
|
190
|
+
2. **Persistent agent memory** — MEMORY.md per agent with 3 scopes (user/project/local), auto-injected tools
|
|
191
|
+
3. **Soft turn limit + grace period** — Steer "wrap up" before hard-aborting, configurable grace turns
|
|
192
|
+
4. **Scheduling** — Full cron/interval/one-shot scheduler with croner, session-scoped persistence
|
|
193
|
+
5. **Parent context inheritance** — `inheritContext` forks the conversation for the subagent
|
|
194
|
+
6. **Append mode** — Agent runs as a "twin" of the parent (inherits system prompt + tools)
|
|
195
195
|
7. **Context % indicator** — Live context window utilization (%), compaction count (↻N)
|
|
196
196
|
8. **Agent memory tools** — Dynamic tool injection based on write capability (read-only vs read-write)
|
|
197
|
-
9. **Skill preloading** — Load skill content directly into system prompt (string[])
|
|
198
|
-
10. **Batch grouping** — 100ms debounce
|
|
199
|
-
11. **Cancelable nudges** — 200ms hold
|
|
200
|
-
12. **Agent creation wizard** — `/agents` → spawn agent
|
|
197
|
+
9. **Skill preloading** — Load skill content directly into the system prompt (string[])
|
|
198
|
+
10. **Batch grouping** — 100ms debounce batches multiple background completions into 1 notification
|
|
199
|
+
11. **Cancelable nudges** — 200ms hold before sending a notification, get_subagent_result cancels the nudge
|
|
200
|
+
12. **Agent creation wizard** — `/agents` → spawn an agent to create an agent config .md file
|
|
201
201
|
|
|
202
|
-
### pi-crew
|
|
202
|
+
### pi-crew has but pi-subagents3 doesn't:
|
|
203
203
|
|
|
204
|
-
1. **Team orchestration** — Multi-agent teams
|
|
204
|
+
1. **Team orchestration** — Multi-agent teams with workflows, phases, parallel dispatch
|
|
205
205
|
2. **Workflow engine** — Declarative workflow definitions (step → agent → gate → next)
|
|
206
206
|
3. **Out-of-process isolation** — Child Pi process, crash-safe, independent event loop
|
|
207
207
|
4. **Full state machine** — manifest.json + tasks.json + events.jsonl, durable persistence
|
|
208
208
|
5. **Crash recovery** — Detect interrupted runs, deadletter queue, stuck-blocked detection
|
|
209
|
-
6. **Mailbox system** — Interactive respond/nudge/ack workflow
|
|
209
|
+
6. **Mailbox system** — Interactive respond/nudge/ack workflow for waiting tasks
|
|
210
210
|
7. **Heartbeat monitoring** — `heartbeat-watcher.ts` + gradient-based health tracking
|
|
211
211
|
8. **Observability** — Metrics registry, OTLP exporter, Prometheus exporter
|
|
212
|
-
9. **Run export/import** — Bundle/unbundle runs
|
|
212
|
+
9. **Run export/import** — Bundle/unbundle runs for cross-machine sharing
|
|
213
213
|
10. **Live session management** — Live IRC, live agent control, live extension bridge
|
|
214
|
-
11. **UI dashboard** — Multi-pane dashboard
|
|
215
|
-
12. **Run snapshot cache** — Efficient state snapshots
|
|
216
|
-
13. **Delivery coordination** — Overflow recovery, delivery coordinator
|
|
214
|
+
11. **UI dashboard** — Multi-pane dashboard with agents/capabilities/health/mailbox/progress
|
|
215
|
+
12. **Run snapshot cache** — Efficient state snapshots for UI rendering
|
|
216
|
+
13. **Delivery coordination** — Overflow recovery, delivery coordinator for message routing
|
|
217
217
|
14. **i18n** — Internationalization support
|
|
218
218
|
15. **Post-checks** — Configurable post-execution verification hooks
|
|
219
|
-
16. **Iteration hooks** — Pre/post iteration hooks
|
|
220
|
-
17. **Model fallback chain** — Multi-model fallback
|
|
221
|
-
18. **Compaction summary** — Context compaction
|
|
219
|
+
16. **Iteration hooks** — Pre/post iteration hooks for external integrations
|
|
220
|
+
17. **Model fallback chain** — Multi-model fallback with cost tracking
|
|
221
|
+
18. **Compaction summary** — Context compaction for long-running agents
|
|
222
222
|
19. **Task quality scoring** — Automatic quality assessment of task outputs
|
|
223
223
|
20. **Agent capability inventory** — Dynamic tool/skill capability detection
|
|
224
224
|
|
|
225
225
|
---
|
|
226
226
|
|
|
227
|
-
## 5.
|
|
227
|
+
## 5. Pros and cons analysis
|
|
228
228
|
|
|
229
229
|
### pi-subagents3
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
-
|
|
231
|
+
**Pros:**
|
|
232
|
+
- **Simple**: ~6K LOC, easy to understand and maintain
|
|
233
233
|
- **Performance**: In-process, zero subprocess overhead, shared memory
|
|
234
|
-
- **
|
|
235
|
-
- **SDK-first**:
|
|
236
|
-
- **Interactive**: Resume, steer, conversation viewer
|
|
237
|
-
- **Settings**: Hot-reload, master switch
|
|
238
|
-
|
|
239
|
-
**
|
|
240
|
-
- **Monolith**: `index.ts` 1.885
|
|
241
|
-
- **No team support**:
|
|
242
|
-
- **Crash propagation**: Agent crash
|
|
243
|
-
- **Limited observability**:
|
|
244
|
-
- **No run persistence**: Agent record
|
|
234
|
+
- **Deep features**: Memory, scheduling, context inheritance, turn management are very detailed
|
|
235
|
+
- **SDK-first**: Uses the Pi SDK directly, fully leveraging the API
|
|
236
|
+
- **Interactive**: Resume, steer, conversation viewer are very smooth
|
|
237
|
+
- **Settings**: Hot-reload, master switch for features
|
|
238
|
+
|
|
239
|
+
**Cons:**
|
|
240
|
+
- **Monolith**: `index.ts` 1.885 lines — hard to maintain, hard to test
|
|
241
|
+
- **No team support**: No workflow, phases, parallel dispatch
|
|
242
|
+
- **Crash propagation**: Agent crash affects the parent process
|
|
243
|
+
- **Limited observability**: No metrics, export, monitoring
|
|
244
|
+
- **No run persistence**: Agent record is in-memory only (except the schedule store)
|
|
245
245
|
|
|
246
246
|
### pi-crew
|
|
247
247
|
|
|
248
|
-
|
|
249
|
-
- **
|
|
250
|
-
- **Team orchestration**: Workflow engine
|
|
251
|
-
- **Crash isolation**: Out-of-process workers, child crash
|
|
248
|
+
**Pros:**
|
|
249
|
+
- **Strong architecture**: Layered, event-driven, state-machine based
|
|
250
|
+
- **Team orchestration**: Workflow engine with phases, parallel, gates
|
|
251
|
+
- **Crash isolation**: Out-of-process workers, child crash doesn't affect parent
|
|
252
252
|
- **Full persistence**: JSONL event log, manifest, atomic writes
|
|
253
253
|
- **Observability**: Metrics, OTLP, Prometheus, heartbeat monitoring
|
|
254
|
-
- **Modular**: 200+ files,
|
|
254
|
+
- **Modular**: 200+ files, each file one responsibility
|
|
255
255
|
- **Enterprise features**: Export/import, i18n, compaction, quality scoring
|
|
256
256
|
|
|
257
|
-
**
|
|
258
|
-
- **
|
|
259
|
-
- **Subprocess overhead**:
|
|
260
|
-
- **
|
|
261
|
-
- **
|
|
262
|
-
- **
|
|
263
|
-
- **
|
|
264
|
-
- **
|
|
257
|
+
**Cons:**
|
|
258
|
+
- **Complex**: 36K LOC, steep learning curve
|
|
259
|
+
- **Subprocess overhead**: Each worker spawns its own process (RAM, startup time)
|
|
260
|
+
- **No memory**: Agents have no persistent memory between sessions
|
|
261
|
+
- **No scheduling**: No cron/interval/one-shot
|
|
262
|
+
- **No context inheritance**: Workers run isolated, can't see parent context
|
|
263
|
+
- **No soft turn limit**: Hard cutoff, no grace period
|
|
264
|
+
- **No interactive steer**: Cannot steer a worker after spawning
|
|
265
265
|
|
|
266
266
|
---
|
|
267
267
|
|
|
268
|
-
## 6.
|
|
268
|
+
## 6. Recommendations
|
|
269
269
|
|
|
270
|
-
### pi-crew
|
|
270
|
+
### What pi-crew should learn from pi-subagents3:
|
|
271
271
|
|
|
272
|
-
1. **Persistent agent memory** — MEMORY.md pattern
|
|
273
|
-
2. **Soft turn limit + grace period** —
|
|
274
|
-
3. **Scheduling** — Cron/interval scheduling
|
|
275
|
-
4. **Context % indicator** —
|
|
276
|
-
5. **Batch notification grouping** —
|
|
277
|
-
6. **In-process mode** (optional) —
|
|
278
|
-
7. **Cancelable nudges** —
|
|
279
|
-
8. **Agent settings hot-reload** —
|
|
272
|
+
1. **Persistent agent memory** — The MEMORY.md pattern is very valuable for long-running projects
|
|
273
|
+
2. **Soft turn limit + grace period** — More elegant than hard abort
|
|
274
|
+
3. **Scheduling** — Cron/interval scheduling for automated tasks
|
|
275
|
+
4. **Context % indicator** — Helps the parent LLM know how much room the subagent has left
|
|
276
|
+
5. **Batch notification grouping** — Reduces noise when many workers complete simultaneously
|
|
277
|
+
6. **In-process mode** (optional) — For lightweight tasks that don't need process isolation
|
|
278
|
+
7. **Cancelable nudges** — Avoid notification spam
|
|
279
|
+
8. **Agent settings hot-reload** — Change settings without restarting
|
|
280
280
|
|
|
281
|
-
### pi-subagents3
|
|
281
|
+
### What pi-subagents3 should learn from pi-crew:
|
|
282
282
|
|
|
283
|
-
1. **Modular architecture** —
|
|
284
|
-
2. **State persistence** — Durable state
|
|
283
|
+
1. **Modular architecture** — Split `index.ts` into multiple files
|
|
284
|
+
2. **State persistence** — Durable state instead of in-memory only
|
|
285
285
|
3. **Crash recovery** — Detect interrupted runs, deadletter
|
|
286
286
|
4. **Observability** — Metrics, monitoring, health checks
|
|
287
287
|
5. **Team support** — Multi-agent workflows
|
|
288
|
-
6. **Out-of-process option** —
|
|
288
|
+
6. **Out-of-process option** — For heavy tasks needing isolation
|
|
289
289
|
7. **Run export/import** — Cross-machine sharing
|
|
290
290
|
|
|
291
291
|
---
|
|
292
292
|
|
|
293
|
-
## 7.
|
|
293
|
+
## 7. Conclusion
|
|
294
294
|
|
|
295
|
-
**pi-subagents3**
|
|
295
|
+
**pi-subagents3** is a **focused** extension — it does one thing very well: spawn and manage individual subagents. It leverages the Pi SDK maximally, in-process, interactive, with deep features like memory and scheduling.
|
|
296
296
|
|
|
297
|
-
**pi-crew**
|
|
297
|
+
**pi-crew** is an **orchestration platform** — broader scope, strong in team workflows, state management, crash recovery, and enterprise features. But much more complex, and missing some "nice-to-have" features that pi-subagents3 has.
|
|
298
298
|
|
|
299
|
-
|
|
300
|
-
- pi-subagents3
|
|
301
|
-
- pi-crew
|
|
299
|
+
The two extensions **complement** each other more than they compete:
|
|
300
|
+
- pi-subagents3 for **quick, interactive subagent tasks** (code review, exploration, one-off analysis)
|
|
301
|
+
- pi-crew for **complex, multi-phase team workflows** (full feature implementation, multi-perspective review, parallel research)
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
An ideal architecture might combine both: use pi-subagents3's in-process execution for lightweight tasks, and pi-crew's orchestration layer for complex workflows.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# pi-crew Deep Review Report
|
|
2
2
|
|
|
3
3
|
**Project:** pi-crew
|
|
4
|
-
**Version:** v0.5.2 *(historical — current version is v0.
|
|
4
|
+
**Version:** v0.5.2 *(historical — current version is v0.9.0)*
|
|
5
5
|
**Review Date:** 2026-05-28
|
|
6
6
|
**Updated:** 2026-05-29
|
|
7
7
|
**Reviewers:** Security Reviewer, Code Reviewer, Documentation Reviewer
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Dynamic Workflows (`.dwf.ts`)
|
|
2
|
+
|
|
3
|
+
pi-crew v0.9.0 introduces dynamic workflows, modeled on Claude Code's Dynamic Workflows.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
A dynamic workflow is a `.dwf.ts` script whose default export orchestrates subagents
|
|
8
|
+
with normal JavaScript (`for`/`while`/`if`/`switch`). It runs in the background, calls
|
|
9
|
+
subagents per phase via `ctx.agent()` / `ctx.fanOut()`, holds intermediate results in
|
|
10
|
+
JS variables, and only `ctx.setResult()` reaches the main context — keeping the plan
|
|
11
|
+
and intermediate data out of the main context window.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// .crew/workflows/security-audit.dwf.ts
|
|
15
|
+
export default async function (ctx) {
|
|
16
|
+
const endpoints = [/* ... */];
|
|
17
|
+
const shards = chunk(endpoints, 3);
|
|
18
|
+
const reports = await ctx.fanOut(shards, 3, (s) =>
|
|
19
|
+
ctx.agent({ role: "explorer", prompt: `Audit ${s.join(",")} for auth + input validation` })
|
|
20
|
+
);
|
|
21
|
+
const synth = await ctx.agent({ role: "analyst", prompt: "Merge + dedupe findings", inputs: reports.map(r => r.artifactPath) });
|
|
22
|
+
for (let i = 0; i < 3; i++) {
|
|
23
|
+
const review = await ctx.review(synth.taskId, "reviewer");
|
|
24
|
+
if (review.outcome === "accept") break;
|
|
25
|
+
await ctx.retry(synth.taskId, { feedback: review.feedback });
|
|
26
|
+
}
|
|
27
|
+
ctx.setResult(synth.artifactPath, { summary: "security audit complete" });
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
Place the script under `.crew/workflows/<name>.dwf.ts`, then:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
team action='run', workflow='security-audit', goal='Audit src/routes'
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Slash command: `/workflows` lists all workflows (static + dynamic).
|
|
40
|
+
|
|
41
|
+
## WorkflowCtx API
|
|
42
|
+
|
|
43
|
+
| Method | Purpose |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `ctx.agent({role, prompt, model?, skill?, maxTurns?, inputs?})` | Spawn one agent, await `{ok, text, structured, artifactPath, usage}`. Concurrency enforced by `ctx.semaphore`. |
|
|
46
|
+
| `ctx.fanOut(items, limit, fn)` | Bounded parallel fan-out (wraps `mapConcurrent`). |
|
|
47
|
+
| `ctx.review(taskId, reviewerRole?)` | Run a reviewer; parse `{outcome, feedback}`. |
|
|
48
|
+
| `ctx.retry(taskId, {feedback?})` | Re-run with feedback (wraps `executeWithRetry`). |
|
|
49
|
+
| `ctx.mail(to, body, opts?)` | Mailbox message to another agent/leader. |
|
|
50
|
+
| `ctx.gatherReplies(ids, deadlineMs)` | Block until N replies arrive or deadline. |
|
|
51
|
+
| `ctx.renderTemplate(name, vars)` | Render a built-in plan template. |
|
|
52
|
+
| `ctx.vars` | Script-local variables. |
|
|
53
|
+
| `ctx.setResult(artifactPath, meta?)` | Mark the final result. ONLY this reaches the main context. |
|
|
54
|
+
|
|
55
|
+
`ctx.agent({role})` resolves the role to an `AgentConfig` via 4-tier precedence:
|
|
56
|
+
explicit `agent` name → `team.roles[].agent` → `discoverAgents` by name → synthesize
|
|
57
|
+
minimal (`source:'dynamic'`).
|
|
58
|
+
|
|
59
|
+
## Security model (IMPORTANT)
|
|
60
|
+
|
|
61
|
+
`.dwf.ts` files are **postinstall-equivalent trust** — treat them as `node script.js`.
|
|
62
|
+
|
|
63
|
+
**v1 boundary (honest):** The `WorkflowCtx` is `Object.freeze()`d and exposes ONLY
|
|
64
|
+
the documented methods — but the script otherwise runs in **plain module scope** with
|
|
65
|
+
full access to `require`/`import`/`process`. There is **no vm sandbox in v1**; the
|
|
66
|
+
script can reach `process`/`require` directly or via constructor walking. The
|
|
67
|
+
"capability-locked ctx" is the documented contract surface, not a security boundary.
|
|
68
|
+
|
|
69
|
+
- The path-allowlist (`resolveRealContainedPath`) limits **WHERE** scripts load from
|
|
70
|
+
(`.crew/workflows/`, `<proj>/.pi/teams/workflows/`, `~/.pi/agent/extensions/pi-crew/workflows/`),
|
|
71
|
+
not what they can do.
|
|
72
|
+
- `isolated-vm` (real V8 isolate) is planned for **v1.5**.
|
|
73
|
+
- **Only place `.dwf.ts` files you have reviewed** in `.crew/workflows/`.
|
|
74
|
+
|
|
75
|
+
`workflow-create` and `workflow-save` are arbitrary-code-execution (ACE) surfaces and are gated:
|
|
76
|
+
- Require `confirm:true` (enforced by `destructive-gate.ts` at the tool_call layer).
|
|
77
|
+
- **User-initiated only** — the agent MUST NOT auto-invoke them.
|
|
78
|
+
- Path-allowlisted via `resolveRealContainedPath` (TOCTOU-safe, not `startsWith`).
|
|
79
|
+
- Content validation rejects obvious `require('child_process')`, `process.exit`, and
|
|
80
|
+
network-import patterns — but this is **advisory only and trivially bypassable**
|
|
81
|
+
(e.g. `require('child'+'_process')`, `globalThis.process.mainModule.require`).
|
|
82
|
+
The real boundary is commit-review + the path-allowlist, not the content check.
|
|
83
|
+
|
|
84
|
+
## Isolation
|
|
85
|
+
|
|
86
|
+
Worker output → artifact file (via `runChildPi` + `writeArtifact`). The dynamic runner
|
|
87
|
+
holds results only in JS variables + `ctx.vars`. Only `ctx.setResult(artifactPath)` is
|
|
88
|
+
read back into the tool result returned to the main context — mirroring the static
|
|
89
|
+
workflow `summary.md` contract. The orchestrator's context never holds raw worker
|
|
90
|
+
output.
|
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
Date: 2026-05-18
|
|
4
4
|
|
|
5
|
-
## H1: Event-log silent loss
|
|
5
|
+
## H1: Event-log silent loss when exceeding MAX_EVENTS_BYTES (50MB)
|
|
6
6
|
|
|
7
7
|
### File
|
|
8
8
|
`src/state/event-log.ts`
|
|
9
9
|
|
|
10
|
-
###
|
|
11
|
-
|
|
10
|
+
### Problem
|
|
11
|
+
When the event log file exceeds 50MB, events are dropped immediately (including terminal events) but `appendCounter` is not incremented → compaction is never triggered.
|
|
12
12
|
|
|
13
|
-
### Fix
|
|
14
|
-
|
|
13
|
+
### Fix applied
|
|
14
|
+
In `appendEventInsideLock`:
|
|
15
15
|
|
|
16
|
-
1.
|
|
17
|
-
2. **Non-terminal events
|
|
18
|
-
3. **
|
|
19
|
-
4. **
|
|
20
|
-
5. **Terminal events
|
|
16
|
+
1. **Prioritize terminal events**: check `isTerminal = TERMINAL_EVENT_TYPES.has(fullEvent.type)` first
|
|
17
|
+
2. **Non-terminal events exceeding the limit** → call `compactEventLog()` immediately (don't wait for counter % 100)
|
|
18
|
+
3. **If still over the limit after compaction** → call `rotateEventLog()`
|
|
19
|
+
4. **Only drop the event** when a non-terminal event is still over the limit after compaction + rotation
|
|
20
|
+
5. **Terminal events are always persisted** regardless of size
|
|
21
21
|
|
|
22
22
|
```ts
|
|
23
23
|
const isTerminal = TERMINAL_EVENT_TYPES.has(fullEvent.type);
|
|
@@ -47,21 +47,21 @@ npm run typecheck # PASSED
|
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
50
|
-
## H2: Mailbox appendFileSync
|
|
50
|
+
## H2: Mailbox appendFileSync has no cross-process lock
|
|
51
51
|
|
|
52
52
|
### File
|
|
53
53
|
`src/state/mailbox.ts`
|
|
54
54
|
|
|
55
|
-
###
|
|
56
|
-
`appendMailboxMessage`
|
|
55
|
+
### Problem
|
|
56
|
+
`appendMailboxMessage` uses `fs.appendFileSync`, which is not atomic on Windows.
|
|
57
57
|
|
|
58
|
-
### Fix
|
|
59
|
-
Import
|
|
58
|
+
### Fix applied
|
|
59
|
+
Import and wrap the append in `withEventLogLockSync`:
|
|
60
60
|
|
|
61
61
|
```ts
|
|
62
62
|
import { withEventLogLockSync } from "./event-log.ts";
|
|
63
63
|
|
|
64
|
-
//
|
|
64
|
+
// In appendMailboxMessage:
|
|
65
65
|
withEventLogLockSync(mailboxFile(manifest, complete.direction, complete.taskId), () => {
|
|
66
66
|
fs.appendFileSync(mailboxFile(manifest, complete.direction, complete.taskId), `${JSON.stringify(redactSecrets(complete))}\n`, "utf-8");
|
|
67
67
|
});
|
|
@@ -83,4 +83,4 @@ npm run typecheck # PASSED
|
|
|
83
83
|
> npm run typecheck
|
|
84
84
|
> tsc --noEmit && node --experimental-strip-types -e "await import('./index.ts'); console.log('strip-types import ok')"
|
|
85
85
|
strip-types import ok
|
|
86
|
-
```
|
|
86
|
+
```
|