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
@@ -10,6 +10,27 @@ import { appKey } from "../components/keybinding-hints.js";
10
10
  // Tracks the last processed content index to avoid re-scanning all blocks on every message_update
11
11
  let lastProcessedContentIndex = 0;
12
12
 
13
+ // Tracks the previous content[] length so we can detect when an adapter resets
14
+ // the assistant content array for a new provider sub-turn within one lifecycle.
15
+ let lastContentLength = 0;
16
+
17
+ // --- Segment walker state (per streaming assistant turn) ---
18
+ type RenderedSegment =
19
+ | {
20
+ kind: "text-run";
21
+ startIndex: number;
22
+ endIndex: number;
23
+ contentType: "text" | "thinking";
24
+ component: AssistantMessageComponent;
25
+ }
26
+ | { kind: "tool"; contentIndex: number; component: ToolExecutionComponent };
27
+
28
+ let renderedSegments: RenderedSegment[] = [];
29
+ // When providers reuse one assistant lifecycle across internal sub-turns,
30
+ // a content[] shrink resets renderedSegments. Keep the displaced segments so
31
+ // claude-code MCP pruning can remove stale provisional text later.
32
+ let orphanedSegments: RenderedSegment[] = [];
33
+
13
34
  function hasVisibleAssistantContent(message: { content: Array<any> }): boolean {
14
35
  return message.content.some(
15
36
  (c) =>
@@ -78,8 +99,11 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
78
99
  // Reset content index tracker and pinned state when a new assistant message starts
79
100
  if (event.type === "message_start" && event.message.role === "assistant") {
80
101
  lastProcessedContentIndex = 0;
102
+ lastContentLength = 0;
81
103
  lastPinnedText = "";
82
104
  hasToolsInTurn = false;
105
+ renderedSegments = [];
106
+ orphanedSegments = [];
83
107
  if (pinnedBorder) pinnedBorder.stopSpinner();
84
108
  pinnedBorder = undefined;
85
109
  pinnedTextComponent = undefined;
@@ -99,6 +123,9 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
99
123
  host.pinnedMessageContainer.clear();
100
124
  lastPinnedText = "";
101
125
  hasToolsInTurn = false;
126
+ renderedSegments = [];
127
+ orphanedSegments = [];
128
+ lastContentLength = 0;
102
129
  if (pinnedBorder) pinnedBorder.stopSpinner();
103
130
  pinnedBorder = undefined;
104
131
  pinnedTextComponent = undefined;
@@ -202,12 +229,23 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
202
229
  }
203
230
 
204
231
  const contentBlocks = host.streamingMessage.content;
205
- // Some adapters reuse a single assistant lifecycle while internally
206
- // spanning multiple provider turns. When a new turn starts, content
207
- // length can shrink back to 0/1; reset scan index to avoid skipping.
208
- if (lastProcessedContentIndex >= contentBlocks.length) {
232
+ // Some adapters (notably claude-code) reuse a single assistant
233
+ // lifecycle while internally spanning multiple provider sub-turns.
234
+ // When a new sub-turn starts, content[] length shrinks back to 0/1.
235
+ // The scan loop needs its index reset, AND the segment walker's
236
+ // renderedSegments map must be cleared so existing text-run
237
+ // components don't get overwritten in place with new sub-turn
238
+ // content (#4144 regression). Prior sub-turn children stay in
239
+ // chatContainer as frozen history; new segments append after them.
240
+ if (contentBlocks.length < lastContentLength) {
241
+ orphanedSegments = [...renderedSegments];
242
+ renderedSegments = [];
243
+ lastPinnedText = "";
244
+ lastProcessedContentIndex = 0;
245
+ } else if (lastProcessedContentIndex >= contentBlocks.length) {
209
246
  lastProcessedContentIndex = 0;
210
247
  }
248
+ lastContentLength = contentBlocks.length;
211
249
  for (let i = lastProcessedContentIndex; i < contentBlocks.length; i++) {
212
250
  const content = contentBlocks[i];
213
251
  if (content.type === "toolCall") {
@@ -273,24 +311,191 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
273
311
  }
274
312
  }
275
313
 
276
- // Render assistant text/thinking after tool components so mixed
277
- // streams keep chronological ordering in the chat container.
278
- const hasToolBlocks = hasAssistantToolBlocks(host.streamingMessage);
279
- if (!host.streamingComponent && hasVisibleAssistantContent(host.streamingMessage)) {
280
- host.streamingComponent = new AssistantMessageComponent(
281
- undefined,
282
- host.hideThinkingBlock,
283
- host.getMarkdownThemeWithSettings(),
284
- host.settingsManager.getTimestampFormat(),
285
- );
286
- host.chatContainer.addChild(host.streamingComponent);
287
- }
288
- if (host.streamingComponent) {
289
- if (hasToolBlocks) {
290
- host.chatContainer.removeChild(host.streamingComponent);
291
- host.chatContainer.addChild(host.streamingComponent);
314
+ // Segment walker: render content blocks in stream order, append-only.
315
+ // Build desired segment plan from content[].
316
+ {
317
+ const blocks = host.streamingMessage.content;
318
+ const isClaudeCodeProvider = host.streamingMessage.provider === "claude-code";
319
+ const hasMcpToolBlock = blocks.some((b: any) => {
320
+ if (b?.type === "toolCall") {
321
+ return typeof b?.mcpServer === "string" || String(b?.name ?? "").startsWith("mcp__");
322
+ }
323
+ if (b?.type === "serverToolUse") {
324
+ return typeof b?.mcpServer === "string" || String(b?.name ?? "").startsWith("mcp__");
325
+ }
326
+ return false;
327
+ });
328
+ const firstToolIdx = blocks.findIndex((b: any) => b.type === "toolCall" || b.type === "serverToolUse");
329
+ const hasPostToolText = firstToolIdx >= 0
330
+ && blocks.some(
331
+ (b: any, idx: number) => (
332
+ idx > firstToolIdx
333
+ && b?.type === "text"
334
+ && typeof b?.text === "string"
335
+ && b.text.trim().length > 0
336
+ ),
337
+ );
338
+ // Only prune provisional pre-tool prose after post-tool prose exists,
339
+ // so MCP tool-only windows do not blank the assistant content.
340
+ const shouldDropPreToolProse = isClaudeCodeProvider && hasMcpToolBlock && hasPostToolText;
341
+ type DesiredSegment =
342
+ | { kind: "text-run"; startIndex: number; endIndex: number; contentType: "text" | "thinking" }
343
+ | { kind: "tool"; contentIndex: number; toolId: string };
344
+ const desired: DesiredSegment[] = [];
345
+ let runStart = -1;
346
+ let runEnd = -1;
347
+ let runType: "text" | "thinking" | undefined;
348
+ const closeRun = () => {
349
+ if (runStart !== -1 && runType) {
350
+ desired.push({ kind: "text-run", startIndex: runStart, endIndex: runEnd, contentType: runType });
351
+ runStart = -1;
352
+ runEnd = -1;
353
+ runType = undefined;
354
+ }
355
+ };
356
+ for (let i = 0; i < blocks.length; i++) {
357
+ const b = blocks[i];
358
+ const blockType = b.type === "text" || b.type === "thinking" ? b.type : undefined;
359
+ const isTextLike = blockType === "text" || blockType === "thinking";
360
+ const isTool = b.type === "toolCall" || b.type === "serverToolUse";
361
+ // For Claude Code MCP turns, prune only pre-tool prose, never thinking.
362
+ const shouldSkipProse = shouldDropPreToolProse && firstToolIdx >= 0 && i < firstToolIdx && blockType === "text";
363
+ if (shouldSkipProse) {
364
+ closeRun();
365
+ continue;
366
+ }
367
+ if (isTextLike) {
368
+ if (runStart === -1) {
369
+ runStart = i;
370
+ runEnd = i;
371
+ runType = blockType;
372
+ } else if (runType !== blockType) {
373
+ closeRun();
374
+ runStart = i;
375
+ runEnd = i;
376
+ runType = blockType;
377
+ } else {
378
+ runEnd = i;
379
+ }
380
+ } else {
381
+ closeRun();
382
+ if (isTool) {
383
+ desired.push({ kind: "tool", contentIndex: i, toolId: b.id });
384
+ }
385
+ }
386
+ }
387
+ closeRun();
388
+
389
+ // Claude Code MCP can emit provisional pre-tool prose that gets
390
+ // superseded by post-tool output. Prune stale text-run segments so
391
+ // the final assistant output remains below tool output.
392
+ if (shouldDropPreToolProse && firstToolIdx >= 0) {
393
+ if (orphanedSegments.length > 0) {
394
+ const remainingOrphans: RenderedSegment[] = [];
395
+ for (const orphan of orphanedSegments) {
396
+ if (orphan.kind === "text-run" && orphan.contentType === "text") {
397
+ host.chatContainer.removeChild(orphan.component);
398
+ if (host.streamingComponent === orphan.component) {
399
+ host.streamingComponent = undefined;
400
+ }
401
+ continue;
402
+ }
403
+ remainingOrphans.push(orphan);
404
+ }
405
+ orphanedSegments = remainingOrphans;
406
+ }
407
+ const desiredTextKeys = new Set(
408
+ desired
409
+ .filter((seg): seg is Extract<DesiredSegment, { kind: "text-run" }> => seg.kind === "text-run")
410
+ .map((seg) => `${seg.contentType}:${seg.startIndex}`),
411
+ );
412
+ const desiredToolIndices = new Set(
413
+ desired
414
+ .filter((seg): seg is Extract<DesiredSegment, { kind: "tool" }> => seg.kind === "tool")
415
+ .map((seg) => seg.contentIndex),
416
+ );
417
+ const nextRendered: RenderedSegment[] = [];
418
+ for (const seg of renderedSegments) {
419
+ if (
420
+ seg.kind === "text-run"
421
+ && seg.contentType === "text"
422
+ && !desiredTextKeys.has(`${seg.contentType}:${seg.startIndex}`)
423
+ ) {
424
+ host.chatContainer.removeChild(seg.component);
425
+ if (host.streamingComponent === seg.component) {
426
+ host.streamingComponent = undefined;
427
+ }
428
+ continue;
429
+ }
430
+ if (seg.kind === "tool" && !desiredToolIndices.has(seg.contentIndex)) {
431
+ continue;
432
+ }
433
+ nextRendered.push(seg);
434
+ }
435
+ renderedSegments = nextRendered;
436
+ }
437
+
438
+ // Append any newly needed segments (never reorder existing ones).
439
+ for (const seg of desired) {
440
+ if (seg.kind === "tool") {
441
+ // Tool segments are already handled above via pendingTools; just
442
+ // register them in renderedSegments if not yet tracked.
443
+ const existing = renderedSegments.find(
444
+ (s) => s.kind === "tool" && s.contentIndex === seg.contentIndex,
445
+ );
446
+ if (!existing) {
447
+ const comp = host.pendingTools.get(seg.toolId);
448
+ if (comp) {
449
+ renderedSegments.push({ kind: "tool", contentIndex: seg.contentIndex, component: comp });
450
+ }
451
+ }
452
+ } else {
453
+ // text-run segment
454
+ const existing = renderedSegments.find(
455
+ (s) => s.kind === "text-run" && s.startIndex === seg.startIndex && s.contentType === seg.contentType,
456
+ );
457
+ if (!existing) {
458
+ const comp = new AssistantMessageComponent(
459
+ undefined,
460
+ host.hideThinkingBlock,
461
+ host.getMarkdownThemeWithSettings(),
462
+ host.settingsManager.getTimestampFormat(),
463
+ { startIndex: seg.startIndex, endIndex: seg.endIndex },
464
+ );
465
+ host.chatContainer.addChild(comp);
466
+ renderedSegments.push({
467
+ kind: "text-run",
468
+ startIndex: seg.startIndex,
469
+ endIndex: seg.endIndex,
470
+ contentType: seg.contentType,
471
+ component: comp,
472
+ });
473
+ host.streamingComponent = comp;
474
+ }
475
+ }
476
+ }
477
+
478
+ // Update all trailing text-run segments with the latest message so
479
+ // streaming text grows in place.
480
+ for (const seg of renderedSegments) {
481
+ if (seg.kind === "text-run") {
482
+ // Find corresponding desired segment to get current endIndex
483
+ const d = desired.find(
484
+ (ds) => ds.kind === "text-run" && ds.startIndex === seg.startIndex && ds.contentType === seg.contentType,
485
+ );
486
+ if (d && d.kind === "text-run" && d.endIndex !== seg.endIndex) {
487
+ seg.endIndex = d.endIndex;
488
+ seg.component.setRange({ startIndex: seg.startIndex, endIndex: seg.endIndex });
489
+ }
490
+ seg.component.updateContent(host.streamingMessage);
491
+ }
492
+ }
493
+
494
+ // Keep streamingComponent pointing at the last text-run for message_end compatibility.
495
+ const lastTextSeg = [...renderedSegments].reverse().find((s) => s.kind === "text-run");
496
+ if (lastTextSeg && lastTextSeg.kind === "text-run") {
497
+ host.streamingComponent = lastTextSeg.component;
292
498
  }
293
- host.streamingComponent.updateContent(host.streamingMessage);
294
499
  }
295
500
 
296
501
  // Update index: fully processed blocks won't need re-scanning.
@@ -376,6 +581,7 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
376
581
  host.chatContainer.addChild(host.streamingComponent);
377
582
  }
378
583
  if (host.streamingComponent) {
584
+ host.streamingComponent.setShowMetadata(true);
379
585
  host.streamingComponent.updateContent(host.streamingMessage);
380
586
  }
381
587
 
@@ -399,6 +605,9 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
399
605
  }
400
606
  host.streamingComponent = undefined;
401
607
  host.streamingMessage = undefined;
608
+ renderedSegments = [];
609
+ orphanedSegments = [];
610
+ lastContentLength = 0;
402
611
  // Clear pinned output once the message is finalized in the chat
403
612
  // container — prevents duplicate display when the agent continues
404
613
  // (e.g. form elicitation) after the assistant message ends.
@@ -454,11 +663,15 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
454
663
  host.loadingAnimation = undefined;
455
664
  host.statusContainer.clear();
456
665
  }
457
- if (host.streamingComponent) {
458
- host.chatContainer.removeChild(host.streamingComponent);
459
- host.streamingComponent = undefined;
460
- host.streamingMessage = undefined;
666
+ if (host.streamingComponent && host.streamingMessage) {
667
+ host.streamingComponent.setShowMetadata(true);
668
+ host.streamingComponent.updateContent(host.streamingMessage);
461
669
  }
670
+ host.streamingComponent = undefined;
671
+ host.streamingMessage = undefined;
672
+ renderedSegments = [];
673
+ orphanedSegments = [];
674
+ lastContentLength = 0;
462
675
  host.pendingTools.clear();
463
676
  // Pinned output is only useful while work is actively streaming.
464
677
  // Keep chat history as the single source after completion.
@@ -0,0 +1,44 @@
1
+ import assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+
4
+ import { buildAssistantReplaySegments } from "./interactive-mode.js";
5
+
6
+ test("buildAssistantReplaySegments preserves tool-first ordering", () => {
7
+ const segments = buildAssistantReplaySegments([
8
+ { type: "toolCall", id: "t1", name: "read", arguments: {} },
9
+ { type: "text", text: "Done." },
10
+ ]);
11
+
12
+ assert.deepEqual(segments, [
13
+ { kind: "tool", contentIndex: 0 },
14
+ { kind: "assistant", startIndex: 1, endIndex: 1 },
15
+ ]);
16
+ });
17
+
18
+ test("buildAssistantReplaySegments preserves interleaved assistant-tool-assistant runs", () => {
19
+ const segments = buildAssistantReplaySegments([
20
+ { type: "text", text: "Let me check." },
21
+ { type: "serverToolUse", id: "s1", name: "mcp__fs__glob", input: {} },
22
+ { type: "thinking", thinking: "Tool result looks good." },
23
+ { type: "text", text: "Here is the answer." },
24
+ ]);
25
+
26
+ assert.deepEqual(segments, [
27
+ { kind: "assistant", startIndex: 0, endIndex: 0 },
28
+ { kind: "tool", contentIndex: 1 },
29
+ { kind: "assistant", startIndex: 2, endIndex: 3 },
30
+ ]);
31
+ });
32
+
33
+ test("buildAssistantReplaySegments ignores non-rendered non-tool blocks", () => {
34
+ const segments = buildAssistantReplaySegments([
35
+ { type: "text", text: "before" },
36
+ { type: "webSearchResult", toolUseId: "s1", content: {} },
37
+ { type: "text", text: "after" },
38
+ ]);
39
+
40
+ assert.deepEqual(segments, [
41
+ { kind: "assistant", startIndex: 0, endIndex: 0 },
42
+ { kind: "assistant", startIndex: 2, endIndex: 2 },
43
+ ]);
44
+ });
@@ -127,6 +127,45 @@ function isExpandable(obj: unknown): obj is Expandable {
127
127
  return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
128
128
  }
129
129
 
130
+ export type AssistantReplaySegment =
131
+ | { kind: "assistant"; startIndex: number; endIndex: number }
132
+ | { kind: "tool"; contentIndex: number };
133
+
134
+ /**
135
+ * Build replay segments for historical assistant messages so rebuild paths
136
+ * preserve the original content[] ordering between assistant prose and tools.
137
+ */
138
+ export function buildAssistantReplaySegments(contentBlocks: Array<any>): AssistantReplaySegment[] {
139
+ const segments: AssistantReplaySegment[] = [];
140
+ let runStart = -1;
141
+
142
+ for (let i = 0; i < contentBlocks.length; i++) {
143
+ const block = contentBlocks[i];
144
+ const isAssistantText = block?.type === "text" || block?.type === "thinking";
145
+ const isTool = block?.type === "toolCall" || block?.type === "serverToolUse";
146
+
147
+ if (isAssistantText) {
148
+ if (runStart === -1) runStart = i;
149
+ continue;
150
+ }
151
+
152
+ if (runStart !== -1) {
153
+ segments.push({ kind: "assistant", startIndex: runStart, endIndex: i - 1 });
154
+ runStart = -1;
155
+ }
156
+
157
+ if (isTool) {
158
+ segments.push({ kind: "tool", contentIndex: i });
159
+ }
160
+ }
161
+
162
+ if (runStart !== -1) {
163
+ segments.push({ kind: "assistant", startIndex: runStart, endIndex: contentBlocks.length - 1 });
164
+ }
165
+
166
+ return segments;
167
+ }
168
+
130
169
  type CompactionQueuedMessage = {
131
170
  text: string;
132
171
  mode: "steer" | "followUp";
@@ -1402,7 +1441,9 @@ export class InteractiveMode {
1402
1441
 
1403
1442
  // widgetContainerAbove: spacer collapses when pinned content is visible
1404
1443
  // so there's no extra blank line between pinned output and the editor border.
1405
- this.widgetContainerAbove.clear();
1444
+ // Use detachChildren() (not clear()) — the extensionWidgetsAbove map owns
1445
+ // disposal; clear() would dispose every mounted widget on every re-render.
1446
+ this.widgetContainerAbove.detachChildren();
1406
1447
  const pinned = this.pinnedMessageContainer;
1407
1448
  this.widgetContainerAbove.addChild({
1408
1449
  render: () => pinned.children.length > 0 ? [] : [""],
@@ -1422,7 +1463,9 @@ export class InteractiveMode {
1422
1463
  spacerWhenEmpty: boolean,
1423
1464
  leadingSpacer: boolean,
1424
1465
  ): void {
1425
- container.clear();
1466
+ // Detach without disposing — the widgets map owns lifecycle; disposing
1467
+ // here would kill refresh timers and subscriptions on every re-render.
1468
+ container.detachChildren();
1426
1469
 
1427
1470
  if (widgets.size === 0) {
1428
1471
  if (spacerWhenEmpty) {
@@ -2197,9 +2240,30 @@ export class InteractiveMode {
2197
2240
  for (const message of sessionContext.messages) {
2198
2241
  // Assistant messages need special handling for tool calls
2199
2242
  if (message.role === "assistant") {
2200
- this.addMessageToChat(message);
2201
- // Render tool call components
2202
- for (const content of message.content) {
2243
+ const hasToolBlocks = message.content.some((c) => c.type === "toolCall" || c.type === "serverToolUse");
2244
+ if (!hasToolBlocks) {
2245
+ this.addMessageToChat(message);
2246
+ continue;
2247
+ }
2248
+
2249
+ const assistantSegments: AssistantMessageComponent[] = [];
2250
+ const replaySegments = buildAssistantReplaySegments(message.content);
2251
+
2252
+ for (const segment of replaySegments) {
2253
+ if (segment.kind === "assistant") {
2254
+ const assistantComponent = new AssistantMessageComponent(
2255
+ message,
2256
+ this.hideThinkingBlock,
2257
+ this.getMarkdownThemeWithSettings(),
2258
+ this.settingsManager.getTimestampFormat(),
2259
+ { startIndex: segment.startIndex, endIndex: segment.endIndex },
2260
+ );
2261
+ this.chatContainer.addChild(assistantComponent);
2262
+ assistantSegments.push(assistantComponent);
2263
+ continue;
2264
+ }
2265
+
2266
+ const content = message.content[segment.contentIndex];
2203
2267
  if (content.type === "toolCall") {
2204
2268
  const component = new ToolExecutionComponent(
2205
2269
  content.name,
@@ -2255,6 +2319,11 @@ export class InteractiveMode {
2255
2319
  }
2256
2320
  }
2257
2321
  }
2322
+
2323
+ // Match streaming-mode behavior: show metadata once on the final
2324
+ // assistant prose segment for this message.
2325
+ const lastAssistantSegment = assistantSegments[assistantSegments.length - 1];
2326
+ lastAssistantSegment?.setShowMetadata(true);
2258
2327
  } else if (message.role === "toolResult") {
2259
2328
  // Match tool results to pending tool components
2260
2329
  const component = this.pendingTools.get(message.toolCallId);
@@ -2302,9 +2371,13 @@ export class InteractiveMode {
2302
2371
 
2303
2372
  private rebuildChatFromMessages(): void {
2304
2373
  this.chatContainer.clear();
2374
+ this.pinnedMessageContainer.clear();
2305
2375
  const context = this.sessionManager.buildSessionContext();
2306
2376
  this.renderSessionContext(context);
2307
- this.populatePinnedFromMessages(context.messages);
2377
+ // Pinned content NOT re-populated here — the streaming lifecycle in
2378
+ // chat-controller.ts manages the pinned zone during active work.
2379
+ // populatePinnedFromMessages() remains in renderInitialMessages()
2380
+ // for the session-resume case at startup.
2308
2381
  }
2309
2382
 
2310
2383
  /**
@@ -0,0 +1,69 @@
1
+ declare module "proper-lockfile" {
2
+ export interface RetryOptions {
3
+ retries?: number;
4
+ factor?: number;
5
+ minTimeout?: number;
6
+ maxTimeout?: number;
7
+ randomize?: boolean;
8
+ }
9
+
10
+ export interface LockOptions {
11
+ realpath?: boolean;
12
+ retries?: number | RetryOptions;
13
+ stale?: number;
14
+ onCompromised?: (err: Error) => void;
15
+ }
16
+
17
+ export type ReleaseSync = () => void;
18
+ export type ReleaseAsync = () => Promise<void>;
19
+
20
+ export interface ProperLockfileApi {
21
+ lockSync(path: string, options?: LockOptions): ReleaseSync;
22
+ lock(path: string, options?: LockOptions): Promise<ReleaseAsync>;
23
+ }
24
+
25
+ const lockfile: ProperLockfileApi;
26
+ export default lockfile;
27
+ }
28
+
29
+ declare module "sql.js" {
30
+ export interface Statement {
31
+ bind(values: (string | number | null | Uint8Array)[]): void;
32
+ step(): boolean;
33
+ getAsObject(): Record<string, unknown>;
34
+ free(): void;
35
+ }
36
+
37
+ export interface Database {
38
+ run(sql: string, params?: unknown[]): void;
39
+ prepare(sql: string): Statement;
40
+ export(): Uint8Array;
41
+ close(): void;
42
+ }
43
+
44
+ export interface SqlJsStatic {
45
+ Database: new (data?: Uint8Array | ArrayBuffer | Buffer) => Database;
46
+ }
47
+
48
+ export interface SqlJsConfig {
49
+ locateFile?: (file: string) => string;
50
+ }
51
+
52
+ export default function initSqlJs(config?: SqlJsConfig): Promise<SqlJsStatic>;
53
+ }
54
+
55
+ declare module "hosted-git-info" {
56
+ export interface HostedGitInfo {
57
+ domain?: string;
58
+ user?: string;
59
+ project?: string;
60
+ committish?: string;
61
+ }
62
+
63
+ export interface HostedGitInfoApi {
64
+ fromUrl(url: string): HostedGitInfo | undefined;
65
+ }
66
+
67
+ const hostedGitInfo: HostedGitInfoApi;
68
+ export default hostedGitInfo;
69
+ }
@@ -6,6 +6,7 @@
6
6
  "strict": true,
7
7
  "esModuleInterop": true,
8
8
  "skipLibCheck": true,
9
+ "incremental": true,
9
10
  "forceConsistentCasingInFileNames": true,
10
11
  "declaration": true,
11
12
  "declarationMap": true,
@@ -22,6 +23,6 @@
22
23
  "outDir": "./dist",
23
24
  "rootDir": "./src"
24
25
  },
25
- "include": ["src/**/*.ts"],
26
- "exclude": ["node_modules", "dist", "**/*.d.ts", "src/**/*.d.ts"]
26
+ "include": ["src/**/*.ts", "src/**/*.d.ts"],
27
+ "exclude": ["node_modules", "dist"]
27
28
  }