@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
@@ -7,9 +7,10 @@
7
7
  * @architecture @.aiwg/architecture/toolsmith-implementation-spec.md
8
8
  */
9
9
 
10
- import { execSync } from 'child_process';
11
- import { readFile, writeFile, mkdir, access } from 'fs/promises';
10
+ import { boundedExecFileSync, boundedExecSync } from '../../process/bounded-child-process.mjs';
11
+ import { readFile, writeFile, mkdir, access, stat } from 'fs/promises';
12
12
  import { existsSync, constants } from 'fs';
13
+ import { createHash } from 'node:crypto';
13
14
  import { resolve, join, dirname } from 'path';
14
15
  import { platform, arch, homedir, tmpdir, cpus, totalmem, freemem } from 'os';
15
16
  import { fileURLToPath } from 'url';
@@ -22,26 +23,59 @@ const __dirname = dirname(__filename);
22
23
  * RuntimeDiscovery - Discovers and catalogs installed system tools
23
24
  */
24
25
  export class RuntimeDiscovery {
25
- constructor(basePath = null) {
26
- this.basePath = basePath || projectAiwgPath(process.cwd(), 'smiths', 'toolsmith');
26
+ constructor(basePath = null, { cwd = process.cwd(), quiet = false } = {}) {
27
+ this.cwd = cwd;
28
+ this.quiet = quiet;
29
+ this.basePath = basePath || projectAiwgPath(this.cwd, 'smiths', 'toolsmith');
27
30
  this.knownTools = this.#loadKnownTools();
28
31
  }
29
32
 
30
33
  /**
31
- * Perform full discovery scan
34
+ * Refresh discovery, skipping version probes when inputs are unchanged.
32
35
  * @returns {Promise<Object>} RuntimeCatalog
33
36
  */
34
- async discover() {
35
- console.log('Starting runtime discovery...');
37
+ async discover({ force = false } = {}) {
38
+ if (!this.quiet) console.log('Starting runtime discovery...');
39
+
40
+ const loaded = await this.#loadCatalog().catch(error => {
41
+ if (error instanceof SyntaxError) return null;
42
+ throw error;
43
+ });
44
+ const previous = Array.isArray(loaded?.tools) ? loaded : null;
45
+ const paths = new Map();
46
+ const inputs = [];
47
+ for (const name of this.#safeTools()) {
48
+ const toolPath = await this.#findToolPath(name);
49
+ paths.set(name, toolPath);
50
+ const metadata = toolPath ? await stat(toolPath).catch(() => null) : null;
51
+ inputs.push([name, toolPath, metadata && [metadata.mtimeMs, metadata.ctimeMs, metadata.size, metadata.mode]]);
52
+ }
53
+ const inputFingerprint = createHash('sha256').update(JSON.stringify([
54
+ 1, this.knownTools, inputs, platform(), arch(), homedir(), this.cwd,
55
+ process.env.PATH, process.env.PATHEXT, process.env.SHELL, process.env.ComSpec,
56
+ ])).digest('hex');
57
+ if (!force && previous?.inputFingerprint === inputFingerprint
58
+ && existsSync(join(this.basePath, 'runtime-info.md'))) {
59
+ if (!this.quiet) console.log(`Discovery skipped: unchanged (${previous.tools.length} tools)`);
60
+ return previous;
61
+ }
36
62
 
37
63
  const environment = await this.getEnvironment();
38
64
  const resources = await this.getResources();
39
- const tools = await this.#discoverTools();
65
+ const tools = await this.#discoverTools(paths);
66
+ const previousIds = new Set((previous?.tools || []).map(tool => tool.id));
67
+ const currentIds = new Set(tools.available.map(tool => tool.id));
68
+ const delta = {
69
+ added: [...currentIds].filter(id => !previousIds.has(id)),
70
+ removed: [...previousIds].filter(id => !currentIds.has(id)),
71
+ };
40
72
 
41
73
  const catalog = {
42
74
  $schema: 'https://aiwg.io/schemas/toolsmith/runtime-catalog-v1.json',
43
75
  version: '1.0',
44
76
  generated: new Date().toISOString(),
77
+ inputFingerprint,
78
+ delta,
45
79
  environment,
46
80
  resources,
47
81
  tools: tools.available,
@@ -52,7 +86,11 @@ export class RuntimeDiscovery {
52
86
  await this.#writeCatalog(catalog);
53
87
  await this.#writeRuntimeInfo(catalog);
54
88
 
55
- console.log(`Discovery complete: ${catalog.tools.length} tools found`);
89
+ if (!this.quiet) console.log(`Discovery complete: ${catalog.tools.length} tools found`);
90
+ if (!this.quiet) console.log(`Tool delta: +${delta.added.length} added, -${delta.removed.length} removed`);
91
+ if (delta.removed.length) {
92
+ if (!this.quiet) console.warn(`Previously cataloged tools no longer available: ${delta.removed.join(', ')}`);
93
+ }
56
94
  return catalog;
57
95
  }
58
96
 
@@ -140,13 +178,13 @@ export class RuntimeDiscovery {
140
178
  }
141
179
  }
142
180
  } else if (os === 'darwin') {
143
- const version = execSync('sw_vers -productVersion', { encoding: 'utf-8' }).trim();
181
+ const version = boundedExecFileSync('sw_vers', ['-productVersion'], 'quick', { encoding: 'utf-8' }).trim();
144
182
  osVersion = `macOS ${version}`;
145
183
  } else if (os === 'win32') {
146
- osVersion = execSync('ver', { encoding: 'utf-8' }).trim();
184
+ osVersion = boundedExecSync('ver', 'quick', { encoding: 'utf-8' }).trim();
147
185
  }
148
186
  } catch (error) {
149
- console.warn('Could not detect OS version:', error.message);
187
+ if (!this.quiet) console.warn('Could not detect OS version:', error.message);
150
188
  }
151
189
 
152
190
  return {
@@ -155,7 +193,7 @@ export class RuntimeDiscovery {
155
193
  arch: arch(),
156
194
  shell: process.env.SHELL || process.env.ComSpec || '/bin/sh',
157
195
  homeDir: homedir(),
158
- workingDir: process.cwd()
196
+ workingDir: this.cwd
159
197
  };
160
198
  }
161
199
 
@@ -172,7 +210,7 @@ export class RuntimeDiscovery {
172
210
  // Disk space
173
211
  if (platform() === 'win32') {
174
212
  // Windows: use wmic
175
- const output = execSync('wmic logicaldisk get size,freespace', { encoding: 'utf-8' });
213
+ const output = boundedExecFileSync('wmic', ['logicaldisk', 'get', 'size,freespace'], 'quick', { encoding: 'utf-8' });
176
214
  const lines = output.trim().split('\n').slice(1);
177
215
  let totalFree = 0;
178
216
  for (const line of lines) {
@@ -184,7 +222,7 @@ export class RuntimeDiscovery {
184
222
  diskFreeGb = Math.round((totalFree / (1024 ** 3)) * 10) / 10;
185
223
  } else {
186
224
  // Unix: use df
187
- const output = execSync('df -k .', { encoding: 'utf-8' });
225
+ const output = boundedExecFileSync('df', ['-k', '.'], 'quick', { encoding: 'utf-8', cwd: this.cwd });
188
226
  const lines = output.trim().split('\n');
189
227
  if (lines.length > 1) {
190
228
  const parts = lines[1].trim().split(/\s+/);
@@ -199,7 +237,7 @@ export class RuntimeDiscovery {
199
237
  memoryTotalGb = Math.round((totalMem / (1024 ** 3)) * 10) / 10;
200
238
  memoryAvailableGb = Math.round((freeMem / (1024 ** 3)) * 10) / 10;
201
239
  } catch (error) {
202
- console.warn('Could not get resource info:', error.message);
240
+ if (!this.quiet) console.warn('Could not get resource info:', error.message);
203
241
  }
204
242
 
205
243
  return {
@@ -298,9 +336,9 @@ export class RuntimeDiscovery {
298
336
  * @see https://git.integrolabs.net/roctinam/aiwg/issues/820
299
337
  * @private
300
338
  */
301
- async #discoverTools() {
339
+ #safeTools() {
302
340
  // Curated list: knownTools database + common dev tools safe to probe
303
- const safeToProbe = new Set([
341
+ return new Set([
304
342
  // From knownTools database
305
343
  ...Object.keys(this.knownTools),
306
344
  // Aliases from knownTools
@@ -328,12 +366,13 @@ export class RuntimeDiscovery {
328
366
  'yq', 'fx', 'miller',
329
367
  'htop', 'ncdu', 'dust', 'procs', 'tokei',
330
368
  ]);
369
+ }
331
370
 
371
+ async #discoverTools(paths) {
332
372
  const available = [];
333
373
  const unavailable = [];
334
374
 
335
- for (const name of safeToProbe) {
336
- const toolPath = await this.#findToolPath(name);
375
+ for (const [name, toolPath] of paths) {
337
376
  if (!toolPath) {
338
377
  // Not installed — skip silently (not an error)
339
378
  continue;
@@ -359,19 +398,38 @@ export class RuntimeDiscovery {
359
398
  }
360
399
 
361
400
  /**
362
- * Find tool path using which/where
401
+ * Search PATH first, then common user installation directories on Unix.
363
402
  * @private
364
403
  */
365
404
  async #findToolPath(toolName) {
366
405
  try {
367
406
  const cmd = platform() === 'win32' ? 'where' : 'which';
368
- const path = execSync(`${cmd} ${toolName}`, { encoding: 'utf-8' })
407
+ const path = boundedExecFileSync(cmd, [toolName], 'quick', { encoding: 'utf-8' })
369
408
  .trim()
370
409
  .split('\n')[0];
371
410
  return path;
372
411
  } catch {
373
- return null;
412
+ // Scheduled jobs often omit user installation directories from PATH.
413
+ }
414
+ if (platform() !== 'win32' && !toolName.includes('/') && !toolName.includes('\\')) {
415
+ const home = homedir();
416
+ const directories = new Set([
417
+ join(process.env.CARGO_HOME || join(home, '.cargo'), 'bin'),
418
+ join(home, '.local', 'bin'), join(home, 'bin'),
419
+ join(home, '.npm-global', 'bin'), join(home, 'go', 'bin'),
420
+ join(home, '.bun', 'bin'), join(home, '.deno', 'bin'),
421
+ ]);
422
+ for (const directory of directories) {
423
+ const candidate = join(directory, toolName);
424
+ try {
425
+ await access(candidate, constants.X_OK);
426
+ if ((await stat(candidate)).isFile()) return candidate;
427
+ } catch {
428
+ // Continue to the next user directory.
429
+ }
430
+ }
374
431
  }
432
+ return null;
375
433
  }
376
434
 
377
435
  /**
@@ -393,15 +451,11 @@ export class RuntimeDiscovery {
393
451
  // Bare `version` (positional) is intentionally excluded: it caused
394
452
  // BPF tools to attach tracepoints, input-leapc to connect to
395
453
  // hostname "version", and cs2cs to open a file named "version".
396
- const versionCommands = [
397
- `${toolPath} --version`,
398
- `${toolPath} -v`,
399
- `${toolPath} -V`
400
- ];
454
+ const versionArgs = ['--version', '-v', '-V'];
401
455
 
402
- for (const cmd of versionCommands) {
456
+ for (const arg of versionArgs) {
403
457
  try {
404
- const output = execSync(cmd, {
458
+ const output = boundedExecFileSync(toolPath, [arg], 'quick', {
405
459
  encoding: 'utf-8',
406
460
  timeout: 3000,
407
461
  killSignal: 'SIGKILL',
@@ -503,7 +557,7 @@ export class RuntimeDiscovery {
503
557
  if (platform() === 'win32') return undefined;
504
558
 
505
559
  try {
506
- const manPath = execSync(`man -w ${toolName}`, {
560
+ const manPath = boundedExecFileSync('man', ['-w', toolName], 'quick', {
507
561
  encoding: 'utf-8',
508
562
  stdio: ['ignore', 'pipe', 'ignore']
509
563
  }).trim();
@@ -9,14 +9,17 @@
9
9
  * @issue #934
10
10
  * @issue #956
11
11
  */
12
- import { existsSync } from 'fs';
13
- import { appendFile, mkdir, readFile, readdir, rm, stat, writeFile } from 'fs/promises';
14
- import { dirname, join, relative, resolve, sep } from 'path';
12
+ import { resolve, sep } from 'path';
13
+ import { pinContainedRoot, readContainedFile, writeContainedFile, appendContainedFile, deleteContainedFile, listContainedFiles } from '../../utils/contained-filesystem.mjs';
15
14
  export class FilesystemAdapter {
16
15
  /** Absolute path where this subsystem's content lives. */
17
16
  root;
17
+ store;
18
18
  constructor(root) {
19
19
  this.root = resolve(root);
20
+ this.store = pinContainedRoot(this.root, undefined, {
21
+ createMissing: true, protectLocationPointer: false, rejectLinkedWrites: true,
22
+ });
20
23
  }
21
24
  /**
22
25
  * Path traversal guard. Rejects `..`, leading `/`, leading `~`, and
@@ -46,89 +49,28 @@ export class FilesystemAdapter {
46
49
  return abs;
47
50
  }
48
51
  async read(path) {
49
- const abs = this.resolveSafe(path);
50
- if (!existsSync(abs))
51
- return null;
52
- return readFile(abs, 'utf-8');
52
+ this.resolveSafe(path);
53
+ return readContainedFile(await this.store, path);
53
54
  }
54
55
  async write(path, content, _meta) {
55
- const abs = this.resolveSafe(path);
56
- await mkdir(dirname(abs), { recursive: true });
57
- await writeFile(abs, content, 'utf-8');
56
+ this.resolveSafe(path);
57
+ await writeContainedFile(await this.store, path, content);
58
58
  }
59
- /**
60
- * Atomic append. Uses fs.appendFile, which opens with O_APPEND so the
61
- * kernel guarantees atomicity for writes ≤ PIPE_BUF (4096 bytes on
62
- * Linux). Concurrent appenders interleave at line granularity rather
63
- * than racing read-then-write. See #976.
64
- */
59
+ /** Append through a verified O_APPEND handle, without read/replace races. */
65
60
  async append(path, content) {
66
- const abs = this.resolveSafe(path);
67
- await mkdir(dirname(abs), { recursive: true });
68
- await appendFile(abs, content, 'utf-8');
61
+ this.resolveSafe(path);
62
+ await appendContainedFile(await this.store, path, content);
69
63
  }
70
64
  async list(prefix) {
71
- // Empty prefix = list everything under root. A non-empty prefix
72
- // restricts to entries whose subsystem-relative path starts with it
73
- // (after path-normalizing the prefix itself).
74
- if (typeof prefix !== 'string') {
65
+ if (typeof prefix !== 'string')
75
66
  throw new Error('storage(fs): list prefix must be a string');
76
- }
77
- if (prefix.length > 0) {
78
- // resolveSafe also validates the prefix shape
67
+ if (prefix)
79
68
  this.resolveSafe(prefix);
80
- }
81
- if (!existsSync(this.root))
82
- return [];
83
- const out = [];
84
- await walkInto(this.root, this.root, prefix, out);
85
- return out;
69
+ return listContainedFiles(await this.store, prefix);
86
70
  }
87
71
  async delete(path) {
88
- const abs = this.resolveSafe(path);
89
- if (!existsSync(abs))
90
- return;
91
- await rm(abs, { force: true });
92
- }
93
- }
94
- async function walkInto(root, dir, prefix, out) {
95
- let entries;
96
- try {
97
- entries = await readdir(dir, { withFileTypes: true });
98
- }
99
- catch {
100
- return;
101
- }
102
- for (const e of entries) {
103
- const full = join(dir, e.name);
104
- const rel = relative(root, full).split(sep).join('/');
105
- if (e.isDirectory()) {
106
- // Descend if the dir could contain matches
107
- if (prefix === '' || rel.startsWith(prefix) || prefix.startsWith(rel + '/')) {
108
- await walkInto(root, full, prefix, out);
109
- }
110
- continue;
111
- }
112
- if (!e.isFile())
113
- continue;
114
- if (prefix !== '' && !rel.startsWith(prefix))
115
- continue;
116
- let size;
117
- let modifiedAt;
118
- try {
119
- const s = await stat(full);
120
- size = s.size;
121
- modifiedAt = s.mtime;
122
- }
123
- catch {
124
- // ignore stat failures
125
- }
126
- const entry = { path: rel };
127
- if (size !== undefined)
128
- entry.size = size;
129
- if (modifiedAt !== undefined)
130
- entry.modifiedAt = modifiedAt;
131
- out.push(entry);
72
+ this.resolveSafe(path);
73
+ await deleteContainedFile(await this.store, path);
132
74
  }
133
75
  }
134
76
  //# sourceMappingURL=fs.js.map
@@ -146,7 +146,7 @@ export class LogseqAdapter {
146
146
  }
147
147
  // Defensive: refuse to write `id::` block IDs ourselves. Logseq
148
148
  // auto-assigns them; if the caller smuggled one in, strip it.
149
- body = body.replace(/^\s*id::\s*[^\n]+\n/gm, '');
149
+ body = stripBlockIds(body);
150
150
  await writeFile(abs, body, 'utf-8');
151
151
  }
152
152
  async list(prefix) {
@@ -221,6 +221,34 @@ function expandHome(p) {
221
221
  }
222
222
  return p;
223
223
  }
224
+ function stripBlockIds(content) {
225
+ const chunks = [];
226
+ let start = 0;
227
+ while (start < content.length) {
228
+ let property = start;
229
+ while (property < content.length && /\s/u.test(content[property]))
230
+ property++;
231
+ if (content.startsWith('id::', property)) {
232
+ // Only the property's own line belongs to the block ID.
233
+ let end = property + 4;
234
+ while (end < content.length && !/[\n\r\u2028\u2029]/u.test(content[end]))
235
+ end++;
236
+ if (content[end] === '\r' && content[end + 1] === '\n')
237
+ end++;
238
+ start = end < content.length ? end + 1 : content.length;
239
+ continue;
240
+ }
241
+ // Keep the original line and any preceding blank lines verbatim.
242
+ let end = property;
243
+ while (end < content.length && !/[\n\r\u2028\u2029]/u.test(content[end]))
244
+ end++;
245
+ if (end < content.length)
246
+ end++;
247
+ chunks.push(content.slice(start, end));
248
+ start = end;
249
+ }
250
+ return chunks.join('');
251
+ }
224
252
  /**
225
253
  * If `content` starts with a `---` YAML block, parse the block and
226
254
  * return the parsed fields plus the body without the YAML. Otherwise
@@ -230,18 +258,51 @@ function expandHome(p) {
230
258
  * Anything more complex falls back to dropping the value as a string.
231
259
  */
232
260
  function extractYamlFrontmatter(content) {
233
- const match = /^---\s*\r?\n([\s\S]*?)\r?\n---\s*\r?\n?([\s\S]*)$/.exec(content);
234
- if (!match)
261
+ if (!content.startsWith('---'))
262
+ return null;
263
+ let openingEnd = 3;
264
+ let firstNewline = -1;
265
+ let lastNewline = -1;
266
+ while (openingEnd < content.length && /\s/u.test(content[openingEnd])) {
267
+ if (content[openingEnd] === '\n') {
268
+ if (firstNewline < 0)
269
+ firstNewline = openingEnd;
270
+ lastNewline = openingEnd;
271
+ }
272
+ openingEnd++;
273
+ }
274
+ if (firstNewline < 0)
235
275
  return null;
236
- const [, yamlBody, body] = match;
276
+ let yamlStart = lastNewline + 1;
277
+ let closing = content.indexOf('\n---', yamlStart);
278
+ if (closing < 0) {
279
+ closing = content.indexOf('\n---', firstNewline + 1);
280
+ if (closing < 0)
281
+ return null;
282
+ yamlStart = firstNewline + 1;
283
+ for (let index = yamlStart; index < closing; index++) {
284
+ if (content[index] === '\n')
285
+ yamlStart = index + 1;
286
+ }
287
+ }
288
+ const yamlBody = content.slice(yamlStart, content[closing - 1] === '\r' ? closing - 1 : closing);
289
+ let bodyStart = closing + 4;
290
+ while (bodyStart < content.length && /\s/u.test(content[bodyStart]))
291
+ bodyStart++;
292
+ const body = content.slice(bodyStart);
237
293
  const fields = {};
238
294
  for (const line of yamlBody.split(/\r?\n/)) {
239
295
  if (line.trim().length === 0 || line.trim().startsWith('#'))
240
296
  continue;
241
- const m = /^([A-Za-z_][A-Za-z0-9_-]*)\s*:\s*(.*)$/.exec(line);
242
- if (!m)
297
+ const separator = line.indexOf(':');
298
+ if (separator < 0)
299
+ continue;
300
+ const k = line.slice(0, separator).trimEnd();
301
+ if (!/^[A-Za-z_][A-Za-z0-9_-]*$/.test(k))
302
+ continue;
303
+ const rawV = line.slice(separator + 1).trimStart();
304
+ if (/[\r\u2028\u2029]/u.test(rawV))
243
305
  continue;
244
- const [, k, rawV] = m;
245
306
  fields[k] = parseYamlScalar(rawV.trim());
246
307
  }
247
308
  return { fields, body };
@@ -96,6 +96,7 @@ export class ObsidianAdapter {
96
96
  execSync('obsidian --version', {
97
97
  stdio: ['ignore', 'pipe', 'pipe'],
98
98
  timeout: 2000,
99
+ killSignal: 'SIGKILL',
99
100
  });
100
101
  }
101
102
  catch {
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { link, mkdir, unlink, writeFile } from "node:fs/promises";
3
3
  import { dirname } from "node:path";
4
- import { execFileSync } from "node:child_process";
4
+ import { boundedExecFileSync } from "../process/bounded-child-process.mjs";
5
5
  export const FORTEMI_QUALIFICATION_RECEIPT = "aiwg.fortemi-live-qualification-receipt/v1";
6
6
  const DIGEST = /^sha256:[0-9a-f]{64}$/;
7
7
  const COMMIT = /^[0-9a-f]{40}$/;
@@ -23,7 +23,7 @@ function hasCompleteOperationInventory(operations) {
23
23
  names.every((name) => REQUIRED_OPERATIONS.has(name)));
24
24
  }
25
25
  export function resolveFortemiQualificationSource(env = process.env, cwd = process.cwd()) {
26
- const git = (...args) => execFileSync("git", args, {
26
+ const git = (...args) => boundedExecFileSync("git", args, 'quick', {
27
27
  cwd,
28
28
  encoding: "utf8",
29
29
  stdio: ["ignore", "pipe", "ignore"],