@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
@@ -0,0 +1,28 @@
1
+ import type { Stats } from 'node:fs';
2
+
3
+ export function assertNoSymlinkParents(file: string, configRoot?: string): Promise<void>;
4
+ export function assertConfigDestination(file: string, projectRoot?: string): Promise<Stats | null>;
5
+ export function isUserMcpScope(provider: string, scope?: string): boolean;
6
+ export function isPathInsideDir(file: string, dir: string): boolean;
7
+ export function assertSupportedScope(provider: string, scope: string | undefined, configPath: string, projectDir?: string): void;
8
+ export function classifyMcpDestination(provider: string, scope: string | undefined, configPath: string, projectDir?: string): { userScope: boolean; projectRoot: string | undefined };
9
+ export function projectCredentialRemedy(provider: string, projectDir?: string): string;
10
+ export function assertProjectCredentials(servers: Array<{ name: string; url?: string; args?: string[]; env?: Record<string, unknown>; headers?: Record<string, unknown>; auth?: Record<string, unknown>; oauth?: Record<string, unknown> }>, configPath: string, remedy?: string): void;
11
+ export function assertConfigObject(config: unknown, serversKey: string): void;
12
+ export interface ConfigWriteOptions {
13
+ userScope?: boolean;
14
+ rejectSymlinkParents?: boolean;
15
+ symlinkRoot?: string;
16
+ projectRoot?: string;
17
+ newFileMode?: number;
18
+ mode?: number;
19
+ }
20
+ export interface ConfigWrite {
21
+ file: string;
22
+ content: string | Uint8Array;
23
+ options?: ConfigWriteOptions;
24
+ }
25
+ export function writeConfigAtomic(file: string, content: string | Uint8Array, options?: ConfigWriteOptions): Promise<void>;
26
+ export function canonicalConfigPath(file: string): Promise<string>;
27
+ export function prepareConfigWrite(file: string, options?: ConfigWriteOptions): Promise<void>;
28
+ export function writeConfigTransaction(writes: ConfigWrite[]): Promise<void>;
@@ -0,0 +1,279 @@
1
+ import { urlCarriesUserinfo, credentialLikeArgs, credentialLikeQueryParams, credentialLikeFragmentParams, isCredentialReferenceValue } from './credentials.mjs';
2
+ import { access, lstat, mkdir, open, readFile, realpath, rename, unlink } from 'node:fs/promises';
3
+ import { basename, dirname, isAbsolute, relative, resolve, sep } from 'node:path';
4
+ import { constants } from 'node:fs';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { getMcpInjectionDefinition, resolveMcpConfigPath } from '../providers/provider-definitions.mjs';
7
+
8
+ export async function assertNoSymlinkParents(file, configRoot = dirname(resolve(file))) {
9
+ const root = resolve(configRoot);
10
+ const rel = relative(root, resolve(file));
11
+ if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
12
+ throw new Error(`MCP config ${file} must be beneath the config directory ${root}`);
13
+ }
14
+ let parent = dirname(resolve(file));
15
+ while (parent !== root) {
16
+ try {
17
+ if ((await lstat(parent)).isSymbolicLink()) {
18
+ throw new Error(`Refusing to write MCP config ${file}: parent directory is a symlink`);
19
+ }
20
+ } catch (error) {
21
+ if (error.code !== 'ENOENT') throw error;
22
+ }
23
+ parent = dirname(parent);
24
+ }
25
+ }
26
+
27
+ export async function assertConfigDestination(file, projectRoot) {
28
+ if (projectRoot) {
29
+ const root = resolve(projectRoot);
30
+ const rel = relative(root, resolve(file));
31
+ if (!rel || rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
32
+ throw new Error(`MCP config ${file} must be beneath the project directory`);
33
+ }
34
+ let current = root;
35
+ for (const component of rel.split(sep).slice(0, -1)) {
36
+ current = resolve(current, component);
37
+ try {
38
+ if ((await lstat(current)).isSymbolicLink()) {
39
+ throw new Error(`Refusing to write MCP config ${file}: parent directory is a symlink`);
40
+ }
41
+ } catch (error) {
42
+ if (error.code !== 'ENOENT') throw error;
43
+ }
44
+ }
45
+ }
46
+ try {
47
+ const info = await lstat(file);
48
+ if (info.isSymbolicLink()) throw new Error(`Refusing to write MCP config ${file}: destination is a symlink`);
49
+ return info;
50
+ } catch (error) {
51
+ if (error.code === 'ENOENT') return null;
52
+ throw error;
53
+ }
54
+ }
55
+
56
+ export function isUserMcpScope(provider, scope) {
57
+ return scope === 'user' || getMcpInjectionDefinition(provider)?.configPath.scope === 'home';
58
+ }
59
+
60
+ /** True when the resolved destination lives inside the project directory. */
61
+ export function isPathInsideDir(file, dir) {
62
+ const root = resolve(dir);
63
+ const rel = relative(root, resolve(file));
64
+ return Boolean(rel) && rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);
65
+ }
66
+
67
+ /**
68
+ * Refuse a `--scope user` request the provider cannot honour: when the
69
+ * resolved destination is still the project file, the request would silently
70
+ * write secrets to a shareable location. Providers whose destination is
71
+ * genuinely outside the project (home configs, explicit user paths) pass.
72
+ */
73
+ export function assertSupportedScope(provider, scope, configPath, projectDir = '.') {
74
+ if (scope !== 'user') return;
75
+ if (!isPathInsideDir(configPath, projectDir)) return;
76
+ throw new Error(`Provider "${provider}" has no user-scope destination: --scope user would still write the project file ${configPath}. Use --scope project with --header-env/--env-from references instead of literal credentials.`);
77
+ }
78
+
79
+ /**
80
+ * The single place every MCP config writer - `inject`, `install`, and OMP's
81
+ * `install`/`uninject` - decides whether a destination is a project write.
82
+ * The decision follows the RESOLVED destination, never the requested scope
83
+ * string and never a provider's home-directory override (e.g.
84
+ * `PI_CODING_AGENT_DIR`, `CODEX_HOME`, `GROK_HOME`): a destination that still
85
+ * resolves inside the project directory gets project containment rules
86
+ * (ancestor-symlink checks, literal-credential refusal) regardless of what
87
+ * scope was requested or which environment variable produced the path.
88
+ * `userScope: true` from this function means the destination is genuinely
89
+ * outside the project; callers must never override it with a flag of their
90
+ * own, and must never derive it from `scope` again downstream.
91
+ *
92
+ * Throws via `assertSupportedScope` when `--scope user` was requested but the
93
+ * destination is still inside the project (no private destination exists).
94
+ */
95
+ export function classifyMcpDestination(provider, scope, configPath, projectDir = '.') {
96
+ assertSupportedScope(provider, scope, configPath, projectDir);
97
+ const inProject = isPathInsideDir(configPath, projectDir);
98
+ return { userScope: !inProject, projectRoot: inProject ? projectDir : undefined };
99
+ }
100
+
101
+ /**
102
+ * Remediation for a project-scope literal refusal that names the provider's
103
+ * real private destination when it has one, instead of always naming
104
+ * ~/.claude.json. Providers without a user-scope destination get reference
105
+ * guidance instead.
106
+ */
107
+ export function projectCredentialRemedy(provider, projectDir = '.') {
108
+ try {
109
+ const userPath = resolveMcpConfigPath(provider, projectDir, { scope: 'user' });
110
+ const projectPath = resolveMcpConfigPath(provider, projectDir, { scope: 'project' });
111
+ if (userPath && userPath !== projectPath && !isPathInsideDir(userPath, projectDir)) {
112
+ return `Use --scope user to write private ${userPath} instead, or move secrets into environment variables with --header-env/--env-from references.`;
113
+ }
114
+ } catch {
115
+ // An unresolvable user destination means references are the only remedy.
116
+ }
117
+ return `Move secrets into environment variables with --header-env/--env-from references instead; --scope user has no private destination for provider "${provider}".`;
118
+ }
119
+
120
+ /** Reject non-string env/headers values with a schema-style error. */
121
+ function assertStringMap(server, field) {
122
+ const entries = server[field];
123
+ if (entries === undefined || entries === null) return {};
124
+ if (typeof entries !== 'object' || Array.isArray(entries)) {
125
+ throw new Error(`Invalid MCP server "${server.name}": ${field} must be an object`);
126
+ }
127
+ for (const [key, value] of Object.entries(entries)) {
128
+ if (typeof value !== 'string') {
129
+ throw new Error(`Invalid MCP server "${server.name}": ${field}["${key}"] must be a string`);
130
+ }
131
+ }
132
+ return entries;
133
+ }
134
+
135
+ export function assertProjectCredentials(servers, configPath, remedy) {
136
+ const literals = servers.flatMap(server => {
137
+ const reasons = [];
138
+ // A value is shareable only when it is empty or a supported reference
139
+ // form (${VAR}, ${env:VAR}, {env:VAR}); any other string is a literal.
140
+ for (const field of ['env', 'headers']) {
141
+ const entries = assertStringMap(server, field);
142
+ const literalKeys = Object.entries(entries)
143
+ .filter(([, value]) => value !== '' && !isCredentialReferenceValue(value))
144
+ .map(([key]) => key);
145
+ if (literalKeys.length) reasons.push(`${server.name} has literal ${field} values (${literalKeys.join(', ')})`);
146
+ }
147
+ // OMP persists auth/oauth beside env/headers, so the same refusal covers
148
+ // any secret-bearing value there; `type` alone selects a flow, not a secret.
149
+ // This deliberately includes all URL fields (tokenUrl/redirectUri/resource),
150
+ // so OAuth query and fragment credentials cannot bypass project protection.
151
+ for (const field of ['auth', 'oauth']) {
152
+ const section = server[field];
153
+ if (section !== undefined && section !== null) {
154
+ if (typeof section !== 'object' || Array.isArray(section)) {
155
+ throw new Error(`Invalid MCP server "${server.name}": ${field} must be an object`);
156
+ }
157
+ const literalKeys = Object.keys(section).filter(key =>
158
+ key !== 'type' && section[key] !== '' && section[key] !== undefined && section[key] !== null);
159
+ if (literalKeys.length) reasons.push(`${server.name} has literal ${field} values (${literalKeys.join(', ')})`);
160
+ }
161
+ }
162
+ if (urlCarriesUserinfo(server.url)) reasons.push(`${server.name} has URL userinfo`);
163
+ if (credentialLikeQueryParams(server.url).length) reasons.push(`${server.name} has URL query credentials`);
164
+ if (credentialLikeFragmentParams(server.url).length) reasons.push(`${server.name} has URL fragment credentials`);
165
+ // A flag like --token=... or --password <value> almost always carries the secret
166
+ // in argv, visible to every process listing on the host; the same literal-credential
167
+ // refusal that applies to env/headers applies here for a shareable project file.
168
+ // Name only the flag, never the "--flag=value" form's value half.
169
+ const argFlags = credentialLikeArgs(server.args).map(arg =>
170
+ /^--?[A-Za-z][A-Za-z0-9_-]*(?=[ =]|$)/.exec(arg)?.[0] || '[redacted]');
171
+ if (argFlags.length) reasons.push(`${server.name} has credential-like args (${argFlags.join(', ')})`);
172
+ return reasons;
173
+ });
174
+ if (literals.length) {
175
+ throw new Error(`Refusing to write project MCP config ${configPath}: ${literals.join('; ')}. ${remedy || 'Use --scope user to write to a private destination instead.'}`);
176
+ }
177
+ }
178
+
179
+ export function assertConfigObject(config, serversKey) {
180
+ const isObject = value => value !== null && typeof value === 'object' && !Array.isArray(value);
181
+ if (!isObject(config) || (Object.hasOwn(config, serversKey) && !isObject(config[serversKey]))) {
182
+ throw new Error('MCP configuration must contain an object root and an object server map');
183
+ }
184
+ }
185
+
186
+ export async function writeConfigAtomic(file, content, { userScope = false, projectRoot, newFileMode, mode: restoreMode, rejectSymlinkParents = false, symlinkRoot } = {}) {
187
+ if (rejectSymlinkParents) await assertNoSymlinkParents(file, symlinkRoot);
188
+ const info = await assertConfigDestination(file, projectRoot);
189
+ const mode = restoreMode ?? (userScope ? 0o600 : info ? info.mode & 0o7777 : newFileMode ?? 0o666);
190
+ await mkdir(dirname(file), { recursive: true });
191
+ const temporary = `${file}.${randomUUID()}.tmp`;
192
+ let handle;
193
+ try {
194
+ handle = await open(temporary, 'wx', mode);
195
+ await handle.writeFile(content, 'utf-8');
196
+ if (userScope || info || restoreMode !== undefined || newFileMode !== undefined) await handle.chmod(mode);
197
+ await handle.sync();
198
+ await handle.close();
199
+ handle = undefined;
200
+ if (rejectSymlinkParents) await assertNoSymlinkParents(file, symlinkRoot);
201
+ await assertConfigDestination(file, projectRoot);
202
+ await rename(temporary, file);
203
+ } finally {
204
+ try {
205
+ if (handle) await handle.close();
206
+ } finally {
207
+ await unlink(temporary).catch(() => {});
208
+ }
209
+ }
210
+ }
211
+
212
+ /** Resolve existing parent aliases without creating directories during a dry run. */
213
+ export async function canonicalConfigPath(file) {
214
+ let parent = dirname(resolve(file));
215
+ const missing = [];
216
+ while (true) {
217
+ try {
218
+ return resolve(await realpath(parent), ...missing, basename(file));
219
+ } catch (error) {
220
+ if (error.code !== 'ENOENT' || dirname(parent) === parent) throw error;
221
+ missing.unshift(basename(parent));
222
+ parent = dirname(parent);
223
+ }
224
+ }
225
+ }
226
+
227
+ /** Check the destination and the nearest existing parent before a multi-file write. */
228
+ export async function prepareConfigWrite(file, options = {}) {
229
+ await assertConfigDestination(file, options.projectRoot);
230
+ let parent = dirname(resolve(file));
231
+ while (true) {
232
+ try {
233
+ // Follow a root/home alias, just as assertConfigDestination does.
234
+ const actual = await realpath(parent);
235
+ if (!(await lstat(actual)).isDirectory()) throw new Error(`Config parent ${parent} must be a directory`);
236
+ await access(actual, constants.W_OK | constants.X_OK);
237
+ return;
238
+ } catch (error) {
239
+ if (error.code !== 'ENOENT' || dirname(parent) === parent) {
240
+ throw new Error(`Cannot prepare config destination ${file}: ${error.message}`);
241
+ }
242
+ parent = dirname(parent);
243
+ }
244
+ }
245
+ }
246
+
247
+ /** Write MCP, settings and ownership in the supplied order, restoring earlier files on failure. */
248
+ export async function writeConfigTransaction(writes) {
249
+ const originals = [];
250
+ for (const { file, options = {} } of writes) {
251
+ await prepareConfigWrite(file, options);
252
+ const info = await assertConfigDestination(file, options.projectRoot);
253
+ originals.push(info ? { content: await readFile(file), mode: info.mode & 0o7777 } : null);
254
+ }
255
+ let completed = 0;
256
+ try {
257
+ for (const { file, content, options } of writes) {
258
+ await writeConfigAtomic(file, content, options);
259
+ completed++;
260
+ }
261
+ } catch (error) {
262
+ const failures = [];
263
+ for (let index = completed - 1; index >= 0; index--) {
264
+ const { file, options = {} } = writes[index];
265
+ try {
266
+ if (originals[index]) {
267
+ await writeConfigAtomic(file, originals[index].content, { ...options, mode: originals[index].mode });
268
+ } else {
269
+ await assertConfigDestination(file, options.projectRoot);
270
+ await unlink(file);
271
+ }
272
+ } catch (rollbackError) {
273
+ failures.push(`${file}: ${rollbackError.message}`);
274
+ }
275
+ }
276
+ if (failures.length) throw new Error(`${error.message}; config rollback failed: ${failures.join('; ')}`);
277
+ throw error;
278
+ }
279
+ }
@@ -0,0 +1,36 @@
1
+ export interface Layering {
2
+ lowerPolicy?: import('./credentials.mjs').McpCredentialPolicy;
3
+ /** Config file of the lower layer that set `lowerPolicy`, for diagnostics. */
4
+ lowerPolicySource?: string;
5
+ ownPolicy?: import('./credentials.mjs').McpCredentialPolicy;
6
+ effectivePolicy?: import('./credentials.mjs').McpCredentialPolicy;
7
+ lower: Map<string, string>;
8
+ own: Set<string>;
9
+ lowerFields: Map<string, string>;
10
+ ownFields: Set<string>;
11
+ }
12
+
13
+ export function resolveConfigLayers(
14
+ configDirOverride?: string,
15
+ env?: Record<string, string | undefined>,
16
+ options?: { platform?: string },
17
+ ): string[] | null;
18
+ export function loadLayered<T extends object>(
19
+ layers: string[],
20
+ filename: string,
21
+ collection: string,
22
+ defaults: T,
23
+ ): Promise<{ data: T; layering: Layering }>;
24
+ export function isLowerLayerEntry(layering: Layering, name: string): boolean;
25
+ export function lowerEntryQualified(layering: Layering, name: string): boolean;
26
+ export function writeLayerData<T extends object>(data: T, collection: string, layering: Layering, explicitPolicy?: boolean): T;
27
+ export function resolveProfileExtends<P extends {
28
+ extends?: string[];
29
+ servers?: string[];
30
+ providerOverrides?: Record<string, { toolDeny?: string[]; toolAllow?: string[] }>;
31
+ }>(name: string, profiles: Record<string, P>, seen?: string[]): P & { servers: string[] };
32
+
33
+ export function assertLayerWriteDestination(layers: string[], filename: string): Promise<void>;
34
+ export function saveLayerData(file: string, data: object, collection: string, layers: string[] | null, layering: Layering | null, explicitPolicy?: boolean): Promise<void>;
35
+
36
+ export function isCaseInsensitivePath(path: string): Promise<boolean>;