@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,231 +0,0 @@
1
- ---
2
- issue: 166
3
- issue_title: "refactor(pi-subagents): extract ParentSessionInfo from AgentSpawnConfig (13 fields)"
4
- ---
5
-
6
- # Extract ParentSessionInfo from AgentSpawnConfig
7
-
8
- ## Problem Statement
9
-
10
- `AgentSpawnConfig` in `agent-manager.ts` has 13 fields.
11
- Three of those fields — `parentSessionFile`, `parentSessionId`, and `toolCallId` — form a natural cluster around parent session identity.
12
- They always travel together through `agent-tool.ts` → `foreground-runner.ts` / `background-spawner.ts` → `AgentManager.spawn()`.
13
- Extracting them into a named value object reduces `AgentSpawnConfig` from 13 to 11 fields (10 + 1 nested) and introduces the `ParentSessionInfo` domain concept.
14
-
15
- ## Goals
16
-
17
- - Extract `ParentSessionInfo` interface with `parentSessionFile`, `parentSessionId`, and `toolCallId`.
18
- - Replace the three flat optional fields on `AgentSpawnConfig` with a single optional `parentSession?: ParentSessionInfo` field.
19
- - Replace the flat fields on `BackgroundParams`, `ForegroundParams`, and `RunOptions` with the same grouped type.
20
- - Update all callers (agent-tool, foreground-runner, background-spawner, agent-manager, agent-runner) and their tests.
21
- - Non-breaking refactor — no public API changes (the `SubagentsService` boundary does not expose these fields).
22
-
23
- ## Non-Goals
24
-
25
- - Changing the `NotificationState` or `notification` module — they remain as-is; `toolCallId` is just extracted from the group at the `AgentManager.spawn` boundary.
26
- - Further decomposition of `AgentSpawnConfig` (e.g., extracting execution or callback clusters) — tracked separately.
27
- - Modifying `session-dir.ts` or `deriveSubagentSessionDir` — the function signature stays the same; callers just unwrap `parentSession.parentSessionFile` before calling it.
28
-
29
- ## Background
30
-
31
- Issue #165 (closed) decomposed `ResolvedSpawnConfig` into `SpawnIdentity`, `SpawnExecution`, and `SpawnPresentation`.
32
- This issue continues that structural improvement by grouping the parent-session fields that flow from `agent-tool.ts` through to `agent-runner.ts`.
33
-
34
- The three fields are:
35
-
36
- - `parentSessionFile` — path to the parent session's JSONL file, used by `deriveSubagentSessionDir` to place child sessions next to the parent.
37
- - `parentSessionId` — session ID of the parent agent, stored in the child session's `parentSession` header via `sessionManager.newSession()`.
38
- - `toolCallId` — tool call ID for background notification wiring; when set, `AgentManager.spawn` creates a `NotificationState`.
39
-
40
- All three originate in `agent-tool.ts`'s `execute` function and are threaded unchanged through intermediate modules.
41
-
42
- ### Current flow
43
-
44
- ```text
45
- agent-tool execute → getSessionInfo() + toolCallId param
46
- → BackgroundParams { parentSessionFile, parentSessionId, toolCallId }
47
- → spawnBackground → manager.spawn(opts: AgentSpawnConfig { ...flat fields })
48
- → AgentManager.spawn → options.toolCallId → NotificationState
49
- → startAgent → runner.run(RunOptions { parentSessionFile, parentSessionId })
50
- → deriveSessionDir(parentSessionFile, ...)
51
- → sessionManager.newSession({ parentSession: parentSessionId })
52
-
53
- → ForegroundParams { parentSessionFile, parentSessionId }
54
- → runForeground → manager.spawnAndWait(opts: AgentSpawnConfig { ...flat fields })
55
- → (same AgentManager path)
56
- ```
57
-
58
- ### After extraction
59
-
60
- ```text
61
- agent-tool execute → getSessionInfo() + toolCallId param
62
- → parentSession: ParentSessionInfo { parentSessionFile, parentSessionId, toolCallId }
63
- → BackgroundParams { parentSession }
64
- → spawnBackground → manager.spawn(opts: AgentSpawnConfig { parentSession })
65
- → AgentManager.spawn → parentSession.toolCallId → NotificationState
66
- → startAgent → runner.run(RunOptions { parentSession })
67
- → deriveSessionDir(parentSession?.parentSessionFile, ...)
68
- → sessionManager.newSession({ parentSession: parentSession?.parentSessionId })
69
-
70
- → ForegroundParams { parentSession }
71
- → runForeground → manager.spawnAndWait(opts: AgentSpawnConfig { parentSession })
72
- → (same AgentManager path)
73
- ```
74
-
75
- ## Design Overview
76
-
77
- ### `ParentSessionInfo` interface
78
-
79
- ```typescript
80
- export interface ParentSessionInfo {
81
- /** Path to the parent session's JSONL file (for deriving the subagent session directory). */
82
- parentSessionFile?: string;
83
- /** Session ID of the parent agent (stored in the child session's parentSession header). */
84
- parentSessionId?: string;
85
- /** Tool call ID for background notification wiring. When set, spawn attaches NotificationState. */
86
- toolCallId?: string;
87
- }
88
- ```
89
-
90
- All three fields remain optional — they are only available when spawning from an active session (the `SubagentsService` boundary omits them entirely).
91
-
92
- The interface lives in `lifecycle/agent-manager.ts` alongside `AgentSpawnConfig` since that is the primary consumer.
93
- If a future refactoring moves `AgentSpawnConfig` to its own file, `ParentSessionInfo` should move with it.
94
-
95
- ### Consumer call-site sketch
96
-
97
- ```typescript
98
- // agent-tool.ts execute():
99
- const parentSession: ParentSessionInfo = {
100
- parentSessionFile: sessionInfo.parentSessionFile,
101
- parentSessionId: sessionInfo.parentSessionId,
102
- toolCallId,
103
- };
104
- // ...
105
- spawnBackground(manager, widget, agentActivity, { config, snapshot, parentSession });
106
- ```
107
-
108
- The grouped object eliminates the three-field spread that was repeated in both `spawnBackground` and `runForeground` call sites.
109
-
110
- ### `AgentSpawnConfig` change
111
-
112
- ```typescript
113
- export interface AgentSpawnConfig {
114
- // ... existing fields (description, model, maxTurns, etc.)
115
- /** Parent session identity — grouped fields that travel together from the tool boundary. */
116
- parentSession?: ParentSessionInfo;
117
- // Remove: parentSessionFile, parentSessionId, toolCallId
118
- }
119
- ```
120
-
121
- ### `RunOptions` change
122
-
123
- ```typescript
124
- export interface RunOptions {
125
- // ... existing fields
126
- /** Parent session identity (file path + session ID). */
127
- parentSession?: ParentSessionInfo;
128
- // Remove: parentSessionFile, parentSessionId
129
- }
130
- ```
131
-
132
- Note: `RunOptions` does not use `toolCallId` — it was never threaded to the runner.
133
- The runner only reads `parentSessionFile` and `parentSessionId` from the group.
134
-
135
- ### `getSessionInfo` return type update
136
-
137
- The `getSessionInfo` callback in `AgentToolDeps` currently returns `{ parentSessionFile: string; parentSessionId: string }`.
138
- It should remain unchanged — it does not include `toolCallId` (which comes from the `execute` callback's first argument).
139
- The `agent-tool.ts` execute function constructs a `ParentSessionInfo` by merging `getSessionInfo()` output with `toolCallId`.
140
-
141
- ## Module-Level Changes
142
-
143
- ### New types
144
-
145
- 1. `src/lifecycle/agent-manager.ts` — add `ParentSessionInfo` interface (exported).
146
-
147
- ### Modified interfaces
148
-
149
- 1. `src/lifecycle/agent-manager.ts` — `AgentSpawnConfig`: replace `parentSessionFile?`, `parentSessionId?`, `toolCallId?` with `parentSession?: ParentSessionInfo`.
150
- 2. `src/lifecycle/agent-runner.ts` — `RunOptions`: replace `parentSessionFile?`, `parentSessionId?` with `parentSession?: ParentSessionInfo`.
151
- 3. `src/tools/background-spawner.ts` — `BackgroundParams`: replace `parentSessionFile`, `parentSessionId`, `toolCallId` with `parentSession: ParentSessionInfo`.
152
- 4. `src/tools/foreground-runner.ts` — `ForegroundParams`: replace `parentSessionFile`, `parentSessionId` with `parentSession: ParentSessionInfo`.
153
-
154
- ### Modified implementations
155
-
156
- 1. `src/lifecycle/agent-manager.ts` — `AgentManager.spawn()`: read `options.parentSession?.toolCallId` instead of `options.toolCallId`; pass `parentSession` to `RunOptions`.
157
- 2. `src/lifecycle/agent-runner.ts` — `runAgent()`: read `options.parentSession?.parentSessionFile` and `options.parentSession?.parentSessionId`.
158
- 3. `src/tools/agent-tool.ts` — `createAgentTool` execute: construct `ParentSessionInfo` from `getSessionInfo()` + `toolCallId`, pass as `parentSession` to both spawners.
159
- 4. `src/tools/background-spawner.ts` — `spawnBackground()`: read `params.parentSession` and pass fields to `AgentSpawnConfig`.
160
- 5. `src/tools/foreground-runner.ts` — `runForeground()`: read `params.parentSession` and pass fields to `AgentSpawnConfig`.
161
-
162
- ### No changes needed
163
-
164
- - `src/tools/agent-tool.ts` — `AgentToolDeps.getSessionInfo` return type stays the same.
165
- - `src/session/session-dir.ts` — `deriveSubagentSessionDir` signature unchanged.
166
- - `src/observation/notification-state.ts` — constructor signature unchanged.
167
- - `src/service/service-adapter.ts` — does not pass parent session fields.
168
- - `src/index.ts` — `getSessionInfo` callback unchanged.
169
-
170
- ## Test Impact Analysis
171
-
172
- ### New tests enabled
173
-
174
- No new unit tests are enabled — this is a structural grouping, not new behavior.
175
-
176
- ### Existing tests that need updates
177
-
178
- 1. `test/lifecycle/agent-manager.test.ts` — update spawn calls from flat `parentSessionFile`/`parentSessionId`/`toolCallId` to nested `parentSession: { ... }` form; update assertions to read from `parentSession`.
179
- 2. `test/lifecycle/agent-runner.test.ts` — update `RunOptions` construction from flat to nested `parentSession`.
180
- 3. `test/tools/agent-tool.test.ts` — update assertion checking `toolCallId` on spawn opts to check `parentSession.toolCallId`.
181
- 4. `test/tools/background-spawner.test.ts` — update `makeParams` factory from flat fields to `parentSession: { ... }`.
182
- 5. `test/tools/foreground-runner.test.ts` — update params construction from flat fields to `parentSession: { ... }`.
183
- 6. `test/helpers/make-deps.ts` — `getSessionInfo` mock stays unchanged (returns flat `{ parentSessionFile, parentSessionId }`).
184
-
185
- ### Tests that stay as-is
186
-
187
- - `test/session/session-dir.test.ts` — tests `deriveSubagentSessionDir` directly, no interface change.
188
- - `test/observation/notification-state.test.ts` — tests `NotificationState` constructor directly.
189
- - `test/observation/notification.test.ts` — tests notification formatting with `record.notification`, not spawn config.
190
-
191
- ## TDD Order
192
-
193
- 1. **Define `ParentSessionInfo` and update `AgentSpawnConfig`** — add interface, replace three flat fields with `parentSession?`.
194
- Update `AgentManager.spawn` and `startAgent` to read from the nested group.
195
- Update `agent-manager.test.ts` to use nested form.
196
- Run `pnpm run check` to verify no downstream type errors remain.
197
- Commit: `refactor: define ParentSessionInfo and nest in AgentSpawnConfig`
198
-
199
- 2. **Update `RunOptions` in `agent-runner.ts`** — replace flat `parentSessionFile?`/`parentSessionId?` with `parentSession?`.
200
- Update `runAgent` to read `options.parentSession?.parentSessionFile` and `options.parentSession?.parentSessionId`.
201
- Update `agent-runner.test.ts`.
202
- Commit: `refactor: nest ParentSessionInfo in RunOptions`
203
-
204
- 3. **Update `BackgroundParams` and `spawnBackground`** — replace three flat fields with `parentSession: ParentSessionInfo`.
205
- Update `spawnBackground` to pass `parentSession` to spawn opts.
206
- Update `background-spawner.test.ts`.
207
- Commit: `refactor: nest ParentSessionInfo in BackgroundParams`
208
-
209
- 4. **Update `ForegroundParams` and `runForeground`** — replace two flat fields with `parentSession: ParentSessionInfo`.
210
- Update `runForeground` to pass `parentSession` to spawn opts.
211
- Update `foreground-runner.test.ts`.
212
- Commit: `refactor: nest ParentSessionInfo in ForegroundParams`
213
-
214
- 5. **Update `agent-tool.ts` execute** — construct `ParentSessionInfo` from `getSessionInfo()` + `toolCallId`, pass as `parentSession` to both spawner call sites.
215
- Update `agent-tool.test.ts`.
216
- Commit: `refactor: construct ParentSessionInfo in agent-tool execute`
217
-
218
- 6. **Final verification** — run full test suite (`pnpm vitest run`) and type check (`pnpm run check`).
219
- No separate commit unless adjustments are needed.
220
-
221
- ## Risks and Mitigations
222
-
223
- | Risk | Mitigation |
224
- | ------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
225
- | Deep-merge trap: test factories using `Partial<BackgroundParams>` spread may silently ignore nested overrides | Audit `makeParams` in `background-spawner.test.ts` — convert from flat-field spread to nested `parentSession` construction |
226
- | `toolCallId` conditionally absent for foreground calls | `ParentSessionInfo.toolCallId` is optional; `ForegroundParams.parentSession` includes it but won't set it — matches current behavior |
227
- | Type check passes but runtime breaks due to nested access on undefined | `parentSession?` is optional on `AgentSpawnConfig`; all reads use optional chaining (`options.parentSession?.toolCallId`) |
228
-
229
- ## Open Questions
230
-
231
- None — the extraction is mechanical and the issue description is unambiguous.
@@ -1,150 +0,0 @@
1
- ---
2
- issue: 167
3
- issue_title: "refactor(pi-subagents): narrow RunnerIO (9 methods → 2 focused interfaces)"
4
- ---
5
-
6
- # Narrow RunnerIO into EnvironmentIO + SessionFactoryIO
7
-
8
- ## Problem Statement
9
-
10
- `RunnerIO` in `agent-runner.ts` bundles 8 members (7 methods + 1 sub-interface) into a single IO boundary.
11
- The methods split naturally into two concerns — environment discovery vs. SDK object creation — but the current monolithic interface forces every consumer (and every test mock) to provide all members regardless of which subset they actually use.
12
- This violates Interface Segregation (ISP) and inflates test factory helpers.
13
-
14
- ## Goals
15
-
16
- - Split `RunnerIO` into two focused interfaces: `EnvironmentIO` (3 methods) and `SessionFactoryIO` (5 methods + `assemblerIO`).
17
- - Keep `RunnerIO` as a type alias (`EnvironmentIO & SessionFactoryIO`) so the change is fully backward-compatible at the type level.
18
- - Update both test `createRunnerIO()` factories to use the new sub-interfaces in their comments/structure (no behavioral test changes needed — factories already return plain objects).
19
- - Zero runtime behavior change.
20
-
21
- ## Non-Goals
22
-
23
- - Splitting the `runAgent()` function itself — that's a separate concern.
24
- - Changing how `createAgentRunner()` accepts its IO parameter — it keeps taking `RunnerIO` (the intersection).
25
- - Refactoring `index.ts` wiring — the construction site already builds a plain object; it will continue to satisfy `RunnerIO`.
26
- - Extracting `AssemblerIO` further — it already has its own interface in `session-config.ts`.
27
-
28
- ## Background
29
-
30
- `RunnerIO` was introduced in issue #133 to decouple `agent-runner.ts` from direct Pi SDK imports.
31
- It succeeded at making the runner testable via plain stubs, but bundled all IO into one wide interface.
32
- Issue #164 (closed) reorganized source into domain directories; the current file path is `src/lifecycle/agent-runner.ts`.
33
-
34
- The 8 members group into two cohesive clusters:
35
-
36
- | Cluster | Members | Responsibility |
37
- | --------------------- | ------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
38
- | Environment discovery | `detectEnv`, `getAgentDir`, `deriveSessionDir` | Discover runtime environment, resolve directories |
39
- | Session factory | `createResourceLoader`, `createSessionManager`, `createSettingsManager`, `createSession`, `assemblerIO` | Create SDK objects for a child session |
40
-
41
- In `runAgent()`, the environment methods are called first (lines ~265–275), then the factory methods build SDK objects (lines ~280–320).
42
- The two groups have no cross-dependencies within `runAgent()`.
43
-
44
- ## Design Overview
45
-
46
- ### New interfaces
47
-
48
- ```typescript
49
- /** Environment discovery — detect runtime context and resolve directories. */
50
- export interface EnvironmentIO {
51
- detectEnv: (exec: ShellExec, cwd: string) => Promise<EnvInfo>;
52
- getAgentDir: () => string;
53
- deriveSessionDir: (parentSessionFile: string | undefined, effectiveCwd: string) => string;
54
- }
55
-
56
- /** Session factory — create SDK objects for a child agent session. */
57
- export interface SessionFactoryIO {
58
- createResourceLoader: (opts: ResourceLoaderOptions) => ResourceLoaderLike;
59
- createSessionManager: (cwd: string, sessionDir: string) => SessionManagerLike;
60
- createSettingsManager: (cwd: string, agentDir: string) => SettingsManager;
61
- createSession: (opts: CreateSessionOptions) => Promise<{ session: AgentSession }>;
62
- assemblerIO: AssemblerIO;
63
- }
64
-
65
- /**
66
- * IO boundary injected into runAgent().
67
- * Backward-compatible intersection of the two focused interfaces.
68
- */
69
- export type RunnerIO = EnvironmentIO & SessionFactoryIO;
70
- ```
71
-
72
- ### Backward compatibility
73
-
74
- - `RunnerIO` becomes a type alias for the intersection.
75
- Any code that imports `RunnerIO` continues to compile unchanged.
76
- - `index.ts` builds a plain object literal that satisfies `RunnerIO` — no change needed.
77
- - Test factories return unannotated objects that are structurally compatible — no change needed for compilation, but comments can be updated to reference the sub-interfaces.
78
-
79
- ### Consumer call-site verification
80
-
81
- The call site in `createAgentRunner()` (3 lines):
82
-
83
- ```typescript
84
- export function createAgentRunner(io: RunnerIO): AgentRunner {
85
- return {
86
- run: (snapshot, type, prompt, options) => runAgent(snapshot, type, prompt, options, io),
87
- resume: resumeAgent,
88
- };
89
- }
90
- ```
91
-
92
- This passes the full `io` to `runAgent()`, which continues to accept `RunnerIO`.
93
- No Tell-Don't-Ask or LoD violations introduced.
94
-
95
- ## Module-Level Changes
96
-
97
- ### `src/lifecycle/agent-runner.ts`
98
-
99
- 1. Add `EnvironmentIO` interface (3 members) before the current `RunnerIO` definition.
100
- 2. Add `SessionFactoryIO` interface (5 members) after `EnvironmentIO`.
101
- 3. Change `RunnerIO` from an `interface` to a `type` alias: `type RunnerIO = EnvironmentIO & SessionFactoryIO`.
102
- 4. Export the two new interfaces alongside `RunnerIO`.
103
- 5. Move existing JSDoc from `RunnerIO` members to the sub-interfaces.
104
- 6. No changes to function signatures — `runAgent()` and `createAgentRunner()` keep accepting `RunnerIO`.
105
-
106
- ### `src/index.ts`
107
-
108
- No changes.
109
- The construction site builds a plain object satisfying all 8 members — TypeScript's structural typing ensures it satisfies `EnvironmentIO & SessionFactoryIO` without annotation changes.
110
-
111
- ### Test files
112
-
113
- No behavioral changes.
114
- The `createRunnerIO()` factories in both test files return unannotated plain objects that structurally satisfy the intersection.
115
- Comments referencing `RunnerIO` can be updated to mention the sub-interfaces for documentation clarity.
116
-
117
- Files affected:
118
-
119
- - `test/lifecycle/agent-runner.test.ts` — update comment (line ~23–27).
120
- - `test/lifecycle/agent-runner-extension-tools.test.ts` — update comment (line ~46).
121
-
122
- ## Test Impact Analysis
123
-
124
- 1. **New unit tests enabled:** The split enables future tests that inject only `EnvironmentIO` or only `SessionFactoryIO` — useful when testing environment-only or factory-only code paths in future extractions.
125
- No new tests are needed in this issue because `runAgent()` still consumes the full intersection.
126
- 2. **Redundant tests:** None — existing tests already test through `runAgent()` which uses all members.
127
- 3. **Tests that stay as-is:** All existing tests in both `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` remain valid; the factories produce objects compatible with the new type alias.
128
-
129
- ## TDD Order
130
-
131
- 1. **Red → Green: export `EnvironmentIO` and `SessionFactoryIO`, convert `RunnerIO` to type alias.**
132
- Test surface: existing `agent-runner.test.ts` and `agent-runner-extension-tools.test.ts` suites (must still pass).
133
- Run `pnpm run check` to verify type compatibility.
134
- Commit: `refactor: split RunnerIO into EnvironmentIO and SessionFactoryIO (#167)`
135
-
136
- 2. **Update test comments to reference sub-interfaces.**
137
- Test surface: no behavioral test changes — comment-only updates.
138
- Commit: `refactor: update test comments for RunnerIO sub-interfaces (#167)`
139
-
140
- ## Risks and Mitigations
141
-
142
- | Risk | Mitigation |
143
- | --------------------------------------------- | --------------------------------------------------------------------------------------------------- |
144
- | External consumers importing `RunnerIO` break | `RunnerIO` remains exported as a type alias for the intersection — fully backward-compatible |
145
- | Test factories need updating | Factories return unannotated objects — structural typing handles the new type alias without changes |
146
- | Future extractions assume wrong interface | Each sub-interface has a clear JSDoc explaining its scope |
147
-
148
- ## Open Questions
149
-
150
- None — the split follows the natural cohesion boundary identified in the issue body.
@@ -1,173 +0,0 @@
1
- ---
2
- issue: 168
3
- issue_title: "refactor(pi-subagents): extract ToolFilterConfig from SessionConfig (11 fields)"
4
- ---
5
-
6
- # Extract ToolFilterConfig from SessionConfig
7
-
8
- ## Problem Statement
9
-
10
- `SessionConfig` in `session-config.ts` has 10 top-level fields.
11
- Three of those fields — `toolNames`, `disallowedSet`, and `extensions` — form a cohesive tool-filtering cluster consumed together by `filterActiveTools` in `agent-runner.ts`.
12
- Today `filterActiveTools` accepts these as three separate positional parameters, and the guard condition `cfg.extensions !== false || cfg.disallowedSet` is duplicated at both call sites.
13
- Extracting the cluster into a named `ToolFilterConfig` type makes the relationship explicit and gives `filterActiveTools` a single named input.
14
-
15
- ## Goals
16
-
17
- - Define a `ToolFilterConfig` interface grouping `toolNames`, `disallowedSet`, and `extensions`.
18
- - Nest `ToolFilterConfig` inside `SessionConfig`, replacing the three flat fields.
19
- - Change `filterActiveTools` to accept `ToolFilterConfig` instead of three positional parameters.
20
- - Update `runAgent` to destructure `cfg.toolFilter` at both filter call sites.
21
- - Update all test assertions that read the three flat fields to use the nested path.
22
-
23
- ## Non-Goals
24
-
25
- - Extracting `ToolFilterConfig` into its own file — the type is small (3 fields) and co-located with its producer (`assembleSessionConfig`).
26
- - Adding a `needsFiltering()` predicate or encapsulating the guard condition — follow-up if the duplication grows.
27
- - Changing the `extensions` field on `AgentConfig` — that lives in the config domain and is unrelated.
28
-
29
- ## Background
30
-
31
- ### Affected modules
32
-
33
- | Module | Role |
34
- | ------------------------------- | -------------------------------------------------------------------- |
35
- | `src/session/session-config.ts` | Defines `SessionConfig`, produces it in `assembleSessionConfig` |
36
- | `src/lifecycle/agent-runner.ts` | Consumes `SessionConfig` in `runAgent`, contains `filterActiveTools` |
37
-
38
- ### Consumer analysis
39
-
40
- `runAgent` accesses the three tool-filter fields in four places:
41
-
42
- 1. `tools: cfg.toolNames` — passed to `io.createSession` (session-creation tool list).
43
- 2. `noExtensions: cfg.extensions === false` — resource-loader option.
44
- 3. Two identical guard-plus-filter blocks passing all three fields to `filterActiveTools`.
45
-
46
- After extraction, sites 1 and 2 will read from `cfg.toolFilter.toolNames` and `cfg.toolFilter.extensions`.
47
- Site 3 (both occurrences) will pass `cfg.toolFilter` as a single argument.
48
-
49
- ### Test files affected
50
-
51
- | Test file | What changes |
52
- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
53
- | `test/session/session-config.test.ts` | Assertions on `result.toolNames`, `result.extensions`, `result.disallowedSet` move to `result.toolFilter.*` |
54
- | `test/lifecycle/agent-runner-extension-tools.test.ts` | No direct `SessionConfig` assertions — exercises tool filtering via `runAgent` end-to-end; no changes needed |
55
-
56
- ### Dependency
57
-
58
- Issue #164 (reorganize into domain directories) — closed ✓.
59
-
60
- ## Design Overview
61
-
62
- ### ToolFilterConfig shape
63
-
64
- ```typescript
65
- /** Tool filtering configuration — consumed by filterActiveTools. */
66
- export interface ToolFilterConfig {
67
- /** Built-in tool name allowlist for this agent type. */
68
- toolNames: string[];
69
- /** Disallowed tool set from agentConfig. undefined when empty. */
70
- disallowedSet: Set<string> | undefined;
71
- /** Resolved extensions setting: false | true | string[] allowlist. */
72
- extensions: boolean | string[];
73
- }
74
- ```
75
-
76
- ### SessionConfig after extraction
77
-
78
- ```typescript
79
- export interface SessionConfig {
80
- effectiveCwd: string;
81
- systemPrompt: string;
82
- toolFilter: ToolFilterConfig;
83
- model: unknown;
84
- thinkingLevel: ThinkingLevel | undefined;
85
- noSkills: boolean;
86
- extras: PromptExtras;
87
- agentMaxTurns: number | undefined;
88
- }
89
- ```
90
-
91
- Field count drops from 10 top-level fields to 8 (7 remaining + 1 `toolFilter`).
92
-
93
- ### filterActiveTools after extraction
94
-
95
- ```typescript
96
- function filterActiveTools(
97
- activeTools: string[],
98
- config: ToolFilterConfig,
99
- ): string[] {
100
- const { toolNames, extensions, disallowedSet } = config;
101
- // ... body unchanged
102
- }
103
- ```
104
-
105
- ### Consumer call site (runAgent)
106
-
107
- ```typescript
108
- // Resource loader
109
- noExtensions: cfg.toolFilter.extensions === false,
110
-
111
- // Session creation
112
- tools: cfg.toolFilter.toolNames,
113
-
114
- // Guard + filter (two sites)
115
- if (cfg.toolFilter.extensions !== false || cfg.toolFilter.disallowedSet) {
116
- const filtered = filterActiveTools(session.getActiveToolNames(), cfg.toolFilter);
117
- session.setActiveToolsByName(filtered);
118
- }
119
- ```
120
-
121
- ## Module-Level Changes
122
-
123
- ### `src/session/session-config.ts`
124
-
125
- 1. Add `ToolFilterConfig` interface (exported — consumed by `agent-runner.ts`).
126
- 2. Replace `toolNames`, `disallowedSet`, and `extensions` fields on `SessionConfig` with a single `toolFilter: ToolFilterConfig` field.
127
- 3. Update `assembleSessionConfig` return statement to nest the three values under `toolFilter`.
128
-
129
- ### `src/lifecycle/agent-runner.ts`
130
-
131
- 1. Import `ToolFilterConfig` from `session-config.ts`.
132
- 2. Change `filterActiveTools` signature from `(activeTools, toolNames, extensions, disallowedSet)` to `(activeTools, config: ToolFilterConfig)`.
133
- 3. Destructure `config` inside `filterActiveTools` body.
134
- 4. Update both filter call sites to pass `cfg.toolFilter` instead of three separate arguments.
135
- 5. Update `noExtensions:` and `tools:` references to use `cfg.toolFilter.*`.
136
-
137
- ### `test/session/session-config.test.ts`
138
-
139
- 1. Update all assertions reading `result.toolNames` → `result.toolFilter.toolNames`.
140
- 2. Update all assertions reading `result.extensions` → `result.toolFilter.extensions`.
141
- 3. Update all assertions reading `result.disallowedSet` → `result.toolFilter.disallowedSet`.
142
-
143
- ## Test Impact Analysis
144
-
145
- 1. No new unit tests are needed — the extraction does not introduce new behavior or branching.
146
- 2. No existing tests become redundant — the assembler tests verify field population, and the extension-tools integration tests verify end-to-end filtering.
147
- Both remain valuable at their respective layers.
148
- 3. The `agent-runner-extension-tools.test.ts` tests exercise tool filtering via `runAgent` and do not reference `SessionConfig` fields directly, so they require no changes and serve as regression canaries for the refactoring.
149
-
150
- ## TDD Order
151
-
152
- This is a pure refactoring with no new behavior, so the steps are refactor→verify rather than red→green.
153
-
154
- 1. **Add `ToolFilterConfig` interface and nest it in `SessionConfig`; update assembler return.**
155
- Update `session-config.test.ts` assertions to read from `result.toolFilter.*`.
156
- Run `pnpm run check` + tests.
157
- Commit: `refactor(pi-subagents): extract ToolFilterConfig from SessionConfig`
158
-
159
- 2. **Change `filterActiveTools` signature to accept `ToolFilterConfig`; update `runAgent` call sites.**
160
- Import `ToolFilterConfig`, destructure inside `filterActiveTools`, update all `cfg.*` references in `runAgent`.
161
- Run `pnpm run check` + full test suite.
162
- Commit: `refactor(pi-subagents): pass ToolFilterConfig to filterActiveTools`
163
-
164
- ## Risks and Mitigations
165
-
166
- | Risk | Mitigation |
167
- | ------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
168
- | `cfg.toolNames` is also used for `tools:` in `createSession` — nesting it might confuse readers about intent | The field name `toolFilter.toolNames` is still descriptive; add a brief inline comment at the `tools:` site if needed |
169
- | Test assertions reference flat fields — missing one causes a silent pass on `undefined` | grep for all three field names across `test/` before committing step 1 |
170
-
171
- ## Open Questions
172
-
173
- None — the issue's proposed shape matches the architecture doc exactly and the change is internal to the package.