@aiwg/cli 2026.10.1 → 2026.10.4

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 (361) hide show
  1. package/README.md +2 -2
  2. package/agentic/code/providers/capability-matrix.yaml +270 -0
  3. package/agentic/code/providers/model-capabilities.v1.json +3183 -24
  4. package/bin/aiwg.mjs +135 -47
  5. package/dist/src/a2a/codecs.js +9 -0
  6. package/dist/src/agents/grounding/knowledge-base.js +54 -6
  7. package/dist/src/artifacts/browser-export.js +6 -0
  8. package/dist/src/artifacts/checksum-manifest.js +1 -0
  9. package/dist/src/artifacts/citation-parser.js +173 -92
  10. package/dist/src/artifacts/citation-table-schema.js +59 -0
  11. package/dist/src/artifacts/cli.js +57 -18
  12. package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
  13. package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
  14. package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
  15. package/dist/src/artifacts/corpus-views/renderers.js +3 -3
  16. package/dist/src/artifacts/discovery-eval.js +6 -4
  17. package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
  18. package/dist/src/artifacts/fortemi-core-sync.js +166 -40
  19. package/dist/src/artifacts/framework-capabilities.js +171 -0
  20. package/dist/src/artifacts/framework-index-paths.js +73 -0
  21. package/dist/src/artifacts/framework-source-digest.js +75 -0
  22. package/dist/src/artifacts/index-builder.js +285 -131
  23. package/dist/src/artifacts/index-files.js +132 -18
  24. package/dist/src/artifacts/index-preparation.js +65 -0
  25. package/dist/src/artifacts/index-refresh.js +576 -0
  26. package/dist/src/artifacts/index-worker.mjs +9 -0
  27. package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
  28. package/dist/src/artifacts/prebuilt-deployment.js +46 -0
  29. package/dist/src/artifacts/prebuilt-relations.js +80 -0
  30. package/dist/src/artifacts/query-engine.js +410 -88
  31. package/dist/src/artifacts/relations-builder.js +168 -0
  32. package/dist/src/artifacts/relations.js +148 -0
  33. package/dist/src/artifacts/repair.js +9 -4
  34. package/dist/src/artifacts/stats.js +5 -2
  35. package/dist/src/artifacts/types.js +30 -10
  36. package/dist/src/artifacts/watcher.js +1 -1
  37. package/dist/src/auth/credential-store.js +2 -1
  38. package/dist/src/catalog/cli.d.mts +5 -0
  39. package/dist/src/channel/manager.d.mts +20 -0
  40. package/dist/src/channel/manager.mjs +78 -12
  41. package/dist/src/cli/child-process-result.js +40 -0
  42. package/dist/src/cli/command-log.js +2 -3
  43. package/dist/src/cli/env.js +38 -16
  44. package/dist/src/cli/flag-parsing.js +236 -0
  45. package/dist/src/cli/handlers/artifacts.js +3 -0
  46. package/dist/src/cli/handlers/auth.js +3 -0
  47. package/dist/src/cli/handlers/decision.js +218 -5
  48. package/dist/src/cli/handlers/diagnose.js +13 -5
  49. package/dist/src/cli/handlers/effect.js +4 -2
  50. package/dist/src/cli/handlers/evidence.js +3 -0
  51. package/dist/src/cli/handlers/feedback.js +14 -5
  52. package/dist/src/cli/handlers/help.js +1 -0
  53. package/dist/src/cli/handlers/index.js +3 -1
  54. package/dist/src/cli/handlers/init.js +248 -30
  55. package/dist/src/cli/handlers/lint.js +5 -0
  56. package/dist/src/cli/handlers/mc.js +23 -0
  57. package/dist/src/cli/handlers/models.js +169 -10
  58. package/dist/src/cli/handlers/ralph-launcher.js +2 -0
  59. package/dist/src/cli/handlers/ralph.js +3 -0
  60. package/dist/src/cli/handlers/refresh.js +28 -0
  61. package/dist/src/cli/handlers/regenerate.js +14 -0
  62. package/dist/src/cli/handlers/resource-versions.js +3 -0
  63. package/dist/src/cli/handlers/rules.js +195 -0
  64. package/dist/src/cli/handlers/run.js +4 -0
  65. package/dist/src/cli/handlers/runtime-info.js +25 -11
  66. package/dist/src/cli/handlers/script-runner.js +19 -8
  67. package/dist/src/cli/handlers/session.js +406 -62
  68. package/dist/src/cli/handlers/sessions.js +243 -76
  69. package/dist/src/cli/handlers/setup-manifest.js +474 -79
  70. package/dist/src/cli/handlers/setup.js +180 -39
  71. package/dist/src/cli/handlers/steward.js +11 -0
  72. package/dist/src/cli/handlers/subcommands.js +60 -3
  73. package/dist/src/cli/handlers/team.js +18 -8
  74. package/dist/src/cli/handlers/uhp.js +3 -0
  75. package/dist/src/cli/handlers/use.js +307 -55
  76. package/dist/src/cli/handlers/utilities.js +125 -26
  77. package/dist/src/cli/handlers/version.js +8 -0
  78. package/dist/src/cli/prompt-utils.js +72 -0
  79. package/dist/src/cli/provider-resolution.js +11 -0
  80. package/dist/src/cli/router.js +15 -1
  81. package/dist/src/cli/services/deployment-verification.js +19 -9
  82. package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
  83. package/dist/src/cli/skill-usage.js +2 -3
  84. package/dist/src/config/aiwg-config.js +349 -35
  85. package/dist/src/config/cli.js +256 -23
  86. package/dist/src/config/decision-config.js +106 -0
  87. package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
  88. package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
  89. package/dist/src/config/gitignore.js +50 -0
  90. package/dist/src/config/index-graph-overrides.js +36 -0
  91. package/dist/src/config/project-artifacts-health.d.mts +37 -0
  92. package/dist/src/config/project-artifacts-health.mjs +14 -3
  93. package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
  94. package/dist/src/config/user-config-dir.d.mts +9 -0
  95. package/dist/src/config/user-config.js +38 -11
  96. package/dist/src/config/user-registry.js +23 -15
  97. package/dist/src/config/user-state.js +7 -0
  98. package/dist/src/decision/adapters/jev.js +75 -27
  99. package/dist/src/decision/ask.js +203 -43
  100. package/dist/src/decision/context-live-qualification.js +2 -2
  101. package/dist/src/decision/driver.js +14 -7
  102. package/dist/src/decision/ensemble/aggregate.js +23 -10
  103. package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
  104. package/dist/src/decision/entry.js +25 -6
  105. package/dist/src/decision/graph-live-qualification.js +1 -1
  106. package/dist/src/decision/graph-run.js +9 -0
  107. package/dist/src/decision/heldout/collector.js +15 -14
  108. package/dist/src/decision/heldout/contract.js +30 -7
  109. package/dist/src/decision/index.js +1 -0
  110. package/dist/src/decision/interop.js +60 -8
  111. package/dist/src/decision/jev-credentials.js +15 -1
  112. package/dist/src/decision/ledger.js +942 -0
  113. package/dist/src/decision/offload-activation.js +137 -0
  114. package/dist/src/decision/offload.js +550 -0
  115. package/dist/src/decision/qualification/load.js +4 -6
  116. package/dist/src/decision/savings.js +28 -0
  117. package/dist/src/decision/validate.js +6 -3
  118. package/dist/src/effects/dispatch-verifier.js +252 -0
  119. package/dist/src/effects/index.js +1 -0
  120. package/dist/src/effects/types.js +5 -1
  121. package/dist/src/effects/verifiers/git.js +2 -1
  122. package/dist/src/effects/verifiers/tracker.js +26 -14
  123. package/dist/src/extensions/commands/definitions.js +19 -0
  124. package/dist/src/extensions/project-local-remove.js +36 -1
  125. package/dist/src/features/installer.js +2 -2
  126. package/dist/src/flow/graph-metadata.js +5 -0
  127. package/dist/src/gates/providers/loader.js +64 -18
  128. package/dist/src/installation/manager-command.d.mts +18 -0
  129. package/dist/src/installation/manager-command.mjs +15 -3
  130. package/dist/src/installation/manager.d.mts +49 -0
  131. package/dist/src/installation/manager.mjs +95 -5
  132. package/dist/src/issues/cli.js +4 -4
  133. package/dist/src/issues/local.js +24 -5
  134. package/dist/src/jobs/runner.js +1 -1
  135. package/dist/src/lint/cli.js +27 -1
  136. package/dist/src/lint/loader.js +2 -1
  137. package/dist/src/lint/reporters.js +25 -1
  138. package/dist/src/lint/rule-activation.js +43 -0
  139. package/dist/src/lint/runner.js +137 -62
  140. package/dist/src/mcp/adapters/codex-runtime.js +366 -56
  141. package/dist/src/mcp/claude-install.d.mts +4 -0
  142. package/dist/src/mcp/claude-install.mjs +41 -0
  143. package/dist/src/mcp/cli.d.mts +1 -0
  144. package/dist/src/mcp/cli.mjs +620 -85
  145. package/dist/src/mcp/config-file.d.mts +28 -0
  146. package/dist/src/mcp/config-file.mjs +279 -0
  147. package/dist/src/mcp/config-layers.d.mts +36 -0
  148. package/dist/src/mcp/config-layers.mjs +348 -0
  149. package/dist/src/mcp/credentials.d.mts +51 -0
  150. package/dist/src/mcp/credentials.mjs +484 -0
  151. package/dist/src/mcp/grok-build-config.d.mts +6 -0
  152. package/dist/src/mcp/grok-build-config.mjs +17 -27
  153. package/dist/src/mcp/helpers.mjs +109 -4
  154. package/dist/src/mcp/muse-native-config.d.mts +13 -0
  155. package/dist/src/mcp/muse-native-config.mjs +1 -0
  156. package/dist/src/mcp/omp-config.d.mts +4 -0
  157. package/dist/src/mcp/omp-config.mjs +50 -29
  158. package/dist/src/mcp/profiles.js +97 -23
  159. package/dist/src/mcp/profiles.mjs +99 -27
  160. package/dist/src/mcp/registry.js +248 -131
  161. package/dist/src/mcp/registry.mjs +169 -100
  162. package/dist/src/mcp/server-config.d.mts +3 -0
  163. package/dist/src/mcp/server-config.mjs +89 -0
  164. package/dist/src/mcp/server.mjs +127 -82
  165. package/dist/src/mcp/test-simple.mjs +2 -1
  166. package/dist/src/mcp/toml-editor.d.mts +4 -0
  167. package/dist/src/mcp/toml-string.d.mts +1 -0
  168. package/dist/src/mcp/toml-string.mjs +9 -0
  169. package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
  170. package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
  171. package/dist/src/mcp/tool-filters.d.mts +46 -0
  172. package/dist/src/mcp/tool-filters.mjs +357 -0
  173. package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
  174. package/dist/src/mcp/tools/decision.mjs +22 -3
  175. package/dist/src/mcp/tools/discovery.mjs +62 -55
  176. package/dist/src/mcp/tools/orchestration.mjs +50 -2
  177. package/dist/src/mcp/tools/subsystems.mjs +39 -8
  178. package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
  179. package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
  180. package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
  181. package/dist/src/memory/project-registry.js +2 -2
  182. package/dist/src/mission-protocol/codecs.js +647 -1
  183. package/dist/src/mission-protocol/types.js +110 -0
  184. package/dist/src/mission-protocol/worker-status.js +2 -0
  185. package/dist/src/models/config-loader.js +76 -14
  186. package/dist/src/models/grok-build-models.js +93 -41
  187. package/dist/src/models/model-capabilities.v1.json +3183 -24
  188. package/dist/src/models/model-discovery.js +931 -67
  189. package/dist/src/models/provider-policy.js +719 -11
  190. package/dist/src/models/qualification-digest.d.mts +2 -0
  191. package/dist/src/models/qualification-digest.mjs +17 -0
  192. package/dist/src/models/resolver.js +261 -0
  193. package/dist/src/models/worker-direct-readiness.js +550 -0
  194. package/dist/src/models/worker-dispatch-offer.js +169 -0
  195. package/dist/src/models/worker-health-readiness.js +144 -0
  196. package/dist/src/models/worker-installation.d.mts +39 -0
  197. package/dist/src/models/worker-installation.mjs +986 -0
  198. package/dist/src/models/wrapper-route.js +18 -0
  199. package/dist/src/ops/registry.js +9 -14
  200. package/dist/src/plugins/standalone-packager.js +4 -3
  201. package/dist/src/process/bounded-child-process.d.mts +84 -0
  202. package/dist/src/process/bounded-child-process.mjs +430 -0
  203. package/dist/src/process/cli-command.d.mts +16 -0
  204. package/dist/src/process/cli-command.mjs +75 -0
  205. package/dist/src/process/signal-child.d.mts +6 -0
  206. package/dist/src/process/signal-child.mjs +7 -0
  207. package/dist/src/providers/capability-matrix.js +8 -0
  208. package/dist/src/providers/capability-matrix.yaml +270 -0
  209. package/dist/src/providers/deployed-skill-roots.js +20 -0
  210. package/dist/src/providers/grok-build-acp.js +3 -2
  211. package/dist/src/providers/grok-build-headless.js +53 -23
  212. package/dist/src/providers/grok-build-inspect.js +1 -0
  213. package/dist/src/providers/omp-agent.d.mts +8 -0
  214. package/dist/src/providers/omp-diagnostics.d.mts +1 -0
  215. package/dist/src/providers/omp-paths.d.mts +13 -0
  216. package/dist/src/providers/provider-definitions.js +9 -1
  217. package/dist/src/providers/provider-definitions.mjs +9 -2
  218. package/dist/src/providers/skill-ownership.d.mts +9 -0
  219. package/dist/src/providers/skill-ownership.mjs +88 -0
  220. package/dist/src/rules/activation.d.mts +21 -0
  221. package/dist/src/rules/activation.mjs +62 -0
  222. package/dist/src/rules/inline-budget.d.mts +26 -0
  223. package/dist/src/rules/inline-budget.mjs +66 -0
  224. package/dist/src/rules/inventory.js +129 -0
  225. package/dist/src/rules/pin-state.js +73 -0
  226. package/dist/src/rules/pins.d.mts +14 -0
  227. package/dist/src/rules/pins.mjs +112 -0
  228. package/dist/src/rules/rule-frontmatter.schema.json +197 -0
  229. package/dist/src/serve/executor-registry.js +16 -24
  230. package/dist/src/serve/fleet-mission-conductor.js +9 -0
  231. package/dist/src/serve/mission-conductor.js +47 -12
  232. package/dist/src/serve/shared-host-scheduler.js +2 -0
  233. package/dist/src/serve/worker-invocation.js +558 -0
  234. package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
  235. package/dist/src/serve/worker-stdin-frame.mjs +107 -0
  236. package/dist/src/sessions/adapter-registry.js +49 -0
  237. package/dist/src/sessions/adapters/claude.js +39 -54
  238. package/dist/src/sessions/adapters/codex.js +82 -67
  239. package/dist/src/sessions/adapters/copilot.js +4 -4
  240. package/dist/src/sessions/adapters/cursor.js +40 -57
  241. package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
  242. package/dist/src/sessions/adapters/factory.js +31 -27
  243. package/dist/src/sessions/adapters/generic.js +43 -9
  244. package/dist/src/sessions/adapters/grok-build.js +11 -11
  245. package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
  246. package/dist/src/sessions/adapters/grokbot.js +434 -24
  247. package/dist/src/sessions/adapters/hermes.js +27 -29
  248. package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
  249. package/dist/src/sessions/adapters/muse.js +200 -104
  250. package/dist/src/sessions/adapters/omp.js +28 -14
  251. package/dist/src/sessions/adapters/openclaw.js +89 -79
  252. package/dist/src/sessions/adapters/opencode.js +27 -24
  253. package/dist/src/sessions/adapters/openhuman.js +18 -60
  254. package/dist/src/sessions/adapters/pi.js +30 -14
  255. package/dist/src/sessions/adapters/warp.js +3 -3
  256. package/dist/src/sessions/adapters/windsurf.js +19 -48
  257. package/dist/src/sessions/batch-contracts.js +25 -5
  258. package/dist/src/sessions/batch-import.js +72 -51
  259. package/dist/src/sessions/candidates.js +47 -11
  260. package/dist/src/sessions/contracts.js +75 -2
  261. package/dist/src/sessions/coverage-preflight.js +134 -0
  262. package/dist/src/sessions/discovery.js +3 -0
  263. package/dist/src/sessions/export-plan.js +4 -3
  264. package/dist/src/sessions/grok-build-cli.js +67 -5
  265. package/dist/src/sessions/import-exclusions.js +72 -0
  266. package/dist/src/sessions/import-lease.js +34 -18
  267. package/dist/src/sessions/import-limits.js +37 -0
  268. package/dist/src/sessions/importer.js +84 -46
  269. package/dist/src/sessions/index.js +2 -0
  270. package/dist/src/sessions/lifecycle.js +45 -0
  271. package/dist/src/sessions/policy.js +133 -25
  272. package/dist/src/sessions/readers.js +106 -53
  273. package/dist/src/sessions/refresh.js +106 -0
  274. package/dist/src/sessions/repository.js +199 -63
  275. package/dist/src/sessions/workspace-discovery.js +315 -88
  276. package/dist/src/sessions/workspace-matching.js +107 -0
  277. package/dist/src/skills/adapters/clawhub.js +10 -8
  278. package/dist/src/skills/adapters/openclaw.js +10 -7
  279. package/dist/src/skills/importer.js +1 -0
  280. package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
  281. package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
  282. package/dist/src/smiths/context-pipeline/finalization.js +6 -5
  283. package/dist/src/smiths/context-pipeline/generator.js +21 -4
  284. package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
  285. package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
  286. package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
  287. package/dist/src/smiths/mcpsmith/example.js +1 -1
  288. package/dist/src/smiths/mcpsmith/generator.js +1 -1
  289. package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
  290. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
  291. package/dist/src/storage/backends/fs.js +18 -76
  292. package/dist/src/storage/backends/logseq.js +68 -7
  293. package/dist/src/storage/backends/obsidian.js +1 -0
  294. package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
  295. package/dist/src/testing/generators/test-code-generator.js +57 -30
  296. package/dist/src/tracker/forge-http.js +2 -1
  297. package/dist/src/uhp/client.js +11 -1
  298. package/dist/src/uhp/mission.js +5 -0
  299. package/dist/src/update/checker.d.mts +2 -0
  300. package/dist/src/update/checker.mjs +5 -5
  301. package/dist/src/update/notifier.mjs +54 -2
  302. package/dist/src/update/service.d.mts +22 -0
  303. package/dist/src/utils/contained-filesystem.d.mts +37 -0
  304. package/dist/src/utils/contained-filesystem.mjs +683 -0
  305. package/dist/src/utils/temporary-directory.js +36 -0
  306. package/dist/src/writing/example-generator.js +1 -1
  307. package/dist/src/writing/fidelity.js +18 -1
  308. package/package.json +32 -2
  309. package/schemas/mission-v1.schema.json +2429 -0
  310. package/schemas/models/model-catalog.v1.schema.json +301 -0
  311. package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
  312. package/schemas/models/model-policy.v1.schema.json +14 -0
  313. package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
  314. package/tools/_resolve-impl.mjs +39 -2
  315. package/tools/agents/deploy-agents.mjs +64 -23
  316. package/tools/agents/providers/base.mjs +153 -166
  317. package/tools/agents/providers/claude.mjs +8 -24
  318. package/tools/agents/providers/codex.mjs +18 -11
  319. package/tools/agents/providers/cursor.mjs +19 -18
  320. package/tools/agents/providers/grok-build.mjs +3 -1
  321. package/tools/agents/providers/grokbot.mjs +11 -12
  322. package/tools/agents/providers/hermes.mjs +62 -49
  323. package/tools/agents/providers/omp.mjs +5 -2
  324. package/tools/agents/providers/openclaw-translator.mjs +19 -5
  325. package/tools/agents/providers/openclaw.mjs +9 -4
  326. package/tools/agents/providers/pi.mjs +5 -0
  327. package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
  328. package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
  329. package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
  330. package/tools/agents/providers/rule-delivery.mjs +1270 -0
  331. package/tools/agents/providers/warp.mjs +20 -26
  332. package/tools/cli/decision-offload-report.mjs +40 -0
  333. package/tools/cli/workspace-status.mjs +862 -0
  334. package/tools/plugin/package-plugins.mjs +186 -8
  335. package/tools/plugin/plugin-links.mjs +114 -0
  336. package/tools/providers/antigravity-transport.mjs +3 -1
  337. package/tools/providers/deepseek-harness-transport.mjs +360 -0
  338. package/tools/providers/omp-transport.mjs +194 -0
  339. package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
  340. package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
  341. package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
  342. package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
  343. package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
  344. package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
  345. package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
  346. package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
  347. package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
  348. package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
  349. package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
  350. package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
  351. package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
  352. package/tools/ralph-external/lib/session-environment.mjs +28 -0
  353. package/tools/ralph-external/lib/systemd-client.mjs +49 -0
  354. package/tools/ralph-external/lib/worker-health.mjs +439 -0
  355. package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
  356. package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
  357. package/tools/ralph-external/process-monitor.mjs +1017 -0
  358. package/tools/ralph-external/session-launcher.mjs +5057 -0
  359. package/tools/scripts/resource-preflight.mjs +541 -0
  360. package/tools/skills/deploy-skills-codex.mjs +2 -1
  361. package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
@@ -1,3 +1,4 @@
1
+ import { trackTemporaryDirectory } from '../../utils/temporary-directory.js';
1
2
  /**
2
3
  * Use Command Handler
3
4
  *
@@ -13,9 +14,12 @@ import fs from 'fs/promises';
13
14
  import path from 'path';
14
15
  import os from 'os';
15
16
  import { pathToFileURL } from 'node:url';
17
+ import { createHash, randomUUID } from 'node:crypto';
18
+ import { canDeploySkill, sameSkillOwner, extractFrameworkSlug } from '../../providers/skill-ownership.mjs';
16
19
  import { resolveOmpPaths } from '../../providers/omp-paths.mjs';
17
20
  import YAML from 'yaml';
18
21
  import { createScriptRunner } from './script-runner.js';
22
+ import { finalizePreparedProvider, prepareProviderDeployments } from '../services/provider-prepare-coordinator.js';
19
23
  import { getFrameworkRoot, getVersionInfo } from '../../channel/manager.mjs';
20
24
  import { getRegistry } from '../../extensions/registry.js';
21
25
  import { registerDeployedExtensions } from '../../extensions/deployment-registration.js';
@@ -39,6 +43,7 @@ import { detectScope, mirrorToUserScope, rejectOpenClawProjectScope, USER_SCOPE_
39
43
  import { maybeWarnProjectIsolation } from '../project-isolation/index.js';
40
44
  import { formatWorkspaceSignalPlan, includedBundleIds, resolveWorkspaceSignalPlan, writeWorkspaceSignalPlan, } from '../workspace-signals.js';
41
45
  import { getProviderArtifactPathStrings, getProviderDefinition, getProviderKernelSkillPath, normalizeProviderDefinitionId, } from '../../providers/provider-definitions.js';
46
+ import { deployedSkillRoots } from '../../providers/deployed-skill-roots.js';
42
47
  // Module-level guard so the iteration loops further down (which re-enter
43
48
  // execute() per framework/provider) don't re-emit the warning each pass.
44
49
  // Reset is not needed: a single CLI process is one user invocation.
@@ -47,12 +52,14 @@ let projectIsolationChecked = false;
47
52
  // collecting child-process output. The CLI is single-command-per-process;
48
53
  // recursive provider expansion shares this guard intentionally.
49
54
  let machineReadableUseDepth = 0;
55
+ // Providers whose complete project projection is covered by the transferable
56
+ // rule-delivery transaction. Other built-ins retain their serial deploy path.
57
+ const PREPARABLE_BUILTIN_PROVIDERS = new Set(['claude', 'codex', 'cursor', 'hermes', 'pi', 'warp']);
50
58
  // Context-pipeline: emits WORKSPACE.md + AIWG.md + provider adapters last.
51
59
  // for non-Claude providers per ADR-1 (.aiwg/architecture/adr-agents-md-aggregation.md).
52
60
  // Distinct from agentsmith (which creates subagent personas).
53
61
  import { generate as generateContextFiles, discoverDeployedArtifacts, } from '../../smiths/context-pipeline/index.js';
54
62
  import { verifyModelWrapperDeployment } from '../../models/wrapper-deployment.js';
55
- import { loadGraphIndexFile } from '../../artifacts/index-reader.js';
56
63
  import { aggregateUseDeploymentResult, buildDryRunUseResult, renderUseDeploymentResult, verifyProviderDeployment, } from '../services/deployment-verification.js';
57
64
  import { finalizeProviderTransformationReceipt, providerReceiptHasLocalSources, sourceVerificationsFromSignedWebRelease, } from '../../providers/transformation-receipt-integration.js';
58
65
  import { loadResourceTrustRootFile, resolveWebRelease, } from '../../resources/web-release.js';
@@ -145,6 +152,11 @@ const MODEL_OVERRIDE_VALUE_FLAGS = new Set([
145
152
  '--model', '--reasoning-model', '--coding-model', '--efficiency-model', '--model-tier',
146
153
  ]);
147
154
  const MODEL_DEPLOY_BOOLEAN_FLAGS = new Set(['--save', '--save-user']);
155
+ /** Forward explicit user scope to every provider deploy subprocess. */
156
+ export function collectUseScopeDeployArgs(args) {
157
+ const scope = detectScope(args);
158
+ return scope === 'user' || args.includes('--user') ? ['--scope', 'user'] : [];
159
+ }
148
160
  export function collectUseModelDeployArgs(args) {
149
161
  const forwarded = [];
150
162
  for (let i = 0; i < args.length; i++) {
@@ -241,7 +253,7 @@ const FRAMEWORK_DIR_MAP = {
241
253
  all: 'sdlc-complete',
242
254
  };
243
255
  /** Resolve actual framework directory name for a given user-facing name. */
244
- function resolveFrameworkDir(framework) {
256
+ export function resolveFrameworkDir(framework) {
245
257
  return FRAMEWORK_DIR_MAP[framework];
246
258
  }
247
259
  /**
@@ -392,6 +404,18 @@ export function addonPath(frameworkRoot, name) {
392
404
  const folderName = resolveAddonFolderName(name);
393
405
  return path.join(frameworkRoot, 'agentic/code/addons', folderName);
394
406
  }
407
+ /**
408
+ * Whether the provider's root deployment already collects every eligible
409
+ * addon for this mode. The caller still registers addon CLI contributions;
410
+ * this only suppresses redundant deploy-agents subprocesses.
411
+ */
412
+ export function mainDeploymentIncludesAddons(provider, selectedMode, providerDeployArgs) {
413
+ return (((provider === 'claude' || provider === 'pi')
414
+ && ['general', 'sdlc', 'both', 'all'].includes(selectedMode))
415
+ || (provider === 'codex' && selectedMode === 'all'))
416
+ && !providerDeployArgs.some(arg => arg === '--source' || arg.startsWith('--source='))
417
+ && providerDeployArgs.filter(arg => arg === '--mode').length === 1;
418
+ }
395
419
  /**
396
420
  * Resolve a selected addon's required addon dependencies in deterministic
397
421
  * dependency-first order. Optional dependencies remain descriptive and are
@@ -1042,17 +1066,11 @@ async function listBundleSkillNameCandidates(bundlePath) {
1042
1066
  return [];
1043
1067
  }
1044
1068
  }
1045
- async function countDeployedBundleSkills(bundlePath, target, provider, paths) {
1069
+ async function countDeployedBundleSkills(bundlePath, target, provider) {
1046
1070
  const skillCandidates = await listBundleSkillNameCandidates(bundlePath);
1047
1071
  if (skillCandidates.length === 0)
1048
1072
  return 0;
1049
- const candidateDirs = [
1050
- paths.skills,
1051
- getProviderKernelSkillsPath(provider),
1052
- ]
1053
- .filter(Boolean)
1054
- .map(dir => resolveDeployPath(target, dir));
1055
- const uniqueCandidateDirs = [...new Set(candidateDirs)];
1073
+ const uniqueCandidateDirs = deployedSkillRoots(target, provider);
1056
1074
  let count = 0;
1057
1075
  for (const names of skillCandidates) {
1058
1076
  let found = false;
@@ -1075,16 +1093,35 @@ async function countBundleDeployedArtifacts(bundlePath, target, provider) {
1075
1093
  return {
1076
1094
  agents: await countDeployedBundleFiles(bundlePath, 'agents', target, paths.agents, ['.md', '.toml']),
1077
1095
  commands: await countDeployedBundleFiles(bundlePath, 'commands', target, paths.commands, ['.md']),
1078
- skills: await countDeployedBundleSkills(bundlePath, target, provider, paths),
1096
+ skills: await countDeployedBundleSkills(bundlePath, target, provider),
1079
1097
  rules: await countDeployedBundleFiles(bundlePath, 'rules', target, paths.rules, ['.md', '.mdc']),
1080
1098
  };
1081
1099
  }
1082
1100
  const SKILL_SUPPORT_REFERENCE = /(?:^|[\s`('"\[])((?:templates|references|scripts|assets)\/[A-Za-z0-9._@/+\-]+)(?=$|[\s`)'"\],:;])/gm;
1083
1101
  /** Copy one support file, preserving its executable bit. */
1084
- async function copySkillSupportFile(source, destination) {
1102
+ async function copySkillSupportFile(source, destination, skillDir) {
1085
1103
  await fs.mkdir(path.dirname(destination), { recursive: true });
1086
1104
  await fs.copyFile(source, destination);
1087
1105
  await fs.chmod(destination, (await fs.stat(source)).mode & 0o777);
1106
+ // Extend the shared copier's receipt for bundle-root assets too. Adapters
1107
+ // without that receipt keep their own ownership and cleanup contract.
1108
+ if (!skillDir)
1109
+ return;
1110
+ const manifestPath = path.join(skillDir, '.aiwg-manifest.json');
1111
+ let manifest;
1112
+ try {
1113
+ manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
1114
+ }
1115
+ catch {
1116
+ return;
1117
+ }
1118
+ if (!manifest.skillSource || !manifest.managed?.['SKILL.md'])
1119
+ return;
1120
+ manifest.managed[path.relative(skillDir, destination)] = {
1121
+ ...manifest.managed['SKILL.md'],
1122
+ hash: `sha256:${createHash('sha256').update(await fs.readFile(destination)).digest('hex')}`,
1123
+ };
1124
+ await fs.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
1088
1125
  }
1089
1126
  /**
1090
1127
  * Materialize a directory-valued support-asset reference (#2503).
@@ -1094,7 +1131,7 @@ async function copySkillSupportFile(source, destination) {
1094
1131
  * file modes are preserved so script packs stay executable. Empty directories
1095
1132
  * are still created — a reference to an empty pack is odd but not an error.
1096
1133
  */
1097
- async function copySkillSupportTree(source, destination, sourceSkillMd, reference, deployFile) {
1134
+ async function copySkillSupportTree(source, destination, sourceSkillMd, reference, deployFile, skillDir) {
1098
1135
  await fs.mkdir(destination, { recursive: true });
1099
1136
  const label = reference.replace(/\/+$/, '');
1100
1137
  const entries = await fs.readdir(source, { withFileTypes: true });
@@ -1105,7 +1142,7 @@ async function copySkillSupportTree(source, destination, sourceSkillMd, referenc
1105
1142
  throw new Error(`unsafe skill support asset '${label}/${entry.name}' referenced by ${sourceSkillMd}: symbolic links are not deployed`);
1106
1143
  }
1107
1144
  if (entry.isDirectory()) {
1108
- await copySkillSupportTree(from, to, sourceSkillMd, `${label}/${entry.name}`, deployFile);
1145
+ await copySkillSupportTree(from, to, sourceSkillMd, `${label}/${entry.name}`, deployFile, skillDir);
1109
1146
  continue;
1110
1147
  }
1111
1148
  if (!entry.isFile())
@@ -1114,7 +1151,7 @@ async function copySkillSupportTree(source, destination, sourceSkillMd, referenc
1114
1151
  deployFile(from, to);
1115
1152
  continue;
1116
1153
  }
1117
- await copySkillSupportFile(from, to);
1154
+ await copySkillSupportFile(from, to, skillDir);
1118
1155
  }
1119
1156
  }
1120
1157
  /**
@@ -1135,12 +1172,9 @@ async function reconcileDeployedSkillAssets(bundlePath, target, provider, option
1135
1172
  catch {
1136
1173
  return;
1137
1174
  }
1138
- const paths = getProviderPaths(provider);
1139
- const kernelSkillsPath = getProviderKernelSkillsPath(provider);
1140
1175
  const deployRoots = provider === 'omp' && options.scope === 'user'
1141
1176
  ? [path.join(resolveOmpPaths({ cwd: target }).agentDir, 'skills')]
1142
- : [...new Set([paths.skills, kernelSkillsPath]
1143
- .filter((value) => Boolean(value)).map(value => resolveDeployPath(target, value)))];
1177
+ : deployedSkillRoots(target, provider);
1144
1178
  for (const skillName of skillDirs) {
1145
1179
  const sourceSkillDir = path.join(skillsRoot, skillName);
1146
1180
  const sourceSkillMd = path.join(sourceSkillDir, 'SKILL.md');
@@ -1151,7 +1185,35 @@ async function reconcileDeployedSkillAssets(bundlePath, target, provider, option
1151
1185
  catch {
1152
1186
  continue;
1153
1187
  }
1154
- if (options.skipUndeployed && !(await Promise.all(deployRoots.map(root => fileExists(path.join(root, skillName, 'SKILL.md'))))).some(Boolean))
1188
+ // Check each deployed tier independently: a foreign mirror must not block
1189
+ // support assets for a tier already owned by this source.
1190
+ const ownedRoots = [];
1191
+ for (const root of deployRoots) {
1192
+ const skillDir = path.join(root, skillName);
1193
+ try {
1194
+ const manifestPath = path.join(skillDir, '.aiwg-manifest.json');
1195
+ const receipt = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
1196
+ if (!canDeploySkill(receipt, sourceSkillDir, options))
1197
+ continue;
1198
+ if (!sameSkillOwner(receipt, sourceSkillDir)) {
1199
+ receipt.skillSource = path.resolve(sourceSkillDir);
1200
+ const slug = extractFrameworkSlug(sourceSkillMd);
1201
+ for (const record of Object.values(receipt.managed ?? {})) {
1202
+ if (slug)
1203
+ record.frameworkSlug = slug;
1204
+ else
1205
+ delete record.frameworkSlug;
1206
+ }
1207
+ await fs.writeFile(manifestPath, `${JSON.stringify(receipt, null, 2)}\n`);
1208
+ }
1209
+ }
1210
+ catch { /* adapters without shared ownership receipts keep their own contract */ }
1211
+ if (await fileExists(path.join(skillDir, 'SKILL.md')))
1212
+ ownedRoots.push(root);
1213
+ }
1214
+ if (ownedRoots.length === 0)
1215
+ continue;
1216
+ if (options.skipUndeployed && !(await Promise.all(ownedRoots.map(root => fileExists(path.join(root, skillName, 'SKILL.md'))))).some(Boolean))
1155
1217
  continue;
1156
1218
  const frontmatter = content.match(/^---\r?\n([\s\S]*?)\r?\n---/)?.[1] ?? '';
1157
1219
  const declaredEntrypoint = frontmatter
@@ -1194,7 +1256,7 @@ async function reconcileDeployedSkillAssets(bundlePath, target, provider, option
1194
1256
  throw new Error(`skill entrypoint '${relative}' in ${sourceSkillMd} resolves to a directory; an entrypoint must be a file`);
1195
1257
  }
1196
1258
  let deployedSkillRoot;
1197
- for (const root of deployRoots) {
1259
+ for (const root of ownedRoots) {
1198
1260
  // The deployer may select the bulk or kernel tier; use the tier that
1199
1261
  // actually contains this skill's transformed SKILL.md.
1200
1262
  if (await fileExists(path.join(root, skillName, 'SKILL.md'))) {
@@ -1212,14 +1274,14 @@ async function reconcileDeployedSkillAssets(bundlePath, target, provider, option
1212
1274
  })()
1213
1275
  : null;
1214
1276
  if (sourceIsDirectory) {
1215
- await copySkillSupportTree(source, destination, sourceSkillMd, relative, deployFile);
1277
+ await copySkillSupportTree(source, destination, sourceSkillMd, relative, deployFile, path.join(deployedSkillRoot, skillName));
1216
1278
  continue;
1217
1279
  }
1218
1280
  if (deployFile) {
1219
1281
  deployFile(source, destination);
1220
1282
  continue;
1221
1283
  }
1222
- await copySkillSupportFile(source, destination);
1284
+ await copySkillSupportFile(source, destination, path.join(deployedSkillRoot, skillName));
1223
1285
  }
1224
1286
  }
1225
1287
  }
@@ -1291,6 +1353,9 @@ async function deployOneProjectLocalBundle(opts) {
1291
1353
  '--deploy-version', projectLocalDeployVersion(bundle),
1292
1354
  ...modelArgs,
1293
1355
  ];
1356
+ args.push(...collectUseScopeDeployArgs(ctx.args));
1357
+ if (ctx.args.includes('--force'))
1358
+ args.push('--force');
1294
1359
  if (dryRun)
1295
1360
  args.push('--dry-run');
1296
1361
  if (verbose)
@@ -1316,7 +1381,7 @@ async function deployOneProjectLocalBundle(opts) {
1316
1381
  exitCode = result.exitCode;
1317
1382
  if (exitCode === 0 && !dryRun) {
1318
1383
  try {
1319
- await reconcileDeployedSkillAssets(bundle.artifactPath, target, provider);
1384
+ await reconcileDeployedSkillAssets(bundle.artifactPath, target, provider, { force: ctx.args.includes('--force') });
1320
1385
  }
1321
1386
  catch (error) {
1322
1387
  ui.warn(`Project-local skill asset deployment failed for '${bundle.id}': ${error.message}`);
@@ -1967,18 +2032,30 @@ async function generateGlobalProjectContext(opts) {
1967
2032
  },
1968
2033
  });
1969
2034
  }
2035
+ /** Receipt reuse applies to complete packages; selected partial sources still need an actual build. */
2036
+ async function reconcileSelectedFrameworkSource(root) {
2037
+ const { refreshFrameworkCapabilities, resolveFrameworkCorpusRoot } = await import('../../artifacts/framework-capabilities.js');
2038
+ if (resolveFrameworkCorpusRoot(root)) {
2039
+ const { loadPrebuiltDeploymentIndex } = await import('../../artifacts/prebuilt-deployment.js');
2040
+ if (loadPrebuiltDeploymentIndex(root, { strictRoot: true }))
2041
+ return;
2042
+ await refreshFrameworkCapabilities(root, true, { force: true });
2043
+ return;
2044
+ }
2045
+ const { buildIndex } = await import('../../artifacts/index-builder.js');
2046
+ await buildIndex(root, { graph: 'framework', explicit: false });
2047
+ const { syncFortemiCoreIndex } = await import('../../artifacts/fortemi-core-sync.js');
2048
+ syncFortemiCoreIndex(root, { graph: 'framework' });
2049
+ }
1970
2050
  async function ensurePostDeployPhases(opts) {
1971
- const currentIndex = loadGraphIndexFile(opts.frameworkRoot, 'metadata.json', 'framework');
1972
- const builtAt = currentIndex ? Date.parse(currentIndex.builtAt) : Number.NaN;
1973
- const startedAt = Date.parse(opts.invocationStartedAt);
1974
- if (!Number.isFinite(builtAt) || builtAt + 2_000 < startedAt) {
1975
- try {
1976
- const { buildIndex } = await import('../../artifacts/index-builder.js');
1977
- await buildIndex(opts.frameworkRoot, { graph: 'framework', explicit: false });
1978
- }
1979
- catch {
1980
- // The shared verifier reports the index failure with stable remediation.
1981
- }
2051
+ // Validate source files once after deployment, including uncommitted edits
2052
+ // that the cheap HEAD/manifest receipt intentionally cannot detect. Earlier
2053
+ // deployment/query phases can reuse that receipt instead of rescanning.
2054
+ try {
2055
+ await reconcileSelectedFrameworkSource(opts.frameworkRoot);
2056
+ }
2057
+ catch {
2058
+ // The shared verifier reports the index failure with stable remediation.
1982
2059
  }
1983
2060
  // The Fortemi export is the default discovery backend. Rebuilding only the
1984
2061
  // source graph makes any existing export stale, so every successful use
@@ -1986,8 +2063,9 @@ async function ensurePostDeployPhases(opts) {
1986
2063
  // materializes a fresh-install cache without requiring a manual index sync.
1987
2064
  try {
1988
2065
  const { getFortemiCoreSyncStatus, syncFortemiCoreIndex, } = await import('../../artifacts/fortemi-core-sync.js');
2066
+ const { loadPrebuiltDeploymentIndex } = await import('../../artifacts/prebuilt-deployment.js');
1989
2067
  const status = getFortemiCoreSyncStatus(opts.frameworkRoot, 'framework');
1990
- if (!status.built || status.stale) {
2068
+ if (!loadPrebuiltDeploymentIndex(opts.frameworkRoot, { strictRoot: true }) && (!status.built || status.stale)) {
1991
2069
  syncFortemiCoreIndex(opts.frameworkRoot, { graph: 'framework' });
1992
2070
  }
1993
2071
  }
@@ -2031,6 +2109,7 @@ async function deploySourceDirectory(opts) {
2031
2109
  '--target', opts.target,
2032
2110
  ...opts.modelArgs,
2033
2111
  ];
2112
+ args.push(...collectUseScopeDeployArgs(opts.ctx.args));
2034
2113
  if (opts.dryRun)
2035
2114
  args.push('--dry-run');
2036
2115
  if (opts.verbose)
@@ -2182,6 +2261,55 @@ async function deployOmpUserSource(opts) {
2182
2261
  counts: { agents: entries.agents.length, commands: entries.commands.length,
2183
2262
  skills: entries.skills.length, rules: entries.rules.length }, entries });
2184
2263
  }
2264
+ /** Record native home writes without mirroring or changing user-scope removal roots. */
2265
+ async function recordNativeAddonDeploy(bundlePath, target, provider, bundle) {
2266
+ const userPaths = USER_SCOPE_PATHS[provider];
2267
+ const paths = getProviderPaths(provider);
2268
+ const entries = {
2269
+ agents: [], commands: [], skills: [], rules: [],
2270
+ };
2271
+ for (const names of await listBundleSkillNameCandidates(bundlePath)) {
2272
+ for (const root of deployedSkillRoots(target, provider)) {
2273
+ let name;
2274
+ for (const candidate of names) {
2275
+ if (await fileExists(path.join(root, candidate, 'SKILL.md'))) {
2276
+ name = candidate;
2277
+ break;
2278
+ }
2279
+ }
2280
+ if (!name)
2281
+ continue;
2282
+ try {
2283
+ const receipt = JSON.parse(await fs.readFile(path.join(root, name, '.aiwg-manifest.json'), 'utf8'));
2284
+ const sourceDir = path.join(bundlePath, 'skills', names[names.length - 1]);
2285
+ if (!sameSkillOwner(receipt, sourceDir))
2286
+ continue;
2287
+ }
2288
+ catch { /* legacy adapters may not write a shared ownership receipt */ }
2289
+ entries.skills.push(path.relative(userPaths.skills, path.join(root, name)));
2290
+ break;
2291
+ }
2292
+ }
2293
+ for (const kind of ['agents', 'commands', 'rules']) {
2294
+ if (!paths[kind] || !userPaths[kind])
2295
+ continue;
2296
+ for (const stem of await listBundleMdStems(bundlePath, kind)) {
2297
+ const filename = `${stem}.md`;
2298
+ const destination = path.join(resolveDeployPath(target, paths[kind]), filename);
2299
+ if (await fileExists(destination))
2300
+ entries[kind].push(path.relative(userPaths[kind], destination));
2301
+ }
2302
+ }
2303
+ const manifestPath = path.join(bundlePath, 'manifest.json');
2304
+ const manifest = JSON.parse(await fs.readFile(manifestPath, 'utf8'));
2305
+ const { recordUserDeploy } = await import('../../config/user-registry.js');
2306
+ await recordUserDeploy({
2307
+ framework: bundle, provider, version: manifest.version ?? (await getVersionInfo()).version,
2308
+ source: 'bundled', manifestHash: await hashManifest(manifestPath), entries,
2309
+ counts: { agents: entries.agents.length, commands: entries.commands.length,
2310
+ skills: entries.skills.length, rules: entries.rules.length },
2311
+ });
2312
+ }
2185
2313
  async function mirrorProjectLocalBundleToUserScope(opts) {
2186
2314
  const paths = getProviderPaths(opts.provider);
2187
2315
  const resolveProjectPath = (value) => !value ? '' : path.isAbsolute(value) ? value : path.join(opts.target, value);
@@ -2262,6 +2390,7 @@ export class UseHandler {
2262
2390
  category = 'framework';
2263
2391
  aliases = [];
2264
2392
  orchestrationDepth = 0;
2393
+ preparedProviderContinuations = new Set();
2265
2394
  async help() {
2266
2395
  return { exitCode: 0, message: USE_HELP, rawOutput: true };
2267
2396
  }
@@ -2274,12 +2403,24 @@ export class UseHandler {
2274
2403
  || ctx.args.includes('--workspace-signals');
2275
2404
  if (bypassOrchestration)
2276
2405
  return this.executeCore(ctx);
2406
+ // Child deployers share one source-index snapshot for this invocation. Each
2407
+ // addon still resolves and validates its bindings through the common query
2408
+ // engine, without rebuilding the entire corpus on every additive pass.
2409
+ const previousBindingCache = process.env.AIWG_RULE_BINDING_INDEX_CACHE;
2410
+ const bindingCache = previousBindingCache || await fs.mkdtemp(path.join(os.tmpdir(), 'aiwg-use-bindings-'));
2411
+ const removeBindingCache = previousBindingCache ? () => { } : trackTemporaryDirectory(bindingCache);
2412
+ process.env.AIWG_RULE_BINDING_INDEX_CACHE = bindingCache;
2277
2413
  this.orchestrationDepth += 1;
2278
2414
  try {
2279
2415
  return await this.executeOrchestrated(ctx, requestedBundle);
2280
2416
  }
2281
2417
  finally {
2282
2418
  this.orchestrationDepth -= 1;
2419
+ if (previousBindingCache === undefined)
2420
+ delete process.env.AIWG_RULE_BINDING_INDEX_CACHE;
2421
+ else
2422
+ process.env.AIWG_RULE_BINDING_INDEX_CACHE = previousBindingCache;
2423
+ removeBindingCache();
2283
2424
  }
2284
2425
  }
2285
2426
  async executeOrchestrated(ctx, requestedBundle) {
@@ -2355,7 +2496,6 @@ export class UseHandler {
2355
2496
  projectPath: projectDir,
2356
2497
  provider,
2357
2498
  args: remainingArgs,
2358
- invocationStartedAt: startedAt,
2359
2499
  });
2360
2500
  }
2361
2501
  }
@@ -2975,6 +3115,10 @@ export class UseHandler {
2975
3115
  }
2976
3116
  const runner = createScriptRunner(frameworkRoot);
2977
3117
  const addonBaseArgs = ['--deploy-commands', '--deploy-skills', '--deploy-rules'];
3118
+ if (remainingArgs.includes('--allow-over-budget'))
3119
+ addonBaseArgs.push('--allow-over-budget');
3120
+ if (addonScope === 'user')
3121
+ addonBaseArgs.push('--scope', 'user');
2978
3122
  // An explicitly selected upstream addon must be self-contained in the
2979
3123
  // project. Unlike a full framework deploy, its standard skills cannot be
2980
3124
  // left index-only: the user asked to install this specific bundle and
@@ -2992,6 +3136,8 @@ export class UseHandler {
2992
3136
  }
2993
3137
  if (dryRunAddon)
2994
3138
  addonBaseArgs.push('--dry-run');
3139
+ if (remainingArgs.includes('--force'))
3140
+ addonBaseArgs.push('--force');
2995
3141
  const kind = isExtension ? 'extension' : 'addon';
2996
3142
  const activationOrder = isAddon
2997
3143
  ? await resolveRequiredAddonActivationOrder(frameworkRoot, framework)
@@ -3014,7 +3160,7 @@ export class UseHandler {
3014
3160
  }
3015
3161
  if (!dryRunAddon) {
3016
3162
  try {
3017
- await reconcileDeployedSkillAssets(dependencySource, target, provider, { strictReferences: false });
3163
+ await reconcileDeployedSkillAssets(dependencySource, target, provider, { strictReferences: false, force: remainingArgs.includes('--force') });
3018
3164
  }
3019
3165
  catch (error) {
3020
3166
  return {
@@ -3056,7 +3202,7 @@ export class UseHandler {
3056
3202
  }
3057
3203
  if (!dryRunAddon) {
3058
3204
  try {
3059
- await reconcileDeployedSkillAssets(addonSource, target, provider, { strictReferences: false });
3205
+ await reconcileDeployedSkillAssets(addonSource, target, provider, { strictReferences: false, force: remainingArgs.includes('--force') });
3060
3206
  }
3061
3207
  catch (error) {
3062
3208
  return {
@@ -3109,6 +3255,14 @@ export class UseHandler {
3109
3255
  message: `Failed to register CLI commands: ${error instanceof Error ? error.message : String(error)}`,
3110
3256
  };
3111
3257
  }
3258
+ if (!dryRunAddon && (provider === 'openclaw' || (provider === 'grokbot' && addonScope === 'user'))) {
3259
+ try {
3260
+ await recordNativeAddonDeploy(addonSource, target, provider, framework);
3261
+ }
3262
+ catch (error) {
3263
+ return { exitCode: 1, message: `Addon user registry update failed: ${error instanceof Error ? error.message : String(error)}` };
3264
+ }
3265
+ }
3112
3266
  // Persist the same lifecycle record frameworks and project-local bundles
3113
3267
  // receive so status, refresh, doctor, and remove can account for this
3114
3268
  // upstream addon and every provider artifact it actually deployed.
@@ -3231,6 +3385,16 @@ export class UseHandler {
3231
3385
  const force = remainingArgs.includes('--force');
3232
3386
  const skipConflicts = remainingArgs.includes('--skip-conflicts');
3233
3387
  const explicitHarnessAgentSelectors = parseOpenHumanHarnessAgentSelector(remainingArgs);
3388
+ const preparedFlag = '--aiwg-provider-main-prepared';
3389
+ const preparedFlagIndex = remainingArgs.indexOf(preparedFlag);
3390
+ const preparedCapability = preparedFlagIndex >= 0 ? remainingArgs[preparedFlagIndex + 1] : undefined;
3391
+ let mainProviderPrepared = false;
3392
+ if (preparedFlagIndex >= 0) {
3393
+ if (!preparedCapability || !this.preparedProviderContinuations.delete(preparedCapability)) {
3394
+ return { exitCode: 1, message: 'Invalid prepared-provider continuation capability.' };
3395
+ }
3396
+ mainProviderPrepared = true;
3397
+ }
3234
3398
  // PUW-027 (#1128): --scope user|project per ADR-4. Default project.
3235
3399
  // #1156 Phase 1: --user is a shorthand for --scope user.
3236
3400
  let scope;
@@ -3253,7 +3417,9 @@ export class UseHandler {
3253
3417
  + ` (active: ${process.env.AIWG_USER_REGISTRY_PATH})`);
3254
3418
  }
3255
3419
  }
3256
- const filteredArgs = deployArgs.filter(a => a !== '--no-utils' && a !== '--no-project-local' && a !== '--ci-hooks-enabled' && a !== '--force' && a !== '--skip-conflicts' && a !== '--no-harness-agents');
3420
+ if (scope === 'user' && !deployArgs.includes('--scope'))
3421
+ deployArgs.push('--scope', 'user');
3422
+ const filteredArgs = removeFlagWithOptionalValue(deployArgs, preparedFlag).filter(a => a !== '--no-utils' && a !== '--no-project-local' && a !== '--ci-hooks-enabled' && a !== '--skip-conflicts' && a !== '--no-harness-agents');
3257
3423
  const deployFilteredArgs = removeFlagWithOptionalValue(filteredArgs, '--harness-agents');
3258
3424
  // Pass --quiet to suppress deploy-agents.mjs header/footer in default mode (#460)
3259
3425
  // Human dry-run remains verbose; machine-readable dry-run captures the
@@ -3278,8 +3444,70 @@ export class UseHandler {
3278
3444
  ui.warn("No .aiwg/aiwg.config found. Run 'aiwg init', then ask your AIWG agent to configure this project properly.");
3279
3445
  }
3280
3446
  }
3281
- // Multi-provider: loop over providers, deploying to each in sequence
3447
+ const targetIdx = remainingArgs.findIndex(a => a === '--target');
3448
+ const target = targetIdx >= 0 && remainingArgs[targetIdx + 1] ? remainingArgs[targetIdx + 1] : process.cwd();
3449
+ // Multi-provider: prepare built-in project-scope projections in at most two
3450
+ // subprocesses, then preserve the existing provider/addon commit order.
3451
+ // User-scope, dry-run, harness-special and project-local adapters retain the
3452
+ // established serial path because their lifecycle is not stage-only.
3282
3453
  if (providers.length > 1) {
3454
+ const preparedJobs = [];
3455
+ let canPrepareConcurrently = !dryRun && scope === 'project' && explicitHarnessAgentSelectors.length === 0;
3456
+ for (const [order, requested] of providers.entries()) {
3457
+ const local = await resolveProjectLocalProviderAdapter(projectDir, requested);
3458
+ if (local.requestedProvider) {
3459
+ canPrepareConcurrently = false;
3460
+ break;
3461
+ }
3462
+ const unsupported = unsupportedProviderMessage(requested);
3463
+ if (unsupported)
3464
+ return { exitCode: 1, message: unsupported };
3465
+ const resolved = resolveBuiltInProviderForUse(local.provider);
3466
+ if (!PREPARABLE_BUILTIN_PROVIDERS.has(resolved.provider)) {
3467
+ canPrepareConcurrently = false;
3468
+ break;
3469
+ }
3470
+ const args = withProviderOverride([...deployFilteredArgs], resolved.provider);
3471
+ if (framework === 'all' && !['pi', 'omp'].includes(resolved.provider)
3472
+ && !remainingArgs.includes('--copy-all') && !remainingArgs.includes('--copy-standard-skills'))
3473
+ args.push('--kernel-only');
3474
+ preparedJobs.push({ order, provider: resolved.provider, target: path.resolve(target), args });
3475
+ }
3476
+ if (canPrepareConcurrently && preparedJobs.length === providers.length) {
3477
+ if (!skipConflicts) {
3478
+ for (const job of preparedJobs) {
3479
+ const canDeploy = await runPreDeployCollisionCheck({
3480
+ frameworkRoot, framework, target, provider: job.provider, force, skipConflicts, verbose,
3481
+ });
3482
+ if (!canDeploy)
3483
+ return { exitCode: 1, message: 'Deployment blocked due to name collisions. See above for details.' };
3484
+ }
3485
+ }
3486
+ let session;
3487
+ try {
3488
+ session = await prepareProviderDeployments(frameworkRoot, preparedJobs);
3489
+ for (const [order, requested] of providers.entries()) {
3490
+ await session.commit(order);
3491
+ const capability = randomUUID();
3492
+ this.preparedProviderContinuations.add(capability);
3493
+ try {
3494
+ const result = await this.execute({ ...ctx, args: [framework, '--provider', requested, preparedFlag, capability, ...remainingArgs] });
3495
+ if (result.exitCode !== 0)
3496
+ return result;
3497
+ }
3498
+ finally {
3499
+ this.preparedProviderContinuations.delete(capability);
3500
+ }
3501
+ }
3502
+ return { exitCode: 0 };
3503
+ }
3504
+ catch (error) {
3505
+ return { exitCode: 1, message: `Concurrent provider preparation failed: ${error instanceof Error ? error.message : String(error)}` };
3506
+ }
3507
+ finally {
3508
+ await session?.dispose();
3509
+ }
3510
+ }
3283
3511
  for (const p of providers) {
3284
3512
  const result = await this.execute({ ...ctx, args: [framework, '--provider', p, ...remainingArgs] });
3285
3513
  if (result.exitCode !== 0)
@@ -3311,8 +3539,6 @@ export class UseHandler {
3311
3539
  && !remainingArgs.includes('--copy-standard-skills');
3312
3540
  if (bulkKernelOnly)
3313
3541
  providerDeployArgs.push('--kernel-only');
3314
- const targetIdx = remainingArgs.findIndex(a => a === '--target');
3315
- const target = targetIdx >= 0 && remainingArgs[targetIdx + 1] ? remainingArgs[targetIdx + 1] : process.cwd();
3316
3542
  if ((verbose || dryRun) && projectLocalProviderResolution.requestedProvider) {
3317
3543
  ui.dim(` project-local provider '${projectLocalProviderResolution.requestedProvider}' extends '${provider}'`);
3318
3544
  }
@@ -3401,7 +3627,19 @@ export class UseHandler {
3401
3627
  ui.blank();
3402
3628
  }
3403
3629
  const runner = createScriptRunner(ctx.frameworkRoot);
3404
- const mainResult = await runner.run('tools/agents/deploy-agents.mjs', providerDeployArgs, captureOpts);
3630
+ let mainResult;
3631
+ if (mainProviderPrepared) {
3632
+ try {
3633
+ await finalizePreparedProvider(frameworkRoot, providerDeployArgs);
3634
+ mainResult = { exitCode: 0 };
3635
+ }
3636
+ catch (error) {
3637
+ mainResult = { exitCode: 1, message: `Prepared provider finalization failed: ${error instanceof Error ? error.message : String(error)}` };
3638
+ }
3639
+ }
3640
+ else {
3641
+ mainResult = await runner.run('tools/agents/deploy-agents.mjs', providerDeployArgs, captureOpts);
3642
+ }
3405
3643
  if (mainResult.exitCode !== 0) {
3406
3644
  return mainResult;
3407
3645
  }
@@ -3430,6 +3668,10 @@ export class UseHandler {
3430
3668
  }
3431
3669
  // Build common args for addon deployments (inherit provider and target)
3432
3670
  const addonBaseArgs = ['--deploy-commands', '--deploy-skills', '--deploy-rules'];
3671
+ if (remainingArgs.includes('--allow-over-budget'))
3672
+ addonBaseArgs.push('--allow-over-budget');
3673
+ if (scope === 'user')
3674
+ addonBaseArgs.push('--scope', 'user');
3433
3675
  if (bulkKernelOnly)
3434
3676
  addonBaseArgs.push('--kernel-only');
3435
3677
  addonBaseArgs.push(...modelDeployArgs);
@@ -3449,6 +3691,12 @@ export class UseHandler {
3449
3691
  // Deploy all addons (excluding disallow list) unless --no-utils
3450
3692
  if (!skipUtils) {
3451
3693
  const allAddons = await getAllAddons(frameworkRoot);
3694
+ // These root collectors already deploy every eligible addon. Re-staging
3695
+ // the entire deployment per addon duplicates that work. Codex's skills
3696
+ // helper includes addons only in all mode; other modes retain their pass.
3697
+ // CLI contribution registration below still runs for every addon.
3698
+ const selectedMode = MODE_MAP[framework];
3699
+ const mainIncludesAddons = mainDeploymentIncludesAddons(provider, selectedMode, providerDeployArgs);
3452
3700
  for (const addon of allAddons) {
3453
3701
  if (verbose) {
3454
3702
  console.log('');
@@ -3458,9 +3706,10 @@ export class UseHandler {
3458
3706
  const addonArgs = quiet
3459
3707
  ? ['--quiet', '--source', source, ...addonBaseArgs]
3460
3708
  : ['--source', source, ...addonBaseArgs];
3461
- const result = await runner.run('tools/agents/deploy-agents.mjs', addonArgs, captureOpts);
3462
- if (result.exitCode !== 0) {
3463
- return result;
3709
+ if (!mainIncludesAddons) {
3710
+ const result = await runner.run('tools/agents/deploy-agents.mjs', addonArgs, captureOpts);
3711
+ if (result.exitCode !== 0)
3712
+ return result;
3464
3713
  }
3465
3714
  try {
3466
3715
  await registerSourceCliCommands({
@@ -3677,7 +3926,14 @@ export class UseHandler {
3677
3926
  // progress through; otherwise we show a single-line spinner-
3678
3927
  // style message and capture the noisy stat lines.
3679
3928
  ui.blank();
3680
- ui.info('Building capability index…');
3929
+ const { loadPrebuiltDeploymentIndex } = await import('../../artifacts/prebuilt-deployment.js');
3930
+ const prebuilt = loadPrebuiltDeploymentIndex(aiwgRootForIndex, { strictRoot: true });
3931
+ ui.info(prebuilt ? 'Validating packaged capability index…' : 'Building capability index…');
3932
+ if (!prebuilt && await fs.access(path.join(aiwgRootForIndex, 'prebuilt', 'framework-relations', 'manifest.json')).then(() => true).catch(() => false)) {
3933
+ const { selectPrebuiltRelations } = await import('../../artifacts/relations.js');
3934
+ const reason = selectPrebuiltRelations(aiwgRootForIndex).reason ?? 'packaged search index is missing, stale, or does not match the source';
3935
+ ui.dim(` Packaged index unavailable: ${reason}.`);
3936
+ }
3681
3937
  ui.dim(' Indexing operational assets for agent-side lookup.');
3682
3938
  const indexStart = Date.now();
3683
3939
  // Capture buildIndex's own console.log noise unless verbose
@@ -3685,13 +3941,9 @@ export class UseHandler {
3685
3941
  if (!verbose)
3686
3942
  console.log = () => { };
3687
3943
  try {
3688
- const { buildIndex } = await import('../../artifacts/index-builder.js');
3689
- // Build against AIWG_ROOT so stored paths resolve from any
3690
- // project (#1217). The output index location is XDG-shared
3691
- // regardless of build cwd.
3692
- await buildIndex(aiwgRootForIndex, { graph: 'framework', explicit: false });
3693
- const { syncFortemiCoreIndex } = await import('../../artifacts/fortemi-core-sync.js');
3694
- syncFortemiCoreIndex(aiwgRootForIndex, { graph: 'framework' });
3944
+ // Validate uncommitted sources once and publish the receipt so
3945
+ // verification/discovery do not immediately scan the corpus again.
3946
+ await reconcileSelectedFrameworkSource(aiwgRootForIndex);
3695
3947
  console.log = origLog;
3696
3948
  const indexElapsedSec = ((Date.now() - indexStart) / 1000).toFixed(1);
3697
3949
  ui.success(`Capability index ready (${indexElapsedSec}s).`);