@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,99 +0,0 @@
1
- ---
2
- issue: 446
3
- issue_title: "pi-subagents: spike — resolve ADR-0004 session-navigation entry criteria"
4
- ---
5
-
6
- # Retro: #446 — pi-subagents: spike — resolve ADR-0004 session-navigation entry criteria
7
-
8
- ## Stage: Planning (2026-06-20T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Planned the Phase 19 Step 1 spike that answers the four ADR-0004 session-navigation entry criteria and records them as an ADR-0004 addendum.
13
- Confirmed the release is independent and that the only committed artifact is the addendum.
14
- The plan lives at `packages/pi-subagents/docs/plans/0446-spike-session-navigation-entry-criteria.md`; next stage is `/build-plan` (docs/spike deliverable, no committed TDD cycles).
15
-
16
- ### Observations
17
-
18
- - Operator owns the issue (`gotgenes` == gh user), so the "Proposed change" is the working hypothesis.
19
- Used `ask_user` once to resolve two method ambiguities: spike method = **automated observed test (vitest)**, committed artifact = **ADR addendum only** (the vitest harness is throwaway, discarded).
20
- - Gathered the SDK evidence up front so the addendum's expected answers are grounded: `switchSession` is a full active-session takeover that tears down the current runtime via `session_shutdown` (so it threatens the root's in-flight turn); `ReplacedSessionContext` exposes `sendUserMessage` (switch makes the child interactive); `loadEntriesFromFile`/`parseSessionEntries` read entries without switching; `Subagent.outputFile` already exposes the child JSONL path; sibling commands use flat hyphenated names (`agents`, `colgrep-reindex`, `permission-system`).
21
- - Expected recommendations the spike will confirm: read-only `loadEntriesFromFile` transcript (resolves root-continuity by construction), command-first parallel-agent selection (widget gesture deferred), and `/subagents-settings` (reject the ADR's tentative `/subagents:settings`).
22
- - `setBeforeSessionInvalidate` is a **host** runtime seam (`agent-session-runtime`/`interactive-mode`), not on the extension command context — noted in Background so Step 4 does not assume the extension can call it.
23
- - No production code changes and no invariants at risk; the read-only path was chosen partly to keep transcript rendering out of core (preserving the Phase 18 spine invariants from issues #422–#425).
24
-
25
- ## Stage: Implementation — Build (2026-06-20T10:00:00Z)
26
-
27
- ### Session summary
28
-
29
- Executed the spike: ran a throwaway vitest harness against a real 43-entry child session JSONL, confirmed the read-only transcript path, then wrote the ADR-0004 addendum answering all four entry criteria.
30
- Discarded the harness (operator decision: addendum only) and folded the architecture.md doc-sync into this build rather than deferring it.
31
- Four `docs:` commits; pre-completion reviewer returned WARN, whose findings were then resolved.
32
-
33
- ### Observations
34
-
35
- - **Key divergence from the plan (Finding 0):** the plan's Design Overview assumed `loadEntriesFromFile(path)` would be the read mechanism, but it is **not part of the package's public surface** — it lives in the deep `core/session-manager` module (marked `/** Exported for testing */`) and the public barrel (`src/index.ts` → `dist/index.{d.ts,js}`) re-exports only a curated subset that includes `parseSessionEntries` but not `loadEntriesFromFile`; the `exports` map exposes only `"."`, so the deep import is unsupported too.
36
- This is **not** a types/runtime mismatch — both barrels agree, and `tsc` rejects the import with `TS2305`.
37
- My first harness reached a runtime `is not a function` only because Vitest/esbuild strips types without type-checking; `pnpm run check` (`tsc`) would have caught it at compile time.
38
- My earlier "types/runtime mismatch" framing in the addendum/architecture was wrong and was corrected in a follow-up `docs:` commit.
39
- Viable path: `parseSessionEntries(readFileSync(outputFile, "utf8"))` (`parseSessionEntries` is public).
40
- - **Upgrade check (operator question):** verified the omission is **not** version-specific — the latest `0.79.8` barrel omits it identically to the pinned `0.79.1`, so an SDK bump does not surface `loadEntriesFromFile`.
41
- No upgrade pursued (out of scope for a docs-only spike); noted the routine `0.79.1` → `0.79.8` freshness gap as a separate, unrelated item.
42
- - **Doc-sync landed now, not deferred:** the reviewer flagged architecture.md line 997 ("Mechanism (confirmed by Step 1): `switchSession` … or `loadEntriesFromFile`") as actively contradicting the spike.
43
- Since the spike now exists, I marked Step 1 ✅ (heading + Mermaid node `S1`), corrected the Phase 18 summary line, and rewrote the Step 4 mechanism line to `parseSessionEntries(readFileSync(...))` — closing the WARN.
44
- - **Pre-completion reviewer: WARN** (no FAILs) — three architecture.md staleness findings, all addressed in the final `docs:` commit (`74e2374f`).
45
- No `src/`/`test/` changes; `pnpm run check` + `pnpm run lint` + `pnpm fallow dead-code` all green at baseline and after.
46
- - Release recommendation unchanged: **ship independently** (`Release: independent`).
47
-
48
- ## Stage: Final Retrospective (2026-06-20T18:00:00Z)
49
-
50
- ### Session summary
51
-
52
- Planned, built, and shipped the Phase 19 Step 1 spike across three workflow stages, producing the ADR-0004 addendum that answers all four session-navigation entry criteria and unblocks #445.
53
- The spike did its job — it rejected ADR-0004's literally-named `loadEntriesFromFile` mechanism before Step 4 coded against it — but the build stage committed an incorrect "types/runtime mismatch" characterization that took two user questions and a correction commit to fix.
54
- Eight `docs:` commits landed; no release (all `docs:`, auto-batched).
55
-
56
- ### Observations
57
-
58
- #### What went well
59
-
60
- - **The spike paid for itself, then over-delivered.**
61
- It caught that ADR-0004's named candidate (`loadEntriesFromFile`) is not in the SDK's public surface — a finding about the *implementation*, not the harness — before Step 4 started.
62
- The operator's three follow-up questions (upgrade?
63
- describe-the-mismatch?
64
- spike-vs-implementation impact?) then drove the addendum from a thin "use `parseSessionEntries`" note into a complete, link-backed render pipeline (Finding 1: `parseSessionEntries` → `buildSessionContext` → Pi's public entry components / `serializeConversation`).
65
- Step 4 now starts from a verified, public-API-only design.
66
- - **Clean, non-defensive self-correction.**
67
- When the operator asked me to substantiate the claim with links (turn 74), running the actual `tsc` probe surfaced my own error; I corrected all three artifacts (addendum, `architecture.md`, retro) in commit `112c4254` without hedging.
68
- "Ask the agent to cite/substantiate a claim" proved a high-leverage verification gesture.
69
-
70
- #### What caused friction (agent side)
71
-
72
- - `wrong-abstraction` (compounded by `missing-context`) — I diagnosed a question about the SDK's *export surface* from a *runtime* symptom.
73
- The throwaway vitest harness threw `loadEntriesFromFile is not a function`, and I leapt to the dramatic reading ("declared in `.d.ts` but absent at runtime — a types/runtime mismatch") instead of running `tsc`, which disambiguates instantly (`TS2305: has no exported member`).
74
- The symbol is simply not in the public barrel — types and runtime agree.
75
- Impact: an incorrect technical claim shipped into three committed artifacts (addendum `7c505b78`, `architecture.md`, the build retro note) and required a 3-file correction commit (`112c4254`) plus two operator questions to surface and fix.
76
- - `instruction-violation` (user-caught) — the `testing` skill already states "Vitest uses esbuild and does not typecheck; run `pnpm run check`."
77
- I never ran `tsc` against the harness or the export claim during the build.
78
- Two reasons it slipped: (1) the skill was not loaded — `/build-plan` only loads `testing` "if the plan involves test changes or TDD steps," and a docs-only spike using a throwaway harness does not obviously match; (2) the existing rule is framed for "type-only changes," not for *claims/findings about what a module exports*, so it would not clearly have fired even if loaded.
79
- - `other` (tooling friction, minor) — getting the `tsc` probe to resolve the package took four attempts (turns 77–80: `npx` blocked → `pnpm exec` → files-on-cmdline tsconfig error → probe-inside-package).
80
- Impact: added friction, no rework; not a conceptual rabbit-hole.
81
-
82
- #### What caused friction (user side)
83
-
84
- - None material — the operator's three interventions were strategic probes (dependency-freshness, claim substantiation, spike-vs-implementation scope) that each improved the artifact.
85
- The only "earlier" opportunity is an agent-side gap: I should have self-applied the `tsc` check so the operator did not need to ask "describe the mismatch" to trigger verification.
86
-
87
- ### Diagnostic details
88
-
89
- - **Model-performance correlation** — Planning + Build + the correction work all ran on `anthropic/claude-opus-4-8` (turns 2–104); the mischaracterization therefore occurred on the *strong* model, so the fix is process (run `tsc` on export claims), not model selection.
90
- The Ship stage (turns 106–122) ran on `opencode-go/deepseek-v4-flash` — appropriate cost-matching for a mechanical git/CI/close procedure, which it executed cleanly.
91
- A transient `anthropic/claude-sonnet-4-6` `model_change` carried no assistant turn (never ran).
92
- - **Escalation-delay tracking** — no rabbit-hole exceeded five consecutive tool calls on one error; the runtime `is not a function` was resolved in ~2 calls (the issue was the *interpretation*, not a stuck loop).
93
- - **Unused-tool detection** — for the mischaracterization, `tsc` / `pnpm run check` was available and routine but applied only at baseline (turn 29) and not again until the operator forced it (turns 77–80); it was never run against the harness or the claim.
94
- - **Feedback-loop gap analysis** — `pnpm run lint` ran after every doc edit (good incremental hygiene), but the *type-check* loop was skipped for precisely the finding that needed it — the harness ran under vitest (no typecheck) and `tsc` was not run on the export claim before committing it.
95
-
96
- ### Changes made
97
-
98
- 1. Extended the `testing` skill's `## Type checking` section to cover verifying claims about module exports with `tsc`, not runtime symptoms — `Refs #446`.
99
- File: `.pi/skills/testing/SKILL.md`.
@@ -1,91 +0,0 @@
1
- ---
2
- issue: 447
3
- issue_title: "pi-subagents: extract subagent settings to a focused /subagents-settings command"
4
- ---
5
-
6
- # Retro: #447 — pi-subagents: extract subagent settings to a focused /subagents-settings command
7
-
8
- ## Stage: Planning (2026-06-20T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Produced a numbered TDD plan for Phase 19 Step 2: a purely additive extraction of `AgentsMenuHandler.showSettings` into a standalone `SubagentsSettingsHandler` registered as the `/subagents-settings` command.
13
- Confirmed the command name against the closed spike (#446) and its ADR-0004 addendum (Criterion 4), and verified `SettingsManager` already structurally satisfies the new narrow manager interface so it can be passed directly.
14
- The plan ships independently (roadmap `Release: independent`).
15
-
16
- ### Observations
17
-
18
- - The extraction is a faithful verbatim lift — `showSettings` already had zero coupling beyond `this.settings` and `ui`, so the design-review checklist came back clean (100% field usage on both new narrow interfaces, no LoD/output-arg smells).
19
- Classified as a genuine collaborator extraction, not procedure-splitting.
20
- - Declared two narrow interfaces owned by the new module: `SubagentsSettingsManager` (shape-identical to the doomed `AgentMenuSettings` but with no import from `agent-menu.ts`) and `SubagentsSettingsUI` (drops `confirm`/`editor`/`custom` from `MenuUI` — ISP).
21
- - Strictly additive: `agent-menu.ts` is untouched, and its settings tests stay as-is because the in-menu path keeps shipping until Step 5 (#442) deletes the file.
22
- Removing them now would drop coverage of a live surface.
23
- - Preserved the single-selection-then-return semantics of `showSettings` verbatim (no re-show loop) — flagged a settings re-show loop as a deferred UX open question.
24
- - Two small TDD steps (handler+tests, then `index.ts` registration); noted they may fold into one commit since the export and its sole call site are tiny, with `pnpm run check` required right after the wiring step.
25
- - No third-party `ask_user` gate needed — issue filed by the operator (`gotgenes`), direction fixed by ADR-0004, design unambiguous.
26
-
27
- ## Stage: Implementation — TDD (2026-06-20T14:30:00Z)
28
-
29
- ### Session summary
30
-
31
- Implemented Phase 19 Step 2 in two TDD cycles plus a doc-sync commit: added `SubagentsSettingsHandler` (with narrow `SubagentsSettingsManager` and `SubagentsSettingsUI` interfaces) lifted verbatim from `AgentsMenuHandler.showSettings`, then registered the `/subagents-settings` command in `index.ts`.
32
- Test count went 1051 → 1062 (+11, one new file `test/ui/subagents-settings.test.ts`).
33
- Full suite, `tsc`, root lint, and `fallow dead-code` all green.
34
-
35
- ### Observations
36
-
37
- - The lift was clean: `SettingsManager` already exposed all six members of the new narrow manager interface, so the `index.ts` wiring passed `settings` directly with zero adapter — `pnpm run check` confirmed structural satisfaction.
38
- - `makeMenuUI` from `ui-stubs.ts` was reused as the UI stub without modification — its wider shape (`confirm`/`editor`/`custom`) structurally satisfies the narrower `SubagentsSettingsUI`, so no new helper was needed.
39
- - Kept the two cycles as separate commits rather than folding them; the export and its sole call site were small enough that either would have been valid.
40
- - Deviation from plan: flipped `✅` on the architecture Step 2 heading and its Mermaid node now (the plan had flagged this as a ship-time open question).
41
- Applied per the `/tdd-plan` template's roadmap-completion rule; verified the diagram still renders via `mmdc`.
42
- The phase status row was left unchanged (only 1 of 7 steps done).
43
- - `agent-menu.ts` was not touched (verified by the reviewer via `git log`), preserving the additive-only constraint.
44
- - Pre-completion reviewer: WARN.
45
- Reviewer warnings: one non-blocking finding — `.pi/skills/package-pi-subagents/SKILL.md` records `ui/` as 10 modules (now 11); the plan intentionally deferred this coarse-summary update to a later Phase 19 doc-sync.
46
- No FAILs; all deterministic checks PASS, verbatim-lift fidelity and ISP of both narrow interfaces confirmed.
47
-
48
- ## Stage: Final Retrospective (2026-06-20T18:36:58Z)
49
-
50
- ### Session summary
51
-
52
- Shipped Phase 19 Step 2 (#447) end to end across planning, TDD, and ship stages, releasing `pi-subagents` `17.1.0`.
53
- The one off-script event was a user-reported Mermaid syntax error in `architecture.md`, which I localized by extracting all six diagram blocks and running `mmdc` on each, then fixed by quoting the offending flowchart node labels.
54
- Execution was otherwise clean: two green TDD cycles (+11 tests), a WARN pre-completion review (one intentionally-deferred doc finding), and a correct `UNSTABLE`/`GITHUB_TOKEN` release-merge fallback.
55
-
56
- ### Observations
57
-
58
- #### What went well
59
-
60
- - Localizing the Mermaid error with the diagram name wrong: the user called it the "State dependency diagram" but the broken block was the "Step dependency diagram" flowchart.
61
- Rather than guess from the ambiguous name (I had glanced at the `stateDiagram-v2` lifecycle and the `classDiagram` first), I scripted extraction of all six `mermaid` fences and ran `mmdc` on each — block 6 failed with `got 'PS'`, pinpointing the exact line.
62
- Brute-force validation beat name-matching.
63
- - The release-merge fallback worked exactly as the ship prompt describes: `release_pr_merge` refused on `merge_state: UNSTABLE`, the status-check rollup was empty (the `GITHUB_TOKEN` no-checks case), and `gh pr merge 450 --rebase` + `git pull --ff-only` landed `17.1.0` linearly.
64
-
65
- #### What caused friction (agent side)
66
-
67
- - `missing-context` (prior session) — the broken diagram was authored in `74e2374f docs: mark Phase 19 Step 1 spike complete (#446)`: a flowchart node label `S1[✅ Step 1 - Spike (#446)]` with unquoted parentheses, which Mermaid parses as a nested round-node shape (`Expecting ... got 'PS'`).
68
- It was committed without an `mmdc` pass and slipped through `pnpm run lint` (rumdl validates markdown, not Mermaid semantics) and CI.
69
- Impact: surfaced two sessions later as a user-caught defect; one extra `docs:` fix commit (`90ca6e2d`) this session.
70
- Root cause is a coverage gap: the `mermaid` skill's pitfall list does not mention parentheses/shape-delimiter characters in node labels, so the exact failure mode was undocumented.
71
-
72
- #### What caused friction (user side)
73
-
74
- - None material.
75
- The diagram-name mismatch ("State" vs "Step" dependency diagram) added one or two orienting reads but did not cause rework — the all-blocks `mmdc` sweep absorbed the ambiguity.
76
-
77
- ### Diagnostic details
78
-
79
- - **Model-performance correlation** — the only subagent dispatch was the `pre-completion-reviewer` on `anthropic/claude-sonnet-4-6` (judgment-heavy review work); appropriate match, no over/under-powered mismatch.
80
- - **Escalation-delay tracking** — the Mermaid detour resolved in ~5 progress-making tool calls (extract blocks → `mmdc` each → read error → quote labels → re-validate); not a rabbit-hole, no subagent escalation warranted.
81
- - **Unused-tool detection** — none; `mmdc` (the correct validator) was used directly.
82
- - **Feedback-loop gap analysis** — verification ran incrementally throughout TDD (per-file `vitest` in each red/green, `pnpm run check` right after the interface-bearing wiring step, full suite + root lint + `fallow dead-code` at the end), not just terminally.
83
-
84
- ### Changes made
85
-
86
- 1. `.pi/skills/mermaid/SKILL.md` — added a "Parentheses and special characters in node labels" pitfall (with the `S1[✅ Step 1 - Spike (#446)]` WRONG/RIGHT example from this session) covering the `(`/`[`/`{`/`:` shape-delimiter trap that produced the `got 'PS'` parse error.
87
-
88
- ### Follow-up (not implemented — suggest a GitHub issue + `/plan-issue`)
89
-
90
- 1. **CI Mermaid-validation gate** — run `mmdc` over every `mermaid` fence as part of `pnpm run lint` or a pre-commit hook, so a broken diagram (like `74e2374f`'s unquoted-parens node) fails at author time instead of surviving to a user-caught defect.
91
- Out of retro scope (infra, touches `package.json`/lint config/hooks); record as its own issue.
@@ -1,75 +0,0 @@
1
- ---
2
- issue: 448
3
- issue_title: "`enabled: false` does not prevent explicitly spawning disabled agents"
4
- ---
5
-
6
- # Retro: #448 — `enabled: false` does not prevent explicitly spawning disabled agents
7
-
8
- ## Stage: Planning (2026-06-20T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Planned the fix for a third-party bug report: `enabled: false` agent overrides are hidden from the available-types list but still spawnable when named explicitly via `subagent_type`.
13
- The plan adds a disabled-type gate in `resolveSpawnConfig` (returning an explicit error) and a `enabled` filter in `buildTypeListText`, both localized changes with no new collaborators or interface changes.
14
-
15
- ### Observations
16
-
17
- - Issue author (`nickadminroot`) is not the operator (`gotgenes`), so I ran the `ask-user` direction gate.
18
- Operator confirmed: fix it, **return an explicit error** (`Agent type "<Name>" is disabled`) rather than the lenient fall-back-to-`general-purpose` alternative, and **include both fixes** (spawn path + tool-description list).
19
- - Root cause is `resolveType` → `resolveKey` ignoring `enabled`; the registry already has `isValidType` (checks `enabled`) but it was unused on the spawn path.
20
- The gate reuses `isValidType`, leaving `resolveType` / `resolveAgentConfig` untouched so UI consumers that intentionally resolve disabled configs keep working.
21
- - Rejected changing `resolveType` or `resolveAgentConfig` directly — `agent-config-editor.ts` and `agent-menu.ts` rely on resolving disabled agents to display/edit/re-enable them.
22
- - For the tool-description fix, chose to filter inside `buildTypeListText` rather than re-define `getDefaultAgentNames` / `getUserAgentNames` semantics; those two methods have `buildTypeListText` as their sole consumer (verified by grep), but keeping their meaning intact is cleaner.
23
- - Classified as non-breaking `fix:` — the change aligns code with the documented README/registry contract; explicit spawning of a disabled agent was undocumented buggy behavior.
24
- - Not in any architecture roadmap step (no `#448` reference in `docs/`), so **ship independently**.
25
-
26
- ## Stage: Implementation — TDD (2026-06-20T12:40:00Z)
27
-
28
- ### Session summary
29
-
30
- Completed 2 TDD cycles and all post-step verification gates.
31
- Step 1 added a 3-line enabled-type gate in `resolveSpawnConfig` (reusing `isValidType`) and 2 new test cases in `test/tools/spawn-config.test.ts`.
32
- Step 2 added an `isEnabled` predicate filter in `buildTypeListText` and 2 new test cases in `test/tools/helpers.test.ts`.
33
- Test count delta: 1047 → 1051 (+4).
34
-
35
- ### Observations
36
-
37
- - No deviations from the plan.
38
- Both changes were as small as designed: 3 lines in `spawn-config.ts`, 2 lines in `helpers.ts`.
39
- - Extended the `makeRegistry` stub's `resolve` type in `test/tools/helpers.test.ts` to include an optional `enabled` field, so the `isEnabled` predicate could be exercised without touching production code.
40
- - The `makeAgentConfig` helper was added to `test/tools/spawn-config.test.ts` (mirroring the pattern in `test/config/agent-types.test.ts`) rather than importing from a shared fixture, since the existing spawn-config test fixture infrastructure didn't need modification.
41
- - All three plan-enumerated cross-step invariants held green throughout: `resolveAgentConfig` disabled-config behavior, unknown-type fallback, and `getAllTypes` disabled-agent listing.
42
- - Pre-completion reviewer: **PASS** — all deterministic checks, code design, test artifacts, and cross-step invariants clean.
43
-
44
- ## Stage: Land — worktree (2026-06-20T17:57:54Z)
45
-
46
- ### Session summary
47
-
48
- Ran `/land-worktree 448` from the root checkout: fast-forward merged the peer branch `issue-448-enabled-false-does-not-prevent-explicitl` onto linear `main`, pushed, verified CI green, closed issue #448, merged the release-please PR, and tore down the worktree.
49
- Released `pi-subagents-v17.0.1` (the plan marked `Release: ship independently`).
50
-
51
- ### Observations
52
-
53
- #### What went well
54
-
55
- - The new `/land-worktree` flow (added in `7cbfea46`) ran cleanly end-to-end on a real issue: ff-merge → push → CI → `issue_close` → release → teardown, with no blockers or rework.
56
- - The release-please PR returned `MERGEABLE` / `UNSTABLE` with an empty `statusCheckRollup` — the documented `GITHUB_TOKEN` no-checks case.
57
- Falling back from `release_pr_merge` to `gh pr merge 449 --rebase` followed by `git pull --ff-only` worked exactly as the prompt anticipates.
58
-
59
- #### What caused friction (agent side)
60
-
61
- - `instruction-violation` (self-identified, in retro) — the prompt's step 6.2 says to check the **full** release-PR body for which packages it bumps **before** merging.
62
- I requested `body` in `gh pr view 449 --json body,...` but the `--jq` filter only printed `title`/`state`/`mergeStateStatus`/`statusCheckRollup`, so the body was never actually inspected.
63
- I learned the bumped package (`pi-subagents`) only **after** merging, from the `git pull` output.
64
- Impact: none this time (a single expected package bumped), but skipping the pre-merge body check means an unexpected sibling-package bump would slip through unnoticed.
65
-
66
- ### Diagnostic details
67
-
68
- - **Model-performance correlation** — no subagents dispatched; the land flow ran entirely on the parent session model.
69
- No mismatch.
70
- - **Escalation-delay tracking** — no rabbit-holes; no error retried more than once.
71
- - **Feedback-loop gap analysis** — no code changes in the land session, so CI (run on the pushed SHA, conclusion `success`) was the appropriate and only verification gate.
72
-
73
- ### Changes made
74
-
75
- 1. `.pi/prompts/land-worktree.md` — added a one-line nudge to step 6.2 to print the release-PR body explicitly with `gh pr view <N> --json body -q .body`, since a `--jq` that drops `body` skips the package-bump check silently.
@@ -1,105 +0,0 @@
1
- ---
2
- issue: 462
3
- issue_title: "pi-subagents: upgrade /subagent-sessions renderer to Pi per-entry TUI components"
4
- ---
5
-
6
- # Retro: #462 — pi-subagents: upgrade /subagent-sessions renderer to Pi per-entry TUI components
7
-
8
- ## Stage: Planning (2026-06-22T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Planned Phase 19 Step 4a: swap the `/subagent-sessions` renderer from `serializeConversation` plain text to Pi's per-entry TUI components behind the existing `TranscriptSource` seam.
13
- Verified the SDK surface (per-entry components, `parseSkillBlock`, `getMarkdownTheme`, `ToolDefinition`, `AgentSession.getToolDefinition`) and mirrored Pi's own `renderSessionContext`/`rebuildChatFromMessages` mapping.
14
- Wrote a four-step TDD plan at `packages/pi-subagents/docs/plans/0462-navigation-renderer-tui-components.md` and committed it.
15
-
16
- ### Observations
17
-
18
- - Three design decisions were surfaced via `ask_user` and locked by the operator:
19
- 1. **Rebuild-on-change** (mirror Pi's `rebuildChatFromMessages`) over incremental `updateContent`/`updateResult` — the seam exposes only a full `getMessages()` snapshot plus a coarse `onChange`, so incremental would still diff snapshots while replicating Pi's `pendingTools` streaming state machine for marginal benefit.
20
- 2. **Keep the lightweight `◍ describeActivity` text indicator** — this absorbs the high-frequency streaming text, so the persisted component tree only changes at message granularity, which is what keeps rebuild-on-change cheap.
21
- 3. **Wire real tool definitions** — the operator flagged a dependency-inversion risk ("can't `SubagentManager` track this?").
22
- Resolved dependency-safely: the SDK `AgentSession` already exposes `getToolDefinition(name)`, so a new read accessor on `SubagentSession`/`Subagent` (mirroring the existing `agentMessages` accessor) surfaces it through the record and onto the `TranscriptSource` seam — arrows stay inward, no `SubagentManager` bookkeeping.
23
- - Key structural move: the component renderer must leave the pure `session-navigation.ts` (per-entry components need `TUI`/`cwd`/`markdownTheme`) and live in the SDK/TUI `session-navigator.ts`.
24
- The pure module sheds `renderTranscriptLines`/`serializeConversation` entirely, becoming selection + sourcing only.
25
- - The `renderTranscriptLines` removal, overlay rewrite, `session-navigation.ts` edits, `index.ts` `cwd` wiring, and test updates must land in **one commit** (TDD step 3) — removing the export breaks the overlay and its tests at the type level.
26
- - Non-breaking internal renderer swap; `Release: independent` per the roadmap.
27
- Step 4a gates Step 5 ([#442]) for rendering parity but is not part of any release batch.
28
- - Follow-up [#463] (Step 4b, file-snapshot source) already exists and is open — referenced as a Non-Goal, nothing new to file.
29
- - Parity is defined as *using Pi's own components*, not byte-equality with the bespoke viewer; `custom`-role messages are skipped (the bespoke viewer never rendered them either), noted as an Open Question.
30
-
31
- ## Stage: Implementation — TDD (2026-06-22T21:30:00Z)
32
-
33
- ### Session summary
34
-
35
- Executed all four planned TDD steps: the `getToolDefinition` read accessor on `SubagentSession`/`Subagent`, the seam method on `TranscriptSource`/`NavigableSubagent`, the per-entry component renderer + overlay rewrite + `cwd` wiring, and the architecture doc flip (Step 4a `✅`).
36
- The renderer now mounts Pi's interactive components into a cached `Container` rebuilt on source change, mirroring Pi's `renderSessionContext`.
37
- Test count went from 1084 to 1088 (+4 net: +4 accessor/seam tests, +3 new navigator tests, −3 removed `renderTranscriptLines` tests), all green; one post-review `test:` commit pins invariant #423.
38
-
39
- ### Observations
40
-
41
- - The production code (`session-navigation.ts`, `session-navigator.ts`, `index.ts`) type-checked clean on the first `tsc` run — the SDK message-union narrowing (`switch (message.role)`), component construction, and `updateResult(toolResultMessage)` all resolved without casts.
42
- `SessionMessage` (= the SDK `AgentMessage` union) narrows by `role` even though `@earendil-works/pi-agent-core` is not a direct dependency.
43
- - Two deviations from the plan's Module-Level Changes, both intentional: (1) `src/types.ts` was *not* changed — `ToolDefinition` is imported directly from `@earendil-works/pi-coding-agent` in each consumer rather than re-exported through the barrel (avoids a speculative re-export `fallow` would flag); (2) `test/helpers/mock-session.ts` gained a `getToolDefinition` stub (needed for the step-1 accessor tests, not listed in the plan).
44
- - Pi's per-entry components read a *global* interactive theme initialized by `initTheme()`; Pi does this at startup, but tests had to call `initTheme(undefined, false)` in `beforeAll`.
45
- An early probe with `AssistantMessageComponent` passed without it, but `UserMessageComponent`/`ToolExecutionComponent` throw `"Theme not initialized"` — so the global-theme dependency is component-specific and only surfaced once the broader role set was exercised.
46
- - `setComplete`'s `TruncationResult` param requires more fields than `BashExecutionMessage` carries, so the bash component is completed with `undefined` truncation info (command + output still render).
47
- Pi's own JS passes `{ truncated: true }` but that path is untyped.
48
- - Pre-completion reviewer verdict: **WARN** (no failures; 3 non-blocking findings).
49
- Reviewer warnings: (1) `package-pi-subagents/SKILL.md` UI module count is stale (10 listed vs 13 actual) — predates this issue, plan left it deliberately; (2) `addMessageComponents` mutates the received `pendingTools` accumulator (output-argument pattern) — intentional, mirrors Pi's own `renderedPendingTools` local and was plan-reviewed; (3) invariant #423 held and is type-enforced but lacked an explicit spy pin — **addressed** by the follow-up `test:` commit asserting the handler never calls `record.getToolDefinition` directly.
50
-
51
- ## Stage: Final Retrospective (2026-06-23T00:00:00Z)
52
-
53
- ### Session summary
54
-
55
- Shipped Phase 19 Step 4a end-to-end across plan → TDD → ship: `/subagent-sessions` now renders through Pi's own per-entry interactive components behind the unchanged `TranscriptSource` seam, released as `pi-subagents` v17.4.0.
56
- Execution was notably clean — six commits, no rework of production code, CI green on the first push, and the only two friction points (a missing `initTheme()` in tests, a wrong post-review assertion) were each self-caught and resolved in a single iteration.
57
-
58
- ### Observations
59
-
60
- #### What went well
61
-
62
- 1. **Upfront SDK verification in planning paid off at implementation.**
63
- Planning inspected the actual component constructors, the `renderSessionContext` mapping, and `AgentSession.getToolDefinition` in `node_modules/**/*.d.ts` before committing to a design.
64
- Result: the production code (`session-navigation.ts`, `session-navigator.ts`, `index.ts`) type-checked clean on the *first* `tsc` run during TDD — the SDK message-union narrowing and component construction needed no casts.
65
- 2. **Probe-driven de-risking.**
66
- Before the renderer rewrite, a throwaway `_probe-theme.test.ts` confirmed `getMarkdownTheme()` + a Pi component render works outside interactive mode — validating the riskiest assumption cheaply, then deleted.
67
- 3. **The operator's planning interjections were strategic, not mechanical.**
68
- Rather than picking an `ask_user` option, the operator asked "what update frequency are we anticipating?"
69
- and flagged a dependency-inversion risk on tool definitions.
70
- Both redirects improved the design: the frequency analysis justified rebuild-on-change, and the inversion concern led to the dependency-safe `getToolDefinition` read accessor (discovered on the SDK, not invented).
71
- 4. **Incremental verification throughout.**
72
- Targeted `vitest` per Red→Green step, `pnpm run check` immediately after each shared-interface change, then full suite + root lint + `fallow dead-code` before each commit — no end-of-session verification pile-up.
73
- 5. **Pre-completion review caught a real gap and the fix's own bug was caught by the loop.**
74
- The reviewer flagged the missing #423 spy pin; while adding it, an over-assertion (`getToolDefinition` called on a no-toolCall fixture) failed the test run and was removed before committing.
75
-
76
- #### What caused friction (agent side)
77
-
78
- 1. `missing-context` (self-identified) — the `initTheme()` requirement for Pi's interactive components.
79
- The de-risking probe exercised only `AssistantMessageComponent`, which happens *not* to read the global theme, so the probe passed and gave false confidence.
80
- The real tests then threw `"Theme not initialized"` from `UserMessageComponent`/`ToolExecutionComponent`.
81
- Impact: one extra Red cycle (4 failing tests) → added `beforeAll(() => initTheme(undefined, false))`; no production rework.
82
- 2. `other` (self-identified) — a wrong second assertion in the post-review #423 pin (`expect(record.getToolDefinition).toHaveBeenCalled()` on a fixture whose assistant message had no `toolCall`, so the lookup never fires).
83
- Impact: one failed test run, immediately diagnosed and the bad assertion removed; ~1 iteration.
84
-
85
- #### What caused friction (user side)
86
-
87
- - None.
88
- The operator's interventions were timely and strategic (see What went well #3); no context was withheld and no correction was reactive.
89
-
90
- ### Diagnostic details
91
-
92
- - **Feedback-loop gap analysis** — no gap.
93
- Verification ran incrementally: per-step targeted `vitest`, `pnpm run check` after each interface change, full suite + lint + `fallow` before commits.
94
- Both friction points were caught by running tests *before* committing, not after.
95
- - **Escalation-delay tracking** — no rabbit holes; each friction point resolved in a single iteration (well under the 5-tool-call threshold).
96
- - **Probe-coverage note** — the `initTheme()` miss is a probe *coverage* gap, not a tool-availability gap: a one-variant probe (`AssistantMessageComponent`) did not validate the environment dependency of the broader component set actually used.
97
- - **Model-performance / unused-tool** — nothing notable.
98
- The only subagent dispatch (`pre-completion-reviewer`) is purpose-built for judgment-heavy review; SDK inspection used direct `grep`/`bash` over `.d.ts` files, which was appropriate.
99
-
100
- ### Changes made
101
-
102
- 1. `.pi/skills/package-pi-subagents/SKILL.md` — added a `## Testing` note: tests mounting Pi's per-entry interactive components must call `initTheme(undefined, false)` in `beforeAll`, with the component-specific / false-confidence caveat.
103
- 2. `.pi/skills/package-pi-subagents/SKILL.md` — corrected the stale UI domain module count (10 → 13) and extended its responsibility blurb to include session navigation.
104
- 3. `.pi/skills/testing/SKILL.md` — extended the existing "Exploration before planning" disposable-probe bullet to require exercising the full input variety (variant-specific environment dependencies defeat a one-representative probe).
105
- Placement confirmed with the operator: kept in the `testing` skill (loaded by both `/plan-issue` and `/tdd-plan`) next to the sibling rule, rather than duplicated into the plan prompt.
@@ -1,103 +0,0 @@
1
- ---
2
- issue: 463
3
- issue_title: "pi-subagents: add file-snapshot source to /subagent-sessions for evicted agents"
4
- ---
5
-
6
- # Retro: #463 — pi-subagents: add file-snapshot source to /subagent-sessions for evicted agents
7
-
8
- ## Stage: Planning (2026-06-23T00:00:00Z)
9
-
10
- ### Session summary
11
-
12
- Produced a 4-step plan for the Phase 19 Step 4b file-snapshot source: implement `fileSnapshotSource(outputFile, readFile)` in the pure `session-navigation.ts`, broaden the `/subagent-sessions` candidate set to evicted agents, and dual-source the handler by `NavigationEntry.kind`.
13
- The central design fork — how evicted agents enter the picker — was resolved with the operator via `ask_user`.
14
-
15
- ### Observations
16
-
17
- - **Eviction is memory management.**
18
- The cleanup sweep's `disposeSession()` frees the in-memory message history; the transcript survives only on disk.
19
- So rendering an evicted agent *always* reads the file (`fileSnapshotSource`) regardless of candidate-set strategy — the strategy only affects the picker *label*.
20
- - **Persisted child sessions carry no `type`/`description`.**
21
- The JSONL has only the conversation plus a header (`id`, `timestamp`, `cwd`, `parentSession`).
22
- A directory scan (the issue's literal wording) would therefore produce degraded labels and parse every file per open.
23
- - **Decision: manager-retained descriptors over directory scan.**
24
- The manager stashes a tiny no-messages `EvictedSubagent` descriptor in `cleanup()` before `removeRecord`, cleared in `clearCompleted()`/`dispose()`.
25
- Rich labels identical to live entries, bounded memory, no per-open parse.
26
- Coverage is limited to in-session evictions — which are the sweep's only targets, since a fresh manager per session never reloads prior-process subagents.
27
- Operator confirmed; an `(evicted)` snapshot marker was also chosen for the label.
28
- - **`NavigationEntry` becomes a discriminated union** (`live` | `evicted`); this breaks the handler, the `index.ts` call site, and both UI test files, so step 3 folds all of them into one commit.
29
- - **SDK-runtime call kept direct.** `fileSnapshotSource` calls `parseSessionEntries` / `buildSessionContext` directly rather than injecting them — the injected `readFile` already provides the unit-test seam, and there is no `no-restricted-imports` rule.
30
- - **Transient dead-code risk noted:** `fileSnapshotSource` and `listEvicted()` have no caller until step 3; flagged not to ship before step 3 lands (CI/`fallow` gate the pushed tip).
31
- - Release: independent (Phase 19 Step 4b roadmap tag).
32
-
33
- ## Stage: Implementation — TDD (2026-06-23T13:00:00Z)
34
-
35
- ### Session summary
36
-
37
- Executed all 4 plan steps in order: (1) `fileSnapshotSource` in the pure `session-navigation.ts`, (2) manager-retained `EvictedSubagent` descriptors (`cleanup` capture, `listEvicted`, `clearCompleted`/`dispose` clear), (3) the breaking `NavigationEntry` discriminated union + handler dual-source + `index.ts` wiring + all test updates in one commit, (4) architecture/ADR doc updates.
38
- Test count went from 1088 to 1099 (+11); full suite, `check`, root `lint`, and `fallow dead-code` all green.
39
-
40
- ### Observations
41
-
42
- - **No deviations from the plan.**
43
- All steps landed as written; Module-Level Changes matched the touched files exactly.
44
- - **Exploratory probe paid off.**
45
- A disposable script confirmed `buildSessionContext` auto-detects the leaf with no `leafId`, the `type !== "session"` filter drops the header, and empty entries yield `[]` — validating the `fileSnapshotSource` shape before writing the test.
46
- - **Two ESLint auto-fixes during commit hooks:** a stray `!` non-null assertion in the manager test (step 2) and four `entry?.kind` optional chains on a non-nullish destructured `entry` (`@typescript-eslint/no-unnecessary-condition`, step 3).
47
- Both fixed and re-committed; `check` + tests confirmed green after.
48
- - **Transient dead code** between steps 1–2 and 3 (predicted in the plan) cleared at the step-3 tip; final `fallow dead-code` is clean.
49
- - **Pre-completion reviewer: PASS** — deterministic checks, code design, test artifacts, Mermaid render, and all three cross-step invariants (no inbound core call, read-only overlay, renderer parity) verified; no follow-ups deferred.
50
-
51
- ## Stage: Final Retrospective (2026-06-23T17:43:05Z)
52
-
53
- ### Session summary
54
-
55
- Single continuous session carried #463 from planning through ship: a 4-step plan, TDD implementation (+11 tests, 1088→1099), pre-completion PASS, and release of `pi-subagents` v17.5.0.
56
- The defining moment was planning: an `ask_user` design gate plus operator Socratic pushback diverged the candidate-set design from the issue's literal "directory scan" wording to manager-retained descriptors.
57
- Execution was notably clean — no rework, no plan deviations, two auto-fixed lint nits.
58
-
59
- ### Observations
60
-
61
- #### What went well
62
-
63
- - **The `ask_user` gate caught a real design fork the issue body got wrong.**
64
- The issue's "Proposed change" said "enumerate persisted child-session JSONL files" (a directory scan).
65
- Exploration revealed the persisted session carries no subagent `type`/`description`, so a scan yields degraded labels.
66
- The gate surfaced descriptors-vs-scan-vs-hybrid; the operator's "why are we evicting at all?"
67
- and "tell me more about how the labels degrade" drove a better-grounded decision (descriptors).
68
- This is the `/plan-issue` "treat Proposed change as a hypothesis" contract working as intended — novel because the divergence was the *enumeration mechanism*, not a surface ambiguity.
69
- - **Exploratory probe before the first TDD test.**
70
- A disposable script (`explore-session.mjs`, deleted after) confirmed `buildSessionContext` auto-detects the leaf with no `leafId` and the `type !== "session"` filter drops the header — validating the `fileSnapshotSource` shape before any test was written (the `testing` skill's "inspect the actual runtime shape first" rule).
71
- - **The plan predicted transient dead code and sequenced to clear it.**
72
- `fileSnapshotSource` and `listEvicted()` had no caller until step 3; the plan flagged this and ordered the integration step to close it, so the final `fallow dead-code` gate passed with no surprise suppressions.
73
- - **Pre-completion reviewer ran on `claude-sonnet-4-6`** — model appropriate for the judgment-heavy invariant/design checklist; returned PASS.
74
-
75
- #### What caused friction (agent side)
76
-
77
- - `other` — the first `ask_user` led with the enumeration mechanism (descriptors/scan/hybrid) before establishing *why eviction creates the problem*.
78
- The operator's first reply was "Why are we 'evicting' subagents in the first place?", i.e. asking for the framing I already held but had not front-loaded.
79
- Impact: two extra `ask_user` round-trips before the decision — but they produced a better-understood outcome, so net-positive; no rework.
80
- - `other` (lint nit) — four `entry?.kind` optional chains on a destructured array element tripped `@typescript-eslint/no-unnecessary-condition`, and a stray `!` tripped `no-unnecessary-type-assertion`; both surfaced via the pre-commit hook.
81
- Impact: two re-commits during steps 2–3, auto-fixed, zero rework.
82
-
83
- #### What caused friction (user side)
84
-
85
- - None.
86
- The operator's Socratic questions mid-`ask_user` were the session's highest-value input — they converted a plausible-but-degraded design (scan) into the right one (descriptors).
87
- If anything, this is a model for how the gate should be used.
88
-
89
- ### Diagnostic details
90
-
91
- - **Model-performance correlation** — the `pre-completion-reviewer` subagent ran on `anthropic/claude-sonnet-4-6` (judgment-heavy review): appropriate, no mismatch.
92
- Main-thread `model_change` events included a `deepseek-v4-flash` variant; no quality degradation was observed in any artifact (plan, code, tests all clean), so no actionable correlation.
93
- - **Escalation-delay tracking** — no `rabbit-hole` points; longest same-error streak was the two lint auto-fixes, each resolved in one re-commit.
94
- - **Unused-tool detection** — exploration used `colgrep`, `grep`, and a disposable runtime probe; no missed-tool opportunities.
95
- - **Feedback-loop gap analysis** — verification ran incrementally: `pnpm run check` after the shared-interface steps (2 and 3), per-file `vitest` on each red/green cycle, and the full suite + lint + `fallow` before the docs commit.
96
- No end-only verification.
97
-
98
- ### Changes made
99
-
100
- 1. Appended this Final Retrospective stage entry to `packages/pi-subagents/docs/retro/0463-file-snapshot-source-evicted-agents.md`.
101
-
102
- No `AGENTS.md` or prompt changes — the session's friction was net-positive (the `ask_user` round-trips) or auto-fixed with zero rework (the lint nits).
103
- Two candidate changes were considered and rejected as noise (a `code-design` note on `entry?.kind` optional chaining; an `ask-user` "why-before-mechanism" guidance already covered by the skill).
@@ -1,27 +0,0 @@
1
- /**
2
- * notification-state.ts — NotificationState: notification-scoped tracking per background agent.
3
- *
4
- * Constructed once when agent-tool assigns the tool call ID (background agents only).
5
- * Foreground agents never get a NotificationState — record.notification stays undefined.
6
- */
7
-
8
- export class NotificationState {
9
- /** The tool call ID that spawned this background agent. Used in task-notification XML. */
10
- readonly toolCallId: string;
11
-
12
- private _resultConsumed = false;
13
-
14
- constructor(toolCallId: string) {
15
- this.toolCallId = toolCallId;
16
- }
17
-
18
- /** Whether the parent agent has already consumed this result (suppresses duplicate notifications). */
19
- get resultConsumed(): boolean {
20
- return this._resultConsumed;
21
- }
22
-
23
- /** Mark the result as consumed — suppresses the completion notification. */
24
- markConsumed(): void {
25
- this._resultConsumed = true;
26
- }
27
- }
package/vitest.config.ts DELETED
@@ -1,14 +0,0 @@
1
- import path from "node:path";
2
- import { defineConfig } from "vitest/config";
3
-
4
- export default defineConfig({
5
- resolve: {
6
- alias: {
7
- "#src": path.resolve(import.meta.dirname, "src"),
8
- "#test": path.resolve(import.meta.dirname, "test"),
9
- },
10
- },
11
- test: {
12
- include: ["test/**/*.test.ts"],
13
- },
14
- });