@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
@@ -17,6 +17,7 @@ import { getFrameworkRoot } from '../../channel/manager.mjs';
17
17
  import { updateInstallation } from '../../update/service.mjs';
18
18
  import { useHandler as useFrameworkHandler } from './use.js';
19
19
  import { projectAiwgPath } from '../../config/project-artifacts.js';
20
+ import { argsTerminatorIndex, hasPositionalOrSwitch, requireFlagValue, valueTokenIndexes } from '../flag-parsing.js';
20
21
  import { checkCollisions, } from '../../smiths/skillsmith/collision-detector.js';
21
22
  import { renderUseDeploymentResult, verifyConfiguredDeployments, } from '../services/deployment-verification.js';
22
23
  /**
@@ -326,6 +327,62 @@ export const validateMetadataHandler = {
326
327
  return result;
327
328
  },
328
329
  };
330
+ /**
331
+ * A directory is a deployed skill only if it carries a SKILL.md manifest —
332
+ * the same marker `isOwnedByNamespace()` in collision-detector.ts reads for
333
+ * ownership. Harness container/bucket directories (e.g. Claude Code's own
334
+ * `.claude/skills/synced/` sync storage, which holds UUID-named dirs with
335
+ * `manifest.json`, not SKILL.md) have no manifest of their own and must
336
+ * never be reported as a colliding skill (#278).
337
+ *
338
+ * A container directory without its own SKILL.md is still descended exactly
339
+ * one level: a real skill nested inside it (`<container>/<skill>/SKILL.md`)
340
+ * is reported as `<container>/<skill>`, while the container itself never is.
341
+ */
342
+ async function hasSkillManifest(dirPath) {
343
+ try {
344
+ await fsp.access(path.join(dirPath, 'SKILL.md'));
345
+ return true;
346
+ }
347
+ catch {
348
+ return false;
349
+ }
350
+ }
351
+ async function collectDeployedSkillDirNames(skillsDir) {
352
+ let topEntries;
353
+ try {
354
+ topEntries = await fsp.readdir(skillsDir, { withFileTypes: true });
355
+ }
356
+ catch {
357
+ return [];
358
+ }
359
+ const names = [];
360
+ for (const entry of topEntries) {
361
+ if (!entry.isDirectory())
362
+ continue;
363
+ const dirPath = path.join(skillsDir, entry.name);
364
+ if (await hasSkillManifest(dirPath)) {
365
+ names.push(entry.name);
366
+ continue;
367
+ }
368
+ let nestedEntries;
369
+ try {
370
+ nestedEntries = await fsp.readdir(dirPath, { withFileTypes: true });
371
+ }
372
+ catch {
373
+ continue;
374
+ }
375
+ for (const nested of nestedEntries) {
376
+ if (!nested.isDirectory())
377
+ continue;
378
+ const nestedPath = path.join(dirPath, nested.name);
379
+ if (await hasSkillManifest(nestedPath)) {
380
+ names.push(path.join(entry.name, nested.name));
381
+ }
382
+ }
383
+ }
384
+ return names;
385
+ }
329
386
  /**
330
387
  * #1156 Phase 1 — Validate the per-user registry at `~/.aiwg/installed.json`.
331
388
  *
@@ -450,8 +507,14 @@ Options:
450
507
  --bundle <name> Limit deployment verification to one bundle
451
508
  --scope <scope> Verification scope: project or user
452
509
  --user Alias for --scope user
510
+ --qualify With --probe-workers, record installation and configured model/role approval
511
+ --yes Confirm worker qualification without a terminal
512
+ --dry-run With --probe-workers, preview qualification without writes
513
+ --cli NAME Limit worker probes/qualification to one configured CLI
514
+ --decision-offload Show offline advisory decision readiness and adoption report
515
+ --probe-workers Run bounded worker CLI version probes (default: config-only, no subprocess)
453
516
  --project-local Include project-local artifact diagnostics
454
- --json Emit machine-readable deployment verification output
517
+ --json Emit machine-readable output (with --probe-workers: one worker-probe record per CLI; with --deployment: deployment verification; with --decision-offload: offline snapshot)
455
518
  --verbose, -v Include verbose diagnostics
456
519
  --help, -h Show this help
457
520
  `;
@@ -477,28 +540,63 @@ export const doctorHandler = {
477
540
  return { exitCode: 0, message: DOCTOR_HELP, rawOutput: true };
478
541
  },
479
542
  async execute(ctx) {
480
- if (ctx.args.includes('--help') || ctx.args.includes('-h')) {
543
+ // Validate before any early-return mode: deployment and user-scope doctor
544
+ // never invoke doctor.mjs, so they must enforce the same flag contract.
545
+ const valueFlags = ['--provider', '--bundle', '--scope', '--context-baseline', '--context-budget-tokens', '--cli'];
546
+ const knownFlags = new Set([
547
+ ...valueFlags, '--all-providers', '--probe-workers', '--qualify', '--yes', '--dry-run', '--no-budget-check', '--strict-context', '--json',
548
+ '--decision-offload', '--deployment', '--user', '--verbose', '-v', '--project-local', '--quiet', '--help', '-h',
549
+ ]);
550
+ const hasSwitch = (name) => hasPositionalOrSwitch(ctx.args, name, valueFlags);
551
+ const values = new Map();
552
+ try {
553
+ for (const flag of valueFlags) {
554
+ values.set(flag, requireFlagValue(ctx.args, { rejectEmpty: true, precedence: 'last' }, flag));
555
+ }
556
+ const consumed = valueTokenIndexes(ctx.args, valueFlags);
557
+ for (let i = 0; i < argsTerminatorIndex(ctx.args); i += 1) {
558
+ const token = ctx.args[i];
559
+ if (consumed.has(i) || !token.startsWith('-'))
560
+ continue;
561
+ const name = token.split('=')[0];
562
+ if (!knownFlags.has(name) || (token.includes('=') && !valueFlags.includes(name))) {
563
+ throw new Error(`Unknown flag: ${name}`);
564
+ }
565
+ }
566
+ if (hasSwitch('--decision-offload') && (hasSwitch('--probe-workers') || hasSwitch('--deployment') || hasSwitch('--user') || values.get('--scope') !== undefined)) {
567
+ throw new Error('--decision-offload is a separate offline mode; do not combine it with worker, deployment or user-scope checks');
568
+ }
569
+ if (['--qualify', '--cli', '--yes', '--dry-run'].some(flag => hasSwitch(flag) || values.get(flag)) && !hasSwitch('--probe-workers')) {
570
+ throw new Error('--qualify, --cli, --yes and --dry-run require --probe-workers');
571
+ }
572
+ if (hasSwitch('--json') && !hasSwitch('--probe-workers') && !hasSwitch('--deployment') && !hasSwitch('--decision-offload')) {
573
+ throw new Error('--json requires --probe-workers or --deployment or --decision-offload');
574
+ }
575
+ }
576
+ catch (error) {
577
+ return { exitCode: 2, message: `${error instanceof Error ? error.message : String(error)}. See 'aiwg doctor --help'.` };
578
+ }
579
+ if (hasSwitch('--help') || hasSwitch('-h')) {
481
580
  return { exitCode: 0, message: DOCTOR_HELP, rawOutput: true };
482
581
  }
483
- if (ctx.args.includes('--deployment')) {
484
- const providerIndex = ctx.args.indexOf('--provider');
485
- const bundleIndex = ctx.args.indexOf('--bundle');
486
- const scopeIndex = ctx.args.indexOf('--scope');
487
- const scopeValue = scopeIndex >= 0 ? ctx.args[scopeIndex + 1] : undefined;
582
+ if (hasSwitch('--deployment')) {
583
+ const scopeValue = values.get('--scope');
488
584
  if (scopeValue && scopeValue !== 'project' && scopeValue !== 'user') {
489
585
  return { exitCode: 2, message: `Invalid deployment verification scope: ${scopeValue}` };
490
586
  }
491
587
  const result = await verifyConfiguredDeployments(ctx.cwd || process.cwd(), {
492
- provider: providerIndex >= 0 ? ctx.args[providerIndex + 1] : undefined,
493
- bundle: bundleIndex >= 0 ? ctx.args[bundleIndex + 1] : undefined,
588
+ provider: values.get('--provider'),
589
+ bundle: values.get('--bundle'),
494
590
  scope: scopeValue,
495
591
  }, ctx.frameworkRoot);
592
+ const { rulePinState } = await import('../../rules/pin-state.js');
593
+ const pins = rulePinState(ctx.cwd, ctx.frameworkRoot);
496
594
  return {
497
595
  exitCode: result.exitCode,
498
- message: ctx.args.includes('--json')
499
- ? JSON.stringify(result, null, 2)
500
- : renderUseDeploymentResult(result),
501
- rawOutput: ctx.args.includes('--json'),
596
+ message: hasSwitch('--json')
597
+ ? JSON.stringify({ ...result, rule_pins: { rules: pins.rules, warnings: pins.warnings } }, null, 2)
598
+ : renderUseDeploymentResult(result) + '\n' + pins.rules.map(rule => `${rule.name}: pinned kernel (canonical ${rule.canonical_activation})`).concat(pins.warnings).join('\n'),
599
+ rawOutput: hasSwitch('--json'),
502
600
  };
503
601
  }
504
602
  // #1156 Phase 1 — `aiwg doctor --scope user` / `aiwg doctor --user`
@@ -506,15 +604,20 @@ export const doctorHandler = {
506
604
  // running the project-scope diagnostics. Operators need this to verify
507
605
  // their user-scope deployments from any cwd, including shells with no
508
606
  // project at all.
509
- const userScopeRequested = ctx.args.includes('--user') ||
510
- (ctx.args.includes('--scope') && ctx.args[ctx.args.indexOf('--scope') + 1] === 'user');
511
- if (userScopeRequested) {
512
- return await runUserScopeDoctor(ctx.args.includes('--verbose') || ctx.args.includes('-v'));
607
+ const userScopeRequested = hasSwitch('--user') || values.get('--scope') === 'user';
608
+ if (userScopeRequested && !hasSwitch('--probe-workers')) {
609
+ return await runUserScopeDoctor(hasSwitch('--verbose') || hasSwitch('-v'));
513
610
  }
514
- const frameworkRoot = await getFrameworkRoot();
611
+ const frameworkRoot = hasSwitch('--decision-offload') ? ctx.frameworkRoot : await getFrameworkRoot();
515
612
  const runner = createScriptRunner(frameworkRoot);
516
613
  // Run core doctor diagnostics
517
614
  const result = await runner.run('tools/cli/doctor.mjs', ctx.args, { cwd: ctx.cwd });
615
+ // Machine-readable worker probes (#3066): tools/cli/doctor.mjs already
616
+ // printed exactly one JSON document (or a usage error) on its own
617
+ // stdio — every section below writes human-readable text, so returning
618
+ // here keeps stdout to the JSON document alone.
619
+ if (hasSwitch('--decision-offload') || hasSwitch('--json') || hasSwitch('--qualify') || hasSwitch('--cli') || hasSwitch('--dry-run') || result.exitCode === 2)
620
+ return result;
518
621
  let agentSkillsFailure = false;
519
622
  try {
520
623
  const { inspectGrokBuildNative } = await import('../../mcp/grok-build-config.mjs');
@@ -562,14 +665,7 @@ export const doctorHandler = {
562
665
  try {
563
666
  const projectDir = ctx.cwd || process.cwd();
564
667
  const skillsDir = path.join(projectDir, '.claude', 'skills');
565
- let deployedSkillNames = [];
566
- try {
567
- const entries = await fsp.readdir(skillsDir, { withFileTypes: true });
568
- deployedSkillNames = entries.filter(e => e.isDirectory()).map(e => e.name);
569
- }
570
- catch {
571
- // No .claude/skills — nothing to check
572
- }
668
+ const deployedSkillNames = await collectDeployedSkillDirNames(skillsDir);
573
669
  if (deployedSkillNames.length > 0) {
574
670
  const collisions = await checkCollisions({
575
671
  platform: 'claude',
@@ -718,6 +814,9 @@ export const contextFirewallHandler = {
718
814
  description: 'Audit provider context and manage its reviewed baseline',
719
815
  category: 'maintenance',
720
816
  aliases: ['-context-firewall', '--context-firewall'],
817
+ async help() {
818
+ return { exitCode: 0, message: CONTEXT_FIREWALL_HELP, rawOutput: true };
819
+ },
721
820
  async execute(ctx) {
722
821
  if (ctx.args.includes('--help') || ctx.args.includes('-h')) {
723
822
  return { exitCode: 0, message: CONTEXT_FIREWALL_HELP };
@@ -55,6 +55,9 @@ function collectFingerprint(versionInfo) {
55
55
  const loggerInfo = getLoggerInfo();
56
56
  const fp = {
57
57
  version: versionInfo.version,
58
+ launcherVersion: versionInfo.launcherVersion ?? versionInfo.version,
59
+ runtimeVersion: versionInfo.runtimeVersion ?? versionInfo.version,
60
+ runtimePath: versionInfo.runtimePath ?? versionInfo.packageRoot,
58
61
  channel: versionInfo.devMode ? 'dev' : versionInfo.channel,
59
62
  packageRoot: versionInfo.packageRoot,
60
63
  node: process.version,
@@ -132,6 +135,11 @@ async function displayVersion(opts) {
132
135
  }
133
136
  ui.blank();
134
137
  console.log(` ${ui.brandMark()} ${ui.bold('aiwg')} ${ui.bold(fp.version)} ${ui.channelLabel(fp.channel)}`);
138
+ if (info.devMode || fp.launcherVersion !== fp.runtimeVersion) {
139
+ ui.dim(` launcher: ${fp.launcherVersion}`);
140
+ ui.dim(` runtime: ${fp.runtimeVersion}`);
141
+ ui.dim(` runtime path: ${fp.runtimePath}`);
142
+ }
135
143
  if (!opts.verbose) {
136
144
  if (fp.git)
137
145
  ui.dim(` git: ${fp.git.sha} (${fp.git.branch})`);
@@ -127,6 +127,78 @@ export async function askChoice(rl, prompt, options, fallback, signal) {
127
127
  return pick;
128
128
  }, pick, label, promptTimeoutMs(), signal);
129
129
  }
130
+ /**
131
+ * Prompt for a strict, distinguishable consent answer. Two differences from
132
+ * {@link askYesNo}, both deliberately scoped to this helper so no existing
133
+ * `askYesNo` call site changes behavior:
134
+ *
135
+ * 1. **Strict parsing**: only a trimmed, case-insensitive `y` or `yes`
136
+ * counts as yes. `askYesNo`'s `startsWith('y')` would also accept
137
+ * `yesterday` or `yolo` — too loose for an irreversible opt-in.
138
+ * 2. **Answered vs. not-answered**: the caller gets a {@link ConsentOutcome}
139
+ * instead of a bare boolean, so a timeout or a closed/EOF'd stdin (the
140
+ * `rl.on('close', ...)` listener settles immediately — it does not wait
141
+ * out the timeout) is distinguishable from an actual "no" answer. A
142
+ * caller that records a persistent decline must only do so for
143
+ * `{ kind: 'answered', value: false }`.
144
+ *
145
+ * Signal abort still rejects (same contract as {@link askWithTimeout}).
146
+ */
147
+ export function askConsent(rl, question, timeoutMs = promptTimeoutMs(), signal) {
148
+ return new Promise((resolve, reject) => {
149
+ let settled = false;
150
+ const cleanup = () => {
151
+ clearTimeout(timer);
152
+ rl.removeListener('close', onClose);
153
+ signal?.removeEventListener('abort', onAbort);
154
+ };
155
+ const timer = setTimeout(() => {
156
+ if (settled)
157
+ return;
158
+ settled = true;
159
+ ui.warn(` No input within ${Math.round(timeoutMs / 1000)}s — leaving the setting unchanged.`);
160
+ cleanup();
161
+ resolve({ kind: 'timeout' });
162
+ }, timeoutMs);
163
+ // See askWithTimeout: unref so a closed event loop never waits on this.
164
+ timer.unref?.();
165
+ // Stdin closing (EOF, piped input exhausted, or the interface being
166
+ // closed elsewhere) must settle immediately, not after the full
167
+ // timeout — a closed stdin must never hang a consent prompt.
168
+ const onClose = () => {
169
+ if (settled)
170
+ return;
171
+ settled = true;
172
+ ui.warn(' Input closed before an answer — leaving the setting unchanged.');
173
+ cleanup();
174
+ resolve({ kind: 'closed' });
175
+ };
176
+ rl.on('close', onClose);
177
+ const onAbort = () => {
178
+ if (settled)
179
+ return;
180
+ settled = true;
181
+ cleanup();
182
+ try {
183
+ rl.close();
184
+ }
185
+ catch { /* already closed */ }
186
+ reject(signal.reason ?? new Error('Aborted'));
187
+ };
188
+ if (signal?.aborted) {
189
+ onAbort();
190
+ return;
191
+ }
192
+ signal?.addEventListener('abort', onAbort, { once: true });
193
+ rl.question(question, (answer) => {
194
+ if (settled)
195
+ return;
196
+ settled = true;
197
+ cleanup();
198
+ resolve({ kind: 'answered', value: ['y', 'yes'].includes(answer.trim().toLowerCase()) });
199
+ });
200
+ });
201
+ }
130
202
  /**
131
203
  * Prompt for a labeled selection from a list of options. Renders each option
132
204
  * as a numbered line before asking. Users can respond by number (1-based) or
@@ -19,6 +19,17 @@ function uniqueProviders(providers) {
19
19
  }
20
20
  return result;
21
21
  }
22
+ /**
23
+ * Sources that say which harness this process is actually running under.
24
+ * `config`, `deployment` and `default` describe the project, not the session:
25
+ * a project deployed for one provider is still not "inside" that provider
26
+ * when a command is run from a plain terminal.
27
+ */
28
+ const SESSION_PROVIDER_SOURCES = new Set(['explicit', 'env', 'runtime-env', 'process']);
29
+ /** True when a resolution came from the running session rather than project state. */
30
+ export function isSessionProviderResolution(resolution) {
31
+ return resolution.provider != null && SESSION_PROVIDER_SOURCES.has(resolution.source);
32
+ }
22
33
  function detectProviderFromRuntimeEnv(env) {
23
34
  const definitions = [...listProviderDefinitions()].sort((a, b) => (a.detection.runtimeEnvPriority ?? Number.MAX_SAFE_INTEGER) - (b.detection.runtimeEnvPriority ?? Number.MAX_SAFE_INTEGER));
24
35
  for (const definition of definitions) {
@@ -75,6 +75,15 @@ export function getHookRegistry() {
75
75
  * ```
76
76
  */
77
77
  export async function run(args, options = {}) {
78
+ // Scheduled index maintenance has no hooks, telemetry, or deployment side effects.
79
+ if (args[0] === 'index' && args[1] === 'refresh'
80
+ && !args.includes('--help') && !args.includes('-h')) {
81
+ const { runIndexRefresh } = await import('../artifacts/index-refresh.js');
82
+ const report = await runIndexRefresh(args.slice(2), options.cwd ?? process.cwd(), options.signal);
83
+ if (report.totals.errors)
84
+ process.exit(1);
85
+ return;
86
+ }
78
87
  const started = process.hrtime.bigint();
79
88
  const registry = await initRouter();
80
89
  // Normalize `help <command>` into the same non-executing help path.
@@ -320,7 +329,12 @@ async function logCommandInvocation(input) {
320
329
  * @returns Handler context
321
330
  */
322
331
  async function buildContext(args, rawArgs, options) {
323
- const frameworkRoot = await getFrameworkRoot({ createIfMissing: !args.includes('--dry-run') });
332
+ const readOnlyRuleInventory = rawArgs[0] === 'rules' && ['inventory', 'list'].includes(args[0]);
333
+ const readOnlyOffloadReport = (['doctor', '-doctor', '--doctor'].includes(rawArgs[0] ?? '') && args.includes('--decision-offload'))
334
+ || (rawArgs[0] === 'steward' && args[0] === 'decision-offload');
335
+ const frameworkRoot = await getFrameworkRoot({
336
+ createIfMissing: !args.includes('--dry-run') && !readOnlyRuleInventory && !readOnlyOffloadReport,
337
+ });
324
338
  const ctx = {
325
339
  args,
326
340
  rawArgs,
@@ -1,5 +1,6 @@
1
1
  import { access, readFile, readdir, stat } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
+ import { loadPrebuiltDeploymentIndex } from '../../artifacts/prebuilt-deployment.js';
3
4
  import { loadGraphIndexFile } from '../../artifacts/index-reader.js';
4
5
  import { readAiwgConfig } from '../../config/aiwg-config.js';
5
6
  import { readUserRegistry } from '../../config/user-registry.js';
@@ -102,7 +103,7 @@ export function normalizeFrameworkDiscoveryInventory(stats) {
102
103
  };
103
104
  }
104
105
  function frameworkDiscoveryInventory(frameworkRoot) {
105
- const stats = loadGraphIndexFile(frameworkRoot, 'stats.json', 'framework');
106
+ const stats = loadPrebuiltDeploymentIndex(frameworkRoot, { strictRoot: true })?.stats ?? loadGraphIndexFile(frameworkRoot, 'stats.json', 'framework');
106
107
  return stats ? normalizeFrameworkDiscoveryInventory(stats) : null;
107
108
  }
108
109
  const BUNDLE_INDEX_TOKENS = {
@@ -510,9 +511,11 @@ export async function verifyProviderDeployment(options) {
510
511
  const frameworkBundles = options.requestedBundles.filter((bundle) => !projectLocalBundles.includes(bundle));
511
512
  const indexesToVerify = [];
512
513
  if (frameworkBundles.length > 0) {
514
+ const prebuilt = loadPrebuiltDeploymentIndex(options.frameworkRoot, { strictRoot: true });
513
515
  indexesToVerify.push({
514
- index: loadGraphIndexFile(options.frameworkRoot, 'metadata.json', 'framework'),
515
- stats: loadGraphIndexFile(options.frameworkRoot, 'stats.json', 'framework'),
516
+ index: prebuilt?.index ?? loadGraphIndexFile(options.frameworkRoot, 'metadata.json', 'framework'),
517
+ stats: prebuilt?.stats ?? loadGraphIndexFile(options.frameworkRoot, 'stats.json', 'framework'),
518
+ prebuiltValidated: Boolean(prebuilt),
516
519
  graph: 'framework',
517
520
  bundles: frameworkBundles,
518
521
  });
@@ -521,11 +524,12 @@ export async function verifyProviderDeployment(options) {
521
524
  const graph = options.scope === 'user' ? 'user' : 'project';
522
525
  indexesToVerify.push({
523
526
  index: loadGraphIndexFile(options.projectRoot, 'metadata.json', graph),
527
+ stats: loadGraphIndexFile(options.projectRoot, 'stats.json', graph),
524
528
  graph,
525
529
  bundles: projectLocalBundles,
526
530
  });
527
531
  }
528
- for (const { index, stats, graph, bundles } of indexesToVerify) {
532
+ for (const { index, stats, graph, bundles, prebuiltValidated } of indexesToVerify) {
529
533
  if (!index || !index.entries || Object.keys(index.entries).length === 0) {
530
534
  findings.push(finding(normalized, `index-unreadable:${graph}`, 'blocking', `The ${graph} capability index is missing, unreadable, or empty.`, `Run aiwg index build --graph ${graph}, then re-run the same aiwg use command.`));
531
535
  continue;
@@ -550,11 +554,14 @@ export async function verifyProviderDeployment(options) {
550
554
  if (!surfacePresent) {
551
555
  findings.push(finding(normalized, `index-surface-missing:${graph}`, 'blocking', `The ${graph} capability index does not contain the requested bundle surface.`, `Rebuild the ${graph} index from the selected AIWG source and re-run aiwg use.`, { requestedBundles: bundles, entryCount: entryPaths.length }));
552
556
  }
553
- if (options.invocationStartedAt) {
554
- const builtAt = Date.parse(index.builtAt);
557
+ if (options.invocationStartedAt && !prebuiltValidated) {
558
+ // No-op builds preserve metadata bytes and record the refresh in stats.
559
+ const refreshedAt = Math.max(...[index.builtAt, stats?.builtAt]
560
+ .map((timestamp) => Date.parse(timestamp ?? ''))
561
+ .filter(Number.isFinite));
555
562
  const startedAt = Date.parse(options.invocationStartedAt);
556
- if (!Number.isFinite(builtAt) || builtAt + 2_000 < startedAt) {
557
- findings.push(finding(normalized, `index-stale:${graph}`, 'blocking', `The ${graph} capability index was not refreshed during this deployment.`, `Re-run aiwg use after correcting the ${graph} index build failure.`, { graph, builtAt: index.builtAt, invocationStartedAt: options.invocationStartedAt }));
563
+ if (!Number.isFinite(refreshedAt) || refreshedAt + 2_000 < startedAt) {
564
+ findings.push(finding(normalized, `index-stale:${graph}`, 'blocking', `The ${graph} capability index was not refreshed during this deployment.`, `Re-run aiwg use after correcting the ${graph} index build failure.`, { graph, builtAt: index.builtAt, statsBuiltAt: stats?.builtAt, invocationStartedAt: options.invocationStartedAt }));
558
565
  }
559
566
  }
560
567
  }
@@ -569,7 +576,7 @@ export async function verifyProviderDeployment(options) {
569
576
  }
570
577
  const requiredContext = [
571
578
  path.join(options.projectRoot, 'WORKSPACE.md'),
572
- path.join(options.projectRoot, 'AIWG.md'),
579
+ ...(definition?.paths.contextFiles.aiwgMd === false ? [] : [path.join(options.projectRoot, 'AIWG.md')]),
573
580
  path.join(options.projectRoot, '.aiwg', 'AIWG.md'),
574
581
  ];
575
582
  for (const contextPath of requiredContext) {
@@ -773,9 +780,12 @@ export async function buildDeploymentStatusProbe(projectRoot, frameworkRoot = pr
773
780
  const notConfigured = result.requestedBundles.length === 0
774
781
  && result.findings.length > 0
775
782
  && result.findings.every((item) => item.id === 'deployment-not-configured');
783
+ const { rulePinState } = await import('../../rules/pin-state.js');
784
+ const rulePins = rulePinState(projectRoot, frameworkRoot);
776
785
  const engaged = result.outcome === 'ready' || result.outcome === 'ready-restart-required' || result.outcome === 'degraded';
777
786
  return {
778
787
  schema: 'aiwg.status.probe.v1',
788
+ rule_pins: { rules: rulePins.rules, warnings: rulePins.warnings },
779
789
  generated_at: result.generatedAt,
780
790
  project_root: result.projectRoot,
781
791
  engaged,
@@ -0,0 +1,24 @@
1
+ import path from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ export async function prepareProviderDeployments(frameworkRoot, jobs) {
4
+ const deployerUrl = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'deploy-agents.mjs')).href;
5
+ const deployer = await import(deployerUrl);
6
+ // Commands-to-skills migration is interactive and changes provider inputs.
7
+ // Run it serially in the coordinator before the shared snapshot is created;
8
+ // finalization then only applies post-deploy mirrors/pruning/config writes.
9
+ for (const job of jobs)
10
+ await deployer.main(job.args, { preflightOnly: true });
11
+ const url = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'providers', 'provider-prepare-coordinator.mjs')).href;
12
+ const coordinator = await import(url);
13
+ const sourceIndex = jobs[0]?.args.findIndex(arg => arg === '--source') ?? -1;
14
+ const srcRoot = sourceIndex >= 0 && jobs[0]?.args[sourceIndex + 1]
15
+ ? path.resolve(jobs[0].args[sourceIndex + 1])
16
+ : frameworkRoot;
17
+ return coordinator.prepareProviderDeployments({ srcRoot, jobs, maxConcurrency: 2 });
18
+ }
19
+ export async function finalizePreparedProvider(frameworkRoot, args) {
20
+ const url = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'deploy-agents.mjs')).href;
21
+ const deployer = await import(url);
22
+ await deployer.main(args, { finalizeOnly: true });
23
+ }
24
+ //# sourceMappingURL=provider-prepare-coordinator.js.map
@@ -3,7 +3,7 @@ import { createReadStream, existsSync } from 'fs';
3
3
  import { createHash } from 'crypto';
4
4
  import { createInterface } from 'readline';
5
5
  import path from 'path';
6
- import os from 'os';
6
+ import { getUserStateDir } from '../config/user-state.js';
7
7
  import { readAiwgConfig } from '../config/aiwg-config.js';
8
8
  import { PROJECT_AIWG_LOCATION_FILE, projectAiwgPath, projectControlPath, } from '../config/project-artifacts.js';
9
9
  const DEFAULT_MAX_BYTES = 1_048_576;
@@ -487,8 +487,7 @@ function resolveUsagePath(scope, projectRoot, env) {
487
487
  return null;
488
488
  return projectAiwgPath(projectRoot, 'telemetry', 'skill-usage.jsonl');
489
489
  }
490
- const stateHome = env.XDG_STATE_HOME || path.join(os.homedir(), '.local', 'state');
491
- return path.join(stateHome, 'aiwg', 'skill-usage.jsonl');
490
+ return path.join(getUserStateDir(env), 'skill-usage.jsonl');
492
491
  }
493
492
  async function appendBoundedJsonl(filePath, event, maxBytes) {
494
493
  await mkdir(path.dirname(filePath), { recursive: true });