@gotgenes/pi-subagents 18.0.1 → 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 (260) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/docs/architecture/architecture.md +157 -204
  3. package/docs/architecture/history/phase-19-implement-ui-decisions.md +282 -0
  4. package/package.json +5 -6
  5. package/src/lifecycle/subagent.ts +5 -9
  6. package/src/observation/notification.ts +23 -10
  7. package/src/observation/subagent-events-observer.ts +1 -3
  8. package/src/tools/get-result-report.ts +60 -0
  9. package/src/tools/get-result-tool.ts +25 -40
  10. package/src/types.ts +1 -1
  11. package/src/ui/session-navigator.ts +0 -2
  12. package/.prettierignore +0 -5
  13. package/AGENTS.md +0 -7
  14. package/docs/plans/0048-implement-subagents-api.md +0 -304
  15. package/docs/plans/0049-remove-group-join-output-file-rpc.md +0 -180
  16. package/docs/plans/0051-update-adr-0001-hard-fork.md +0 -77
  17. package/docs/plans/0052-remove-scheduled-subagents.md +0 -133
  18. package/docs/plans/0053-extract-model-resolution-from-execute.md +0 -181
  19. package/docs/plans/0054-decompose-index-into-modules.md +0 -302
  20. package/docs/plans/0057-structured-debug-logging.md +0 -154
  21. package/docs/plans/0061-session-format-transcript.md +0 -284
  22. package/docs/plans/0066-replace-as-any-with-sdk-types.md +0 -215
  23. package/docs/plans/0069-create-subagent-runtime.md +0 -345
  24. package/docs/plans/0070-extract-event-handlers.md +0 -306
  25. package/docs/plans/0071-extract-session-config-assembler.md +0 -362
  26. package/docs/plans/0072-inject-agent-manager-collaborators.md +0 -329
  27. package/docs/plans/0076-inject-cwd-into-agent-manager.md +0 -102
  28. package/docs/plans/0077-inject-project-agents-dir.md +0 -115
  29. package/docs/plans/0080-consolidate-agent-config-lookup.md +0 -247
  30. package/docs/plans/0084-extract-git-worktree-manager.md +0 -142
  31. package/docs/plans/0087-evolve-subagent-runtime-methods.md +0 -240
  32. package/docs/plans/0098-extract-agent-record-state-machine.md +0 -435
  33. package/docs/plans/0099-replace-ctx-with-parent-snapshot.md +0 -488
  34. package/docs/plans/0100-replace-callback-threading-with-session-subscription.md +0 -454
  35. package/docs/plans/0102-consolidate-test-record-factory.md +0 -176
  36. package/docs/plans/0108-extract-agent-type-registry.md +0 -322
  37. package/docs/plans/0109-extract-settings-manager.md +0 -276
  38. package/docs/plans/0110-agent-activity-tracker.md +0 -297
  39. package/docs/plans/0111-split-agent-record-lifecycle.md +0 -582
  40. package/docs/plans/0112-replace-agent-manager-callbacks.md +0 -241
  41. package/docs/plans/0113-disambiguate-spawn-options.md +0 -155
  42. package/docs/plans/0114-narrow-agent-tool-menu-deps.md +0 -279
  43. package/docs/plans/0115-decompose-agent-tool.md +0 -337
  44. package/docs/plans/0116-type-housekeeping.md +0 -351
  45. package/docs/plans/0118-settings-manager-apply-methods.md +0 -271
  46. package/docs/plans/0123-remove-vi-fn-cast-smell.md +0 -179
  47. package/docs/plans/0131-consolidate-shared-test-fixtures.md +0 -207
  48. package/docs/plans/0132-inject-io-into-session-config.md +0 -219
  49. package/docs/plans/0133-inject-sdk-boundary-into-agent-runner.md +0 -373
  50. package/docs/plans/0134-reduce-as-any-casts.md +0 -366
  51. package/docs/plans/0135-extract-display-helpers.md +0 -182
  52. package/docs/plans/0136-decompose-agent-menu.md +0 -300
  53. package/docs/plans/0144-consolidate-observation-model.md +0 -263
  54. package/docs/plans/0145-decompose-execute-push-ctx-to-boundary.md +0 -290
  55. package/docs/plans/0146-narrow-ui-context.md +0 -319
  56. package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +0 -166
  57. package/docs/plans/0148-split-agent-widget-rendering.md +0 -255
  58. package/docs/plans/0152-add-prompt-snippet.md +0 -91
  59. package/docs/plans/0164-reorganize-into-domain-directories.md +0 -409
  60. package/docs/plans/0165-decompose-resolved-spawn-config.md +0 -157
  61. package/docs/plans/0166-extract-parent-session-info.md +0 -231
  62. package/docs/plans/0167-narrow-runner-io.md +0 -150
  63. package/docs/plans/0168-extract-tool-filter-config.md +0 -173
  64. package/docs/plans/0169-extract-run-context-from-run-options.md +0 -194
  65. package/docs/plans/0170-reduce-build-content-lines-complexity.md +0 -225
  66. package/docs/plans/0171-reduce-render-result-complexity.md +0 -200
  67. package/docs/plans/0172-extract-turn-formatting.md +0 -206
  68. package/docs/plans/0180-reorder-append-prompt-for-kv-cache.md +0 -100
  69. package/docs/plans/0185-remove-persistent-agent-memory.md +0 -161
  70. package/docs/plans/0188-replace-any-casts-with-sdk-types.md +0 -162
  71. package/docs/plans/0192-define-session-context-interface.md +0 -107
  72. package/docs/plans/0193-runtime-owns-context-queries.md +0 -245
  73. package/docs/plans/0194-align-tool-interfaces-for-structural-typing.md +0 -139
  74. package/docs/plans/0195-convert-tool-factories-to-classes.md +0 -264
  75. package/docs/plans/0196-convert-runner-menu-to-classes.md +0 -268
  76. package/docs/plans/0205-decompose-render-widget-lines.md +0 -140
  77. package/docs/plans/0206-decompose-show-agent-detail.md +0 -211
  78. package/docs/plans/0207-decompose-agent-widget-update.md +0 -242
  79. package/docs/plans/0208-extract-shared-test-fixtures.md +0 -298
  80. package/docs/plans/0214-convert-remaining-closure-factories-to-classes.md +0 -261
  81. package/docs/plans/0215-decompose-build-parent-context.md +0 -166
  82. package/docs/plans/0216-decompose-start-agent.md +0 -255
  83. package/docs/plans/0217-extract-overwrite-guard.md +0 -176
  84. package/docs/plans/0218-push-sdk-boundary-in-settings.md +0 -172
  85. package/docs/plans/0219-reduce-test-duplication-top-3-clone-families.md +0 -162
  86. package/docs/plans/0227-evolve-agent-record-into-agent.md +0 -322
  87. package/docs/plans/0228-async-start-agent-dissolve-run-handle.md +0 -288
  88. package/docs/plans/0229-agent-born-complete.md +0 -564
  89. package/docs/plans/0230-extract-concurrency-queue.md +0 -265
  90. package/docs/plans/0231-push-exec-registry-to-runner.md +0 -245
  91. package/docs/plans/0232-agent-resume-internal-observer-lifecycle.md +0 -180
  92. package/docs/plans/0237-remove-disallowed-tools.md +0 -180
  93. package/docs/plans/0238-remove-extensions-filtering.md +0 -191
  94. package/docs/plans/0239-collapse-filter-active-tools.md +0 -217
  95. package/docs/plans/0242-rename-agent-tool-to-subagent.md +0 -165
  96. package/docs/plans/0256-extract-worktree-isolation.md +0 -256
  97. package/docs/plans/0257-extract-child-session-factory.md +0 -285
  98. package/docs/plans/0262-add-workspace-provider-seam.md +0 -264
  99. package/docs/plans/0264-remove-extension-lifecycle-control.md +0 -277
  100. package/docs/plans/0265-born-complete-subagent-session.md +0 -333
  101. package/docs/plans/0270-type-consumable-public-surface.md +0 -204
  102. package/docs/plans/0272-export-workspace-collaborator-types.md +0 -147
  103. package/docs/plans/0277-encapsulate-agent-session.md +0 -304
  104. package/docs/plans/0280-rename-agent-to-subagent.md +0 -197
  105. package/docs/plans/0360-custom-agents-default-append.md +0 -132
  106. package/docs/plans/0373-extract-subagent-state.md +0 -250
  107. package/docs/plans/0374-encapsulate-subagent-start-notification.md +0 -268
  108. package/docs/plans/0375-extract-run-listener-workspace-bracket.md +0 -300
  109. package/docs/plans/0376-extract-manager-observer.md +0 -232
  110. package/docs/plans/0377-split-widget-delegation-from-runtime.md +0 -254
  111. package/docs/plans/0378-consolidate-lifecycle-test-fixtures.md +0 -243
  112. package/docs/plans/0379-consolidate-ui-tools-test-fixtures.md +0 -335
  113. package/docs/plans/0380-extract-layered-settings-loader.md +0 -223
  114. package/docs/plans/0381-replace-concurrency-queue-with-limiter.md +0 -267
  115. package/docs/plans/0400-include-parent-prompt-in-replace-mode.md +0 -199
  116. package/docs/plans/0403-abort-subagents-on-interrupt.md +0 -180
  117. package/docs/plans/0412-unify-session-mock-builders.md +0 -146
  118. package/docs/plans/0420-fold-run-metrics-live-activity-onto-record.md +0 -228
  119. package/docs/plans/0421-migrate-activity-readers-to-record-getters.md +0 -309
  120. package/docs/plans/0422-delete-activity-tracker-ui-observer.md +0 -204
  121. package/docs/plans/0423-widget-self-drive-from-lifecycle.md +0 -264
  122. package/docs/plans/0424-drop-widget-dep-from-subagent-tool.md +0 -166
  123. package/docs/plans/0425-reconcile-subagent-events-contract.md +0 -144
  124. package/docs/plans/0426-consolidate-residual-test-clone-families.md +0 -235
  125. package/docs/plans/0427-reconsider-ui-direction.md +0 -212
  126. package/docs/plans/0441-remove-agent-definition-management-subtree.md +0 -180
  127. package/docs/plans/0442-dissolve-agents-conversation-viewer.md +0 -195
  128. package/docs/plans/0443-consolidate-remaining-test-clone-families.md +0 -268
  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/plans/0470-refresh-readme-command-surface.md +0 -159
  137. package/docs/retro/0048-implement-subagents-api.md +0 -44
  138. package/docs/retro/0049-remove-group-join-output-file-rpc.md +0 -49
  139. package/docs/retro/0051-update-adr-0001-hard-fork.md +0 -39
  140. package/docs/retro/0053-extract-model-resolution-from-execute.md +0 -40
  141. package/docs/retro/0054-decompose-index-into-modules.md +0 -53
  142. package/docs/retro/0057-structured-debug-logging.md +0 -77
  143. package/docs/retro/0061-session-format-transcript.md +0 -41
  144. package/docs/retro/0066-replace-as-any-with-sdk-types.md +0 -44
  145. package/docs/retro/0069-create-subagent-runtime.md +0 -43
  146. package/docs/retro/0070-extract-event-handlers.md +0 -49
  147. package/docs/retro/0071-extract-session-config-assembler.md +0 -60
  148. package/docs/retro/0072-inject-agent-manager-collaborators.md +0 -46
  149. package/docs/retro/0076-inject-cwd-into-agent-manager.md +0 -35
  150. package/docs/retro/0077-inject-project-agents-dir.md +0 -33
  151. package/docs/retro/0080-consolidate-agent-config-lookup.md +0 -35
  152. package/docs/retro/0084-extract-git-worktree-manager.md +0 -37
  153. package/docs/retro/0087-evolve-subagent-runtime-methods.md +0 -42
  154. package/docs/retro/0098-extract-agent-record-state-machine.md +0 -46
  155. package/docs/retro/0099-replace-ctx-with-parent-snapshot.md +0 -37
  156. package/docs/retro/0100-replace-callback-threading-with-session-subscription.md +0 -36
  157. package/docs/retro/0102-consolidate-test-record-factory.md +0 -30
  158. package/docs/retro/0108-extract-agent-type-registry.md +0 -41
  159. package/docs/retro/0109-extract-settings-manager.md +0 -55
  160. package/docs/retro/0110-agent-activity-tracker.md +0 -44
  161. package/docs/retro/0111-split-agent-record-lifecycle.md +0 -61
  162. package/docs/retro/0112-replace-agent-manager-callbacks.md +0 -35
  163. package/docs/retro/0113-disambiguate-spawn-options.md +0 -29
  164. package/docs/retro/0114-narrow-agent-tool-menu-deps.md +0 -38
  165. package/docs/retro/0115-decompose-agent-tool.md +0 -51
  166. package/docs/retro/0116-type-housekeeping.md +0 -42
  167. package/docs/retro/0118-settings-manager-apply-methods.md +0 -40
  168. package/docs/retro/0123-remove-vi-fn-cast-smell.md +0 -49
  169. package/docs/retro/0131-consolidate-shared-test-fixtures.md +0 -46
  170. package/docs/retro/0132-inject-io-into-session-config.md +0 -33
  171. package/docs/retro/0133-inject-sdk-boundary-into-agent-runner.md +0 -45
  172. package/docs/retro/0134-reduce-as-any-casts.md +0 -56
  173. package/docs/retro/0135-extract-display-helpers.md +0 -38
  174. package/docs/retro/0136-decompose-agent-menu.md +0 -43
  175. package/docs/retro/0144-consolidate-observation-model.md +0 -39
  176. package/docs/retro/0145-decompose-execute-push-ctx-to-boundary.md +0 -56
  177. package/docs/retro/0146-narrow-ui-context.md +0 -70
  178. package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +0 -90
  179. package/docs/retro/0148-split-agent-widget-rendering.md +0 -39
  180. package/docs/retro/0152-add-prompt-snippet.md +0 -34
  181. package/docs/retro/0164-reorganize-into-domain-directories.md +0 -82
  182. package/docs/retro/0165-decompose-resolved-spawn-config.md +0 -78
  183. package/docs/retro/0166-extract-parent-session-info.md +0 -66
  184. package/docs/retro/0167-narrow-runner-io.md +0 -63
  185. package/docs/retro/0168-extract-tool-filter-config.md +0 -76
  186. package/docs/retro/0169-extract-run-context-from-run-options.md +0 -68
  187. package/docs/retro/0170-reduce-build-content-lines-complexity.md +0 -72
  188. package/docs/retro/0171-reduce-render-result-complexity.md +0 -77
  189. package/docs/retro/0172-extract-turn-formatting.md +0 -80
  190. package/docs/retro/0180-reorder-append-prompt-for-kv-cache.md +0 -62
  191. package/docs/retro/0185-remove-persistent-agent-memory.md +0 -73
  192. package/docs/retro/0188-replace-any-casts-with-sdk-types.md +0 -69
  193. package/docs/retro/0192-define-session-context-interface.md +0 -59
  194. package/docs/retro/0193-runtime-owns-context-queries.md +0 -75
  195. package/docs/retro/0194-align-tool-interfaces-for-structural-typing.md +0 -62
  196. package/docs/retro/0195-convert-tool-factories-to-classes.md +0 -84
  197. package/docs/retro/0196-convert-runner-menu-to-classes.md +0 -73
  198. package/docs/retro/0205-decompose-render-widget-lines.md +0 -64
  199. package/docs/retro/0206-decompose-show-agent-detail.md +0 -67
  200. package/docs/retro/0207-decompose-agent-widget-update.md +0 -92
  201. package/docs/retro/0208-extract-shared-test-fixtures.md +0 -102
  202. package/docs/retro/0214-convert-remaining-closure-factories-to-classes.md +0 -66
  203. package/docs/retro/0215-decompose-build-parent-context.md +0 -61
  204. package/docs/retro/0216-decompose-start-agent.md +0 -80
  205. package/docs/retro/0217-extract-overwrite-guard.md +0 -63
  206. package/docs/retro/0218-push-sdk-boundary-in-settings.md +0 -72
  207. package/docs/retro/0219-reduce-test-duplication-top-3-clone-families.md +0 -64
  208. package/docs/retro/0227-evolve-agent-record-into-agent.md +0 -80
  209. package/docs/retro/0228-async-start-agent-dissolve-run-handle.md +0 -80
  210. package/docs/retro/0229-agent-born-complete.md +0 -89
  211. package/docs/retro/0230-extract-concurrency-queue.md +0 -38
  212. package/docs/retro/0231-push-exec-registry-to-runner.md +0 -71
  213. package/docs/retro/0232-agent-resume-internal-observer-lifecycle.md +0 -109
  214. package/docs/retro/0237-remove-disallowed-tools.md +0 -78
  215. package/docs/retro/0238-remove-extensions-filtering.md +0 -72
  216. package/docs/retro/0239-collapse-filter-active-tools.md +0 -70
  217. package/docs/retro/0242-rename-agent-tool-to-subagent.md +0 -82
  218. package/docs/retro/0256-extract-worktree-isolation.md +0 -89
  219. package/docs/retro/0257-extract-child-session-factory.md +0 -33
  220. package/docs/retro/0262-add-workspace-provider-seam.md +0 -89
  221. package/docs/retro/0264-remove-extension-lifecycle-control.md +0 -91
  222. package/docs/retro/0265-born-complete-subagent-session.md +0 -97
  223. package/docs/retro/0270-type-consumable-public-surface.md +0 -108
  224. package/docs/retro/0272-export-workspace-collaborator-types.md +0 -38
  225. package/docs/retro/0277-encapsulate-agent-session.md +0 -80
  226. package/docs/retro/0280-rename-agent-to-subagent.md +0 -96
  227. package/docs/retro/0360-custom-agents-default-append.md +0 -81
  228. package/docs/retro/0373-extract-subagent-state.md +0 -94
  229. package/docs/retro/0374-encapsulate-subagent-start-notification.md +0 -171
  230. package/docs/retro/0375-extract-run-listener-workspace-bracket.md +0 -104
  231. package/docs/retro/0376-extract-manager-observer.md +0 -81
  232. package/docs/retro/0377-split-widget-delegation-from-runtime.md +0 -105
  233. package/docs/retro/0378-consolidate-lifecycle-test-fixtures.md +0 -100
  234. package/docs/retro/0379-consolidate-ui-tools-test-fixtures.md +0 -52
  235. package/docs/retro/0380-extract-layered-settings-loader.md +0 -97
  236. package/docs/retro/0381-replace-concurrency-queue-with-limiter.md +0 -95
  237. package/docs/retro/0400-include-parent-prompt-in-replace-mode.md +0 -84
  238. package/docs/retro/0403-abort-subagents-on-interrupt.md +0 -90
  239. package/docs/retro/0412-unify-session-mock-builders.md +0 -80
  240. package/docs/retro/0420-fold-run-metrics-live-activity-onto-record.md +0 -90
  241. package/docs/retro/0421-migrate-activity-readers-to-record-getters.md +0 -105
  242. package/docs/retro/0422-delete-activity-tracker-ui-observer.md +0 -97
  243. package/docs/retro/0423-widget-self-drive-from-lifecycle.md +0 -112
  244. package/docs/retro/0424-drop-widget-dep-from-subagent-tool.md +0 -89
  245. package/docs/retro/0425-reconcile-subagent-events-contract.md +0 -101
  246. package/docs/retro/0426-consolidate-residual-test-clone-families.md +0 -100
  247. package/docs/retro/0427-reconsider-ui-direction.md +0 -102
  248. package/docs/retro/0441-remove-agent-definition-management-subtree.md +0 -97
  249. package/docs/retro/0442-dissolve-agents-conversation-viewer.md +0 -108
  250. package/docs/retro/0443-consolidate-remaining-test-clone-families.md +0 -28
  251. package/docs/retro/0444-shrink-widget-to-background-agents.md +0 -81
  252. package/docs/retro/0445-native-session-navigation.md +0 -122
  253. package/docs/retro/0446-spike-session-navigation-entry-criteria.md +0 -99
  254. package/docs/retro/0447-extract-subagents-settings-command.md +0 -91
  255. package/docs/retro/0448-block-disabled-agent-spawn.md +0 -75
  256. package/docs/retro/0462-navigation-renderer-tui-components.md +0 -105
  257. package/docs/retro/0463-file-snapshot-source-evicted-agents.md +0 -103
  258. package/docs/retro/0470-refresh-readme-command-surface.md +0 -40
  259. package/src/observation/notification-state.ts +0 -27
  260. package/vitest.config.ts +0 -14
@@ -1,298 +0,0 @@
1
- ---
2
- issue: 208
3
- issue_title: "Extract shared test fixtures to reduce test duplication"
4
- ---
5
-
6
- # Extract shared test fixtures
7
-
8
- ## Problem Statement
9
-
10
- Test duplication across the pi-subagents package is 1,367 lines (7.2%) across 23 files (67 clone groups per fallow analysis).
11
- The three heaviest clone families are:
12
-
13
- 1. Runner IO tests (`agent-runner.test.ts` + `agent-runner-extension-tools.test.ts` + `concrete-agent-runner.test.ts`): 60-line shared setup — `createRunnerIO()`, `AgentConfigLookup` stub, `ParentSnapshot` constant.
14
- 2. Menu/wizard UI tests (`agent-menu.test.ts` + `agent-creation-wizard.test.ts` + `agent-config-editor.test.ts`): 54+51+24 lines — `makeFileOps()`, `makeUI()`, `makeManager()`, `AgentConfig` defaults, `ParentSnapshot` constant.
15
- 3. `agent-manager.test.ts` internal: 18 clone groups, 210 duplicated lines — repetitive `manager.spawn(...)` call patterns.
16
-
17
- Issue #131 (closed) already extracted `createMockSession`, `createToolDeps`, and `createTestRecord` into `test/helpers/`.
18
- This issue targets the remaining duplication families.
19
-
20
- ## Goals
21
-
22
- - Extract `createRunnerIO()` and `createAgentLookup()` into `test/helpers/runner-io.ts` — single source of truth for the `RunnerIO` and `AgentConfigLookup` stubs used by runner tests.
23
- - Extract `makeFileOps()`, `makeMenuUI()`, `makeMenuManager()`, and `createTestAgentConfig()` into `test/helpers/ui-stubs.ts` — shared factories for the three UI test files.
24
- - Consolidate `agent-manager.test.ts` internal duplication with local helper functions (`spawnBg`, `spawnFg`).
25
- - Replace local `ParentSnapshot` definitions with the existing `STUB_SNAPSHOT` from `test/helpers/stub-ctx.ts` where possible.
26
- - Remove stale `buildMemoryBlock` and `buildReadOnlyMemoryBlock` stubs from the `createRunnerIO` factory (these methods no longer exist on `AssemblerIO`).
27
- - Target: ~250 lines of test duplication removed.
28
-
29
- ## Non-Goals
30
-
31
- - Extracting session mock factories from the runner tests — each file's session factory serves a specialized purpose (`createSession(finalText)`, `createSessionWithExtensionToolRegistration(beforeBind, afterBind)`, `makeSession(text)`) and the variance is structural, not incidental.
32
- - Extracting `makeSettings()` from `agent-menu.test.ts` — only used in one file.
33
- - Extracting `makeHandler()` / `makeEditor()` / `makeDeps()` wrapper functions that compose collaborator stubs for specific handlers — too tightly coupled to each file's test structure.
34
- - Extracting the mutable `agentConfigMock` pattern from `agent-runner-extension-tools.test.ts` — its per-test config mutation is inherently local.
35
- - Decomposing UI complexity (Steps 1–3 of Phase 12, issues #205, #206, #207) — separate issues.
36
-
37
- ## Background
38
-
39
- ### Existing test helpers
40
-
41
- `test/helpers/` already contains shared factories from issue #131:
42
-
43
- | File | Exports | Used by |
44
- | ----------------- | ----------------------------------------- | ------------------------------------------------------- |
45
- | `mock-session.ts` | `createMockSession()`, `toAgentSession()` | agent-manager, record-observer, ui-observer tests |
46
- | `make-deps.ts` | `createToolDeps()` | agent-tool, background-spawner, foreground-runner tests |
47
- | `make-record.ts` | `createTestRecord()` | tool tests, UI tests |
48
- | `stub-ctx.ts` | `STUB_CTX`, `STUB_SNAPSHOT` | tool tests (via `make-deps.ts`) |
49
-
50
- The new factories follow the same pattern: shared files in `test/helpers/` with optional unit tests.
51
-
52
- ### Architecture doc reference
53
-
54
- Phase 12, Step 4 in `docs/architecture/architecture.md` (lines 637–644) calls for `test/fixtures/` modules.
55
- We use `test/helpers/` instead to follow the existing convention established in issue #131.
56
- The architecture doc reference will be updated as part of this work.
57
-
58
- ### Interface shapes
59
-
60
- `RunnerIO` = `EnvironmentIO & SessionFactoryIO` (in `src/lifecycle/agent-runner.ts`):
61
-
62
- ```typescript
63
- interface EnvironmentIO {
64
- detectEnv: (exec: ShellExec, cwd: string) => Promise<EnvInfo>;
65
- getAgentDir: () => string;
66
- deriveSessionDir: (parentSessionFile: string | undefined, cwd: string) => string;
67
- }
68
-
69
- interface SessionFactoryIO {
70
- createResourceLoader: (opts: ResourceLoaderOptions) => ResourceLoaderLike;
71
- createSessionManager: (cwd: string, sessionDir: string) => SessionManagerLike;
72
- createSettingsManager: (cwd: string, agentDir: string) => SettingsManager;
73
- createSession: (opts: CreateSessionOptions) => Promise<{ session: AgentSession }>;
74
- assemblerIO: AssemblerIO;
75
- }
76
- ```
77
-
78
- `AssemblerIO` (in `src/session/session-config.ts`) has only `preloadSkills` and `buildAgentPrompt`.
79
- The existing test factories in `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` include stale `buildMemoryBlock` and `buildReadOnlyMemoryBlock` stubs that no longer match the interface — the shared factory will omit them.
80
-
81
- ### Duplication diff: default values across copies
82
-
83
- Before extracting, the following differences across copies were identified:
84
-
85
- **`createRunnerIO` / `makeIO`:**
86
-
87
- | Field | agent-runner | extension-tools | concrete-agent-runner |
88
- | -------------------------------------- | --------------- | --------------- | --------------------- |
89
- | `assemblerIO.buildMemoryBlock` | present (stale) | present (stale) | absent |
90
- | `assemblerIO.buildReadOnlyMemoryBlock` | present (stale) | absent | absent |
91
- | Other fields | identical | identical | identical |
92
-
93
- **`ParentSnapshot` stubs:**
94
-
95
- | Field | agent-runner | extension-tools | concrete-agent-runner | agent-manager | agent-menu/wizard | STUB_SNAPSHOT |
96
- | ---------------------------- | --------------- | --------------- | --------------------- | --------------- | ----------------- | ----------------- |
97
- | `cwd` | "/tmp" | "/tmp" | "/workspace" | "/tmp" | "/test" | "/test" |
98
- | `systemPrompt` | "parent prompt" | "parent prompt" | "" | "parent prompt" | "" | "test prompt" |
99
- | `model` | undefined | undefined | {} | undefined | {} | undefined |
100
- | `modelRegistry.find` | vi.fn() | vi.fn() | vi.fn() | vi.fn() | `() => undefined` | `() => undefined` |
101
- | `modelRegistry.getAvailable` | vi.fn() | vi.fn() | — | — | — | — |
102
-
103
- None of the consumer tests assert on `cwd`, `systemPrompt`, `model`, or `modelRegistry.find` return values — these fields are passed through to functions that are already mocked.
104
- Using `STUB_SNAPSHOT` is safe for all consumers.
105
-
106
- **`makeFileOps`:** character-for-character identical in all three UI test files.
107
-
108
- **`makeUI`:** identical core in wizard and config-editor; agent-menu wraps it in an outer `{ ui, modelRegistry, parentSnapshot }` object.
109
-
110
- **`makeManager`:** identical in agent-menu and wizard.
111
-
112
- **`testDefaultAgentConfig`:** identical in agent-menu and config-editor (same 9 fields).
113
-
114
- ## Design Overview
115
-
116
- ### `test/helpers/runner-io.ts`
117
-
118
- Two exports:
119
-
120
- ```typescript
121
- /** Shared RunnerIO stub factory for agent-runner tests. */
122
- function createRunnerIO(assemblerOverrides?: Partial<AssemblerIOStub>): RunnerIOStub;
123
-
124
- /** Shared AgentConfigLookup stub. Returns a static Explore config by default. */
125
- function createAgentLookup(config?: Partial<AgentConfig>): AgentLookupStub;
126
- ```
127
-
128
- `createRunnerIO` builds the full `RunnerIO` stub shape.
129
- The `assemblerIO` sub-object defaults to stubs for `preloadSkills` and `buildAgentPrompt` only (matching the current `AssemblerIO` interface).
130
- `assemblerOverrides` lets tests customize individual methods without rebuilding the entire factory.
131
-
132
- `createAgentLookup` returns `{ resolveAgentConfig, getToolNamesForType }` wrapping a static config.
133
- The default config is the Explore agent used in `agent-runner.test.ts` and `concrete-agent-runner.test.ts`.
134
- Tests that need per-test config mutation (extension-tools) keep their local mutable wrapper but use the default config as a starting point.
135
-
136
- Return types are deliberately unannotated (per testing skill) so `vi.fn()` stubs retain their `Mock<...>` methods.
137
-
138
- ### `test/helpers/ui-stubs.ts`
139
-
140
- Four exports:
141
-
142
- ```typescript
143
- /** FileOps stub — identical across all three UI test files. */
144
- function makeFileOps(): FileOpsStub;
145
-
146
- /** MenuUI stub with sequential select responses. */
147
- function makeMenuUI(selectResults?: (string | undefined)[]): MenuUIStub;
148
-
149
- /** Manager stub for UI tests (listAgents, getRecord, spawnAndWait). */
150
- function makeMenuManager(): MenuManagerStub;
151
-
152
- /** AgentConfig factory with sensible defaults and override support. */
153
- function createTestAgentConfig(overrides?: Partial<AgentConfig>): AgentConfig;
154
- ```
155
-
156
- `makeMenuUI` returns the flat UI shape (select, input, confirm, editor, notify, custom).
157
- `agent-menu.test.ts` wraps this locally into its `{ ui, modelRegistry, parentSnapshot }` structure — the wrapping stays in the test file because it's specific to `AgentsMenuHandler`'s interface.
158
-
159
- ### `agent-manager.test.ts` local helpers
160
-
161
- Two local helpers reduce the 42 repetitive `manager.spawn(...)` calls:
162
-
163
- ```typescript
164
- function spawnBg(mgr: AgentManager, prompt = "test", desc = prompt) {
165
- return mgr.spawn(STUB_SNAPSHOT, "general-purpose", prompt, {
166
- description: desc,
167
- isBackground: true,
168
- });
169
- }
170
-
171
- function spawnFg(mgr: AgentManager, prompt = "test", desc = prompt) {
172
- return mgr.spawnAndWait(STUB_SNAPSHOT, "general-purpose", prompt, {
173
- description: desc,
174
- });
175
- }
176
- ```
177
-
178
- These stay local because they are only needed in this file.
179
- They also replace the local `mockSnapshot` with the imported `STUB_SNAPSHOT`.
180
-
181
- ## Module-Level Changes
182
-
183
- ### New files
184
-
185
- 1. `test/helpers/runner-io.ts` — exports `createRunnerIO()`, `createAgentLookup()`.
186
- 2. `test/helpers/runner-io.test.ts` — unit tests: verifies stub shape satisfies `RunnerIO`, override merging, default config shape.
187
- 3. `test/helpers/ui-stubs.ts` — exports `makeFileOps()`, `makeMenuUI()`, `makeMenuManager()`, `createTestAgentConfig()`.
188
- 4. `test/helpers/ui-stubs.test.ts` — unit tests: verifies stub shapes, sequential select behavior, config override merging.
189
-
190
- ### Modified files
191
-
192
- 1. `test/lifecycle/agent-runner.test.ts` — remove local `createRunnerIO()`, `mockAgentLookup`, `snapshot`, `exec`; import from helpers.
193
- 2. `test/lifecycle/agent-runner-extension-tools.test.ts` — remove local `createRunnerIO()`, `snapshot`; import from helpers; keep local mutable `agentConfigMock` and `mockAgentLookup` (they use the mutable wrapper pattern).
194
- 3. `test/lifecycle/concrete-agent-runner.test.ts` — remove local `makeIO()`, `registry`, `snapshot`; import from helpers.
195
- 4. `test/lifecycle/agent-manager.test.ts` — remove local `mockSnapshot`; import `STUB_SNAPSHOT`; add local `spawnBg()` and `spawnFg()` helpers; update all `manager.spawn(mockSnapshot, ...)` calls.
196
- 5. `test/ui/agent-menu.test.ts` — remove local `makeFileOps()`, `makeManager()`, `testDefaultAgentConfig`, `stubParentSnapshot`; import from helpers; keep local `makeSettings()` and `makeHandler()`.
197
- 6. `test/ui/agent-creation-wizard.test.ts` — remove local `makeFileOps()`, `makeManager()`, `stubParentSnapshot`; import from helpers; keep local `makeDeps()`.
198
- 7. `test/ui/agent-config-editor.test.ts` — remove local `makeFileOps()`, `testDefaultConfig`, `testCustomConfig`; import from helpers; keep local `makeEditor()`.
199
-
200
- ### Doc updates
201
-
202
- 1. `docs/architecture/architecture.md` — update Phase 12 Step 4 reference from `test/fixtures/` to `test/helpers/` (lines 640, 642).
203
-
204
- ## Test Impact Analysis
205
-
206
- 1. The new factory unit tests (`runner-io.test.ts`, `ui-stubs.test.ts`) verify shared fixture behavior that was previously only implicitly tested through consumer test files.
207
- This enables targeted debugging when a mock shape drifts from the production interface.
208
- 2. No existing tests become redundant — consumer tests exercise distinct production behavior that the factory tests do not cover.
209
- 3. All existing tests stay as-is in terms of assertions.
210
- Only the setup code (local factory → shared import) changes.
211
- 4. The removal of stale `buildMemoryBlock` and `buildReadOnlyMemoryBlock` stubs from `createRunnerIO` is safe because `AssemblerIO` no longer declares these methods — structural typing means they were always no-ops.
212
-
213
- ## TDD Order
214
-
215
- 1. **Red → Green: `createRunnerIO` and `createAgentLookup` factories.**
216
- Write `test/helpers/runner-io.test.ts` — verify `createRunnerIO()` returns a shape satisfying `RunnerIO` (`EnvironmentIO & SessionFactoryIO`), verify `assemblerIO` override merging, verify `createAgentLookup()` returns the default Explore config and accepts overrides.
217
- Implement `test/helpers/runner-io.ts`.
218
- Run: `pnpm vitest run test/helpers/runner-io.test.ts`.
219
- Commit: `test: add createRunnerIO and createAgentLookup shared test fixtures`
220
-
221
- 2. **Green: migrate `agent-runner.test.ts` to shared runner-io factories.**
222
- Import `createRunnerIO`, `createAgentLookup` from helpers.
223
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
224
- Remove local `createRunnerIO()`, `mockAgentLookup`, `snapshot`.
225
- Run: `pnpm vitest run test/lifecycle/agent-runner.test.ts`.
226
- Commit: `test: use shared runner-io fixtures in agent-runner tests`
227
-
228
- 3. **Green: migrate `agent-runner-extension-tools.test.ts` to shared `createRunnerIO`.**
229
- Import `createRunnerIO` from helpers.
230
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
231
- Remove local `createRunnerIO()` and `snapshot`.
232
- Keep local `agentConfigMock` and `mockAgentLookup` (mutable wrapper pattern).
233
- Run: `pnpm vitest run test/lifecycle/agent-runner-extension-tools.test.ts`.
234
- Commit: `test: use shared createRunnerIO in extension-tools tests`
235
-
236
- 4. **Green: migrate `concrete-agent-runner.test.ts` to shared factories.**
237
- Import `createRunnerIO`, `createAgentLookup` from helpers.
238
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
239
- Remove local `makeIO()`, `registry`, `snapshot`.
240
- Run: `pnpm vitest run test/lifecycle/concrete-agent-runner.test.ts`.
241
- Commit: `test: use shared runner-io fixtures in concrete-agent-runner tests`
242
-
243
- 5. **Red → Green: UI stub factories.**
244
- Write `test/helpers/ui-stubs.test.ts` — verify `makeFileOps()` shape, `makeMenuUI()` sequential select behavior, `makeMenuManager()` shape, `createTestAgentConfig()` default and override merging.
245
- Implement `test/helpers/ui-stubs.ts`.
246
- Run: `pnpm vitest run test/helpers/ui-stubs.test.ts`.
247
- Commit: `test: add shared UI stub factories`
248
-
249
- 6. **Green: migrate `agent-config-editor.test.ts` to shared UI stubs.**
250
- Import `makeFileOps`, `makeMenuUI`, `createTestAgentConfig` from helpers.
251
- Remove local `makeFileOps()`, `makeUI()`, `testDefaultConfig`; derive `testCustomConfig` from `createTestAgentConfig`.
252
- Run: `pnpm vitest run test/ui/agent-config-editor.test.ts`.
253
- Commit: `test: use shared UI stubs in agent-config-editor tests`
254
-
255
- 7. **Green: migrate `agent-creation-wizard.test.ts` to shared UI stubs.**
256
- Import `makeFileOps`, `makeMenuUI`, `makeMenuManager` from helpers.
257
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
258
- Remove local `makeFileOps()`, `makeUI()`, `makeManager()`, `stubParentSnapshot`.
259
- Run: `pnpm vitest run test/ui/agent-creation-wizard.test.ts`.
260
- Commit: `test: use shared UI stubs in agent-creation-wizard tests`
261
-
262
- 8. **Green: migrate `agent-menu.test.ts` to shared UI stubs.**
263
- Import `makeFileOps`, `makeMenuUI`, `makeMenuManager`, `createTestAgentConfig` from helpers.
264
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
265
- Remove local `makeFileOps()`, `makeManager()`, `testDefaultAgentConfig`, `stubParentSnapshot`.
266
- Adapt `makeHandler()` to wrap `makeMenuUI()` into its `{ ui, modelRegistry, parentSnapshot }` shape.
267
- Keep local `makeSettings()`.
268
- Run: `pnpm vitest run test/ui/agent-menu.test.ts`.
269
- Commit: `test: use shared UI stubs in agent-menu tests`
270
-
271
- 9. **Green: consolidate `agent-manager.test.ts` internal duplication.**
272
- Import `STUB_SNAPSHOT` from `stub-ctx.ts`.
273
- Remove local `mockSnapshot`.
274
- Add local `spawnBg()` and `spawnFg()` helpers.
275
- Update all ~42 `manager.spawn(mockSnapshot, ...)` calls to use `spawnBg()`.
276
- Update `spawnAndWait` calls to use `spawnFg()`.
277
- Run: `pnpm vitest run test/lifecycle/agent-manager.test.ts`.
278
- Commit: `test: consolidate agent-manager spawn patterns with local helpers`
279
-
280
- 10. **Docs: update architecture doc reference.**
281
- Update `docs/architecture/architecture.md` Phase 12 Step 4 to reference `test/helpers/` instead of `test/fixtures/`.
282
- Commit: `docs: update Phase 12 Step 4 to reference test/helpers/`
283
-
284
- ## Risks and Mitigations
285
-
286
- | Risk | Mitigation |
287
- | ------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
288
- | `STUB_SNAPSHOT` shape differs from local snapshots (`cwd`, `model`, `systemPrompt` values) | Verified: no consumer tests assert on these field values. The snapshot is passed through to fully-mocked functions. Run full test suite after each migration step. |
289
- | Removing stale `buildMemoryBlock`/`buildReadOnlyMemoryBlock` stubs breaks a test that somehow depends on them | These methods don't exist on `AssemblerIO` — any code accessing them would be a TypeScript error in production. Vitest's esbuild won't catch this, so run `pnpm run check` after step 2. |
290
- | Wider mock shape in `createRunnerIO` causes false-positive tests (runner tests pass when they should fail) | The production `RunnerIO` interface is already narrow; extra mock methods are harmless. Existing assertions on specific mock calls catch regressions. |
291
- | `makeMenuUI` sequential-select pattern breaks when agent-menu wraps it differently | Agent-menu's `makeHandler()` composes the wrapping locally. The shared factory returns only the flat UI shape, avoiding coupling to any specific consumer's wrapping structure. |
292
- | `agent-manager.test.ts` `spawnBg()` helper hides important spawn options from test readers | Helper uses default values matching the most common pattern. Tests that need non-default options (e.g., `description: "first"`) pass explicit arguments, preserving readability. |
293
-
294
- ## Open Questions
295
-
296
- - Should `STUB_SNAPSHOT` be updated to use `vi.fn()` for `modelRegistry.find` instead of `() => undefined`?
297
- Currently it uses plain functions, but some runner tests use `vi.fn()`.
298
- Decide during implementation — if no test asserts on `find` call counts, plain functions are fine.
@@ -1,261 +0,0 @@
1
- ---
2
- issue: 214
3
- issue_title: "Convert remaining closure factories to classes (Phase 13, Step 1)"
4
- ---
5
-
6
- # Convert remaining closure factories to classes
7
-
8
- ## Problem Statement
9
-
10
- Three closure factories survived Phase 11 — each captures dependencies in closure scope and returns a method bag, the exact pattern Phase 11 eliminated elsewhere.
11
- Converting them to classes makes dependencies explicit as constructor parameters and aligns with the class-based pattern established in Phase 11.
12
-
13
- ## Goals
14
-
15
- - Convert `createAgentConfigEditor()` to an `AgentConfigEditor` class.
16
- - Convert `createAgentCreationWizard()` to an `AgentCreationWizard` class.
17
- - Convert `createSubagentsService()` to a `SubagentsServiceAdapter` class implementing `SubagentsService`.
18
- - Remove the `AgentCreationWizardDeps` interface (the class constructor replaces it).
19
- - Update `AgentsMenuHandler` to store typed class instances instead of `ReturnType<typeof ...>`.
20
- - Update `index.ts` to construct `SubagentsServiceAdapter` with `new`.
21
- - 0 remaining closure factories (excluding pure-function factories like `createNotificationRenderer`).
22
-
23
- ## Non-Goals
24
-
25
- - Changing any behavior — all conversions are purely structural.
26
- - Extracting the shared overwrite guard between `AgentConfigEditor` and `AgentCreationWizard` — that is #218.
27
- - Reducing test duplication in `agent-config-editor.test.ts` — that is #219.
28
- - Decomposing `buildParentContext` or `startAgent` — those are #215 and #216.
29
- - Modifying `createNotificationRenderer()` — it returns a pure render function with no captured state.
30
-
31
- ## Background
32
-
33
- ### Phase 11 precedent
34
-
35
- Phase 11 converted all closure factories in tools, runner, and menu layers to classes.
36
- Issues #195 and #196 established the pattern:
37
-
38
- - Closure-captured deps become constructor parameters stored as `private readonly` fields.
39
- - Nested functions become private methods.
40
- - Consumer call sites change from `createFoo(deps)` to `new Foo(deps)`.
41
- - Tests update `makeXxx()` helpers to use `new` instead of calling the factory.
42
-
43
- ### Current state
44
-
45
- | Factory | File | Captures | Returns |
46
- | ----------------------------- | ----------------------------- | ---------------------------------------- | ------------------------------------------- |
47
- | `createAgentConfigEditor()` | `ui/agent-config-editor.ts` | `fileOps`, `registry`, 2 dirs | `{ showAgentDetail }` (7 nested async fns) |
48
- | `createAgentCreationWizard()` | `ui/agent-creation-wizard.ts` | `fileOps`, `manager`, `registry`, 2 dirs | `{ showCreateWizard }` (3 nested async fns) |
49
- | `createSubagentsService()` | `service/service-adapter.ts` | `manager`, `resolveModel`, `runtime` | 7-method `SubagentsService` |
50
-
51
- ### Consumer sites
52
-
53
- - `AgentsMenuHandler` (in `agent-menu.ts`) constructs both UI factories in its constructor and stores them as `private readonly` fields typed as `ReturnType<typeof createAgentConfigEditor>` and `ReturnType<typeof createAgentCreationWizard>`.
54
- - `index.ts` calls `createSubagentsService(manager, resolveModel, runtime)` and passes the result to `publishSubagentsService`.
55
-
56
- ### Structural typing
57
-
58
- `AgentCreationWizardDeps` is only used within `agent-creation-wizard.ts` — no external imports.
59
- The class constructor replaces the deps interface entirely.
60
-
61
- ## Design Overview
62
-
63
- ### AgentConfigEditor
64
-
65
- Deps become positional constructor parameters (matching the factory's positional signature):
66
-
67
- ```typescript
68
- export class AgentConfigEditor {
69
- constructor(
70
- private readonly fileOps: AgentFileOps,
71
- private readonly registry: AgentTypeRegistry,
72
- private readonly personalAgentsDir: string,
73
- private readonly projectAgentsDir: string,
74
- ) {}
75
-
76
- private agentDirs(): string[] { ... }
77
- async showAgentDetail(ui: MenuUI, name: string): Promise<void> { ... }
78
- private async handleEdit(ui: MenuUI, name: string, file: string): Promise<void> { ... }
79
- private async handleDelete(ui: MenuUI, name: string, file: string): Promise<void> { ... }
80
- private async handleReset(ui: MenuUI, name: string, file: string): Promise<void> { ... }
81
- private async ejectAgent(ui: MenuUI, name: string, cfg: AgentConfig): Promise<void> { ... }
82
- private async disableAgent(ui: MenuUI, name: string): Promise<void> { ... }
83
- private async enableAgent(ui: MenuUI, name: string): Promise<void> { ... }
84
- }
85
- ```
86
-
87
- The pure helper functions `buildMenuOptions` and `buildEjectContent` remain as exported free functions — they have no captured state and their tests exercise them independently.
88
-
89
- ### AgentCreationWizard
90
-
91
- Deps become positional constructor parameters (dissolving `AgentCreationWizardDeps`):
92
-
93
- ```typescript
94
- export class AgentCreationWizard {
95
- constructor(
96
- private readonly fileOps: AgentFileOps,
97
- private readonly manager: WizardManager,
98
- private readonly registry: WizardRegistry,
99
- private readonly personalAgentsDir: string,
100
- private readonly projectAgentsDir: string,
101
- ) {}
102
-
103
- async showCreateWizard(ui: MenuUI, parentSnapshot: ParentSnapshot): Promise<void> { ... }
104
- private async showGenerateWizard(ui: MenuUI, parentSnapshot: ParentSnapshot, targetDir: string): Promise<void> { ... }
105
- private async showManualWizard(ui: MenuUI, targetDir: string): Promise<void> { ... }
106
- }
107
- ```
108
-
109
- `WizardManager` and `WizardRegistry` interfaces remain exported — they define the narrow contracts for the class's collaborators.
110
-
111
- ### SubagentsServiceAdapter
112
-
113
- The class implements `SubagentsService` directly:
114
-
115
- ```typescript
116
- export class SubagentsServiceAdapter implements SubagentsService {
117
- constructor(
118
- private readonly manager: AgentManagerLike,
119
- private readonly resolveModel: (input: string, registry: ModelRegistry) => unknown,
120
- private readonly runtime: ServiceRuntimeLike,
121
- ) {}
122
-
123
- spawn(type: string, prompt: string, options?: SpawnOptions): string { ... }
124
- getRecord(id: string): SubagentRecord | undefined { ... }
125
- listAgents(): SubagentRecord[] { ... }
126
- abort(id: string): boolean { ... }
127
- async steer(id: string, message: string): Promise<boolean> { ... }
128
- async waitForAll(): Promise<void> { ... }
129
- hasRunning(): boolean { ... }
130
- }
131
- ```
132
-
133
- `AgentManagerLike` and `ServiceRuntimeLike` interfaces remain exported — they define the narrow contracts.
134
- The `toSubagentRecord` helper remains an exported free function — it is pure and tested independently.
135
-
136
- ### AgentsMenuHandler updates
137
-
138
- The `editor` and `wizard` fields change from `ReturnType<typeof ...>` to the concrete class types:
139
-
140
- ```typescript
141
- private readonly editor: AgentConfigEditor;
142
- private readonly wizard: AgentCreationWizard;
143
- ```
144
-
145
- Construction changes from `createAgentConfigEditor(...)` to `new AgentConfigEditor(...)` and from `createAgentCreationWizard({...})` to `new AgentCreationWizard(...)`.
146
-
147
- ## Module-Level Changes
148
-
149
- ### `src/ui/agent-config-editor.ts`
150
-
151
- - Replace `createAgentConfigEditor` factory function with `AgentConfigEditor` class.
152
- - `agentDirs()` becomes a private method.
153
- - `showAgentDetail`, `handleEdit`, `handleDelete`, `handleReset`, `ejectAgent`, `disableAgent`, `enableAgent` become class methods (`showAgentDetail` is public, rest are private).
154
- - `buildMenuOptions` and `buildEjectContent` remain as exported free functions.
155
-
156
- ### `src/ui/agent-creation-wizard.ts`
157
-
158
- - Replace `createAgentCreationWizard` factory function with `AgentCreationWizard` class.
159
- - Remove `AgentCreationWizardDeps` interface.
160
- - `showCreateWizard` becomes a public method; `showGenerateWizard` and `showManualWizard` become private methods.
161
- - `WizardManager` and `WizardRegistry` interfaces remain exported.
162
-
163
- ### `src/service/service-adapter.ts`
164
-
165
- - Replace `createSubagentsService` factory function with `SubagentsServiceAdapter` class implementing `SubagentsService`.
166
- - `AgentManagerLike` and `ServiceRuntimeLike` interfaces remain exported.
167
- - `toSubagentRecord` remains an exported free function.
168
- - Add import for `SpawnOptions` from `#src/service/service` (needed for the `spawn` method signature).
169
-
170
- ### `src/ui/agent-menu.ts`
171
-
172
- - Replace `ReturnType<typeof createAgentConfigEditor>` with `AgentConfigEditor`.
173
- - Replace `ReturnType<typeof createAgentCreationWizard>` with `AgentCreationWizard`.
174
- - Update constructor body: `new AgentConfigEditor(...)` instead of `createAgentConfigEditor(...)`.
175
- - Update constructor body: `new AgentCreationWizard(...)` instead of `createAgentCreationWizard({...})`.
176
- - Update imports: `AgentConfigEditor` instead of `createAgentConfigEditor`, `AgentCreationWizard` instead of `createAgentCreationWizard`.
177
-
178
- ### `src/index.ts`
179
-
180
- - Replace `createSubagentsService(manager, resolveModel, runtime)` with `new SubagentsServiceAdapter(manager, resolveModel, runtime)`.
181
- - Update import: `SubagentsServiceAdapter` instead of `createSubagentsService`.
182
-
183
- ### `docs/architecture/architecture.md`
184
-
185
- - Mark Step 1 of Phase 13 as complete.
186
- - Update the factory table to show conversions done.
187
-
188
- ## Test Impact Analysis
189
-
190
- ### `test/ui/agent-config-editor.test.ts`
191
-
192
- - Update `makeEditor()` helper: replace `createAgentConfigEditor(...)` with `new AgentConfigEditor(...)`.
193
- - Update import: `AgentConfigEditor` instead of `createAgentConfigEditor`.
194
- - No test logic changes — all existing assertions remain valid.
195
- - The `makeEditor()` helper centralizes the factory call, so only 1 line changes.
196
-
197
- ### `test/ui/agent-creation-wizard.test.ts`
198
-
199
- - Replace all `createAgentCreationWizard(deps)` calls with `new AgentCreationWizard(deps.fileOps, deps.manager, deps.registry, deps.personalAgentsDir, deps.projectAgentsDir)`.
200
- - Update import: `AgentCreationWizard` instead of `createAgentCreationWizard`.
201
- - This file has ~18 call sites that each construct the wizard inline; each changes from `createAgentCreationWizard(deps)` to `new AgentCreationWizard(deps.fileOps, deps.manager, deps.registry, deps.personalAgentsDir, deps.projectAgentsDir)`.
202
- - Alternatively, add a `makeWizard(deps)` helper to centralize construction, then each call site becomes `makeWizard(deps)`.
203
- - No test logic changes.
204
-
205
- ### `test/service/service-adapter.test.ts`
206
-
207
- - Replace all `createSubagentsService(manager, resolveModel, runtime)` calls with `new SubagentsServiceAdapter(manager, resolveModel, runtime)`.
208
- - Update import: `SubagentsServiceAdapter` instead of `createSubagentsService`.
209
- - ~12 call sites change; each is a mechanical find-and-replace.
210
- - Update `describe` block names from `createSubagentsService —` to `SubagentsServiceAdapter —`.
211
- - No test logic changes.
212
-
213
- ### No new tests needed
214
-
215
- The conversions are structural — existing tests fully cover all behavior.
216
- Adding "verify it's a class" tests would test the language, not the code.
217
-
218
- ## TDD Order
219
-
220
- 1. **Convert `createAgentConfigEditor` to `AgentConfigEditor` class.**
221
- Replace factory with class in `agent-config-editor.ts`.
222
- Update `makeEditor()` in `agent-config-editor.test.ts`.
223
- Update `agent-menu.ts` field types and constructor.
224
- Remove factory function.
225
- Verify: `pnpm vitest run test/ui/agent-config-editor.test.ts` and `pnpm run check`.
226
- `refactor: convert createAgentConfigEditor to AgentConfigEditor class`
227
-
228
- 2. **Convert `createAgentCreationWizard` to `AgentCreationWizard` class.**
229
- Replace factory with class in `agent-creation-wizard.ts`.
230
- Remove `AgentCreationWizardDeps` interface.
231
- Update all call sites in `agent-creation-wizard.test.ts` (add `makeWizard` helper to centralize construction).
232
- Update `agent-menu.ts` field type and constructor.
233
- Remove factory function.
234
- Verify: `pnpm vitest run test/ui/agent-creation-wizard.test.ts` and `pnpm run check`.
235
- `refactor: convert createAgentCreationWizard to AgentCreationWizard class`
236
-
237
- 3. **Convert `createSubagentsService` to `SubagentsServiceAdapter` class.**
238
- Replace factory with class in `service-adapter.ts`.
239
- Update all call sites in `service-adapter.test.ts`.
240
- Update `describe` block names.
241
- Update `index.ts` import and construction.
242
- Remove factory function.
243
- Verify: `pnpm vitest run test/service/service-adapter.test.ts` and `pnpm run check`.
244
- `refactor: convert createSubagentsService to SubagentsServiceAdapter class`
245
-
246
- 4. **Update architecture doc.**
247
- Mark Phase 13 Step 1 as complete in `docs/architecture/architecture.md`.
248
- `docs: mark Phase 13 Step 1 complete`
249
-
250
- ## Risks and Mitigations
251
-
252
- | Risk | Mitigation |
253
- | ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
254
- | `AgentCreationWizard` test has ~18 inline factory calls that all need updating | Add a `makeWizard(deps)` test helper to centralize construction — same pattern used in `agent-config-editor.test.ts`. |
255
- | `SubagentsServiceAdapter` class might not satisfy `SubagentsService` interface | The class uses `implements SubagentsService`, so `pnpm run check` catches any mismatches at compile time. |
256
- | Spreading a class instance in tests produces a plain object lacking methods | Not applicable — none of the test files spread factory results. Tests call methods directly on the returned object. |
257
- | `AgentCreationWizardDeps` removal might break external consumers | Verified: the interface is only used within `agent-creation-wizard.ts` itself. No external imports. |
258
-
259
- ## Open Questions
260
-
261
- None — the conversions are mechanical and follow the established Phase 11 pattern.