gsd-pi 2.76.0 → 2.77.0-dev.538325aea

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 (1182) hide show
  1. package/README.md +32 -30
  2. package/dist/claude-cli-check.js +32 -3
  3. package/dist/cli.js +13 -21
  4. package/dist/extension-registry.js +1 -1
  5. package/dist/headless-ui.d.ts +1 -1
  6. package/dist/headless.js +2 -4
  7. package/dist/loader.js +0 -1
  8. package/dist/mcp-server.d.ts +7 -0
  9. package/dist/mcp-server.js +35 -1
  10. package/dist/onboarding.js +50 -5
  11. package/dist/provider-migrations.d.ts +2 -2
  12. package/dist/provider-migrations.js +2 -1
  13. package/dist/remote-questions-config.js +1 -1
  14. package/dist/resource-loader.d.ts +1 -1
  15. package/dist/resource-loader.js +2 -8
  16. package/dist/resources/agents/researcher.md +1 -1
  17. package/dist/resources/extensions/async-jobs/async-bash-tool.js +1 -1
  18. package/dist/resources/extensions/aws-auth/index.js +2 -1
  19. package/dist/resources/extensions/bg-shell/bg-shell-lifecycle.js +6 -9
  20. package/dist/resources/extensions/bg-shell/process-manager.js +2 -1
  21. package/dist/resources/extensions/browser-tools/index.js +0 -1
  22. package/dist/resources/extensions/claude-code-cli/index.js +1 -1
  23. package/dist/resources/extensions/claude-code-cli/partial-builder.js +106 -17
  24. package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
  25. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +94 -27
  26. package/dist/resources/extensions/gsd/auto/loop.js +9 -0
  27. package/dist/resources/extensions/gsd/auto/phases.js +104 -11
  28. package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
  29. package/dist/resources/extensions/gsd/auto/session.js +22 -1
  30. package/dist/resources/extensions/gsd/auto-dispatch.js +56 -17
  31. package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
  32. package/dist/resources/extensions/gsd/auto-post-unit.js +59 -2
  33. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  34. package/dist/resources/extensions/gsd/auto-recovery.js +69 -1
  35. package/dist/resources/extensions/gsd/auto-start.js +74 -59
  36. package/dist/resources/extensions/gsd/auto-verification.js +33 -0
  37. package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
  38. package/dist/resources/extensions/gsd/auto.js +70 -28
  39. package/dist/resources/extensions/gsd/blocked-models.js +68 -0
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
  41. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
  42. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
  43. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
  45. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
  46. package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -23
  47. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  48. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  49. package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
  50. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  51. package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
  52. package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
  53. package/dist/resources/extensions/gsd/db-writer.js +88 -16
  54. package/dist/resources/extensions/gsd/dispatch-guard.js +44 -3
  55. package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
  56. package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
  57. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
  58. package/dist/resources/extensions/gsd/error-classifier.js +31 -3
  59. package/dist/resources/extensions/gsd/exec-history.js +120 -0
  60. package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
  61. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  62. package/dist/resources/extensions/gsd/gsd-db.js +168 -23
  63. package/dist/resources/extensions/gsd/guided-flow.js +191 -2
  64. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  65. package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
  66. package/dist/resources/extensions/gsd/init-wizard.js +15 -1
  67. package/dist/resources/extensions/gsd/key-manager.js +28 -0
  68. package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
  69. package/dist/resources/extensions/gsd/memory-store.js +19 -0
  70. package/dist/resources/extensions/gsd/model-router.js +36 -3
  71. package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
  72. package/dist/resources/extensions/gsd/preferences-types.js +9 -0
  73. package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
  74. package/dist/resources/extensions/gsd/preferences.js +17 -17
  75. package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
  76. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  78. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  80. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  81. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  82. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  84. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
  85. package/dist/resources/extensions/gsd/prompts/system.md +1 -0
  86. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  87. package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
  88. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  89. package/dist/resources/extensions/gsd/state.js +43 -4
  90. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  91. package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
  92. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
  93. package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
  94. package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
  95. package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
  96. package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
  97. package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
  98. package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  99. package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
  100. package/dist/resources/extensions/mcp-client/index.js +1 -1
  101. package/dist/resources/extensions/ollama/index.js +1 -2
  102. package/dist/resources/extensions/ollama/ollama-chat-provider.js +5 -15
  103. package/dist/resources/extensions/remote-questions/config.js +12 -1
  104. package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
  105. package/dist/resources/extensions/search-the-web/native-search.js +45 -13
  106. package/dist/resources/extensions/universal-config/index.js +1 -1
  107. package/dist/resources/skills/api-design/SKILL.md +190 -0
  108. package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
  109. package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
  110. package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
  111. package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
  112. package/dist/resources/skills/forensics/SKILL.md +153 -0
  113. package/dist/resources/skills/grill-me/SKILL.md +93 -0
  114. package/dist/resources/skills/handoff/SKILL.md +121 -0
  115. package/dist/resources/skills/observability/SKILL.md +174 -0
  116. package/dist/resources/skills/security-review/SKILL.md +181 -0
  117. package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
  118. package/dist/resources/skills/tdd/SKILL.md +112 -0
  119. package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
  120. package/dist/resources/skills/write-docs/SKILL.md +82 -0
  121. package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
  122. package/dist/security-overrides.d.ts +4 -1
  123. package/dist/security-overrides.js +16 -3
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  127. package/dist/web/standalone/.next/build-manifest.json +4 -4
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  130. package/dist/web/standalone/.next/required-server-files.json +4 -4
  131. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  132. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  142. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  158. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  170. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  200. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  206. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  220. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  222. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  224. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  226. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  235. package/dist/web/standalone/.next/server/app/index.html +1 -1
  236. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  237. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  238. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  239. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  240. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  241. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  242. package/dist/web/standalone/.next/server/app/page.js +2 -2
  243. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  244. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  245. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  246. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  247. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  249. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/middleware.js +2 -2
  251. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  252. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  253. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  254. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  255. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  256. package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +9 -0
  257. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  258. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  259. package/dist/web/standalone/.next/static/chunks/app/page-5b113fd32bc2a1c3.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  261. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-1832629448831fdc.js} +1 -1
  263. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  264. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  265. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  266. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  267. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  268. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  269. package/dist/web/standalone/server.js +1 -1
  270. package/dist/web-mode.js +1 -1
  271. package/dist/welcome-screen.js +19 -15
  272. package/dist/wizard.js +4 -5
  273. package/package.json +25 -7
  274. package/packages/daemon/package.json +2 -2
  275. package/packages/gsd-agent-core/dist/agent-session.d.ts +716 -0
  276. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -0
  277. package/packages/gsd-agent-core/dist/agent-session.js +2595 -0
  278. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -0
  279. package/packages/gsd-agent-core/dist/artifact-manager.d.ts +52 -0
  280. package/packages/gsd-agent-core/dist/artifact-manager.d.ts.map +1 -0
  281. package/packages/gsd-agent-core/dist/artifact-manager.js +118 -0
  282. package/packages/gsd-agent-core/dist/artifact-manager.js.map +1 -0
  283. package/packages/gsd-agent-core/dist/bash-executor.d.ts +57 -0
  284. package/packages/gsd-agent-core/dist/bash-executor.d.ts.map +1 -0
  285. package/packages/gsd-agent-core/dist/bash-executor.js +282 -0
  286. package/packages/gsd-agent-core/dist/bash-executor.js.map +1 -0
  287. package/packages/gsd-agent-core/dist/blob-store.d.ts +39 -0
  288. package/packages/gsd-agent-core/dist/blob-store.d.ts.map +1 -0
  289. package/packages/gsd-agent-core/dist/blob-store.js +151 -0
  290. package/packages/gsd-agent-core/dist/blob-store.js.map +1 -0
  291. package/packages/gsd-agent-core/dist/compaction/branch-summarization.d.ts +90 -0
  292. package/packages/gsd-agent-core/dist/compaction/branch-summarization.d.ts.map +1 -0
  293. package/packages/gsd-agent-core/dist/compaction/branch-summarization.js +207 -0
  294. package/packages/gsd-agent-core/dist/compaction/branch-summarization.js.map +1 -0
  295. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +137 -0
  296. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -0
  297. package/packages/gsd-agent-core/dist/compaction/compaction.js +621 -0
  298. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -0
  299. package/packages/gsd-agent-core/dist/compaction/index.d.ts +7 -0
  300. package/packages/gsd-agent-core/dist/compaction/index.d.ts.map +1 -0
  301. package/packages/gsd-agent-core/dist/compaction/index.js +7 -0
  302. package/packages/gsd-agent-core/dist/compaction/index.js.map +1 -0
  303. package/packages/gsd-agent-core/dist/compaction/utils.d.ts +78 -0
  304. package/packages/gsd-agent-core/dist/compaction/utils.d.ts.map +1 -0
  305. package/packages/gsd-agent-core/dist/compaction/utils.js +263 -0
  306. package/packages/gsd-agent-core/dist/compaction/utils.js.map +1 -0
  307. package/packages/gsd-agent-core/dist/compaction-orchestrator.d.ts +90 -0
  308. package/packages/gsd-agent-core/dist/compaction-orchestrator.d.ts.map +1 -0
  309. package/packages/gsd-agent-core/dist/compaction-orchestrator.js +338 -0
  310. package/packages/gsd-agent-core/dist/compaction-orchestrator.js.map +1 -0
  311. package/packages/gsd-agent-core/dist/contextual-tips.d.ts +43 -0
  312. package/packages/gsd-agent-core/dist/contextual-tips.d.ts.map +1 -0
  313. package/packages/gsd-agent-core/dist/contextual-tips.js +208 -0
  314. package/packages/gsd-agent-core/dist/contextual-tips.js.map +1 -0
  315. package/packages/gsd-agent-core/dist/export-html/ansi-to-html.d.ts +18 -0
  316. package/packages/gsd-agent-core/dist/export-html/ansi-to-html.d.ts.map +1 -0
  317. package/packages/gsd-agent-core/dist/export-html/ansi-to-html.js +250 -0
  318. package/packages/gsd-agent-core/dist/export-html/ansi-to-html.js.map +1 -0
  319. package/packages/gsd-agent-core/dist/export-html/index.d.ts +37 -0
  320. package/packages/gsd-agent-core/dist/export-html/index.d.ts.map +1 -0
  321. package/packages/gsd-agent-core/dist/export-html/index.js +257 -0
  322. package/packages/gsd-agent-core/dist/export-html/index.js.map +1 -0
  323. package/packages/gsd-agent-core/dist/export-html/template.css +971 -0
  324. package/packages/gsd-agent-core/dist/export-html/template.html +54 -0
  325. package/packages/gsd-agent-core/dist/export-html/template.js +1583 -0
  326. package/packages/gsd-agent-core/dist/export-html/tool-renderer.d.ts +38 -0
  327. package/packages/gsd-agent-core/dist/export-html/tool-renderer.d.ts.map +1 -0
  328. package/packages/gsd-agent-core/dist/export-html/tool-renderer.js +70 -0
  329. package/packages/gsd-agent-core/dist/export-html/tool-renderer.js.map +1 -0
  330. package/packages/gsd-agent-core/dist/export-html/vendor/highlight.min.js +1213 -0
  331. package/packages/gsd-agent-core/dist/export-html/vendor/marked.min.js +6 -0
  332. package/packages/gsd-agent-core/dist/fallback-resolver.d.ts +75 -0
  333. package/packages/gsd-agent-core/dist/fallback-resolver.d.ts.map +1 -0
  334. package/packages/gsd-agent-core/dist/fallback-resolver.js +118 -0
  335. package/packages/gsd-agent-core/dist/fallback-resolver.js.map +1 -0
  336. package/packages/gsd-agent-core/dist/image-overflow-recovery.d.ts +44 -0
  337. package/packages/gsd-agent-core/dist/image-overflow-recovery.d.ts.map +1 -0
  338. package/packages/gsd-agent-core/dist/image-overflow-recovery.js +99 -0
  339. package/packages/gsd-agent-core/dist/image-overflow-recovery.js.map +1 -0
  340. package/packages/gsd-agent-core/dist/index.d.ts +14 -0
  341. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -0
  342. package/packages/gsd-agent-core/dist/index.js +19 -0
  343. package/packages/gsd-agent-core/dist/index.js.map +1 -0
  344. package/packages/gsd-agent-core/dist/keybindings.d.ts +47 -0
  345. package/packages/gsd-agent-core/dist/keybindings.d.ts.map +1 -0
  346. package/packages/gsd-agent-core/dist/keybindings.js +156 -0
  347. package/packages/gsd-agent-core/dist/keybindings.js.map +1 -0
  348. package/packages/gsd-agent-core/dist/lifecycle-hooks.d.ts +42 -0
  349. package/packages/gsd-agent-core/dist/lifecycle-hooks.d.ts.map +1 -0
  350. package/packages/gsd-agent-core/dist/lifecycle-hooks.js +204 -0
  351. package/packages/gsd-agent-core/dist/lifecycle-hooks.js.map +1 -0
  352. package/packages/gsd-agent-core/dist/retry-handler.d.ts +128 -0
  353. package/packages/gsd-agent-core/dist/retry-handler.d.ts.map +1 -0
  354. package/packages/gsd-agent-core/dist/retry-handler.js +518 -0
  355. package/packages/gsd-agent-core/dist/retry-handler.js.map +1 -0
  356. package/packages/gsd-agent-core/dist/sdk.d.ts +159 -0
  357. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -0
  358. package/packages/gsd-agent-core/dist/sdk.js +375 -0
  359. package/packages/gsd-agent-core/dist/sdk.js.map +1 -0
  360. package/packages/gsd-agent-core/dist/system-prompt.d.ts +28 -0
  361. package/packages/gsd-agent-core/dist/system-prompt.d.ts.map +1 -0
  362. package/packages/gsd-agent-core/dist/system-prompt.js +201 -0
  363. package/packages/gsd-agent-core/dist/system-prompt.js.map +1 -0
  364. package/packages/gsd-agent-core/package.json +25 -0
  365. package/packages/gsd-agent-core/scripts/copy-assets.cjs +43 -0
  366. package/packages/gsd-agent-core/src/agent-session.test.ts +169 -0
  367. package/packages/gsd-agent-core/src/agent-session.ts +3358 -0
  368. package/packages/gsd-agent-core/src/artifact-manager.ts +126 -0
  369. package/packages/gsd-agent-core/src/bash-executor.ts +352 -0
  370. package/packages/gsd-agent-core/src/blob-store.ts +154 -0
  371. package/packages/gsd-agent-core/src/compaction/branch-summarization.ts +317 -0
  372. package/packages/gsd-agent-core/src/compaction/compaction.ts +855 -0
  373. package/packages/gsd-agent-core/src/compaction/index.ts +7 -0
  374. package/packages/gsd-agent-core/src/compaction/utils.ts +312 -0
  375. package/packages/gsd-agent-core/src/compaction-orchestrator.ts +449 -0
  376. package/packages/gsd-agent-core/src/contextual-tips.ts +232 -0
  377. package/packages/gsd-agent-core/src/export-html/ansi-to-html.ts +259 -0
  378. package/packages/gsd-agent-core/src/export-html/index.ts +345 -0
  379. package/packages/gsd-agent-core/src/export-html/template.css +971 -0
  380. package/packages/gsd-agent-core/src/export-html/template.html +54 -0
  381. package/packages/gsd-agent-core/src/export-html/template.js +1583 -0
  382. package/packages/gsd-agent-core/src/export-html/tool-renderer.ts +114 -0
  383. package/packages/gsd-agent-core/src/export-html/vendor/highlight.min.js +1213 -0
  384. package/packages/gsd-agent-core/src/export-html/vendor/marked.min.js +6 -0
  385. package/packages/gsd-agent-core/src/fallback-resolver.ts +193 -0
  386. package/packages/gsd-agent-core/src/image-overflow-recovery.ts +120 -0
  387. package/packages/gsd-agent-core/src/index.ts +68 -0
  388. package/packages/gsd-agent-core/src/keybindings.ts +220 -0
  389. package/packages/gsd-agent-core/src/lifecycle-hooks.ts +284 -0
  390. package/packages/gsd-agent-core/src/retry-handler.ts +620 -0
  391. package/packages/gsd-agent-core/src/sdk.ts +550 -0
  392. package/packages/gsd-agent-core/src/system-prompt.ts +270 -0
  393. package/packages/gsd-agent-core/tsconfig.json +28 -0
  394. package/packages/gsd-agent-core/tsconfig.tsbuildinfo +1 -0
  395. package/packages/gsd-agent-modes/dist/cli/args.d.ts +58 -0
  396. package/packages/gsd-agent-modes/dist/cli/args.d.ts.map +1 -0
  397. package/packages/gsd-agent-modes/dist/cli/args.js +324 -0
  398. package/packages/gsd-agent-modes/dist/cli/args.js.map +1 -0
  399. package/packages/gsd-agent-modes/dist/cli/config-selector.d.ts +13 -0
  400. package/packages/gsd-agent-modes/dist/cli/config-selector.d.ts.map +1 -0
  401. package/packages/gsd-agent-modes/dist/cli/config-selector.js +32 -0
  402. package/packages/gsd-agent-modes/dist/cli/config-selector.js.map +1 -0
  403. package/packages/gsd-agent-modes/dist/cli/file-processor.d.ts +15 -0
  404. package/packages/gsd-agent-modes/dist/cli/file-processor.d.ts.map +1 -0
  405. package/packages/gsd-agent-modes/dist/cli/file-processor.js +86 -0
  406. package/packages/gsd-agent-modes/dist/cli/file-processor.js.map +1 -0
  407. package/packages/gsd-agent-modes/dist/cli/list-models.d.ts +21 -0
  408. package/packages/gsd-agent-modes/dist/cli/list-models.d.ts.map +1 -0
  409. package/packages/gsd-agent-modes/dist/cli/list-models.js +114 -0
  410. package/packages/gsd-agent-modes/dist/cli/list-models.js.map +1 -0
  411. package/packages/gsd-agent-modes/dist/cli/session-picker.d.ts +10 -0
  412. package/packages/gsd-agent-modes/dist/cli/session-picker.d.ts.map +1 -0
  413. package/packages/gsd-agent-modes/dist/cli/session-picker.js +37 -0
  414. package/packages/gsd-agent-modes/dist/cli/session-picker.js.map +1 -0
  415. package/packages/gsd-agent-modes/dist/index.d.ts +7 -0
  416. package/packages/gsd-agent-modes/dist/index.d.ts.map +1 -0
  417. package/packages/gsd-agent-modes/dist/index.js +7 -0
  418. package/packages/gsd-agent-modes/dist/index.js.map +1 -0
  419. package/packages/gsd-agent-modes/dist/main.d.ts +8 -0
  420. package/packages/gsd-agent-modes/dist/main.d.ts.map +1 -0
  421. package/packages/gsd-agent-modes/dist/main.js +491 -0
  422. package/packages/gsd-agent-modes/dist/main.js.map +1 -0
  423. package/packages/gsd-agent-modes/dist/modes/interactive/components/armin.d.ts +34 -0
  424. package/packages/gsd-agent-modes/dist/modes/interactive/components/armin.d.ts.map +1 -0
  425. package/packages/gsd-agent-modes/dist/modes/interactive/components/armin.js +330 -0
  426. package/packages/gsd-agent-modes/dist/modes/interactive/components/armin.js.map +1 -0
  427. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts +29 -0
  428. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  429. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +141 -0
  430. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -0
  431. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.d.ts +36 -0
  432. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  433. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js +157 -0
  434. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js.map +1 -0
  435. package/packages/gsd-agent-modes/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  436. package/packages/gsd-agent-modes/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  437. package/packages/gsd-agent-modes/dist/modes/interactive/components/bordered-loader.js +48 -0
  438. package/packages/gsd-agent-modes/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  439. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  440. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  441. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js +43 -0
  442. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  443. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  444. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  445. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-frame.js +47 -0
  446. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-frame.js.map +1 -0
  447. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  448. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  449. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js +44 -0
  450. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  451. package/packages/gsd-agent-modes/dist/modes/interactive/components/config-selector.d.ts +71 -0
  452. package/packages/gsd-agent-modes/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  453. package/packages/gsd-agent-modes/dist/modes/interactive/components/config-selector.js +474 -0
  454. package/packages/gsd-agent-modes/dist/modes/interactive/components/config-selector.js.map +1 -0
  455. package/packages/gsd-agent-modes/dist/modes/interactive/components/countdown-timer.d.ts +15 -0
  456. package/packages/gsd-agent-modes/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  457. package/packages/gsd-agent-modes/dist/modes/interactive/components/countdown-timer.js +32 -0
  458. package/packages/gsd-agent-modes/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  459. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts +22 -0
  460. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  461. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js +70 -0
  462. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js.map +1 -0
  463. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-message.d.ts +20 -0
  464. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  465. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-message.js +75 -0
  466. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-message.js.map +1 -0
  467. package/packages/gsd-agent-modes/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  468. package/packages/gsd-agent-modes/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  469. package/packages/gsd-agent-modes/dist/modes/interactive/components/daxnuts.js +140 -0
  470. package/packages/gsd-agent-modes/dist/modes/interactive/components/daxnuts.js.map +1 -0
  471. package/packages/gsd-agent-modes/dist/modes/interactive/components/diff.d.ts +12 -0
  472. package/packages/gsd-agent-modes/dist/modes/interactive/components/diff.d.ts.map +1 -0
  473. package/packages/gsd-agent-modes/dist/modes/interactive/components/diff.js +133 -0
  474. package/packages/gsd-agent-modes/dist/modes/interactive/components/diff.js.map +1 -0
  475. package/packages/gsd-agent-modes/dist/modes/interactive/components/dynamic-border.d.ts +33 -0
  476. package/packages/gsd-agent-modes/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  477. package/packages/gsd-agent-modes/dist/modes/interactive/components/dynamic-border.js +82 -0
  478. package/packages/gsd-agent-modes/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  479. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  480. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  481. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +111 -0
  482. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -0
  483. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +24 -0
  484. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  485. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +63 -0
  486. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -0
  487. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +33 -0
  488. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  489. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +118 -0
  490. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -0
  491. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts +32 -0
  492. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts.map +1 -0
  493. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js +230 -0
  494. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js.map +1 -0
  495. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +34 -0
  496. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -0
  497. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +36 -0
  498. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -0
  499. package/packages/gsd-agent-modes/dist/modes/interactive/components/keybinding-hints.d.ts +48 -0
  500. package/packages/gsd-agent-modes/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  501. package/packages/gsd-agent-modes/dist/modes/interactive/components/keybinding-hints.js +72 -0
  502. package/packages/gsd-agent-modes/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  503. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +63 -0
  504. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  505. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +213 -0
  506. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -0
  507. package/packages/gsd-agent-modes/dist/modes/interactive/components/model-selector.d.ts +86 -0
  508. package/packages/gsd-agent-modes/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  509. package/packages/gsd-agent-modes/dist/modes/interactive/components/model-selector.js +536 -0
  510. package/packages/gsd-agent-modes/dist/modes/interactive/components/model-selector.js.map +1 -0
  511. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
  512. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  513. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +93 -0
  514. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  515. package/packages/gsd-agent-modes/dist/modes/interactive/components/provider-manager.d.ts +30 -0
  516. package/packages/gsd-agent-modes/dist/modes/interactive/components/provider-manager.d.ts.map +1 -0
  517. package/packages/gsd-agent-modes/dist/modes/interactive/components/provider-manager.js +169 -0
  518. package/packages/gsd-agent-modes/dist/modes/interactive/components/provider-manager.js.map +1 -0
  519. package/packages/gsd-agent-modes/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
  520. package/packages/gsd-agent-modes/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  521. package/packages/gsd-agent-modes/dist/modes/interactive/components/scoped-models-selector.js +267 -0
  522. package/packages/gsd-agent-modes/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  523. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector-search.d.ts +21 -0
  524. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  525. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector-search.js +155 -0
  526. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  527. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector.d.ts +97 -0
  528. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  529. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector.js +810 -0
  530. package/packages/gsd-agent-modes/dist/modes/interactive/components/session-selector.js.map +1 -0
  531. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +71 -0
  532. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  533. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +320 -0
  534. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -0
  535. package/packages/gsd-agent-modes/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  536. package/packages/gsd-agent-modes/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  537. package/packages/gsd-agent-modes/dist/modes/interactive/components/show-images-selector.js +34 -0
  538. package/packages/gsd-agent-modes/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  539. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  540. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  541. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js +46 -0
  542. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  543. package/packages/gsd-agent-modes/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  544. package/packages/gsd-agent-modes/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  545. package/packages/gsd-agent-modes/dist/modes/interactive/components/theme-selector.js +45 -0
  546. package/packages/gsd-agent-modes/dist/modes/interactive/components/theme-selector.js.map +1 -0
  547. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  548. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  549. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js +46 -0
  550. package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  551. package/packages/gsd-agent-modes/dist/modes/interactive/components/timestamp.d.ts +15 -0
  552. package/packages/gsd-agent-modes/dist/modes/interactive/components/timestamp.d.ts.map +1 -0
  553. package/packages/gsd-agent-modes/dist/modes/interactive/components/timestamp.js +40 -0
  554. package/packages/gsd-agent-modes/dist/modes/interactive/components/timestamp.js.map +1 -0
  555. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +111 -0
  556. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  557. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +984 -0
  558. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -0
  559. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  560. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  561. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-render-utils.js +61 -0
  562. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  563. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-selector.d.ts +109 -0
  564. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  565. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-selector.js +1035 -0
  566. package/packages/gsd-agent-modes/dist/modes/interactive/components/tree-selector.js.map +1 -0
  567. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  568. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  569. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message-selector.js +112 -0
  570. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  571. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts +12 -0
  572. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  573. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js +38 -0
  574. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js.map +1 -0
  575. package/packages/gsd-agent-modes/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  576. package/packages/gsd-agent-modes/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  577. package/packages/gsd-agent-modes/dist/modes/interactive/components/visual-truncate.js +33 -0
  578. package/packages/gsd-agent-modes/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  579. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +27 -0
  580. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -0
  581. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +793 -0
  582. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -0
  583. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.d.ts +4 -0
  584. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -0
  585. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js +62 -0
  586. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -0
  587. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts +22 -0
  588. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -0
  589. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +118 -0
  590. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -0
  591. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/model-controller.d.ts +7 -0
  592. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -0
  593. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/model-controller.js +68 -0
  594. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/model-controller.js.map +1 -0
  595. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +50 -0
  596. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -0
  597. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +2 -0
  598. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -0
  599. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +358 -0
  600. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  601. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +3409 -0
  602. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -0
  603. package/packages/gsd-agent-modes/dist/modes/interactive/slash-command-handlers.d.ts +77 -0
  604. package/packages/gsd-agent-modes/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  605. package/packages/gsd-agent-modes/dist/modes/interactive/slash-command-handlers.js +529 -0
  606. package/packages/gsd-agent-modes/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  607. package/packages/gsd-agent-modes/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  608. package/packages/gsd-agent-modes/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  609. package/packages/gsd-agent-modes/dist/modes/interactive/utils/shorten-path.js +15 -0
  610. package/packages/gsd-agent-modes/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  611. package/packages/gsd-agent-modes/dist/modes/print-mode.d.ts +28 -0
  612. package/packages/gsd-agent-modes/dist/modes/print-mode.d.ts.map +1 -0
  613. package/packages/gsd-agent-modes/dist/modes/print-mode.js +84 -0
  614. package/packages/gsd-agent-modes/dist/modes/print-mode.js.map +1 -0
  615. package/packages/gsd-agent-modes/dist/modes/rpc/jsonl.d.ts +17 -0
  616. package/packages/gsd-agent-modes/dist/modes/rpc/jsonl.d.ts.map +1 -0
  617. package/packages/gsd-agent-modes/dist/modes/rpc/jsonl.js +49 -0
  618. package/packages/gsd-agent-modes/dist/modes/rpc/jsonl.js.map +1 -0
  619. package/packages/gsd-agent-modes/dist/modes/rpc/remote-terminal.d.ts +37 -0
  620. package/packages/gsd-agent-modes/dist/modes/rpc/remote-terminal.d.ts.map +1 -0
  621. package/packages/gsd-agent-modes/dist/modes/rpc/remote-terminal.js +84 -0
  622. package/packages/gsd-agent-modes/dist/modes/rpc/remote-terminal.js.map +1 -0
  623. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +243 -0
  624. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  625. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +464 -0
  626. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -0
  627. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts +25 -0
  628. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  629. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +750 -0
  630. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -0
  631. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-types.d.ts +511 -0
  632. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  633. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-types.js +8 -0
  634. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-types.js.map +1 -0
  635. package/packages/gsd-agent-modes/dist/modes/shared/command-context-actions.d.ts +19 -0
  636. package/packages/gsd-agent-modes/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  637. package/packages/gsd-agent-modes/dist/modes/shared/command-context-actions.js +45 -0
  638. package/packages/gsd-agent-modes/dist/modes/shared/command-context-actions.js.map +1 -0
  639. package/packages/gsd-agent-modes/dist/pi-coding-agent-compat.d.ts +22 -0
  640. package/packages/gsd-agent-modes/dist/pi-coding-agent-compat.d.ts.map +1 -0
  641. package/packages/gsd-agent-modes/dist/pi-coding-agent-compat.js +21 -0
  642. package/packages/gsd-agent-modes/dist/pi-coding-agent-compat.js.map +1 -0
  643. package/packages/gsd-agent-modes/dist/pi-tui-compat.d.ts +4 -0
  644. package/packages/gsd-agent-modes/dist/pi-tui-compat.d.ts.map +1 -0
  645. package/packages/gsd-agent-modes/dist/pi-tui-compat.js +3 -0
  646. package/packages/gsd-agent-modes/dist/pi-tui-compat.js.map +1 -0
  647. package/packages/gsd-agent-modes/dist/theme.d.ts +15 -0
  648. package/packages/gsd-agent-modes/dist/theme.d.ts.map +1 -0
  649. package/packages/gsd-agent-modes/dist/theme.js +23 -0
  650. package/packages/gsd-agent-modes/dist/theme.js.map +1 -0
  651. package/packages/gsd-agent-modes/dist/utils/theme.d.ts +16 -0
  652. package/packages/gsd-agent-modes/dist/utils/theme.d.ts.map +1 -0
  653. package/packages/gsd-agent-modes/dist/utils/theme.js +11 -0
  654. package/packages/gsd-agent-modes/dist/utils/theme.js.map +1 -0
  655. package/packages/gsd-agent-modes/package.json +23 -0
  656. package/packages/gsd-agent-modes/src/cli/args.ts +350 -0
  657. package/packages/gsd-agent-modes/src/cli/config-selector.ts +54 -0
  658. package/packages/gsd-agent-modes/src/cli/file-processor.ts +107 -0
  659. package/packages/gsd-agent-modes/src/cli/list-models.ts +141 -0
  660. package/packages/gsd-agent-modes/src/cli/session-picker.ts +59 -0
  661. package/packages/gsd-agent-modes/src/index.ts +6 -0
  662. package/packages/gsd-agent-modes/src/main.ts +614 -0
  663. package/packages/gsd-agent-modes/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
  664. package/packages/gsd-agent-modes/src/modes/interactive/components/__tests__/provider-display-name.test.ts +18 -0
  665. package/packages/gsd-agent-modes/src/modes/interactive/components/__tests__/timestamp.test.ts +38 -0
  666. package/packages/gsd-agent-modes/src/modes/interactive/components/__tests__/tool-execution.test.ts +171 -0
  667. package/packages/gsd-agent-modes/src/modes/interactive/components/armin.ts +382 -0
  668. package/packages/gsd-agent-modes/src/modes/interactive/components/assistant-message.ts +178 -0
  669. package/packages/gsd-agent-modes/src/modes/interactive/components/bash-execution.ts +212 -0
  670. package/packages/gsd-agent-modes/src/modes/interactive/components/bordered-loader.ts +66 -0
  671. package/packages/gsd-agent-modes/src/modes/interactive/components/branch-summary-message.ts +59 -0
  672. package/packages/gsd-agent-modes/src/modes/interactive/components/chat-frame.ts +67 -0
  673. package/packages/gsd-agent-modes/src/modes/interactive/components/compaction-summary-message.ts +60 -0
  674. package/packages/gsd-agent-modes/src/modes/interactive/components/config-selector.ts +597 -0
  675. package/packages/gsd-agent-modes/src/modes/interactive/components/countdown-timer.ts +41 -0
  676. package/packages/gsd-agent-modes/src/modes/interactive/components/custom-editor.ts +88 -0
  677. package/packages/gsd-agent-modes/src/modes/interactive/components/custom-message.ts +100 -0
  678. package/packages/gsd-agent-modes/src/modes/interactive/components/daxnuts.ts +165 -0
  679. package/packages/gsd-agent-modes/src/modes/interactive/components/diff.ts +147 -0
  680. package/packages/gsd-agent-modes/src/modes/interactive/components/dynamic-border.test.ts +73 -0
  681. package/packages/gsd-agent-modes/src/modes/interactive/components/dynamic-border.ts +89 -0
  682. package/packages/gsd-agent-modes/src/modes/interactive/components/extension-editor.ts +151 -0
  683. package/packages/gsd-agent-modes/src/modes/interactive/components/extension-input.ts +100 -0
  684. package/packages/gsd-agent-modes/src/modes/interactive/components/extension-selector.ts +156 -0
  685. package/packages/gsd-agent-modes/src/modes/interactive/components/footer.ts +257 -0
  686. package/packages/gsd-agent-modes/src/modes/interactive/components/index.ts +35 -0
  687. package/packages/gsd-agent-modes/src/modes/interactive/components/keybinding-hints.ts +84 -0
  688. package/packages/gsd-agent-modes/src/modes/interactive/components/login-dialog.ts +257 -0
  689. package/packages/gsd-agent-modes/src/modes/interactive/components/model-selector.ts +656 -0
  690. package/packages/gsd-agent-modes/src/modes/interactive/components/oauth-selector.ts +122 -0
  691. package/packages/gsd-agent-modes/src/modes/interactive/components/provider-manager.ts +210 -0
  692. package/packages/gsd-agent-modes/src/modes/interactive/components/scoped-models-selector.ts +342 -0
  693. package/packages/gsd-agent-modes/src/modes/interactive/components/session-selector-search.ts +194 -0
  694. package/packages/gsd-agent-modes/src/modes/interactive/components/session-selector.ts +1011 -0
  695. package/packages/gsd-agent-modes/src/modes/interactive/components/settings-selector.ts +452 -0
  696. package/packages/gsd-agent-modes/src/modes/interactive/components/show-images-selector.ts +45 -0
  697. package/packages/gsd-agent-modes/src/modes/interactive/components/skill-invocation-message.ts +56 -0
  698. package/packages/gsd-agent-modes/src/modes/interactive/components/theme-selector.ts +63 -0
  699. package/packages/gsd-agent-modes/src/modes/interactive/components/thinking-selector.ts +64 -0
  700. package/packages/gsd-agent-modes/src/modes/interactive/components/timestamp.ts +48 -0
  701. package/packages/gsd-agent-modes/src/modes/interactive/components/tool-execution.ts +1157 -0
  702. package/packages/gsd-agent-modes/src/modes/interactive/components/tree-render-utils.ts +81 -0
  703. package/packages/gsd-agent-modes/src/modes/interactive/components/tree-selector.ts +1208 -0
  704. package/packages/gsd-agent-modes/src/modes/interactive/components/user-message-selector.ts +145 -0
  705. package/packages/gsd-agent-modes/src/modes/interactive/components/user-message.ts +44 -0
  706. package/packages/gsd-agent-modes/src/modes/interactive/components/visual-truncate.ts +50 -0
  707. package/packages/gsd-agent-modes/src/modes/interactive/controllers/chat-controller-ordering.test.ts +1430 -0
  708. package/packages/gsd-agent-modes/src/modes/interactive/controllers/chat-controller.test.ts +71 -0
  709. package/packages/gsd-agent-modes/src/modes/interactive/controllers/chat-controller.ts +957 -0
  710. package/packages/gsd-agent-modes/src/modes/interactive/controllers/extension-ui-controller.ts +63 -0
  711. package/packages/gsd-agent-modes/src/modes/interactive/controllers/input-controller.test.ts +183 -0
  712. package/packages/gsd-agent-modes/src/modes/interactive/controllers/input-controller.ts +140 -0
  713. package/packages/gsd-agent-modes/src/modes/interactive/controllers/model-controller.ts +77 -0
  714. package/packages/gsd-agent-modes/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  715. package/packages/gsd-agent-modes/src/modes/interactive/interactive-mode-state.ts +49 -0
  716. package/packages/gsd-agent-modes/src/modes/interactive/interactive-mode.ts +4195 -0
  717. package/packages/gsd-agent-modes/src/modes/interactive/slash-command-handlers.ts +670 -0
  718. package/packages/gsd-agent-modes/src/modes/interactive/utils/shorten-path.ts +14 -0
  719. package/packages/gsd-agent-modes/src/modes/print-mode.ts +106 -0
  720. package/packages/gsd-agent-modes/src/modes/rpc/jsonl.ts +58 -0
  721. package/packages/gsd-agent-modes/src/modes/rpc/remote-terminal.ts +109 -0
  722. package/packages/gsd-agent-modes/src/modes/rpc/rpc-client.ts +572 -0
  723. package/packages/gsd-agent-modes/src/modes/rpc/rpc-mode.ts +902 -0
  724. package/packages/gsd-agent-modes/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  725. package/packages/gsd-agent-modes/src/modes/rpc/rpc-types.ts +335 -0
  726. package/packages/gsd-agent-modes/src/modes/shared/command-context-actions.ts +53 -0
  727. package/packages/gsd-agent-modes/src/pi-coding-agent-compat.ts +42 -0
  728. package/packages/gsd-agent-modes/src/pi-tui-compat.ts +4 -0
  729. package/packages/gsd-agent-modes/src/theme.ts +25 -0
  730. package/packages/gsd-agent-modes/src/utils/theme.ts +24 -0
  731. package/packages/gsd-agent-modes/tsconfig.json +28 -0
  732. package/packages/gsd-agent-modes/tsconfig.tsbuildinfo +1 -0
  733. package/packages/gsd-agent-types/dist/index.d.ts +176 -0
  734. package/packages/gsd-agent-types/dist/index.d.ts.map +1 -0
  735. package/packages/gsd-agent-types/dist/index.js +24 -0
  736. package/packages/gsd-agent-types/dist/index.js.map +1 -0
  737. package/packages/gsd-agent-types/package.json +24 -0
  738. package/packages/gsd-agent-types/src/index.ts +206 -0
  739. package/packages/gsd-agent-types/tsconfig.json +25 -0
  740. package/packages/gsd-agent-types/tsconfig.tsbuildinfo +1 -0
  741. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  742. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  743. package/packages/mcp-server/dist/remote-questions.js +732 -0
  744. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  745. package/packages/mcp-server/dist/server.d.ts +7 -0
  746. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  747. package/packages/mcp-server/dist/server.js +77 -11
  748. package/packages/mcp-server/dist/server.js.map +1 -1
  749. package/packages/mcp-server/dist/session-manager.d.ts +14 -0
  750. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  751. package/packages/mcp-server/dist/session-manager.js +49 -1
  752. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  753. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
  754. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  755. package/packages/mcp-server/dist/workflow-tools.js +163 -25
  756. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  757. package/packages/mcp-server/package.json +4 -3
  758. package/packages/mcp-server/src/mcp-server.test.ts +67 -0
  759. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  760. package/packages/mcp-server/src/remote-questions.ts +916 -0
  761. package/packages/mcp-server/src/server.ts +94 -18
  762. package/packages/mcp-server/src/session-manager.ts +43 -1
  763. package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
  764. package/packages/mcp-server/src/workflow-tools.ts +215 -43
  765. package/packages/mcp-server/tsconfig.test.json +19 -0
  766. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  767. package/packages/native/dist/tsconfig.tsbuildinfo +1 -0
  768. package/packages/native/package.json +1 -1
  769. package/packages/native/tsconfig.json +2 -1
  770. package/packages/pi-agent-core/dist/agent-loop.js +12 -0
  771. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  772. package/packages/pi-agent-core/dist/types.d.ts +30 -0
  773. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  774. package/packages/pi-agent-core/dist/types.js.map +1 -1
  775. package/packages/pi-agent-core/package.json +1 -1
  776. package/packages/pi-agent-core/src/agent-loop.ts +14 -0
  777. package/packages/pi-agent-core/src/types.ts +34 -0
  778. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  779. package/packages/pi-ai/dist/models/custom.d.ts +38 -0
  780. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
  781. package/packages/pi-ai/dist/models/custom.js +41 -0
  782. package/packages/pi-ai/dist/models/custom.js.map +1 -1
  783. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  784. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  785. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
  786. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
  787. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
  788. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
  789. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  790. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  791. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  792. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  793. package/packages/pi-ai/dist/providers/anthropic.js +13 -4
  794. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  795. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  796. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  797. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  798. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  799. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  800. package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
  801. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  802. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  803. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  804. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  805. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  806. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
  807. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
  808. package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
  809. package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
  810. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
  811. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
  812. package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
  813. package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
  814. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  815. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
  816. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  817. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
  818. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  819. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  820. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
  821. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  822. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
  823. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
  824. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
  825. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
  826. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  827. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
  828. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  829. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
  830. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
  831. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
  832. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
  833. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
  834. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
  835. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
  836. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
  837. package/packages/pi-ai/package.json +1 -1
  838. package/packages/pi-ai/src/models/custom.ts +42 -0
  839. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  840. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
  841. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  842. package/packages/pi-ai/src/providers/anthropic.ts +15 -4
  843. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  844. package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
  845. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  846. package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
  847. package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
  848. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
  849. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
  850. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
  851. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
  852. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
  853. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
  854. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
  855. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  856. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
  857. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  858. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
  859. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  860. package/packages/pi-coding-agent/dist/core/agent-session.js +32 -2
  861. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  862. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  863. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  864. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  865. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  866. package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
  867. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  868. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
  869. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  870. package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
  871. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  872. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +205 -2
  873. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  874. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  875. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
  876. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
  877. package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
  878. package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
  879. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
  880. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
  881. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
  882. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
  883. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  884. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  885. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  886. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  887. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
  888. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
  889. package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
  890. package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
  891. package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
  892. package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
  893. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
  894. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
  895. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
  896. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
  897. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  898. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  899. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  900. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  901. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
  902. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
  903. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
  904. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  905. package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
  906. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  907. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
  908. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
  909. package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
  910. package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
  911. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
  912. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
  913. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
  914. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
  915. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  916. package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
  917. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  918. package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
  919. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  920. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
  921. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  922. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  923. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  924. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  925. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  926. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
  927. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  928. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
  929. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  930. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  931. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
  932. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  933. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
  934. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  935. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
  936. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  937. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  938. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  939. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  940. package/packages/pi-coding-agent/package.json +1 -1
  941. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
  942. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
  943. package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
  944. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  945. package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
  946. package/packages/pi-coding-agent/src/core/extensions/types.ts +258 -0
  947. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
  948. package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
  949. package/packages/pi-coding-agent/src/core/index.ts +10 -0
  950. package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
  951. package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
  952. package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
  953. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  954. package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
  955. package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
  956. package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
  957. package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
  958. package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
  959. package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
  960. package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
  961. package/packages/pi-coding-agent/src/index.ts +16 -0
  962. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
  963. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
  964. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
  965. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  966. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  967. package/packages/pi-tui/package.json +1 -1
  968. package/packages/rpc-client/package.json +1 -1
  969. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  970. package/pkg/dist/core/export-html/ansi-to-html.js +1 -0
  971. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  972. package/pkg/dist/core/export-html/index.d.ts +1 -1
  973. package/pkg/dist/core/export-html/index.d.ts.map +1 -1
  974. package/pkg/dist/core/export-html/index.js +39 -5
  975. package/pkg/dist/core/export-html/index.js.map +1 -1
  976. package/pkg/dist/core/export-html/tool-renderer.d.ts +2 -2
  977. package/pkg/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  978. package/pkg/dist/core/export-html/tool-renderer.js.map +1 -1
  979. package/pkg/package.json +1 -1
  980. package/scripts/ensure-workspace-builds.cjs +2 -0
  981. package/scripts/install.js +512 -0
  982. package/scripts/link-workspace-packages.cjs +3 -0
  983. package/scripts/postinstall.js +9 -178
  984. package/src/resources/agents/researcher.md +1 -1
  985. package/src/resources/extensions/async-jobs/async-bash-tool.ts +1 -1
  986. package/src/resources/extensions/aws-auth/index.ts +2 -1
  987. package/src/resources/extensions/bg-shell/bg-shell-lifecycle.ts +4 -7
  988. package/src/resources/extensions/bg-shell/index.ts +2 -1
  989. package/src/resources/extensions/bg-shell/process-manager.ts +2 -1
  990. package/src/resources/extensions/browser-tools/index.ts +2 -1
  991. package/src/resources/extensions/claude-code-cli/index.ts +1 -1
  992. package/src/resources/extensions/claude-code-cli/partial-builder.ts +115 -23
  993. package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
  994. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +97 -26
  995. package/src/resources/extensions/claude-code-cli/tests/provider-registration.test.ts +27 -0
  996. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +176 -8
  997. package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -0
  998. package/src/resources/extensions/gsd/auto/loop.ts +9 -0
  999. package/src/resources/extensions/gsd/auto/phases.ts +131 -10
  1000. package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
  1001. package/src/resources/extensions/gsd/auto/session.ts +35 -2
  1002. package/src/resources/extensions/gsd/auto-dispatch.ts +59 -16
  1003. package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
  1004. package/src/resources/extensions/gsd/auto-post-unit.ts +62 -3
  1005. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  1006. package/src/resources/extensions/gsd/auto-recovery.ts +62 -1
  1007. package/src/resources/extensions/gsd/auto-start.ts +80 -74
  1008. package/src/resources/extensions/gsd/auto-verification.ts +33 -0
  1009. package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
  1010. package/src/resources/extensions/gsd/auto.ts +73 -28
  1011. package/src/resources/extensions/gsd/blocked-models.ts +98 -0
  1012. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
  1013. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
  1014. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
  1015. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
  1016. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
  1017. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
  1018. package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -26
  1019. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  1020. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  1021. package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
  1022. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  1023. package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
  1024. package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
  1025. package/src/resources/extensions/gsd/db-writer.ts +88 -17
  1026. package/src/resources/extensions/gsd/dispatch-guard.ts +44 -2
  1027. package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
  1028. package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
  1029. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
  1030. package/src/resources/extensions/gsd/error-classifier.ts +36 -3
  1031. package/src/resources/extensions/gsd/exec-history.ts +153 -0
  1032. package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
  1033. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  1034. package/src/resources/extensions/gsd/gsd-db.ts +186 -23
  1035. package/src/resources/extensions/gsd/guided-flow.ts +223 -2
  1036. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  1037. package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
  1038. package/src/resources/extensions/gsd/init-wizard.ts +15 -1
  1039. package/src/resources/extensions/gsd/journal.ts +2 -1
  1040. package/src/resources/extensions/gsd/key-manager.ts +28 -0
  1041. package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
  1042. package/src/resources/extensions/gsd/memory-store.ts +26 -0
  1043. package/src/resources/extensions/gsd/model-router.ts +42 -1
  1044. package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
  1045. package/src/resources/extensions/gsd/preferences-types.ts +46 -0
  1046. package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
  1047. package/src/resources/extensions/gsd/preferences.ts +17 -17
  1048. package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
  1049. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  1050. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  1051. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  1052. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  1053. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  1054. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  1055. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  1056. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  1057. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
  1058. package/src/resources/extensions/gsd/prompts/system.md +1 -0
  1059. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  1060. package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
  1061. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  1062. package/src/resources/extensions/gsd/state.ts +45 -4
  1063. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
  1064. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
  1065. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  1066. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
  1067. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
  1068. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
  1069. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
  1070. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
  1071. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
  1072. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
  1073. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
  1074. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  1075. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
  1076. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
  1077. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
  1078. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
  1079. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  1080. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  1081. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
  1082. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  1083. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
  1084. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
  1085. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +9 -9
  1086. package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
  1087. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
  1088. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  1089. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
  1090. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  1091. package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
  1092. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
  1093. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
  1094. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
  1095. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
  1096. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
  1097. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
  1098. package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
  1099. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
  1100. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
  1101. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
  1102. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
  1103. package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
  1104. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
  1105. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
  1106. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  1107. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
  1108. package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
  1109. package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
  1110. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  1111. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
  1112. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  1113. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
  1114. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  1115. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
  1116. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
  1117. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  1118. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
  1119. package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
  1120. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  1121. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
  1122. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
  1123. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  1124. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  1125. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
  1126. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  1127. package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
  1128. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
  1129. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  1130. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  1131. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  1132. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  1133. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
  1134. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +136 -8
  1135. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  1136. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
  1137. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
  1138. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
  1139. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  1140. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
  1141. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  1142. package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
  1143. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
  1144. package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
  1145. package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
  1146. package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
  1147. package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
  1148. package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
  1149. package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
  1150. package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  1151. package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
  1152. package/src/resources/extensions/mcp-client/index.ts +1 -1
  1153. package/src/resources/extensions/ollama/index.ts +3 -3
  1154. package/src/resources/extensions/ollama/ollama-chat-provider.ts +6 -18
  1155. package/src/resources/extensions/remote-questions/config.ts +15 -4
  1156. package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
  1157. package/src/resources/extensions/search-the-web/index.ts +2 -1
  1158. package/src/resources/extensions/search-the-web/native-search.ts +48 -12
  1159. package/src/resources/extensions/shared/tests/format-utils.test.ts +5 -3
  1160. package/src/resources/extensions/universal-config/index.ts +1 -1
  1161. package/src/resources/skills/api-design/SKILL.md +190 -0
  1162. package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
  1163. package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
  1164. package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
  1165. package/src/resources/skills/design-an-interface/SKILL.md +102 -0
  1166. package/src/resources/skills/forensics/SKILL.md +153 -0
  1167. package/src/resources/skills/grill-me/SKILL.md +93 -0
  1168. package/src/resources/skills/handoff/SKILL.md +121 -0
  1169. package/src/resources/skills/observability/SKILL.md +174 -0
  1170. package/src/resources/skills/security-review/SKILL.md +181 -0
  1171. package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
  1172. package/src/resources/skills/tdd/SKILL.md +112 -0
  1173. package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
  1174. package/src/resources/skills/write-docs/SKILL.md +82 -0
  1175. package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
  1176. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
  1177. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  1178. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  1179. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  1180. package/packages/native/tsconfig.tsbuildinfo +0 -1
  1181. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → gy6_foLMsEzdGBT19c3hr}/_buildManifest.js +0 -0
  1182. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → gy6_foLMsEzdGBT19c3hr}/_ssgManifest.js +0 -0
@@ -0,0 +1,1430 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { handleAgentEvent } from "./chat-controller.js";
5
+
6
+ function makeUsage() {
7
+ return {
8
+ input: 0,
9
+ output: 0,
10
+ cacheRead: 0,
11
+ cacheWrite: 0,
12
+ totalTokens: 0,
13
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
14
+ };
15
+ }
16
+
17
+ function makeAssistant(content: any[]) {
18
+ return {
19
+ role: "assistant",
20
+ content,
21
+ api: "anthropic-messages",
22
+ provider: "claude-code",
23
+ model: "claude-sonnet-4",
24
+ usage: makeUsage(),
25
+ stopReason: "stop",
26
+ timestamp: Date.now(),
27
+ };
28
+ }
29
+
30
+ function createHost() {
31
+ const chatContainer = {
32
+ children: [] as any[],
33
+ addChild(component: any) {
34
+ this.children.push(component);
35
+ },
36
+ removeChild(component: any) {
37
+ const idx = this.children.indexOf(component);
38
+ if (idx !== -1) this.children.splice(idx, 1);
39
+ },
40
+ clear() {
41
+ this.children = [];
42
+ },
43
+ };
44
+
45
+ const pinnedMessageContainer = {
46
+ children: [] as any[],
47
+ addChild(component: any) {
48
+ this.children.push(component);
49
+ },
50
+ removeChild(component: any) {
51
+ const idx = this.children.indexOf(component);
52
+ if (idx !== -1) this.children.splice(idx, 1);
53
+ },
54
+ clear() {
55
+ this.children = [];
56
+ },
57
+ };
58
+
59
+ const host: any = {
60
+ isInitialized: true,
61
+ init: async () => {},
62
+ defaultEditor: { onEscape: undefined },
63
+ editor: {},
64
+ session: { retryAttempt: 0, abortCompaction: () => {}, abortRetry: () => {} },
65
+ // rows:1 keeps the pinned-zone off-screen-threshold at its floor (1) so
66
+ // any rendered segment after a pinnable text block triggers the pin.
67
+ // Real terminals are larger; see chat-controller rowsRenderedAfterContentIndex.
68
+ ui: { requestRender: () => {}, terminal: { rows: 1, columns: 80 } },
69
+ footer: { invalidate: () => {} },
70
+ keybindings: {},
71
+ statusContainer: { clear: () => {}, addChild: () => {} },
72
+ chatContainer,
73
+ settingsManager: { getTimestampFormat: () => "date-time-iso", getShowImages: () => false },
74
+ pendingTools: new Map(),
75
+ toolOutputExpanded: false,
76
+ hideThinkingBlock: false,
77
+ isBashMode: false,
78
+ defaultWorkingMessage: "Working...",
79
+ compactionQueuedMessages: [],
80
+ editorContainer: {},
81
+ pendingMessagesContainer: { clear: () => {} },
82
+ pinnedMessageContainer,
83
+ addMessageToChat: () => {},
84
+ getMarkdownThemeWithSettings: () => ({}),
85
+ formatWebSearchResult: () => "",
86
+ getRegisteredToolDefinition: () => undefined,
87
+ checkShutdownRequested: async () => {},
88
+ rebuildChatFromMessages: () => {},
89
+ flushCompactionQueue: async () => {},
90
+ showStatus: () => {},
91
+ showError: () => {},
92
+ updatePendingMessagesDisplay: () => {},
93
+ updateTerminalTitle: () => {},
94
+ updateEditorBorderColor: () => {},
95
+ };
96
+
97
+ return host;
98
+ }
99
+
100
+ test("chat-controller renders content blocks in content[] index order (tool-first stream)", async () => {
101
+ // ToolExecutionComponent uses the global theme singleton.
102
+ // Install a minimal no-op theme implementation for this unit test.
103
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
104
+ fg: (_key: string, text: string) => text,
105
+ bg: (_key: string, text: string) => text,
106
+ bold: (text: string) => text,
107
+ italic: (text: string) => text,
108
+ truncate: (text: string) => text,
109
+ };
110
+
111
+ const host = createHost();
112
+ const toolId = "mcp-tool-1";
113
+ const toolCall = {
114
+ type: "toolCall",
115
+ id: toolId,
116
+ name: "exec_command",
117
+ arguments: { cmd: "echo hi" },
118
+ };
119
+
120
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
121
+
122
+ assert.equal(host.chatContainer.children.length, 0, "nothing should render before content arrives");
123
+
124
+ await handleAgentEvent(
125
+ host,
126
+ {
127
+ type: "message_update",
128
+ message: makeAssistant([toolCall]),
129
+ assistantMessageEvent: {
130
+ type: "toolcall_end",
131
+ contentIndex: 0,
132
+ toolCall: {
133
+ ...toolCall,
134
+ externalResult: {
135
+ content: [{ type: "text", text: "tool output" }],
136
+ details: {},
137
+ isError: false,
138
+ },
139
+ },
140
+ partial: makeAssistant([toolCall]),
141
+ },
142
+ } as any,
143
+ );
144
+
145
+ // content[0] = toolCall → ToolExecutionComponent renders first
146
+ assert.equal(host.chatContainer.children.length, 1, "tool execution block should render immediately");
147
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
148
+
149
+ host.getMarkdownThemeWithSettings = () => ({});
150
+
151
+ await handleAgentEvent(
152
+ host,
153
+ {
154
+ type: "message_update",
155
+ message: makeAssistant([toolCall, { type: "text", text: "done" }]),
156
+ assistantMessageEvent: {
157
+ type: "text_delta",
158
+ contentIndex: 1,
159
+ delta: "done",
160
+ partial: makeAssistant([toolCall, { type: "text", text: "done" }]),
161
+ },
162
+ } as any,
163
+ );
164
+
165
+ // content[0]=toolCall, content[1]=text → order: tool, then text
166
+ assert.equal(host.chatContainer.children.length, 2, "text run should render after tool in content[] order");
167
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
168
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
169
+ });
170
+
171
+ test("chat-controller renders serverToolUse before trailing text matching content[] index order", async () => {
172
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
173
+ fg: (_key: string, text: string) => text,
174
+ bg: (_key: string, text: string) => text,
175
+ bold: (text: string) => text,
176
+ italic: (text: string) => text,
177
+ truncate: (text: string) => text,
178
+ };
179
+
180
+ const host = createHost();
181
+ const toolId = "mcp-secure-1";
182
+ const serverToolUse = {
183
+ type: "serverToolUse",
184
+ id: toolId,
185
+ name: "mcp__gsd-workflow__secure_env_collect",
186
+ input: { projectDir: "/tmp/project", keys: [{ key: "SECURE_PASSWORD" }], destination: "dotenv" },
187
+ };
188
+
189
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
190
+
191
+ await handleAgentEvent(
192
+ host,
193
+ {
194
+ type: "message_update",
195
+ message: makeAssistant([serverToolUse]),
196
+ assistantMessageEvent: {
197
+ type: "server_tool_use",
198
+ contentIndex: 0,
199
+ partial: makeAssistant([serverToolUse]),
200
+ },
201
+ } as any,
202
+ );
203
+
204
+ // content[0] = serverToolUse → ToolExecutionComponent renders first
205
+ assert.equal(host.chatContainer.children.length, 1, "server tool block should render immediately");
206
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
207
+
208
+ host.getMarkdownThemeWithSettings = () => ({});
209
+ const resultMessage = makeAssistant([
210
+ {
211
+ ...serverToolUse,
212
+ externalResult: {
213
+ content: [{ type: "text", text: "secure_env_collect was cancelled by user." }],
214
+ details: {},
215
+ isError: true,
216
+ },
217
+ },
218
+ { type: "text", text: "The secure password collection was cancelled." },
219
+ ]);
220
+
221
+ await handleAgentEvent(
222
+ host,
223
+ {
224
+ type: "message_update",
225
+ message: resultMessage,
226
+ assistantMessageEvent: {
227
+ type: "server_tool_use",
228
+ contentIndex: 0,
229
+ partial: resultMessage,
230
+ },
231
+ } as any,
232
+ );
233
+
234
+ // content[0]=serverToolUse, content[1]=text → order: tool, then text
235
+ assert.equal(host.chatContainer.children.length, 2, "text run should render after server tool in content[] order");
236
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
237
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
238
+ });
239
+
240
+ test("chat-controller replays final message_end content when result adds unstreamed trailing text", async () => {
241
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
242
+ fg: (_key: string, text: string) => text,
243
+ bg: (_key: string, text: string) => text,
244
+ bold: (text: string) => text,
245
+ italic: (text: string) => text,
246
+ truncate: (text: string) => text,
247
+ };
248
+
249
+ const host = createHost();
250
+ host.getMarkdownThemeWithSettings = () => ({});
251
+
252
+ const tool = {
253
+ type: "toolCall",
254
+ id: "mcp-end-replay-1",
255
+ name: "read",
256
+ mcpServer: "filesystem",
257
+ arguments: { filePath: "/tmp/demo.txt" },
258
+ };
259
+
260
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
261
+
262
+ const streamedContent = [
263
+ tool,
264
+ { type: "thinking", thinking: "I am analyzing tool output..." },
265
+ ];
266
+ await handleAgentEvent(
267
+ host,
268
+ {
269
+ type: "message_update",
270
+ message: makeAssistant(streamedContent),
271
+ assistantMessageEvent: {
272
+ type: "thinking_delta",
273
+ contentIndex: 1,
274
+ delta: "I am analyzing tool output...",
275
+ partial: makeAssistant(streamedContent),
276
+ },
277
+ } as any,
278
+ );
279
+
280
+ assert.equal(host.chatContainer.children.length, 2, "streaming shows tool + thinking only");
281
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
282
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
283
+
284
+ // Final payload includes trailing text that never arrived as message_update.
285
+ const finalContent = [
286
+ tool,
287
+ { type: "thinking", thinking: "I am analyzing tool output..." },
288
+ { type: "text", text: "Correct anything important I missed?" },
289
+ ];
290
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
291
+
292
+ assert.equal(host.chatContainer.children.length, 3, "message_end should replay and include trailing text segment");
293
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
294
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
295
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent");
296
+ });
297
+
298
+ test("chat-controller keeps pre-tool prose visible until post-tool prose arrives, then prunes it", async () => {
299
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
300
+ fg: (_key: string, text: string) => text,
301
+ bg: (_key: string, text: string) => text,
302
+ bold: (text: string) => text,
303
+ italic: (text: string) => text,
304
+ truncate: (text: string) => text,
305
+ };
306
+
307
+ const host = createHost();
308
+ host.getMarkdownThemeWithSettings = () => ({});
309
+
310
+ const mcpTool = {
311
+ type: "toolCall",
312
+ id: "mcp-tool-1",
313
+ name: "read",
314
+ mcpServer: "filesystem",
315
+ arguments: { filePath: "/tmp/demo.txt" },
316
+ };
317
+
318
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
319
+
320
+ // Provisional assistant text arrives first.
321
+ await handleAgentEvent(
322
+ host,
323
+ {
324
+ type: "message_update",
325
+ message: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }]),
326
+ assistantMessageEvent: {
327
+ type: "text_delta",
328
+ contentIndex: 0,
329
+ delta: "Let me inspect the workspace first.",
330
+ partial: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }]),
331
+ },
332
+ } as any,
333
+ );
334
+ assert.equal(host.chatContainer.children.length, 1);
335
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
336
+
337
+ // MCP tool appears; provisional text should remain visible until post-tool prose exists.
338
+ await handleAgentEvent(
339
+ host,
340
+ {
341
+ type: "message_update",
342
+ message: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }, mcpTool]),
343
+ assistantMessageEvent: {
344
+ type: "toolcall_end",
345
+ contentIndex: 1,
346
+ toolCall: {
347
+ ...mcpTool,
348
+ externalResult: {
349
+ content: [{ type: "text", text: "file preview" }],
350
+ details: {},
351
+ isError: false,
352
+ },
353
+ },
354
+ partial: makeAssistant([{ type: "text", text: "Let me inspect the workspace first." }, mcpTool]),
355
+ },
356
+ } as any,
357
+ );
358
+ assert.equal(host.chatContainer.children.length, 2, "pre-tool prose should remain during tool-only window");
359
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
360
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent");
361
+
362
+ // Post-tool prose arrives: pre-tool prose should now be pruned.
363
+ const finalContent = [
364
+ { type: "text", text: "Let me inspect the workspace first." },
365
+ mcpTool,
366
+ { type: "text", text: "Which missing feature matters most to you?" },
367
+ ];
368
+ await handleAgentEvent(
369
+ host,
370
+ {
371
+ type: "message_update",
372
+ message: makeAssistant(finalContent),
373
+ assistantMessageEvent: {
374
+ type: "text_delta",
375
+ contentIndex: 2,
376
+ delta: "Which missing feature matters most to you?",
377
+ partial: makeAssistant(finalContent),
378
+ },
379
+ } as any,
380
+ );
381
+ assert.equal(host.chatContainer.children.length, 2);
382
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
383
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
384
+
385
+ // Finalize to tear down any pinned spinner state.
386
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
387
+ });
388
+
389
+ test("chat-controller keeps pre-tool thinking visible for claude-code MCP turns without post-tool prose", async () => {
390
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
391
+ fg: (_key: string, text: string) => text,
392
+ bg: (_key: string, text: string) => text,
393
+ bold: (text: string) => text,
394
+ italic: (text: string) => text,
395
+ truncate: (text: string) => text,
396
+ };
397
+
398
+ const host = createHost();
399
+ host.getMarkdownThemeWithSettings = () => ({});
400
+
401
+ const mcpTool = {
402
+ type: "toolCall",
403
+ id: "mcp-tool-thinking-1",
404
+ name: "read",
405
+ mcpServer: "filesystem",
406
+ arguments: { filePath: "/tmp/demo.txt" },
407
+ };
408
+
409
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
410
+
411
+ const thinkingOnly = [{ type: "thinking", thinking: "I should inspect the workspace." }];
412
+ await handleAgentEvent(
413
+ host,
414
+ {
415
+ type: "message_update",
416
+ message: makeAssistant(thinkingOnly),
417
+ assistantMessageEvent: {
418
+ type: "thinking_delta",
419
+ contentIndex: 0,
420
+ delta: "I should inspect the workspace.",
421
+ partial: makeAssistant(thinkingOnly),
422
+ },
423
+ } as any,
424
+ );
425
+ assert.equal(host.chatContainer.children.length, 1);
426
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
427
+
428
+ await handleAgentEvent(
429
+ host,
430
+ {
431
+ type: "message_update",
432
+ message: makeAssistant([thinkingOnly[0], mcpTool]),
433
+ assistantMessageEvent: {
434
+ type: "toolcall_end",
435
+ contentIndex: 1,
436
+ toolCall: {
437
+ ...mcpTool,
438
+ externalResult: {
439
+ content: [{ type: "text", text: "file preview" }],
440
+ details: {},
441
+ isError: false,
442
+ },
443
+ },
444
+ partial: makeAssistant([thinkingOnly[0], mcpTool]),
445
+ },
446
+ } as any,
447
+ );
448
+
449
+ assert.equal(host.chatContainer.children.length, 2, "thinking should remain visible while only tool output is present");
450
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
451
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent");
452
+
453
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant([thinkingOnly[0], mcpTool]) } as any);
454
+ });
455
+
456
+ test("chat-controller keeps pre-tool question text for claude-code MCP when post-tool prose exists", async () => {
457
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
458
+ fg: (_key: string, text: string) => text,
459
+ bg: (_key: string, text: string) => text,
460
+ bold: (text: string) => text,
461
+ italic: (text: string) => text,
462
+ truncate: (text: string) => text,
463
+ };
464
+
465
+ const host = createHost();
466
+ host.getMarkdownThemeWithSettings = () => ({});
467
+
468
+ const mcpTool = {
469
+ type: "toolCall",
470
+ id: "mcp-tool-question-1",
471
+ name: "glob",
472
+ mcpServer: "filesystem",
473
+ arguments: { pattern: "**/*" },
474
+ };
475
+
476
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
477
+
478
+ const questionText = { type: "text", text: "Which file should I inspect?" };
479
+
480
+ await handleAgentEvent(
481
+ host,
482
+ {
483
+ type: "message_update",
484
+ message: makeAssistant([questionText]),
485
+ assistantMessageEvent: {
486
+ type: "text_delta",
487
+ contentIndex: 0,
488
+ delta: questionText.text,
489
+ partial: makeAssistant([questionText]),
490
+ },
491
+ } as any,
492
+ );
493
+
494
+ await handleAgentEvent(
495
+ host,
496
+ {
497
+ type: "message_update",
498
+ message: makeAssistant([questionText, mcpTool]),
499
+ assistantMessageEvent: {
500
+ type: "toolcall_end",
501
+ contentIndex: 1,
502
+ toolCall: {
503
+ ...mcpTool,
504
+ externalResult: {
505
+ content: [{ type: "text", text: "glob output" }],
506
+ details: {},
507
+ isError: false,
508
+ },
509
+ },
510
+ partial: makeAssistant([questionText, mcpTool]),
511
+ },
512
+ } as any,
513
+ );
514
+
515
+ const postTool = { type: "text", text: "I'll review that next." };
516
+ const finalContent = [questionText, mcpTool, postTool];
517
+ await handleAgentEvent(
518
+ host,
519
+ {
520
+ type: "message_update",
521
+ message: makeAssistant(finalContent),
522
+ assistantMessageEvent: {
523
+ type: "text_delta",
524
+ contentIndex: 2,
525
+ delta: postTool.text,
526
+ partial: makeAssistant(finalContent),
527
+ },
528
+ } as any,
529
+ );
530
+
531
+ assert.equal(host.chatContainer.children.length, 3, "question text should remain alongside MCP tool and post-tool prose");
532
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent", "pre-tool question stays visible");
533
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent", "tool renders in the middle");
534
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent", "post-tool prose renders last");
535
+
536
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
537
+ });
538
+
539
+ test("chat-controller prunes orphaned provisional text after claude-code sub-turn shrink when MCP tools appear", async () => {
540
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
541
+ fg: (_key: string, text: string) => text,
542
+ bg: (_key: string, text: string) => text,
543
+ bold: (text: string) => text,
544
+ italic: (text: string) => text,
545
+ truncate: (text: string) => text,
546
+ };
547
+
548
+ const host = createHost();
549
+ host.getMarkdownThemeWithSettings = () => ({});
550
+
551
+ const mcpTool = {
552
+ type: "toolCall",
553
+ id: "mcp-tool-shrink-1",
554
+ name: "glob",
555
+ mcpServer: "filesystem",
556
+ arguments: { pattern: "**/*" },
557
+ };
558
+
559
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
560
+
561
+ // Sub-turn 1: generate longer provisional text content.
562
+ await handleAgentEvent(
563
+ host,
564
+ {
565
+ type: "message_update",
566
+ message: makeAssistant([{ type: "text", text: "Old provisional preface." }, { type: "text", text: "More old text." }]),
567
+ assistantMessageEvent: {
568
+ type: "text_delta",
569
+ contentIndex: 1,
570
+ delta: "More old text.",
571
+ partial: makeAssistant([{ type: "text", text: "Old provisional preface." }, { type: "text", text: "More old text." }]),
572
+ },
573
+ } as any,
574
+ );
575
+ assert.equal(host.chatContainer.children.length, 1, "first sub-turn text run should render");
576
+
577
+ // Sub-turn 2 starts (content shrink): old component is orphaned by design.
578
+ await handleAgentEvent(
579
+ host,
580
+ {
581
+ type: "message_update",
582
+ message: makeAssistant([{ type: "text", text: "New provisional text before tool." }]),
583
+ assistantMessageEvent: {
584
+ type: "text_delta",
585
+ contentIndex: 0,
586
+ delta: "New provisional text before tool.",
587
+ partial: makeAssistant([{ type: "text", text: "New provisional text before tool." }]),
588
+ },
589
+ } as any,
590
+ );
591
+ assert.equal(host.chatContainer.children.length, 2, "shrink keeps prior text until MCP tool context appears");
592
+
593
+ // MCP tool appears in sub-turn 2: tool-only windows keep provisional prose visible.
594
+ await handleAgentEvent(
595
+ host,
596
+ {
597
+ type: "message_update",
598
+ message: makeAssistant([{ type: "text", text: "New provisional text before tool." }, mcpTool]),
599
+ assistantMessageEvent: {
600
+ type: "toolcall_end",
601
+ contentIndex: 1,
602
+ toolCall: {
603
+ ...mcpTool,
604
+ externalResult: {
605
+ content: [{ type: "text", text: "glob output" }],
606
+ details: {},
607
+ isError: false,
608
+ },
609
+ },
610
+ partial: makeAssistant([{ type: "text", text: "New provisional text before tool." }, mcpTool]),
611
+ },
612
+ } as any,
613
+ );
614
+ assert.equal(host.chatContainer.children.length, 3, "stale text runs are deferred until post-tool prose arrives");
615
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
616
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
617
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "ToolExecutionComponent");
618
+
619
+ const finalContent = [mcpTool, { type: "text", text: "Final visible question?" }];
620
+ await handleAgentEvent(
621
+ host,
622
+ {
623
+ type: "message_update",
624
+ message: makeAssistant(finalContent),
625
+ assistantMessageEvent: {
626
+ type: "text_delta",
627
+ contentIndex: 1,
628
+ delta: "Final visible question?",
629
+ partial: makeAssistant(finalContent),
630
+ },
631
+ } as any,
632
+ );
633
+ assert.equal(host.chatContainer.children.length, 2);
634
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
635
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
636
+
637
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
638
+ });
639
+
640
+ test("chat-controller prunes orphans from multiple sub-turn shrinks before MCP post-tool prose", async () => {
641
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
642
+ fg: (_key: string, text: string) => text,
643
+ bg: (_key: string, text: string) => text,
644
+ bold: (text: string) => text,
645
+ italic: (text: string) => text,
646
+ truncate: (text: string) => text,
647
+ };
648
+
649
+ const host = createHost();
650
+ host.getMarkdownThemeWithSettings = () => ({});
651
+
652
+ const mcpTool = {
653
+ type: "toolCall",
654
+ id: "mcp-tool-multi-shrink-1",
655
+ name: "glob",
656
+ mcpServer: "filesystem",
657
+ arguments: { pattern: "**/*" },
658
+ };
659
+
660
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
661
+
662
+ // Sub-turn 1: 3 text blocks (merged into one text-run).
663
+ const subTurn1 = [
664
+ { type: "text", text: "First provisional A." },
665
+ { type: "text", text: "First provisional B." },
666
+ { type: "text", text: "First provisional C." },
667
+ ];
668
+ await handleAgentEvent(
669
+ host,
670
+ {
671
+ type: "message_update",
672
+ message: makeAssistant(subTurn1),
673
+ assistantMessageEvent: {
674
+ type: "text_delta",
675
+ contentIndex: 2,
676
+ delta: "First provisional C.",
677
+ partial: makeAssistant(subTurn1),
678
+ },
679
+ } as any,
680
+ );
681
+ assert.equal(host.chatContainer.children.length, 1, "first sub-turn renders 1 text-run");
682
+
683
+ // Sub-turn 2 (first shrink 3 → 2 blocks).
684
+ const subTurn2 = [
685
+ { type: "text", text: "Second provisional A." },
686
+ { type: "text", text: "Second provisional B." },
687
+ ];
688
+ await handleAgentEvent(
689
+ host,
690
+ {
691
+ type: "message_update",
692
+ message: makeAssistant(subTurn2),
693
+ assistantMessageEvent: {
694
+ type: "text_delta",
695
+ contentIndex: 1,
696
+ delta: "Second provisional B.",
697
+ partial: makeAssistant(subTurn2),
698
+ },
699
+ } as any,
700
+ );
701
+ assert.equal(host.chatContainer.children.length, 2, "first shrink appends, keeps prior text as frozen history");
702
+
703
+ // Sub-turn 3 (second shrink 2 → 1 block). This is the critical step —
704
+ // without orphan accumulation, sub-turn 1's orphaned segment would be
705
+ // dropped from tracking here and later strand in the container.
706
+ const subTurn3 = [{ type: "text", text: "Third provisional." }];
707
+ await handleAgentEvent(
708
+ host,
709
+ {
710
+ type: "message_update",
711
+ message: makeAssistant(subTurn3),
712
+ assistantMessageEvent: {
713
+ type: "text_delta",
714
+ contentIndex: 0,
715
+ delta: "Third provisional.",
716
+ partial: makeAssistant(subTurn3),
717
+ },
718
+ } as any,
719
+ );
720
+ assert.equal(host.chatContainer.children.length, 3, "second shrink appends again, still no prune (no post-tool text)");
721
+
722
+ // MCP tool appears — tool-only window still keeps provisional prose visible.
723
+ await handleAgentEvent(
724
+ host,
725
+ {
726
+ type: "message_update",
727
+ message: makeAssistant([{ type: "text", text: "Third provisional." }, mcpTool]),
728
+ assistantMessageEvent: {
729
+ type: "toolcall_end",
730
+ contentIndex: 1,
731
+ toolCall: {
732
+ ...mcpTool,
733
+ externalResult: {
734
+ content: [{ type: "text", text: "glob output" }],
735
+ details: {},
736
+ isError: false,
737
+ },
738
+ },
739
+ partial: makeAssistant([{ type: "text", text: "Third provisional." }, mcpTool]),
740
+ },
741
+ } as any,
742
+ );
743
+ assert.equal(host.chatContainer.children.length, 4, "tool-only window keeps all three provisional text-runs");
744
+
745
+ // Final post-tool text arrives — prune must drop ALL three pre-tool
746
+ // provisional text-runs across both shrinks, leaving only tool + final text.
747
+ const finalContent = [mcpTool, { type: "text", text: "Final answer." }];
748
+ await handleAgentEvent(
749
+ host,
750
+ {
751
+ type: "message_update",
752
+ message: makeAssistant(finalContent),
753
+ assistantMessageEvent: {
754
+ type: "text_delta",
755
+ contentIndex: 1,
756
+ delta: "Final answer.",
757
+ partial: makeAssistant(finalContent),
758
+ },
759
+ } as any,
760
+ );
761
+ assert.equal(
762
+ host.chatContainer.children.length,
763
+ 2,
764
+ "all pre-tool provisional segments from every shrink must be pruned once post-tool prose arrives",
765
+ );
766
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolExecutionComponent");
767
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
768
+
769
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
770
+ });
771
+
772
+ test("chat-controller pins latest assistant text above editor when tool calls are present", async () => {
773
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
774
+ fg: (_key: string, text: string) => text,
775
+ bg: (_key: string, text: string) => text,
776
+ bold: (text: string) => text,
777
+ italic: (text: string) => text,
778
+ truncate: (text: string) => text,
779
+ };
780
+
781
+ const host = createHost();
782
+ const toolId = "tool-pin-1";
783
+ const toolCall = {
784
+ type: "toolCall",
785
+ id: toolId,
786
+ name: "exec_command",
787
+ arguments: { cmd: "echo hi" },
788
+ };
789
+
790
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
791
+
792
+ assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should be empty at message_start");
793
+
794
+ // Send a message with text followed by a tool call
795
+ host.getMarkdownThemeWithSettings = () => ({});
796
+ await handleAgentEvent(
797
+ host,
798
+ {
799
+ type: "message_update",
800
+ message: makeAssistant([
801
+ { type: "text", text: "Looking at the files now." },
802
+ toolCall,
803
+ ]),
804
+ assistantMessageEvent: {
805
+ type: "toolcall_end",
806
+ contentIndex: 1,
807
+ toolCall: {
808
+ ...toolCall,
809
+ externalResult: {
810
+ content: [{ type: "text", text: "file contents" }],
811
+ details: {},
812
+ isError: false,
813
+ },
814
+ },
815
+ partial: makeAssistant([{ type: "text", text: "Looking at the files now." }, toolCall]),
816
+ },
817
+ } as any,
818
+ );
819
+
820
+ // Pinned zone should now have a DynamicBorder and a Markdown component
821
+ assert.equal(host.pinnedMessageContainer.children.length, 2, "pinned zone should have border + markdown");
822
+ assert.equal(host.pinnedMessageContainer.children[0]?.constructor?.name, "DynamicBorder");
823
+ assert.equal(host.pinnedMessageContainer.children[1]?.constructor?.name, "Markdown");
824
+ });
825
+
826
+ test("chat-controller clears pinned zone when a new assistant message starts", async () => {
827
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
828
+ fg: (_key: string, text: string) => text,
829
+ bg: (_key: string, text: string) => text,
830
+ bold: (text: string) => text,
831
+ italic: (text: string) => text,
832
+ truncate: (text: string) => text,
833
+ };
834
+
835
+ const host = createHost();
836
+ const toolCall = {
837
+ type: "toolCall",
838
+ id: "tool-clear-1",
839
+ name: "exec_command",
840
+ arguments: { cmd: "echo hi" },
841
+ };
842
+
843
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
844
+
845
+ // Populate the pinned zone
846
+ host.getMarkdownThemeWithSettings = () => ({});
847
+ await handleAgentEvent(
848
+ host,
849
+ {
850
+ type: "message_update",
851
+ message: makeAssistant([{ type: "text", text: "Working on it." }, toolCall]),
852
+ assistantMessageEvent: {
853
+ type: "toolcall_end",
854
+ contentIndex: 1,
855
+ toolCall: {
856
+ ...toolCall,
857
+ externalResult: {
858
+ content: [{ type: "text", text: "ok" }],
859
+ details: {},
860
+ isError: false,
861
+ },
862
+ },
863
+ partial: makeAssistant([{ type: "text", text: "Working on it." }, toolCall]),
864
+ },
865
+ } as any,
866
+ );
867
+
868
+ assert.ok(host.pinnedMessageContainer.children.length > 0, "pinned zone should be populated");
869
+
870
+ // Start a new assistant message — pinned zone should clear
871
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
872
+
873
+ assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should clear on new assistant message");
874
+ });
875
+
876
+ test("chat-controller clears pinned zone when the agent turn ends", async () => {
877
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
878
+ fg: (_key: string, text: string) => text,
879
+ bg: (_key: string, text: string) => text,
880
+ bold: (text: string) => text,
881
+ italic: (text: string) => text,
882
+ truncate: (text: string) => text,
883
+ };
884
+
885
+ const host = createHost();
886
+ const toolCall = {
887
+ type: "toolCall",
888
+ id: "tool-clear-on-end-1",
889
+ name: "exec_command",
890
+ arguments: { cmd: "echo hi" },
891
+ };
892
+
893
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
894
+
895
+ host.getMarkdownThemeWithSettings = () => ({});
896
+ await handleAgentEvent(
897
+ host,
898
+ {
899
+ type: "message_update",
900
+ message: makeAssistant([{ type: "text", text: "Working on it." }, toolCall]),
901
+ assistantMessageEvent: {
902
+ type: "toolcall_end",
903
+ contentIndex: 1,
904
+ toolCall: {
905
+ ...toolCall,
906
+ externalResult: {
907
+ content: [{ type: "text", text: "ok" }],
908
+ details: {},
909
+ isError: false,
910
+ },
911
+ },
912
+ partial: makeAssistant([{ type: "text", text: "Working on it." }, toolCall]),
913
+ },
914
+ } as any,
915
+ );
916
+
917
+ assert.ok(host.pinnedMessageContainer.children.length > 0, "pinned zone should be populated before agent_end");
918
+
919
+ await handleAgentEvent(host, { type: "agent_end" } as any);
920
+
921
+ assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should clear on agent_end");
922
+ });
923
+
924
+ test("chat-controller clears pinned zone when assistant message ends", async () => {
925
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
926
+ fg: (_key: string, text: string) => text,
927
+ bg: (_key: string, text: string) => text,
928
+ bold: (text: string) => text,
929
+ italic: (text: string) => text,
930
+ truncate: (text: string) => text,
931
+ };
932
+
933
+ const host = createHost();
934
+ const toolCall = {
935
+ type: "toolCall",
936
+ id: "tool-msg-end-1",
937
+ name: "exec_command",
938
+ arguments: { cmd: "echo hi" },
939
+ };
940
+
941
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
942
+
943
+ host.getMarkdownThemeWithSettings = () => ({});
944
+ const msgContent = [{ type: "text", text: "Summary after tools." }, toolCall];
945
+ await handleAgentEvent(
946
+ host,
947
+ {
948
+ type: "message_update",
949
+ message: makeAssistant(msgContent),
950
+ assistantMessageEvent: {
951
+ type: "toolcall_end",
952
+ contentIndex: 1,
953
+ toolCall: {
954
+ ...toolCall,
955
+ externalResult: {
956
+ content: [{ type: "text", text: "ok" }],
957
+ details: {},
958
+ isError: false,
959
+ },
960
+ },
961
+ partial: makeAssistant(msgContent),
962
+ },
963
+ } as any,
964
+ );
965
+
966
+ assert.ok(host.pinnedMessageContainer.children.length > 0, "pinned zone should be populated during streaming");
967
+
968
+ // End the assistant message (e.g. before form elicitation) — pinned zone should clear
969
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(msgContent) } as any);
970
+
971
+ assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should clear on message_end to prevent duplicate display");
972
+ });
973
+
974
+ test("chat-controller does not pin when there are no tool calls", async () => {
975
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
976
+ fg: (_key: string, text: string) => text,
977
+ bg: (_key: string, text: string) => text,
978
+ bold: (text: string) => text,
979
+ italic: (text: string) => text,
980
+ truncate: (text: string) => text,
981
+ };
982
+
983
+ const host = createHost();
984
+
985
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
986
+
987
+ host.getMarkdownThemeWithSettings = () => ({});
988
+ await handleAgentEvent(
989
+ host,
990
+ {
991
+ type: "message_update",
992
+ message: makeAssistant([{ type: "text", text: "Just some text, no tools." }]),
993
+ assistantMessageEvent: {
994
+ type: "text_delta",
995
+ contentIndex: 0,
996
+ delta: "Just some text, no tools.",
997
+ partial: makeAssistant([{ type: "text", text: "Just some text, no tools." }]),
998
+ },
999
+ } as any,
1000
+ );
1001
+
1002
+ assert.equal(host.pinnedMessageContainer.children.length, 0, "pinned zone should stay empty without tool calls");
1003
+ });
1004
+
1005
+ // Regression test for issue #4144: interleaved text/tool content must render in content[] index order.
1006
+ // Stream: [text "A", toolCall T1, text "B", toolCall T2, text "C"]
1007
+ // Expected chatContainer order: textRun(A), toolExec(T1), textRun(B), toolExec(T2), textRun(C)
1008
+ // Each AssistantMessageComponent must render ONLY its own text — no duplication after message_end.
1009
+ test("chat-controller renders interleaved text and tool blocks in content[] index order (#4144)", async () => {
1010
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1011
+ fg: (_key: string, text: string) => text,
1012
+ bg: (_key: string, text: string) => text,
1013
+ bold: (text: string) => text,
1014
+ italic: (text: string) => text,
1015
+ truncate: (text: string) => text,
1016
+ };
1017
+
1018
+ const host = createHost();
1019
+ host.getMarkdownThemeWithSettings = () => ({});
1020
+
1021
+ const t1 = { type: "toolCall", id: "t1", name: "tool_one", arguments: {} };
1022
+ const t2 = { type: "toolCall", id: "t2", name: "tool_two", arguments: {} };
1023
+
1024
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
1025
+
1026
+ // Stream text "A" at index 0
1027
+ await handleAgentEvent(host, {
1028
+ type: "message_update",
1029
+ message: makeAssistant([{ type: "text", text: "A" }]),
1030
+ assistantMessageEvent: {
1031
+ type: "text_delta",
1032
+ contentIndex: 0,
1033
+ delta: "A",
1034
+ partial: makeAssistant([{ type: "text", text: "A" }]),
1035
+ },
1036
+ } as any);
1037
+
1038
+ // Stream toolCall T1 at index 1
1039
+ await handleAgentEvent(host, {
1040
+ type: "message_update",
1041
+ message: makeAssistant([{ type: "text", text: "A" }, t1]),
1042
+ assistantMessageEvent: {
1043
+ type: "toolcall_end",
1044
+ contentIndex: 1,
1045
+ toolCall: {
1046
+ ...t1,
1047
+ externalResult: { content: [{ type: "text", text: "result1" }], details: {}, isError: false },
1048
+ },
1049
+ partial: makeAssistant([{ type: "text", text: "A" }, t1]),
1050
+ },
1051
+ } as any);
1052
+
1053
+ // Stream text "B" at index 2
1054
+ await handleAgentEvent(host, {
1055
+ type: "message_update",
1056
+ message: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }]),
1057
+ assistantMessageEvent: {
1058
+ type: "text_delta",
1059
+ contentIndex: 2,
1060
+ delta: "B",
1061
+ partial: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }]),
1062
+ },
1063
+ } as any);
1064
+
1065
+ // Stream toolCall T2 at index 3
1066
+ await handleAgentEvent(host, {
1067
+ type: "message_update",
1068
+ message: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }, t2]),
1069
+ assistantMessageEvent: {
1070
+ type: "toolcall_end",
1071
+ contentIndex: 3,
1072
+ toolCall: {
1073
+ ...t2,
1074
+ externalResult: { content: [{ type: "text", text: "result2" }], details: {}, isError: false },
1075
+ },
1076
+ partial: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }, t2]),
1077
+ },
1078
+ } as any);
1079
+
1080
+ // Stream text "C" at index 4
1081
+ const finalContent = [
1082
+ { type: "text", text: "A" }, t1, { type: "text", text: "B" }, t2, { type: "text", text: "C" },
1083
+ ];
1084
+ await handleAgentEvent(host, {
1085
+ type: "message_update",
1086
+ message: makeAssistant(finalContent),
1087
+ assistantMessageEvent: {
1088
+ type: "text_delta",
1089
+ contentIndex: 4,
1090
+ delta: "C",
1091
+ partial: makeAssistant(finalContent),
1092
+ },
1093
+ } as any);
1094
+
1095
+ // Finalize — exercises the message_end path where a buggy setRange(undefined) would cause duplication
1096
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
1097
+
1098
+ // Assert interleaved order: textRun(A), toolExec(T1), textRun(B), toolExec(T2), textRun(C)
1099
+ assert.equal(host.chatContainer.children.length, 5, "should have 5 children in interleaved order");
1100
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent", "index 0: text run A");
1101
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent", "index 1: tool T1");
1102
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent", "index 2: text run B");
1103
+ assert.equal(host.chatContainer.children[3]?.constructor?.name, "ToolExecutionComponent", "index 3: tool T2");
1104
+ assert.equal(host.chatContainer.children[4]?.constructor?.name, "AssistantMessageComponent", "index 4: text run C");
1105
+
1106
+ // Helper: collect the text of all Markdown children inside an AssistantMessageComponent.
1107
+ // Structure: AssistantMessageComponent (Container) -> contentContainer (children[0]) -> Markdown nodes.
1108
+ function getRenderedTexts(comp: any): string[] {
1109
+ const contentContainer = comp.children?.[0];
1110
+ if (!contentContainer) return [];
1111
+ return (contentContainer.children ?? [])
1112
+ .filter((c: any) => c.constructor?.name === "Markdown")
1113
+ .map((c: any) => (c as any).text as string);
1114
+ }
1115
+
1116
+ // Each text-run component must contain only its own text — no cross-contamination after message_end
1117
+ assert.deepEqual(getRenderedTexts(host.chatContainer.children[0]), ["A"], "text run A must contain only 'A'");
1118
+ assert.deepEqual(getRenderedTexts(host.chatContainer.children[2]), ["B"], "text run B must contain only 'B'");
1119
+ assert.deepEqual(getRenderedTexts(host.chatContainer.children[4]), ["C"], "text run C must contain only 'C'");
1120
+ });
1121
+
1122
+ test("chat-controller does not duplicate text when content is [text, tool, text] (interleaved stream)", async () => {
1123
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1124
+ fg: (_key: string, text: string) => text,
1125
+ bg: (_key: string, text: string) => text,
1126
+ bold: (text: string) => text,
1127
+ italic: (text: string) => text,
1128
+ truncate: (text: string) => text,
1129
+ };
1130
+
1131
+ const host = createHost();
1132
+ host.getMarkdownThemeWithSettings = () => ({});
1133
+
1134
+ const t1 = { type: "toolCall", id: "t1", name: "tool_one", arguments: {} };
1135
+
1136
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
1137
+
1138
+ // Step 1: text "A" at index 0
1139
+ await handleAgentEvent(host, {
1140
+ type: "message_update",
1141
+ message: makeAssistant([{ type: "text", text: "A" }]),
1142
+ assistantMessageEvent: {
1143
+ type: "text_delta",
1144
+ contentIndex: 0,
1145
+ delta: "A",
1146
+ partial: makeAssistant([{ type: "text", text: "A" }]),
1147
+ },
1148
+ } as any);
1149
+
1150
+ // Step 2: toolCall at index 1
1151
+ await handleAgentEvent(host, {
1152
+ type: "message_update",
1153
+ message: makeAssistant([{ type: "text", text: "A" }, t1]),
1154
+ assistantMessageEvent: {
1155
+ type: "toolcall_end",
1156
+ contentIndex: 1,
1157
+ toolCall: {
1158
+ ...t1,
1159
+ externalResult: { content: [{ type: "text", text: "result1" }], details: {}, isError: false },
1160
+ },
1161
+ partial: makeAssistant([{ type: "text", text: "A" }, t1]),
1162
+ },
1163
+ } as any);
1164
+
1165
+ // Step 3: text "B" at index 2
1166
+ const finalContent = [{ type: "text", text: "A" }, t1, { type: "text", text: "B" }];
1167
+ await handleAgentEvent(host, {
1168
+ type: "message_update",
1169
+ message: makeAssistant(finalContent),
1170
+ assistantMessageEvent: {
1171
+ type: "text_delta",
1172
+ contentIndex: 2,
1173
+ delta: "B",
1174
+ partial: makeAssistant(finalContent),
1175
+ },
1176
+ } as any);
1177
+
1178
+ assert.equal(host.chatContainer.children.length, 3);
1179
+ assert.equal(host.chatContainer.children[0]?.constructor?.name, "AssistantMessageComponent");
1180
+ assert.equal(host.chatContainer.children[1]?.constructor?.name, "ToolExecutionComponent");
1181
+ assert.equal(host.chatContainer.children[2]?.constructor?.name, "AssistantMessageComponent");
1182
+
1183
+ const firstText = host.chatContainer.children[0];
1184
+ const secondText = host.chatContainer.children[2];
1185
+ assert.notEqual(firstText, secondText, "text-before-tool and text-after-tool must be separate component instances");
1186
+ assert.deepEqual((firstText as any).range, { startIndex: 0, endIndex: 0 }, "first text-run covers only content[0]");
1187
+ assert.deepEqual((secondText as any).range, { startIndex: 2, endIndex: 2 }, "second text-run covers only content[2]");
1188
+
1189
+ // Finalize — regression guard: range must NOT be cleared on message_end (would cause duplication)
1190
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant(finalContent) } as any);
1191
+
1192
+ assert.deepEqual((secondText as any).range, { startIndex: 2, endIndex: 2 }, "range must not be cleared on message_end (would cause duplication)");
1193
+ });
1194
+
1195
+ // Regression for the claude-code sub-turn bug that followed #4144:
1196
+ // an adapter can reset content[] back to 0/1 mid-lifecycle when a new provider
1197
+ // sub-turn begins. The segment walker must NOT update prior-sub-turn text-run
1198
+ // components in place (which would destroy earlier history) and must NOT reuse
1199
+ // stale tool registrations for a new tool at the same contentIndex. Prior
1200
+ // sub-turn children must stay frozen; new sub-turn segments must append after
1201
+ // them, and the pinned "Latest Output" mirror must re-evaluate for the new sub-turn.
1202
+ test("chat-controller freezes prior sub-turn and appends new segments when content shrinks", async () => {
1203
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1204
+ fg: (_key: string, text: string) => text,
1205
+ bg: (_key: string, text: string) => text,
1206
+ bold: (text: string) => text,
1207
+ italic: (text: string) => text,
1208
+ truncate: (text: string) => text,
1209
+ };
1210
+
1211
+ const host = createHost();
1212
+ host.getMarkdownThemeWithSettings = () => ({});
1213
+
1214
+ const t1 = { type: "toolCall", id: "t1", name: "tool_one", arguments: {} };
1215
+ const t2 = { type: "toolCall", id: "t2", name: "tool_two", arguments: {} };
1216
+
1217
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
1218
+
1219
+ // Sub-turn 1: grow to [A, T1, B]
1220
+ await handleAgentEvent(host, {
1221
+ type: "message_update",
1222
+ message: makeAssistant([{ type: "text", text: "A" }]),
1223
+ assistantMessageEvent: {
1224
+ type: "text_delta", contentIndex: 0, delta: "A",
1225
+ partial: makeAssistant([{ type: "text", text: "A" }]),
1226
+ },
1227
+ } as any);
1228
+ await handleAgentEvent(host, {
1229
+ type: "message_update",
1230
+ message: makeAssistant([{ type: "text", text: "A" }, t1]),
1231
+ assistantMessageEvent: {
1232
+ type: "toolcall_end", contentIndex: 1,
1233
+ toolCall: { ...t1, externalResult: { content: [{ type: "text", text: "r1" }], details: {}, isError: false } },
1234
+ partial: makeAssistant([{ type: "text", text: "A" }, t1]),
1235
+ },
1236
+ } as any);
1237
+ await handleAgentEvent(host, {
1238
+ type: "message_update",
1239
+ message: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }]),
1240
+ assistantMessageEvent: {
1241
+ type: "text_delta", contentIndex: 2, delta: "B",
1242
+ partial: makeAssistant([{ type: "text", text: "A" }, t1, { type: "text", text: "B" }]),
1243
+ },
1244
+ } as any);
1245
+
1246
+ assert.equal(host.chatContainer.children.length, 3, "sub-turn 1 renders 3 children");
1247
+ const priorA = host.chatContainer.children[0];
1248
+ const priorT1 = host.chatContainer.children[1];
1249
+ const priorB = host.chatContainer.children[2];
1250
+
1251
+ // Sub-turn boundary: adapter resets content[] to [C]
1252
+ await handleAgentEvent(host, {
1253
+ type: "message_update",
1254
+ message: makeAssistant([{ type: "text", text: "C" }]),
1255
+ assistantMessageEvent: {
1256
+ type: "text_delta", contentIndex: 0, delta: "C",
1257
+ partial: makeAssistant([{ type: "text", text: "C" }]),
1258
+ },
1259
+ } as any);
1260
+
1261
+ // Prior 3 children must still exist in DOM — and a NEW text-run for "C" appended after them.
1262
+ assert.equal(host.chatContainer.children.length, 4, "shrink must append new segment, not replace prior history");
1263
+ assert.equal(host.chatContainer.children[0], priorA, "prior A component stays at index 0");
1264
+ assert.equal(host.chatContainer.children[1], priorT1, "prior T1 component stays at index 1");
1265
+ assert.equal(host.chatContainer.children[2], priorB, "prior B component stays at index 2");
1266
+ assert.notEqual(host.chatContainer.children[3], priorA, "new C text-run must be a different component from prior A");
1267
+ assert.equal(host.chatContainer.children[3]?.constructor?.name, "AssistantMessageComponent");
1268
+
1269
+ // Prior A component must still render "A", not be overwritten with "C".
1270
+ function getRenderedTexts(comp: any): string[] {
1271
+ const contentContainer = comp.children?.[0];
1272
+ if (!contentContainer) return [];
1273
+ return (contentContainer.children ?? [])
1274
+ .filter((c: any) => c.constructor?.name === "Markdown")
1275
+ .map((c: any) => (c as any).text as string);
1276
+ }
1277
+ assert.deepEqual(getRenderedTexts(priorA), ["A"], "prior A text-run must still contain 'A' after shrink");
1278
+ assert.deepEqual(getRenderedTexts(priorB), ["B"], "prior B text-run must still contain 'B' after shrink");
1279
+ assert.deepEqual(getRenderedTexts(host.chatContainer.children[3]), ["C"], "new text-run must contain only 'C'");
1280
+
1281
+ // Sub-turn 2 grows with a new tool T2 at contentIndex=1.
1282
+ await handleAgentEvent(host, {
1283
+ type: "message_update",
1284
+ message: makeAssistant([{ type: "text", text: "C" }, t2]),
1285
+ assistantMessageEvent: {
1286
+ type: "toolcall_end", contentIndex: 1,
1287
+ toolCall: { ...t2, externalResult: { content: [{ type: "text", text: "r2" }], details: {}, isError: false } },
1288
+ partial: makeAssistant([{ type: "text", text: "C" }, t2]),
1289
+ },
1290
+ } as any);
1291
+
1292
+ // T2 must be appended after the new C text-run, not conflated with the stale T1 registration.
1293
+ assert.equal(host.chatContainer.children.length, 5, "new tool appends after new text-run");
1294
+ assert.equal(host.chatContainer.children[4]?.constructor?.name, "ToolExecutionComponent");
1295
+ assert.notEqual(host.chatContainer.children[4], priorT1, "new T2 must be a different component from prior T1");
1296
+
1297
+ // Finalize so the module-level pinned spinner (setInterval) is torn down and the test process can exit.
1298
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant([{ type: "text", text: "C" }, t2]) } as any);
1299
+ });
1300
+
1301
+ // Regression: after a sub-turn shrink, lastPinnedText must be cleared so the
1302
+ // pinned "Latest Output" mirror can display text from the new sub-turn instead
1303
+ // of staying frozen on a stale snapshot (the "bottom green stays" symptom).
1304
+ test("chat-controller updates pinned zone after sub-turn shrink", async () => {
1305
+ (globalThis as any)[Symbol.for("@gsd/pi-coding-agent:theme")] = {
1306
+ fg: (_key: string, text: string) => text,
1307
+ bg: (_key: string, text: string) => text,
1308
+ bold: (text: string) => text,
1309
+ italic: (text: string) => text,
1310
+ truncate: (text: string) => text,
1311
+ };
1312
+
1313
+ const host = createHost();
1314
+ host.getMarkdownThemeWithSettings = () => ({});
1315
+
1316
+ const t1 = { type: "toolCall", id: "t1", name: "tool_one", arguments: {} };
1317
+ const t2 = { type: "toolCall", id: "t2", name: "tool_two", arguments: {} };
1318
+
1319
+ await handleAgentEvent(host, { type: "message_start", message: makeAssistant([]) } as any);
1320
+
1321
+ // Sub-turn 1 with pinnable text before a tool → populates pinned zone with "first".
1322
+ await handleAgentEvent(host, {
1323
+ type: "message_update",
1324
+ message: makeAssistant([{ type: "text", text: "first" }, t1]),
1325
+ assistantMessageEvent: {
1326
+ type: "toolcall_end", contentIndex: 1,
1327
+ toolCall: { ...t1, externalResult: { content: [{ type: "text", text: "r1" }], details: {}, isError: false } },
1328
+ partial: makeAssistant([{ type: "text", text: "first" }, t1]),
1329
+ },
1330
+ } as any);
1331
+ const pinnedMarkdown = host.pinnedMessageContainer.children[1];
1332
+ assert.equal((pinnedMarkdown as any)?.text, "first", "pinned zone seeded with sub-turn 1 text");
1333
+
1334
+ // Sub-turn boundary: content resets to [second, t2].
1335
+ await handleAgentEvent(host, {
1336
+ type: "message_update",
1337
+ message: makeAssistant([{ type: "text", text: "second" }, t2]),
1338
+ assistantMessageEvent: {
1339
+ type: "toolcall_end", contentIndex: 1,
1340
+ toolCall: { ...t2, externalResult: { content: [{ type: "text", text: "r2" }], details: {}, isError: false } },
1341
+ partial: makeAssistant([{ type: "text", text: "second" }, t2]),
1342
+ },
1343
+ } as any);
1344
+
1345
+ // Pinned markdown must now reflect the new sub-turn's text, not stay frozen on "first".
1346
+ assert.equal((pinnedMarkdown as any)?.text, "second", "pinned zone must update after sub-turn shrink (#4144 regression)");
1347
+
1348
+ // Finalize so the module-level pinned spinner (setInterval) is torn down and the test process can exit.
1349
+ await handleAgentEvent(host, { type: "message_end", message: makeAssistant([{ type: "text", text: "second" }, t2]) } as any);
1350
+ });
1351
+
1352
+ test("chat-controller: agent_end without message_end must not remove streaming component from DOM (regression #4197)", async () => {
1353
+ const host = createHost();
1354
+
1355
+ await handleAgentEvent(host, {
1356
+ type: "message_start",
1357
+ message: makeAssistant([]),
1358
+ } as any);
1359
+
1360
+ // Simulate partial streaming that creates an AssistantMessageComponent
1361
+ await handleAgentEvent(host, {
1362
+ type: "message_update",
1363
+ message: makeAssistant([{ type: "text", text: "partial answer" }]),
1364
+ assistantMessageEvent: {
1365
+ type: "text_delta",
1366
+ contentIndex: 0,
1367
+ delta: "partial answer",
1368
+ partial: makeAssistant([{ type: "text", text: "partial answer" }]),
1369
+ },
1370
+ } as any);
1371
+
1372
+ // Precondition: component is in DOM
1373
+ assert.equal(
1374
+ host.chatContainer.children.length,
1375
+ 1,
1376
+ "streaming component must be in DOM after message_update",
1377
+ );
1378
+ const comp = host.chatContainer.children[0];
1379
+
1380
+ // Simulate abort: agent_end fires WITHOUT message_end
1381
+ await handleAgentEvent(host, { type: "agent_end" } as any);
1382
+
1383
+ assert.equal(
1384
+ host.chatContainer.children.length,
1385
+ 1,
1386
+ "agent_end must NOT remove the streaming component from the DOM (issue #4197)",
1387
+ );
1388
+ assert.equal(
1389
+ host.chatContainer.children[0],
1390
+ comp,
1391
+ "the same component instance must remain in the DOM after agent_end",
1392
+ );
1393
+ });
1394
+
1395
+ test("chat-controller: agent_end after message_end must not alter DOM", async () => {
1396
+ const host = createHost();
1397
+ const content = [{ type: "text", text: "complete answer" }];
1398
+
1399
+ await handleAgentEvent(host, {
1400
+ type: "message_start",
1401
+ message: makeAssistant([]),
1402
+ } as any);
1403
+
1404
+ await handleAgentEvent(host, {
1405
+ type: "message_update",
1406
+ message: makeAssistant(content),
1407
+ assistantMessageEvent: {
1408
+ type: "text_delta",
1409
+ contentIndex: 0,
1410
+ delta: "complete answer",
1411
+ partial: makeAssistant(content),
1412
+ },
1413
+ } as any);
1414
+
1415
+ await handleAgentEvent(host, {
1416
+ type: "message_end",
1417
+ message: makeAssistant(content),
1418
+ } as any);
1419
+
1420
+ const countAfterMessageEnd = host.chatContainer.children.length;
1421
+ assert.ok(countAfterMessageEnd > 0, "component must be present after message_end");
1422
+
1423
+ await handleAgentEvent(host, { type: "agent_end" } as any);
1424
+
1425
+ assert.equal(
1426
+ host.chatContainer.children.length,
1427
+ countAfterMessageEnd,
1428
+ "agent_end after message_end must not add or remove DOM nodes",
1429
+ );
1430
+ });