gsd-pi 2.73.1 → 2.74.0-dev.16f2f3b

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 (480) hide show
  1. package/dist/cli-web-branch.d.ts +4 -3
  2. package/dist/cli-web-branch.js +10 -7
  3. package/dist/cli.js +184 -206
  4. package/dist/headless-query.js +4 -1
  5. package/dist/help-text.js +23 -0
  6. package/dist/logo.d.ts +1 -1
  7. package/dist/logo.js +1 -1
  8. package/dist/onboarding.js +59 -53
  9. package/dist/resource-loader.js +2 -2
  10. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +68 -4
  11. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  12. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  13. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  14. package/dist/resources/extensions/gsd/auto/phases.js +173 -13
  15. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +22 -4
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +105 -16
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +254 -15
  19. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  20. package/dist/resources/extensions/gsd/auto-start.js +23 -6
  21. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +13 -0
  22. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  23. package/dist/resources/extensions/gsd/auto-verification.js +186 -3
  24. package/dist/resources/extensions/gsd/auto.js +65 -12
  25. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +21 -8
  26. package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
  27. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  28. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  29. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  30. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  31. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  32. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  33. package/dist/resources/extensions/gsd/commands-handlers.js +8 -2
  34. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  35. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  36. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  37. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  38. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  39. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  40. package/dist/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  41. package/dist/resources/extensions/gsd/git-service.js +49 -1
  42. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  43. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  44. package/dist/resources/extensions/gsd/guided-flow.js +23 -0
  45. package/dist/resources/extensions/gsd/index.js +15 -2
  46. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  47. package/dist/resources/extensions/gsd/journal.js +27 -0
  48. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  49. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  50. package/dist/resources/extensions/gsd/metrics.js +19 -0
  51. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  53. package/dist/resources/extensions/gsd/notification-widget.js +2 -2
  54. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  55. package/dist/resources/extensions/gsd/preferences-models.js +63 -3
  56. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  57. package/dist/resources/extensions/gsd/preferences-validation.js +130 -2
  58. package/dist/resources/extensions/gsd/preferences.js +26 -0
  59. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  60. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  61. package/dist/resources/extensions/gsd/state.js +66 -15
  62. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  63. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  64. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  65. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  66. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  67. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  68. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  69. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  70. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  71. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  72. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  73. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  74. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  75. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  76. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  77. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  78. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  79. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  80. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  81. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  82. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  83. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  84. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  85. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  86. package/dist/update-check.d.ts +1 -0
  87. package/dist/update-check.js +13 -5
  88. package/dist/update-cmd.js +4 -3
  89. package/dist/web/standalone/.next/BUILD_ID +1 -1
  90. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  91. package/dist/web/standalone/.next/build-manifest.json +3 -3
  92. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  93. package/dist/web/standalone/.next/required-server-files.json +3 -3
  94. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  95. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  105. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  133. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  163. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  169. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  187. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  189. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/index.html +1 -1
  199. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  200. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  201. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  202. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  204. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/page.js +2 -2
  206. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  208. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  209. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  212. package/dist/web/standalone/.next/server/middleware.js +2 -2
  213. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  215. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  216. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  217. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  218. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  220. package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  223. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  224. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  225. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  226. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  227. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  228. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  229. package/dist/web/standalone/server.js +1 -1
  230. package/package.json +3 -3
  231. package/packages/daemon/package.json +2 -2
  232. package/packages/mcp-server/dist/index.d.ts +3 -0
  233. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  234. package/packages/mcp-server/dist/index.js +3 -0
  235. package/packages/mcp-server/dist/index.js.map +1 -1
  236. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  237. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  238. package/packages/mcp-server/dist/readers/graph.js +655 -0
  239. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  240. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  241. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  242. package/packages/mcp-server/dist/readers/index.js +1 -0
  243. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  244. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  245. package/packages/mcp-server/dist/server.js +65 -0
  246. package/packages/mcp-server/dist/server.js.map +1 -1
  247. package/packages/mcp-server/package.json +2 -2
  248. package/packages/mcp-server/src/index.ts +15 -0
  249. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  250. package/packages/mcp-server/src/readers/graph.ts +855 -0
  251. package/packages/mcp-server/src/readers/index.ts +12 -0
  252. package/packages/mcp-server/src/server.ts +83 -0
  253. package/packages/mcp-server/tsconfig.json +1 -0
  254. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  255. package/packages/native/package.json +2 -2
  256. package/packages/native/tsconfig.tsbuildinfo +1 -0
  257. package/packages/pi-agent-core/package.json +1 -1
  258. package/packages/pi-agent-core/tsconfig.json +1 -0
  259. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  260. package/packages/pi-ai/dist/index.d.ts +1 -0
  261. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  262. package/packages/pi-ai/dist/index.js +1 -0
  263. package/packages/pi-ai/dist/index.js.map +1 -1
  264. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  265. package/packages/pi-ai/dist/utils/overflow.js +12 -0
  266. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  267. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts +2 -0
  268. package/packages/pi-ai/dist/utils/tests/overflow.test.d.ts.map +1 -0
  269. package/packages/pi-ai/dist/utils/tests/overflow.test.js +50 -0
  270. package/packages/pi-ai/dist/utils/tests/overflow.test.js.map +1 -0
  271. package/packages/pi-ai/package.json +1 -1
  272. package/packages/pi-ai/src/index.ts +4 -0
  273. package/packages/pi-ai/src/utils/overflow.ts +14 -1
  274. package/packages/pi-ai/src/utils/tests/overflow.test.ts +58 -0
  275. package/packages/pi-ai/tsconfig.json +1 -0
  276. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  277. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +571 -8
  278. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/compaction/utils.js +5 -5
  280. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts +2 -0
  282. package/packages/pi-coding-agent/dist/core/compaction-utils.test.d.ts.map +1 -0
  283. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +45 -0
  284. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -0
  285. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  287. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  288. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  289. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  291. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +12 -2
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +65 -28
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +2 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +9 -3
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts +2 -0
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.d.ts.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +52 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +201 -20
  306. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +13 -0
  312. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +59 -6
  314. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  315. package/packages/pi-coding-agent/package.json +1 -1
  316. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +694 -8
  317. package/packages/pi-coding-agent/src/core/compaction/utils.ts +5 -5
  318. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +50 -0
  319. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  320. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  321. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +78 -32
  322. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +73 -0
  323. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +9 -3
  324. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +238 -25
  325. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  326. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +79 -6
  327. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  328. package/packages/pi-coding-agent/tsconfig.json +3 -2
  329. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  330. package/packages/pi-tui/dist/__tests__/tui.test.js +60 -1
  331. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  332. package/packages/pi-tui/dist/tui.d.ts +8 -0
  333. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  334. package/packages/pi-tui/dist/tui.js +32 -3
  335. package/packages/pi-tui/dist/tui.js.map +1 -1
  336. package/packages/pi-tui/package.json +1 -1
  337. package/packages/pi-tui/src/__tests__/tui.test.ts +76 -1
  338. package/packages/pi-tui/src/tui.ts +31 -3
  339. package/packages/pi-tui/tsconfig.json +1 -0
  340. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  341. package/packages/rpc-client/package.json +1 -1
  342. package/packages/rpc-client/tsconfig.json +1 -0
  343. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  344. package/pkg/package.json +1 -1
  345. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +107 -5
  346. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +111 -2
  347. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  348. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  349. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  350. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  351. package/src/resources/extensions/gsd/auto/phases.ts +213 -13
  352. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  353. package/src/resources/extensions/gsd/auto-dispatch.ts +26 -10
  354. package/src/resources/extensions/gsd/auto-model-selection.ts +151 -16
  355. package/src/resources/extensions/gsd/auto-post-unit.ts +278 -16
  356. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  357. package/src/resources/extensions/gsd/auto-start.ts +30 -6
  358. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +17 -0
  359. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  360. package/src/resources/extensions/gsd/auto-verification.ts +225 -3
  361. package/src/resources/extensions/gsd/auto.ts +72 -16
  362. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -8
  363. package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
  364. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  365. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  366. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  367. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  368. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  369. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  370. package/src/resources/extensions/gsd/commands-handlers.ts +8 -2
  371. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  372. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  373. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  374. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  375. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  376. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  377. package/src/resources/extensions/gsd/docs/preferences-reference.md +15 -2
  378. package/src/resources/extensions/gsd/git-service.ts +68 -0
  379. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  380. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  381. package/src/resources/extensions/gsd/guided-flow.ts +32 -0
  382. package/src/resources/extensions/gsd/index.ts +18 -2
  383. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  384. package/src/resources/extensions/gsd/journal.ts +30 -0
  385. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  386. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  387. package/src/resources/extensions/gsd/metrics.ts +26 -0
  388. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  389. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  390. package/src/resources/extensions/gsd/notification-widget.ts +2 -2
  391. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  392. package/src/resources/extensions/gsd/preferences-models.ts +61 -3
  393. package/src/resources/extensions/gsd/preferences-types.ts +44 -0
  394. package/src/resources/extensions/gsd/preferences-validation.ts +130 -2
  395. package/src/resources/extensions/gsd/preferences.ts +28 -0
  396. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  397. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  398. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  399. package/src/resources/extensions/gsd/state.ts +80 -17
  400. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  401. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +9 -5
  402. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  403. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +53 -0
  404. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  405. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +51 -2
  406. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  407. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  408. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  409. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  410. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  411. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  412. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  413. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  414. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +142 -0
  415. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  416. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  417. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +42 -0
  418. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -2
  419. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +3 -2
  420. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +68 -8
  421. package/src/resources/extensions/gsd/tests/derive-state.test.ts +3 -3
  422. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  423. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  424. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +137 -1
  425. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  426. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  427. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  428. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
  429. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  430. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  431. package/src/resources/extensions/gsd/tests/model-isolation.test.ts +91 -2
  432. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  433. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  434. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  435. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  436. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -0
  437. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  438. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +5 -7
  439. package/src/resources/extensions/gsd/tests/token-profile.test.ts +9 -6
  440. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  441. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  442. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  443. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  444. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  445. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  446. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  447. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  448. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  449. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  450. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +179 -0
  451. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  452. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  453. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  454. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  455. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  456. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  457. package/src/resources/extensions/gsd/types.ts +1 -1
  458. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  459. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  460. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  461. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  462. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  463. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  464. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  465. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  466. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  467. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  468. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  469. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  470. package/src/resources/extensions/gsd/workflow-logger.ts +25 -0
  471. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  472. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  473. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  474. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  475. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  476. package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
  477. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  478. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  479. /package/dist/web/standalone/.next/static/{Qr27MOHx0lxRGnJvlhxxu → C7qugsXHwdw4-b4ROHvOE}/_buildManifest.js +0 -0
  480. /package/dist/web/standalone/.next/static/{Qr27MOHx0lxRGnJvlhxxu → C7qugsXHwdw4-b4ROHvOE}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"dynamic-border.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, TUI } from \"@gsd/pi-tui\";\nimport { visibleWidth } from \"@gsd/pi-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Dynamic border component that adjusts to viewport width.\n * Supports an optional animated spinner in the label area.\n *\n * Note: When used from extensions loaded via jiti, the global `theme` may be undefined\n * because jiti creates a separate module cache. Always pass an explicit color\n * function when using DynamicBorder in components exported for extension use.\n */\nexport class DynamicBorder implements Component {\n\tprivate color: (str: string) => string;\n\tprivate label?: string;\n\tprivate spinnerFrames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\tprivate spinnerIndex = 0;\n\tprivate spinnerInterval: NodeJS.Timeout | null = null;\n\tprivate spinnerColorFn?: (str: string) => string;\n\n\tconstructor(color: (str: string) => string = (str) => {\n\t\ttry { return theme.fg(\"border\", str); } catch { return str; }\n\t}, label?: string) {\n\t\tthis.color = color;\n\t\tthis.label = label;\n\t}\n\n\tsetLabel(label: string | undefined): void {\n\t\tthis.label = label;\n\t}\n\n\t/**\n\t * Start an animated spinner that prepends to the label.\n\t * The spinner rotates every 80ms and triggers a re-render via the TUI.\n\t */\n\tstartSpinner(ui: TUI, colorFn: (str: string) => string): void {\n\t\tthis.stopSpinner();\n\t\tthis.spinnerColorFn = colorFn;\n\t\tthis.spinnerIndex = 0;\n\t\tthis.spinnerInterval = setInterval(() => {\n\t\t\tthis.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n\t\t\tui.requestRender();\n\t\t}, 80);\n\t\tui.requestRender();\n\t}\n\n\t/**\n\t * Stop the spinner animation. The border reverts to a static label.\n\t */\n\tstopSpinner(): void {\n\t\tif (this.spinnerInterval) {\n\t\t\tclearInterval(this.spinnerInterval);\n\t\t\tthis.spinnerInterval = null;\n\t\t}\n\t\tthis.spinnerColorFn = undefined;\n\t}\n\n\tget isSpinning(): boolean {\n\t\treturn this.spinnerInterval !== null;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tconst spinnerPrefix = this.spinnerInterval && this.spinnerColorFn\n\t\t\t? this.spinnerColorFn(this.spinnerFrames[this.spinnerIndex]) + \" \"\n\t\t\t: \"\";\n\n\t\tif (this.label) {\n\t\t\tconst labelText = ` ${spinnerPrefix}${this.label} `;\n\t\t\tconst labelVisible = visibleWidth(labelText);\n\t\t\tconst leading = \"── \";\n\t\t\tconst remaining = Math.max(0, width - labelVisible - leading.length);\n\t\t\tconst trailing = \"─\".repeat(Math.max(1, remaining));\n\t\t\t// Color leading and trailing separately so embedded ANSI in the\n\t\t\t// spinner/label doesn't bleed into the trailing dashes.\n\t\t\treturn [this.color(leading) + labelText + this.color(trailing)];\n\t\t}\n\t\treturn [this.color(\"─\".repeat(Math.max(1, width)))];\n\t}\n}\n"]}
1
+ {"version":3,"file":"dynamic-border.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Component, TUI } from \"@gsd/pi-tui\";\nimport { visibleWidth } from \"@gsd/pi-tui\";\nimport { theme } from \"../theme/theme.js\";\n\n/**\n * Dynamic border component that adjusts to viewport width.\n * Supports an optional animated spinner in the label area.\n *\n * Note: When used from extensions loaded via jiti, the global `theme` may be undefined\n * because jiti creates a separate module cache. Always pass an explicit color\n * function when using DynamicBorder in components exported for extension use.\n */\nexport class DynamicBorder implements Component {\n\tprivate color: (str: string) => string;\n\tprivate label?: string;\n\tprivate spinnerFrames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n\tprivate spinnerIndex = 0;\n\tprivate spinnerInterval: NodeJS.Timeout | null = null;\n\tprivate spinnerColorFn?: (str: string) => string;\n\tprivate lastExternalRender = 0;\n\n\tconstructor(color: (str: string) => string = (str) => {\n\t\ttry { return theme.fg(\"border\", str); } catch { return str; }\n\t}, label?: string) {\n\t\tthis.color = color;\n\t\tthis.label = label;\n\t}\n\n\tsetLabel(label: string | undefined): void {\n\t\tthis.label = label;\n\t}\n\n\t/**\n\t * Start an animated spinner that prepends to the label.\n\t * The spinner rotates every 200ms and triggers a re-render via the TUI.\n\t */\n\tstartSpinner(ui: TUI, colorFn: (str: string) => string): void {\n\t\tthis.stopSpinner();\n\t\tthis.spinnerColorFn = colorFn;\n\t\tthis.spinnerIndex = 0;\n\t\tthis.spinnerInterval = setInterval(() => {\n\t\t\tthis.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;\n\t\t\t// Only trigger standalone render if no other source rendered recently.\n\t\t\t// During active streaming, message_update already calls requestRender().\n\t\t\tif (Date.now() - this.lastExternalRender > 200) {\n\t\t\t\tui.requestRender();\n\t\t\t}\n\t\t}, 200);\n\t\tui.requestRender();\n\t}\n\n\t/**\n\t * Stop the spinner animation. The border reverts to a static label.\n\t */\n\tstopSpinner(): void {\n\t\tif (this.spinnerInterval) {\n\t\t\tclearInterval(this.spinnerInterval);\n\t\t\tthis.spinnerInterval = null;\n\t\t}\n\t\tthis.spinnerColorFn = undefined;\n\t}\n\n\tget isSpinning(): boolean {\n\t\treturn this.spinnerInterval !== null;\n\t}\n\n\tinvalidate(): void {\n\t\t// No cached state to invalidate currently\n\t}\n\n\trender(width: number): string[] {\n\t\tthis.lastExternalRender = Date.now();\n\t\tconst spinnerPrefix = this.spinnerInterval && this.spinnerColorFn\n\t\t\t? this.spinnerColorFn(this.spinnerFrames[this.spinnerIndex]) + \" \"\n\t\t\t: \"\";\n\n\t\tif (this.label) {\n\t\t\tconst labelText = ` ${spinnerPrefix}${this.label} `;\n\t\t\tconst labelVisible = visibleWidth(labelText);\n\t\t\tconst leading = \"── \";\n\t\t\tconst remaining = Math.max(0, width - labelVisible - leading.length);\n\t\t\tconst trailing = \"─\".repeat(Math.max(1, remaining));\n\t\t\t// Color leading and trailing separately so embedded ANSI in the\n\t\t\t// spinner/label doesn't bleed into the trailing dashes.\n\t\t\treturn [this.color(leading) + labelText + this.color(trailing)];\n\t\t}\n\t\treturn [this.color(\"─\".repeat(Math.max(1, width)))];\n\t}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dynamic-border.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-border.test.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it } from "node:test";
3
+ import { DynamicBorder } from "./dynamic-border.js";
4
+ function makeTUI() {
5
+ return {
6
+ renderCount: 0,
7
+ requestRender() {
8
+ this.renderCount++;
9
+ },
10
+ };
11
+ }
12
+ describe("DynamicBorder spinner", () => {
13
+ it("suppresses standalone render when an external render occurred recently", () => {
14
+ const border = new DynamicBorder((s) => s);
15
+ const tui = makeTUI();
16
+ border.startSpinner(tui, (s) => s);
17
+ // startSpinner calls requestRender once immediately
18
+ assert.equal(tui.renderCount, 1, "initial render on startSpinner");
19
+ // Simulate an externally-triggered render (e.g. from streaming)
20
+ border.render(80);
21
+ // Access the private interval callback by advancing the timer
22
+ // Instead, we directly test the render-batching logic:
23
+ // After render() sets lastExternalRender, a spinner tick within 200ms
24
+ // should NOT call requestRender.
25
+ const anyBorder = border;
26
+ assert.ok(Date.now() - anyBorder.lastExternalRender < 200, "lastExternalRender should be recent after render()");
27
+ border.stopSpinner();
28
+ });
29
+ it("triggers standalone render when no external render occurred recently", async () => {
30
+ const border = new DynamicBorder((s) => s);
31
+ const tui = makeTUI();
32
+ // Set lastExternalRender to a time well in the past
33
+ const anyBorder = border;
34
+ anyBorder.lastExternalRender = 0;
35
+ border.startSpinner(tui, (s) => s);
36
+ const initialCount = tui.renderCount;
37
+ // Wait for one spinner tick (200ms interval + buffer)
38
+ await new Promise((r) => setTimeout(r, 250));
39
+ assert.ok(tui.renderCount > initialCount, "spinner should trigger requestRender when no recent external render");
40
+ border.stopSpinner();
41
+ });
42
+ it("updates lastExternalRender on each render() call", () => {
43
+ const border = new DynamicBorder((s) => s);
44
+ const anyBorder = border;
45
+ const before = Date.now();
46
+ border.render(80);
47
+ const after = Date.now();
48
+ assert.ok(anyBorder.lastExternalRender >= before);
49
+ assert.ok(anyBorder.lastExternalRender <= after);
50
+ });
51
+ });
52
+ //# sourceMappingURL=dynamic-border.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-border.test.js","sourceRoot":"","sources":["../../../../src/modes/interactive/components/dynamic-border.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAQ,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,SAAS,OAAO;IACf,OAAO;QACN,WAAW,EAAE,CAAC;QACd,aAAa;YACZ,IAAI,CAAC,WAAW,EAAE,CAAC;QACpB,CAAC;KACD,CAAC;AACH,CAAC;AAED,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QACjF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QAEtB,MAAM,CAAC,YAAY,CAAC,GAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,oDAAoD;QACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,gCAAgC,CAAC,CAAC;QAEnE,gEAAgE;QAChE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAElB,8DAA8D;QAC9D,uDAAuD;QACvD,sEAAsE;QACtE,iCAAiC;QACjC,MAAM,SAAS,GAAG,MAAa,CAAC;QAChC,MAAM,CAAC,EAAE,CACR,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,kBAAkB,GAAG,GAAG,EAC/C,oDAAoD,CACpD,CAAC;QAEF,MAAM,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;QAEtB,oDAAoD;QACpD,MAAM,SAAS,GAAG,MAAa,CAAC;QAChC,SAAS,CAAC,kBAAkB,GAAG,CAAC,CAAC;QAEjC,MAAM,CAAC,YAAY,CAAC,GAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,WAAW,CAAC;QAErC,sDAAsD;QACtD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAE7C,MAAM,CAAC,EAAE,CACR,GAAG,CAAC,WAAW,GAAG,YAAY,EAC9B,qEAAqE,CACrE,CAAC;QAEF,MAAM,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC3D,MAAM,MAAM,GAAG,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,SAAS,GAAG,MAAa,CAAC;QAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,kBAAkB,IAAI,MAAM,CAAC,CAAC;QAClD,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport { describe, it, mock } from \"node:test\";\n\nimport { DynamicBorder } from \"./dynamic-border.js\";\n\nfunction makeTUI() {\n\treturn {\n\t\trenderCount: 0,\n\t\trequestRender() {\n\t\t\tthis.renderCount++;\n\t\t},\n\t};\n}\n\ndescribe(\"DynamicBorder spinner\", () => {\n\tit(\"suppresses standalone render when an external render occurred recently\", () => {\n\t\tconst border = new DynamicBorder((s) => s);\n\t\tconst tui = makeTUI();\n\n\t\tborder.startSpinner(tui as any, (s) => s);\n\t\t// startSpinner calls requestRender once immediately\n\t\tassert.equal(tui.renderCount, 1, \"initial render on startSpinner\");\n\n\t\t// Simulate an externally-triggered render (e.g. from streaming)\n\t\tborder.render(80);\n\n\t\t// Access the private interval callback by advancing the timer\n\t\t// Instead, we directly test the render-batching logic:\n\t\t// After render() sets lastExternalRender, a spinner tick within 200ms\n\t\t// should NOT call requestRender.\n\t\tconst anyBorder = border as any;\n\t\tassert.ok(\n\t\t\tDate.now() - anyBorder.lastExternalRender < 200,\n\t\t\t\"lastExternalRender should be recent after render()\",\n\t\t);\n\n\t\tborder.stopSpinner();\n\t});\n\n\tit(\"triggers standalone render when no external render occurred recently\", async () => {\n\t\tconst border = new DynamicBorder((s) => s);\n\t\tconst tui = makeTUI();\n\n\t\t// Set lastExternalRender to a time well in the past\n\t\tconst anyBorder = border as any;\n\t\tanyBorder.lastExternalRender = 0;\n\n\t\tborder.startSpinner(tui as any, (s) => s);\n\t\tconst initialCount = tui.renderCount;\n\n\t\t// Wait for one spinner tick (200ms interval + buffer)\n\t\tawait new Promise((r) => setTimeout(r, 250));\n\n\t\tassert.ok(\n\t\t\ttui.renderCount > initialCount,\n\t\t\t\"spinner should trigger requestRender when no recent external render\",\n\t\t);\n\n\t\tborder.stopSpinner();\n\t});\n\n\tit(\"updates lastExternalRender on each render() call\", () => {\n\t\tconst border = new DynamicBorder((s) => s);\n\t\tconst anyBorder = border as any;\n\n\t\tconst before = Date.now();\n\t\tborder.render(80);\n\t\tconst after = Date.now();\n\n\t\tassert.ok(anyBorder.lastExternalRender >= before);\n\t\tassert.ok(anyBorder.lastExternalRender <= after);\n\t});\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"chat-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/controllers/chat-controller.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AA0BnG,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAgBxE;AAWD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,wBAAwB,GAAG;IACvE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,4BAA4B,EAAE,MAAM,GAAG,CAAC;IACxC,gBAAgB,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACxD,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;IACpD,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,CAAC;IACvD,sBAAsB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,oBAAoB,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,4BAA4B,EAAE,MAAM,IAAI,CAAC;IACzC,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,wBAAwB,EAAE;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAChD,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsf7C"}
1
+ {"version":3,"file":"chat-controller.d.ts","sourceRoot":"","sources":["../../../../src/modes/interactive/controllers/chat-controller.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AA+CnG,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAgBxE;AAWD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,wBAAwB,GAAG;IACvE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,4BAA4B,EAAE,MAAM,GAAG,CAAC;IACxC,gBAAgB,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IACxD,qBAAqB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;IACpD,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,CAAC;IACvD,sBAAsB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,oBAAoB,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,4BAA4B,EAAE,MAAM,IAAI,CAAC;IACzC,mBAAmB,EAAE,MAAM,IAAI,CAAC;IAChC,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,wBAAwB,EAAE;QAAE,KAAK,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;CAChD,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsrB7C"}
@@ -6,6 +6,14 @@ import { DynamicBorder } from "../components/dynamic-border.js";
6
6
  import { appKey } from "../components/keybinding-hints.js";
7
7
  // Tracks the last processed content index to avoid re-scanning all blocks on every message_update
8
8
  let lastProcessedContentIndex = 0;
9
+ // Tracks the previous content[] length so we can detect when an adapter resets
10
+ // the assistant content array for a new provider sub-turn within one lifecycle.
11
+ let lastContentLength = 0;
12
+ let renderedSegments = [];
13
+ // When providers reuse one assistant lifecycle across internal sub-turns,
14
+ // a content[] shrink resets renderedSegments. Keep the displaced segments so
15
+ // claude-code MCP pruning can remove stale provisional text later.
16
+ let orphanedSegments = [];
9
17
  function hasVisibleAssistantContent(message) {
10
18
  return message.content.some((c) => (c.type === "text" && typeof c.text === "string" && c.text.trim().length > 0)
11
19
  || (c.type === "thinking" && typeof c.thinking === "string" && c.thinking.trim().length > 0));
@@ -50,8 +58,11 @@ export async function handleAgentEvent(host, event) {
50
58
  // Reset content index tracker and pinned state when a new assistant message starts
51
59
  if (event.type === "message_start" && event.message.role === "assistant") {
52
60
  lastProcessedContentIndex = 0;
61
+ lastContentLength = 0;
53
62
  lastPinnedText = "";
54
63
  hasToolsInTurn = false;
64
+ renderedSegments = [];
65
+ orphanedSegments = [];
55
66
  if (pinnedBorder)
56
67
  pinnedBorder.stopSpinner();
57
68
  pinnedBorder = undefined;
@@ -71,6 +82,9 @@ export async function handleAgentEvent(host, event) {
71
82
  host.pinnedMessageContainer.clear();
72
83
  lastPinnedText = "";
73
84
  hasToolsInTurn = false;
85
+ renderedSegments = [];
86
+ orphanedSegments = [];
87
+ lastContentLength = 0;
74
88
  if (pinnedBorder)
75
89
  pinnedBorder.stopSpinner();
76
90
  pinnedBorder = undefined;
@@ -167,12 +181,24 @@ export async function handleAgentEvent(host, event) {
167
181
  }
168
182
  }
169
183
  const contentBlocks = host.streamingMessage.content;
170
- // Some adapters reuse a single assistant lifecycle while internally
171
- // spanning multiple provider turns. When a new turn starts, content
172
- // length can shrink back to 0/1; reset scan index to avoid skipping.
173
- if (lastProcessedContentIndex >= contentBlocks.length) {
184
+ // Some adapters (notably claude-code) reuse a single assistant
185
+ // lifecycle while internally spanning multiple provider sub-turns.
186
+ // When a new sub-turn starts, content[] length shrinks back to 0/1.
187
+ // The scan loop needs its index reset, AND the segment walker's
188
+ // renderedSegments map must be cleared so existing text-run
189
+ // components don't get overwritten in place with new sub-turn
190
+ // content (#4144 regression). Prior sub-turn children stay in
191
+ // chatContainer as frozen history; new segments append after them.
192
+ if (contentBlocks.length < lastContentLength) {
193
+ orphanedSegments = [...renderedSegments];
194
+ renderedSegments = [];
195
+ lastPinnedText = "";
196
+ lastProcessedContentIndex = 0;
197
+ }
198
+ else if (lastProcessedContentIndex >= contentBlocks.length) {
174
199
  lastProcessedContentIndex = 0;
175
200
  }
201
+ lastContentLength = contentBlocks.length;
176
202
  for (let i = lastProcessedContentIndex; i < contentBlocks.length; i++) {
177
203
  const content = contentBlocks[i];
178
204
  if (content.type === "toolCall") {
@@ -228,19 +254,166 @@ export async function handleAgentEvent(host, event) {
228
254
  });
229
255
  }
230
256
  }
231
- // Render assistant text/thinking after tool components so mixed
232
- // streams keep chronological ordering in the chat container.
233
- const hasToolBlocks = hasAssistantToolBlocks(host.streamingMessage);
234
- if (!host.streamingComponent && hasVisibleAssistantContent(host.streamingMessage)) {
235
- host.streamingComponent = new AssistantMessageComponent(undefined, host.hideThinkingBlock, host.getMarkdownThemeWithSettings(), host.settingsManager.getTimestampFormat());
236
- host.chatContainer.addChild(host.streamingComponent);
237
- }
238
- if (host.streamingComponent) {
239
- if (hasToolBlocks) {
240
- host.chatContainer.removeChild(host.streamingComponent);
241
- host.chatContainer.addChild(host.streamingComponent);
257
+ // Segment walker: render content blocks in stream order, append-only.
258
+ // Build desired segment plan from content[].
259
+ {
260
+ const blocks = host.streamingMessage.content;
261
+ const isClaudeCodeProvider = host.streamingMessage.provider === "claude-code";
262
+ const hasMcpToolBlock = blocks.some((b) => {
263
+ if (b?.type === "toolCall") {
264
+ return typeof b?.mcpServer === "string" || String(b?.name ?? "").startsWith("mcp__");
265
+ }
266
+ if (b?.type === "serverToolUse") {
267
+ return typeof b?.mcpServer === "string" || String(b?.name ?? "").startsWith("mcp__");
268
+ }
269
+ return false;
270
+ });
271
+ const firstToolIdx = blocks.findIndex((b) => b.type === "toolCall" || b.type === "serverToolUse");
272
+ const hasPostToolText = firstToolIdx >= 0
273
+ && blocks.some((b, idx) => (idx > firstToolIdx
274
+ && b?.type === "text"
275
+ && typeof b?.text === "string"
276
+ && b.text.trim().length > 0));
277
+ // Only prune provisional pre-tool prose after post-tool prose exists,
278
+ // so MCP tool-only windows do not blank the assistant content.
279
+ const shouldDropPreToolProse = isClaudeCodeProvider && hasMcpToolBlock && hasPostToolText;
280
+ const desired = [];
281
+ let runStart = -1;
282
+ let runEnd = -1;
283
+ let runType;
284
+ const closeRun = () => {
285
+ if (runStart !== -1 && runType) {
286
+ desired.push({ kind: "text-run", startIndex: runStart, endIndex: runEnd, contentType: runType });
287
+ runStart = -1;
288
+ runEnd = -1;
289
+ runType = undefined;
290
+ }
291
+ };
292
+ for (let i = 0; i < blocks.length; i++) {
293
+ const b = blocks[i];
294
+ const blockType = b.type === "text" || b.type === "thinking" ? b.type : undefined;
295
+ const isTextLike = blockType === "text" || blockType === "thinking";
296
+ const isTool = b.type === "toolCall" || b.type === "serverToolUse";
297
+ // For Claude Code MCP turns, prune only pre-tool prose, never thinking.
298
+ const shouldSkipProse = shouldDropPreToolProse && firstToolIdx >= 0 && i < firstToolIdx && blockType === "text";
299
+ if (shouldSkipProse) {
300
+ closeRun();
301
+ continue;
302
+ }
303
+ if (isTextLike) {
304
+ if (runStart === -1) {
305
+ runStart = i;
306
+ runEnd = i;
307
+ runType = blockType;
308
+ }
309
+ else if (runType !== blockType) {
310
+ closeRun();
311
+ runStart = i;
312
+ runEnd = i;
313
+ runType = blockType;
314
+ }
315
+ else {
316
+ runEnd = i;
317
+ }
318
+ }
319
+ else {
320
+ closeRun();
321
+ if (isTool) {
322
+ desired.push({ kind: "tool", contentIndex: i, toolId: b.id });
323
+ }
324
+ }
325
+ }
326
+ closeRun();
327
+ // Claude Code MCP can emit provisional pre-tool prose that gets
328
+ // superseded by post-tool output. Prune stale text-run segments so
329
+ // the final assistant output remains below tool output.
330
+ if (shouldDropPreToolProse && firstToolIdx >= 0) {
331
+ if (orphanedSegments.length > 0) {
332
+ const remainingOrphans = [];
333
+ for (const orphan of orphanedSegments) {
334
+ if (orphan.kind === "text-run" && orphan.contentType === "text") {
335
+ host.chatContainer.removeChild(orphan.component);
336
+ if (host.streamingComponent === orphan.component) {
337
+ host.streamingComponent = undefined;
338
+ }
339
+ continue;
340
+ }
341
+ remainingOrphans.push(orphan);
342
+ }
343
+ orphanedSegments = remainingOrphans;
344
+ }
345
+ const desiredTextKeys = new Set(desired
346
+ .filter((seg) => seg.kind === "text-run")
347
+ .map((seg) => `${seg.contentType}:${seg.startIndex}`));
348
+ const desiredToolIndices = new Set(desired
349
+ .filter((seg) => seg.kind === "tool")
350
+ .map((seg) => seg.contentIndex));
351
+ const nextRendered = [];
352
+ for (const seg of renderedSegments) {
353
+ if (seg.kind === "text-run"
354
+ && seg.contentType === "text"
355
+ && !desiredTextKeys.has(`${seg.contentType}:${seg.startIndex}`)) {
356
+ host.chatContainer.removeChild(seg.component);
357
+ if (host.streamingComponent === seg.component) {
358
+ host.streamingComponent = undefined;
359
+ }
360
+ continue;
361
+ }
362
+ if (seg.kind === "tool" && !desiredToolIndices.has(seg.contentIndex)) {
363
+ continue;
364
+ }
365
+ nextRendered.push(seg);
366
+ }
367
+ renderedSegments = nextRendered;
368
+ }
369
+ // Append any newly needed segments (never reorder existing ones).
370
+ for (const seg of desired) {
371
+ if (seg.kind === "tool") {
372
+ // Tool segments are already handled above via pendingTools; just
373
+ // register them in renderedSegments if not yet tracked.
374
+ const existing = renderedSegments.find((s) => s.kind === "tool" && s.contentIndex === seg.contentIndex);
375
+ if (!existing) {
376
+ const comp = host.pendingTools.get(seg.toolId);
377
+ if (comp) {
378
+ renderedSegments.push({ kind: "tool", contentIndex: seg.contentIndex, component: comp });
379
+ }
380
+ }
381
+ }
382
+ else {
383
+ // text-run segment
384
+ const existing = renderedSegments.find((s) => s.kind === "text-run" && s.startIndex === seg.startIndex && s.contentType === seg.contentType);
385
+ if (!existing) {
386
+ const comp = new AssistantMessageComponent(undefined, host.hideThinkingBlock, host.getMarkdownThemeWithSettings(), host.settingsManager.getTimestampFormat(), { startIndex: seg.startIndex, endIndex: seg.endIndex });
387
+ host.chatContainer.addChild(comp);
388
+ renderedSegments.push({
389
+ kind: "text-run",
390
+ startIndex: seg.startIndex,
391
+ endIndex: seg.endIndex,
392
+ contentType: seg.contentType,
393
+ component: comp,
394
+ });
395
+ host.streamingComponent = comp;
396
+ }
397
+ }
398
+ }
399
+ // Update all trailing text-run segments with the latest message so
400
+ // streaming text grows in place.
401
+ for (const seg of renderedSegments) {
402
+ if (seg.kind === "text-run") {
403
+ // Find corresponding desired segment to get current endIndex
404
+ const d = desired.find((ds) => ds.kind === "text-run" && ds.startIndex === seg.startIndex && ds.contentType === seg.contentType);
405
+ if (d && d.kind === "text-run" && d.endIndex !== seg.endIndex) {
406
+ seg.endIndex = d.endIndex;
407
+ seg.component.setRange({ startIndex: seg.startIndex, endIndex: seg.endIndex });
408
+ }
409
+ seg.component.updateContent(host.streamingMessage);
410
+ }
411
+ }
412
+ // Keep streamingComponent pointing at the last text-run for message_end compatibility.
413
+ const lastTextSeg = [...renderedSegments].reverse().find((s) => s.kind === "text-run");
414
+ if (lastTextSeg && lastTextSeg.kind === "text-run") {
415
+ host.streamingComponent = lastTextSeg.component;
242
416
  }
243
- host.streamingComponent.updateContent(host.streamingMessage);
244
417
  }
245
418
  // Update index: fully processed blocks won't need re-scanning.
246
419
  // Keep the last block's index (it may still be accumulating data),
@@ -309,6 +482,7 @@ export async function handleAgentEvent(host, event) {
309
482
  host.chatContainer.addChild(host.streamingComponent);
310
483
  }
311
484
  if (host.streamingComponent) {
485
+ host.streamingComponent.setShowMetadata(true);
312
486
  host.streamingComponent.updateContent(host.streamingMessage);
313
487
  }
314
488
  if (host.streamingMessage.stopReason === "aborted" || host.streamingMessage.stopReason === "error") {
@@ -332,6 +506,9 @@ export async function handleAgentEvent(host, event) {
332
506
  }
333
507
  host.streamingComponent = undefined;
334
508
  host.streamingMessage = undefined;
509
+ renderedSegments = [];
510
+ orphanedSegments = [];
511
+ lastContentLength = 0;
335
512
  // Clear pinned output once the message is finalized in the chat
336
513
  // container — prevents duplicate display when the agent continues
337
514
  // (e.g. form elicitation) after the assistant message ends.
@@ -378,11 +555,15 @@ export async function handleAgentEvent(host, event) {
378
555
  host.loadingAnimation = undefined;
379
556
  host.statusContainer.clear();
380
557
  }
381
- if (host.streamingComponent) {
382
- host.chatContainer.removeChild(host.streamingComponent);
383
- host.streamingComponent = undefined;
384
- host.streamingMessage = undefined;
558
+ if (host.streamingComponent && host.streamingMessage) {
559
+ host.streamingComponent.setShowMetadata(true);
560
+ host.streamingComponent.updateContent(host.streamingMessage);
385
561
  }
562
+ host.streamingComponent = undefined;
563
+ host.streamingMessage = undefined;
564
+ renderedSegments = [];
565
+ orphanedSegments = [];
566
+ lastContentLength = 0;
386
567
  host.pendingTools.clear();
387
568
  // Pinned output is only useful while work is actively streaming.
388
569
  // Keep chat history as the single source after completion.