@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
@@ -22,6 +22,7 @@
22
22
  * @tests @test/unit/artifacts/citation-parser.test.ts
23
23
  */
24
24
  import { parseFrontmatter } from './index-builder.js';
25
+ import { CITATION_HEADER_ALIASES, CITATION_SECTION_ALIASES } from './citation-table-schema.js';
25
26
  /**
26
27
  * Match a single node identifier (REF-* or PROF-*) anywhere in a string.
27
28
  * Used by `extractRefsFromTable` to pull every ID out of a table cell.
@@ -33,31 +34,71 @@ const NODE_ID_PATTERN = /(?:REF-\d+[a-z]?|PROF-[POFG]-[a-z0-9-]+)/g;
33
34
  * frontmatter `ref` values.
34
35
  */
35
36
  const NODE_ID_FULL = /^(?:REF-\d+[a-z]?|PROF-[POFG]-[a-z0-9-]+)$/;
36
- /** Explicit column aliases used by historical citation-sidecar variants. */
37
- const CITATION_REF_COLUMNS = [
38
- 'Inducted REF',
39
- 'REF',
40
- 'Corpus REF',
41
- 'In-corpus REF',
42
- ];
43
- /**
44
- * Preserve the corpus snapshot's legacy edge semantics: every node ID on a
45
- * pipe-delimited line inside an outgoing/incoming section is a declaration.
46
- * Explicit column parsing remains the primary path, while this compatibility
47
- * scan covers malformed rows and prose continuations that historical corpus
48
- * snapshots already count.
49
- */
50
- function extractSectionNodeIds(section) {
51
- const refs = [];
52
- for (const line of section.split('\n')) {
53
- if (!line.includes('|'))
54
- continue;
55
- NODE_ID_PATTERN.lastIndex = 0;
56
- const matches = line.match(NODE_ID_PATTERN);
57
- if (matches)
58
- refs.push(...matches);
37
+ /** An unnamed resolution cell must contain only one REF, optionally decorated. */
38
+ function standaloneRef(value) {
39
+ let text = value.trim();
40
+ const link = text.match(/^\[([^\]]+)\]\([^\s]+(?:\s+"[^"\n]*")?\)$/);
41
+ if (link)
42
+ text = link[1].trim();
43
+ const code = text.match(/^`([^`]+)`$/);
44
+ if (code)
45
+ text = code[1].trim();
46
+ return /^REF-\d+[a-z]?$/.test(text) ? text : null;
47
+ }
48
+ /** Resolution aliases are shared by every registered bibliographic form. */
49
+ const CITATION_REF_COLUMNS = CITATION_HEADER_ALIASES.ref;
50
+ const HEADER_ROLES = new Map(Object.entries(CITATION_HEADER_ALIASES).flatMap(([role, aliases]) => aliases.map(alias => [alias, role])));
51
+ function normalizeCell(value) {
52
+ return value.toLowerCase().replace(/[`*_]/g, '').replace(/\s+/g, ' ').trim();
53
+ }
54
+ /** Direction belongs to the heading, never to a mention in its section body. */
55
+ function citationDirection(heading) {
56
+ const text = normalizeCell(heading.replace(/[ \t]+#+[ \t]*$/, ''));
57
+ const segment = text.split(/[/—:(]/, 1)[0].trim();
58
+ // Keep the corpus's Incoming/Outgoing descriptions, with a word boundary
59
+ // so unrelated words such as "Incomingish" cannot declare citations.
60
+ if (/^incoming(?:\s|$)/.test(segment))
61
+ return 'incoming';
62
+ if (/^outgoing(?:\s|$)/.test(segment))
63
+ return 'outgoing';
64
+ for (const direction of ['incoming', 'outgoing']) {
65
+ if (CITATION_SECTION_ALIASES[direction].some(alias => text === alias
66
+ || (text.startsWith(alias) && /^\s*[/—:(]/.test(text.slice(alias.length)))))
67
+ return direction;
59
68
  }
60
- return [...new Set(refs)];
69
+ return null;
70
+ }
71
+ /** Explicitly non-bibliographic or uncertain declarations must not assert citations. */
72
+ function isNonCitation(value) {
73
+ const text = normalizeCell(value);
74
+ // An explicit disavowal wins even when the description also says "cites".
75
+ if (/\b(?:topical|thematic|non[- ]citations?|methodological cousin|unverified)\b/.test(text)
76
+ || /\bnot (?:(?:a|an) )?(?:(?:verified|formal|directly) )?(?:citations?|cites?|cited|verified)\b/.test(text)
77
+ || /\bno (?:formal |verified )?citations?\b/.test(text)
78
+ || /\b(?:if|unless|provided that|assuming)\s+(?:ref-\d+|prof-[pofg]-|present\b)/.test(text)
79
+ || /\bconditional (?:on|upon)\b/.test(text)
80
+ || /^(?:conditional|related)(?:\s+only)?\s*(?:[(:;—-]|$)/.test(text))
81
+ return true;
82
+ // "Cites X in Related Work", "cites-related-version", and citations to a
83
+ // paper named "Conditional Memory" describe real citations, not qualifiers.
84
+ if (/\b(?:cites?|cited|citing)\b/.test(text))
85
+ return false;
86
+ return /\brelated\b/.test(text);
87
+ }
88
+ /** Table/section declarations, rather than incidental mentions in audit prose. */
89
+ function isNonCitationContext(value) {
90
+ // Candidate-specific audit prose does not disavow the surrounding tables.
91
+ // Keep whole-table declarations separate from notes about particular REFs.
92
+ const text = value.replace(/<!--[\s\S]*?-->/g, '').toLowerCase().replace(/[`*_]/g, '').split('\n')
93
+ .filter(line => !/\b(?:search results|external .*?candidates?|historical records)\b/.test(line))
94
+ .filter(line => !/(?:ref-\d+|prof-[pofg]-)/.test(line)
95
+ || /\b(?:rows|tables?|relationships?|connections?) (?:below|are|only)\b/.test(line))
96
+ .join('\n');
97
+ return /(?:^|\n)\s*(?:related|topical|thematic) works[^\n]*\b(?:do|does) not (?:directly )?cite\b/.test(text)
98
+ || /\b(?:no (?:formal|verified) citations?|not (?:(?:asserted|verified) )?citation (?:edges?|rows?)|relationship notes|related corpus nodes)\b/.test(text)
99
+ || /\bno citations\s*(?:[.!;]|$)/.test(text)
100
+ || /\b(?:topical|thematic|related|conditional|non-citation) (?:relationships?|connections?|only)\b/.test(text)
101
+ || /(?:^|\n)\s*(?:topical|thematic|related|conditional|non-citation)(?:\s+(?:relationships?|connections?|notes|rows|only))?\s*(?:$|\n)/.test(text);
61
102
  }
62
103
  /**
63
104
  * Test whether a string is a valid sidecar node identifier.
@@ -73,75 +114,102 @@ export function isNodeId(value) {
73
114
  * Extract node identifiers from a markdown table column.
74
115
  *
75
116
  * Scans table rows for a column matching `columnName` (case-insensitive)
76
- * and extracts node IDs (REF-* or PROF-*), skipping empty/dash values.
117
+ * and extracts node IDs (REF-* or PROF-*) only from that cell. Malformed
118
+ * tables/rows and explicit non-citation qualifiers are skipped.
77
119
  *
78
120
  * @param tableText - Markdown table text (header + separator + rows)
79
121
  * @param columnName - Column header to extract from (e.g., "Inducted REF")
80
122
  * @returns Array of node identifiers found
81
123
  */
82
124
  export function extractRefsFromTable(tableText, columnName) {
83
- const aliases = (Array.isArray(columnName) ? columnName : [columnName])
84
- .map(name => name.trim().toLowerCase());
85
- const tableBlocks = [];
86
- let currentBlock = [];
87
- for (const line of tableText.split('\n')) {
88
- if (line.trim().startsWith('|')) {
89
- currentBlock.push(line);
90
- }
91
- else if (currentBlock.length > 0) {
92
- tableBlocks.push(currentBlock);
93
- currentBlock = [];
94
- }
95
- }
96
- if (currentBlock.length > 0)
97
- tableBlocks.push(currentBlock);
98
- const parseRow = (line) => {
99
- let row = line.trim();
100
- if (row.startsWith('|'))
101
- row = row.slice(1);
102
- if (row.endsWith('|'))
103
- row = row.slice(0, -1);
104
- return row.split('|').map(cell => cell.trim());
105
- };
125
+ return extractTableRefs(tableText, columnName, false);
126
+ }
127
+ function extractTableRefs(tableText, columnName, bibliographicOnly) {
128
+ const aliases = (typeof columnName === 'string' ? [columnName] : columnName)
129
+ .map(normalizeCell);
130
+ const parseRow = (line) => line.trim().replace(/^\|/, '').replace(/\|$/, '').split(/(?<!\\)\|/)
131
+ .map(cell => cell.replace(/\\\|/g, '|').trim());
132
+ const lines = tableText.split('\n');
133
+ const headings = [];
134
+ let preamble = [];
106
135
  const refs = [];
107
- for (const lines of tableBlocks) {
108
- const headerCells = parseRow(lines[0]);
109
- const colIndex = headerCells.findIndex(header => {
110
- const normalized = header.toLowerCase().replace(/[`*_]/g, '').trim();
111
- return aliases.some(alias => normalized === alias ||
112
- normalized.startsWith(`${alias} /`) ||
113
- normalized.startsWith(`${alias} (`));
114
- });
115
- if (lines.length < 3 || colIndex === -1) {
116
- // Legacy sidecars sometimes have headerless continuation rows or a
117
- // generic table whose rows were extended with a final REF cell. The
118
- // corpus snapshot has always treated every in-section table REF as an
119
- // outgoing/incoming declaration, so retain that compatibility fallback.
120
- const dataLines = lines.length >= 3 ? lines.slice(2) : lines;
121
- for (const line of dataLines) {
122
- NODE_ID_PATTERN.lastIndex = 0;
123
- const refMatches = line.match(NODE_ID_PATTERN);
124
- if (refMatches)
125
- refs.push(...refMatches);
126
- }
136
+ for (let i = 0; i < lines.length; i++) {
137
+ const heading = lines[i].match(/^ {0,3}(#{1,6})[ \t]+(.+)/);
138
+ if (heading) {
139
+ // A parent section's declaration also governs its nested tables.
140
+ const parent = headings[headings.length - 1];
141
+ if (parent && parent.level < heading[1].length)
142
+ parent.text += `\n${preamble.join('\n')}`;
143
+ while (headings.length && headings[headings.length - 1].level >= heading[1].length)
144
+ headings.pop();
145
+ headings.push({ level: heading[1].length, text: heading[2] });
146
+ preamble = [];
147
+ continue;
148
+ }
149
+ if (!lines[i].trim().startsWith('|')) {
150
+ preamble.push(lines[i]);
127
151
  continue;
128
152
  }
129
- // Skip this table's header and separator, preserving all interior cells.
130
- for (let i = 2; i < lines.length; i++) {
131
- const cells = parseRow(lines[i]);
132
- if (colIndex >= cells.length)
153
+ const table = [];
154
+ while (i < lines.length && lines[i].trim().startsWith('|'))
155
+ table.push(lines[i++]);
156
+ i--;
157
+ const context = [...headings.map(h => h.text), ...preamble];
158
+ preamble = [];
159
+ // A trailing note can explicitly disavow the preceding table's citations.
160
+ const following = [];
161
+ for (let j = i + 1; j < lines.length && !/^\s*[#|]/.test(lines[j]); j++)
162
+ following.push(lines[j]);
163
+ if (/^\s*note\b/im.test(following.join('\n')))
164
+ context.push(...following);
165
+ if (isNonCitationContext(context.join('\n')) || table.length < 3)
166
+ continue;
167
+ const headers = parseRow(table[0]).map(normalizeCell);
168
+ if (headers.some(isNonCitation))
169
+ continue;
170
+ const separator = parseRow(table[1]);
171
+ if (separator.length !== headers.length || !separator.every(cell => /^:?-{3,}:?$/.test(cell)))
172
+ continue;
173
+ const roles = headers.map(header => HEADER_ROLES.get(header));
174
+ // Incoming/Outgoing declares the direction; the named resolution header
175
+ // identifies the target when present. Otherwise whole-cell REF IDs
176
+ // resolve rows. Additional metadata and column order do not change
177
+ // those semantics. Multiple resolution columns are ambiguous.
178
+ if (bibliographicOnly && roles.filter(role => role === 'ref').length > 1)
179
+ continue;
180
+ // For graph extraction the headers register exactly one resolution
181
+ // column when present. The generic column helper still honors its explicit alias order.
182
+ const colIndex = bibliographicOnly
183
+ ? roles.indexOf('ref')
184
+ : aliases.map(alias => headers.indexOf(alias)).find(index => index !== -1) ?? -1;
185
+ if (colIndex === -1 && !bibliographicOnly)
186
+ continue;
187
+ for (const line of table.slice(2)) {
188
+ const cells = parseRow(line);
189
+ // Extra/missing cells have no unambiguous column semantics. Never guess.
190
+ if (cells.length !== headers.length)
191
+ continue;
192
+ // A resolution explicitly labelled as context/adjacency does not map
193
+ // the printed entry to that node (corpus Formal References variants).
194
+ if (colIndex !== -1
195
+ && /\b(?:REF-\d+[a-z]?|PROF-[POFG]-[a-z0-9-]+)\s+(?:(?:family )?context|adjacent)\b/i.test(normalizeCell(cells[colIndex])))
133
196
  continue;
134
- // Historical rows may expand the named REF cell into an issue/REF pair
135
- // or append placeholder cells without extending the header. Scan from
136
- // the named column through the remainder of the row; columns before the
137
- // alias (title/authors/year) remain excluded.
138
- const value = cells.slice(colIndex).join(' | ');
139
- if (!value || value === '—' || value === '-' || value === '–')
197
+ // A condition can also qualify the printed title, as in the downstream
198
+ // "Learning is Forgetting (if REF-828 in 6-benchmark suite)" row.
199
+ if (cells.some(cell => /\b(?:if|unless|provided that|assuming)\s+[`*_[\s]*(?:REF-\d+|PROF-[POFG]-)/i.test(cell)))
140
200
  continue;
141
- NODE_ID_PATTERN.lastIndex = 0;
142
- const refMatches = value.match(NODE_ID_PATTERN);
143
- if (refMatches)
144
- refs.push(...refMatches);
201
+ const qualifiers = cells.filter((_, index) => (bibliographicOnly && colIndex === -1) || index === colIndex
202
+ || ['notes', 'evidence', 'context', 'kind', 'relationship', 'status'].includes(roles[index] ?? '')
203
+ || (!bibliographicOnly && !['#', 'title', 'work', 'authors', 'year', 'doi/url', 'doi', 'url'].includes(headers[index])));
204
+ if (qualifiers.some(isNonCitation))
205
+ continue;
206
+ // Without a named resolution column, only whole-cell REF IDs resolve.
207
+ // Named columns always take precedence over incidental IDs elsewhere.
208
+ const matches = colIndex === -1
209
+ ? cells.map(standaloneRef).filter((ref) => ref !== null)
210
+ : cells[colIndex].match(NODE_ID_PATTERN);
211
+ if (matches)
212
+ refs.push(...matches);
145
213
  }
146
214
  }
147
215
  return [...new Set(refs)];
@@ -149,6 +217,12 @@ export function extractRefsFromTable(tableText, columnName) {
149
217
  /**
150
218
  * Parse a citation sidecar markdown file into structured edges.
151
219
  *
220
+ * Tables in recognized directional or reference sections declare citations through a unique
221
+ * registered resolution column, or whole-cell REF IDs when no such column
222
+ * exists, independent of other metadata columns.
223
+ * Topical, related, conditional and explicitly non-citation declarations are
224
+ * skipped; they do not produce citation edges or new relationship types.
225
+ *
152
226
  * @param content - Full markdown content of the sidecar file
153
227
  * @returns Parse result with ref ID and edge arrays, or null if not a valid sidecar
154
228
  */
@@ -158,22 +232,29 @@ export function parseCitationSidecar(content) {
158
232
  const ref = typeof data.ref === 'string' ? data.ref : null;
159
233
  if (!ref || !NODE_ID_FULL.test(ref))
160
234
  return null;
161
- // Split body into sections by ## headings
162
- const sections = body.split(/^## /m).filter(Boolean);
235
+ // ATX level-two headings allow indentation, tabs and closing hashes.
236
+ const sectionHeading = /^ {0,3}##[ \t]+([^\r\n]+)/m;
237
+ const sections = body.split(/(?=^ {0,3}##[ \t]+)/m).filter(Boolean);
238
+ const preamble = sectionHeading.test(sections[0] ?? '') ? '' : sections[0] ?? '';
239
+ if (isNonCitationContext(preamble.replace(/^#+ .*$/gm, '')))
240
+ return { ref, cites: [], citedBy: [] };
163
241
  let cites = [];
164
242
  let citedBy = [];
165
243
  for (const section of sections) {
166
- const sectionLower = section.toLowerCase();
167
- if (sectionLower.startsWith('outgoing')) {
168
- cites.push(...extractRefsFromTable(section, CITATION_REF_COLUMNS));
169
- cites.push(...extractSectionNodeIds(section));
244
+ const heading = section.match(sectionHeading);
245
+ const direction = heading ? citationDirection(heading[1]) : null;
246
+ if (direction === 'outgoing') {
247
+ cites.push(...extractTableRefs(section, CITATION_REF_COLUMNS, true));
170
248
  }
171
- else if (sectionLower.startsWith('incoming')) {
172
- citedBy.push(...extractRefsFromTable(section, CITATION_REF_COLUMNS));
173
- citedBy.push(...extractSectionNodeIds(section));
249
+ else if (direction === 'incoming') {
250
+ citedBy.push(...extractTableRefs(section, CITATION_REF_COLUMNS, true));
174
251
  }
175
252
  }
176
- return { ref, cites: [...new Set(cites)], citedBy: [...new Set(citedBy)] };
253
+ return {
254
+ ref,
255
+ cites: [...new Set(cites)].filter(target => target !== ref),
256
+ citedBy: [...new Set(citedBy)].filter(source => source !== ref),
257
+ };
177
258
  }
178
259
  /**
179
260
  * Convert a CitationParseResult into TypedEdge arrays for the dependency graph.
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Registered column aliases for citation-sidecar edge extraction.
3
+ *
4
+ * Based on the research-papers corpus table contract
5
+ * (scripts/corpus/citation-sidecar.schema.json, schemaVersion 1). A unique
6
+ * resolution header identifies the target cell in Incoming/Outgoing tables.
7
+ * Without one, a whole-cell REF ID can resolve a row.
8
+ * Other columns supply metadata or explicit qualifiers that disavow citations;
9
+ * they do not need to follow an enumerated table shape.
10
+ */
11
+ /** Direction names used as whole headings or before /, —, :, or (. */
12
+ export const CITATION_SECTION_ALIASES = {
13
+ incoming: ['cited-by', 'cited by', 'papers that cite this work', 'sources that cite this work', 'works that cite this work'],
14
+ outgoing: [
15
+ 'cites', 'references', 'papers this work cites', 'sources this work cites', 'works this work cites',
16
+ 'formal / high-value references extracted',
17
+ 'formal / high-value references and benchmarks extracted',
18
+ 'formal references extracted from the card',
19
+ 'formal references extracted from the addendum / parent card',
20
+ 'high-value references and benchmarks',
21
+ 'foundational external citations',
22
+ ],
23
+ };
24
+ export const CITATION_HEADER_ALIASES = {
25
+ ordinal: ['#', 'bibliography #', 'label', 'row', 'original label', '# (arxiv)'],
26
+ title: [
27
+ 'title', 'citing work', 'cited work', 'citation', 'citation (extracted)', 'title / source',
28
+ 'title / work', 'title / source bibliographic entry', 'citation as printed (normalized whitespace)',
29
+ 'citation as printed or faithfully transcribed', 'cited source / concept',
30
+ 'mentioned work / cluster', 'work cited / discussed', 'source', 'artifact', 'title / referent',
31
+ 'work / cluster', 'source-reported reference', 'title / source label', 'title / target', 'entry',
32
+ 'reference', 'reference (as printed, cvpr 2026 camera-ready)', 'reference (as printed, arxiv v2)',
33
+ ],
34
+ authors: [
35
+ 'authors', 'authors / publisher', 'organization', 'party', 'authors / project', 'author(s)',
36
+ 'authors / attributed entity', 'authors (as printed)', 'author or owner', 'authors / org',
37
+ ],
38
+ year: ['year'],
39
+ locator: [
40
+ 'doi/url', 'doi / url', 'url', 'identifier', 'venue / doi / url', 'doi/url/venue', 'venue / url',
41
+ 'doi/url or venue', 'venue / id', 'venue / identifier', 'identifier / url', 'venue / doi',
42
+ ],
43
+ ref: [
44
+ 'inducted ref', 'corpus node', 'corpus ref', 'in-corpus ref', 'ref', 'citing ref', 'ref / issue',
45
+ 'in-corpus ref / issue', 'corpus id',
46
+ ],
47
+ context: ['context', 'where it appears'],
48
+ notes: ['notes', 'note', 'rationale', 'why the guarded matcher missed it'],
49
+ evidence: [
50
+ 'source evidence', 'in-text evidence', 'provenance', 'evidence', 'basis', 'verification',
51
+ 'confirmed by',
52
+ ],
53
+ 'their-row': ['their row', '[ref]', 'row in its sidecar'],
54
+ venue: ['venue'],
55
+ kind: ['kind', 'type', 'nature'],
56
+ relationship: ['relationship', 'relation', 'relationship (conceptual, not citation-grounded)'],
57
+ status: ['mapping status', 'status', 'mapping'],
58
+ };
59
+ //# sourceMappingURL=citation-table-schema.js.map
@@ -213,6 +213,15 @@ export async function main(args) {
213
213
  process.exit(0);
214
214
  }
215
215
  switch (subcommand) {
216
+ case 'refresh': {
217
+ if (subcommandArgs.includes('--help') || subcommandArgs.includes('-h')) {
218
+ printIndexUsage();
219
+ break;
220
+ }
221
+ const { runIndexRefresh } = await import('./index-refresh.js');
222
+ await runIndexRefresh(subcommandArgs);
223
+ break;
224
+ }
216
225
  case 'build':
217
226
  await handleBuild(subcommandArgs);
218
227
  break;
@@ -288,15 +297,16 @@ export async function main(args) {
288
297
  break;
289
298
  default:
290
299
  console.error(`Error: Unknown index subcommand '${subcommand}'`);
291
- console.log('Available: build, query, discover, show, export, sync, migrate-legacy, deps, stats, status, list, neighbors, set, embed, similar, dedup-report, eval-discovery, watch');
300
+ console.log('Available: build, refresh, query, discover, show, export, sync, migrate-legacy, deps, stats, status, list, neighbors, set, embed, similar, dedup-report, eval-discovery, watch');
292
301
  process.exit(1);
293
302
  }
294
303
  }
295
- function printIndexUsage() {
304
+ export function printIndexUsage() {
296
305
  console.log('Usage: aiwg index <subcommand> [options]');
297
306
  console.log('');
298
307
  console.log('Available subcommands:');
299
308
  console.log(' build Build/rebuild the artifact index');
309
+ console.log(' refresh Safely refresh graphs, caches, sessions, runtime, models, and local issues');
300
310
  console.log(' query Search artifacts by keyword, type, phase, tags');
301
311
  console.log(' discover Capability search across operational asset types (#1214)');
302
312
  console.log(' show Print the full text of a specific operational asset');
@@ -315,12 +325,22 @@ function printIndexUsage() {
315
325
  console.log(' watch Start a filesystem watcher for automatic incremental index updates');
316
326
  console.log('');
317
327
  console.log('Options:');
328
+ console.log(' build [--force] [--verbose] [--all] [--scope <dir>] [--graph <name>]');
329
+ console.log(' refresh [--full] [--workspace <path>]... [--root <dir>]...');
330
+ console.log(' [--only graphs|sessions|caches|runtime|models|issues] [--dry-run] [--json] [--lock-wait-ms <n>]');
331
+ console.log(' [--max-record-bytes <n>] [--max-source-bytes <n>]');
332
+ console.log(' Session import defaults: 67108864 bytes per record, 1073741824 bytes (1 GiB) per source; source 0 is unlimited.');
333
+ console.log(' --exclude <id-or-glob> (repeatable): skip session IDs or absolute path globs; adds to sessions.import.exclude and AIWG_SESSIONS_IMPORT_EXCLUDE (comma-separated).');
334
+ console.log(' Import limits: CLI flag > AIWG_SESSIONS_IMPORT_MAX_RECORD_BYTES / AIWG_SESSIONS_IMPORT_MAX_SOURCE_BYTES > workspace config > default.');
335
+ console.log(' sync [--backend fortemi-core] [--graph <name> | --all] [--repo <name>]');
336
+ console.log(' [--privacy private|sanitized|public] [--generated-at <iso>] [--json]');
318
337
  console.log(' --graph <name> Target a specific graph (framework, project, codebase, source, user, or user-defined)');
319
338
  console.log(' --all Build all known graphs (including user-defined)');
320
339
  console.log('');
321
340
  console.log('Examples:');
322
341
  console.log(' aiwg index build');
323
342
  console.log(' aiwg index build --all');
343
+ console.log(' aiwg index refresh --root ~/dev --json');
324
344
  console.log(' aiwg index build --graph codebase --force');
325
345
  console.log(' aiwg index discover "create intake"');
326
346
  console.log(' aiwg index discover "deploy production" --limit 5 --json');
@@ -487,6 +507,8 @@ async function handleBuild(args) {
487
507
  console.log(' --verbose Show detailed progress during indexing');
488
508
  console.log(' --all Build all known graphs (including user-defined)');
489
509
  console.log(' --scope <dir> Limit scan to a specific subdirectory');
510
+ console.log(' --include-ignored Include gitignored sources (runtime directories stay excluded)');
511
+ console.log(' Source discovery skips symlinks and .aiwg/{working,sessions,scratch,tmp,temp,cache,.index,.cache,.storage-cache}/.');
490
512
  console.log(' --graph <name> Build a specific graph only (built-in or user-defined)');
491
513
  console.log('');
492
514
  console.log('Built-in graph names: project, codebase, source, user, framework');
@@ -516,6 +538,7 @@ async function handleBuild(args) {
516
538
  const force = args.includes('--force');
517
539
  const verbose = args.includes('--verbose');
518
540
  const all = args.includes('--all');
541
+ const includeIgnored = args.includes('--include-ignored');
519
542
  const graph = parseGraphFlag(args);
520
543
  let scope;
521
544
  const scopeIdx = args.indexOf('--scope');
@@ -531,7 +554,7 @@ async function handleBuild(args) {
531
554
  // --graph X: build the JSON graph if X is one; otherwise X may be a
532
555
  // research-corpus markdown view, rendered below.
533
556
  if (graph in GRAPH_CONFIGS) {
534
- await buildIndex(cwd, { force, verbose, scope, graph, explicit: true });
557
+ await buildIndex(cwd, { force, verbose, scope, includeIgnored, graph, explicit: true });
535
558
  jsonBuilt = true;
536
559
  builtGraphs.add(graph);
537
560
  }
@@ -539,7 +562,7 @@ async function handleBuild(args) {
539
562
  else if (all) {
540
563
  // Build all known graphs — user asked for everything, but don't hard-error on missing dirs
541
564
  for (const [name] of orderedGraphEntries(Object.entries(GRAPH_CONFIGS))) {
542
- await buildIndex(cwd, { force, verbose, graph: name, explicit: false });
565
+ await buildIndex(cwd, { force, verbose, includeIgnored, graph: name, explicit: false });
543
566
  builtGraphs.add(name);
544
567
  }
545
568
  jsonBuilt = true;
@@ -548,7 +571,7 @@ async function handleBuild(args) {
548
571
  // Default: build graphs with defaultBuild=true; skip gracefully if their dirs don't exist
549
572
  for (const [name, config] of orderedGraphEntries(Object.entries(GRAPH_CONFIGS))) {
550
573
  if (config.defaultBuild) {
551
- await buildIndex(cwd, { force, verbose, scope: name === Object.keys(GRAPH_CONFIGS)[0] ? scope : undefined, graph: name, explicit: false });
574
+ await buildIndex(cwd, { force, verbose, includeIgnored, scope: name === Object.keys(GRAPH_CONFIGS)[0] ? scope : undefined, graph: name, explicit: false });
552
575
  builtGraphs.add(name);
553
576
  }
554
577
  }
@@ -589,18 +612,18 @@ async function syncFortemiCoreCachesAfterBuild(cwd, graphs, verbose) {
589
612
  const { syncFortemiCoreIndex } = await import('./fortemi-core-sync.js');
590
613
  const { loadGraphIndexFile } = await import('./index-reader.js');
591
614
  for (const graph of graphs) {
592
- // Some default-build graphs skip cleanly when their scan roots are absent.
593
- // Only materialize a cache when this build left an actual source index.
594
- if (!loadGraphIndexFile(cwd, 'metadata.json', graph))
595
- continue;
596
615
  try {
616
+ // Some auto-selected graphs skip cleanly when their scan roots are absent.
617
+ if (!loadGraphIndexFile(cwd, 'metadata.json', graph))
618
+ continue;
597
619
  const manifest = syncFortemiCoreIndex(cwd, { graph });
598
620
  if (verbose) {
599
621
  console.log(`Fortemi Core ${graph} sync: ${manifest.status}, ${manifest.item_count} item(s) → ${manifest.export_path}`);
600
622
  }
601
623
  }
602
624
  catch (err) {
603
- console.error(`Warning: Fortemi Core ${graph} sync failed: ${err instanceof Error ? err.message : String(err)}`);
625
+ process.exitCode = 1;
626
+ console.error(`Error: Fortemi Core ${graph} sync failed: ${err instanceof Error ? err.message : String(err)}`);
604
627
  console.error(`Run \`aiwg index sync --graph ${graph}\` before using Fortemi-backed commands for '${graph}' artifacts.`);
605
628
  }
606
629
  }
@@ -1099,19 +1122,30 @@ async function handleSync(args) {
1099
1122
  if (all) {
1100
1123
  const { loadGraphIndexFile } = await import('./index-reader.js');
1101
1124
  const manifests = [];
1125
+ const failures = [];
1102
1126
  for (const [name] of orderedGraphEntries(Object.entries(GRAPH_CONFIGS))) {
1103
- if (!loadGraphIndexFile(cwd, 'metadata.json', name))
1104
- continue;
1105
- manifests.push(syncFortemiCoreIndex(cwd, { ...options, graph: name }));
1127
+ try {
1128
+ if (!loadGraphIndexFile(cwd, 'metadata.json', name))
1129
+ continue;
1130
+ manifests.push(syncFortemiCoreIndex(cwd, { ...options, graph: name }));
1131
+ }
1132
+ catch (err) {
1133
+ failures.push({ graph: name, status: 'failed', error: err instanceof Error ? err.message : String(err) });
1134
+ }
1106
1135
  }
1136
+ if (failures.length)
1137
+ process.exitCode = 1;
1107
1138
  if (json) {
1108
- console.log(JSON.stringify({ manifests }, null, 2));
1139
+ console.log(JSON.stringify({ manifests, failures }, null, 2));
1109
1140
  return;
1110
1141
  }
1111
- console.log(`Fortemi Core sync: ${manifests.length} graph(s)`);
1142
+ console.log(`Fortemi Core sync: ${manifests.length} graph(s) succeeded, ${failures.length} failed`);
1112
1143
  for (const manifest of manifests) {
1113
1144
  console.log(` ${manifest.graph}: ${manifest.status}, ${manifest.item_count} item(s) → ${manifest.export_path}`);
1114
1145
  }
1146
+ for (const failure of failures) {
1147
+ console.error(` ${failure.graph}: failed — ${failure.error}`);
1148
+ }
1115
1149
  return;
1116
1150
  }
1117
1151
  const manifest = syncFortemiCoreIndex(cwd, {
@@ -1480,7 +1514,7 @@ async function handleDiscover(args) {
1480
1514
  * artifact by type and name.
1481
1515
  *
1482
1516
  * Shape (#1218):
1483
- * aiwg show <type> <name> [--json] [--first] [--graph <name>] [--backend local|fortemi-core]
1517
+ * aiwg show <type> <name> [--json] [--first] [--bound-rule-bodies] [--graph <name>] [--backend local|fortemi-core]
1484
1518
  *
1485
1519
  * Type is positional (not a flag) so the verb reads as
1486
1520
  * "show <kind> <name>". `<type>` is one of the operational show types.
@@ -1504,8 +1538,8 @@ async function handleShow(args) {
1504
1538
  }
1505
1539
  const HELP_TEXT = [
1506
1540
  '',
1507
- 'Usage: aiwg show <type> <name> [--json] [--first] [--graph <name>] [--backend local|fortemi-core] [--resource-source local|web|auto] [--aiwg-version <version|range|digest|channel>] [--offline]',
1508
- ' aiwg show metadata <id-or-name-or-path> [--json] [--first] [--graph <name>] [--backend local|fortemi-core] [--resource-source local|web|auto] [--aiwg-version <version|range|digest|channel>] [--offline]',
1541
+ 'Usage: aiwg show <type> <name> [--json] [--first] [--bound-rule-bodies] [--graph <name>] [--backend local|fortemi-core] [--resource-source local|web|auto] [--aiwg-version <version|range|digest|channel>] [--offline]',
1542
+ ' aiwg show metadata <id-or-name-or-path> [--json] [--first] [--bound-rule-bodies] [--graph <name>] [--backend local|fortemi-core] [--resource-source local|web|auto] [--aiwg-version <version|range|digest|channel>] [--offline]',
1509
1543
  ' aiwg index show <type> <name> ...',
1510
1544
  '',
1511
1545
  `Types: ${OPERATIONAL_SHOW_TYPES.join(' | ')}`,
@@ -1521,6 +1555,10 @@ async function handleShow(args) {
1521
1555
  ' aiwg show command discover',
1522
1556
  ' aiwg show skill intake-wizard --resource-source web --aiwg-version stable',
1523
1557
  '',
1558
+ 'Bound rules: summaries and show pointers are appended for bound skills, agents, and flows.',
1559
+ 'Fetch and follow every required_rule_checks entry before starting governed work; summaries do not replace full rules.',
1560
+ 'Use --bound-rule-bodies to include their full text (JSON: bound_rules[].content).',
1561
+ '',
1524
1562
  'Tip: use `aiwg discover "<phrase>" --json` first to find the stable id.',
1525
1563
  ].join('\n');
1526
1564
  if (positional.length === 0) {
@@ -1584,6 +1622,7 @@ async function handleShow(args) {
1584
1622
  : webReleaseOptionsFromEnvironment();
1585
1623
  const params = {
1586
1624
  name,
1625
+ boundRuleBodies: flags.includes('--bound-rule-bodies'),
1587
1626
  typeFilter: type ? [type] : undefined,
1588
1627
  json,
1589
1628
  first,
@@ -238,7 +238,7 @@ export function computeSnapshot(root, options = {}) {
238
238
  if (r.year)
239
239
  years.push(r.year);
240
240
  inc(sourceTypes, r.sourceType || 'other');
241
- const grade = r.radar?.gradeCurrent?.trim().toUpperCase();
241
+ const grade = r.grade?.trim().toUpperCase();
242
242
  if (!grade)
243
243
  grades.Missing++;
244
244
  else if (CONTROLLED_GRADES.includes(grade))