gsd-pi 2.41.0 → 2.42.0-dev.97e9e30

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 (383) hide show
  1. package/README.md +69 -29
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/onboarding.js +2 -1
  5. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  6. package/dist/resources/extensions/gsd/auto/phases.js +28 -10
  7. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  11. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  12. package/dist/resources/extensions/gsd/auto-start.js +8 -3
  13. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  14. package/dist/resources/extensions/gsd/auto.js +64 -2
  15. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  16. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  17. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  18. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +16 -0
  19. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  20. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  21. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  22. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  23. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  24. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  25. package/dist/resources/extensions/gsd/context-store.js +4 -3
  26. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  27. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  28. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  29. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  30. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  31. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  32. package/dist/resources/extensions/gsd/detection.js +1 -1
  33. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  34. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  35. package/dist/resources/extensions/gsd/doctor.js +11 -1
  36. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  37. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  38. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  39. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  40. package/dist/resources/extensions/gsd/export.js +9 -13
  41. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  42. package/dist/resources/extensions/gsd/files.js +28 -11
  43. package/dist/resources/extensions/gsd/forensics.js +10 -3
  44. package/dist/resources/extensions/gsd/git-service.js +5 -1
  45. package/dist/resources/extensions/gsd/graph.js +225 -0
  46. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  47. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  48. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  49. package/dist/resources/extensions/gsd/journal.js +85 -0
  50. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  51. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +2 -2
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  54. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  55. package/dist/resources/extensions/gsd/preferences.js +1 -0
  56. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  57. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  58. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  59. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  61. package/dist/resources/extensions/gsd/repo-identity.js +46 -2
  62. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  63. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  64. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  65. package/dist/resources/extensions/gsd/service-tier.js +138 -0
  66. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  67. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  68. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  69. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  70. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  71. package/dist/resources/extensions/gsd/worktree-resolver.js +19 -2
  72. package/dist/resources/extensions/subagent/index.js +7 -3
  73. package/dist/resources/extensions/voice/index.js +4 -4
  74. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  75. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  76. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  77. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  78. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  79. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  80. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  81. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  82. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  83. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  86. package/dist/web/standalone/.next/build-manifest.json +4 -4
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  89. package/dist/web/standalone/.next/required-server-files.json +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  91. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  101. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  155. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  175. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  177. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  179. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/index.html +1 -1
  189. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  192. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  194. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/page.js +2 -2
  196. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  198. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  199. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  200. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/middleware.js +2 -2
  203. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  205. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  206. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  207. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  208. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  209. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  210. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  211. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  212. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  213. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  214. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  215. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  216. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  217. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  218. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  219. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  220. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  221. package/dist/web/standalone/server.js +1 -1
  222. package/dist/web-mode.d.ts +2 -0
  223. package/dist/web-mode.js +29 -7
  224. package/package.json +1 -1
  225. package/packages/native/src/__tests__/text.test.mjs +33 -0
  226. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  227. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  229. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  230. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  234. package/packages/pi-coding-agent/package.json +1 -1
  235. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  236. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  237. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
  238. package/pkg/package.json +1 -1
  239. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
  240. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  241. package/src/resources/extensions/gsd/auto/phases.ts +30 -10
  242. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  243. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  244. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  245. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  246. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  247. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  248. package/src/resources/extensions/gsd/auto-start.ts +8 -3
  249. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  250. package/src/resources/extensions/gsd/auto.ts +71 -2
  251. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  252. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  253. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  254. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -0
  255. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  256. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  257. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  258. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  259. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  260. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  261. package/src/resources/extensions/gsd/context-store.ts +4 -3
  262. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  263. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  264. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  265. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  266. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  267. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  268. package/src/resources/extensions/gsd/detection.ts +1 -1
  269. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  270. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  271. package/src/resources/extensions/gsd/doctor.ts +12 -1
  272. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  273. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  274. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  275. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  276. package/src/resources/extensions/gsd/export.ts +8 -15
  277. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  278. package/src/resources/extensions/gsd/files.ts +29 -12
  279. package/src/resources/extensions/gsd/forensics.ts +9 -3
  280. package/src/resources/extensions/gsd/git-service.ts +5 -4
  281. package/src/resources/extensions/gsd/graph.ts +312 -0
  282. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  283. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  284. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  285. package/src/resources/extensions/gsd/journal.ts +134 -0
  286. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  287. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  288. package/src/resources/extensions/gsd/native-git-bridge.ts +2 -2
  289. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  290. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  291. package/src/resources/extensions/gsd/preferences.ts +1 -0
  292. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  293. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  294. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  295. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  296. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  297. package/src/resources/extensions/gsd/repo-identity.ts +47 -2
  298. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  299. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  300. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  301. package/src/resources/extensions/gsd/service-tier.ts +171 -0
  302. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  303. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  304. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  305. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  306. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  307. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  308. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  309. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  310. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  311. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  312. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  313. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  314. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  315. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  316. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  317. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  318. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  319. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  320. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  321. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  322. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  323. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  324. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  325. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  326. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  327. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  328. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  329. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  330. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  331. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  332. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  333. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  334. package/src/resources/extensions/gsd/tests/journal.test.ts +386 -0
  335. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  336. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  337. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  338. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  339. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  340. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  341. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  342. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  343. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  344. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  345. package/src/resources/extensions/gsd/tests/service-tier.test.ts +98 -0
  346. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  347. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  348. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  349. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  350. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  351. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  352. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  353. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  354. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  355. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +178 -0
  356. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +195 -105
  357. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
  358. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  359. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  360. package/src/resources/extensions/gsd/types.ts +3 -0
  361. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  362. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  363. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  364. package/src/resources/extensions/gsd/worktree-resolver.ts +30 -9
  365. package/src/resources/extensions/subagent/index.ts +7 -3
  366. package/src/resources/extensions/voice/index.ts +4 -4
  367. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  368. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  369. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  370. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  371. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  372. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  373. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  374. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  375. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  376. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  377. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  378. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  379. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  380. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  381. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  382. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → PXrI5DoWsm7rwAVnEU2rD}/_buildManifest.js +0 -0
  383. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → PXrI5DoWsm7rwAVnEU2rD}/_ssgManifest.js +0 -0
@@ -11,7 +11,7 @@
11
11
  import { deriveState } from "./state.js";
12
12
  import { loadFile, getManifestStatus } from "./files.js";
13
13
  import { loadEffectiveGSDPreferences, resolveSkillDiscoveryMode, getIsolationMode, } from "./preferences.js";
14
- import { ensureGsdSymlink, validateProjectId } from "./repo-identity.js";
14
+ import { ensureGsdSymlink, isInheritedRepo, validateProjectId } from "./repo-identity.js";
15
15
  import { migrateToExternalState, recoverFailedMigration } from "./migrate-external.js";
16
16
  import { collectSecretsFromManifest } from "../get-secrets-from-user.js";
17
17
  import { gsdRoot, resolveMilestoneFile } from "./paths.js";
@@ -69,8 +69,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
69
69
  ctx.ui.notify(`GSD_PROJECT_ID must contain only alphanumeric characters, hyphens, and underscores. Got: "${customProjectId}"`, "error");
70
70
  return releaseLockAndReturn();
71
71
  }
72
- // Ensure git repo exists
73
- if (!nativeIsRepo(base)) {
72
+ // Ensure git repo exists.
73
+ // Guard against inherited repos: if `base` is a subdirectory of another
74
+ // git repo that has no .gsd (i.e. the parent project was never initialised
75
+ // with GSD), create a fresh git repo at `base` so it gets its own identity
76
+ // hash. Without this, repoIdentity() resolves to the parent repo's hash
77
+ // and loads milestones from an unrelated project (#1639).
78
+ if (!nativeIsRepo(base) || isInheritedRepo(base)) {
74
79
  const mainBranch = loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
75
80
  nativeInit(base, mainBranch);
76
81
  }
@@ -5,21 +5,21 @@
5
5
  * manual `/worktree` which uses `worktree/<name>` branches). This module
6
6
  * manages create, enter, detect, and teardown for auto-mode worktrees.
7
7
  */
8
- import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
8
+ import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
9
9
  import { isAbsolute, join } from "node:path";
10
10
  import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
11
11
  import { copyWorktreeDb, reconcileWorktreeDb, isDbAvailable, } from "./gsd-db.js";
12
12
  import { atomicWriteSync } from "./atomic-write.js";
13
- import { execSync, execFileSync } from "node:child_process";
13
+ import { execFileSync } from "node:child_process";
14
14
  import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
15
15
  import { gsdRoot } from "./paths.js";
16
- import { createWorktree, removeWorktree, worktreePath, } from "./worktree-manager.js";
16
+ import { createWorktree, removeWorktree, resolveGitDir, worktreePath, } from "./worktree-manager.js";
17
17
  import { detectWorktreeName, nudgeGitBranchCache, } from "./worktree.js";
18
18
  import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } from "./git-service.js";
19
19
  import { debugLog } from "./debug-logger.js";
20
20
  import { parseRoadmap } from "./files.js";
21
21
  import { loadEffectiveGSDPreferences } from "./preferences.js";
22
- import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, } from "./native-git-bridge.js";
22
+ import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, } from "./native-git-bridge.js";
23
23
  // ─── Module State ──────────────────────────────────────────────────────────
24
24
  /** Original project root before chdir into auto-worktree. */
25
25
  let originalBase = null;
@@ -133,7 +133,7 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
133
133
  const mainMilestones = readdirSync(mainMilestonesDir, {
134
134
  withFileTypes: true,
135
135
  })
136
- .filter((d) => d.isDirectory() && /^M\d{3}/.test(d.name))
136
+ .filter((d) => d.isDirectory())
137
137
  .map((d) => d.name);
138
138
  for (const mid of mainMilestones) {
139
139
  const srcDir = join(mainMilestonesDir, mid);
@@ -287,7 +287,7 @@ export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
287
287
  return { synced };
288
288
  try {
289
289
  const wtMilestones = readdirSync(wtMilestonesDir, { withFileTypes: true })
290
- .filter((d) => d.isDirectory() && /^M\d{3}/.test(d.name))
290
+ .filter((d) => d.isDirectory())
291
291
  .map((d) => d.name);
292
292
  for (const mid of wtMilestones) {
293
293
  syncMilestoneDir(wtGsd, mainGsd, mid, synced);
@@ -405,13 +405,24 @@ export function runWorktreePostCreateHook(sourceDir, worktreeDir, hookPath) {
405
405
  }
406
406
  if (!hookPath)
407
407
  return null;
408
- // Resolve relative paths against the source project root
409
- const resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
408
+ // Resolve relative paths against the source project root.
409
+ // On Windows, convert 8.3 short paths (e.g. RUNNER~1) to long paths
410
+ // so execFileSync can locate the file correctly.
411
+ let resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
410
412
  if (!existsSync(resolved)) {
411
413
  return `Worktree post-create hook not found: ${resolved}`;
412
414
  }
415
+ if (process.platform === "win32") {
416
+ try {
417
+ resolved = realpathSync.native(resolved);
418
+ }
419
+ catch { /* keep original */ }
420
+ }
413
421
  try {
414
- execSync(resolved, {
422
+ // .bat/.cmd files on Windows require shell mode — execFileSync cannot
423
+ // spawn them directly (EINVAL).
424
+ const needsShell = process.platform === "win32" && /\.(bat|cmd)$/i.test(resolved);
425
+ execFileSync(resolved, [], {
415
426
  cwd: worktreeDir,
416
427
  env: {
417
428
  ...process.env,
@@ -421,6 +432,7 @@ export function runWorktreePostCreateHook(sourceDir, worktreeDir, hookPath) {
421
432
  stdio: ["ignore", "pipe", "pipe"],
422
433
  encoding: "utf-8",
423
434
  timeout: 30_000, // 30 second timeout
435
+ shell: needsShell,
424
436
  });
425
437
  return null;
426
438
  }
@@ -661,6 +673,22 @@ export function teardownAutoWorktree(originalBasePath, milestoneId, opts = {}) {
661
673
  branch,
662
674
  deleteBranch: !preserveBranch,
663
675
  });
676
+ // Verify cleanup succeeded — warn if the worktree directory is still on disk.
677
+ // On Windows, bash-based cleanup can silently fail when paths contain
678
+ // backslashes (#1436), leaving ~1 GB+ orphaned directories.
679
+ const wtDir = worktreePath(originalBasePath, milestoneId);
680
+ if (existsSync(wtDir)) {
681
+ console.error(`[GSD] WARNING: Worktree directory still exists after teardown: ${wtDir}\n` +
682
+ ` This is likely an orphaned directory consuming disk space.\n` +
683
+ ` Remove it manually with: rm -rf "${wtDir.replaceAll("\\", "/")}"`);
684
+ // Attempt a direct filesystem removal as a fallback
685
+ try {
686
+ rmSync(wtDir, { recursive: true, force: true });
687
+ }
688
+ catch {
689
+ // Non-fatal — the warning above tells the user how to clean up
690
+ }
691
+ }
664
692
  }
665
693
  /**
666
694
  * Detect if the process is currently inside an auto-worktree.
@@ -858,6 +886,56 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
858
886
  body = `\n\nCompleted slices:\n${sliceLines}\n\nBranch: ${milestoneBranch}`;
859
887
  }
860
888
  const commitMessage = subject + body;
889
+ // 6b. Reconcile worktree HEAD with milestone branch ref (#1846).
890
+ // When the worktree HEAD detaches and advances past the named branch,
891
+ // the branch ref becomes stale. Squash-merging the stale ref silently
892
+ // orphans all commits between the branch ref and the actual worktree HEAD.
893
+ // Fix: fast-forward the branch ref to the worktree HEAD before merging.
894
+ // Only applies when merging from an actual worktree (worktreeCwd differs
895
+ // from originalBasePath_).
896
+ if (worktreeCwd !== originalBasePath_) {
897
+ try {
898
+ const worktreeHead = execFileSync("git", ["rev-parse", "HEAD"], {
899
+ cwd: worktreeCwd,
900
+ stdio: ["ignore", "pipe", "pipe"],
901
+ encoding: "utf-8",
902
+ }).trim();
903
+ const branchHead = execFileSync("git", ["rev-parse", milestoneBranch], {
904
+ cwd: originalBasePath_,
905
+ stdio: ["ignore", "pipe", "pipe"],
906
+ encoding: "utf-8",
907
+ }).trim();
908
+ if (worktreeHead && branchHead && worktreeHead !== branchHead) {
909
+ if (nativeIsAncestor(originalBasePath_, branchHead, worktreeHead)) {
910
+ // Worktree HEAD is strictly ahead — fast-forward the branch ref
911
+ nativeUpdateRef(originalBasePath_, `refs/heads/${milestoneBranch}`, worktreeHead);
912
+ debugLog("mergeMilestoneToMain", {
913
+ action: "fast-forward-branch-ref",
914
+ milestoneBranch,
915
+ oldRef: branchHead.slice(0, 8),
916
+ newRef: worktreeHead.slice(0, 8),
917
+ });
918
+ }
919
+ else {
920
+ // Diverged — fail loudly rather than silently losing commits
921
+ process.chdir(previousCwd);
922
+ throw new GSDError(GSD_GIT_ERROR, `Worktree HEAD (${worktreeHead.slice(0, 8)}) diverged from ` +
923
+ `${milestoneBranch} (${branchHead.slice(0, 8)}). ` +
924
+ `Manual reconciliation required before merge.`);
925
+ }
926
+ }
927
+ }
928
+ catch (err) {
929
+ // Re-throw GSDError (divergence); swallow rev-parse failures
930
+ // (e.g. worktree dir already removed by external cleanup)
931
+ if (err instanceof GSDError)
932
+ throw err;
933
+ debugLog("mergeMilestoneToMain", {
934
+ action: "reconcile-skipped",
935
+ reason: String(err),
936
+ });
937
+ }
938
+ }
861
939
  // 7. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
862
940
  const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
863
941
  if (!mergeResult.success) {
@@ -905,6 +983,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
905
983
  // 8. Commit (handle nothing-to-commit gracefully)
906
984
  const commitResult = nativeCommit(originalBasePath_, commitMessage);
907
985
  const nothingToCommit = commitResult === null;
986
+ // 8a. Clean up SQUASH_MSG left by git merge --squash (#1853).
987
+ // git only removes SQUASH_MSG when the commit reads it directly (plain
988
+ // `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
989
+ // of which trigger git's SQUASH_MSG cleanup. If left on disk, doctor
990
+ // reports `corrupt_merge_state` on every subsequent run.
991
+ try {
992
+ const squashMsgPath = join(resolveGitDir(originalBasePath_), "SQUASH_MSG");
993
+ if (existsSync(squashMsgPath))
994
+ unlinkSync(squashMsgPath);
995
+ }
996
+ catch { /* best-effort */ }
908
997
  // 8b. Safety check (#1792): if nothing was committed, verify the milestone
909
998
  // work is already on the integration branch before allowing teardown.
910
999
  // Compare only non-.gsd/ paths — .gsd/ state files diverge normally and
@@ -920,12 +1009,27 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
920
1009
  `Aborting worktree teardown to prevent data loss.`);
921
1010
  }
922
1011
  }
1012
+ // 8c. Detect whether any non-.gsd/ code files were actually merged (#1906).
1013
+ // When a milestone only produced .gsd/ metadata (summaries, roadmaps) but no
1014
+ // real code, the user sees "milestone complete" but nothing changed in their
1015
+ // codebase. Surface this so the caller can warn the user.
1016
+ let codeFilesChanged = false;
1017
+ if (!nothingToCommit) {
1018
+ try {
1019
+ const mergedFiles = nativeDiffNumstat(originalBasePath_, "HEAD~1", "HEAD");
1020
+ codeFilesChanged = mergedFiles.some((entry) => !entry.path.startsWith(".gsd/"));
1021
+ }
1022
+ catch {
1023
+ // If HEAD~1 doesn't exist (first commit), assume code was changed
1024
+ codeFilesChanged = true;
1025
+ }
1026
+ }
923
1027
  // 9. Auto-push if enabled
924
1028
  let pushed = false;
925
1029
  if (prefs.auto_push === true && !nothingToCommit) {
926
1030
  const remote = prefs.remote ?? "origin";
927
1031
  try {
928
- execSync(`git push ${remote} ${mainBranch}`, {
1032
+ execFileSync("git", ["push", remote, mainBranch], {
929
1033
  cwd: originalBasePath_,
930
1034
  stdio: ["ignore", "pipe", "pipe"],
931
1035
  encoding: "utf-8",
@@ -943,13 +1047,19 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
943
1047
  const prTarget = prefs.pr_target_branch ?? mainBranch;
944
1048
  try {
945
1049
  // Push the milestone branch to remote first
946
- execSync(`git push ${remote} ${milestoneBranch}`, {
1050
+ execFileSync("git", ["push", remote, milestoneBranch], {
947
1051
  cwd: originalBasePath_,
948
1052
  stdio: ["ignore", "pipe", "pipe"],
949
1053
  encoding: "utf-8",
950
1054
  });
951
1055
  // Create PR via gh CLI
952
- execSync(`gh pr create --base "${prTarget}" --head "${milestoneBranch}" --title "Milestone ${milestoneId} complete" --body "Auto-created by GSD on milestone completion."`, {
1056
+ execFileSync("gh", [
1057
+ "pr", "create",
1058
+ "--base", prTarget,
1059
+ "--head", milestoneBranch,
1060
+ "--title", `Milestone ${milestoneId} complete`,
1061
+ "--body", "Auto-created by GSD on milestone completion.",
1062
+ ], {
953
1063
  cwd: originalBasePath_,
954
1064
  stdio: ["ignore", "pipe", "pipe"],
955
1065
  encoding: "utf-8",
@@ -963,6 +1073,30 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
963
1073
  // 10. Guard removed — step 8b (#1792) now handles this with a smarter check:
964
1074
  // throws only when the milestone has unanchored code changes, passes
965
1075
  // through when the code is genuinely already on the integration branch.
1076
+ // 10a. Pre-teardown safety net (#1853): if the worktree still has uncommitted
1077
+ // changes (e.g. nativeHasChanges cache returned stale false, or auto-commit
1078
+ // silently failed), force one final commit so code is not destroyed by
1079
+ // `git worktree remove --force`.
1080
+ if (existsSync(worktreeCwd)) {
1081
+ try {
1082
+ const dirtyCheck = nativeWorkingTreeStatus(worktreeCwd);
1083
+ if (dirtyCheck) {
1084
+ debugLog("mergeMilestoneToMain", {
1085
+ phase: "pre-teardown-dirty",
1086
+ worktreeCwd,
1087
+ status: dirtyCheck.slice(0, 200),
1088
+ });
1089
+ nativeAddAllWithExclusions(worktreeCwd, RUNTIME_EXCLUSION_PATHS);
1090
+ nativeCommit(worktreeCwd, "chore: pre-teardown auto-commit of uncommitted worktree changes");
1091
+ }
1092
+ }
1093
+ catch (e) {
1094
+ debugLog("mergeMilestoneToMain", {
1095
+ phase: "pre-teardown-commit-error",
1096
+ error: String(e),
1097
+ });
1098
+ }
1099
+ }
966
1100
  // 11. Remove worktree directory first (must happen before branch deletion)
967
1101
  try {
968
1102
  removeWorktree(originalBasePath_, milestoneId, {
@@ -983,5 +1117,5 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
983
1117
  // 13. Clear module state
984
1118
  originalBase = null;
985
1119
  nudgeGitBranchCache(previousCwd);
986
- return { commitMessage, pushed, prCreated };
1120
+ return { commitMessage, pushed, prCreated, codeFilesChanged };
987
1121
  }
@@ -46,7 +46,9 @@ import { createAutoWorktree, enterAutoWorktree, teardownAutoWorktree, isInAutoWo
46
46
  import { pruneQueueOrder } from "./queue-order.js";
47
47
  import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
48
48
  import { verifyExpectedArtifact, reconcileMergeState, } from "./auto-recovery.js";
49
- import { resolveDispatch } from "./auto-dispatch.js";
49
+ import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
50
+ import { initRegistry, convertDispatchRules } from "./rule-registry.js";
51
+ import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
50
52
  import { updateProgressWidget as _updateProgressWidget, updateSliceProgressCache, clearSliceProgressCache, hideFooter, } from "./auto-dashboard.js";
51
53
  import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
52
54
  import { isDbAvailable } from "./gsd-db.js";
@@ -159,6 +161,18 @@ export function isAutoActive() {
159
161
  export function isAutoPaused() {
160
162
  return s.paused;
161
163
  }
164
+ export function setActiveEngineId(id) {
165
+ s.activeEngineId = id;
166
+ }
167
+ export function getActiveEngineId() {
168
+ return s.activeEngineId;
169
+ }
170
+ export function setActiveRunDir(runDir) {
171
+ s.activeRunDir = runDir;
172
+ }
173
+ export function getActiveRunDir() {
174
+ return s.activeRunDir;
175
+ }
162
176
  /**
163
177
  * Return the model captured at auto-mode start for this session.
164
178
  * Used by error-recovery to fall back to the session's own model
@@ -298,6 +312,31 @@ function handleLostSessionLock(ctx, lockStatus) {
298
312
  ctx?.ui.setWidget("gsd-progress", undefined);
299
313
  ctx?.ui.setFooter(undefined);
300
314
  }
315
+ /**
316
+ * Lightweight cleanup after autoLoop exits via step-wizard break.
317
+ *
318
+ * Unlike stopAuto (which tears down the entire session), this only clears
319
+ * the stale unit state, progress widget, status badge, and restores CWD so
320
+ * the dashboard does not show an orphaned timer and the shell is usable.
321
+ */
322
+ function cleanupAfterLoopExit(ctx) {
323
+ s.currentUnit = null;
324
+ s.active = false;
325
+ clearUnitTimeout();
326
+ ctx.ui.setStatus("gsd-auto", undefined);
327
+ ctx.ui.setWidget("gsd-progress", undefined);
328
+ ctx.ui.setFooter(undefined);
329
+ // Restore CWD out of worktree back to original project root
330
+ if (s.originalBasePath) {
331
+ s.basePath = s.originalBasePath;
332
+ try {
333
+ process.chdir(s.basePath);
334
+ }
335
+ catch {
336
+ /* best-effort */
337
+ }
338
+ }
339
+ }
301
340
  export async function stopAuto(ctx, pi, reason) {
302
341
  if (!s.active && !s.paused)
303
342
  return;
@@ -504,6 +543,8 @@ export async function pauseAuto(ctx, _pi) {
504
543
  stepMode: s.stepMode,
505
544
  pausedAt: new Date().toISOString(),
506
545
  sessionFile: s.pausedSessionFile,
546
+ activeEngineId: s.activeEngineId,
547
+ activeRunDir: s.activeRunDir,
507
548
  };
508
549
  const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
509
550
  mkdirSync(runtimeDir, { recursive: true });
@@ -585,6 +626,10 @@ function buildResolver() {
585
626
  * This bundles all private functions that autoLoop needs without exporting them.
586
627
  */
587
628
  function buildLoopDeps() {
629
+ // Initialize the unified rule registry with converted dispatch rules.
630
+ // Must happen before LoopDeps is assembled so facade functions
631
+ // (resolveDispatch, runPreDispatchHooks, etc.) delegate to the registry.
632
+ initRegistry(convertDispatchRules(DISPATCH_RULES));
588
633
  return {
589
634
  lockBase,
590
635
  buildSnapshotOpts,
@@ -679,6 +724,8 @@ function buildLoopDeps() {
679
724
  return "";
680
725
  }
681
726
  },
727
+ // Journal
728
+ emitJournalEvent: (entry) => _emitJournalEvent(s.basePath, entry),
682
729
  };
683
730
  }
684
731
  export async function startAuto(ctx, pi, base, verboseMode, options) {
@@ -692,7 +739,20 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
692
739
  const pausedPath = join(gsdRoot(base), "runtime", "paused-session.json");
693
740
  if (existsSync(pausedPath)) {
694
741
  const meta = JSON.parse(readFileSync(pausedPath, "utf-8"));
695
- if (meta.milestoneId) {
742
+ if (meta.activeEngineId && meta.activeEngineId !== "dev") {
743
+ // Custom workflow resume — restore engine state
744
+ s.activeEngineId = meta.activeEngineId;
745
+ s.activeRunDir = meta.activeRunDir ?? null;
746
+ s.originalBasePath = meta.originalBasePath || base;
747
+ s.stepMode = meta.stepMode ?? requestedStepMode;
748
+ s.paused = true;
749
+ try {
750
+ unlinkSync(pausedPath);
751
+ }
752
+ catch { /* non-fatal */ }
753
+ ctx.ui.notify(`Resuming paused custom workflow${meta.activeRunDir ? ` (${meta.activeRunDir})` : ""}.`, "info");
754
+ }
755
+ else if (meta.milestoneId) {
696
756
  // Validate the milestone still exists and isn't already complete (#1664).
697
757
  const mDir = resolveMilestonePath(base, meta.milestoneId);
698
758
  const summaryFile = resolveMilestoneFile(base, meta.milestoneId, "SUMMARY");
@@ -802,6 +862,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
802
862
  // Clear orphaned runtime records from prior process deaths before entering the loop
803
863
  await selfHealRuntimeRecords(s.basePath, ctx);
804
864
  await autoLoop(ctx, pi, s, buildLoopDeps());
865
+ cleanupAfterLoopExit(ctx);
805
866
  return;
806
867
  }
807
868
  // ── Fresh start path — delegated to auto-start.ts ──
@@ -825,6 +886,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
825
886
  await selfHealRuntimeRecords(s.basePath, ctx);
826
887
  // Dispatch the first unit
827
888
  await autoLoop(ctx, pi, s, buildLoopDeps());
889
+ cleanupAfterLoopExit(ctx);
828
890
  }
829
891
  // ─── Agent End Handler ────────────────────────────────────────────────────────
830
892
  /**