gsd-pi 2.51.0 → 2.52.0-dev.585e355

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 (399) hide show
  1. package/README.md +4 -4
  2. package/dist/headless-events.d.ts +18 -0
  3. package/dist/headless-events.js +36 -0
  4. package/dist/headless-types.d.ts +28 -0
  5. package/dist/headless-types.js +7 -0
  6. package/dist/headless.d.ts +8 -3
  7. package/dist/headless.js +47 -16
  8. package/dist/help-text.js +16 -5
  9. package/dist/onboarding.js +5 -4
  10. package/dist/remote-questions-config.js +1 -1
  11. package/dist/resources/extensions/async-jobs/async-bash-tool.js +29 -17
  12. package/dist/resources/extensions/async-jobs/job-manager.js +4 -1
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  14. package/dist/resources/extensions/gsd/auto/phases.js +6 -0
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -0
  16. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  17. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  18. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  19. package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
  20. package/dist/resources/extensions/gsd/auto.js +8 -4
  21. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +105 -70
  22. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  23. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
  24. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  25. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  26. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  27. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +4 -4
  28. package/dist/resources/extensions/gsd/detection.js +6 -6
  29. package/dist/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  30. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  31. package/dist/resources/extensions/gsd/git-service.js +4 -3
  32. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  33. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  34. package/dist/resources/extensions/gsd/init-wizard.js +2 -2
  35. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  36. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
  37. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  38. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  39. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  40. package/dist/resources/extensions/gsd/preferences-types.js +1 -1
  41. package/dist/resources/extensions/gsd/preferences.js +13 -13
  42. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  43. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -44
  44. package/dist/resources/extensions/gsd/rule-registry.js +1 -1
  45. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  46. package/dist/resources/extensions/gsd/state.js +33 -19
  47. package/dist/resources/extensions/gsd/status-guards.js +12 -0
  48. package/dist/resources/extensions/gsd/tools/complete-milestone.js +7 -13
  49. package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -20
  50. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -21
  51. package/dist/resources/extensions/gsd/tools/plan-milestone.js +28 -29
  52. package/dist/resources/extensions/gsd/tools/plan-slice.js +27 -26
  53. package/dist/resources/extensions/gsd/tools/plan-task.js +23 -23
  54. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +50 -41
  55. package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
  56. package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
  57. package/dist/resources/extensions/gsd/tools/replan-slice.js +51 -41
  58. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  59. package/dist/resources/extensions/gsd/validation.js +21 -0
  60. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  61. package/dist/resources/extensions/remote-questions/config.js +1 -1
  62. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  63. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  64. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  65. package/dist/resources/extensions/shared/rtk.js +5 -3
  66. package/dist/rtk.js +3 -1
  67. package/dist/web/standalone/.next/BUILD_ID +1 -1
  68. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  69. package/dist/web/standalone/.next/build-manifest.json +4 -4
  70. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  71. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  72. package/dist/web/standalone/.next/required-server-files.json +3 -3
  73. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  74. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  76. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  84. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  93. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  100. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  112. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  140. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  146. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  160. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  162. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  164. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  166. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/index.html +1 -1
  176. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  177. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  178. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  179. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  180. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  181. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  182. package/dist/web/standalone/.next/server/app/page.js +2 -2
  183. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  185. package/dist/web/standalone/.next/server/chunks/2229.js +3 -3
  186. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  187. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/middleware.js +2 -2
  190. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  192. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  193. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  194. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  195. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
  196. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  197. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  198. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  199. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  200. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  201. package/dist/web/standalone/.next/static/chunks/{webpack-cfc9a116e6450a6b.js → webpack-024d82be84800e52.js} +1 -1
  202. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  203. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  204. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  205. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  206. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  207. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  208. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  209. package/dist/web/standalone/server.js +1 -1
  210. package/dist/wizard.js +4 -1
  211. package/package.json +2 -2
  212. package/packages/mcp-server/README.md +202 -0
  213. package/packages/mcp-server/package.json +36 -0
  214. package/packages/mcp-server/src/cli.ts +68 -0
  215. package/packages/mcp-server/src/index.ts +14 -0
  216. package/packages/mcp-server/src/mcp-server.test.ts +628 -0
  217. package/packages/mcp-server/src/server.ts +278 -0
  218. package/packages/mcp-server/src/session-manager.ts +328 -0
  219. package/packages/mcp-server/src/types.ts +107 -0
  220. package/packages/mcp-server/tsconfig.json +24 -0
  221. package/packages/pi-ai/dist/models.d.ts +14 -3
  222. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  223. package/packages/pi-ai/dist/models.js +53 -10
  224. package/packages/pi-ai/dist/models.js.map +1 -1
  225. package/packages/pi-ai/dist/models.test.js +102 -1
  226. package/packages/pi-ai/dist/models.test.js.map +1 -1
  227. package/packages/pi-ai/dist/types.d.ts +30 -0
  228. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  229. package/packages/pi-ai/dist/types.js.map +1 -1
  230. package/packages/pi-ai/src/models.test.ts +114 -1
  231. package/packages/pi-ai/src/models.ts +70 -13
  232. package/packages/pi-ai/src/types.ts +31 -0
  233. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  234. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  236. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/bash-executor.js +5 -1
  239. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  242. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  244. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  245. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  246. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  247. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  249. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  251. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  254. package/packages/pi-coding-agent/dist/main.js +5 -3
  255. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  256. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  257. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  261. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  263. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  265. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  267. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  269. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  271. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  272. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  273. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  274. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  275. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  278. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  279. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  280. package/packages/pi-coding-agent/package.json +1 -1
  281. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  282. package/packages/pi-coding-agent/src/core/bash-executor.ts +5 -1
  283. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  284. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  285. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  286. package/packages/pi-coding-agent/src/index.ts +3 -0
  287. package/packages/pi-coding-agent/src/main.ts +5 -3
  288. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  289. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  290. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  291. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  292. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  293. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  294. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  295. package/packages/rpc-client/package.json +20 -0
  296. package/pkg/package.json +1 -1
  297. package/scripts/ensure-workspace-builds.cjs +36 -8
  298. package/src/resources/extensions/async-jobs/async-bash-tool.ts +22 -11
  299. package/src/resources/extensions/async-jobs/job-manager.ts +4 -1
  300. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  301. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  302. package/src/resources/extensions/gsd/auto/phases.ts +6 -0
  303. package/src/resources/extensions/gsd/auto-dispatch.ts +19 -0
  304. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  305. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  306. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  307. package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
  308. package/src/resources/extensions/gsd/auto.ts +10 -4
  309. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -73
  310. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  311. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
  312. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  313. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  314. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  315. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -4
  316. package/src/resources/extensions/gsd/detection.ts +6 -6
  317. package/src/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  318. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  319. package/src/resources/extensions/gsd/git-service.ts +4 -3
  320. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  321. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  322. package/src/resources/extensions/gsd/init-wizard.ts +2 -2
  323. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  324. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
  325. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  326. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  327. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  328. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  329. package/src/resources/extensions/gsd/preferences.ts +12 -13
  330. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  331. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -57
  332. package/src/resources/extensions/gsd/rule-registry.ts +1 -1
  333. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  334. package/src/resources/extensions/gsd/state.ts +34 -20
  335. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  336. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -1
  337. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  338. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  339. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  340. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  341. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  342. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  343. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  344. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +35 -7
  345. package/src/resources/extensions/gsd/tests/detection.test.ts +1 -1
  346. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  347. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  348. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  349. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  350. package/src/resources/extensions/gsd/tests/git-service.test.ts +37 -4
  351. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  352. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  353. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  354. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  355. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  356. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  357. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  358. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  359. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  360. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  361. package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -2
  362. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  363. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  364. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  365. package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
  366. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +42 -31
  367. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  368. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  369. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  370. package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
  371. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  372. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  373. package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -17
  374. package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -24
  375. package/src/resources/extensions/gsd/tools/complete-task.ts +13 -25
  376. package/src/resources/extensions/gsd/tools/plan-milestone.ts +30 -32
  377. package/src/resources/extensions/gsd/tools/plan-slice.ts +30 -30
  378. package/src/resources/extensions/gsd/tools/plan-task.ts +26 -26
  379. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +57 -46
  380. package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
  381. package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
  382. package/src/resources/extensions/gsd/tools/replan-slice.ts +55 -44
  383. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  384. package/src/resources/extensions/gsd/validation.ts +23 -0
  385. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  386. package/src/resources/extensions/remote-questions/config.ts +1 -1
  387. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  388. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  389. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  390. package/src/resources/extensions/shared/rtk.ts +12 -3
  391. package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.js +0 -9
  392. package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +0 -1
  393. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  394. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  395. package/dist/web/standalone/.next/static/css/de141508b083f922.css +0 -1
  396. /package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
  397. /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → KTe1kB5nPLQFIIFz2OcmI}/_buildManifest.js +0 -0
  398. /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → KTe1kB5nPLQFIIFz2OcmI}/_ssgManifest.js +0 -0
  399. /package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
@@ -0,0 +1,101 @@
1
+ /**
2
+ * bash-spawn-windows.test.ts — Regression test for Windows spawn EINVAL.
3
+ *
4
+ * Verifies that bash tool spawn options disable `detached: true` on Windows
5
+ * to prevent EINVAL errors in ConPTY / VSCode terminal contexts.
6
+ *
7
+ * Background:
8
+ * On Windows, `spawn()` with `detached: true` sets the
9
+ * CREATE_NEW_PROCESS_GROUP flag in CreateProcess. In certain terminal
10
+ * contexts (VSCode integrated terminal, ConPTY, Windows Terminal) this
11
+ * flag conflicts with the parent process group and causes a synchronous
12
+ * EINVAL from libuv. The bg-shell extension already guards against this
13
+ * with `detached: process.platform !== "win32"` (process-manager.ts);
14
+ * this test ensures all other spawn sites are aligned.
15
+ *
16
+ * See: gsd-build/gsd-2#XXXX
17
+ */
18
+
19
+ import test from "node:test";
20
+ import assert from "node:assert/strict";
21
+ import { spawn } from "node:child_process";
22
+
23
+ // Verify the spawn option pattern used across the codebase.
24
+ // This is a static/structural test — it reads the source files and asserts
25
+ // they use the platform-guarded detached flag.
26
+ import { readFileSync } from "node:fs";
27
+ import { join, dirname } from "node:path";
28
+ import { fileURLToPath } from "node:url";
29
+
30
+ const __dirname = dirname(fileURLToPath(import.meta.url));
31
+
32
+ const SPAWN_FILES = [
33
+ join(__dirname, "bash.ts"),
34
+ join(__dirname, "..", "bash-executor.ts"),
35
+ join(__dirname, "..", "..", "utils", "shell.ts"),
36
+ ];
37
+
38
+ test("spawn calls use platform-guarded detached flag (no unconditional detached: true)", () => {
39
+ for (const file of SPAWN_FILES) {
40
+ const content = readFileSync(file, "utf-8");
41
+ const lines = content.split("\n");
42
+
43
+ for (let i = 0; i < lines.length; i++) {
44
+ const line = lines[i]!;
45
+ // Skip comments
46
+ if (line.trim().startsWith("//") || line.trim().startsWith("*")) continue;
47
+ // Check for unconditional `detached: true`
48
+ if (/detached:\s*true\b/.test(line)) {
49
+ assert.fail(
50
+ `${file}:${i + 1} has unconditional 'detached: true' — ` +
51
+ `must use 'detached: process.platform !== "win32"' ` +
52
+ `to prevent EINVAL on Windows (ConPTY / VSCode terminal)`,
53
+ );
54
+ }
55
+ }
56
+ }
57
+ });
58
+
59
+ test("killProcessTree does not use detached: true for taskkill on Windows", () => {
60
+ const shellFile = join(__dirname, "..", "..", "utils", "shell.ts");
61
+ const content = readFileSync(shellFile, "utf-8");
62
+
63
+ // Find the taskkill spawn call and ensure it doesn't have detached: true
64
+ const taskkillRegion = content.match(/spawn\("taskkill"[\s\S]*?\}\)/);
65
+ if (taskkillRegion) {
66
+ assert.ok(
67
+ !/detached:\s*true/.test(taskkillRegion[0]),
68
+ "taskkill spawn should not use detached: true — " +
69
+ "it can cause EINVAL on Windows and is unnecessary for a utility process",
70
+ );
71
+ }
72
+ });
73
+
74
+ // Smoke test: spawn with platform-guarded detached flag actually works
75
+ test("spawn with detached: process.platform !== 'win32' succeeds", async () => {
76
+ const { promise, resolve, reject } = Promise.withResolvers<void>();
77
+
78
+ const child = spawn(
79
+ process.platform === "win32" ? "cmd" : "sh",
80
+ process.platform === "win32" ? ["/c", "echo ok"] : ["-c", "echo ok"],
81
+ {
82
+ detached: process.platform !== "win32",
83
+ stdio: ["ignore", "pipe", "pipe"],
84
+ },
85
+ );
86
+
87
+ let output = "";
88
+ child.stdout?.on("data", (d: Buffer) => { output += d.toString(); });
89
+ child.on("error", reject);
90
+ child.on("close", (code) => {
91
+ try {
92
+ assert.equal(code, 0, "spawn should succeed");
93
+ assert.ok(output.trim().includes("ok"), `Expected 'ok' in output, got: ${output}`);
94
+ resolve();
95
+ } catch (e) {
96
+ reject(e);
97
+ }
98
+ });
99
+
100
+ await promise;
101
+ });
@@ -158,9 +158,13 @@ const defaultBashOperations: BashOperations = {
158
158
  return;
159
159
  }
160
160
 
161
+ // On Windows, detached: true sets CREATE_NEW_PROCESS_GROUP which can
162
+ // cause EINVAL in VSCode/ConPTY terminal contexts. The bg-shell
163
+ // extension already guards this (process-manager.ts); align here.
164
+ // Process-tree cleanup uses taskkill /F /T on Windows regardless.
161
165
  const child = spawn(shell, [...args, command], {
162
166
  cwd,
163
- detached: true,
167
+ detached: process.platform !== "win32",
164
168
  env: env ?? getShellEnv(),
165
169
  stdio: ["ignore", "pipe", "pipe"],
166
170
  });
@@ -314,8 +314,11 @@ export {
314
314
  type RpcClientOptions,
315
315
  type RpcEventListener,
316
316
  type RpcCommand,
317
+ type RpcInitResult,
318
+ type RpcProtocolVersion,
317
319
  type RpcResponse,
318
320
  type RpcSessionState,
321
+ type RpcV2Event,
319
322
  } from "./modes/index.js";
320
323
  // RPC JSONL utilities
321
324
  export { attachJsonlLineReader, serializeJsonLine } from "./modes/rpc/jsonl.js";
@@ -419,11 +419,13 @@ export async function main(args: string[]) {
419
419
  additionalPromptTemplatePaths: firstPass.promptTemplates,
420
420
  additionalThemePaths: firstPass.themes,
421
421
  noExtensions: firstPass.noExtensions,
422
- noSkills: firstPass.noSkills,
423
- noPromptTemplates: firstPass.noPromptTemplates,
424
- noThemes: firstPass.noThemes,
422
+ noSkills: firstPass.noSkills || firstPass.bare,
423
+ noPromptTemplates: firstPass.noPromptTemplates || firstPass.bare,
424
+ noThemes: firstPass.noThemes || firstPass.bare,
425
425
  systemPrompt: firstPass.systemPrompt,
426
426
  appendSystemPrompt: firstPass.appendSystemPrompt,
427
+ // --bare: suppress CLAUDE.md/AGENTS.md ancestor walk
428
+ ...(firstPass.bare ? { agentsFilesOverride: () => ({ agentsFiles: [] }) } : {}),
427
429
  });
428
430
  await resourceLoader.reload();
429
431
  time("resourceLoader.reload");
@@ -6,4 +6,11 @@ export { InteractiveMode, type InteractiveModeOptions } from "./interactive/inte
6
6
  export { type PrintModeOptions, runPrintMode } from "./print-mode.js";
7
7
  export { type ModelInfo, RpcClient, type RpcClientOptions, type RpcEventListener } from "./rpc/rpc-client.js";
8
8
  export { runRpcMode } from "./rpc/rpc-mode.js";
9
- export type { RpcCommand, RpcResponse, RpcSessionState } from "./rpc/rpc-types.js";
9
+ export type {
10
+ RpcCommand,
11
+ RpcInitResult,
12
+ RpcProtocolVersion,
13
+ RpcResponse,
14
+ RpcSessionState,
15
+ RpcV2Event,
16
+ } from "./rpc/rpc-types.js";
@@ -150,7 +150,6 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
150
150
  content: [{ type: "text", text: "Web search disabled (offline mode)" }],
151
151
  isError: false,
152
152
  });
153
- host.pendingTools.delete(content.toolUseId);
154
153
  } else {
155
154
  const searchContent = content.content;
156
155
  const isError = searchContent && typeof searchContent === "object" && "type" in (searchContent as any) && (searchContent as any).type === "web_search_tool_result_error";
@@ -158,7 +157,6 @@ export async function handleAgentEvent(host: InteractiveModeStateHost & {
158
157
  content: [{ type: "text", text: host.formatWebSearchResult(searchContent) }],
159
158
  isError: !!isError,
160
159
  });
161
- host.pendingTools.delete(content.toolUseId);
162
160
  }
163
161
  }
164
162
  }
@@ -11,7 +11,7 @@ import type { SessionStats } from "../../core/agent-session.js";
11
11
  import type { BashResult } from "../../core/bash-executor.js";
12
12
  import type { CompactionResult } from "../../core/compaction/index.js";
13
13
  import { attachJsonlLineReader, serializeJsonLine } from "./jsonl.js";
14
- import type { RpcCommand, RpcResponse, RpcSessionState, RpcSlashCommand } from "./rpc-types.js";
14
+ import type { RpcCommand, RpcInitResult, RpcResponse, RpcSessionState, RpcSlashCommand } from "./rpc-types.js";
15
15
 
16
16
  // ============================================================================
17
17
  // Types
@@ -398,6 +398,59 @@ export class RpcClient {
398
398
  return this.getData<{ commands: RpcSlashCommand[] }>(response).commands;
399
399
  }
400
400
 
401
+ /**
402
+ * Send a UI response to a pending extension_ui_request.
403
+ * Fire-and-forget — no request/response correlation.
404
+ */
405
+ sendUIResponse(id: string, response: { value?: string; values?: string[]; confirmed?: boolean; cancelled?: boolean }): void {
406
+ if (!this.process?.stdin) {
407
+ throw new Error("Client not started");
408
+ }
409
+ this.process.stdin.write(serializeJsonLine({
410
+ type: "extension_ui_response",
411
+ id,
412
+ ...response,
413
+ }));
414
+ }
415
+
416
+ /**
417
+ * Initialize a v2 protocol session. Must be sent as the first command.
418
+ * Returns the negotiated protocol version, session ID, and server capabilities.
419
+ */
420
+ async init(options?: { clientId?: string }): Promise<RpcInitResult> {
421
+ const response = await this.send({ type: "init", protocolVersion: 2, clientId: options?.clientId });
422
+ return this.getData<RpcInitResult>(response);
423
+ }
424
+
425
+ /**
426
+ * Request a graceful shutdown of the agent process.
427
+ * Waits for the response before the process exits.
428
+ */
429
+ async shutdown(): Promise<void> {
430
+ await this.send({ type: "shutdown" });
431
+ // Wait for process to exit after shutdown acknowledgment
432
+ if (this.process) {
433
+ await new Promise<void>((resolve) => {
434
+ const timeout = setTimeout(() => {
435
+ this.process?.kill("SIGKILL");
436
+ resolve();
437
+ }, 5000);
438
+ this.process?.on("exit", () => {
439
+ clearTimeout(timeout);
440
+ resolve();
441
+ });
442
+ });
443
+ }
444
+ }
445
+
446
+ /**
447
+ * Subscribe to specific event types (v2 only).
448
+ * Pass ["*"] to receive all events, or a list of event type strings to filter.
449
+ */
450
+ async subscribe(events: string[]): Promise<void> {
451
+ await this.send({ type: "subscribe", events });
452
+ }
453
+
401
454
  // =========================================================================
402
455
  // Helpers
403
456
  // =========================================================================
@@ -27,6 +27,7 @@ import type {
27
27
  RpcCommand,
28
28
  RpcExtensionUIRequest,
29
29
  RpcExtensionUIResponse,
30
+ RpcInitResult,
30
31
  RpcResponse,
31
32
  RpcSessionState,
32
33
  RpcSlashCommand,
@@ -37,8 +38,11 @@ export type {
37
38
  RpcCommand,
38
39
  RpcExtensionUIRequest,
39
40
  RpcExtensionUIResponse,
41
+ RpcInitResult,
42
+ RpcProtocolVersion,
40
43
  RpcResponse,
41
44
  RpcSessionState,
45
+ RpcV2Event,
42
46
  } from "./rpc-types.js";
43
47
 
44
48
  /**
@@ -74,6 +78,16 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
74
78
  // Shutdown request flag
75
79
  let shutdownRequested = false;
76
80
 
81
+ // v2 protocol version detection state
82
+ let protocolVersion: 1 | 2 = 1;
83
+ let protocolLocked = false;
84
+
85
+ // v2 runId threading: tracks the current execution run
86
+ let currentRunId: string | null = null;
87
+
88
+ // v2 event filtering: null = no filter (all events); Set = only listed event types
89
+ let eventFilter: Set<string> | null = null;
90
+
77
91
  const embeddedTerminalEnabled = process.env.GSD_WEB_BRIDGE_TUI === "1";
78
92
  const remoteTerminal = embeddedTerminalEnabled
79
93
  ? new RemoteTerminal({
@@ -425,7 +439,55 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
425
439
 
426
440
  // Output all agent events as JSON
427
441
  const unsubscribe = session.subscribe((event) => {
428
- output(event);
442
+ // v2: emit synthesized events before the regular event
443
+ if (protocolVersion === 2) {
444
+ // cost_update on assistant message_end
445
+ if (event.type === "message_end" && event.message.role === "assistant" && currentRunId) {
446
+ const stats = session.getSessionStats();
447
+ const costUpdate = {
448
+ type: "cost_update" as const,
449
+ runId: currentRunId,
450
+ turnCost: session.getLastTurnCost(),
451
+ cumulativeCost: stats.cost,
452
+ tokens: {
453
+ input: stats.tokens.input,
454
+ output: stats.tokens.output,
455
+ cacheRead: stats.tokens.cacheRead,
456
+ cacheWrite: stats.tokens.cacheWrite,
457
+ },
458
+ };
459
+ if (!eventFilter || eventFilter.has("cost_update")) {
460
+ output(costUpdate);
461
+ }
462
+ }
463
+
464
+ // execution_complete on agent_end
465
+ if (event.type === "agent_end" && currentRunId) {
466
+ const stats = session.getSessionStats();
467
+ const completionEvent = {
468
+ type: "execution_complete" as const,
469
+ runId: currentRunId,
470
+ status: "completed" as const,
471
+ stats,
472
+ };
473
+ if (!eventFilter || eventFilter.has("execution_complete")) {
474
+ output(completionEvent);
475
+ }
476
+ currentRunId = null;
477
+ }
478
+ }
479
+
480
+ // Apply event filter (v2 only, applies to agent session events only)
481
+ if (protocolVersion === 2 && eventFilter && !eventFilter.has(event.type)) {
482
+ return;
483
+ }
484
+
485
+ // Emit the regular event, with runId injection in v2 mode
486
+ if (protocolVersion === 2 && currentRunId) {
487
+ output({ ...event, runId: currentRunId });
488
+ } else {
489
+ output(event);
490
+ }
429
491
  });
430
492
 
431
493
  // Handle a single command
@@ -438,6 +500,9 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
438
500
  // =================================================================
439
501
 
440
502
  case "prompt": {
503
+ // v2: generate runId for execution tracking
504
+ const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
505
+ if (runId) currentRunId = runId;
441
506
  // Don't await - events will stream
442
507
  // Extension commands are executed immediately, file prompt templates are expanded
443
508
  // If streaming and streamingBehavior specified, queues via steer/followUp
@@ -448,17 +513,23 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
448
513
  source: "rpc",
449
514
  })
450
515
  .catch((e) => output(error(id, "prompt", e.message)));
451
- return success(id, "prompt");
516
+ return { id, type: "response", command: "prompt", success: true, ...(runId && { runId }) } as RpcResponse;
452
517
  }
453
518
 
454
519
  case "steer": {
520
+ // v2: generate runId for execution tracking
521
+ const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
522
+ if (runId) currentRunId = runId;
455
523
  await session.steer(command.message, command.images);
456
- return success(id, "steer");
524
+ return { id, type: "response", command: "steer", success: true, ...(runId && { runId }) } as RpcResponse;
457
525
  }
458
526
 
459
527
  case "follow_up": {
528
+ // v2: generate runId for execution tracking
529
+ const runId = protocolVersion === 2 ? crypto.randomUUID() : undefined;
530
+ if (runId) currentRunId = runId;
460
531
  await session.followUp(command.message, command.images);
461
- return success(id, "follow_up");
532
+ return { id, type: "response", command: "follow_up", success: true, ...(runId && { runId }) } as RpcResponse;
462
533
  }
463
534
 
464
535
  case "abort": {
@@ -709,6 +780,28 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
709
780
  return success(id, "terminal_redraw");
710
781
  }
711
782
 
783
+ // =================================================================
784
+ // v2 Protocol: subscribe
785
+ // =================================================================
786
+
787
+ case "subscribe": {
788
+ if (command.events.includes("*")) {
789
+ eventFilter = null; // wildcard = all events
790
+ } else {
791
+ eventFilter = new Set(command.events);
792
+ }
793
+ return success(id, "subscribe");
794
+ }
795
+
796
+ // =================================================================
797
+ // v2 Protocol: shutdown
798
+ // =================================================================
799
+
800
+ case "shutdown": {
801
+ shutdownRequested = true;
802
+ return success(id, "shutdown");
803
+ }
804
+
712
805
  default: {
713
806
  const unknownCommand = command as { type: string; id?: string };
714
807
  return error(unknownCommand.id, unknownCommand.type, `Unknown command: ${unknownCommand.type}`);
@@ -741,7 +834,7 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
741
834
  try {
742
835
  const parsed = JSON.parse(line);
743
836
 
744
- // Handle extension UI responses
837
+ // Handle extension UI responses (bypass protocol detection)
745
838
  if (parsed.type === "extension_ui_response") {
746
839
  const response = parsed as RpcExtensionUIResponse;
747
840
  const pending = pendingExtensionRequests.get(response.id);
@@ -752,8 +845,33 @@ export async function runRpcMode(session: AgentSession): Promise<never> {
752
845
  return;
753
846
  }
754
847
 
755
- // Handle regular commands
756
848
  const command = parsed as RpcCommand;
849
+
850
+ // Protocol version detection: first non-UI-response command locks the version
851
+ if (!protocolLocked) {
852
+ protocolLocked = true;
853
+ if (command.type === "init") {
854
+ protocolVersion = 2;
855
+ const initResult: RpcInitResult = {
856
+ protocolVersion: 2,
857
+ sessionId: session.sessionId,
858
+ capabilities: {
859
+ events: ["execution_complete", "cost_update"],
860
+ commands: ["init", "shutdown", "subscribe"],
861
+ },
862
+ };
863
+ output(success(command.id, "init", initResult));
864
+ return;
865
+ }
866
+ // Non-init first message: lock to v1, fall through to normal handling
867
+ protocolVersion = 1;
868
+ } else if (command.type === "init") {
869
+ // Already locked — reject re-init
870
+ output(error(command.id, "init", "Protocol version already locked. init must be the first command."));
871
+ return;
872
+ }
873
+
874
+ // Handle regular commands
757
875
  const response = await handleCommand(command);
758
876
  output(response);
759
877