@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,611 @@
1
+ /**
2
+ * Workflow executor - runs workflows and tracks data flow.
3
+ */
4
+ import { StateTracker } from './state-tracker.js';
5
+ import { buildWorkflowStepAnalysisPrompt, buildWorkflowSummaryPrompt, COMPLETION_OPTIONS, } from '../prompts/templates.js';
6
+ import { getLogger, startTiming } from '../logging/logger.js';
7
+ import { withTimeout, DEFAULT_TIMEOUTS, checkAborted } from '../utils/timeout.js';
8
+ /**
9
+ * Default executor options (excluding callbacks and signal).
10
+ */
11
+ const DEFAULT_OPTIONS = {
12
+ continueOnError: false,
13
+ stepTimeout: DEFAULT_TIMEOUTS.toolCall,
14
+ analyzeSteps: true,
15
+ generateSummary: true,
16
+ requireSuccessfulDependencies: true,
17
+ timeouts: {
18
+ toolCall: DEFAULT_TIMEOUTS.toolCall,
19
+ stateSnapshot: DEFAULT_TIMEOUTS.stateSnapshot,
20
+ probeTool: DEFAULT_TIMEOUTS.probeTool,
21
+ llmAnalysis: DEFAULT_TIMEOUTS.responseAnalysis,
22
+ llmSummary: DEFAULT_TIMEOUTS.profileSynthesis,
23
+ },
24
+ };
25
+ /**
26
+ * Executes workflows against an MCP server.
27
+ */
28
+ export class WorkflowExecutor {
29
+ client;
30
+ llm;
31
+ tools;
32
+ options;
33
+ stepResults = [];
34
+ onProgress;
35
+ logger = getLogger('workflow-executor');
36
+ stateTracker;
37
+ timeouts;
38
+ constructor(client, llm, tools, options = {}) {
39
+ this.client = client;
40
+ this.llm = llm;
41
+ this.tools = tools;
42
+ this.options = options;
43
+ // Merge options with defaults, including nested timeouts
44
+ this.options = {
45
+ ...DEFAULT_OPTIONS,
46
+ ...options,
47
+ timeouts: { ...DEFAULT_OPTIONS.timeouts, ...options.timeouts },
48
+ };
49
+ this.timeouts = this.options.timeouts;
50
+ this.onProgress = options.onProgress;
51
+ // Initialize state tracker if enabled and LLM is available
52
+ // State tracking requires LLM for analysis
53
+ if (this.options.stateTracking?.enabled && llm) {
54
+ this.stateTracker = new StateTracker(client, tools, llm, this.options.stateTracking, {
55
+ snapshotTimeout: this.timeouts.stateSnapshot,
56
+ probeTimeout: this.timeouts.probeTool,
57
+ });
58
+ }
59
+ }
60
+ /**
61
+ * Emit progress event if callback is registered.
62
+ */
63
+ emitProgress(workflow, phase, currentStep, startTime, currentStepInfo) {
64
+ if (!this.onProgress)
65
+ return;
66
+ const stepsFailed = this.stepResults.filter(r => !r.success).length;
67
+ this.onProgress({
68
+ phase,
69
+ workflow,
70
+ currentStep,
71
+ totalSteps: workflow.steps.length,
72
+ currentStepInfo,
73
+ stepsCompleted: this.stepResults.length,
74
+ stepsFailed,
75
+ elapsedMs: Date.now() - startTime,
76
+ });
77
+ }
78
+ /**
79
+ * Execute a workflow.
80
+ *
81
+ * @param workflow - The workflow to execute
82
+ * @throws AbortError if the operation is aborted via signal
83
+ */
84
+ async execute(workflow) {
85
+ const signal = this.options.signal;
86
+ const done = startTiming(this.logger, `workflow:${workflow.id}`);
87
+ const startTime = Date.now();
88
+ this.stepResults = [];
89
+ // Check if already aborted before starting
90
+ checkAborted(signal, `Workflow '${workflow.id}'`);
91
+ this.logger.info({
92
+ workflowId: workflow.id,
93
+ workflowName: workflow.name,
94
+ stepCount: workflow.steps.length,
95
+ stateTrackingEnabled: !!this.stateTracker,
96
+ }, 'Starting workflow execution');
97
+ let success = true;
98
+ let failureReason;
99
+ let failedStepIndex;
100
+ // State tracking data
101
+ const snapshots = [];
102
+ const changes = [];
103
+ // Emit starting progress
104
+ this.emitProgress(workflow, 'starting', 0, startTime);
105
+ // Take initial state snapshot if enabled
106
+ if (this.stateTracker && this.options.stateTracking?.snapshotBefore) {
107
+ checkAborted(signal, 'Initial state snapshot');
108
+ this.logger.debug('Taking initial state snapshot');
109
+ const initialSnapshot = await this.stateTracker.takeSnapshot(-1);
110
+ snapshots.push(initialSnapshot);
111
+ }
112
+ for (let i = 0; i < workflow.steps.length; i++) {
113
+ const step = workflow.steps[i];
114
+ // Check for abort before each step
115
+ checkAborted(signal, `Workflow step ${i + 1}/${workflow.steps.length}`);
116
+ // Check if any dependency steps have failed (when requireSuccessfulDependencies is enabled)
117
+ const requireSuccessfulDeps = this.options.requireSuccessfulDependencies ?? DEFAULT_OPTIONS.requireSuccessfulDependencies;
118
+ if (requireSuccessfulDeps) {
119
+ const failedDependencies = this.getFailedDependencies(step, i);
120
+ if (failedDependencies.length > 0) {
121
+ const failedStepNames = failedDependencies.map((idx) => `step ${idx + 1} (${workflow.steps[idx]?.tool ?? 'unknown'})`).join(', ');
122
+ this.logger.debug({
123
+ stepIndex: i,
124
+ tool: step.tool,
125
+ failedDependencies,
126
+ }, 'Skipping step due to failed dependencies');
127
+ const skipResult = {
128
+ step,
129
+ stepIndex: i,
130
+ success: false,
131
+ response: null,
132
+ error: `Skipped: depends on failed ${failedStepNames}`,
133
+ resolvedArgs: step.args ?? {},
134
+ durationMs: 0,
135
+ };
136
+ this.stepResults.push(skipResult);
137
+ // Continue to next step (don't break, let the workflow continue)
138
+ // The step failure will be handled by the existing logic
139
+ if (!step.optional && !this.options.continueOnError) {
140
+ success = false;
141
+ failureReason = skipResult.error;
142
+ failedStepIndex = i;
143
+ break;
144
+ }
145
+ continue;
146
+ }
147
+ }
148
+ // Emit executing progress before step
149
+ this.emitProgress(workflow, 'executing', i, startTime, step);
150
+ const stepResult = await this.executeStep(step, i, workflow);
151
+ this.stepResults.push(stepResult);
152
+ // Take snapshot after each step if enabled
153
+ if (this.stateTracker && this.options.stateTracking?.snapshotAfterEachStep) {
154
+ checkAborted(signal, `State snapshot after step ${i + 1}`);
155
+ const snapshot = await this.stateTracker.takeSnapshot(i);
156
+ snapshots.push(snapshot);
157
+ // Compare with previous snapshot to detect changes
158
+ if (snapshots.length >= 2) {
159
+ const prevSnapshot = snapshots[snapshots.length - 2];
160
+ const stepChanges = this.stateTracker.compareSnapshots(prevSnapshot, snapshot, i);
161
+ changes.push(...stepChanges);
162
+ }
163
+ }
164
+ if (!stepResult.success) {
165
+ if (!step.optional && !this.options.continueOnError) {
166
+ success = false;
167
+ failureReason = stepResult.error ?? 'Step failed';
168
+ failedStepIndex = i;
169
+ break;
170
+ }
171
+ }
172
+ }
173
+ // Take final state snapshot if enabled
174
+ if (this.stateTracker && this.options.stateTracking?.snapshotAfter) {
175
+ checkAborted(signal, 'Final state snapshot');
176
+ this.logger.debug('Taking final state snapshot');
177
+ const finalSnapshot = await this.stateTracker.takeSnapshot(this.stepResults.length - 1);
178
+ // If we haven't been taking per-step snapshots, compare initial to final
179
+ if (!this.options.stateTracking?.snapshotAfterEachStep && snapshots.length > 0) {
180
+ const initialSnapshot = snapshots[0];
181
+ const overallChanges = this.stateTracker.compareSnapshots(initialSnapshot, finalSnapshot, this.stepResults.length - 1);
182
+ changes.push(...overallChanges);
183
+ }
184
+ snapshots.push(finalSnapshot);
185
+ }
186
+ // Build data flow graph
187
+ const dataFlow = this.buildDataFlowGraph(workflow);
188
+ // Build state tracking result
189
+ let stateTracking;
190
+ if (this.stateTracker) {
191
+ checkAborted(signal, 'State tracking summary');
192
+ const toolRoles = this.stateTracker.getAllToolInfo();
193
+ let dependencies = this.stateTracker.inferDependencies(this.stepResults);
194
+ // Verify dependencies if we have snapshots
195
+ if (snapshots.length > 0 && changes.length > 0) {
196
+ dependencies = this.stateTracker.verifyDependencies(dependencies, snapshots, changes);
197
+ }
198
+ const summary = await this.stateTracker.generateSummary({
199
+ snapshots,
200
+ changes,
201
+ dependencies,
202
+ toolRoles,
203
+ });
204
+ stateTracking = {
205
+ snapshots,
206
+ changes,
207
+ dependencies,
208
+ toolRoles,
209
+ summary,
210
+ };
211
+ this.logger.debug({
212
+ snapshotCount: snapshots.length,
213
+ changeCount: changes.length,
214
+ dependencyCount: dependencies.length,
215
+ }, 'State tracking complete');
216
+ }
217
+ // Generate summary if requested
218
+ let summary;
219
+ if (this.options.generateSummary) {
220
+ checkAborted(signal, 'Workflow summary generation');
221
+ // Emit summarizing progress
222
+ this.emitProgress(workflow, 'summarizing', workflow.steps.length, startTime);
223
+ summary = await this.generateWorkflowSummary(workflow, this.stepResults, success);
224
+ }
225
+ // Emit complete progress
226
+ this.emitProgress(workflow, 'complete', workflow.steps.length, startTime);
227
+ const durationMs = Date.now() - startTime;
228
+ this.logger.info({
229
+ workflowId: workflow.id,
230
+ success,
231
+ stepsCompleted: this.stepResults.length,
232
+ stepsFailed: this.stepResults.filter(r => !r.success).length,
233
+ durationMs,
234
+ }, 'Workflow execution complete');
235
+ done();
236
+ return {
237
+ workflow,
238
+ steps: this.stepResults,
239
+ success,
240
+ failureReason,
241
+ failedStepIndex,
242
+ durationMs,
243
+ dataFlow,
244
+ summary,
245
+ stateTracking,
246
+ };
247
+ }
248
+ /**
249
+ * Execute a single workflow step.
250
+ */
251
+ async executeStep(step, stepIndex, workflow) {
252
+ const startTime = Date.now();
253
+ // Verify tool exists
254
+ const tool = this.tools.find(t => t.name === step.tool);
255
+ if (!tool) {
256
+ return {
257
+ step,
258
+ stepIndex,
259
+ success: false,
260
+ response: null,
261
+ error: `Tool not found: ${step.tool}`,
262
+ resolvedArgs: {},
263
+ durationMs: Date.now() - startTime,
264
+ };
265
+ }
266
+ // Resolve arguments (apply mapping from previous steps)
267
+ let resolvedArgs;
268
+ try {
269
+ resolvedArgs = this.resolveArguments(step, stepIndex);
270
+ }
271
+ catch (error) {
272
+ return {
273
+ step,
274
+ stepIndex,
275
+ success: false,
276
+ response: null,
277
+ error: `Failed to resolve arguments: ${error instanceof Error ? error.message : String(error)}`,
278
+ resolvedArgs: step.args ?? {},
279
+ durationMs: Date.now() - startTime,
280
+ };
281
+ }
282
+ // Execute the tool call with timeout
283
+ let response = null;
284
+ let error;
285
+ const stepTimeout = this.options.stepTimeout ?? DEFAULT_OPTIONS.stepTimeout;
286
+ try {
287
+ response = await withTimeout(this.client.callTool(step.tool, resolvedArgs), stepTimeout, `Tool call '${step.tool}'`);
288
+ if (response.isError) {
289
+ error = this.extractErrorMessage(response);
290
+ }
291
+ }
292
+ catch (e) {
293
+ error = e instanceof Error ? e.message : String(e);
294
+ }
295
+ // Run assertions
296
+ const assertionResults = step.assertions
297
+ ? this.runAssertions(step.assertions, response)
298
+ : undefined;
299
+ const assertionsFailed = assertionResults?.some(r => !r.passed) ?? false;
300
+ const success = !error && !assertionsFailed;
301
+ // Generate analysis if requested
302
+ let analysis;
303
+ if (this.options.analyzeSteps) {
304
+ analysis = await this.analyzeStep(step, stepIndex, workflow, response, error);
305
+ }
306
+ return {
307
+ step,
308
+ stepIndex,
309
+ success,
310
+ response,
311
+ error,
312
+ resolvedArgs,
313
+ assertionResults,
314
+ durationMs: Date.now() - startTime,
315
+ analysis,
316
+ };
317
+ }
318
+ /**
319
+ * Resolve arguments for a step, applying mappings from previous step outputs.
320
+ */
321
+ resolveArguments(step, stepIndex) {
322
+ const args = { ...(step.args ?? {}) };
323
+ if (!step.argMapping) {
324
+ return args;
325
+ }
326
+ for (const [paramName, pathExpr] of Object.entries(step.argMapping)) {
327
+ const value = this.resolvePath(pathExpr, stepIndex);
328
+ if (value !== undefined) {
329
+ args[paramName] = value;
330
+ }
331
+ }
332
+ return args;
333
+ }
334
+ /**
335
+ * Resolve a JSONPath-like expression against previous step results.
336
+ * Supports: $steps[n].result.path.to.value
337
+ */
338
+ resolvePath(pathExpr, currentStepIndex) {
339
+ // Parse the path expression
340
+ const match = pathExpr.match(/^\$steps\[(\d+)\]\.(.+)$/);
341
+ if (!match) {
342
+ throw new Error(`Invalid path expression: ${pathExpr}. Expected format: $steps[n].path.to.value`);
343
+ }
344
+ const stepIndex = parseInt(match[1], 10);
345
+ const propertyPath = match[2];
346
+ if (stepIndex >= currentStepIndex) {
347
+ throw new Error(`Cannot reference step ${stepIndex} from step ${currentStepIndex} (can only reference earlier steps)`);
348
+ }
349
+ const stepResult = this.stepResults[stepIndex];
350
+ if (!stepResult) {
351
+ throw new Error(`Step ${stepIndex} has not been executed yet`);
352
+ }
353
+ if (!stepResult.success || !stepResult.response) {
354
+ throw new Error(`Step ${stepIndex} failed or has no response`);
355
+ }
356
+ // Navigate the property path
357
+ // First check if we're accessing 'result' (the raw content) or 'response' (the full response)
358
+ let target;
359
+ if (propertyPath.startsWith('result.') || propertyPath === 'result') {
360
+ // Extract text content from the response
361
+ const content = stepResult.response.content;
362
+ const textContent = content.find(c => c.type === 'text' && c.text !== undefined);
363
+ if (!textContent || textContent.text === undefined) {
364
+ throw new Error(`Step ${stepIndex} response has no text content`);
365
+ }
366
+ const textValue = textContent.text;
367
+ // Try to parse as JSON
368
+ try {
369
+ target = JSON.parse(textValue);
370
+ }
371
+ catch {
372
+ target = textValue;
373
+ }
374
+ // Navigate the remaining path after 'result.'
375
+ const remainingPath = propertyPath.replace(/^result\.?/, '');
376
+ if (remainingPath) {
377
+ target = this.navigatePath(target, remainingPath);
378
+ }
379
+ }
380
+ else if (propertyPath.startsWith('response.')) {
381
+ target = this.navigatePath(stepResult.response, propertyPath.replace(/^response\./, ''));
382
+ }
383
+ else {
384
+ throw new Error(`Path must start with 'result.' or 'response.': ${pathExpr}`);
385
+ }
386
+ return target;
387
+ }
388
+ /**
389
+ * Navigate a dot-separated path in an object.
390
+ */
391
+ navigatePath(obj, path) {
392
+ const parts = path.split('.');
393
+ let current = obj;
394
+ for (const part of parts) {
395
+ if (current === null || current === undefined) {
396
+ return undefined;
397
+ }
398
+ // Handle array access: field[0]
399
+ const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
400
+ if (arrayMatch) {
401
+ const [, fieldName, indexStr] = arrayMatch;
402
+ const index = parseInt(indexStr, 10);
403
+ current = current[fieldName];
404
+ if (Array.isArray(current)) {
405
+ current = current[index];
406
+ }
407
+ else {
408
+ return undefined;
409
+ }
410
+ }
411
+ else {
412
+ current = current[part];
413
+ }
414
+ }
415
+ return current;
416
+ }
417
+ /**
418
+ * Run assertions against a step response.
419
+ */
420
+ runAssertions(assertions, response) {
421
+ return assertions.map(assertion => this.runAssertion(assertion, response));
422
+ }
423
+ /**
424
+ * Run a single assertion.
425
+ */
426
+ runAssertion(assertion, response) {
427
+ if (!response) {
428
+ return {
429
+ assertion,
430
+ passed: false,
431
+ message: assertion.message ?? 'No response to assert against',
432
+ };
433
+ }
434
+ // Extract the value at the path
435
+ let actualValue;
436
+ try {
437
+ // Parse the response content as JSON
438
+ const textContent = response.content.find(c => c.type === 'text' && c.text !== undefined);
439
+ if (!textContent || textContent.text === undefined) {
440
+ throw new Error('No text content in response');
441
+ }
442
+ const textValue = textContent.text;
443
+ let parsed;
444
+ try {
445
+ parsed = JSON.parse(textValue);
446
+ }
447
+ catch {
448
+ parsed = textValue;
449
+ }
450
+ actualValue = this.navigatePath(parsed, assertion.path);
451
+ }
452
+ catch (error) {
453
+ return {
454
+ assertion,
455
+ passed: false,
456
+ message: `Failed to extract path ${assertion.path}: ${error instanceof Error ? error.message : String(error)}`,
457
+ };
458
+ }
459
+ // Check the condition
460
+ let passed = false;
461
+ switch (assertion.condition) {
462
+ case 'exists':
463
+ passed = actualValue !== undefined && actualValue !== null;
464
+ break;
465
+ case 'truthy':
466
+ passed = Boolean(actualValue);
467
+ break;
468
+ case 'equals':
469
+ passed = actualValue === assertion.value;
470
+ break;
471
+ case 'contains':
472
+ if (typeof actualValue === 'string' && typeof assertion.value === 'string') {
473
+ passed = actualValue.includes(assertion.value);
474
+ }
475
+ else if (Array.isArray(actualValue)) {
476
+ passed = actualValue.includes(assertion.value);
477
+ }
478
+ break;
479
+ case 'type':
480
+ passed = typeof actualValue === assertion.value;
481
+ break;
482
+ }
483
+ return {
484
+ assertion,
485
+ passed,
486
+ actualValue,
487
+ message: passed ? undefined : (assertion.message ?? `Assertion failed: ${assertion.condition}`),
488
+ };
489
+ }
490
+ /**
491
+ * Extract error message from a tool response.
492
+ */
493
+ extractErrorMessage(response) {
494
+ const textContent = response.content.find(c => c.type === 'text');
495
+ if (textContent && 'text' in textContent) {
496
+ return String(textContent.text);
497
+ }
498
+ return 'Unknown error';
499
+ }
500
+ /**
501
+ * Get indices of dependency steps that have failed.
502
+ * Dependencies are steps referenced in argMapping.
503
+ */
504
+ getFailedDependencies(step, stepIndex) {
505
+ if (!step.argMapping) {
506
+ return [];
507
+ }
508
+ const failedDeps = [];
509
+ const seenIndices = new Set();
510
+ for (const pathExpr of Object.values(step.argMapping)) {
511
+ const match = pathExpr.match(/^\$steps\[(\d+)\]\.(.+)$/);
512
+ if (!match)
513
+ continue;
514
+ const depIndex = parseInt(match[1], 10);
515
+ // Skip if we already checked this dependency
516
+ if (seenIndices.has(depIndex))
517
+ continue;
518
+ seenIndices.add(depIndex);
519
+ // Check if the dependency step exists and has failed
520
+ if (depIndex >= 0 && depIndex < stepIndex) {
521
+ const depResult = this.stepResults[depIndex];
522
+ if (depResult && !depResult.success) {
523
+ failedDeps.push(depIndex);
524
+ }
525
+ }
526
+ }
527
+ return failedDeps;
528
+ }
529
+ /**
530
+ * Build a data flow graph showing how data moves between steps.
531
+ */
532
+ buildDataFlowGraph(workflow) {
533
+ const edges = [];
534
+ for (let i = 0; i < workflow.steps.length; i++) {
535
+ const step = workflow.steps[i];
536
+ if (!step.argMapping)
537
+ continue;
538
+ for (const [targetParam, pathExpr] of Object.entries(step.argMapping)) {
539
+ const match = pathExpr.match(/^\$steps\[(\d+)\]\.(.+)$/);
540
+ if (!match)
541
+ continue;
542
+ const fromStep = parseInt(match[1], 10);
543
+ const sourcePath = match[2];
544
+ // Try to get sample value from executed results
545
+ let sampleValue;
546
+ try {
547
+ const stepResult = this.stepResults[fromStep];
548
+ if (stepResult?.response) {
549
+ sampleValue = this.resolvePath(pathExpr, i);
550
+ }
551
+ }
552
+ catch {
553
+ // Ignore resolution errors for graph building
554
+ }
555
+ edges.push({
556
+ fromStep,
557
+ toStep: i,
558
+ sourcePath,
559
+ targetParam,
560
+ sampleValue,
561
+ });
562
+ }
563
+ }
564
+ return edges;
565
+ }
566
+ /**
567
+ * Generate LLM analysis for a step.
568
+ * Returns a fallback message if LLM is not available (check mode).
569
+ */
570
+ async analyzeStep(step, stepIndex, workflow, response, error) {
571
+ // Skip LLM analysis if no LLM is available (check mode)
572
+ if (!this.llm) {
573
+ return error ? `Step failed: ${error}` : 'Step completed.';
574
+ }
575
+ const prompt = buildWorkflowStepAnalysisPrompt({
576
+ workflow,
577
+ step,
578
+ stepIndex,
579
+ response,
580
+ error,
581
+ });
582
+ try {
583
+ return await this.llm.complete(prompt, COMPLETION_OPTIONS.workflowStepAnalysis);
584
+ }
585
+ catch {
586
+ return error ? `Step failed: ${error}` : 'Step completed.';
587
+ }
588
+ }
589
+ /**
590
+ * Generate a summary of the workflow execution.
591
+ * Returns a fallback message if LLM is not available (check mode).
592
+ */
593
+ async generateWorkflowSummary(workflow, stepResults, success) {
594
+ // Skip LLM summary if no LLM is available (check mode)
595
+ if (!this.llm) {
596
+ return success
597
+ ? `Workflow "${workflow.name}" completed successfully with ${stepResults.length} steps.`
598
+ : `Workflow "${workflow.name}" failed at step ${stepResults.findIndex(r => !r.success) + 1}.`;
599
+ }
600
+ const prompt = buildWorkflowSummaryPrompt({ workflow, stepResults, success });
601
+ try {
602
+ return await this.llm.complete(prompt, COMPLETION_OPTIONS.workflowSummary);
603
+ }
604
+ catch {
605
+ return success
606
+ ? `Workflow "${workflow.name}" completed successfully with ${stepResults.length} steps.`
607
+ : `Workflow "${workflow.name}" failed at step ${stepResults.findIndex(r => !r.success) + 1}.`;
608
+ }
609
+ }
610
+ }
611
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Workflow module - chained tool testing.
3
+ */
4
+ export * from './types.js';
5
+ export * from './executor.js';
6
+ export * from './discovery.js';
7
+ export * from './loader.js';
8
+ export * from './state-tracker.js';
9
+ export * from './auto-generator.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Workflow module - chained tool testing.
3
+ */
4
+ export * from './types.js';
5
+ export * from './executor.js';
6
+ export * from './discovery.js';
7
+ export * from './loader.js';
8
+ export * from './state-tracker.js';
9
+ export * from './auto-generator.js';
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Workflow loader - loads workflows from YAML files.
3
+ */
4
+ import type { Workflow } from './types.js';
5
+ /** Default file name for workflow definitions */
6
+ export declare const DEFAULT_WORKFLOWS_FILE: "bellwether-workflows.yaml";
7
+ /**
8
+ * Load workflows from a YAML file.
9
+ * Supports both single-document and multi-document YAML (separated by ---).
10
+ */
11
+ export declare function loadWorkflowsFromFile(path: string): Workflow[];
12
+ /**
13
+ * Try to load workflows from the default file in a directory.
14
+ * Returns null if file doesn't exist.
15
+ *
16
+ * This enables auto-discovery of workflow files similar to how
17
+ * scenarios are auto-loaded from bellwether-tests.yaml.
18
+ */
19
+ export declare function tryLoadDefaultWorkflows(directory: string): Workflow[] | null;
20
+ /**
21
+ * Generate a sample workflow YAML template.
22
+ */
23
+ export declare function generateSampleWorkflowYaml(): string;
24
+ //# sourceMappingURL=loader.d.ts.map