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
@@ -83,6 +83,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
83
83
  "post_unit_hooks",
84
84
  "pre_dispatch_hooks",
85
85
  "dynamic_routing",
86
+ "uok",
86
87
  "token_profile",
87
88
  "phases",
88
89
  "auto_visualize",
@@ -208,6 +209,35 @@ export interface CmuxPreferences {
208
209
  browser?: boolean;
209
210
  }
210
211
 
212
+ export type UokTurnActionMode = "commit" | "snapshot" | "status-only";
213
+
214
+ export interface UokPreferences {
215
+ enabled?: boolean;
216
+ legacy_fallback?: {
217
+ enabled?: boolean;
218
+ };
219
+ gates?: {
220
+ enabled?: boolean;
221
+ };
222
+ model_policy?: {
223
+ enabled?: boolean;
224
+ };
225
+ execution_graph?: {
226
+ enabled?: boolean;
227
+ };
228
+ gitops?: {
229
+ enabled?: boolean;
230
+ turn_action?: UokTurnActionMode;
231
+ turn_push?: boolean;
232
+ };
233
+ audit_unified?: {
234
+ enabled?: boolean;
235
+ };
236
+ plan_v2?: {
237
+ enabled?: boolean;
238
+ };
239
+ }
240
+
211
241
  /**
212
242
  * Opt-in experimental features. All features in this block are disabled by
213
243
  * default and must be explicitly enabled. They may change or be removed without
@@ -256,6 +286,8 @@ export interface GSDPreferences {
256
286
  post_unit_hooks?: PostUnitHookConfig[];
257
287
  pre_dispatch_hooks?: PreDispatchHookConfig[];
258
288
  dynamic_routing?: DynamicRoutingConfig;
289
+ /** Unified Orchestration Kernel controls (all flags default off). */
290
+ uok?: UokPreferences;
259
291
  /** Per-model capability overrides. Deep-merged with built-in profiles for capability-aware routing (ADR-004). */
260
292
  modelOverrides?: Record<string, { capabilities?: Partial<ModelCapabilities> }>;
261
293
  context_management?: ContextManagementConfig;
@@ -22,7 +22,12 @@ import {
22
22
  type GSDSkillRule,
23
23
  } from "./preferences-types.js";
24
24
 
25
- const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality"]);
25
+ const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality", "burn-max"]);
26
+ const VALID_UOK_TURN_ACTIONS = new Set<"commit" | "snapshot" | "status-only">([
27
+ "commit",
28
+ "snapshot",
29
+ "status-only",
30
+ ]);
26
31
 
27
32
  export function validatePreferences(preferences: GSDPreferences): {
28
33
  preferences: GSDPreferences;
@@ -161,12 +166,112 @@ export function validatePreferences(preferences: GSDPreferences): {
161
166
  }
162
167
  }
163
168
 
169
+ // ─── UOK Flags ──────────────────────────────────────────────────────
170
+ if (preferences.uok !== undefined) {
171
+ if (typeof preferences.uok === "object" && preferences.uok !== null) {
172
+ const raw = preferences.uok as Record<string, unknown>;
173
+ const valid: NonNullable<GSDPreferences["uok"]> = {};
174
+
175
+ if (raw.enabled !== undefined) {
176
+ if (typeof raw.enabled === "boolean") valid.enabled = raw.enabled;
177
+ else errors.push("uok.enabled must be a boolean");
178
+ }
179
+
180
+ const parseEnabledBlock = (
181
+ key: "legacy_fallback" | "gates" | "model_policy" | "execution_graph" | "audit_unified" | "plan_v2",
182
+ ): void => {
183
+ const value = raw[key];
184
+ if (value === undefined) return;
185
+ if (typeof value !== "object" || value === null) {
186
+ errors.push(`uok.${key} must be an object`);
187
+ return;
188
+ }
189
+ const block = value as Record<string, unknown>;
190
+ const parsed: { enabled?: boolean } = {};
191
+ if (block.enabled !== undefined) {
192
+ if (typeof block.enabled === "boolean") parsed.enabled = block.enabled;
193
+ else errors.push(`uok.${key}.enabled must be a boolean`);
194
+ }
195
+ const unknown = Object.keys(block).filter((k) => k !== "enabled");
196
+ for (const unk of unknown) {
197
+ warnings.push(`unknown uok.${key} key "${unk}" — ignored`);
198
+ }
199
+ if (Object.keys(parsed).length > 0) {
200
+ valid[key] = parsed;
201
+ }
202
+ };
203
+
204
+ parseEnabledBlock("legacy_fallback");
205
+ parseEnabledBlock("gates");
206
+ parseEnabledBlock("model_policy");
207
+ parseEnabledBlock("execution_graph");
208
+ parseEnabledBlock("audit_unified");
209
+ parseEnabledBlock("plan_v2");
210
+
211
+ if (raw.gitops !== undefined) {
212
+ if (typeof raw.gitops !== "object" || raw.gitops === null) {
213
+ errors.push("uok.gitops must be an object");
214
+ } else {
215
+ const gitops = raw.gitops as Record<string, unknown>;
216
+ const parsed: NonNullable<NonNullable<GSDPreferences["uok"]>["gitops"]> = {};
217
+ if (gitops.enabled !== undefined) {
218
+ if (typeof gitops.enabled === "boolean") parsed.enabled = gitops.enabled;
219
+ else errors.push("uok.gitops.enabled must be a boolean");
220
+ }
221
+ if (gitops.turn_action !== undefined) {
222
+ if (
223
+ typeof gitops.turn_action === "string" &&
224
+ VALID_UOK_TURN_ACTIONS.has(gitops.turn_action as "commit" | "snapshot" | "status-only")
225
+ ) {
226
+ parsed.turn_action = gitops.turn_action as "commit" | "snapshot" | "status-only";
227
+ } else {
228
+ errors.push("uok.gitops.turn_action must be one of: commit, snapshot, status-only");
229
+ }
230
+ }
231
+ if (gitops.turn_push !== undefined) {
232
+ if (typeof gitops.turn_push === "boolean") parsed.turn_push = gitops.turn_push;
233
+ else errors.push("uok.gitops.turn_push must be a boolean");
234
+ }
235
+ const unknown = Object.keys(gitops).filter((k) => !["enabled", "turn_action", "turn_push"].includes(k));
236
+ for (const unk of unknown) {
237
+ warnings.push(`unknown uok.gitops key "${unk}" — ignored`);
238
+ }
239
+ if (Object.keys(parsed).length > 0) {
240
+ valid.gitops = parsed;
241
+ }
242
+ }
243
+ }
244
+
245
+ const knownUokKeys = new Set([
246
+ "enabled",
247
+ "legacy_fallback",
248
+ "gates",
249
+ "model_policy",
250
+ "execution_graph",
251
+ "gitops",
252
+ "audit_unified",
253
+ "plan_v2",
254
+ ]);
255
+ for (const key of Object.keys(raw)) {
256
+ if (!knownUokKeys.has(key)) {
257
+ warnings.push(`unknown uok key "${key}" — ignored`);
258
+ }
259
+ }
260
+
261
+ if (Object.keys(valid).length > 0) {
262
+ validated.uok = valid;
263
+ }
264
+ } else {
265
+ errors.push("uok must be an object");
266
+ }
267
+ }
268
+
164
269
  // ─── Token Profile ─────────────────────────────────────────────────
165
270
  if (preferences.token_profile !== undefined) {
166
271
  if (typeof preferences.token_profile === "string" && VALID_TOKEN_PROFILES.has(preferences.token_profile as TokenProfile)) {
167
272
  validated.token_profile = preferences.token_profile as TokenProfile;
168
273
  } else {
169
- errors.push(`token_profile must be one of: budget, balanced, quality`);
274
+ errors.push(`token_profile must be one of: budget, balanced, quality, burn-max`);
170
275
  }
171
276
  }
172
277
 
@@ -50,6 +50,8 @@ export type {
50
50
  AutoSupervisorConfig,
51
51
  RemoteQuestionsConfig,
52
52
  CmuxPreferences,
53
+ UokTurnActionMode,
54
+ UokPreferences,
53
55
  CodebaseMapPreferences,
54
56
  GSDPreferences,
55
57
  LoadedGSDPreferences,
@@ -378,6 +380,32 @@ function mergePreferences(base: GSDPreferences, override: GSDPreferences): GSDPr
378
380
  dynamic_routing: (base.dynamic_routing || override.dynamic_routing)
379
381
  ? { ...(base.dynamic_routing ?? {}), ...(override.dynamic_routing ?? {}) } as DynamicRoutingConfig
380
382
  : undefined,
383
+ uok: (base.uok || override.uok)
384
+ ? {
385
+ enabled: override.uok?.enabled ?? base.uok?.enabled,
386
+ legacy_fallback: (base.uok?.legacy_fallback || override.uok?.legacy_fallback)
387
+ ? { ...(base.uok?.legacy_fallback ?? {}), ...(override.uok?.legacy_fallback ?? {}) }
388
+ : undefined,
389
+ gates: (base.uok?.gates || override.uok?.gates)
390
+ ? { ...(base.uok?.gates ?? {}), ...(override.uok?.gates ?? {}) }
391
+ : undefined,
392
+ model_policy: (base.uok?.model_policy || override.uok?.model_policy)
393
+ ? { ...(base.uok?.model_policy ?? {}), ...(override.uok?.model_policy ?? {}) }
394
+ : undefined,
395
+ execution_graph: (base.uok?.execution_graph || override.uok?.execution_graph)
396
+ ? { ...(base.uok?.execution_graph ?? {}), ...(override.uok?.execution_graph ?? {}) }
397
+ : undefined,
398
+ gitops: (base.uok?.gitops || override.uok?.gitops)
399
+ ? { ...(base.uok?.gitops ?? {}), ...(override.uok?.gitops ?? {}) }
400
+ : undefined,
401
+ audit_unified: (base.uok?.audit_unified || override.uok?.audit_unified)
402
+ ? { ...(base.uok?.audit_unified ?? {}), ...(override.uok?.audit_unified ?? {}) }
403
+ : undefined,
404
+ plan_v2: (base.uok?.plan_v2 || override.uok?.plan_v2)
405
+ ? { ...(base.uok?.plan_v2 ?? {}), ...(override.uok?.plan_v2 ?? {}) }
406
+ : undefined,
407
+ }
408
+ : undefined,
381
409
  token_profile: override.token_profile ?? base.token_profile,
382
410
  phases: (base.phases || override.phases)
383
411
  ? { ...(base.phases ?? {}), ...(override.phases ?? {}) }
@@ -68,11 +68,11 @@ export function getFilePaths(): string[] {
68
68
  * Record a tool call at dispatch time (before execution).
69
69
  * Exit codes and output are filled in by recordToolResult after execution.
70
70
  */
71
- export function recordToolCall(toolName: string, input: Record<string, unknown>): void {
71
+ export function recordToolCall(toolCallId: string, toolName: string, input: Record<string, unknown>): void {
72
72
  if (toolName === "bash" || toolName === "Bash") {
73
73
  unitEvidence.push({
74
74
  kind: "bash",
75
- toolCallId: "",
75
+ toolCallId,
76
76
  command: String(input.command ?? ""),
77
77
  exitCode: -1,
78
78
  outputSnippet: "",
@@ -81,14 +81,14 @@ export function recordToolCall(toolName: string, input: Record<string, unknown>)
81
81
  } else if (toolName === "write" || toolName === "Write") {
82
82
  unitEvidence.push({
83
83
  kind: "write",
84
- toolCallId: "",
84
+ toolCallId,
85
85
  path: String(input.file_path ?? input.path ?? ""),
86
86
  timestamp: Date.now(),
87
87
  });
88
88
  } else if (toolName === "edit" || toolName === "Edit") {
89
89
  unitEvidence.push({
90
90
  kind: "edit",
91
- toolCallId: "",
91
+ toolCallId,
92
92
  path: String(input.file_path ?? input.path ?? ""),
93
93
  timestamp: Date.now(),
94
94
  });
@@ -96,8 +96,9 @@ export function recordToolCall(toolName: string, input: Record<string, unknown>)
96
96
  }
97
97
 
98
98
  /**
99
- * Record a tool execution result. Matches the most recent unresolved entry
100
- * of the same kind and fills in the toolCallId, exit code, and output.
99
+ * Record a tool execution result. Matches the entry by toolCallId (assigned
100
+ * at dispatch time) and fills in exit code + output. Prior versions matched
101
+ * by `kind + empty-string` which corrupted parallel tool calls.
101
102
  */
102
103
  export function recordToolResult(
103
104
  toolCallId: string,
@@ -105,36 +106,19 @@ export function recordToolResult(
105
106
  result: unknown,
106
107
  isError: boolean,
107
108
  ): void {
108
- const normalizedName = toolName.toLowerCase();
109
-
110
- if (normalizedName === "bash") {
111
- const entry = findLastUnresolved("bash") as BashEvidence | undefined;
112
- if (entry) {
113
- entry.toolCallId = toolCallId;
114
- const text = extractResultText(result);
115
- entry.outputSnippet = text.slice(0, 500);
116
- const exitMatch = text.match(/Command exited with code (\d+)/);
117
- entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
118
- }
119
- } else if (normalizedName === "write" || normalizedName === "edit") {
120
- const entry = findLastUnresolved(normalizedName as "write" | "edit");
121
- if (entry) {
122
- entry.toolCallId = toolCallId;
123
- }
109
+ const entry = unitEvidence.find(e => e.toolCallId === toolCallId);
110
+ if (!entry) return;
111
+
112
+ if (entry.kind === "bash") {
113
+ const text = extractResultText(result);
114
+ entry.outputSnippet = text.slice(0, 500);
115
+ const exitMatch = text.match(/Command exited with code (\d+)/);
116
+ entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
124
117
  }
125
118
  }
126
119
 
127
120
  // ─── Internals ──────────────────────────────────────────────────────────────
128
121
 
129
- function findLastUnresolved(kind: string): EvidenceEntry | undefined {
130
- for (let i = unitEvidence.length - 1; i >= 0; i--) {
131
- if (unitEvidence[i].kind === kind && unitEvidence[i].toolCallId === "") {
132
- return unitEvidence[i];
133
- }
134
- }
135
- return undefined;
136
- }
137
-
138
122
  function extractResultText(result: unknown): string {
139
123
  if (typeof result === "string") return result;
140
124
  if (result && typeof result === "object") {
@@ -52,6 +52,18 @@ export interface SessionLockStatus {
52
52
  recovered?: boolean;
53
53
  }
54
54
 
55
+ interface ProperLockfileApi {
56
+ lockSync(
57
+ path: string,
58
+ options?: {
59
+ realpath?: boolean;
60
+ stale?: number;
61
+ update?: number;
62
+ onCompromised?: () => void;
63
+ },
64
+ ): () => void;
65
+ }
66
+
55
67
  // ─── Module State ───────────────────────────────────────────────────────────
56
68
 
57
69
  /** Release function from proper-lockfile — calling it releases the OS lock. */
@@ -277,9 +289,9 @@ export function acquireSessionLock(basePath: string): SessionLockResult {
277
289
  unitStartedAt: new Date().toISOString(),
278
290
  };
279
291
 
280
- let lockfile: typeof import("proper-lockfile");
292
+ let lockfile: ProperLockfileApi;
281
293
  try {
282
- lockfile = _require("proper-lockfile") as typeof import("proper-lockfile");
294
+ lockfile = _require("proper-lockfile") as ProperLockfileApi;
283
295
  } catch {
284
296
  // proper-lockfile not available — fall back to PID-based check
285
297
  return acquireFallbackLock(basePath, lp, lockData);
@@ -32,6 +32,7 @@ import {
32
32
  } from "./session-status-io.js";
33
33
  import { hasFileConflict } from "./slice-parallel-conflict.js";
34
34
  import { getErrorMessage } from "./error-utils.js";
35
+ import { selectConflictFreeBatch } from "./uok/execution-graph.js";
35
36
 
36
37
  // ─── Types ─────────────────────────────────────────────────────────────────
37
38
 
@@ -61,6 +62,7 @@ export interface SliceOrchestratorState {
61
62
  export interface StartSliceParallelOpts {
62
63
  maxWorkers?: number;
63
64
  budgetCeiling?: number;
65
+ useExecutionGraph?: boolean;
64
66
  }
65
67
 
66
68
  // ─── Module State ──────────────────────────────────────────────────────────
@@ -118,7 +120,12 @@ export async function startSliceParallel(
118
120
  const errors: Array<{ sid: string; error: string }> = [];
119
121
 
120
122
  // Filter out conflicting slices (conservative: check all pairs)
121
- const safeSlices = filterConflictingSlices(basePath, milestoneId, eligibleSlices);
123
+ const safeSlices = filterConflictingSlices(
124
+ basePath,
125
+ milestoneId,
126
+ eligibleSlices,
127
+ opts.useExecutionGraph === true,
128
+ );
122
129
 
123
130
  // Limit to maxWorkers
124
131
  const toSpawn = safeSlices.slice(0, maxWorkers);
@@ -245,7 +252,19 @@ function filterConflictingSlices(
245
252
  basePath: string,
246
253
  milestoneId: string,
247
254
  slices: Array<{ id: string }>,
255
+ useExecutionGraph: boolean,
248
256
  ): Array<{ id: string }> {
257
+ if (useExecutionGraph) {
258
+ const selectedIds = selectConflictFreeBatch({
259
+ orderedIds: slices.map((slice) => slice.id),
260
+ maxParallel: slices.length,
261
+ hasConflict: (candidate, existing) =>
262
+ hasFileConflict(basePath, milestoneId, candidate, existing),
263
+ });
264
+ const selected = new Set(selectedIds);
265
+ return slices.filter((slice) => selected.has(slice.id));
266
+ }
267
+
249
268
  const safe: Array<{ id: string }> = [];
250
269
 
251
270
  for (const candidate of slices) {
@@ -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:
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Regression test: invalidateAllCaches() must NOT wipe the artifacts table.
3
+ *
4
+ * Prior to this fix, `cache.ts` bundled `clearArtifacts()` (which runs
5
+ * `DELETE FROM artifacts`) into `invalidateAllCaches()`. That helper fires
6
+ * on every post-unit pass, so rows written by `saveArtifactToDb` and
7
+ * `writeAndStore` (RESEARCH, CONTEXT, VALIDATION, ASSESSMENT, PLAN,
8
+ * ROADMAP, task PLAN, task SUMMARY) got deleted within seconds of being
9
+ * written. The milestone completed on disk, but `SELECT COUNT(*) FROM
10
+ * artifacts` returned 0, and the agent fell into a "file exists but DB
11
+ * record missing" recovery loop.
12
+ *
13
+ * The artifacts table is a write-through store, not a read cache. Routine
14
+ * cache invalidation must preserve its contents.
15
+ *
16
+ * Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
17
+ */
18
+
19
+ import { describe, test, afterEach } from "node:test";
20
+ import assert from "node:assert/strict";
21
+ import { readFileSync } from "node:fs";
22
+ import { resolve } from "node:path";
23
+
24
+ import { invalidateAllCaches } from "../cache.ts";
25
+ import {
26
+ openDatabase,
27
+ closeDatabase,
28
+ insertArtifact,
29
+ isDbAvailable,
30
+ _getAdapter,
31
+ } from "../gsd-db.ts";
32
+
33
+ afterEach(() => {
34
+ if (isDbAvailable()) {
35
+ try {
36
+ closeDatabase();
37
+ } catch {
38
+ /* best-effort teardown */
39
+ }
40
+ }
41
+ });
42
+
43
+ describe("invalidateAllCaches() must preserve the artifacts table", () => {
44
+ test("rows survive a single invalidate call", () => {
45
+ const opened = openDatabase(":memory:");
46
+ assert.equal(opened, true, "in-memory DB must open");
47
+
48
+ insertArtifact({
49
+ path: "milestones/M001/slices/S01/S01-RESEARCH.md",
50
+ artifact_type: "RESEARCH",
51
+ milestone_id: "M001",
52
+ slice_id: "S01",
53
+ task_id: null,
54
+ full_content: "# Research\n\nFindings go here.\n",
55
+ });
56
+
57
+ invalidateAllCaches();
58
+
59
+ const adapter = _getAdapter();
60
+ assert.ok(adapter, "adapter should be available");
61
+ const row = adapter!
62
+ .prepare(
63
+ "SELECT path, artifact_type, length(full_content) AS len FROM artifacts WHERE path = :path",
64
+ )
65
+ .get({ ":path": "milestones/M001/slices/S01/S01-RESEARCH.md" }) as
66
+ | { path: string; artifact_type: string; len: number }
67
+ | undefined;
68
+
69
+ assert.ok(
70
+ row,
71
+ "artifact row must still exist after invalidateAllCaches — this is the Phase B bug",
72
+ );
73
+ assert.equal(row!.artifact_type, "RESEARCH");
74
+ assert.ok((row!.len ?? 0) > 0, "full_content must not be truncated");
75
+ });
76
+
77
+ test("multiple rows for a full milestone survive repeated invalidates", () => {
78
+ openDatabase(":memory:");
79
+
80
+ const inserts = [
81
+ {
82
+ path: "milestones/M001/M001-ROADMAP.md",
83
+ artifact_type: "ROADMAP",
84
+ milestone_id: "M001",
85
+ slice_id: null,
86
+ task_id: null,
87
+ },
88
+ {
89
+ path: "milestones/M001/slices/S01/S01-RESEARCH.md",
90
+ artifact_type: "RESEARCH",
91
+ milestone_id: "M001",
92
+ slice_id: "S01",
93
+ task_id: null,
94
+ },
95
+ {
96
+ path: "milestones/M001/slices/S01/S01-PLAN.md",
97
+ artifact_type: "PLAN",
98
+ milestone_id: "M001",
99
+ slice_id: "S01",
100
+ task_id: null,
101
+ },
102
+ {
103
+ path: "milestones/M001/slices/S01/tasks/T01-PLAN.md",
104
+ artifact_type: "PLAN",
105
+ milestone_id: "M001",
106
+ slice_id: "S01",
107
+ task_id: "T01",
108
+ },
109
+ {
110
+ path: "milestones/M001/slices/S01/tasks/T01-SUMMARY.md",
111
+ artifact_type: "SUMMARY",
112
+ milestone_id: "M001",
113
+ slice_id: "S01",
114
+ task_id: "T01",
115
+ },
116
+ {
117
+ path: "milestones/M001/M001-SUMMARY.md",
118
+ artifact_type: "SUMMARY",
119
+ milestone_id: "M001",
120
+ slice_id: null,
121
+ task_id: null,
122
+ },
123
+ ];
124
+
125
+ for (const i of inserts) {
126
+ insertArtifact({ ...i, full_content: `# ${i.artifact_type} content\n` });
127
+ }
128
+
129
+ // Simulate a full milestone's worth of post-unit cycles.
130
+ for (let i = 0; i < 10; i++) {
131
+ invalidateAllCaches();
132
+ }
133
+
134
+ const adapter = _getAdapter()!;
135
+ const count = (
136
+ adapter.prepare("SELECT COUNT(*) AS n FROM artifacts").get() as { n: number }
137
+ ).n;
138
+
139
+ assert.equal(
140
+ count,
141
+ inserts.length,
142
+ `all ${inserts.length} artifact rows must survive repeated invalidate calls; got ${count}`,
143
+ );
144
+ });
145
+ });
146
+
147
+ describe("cache.ts must not re-import clearArtifacts into invalidateAllCaches", () => {
148
+ const src = readFileSync(
149
+ resolve(process.cwd(), "src", "resources", "extensions", "gsd", "cache.ts"),
150
+ "utf-8",
151
+ );
152
+
153
+ test("clearArtifacts is not imported from gsd-db", () => {
154
+ assert.ok(
155
+ !/import\s*\{[^}]*clearArtifacts[^}]*\}\s*from\s*['"]\.\/gsd-db/.test(src),
156
+ "cache.ts must not import clearArtifacts — it causes the artifacts-table-wipe regression",
157
+ );
158
+ });
159
+
160
+ test("invalidateAllCaches does not call clearArtifacts", () => {
161
+ const fnIdx = src.indexOf("function invalidateAllCaches");
162
+ assert.ok(fnIdx !== -1);
163
+ const body = src.slice(fnIdx, fnIdx + 1000);
164
+ assert.ok(
165
+ !/\bclearArtifacts\s*\(/.test(body),
166
+ "invalidateAllCaches must not call clearArtifacts() — it wipes the write-through store",
167
+ );
168
+ });
169
+
170
+ test("cache.ts documents why clearArtifacts is not bundled here", () => {
171
+ // Future reviewers need to see the rationale or they'll re-add it.
172
+ assert.ok(
173
+ /artifacts.*NOT included|write-through store/i.test(src),
174
+ "cache.ts must explain why the artifacts table is NOT invalidated here",
175
+ );
176
+ });
177
+ });
@@ -1267,7 +1267,7 @@ test("auto-loop.ts barrel re-exports autoLoop, runUnit, and resolveAgentEnd", ()
1267
1267
  );
1268
1268
  });
1269
1269
 
1270
- test("auto.ts startAuto calls autoLoop (not dispatchNextUnit as first dispatch)", () => {
1270
+ test("auto.ts startAuto dispatches through the UOK kernel wrapper (legacy loop adapter)", () => {
1271
1271
  const src = readFileSync(
1272
1272
  resolve(import.meta.dirname, "..", "auto.ts"),
1273
1273
  "utf-8",
@@ -1279,8 +1279,12 @@ test("auto.ts startAuto calls autoLoop (not dispatchNextUnit as first dispatch)"
1279
1279
  const fnBlock =
1280
1280
  fnEnd > -1 ? src.slice(fnIdx, fnEnd) : src.slice(fnIdx, fnIdx + 5000);
1281
1281
  assert.ok(
1282
- fnBlock.includes("autoLoop("),
1283
- "startAuto must call autoLoop() instead of dispatchNextUnit()",
1282
+ fnBlock.includes("runAutoLoopWithUok("),
1283
+ "startAuto must dispatch through runAutoLoopWithUok()",
1284
+ );
1285
+ assert.ok(
1286
+ fnBlock.includes("runLegacyLoop: autoLoop"),
1287
+ "startAuto must preserve the legacy autoLoop adapter in kernel dispatch",
1284
1288
  );
1285
1289
  });
1286
1290
 
@@ -227,6 +227,26 @@ test("model change notify in selectAndApplyModel is gated behind verbose flag",
227
227
  );
228
228
  });
229
229
 
230
+ test("model policy resolves candidates from the policy-eligible pool", () => {
231
+ const src = readFileSync(join(__dirname, "..", "auto-model-selection.ts"), "utf-8");
232
+ assert.ok(
233
+ src.includes("const resolutionPool = uokFlags.modelPolicy ? routingEligibleModels : availableModels"),
234
+ "selectAndApplyModel should resolve model IDs against policy-eligible models when model policy is enabled",
235
+ );
236
+ });
237
+
238
+ test("model policy receives task metadata for requirement-vector decisions", () => {
239
+ const src = readFileSync(join(__dirname, "..", "auto-model-selection.ts"), "utf-8");
240
+ assert.ok(
241
+ src.includes("taskMetadata: taskMetadataForPolicy"),
242
+ "applyModelPolicyFilter should receive task metadata so requirement vectors are unit-aware",
243
+ );
244
+ assert.ok(
245
+ src.includes("extractTaskMetadata(unitId, basePath)"),
246
+ "execute-task dispatch should derive metadata before policy filtering",
247
+ );
248
+ });
249
+
230
250
  test("resolveModelId: anthropic wins over claude-code when session provider is not claude-code", () => {
231
251
  const availableModels = [
232
252
  { id: "claude-sonnet-4-6", provider: "claude-code" },
@@ -13,11 +13,15 @@ test("auto-mode captures GSD_PROJECT_ROOT before entering the dispatch loop", ()
13
13
  const resumeCallIdx = source.indexOf("captureProjectRootEnv(s.originalBasePath || s.basePath);");
14
14
  assert.ok(resumeCallIdx > -1, "auto.ts should capture GSD_PROJECT_ROOT before resume autoLoop");
15
15
 
16
- const firstAutoLoopIdx = source.indexOf("await autoLoop(ctx, pi, s, buildLoopDeps());");
17
- assert.ok(firstAutoLoopIdx > -1, "auto.ts should invoke autoLoop()");
16
+ const firstLoopIdxCandidates = [
17
+ source.indexOf("await runAutoLoopWithUok({"),
18
+ source.indexOf("await autoLoop(ctx, pi, s, buildLoopDeps());"),
19
+ ].filter((idx) => idx > -1);
20
+ const firstAutoLoopIdx = firstLoopIdxCandidates.length > 0 ? Math.min(...firstLoopIdxCandidates) : -1;
21
+ assert.ok(firstAutoLoopIdx > -1, "auto.ts should invoke the auto dispatch loop");
18
22
  assert.ok(
19
23
  resumeCallIdx < firstAutoLoopIdx,
20
- "auto.ts must set GSD_PROJECT_ROOT before the first autoLoop() call",
24
+ "auto.ts must set GSD_PROJECT_ROOT before the first loop call",
21
25
  );
22
26
  });
23
27