@gotgenes/pi-subagents 18.0.0 → 18.0.2
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 +14 -0
- package/README.md +22 -31
- package/docs/architecture/architecture.md +157 -204
- package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
- package/package.json +5 -6
- package/src/lifecycle/subagent.ts +5 -9
- package/src/observation/notification.ts +23 -10
- package/src/observation/subagent-events-observer.ts +1 -3
- package/src/tools/get-result-report.ts +60 -0
- package/src/tools/get-result-tool.ts +25 -40
- package/src/types.ts +1 -1
- package/src/ui/session-navigator.ts +0 -2
- package/.prettierignore +0 -5
- package/AGENTS.md +0 -7
- package/docs/plans/0048-implement-subagents-api.md +0 -304
- package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
- package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
- package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
- package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
- package/docs/plans/0054-decompose-index-into-modules.md +0 -302
- package/docs/plans/0057-structured-debug-logging.md +0 -154
- package/docs/plans/0061-session-format-transcript.md +0 -284
- package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
- package/docs/plans/0069-create-subagent-runtime.md +0 -345
- package/docs/plans/0070-extract-event-handlers.md +0 -306
- package/docs/plans/0071-extract-session-config-assembler.md +0 -362
- package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
- package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
- package/docs/plans/0077-inject-project-agents-dir.md +0 -115
- package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
- package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
- package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
- package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
- package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
- package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
- package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
- package/docs/plans/0108-extract-agent-type-registry.md +0 -322
- package/docs/plans/0109-extract-settings-manager.md +0 -276
- package/docs/plans/0110-agent-activity-tracker.md +0 -297
- package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
- package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
- package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
- package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
- package/docs/plans/0115-decompose-agent-tool.md +0 -337
- package/docs/plans/0116-type-housekeeping.md +0 -351
- package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
- package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
- package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
- package/docs/plans/0132-inject-io-into-session-config.md +0 -219
- package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
- package/docs/plans/0134-reduce-as-any-casts.md +0 -366
- package/docs/plans/0135-extract-display-helpers.md +0 -182
- package/docs/plans/0136-decompose-agent-menu.md +0 -300
- package/docs/plans/0144-consolidate-observation-model.md +0 -263
- package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
- package/docs/plans/0146-narrow-ui-context.md +0 -319
- package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
- package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
- package/docs/plans/0152-add-prompt-snippet.md +0 -91
- package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
- package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
- package/docs/plans/0166-extract-parent-session-info.md +0 -231
- package/docs/plans/0167-narrow-runner-io.md +0 -150
- package/docs/plans/0168-extract-tool-filter-config.md +0 -173
- package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
- package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
- package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
- package/docs/plans/0172-extract-turn-formatting.md +0 -206
- package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
- package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
- package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
- package/docs/plans/0192-define-session-context-interface.md +0 -107
- package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
- package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
- package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
- package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
- package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
- package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
- package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
- package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
- package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
- package/docs/plans/0215-decompose-build-parent-context.md +0 -166
- package/docs/plans/0216-decompose-start-agent.md +0 -255
- package/docs/plans/0217-extract-overwrite-guard.md +0 -176
- package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
- package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
- package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
- package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
- package/docs/plans/0229-agent-born-complete.md +0 -564
- package/docs/plans/0230-extract-concurrency-queue.md +0 -265
- package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
- package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
- package/docs/plans/0237-remove-disallowed-tools.md +0 -180
- package/docs/plans/0238-remove-extensions-filtering.md +0 -191
- package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
- package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
- package/docs/plans/0256-extract-worktree-isolation.md +0 -256
- package/docs/plans/0257-extract-child-session-factory.md +0 -285
- package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
- package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
- package/docs/plans/0265-born-complete-subagent-session.md +0 -333
- package/docs/plans/0270-type-consumable-public-surface.md +0 -204
- package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
- package/docs/plans/0277-encapsulate-agent-session.md +0 -304
- package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
- package/docs/plans/0360-custom-agents-default-append.md +0 -132
- package/docs/plans/0373-extract-subagent-state.md +0 -250
- package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
- package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
- package/docs/plans/0376-extract-manager-observer.md +0 -232
- package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
- package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
- package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
- package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
- package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
- package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
- package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
- package/docs/plans/0412-unify-session-mock-builders.md +0 -146
- package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
- package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
- package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
- package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
- package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
- package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
- package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
- package/docs/plans/0427-reconsider-ui-direction.md +0 -212
- package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
- package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
- package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
- package/docs/plans/0445-native-session-navigation.md +0 -365
- package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
- package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
- package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
- package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
- package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
- package/docs/retro/0048-implement-subagents-api.md +0 -44
- package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
- package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
- package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
- package/docs/retro/0054-decompose-index-into-modules.md +0 -53
- package/docs/retro/0057-structured-debug-logging.md +0 -77
- package/docs/retro/0061-session-format-transcript.md +0 -41
- package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
- package/docs/retro/0069-create-subagent-runtime.md +0 -43
- package/docs/retro/0070-extract-event-handlers.md +0 -49
- package/docs/retro/0071-extract-session-config-assembler.md +0 -60
- package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
- package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
- package/docs/retro/0077-inject-project-agents-dir.md +0 -33
- package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
- package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
- package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
- package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
- package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
- package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
- package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
- package/docs/retro/0108-extract-agent-type-registry.md +0 -41
- package/docs/retro/0109-extract-settings-manager.md +0 -55
- package/docs/retro/0110-agent-activity-tracker.md +0 -44
- package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
- package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
- package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
- package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
- package/docs/retro/0115-decompose-agent-tool.md +0 -51
- package/docs/retro/0116-type-housekeeping.md +0 -42
- package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
- package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
- package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
- package/docs/retro/0132-inject-io-into-session-config.md +0 -33
- package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
- package/docs/retro/0134-reduce-as-any-casts.md +0 -56
- package/docs/retro/0135-extract-display-helpers.md +0 -38
- package/docs/retro/0136-decompose-agent-menu.md +0 -43
- package/docs/retro/0144-consolidate-observation-model.md +0 -39
- package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
- package/docs/retro/0146-narrow-ui-context.md +0 -70
- package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
- package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
- package/docs/retro/0152-add-prompt-snippet.md +0 -34
- package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
- package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
- package/docs/retro/0166-extract-parent-session-info.md +0 -66
- package/docs/retro/0167-narrow-runner-io.md +0 -63
- package/docs/retro/0168-extract-tool-filter-config.md +0 -76
- package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
- package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
- package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
- package/docs/retro/0172-extract-turn-formatting.md +0 -80
- package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
- package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
- package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
- package/docs/retro/0192-define-session-context-interface.md +0 -59
- package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
- package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
- package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
- package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
- package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
- package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
- package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
- package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
- package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
- package/docs/retro/0215-decompose-build-parent-context.md +0 -61
- package/docs/retro/0216-decompose-start-agent.md +0 -80
- package/docs/retro/0217-extract-overwrite-guard.md +0 -63
- package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
- package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
- package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
- package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
- package/docs/retro/0229-agent-born-complete.md +0 -89
- package/docs/retro/0230-extract-concurrency-queue.md +0 -38
- package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
- package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
- package/docs/retro/0237-remove-disallowed-tools.md +0 -78
- package/docs/retro/0238-remove-extensions-filtering.md +0 -72
- package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
- package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
- package/docs/retro/0256-extract-worktree-isolation.md +0 -89
- package/docs/retro/0257-extract-child-session-factory.md +0 -33
- package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
- package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
- package/docs/retro/0265-born-complete-subagent-session.md +0 -97
- package/docs/retro/0270-type-consumable-public-surface.md +0 -108
- package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
- package/docs/retro/0277-encapsulate-agent-session.md +0 -80
- package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
- package/docs/retro/0360-custom-agents-default-append.md +0 -81
- package/docs/retro/0373-extract-subagent-state.md +0 -94
- package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
- package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
- package/docs/retro/0376-extract-manager-observer.md +0 -81
- package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
- package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
- package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
- package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
- package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
- package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
- package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
- package/docs/retro/0412-unify-session-mock-builders.md +0 -80
- package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
- package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
- package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
- package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
- package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
- package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
- package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
- package/docs/retro/0427-reconsider-ui-direction.md +0 -102
- package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -45
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
- package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
- package/docs/retro/0445-native-session-navigation.md +0 -122
- package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
- package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
- package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
- package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
- package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
- package/src/observation/notification-state.ts +0 -27
- package/vitest.config.ts +0 -14
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 207
|
|
3
|
-
issue_title: "Decompose update in agent-widget.ts (cognitive 31)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #207 — Decompose `update` in `agent-widget.ts`
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T04:12:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the decomposition of `update` (cognitive complexity 31) into an exported pure `assembleWidgetState` function, a `clearWidget` method, and an `updateStatusBar` method.
|
|
13
|
-
The plan follows the Phase 12 pattern established by Steps 1 and 2 (#205, #206) — extract pure functions where possible, otherwise extract methods, and simplify the original function to a thin orchestrator.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The sibling plans (#205, #206) provided a clear template for this plan — structure, section ordering, and test impact analysis all followed the established pattern.
|
|
18
|
-
- There are **no existing tests** for `AgentWidget` — the only testable concern is the newly extracted `assembleWidgetState` pure function.
|
|
19
|
-
The rest of the refactoring is a mechanical extraction verified by the type checker.
|
|
20
|
-
- `categorizeAgents` in `widget-renderer.ts` does a similar filter but returns full arrays (for rendering), while `assembleWidgetState` returns lightweight counts (for lifecycle decisions).
|
|
21
|
-
Different outputs for different consumers — no duplication concern.
|
|
22
|
-
- No `ask_user` was needed — the issue's "Proposed change" section was unambiguous and the design pattern was well-established by the two preceding Phase 12 steps.
|
|
23
|
-
|
|
24
|
-
## Stage: Planning — revision (2026-05-25T16:00:00Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
Reviewed and revised the prior plan after a thorough code audit of `agent-widget.ts`, `widget-renderer.ts`, `agent-record.ts`, and `runtime.ts`.
|
|
29
|
-
Three design changes were made to the original plan.
|
|
30
|
-
|
|
31
|
-
### Observations
|
|
32
|
-
|
|
33
|
-
- **Narrowed the input type:** Changed `assembleWidgetState` from accepting `WidgetAgent[]` (10+ fields) to a local `AgentSummary` interface (3 fields: `id`, `status`, `completedAt?`).
|
|
34
|
-
The original plan violated ISP — the function only reads 3 fields, so requiring full `WidgetAgent` fixtures in tests would be needless friction.
|
|
35
|
-
`AgentRecord` satisfies `AgentSummary` structurally, so no adapter is needed at the call site.
|
|
36
|
-
- **Kept `dispose` independent:** The original plan made `dispose` delegate to `clearWidget`, but `dispose` and `update`'s idle path have different lifecycle semantics — `dispose` uses unconditional teardown (correctness guarantee), while `update`'s idle path uses guarded calls (avoiding redundant SDK calls during repeated ticks).
|
|
37
|
-
`dispose` also skips stale-entry cleanup (the Map is about to be GC'd).
|
|
38
|
-
Per the code-design skill's Sandi Metz principle, this is structural duplication that should not be extracted.
|
|
39
|
-
- **Added complexity budget table:** Explicitly estimated cognitive complexity for each extracted function to verify the < 10 target is achievable across the board.
|
|
40
|
-
|
|
41
|
-
## Stage: Implementation — TDD (2026-05-25T13:10:00Z)
|
|
42
|
-
|
|
43
|
-
### Session summary
|
|
44
|
-
|
|
45
|
-
Completed all three TDD steps from the plan.
|
|
46
|
-
`assembleWidgetState` was extracted and tested with 16 unit tests covering all status combinations; `clearWidget` and `updateStatusBar` were extracted as private methods simplifying `update` to a thin orchestrator.
|
|
47
|
-
Test count went from 868 to 884 (+16 tests across 55 files, up from 54).
|
|
48
|
-
|
|
49
|
-
### Observations
|
|
50
|
-
|
|
51
|
-
- No deviations from the plan.
|
|
52
|
-
The non-null assertion (`this.uiCtx!`) in `clearWidget` and `updateStatusBar` is safe because both methods are only called from `update` after the `if (!this.uiCtx) return` guard.
|
|
53
|
-
- The `AgentSummary` interface and narrow test fixtures worked exactly as planned — test objects are plain 3-field literals, no `createTestRecord` needed.
|
|
54
|
-
- The complexity hotspots table in `architecture.md` now has no rows (both `renderWidgetLines` from #205 and `update` from this issue are resolved).
|
|
55
|
-
The section note was updated to reflect that Phase 12 cleared all critical hotspots.
|
|
56
|
-
- `pnpm fallow dead-code` (from repo root) passed with no issues.
|
|
57
|
-
|
|
58
|
-
## Stage: Final Retrospective (2026-05-25T13:15:00Z)
|
|
59
|
-
|
|
60
|
-
### Session summary
|
|
61
|
-
|
|
62
|
-
Issue #207 shipped as `pi-subagents-v7.3.0` with zero deviations from the revised plan.
|
|
63
|
-
The session covered plan revision, TDD implementation (16 new tests, 868 → 884), shipping, and CI verification.
|
|
64
|
-
|
|
65
|
-
### Observations
|
|
66
|
-
|
|
67
|
-
#### What went well
|
|
68
|
-
|
|
69
|
-
- The plan revision caught three real design issues before implementation started: ISP violation in the function parameter type, incorrect `dispose` → `clearWidget` delegation, and missing complexity budget.
|
|
70
|
-
Fixing these upfront meant the TDD execution had zero deviations and zero rework.
|
|
71
|
-
- The narrow `AgentSummary` type (3 fields) made test fixtures trivial plain objects — no `createTestRecord` or factory infrastructure needed.
|
|
72
|
-
This validated the ISP improvement concretely.
|
|
73
|
-
- The `dispose` independence decision (Sandi Metz principle applied to lifecycle semantics) kept `dispose` at its current 10-line simplicity while `clearWidget` got its own guarded teardown logic.
|
|
74
|
-
|
|
75
|
-
#### What caused friction (agent side)
|
|
76
|
-
|
|
77
|
-
- `missing-context` — The original planning session (prior to this one) used `WidgetAgent[]` as the input type without checking which fields `assembleWidgetState` actually reads.
|
|
78
|
-
The `code-design` skill already says "do not pass a shared dependency bag to functions that only use a subset of it" but the principle wasn't applied to the proposed function signature.
|
|
79
|
-
Impact: required a full plan revision session; no rework in implementation because it was caught before TDD started.
|
|
80
|
-
- `wrong-abstraction` — The original plan proposed `dispose` → `clearWidget` delegation as "eliminating duplication" without evaluating whether the two methods have the same lifecycle semantics.
|
|
81
|
-
`dispose` uses unconditional teardown (shutdown correctness); `clearWidget` uses guarded calls (avoiding redundant SDK calls during repeated timer ticks).
|
|
82
|
-
Impact: same as above — caught in revision, no implementation rework.
|
|
83
|
-
|
|
84
|
-
#### What caused friction (user side)
|
|
85
|
-
|
|
86
|
-
- The user's "I don't yet trust the plan" intervention was the key moment that improved the design.
|
|
87
|
-
Without it, the plan would have been implemented with the wider type and the `dispose` delegation.
|
|
88
|
-
This was effective judgment — the user identified that a mechanical plan for a mechanical refactoring still warranted critical design review.
|
|
89
|
-
|
|
90
|
-
### Changes made
|
|
91
|
-
|
|
92
|
-
1. Added two sentences to `.pi/prompts/plan-issue.md` Design Overview section: ISP check for new function parameter types, and structural-duplication check when consolidating methods into a shared helper.
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 208
|
|
3
|
-
issue_title: "Extract shared test fixtures to reduce test duplication"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #208 — Extract shared test fixtures to reduce test duplication
|
|
7
|
-
|
|
8
|
-
## Stage: Final Retrospective (2026-05-25T22:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Reviewed the planning, TDD, and shipping sessions for issue #208.
|
|
13
|
-
The work completed Phase 12 of the pi-subagents improvement roadmap.
|
|
14
|
-
Identified Vitest v4 type compatibility as the dominant friction pattern, and the user surfaced a strategic insight: shared test factories are treating symptoms of ISP violations in production interfaces.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
#### What went well
|
|
19
|
-
|
|
20
|
-
- The planning session's duplication diff (comparing default values across all copies before writing the shared factory) prevented cascading assertion failures during migration — the testing skill rule paid off.
|
|
21
|
-
- Using a Python script for the `agent-manager.test.ts` spawn consolidation (step 9) handled 42 multi-line replacements with 7 distinct patterns cleanly in one pass.
|
|
22
|
-
- `pnpm run check` caught 4 separate type errors that Vitest's esbuild would have silently ignored at runtime: wrong `findAgentFile` parameter type, dropped `AgentConfig` import, unused `@ts-expect-error` directives, and `Mock<Procedure>` incompatibility.
|
|
23
|
-
|
|
24
|
-
#### What caused friction (agent side)
|
|
25
|
-
|
|
26
|
-
1. `missing-context` — Wrote `vi.fn().mockReturnValue([])` in the shared factory without checking whether `Mock<Procedure>` is structurally assignable to the production function signatures (`RunnerIO`, `AgentFileOps`).
|
|
27
|
-
The testing skill warns about `ReturnType<typeof vi.fn>` at the field level, but I didn't connect this to the structural-compatibility scenario where a factory's return value flows to a typed production parameter.
|
|
28
|
-
Impact: 37 type errors after step 2, requiring a fixup commit (2953adc) and removal of the `assemblerOverrides` parameter.
|
|
29
|
-
2. `missing-context` — Assumed `findAgentFile` took `(dir: string, name: string)` based on test usage patterns rather than checking the `AgentFileOps` interface.
|
|
30
|
-
The actual signature is `(name: string, dirs: string[])` — the second parameter is `string[]`.
|
|
31
|
-
Impact: caught by `pnpm run check`, fixed in the same commit, no rework.
|
|
32
|
-
3. `scope-drift` — Removed `import type { AgentConfig }` from `agent-config-editor.test.ts` because the symbols it was needed for (`testDefaultConfig`, `testCustomConfig`) were being removed.
|
|
33
|
-
Didn't check that `buildEjectContent` tests 400 lines later also used `AgentConfig`.
|
|
34
|
-
Impact: caught by `pnpm run check`, one-line fix, no rework.
|
|
35
|
-
4. `premature-convergence` — Added `@ts-expect-error` directives for `.mock` property access in the factory tests, assuming TypeScript wouldn't know about Mock's `.mock` property.
|
|
36
|
-
Once the `vi.fn()` stubs were typed with implementations, TypeScript recognized the Mock type and `.mock` was accessible, making all 5 directives unused.
|
|
37
|
-
Impact: added friction but no rework — eslint caught them.
|
|
38
|
-
|
|
39
|
-
#### What caused friction (user side)
|
|
40
|
-
|
|
41
|
-
- No friction caused by the user.
|
|
42
|
-
The user's post-ship reflection ("we need to eliminate complex setup, right?") was a strategic insight that elevated the conversation from mechanical duplication reduction to ISP-driven interface narrowing.
|
|
43
|
-
This kind of mid-session reframing is valuable and came at exactly the right time — after the work was done, so it informs future phases rather than disrupting the current one.
|
|
44
|
-
|
|
45
|
-
#### Phase 13 guidance: ISP narrowing targets
|
|
46
|
-
|
|
47
|
-
The `test/helpers/` factory inventory is a concrete map of production interfaces worth narrowing:
|
|
48
|
-
|
|
49
|
-
| Factory | Production interface | Methods | Consumer usage |
|
|
50
|
-
| ------------------- | ------------------------------------------------------------- | ----------------------------- | -------------------------------- |
|
|
51
|
-
| `createRunnerIO` | `RunnerIO` (`EnvironmentIO & SessionFactoryIO`) | 8 (7 functions + assemblerIO) | Most tests use 2–3 |
|
|
52
|
-
| `makeFileOps` | `AgentFileOps` | 6 | Most tests use `exists` + `read` |
|
|
53
|
-
| `createToolDeps` | `AgentToolManager` + `AgentToolRuntime` + `AgentToolSettings` | 12+ across 3 interfaces | Spawners use 2–3 each |
|
|
54
|
-
| `createMockSession` | `AgentSession` (SDK class) | 5 stubs | Observers use `subscribe` only |
|
|
55
|
-
| `createAgentLookup` | `AgentConfigLookup` | 2 | Already narrow ✓ |
|
|
56
|
-
|
|
57
|
-
When a factory needs its own unit tests, the interface it stubs is too wide for its consumers.
|
|
58
|
-
The fix is ISP narrowing of the production interface, not more test infrastructure.
|
|
59
|
-
|
|
60
|
-
### Changes made
|
|
61
|
-
|
|
62
|
-
1. Added rule to `testing` skill: typed implementations in shared factories when return value satisfies a production interface.
|
|
63
|
-
2. Added ISP signal to `improvement-discovery` skill Category D table: shared factory complexity → narrow the production interface.
|
|
64
|
-
|
|
65
|
-
## Stage: Implementation — TDD (2026-05-25T21:00:00Z)
|
|
66
|
-
|
|
67
|
-
### Session summary
|
|
68
|
-
|
|
69
|
-
Completed all 10 TDD steps plus a type-fix commit.
|
|
70
|
-
Created 4 new files (`runner-io.ts`, `runner-io.test.ts`, `ui-stubs.ts`, `ui-stubs.test.ts`) and migrated 7 existing test files.
|
|
71
|
-
Test count grew from 884 → 913 (+29 tests in new helper unit tests).
|
|
72
|
-
|
|
73
|
-
### Observations
|
|
74
|
-
|
|
75
|
-
- Vitest v4 changed `vi.fn()` without implementation annotation to type `Mock<Procedure | Constructable>`, which is NOT assignable to specific function signatures in production interfaces.
|
|
76
|
-
The fix was to add typed implementation annotations (`vi.fn((_path: string): boolean => false)`) to all vi.fn() stubs in the shared factories.
|
|
77
|
-
This was a new friction point not anticipated in the plan.
|
|
78
|
-
- The plan's `assemblerOverrides` parameter in `createRunnerIO()` was removed because the `??` union typing caused `Mock<Procedure | Constructable> | Mock<specific-fn>` which TypeScript couldn't resolve as assignable to `RunnerIO`.
|
|
79
|
-
No consumer test actually used the override parameter, so removing it simplified both the implementation and the type story.
|
|
80
|
-
- The `findAgentFile` signature in `AgentFileOps` is `(name: string, dirs: string[])` — the second parameter is `string[]`, not a second string as initially assumed from test patterns.
|
|
81
|
-
This was caught by `pnpm run check`.
|
|
82
|
-
- The `agent-config-editor.test.ts` migration removed the `import type { AgentConfig }` import that was still needed by `buildEjectContent` tests further down the file.
|
|
83
|
-
Also caught by `pnpm run check`.
|
|
84
|
-
- `STUB_SNAPSHOT` replacement was safe: no consumer test asserts on snapshot field values.
|
|
85
|
-
The `mockSnapshot` in `agent-manager.test.ts` had `systemPrompt: "parent prompt"` vs `STUB_SNAPSHOT`'s `"test prompt"` but this caused no test failures.
|
|
86
|
-
- Architecture doc was updated to reference `test/helpers/` (correcting `test/fixtures/` from the original entry).
|
|
87
|
-
|
|
88
|
-
## Stage: Planning (2026-05-25T20:00:00Z)
|
|
89
|
-
|
|
90
|
-
### Session summary
|
|
91
|
-
|
|
92
|
-
Analyzed the three heaviest test clone families identified by fallow and designed a 10-step TDD plan to extract shared factories into `test/helpers/`.
|
|
93
|
-
Decided to follow the existing `test/helpers/` convention rather than the `test/fixtures/` directory mentioned in the issue and architecture doc.
|
|
94
|
-
|
|
95
|
-
### Observations
|
|
96
|
-
|
|
97
|
-
- Issue #131 (closed) already extracted `createMockSession`, `createToolDeps`, and `createTestRecord` — this issue targets the remaining duplication.
|
|
98
|
-
- The `createRunnerIO` factory in `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` includes stale `buildMemoryBlock` and `buildReadOnlyMemoryBlock` stubs that no longer match the `AssemblerIO` interface — the shared factory will clean these up as a side benefit.
|
|
99
|
-
- Session mock factories in the runner tests are structurally specialized (each serves a different test purpose) and were explicitly scoped as non-goals — extracting them would create a confusing multi-mode factory.
|
|
100
|
-
- The `agent-runner-extension-tools.test.ts` uses a mutable `agentConfigMock.current` pattern that doesn't fit into a shared static factory — only `createRunnerIO` is shared from that file.
|
|
101
|
-
- `STUB_SNAPSHOT` from `stub-ctx.ts` can replace all 5 local `ParentSnapshot` definitions — verified no test asserts on the specific field values.
|
|
102
|
-
- The `agent-manager.test.ts` internal duplication (~42 repetitive spawn calls) is best handled with local `spawnBg()`/`spawnFg()` helpers rather than cross-file extraction.
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 214
|
|
3
|
-
issue_title: "Convert remaining closure factories to classes (Phase 13, Step 1)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #214 — Convert remaining closure factories to classes
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T20:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 4-step TDD plan to convert the three remaining closure factories (`createAgentConfigEditor`, `createAgentCreationWizard`, `createSubagentsService`) to classes.
|
|
13
|
-
Each conversion is one commit covering source, test, and consumer updates together.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The conversions are entirely mechanical — same pattern as Phase 11 (#195, #196).
|
|
18
|
-
No design ambiguity requiring user input.
|
|
19
|
-
- `AgentCreationWizardDeps` is only used within its own file, so removing it is safe.
|
|
20
|
-
The class dissolves the deps bag into positional constructor params for consistency with `AgentConfigEditor`.
|
|
21
|
-
- The `agent-creation-wizard.test.ts` has ~18 inline `createAgentCreationWizard(deps)` calls; the plan suggests adding a `makeWizard(deps)` helper to centralize construction and reduce the diff size.
|
|
22
|
-
- `SubagentsServiceAdapter` uses `implements SubagentsService` for compile-time verification, unlike the factory which relied on structural typing of the returned object literal.
|
|
23
|
-
- Pure helper functions (`buildMenuOptions`, `buildEjectContent`, `toSubagentRecord`) and narrow interfaces (`AgentManagerLike`, `ServiceRuntimeLike`, `WizardManager`, `WizardRegistry`) remain unchanged.
|
|
24
|
-
|
|
25
|
-
## Stage: Implementation — TDD (2026-05-25T21:00:00Z)
|
|
26
|
-
|
|
27
|
-
### Session summary
|
|
28
|
-
|
|
29
|
-
All 4 TDD steps completed in 4 commits.
|
|
30
|
-
Three closure factories converted to classes (`AgentConfigEditor`, `AgentCreationWizard`, `SubagentsServiceAdapter`) with tests and consumers updated in the same commit as each production change.
|
|
31
|
-
Test count held at 913 (57 files) — no new tests needed, no tests removed.
|
|
32
|
-
|
|
33
|
-
### Observations
|
|
34
|
-
|
|
35
|
-
- All three conversions were mechanical find-and-replace with no behavioral surprises.
|
|
36
|
-
- The `makeWizard(deps)` helper in `agent-creation-wizard.test.ts` centralized 14 inline `createAgentCreationWizard(deps)` calls, keeping the diff readable.
|
|
37
|
-
- `SubagentsServiceAdapter` uses `implements SubagentsService` — the TypeScript compiler confirmed the contract at compile time with no gaps.
|
|
38
|
-
- Adding the `SpawnOptions` import to `service-adapter.ts` was required for the `spawn` method signature; the plan anticipated this correctly.
|
|
39
|
-
- The `sed -i` command required the macOS `-i ''` form (no in-place backup extension) rather than the GNU `sed -i` form.
|
|
40
|
-
- Dead-code gate (`pnpm fallow dead-code`) passed cleanly from the repo root — no suppression needed.
|
|
41
|
-
|
|
42
|
-
## Stage: Final Retrospective (2026-05-25T22:00:00Z)
|
|
43
|
-
|
|
44
|
-
### Session summary
|
|
45
|
-
|
|
46
|
-
Shipped `pi-subagents-v7.3.2` with 3 refactor commits converting all remaining closure factories to classes.
|
|
47
|
-
All 4 lifecycle stages (plan → TDD → ship → retro) completed in a single day with zero rework and zero deviations from the plan.
|
|
48
|
-
|
|
49
|
-
### Observations
|
|
50
|
-
|
|
51
|
-
#### What went well
|
|
52
|
-
|
|
53
|
-
- Strong precedent from Phase 11 (#195, #196) made this issue zero-friction — the plan, implementation, and test updates all followed an established template.
|
|
54
|
-
- The plan's prediction of a `makeWizard(deps)` helper for `agent-creation-wizard.test.ts` kept the step-2 diff readable by centralizing 14 inline constructor calls.
|
|
55
|
-
- `SubagentsServiceAdapter implements SubagentsService` gave compile-time contract verification, catching any interface drift immediately via `pnpm run check`.
|
|
56
|
-
- The plan correctly anticipated the `SpawnOptions` import need in `service-adapter.ts`.
|
|
57
|
-
|
|
58
|
-
#### What caused friction (agent side)
|
|
59
|
-
|
|
60
|
-
- None.
|
|
61
|
-
This was a textbook mechanical refactoring with no behavioral changes, no edge cases, and no test rework.
|
|
62
|
-
|
|
63
|
-
#### What caused friction (user side)
|
|
64
|
-
|
|
65
|
-
- None.
|
|
66
|
-
The issue was well-scoped with explicit target files and a clear precedent to follow.
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 215
|
|
3
|
-
issue_title: "Decompose buildParentContext (cognitive 30) (Phase 13, Step 2)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #215 — Decompose buildParentContext
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T12:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 3-step TDD plan to decompose `buildParentContext` in `src/session/context.ts`.
|
|
13
|
-
Steps 1–2 add tests locking current behavior for `extractText` and `buildParentContext`; step 3 extracts three private helpers (`formatMessageEntry`, `formatCompactionEntry`, `formatBranchEntry`) and simplifies the orchestrator to map/filter/join.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- No existing unit tests cover `context.ts` — `parent-snapshot.test.ts` mocks `buildParentContext` entirely, so the formatting logic is currently untested.
|
|
18
|
-
- The decomposition is straightforward with no design ambiguity; the architecture roadmap specifies the exact extraction targets.
|
|
19
|
-
- All extracted helpers remain private (not exported), keeping the public API surface unchanged.
|
|
20
|
-
- The `eslint-disable` comment on the `getBranch()` nullability check must be preserved through the refactoring step.
|
|
21
|
-
|
|
22
|
-
## Stage: Implementation — TDD (2026-05-25T22:36:00Z)
|
|
23
|
-
|
|
24
|
-
### Session summary
|
|
25
|
-
|
|
26
|
-
Completed all 3 TDD steps: 2 test-only commits locking `extractText` (5 tests) and `buildParentContext` (14 tests) behavior, then a refactor commit extracting `formatMessageEntry`, `formatCompactionEntry`, and `formatBranchEntry`.
|
|
27
|
-
Test count increased from 939 to 958 (+19).
|
|
28
|
-
All checks green: full suite, `pnpm run check`, `pnpm run lint`, `pnpm fallow dead-code`.
|
|
29
|
-
|
|
30
|
-
### Observations
|
|
31
|
-
|
|
32
|
-
- Because `extractText` and `buildParentContext` already existed, both test steps passed immediately (no red phase) — this is correct for behavior-locking tests before a refactor.
|
|
33
|
-
- The `makeCtx` helper in the test file creates a minimal `SessionContext` satisfying only `sessionManager.getBranch()`; the extra required fields (`cwd`, `model`, `modelRegistry`, `getSystemPrompt`) are satisfied with stubs.
|
|
34
|
-
- The `eslint-disable` comment on the `getBranch()` nullability check was preserved unchanged through the refactor.
|
|
35
|
-
- No deviations from the plan.
|
|
36
|
-
|
|
37
|
-
## Stage: Final Retrospective (2026-05-26T02:50:00Z)
|
|
38
|
-
|
|
39
|
-
### Session summary
|
|
40
|
-
|
|
41
|
-
Completed the full issue lifecycle (plan → TDD → ship → retro) in a single session with zero rework or user corrections.
|
|
42
|
-
Released as `pi-subagents-v7.5.1`.
|
|
43
|
-
Test count: 939 → 958 (+19 tests in new `test/session/context.test.ts`).
|
|
44
|
-
|
|
45
|
-
### Observations
|
|
46
|
-
|
|
47
|
-
#### What went well
|
|
48
|
-
|
|
49
|
-
- Zero-deviation execution: the architecture roadmap specified exact decomposition targets, the plan translated them into 3 TDD steps, and implementation was a straight transcription.
|
|
50
|
-
- Multi-model cost efficiency: `claude-sonnet-4-6` for planning/TDD, `deepseek-v4-flash` for shipping (~$0.002 for the entire ship workflow), `claude-opus-4-6` for retro synthesis.
|
|
51
|
-
- Incremental verification at every stage: per-file test runs after each TDD step, full suite + `pnpm run check` + `pnpm run lint` + `pnpm fallow dead-code` after the last step, repo-root lint before push.
|
|
52
|
-
|
|
53
|
-
#### What caused friction (agent side)
|
|
54
|
-
|
|
55
|
-
None identified.
|
|
56
|
-
The issue was well-scoped, the architecture roadmap was unambiguous, and the existing code had no surprising edge cases.
|
|
57
|
-
|
|
58
|
-
#### What caused friction (user side)
|
|
59
|
-
|
|
60
|
-
None identified.
|
|
61
|
-
The user ran four prompt commands in sequence (`/plan-issue`, `/tdd-plan`, `/ship-issue`, `/retro`) with no corrections or redirections needed.
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 216
|
|
3
|
-
issue_title: "Decompose startAgent in agent-manager.ts (Phase 13, Step 3)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #216 — Decompose startAgent in agent-manager.ts
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T20:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Analyzed the `startAgent` method's structural problems beyond surface-level length.
|
|
13
|
-
The original issue proposed extracting three methods (`handleRunCompletion`, `handleRunError`, `finalizeBackgroundRun`).
|
|
14
|
-
Through design discussion, identified the root cause as **mutable closure state without an owner** — two `let` variables shared across three closures — and proposed a `RunHandle` lifecycle object as the missing collaborator.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- The initial mechanical-extraction approach (3 methods) wouldn't have eliminated the mutable closure variables — `.then()`/`.catch()` would still close over `unsubRecordObserver` and `detach`.
|
|
19
|
-
`RunHandle` eliminates these entirely by owning the resource-release handles.
|
|
20
|
-
- `WorktreeState` has an ask-tell smell: callers call `worktrees.cleanup()` then `worktreeState.recordCleanup()`.
|
|
21
|
-
Adding `performCleanup()` is a small prep step that simplifies `RunHandle`'s completion/error methods.
|
|
22
|
-
- `record.description` is already available on `AgentRecord`, so `RunHandle` doesn't need `description` as a separate dependency — it can use `record.description` for worktree cleanup.
|
|
23
|
-
- `RunResult` is already exported from `agent-runner.ts`, so `RunHandle.complete()` can accept it directly without a new type.
|
|
24
|
-
- The `.catch()` handler doesn't wrap `onAgentCompleted` in try/catch while `.then()` does — `finalizeBackgroundRun` unifies this by always wrapping, preventing an observer error from blocking `drainQueue()`.
|
|
25
|
-
- `fireOnFinished` idempotency is important: if `complete()` throws after worktree cleanup but before returning, `.catch()` → `fail()` must not double-fire the background finalization.
|
|
26
|
-
`AgentRecord`'s transition guards (`if (this._status !== "stopped")`) provide a second safety net.
|
|
27
|
-
|
|
28
|
-
## Stage: Implementation — TDD (2026-05-25T23:20:00Z)
|
|
29
|
-
|
|
30
|
-
### Session summary
|
|
31
|
-
|
|
32
|
-
Completed all 4 TDD steps across 5 commits (one extra for the type-annotation fixup caught by `pnpm run check`).
|
|
33
|
-
Added 4 new tests for `WorktreeState.performCleanup`; total test count rose from 958 to 962.
|
|
34
|
-
All 60 test files pass; `pnpm run check`, `pnpm run lint`, and `pnpm fallow dead-code` all clean.
|
|
35
|
-
|
|
36
|
-
### Observations
|
|
37
|
-
|
|
38
|
-
- One deviation from the plan: the `makeWorktrees` test helper in `worktree-state.test.ts` needed an explicit `WorktreeCleanupResult` type annotation on its `result` parameter — TypeScript inferred `{ hasChanges: boolean }` (no optional `branch`/`path` fields) from the default argument, which caused a type error on the call site that passed `{ hasChanges: true, branch: "pi-agent-1" }`.
|
|
39
|
-
Fixed in the same commit as the `RunHandle` step.
|
|
40
|
-
- `RunHandle` landed exactly as designed: `wireSignal`, `attachObserver`, `complete`, `fail`, `releaseListeners`, `fireOnFinished` (idempotent). `startAgent` is now ~40 lines with zero mutable `let` bindings and one-liner `.then()`/`.catch()` handlers.
|
|
41
|
-
- `flushPendingSteers` and `setupWorktree` extracted cleanly — each about 8 lines, no surprises.
|
|
42
|
-
- The `WorktreeCleanupResult` import needed to be added to the test file alongside the existing `WorktreeManager` import for the type annotation fix — minor but worth noting for the next engineer.
|
|
43
|
-
- Architecture doc updated: Step 3 entry now reflects `RunHandle` rather than the original `handleRunCompletion`/`handleRunError` proposal.
|
|
44
|
-
|
|
45
|
-
## Stage: Final Retrospective (2026-05-26T15:10:00Z)
|
|
46
|
-
|
|
47
|
-
### Session summary
|
|
48
|
-
|
|
49
|
-
Issue #216 was planned, implemented via 4 TDD steps (5 commits), shipped, CI verified (after a GitHub Actions outage), and released as `pi-subagents-v7.6.0`.
|
|
50
|
-
The final design replaced the original mechanical-extraction proposal with a `RunHandle` lifecycle object that eliminated mutable closure state from `startAgent`.
|
|
51
|
-
|
|
52
|
-
### Observations
|
|
53
|
-
|
|
54
|
-
#### What went well
|
|
55
|
-
|
|
56
|
-
- The user's two design redirections during planning ("What collaborators are still missing?"
|
|
57
|
-
and "Make the change that makes the change easy") transformed a mechanical extraction plan into a structural improvement.
|
|
58
|
-
The resulting `RunHandle` eliminated the root cause (mutable closure state) rather than just shortening the method.
|
|
59
|
-
- The prep-step pattern worked exactly as intended: `WorktreeState.performCleanup` (step 1) and `finalizeBackgroundRun` (step 3) made the `RunHandle` rewrite (step 4) straightforward.
|
|
60
|
-
Step 4's large edit landed cleanly with all 962 tests passing on the first run.
|
|
61
|
-
- Two Explore subagents dispatched during planning (reading collaborator files and checking `WorktreeState` details) gathered the right context efficiently — `RunResult` being already exported and `record.description` being available at cleanup time were both discovered this way and shaped the `RunHandle` interface.
|
|
62
|
-
|
|
63
|
-
#### What caused friction (agent side)
|
|
64
|
-
|
|
65
|
-
- `premature-convergence` — accepted the issue's proposed mechanical extraction (3 methods) at face value and spent analysis time on LOC arithmetic before the user redirected toward structural thinking.
|
|
66
|
-
Impact: two user redirections needed; no rework since no code was committed yet.
|
|
67
|
-
- `instruction-violation` (self-identified) — the testing skill says "run `pnpm run check` immediately after" changing a shared interface, but step 1 added `performCleanup` to `WorktreeState` without running `pnpm run check`.
|
|
68
|
-
The type error in the test helper (`makeWorktrees` default parameter needing `WorktreeCleanupResult` annotation) went undetected for 3 commits until step 4's `pnpm run check`.
|
|
69
|
-
Impact: added friction but no rework — fixed in the same commit.
|
|
70
|
-
|
|
71
|
-
#### What caused friction (user side)
|
|
72
|
-
|
|
73
|
-
- The user's design redirections were necessary and well-timed.
|
|
74
|
-
No friction from the user side — the two interventions were strategic and saved significant implementation effort.
|
|
75
|
-
|
|
76
|
-
### Diagnostic details
|
|
77
|
-
|
|
78
|
-
- **Model-performance correlation** — two Explore subagents ran on `claude-haiku-4-5`; appropriate for read-only codebase search (reading collaborator files, checking types and test patterns).
|
|
79
|
-
- **Feedback-loop gap analysis** — `pnpm run check` ran only after step 4 (the `RunHandle` commit); should have run after step 1 (`WorktreeState.performCleanup` is a shared interface change per the testing skill).
|
|
80
|
-
The gap allowed a type annotation error to persist for 3 commits.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 217
|
|
3
|
-
issue_title: "Extract overwrite guard from UI (Phase 13, Step 4)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #217 — Extract overwrite guard from UI
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-26T20:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 5-step TDD plan to extract the duplicated overwrite-guard + write + reload + notify pattern from `AgentConfigEditor.ejectAgent` and `AgentCreationWizard.showManualWizard` into a shared `writeAgentFile` function in a new `src/ui/agent-file-writer.ts` module.
|
|
13
|
-
Confirmed dependency #214 (closure-to-class conversion) is already closed.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The `showGenerateWizard` overwrite guard was explicitly scoped out — it has different lifecycle semantics (spawned agent writes the file, post-write check is conditional).
|
|
18
|
-
This avoids a leaky abstraction with a discriminator parameter.
|
|
19
|
-
- Narrow ISP interfaces (`FileWriter`, `WriterUI`, `Reloadable`) keep the extracted function decoupled from the full `AgentFileOps` and `MenuUI` interfaces — 2/6 and 2/6 methods respectively.
|
|
20
|
-
- Both consumer call sites hold `this.fileOps` and `this.registry` as private fields and receive `ui` as a method parameter, so no constructor or wiring changes are needed.
|
|
21
|
-
- Existing tests in both consumer test files use `expect.stringContaining("already exists")` for overwrite prompts, which is stable across the extraction.
|
|
22
|
-
|
|
23
|
-
## Stage: Implementation — TDD (2026-05-26T20:40:00Z)
|
|
24
|
-
|
|
25
|
-
### Session summary
|
|
26
|
-
|
|
27
|
-
Implemented `writeAgentFile` in new `src/ui/agent-file-writer.ts`, replaced the inline overwrite-guard blocks in `AgentConfigEditor.ejectAgent` and `AgentCreationWizard.showManualWizard`, and updated the architecture doc.
|
|
28
|
-
All 5 plan steps completed across 4 commits (plan steps 1 and 2 folded into one).
|
|
29
|
-
Test count: 962 → 970 (+8 new tests in `test/ui/agent-file-writer.test.ts`).
|
|
30
|
-
|
|
31
|
-
### Observations
|
|
32
|
-
|
|
33
|
-
- Plan steps 1 and 2 naturally collapsed into a single commit — writing all 8 tests at once and implementing the full function body (including the guard) in one pass was cleaner than splitting them artificially.
|
|
34
|
-
- Both consumer refactors were straightforward one-import-add + one-block-replace edits; all existing tests passed without modification, confirming the extraction preserved exact behavior.
|
|
35
|
-
- The notification label `"Ejected ${name} to"` (with trailing space absorbed by `${targetPath}`) matched the pre-existing message format `"Ejected test-agent to /path"` exactly — no test assertions changed.
|
|
36
|
-
- `FileWriter`, `WriterUI`, and `Reloadable` narrow interfaces are exported from `agent-file-writer.ts`; both consumer files import the concrete types from their original sources, satisfying TypeScript's structural checker without any casts.
|
|
37
|
-
|
|
38
|
-
## Stage: Final Retrospective (2026-05-26T21:00:00Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
Full plan → TDD → ship → release lifecycle completed in a single continuous session.
|
|
43
|
-
Released as `pi-subagents-v7.7.0`.
|
|
44
|
-
Zero rework, zero test failures, zero CI issues.
|
|
45
|
-
|
|
46
|
-
### Observations
|
|
47
|
-
|
|
48
|
-
#### What went well
|
|
49
|
-
|
|
50
|
-
- The Phase 13 roadmap's step-level issue decomposition produced an issue (#217) that was right-sized for fully autonomous execution — the entire lifecycle completed without any blocking questions or scope surprises.
|
|
51
|
-
- ISP-narrow interfaces (`FileWriter`, `WriterUI`, `Reloadable`) structurally satisfied both consumer types without casts, confirming the plan's design.
|
|
52
|
-
- Existing tests in both consumer files passed without modification after the refactors, validating that the extraction preserved exact behavior.
|
|
53
|
-
|
|
54
|
-
#### What caused friction (agent side)
|
|
55
|
-
|
|
56
|
-
- `wrong-abstraction` — The plan split TDD steps 1 (happy-path tests) and 2 (overwrite-guard tests) for a ~10-line function with a single conditional.
|
|
57
|
-
Writing all 8 tests at once and implementing the full function body in one pass was natural; splitting them would have been artificial.
|
|
58
|
-
Self-corrected by folding into one commit.
|
|
59
|
-
Impact: added friction but no rework — the plan said "implementation should already pass" for step 2, acknowledging the fold was expected.
|
|
60
|
-
|
|
61
|
-
#### What caused friction (user side)
|
|
62
|
-
|
|
63
|
-
- Nothing notable — the issue was well-scoped with clear target files, a concrete smell label, and an explicit dependency chain.
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 218
|
|
3
|
-
issue_title: "Push SDK boundary in settings.ts (Phase 13, Step 5)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #218 — Push SDK boundary in settings.ts
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-26T17:01:55Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 3-step TDD plan to inject `agentDir: string` into `SettingsManager` and `loadSettings`, removing the only Pi SDK import from `settings.ts`.
|
|
13
|
-
The change is straightforward — a single parameter addition threading through constructor, free function, and boundary wiring.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The change is entirely mechanical: no design ambiguity, no new abstractions, no breaking public API.
|
|
18
|
-
- The main implementation effort is in test updates (~35 `new SettingsManager(...)` call sites plus ~15 `loadSettings(...)` calls), all requiring an `agentDir` argument.
|
|
19
|
-
- All test `describe` blocks that manipulate `PI_CODING_AGENT_DIR` env var can drop that scaffolding entirely, simplifying setup/teardown.
|
|
20
|
-
- `saveSettings` has no SDK dependency and needs no signature change — only `loadSettings` calls `globalPath()`.
|
|
21
|
-
|
|
22
|
-
## Stage: Implementation — TDD (2026-05-26T17:13:26Z)
|
|
23
|
-
|
|
24
|
-
### Session summary
|
|
25
|
-
|
|
26
|
-
Completed all 3 plan steps across 2 commits plus 1 doc commit.
|
|
27
|
-
All 970 tests pass; `settings.ts` now has 0 Pi SDK imports and all `PI_CODING_AGENT_DIR` env var manipulation is gone from `settings.test.ts`.
|
|
28
|
-
|
|
29
|
-
### Observations
|
|
30
|
-
|
|
31
|
-
- **Steps 1+2 combined:** Changing `loadSettings(cwd)` to `loadSettings(agentDir, cwd)` forced updating `SettingsManager.load()` in the same commit — they were inseparable (esbuild skips type checks, so the old call compiled but produced wrong runtime behavior).
|
|
32
|
-
The two production changes landed in one commit with a note in the body.
|
|
33
|
-
- **Test simplification was significant:** Removed `originalAgentDirEnv` save/restore scaffolding from 5 `describe` blocks; the test code shrank by 32 lines net.
|
|
34
|
-
- **`/nonexistent` sentinel:** Tests that construct `SettingsManager` but never call `load()` pass `agentDir: "/nonexistent"` — a clear signal the field is unused in that scope.
|
|
35
|
-
- Architecture doc Step 5 heading marked `✓` and folded into the last `feat:` commit by `pi-autoformat`.
|
|
36
|
-
|
|
37
|
-
## Stage: Final Retrospective (2026-05-26T17:22:11Z)
|
|
38
|
-
|
|
39
|
-
### Session summary
|
|
40
|
-
|
|
41
|
-
Issue #218 went from plan to shipped release (`pi-subagents-v7.8.0`) in a single continuous session.
|
|
42
|
-
Planning, TDD (2 feat commits + 1 doc commit), shipping, CI verification, issue close, and release-please merge all completed without user intervention beyond stage transitions.
|
|
43
|
-
|
|
44
|
-
### Observations
|
|
45
|
-
|
|
46
|
-
#### What went well
|
|
47
|
-
|
|
48
|
-
- **Clean mechanical execution:** The entire change was 2 production files (`settings.ts`, `index.ts`) and 1 test file, with zero unexpected test breakage and zero rework commits.
|
|
49
|
-
- **Test simplification payoff:** Removing `PI_CODING_AGENT_DIR` env var scaffolding from 5 `describe` blocks shrank the test file by 32 lines net — a tangible improvement in test readability.
|
|
50
|
-
- **Ship stage model efficiency:** The `/ship-issue` stage ran on `deepseek-v4-flash`, which was appropriate for the purely mechanical push/CI/close/merge workflow.
|
|
51
|
-
|
|
52
|
-
#### What caused friction (agent side)
|
|
53
|
-
|
|
54
|
-
1. `wrong-abstraction` — The plan split steps 1 and 2 into separate commits, but changing `loadSettings(cwd)` to `loadSettings(agentDir, cwd)` immediately broke `SettingsManager.load()` which calls it.
|
|
55
|
-
The agent recognized this during the red phase and combined them into one commit.
|
|
56
|
-
The existing testing skill rule ("When a TDD plan lists separate steps that share a type definition… fold them into one step") already covers this — the plan just didn't apply it.
|
|
57
|
-
Impact: added friction but no rework; recognized on first test run.
|
|
58
|
-
2. `missing-context` — Attempted to add `| ✓ #218 |` as an extra column to one row of the architecture doc's findings table, creating a column-count mismatch.
|
|
59
|
-
The autoformatter reverted the broken table.
|
|
60
|
-
The agent then spent ~5 tool calls (`git show --stat`, `git status`, `grep` ×2, `read`) investigating what happened before switching to the Step 5 heading approach.
|
|
61
|
-
Impact: ~2 minutes of investigation; no rework beyond the heading edit.
|
|
62
|
-
|
|
63
|
-
#### What caused friction (user side)
|
|
64
|
-
|
|
65
|
-
- The user asked "Are we ready for shipping?"
|
|
66
|
-
which surfaced that the TDD retro stage notes were still uncommitted.
|
|
67
|
-
This was a useful checkpoint — the ship stage committed them before pushing.
|
|
68
|
-
Opportunity: the `/tdd-plan` prompt could commit retro notes as part of its final step, but the current flow (write notes, then commit in ship) is lightweight enough that enforcing it would add complexity for marginal gain.
|
|
69
|
-
|
|
70
|
-
### Changes made
|
|
71
|
-
|
|
72
|
-
1. Retro file updated at `packages/pi-subagents/docs/retro/0218-push-sdk-boundary-in-settings.md` — no other files changed.
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 219
|
|
3
|
-
issue_title: "Reduce test duplication — top 3 clone families (Phase 13, Step 6)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #219 — Reduce test duplication — top 3 clone families
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-26T20:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Analyzed duplication patterns in the three target test files (`agent-manager.test.ts`, `conversation-viewer.test.ts`, `agent-config-editor.test.ts`).
|
|
13
|
-
Produced a 5-step TDD plan with shared `manager-stubs.ts` helper for runner/worktree factories, plus inline factories for the two UI test files.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The agent-manager test has the most diverse clone families (runner stubs, worktree stubs, run-result shapes) — these benefit from a shared helper file since the patterns are reused across 15+ describe blocks.
|
|
18
|
-
- The conversation-viewer and config-editor duplication is more localized — inline factories within each test file are the right granularity to avoid over-extraction.
|
|
19
|
-
- Gated runners (using `Promise.withResolvers`) were deliberately kept inline since they encode test-specific flow control that a factory would obscure.
|
|
20
|
-
- Both dependencies (#214, #216) are closed, so the production code is stable and the tests won't shift under us during implementation.
|
|
21
|
-
|
|
22
|
-
## Stage: Implementation — TDD (2026-05-26T17:42:41Z)
|
|
23
|
-
|
|
24
|
-
### Session summary
|
|
25
|
-
|
|
26
|
-
Completed all 4 TDD cycles: created `test/helpers/manager-stubs.ts` + `manager-stubs.test.ts` (13 smoke tests), migrated `agent-manager.test.ts`, `conversation-viewer.test.ts`, and `agent-config-editor.test.ts`.
|
|
27
|
-
Test count delta: 970 → 983 (+13 from smoke tests).
|
|
28
|
-
All 4 commits landed cleanly; full suite green at every step.
|
|
29
|
-
|
|
30
|
-
### Observations
|
|
31
|
-
|
|
32
|
-
- Target file line savings: `agent-manager.test.ts` −63, `conversation-viewer.test.ts` −58, `agent-config-editor.test.ts` −16; offset by +211 for the new helper files.
|
|
33
|
-
Net LOC is positive, but the _clone_ lines fallow detects are eliminated — the metric the issue targets.
|
|
34
|
-
- The `createSessionRunner` + `createRunResult` chain required careful identity-check verification: `createRunResult(sess)` calls `toAgentSession(sess)` which casts without creating a new object, so `toBe(session)` assertions in the execution-state tests still pass. ✓
|
|
35
|
-
- ESLint auto-fixed two cosmetic issues on commit (`activity = undefined` → `activity` destructuring, `session as unknown` cast removal) — caught by pre-commit hooks, not a problem in practice.
|
|
36
|
-
- The `assertRenderFitsWidths` helper in `conversation-viewer.test.ts` reduced the 10 render-safety tests from ~8 lines each to 1–4 lines each; the `setupDetail` helper in `agent-config-editor.test.ts` eliminated 3 repeated setup lines per test across 18 `showAgentDetail` tests.
|
|
37
|
-
|
|
38
|
-
## Stage: Final Retrospective (2026-05-26T17:50:31Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
All three stages (planning, TDD, ship) completed in a single session with zero user corrections.
|
|
43
|
-
Four TDD commits landed cleanly, CI passed on first push, issue #219 closed, and `pi-subagents-v7.8.1` released.
|
|
44
|
-
|
|
45
|
-
### Observations
|
|
46
|
-
|
|
47
|
-
#### What went well
|
|
48
|
-
|
|
49
|
-
- Clean incremental verification: `pnpm vitest run <file>` ran after every code change, full suite at the end.
|
|
50
|
-
No regressions at any step.
|
|
51
|
-
- The plan's decision to keep gated runners inline proved correct — tests with `Promise.withResolvers` flow control stayed readable without abstraction.
|
|
52
|
-
- The `write` tool was the right choice for `conversation-viewer.test.ts` and `agent-config-editor.test.ts` (pervasive changes), while `edit` with 16 targeted replacements worked cleanly for `agent-manager.test.ts` (scattered but formulaic substitutions).
|
|
53
|
-
- Ship stage used `deepseek-v4-flash` for purely mechanical CI/release steps — appropriate model-task alignment.
|
|
54
|
-
|
|
55
|
-
#### What caused friction (agent side)
|
|
56
|
-
|
|
57
|
-
- `other` — ESLint pre-commit hooks auto-fixed two cosmetic patterns (`activity = undefined` → bare destructuring; `session as unknown` cast removal), requiring re-stage + re-commit.
|
|
58
|
-
Impact: ~10 seconds per occurrence, no rework.
|
|
59
|
-
This is routine and inherent to the workflow.
|
|
60
|
-
|
|
61
|
-
#### What caused friction (user side)
|
|
62
|
-
|
|
63
|
-
- None observed.
|
|
64
|
-
The user's three-stage prompt chain (`/plan-issue` → `/tdd-plan` → `/ship-issue`) provided sufficient context at each stage with no manual intervention needed.
|