gsd-pi 2.74.0-dev.2b524c3 → 2.74.0-dev.703eabc

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 (484) hide show
  1. package/dist/cli.js +85 -0
  2. package/dist/headless-query.js +4 -1
  3. package/dist/help-text.js +23 -0
  4. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  5. package/dist/resources/extensions/gsd/auto/detect-stuck.js +11 -4
  6. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  7. package/dist/resources/extensions/gsd/auto/phases.js +158 -4
  8. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
  10. package/dist/resources/extensions/gsd/auto-model-selection.js +51 -5
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +220 -17
  12. package/dist/resources/extensions/gsd/auto-prompts.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  14. package/dist/resources/extensions/gsd/auto-verification.js +100 -2
  15. package/dist/resources/extensions/gsd/auto.js +36 -4
  16. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +30 -8
  17. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +45 -4
  18. package/dist/resources/extensions/gsd/commands/catalog.js +26 -1
  19. package/dist/resources/extensions/gsd/commands/handlers/ops.js +25 -0
  20. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +68 -9
  21. package/dist/resources/extensions/gsd/commands-add-tests.js +111 -0
  22. package/dist/resources/extensions/gsd/commands-backlog.js +140 -0
  23. package/dist/resources/extensions/gsd/commands-do.js +79 -0
  24. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  25. package/dist/resources/extensions/gsd/commands-maintenance.js +6 -6
  26. package/dist/resources/extensions/gsd/commands-pr-branch.js +180 -0
  27. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  28. package/dist/resources/extensions/gsd/commands-session-report.js +82 -0
  29. package/dist/resources/extensions/gsd/commands-ship.js +187 -0
  30. package/dist/resources/extensions/gsd/db-writer.js +3 -5
  31. package/dist/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  32. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  33. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  34. package/dist/resources/extensions/gsd/git-service.js +49 -1
  35. package/dist/resources/extensions/gsd/graph-context.js +157 -0
  36. package/dist/resources/extensions/gsd/gsd-db.js +581 -2
  37. package/dist/resources/extensions/gsd/guided-flow.js +23 -0
  38. package/dist/resources/extensions/gsd/index.js +15 -2
  39. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  40. package/dist/resources/extensions/gsd/journal.js +27 -0
  41. package/dist/resources/extensions/gsd/md-importer.js +3 -4
  42. package/dist/resources/extensions/gsd/memory-store.js +19 -51
  43. package/dist/resources/extensions/gsd/metrics.js +19 -0
  44. package/dist/resources/extensions/gsd/milestone-validation-gates.js +13 -12
  45. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -4
  46. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  47. package/dist/resources/extensions/gsd/preferences-models.js +20 -3
  48. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  49. package/dist/resources/extensions/gsd/preferences-validation.js +108 -2
  50. package/dist/resources/extensions/gsd/preferences.js +26 -0
  51. package/dist/resources/extensions/gsd/prompts/add-tests.md +35 -0
  52. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  53. package/dist/resources/extensions/gsd/state.js +5 -1
  54. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  55. package/dist/resources/extensions/gsd/tools/complete-slice.js +20 -0
  56. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  57. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +3 -14
  58. package/dist/resources/extensions/gsd/triage-resolution.js +2 -5
  59. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  60. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  61. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  62. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  63. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  64. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  65. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  66. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  67. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  68. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  69. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  70. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  71. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  72. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -69
  73. package/dist/resources/extensions/gsd/workflow-migration.js +21 -22
  74. package/dist/resources/extensions/gsd/workflow-projections.js +4 -1
  75. package/dist/resources/extensions/gsd/workflow-reconcile.js +14 -11
  76. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  77. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  78. package/dist/web/standalone/.next/BUILD_ID +1 -1
  79. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  80. package/dist/web/standalone/.next/build-manifest.json +2 -2
  81. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  82. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  83. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  91. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  103. package/dist/web/standalone/.next/server/app/index.html +1 -1
  104. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  111. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  112. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  114. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  115. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  116. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  117. package/package.json +3 -2
  118. package/packages/daemon/package.json +2 -2
  119. package/packages/mcp-server/dist/index.d.ts +3 -0
  120. package/packages/mcp-server/dist/index.d.ts.map +1 -1
  121. package/packages/mcp-server/dist/index.js +3 -0
  122. package/packages/mcp-server/dist/index.js.map +1 -1
  123. package/packages/mcp-server/dist/readers/graph.d.ts +87 -0
  124. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -0
  125. package/packages/mcp-server/dist/readers/graph.js +655 -0
  126. package/packages/mcp-server/dist/readers/graph.js.map +1 -0
  127. package/packages/mcp-server/dist/readers/index.d.ts +2 -0
  128. package/packages/mcp-server/dist/readers/index.d.ts.map +1 -1
  129. package/packages/mcp-server/dist/readers/index.js +1 -0
  130. package/packages/mcp-server/dist/readers/index.js.map +1 -1
  131. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  132. package/packages/mcp-server/dist/server.js +65 -0
  133. package/packages/mcp-server/dist/server.js.map +1 -1
  134. package/packages/mcp-server/package.json +2 -2
  135. package/packages/mcp-server/src/index.ts +15 -0
  136. package/packages/mcp-server/src/readers/graph.test.ts +604 -0
  137. package/packages/mcp-server/src/readers/graph.ts +855 -0
  138. package/packages/mcp-server/src/readers/index.ts +12 -0
  139. package/packages/mcp-server/src/server.ts +83 -0
  140. package/packages/mcp-server/tsconfig.json +1 -0
  141. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -0
  142. package/packages/native/package.json +2 -2
  143. package/packages/native/tsconfig.tsbuildinfo +1 -0
  144. package/packages/pi-agent-core/package.json +1 -1
  145. package/packages/pi-agent-core/tsconfig.json +1 -0
  146. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -0
  147. package/packages/pi-ai/dist/index.d.ts +1 -9
  148. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  149. package/packages/pi-ai/dist/index.js +1 -9
  150. package/packages/pi-ai/dist/index.js.map +1 -1
  151. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  152. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  153. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  154. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  155. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  156. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  157. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  158. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  159. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  160. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  161. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  162. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  163. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  164. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  165. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  166. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  167. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  168. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  169. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  170. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  171. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  172. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  174. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  176. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  177. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  178. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  179. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  180. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  181. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  182. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  183. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  184. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  185. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  186. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  187. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  188. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  189. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  190. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  191. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  192. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  193. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  194. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  195. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  196. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  197. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  198. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  199. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  200. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  201. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  202. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  203. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  204. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  205. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  206. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  207. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  208. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  209. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  210. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  211. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  212. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  213. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  214. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  215. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  216. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  217. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  218. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  219. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  220. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  221. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  222. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  223. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  224. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  225. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  226. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  227. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  228. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  229. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  230. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  231. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  232. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  233. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  234. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  235. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  236. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  237. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  238. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  239. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  240. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  241. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  242. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  243. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  244. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  245. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  246. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  247. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  248. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  249. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  250. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  251. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  252. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  253. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  254. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  255. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  256. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  257. package/packages/pi-ai/dist/models/index.js +80 -0
  258. package/packages/pi-ai/dist/models/index.js.map +1 -0
  259. package/packages/pi-ai/dist/models.d.ts +1 -36
  260. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  262. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  263. package/packages/pi-ai/dist/models.js +3 -112
  264. package/packages/pi-ai/dist/models.js.map +1 -1
  265. package/packages/pi-ai/dist/models.test.js +6 -5
  266. package/packages/pi-ai/dist/models.test.js.map +1 -1
  267. package/packages/pi-ai/package.json +1 -1
  268. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  269. package/packages/pi-ai/src/index.ts +1 -9
  270. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  271. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  272. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  273. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  274. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  275. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  276. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  277. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  278. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  279. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  280. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  281. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  282. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  283. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  284. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  285. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  286. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  287. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  288. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  289. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  290. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  291. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  292. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  293. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  294. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  295. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  296. package/packages/pi-ai/src/models/index.ts +106 -0
  297. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  298. package/packages/pi-ai/src/models.test.ts +6 -5
  299. package/packages/pi-ai/src/models.ts +3 -153
  300. package/packages/pi-ai/tsconfig.json +1 -0
  301. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -0
  302. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  304. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
  306. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  308. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  310. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  313. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +51 -8
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
  332. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  335. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  336. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  337. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +13 -0
  338. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +53 -6
  340. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  341. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  342. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
  343. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  344. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  345. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  346. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  347. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
  348. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +66 -7
  349. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  350. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
  351. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  352. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +73 -6
  353. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  354. package/packages/pi-coding-agent/tsconfig.json +3 -2
  355. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -0
  356. package/packages/pi-tui/package.json +1 -1
  357. package/packages/pi-tui/tsconfig.json +1 -0
  358. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -0
  359. package/packages/rpc-client/package.json +1 -1
  360. package/packages/rpc-client/tsconfig.json +1 -0
  361. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -0
  362. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  363. package/src/resources/extensions/gsd/auto/detect-stuck.ts +12 -4
  364. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -0
  365. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  366. package/src/resources/extensions/gsd/auto/phases.ts +191 -4
  367. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  368. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
  369. package/src/resources/extensions/gsd/auto-model-selection.ts +66 -5
  370. package/src/resources/extensions/gsd/auto-post-unit.ts +238 -18
  371. package/src/resources/extensions/gsd/auto-prompts.ts +13 -0
  372. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  373. package/src/resources/extensions/gsd/auto-verification.ts +129 -2
  374. package/src/resources/extensions/gsd/auto.ts +41 -2
  375. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +38 -8
  376. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +56 -3
  377. package/src/resources/extensions/gsd/commands/catalog.ts +26 -1
  378. package/src/resources/extensions/gsd/commands/handlers/ops.ts +25 -0
  379. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +74 -9
  380. package/src/resources/extensions/gsd/commands-add-tests.ts +137 -0
  381. package/src/resources/extensions/gsd/commands-backlog.ts +182 -0
  382. package/src/resources/extensions/gsd/commands-do.ts +109 -0
  383. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  384. package/src/resources/extensions/gsd/commands-maintenance.ts +6 -6
  385. package/src/resources/extensions/gsd/commands-pr-branch.ts +234 -0
  386. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  387. package/src/resources/extensions/gsd/commands-session-report.ts +101 -0
  388. package/src/resources/extensions/gsd/commands-ship.ts +219 -0
  389. package/src/resources/extensions/gsd/db-writer.ts +3 -5
  390. package/src/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  391. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  392. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  393. package/src/resources/extensions/gsd/git-service.ts +68 -0
  394. package/src/resources/extensions/gsd/graph-context.ts +212 -0
  395. package/src/resources/extensions/gsd/gsd-db.ts +788 -3
  396. package/src/resources/extensions/gsd/guided-flow.ts +32 -0
  397. package/src/resources/extensions/gsd/index.ts +18 -2
  398. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  399. package/src/resources/extensions/gsd/journal.ts +30 -0
  400. package/src/resources/extensions/gsd/md-importer.ts +3 -5
  401. package/src/resources/extensions/gsd/memory-store.ts +31 -62
  402. package/src/resources/extensions/gsd/metrics.ts +26 -0
  403. package/src/resources/extensions/gsd/milestone-validation-gates.ts +13 -14
  404. package/src/resources/extensions/gsd/native-git-bridge.ts +11 -12
  405. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  406. package/src/resources/extensions/gsd/preferences-models.ts +20 -3
  407. package/src/resources/extensions/gsd/preferences-types.ts +32 -0
  408. package/src/resources/extensions/gsd/preferences-validation.ts +107 -2
  409. package/src/resources/extensions/gsd/preferences.ts +28 -0
  410. package/src/resources/extensions/gsd/prompts/add-tests.md +35 -0
  411. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  412. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  413. package/src/resources/extensions/gsd/state.ts +9 -2
  414. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  415. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
  416. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  417. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  418. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  419. package/src/resources/extensions/gsd/tests/commands-backlog.test.ts +158 -0
  420. package/src/resources/extensions/gsd/tests/commands-do.test.ts +127 -0
  421. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  422. package/src/resources/extensions/gsd/tests/commands-pr-branch.test.ts +68 -0
  423. package/src/resources/extensions/gsd/tests/commands-session-report.test.ts +82 -0
  424. package/src/resources/extensions/gsd/tests/commands-ship.test.ts +71 -0
  425. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +14 -0
  426. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  427. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  428. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +154 -0
  429. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  430. package/src/resources/extensions/gsd/tests/graph-context.test.ts +337 -0
  431. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  432. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  433. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +68 -1
  434. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  435. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  436. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +140 -0
  437. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  438. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  439. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  440. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  441. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +180 -0
  442. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  443. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  444. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  445. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  446. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  447. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  448. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  449. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  450. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  451. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  452. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  453. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  454. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +223 -0
  455. package/src/resources/extensions/gsd/tools/complete-slice.ts +26 -0
  456. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  457. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +3 -11
  458. package/src/resources/extensions/gsd/triage-resolution.ts +2 -7
  459. package/src/resources/extensions/gsd/types.ts +14 -1
  460. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  461. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  462. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  463. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  464. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  465. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  466. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  467. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  468. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  469. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  470. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  471. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  472. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  473. package/src/resources/extensions/gsd/workflow-manifest.ts +9 -104
  474. package/src/resources/extensions/gsd/workflow-migration.ts +21 -29
  475. package/src/resources/extensions/gsd/workflow-projections.ts +8 -1
  476. package/src/resources/extensions/gsd/workflow-reconcile.ts +15 -15
  477. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  478. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  479. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  480. package/packages/pi-ai/dist/models.generated.js +0 -14343
  481. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  482. package/packages/pi-ai/src/models.generated.ts +0 -14345
  483. /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → 3U-oZ5FT59BM7sm2GInic}/_buildManifest.js +0 -0
  484. /package/dist/web/standalone/.next/static/{YzIEI9sxJy4t5xgClF08g → 3U-oZ5FT59BM7sm2GInic}/_ssgManifest.js +0 -0
@@ -0,0 +1,167 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { join, dirname } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { fileURLToPath } from "node:url";
7
+
8
+ import {
9
+ closeDatabase,
10
+ insertMilestone,
11
+ insertSlice,
12
+ insertTask,
13
+ openDatabase,
14
+ } from "../gsd-db.ts";
15
+ import type { GSDState, Phase } from "../types.ts";
16
+ import { ensurePlanV2Graph } from "../uok/plan-v2.ts";
17
+
18
+ const __dirname = dirname(fileURLToPath(import.meta.url));
19
+ const gsdDir = join(__dirname, "..");
20
+ const MILESTONE_ID = "M001";
21
+ const SLICE_ID = "S01";
22
+ const TASK_ID = "T01";
23
+ const tempDirs = new Set<string>();
24
+
25
+ function createBasePath(): string {
26
+ const basePath = mkdtempSync(join(tmpdir(), "gsd-uok-planv2-"));
27
+ mkdirSync(join(basePath, ".gsd", "milestones", MILESTONE_ID), { recursive: true });
28
+ tempDirs.add(basePath);
29
+ return basePath;
30
+ }
31
+
32
+ function writeMilestoneFile(basePath: string, suffix: string, content: string): void {
33
+ const milestoneDir = join(basePath, ".gsd", "milestones", MILESTONE_ID);
34
+ mkdirSync(milestoneDir, { recursive: true });
35
+ writeFileSync(join(milestoneDir, `${MILESTONE_ID}-${suffix}.md`), `${content}\n`, "utf-8");
36
+ }
37
+
38
+ function writeSliceFile(basePath: string, suffix: string, content: string): void {
39
+ const sliceDir = join(basePath, ".gsd", "milestones", MILESTONE_ID, "slices", SLICE_ID);
40
+ mkdirSync(sliceDir, { recursive: true });
41
+ writeFileSync(join(sliceDir, `${SLICE_ID}-${suffix}.md`), `${content}\n`, "utf-8");
42
+ }
43
+
44
+ function seedGraphRows(): void {
45
+ insertMilestone({ id: MILESTONE_ID, title: "Milestone", status: "active" });
46
+ insertSlice({
47
+ id: SLICE_ID,
48
+ milestoneId: MILESTONE_ID,
49
+ title: "Slice",
50
+ status: "in_progress",
51
+ sequence: 1,
52
+ });
53
+ insertTask({
54
+ id: TASK_ID,
55
+ milestoneId: MILESTONE_ID,
56
+ sliceId: SLICE_ID,
57
+ title: "Task",
58
+ status: "pending",
59
+ keyFiles: ["src/task.ts"],
60
+ sequence: 1,
61
+ });
62
+ }
63
+
64
+ function buildState(phase: Phase): GSDState {
65
+ return {
66
+ phase,
67
+ activeMilestone: { id: MILESTONE_ID, title: "Milestone" },
68
+ activeSlice: null,
69
+ activeTask: null,
70
+ recentDecisions: [],
71
+ blockers: [],
72
+ nextAction: "dispatch",
73
+ registry: [],
74
+ };
75
+ }
76
+
77
+ test.beforeEach(() => {
78
+ closeDatabase();
79
+ const opened = openDatabase(":memory:");
80
+ assert.equal(opened, true);
81
+ });
82
+
83
+ test.afterEach(() => {
84
+ closeDatabase();
85
+ for (const path of tempDirs) {
86
+ rmSync(path, { recursive: true, force: true });
87
+ }
88
+ tempDirs.clear();
89
+ });
90
+
91
+ test("guided flow enforces plan-v2 gate before execution-oriented dispatch", () => {
92
+ const source = readFileSync(join(gsdDir, "guided-flow.ts"), "utf-8");
93
+ assert.ok(
94
+ source.includes("needsPlanV2Gate") &&
95
+ source.includes("ensurePlanV2Graph") &&
96
+ source.includes("Plan gate failed-closed"),
97
+ "guided flow should fail-closed when plan-v2 graph compilation fails",
98
+ );
99
+ });
100
+
101
+ test("plan-v2 gate fails closed for execution phase when finalized context is missing", () => {
102
+ const basePath = createBasePath();
103
+ seedGraphRows();
104
+
105
+ writeMilestoneFile(basePath, "CONTEXT-DRAFT", "Draft context only.");
106
+
107
+ const compiled = ensurePlanV2Graph(basePath, buildState("executing"));
108
+ assert.equal(compiled.ok, false);
109
+ assert.match(compiled.reason ?? "", /CONTEXT\.md/i);
110
+ });
111
+
112
+ test("plan-v2 compiler writes pipeline metadata for clarify/research/draft stages", () => {
113
+ const basePath = createBasePath();
114
+ seedGraphRows();
115
+
116
+ writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
117
+ writeMilestoneFile(basePath, "CONTEXT-DRAFT", "Draft context retained.");
118
+ writeMilestoneFile(basePath, "RESEARCH", "Milestone research synthesis.");
119
+ writeSliceFile(basePath, "RESEARCH", "Slice research detail.");
120
+
121
+ const compiled = ensurePlanV2Graph(basePath, buildState("executing"));
122
+ assert.equal(compiled.ok, true);
123
+ assert.equal(compiled.clarifyRoundLimit, 3);
124
+ assert.equal(compiled.researchSynthesized, true);
125
+ assert.equal(compiled.draftContextIncluded, true);
126
+ assert.equal(compiled.finalizedContextIncluded, true);
127
+
128
+ const graphPath = compiled.graphPath ?? "";
129
+ const graphRaw = readFileSync(graphPath, "utf-8");
130
+ const graph = JSON.parse(graphRaw) as {
131
+ pipeline?: Record<string, unknown>;
132
+ nodes?: unknown[];
133
+ };
134
+
135
+ assert.equal(graph.pipeline?.["clarifyRoundLimit"], 3);
136
+ assert.equal(graph.pipeline?.["researchSynthesized"], true);
137
+ assert.equal(graph.pipeline?.["draftContextIncluded"], true);
138
+ assert.equal(graph.pipeline?.["finalizedContextIncluded"], true);
139
+ assert.equal(Array.isArray(graph.nodes), true);
140
+ });
141
+
142
+ test("plan-v2 graph may compile during planning even without finalized context", () => {
143
+ const basePath = createBasePath();
144
+ seedGraphRows();
145
+
146
+ writeMilestoneFile(basePath, "CONTEXT-DRAFT", "Planning draft context.");
147
+ const compiled = ensurePlanV2Graph(basePath, buildState("planning"));
148
+ assert.equal(compiled.ok, true);
149
+ });
150
+
151
+ test("plan-v2 ensure rejects empty executable graph", () => {
152
+ const basePath = createBasePath();
153
+ writeMilestoneFile(basePath, "CONTEXT", "Finalized context.");
154
+
155
+ insertMilestone({ id: MILESTONE_ID, title: "Milestone", status: "active" });
156
+ insertSlice({
157
+ id: SLICE_ID,
158
+ milestoneId: MILESTONE_ID,
159
+ title: "Slice",
160
+ status: "pending",
161
+ sequence: 1,
162
+ });
163
+
164
+ const compiled = ensurePlanV2Graph(basePath, buildState("executing"));
165
+ assert.equal(compiled.ok, false);
166
+ assert.match(compiled.reason ?? "", /compiled graph is empty/i);
167
+ });
@@ -0,0 +1,42 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+
4
+ import { validatePreferences } from "../preferences-validation.ts";
5
+
6
+ test("uok preferences validate nested flags and turn_action", () => {
7
+ const input = {
8
+ uok: {
9
+ enabled: true,
10
+ legacy_fallback: { enabled: false },
11
+ gates: { enabled: true },
12
+ model_policy: { enabled: true },
13
+ execution_graph: { enabled: false },
14
+ gitops: {
15
+ enabled: true,
16
+ turn_action: "status-only",
17
+ turn_push: false,
18
+ },
19
+ audit_unified: { enabled: true },
20
+ plan_v2: { enabled: true },
21
+ },
22
+ };
23
+
24
+ const result = validatePreferences(input as never);
25
+ assert.equal(result.errors.length, 0);
26
+ assert.equal(result.preferences.uok?.enabled, true);
27
+ assert.equal(result.preferences.uok?.legacy_fallback?.enabled, false);
28
+ assert.equal(result.preferences.uok?.gitops?.turn_action, "status-only");
29
+ assert.equal(result.preferences.uok?.plan_v2?.enabled, true);
30
+ });
31
+
32
+ test("uok preferences reject invalid turn_action", () => {
33
+ const result = validatePreferences({
34
+ uok: {
35
+ gitops: {
36
+ turn_action: "push-everything",
37
+ },
38
+ },
39
+ } as never);
40
+
41
+ assert.ok(result.errors.some((e) => e.includes("uok.gitops.turn_action")));
42
+ });
@@ -112,4 +112,43 @@ describe("handleValidateMilestone write ordering (#2725)", () => {
112
112
  ).get();
113
113
  assert.equal(row, undefined, "assessment row should be deleted after disk-write rollback");
114
114
  });
115
+
116
+ it("persists milestone validation gate_runs rows when UOK gates are enabled", async () => {
117
+ base = makeTmpBase();
118
+ const dbPath = join(base, ".gsd", "gsd.db");
119
+ openDatabase(dbPath);
120
+ insertMilestone({ id: "M001" });
121
+ insertSlice({ id: "S01", milestoneId: "M001" });
122
+
123
+ const result = await handleValidateMilestone(VALID_PARAMS, base, {
124
+ uokGatesEnabled: true,
125
+ traceId: "trace-val-1",
126
+ turnId: "turn-val-1",
127
+ });
128
+ assert.ok(!("error" in result), `unexpected error: ${"error" in result ? result.error : ""}`);
129
+
130
+ const adapter = _getAdapter()!;
131
+ const row = adapter.prepare(
132
+ `SELECT gate_id, outcome, failure_class, trace_id, turn_id
133
+ FROM gate_runs
134
+ WHERE gate_id = 'milestone-validation-gates'
135
+ ORDER BY id DESC
136
+ LIMIT 1`,
137
+ ).get() as
138
+ | {
139
+ gate_id: string;
140
+ outcome: string;
141
+ failure_class: string;
142
+ trace_id: string;
143
+ turn_id: string;
144
+ }
145
+ | undefined;
146
+
147
+ assert.ok(row, "milestone validation gate row should be persisted");
148
+ assert.equal(row?.gate_id, "milestone-validation-gates");
149
+ assert.equal(row?.outcome, "pass");
150
+ assert.equal(row?.failure_class, "none");
151
+ assert.equal(row?.trace_id, "trace-val-1");
152
+ assert.equal(row?.turn_id, "turn-val-1");
153
+ });
115
154
  });
@@ -0,0 +1,223 @@
1
+ // GSD Extension — workflow-logger wiring regression tests
2
+ //
3
+ // Verifies the plumbing between workflow-logger and the rest of the state
4
+ // system (auto-loop phases, detect-stuck, notification store). Without this
5
+ // wiring, warnings/errors logged during a unit leak across units, never
6
+ // reach the user as a consolidated post-unit alert, and don't enrich
7
+ // stuck-detection reasons.
8
+
9
+ import test from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { readFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+
14
+ import {
15
+ logWarning,
16
+ logError,
17
+ peekLogs,
18
+ _resetLogs,
19
+ setStderrLoggingEnabled,
20
+ } from "../workflow-logger.ts";
21
+ import { detectStuck } from "../auto/detect-stuck.ts";
22
+
23
+ const phasesSrc = readFileSync(
24
+ join(import.meta.dirname, "..", "auto", "phases.ts"),
25
+ "utf-8",
26
+ );
27
+ const autoSrc = readFileSync(
28
+ join(import.meta.dirname, "..", "auto.ts"),
29
+ "utf-8",
30
+ );
31
+
32
+ // ─── Source-scan: phases.ts calls the logger lifecycle API ─────────────────
33
+
34
+ test("auto/phases.ts imports _resetLogs, drainAndSummarize, formatForNotification, hasAnyIssues", () => {
35
+ assert.match(
36
+ phasesSrc,
37
+ /from\s+"\.\.\/workflow-logger\.js"/,
38
+ "phases.ts imports from workflow-logger",
39
+ );
40
+ for (const name of [
41
+ "_resetLogs",
42
+ "drainLogs",
43
+ "drainAndSummarize",
44
+ "formatForNotification",
45
+ "hasAnyIssues",
46
+ ]) {
47
+ assert.ok(
48
+ phasesSrc.includes(name),
49
+ `phases.ts should reference ${name}`,
50
+ );
51
+ }
52
+ });
53
+
54
+ test("runUnitPhase calls _resetLogs() before assigning s.currentUnit", () => {
55
+ // Find the "s.currentUnit = { type: unitType" assignment line and check
56
+ // the preceding ~500 chars contain a _resetLogs() call.
57
+ const idx = phasesSrc.indexOf("s.currentUnit = { type: unitType");
58
+ assert.ok(idx > 0, "runUnitPhase should assign s.currentUnit");
59
+ const before = phasesSrc.slice(Math.max(0, idx - 500), idx);
60
+ assert.match(
61
+ before,
62
+ /_resetLogs\(\)/,
63
+ "_resetLogs() must be called immediately before s.currentUnit assignment",
64
+ );
65
+ });
66
+
67
+ test("runFinalize drains and surfaces logger buffer via ctx.ui.notify", () => {
68
+ // Locate the runFinalize success path and verify it calls drainAndSummarize
69
+ // and routes the result through ctx.ui.notify.
70
+ const runFinalizeIdx = phasesSrc.indexOf("export async function runFinalize");
71
+ assert.ok(runFinalizeIdx > 0, "runFinalize export should exist");
72
+ const finalizeBody = phasesSrc.slice(runFinalizeIdx);
73
+ assert.match(
74
+ finalizeBody,
75
+ /hasAnyIssues\(\)/,
76
+ "runFinalize should gate drain on hasAnyIssues",
77
+ );
78
+ assert.match(
79
+ finalizeBody,
80
+ /drainAndSummarize\(\)/,
81
+ "runFinalize should call drainAndSummarize on success",
82
+ );
83
+ assert.match(
84
+ finalizeBody,
85
+ /formatForNotification\(logs\)/,
86
+ "runFinalize should format drained logs for the notification",
87
+ );
88
+ });
89
+
90
+ test("runFinalize timeout branches drain the buffer to prevent bleed", () => {
91
+ // Both timeout branches null out s.currentUnit — they should also drain
92
+ // so accumulated logs for the timed-out unit don't leak into the next.
93
+ const runFinalizeIdx = phasesSrc.indexOf("export async function runFinalize");
94
+ const finalizeBody = phasesSrc.slice(runFinalizeIdx);
95
+ const drainCallCount =
96
+ (finalizeBody.match(/drainLogs\(\)/g) ?? []).length;
97
+ assert.ok(
98
+ drainCallCount >= 2,
99
+ `runFinalize timeout branches should each call drainLogs() (found ${drainCallCount}, expected >= 2)`,
100
+ );
101
+ });
102
+
103
+ // ─── Source-scan: auto.ts calls setLogBasePath in startAuto ────────────────
104
+
105
+ test("startAuto calls setLogBasePath(base) so audit log is pinned on resume", () => {
106
+ const startAutoIdx = autoSrc.indexOf("export async function startAuto");
107
+ assert.ok(startAutoIdx > 0, "startAuto export should exist");
108
+ const body = autoSrc.slice(startAutoIdx);
109
+ assert.match(
110
+ body,
111
+ /setLogBasePath\(base\)/,
112
+ "startAuto must call setLogBasePath(base) to pin the audit log",
113
+ );
114
+ });
115
+
116
+ // ─── Runtime: detect-stuck enriches reason with summarizeLogs() ────────────
117
+
118
+ test("detectStuck reason includes workflow-logger summary when logs present", () => {
119
+ setStderrLoggingEnabled(false);
120
+ try {
121
+ _resetLogs();
122
+ logWarning("projection", "STATE.md render failed");
123
+ logError("db", "WAL checkpoint failed");
124
+
125
+ const result = detectStuck([
126
+ { key: "execute-task/slice-A/task-1", error: "ENOENT: no such file" },
127
+ { key: "execute-task/slice-A/task-1", error: "ENOENT: no such file" },
128
+ ]);
129
+
130
+ assert.notEqual(result, null);
131
+ assert.equal(result!.stuck, true);
132
+ assert.match(
133
+ result!.reason,
134
+ /Same error repeated:/,
135
+ "reason should still start with the rule string",
136
+ );
137
+ assert.match(
138
+ result!.reason,
139
+ /STATE\.md render failed/,
140
+ "reason should include the accumulated logger warning",
141
+ );
142
+ assert.match(
143
+ result!.reason,
144
+ /WAL checkpoint failed/,
145
+ "reason should include the accumulated logger error",
146
+ );
147
+
148
+ // Critical: summarizeLogs must not drain — the auto-loop's finalize
149
+ // step owns the buffer lifecycle, detect-stuck is read-only.
150
+ assert.equal(
151
+ peekLogs().length,
152
+ 2,
153
+ "detect-stuck must not drain the buffer",
154
+ );
155
+ } finally {
156
+ _resetLogs();
157
+ setStderrLoggingEnabled(true);
158
+ }
159
+ });
160
+
161
+ test("detectStuck reason unchanged when logger buffer is empty", () => {
162
+ setStderrLoggingEnabled(false);
163
+ try {
164
+ _resetLogs();
165
+ const result = detectStuck([
166
+ { key: "A", error: "boom" },
167
+ { key: "A", error: "boom" },
168
+ ]);
169
+ assert.notEqual(result, null);
170
+ // No trailing " — " suffix when there are no logs to summarize.
171
+ assert.doesNotMatch(
172
+ result!.reason,
173
+ / — \d+ (error|warning)/,
174
+ "reason should have no logger suffix when buffer is empty",
175
+ );
176
+ } finally {
177
+ setStderrLoggingEnabled(true);
178
+ }
179
+ });
180
+
181
+ // ─── Runtime: readTransaction rollback failure surfaces via logError ────────
182
+ //
183
+ // snapshotState now delegates its transaction to readTransaction() in
184
+ // gsd-db.ts (single-writer refactor in #4198), so the split-brain
185
+ // ROLLBACK-failure log lives there, not in workflow-manifest.ts.
186
+
187
+ test("readTransaction logs ROLLBACK failures as split-brain signal", () => {
188
+ const dbSrc = readFileSync(
189
+ join(import.meta.dirname, "..", "gsd-db.ts"),
190
+ "utf-8",
191
+ );
192
+ assert.match(
193
+ dbSrc,
194
+ /logError\("db",\s*"snapshotState ROLLBACK failed"/,
195
+ "readTransaction ROLLBACK catch should call logError",
196
+ );
197
+ });
198
+
199
+ // ─── Runtime: state.ts and workflow-projections.ts log silent bailouts ─────
200
+
201
+ test("state.ts logs roadmap read failures instead of silently continuing", () => {
202
+ const stateSrc = readFileSync(
203
+ join(import.meta.dirname, "..", "state.ts"),
204
+ "utf-8",
205
+ );
206
+ assert.match(
207
+ stateSrc,
208
+ /logWarning\("state",\s*"reconcileDiskToDb: roadmap read failed/,
209
+ "state.ts reconcileDiskToDb should log roadmap read failures",
210
+ );
211
+ });
212
+
213
+ test("workflow-projections.ts logs DB probe failures instead of silent return", () => {
214
+ const projectionsSrc = readFileSync(
215
+ join(import.meta.dirname, "..", "workflow-projections.ts"),
216
+ "utf-8",
217
+ );
218
+ assert.match(
219
+ projectionsSrc,
220
+ /logWarning\("projection",\s*"renderStateProjection: DB handle probe failed/,
221
+ "renderStateProjection DB probe should log on failure",
222
+ );
223
+ });
@@ -424,6 +424,32 @@ export async function handleCompleteSlice(
424
424
  logError("tool", `complete-slice event log FAILED — completion invisible to reconciliation`, { error: (eventErr as Error).message });
425
425
  }
426
426
 
427
+ // Fire-and-forget graph rebuild — must NOT await, must NOT crash slice completion.
428
+ // Dynamic import of the package name (not a relative path) so it resolves
429
+ // correctly via package.json#exports in both development and production.
430
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
431
+ (async () => {
432
+ try {
433
+ const graphMod = await import("@gsd-build/mcp-server") as unknown as Partial<{
434
+ buildGraph: (dir: string) => Promise<{ nodes: unknown[]; edges: unknown[]; builtAt: string }>;
435
+ writeGraph: (gsdRoot: string, graph: unknown) => Promise<void>;
436
+ resolveGsdRoot: (basePath: string) => string;
437
+ }>;
438
+ if (
439
+ typeof graphMod.buildGraph !== "function"
440
+ || typeof graphMod.writeGraph !== "function"
441
+ || typeof graphMod.resolveGsdRoot !== "function"
442
+ ) {
443
+ throw new Error("graph helpers unavailable from @gsd-build/mcp-server");
444
+ }
445
+ const g = await graphMod.buildGraph(basePath);
446
+ await graphMod.writeGraph(graphMod.resolveGsdRoot(basePath), g);
447
+ } catch (graphErr) {
448
+ // Graph rebuild is best-effort — log at warning level but never propagate
449
+ logWarning("tool", `complete-slice graph rebuild failed (non-fatal): ${(graphErr as Error).message ?? String(graphErr)}`);
450
+ }
451
+ })();
452
+
427
453
  return {
428
454
  sliceId: params.sliceId,
429
455
  milestoneId: params.milestoneId,
@@ -23,6 +23,9 @@ import { invalidateStateCache } from "../state.js";
23
23
  import { VALIDATION_VERDICTS, isValidMilestoneVerdict } from "../verdict-parser.js";
24
24
  import { insertMilestoneValidationGates } from "../milestone-validation-gates.js";
25
25
  import { logWarning } from "../workflow-logger.js";
26
+ import { UokGateRunner } from "../uok/gate-runner.js";
27
+ import { loadEffectiveGSDPreferences } from "../preferences.js";
28
+ import { resolveUokFlags } from "../uok/flags.js";
26
29
 
27
30
  export interface ValidateMilestoneParams {
28
31
  milestoneId: string;
@@ -43,6 +46,12 @@ export interface ValidateMilestoneResult {
43
46
  validationPath: string;
44
47
  }
45
48
 
49
+ export interface ValidateMilestoneOptions {
50
+ uokGatesEnabled?: boolean;
51
+ traceId?: string;
52
+ turnId?: string;
53
+ }
54
+
46
55
  function renderValidationMarkdown(params: ValidateMilestoneParams): string {
47
56
  let md = `---
48
57
  verdict: ${params.verdict}
@@ -81,6 +90,7 @@ ${params.verdictRationale}
81
90
  export async function handleValidateMilestone(
82
91
  params: ValidateMilestoneParams,
83
92
  basePath: string,
93
+ opts?: ValidateMilestoneOptions,
84
94
  ): Promise<ValidateMilestoneResult | { error: string }> {
85
95
  if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
86
96
  return { error: "milestoneId is required and must be a non-empty string" };
@@ -108,6 +118,8 @@ export async function handleValidateMilestone(
108
118
  // rendering can regenerate. The inverse (file exists, no DB row) is
109
119
  // harder to detect and recover from (#2725).
110
120
  const validatedAt = new Date().toISOString();
121
+ const slices = getMilestoneSlices(params.milestoneId);
122
+ const gateSliceId = slices.length > 0 ? slices[0].id : "_milestone";
111
123
 
112
124
  transaction(() => {
113
125
  insertAssessment({
@@ -123,11 +135,9 @@ export async function handleValidateMilestone(
123
135
  // #2945 Bug 4: persist quality_gates records alongside the assessment.
124
136
  // Previously only the assessment was written, leaving M002+ milestones
125
137
  // with zero quality_gate records despite passing validation.
126
- const slices = getMilestoneSlices(params.milestoneId);
127
- const sliceId = slices.length > 0 ? slices[0].id : "_milestone";
128
138
  insertMilestoneValidationGates(
129
139
  params.milestoneId,
130
- sliceId,
140
+ gateSliceId,
131
141
  params.verdict,
132
142
  validatedAt,
133
143
  );
@@ -147,6 +157,41 @@ export async function handleValidateMilestone(
147
157
  clearPathCache();
148
158
  clearParseCache();
149
159
 
160
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
161
+ const gatesEnabled = opts?.uokGatesEnabled ?? resolveUokFlags(prefs).gates;
162
+ if (gatesEnabled) {
163
+ try {
164
+ const gateRunner = new UokGateRunner();
165
+ const nonPassVerdict = params.verdict !== "pass";
166
+ gateRunner.register({
167
+ id: "milestone-validation-gates",
168
+ type: "verification",
169
+ execute: async () => ({
170
+ outcome: nonPassVerdict ? "manual-attention" : "pass",
171
+ failureClass: nonPassVerdict ? "manual-attention" : "none",
172
+ rationale: `milestone validation verdict: ${params.verdict}`,
173
+ findings: nonPassVerdict
174
+ ? [params.verdictRationale, params.remediationPlan ?? ""].filter(Boolean).join("\n")
175
+ : "",
176
+ }),
177
+ });
178
+ await gateRunner.run("milestone-validation-gates", {
179
+ basePath,
180
+ traceId: opts?.traceId ?? `validate-milestone:${params.milestoneId}`,
181
+ turnId: opts?.turnId ?? `${params.milestoneId}:validate`,
182
+ milestoneId: params.milestoneId,
183
+ sliceId: gateSliceId,
184
+ unitType: "validate-milestone",
185
+ unitId: params.milestoneId,
186
+ });
187
+ } catch (err) {
188
+ logWarning(
189
+ "tool",
190
+ `validate_milestone — failed to persist UOK gate result: ${(err as Error).message}`,
191
+ );
192
+ }
193
+ }
194
+
150
195
  return {
151
196
  milestoneId: params.milestoneId,
152
197
  verdict: params.verdict,
@@ -5,7 +5,7 @@ import {
5
5
  getMilestone,
6
6
  getSliceStatusSummary,
7
7
  getSliceTaskCounts,
8
- _getAdapter,
8
+ readTransaction,
9
9
  saveGateResult,
10
10
  } from "../gsd-db.js";
11
11
  import { GATE_REGISTRY } from "../gate-registry.js";
@@ -616,12 +616,9 @@ export async function executeMilestoneStatus(
616
616
  };
617
617
  }
618
618
 
619
- const adapter = _getAdapter()!;
620
- adapter.exec("BEGIN");
621
- try {
619
+ return readTransaction(() => {
622
620
  const milestone = getMilestone(params.milestoneId);
623
621
  if (!milestone) {
624
- adapter.exec("COMMIT");
625
622
  return {
626
623
  content: [{ type: "text", text: `Milestone ${params.milestoneId} not found in database.` }],
627
624
  details: { operation: "milestone_status", milestoneId: params.milestoneId, found: false },
@@ -635,8 +632,6 @@ export async function executeMilestoneStatus(
635
632
  taskCounts: getSliceTaskCounts(params.milestoneId, s.id),
636
633
  }));
637
634
 
638
- adapter.exec("COMMIT");
639
-
640
635
  const result = {
641
636
  milestoneId: milestone.id,
642
637
  title: milestone.title,
@@ -651,10 +646,7 @@ export async function executeMilestoneStatus(
651
646
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
652
647
  details: { operation: "milestone_status", milestoneId: milestone.id, sliceCount: slices.length },
653
648
  };
654
- } catch (txErr) {
655
- try { adapter.exec("ROLLBACK"); } catch { /* swallow */ }
656
- throw txErr;
657
- }
649
+ });
658
650
  } catch (err) {
659
651
  const msg = err instanceof Error ? err.message : String(err);
660
652
  logWarning("tool", `gsd_milestone_status tool failed: ${msg}`);
@@ -111,14 +111,9 @@ export function executeReplan(
111
111
  // Also write replan_triggered_at column for DB-backed detection
112
112
  try {
113
113
  const req = createRequire(import.meta.url);
114
- const { isDbAvailable, _getAdapter } = req("./gsd-db.js");
114
+ const { isDbAvailable, setSliceReplanTriggeredAt } = req("./gsd-db.js");
115
115
  if (isDbAvailable()) {
116
- const adapter = _getAdapter();
117
- if (adapter) {
118
- adapter.prepare(
119
- "UPDATE slices SET replan_triggered_at = :ts WHERE milestone_id = :mid AND id = :sid",
120
- ).run({ ":ts": ts, ":mid": mid, ":sid": sid });
121
- }
116
+ setSliceReplanTriggeredAt(mid, sid, ts);
122
117
  }
123
118
  } catch {
124
119
  // DB write is best-effort — disk file is the primary trigger for fallback path