@gotgenes/pi-subagents 18.0.1 → 18.0.3
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 +15 -0
- package/docs/architecture/architecture.md +165 -203
- package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
- package/package.json +6 -7
- package/src/config/default-agents.ts +3 -0
- package/src/lifecycle/subagent.ts +25 -14
- package/src/observation/notification.ts +23 -10
- package/src/observation/subagent-events-observer.ts +1 -3
- package/src/runtime.ts +2 -1
- package/src/service/service-adapter.ts +20 -17
- package/src/session/model-resolver.ts +31 -30
- package/src/tools/agent-tool.ts +17 -13
- package/src/tools/get-result-report.ts +60 -0
- package/src/tools/get-result-tool.ts +25 -40
- package/src/tools/helpers.ts +21 -5
- package/src/tools/spawn-config.ts +5 -5
- package/src/tools/steer-tool.ts +37 -27
- package/src/types.ts +4 -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/0443-consolidate-remaining-test-clone-families.md +0 -268
- 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/plans/0470-refresh-readme-command-surface.md +0 -159
- 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 -97
- package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
- package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
- 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/docs/retro/0470-refresh-readme-command-surface.md +0 -40
- package/src/observation/notification-state.ts +0 -27
- package/vitest.config.ts +0 -14
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 172
|
|
3
|
-
issue_title: "refactor(pi-subagents): extract shared turn-formatting logic"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #172 — Extract shared turn-formatting logic
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T18:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the extraction of duplicated turn-formatting logic from `lifecycle/agent-runner.ts` and `ui/message-formatters.ts` into a new shared module `session/content-items.ts`.
|
|
13
|
-
The plan covers extracting `ToolCallContent`, `getToolCallName`, and a new `extractAssistantContent` function, with a 6-step TDD order.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Issue #170 (completed) shifted the duplication target from `conversation-viewer.ts` to `message-formatters.ts` — the issue body's line references are stale but the duplication still exists in the same form.
|
|
18
|
-
- Both dependencies (#164 and #170) are closed, so this is unblocked.
|
|
19
|
-
- The duplication is clearly incidental (same data extraction, different presentation) — safe to extract per the code-design skill's structural-reasons check.
|
|
20
|
-
- `getToolCallName` has no direct unit tests today; the extraction enables testing it for the first time.
|
|
21
|
-
- `getAgentConversation` also has no tests — noted as out of scope but worth a follow-up.
|
|
22
|
-
- Considered adding `extractText` to the new module for consistency but deferred to keep scope tight.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-24T19:05:00Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
Completed all 6 TDD steps from the plan.
|
|
29
|
-
Created `session/content-items.ts` with `getToolCallName` and `extractAssistantContent`, added 11 unit tests, then refactored both `message-formatters.ts` and `agent-runner.ts` to use the shared module.
|
|
30
|
-
Test count went from 896 to 907 (+11).
|
|
31
|
-
|
|
32
|
-
### Observations
|
|
33
|
-
|
|
34
|
-
- Steps 1 and 2 (test-only commits) were folded into step 3's feat commit per the plan's intent — all three land together.
|
|
35
|
-
- The `getToolCallName` parameter type needed widening from `{ type: string }` to `{ type: string; [key: string]: unknown }` to allow test object literals to pass excess-property checking.
|
|
36
|
-
This in turn required an `as unknown as` double cast at the `agent-runner.ts` call site, because the SDK's `TextContent | ThinkingContent | ToolCall` union lacks an index signature.
|
|
37
|
-
Same pattern already present in `conversation-viewer.ts`.
|
|
38
|
-
- `message-formatters.ts` had both an import and a re-export of `getToolCallName`; simplified to a pure re-export only.
|
|
39
|
-
- The lint fixup (unused import) was amended into the same refactor commit before pushing.
|
|
40
|
-
- Architecture doc updated: `content-items.ts` added to session module listing, production-duplication section updated, Step 9 marked Done.
|
|
41
|
-
|
|
42
|
-
## Stage: Final Retrospective (2026-05-24T20:30:00Z)
|
|
43
|
-
|
|
44
|
-
### Session summary
|
|
45
|
-
|
|
46
|
-
Planned, implemented, and shipped the extraction of shared turn-formatting logic from `lifecycle/agent-runner.ts` and `ui/message-formatters.ts` into `session/content-items.ts`.
|
|
47
|
-
Released as `pi-subagents-v6.19.0`.
|
|
48
|
-
During code review the user challenged double-casts in the initial implementation, which led to discovering that the local `ToolCallContent` type was dead code and the SDK exports the real `ToolCall` type — the final implementation is significantly cleaner than what the plan specified.
|
|
49
|
-
Filed #188 for broader `any`-to-SDK-type cleanup discovered during the investigation.
|
|
50
|
-
|
|
51
|
-
### Observations
|
|
52
|
-
|
|
53
|
-
#### What went well
|
|
54
|
-
|
|
55
|
-
- The user's Socratic challenge ("Talk to me about these double-casts") was the pivotal moment.
|
|
56
|
-
Rather than directing a fix, it prompted an investigation of the SDK's actual `ToolCall` type, which revealed that `ToolCall.name` is always required and `toolName` never appears on content items.
|
|
57
|
-
This eliminated the `ToolCallContent` interface, the `toolName` fallback, the index-signature parameter type, and all double-casts — none of which the plan anticipated.
|
|
58
|
-
- Cross-session retro context worked well: the planning-stage note about #170 shifting the duplication target saved time during TDD.
|
|
59
|
-
- The SDK source investigation yielded a follow-up issue (#188) for replacing `any` casts in `extractText` and `SubscribableSession` with proper SDK types.
|
|
60
|
-
|
|
61
|
-
#### What caused friction (agent side)
|
|
62
|
-
|
|
63
|
-
- `missing-context` — Did not check SDK type exports during planning.
|
|
64
|
-
The plan copied `ToolCallContent` verbatim from the existing code without verifying what `@earendil-works/pi-ai` exports.
|
|
65
|
-
The source comments ("SDK doesn't export the narrow type") were wrong — the types have been exported for some time.
|
|
66
|
-
Impact: the initial TDD implementation introduced a `{ type: string; [key: string]: unknown }` parameter type that forced `as unknown as` double-casts, requiring a full rework after user review.
|
|
67
|
-
- `premature-convergence` — When TypeScript rejected excess properties in test object literals, I widened the parameter type to include an index signature instead of exploring alternatives.
|
|
68
|
-
The correct fix (using `ReadonlyArray<{ type: string }>` with `in` narrowing, or importing SDK types as test fixtures) was simpler and avoided the cast cascade.
|
|
69
|
-
Impact: one round of rework plus an amended commit that muddied the git history.
|
|
70
|
-
|
|
71
|
-
#### What caused friction (user side)
|
|
72
|
-
|
|
73
|
-
- The user's intervention at the cast review stage was well-timed and effective.
|
|
74
|
-
One earlier opportunity: if the user had flagged the `toolName` fallback or the SDK-type question during the plan review (before TDD started), the initial implementation would have been correct from the start.
|
|
75
|
-
However, this is a marginal improvement — the plan review was clean and the friction was minor.
|
|
76
|
-
|
|
77
|
-
### Changes made
|
|
78
|
-
|
|
79
|
-
1. `.pi/skills/code-design/SKILL.md` — Added two rules to "Pi SDK boundaries": verify SDK exports before redeclaring types locally; prefer minimal structural supertypes over index-signature types for parameters accepting SDK content.
|
|
80
|
-
2. `.pi/skills/testing/SKILL.md` — Added TDD planning rule: verify SDK exports when extracting locally-declared types that shadow SDK types.
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 180
|
|
3
|
-
issue_title: "perf(pi-subagents): reorder append-mode system prompt to enable KV cache reuse"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #180 — Reorder append-mode system prompt for KV cache reuse
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T20:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a plan to reorder the append-mode system prompt in `buildAgentPrompt()` so the shared inherited content (~8k tokens) comes before the varying `<active_agent>` tag and env block, enabling LLM KV cache prefix reuse across subagent invocations.
|
|
13
|
-
|
|
14
|
-
### Observations
|
|
15
|
-
|
|
16
|
-
- Confirmed pi-permission-system's `ACTIVE_AGENT_TAG_REGEX.exec()` is position-independent — no changes needed in that package despite the `pkg:pi-permission-system` label on the issue.
|
|
17
|
-
- Only two tests assert positional ordering in append mode (`startsWith` and `tagIdx === 0`); all other prompt tests use `toContain()` and are unaffected.
|
|
18
|
-
- Replace mode is a separate code path and is not touched.
|
|
19
|
-
- The TDD cycle is minimal: one red step (update two positional assertions), one green step (reorder the return statement + update JSDoc).
|
|
20
|
-
|
|
21
|
-
## Stage: Implementation — TDD (2026-05-24T20:15:00Z)
|
|
22
|
-
|
|
23
|
-
### Session summary
|
|
24
|
-
|
|
25
|
-
Completed both TDD cycles in `buildAgentPrompt()` in `src/session/prompts.ts`.
|
|
26
|
-
Two positional assertions in `test/session/prompts.test.ts` were updated to expect the new ordering (red), then the append-mode return statement was reordered and the JSDoc updated (green).
|
|
27
|
-
Test count unchanged at 805 across 50 files.
|
|
28
|
-
|
|
29
|
-
### Observations
|
|
30
|
-
|
|
31
|
-
- The JSDoc bullet for append mode also described the old ordering ("env header + parent system prompt + ...") and was corrected as part of the green step.
|
|
32
|
-
- The `<active_agent>` tag is followed by a `\n\n`, so when it moves after `<sub_agent_context>`, a `\n\n` separator between the bridge and the tag was needed to maintain clean section boundaries.
|
|
33
|
-
- No deviations from the plan; both steps were exactly as described.
|
|
34
|
-
|
|
35
|
-
## Stage: Final Retrospective (2026-05-24T21:00:00Z)
|
|
36
|
-
|
|
37
|
-
### Session summary
|
|
38
|
-
|
|
39
|
-
Issue #180 went from external community observation through release (`pi-subagents-v6.18.3`) in a single continuous session.
|
|
40
|
-
The plan predicted exactly two TDD steps; both executed without deviation or rework.
|
|
41
|
-
|
|
42
|
-
### Observations
|
|
43
|
-
|
|
44
|
-
#### What went well
|
|
45
|
-
|
|
46
|
-
- End-to-end lifecycle in one session: external comment → issue → plan → TDD → ship → release.
|
|
47
|
-
No corrections, no scope drift, no rework across any stage.
|
|
48
|
-
- The plan's test impact analysis was accurate — only two positional assertions needed updating; all `toContain()` tests passed untouched.
|
|
49
|
-
- Confirming pi-permission-system's `ACTIVE_AGENT_TAG_REGEX.exec()` is position-independent during planning eliminated the second `pkg:*` label's scope entirely, keeping the change to a single file.
|
|
50
|
-
|
|
51
|
-
#### What caused friction (agent side)
|
|
52
|
-
|
|
53
|
-
- `wrong-abstraction` — Launched an Explore agent (75.9s, 18 tool uses) to map the prompt assembly flow when the `package-pi-subagents` skill already listed the file layout and `prompts.ts` is 107 lines.
|
|
54
|
-
Direct `read` + `grep` achieved the same confirmation in ~3 seconds during the planning phase.
|
|
55
|
-
Impact: added ~75 seconds of latency but no rework.
|
|
56
|
-
- `missing-context` — The plan listed "Update the JSDoc comment" but missed that the mode-description bullet ("env header + parent system prompt + ...") also encoded the old ordering.
|
|
57
|
-
Caught during the green step and fixed in the same commit.
|
|
58
|
-
Impact: added friction but no rework.
|
|
59
|
-
|
|
60
|
-
#### What caused friction (user side)
|
|
61
|
-
|
|
62
|
-
- Nothing notable — the user's prompts were well-scoped and the issue description was unambiguous.
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 185
|
|
3
|
-
issue_title: "pi-subagents: Remove persistent agent memory feature"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #185 — pi-subagents: Remove persistent agent memory feature
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T20:46:56Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Traced all memory-related code across 9 source files, 5 test files, and the architecture doc.
|
|
13
|
-
Produced a 5-step TDD plan: extract shared utilities (`isSymlink`, `isUnsafeName`, `safeReadFile`) to `safe-fs.ts`, then remove memory consumers (session assembly, config, UI), then delete the module, then update docs.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The three utility functions in `memory.ts` are the only complication — `skill-loader.ts` imports them independently of memory.
|
|
18
|
-
Extracting to `src/session/safe-fs.ts` keeps them co-located with their sole remaining consumer.
|
|
19
|
-
- The removal is consumers-first, declaration-last: session-config and prompts lose their memory logic before `MemoryScope` is removed from `types.ts`, avoiding intermediate type errors.
|
|
20
|
-
- No ambiguous design choices — the issue scope section is precise about what to remove and what to extract.
|
|
21
|
-
- Memory field in custom agent frontmatter will silently become a no-op (ignored by the YAML parser) — no user-facing error, just loss of the feature.
|
|
22
|
-
- The `AssemblerIO` interface shrinks from 4 fields to 2 after removal, which is a welcome simplification.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-24T22:41:23Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
All 5 TDD steps completed across 5 commits.
|
|
29
|
-
Test count went from 901 (54 files) to 848 (53 files) — a net reduction of 53 tests and 1 file, reflecting the deletion of the `memory.test.ts` file with its memory-specific tests and the removal of memory-related tests from `session-config.test.ts`, `prompts.test.ts`, `agent-types.test.ts`, and `custom-agents.test.ts`.
|
|
30
|
-
New file `safe-fs.test.ts` was created with 13 tests for the extracted utilities.
|
|
31
|
-
|
|
32
|
-
### Observations
|
|
33
|
-
|
|
34
|
-
- Step 1 had a subtle bug: after re-exporting `isUnsafeName` from `safe-fs` in `memory.ts`, the function was not imported into the `memory.ts` module scope itself, so `resolveMemoryDir` got a `ReferenceError` at runtime.
|
|
35
|
-
Fix was trivial: add `isUnsafeName` to the import alongside `isSymlink` and `safeReadFile`.
|
|
36
|
-
- Step 3 introduced a type error in `memory.ts` (still alive at that point): `MemoryScope` was imported from `#src/types` which no longer exported it.
|
|
37
|
-
Fix: inline the literal union `"user" | "project" | "local"` directly in `memory.ts` as a local type, so it compiles cleanly until deletion in step 4.
|
|
38
|
-
- The `SKILL.md` for `package-pi-subagents` also listed `memory.ts` in the session domain table — updated alongside `architecture.md` in the docs commit.
|
|
39
|
-
- No deviations from the plan other than the two minor bugs above (both self-corrected within the same TDD step).
|
|
40
|
-
|
|
41
|
-
## Stage: Final Retrospective (2026-05-24T22:47:55Z)
|
|
42
|
-
|
|
43
|
-
### Session summary
|
|
44
|
-
|
|
45
|
-
Shipped issue #185 as `pi-subagents-v7.0.0`.
|
|
46
|
-
CI passed, issue closed, release-please PR #190 merged.
|
|
47
|
-
Three sessions total: planning, TDD (5 steps / 5 commits), shipping.
|
|
48
|
-
|
|
49
|
-
### Observations
|
|
50
|
-
|
|
51
|
-
#### What went well
|
|
52
|
-
|
|
53
|
-
- The issue's "Scope" section was precise enough that the planning session required no `ask_user` and the Explore agent's trace matched the final commit diff exactly.
|
|
54
|
-
- Consumers-first, declaration-last ordering kept each commit independently compilable (after the two self-corrected fixes).
|
|
55
|
-
- The `SKILL.md` domain table update was caught naturally during the docs step even though the plan didn't list it.
|
|
56
|
-
|
|
57
|
-
#### What caused friction (agent side)
|
|
58
|
-
|
|
59
|
-
- `missing-context` — In TDD step 1, `memory.ts` was updated to re-export `isUnsafeName` from `safe-fs`, but the function was not imported into `memory.ts`'s own scope.
|
|
60
|
-
`resolveMemoryDir` threw a `ReferenceError` at runtime.
|
|
61
|
-
Impact: one extra test-run cycle (~5 seconds) and a trivial one-line fix; no rework commit.
|
|
62
|
-
- `missing-context` — In TDD step 3, removing `MemoryScope` from `types.ts` broke `memory.ts` (scheduled for deletion in step 4).
|
|
63
|
-
The plan said "consumers-first" but didn't account for the doomed module itself being a consumer of the type.
|
|
64
|
-
Impact: one extra `pnpm run check` cycle and a local type inline; no rework commit.
|
|
65
|
-
Both share the same root cause: incremental deletion plans must account for doomed files' own imports at each intermediate step.
|
|
66
|
-
|
|
67
|
-
#### What caused friction (user side)
|
|
68
|
-
|
|
69
|
-
- None observed — all three sessions ran without user corrections or redirections.
|
|
70
|
-
|
|
71
|
-
### Changes made
|
|
72
|
-
|
|
73
|
-
1. Added a TDD planning rule to `.pi/skills/testing/SKILL.md` about accounting for doomed modules' own imports during multi-step deletion.
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 188
|
|
3
|
-
issue_title: "refactor(pi-subagents): replace any casts with SDK types in extractText and SubscribableSession"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #188 — Replace any casts with SDK types
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T20:04:58Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a two-step refactoring plan for replacing `any` casts in `extractText` (with a `TextContent` type predicate) and `SubscribableSession` (with `AgentSessionEvent`).
|
|
13
|
-
Verified that both SDK types are already imported and used in adjacent files within the package.
|
|
14
|
-
Confirmed mock session compatibility via function parameter contravariance — no test changes expected.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- The `extractText` parameter type stays `unknown[]` to avoid rippling through callers in `message-formatters.ts` that declare `content: unknown[]`.
|
|
19
|
-
A future cleanup could tighten those caller signatures.
|
|
20
|
-
- `SubscribableSession` moves to `src/types.ts` as the shared location, matching existing cross-domain types there (`SubagentType`, `ThinkingLevel`, `ShellExec`).
|
|
21
|
-
- All three `eslint-disable` top-level comments (`context.ts`, `record-observer.ts`, `ui-observer.ts`) should be removable once the `any` casts are gone, since the SDK union's discriminated members cover the property access patterns.
|
|
22
|
-
- Risk: if `AgentSessionEvent` doesn't cover `assistantMessageEvent` in `ui-observer.ts`, the type checker will surface it immediately — the mitigation is to check the union members during implementation.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-24T20:17:38Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
Completed both TDD steps from the plan.
|
|
29
|
-
Step 1 replaced the `any` filter/map chain in `extractText` with an `isTextContent` type predicate; the `??""` removal was required because `TextContent.text` is non-optional per the SDK type.
|
|
30
|
-
Step 2 moved `SubscribableSession` to `types.ts` typed with `AgentSessionEvent`, removed both duplicate local interfaces, and removed all three `eslint-disable` comments.
|
|
31
|
-
Test count: 902 → 901 (one test removed).
|
|
32
|
-
|
|
33
|
-
### Observations
|
|
34
|
-
|
|
35
|
-
- The `??` operator on `c.text` in `extractText` triggered `@typescript-eslint/no-unnecessary-condition` at commit time because `TextContent.text` is `string` (non-nullable); removing it was necessary, not just cosmetic.
|
|
36
|
-
- After typing the `record-observer` callback as `AgentSessionEvent`, five additional lint errors surfaced: `event.message?.role` (optional chain unnecessary since `MessageEndEvent.message` is required), `if (u)` guard (unnecessary since `AssistantMessage.usage` is required), and three `?? 0` guards on `input`/`output`/`cacheWrite` (all required `number` fields per `Usage` interface in the Pi source at `~/development/pi/pi/packages/ai/src/types.ts`).
|
|
37
|
-
- The test `"ignores message_end without usage"` was removed — it emitted a non-conforming event that the SDK types guarantee cannot occur at runtime.
|
|
38
|
-
- `ui-observer.ts` had one analogous fix: `event.assistantMessageEvent?.type` → `.type` (the field is required on `MessageUpdateEvent`).
|
|
39
|
-
- No test file changes were needed for `ui-observer.ts` — its existing tests all emit conforming events.
|
|
40
|
-
- The plan's contravariance reasoning about mock session compatibility was correct: `pnpm run check` passed without updating `MockSession.subscribe`.
|
|
41
|
-
|
|
42
|
-
## Stage: Final Retrospective (2026-05-24T20:41:42Z)
|
|
43
|
-
|
|
44
|
-
### Session summary
|
|
45
|
-
|
|
46
|
-
Clean two-step refactoring shipped as `pi-subagents-v6.19.1`.
|
|
47
|
-
Both TDD steps completed in a single session with two minor deviations from the plan, both caught by pre-commit hooks.
|
|
48
|
-
Test count: 902 → 901 (one non-conforming test removed).
|
|
49
|
-
|
|
50
|
-
### Observations
|
|
51
|
-
|
|
52
|
-
#### What went well
|
|
53
|
-
|
|
54
|
-
- The plan's contravariance analysis of `MockSession.subscribe` vs `SubscribableSession` was correct — zero test infrastructure changes needed.
|
|
55
|
-
- Pre-commit hooks (ESLint) caught both deviations from the plan at commit time, before they could reach CI.
|
|
56
|
-
- The user providing the Pi source path (`~/development/pi/pi`) unblocked verification of `AssistantMessage.usage` field requirements without guesswork.
|
|
57
|
-
|
|
58
|
-
#### What caused friction (agent side)
|
|
59
|
-
|
|
60
|
-
- `missing-context` — The plan's Risk 3 said "keep `?? ""` for safety" on `TextContent.text`, but `@typescript-eslint/no-unnecessary-condition` rejected it at commit time because `TextContent.text: string` is non-optional.
|
|
61
|
-
Impact: one failed commit attempt, immediate fix (changed `.map((c) => c.text ?? "")` to `.map((c) => c.text)`).
|
|
62
|
-
- `missing-context` — The plan's step 2 didn't anticipate the five additional lint errors surfaced by properly typing the `record-observer` callback: unnecessary optional chain on `event.message?.role`, unnecessary `if (u)` guard, and three unnecessary `?? 0` guards on usage fields.
|
|
63
|
-
Impact: added ~5 minutes of investigation to verify the SDK types were truly non-optional before removing guards; required removing one test case (`"ignores message_end without usage"`).
|
|
64
|
-
Both instances stem from the same root cause: the plan checked that the SDK types *existed* but didn't trace the *field optionality* of types downstream of `AgentSessionEvent` (specifically `AgentMessage.usage` and `Usage.{input,output,cacheWrite}`).
|
|
65
|
-
|
|
66
|
-
#### What caused friction (user side)
|
|
67
|
-
|
|
68
|
-
- The Pi source path (`~/development/pi/pi`) was provided reactively after I'd already spent several tool calls trying to locate `AgentMessage` type definitions in `node_modules`.
|
|
69
|
-
Sharing this path earlier (or noting it in the package skill) would have saved ~4 `grep`/`find` calls.
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 192
|
|
3
|
-
issue_title: "Define SessionContext narrow interface"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #192 — Define SessionContext narrow interface
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T16:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the pure-additive `SessionContext` interface for `src/types.ts`.
|
|
13
|
-
Traced all 5 consumed fields against the SDK's `ExtensionContext` type declarations to confirm shape alignment.
|
|
14
|
-
Single TDD step: add the interface and verify with `pnpm run check`.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- The interface is trivial in scope — one new export with no consumers changing.
|
|
19
|
-
This is intentionally the smallest possible first step to unblock Layer 1 (#193).
|
|
20
|
-
- `ModelRegistry` already exists as a local narrow interface in `src/session/model-resolver.ts`; `SessionContext` imports it rather than redeclaring.
|
|
21
|
-
- `sessionManager` uses an inline structural type (3 methods) rather than importing the SDK's `ReadonlySessionManager` (13 methods) — ISP applies here.
|
|
22
|
-
- No design ambiguity required `ask_user`; the issue's proposed change section was fully specified.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-24T19:55:00Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
Added the `SessionContext` interface to `src/types.ts` with an `import type { ModelRegistry }` from `#src/session/model-resolver`.
|
|
29
|
-
Single compile-time step — no runtime tests needed for a pure type definition.
|
|
30
|
-
Baseline: 53 test files, 848 tests; final: unchanged.
|
|
31
|
-
|
|
32
|
-
### Observations
|
|
33
|
-
|
|
34
|
-
- Pre-existing lint failure in `docs/architecture/architecture.md` (5 unused MD053 link references for issues #164, #165, #170, #171, #172) was fixed as part of the baseline verification and included in the feat commit.
|
|
35
|
-
- The interface landed exactly as planned — no deviations from the plan's Design Overview.
|
|
36
|
-
|
|
37
|
-
## Stage: Final Retrospective (2026-05-24T20:00:00Z)
|
|
38
|
-
|
|
39
|
-
### Session summary
|
|
40
|
-
|
|
41
|
-
All three stages (plan, TDD, ship) completed in a single session.
|
|
42
|
-
Released as `pi-subagents-v7.1.0`.
|
|
43
|
-
No rework, no deviations from plan.
|
|
44
|
-
|
|
45
|
-
### Observations
|
|
46
|
-
|
|
47
|
-
#### What went well
|
|
48
|
-
|
|
49
|
-
- The issue was fully specified — no ambiguity, no `ask_user` needed at any stage.
|
|
50
|
-
- Trivial scope (one interface, no consumers) made the plan-to-ship pipeline fast and mechanical.
|
|
51
|
-
- Pre-existing lint failures in `architecture.md` were caught during baseline verification and fixed without disrupting the flow.
|
|
52
|
-
|
|
53
|
-
#### What caused friction (agent side)
|
|
54
|
-
|
|
55
|
-
- None — clean execution with no rework or corrections.
|
|
56
|
-
|
|
57
|
-
#### What caused friction (user side)
|
|
58
|
-
|
|
59
|
-
- None — no intervention needed beyond invoking the three workflow commands.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 193
|
|
3
|
-
issue_title: "SubagentRuntime owns context queries"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #193 — SubagentRuntime owns context queries
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T21:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the Layer 1 change that types `SubagentRuntime.currentCtx` as `SessionContext`, adds three query methods (`buildSnapshot`, `getModelInfo`, `getSessionInfo`), and eliminates 4 `as any` casts from `index.ts`.
|
|
13
|
-
The plan covers 7 TDD steps touching `runtime.ts`, `handlers/lifecycle.ts`, `parent-snapshot.ts`, `context.ts`, `service-adapter.ts`, and `index.ts`.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The `pi` field in `currentCtx` is never read back — only stored.
|
|
18
|
-
Dropping it is safe; `SessionLifecycleHandler` already holds `pi` as a constructor param.
|
|
19
|
-
- `ExtensionContext` structurally satisfies `SessionContext`, so changing `buildParentSnapshot`'s param type is source-compatible with the `/agents` command handler that passes raw SDK `ctx`.
|
|
20
|
-
- `service-adapter.ts` gets the biggest structural change: its two closure params (`getCtx`, `getModelRegistry`) collapse into a single `ServiceRuntimeLike` interface.
|
|
21
|
-
- No design ambiguity — the architecture doc's Layer 1 spec and the issue body are fully aligned.
|
|
22
|
-
- Test fixtures in `make-deps.ts` are unaffected because the `AgentToolDeps` interface shape doesn't change — only the wiring in `index.ts` that supplies the implementations changes.
|
|
23
|
-
|
|
24
|
-
## Stage: Implementation — TDD (2026-05-24T20:30:00Z)
|
|
25
|
-
|
|
26
|
-
### Session summary
|
|
27
|
-
|
|
28
|
-
Completed all 6 implementation TDD steps plus an architecture doc update in one session.
|
|
29
|
-
The `getSessionInfo` implementation needed `?.sessionManager.getSessionFile()` (not `?.sessionManager?.getSessionFile()`) since `sessionManager` is a required field of `SessionContext` — ESLint's `no-unnecessary-condition` caught this at the pre-commit hook.
|
|
30
|
-
Final test count: 854 (up from 848 baseline, +6 new tests for `buildSnapshot`, `getModelInfo`, `getSessionInfo`).
|
|
31
|
-
|
|
32
|
-
### Observations
|
|
33
|
-
|
|
34
|
-
- The plan's Non-Goals section incorrectly said `buildParentContext` would NOT change.
|
|
35
|
-
In practice it had to accept `SessionContext` instead of `ExtensionContext` — they are not substitutable in that direction.
|
|
36
|
-
The Module-Level Changes list was correct; only the Non-Goals prose was wrong.
|
|
37
|
-
- `context.ts` needed a local `BranchEntry` union type to handle `getBranch(): unknown[]`.
|
|
38
|
-
TypeScript's discriminated union narrowing doesn't work when the union includes a catch-all `{ type: string }` arm — explicit casts within each `if` branch were required.
|
|
39
|
-
- `service-adapter.ts` ended up using `runtime.currentCtx.modelRegistry` directly (no `getModelInfo()` call needed in the service adapter) — `ServiceRuntimeLike` only needs `currentCtx` and `buildSnapshot`.
|
|
40
|
-
This is cleaner than the plan's `getModelInfo(): { modelRegistry: unknown }` approach.
|
|
41
|
-
- Biome's `noUnusedPrivateClassMembers` warning caught the leftover `private readonly pi: unknown` in `SessionLifecycleHandler`.
|
|
42
|
-
Removed `pi` from the constructor entirely (rather than adding `_` prefix), which also cleaned up `index.ts`.
|
|
43
|
-
- The `eslint-disable` directive at the top of `index.ts` had two now-unused entries (`no-unsafe-member-access`, `no-unsafe-call`) removed by `eslint --fix`.
|
|
44
|
-
|
|
45
|
-
## Stage: Final Retrospective (2026-05-24T20:45:00Z)
|
|
46
|
-
|
|
47
|
-
### Session summary
|
|
48
|
-
|
|
49
|
-
All three stages (plan, TDD, ship) completed in a single session.
|
|
50
|
-
Released as `pi-subagents-v7.2.0`.
|
|
51
|
-
One plan contradiction required a judgment call during implementation; otherwise clean mechanical execution.
|
|
52
|
-
|
|
53
|
-
### Observations
|
|
54
|
-
|
|
55
|
-
#### What went well
|
|
56
|
-
|
|
57
|
-
- The architecture doc's Phase 11 Layer 1 spec was precise enough that no `ask_user` was needed at any stage — the issue body, architecture doc, and #192 retro were fully aligned.
|
|
58
|
-
- `ServiceRuntimeLike` ended up simpler than planned (only `currentCtx` + `buildSnapshot` instead of also requiring `getModelInfo()`) — the implementation found a cleaner design than the plan specified.
|
|
59
|
-
- Test count increase (+6) validates the design: methods that were previously untestable as anonymous closures now have dedicated unit tests.
|
|
60
|
-
|
|
61
|
-
#### What caused friction (agent side)
|
|
62
|
-
|
|
63
|
-
- `missing-context` — The plan's Non-Goals section claimed `buildParentContext` would not change, contradicting Module-Level Changes item #4 which explicitly listed the file.
|
|
64
|
-
The planning stage didn't cross-check these sections before committing.
|
|
65
|
-
Impact: brief confusion during step 3 about which section to trust (resolved by following Module-Level Changes); no rework, added ~30s of deliberation.
|
|
66
|
-
- `missing-context` — TypeScript's discriminated union narrowing limitation with a `{ type: string }` catch-all arm was not anticipated.
|
|
67
|
-
Impact: required adding a local `BranchEntry` union type and explicit casts in `context.ts`; no rework but ~2 min of debugging the type error.
|
|
68
|
-
|
|
69
|
-
#### What caused friction (user side)
|
|
70
|
-
|
|
71
|
-
- None — no user intervention was needed at any point across all three stages.
|
|
72
|
-
|
|
73
|
-
### Changes made
|
|
74
|
-
|
|
75
|
-
1. `.pi/prompts/plan-issue.md` — added a Non-Goals vs Module-Level Changes cross-check instruction under the Module-Level Changes bullet.
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 194
|
|
3
|
-
issue_title: "Align tool interfaces for structural typing"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #194 — Align tool interfaces for structural typing
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T12:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced an implementation plan for three targeted alignment changes: moving `getMaxConcurrent` off manager interfaces to the settings accessor, renaming `SubagentRuntime.updateWidget()` → `update()`, and removing the dead `getToolCallName` re-export.
|
|
13
|
-
The plan includes a 4-step TDD order with type-check gates after each refactoring step.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Issue #193 (Layer 1) is already closed/implemented, confirming this layer can proceed immediately.
|
|
18
|
-
|
|
19
|
-
## Stage: Implementation — TDD (2026-05-24T21:00:00Z)
|
|
20
|
-
|
|
21
|
-
### Session summary
|
|
22
|
-
|
|
23
|
-
Completed all 4 TDD steps: renamed `SubagentRuntime.updateWidget()` → `update()`, moved `getMaxConcurrent` from manager interfaces to the `settings` narrow type, removed the dead `getToolCallName` re-export, and updated the architecture doc.
|
|
24
|
-
Test count stayed flat at 854 (53 files) — all green.
|
|
25
|
-
The `pnpm run check` type-gate caught a previously-unnoticed `test/helpers/make-deps.test.ts` that also validated `getMaxConcurrent` and the old `settings` shape; this file was updated as part of step 2.
|
|
26
|
-
|
|
27
|
-
### Observations
|
|
28
|
-
|
|
29
|
-
- An unexpected file `test/helpers/make-deps.test.ts` had three type errors after removing `getMaxConcurrent` (one test asserting `manager.getMaxConcurrent()`, one structural compatibility check referencing it, and one settings override that only passed `defaultMaxTurns`).
|
|
30
|
-
All three were fixed in the same commit as step 2 — no deviation from the plan.
|
|
31
|
-
- Adding `settings` to `BackgroundParams` (instead of as a 5th function parameter) was the right call: it keeps `spawnBackground` at 4 arguments and groups all spawn-context values together.
|
|
32
|
-
- The health metric update: dead exports 1 → 0, adapter closures 41 → 40 (only `getMaxConcurrent` was removed in this layer; the remaining 8 widget/manager adapter closures need #195 class conversion to collapse).
|
|
33
|
-
- The `background-spawner.ts` module is the only consumer of `getMaxConcurrent` — grep confirms no other call sites beyond `agent-tool.ts`'s interface definition.
|
|
34
|
-
- The `NotificationManager` constructor takes `updateWidget` as a positional callback parameter name — this does NOT need renaming (it's not a structural interface member).
|
|
35
|
-
- The rename from `updateWidget` → `update` is safe because the `WidgetLike` interface in `runtime.ts` already uses `update()` — no naming conflict within the class.
|
|
36
|
-
- All three changes are independent of each other and could be committed in any order, but the plan sequences them for clean `pnpm run check` passes at each step.
|
|
37
|
-
|
|
38
|
-
## Stage: Final Retrospective (2026-05-24T21:15:00Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
Planning, TDD implementation, and shipping completed in one continuous session.
|
|
43
|
-
Released as `pi-subagents-v7.2.1` with zero rework or deviations from the plan.
|
|
44
|
-
|
|
45
|
-
### Observations
|
|
46
|
-
|
|
47
|
-
#### What went well
|
|
48
|
-
|
|
49
|
-
- Clean execution end-to-end: 3 refactor commits + 1 docs commit, all planned in advance.
|
|
50
|
-
- The `pnpm run check` gate after step 2 caught `test/helpers/make-deps.test.ts` — a file the plan didn't list — preventing a broken intermediate state.
|
|
51
|
-
This validates the "run type-check after each step" pattern for interface-alignment work.
|
|
52
|
-
- Phased architecture approach paid off: Layers 0 and 1 being done made Layer 2 entirely mechanical.
|
|
53
|
-
|
|
54
|
-
#### What caused friction (agent side)
|
|
55
|
-
|
|
56
|
-
- None identified.
|
|
57
|
-
The issue scope was tight, the plan was unambiguous, and no rabbit-holes arose.
|
|
58
|
-
|
|
59
|
-
#### What caused friction (user side)
|
|
60
|
-
|
|
61
|
-
- None identified.
|
|
62
|
-
The issue body and architecture doc provided complete context with no ambiguity.
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 195
|
|
3
|
-
issue_title: "Convert tool factories to classes"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #195 — Convert tool factories to classes
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-24T12:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 5-step TDD plan converting `createAgentTool`, `createGetResultTool`, and `createSteerTool` to classes with constructor-injected dependencies.
|
|
13
|
-
Verified both prerequisites (#193, #194) are closed and their effects visible in the current source.
|
|
14
|
-
Designed narrow interfaces (`AgentToolRuntime`, `GetResultToolManager`, `SteerToolManager`, `SteerToolEvents`, etc.) that `SubagentRuntime`, `AgentManager`, and `NotificationManager` satisfy structurally.
|
|
15
|
-
|
|
16
|
-
### Observations
|
|
17
|
-
|
|
18
|
-
- The conversion is mechanical — no behavioral changes, just structural.
|
|
19
|
-
Existing tests cover all paths; only test helpers need updating.
|
|
20
|
-
- `steerAgent` and `getAgentConversation` are pure functions that can be imported directly by the classes rather than injected — simplifies the constructor signature.
|
|
21
|
-
- `agentDir` doesn't fit neatly on any existing collaborator, so it remains a constructor param for `AgentTool`.
|
|
22
|
-
- The `AgentToolWidget` interface may become redundant once `AgentToolRuntime` replaces it as the type passed to `spawnBackground`/`runForeground`, but this is deferred to implementation.
|
|
23
|
-
- Ordered TDD steps from smallest (SteerTool) to largest (AgentTool) to build confidence incrementally.
|
|
24
|
-
|
|
25
|
-
## Stage: Implementation — TDD (2026-05-24T21:26:00Z)
|
|
26
|
-
|
|
27
|
-
### Session summary
|
|
28
|
-
|
|
29
|
-
Completed all 5 planned TDD cycles (SteerTool → GetResultTool → AgentTool → `index.ts` wiring → architecture doc).
|
|
30
|
-
All 854 tests pass; type check and lint clean.
|
|
31
|
-
Total: 5 commits across source + test files, plus 1 cleanup fix commit.
|
|
32
|
-
|
|
33
|
-
### Observations
|
|
34
|
-
|
|
35
|
-
- `steerAgent` was inlined as `session.steer(message)` directly in `SteerTool.execute()` rather than imported as a module function.
|
|
36
|
-
This eliminated the dep entirely — the mock session's `steer` vi.fn() handles it in tests without `vi.mock`.
|
|
37
|
-
- The `verbose` test in `get-result-tool.test.ts` was upgraded to drive the real `getAgentConversation` function via `createMockSession({ messages: [...] })` overrides, making it a stronger integration test.
|
|
38
|
-
- `AgentToolWidget` was eliminated: `AgentToolRuntime` (a superset) replaced it, and `background-spawner` and `foreground-runner` already define their own narrow `BackgroundWidgetDeps`/`ForegroundWidgetDeps` interfaces.
|
|
39
|
-
- `createToolDeps()` changed shape from `AgentToolDeps` bag to `AgentToolFixture` (`{ manager, runtime, settings, registry, agentDir }`).
|
|
40
|
-
This required updating `background-spawner.test.ts` and `foreground-runner.test.ts` (not listed in the plan) to destructure `{ manager, runtime }` instead of `{ manager, widget, agentActivity }`.
|
|
41
|
-
- Biome flagged an unused `import type { AgentSession }` in `get-result-tool.ts` (left by ESLint's cast removal in step 2) — caught by `pnpm run lint` and fixed in a separate commit.
|
|
42
|
-
- The `ReturnType<typeof vi.fn>` annotation on `makeNotifications()` in the get-result-tool test triggered a TypeScript error; fixed by removing the return type annotation entirely (per testing skill guidance).
|
|
43
|
-
|
|
44
|
-
## Stage: Final Retrospective (2026-05-25T14:06:00Z)
|
|
45
|
-
|
|
46
|
-
### Session summary
|
|
47
|
-
|
|
48
|
-
Shipped #195 (three tool factory-to-class conversions), then discovered and fixed a process gap: the fallow dead-code gate was advisory (`continue-on-error: true`) and the `/tdd-plan` and `/ship-issue` prompts didn't run `pnpm fallow dead-code` at all.
|
|
49
|
-
Resulting follow-up work promoted all dead-code rule categories to `error` severity, split the CI fallow step into a hard gate plus advisory full report, and removed the genuinely dead `steerAgent` export and unused `@eslint/js` devDependency.
|
|
50
|
-
|
|
51
|
-
### Observations
|
|
52
|
-
|
|
53
|
-
#### What went well
|
|
54
|
-
|
|
55
|
-
- The user reading CI output carefully and asking "why did fallow check fail yet we proceeded to release?"
|
|
56
|
-
surfaced a real process gap that would have silently accumulated dead code over time.
|
|
57
|
-
- Incremental severity promotion was effective: checking each category's violation count before promoting let us ratchet from 3 error-level rules to 9 in three commits with zero cleanup work (all categories were already clean except the `steerAgent` export we'd just created).
|
|
58
|
-
|
|
59
|
-
#### What caused friction (agent side)
|
|
60
|
-
|
|
61
|
-
- `missing-context` — During the TDD session, I didn't run `pnpm fallow dead-code` after removing all callers of `steerAgent`, so the dead export shipped.
|
|
62
|
-
The existing `/tdd-plan` prompt's "after last step" checks didn't include fallow.
|
|
63
|
-
Impact: dead code shipped to a release, required a follow-up fix commit and re-release (`v7.2.2` → `v7.2.3`).
|
|
64
|
-
- `missing-context` — Used `// fallow-ignore-next-line unused-class-member -- reason text` but fallow parses every space-separated token after the rule name as additional rule names.
|
|
65
|
-
The existing codebase uses bare comments with no trailing text.
|
|
66
|
-
Impact: 12 stale-suppression warnings until the comment was fixed; no rework but added noise.
|
|
67
|
-
- `missing-context` — During planning, the Module-Level Changes section didn't list `background-spawner.test.ts` or `foreground-runner.test.ts`, even though both destructure `{ widget, agentActivity }` from `createToolDeps()`.
|
|
68
|
-
The testing skill already has guidance ("grep for ALL test files that construct a compatible mock") but I didn't apply it during planning.
|
|
69
|
-
Impact: caught immediately by running the full test suite; added friction but no rework.
|
|
70
|
-
|
|
71
|
-
#### What caused friction (user side)
|
|
72
|
-
|
|
73
|
-
- The fallow dead-code gap could have been caught earlier if the CI workflow had been configured to block on fallow findings from the start.
|
|
74
|
-
The `continue-on-error: true` was a reasonable initial setting during adoption but had outlived its usefulness.
|
|
75
|
-
|
|
76
|
-
### Follow-up ideas
|
|
77
|
-
|
|
78
|
-
- **Pre-completion reviewer subagent** — a `.pi/agents/pre-completion-reviewer.md` dispatched before `/ship-issue` that runs deterministic checks (`pnpm fallow dead-code`, `pnpm run check`, `pnpm run lint`, `pnpm vitest run`) and judgment checks (conventional commits, architecture doc staleness) in a fresh read-only context.
|
|
79
|
-
Modeled after RepOne's `pre-completion-reviewer` but scoped to this monorepo's needs.
|
|
80
|
-
This would be a separate issue.
|
|
81
|
-
|
|
82
|
-
### Changes made
|
|
83
|
-
|
|
84
|
-
1. `.pi/prompts/tdd-plan.md` — added `pnpm fallow dead-code` as step 4 in "After the last TDD step" (renumbered steps 4–7 → 5–8).
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 196
|
|
3
|
-
issue_title: "Convert AgentRunner and AgentsMenuHandler to classes, simplify index.ts"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #196 — Convert AgentRunner and AgentsMenuHandler to classes, simplify index.ts
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T14:35:46Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 6-step TDD plan covering the final two closure-factory-to-class conversions (`createAgentRunner` → `ConcreteAgentRunner`, `createAgentsMenuHandler` → `AgentsMenuHandler`) and the subsequent `index.ts` simplification.
|
|
13
|
-
Confirmed that `AgentManager` structurally satisfies `AgentMenuManager`, enabling direct pass-through without adapter closures.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The issue's proposed `AgentsMenuHandler` constructor omits `agentActivity`, but the class needs it for `viewAgentConversation`.
|
|
18
|
-
Plan includes it as a constructor param — minimal deviation from the issue.
|
|
19
|
-
- `getModelLabel` can be internalized into `AgentsMenuHandler` since it only uses two pure imported functions (`resolveModel`, `getModelLabelFromConfig`) plus the registry (already a constructor param).
|
|
20
|
-
This eliminates a 7-line closure from `index.ts`.
|
|
21
|
-
- Tests for `agent-runner` call `runAgent`/`resumeAgent` directly — no test uses `createAgentRunner`, so the runner conversion has zero test impact.
|
|
22
|
-
- The `agent-menu.test.ts` file is 215 lines and needs call-site updates (factory → class constructor + `.handle()`), but no logic changes.
|
|
23
|
-
- After both conversions, `index.ts` loses ~5 imports and ~4 adapter closures.
|
|
24
|
-
The remaining ~15 closures are structural (event registrations, SDK factory callbacks) and cannot be eliminated.
|
|
25
|
-
|
|
26
|
-
## Stage: Implementation — TDD (2026-05-25T14:56:11Z)
|
|
27
|
-
|
|
28
|
-
### Session summary
|
|
29
|
-
|
|
30
|
-
Completed all 6 plan steps (collapsed into 5 commits: steps 3 and 5 merged).
|
|
31
|
-
Baseline was 854 tests across 53 files; final suite is 856 tests across 54 files (+2 tests, +1 file for `concrete-agent-runner.test.ts`).
|
|
32
|
-
All type-check, lint, and dead-code gates pass clean.
|
|
33
|
-
|
|
34
|
-
### Observations
|
|
35
|
-
|
|
36
|
-
- Plan steps 3 and 5 had to be merged into a single commit: removing `createAgentsMenuHandler` immediately broke `index.ts` imports, so the `index.ts` update could not wait for a separate commit.
|
|
37
|
-
This is a known coupling when a factory's only call site is in `index.ts`.
|
|
38
|
-
- The `AgentsMenuHandler` class constructor includes `agentActivity` as planned (the issue's proposed signature omitted it; the plan's deviation was correct).
|
|
39
|
-
- `getModelLabel` internalization was clean: `resolveModel` and `getModelLabelFromConfig` are pure functions the class imports directly.
|
|
40
|
-
- `AgentManager` structurally satisfies `AgentMenuManager` with no adapter closures — confirmed by `pnpm run check` passing immediately.
|
|
41
|
-
- The `agent-menu.test.ts` refactor replaced `Partial<AgentMenuDeps>` overrides with a `makeHandler(opts)` helper that returns both the handler and collaborator stubs, which is cleaner for assertion.
|
|
42
|
-
- `rumdl` emitted 3 warnings in `pnpm run lint` — these are pre-existing and unrelated to this change (lint passes for markdown linting, the warnings are from biome/eslint steps that auto-fixed nothing).
|
|
43
|
-
|
|
44
|
-
## Stage: Final Retrospective (2026-05-25T15:04:47Z)
|
|
45
|
-
|
|
46
|
-
### Session summary
|
|
47
|
-
|
|
48
|
-
Completed all three stages (planning, TDD, shipping) in one sitting.
|
|
49
|
-
Issue #196 shipped as `pi-subagents-v7.2.5`.
|
|
50
|
-
All closure factories in pi-subagents are now classes; Phase 11 (Layers 3 + 4) is complete.
|
|
51
|
-
|
|
52
|
-
### Observations
|
|
53
|
-
|
|
54
|
-
#### What went well
|
|
55
|
-
|
|
56
|
-
- The three-session lifecycle (plan → TDD → ship) completed cleanly in a single sitting with no user corrections.
|
|
57
|
-
- Structural typing confirmation during planning paid off — `AgentManager` satisfied `AgentMenuManager` without adapter closures, and `pnpm run check` passed immediately after the wiring change.
|
|
58
|
-
- The `makeHandler(opts)` test helper pattern (returning handler + collaborator stubs) was cleaner than the `Partial<AgentMenuDeps>` spread approach it replaced.
|
|
59
|
-
|
|
60
|
-
#### What caused friction (agent side)
|
|
61
|
-
|
|
62
|
-
- `wrong-abstraction` — The plan separated factory removal (step 3) from call-site update (step 5), even though the testing skill already has a rule: "When a TDD step changes an interface that has a single call site, the step must include updating that call site."
|
|
63
|
-
The planner treated this as a testing concern and didn't apply it during plan authoring.
|
|
64
|
-
Impact: steps 3 and 5 had to be merged at implementation time, producing a commit message explaining the deviation.
|
|
65
|
-
Added a cross-reference to `plan-issue.md`.
|
|
66
|
-
|
|
67
|
-
#### What caused friction (user side)
|
|
68
|
-
|
|
69
|
-
Nothing notable — the user's issue was well-specified and the three `/` commands ran without intervention.
|
|
70
|
-
|
|
71
|
-
### Changes made
|
|
72
|
-
|
|
73
|
-
1. Added single-call-site rule to `.pi/prompts/plan-issue.md` TDD Order section: when a step removes a factory/export with one call site, include the call-site update in the same step.
|