gsd-pi 2.41.0 → 2.42.0-dev.1df898f

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 (494) hide show
  1. package/README.md +92 -29
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/cli.js +18 -3
  5. package/dist/loader.js +3 -1
  6. package/dist/onboarding.js +2 -1
  7. package/dist/resource-loader.js +39 -6
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  9. package/dist/resources/extensions/async-jobs/await-tool.js +5 -0
  10. package/dist/resources/extensions/async-jobs/index.js +2 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  12. package/dist/resources/extensions/gsd/auto/phases.js +29 -13
  13. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  17. package/dist/resources/extensions/gsd/auto-prompts.js +3 -16
  18. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  19. package/dist/resources/extensions/gsd/auto-start.js +16 -14
  20. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  21. package/dist/resources/extensions/gsd/auto.js +64 -2
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  23. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  31. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  32. package/dist/resources/extensions/gsd/context-store.js +4 -3
  33. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  34. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  35. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  37. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  38. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  39. package/dist/resources/extensions/gsd/detection.js +20 -1
  40. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  41. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  42. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  43. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  44. package/dist/resources/extensions/gsd/doctor.js +11 -1
  45. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  46. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  47. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  48. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  49. package/dist/resources/extensions/gsd/export.js +9 -13
  50. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  51. package/dist/resources/extensions/gsd/files.js +28 -11
  52. package/dist/resources/extensions/gsd/forensics.js +94 -3
  53. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  54. package/dist/resources/extensions/gsd/git-service.js +6 -2
  55. package/dist/resources/extensions/gsd/graph.js +225 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  59. package/dist/resources/extensions/gsd/journal.js +85 -0
  60. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  61. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  62. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  63. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  64. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  65. package/dist/resources/extensions/gsd/preferences.js +60 -8
  66. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  67. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  71. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  72. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  73. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  74. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  75. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  76. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  77. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  78. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  79. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  80. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  81. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  82. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  83. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  84. package/dist/resources/extensions/gsd/worktree.js +2 -2
  85. package/dist/resources/extensions/mcp-client/index.js +2 -1
  86. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  87. package/dist/resources/extensions/subagent/index.js +7 -3
  88. package/dist/resources/extensions/voice/index.js +4 -4
  89. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  90. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  91. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  92. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  93. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  94. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  95. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  96. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  97. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  98. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  101. package/dist/web/standalone/.next/build-manifest.json +4 -4
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  104. package/dist/web/standalone/.next/required-server-files.json +3 -3
  105. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  108. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  116. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  170. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  176. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/page.js +2 -2
  211. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  213. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  214. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  215. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/middleware.js +2 -2
  218. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  220. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  221. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  222. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  223. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  224. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  228. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  230. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  231. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  232. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  233. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  234. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  235. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  236. package/dist/web/standalone/server.js +1 -1
  237. package/dist/web-mode.d.ts +4 -0
  238. package/dist/web-mode.js +69 -11
  239. package/package.json +1 -1
  240. package/packages/native/src/__tests__/text.test.mjs +33 -0
  241. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/agent.js +2 -0
  243. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  244. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  245. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  246. package/packages/pi-agent-core/dist/types.js.map +1 -1
  247. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  248. package/packages/pi-agent-core/src/agent.ts +3 -0
  249. package/packages/pi-agent-core/src/types.ts +6 -0
  250. package/packages/pi-agent-core/tsconfig.json +1 -1
  251. package/packages/pi-ai/dist/models.d.ts +5 -3
  252. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  253. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  254. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  256. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  257. package/packages/pi-ai/dist/models.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  261. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  262. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  263. package/packages/pi-ai/src/models.ts +7 -4
  264. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  273. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  275. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  278. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  281. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  284. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  286. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  288. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  290. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  292. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  295. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  307. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  308. package/packages/pi-coding-agent/package.json +1 -1
  309. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  310. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  311. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  312. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  313. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  314. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  315. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  316. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  317. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  318. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  319. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  320. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  321. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  322. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  323. package/pkg/package.json +1 -1
  324. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  325. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  326. package/src/resources/extensions/async-jobs/await-tool.test.ts +47 -0
  327. package/src/resources/extensions/async-jobs/await-tool.ts +5 -0
  328. package/src/resources/extensions/async-jobs/index.ts +1 -0
  329. package/src/resources/extensions/async-jobs/job-manager.ts +2 -0
  330. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -2
  331. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  332. package/src/resources/extensions/gsd/auto/phases.ts +31 -13
  333. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  334. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  335. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  336. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  337. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  338. package/src/resources/extensions/gsd/auto-prompts.ts +2 -18
  339. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  340. package/src/resources/extensions/gsd/auto-start.ts +15 -13
  341. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  342. package/src/resources/extensions/gsd/auto.ts +71 -2
  343. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  344. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  345. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  347. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  348. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  349. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  350. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  351. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  352. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  353. package/src/resources/extensions/gsd/context-store.ts +4 -3
  354. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  355. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  356. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  357. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  358. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  359. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  360. package/src/resources/extensions/gsd/detection.ts +20 -1
  361. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  362. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  363. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  364. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  365. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  366. package/src/resources/extensions/gsd/doctor.ts +12 -1
  367. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  368. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  369. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  370. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  371. package/src/resources/extensions/gsd/export.ts +8 -15
  372. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  373. package/src/resources/extensions/gsd/files.ts +29 -12
  374. package/src/resources/extensions/gsd/forensics.ts +101 -3
  375. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  376. package/src/resources/extensions/gsd/git-service.ts +5 -5
  377. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  378. package/src/resources/extensions/gsd/graph.ts +312 -0
  379. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  380. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  381. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  382. package/src/resources/extensions/gsd/journal.ts +134 -0
  383. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  384. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  385. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  386. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  387. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  388. package/src/resources/extensions/gsd/preferences.ts +63 -6
  389. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  390. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  391. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  392. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  393. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  394. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  395. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  396. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  397. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  398. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  399. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  400. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  401. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  402. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  403. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  404. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  405. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  406. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  407. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  408. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  409. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  410. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  411. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  412. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  413. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  414. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  415. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  416. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  417. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  419. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  420. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  421. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  422. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  423. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  424. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  425. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  426. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  427. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  428. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  429. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  430. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  431. package/src/resources/extensions/gsd/tests/git-service.test.ts +44 -0
  432. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  433. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  434. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  435. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  436. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  437. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  438. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  439. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  440. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  441. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  442. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  443. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  444. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  445. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  446. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  447. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  448. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  449. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  451. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +56 -3
  452. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  453. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  454. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  455. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  456. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  457. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  458. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  459. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  460. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  461. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  462. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  463. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  464. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +79 -5
  466. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  468. package/src/resources/extensions/gsd/types.ts +3 -0
  469. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  470. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  471. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  472. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -12
  473. package/src/resources/extensions/gsd/worktree.ts +2 -2
  474. package/src/resources/extensions/mcp-client/index.ts +5 -1
  475. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  476. package/src/resources/extensions/subagent/index.ts +7 -3
  477. package/src/resources/extensions/voice/index.ts +4 -4
  478. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  479. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  480. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  481. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  482. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  483. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  484. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  485. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  486. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  487. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  488. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  489. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  490. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  491. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  492. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  493. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_buildManifest.js +0 -0
  494. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_ssgManifest.js +0 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * graph.ts — Pure data module for GRAPH.yaml workflow step tracking.
3
+ *
4
+ * Provides types and functions for reading, writing, and querying the
5
+ * step graph that drives CustomWorkflowEngine. Zero engine dependencies.
6
+ *
7
+ * GRAPH.yaml lives in a run directory and tracks step statuses
8
+ * (pending → active → complete) with optional dependency edges.
9
+ *
10
+ * Observability:
11
+ * - readGraph/writeGraph use YAML on disk — human-readable, diffable,
12
+ * inspectable with `cat` or any YAML viewer.
13
+ * - Each GraphStep has status, startedAt, finishedAt fields visible in GRAPH.yaml.
14
+ * - writeGraph uses atomic write (tmp + rename) for crash safety.
15
+ * - All operations are immutable — callers always get a new graph object.
16
+ */
17
+
18
+ import { parse, stringify } from "yaml";
19
+ import { readFileSync, writeFileSync, renameSync, existsSync, mkdirSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import type { WorkflowDefinition } from "./definition-loader.js";
22
+
23
+ // ─── Types ───────────────────────────────────────────────────────────────
24
+
25
+ export interface GraphStep {
26
+ /** Unique step identifier within the workflow. */
27
+ id: string;
28
+ /** Human-readable step title. */
29
+ title: string;
30
+ /** Current status: pending → active → complete → expanded (iterate parent). */
31
+ status: "pending" | "active" | "complete" | "expanded";
32
+ /** The prompt to dispatch for this step. */
33
+ prompt: string;
34
+ /** IDs of steps that must be "complete" before this step can run. */
35
+ dependsOn: string[];
36
+ /** For iteration instances: ID of the parent step that was expanded. */
37
+ parentStepId?: string;
38
+ /** ISO timestamp when the step started executing. */
39
+ startedAt?: string;
40
+ /** ISO timestamp when the step finished executing. */
41
+ finishedAt?: string;
42
+ }
43
+
44
+ export interface WorkflowGraph {
45
+ /** Ordered list of steps in the workflow. */
46
+ steps: GraphStep[];
47
+ /** Workflow metadata. */
48
+ metadata: {
49
+ name: string;
50
+ createdAt: string;
51
+ };
52
+ }
53
+
54
+ // ─── YAML schema mapping ─────────────────────────────────────────────────
55
+
56
+ const GRAPH_FILENAME = "GRAPH.yaml";
57
+
58
+ /**
59
+ * Internal YAML shape — uses snake_case for YAML keys.
60
+ * Converted to/from the camelCase TypeScript types on read/write.
61
+ */
62
+ interface YamlStep {
63
+ id: string;
64
+ title: string;
65
+ status: string;
66
+ prompt: string;
67
+ depends_on?: string[];
68
+ parent_step_id?: string;
69
+ started_at?: string;
70
+ finished_at?: string;
71
+ }
72
+
73
+ interface YamlGraph {
74
+ steps: YamlStep[];
75
+ metadata: { name: string; created_at: string };
76
+ }
77
+
78
+ // ─── Functions ───────────────────────────────────────────────────────────
79
+
80
+ /**
81
+ * Read and parse GRAPH.yaml from a run directory.
82
+ *
83
+ * @param runDir — directory containing GRAPH.yaml
84
+ * @returns Parsed workflow graph
85
+ * @throws Error if file doesn't exist or YAML is malformed
86
+ */
87
+ export function readGraph(runDir: string): WorkflowGraph {
88
+ const filePath = join(runDir, GRAPH_FILENAME);
89
+ if (!existsSync(filePath)) {
90
+ throw new Error(`GRAPH.yaml not found: ${filePath}`);
91
+ }
92
+ const raw = readFileSync(filePath, "utf-8");
93
+ const yaml = parse(raw) as YamlGraph;
94
+
95
+ if (!yaml?.steps || !Array.isArray(yaml.steps)) {
96
+ throw new Error(`Invalid GRAPH.yaml: missing or invalid 'steps' array in ${filePath}`);
97
+ }
98
+
99
+ return {
100
+ steps: yaml.steps.map((s) => ({
101
+ id: s.id,
102
+ title: s.title,
103
+ status: s.status as GraphStep["status"],
104
+ prompt: s.prompt,
105
+ dependsOn: s.depends_on ?? [],
106
+ ...(s.parent_step_id != null ? { parentStepId: s.parent_step_id } : {}),
107
+ ...(s.started_at != null ? { startedAt: s.started_at } : {}),
108
+ ...(s.finished_at != null ? { finishedAt: s.finished_at } : {}),
109
+ })),
110
+ metadata: {
111
+ name: yaml.metadata?.name ?? "unnamed",
112
+ createdAt: yaml.metadata?.created_at ?? new Date().toISOString(),
113
+ },
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Write a workflow graph to GRAPH.yaml in a run directory.
119
+ * Creates the directory if it doesn't exist. Write is atomic (write + rename).
120
+ *
121
+ * @param runDir — directory to write GRAPH.yaml into
122
+ * @param graph — the workflow graph to serialize
123
+ */
124
+ export function writeGraph(runDir: string, graph: WorkflowGraph): void {
125
+ if (!existsSync(runDir)) {
126
+ mkdirSync(runDir, { recursive: true });
127
+ }
128
+
129
+ const yamlData: YamlGraph = {
130
+ steps: graph.steps.map((s) => ({
131
+ id: s.id,
132
+ title: s.title,
133
+ status: s.status,
134
+ prompt: s.prompt,
135
+ depends_on: s.dependsOn.length > 0 ? s.dependsOn : undefined,
136
+ parent_step_id: s.parentStepId ?? undefined,
137
+ started_at: s.startedAt ?? undefined,
138
+ finished_at: s.finishedAt ?? undefined,
139
+ })) as YamlStep[],
140
+ metadata: {
141
+ name: graph.metadata.name,
142
+ created_at: graph.metadata.createdAt,
143
+ },
144
+ };
145
+
146
+ const filePath = join(runDir, GRAPH_FILENAME);
147
+ const tmpPath = filePath + ".tmp";
148
+ const content = stringify(yamlData);
149
+ writeFileSync(tmpPath, content, "utf-8");
150
+ // Atomic rename for crash safety
151
+ renameSync(tmpPath, filePath);
152
+ }
153
+
154
+ /**
155
+ * Get the next pending step whose dependencies are all complete.
156
+ *
157
+ * Returns the first step (in array order) with status "pending" where
158
+ * every step in its `dependsOn` list has status "complete".
159
+ *
160
+ * @param graph — the workflow graph to query
161
+ * @returns The next dispatchable step, or null if none available
162
+ */
163
+ export function getNextPendingStep(graph: WorkflowGraph): GraphStep | null {
164
+ const statusMap = new Map(graph.steps.map((s) => [s.id, s.status]));
165
+
166
+ for (const step of graph.steps) {
167
+ if (step.status !== "pending") continue;
168
+ const depsComplete = step.dependsOn.every(
169
+ (depId) => statusMap.get(depId) === "complete",
170
+ );
171
+ if (depsComplete) return step;
172
+ }
173
+
174
+ return null;
175
+ }
176
+
177
+ /**
178
+ * Return a new graph with the specified step marked as "complete".
179
+ * Immutable — does not mutate the input graph.
180
+ *
181
+ * @param graph — the current workflow graph
182
+ * @param stepId — ID of the step to mark complete
183
+ * @returns New graph with the step's status set to "complete"
184
+ * @throws Error if stepId is not found in the graph
185
+ */
186
+ export function markStepComplete(
187
+ graph: WorkflowGraph,
188
+ stepId: string,
189
+ ): WorkflowGraph {
190
+ const found = graph.steps.some((s) => s.id === stepId);
191
+ if (!found) {
192
+ throw new Error(`Step not found: ${stepId}`);
193
+ }
194
+
195
+ return {
196
+ ...graph,
197
+ steps: graph.steps.map((s) =>
198
+ s.id === stepId
199
+ ? { ...s, status: "complete" as const, finishedAt: new Date().toISOString() }
200
+ : s,
201
+ ),
202
+ };
203
+ }
204
+
205
+ // ─── Iteration expansion ─────────────────────────────────────────────────
206
+
207
+ /**
208
+ * Expand an iterate step into concrete instances. Pure and deterministic —
209
+ * identical inputs always produce identical output.
210
+ *
211
+ * Given a parent step with status "pending" and an array of matched items,
212
+ * creates one instance step per item, marks the parent as "expanded", and
213
+ * rewrites any downstream dependsOn references from the parent ID to the
214
+ * full set of instance IDs.
215
+ *
216
+ * @param graph — the current workflow graph (not mutated)
217
+ * @param stepId — ID of the iterate step to expand
218
+ * @param items — matched items from the source artifact
219
+ * @param promptTemplate — template with {{item}} placeholders
220
+ * @returns New WorkflowGraph with instances inserted and deps rewritten
221
+ * @throws Error if stepId not found or step is not pending
222
+ */
223
+ export function expandIteration(
224
+ graph: WorkflowGraph,
225
+ stepId: string,
226
+ items: string[],
227
+ promptTemplate: string,
228
+ ): WorkflowGraph {
229
+ const parentIndex = graph.steps.findIndex((s) => s.id === stepId);
230
+ if (parentIndex === -1) {
231
+ throw new Error(`expandIteration: step not found: ${stepId}`);
232
+ }
233
+ const parentStep = graph.steps[parentIndex];
234
+ if (parentStep.status !== "pending") {
235
+ throw new Error(
236
+ `expandIteration: step "${stepId}" has status "${parentStep.status}", expected "pending"`,
237
+ );
238
+ }
239
+
240
+ // Create instance steps
241
+ const instanceIds: string[] = [];
242
+ const instances: GraphStep[] = items.map((item, i) => {
243
+ const instanceId = `${stepId}--${String(i + 1).padStart(3, "0")}`;
244
+ instanceIds.push(instanceId);
245
+ return {
246
+ id: instanceId,
247
+ title: `${parentStep.title}: ${item}`,
248
+ status: "pending" as const,
249
+ prompt: promptTemplate.replace(/\{\{item\}\}/g, () => item),
250
+ dependsOn: [...parentStep.dependsOn],
251
+ parentStepId: stepId,
252
+ };
253
+ });
254
+
255
+ // Build new steps array: copy everything, mark parent as expanded,
256
+ // insert instances right after the parent, rewrite downstream deps.
257
+ const newSteps: GraphStep[] = [];
258
+ for (let i = 0; i < graph.steps.length; i++) {
259
+ if (i === parentIndex) {
260
+ // Mark parent as expanded
261
+ newSteps.push({ ...parentStep, status: "expanded" as const });
262
+ // Insert instances immediately after parent
263
+ newSteps.push(...instances);
264
+ } else {
265
+ const step = graph.steps[i];
266
+ // Rewrite dependsOn: replace parent ID with all instance IDs
267
+ const hasDep = step.dependsOn.includes(stepId);
268
+ if (hasDep) {
269
+ const rewritten = step.dependsOn.flatMap((dep) =>
270
+ dep === stepId ? instanceIds : [dep],
271
+ );
272
+ newSteps.push({ ...step, dependsOn: rewritten });
273
+ } else {
274
+ newSteps.push(step);
275
+ }
276
+ }
277
+ }
278
+
279
+ return {
280
+ ...graph,
281
+ steps: newSteps,
282
+ };
283
+ }
284
+
285
+ // ─── Definition → Graph conversion ──────────────────────────────────────
286
+
287
+ /**
288
+ * Convert a parsed WorkflowDefinition into a WorkflowGraph with all
289
+ * steps in "pending" status. Used by run-manager to generate the initial
290
+ * GRAPH.yaml for a new run.
291
+ *
292
+ * @param def — a validated WorkflowDefinition from definition-loader
293
+ * @returns WorkflowGraph with pending steps and metadata from the definition
294
+ */
295
+ export function initializeGraph(def: WorkflowDefinition): WorkflowGraph {
296
+ return {
297
+ steps: def.steps.map((s) => ({
298
+ id: s.id,
299
+ title: s.name,
300
+ status: "pending" as const,
301
+ prompt: s.prompt,
302
+ dependsOn: s.requires ?? [],
303
+ })),
304
+ metadata: {
305
+ name: def.name,
306
+ createdAt: new Date().toISOString(),
307
+ },
308
+ };
309
+ }
310
+
311
+ /** @deprecated Use initializeGraph instead. Kept for backward compatibility. */
312
+ export { initializeGraph as graphFromDefinition };
@@ -168,7 +168,7 @@ function openRawDb(path: string): unknown {
168
168
 
169
169
  // ─── Schema ────────────────────────────────────────────────────────────────
170
170
 
171
- const SCHEMA_VERSION = 3;
171
+ const SCHEMA_VERSION = 4;
172
172
 
173
173
  function initSchema(db: DbAdapter, fileBacked: boolean): void {
174
174
  // WAL mode for file-backed databases (must be outside transaction)
@@ -195,6 +195,7 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
195
195
  choice TEXT NOT NULL DEFAULT '',
196
196
  rationale TEXT NOT NULL DEFAULT '',
197
197
  revisable TEXT NOT NULL DEFAULT '',
198
+ made_by TEXT NOT NULL DEFAULT 'agent',
198
199
  superseded_by TEXT DEFAULT NULL
199
200
  )
200
201
  `);
@@ -360,6 +361,22 @@ function migrateSchema(db: DbAdapter): void {
360
361
  ).run({ ":version": 3, ":applied_at": new Date().toISOString() });
361
362
  }
362
363
 
364
+ // v3 → v4: add made_by column to decisions table
365
+ if (currentVersion < 4) {
366
+ // Add made_by column — default 'agent' for existing rows (pre-attribution decisions)
367
+ db.exec(`ALTER TABLE decisions ADD COLUMN made_by TEXT NOT NULL DEFAULT 'agent'`);
368
+
369
+ // Recreate views to pick up new columns (SQLite expands SELECT * at view creation time)
370
+ db.exec("DROP VIEW IF EXISTS active_decisions");
371
+ db.exec(
372
+ "CREATE VIEW active_decisions AS SELECT * FROM decisions WHERE superseded_by IS NULL",
373
+ );
374
+
375
+ db.prepare(
376
+ "INSERT INTO schema_version (version, applied_at) VALUES (:version, :applied_at)",
377
+ ).run({ ":version": 4, ":applied_at": new Date().toISOString() });
378
+ }
379
+
363
380
  db.exec("COMMIT");
364
381
  } catch (err) {
365
382
  db.exec("ROLLBACK");
@@ -471,8 +488,8 @@ export function insertDecision(d: Omit<Decision, "seq">): void {
471
488
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
472
489
  currentDb
473
490
  .prepare(
474
- `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, superseded_by)
475
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :superseded_by)`,
491
+ `INSERT INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
492
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)`,
476
493
  )
477
494
  .run({
478
495
  ":id": d.id,
@@ -482,6 +499,7 @@ export function insertDecision(d: Omit<Decision, "seq">): void {
482
499
  ":choice": d.choice,
483
500
  ":rationale": d.rationale,
484
501
  ":revisable": d.revisable,
502
+ ":made_by": d.made_by ?? "agent",
485
503
  ":superseded_by": d.superseded_by,
486
504
  });
487
505
  }
@@ -502,6 +520,7 @@ export function getDecisionById(id: string): Decision | null {
502
520
  choice: row["choice"] as string,
503
521
  rationale: row["rationale"] as string,
504
522
  revisable: row["revisable"] as string,
523
+ made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
505
524
  superseded_by: (row["superseded_by"] as string) ?? null,
506
525
  };
507
526
  }
@@ -521,6 +540,7 @@ export function getActiveDecisions(): Decision[] {
521
540
  choice: row["choice"] as string,
522
541
  rationale: row["rationale"] as string,
523
542
  revisable: row["revisable"] as string,
543
+ made_by: (row["made_by"] as string as import("./types.js").DecisionMadeBy) ?? "agent",
524
544
  superseded_by: null,
525
545
  }));
526
546
  }
@@ -644,8 +664,8 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
644
664
  throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
645
665
  currentDb
646
666
  .prepare(
647
- `INSERT OR REPLACE INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, superseded_by)
648
- VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :superseded_by)`,
667
+ `INSERT OR REPLACE INTO decisions (id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by)
668
+ VALUES (:id, :when_context, :scope, :decision, :choice, :rationale, :revisable, :made_by, :superseded_by)`,
649
669
  )
650
670
  .run({
651
671
  ":id": d.id,
@@ -655,6 +675,7 @@ export function upsertDecision(d: Omit<Decision, "seq">): void {
655
675
  ":choice": d.choice,
656
676
  ":rationale": d.rationale,
657
677
  ":revisable": d.revisable,
678
+ ":made_by": d.made_by ?? "agent",
658
679
  ":superseded_by": d.superseded_by ?? null,
659
680
  });
660
681
  }
@@ -783,9 +804,15 @@ export function reconcileWorktreeDb(
783
804
  try {
784
805
  adapter.exec(`ATTACH DATABASE '${worktreeDbPath}' AS wt`);
785
806
  try {
807
+ // Check if attached wt database has the made_by column (legacy v3 worktrees won't)
808
+ const wtInfo = adapter.prepare("PRAGMA wt.table_info('decisions')").all();
809
+ const hasMadeBy = wtInfo.some((col) => col["name"] === "made_by");
810
+
786
811
  const decConf = adapter
787
812
  .prepare(
788
- `SELECT m.id FROM decisions m INNER JOIN wt.decisions w ON m.id = w.id WHERE m.decision != w.decision OR m.choice != w.choice OR m.rationale != w.rationale OR m.superseded_by IS NOT w.superseded_by`,
813
+ `SELECT m.id FROM decisions m INNER JOIN wt.decisions w ON m.id = w.id WHERE m.decision != w.decision OR m.choice != w.choice OR m.rationale != w.rationale OR ${
814
+ hasMadeBy ? "m.made_by != w.made_by" : "'agent' != 'agent'"
815
+ } OR m.superseded_by IS NOT w.superseded_by`,
789
816
  )
790
817
  .all();
791
818
  for (const row of decConf)
@@ -808,10 +835,12 @@ export function reconcileWorktreeDb(
808
835
  .prepare(
809
836
  `
810
837
  INSERT OR REPLACE INTO decisions (
811
- id, when_context, scope, decision, choice, rationale, revisable, superseded_by
838
+ id, when_context, scope, decision, choice, rationale, revisable, made_by, superseded_by
812
839
  )
813
840
  SELECT
814
- id, when_context, scope, decision, choice, rationale, revisable, superseded_by
841
+ id, when_context, scope, decision, choice, rationale, revisable, ${
842
+ hasMadeBy ? "made_by" : "'agent'"
843
+ }, superseded_by
815
844
  FROM wt.decisions
816
845
  `,
817
846
  )
@@ -170,7 +170,7 @@ export async function showQueueAdd(
170
170
  const existingContext = await buildExistingMilestonesContext(basePath, milestoneIds, state);
171
171
 
172
172
  // ── Determine next milestone ID ─────────────────────────────────────
173
- // Note: the LLM will use the gsd_generate_milestone_id tool to get IDs
173
+ // Note: the LLM will use the gsd_milestone_generate_id tool to get IDs
174
174
  // at creation time, but we still mention the next ID in the preamble
175
175
  // for context about where the sequence is.
176
176
  const uniqueEnabled = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
@@ -26,6 +26,7 @@ import { join } from "node:path";
26
26
  import { readFileSync, existsSync, mkdirSync, readdirSync, rmSync, unlinkSync } from "node:fs";
27
27
  import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.js";
28
28
  import { nativeIsRepo, nativeInit } from "./native-git-bridge.js";
29
+ import { isInheritedRepo } from "./repo-identity.js";
29
30
  import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
30
31
  import { loadEffectiveGSDPreferences } from "./preferences.js";
31
32
  import { detectProjectState } from "./detection.js";
@@ -54,7 +55,7 @@ import { getErrorMessage } from "./error-utils.js";
54
55
 
55
56
  /**
56
57
  * Generate the next milestone ID, accounting for reserved IDs, and reserve it.
57
- * Ensures any preview ID shown in the UI matches what `gsd_generate_milestone_id`
58
+ * Ensures any preview ID shown in the UI matches what `gsd_milestone_generate_id`
58
59
  * will later return.
59
60
  */
60
61
  function nextMilestoneIdReserved(existingIds: string[], uniqueEnabled: boolean): string {
@@ -346,7 +347,7 @@ function buildHeadlessDiscussPrompt(nextId: string, seedContext: string, _basePa
346
347
  * Ensures git repo, .gsd/ structure, gitignore, and preferences all exist.
347
348
  */
348
349
  function bootstrapGsdProject(basePath: string): void {
349
- if (!nativeIsRepo(basePath)) {
350
+ if (!nativeIsRepo(basePath) || isInheritedRepo(basePath)) {
350
351
  const mainBranch = loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
351
352
  nativeInit(basePath, mainBranch);
352
353
  }
@@ -870,7 +871,10 @@ export async function showSmartEntry(
870
871
  }
871
872
 
872
873
  // ── Ensure git repo exists — GSD needs it for worktree isolation ──────
873
- if (!nativeIsRepo(basePath)) {
874
+ // Also handle inherited repos: if basePath is a subdirectory of another
875
+ // git repo that has no .gsd, create a fresh repo to prevent cross-project
876
+ // state leaks (#1639).
877
+ if (!nativeIsRepo(basePath) || isInheritedRepo(basePath)) {
874
878
  const mainBranch = loadEffectiveGSDPreferences()?.preferences?.git?.main_branch || "main";
875
879
  nativeInit(basePath, mainBranch);
876
880
  }
@@ -0,0 +1,134 @@
1
+ /**
2
+ * GSD Event Journal — structured JSONL event log for auto-mode iterations.
3
+ *
4
+ * Writes daily-rotated JSONL files to `.gsd/journal/YYYY-MM-DD.jsonl`.
5
+ * Zero imports from `auto/` — depends only on node:fs, node:path, and paths.ts.
6
+ *
7
+ * Observability:
8
+ * - Each line in the JSONL file is a self-contained JournalEntry
9
+ * - Events are grouped by flowId (one per iteration) with monotonic seq numbers
10
+ * - causedBy references enable causal chain reconstruction
11
+ * - queryJournal() enables programmatic filtering by flowId, eventType, unitId, time range
12
+ * - Silent failure: journal writes never throw — absence of events is the failure signal
13
+ */
14
+
15
+ import { appendFileSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
16
+ import { join } from "node:path";
17
+ import { gsdRoot } from "./paths.js";
18
+
19
+ // ─── Types ────────────────────────────────────────────────────────────────────
20
+
21
+ /** Event types emitted by the auto-mode loop and phases. */
22
+ export type JournalEventType =
23
+ | "iteration-start"
24
+ | "dispatch-match"
25
+ | "dispatch-stop"
26
+ | "pre-dispatch-hook"
27
+ | "unit-start"
28
+ | "unit-end"
29
+ | "post-unit-hook"
30
+ | "terminal"
31
+ | "guard-block"
32
+ | "milestone-transition"
33
+ | "stuck-detected"
34
+ | "sidecar-dequeue"
35
+ | "iteration-end";
36
+
37
+ /** A single structured event in the journal. */
38
+ export interface JournalEntry {
39
+ /** ISO-8601 timestamp */
40
+ ts: string;
41
+ /** UUID grouping all events from one iteration */
42
+ flowId: string;
43
+ /** Monotonically increasing sequence number within a flow */
44
+ seq: number;
45
+ /** The kind of event */
46
+ eventType: JournalEventType;
47
+ /** Name of the matched rule (from the unified registry), if applicable */
48
+ rule?: string;
49
+ /** Causal reference to a prior event in this or another flow */
50
+ causedBy?: { flowId: string; seq: number };
51
+ /** Arbitrary structured payload (e.g. unitId, status, action details) */
52
+ data?: Record<string, unknown>;
53
+ }
54
+
55
+ /** Filters for querying journal entries. */
56
+ export interface JournalQueryFilters {
57
+ flowId?: string;
58
+ eventType?: string;
59
+ unitId?: string;
60
+ /** Filter by the rule name that produced the event */
61
+ rule?: string;
62
+ /** ISO-8601 lower bound (inclusive) */
63
+ after?: string;
64
+ /** ISO-8601 upper bound (inclusive) */
65
+ before?: string;
66
+ }
67
+
68
+ // ─── Emit ─────────────────────────────────────────────────────────────────────
69
+
70
+ /**
71
+ * Append a journal event to the daily JSONL file.
72
+ *
73
+ * File path: `<gsdRoot>/journal/<YYYY-MM-DD>.jsonl`
74
+ * where the date is extracted from `entry.ts.slice(0, 10)`.
75
+ *
76
+ * Never throws — all errors are silently caught.
77
+ */
78
+ export function emitJournalEvent(basePath: string, entry: JournalEntry): void {
79
+ try {
80
+ const journalDir = join(gsdRoot(basePath), "journal");
81
+ mkdirSync(journalDir, { recursive: true });
82
+ const dateStr = entry.ts.slice(0, 10);
83
+ const filePath = join(journalDir, `${dateStr}.jsonl`);
84
+ appendFileSync(filePath, JSON.stringify(entry) + "\n");
85
+ } catch {
86
+ // Silent failure — journal must never break auto-mode
87
+ }
88
+ }
89
+
90
+ // ─── Query ────────────────────────────────────────────────────────────────────
91
+
92
+ /**
93
+ * Read and filter journal entries from all daily JSONL files.
94
+ *
95
+ * Returns an empty array on any error (missing directory, corrupt files, etc.).
96
+ */
97
+ export function queryJournal(
98
+ basePath: string,
99
+ filters?: JournalQueryFilters,
100
+ ): JournalEntry[] {
101
+ try {
102
+ const journalDir = join(gsdRoot(basePath), "journal");
103
+ const files = readdirSync(journalDir).filter(f => f.endsWith(".jsonl")).sort();
104
+
105
+ const entries: JournalEntry[] = [];
106
+ for (const file of files) {
107
+ const raw = readFileSync(join(journalDir, file), "utf-8");
108
+ for (const line of raw.split("\n")) {
109
+ if (!line.trim()) continue;
110
+ try {
111
+ const entry = JSON.parse(line) as JournalEntry;
112
+ entries.push(entry);
113
+ } catch {
114
+ // Skip malformed lines
115
+ }
116
+ }
117
+ }
118
+
119
+ if (!filters) return entries;
120
+
121
+ return entries.filter(e => {
122
+ if (filters.flowId && e.flowId !== filters.flowId) return false;
123
+ if (filters.eventType && e.eventType !== filters.eventType) return false;
124
+ if (filters.rule && e.rule !== filters.rule) return false;
125
+ if (filters.unitId && (e.data as Record<string, unknown> | undefined)?.unitId !== filters.unitId) return false;
126
+ if (filters.after && e.ts < filters.after) return false;
127
+ if (filters.before && e.ts > filters.before) return false;
128
+ return true;
129
+ });
130
+ } catch {
131
+ // Missing directory, permission errors, etc. — return empty
132
+ return [];
133
+ }
134
+ }
@@ -25,6 +25,8 @@ import { findMilestoneIds } from './guided-flow.js';
25
25
 
26
26
  // ─── DECISIONS.md Parser ───────────────────────────────────────────────────
27
27
 
28
+ const VALID_MADE_BY = new Set(['human', 'agent', 'collaborative']);
29
+
28
30
  /**
29
31
  * Parse a DECISIONS.md markdown table into Decision objects (without seq).
30
32
  * Detects `(amends DXXX)` in the Decision column to build supersession info.
@@ -64,6 +66,9 @@ export function parseDecisionsTable(content: string): Omit<Decision, 'seq'>[] {
64
66
  const choice = cells[4].trim();
65
67
  const rationale = cells[5].trim();
66
68
  const revisable = cells[6].trim();
69
+ // Made By column is optional for backward compatibility — defaults to 'agent'
70
+ const rawMadeBy = cells.length >= 8 ? cells[7].trim().toLowerCase() : 'agent';
71
+ const made_by = (VALID_MADE_BY.has(rawMadeBy) ? rawMadeBy : 'agent') as import('./types.js').DecisionMadeBy;
67
72
 
68
73
  // Detect (amends DXXX) in the Decision column
69
74
  const amendsMatch = decisionText.match(/\(amends\s+(D\d+)\)/i);
@@ -79,6 +84,7 @@ export function parseDecisionsTable(content: string): Omit<Decision, 'seq'>[] {
79
84
  choice,
80
85
  rationale,
81
86
  revisable,
87
+ made_by,
82
88
  superseded_by: null,
83
89
  });
84
90
  }
@@ -75,7 +75,7 @@ export function nextMilestoneId(milestoneIds: string[], uniqueEnabled?: boolean)
75
75
  /**
76
76
  * Module-level set of milestone IDs that have been previewed/promised to the
77
77
  * user but not yet materialised on disk. Both guided-flow (preview) and
78
- * gsd_generate_milestone_id (tool) share this set so the ID shown in the UI
78
+ * gsd_milestone_generate_id (tool) share this set so the ID shown in the UI
79
79
  * matches the one the tool returns.
80
80
  */
81
81
  const reservedMilestoneIds = new Set<string>();
@@ -808,7 +808,7 @@ export function nativeCheckoutBranch(basePath: string, branch: string): void {
808
808
  native.gitCheckoutBranch(basePath, branch);
809
809
  return;
810
810
  }
811
- execSync(`git checkout ${branch}`, {
811
+ execFileSync("git", ["checkout", branch], {
812
812
  cwd: basePath,
813
813
  stdio: ["ignore", "pipe", "pipe"],
814
814
  encoding: "utf-8",
@@ -843,10 +843,11 @@ export function nativeMergeSquash(basePath: string, branch: string): GitMergeRes
843
843
  }
844
844
 
845
845
  try {
846
- execSync(`git merge --squash ${branch}`, {
846
+ execFileSync("git", ["merge", "--squash", branch], {
847
847
  cwd: basePath,
848
848
  stdio: ["ignore", "pipe", "pipe"],
849
849
  encoding: "utf-8",
850
+ env: GIT_NO_PROMPT_ENV,
850
851
  });
851
852
  return { success: true, conflicts: [] };
852
853
  } catch (err: unknown) {