@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,263 @@
1
+ /**
2
+ * MCP Profile Registry (TypeScript)
3
+ *
4
+ * Named, ordered subsets of registered MCP servers.
5
+ * Stored in ~/.aiwg/mcp-profiles.json.
6
+ *
7
+ * This module is used for type checking and vitest.
8
+ * profiles.mjs is the runtime ESM version used by cli.mjs.
9
+ *
10
+ * @implements #889
11
+ */
12
+ import { readFile, writeFile, mkdir } from 'fs/promises';
13
+ import { resolve } from 'path';
14
+ import { resolveConfigDir } from '../config/user-config.js';
15
+ // ─────────────────────────────────────────────
16
+ // Constants
17
+ // ─────────────────────────────────────────────
18
+ const PROFILES_FILENAME = 'mcp-profiles.json';
19
+ const RESERVED_NAMES = new Set(['all', 'none', 'default']);
20
+ const NAME_RE = /^[a-z0-9-]+$/;
21
+ const DEFAULT_DATA = {
22
+ apiVersion: 'aiwg.io/v1',
23
+ kind: 'McpProfileRegistry',
24
+ profiles: {},
25
+ };
26
+ // ─────────────────────────────────────────────
27
+ // Preset profiles
28
+ // ─────────────────────────────────────────────
29
+ export const PRESET_PROFILES = {
30
+ minimal: {
31
+ description: 'Minimal toolset for smoke tests (~6K token budget)',
32
+ servers: [],
33
+ providerOverrides: {},
34
+ },
35
+ dev: {
36
+ description: 'Code editing + git + memory (~12K token budget)',
37
+ servers: ['git-gitea', 'codeindex-codehound', 'memory-fortemi'],
38
+ providerOverrides: {
39
+ codex: { toolDeny: ['git-gitea__delete_*', 'git-gitea__actions_config_write'] },
40
+ },
41
+ },
42
+ ops: {
43
+ description: 'Infra + git + CMDB operations (~14K token budget)',
44
+ servers: ['git-gitea', 'cmdb-itassets', 'memory-fortemi'],
45
+ providerOverrides: {},
46
+ },
47
+ research: {
48
+ description: 'Documentation + memory + calendar (~10K token budget)',
49
+ servers: ['memory-fortemi', 'claude_ai_Google_Drive', 'claude_ai_Google_Calendar'],
50
+ providerOverrides: {},
51
+ },
52
+ incident: {
53
+ description: 'Incident response — git + CMDB + memory (~16K token budget)',
54
+ servers: ['git-gitea', 'cmdb-itassets', 'memory-fortemi', 'codeindex-codehound'],
55
+ providerOverrides: {},
56
+ },
57
+ full: {
58
+ description: 'All registered servers — for exploration (~21K token budget)',
59
+ servers: ['__all__'],
60
+ providerOverrides: {},
61
+ },
62
+ };
63
+ // ─────────────────────────────────────────────
64
+ // Registry class
65
+ // ─────────────────────────────────────────────
66
+ export class McpProfileRegistry {
67
+ configDir;
68
+ cache = null;
69
+ constructor(configDirOverride) {
70
+ this.configDir = resolveConfigDir(configDirOverride);
71
+ }
72
+ getPath() {
73
+ return resolve(this.configDir, PROFILES_FILENAME);
74
+ }
75
+ async load() {
76
+ if (this.cache)
77
+ return this.cache;
78
+ const filePath = this.getPath();
79
+ try {
80
+ const content = await readFile(filePath, 'utf-8');
81
+ const parsed = JSON.parse(content);
82
+ this.cache = {
83
+ ...DEFAULT_DATA,
84
+ ...parsed,
85
+ profiles: parsed.profiles || {},
86
+ };
87
+ }
88
+ catch {
89
+ this.cache = { ...DEFAULT_DATA, profiles: {} };
90
+ }
91
+ return this.cache;
92
+ }
93
+ async save() {
94
+ if (!this.cache)
95
+ return;
96
+ await mkdir(this.configDir, { recursive: true });
97
+ await writeFile(this.getPath(), JSON.stringify(this.cache, null, 2) + '\n', 'utf-8');
98
+ }
99
+ validateName(name) {
100
+ if (!NAME_RE.test(name)) {
101
+ throw new Error(`Invalid profile name "${name}". Names must match [a-z0-9-]+.`);
102
+ }
103
+ if (RESERVED_NAMES.has(name)) {
104
+ throw new Error(`"${name}" is a reserved profile name. Choose a different name.`);
105
+ }
106
+ }
107
+ async validateServers(serverNames, serverRegistry) {
108
+ if (!serverRegistry)
109
+ return;
110
+ const missing = [];
111
+ for (const name of serverNames) {
112
+ if (name === '__all__')
113
+ continue;
114
+ const server = await serverRegistry.get(name);
115
+ if (!server)
116
+ missing.push(name);
117
+ }
118
+ if (missing.length > 0) {
119
+ throw new Error(`Server(s) not found in registry: ${missing.join(', ')}.\n` +
120
+ `Use "aiwg mcp list" to see registered servers.`);
121
+ }
122
+ }
123
+ async add(profile, serverRegistry) {
124
+ this.validateName(profile.name);
125
+ const data = await this.load();
126
+ if (data.profiles[profile.name]) {
127
+ throw new Error(`Profile "${profile.name}" already exists. Use "aiwg mcp profile edit" to modify it.`);
128
+ }
129
+ await this.validateServers(profile.servers ?? [], serverRegistry);
130
+ data.profiles[profile.name] = {
131
+ ...profile,
132
+ servers: profile.servers ?? [],
133
+ providerOverrides: profile.providerOverrides ?? {},
134
+ createdAt: new Date().toISOString(),
135
+ updatedAt: new Date().toISOString(),
136
+ };
137
+ await this.save();
138
+ }
139
+ async get(name) {
140
+ const data = await this.load();
141
+ return data.profiles[name];
142
+ }
143
+ async list() {
144
+ const data = await this.load();
145
+ return Object.values(data.profiles);
146
+ }
147
+ async edit(name, changes, serverRegistry) {
148
+ const data = await this.load();
149
+ const existing = data.profiles[name];
150
+ if (!existing)
151
+ throw new Error(`Profile "${name}" not found.`);
152
+ const current = { ...existing, servers: [...existing.servers] };
153
+ if (changes.description !== undefined)
154
+ current.description = changes.description;
155
+ if (changes.addServers && changes.addServers.length > 0) {
156
+ await this.validateServers(changes.addServers, serverRegistry);
157
+ for (const s of changes.addServers) {
158
+ if (!current.servers.includes(s))
159
+ current.servers.push(s);
160
+ }
161
+ }
162
+ if (changes.removeServers && changes.removeServers.length > 0) {
163
+ current.servers = current.servers.filter((s) => !(changes.removeServers ?? []).includes(s));
164
+ }
165
+ current.updatedAt = new Date().toISOString();
166
+ data.profiles[name] = current;
167
+ await this.save();
168
+ return data.profiles[name];
169
+ }
170
+ async remove(name) {
171
+ const data = await this.load();
172
+ if (!data.profiles[name])
173
+ throw new Error(`Profile "${name}" not found.`);
174
+ delete data.profiles[name];
175
+ await this.save();
176
+ }
177
+ async resolveServers(name, serverRegistry) {
178
+ const profile = await this.get(name);
179
+ if (!profile)
180
+ throw new Error(`Profile "${name}" not found.`);
181
+ if (profile.servers.includes('__all__') && serverRegistry) {
182
+ return serverRegistry.list();
183
+ }
184
+ if (!serverRegistry)
185
+ return profile.servers;
186
+ const resolved = [];
187
+ for (const serverName of profile.servers) {
188
+ const server = await serverRegistry.get(serverName);
189
+ if (server)
190
+ resolved.push(server);
191
+ }
192
+ return resolved;
193
+ }
194
+ async importFrom(filePath) {
195
+ const content = await readFile(filePath, 'utf-8');
196
+ const imported = JSON.parse(content);
197
+ const data = await this.load();
198
+ let added = 0;
199
+ let updated = 0;
200
+ const profiles = imported.profiles ?? {};
201
+ for (const [name, profile] of Object.entries(profiles)) {
202
+ try {
203
+ this.validateName(name);
204
+ }
205
+ catch {
206
+ continue;
207
+ }
208
+ if (data.profiles[name]) {
209
+ data.profiles[name] = {
210
+ ...data.profiles[name],
211
+ ...profile,
212
+ name,
213
+ updatedAt: new Date().toISOString(),
214
+ };
215
+ updated++;
216
+ }
217
+ else {
218
+ data.profiles[name] = {
219
+ name,
220
+ description: profile.description,
221
+ servers: profile.servers ?? [],
222
+ providerOverrides: profile.providerOverrides ?? {},
223
+ createdAt: new Date().toISOString(),
224
+ updatedAt: new Date().toISOString(),
225
+ };
226
+ added++;
227
+ }
228
+ }
229
+ await this.save();
230
+ return { added, updated };
231
+ }
232
+ async exportTo(filePath, profileName) {
233
+ const data = await this.load();
234
+ if (profileName && !data.profiles[profileName]) {
235
+ throw new Error(`Profile "${profileName}" not found.`);
236
+ }
237
+ const toExport = profileName
238
+ ? { [profileName]: data.profiles[profileName] }
239
+ : data.profiles;
240
+ await writeFile(filePath, JSON.stringify({ profiles: toExport }, null, 2) + '\n', 'utf-8');
241
+ }
242
+ async initPresets() {
243
+ const data = await this.load();
244
+ let added = 0;
245
+ for (const [name, preset] of Object.entries(PRESET_PROFILES)) {
246
+ if (!data.profiles[name]) {
247
+ data.profiles[name] = {
248
+ name,
249
+ ...preset,
250
+ createdAt: new Date().toISOString(),
251
+ updatedAt: new Date().toISOString(),
252
+ };
253
+ added++;
254
+ }
255
+ }
256
+ await this.save();
257
+ return { added, total: Object.keys(PRESET_PROFILES).length };
258
+ }
259
+ clearCache() {
260
+ this.cache = null;
261
+ }
262
+ }
263
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1,360 @@
1
+ /**
2
+ * MCP Profile Registry (Runtime ESM)
3
+ *
4
+ * Named, ordered subsets of registered MCP servers.
5
+ * Stored in ~/.aiwg/mcp-profiles.json.
6
+ *
7
+ * This is the runtime .mjs version used by cli.mjs.
8
+ * profiles.ts exists for type checking and vitest.
9
+ *
10
+ * @implements #889
11
+ */
12
+
13
+ import { readFile, writeFile, mkdir } from 'fs/promises';
14
+ import { resolve } from 'path';
15
+ import { homedir } from 'os';
16
+ import { existsSync } from 'fs';
17
+
18
+ // ─────────────────────────────────────────────
19
+ // Config dir resolution (mirrors registry.mjs)
20
+ // ─────────────────────────────────────────────
21
+
22
+ function resolveConfigDir(overridePath) {
23
+ const envOverride = process.env.AIWG_CONFIG;
24
+ if (overridePath) return resolve(overridePath);
25
+ if (envOverride) return resolve(envOverride);
26
+
27
+ const primary = resolve(homedir(), '.aiwg');
28
+ if (existsSync(primary)) return primary;
29
+
30
+ const fallback = resolve(homedir(), '.config/aiwg');
31
+ if (existsSync(fallback)) return fallback;
32
+
33
+ return primary;
34
+ }
35
+
36
+ // ─────────────────────────────────────────────
37
+ // Constants
38
+ // ─────────────────────────────────────────────
39
+
40
+ const PROFILES_FILENAME = 'mcp-profiles.json';
41
+
42
+ const RESERVED_NAMES = new Set(['all', 'none', 'default']);
43
+ const NAME_RE = /^[a-z0-9-]+$/;
44
+
45
+ const DEFAULT_DATA = {
46
+ apiVersion: 'aiwg.io/v1',
47
+ kind: 'McpProfileRegistry',
48
+ profiles: {},
49
+ };
50
+
51
+ // ─────────────────────────────────────────────
52
+ // Preset profiles
53
+ // ─────────────────────────────────────────────
54
+
55
+ export const PRESET_PROFILES = {
56
+ minimal: {
57
+ description: 'Minimal toolset for smoke tests (~6K token budget)',
58
+ servers: [],
59
+ providerOverrides: {},
60
+ },
61
+ dev: {
62
+ description: 'Code editing + git + memory (~12K token budget)',
63
+ servers: ['git-gitea', 'codeindex-codehound', 'memory-fortemi'],
64
+ providerOverrides: {
65
+ codex: { toolDeny: ['git-gitea__delete_*', 'git-gitea__actions_config_write'] },
66
+ },
67
+ },
68
+ ops: {
69
+ description: 'Infra + git + CMDB operations (~14K token budget)',
70
+ servers: ['git-gitea', 'cmdb-itassets', 'memory-fortemi'],
71
+ providerOverrides: {},
72
+ },
73
+ research: {
74
+ description: 'Documentation + memory + calendar (~10K token budget)',
75
+ servers: ['memory-fortemi', 'claude_ai_Google_Drive', 'claude_ai_Google_Calendar'],
76
+ providerOverrides: {},
77
+ },
78
+ incident: {
79
+ description: 'Incident response — git + CMDB + memory (~16K token budget)',
80
+ servers: ['git-gitea', 'cmdb-itassets', 'memory-fortemi', 'codeindex-codehound'],
81
+ providerOverrides: {},
82
+ },
83
+ full: {
84
+ description: 'All registered servers — for exploration (~21K token budget)',
85
+ servers: ['__all__'],
86
+ providerOverrides: {},
87
+ },
88
+ };
89
+
90
+ // ─────────────────────────────────────────────
91
+ // Registry class
92
+ // ─────────────────────────────────────────────
93
+
94
+ export class McpProfileRegistry {
95
+ #configDir;
96
+ #cache = null;
97
+
98
+ constructor(configDirOverride) {
99
+ this.#configDir = resolveConfigDir(configDirOverride);
100
+ }
101
+
102
+ getPath() {
103
+ return resolve(this.#configDir, PROFILES_FILENAME);
104
+ }
105
+
106
+ async load() {
107
+ if (this.#cache) return this.#cache;
108
+
109
+ const filePath = this.getPath();
110
+ try {
111
+ const content = await readFile(filePath, 'utf-8');
112
+ const parsed = JSON.parse(content);
113
+ this.#cache = {
114
+ ...DEFAULT_DATA,
115
+ ...parsed,
116
+ profiles: parsed.profiles || {},
117
+ };
118
+ } catch {
119
+ this.#cache = { ...DEFAULT_DATA, profiles: {} };
120
+ }
121
+
122
+ return this.#cache;
123
+ }
124
+
125
+ async save() {
126
+ if (!this.#cache) return;
127
+ await mkdir(this.#configDir, { recursive: true });
128
+ await writeFile(
129
+ this.getPath(),
130
+ JSON.stringify(this.#cache, null, 2) + '\n',
131
+ 'utf-8',
132
+ );
133
+ }
134
+
135
+ /**
136
+ * Validate a profile name. Throws on invalid.
137
+ */
138
+ #validateName(name) {
139
+ if (!NAME_RE.test(name)) {
140
+ throw new Error(
141
+ `Invalid profile name "${name}". Names must match [a-z0-9-]+.`,
142
+ );
143
+ }
144
+ if (RESERVED_NAMES.has(name)) {
145
+ throw new Error(
146
+ `"${name}" is a reserved profile name. Choose a different name.`,
147
+ );
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Validate that all server names exist in the server registry.
153
+ * Skip validation for the special '__all__' sentinel.
154
+ */
155
+ async #validateServers(serverNames, serverRegistry) {
156
+ if (!serverRegistry) return; // skip if no registry provided
157
+ const missing = [];
158
+ for (const name of serverNames) {
159
+ if (name === '__all__') continue;
160
+ const server = await serverRegistry.get(name);
161
+ if (!server) missing.push(name);
162
+ }
163
+ if (missing.length > 0) {
164
+ throw new Error(
165
+ `Server(s) not found in registry: ${missing.join(', ')}.\n` +
166
+ `Use "aiwg mcp list" to see registered servers.`,
167
+ );
168
+ }
169
+ }
170
+
171
+ /** Add a new profile */
172
+ async add(profile, serverRegistry) {
173
+ this.#validateName(profile.name);
174
+ const data = await this.load();
175
+
176
+ if (data.profiles[profile.name]) {
177
+ throw new Error(
178
+ `Profile "${profile.name}" already exists. Use "aiwg mcp profile edit" to modify it.`,
179
+ );
180
+ }
181
+
182
+ await this.#validateServers(profile.servers ?? [], serverRegistry);
183
+
184
+ data.profiles[profile.name] = {
185
+ name: profile.name,
186
+ description: profile.description,
187
+ servers: profile.servers ?? [],
188
+ providerOverrides: profile.providerOverrides ?? {},
189
+ createdAt: new Date().toISOString(),
190
+ updatedAt: new Date().toISOString(),
191
+ };
192
+
193
+ await this.save();
194
+ }
195
+
196
+ /** Get a profile by name */
197
+ async get(name) {
198
+ const data = await this.load();
199
+ return data.profiles[name];
200
+ }
201
+
202
+ /** List all profiles */
203
+ async list() {
204
+ const data = await this.load();
205
+ return Object.values(data.profiles);
206
+ }
207
+
208
+ /** Edit an existing profile (add/remove servers, update description) */
209
+ async edit(name, changes, serverRegistry) {
210
+ const data = await this.load();
211
+ const existing = data.profiles[name];
212
+ if (!existing) {
213
+ throw new Error(`Profile "${name}" not found.`);
214
+ }
215
+
216
+ const current = { ...existing };
217
+
218
+ if (changes.description !== undefined) {
219
+ current.description = changes.description;
220
+ }
221
+
222
+ if (changes.addServers && changes.addServers.length > 0) {
223
+ await this.#validateServers(changes.addServers, serverRegistry);
224
+ for (const s of changes.addServers) {
225
+ if (!current.servers.includes(s)) current.servers.push(s);
226
+ }
227
+ }
228
+
229
+ if (changes.removeServers && changes.removeServers.length > 0) {
230
+ current.servers = current.servers.filter(
231
+ (s) => !changes.removeServers.includes(s),
232
+ );
233
+ }
234
+
235
+ current.updatedAt = new Date().toISOString();
236
+ data.profiles[name] = current;
237
+ await this.save();
238
+ return data.profiles[name];
239
+ }
240
+
241
+ /** Remove a profile */
242
+ async remove(name) {
243
+ const data = await this.load();
244
+ if (!data.profiles[name]) {
245
+ throw new Error(`Profile "${name}" not found.`);
246
+ }
247
+ delete data.profiles[name];
248
+ await this.save();
249
+ }
250
+
251
+ /**
252
+ * Resolve the effective server list for a profile.
253
+ * If the profile contains '__all__', expand to all servers in serverRegistry.
254
+ */
255
+ async resolveServers(name, serverRegistry) {
256
+ const profile = await this.get(name);
257
+ if (!profile) {
258
+ throw new Error(`Profile "${name}" not found.`);
259
+ }
260
+
261
+ if (profile.servers.includes('__all__') && serverRegistry) {
262
+ return serverRegistry.list();
263
+ }
264
+
265
+ if (!serverRegistry) return profile.servers;
266
+
267
+ const resolved = [];
268
+ for (const serverName of profile.servers) {
269
+ const server = await serverRegistry.get(serverName);
270
+ if (server) resolved.push(server);
271
+ }
272
+ return resolved;
273
+ }
274
+
275
+ /** Import profiles from a JSON file */
276
+ async importFrom(filePath) {
277
+ const content = await readFile(filePath, 'utf-8');
278
+ const imported = JSON.parse(content);
279
+ const data = await this.load();
280
+
281
+ let added = 0;
282
+ let updated = 0;
283
+
284
+ const profiles = imported.profiles ?? (
285
+ typeof imported === 'object' && !Array.isArray(imported)
286
+ ? imported
287
+ : {}
288
+ );
289
+
290
+ for (const [name, profile] of Object.entries(profiles)) {
291
+ try {
292
+ this.#validateName(name);
293
+ } catch {
294
+ continue; // skip invalid names silently during import
295
+ }
296
+ if (data.profiles[name]) {
297
+ data.profiles[name] = {
298
+ ...data.profiles[name],
299
+ ...profile,
300
+ name,
301
+ updatedAt: new Date().toISOString(),
302
+ };
303
+ updated++;
304
+ } else {
305
+ data.profiles[name] = {
306
+ name,
307
+ description: profile.description,
308
+ servers: profile.servers ?? [],
309
+ providerOverrides: profile.providerOverrides ?? {},
310
+ createdAt: new Date().toISOString(),
311
+ updatedAt: new Date().toISOString(),
312
+ };
313
+ added++;
314
+ }
315
+ }
316
+
317
+ await this.save();
318
+ return { added, updated };
319
+ }
320
+
321
+ /** Export a profile (or all profiles) to a JSON file */
322
+ async exportTo(filePath, profileName) {
323
+ const data = await this.load();
324
+
325
+ const toExport = profileName
326
+ ? { [profileName]: data.profiles[profileName] }
327
+ : data.profiles;
328
+
329
+ if (profileName && !data.profiles[profileName]) {
330
+ throw new Error(`Profile "${profileName}" not found.`);
331
+ }
332
+
333
+ await writeFile(filePath, JSON.stringify({ profiles: toExport }, null, 2) + '\n', 'utf-8');
334
+ }
335
+
336
+ /** Install preset profiles (does not overwrite existing) */
337
+ async initPresets() {
338
+ const data = await this.load();
339
+ let added = 0;
340
+
341
+ for (const [name, preset] of Object.entries(PRESET_PROFILES)) {
342
+ if (!data.profiles[name]) {
343
+ data.profiles[name] = {
344
+ name,
345
+ ...preset,
346
+ createdAt: new Date().toISOString(),
347
+ updatedAt: new Date().toISOString(),
348
+ };
349
+ added++;
350
+ }
351
+ }
352
+
353
+ await this.save();
354
+ return { added, total: Object.keys(PRESET_PROFILES).length };
355
+ }
356
+
357
+ clearCache() {
358
+ this.#cache = null;
359
+ }
360
+ }