@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.
Files changed (257) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +22 -31
  3. package/docs/architecture/architecture.md +157 -204
  4. package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
  5. package/package.json +5 -6
  6. package/src/lifecycle/subagent.ts +5 -9
  7. package/src/observation/notification.ts +23 -10
  8. package/src/observation/subagent-events-observer.ts +1 -3
  9. package/src/tools/get-result-report.ts +60 -0
  10. package/src/tools/get-result-tool.ts +25 -40
  11. package/src/types.ts +1 -1
  12. package/src/ui/session-navigator.ts +0 -2
  13. package/.prettierignore +0 -5
  14. package/AGENTS.md +0 -7
  15. package/docs/plans/0048-implement-subagents-api.md +0 -304
  16. package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
  17. package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
  18. package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
  19. package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
  20. package/docs/plans/0054-decompose-index-into-modules.md +0 -302
  21. package/docs/plans/0057-structured-debug-logging.md +0 -154
  22. package/docs/plans/0061-session-format-transcript.md +0 -284
  23. package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
  24. package/docs/plans/0069-create-subagent-runtime.md +0 -345
  25. package/docs/plans/0070-extract-event-handlers.md +0 -306
  26. package/docs/plans/0071-extract-session-config-assembler.md +0 -362
  27. package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
  28. package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
  29. package/docs/plans/0077-inject-project-agents-dir.md +0 -115
  30. package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
  31. package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
  32. package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
  33. package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
  34. package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
  35. package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
  36. package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
  37. package/docs/plans/0108-extract-agent-type-registry.md +0 -322
  38. package/docs/plans/0109-extract-settings-manager.md +0 -276
  39. package/docs/plans/0110-agent-activity-tracker.md +0 -297
  40. package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
  41. package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
  42. package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
  43. package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
  44. package/docs/plans/0115-decompose-agent-tool.md +0 -337
  45. package/docs/plans/0116-type-housekeeping.md +0 -351
  46. package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
  47. package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
  48. package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
  49. package/docs/plans/0132-inject-io-into-session-config.md +0 -219
  50. package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
  51. package/docs/plans/0134-reduce-as-any-casts.md +0 -366
  52. package/docs/plans/0135-extract-display-helpers.md +0 -182
  53. package/docs/plans/0136-decompose-agent-menu.md +0 -300
  54. package/docs/plans/0144-consolidate-observation-model.md +0 -263
  55. package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
  56. package/docs/plans/0146-narrow-ui-context.md +0 -319
  57. package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
  58. package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
  59. package/docs/plans/0152-add-prompt-snippet.md +0 -91
  60. package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
  61. package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
  62. package/docs/plans/0166-extract-parent-session-info.md +0 -231
  63. package/docs/plans/0167-narrow-runner-io.md +0 -150
  64. package/docs/plans/0168-extract-tool-filter-config.md +0 -173
  65. package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
  66. package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
  67. package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
  68. package/docs/plans/0172-extract-turn-formatting.md +0 -206
  69. package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
  70. package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
  71. package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
  72. package/docs/plans/0192-define-session-context-interface.md +0 -107
  73. package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
  74. package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
  75. package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
  76. package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
  77. package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
  78. package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
  79. package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
  80. package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
  81. package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
  82. package/docs/plans/0215-decompose-build-parent-context.md +0 -166
  83. package/docs/plans/0216-decompose-start-agent.md +0 -255
  84. package/docs/plans/0217-extract-overwrite-guard.md +0 -176
  85. package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
  86. package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
  87. package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
  88. package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
  89. package/docs/plans/0229-agent-born-complete.md +0 -564
  90. package/docs/plans/0230-extract-concurrency-queue.md +0 -265
  91. package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
  92. package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
  93. package/docs/plans/0237-remove-disallowed-tools.md +0 -180
  94. package/docs/plans/0238-remove-extensions-filtering.md +0 -191
  95. package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
  96. package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
  97. package/docs/plans/0256-extract-worktree-isolation.md +0 -256
  98. package/docs/plans/0257-extract-child-session-factory.md +0 -285
  99. package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
  100. package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
  101. package/docs/plans/0265-born-complete-subagent-session.md +0 -333
  102. package/docs/plans/0270-type-consumable-public-surface.md +0 -204
  103. package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
  104. package/docs/plans/0277-encapsulate-agent-session.md +0 -304
  105. package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
  106. package/docs/plans/0360-custom-agents-default-append.md +0 -132
  107. package/docs/plans/0373-extract-subagent-state.md +0 -250
  108. package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
  109. package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
  110. package/docs/plans/0376-extract-manager-observer.md +0 -232
  111. package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
  112. package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
  113. package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
  114. package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
  115. package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
  116. package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
  117. package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
  118. package/docs/plans/0412-unify-session-mock-builders.md +0 -146
  119. package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
  120. package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
  121. package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
  122. package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
  123. package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
  124. package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
  125. package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
  126. package/docs/plans/0427-reconsider-ui-direction.md +0 -212
  127. package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
  128. package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
  129. package/docs/plans/0444-shrink-widget-to-background-agents.md +0 -156
  130. package/docs/plans/0445-native-session-navigation.md +0 -365
  131. package/docs/plans/0446-spike-session-navigation-entry-criteria.md +0 -171
  132. package/docs/plans/0447-extract-subagents-settings-command.md +0 -220
  133. package/docs/plans/0448-block-disabled-agent-spawn.md +0 -207
  134. package/docs/plans/0462-navigation-renderer-tui-components.md +0 -338
  135. package/docs/plans/0463-file-snapshot-source-evicted-agents.md +0 -306
  136. package/docs/retro/0048-implement-subagents-api.md +0 -44
  137. package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
  138. package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
  139. package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
  140. package/docs/retro/0054-decompose-index-into-modules.md +0 -53
  141. package/docs/retro/0057-structured-debug-logging.md +0 -77
  142. package/docs/retro/0061-session-format-transcript.md +0 -41
  143. package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
  144. package/docs/retro/0069-create-subagent-runtime.md +0 -43
  145. package/docs/retro/0070-extract-event-handlers.md +0 -49
  146. package/docs/retro/0071-extract-session-config-assembler.md +0 -60
  147. package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
  148. package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
  149. package/docs/retro/0077-inject-project-agents-dir.md +0 -33
  150. package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
  151. package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
  152. package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
  153. package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
  154. package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
  155. package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
  156. package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
  157. package/docs/retro/0108-extract-agent-type-registry.md +0 -41
  158. package/docs/retro/0109-extract-settings-manager.md +0 -55
  159. package/docs/retro/0110-agent-activity-tracker.md +0 -44
  160. package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
  161. package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
  162. package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
  163. package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
  164. package/docs/retro/0115-decompose-agent-tool.md +0 -51
  165. package/docs/retro/0116-type-housekeeping.md +0 -42
  166. package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
  167. package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
  168. package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
  169. package/docs/retro/0132-inject-io-into-session-config.md +0 -33
  170. package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
  171. package/docs/retro/0134-reduce-as-any-casts.md +0 -56
  172. package/docs/retro/0135-extract-display-helpers.md +0 -38
  173. package/docs/retro/0136-decompose-agent-menu.md +0 -43
  174. package/docs/retro/0144-consolidate-observation-model.md +0 -39
  175. package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
  176. package/docs/retro/0146-narrow-ui-context.md +0 -70
  177. package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
  178. package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
  179. package/docs/retro/0152-add-prompt-snippet.md +0 -34
  180. package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
  181. package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
  182. package/docs/retro/0166-extract-parent-session-info.md +0 -66
  183. package/docs/retro/0167-narrow-runner-io.md +0 -63
  184. package/docs/retro/0168-extract-tool-filter-config.md +0 -76
  185. package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
  186. package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
  187. package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
  188. package/docs/retro/0172-extract-turn-formatting.md +0 -80
  189. package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
  190. package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
  191. package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
  192. package/docs/retro/0192-define-session-context-interface.md +0 -59
  193. package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
  194. package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
  195. package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
  196. package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
  197. package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
  198. package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
  199. package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
  200. package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
  201. package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
  202. package/docs/retro/0215-decompose-build-parent-context.md +0 -61
  203. package/docs/retro/0216-decompose-start-agent.md +0 -80
  204. package/docs/retro/0217-extract-overwrite-guard.md +0 -63
  205. package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
  206. package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
  207. package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
  208. package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
  209. package/docs/retro/0229-agent-born-complete.md +0 -89
  210. package/docs/retro/0230-extract-concurrency-queue.md +0 -38
  211. package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
  212. package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
  213. package/docs/retro/0237-remove-disallowed-tools.md +0 -78
  214. package/docs/retro/0238-remove-extensions-filtering.md +0 -72
  215. package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
  216. package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
  217. package/docs/retro/0256-extract-worktree-isolation.md +0 -89
  218. package/docs/retro/0257-extract-child-session-factory.md +0 -33
  219. package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
  220. package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
  221. package/docs/retro/0265-born-complete-subagent-session.md +0 -97
  222. package/docs/retro/0270-type-consumable-public-surface.md +0 -108
  223. package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
  224. package/docs/retro/0277-encapsulate-agent-session.md +0 -80
  225. package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
  226. package/docs/retro/0360-custom-agents-default-append.md +0 -81
  227. package/docs/retro/0373-extract-subagent-state.md +0 -94
  228. package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
  229. package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
  230. package/docs/retro/0376-extract-manager-observer.md +0 -81
  231. package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
  232. package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
  233. package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
  234. package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
  235. package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
  236. package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
  237. package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
  238. package/docs/retro/0412-unify-session-mock-builders.md +0 -80
  239. package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
  240. package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
  241. package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
  242. package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
  243. package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
  244. package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
  245. package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
  246. package/docs/retro/0427-reconsider-ui-direction.md +0 -102
  247. package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -45
  248. package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
  249. package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
  250. package/docs/retro/0445-native-session-navigation.md +0 -122
  251. package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
  252. package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
  253. package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
  254. package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
  255. package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
  256. package/src/observation/notification-state.ts +0 -27
  257. 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.