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
@@ -15,7 +15,7 @@
15
15
  * 11. Dependency audit — git diff detection, npm audit parsing, graceful failures
16
16
  */
17
17
 
18
- import test from "node:test";
18
+ import { describe, test, beforeEach, afterEach } from "node:test";
19
19
  import assert from "node:assert/strict";
20
20
  import { mkdirSync, writeFileSync, rmSync } from "node:fs";
21
21
  import { join, dirname } from "node:path";
@@ -37,37 +37,30 @@ function makeTempDir(prefix: string): string {
37
37
 
38
38
  // ─── Discovery Tests ─────────────────────────────────────────────────────────
39
39
 
40
- test("verification-gate: discoverCommands from preference commands", () => {
41
- const tmp = makeTempDir("vg-pref");
42
- try {
40
+ describe("verification-gate: discovery", () => {
41
+ let tmp: string;
42
+ beforeEach(() => { tmp = makeTempDir("vg-discovery"); });
43
+ afterEach(() => { rmSync(tmp, { recursive: true, force: true }); });
44
+
45
+ test("discoverCommands from preference commands", () => {
43
46
  const result = discoverCommands({
44
47
  preferenceCommands: ["npm run lint", "npm run test"],
45
48
  cwd: tmp,
46
49
  });
47
50
  assert.deepStrictEqual(result.commands, ["npm run lint", "npm run test"]);
48
51
  assert.equal(result.source, "preference");
49
- } finally {
50
- rmSync(tmp, { recursive: true, force: true });
51
- }
52
- });
52
+ });
53
53
 
54
- test("verification-gate: discoverCommands from task plan verify field", () => {
55
- const tmp = makeTempDir("vg-taskplan");
56
- try {
54
+ test("discoverCommands from task plan verify field", () => {
57
55
  const result = discoverCommands({
58
56
  taskPlanVerify: "npm run lint && npm run test",
59
57
  cwd: tmp,
60
58
  });
61
59
  assert.deepStrictEqual(result.commands, ["npm run lint", "npm run test"]);
62
60
  assert.equal(result.source, "task-plan");
63
- } finally {
64
- rmSync(tmp, { recursive: true, force: true });
65
- }
66
- });
61
+ });
67
62
 
68
- test("verification-gate: discoverCommands from package.json scripts", () => {
69
- const tmp = makeTempDir("vg-pkg");
70
- try {
63
+ test("discoverCommands from package.json scripts", () => {
71
64
  writeFileSync(
72
65
  join(tmp, "package.json"),
73
66
  JSON.stringify({
@@ -86,14 +79,9 @@ test("verification-gate: discoverCommands from package.json scripts", () => {
86
79
  "npm run test",
87
80
  ]);
88
81
  assert.equal(result.source, "package-json");
89
- } finally {
90
- rmSync(tmp, { recursive: true, force: true });
91
- }
92
- });
82
+ });
93
83
 
94
- test("verification-gate: first-non-empty-wins — preference beats task plan and package.json", () => {
95
- const tmp = makeTempDir("vg-precedence");
96
- try {
84
+ test("first-non-empty-wins — preference beats task plan and package.json", () => {
97
85
  writeFileSync(
98
86
  join(tmp, "package.json"),
99
87
  JSON.stringify({ scripts: { lint: "eslint ." } }),
@@ -105,14 +93,9 @@ test("verification-gate: first-non-empty-wins — preference beats task plan and
105
93
  });
106
94
  assert.deepStrictEqual(result.commands, ["custom-check"]);
107
95
  assert.equal(result.source, "preference");
108
- } finally {
109
- rmSync(tmp, { recursive: true, force: true });
110
- }
111
- });
96
+ });
112
97
 
113
- test("verification-gate: task plan verify beats package.json", () => {
114
- const tmp = makeTempDir("vg-tp-beats-pkg");
115
- try {
98
+ test("task plan verify beats package.json", () => {
116
99
  writeFileSync(
117
100
  join(tmp, "package.json"),
118
101
  JSON.stringify({ scripts: { lint: "eslint ." } }),
@@ -123,25 +106,15 @@ test("verification-gate: task plan verify beats package.json", () => {
123
106
  });
124
107
  assert.deepStrictEqual(result.commands, ["custom-verify"]);
125
108
  assert.equal(result.source, "task-plan");
126
- } finally {
127
- rmSync(tmp, { recursive: true, force: true });
128
- }
129
- });
109
+ });
130
110
 
131
- test("verification-gate: missing package.json → 0 checks, source none", () => {
132
- const tmp = makeTempDir("vg-no-pkg");
133
- try {
111
+ test("missing package.json → 0 checks, source none", () => {
134
112
  const result = discoverCommands({ cwd: tmp });
135
113
  assert.deepStrictEqual(result.commands, []);
136
114
  assert.equal(result.source, "none");
137
- } finally {
138
- rmSync(tmp, { recursive: true, force: true });
139
- }
140
- });
115
+ });
141
116
 
142
- test("verification-gate: package.json with no matching scripts → 0 checks", () => {
143
- const tmp = makeTempDir("vg-no-scripts");
144
- try {
117
+ test("package.json with no matching scripts → 0 checks", () => {
145
118
  writeFileSync(
146
119
  join(tmp, "package.json"),
147
120
  JSON.stringify({ scripts: { build: "tsc", start: "node index.js" } }),
@@ -149,14 +122,9 @@ test("verification-gate: package.json with no matching scripts → 0 checks", ()
149
122
  const result = discoverCommands({ cwd: tmp });
150
123
  assert.deepStrictEqual(result.commands, []);
151
124
  assert.equal(result.source, "none");
152
- } finally {
153
- rmSync(tmp, { recursive: true, force: true });
154
- }
155
- });
125
+ });
156
126
 
157
- test("verification-gate: empty preference array falls through to task plan", () => {
158
- const tmp = makeTempDir("vg-empty-pref");
159
- try {
127
+ test("empty preference array falls through to task plan", () => {
160
128
  const result = discoverCommands({
161
129
  preferenceCommands: [],
162
130
  taskPlanVerify: "echo ok",
@@ -164,16 +132,99 @@ test("verification-gate: empty preference array falls through to task plan", ()
164
132
  });
165
133
  assert.deepStrictEqual(result.commands, ["echo ok"]);
166
134
  assert.equal(result.source, "task-plan");
167
- } finally {
168
- rmSync(tmp, { recursive: true, force: true });
169
- }
135
+ });
136
+
137
+ test("package.json with only test script → returns only npm run test", () => {
138
+ writeFileSync(
139
+ join(tmp, "package.json"),
140
+ JSON.stringify({
141
+ scripts: {
142
+ test: "vitest",
143
+ build: "tsc",
144
+ start: "node index.js",
145
+ },
146
+ }),
147
+ );
148
+ const result = discoverCommands({ cwd: tmp });
149
+ assert.deepStrictEqual(result.commands, ["npm run test"]);
150
+ assert.equal(result.source, "package-json");
151
+ });
152
+
153
+ test("taskPlanVerify with single command (no &&)", () => {
154
+ const result = discoverCommands({
155
+ taskPlanVerify: "npm test",
156
+ cwd: tmp,
157
+ });
158
+ assert.deepStrictEqual(result.commands, ["npm test"]);
159
+ assert.equal(result.source, "task-plan");
160
+ });
161
+
162
+ test("whitespace-only preference commands fall through", () => {
163
+ writeFileSync(
164
+ join(tmp, "package.json"),
165
+ JSON.stringify({ scripts: { lint: "eslint ." } }),
166
+ );
167
+ const result = discoverCommands({
168
+ preferenceCommands: [" ", ""],
169
+ cwd: tmp,
170
+ });
171
+ // Whitespace-only strings are trimmed to empty and filtered out
172
+ assert.equal(result.source, "package-json");
173
+ assert.deepStrictEqual(result.commands, ["npm run lint"]);
174
+ });
175
+
176
+ test("prose taskPlanVerify is rejected, falls through to package.json", () => {
177
+ writeFileSync(
178
+ join(tmp, "package.json"),
179
+ JSON.stringify({ scripts: { test: "vitest" } }),
180
+ );
181
+ const result = discoverCommands({
182
+ taskPlanVerify: "Document exists, contains all 5 scale names, all 14 semantic tokens",
183
+ cwd: tmp,
184
+ });
185
+ // Prose should be rejected, so it falls through to package.json
186
+ assert.equal(result.source, "package-json");
187
+ assert.deepStrictEqual(result.commands, ["npm run test"]);
188
+ });
189
+
190
+ test("prose taskPlanVerify with no package.json → source none", () => {
191
+ const result = discoverCommands({
192
+ taskPlanVerify: "Verify the output matches expected format and all fields are present",
193
+ cwd: tmp,
194
+ });
195
+ assert.equal(result.source, "none");
196
+ assert.deepStrictEqual(result.commands, []);
197
+ });
198
+
199
+ test("valid command in taskPlanVerify still works", () => {
200
+ const result = discoverCommands({
201
+ taskPlanVerify: "npm run lint && npm run test",
202
+ cwd: tmp,
203
+ });
204
+ assert.equal(result.source, "task-plan");
205
+ assert.deepStrictEqual(result.commands, ["npm run lint", "npm run test"]);
206
+ });
207
+
208
+ test("mixed prose and commands in taskPlanVerify — only commands kept", () => {
209
+ const result = discoverCommands({
210
+ taskPlanVerify: "Check that everything works && npm run test",
211
+ cwd: tmp,
212
+ });
213
+ // "Check that everything works" is prose (starts with capital, 4+ words)
214
+ // "npm run test" is a valid command
215
+ assert.equal(result.source, "task-plan");
216
+ assert.deepStrictEqual(result.commands, ["npm run test"]);
217
+ });
170
218
  });
171
219
 
172
220
  // ─── Execution Tests ─────────────────────────────────────────────────────────
173
221
 
174
- test("verification-gate: all commands pass → gate passes", () => {
175
- const tmp = makeTempDir("vg-pass");
176
- try {
222
+ describe("verification-gate: execution", () => {
223
+ let tmp: string;
224
+ beforeEach(() => { tmp = makeTempDir("vg-exec"); });
225
+ afterEach(() => { rmSync(tmp, { recursive: true, force: true }); });
226
+
227
+ test("all commands pass → gate passes", () => {
177
228
  const result = runVerificationGate({
178
229
  basePath: tmp,
179
230
  unitId: "T01",
@@ -188,14 +239,9 @@ test("verification-gate: all commands pass → gate passes", () => {
188
239
  assert.ok(result.checks[0].stdout.includes("hello"));
189
240
  assert.ok(result.checks[1].stdout.includes("world"));
190
241
  assert.equal(typeof result.timestamp, "number");
191
- } finally {
192
- rmSync(tmp, { recursive: true, force: true });
193
- }
194
- });
242
+ });
195
243
 
196
- test("verification-gate: one command fails → gate fails with exit code + stderr", () => {
197
- const tmp = makeTempDir("vg-fail");
198
- try {
244
+ test("one command fails → gate fails with exit code + stderr", () => {
199
245
  const result = runVerificationGate({
200
246
  basePath: tmp,
201
247
  unitId: "T01",
@@ -207,14 +253,9 @@ test("verification-gate: one command fails → gate fails with exit code + stder
207
253
  assert.equal(result.checks[0].exitCode, 0);
208
254
  assert.equal(result.checks[1].exitCode, 1);
209
255
  assert.ok(result.checks[1].stderr.includes("err"));
210
- } finally {
211
- rmSync(tmp, { recursive: true, force: true });
212
- }
213
- });
256
+ });
214
257
 
215
- test("verification-gate: no commands discovered → gate passes with 0 checks", () => {
216
- const tmp = makeTempDir("vg-empty");
217
- try {
258
+ test("no commands discovered → gate passes with 0 checks", () => {
218
259
  const result = runVerificationGate({
219
260
  basePath: tmp,
220
261
  unitId: "T01",
@@ -223,14 +264,9 @@ test("verification-gate: no commands discovered → gate passes with 0 checks",
223
264
  assert.equal(result.passed, true);
224
265
  assert.equal(result.checks.length, 0);
225
266
  assert.equal(result.discoverySource, "none");
226
- } finally {
227
- rmSync(tmp, { recursive: true, force: true });
228
- }
229
- });
267
+ });
230
268
 
231
- test("verification-gate: command not found → exit code 127", () => {
232
- const tmp = makeTempDir("vg-notfound");
233
- try {
269
+ test("command not found → exit code 127", () => {
234
270
  const result = runVerificationGate({
235
271
  basePath: tmp,
236
272
  unitId: "T01",
@@ -241,14 +277,9 @@ test("verification-gate: command not found → exit code 127", () => {
241
277
  assert.equal(result.checks.length, 1);
242
278
  assert.ok(result.checks[0].exitCode !== 0, "should have non-zero exit code");
243
279
  assert.ok(result.checks[0].durationMs >= 0);
244
- } finally {
245
- rmSync(tmp, { recursive: true, force: true });
246
- }
247
- });
280
+ });
248
281
 
249
- test("verification-gate: no DEP0190 deprecation warning when running commands", () => {
250
- const tmp = makeTempDir("vg-dep0190");
251
- try {
282
+ test("no DEP0190 deprecation warning when running commands", () => {
252
283
  // Run a subprocess with --throw-deprecation so any DeprecationWarning
253
284
  // becomes a thrown error (non-zero exit). The fix passes the command
254
285
  // string to sh -c explicitly instead of using spawnSync(cmd, {shell:true}).
@@ -282,14 +313,9 @@ test("verification-gate: no DEP0190 deprecation warning when running commands",
282
313
  0,
283
314
  `Expected exit 0 (no deprecation) but got ${child.status}. stderr: ${child.stderr}`,
284
315
  );
285
- } finally {
286
- rmSync(tmp, { recursive: true, force: true });
287
- }
288
- });
316
+ });
289
317
 
290
- test("verification-gate: each check has durationMs", () => {
291
- const tmp = makeTempDir("vg-duration");
292
- try {
318
+ test("each check has durationMs", () => {
293
319
  const result = runVerificationGate({
294
320
  basePath: tmp,
295
321
  unitId: "T01",
@@ -299,9 +325,42 @@ test("verification-gate: each check has durationMs", () => {
299
325
  assert.equal(result.checks.length, 1);
300
326
  assert.equal(typeof result.checks[0].durationMs, "number");
301
327
  assert.ok(result.checks[0].durationMs >= 0);
302
- } finally {
303
- rmSync(tmp, { recursive: true, force: true });
304
- }
328
+ });
329
+
330
+ test("one command fails — remaining commands still run (non-short-circuit)", () => {
331
+ // First fails, second and third should still execute
332
+ const result = runVerificationGate({
333
+ basePath: tmp,
334
+ unitId: "T02",
335
+ cwd: tmp,
336
+ preferenceCommands: [
337
+ "sh -c 'exit 1'",
338
+ "echo second",
339
+ "echo third",
340
+ ],
341
+ });
342
+ assert.equal(result.passed, false);
343
+ assert.equal(result.checks.length, 3, "all 3 commands should run");
344
+ assert.equal(result.checks[0].exitCode, 1, "first command fails");
345
+ assert.equal(result.checks[1].exitCode, 0, "second command runs and passes");
346
+ assert.ok(result.checks[1].stdout.includes("second"));
347
+ assert.equal(result.checks[2].exitCode, 0, "third command runs and passes");
348
+ assert.ok(result.checks[2].stdout.includes("third"));
349
+ });
350
+
351
+ test("gate execution uses cwd for spawnSync", () => {
352
+ // pwd should report the temp dir
353
+ const result = runVerificationGate({
354
+ basePath: tmp,
355
+ unitId: "T02",
356
+ cwd: tmp,
357
+ preferenceCommands: ["pwd"],
358
+ });
359
+ assert.equal(result.passed, true);
360
+ assert.equal(result.checks.length, 1);
361
+ // The stdout should contain the tmp dir path (resolving symlinks)
362
+ assert.ok(result.checks[0].stdout.trim().length > 0, "pwd should produce output");
363
+ });
305
364
  });
306
365
 
307
366
  // ─── Preference Validation Tests ─────────────────────────────────────────────
@@ -361,62 +420,6 @@ test("verification-gate: validatePreferences floors verification_max_retries", (
361
420
  assert.equal(result.errors.length, 0);
362
421
  });
363
422
 
364
- // ─── Additional Discovery Tests (T02) ───────────────────────────────────────
365
-
366
- test("verification-gate: package.json with only test script → returns only npm run test", () => {
367
- const tmp = makeTempDir("vg-only-test");
368
- try {
369
- writeFileSync(
370
- join(tmp, "package.json"),
371
- JSON.stringify({
372
- scripts: {
373
- test: "vitest",
374
- build: "tsc",
375
- start: "node index.js",
376
- },
377
- }),
378
- );
379
- const result = discoverCommands({ cwd: tmp });
380
- assert.deepStrictEqual(result.commands, ["npm run test"]);
381
- assert.equal(result.source, "package-json");
382
- } finally {
383
- rmSync(tmp, { recursive: true, force: true });
384
- }
385
- });
386
-
387
- test("verification-gate: taskPlanVerify with single command (no &&)", () => {
388
- const tmp = makeTempDir("vg-tp-single");
389
- try {
390
- const result = discoverCommands({
391
- taskPlanVerify: "npm test",
392
- cwd: tmp,
393
- });
394
- assert.deepStrictEqual(result.commands, ["npm test"]);
395
- assert.equal(result.source, "task-plan");
396
- } finally {
397
- rmSync(tmp, { recursive: true, force: true });
398
- }
399
- });
400
-
401
- test("verification-gate: whitespace-only preference commands fall through", () => {
402
- const tmp = makeTempDir("vg-ws-pref");
403
- try {
404
- writeFileSync(
405
- join(tmp, "package.json"),
406
- JSON.stringify({ scripts: { lint: "eslint ." } }),
407
- );
408
- const result = discoverCommands({
409
- preferenceCommands: [" ", ""],
410
- cwd: tmp,
411
- });
412
- // Whitespace-only strings are trimmed to empty and filtered out
413
- assert.equal(result.source, "package-json");
414
- assert.deepStrictEqual(result.commands, ["npm run lint"]);
415
- } finally {
416
- rmSync(tmp, { recursive: true, force: true });
417
- }
418
- });
419
-
420
423
  // ─── isLikelyCommand Tests (issue #1066) ────────────────────────────────────
421
424
 
422
425
  test("isLikelyCommand: known command prefixes are accepted", () => {
@@ -468,116 +471,6 @@ test("isLikelyCommand: short lowercase tokens without flags are accepted (could
468
471
  assert.equal(isLikelyCommand("mycheck"), true);
469
472
  });
470
473
 
471
- test("verification-gate: prose taskPlanVerify is rejected, falls through to package.json", () => {
472
- const tmp = makeTempDir("vg-prose-reject");
473
- try {
474
- writeFileSync(
475
- join(tmp, "package.json"),
476
- JSON.stringify({ scripts: { test: "vitest" } }),
477
- );
478
- const result = discoverCommands({
479
- taskPlanVerify: "Document exists, contains all 5 scale names, all 14 semantic tokens",
480
- cwd: tmp,
481
- });
482
- // Prose should be rejected, so it falls through to package.json
483
- assert.equal(result.source, "package-json");
484
- assert.deepStrictEqual(result.commands, ["npm run test"]);
485
- } finally {
486
- rmSync(tmp, { recursive: true, force: true });
487
- }
488
- });
489
-
490
- test("verification-gate: prose taskPlanVerify with no package.json → source none", () => {
491
- const tmp = makeTempDir("vg-prose-none");
492
- try {
493
- const result = discoverCommands({
494
- taskPlanVerify: "Verify the output matches expected format and all fields are present",
495
- cwd: tmp,
496
- });
497
- assert.equal(result.source, "none");
498
- assert.deepStrictEqual(result.commands, []);
499
- } finally {
500
- rmSync(tmp, { recursive: true, force: true });
501
- }
502
- });
503
-
504
- test("verification-gate: valid command in taskPlanVerify still works", () => {
505
- const tmp = makeTempDir("vg-valid-cmd");
506
- try {
507
- const result = discoverCommands({
508
- taskPlanVerify: "npm run lint && npm run test",
509
- cwd: tmp,
510
- });
511
- assert.equal(result.source, "task-plan");
512
- assert.deepStrictEqual(result.commands, ["npm run lint", "npm run test"]);
513
- } finally {
514
- rmSync(tmp, { recursive: true, force: true });
515
- }
516
- });
517
-
518
- test("verification-gate: mixed prose and commands in taskPlanVerify — only commands kept", () => {
519
- const tmp = makeTempDir("vg-mixed");
520
- try {
521
- const result = discoverCommands({
522
- taskPlanVerify: "Check that everything works && npm run test",
523
- cwd: tmp,
524
- });
525
- // "Check that everything works" is prose (starts with capital, 4+ words)
526
- // "npm run test" is a valid command
527
- assert.equal(result.source, "task-plan");
528
- assert.deepStrictEqual(result.commands, ["npm run test"]);
529
- } finally {
530
- rmSync(tmp, { recursive: true, force: true });
531
- }
532
- });
533
-
534
- // ─── Additional Execution Tests (T02) ───────────────────────────────────────
535
-
536
- test("verification-gate: one command fails — remaining commands still run (non-short-circuit)", () => {
537
- const tmp = makeTempDir("vg-no-short-circuit");
538
- try {
539
- // First fails, second and third should still execute
540
- const result = runVerificationGate({
541
- basePath: tmp,
542
- unitId: "T02",
543
- cwd: tmp,
544
- preferenceCommands: [
545
- "sh -c 'exit 1'",
546
- "echo second",
547
- "echo third",
548
- ],
549
- });
550
- assert.equal(result.passed, false);
551
- assert.equal(result.checks.length, 3, "all 3 commands should run");
552
- assert.equal(result.checks[0].exitCode, 1, "first command fails");
553
- assert.equal(result.checks[1].exitCode, 0, "second command runs and passes");
554
- assert.ok(result.checks[1].stdout.includes("second"));
555
- assert.equal(result.checks[2].exitCode, 0, "third command runs and passes");
556
- assert.ok(result.checks[2].stdout.includes("third"));
557
- } finally {
558
- rmSync(tmp, { recursive: true, force: true });
559
- }
560
- });
561
-
562
- test("verification-gate: gate execution uses cwd for spawnSync", () => {
563
- const tmp = makeTempDir("vg-cwd");
564
- try {
565
- // pwd should report the temp dir
566
- const result = runVerificationGate({
567
- basePath: tmp,
568
- unitId: "T02",
569
- cwd: tmp,
570
- preferenceCommands: ["pwd"],
571
- });
572
- assert.equal(result.passed, true);
573
- assert.equal(result.checks.length, 1);
574
- // The stdout should contain the tmp dir path (resolving symlinks)
575
- assert.ok(result.checks[0].stdout.trim().length > 0, "pwd should produce output");
576
- } finally {
577
- rmSync(tmp, { recursive: true, force: true });
578
- }
579
- });
580
-
581
474
  // ─── Additional Preference Validation Tests (T02) ──────────────────────────
582
475
 
583
476
  test("verification-gate: verification_commands produces no unknown-key warnings", () => {
@@ -0,0 +1,99 @@
1
+ /**
2
+ * windows-path-normalization.test.ts — Verify Windows backslash paths are
3
+ * normalised to forward slashes before embedding in bash command strings.
4
+ *
5
+ * Regression test for #1436: on Windows, `cd C:\Users\user\project` in bash
6
+ * strips backslashes (escape characters), producing `C:Usersuserproject`.
7
+ */
8
+
9
+ import { createTestContext } from "./test-helpers.ts";
10
+
11
+ const { assertEq, assertTrue, report } = createTestContext();
12
+
13
+ // ─── shellEscape + path normalization ──────────────────────────────────────
14
+
15
+ // Replicate the shellEscape helper from cmux/index.ts
16
+ function shellEscape(value: string): string {
17
+ return `'${value.replace(/'/g, `'\\''`)}'`;
18
+ }
19
+
20
+ // The bashPath pattern used in subagent/index.ts
21
+ function bashPath(p: string): string {
22
+ return shellEscape(p.replaceAll("\\", "/"));
23
+ }
24
+
25
+ console.log("\n=== Windows backslash path normalization (#1436) ===");
26
+
27
+ // Backslash paths are converted to forward slashes
28
+ assertEq(
29
+ bashPath("C:\\Users\\user\\project"),
30
+ "'C:/Users/user/project'",
31
+ "backslash path normalised to forward slashes in shell-escaped string",
32
+ );
33
+
34
+ // Unix paths pass through unchanged
35
+ assertEq(
36
+ bashPath("/home/user/project"),
37
+ "'/home/user/project'",
38
+ "Unix path unchanged",
39
+ );
40
+
41
+ // Mixed separators are normalised
42
+ assertEq(
43
+ bashPath("C:\\Users/user\\project/src"),
44
+ "'C:/Users/user/project/src'",
45
+ "mixed separators normalised",
46
+ );
47
+
48
+ // Paths with single quotes are still properly escaped
49
+ assertEq(
50
+ bashPath("C:\\Users\\o'brien\\project"),
51
+ "'C:/Users/o'\\''brien/project'",
52
+ "single quote in path is escaped after normalisation",
53
+ );
54
+
55
+ // UNC paths
56
+ assertEq(
57
+ bashPath("\\\\server\\share\\dir"),
58
+ "'//server/share/dir'",
59
+ "UNC path normalised",
60
+ );
61
+
62
+ // Empty string
63
+ assertEq(
64
+ bashPath(""),
65
+ "''",
66
+ "empty string handled",
67
+ );
68
+
69
+ // ─── cd command construction ───────────────────────────────────────────────
70
+
71
+ console.log("\n=== cd command construction with normalised paths ===");
72
+
73
+ const windowsCwd = "C:\\Users\\user\\project\\.gsd\\worktrees\\M001";
74
+ const cdCommand = `cd ${bashPath(windowsCwd)}`;
75
+ assertEq(
76
+ cdCommand,
77
+ "cd 'C:/Users/user/project/.gsd/worktrees/M001'",
78
+ "cd command uses forward slashes for Windows worktree path",
79
+ );
80
+
81
+ // Verify the mangled form from #1436 is NOT produced
82
+ assertTrue(
83
+ !cdCommand.includes("C:Users"),
84
+ "mangled path C:Usersuserproject must not appear",
85
+ );
86
+
87
+ // ─── Worktree teardown orphan detection ────────────────────────────────────
88
+
89
+ console.log("\n=== teardown orphan warning path formatting ===");
90
+
91
+ const windowsWtDir = "C:\\Users\\user\\project\\.gsd\\worktrees\\M001";
92
+ const helpCommand = `rm -rf "${windowsWtDir.replaceAll("\\", "/")}"`;
93
+ assertEq(
94
+ helpCommand,
95
+ 'rm -rf "C:/Users/user/project/.gsd/worktrees/M001"',
96
+ "orphan cleanup help command uses forward slashes",
97
+ );
98
+
99
+ report();
@@ -138,6 +138,7 @@ async function main(): Promise<void> {
138
138
  choice: "reconcile on merge",
139
139
  rationale: "test coverage",
140
140
  revisable: "no",
141
+ made_by: 'agent',
141
142
  superseded_by: null,
142
143
  });
143
144
  closeDatabase();
@@ -47,6 +47,7 @@ function seedMainDb(dbPath: string): void {
47
47
  choice: 'node:sqlite',
48
48
  rationale: 'Built-in',
49
49
  revisable: 'yes',
50
+ made_by: 'agent',
50
51
  superseded_by: null,
51
52
  });
52
53
  insertRequirement({
@@ -182,6 +183,7 @@ console.log('\n=== worktree-db: reconcileWorktreeDb ===');
182
183
  choice: 'WAL',
183
184
  rationale: 'Performance',
184
185
  revisable: 'yes',
186
+ made_by: 'agent',
185
187
  superseded_by: null,
186
188
  });
187
189
  closeDatabase();
@@ -357,6 +359,7 @@ console.log('\n=== worktree-db: reconcileWorktreeDb ===');
357
359
  choice: 'yes',
358
360
  rationale: 'Robustness',
359
361
  revisable: 'no',
362
+ made_by: 'agent',
360
363
  superseded_by: null,
361
364
  });
362
365
  closeDatabase();
@@ -395,6 +398,7 @@ console.log('\n=== worktree-db: reconcileWorktreeDb ===');
395
398
  choice: 'works',
396
399
  rationale: 'Verify DETACH cleanup',
397
400
  revisable: 'no',
401
+ made_by: 'agent',
398
402
  superseded_by: null,
399
403
  });
400
404