gsd-pi 2.74.0-dev.b741afb → 2.74.0-dev.ffbcc03

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 (403) hide show
  1. package/dist/resources/extensions/gsd/activity-log.js +16 -0
  2. package/dist/resources/extensions/gsd/auto/loop.js +147 -10
  3. package/dist/resources/extensions/gsd/auto/phases.js +113 -3
  4. package/dist/resources/extensions/gsd/auto/session.js +10 -0
  5. package/dist/resources/extensions/gsd/auto-dispatch.js +11 -1
  6. package/dist/resources/extensions/gsd/auto-model-selection.js +51 -5
  7. package/dist/resources/extensions/gsd/auto-post-unit.js +215 -8
  8. package/dist/resources/extensions/gsd/auto-recovery.js +24 -10
  9. package/dist/resources/extensions/gsd/auto-unit-closeout.js +18 -0
  10. package/dist/resources/extensions/gsd/auto-verification.js +100 -2
  11. package/dist/resources/extensions/gsd/auto.js +28 -2
  12. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +10 -1
  13. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +61 -9
  14. package/dist/resources/extensions/gsd/cache.js +16 -5
  15. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  16. package/dist/resources/extensions/gsd/commands-extract-learnings.js +225 -0
  17. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  18. package/dist/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  19. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +144 -0
  20. package/dist/resources/extensions/gsd/ecosystem/loader.js +145 -0
  21. package/dist/resources/extensions/gsd/git-service.js +49 -1
  22. package/dist/resources/extensions/gsd/graph-context.js +98 -7
  23. package/dist/resources/extensions/gsd/gsd-db.js +260 -2
  24. package/dist/resources/extensions/gsd/guided-flow.js +24 -1
  25. package/dist/resources/extensions/gsd/init-wizard.js +1 -0
  26. package/dist/resources/extensions/gsd/journal.js +27 -0
  27. package/dist/resources/extensions/gsd/metrics.js +19 -0
  28. package/dist/resources/extensions/gsd/parallel-orchestrator.js +33 -1
  29. package/dist/resources/extensions/gsd/preferences-models.js +20 -3
  30. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  31. package/dist/resources/extensions/gsd/preferences-validation.js +108 -2
  32. package/dist/resources/extensions/gsd/preferences.js +26 -0
  33. package/dist/resources/extensions/gsd/safety/evidence-collector.js +15 -30
  34. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +12 -2
  35. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  36. package/dist/resources/extensions/gsd/tools/complete-slice.js +5 -0
  37. package/dist/resources/extensions/gsd/tools/validate-milestone.js +39 -4
  38. package/dist/resources/extensions/gsd/unit-ownership.js +1 -1
  39. package/dist/resources/extensions/gsd/uok/audit-toggle.js +7 -0
  40. package/dist/resources/extensions/gsd/uok/audit.js +40 -0
  41. package/dist/resources/extensions/gsd/uok/contracts.js +1 -0
  42. package/dist/resources/extensions/gsd/uok/execution-graph.js +179 -0
  43. package/dist/resources/extensions/gsd/uok/flags.js +29 -0
  44. package/dist/resources/extensions/gsd/uok/gate-runner.js +109 -0
  45. package/dist/resources/extensions/gsd/uok/gitops.js +53 -0
  46. package/dist/resources/extensions/gsd/uok/kernel.js +80 -0
  47. package/dist/resources/extensions/gsd/uok/loop-adapter.js +133 -0
  48. package/dist/resources/extensions/gsd/uok/model-policy.js +66 -0
  49. package/dist/resources/extensions/gsd/uok/plan-v2.js +132 -0
  50. package/dist/resources/extensions/gsd/workflow-logger.js +22 -0
  51. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  52. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  53. package/dist/web/standalone/.next/BUILD_ID +1 -1
  54. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  55. package/dist/web/standalone/.next/build-manifest.json +2 -2
  56. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/index.html +1 -1
  79. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  86. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  87. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  88. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  89. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  90. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  91. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  92. package/package.json +1 -1
  93. package/packages/mcp-server/dist/readers/graph.d.ts +1 -1
  94. package/packages/mcp-server/dist/readers/graph.d.ts.map +1 -1
  95. package/packages/mcp-server/dist/readers/graph.js +107 -0
  96. package/packages/mcp-server/dist/readers/graph.js.map +1 -1
  97. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  98. package/packages/mcp-server/dist/workflow-tools.js +88 -6
  99. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  100. package/packages/mcp-server/src/readers/graph.test.ts +178 -0
  101. package/packages/mcp-server/src/readers/graph.ts +148 -1
  102. package/packages/mcp-server/src/workflow-tools.ts +95 -10
  103. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  104. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  105. package/packages/pi-ai/dist/index.d.ts +1 -9
  106. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  107. package/packages/pi-ai/dist/index.js +1 -9
  108. package/packages/pi-ai/dist/index.js.map +1 -1
  109. package/packages/pi-ai/dist/models/capability-patches.d.ts +19 -0
  110. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -0
  111. package/packages/pi-ai/dist/models/capability-patches.js +36 -0
  112. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -0
  113. package/packages/pi-ai/dist/{models.custom.d.ts → models/custom.d.ts} +1 -1
  114. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -0
  115. package/packages/pi-ai/dist/{models.custom.js → models/custom.js} +4 -4
  116. package/packages/pi-ai/dist/models/custom.js.map +1 -0
  117. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +1482 -0
  118. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -0
  119. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +1484 -0
  120. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -0
  121. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +377 -0
  122. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -0
  123. package/packages/pi-ai/dist/models/generated/anthropic.js +379 -0
  124. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -0
  125. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts +700 -0
  126. package/packages/pi-ai/dist/models/generated/azure-openai-responses.d.ts.map +1 -0
  127. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js +702 -0
  128. package/packages/pi-ai/dist/models/generated/azure-openai-responses.js.map +1 -0
  129. package/packages/pi-ai/dist/models/generated/cerebras.d.ts +71 -0
  130. package/packages/pi-ai/dist/models/generated/cerebras.d.ts.map +1 -0
  131. package/packages/pi-ai/dist/models/generated/cerebras.js +73 -0
  132. package/packages/pi-ai/dist/models/generated/cerebras.js.map +1 -0
  133. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts +590 -0
  134. package/packages/pi-ai/dist/models/generated/github-copilot.d.ts.map +1 -0
  135. package/packages/pi-ai/dist/models/generated/github-copilot.js +444 -0
  136. package/packages/pi-ai/dist/models/generated/github-copilot.js.map +1 -0
  137. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +156 -0
  138. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -0
  139. package/packages/pi-ai/dist/models/generated/google-antigravity.js +158 -0
  140. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -0
  141. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts +105 -0
  142. package/packages/pi-ai/dist/models/generated/google-gemini-cli.d.ts.map +1 -0
  143. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js +107 -0
  144. package/packages/pi-ai/dist/models/generated/google-gemini-cli.js.map +1 -0
  145. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts +207 -0
  146. package/packages/pi-ai/dist/models/generated/google-vertex.d.ts.map +1 -0
  147. package/packages/pi-ai/dist/models/generated/google-vertex.js +209 -0
  148. package/packages/pi-ai/dist/models/generated/google-vertex.js.map +1 -0
  149. package/packages/pi-ai/dist/models/generated/google.d.ts +462 -0
  150. package/packages/pi-ai/dist/models/generated/google.d.ts.map +1 -0
  151. package/packages/pi-ai/dist/models/generated/google.js +464 -0
  152. package/packages/pi-ai/dist/models/generated/google.js.map +1 -0
  153. package/packages/pi-ai/dist/models/generated/groq.d.ts +309 -0
  154. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -0
  155. package/packages/pi-ai/dist/models/generated/groq.js +311 -0
  156. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -0
  157. package/packages/pi-ai/dist/models/generated/huggingface.d.ts +383 -0
  158. package/packages/pi-ai/dist/models/generated/huggingface.d.ts.map +1 -0
  159. package/packages/pi-ai/dist/models/generated/huggingface.js +347 -0
  160. package/packages/pi-ai/dist/models/generated/huggingface.js.map +1 -0
  161. package/packages/pi-ai/dist/{models.generated.d.ts → models/generated/index.d.ts} +1 -1
  162. package/packages/pi-ai/dist/{models.generated.d.ts.map → models/generated/index.d.ts.map} +1 -1
  163. package/packages/pi-ai/dist/models/generated/index.js +51 -0
  164. package/packages/pi-ai/dist/models/generated/index.js.map +1 -0
  165. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts +37 -0
  166. package/packages/pi-ai/dist/models/generated/kimi-coding.d.ts.map +1 -0
  167. package/packages/pi-ai/dist/models/generated/kimi-coding.js +39 -0
  168. package/packages/pi-ai/dist/models/generated/kimi-coding.js.map +1 -0
  169. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts +105 -0
  170. package/packages/pi-ai/dist/models/generated/minimax-cn.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/models/generated/minimax-cn.js +107 -0
  172. package/packages/pi-ai/dist/models/generated/minimax-cn.js.map +1 -0
  173. package/packages/pi-ai/dist/models/generated/minimax.d.ts +105 -0
  174. package/packages/pi-ai/dist/models/generated/minimax.d.ts.map +1 -0
  175. package/packages/pi-ai/dist/models/generated/minimax.js +107 -0
  176. package/packages/pi-ai/dist/models/generated/minimax.js.map +1 -0
  177. package/packages/pi-ai/dist/models/generated/mistral.d.ts +445 -0
  178. package/packages/pi-ai/dist/models/generated/mistral.d.ts.map +1 -0
  179. package/packages/pi-ai/dist/models/generated/mistral.js +447 -0
  180. package/packages/pi-ai/dist/models/generated/mistral.js.map +1 -0
  181. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +139 -0
  182. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -0
  183. package/packages/pi-ai/dist/models/generated/openai-codex.js +141 -0
  184. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -0
  185. package/packages/pi-ai/dist/models/generated/openai.d.ts +700 -0
  186. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -0
  187. package/packages/pi-ai/dist/models/generated/openai.js +702 -0
  188. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -0
  189. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts +122 -0
  190. package/packages/pi-ai/dist/models/generated/opencode-go.d.ts.map +1 -0
  191. package/packages/pi-ai/dist/models/generated/opencode-go.js +124 -0
  192. package/packages/pi-ai/dist/models/generated/opencode-go.js.map +1 -0
  193. package/packages/pi-ai/dist/models/generated/opencode.d.ts +530 -0
  194. package/packages/pi-ai/dist/models/generated/opencode.d.ts.map +1 -0
  195. package/packages/pi-ai/dist/models/generated/opencode.js +532 -0
  196. package/packages/pi-ai/dist/models/generated/opencode.js.map +1 -0
  197. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +4270 -0
  198. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -0
  199. package/packages/pi-ai/dist/models/generated/openrouter.js +4272 -0
  200. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -0
  201. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts +2604 -0
  202. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.d.ts.map +1 -0
  203. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js +2606 -0
  204. package/packages/pi-ai/dist/models/generated/vercel-ai-gateway.js.map +1 -0
  205. package/packages/pi-ai/dist/models/generated/xai.d.ts +411 -0
  206. package/packages/pi-ai/dist/models/generated/xai.d.ts.map +1 -0
  207. package/packages/pi-ai/dist/models/generated/xai.js +413 -0
  208. package/packages/pi-ai/dist/models/generated/xai.js.map +1 -0
  209. package/packages/pi-ai/dist/models/generated/zai.d.ts +276 -0
  210. package/packages/pi-ai/dist/models/generated/zai.d.ts.map +1 -0
  211. package/packages/pi-ai/dist/models/generated/zai.js +239 -0
  212. package/packages/pi-ai/dist/models/generated/zai.js.map +1 -0
  213. package/packages/pi-ai/dist/models/index.d.ts +27 -0
  214. package/packages/pi-ai/dist/models/index.d.ts.map +1 -0
  215. package/packages/pi-ai/dist/models/index.js +80 -0
  216. package/packages/pi-ai/dist/models/index.js.map +1 -0
  217. package/packages/pi-ai/dist/models.d.ts +1 -36
  218. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  219. package/packages/pi-ai/dist/models.generated.test.js +1 -2
  220. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  221. package/packages/pi-ai/dist/models.js +3 -112
  222. package/packages/pi-ai/dist/models.js.map +1 -1
  223. package/packages/pi-ai/dist/models.test.js +6 -5
  224. package/packages/pi-ai/dist/models.test.js.map +1 -1
  225. package/packages/pi-ai/scripts/generate-models.ts +74 -40
  226. package/packages/pi-ai/src/index.ts +1 -9
  227. package/packages/pi-ai/src/models/capability-patches.ts +40 -0
  228. package/packages/pi-ai/src/{models.custom.ts → models/custom.ts} +4 -4
  229. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +1486 -0
  230. package/packages/pi-ai/src/models/generated/anthropic.ts +381 -0
  231. package/packages/pi-ai/src/models/generated/azure-openai-responses.ts +704 -0
  232. package/packages/pi-ai/src/models/generated/cerebras.ts +75 -0
  233. package/packages/pi-ai/src/models/generated/github-copilot.ts +446 -0
  234. package/packages/pi-ai/src/models/generated/google-antigravity.ts +160 -0
  235. package/packages/pi-ai/src/models/generated/google-gemini-cli.ts +109 -0
  236. package/packages/pi-ai/src/models/generated/google-vertex.ts +211 -0
  237. package/packages/pi-ai/src/models/generated/google.ts +466 -0
  238. package/packages/pi-ai/src/models/generated/groq.ts +313 -0
  239. package/packages/pi-ai/src/models/generated/huggingface.ts +349 -0
  240. package/packages/pi-ai/src/models/generated/index.ts +52 -0
  241. package/packages/pi-ai/src/models/generated/kimi-coding.ts +41 -0
  242. package/packages/pi-ai/src/models/generated/minimax-cn.ts +109 -0
  243. package/packages/pi-ai/src/models/generated/minimax.ts +109 -0
  244. package/packages/pi-ai/src/models/generated/mistral.ts +449 -0
  245. package/packages/pi-ai/src/models/generated/openai-codex.ts +143 -0
  246. package/packages/pi-ai/src/models/generated/openai.ts +704 -0
  247. package/packages/pi-ai/src/models/generated/opencode-go.ts +126 -0
  248. package/packages/pi-ai/src/models/generated/opencode.ts +534 -0
  249. package/packages/pi-ai/src/models/generated/openrouter.ts +4274 -0
  250. package/packages/pi-ai/src/models/generated/vercel-ai-gateway.ts +2608 -0
  251. package/packages/pi-ai/src/models/generated/xai.ts +415 -0
  252. package/packages/pi-ai/src/models/generated/zai.ts +241 -0
  253. package/packages/pi-ai/src/models/index.ts +106 -0
  254. package/packages/pi-ai/src/models.generated.test.ts +1 -2
  255. package/packages/pi-ai/src/models.test.ts +6 -5
  256. package/packages/pi-ai/src/models.ts +3 -153
  257. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  258. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -2
  260. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +472 -0
  262. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts +2 -0
  264. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.d.ts.map +1 -0
  265. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js +52 -0
  266. package/packages/pi-coding-agent/dist/core/model-registry-env-fallback.test.js.map +1 -0
  267. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -2
  269. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +11 -0
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts +1 -0
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +23 -9
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +11 -0
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +47 -0
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +8 -0
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +68 -8
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +22 -22
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +232 -18
  289. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts +2 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.d.ts.map +1 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +38 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +14 -0
  295. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +70 -6
  297. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  298. package/packages/pi-coding-agent/src/core/agent-session.ts +12 -6
  299. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +612 -0
  300. package/packages/pi-coding-agent/src/core/model-registry-env-fallback.test.ts +59 -0
  301. package/packages/pi-coding-agent/src/core/model-registry.ts +2 -1
  302. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +19 -0
  303. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +25 -10
  304. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +67 -0
  305. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +83 -7
  306. package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +23 -26
  307. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +298 -41
  308. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +44 -0
  309. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +92 -6
  310. package/packages/pi-coding-agent/src/types/ambient-modules.d.ts +69 -0
  311. package/packages/pi-coding-agent/tsconfig.json +2 -2
  312. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  313. package/src/resources/extensions/gsd/activity-log.ts +21 -0
  314. package/src/resources/extensions/gsd/auto/loop-deps.ts +4 -0
  315. package/src/resources/extensions/gsd/auto/loop.ts +159 -10
  316. package/src/resources/extensions/gsd/auto/phases.ts +123 -3
  317. package/src/resources/extensions/gsd/auto/session.ts +10 -0
  318. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -6
  319. package/src/resources/extensions/gsd/auto-model-selection.ts +66 -5
  320. package/src/resources/extensions/gsd/auto-post-unit.ts +226 -9
  321. package/src/resources/extensions/gsd/auto-recovery.ts +29 -9
  322. package/src/resources/extensions/gsd/auto-unit-closeout.ts +25 -1
  323. package/src/resources/extensions/gsd/auto-verification.ts +129 -2
  324. package/src/resources/extensions/gsd/auto.ts +34 -2
  325. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -1
  326. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +72 -8
  327. package/src/resources/extensions/gsd/cache.ts +16 -5
  328. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  329. package/src/resources/extensions/gsd/commands-extract-learnings.ts +304 -0
  330. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  331. package/src/resources/extensions/gsd/docs/preferences-reference.md +14 -1
  332. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +228 -0
  333. package/src/resources/extensions/gsd/ecosystem/loader.ts +201 -0
  334. package/src/resources/extensions/gsd/git-service.ts +68 -0
  335. package/src/resources/extensions/gsd/graph-context.ts +139 -12
  336. package/src/resources/extensions/gsd/gsd-db.ts +321 -3
  337. package/src/resources/extensions/gsd/guided-flow.ts +33 -1
  338. package/src/resources/extensions/gsd/init-wizard.ts +3 -2
  339. package/src/resources/extensions/gsd/journal.ts +30 -0
  340. package/src/resources/extensions/gsd/metrics.ts +26 -0
  341. package/src/resources/extensions/gsd/parallel-orchestrator.ts +40 -1
  342. package/src/resources/extensions/gsd/preferences-models.ts +20 -3
  343. package/src/resources/extensions/gsd/preferences-types.ts +32 -0
  344. package/src/resources/extensions/gsd/preferences-validation.ts +107 -2
  345. package/src/resources/extensions/gsd/preferences.ts +28 -0
  346. package/src/resources/extensions/gsd/safety/evidence-collector.ts +15 -31
  347. package/src/resources/extensions/gsd/session-lock.ts +14 -2
  348. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +20 -1
  349. package/src/resources/extensions/gsd/templates/PREFERENCES.md +18 -0
  350. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +177 -0
  351. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +7 -3
  352. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +20 -0
  353. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +7 -3
  354. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +272 -0
  355. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +6 -2
  356. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +340 -0
  357. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  358. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  359. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +10 -7
  360. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  361. package/src/resources/extensions/gsd/tests/health-widget.test.ts +1 -1
  362. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -2
  363. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -3
  364. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  365. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +2 -1
  366. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +40 -1
  367. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +1 -1
  368. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -5
  369. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +101 -0
  370. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +85 -0
  371. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +69 -0
  372. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +39 -0
  373. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +70 -0
  374. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +85 -0
  375. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +35 -0
  376. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +89 -0
  377. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +167 -0
  378. package/src/resources/extensions/gsd/tests/uok-preferences.test.ts +42 -0
  379. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +39 -0
  380. package/src/resources/extensions/gsd/tools/complete-slice.ts +9 -2
  381. package/src/resources/extensions/gsd/tools/validate-milestone.ts +48 -3
  382. package/src/resources/extensions/gsd/types.ts +14 -1
  383. package/src/resources/extensions/gsd/unit-ownership.ts +2 -2
  384. package/src/resources/extensions/gsd/uok/audit-toggle.ts +9 -0
  385. package/src/resources/extensions/gsd/uok/audit.ts +51 -0
  386. package/src/resources/extensions/gsd/uok/contracts.ts +135 -0
  387. package/src/resources/extensions/gsd/uok/execution-graph.ts +241 -0
  388. package/src/resources/extensions/gsd/uok/flags.ts +45 -0
  389. package/src/resources/extensions/gsd/uok/gate-runner.ts +146 -0
  390. package/src/resources/extensions/gsd/uok/gitops.ts +75 -0
  391. package/src/resources/extensions/gsd/uok/kernel.ts +105 -0
  392. package/src/resources/extensions/gsd/uok/loop-adapter.ts +162 -0
  393. package/src/resources/extensions/gsd/uok/model-policy.ts +112 -0
  394. package/src/resources/extensions/gsd/uok/plan-v2.ts +156 -0
  395. package/src/resources/extensions/gsd/workflow-logger.ts +27 -1
  396. package/src/resources/extensions/ttsr/ttsr-manager.ts +10 -5
  397. package/packages/pi-ai/dist/models.custom.d.ts.map +0 -1
  398. package/packages/pi-ai/dist/models.custom.js.map +0 -1
  399. package/packages/pi-ai/dist/models.generated.js +0 -14343
  400. package/packages/pi-ai/dist/models.generated.js.map +0 -1
  401. package/packages/pi-ai/src/models.generated.ts +0 -14345
  402. /package/dist/web/standalone/.next/static/{XnHY5eXUsTCFmNodWHetD → kn6xzWKYnogsxp2b6RpDD}/_buildManifest.js +0 -0
  403. /package/dist/web/standalone/.next/static/{XnHY5eXUsTCFmNodWHetD → kn6xzWKYnogsxp2b6RpDD}/_ssgManifest.js +0 -0
@@ -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 ─────────────────────────────────────────────
@@ -293,6 +293,32 @@ function mergePreferences(base, override) {
293
293
  dynamic_routing: (base.dynamic_routing || override.dynamic_routing)
294
294
  ? { ...(base.dynamic_routing ?? {}), ...(override.dynamic_routing ?? {}) }
295
295
  : undefined,
296
+ uok: (base.uok || override.uok)
297
+ ? {
298
+ enabled: override.uok?.enabled ?? base.uok?.enabled,
299
+ legacy_fallback: (base.uok?.legacy_fallback || override.uok?.legacy_fallback)
300
+ ? { ...(base.uok?.legacy_fallback ?? {}), ...(override.uok?.legacy_fallback ?? {}) }
301
+ : undefined,
302
+ gates: (base.uok?.gates || override.uok?.gates)
303
+ ? { ...(base.uok?.gates ?? {}), ...(override.uok?.gates ?? {}) }
304
+ : undefined,
305
+ model_policy: (base.uok?.model_policy || override.uok?.model_policy)
306
+ ? { ...(base.uok?.model_policy ?? {}), ...(override.uok?.model_policy ?? {}) }
307
+ : undefined,
308
+ execution_graph: (base.uok?.execution_graph || override.uok?.execution_graph)
309
+ ? { ...(base.uok?.execution_graph ?? {}), ...(override.uok?.execution_graph ?? {}) }
310
+ : undefined,
311
+ gitops: (base.uok?.gitops || override.uok?.gitops)
312
+ ? { ...(base.uok?.gitops ?? {}), ...(override.uok?.gitops ?? {}) }
313
+ : undefined,
314
+ audit_unified: (base.uok?.audit_unified || override.uok?.audit_unified)
315
+ ? { ...(base.uok?.audit_unified ?? {}), ...(override.uok?.audit_unified ?? {}) }
316
+ : undefined,
317
+ plan_v2: (base.uok?.plan_v2 || override.uok?.plan_v2)
318
+ ? { ...(base.uok?.plan_v2 ?? {}), ...(override.uok?.plan_v2 ?? {}) }
319
+ : undefined,
320
+ }
321
+ : undefined,
296
322
  token_profile: override.token_profile ?? base.token_profile,
297
323
  phases: (base.phases || override.phases)
298
324
  ? { ...(base.phases ?? {}), ...(override.phases ?? {}) }
@@ -32,11 +32,11 @@ export function getFilePaths() {
32
32
  * Record a tool call at dispatch time (before execution).
33
33
  * Exit codes and output are filled in by recordToolResult after execution.
34
34
  */
35
- export function recordToolCall(toolName, input) {
35
+ export function recordToolCall(toolCallId, toolName, input) {
36
36
  if (toolName === "bash" || toolName === "Bash") {
37
37
  unitEvidence.push({
38
38
  kind: "bash",
39
- toolCallId: "",
39
+ toolCallId,
40
40
  command: String(input.command ?? ""),
41
41
  exitCode: -1,
42
42
  outputSnippet: "",
@@ -46,7 +46,7 @@ export function recordToolCall(toolName, input) {
46
46
  else if (toolName === "write" || toolName === "Write") {
47
47
  unitEvidence.push({
48
48
  kind: "write",
49
- toolCallId: "",
49
+ toolCallId,
50
50
  path: String(input.file_path ?? input.path ?? ""),
51
51
  timestamp: Date.now(),
52
52
  });
@@ -54,44 +54,29 @@ export function recordToolCall(toolName, input) {
54
54
  else if (toolName === "edit" || toolName === "Edit") {
55
55
  unitEvidence.push({
56
56
  kind: "edit",
57
- toolCallId: "",
57
+ toolCallId,
58
58
  path: String(input.file_path ?? input.path ?? ""),
59
59
  timestamp: Date.now(),
60
60
  });
61
61
  }
62
62
  }
63
63
  /**
64
- * Record a tool execution result. Matches the most recent unresolved entry
65
- * of the same kind and fills in the toolCallId, exit code, and output.
64
+ * Record a tool execution result. Matches the entry by toolCallId (assigned
65
+ * at dispatch time) and fills in exit code + output. Prior versions matched
66
+ * by `kind + empty-string` which corrupted parallel tool calls.
66
67
  */
67
68
  export function recordToolResult(toolCallId, toolName, result, isError) {
68
- const normalizedName = toolName.toLowerCase();
69
- if (normalizedName === "bash") {
70
- const entry = findLastUnresolved("bash");
71
- if (entry) {
72
- entry.toolCallId = toolCallId;
73
- const text = extractResultText(result);
74
- entry.outputSnippet = text.slice(0, 500);
75
- const exitMatch = text.match(/Command exited with code (\d+)/);
76
- entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
77
- }
78
- }
79
- else if (normalizedName === "write" || normalizedName === "edit") {
80
- const entry = findLastUnresolved(normalizedName);
81
- if (entry) {
82
- entry.toolCallId = toolCallId;
83
- }
69
+ const entry = unitEvidence.find(e => e.toolCallId === toolCallId);
70
+ if (!entry)
71
+ return;
72
+ if (entry.kind === "bash") {
73
+ const text = extractResultText(result);
74
+ entry.outputSnippet = text.slice(0, 500);
75
+ const exitMatch = text.match(/Command exited with code (\d+)/);
76
+ entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
84
77
  }
85
78
  }
86
79
  // ─── Internals ──────────────────────────────────────────────────────────────
87
- function findLastUnresolved(kind) {
88
- for (let i = unitEvidence.length - 1; i >= 0; i--) {
89
- if (unitEvidence[i].kind === kind && unitEvidence[i].toolCallId === "") {
90
- return unitEvidence[i];
91
- }
92
- }
93
- return undefined;
94
- }
95
80
  function extractResultText(result) {
96
81
  if (typeof result === "string")
97
82
  return result;
@@ -21,6 +21,7 @@ import { createWorktree, worktreePath, removeWorktree } from "./worktree-manager
21
21
  import { writeSessionStatus, } from "./session-status-io.js";
22
22
  import { hasFileConflict } from "./slice-parallel-conflict.js";
23
23
  import { getErrorMessage } from "./error-utils.js";
24
+ import { selectConflictFreeBatch } from "./uok/execution-graph.js";
24
25
  // ─── Module State ──────────────────────────────────────────────────────────
25
26
  let sliceState = null;
26
27
  // ─── Public API ────────────────────────────────────────────────────────────
@@ -62,7 +63,7 @@ export async function startSliceParallel(basePath, milestoneId, eligibleSlices,
62
63
  const started = [];
63
64
  const errors = [];
64
65
  // Filter out conflicting slices (conservative: check all pairs)
65
- const safeSlices = filterConflictingSlices(basePath, milestoneId, eligibleSlices);
66
+ const safeSlices = filterConflictingSlices(basePath, milestoneId, eligibleSlices, opts.useExecutionGraph === true);
66
67
  // Limit to maxWorkers
67
68
  const toSpawn = safeSlices.slice(0, maxWorkers);
68
69
  for (const slice of toSpawn) {
@@ -176,7 +177,16 @@ export function resetSliceOrchestrator() {
176
177
  * Greedy: add slices to the safe set in order; skip any that conflict
177
178
  * with an already-included slice.
178
179
  */
179
- function filterConflictingSlices(basePath, milestoneId, slices) {
180
+ function filterConflictingSlices(basePath, milestoneId, slices, useExecutionGraph) {
181
+ if (useExecutionGraph) {
182
+ const selectedIds = selectConflictFreeBatch({
183
+ orderedIds: slices.map((slice) => slice.id),
184
+ maxParallel: slices.length,
185
+ hasConflict: (candidate, existing) => hasFileConflict(basePath, milestoneId, candidate, existing),
186
+ });
187
+ const selected = new Set(selectedIds);
188
+ return slices.filter((slice) => selected.has(slice.id));
189
+ }
180
190
  const safe = [];
181
191
  for (const candidate of slices) {
182
192
  let conflictsWithSafe = false;
@@ -39,6 +39,24 @@ dynamic_routing:
39
39
  budget_pressure:
40
40
  cross_provider:
41
41
  hooks:
42
+ uok:
43
+ enabled: true
44
+ legacy_fallback:
45
+ enabled: false
46
+ gates:
47
+ enabled: false
48
+ model_policy:
49
+ enabled: false
50
+ execution_graph:
51
+ enabled: false
52
+ gitops:
53
+ enabled: false
54
+ turn_action: status-only
55
+ turn_push: false
56
+ audit_unified:
57
+ enabled: false
58
+ plan_v2:
59
+ enabled: false
42
60
  auto_visualize:
43
61
  auto_report:
44
62
  parallel:
@@ -361,6 +361,11 @@ export async function handleCompleteSlice(params, basePath) {
361
361
  (async () => {
362
362
  try {
363
363
  const graphMod = await import("@gsd-build/mcp-server");
364
+ if (typeof graphMod.buildGraph !== "function"
365
+ || typeof graphMod.writeGraph !== "function"
366
+ || typeof graphMod.resolveGsdRoot !== "function") {
367
+ throw new Error("graph helpers unavailable from @gsd-build/mcp-server");
368
+ }
364
369
  const g = await graphMod.buildGraph(basePath);
365
370
  await graphMod.writeGraph(graphMod.resolveGsdRoot(basePath), g);
366
371
  }
@@ -16,6 +16,9 @@ import { invalidateStateCache } from "../state.js";
16
16
  import { VALIDATION_VERDICTS, isValidMilestoneVerdict } from "../verdict-parser.js";
17
17
  import { insertMilestoneValidationGates } from "../milestone-validation-gates.js";
18
18
  import { logWarning } from "../workflow-logger.js";
19
+ import { UokGateRunner } from "../uok/gate-runner.js";
20
+ import { loadEffectiveGSDPreferences } from "../preferences.js";
21
+ import { resolveUokFlags } from "../uok/flags.js";
19
22
  function renderValidationMarkdown(params) {
20
23
  let md = `---
21
24
  verdict: ${params.verdict}
@@ -48,7 +51,7 @@ ${params.verdictRationale}
48
51
  }
49
52
  return md;
50
53
  }
51
- export async function handleValidateMilestone(params, basePath) {
54
+ export async function handleValidateMilestone(params, basePath, opts) {
52
55
  if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
53
56
  return { error: "milestoneId is required and must be a non-empty string" };
54
57
  }
@@ -73,6 +76,8 @@ export async function handleValidateMilestone(params, basePath) {
73
76
  // rendering can regenerate. The inverse (file exists, no DB row) is
74
77
  // harder to detect and recover from (#2725).
75
78
  const validatedAt = new Date().toISOString();
79
+ const slices = getMilestoneSlices(params.milestoneId);
80
+ const gateSliceId = slices.length > 0 ? slices[0].id : "_milestone";
76
81
  transaction(() => {
77
82
  insertAssessment({
78
83
  path: validationPath,
@@ -86,9 +91,7 @@ export async function handleValidateMilestone(params, basePath) {
86
91
  // #2945 Bug 4: persist quality_gates records alongside the assessment.
87
92
  // Previously only the assessment was written, leaving M002+ milestones
88
93
  // with zero quality_gate records despite passing validation.
89
- const slices = getMilestoneSlices(params.milestoneId);
90
- const sliceId = slices.length > 0 ? slices[0].id : "_milestone";
91
- insertMilestoneValidationGates(params.milestoneId, sliceId, params.verdict, validatedAt);
94
+ insertMilestoneValidationGates(params.milestoneId, gateSliceId, params.verdict, validatedAt);
92
95
  });
93
96
  // ── Filesystem render (outside transaction) ────────────────────────────
94
97
  // If disk render fails, roll back the DB row so state stays consistent.
@@ -103,6 +106,38 @@ export async function handleValidateMilestone(params, basePath) {
103
106
  invalidateStateCache();
104
107
  clearPathCache();
105
108
  clearParseCache();
109
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
110
+ const gatesEnabled = opts?.uokGatesEnabled ?? resolveUokFlags(prefs).gates;
111
+ if (gatesEnabled) {
112
+ try {
113
+ const gateRunner = new UokGateRunner();
114
+ const nonPassVerdict = params.verdict !== "pass";
115
+ gateRunner.register({
116
+ id: "milestone-validation-gates",
117
+ type: "verification",
118
+ execute: async () => ({
119
+ outcome: nonPassVerdict ? "manual-attention" : "pass",
120
+ failureClass: nonPassVerdict ? "manual-attention" : "none",
121
+ rationale: `milestone validation verdict: ${params.verdict}`,
122
+ findings: nonPassVerdict
123
+ ? [params.verdictRationale, params.remediationPlan ?? ""].filter(Boolean).join("\n")
124
+ : "",
125
+ }),
126
+ });
127
+ await gateRunner.run("milestone-validation-gates", {
128
+ basePath,
129
+ traceId: opts?.traceId ?? `validate-milestone:${params.milestoneId}`,
130
+ turnId: opts?.turnId ?? `${params.milestoneId}:validate`,
131
+ milestoneId: params.milestoneId,
132
+ sliceId: gateSliceId,
133
+ unitType: "validate-milestone",
134
+ unitId: params.milestoneId,
135
+ });
136
+ }
137
+ catch (err) {
138
+ logWarning("tool", `validate_milestone — failed to persist UOK gate result: ${err.message}`);
139
+ }
140
+ }
106
141
  return {
107
142
  milestoneId: params.milestoneId,
108
143
  verdict: params.verdict,
@@ -20,7 +20,7 @@ let providerModule = null;
20
20
  let loadAttempted = false;
21
21
  function suppressSqliteWarning() {
22
22
  const origEmit = process.emit;
23
- // @ts-expect-error overriding process.emit for warning filter
23
+ // Override via loose cast: Node's overloaded emit signature is not directly assignable.
24
24
  process.emit = function (event, ...args) {
25
25
  if (event === "warning" &&
26
26
  args[0] &&
@@ -0,0 +1,7 @@
1
+ const AUDIT_ENV_KEY = "GSD_UOK_AUDIT_UNIFIED";
2
+ export function setUnifiedAuditEnabled(enabled) {
3
+ process.env[AUDIT_ENV_KEY] = enabled ? "1" : "0";
4
+ }
5
+ export function isUnifiedAuditEnabled() {
6
+ return process.env[AUDIT_ENV_KEY] === "1";
7
+ }
@@ -0,0 +1,40 @@
1
+ import { appendFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { gsdRoot } from "../paths.js";
5
+ import { isDbAvailable, insertAuditEvent } from "../gsd-db.js";
6
+ function auditLogPath(basePath) {
7
+ return join(gsdRoot(basePath), "audit", "events.jsonl");
8
+ }
9
+ function ensureAuditDir(basePath) {
10
+ mkdirSync(join(gsdRoot(basePath), "audit"), { recursive: true });
11
+ }
12
+ export function buildAuditEnvelope(args) {
13
+ return {
14
+ eventId: randomUUID(),
15
+ traceId: args.traceId,
16
+ turnId: args.turnId,
17
+ causedBy: args.causedBy,
18
+ category: args.category,
19
+ type: args.type,
20
+ ts: new Date().toISOString(),
21
+ payload: args.payload ?? {},
22
+ };
23
+ }
24
+ export function emitUokAuditEvent(basePath, event) {
25
+ try {
26
+ ensureAuditDir(basePath);
27
+ appendFileSync(auditLogPath(basePath), `${JSON.stringify(event)}\n`, "utf-8");
28
+ }
29
+ catch {
30
+ // Best-effort: audit writes must never break orchestration.
31
+ }
32
+ if (!isDbAvailable())
33
+ return;
34
+ try {
35
+ insertAuditEvent(event);
36
+ }
37
+ catch {
38
+ // Projection failures are non-fatal while legacy readers are still active.
39
+ }
40
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,179 @@
1
+ export function selectConflictFreeBatch({ orderedIds, maxParallel, hasConflict, }) {
2
+ if (maxParallel <= 0 || orderedIds.length === 0)
3
+ return [];
4
+ const selected = [];
5
+ for (const candidate of orderedIds) {
6
+ if (selected.length >= maxParallel)
7
+ break;
8
+ const conflictsExisting = selected.some((existing) => hasConflict(candidate, existing));
9
+ if (conflictsExisting)
10
+ continue;
11
+ selected.push(candidate);
12
+ }
13
+ return selected;
14
+ }
15
+ function buildReactiveNodes(graph) {
16
+ return graph.map((node) => ({
17
+ id: node.id,
18
+ kind: "unit",
19
+ dependsOn: [...node.dependsOn],
20
+ writes: [...node.outputFiles],
21
+ }));
22
+ }
23
+ export function selectReactiveDispatchBatch(input) {
24
+ const nodeMap = new Map(buildReactiveNodes(input.graph).map((n) => [n.id, n]));
25
+ const readyNodes = input.readyIds
26
+ .map((id) => nodeMap.get(id))
27
+ .filter((node) => !!node);
28
+ const conflicts = detectFileConflicts(readyNodes);
29
+ if (readyNodes.length === 0 || input.maxParallel <= 0) {
30
+ return { selected: [], conflicts };
31
+ }
32
+ const claimed = new Set(input.inFlightOutputs ?? []);
33
+ const selected = [];
34
+ const selectedSet = new Set();
35
+ const readySet = new Set(input.readyIds);
36
+ for (const id of input.readyIds) {
37
+ if (selected.length >= input.maxParallel)
38
+ break;
39
+ const node = nodeMap.get(id);
40
+ if (!node)
41
+ continue;
42
+ const hasUnmetReadyDependency = node.dependsOn.some((dep) => readySet.has(dep) && !selectedSet.has(dep));
43
+ if (hasUnmetReadyDependency)
44
+ continue;
45
+ const writes = node.writes ?? [];
46
+ const conflictsWithClaimed = writes.some((file) => claimed.has(file));
47
+ if (conflictsWithClaimed)
48
+ continue;
49
+ selected.push(node.id);
50
+ selectedSet.add(node.id);
51
+ for (const file of writes)
52
+ claimed.add(file);
53
+ }
54
+ return { selected, conflicts };
55
+ }
56
+ function sidecarToNodeKind(kind) {
57
+ if (kind === "hook")
58
+ return "hook";
59
+ if (kind === "triage")
60
+ return "verification";
61
+ return "team-worker";
62
+ }
63
+ export function buildSidecarQueueNodes(queue) {
64
+ return queue.map((item, index) => ({
65
+ id: `sidecar-${String(index).padStart(4, "0")}:${item.kind}:${item.unitType}:${item.unitId}`,
66
+ kind: sidecarToNodeKind(item.kind),
67
+ dependsOn: index > 0 ? [`sidecar-${String(index - 1).padStart(4, "0")}:${queue[index - 1].kind}:${queue[index - 1].unitType}:${queue[index - 1].unitId}`] : [],
68
+ metadata: { index },
69
+ }));
70
+ }
71
+ export async function scheduleSidecarQueue(queue) {
72
+ if (queue.length <= 1)
73
+ return [...queue];
74
+ const nodes = buildSidecarQueueNodes(queue);
75
+ const scheduler = new ExecutionGraphScheduler();
76
+ const orderedIndexes = [];
77
+ const seenKinds = new Set(nodes.map((n) => n.kind));
78
+ for (const kind of seenKinds) {
79
+ scheduler.registerHandler(kind, async (node) => {
80
+ const idx = Number(node.metadata?.index);
81
+ if (Number.isInteger(idx) && idx >= 0)
82
+ orderedIndexes.push(idx);
83
+ });
84
+ }
85
+ await scheduler.run(nodes, { parallel: false });
86
+ return orderedIndexes.map((idx) => queue[idx]).filter((item) => !!item);
87
+ }
88
+ export class ExecutionGraphScheduler {
89
+ handlers = new Map();
90
+ registerHandler(kind, handler) {
91
+ this.handlers.set(kind, handler);
92
+ }
93
+ async run(nodes, options) {
94
+ const sorted = topologicalSort(nodes);
95
+ const conflicts = detectFileConflicts(nodes);
96
+ // Default deterministic serial execution remains the reference path.
97
+ if (!options?.parallel) {
98
+ for (const node of sorted) {
99
+ const handler = this.handlers.get(node.kind);
100
+ if (handler)
101
+ await handler(node);
102
+ }
103
+ return { order: sorted.map((n) => n.id), conflicts };
104
+ }
105
+ // Parallel mode only for nodes whose dependencies are already satisfied.
106
+ const maxWorkers = Math.max(1, Math.min(8, options.maxWorkers ?? 2));
107
+ const remaining = new Map(nodes.map((n) => [n.id, n]));
108
+ const done = new Set();
109
+ const order = [];
110
+ while (remaining.size > 0) {
111
+ const ready = Array.from(remaining.values()).filter((node) => node.dependsOn.every((dep) => done.has(dep)));
112
+ ready.sort((a, b) => a.id.localeCompare(b.id));
113
+ if (ready.length === 0) {
114
+ throw new Error("Execution graph deadlock detected: no ready nodes and graph not complete");
115
+ }
116
+ const batch = ready.slice(0, maxWorkers);
117
+ await Promise.all(batch.map(async (node) => {
118
+ const handler = this.handlers.get(node.kind);
119
+ if (handler)
120
+ await handler(node);
121
+ done.add(node.id);
122
+ order.push(node.id);
123
+ remaining.delete(node.id);
124
+ }));
125
+ }
126
+ return { order, conflicts };
127
+ }
128
+ }
129
+ function topologicalSort(nodes) {
130
+ const nodeMap = new Map(nodes.map((n) => [n.id, n]));
131
+ const inDegree = new Map(nodes.map((n) => [n.id, 0]));
132
+ for (const node of nodes) {
133
+ for (const dep of node.dependsOn) {
134
+ if (nodeMap.has(dep)) {
135
+ inDegree.set(node.id, (inDegree.get(node.id) ?? 0) + 1);
136
+ }
137
+ }
138
+ }
139
+ const queue = nodes
140
+ .filter((n) => (inDegree.get(n.id) ?? 0) === 0)
141
+ .sort((a, b) => a.id.localeCompare(b.id));
142
+ const ordered = [];
143
+ while (queue.length > 0) {
144
+ const current = queue.shift();
145
+ ordered.push(current);
146
+ for (const next of nodes) {
147
+ if (!next.dependsOn.includes(current.id))
148
+ continue;
149
+ const deg = (inDegree.get(next.id) ?? 0) - 1;
150
+ inDegree.set(next.id, deg);
151
+ if (deg === 0) {
152
+ queue.push(next);
153
+ queue.sort((a, b) => a.id.localeCompare(b.id));
154
+ }
155
+ }
156
+ }
157
+ if (ordered.length !== nodes.length) {
158
+ throw new Error("Execution graph has cyclic dependencies");
159
+ }
160
+ return ordered;
161
+ }
162
+ function detectFileConflicts(nodes) {
163
+ const conflicts = [];
164
+ for (let i = 0; i < nodes.length; i++) {
165
+ const a = nodes[i];
166
+ const writesA = new Set(a.writes ?? []);
167
+ if (writesA.size === 0)
168
+ continue;
169
+ for (let j = i + 1; j < nodes.length; j++) {
170
+ const b = nodes[j];
171
+ for (const file of b.writes ?? []) {
172
+ if (writesA.has(file)) {
173
+ conflicts.push({ nodeA: a.id, nodeB: b.id, file });
174
+ }
175
+ }
176
+ }
177
+ }
178
+ return conflicts;
179
+ }
@@ -0,0 +1,29 @@
1
+ import { loadEffectiveGSDPreferences } from "../preferences.js";
2
+ function envForcesLegacyFallback() {
3
+ const raw = process.env.GSD_UOK_FORCE_LEGACY ?? process.env.GSD_UOK_LEGACY_FALLBACK;
4
+ if (!raw)
5
+ return false;
6
+ const normalized = raw.trim().toLowerCase();
7
+ return normalized === "1" || normalized === "true" || normalized === "yes" || normalized === "on";
8
+ }
9
+ export function resolveUokFlags(prefs) {
10
+ const uok = prefs?.uok;
11
+ const legacyFallback = uok?.legacy_fallback?.enabled === true || envForcesLegacyFallback();
12
+ const enabledByPreference = uok?.enabled ?? true;
13
+ return {
14
+ enabled: enabledByPreference && !legacyFallback,
15
+ legacyFallback,
16
+ gates: uok?.gates?.enabled === true,
17
+ modelPolicy: uok?.model_policy?.enabled === true,
18
+ executionGraph: uok?.execution_graph?.enabled === true,
19
+ gitops: uok?.gitops?.enabled === true,
20
+ gitopsTurnAction: uok?.gitops?.turn_action ?? "status-only",
21
+ gitopsTurnPush: uok?.gitops?.turn_push === true,
22
+ auditUnified: uok?.audit_unified?.enabled === true,
23
+ planV2: uok?.plan_v2?.enabled === true,
24
+ };
25
+ }
26
+ export function loadUokFlags() {
27
+ const prefs = loadEffectiveGSDPreferences()?.preferences;
28
+ return resolveUokFlags(prefs);
29
+ }