gsd-pi 2.41.0 → 2.42.0-dev.1df898f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (494) hide show
  1. package/README.md +92 -29
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/cli.js +18 -3
  5. package/dist/loader.js +3 -1
  6. package/dist/onboarding.js +2 -1
  7. package/dist/resource-loader.js +39 -6
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  9. package/dist/resources/extensions/async-jobs/await-tool.js +5 -0
  10. package/dist/resources/extensions/async-jobs/index.js +2 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  12. package/dist/resources/extensions/gsd/auto/phases.js +29 -13
  13. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  17. package/dist/resources/extensions/gsd/auto-prompts.js +3 -16
  18. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  19. package/dist/resources/extensions/gsd/auto-start.js +16 -14
  20. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  21. package/dist/resources/extensions/gsd/auto.js +64 -2
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  23. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  31. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  32. package/dist/resources/extensions/gsd/context-store.js +4 -3
  33. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  34. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  35. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  37. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  38. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  39. package/dist/resources/extensions/gsd/detection.js +20 -1
  40. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  41. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  42. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  43. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  44. package/dist/resources/extensions/gsd/doctor.js +11 -1
  45. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  46. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  47. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  48. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  49. package/dist/resources/extensions/gsd/export.js +9 -13
  50. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  51. package/dist/resources/extensions/gsd/files.js +28 -11
  52. package/dist/resources/extensions/gsd/forensics.js +94 -3
  53. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  54. package/dist/resources/extensions/gsd/git-service.js +6 -2
  55. package/dist/resources/extensions/gsd/graph.js +225 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  59. package/dist/resources/extensions/gsd/journal.js +85 -0
  60. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  61. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  62. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  63. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  64. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  65. package/dist/resources/extensions/gsd/preferences.js +60 -8
  66. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  67. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  71. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  72. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  73. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  74. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  75. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  76. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  77. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  78. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  79. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  80. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  81. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  82. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  83. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  84. package/dist/resources/extensions/gsd/worktree.js +2 -2
  85. package/dist/resources/extensions/mcp-client/index.js +2 -1
  86. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  87. package/dist/resources/extensions/subagent/index.js +7 -3
  88. package/dist/resources/extensions/voice/index.js +4 -4
  89. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  90. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  91. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  92. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  93. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  94. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  95. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  96. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  97. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  98. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  101. package/dist/web/standalone/.next/build-manifest.json +4 -4
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  104. package/dist/web/standalone/.next/required-server-files.json +3 -3
  105. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  108. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  116. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  170. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  176. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/page.js +2 -2
  211. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  213. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  214. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  215. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/middleware.js +2 -2
  218. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  220. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  221. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  222. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  223. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  224. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  228. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  230. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  231. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  232. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  233. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  234. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  235. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  236. package/dist/web/standalone/server.js +1 -1
  237. package/dist/web-mode.d.ts +4 -0
  238. package/dist/web-mode.js +69 -11
  239. package/package.json +1 -1
  240. package/packages/native/src/__tests__/text.test.mjs +33 -0
  241. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/agent.js +2 -0
  243. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  244. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  245. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  246. package/packages/pi-agent-core/dist/types.js.map +1 -1
  247. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  248. package/packages/pi-agent-core/src/agent.ts +3 -0
  249. package/packages/pi-agent-core/src/types.ts +6 -0
  250. package/packages/pi-agent-core/tsconfig.json +1 -1
  251. package/packages/pi-ai/dist/models.d.ts +5 -3
  252. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  253. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  254. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  256. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  257. package/packages/pi-ai/dist/models.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  261. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  262. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  263. package/packages/pi-ai/src/models.ts +7 -4
  264. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  273. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  275. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  278. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  281. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  284. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  286. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  288. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  290. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  292. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  295. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  307. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  308. package/packages/pi-coding-agent/package.json +1 -1
  309. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  310. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  311. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  312. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  313. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  314. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  315. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  316. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  317. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  318. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  319. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  320. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  321. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  322. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  323. package/pkg/package.json +1 -1
  324. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  325. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  326. package/src/resources/extensions/async-jobs/await-tool.test.ts +47 -0
  327. package/src/resources/extensions/async-jobs/await-tool.ts +5 -0
  328. package/src/resources/extensions/async-jobs/index.ts +1 -0
  329. package/src/resources/extensions/async-jobs/job-manager.ts +2 -0
  330. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -2
  331. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  332. package/src/resources/extensions/gsd/auto/phases.ts +31 -13
  333. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  334. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  335. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  336. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  337. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  338. package/src/resources/extensions/gsd/auto-prompts.ts +2 -18
  339. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  340. package/src/resources/extensions/gsd/auto-start.ts +15 -13
  341. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  342. package/src/resources/extensions/gsd/auto.ts +71 -2
  343. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  344. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  345. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  347. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  348. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  349. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  350. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  351. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  352. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  353. package/src/resources/extensions/gsd/context-store.ts +4 -3
  354. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  355. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  356. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  357. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  358. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  359. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  360. package/src/resources/extensions/gsd/detection.ts +20 -1
  361. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  362. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  363. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  364. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  365. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  366. package/src/resources/extensions/gsd/doctor.ts +12 -1
  367. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  368. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  369. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  370. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  371. package/src/resources/extensions/gsd/export.ts +8 -15
  372. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  373. package/src/resources/extensions/gsd/files.ts +29 -12
  374. package/src/resources/extensions/gsd/forensics.ts +101 -3
  375. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  376. package/src/resources/extensions/gsd/git-service.ts +5 -5
  377. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  378. package/src/resources/extensions/gsd/graph.ts +312 -0
  379. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  380. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  381. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  382. package/src/resources/extensions/gsd/journal.ts +134 -0
  383. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  384. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  385. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  386. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  387. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  388. package/src/resources/extensions/gsd/preferences.ts +63 -6
  389. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  390. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  391. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  392. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  393. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  394. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  395. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  396. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  397. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  398. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  399. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  400. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  401. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  402. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  403. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  404. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  405. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  406. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  407. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  408. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  409. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  410. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  411. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  412. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  413. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  414. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  415. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  416. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  417. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  419. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  420. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  421. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  422. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  423. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  424. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  425. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  426. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  427. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  428. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  429. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  430. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  431. package/src/resources/extensions/gsd/tests/git-service.test.ts +44 -0
  432. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  433. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  434. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  435. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  436. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  437. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  438. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  439. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  440. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  441. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  442. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  443. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  444. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  445. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  446. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  447. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  448. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  449. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  451. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +56 -3
  452. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  453. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  454. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  455. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  456. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  457. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  458. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  459. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  460. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  461. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  462. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  463. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  464. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +79 -5
  466. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  468. package/src/resources/extensions/gsd/types.ts +3 -0
  469. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  470. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  471. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  472. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -12
  473. package/src/resources/extensions/gsd/worktree.ts +2 -2
  474. package/src/resources/extensions/mcp-client/index.ts +5 -1
  475. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  476. package/src/resources/extensions/subagent/index.ts +7 -3
  477. package/src/resources/extensions/voice/index.ts +4 -4
  478. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  479. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  480. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  481. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  482. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  483. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  484. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  485. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  486. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  487. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  488. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  489. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  490. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  491. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  492. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  493. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_buildManifest.js +0 -0
  494. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_ssgManifest.js +0 -0
@@ -0,0 +1,117 @@
1
+ // tool-naming — Verifies canonical + alias tool registration for GSD DB tools.
2
+ //
3
+ // Each of the 4 DB tools must register under its canonical gsd_concept_action name
4
+ // AND under the old gsd_action_concept name as a backward-compatible alias.
5
+ // The alias must share the exact same execute function reference as the canonical tool.
6
+
7
+ import { createTestContext } from './test-helpers.ts';
8
+ import { registerDbTools } from '../bootstrap/db-tools.ts';
9
+
10
+ const { assertEq, assertTrue, report } = createTestContext();
11
+
12
+ // ─── Mock PI ──────────────────────────────────────────────────────────────────
13
+
14
+ function makeMockPi() {
15
+ const tools: any[] = [];
16
+ return {
17
+ registerTool: (tool: any) => tools.push(tool),
18
+ tools,
19
+ } as any;
20
+ }
21
+
22
+ // ─── Rename map ───────────────────────────────────────────────────────────────
23
+
24
+ const RENAME_MAP: Array<{ canonical: string; alias: string }> = [
25
+ { canonical: "gsd_decision_save", alias: "gsd_save_decision" },
26
+ { canonical: "gsd_requirement_update", alias: "gsd_update_requirement" },
27
+ { canonical: "gsd_summary_save", alias: "gsd_save_summary" },
28
+ { canonical: "gsd_milestone_generate_id", alias: "gsd_generate_milestone_id" },
29
+ ];
30
+
31
+ // ─── Registration count ──────────────────────────────────────────────────────
32
+
33
+ console.log('\n── Tool naming: registration count ──');
34
+
35
+ const pi = makeMockPi();
36
+ registerDbTools(pi);
37
+
38
+ assertEq(pi.tools.length, 8, 'Should register exactly 8 tools (4 canonical + 4 aliases)');
39
+
40
+ // ─── Both names exist for each pair ──────────────────────────────────────────
41
+
42
+ console.log('\n── Tool naming: canonical and alias names exist ──');
43
+
44
+ for (const { canonical, alias } of RENAME_MAP) {
45
+ const canonicalTool = pi.tools.find((t: any) => t.name === canonical);
46
+ const aliasTool = pi.tools.find((t: any) => t.name === alias);
47
+
48
+ assertTrue(canonicalTool !== undefined, `Canonical tool "${canonical}" should be registered`);
49
+ assertTrue(aliasTool !== undefined, `Alias tool "${alias}" should be registered`);
50
+ }
51
+
52
+ // ─── Execute function identity ───────────────────────────────────────────────
53
+
54
+ console.log('\n── Tool naming: execute function identity (===) ──');
55
+
56
+ for (const { canonical, alias } of RENAME_MAP) {
57
+ const canonicalTool = pi.tools.find((t: any) => t.name === canonical);
58
+ const aliasTool = pi.tools.find((t: any) => t.name === alias);
59
+
60
+ if (canonicalTool && aliasTool) {
61
+ assertTrue(
62
+ canonicalTool.execute === aliasTool.execute,
63
+ `"${canonical}" and "${alias}" should share the same execute function reference`,
64
+ );
65
+ }
66
+ }
67
+
68
+ // ─── Alias descriptions include "(alias for ...)" ───────────────────────────
69
+
70
+ console.log('\n── Tool naming: alias descriptions ──');
71
+
72
+ for (const { canonical, alias } of RENAME_MAP) {
73
+ const aliasTool = pi.tools.find((t: any) => t.name === alias);
74
+
75
+ if (aliasTool) {
76
+ assertTrue(
77
+ aliasTool.description.includes(`alias for ${canonical}`),
78
+ `Alias "${alias}" description should include "alias for ${canonical}"`,
79
+ );
80
+ }
81
+ }
82
+
83
+ // ─── Canonical tools have proper promptGuidelines ────────────────────────────
84
+
85
+ console.log('\n── Tool naming: canonical promptGuidelines use canonical name ──');
86
+
87
+ for (const { canonical } of RENAME_MAP) {
88
+ const canonicalTool = pi.tools.find((t: any) => t.name === canonical);
89
+
90
+ if (canonicalTool) {
91
+ const guidelinesText = canonicalTool.promptGuidelines.join(' ');
92
+ assertTrue(
93
+ guidelinesText.includes(canonical),
94
+ `Canonical tool "${canonical}" promptGuidelines should reference its own name`,
95
+ );
96
+ }
97
+ }
98
+
99
+ // ─── Alias promptGuidelines direct to canonical ──────────────────────────────
100
+
101
+ console.log('\n── Tool naming: alias promptGuidelines redirect to canonical ──');
102
+
103
+ for (const { canonical, alias } of RENAME_MAP) {
104
+ const aliasTool = pi.tools.find((t: any) => t.name === alias);
105
+
106
+ if (aliasTool) {
107
+ const guidelinesText = aliasTool.promptGuidelines.join(' ');
108
+ assertTrue(
109
+ guidelinesText.includes(`Alias for ${canonical}`),
110
+ `Alias "${alias}" promptGuidelines should say "Alias for ${canonical}"`,
111
+ );
112
+ }
113
+ }
114
+
115
+ // ═══════════════════════════════════════════════════════════════════════════
116
+
117
+ report();
@@ -15,6 +15,7 @@ import { fileURLToPath } from "node:url";
15
15
 
16
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
17
  const hooksPath = join(__dirname, "..", "post-unit-hooks.ts");
18
+ const registryPath = join(__dirname, "..", "rule-registry.ts");
18
19
  const autoPromptsPath = join(__dirname, "..", "auto-prompts.ts");
19
20
 
20
21
  // After decomposition, triage/dispatch logic lives in auto-post-unit.ts
@@ -25,7 +26,11 @@ const autoSrc = [
25
26
  postUnitSrc,
26
27
  readFileSync(join(__dirname, "..", "auto-start.ts"), "utf-8"),
27
28
  ].join("\n");
28
- const hooksSrc = readFileSync(hooksPath, "utf-8");
29
+ // Hook exclusion logic lives in the rule-registry (facade delegates there)
30
+ const hooksSrc = [
31
+ readFileSync(hooksPath, "utf-8"),
32
+ readFileSync(registryPath, "utf-8"),
33
+ ].join("\n");
29
34
  const autoPromptsSrc = (() => { try { return readFileSync(autoPromptsPath, "utf-8"); } catch { return autoSrc; } })();
30
35
 
31
36
  // ─── Hook exclusion ──────────────────────────────────────────────────────────
@@ -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", () => {