@gotgenes/pi-subagents 18.0.1 → 18.0.3

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