@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,166 +0,0 @@
1
- ---
2
- issue: 147
3
- issue_title: "Inject text wrapping into ConversationViewer (Phase 9, Step O)"
4
- ---
5
-
6
- # Inject text wrapping into ConversationViewer
7
-
8
- ## Problem Statement
9
-
10
- `ConversationViewer` calls `wrapTextWithAnsi` directly from `@earendil-works/pi-tui` in four places inside `buildContentLines`.
11
- Because the function is a module-level binding, tests must intercept it via a hoisted `vi.mock("@earendil-works/pi-tui")` factory that replaces the entire TUI module.
12
- This is the last `vi.mock` on an SDK module in the test suite, added specifically to exercise the overwidth-clamping safety net.
13
-
14
- ## Goals
15
-
16
- - Accept `wrapText: (text: string, width: number) => string[]` via `ConversationViewerOptions`.
17
- - Destructure `ConversationViewerOptions` in the constructor signature (dependency bag convention).
18
- - Replace all four `wrapTextWithAnsi` calls in `buildContentLines` with `this.wrapText`.
19
- - Remove `wrapTextWithAnsi` from `conversation-viewer.ts`'s `@earendil-works/pi-tui` import.
20
- - Pass `wrapTextWithAnsi` at the production call site in `agent-menu.ts`.
21
- - Eliminate the hoisted `vi.mock("@earendil-works/pi-tui")` from `conversation-viewer.test.ts`.
22
-
23
- ## Non-Goals
24
-
25
- - Injecting `truncateToWidth` or any other TUI function (only `wrapTextWithAnsi` is relevant here).
26
- - Changing the overwidth-clamping behavior of `buildContentLines`.
27
- - Touching `agent-widget.ts` (tracked separately as Issue #148, Step P — already closed).
28
-
29
- ## Background
30
-
31
- `ui/conversation-viewer.ts` is the live conversation overlay rendered when a user selects an agent in the `/agents` menu.
32
- Its `buildContentLines` method formats messages from the agent session into displayable lines, calling `wrapTextWithAnsi` to soft-wrap text to the available terminal width.
33
-
34
- The overwidth-clamping safety net (`truncateToWidth` applied after `wrapTextWithAnsi`) exists because a prior upstream bug returned lines wider than the requested width.
35
- The `vi.mock` in the test is the mechanism for simulating that bug by returning overwidth strings from `wrapTextWithAnsi`.
36
-
37
- The only production call site for `new ConversationViewer(...)` is in the `viewAgentConversation` closure inside `createAgentsMenuHandler` in `ui/agent-menu.ts`.
38
-
39
- Architecture reference: `docs/architecture/architecture.md` § Phase 9, Step O.
40
-
41
- ## Design Overview
42
-
43
- ### `ConversationViewerOptions` — add `wrapText`
44
-
45
- ```typescript
46
- export interface ConversationViewerOptions {
47
- tui: TUI;
48
- session: AgentSession;
49
- record: AgentRecord;
50
- activity: AgentActivityTracker | undefined;
51
- theme: Theme;
52
- done: (result: undefined) => void;
53
- registry: AgentConfigLookup;
54
- wrapText: (text: string, width: number) => string[];
55
- }
56
- ```
57
-
58
- The field is **required** — it must be supplied at every construction site.
59
- No default is provided; the default would be an invisible SDK dependency hidden inside the class.
60
-
61
- ### Constructor destructuring
62
-
63
- The constructor adopts the dependency bag convention — destructure the options object rather than accessing via `options.*`:
64
-
65
- ```typescript
66
- constructor({
67
- tui, session, record, activity, theme, done, registry, wrapText,
68
- }: ConversationViewerOptions) {
69
- this.tui = tui;
70
- this.session = session;
71
- // … etc.
72
- this.wrapText = wrapText;
73
- this.unsubscribe = session.subscribe(() => { … });
74
- }
75
- ```
76
-
77
- ### Production wiring — `agent-menu.ts`
78
-
79
- `agent-menu.ts` statically imports `wrapTextWithAnsi` from `@earendil-works/pi-tui` and passes it when constructing `ConversationViewer`:
80
-
81
- ```typescript
82
- import { wrapTextWithAnsi } from "@earendil-works/pi-tui";
83
- // …
84
- return new ConversationViewer({
85
- tui, session, record, activity, theme, done, registry,
86
- wrapText: wrapTextWithAnsi,
87
- });
88
- ```
89
-
90
- Adding `wrapText` to `AgentMenuDeps` and threading it through the closure would violate the Law of Demeter — `AgentMenuDeps` has no conceptual ownership of a text-wrapping function.
91
- The `viewAgentConversation` closure is the direct consumer; the import belongs there.
92
-
93
- ### Test strategy
94
-
95
- After DI, tests pass `wrapText` directly in `ConversationViewerOptions`:
96
-
97
- - **"render width safety" tests**: pass `wrapText: wrapTextWithAnsi` (real function, statically imported — no mock).
98
- - **"safety net" tests**: pass a stub `wrapText: () => ["X".repeat(width + 50)]` inline in options — no `vi.mock` needed.
99
- - The "mock is intercepting wrapTextWithAnsi" test is removed (it verified the mock mechanism, not viewer behavior).
100
- - The module-level `wrapOverride` variable and the `vi.mock` block are removed entirely.
101
- - The `await import("@earendil-works/pi-tui")` and `await import("../src/ui/conversation-viewer.js")` dynamic imports are converted to ordinary top-level `import` statements.
102
-
103
- ## Module-Level Changes
104
-
105
- | File | Change |
106
- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
107
- | `src/ui/conversation-viewer.ts` | Add `wrapText` field to `ConversationViewerOptions`; add `private wrapText` field; destructure options in constructor; replace 4× `wrapTextWithAnsi(...)` with `this.wrapText(...)`; remove `wrapTextWithAnsi` from the `@earendil-works/pi-tui` import line |
108
- | `src/ui/agent-menu.ts` | Add `import { wrapTextWithAnsi } from "@earendil-works/pi-tui"`; pass `wrapText: wrapTextWithAnsi` in `viewAgentConversation` |
109
- | `test/conversation-viewer.test.ts` | Convert top-level dynamic `await import()` to static imports; remove `vi.mock`, `wrapOverride`, and "mock is intercepting" test; add `wrapText` to every `new ConversationViewer({…})` call; update safety-net tests to pass inline stub `wrapText` |
110
-
111
- No symbols are removed from exported API (`ConversationViewerOptions`, `ConversationViewer`, `VIEWPORT_HEIGHT_PCT` all remain).
112
- The `wrapText` addition to `ConversationViewerOptions` is a breaking change for any external consumers that construct `ConversationViewer` — check for usages outside this package.
113
-
114
- Grep check: `ConversationViewer` appears only in `src/ui/conversation-viewer.ts`, `src/ui/agent-menu.ts`, and `test/conversation-viewer.test.ts` — no other files construct it.
115
-
116
- ## Test Impact Analysis
117
-
118
- 1. **New unit-test capability**: The safety-net tests can now inject exactly the stub they need without patching a module.
119
- Each test is self-contained and immediately legible — the stub is declared inline at the call site.
120
-
121
- 2. **Tests that become redundant**: The "mock is intercepting wrapTextWithAnsi" test verified the test mechanism, not production behavior.
122
- It is deleted.
123
- The `wrapOverride` reset in `beforeEach` is no longer needed.
124
-
125
- 3. **Tests that stay**: All "render width safety" tests and all overwidth-clamping tests remain; they exercise real viewer behavior with real or controlled inputs.
126
-
127
- ## TDD Order
128
-
129
- ### Cycle 1 — Add `wrapText` field and update production wiring
130
-
131
- 1. **Red**: Update one `new ConversationViewer({…})` in the test to include `wrapText: vi.fn()` — TypeScript rejects the unknown field.
132
- 2. **Green**:
133
- - Add `wrapText: (text: string, width: number) => string[]` to `ConversationViewerOptions`.
134
- - Add `private wrapText: (text: string, width: number) => string[]` field to the class.
135
- - Destructure options in the constructor; assign `this.wrapText = wrapText`.
136
- - Replace all four `wrapTextWithAnsi(...)` calls with `this.wrapText(...)` in `buildContentLines`.
137
- - Remove `wrapTextWithAnsi` from the `@earendil-works/pi-tui` import in `conversation-viewer.ts`.
138
- - In `agent-menu.ts`: add static import of `wrapTextWithAnsi` from `@earendil-works/pi-tui`; pass `wrapText: wrapTextWithAnsi`.
139
- - Update **all** `new ConversationViewer({…})` calls in `conversation-viewer.test.ts` to include `wrapText`.
140
- "Render width safety" tests pass `wrapText: wrapTextWithAnsi` (real function, still imported via the existing `vi.mock` shim for now).
141
- Safety-net tests pass a stub inline: `wrapText: () => ["X".repeat(w + 50)]`.
142
- - Delete the "mock is intercepting wrapTextWithAnsi" test.
143
- 3. **Verify**: `pnpm vitest run test/conversation-viewer.test.ts` passes.
144
- 4. **Commit**: `feat: inject wrapText into ConversationViewer (Phase 9, Step O) (#147)`
145
-
146
- ### Cycle 2 — Remove the module mock
147
-
148
- 1. **Red**: Remove the `vi.mock("@earendil-works/pi-tui", …)` block, the `wrapOverride` variable, and the `beforeEach(() => { wrapOverride = null; })` reset.
149
- Convert `const { visibleWidth } = await import("@earendil-works/pi-tui")` to `import { visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui"`.
150
- Convert `const { ConversationViewer } = await import("../src/ui/conversation-viewer.js")` to `import { ConversationViewer } from "../src/ui/conversation-viewer.js"`.
151
- Run tests — they should still pass (the mock was no longer needed after Cycle 1).
152
- 2. **Green**: Tests pass without any module mock.
153
- 3. **Verify**: `pnpm vitest run test/conversation-viewer.test.ts` and `pnpm run check` both pass.
154
- 4. **Commit**: `refactor: remove vi.mock from conversation-viewer tests (#147)`
155
-
156
- ## Risks and Mitigations
157
-
158
- | Risk | Mitigation |
159
- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
160
- | Missing a `new ConversationViewer({…})` call site in tests | Grep confirms only `test/conversation-viewer.test.ts` constructs the viewer; all instances are in-file |
161
- | TypeScript missing the `private wrapText` field type | Use `pnpm run check` after Cycle 1 to verify no type errors |
162
- | The dynamic `await import()` pattern in tests was necessary for some other reason | The only purpose was to run after `vi.mock` hoisting; once the mock is gone, static imports work fine |
163
-
164
- ## Open Questions
165
-
166
- None — the issue's "Changes" section is unambiguous and the call-site inventory is small.
@@ -1,255 +0,0 @@
1
- ---
2
- issue: 148
3
- issue_title: "Split AgentWidget rendering from lifecycle (Phase 9, Step P)"
4
- ---
5
-
6
- # Split AgentWidget rendering from lifecycle
7
-
8
- ## Problem Statement
9
-
10
- `AgentWidget` (374 lines) mixes rendering, lifecycle management, spinner animation, state filtering, and status bar management in a single class.
11
- `renderWidget` alone is ~109 lines, and `renderFinishedLine` adds another ~40.
12
- The constructor takes 3 concrete collaborators (`AgentManager`, `Map<string, AgentActivityTracker>`, `AgentTypeRegistry`) with no interface extraction.
13
- Rendering logic cannot be unit-tested without instantiating the full widget with its lifecycle machinery.
14
-
15
- ## Goals
16
-
17
- - Extract pure rendering functions from `AgentWidget` into `ui/widget-renderer.ts`.
18
- - Make `AgentWidget` a thin lifecycle/polling wrapper that delegates to pure render functions.
19
- - Enable direct unit testing of rendering logic with plain data — no widget lifecycle, no mocks for `setInterval`/`setWidget`/`requestRender`.
20
-
21
- ## Non-Goals
22
-
23
- - Changing the visual output of the widget (this is a pure refactor).
24
- - Extracting the status bar logic into a separate module (could follow up).
25
- - Narrowing the `AgentManager` dependency to an interface (tracked separately in the architecture doc).
26
- - Injecting `truncateToWidth` (tracked as #147, Step O — an independent track).
27
-
28
- ## Background
29
-
30
- ### Dependency: #144 (Step L) — Consolidate observation model
31
-
32
- Issue #144 is **closed/implemented**.
33
- The renderer now reads stats (`toolUses`, `lifetimeUsage`, `compactionCount`) from `AgentRecord` and live UI state (`activeTools`, `responseText`, `turnCount`, `maxTurns`) from `AgentActivityTracker`.
34
- No dual-counting fallback exists.
35
-
36
- ### Existing pure helpers
37
-
38
- `ui/display.ts` already contains stateless formatting functions (`formatMs`, `formatTurns`, `formatSessionTokens`, `describeActivity`, `getDisplayName`, `getPromptModeLabel`, `SPINNER`, `ERROR_STATUSES`, `Theme`).
39
- The new `widget-renderer.ts` will consume these — it does not duplicate them.
40
-
41
- ### Rendering data flow
42
-
43
- The widget's `renderWidget` currently:
44
-
45
- 1. Calls `this.manager.listAgents()` to get `AgentRecord[]`.
46
- 2. Categorizes into running/queued/finished.
47
- 3. Filters finished agents via `this.shouldShowFinished()`.
48
- 4. Looks up `this.agentActivity.get(a.id)` for live stats.
49
- 5. Calls `this.registry` for display names.
50
- 6. Reads `this.widgetFrame` for spinner animation.
51
- 7. Assembles tree-style lines with overflow logic.
52
-
53
- Steps 3–7 are pure given the right inputs.
54
- Steps 1–2 are also pure categorization.
55
-
56
- ## Design Overview
57
-
58
- ### Separation of concerns
59
-
60
- The rendering extraction splits the widget into two layers:
61
-
62
- 1. **`widget-renderer.ts`** — Pure functions that accept data and return `string[]`.
63
- No `this`, no timers, no SDK types, no side effects.
64
- 2. **`agent-widget.ts`** — Thin lifecycle wrapper that owns timers, UICtx, finished-turn aging, and calls the renderer with live data.
65
-
66
- ### Renderer input shape
67
-
68
- Rather than passing the full `AgentRecord` class (which carries mutation methods and phase collaborators), the renderer receives a plain data slice:
69
-
70
- ```typescript
71
- /** Minimal agent snapshot for rendering — no class methods, no mutation surface. */
72
- export interface WidgetAgent {
73
- readonly id: string;
74
- readonly type: SubagentType;
75
- readonly status: string;
76
- readonly description: string;
77
- readonly toolUses: number;
78
- readonly startedAt: number;
79
- readonly completedAt?: number;
80
- readonly error?: string;
81
- readonly lifetimeUsage?: Readonly<LifetimeUsage>;
82
- readonly compactionCount: number;
83
- }
84
- ```
85
-
86
- This is structurally compatible with `AgentRecord` (the class satisfies it), so no mapping code is needed at the call site — `listAgents()` returns `AgentRecord[]` which satisfies `WidgetAgent[]`.
87
-
88
- ### Renderer input for activity
89
-
90
- Activity state is read from `AgentActivityTracker`.
91
- The renderer needs a read-only view per agent:
92
-
93
- ```typescript
94
- /** Read-only activity snapshot for widget rendering. */
95
- export interface WidgetActivity {
96
- readonly activeTools: ReadonlyMap<string, string>;
97
- readonly responseText: string;
98
- readonly turnCount: number;
99
- readonly maxTurns?: number;
100
- readonly session?: SessionLike;
101
- }
102
- ```
103
-
104
- `AgentActivityTracker` already satisfies this structurally (it exposes these as getters).
105
-
106
- ### Agent config lookup
107
-
108
- The renderer needs `getDisplayName` and `getPromptModeLabel`, which take a `SubagentType` and an `AgentConfigLookup`.
109
- The renderer accepts `AgentConfigLookup` (the existing interface from `agent-types.ts`) — not the concrete `AgentTypeRegistry` class.
110
-
111
- ### Renderer API
112
-
113
- ```typescript
114
- /** Pure rendering of the widget body. Returns lines to display. */
115
- export function renderWidgetLines(params: {
116
- agents: readonly WidgetAgent[];
117
- activityMap: ReadonlyMap<string, WidgetActivity>;
118
- registry: AgentConfigLookup;
119
- spinnerFrame: number;
120
- terminalWidth: number;
121
- shouldShowFinished: (agentId: string, status: string) => boolean;
122
- }): string[];
123
-
124
- /** Pure rendering of a single finished agent line (no tree connector prefix). */
125
- export function renderFinishedLine(
126
- agent: WidgetAgent,
127
- activity: WidgetActivity | undefined,
128
- registry: AgentConfigLookup,
129
- theme: Theme,
130
- ): string;
131
-
132
- /** Pure rendering of a single running agent (header + activity lines, no tree connector prefix). */
133
- export function renderRunningLines(
134
- agent: WidgetAgent,
135
- activity: WidgetActivity | undefined,
136
- registry: AgentConfigLookup,
137
- spinnerFrame: number,
138
- theme: Theme,
139
- ): [header: string, activity: string];
140
- ```
141
-
142
- The top-level `renderWidgetLines` encapsulates the full categorization, overflow logic, and tree-connector fixup.
143
- The per-agent functions are exported for fine-grained testing.
144
-
145
- The `shouldShowFinished` callback is injected rather than re-implementing the aging logic inside the renderer, keeping the renderer pure and the aging state in the widget.
146
-
147
- ### Call site in AgentWidget
148
-
149
- ```typescript
150
- // Inside renderWidget(tui, theme):
151
- const w = tui.terminal.columns;
152
- return renderWidgetLines({
153
- agents: this.manager.listAgents(),
154
- activityMap: this.agentActivity,
155
- registry: this.registry,
156
- spinnerFrame: this.widgetFrame,
157
- terminalWidth: w,
158
- shouldShowFinished: (id, status) => this.shouldShowFinished(id, status),
159
- });
160
- ```
161
-
162
- The widget's `renderWidget` method shrinks to ~5 lines.
163
-
164
- ### Tell-Don't-Ask verification
165
-
166
- The renderer receives pre-collected data and returns formatted strings.
167
- It does not reach through collaborators — it reads flat fields from `WidgetAgent` and `WidgetActivity`.
168
- The widget tells the renderer "render this data"; the renderer returns lines.
169
- No Law of Demeter violations.
170
-
171
- ## Module-Level Changes
172
-
173
- ### New file: `src/ui/widget-renderer.ts`
174
-
175
- - `WidgetAgent` interface (structural subset of `AgentRecord`).
176
- - `WidgetActivity` interface (structural subset of `AgentActivityTracker`).
177
- - `renderWidgetLines()` — top-level rendering with categorization, overflow, tree connectors.
178
- - `renderFinishedLine()` — single finished-agent line.
179
- - `renderRunningLines()` — single running-agent header + activity pair.
180
- - Imports from `display.ts` (`SPINNER`, `ERROR_STATUSES`, `formatMs`, `formatTurns`, `formatSessionTokens`, `describeActivity`, `getDisplayName`, `getPromptModeLabel`, `Theme`), from `usage.ts` (`getLifetimeTotal`, `getSessionContextPercent`, `LifetimeUsage`, `SessionLike`), and from `@earendil-works/pi-tui` (`truncateToWidth`).
181
-
182
- ### Modified: `src/ui/agent-widget.ts`
183
-
184
- - Remove `renderWidget()` method body — replace with call to `renderWidgetLines()`.
185
- - Remove `renderFinishedLine()` method entirely.
186
- - Remove direct imports of display helpers and usage helpers that are now only consumed by `widget-renderer.ts`.
187
- - Keep: constructor, `setUICtx`, `onTurnStart`, `ensureTimer`, `shouldShowFinished`, `markFinished`, `update`, `dispose`, `UICtx` type, `MAX_WIDGET_LINES`.
188
- - The inline type on `renderFinishedLine`'s parameter `a` is replaced by the `WidgetAgent` import.
189
-
190
- ### New file: `test/widget-renderer.test.ts`
191
-
192
- - Unit tests for `renderWidgetLines`, `renderFinishedLine`, `renderRunningLines`.
193
- - Uses plain data objects (no mocks for `AgentManager`, `setInterval`, or SDK).
194
- - Stub `Theme` matching the pattern in `test/renderer.test.ts`.
195
-
196
- ### No changes to
197
-
198
- - `src/index.ts` — the widget is constructed the same way; renderer is internal to the widget module.
199
- - `src/ui/display.ts` — unchanged; consumed by the new renderer.
200
- - `src/usage.ts` — unchanged.
201
-
202
- ## Test Impact Analysis
203
-
204
- 1. The extraction enables direct unit testing of widget rendering that was previously impossible — testing `renderWidget` required constructing a full `AgentWidget` with mocked `AgentManager`, fake timers, and a stubbed UICtx.
205
- The new tests cover: finished-agent line formatting (all status variants), running-agent header/activity rendering, overflow logic, tree-connector fixup, empty-state handling, and `shouldShowFinished` filtering.
206
- 2. No existing tests become redundant — there are currently **no** unit tests for `AgentWidget` rendering.
207
- The existing `display.test.ts` tests lower-level formatters and remains as-is.
208
- 3. `renderer.test.ts` tests the notification renderer — unrelated, stays as-is.
209
-
210
- ## TDD Order
211
-
212
- 1. **Red → Green:** Test `renderFinishedLine` for a completed agent (success icon, stats, duration).
213
- Commit: `test: add renderFinishedLine tests for completed status`
214
-
215
- 2. **Red → Green:** Test `renderFinishedLine` for error/aborted/steered/stopped statuses (icon and status text variations).
216
- Commit: `test: renderFinishedLine error and terminal status variants`
217
-
218
- 3. **Red → Green:** Test `renderRunningLines` (spinner frame, stats, activity description, token display).
219
- Commit: `test: add renderRunningLines tests`
220
-
221
- 4. **Red → Green:** Test `renderWidgetLines` — basic case with one running agent (heading, tree connectors).
222
- Commit: `test: renderWidgetLines single running agent`
223
-
224
- 5. **Red → Green:** Test `renderWidgetLines` — mixed running + finished + queued, verifying categorization and ordering.
225
- Commit: `test: renderWidgetLines mixed agent states`
226
-
227
- 6. **Red → Green:** Test `renderWidgetLines` — overflow cap with many agents, verifying the priority (running > queued > finished) and overflow summary line.
228
- Commit: `test: renderWidgetLines overflow behavior`
229
-
230
- 7. **Red → Green:** Test `renderWidgetLines` — empty state returns `[]`; finished-only state uses dim heading.
231
- Commit: `test: renderWidgetLines empty and finished-only states`
232
-
233
- 8. **Green → Refactor:** Extract `renderFinishedLine`, `renderRunningLines`, and `renderWidgetLines` into `src/ui/widget-renderer.ts`.
234
- All tests pass against the extracted module.
235
- Commit: `refactor: extract widget rendering into widget-renderer`
236
-
237
- 9. **Green → Refactor:** Wire `AgentWidget.renderWidget()` to delegate to `renderWidgetLines()`.
238
- Remove the inlined rendering logic from `agent-widget.ts`.
239
- Remove unused imports.
240
- Commit: `refactor: AgentWidget delegates rendering to widget-renderer`
241
-
242
- 10. **Verify:** Run full test suite (`pnpm vitest run`) and type check (`pnpm run check`).
243
- Commit: none (verification only).
244
-
245
- ## Risks and Mitigations
246
-
247
- | Risk | Mitigation |
248
- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
249
- | Structural compatibility between `AgentRecord` and `WidgetAgent` could drift if `AgentRecord` renames a field. | TypeScript's structural checking catches this at the call site in `agent-widget.ts` — `listAgents()` returns `AgentRecord[]` which must satisfy `readonly WidgetAgent[]`. |
250
- | `truncateToWidth` is an external dependency (`@earendil-works/pi-tui`) in the renderer. | Step O (#147) will inject it; for now, the renderer imports it directly, matching the current widget behavior. |
251
- | Overflow logic is complex and hand-tested — extraction could introduce subtle line-count bugs. | TDD steps 4–7 exercise overflow edge cases before the extraction step. The extraction is a mechanical move with tests already passing. |
252
-
253
- ## Open Questions
254
-
255
- - None — the design follows the architecture doc's Step P specification and the dependency (#144) is already implemented.
@@ -1,91 +0,0 @@
1
- ---
2
- issue: 152
3
- issue_title: "Add promptSnippet to pi-subagents tools"
4
- ---
5
-
6
- # Add `promptSnippet` to pi-subagents tools
7
-
8
- ## Problem Statement
9
-
10
- The `Agent`, `get_subagent_result`, and `steer_subagent` tools are the only tools across the monorepo that lack `promptSnippet`.
11
- Pi's `buildSystemPrompt` uses `promptSnippet` to build a concise tool summary in the system prompt.
12
- Without it, these tools rely entirely on their `description` field for model guidance.
13
- The `Agent` tool's description is especially long (embeds full usage guidelines), so a short snippet would give the model a better quick-reference view.
14
-
15
- ## Goals
16
-
17
- - Add `promptSnippet` to each of the three tool registrations in pi-subagents.
18
- - Match the established `"<toolName>: <one-liner>"` format used by pi-github-tools and pi-colgrep.
19
-
20
- ## Non-Goals
21
-
22
- - Changing `description`, `promptGuidelines`, or any other tool registration field.
23
- - Adding `promptSnippet` to tools in other packages (already done).
24
-
25
- ## Background
26
-
27
- Sibling packages pi-github-tools and pi-colgrep already provide `promptSnippet` on every tool.
28
- The convention is a single string in the form `"tool_name: Short imperative description."`.
29
- For example: `"ci_list: List recent CI runs for a workflow."`.
30
-
31
- The three tool factories live in:
32
-
33
- | Factory | File |
34
- | --------------------- | ------------------------------ |
35
- | `createAgentTool` | `src/tools/agent-tool.ts` |
36
- | `createGetResultTool` | `src/tools/get-result-tool.ts` |
37
- | `createSteerTool` | `src/tools/steer-tool.ts` |
38
-
39
- Each factory returns a plain object with `name`, `label`, `description`, `parameters`, and `execute`.
40
- Adding `promptSnippet` is a single property addition per factory.
41
-
42
- ## Design Overview
43
-
44
- No structural change — this is a property addition to three existing object literals.
45
-
46
- Proposed snippets:
47
-
48
- - **Agent** — `"Agent: Launch a specialized agent for complex, multi-step tasks."`
49
- - **get_subagent_result** — `"get_subagent_result: Check status and retrieve results from a background agent."`
50
- - **steer_subagent** — `"steer_subagent: Send a mid-run message to redirect a running background agent."`
51
-
52
- These are the exact phrasings from the issue.
53
- Exact wording may be refined during implementation.
54
-
55
- ## Module-Level Changes
56
-
57
- ### `src/tools/agent-tool.ts`
58
-
59
- Add `promptSnippet` property to the object returned by `createAgentTool`, after `label`.
60
-
61
- ### `src/tools/get-result-tool.ts`
62
-
63
- Add `promptSnippet` property to the object returned by `createGetResultTool`, after `label`.
64
-
65
- ### `src/tools/steer-tool.ts`
66
-
67
- Add `promptSnippet` property to the object returned by `createSteerTool`, after `label`.
68
-
69
- ## Test Impact Analysis
70
-
71
- Existing tool-definition tests (`test/tools/agent-tool.test.ts`, `get-result-tool.test.ts`, `steer-tool.test.ts`) assert `name`, `label`, and `description` but not `promptSnippet`.
72
- New assertions will verify the property exists with the expected value.
73
- No existing tests need modification — the new property is additive.
74
-
75
- ## TDD Order
76
-
77
- 1. **Red → Green:** Add `promptSnippet` assertions to the tool-definition tests for all three tools, then add the `promptSnippet` property to each factory.
78
- Commit: `feat: add promptSnippet to Agent, get_subagent_result, and steer_subagent (#152)`
79
-
80
- This is a single-cycle change — one test step, one implementation step, one commit.
81
-
82
- ## Risks and Mitigations
83
-
84
- | Risk | Mitigation |
85
- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
86
- | Snippet wording doesn't match what Pi displays well | The snippets mirror the first sentence of each tool's `description`; can be tweaked in a follow-up without breaking anything. |
87
- | SDK `defineTool` doesn't pass through `promptSnippet` | Sibling packages already use it successfully, confirming SDK support. |
88
-
89
- ## Open Questions
90
-
91
- None.