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
@@ -53,6 +53,8 @@ import {
53
53
  checkNeedsRunUat,
54
54
  } from "./auto-prompts.js";
55
55
  import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
56
+ import { resolveUokFlags } from "./uok/flags.js";
57
+ import { selectReactiveDispatchBatch } from "./uok/execution-graph.js";
56
58
 
57
59
  // ─── Types ────────────────────────────────────────────────────────────────
58
60
 
@@ -584,12 +586,20 @@ export const DISPATCH_RULES: DispatchRule[] = [
584
586
  // Only activate reactive dispatch when >1 task is ready
585
587
  if (readyIds.length <= 1) return null;
586
588
 
587
- const selected = chooseNonConflictingSubset(
588
- readyIds,
589
- graph,
590
- maxParallel,
591
- new Set(),
592
- );
589
+ const uokFlags = resolveUokFlags(prefs);
590
+ const selected = uokFlags.executionGraph
591
+ ? selectReactiveDispatchBatch({
592
+ graph,
593
+ readyIds,
594
+ maxParallel,
595
+ inFlightOutputs: new Set(),
596
+ }).selected
597
+ : chooseNonConflictingSubset(
598
+ readyIds,
599
+ graph,
600
+ maxParallel,
601
+ new Set(),
602
+ );
593
603
  if (selected.length <= 1) return null;
594
604
 
595
605
  // Log graph metrics for observability
@@ -10,12 +10,14 @@ import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
10
10
  import type { GSDPreferences } from "./preferences.js";
11
11
  import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
12
12
  import type { ComplexityTier } from "./complexity-classifier.js";
13
- import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
13
+ import { classifyUnitComplexity, extractTaskMetadata, tierLabel } from "./complexity-classifier.js";
14
14
  import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet, filterToolsForProvider } from "./model-router.js";
15
15
  import { getLedger, getProjectTotals } from "./metrics.js";
16
16
  import { unitPhaseLabel } from "./auto-dashboard.js";
17
17
  import { getSessionModelOverride } from "./session-model-override.js";
18
18
  import { logWarning } from "./workflow-logger.js";
19
+ import { resolveUokFlags } from "./uok/flags.js";
20
+ import { applyModelPolicyFilter } from "./uok/model-policy.js";
19
21
 
20
22
  export interface ModelSelectionResult {
21
23
  /** Routing metadata for metrics recording */
@@ -75,6 +77,7 @@ export async function selectAndApplyModel(
75
77
  /** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
76
78
  sessionModelOverride?: { provider: string; id: string } | null,
77
79
  ): Promise<ModelSelectionResult> {
80
+ const uokFlags = resolveUokFlags(prefs);
78
81
  const effectiveSessionModelOverride = sessionModelOverride === undefined
79
82
  ? getSessionModelOverride(ctx.sessionManager.getSessionId())
80
83
  : (sessionModelOverride ?? undefined);
@@ -97,6 +100,9 @@ export async function selectAndApplyModel(
97
100
 
98
101
  if (modelConfig) {
99
102
  const availableModels = ctx.modelRegistry.getAvailable();
103
+ const modelPolicyTraceId = `model:${ctx.sessionManager.getSessionId()}:${Date.now()}`;
104
+ const modelPolicyTurnId = `${unitType}:${unitId}`;
105
+ let policyAllowedModelKeys: Set<string> | null = null;
100
106
 
101
107
  // ─── Dynamic Model Routing ─────────────────────────────────────────
102
108
  // Dynamic routing (complexity-based downgrading) only applies in auto-mode.
@@ -106,8 +112,40 @@ export async function selectAndApplyModel(
106
112
  if (!isAutoMode) {
107
113
  routingConfig.enabled = false;
108
114
  }
115
+ // burn-max defaults to quality-first dispatch (no downgrade routing).
116
+ if (prefs?.token_profile === "burn-max") {
117
+ routingConfig.enabled = false;
118
+ }
109
119
  let effectiveModelConfig = modelConfig;
110
120
  let routingTierLabel = "";
121
+ let routingEligibleModels = availableModels;
122
+
123
+ const taskMetadataForPolicy = unitType === "execute-task"
124
+ ? extractTaskMetadata(unitId, basePath)
125
+ : undefined;
126
+
127
+ if (uokFlags.modelPolicy) {
128
+ const policy = applyModelPolicyFilter(
129
+ availableModels,
130
+ {
131
+ basePath,
132
+ traceId: modelPolicyTraceId,
133
+ turnId: modelPolicyTurnId,
134
+ unitType,
135
+ taskMetadata: taskMetadataForPolicy,
136
+ currentProvider: ctx.model?.provider,
137
+ allowCrossProvider: routingConfig.cross_provider !== false,
138
+ requiredTools: pi.getActiveTools(),
139
+ },
140
+ );
141
+ routingEligibleModels = policy.eligible;
142
+ policyAllowedModelKeys = new Set(
143
+ policy.eligible.map((m) => `${m.provider.toLowerCase()}/${m.id.toLowerCase()}`),
144
+ );
145
+ if (routingEligibleModels.length === 0) {
146
+ throw new Error(`Model policy denied all candidate models for ${unitType}/${unitId}`);
147
+ }
148
+ }
111
149
 
112
150
  // Disable routing for flat-rate providers like GitHub Copilot (#3453).
113
151
  // All models cost the same per request, so downgrading to a cheaper
@@ -115,7 +153,7 @@ export async function selectAndApplyModel(
115
153
  // Fail-closed: if primary model can't be resolved, fall back to
116
154
  // provider-level signals rather than allowing unwanted downgrades.
117
155
  if (routingConfig.enabled) {
118
- const primaryModel = resolveModelId(modelConfig.primary, availableModels, ctx.model?.provider);
156
+ const primaryModel = resolveModelId(modelConfig.primary, routingEligibleModels, ctx.model?.provider);
119
157
  if (primaryModel) {
120
158
  const primaryFlatRateCtx = buildFlatRateContext(primaryModel.provider, ctx, prefs);
121
159
  if (isFlatRateProvider(primaryModel.provider, primaryFlatRateCtx)) {
@@ -149,8 +187,14 @@ export async function selectAndApplyModel(
149
187
  const shouldClassify = !isHook || routingConfig.hooks !== false;
150
188
 
151
189
  if (shouldClassify) {
152
- let classification = classifyUnitComplexity(unitType, unitId, basePath, budgetPct);
153
- const availableModelIds = availableModels.map(m => m.id);
190
+ let classification = classifyUnitComplexity(
191
+ unitType,
192
+ unitId,
193
+ basePath,
194
+ budgetPct,
195
+ taskMetadataForPolicy,
196
+ );
197
+ const availableModelIds = routingEligibleModels.map(m => m.id);
154
198
 
155
199
  // Escalate tier on retry when escalate_on_failure is enabled (default: true)
156
200
  if (
@@ -257,15 +301,28 @@ export async function selectAndApplyModel(
257
301
  }
258
302
 
259
303
  const modelsToTry = [effectiveModelConfig.primary, ...effectiveModelConfig.fallbacks];
304
+ let attemptedPolicyEligible = false;
260
305
 
261
306
  for (const modelId of modelsToTry) {
262
- const model = resolveModelId(modelId, availableModels, ctx.model?.provider);
307
+ const resolutionPool = uokFlags.modelPolicy ? routingEligibleModels : availableModels;
308
+ const model = resolveModelId(modelId, resolutionPool, ctx.model?.provider);
263
309
 
264
310
  if (!model) {
265
311
  if (verbose) ctx.ui.notify(`Model ${modelId} not found, trying fallback.`, "info");
266
312
  continue;
267
313
  }
268
314
 
315
+ if (policyAllowedModelKeys) {
316
+ const key = `${model.provider.toLowerCase()}/${model.id.toLowerCase()}`;
317
+ if (!policyAllowedModelKeys.has(key)) {
318
+ if (verbose) {
319
+ ctx.ui.notify(`Model policy denied ${model.provider}/${model.id}; trying fallback.`, "warning");
320
+ }
321
+ continue;
322
+ }
323
+ attemptedPolicyEligible = true;
324
+ }
325
+
269
326
  // Warn if the ID is ambiguous across providers
270
327
  if (!modelId.includes("/")) {
271
328
  const providers = availableModels.filter(m => m.id === modelId).map(m => m.provider);
@@ -331,6 +388,10 @@ export async function selectAndApplyModel(
331
388
  }
332
389
  }
333
390
  }
391
+
392
+ if (uokFlags.modelPolicy && policyAllowedModelKeys && !attemptedPolicyEligible) {
393
+ throw new Error(`Model policy denied dispatch for ${unitType}/${unitId} before prompt send`);
394
+ }
334
395
  } else if (autoModeStartModel) {
335
396
  // No model preference for this unit type — re-apply the model captured
336
397
  // at auto-mode start to prevent bleed from shared global settings.json (#650).
@@ -29,9 +29,10 @@ import { rebuildState } from "./doctor.js";
29
29
  import { parseUnitId } from "./unit-id.js";
30
30
  import { closeoutUnit, type CloseoutOptions } from "./auto-unit-closeout.js";
31
31
  import {
32
- autoCommitCurrentBranch,
32
+ runTurnGitAction,
33
33
  type TaskCommitContext,
34
- } from "./worktree.js";
34
+ type TurnGitActionMode,
35
+ } from "./git-service.js";
35
36
  import {
36
37
  verifyExpectedArtifact,
37
38
  resolveExpectedArtifactPath,
@@ -66,6 +67,9 @@ import { getSliceTasks } from "./gsd-db.js";
66
67
  import { runPreExecutionChecks, type PreExecutionResult } from "./pre-execution-checks.js";
67
68
  import { writePreExecutionEvidence } from "./verification-evidence.js";
68
69
  import { ensureCodebaseMapFresh } from "./codebase-generator.js";
70
+ import { resolveUokFlags } from "./uok/flags.js";
71
+ import { UokGateRunner } from "./uok/gate-runner.js";
72
+ import { writeTurnGitTransaction } from "./uok/gitops.js";
69
73
 
70
74
  /** Maximum verification retry attempts before escalating to blocker placeholder (#2653). */
71
75
  const MAX_VERIFICATION_RETRIES = 3;
@@ -109,6 +113,7 @@ import {
109
113
  import { existsSync, unlinkSync } from "node:fs";
110
114
  import { join } from "node:path";
111
115
  import { _resetHasChangesCache } from "./native-git-bridge.js";
116
+ import { autoCommitCurrentBranch } from "./worktree.js";
112
117
 
113
118
  // ─── Rogue File Detection ──────────────────────────────────────────────────
114
119
 
@@ -262,6 +267,65 @@ export interface PostUnitContext {
262
267
  updateProgressWidget: (ctx: ExtensionContext, unitType: string, unitId: string, state: import("./types.js").GSDState) => void;
263
268
  }
264
269
 
270
+ export async function autoCommitUnit(
271
+ basePath: string,
272
+ unitType: string,
273
+ unitId: string,
274
+ ctx?: ExtensionContext,
275
+ ): Promise<string | null> {
276
+ try {
277
+ let taskContext: TaskCommitContext | undefined;
278
+
279
+ if (unitType === "execute-task") {
280
+ const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
281
+ if (mid && sid && tid) {
282
+ const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
283
+ if (summaryPath) {
284
+ try {
285
+ const summaryContent = await loadFile(summaryPath);
286
+ if (summaryContent) {
287
+ const summary = parseSummary(summaryContent);
288
+ let ghIssueNumber: number | undefined;
289
+ try {
290
+ const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
291
+ ghIssueNumber = getTaskIssueNumberForCommit(basePath, mid, sid, tid) ?? undefined;
292
+ } catch (err) {
293
+ logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
294
+ }
295
+
296
+ taskContext = {
297
+ taskId: `${sid}/${tid}`,
298
+ taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
299
+ oneLiner: summary.oneLiner || undefined,
300
+ keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
301
+ issueNumber: ghIssueNumber,
302
+ };
303
+ }
304
+ } catch (e) {
305
+ debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
306
+ }
307
+ }
308
+ }
309
+ }
310
+
311
+ _resetHasChangesCache();
312
+
313
+ if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
314
+ return null;
315
+ }
316
+
317
+ const commitMsg = autoCommitCurrentBranch(basePath, unitType, unitId, taskContext);
318
+ if (commitMsg) {
319
+ ctx?.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
320
+ }
321
+ return commitMsg;
322
+ } catch (e) {
323
+ debugLog("postUnit", { phase: "auto-commit", error: String(e) });
324
+ ctx?.ui.notify(`Auto-commit failed: ${String(e).split("\n")[0]}`, "warning");
325
+ return null;
326
+ }
327
+ }
328
+
265
329
  /**
266
330
  * Pre-verification processing: parallel worker signal check, cache invalidation,
267
331
  * auto-commit, doctor run, state rebuild, worktree sync, artifact verification.
@@ -298,13 +362,21 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
298
362
  await new Promise(r => setTimeout(r, 100));
299
363
  }
300
364
 
301
- // Auto-commit
365
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
366
+ const uokFlags = resolveUokFlags(prefs);
367
+
368
+ // Turn-level git action (commit | snapshot | status-only)
302
369
  if (s.currentUnit) {
303
370
  const unit = s.currentUnit;
371
+ const turnAction: TurnGitActionMode = uokFlags.gitops ? uokFlags.gitopsTurnAction : "commit";
372
+ const traceId = s.currentTraceId ?? `turn:${unit.startedAt}`;
373
+ const turnId = s.currentTurnId ?? `${unit.type}/${unit.id}/${unit.startedAt}`;
374
+ s.lastGitActionFailure = null;
375
+ s.lastGitActionStatus = null;
304
376
  try {
305
377
  let taskContext: TaskCommitContext | undefined;
306
378
 
307
- if (s.currentUnit.type === "execute-task") {
379
+ if (turnAction === "commit" && s.currentUnit.type === "execute-task") {
308
380
  const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
309
381
  if (mid && sid && tid) {
310
382
  const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
@@ -345,18 +417,105 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
345
417
  // `git worktree remove --force` during teardown.
346
418
  _resetHasChangesCache();
347
419
 
348
- // Skip auto-commit for lifecycle-only units (#2553) — they only touch
349
- // `.gsd/` internal state files. Those files are picked up by the next
350
- // actual task commit via smartStage().
351
- if (!LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type)) {
352
- const commitMsg = autoCommitCurrentBranch(s.basePath, s.currentUnit.type, s.currentUnit.id, taskContext);
353
- if (commitMsg) {
354
- ctx.ui.notify(`Committed: ${commitMsg.split("\n")[0]}`, "info");
420
+ const skipLifecycleCommit =
421
+ turnAction === "commit" && LIFECYCLE_ONLY_UNITS.has(s.currentUnit.type);
422
+
423
+ if (skipLifecycleCommit) {
424
+ debugLog("postUnit", {
425
+ phase: "git-action-skipped",
426
+ reason: "lifecycle-only-unit",
427
+ unitType: s.currentUnit.type,
428
+ unitId: s.currentUnit.id,
429
+ });
430
+ } else {
431
+ const gitResult = runTurnGitAction({
432
+ basePath: s.basePath,
433
+ action: turnAction,
434
+ unitType: s.currentUnit.type,
435
+ unitId: s.currentUnit.id,
436
+ taskContext,
437
+ });
438
+
439
+ if (uokFlags.gitops) {
440
+ writeTurnGitTransaction({
441
+ basePath: s.basePath,
442
+ traceId,
443
+ turnId,
444
+ unitType: unit.type,
445
+ unitId: unit.id,
446
+ stage: "publish",
447
+ action: turnAction,
448
+ push: uokFlags.gitopsTurnPush,
449
+ status: gitResult.status,
450
+ error: gitResult.error,
451
+ metadata: {
452
+ dirty: gitResult.dirty,
453
+ commitMessage: gitResult.commitMessage,
454
+ snapshotLabel: gitResult.snapshotLabel,
455
+ },
456
+ });
457
+ }
458
+
459
+ if (gitResult.status === "failed") {
460
+ s.lastGitActionFailure = gitResult.error ?? `git ${turnAction} failed`;
461
+ s.lastGitActionStatus = "failed";
462
+ if (uokFlags.gitops && uokFlags.gates) {
463
+ const parsed = parseUnitId(unit.id);
464
+ const gateRunner = new UokGateRunner();
465
+ gateRunner.register({
466
+ id: "closeout-git-action",
467
+ type: "closeout",
468
+ execute: async () => ({
469
+ outcome: "fail",
470
+ failureClass: "git",
471
+ rationale: `turn git action "${turnAction}" failed`,
472
+ findings: gitResult.error ?? "unknown git failure",
473
+ }),
474
+ });
475
+ await gateRunner.run("closeout-git-action", {
476
+ basePath: s.basePath,
477
+ traceId,
478
+ turnId,
479
+ milestoneId: parsed.milestone ?? undefined,
480
+ sliceId: parsed.slice ?? undefined,
481
+ taskId: parsed.task ?? undefined,
482
+ unitType: unit.type,
483
+ unitId: unit.id,
484
+ });
485
+ }
486
+
487
+ const failureMsg = `Git ${turnAction} failed: ${(gitResult.error ?? "unknown error").split("\n")[0]}`;
488
+ if (uokFlags.gitops) {
489
+ ctx.ui.notify(failureMsg, "error");
490
+ await pauseAuto(ctx, pi);
491
+ return "dispatched";
492
+ }
493
+ ctx.ui.notify(failureMsg, "warning");
494
+ debugLog("postUnit", {
495
+ phase: "git-action-failed-nonblocking",
496
+ action: turnAction,
497
+ error: gitResult.error ?? "unknown error",
498
+ });
499
+ }
500
+
501
+ s.lastGitActionStatus = "ok";
502
+
503
+ if (turnAction === "commit" && gitResult.commitMessage) {
504
+ ctx.ui.notify(`Committed: ${gitResult.commitMessage.split("\n")[0]}`, "info");
505
+ } else if (turnAction === "snapshot" && gitResult.snapshotLabel) {
506
+ ctx.ui.notify(`Snapshot recorded: ${gitResult.snapshotLabel}`, "info");
355
507
  }
356
508
  }
357
509
  } catch (e) {
358
- debugLog("postUnit", { phase: "auto-commit", error: String(e) });
359
- ctx.ui.notify(`Auto-commit failed: ${String(e).split("\n")[0]}`, "warning");
510
+ const message = e instanceof Error ? e.message : String(e);
511
+ s.lastGitActionFailure = message;
512
+ s.lastGitActionStatus = "failed";
513
+ debugLog("postUnit", { phase: "git-action", error: message, action: turnAction });
514
+ ctx.ui.notify(`Git ${turnAction} failed: ${message.split("\n")[0]}`, uokFlags.gitops ? "error" : "warning");
515
+ if (uokFlags.gitops) {
516
+ await pauseAuto(ctx, pi);
517
+ return "dispatched";
518
+ }
360
519
  }
361
520
 
362
521
  // GitHub sync (non-blocking, opt-in)
@@ -866,11 +1025,13 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
866
1025
  s.currentUnit &&
867
1026
  s.currentUnit.type === "plan-slice"
868
1027
  ) {
1028
+ const currentUnit = s.currentUnit;
869
1029
  let preExecPauseNeeded = false;
870
1030
  await runSafely("postUnitPostVerification", "pre-execution-checks", async () => {
1031
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
1032
+ const uokFlags = resolveUokFlags(prefs);
871
1033
  try {
872
1034
  // Check preferences — respect enhanced_verification and enhanced_verification_pre
873
- const prefs = loadEffectiveGSDPreferences()?.preferences;
874
1035
  const enhancedEnabled = prefs?.enhanced_verification !== false; // default true
875
1036
  const preEnabled = prefs?.enhanced_verification_pre !== false; // default true
876
1037
 
@@ -884,7 +1045,7 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
884
1045
  }
885
1046
 
886
1047
  // Parse the unit ID to get milestone/slice IDs
887
- const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit!.id);
1048
+ const { milestone: mid, slice: sid } = parseUnitId(currentUnit.id);
888
1049
  if (!mid || !sid) {
889
1050
  debugLog("postUnitPostVerification", {
890
1051
  phase: "pre-execution-checks",
@@ -905,6 +1066,8 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
905
1066
  return;
906
1067
  }
907
1068
 
1069
+ const strictMode = prefs?.enhanced_verification_strict === true;
1070
+
908
1071
  // Run pre-execution checks
909
1072
  const result: PreExecutionResult = await runPreExecutionChecks(tasks, s.basePath);
910
1073
 
@@ -928,11 +1091,45 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
928
1091
  writePreExecutionEvidence(result, slicePath, mid, sid);
929
1092
  }
930
1093
 
931
- // Notify UI
1094
+ if (uokFlags.gates) {
1095
+ const failedChecks = result.checks
1096
+ .filter((check) => !check.passed)
1097
+ .map((check) => `[${check.category}] ${check.target}: ${check.message}`);
1098
+ const warnEscalated = result.status === "warn" && strictMode;
1099
+ const blockingFailure = result.status === "fail" || warnEscalated;
1100
+ const gateRunner = new UokGateRunner();
1101
+ gateRunner.register({
1102
+ id: "pre-execution-checks",
1103
+ type: "input",
1104
+ execute: async () => ({
1105
+ outcome: blockingFailure ? "fail" : "pass",
1106
+ failureClass: result.status === "fail" ? "input" : warnEscalated ? "policy" : "none",
1107
+ rationale: blockingFailure
1108
+ ? `pre-execution checks ${result.status}${warnEscalated ? " (strict)" : ""}`
1109
+ : "pre-execution checks passed",
1110
+ findings: failedChecks.join("\n"),
1111
+ }),
1112
+ });
1113
+ await gateRunner.run("pre-execution-checks", {
1114
+ basePath: s.basePath,
1115
+ traceId: `pre-execution:${currentUnit.id}`,
1116
+ turnId: currentUnit.id,
1117
+ milestoneId: mid,
1118
+ sliceId: sid,
1119
+ unitType: currentUnit.type,
1120
+ unitId: currentUnit.id,
1121
+ });
1122
+ }
1123
+
1124
+ // Notify UI — surface actionable details (#4259)
932
1125
  if (result.status === "fail") {
933
- const blockingCount = result.checks.filter(c => !c.passed && c.blocking).length;
1126
+ const blockingChecks = result.checks.filter(c => !c.passed && c.blocking);
1127
+ const blockingCount = blockingChecks.length;
1128
+ const details = blockingChecks.slice(0, 3).map(c => ` \u2022 ${c.message}`).join("\n");
1129
+ const suffix = blockingChecks.length > 3 ? `\n \u2022 ...and ${blockingChecks.length - 3} more` : "";
1130
+ const evidenceNote = `\nSee ${sid}-PRE-EXEC-VERIFY.json for full details.`;
934
1131
  ctx.ui.notify(
935
- `Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found`,
1132
+ `Pre-execution checks failed: ${blockingCount} blocking issue${blockingCount === 1 ? "" : "s"} found\n${details}${suffix}${evidenceNote}`,
936
1133
  "error",
937
1134
  );
938
1135
  preExecPauseNeeded = true;
@@ -966,6 +1163,29 @@ export async function postUnitPostVerification(pctx: PostUnitContext): Promise<"
966
1163
  `Pre-execution checks error: ${errorMessage} — pausing for human review`,
967
1164
  "error",
968
1165
  );
1166
+ if (uokFlags.gates && s.currentUnit) {
1167
+ const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
1168
+ const gateRunner = new UokGateRunner();
1169
+ gateRunner.register({
1170
+ id: "pre-execution-checks",
1171
+ type: "input",
1172
+ execute: async () => ({
1173
+ outcome: "manual-attention",
1174
+ failureClass: "manual-attention",
1175
+ rationale: "pre-execution checks threw before completion",
1176
+ findings: errorMessage,
1177
+ }),
1178
+ });
1179
+ await gateRunner.run("pre-execution-checks", {
1180
+ basePath: s.basePath,
1181
+ traceId: `pre-execution:${s.currentUnit.id}`,
1182
+ turnId: s.currentUnit.id,
1183
+ milestoneId: mid ?? undefined,
1184
+ sliceId: sid ?? undefined,
1185
+ unitType: s.currentUnit.type,
1186
+ unitId: s.currentUnit.id,
1187
+ });
1188
+ }
969
1189
  preExecPauseNeeded = true;
970
1190
  }
971
1191
  });
@@ -34,6 +34,7 @@ import {
34
34
  import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
35
35
  import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
36
36
  import { logWarning } from "./workflow-logger.js";
37
+ import { inlineGraphSubgraph } from "./graph-context.js";
37
38
 
38
39
  // ─── Preamble Cap ─────────────────────────────────────────────────────────────
39
40
 
@@ -1175,6 +1176,10 @@ export async function buildResearchSlicePrompt(
1175
1176
  const knowledgeInlineRS = await inlineKnowledgeScoped(base, keywords);
1176
1177
  if (knowledgeInlineRS) inlined.push(knowledgeInlineRS);
1177
1178
 
1179
+ // Knowledge graph: subgraph for this slice (graceful — skipped if no graph.json)
1180
+ const graphBlockRS = await inlineGraphSubgraph(base, `${sid} ${sTitle}`, { budget: 3000 });
1181
+ if (graphBlockRS) inlined.push(graphBlockRS);
1182
+
1178
1183
  inlined.push(inlineTemplate("research", "Research"));
1179
1184
 
1180
1185
  const depContent = await inlineDependencySummaries(mid, sid, base);
@@ -1250,6 +1255,10 @@ export async function buildPlanSlicePrompt(
1250
1255
  const knowledgeInlinePS = await inlineKnowledgeScoped(base, keywordsPS);
1251
1256
  if (knowledgeInlinePS) inlined.push(knowledgeInlinePS);
1252
1257
 
1258
+ // Knowledge graph: subgraph for this slice (graceful — skipped if no graph.json)
1259
+ const graphBlockPS = await inlineGraphSubgraph(base, `${sid} ${sTitle}`, { budget: 3000 });
1260
+ if (graphBlockPS) inlined.push(graphBlockPS);
1261
+
1253
1262
  inlined.push(inlineTemplate("plan", "Slice Plan"));
1254
1263
  if (inlineLevel === "full") {
1255
1264
  inlined.push(inlineTemplate("task-plan", "Task Plan"));
@@ -1366,12 +1375,16 @@ export async function buildExecuteTaskPrompt(
1366
1375
  // Only include if it has content (not a "not found" result)
1367
1376
  const knowledgeContent = knowledgeInlineET && !knowledgeInlineET.includes("not found") ? knowledgeInlineET : null;
1368
1377
 
1378
+ // Knowledge graph: tight subgraph for this task (graceful — skipped if no graph.json)
1379
+ const graphBlockET = await inlineGraphSubgraph(base, `${tid} ${tTitle}`, { budget: 2000 });
1380
+
1369
1381
  const inlinedTemplates = inlineLevel === "minimal"
1370
1382
  ? inlineTemplate("task-summary", "Task Summary")
1371
1383
  : [
1372
1384
  inlineTemplate("task-summary", "Task Summary"),
1373
1385
  inlineTemplate("decisions", "Decisions"),
1374
1386
  ...(knowledgeContent ? [knowledgeContent] : []),
1387
+ ...(graphBlockET ? [graphBlockET] : []),
1375
1388
  ].join("\n\n---\n\n");
1376
1389
 
1377
1390
  const taskSummaryPath = join(base, `${relSlicePath(base, mid, sid)}/tasks/${tid}-SUMMARY.md`);
@@ -8,6 +8,7 @@ import type { ExtensionContext } from "@gsd/pi-coding-agent";
8
8
  import { snapshotUnitMetrics } from "./metrics.js";
9
9
  import { saveActivityLog } from "./activity-log.js";
10
10
  import { logWarning } from "./workflow-logger.js";
11
+ import { writeTurnGitTransaction } from "./uok/gitops.js";
11
12
 
12
13
  export interface CloseoutOptions {
13
14
  promptCharCount?: number;
@@ -15,6 +16,12 @@ export interface CloseoutOptions {
15
16
  tier?: string;
16
17
  modelDowngraded?: boolean;
17
18
  continueHereFired?: boolean;
19
+ traceId?: string;
20
+ turnId?: string;
21
+ gitAction?: "commit" | "snapshot" | "status-only";
22
+ gitPush?: boolean;
23
+ gitStatus?: "ok" | "failed";
24
+ gitError?: string;
18
25
  }
19
26
 
20
27
  /**
@@ -47,6 +54,23 @@ export async function closeoutUnit(
47
54
  }
48
55
  }
49
56
 
57
+ if (opts?.traceId && opts.turnId && opts.gitAction && opts.gitStatus) {
58
+ writeTurnGitTransaction({
59
+ basePath,
60
+ traceId: opts.traceId,
61
+ turnId: opts.turnId,
62
+ unitType,
63
+ unitId,
64
+ stage: "record",
65
+ action: opts.gitAction,
66
+ push: opts.gitPush === true,
67
+ status: opts.gitStatus,
68
+ error: opts.gitError,
69
+ metadata: {
70
+ activityFile,
71
+ },
72
+ });
73
+ }
74
+
50
75
  return activityFile ?? undefined;
51
76
  }
52
-