@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.17

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 (466) hide show
  1. package/README.md +21 -1
  2. package/bin/aiwg.mjs +349 -0
  3. package/dist/src/a2a/agent-card.js +145 -0
  4. package/dist/src/a2a/client.js +411 -0
  5. package/dist/src/a2a/hitl-cli.js +171 -0
  6. package/dist/src/a2a/hitl-driver.js +370 -0
  7. package/dist/src/a2a/hitl.js +181 -0
  8. package/dist/src/a2a/http.js +193 -0
  9. package/dist/src/a2a/jcs.js +128 -0
  10. package/dist/src/a2a/jws.js +187 -0
  11. package/dist/src/a2a/types.js +24 -0
  12. package/dist/src/a2a/webhook.js +240 -0
  13. package/dist/src/activity-log/cli.js +348 -0
  14. package/dist/src/activity-log/parser.js +81 -0
  15. package/dist/src/activity-log/types.js +50 -0
  16. package/dist/src/agents/agent-deployer.js +367 -0
  17. package/dist/src/agents/agent-packager.js +271 -0
  18. package/dist/src/agents/agent-validator.js +271 -0
  19. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  20. package/dist/src/agents/grounding/types.js +12 -0
  21. package/dist/src/agents/index.js +10 -0
  22. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  23. package/dist/src/agents/types.js +7 -0
  24. package/dist/src/api/index.d.ts +10 -0
  25. package/dist/src/api/index.js +10 -0
  26. package/dist/src/artifacts/address-parser.js +73 -0
  27. package/dist/src/artifacts/audit/cli.js +183 -0
  28. package/dist/src/artifacts/audit/drift.js +122 -0
  29. package/dist/src/artifacts/audit/types.js +12 -0
  30. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  31. package/dist/src/artifacts/backends/json-backend.js +129 -0
  32. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  33. package/dist/src/artifacts/browser-export.js +622 -0
  34. package/dist/src/artifacts/capability-resolver.js +94 -0
  35. package/dist/src/artifacts/checksum-manifest.js +91 -0
  36. package/dist/src/artifacts/citation-parser.js +162 -0
  37. package/dist/src/artifacts/cli.js +1462 -0
  38. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  39. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  40. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  41. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  42. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  43. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  44. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  45. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  46. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  47. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  48. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  49. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  51. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  52. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  53. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  54. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  55. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  56. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  57. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  58. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  60. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  61. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  62. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  63. package/dist/src/artifacts/corpus-views/build.js +126 -0
  64. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  65. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  66. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  67. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  68. package/dist/src/artifacts/dep-graph.js +173 -0
  69. package/dist/src/artifacts/discover-facets.js +375 -0
  70. package/dist/src/artifacts/embedding-index.js +354 -0
  71. package/dist/src/artifacts/enrichment/cli.js +240 -0
  72. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  73. package/dist/src/artifacts/enrichment/store.js +90 -0
  74. package/dist/src/artifacts/enrichment/types.js +12 -0
  75. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  76. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  77. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  78. package/dist/src/artifacts/fulltext.js +108 -0
  79. package/dist/src/artifacts/graph-backend.js +51 -0
  80. package/dist/src/artifacts/graph-query.js +247 -0
  81. package/dist/src/artifacts/hybrid-query.js +225 -0
  82. package/dist/src/artifacts/index-builder.js +1089 -0
  83. package/dist/src/artifacts/index-reader.js +112 -0
  84. package/dist/src/artifacts/index-status.js +193 -0
  85. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  86. package/dist/src/artifacts/move.js +154 -0
  87. package/dist/src/artifacts/operational-state.js +239 -0
  88. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  89. package/dist/src/artifacts/query-engine.js +1955 -0
  90. package/dist/src/artifacts/source-graph.js +529 -0
  91. package/dist/src/artifacts/stats.js +169 -0
  92. package/dist/src/artifacts/types.js +606 -0
  93. package/dist/src/artifacts/views/cli.js +293 -0
  94. package/dist/src/artifacts/views/definition.js +170 -0
  95. package/dist/src/artifacts/views/store.js +149 -0
  96. package/dist/src/artifacts/views/types.js +8 -0
  97. package/dist/src/artifacts/watcher.js +255 -0
  98. package/dist/src/catalog/builtin-models.json +636 -0
  99. package/dist/src/catalog/cli.js +228 -0
  100. package/dist/src/catalog/cli.mjs +289 -0
  101. package/dist/src/catalog/index.js +15 -0
  102. package/dist/src/catalog/loader.js +217 -0
  103. package/dist/src/catalog/loader.mjs +251 -0
  104. package/dist/src/catalog/sources.json +41 -0
  105. package/dist/src/catalog/types.js +8 -0
  106. package/dist/src/channel/manager.mjs +504 -0
  107. package/dist/src/cli/agent-spawn.js +178 -0
  108. package/dist/src/cli/cli-extension-loader.js +245 -0
  109. package/dist/src/cli/command-log.js +275 -0
  110. package/dist/src/cli/config-loader.js +232 -0
  111. package/dist/src/cli/env.js +82 -0
  112. package/dist/src/cli/errors.js +150 -0
  113. package/dist/src/cli/find-package-root.js +40 -0
  114. package/dist/src/cli/git-hooks.js +250 -0
  115. package/dist/src/cli/handlers/agentcard.js +206 -0
  116. package/dist/src/cli/handlers/artifacts.js +76 -0
  117. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  118. package/dist/src/cli/handlers/cockpit.js +137 -0
  119. package/dist/src/cli/handlers/command-log.js +37 -0
  120. package/dist/src/cli/handlers/daemon.js +59 -0
  121. package/dist/src/cli/handlers/diagnose.js +300 -0
  122. package/dist/src/cli/handlers/execution-mode.js +105 -0
  123. package/dist/src/cli/handlers/feedback.js +341 -0
  124. package/dist/src/cli/handlers/help.js +147 -0
  125. package/dist/src/cli/handlers/index.js +302 -0
  126. package/dist/src/cli/handlers/init.js +179 -0
  127. package/dist/src/cli/handlers/install.js +129 -0
  128. package/dist/src/cli/handlers/issues.js +46 -0
  129. package/dist/src/cli/handlers/lint.js +42 -0
  130. package/dist/src/cli/handlers/local-executor.js +315 -0
  131. package/dist/src/cli/handlers/marketplace.js +168 -0
  132. package/dist/src/cli/handlers/mc.js +1010 -0
  133. package/dist/src/cli/handlers/models.js +352 -0
  134. package/dist/src/cli/handlers/packages.js +155 -0
  135. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  136. package/dist/src/cli/handlers/ralph.js +575 -0
  137. package/dist/src/cli/handlers/refresh.js +432 -0
  138. package/dist/src/cli/handlers/regenerate.js +336 -0
  139. package/dist/src/cli/handlers/repo-access.js +109 -0
  140. package/dist/src/cli/handlers/run.js +165 -0
  141. package/dist/src/cli/handlers/runtime-info.js +301 -0
  142. package/dist/src/cli/handlers/sandbox.js +197 -0
  143. package/dist/src/cli/handlers/scaffolding.js +149 -0
  144. package/dist/src/cli/handlers/script-runner.js +121 -0
  145. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  146. package/dist/src/cli/handlers/serve.js +1835 -0
  147. package/dist/src/cli/handlers/session.js +348 -0
  148. package/dist/src/cli/handlers/setup.js +440 -0
  149. package/dist/src/cli/handlers/skill-lint.js +367 -0
  150. package/dist/src/cli/handlers/skill-usage.js +74 -0
  151. package/dist/src/cli/handlers/steward.js +567 -0
  152. package/dist/src/cli/handlers/subcommands.js +1702 -0
  153. package/dist/src/cli/handlers/team.js +337 -0
  154. package/dist/src/cli/handlers/types.js +11 -0
  155. package/dist/src/cli/handlers/use.js +2772 -0
  156. package/dist/src/cli/handlers/utilities.js +703 -0
  157. package/dist/src/cli/handlers/version.js +134 -0
  158. package/dist/src/cli/handlers/workspace-context.js +93 -0
  159. package/dist/src/cli/handlers/workspace.js +126 -0
  160. package/dist/src/cli/help-generator.js +178 -0
  161. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  162. package/dist/src/cli/hooks/executor.js +96 -0
  163. package/dist/src/cli/hooks/index.js +15 -0
  164. package/dist/src/cli/hooks/registry.js +143 -0
  165. package/dist/src/cli/hooks/types.js +13 -0
  166. package/dist/src/cli/log.js +492 -0
  167. package/dist/src/cli/project-isolation/detect.js +70 -0
  168. package/dist/src/cli/project-isolation/index.js +7 -0
  169. package/dist/src/cli/project-isolation/signals.js +17 -0
  170. package/dist/src/cli/project-isolation/warning.js +102 -0
  171. package/dist/src/cli/prompt-utils.js +155 -0
  172. package/dist/src/cli/provider-deployment-plan.js +126 -0
  173. package/dist/src/cli/provider-resolution.js +119 -0
  174. package/dist/src/cli/router.js +305 -0
  175. package/dist/src/cli/scope-resolver.js +392 -0
  176. package/dist/src/cli/skill-usage.js +616 -0
  177. package/dist/src/cli/ui.js +224 -0
  178. package/dist/src/cli/watch-service.js +203 -0
  179. package/dist/src/cli/workflow-orchestrator.js +478 -0
  180. package/dist/src/cli/workspace-signals.js +321 -0
  181. package/dist/src/community/footer.js +14 -0
  182. package/dist/src/community/links.js +123 -0
  183. package/dist/src/community/milestones.js +46 -0
  184. package/dist/src/community/nudge-policy.js +93 -0
  185. package/dist/src/config/aiwg-config.js +883 -0
  186. package/dist/src/config/cli.js +703 -0
  187. package/dist/src/config/gitignore.js +156 -0
  188. package/dist/src/config/project-artifacts.js +76 -0
  189. package/dist/src/config/user-config.js +428 -0
  190. package/dist/src/config/user-registry.js +127 -0
  191. package/dist/src/config/workspace.js +276 -0
  192. package/dist/src/contributors/detect.js +39 -0
  193. package/dist/src/contributors/discover.js +172 -0
  194. package/dist/src/contributors/heuristic.js +186 -0
  195. package/dist/src/contributors/index.js +11 -0
  196. package/dist/src/contributors/types.js +13 -0
  197. package/dist/src/contributors/validation.js +116 -0
  198. package/dist/src/data/community.schema.json +43 -0
  199. package/dist/src/data/community.yaml +16 -0
  200. package/dist/src/extensions/capability-index.js +270 -0
  201. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  202. package/dist/src/extensions/commands/definitions.js +3485 -0
  203. package/dist/src/extensions/deployment-registration.js +463 -0
  204. package/dist/src/extensions/index.js +22 -0
  205. package/dist/src/extensions/loader.js +132 -0
  206. package/dist/src/extensions/managed-marker.js +100 -0
  207. package/dist/src/extensions/manifest.js +196 -0
  208. package/dist/src/extensions/project-local-activity.js +114 -0
  209. package/dist/src/extensions/project-local-discovery.js +261 -0
  210. package/dist/src/extensions/project-local-doctor.js +281 -0
  211. package/dist/src/extensions/project-local-gitignore.js +176 -0
  212. package/dist/src/extensions/project-local-paths.js +121 -0
  213. package/dist/src/extensions/project-local-promote.js +218 -0
  214. package/dist/src/extensions/project-local-remove.js +373 -0
  215. package/dist/src/extensions/project-local-scaffold.js +252 -0
  216. package/dist/src/extensions/project-quickref.js +291 -0
  217. package/dist/src/extensions/registry.js +368 -0
  218. package/dist/src/extensions/shadow-resolver.js +271 -0
  219. package/dist/src/extensions/types.js +86 -0
  220. package/dist/src/extensions/upstream-registry.js +195 -0
  221. package/dist/src/extensions/validation.js +631 -0
  222. package/dist/src/features/catalog.js +88 -0
  223. package/dist/src/features/cli.js +197 -0
  224. package/dist/src/features/installer.js +57 -0
  225. package/dist/src/features/paths.js +14 -0
  226. package/dist/src/features/runtime.js +21 -0
  227. package/dist/src/features/status.js +134 -0
  228. package/dist/src/hooks/laziness-detection.js +532 -0
  229. package/dist/src/intake/git-history-analyzer.js +486 -0
  230. package/dist/src/intake/index.js +9 -0
  231. package/dist/src/issues/cli.js +327 -0
  232. package/dist/src/issues/index.js +5 -0
  233. package/dist/src/issues/live.js +154 -0
  234. package/dist/src/issues/local.js +666 -0
  235. package/dist/src/issues/sync.js +143 -0
  236. package/dist/src/issues/types.js +2 -0
  237. package/dist/src/issues/workflows.js +164 -0
  238. package/dist/src/kb/cli.js +173 -0
  239. package/dist/src/lint/cli.js +171 -0
  240. package/dist/src/lint/loader.js +225 -0
  241. package/dist/src/lint/reporters.js +141 -0
  242. package/dist/src/lint/runner.js +364 -0
  243. package/dist/src/lint/types.js +10 -0
  244. package/dist/src/marketplace/cache.js +110 -0
  245. package/dist/src/marketplace/identifier.js +63 -0
  246. package/dist/src/marketplace/registry.js +36 -0
  247. package/dist/src/marketplace/sources/clawhub.js +53 -0
  248. package/dist/src/marketplace/sources/git.js +45 -0
  249. package/dist/src/marketplace/types.js +9 -0
  250. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  251. package/dist/src/mcp/cli.mjs +1197 -0
  252. package/dist/src/mcp/elicitation.mjs +149 -0
  253. package/dist/src/mcp/helpers.mjs +287 -0
  254. package/dist/src/mcp/index.mjs +11 -0
  255. package/dist/src/mcp/profiles.js +263 -0
  256. package/dist/src/mcp/profiles.mjs +360 -0
  257. package/dist/src/mcp/registry.js +376 -0
  258. package/dist/src/mcp/registry.mjs +387 -0
  259. package/dist/src/mcp/server.mjs +633 -0
  260. package/dist/src/mcp/test-simple.mjs +271 -0
  261. package/dist/src/mcp/tools/command-run.mjs +101 -0
  262. package/dist/src/mcp/tools/discovery.mjs +291 -0
  263. package/dist/src/mcp/tools/interaction.mjs +87 -0
  264. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  265. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  266. package/dist/src/memory/cli.js +166 -0
  267. package/dist/src/memory/project-registry.js +282 -0
  268. package/dist/src/metrics/artifact-metrics.js +184 -0
  269. package/dist/src/metrics/context-budget.js +174 -0
  270. package/dist/src/metrics/token-counter.js +133 -0
  271. package/dist/src/models/config-loader.js +228 -0
  272. package/dist/src/models/index.js +22 -0
  273. package/dist/src/models/model-capabilities.v1.json +120 -0
  274. package/dist/src/models/model-catalog.v1.json +96 -0
  275. package/dist/src/models/model-discovery.js +521 -0
  276. package/dist/src/models/provider-models.js +73 -0
  277. package/dist/src/models/provider-policy.js +273 -0
  278. package/dist/src/models/resolver.js +245 -0
  279. package/dist/src/models/router.js +70 -0
  280. package/dist/src/models/types.js +8 -0
  281. package/dist/src/models/wrapper-deployment.js +178 -0
  282. package/dist/src/models/wrapper-route.js +54 -0
  283. package/dist/src/ops/cli.js +268 -0
  284. package/dist/src/ops/registry.js +623 -0
  285. package/dist/src/packages/adapters/clawhub.js +113 -0
  286. package/dist/src/packages/adapters/git.js +153 -0
  287. package/dist/src/packages/adapters/gitea.js +93 -0
  288. package/dist/src/packages/adapters/github.js +69 -0
  289. package/dist/src/packages/adapters/local-cache.js +89 -0
  290. package/dist/src/packages/package-registry.js +143 -0
  291. package/dist/src/packages/registry.js +238 -0
  292. package/dist/src/packages/types.js +11 -0
  293. package/dist/src/plugin/cross-framework-ops.js +475 -0
  294. package/dist/src/plugin/framework-config-loader.js +235 -0
  295. package/dist/src/plugin/framework-detector.js +186 -0
  296. package/dist/src/plugin/framework-isolator.js +341 -0
  297. package/dist/src/plugin/framework-migration.js +371 -0
  298. package/dist/src/plugin/metadata-validator.js +906 -0
  299. package/dist/src/plugin/plugin-installer.js +436 -0
  300. package/dist/src/plugin/plugin-status.js +369 -0
  301. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  302. package/dist/src/plugin/registry-validator.js +344 -0
  303. package/dist/src/plugin/skill-command-translator.js +415 -0
  304. package/dist/src/plugin/workspace-creator.js +189 -0
  305. package/dist/src/plugin/workspace-migrator.js +821 -0
  306. package/dist/src/policy/authorization.js +390 -0
  307. package/dist/src/policy/repo-access.js +215 -0
  308. package/dist/src/provenance/cli.js +16 -0
  309. package/dist/src/providers/capability-matrix.js +300 -0
  310. package/dist/src/providers/capability-matrix.yaml +514 -0
  311. package/dist/src/providers/provider-definitions.js +977 -0
  312. package/dist/src/providers/provider-definitions.mjs +159 -0
  313. package/dist/src/providers/provider-inventory.js +169 -0
  314. package/dist/src/quality/feedback-ab.js +174 -0
  315. package/dist/src/quality/feedback-collector.js +176 -0
  316. package/dist/src/quality/feedback-tracker.js +123 -0
  317. package/dist/src/quality/patterns/adr.json +24 -0
  318. package/dist/src/quality/patterns/sad.json +24 -0
  319. package/dist/src/quality/patterns/test-plan.json +24 -0
  320. package/dist/src/quality/patterns/use-case.json +24 -0
  321. package/dist/src/quality/scoring.js +157 -0
  322. package/dist/src/reflections/cli.js +15 -0
  323. package/dist/src/release/plan.js +139 -0
  324. package/dist/src/research/cache/manager.js +227 -0
  325. package/dist/src/research/clients/arxiv.js +156 -0
  326. package/dist/src/research/clients/base.js +197 -0
  327. package/dist/src/research/clients/crossref.js +112 -0
  328. package/dist/src/research/clients/semantic-scholar.js +126 -0
  329. package/dist/src/research/clients/unpaywall.js +87 -0
  330. package/dist/src/research/index.js +14 -0
  331. package/dist/src/research/query-cli.js +336 -0
  332. package/dist/src/research/services/acquisition.js +313 -0
  333. package/dist/src/research/services/archival.js +225 -0
  334. package/dist/src/research/services/citation.js +279 -0
  335. package/dist/src/research/services/discovery.js +243 -0
  336. package/dist/src/research/services/documentation.js +269 -0
  337. package/dist/src/research/services/index.js +14 -0
  338. package/dist/src/research/services/provenance.js +279 -0
  339. package/dist/src/research/services/quality.js +370 -0
  340. package/dist/src/research/services/types.js +7 -0
  341. package/dist/src/research/storage-cli.js +20 -0
  342. package/dist/src/research/types.js +47 -0
  343. package/dist/src/resources/index.d.ts +2 -0
  344. package/dist/src/resources/index.js +2 -0
  345. package/dist/src/resources/web-release.d.ts +89 -0
  346. package/dist/src/resources/web-release.js +882 -0
  347. package/dist/src/rlm/cache/cli.js +162 -0
  348. package/dist/src/rlm/cache/hash.js +35 -0
  349. package/dist/src/rlm/cache/store.js +170 -0
  350. package/dist/src/rlm/cache/types.js +8 -0
  351. package/dist/src/rlm/cli.js +650 -0
  352. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  353. package/dist/src/serve/agent-router.js +205 -0
  354. package/dist/src/serve/dispatch-router.js +171 -0
  355. package/dist/src/serve/executor-registry.js +715 -0
  356. package/dist/src/serve/mission-conductor.js +177 -0
  357. package/dist/src/serve/orchestrator-adapter.js +113 -0
  358. package/dist/src/serve/orchestrator-override.js +94 -0
  359. package/dist/src/serve/orchestrator-pty.js +133 -0
  360. package/dist/src/serve/pty-bridge.js +799 -0
  361. package/dist/src/serve/sandbox-registry.js +832 -0
  362. package/dist/src/serve/screen-reader.js +228 -0
  363. package/dist/src/serve/stack-adapters.js +68 -0
  364. package/dist/src/serve/telemetry.js +143 -0
  365. package/dist/src/skills/adapters/clawhub.js +250 -0
  366. package/dist/src/skills/adapters/local.js +335 -0
  367. package/dist/src/skills/adapters/openclaw.js +316 -0
  368. package/dist/src/skills/cli.js +334 -0
  369. package/dist/src/skills/registry.js +117 -0
  370. package/dist/src/skills/run.js +259 -0
  371. package/dist/src/skills/runtime.js +94 -0
  372. package/dist/src/skills/types.js +10 -0
  373. package/dist/src/smiths/agentsmith/demo.js +116 -0
  374. package/dist/src/smiths/agentsmith/examples.js +300 -0
  375. package/dist/src/smiths/agentsmith/generator.js +503 -0
  376. package/dist/src/smiths/agentsmith/index.js +11 -0
  377. package/dist/src/smiths/agentsmith/types.js +8 -0
  378. package/dist/src/smiths/commandsmith/example.js +220 -0
  379. package/dist/src/smiths/commandsmith/generator.js +288 -0
  380. package/dist/src/smiths/commandsmith/index.js +41 -0
  381. package/dist/src/smiths/commandsmith/templates.js +296 -0
  382. package/dist/src/smiths/commandsmith/types.js +7 -0
  383. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  384. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  385. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  386. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  387. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  388. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  389. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  390. package/dist/src/smiths/context-pipeline/index.js +30 -0
  391. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  392. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  393. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  394. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  395. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  396. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  397. package/dist/src/smiths/context-pipeline/types.js +23 -0
  398. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  399. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  400. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  401. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  402. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  403. package/dist/src/smiths/hook-bridge/index.js +79 -0
  404. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  405. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  406. package/dist/src/smiths/hook-bridge/types.js +31 -0
  407. package/dist/src/smiths/index.js +39 -0
  408. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  409. package/dist/src/smiths/mcpsmith/example.js +119 -0
  410. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  411. package/dist/src/smiths/mcpsmith/index.js +17 -0
  412. package/dist/src/smiths/mcpsmith/types.js +10 -0
  413. package/dist/src/smiths/platform-paths.js +101 -0
  414. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  415. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  416. package/dist/src/smiths/skillsmith/demo.js +83 -0
  417. package/dist/src/smiths/skillsmith/examples.js +161 -0
  418. package/dist/src/smiths/skillsmith/generator.js +316 -0
  419. package/dist/src/smiths/skillsmith/index.js +12 -0
  420. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  421. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  422. package/dist/src/smiths/skillsmith/types.js +9 -0
  423. package/dist/src/smiths/toolsmith/index.js +10 -0
  424. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  425. package/dist/src/smiths/toolsmith/types.js +8 -0
  426. package/dist/src/storage/backends/fortemi.js +227 -0
  427. package/dist/src/storage/backends/fs.js +134 -0
  428. package/dist/src/storage/backends/logseq.js +309 -0
  429. package/dist/src/storage/backends/obsidian.js +233 -0
  430. package/dist/src/storage/cli.js +468 -0
  431. package/dist/src/storage/config.js +272 -0
  432. package/dist/src/storage/index.js +108 -0
  433. package/dist/src/storage/subsystem-cli.js +201 -0
  434. package/dist/src/storage/types.js +33 -0
  435. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  436. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  437. package/dist/src/testing/corpus/index.js +10 -0
  438. package/dist/src/testing/fixtures/index.js +9 -0
  439. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  440. package/dist/src/testing/generators/index.js +11 -0
  441. package/dist/src/testing/generators/test-case-generator.js +393 -0
  442. package/dist/src/testing/generators/test-code-generator.js +384 -0
  443. package/dist/src/testing/generators/use-case-parser.js +325 -0
  444. package/dist/src/testing/index.js +11 -0
  445. package/dist/src/tracker/capability-protocol.js +118 -0
  446. package/dist/src/update/checker.mjs +396 -0
  447. package/dist/src/update/notifier.mjs +235 -0
  448. package/dist/src/writing/content-diversifier.js +804 -0
  449. package/dist/src/writing/example-generator.js +959 -0
  450. package/dist/src/writing/example-templates.js +99 -0
  451. package/dist/src/writing/pattern-library.js +486 -0
  452. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  453. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  454. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  455. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  456. package/dist/src/writing/patterns/transition-words.json +1285 -0
  457. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  458. package/dist/src/writing/prompt-optimizer.js +660 -0
  459. package/dist/src/writing/prompt-templates.js +583 -0
  460. package/dist/src/writing/scoring-config-loader.js +168 -0
  461. package/dist/src/writing/validation-engine.js +595 -0
  462. package/dist/src/writing/validation-rules.js +380 -0
  463. package/dist/src/writing/voice-analyzer.js +439 -0
  464. package/dist/src/writing/voice-calibration.js +661 -0
  465. package/dist/src/writing/voice-profiles.json +588 -0
  466. package/package.json +64 -9
@@ -0,0 +1,202 @@
1
+ /**
2
+ * Corpus integrity / submission-risk scan (#1506). TS-native port of section9
3
+ * `scripts/corpus/llm_artifact_scan.py`.
4
+ *
5
+ * Conservative triage: flags artifacts carrying LLM residue, placeholder/
6
+ * template markers, unresolved citation markers, or non-final experiment
7
+ * language so they get human review before induction/scoring/synthesis. It
8
+ * does NOT decide misconduct. Reports by default; `--quarantine` writes a
9
+ * per-REF report under `.aiwg/research/quarantine/` (source files untouched).
10
+ *
11
+ * The regex catalog is externalized (epic #1496 principle #3): the built-in
12
+ * `DEFAULT_INTEGRITY_PATTERNS` is overridable per-corpus via
13
+ * `documentation/integrity-patterns.yaml`.
14
+ *
15
+ * @source historical: corpus/llm_artifact_scan.py
16
+ * @tests @test/unit/artifacts/integrity-scan.test.ts
17
+ */
18
+ import * as fs from 'fs';
19
+ import * as path from 'path';
20
+ import { load as loadYaml } from 'js-yaml';
21
+ const TEXT_SUFFIXES = new Set(['.md', '.txt', '.tex', '.bib', '.yaml', '.yml', '.html', '.htm']);
22
+ const SKIP_DIRS = new Set(['.git', '__pycache__', 'node_modules']);
23
+ const DEFAULT_TARGET_DIRS = [
24
+ ['documentation', 'references'],
25
+ ['documentation', 'citations'],
26
+ ['documentation', 'radar'],
27
+ ];
28
+ const PATTERNS_FILE = ['documentation', 'integrity-patterns.yaml'];
29
+ /** Built-in pattern catalog. Ports the section9 PATTERNS list. */
30
+ export const DEFAULT_INTEGRITY_PATTERNS = [
31
+ { category: 'llm-meta-comment', severity: 'critical', weight: 35, regex: "\\b(as an ai language model|i cannot|i can(?:not|'t) browse|here is a \\d+\\s+word summary)\\b", description: 'Visible assistant/system meta-comment' },
32
+ { category: 'llm-meta-comment', severity: 'critical', weight: 35, regex: '\\b(would you like me to|let me know if you want|i hope this helps|i have provided)\\b', description: 'Conversational assistant residue' },
33
+ { category: 'placeholder-data', severity: 'critical', weight: 40, regex: '\\b(fill (?:in|this) with (?:the )?real (?:numbers|data|results)|replace with actual|insert actual)\\b', description: 'Explicit instruction to replace fabricated or illustrative data' },
34
+ { category: 'placeholder-data', severity: 'high', weight: 25, regex: '\\b(placeholder|dummy data|sample data|illustrative only|synthetic example values?)\\b', description: 'Placeholder or illustrative data language' },
35
+ { category: 'template-residue', severity: 'high', weight: 25, regex: '(\\[to be filled\\]|\\[todo\\]|\\btodo:\\s*(add|fill|insert|replace)|tbd\\b|xxx)', description: 'Template residue or unfinished TODO marker' },
36
+ { category: 'citation-risk', severity: 'high', weight: 25, regex: '(\\[(citation|reference|source) needed\\]|\\b(citation needed|reference needed|source needed|add citation here)\\b)', description: 'Unresolved citation verification marker' },
37
+ { category: 'experiment-risk', severity: 'high', weight: 25, regex: '\\b(results? (?:are|is) (?:simulated|fabricated|mock|not final)|numbers? (?:are|is) (?:made up|illustrative))\\b', description: 'Experiment or table result is not final/real' },
38
+ { category: 'submission-risk', severity: 'low', weight: 5, regex: '\\b(position paper|survey paper|review article|literature review)\\b', description: 'Content type may need venue/peer-review check before submission' },
39
+ { category: 'ai-disclosure', severity: 'low', weight: 2, regex: '\\b(chatgpt|claude|gemini|copilot|large language model|llm-generated|ai-generated)\\b', description: 'AI/tooling disclosure or generated-content mention' },
40
+ ];
41
+ /** Load the pattern catalog (corpus override → built-in default), compiled. */
42
+ export function loadIntegrityPatterns(root) {
43
+ let patterns = DEFAULT_INTEGRITY_PATTERNS;
44
+ const file = path.join(root, ...PATTERNS_FILE);
45
+ if (fs.existsSync(file)) {
46
+ try {
47
+ const raw = loadYaml(fs.readFileSync(file, 'utf-8'));
48
+ if (Array.isArray(raw) && raw.length)
49
+ patterns = raw;
50
+ }
51
+ catch {
52
+ /* malformed override → fall back to defaults */
53
+ }
54
+ }
55
+ return patterns.map((p) => ({ ...p, re: new RegExp(p.regex, 'i') }));
56
+ }
57
+ const SEVERITY_RANK = { none: 0, low: 1, medium: 2, high: 3, critical: 4 };
58
+ function refFromPath(p) {
59
+ const m = p.match(/REF-\d{3,}[a-z]?/);
60
+ return m ? m[0] : 'NO-REF';
61
+ }
62
+ function excerpt(line, limit = 220) {
63
+ const compact = line.trim().split(/\s+/).join(' ');
64
+ return compact.length <= limit ? compact : compact.slice(0, limit - 3) + '...';
65
+ }
66
+ function* iterFiles(targets) {
67
+ for (const target of targets) {
68
+ if (!fs.existsSync(target))
69
+ continue;
70
+ const stat = fs.statSync(target);
71
+ if (stat.isFile()) {
72
+ if (TEXT_SUFFIXES.has(path.extname(target).toLowerCase()))
73
+ yield target;
74
+ continue;
75
+ }
76
+ const stack = [target];
77
+ while (stack.length) {
78
+ const dir = stack.pop();
79
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
80
+ if (entry.isDirectory()) {
81
+ if (!SKIP_DIRS.has(entry.name))
82
+ stack.push(path.join(dir, entry.name));
83
+ }
84
+ else if (TEXT_SUFFIXES.has(path.extname(entry.name).toLowerCase())) {
85
+ yield path.join(dir, entry.name);
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ function scanFile(root, file, patterns) {
92
+ const findings = [];
93
+ const ref = refFromPath(file);
94
+ const rel = path.relative(root, file);
95
+ let lines;
96
+ try {
97
+ lines = fs.readFileSync(file, 'utf-8').split('\n');
98
+ }
99
+ catch (e) {
100
+ return [{ ref, path: rel, line: 0, category: 'read-error', severity: 'high', weight: 20, description: `Could not read file: ${String(e)}`, excerpt: '' }];
101
+ }
102
+ for (let i = 0; i < lines.length; i++) {
103
+ for (const p of patterns) {
104
+ if (p.re.test(lines[i])) {
105
+ findings.push({ ref, path: rel, line: i + 1, category: p.category, severity: p.severity, weight: p.weight, description: p.description, excerpt: excerpt(lines[i]) });
106
+ }
107
+ }
108
+ }
109
+ return findings;
110
+ }
111
+ function recommendation(score, highest) {
112
+ if (highest === 'critical')
113
+ return 'quarantine';
114
+ if (score >= 50 && SEVERITY_RANK[highest] >= SEVERITY_RANK.high)
115
+ return 'quarantine';
116
+ if (score >= 20 || SEVERITY_RANK[highest] >= SEVERITY_RANK.high)
117
+ return 'review';
118
+ return 'pass';
119
+ }
120
+ function scoreFindings(findings) {
121
+ const byRef = {};
122
+ for (const f of findings) {
123
+ const rec = (byRef[f.ref] ??= { ref: f.ref, score: 0, highestSeverity: 'none', findingCount: 0, categories: {}, recommendation: 'pass' });
124
+ rec.score += f.weight;
125
+ rec.findingCount += 1;
126
+ rec.categories[f.category] = (rec.categories[f.category] ?? 0) + 1;
127
+ if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[rec.highestSeverity])
128
+ rec.highestSeverity = f.severity;
129
+ }
130
+ for (const rec of Object.values(byRef)) {
131
+ rec.score = Math.min(100, rec.score);
132
+ rec.recommendation = recommendation(rec.score, rec.highestSeverity);
133
+ }
134
+ return byRef;
135
+ }
136
+ export function scanCorpus(root, opts = {}) {
137
+ const patterns = loadIntegrityPatterns(root);
138
+ const targets = opts.targets && opts.targets.length
139
+ ? opts.targets.map((t) => (path.isAbsolute(t) ? t : path.join(root, t)))
140
+ : DEFAULT_TARGET_DIRS.map((parts) => path.join(root, ...parts));
141
+ const findings = [];
142
+ for (const file of iterFiles(targets)) {
143
+ if (opts.ref && !file.includes(opts.ref))
144
+ continue;
145
+ findings.push(...scanFile(root, file, patterns));
146
+ }
147
+ return { findings, summary: scoreFindings(findings) };
148
+ }
149
+ export function renderScan(result) {
150
+ const out = [];
151
+ out.push('LLM Artifact / Integrity Scan');
152
+ out.push(`Findings: ${result.findings.length}`);
153
+ const recs = Object.values(result.summary);
154
+ out.push(`REFs flagged: ${recs.length}`);
155
+ out.push('');
156
+ if (!recs.length) {
157
+ out.push('No suspect patterns found.');
158
+ return out.join('\n') + '\n';
159
+ }
160
+ out.push(`${'REF'.padEnd(12)} ${'score'.padEnd(6)} ${'severity'.padEnd(10)} ${'rec'.padEnd(11)} findings categories`);
161
+ for (const rec of recs.sort((a, b) => b.score - a.score || a.ref.localeCompare(b.ref))) {
162
+ const cats = Object.entries(rec.categories).sort().map(([k, v]) => `${k}=${v}`).join(', ');
163
+ out.push(`${rec.ref.padEnd(12)} ${String(rec.score).padEnd(6)} ${rec.highestSeverity.padEnd(10)} ${rec.recommendation.padEnd(11)} ${String(rec.findingCount).padEnd(8)} ${cats}`);
164
+ }
165
+ return out.join('\n') + '\n';
166
+ }
167
+ /** Write per-REF quarantine reports for `quarantine`-recommended REFs. Returns relative paths written. */
168
+ export function writeQuarantineReports(root, result) {
169
+ const dir = path.join(root, '.aiwg', 'research', 'quarantine');
170
+ const byRef = {};
171
+ for (const f of result.findings)
172
+ (byRef[f.ref] ??= []).push(f);
173
+ const written = [];
174
+ for (const rec of Object.values(result.summary).sort((a, b) => a.ref.localeCompare(b.ref))) {
175
+ if (rec.recommendation !== 'quarantine')
176
+ continue;
177
+ fs.mkdirSync(dir, { recursive: true });
178
+ const lines = [
179
+ '---', `ref: ${rec.ref}`, 'type: llm-artifact-scan', `score: ${rec.score}`,
180
+ `highest-severity: ${rec.highestSeverity}`, `recommendation: ${rec.recommendation}`, '---', '',
181
+ `# ${rec.ref} LLM Artifact Scan`, '',
182
+ 'Triage artifact (possible LLM residue / placeholders / submission risk) — not a misconduct determination.', '',
183
+ '## Summary', '',
184
+ `- Score: ${rec.score}/100`, `- Highest severity: ${rec.highestSeverity}`,
185
+ `- Findings: ${rec.findingCount}`, `- Recommendation: ${rec.recommendation}`, '',
186
+ '## Findings', '', '| Severity | Category | File | Line | Excerpt |', '|---|---|---|---:|---|',
187
+ ];
188
+ for (const f of byRef[rec.ref] ?? []) {
189
+ lines.push(`| ${f.severity} | ${f.category} | ${f.path} | ${f.line} | ${f.excerpt.replace(/\|/g, '\\|')} |`);
190
+ }
191
+ lines.push('', '## Required Triage', '', '- Confirm each finding is source-authored text, OCR noise, or generated-note residue.', '- Source-authored residue → downgrade trust/grade until externally verified.', '- Generated-note residue → fix the note and rerun the scan.', '- Do not use this REF in synthesis until the quarantine recommendation clears.');
192
+ const file = path.join(dir, `${rec.ref}-llm-artifact-scan.md`);
193
+ fs.writeFileSync(file, lines.join('\n') + '\n');
194
+ written.push(path.relative(root, file));
195
+ }
196
+ return written;
197
+ }
198
+ /** True if any REF reaches the fail threshold (quarantine, or review+quarantine when threshold=review). */
199
+ export function failsThreshold(result, threshold) {
200
+ return Object.values(result.summary).some((r) => r.recommendation === threshold || (threshold === 'review' && r.recommendation === 'quarantine'));
201
+ }
202
+ //# sourceMappingURL=integrity-scan.js.map
@@ -0,0 +1,166 @@
1
+ /**
2
+ * profile-communities — co-author community detection (#1501).
3
+ *
4
+ * Label-propagation communities (deterministic variant: sorted node order,
5
+ * lexicographic tie-break — no python-louvain dependency, the graceful fallback
6
+ * the issue calls for) + modularity Q + bridge-node detection (high betweenness).
7
+ *
8
+ * @source historical: profiles/community_detection.py
9
+ */
10
+ import { loadCorpus } from '../corpus-views/ref-parser.js';
11
+ import { buildCoauthorGraph, betweenness } from './corpus-graph.js';
12
+ /** Deterministic label propagation: each node adopts the highest-weight neighbour label. */
13
+ function labelPropagation(g, maxIter = 100) {
14
+ const nodes = [...g.keys()].sort();
15
+ const labels = new Map(nodes.map((n) => [n, n]));
16
+ for (let iter = 0; iter < maxIter; iter++) {
17
+ let changed = false;
18
+ for (const v of nodes) {
19
+ const nbrs = g.get(v);
20
+ if (nbrs.size === 0)
21
+ continue;
22
+ const weight = new Map();
23
+ for (const [w, ew] of nbrs) {
24
+ const lab = labels.get(w);
25
+ weight.set(lab, (weight.get(lab) ?? 0) + ew);
26
+ }
27
+ // Highest weight; tie-break to the lexicographically smallest label.
28
+ let best = labels.get(v);
29
+ let bestW = -1;
30
+ for (const [lab, wgt] of [...weight.entries()].sort((a, b) => (a[0] < b[0] ? -1 : 1))) {
31
+ if (wgt > bestW) {
32
+ bestW = wgt;
33
+ best = lab;
34
+ }
35
+ }
36
+ if (best !== labels.get(v)) {
37
+ labels.set(v, best);
38
+ changed = true;
39
+ }
40
+ }
41
+ if (!changed)
42
+ break;
43
+ }
44
+ return labels;
45
+ }
46
+ /** Newman modularity Q for a labelled undirected weighted graph. */
47
+ function modularity(g, labels) {
48
+ const deg = new Map();
49
+ let twoM = 0;
50
+ for (const [v, nbrs] of g) {
51
+ let d = 0;
52
+ for (const w of nbrs.values())
53
+ d += w;
54
+ deg.set(v, d);
55
+ twoM += d;
56
+ }
57
+ if (twoM === 0)
58
+ return 0;
59
+ const nodes = [...g.keys()];
60
+ let q = 0;
61
+ for (const i of nodes) {
62
+ const nbrs = g.get(i);
63
+ for (const j of nodes) {
64
+ if (labels.get(i) !== labels.get(j))
65
+ continue;
66
+ const a = nbrs.get(j) ?? 0;
67
+ q += a - (deg.get(i) * deg.get(j)) / twoM;
68
+ }
69
+ }
70
+ return Math.round((q / twoM) * 1e4) / 1e4;
71
+ }
72
+ /** Detect co-author communities + modularity + bridge nodes. */
73
+ export function detectCommunities(corpusRoot, minModularity = 0.3) {
74
+ const { records } = loadCorpus(corpusRoot);
75
+ const g = buildCoauthorGraph(records);
76
+ const labels = labelPropagation(g);
77
+ const byLabel = new Map();
78
+ for (const [node, lab] of labels)
79
+ (byLabel.get(lab) ?? byLabel.set(lab, []).get(lab)).push(node);
80
+ const communities = [...byLabel.entries()]
81
+ .map(([label, members]) => ({ label, members: members.sort() }))
82
+ .sort((a, b) => b.members.length - a.members.length);
83
+ const q = modularity(g, labels);
84
+ // Bridge nodes: top betweenness (span communities).
85
+ const bc = betweenness(g);
86
+ const bridges = [...bc.entries()]
87
+ .filter(([, v]) => v > 0)
88
+ .sort((a, b) => b[1] - a[1])
89
+ .slice(0, 10)
90
+ .map(([node, v]) => ({ node, betweenness: Math.round(v * 1e6) / 1e6 }));
91
+ const result = { communities, modularity: q, bridges };
92
+ if (q < minModularity)
93
+ result.warning = `modularity ${q} < ${minModularity} — weak community structure (sparse co-author graph)`;
94
+ return result;
95
+ }
96
+ /** Render communities + modularity + bridges as markdown. */
97
+ export function renderCommunities(r) {
98
+ const lines = [
99
+ '# Co-author communities',
100
+ '',
101
+ `${r.communities.length} communities · modularity Q = ${r.modularity}`,
102
+ ...(r.warning ? ['', `> ⚠ ${r.warning}`] : []),
103
+ '',
104
+ '| Community | Size | Members (top 8) |',
105
+ '|---|---:|---|',
106
+ ];
107
+ let i = 1;
108
+ for (const c of r.communities) {
109
+ if (c.members.length < 2)
110
+ continue; // skip singletons in the table
111
+ lines.push(`| C${i++} | ${c.members.length} | ${c.members.slice(0, 8).join(', ')}${c.members.length > 8 ? ' …' : ''} |`);
112
+ }
113
+ lines.push('', '## Bridge authors (top betweenness)', '', '| Author | Betweenness |', '|---|---:|');
114
+ for (const b of r.bridges)
115
+ lines.push(`| ${b.node} | ${b.betweenness} |`);
116
+ return lines.join('\n') + '\n';
117
+ }
118
+ /** Group Fortemi v2 records by extracted SKOS concept id/prefLabel (#1720). */
119
+ export function detectSkosCommunities(exported) {
120
+ const labels = new Map();
121
+ const membersByConcept = new Map();
122
+ let recordsWithConcepts = 0;
123
+ for (const item of exported.items) {
124
+ const concepts = item.skos_concepts ?? [];
125
+ if (concepts.length > 0)
126
+ recordsWithConcepts++;
127
+ const member = item.title || item.name || item.source.path;
128
+ for (const concept of concepts) {
129
+ labels.set(concept.id, concept.prefLabel);
130
+ if (!membersByConcept.has(concept.id))
131
+ membersByConcept.set(concept.id, new Set());
132
+ membersByConcept.get(concept.id).add(member);
133
+ }
134
+ }
135
+ const communities = [...membersByConcept.entries()]
136
+ .map(([id, members]) => ({
137
+ label: labels.get(id) ?? id,
138
+ members: [...members].sort(),
139
+ }))
140
+ .sort((a, b) => b.members.length - a.members.length || a.label.localeCompare(b.label));
141
+ return {
142
+ communities,
143
+ coverage: {
144
+ recordsWithConcepts,
145
+ totalRecords: exported.items.length,
146
+ ratio: exported.items.length === 0
147
+ ? 1
148
+ : Math.round((recordsWithConcepts / exported.items.length) * 10000) / 10000,
149
+ },
150
+ };
151
+ }
152
+ export function renderSkosCommunities(r) {
153
+ const lines = [
154
+ '# SKOS concept communities',
155
+ '',
156
+ `${r.communities.length} concepts · SKOS coverage ${r.coverage.recordsWithConcepts}/${r.coverage.totalRecords} (${r.coverage.ratio})`,
157
+ '',
158
+ '| Concept | Size | Records (top 8) |',
159
+ '|---|---:|---|',
160
+ ];
161
+ for (const c of r.communities) {
162
+ lines.push(`| ${c.label} | ${c.members.length} | ${c.members.slice(0, 8).join(', ')}${c.members.length > 8 ? ' …' : ''} |`);
163
+ }
164
+ return lines.join('\n') + '\n';
165
+ }
166
+ //# sourceMappingURL=profile-communities.js.map
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Profile→REF edges as first-class graph data (#1501, reassigned from #1502).
3
+ *
4
+ * TS-native port of section9 `scripts/profiles/build_profile_edges.py`. Builds
5
+ * the entity-profile → reference edge graph from `loadProfiles` (PROF-{P,O,G,F,S}
6
+ * `corpus-refs`), reconciled against the citation graph so only edges to REFs
7
+ * that actually exist in the corpus are kept (the source script emitted synthetic
8
+ * `documentation/profiles/edges/` files; per the issue these are first-class
9
+ * graph adjacency objects instead, reconcilable with the #727 graph backends).
10
+ *
11
+ * @source historical: profiles/build_profile_edges.py
12
+ * @tests @test/unit/artifacts/profile-edges.test.ts
13
+ */
14
+ import { loadProfiles, loadCorpus } from '../corpus-views/ref-parser.js';
15
+ /** Build the profile→REF edge graph, keeping only edges to REFs present in the corpus. */
16
+ export function buildProfileEdges(corpusRoot) {
17
+ const profiles = loadProfiles(corpusRoot);
18
+ const knownRefs = new Set(loadCorpus(corpusRoot).records.map((r) => r.refId));
19
+ const edges = [];
20
+ const byProfile = new Map();
21
+ const byRef = new Map();
22
+ const danglingRefs = [];
23
+ for (const p of profiles) {
24
+ const type = p.type ?? 'unknown';
25
+ const refs = [];
26
+ for (const ref of p.corpusRefs) {
27
+ if (!knownRefs.has(ref)) {
28
+ danglingRefs.push({ profId: p.profId, ref });
29
+ continue;
30
+ }
31
+ edges.push({ profId: p.profId, profileType: type, ref });
32
+ refs.push(ref);
33
+ (byRef.get(ref) ?? byRef.set(ref, []).get(ref)).push(p.profId);
34
+ }
35
+ byProfile.set(p.profId, { name: p.name, type, refs });
36
+ }
37
+ return {
38
+ edges,
39
+ byProfile,
40
+ byRef,
41
+ danglingRefs,
42
+ stats: { profiles: profiles.length, edges: edges.length, refsCovered: byRef.size },
43
+ };
44
+ }
45
+ export function renderProfileEdges(g) {
46
+ const out = [];
47
+ out.push('Profile→REF edge graph');
48
+ out.push(`Profiles: ${g.stats.profiles} Edges: ${g.stats.edges} REFs covered: ${g.stats.refsCovered} Dangling: ${g.danglingRefs.length}`);
49
+ out.push('');
50
+ // Top profiles by edge count.
51
+ const topProfiles = [...g.byProfile.entries()].sort((a, b) => b[1].refs.length - a[1].refs.length).slice(0, 15);
52
+ out.push('Top profiles by linked REFs:');
53
+ for (const [profId, info] of topProfiles) {
54
+ if (!info.refs.length)
55
+ continue;
56
+ out.push(` ${profId} (${info.type})${info.name ? ` — ${info.name}` : ''}: ${info.refs.length}`);
57
+ }
58
+ out.push('');
59
+ // Top REFs by profile in-degree.
60
+ const topRefs = [...g.byRef.entries()].sort((a, b) => b[1].length - a[1].length).slice(0, 15);
61
+ out.push('Top REFs by linked-profile count:');
62
+ for (const [ref, profs] of topRefs)
63
+ out.push(` ${ref}: ${profs.length} profiles`);
64
+ if (g.danglingRefs.length) {
65
+ out.push('');
66
+ out.push(`Dangling profile→REF edges (REF doc missing): ${g.danglingRefs.length}`);
67
+ for (const d of g.danglingRefs.slice(0, 10))
68
+ out.push(` ${d.profId} → ${d.ref}`);
69
+ }
70
+ return out.join('\n') + '\n';
71
+ }
72
+ //# sourceMappingURL=profile-edges.js.map
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Profile text embeddings → researcher similarity + collaboration prediction (#1501).
3
+ *
4
+ * The #1501 "node2vec embeddings" slot, implemented (per operator decision) by
5
+ * reusing the text-embedding backend (#1493) instead of a heavy graph-embedding
6
+ * stack: each person profile is embedded from its name + the titles of its
7
+ * corpus-refs, then cosine similarity gives nearest researchers and
8
+ * collaboration link-prediction (highly-similar people who have NOT co-authored —
9
+ * corpus-refs overlap is the co-authorship proxy).
10
+ *
11
+ * Opt-in: requires `@xenova/transformers` (and `hnswlib-node` is not needed here —
12
+ * similarity is an in-memory cosine over the ~hundreds of person profiles).
13
+ * Degrades gracefully when the optional dep is absent.
14
+ *
15
+ * @source historical: profiles/graph_embeddings.py (node2vec → text-embedding here)
16
+ * @tests @test/unit/artifacts/profile-embed.test.ts
17
+ */
18
+ import { loadProfiles, loadCorpus } from '../corpus-views/ref-parser.js';
19
+ import { checkEmbeddingDeps, DEFAULT_EMBEDDING_MODEL } from '../embedding-index.js';
20
+ function cosine(a, b) {
21
+ let dot = 0;
22
+ // Vectors are L2-normalized at embed time (normalize: true), so dot == cosine.
23
+ for (let i = 0; i < a.length; i++)
24
+ dot += a[i] * b[i];
25
+ return dot;
26
+ }
27
+ /**
28
+ * Build text embeddings for person profiles. Text = profile name + the titles of
29
+ * its corpus-refs. Requires `@xenova/transformers`; throws a clear error when absent.
30
+ */
31
+ export async function buildProfileEmbeddings(corpusRoot, model = DEFAULT_EMBEDDING_MODEL) {
32
+ const deps = await checkEmbeddingDeps();
33
+ if (!deps.available) {
34
+ throw new Error(`profile embeddings need optional deps: ${deps.missing.join(', ')} (npm install @xenova/transformers)`);
35
+ }
36
+ const titleByRef = new Map();
37
+ for (const r of loadCorpus(corpusRoot).records)
38
+ titleByRef.set(r.refId, r.title);
39
+ const people = loadProfiles(corpusRoot).filter((p) => (p.type ?? '') === 'person');
40
+ const profIds = [];
41
+ const names = [];
42
+ const texts = [];
43
+ const refs = [];
44
+ for (const p of people) {
45
+ const titles = p.corpusRefs.map((r) => titleByRef.get(r)).filter(Boolean);
46
+ // Skip profiles with no usable text signal.
47
+ const text = `${p.name ?? p.profId}. ${titles.join('. ')}`.trim();
48
+ if (!titles.length && !p.name)
49
+ continue;
50
+ profIds.push(p.profId);
51
+ names.push(p.name);
52
+ texts.push(text);
53
+ refs.push(new Set(p.corpusRefs));
54
+ }
55
+ const transformersMod = await (new Function('m', 'return import(m)'))('@xenova/transformers');
56
+ const embed = await transformersMod.pipeline('feature-extraction', model);
57
+ const vectors = [];
58
+ for (const t of texts) {
59
+ const res = await embed(t, { pooling: 'mean', normalize: true });
60
+ vectors.push(Array.from(res.data));
61
+ }
62
+ return { profIds, names, vectors, refs };
63
+ }
64
+ /** Nearest researchers to a profile by embedding cosine (excludes self). */
65
+ export function profileSimilar(emb, profId, topK = 10) {
66
+ const i = emb.profIds.indexOf(profId);
67
+ if (i === -1)
68
+ throw new Error(`profile '${profId}' not in the embedding set`);
69
+ const hits = [];
70
+ for (let j = 0; j < emb.profIds.length; j++) {
71
+ if (j === i)
72
+ continue;
73
+ hits.push({ profId: emb.profIds[j], name: emb.names[j], score: cosine(emb.vectors[i], emb.vectors[j]) });
74
+ }
75
+ return hits.sort((a, b) => b.score - a.score).slice(0, topK);
76
+ }
77
+ /**
78
+ * Collaboration link-prediction: pairs of people with embedding similarity ≥
79
+ * threshold who share NO corpus-refs (i.e. have not co-authored). Ranked desc.
80
+ */
81
+ export function collaborationPredictions(emb, threshold = 0.8, limit = 50) {
82
+ const preds = [];
83
+ for (let i = 0; i < emb.profIds.length; i++) {
84
+ for (let j = i + 1; j < emb.profIds.length; j++) {
85
+ // Already co-authored if their corpus-refs intersect.
86
+ let shared = false;
87
+ for (const r of emb.refs[i])
88
+ if (emb.refs[j].has(r)) {
89
+ shared = true;
90
+ break;
91
+ }
92
+ if (shared)
93
+ continue;
94
+ const score = cosine(emb.vectors[i], emb.vectors[j]);
95
+ if (score >= threshold)
96
+ preds.push({ a: emb.profIds[i], b: emb.profIds[j], score });
97
+ }
98
+ }
99
+ return preds.sort((x, y) => y.score - x.score).slice(0, limit);
100
+ }
101
+ export function renderSimilar(profId, hits) {
102
+ const out = [`Researchers similar to ${profId} (${hits.length}):`, ''];
103
+ for (const h of hits)
104
+ out.push(` ${h.score.toFixed(3)} ${h.profId}${h.name ? ` — ${h.name}` : ''}`);
105
+ return out.join('\n') + '\n';
106
+ }
107
+ export function renderCollabPredictions(preds, threshold) {
108
+ const out = [`Collaboration predictions (cosine ≥ ${threshold}, not yet co-authored): ${preds.length}`, ''];
109
+ for (const p of preds)
110
+ out.push(` ${p.score.toFixed(3)} ${p.a} ↔ ${p.b}`);
111
+ return out.join('\n') + '\n';
112
+ }
113
+ //# sourceMappingURL=profile-embed.js.map