@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -1
  3. package/bin/aiwg.mjs +349 -0
  4. package/dist/src/a2a/agent-card.js +145 -0
  5. package/dist/src/a2a/client.js +411 -0
  6. package/dist/src/a2a/hitl-cli.js +171 -0
  7. package/dist/src/a2a/hitl-driver.js +370 -0
  8. package/dist/src/a2a/hitl.js +181 -0
  9. package/dist/src/a2a/http.js +193 -0
  10. package/dist/src/a2a/jcs.js +128 -0
  11. package/dist/src/a2a/jws.js +187 -0
  12. package/dist/src/a2a/types.js +24 -0
  13. package/dist/src/a2a/webhook.js +240 -0
  14. package/dist/src/activity-log/cli.js +348 -0
  15. package/dist/src/activity-log/parser.js +81 -0
  16. package/dist/src/activity-log/types.js +50 -0
  17. package/dist/src/agents/agent-deployer.js +367 -0
  18. package/dist/src/agents/agent-packager.js +271 -0
  19. package/dist/src/agents/agent-validator.js +271 -0
  20. package/dist/src/agents/grounding/knowledge-base.js +161 -0
  21. package/dist/src/agents/grounding/types.js +12 -0
  22. package/dist/src/agents/index.js +10 -0
  23. package/dist/src/agents/packaged-agent-inventory.js +75 -0
  24. package/dist/src/agents/types.js +7 -0
  25. package/dist/src/api/index.d.ts +10 -0
  26. package/dist/src/api/index.js +10 -0
  27. package/dist/src/artifacts/address-parser.js +73 -0
  28. package/dist/src/artifacts/audit/cli.js +183 -0
  29. package/dist/src/artifacts/audit/drift.js +122 -0
  30. package/dist/src/artifacts/audit/types.js +12 -0
  31. package/dist/src/artifacts/backends/graphology-backend.js +160 -0
  32. package/dist/src/artifacts/backends/json-backend.js +129 -0
  33. package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
  34. package/dist/src/artifacts/browser-export.js +622 -0
  35. package/dist/src/artifacts/capability-resolver.js +94 -0
  36. package/dist/src/artifacts/checksum-manifest.js +91 -0
  37. package/dist/src/artifacts/citation-parser.js +162 -0
  38. package/dist/src/artifacts/cli.js +1486 -0
  39. package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
  40. package/dist/src/artifacts/corpus-tools/cli.js +393 -0
  41. package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
  42. package/dist/src/artifacts/corpus-tools/curator.js +186 -0
  43. package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
  44. package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
  45. package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
  46. package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
  47. package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
  48. package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
  49. package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
  50. package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
  51. package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
  52. package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
  53. package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
  54. package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
  55. package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
  56. package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
  57. package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
  58. package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
  59. package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
  60. package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
  61. package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
  62. package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
  63. package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
  64. package/dist/src/artifacts/corpus-views/build.js +126 -0
  65. package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
  66. package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
  67. package/dist/src/artifacts/corpus-views/renderers.js +353 -0
  68. package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
  69. package/dist/src/artifacts/dep-graph.js +173 -0
  70. package/dist/src/artifacts/discover-facets.js +375 -0
  71. package/dist/src/artifacts/embedding-index.js +354 -0
  72. package/dist/src/artifacts/enrichment/cli.js +240 -0
  73. package/dist/src/artifacts/enrichment/prompt.js +47 -0
  74. package/dist/src/artifacts/enrichment/store.js +90 -0
  75. package/dist/src/artifacts/enrichment/types.js +12 -0
  76. package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
  77. package/dist/src/artifacts/fortemi-core-sync.js +251 -0
  78. package/dist/src/artifacts/fortemi-shard-export.js +44 -0
  79. package/dist/src/artifacts/fulltext.js +108 -0
  80. package/dist/src/artifacts/graph-backend.js +51 -0
  81. package/dist/src/artifacts/graph-query.js +247 -0
  82. package/dist/src/artifacts/hybrid-query.js +225 -0
  83. package/dist/src/artifacts/index-builder.js +1089 -0
  84. package/dist/src/artifacts/index-reader.js +112 -0
  85. package/dist/src/artifacts/index-status.js +193 -0
  86. package/dist/src/artifacts/legacy-index-migration.js +169 -0
  87. package/dist/src/artifacts/move.js +154 -0
  88. package/dist/src/artifacts/operational-state.js +239 -0
  89. package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
  90. package/dist/src/artifacts/query-engine.js +1955 -0
  91. package/dist/src/artifacts/source-graph.js +529 -0
  92. package/dist/src/artifacts/stats.js +169 -0
  93. package/dist/src/artifacts/types.js +606 -0
  94. package/dist/src/artifacts/views/cli.js +293 -0
  95. package/dist/src/artifacts/views/definition.js +170 -0
  96. package/dist/src/artifacts/views/store.js +149 -0
  97. package/dist/src/artifacts/views/types.js +8 -0
  98. package/dist/src/artifacts/watcher.js +255 -0
  99. package/dist/src/catalog/builtin-models.json +636 -0
  100. package/dist/src/catalog/cli.js +228 -0
  101. package/dist/src/catalog/cli.mjs +289 -0
  102. package/dist/src/catalog/index.js +15 -0
  103. package/dist/src/catalog/loader.js +217 -0
  104. package/dist/src/catalog/loader.mjs +251 -0
  105. package/dist/src/catalog/sources.json +41 -0
  106. package/dist/src/catalog/types.js +8 -0
  107. package/dist/src/channel/manager.mjs +504 -0
  108. package/dist/src/cli/agent-spawn.js +178 -0
  109. package/dist/src/cli/cli-extension-loader.js +245 -0
  110. package/dist/src/cli/command-log.js +275 -0
  111. package/dist/src/cli/config-loader.js +232 -0
  112. package/dist/src/cli/env.js +82 -0
  113. package/dist/src/cli/errors.js +150 -0
  114. package/dist/src/cli/find-package-root.js +40 -0
  115. package/dist/src/cli/git-hooks.js +250 -0
  116. package/dist/src/cli/handlers/agentcard.js +206 -0
  117. package/dist/src/cli/handlers/artifacts.js +76 -0
  118. package/dist/src/cli/handlers/best-practices-audit.js +280 -0
  119. package/dist/src/cli/handlers/cockpit.js +137 -0
  120. package/dist/src/cli/handlers/command-log.js +37 -0
  121. package/dist/src/cli/handlers/daemon.js +59 -0
  122. package/dist/src/cli/handlers/diagnose.js +300 -0
  123. package/dist/src/cli/handlers/execution-mode.js +105 -0
  124. package/dist/src/cli/handlers/feedback.js +341 -0
  125. package/dist/src/cli/handlers/help.js +147 -0
  126. package/dist/src/cli/handlers/index.js +302 -0
  127. package/dist/src/cli/handlers/init.js +179 -0
  128. package/dist/src/cli/handlers/install.js +129 -0
  129. package/dist/src/cli/handlers/issues.js +46 -0
  130. package/dist/src/cli/handlers/lint.js +42 -0
  131. package/dist/src/cli/handlers/local-executor.js +315 -0
  132. package/dist/src/cli/handlers/marketplace.js +168 -0
  133. package/dist/src/cli/handlers/mc.js +1010 -0
  134. package/dist/src/cli/handlers/models.js +352 -0
  135. package/dist/src/cli/handlers/packages.js +155 -0
  136. package/dist/src/cli/handlers/ralph-launcher.js +717 -0
  137. package/dist/src/cli/handlers/ralph.js +575 -0
  138. package/dist/src/cli/handlers/refresh.js +432 -0
  139. package/dist/src/cli/handlers/regenerate.js +336 -0
  140. package/dist/src/cli/handlers/repo-access.js +109 -0
  141. package/dist/src/cli/handlers/run.js +165 -0
  142. package/dist/src/cli/handlers/runtime-info.js +301 -0
  143. package/dist/src/cli/handlers/sandbox.js +197 -0
  144. package/dist/src/cli/handlers/scaffolding.js +149 -0
  145. package/dist/src/cli/handlers/script-runner.js +121 -0
  146. package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
  147. package/dist/src/cli/handlers/serve.js +1835 -0
  148. package/dist/src/cli/handlers/session.js +348 -0
  149. package/dist/src/cli/handlers/setup.js +440 -0
  150. package/dist/src/cli/handlers/skill-lint.js +367 -0
  151. package/dist/src/cli/handlers/skill-usage.js +74 -0
  152. package/dist/src/cli/handlers/steward.js +567 -0
  153. package/dist/src/cli/handlers/subcommands.js +1702 -0
  154. package/dist/src/cli/handlers/team.js +337 -0
  155. package/dist/src/cli/handlers/types.js +11 -0
  156. package/dist/src/cli/handlers/use.js +2772 -0
  157. package/dist/src/cli/handlers/utilities.js +703 -0
  158. package/dist/src/cli/handlers/version.js +134 -0
  159. package/dist/src/cli/handlers/workspace-context.js +93 -0
  160. package/dist/src/cli/handlers/workspace.js +126 -0
  161. package/dist/src/cli/help-generator.js +178 -0
  162. package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
  163. package/dist/src/cli/hooks/executor.js +96 -0
  164. package/dist/src/cli/hooks/index.js +15 -0
  165. package/dist/src/cli/hooks/registry.js +143 -0
  166. package/dist/src/cli/hooks/types.js +13 -0
  167. package/dist/src/cli/log.js +492 -0
  168. package/dist/src/cli/project-isolation/detect.js +70 -0
  169. package/dist/src/cli/project-isolation/index.js +7 -0
  170. package/dist/src/cli/project-isolation/signals.js +17 -0
  171. package/dist/src/cli/project-isolation/warning.js +102 -0
  172. package/dist/src/cli/prompt-utils.js +155 -0
  173. package/dist/src/cli/provider-deployment-plan.js +126 -0
  174. package/dist/src/cli/provider-resolution.js +119 -0
  175. package/dist/src/cli/router.js +305 -0
  176. package/dist/src/cli/scope-resolver.js +392 -0
  177. package/dist/src/cli/skill-usage.js +616 -0
  178. package/dist/src/cli/ui.js +224 -0
  179. package/dist/src/cli/watch-service.js +203 -0
  180. package/dist/src/cli/workflow-orchestrator.js +478 -0
  181. package/dist/src/cli/workspace-signals.js +321 -0
  182. package/dist/src/community/footer.js +14 -0
  183. package/dist/src/community/links.js +123 -0
  184. package/dist/src/community/milestones.js +46 -0
  185. package/dist/src/community/nudge-policy.js +93 -0
  186. package/dist/src/config/aiwg-config.js +883 -0
  187. package/dist/src/config/cli.js +703 -0
  188. package/dist/src/config/gitignore.js +156 -0
  189. package/dist/src/config/project-artifacts.js +76 -0
  190. package/dist/src/config/user-config.js +428 -0
  191. package/dist/src/config/user-registry.js +127 -0
  192. package/dist/src/config/workspace.js +276 -0
  193. package/dist/src/contributors/detect.js +39 -0
  194. package/dist/src/contributors/discover.js +172 -0
  195. package/dist/src/contributors/heuristic.js +186 -0
  196. package/dist/src/contributors/index.js +11 -0
  197. package/dist/src/contributors/types.js +13 -0
  198. package/dist/src/contributors/validation.js +116 -0
  199. package/dist/src/data/community.schema.json +43 -0
  200. package/dist/src/data/community.yaml +16 -0
  201. package/dist/src/extensions/capability-index.js +270 -0
  202. package/dist/src/extensions/claude-hooks-installer.js +268 -0
  203. package/dist/src/extensions/commands/definitions.js +3485 -0
  204. package/dist/src/extensions/deployment-registration.js +463 -0
  205. package/dist/src/extensions/index.js +22 -0
  206. package/dist/src/extensions/loader.js +132 -0
  207. package/dist/src/extensions/managed-marker.js +100 -0
  208. package/dist/src/extensions/manifest.js +196 -0
  209. package/dist/src/extensions/project-local-activity.js +114 -0
  210. package/dist/src/extensions/project-local-discovery.js +261 -0
  211. package/dist/src/extensions/project-local-doctor.js +281 -0
  212. package/dist/src/extensions/project-local-gitignore.js +176 -0
  213. package/dist/src/extensions/project-local-paths.js +121 -0
  214. package/dist/src/extensions/project-local-promote.js +218 -0
  215. package/dist/src/extensions/project-local-remove.js +373 -0
  216. package/dist/src/extensions/project-local-scaffold.js +252 -0
  217. package/dist/src/extensions/project-quickref.js +291 -0
  218. package/dist/src/extensions/registry.js +368 -0
  219. package/dist/src/extensions/shadow-resolver.js +271 -0
  220. package/dist/src/extensions/types.js +86 -0
  221. package/dist/src/extensions/upstream-registry.js +195 -0
  222. package/dist/src/extensions/validation.js +631 -0
  223. package/dist/src/features/catalog.js +88 -0
  224. package/dist/src/features/cli.js +197 -0
  225. package/dist/src/features/installer.js +57 -0
  226. package/dist/src/features/paths.js +14 -0
  227. package/dist/src/features/runtime.js +21 -0
  228. package/dist/src/features/status.js +134 -0
  229. package/dist/src/hooks/laziness-detection.js +532 -0
  230. package/dist/src/intake/git-history-analyzer.js +486 -0
  231. package/dist/src/intake/index.js +9 -0
  232. package/dist/src/issues/cli.js +327 -0
  233. package/dist/src/issues/index.js +5 -0
  234. package/dist/src/issues/live.js +154 -0
  235. package/dist/src/issues/local.js +666 -0
  236. package/dist/src/issues/sync.js +143 -0
  237. package/dist/src/issues/types.js +2 -0
  238. package/dist/src/issues/workflows.js +164 -0
  239. package/dist/src/kb/cli.js +173 -0
  240. package/dist/src/lint/cli.js +171 -0
  241. package/dist/src/lint/loader.js +225 -0
  242. package/dist/src/lint/reporters.js +141 -0
  243. package/dist/src/lint/runner.js +364 -0
  244. package/dist/src/lint/types.js +10 -0
  245. package/dist/src/marketplace/cache.js +110 -0
  246. package/dist/src/marketplace/identifier.js +63 -0
  247. package/dist/src/marketplace/registry.js +36 -0
  248. package/dist/src/marketplace/sources/clawhub.js +53 -0
  249. package/dist/src/marketplace/sources/git.js +45 -0
  250. package/dist/src/marketplace/types.js +9 -0
  251. package/dist/src/mcp/adapters/codex-runtime.js +224 -0
  252. package/dist/src/mcp/cli.mjs +1197 -0
  253. package/dist/src/mcp/elicitation.mjs +149 -0
  254. package/dist/src/mcp/helpers.mjs +287 -0
  255. package/dist/src/mcp/index.mjs +11 -0
  256. package/dist/src/mcp/profiles.js +263 -0
  257. package/dist/src/mcp/profiles.mjs +360 -0
  258. package/dist/src/mcp/registry.js +376 -0
  259. package/dist/src/mcp/registry.mjs +387 -0
  260. package/dist/src/mcp/server.mjs +633 -0
  261. package/dist/src/mcp/test-simple.mjs +271 -0
  262. package/dist/src/mcp/tools/command-run.mjs +101 -0
  263. package/dist/src/mcp/tools/discovery.mjs +291 -0
  264. package/dist/src/mcp/tools/interaction.mjs +87 -0
  265. package/dist/src/mcp/tools/orchestration.mjs +320 -0
  266. package/dist/src/mcp/tools/subsystems.mjs +640 -0
  267. package/dist/src/memory/cli.js +166 -0
  268. package/dist/src/memory/project-registry.js +282 -0
  269. package/dist/src/metrics/artifact-metrics.js +184 -0
  270. package/dist/src/metrics/context-budget.js +174 -0
  271. package/dist/src/metrics/token-counter.js +133 -0
  272. package/dist/src/models/config-loader.js +228 -0
  273. package/dist/src/models/index.js +22 -0
  274. package/dist/src/models/model-capabilities.v1.json +120 -0
  275. package/dist/src/models/model-catalog.v1.json +96 -0
  276. package/dist/src/models/model-discovery.js +521 -0
  277. package/dist/src/models/provider-models.js +73 -0
  278. package/dist/src/models/provider-policy.js +273 -0
  279. package/dist/src/models/resolver.js +245 -0
  280. package/dist/src/models/router.js +70 -0
  281. package/dist/src/models/types.js +8 -0
  282. package/dist/src/models/wrapper-deployment.js +178 -0
  283. package/dist/src/models/wrapper-route.js +54 -0
  284. package/dist/src/ops/cli.js +268 -0
  285. package/dist/src/ops/registry.js +623 -0
  286. package/dist/src/packages/adapters/clawhub.js +113 -0
  287. package/dist/src/packages/adapters/git.js +153 -0
  288. package/dist/src/packages/adapters/gitea.js +93 -0
  289. package/dist/src/packages/adapters/github.js +69 -0
  290. package/dist/src/packages/adapters/local-cache.js +89 -0
  291. package/dist/src/packages/package-registry.js +143 -0
  292. package/dist/src/packages/registry.js +238 -0
  293. package/dist/src/packages/types.js +11 -0
  294. package/dist/src/plugin/cross-framework-ops.js +475 -0
  295. package/dist/src/plugin/framework-config-loader.js +235 -0
  296. package/dist/src/plugin/framework-detector.js +186 -0
  297. package/dist/src/plugin/framework-isolator.js +341 -0
  298. package/dist/src/plugin/framework-migration.js +371 -0
  299. package/dist/src/plugin/metadata-validator.js +906 -0
  300. package/dist/src/plugin/plugin-installer.js +436 -0
  301. package/dist/src/plugin/plugin-status.js +369 -0
  302. package/dist/src/plugin/plugin-uninstaller.js +473 -0
  303. package/dist/src/plugin/registry-validator.js +344 -0
  304. package/dist/src/plugin/skill-command-translator.js +415 -0
  305. package/dist/src/plugin/workspace-creator.js +189 -0
  306. package/dist/src/plugin/workspace-migrator.js +821 -0
  307. package/dist/src/policy/authorization.js +390 -0
  308. package/dist/src/policy/repo-access.js +215 -0
  309. package/dist/src/provenance/cli.js +16 -0
  310. package/dist/src/providers/capability-matrix.js +300 -0
  311. package/dist/src/providers/capability-matrix.yaml +514 -0
  312. package/dist/src/providers/provider-definitions.js +977 -0
  313. package/dist/src/providers/provider-definitions.mjs +159 -0
  314. package/dist/src/providers/provider-inventory.js +169 -0
  315. package/dist/src/quality/feedback-ab.js +174 -0
  316. package/dist/src/quality/feedback-collector.js +176 -0
  317. package/dist/src/quality/feedback-tracker.js +123 -0
  318. package/dist/src/quality/patterns/adr.json +24 -0
  319. package/dist/src/quality/patterns/sad.json +24 -0
  320. package/dist/src/quality/patterns/test-plan.json +24 -0
  321. package/dist/src/quality/patterns/use-case.json +24 -0
  322. package/dist/src/quality/scoring.js +157 -0
  323. package/dist/src/reflections/cli.js +15 -0
  324. package/dist/src/release/plan.js +139 -0
  325. package/dist/src/research/cache/manager.js +227 -0
  326. package/dist/src/research/clients/arxiv.js +156 -0
  327. package/dist/src/research/clients/base.js +197 -0
  328. package/dist/src/research/clients/crossref.js +112 -0
  329. package/dist/src/research/clients/semantic-scholar.js +126 -0
  330. package/dist/src/research/clients/unpaywall.js +87 -0
  331. package/dist/src/research/index.js +14 -0
  332. package/dist/src/research/query-cli.js +336 -0
  333. package/dist/src/research/services/acquisition.js +313 -0
  334. package/dist/src/research/services/archival.js +225 -0
  335. package/dist/src/research/services/citation.js +279 -0
  336. package/dist/src/research/services/discovery.js +243 -0
  337. package/dist/src/research/services/documentation.js +269 -0
  338. package/dist/src/research/services/index.js +14 -0
  339. package/dist/src/research/services/provenance.js +279 -0
  340. package/dist/src/research/services/quality.js +370 -0
  341. package/dist/src/research/services/types.js +7 -0
  342. package/dist/src/research/storage-cli.js +20 -0
  343. package/dist/src/research/types.js +47 -0
  344. package/dist/src/resources/index.d.ts +2 -0
  345. package/dist/src/resources/index.js +2 -0
  346. package/dist/src/resources/web-release.d.ts +89 -0
  347. package/dist/src/resources/web-release.js +886 -0
  348. package/dist/src/rlm/cache/cli.js +162 -0
  349. package/dist/src/rlm/cache/hash.js +35 -0
  350. package/dist/src/rlm/cache/store.js +170 -0
  351. package/dist/src/rlm/cache/types.js +8 -0
  352. package/dist/src/rlm/cli.js +650 -0
  353. package/dist/src/serve/a2a-terminal-observer.js +120 -0
  354. package/dist/src/serve/agent-router.js +205 -0
  355. package/dist/src/serve/dispatch-router.js +171 -0
  356. package/dist/src/serve/executor-registry.js +715 -0
  357. package/dist/src/serve/mission-conductor.js +177 -0
  358. package/dist/src/serve/orchestrator-adapter.js +113 -0
  359. package/dist/src/serve/orchestrator-override.js +94 -0
  360. package/dist/src/serve/orchestrator-pty.js +133 -0
  361. package/dist/src/serve/pty-bridge.js +799 -0
  362. package/dist/src/serve/sandbox-registry.js +832 -0
  363. package/dist/src/serve/screen-reader.js +228 -0
  364. package/dist/src/serve/stack-adapters.js +68 -0
  365. package/dist/src/serve/telemetry.js +143 -0
  366. package/dist/src/skills/adapters/clawhub.js +250 -0
  367. package/dist/src/skills/adapters/local.js +335 -0
  368. package/dist/src/skills/adapters/openclaw.js +316 -0
  369. package/dist/src/skills/cli.js +334 -0
  370. package/dist/src/skills/registry.js +117 -0
  371. package/dist/src/skills/run.js +259 -0
  372. package/dist/src/skills/runtime.js +94 -0
  373. package/dist/src/skills/types.js +10 -0
  374. package/dist/src/smiths/agentsmith/demo.js +116 -0
  375. package/dist/src/smiths/agentsmith/examples.js +300 -0
  376. package/dist/src/smiths/agentsmith/generator.js +503 -0
  377. package/dist/src/smiths/agentsmith/index.js +11 -0
  378. package/dist/src/smiths/agentsmith/types.js +8 -0
  379. package/dist/src/smiths/commandsmith/example.js +220 -0
  380. package/dist/src/smiths/commandsmith/generator.js +288 -0
  381. package/dist/src/smiths/commandsmith/index.js +41 -0
  382. package/dist/src/smiths/commandsmith/templates.js +296 -0
  383. package/dist/src/smiths/commandsmith/types.js +7 -0
  384. package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
  385. package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
  386. package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
  387. package/dist/src/smiths/context-pipeline/discovery.js +187 -0
  388. package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
  389. package/dist/src/smiths/context-pipeline/finalization.js +147 -0
  390. package/dist/src/smiths/context-pipeline/generator.js +477 -0
  391. package/dist/src/smiths/context-pipeline/index.js +30 -0
  392. package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
  393. package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
  394. package/dist/src/smiths/context-pipeline/overflow.js +212 -0
  395. package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
  396. package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
  397. package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
  398. package/dist/src/smiths/context-pipeline/types.js +23 -0
  399. package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
  400. package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
  401. package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
  402. package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
  403. package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
  404. package/dist/src/smiths/hook-bridge/index.js +79 -0
  405. package/dist/src/smiths/hook-bridge/loader.js +116 -0
  406. package/dist/src/smiths/hook-bridge/shim.js +89 -0
  407. package/dist/src/smiths/hook-bridge/types.js +31 -0
  408. package/dist/src/smiths/index.js +39 -0
  409. package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
  410. package/dist/src/smiths/mcpsmith/example.js +119 -0
  411. package/dist/src/smiths/mcpsmith/generator.js +236 -0
  412. package/dist/src/smiths/mcpsmith/index.js +17 -0
  413. package/dist/src/smiths/mcpsmith/types.js +10 -0
  414. package/dist/src/smiths/platform-paths.js +101 -0
  415. package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
  416. package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
  417. package/dist/src/smiths/skillsmith/demo.js +83 -0
  418. package/dist/src/smiths/skillsmith/examples.js +161 -0
  419. package/dist/src/smiths/skillsmith/generator.js +316 -0
  420. package/dist/src/smiths/skillsmith/index.js +12 -0
  421. package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
  422. package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
  423. package/dist/src/smiths/skillsmith/types.js +9 -0
  424. package/dist/src/smiths/toolsmith/index.js +10 -0
  425. package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
  426. package/dist/src/smiths/toolsmith/types.js +8 -0
  427. package/dist/src/storage/backends/fortemi.js +227 -0
  428. package/dist/src/storage/backends/fs.js +134 -0
  429. package/dist/src/storage/backends/logseq.js +309 -0
  430. package/dist/src/storage/backends/obsidian.js +233 -0
  431. package/dist/src/storage/cli.js +468 -0
  432. package/dist/src/storage/config.js +272 -0
  433. package/dist/src/storage/index.js +108 -0
  434. package/dist/src/storage/subsystem-cli.js +201 -0
  435. package/dist/src/storage/types.js +33 -0
  436. package/dist/src/testing/corpus/corpus-builder.js +383 -0
  437. package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
  438. package/dist/src/testing/corpus/index.js +10 -0
  439. package/dist/src/testing/fixtures/index.js +9 -0
  440. package/dist/src/testing/fixtures/test-data-factory.js +472 -0
  441. package/dist/src/testing/generators/index.js +11 -0
  442. package/dist/src/testing/generators/test-case-generator.js +393 -0
  443. package/dist/src/testing/generators/test-code-generator.js +384 -0
  444. package/dist/src/testing/generators/use-case-parser.js +325 -0
  445. package/dist/src/testing/index.js +11 -0
  446. package/dist/src/tracker/capability-protocol.js +118 -0
  447. package/dist/src/update/checker.mjs +396 -0
  448. package/dist/src/update/notifier.mjs +235 -0
  449. package/dist/src/writing/content-diversifier.js +804 -0
  450. package/dist/src/writing/example-generator.js +959 -0
  451. package/dist/src/writing/example-templates.js +99 -0
  452. package/dist/src/writing/pattern-library.js +486 -0
  453. package/dist/src/writing/patterns/banned-phrases.json +4413 -0
  454. package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
  455. package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
  456. package/dist/src/writing/patterns/hedging-language.json +2096 -0
  457. package/dist/src/writing/patterns/transition-words.json +1285 -0
  458. package/dist/src/writing/patterns/weak-verbs.json +1112 -0
  459. package/dist/src/writing/prompt-optimizer.js +660 -0
  460. package/dist/src/writing/prompt-templates.js +583 -0
  461. package/dist/src/writing/scoring-config-loader.js +168 -0
  462. package/dist/src/writing/validation-engine.js +595 -0
  463. package/dist/src/writing/validation-rules.js +380 -0
  464. package/dist/src/writing/voice-analyzer.js +439 -0
  465. package/dist/src/writing/voice-calibration.js +661 -0
  466. package/dist/src/writing/voice-profiles.json +588 -0
  467. package/package.json +65 -9
@@ -0,0 +1,390 @@
1
+ /**
2
+ * Provider-neutral authorization model and legacy normalization.
3
+ *
4
+ * The core follows NIST RBAC separation of roles and assignments. Provider
5
+ * mappings are metadata: they must never silently broaden the core grant.
6
+ *
7
+ * @implements #1800
8
+ */
9
+ import { access, copyFile, mkdir, readFile, rename } from 'node:fs/promises';
10
+ import { isAbsolute, join, relative, resolve } from 'node:path';
11
+ import { load as loadYaml } from 'js-yaml';
12
+ import { projectAiwgPath } from '../config/project-artifacts.js';
13
+ /**
14
+ * Export provider mappings without inventing provider grants. Stable IDs,
15
+ * principals, scopes, resources, actions, and conditions survive unchanged;
16
+ * unsupported core features are reported instead of discarded silently.
17
+ */
18
+ export function exportProviderMappings(model, provider) {
19
+ const diagnostics = [];
20
+ const mappings = structuredClone(model.provider_mappings?.[provider] ?? []);
21
+ if (!mappings.length)
22
+ diagnostics.push({
23
+ severity: 'warning',
24
+ code: 'provider-mapping-missing',
25
+ message: `No explicit ${provider} mappings exist; no provider policy was generated.`,
26
+ });
27
+ if (provider === 'aws_iam' && Object.values(model.roles).some(role => role.inherits?.length)) {
28
+ diagnostics.push({ severity: 'warning', code: 'aws-role-inheritance-loss', message: 'AWS IAM has no direct role-inheritance equivalent; inherited grants must be flattened and reviewed.' });
29
+ }
30
+ if (provider === 'entra_id' && Object.keys(model.boundaries ?? {}).length) {
31
+ diagnostics.push({ severity: 'warning', code: 'entra-boundary-loss', message: 'Entra/Azure RBAC has no IAM permission-boundary equivalent; preserve narrowing with assignment scopes and conditions.' });
32
+ }
33
+ diagnostics.push(...validateAuthorization(model).filter(d => d.code.startsWith(provider === 'openbao' ? 'openbao-' : '__none__')));
34
+ return { provider, mappings, diagnostics };
35
+ }
36
+ function matches(pattern, value) {
37
+ if (pattern === '*')
38
+ return true;
39
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*');
40
+ return new RegExp(`^${escaped}$`).test(value);
41
+ }
42
+ function rolePermissions(model, roleId, seen = new Set()) {
43
+ if (seen.has(roleId))
44
+ return new Set();
45
+ seen.add(roleId);
46
+ const role = model.roles[roleId];
47
+ if (!role)
48
+ return new Set();
49
+ const result = new Set(role.permissions);
50
+ for (const parent of role.inherits ?? []) {
51
+ for (const permission of rolePermissions(model, parent, seen))
52
+ result.add(permission);
53
+ }
54
+ return result;
55
+ }
56
+ /** Evaluate a grant. Unknown inputs and malformed references fail closed. */
57
+ export function evaluateAuthorization(model, request) {
58
+ if (!model || model.default_effect !== 'deny') {
59
+ return { allowed: false, reason: 'missing-or-invalid-default-deny-model', matched_permissions: [] };
60
+ }
61
+ const matched = new Set();
62
+ let allowed = false;
63
+ const resource = model.resources[request.resource];
64
+ if (!resource)
65
+ return { allowed: false, reason: 'unknown-resource', matched_permissions: [] };
66
+ const permissionMatches = (permission) => Boolean(permission
67
+ && permission.actions.some(a => matches(a, request.action))
68
+ && (permission.resource_types.includes(resource.type) || permission.resource_types.includes('*')));
69
+ for (const assignment of model.assignments) {
70
+ if (!assignment.subjects.some(s => request.subjects.some(r => r.kind === s.kind && r.id === s.id)))
71
+ continue;
72
+ if (!assignment.scope.resources.some(resource => matches(resource, request.resource)))
73
+ continue;
74
+ if (assignment.expires_at && (request.now ?? new Date()) >= new Date(assignment.expires_at))
75
+ continue;
76
+ if (assignment.conditions && !Object.entries(assignment.conditions).every(([key, value]) => Object.prototype.hasOwnProperty.call(request.context ?? {}, key)
77
+ && JSON.stringify(request.context?.[key]) === JSON.stringify(value)))
78
+ continue;
79
+ for (const roleId of assignment.roles) {
80
+ const role = model.roles[roleId];
81
+ if (!role)
82
+ continue;
83
+ const rawPermissions = rolePermissions(model, roleId);
84
+ // Explicit deny is evaluated before boundaries. A narrowing control may
85
+ // never erase a deny.
86
+ for (const permissionId of rawPermissions) {
87
+ const permission = model.permissions[permissionId];
88
+ if (permission?.effect === 'deny' && permissionMatches(permission)) {
89
+ matched.add(permissionId);
90
+ return { allowed: false, reason: `explicit-deny:${permissionId}`, matched_permissions: [...matched] };
91
+ }
92
+ }
93
+ let permissions = rawPermissions;
94
+ for (const boundaryId of role.boundaries ?? []) {
95
+ const boundary = model.boundaries?.[boundaryId];
96
+ permissions = new Set([...permissions].filter(p => boundary?.permissions?.includes(p)
97
+ && (!boundary.resources || boundary.resources.some(r => matches(r, request.resource)))));
98
+ }
99
+ for (const permissionId of permissions) {
100
+ const permission = model.permissions[permissionId];
101
+ if (!permissionMatches(permission))
102
+ continue;
103
+ matched.add(permissionId);
104
+ allowed = true;
105
+ }
106
+ }
107
+ }
108
+ return {
109
+ allowed,
110
+ reason: allowed ? 'role-grant' : 'default-deny',
111
+ matched_permissions: [...matched].sort(),
112
+ };
113
+ }
114
+ export function validateAuthorization(model) {
115
+ if (!model)
116
+ return [{ severity: 'warning', code: 'authorization-missing', message: 'No normalized authorization block; run steward permissions audit.' }];
117
+ const out = [];
118
+ if (model.version !== '1')
119
+ out.push({ severity: 'error', code: 'version', message: `Unsupported authorization version: ${model.version}` });
120
+ if (model.default_effect !== 'deny')
121
+ out.push({ severity: 'error', code: 'default-effect', message: 'Authorization must default to deny.' });
122
+ for (const [id, role] of Object.entries(model.roles)) {
123
+ for (const permission of role.permissions)
124
+ if (!model.permissions[permission])
125
+ out.push({ severity: 'error', code: 'unknown-permission', message: `Role ${id} references unknown permission ${permission}.` });
126
+ for (const parent of role.inherits ?? [])
127
+ if (!model.roles[parent])
128
+ out.push({ severity: 'error', code: 'unknown-role', message: `Role ${id} inherits unknown role ${parent}.` });
129
+ for (const boundary of role.boundaries ?? [])
130
+ if (!model.boundaries?.[boundary])
131
+ out.push({ severity: 'error', code: 'unknown-boundary', message: `Role ${id} references unknown boundary ${boundary}.` });
132
+ }
133
+ const visiting = new Set();
134
+ const visited = new Set();
135
+ const visitRole = (id) => {
136
+ if (visiting.has(id)) {
137
+ out.push({ severity: 'error', code: 'role-cycle', message: `Role inheritance cycle includes ${id}.` });
138
+ return;
139
+ }
140
+ if (visited.has(id))
141
+ return;
142
+ visiting.add(id);
143
+ for (const parent of model.roles[id]?.inherits ?? [])
144
+ visitRole(parent);
145
+ visiting.delete(id);
146
+ visited.add(id);
147
+ };
148
+ for (const id of Object.keys(model.roles))
149
+ visitRole(id);
150
+ for (const assignment of model.assignments) {
151
+ for (const role of assignment.roles)
152
+ if (!model.roles[role])
153
+ out.push({ severity: 'error', code: 'unknown-role', message: `Assignment ${assignment.id} references unknown role ${role}.` });
154
+ for (const resource of assignment.scope.resources)
155
+ if (!model.resources[resource] && resource !== '*')
156
+ out.push({ severity: 'error', code: 'unknown-resource', message: `Assignment ${assignment.id} references unknown resource ${resource}.` });
157
+ if (assignment.expires_at && Number.isNaN(Date.parse(assignment.expires_at)))
158
+ out.push({ severity: 'error', code: 'invalid-expiry', message: `Assignment ${assignment.id} has an invalid expires_at timestamp.` });
159
+ }
160
+ for (const mapping of model.provider_mappings?.openbao ?? []) {
161
+ if (!mapping.locator_env)
162
+ out.push({ severity: 'error', code: 'openbao-locator', message: `OpenBao mapping ${mapping.stable_id} must use locator_env.` });
163
+ if (!mapping.token_ttl || !mapping.token_max_ttl || !mapping.secret_id_ttl || mapping.secret_id_num_uses === undefined) {
164
+ out.push({ severity: 'error', code: 'openbao-constraints', message: `OpenBao mapping ${mapping.stable_id} requires bounded token and SecretID constraints.` });
165
+ }
166
+ }
167
+ return out;
168
+ }
169
+ const LEGACY_MANIFESTS = [
170
+ '.aiwg/ops/security/repo-access.manifest.yaml',
171
+ '.aiwg/security/repo-access.manifest.yaml',
172
+ ];
173
+ export async function auditLegacyPermissions(projectDir, config) {
174
+ const out = validateAuthorization(config?.authorization);
175
+ if (!config?.authorization && config?.repos?.some(repo => repo.allowed?.length))
176
+ out.push({ severity: 'warning', code: 'legacy-repos-allowed', source: '.aiwg/aiwg.config', message: 'repos[].allowed should be normalized into authorization roles and assignments.' });
177
+ if (!config?.authorization && Object.keys(config?.repo_maintainer?.tiers ?? {}).length)
178
+ out.push({ severity: 'warning', code: 'legacy-maintainer-tiers', source: '.aiwg/aiwg.config', message: 'repo_maintainer.tiers should be represented by normalized role assignments.' });
179
+ if (!config?.authorization && config?.delivery)
180
+ out.push({ severity: 'warning', code: 'legacy-delivery-policy', source: '.aiwg/aiwg.config', message: 'delivery and signing operations should be normalized into scoped role assignments.' });
181
+ for (const path of LEGACY_MANIFESTS) {
182
+ try {
183
+ await access(join(projectDir, path));
184
+ out.push({ severity: 'warning', code: 'legacy-repo-manifest', source: path, message: 'Legacy repository permission manifest detected.' });
185
+ }
186
+ catch { /* absent */ }
187
+ }
188
+ return out;
189
+ }
190
+ /** Deterministically normalize current repo grants. It only copies declared legacy actions. */
191
+ export function normalizeLegacyPermissions(config) {
192
+ if (config.authorization)
193
+ return config;
194
+ const resources = {};
195
+ const permissions = {};
196
+ const roles = {};
197
+ const assignments = [];
198
+ for (const repo of config.repos ?? []) {
199
+ const resourceId = `repo:${repo.name}`;
200
+ const roleId = `legacy.repo.${repo.name}`;
201
+ resources[resourceId] = { type: 'repo', value: repo.path, provider: repo.provider };
202
+ const ids = [];
203
+ for (const action of repo.allowed ?? []) {
204
+ const permissionId = `repo.${action}`;
205
+ permissions[permissionId] ??= { actions: [action], resource_types: ['repo'], effect: 'allow' };
206
+ ids.push(permissionId);
207
+ }
208
+ roles[roleId] = { permissions: [...new Set(ids)].sort(), description: 'Normalized from repos[].allowed' };
209
+ assignments.push({ id: `legacy.${repo.name}`, subjects: [{ kind: 'workload', id: 'aiwg:workspace' }], roles: [roleId], scope: { resources: [resourceId] }, justification: 'Mechanical normalization of legacy workspace grants' });
210
+ }
211
+ for (const [target, tier] of Object.entries(config.repo_maintainer?.tiers ?? {})) {
212
+ const resourceId = `repo-maintainer:${target}`;
213
+ resources[resourceId] = { type: 'repo', value: target };
214
+ const actions = ['read', 'write', 'commit', 'push', 'issue-comment'];
215
+ if (tier === 'maintainer' || tier === 'admin')
216
+ actions.push('service-action');
217
+ if (tier === 'admin')
218
+ actions.push('destructive');
219
+ for (const action of actions)
220
+ permissions[`repo.${action}`] ??= { actions: [action], resource_types: ['repo'] };
221
+ const roleId = `legacy.repo-maintainer.${tier}`;
222
+ roles[roleId] ??= { permissions: actions.map(action => `repo.${action}`), description: `Normalized ${tier} compatibility tier` };
223
+ assignments.push({
224
+ id: `legacy.repo-maintainer.${assignments.length}`,
225
+ subjects: [{ kind: 'workload', id: 'aiwg:repo-maintainer' }],
226
+ roles: [roleId],
227
+ scope: { resources: [resourceId] },
228
+ justification: 'Mechanical normalization of repo_maintainer.tiers',
229
+ });
230
+ }
231
+ // Single-repository delivery declarations are also legacy authorization
232
+ // inputs. Map only the operations the selected mode already authorizes.
233
+ if (config.delivery) {
234
+ resources['repo:local'] = { type: 'repo', value: '.' };
235
+ const deliveryActions = ['read', 'write', 'commit'];
236
+ if (config.delivery.mode === 'direct' || config.delivery.mode === 'feature-branch' || config.delivery.mode === 'pr-required') {
237
+ deliveryActions.push('push');
238
+ }
239
+ for (const action of deliveryActions)
240
+ permissions[`repo.${action}`] ??= { actions: [action], resource_types: ['repo'] };
241
+ if (config.delivery.issue_comment_on_cycle && config.remotes?.issue_tracker) {
242
+ resources['tracker:issues'] = { type: 'tracker', value: config.remotes.issue_tracker };
243
+ permissions['tracker.issue-comment'] = { actions: ['issue-comment'], resource_types: ['tracker'] };
244
+ }
245
+ const scopedResources = ['repo:local', ...(resources['tracker:issues'] ? ['tracker:issues'] : [])];
246
+ roles['delivery.contributor'] = {
247
+ permissions: [...deliveryActions.map(action => `repo.${action}`), ...(permissions['tracker.issue-comment'] ? ['tracker.issue-comment'] : [])],
248
+ description: 'Normalized from delivery and tracker policy',
249
+ };
250
+ assignments.push({
251
+ id: 'delivery.address-issues',
252
+ subjects: [{ kind: 'workload', id: 'aiwg:address-issues' }],
253
+ roles: ['delivery.contributor'],
254
+ scope: { resources: scopedResources },
255
+ justification: 'Mechanical normalization of declared delivery operations',
256
+ });
257
+ }
258
+ if (config.delivery?.signing?.enforce === 'commits') {
259
+ resources['secret:commit-signing-key'] = {
260
+ type: 'secret',
261
+ value: 'commit-signing-key',
262
+ provider: 'openbao',
263
+ locator_env: 'COMMIT_SIGNING_KEY_VAULT_PATH',
264
+ };
265
+ permissions['secret.commit-signing-key.read'] = { actions: ['read'], resource_types: ['secret'] };
266
+ roles['delivery.commit-signer'] = {
267
+ permissions: ['secret.commit-signing-key.read'],
268
+ boundaries: ['commit-signing-only'],
269
+ description: 'Read only the commit signing key; never the release signing key',
270
+ };
271
+ assignments.push({
272
+ id: 'delivery.commit-signer',
273
+ subjects: [{ kind: 'workload', id: 'aiwg:commit-signer' }],
274
+ roles: ['delivery.commit-signer'],
275
+ scope: { resources: ['secret:commit-signing-key'] },
276
+ justification: 'Normalized from commit-signing enforcement',
277
+ });
278
+ }
279
+ return {
280
+ ...config,
281
+ authorization: {
282
+ version: '1',
283
+ default_effect: 'deny',
284
+ resources,
285
+ permissions,
286
+ roles,
287
+ boundaries: roles['delivery.commit-signer']
288
+ ? { 'commit-signing-only': { permissions: ['secret.commit-signing-key.read'], resources: ['secret:commit-signing-key'] } }
289
+ : undefined,
290
+ assignments,
291
+ provider_mappings: roles['delivery.commit-signer'] ? {
292
+ openbao: [{
293
+ stable_id: 'aiwg-commit-signer',
294
+ provider_id: 'aiwg-commit-signer',
295
+ actions: ['read'],
296
+ resources: ['secret:commit-signing-key'],
297
+ token_ttl: '5m',
298
+ token_max_ttl: '15m',
299
+ secret_id_ttl: '24h',
300
+ secret_id_num_uses: 1,
301
+ locator_env: 'COMMIT_SIGNING_KEY_VAULT_PATH',
302
+ }],
303
+ } : undefined,
304
+ },
305
+ };
306
+ }
307
+ /**
308
+ * Include the first historical YAML repo manifest in normalization. Invalid or
309
+ * broad-by-default manifests abort; they are never partially imported.
310
+ */
311
+ export async function normalizeProjectPermissions(projectDir, config) {
312
+ if (config.authorization)
313
+ return config;
314
+ let source = config;
315
+ if (!config.repos?.length) {
316
+ for (const manifestPath of LEGACY_MANIFESTS) {
317
+ try {
318
+ const raw = loadYaml(await readFile(join(projectDir, manifestPath), 'utf8'));
319
+ if ((raw.defaultPolicy ?? raw.default_policy ?? 'deny') !== 'deny') {
320
+ throw new Error(`${manifestPath} must default to deny`);
321
+ }
322
+ if (!Array.isArray(raw.repos))
323
+ throw new Error(`${manifestPath} requires repos: []`);
324
+ const repos = raw.repos.map((entry, index) => {
325
+ if (!entry || typeof entry !== 'object')
326
+ throw new Error(`${manifestPath} repos[${index}] must be an object`);
327
+ const value = entry;
328
+ const actions = value.allowed ?? value.actions ?? value.permissions;
329
+ if (typeof value.name !== 'string' || typeof value.path !== 'string' || !Array.isArray(actions)) {
330
+ throw new Error(`${manifestPath} repos[${index}] requires name, path, and actions`);
331
+ }
332
+ for (const action of actions) {
333
+ if (typeof action !== 'string' || !['read', 'write', 'commit', 'push', 'issue-comment', 'service-action', 'destructive'].includes(action)) {
334
+ throw new Error(`${manifestPath} repos[${index}] has invalid action ${String(action)}`);
335
+ }
336
+ }
337
+ const absolute = isAbsolute(value.path) ? resolve(value.path) : resolve(projectDir, value.path);
338
+ return {
339
+ name: value.name,
340
+ path: relative(projectDir, absolute) || '.',
341
+ allowed: actions,
342
+ provider: ['gitea', 'github', 'gitlab'].includes(String(value.provider))
343
+ ? value.provider
344
+ : undefined,
345
+ notes: typeof value.notes === 'string' ? value.notes : undefined,
346
+ };
347
+ });
348
+ source = { ...config, repos };
349
+ break;
350
+ }
351
+ catch (error) {
352
+ if (error.code === 'ENOENT')
353
+ continue;
354
+ throw error;
355
+ }
356
+ }
357
+ }
358
+ const normalized = normalizeLegacyPermissions(source);
359
+ return source === config ? normalized : { ...normalized, repos: config.repos };
360
+ }
361
+ /** Archive migrated standalone manifests so subsequent audits are clean. */
362
+ export async function archiveLegacyPermissionManifests(projectDir) {
363
+ const archived = [];
364
+ for (const path of LEGACY_MANIFESTS) {
365
+ try {
366
+ const target = `${path}.migrated.bak`;
367
+ await rename(join(projectDir, path), join(projectDir, target));
368
+ archived.push(target);
369
+ }
370
+ catch (error) {
371
+ if (error.code !== 'ENOENT')
372
+ throw error;
373
+ }
374
+ }
375
+ return archived;
376
+ }
377
+ export async function backupConfig(projectDir) {
378
+ const source = projectAiwgPath(projectDir, 'aiwg.config');
379
+ const backupDir = projectAiwgPath(projectDir, 'backups');
380
+ await mkdir(backupDir, { recursive: true });
381
+ const content = await readFile(source);
382
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-');
383
+ const target = join(backupDir, `aiwg.config.permissions-${stamp}.bak`);
384
+ await copyFile(source, target);
385
+ // Ensure the source remained readable before the caller atomically replaces it.
386
+ if (!content.length)
387
+ throw new Error('Refusing to migrate an empty aiwg.config');
388
+ return target;
389
+ }
390
+ //# sourceMappingURL=authorization.js.map
@@ -0,0 +1,215 @@
1
+ import { existsSync, readFileSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { dirname, isAbsolute, join, relative, resolve } from 'path';
4
+ import { load as loadYaml } from 'js-yaml';
5
+ import { WORKSPACE_REPO_ACTIONS, } from '../config/aiwg-config.js';
6
+ import { resolveProjectAiwgDir } from '../config/project-artifacts.js';
7
+ export const REPO_ACCESS_MANIFEST_PATHS = [
8
+ '.aiwg/ops/security/repo-access.manifest.yaml',
9
+ '.aiwg/security/repo-access.manifest.yaml',
10
+ ];
11
+ export const REPO_ACCESS_ACTIONS = [
12
+ ...WORKSPACE_REPO_ACTIONS,
13
+ ];
14
+ const ACTION_SET = new Set(REPO_ACCESS_ACTIONS);
15
+ function isObject(value) {
16
+ return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
17
+ }
18
+ function findProjectRootFromManifest(manifestPath) {
19
+ const normalized = manifestPath.replace(/\\/g, '/');
20
+ if (normalized.endsWith('/.aiwg/aiwg.config')) {
21
+ return resolve(dirname(manifestPath), '..');
22
+ }
23
+ if (normalized.endsWith('/.aiwg/ops/security/repo-access.manifest.yaml')) {
24
+ return resolve(dirname(manifestPath), '..', '..', '..');
25
+ }
26
+ if (normalized.endsWith('/.aiwg/security/repo-access.manifest.yaml')) {
27
+ return resolve(dirname(manifestPath), '..', '..');
28
+ }
29
+ return resolve(dirname(manifestPath));
30
+ }
31
+ export function findRepoAccessManifest(startDir = process.cwd()) {
32
+ const explicitWorkspace = process.env.AIWG_WORKSPACE;
33
+ if (explicitWorkspace) {
34
+ const expanded = explicitWorkspace === '~'
35
+ ? homedir()
36
+ : explicitWorkspace.startsWith('~/') || explicitWorkspace.startsWith('~\\')
37
+ ? resolve(homedir(), explicitWorkspace.slice(2))
38
+ : explicitWorkspace;
39
+ const explicitConfig = join(resolveProjectAiwgDir(expanded), 'aiwg.config');
40
+ if (existsSync(explicitConfig)) {
41
+ const parsed = JSON.parse(readFileSync(explicitConfig, 'utf8'));
42
+ if (Array.isArray(parsed.repos))
43
+ return explicitConfig;
44
+ }
45
+ }
46
+ let current = resolve(startDir);
47
+ while (true) {
48
+ const workspaceConfig = join(resolveProjectAiwgDir(current), 'aiwg.config');
49
+ if (existsSync(workspaceConfig)) {
50
+ try {
51
+ const parsed = JSON.parse(readFileSync(workspaceConfig, 'utf8'));
52
+ if (Array.isArray(parsed.repos))
53
+ return workspaceConfig;
54
+ if (isObject(parsed.workspace) && typeof parsed.workspace.member_of === 'string') {
55
+ const memberOf = parsed.workspace.member_of;
56
+ const expanded = memberOf === '~'
57
+ ? homedir()
58
+ : memberOf.startsWith('~/') || memberOf.startsWith('~\\')
59
+ ? resolve(homedir(), memberOf.slice(2))
60
+ : memberOf;
61
+ const workspaceRoot = isAbsolute(expanded)
62
+ ? resolve(expanded)
63
+ : resolve(current, expanded);
64
+ const parentConfig = join(resolveProjectAiwgDir(workspaceRoot), 'aiwg.config');
65
+ if (existsSync(parentConfig)) {
66
+ const parent = JSON.parse(readFileSync(parentConfig, 'utf8'));
67
+ if (Array.isArray(parent.repos))
68
+ return parentConfig;
69
+ }
70
+ }
71
+ }
72
+ catch {
73
+ // Fail closed: a malformed nearer config must not silently fall through
74
+ // to a broader legacy authorization manifest.
75
+ return workspaceConfig;
76
+ }
77
+ }
78
+ for (const manifestRel of REPO_ACCESS_MANIFEST_PATHS) {
79
+ const candidate = resolve(current, manifestRel);
80
+ if (existsSync(candidate))
81
+ return candidate;
82
+ }
83
+ const parent = dirname(current);
84
+ if (parent === current)
85
+ return null;
86
+ current = parent;
87
+ }
88
+ }
89
+ function normalizeAction(action) {
90
+ if (typeof action !== 'string' || !ACTION_SET.has(action)) {
91
+ throw new Error(`Invalid repo access action: ${String(action)}`);
92
+ }
93
+ return action;
94
+ }
95
+ function normalizeRepoEntry(entry, index, projectRoot) {
96
+ if (!isObject(entry))
97
+ throw new Error(`repos[${index}] must be an object`);
98
+ const name = entry.name;
99
+ const repoPath = entry.path;
100
+ const rawActions = entry.allowed ?? entry.actions ?? entry.permissions;
101
+ if (typeof name !== 'string' || !name.trim()) {
102
+ throw new Error(`repos[${index}].name is required`);
103
+ }
104
+ if (typeof repoPath !== 'string' || !repoPath.trim()) {
105
+ throw new Error(`repos[${index}].path is required`);
106
+ }
107
+ if (!Array.isArray(rawActions) || rawActions.length === 0) {
108
+ throw new Error(`repos[${index}].actions must be a non-empty array`);
109
+ }
110
+ const resolvedPath = isAbsolute(repoPath)
111
+ ? resolve(repoPath)
112
+ : resolve(projectRoot, repoPath);
113
+ return {
114
+ name: name.trim(),
115
+ path: resolvedPath,
116
+ actions: rawActions.map(normalizeAction),
117
+ provider: ['gitea', 'github', 'gitlab'].includes(String(entry.provider))
118
+ ? entry.provider
119
+ : undefined,
120
+ notes: typeof entry.notes === 'string' ? entry.notes : undefined,
121
+ };
122
+ }
123
+ export function loadRepoAccessManifest(startDir = process.cwd()) {
124
+ const manifestPath = findRepoAccessManifest(startDir);
125
+ if (!manifestPath) {
126
+ throw new Error(`Repo access manifest not found. Expected ${REPO_ACCESS_MANIFEST_PATHS.join(' or ')}`);
127
+ }
128
+ const workspaceProjectRoot = findProjectRootFromManifest(manifestPath);
129
+ const isWorkspaceConfig = manifestPath.endsWith('/.aiwg/aiwg.config')
130
+ || manifestPath.endsWith('\\.aiwg\\aiwg.config');
131
+ const raw = isWorkspaceConfig
132
+ ? JSON.parse(readFileSync(manifestPath, 'utf8'))
133
+ : loadYaml(readFileSync(manifestPath, 'utf8'));
134
+ if (!isObject(raw))
135
+ throw new Error('Repo access manifest must be an object');
136
+ const repos = raw.repos;
137
+ if (!Array.isArray(repos))
138
+ throw new Error('repo access manifest requires repos: []');
139
+ const defaultPolicy = raw.defaultPolicy ?? raw.default_policy ?? 'deny';
140
+ if (defaultPolicy !== 'deny') {
141
+ throw new Error('repo access manifest default policy must be deny');
142
+ }
143
+ const workspace = isObject(raw.workspace) ? raw.workspace : undefined;
144
+ const configuredRoot = workspace && typeof workspace.root === 'string'
145
+ ? workspace.root
146
+ : undefined;
147
+ const expandedRoot = configuredRoot === '~'
148
+ ? homedir()
149
+ : configuredRoot?.startsWith('~/') || configuredRoot?.startsWith('~\\')
150
+ ? resolve(homedir(), configuredRoot.slice(2))
151
+ : configuredRoot;
152
+ const projectRoot = expandedRoot
153
+ ? isAbsolute(expandedRoot)
154
+ ? resolve(expandedRoot)
155
+ : resolve(workspaceProjectRoot, expandedRoot)
156
+ : workspaceProjectRoot;
157
+ return {
158
+ version: typeof raw.version === 'string' ? raw.version : '1',
159
+ path: manifestPath,
160
+ source: isWorkspaceConfig ? 'workspace-config' : 'legacy-manifest',
161
+ workspaceProjectRoot,
162
+ projectRoot,
163
+ workspaceName: workspace && typeof workspace.name === 'string'
164
+ ? workspace.name
165
+ : undefined,
166
+ defaultPolicy: 'deny',
167
+ repos: repos.map((entry, index) => normalizeRepoEntry(entry, index, projectRoot)),
168
+ };
169
+ }
170
+ function isSameOrInside(candidate, root) {
171
+ const rel = relative(root, candidate);
172
+ return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
173
+ }
174
+ export function findRepoEntry(manifest, requestedPath, cwd = process.cwd()) {
175
+ const resolved = isAbsolute(requestedPath) ? resolve(requestedPath) : resolve(cwd, requestedPath);
176
+ const matches = manifest.repos
177
+ .filter((entry) => isSameOrInside(resolved, entry.path))
178
+ .sort((a, b) => b.path.length - a.path.length);
179
+ return matches[0] ?? null;
180
+ }
181
+ export function checkRepoAccess(manifest, requestedPath, action, cwd = process.cwd()) {
182
+ const normalizedAction = normalizeAction(action);
183
+ const resolved = isAbsolute(requestedPath) ? resolve(requestedPath) : resolve(cwd, requestedPath);
184
+ const matchedRepo = findRepoEntry(manifest, resolved, cwd);
185
+ if (!matchedRepo) {
186
+ return {
187
+ allowed: false,
188
+ action: normalizedAction,
189
+ requestedPath: resolved,
190
+ matchedRepo: null,
191
+ reason: 'unlisted repo/path defaults to denied',
192
+ };
193
+ }
194
+ if (!matchedRepo.actions.includes(normalizedAction)) {
195
+ return {
196
+ allowed: false,
197
+ action: normalizedAction,
198
+ requestedPath: resolved,
199
+ matchedRepo,
200
+ reason: `repo '${matchedRepo.name}' does not allow ${normalizedAction}`,
201
+ };
202
+ }
203
+ return {
204
+ allowed: true,
205
+ action: normalizedAction,
206
+ requestedPath: resolved,
207
+ matchedRepo,
208
+ reason: `repo '${matchedRepo.name}' allows ${normalizedAction}`,
209
+ };
210
+ }
211
+ export function formatRepoAccessEntry(entry) {
212
+ const notes = entry.notes ? ` — ${entry.notes}` : '';
213
+ return `${entry.name}: ${entry.path} [${entry.actions.join(', ')}]${notes}`;
214
+ }
215
+ //# sourceMappingURL=repo-access.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Provenance CLI — `aiwg provenance <subcommand>`
3
+ *
4
+ * Thin wrapper around `runSubsystemCli('provenance', ...)`. Used by
5
+ * provenance-create / provenance-query / provenance-report /
6
+ * provenance-validate / auto-provenance skills (#968) so W3C PROV
7
+ * records honor `.aiwg/storage.config` redirection.
8
+ *
9
+ * @issue #934
10
+ * @issue #968
11
+ */
12
+ import { runSubsystemCli } from '../storage/subsystem-cli.js';
13
+ export async function main(args) {
14
+ await runSubsystemCli('provenance', args);
15
+ }
16
+ //# sourceMappingURL=cli.js.map