@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,127 @@
1
+ /**
2
+ * Per-user AIWG registry — `~/.aiwg/installed.json` (#1156 Phase 1).
3
+ *
4
+ * Tracks frameworks/addons deployed at user scope (`aiwg use --scope user`).
5
+ * Operationally distinct from the project-level `.aiwg/aiwg.config`:
6
+ *
7
+ * project: .aiwg/aiwg.config — installed.{name}
8
+ * user: ~/.aiwg/installed.json — installed.{name}.deployedTo.{provider}
9
+ *
10
+ * Same shape as `AiwgConfig.installed` so existing helpers can be lifted with
11
+ * minimal change. The user registry exists outside any project so `aiwg list
12
+ * --scope user` works from any cwd.
13
+ */
14
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
15
+ import { existsSync } from 'node:fs';
16
+ import { dirname } from 'node:path';
17
+ import { userScopeConfigPath } from '../cli/scope-resolver.js';
18
+ /**
19
+ * Path to ~/.aiwg/installed.json. Distinct from `userScopeConfigPath()`
20
+ * (which points at ~/.aiwg/aiwg.config and is reserved for future user-level
21
+ * config that mirrors the project aiwg.config structure).
22
+ *
23
+ * Honors `AIWG_USER_REGISTRY_PATH` for test isolation: setting that env var
24
+ * redirects all reads/writes to the supplied path. Production code should
25
+ * never set this — it exists so the test suite can avoid clobbering the real
26
+ * `~/.aiwg/installed.json` on the developer's machine.
27
+ */
28
+ export function userRegistryPath() {
29
+ const override = process.env.AIWG_USER_REGISTRY_PATH;
30
+ if (override)
31
+ return override;
32
+ // Reuse the directory portion of userScopeConfigPath() to stay consistent
33
+ // with the documented user-scope convention from ADR-4.
34
+ return dirname(userScopeConfigPath()) + '/installed.json';
35
+ }
36
+ export function emptyUserRegistry() {
37
+ return { version: '1', installed: {} };
38
+ }
39
+ /**
40
+ * Read the per-user registry. Returns an empty registry when the file doesn't
41
+ * exist — that's the normal case before the operator's first `aiwg use --scope
42
+ * user`. On parse failure returns the empty registry and writes a stderr
43
+ * warning (the broken file is preserved so the operator can inspect it).
44
+ */
45
+ export async function readUserRegistry() {
46
+ const path = userRegistryPath();
47
+ if (!existsSync(path))
48
+ return emptyUserRegistry();
49
+ try {
50
+ const raw = await readFile(path, 'utf-8');
51
+ const parsed = JSON.parse(raw);
52
+ if (!parsed.installed || typeof parsed.installed !== 'object') {
53
+ return emptyUserRegistry();
54
+ }
55
+ return { version: '1', installed: parsed.installed };
56
+ }
57
+ catch (err) {
58
+ process.stderr.write(`[user-registry] failed to parse ${path}: ${err instanceof Error ? err.message : String(err)} — using empty registry\n`);
59
+ return emptyUserRegistry();
60
+ }
61
+ }
62
+ /**
63
+ * Persist the user registry. Creates the parent directory if missing.
64
+ */
65
+ export async function writeUserRegistry(registry) {
66
+ const path = userRegistryPath();
67
+ await mkdir(dirname(path), { recursive: true });
68
+ await writeFile(path, JSON.stringify(registry, null, 2) + '\n', 'utf-8');
69
+ }
70
+ /**
71
+ * Record a successful user-scope deploy. Idempotent — re-running `aiwg use
72
+ * --scope user` for the same framework+provider overwrites the prior entry's
73
+ * counts, entries, and timestamp.
74
+ *
75
+ * Mutates the passed registry in place AND writes it to disk so callers don't
76
+ * have to manage the persistence dance themselves.
77
+ *
78
+ * `entries` (optional) records the actual artifact names this deploy
79
+ * mirrored, enabling precise remove later.
80
+ */
81
+ export async function recordUserDeploy(opts) {
82
+ const registry = await readUserRegistry();
83
+ const existing = registry.installed[opts.framework];
84
+ const deployedTo = existing?.deployedTo ?? {};
85
+ // Merge the new counts with the optional entries snapshot. Cast through
86
+ // UserScopeProviderDeploy so the registry can carry the richer shape.
87
+ const merged = { ...opts.counts };
88
+ if (opts.entries)
89
+ merged.entries = opts.entries;
90
+ deployedTo[opts.provider] = merged;
91
+ registry.installed[opts.framework] = {
92
+ version: opts.version,
93
+ source: opts.source,
94
+ installedAt: new Date().toISOString(),
95
+ deployedTo,
96
+ manifestHash: opts.manifestHash,
97
+ };
98
+ await writeUserRegistry(registry);
99
+ return registry;
100
+ }
101
+ /**
102
+ * Remove a framework's user-scope deploy from the registry. If `provider` is
103
+ * specified, removes only that provider's entry; the framework entry stays if
104
+ * other providers remain. Without `provider`, removes the framework entirely.
105
+ *
106
+ * Returns the updated registry. The caller is responsible for the actual
107
+ * filesystem revert (deleting the mirrored artifacts) — this only updates the
108
+ * bookkeeping.
109
+ */
110
+ export async function removeUserDeploy(opts) {
111
+ const registry = await readUserRegistry();
112
+ const entry = registry.installed[opts.framework];
113
+ if (!entry)
114
+ return registry;
115
+ if (opts.provider) {
116
+ delete entry.deployedTo[opts.provider];
117
+ if (Object.keys(entry.deployedTo).length === 0) {
118
+ delete registry.installed[opts.framework];
119
+ }
120
+ }
121
+ else {
122
+ delete registry.installed[opts.framework];
123
+ }
124
+ await writeUserRegistry(registry);
125
+ return registry;
126
+ }
127
+ //# sourceMappingURL=user-registry.js.map
@@ -0,0 +1,276 @@
1
+ /**
2
+ * General workspace-of-repositories resolution.
3
+ *
4
+ * A workspace root declares members in its `.aiwg/aiwg.config`. Every member
5
+ * keeps its own `.aiwg/aiwg.config`; that member config is authoritative for
6
+ * delivery, remotes, tracker actor, and signing. Workspace capabilities are an
7
+ * additional deny-by-default authorization layer.
8
+ *
9
+ * @implements #1764
10
+ */
11
+ import { execFile } from 'child_process';
12
+ import { existsSync, statSync } from 'fs';
13
+ import { homedir } from 'os';
14
+ import { dirname, isAbsolute, relative, resolve } from 'path';
15
+ import { promisify } from 'util';
16
+ import { getConfigPath, readAiwgConfig, resolveDelivery, resolveRemoteProvider, resolveRemotes, } from './aiwg-config.js';
17
+ const execFileAsync = promisify(execFile);
18
+ function expandHome(value) {
19
+ if (value === '~')
20
+ return homedir();
21
+ if (value.startsWith('~/') || value.startsWith('~\\')) {
22
+ return resolve(homedir(), value.slice(2));
23
+ }
24
+ return value;
25
+ }
26
+ function asDirectory(value) {
27
+ const absolute = resolve(value);
28
+ try {
29
+ return statSync(absolute).isDirectory() ? absolute : dirname(absolute);
30
+ }
31
+ catch {
32
+ return absolute;
33
+ }
34
+ }
35
+ function isSameOrInside(candidate, root) {
36
+ const rel = relative(root, candidate);
37
+ return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
38
+ }
39
+ function resolveFrom(base, value) {
40
+ const expanded = expandHome(value);
41
+ return isAbsolute(expanded) ? resolve(expanded) : resolve(base, expanded);
42
+ }
43
+ /**
44
+ * Find the workspace root that governs `startPath`.
45
+ *
46
+ * Child members discover an ancestor workspace naturally. External members
47
+ * can set `workspace.member_of`, or callers can set AIWG_WORKSPACE / pass an
48
+ * explicit workspace root.
49
+ */
50
+ export async function findWorkspaceProjectRoot(startPath = process.cwd(), explicitWorkspace) {
51
+ const override = explicitWorkspace ?? process.env.AIWG_WORKSPACE;
52
+ if (override) {
53
+ const projectRoot = asDirectory(expandHome(override));
54
+ const config = await readAiwgConfig(projectRoot);
55
+ if (!config?.repos) {
56
+ throw new Error(`Workspace config at ${getConfigPath(projectRoot)} does not declare repos`);
57
+ }
58
+ return projectRoot;
59
+ }
60
+ let current = asDirectory(startPath);
61
+ while (true) {
62
+ if (existsSync(getConfigPath(current))) {
63
+ const config = await readAiwgConfig(current);
64
+ if (config?.repos)
65
+ return current;
66
+ if (config?.workspace?.member_of) {
67
+ const projectRoot = resolveFrom(current, config.workspace.member_of);
68
+ const workspaceConfig = await readAiwgConfig(projectRoot);
69
+ if (!workspaceConfig?.repos) {
70
+ throw new Error(`workspace.member_of resolves to ${projectRoot}, but its .aiwg/aiwg.config does not declare repos`);
71
+ }
72
+ return projectRoot;
73
+ }
74
+ }
75
+ const parent = dirname(current);
76
+ if (parent === current)
77
+ return null;
78
+ current = parent;
79
+ }
80
+ }
81
+ function remoteDomain(remoteUrl) {
82
+ if (!remoteUrl)
83
+ return undefined;
84
+ const scp = remoteUrl.match(/^[^@/\s]+@([^:/\s]+):/);
85
+ if (scp?.[1])
86
+ return scp[1].toLowerCase();
87
+ try {
88
+ const parsed = new URL(remoteUrl);
89
+ return parsed.hostname.toLowerCase() || undefined;
90
+ }
91
+ catch {
92
+ return undefined;
93
+ }
94
+ }
95
+ async function readRemoteUrl(repoPath, remote) {
96
+ if (remote.includes('://') || /^[^@/\s]+@[^:/\s]+:/.test(remote))
97
+ return remote;
98
+ try {
99
+ const { stdout } = await execFileAsync('git', ['-C', repoPath, 'remote', 'get-url', remote], { encoding: 'utf8' });
100
+ return stdout.trim() || undefined;
101
+ }
102
+ catch {
103
+ return undefined;
104
+ }
105
+ }
106
+ async function resolveEndpoint(repoPath, remote, providerHint) {
107
+ const url = await readRemoteUrl(repoPath, remote);
108
+ const detected = resolveRemoteProvider(url ?? '');
109
+ const provider = detected === 'unknown' && providerHint ? providerHint : detected;
110
+ return {
111
+ name: remote,
112
+ ...(url ? { url } : {}),
113
+ provider,
114
+ ...(remoteDomain(url) ? { domain: remoteDomain(url) } : {}),
115
+ providerSource: detected !== 'unknown'
116
+ ? 'remote'
117
+ : providerHint
118
+ ? 'manifest-hint'
119
+ : 'unknown',
120
+ };
121
+ }
122
+ async function resolveMember(entry, workspaceRoot) {
123
+ const memberPath = resolveFrom(workspaceRoot, entry.path);
124
+ const configPath = getConfigPath(memberPath);
125
+ const config = await readAiwgConfig(memberPath);
126
+ const remotes = resolveRemotes(config?.remotes);
127
+ const [primary, issueTracker, ci] = await Promise.all([
128
+ resolveEndpoint(memberPath, remotes.primary, entry.provider),
129
+ resolveEndpoint(memberPath, remotes.issue_tracker, entry.provider),
130
+ resolveEndpoint(memberPath, remotes.ci, entry.provider),
131
+ ]);
132
+ const drift = [];
133
+ if (!existsSync(memberPath))
134
+ drift.push('member path is missing');
135
+ if (!config)
136
+ drift.push('member .aiwg/aiwg.config is missing');
137
+ if (!primary.url)
138
+ drift.push(`primary remote '${remotes.primary}' is unavailable`);
139
+ if (!issueTracker.url)
140
+ drift.push(`issue tracker remote '${remotes.issue_tracker}' is unavailable`);
141
+ if (primary.provider === 'unknown') {
142
+ drift.push(`primary remote provider is unknown for '${primary.domain ?? remotes.primary}'`);
143
+ }
144
+ if (issueTracker.provider === 'unknown') {
145
+ drift.push(`issue tracker provider is unknown for '${issueTracker.domain ?? remotes.issue_tracker}'`);
146
+ }
147
+ if (entry.allowed.includes('issue-comment') && !remotes.tracker_actor?.login) {
148
+ drift.push('issue-comment is allowed but remotes.tracker_actor.login is missing');
149
+ }
150
+ if (remotes.tracker_actor?.login
151
+ && remotes.tracker_actor.forbid_actors?.includes(remotes.tracker_actor.login)) {
152
+ drift.push(`configured tracker actor '${remotes.tracker_actor.login}' is also forbidden`);
153
+ }
154
+ if (config?.delivery?.signing?.enforce
155
+ && !config.delivery.signing.key
156
+ && !config.delivery.signing.key_file) {
157
+ drift.push('delivery signing is enforced but no key or key_file is configured');
158
+ }
159
+ if (entry.provider && primary.providerSource === 'remote' && primary.provider !== entry.provider) {
160
+ drift.push(`provider hint '${entry.provider}' disagrees with primary remote provider '${primary.provider}'`);
161
+ }
162
+ return {
163
+ name: entry.name,
164
+ path: memberPath,
165
+ allowed: [...entry.allowed],
166
+ ...(entry.notes ? { notes: entry.notes } : {}),
167
+ configPath,
168
+ config,
169
+ delivery: resolveDelivery(config?.delivery),
170
+ remotes,
171
+ primary,
172
+ issueTracker,
173
+ ci,
174
+ drift,
175
+ };
176
+ }
177
+ /** Load and resolve every member from the canonical workspace manifest. */
178
+ export async function resolveWorkspace(startPath = process.cwd(), explicitWorkspace) {
179
+ const projectRoot = await findWorkspaceProjectRoot(startPath, explicitWorkspace);
180
+ if (!projectRoot) {
181
+ throw new Error('No workspace .aiwg/aiwg.config with repos was found');
182
+ }
183
+ const config = await readAiwgConfig(projectRoot);
184
+ if (!config?.repos || !config.workspace?.name) {
185
+ throw new Error(`Invalid workspace config at ${getConfigPath(projectRoot)}`);
186
+ }
187
+ const workspaceRoot = config.workspace.root
188
+ ? resolveFrom(projectRoot, config.workspace.root)
189
+ : projectRoot;
190
+ const members = await Promise.all(config.repos.map((entry) => resolveMember(entry, workspaceRoot)));
191
+ return {
192
+ name: config.workspace.name,
193
+ projectRoot,
194
+ root: workspaceRoot,
195
+ configPath: getConfigPath(projectRoot),
196
+ config,
197
+ members,
198
+ };
199
+ }
200
+ /** Resolve the most-specific workspace member containing a target path. */
201
+ export async function resolveWorkspaceMember(startPath, targetPath = startPath, explicitWorkspace) {
202
+ const workspace = await resolveWorkspace(startPath, explicitWorkspace);
203
+ const target = isAbsolute(targetPath)
204
+ ? resolve(targetPath)
205
+ : resolve(asDirectory(startPath), targetPath);
206
+ const member = workspace.members
207
+ .filter((candidate) => isSameOrInside(target, candidate.path))
208
+ .sort((a, b) => b.path.length - a.path.length)[0] ?? null;
209
+ return { workspace, member };
210
+ }
211
+ /**
212
+ * Apply workspace authorization to an operation. An unlisted target or a
213
+ * missing action is denied regardless of filesystem/tool writability.
214
+ */
215
+ export async function authorizeWorkspaceOperation(startPath, targetPath, action, explicitWorkspace) {
216
+ const requestedPath = isAbsolute(targetPath)
217
+ ? resolve(targetPath)
218
+ : resolve(asDirectory(startPath), targetPath);
219
+ const { member } = await resolveWorkspaceMember(startPath, requestedPath, explicitWorkspace);
220
+ if (!member) {
221
+ return {
222
+ allowed: false,
223
+ action,
224
+ requestedPath,
225
+ member: null,
226
+ reason: 'unlisted repo/path defaults to denied',
227
+ };
228
+ }
229
+ if (!member.allowed.includes(action)) {
230
+ return {
231
+ allowed: false,
232
+ action,
233
+ requestedPath,
234
+ member,
235
+ reason: `repo '${member.name}' does not allow ${action}`,
236
+ };
237
+ }
238
+ return {
239
+ allowed: true,
240
+ action,
241
+ requestedPath,
242
+ member,
243
+ reason: `repo '${member.name}' allows ${action}`,
244
+ };
245
+ }
246
+ /** Enforce the member config tracker_actor + forbid_actors contract. */
247
+ export function checkTrackerActor(member, actualActor) {
248
+ const configured = member.remotes.tracker_actor;
249
+ const actor = actualActor ?? configured?.login;
250
+ if (!actor) {
251
+ return {
252
+ allowed: false,
253
+ reason: `repo '${member.name}' does not resolve a tracker actor`,
254
+ };
255
+ }
256
+ if (configured?.forbid_actors?.includes(actor)) {
257
+ return {
258
+ allowed: false,
259
+ actor,
260
+ reason: `tracker actor '${actor}' is forbidden by repo '${member.name}'`,
261
+ };
262
+ }
263
+ if (actualActor && configured?.login && actualActor !== configured.login) {
264
+ return {
265
+ allowed: false,
266
+ actor,
267
+ reason: `tracker actor '${actualActor}' does not match configured actor '${configured.login}'`,
268
+ };
269
+ }
270
+ return {
271
+ allowed: true,
272
+ actor,
273
+ reason: `tracker actor '${actor}' is allowed for repo '${member.name}'`,
274
+ };
275
+ }
276
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Contributor Detection Runner
3
+ *
4
+ * Runs a contributor's declarative detection spec against the project root.
5
+ * Determines whether the contributor's framework is *in use* on this project,
6
+ * not just installed. Pure I/O — no code execution.
7
+ *
8
+ * @architecture @.aiwg/architecture/decisions/ADR-023-contributor-discovery-convention.md
9
+ * @issue #938
10
+ */
11
+ import { glob } from 'glob';
12
+ /**
13
+ * Run a contributor's detection spec. Returns the count of files matching
14
+ * any glob pattern (with deduplication). The caller compares against
15
+ * `spec.minCount` to decide in-use status.
16
+ */
17
+ export async function runDetection(spec, projectRoot) {
18
+ const seen = new Set();
19
+ for (const pattern of spec.glob) {
20
+ const matches = await glob(pattern, {
21
+ cwd: projectRoot,
22
+ nodir: true,
23
+ dot: false,
24
+ absolute: false,
25
+ });
26
+ for (const m of matches)
27
+ seen.add(m);
28
+ }
29
+ return seen.size;
30
+ }
31
+ /**
32
+ * Convenience wrapper: returns true when match count meets minCount (default 1).
33
+ */
34
+ export async function isInUse(spec, projectRoot) {
35
+ const min = spec.minCount ?? 1;
36
+ const count = await runDetection(spec, projectRoot);
37
+ return count >= min;
38
+ }
39
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Contributor Discovery
3
+ *
4
+ * Walks the installed framework registry and project-local override directory
5
+ * to find `<framework>/<kind>/contributor.md` files. Parses, validates, and
6
+ * runs detection on each candidate. Returns kept records and skipped entries
7
+ * with reasons. Failures of one contributor never abort discovery.
8
+ *
9
+ * @architecture @.aiwg/architecture/decisions/ADR-023-contributor-discovery-convention.md
10
+ * @issue #938
11
+ */
12
+ import { existsSync } from 'fs';
13
+ import { readFile } from 'fs/promises';
14
+ import { glob } from 'glob';
15
+ import path from 'path';
16
+ import { parseFrontmatter } from '../artifacts/index-builder.js';
17
+ import { projectAiwgPath } from '../config/project-artifacts.js';
18
+ import { isInUse } from './detect.js';
19
+ import { validateContributor } from './validation.js';
20
+ /**
21
+ * Subdirectories under a framework root that may host installable units.
22
+ * The discovery loop checks each in order so a single id can resolve to
23
+ * the right source path regardless of whether it's a framework, addon, or
24
+ * extension. First match wins.
25
+ */
26
+ const FRAMEWORK_SUBDIRS = ['frameworks', 'addons', 'extensions'];
27
+ /**
28
+ * Read the registry. Returns empty list if missing or unparseable — discovery
29
+ * is non-fatal and project-local contributors can still be found.
30
+ */
31
+ async function readRegistry(registryPath) {
32
+ if (!existsSync(registryPath))
33
+ return { frameworks: [] };
34
+ try {
35
+ const raw = await readFile(registryPath, 'utf-8');
36
+ const parsed = JSON.parse(raw);
37
+ return parsed && Array.isArray(parsed.frameworks) ? parsed : { frameworks: [] };
38
+ }
39
+ catch {
40
+ return { frameworks: [] };
41
+ }
42
+ }
43
+ /**
44
+ * Resolve a framework id to its source path under the AIWG installation.
45
+ * Tries `frameworks/`, `addons/`, `extensions/` in order. Returns null if
46
+ * none exist on disk — the id is registered but its source is missing.
47
+ */
48
+ function resolveFrameworkSourcePath(frameworkRoot, id) {
49
+ for (const sub of FRAMEWORK_SUBDIRS) {
50
+ const candidate = path.join(frameworkRoot, 'agentic', 'code', sub, id);
51
+ if (existsSync(candidate))
52
+ return candidate;
53
+ }
54
+ return null;
55
+ }
56
+ /**
57
+ * Process one contributor source: parse, validate, run detection.
58
+ * Returns either a record (in-use) or a skip entry. Never throws.
59
+ */
60
+ async function processContributor(src, projectRoot) {
61
+ let raw;
62
+ try {
63
+ raw = await readFile(src.path, 'utf-8');
64
+ }
65
+ catch (err) {
66
+ return {
67
+ kind: 'skip',
68
+ entry: { ...src, reason: 'parse-error', message: `cannot read file: ${err.message}` },
69
+ };
70
+ }
71
+ let data;
72
+ let body;
73
+ try {
74
+ const parsed = parseFrontmatter(raw);
75
+ data = parsed.data;
76
+ body = parsed.body;
77
+ }
78
+ catch (err) {
79
+ return {
80
+ kind: 'skip',
81
+ entry: { ...src, reason: 'parse-error', message: `cannot parse frontmatter: ${err.message}` },
82
+ };
83
+ }
84
+ const validation = validateContributor(data);
85
+ if (!validation.ok) {
86
+ return {
87
+ kind: 'skip',
88
+ entry: { ...src, reason: 'schema-violation', message: validation.errors.join('; ') },
89
+ };
90
+ }
91
+ const validData = validation.data;
92
+ let inUse;
93
+ try {
94
+ inUse = await isInUse(validData.detect, projectRoot);
95
+ }
96
+ catch (err) {
97
+ return {
98
+ kind: 'skip',
99
+ entry: { ...src, reason: 'detection-error', message: `detection threw: ${err.message}` },
100
+ };
101
+ }
102
+ if (!inUse) {
103
+ return {
104
+ kind: 'skip',
105
+ entry: { ...src, reason: 'detection-no-match', message: 'declared globs matched fewer files than minCount' },
106
+ };
107
+ }
108
+ return {
109
+ kind: 'record',
110
+ record: { ...src, data: validData, body },
111
+ };
112
+ }
113
+ /**
114
+ * Discover all in-use contributors of a given kind for a project.
115
+ *
116
+ * Walks two source classes:
117
+ *
118
+ * 1. Framework-shipped contributors — for each framework id in the project's
119
+ * `.aiwg/frameworks/registry.json`, look up its source path under the
120
+ * AIWG installation and check for `<kind>/contributor.md`.
121
+ *
122
+ * 2. Project-local contributors — every `.aiwg/contributors/<kind>/*.md`
123
+ * file in the project root. Lets users add custom contributors without
124
+ * forking a framework.
125
+ *
126
+ * Order is preserved: framework contributors appear in registry order, then
127
+ * project-local contributors in glob order. Each kept record carries its
128
+ * `origin` (framework id or `'project-local'`) and absolute `path`.
129
+ *
130
+ * Failures (parse, validation, detection-throw, detection-no-match) are
131
+ * captured as `SkippedContributor` entries — discovery never aborts on a
132
+ * single bad contributor.
133
+ */
134
+ export async function discoverContributors(kind, options) {
135
+ const { frameworkRoot, projectRoot } = options;
136
+ const registryPath = options.registryPath ?? projectAiwgPath(projectRoot, 'frameworks', 'registry.json');
137
+ const sources = [];
138
+ // 1. Framework-shipped contributors via registry.
139
+ const registry = await readRegistry(registryPath);
140
+ for (const entry of registry.frameworks) {
141
+ const sourcePath = resolveFrameworkSourcePath(frameworkRoot, entry.id);
142
+ if (!sourcePath)
143
+ continue;
144
+ const candidate = path.join(sourcePath, kind, 'contributor.md');
145
+ if (existsSync(candidate)) {
146
+ sources.push({ origin: entry.id, path: candidate });
147
+ }
148
+ }
149
+ // 2. Project-local contributors.
150
+ const localDir = projectAiwgPath(projectRoot, 'contributors', kind);
151
+ if (existsSync(localDir)) {
152
+ const localFiles = await glob('*.md', { cwd: localDir, absolute: true, nodir: true });
153
+ localFiles.sort(); // deterministic ordering
154
+ for (const file of localFiles) {
155
+ sources.push({ origin: 'project-local', path: file });
156
+ }
157
+ }
158
+ // Process each source. Failures become skip entries; the rest become records.
159
+ const records = [];
160
+ const skipped = [];
161
+ for (const src of sources) {
162
+ const result = await processContributor(src, projectRoot);
163
+ if (result.kind === 'record') {
164
+ records.push(result.record);
165
+ }
166
+ else {
167
+ skipped.push(result.entry);
168
+ }
169
+ }
170
+ return { kind, records, skipped };
171
+ }
172
+ //# sourceMappingURL=discover.js.map