@dotsetlabs/bellwether 0.10.0

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 (403) hide show
  1. package/CHANGELOG.md +291 -0
  2. package/LICENSE +21 -0
  3. package/README.md +739 -0
  4. package/dist/auth/credentials.d.ts +64 -0
  5. package/dist/auth/credentials.js +218 -0
  6. package/dist/auth/index.d.ts +6 -0
  7. package/dist/auth/index.js +6 -0
  8. package/dist/auth/keychain.d.ts +64 -0
  9. package/dist/auth/keychain.js +268 -0
  10. package/dist/baseline/ab-testing.d.ts +80 -0
  11. package/dist/baseline/ab-testing.js +236 -0
  12. package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
  13. package/dist/baseline/ai-compatibility-scorer.js +606 -0
  14. package/dist/baseline/calibration.d.ts +77 -0
  15. package/dist/baseline/calibration.js +136 -0
  16. package/dist/baseline/category-matching.d.ts +85 -0
  17. package/dist/baseline/category-matching.js +289 -0
  18. package/dist/baseline/change-impact-analyzer.d.ts +98 -0
  19. package/dist/baseline/change-impact-analyzer.js +592 -0
  20. package/dist/baseline/comparator.d.ts +64 -0
  21. package/dist/baseline/comparator.js +916 -0
  22. package/dist/baseline/confidence.d.ts +55 -0
  23. package/dist/baseline/confidence.js +122 -0
  24. package/dist/baseline/converter.d.ts +61 -0
  25. package/dist/baseline/converter.js +585 -0
  26. package/dist/baseline/dependency-analyzer.d.ts +89 -0
  27. package/dist/baseline/dependency-analyzer.js +567 -0
  28. package/dist/baseline/deprecation-tracker.d.ts +133 -0
  29. package/dist/baseline/deprecation-tracker.js +322 -0
  30. package/dist/baseline/diff.d.ts +55 -0
  31. package/dist/baseline/diff.js +1584 -0
  32. package/dist/baseline/documentation-scorer.d.ts +205 -0
  33. package/dist/baseline/documentation-scorer.js +466 -0
  34. package/dist/baseline/embeddings.d.ts +118 -0
  35. package/dist/baseline/embeddings.js +251 -0
  36. package/dist/baseline/error-analyzer.d.ts +198 -0
  37. package/dist/baseline/error-analyzer.js +721 -0
  38. package/dist/baseline/evaluation/evaluator.d.ts +42 -0
  39. package/dist/baseline/evaluation/evaluator.js +323 -0
  40. package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
  41. package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
  42. package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
  43. package/dist/baseline/evaluation/golden-dataset.js +717 -0
  44. package/dist/baseline/evaluation/index.d.ts +15 -0
  45. package/dist/baseline/evaluation/index.js +15 -0
  46. package/dist/baseline/evaluation/types.d.ts +186 -0
  47. package/dist/baseline/evaluation/types.js +8 -0
  48. package/dist/baseline/external-dependency-detector.d.ts +181 -0
  49. package/dist/baseline/external-dependency-detector.js +524 -0
  50. package/dist/baseline/golden-output.d.ts +162 -0
  51. package/dist/baseline/golden-output.js +636 -0
  52. package/dist/baseline/health-scorer.d.ts +174 -0
  53. package/dist/baseline/health-scorer.js +451 -0
  54. package/dist/baseline/incremental-checker.d.ts +97 -0
  55. package/dist/baseline/incremental-checker.js +174 -0
  56. package/dist/baseline/index.d.ts +31 -0
  57. package/dist/baseline/index.js +42 -0
  58. package/dist/baseline/migration-generator.d.ts +137 -0
  59. package/dist/baseline/migration-generator.js +554 -0
  60. package/dist/baseline/migrations.d.ts +60 -0
  61. package/dist/baseline/migrations.js +197 -0
  62. package/dist/baseline/performance-tracker.d.ts +214 -0
  63. package/dist/baseline/performance-tracker.js +577 -0
  64. package/dist/baseline/pr-comment-generator.d.ts +117 -0
  65. package/dist/baseline/pr-comment-generator.js +546 -0
  66. package/dist/baseline/response-fingerprint.d.ts +127 -0
  67. package/dist/baseline/response-fingerprint.js +728 -0
  68. package/dist/baseline/response-schema-tracker.d.ts +129 -0
  69. package/dist/baseline/response-schema-tracker.js +420 -0
  70. package/dist/baseline/risk-scorer.d.ts +54 -0
  71. package/dist/baseline/risk-scorer.js +434 -0
  72. package/dist/baseline/saver.d.ts +89 -0
  73. package/dist/baseline/saver.js +554 -0
  74. package/dist/baseline/scenario-generator.d.ts +151 -0
  75. package/dist/baseline/scenario-generator.js +905 -0
  76. package/dist/baseline/schema-compare.d.ts +86 -0
  77. package/dist/baseline/schema-compare.js +557 -0
  78. package/dist/baseline/schema-evolution.d.ts +189 -0
  79. package/dist/baseline/schema-evolution.js +467 -0
  80. package/dist/baseline/semantic.d.ts +203 -0
  81. package/dist/baseline/semantic.js +908 -0
  82. package/dist/baseline/synonyms.d.ts +60 -0
  83. package/dist/baseline/synonyms.js +386 -0
  84. package/dist/baseline/telemetry.d.ts +165 -0
  85. package/dist/baseline/telemetry.js +294 -0
  86. package/dist/baseline/test-pruner.d.ts +120 -0
  87. package/dist/baseline/test-pruner.js +387 -0
  88. package/dist/baseline/types.d.ts +449 -0
  89. package/dist/baseline/types.js +5 -0
  90. package/dist/baseline/version.d.ts +138 -0
  91. package/dist/baseline/version.js +206 -0
  92. package/dist/cache/index.d.ts +5 -0
  93. package/dist/cache/index.js +5 -0
  94. package/dist/cache/response-cache.d.ts +151 -0
  95. package/dist/cache/response-cache.js +287 -0
  96. package/dist/ci/index.d.ts +60 -0
  97. package/dist/ci/index.js +342 -0
  98. package/dist/cli/commands/auth.d.ts +12 -0
  99. package/dist/cli/commands/auth.js +352 -0
  100. package/dist/cli/commands/badge.d.ts +3 -0
  101. package/dist/cli/commands/badge.js +74 -0
  102. package/dist/cli/commands/baseline-accept.d.ts +15 -0
  103. package/dist/cli/commands/baseline-accept.js +178 -0
  104. package/dist/cli/commands/baseline-migrate.d.ts +12 -0
  105. package/dist/cli/commands/baseline-migrate.js +164 -0
  106. package/dist/cli/commands/baseline.d.ts +14 -0
  107. package/dist/cli/commands/baseline.js +449 -0
  108. package/dist/cli/commands/beta.d.ts +10 -0
  109. package/dist/cli/commands/beta.js +231 -0
  110. package/dist/cli/commands/check.d.ts +11 -0
  111. package/dist/cli/commands/check.js +820 -0
  112. package/dist/cli/commands/cloud/badge.d.ts +3 -0
  113. package/dist/cli/commands/cloud/badge.js +74 -0
  114. package/dist/cli/commands/cloud/diff.d.ts +6 -0
  115. package/dist/cli/commands/cloud/diff.js +79 -0
  116. package/dist/cli/commands/cloud/history.d.ts +6 -0
  117. package/dist/cli/commands/cloud/history.js +102 -0
  118. package/dist/cli/commands/cloud/link.d.ts +9 -0
  119. package/dist/cli/commands/cloud/link.js +119 -0
  120. package/dist/cli/commands/cloud/login.d.ts +7 -0
  121. package/dist/cli/commands/cloud/login.js +499 -0
  122. package/dist/cli/commands/cloud/projects.d.ts +6 -0
  123. package/dist/cli/commands/cloud/projects.js +44 -0
  124. package/dist/cli/commands/cloud/shared.d.ts +7 -0
  125. package/dist/cli/commands/cloud/shared.js +42 -0
  126. package/dist/cli/commands/cloud/teams.d.ts +8 -0
  127. package/dist/cli/commands/cloud/teams.js +169 -0
  128. package/dist/cli/commands/cloud/upload.d.ts +8 -0
  129. package/dist/cli/commands/cloud/upload.js +181 -0
  130. package/dist/cli/commands/contract.d.ts +11 -0
  131. package/dist/cli/commands/contract.js +280 -0
  132. package/dist/cli/commands/discover.d.ts +3 -0
  133. package/dist/cli/commands/discover.js +82 -0
  134. package/dist/cli/commands/eval.d.ts +9 -0
  135. package/dist/cli/commands/eval.js +187 -0
  136. package/dist/cli/commands/explore.d.ts +11 -0
  137. package/dist/cli/commands/explore.js +437 -0
  138. package/dist/cli/commands/feedback.d.ts +9 -0
  139. package/dist/cli/commands/feedback.js +174 -0
  140. package/dist/cli/commands/golden.d.ts +12 -0
  141. package/dist/cli/commands/golden.js +407 -0
  142. package/dist/cli/commands/history.d.ts +10 -0
  143. package/dist/cli/commands/history.js +202 -0
  144. package/dist/cli/commands/init.d.ts +9 -0
  145. package/dist/cli/commands/init.js +219 -0
  146. package/dist/cli/commands/interview.d.ts +3 -0
  147. package/dist/cli/commands/interview.js +903 -0
  148. package/dist/cli/commands/link.d.ts +10 -0
  149. package/dist/cli/commands/link.js +169 -0
  150. package/dist/cli/commands/login.d.ts +7 -0
  151. package/dist/cli/commands/login.js +499 -0
  152. package/dist/cli/commands/preset.d.ts +33 -0
  153. package/dist/cli/commands/preset.js +297 -0
  154. package/dist/cli/commands/profile.d.ts +33 -0
  155. package/dist/cli/commands/profile.js +286 -0
  156. package/dist/cli/commands/registry.d.ts +11 -0
  157. package/dist/cli/commands/registry.js +146 -0
  158. package/dist/cli/commands/shared.d.ts +79 -0
  159. package/dist/cli/commands/shared.js +196 -0
  160. package/dist/cli/commands/teams.d.ts +8 -0
  161. package/dist/cli/commands/teams.js +169 -0
  162. package/dist/cli/commands/test.d.ts +9 -0
  163. package/dist/cli/commands/test.js +500 -0
  164. package/dist/cli/commands/upload.d.ts +8 -0
  165. package/dist/cli/commands/upload.js +223 -0
  166. package/dist/cli/commands/validate-config.d.ts +6 -0
  167. package/dist/cli/commands/validate-config.js +35 -0
  168. package/dist/cli/commands/verify.d.ts +11 -0
  169. package/dist/cli/commands/verify.js +283 -0
  170. package/dist/cli/commands/watch.d.ts +12 -0
  171. package/dist/cli/commands/watch.js +253 -0
  172. package/dist/cli/index.d.ts +3 -0
  173. package/dist/cli/index.js +178 -0
  174. package/dist/cli/interactive.d.ts +47 -0
  175. package/dist/cli/interactive.js +216 -0
  176. package/dist/cli/output/terminal-reporter.d.ts +19 -0
  177. package/dist/cli/output/terminal-reporter.js +104 -0
  178. package/dist/cli/output.d.ts +226 -0
  179. package/dist/cli/output.js +438 -0
  180. package/dist/cli/utils/env.d.ts +5 -0
  181. package/dist/cli/utils/env.js +14 -0
  182. package/dist/cli/utils/progress.d.ts +59 -0
  183. package/dist/cli/utils/progress.js +206 -0
  184. package/dist/cli/utils/server-context.d.ts +10 -0
  185. package/dist/cli/utils/server-context.js +36 -0
  186. package/dist/cloud/auth.d.ts +144 -0
  187. package/dist/cloud/auth.js +374 -0
  188. package/dist/cloud/client.d.ts +24 -0
  189. package/dist/cloud/client.js +65 -0
  190. package/dist/cloud/http-client.d.ts +38 -0
  191. package/dist/cloud/http-client.js +215 -0
  192. package/dist/cloud/index.d.ts +23 -0
  193. package/dist/cloud/index.js +25 -0
  194. package/dist/cloud/mock-client.d.ts +107 -0
  195. package/dist/cloud/mock-client.js +545 -0
  196. package/dist/cloud/types.d.ts +515 -0
  197. package/dist/cloud/types.js +15 -0
  198. package/dist/config/defaults.d.ts +160 -0
  199. package/dist/config/defaults.js +169 -0
  200. package/dist/config/loader.d.ts +24 -0
  201. package/dist/config/loader.js +122 -0
  202. package/dist/config/template.d.ts +42 -0
  203. package/dist/config/template.js +647 -0
  204. package/dist/config/validator.d.ts +2112 -0
  205. package/dist/config/validator.js +658 -0
  206. package/dist/constants/cloud.d.ts +107 -0
  207. package/dist/constants/cloud.js +110 -0
  208. package/dist/constants/core.d.ts +521 -0
  209. package/dist/constants/core.js +556 -0
  210. package/dist/constants/testing.d.ts +1283 -0
  211. package/dist/constants/testing.js +1568 -0
  212. package/dist/constants.d.ts +10 -0
  213. package/dist/constants.js +10 -0
  214. package/dist/contract/index.d.ts +6 -0
  215. package/dist/contract/index.js +5 -0
  216. package/dist/contract/validator.d.ts +177 -0
  217. package/dist/contract/validator.js +574 -0
  218. package/dist/cost/index.d.ts +6 -0
  219. package/dist/cost/index.js +5 -0
  220. package/dist/cost/tracker.d.ts +134 -0
  221. package/dist/cost/tracker.js +313 -0
  222. package/dist/discovery/discovery.d.ts +16 -0
  223. package/dist/discovery/discovery.js +173 -0
  224. package/dist/discovery/types.d.ts +51 -0
  225. package/dist/discovery/types.js +2 -0
  226. package/dist/docs/agents.d.ts +3 -0
  227. package/dist/docs/agents.js +995 -0
  228. package/dist/docs/contract.d.ts +51 -0
  229. package/dist/docs/contract.js +1681 -0
  230. package/dist/docs/generator.d.ts +4 -0
  231. package/dist/docs/generator.js +4 -0
  232. package/dist/docs/html-reporter.d.ts +9 -0
  233. package/dist/docs/html-reporter.js +757 -0
  234. package/dist/docs/index.d.ts +10 -0
  235. package/dist/docs/index.js +11 -0
  236. package/dist/docs/junit-reporter.d.ts +18 -0
  237. package/dist/docs/junit-reporter.js +210 -0
  238. package/dist/docs/report.d.ts +14 -0
  239. package/dist/docs/report.js +44 -0
  240. package/dist/docs/sarif-reporter.d.ts +19 -0
  241. package/dist/docs/sarif-reporter.js +335 -0
  242. package/dist/docs/shared.d.ts +35 -0
  243. package/dist/docs/shared.js +162 -0
  244. package/dist/docs/templates.d.ts +12 -0
  245. package/dist/docs/templates.js +76 -0
  246. package/dist/errors/index.d.ts +6 -0
  247. package/dist/errors/index.js +6 -0
  248. package/dist/errors/retry.d.ts +92 -0
  249. package/dist/errors/retry.js +323 -0
  250. package/dist/errors/types.d.ts +321 -0
  251. package/dist/errors/types.js +584 -0
  252. package/dist/index.d.ts +32 -0
  253. package/dist/index.js +32 -0
  254. package/dist/interview/dependency-resolver.d.ts +11 -0
  255. package/dist/interview/dependency-resolver.js +32 -0
  256. package/dist/interview/interviewer.d.ts +232 -0
  257. package/dist/interview/interviewer.js +1939 -0
  258. package/dist/interview/mock-response-generator.d.ts +7 -0
  259. package/dist/interview/mock-response-generator.js +102 -0
  260. package/dist/interview/orchestrator.d.ts +237 -0
  261. package/dist/interview/orchestrator.js +1296 -0
  262. package/dist/interview/rate-limiter.d.ts +15 -0
  263. package/dist/interview/rate-limiter.js +55 -0
  264. package/dist/interview/response-validator.d.ts +10 -0
  265. package/dist/interview/response-validator.js +132 -0
  266. package/dist/interview/schema-inferrer.d.ts +8 -0
  267. package/dist/interview/schema-inferrer.js +71 -0
  268. package/dist/interview/schema-test-generator.d.ts +71 -0
  269. package/dist/interview/schema-test-generator.js +834 -0
  270. package/dist/interview/smart-value-generator.d.ts +155 -0
  271. package/dist/interview/smart-value-generator.js +554 -0
  272. package/dist/interview/stateful-test-runner.d.ts +19 -0
  273. package/dist/interview/stateful-test-runner.js +106 -0
  274. package/dist/interview/types.d.ts +561 -0
  275. package/dist/interview/types.js +2 -0
  276. package/dist/llm/anthropic.d.ts +41 -0
  277. package/dist/llm/anthropic.js +355 -0
  278. package/dist/llm/client.d.ts +123 -0
  279. package/dist/llm/client.js +42 -0
  280. package/dist/llm/factory.d.ts +38 -0
  281. package/dist/llm/factory.js +145 -0
  282. package/dist/llm/fallback.d.ts +140 -0
  283. package/dist/llm/fallback.js +379 -0
  284. package/dist/llm/index.d.ts +18 -0
  285. package/dist/llm/index.js +15 -0
  286. package/dist/llm/ollama.d.ts +37 -0
  287. package/dist/llm/ollama.js +330 -0
  288. package/dist/llm/openai.d.ts +25 -0
  289. package/dist/llm/openai.js +320 -0
  290. package/dist/llm/token-budget.d.ts +161 -0
  291. package/dist/llm/token-budget.js +395 -0
  292. package/dist/logging/logger.d.ts +70 -0
  293. package/dist/logging/logger.js +130 -0
  294. package/dist/metrics/collector.d.ts +106 -0
  295. package/dist/metrics/collector.js +547 -0
  296. package/dist/metrics/index.d.ts +7 -0
  297. package/dist/metrics/index.js +7 -0
  298. package/dist/metrics/prometheus.d.ts +20 -0
  299. package/dist/metrics/prometheus.js +241 -0
  300. package/dist/metrics/types.d.ts +209 -0
  301. package/dist/metrics/types.js +5 -0
  302. package/dist/persona/builtins.d.ts +54 -0
  303. package/dist/persona/builtins.js +219 -0
  304. package/dist/persona/index.d.ts +8 -0
  305. package/dist/persona/index.js +8 -0
  306. package/dist/persona/loader.d.ts +30 -0
  307. package/dist/persona/loader.js +190 -0
  308. package/dist/persona/types.d.ts +144 -0
  309. package/dist/persona/types.js +5 -0
  310. package/dist/persona/validation.d.ts +94 -0
  311. package/dist/persona/validation.js +332 -0
  312. package/dist/prompts/index.d.ts +5 -0
  313. package/dist/prompts/index.js +5 -0
  314. package/dist/prompts/templates.d.ts +180 -0
  315. package/dist/prompts/templates.js +431 -0
  316. package/dist/registry/client.d.ts +49 -0
  317. package/dist/registry/client.js +191 -0
  318. package/dist/registry/index.d.ts +7 -0
  319. package/dist/registry/index.js +6 -0
  320. package/dist/registry/types.d.ts +140 -0
  321. package/dist/registry/types.js +6 -0
  322. package/dist/scenarios/evaluator.d.ts +43 -0
  323. package/dist/scenarios/evaluator.js +206 -0
  324. package/dist/scenarios/index.d.ts +10 -0
  325. package/dist/scenarios/index.js +9 -0
  326. package/dist/scenarios/loader.d.ts +20 -0
  327. package/dist/scenarios/loader.js +285 -0
  328. package/dist/scenarios/types.d.ts +153 -0
  329. package/dist/scenarios/types.js +8 -0
  330. package/dist/security/index.d.ts +17 -0
  331. package/dist/security/index.js +18 -0
  332. package/dist/security/payloads.d.ts +61 -0
  333. package/dist/security/payloads.js +268 -0
  334. package/dist/security/security-tester.d.ts +42 -0
  335. package/dist/security/security-tester.js +582 -0
  336. package/dist/security/types.d.ts +166 -0
  337. package/dist/security/types.js +8 -0
  338. package/dist/transport/base-transport.d.ts +59 -0
  339. package/dist/transport/base-transport.js +38 -0
  340. package/dist/transport/http-transport.d.ts +67 -0
  341. package/dist/transport/http-transport.js +238 -0
  342. package/dist/transport/mcp-client.d.ts +141 -0
  343. package/dist/transport/mcp-client.js +496 -0
  344. package/dist/transport/sse-transport.d.ts +88 -0
  345. package/dist/transport/sse-transport.js +316 -0
  346. package/dist/transport/stdio-transport.d.ts +43 -0
  347. package/dist/transport/stdio-transport.js +238 -0
  348. package/dist/transport/types.d.ts +125 -0
  349. package/dist/transport/types.js +16 -0
  350. package/dist/utils/concurrency.d.ts +123 -0
  351. package/dist/utils/concurrency.js +213 -0
  352. package/dist/utils/formatters.d.ts +16 -0
  353. package/dist/utils/formatters.js +37 -0
  354. package/dist/utils/index.d.ts +8 -0
  355. package/dist/utils/index.js +8 -0
  356. package/dist/utils/jsonpath.d.ts +87 -0
  357. package/dist/utils/jsonpath.js +326 -0
  358. package/dist/utils/markdown.d.ts +113 -0
  359. package/dist/utils/markdown.js +265 -0
  360. package/dist/utils/network.d.ts +14 -0
  361. package/dist/utils/network.js +17 -0
  362. package/dist/utils/sanitize.d.ts +92 -0
  363. package/dist/utils/sanitize.js +191 -0
  364. package/dist/utils/semantic.d.ts +194 -0
  365. package/dist/utils/semantic.js +1051 -0
  366. package/dist/utils/smart-truncate.d.ts +94 -0
  367. package/dist/utils/smart-truncate.js +361 -0
  368. package/dist/utils/timeout.d.ts +153 -0
  369. package/dist/utils/timeout.js +205 -0
  370. package/dist/utils/yaml-parser.d.ts +58 -0
  371. package/dist/utils/yaml-parser.js +86 -0
  372. package/dist/validation/index.d.ts +32 -0
  373. package/dist/validation/index.js +32 -0
  374. package/dist/validation/semantic-test-generator.d.ts +50 -0
  375. package/dist/validation/semantic-test-generator.js +176 -0
  376. package/dist/validation/semantic-types.d.ts +66 -0
  377. package/dist/validation/semantic-types.js +94 -0
  378. package/dist/validation/semantic-validator.d.ts +38 -0
  379. package/dist/validation/semantic-validator.js +340 -0
  380. package/dist/verification/index.d.ts +6 -0
  381. package/dist/verification/index.js +5 -0
  382. package/dist/verification/types.d.ts +133 -0
  383. package/dist/verification/types.js +5 -0
  384. package/dist/verification/verifier.d.ts +30 -0
  385. package/dist/verification/verifier.js +309 -0
  386. package/dist/version.d.ts +19 -0
  387. package/dist/version.js +48 -0
  388. package/dist/workflow/auto-generator.d.ts +27 -0
  389. package/dist/workflow/auto-generator.js +513 -0
  390. package/dist/workflow/discovery.d.ts +40 -0
  391. package/dist/workflow/discovery.js +195 -0
  392. package/dist/workflow/executor.d.ts +82 -0
  393. package/dist/workflow/executor.js +611 -0
  394. package/dist/workflow/index.d.ts +10 -0
  395. package/dist/workflow/index.js +10 -0
  396. package/dist/workflow/loader.d.ts +24 -0
  397. package/dist/workflow/loader.js +194 -0
  398. package/dist/workflow/state-tracker.d.ts +98 -0
  399. package/dist/workflow/state-tracker.js +424 -0
  400. package/dist/workflow/types.d.ts +337 -0
  401. package/dist/workflow/types.js +5 -0
  402. package/package.json +94 -0
  403. package/schemas/bellwether-check.schema.json +651 -0
@@ -0,0 +1,585 @@
1
+ /**
2
+ * Baseline format converter.
3
+ *
4
+ * Converts between local BehavioralBaseline format and cloud BellwetherBaseline format.
5
+ *
6
+ * ## Severity Type Mappings
7
+ *
8
+ * The codebase uses three different severity type systems for different contexts:
9
+ *
10
+ * ### ChangeSeverity (baseline/types.ts)
11
+ * Used for drift detection change classification. Maps to CLI exit codes.
12
+ * Values: 'none' | 'info' | 'warning' | 'breaking'
13
+ *
14
+ * ### ErrorSeverity (errors/types.ts)
15
+ * Used for error severity classification in error handling.
16
+ * Values: 'low' | 'medium' | 'high' | 'critical'
17
+ *
18
+ * ### CloudAssertionSeverity (cloud/types.ts)
19
+ * Used for cloud assertions and PersonaFinding severity levels.
20
+ * Values: 'info' | 'low' | 'medium' | 'high' | 'critical'
21
+ *
22
+ * ### Conversion Mappings
23
+ *
24
+ * ChangeSeverity → CloudAssertionSeverity:
25
+ * - 'none' → 'info' (no change, informational)
26
+ * - 'info' → 'low' (minor changes)
27
+ * - 'warning' → 'medium' (moderate changes)
28
+ * - 'breaking' → 'critical' (breaking changes)
29
+ *
30
+ * CloudAssertionSeverity → ChangeSeverity (for display/filtering):
31
+ * - 'info' → 'info'
32
+ * - 'low' → 'info'
33
+ * - 'medium' → 'warning'
34
+ * - 'high' → 'warning'
35
+ * - 'critical' → 'breaking'
36
+ */
37
+ import { createHash } from 'crypto';
38
+ import { analyzeResponses } from './response-fingerprint.js';
39
+ import { getBaselineVersion } from './version.js';
40
+ import { VERSION } from '../version.js';
41
+ /**
42
+ * Map ChangeSeverity to CloudAssertionSeverity.
43
+ * Used when converting local baselines to cloud format.
44
+ */
45
+ export const CHANGE_TO_CLOUD_SEVERITY = {
46
+ none: 'info',
47
+ info: 'low',
48
+ warning: 'medium',
49
+ breaking: 'critical',
50
+ };
51
+ /**
52
+ * Map CloudAssertionSeverity to ChangeSeverity.
53
+ * Used when filtering or displaying cloud data locally.
54
+ */
55
+ export const CLOUD_TO_CHANGE_SEVERITY = {
56
+ info: 'info',
57
+ low: 'info',
58
+ medium: 'warning',
59
+ high: 'warning',
60
+ critical: 'breaking',
61
+ };
62
+ /**
63
+ * Hash a string using SHA-256.
64
+ */
65
+ function hashString(input) {
66
+ return createHash('sha256').update(input).digest('hex').slice(0, 16);
67
+ }
68
+ /**
69
+ * Convert a local BehavioralAssertion to cloud CloudAssertion format.
70
+ *
71
+ * Mapping:
72
+ * - isPositive=true + security aspect → 'requires' (critical security requirement)
73
+ * - isPositive=true + other aspect → 'expects' (expected behavior)
74
+ * - isPositive=false + security aspect → 'warns' (security warning)
75
+ * - isPositive=false + other aspect → 'notes' (limitation/note)
76
+ */
77
+ function convertAssertion(assertion) {
78
+ // Determine assertion type based on isPositive and aspect
79
+ let type;
80
+ if (assertion.isPositive) {
81
+ type = assertion.aspect === 'security' ? 'requires' : 'expects';
82
+ }
83
+ else {
84
+ type = assertion.aspect === 'security' ? 'warns' : 'notes';
85
+ }
86
+ // Determine severity based on aspect and content
87
+ let severity = 'info';
88
+ const lowerAssertion = assertion.assertion.toLowerCase();
89
+ if (assertion.aspect === 'security') {
90
+ if (lowerAssertion.includes('critical') ||
91
+ lowerAssertion.includes('injection') ||
92
+ lowerAssertion.includes('rce')) {
93
+ severity = 'critical';
94
+ }
95
+ else if (lowerAssertion.includes('high') ||
96
+ lowerAssertion.includes('dangerous') ||
97
+ lowerAssertion.includes('exploit')) {
98
+ severity = 'high';
99
+ }
100
+ else if (lowerAssertion.includes('medium') ||
101
+ lowerAssertion.includes('sensitive') ||
102
+ lowerAssertion.includes('leak')) {
103
+ severity = 'medium';
104
+ }
105
+ else {
106
+ severity = 'low';
107
+ }
108
+ }
109
+ else if (assertion.aspect === 'error_handling') {
110
+ severity = assertion.isPositive ? 'info' : 'low';
111
+ }
112
+ else if (assertion.aspect === 'performance') {
113
+ severity = 'medium';
114
+ }
115
+ return {
116
+ type,
117
+ condition: assertion.assertion,
118
+ tool: assertion.tool,
119
+ severity,
120
+ };
121
+ }
122
+ /**
123
+ * Convert an array of BehavioralAssertions to CloudAssertions.
124
+ */
125
+ function convertAssertions(assertions) {
126
+ return assertions.map(convertAssertion);
127
+ }
128
+ /**
129
+ * Derive baseline mode from result metadata.
130
+ * Returns 'check' for check mode results, 'explore' for explore mode results.
131
+ * Note: Baselines should only be created from check mode results,
132
+ * but explore uploads are still supported for documentation tracking.
133
+ */
134
+ function deriveCloudMode(resultModel) {
135
+ // Check mode results have model === 'check'
136
+ if (resultModel === 'check')
137
+ return 'check';
138
+ // Everything else (explore mode with LLM model names) is explore
139
+ return 'explore';
140
+ }
141
+ /**
142
+ * Convert a BehavioralBaseline to cloud BellwetherBaseline format.
143
+ */
144
+ export function convertToCloudBaseline(baseline, discovery, interviewResult) {
145
+ // Derive mode from result metadata
146
+ const mode = deriveCloudMode(interviewResult?.metadata.model);
147
+ // Build metadata
148
+ const metadata = {
149
+ mode,
150
+ generatedAt: baseline.createdAt.toISOString(),
151
+ cliVersion: VERSION,
152
+ serverCommand: baseline.serverCommand,
153
+ serverName: baseline.server.name,
154
+ durationMs: interviewResult?.metadata.durationMs ?? 0,
155
+ personas: extractPersonas(interviewResult),
156
+ model: interviewResult?.metadata.model ?? 'unknown',
157
+ };
158
+ // Build server fingerprint
159
+ const server = {
160
+ name: baseline.server.name,
161
+ version: baseline.server.version,
162
+ protocolVersion: baseline.server.protocolVersion,
163
+ capabilities: baseline.server.capabilities,
164
+ };
165
+ // Build capabilities
166
+ const capabilities = buildCapabilities(baseline, discovery);
167
+ // Build interviews
168
+ const interviews = buildInterviews(interviewResult);
169
+ // Build tool profiles (with converted assertions)
170
+ const toolProfiles = baseline.tools.map(convertToolFingerprint);
171
+ // Build workflows
172
+ const workflows = baseline.workflowSignatures;
173
+ // Convert assertions to cloud format
174
+ const assertions = convertAssertions(baseline.assertions);
175
+ // Build content hash
176
+ const contentForHash = JSON.stringify({
177
+ metadata,
178
+ server,
179
+ capabilities,
180
+ interviews,
181
+ toolProfiles,
182
+ workflows,
183
+ assertions,
184
+ summary: baseline.summary,
185
+ });
186
+ const hash = hashString(contentForHash);
187
+ return {
188
+ version: getBaselineVersion(),
189
+ metadata,
190
+ server,
191
+ capabilities,
192
+ interviews,
193
+ toolProfiles,
194
+ workflows,
195
+ assertions,
196
+ summary: baseline.summary,
197
+ hash,
198
+ };
199
+ }
200
+ /**
201
+ * Extract persona names from interview result.
202
+ */
203
+ function extractPersonas(result) {
204
+ if (!result?.metadata.personas) {
205
+ return ['technical_writer']; // Default persona
206
+ }
207
+ return result.metadata.personas.map((p) => p.id);
208
+ }
209
+ /**
210
+ * Build capabilities from baseline and discovery.
211
+ */
212
+ function buildCapabilities(baseline, discovery) {
213
+ // Build tool capabilities
214
+ // Prefer discovery schema, fall back to stored inputSchema from baseline
215
+ // Include response fingerprinting data from baseline
216
+ const tools = baseline.tools.map((tool) => ({
217
+ name: tool.name,
218
+ description: tool.description,
219
+ inputSchema: discovery
220
+ ? getToolSchema(discovery, tool.name)
221
+ : (tool.inputSchema ?? {}),
222
+ schemaHash: tool.schemaHash,
223
+ // Response fingerprinting (check mode enhancement)
224
+ responseFingerprint: tool.responseFingerprint,
225
+ inferredOutputSchema: tool.inferredOutputSchema,
226
+ errorPatterns: tool.errorPatterns,
227
+ }));
228
+ // Build resource capabilities (from discovery if available)
229
+ let resources;
230
+ // Note: Resources would come from discovery.resources if we had them
231
+ // Build prompt capabilities (from discovery if available)
232
+ let prompts;
233
+ if (discovery?.prompts && discovery.prompts.length > 0) {
234
+ prompts = discovery.prompts.map((p) => ({
235
+ name: p.name,
236
+ description: p.description,
237
+ arguments: p.arguments?.map((a) => ({
238
+ name: a.name,
239
+ description: a.description,
240
+ required: a.required,
241
+ })),
242
+ }));
243
+ }
244
+ return {
245
+ tools,
246
+ resources,
247
+ prompts,
248
+ };
249
+ }
250
+ /**
251
+ * Get tool schema from discovery.
252
+ */
253
+ function getToolSchema(discovery, toolName) {
254
+ const tool = discovery.tools.find((t) => t.name === toolName);
255
+ return tool?.inputSchema ?? {};
256
+ }
257
+ /**
258
+ * Build interview summaries from interview result.
259
+ */
260
+ function buildInterviews(result) {
261
+ if (!result?.metadata.personas) {
262
+ // Create a default technical_writer interview
263
+ const totalQuestions = result?.toolProfiles.reduce((sum, p) => sum + p.interactions.length, 0) ?? 0;
264
+ return [
265
+ {
266
+ persona: 'technical_writer',
267
+ toolsInterviewed: result?.toolProfiles.length ?? 0,
268
+ questionsAsked: totalQuestions,
269
+ findings: extractFindings(result?.toolProfiles ?? []),
270
+ },
271
+ ];
272
+ }
273
+ // Build interviews per persona
274
+ return result.metadata.personas.map((persona) => {
275
+ const personaInteractions = result.toolProfiles.flatMap((profile) => profile.interactions.filter((i) => i.personaId === persona.id));
276
+ const toolsWithPersonaInteractions = new Set(personaInteractions.map((i) => i.toolName));
277
+ return {
278
+ persona: persona.id,
279
+ toolsInterviewed: toolsWithPersonaInteractions.size,
280
+ questionsAsked: persona.questionsAsked,
281
+ findings: extractFindingsForPersona(result.toolProfiles, persona.id),
282
+ };
283
+ });
284
+ }
285
+ /**
286
+ * Extract findings from tool profiles.
287
+ */
288
+ function extractFindings(toolProfiles) {
289
+ const findings = [];
290
+ for (const profile of toolProfiles) {
291
+ // Add security findings
292
+ for (const note of profile.securityNotes) {
293
+ findings.push({
294
+ tool: profile.name,
295
+ category: 'security',
296
+ severity: classifySeverity(note),
297
+ description: note,
298
+ });
299
+ }
300
+ // Add limitation findings
301
+ for (const limitation of profile.limitations) {
302
+ findings.push({
303
+ tool: profile.name,
304
+ category: 'reliability',
305
+ severity: 'low',
306
+ description: limitation,
307
+ });
308
+ }
309
+ // Add behavioral findings (first few as behavior category)
310
+ for (const note of profile.behavioralNotes.slice(0, 3)) {
311
+ findings.push({
312
+ tool: profile.name,
313
+ category: 'behavior',
314
+ severity: 'info',
315
+ description: note,
316
+ });
317
+ }
318
+ }
319
+ return findings;
320
+ }
321
+ /**
322
+ * Extract findings for a specific persona.
323
+ */
324
+ function extractFindingsForPersona(toolProfiles, personaId) {
325
+ const findings = [];
326
+ for (const profile of toolProfiles) {
327
+ const personaFindings = profile.findingsByPersona?.find((f) => f.personaId === personaId);
328
+ if (!personaFindings)
329
+ continue;
330
+ // Add security findings
331
+ for (const note of personaFindings.securityNotes) {
332
+ findings.push({
333
+ tool: profile.name,
334
+ category: 'security',
335
+ severity: classifySeverity(note),
336
+ description: note,
337
+ });
338
+ }
339
+ // Add limitation findings
340
+ for (const limitation of personaFindings.limitations) {
341
+ findings.push({
342
+ tool: profile.name,
343
+ category: 'reliability',
344
+ severity: 'low',
345
+ description: limitation,
346
+ });
347
+ }
348
+ // Add behavioral findings
349
+ for (const note of personaFindings.behavioralNotes.slice(0, 3)) {
350
+ findings.push({
351
+ tool: profile.name,
352
+ category: 'behavior',
353
+ severity: 'info',
354
+ description: note,
355
+ });
356
+ }
357
+ }
358
+ return findings;
359
+ }
360
+ /**
361
+ * Classify severity based on note content.
362
+ */
363
+ function classifySeverity(note) {
364
+ const lowerNote = note.toLowerCase();
365
+ if (lowerNote.includes('critical') ||
366
+ lowerNote.includes('severe') ||
367
+ lowerNote.includes('injection') ||
368
+ lowerNote.includes('rce') ||
369
+ lowerNote.includes('remote code')) {
370
+ return 'critical';
371
+ }
372
+ if (lowerNote.includes('high') ||
373
+ lowerNote.includes('dangerous') ||
374
+ lowerNote.includes('exploit') ||
375
+ lowerNote.includes('bypass')) {
376
+ return 'high';
377
+ }
378
+ if (lowerNote.includes('medium') ||
379
+ lowerNote.includes('moderate') ||
380
+ lowerNote.includes('sensitive') ||
381
+ lowerNote.includes('leak')) {
382
+ return 'medium';
383
+ }
384
+ if (lowerNote.includes('low') ||
385
+ lowerNote.includes('minor') ||
386
+ lowerNote.includes('potential')) {
387
+ return 'low';
388
+ }
389
+ return 'info';
390
+ }
391
+ /**
392
+ * Convert ToolFingerprint to CloudToolProfile.
393
+ */
394
+ function convertToolFingerprint(tool) {
395
+ return {
396
+ name: tool.name,
397
+ description: tool.description,
398
+ schemaHash: tool.schemaHash,
399
+ assertions: convertAssertions(tool.assertions),
400
+ securityNotes: tool.securityNotes,
401
+ limitations: tool.limitations,
402
+ behavioralNotes: tool.assertions
403
+ .filter((a) => a.aspect === 'response_format' && a.isPositive)
404
+ .map((a) => a.assertion),
405
+ };
406
+ }
407
+ /**
408
+ * Create a BellwetherBaseline directly from InterviewResult.
409
+ *
410
+ * This is the preferred method when you have fresh interview results.
411
+ */
412
+ export function createCloudBaseline(result, serverCommand) {
413
+ // Derive mode from result metadata
414
+ const mode = deriveCloudMode(result.metadata.model);
415
+ // Build metadata
416
+ const metadata = {
417
+ mode,
418
+ generatedAt: new Date().toISOString(),
419
+ cliVersion: VERSION,
420
+ serverCommand,
421
+ serverName: result.discovery.serverInfo.name,
422
+ durationMs: result.metadata.durationMs,
423
+ personas: result.metadata.personas?.map((p) => p.id) ?? ['technical_writer'],
424
+ model: result.metadata.model ?? 'unknown',
425
+ };
426
+ // Build server fingerprint
427
+ const server = {
428
+ name: result.discovery.serverInfo.name,
429
+ version: result.discovery.serverInfo.version,
430
+ protocolVersion: result.discovery.protocolVersion,
431
+ capabilities: buildCapabilityList(result.discovery),
432
+ };
433
+ // Build response fingerprint map from tool profiles
434
+ const fingerprintMap = new Map();
435
+ for (const profile of result.toolProfiles) {
436
+ const responseData = profile.interactions.map(i => ({
437
+ response: i.response,
438
+ error: i.error,
439
+ }));
440
+ fingerprintMap.set(profile.name, analyzeResponses(responseData));
441
+ }
442
+ // Build capabilities (including response fingerprinting)
443
+ const tools = result.discovery.tools.map((tool) => {
444
+ const analysis = fingerprintMap.get(tool.name);
445
+ return {
446
+ name: tool.name,
447
+ description: tool.description ?? '',
448
+ inputSchema: tool.inputSchema ?? {},
449
+ schemaHash: hashString(JSON.stringify(tool.inputSchema ?? {})),
450
+ // Response fingerprinting (check mode enhancement)
451
+ responseFingerprint: analysis?.fingerprint,
452
+ inferredOutputSchema: analysis?.inferredSchema,
453
+ errorPatterns: analysis?.errorPatterns.length ? analysis.errorPatterns : undefined,
454
+ };
455
+ });
456
+ const prompts = result.discovery.prompts.length > 0
457
+ ? result.discovery.prompts.map((p) => ({
458
+ name: p.name,
459
+ description: p.description,
460
+ arguments: p.arguments?.map((a) => ({
461
+ name: a.name,
462
+ description: a.description,
463
+ required: a.required,
464
+ })),
465
+ }))
466
+ : undefined;
467
+ // Build interviews
468
+ const interviews = buildInterviews(result);
469
+ // Build tool profiles (with converted assertions)
470
+ const toolProfiles = result.toolProfiles.map((profile) => ({
471
+ name: profile.name,
472
+ description: profile.description,
473
+ schemaHash: hashString(JSON.stringify(result.discovery.tools.find((t) => t.name === profile.name)?.inputSchema ?? {})),
474
+ assertions: convertAssertions(extractToolAssertions(profile)),
475
+ securityNotes: profile.securityNotes,
476
+ limitations: profile.limitations,
477
+ behavioralNotes: profile.behavioralNotes,
478
+ }));
479
+ // Build workflows
480
+ const workflows = result.workflowResults?.map((wr) => ({
481
+ id: wr.workflow.id,
482
+ name: wr.workflow.name,
483
+ toolSequence: wr.workflow.steps.map((s) => s.tool),
484
+ succeeded: wr.success,
485
+ summary: wr.summary,
486
+ }));
487
+ // Build assertions (convert to cloud format)
488
+ const assertions = convertAssertions(extractAllAssertions(result));
489
+ // Build content hash
490
+ const contentForHash = JSON.stringify({
491
+ metadata,
492
+ server,
493
+ capabilities: { tools, prompts },
494
+ interviews,
495
+ toolProfiles,
496
+ workflows,
497
+ assertions,
498
+ summary: result.summary,
499
+ });
500
+ const hash = hashString(contentForHash);
501
+ return {
502
+ version: getBaselineVersion(),
503
+ metadata,
504
+ server,
505
+ capabilities: { tools, prompts },
506
+ interviews,
507
+ toolProfiles,
508
+ workflows,
509
+ assertions,
510
+ summary: result.summary,
511
+ hash,
512
+ };
513
+ }
514
+ /**
515
+ * Build capability list from discovery.
516
+ */
517
+ function buildCapabilityList(discovery) {
518
+ const capabilities = [];
519
+ if (discovery.capabilities.tools)
520
+ capabilities.push('tools');
521
+ if (discovery.capabilities.prompts)
522
+ capabilities.push('prompts');
523
+ if (discovery.capabilities.resources)
524
+ capabilities.push('resources');
525
+ if (discovery.capabilities.logging)
526
+ capabilities.push('logging');
527
+ return capabilities;
528
+ }
529
+ /**
530
+ * Extract behavioral assertions from a tool profile.
531
+ */
532
+ function extractToolAssertions(profile) {
533
+ const assertions = [];
534
+ // Behavioral notes as positive assertions
535
+ for (const note of profile.behavioralNotes) {
536
+ assertions.push({
537
+ tool: profile.name,
538
+ aspect: 'response_format',
539
+ assertion: note,
540
+ isPositive: true,
541
+ });
542
+ }
543
+ // Limitations as negative assertions
544
+ for (const limitation of profile.limitations) {
545
+ assertions.push({
546
+ tool: profile.name,
547
+ aspect: 'error_handling',
548
+ assertion: limitation,
549
+ isPositive: false,
550
+ });
551
+ }
552
+ // Security notes as security assertions
553
+ for (const secNote of profile.securityNotes) {
554
+ assertions.push({
555
+ tool: profile.name,
556
+ aspect: 'security',
557
+ assertion: secNote,
558
+ isPositive: !secNote.toLowerCase().includes('risk') &&
559
+ !secNote.toLowerCase().includes('vulnerab') &&
560
+ !secNote.toLowerCase().includes('dangerous'),
561
+ });
562
+ }
563
+ return assertions;
564
+ }
565
+ /**
566
+ * Extract all assertions from interview result.
567
+ */
568
+ function extractAllAssertions(result) {
569
+ const assertions = [];
570
+ // Extract from each tool
571
+ for (const profile of result.toolProfiles) {
572
+ assertions.push(...extractToolAssertions(profile));
573
+ }
574
+ // Add overall limitations as server assertions
575
+ for (const limitation of result.limitations) {
576
+ assertions.push({
577
+ tool: 'server',
578
+ aspect: 'error_handling',
579
+ assertion: limitation,
580
+ isPositive: false,
581
+ });
582
+ }
583
+ return assertions;
584
+ }
585
+ //# sourceMappingURL=converter.js.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Cross-Tool Dependency Analyzer.
3
+ *
4
+ * Analyzes tool descriptions and schemas to identify dependencies
5
+ * between tools, enabling better testing strategies and documentation.
6
+ *
7
+ * Detection strategies:
8
+ * 1. Description analysis - mentions of other tool names
9
+ * 2. Parameter name matching - params that match output field names
10
+ * 3. Resource reference patterns - common ID/token patterns
11
+ * 4. Workflow step order - sequence implied by tool naming
12
+ */
13
+ import type { MCPTool } from '../transport/types.js';
14
+ /**
15
+ * A dependency edge between two tools.
16
+ */
17
+ export interface DependencyEdge {
18
+ /** Source tool that provides data */
19
+ from: string;
20
+ /** Target tool that consumes data */
21
+ to: string;
22
+ /** Type of dependency relationship */
23
+ type: DependencyType;
24
+ /** Confidence level of this dependency detection (0-1) */
25
+ confidence: number;
26
+ /** Description of the relationship */
27
+ description: string;
28
+ /** Which field/parameter creates the dependency */
29
+ field?: string;
30
+ }
31
+ /**
32
+ * Types of dependencies between tools.
33
+ */
34
+ export type DependencyType = 'mention' | 'output_input' | 'resource_ref' | 'sequence' | 'shared_resource';
35
+ /**
36
+ * Full dependency graph for a set of tools.
37
+ */
38
+ export interface DependencyGraph {
39
+ /** All dependency edges */
40
+ edges: DependencyEdge[];
41
+ /** Tools grouped by layer (no dependencies -> most dependencies) */
42
+ layers: string[][];
43
+ /** Tools with no dependencies (entry points) */
44
+ entryPoints: string[];
45
+ /** Tools with no dependents (terminal operations) */
46
+ terminalPoints: string[];
47
+ /** Detected cycles (if any) */
48
+ cycles: string[][];
49
+ }
50
+ /**
51
+ * Statistics about the dependency graph.
52
+ */
53
+ export interface DependencyStats {
54
+ /** Total number of edges */
55
+ totalEdges: number;
56
+ /** Edges by type */
57
+ byType: Record<DependencyType, number>;
58
+ /** Average dependencies per tool */
59
+ avgDependencies: number;
60
+ /** Maximum dependency chain length */
61
+ maxChainLength: number;
62
+ /** Tools with most dependencies */
63
+ mostDependent: Array<{
64
+ tool: string;
65
+ count: number;
66
+ }>;
67
+ /** Tools most depended upon */
68
+ mostDependedUpon: Array<{
69
+ tool: string;
70
+ count: number;
71
+ }>;
72
+ }
73
+ /**
74
+ * Analyze dependencies between tools.
75
+ */
76
+ export declare function analyzeDependencies(tools: MCPTool[]): DependencyGraph;
77
+ /**
78
+ * Calculate statistics about the dependency graph.
79
+ */
80
+ export declare function calculateDependencyStats(graph: DependencyGraph): DependencyStats;
81
+ /**
82
+ * Generate a Mermaid diagram for the dependency graph.
83
+ */
84
+ export declare function generateDependencyMermaid(graph: DependencyGraph): string;
85
+ /**
86
+ * Generate markdown documentation for dependencies.
87
+ */
88
+ export declare function generateDependencyMarkdown(graph: DependencyGraph, stats: DependencyStats): string;
89
+ //# sourceMappingURL=dependency-analyzer.d.ts.map