@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,285 @@
1
+ /**
2
+ * Scenario loader - loads test scenarios from YAML files.
3
+ */
4
+ import { readFileSync, existsSync } from 'fs';
5
+ import { parseYamlSecure } from '../utils/yaml-parser.js';
6
+ import { PATHS } from '../constants.js';
7
+ /** Default file name for test scenarios */
8
+ export const DEFAULT_SCENARIOS_FILE = PATHS.DEFAULT_SCENARIOS_FILE;
9
+ /** Valid question categories */
10
+ const VALID_CATEGORIES = [
11
+ 'happy_path',
12
+ 'edge_case',
13
+ 'error_handling',
14
+ 'boundary',
15
+ 'security',
16
+ ];
17
+ /** Valid assertion conditions */
18
+ const VALID_CONDITIONS = [
19
+ 'exists',
20
+ 'equals',
21
+ 'contains',
22
+ 'truthy',
23
+ 'type',
24
+ 'not_error',
25
+ ];
26
+ /**
27
+ * Load test scenarios from a YAML file.
28
+ */
29
+ export function loadScenariosFromFile(path) {
30
+ if (!existsSync(path)) {
31
+ throw new Error(`Test scenarios file not found: ${path}`);
32
+ }
33
+ const content = readFileSync(path, 'utf-8');
34
+ const parsed = parseYamlSecure(content);
35
+ if (!parsed || typeof parsed !== 'object') {
36
+ throw new Error(`Invalid test scenarios file: ${path} (expected object)`);
37
+ }
38
+ const globalTags = parsed.tags ?? [];
39
+ const toolScenarios = [];
40
+ const promptScenarios = [];
41
+ // Parse tool scenarios
42
+ if (parsed.scenarios && Array.isArray(parsed.scenarios)) {
43
+ for (let i = 0; i < parsed.scenarios.length; i++) {
44
+ const raw = parsed.scenarios[i];
45
+ try {
46
+ const scenario = validateToolScenario(raw, i, path, globalTags);
47
+ toolScenarios.push(scenario);
48
+ }
49
+ catch (error) {
50
+ throw new Error(`Error in scenario ${i + 1} of ${path}: ${error.message}`);
51
+ }
52
+ }
53
+ }
54
+ // Parse prompt scenarios
55
+ if (parsed.prompts && Array.isArray(parsed.prompts)) {
56
+ for (let i = 0; i < parsed.prompts.length; i++) {
57
+ const raw = parsed.prompts[i];
58
+ try {
59
+ const scenario = validatePromptScenario(raw, i, path, globalTags);
60
+ promptScenarios.push(scenario);
61
+ }
62
+ catch (error) {
63
+ throw new Error(`Error in prompt scenario ${i + 1} of ${path}: ${error.message}`);
64
+ }
65
+ }
66
+ }
67
+ return {
68
+ source: path,
69
+ toolScenarios,
70
+ promptScenarios,
71
+ description: parsed.description,
72
+ version: parsed.version,
73
+ };
74
+ }
75
+ /**
76
+ * Try to load scenarios from the default file in a directory.
77
+ * Returns null if file doesn't exist.
78
+ */
79
+ export function tryLoadDefaultScenarios(directory) {
80
+ const path = `${directory}/${DEFAULT_SCENARIOS_FILE}`;
81
+ if (!existsSync(path)) {
82
+ return null;
83
+ }
84
+ return loadScenariosFromFile(path);
85
+ }
86
+ /**
87
+ * Validate and normalize a tool test scenario.
88
+ */
89
+ function validateToolScenario(data, _index, _source, globalTags) {
90
+ // Required: tool
91
+ if (!data.tool || typeof data.tool !== 'string') {
92
+ throw new Error('missing required field: tool');
93
+ }
94
+ // Optional: category (default: happy_path)
95
+ let category = 'happy_path';
96
+ if (data.category) {
97
+ if (!VALID_CATEGORIES.includes(data.category)) {
98
+ throw new Error(`invalid category "${data.category}". Valid categories: ${VALID_CATEGORIES.join(', ')}`);
99
+ }
100
+ category = data.category;
101
+ }
102
+ // Optional: args (default: empty)
103
+ const args = data.args ?? {};
104
+ if (typeof args !== 'object' || Array.isArray(args)) {
105
+ throw new Error('args must be an object');
106
+ }
107
+ // Optional: assertions
108
+ const assertions = data.assertions?.map((a, i) => validateAssertion(a, i));
109
+ // Merge global tags with scenario tags
110
+ const tags = [...globalTags, ...(data.tags ?? [])];
111
+ return {
112
+ tool: data.tool,
113
+ description: data.description ?? `Test ${data.tool} with ${category} scenario`,
114
+ category,
115
+ args,
116
+ assertions,
117
+ skip: data.skip ?? false,
118
+ tags: tags.length > 0 ? tags : undefined,
119
+ };
120
+ }
121
+ /**
122
+ * Validate and normalize a prompt test scenario.
123
+ */
124
+ function validatePromptScenario(data, _index, _source, globalTags) {
125
+ // Required: prompt
126
+ if (!data.prompt || typeof data.prompt !== 'string') {
127
+ throw new Error('missing required field: prompt');
128
+ }
129
+ // Optional: args (default: empty)
130
+ const args = data.args ?? {};
131
+ if (typeof args !== 'object' || Array.isArray(args)) {
132
+ throw new Error('args must be an object');
133
+ }
134
+ // Validate that all arg values are strings
135
+ for (const [key, value] of Object.entries(args)) {
136
+ if (typeof value !== 'string') {
137
+ throw new Error(`prompt arg "${key}" must be a string, got ${typeof value}`);
138
+ }
139
+ }
140
+ // Optional: assertions
141
+ const assertions = data.assertions?.map((a, i) => validateAssertion(a, i));
142
+ // Merge global tags with scenario tags
143
+ const tags = [...globalTags, ...(data.tags ?? [])];
144
+ return {
145
+ prompt: data.prompt,
146
+ description: data.description ?? `Test prompt ${data.prompt}`,
147
+ args,
148
+ assertions,
149
+ skip: data.skip ?? false,
150
+ tags: tags.length > 0 ? tags : undefined,
151
+ };
152
+ }
153
+ /**
154
+ * Validate and normalize an assertion.
155
+ */
156
+ function validateAssertion(data, index) {
157
+ // Required: path
158
+ if (!data.path || typeof data.path !== 'string') {
159
+ throw new Error(`assertion ${index + 1}: missing required field "path"`);
160
+ }
161
+ // Required: condition
162
+ if (!data.condition || typeof data.condition !== 'string') {
163
+ throw new Error(`assertion ${index + 1}: missing required field "condition"`);
164
+ }
165
+ if (!VALID_CONDITIONS.includes(data.condition)) {
166
+ throw new Error(`assertion ${index + 1}: invalid condition "${data.condition}". ` +
167
+ `Valid conditions: ${VALID_CONDITIONS.join(', ')}`);
168
+ }
169
+ // Validate that 'value' is provided for conditions that require it
170
+ const conditionsRequiringValue = ['equals', 'contains', 'type'];
171
+ if (conditionsRequiringValue.includes(data.condition) && data.value === undefined) {
172
+ throw new Error(`assertion ${index + 1}: condition "${data.condition}" requires a "value" field`);
173
+ }
174
+ return {
175
+ path: data.path,
176
+ condition: data.condition,
177
+ value: data.value,
178
+ message: data.message,
179
+ };
180
+ }
181
+ /**
182
+ * Generate a sample YAML template for test scenarios.
183
+ */
184
+ export function generateSampleScenariosYaml() {
185
+ return `# Bellwether Test Scenarios
186
+ # Save as: bellwether-tests.yaml in your project root
187
+ # Docs: https://docs.bellwether.sh/guides/custom-scenarios
188
+
189
+ version: "1"
190
+ description: Custom test scenarios for my MCP server
191
+
192
+ # Global tags applied to all scenarios (optional)
193
+ tags:
194
+ - custom
195
+
196
+ # Tool test scenarios
197
+ scenarios:
198
+ # Happy path test
199
+ - tool: read_file
200
+ description: Read a valid file
201
+ category: happy_path
202
+ args:
203
+ path: "/tmp/test.txt"
204
+ assertions:
205
+ - path: content
206
+ condition: exists
207
+ message: File content should be returned
208
+
209
+ # Edge case test
210
+ - tool: read_file
211
+ description: Read file with special characters in name
212
+ category: edge_case
213
+ args:
214
+ path: "/tmp/file with spaces.txt"
215
+ assertions:
216
+ - path: content
217
+ condition: exists
218
+
219
+ # Error handling test
220
+ - tool: read_file
221
+ description: Handle missing file gracefully
222
+ category: error_handling
223
+ args:
224
+ path: "/nonexistent/file.txt"
225
+ assertions:
226
+ - path: error
227
+ condition: exists
228
+ message: Should return error for missing file
229
+
230
+ # Security test
231
+ - tool: read_file
232
+ description: Reject path traversal attempt
233
+ category: security
234
+ args:
235
+ path: "../../etc/passwd"
236
+ tags:
237
+ - security
238
+ - critical
239
+
240
+ # Skip a test (won't run)
241
+ - tool: dangerous_operation
242
+ description: Skipped test
243
+ skip: true
244
+ args:
245
+ action: delete_all
246
+
247
+ # Prompt test scenarios
248
+ prompts:
249
+ - prompt: summarize
250
+ description: Test summarize prompt with sample text
251
+ args:
252
+ text: "This is a long document that needs to be summarized..."
253
+ assertions:
254
+ - path: messages
255
+ condition: exists
256
+ - path: messages[0].content
257
+ condition: truthy
258
+
259
+ - prompt: translate
260
+ description: Test translation prompt
261
+ args:
262
+ text: "Hello, world!"
263
+ language: "Spanish"
264
+ assertions:
265
+ - path: messages[0].content.text
266
+ condition: contains
267
+ value: "Hola"
268
+
269
+ # Assertion conditions:
270
+ # - exists: Path exists (value is not undefined)
271
+ # - equals: Value equals expected
272
+ # - contains: String/array contains value
273
+ # - truthy: Value is truthy
274
+ # - type: Value is of type (string, number, boolean, object, array)
275
+ # - not_error: Response is not an error
276
+
277
+ # Categories:
278
+ # - happy_path: Normal usage
279
+ # - edge_case: Boundary conditions
280
+ # - error_handling: Invalid inputs
281
+ # - boundary: Limits and extremes
282
+ # - security: Security-related tests
283
+ `;
284
+ }
285
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Types for custom YAML-defined test scenarios.
3
+ *
4
+ * These types define the schema for user-defined test cases
5
+ * that can be provided via bellwether-tests.yaml files.
6
+ */
7
+ import type { QuestionCategory } from '../persona/types.js';
8
+ /**
9
+ * Valid assertion conditions for scenario expectations.
10
+ */
11
+ export type AssertionCondition = 'exists' | 'equals' | 'contains' | 'truthy' | 'type' | 'not_error';
12
+ /**
13
+ * An assertion/expectation for a test scenario.
14
+ */
15
+ export interface ScenarioAssertion {
16
+ /** JSONPath to the value to check */
17
+ path: string;
18
+ /** Condition to evaluate */
19
+ condition: AssertionCondition;
20
+ /** Expected value (for equals, contains, type) */
21
+ value?: unknown;
22
+ /** Custom error message on failure */
23
+ message?: string;
24
+ }
25
+ /**
26
+ * A single test scenario for a tool.
27
+ */
28
+ export interface TestScenario {
29
+ /** Tool to test */
30
+ tool: string;
31
+ /** Description of what this test verifies */
32
+ description: string;
33
+ /** Category of test (default: happy_path) */
34
+ category: QuestionCategory;
35
+ /** Arguments to pass to the tool */
36
+ args: Record<string, unknown>;
37
+ /** Assertions to verify after execution */
38
+ assertions?: ScenarioAssertion[];
39
+ /** Whether this scenario should be skipped */
40
+ skip?: boolean;
41
+ /** Tags for filtering scenarios */
42
+ tags?: string[];
43
+ }
44
+ /**
45
+ * A single test scenario for a prompt.
46
+ */
47
+ export interface PromptScenario {
48
+ /** Prompt to test */
49
+ prompt: string;
50
+ /** Description of what this test verifies */
51
+ description: string;
52
+ /** Arguments to pass to the prompt */
53
+ args: Record<string, string>;
54
+ /** Assertions to verify on the rendered output */
55
+ assertions?: ScenarioAssertion[];
56
+ /** Whether this scenario should be skipped */
57
+ skip?: boolean;
58
+ /** Tags for filtering scenarios */
59
+ tags?: string[];
60
+ }
61
+ /**
62
+ * YAML file structure for test scenarios.
63
+ */
64
+ export interface TestScenariosYAML {
65
+ /** Version of the schema (for future compatibility) */
66
+ version?: string;
67
+ /** Description of this test file */
68
+ description?: string;
69
+ /** Tool test scenarios */
70
+ scenarios?: TestScenarioYAML[];
71
+ /** Prompt test scenarios */
72
+ prompts?: PromptScenarioYAML[];
73
+ /** Global tags applied to all scenarios */
74
+ tags?: string[];
75
+ }
76
+ /**
77
+ * YAML representation of a test scenario (looser types for parsing).
78
+ */
79
+ export interface TestScenarioYAML {
80
+ tool: string;
81
+ description?: string;
82
+ category?: string;
83
+ args?: Record<string, unknown>;
84
+ assertions?: ScenarioAssertionYAML[];
85
+ skip?: boolean;
86
+ tags?: string[];
87
+ }
88
+ /**
89
+ * YAML representation of a prompt scenario.
90
+ */
91
+ export interface PromptScenarioYAML {
92
+ prompt: string;
93
+ description?: string;
94
+ args?: Record<string, string>;
95
+ assertions?: ScenarioAssertionYAML[];
96
+ skip?: boolean;
97
+ tags?: string[];
98
+ }
99
+ /**
100
+ * YAML representation of an assertion.
101
+ */
102
+ export interface ScenarioAssertionYAML {
103
+ path?: string;
104
+ condition?: string;
105
+ value?: unknown;
106
+ message?: string;
107
+ }
108
+ /**
109
+ * Loaded test scenarios file.
110
+ */
111
+ export interface LoadedScenarios {
112
+ /** Source file path */
113
+ source: string;
114
+ /** Tool test scenarios */
115
+ toolScenarios: TestScenario[];
116
+ /** Prompt test scenarios */
117
+ promptScenarios: PromptScenario[];
118
+ /** File description */
119
+ description?: string;
120
+ /** Schema version */
121
+ version?: string;
122
+ }
123
+ /**
124
+ * Result of running a scenario assertion.
125
+ */
126
+ export interface AssertionResult {
127
+ /** The assertion that was checked */
128
+ assertion: ScenarioAssertion;
129
+ /** Whether the assertion passed */
130
+ passed: boolean;
131
+ /** Actual value found */
132
+ actualValue?: unknown;
133
+ /** Error message if failed */
134
+ error?: string;
135
+ }
136
+ /**
137
+ * Result of running a single test scenario.
138
+ */
139
+ export interface ScenarioResult {
140
+ /** The scenario that was run */
141
+ scenario: TestScenario | PromptScenario;
142
+ /** Whether the scenario passed (all assertions passed and no error) */
143
+ passed: boolean;
144
+ /** Assertion results */
145
+ assertionResults: AssertionResult[];
146
+ /** Error if execution failed */
147
+ error?: string;
148
+ /** Response from the tool/prompt */
149
+ response?: unknown;
150
+ /** Execution duration in ms */
151
+ durationMs: number;
152
+ }
153
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Types for custom YAML-defined test scenarios.
3
+ *
4
+ * These types define the schema for user-defined test cases
5
+ * that can be provided via bellwether-tests.yaml files.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Security testing module for bellwether check mode.
3
+ *
4
+ * This module provides deterministic security testing capabilities that can
5
+ * detect common vulnerability patterns in MCP tools without requiring LLM.
6
+ *
7
+ * Usage:
8
+ * bellwether check --security # Run security tests with default categories
9
+ * bellwether check --security --security-categories sql_injection,xss
10
+ *
11
+ * The security baseline is stored in the baseline file and can be compared
12
+ * across runs to detect security posture changes.
13
+ */
14
+ export type { SecurityCategory, RiskLevel, SecurityPayload, SecurityTestResult, SecurityFinding, SecurityFingerprint, SecurityDiff, SecurityTestOptions, SecurityTestContext, SecurityToolCallResult, SecurityReport, } from './types.js';
15
+ export { SQL_INJECTION_PAYLOADS, XSS_PAYLOADS, PATH_TRAVERSAL_PAYLOADS, COMMAND_INJECTION_PAYLOADS, SSRF_PAYLOADS, getPayloadsForCategory, getAllSecurityPayloads, getAllSecurityCategories, } from './payloads.js';
16
+ export { runSecurityTests, compareSecurityFingerprints, getRiskLevelFromScore, parseSecurityCategories, } from './security-tester.js';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Security testing module for bellwether check mode.
3
+ *
4
+ * This module provides deterministic security testing capabilities that can
5
+ * detect common vulnerability patterns in MCP tools without requiring LLM.
6
+ *
7
+ * Usage:
8
+ * bellwether check --security # Run security tests with default categories
9
+ * bellwether check --security --security-categories sql_injection,xss
10
+ *
11
+ * The security baseline is stored in the baseline file and can be compared
12
+ * across runs to detect security posture changes.
13
+ */
14
+ // Payload exports
15
+ export { SQL_INJECTION_PAYLOADS, XSS_PAYLOADS, PATH_TRAVERSAL_PAYLOADS, COMMAND_INJECTION_PAYLOADS, SSRF_PAYLOADS, getPayloadsForCategory, getAllSecurityPayloads, getAllSecurityCategories, } from './payloads.js';
16
+ // Security tester exports
17
+ export { runSecurityTests, compareSecurityFingerprints, getRiskLevelFromScore, parseSecurityCategories, } from './security-tester.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Deterministic security test payloads.
3
+ *
4
+ * These are well-known test patterns used for security testing that don't
5
+ * require LLM generation. Each payload is designed to test a specific
6
+ * vulnerability class.
7
+ *
8
+ * IMPORTANT: These payloads are for defensive security testing only.
9
+ * They help developers identify input validation gaps in their MCP servers.
10
+ */
11
+ import type { SecurityPayload, SecurityCategory } from './types.js';
12
+ /**
13
+ * SQL injection test payloads.
14
+ * Tests for improper handling of SQL metacharacters in user input.
15
+ * CWE-89: Improper Neutralization of Special Elements used in an SQL Command
16
+ */
17
+ export declare const SQL_INJECTION_PAYLOADS: SecurityPayload[];
18
+ /**
19
+ * Cross-Site Scripting (XSS) test payloads.
20
+ * Tests for improper handling of HTML/JavaScript in user input.
21
+ * CWE-79: Improper Neutralization of Input During Web Page Generation
22
+ */
23
+ export declare const XSS_PAYLOADS: SecurityPayload[];
24
+ /**
25
+ * Path traversal test payloads.
26
+ * Tests for improper handling of file path inputs.
27
+ * CWE-22: Improper Limitation of a Pathname to a Restricted Directory
28
+ */
29
+ export declare const PATH_TRAVERSAL_PAYLOADS: SecurityPayload[];
30
+ /**
31
+ * Command injection test payloads.
32
+ * Tests for improper handling of shell metacharacters.
33
+ * CWE-78: Improper Neutralization of Special Elements used in an OS Command
34
+ */
35
+ export declare const COMMAND_INJECTION_PAYLOADS: SecurityPayload[];
36
+ /**
37
+ * Server-Side Request Forgery (SSRF) test payloads.
38
+ * Tests for improper URL validation allowing internal network access.
39
+ * CWE-918: Server-Side Request Forgery (SSRF)
40
+ */
41
+ export declare const SSRF_PAYLOADS: SecurityPayload[];
42
+ /**
43
+ * Get payloads for a specific security category.
44
+ *
45
+ * @param category - The security category to get payloads for
46
+ * @returns Array of payloads for that category
47
+ */
48
+ export declare function getPayloadsForCategory(category: SecurityCategory): SecurityPayload[];
49
+ /**
50
+ * Get all security payloads across all categories.
51
+ *
52
+ * @returns Array of all security payloads
53
+ */
54
+ export declare function getAllSecurityPayloads(): SecurityPayload[];
55
+ /**
56
+ * Get all available security categories.
57
+ *
58
+ * @returns Array of all security category identifiers
59
+ */
60
+ export declare function getAllSecurityCategories(): SecurityCategory[];
61
+ //# sourceMappingURL=payloads.d.ts.map