gsd-pi 2.41.0 → 2.42.0-dev.eedc83f

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 (483) 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 +15 -1
  5. package/dist/onboarding.js +2 -1
  6. package/dist/resource-loader.js +39 -6
  7. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  8. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  9. package/dist/resources/extensions/gsd/auto/phases.js +28 -10
  10. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  11. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  14. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  15. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  16. package/dist/resources/extensions/gsd/auto-start.js +8 -3
  17. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  18. package/dist/resources/extensions/gsd/auto.js +64 -2
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  20. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  21. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  23. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  24. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  26. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  27. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  28. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  29. package/dist/resources/extensions/gsd/context-store.js +4 -3
  30. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  31. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  32. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  33. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  34. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  35. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  36. package/dist/resources/extensions/gsd/detection.js +20 -1
  37. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  38. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  39. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  40. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  41. package/dist/resources/extensions/gsd/doctor.js +11 -1
  42. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  43. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  44. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  45. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  46. package/dist/resources/extensions/gsd/export.js +9 -13
  47. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  48. package/dist/resources/extensions/gsd/files.js +28 -11
  49. package/dist/resources/extensions/gsd/forensics.js +94 -3
  50. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  51. package/dist/resources/extensions/gsd/git-service.js +73 -3
  52. package/dist/resources/extensions/gsd/graph.js +225 -0
  53. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  54. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  55. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  56. package/dist/resources/extensions/gsd/journal.js +85 -0
  57. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  58. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  59. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  60. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  61. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  62. package/dist/resources/extensions/gsd/preferences.js +60 -8
  63. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  64. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  65. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  66. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  68. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  69. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  70. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  71. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  72. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  73. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  74. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  75. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  76. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  77. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  78. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  79. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  80. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  81. package/dist/resources/extensions/mcp-client/index.js +2 -1
  82. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  83. package/dist/resources/extensions/subagent/index.js +7 -3
  84. package/dist/resources/extensions/voice/index.js +4 -4
  85. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  86. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  87. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  88. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  89. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  90. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  91. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  92. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  93. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  94. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  95. package/dist/web/standalone/.next/BUILD_ID +1 -1
  96. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  97. package/dist/web/standalone/.next/build-manifest.json +4 -4
  98. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  99. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  100. package/dist/web/standalone/.next/required-server-files.json +3 -3
  101. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  102. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  104. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  112. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  166. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  186. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  190. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app/page.js +2 -2
  207. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  209. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  210. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  211. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/middleware.js +2 -2
  214. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  216. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  217. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  218. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  219. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  224. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  226. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  227. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  228. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  229. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  230. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  231. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  232. package/dist/web/standalone/server.js +1 -1
  233. package/dist/web-mode.d.ts +4 -0
  234. package/dist/web-mode.js +69 -11
  235. package/package.json +1 -1
  236. package/packages/native/src/__tests__/text.test.mjs +33 -0
  237. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  238. package/packages/pi-agent-core/dist/agent.js +2 -0
  239. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  240. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  241. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/types.js.map +1 -1
  243. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  244. package/packages/pi-agent-core/src/agent.ts +3 -0
  245. package/packages/pi-agent-core/src/types.ts +6 -0
  246. package/packages/pi-agent-core/tsconfig.json +1 -1
  247. package/packages/pi-ai/dist/models.d.ts +5 -3
  248. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  249. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  250. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  252. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  253. package/packages/pi-ai/dist/models.js.map +1 -1
  254. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  256. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  257. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  258. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  259. package/packages/pi-ai/src/models.ts +7 -4
  260. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  261. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  263. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  265. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  267. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  271. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  274. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  277. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  280. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  282. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  284. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  286. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  288. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  291. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  292. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  303. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  304. package/packages/pi-coding-agent/package.json +1 -1
  305. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  306. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  307. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  308. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  309. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  310. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  311. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  312. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  313. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  314. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  315. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  316. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  317. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  318. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  319. package/pkg/package.json +1 -1
  320. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  321. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  322. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
  323. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  324. package/src/resources/extensions/gsd/auto/phases.ts +30 -10
  325. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  326. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  327. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  328. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  329. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  330. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  331. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  332. package/src/resources/extensions/gsd/auto-start.ts +8 -3
  333. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  334. package/src/resources/extensions/gsd/auto.ts +71 -2
  335. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  336. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  337. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  338. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  339. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  340. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  341. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  342. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  343. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  344. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  345. package/src/resources/extensions/gsd/context-store.ts +4 -3
  346. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  347. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  348. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  349. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  350. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  351. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  352. package/src/resources/extensions/gsd/detection.ts +20 -1
  353. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  354. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  355. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  356. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  357. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  358. package/src/resources/extensions/gsd/doctor.ts +12 -1
  359. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  360. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  361. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  362. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  363. package/src/resources/extensions/gsd/export.ts +8 -15
  364. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  365. package/src/resources/extensions/gsd/files.ts +29 -12
  366. package/src/resources/extensions/gsd/forensics.ts +101 -3
  367. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  368. package/src/resources/extensions/gsd/git-service.ts +76 -6
  369. package/src/resources/extensions/gsd/graph.ts +312 -0
  370. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  371. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  372. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  373. package/src/resources/extensions/gsd/journal.ts +134 -0
  374. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  375. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  376. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  377. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  378. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  379. package/src/resources/extensions/gsd/preferences.ts +63 -6
  380. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  381. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  382. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  383. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  384. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  385. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  386. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  387. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  388. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  389. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  390. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  391. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  392. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  393. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  394. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  395. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  396. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  397. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  398. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  399. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  400. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  401. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  402. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  403. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  404. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  405. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  406. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  407. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  408. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  409. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  410. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  411. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  412. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  413. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  414. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  415. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  416. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  417. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  418. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  419. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  420. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  421. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  422. package/src/resources/extensions/gsd/tests/git-service.test.ts +49 -0
  423. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  424. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  425. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  426. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  427. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  428. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  429. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  430. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  431. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  432. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  433. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  434. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  435. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  436. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  437. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  438. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  439. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  440. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  441. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  442. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  443. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  444. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  445. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  446. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  447. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  448. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  449. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  450. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  451. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  452. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  453. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  454. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  455. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
  456. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  457. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  458. package/src/resources/extensions/gsd/types.ts +3 -0
  459. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  460. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  461. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  462. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -11
  463. package/src/resources/extensions/mcp-client/index.ts +5 -1
  464. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  465. package/src/resources/extensions/subagent/index.ts +7 -3
  466. package/src/resources/extensions/voice/index.ts +4 -4
  467. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  468. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  469. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  470. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  471. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  472. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  473. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  474. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  475. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  476. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  477. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  478. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  479. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  480. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  481. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  482. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_buildManifest.js +0 -0
  483. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → JUBX5FUR73jiViQU5a-Cx}/_ssgManifest.js +0 -0
@@ -0,0 +1,462 @@
1
+ /**
2
+ * definition-loader.ts — Parse and validate V1 YAML workflow definitions.
3
+ *
4
+ * Loads definition YAML files from `.gsd/workflow-defs/`, validates the
5
+ * V1 schema shape, and returns typed TypeScript objects. Pure functions
6
+ * with no engine or runtime dependencies — just `yaml` and `node:fs`.
7
+ *
8
+ * YAML uses snake_case (`depends_on`, `context_from`) per project convention (P005).
9
+ * TypeScript uses camelCase (`dependsOn`, `contextFrom`).
10
+ *
11
+ * Observability: All validation errors are collected into a string[] — callers
12
+ * can log, surface in dashboards, or return to agents for self-repair.
13
+ * substituteParams errors include the offending key name for traceability.
14
+ */
15
+
16
+ import { parse } from "yaml";
17
+ import { readFileSync, existsSync } from "node:fs";
18
+ import { join } from "node:path";
19
+
20
+ // ─── Public TypeScript Types (camelCase) ─────────────────────────────────
21
+
22
+ export type VerifyPolicy =
23
+ | { policy: "content-heuristic"; minSize?: number; pattern?: string }
24
+ | { policy: "shell-command"; command: string }
25
+ | { policy: "prompt-verify"; prompt: string }
26
+ | { policy: "human-review" };
27
+
28
+ export interface IterateConfig {
29
+ /** Artifact path (relative to run dir) to read and match against. */
30
+ source: string;
31
+ /** Regex pattern string. Must contain at least one capture group. Applied with global flag. */
32
+ pattern: string;
33
+ }
34
+
35
+ export interface StepDefinition {
36
+ /** Unique step identifier within the workflow. */
37
+ id: string;
38
+ /** Human-readable step name. */
39
+ name: string;
40
+ /** The prompt to dispatch for this step. */
41
+ prompt: string;
42
+ /** IDs of steps that must complete before this step can run. */
43
+ requires: string[];
44
+ /** Artifact paths produced by this step (relative to run dir). */
45
+ produces: string[];
46
+ /** Step IDs whose artifacts to include as context (S05 — accepted, not processed). */
47
+ contextFrom?: string[];
48
+ /** Verification policy for this step (S05 — typed + validated). */
49
+ verify?: VerifyPolicy;
50
+ /** Iteration config for this step (S06 — typed + validated). */
51
+ iterate?: IterateConfig;
52
+ }
53
+
54
+ export interface WorkflowDefinition {
55
+ /** Schema version — must be 1. */
56
+ version: number;
57
+ /** Workflow name. */
58
+ name: string;
59
+ /** Optional description. */
60
+ description?: string;
61
+ /** Optional parameter map for template substitution (S07). */
62
+ params?: Record<string, string>;
63
+ /** Ordered list of steps. */
64
+ steps: StepDefinition[];
65
+ }
66
+
67
+ // ─── Internal YAML Types (snake_case) ────────────────────────────────────
68
+
69
+ interface YamlStepDef {
70
+ id?: unknown;
71
+ name?: unknown;
72
+ prompt?: unknown;
73
+ requires?: unknown;
74
+ depends_on?: unknown;
75
+ produces?: unknown;
76
+ context_from?: unknown;
77
+ verify?: unknown;
78
+ iterate?: unknown;
79
+ [key: string]: unknown; // Forward-compat: unknown fields accepted silently
80
+ }
81
+
82
+ interface YamlWorkflowDef {
83
+ version?: unknown;
84
+ name?: unknown;
85
+ description?: unknown;
86
+ params?: unknown;
87
+ steps?: unknown;
88
+ [key: string]: unknown; // Forward-compat: unknown fields accepted silently
89
+ }
90
+
91
+ // ─── Validation ──────────────────────────────────────────────────────────
92
+
93
+ /**
94
+ * Validate a parsed (but untyped) YAML object against the V1 workflow schema.
95
+ *
96
+ * Collects all errors (does not short-circuit) so a single call reveals
97
+ * every problem with the definition.
98
+ *
99
+ * Unknown fields are silently accepted for forward compatibility with
100
+ * S05/S06 features (`context_from`, `verify`, `iterate`).
101
+ */
102
+ export function validateDefinition(parsed: unknown): { valid: boolean; errors: string[] } {
103
+ const errors: string[] = [];
104
+
105
+ if (parsed == null || typeof parsed !== "object") {
106
+ return { valid: false, errors: ["Definition must be a non-null object"] };
107
+ }
108
+
109
+ const def = parsed as YamlWorkflowDef;
110
+
111
+ // version: must be 1 (number)
112
+ if (def.version === undefined || def.version === null) {
113
+ errors.push("Missing required field: version");
114
+ } else if (def.version !== 1) {
115
+ errors.push(`Unsupported version: ${def.version} (expected 1)`);
116
+ }
117
+
118
+ // name: must be a non-empty string
119
+ if (typeof def.name !== "string" || def.name.trim() === "") {
120
+ errors.push("Missing or empty required field: name");
121
+ }
122
+
123
+ // steps: must be a non-empty array
124
+ if (!Array.isArray(def.steps)) {
125
+ errors.push("Missing required field: steps (must be an array)");
126
+ } else if (def.steps.length === 0) {
127
+ errors.push("steps must contain at least one step");
128
+ } else {
129
+ // Track whether all steps have valid IDs — graph-level checks only run when true
130
+ let allStepIdsValid = true;
131
+
132
+ for (let i = 0; i < def.steps.length; i++) {
133
+ const step = def.steps[i] as YamlStepDef;
134
+ if (step == null || typeof step !== "object") {
135
+ errors.push(`Step at index ${i} is not an object`);
136
+ allStepIdsValid = false;
137
+ continue;
138
+ }
139
+
140
+ // Required step fields
141
+ if (typeof step.id !== "string" || step.id.trim() === "") {
142
+ errors.push(`Step at index ${i} missing required field: id`);
143
+ allStepIdsValid = false;
144
+ }
145
+ if (typeof step.name !== "string" || step.name.trim() === "") {
146
+ errors.push(`Step at index ${i} missing required field: name`);
147
+ }
148
+ if (typeof step.prompt !== "string" || step.prompt.trim() === "") {
149
+ errors.push(`Step at index ${i} missing required field: prompt`);
150
+ }
151
+
152
+ // produces: path traversal guard
153
+ if (Array.isArray(step.produces)) {
154
+ for (const p of step.produces) {
155
+ if (typeof p === "string" && p.includes("..")) {
156
+ errors.push(`Step "${step.id}" produces path contains disallowed '..': ${p}`);
157
+ }
158
+ }
159
+ }
160
+
161
+ // iterate: optional, but if present must conform to IterateConfig shape
162
+ if (step.iterate !== undefined) {
163
+ const it = step.iterate;
164
+ const sid = typeof step.id === "string" ? step.id : `index ${i}`;
165
+ if (it == null || typeof it !== "object" || Array.isArray(it)) {
166
+ errors.push(`Step "${sid}" iterate must be an object with "source" and "pattern" fields`);
167
+ } else {
168
+ const itObj = it as Record<string, unknown>;
169
+ if (typeof itObj.source !== "string" || (itObj.source as string).trim() === "") {
170
+ errors.push(`Step "${sid}" iterate.source must be a non-empty string`);
171
+ } else if ((itObj.source as string).includes("..")) {
172
+ errors.push(`Step "${sid}" iterate.source contains disallowed '..' path traversal`);
173
+ }
174
+ if (typeof itObj.pattern !== "string" || (itObj.pattern as string).trim() === "") {
175
+ errors.push(`Step "${sid}" iterate.pattern must be a non-empty string`);
176
+ } else {
177
+ const pat = itObj.pattern as string;
178
+ let regexValid = true;
179
+ try {
180
+ new RegExp(pat);
181
+ } catch {
182
+ regexValid = false;
183
+ errors.push(`Step "${sid}" iterate.pattern is not a valid regex: ${pat}`);
184
+ }
185
+ if (regexValid && !/\((?!\?)/.test(pat)) {
186
+ errors.push(`Step "${sid}" iterate.pattern must contain at least one capture group`);
187
+ }
188
+ }
189
+ }
190
+ }
191
+
192
+ // verify: optional, but if present must conform to VerifyPolicy shape
193
+ if (step.verify !== undefined) {
194
+ const v = step.verify;
195
+ const sid = typeof step.id === "string" ? step.id : `index ${i}`;
196
+ if (v == null || typeof v !== "object" || Array.isArray(v)) {
197
+ errors.push(`Step "${sid}" verify must be an object with a "policy" field`);
198
+ } else {
199
+ const vObj = v as Record<string, unknown>;
200
+ const VALID_POLICIES = ["content-heuristic", "shell-command", "prompt-verify", "human-review"];
201
+ if (typeof vObj.policy !== "string" || !VALID_POLICIES.includes(vObj.policy)) {
202
+ errors.push(`Step "${sid}" verify.policy must be one of: ${VALID_POLICIES.join(", ")}`);
203
+ } else {
204
+ // Policy-specific required field checks
205
+ if (vObj.policy === "shell-command") {
206
+ if (typeof vObj.command !== "string" || (vObj.command as string).trim() === "") {
207
+ errors.push(`Step "${sid}" verify policy "shell-command" requires a non-empty "command" field`);
208
+ }
209
+ }
210
+ if (vObj.policy === "prompt-verify") {
211
+ if (typeof vObj.prompt !== "string" || (vObj.prompt as string).trim() === "") {
212
+ errors.push(`Step "${sid}" verify policy "prompt-verify" requires a non-empty "prompt" field`);
213
+ }
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ // ─── Graph-level validations (only when all step IDs are valid) ────
221
+ if (allStepIdsValid) {
222
+ const steps = def.steps as YamlStepDef[];
223
+
224
+ // 1. Duplicate step ID check
225
+ const idCounts = new Map<string, number>();
226
+ for (const step of steps) {
227
+ const id = step.id as string;
228
+ idCounts.set(id, (idCounts.get(id) ?? 0) + 1);
229
+ }
230
+ for (const [id, count] of idCounts) {
231
+ if (count > 1) {
232
+ errors.push(`Duplicate step id: ${id}`);
233
+ }
234
+ }
235
+
236
+ // Build valid ID set for remaining checks
237
+ const validIds = new Set(steps.map((s) => s.id as string));
238
+
239
+ // 2. Dangling dependency check + 3. Self-referencing dependency check
240
+ for (const step of steps) {
241
+ const sid = step.id as string;
242
+ const deps = Array.isArray(step.requires)
243
+ ? (step.requires as string[])
244
+ : Array.isArray(step.depends_on)
245
+ ? (step.depends_on as string[])
246
+ : [];
247
+
248
+ for (const depId of deps) {
249
+ if (depId === sid) {
250
+ errors.push(`Step '${sid}' depends on itself`);
251
+ } else if (!validIds.has(depId)) {
252
+ errors.push(`Step '${sid}' requires unknown step '${depId}'`);
253
+ }
254
+ }
255
+ }
256
+
257
+ // 4. Cycle detection (DFS) — only when no duplicate IDs
258
+ if (![...idCounts.values()].some((c: number) => c > 1)) {
259
+ // Build adjacency list: step → its dependencies
260
+ const adj = new Map<string, string[]>();
261
+ for (const step of steps) {
262
+ const sid = step.id as string;
263
+ const deps = Array.isArray(step.requires)
264
+ ? (step.requires as string[])
265
+ : Array.isArray(step.depends_on)
266
+ ? (step.depends_on as string[])
267
+ : [];
268
+ adj.set(sid, deps.filter((d) => validIds.has(d) && d !== sid));
269
+ }
270
+
271
+ const WHITE = 0, GRAY = 1, BLACK = 2;
272
+ const color = new Map<string, number>();
273
+ for (const id of validIds) color.set(id, WHITE);
274
+
275
+ const parent = new Map<string, string | null>();
276
+
277
+ function dfs(node: string): string[] | null {
278
+ color.set(node, GRAY);
279
+ for (const dep of adj.get(node) ?? []) {
280
+ if (color.get(dep) === GRAY) {
281
+ // Back edge found — reconstruct cycle path
282
+ const cycle: string[] = [dep, node];
283
+ let cur = node;
284
+ while (parent.has(cur) && parent.get(cur) !== null && parent.get(cur) !== dep) {
285
+ cur = parent.get(cur)!;
286
+ cycle.push(cur);
287
+ }
288
+ cycle.push(dep);
289
+ cycle.reverse();
290
+ return cycle;
291
+ }
292
+ if (color.get(dep) === WHITE) {
293
+ parent.set(dep, node);
294
+ const result = dfs(dep);
295
+ if (result) return result;
296
+ }
297
+ }
298
+ color.set(node, BLACK);
299
+ return null;
300
+ }
301
+
302
+ for (const id of validIds) {
303
+ if (color.get(id) === WHITE) {
304
+ parent.set(id, null);
305
+ const cycle = dfs(id);
306
+ if (cycle) {
307
+ errors.push(`Cycle detected: ${cycle.join(" → ")}`);
308
+ break; // One cycle error is enough
309
+ }
310
+ }
311
+ }
312
+ }
313
+ }
314
+ }
315
+
316
+ return { valid: errors.length === 0, errors };
317
+ }
318
+
319
+ // ─── Loading ─────────────────────────────────────────────────────────────
320
+
321
+ /**
322
+ * Load and validate a YAML workflow definition from the filesystem.
323
+ *
324
+ * Reads `<defsDir>/<name>.yaml`, parses YAML, validates the V1 schema,
325
+ * and converts snake_case YAML keys to camelCase TypeScript types.
326
+ *
327
+ * @param defsDir — directory containing definition YAML files
328
+ * @param name — definition filename without extension
329
+ * @returns Parsed and validated WorkflowDefinition
330
+ * @throws Error if file is missing, YAML is malformed, or schema is invalid
331
+ */
332
+ export function loadDefinition(defsDir: string, name: string): WorkflowDefinition {
333
+ const filePath = join(defsDir, `${name}.yaml`);
334
+
335
+ if (!existsSync(filePath)) {
336
+ throw new Error(`Definition file not found: ${filePath}`);
337
+ }
338
+
339
+ const raw = readFileSync(filePath, "utf-8");
340
+ let parsed: unknown;
341
+ try {
342
+ parsed = parse(raw);
343
+ } catch (e) {
344
+ const msg = e instanceof Error ? e.message : String(e);
345
+ throw new Error(`Failed to parse YAML in ${filePath}: ${msg}`);
346
+ }
347
+
348
+ const { valid, errors } = validateDefinition(parsed);
349
+ if (!valid) {
350
+ throw new Error(`Invalid workflow definition in ${filePath}:\n - ${errors.join("\n - ")}`);
351
+ }
352
+
353
+ // Convert snake_case YAML → camelCase TypeScript
354
+ const yamlDef = parsed as YamlWorkflowDef;
355
+ const yamlSteps = yamlDef.steps as YamlStepDef[];
356
+
357
+ return {
358
+ version: yamlDef.version as number,
359
+ name: yamlDef.name as string,
360
+ description: typeof yamlDef.description === "string" ? yamlDef.description : undefined,
361
+ params: yamlDef.params != null && typeof yamlDef.params === "object"
362
+ ? Object.fromEntries(
363
+ Object.entries(yamlDef.params as Record<string, unknown>).map(
364
+ ([k, v]) => [k, String(v)],
365
+ ),
366
+ )
367
+ : undefined,
368
+ steps: yamlSteps.map((s) => ({
369
+ id: s.id as string,
370
+ name: s.name as string,
371
+ prompt: s.prompt as string,
372
+ requires: Array.isArray(s.requires)
373
+ ? (s.requires as string[])
374
+ : Array.isArray(s.depends_on)
375
+ ? (s.depends_on as string[])
376
+ : [],
377
+ produces: Array.isArray(s.produces) ? (s.produces as string[]) : [],
378
+ contextFrom: Array.isArray(s.context_from) ? (s.context_from as string[]) : undefined,
379
+ verify: s.verify as VerifyPolicy | undefined,
380
+ iterate: (s.iterate != null && typeof s.iterate === "object")
381
+ ? s.iterate as IterateConfig
382
+ : undefined,
383
+ })),
384
+ };
385
+ }
386
+
387
+ // ─── Parameter Substitution ──────────────────────────────────────────────
388
+
389
+ /** Regex matching `{{key}}` placeholders — captures the key name. */
390
+ const PARAM_PATTERN = /\{\{(\w+)\}\}/g;
391
+
392
+ /**
393
+ * Replace `{{key}}` placeholders in a single prompt string.
394
+ *
395
+ * Exported for use by the engine on iteration-instance prompts that live
396
+ * in GRAPH.yaml (outside the definition's step list).
397
+ *
398
+ * @throws Error if any merged param value contains `..` (path-traversal guard)
399
+ */
400
+ export function substitutePromptString(
401
+ prompt: string,
402
+ merged: Record<string, string>,
403
+ ): string {
404
+ return prompt.replace(PARAM_PATTERN, (match, key: string) => {
405
+ const value = merged[key];
406
+ return value !== undefined ? value : match;
407
+ });
408
+ }
409
+
410
+ /**
411
+ * Replace `{{key}}` placeholders in all step prompts with param values.
412
+ *
413
+ * Merge order: `definition.params` (defaults) ← `overrides` (CLI wins).
414
+ * Returns a **new** WorkflowDefinition — the input is never mutated.
415
+ *
416
+ * @throws Error if any param value contains `..` (path-traversal guard)
417
+ * @throws Error if any `{{key}}` remains unresolved after substitution
418
+ */
419
+ export function substituteParams(
420
+ definition: WorkflowDefinition,
421
+ overrides?: Record<string, string>,
422
+ ): WorkflowDefinition {
423
+ const merged: Record<string, string> = {
424
+ ...(definition.params ?? {}),
425
+ ...(overrides ?? {}),
426
+ };
427
+
428
+ // Path-traversal guard: reject any value containing ".."
429
+ for (const [key, value] of Object.entries(merged)) {
430
+ if (value.includes("..")) {
431
+ throw new Error(
432
+ `Parameter "${key}" contains disallowed '..' (path traversal): ${value}`,
433
+ );
434
+ }
435
+ }
436
+
437
+ // Substitute in each step prompt
438
+ const substitutedSteps = definition.steps.map((step) => ({
439
+ ...step,
440
+ prompt: substitutePromptString(step.prompt, merged),
441
+ }));
442
+
443
+ // Check for unresolved placeholders
444
+ const unresolved = new Set<string>();
445
+ for (const step of substitutedSteps) {
446
+ let m: RegExpExecArray | null;
447
+ const re = new RegExp(PARAM_PATTERN.source, "g");
448
+ while ((m = re.exec(step.prompt)) !== null) {
449
+ unresolved.add(m[1]);
450
+ }
451
+ }
452
+
453
+ if (unresolved.size > 0) {
454
+ const keys = [...unresolved].sort().join(", ");
455
+ throw new Error(`Unresolved parameter(s) in step prompts: ${keys}`);
456
+ }
457
+
458
+ return {
459
+ ...definition,
460
+ steps: substitutedSteps,
461
+ };
462
+ }
@@ -69,7 +69,7 @@ export interface ProjectSignals {
69
69
 
70
70
  // ─── Project File Markers ───────────────────────────────────────────────────────
71
71
 
72
- const PROJECT_FILES = [
72
+ export const PROJECT_FILES = [
73
73
  "package.json",
74
74
  "Cargo.toml",
75
75
  "go.mod",
@@ -87,6 +87,18 @@ const PROJECT_FILES = [
87
87
  "mix.exs",
88
88
  "deno.json",
89
89
  "deno.jsonc",
90
+ // .NET
91
+ ".sln",
92
+ ".csproj",
93
+ "Directory.Build.props",
94
+ // Git submodules
95
+ ".gitmodules",
96
+ // Xcode
97
+ "project.yml",
98
+ ".xcodeproj",
99
+ ".xcworkspace",
100
+ // Docker
101
+ "Dockerfile",
90
102
  ] as const;
91
103
 
92
104
  const LANGUAGE_MAP: Record<string, string> = {
@@ -106,6 +118,13 @@ const LANGUAGE_MAP: Record<string, string> = {
106
118
  "mix.exs": "elixir",
107
119
  "deno.json": "typescript/deno",
108
120
  "deno.jsonc": "typescript/deno",
121
+ ".sln": "dotnet",
122
+ ".csproj": "dotnet",
123
+ "Directory.Build.props": "dotnet",
124
+ "project.yml": "swift/xcode",
125
+ ".xcodeproj": "swift/xcode",
126
+ ".xcworkspace": "swift/xcode",
127
+ "Dockerfile": "docker",
109
128
  };
110
129
 
111
130
  const MONOREPO_MARKERS = [
@@ -0,0 +1,51 @@
1
+ /**
2
+ * dev-execution-policy.ts — DevExecutionPolicy implementation.
3
+ *
4
+ * Stub policy for the dev engine. All methods return safe defaults.
5
+ * Real verification/closeout continues running through phases.ts via LoopDeps.
6
+ * Wiring this policy into the loop is S04's responsibility.
7
+ */
8
+
9
+ import type { ExecutionPolicy } from "./execution-policy.js";
10
+ import type { RecoveryAction, CloseoutResult } from "./engine-types.js";
11
+
12
+ export class DevExecutionPolicy implements ExecutionPolicy {
13
+ async prepareWorkspace(
14
+ _basePath: string,
15
+ _milestoneId: string,
16
+ ): Promise<void> {
17
+ // no-op — workspace preparation handled by existing GSD logic
18
+ }
19
+
20
+ async selectModel(
21
+ _unitType: string,
22
+ _unitId: string,
23
+ _context: { basePath: string },
24
+ ): Promise<{ tier: string; modelDowngraded: boolean } | null> {
25
+ return null; // use default model selection
26
+ }
27
+
28
+ async verify(
29
+ _unitType: string,
30
+ _unitId: string,
31
+ _context: { basePath: string },
32
+ ): Promise<"continue" | "retry" | "pause"> {
33
+ return "continue";
34
+ }
35
+
36
+ async recover(
37
+ _unitType: string,
38
+ _unitId: string,
39
+ _context: { basePath: string },
40
+ ): Promise<RecoveryAction> {
41
+ return { outcome: "retry" };
42
+ }
43
+
44
+ async closeout(
45
+ _unitType: string,
46
+ _unitId: string,
47
+ _context: { basePath: string; startedAt: number },
48
+ ): Promise<CloseoutResult> {
49
+ return { committed: false, artifacts: [] };
50
+ }
51
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * dev-workflow-engine.ts — DevWorkflowEngine implementation.
3
+ *
4
+ * Implements WorkflowEngine by delegating to existing GSD state derivation
5
+ * and dispatch logic. This is the "dev" engine — it wraps the current GSD
6
+ * auto-mode behavior behind the engine-polymorphic interface.
7
+ */
8
+
9
+ import type { WorkflowEngine } from "./workflow-engine.js";
10
+ import type {
11
+ EngineState,
12
+ EngineDispatchAction,
13
+ CompletedStep,
14
+ ReconcileResult,
15
+ DisplayMetadata,
16
+ } from "./engine-types.js";
17
+ import type { GSDState } from "./types.js";
18
+ import type { DispatchAction, DispatchContext } from "./auto-dispatch.js";
19
+
20
+ import { deriveState } from "./state.js";
21
+ import { resolveDispatch } from "./auto-dispatch.js";
22
+ import { loadEffectiveGSDPreferences } from "./preferences.js";
23
+
24
+ // ─── Bridge: DispatchAction → EngineDispatchAction ────────────────────────
25
+
26
+ /**
27
+ * Map a GSD-specific DispatchAction (which carries `matchedRule`, `unitType`,
28
+ * etc.) to the engine-generic EngineDispatchAction discriminated union.
29
+ *
30
+ * Exported for unit testing.
31
+ */
32
+ export function bridgeDispatchAction(da: DispatchAction): EngineDispatchAction {
33
+ switch (da.action) {
34
+ case "dispatch":
35
+ return {
36
+ action: "dispatch",
37
+ step: {
38
+ unitType: da.unitType,
39
+ unitId: da.unitId,
40
+ prompt: da.prompt,
41
+ },
42
+ };
43
+ case "stop":
44
+ return {
45
+ action: "stop",
46
+ reason: da.reason,
47
+ level: da.level,
48
+ };
49
+ case "skip":
50
+ return { action: "skip" };
51
+ }
52
+ }
53
+
54
+ // ─── DevWorkflowEngine ───────────────────────────────────────────────────
55
+
56
+ export class DevWorkflowEngine implements WorkflowEngine {
57
+ readonly engineId = "dev" as const;
58
+
59
+ async deriveState(basePath: string): Promise<EngineState> {
60
+ const gsd: GSDState = await deriveState(basePath);
61
+ return {
62
+ phase: gsd.phase,
63
+ currentMilestoneId: gsd.activeMilestone?.id ?? null,
64
+ activeSliceId: gsd.activeSlice?.id ?? null,
65
+ activeTaskId: gsd.activeTask?.id ?? null,
66
+ isComplete: gsd.phase === "complete",
67
+ raw: gsd,
68
+ };
69
+ }
70
+
71
+ async resolveDispatch(
72
+ state: EngineState,
73
+ context: { basePath: string },
74
+ ): Promise<EngineDispatchAction> {
75
+ const gsd = state.raw as GSDState;
76
+ const mid = gsd.activeMilestone?.id ?? "";
77
+ const midTitle = gsd.activeMilestone?.title ?? "";
78
+ const loaded = loadEffectiveGSDPreferences();
79
+ const prefs = loaded?.preferences ?? undefined;
80
+
81
+ const dispatchCtx: DispatchContext = {
82
+ basePath: context.basePath,
83
+ mid,
84
+ midTitle,
85
+ state: gsd,
86
+ prefs,
87
+ };
88
+
89
+ const result = await resolveDispatch(dispatchCtx);
90
+ return bridgeDispatchAction(result);
91
+ }
92
+
93
+ async reconcile(
94
+ state: EngineState,
95
+ _completedStep: CompletedStep,
96
+ ): Promise<ReconcileResult> {
97
+ return {
98
+ outcome: state.isComplete ? "milestone-complete" : "continue",
99
+ };
100
+ }
101
+
102
+ getDisplayMetadata(state: EngineState): DisplayMetadata {
103
+ return {
104
+ engineLabel: "GSD Dev",
105
+ currentPhase: state.phase,
106
+ progressSummary: `${state.currentMilestoneId ?? "no milestone"} / ${state.activeSliceId ?? "—"} / ${state.activeTaskId ?? "—"}`,
107
+ stepCount: null,
108
+ };
109
+ }
110
+ }