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
@@ -26,6 +26,8 @@ import { nativeIsRepo, nativeInit } from "./native-git-bridge.js";
26
26
  import { isInheritedRepo } from "./repo-identity.js";
27
27
  import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
28
28
  import { loadEffectiveGSDPreferences } from "./preferences.js";
29
+ import { resolveUokFlags } from "./uok/flags.js";
30
+ import { ensurePlanV2Graph } from "./uok/plan-v2.js";
29
31
  import { detectProjectState } from "./detection.js";
30
32
  import { showProjectInit, offerMigration } from "./init-wizard.js";
31
33
  import { validateDirectory } from "./validate-directory.js";
@@ -53,6 +55,25 @@ function nextMilestoneIdReserved(existingIds, uniqueEnabled) {
53
55
  reserveMilestoneId(id);
54
56
  return id;
55
57
  }
58
+ function needsPlanV2Gate(state) {
59
+ return state.phase === "executing"
60
+ || state.phase === "summarizing"
61
+ || state.phase === "validating-milestone"
62
+ || state.phase === "completing-milestone";
63
+ }
64
+ function runPlanV2Gate(ctx, basePath, state) {
65
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
66
+ const uokFlags = resolveUokFlags(prefs);
67
+ if (!uokFlags.planV2 || !needsPlanV2Gate(state))
68
+ return true;
69
+ const compiled = ensurePlanV2Graph(basePath, state);
70
+ if (!compiled.ok) {
71
+ const reason = compiled.reason ?? "plan-v2 compilation failed";
72
+ ctx.ui.notify(`Plan gate failed-closed: ${reason}. Complete plan/discuss artifacts before execution.`, "error");
73
+ return false;
74
+ }
75
+ return true;
76
+ }
56
77
  // ─── Commit Instruction Helpers ──────────────────────────────────────────────
57
78
  /** Build commit instruction for planning prompts. .gsd/ is managed externally and always gitignored. */
58
79
  function buildDocsCommitInstruction(_message) {
@@ -1110,6 +1131,8 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1110
1131
  catch (err) {
1111
1132
  logWarning("guided", `STATE.md rebuild failed: ${err.message}`);
1112
1133
  }
1134
+ if (!runPlanV2Gate(ctx, basePath, state))
1135
+ return;
1113
1136
  if (!state.activeMilestone?.id) {
1114
1137
  // Guard: if a discuss session is already in flight, don't re-inject the prompt.
1115
1138
  // Both /gsd and /gsd auto reach this branch when no milestone exists yet.
@@ -1,5 +1,18 @@
1
1
  export { isDepthConfirmationAnswer, isDepthVerified, isGateQuestionId, isQueuePhaseActive, setQueuePhaseActive, shouldBlockContextWrite, shouldBlockPendingGate, shouldBlockPendingGateBash, shouldBlockQueueExecution, setPendingGate, clearPendingGate, getPendingGate, } from "./bootstrap/write-gate.js";
2
2
  export default async function registerExtension(pi) {
3
- const { registerGsdExtension } = await import("./bootstrap/register-extension.js");
4
- registerGsdExtension(pi);
3
+ // Always register the core /gsd command first, in isolation.
4
+ // This ensures /gsd is available even if the full bootstrap (shortcuts,
5
+ // tools, hooks) fails — e.g. due to a Windows-specific import error.
6
+ const { registerGSDCommand } = await import("./commands/index.js");
7
+ registerGSDCommand(pi);
8
+ // Full setup (shortcuts, tools, hooks) in a separate try/catch so that
9
+ // any platform-specific load failure doesn't take out the core command.
10
+ try {
11
+ const { registerGsdExtension } = await import("./bootstrap/register-extension.js");
12
+ registerGsdExtension(pi);
13
+ }
14
+ catch (err) {
15
+ const { logWarning } = await import("./workflow-logger.js");
16
+ logWarning("bootstrap", `Extension setup partially failed — /gsd commands are available but shortcuts/tools may be missing: ${err instanceof Error ? err.message : String(err)}`);
17
+ }
5
18
  }
@@ -336,6 +336,7 @@ async function customizeAdvancedPrefs(ctx, prefs) {
336
336
  { id: "balanced", label: "Balanced", description: "Good trade-off (default)", recommended: true },
337
337
  { id: "budget", label: "Budget", description: "Minimize token usage" },
338
338
  { id: "quality", label: "Quality", description: "Maximize thoroughness" },
339
+ { id: "burn-max", label: "Burn Max", description: "Maximum depth, no phase skips" },
339
340
  ],
340
341
  });
341
342
  if (profileChoice !== "not_yet") {
@@ -14,6 +14,8 @@
14
14
  import { appendFileSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
15
15
  import { join } from "node:path";
16
16
  import { gsdRoot } from "./paths.js";
17
+ import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
18
+ import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
17
19
  // ─── Emit ─────────────────────────────────────────────────────────────────────
18
20
  /**
19
21
  * Append a journal event to the daily JSONL file.
@@ -34,6 +36,31 @@ export function emitJournalEvent(basePath, entry) {
34
36
  catch {
35
37
  // Silent failure — journal must never break auto-mode
36
38
  }
39
+ if (!isUnifiedAuditEnabled())
40
+ return;
41
+ try {
42
+ const causedBy = entry.causedBy
43
+ ? `${entry.causedBy.flowId}:${entry.causedBy.seq}`
44
+ : undefined;
45
+ const turnId = typeof entry.data?.turnId === "string"
46
+ ? entry.data.turnId
47
+ : undefined;
48
+ emitUokAuditEvent(basePath, buildAuditEnvelope({
49
+ traceId: entry.flowId,
50
+ turnId,
51
+ causedBy,
52
+ category: "orchestration",
53
+ type: `journal-${entry.eventType}`,
54
+ payload: {
55
+ seq: entry.seq,
56
+ rule: entry.rule,
57
+ data: entry.data ?? {},
58
+ },
59
+ }));
60
+ }
61
+ catch {
62
+ // Best-effort: audit projection must never block journal writes.
63
+ }
37
64
  }
38
65
  // ─── Query ────────────────────────────────────────────────────────────────────
39
66
  /**
@@ -5,7 +5,7 @@
5
5
  // Exports: parseDecisionsTable, parseRequirementsSections, migrateFromMarkdown
6
6
  import { readFileSync, readdirSync, existsSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
- import { upsertDecision, upsertRequirement, insertArtifact, insertMilestone, insertSlice, insertTask, openDatabase, transaction, _getAdapter, } from './gsd-db.js';
8
+ import { upsertDecision, upsertRequirement, insertArtifact, insertMilestone, insertSlice, insertTask, openDatabase, transaction, updateSliceStatus, _getAdapter, } from './gsd-db.js';
9
9
  import { resolveGsdRootFile, resolveMilestoneFile, resolveSliceFile, resolveTasksDir, milestonesDir, gsdRoot, resolveTaskFiles, } from './paths.js';
10
10
  import { findMilestoneIds } from './guided-flow.js';
11
11
  import { parseRoadmap, parsePlan } from './parsers-legacy.js';
@@ -571,9 +571,8 @@ export function migrateHierarchyToDb(basePath) {
571
571
  return t.done && existsSync(summaryFile);
572
572
  });
573
573
  if (allTasksDone && hasSliceSummary) {
574
- const adapter = _getAdapter();
575
- if (adapter) {
576
- adapter.prepare(`UPDATE slices SET status = 'complete' WHERE id = :sid AND milestone_id = :mid`).run({ ':sid': sliceEntry.id, ':mid': milestoneId });
574
+ if (_getAdapter()) {
575
+ updateSliceStatus(milestoneId, sliceEntry.id, 'complete');
577
576
  process.stderr.write(`gsd-migrate: ${milestoneId}/${sliceEntry.id} all tasks + slice summary complete — upgrading slice to complete\n`);
578
577
  }
579
578
  }
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // Storage layer for auto-learned project memories. Follows context-store.ts patterns.
4
4
  // All functions degrade gracefully: return empty results when DB unavailable, never throw.
5
- import { isDbAvailable, _getAdapter, transaction } from './gsd-db.js';
5
+ import { isDbAvailable, _getAdapter, transaction, insertMemoryRow, rewriteMemoryId, updateMemoryContentRow, incrementMemoryHitCount, supersedeMemoryRow, markMemoryUnitProcessed, decayMemoriesBefore, supersedeLowestRankedMemories, } from './gsd-db.js';
6
6
  // ─── Category Display Order ─────────────────────────────────────────────────
7
7
  const CATEGORY_PRIORITY = {
8
8
  gotcha: 0,
@@ -112,27 +112,23 @@ export function createMemory(fields) {
112
112
  const now = new Date().toISOString();
113
113
  // Insert with a temporary placeholder ID — seq is auto-assigned
114
114
  const placeholder = `_TMP_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
115
- adapter.prepare(`INSERT INTO memories (id, category, content, confidence, source_unit_type, source_unit_id, created_at, updated_at)
116
- VALUES (:id, :category, :content, :confidence, :source_unit_type, :source_unit_id, :created_at, :updated_at)`).run({
117
- ':id': placeholder,
118
- ':category': fields.category,
119
- ':content': fields.content,
120
- ':confidence': fields.confidence ?? 0.8,
121
- ':source_unit_type': fields.source_unit_type ?? null,
122
- ':source_unit_id': fields.source_unit_id ?? null,
123
- ':created_at': now,
124
- ':updated_at': now,
115
+ insertMemoryRow({
116
+ id: placeholder,
117
+ category: fields.category,
118
+ content: fields.content,
119
+ confidence: fields.confidence ?? 0.8,
120
+ sourceUnitType: fields.source_unit_type ?? null,
121
+ sourceUnitId: fields.source_unit_id ?? null,
122
+ createdAt: now,
123
+ updatedAt: now,
125
124
  });
126
- // Derive the real ID from the assigned seq
125
+ // Derive the real ID from the assigned seq (SELECT is still fine via adapter)
127
126
  const row = adapter.prepare('SELECT seq FROM memories WHERE id = :id').get({ ':id': placeholder });
128
127
  if (!row)
129
128
  return placeholder; // fallback — should not happen
130
129
  const seq = row['seq'];
131
130
  const realId = `MEM${String(seq).padStart(3, '0')}`;
132
- adapter.prepare('UPDATE memories SET id = :real_id WHERE id = :placeholder').run({
133
- ':real_id': realId,
134
- ':placeholder': placeholder,
135
- });
131
+ rewriteMemoryId(placeholder, realId);
136
132
  return realId;
137
133
  }
138
134
  catch {
@@ -145,17 +141,8 @@ export function createMemory(fields) {
145
141
  export function updateMemoryContent(id, content, confidence) {
146
142
  if (!isDbAvailable())
147
143
  return false;
148
- const adapter = _getAdapter();
149
- if (!adapter)
150
- return false;
151
144
  try {
152
- const now = new Date().toISOString();
153
- if (confidence != null) {
154
- adapter.prepare('UPDATE memories SET content = :content, confidence = :confidence, updated_at = :updated_at WHERE id = :id').run({ ':content': content, ':confidence': confidence, ':updated_at': now, ':id': id });
155
- }
156
- else {
157
- adapter.prepare('UPDATE memories SET content = :content, updated_at = :updated_at WHERE id = :id').run({ ':content': content, ':updated_at': now, ':id': id });
158
- }
145
+ updateMemoryContentRow(id, content, confidence, new Date().toISOString());
159
146
  return true;
160
147
  }
161
148
  catch {
@@ -168,11 +155,8 @@ export function updateMemoryContent(id, content, confidence) {
168
155
  export function reinforceMemory(id) {
169
156
  if (!isDbAvailable())
170
157
  return false;
171
- const adapter = _getAdapter();
172
- if (!adapter)
173
- return false;
174
158
  try {
175
- adapter.prepare('UPDATE memories SET hit_count = hit_count + 1, updated_at = :updated_at WHERE id = :id').run({ ':updated_at': new Date().toISOString(), ':id': id });
159
+ incrementMemoryHitCount(id, new Date().toISOString());
176
160
  return true;
177
161
  }
178
162
  catch {
@@ -185,11 +169,8 @@ export function reinforceMemory(id) {
185
169
  export function supersedeMemory(oldId, newId) {
186
170
  if (!isDbAvailable())
187
171
  return false;
188
- const adapter = _getAdapter();
189
- if (!adapter)
190
- return false;
191
172
  try {
192
- adapter.prepare('UPDATE memories SET superseded_by = :new_id, updated_at = :updated_at WHERE id = :old_id').run({ ':new_id': newId, ':updated_at': new Date().toISOString(), ':old_id': oldId });
173
+ supersedeMemoryRow(oldId, newId, new Date().toISOString());
193
174
  return true;
194
175
  }
195
176
  catch {
@@ -220,12 +201,8 @@ export function isUnitProcessed(unitKey) {
220
201
  export function markUnitProcessed(unitKey, activityFile) {
221
202
  if (!isDbAvailable())
222
203
  return false;
223
- const adapter = _getAdapter();
224
- if (!adapter)
225
- return false;
226
204
  try {
227
- adapter.prepare(`INSERT OR IGNORE INTO memory_processed_units (unit_key, activity_file, processed_at)
228
- VALUES (:key, :file, :at)`).run({ ':key': unitKey, ':file': activityFile, ':at': new Date().toISOString() });
205
+ markMemoryUnitProcessed(unitKey, activityFile, new Date().toISOString());
229
206
  return true;
230
207
  }
231
208
  catch {
@@ -244,16 +221,14 @@ export function decayStaleMemories(thresholdUnits = 20) {
244
221
  if (!adapter)
245
222
  return;
246
223
  try {
247
- // Find the timestamp of the Nth most recent processed unit
224
+ // Find the timestamp of the Nth most recent processed unit (read-only SELECT)
248
225
  const row = adapter.prepare(`SELECT processed_at FROM memory_processed_units
249
226
  ORDER BY processed_at DESC
250
227
  LIMIT 1 OFFSET :offset`).get({ ':offset': thresholdUnits - 1 });
251
228
  if (!row)
252
229
  return; // not enough processed units yet
253
230
  const cutoff = row['processed_at'];
254
- adapter.prepare(`UPDATE memories
255
- SET confidence = MAX(0.1, confidence - 0.1), updated_at = :now
256
- WHERE superseded_by IS NULL AND updated_at < :cutoff AND confidence > 0.1`).run({ ':now': new Date().toISOString(), ':cutoff': cutoff });
231
+ decayMemoriesBefore(cutoff, new Date().toISOString());
257
232
  }
258
233
  catch {
259
234
  // non-fatal
@@ -274,14 +249,7 @@ export function enforceMemoryCap(max = 50) {
274
249
  if (count <= max)
275
250
  return;
276
251
  const excess = count - max;
277
- // Batch update: supersede lowest-ranked active memories in a single statement
278
- adapter.prepare(`UPDATE memories SET superseded_by = 'CAP_EXCEEDED', updated_at = :now
279
- WHERE id IN (
280
- SELECT id FROM memories
281
- WHERE superseded_by IS NULL
282
- ORDER BY (confidence * (1.0 + hit_count * 0.1)) ASC
283
- LIMIT :limit
284
- )`).run({ ':now': new Date().toISOString(), ':limit': excess });
252
+ supersedeLowestRankedMemories(excess, new Date().toISOString());
285
253
  }
286
254
  catch {
287
255
  // non-fatal
@@ -17,6 +17,8 @@ import { gsdRoot } from "./paths.js";
17
17
  import { getAndClearSkills } from "./skill-telemetry.js";
18
18
  import { loadJsonFile, loadJsonFileOrNull, saveJsonFile } from "./json-persistence.js";
19
19
  import { parseUnitId } from "./unit-id.js";
20
+ import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
21
+ import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
20
22
  // Re-export from shared — import directly from format-utils to avoid pulling
21
23
  // in the full barrel (mod.js → ui.js → @gsd/pi-tui) which breaks when loaded
22
24
  // outside jiti's alias resolution (e.g. dynamic import in auto-loop reports).
@@ -152,6 +154,23 @@ export function snapshotUnitMetrics(ctx, unitType, unitId, startedAt, model, opt
152
154
  ledger.units.push(unit);
153
155
  }
154
156
  saveLedger(basePath, ledger);
157
+ if (isUnifiedAuditEnabled()) {
158
+ emitUokAuditEvent(basePath, buildAuditEnvelope({
159
+ traceId: opts?.traceId ?? `metrics:${unitType}:${unitId}`,
160
+ turnId: opts?.turnId,
161
+ causedBy: opts?.causedBy,
162
+ category: "metrics",
163
+ type: "unit-metrics-snapshot",
164
+ payload: {
165
+ unitType,
166
+ unitId,
167
+ model,
168
+ tokens: unit.tokens,
169
+ cost: unit.cost,
170
+ toolCalls: unit.toolCalls,
171
+ },
172
+ }));
173
+ }
155
174
  return unit;
156
175
  }
157
176
  /**
@@ -10,7 +10,7 @@
10
10
  * gate registry so the definitions stay in lockstep with prompt builders,
11
11
  * dispatch rules, and state derivation. See gate-registry.ts.
12
12
  */
13
- import { _getAdapter } from "./gsd-db.js";
13
+ import { isDbAvailable, upsertQualityGate } from "./gsd-db.js";
14
14
  import { getGatesForTurn } from "./gate-registry.js";
15
15
  /**
16
16
  * Insert milestone-level quality_gates records for a validation run.
@@ -24,21 +24,22 @@ import { getGatesForTurn } from "./gate-registry.js";
24
24
  * in gate-registry.ts automatically flows through here.
25
25
  */
26
26
  export function insertMilestoneValidationGates(milestoneId, sliceId, verdict, evaluatedAt) {
27
- const db = _getAdapter();
28
- if (!db)
27
+ if (!isDbAvailable())
29
28
  return;
30
29
  const gateVerdict = verdict === "pass" ? "pass" : "flag";
31
30
  const milestoneGates = getGatesForTurn("validate-milestone");
32
31
  for (const def of milestoneGates) {
33
- db.prepare(`INSERT OR REPLACE INTO quality_gates
34
- (milestone_id, slice_id, gate_id, scope, task_id, status, verdict, rationale, findings, evaluated_at)
35
- VALUES (:mid, :sid, :gid, 'milestone', '', 'complete', :verdict, :rationale, '', :evaluated_at)`).run({
36
- ":mid": milestoneId,
37
- ":sid": sliceId,
38
- ":gid": def.id,
39
- ":verdict": gateVerdict,
40
- ":rationale": `${def.promptSection} — milestone validation verdict: ${verdict}`,
41
- ":evaluated_at": evaluatedAt,
32
+ upsertQualityGate({
33
+ milestoneId,
34
+ sliceId,
35
+ gateId: def.id,
36
+ scope: "milestone",
37
+ taskId: "",
38
+ status: "complete",
39
+ verdict: gateVerdict,
40
+ rationale: `${def.promptSection} — milestone validation verdict: ${verdict}`,
41
+ findings: "",
42
+ evaluatedAt,
42
43
  });
43
44
  }
44
45
  }
@@ -4,7 +4,7 @@
4
4
  //
5
5
  // Both READ and WRITE operations are native — push operations remain as
6
6
  // execSync calls because git2 credential handling is too complex.
7
- import { execSync, execFileSync } from "node:child_process";
7
+ import { execFileSync } from "node:child_process";
8
8
  import { GSDError, GSD_GIT_ERROR } from "./errors.js";
9
9
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
10
10
  import { getErrorMessage } from "./error-utils.js";
@@ -206,7 +206,7 @@ export function nativeIsRepo(basePath) {
206
206
  return native.gitIsRepo(basePath);
207
207
  }
208
208
  try {
209
- execSync("git rev-parse --git-dir", { cwd: basePath, stdio: "pipe" });
209
+ execFileSync("git", ["rev-parse", "--git-dir"], { cwd: basePath, stdio: "pipe" });
210
210
  return true;
211
211
  }
212
212
  catch {
@@ -629,7 +629,10 @@ export function nativeCommit(basePath, message, options) {
629
629
  }
630
630
  // Fallback: use git commit with stdin pipe for safe multi-line messages
631
631
  try {
632
- const result = execSync(`git commit --no-verify -F -${options?.allowEmpty ? " --allow-empty" : ""}`, {
632
+ const args = ["commit", "--no-verify", "-F", "-"];
633
+ if (options?.allowEmpty)
634
+ args.push("--allow-empty");
635
+ const result = execFileSync("git", args, {
633
636
  cwd: basePath,
634
637
  stdio: ["pipe", "pipe", "pipe"],
635
638
  encoding: "utf-8",
@@ -767,7 +770,7 @@ export function nativeResetHard(basePath) {
767
770
  native.gitResetHard(basePath);
768
771
  return;
769
772
  }
770
- execSync("git reset --hard HEAD", { cwd: basePath, stdio: "pipe" });
773
+ execFileSync("git", ["reset", "--hard", "HEAD"], { cwd: basePath, stdio: "pipe" });
771
774
  }
772
775
  /**
773
776
  * Soft reset to a target ref (git reset --soft <ref>).
@@ -20,8 +20,13 @@ import { writeSessionStatus, readAllSessionStatuses, readSessionStatus, removeSe
20
20
  import { analyzeParallelEligibility, } from "./parallel-eligibility.js";
21
21
  import { getErrorMessage } from "./error-utils.js";
22
22
  import { logWarning } from "./workflow-logger.js";
23
+ import { resolveUokFlags } from "./uok/flags.js";
24
+ import { selectConflictFreeBatch } from "./uok/execution-graph.js";
23
25
  // ─── Module State ──────────────────────────────────────────────────────────
24
26
  let state = null;
27
+ function overlapKey(a, b) {
28
+ return a < b ? `${a}::${b}` : `${b}::${a}`;
29
+ }
25
30
  // ─── Persistence ──────────────────────────────────────────────────────────
26
31
  const ORCHESTRATOR_STATE_FILE = "orchestrator.json";
27
32
  const TMP_SUFFIX = ".tmp";
@@ -277,6 +282,7 @@ export async function startParallel(basePath, milestoneIds, prefs) {
277
282
  return { started: [], errors: [{ mid: "all", error: "Cannot start parallel from within a parallel worker" }] };
278
283
  }
279
284
  const config = resolveParallelConfig(prefs);
285
+ const uokFlags = resolveUokFlags(prefs);
280
286
  // Release any leftover state from a previous session before reassigning
281
287
  if (state) {
282
288
  for (const w of state.workers.values()) {
@@ -324,8 +330,34 @@ export async function startParallel(basePath, milestoneIds, prefs) {
324
330
  };
325
331
  const started = [];
326
332
  const errors = [];
333
+ let filteredMilestoneIds = milestoneIds;
334
+ if (uokFlags.executionGraph && milestoneIds.length > 1) {
335
+ try {
336
+ const requestedIds = new Set(milestoneIds);
337
+ const candidates = await analyzeParallelEligibility(basePath);
338
+ const overlapPairs = new Set();
339
+ for (const overlap of candidates.fileOverlaps) {
340
+ if (!requestedIds.has(overlap.mid1) || !requestedIds.has(overlap.mid2))
341
+ continue;
342
+ overlapPairs.add(overlapKey(overlap.mid1, overlap.mid2));
343
+ }
344
+ filteredMilestoneIds = selectConflictFreeBatch({
345
+ orderedIds: milestoneIds,
346
+ maxParallel: milestoneIds.length,
347
+ hasConflict: (candidate, existing) => overlapPairs.has(overlapKey(candidate, existing)),
348
+ });
349
+ if (filteredMilestoneIds.length < milestoneIds.length) {
350
+ const skipped = milestoneIds.filter((mid) => !filteredMilestoneIds.includes(mid));
351
+ logWarning("parallel", `uok execution graph filtered ${skipped.length} conflicting milestone(s): ${skipped.join(", ")}`);
352
+ }
353
+ }
354
+ catch (e) {
355
+ logWarning("parallel", `uok execution graph overlap analysis failed; using legacy milestone selection: ${e.message}`);
356
+ filteredMilestoneIds = milestoneIds;
357
+ }
358
+ }
327
359
  // Cap to max_workers
328
- const toStart = milestoneIds.slice(0, config.max_workers);
360
+ const toStart = filteredMilestoneIds.slice(0, config.max_workers);
329
361
  for (const mid of toStart) {
330
362
  // Check budget ceiling before each spawn
331
363
  if (isBudgetExceeded()) {
@@ -321,7 +321,7 @@ export function resolveAutoSupervisorConfig() {
321
321
  };
322
322
  }
323
323
  // ─── Token Profile Resolution ─────────────────────────────────────────────
324
- const VALID_TOKEN_PROFILES = new Set(["budget", "balanced", "quality"]);
324
+ const VALID_TOKEN_PROFILES = new Set(["budget", "balanced", "quality", "burn-max"]);
325
325
  /**
326
326
  * Resolve profile defaults for a given token profile tier.
327
327
  * Returns a partial GSDPreferences that is used as the base layer --
@@ -365,6 +365,22 @@ export function resolveProfileDefaults(profile) {
365
365
  skip_reassess: true,
366
366
  },
367
367
  };
368
+ case "burn-max":
369
+ return {
370
+ // Quality-first profile: keep user-selected models, disable downgrade routing.
371
+ // Policy constraints still apply at dispatch time.
372
+ dynamic_routing: {
373
+ enabled: false,
374
+ },
375
+ context_selection: "full",
376
+ phases: {
377
+ skip_research: false,
378
+ skip_slice_research: false,
379
+ skip_reassess: false,
380
+ skip_milestone_validation: false,
381
+ reassess_after_slice: true,
382
+ },
383
+ };
368
384
  }
369
385
  }
370
386
  /**
@@ -380,7 +396,7 @@ export function resolveEffectiveProfile() {
380
396
  }
381
397
  /**
382
398
  * Resolve the inline level from the active token profile.
383
- * budget -> minimal, balanced -> standard, quality -> full.
399
+ * budget -> minimal, balanced -> standard, quality/burn-max -> full.
384
400
  */
385
401
  export function resolveInlineLevel() {
386
402
  const profile = resolveEffectiveProfile();
@@ -388,11 +404,12 @@ export function resolveInlineLevel() {
388
404
  case "budget": return "minimal";
389
405
  case "balanced": return "standard";
390
406
  case "quality": return "full";
407
+ case "burn-max": return "full";
391
408
  }
392
409
  }
393
410
  /**
394
411
  * Resolve the context selection mode from the active token profile.
395
- * budget -> "smart", balanced/quality -> "full".
412
+ * budget -> "smart", balanced/quality/burn-max -> "full".
396
413
  * Explicit preference always wins.
397
414
  */
398
415
  export function resolveContextSelection() {
@@ -53,6 +53,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
53
53
  "post_unit_hooks",
54
54
  "pre_dispatch_hooks",
55
55
  "dynamic_routing",
56
+ "uok",
56
57
  "token_profile",
57
58
  "phases",
58
59
  "auto_visualize",
@@ -8,7 +8,12 @@
8
8
  import { VALID_BRANCH_NAME } from "./git-service.js";
9
9
  import { normalizeStringArray } from "../shared/format-utils.js";
10
10
  import { KNOWN_PREFERENCE_KEYS, KNOWN_UNIT_TYPES, SKILL_ACTIONS, } from "./preferences-types.js";
11
- const VALID_TOKEN_PROFILES = new Set(["budget", "balanced", "quality"]);
11
+ const VALID_TOKEN_PROFILES = new Set(["budget", "balanced", "quality", "burn-max"]);
12
+ const VALID_UOK_TURN_ACTIONS = new Set([
13
+ "commit",
14
+ "snapshot",
15
+ "status-only",
16
+ ]);
12
17
  export function validatePreferences(preferences) {
13
18
  const errors = [];
14
19
  const warnings = [];
@@ -136,13 +141,114 @@ export function validatePreferences(preferences) {
136
141
  errors.push(`budget_enforcement must be one of: warn, pause, halt`);
137
142
  }
138
143
  }
144
+ // ─── UOK Flags ──────────────────────────────────────────────────────
145
+ if (preferences.uok !== undefined) {
146
+ if (typeof preferences.uok === "object" && preferences.uok !== null) {
147
+ const raw = preferences.uok;
148
+ const valid = {};
149
+ if (raw.enabled !== undefined) {
150
+ if (typeof raw.enabled === "boolean")
151
+ valid.enabled = raw.enabled;
152
+ else
153
+ errors.push("uok.enabled must be a boolean");
154
+ }
155
+ const parseEnabledBlock = (key) => {
156
+ const value = raw[key];
157
+ if (value === undefined)
158
+ return;
159
+ if (typeof value !== "object" || value === null) {
160
+ errors.push(`uok.${key} must be an object`);
161
+ return;
162
+ }
163
+ const block = value;
164
+ const parsed = {};
165
+ if (block.enabled !== undefined) {
166
+ if (typeof block.enabled === "boolean")
167
+ parsed.enabled = block.enabled;
168
+ else
169
+ errors.push(`uok.${key}.enabled must be a boolean`);
170
+ }
171
+ const unknown = Object.keys(block).filter((k) => k !== "enabled");
172
+ for (const unk of unknown) {
173
+ warnings.push(`unknown uok.${key} key "${unk}" — ignored`);
174
+ }
175
+ if (Object.keys(parsed).length > 0) {
176
+ valid[key] = parsed;
177
+ }
178
+ };
179
+ parseEnabledBlock("legacy_fallback");
180
+ parseEnabledBlock("gates");
181
+ parseEnabledBlock("model_policy");
182
+ parseEnabledBlock("execution_graph");
183
+ parseEnabledBlock("audit_unified");
184
+ parseEnabledBlock("plan_v2");
185
+ if (raw.gitops !== undefined) {
186
+ if (typeof raw.gitops !== "object" || raw.gitops === null) {
187
+ errors.push("uok.gitops must be an object");
188
+ }
189
+ else {
190
+ const gitops = raw.gitops;
191
+ const parsed = {};
192
+ if (gitops.enabled !== undefined) {
193
+ if (typeof gitops.enabled === "boolean")
194
+ parsed.enabled = gitops.enabled;
195
+ else
196
+ errors.push("uok.gitops.enabled must be a boolean");
197
+ }
198
+ if (gitops.turn_action !== undefined) {
199
+ if (typeof gitops.turn_action === "string" &&
200
+ VALID_UOK_TURN_ACTIONS.has(gitops.turn_action)) {
201
+ parsed.turn_action = gitops.turn_action;
202
+ }
203
+ else {
204
+ errors.push("uok.gitops.turn_action must be one of: commit, snapshot, status-only");
205
+ }
206
+ }
207
+ if (gitops.turn_push !== undefined) {
208
+ if (typeof gitops.turn_push === "boolean")
209
+ parsed.turn_push = gitops.turn_push;
210
+ else
211
+ errors.push("uok.gitops.turn_push must be a boolean");
212
+ }
213
+ const unknown = Object.keys(gitops).filter((k) => !["enabled", "turn_action", "turn_push"].includes(k));
214
+ for (const unk of unknown) {
215
+ warnings.push(`unknown uok.gitops key "${unk}" — ignored`);
216
+ }
217
+ if (Object.keys(parsed).length > 0) {
218
+ valid.gitops = parsed;
219
+ }
220
+ }
221
+ }
222
+ const knownUokKeys = new Set([
223
+ "enabled",
224
+ "legacy_fallback",
225
+ "gates",
226
+ "model_policy",
227
+ "execution_graph",
228
+ "gitops",
229
+ "audit_unified",
230
+ "plan_v2",
231
+ ]);
232
+ for (const key of Object.keys(raw)) {
233
+ if (!knownUokKeys.has(key)) {
234
+ warnings.push(`unknown uok key "${key}" — ignored`);
235
+ }
236
+ }
237
+ if (Object.keys(valid).length > 0) {
238
+ validated.uok = valid;
239
+ }
240
+ }
241
+ else {
242
+ errors.push("uok must be an object");
243
+ }
244
+ }
139
245
  // ─── Token Profile ─────────────────────────────────────────────────
140
246
  if (preferences.token_profile !== undefined) {
141
247
  if (typeof preferences.token_profile === "string" && VALID_TOKEN_PROFILES.has(preferences.token_profile)) {
142
248
  validated.token_profile = preferences.token_profile;
143
249
  }
144
250
  else {
145
- errors.push(`token_profile must be one of: budget, balanced, quality`);
251
+ errors.push(`token_profile must be one of: budget, balanced, quality, burn-max`);
146
252
  }
147
253
  }
148
254
  // ─── Search Provider ─────────────────────────────────────────────