@gotgenes/pi-subagents 10.0.1 → 10.1.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.
@@ -0,0 +1,322 @@
1
+ ---
2
+ issue: 227
3
+ issue_title: "Evolve AgentRecord into Agent with behavior (Phase 15, Step 1)"
4
+ ---
5
+
6
+ # Evolve AgentRecord into Agent with behavior
7
+
8
+ ## Problem Statement
9
+
10
+ `AgentRecord` is an anemic domain model — it holds identity, status transitions, and stats but no behavior.
11
+ `AgentManager` reaches into records 37 times, performing work that belongs on the agent:
12
+
13
+ - **abort**: `AgentManager.abort()` checks `record.status`, calls `record.abortController?.abort()`, calls `record.markStopped()` — this is the agent aborting itself, but the logic lives on the manager.
14
+ - **pending steers**: per-agent steer buffers live in a manager-level `Map<string, string[]>`, not on the agent.
15
+ - **steer flushing**: `flushPendingSteers(id, session)` iterates the manager map — should be `agent.flushPendingSteers(session)`.
16
+ - **worktree setup**: `setupWorktree()` creates a worktree and attaches it to the record — the agent should set up its own worktree.
17
+
18
+ ## Goals
19
+
20
+ - Move per-agent behavior (`abort`, `queueSteer`/`flushPendingSteers`, `setupWorktree`) from `AgentManager` to the agent.
21
+ - `AgentManager` delegates to agents via Tell-Don't-Ask instead of reaching into records.
22
+ - Rename `AgentRecord` → `Agent`, `AgentRecordStatus` → `AgentStatus`, `AgentRecordInit` → `AgentInit` across the codebase.
23
+ - All changes are internal — the public `SubagentsService` API (`service.ts`) is unaffected.
24
+
25
+ ## Non-Goals
26
+
27
+ - **`RunHandle` ownership** — moves to `Agent` in #228, not here.
28
+ - **Async `startAgent`** — deferred to #228.
29
+ - **`onSessionCreated` observer** — deferred to #229.
30
+ - **`ConcurrencyQueue` extraction** — deferred to #230.
31
+ Queue removal logic stays on `AgentManager.abort()` until then.
32
+ - **Relay deps** — deferred to #231.
33
+ - **Resume unification** — deferred to #232.
34
+
35
+ ## Background
36
+
37
+ ### Relevant modules
38
+
39
+ | Module | Responsibility | Relationship to this change |
40
+ | ------------------------------------------ | ------------------------------------------------------- | ---------------------------------------------------------------------------------- |
41
+ | `src/lifecycle/agent-record.ts` (201 LOC) | Status state machine, stats accumulation | Gains behavior methods, renames to `agent.ts` |
42
+ | `src/lifecycle/agent-manager.ts` (541 LOC) | Agent collection, spawn, abort, queue, steer buffering | Loses private methods, delegates to agent |
43
+ | `src/lifecycle/worktree.ts` | `WorktreeManager` interface and git worktree operations | Agent calls `worktrees.create()` directly |
44
+ | `src/lifecycle/worktree-state.ts` | Per-agent worktree lifecycle state | Already attached to agent — `setupWorktree` formalizes this |
45
+ | `src/tools/steer-tool.ts` | LLM-facing steer tool | Calls `record.queueSteer()` directly instead of `manager.queueSteer()` |
46
+ | `src/service/service-adapter.ts` | Cross-extension API adapter | Calls `record.queueSteer()` directly; `queueSteer` removed from `AgentManagerLike` |
47
+ | `src/observation/record-observer.ts` | Session event → agent stats accumulation | Import rename only |
48
+ | `src/types.ts` | Internal re-exports | Re-export updates |
49
+ | `test/helpers/make-record.ts` | Shared test factory | Renames to `make-agent.ts`, factory → `createTestAgent()` |
50
+
51
+ ### Constraints
52
+
53
+ - The public export from `package.json` is `"./src/service.ts"` only — `AgentRecord` is internal, so the rename is not breaking for consumers.
54
+ - `WorktreeManager` is injected via the manager's constructor — `Agent.setupWorktree()` receives it as a parameter (no new constructor dependency).
55
+ - Queue removal in `abort()` stays on `AgentManager` because the queue is manager-owned until #230 extracts `ConcurrencyQueue`.
56
+
57
+ ## Design Overview
58
+
59
+ ### New methods on Agent
60
+
61
+ ```typescript
62
+ class Agent {
63
+ // Existing: markRunning, markCompleted, markAborted, markSteered, markError, markStopped,
64
+ // incrementToolUses, addUsage, incrementCompactions, resetForResume
65
+
66
+ // --- New behavior ---
67
+
68
+ /** Buffer a steer message for delivery once the session is ready. */
69
+ queueSteer(message: string): void;
70
+
71
+ /** Flush buffered steers to the session and clear the buffer. */
72
+ flushPendingSteers(session: AgentSession): void;
73
+
74
+ /** Abort a running agent: fire AbortController, transition to stopped. */
75
+ abort(): boolean;
76
+
77
+ /** Create a worktree for isolated execution. Throws if impossible. */
78
+ setupWorktree(worktrees: WorktreeManager, isolation: IsolationMode | undefined): string | undefined;
79
+ }
80
+ ```
81
+
82
+ ### Steer buffering moves to agent
83
+
84
+ Before: `AgentManager` owns `pendingSteers: Map<string, string[]>` and exposes `queueSteer(id, msg)`.
85
+ After: each `Agent` owns `private pendingSteers: string[] = []`.
86
+ Callers that already hold a record reference (steer tool, service adapter) call `agent.queueSteer(msg)` directly — the manager's `queueSteer` method and the `pendingSteers` map are removed.
87
+
88
+ Consumer call-site (steer tool):
89
+
90
+ ```typescript
91
+ // Before:
92
+ this.manager.queueSteer(record.id, params.message);
93
+ // After:
94
+ record.queueSteer(params.message);
95
+ ```
96
+
97
+ ### Abort moves to agent
98
+
99
+ `Agent.abort()` encapsulates the running-check + controller.abort + markStopped sequence:
100
+
101
+ ```typescript
102
+ abort(): boolean {
103
+ if (this._status !== "running") return false;
104
+ this.abortController?.abort();
105
+ this.markStopped();
106
+ return true;
107
+ }
108
+ ```
109
+
110
+ `AgentManager.abort(id)` retains queue-removal logic (queue is manager-owned until #230) and delegates the running case to `agent.abort()`.
111
+ `AgentManager.abortAll()` calls `agent.abort()` for running agents.
112
+
113
+ ### Worktree setup moves to agent
114
+
115
+ `Agent.setupWorktree(worktrees, isolation)` replaces `AgentManager.setupWorktree(id, record, isolation)`.
116
+ The agent creates the worktree, sets `this.worktreeState`, and returns the worktree path.
117
+ The error message for impossible worktree creation stays identical.
118
+
119
+ ### Rename strategy
120
+
121
+ The rename (`AgentRecord` → `Agent`) is the final step — a purely mechanical search-and-replace with no behavior change.
122
+ This keeps behavior-adding commits small and reviewable, then consolidates the rename noise into one commit.
123
+
124
+ Files affected by the rename:
125
+
126
+ | Layer | Files |
127
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
128
+ | Source (lifecycle) | `agent-record.ts` → `agent.ts`, `agent-manager.ts`, `execution-state.ts` |
129
+ | Source (observation) | `record-observer.ts`, `notification.ts` |
130
+ | Source (tools) | `agent-tool.ts`, `steer-tool.ts`, `get-result-tool.ts`, `background-spawner.ts`, `foreground-runner.ts` |
131
+ | Source (UI) | `agent-menu.ts`, `agent-creation-wizard.ts`, `conversation-viewer.ts` |
132
+ | Source (service) | `service-adapter.ts` |
133
+ | Source (types) | `types.ts` |
134
+ | Tests | `agent-record.test.ts` → `agent.test.ts`, `agent-manager.test.ts`, `record-observer.test.ts`, `steer-tool.test.ts`, `get-result-tool.test.ts`, `service-adapter.test.ts` |
135
+ | Test helpers | `make-record.ts` → `make-agent.ts` |
136
+
137
+ ## Module-Level Changes
138
+
139
+ ### `src/lifecycle/agent-record.ts` → `src/lifecycle/agent.ts`
140
+
141
+ 1. Add `private pendingSteers: string[] = []` field.
142
+ 2. Add `queueSteer(message: string): void` — pushes to `pendingSteers`.
143
+ 3. Add `flushPendingSteers(session: AgentSession): void` — iterates buffer, calls `session.steer()`, clears array.
144
+ 4. Add `abort(): boolean` — if running, fires controller and marks stopped.
145
+ 5. Add `setupWorktree(worktrees: WorktreeManager, isolation: IsolationMode | undefined): string | undefined` — creates worktree, sets `worktreeState`, returns path.
146
+ 6. Add import for `WorktreeState`, `WorktreeManager`, `IsolationMode`.
147
+ 7. Rename class `AgentRecord` → `Agent`, type `AgentRecordStatus` → `AgentStatus`, interface `AgentRecordInit` → `AgentInit`.
148
+
149
+ ### `src/lifecycle/agent-manager.ts`
150
+
151
+ 1. Remove `private pendingSteers = new Map<string, string[]>()`.
152
+ 2. Remove `queueSteer(id, message)` public method.
153
+ 3. Remove `private flushPendingSteers(id, session)` method.
154
+ 4. In `startAgent`'s `onSessionCreated` callback: replace `this.flushPendingSteers(id, session)` with `record.flushPendingSteers(session)`.
155
+ 5. Remove `private setupWorktree(id, record, isolation)` method.
156
+ 6. In `startAgent`: replace `this.setupWorktree(id, record, options.isolation)` with `record.setupWorktree(this.worktrees, options.isolation)`.
157
+ 7. Simplify `abort(id)`: delegate running case to `record.abort()`.
158
+ 8. Simplify `abortAll()`: call `record.abort()` for running agents.
159
+ 9. In `removeRecord`: remove `this.pendingSteers.delete(id)`.
160
+ 10. Update imports: `AgentRecord` → `Agent`, `AgentRecordInit` → `AgentInit` (if used).
161
+
162
+ ### `src/tools/steer-tool.ts`
163
+
164
+ 1. Remove `queueSteer` from `SteerToolManager` interface.
165
+ 2. Replace `this.manager.queueSteer(record.id, params.message)` with `record.queueSteer(params.message)`.
166
+ 3. Update import: `AgentRecord` → `Agent`.
167
+
168
+ ### `src/service/service-adapter.ts`
169
+
170
+ 1. Remove `queueSteer` from `AgentManagerLike` interface.
171
+ 2. In `steer()`: replace `this.manager.queueSteer(id, message)` with `record.queueSteer(message)` and return `true`.
172
+ 3. Update import: `AgentRecord` → `Agent`.
173
+
174
+ ### `src/types.ts`
175
+
176
+ 1. Update re-export: `AgentRecord` → `Agent`, source path `#src/lifecycle/agent-record` → `#src/lifecycle/agent`.
177
+
178
+ ### `src/observation/record-observer.ts`
179
+
180
+ 1. Update import and parameter types: `AgentRecord` → `Agent`.
181
+
182
+ ### `src/observation/notification.ts`
183
+
184
+ 1. Update import and parameter types: `AgentRecord` → `Agent`.
185
+
186
+ ### `src/tools/*.ts` (agent-tool, get-result-tool, background-spawner, foreground-runner)
187
+
188
+ 1. Update imports and type annotations: `AgentRecord` → `Agent`.
189
+
190
+ ### `src/ui/*.ts` (agent-menu, agent-creation-wizard, conversation-viewer)
191
+
192
+ 1. Update imports and type annotations: `AgentRecord` → `Agent`.
193
+
194
+ ### `test/helpers/make-record.ts` → `test/helpers/make-agent.ts`
195
+
196
+ 1. Rename file.
197
+ 2. Update imports: `AgentRecord` → `Agent`, `AgentRecordInit` → `AgentInit`.
198
+ 3. Rename factory: `createTestRecord` → `createTestAgent`.
199
+ 4. Update return type annotation.
200
+
201
+ ### `test/lifecycle/agent-record.test.ts` → `test/lifecycle/agent.test.ts`
202
+
203
+ 1. Rename file.
204
+ 2. Update import: `AgentRecord` → `Agent`.
205
+ 3. Update all `describe` block names and `new AgentRecord(...)` calls.
206
+ 4. Add new test blocks for `queueSteer`, `flushPendingSteers`, `abort`, `setupWorktree`.
207
+
208
+ ### `test/lifecycle/agent-manager.test.ts`
209
+
210
+ 1. Remove tests for `AgentManager.queueSteer` (behavior moved to agent).
211
+ 2. Update `abort()` tests to verify delegation.
212
+ 3. Update imports if `AgentRecord` type is referenced.
213
+
214
+ ### `test/tools/steer-tool.test.ts`
215
+
216
+ 1. Remove `queueSteer` from mock manager.
217
+ 2. Update "session not ready" test to verify `record.queueSteer()` is called.
218
+
219
+ ### `test/service/service-adapter.test.ts`
220
+
221
+ 1. Remove `queueSteer` from mock managers.
222
+ 2. Update steer tests to verify `record.queueSteer()`.
223
+
224
+ ### `packages/pi-subagents/docs/architecture/architecture.md`
225
+
226
+ 1. Update file listing: `agent-record.ts` → `agent.ts`.
227
+ 2. Update `AgentRecordInit` reference in interface width table.
228
+
229
+ ## Test Impact Analysis
230
+
231
+ ### New unit tests enabled by the extraction
232
+
233
+ 1. **`Agent.queueSteer()` / `Agent.flushPendingSteers()`** — isolated tests for steer buffering without needing a full `AgentManager` setup.
234
+ Previously the steer buffering was only testable via `AgentManager` integration tests.
235
+ 2. **`Agent.abort()`** — isolated tests for the abort state machine (running → stopped, not-running → no-op) without needing manager scaffolding.
236
+ 3. **`Agent.setupWorktree()`** — isolated tests for worktree creation and error handling with a mock `WorktreeManager`, without full spawn infrastructure.
237
+
238
+ ### Existing tests that become redundant
239
+
240
+ 1. `AgentManager — queueSteer` tests — the behavior is now tested directly on `Agent`.
241
+ The manager no longer has a `queueSteer` method.
242
+ 2. Parts of `AgentManager — abort` tests that verify controller.abort + markStopped — these are now `Agent.abort()` tests.
243
+ The manager abort tests should focus on queue-removal logic and delegation.
244
+
245
+ ### Existing tests that must stay
246
+
247
+ 1. `AgentManager — abort` tests for the "queued" case (queue removal is still manager-owned).
248
+ 2. `AgentManager — abortAll` tests (orchestrates both queue clearing and agent abort).
249
+ 3. All `AgentManager — spawn/spawnAndWait` tests — the spawn flow still lives on the manager.
250
+ 4. `steer-tool` and `service-adapter` tests for the steer path — updated to verify the new call pattern.
251
+
252
+ ## TDD Order
253
+
254
+ 1. **Red/Green: add `queueSteer()` and `flushPendingSteers()` to `AgentRecord`**
255
+ - Add tests in `agent-record.test.ts` for buffering and flushing steers.
256
+ - Implement the methods on `AgentRecord`.
257
+ - Commit: `feat(pi-subagents): add steer buffering to AgentRecord`
258
+
259
+ 2. **Refactor: delegate steer buffering from manager to agent**
260
+ - Remove `pendingSteers` map, `queueSteer()`, `flushPendingSteers()` from `AgentManager`.
261
+ - In `startAgent`'s `onSessionCreated`: call `record.flushPendingSteers(session)`.
262
+ - In `removeRecord`: remove `pendingSteers.delete(id)`.
263
+ - Update `steer-tool.ts`: remove `queueSteer` from `SteerToolManager`, call `record.queueSteer()`.
264
+ - Update `service-adapter.ts`: remove `queueSteer` from `AgentManagerLike`, call `record.queueSteer()`.
265
+ - Remove `AgentManager — queueSteer` tests; update steer-tool and service-adapter tests.
266
+ - Run `pnpm run check` to verify no type errors.
267
+ - Commit: `refactor(pi-subagents): delegate steer buffering from manager to agent`
268
+
269
+ 3. **Red/Green: add `abort()` to `AgentRecord`**
270
+ - Add tests in `agent-record.test.ts`: running → aborts and returns true; non-running → returns false; no controller → still marks stopped.
271
+ - Implement the method.
272
+ - Commit: `feat(pi-subagents): add abort() to AgentRecord`
273
+
274
+ 4. **Refactor: delegate abort from manager to agent**
275
+ - Simplify `AgentManager.abort()`: queued case stays, running case delegates to `record.abort()`.
276
+ - Simplify `AgentManager.abortAll()`: call `record.abort()` for running agents.
277
+ - Update manager abort tests to focus on queue removal and delegation.
278
+ - Commit: `refactor(pi-subagents): delegate abort from manager to agent`
279
+
280
+ 5. **Red/Green: add `setupWorktree()` to `AgentRecord`**
281
+ - Add tests in `agent-record.test.ts`: non-worktree returns undefined; worktree created → sets `worktreeState` and returns path; creation fails → throws.
282
+ - Implement the method (import `WorktreeState`, `WorktreeManager`, `IsolationMode`).
283
+ - Commit: `feat(pi-subagents): add setupWorktree() to AgentRecord`
284
+
285
+ 6. **Refactor: delegate worktree setup from manager to agent**
286
+ - Remove `private setupWorktree()` from `AgentManager`.
287
+ - In `startAgent`: replace `this.setupWorktree(id, record, options.isolation)` with `record.setupWorktree(this.worktrees, options.isolation)`.
288
+ - Update any tests that verify worktree setup delegation.
289
+ - Commit: `refactor(pi-subagents): delegate worktree setup from manager to agent`
290
+
291
+ 7. **Rename `AgentRecord` → `Agent` across codebase**
292
+ - Rename `src/lifecycle/agent-record.ts` → `src/lifecycle/agent.ts`.
293
+ - Rename class `AgentRecord` → `Agent`, type `AgentRecordStatus` → `AgentStatus`, interface `AgentRecordInit` → `AgentInit`.
294
+ - Update all source imports and type references (~20 source files).
295
+ - Rename `test/lifecycle/agent-record.test.ts` → `test/lifecycle/agent.test.ts`.
296
+ - Rename `test/helpers/make-record.ts` → `test/helpers/make-agent.ts`, factory `createTestRecord` → `createTestAgent`.
297
+ - Update all test imports and references (~10 test files).
298
+ - Rename `subscribeRecordObserver` → `subscribeAgentObserver` and `RecordObserverOptions` → `AgentObserverOptions` in `record-observer.ts`.
299
+ - Run `pnpm run check` and full test suite.
300
+ - Commit: `refactor(pi-subagents): rename AgentRecord to Agent`
301
+
302
+ 8. **Update architecture docs**
303
+ - Update `docs/architecture/architecture.md` file listing: `agent-record.ts` → `agent.ts`.
304
+ - Update `AgentRecordInit` → `AgentInit` in the interface width table.
305
+ - Update the Phase 15 Step 1 entry to reflect completion.
306
+ - Commit: `docs(pi-subagents): update architecture for Agent rename`
307
+
308
+ ## Risks and Mitigations
309
+
310
+ 1. **Large rename diff in step 7** — The rename touches ~30 files.
311
+ Mitigated by making it a purely mechanical change (no behavior change) in a dedicated commit, so reviewers can verify it's a clean rename.
312
+ 2. **Queue-removal leaks into agent** — `Agent.abort()` must NOT remove from the manager's queue (that's #230's concern).
313
+ Mitigated by scoping `Agent.abort()` to only handle the running case; `AgentManager.abort()` retains queue removal.
314
+ 3. **Interface changes cascade** — Removing `queueSteer` from `SteerToolManager` and `AgentManagerLike` requires updating test mocks.
315
+ Mitigated by handling interface changes and test updates in the same step (step 2).
316
+ 4. **Test factory rename ripple** — `createTestRecord` → `createTestAgent` touches many test files.
317
+ Mitigated by including this in the rename step (step 7), which is already a mechanical change.
318
+
319
+ ## Open Questions
320
+
321
+ None — the issue's proposed change is unambiguous and scoped.
322
+ `RunHandle` ownership and other Phase 15 steps are explicitly deferred to their own issues.
@@ -0,0 +1,37 @@
1
+ ---
2
+ issue: 227
3
+ issue_title: "Evolve AgentRecord into Agent with behavior (Phase 15, Step 1)"
4
+ ---
5
+
6
+ # Retro: #227 — Evolve AgentRecord into Agent with behavior
7
+
8
+ ## Stage: Planning (2026-05-27T12:00:00Z)
9
+
10
+ ### Session summary
11
+
12
+ Produced an 8-step TDD plan to move per-agent behavior (`abort`, `queueSteer`/`flushPendingSteers`, `setupWorktree`) from `AgentManager` into `AgentRecord`, then rename `AgentRecord` → `Agent` across the codebase.
13
+ The plan follows a "add behavior first, rename last" strategy to keep behavior diffs small and the rename commit purely mechanical.
14
+
15
+ ### Observations
16
+
17
+ - `AgentRecord` is internal-only (public API is `SubagentRecord` in `service.ts`), so the rename is non-breaking.
18
+ - The `queueSteer` method can be removed from `AgentManagerLike` and `SteerToolManager` interfaces entirely — both callers (`steer-tool`, `service-adapter`) already hold the agent reference from `getRecord()`, so they can call `agent.queueSteer()` directly.
19
+ - Queue removal in `abort()` must stay on `AgentManager` until #230 extracts `ConcurrencyQueue`.
20
+ - `RunHandle` ownership explicitly deferred to #228 — the plan does not touch `RunHandle` at all.
21
+ - The rename step (step 7) touches ~30 files but is purely mechanical; all behavior changes land in steps 1–6.
22
+
23
+ ## Stage: Implementation — TDD (2026-05-27T13:00:00Z)
24
+
25
+ ### Session summary
26
+
27
+ Completed all 8 TDD steps from the plan.
28
+ Added 9 new tests (steer buffering, `abort()`, `setupWorktree()`) and migrated 977 existing tests to the renamed `Agent` class.
29
+ Test count went from 977 to 986 across 62 test files.
30
+
31
+ ### Observations
32
+
33
+ - Fallow reported `AgentInit` and `AgentStatus` as unused type exports from `types.ts`; suppressed with `// fallow-ignore-next-line unused-type` (correct singular form — tool's error message hints at this).
34
+ - `ESLint` auto-removed an `as any` cast in the `setupWorktree` test (the mock `WorktreeManager` already satisfied the interface structurally); staged and re-committed cleanly.
35
+ - Biome auto-formatted several test files during the rename commit; re-staged and re-committed.
36
+ - Pre-completion reviewer returned **WARN** for 4 stale diagram/table references in `architecture.md` and the `package-pi-subagents` skill table; all fixed before the final commit.
37
+ - No deviations from the plan's behavior design; the `queueSteer` removal from manager interfaces worked exactly as anticipated in the retro notes.
@@ -35,3 +35,36 @@ A follow-up skill maintenance commit updated `.pi/skills/package-pi-subagents/SK
35
35
  - Pre-completion reviewer returned **WARN** for stale `package-pi-subagents` skill content: the "Patch 2 scheduled for removal" note and the `// Patch 2 (RepOne` grep instruction were both stale after #239 completion.
36
36
  Fixed immediately as a follow-up `docs:` commit before writing retro notes.
37
37
  - `pnpm fallow dead-code` passed with 0 issues — no orphaned exports left behind.
38
+
39
+ ## Stage: Final Retrospective (2026-05-27T14:40:00Z)
40
+
41
+ ### Session summary
42
+
43
+ Completed the full issue lifecycle (plan → TDD → ship → retro) in a single continuous session.
44
+ Issue #239 shipped as `pi-subagents-v10.0.1` with 7 commits (2 refactor, 4 docs, 1 release).
45
+ Phase 14 is now fully complete, unblocking Phase 15 (#227–#232).
46
+
47
+ ### Observations
48
+
49
+ #### What went well
50
+
51
+ - The plan's type-dependency-chain ordering (`SessionConfig` first → expected compile errors → `agent-runner.ts` resolves them) produced zero surprises during TDD.
52
+ Each step's red/green boundary was exactly where the plan predicted.
53
+ - Pre-completion reviewer caught stale `package-pi-subagents` skill content ("Patch 2 scheduled for removal" and a `// Patch 2 (RepOne` grep instruction) that no longer matched source.
54
+ Fixed before shipping — the reviewer earned its keep.
55
+ - Multi-model routing was well-matched: `claude-sonnet-4-6` for planning and TDD (judgment + code), `deepseek-v4-flash` for shipping (mechanical checklist), `claude-opus-4-6` for retrospective (synthesis).
56
+ - Feedback loops were incremental: `pnpm vitest run` after each test change, `pnpm run check` after Step 1 to confirm expected errors, full suite + lint + dead-code after all steps.
57
+
58
+ #### What caused friction (agent side)
59
+
60
+ No friction points identified.
61
+ This was the final step of a 3-step phase with both dependencies already closed, a well-scoped plan, and internal-only API changes — the simplest possible lifecycle.
62
+
63
+ #### What caused friction (user side)
64
+
65
+ None observed.
66
+ The user's involvement was limited to issuing the four standard lifecycle commands (`/plan-issue`, `/tdd-plan`, `/ship-issue`, `/retro`) with no corrections or redirections needed.
67
+
68
+ ### Changes made
69
+
70
+ 1. Appended Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0239-collapse-filter-active-tools.md`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gotgenes/pi-subagents",
3
- "version": "10.0.1",
3
+ "version": "10.1.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/service.ts"