@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,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.
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 205
|
|
3
|
-
issue_title: "Decompose renderWidgetLines (cognitive 44)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #205 — Decompose renderWidgetLines
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T15:27:45Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Planned the decomposition of `renderWidgetLines` (cognitive complexity 44) into four private helper functions: `categorizeAgents`, `buildSections`, `assembleWithinBudget`, and `assembleOverflow`.
|
|
13
|
-
Also updated `architecture.md` Phase 12 steps with issue links (#205–#208) and added a Phase 12 row to the structural refactoring issues table.
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- The function's complexity comes from five interwoven concerns (categorization, section building, heading, non-overflow assembly with connector fixup, overflow-budget assembly) — but the extraction is mechanical since all logic is already pure and stateless.
|
|
18
|
-
- No new tests are needed — the existing 8 tests in `widget-renderer.test.ts` cover all branches end-to-end and remain the correct test level for assembly logic.
|
|
19
|
-
- The tree-connector fixup (swapping `├─` → `└─` via string replacement on Unicode chars) is the most fragile part; it stays as-is inside `assembleWithinBudget` rather than being further decomposed.
|
|
20
|
-
- A `sections` return object from `buildSections` bundles `finishedLines`, `runningLines`, and `queuedLine` to avoid long parameter lists on the assembly helpers.
|
|
21
|
-
|
|
22
|
-
## Stage: Implementation — TDD (2026-05-25T15:35:10Z)
|
|
23
|
-
|
|
24
|
-
### Session summary
|
|
25
|
-
|
|
26
|
-
Completed all four TDD steps: extracted `categorizeAgents`, `buildSections`, `assembleWithinBudget`, and `assembleOverflow` from `renderWidgetLines`.
|
|
27
|
-
All 23 `widget-renderer.test.ts` tests pass throughout; no new tests were added.
|
|
28
|
-
Full suite (856 tests, 54 files) is green; type check and lint are clean.
|
|
29
|
-
|
|
30
|
-
### Observations
|
|
31
|
-
|
|
32
|
-
- **Stray backtick during `assembleOverflow` extraction:** The Edit tool introduced a double-backtick (`\`\``) at the end of the nested template literal on the overflow indicator line — the inner template literal's closing backtick concatenated with the outer template's closing backtick, creating a parse error.
|
|
33
|
-
Required Python-based line-level surgery to fix since the Edit tool cannot reliably match nested template literals through JSON escaping.
|
|
34
|
-
- The `renderWidgetLines` `else` block removal also required Python because the Edit tool's `oldText` matching is unreliable when the target contains nested template literals with backticks.
|
|
35
|
-
- Aside from the template-literal matching friction, all extractions were purely mechanical; no logic changes were needed.
|
|
36
|
-
- The final `renderWidgetLines` is a clean 12-line orchestrator; each helper is well under complexity 10.
|
|
37
|
-
|
|
38
|
-
## Stage: Final Retrospective (2026-05-25T15:41:48Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
All three stages (planning, TDD implementation, shipping) completed in a single session.
|
|
43
|
-
Four refactor commits extracted `categorizeAgents`, `buildSections`, `assembleWithinBudget`, and `assembleOverflow` from `renderWidgetLines`, reducing cognitive complexity from 44 to <10 per function.
|
|
44
|
-
Released as `pi-subagents-v7.2.6`.
|
|
45
|
-
|
|
46
|
-
### Observations
|
|
47
|
-
|
|
48
|
-
#### What went well
|
|
49
|
-
|
|
50
|
-
- The planning-through-shipping pipeline was efficient: plan → 4 TDD steps → ship → release in one session with no rework.
|
|
51
|
-
- The plan correctly identified all four extraction targets and ordered TDD steps to avoid intermediate breakage.
|
|
52
|
-
- All 23 existing `widget-renderer.test.ts` tests passed throughout with zero modifications — the existing test coverage was at the right abstraction level for this refactoring.
|
|
53
|
-
- The `architecture.md` Phase 12 update (issue links, refactoring table row) was a clean opportunistic addition.
|
|
54
|
-
|
|
55
|
-
#### What caused friction (agent side)
|
|
56
|
-
|
|
57
|
-
- `other` (Edit tool limitation) — The Edit tool introduced a stray double-backtick when inserting `assembleOverflow`'s body, caused by JSON escaping colliding with nested template literal backticks.
|
|
58
|
-
The same limitation then prevented matching `oldText` containing nested template literals in the `renderWidgetLines` overflow block.
|
|
59
|
-
Required two Python-based line-level fixes via bash.
|
|
60
|
-
Impact: ~3 extra tool calls; self-identified and self-corrected.
|
|
61
|
-
|
|
62
|
-
#### What caused friction (user side)
|
|
63
|
-
|
|
64
|
-
- No friction observed.
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
issue: 206
|
|
3
|
-
issue_title: "Decompose showAgentDetail (cognitive 33)"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Retro: #206 — Decompose showAgentDetail (cognitive 33)
|
|
7
|
-
|
|
8
|
-
## Stage: Planning (2026-05-25T12:00:00Z)
|
|
9
|
-
|
|
10
|
-
### Session summary
|
|
11
|
-
|
|
12
|
-
Produced a 4-step plan to decompose `showAgentDetail` (cognitive 33) and `ejectAgent` (cognitive 20) in `ui/agent-config-editor.ts`.
|
|
13
|
-
The plan extracts two exported pure functions (`buildMenuOptions`, `buildEjectContent`) with dedicated unit tests, plus three closure-internal handlers (`handleEdit`, `handleDelete`, `handleReset`).
|
|
14
|
-
|
|
15
|
-
### Observations
|
|
16
|
-
|
|
17
|
-
- Three of the six action handlers (`ejectAgent`, `disableAgent`, `enableAgent`) were already extracted as closure functions — only Edit, Delete, and Reset were inlined in the dispatch chain.
|
|
18
|
-
- `buildMenuOptions` and `buildEjectContent` are ideal pure-function extractions: complex branching logic with no IO dependencies, previously untestable in isolation.
|
|
19
|
-
- The existing 18 integration tests through `showAgentDetail` provide a strong safety net — no risk of behavior regression during extraction.
|
|
20
|
-
- Chose to scope `ejectAgent` decomposition into this issue since the issue's outcome says "< 10 per function" and `ejectAgent` is at cognitive 20 in the same file.
|
|
21
|
-
- `disableAgent` and `enableAgent` were explicitly deferred — their cognitive complexity is manageable and decomposing them would add scope without meaningful benefit.
|
|
22
|
-
|
|
23
|
-
## Stage: Implementation — TDD (2026-05-25T11:55:00Z)
|
|
24
|
-
|
|
25
|
-
### Session summary
|
|
26
|
-
|
|
27
|
-
Completed all 4 TDD steps. 3 `refactor:` commits extract `buildMenuOptions`, the three inline handlers, and `buildEjectContent`; 1 `docs:` commit updates the architecture table.
|
|
28
|
-
Test count grew from 21 to 33 (+12 new unit tests for the two exported pure functions).
|
|
29
|
-
|
|
30
|
-
### Observations
|
|
31
|
-
|
|
32
|
-
- A `newText: null` bug in the Edit tool corrupted `agent-config-editor.ts` during step 1; recovered immediately by rewriting the file with `Write`.
|
|
33
|
-
- The test used `thinking: "auto"` which is not a valid `ThinkingLevel` — fixed by changing to `"low"` before the final commit; the type error was caught by `pnpm run check` after the TDD step.
|
|
34
|
-
- `buildMenuOptions` extracted cleanly with early-return style (no `let menuOptions` intermediate); the refactored function passes all 5 new unit tests and all 21 existing integration tests.
|
|
35
|
-
- `handleEdit`, `handleDelete`, and `handleReset` are closure-internal; they drop the outer `if (file)` guard since the menu only shows those options when `file` is defined.
|
|
36
|
-
- `buildEjectContent` extracted from `ejectAgent` reduces `ejectAgent` to a thin IO function (~10 lines); no behavior change verified by the existing eject integration tests.
|
|
37
|
-
|
|
38
|
-
## Stage: Final Retrospective (2026-05-25T12:10:00Z)
|
|
39
|
-
|
|
40
|
-
### Session summary
|
|
41
|
-
|
|
42
|
-
Completed full lifecycle — Planning, TDD (3 `refactor:` + 1 `docs:` commits, +12 tests), Ship, and Release (`pi-subagents-v7.2.7`) — in a single session with no user corrections.
|
|
43
|
-
|
|
44
|
-
### Observations
|
|
45
|
-
|
|
46
|
-
#### What went well
|
|
47
|
-
|
|
48
|
-
- The three-stage workflow (plan → TDD → ship) executed without any user intervention between stages.
|
|
49
|
-
Each stage's retro notes provided clean context for the next.
|
|
50
|
-
- Pure-function extraction pattern worked cleanly: `buildMenuOptions` and `buildEjectContent` exported for unit testing; `handleEdit`, `handleDelete`, `handleReset` kept as closure-internal, tested via existing integration tests.
|
|
51
|
-
- The existing 21 integration tests caught no regressions across all 3 refactor commits — strong safety net for mechanical extraction.
|
|
52
|
-
|
|
53
|
-
#### What caused friction (agent side)
|
|
54
|
-
|
|
55
|
-
- `other` — Passed `newText: null` to the `Edit` tool during TDD step 1, injecting a literal `null` into `agent-config-editor.ts` and corrupting the file.
|
|
56
|
-
Self-identified immediately via Biome autoformat failure.
|
|
57
|
-
Impact: one wasted tool round-trip; recovered by rewriting the file with `Write`.
|
|
58
|
-
- `missing-context` — Used `thinking: "auto"` in a `buildEjectContent` test fixture without checking `ThinkingLevel` is `"minimal" | "low" | "medium" | "high" | "xhigh"`.
|
|
59
|
-
Self-identified by `pnpm run check` post-TDD gate.
|
|
60
|
-
Impact: one `--amend` fix, no extra commit.
|
|
61
|
-
- `missing-context` — Plan stated "18 tests" as the baseline count; actual baseline was 21.
|
|
62
|
-
Impact: none — just an inaccurate number in the plan text.
|
|
63
|
-
|
|
64
|
-
#### What caused friction (user side)
|
|
65
|
-
|
|
66
|
-
- No user-side friction observed.
|
|
67
|
-
The user triggered each stage sequentially without needing to redirect or correct.
|