@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,7 +1,14 @@
1
+ import { tomlString } from './toml-string.mjs';
2
+ import { buildServerConfig } from './server-config.mjs';
3
+ export { buildServerConfig } from './server-config.mjs';
4
+ import { isLowerLayerEntry, loadLayered, lowerEntryQualified, resolveConfigLayers, saveLayerData } from './config-layers.mjs';
5
+ import { assertConfigDestination, assertProjectCredentials, classifyMcpDestination, projectCredentialRemedy, writeConfigAtomic, writeConfigTransaction } from './config-file.mjs';
1
6
  import { manageOmpMcp } from './omp-config.mjs';
2
7
  import { manageGrokBuildMcp } from './grok-build-config.mjs';
3
8
  import { replaceServer } from './toml-editor.mjs';
4
9
  import { resolveOmpPaths } from '../providers/omp-paths.mjs';
10
+ import { applyJsonToolFilterPlan, claudeSettingsPath, prepareClaudePermissions, planToolFilters } from './tool-filters.mjs';
11
+ import { assertCredentialPolicy, resolveCredentialPolicy, validateEnvReferenceName } from './credentials.mjs';
5
12
  /**
6
13
  * MCP Server Registry (Runtime ESM)
7
14
  *
@@ -15,7 +22,8 @@ import { resolveOmpPaths } from '../providers/omp-paths.mjs';
15
22
  * @implements #554
16
23
  */
17
24
 
18
- import { readFile, writeFile, mkdir } from 'fs/promises';
25
+ import { readFile } from 'fs/promises';
26
+ import { qualificationDigest } from '../models/qualification-digest.mjs';
19
27
  import { dirname, resolve } from 'path';
20
28
  import { homedir } from 'os';
21
29
  import { existsSync } from 'fs';
@@ -73,14 +81,31 @@ function validateCredentialReferences(def) {
73
81
  throw new Error(`Invalid MCP header environment variable reference "${envName}"`);
74
82
  }
75
83
  }
84
+ for (const [key, envName] of Object.entries(def.envFrom || {})) {
85
+ if (!ENV_REFERENCE_NAME.test(key)) throw new Error(`Invalid MCP env-from variable name "${key}"`);
86
+ if (!ENV_REFERENCE_NAME.test(envName)) {
87
+ throw new Error(`Invalid MCP env-from environment variable reference "${envName}"`);
88
+ }
89
+ }
90
+ }
91
+
92
+ // The typed worker dispatch boundary owns qualification. Legacy runtime edits
93
+ // invalidate its binding without importing the TypeScript policy owner.
94
+ export function workerServerDigest(server) {
95
+ const { workerQualification, description, injectedProviders, addedAt, updatedAt, ...execution } = server;
96
+ return qualificationDigest(execution);
76
97
  }
77
98
 
78
99
  export class McpServerRegistry {
79
100
  #configDir;
80
101
  #cache = null;
81
102
 
103
+ #layers;
104
+ #layering = null;
105
+
82
106
  constructor(configDirOverride) {
83
- this.#configDir = resolveConfigDir(configDirOverride);
107
+ this.#layers = resolveConfigLayers(configDirOverride);
108
+ this.#configDir = this.#layers ? this.#layers[this.#layers.length - 1] : resolveConfigDir(configDirOverride);
84
109
  }
85
110
 
86
111
  getPath() {
@@ -90,6 +115,13 @@ export class McpServerRegistry {
90
115
  async load() {
91
116
  if (this.#cache) return this.#cache;
92
117
 
118
+ if (this.#layers) {
119
+ const layered = await loadLayered(this.#layers, REGISTRY_FILENAME, 'servers', DEFAULT_REGISTRY);
120
+ this.#cache = layered.data;
121
+ this.#layering = layered.layering;
122
+ return this.#cache;
123
+ }
124
+
93
125
  const filePath = this.getPath();
94
126
  try {
95
127
  const content = await readFile(filePath, 'utf-8');
@@ -103,19 +135,36 @@ export class McpServerRegistry {
103
135
  this.#cache = { ...DEFAULT_REGISTRY, servers: {} };
104
136
  }
105
137
 
138
+ try {
139
+ resolveCredentialPolicy({ registryPolicy: this.#cache.credentialPolicy, env: {} });
140
+ } catch (error) {
141
+ this.#cache = null;
142
+ throw new Error(`Invalid MCP credential policy in ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
143
+ }
144
+
106
145
  return this.#cache;
107
146
  }
108
147
 
109
- async save() {
110
- if (!this.#cache) return;
111
- await mkdir(this.#configDir, { recursive: true });
112
- const filePath = this.getPath();
113
- await writeFile(filePath, JSON.stringify(this.#cache, null, 2) + '\n', 'utf-8');
148
+ async save(data = this.#cache, explicitPolicy = false) {
149
+ if (!data) return;
150
+ // A fresh instance has no ownership record yet; load it first so inherited
151
+ // entries and inherited policy are never copied into the write layer.
152
+ let layering = this.#layering;
153
+ if (this.#layers && !layering) {
154
+ await this.load();
155
+ layering = this.#layering;
156
+ }
157
+ await saveLayerData(this.getPath(), data, 'servers', this.#layers, layering, explicitPolicy);
158
+ this.#cache = data;
159
+ if (this.#layers) {
160
+ this.clearCache();
161
+ await this.load();
162
+ }
114
163
  }
115
164
 
116
165
  async add(def) {
117
166
  validateCredentialReferences(def);
118
- const data = await this.load();
167
+ const data = structuredClone(await this.load());
119
168
 
120
169
  if (data.servers[def.name]) {
121
170
  throw new Error(`Server "${def.name}" already exists. Use "update" to modify it.`);
@@ -123,27 +172,34 @@ export class McpServerRegistry {
123
172
 
124
173
  data.servers[def.name] = {
125
174
  ...def,
175
+ workerQualification: undefined,
126
176
  injectedProviders: [],
127
177
  addedAt: new Date().toISOString(),
128
178
  updatedAt: new Date().toISOString(),
129
179
  };
130
180
 
131
- await this.save();
181
+ await this.save(data);
132
182
  }
133
183
 
134
184
  async remove(name) {
135
- const data = await this.load();
185
+ const data = structuredClone(await this.load());
136
186
 
137
187
  if (!data.servers[name]) {
138
188
  throw new Error(`Server "${name}" not found.`);
139
189
  }
140
190
 
191
+ if (this.#layering && isLowerLayerEntry(this.#layering, name)) {
192
+ throw new Error(`Server "${name}" is defined in a lower configuration layer; remove it there.`);
193
+ }
194
+ if (this.#layering && lowerEntryQualified(this.#layering, name)) {
195
+ throw new Error(`Server "${name}" overrides a qualified lower-layer entry; removing the override would silently re-expose its qualification. Remove the lower-layer entry in its own layer instead.`);
196
+ }
141
197
  delete data.servers[name];
142
- await this.save();
198
+ await this.save(data);
143
199
  }
144
200
 
145
201
  async update(name, updates) {
146
- const data = await this.load();
202
+ const data = structuredClone(await this.load());
147
203
 
148
204
  if (!data.servers[name]) {
149
205
  throw new Error(`Server "${name}" not found.`);
@@ -156,9 +212,11 @@ export class McpServerRegistry {
156
212
  updatedAt: new Date().toISOString(),
157
213
  };
158
214
  validateCredentialReferences(next);
215
+ next.workerQualification = workerServerDigest(next) === workerServerDigest(data.servers[name])
216
+ ? data.servers[name].workerQualification : undefined;
159
217
  data.servers[name] = next;
160
218
 
161
- await this.save();
219
+ await this.save(data);
162
220
  }
163
221
 
164
222
  async get(name) {
@@ -172,7 +230,7 @@ export class McpServerRegistry {
172
230
  }
173
231
 
174
232
  async recordInjection(name, provider) {
175
- const data = await this.load();
233
+ const data = structuredClone(await this.load());
176
234
  const server = data.servers[name];
177
235
  if (!server) return;
178
236
 
@@ -183,7 +241,7 @@ export class McpServerRegistry {
183
241
  server.injectedProviders.push(provider);
184
242
  }
185
243
 
186
- await this.save();
244
+ await this.save(data);
187
245
  }
188
246
 
189
247
  async getInjectedProviders() {
@@ -197,94 +255,55 @@ export class McpServerRegistry {
197
255
  return [...providers];
198
256
  }
199
257
 
200
- clearCache() {
201
- this.#cache = null;
258
+ async getCredentialPolicy() {
259
+ const data = await this.load();
260
+ return data.credentialPolicy;
202
261
  }
203
- }
204
-
205
- // ============================================
206
- // Provider injection logic
207
- // ============================================
208
-
209
- function buildServerConfig(server, provider) {
210
- const mcpDefinition = getMcpInjectionDefinition(provider);
211
262
 
212
- switch (mcpDefinition?.serverConfigFormat) {
213
- case 'antigravity': {
214
- if (server.type === 'stdio') {
215
- return { command: server.command, args: server.args || [], ...(server.env ? { env: server.env } : {}) };
216
- }
217
- return { serverUrl: server.url, ...(server.headers ? { headers: server.headers } : {}) };
218
- }
219
- case 'standard': {
220
- if (server.type === 'stdio') {
221
- return {
222
- command: server.command,
223
- args: server.args || [],
224
- ...(server.env ? { env: server.env } : {}),
225
- };
226
- }
227
- return {
228
- url: server.url,
229
- ...(server.headers ? { headers: server.headers } : {}),
230
- };
231
- }
263
+ /** The enforced organisation floor for this registry, if any layer below the write layer sets one. */
264
+ async getCredentialPolicyFloor() {
265
+ await this.load();
266
+ return this.#layering?.lowerPolicy;
267
+ }
232
268
 
233
- case 'factory': {
234
- if (server.type === 'stdio') {
235
- return {
236
- type: 'stdio',
237
- command: server.command,
238
- args: server.args || [],
239
- disabled: false,
240
- ...(server.env ? { env: server.env } : {}),
241
- };
242
- }
243
- return {
244
- type: server.type,
245
- url: server.url,
246
- disabled: false,
247
- ...(server.headers ? { headers: server.headers } : {}),
248
- };
249
- }
269
+ /** The config file of the layer that set the enforced floor, for diagnostics. */
270
+ async getCredentialPolicyFloorSource() {
271
+ await this.load();
272
+ return this.#layering?.lowerPolicySource;
273
+ }
250
274
 
251
- case 'opencode': {
252
- if (server.type === 'stdio') {
253
- return {
254
- type: 'local',
255
- command: [server.command, ...(server.args || [])],
256
- ...(server.env ? { env: server.env } : {}),
257
- };
258
- }
259
- return {
260
- type: 'remote',
261
- url: server.url,
262
- ...(server.headers ? { headers: server.headers } : {}),
263
- };
275
+ async setCredentialPolicy(policy) {
276
+ const data = structuredClone(await this.load());
277
+ const floorPolicy = this.#layering?.lowerPolicy;
278
+ const floorSource = this.#layering?.lowerPolicySource;
279
+ const effective = resolveCredentialPolicy({ flag: policy, floorPolicy, floorSource, env: {} });
280
+ if (effective !== policy) {
281
+ const location = floorSource ? ` (set in ${floorSource})` : '';
282
+ throw new Error(`Cannot relax MCP credential policy floor "${effective}"${location} to "${policy}".`);
264
283
  }
284
+ data.credentialPolicy = policy;
285
+ await this.save(data, true);
286
+ }
265
287
 
266
- case 'toml':
267
- return {};
268
-
269
- default:
270
- return {};
288
+ clearCache() {
289
+ this.#cache = null;
271
290
  }
272
291
  }
273
292
 
274
- function tomlString(value) {
275
- if (typeof value !== 'string' || [...value].some(char => {
276
- const point = char.codePointAt(0);
277
- return point >= 0xd800 && point <= 0xdfff;
278
- })) throw new Error('TOML values must be strings containing valid Unicode scalar values');
279
- // JSON escapes align with TOML basic strings except DEL must also be escaped.
280
- return JSON.stringify(value).replace(/\u007f/g, '\\u007f');
281
- }
293
+ // ============================================
294
+ // Provider injection logic
295
+ // ============================================
296
+
282
297
 
283
298
  function tomlKey(value) {
284
299
  return typeof value === 'string' && /^[A-Za-z0-9_-]+$/.test(value) ? value : tomlString(value);
285
300
  }
286
301
 
287
- function buildServerToml(server) {
302
+ function tomlInlineTable(values) {
303
+ return `{ ${Object.entries(values).map(([name, value]) => `${tomlKey(name)} = ${tomlString(value)}`).join(', ')} }`;
304
+ }
305
+
306
+ export function buildServerToml(server) {
288
307
  const lines = [];
289
308
  lines.push(`[mcp_servers.${tomlKey(server.name)}]`);
290
309
 
@@ -294,8 +313,21 @@ function buildServerToml(server) {
294
313
  const argsStr = server.args.map(a => tomlString(a)).join(', ');
295
314
  lines.push(`args = [${argsStr}]`);
296
315
  }
316
+ if (server.env && Object.keys(server.env).length > 0) lines.push(`env = ${tomlInlineTable(server.env)}`);
317
+ // Codex forwards a variable only under its own name (env_vars).
318
+ const forwarded = Object.entries(server.envFrom || {});
319
+ for (const [key, name] of forwarded) {
320
+ validateEnvReferenceName(name);
321
+ if (key !== name) {
322
+ throw new Error(`MCP server "${server.name}": Codex forwards environment variables under their own name only; env-from ${key}=${name} cannot be rendered. Use ${name}=${name}.`);
323
+ }
324
+ }
325
+ if (forwarded.length > 0) lines.push(`env_vars = [${forwarded.map(([name]) => tomlString(name)).join(', ')}]`);
297
326
  } else {
298
327
  lines.push(`url = ${tomlString(server.url)}`);
328
+ if (server.headers && Object.keys(server.headers).length > 0) lines.push(`http_headers = ${tomlInlineTable(server.headers)}`);
329
+ for (const name of Object.values(server.headerEnv || {})) validateEnvReferenceName(name);
330
+ if (server.headerEnv && Object.keys(server.headerEnv).length > 0) lines.push(`env_http_headers = ${tomlInlineTable(server.headerEnv)}`);
299
331
  }
300
332
 
301
333
  lines.push(`startup_timeout_sec = 10.0`);
@@ -327,18 +359,39 @@ export async function injectServers(registry, provider, options = {}) {
327
359
  }
328
360
 
329
361
  let allServers = await registry.list();
330
- if (serverFilter && serverFilter.length > 0) {
362
+ if (serverFilter !== undefined) {
331
363
  allServers = allServers.filter(s => serverFilter.includes(s.name));
332
364
  }
333
365
 
366
+ const toolPlan = options.toolFilters
367
+ ? planToolFilters(provider, allServers.map(server => server.name), options.toolFilters)
368
+ : null;
369
+ if (toolPlan) result.warnings = toolPlan.warnings;
334
370
  if (allServers.length === 0) {
335
371
  result.error = 'No servers to inject. Use "aiwg mcp add" first.';
336
372
  return result;
337
373
  }
338
374
 
375
+ assertCredentialPolicy(allServers, resolveCredentialPolicy({
376
+ flag: options.credentialPolicy, registryPolicy: await registry.getCredentialPolicy(),
377
+ floorPolicy: await registry.getCredentialPolicyFloor(),
378
+ floorSource: await registry.getCredentialPolicyFloorSource(),
379
+ }));
380
+
381
+ // The shareable-project decision follows the actual resolved destination,
382
+ // never the requested scope: a `--scope user` request for a provider without
383
+ // a user-scope destination still resolves to the project file and is refused.
384
+ const { userScope, projectRoot } = classifyMcpDestination(provider, options.scope, configPath, projectDir);
385
+ await assertConfigDestination(configPath, projectRoot);
386
+ // Every destination inside the project directory is meant to be committed to
387
+ // version control; home destinations are private, so literals there are not
388
+ // copied into a shared file.
389
+ if (projectRoot) {
390
+ assertProjectCredentials(allServers, configPath, projectCredentialRemedy(provider, projectDir));
391
+ }
339
392
  if (normalizedProvider === 'omp') {
340
393
  try {
341
- const managed = await manageOmpMcp(configPath, allServers, { dryRun });
394
+ const managed = await manageOmpMcp(configPath, allServers, { dryRun, userScope, projectRoot });
342
395
  if (!dryRun) for (const server of allServers) await registry.recordInjection(server.name, 'omp');
343
396
  return { ...result, ...managed };
344
397
  } catch (error) {
@@ -350,6 +403,7 @@ export async function injectServers(registry, provider, options = {}) {
350
403
  try {
351
404
  const managed = await manageGrokBuildMcp(configPath, allServers, {
352
405
  dryRun,
406
+ userScope,
353
407
  root: options.scope === 'user'
354
408
  ? dirname(dirname(configPath))
355
409
  : resolve(projectDir),
@@ -365,13 +419,13 @@ export async function injectServers(registry, provider, options = {}) {
365
419
  }
366
420
 
367
421
  if (mcpDefinition?.configFormat === 'toml') {
368
- return injectToml(registry, allServers, configPath, provider, dryRun, result);
422
+ return injectToml(registry, allServers, configPath, provider, dryRun, result, userScope, projectRoot, toolPlan);
369
423
  }
370
424
 
371
- return injectJson(registry, allServers, configPath, provider, dryRun, result);
425
+ return injectJson(registry, allServers, configPath, provider, dryRun, result, userScope, projectRoot, toolPlan, { projectDir, scope: options.scope });
372
426
  }
373
427
 
374
- async function injectJson(registry, servers, configPath, provider, dryRun, result) {
428
+ async function injectJson(registry, servers, configPath, provider, dryRun, result, userScope, projectRoot, toolPlan = null, location = {}) {
375
429
  let existing = {};
376
430
  try {
377
431
  const content = await readFile(configPath, 'utf-8');
@@ -404,10 +458,24 @@ async function injectJson(registry, servers, configPath, provider, dryRun, resul
404
458
  }
405
459
 
406
460
  const merged = { ...existing, [mcpKey]: newServers };
461
+ if (toolPlan) {
462
+ applyJsonToolFilterPlan(merged, mcpKey, toolPlan);
463
+ }
464
+
465
+ const isClaude = normalizeRuntimeProviderId(provider) === 'claude-code';
466
+ const settingsPath = isClaude ? claudeSettingsPath(location.projectDir, location.scope) : null;
467
+ const settings = settingsPath ? await prepareClaudePermissions(
468
+ settingsPath, toolPlan?.claudePermissions || { deny: [], allow: [] },
469
+ { userScope, projectRoot, managedDir: dirname(registry.getPath()), mcpPath: configPath },
470
+ ) : null;
471
+ if (settings?.active && settingsPath) result.settingsPath = settingsPath;
472
+ if (settings?.warnings.length) result.warnings = [...(result.warnings || []), ...settings.warnings];
407
473
 
408
474
  if (!dryRun) {
409
- await mkdir(resolve(configPath, '..'), { recursive: true });
410
- await writeFile(configPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
475
+ await writeConfigTransaction([
476
+ { file: configPath, content: JSON.stringify(merged, null, 2) + '\n', options: { userScope, projectRoot } },
477
+ ...(settings?.writes || []),
478
+ ]);
411
479
 
412
480
  for (const server of servers) {
413
481
  if (normalizeRuntimeProviderId(provider) === 'antigravity' && !result.serversInjected.includes(server.name)) continue;
@@ -415,10 +483,11 @@ async function injectJson(registry, servers, configPath, provider, dryRun, resul
415
483
  }
416
484
  }
417
485
 
486
+
418
487
  return result;
419
488
  }
420
489
 
421
- async function injectToml(registry, servers, configPath, provider, dryRun, result) {
490
+ async function injectToml(registry, servers, configPath, provider, dryRun, result, userScope, projectRoot, toolPlan = null) {
422
491
  let existing = '';
423
492
  try {
424
493
  existing = await readFile(configPath, 'utf-8');
@@ -427,15 +496,15 @@ async function injectToml(registry, servers, configPath, provider, dryRun, resul
427
496
  }
428
497
 
429
498
  for (const server of servers) {
430
- const edited = replaceServer(existing, server.name, buildServerToml(server));
499
+ const filterLines = toolPlan?.tomlLines[server.name] || [];
500
+ const edited = replaceServer(existing, server.name, [buildServerToml(server), ...filterLines].join('\n'));
431
501
  existing = edited.text;
432
502
  if (edited.alreadyPresent) result.alreadyPresent.push(server.name);
433
503
  result.serversInjected.push(server.name);
434
504
  }
435
505
 
436
506
  if (!dryRun) {
437
- await mkdir(resolve(configPath, '..'), { recursive: true });
438
- await writeFile(configPath, existing, 'utf-8');
507
+ await writeConfigAtomic(configPath, existing, { userScope, projectRoot });
439
508
 
440
509
  for (const server of servers) {
441
510
  await registry.recordInjection(server.name, provider);
@@ -0,0 +1,3 @@
1
+ import type { InjectProvider, McpServerDefinition } from './registry.js';
2
+
3
+ export function buildServerConfig(server: McpServerDefinition, provider: InjectProvider): Record<string, unknown>;
@@ -0,0 +1,89 @@
1
+ import { renderCredentialMaps } from './credentials.mjs';
2
+ import { getMcpInjectionDefinition, normalizeRuntimeProviderId } from '../providers/provider-definitions.mjs';
3
+
4
+ export function buildServerConfig(server, provider) {
5
+ const mcpDefinition = getMcpInjectionDefinition(provider);
6
+ // TOML providers render references through their own named keys in
7
+ // buildServerToml; unconditional interpolation would refuse them here even
8
+ // though the TOML writer handles them.
9
+ const { env, headers } = mcpDefinition?.serverConfigFormat === 'toml'
10
+ ? {}
11
+ : renderCredentialMaps(server, normalizeRuntimeProviderId(provider) || provider);
12
+
13
+ switch (mcpDefinition?.serverConfigFormat) {
14
+ case 'claude-code': {
15
+ if (server.type === 'stdio') {
16
+ return {
17
+ command: server.command,
18
+ args: server.args || [],
19
+ ...(env ? { env } : {}),
20
+ };
21
+ }
22
+ // Claude Code skips a url entry that has no type.
23
+ return {
24
+ type: server.type,
25
+ url: server.url,
26
+ ...(headers ? { headers } : {}),
27
+ };
28
+ }
29
+ case 'antigravity': {
30
+ if (server.type === 'stdio') {
31
+ return { command: server.command, args: server.args || [], ...(env ? { env } : {}) };
32
+ }
33
+ return { serverUrl: server.url, ...(headers ? { headers } : {}) };
34
+ }
35
+ case 'standard': {
36
+ if (server.type === 'stdio') {
37
+ return {
38
+ command: server.command,
39
+ args: server.args || [],
40
+ ...(env ? { env } : {}),
41
+ };
42
+ }
43
+ return {
44
+ url: server.url,
45
+ ...(headers ? { headers } : {}),
46
+ };
47
+ }
48
+
49
+ case 'factory': {
50
+ if (server.type === 'stdio') {
51
+ return {
52
+ type: 'stdio',
53
+ command: server.command,
54
+ args: server.args || [],
55
+ disabled: false,
56
+ ...(env ? { env } : {}),
57
+ };
58
+ }
59
+ return {
60
+ type: server.type,
61
+ url: server.url,
62
+ disabled: false,
63
+ ...(headers ? { headers } : {}),
64
+ };
65
+ }
66
+
67
+ case 'opencode': {
68
+ if (server.type === 'stdio') {
69
+ // opencode names a local server's variables `environment`.
70
+ return {
71
+ type: 'local',
72
+ command: [server.command, ...(server.args || [])],
73
+ ...(env ? { environment: env } : {}),
74
+ };
75
+ }
76
+ return {
77
+ type: 'remote',
78
+ url: server.url,
79
+ ...(headers ? { headers } : {}),
80
+ };
81
+ }
82
+
83
+ case 'toml':
84
+ return {};
85
+
86
+ default:
87
+ return {};
88
+ }
89
+ }