gsd-pi 2.41.0-dev.0acbce9 → 2.41.0-dev.5a170d0

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 (291) hide show
  1. package/README.md +1 -1
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/onboarding.js +2 -1
  5. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  6. package/dist/resources/extensions/gsd/auto/phases.js +28 -10
  7. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  11. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  12. package/dist/resources/extensions/gsd/auto-start.js +8 -3
  13. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  14. package/dist/resources/extensions/gsd/auto.js +64 -2
  15. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  16. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  17. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  18. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +16 -0
  19. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  20. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  21. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  22. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  23. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  24. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  25. package/dist/resources/extensions/gsd/context-store.js +4 -3
  26. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  27. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  28. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  29. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  30. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  31. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  32. package/dist/resources/extensions/gsd/detection.js +1 -1
  33. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  34. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  35. package/dist/resources/extensions/gsd/doctor.js +11 -1
  36. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  37. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  38. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  39. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  40. package/dist/resources/extensions/gsd/export.js +9 -13
  41. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  42. package/dist/resources/extensions/gsd/files.js +28 -11
  43. package/dist/resources/extensions/gsd/forensics.js +10 -3
  44. package/dist/resources/extensions/gsd/git-service.js +5 -1
  45. package/dist/resources/extensions/gsd/graph.js +225 -0
  46. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  47. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  48. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  49. package/dist/resources/extensions/gsd/journal.js +85 -0
  50. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  51. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  52. package/dist/resources/extensions/gsd/native-git-bridge.js +2 -2
  53. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  54. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  55. package/dist/resources/extensions/gsd/preferences.js +1 -0
  56. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  57. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  58. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  59. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  60. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  61. package/dist/resources/extensions/gsd/repo-identity.js +46 -2
  62. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  63. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  64. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  65. package/dist/resources/extensions/gsd/service-tier.js +138 -0
  66. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  67. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  68. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  69. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  70. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  71. package/dist/resources/extensions/gsd/worktree-resolver.js +19 -2
  72. package/dist/resources/extensions/subagent/index.js +7 -3
  73. package/dist/resources/extensions/voice/index.js +4 -4
  74. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  75. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  76. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  77. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  78. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  79. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  80. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  81. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  82. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  83. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  84. package/dist/web/standalone/.next/BUILD_ID +1 -1
  85. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  86. package/dist/web/standalone/.next/build-manifest.json +3 -3
  87. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  88. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  90. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/index.html +1 -1
  121. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  128. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  129. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  132. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  133. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  134. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  135. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  136. package/dist/web-mode.d.ts +2 -0
  137. package/dist/web-mode.js +29 -7
  138. package/package.json +1 -1
  139. package/packages/native/src/__tests__/text.test.mjs +33 -0
  140. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  141. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  144. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -0
  147. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  148. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  149. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  150. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +5 -0
  151. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -1
  152. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  153. package/src/resources/extensions/gsd/auto/phases.ts +30 -10
  154. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  155. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  156. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  157. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  158. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  159. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  160. package/src/resources/extensions/gsd/auto-start.ts +8 -3
  161. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  162. package/src/resources/extensions/gsd/auto.ts +71 -2
  163. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  164. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  165. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  166. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -0
  167. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  168. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  169. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  170. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  171. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  172. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  173. package/src/resources/extensions/gsd/context-store.ts +4 -3
  174. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  175. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  176. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  177. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  178. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  179. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  180. package/src/resources/extensions/gsd/detection.ts +1 -1
  181. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  182. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  183. package/src/resources/extensions/gsd/doctor.ts +12 -1
  184. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  185. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  186. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  187. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  188. package/src/resources/extensions/gsd/export.ts +8 -15
  189. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  190. package/src/resources/extensions/gsd/files.ts +29 -12
  191. package/src/resources/extensions/gsd/forensics.ts +9 -3
  192. package/src/resources/extensions/gsd/git-service.ts +5 -4
  193. package/src/resources/extensions/gsd/graph.ts +312 -0
  194. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  195. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  196. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  197. package/src/resources/extensions/gsd/journal.ts +134 -0
  198. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  199. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  200. package/src/resources/extensions/gsd/native-git-bridge.ts +2 -2
  201. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  202. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  203. package/src/resources/extensions/gsd/preferences.ts +1 -0
  204. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  205. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  206. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  207. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  208. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  209. package/src/resources/extensions/gsd/repo-identity.ts +47 -2
  210. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  211. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  212. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  213. package/src/resources/extensions/gsd/service-tier.ts +171 -0
  214. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  215. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  216. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  217. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  218. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  219. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  220. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  221. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  222. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  223. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  224. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  225. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  226. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  227. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  228. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  229. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  230. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  231. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  232. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  233. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  234. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  235. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  236. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  237. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  238. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  239. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  240. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  241. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  242. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  243. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  244. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  245. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  246. package/src/resources/extensions/gsd/tests/journal.test.ts +386 -0
  247. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  248. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  249. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  250. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  251. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  252. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  253. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  254. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  255. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  256. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  257. package/src/resources/extensions/gsd/tests/service-tier.test.ts +98 -0
  258. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  259. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  260. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  261. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  262. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  263. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  264. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  265. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  266. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  267. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +178 -0
  268. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +195 -105
  269. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -3
  270. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  271. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  272. package/src/resources/extensions/gsd/types.ts +3 -0
  273. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  274. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  275. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  276. package/src/resources/extensions/gsd/worktree-resolver.ts +30 -9
  277. package/src/resources/extensions/subagent/index.ts +7 -3
  278. package/src/resources/extensions/voice/index.ts +4 -4
  279. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  280. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  281. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  282. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  283. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  284. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  285. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  286. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  287. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  288. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  289. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  290. /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_buildManifest.js +0 -0
  291. /package/dist/web/standalone/.next/static/{SwbKZ7JPNFlEmU4f8pKEv → K7GYOOPvQWX6TKYEKhODM}/_ssgManifest.js +0 -0
@@ -569,6 +569,208 @@ async function main(): Promise<void> {
569
569
  assertTrue(existsSync(join(repo, "landed.ts")), "landed.ts present on main");
570
570
  }
571
571
 
572
+ // ─── Test 14: Stale branch ref — worktree HEAD ahead of branch (#1846) ─
573
+ console.log("\n=== stale branch ref — fast-forward before squash merge (#1846) ===");
574
+ {
575
+ const repo = freshRepo();
576
+ const wtPath = createAutoWorktree(repo, "M140");
577
+
578
+ // Add a first slice normally — this advances both the branch ref and HEAD
579
+ addSliceToMilestone(repo, wtPath, "M140", "S01", "Initial work", [
580
+ { file: "initial.ts", content: "export const initial = true;\n", message: "add initial" },
581
+ ]);
582
+
583
+ // Now simulate the bug: detach HEAD in the worktree, then make commits
584
+ // that advance HEAD but leave the milestone/M140 branch ref behind.
585
+ const branchRefBefore = run("git rev-parse milestone/M140", wtPath);
586
+ run("git checkout --detach HEAD", wtPath);
587
+
588
+ // Add multiple commits on the detached HEAD (simulates agent work)
589
+ writeFileSync(join(wtPath, "feature-a.ts"), "export const featureA = true;\n");
590
+ run("git add .", wtPath);
591
+ run('git commit -m "add feature-a"', wtPath);
592
+
593
+ writeFileSync(join(wtPath, "feature-b.ts"), "export const featureB = true;\n");
594
+ run("git add .", wtPath);
595
+ run('git commit -m "add feature-b"', wtPath);
596
+
597
+ writeFileSync(join(wtPath, "feature-c.ts"), "export const featureC = true;\n");
598
+ run("git add .", wtPath);
599
+ run('git commit -m "add feature-c"', wtPath);
600
+
601
+ // Verify: branch ref is stale, HEAD is ahead
602
+ const branchRefAfter = run("git rev-parse milestone/M140", wtPath);
603
+ const worktreeHead = run("git rev-parse HEAD", wtPath);
604
+ assertEq(branchRefBefore, branchRefAfter, "branch ref unchanged (stale)");
605
+ assertTrue(worktreeHead !== branchRefAfter, "worktree HEAD ahead of branch ref");
606
+
607
+ const roadmap = makeRoadmap("M140", "Stale ref milestone", [
608
+ { id: "S01", title: "Initial work" },
609
+ ]);
610
+
611
+ // The fix should fast-forward the branch ref to worktree HEAD before
612
+ // squash-merging, so ALL commits are captured.
613
+ let threw = false;
614
+ let errMsg = "";
615
+ try {
616
+ const result = mergeMilestoneToMain(repo, "M140", roadmap);
617
+ assertTrue(result.commitMessage.includes("feat(M140)"), "merge commit created");
618
+ } catch (err) {
619
+ threw = true;
620
+ errMsg = err instanceof Error ? err.message : String(err);
621
+ }
622
+ assertTrue(!threw, `should not throw with stale branch ref (got: ${errMsg})`);
623
+
624
+ // ALL files from detached HEAD commits must be on main — not just
625
+ // the ones from the stale branch ref
626
+ assertTrue(existsSync(join(repo, "initial.ts")), "initial.ts on main");
627
+ assertTrue(existsSync(join(repo, "feature-a.ts")), "feature-a.ts on main (#1846)");
628
+ assertTrue(existsSync(join(repo, "feature-b.ts")), "feature-b.ts on main (#1846)");
629
+ assertTrue(existsSync(join(repo, "feature-c.ts")), "feature-c.ts on main (#1846)");
630
+ }
631
+
632
+ // ─── Test 15: Diverged worktree HEAD — throws instead of losing data (#1846) ─
633
+ console.log("\n=== diverged worktree HEAD — throws on divergence (#1846) ===");
634
+ {
635
+ const repo = freshRepo();
636
+ const wtPath = createAutoWorktree(repo, "M150");
637
+
638
+ addSliceToMilestone(repo, wtPath, "M150", "S01", "Base work", [
639
+ { file: "base.ts", content: "export const base = true;\n", message: "add base" },
640
+ ]);
641
+
642
+ run("git checkout --detach HEAD", wtPath);
643
+ writeFileSync(join(wtPath, "detached-work.ts"), "export const detached = true;\n");
644
+ run("git add .", wtPath);
645
+ run('git commit -m "detached work"', wtPath);
646
+
647
+ run("git checkout milestone/M150", repo);
648
+ writeFileSync(join(repo, "diverged-work.ts"), "export const diverged = true;\n");
649
+ run("git add .", repo);
650
+ run('git commit -m "diverged work on branch"', repo);
651
+ run("git checkout main", repo);
652
+
653
+ process.chdir(wtPath);
654
+
655
+ const roadmap = makeRoadmap("M150", "Diverged milestone", [
656
+ { id: "S01", title: "Base work" },
657
+ ]);
658
+
659
+ let threw = false;
660
+ let errMsg = "";
661
+ try {
662
+ mergeMilestoneToMain(repo, "M150", roadmap);
663
+ } catch (err) {
664
+ threw = true;
665
+ errMsg = err instanceof Error ? err.message : String(err);
666
+ }
667
+ assertTrue(threw, "throws when worktree HEAD diverged from branch ref (#1846)");
668
+ assertTrue(errMsg.includes("diverged"), "error message mentions divergence (#1846)");
669
+
670
+ const branches = run("git branch", repo);
671
+ assertTrue(branches.includes("milestone/M150"), "milestone branch preserved on divergence (#1846)");
672
+ }
673
+
674
+ // ─── Test 16: #1853 Bug 1 — SQUASH_MSG cleaned up after squash-merge ──
675
+ console.log("\n=== #1853 bug 1: SQUASH_MSG cleaned up after successful squash-merge ===");
676
+ {
677
+ const repo = freshRepo();
678
+ const wtPath = createAutoWorktree(repo, "M160");
679
+
680
+ addSliceToMilestone(repo, wtPath, "M160", "S01", "SQUASH_MSG cleanup test", [
681
+ { file: "squash-cleanup.ts", content: "export const cleanup = true;\n", message: "add squash-cleanup" },
682
+ ]);
683
+
684
+ const roadmap = makeRoadmap("M160", "SQUASH_MSG cleanup", [
685
+ { id: "S01", title: "SQUASH_MSG cleanup test" },
686
+ ]);
687
+
688
+ const squashMsgPath = join(repo, ".git", "SQUASH_MSG");
689
+ writeFileSync(squashMsgPath, "leftover squash message\n");
690
+ assertTrue(existsSync(squashMsgPath), "SQUASH_MSG planted before merge");
691
+
692
+ const result = mergeMilestoneToMain(repo, "M160", roadmap);
693
+ assertTrue(result.commitMessage.includes("feat(M160)"), "merge commit created");
694
+
695
+ assertTrue(
696
+ !existsSync(squashMsgPath),
697
+ "#1853: SQUASH_MSG must not persist after successful squash-merge",
698
+ );
699
+ }
700
+
701
+ // ─── Test 17: #1853 Bug 2 — uncommitted worktree code survives teardown ──
702
+ console.log("\n=== #1853 bug 2: uncommitted worktree changes committed before teardown ===");
703
+ {
704
+ const repo = freshRepo();
705
+ const wtPath = createAutoWorktree(repo, "M170");
706
+
707
+ addSliceToMilestone(repo, wtPath, "M170", "S01", "Teardown safety test", [
708
+ { file: "safe-file.ts", content: "export const safe = true;\n", message: "add safe file" },
709
+ ]);
710
+
711
+ writeFileSync(join(wtPath, "uncommitted-agent-code.ts"), "export const lost = true;\n");
712
+
713
+ const roadmap = makeRoadmap("M170", "Teardown safety", [
714
+ { id: "S01", title: "Teardown safety test" },
715
+ ]);
716
+
717
+ const result = mergeMilestoneToMain(repo, "M170", roadmap);
718
+ assertTrue(result.commitMessage.includes("feat(M170)"), "merge commit created");
719
+
720
+ assertTrue(
721
+ existsSync(join(repo, "uncommitted-agent-code.ts")),
722
+ "#1853: uncommitted worktree code must survive teardown",
723
+ );
724
+ }
725
+
726
+ // ─── Test 18: #1906 — codeFilesChanged false when only .gsd/ metadata merged ──
727
+ console.log("\n=== #1906: codeFilesChanged=false when only .gsd/ metadata merged ===");
728
+ {
729
+ const repo = freshRepo();
730
+ const wtPath = createAutoWorktree(repo, "M180");
731
+
732
+ // Only add .gsd/ metadata files — no actual code
733
+ mkdirSync(join(wtPath, ".gsd", "milestones", "M180"), { recursive: true });
734
+ writeFileSync(
735
+ join(wtPath, ".gsd", "milestones", "M180", "SUMMARY.md"),
736
+ "# M180 Summary\n\nThis milestone was planned but not implemented.\n",
737
+ );
738
+ run("git add .", wtPath);
739
+ run('git commit -m "chore: add milestone summary"', wtPath);
740
+
741
+ const roadmap = makeRoadmap("M180", "Metadata-only milestone", []);
742
+
743
+ const result = mergeMilestoneToMain(repo, "M180", roadmap);
744
+ assertEq(
745
+ result.codeFilesChanged,
746
+ false,
747
+ "#1906: codeFilesChanged must be false when only .gsd/ files were merged",
748
+ );
749
+ }
750
+
751
+ // ─── Test 19: #1906 — codeFilesChanged true when real code is merged ──
752
+ console.log("\n=== #1906: codeFilesChanged=true when real code is merged ===");
753
+ {
754
+ const repo = freshRepo();
755
+ const wtPath = createAutoWorktree(repo, "M190");
756
+
757
+ addSliceToMilestone(repo, wtPath, "M190", "S01", "Real code", [
758
+ { file: "real-code.ts", content: "export const real = true;\n", message: "add real code" },
759
+ ]);
760
+
761
+ const roadmap = makeRoadmap("M190", "Code milestone", [
762
+ { id: "S01", title: "Real code" },
763
+ ]);
764
+
765
+ const result = mergeMilestoneToMain(repo, "M190", roadmap);
766
+ assertEq(
767
+ result.codeFilesChanged,
768
+ true,
769
+ "#1906: codeFilesChanged must be true when real code files were merged",
770
+ );
771
+ assertTrue(existsSync(join(repo, "real-code.ts")), "real-code.ts merged to main");
772
+ }
773
+
572
774
  } finally {
573
775
  process.chdir(savedCwd);
574
776
  for (const d of tempDirs) {
@@ -0,0 +1,180 @@
1
+ /**
2
+ * Bundled workflow definition validation tests.
3
+ *
4
+ * Verifies that every example YAML in src/resources/skills/create-workflow/templates/
5
+ * passes validateDefinition() from definition-loader.ts with { valid: true, errors: [] }.
6
+ *
7
+ * Also validates scaffold template and structural properties of each example
8
+ * (step counts, feature usage) to guard against accidental regressions.
9
+ */
10
+
11
+ import test from "node:test";
12
+ import assert from "node:assert/strict";
13
+ import { readFileSync } from "node:fs";
14
+ import { join, dirname } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+ import { parse } from "yaml";
17
+
18
+ import { validateDefinition } from "../definition-loader.ts";
19
+
20
+ // ─── Path resolution ─────────────────────────────────────────────────────
21
+
22
+ const __dirname = dirname(fileURLToPath(import.meta.url));
23
+ // Navigate from tests/ → extensions/gsd/ → extensions/ → resources/ → skills/create-workflow/templates/
24
+ const templatesDir = join(
25
+ __dirname,
26
+ "..",
27
+ "..",
28
+ "..",
29
+ "skills",
30
+ "create-workflow",
31
+ "templates",
32
+ );
33
+
34
+ function loadYaml(filename: string): unknown {
35
+ const raw = readFileSync(join(templatesDir, filename), "utf-8");
36
+ return parse(raw);
37
+ }
38
+
39
+ // ─── Scaffold template ──────────────────────────────────────────────────
40
+
41
+ test("scaffold template (workflow-definition.yaml) passes validation", () => {
42
+ const parsed = loadYaml("workflow-definition.yaml");
43
+ const result = validateDefinition(parsed);
44
+ assert.equal(result.valid, true, `Scaffold invalid: ${result.errors.join("; ")}`);
45
+ assert.equal(result.errors.length, 0);
46
+ });
47
+
48
+ // ─── blog-post-pipeline.yaml ────────────────────────────────────────────
49
+
50
+ test("blog-post-pipeline.yaml passes validation", () => {
51
+ const parsed = loadYaml("blog-post-pipeline.yaml");
52
+ const result = validateDefinition(parsed);
53
+ assert.equal(result.valid, true, `Invalid: ${result.errors.join("; ")}`);
54
+ assert.equal(result.errors.length, 0);
55
+ });
56
+
57
+ test("blog-post-pipeline.yaml: 3 steps, context_from, params, content-heuristic", () => {
58
+ const parsed = loadYaml("blog-post-pipeline.yaml") as Record<string, unknown>;
59
+ const steps = parsed.steps as Array<Record<string, unknown>>;
60
+
61
+ // 3 steps
62
+ assert.equal(steps.length, 3, "Expected 3 steps");
63
+
64
+ // params defined
65
+ assert.ok(parsed.params, "Expected params to be defined");
66
+ const params = parsed.params as Record<string, string>;
67
+ assert.ok("topic" in params, "Expected 'topic' param");
68
+ assert.ok("audience" in params, "Expected 'audience' param");
69
+
70
+ // At least one step uses context_from
71
+ const hasContextFrom = steps.some(
72
+ (s) => Array.isArray(s.context_from) && s.context_from.length > 0,
73
+ );
74
+ assert.ok(hasContextFrom, "Expected at least one step with context_from");
75
+
76
+ // All steps use content-heuristic verify
77
+ for (const step of steps) {
78
+ const verify = step.verify as Record<string, unknown> | undefined;
79
+ assert.ok(verify, `Step "${step.id}" missing verify`);
80
+ assert.equal(verify.policy, "content-heuristic", `Step "${step.id}" should use content-heuristic`);
81
+ }
82
+ });
83
+
84
+ // ─── code-audit.yaml ────────────────────────────────────────────────────
85
+
86
+ test("code-audit.yaml passes validation", () => {
87
+ const parsed = loadYaml("code-audit.yaml");
88
+ const result = validateDefinition(parsed);
89
+ assert.equal(result.valid, true, `Invalid: ${result.errors.join("; ")}`);
90
+ assert.equal(result.errors.length, 0);
91
+ });
92
+
93
+ test("code-audit.yaml: iterate with capture group and shell-command verify", () => {
94
+ const parsed = loadYaml("code-audit.yaml") as Record<string, unknown>;
95
+ const steps = parsed.steps as Array<Record<string, unknown>>;
96
+
97
+ // Find step with iterate
98
+ const iterateStep = steps.find((s) => s.iterate != null);
99
+ assert.ok(iterateStep, "Expected a step with iterate config");
100
+
101
+ const iterate = iterateStep.iterate as Record<string, unknown>;
102
+ assert.equal(typeof iterate.source, "string", "iterate.source must be a string");
103
+ assert.equal(typeof iterate.pattern, "string", "iterate.pattern must be a string");
104
+
105
+ // Pattern has a capture group
106
+ const pattern = iterate.pattern as string;
107
+ assert.ok(/\((?!\?)/.test(pattern), "iterate.pattern must contain a capture group");
108
+
109
+ // Pattern is valid regex
110
+ assert.doesNotThrow(() => new RegExp(pattern), "iterate.pattern must be valid regex");
111
+
112
+ // Has shell-command verify
113
+ const verify = iterateStep.verify as Record<string, unknown>;
114
+ assert.equal(verify.policy, "shell-command");
115
+ assert.equal(typeof verify.command, "string");
116
+ });
117
+
118
+ // ─── release-checklist.yaml ─────────────────────────────────────────────
119
+
120
+ test("release-checklist.yaml passes validation", () => {
121
+ const parsed = loadYaml("release-checklist.yaml");
122
+ const result = validateDefinition(parsed);
123
+ assert.equal(result.valid, true, `Invalid: ${result.errors.join("; ")}`);
124
+ assert.equal(result.errors.length, 0);
125
+ });
126
+
127
+ test("release-checklist.yaml: diamond dependencies and human-review", () => {
128
+ const parsed = loadYaml("release-checklist.yaml") as Record<string, unknown>;
129
+ const steps = parsed.steps as Array<Record<string, unknown>>;
130
+
131
+ // 4 steps
132
+ assert.equal(steps.length, 4, "Expected 4 steps");
133
+
134
+ // Diamond pattern: two steps depend on the same parent
135
+ const changelog = steps.find((s) => s.id === "changelog");
136
+ const versionBump = steps.find((s) => s.id === "version-bump");
137
+ const testSuite = steps.find((s) => s.id === "test-suite");
138
+ const publish = steps.find((s) => s.id === "publish");
139
+
140
+ assert.ok(changelog, "Expected 'changelog' step");
141
+ assert.ok(versionBump, "Expected 'version-bump' step");
142
+ assert.ok(testSuite, "Expected 'test-suite' step");
143
+ assert.ok(publish, "Expected 'publish' step");
144
+
145
+ // Both version-bump and test-suite depend on changelog
146
+ const vbReqs = versionBump.requires as string[];
147
+ const tsReqs = testSuite.requires as string[];
148
+ assert.ok(vbReqs.includes("changelog"), "version-bump should require changelog");
149
+ assert.ok(tsReqs.includes("changelog"), "test-suite should require changelog");
150
+
151
+ // publish depends on both (diamond join)
152
+ const pubReqs = publish.requires as string[];
153
+ assert.ok(pubReqs.includes("version-bump"), "publish should require version-bump");
154
+ assert.ok(pubReqs.includes("test-suite"), "publish should require test-suite");
155
+
156
+ // publish uses human-review
157
+ const verify = publish.verify as Record<string, unknown>;
158
+ assert.equal(verify.policy, "human-review");
159
+ });
160
+
161
+ // ─── Cross-cutting: no path traversal in produces ───────────────────────
162
+
163
+ test("no produces path contains '..'", () => {
164
+ const files = [
165
+ "blog-post-pipeline.yaml",
166
+ "code-audit.yaml",
167
+ "release-checklist.yaml",
168
+ ];
169
+
170
+ for (const file of files) {
171
+ const parsed = loadYaml(file) as Record<string, unknown>;
172
+ const steps = parsed.steps as Array<Record<string, unknown>>;
173
+ for (const step of steps) {
174
+ const produces = (step.produces as string[]) ?? [];
175
+ for (const p of produces) {
176
+ assert.ok(!p.includes(".."), `${file} step "${step.id}" produces path contains '..': ${p}`);
177
+ }
178
+ }
179
+ }
180
+ });
@@ -119,12 +119,23 @@ test("captures: loadPendingCaptures filters resolved entries", () => {
119
119
  const id1 = appendCapture(tmp, "pending one");
120
120
  appendCapture(tmp, "pending two");
121
121
 
122
- // Resolve the first one
123
122
  markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
124
123
 
125
124
  const pending = loadPendingCaptures(tmp);
126
125
  assert.strictEqual(pending.length, 1, "should have 1 pending");
127
126
  assert.strictEqual(pending[0].text, "pending two");
127
+ } finally {
128
+ rmSync(tmp, { recursive: true, force: true });
129
+ }
130
+ });
131
+
132
+ test("captures: loadAllCaptures preserves resolved entries", () => {
133
+ const tmp = makeTempDir("cap-all-resolved");
134
+ try {
135
+ const id1 = appendCapture(tmp, "pending one");
136
+ appendCapture(tmp, "pending two");
137
+
138
+ markCaptureResolved(tmp, id1, "note", "acknowledged", "just a note");
128
139
 
129
140
  const all = loadAllCaptures(tmp);
130
141
  assert.strictEqual(all.length, 2, "all should still have 2");