gsd-pi 2.51.0 → 2.52.0-dev.655ad8a

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 (419) hide show
  1. package/README.md +59 -36
  2. package/dist/headless-events.d.ts +18 -0
  3. package/dist/headless-events.js +36 -0
  4. package/dist/headless-query.js +1 -1
  5. package/dist/headless-types.d.ts +28 -0
  6. package/dist/headless-types.js +7 -0
  7. package/dist/headless.d.ts +8 -3
  8. package/dist/headless.js +47 -16
  9. package/dist/help-text.js +16 -5
  10. package/dist/onboarding.js +5 -4
  11. package/dist/remote-questions-config.js +1 -1
  12. package/dist/resources/extensions/async-jobs/async-bash-tool.js +29 -17
  13. package/dist/resources/extensions/async-jobs/job-manager.js +4 -1
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  15. package/dist/resources/extensions/get-secrets-from-user.js +7 -0
  16. package/dist/resources/extensions/gsd/auto/phases.js +34 -8
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +23 -1
  18. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  19. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  20. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  21. package/dist/resources/extensions/gsd/auto-worktree.js +91 -14
  22. package/dist/resources/extensions/gsd/auto.js +30 -4
  23. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -70
  24. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
  26. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  27. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  28. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  29. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +4 -4
  30. package/dist/resources/extensions/gsd/detection.js +6 -6
  31. package/dist/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  32. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  33. package/dist/resources/extensions/gsd/git-service.js +4 -3
  34. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  35. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  36. package/dist/resources/extensions/gsd/guided-flow.js +4 -3
  37. package/dist/resources/extensions/gsd/init-wizard.js +2 -2
  38. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  39. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
  40. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  41. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  42. package/dist/resources/extensions/gsd/parallel-orchestrator.js +18 -2
  43. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  44. package/dist/resources/extensions/gsd/preferences-types.js +1 -1
  45. package/dist/resources/extensions/gsd/preferences.js +13 -13
  46. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  47. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -44
  48. package/dist/resources/extensions/gsd/rule-registry.js +1 -1
  49. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  50. package/dist/resources/extensions/gsd/state.js +38 -30
  51. package/dist/resources/extensions/gsd/status-guards.js +12 -0
  52. package/dist/resources/extensions/gsd/tools/complete-milestone.js +7 -13
  53. package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -20
  54. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -21
  55. package/dist/resources/extensions/gsd/tools/plan-milestone.js +28 -29
  56. package/dist/resources/extensions/gsd/tools/plan-slice.js +27 -26
  57. package/dist/resources/extensions/gsd/tools/plan-task.js +23 -23
  58. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +50 -41
  59. package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
  60. package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
  61. package/dist/resources/extensions/gsd/tools/replan-slice.js +51 -41
  62. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  63. package/dist/resources/extensions/gsd/validation.js +21 -0
  64. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  65. package/dist/resources/extensions/remote-questions/config.js +1 -1
  66. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  67. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  68. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  69. package/dist/resources/extensions/shared/rtk.js +14 -4
  70. package/dist/rtk.js +3 -1
  71. package/dist/web/standalone/.next/BUILD_ID +1 -1
  72. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  73. package/dist/web/standalone/.next/build-manifest.json +4 -4
  74. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  75. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  76. package/dist/web/standalone/.next/required-server-files.json +3 -3
  77. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  78. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  80. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  88. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  97. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  104. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  144. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  164. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  166. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  168. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  170. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/index.html +1 -1
  180. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  181. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  182. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  183. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  185. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  186. package/dist/web/standalone/.next/server/app/page.js +2 -2
  187. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  189. package/dist/web/standalone/.next/server/chunks/2229.js +3 -3
  190. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  191. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/middleware.js +2 -2
  194. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  196. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  197. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  198. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  199. package/dist/web/standalone/.next/static/chunks/4024.87fd909ae0110f50.js +9 -0
  200. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  201. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  202. package/dist/web/standalone/.next/static/chunks/app/page-b950e4e384cc62b3.js +1 -0
  203. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  204. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  205. package/dist/web/standalone/.next/static/chunks/{webpack-cfc9a116e6450a6b.js → webpack-bca0e732db0dcec3.js} +1 -1
  206. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  207. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  208. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  209. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  210. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  211. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  212. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  213. package/dist/web/standalone/server.js +1 -1
  214. package/dist/wizard.js +4 -1
  215. package/package.json +2 -2
  216. package/packages/mcp-server/README.md +202 -0
  217. package/packages/mcp-server/package.json +36 -0
  218. package/packages/mcp-server/src/cli.ts +68 -0
  219. package/packages/mcp-server/src/index.ts +14 -0
  220. package/packages/mcp-server/src/mcp-server.test.ts +628 -0
  221. package/packages/mcp-server/src/server.ts +278 -0
  222. package/packages/mcp-server/src/session-manager.ts +328 -0
  223. package/packages/mcp-server/src/types.ts +107 -0
  224. package/packages/mcp-server/tsconfig.json +24 -0
  225. package/packages/pi-ai/dist/models.d.ts +14 -3
  226. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  227. package/packages/pi-ai/dist/models.js +53 -10
  228. package/packages/pi-ai/dist/models.js.map +1 -1
  229. package/packages/pi-ai/dist/models.test.js +102 -1
  230. package/packages/pi-ai/dist/models.test.js.map +1 -1
  231. package/packages/pi-ai/dist/types.d.ts +30 -0
  232. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  233. package/packages/pi-ai/dist/types.js.map +1 -1
  234. package/packages/pi-ai/src/models.test.ts +114 -1
  235. package/packages/pi-ai/src/models.ts +70 -13
  236. package/packages/pi-ai/src/types.ts +31 -0
  237. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  238. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  240. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/bash-executor.js +5 -1
  243. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  246. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  248. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  249. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  250. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  251. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  252. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  253. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  255. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/main.js +5 -3
  259. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  261. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  265. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  267. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  269. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  271. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  273. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  275. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  276. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  277. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  278. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  279. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  283. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  284. package/packages/pi-coding-agent/package.json +1 -1
  285. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  286. package/packages/pi-coding-agent/src/core/bash-executor.ts +5 -1
  287. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  288. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  289. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  290. package/packages/pi-coding-agent/src/index.ts +3 -0
  291. package/packages/pi-coding-agent/src/main.ts +5 -3
  292. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  293. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  294. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  295. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  296. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  297. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  298. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  299. package/packages/rpc-client/package.json +20 -0
  300. package/pkg/package.json +1 -1
  301. package/scripts/ensure-workspace-builds.cjs +36 -8
  302. package/src/resources/extensions/async-jobs/async-bash-tool.ts +22 -11
  303. package/src/resources/extensions/async-jobs/job-manager.ts +4 -1
  304. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  305. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  306. package/src/resources/extensions/get-secrets-from-user.ts +8 -0
  307. package/src/resources/extensions/gsd/auto/phases.ts +44 -7
  308. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -1
  309. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  310. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  311. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  312. package/src/resources/extensions/gsd/auto-worktree.ts +94 -14
  313. package/src/resources/extensions/gsd/auto.ts +31 -4
  314. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +118 -73
  315. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  316. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
  317. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  318. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  319. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  320. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -4
  321. package/src/resources/extensions/gsd/detection.ts +6 -6
  322. package/src/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  323. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  324. package/src/resources/extensions/gsd/git-service.ts +4 -3
  325. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  326. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  327. package/src/resources/extensions/gsd/guided-flow.ts +4 -3
  328. package/src/resources/extensions/gsd/init-wizard.ts +2 -2
  329. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  330. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
  331. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  332. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  333. package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -1
  334. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  335. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  336. package/src/resources/extensions/gsd/preferences.ts +12 -13
  337. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  338. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -57
  339. package/src/resources/extensions/gsd/rule-registry.ts +1 -1
  340. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  341. package/src/resources/extensions/gsd/state.ts +39 -30
  342. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  343. package/src/resources/extensions/gsd/tests/active-milestone-id-guard.test.ts +91 -0
  344. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -1
  345. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  346. package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +87 -0
  347. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +80 -0
  348. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +1 -1
  349. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  350. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  351. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +39 -0
  352. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  353. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  354. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  355. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  356. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +35 -7
  357. package/src/resources/extensions/gsd/tests/detection.test.ts +1 -1
  358. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  359. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  360. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  361. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  362. package/src/resources/extensions/gsd/tests/git-service.test.ts +65 -31
  363. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  364. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  365. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  366. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  367. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  368. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  369. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  370. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +51 -0
  371. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  372. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +277 -0
  373. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  374. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +103 -0
  375. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  376. package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -2
  377. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  378. package/src/resources/extensions/gsd/tests/rate-limit-model-fallback.test.ts +90 -0
  379. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  380. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  381. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +9 -8
  382. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +125 -0
  383. package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
  384. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +42 -31
  385. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  386. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  387. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  388. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -2
  389. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +124 -0
  390. package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
  391. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  392. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  393. package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -17
  394. package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -24
  395. package/src/resources/extensions/gsd/tools/complete-task.ts +13 -25
  396. package/src/resources/extensions/gsd/tools/plan-milestone.ts +30 -32
  397. package/src/resources/extensions/gsd/tools/plan-slice.ts +30 -30
  398. package/src/resources/extensions/gsd/tools/plan-task.ts +26 -26
  399. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +57 -46
  400. package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
  401. package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
  402. package/src/resources/extensions/gsd/tools/replan-slice.ts +55 -44
  403. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  404. package/src/resources/extensions/gsd/validation.ts +23 -0
  405. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  406. package/src/resources/extensions/remote-questions/config.ts +1 -1
  407. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  408. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  409. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  410. package/src/resources/extensions/shared/rtk.ts +22 -4
  411. package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.js +0 -9
  412. package/dist/web/standalone/.next/static/chunks/app/page-fbecd1237e2d6d1f.js +0 -1
  413. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  414. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  415. package/dist/web/standalone/.next/static/css/de141508b083f922.css +0 -1
  416. /package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
  417. /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → zpvUPKoW5jRAMB_fWHlPi}/_buildManifest.js +0 -0
  418. /package/dist/web/standalone/.next/static/{vkr67v-utm1dgZnbrBWQh → zpvUPKoW5jRAMB_fWHlPi}/_ssgManifest.js +0 -0
  419. /package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
package/README.md CHANGED
@@ -27,55 +27,78 @@ One command. Walk away. Come back to a built project with clean git history.
27
27
 
28
28
  ---
29
29
 
30
- ## What's New in v2.46.0
30
+ ## What's New in v2.52.0
31
31
 
32
- ### Single-Writer State Engine
32
+ ### VS Code Extension & Web UI
33
33
 
34
- The biggest architectural change since DB-backed planning tools. The single-writer engine enforces disciplined state transitions through three iterations:
34
+ - **VS Code integration** status bar, file decorations, bash terminal, session tree, conversation history, and code lens. (#2651)
35
+ - **Dark mode contrast** — raised token floor and flattened opacity tier system for better readability. (#2734)
36
+ - **Auth token gate** — synthetic 401 on missing token, unauthenticated boot state, and recovery screen. (#2740)
35
37
 
36
- - **v2 discipline layer** — adds a write-side discipline layer on top of the DB architecture, ensuring all state mutations flow through controlled tool calls.
37
- - **v3 — state machine guards, actor identity, reversibility** — introduces formal state machine guards, tracks which actor (human vs agent) initiated each transition, and makes transitions reversible.
38
- - **Hardened** — closes TOCTOU race conditions, intercepts bypass attempts, and resolves status inconsistencies.
38
+ ### Capability Metadata & Model Routing
39
39
 
40
- All prompts are now aligned with the single-writer tool API, and a new **workflow-logger** is wired into the engine, tool, manifest, and reconcile paths for full observability. (#2494)
41
-
42
- ### v2.45.0 — New Commands and Capabilities
43
-
44
- - **`/gsd rethink`** — conversational project reorganization. Rethink your milestone structure, slice decomposition, or overall approach through guided discussion. (#2459)
45
- - **`/gsd mcp`** — MCP server status and connectivity. Check which MCP servers are configured, connected, and healthy. (#2362)
46
- - **Complete offline mode** — GSD now works fully offline with local models. (#2429)
47
- - **Global KNOWLEDGE.md injection** — `~/.gsd/agent/KNOWLEDGE.md` is injected into the system prompt, so cross-project knowledge persists globally. (#2331)
48
- - **Mobile-responsive web UI** — the browser interface now works on phones and tablets. (#2354)
49
- - **DB tool previews** — `renderCall`/`renderResult` previews on DB tools show what each tool call does before and after execution. (#2273)
50
- - **Message timestamps** — user and assistant messages now include timestamps. (#2368)
40
+ - **Capability-based model selection** replaced model-ID pattern matching with capability metadata, making custom provider integration more reliable. (#2548)
51
41
 
52
42
  ### Key Changes
53
43
 
54
- - **Default isolation mode changed to `none`** `git.isolation` now defaults to `none` instead of `worktree`. Projects that rely on worktree isolation should set `git.isolation: worktree` explicitly in preferences. (#2481)
55
- - **Startup checks** — GSD now validates Node.js version and git availability at startup, with clear error messages. (#2463)
56
- - **Worktree lifecycle journaling** — worktree create, switch, merge, and remove events are recorded in the event journal. (#2486)
57
- - **Milestone verification gate** — milestone completion is blocked when verification fails, preventing premature closure. (#2500)
44
+ - **`--bare` mode**wired across headless, pi-coding-agent, and resource-loader for minimal-output operation.
45
+ - **RPC protocol v2** — new types, init handshake with version detection, and runId generation on prompt/steer/follow_up commands.
46
+ - **PREFERENCES.md rename** — `preferences.md` renamed to `PREFERENCES.md` for consistency. (#2700, #2738)
47
+ - **Comprehensive SQLite audit** — indexes, caching, safety, and reconciliation fixes across gsd-db.
48
+ - **Unified error classifier** — three overlapping error classifiers consolidated into a single classify-decide-act pipeline.
58
49
 
59
50
  ### Key Fixes
60
51
 
61
- - **Auto-mode stability** — recovery attempts reset on unit re-dispatch (#2424), survivor branch recovery handles `phase=complete` (#2427), and auto mode stops on real merge conflicts (#2428).
62
- - **Supervision timeouts** — now respect task `est:` annotations, so complex tasks get proportionally longer timeouts. (#2434)
63
- - **`auto_pr: true` fixed** — three interacting bugs prevented auto-PR creation; all three are resolved. (#2433)
64
- - **Rich task plan preservation** — plans survive DB roundtrip without losing structured content. (#2453)
65
- - **Artifact truncation prevention** — `saveArtifactToDb` no longer overwrites larger files with truncated content. (#2447)
66
- - **Worktree teardown** — submodule state is detected and preserved during teardown (#2425), and worktree merge back to main works after `stopAuto` on milestone completion (#2430).
67
- - **Windows portability** — `retentionDays=0` handling and CRLF fixes on Windows. (#2460)
68
- - **Voice on Linux** — misleading portaudio error on PEP 668 systems replaced with actionable guidance. (#2407)
52
+ - **Auto-mode stops on provider errors** — auto loop now halts after provider errors instead of retrying indefinitely. (#2762, #2764)
53
+ - **Transaction safety** — state machine guards moved inside transactions in 5 tool handlers (#2752), and `transaction()` made re-entrant.
54
+ - **Worktree seeding** — `preferences.md` seeded into auto-mode worktrees and included in worktree sync. (#2693)
55
+ - **Idle watchdog** — interactive tools exempted from stall detection (#2676), and filesystem activity no longer overrides stalled-tool detection. (#2697)
56
+ - **Milestone guards** — `allSlicesDone` guarded against vacuous truth on empty slice arrays (#2679), and `complete-milestone` dispatch blocked when validation is `needs-remediation`. (#2682)
57
+ - **Docker overhaul** — fragile setup replaced with proven container patterns. (#2716)
58
+ - **Windows** — EINVAL prevented by disabling detached process groups on Win32. (#2744)
59
+ - **Audit log** — `setLogBasePath` wired into engine init to resurrect audit logging. (#2745)
60
+
61
+ ### v2.51.0 — Skills, RTK, and Verification
62
+
63
+ - **`/terminal` command** — direct shell execution from the slash command interface. (#2349)
64
+ - **Managed RTK integration** — RTK binary auto-provisioned with opt-in preference and web UI toggle. (#2620)
65
+ - **Verification classes** — compliance checked before milestone completion, with classes injected into validation prompts. (#2621, #2623)
66
+ - **Skills overhaul** — 30+ new skill packs covering major frameworks, databases, and cloud platforms; curated catalog with `~/.agents/skills/` as primary directory.
67
+
68
+ ### v2.50.0 — Quality Gates
69
+
70
+ - **Quality gates** — 8-question quality gates added to planning and completion templates, with parallel evaluation via `evaluating-gates` phase.
71
+ - **Structured error propagation** — errors wired through `UnitResult` for better diagnostics.
72
+
73
+ ### v2.49.0 — Git Trailers & Yolo Mode
74
+
75
+ - **`--yolo` flag** — `/gsd auto --yolo` for non-interactive project init.
76
+ - **Git trailers** — GSD metadata moved from commit subject scopes to git trailers.
77
+
78
+ ### v2.48.0 — Forensics & Discussion
79
+
80
+ - **`/gsd discuss` for queued milestones** — target milestones still in the queue. (#2349)
81
+ - **Enhanced forensics** — journal and activity log awareness added to `/gsd forensics`.
82
+
83
+ ### v2.47.0 — External Providers
84
+
85
+ - **External tool execution mode** — `externalToolExecution` mode for external providers in agent-core.
86
+ - **Claude Code CLI provider** — new provider extension for Claude Code CLI. (#2382)
69
87
 
70
- ### Previous highlights (v2.42–v2.44)
88
+ ### Previous highlights (v2.42–v2.46)
71
89
 
90
+ - **Single-writer state engine** — disciplined state transitions with machine guards, actor identity, reversibility, and TOCTOU hardening. (#2494)
91
+ - **`/gsd rethink`** — conversational project reorganization. (#2459)
92
+ - **`/gsd mcp`** — MCP server status and connectivity. (#2362)
93
+ - **Complete offline mode** — fully offline with local models. (#2429)
94
+ - **Global KNOWLEDGE.md injection** — cross-project knowledge via `~/.gsd/agent/KNOWLEDGE.md`. (#2331)
95
+ - **Mobile-responsive web UI** — browser interface works on phones and tablets. (#2354)
96
+ - **Default isolation mode changed to `none`** — set `git.isolation: worktree` explicitly if needed. (#2481)
72
97
  - **Non-API-key provider extensions** — support for Claude Code CLI and similar providers. (#2382)
73
98
  - **Docker sandbox template** — official Docker template for isolated auto mode. (#2360)
74
99
  - **DB-backed planning tools** — write-side state transitions use atomic SQLite tool calls. (#2141)
75
100
  - **Declarative workflow engine** — YAML workflows through auto-loop. (#2024)
76
101
  - **`/gsd fast`** — toggle service tier for prioritized API routing. (#1862)
77
- - **Forensics dedup** — duplicate detection before issue creation. (#2105)
78
- - **Startup optimizations** — pre-compiled extensions, compile cache, batch discovery. (#2125)
79
102
 
80
103
  ---
81
104
 
@@ -521,7 +544,7 @@ An auto-generated `index.html` shows all reports with progression metrics across
521
544
 
522
545
  ### Preferences
523
546
 
524
- GSD preferences live in `~/.gsd/preferences.md` (global) or `.gsd/preferences.md` (project). Manage with `/gsd prefs`.
547
+ GSD preferences live in `~/.gsd/PREFERENCES.md` (global) or `.gsd/PREFERENCES.md` (project). Manage with `/gsd prefs`.
525
548
 
526
549
  ```yaml
527
550
  ---
@@ -672,7 +695,7 @@ The best practice for working in teams is to ensure unique milestone names acros
672
695
 
673
696
  ### Unique Milestone Names
674
697
 
675
- Create or amend your `.gsd/preferences.md` file within the repo to include `unique_milestone_ids: true` e.g.
698
+ Create or amend your `.gsd/PREFERENCES.md` file within the repo to include `unique_milestone_ids: true` e.g.
676
699
 
677
700
  ```markdown
678
701
  ---
@@ -681,7 +704,7 @@ unique_milestone_ids: true
681
704
  ---
682
705
  ```
683
706
 
684
- With the above `.gitignore` set up, the `.gsd/preferences.md` file is checked into the repo ensuring all teammates use unique milestone names to avoid collisions.
707
+ With the above `.gitignore` set up, the `.gsd/PREFERENCES.md` file is checked into the repo ensuring all teammates use unique milestone names to avoid collisions.
685
708
 
686
709
  Milestone names will now be generated with a 6 char random string appended e.g. instead of `M001` you'll get something like `M001-ush8s3`
687
710
 
@@ -689,7 +712,7 @@ Milestone names will now be generated with a 6 char random string appended e.g.
689
712
 
690
713
  1. Ensure you are not in the middle of any milestones (clean state)
691
714
  2. Update the `.gsd/` related entries in your `.gitignore` to follow the `Suggested .gitignore setup` section under `Working in teams` (ensure you are no longer blanket ignoring the whole `.gsd/` directory)
692
- 3. Update your `.gsd/preferences.md` file within the repo as per section `Unique Milestone Names`
715
+ 3. Update your `.gsd/PREFERENCES.md` file within the repo as per section `Unique Milestone Names`
693
716
  4. If you want to update all your existing milestones use this prompt in GSD: `I have turned on unique milestone ids, please update all old milestone ids to use this new format e.g. M001-abc123 where abc123 is a random 6 char lowercase alpha numeric string. Update all references in all .gsd file contents, file names and directory names. Validate your work once done to ensure referential integrity.`
694
717
  5. Commit to git
695
718
 
@@ -3,7 +3,25 @@
3
3
  *
4
4
  * Detects terminal notifications, blocked notifications, milestone-ready signals,
5
5
  * and classifies commands as quick (single-turn) vs long-running.
6
+ *
7
+ * Also defines exit code constants and the status→exit-code mapping function.
8
+ */
9
+ export declare const EXIT_SUCCESS = 0;
10
+ export declare const EXIT_ERROR = 1;
11
+ export declare const EXIT_BLOCKED = 10;
12
+ export declare const EXIT_CANCELLED = 11;
13
+ /**
14
+ * Map a headless session status string to its standardized exit code.
15
+ *
16
+ * success → 0
17
+ * error → 1
18
+ * timeout → 1
19
+ * blocked → 10
20
+ * cancelled → 11
21
+ *
22
+ * Unknown statuses default to EXIT_ERROR (1).
6
23
  */
24
+ export declare function mapStatusToExitCode(status: string): number;
7
25
  /**
8
26
  * Detect genuine auto-mode termination notifications.
9
27
  *
@@ -3,7 +3,43 @@
3
3
  *
4
4
  * Detects terminal notifications, blocked notifications, milestone-ready signals,
5
5
  * and classifies commands as quick (single-turn) vs long-running.
6
+ *
7
+ * Also defines exit code constants and the status→exit-code mapping function.
8
+ */
9
+ // ---------------------------------------------------------------------------
10
+ // Exit Code Constants
11
+ // ---------------------------------------------------------------------------
12
+ export const EXIT_SUCCESS = 0;
13
+ export const EXIT_ERROR = 1;
14
+ export const EXIT_BLOCKED = 10;
15
+ export const EXIT_CANCELLED = 11;
16
+ /**
17
+ * Map a headless session status string to its standardized exit code.
18
+ *
19
+ * success → 0
20
+ * error → 1
21
+ * timeout → 1
22
+ * blocked → 10
23
+ * cancelled → 11
24
+ *
25
+ * Unknown statuses default to EXIT_ERROR (1).
6
26
  */
27
+ export function mapStatusToExitCode(status) {
28
+ switch (status) {
29
+ case 'success':
30
+ case 'complete':
31
+ return EXIT_SUCCESS;
32
+ case 'error':
33
+ case 'timeout':
34
+ return EXIT_ERROR;
35
+ case 'blocked':
36
+ return EXIT_BLOCKED;
37
+ case 'cancelled':
38
+ return EXIT_CANCELLED;
39
+ default:
40
+ return EXIT_ERROR;
41
+ }
42
+ }
7
43
  // ---------------------------------------------------------------------------
8
44
  // Completion Detection
9
45
  // ---------------------------------------------------------------------------
@@ -36,7 +36,7 @@ export async function handleQuery(basePath) {
36
36
  const state = await deriveState(basePath);
37
37
  // Derive next dispatch action
38
38
  let next;
39
- if (!state.activeMilestone) {
39
+ if (!state.activeMilestone?.id) {
40
40
  next = {
41
41
  action: 'stop',
42
42
  reason: state.phase === 'complete' ? 'All milestones complete.' : state.nextAction,
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Headless Types — shared types for the headless orchestrator surface.
3
+ *
4
+ * Contains the structured result type emitted in --output-format json mode
5
+ * and the output format discriminator.
6
+ */
7
+ export type OutputFormat = 'text' | 'json' | 'stream-json';
8
+ export declare const VALID_OUTPUT_FORMATS: ReadonlySet<string>;
9
+ export interface HeadlessJsonResult {
10
+ status: 'success' | 'error' | 'blocked' | 'cancelled' | 'timeout';
11
+ exitCode: number;
12
+ sessionId?: string;
13
+ duration: number;
14
+ cost: {
15
+ total: number;
16
+ input_tokens: number;
17
+ output_tokens: number;
18
+ cache_read_tokens: number;
19
+ cache_write_tokens: number;
20
+ };
21
+ toolCalls: number;
22
+ events: number;
23
+ milestone?: string;
24
+ phase?: string;
25
+ nextAction?: string;
26
+ artifacts?: string[];
27
+ commits?: string[];
28
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Headless Types — shared types for the headless orchestrator surface.
3
+ *
4
+ * Contains the structured result type emitted in --output-format json mode
5
+ * and the output format discriminator.
6
+ */
7
+ export const VALID_OUTPUT_FORMATS = new Set(['text', 'json', 'stream-json']);
@@ -6,13 +6,16 @@
6
6
  * progress to stderr.
7
7
  *
8
8
  * Exit codes:
9
- * 0 — complete (command finished successfully)
10
- * 1 — error or timeout
11
- * 2 — blocked (command reported a blocker)
9
+ * 0 — complete (command finished successfully)
10
+ * 1 — error or timeout
11
+ * 10 — blocked (command reported a blocker)
12
+ * 11 — cancelled (SIGINT/SIGTERM received)
12
13
  */
14
+ import type { OutputFormat } from './headless-types.js';
13
15
  export interface HeadlessOptions {
14
16
  timeout: number;
15
17
  json: boolean;
18
+ outputFormat: OutputFormat;
16
19
  model?: string;
17
20
  command: string;
18
21
  commandArgs: string[];
@@ -25,6 +28,8 @@ export interface HeadlessOptions {
25
28
  responseTimeout?: number;
26
29
  answers?: string;
27
30
  eventFilter?: Set<string>;
31
+ resumeSession?: string;
32
+ bare?: boolean;
28
33
  }
29
34
  export declare function parseHeadlessArgs(argv: string[]): HeadlessOptions;
30
35
  export declare function runHeadless(options: HeadlessOptions): Promise<void>;
package/dist/headless.js CHANGED
@@ -6,16 +6,18 @@
6
6
  * progress to stderr.
7
7
  *
8
8
  * Exit codes:
9
- * 0 — complete (command finished successfully)
10
- * 1 — error or timeout
11
- * 2 — blocked (command reported a blocker)
9
+ * 0 — complete (command finished successfully)
10
+ * 1 — error or timeout
11
+ * 10 — blocked (command reported a blocker)
12
+ * 11 — cancelled (SIGINT/SIGTERM received)
12
13
  */
13
14
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
14
15
  import { join } from 'node:path';
15
16
  import { resolve } from 'node:path';
16
17
  import { RpcClient } from '@gsd/pi-coding-agent';
17
18
  import { loadAndValidateAnswerFile, AnswerInjector } from './headless-answers.js';
18
- import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, } from './headless-events.js';
19
+ import { isTerminalNotification, isBlockedNotification, isMilestoneReadyNotification, isQuickCommand, FIRE_AND_FORGET_METHODS, IDLE_TIMEOUT_MS, NEW_MILESTONE_IDLE_TIMEOUT_MS, EXIT_SUCCESS, EXIT_ERROR, EXIT_BLOCKED, EXIT_CANCELLED, } from './headless-events.js';
20
+ import { VALID_OUTPUT_FORMATS } from './headless-types.js';
19
21
  import { handleExtensionUIRequest, formatProgress, startSupervisedStdinReader, } from './headless-ui.js';
20
22
  import { loadContext, bootstrapGsdProject, } from './headless-context.js';
21
23
  // ---------------------------------------------------------------------------
@@ -25,6 +27,7 @@ export function parseHeadlessArgs(argv) {
25
27
  const options = {
26
28
  timeout: 300_000,
27
29
  json: false,
30
+ outputFormat: 'text',
28
31
  command: 'auto',
29
32
  commandArgs: [],
30
33
  };
@@ -44,6 +47,18 @@ export function parseHeadlessArgs(argv) {
44
47
  }
45
48
  else if (arg === '--json') {
46
49
  options.json = true;
50
+ options.outputFormat = 'stream-json';
51
+ }
52
+ else if (arg === '--output-format' && i + 1 < args.length) {
53
+ const fmt = args[++i];
54
+ if (!VALID_OUTPUT_FORMATS.has(fmt)) {
55
+ process.stderr.write(`[headless] Error: --output-format must be one of: text, json, stream-json (got '${fmt}')\n`);
56
+ process.exit(1);
57
+ }
58
+ options.outputFormat = fmt;
59
+ if (fmt === 'stream-json' || fmt === 'json') {
60
+ options.json = true;
61
+ }
47
62
  }
48
63
  else if (arg === '--model' && i + 1 < args.length) {
49
64
  // --model can also be passed from the main CLI; headless-specific takes precedence
@@ -74,10 +89,16 @@ export function parseHeadlessArgs(argv) {
74
89
  else if (arg === '--events' && i + 1 < args.length) {
75
90
  options.eventFilter = new Set(args[++i].split(','));
76
91
  options.json = true; // --events implies --json
92
+ if (options.outputFormat === 'text') {
93
+ options.outputFormat = 'stream-json';
94
+ }
77
95
  }
78
96
  else if (arg === '--supervised') {
79
97
  options.supervised = true;
80
98
  options.json = true; // supervised implies json
99
+ if (options.outputFormat === 'text') {
100
+ options.outputFormat = 'stream-json';
101
+ }
81
102
  }
82
103
  else if (arg === '--response-timeout' && i + 1 < args.length) {
83
104
  options.responseTimeout = parseInt(args[++i], 10);
@@ -86,6 +107,12 @@ export function parseHeadlessArgs(argv) {
86
107
  process.exit(1);
87
108
  }
88
109
  }
110
+ else if (arg === '--resume' && i + 1 < args.length) {
111
+ options.resumeSession = args[++i];
112
+ }
113
+ else if (arg === '--bare') {
114
+ options.bare = true;
115
+ }
89
116
  }
90
117
  else if (!positionalStarted) {
91
118
  positionalStarted = true;
@@ -106,7 +133,7 @@ export async function runHeadless(options) {
106
133
  while (true) {
107
134
  const result = await runHeadlessOnce(options, restartCount);
108
135
  // Success or blocked — exit normally
109
- if (result.exitCode === 0 || result.exitCode === 2) {
136
+ if (result.exitCode === EXIT_SUCCESS || result.exitCode === EXIT_BLOCKED) {
110
137
  process.exit(result.exitCode);
111
138
  }
112
139
  // Crash/error — check if we should restart
@@ -216,6 +243,10 @@ async function runHeadlessOnce(options, restartCount) {
216
243
  if (injector) {
217
244
  clientOptions.env = injector.getSecretEnvVars();
218
245
  }
246
+ // Propagate --bare to the child process
247
+ if (options.bare) {
248
+ clientOptions.args = [...(clientOptions.args || []), '--bare'];
249
+ }
219
250
  const client = new RpcClient(clientOptions);
220
251
  // Event tracking
221
252
  let totalEvents = 0;
@@ -278,7 +309,7 @@ async function runHeadlessOnce(options, restartCount) {
278
309
  const timeoutTimer = options.timeout > 0
279
310
  ? setTimeout(() => {
280
311
  process.stderr.write(`[headless] Timeout after ${options.timeout / 1000}s\n`);
281
- exitCode = 1;
312
+ exitCode = EXIT_ERROR;
282
313
  resolveCompletion();
283
314
  }, options.timeout)
284
315
  : null;
@@ -319,7 +350,7 @@ async function runHeadlessOnce(options, restartCount) {
319
350
  if (injector && !FIRE_AND_FORGET_METHODS.has(String(eventObj.method ?? ''))) {
320
351
  if (injector.tryHandle(eventObj, stdinWriter)) {
321
352
  if (completed) {
322
- exitCode = blocked ? 2 : 0;
353
+ exitCode = blocked ? EXIT_BLOCKED : EXIT_SUCCESS;
323
354
  resolveCompletion();
324
355
  }
325
356
  return;
@@ -343,7 +374,7 @@ async function runHeadlessOnce(options, restartCount) {
343
374
  }
344
375
  // If we detected a terminal notification, resolve after responding
345
376
  if (completed) {
346
- exitCode = blocked ? 2 : 0;
377
+ exitCode = blocked ? EXIT_BLOCKED : EXIT_SUCCESS;
347
378
  resolveCompletion();
348
379
  return;
349
380
  }
@@ -361,7 +392,7 @@ async function runHeadlessOnce(options, restartCount) {
361
392
  const signalHandler = () => {
362
393
  process.stderr.write('\n[headless] Interrupted, stopping child process...\n');
363
394
  interrupted = true;
364
- exitCode = 1;
395
+ exitCode = EXIT_CANCELLED;
365
396
  client.stop().finally(() => {
366
397
  if (timeoutTimer)
367
398
  clearTimeout(timeoutTimer);
@@ -411,7 +442,7 @@ async function runHeadlessOnce(options, restartCount) {
411
442
  if (!completed) {
412
443
  const msg = `[headless] Child process exited unexpectedly with code ${code ?? 'null'}\n`;
413
444
  process.stderr.write(msg);
414
- exitCode = 1;
445
+ exitCode = EXIT_ERROR;
415
446
  resolveCompletion();
416
447
  }
417
448
  });
@@ -425,14 +456,14 @@ async function runHeadlessOnce(options, restartCount) {
425
456
  }
426
457
  catch (err) {
427
458
  process.stderr.write(`[headless] Error: Failed to send prompt: ${err instanceof Error ? err.message : String(err)}\n`);
428
- exitCode = 1;
459
+ exitCode = EXIT_ERROR;
429
460
  }
430
461
  // Wait for completion
431
- if (exitCode === 0 || exitCode === 2) {
462
+ if (exitCode === EXIT_SUCCESS || exitCode === EXIT_BLOCKED) {
432
463
  await completionPromise;
433
464
  }
434
465
  // Auto-mode chaining: if --auto and milestone creation succeeded, send /gsd auto
435
- if (isNewMilestone && options.auto && milestoneReady && !blocked && exitCode === 0) {
466
+ if (isNewMilestone && options.auto && milestoneReady && !blocked && exitCode === EXIT_SUCCESS) {
436
467
  if (!options.json) {
437
468
  process.stderr.write('[headless] Milestone ready — chaining into auto-mode...\n');
438
469
  }
@@ -451,9 +482,9 @@ async function runHeadlessOnce(options, restartCount) {
451
482
  }
452
483
  catch (err) {
453
484
  process.stderr.write(`[headless] Error: Failed to start auto-mode: ${err instanceof Error ? err.message : String(err)}\n`);
454
- exitCode = 1;
485
+ exitCode = EXIT_ERROR;
455
486
  }
456
- if (exitCode === 0 || exitCode === 2) {
487
+ if (exitCode === EXIT_SUCCESS || exitCode === EXIT_BLOCKED) {
457
488
  await autoCompletionPromise;
458
489
  }
459
490
  }
@@ -471,7 +502,7 @@ async function runHeadlessOnce(options, restartCount) {
471
502
  await client.stop();
472
503
  // Summary
473
504
  const duration = ((Date.now() - startTime) / 1000).toFixed(1);
474
- const status = blocked ? 'blocked' : exitCode === 1 ? (totalEvents === 0 ? 'error' : 'timeout') : 'complete';
505
+ const status = blocked ? 'blocked' : exitCode === EXIT_CANCELLED ? 'cancelled' : exitCode === EXIT_ERROR ? (totalEvents === 0 ? 'error' : 'timeout') : 'complete';
475
506
  process.stderr.write(`[headless] Status: ${status}\n`);
476
507
  process.stderr.write(`[headless] Duration: ${duration}s\n`);
477
508
  process.stderr.write(`[headless] Events: ${totalEvents} total, ${toolCallCount} tool calls\n`);
package/dist/help-text.js CHANGED
@@ -87,9 +87,12 @@ const SUBCOMMAND_HELP = {
87
87
  'Run /gsd commands without the TUI. Default command: auto',
88
88
  '',
89
89
  'Flags:',
90
- ' --timeout N Overall timeout in ms (default: 300000)',
91
- ' --json JSONL event stream to stdout',
92
- ' --model ID Override model',
90
+ ' --timeout N Overall timeout in ms (default: 300000)',
91
+ ' --json JSONL event stream to stdout (alias for --output-format stream-json)',
92
+ ' --output-format <fmt> Output format: text (default), json (structured result), stream-json (JSONL events)',
93
+ ' --bare Minimal context: skip CLAUDE.md, AGENTS.md, user settings, user skills',
94
+ ' --resume <id> Resume a prior headless session by ID',
95
+ ' --model ID Override model',
93
96
  ' --supervised Forward interactive UI requests to orchestrator via stdout/stdin',
94
97
  ' --response-timeout N Timeout (ms) for orchestrator response (default: 30000)',
95
98
  ' --answers <path> Pre-supply answers and secrets (JSON file)',
@@ -108,11 +111,19 @@ const SUBCOMMAND_HELP = {
108
111
  ' --auto Start auto-mode after milestone creation',
109
112
  ' --verbose Show tool calls in progress output',
110
113
  '',
114
+ 'Output formats:',
115
+ ' text Human-readable progress on stderr (default)',
116
+ ' json Collect events silently, emit structured HeadlessJsonResult on stdout at exit',
117
+ ' stream-json Stream JSONL events to stdout in real time (same as --json)',
118
+ '',
111
119
  'Examples:',
112
120
  ' gsd headless Run /gsd auto',
113
121
  ' gsd headless next Run one unit',
114
- ' gsd headless --json status Machine-readable status',
122
+ ' gsd headless --output-format json auto Structured JSON result on stdout',
123
+ ' gsd headless --json status Machine-readable JSONL stream',
115
124
  ' gsd headless --timeout 60000 With 1-minute timeout',
125
+ ' gsd headless --bare auto Minimal context (CI/ecosystem use)',
126
+ ' gsd headless --resume abc123 auto Resume a prior session',
116
127
  ' gsd headless new-milestone --context spec.md Create milestone from file',
117
128
  ' cat spec.md | gsd headless new-milestone --context - From stdin',
118
129
  ' gsd headless new-milestone --context spec.md --auto Create + auto-execute',
@@ -121,7 +132,7 @@ const SUBCOMMAND_HELP = {
121
132
  ' gsd headless --events agent_end,extension_ui_request auto Filtered event stream',
122
133
  ' gsd headless query Instant JSON state snapshot',
123
134
  '',
124
- 'Exit codes: 0 = complete, 1 = error/timeout, 2 = blocked',
135
+ 'Exit codes: 0 = success, 1 = error/timeout, 10 = blocked, 11 = cancelled',
125
136
  ].join('\n'),
126
137
  };
127
138
  // Alias: `gsd wt --help` → same as `gsd worktree --help`
@@ -568,10 +568,11 @@ async function runToolKeysStep(p, pc, authStorage) {
568
568
  }
569
569
  // ─── Remote Questions Step ────────────────────────────────────────────────────
570
570
  async function runRemoteQuestionsStep(p, pc, authStorage) {
571
- // Check existing config
572
- const hasDiscord = authStorage.has('discord_bot') && !!authStorage.get('discord_bot')?.key;
573
- const hasSlack = authStorage.has('slack_bot') && !!authStorage.get('slack_bot')?.key;
574
- const hasTelegram = authStorage.has('telegram_bot') && !!authStorage.get('telegram_bot')?.key;
571
+ // Check existing config — use getCredentialsForProvider to skip empty-key entries
572
+ const hasValidKey = (provider) => authStorage.getCredentialsForProvider(provider).some((c) => c.type === 'api_key' && c.key);
573
+ const hasDiscord = hasValidKey('discord_bot');
574
+ const hasSlack = hasValidKey('slack_bot');
575
+ const hasTelegram = hasValidKey('telegram_bot');
575
576
  const existingChannel = hasDiscord ? 'Discord' : hasSlack ? 'Slack' : hasTelegram ? 'Telegram' : null;
576
577
  const options = [];
577
578
  if (existingChannel) {
@@ -14,7 +14,7 @@ import { appRoot } from "./app-paths.js";
14
14
  // boundary — this file is compiled by tsc, but preferences.ts is loaded
15
15
  // via jiti at runtime. Importing it as .js fails because no .js exists
16
16
  // in dist/. See #592, #1110.
17
- const GLOBAL_PREFERENCES_PATH = join(appRoot, "preferences.md");
17
+ const GLOBAL_PREFERENCES_PATH = join(appRoot, "PREFERENCES.md");
18
18
  export function saveRemoteQuestionsConfig(channel, channelId) {
19
19
  const prefsPath = GLOBAL_PREFERENCES_PATH;
20
20
  const block = [
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { getShellConfig, sanitizeCommand, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, } from "@gsd/pi-coding-agent";
9
9
  import { Type } from "@sinclair/typebox";
10
- import { spawn } from "node:child_process";
10
+ import { spawn, spawnSync } from "node:child_process";
11
11
  import { createWriteStream } from "node:fs";
12
12
  import { tmpdir } from "node:os";
13
13
  import { join } from "node:path";
@@ -23,19 +23,33 @@ function getTempFilePath() {
23
23
  return join(tmpdir(), `pi-async-bash-${id}.log`);
24
24
  }
25
25
  /**
26
- * Kill a process and its children. Uses process group kill on Unix.
26
+ * Kill a process and its children (cross-platform).
27
+ * Uses process group kill on Unix; taskkill /F /T on Windows.
27
28
  */
28
29
  function killTree(pid) {
29
- try {
30
- // Kill the process group (negative PID)
31
- process.kill(-pid, "SIGTERM");
30
+ if (process.platform === "win32") {
31
+ try {
32
+ spawnSync("taskkill", ["/F", "/T", "/PID", String(pid)], {
33
+ timeout: 5_000,
34
+ stdio: "ignore",
35
+ });
36
+ }
37
+ catch {
38
+ try {
39
+ process.kill(pid, "SIGTERM");
40
+ }
41
+ catch { /* already exited */ }
42
+ }
32
43
  }
33
- catch {
44
+ else {
34
45
  try {
35
- process.kill(pid, "SIGTERM");
46
+ process.kill(-pid, "SIGTERM");
36
47
  }
37
48
  catch {
38
- // Already exited
49
+ try {
50
+ process.kill(pid, "SIGTERM");
51
+ }
52
+ catch { /* already exited */ }
39
53
  }
40
54
  }
41
55
  }
@@ -96,9 +110,13 @@ function executeBashInBackground(command, cwd, signal, timeout) {
96
110
  const { shell, args } = getShellConfig();
97
111
  const rewrittenCommand = rewriteCommandWithRtk(command);
98
112
  const resolvedCommand = sanitizeCommand(rewrittenCommand);
113
+ // On Windows, detached: true sets CREATE_NEW_PROCESS_GROUP which can
114
+ // cause EINVAL in VSCode/ConPTY terminal contexts. The bg-shell
115
+ // extension already guards this (process-manager.ts); align here.
116
+ // Process-tree cleanup uses taskkill /F /T on Windows regardless.
99
117
  const child = spawn(shell, [...args, resolvedCommand], {
100
118
  cwd,
101
- detached: true,
119
+ detached: process.platform !== "win32",
102
120
  env: { ...process.env },
103
121
  stdio: ["ignore", "pipe", "pipe"],
104
122
  });
@@ -118,14 +136,8 @@ function executeBashInBackground(command, cwd, signal, timeout) {
118
136
  // If the process ignores SIGTERM, escalate to SIGKILL
119
137
  sigkillHandle = setTimeout(() => {
120
138
  if (child.pid) {
121
- try {
122
- process.kill(-child.pid, "SIGKILL");
123
- }
124
- catch { /* ignore */ }
125
- try {
126
- process.kill(child.pid, "SIGKILL");
127
- }
128
- catch { /* ignore */ }
139
+ // killTree already uses taskkill /F /T on Windows
140
+ killTree(child.pid);
129
141
  }
130
142
  // Hard deadline: if even SIGKILL doesn't trigger 'close',
131
143
  // force-resolve so the job doesn't hang forever (#2186).
@@ -121,7 +121,10 @@ export class AsyncJobManager {
121
121
  deliverResult(job) {
122
122
  if (!this.onJobComplete)
123
123
  return;
124
- this.onJobComplete(job);
124
+ // Defer delivery by one microtask so await_job's .then() chain runs first
125
+ // and can set job.awaited = true before onJobComplete checks it (#2762).
126
+ const cb = this.onJobComplete;
127
+ queueMicrotask(() => cb(job));
125
128
  }
126
129
  scheduleEviction(id) {
127
130
  const existing = this.evictionTimers.get(id);