@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18

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 (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -1
  3. package/bin/aiwg.mjs +349 -0
  4. package/dist/src/a2a/agent-card.js +145 -0
  5. package/dist/src/a2a/client.js +411 -0
  6. package/dist/src/a2a/hitl-cli.js +171 -0
  7. package/dist/src/a2a/hitl-driver.js +370 -0
  8. package/dist/src/a2a/hitl.js +181 -0
  9. package/dist/src/a2a/http.js +193 -0
  10. package/dist/src/a2a/jcs.js +128 -0
  11. package/dist/src/a2a/jws.js +187 -0
  12. package/dist/src/a2a/types.js +24 -0
  13. package/dist/src/a2a/webhook.js +240 -0
  14. package/dist/src/activity-log/cli.js +348 -0
  15. package/dist/src/activity-log/parser.js +81 -0
  16. package/dist/src/activity-log/types.js +50 -0
  17. package/dist/src/agents/agent-deployer.js +367 -0
  18. package/dist/src/agents/agent-packager.js +271 -0
  19. package/dist/src/agents/agent-validator.js +271 -0
  20. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  21. package/dist/src/agents/grounding/types.js +12 -0
  22. package/dist/src/agents/index.js +10 -0
  23. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  24. package/dist/src/agents/types.js +7 -0
  25. package/dist/src/api/index.d.ts +10 -0
  26. package/dist/src/api/index.js +10 -0
  27. package/dist/src/artifacts/address-parser.js +73 -0
  28. package/dist/src/artifacts/audit/cli.js +183 -0
  29. package/dist/src/artifacts/audit/drift.js +122 -0
  30. package/dist/src/artifacts/audit/types.js +12 -0
  31. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  32. package/dist/src/artifacts/backends/json-backend.js +129 -0
  33. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  34. package/dist/src/artifacts/browser-export.js +622 -0
  35. package/dist/src/artifacts/capability-resolver.js +94 -0
  36. package/dist/src/artifacts/checksum-manifest.js +91 -0
  37. package/dist/src/artifacts/citation-parser.js +162 -0
  38. package/dist/src/artifacts/cli.js +1486 -0
  39. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  40. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  41. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  42. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  43. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  44. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  45. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  46. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  47. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  48. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  49. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  51. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  52. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  53. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  54. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  55. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  56. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  57. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  58. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  60. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  61. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  62. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  63. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  64. package/dist/src/artifacts/corpus-views/build.js +126 -0
  65. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  66. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  67. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  68. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  69. package/dist/src/artifacts/dep-graph.js +173 -0
  70. package/dist/src/artifacts/discover-facets.js +375 -0
  71. package/dist/src/artifacts/embedding-index.js +354 -0
  72. package/dist/src/artifacts/enrichment/cli.js +240 -0
  73. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  74. package/dist/src/artifacts/enrichment/store.js +90 -0
  75. package/dist/src/artifacts/enrichment/types.js +12 -0
  76. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  77. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  78. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  79. package/dist/src/artifacts/fulltext.js +108 -0
  80. package/dist/src/artifacts/graph-backend.js +51 -0
  81. package/dist/src/artifacts/graph-query.js +247 -0
  82. package/dist/src/artifacts/hybrid-query.js +225 -0
  83. package/dist/src/artifacts/index-builder.js +1089 -0
  84. package/dist/src/artifacts/index-reader.js +112 -0
  85. package/dist/src/artifacts/index-status.js +193 -0
  86. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  87. package/dist/src/artifacts/move.js +154 -0
  88. package/dist/src/artifacts/operational-state.js +239 -0
  89. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  90. package/dist/src/artifacts/query-engine.js +1955 -0
  91. package/dist/src/artifacts/source-graph.js +529 -0
  92. package/dist/src/artifacts/stats.js +169 -0
  93. package/dist/src/artifacts/types.js +606 -0
  94. package/dist/src/artifacts/views/cli.js +293 -0
  95. package/dist/src/artifacts/views/definition.js +170 -0
  96. package/dist/src/artifacts/views/store.js +149 -0
  97. package/dist/src/artifacts/views/types.js +8 -0
  98. package/dist/src/artifacts/watcher.js +255 -0
  99. package/dist/src/catalog/builtin-models.json +636 -0
  100. package/dist/src/catalog/cli.js +228 -0
  101. package/dist/src/catalog/cli.mjs +289 -0
  102. package/dist/src/catalog/index.js +15 -0
  103. package/dist/src/catalog/loader.js +217 -0
  104. package/dist/src/catalog/loader.mjs +251 -0
  105. package/dist/src/catalog/sources.json +41 -0
  106. package/dist/src/catalog/types.js +8 -0
  107. package/dist/src/channel/manager.mjs +504 -0
  108. package/dist/src/cli/agent-spawn.js +178 -0
  109. package/dist/src/cli/cli-extension-loader.js +245 -0
  110. package/dist/src/cli/command-log.js +275 -0
  111. package/dist/src/cli/config-loader.js +232 -0
  112. package/dist/src/cli/env.js +82 -0
  113. package/dist/src/cli/errors.js +150 -0
  114. package/dist/src/cli/find-package-root.js +40 -0
  115. package/dist/src/cli/git-hooks.js +250 -0
  116. package/dist/src/cli/handlers/agentcard.js +206 -0
  117. package/dist/src/cli/handlers/artifacts.js +76 -0
  118. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  119. package/dist/src/cli/handlers/cockpit.js +137 -0
  120. package/dist/src/cli/handlers/command-log.js +37 -0
  121. package/dist/src/cli/handlers/daemon.js +59 -0
  122. package/dist/src/cli/handlers/diagnose.js +300 -0
  123. package/dist/src/cli/handlers/execution-mode.js +105 -0
  124. package/dist/src/cli/handlers/feedback.js +341 -0
  125. package/dist/src/cli/handlers/help.js +147 -0
  126. package/dist/src/cli/handlers/index.js +302 -0
  127. package/dist/src/cli/handlers/init.js +179 -0
  128. package/dist/src/cli/handlers/install.js +129 -0
  129. package/dist/src/cli/handlers/issues.js +46 -0
  130. package/dist/src/cli/handlers/lint.js +42 -0
  131. package/dist/src/cli/handlers/local-executor.js +315 -0
  132. package/dist/src/cli/handlers/marketplace.js +168 -0
  133. package/dist/src/cli/handlers/mc.js +1010 -0
  134. package/dist/src/cli/handlers/models.js +352 -0
  135. package/dist/src/cli/handlers/packages.js +155 -0
  136. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  137. package/dist/src/cli/handlers/ralph.js +575 -0
  138. package/dist/src/cli/handlers/refresh.js +432 -0
  139. package/dist/src/cli/handlers/regenerate.js +336 -0
  140. package/dist/src/cli/handlers/repo-access.js +109 -0
  141. package/dist/src/cli/handlers/run.js +165 -0
  142. package/dist/src/cli/handlers/runtime-info.js +301 -0
  143. package/dist/src/cli/handlers/sandbox.js +197 -0
  144. package/dist/src/cli/handlers/scaffolding.js +149 -0
  145. package/dist/src/cli/handlers/script-runner.js +121 -0
  146. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  147. package/dist/src/cli/handlers/serve.js +1835 -0
  148. package/dist/src/cli/handlers/session.js +348 -0
  149. package/dist/src/cli/handlers/setup.js +440 -0
  150. package/dist/src/cli/handlers/skill-lint.js +367 -0
  151. package/dist/src/cli/handlers/skill-usage.js +74 -0
  152. package/dist/src/cli/handlers/steward.js +567 -0
  153. package/dist/src/cli/handlers/subcommands.js +1702 -0
  154. package/dist/src/cli/handlers/team.js +337 -0
  155. package/dist/src/cli/handlers/types.js +11 -0
  156. package/dist/src/cli/handlers/use.js +2772 -0
  157. package/dist/src/cli/handlers/utilities.js +703 -0
  158. package/dist/src/cli/handlers/version.js +134 -0
  159. package/dist/src/cli/handlers/workspace-context.js +93 -0
  160. package/dist/src/cli/handlers/workspace.js +126 -0
  161. package/dist/src/cli/help-generator.js +178 -0
  162. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  163. package/dist/src/cli/hooks/executor.js +96 -0
  164. package/dist/src/cli/hooks/index.js +15 -0
  165. package/dist/src/cli/hooks/registry.js +143 -0
  166. package/dist/src/cli/hooks/types.js +13 -0
  167. package/dist/src/cli/log.js +492 -0
  168. package/dist/src/cli/project-isolation/detect.js +70 -0
  169. package/dist/src/cli/project-isolation/index.js +7 -0
  170. package/dist/src/cli/project-isolation/signals.js +17 -0
  171. package/dist/src/cli/project-isolation/warning.js +102 -0
  172. package/dist/src/cli/prompt-utils.js +155 -0
  173. package/dist/src/cli/provider-deployment-plan.js +126 -0
  174. package/dist/src/cli/provider-resolution.js +119 -0
  175. package/dist/src/cli/router.js +305 -0
  176. package/dist/src/cli/scope-resolver.js +392 -0
  177. package/dist/src/cli/skill-usage.js +616 -0
  178. package/dist/src/cli/ui.js +224 -0
  179. package/dist/src/cli/watch-service.js +203 -0
  180. package/dist/src/cli/workflow-orchestrator.js +478 -0
  181. package/dist/src/cli/workspace-signals.js +321 -0
  182. package/dist/src/community/footer.js +14 -0
  183. package/dist/src/community/links.js +123 -0
  184. package/dist/src/community/milestones.js +46 -0
  185. package/dist/src/community/nudge-policy.js +93 -0
  186. package/dist/src/config/aiwg-config.js +883 -0
  187. package/dist/src/config/cli.js +703 -0
  188. package/dist/src/config/gitignore.js +156 -0
  189. package/dist/src/config/project-artifacts.js +76 -0
  190. package/dist/src/config/user-config.js +428 -0
  191. package/dist/src/config/user-registry.js +127 -0
  192. package/dist/src/config/workspace.js +276 -0
  193. package/dist/src/contributors/detect.js +39 -0
  194. package/dist/src/contributors/discover.js +172 -0
  195. package/dist/src/contributors/heuristic.js +186 -0
  196. package/dist/src/contributors/index.js +11 -0
  197. package/dist/src/contributors/types.js +13 -0
  198. package/dist/src/contributors/validation.js +116 -0
  199. package/dist/src/data/community.schema.json +43 -0
  200. package/dist/src/data/community.yaml +16 -0
  201. package/dist/src/extensions/capability-index.js +270 -0
  202. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  203. package/dist/src/extensions/commands/definitions.js +3485 -0
  204. package/dist/src/extensions/deployment-registration.js +463 -0
  205. package/dist/src/extensions/index.js +22 -0
  206. package/dist/src/extensions/loader.js +132 -0
  207. package/dist/src/extensions/managed-marker.js +100 -0
  208. package/dist/src/extensions/manifest.js +196 -0
  209. package/dist/src/extensions/project-local-activity.js +114 -0
  210. package/dist/src/extensions/project-local-discovery.js +261 -0
  211. package/dist/src/extensions/project-local-doctor.js +281 -0
  212. package/dist/src/extensions/project-local-gitignore.js +176 -0
  213. package/dist/src/extensions/project-local-paths.js +121 -0
  214. package/dist/src/extensions/project-local-promote.js +218 -0
  215. package/dist/src/extensions/project-local-remove.js +373 -0
  216. package/dist/src/extensions/project-local-scaffold.js +252 -0
  217. package/dist/src/extensions/project-quickref.js +291 -0
  218. package/dist/src/extensions/registry.js +368 -0
  219. package/dist/src/extensions/shadow-resolver.js +271 -0
  220. package/dist/src/extensions/types.js +86 -0
  221. package/dist/src/extensions/upstream-registry.js +195 -0
  222. package/dist/src/extensions/validation.js +631 -0
  223. package/dist/src/features/catalog.js +88 -0
  224. package/dist/src/features/cli.js +197 -0
  225. package/dist/src/features/installer.js +57 -0
  226. package/dist/src/features/paths.js +14 -0
  227. package/dist/src/features/runtime.js +21 -0
  228. package/dist/src/features/status.js +134 -0
  229. package/dist/src/hooks/laziness-detection.js +532 -0
  230. package/dist/src/intake/git-history-analyzer.js +486 -0
  231. package/dist/src/intake/index.js +9 -0
  232. package/dist/src/issues/cli.js +327 -0
  233. package/dist/src/issues/index.js +5 -0
  234. package/dist/src/issues/live.js +154 -0
  235. package/dist/src/issues/local.js +666 -0
  236. package/dist/src/issues/sync.js +143 -0
  237. package/dist/src/issues/types.js +2 -0
  238. package/dist/src/issues/workflows.js +164 -0
  239. package/dist/src/kb/cli.js +173 -0
  240. package/dist/src/lint/cli.js +171 -0
  241. package/dist/src/lint/loader.js +225 -0
  242. package/dist/src/lint/reporters.js +141 -0
  243. package/dist/src/lint/runner.js +364 -0
  244. package/dist/src/lint/types.js +10 -0
  245. package/dist/src/marketplace/cache.js +110 -0
  246. package/dist/src/marketplace/identifier.js +63 -0
  247. package/dist/src/marketplace/registry.js +36 -0
  248. package/dist/src/marketplace/sources/clawhub.js +53 -0
  249. package/dist/src/marketplace/sources/git.js +45 -0
  250. package/dist/src/marketplace/types.js +9 -0
  251. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  252. package/dist/src/mcp/cli.mjs +1197 -0
  253. package/dist/src/mcp/elicitation.mjs +149 -0
  254. package/dist/src/mcp/helpers.mjs +287 -0
  255. package/dist/src/mcp/index.mjs +11 -0
  256. package/dist/src/mcp/profiles.js +263 -0
  257. package/dist/src/mcp/profiles.mjs +360 -0
  258. package/dist/src/mcp/registry.js +376 -0
  259. package/dist/src/mcp/registry.mjs +387 -0
  260. package/dist/src/mcp/server.mjs +633 -0
  261. package/dist/src/mcp/test-simple.mjs +271 -0
  262. package/dist/src/mcp/tools/command-run.mjs +101 -0
  263. package/dist/src/mcp/tools/discovery.mjs +291 -0
  264. package/dist/src/mcp/tools/interaction.mjs +87 -0
  265. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  266. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  267. package/dist/src/memory/cli.js +166 -0
  268. package/dist/src/memory/project-registry.js +282 -0
  269. package/dist/src/metrics/artifact-metrics.js +184 -0
  270. package/dist/src/metrics/context-budget.js +174 -0
  271. package/dist/src/metrics/token-counter.js +133 -0
  272. package/dist/src/models/config-loader.js +228 -0
  273. package/dist/src/models/index.js +22 -0
  274. package/dist/src/models/model-capabilities.v1.json +120 -0
  275. package/dist/src/models/model-catalog.v1.json +96 -0
  276. package/dist/src/models/model-discovery.js +521 -0
  277. package/dist/src/models/provider-models.js +73 -0
  278. package/dist/src/models/provider-policy.js +273 -0
  279. package/dist/src/models/resolver.js +245 -0
  280. package/dist/src/models/router.js +70 -0
  281. package/dist/src/models/types.js +8 -0
  282. package/dist/src/models/wrapper-deployment.js +178 -0
  283. package/dist/src/models/wrapper-route.js +54 -0
  284. package/dist/src/ops/cli.js +268 -0
  285. package/dist/src/ops/registry.js +623 -0
  286. package/dist/src/packages/adapters/clawhub.js +113 -0
  287. package/dist/src/packages/adapters/git.js +153 -0
  288. package/dist/src/packages/adapters/gitea.js +93 -0
  289. package/dist/src/packages/adapters/github.js +69 -0
  290. package/dist/src/packages/adapters/local-cache.js +89 -0
  291. package/dist/src/packages/package-registry.js +143 -0
  292. package/dist/src/packages/registry.js +238 -0
  293. package/dist/src/packages/types.js +11 -0
  294. package/dist/src/plugin/cross-framework-ops.js +475 -0
  295. package/dist/src/plugin/framework-config-loader.js +235 -0
  296. package/dist/src/plugin/framework-detector.js +186 -0
  297. package/dist/src/plugin/framework-isolator.js +341 -0
  298. package/dist/src/plugin/framework-migration.js +371 -0
  299. package/dist/src/plugin/metadata-validator.js +906 -0
  300. package/dist/src/plugin/plugin-installer.js +436 -0
  301. package/dist/src/plugin/plugin-status.js +369 -0
  302. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  303. package/dist/src/plugin/registry-validator.js +344 -0
  304. package/dist/src/plugin/skill-command-translator.js +415 -0
  305. package/dist/src/plugin/workspace-creator.js +189 -0
  306. package/dist/src/plugin/workspace-migrator.js +821 -0
  307. package/dist/src/policy/authorization.js +390 -0
  308. package/dist/src/policy/repo-access.js +215 -0
  309. package/dist/src/provenance/cli.js +16 -0
  310. package/dist/src/providers/capability-matrix.js +300 -0
  311. package/dist/src/providers/capability-matrix.yaml +514 -0
  312. package/dist/src/providers/provider-definitions.js +977 -0
  313. package/dist/src/providers/provider-definitions.mjs +159 -0
  314. package/dist/src/providers/provider-inventory.js +169 -0
  315. package/dist/src/quality/feedback-ab.js +174 -0
  316. package/dist/src/quality/feedback-collector.js +176 -0
  317. package/dist/src/quality/feedback-tracker.js +123 -0
  318. package/dist/src/quality/patterns/adr.json +24 -0
  319. package/dist/src/quality/patterns/sad.json +24 -0
  320. package/dist/src/quality/patterns/test-plan.json +24 -0
  321. package/dist/src/quality/patterns/use-case.json +24 -0
  322. package/dist/src/quality/scoring.js +157 -0
  323. package/dist/src/reflections/cli.js +15 -0
  324. package/dist/src/release/plan.js +139 -0
  325. package/dist/src/research/cache/manager.js +227 -0
  326. package/dist/src/research/clients/arxiv.js +156 -0
  327. package/dist/src/research/clients/base.js +197 -0
  328. package/dist/src/research/clients/crossref.js +112 -0
  329. package/dist/src/research/clients/semantic-scholar.js +126 -0
  330. package/dist/src/research/clients/unpaywall.js +87 -0
  331. package/dist/src/research/index.js +14 -0
  332. package/dist/src/research/query-cli.js +336 -0
  333. package/dist/src/research/services/acquisition.js +313 -0
  334. package/dist/src/research/services/archival.js +225 -0
  335. package/dist/src/research/services/citation.js +279 -0
  336. package/dist/src/research/services/discovery.js +243 -0
  337. package/dist/src/research/services/documentation.js +269 -0
  338. package/dist/src/research/services/index.js +14 -0
  339. package/dist/src/research/services/provenance.js +279 -0
  340. package/dist/src/research/services/quality.js +370 -0
  341. package/dist/src/research/services/types.js +7 -0
  342. package/dist/src/research/storage-cli.js +20 -0
  343. package/dist/src/research/types.js +47 -0
  344. package/dist/src/resources/index.d.ts +2 -0
  345. package/dist/src/resources/index.js +2 -0
  346. package/dist/src/resources/web-release.d.ts +89 -0
  347. package/dist/src/resources/web-release.js +886 -0
  348. package/dist/src/rlm/cache/cli.js +162 -0
  349. package/dist/src/rlm/cache/hash.js +35 -0
  350. package/dist/src/rlm/cache/store.js +170 -0
  351. package/dist/src/rlm/cache/types.js +8 -0
  352. package/dist/src/rlm/cli.js +650 -0
  353. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  354. package/dist/src/serve/agent-router.js +205 -0
  355. package/dist/src/serve/dispatch-router.js +171 -0
  356. package/dist/src/serve/executor-registry.js +715 -0
  357. package/dist/src/serve/mission-conductor.js +177 -0
  358. package/dist/src/serve/orchestrator-adapter.js +113 -0
  359. package/dist/src/serve/orchestrator-override.js +94 -0
  360. package/dist/src/serve/orchestrator-pty.js +133 -0
  361. package/dist/src/serve/pty-bridge.js +799 -0
  362. package/dist/src/serve/sandbox-registry.js +832 -0
  363. package/dist/src/serve/screen-reader.js +228 -0
  364. package/dist/src/serve/stack-adapters.js +68 -0
  365. package/dist/src/serve/telemetry.js +143 -0
  366. package/dist/src/skills/adapters/clawhub.js +250 -0
  367. package/dist/src/skills/adapters/local.js +335 -0
  368. package/dist/src/skills/adapters/openclaw.js +316 -0
  369. package/dist/src/skills/cli.js +334 -0
  370. package/dist/src/skills/registry.js +117 -0
  371. package/dist/src/skills/run.js +259 -0
  372. package/dist/src/skills/runtime.js +94 -0
  373. package/dist/src/skills/types.js +10 -0
  374. package/dist/src/smiths/agentsmith/demo.js +116 -0
  375. package/dist/src/smiths/agentsmith/examples.js +300 -0
  376. package/dist/src/smiths/agentsmith/generator.js +503 -0
  377. package/dist/src/smiths/agentsmith/index.js +11 -0
  378. package/dist/src/smiths/agentsmith/types.js +8 -0
  379. package/dist/src/smiths/commandsmith/example.js +220 -0
  380. package/dist/src/smiths/commandsmith/generator.js +288 -0
  381. package/dist/src/smiths/commandsmith/index.js +41 -0
  382. package/dist/src/smiths/commandsmith/templates.js +296 -0
  383. package/dist/src/smiths/commandsmith/types.js +7 -0
  384. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  385. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  386. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  387. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  388. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  389. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  390. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  391. package/dist/src/smiths/context-pipeline/index.js +30 -0
  392. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  393. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  394. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  395. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  396. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  397. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  398. package/dist/src/smiths/context-pipeline/types.js +23 -0
  399. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  400. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  401. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  402. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  403. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  404. package/dist/src/smiths/hook-bridge/index.js +79 -0
  405. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  406. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  407. package/dist/src/smiths/hook-bridge/types.js +31 -0
  408. package/dist/src/smiths/index.js +39 -0
  409. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  410. package/dist/src/smiths/mcpsmith/example.js +119 -0
  411. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  412. package/dist/src/smiths/mcpsmith/index.js +17 -0
  413. package/dist/src/smiths/mcpsmith/types.js +10 -0
  414. package/dist/src/smiths/platform-paths.js +101 -0
  415. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  416. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  417. package/dist/src/smiths/skillsmith/demo.js +83 -0
  418. package/dist/src/smiths/skillsmith/examples.js +161 -0
  419. package/dist/src/smiths/skillsmith/generator.js +316 -0
  420. package/dist/src/smiths/skillsmith/index.js +12 -0
  421. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  422. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  423. package/dist/src/smiths/skillsmith/types.js +9 -0
  424. package/dist/src/smiths/toolsmith/index.js +10 -0
  425. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  426. package/dist/src/smiths/toolsmith/types.js +8 -0
  427. package/dist/src/storage/backends/fortemi.js +227 -0
  428. package/dist/src/storage/backends/fs.js +134 -0
  429. package/dist/src/storage/backends/logseq.js +309 -0
  430. package/dist/src/storage/backends/obsidian.js +233 -0
  431. package/dist/src/storage/cli.js +468 -0
  432. package/dist/src/storage/config.js +272 -0
  433. package/dist/src/storage/index.js +108 -0
  434. package/dist/src/storage/subsystem-cli.js +201 -0
  435. package/dist/src/storage/types.js +33 -0
  436. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  437. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  438. package/dist/src/testing/corpus/index.js +10 -0
  439. package/dist/src/testing/fixtures/index.js +9 -0
  440. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  441. package/dist/src/testing/generators/index.js +11 -0
  442. package/dist/src/testing/generators/test-case-generator.js +393 -0
  443. package/dist/src/testing/generators/test-code-generator.js +384 -0
  444. package/dist/src/testing/generators/use-case-parser.js +325 -0
  445. package/dist/src/testing/index.js +11 -0
  446. package/dist/src/tracker/capability-protocol.js +118 -0
  447. package/dist/src/update/checker.mjs +396 -0
  448. package/dist/src/update/notifier.mjs +235 -0
  449. package/dist/src/writing/content-diversifier.js +804 -0
  450. package/dist/src/writing/example-generator.js +959 -0
  451. package/dist/src/writing/example-templates.js +99 -0
  452. package/dist/src/writing/pattern-library.js +486 -0
  453. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  454. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  455. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  456. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  457. package/dist/src/writing/patterns/transition-words.json +1285 -0
  458. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  459. package/dist/src/writing/prompt-optimizer.js +660 -0
  460. package/dist/src/writing/prompt-templates.js +583 -0
  461. package/dist/src/writing/scoring-config-loader.js +168 -0
  462. package/dist/src/writing/validation-engine.js +595 -0
  463. package/dist/src/writing/validation-rules.js +380 -0
  464. package/dist/src/writing/voice-analyzer.js +439 -0
  465. package/dist/src/writing/voice-calibration.js +661 -0
  466. package/dist/src/writing/voice-profiles.json +588 -0
  467. package/package.json +65 -9
@@ -0,0 +1,164 @@
1
+ /**
2
+ * Canonical, extensible source-type registry + normalizer (#1509).
3
+ *
4
+ * A research corpus accumulates three drifting type vocabularies — frontmatter
5
+ * `type:` (mixes source type with doc role), `source_type:` (hyphen/underscore
6
+ * drift), and a body "Source Type" field. This module gives one canonical
7
+ * registry and a `normalizeSourceType` that folds all three (plus a venue
8
+ * fallback) into a single source-type dimension.
9
+ *
10
+ * The authoritative runtime default is `DEFAULT_SOURCE_TYPES` below; the
11
+ * human-readable + overridable form ships at
12
+ * `agentic/code/frameworks/research-complete/config/source-types.yaml`
13
+ * (a corpus may override at `documentation/source-types.yaml`). A drift test
14
+ * keeps the YAML and this constant in sync.
15
+ *
16
+ * Consumed by: the `by-source-type` index view, per-type induction audit
17
+ * (#1504), acquisition dispatch (#1507).
18
+ *
19
+ * @source historical: section9 REFERENCE-TEMPLATE*.md per-type rules
20
+ * @tests @test/unit/artifacts/source-types.test.ts
21
+ */
22
+ import * as fs from 'fs';
23
+ import * as path from 'path';
24
+ import { load as loadYaml } from 'js-yaml';
25
+ const OVERRIDE_FILE = ['documentation', 'source-types.yaml'];
26
+ /** Authoritative runtime default registry. Mirrors the framework source-types.yaml. */
27
+ export const DEFAULT_SOURCE_TYPES = {
28
+ version: 1,
29
+ // VENUE_PATTERNS label → canonical type. Academic conferences/journals → paper;
30
+ // arXiv → preprint; lab/vendor research posts → blog; GitHub/Docs → repo;
31
+ // RFC → standard; Wikipedia → encyclopedia. Used only when frontmatter
32
+ // type/source_type is absent or unmatched.
33
+ venueFallback: {
34
+ NeurIPS: 'paper', ICML: 'paper', ICLR: 'paper', ACL: 'paper', EMNLP: 'paper',
35
+ NAACL: 'paper', CVPR: 'paper', ICCV: 'paper', ECCV: 'paper', AAAI: 'paper',
36
+ IJCAI: 'paper', KDD: 'paper', SIGIR: 'paper', WWW: 'paper', RSS: 'paper',
37
+ CoRL: 'paper', ICRA: 'paper', IROS: 'paper', OSDI: 'paper', SOSP: 'paper',
38
+ NSDI: 'paper', 'USENIX ATC': 'paper', 'USENIX Security': 'paper',
39
+ 'IEEE S&P / Oakland': 'paper', CCS: 'paper', CHI: 'paper', UIST: 'paper',
40
+ VLDB: 'paper', SIGMOD: 'paper', FAccT: 'paper', TMLR: 'paper', JMLR: 'paper',
41
+ Nature: 'paper', Science: 'paper', PNAS: 'paper',
42
+ arXiv: 'preprint',
43
+ 'RFC (IETF)': 'standard',
44
+ 'Anthropic Research': 'blog', 'OpenAI Research': 'blog',
45
+ 'DeepMind / Google Research': 'blog', 'Meta AI / FAIR': 'blog',
46
+ 'Microsoft Research': 'blog',
47
+ 'GitHub / Documentation': 'repo',
48
+ 'Blog / Web Article': 'blog',
49
+ Wikipedia: 'encyclopedia',
50
+ },
51
+ metaRoles: ['redirect', 'stub', 'gap-note', 'merged', 'index'],
52
+ types: {
53
+ paper: { description: 'Peer-reviewed conference or journal paper.', aliases: ['paper', 'conference-paper', 'conference_paper', 'conference paper', 'journal_article', 'journal-article', 'journal article', 'reference', 'peer-reviewed'], template: 'reference-academic', requiredSections: ['Citation', 'Summary', 'Key Contributions', 'Benchmark Results', 'Comparison with Related Work'], citationFormat: 'doi-bibtex', acquisition: 'pdf-download', storage: 'sources/pdfs/full', qualityRules: 'peer-review-grade', defaultRadarCadence: 'quarterly' },
54
+ preprint: { description: 'arXiv / preprint server; not yet peer reviewed.', aliases: ['preprint', 'arxiv', 'arxiv-preprint', 'eprint'], template: 'reference-academic', requiredSections: ['Citation', 'Summary', 'Key Contributions', 'Benchmark Results'], citationFormat: 'arxiv-id', acquisition: 'pdf-download', storage: 'sources/pdfs/full', qualityRules: 'preprint-hedged-grade', defaultRadarCadence: 'quarterly' },
55
+ blog: { description: 'Blog post, lab announcement, or vendor research post.', aliases: ['blog', 'blog-post', 'blog post', 'announcement', 'lab-announcement', 'lab announcement', 'vendor-research', 'post'], template: 'reference-web', requiredSections: ['Citation', 'Executive Summary', 'Key Claim', 'Practical Relevance'], citationFormat: 'url-venue-retrieved', acquisition: 'web-snapshot', storage: 'sources/web', qualityRules: 'non-peer-reviewed-hedging', defaultRadarCadence: 'biannual' },
56
+ repo: { description: 'Code repository or benchmark repository.', aliases: ['repo', 'codebase', 'code', 'repository', 'benchmark-repository', 'benchmark-repo', 'benchmark repository', 'github'], template: 'reference-repo', requiredSections: ['Citation', 'Summary', 'Architecture', 'Maintenance Signals'], citationFormat: 'repo-url-commit', acquisition: 'git-clone', storage: 'sources/repos', qualityRules: 'maintenance-activity-signals', defaultRadarCadence: 'on-demand' },
57
+ book: { description: 'Book.', aliases: ['book', 'monograph'], template: 'reference-academic', requiredSections: ['Citation', 'Summary', 'Key Contributions'], citationFormat: 'isbn', acquisition: 'manual', storage: 'sources/pdfs/full', qualityRules: 'editorial-grade', defaultRadarCadence: 'on-demand' },
58
+ chapter: { description: 'Book chapter.', aliases: ['chapter', 'book_chapter', 'book-chapter', 'book chapter'], template: 'reference-academic', requiredSections: ['Citation', 'Summary', 'Key Contributions'], citationFormat: 'isbn-chapter', acquisition: 'manual', storage: 'sources/pdfs/full', qualityRules: 'editorial-grade', defaultRadarCadence: 'on-demand' },
59
+ standard: { description: 'RFC, IETF/ISO/W3C standard, or formal specification.', aliases: ['standard', 'rfc', 'spec', 'specification', 'ietf', 'iso', 'w3c'], template: 'reference-web', requiredSections: ['Citation', 'Summary', 'Scope', 'Key Requirements'], citationFormat: 'standard-id', acquisition: 'web-snapshot', storage: 'sources/web', qualityRules: 'normative-spec', defaultRadarCadence: 'annual' },
60
+ doc: { description: 'Maintainer/vendor documentation, technical report, or report.', aliases: ['doc', 'documentation', 'maintainer-doc', 'vendor-doc', 'technical-report', 'technical report', 'report', 'manual'], template: 'reference-web', requiredSections: ['Citation', 'Summary', 'Practical Relevance'], citationFormat: 'url-venue-retrieved', acquisition: 'web-snapshot', storage: 'sources/web', qualityRules: 'non-peer-reviewed-hedging', defaultRadarCadence: 'biannual' },
61
+ discussion: { description: 'Issue, forum thread, or discussion.', aliases: ['discussion', 'issue', 'thread', 'forum'], template: 'reference-web', requiredSections: ['Citation', 'Summary', 'Key Points'], citationFormat: 'url-venue-retrieved', acquisition: 'web-snapshot', storage: 'sources/web', qualityRules: 'anecdotal-hedging', defaultRadarCadence: 'on-demand' },
62
+ encyclopedia: { description: 'Encyclopedia / reference-work entry (e.g. Wikipedia).', aliases: ['encyclopedia', 'wikipedia', 'wiki'], template: 'reference-web', requiredSections: ['Citation', 'Summary'], citationFormat: 'url-venue-retrieved', acquisition: 'web-snapshot', storage: 'sources/web', qualityRules: 'tertiary-source-hedging', defaultRadarCadence: 'annual' },
63
+ 'expert-material': { description: 'Expert commentary, talk, or interview material.', aliases: ['expert-material', 'expert material', 'talk', 'interview', 'keynote'], template: 'reference-media', requiredSections: ['Citation', 'Media Profile', 'Summary', 'Key Timestamps'], citationFormat: 'timestamp-transcript', acquisition: 'manual', storage: 'media/transcripts', qualityRules: 'expert-opinion-hedging', defaultRadarCadence: 'on-demand' },
64
+ video: { description: 'Video, conference recording, course recording, or platform-hosted talk.', aliases: ['video', 'recording', 'webcast', 'livestream', 'stream', 'lecture-video', 'conference-video'], template: 'reference-media', requiredSections: ['Citation', 'Media Profile', 'Summary', 'Key Timestamps', 'Evidence and Transcript Method'], citationFormat: 'timestamp-transcript', acquisition: 'media-curator', storage: 'media/video', qualityRules: 'media-grade', defaultRadarCadence: 'on-demand' },
65
+ audio: { description: 'Audio recording, lecture audio, or direct-hosted audio source.', aliases: ['audio', 'audio-recording', 'lecture-audio', 'recording-audio'], template: 'reference-media', requiredSections: ['Citation', 'Media Profile', 'Summary', 'Key Timestamps', 'Evidence and Transcript Method'], citationFormat: 'timestamp-transcript', acquisition: 'media-curator', storage: 'media/audio', qualityRules: 'media-grade', defaultRadarCadence: 'on-demand' },
66
+ podcast: { description: 'Podcast episode or feed-hosted interview.', aliases: ['podcast', 'podcast-episode', 'episode', 'interview-audio'], template: 'reference-media', requiredSections: ['Citation', 'Media Profile', 'Summary', 'Key Timestamps', 'Evidence and Transcript Method'], citationFormat: 'timestamp-transcript', acquisition: 'media-curator', storage: 'media/audio', qualityRules: 'interview-hedged-grade', defaultRadarCadence: 'on-demand' },
67
+ lecture: { description: 'Institutional lecture, course video, keynote, seminar, or invited talk recording.', aliases: ['lecture', 'course', 'seminar', 'keynote', 'talk', 'invited-talk', 'conference-talk'], template: 'reference-media', requiredSections: ['Citation', 'Media Profile', 'Summary', 'Key Timestamps', 'Evidence and Transcript Method'], citationFormat: 'timestamp-transcript', acquisition: 'media-curator', storage: 'media/video', qualityRules: 'lecture-grade', defaultRadarCadence: 'on-demand' },
68
+ 'internal-review': { description: 'Internal research note or architecture review (not an external source).', aliases: ['internal-review', 'internal-research', 'internal-architecture-review', 'audit'], template: 'reference-internal', requiredSections: ['Summary', 'Findings'], citationFormat: 'internal-ref', acquisition: 'internal', storage: 'documentation/synthesis', qualityRules: 'internal-note', defaultRadarCadence: 'on-demand' },
69
+ },
70
+ };
71
+ /** Coerce a parsed YAML registry (snake_case fields) into the typed registry. */
72
+ function coerceRegistry(raw) {
73
+ if (!raw || typeof raw !== 'object' || !raw.types)
74
+ return null;
75
+ const types = {};
76
+ for (const [k, v] of Object.entries(raw.types)) {
77
+ types[k] = {
78
+ description: String(v.description ?? ''),
79
+ aliases: (v.aliases ?? []).map(String),
80
+ template: String(v.template ?? ''),
81
+ requiredSections: (v.required_sections ?? v.requiredSections ?? []).map(String),
82
+ citationFormat: String(v.citation_format ?? v.citationFormat ?? ''),
83
+ acquisition: String(v.acquisition ?? ''),
84
+ storage: String(v.storage ?? ''),
85
+ qualityRules: String(v.quality_rules ?? v.qualityRules ?? ''),
86
+ defaultRadarCadence: String(v.default_radar_cadence ?? v.defaultRadarCadence ?? 'on-demand'),
87
+ };
88
+ }
89
+ return {
90
+ version: Number(raw.version ?? 1),
91
+ types,
92
+ venueFallback: (raw.venue_fallback ?? raw.venueFallback ?? {}),
93
+ metaRoles: (raw.meta_roles ?? raw.metaRoles ?? []).map(String),
94
+ };
95
+ }
96
+ /** Load the registry: corpus override (`documentation/source-types.yaml`) → built-in default. */
97
+ export function loadSourceTypeRegistry(corpusRoot) {
98
+ const override = path.join(corpusRoot, ...OVERRIDE_FILE);
99
+ if (fs.existsSync(override)) {
100
+ try {
101
+ const reg = coerceRegistry(loadYaml(fs.readFileSync(override, 'utf-8')));
102
+ if (reg && Object.keys(reg.types).length)
103
+ return reg;
104
+ }
105
+ catch {
106
+ /* malformed override → default */
107
+ }
108
+ }
109
+ return DEFAULT_SOURCE_TYPES;
110
+ }
111
+ /** Build alias → canonical and meta-role lookups for fast normalization. */
112
+ function buildLookup(reg) {
113
+ const alias = new Map();
114
+ for (const [canonical, t] of Object.entries(reg.types)) {
115
+ alias.set(canonical.toLowerCase(), canonical);
116
+ for (const a of t.aliases)
117
+ alias.set(a.toLowerCase().trim(), canonical);
118
+ }
119
+ return { alias, meta: new Set(reg.metaRoles.map((r) => r.toLowerCase())) };
120
+ }
121
+ /**
122
+ * Normalize any of the three drifting type vocabularies (+ venue fallback) to a
123
+ * canonical source type. Returns the canonical key, `'meta'` for doc-role
124
+ * values (redirect/stub/…), or `'other'` when nothing matches.
125
+ */
126
+ export function normalizeSourceType(input, reg = DEFAULT_SOURCE_TYPES) {
127
+ const { alias, meta } = buildLookup(reg);
128
+ const candidates = [input.sourceType, input.type, input.bodySourceType]
129
+ .map((v) => (v ?? '').toLowerCase().trim())
130
+ .filter(Boolean);
131
+ for (const c of candidates) {
132
+ if (meta.has(c))
133
+ return 'meta';
134
+ if (alias.has(c))
135
+ return alias.get(c);
136
+ }
137
+ // No explicit type matched — try the venue classification fallback.
138
+ if (input.venue && reg.venueFallback[input.venue])
139
+ return reg.venueFallback[input.venue];
140
+ return 'other';
141
+ }
142
+ /** Look up a canonical source type's rules. */
143
+ export function getSourceType(canonical, reg = DEFAULT_SOURCE_TYPES) {
144
+ return reg.types[canonical] ?? null;
145
+ }
146
+ /** List canonical source-type keys. */
147
+ export function listSourceTypes(reg = DEFAULT_SOURCE_TYPES) {
148
+ return Object.keys(reg.types).sort();
149
+ }
150
+ /** Render the registry as a human-readable table. */
151
+ export function renderSourceTypes(reg) {
152
+ const out = [];
153
+ out.push(`Source-type registry (v${reg.version}) — ${Object.keys(reg.types).length} canonical types`);
154
+ out.push('');
155
+ out.push(`${'type'.padEnd(16)} ${'template'.padEnd(20)} ${'acquisition'.padEnd(14)} ${'cadence'.padEnd(10)} aliases`);
156
+ for (const key of listSourceTypes(reg)) {
157
+ const t = reg.types[key];
158
+ out.push(`${key.padEnd(16)} ${t.template.padEnd(20)} ${t.acquisition.padEnd(14)} ${t.defaultRadarCadence.padEnd(10)} ${t.aliases.slice(0, 4).join(', ')}${t.aliases.length > 4 ? ', …' : ''}`);
159
+ }
160
+ out.push('');
161
+ out.push(`meta roles (not source types): ${reg.metaRoles.join(', ')}`);
162
+ return out.join('\n') + '\n';
163
+ }
164
+ //# sourceMappingURL=source-types.js.map
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Scanned-page vision extraction (#1507). TS-native, provider-neutral port of
3
+ * section9 `scripts/corpus/codex_vision_extract_pages.sh`.
4
+ *
5
+ * Transcribes a directory of scanned page PNGs into per-page + combined Markdown
6
+ * via a pluggable vision adapter (the source script hardcoded the `codex` CLI;
7
+ * per the issue this is provider-neutral). Preserves the resumable / retry /
8
+ * `# Page N` contract and the `<!-- extraction-status: complete -->` markers.
9
+ * Optionally rasterizes a PDF → page PNGs first (poppler `pdftoppm`).
10
+ *
11
+ * Adapters:
12
+ * - `codex` — `codex exec --sandbox read-only --image … --output-last-message`
13
+ * - `command` — a generic shell-command template (AIWG_VISION_COMMAND) with
14
+ * {image}/{prompt_file}/{out} placeholders → works with any vision
15
+ * CLI (claude, a custom script, …). Truly provider-neutral.
16
+ * - a caller-supplied adapter (used by tests with a fake transcriber).
17
+ *
18
+ * @source historical: corpus/codex_vision_extract_pages.sh
19
+ * @tests @test/unit/artifacts/vision-extract.test.ts
20
+ */
21
+ import * as fs from 'fs';
22
+ import * as path from 'path';
23
+ import { spawnSync } from 'child_process';
24
+ /** Strict-transcription prompt. `title` parameterizes the corpus-specific intro. */
25
+ export function buildPrompt(page, title) {
26
+ const subject = title ? `from ${title}` : 'from a scanned document';
27
+ return [
28
+ `You are transcribing one scanned page image ${subject}.`,
29
+ '',
30
+ 'Task:',
31
+ '- Extract all readable text from this image as accurately as possible.',
32
+ '- Preserve reading order.',
33
+ '- Keep headings, captions, labels, footnotes, marginal text, chart labels, table entries, and page numbers when readable.',
34
+ '- If text is part of a figure or chart, include it under a short marker like "[figure text]" or "[chart labels]".',
35
+ '- Do not summarize, interpret, modernize spelling, or add commentary.',
36
+ '- If a word is uncertain, write the best reading followed by "[?]".',
37
+ '- If a region is unreadable, write "[unreadable]" only for that region.',
38
+ '- Output Markdown only.',
39
+ `- Start exactly with: "# Page ${page}"`,
40
+ '',
41
+ 'Accuracy is more important than preserving coordinates or line breaks.',
42
+ ].join('\n');
43
+ }
44
+ // ── Adapters ─────────────────────────────────────────────────────────────────
45
+ const codexAdapter = {
46
+ name: 'codex',
47
+ transcribe(imagePath, prompt, ctx) {
48
+ const tmp = path.join(path.dirname(imagePath), `.codex-out-${ctx.page}.txt`);
49
+ const args = ['exec'];
50
+ if (ctx.model)
51
+ args.push('--model', ctx.model);
52
+ args.push('--sandbox', 'read-only', '--cd', ctx.root, '--image', imagePath, '--output-last-message', tmp, '-');
53
+ try {
54
+ const r = spawnSync(process.env.AIWG_CODEX_BIN || 'codex', args, {
55
+ input: prompt,
56
+ timeout: ctx.timeoutSec * 1000,
57
+ encoding: 'utf8',
58
+ });
59
+ if (r.status === 0 && fs.existsSync(tmp)) {
60
+ const text = fs.readFileSync(tmp, 'utf8');
61
+ fs.rmSync(tmp, { force: true });
62
+ return { ok: true, text };
63
+ }
64
+ fs.rmSync(tmp, { force: true });
65
+ return { ok: false };
66
+ }
67
+ catch {
68
+ fs.rmSync(tmp, { force: true });
69
+ return { ok: false };
70
+ }
71
+ },
72
+ };
73
+ /**
74
+ * Generic command-template adapter (provider-neutral). Runs
75
+ * `AIWG_VISION_COMMAND` (or the `--command` flag) with placeholders:
76
+ * {image} absolute image path
77
+ * {prompt_file} path to a file containing the prompt
78
+ * {out} path the command must write the transcription to
79
+ * e.g. claude -p "$(cat {prompt_file})" --image {image} > {out}
80
+ */
81
+ function commandAdapter(template) {
82
+ return {
83
+ name: 'command',
84
+ transcribe(imagePath, prompt, ctx) {
85
+ const dir = path.dirname(imagePath);
86
+ const promptFile = path.join(dir, `.vision-prompt-${ctx.page}.txt`);
87
+ const out = path.join(dir, `.vision-out-${ctx.page}.txt`);
88
+ fs.writeFileSync(promptFile, prompt);
89
+ const cmd = template
90
+ .replaceAll('{image}', JSON.stringify(imagePath))
91
+ .replaceAll('{prompt_file}', JSON.stringify(promptFile))
92
+ .replaceAll('{out}', JSON.stringify(out));
93
+ try {
94
+ const r = spawnSync('sh', ['-c', cmd], { timeout: ctx.timeoutSec * 1000, encoding: 'utf8' });
95
+ let text;
96
+ if (fs.existsSync(out))
97
+ text = fs.readFileSync(out, 'utf8');
98
+ else if (r.status === 0 && r.stdout)
99
+ text = r.stdout; // command wrote to stdout
100
+ fs.rmSync(promptFile, { force: true });
101
+ fs.rmSync(out, { force: true });
102
+ return { ok: r.status === 0 && !!text, text };
103
+ }
104
+ catch {
105
+ fs.rmSync(promptFile, { force: true });
106
+ fs.rmSync(out, { force: true });
107
+ return { ok: false };
108
+ }
109
+ },
110
+ };
111
+ }
112
+ /** Resolve the vision adapter from options/env. Throws when misconfigured. */
113
+ export function resolveAdapter(opts = {}) {
114
+ const command = opts.command ?? process.env.AIWG_VISION_COMMAND;
115
+ const provider = opts.provider ?? process.env.AIWG_VISION_PROVIDER ?? (command ? 'command' : 'codex');
116
+ if (provider === 'command') {
117
+ if (!command)
118
+ throw new Error("vision provider 'command' requires --command or AIWG_VISION_COMMAND (template with {image}/{prompt_file}/{out})");
119
+ return commandAdapter(command);
120
+ }
121
+ if (provider === 'codex')
122
+ return codexAdapter;
123
+ throw new Error(`unknown vision provider '${provider}' (codex | command)`);
124
+ }
125
+ // ── PDF → PNG rasterization (poppler pdftoppm) ───────────────────────────────
126
+ export function pdftoppmAvailable() {
127
+ try {
128
+ return spawnSync('pdftoppm', ['-v'], { encoding: 'utf8' }).status === 0 || spawnSync('pdftoppm', ['-h'], { encoding: 'utf8' }).status !== null;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ }
134
+ /**
135
+ * Rasterize a PDF into zero-padded `page-NNN.png` files in `outDir` via
136
+ * `pdftoppm`. Returns the page count. Throws if pdftoppm is unavailable.
137
+ */
138
+ export function rasterizePdf(pdfPath, outDir, dpi = 200) {
139
+ if (!pdftoppmAvailable()) {
140
+ throw new Error('PDF rasterization needs poppler `pdftoppm` on PATH (macOS: `brew install poppler`; Debian/Ubuntu: `apt install poppler-utils`).');
141
+ }
142
+ if (!fs.existsSync(pdfPath))
143
+ throw new Error(`PDF not found: ${pdfPath}`);
144
+ fs.mkdirSync(outDir, { recursive: true });
145
+ // pdftoppm writes <prefix>-<n>.png with its own zero-padding based on page count.
146
+ const prefix = path.join(outDir, 'page');
147
+ const r = spawnSync('pdftoppm', ['-png', '-r', String(dpi), pdfPath, prefix], { encoding: 'utf8' });
148
+ if (r.status !== 0)
149
+ throw new Error(`pdftoppm failed: ${r.stderr || r.status}`);
150
+ // Normalize names to page-NNN.png (3-digit zero-pad).
151
+ let count = 0;
152
+ for (const f of fs.readdirSync(outDir)) {
153
+ const m = f.match(/^page-(\d+)\.png$/);
154
+ if (!m)
155
+ continue;
156
+ count++;
157
+ const padded = `page-${m[1].padStart(3, '0')}.png`;
158
+ if (padded !== f)
159
+ fs.renameSync(path.join(outDir, f), path.join(outDir, padded));
160
+ }
161
+ return count;
162
+ }
163
+ // ── Orchestration (resumable page loop + combine) ────────────────────────────
164
+ const COMPLETE_MARKER = '<!-- extraction-status: complete -->';
165
+ function pageNumber(file) {
166
+ const m = path.basename(file).match(/^page-0*(\d+)\.png$/);
167
+ return m ? parseInt(m[1], 10) : null;
168
+ }
169
+ function isComplete(outFile) {
170
+ return fs.existsSync(outFile) && fs.readFileSync(outFile, 'utf8').startsWith(COMPLETE_MARKER);
171
+ }
172
+ export async function extractPages(opts) {
173
+ if (!fs.existsSync(opts.imageDir))
174
+ throw new Error(`missing image directory: ${opts.imageDir}`);
175
+ const pageDir = path.join(opts.outDir, 'pages');
176
+ fs.mkdirSync(pageDir, { recursive: true });
177
+ const log = [];
178
+ const logLine = (s) => log.push(s);
179
+ const sleep = opts.sleep ?? (() => { });
180
+ const start = opts.start ?? 1;
181
+ const end = opts.end ?? Number.MAX_SAFE_INTEGER;
182
+ const retries = opts.retries ?? 0;
183
+ const timeoutSec = opts.timeoutSec ?? 240;
184
+ const images = fs
185
+ .readdirSync(opts.imageDir)
186
+ .filter((f) => /^page-\d+\.png$/.test(f))
187
+ .map((f) => path.join(opts.imageDir, f))
188
+ .sort();
189
+ let processed = 0;
190
+ let completed = 0;
191
+ let failed = 0;
192
+ for (const image of images) {
193
+ const page = pageNumber(image);
194
+ if (page == null || page < start || page > end)
195
+ continue;
196
+ processed++;
197
+ const outFile = path.join(pageDir, `page-${String(page).padStart(3, '0')}.md`);
198
+ if (!opts.force && isComplete(outFile)) {
199
+ logLine(`skip page ${page}: already complete`);
200
+ completed++;
201
+ continue;
202
+ }
203
+ const prompt = buildPrompt(page, opts.title);
204
+ let ok = false;
205
+ for (let attempt = 1; attempt <= retries + 1; attempt++) {
206
+ const res = opts.adapter.transcribe(image, prompt, { root: path.dirname(opts.imageDir), page, timeoutSec, model: opts.model });
207
+ if (res.ok && res.text && new RegExp(`^# Page ${page}\\b`, 'm').test(res.text)) {
208
+ fs.writeFileSync(outFile, `${COMPLETE_MARKER}\n<!-- source-image: ${image} -->\n\n${res.text.trimEnd()}\n`);
209
+ logLine(`page ${page}: complete (attempt ${attempt})`);
210
+ ok = true;
211
+ completed++;
212
+ break;
213
+ }
214
+ logLine(`page ${page}: unusable output (attempt ${attempt})`);
215
+ if (attempt <= retries)
216
+ sleep(opts.sleepSec ?? 0);
217
+ }
218
+ if (!ok) {
219
+ fs.writeFileSync(outFile, `<!-- extraction-status: failed -->\n<!-- source-image: ${image} -->\n\n# Page ${page}\n\n[extraction failed]\n`);
220
+ logLine(`page ${page}: failed after ${retries + 1} attempts`);
221
+ failed++;
222
+ sleep(opts.sleepSec ?? 0);
223
+ }
224
+ sleep(opts.sleepSec ?? 0);
225
+ }
226
+ // Combine.
227
+ const slug = path.basename(opts.outDir);
228
+ const head = [`# ${opts.title ?? slug}`, '', `Source: vision extraction (${opts.adapter.name}) from page PNGs`, `Pages processed: ${processed}`, ''];
229
+ const parts = [];
230
+ for (const f of fs.readdirSync(pageDir).filter((x) => /^page-\d+\.md$/.test(x)).sort()) {
231
+ parts.push(fs.readFileSync(path.join(pageDir, f), 'utf8'), '\n---\n\n');
232
+ }
233
+ const combinedMd = head.join('\n') + parts.join('');
234
+ const combinedTxt = combinedMd.split('\n').filter((l) => !/^<!--.*-->$/.test(l.trim())).join('\n');
235
+ fs.writeFileSync(path.join(opts.outDir, `${slug}.vision.md`), combinedMd);
236
+ fs.writeFileSync(path.join(opts.outDir, `${slug}.vision.txt`), combinedTxt);
237
+ fs.writeFileSync(path.join(opts.outDir, 'run.log'), log.join('\n') + '\n');
238
+ return { processed, completed, failed, combinedMd, combinedTxt };
239
+ }
240
+ export function renderExtract(r) {
241
+ return `vision-extract: processed ${r.processed}, completed ${r.completed}, failed ${r.failed}\n`;
242
+ }
243
+ //# sourceMappingURL=vision-extract.js.map
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Research-corpus markdown-view builder (#1490).
3
+ *
4
+ * The native replacement for the retired `corpus-index-build/build.py`.
5
+ * `aiwg index build` invokes this in the same process that builds the JSON
6
+ * graphs, so the corpus is parsed once. Reads the view manifest from
7
+ * `index.graphs.indices.manifest` (canonical `.aiwg/aiwg.config`, #1491).
8
+ *
9
+ * @source historical: corpus-index-build/build.py (configured_graphs, main)
10
+ */
11
+ import * as fs from 'fs';
12
+ import * as path from 'path';
13
+ import { readIndexConfig, readAiwgConfig } from '../../config/aiwg-config.js';
14
+ import { loadCorpus } from './ref-parser.js';
15
+ import { renderView, outputForView } from './renderers.js';
16
+ const DEFAULT_VIEWS = ['by-topic', 'by-year', 'authors', 'by-venue', 'by-method', 'training-pipeline', 'by-model-size'];
17
+ /**
18
+ * Resolve which views to render from the index config, mirroring build.py
19
+ * configured_graphs(): manifest entries (by name), else a default set, plus
20
+ * citation-network when it is present as an index.graphs key.
21
+ */
22
+ function configuredViews(index) {
23
+ const views = new Map();
24
+ const graphs = (index?.graphs ?? {});
25
+ const indices = graphs.indices;
26
+ const manifest = Array.isArray(indices?.manifest) ? indices.manifest : [];
27
+ for (const entry of manifest) {
28
+ if (entry && typeof entry === 'object' && typeof entry.name === 'string') {
29
+ const e = entry;
30
+ views.set(e.name, e);
31
+ }
32
+ }
33
+ if (views.size === 0) {
34
+ for (const name of DEFAULT_VIEWS)
35
+ views.set(name, { name });
36
+ }
37
+ if ('citation-network' in graphs && !views.has('citation-network')) {
38
+ views.set('citation-network', { name: 'citation-network' });
39
+ }
40
+ return views;
41
+ }
42
+ /** Read the Source-Checksum recorded in an existing view file (for staleness skip). */
43
+ function existingChecksum(filePath) {
44
+ if (!fs.existsSync(filePath))
45
+ return null;
46
+ const m = fs.readFileSync(filePath, 'utf-8').match(/^Source-Checksum:\s*sha256:([a-f0-9]{64})\s*$/m);
47
+ return m ? m[1] : null;
48
+ }
49
+ function utcTimestamp() {
50
+ // Second-precision UTC, matching build.py's isoformat().replace("+00:00","Z").
51
+ return new Date().toISOString().replace(/\.\d{3}Z$/, 'Z');
52
+ }
53
+ /**
54
+ * Resolve the corpus root (#1497): `AIWG_CORPUS_ROOT` env > `research.corpusRoot`
55
+ * in `.aiwg/aiwg.config` > the project root (cwd). Relative values resolve
56
+ * against cwd.
57
+ */
58
+ export async function resolveCorpusRoot(cwd) {
59
+ const env = process.env.AIWG_CORPUS_ROOT;
60
+ if (env && env.trim())
61
+ return path.isAbsolute(env) ? env : path.join(cwd, env);
62
+ try {
63
+ const cfg = await readAiwgConfig(cwd);
64
+ const cr = cfg?.research?.corpusRoot;
65
+ if (cr && cr.trim())
66
+ return path.isAbsolute(cr) ? cr : path.join(cwd, cr);
67
+ }
68
+ catch {
69
+ /* no config / unreadable — fall through to cwd */
70
+ }
71
+ return cwd;
72
+ }
73
+ /**
74
+ * Render the configured research-corpus markdown views. Returns one result per
75
+ * selected view. Returns `[]` (renders nothing) when the corpus root has no
76
+ * `documentation/references/` corpus — so this is a safe no-op in ordinary
77
+ * SDLC projects.
78
+ */
79
+ export async function buildCorpusViews(cwd, opts = {}) {
80
+ // Corpus root may differ from the project root (#1497): env override >
81
+ // research.corpusRoot in .aiwg/aiwg.config > project root. The index config
82
+ // is always read from the project's .aiwg/aiwg.config (cwd); corpus content
83
+ // and rendered views live under the corpus root.
84
+ const root = await resolveCorpusRoot(cwd);
85
+ // No research corpus → nothing to render.
86
+ if (!fs.existsSync(path.join(root, 'documentation', 'references')))
87
+ return [];
88
+ const { index } = await readIndexConfig(cwd);
89
+ const views = configuredViews(index);
90
+ // `only` selects a single view when it is one we render; an unrelated JSON
91
+ // graph name (e.g. 'codebase') selects nothing here.
92
+ let selected;
93
+ if (opts.only) {
94
+ if (!views.has(opts.only))
95
+ return [];
96
+ selected = [opts.only];
97
+ }
98
+ else {
99
+ selected = [...views.keys()];
100
+ }
101
+ const { records, corpusRoot, checksum } = loadCorpus(root);
102
+ const generated = utcTimestamp();
103
+ const ctx = { records, corpusRoot, generated, checksum };
104
+ const results = [];
105
+ for (const name of selected) {
106
+ const outRel = outputForView(name, views.get(name)?.output);
107
+ const outPath = path.join(root, outRel);
108
+ if (!opts.force && existingChecksum(outPath) === checksum) {
109
+ results.push({ graph: name, status: 'skipped', output: outRel, papers: records.length });
110
+ continue;
111
+ }
112
+ let content;
113
+ try {
114
+ content = renderView(name, ctx);
115
+ }
116
+ catch (err) {
117
+ results.push({ graph: name, status: 'unsupported', output: outRel, error: err.message });
118
+ continue;
119
+ }
120
+ fs.mkdirSync(path.dirname(outPath), { recursive: true });
121
+ fs.writeFileSync(outPath, content, 'utf-8');
122
+ results.push({ graph: name, status: 'built', output: outRel, papers: records.length });
123
+ }
124
+ return results;
125
+ }
126
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Shared research-corpus cadence + staleness config (#1498, #1502).
3
+ *
4
+ * Single source of truth for refresh-cadence → window math. Consumed by:
5
+ * - renderers.ts `radar-stale-queue` view (#1492)
6
+ * - the radar subsystem: radar-init GRADE→cadence default, radar-status (#1498)
7
+ * - the profile subsystem: profile-status staleness (#1502)
8
+ *
9
+ * Ports `corpus/radar_staleness.py` CADENCE_DAYS, `corpus/radar_init.py`
10
+ * CADENCE_BY_GRADE, and `profiles/find_stale_profiles.py`'s cadence map into one
11
+ * module so the date-math lives in exactly one place — the explicit #1498/#1502
12
+ * "one staleness helper" requirement.
13
+ *
14
+ * @source historical: corpus/radar_staleness.py, corpus/radar_init.py
15
+ */
16
+ /**
17
+ * Refresh-cadence enum word → staleness window in days.
18
+ *
19
+ * `null` = on-demand: never auto-overdue. `biennial` is accepted as a synonym
20
+ * for `biannual` (180d); both spellings appear in corpus sidecars. The Python
21
+ * sources used distinct on-demand sentinels (radar_staleness: None;
22
+ * find_stale_profiles: 9999) — both mean "never auto-stale", normalized to
23
+ * `null` here.
24
+ */
25
+ export const CADENCE_DAYS = {
26
+ // PROF-S curator revisit-cadence vocab (#1499): daily/weekly/biweekly.
27
+ daily: 1,
28
+ weekly: 7,
29
+ biweekly: 14,
30
+ monthly: 30,
31
+ quarterly: 90,
32
+ biannual: 180,
33
+ biennial: 180,
34
+ 'semi-annual': 180, // profile sidecars (#1502) spell the 180-day cadence this way
35
+ annual: 365,
36
+ 'on-demand': null,
37
+ };
38
+ /**
39
+ * Default refresh cadence by GRADE letter (radar-init scaffold default).
40
+ * A→quarterly, B/C→biannual, D→on-demand. Ports `radar_init.py` CADENCE_BY_GRADE.
41
+ */
42
+ export const CADENCE_BY_GRADE = {
43
+ A: 'quarterly',
44
+ B: 'biannual',
45
+ C: 'biannual',
46
+ D: 'on-demand',
47
+ };
48
+ /**
49
+ * Look up the staleness window for a cadence word.
50
+ * Returns `null` for on-demand and `undefined` for an unknown/absent cadence —
51
+ * callers distinguish "never stale" (null) from "can't tell" (undefined).
52
+ */
53
+ export function cadenceWindowDays(cadence) {
54
+ if (!cadence)
55
+ return undefined;
56
+ return CADENCE_DAYS[cadence.toLowerCase()];
57
+ }
58
+ /** Default cadence for a GRADE letter; falls back to `biannual` for unknown/absent grades. */
59
+ export function cadenceForGrade(grade) {
60
+ if (!grade)
61
+ return 'biannual';
62
+ const letter = grade.trim().toUpperCase()[0] ?? '';
63
+ return CADENCE_BY_GRADE[letter] ?? 'biannual';
64
+ }
65
+ /**
66
+ * Default affiliation canonicalization map (#1503): canonical `PROF-O-{slug}`
67
+ * → variant org-name strings that should resolve to it. Ports
68
+ * `corpus/normalize_affiliation.py` CANONICAL_MAP. Per epic #1496 principle #3
69
+ * (externalize hardcoded data), this default is overridable per-corpus via a
70
+ * `documentation/profiles/orgs/affiliation-map.yaml` data file (loaded by the
71
+ * sidecar-repair tool); this module keeps only the pure default + reverse-map
72
+ * builder so it stays dependency-free.
73
+ */
74
+ export const DEFAULT_AFFILIATION_MAP = {
75
+ 'PROF-O-anthropic': ['anthropic'],
76
+ 'PROF-O-openai': ['openai'],
77
+ 'PROF-O-google-deepmind': ['google deepmind', 'deepmind', 'google brain (now part of google deepmind)'],
78
+ 'PROF-O-meta-fair': ['meta fair', 'facebook ai research', 'meta ai', 'meta ai research'],
79
+ 'PROF-O-microsoft-research': ['microsoft research'],
80
+ 'PROF-O-mit-csail': ['mit csail', 'massachusetts institute of technology — csail'],
81
+ 'PROF-O-nvidia': ['nvidia', 'nvidia research'],
82
+ 'PROF-O-sakana-ai': ['sakana ai'],
83
+ 'PROF-O-stanford-hai': ['stanford hai', 'stanford institute for human-centered artificial intelligence'],
84
+ 'PROF-O-together-ai': ['together ai', 'together.ai'],
85
+ 'PROF-O-uc-berkeley': ['uc berkeley', 'university of california, berkeley'],
86
+ 'PROF-O-cohere': ['cohere'],
87
+ 'PROF-O-apollo-research': ['apollo research'],
88
+ };
89
+ /**
90
+ * Reverse a canonical map (slug → variants) into variant-name → slug, plus
91
+ * self-mapping each slug. All keys lowercased/trimmed for direct lookup.
92
+ */
93
+ export function buildAffiliationReverse(map) {
94
+ const rev = new Map();
95
+ for (const [slug, names] of Object.entries(map)) {
96
+ for (const n of names)
97
+ rev.set(n.toLowerCase().trim(), slug);
98
+ rev.set(slug.toLowerCase(), slug);
99
+ }
100
+ return rev;
101
+ }
102
+ const MS_PER_DAY = 86_400_000;
103
+ /**
104
+ * Compute staleness for a `refresh-cadence` + `last-refreshed` ISO date as of
105
+ * `today`. Mirrors `radar_staleness.compute_staleness`: whole-day floor,
106
+ * UTC-midnight anchoring, and on-demand / unknown-cadence / undatable inputs all
107
+ * yield `overdueDays === null` (not stale).
108
+ *
109
+ * `today` should be a UTC-midnight Date (e.g. `new Date('2026-05-26T00:00:00Z')`)
110
+ * so day deltas are exact.
111
+ */
112
+ export function computeStaleness(cadence, lastRefreshed, today) {
113
+ const windowDays = cadenceWindowDays(cadence);
114
+ let daysSince = null;
115
+ if (lastRefreshed) {
116
+ const last = new Date(`${lastRefreshed}T00:00:00Z`);
117
+ if (!Number.isNaN(last.getTime())) {
118
+ daysSince = Math.floor((today.getTime() - last.getTime()) / MS_PER_DAY);
119
+ }
120
+ }
121
+ const overdueDays = daysSince !== null && typeof windowDays === 'number' ? daysSince - windowDays : null;
122
+ return { daysSince, windowDays, overdueDays, isStale: overdueDays !== null && overdueDays > 0 };
123
+ }
124
+ //# sourceMappingURL=corpus-config.js.map