@probelabs/visor 0.1.106 → 0.1.111

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 (530) hide show
  1. package/README.md +71 -2
  2. package/action.yml +1 -1
  3. package/defaults/code-refiner.yaml +114 -0
  4. package/defaults/{.visor.yaml → code-review.yaml} +35 -226
  5. package/defaults/override.yaml +52 -0
  6. package/defaults/task-refinement.yaml +624 -0
  7. package/defaults/visor.tests.yaml +685 -0
  8. package/defaults/visor.yaml +483 -0
  9. package/dist/action-cli-bridge.d.ts +11 -82
  10. package/dist/action-cli-bridge.d.ts.map +1 -1
  11. package/dist/ai-review-service.d.ts +28 -9
  12. package/dist/ai-review-service.d.ts.map +1 -1
  13. package/dist/check-execution-engine.d.ts +19 -331
  14. package/dist/check-execution-engine.d.ts.map +1 -1
  15. package/dist/cli-main.d.ts.map +1 -1
  16. package/dist/cli.d.ts +0 -1
  17. package/dist/cli.d.ts.map +1 -1
  18. package/dist/config.d.ts +16 -0
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/cron-scheduler.d.ts +3 -3
  21. package/dist/cron-scheduler.d.ts.map +1 -1
  22. package/dist/debug-visualizer/ws-server.d.ts +7 -1
  23. package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
  24. package/dist/defaults/code-refiner.yaml +114 -0
  25. package/dist/defaults/{.visor.yaml → code-review.yaml} +35 -226
  26. package/dist/defaults/override.yaml +52 -0
  27. package/dist/defaults/task-refinement.yaml +624 -0
  28. package/dist/defaults/visor.tests.yaml +685 -0
  29. package/dist/defaults/visor.yaml +483 -0
  30. package/dist/docs/DEPLOYMENT.md +118 -0
  31. package/dist/docs/GITHUB_CHECKS.md +280 -0
  32. package/dist/docs/NPM_USAGE.md +208 -0
  33. package/dist/docs/action-reference.md +19 -0
  34. package/dist/docs/advanced-ai.md +237 -0
  35. package/dist/docs/ai-configuration.md +535 -0
  36. package/dist/docs/ai-custom-tools-usage.md +261 -0
  37. package/dist/docs/ai-custom-tools.md +392 -0
  38. package/dist/docs/author-permissions.md +610 -0
  39. package/dist/docs/bot-transports-rfc.md +23 -0
  40. package/dist/docs/ci-cli-mode.md +34 -0
  41. package/dist/docs/claude-code.md +74 -0
  42. package/dist/docs/command-provider.md +559 -0
  43. package/dist/docs/commands.md +8 -0
  44. package/dist/docs/configuration.md +324 -0
  45. package/dist/docs/custom-tools.md +424 -0
  46. package/dist/docs/dashboards/README.md +23 -0
  47. package/dist/docs/dashboards/grafana-visor-diagrams.json +20 -0
  48. package/dist/docs/dashboards/grafana-visor-overview.json +33 -0
  49. package/dist/docs/debug-visualizer-progress.md +572 -0
  50. package/dist/docs/debug-visualizer-rfc.md +691 -0
  51. package/dist/docs/debug-visualizer.md +114 -0
  52. package/dist/docs/debugging.md +636 -0
  53. package/dist/docs/default-output-schema.md +28 -0
  54. package/dist/docs/dependencies.md +369 -0
  55. package/dist/docs/dev-playbook.md +9 -0
  56. package/dist/docs/engine-pause-resume-rfc.md +192 -0
  57. package/dist/docs/engine-state-machine-plan.md +333 -0
  58. package/dist/docs/event-driven-github-integration-rfc.md +743 -0
  59. package/dist/docs/event-triggers.md +292 -0
  60. package/dist/docs/execution-statistics-rfc.md +290 -0
  61. package/dist/docs/fact-validator-gap-analysis.md +178 -0
  62. package/dist/docs/fact-validator-implementation-plan.md +1235 -0
  63. package/dist/docs/fail-if.md +95 -0
  64. package/dist/docs/failure-conditions-implementation.md +271 -0
  65. package/dist/docs/failure-conditions-schema.md +173 -0
  66. package/dist/docs/failure-routing-rfc.md +193 -0
  67. package/dist/docs/failure-routing.md +507 -0
  68. package/dist/docs/foreach-dependency-propagation.md +473 -0
  69. package/dist/docs/github-ops.md +89 -0
  70. package/dist/docs/goto-forward-run-plan.md +113 -0
  71. package/dist/docs/guides/criticality-modes.md +332 -0
  72. package/dist/docs/guides/fault-management-and-contracts.md +738 -0
  73. package/dist/docs/guides/workflow-style-guide.md +224 -0
  74. package/dist/docs/http.md +299 -0
  75. package/dist/docs/human-input-provider.md +372 -0
  76. package/dist/docs/lifecycle-hooks.md +253 -0
  77. package/dist/docs/limits.md +64 -0
  78. package/dist/docs/liquid-templates.md +490 -0
  79. package/dist/docs/loop-routing-refactor.md +89 -0
  80. package/dist/docs/mcp-provider.md +557 -0
  81. package/dist/docs/mcp.md +124 -0
  82. package/dist/docs/memory.md +903 -0
  83. package/dist/docs/observability.md +12 -0
  84. package/dist/docs/output-formats.md +20 -0
  85. package/dist/docs/output-formatting.md +29 -0
  86. package/dist/docs/output-history.md +383 -0
  87. package/dist/docs/performance.md +6 -0
  88. package/dist/docs/pluggable.md +124 -0
  89. package/dist/docs/proposals/snapshot-scope-execution.md +236 -0
  90. package/dist/docs/providers/git-checkout.md +589 -0
  91. package/dist/docs/recipes.md +474 -0
  92. package/dist/docs/rfc/git-checkout-step.md +601 -0
  93. package/dist/docs/rfc/on_init-hook.md +1294 -0
  94. package/dist/docs/rfc/workspace-isolation.md +216 -0
  95. package/dist/docs/roadmap/criticality-implementation-tasks.md +92 -0
  96. package/dist/docs/router-patterns.md +339 -0
  97. package/dist/docs/schema-next-pr.md +10 -0
  98. package/dist/docs/schema-templates.md +68 -0
  99. package/dist/docs/script.md +34 -0
  100. package/dist/docs/sdk.md +222 -0
  101. package/dist/docs/security.md +7 -0
  102. package/dist/docs/suppressions.md +89 -0
  103. package/dist/docs/tag-filtering.md +258 -0
  104. package/dist/docs/telemetry-setup.md +119 -0
  105. package/dist/docs/telemetry-tracing-rfc.md +275 -0
  106. package/dist/docs/test-framework-rfc.md +680 -0
  107. package/dist/docs/testing/assertions.md +85 -0
  108. package/dist/docs/testing/ci.md +44 -0
  109. package/dist/docs/testing/cli.md +41 -0
  110. package/dist/docs/testing/cookbook.md +172 -0
  111. package/dist/docs/testing/dsl-reference.md +199 -0
  112. package/dist/docs/testing/fixtures-and-mocks.md +91 -0
  113. package/dist/docs/testing/flows.md +92 -0
  114. package/dist/docs/testing/getting-started.md +93 -0
  115. package/dist/docs/testing/troubleshooting.md +55 -0
  116. package/dist/docs/timeouts.md +50 -0
  117. package/dist/docs/troubleshooting.md +7 -0
  118. package/dist/docs/visor-sdk-rfc.md +186 -0
  119. package/dist/docs/workflows.md +569 -0
  120. package/dist/engine/on-finish/orchestrator.d.ts +19 -0
  121. package/dist/engine/on-finish/orchestrator.d.ts.map +1 -0
  122. package/dist/engine/on-finish/utils.d.ts +44 -0
  123. package/dist/engine/on-finish/utils.d.ts.map +1 -0
  124. package/dist/event-bus/event-bus.d.ts +13 -0
  125. package/dist/event-bus/event-bus.d.ts.map +1 -0
  126. package/dist/event-bus/types.d.ts +71 -0
  127. package/dist/event-bus/types.d.ts.map +1 -0
  128. package/dist/examples/.claude/agents/code-reviewer.md +69 -0
  129. package/dist/examples/.mcp.json +34 -0
  130. package/dist/examples/CALCULATOR-SDK.md +364 -0
  131. package/dist/examples/README.md +384 -0
  132. package/dist/examples/ai-custom-tools-example.yaml +206 -0
  133. package/dist/examples/ai-custom-tools-simple.yaml +76 -0
  134. package/dist/examples/ai-retry-fallback-config.yaml +180 -0
  135. package/dist/examples/ai-with-bash.yaml +126 -0
  136. package/dist/examples/ai-with-mcp.yaml +82 -0
  137. package/dist/examples/basic-human-input.yaml +15 -0
  138. package/dist/examples/bedrock-config.yaml +77 -0
  139. package/dist/examples/calculator-config.yaml +133 -0
  140. package/dist/examples/calculator-json-output-guide.md +311 -0
  141. package/dist/examples/calculator-sdk-automated.ts +340 -0
  142. package/dist/examples/calculator-sdk-example.ts +275 -0
  143. package/dist/examples/calculator-sdk-json.ts +331 -0
  144. package/dist/examples/calculator-sdk-real.ts +374 -0
  145. package/dist/examples/calculator-sdk-test.ts +148 -0
  146. package/dist/examples/claude-code-config.yaml +191 -0
  147. package/dist/examples/cron-webhook-config.yaml +215 -0
  148. package/dist/examples/custom-template.liquid +57 -0
  149. package/dist/examples/custom-tools-example.yaml +281 -0
  150. package/dist/examples/enhanced-config.yaml +165 -0
  151. package/dist/examples/environments/visor.base.yaml +92 -0
  152. package/dist/examples/environments/visor.dev.yaml +33 -0
  153. package/dist/examples/environments/visor.prod.yaml +95 -0
  154. package/dist/examples/environments/visor.staging.yaml +46 -0
  155. package/dist/examples/fact-validator.yaml +361 -0
  156. package/dist/examples/fail-if-simple.yaml +90 -0
  157. package/dist/examples/failure-conditions-advanced.yaml +136 -0
  158. package/dist/examples/failure-conditions-basic.yaml +48 -0
  159. package/dist/examples/failure-conditions-github-style.yaml +119 -0
  160. package/dist/examples/failure-conditions-migration.yaml +74 -0
  161. package/dist/examples/for-loop-example.yaml +176 -0
  162. package/dist/examples/forEach-example.yaml +120 -0
  163. package/dist/examples/git-checkout-basic.yaml +32 -0
  164. package/dist/examples/git-checkout-compare.yaml +59 -0
  165. package/dist/examples/git-checkout-cross-repo.yaml +76 -0
  166. package/dist/examples/github-workflow-with-tags.yml +163 -0
  167. package/dist/examples/http-integration-config.yaml +240 -0
  168. package/dist/examples/https-server-config.yaml +209 -0
  169. package/dist/examples/human-input-example.yaml +63 -0
  170. package/dist/examples/if-conditions.yaml +173 -0
  171. package/dist/examples/jira-simple-example.yaml +56 -0
  172. package/dist/examples/jira-single-issue-workflow.yaml +166 -0
  173. package/dist/examples/jira-workflow-mcp.yaml +182 -0
  174. package/dist/examples/mcp/analyzer.py +119 -0
  175. package/dist/examples/mcp-provider-example.yaml +301 -0
  176. package/dist/examples/memory-counter.yaml +99 -0
  177. package/dist/examples/memory-error-collection.yaml +104 -0
  178. package/dist/examples/memory-exec-js.yaml +247 -0
  179. package/dist/examples/memory-namespace-isolation.yaml +184 -0
  180. package/dist/examples/memory-retry-counter.yaml +65 -0
  181. package/dist/examples/memory-state-machine.yaml +170 -0
  182. package/dist/examples/on-init-import-demo.yaml +179 -0
  183. package/dist/examples/outputs-raw-basic.yaml +26 -0
  184. package/dist/examples/project-with-tools.yaml +174 -0
  185. package/dist/examples/prompts/architecture-analysis.liquid +116 -0
  186. package/dist/examples/prompts/security-comprehensive.liquid +107 -0
  187. package/dist/examples/quick-start-tags.yaml +53 -0
  188. package/dist/examples/reusable-tools.yaml +92 -0
  189. package/dist/examples/reusable-workflows.yaml +88 -0
  190. package/dist/examples/routing-basic.yaml +35 -0
  191. package/dist/examples/routing-dynamic-js.yaml +46 -0
  192. package/dist/examples/routing-foreach.yaml +34 -0
  193. package/dist/examples/routing-goto-event.yaml +34 -0
  194. package/dist/examples/routing-on-success.yaml +25 -0
  195. package/dist/examples/run-calculator-demo.sh +71 -0
  196. package/dist/examples/sdk-basic.mjs +10 -0
  197. package/dist/examples/sdk-cjs.cjs +10 -0
  198. package/dist/examples/sdk-comprehensive.mjs +175 -0
  199. package/dist/examples/sdk-manual-config.mjs +65 -0
  200. package/dist/examples/sdk-typescript.js +81 -0
  201. package/dist/examples/sdk-typescript.ts +92 -0
  202. package/dist/examples/session-reuse-config.yaml +151 -0
  203. package/dist/examples/session-reuse-self.yaml +81 -0
  204. package/dist/examples/slack-simple-chat.yaml +775 -0
  205. package/dist/examples/templates/security-report.liquid +137 -0
  206. package/dist/examples/tools-library.yaml +281 -0
  207. package/dist/examples/transform-example.yaml +199 -0
  208. package/dist/examples/visor-with-tags.yaml +198 -0
  209. package/dist/examples/webhook-pipeline-config.yaml +218 -0
  210. package/dist/examples/workflows/calculator-workflow.yaml +163 -0
  211. package/dist/examples/workflows/code-quality.yaml +222 -0
  212. package/dist/examples/workflows/quick-pr-check.yaml +90 -0
  213. package/dist/examples/workflows/workflow-composition-example.yaml +130 -0
  214. package/dist/failure-condition-evaluator.d.ts +3 -0
  215. package/dist/failure-condition-evaluator.d.ts.map +1 -1
  216. package/dist/frontends/github-frontend.d.ts +58 -0
  217. package/dist/frontends/github-frontend.d.ts.map +1 -0
  218. package/dist/frontends/host.d.ts +47 -0
  219. package/dist/frontends/host.d.ts.map +1 -0
  220. package/dist/frontends/ndjson-sink.d.ts +12 -0
  221. package/dist/frontends/ndjson-sink.d.ts.map +1 -0
  222. package/dist/frontends/slack-frontend.d.ts +58 -0
  223. package/dist/frontends/slack-frontend.d.ts.map +1 -0
  224. package/dist/generated/config-schema.d.ts +967 -57
  225. package/dist/generated/config-schema.d.ts.map +1 -1
  226. package/dist/generated/config-schema.json +1033 -56
  227. package/dist/github-check-service.d.ts +4 -6
  228. package/dist/github-check-service.d.ts.map +1 -1
  229. package/dist/github-comments.d.ts +2 -4
  230. package/dist/github-comments.d.ts.map +1 -1
  231. package/dist/index.d.ts.map +1 -1
  232. package/dist/index.js +134327 -99004
  233. package/dist/liquid-extensions.d.ts.map +1 -1
  234. package/dist/logger.d.ts +2 -0
  235. package/dist/logger.d.ts.map +1 -1
  236. package/dist/memory-store.d.ts +6 -0
  237. package/dist/memory-store.d.ts.map +1 -1
  238. package/dist/output/assistant-json/template.liquid +0 -0
  239. package/dist/output/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
  240. package/dist/output/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
  241. package/dist/output-formatters.d.ts +1 -1
  242. package/dist/output-formatters.d.ts.map +1 -1
  243. package/dist/providers/ai-check-provider.d.ts +12 -0
  244. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  245. package/dist/providers/check-provider-registry.d.ts +6 -0
  246. package/dist/providers/check-provider-registry.d.ts.map +1 -1
  247. package/dist/providers/check-provider.interface.d.ts +43 -1
  248. package/dist/providers/check-provider.interface.d.ts.map +1 -1
  249. package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
  250. package/dist/providers/command-check-provider.d.ts +1 -1
  251. package/dist/providers/command-check-provider.d.ts.map +1 -1
  252. package/dist/providers/custom-tool-executor.d.ts +61 -0
  253. package/dist/providers/custom-tool-executor.d.ts.map +1 -0
  254. package/dist/providers/git-checkout-provider.d.ts +25 -0
  255. package/dist/providers/git-checkout-provider.d.ts.map +1 -0
  256. package/dist/providers/github-ops-provider.d.ts.map +1 -1
  257. package/dist/providers/http-client-provider.d.ts +4 -4
  258. package/dist/providers/http-client-provider.d.ts.map +1 -1
  259. package/dist/providers/human-input-check-provider.d.ts +5 -0
  260. package/dist/providers/human-input-check-provider.d.ts.map +1 -1
  261. package/dist/providers/index.d.ts +1 -0
  262. package/dist/providers/index.d.ts.map +1 -1
  263. package/dist/providers/log-check-provider.d.ts +2 -5
  264. package/dist/providers/log-check-provider.d.ts.map +1 -1
  265. package/dist/providers/mcp-check-provider.d.ts +10 -4
  266. package/dist/providers/mcp-check-provider.d.ts.map +1 -1
  267. package/dist/providers/mcp-custom-sse-server.d.ts +66 -0
  268. package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -0
  269. package/dist/providers/memory-check-provider.d.ts +2 -8
  270. package/dist/providers/memory-check-provider.d.ts.map +1 -1
  271. package/dist/providers/script-check-provider.d.ts +25 -0
  272. package/dist/providers/script-check-provider.d.ts.map +1 -0
  273. package/dist/providers/workflow-check-provider.d.ts +56 -0
  274. package/dist/providers/workflow-check-provider.d.ts.map +1 -0
  275. package/dist/reviewer.d.ts +2 -1
  276. package/dist/reviewer.d.ts.map +1 -1
  277. package/dist/sdk/check-provider-registry-534KL5HT.mjs +27 -0
  278. package/dist/sdk/chunk-23L3QRYX.mjs +16872 -0
  279. package/dist/sdk/chunk-23L3QRYX.mjs.map +1 -0
  280. package/dist/sdk/{chunk-TUTOLSFV.mjs → chunk-3OMWVM6J.mjs} +11 -1
  281. package/dist/sdk/chunk-3OMWVM6J.mjs.map +1 -0
  282. package/dist/sdk/chunk-7UK3NIIT.mjs +482 -0
  283. package/dist/sdk/chunk-7UK3NIIT.mjs.map +1 -0
  284. package/dist/sdk/chunk-AGIZJ4UZ.mjs +173 -0
  285. package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +1 -0
  286. package/dist/sdk/chunk-AIVFBIS4.mjs +1371 -0
  287. package/dist/sdk/chunk-AIVFBIS4.mjs.map +1 -0
  288. package/dist/sdk/chunk-AK6BVWIT.mjs +426 -0
  289. package/dist/sdk/chunk-AK6BVWIT.mjs.map +1 -0
  290. package/dist/sdk/chunk-AUT26LHW.mjs +139 -0
  291. package/dist/sdk/chunk-AUT26LHW.mjs.map +1 -0
  292. package/dist/sdk/chunk-BOVFH3LI.mjs +232 -0
  293. package/dist/sdk/chunk-BOVFH3LI.mjs.map +1 -0
  294. package/dist/sdk/chunk-CNX7V5JK.mjs +89 -0
  295. package/dist/sdk/chunk-CNX7V5JK.mjs.map +1 -0
  296. package/dist/sdk/chunk-HTOKWMPO.mjs +157 -0
  297. package/dist/sdk/chunk-HTOKWMPO.mjs.map +1 -0
  298. package/dist/sdk/chunk-NAW3DB3I.mjs +197 -0
  299. package/dist/sdk/chunk-NAW3DB3I.mjs.map +1 -0
  300. package/dist/sdk/chunk-O5EZDNYL.mjs +274 -0
  301. package/dist/sdk/chunk-O5EZDNYL.mjs.map +1 -0
  302. package/dist/sdk/chunk-QR7MOMJH.mjs +558 -0
  303. package/dist/sdk/chunk-QR7MOMJH.mjs.map +1 -0
  304. package/dist/sdk/chunk-QY2XYPEV.mjs +3556 -0
  305. package/dist/sdk/chunk-QY2XYPEV.mjs.map +1 -0
  306. package/dist/sdk/chunk-S2RUE2RG.mjs +145 -0
  307. package/dist/sdk/chunk-S2RUE2RG.mjs.map +1 -0
  308. package/dist/sdk/chunk-SIWNBRTK.mjs +800 -0
  309. package/dist/sdk/chunk-SIWNBRTK.mjs.map +1 -0
  310. package/dist/sdk/chunk-YSN4G6CI.mjs +146 -0
  311. package/dist/sdk/chunk-YSN4G6CI.mjs.map +1 -0
  312. package/dist/sdk/chunk-ZYAUYXSW.mjs +206 -0
  313. package/dist/sdk/chunk-ZYAUYXSW.mjs.map +1 -0
  314. package/dist/sdk/command-executor-TYUV6HUS.mjs +14 -0
  315. package/dist/sdk/config-YNC2EOOT.mjs +16 -0
  316. package/dist/sdk/config-merger-PX3WIT57.mjs +10 -0
  317. package/dist/sdk/event-bus-5BEVPQ6T.mjs +35 -0
  318. package/dist/sdk/event-bus-5BEVPQ6T.mjs.map +1 -0
  319. package/dist/sdk/failure-condition-evaluator-YGTF2GHG.mjs +17 -0
  320. package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs +458 -0
  321. package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs.map +1 -0
  322. package/dist/sdk/github-frontend-SIAEOCON.mjs +1420 -0
  323. package/dist/sdk/github-frontend-SIAEOCON.mjs.map +1 -0
  324. package/dist/sdk/host-DXUYTNMU.mjs +52 -0
  325. package/dist/sdk/host-DXUYTNMU.mjs.map +1 -0
  326. package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs → liquid-extensions-PKWCKK7E.mjs} +8 -2
  327. package/dist/sdk/memory-store-XGBB7LX7.mjs +12 -0
  328. package/dist/sdk/memory-store-XGBB7LX7.mjs.map +1 -0
  329. package/dist/sdk/metrics-7PP3EJUH.mjs +29 -0
  330. package/dist/sdk/metrics-7PP3EJUH.mjs.map +1 -0
  331. package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs +44 -0
  332. package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs.map +1 -0
  333. package/dist/sdk/prompt-state-YRJY6QAL.mjs +16 -0
  334. package/dist/sdk/prompt-state-YRJY6QAL.mjs.map +1 -0
  335. package/dist/sdk/renderer-schema-LPKN5UJS.mjs +51 -0
  336. package/dist/sdk/renderer-schema-LPKN5UJS.mjs.map +1 -0
  337. package/dist/sdk/routing-6N45MJ4F.mjs +24 -0
  338. package/dist/sdk/routing-6N45MJ4F.mjs.map +1 -0
  339. package/dist/sdk/sdk.d.mts +541 -22
  340. package/dist/sdk/sdk.d.ts +541 -22
  341. package/dist/sdk/sdk.js +27963 -16505
  342. package/dist/sdk/sdk.js.map +1 -1
  343. package/dist/sdk/sdk.mjs +1116 -2169
  344. package/dist/sdk/sdk.mjs.map +1 -1
  345. package/dist/sdk/session-registry-4E6YRQ77.mjs +10 -0
  346. package/dist/sdk/session-registry-4E6YRQ77.mjs.map +1 -0
  347. package/dist/sdk/slack-frontend-BVKW3GD5.mjs +735 -0
  348. package/dist/sdk/slack-frontend-BVKW3GD5.mjs.map +1 -0
  349. package/dist/sdk/trace-helpers-VP6QYVBX.mjs +23 -0
  350. package/dist/sdk/trace-helpers-VP6QYVBX.mjs.map +1 -0
  351. package/dist/sdk/{tracer-init-WC75N5NW.mjs → tracer-init-GSLPPLCD.mjs} +2 -2
  352. package/dist/sdk/tracer-init-GSLPPLCD.mjs.map +1 -0
  353. package/dist/sdk/workflow-registry-R6KSACFR.mjs +12 -0
  354. package/dist/sdk/workflow-registry-R6KSACFR.mjs.map +1 -0
  355. package/dist/sdk.d.ts.map +1 -1
  356. package/dist/slack/adapter.d.ts +36 -0
  357. package/dist/slack/adapter.d.ts.map +1 -0
  358. package/dist/slack/cache-prewarmer.d.ts +31 -0
  359. package/dist/slack/cache-prewarmer.d.ts.map +1 -0
  360. package/dist/slack/client.d.ts +77 -0
  361. package/dist/slack/client.d.ts.map +1 -0
  362. package/dist/slack/markdown.d.ts +45 -0
  363. package/dist/slack/markdown.d.ts.map +1 -0
  364. package/dist/slack/prompt-state.d.ts +33 -0
  365. package/dist/slack/prompt-state.d.ts.map +1 -0
  366. package/dist/slack/rate-limiter.d.ts +56 -0
  367. package/dist/slack/rate-limiter.d.ts.map +1 -0
  368. package/dist/slack/signature.d.ts +2 -0
  369. package/dist/slack/signature.d.ts.map +1 -0
  370. package/dist/slack/socket-runner.d.ts +42 -0
  371. package/dist/slack/socket-runner.d.ts.map +1 -0
  372. package/dist/slack/thread-cache.d.ts +51 -0
  373. package/dist/slack/thread-cache.d.ts.map +1 -0
  374. package/dist/snapshot-store.d.ts +59 -0
  375. package/dist/snapshot-store.d.ts.map +1 -0
  376. package/dist/state-machine/context/build-engine-context.d.ts +17 -0
  377. package/dist/state-machine/context/build-engine-context.d.ts.map +1 -0
  378. package/dist/state-machine/dispatch/dependency-gating.d.ts +12 -0
  379. package/dist/state-machine/dispatch/dependency-gating.d.ts.map +1 -0
  380. package/dist/state-machine/dispatch/execution-invoker.d.ts +14 -0
  381. package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -0
  382. package/dist/state-machine/dispatch/foreach-processor.d.ts +8 -0
  383. package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -0
  384. package/dist/state-machine/dispatch/history-snapshot.d.ts +8 -0
  385. package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -0
  386. package/dist/state-machine/dispatch/on-init-handlers.d.ts +43 -0
  387. package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -0
  388. package/dist/state-machine/dispatch/renderer-schema.d.ts +8 -0
  389. package/dist/state-machine/dispatch/renderer-schema.d.ts.map +1 -0
  390. package/dist/state-machine/dispatch/stats-manager.d.ts +15 -0
  391. package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -0
  392. package/dist/state-machine/dispatch/template-renderer.d.ts +7 -0
  393. package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -0
  394. package/dist/state-machine/execution/summary.d.ts +8 -0
  395. package/dist/state-machine/execution/summary.d.ts.map +1 -0
  396. package/dist/state-machine/runner.d.ts +79 -0
  397. package/dist/state-machine/runner.d.ts.map +1 -0
  398. package/dist/state-machine/states/check-running.d.ts +14 -0
  399. package/dist/state-machine/states/check-running.d.ts.map +1 -0
  400. package/dist/state-machine/states/completed.d.ts +12 -0
  401. package/dist/state-machine/states/completed.d.ts.map +1 -0
  402. package/dist/state-machine/states/error.d.ts +11 -0
  403. package/dist/state-machine/states/error.d.ts.map +1 -0
  404. package/dist/state-machine/states/init.d.ts +11 -0
  405. package/dist/state-machine/states/init.d.ts.map +1 -0
  406. package/dist/state-machine/states/level-dispatch.d.ts +17 -0
  407. package/dist/state-machine/states/level-dispatch.d.ts.map +1 -0
  408. package/dist/state-machine/states/plan-ready.d.ts +12 -0
  409. package/dist/state-machine/states/plan-ready.d.ts.map +1 -0
  410. package/dist/state-machine/states/routing.d.ts +52 -0
  411. package/dist/state-machine/states/routing.d.ts.map +1 -0
  412. package/dist/state-machine/states/wave-planning.d.ts +14 -0
  413. package/dist/state-machine/states/wave-planning.d.ts.map +1 -0
  414. package/dist/state-machine/workflow-projection.d.ts +47 -0
  415. package/dist/state-machine/workflow-projection.d.ts.map +1 -0
  416. package/dist/state-machine-execution-engine.d.ts +159 -0
  417. package/dist/state-machine-execution-engine.d.ts.map +1 -0
  418. package/dist/telemetry/opentelemetry.d.ts.map +1 -1
  419. package/dist/telemetry/state-capture.d.ts +5 -0
  420. package/dist/telemetry/state-capture.d.ts.map +1 -1
  421. package/dist/test-runner/assertions.d.ts +59 -0
  422. package/dist/test-runner/assertions.d.ts.map +1 -0
  423. package/dist/test-runner/core/environment.d.ts +8 -0
  424. package/dist/test-runner/core/environment.d.ts.map +1 -0
  425. package/dist/test-runner/core/fixture.d.ts +3 -0
  426. package/dist/test-runner/core/fixture.d.ts.map +1 -0
  427. package/dist/test-runner/core/flow-stage.d.ts +32 -0
  428. package/dist/test-runner/core/flow-stage.d.ts.map +1 -0
  429. package/dist/test-runner/core/mocks.d.ts +8 -0
  430. package/dist/test-runner/core/mocks.d.ts.map +1 -0
  431. package/dist/test-runner/core/test-execution-wrapper.d.ts +18 -0
  432. package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -0
  433. package/dist/test-runner/evaluators.d.ts +45 -0
  434. package/dist/test-runner/evaluators.d.ts.map +1 -0
  435. package/dist/test-runner/fixture-loader.d.ts +30 -0
  436. package/dist/test-runner/fixture-loader.d.ts.map +1 -0
  437. package/dist/test-runner/index.d.ts +127 -0
  438. package/dist/test-runner/index.d.ts.map +1 -0
  439. package/dist/test-runner/recorders/github-recorder.d.ts +23 -0
  440. package/dist/test-runner/recorders/github-recorder.d.ts.map +1 -0
  441. package/dist/test-runner/recorders/global-recorder.d.ts +4 -0
  442. package/dist/test-runner/recorders/global-recorder.d.ts.map +1 -0
  443. package/dist/test-runner/recorders/slack-recorder.d.ts +17 -0
  444. package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -0
  445. package/dist/test-runner/utils/selectors.d.ts +2 -0
  446. package/dist/test-runner/utils/selectors.d.ts.map +1 -0
  447. package/dist/test-runner/validator.d.ts +8 -0
  448. package/dist/test-runner/validator.d.ts.map +1 -0
  449. package/dist/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
  450. package/dist/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
  451. package/dist/types/bot.d.ts +109 -0
  452. package/dist/types/bot.d.ts.map +1 -0
  453. package/dist/types/cli.d.ts +8 -1
  454. package/dist/types/cli.d.ts.map +1 -1
  455. package/dist/types/config.d.ts +459 -9
  456. package/dist/types/config.d.ts.map +1 -1
  457. package/dist/types/engine.d.ts +177 -0
  458. package/dist/types/engine.d.ts.map +1 -0
  459. package/dist/types/execution.d.ts +73 -0
  460. package/dist/types/execution.d.ts.map +1 -0
  461. package/dist/types/git-checkout.d.ts +76 -0
  462. package/dist/types/git-checkout.d.ts.map +1 -0
  463. package/dist/types/github.d.ts +51 -0
  464. package/dist/types/github.d.ts.map +1 -0
  465. package/dist/types/workflow.d.ts +237 -0
  466. package/dist/types/workflow.d.ts.map +1 -0
  467. package/dist/utils/command-executor.d.ts +43 -0
  468. package/dist/utils/command-executor.d.ts.map +1 -0
  469. package/dist/utils/comment-metadata.d.ts +21 -0
  470. package/dist/utils/comment-metadata.d.ts.map +1 -0
  471. package/dist/utils/config-loader.d.ts.map +1 -1
  472. package/dist/utils/config-merger.d.ts.map +1 -1
  473. package/dist/utils/env-exposure.d.ts +3 -0
  474. package/dist/utils/env-exposure.d.ts.map +1 -0
  475. package/dist/utils/file-exclusion.d.ts.map +1 -1
  476. package/dist/utils/interactive-prompt.d.ts +1 -1
  477. package/dist/utils/interactive-prompt.d.ts.map +1 -1
  478. package/dist/utils/json-text-extractor.d.ts +17 -0
  479. package/dist/utils/json-text-extractor.d.ts.map +1 -0
  480. package/dist/utils/sandbox.d.ts +10 -0
  481. package/dist/utils/sandbox.d.ts.map +1 -1
  482. package/dist/utils/script-memory-ops.d.ts +21 -0
  483. package/dist/utils/script-memory-ops.d.ts.map +1 -0
  484. package/dist/utils/template-context.d.ts +8 -0
  485. package/dist/utils/template-context.d.ts.map +1 -0
  486. package/dist/utils/tracer-init.d.ts.map +1 -1
  487. package/dist/utils/workspace-manager.d.ts +118 -0
  488. package/dist/utils/workspace-manager.d.ts.map +1 -0
  489. package/dist/utils/worktree-cleanup.d.ts +33 -0
  490. package/dist/utils/worktree-cleanup.d.ts.map +1 -0
  491. package/dist/utils/worktree-manager.d.ts +153 -0
  492. package/dist/utils/worktree-manager.d.ts.map +1 -0
  493. package/dist/webhook-server.d.ts +3 -3
  494. package/dist/webhook-server.d.ts.map +1 -1
  495. package/dist/workflow-executor.d.ts +81 -0
  496. package/dist/workflow-executor.d.ts.map +1 -0
  497. package/dist/workflow-registry.d.ts +79 -0
  498. package/dist/workflow-registry.d.ts.map +1 -0
  499. package/package.json +12 -5
  500. package/dist/output/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
  501. package/dist/sdk/check-execution-engine-2YYKUUSH.mjs +0 -11
  502. package/dist/sdk/check-execution-engine-6QJXYYON.mjs +0 -11
  503. package/dist/sdk/check-execution-engine-PJZ4ZOKG.mjs +0 -11
  504. package/dist/sdk/chunk-33QVZ2D4.mjs +0 -316
  505. package/dist/sdk/chunk-33QVZ2D4.mjs.map +0 -1
  506. package/dist/sdk/chunk-B5QBV2QJ.mjs +0 -752
  507. package/dist/sdk/chunk-B5QBV2QJ.mjs.map +0 -1
  508. package/dist/sdk/chunk-BVFNRCHT.mjs +0 -14129
  509. package/dist/sdk/chunk-BVFNRCHT.mjs.map +0 -1
  510. package/dist/sdk/chunk-KWZW23FG.mjs +0 -14129
  511. package/dist/sdk/chunk-KWZW23FG.mjs.map +0 -1
  512. package/dist/sdk/chunk-O4RP4BRH.mjs +0 -14092
  513. package/dist/sdk/chunk-O4RP4BRH.mjs.map +0 -1
  514. package/dist/sdk/chunk-TUTOLSFV.mjs.map +0 -1
  515. package/dist/sdk/chunk-U5D2LY66.mjs +0 -245
  516. package/dist/sdk/chunk-U5D2LY66.mjs.map +0 -1
  517. package/dist/sdk/chunk-U7X54EMV.mjs +0 -331
  518. package/dist/sdk/chunk-U7X54EMV.mjs.map +0 -1
  519. package/dist/sdk/config-merger-TWUBWFC2.mjs +0 -8
  520. package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs +0 -61
  521. package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs.map +0 -1
  522. package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs +0 -61
  523. package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs.map +0 -1
  524. package/dist/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
  525. /package/dist/sdk/{check-execution-engine-2YYKUUSH.mjs.map → check-provider-registry-534KL5HT.mjs.map} +0 -0
  526. /package/dist/sdk/{check-execution-engine-6QJXYYON.mjs.map → command-executor-TYUV6HUS.mjs.map} +0 -0
  527. /package/dist/sdk/{check-execution-engine-PJZ4ZOKG.mjs.map → config-YNC2EOOT.mjs.map} +0 -0
  528. /package/dist/sdk/{config-merger-TWUBWFC2.mjs.map → config-merger-PX3WIT57.mjs.map} +0 -0
  529. /package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs.map → failure-condition-evaluator-YGTF2GHG.mjs.map} +0 -0
  530. /package/dist/sdk/{tracer-init-WC75N5NW.mjs.map → liquid-extensions-PKWCKK7E.mjs.map} +0 -0
@@ -0,0 +1,680 @@
1
+ # Visor Integration Test Framework (RFC)
2
+
3
+ Status: In Progress
4
+ Date: 2025-10-27
5
+ Owners: @probelabs/visor
6
+
7
+ ## Summary
8
+
9
+ Add a first‑class, YAML‑native integration test framework for Visor that lets teams describe user flows, mocks, and assertions directly alongside their Visor config. Tests are defined in a separate YAML that can `extends` the base configuration, run entirely offline (no network), and default to strict verification.
10
+
11
+ Key ideas:
12
+ - Integration‑first: simulate real GitHub events and repo context; no manual step lists.
13
+ - Strict by default: if a step ran and you didn’t assert it, the test fails.
14
+ - Provider record mode by default: GitHub calls are intercepted and recorded (no network); assert them later.
15
+ - Simple mocks keyed by step name; schema‑aware AI outputs (objects/arrays for structured schemas; `text` for plain).
16
+ - Support multi‑event “flows” that preserve memory and outputs across events.
17
+ (Docs use a “fact validation” workflow as an example pattern only; it is not a built‑in feature.)
18
+
19
+ Developer Guides
20
+ - Getting started: docs/testing/getting-started.md
21
+ - DSL reference: docs/testing/dsl-reference.md
22
+ - Flows: docs/testing/flows.md
23
+ - Fixtures & mocks: docs/testing/fixtures-and-mocks.md
24
+ - Assertions: docs/testing/assertions.md
25
+ - Cookbook: docs/testing/cookbook.md
26
+ - CLI & reporters: docs/testing/cli.md
27
+ - CI integration: docs/testing/ci.md
28
+ - Troubleshooting: docs/testing/troubleshooting.md
29
+
30
+ ## Progress Update (Oct 29, 2025)
31
+
32
+ - Extracted focused helpers to simplify the runner:
33
+ - `EnvironmentManager` (per-case/stage env apply/restore)
34
+ - `MockManager` (step mocks and list-mocks cursors)
35
+ - `buildPrInfoFromFixture` moved to `src/test-runner/core/fixture.ts`
36
+ - Evaluators module scaffolded (`src/test-runner/evaluators.ts`) for assertion logic reuse
37
+ - `setupTestCase` now delegates env and mock management to the helpers.
38
+ - Flow stages: stage-local env now uses `EnvironmentManager`; stage mocks use `MockManager`.
39
+ - Default suite runs green under strict mode; GitHub negative-mode case passes deterministically.
40
+
41
+ Next steps (milestones excerpt)
42
+ - Finish splitting `runFlowCase` into stage helpers (execute, state, assertions) or a `FlowStage` class.
43
+ - Move the large `evaluateCase` body into the evaluators module with no behavior changes.
44
+ - Enrich reporters with per-stage details (JSON/JUnit/Markdown) using structured results.
45
+ - Keep all debug logs behind `VISOR_DEBUG` and remove ad-hoc prints.
46
+
47
+ ## Motivation
48
+
49
+ - Keep tests next to config and use the same mental model: events → checks → outputs → effects.
50
+ - Validate real behavior (routing, `on` filters, `if` guards, `goto`/`on_success`, forEach) rather than unit‑style steps.
51
+ - Make CI reliable and offline by default while still asserting side‑effects (labels, comments, check runs).
52
+
53
+ ## Non‑Goals
54
+
55
+ - Unit testing individual providers (covered by Jest/TS tests).
56
+ - Golden CI logs; we assert structured outputs and recorded operations instead.
57
+
58
+ ## Terminology
59
+
60
+ - Case: a single integration test driven by one event + fixture.
61
+ - Flow: an ordered list of cases; runner preserves memory/outputs across steps.
62
+ - Fixture: a reusable external context (webhook payload, changed files, env, fs overlay, frozen clock).
63
+
64
+ ## File Layout
65
+
66
+ - Base config (unchanged): `defaults/.visor.yaml` (regular steps live here).
67
+ - Test suite (new): `defaults/.visor.tests.yaml`
68
+ - `extends: ".visor.yaml"` to inherit the base checks.
69
+ - Contains `tests.defaults`, `tests.fixtures`, `tests.cases`.
70
+
71
+ ## Default Behaviors (Test Mode)
72
+
73
+ - Strict mode: enabled by default (`tests.defaults.strict: true`). Any executed step must appear in `expect.calls`, or the case fails.
74
+ - GitHub recording: the runner uses a recording Octokit by default; no network calls are made. Assert effects via `expect.calls` with `provider: github` and an `op` (e.g., `issues.createComment`, `labels.add`, `checks.create`).
75
+ - AI provider: `mock` by default for tests; schema‑aware handling (see below).
76
+
77
+ ## Built‑in Fixtures and GitHub Mocks
78
+
79
+ The runner ships with a library of built‑in fixtures and a recording GitHub mock so you don’t have to redefine common scenarios.
80
+
81
+ ### Built‑in Fixtures (gh.*)
82
+
83
+ Use via `fixture: <name>`:
84
+
85
+ - `gh.pr_open.minimal` — pull_request opened with a small PR (branch/base, 1–2 files, tiny patch).
86
+ - `gh.pr_sync.minimal` — pull_request synchronize (new commit pushed) with updated HEAD SHA.
87
+ - `gh.issue_open.minimal` — issues opened with a short title/body.
88
+ - `gh.issue_comment.standard` — issue_comment created with a normal message on a PR.
89
+ - `gh.issue_comment.visor_help` — issue_comment created with "/visor help".
90
+ - `gh.issue_comment.visor_regenerate` — issue_comment created with "/visor Regenerate reviews".
91
+ - `gh.issue_comment.edited` — issue_comment edited event.
92
+ - `gh.pr_closed.minimal` — pull_request closed event.
93
+
94
+ All gh.* fixtures populate:
95
+ - `webhook` (name, action, payload)
96
+ - `git` (branch, baseBranch)
97
+ - `files` and `diff` (for PR fixtures)
98
+ - `env` and `time.now` for determinism
99
+
100
+ Optional overrides (future):
101
+
102
+ ```yaml
103
+ fixture:
104
+ builtin: gh.pr_open.minimal
105
+ overrides:
106
+ pr.title: "feat: custom title"
107
+ webhook.payload.pull_request.number: 42
108
+ ```
109
+
110
+ ### GitHub Recorder (Built‑in)
111
+
112
+ By default in test mode, the runner installs a recording Octokit:
113
+ - Captures all calls and args for assertions (`expect.calls` with `provider: github`).
114
+ - Returns stable stub shapes to unblock flows:
115
+ - `issues.createComment` → `{ data: { id, html_url, body, user, created_at } }`
116
+ - `issues.updateComment` → same shape
117
+ - `pulls.get`, `pulls.listFiles` → derived from fixture
118
+ - `checks.create`, `checks.update` → `{ data: { id, status, conclusion, url } }`
119
+ - `labels.add` → `{ data: { labels: [ ... ] } }` (or a no‑op with capture)
120
+
121
+ No network calls are made. You can still opt into real Octokit in the future with a `mode: passthrough` runner flag (not default).
122
+ Optional negative modes (per case or global):
123
+ - `error(429|422|404)` — simulate API errors; captured in call history.
124
+ - `timeout(1000ms)` — simulate request timeouts.
125
+
126
+ ## YAML Syntax Overview
127
+
128
+ Minimal suite:
129
+
130
+ ```yaml
131
+ version: "1.0"
132
+ extends: ".visor.yaml"
133
+
134
+ tests:
135
+ defaults:
136
+ strict: true
137
+ ai_provider: mock
138
+ macros:
139
+ expect_review_posted:
140
+ calls:
141
+ - provider: github
142
+ op: issues.createComment
143
+ at_least: 1
144
+
145
+ fixtures: [] # (Optional) rely on gh.* built‑ins
146
+
147
+ cases:
148
+ - name: label-flow
149
+ event: pr_opened
150
+ fixture:
151
+ builtin: gh.pr_open.minimal
152
+ overrides:
153
+ pr.title: "feat: add user search"
154
+ mocks:
155
+ overview:
156
+ text: "Overview body"
157
+ tags: { label: feature, review-effort: 2 }
158
+ expect:
159
+ use: [expect_review_posted]
160
+ calls:
161
+ - step: overview
162
+ exactly: 1
163
+ - step: apply-overview-labels
164
+ exactly: 1
165
+ - provider: github
166
+ op: labels.add
167
+ at_least: 1
168
+ args:
169
+ contains_unordered: [feature, "review/effort:2"]
170
+ ```
171
+
172
+ ### Flows (multi‑event)
173
+
174
+ ```yaml
175
+ - name: pr-review-e2e-flow
176
+ strict: true
177
+ flow:
178
+ - name: pr-open
179
+ event: pr_opened
180
+ fixture: gh.pr_open.minimal
181
+ mocks:
182
+ overview: { text: "Overview body", tags: { label: feature, review-effort: 2 } }
183
+ security: { issues: [] }
184
+ quality: { issues: [] }
185
+ performance: { issues: [] }
186
+ expect:
187
+ calls:
188
+ - step: overview
189
+ exactly: 1
190
+ - step: security
191
+ exactly: 1
192
+ - step: architecture
193
+ exactly: 1
194
+ - step: performance
195
+ exactly: 1
196
+ - step: quality
197
+ exactly: 1
198
+ - step: apply-overview-labels
199
+ exactly: 1
200
+ - provider: github
201
+ op: issues.createComment
202
+ at_least: 1
203
+ - provider: github
204
+ op: labels.add
205
+ at_least: 1
206
+ args: { contains: [feature] }
207
+
208
+ - name: visor-plain
209
+ event: issue_comment
210
+ fixture: gh.issue_comment.visor_help
211
+ mocks:
212
+ comment-assistant: { text: "Sure, here's how I can help.", intent: comment_reply }
213
+ expect:
214
+ calls:
215
+ - step: comment-assistant
216
+ exactly: 1
217
+ - provider: github
218
+ op: issues.createComment
219
+ exactly: 1
220
+ outputs:
221
+ - step: comment-assistant
222
+ path: intent
223
+ equals: comment_reply
224
+ ```
225
+
226
+ ## CLI Usage
227
+
228
+ - Discover tests:
229
+ - `node dist/index.js test --config defaults/.visor.tests.yaml --list`
230
+ - Validate test file shape (schema):
231
+ - `node dist/index.js test --config defaults/.visor.tests.yaml --validate`
232
+ - Run all tests with compact progress (default):
233
+ - `node dist/index.js test --config defaults/.visor.tests.yaml`
234
+ - Run a single case:
235
+ - `node dist/index.js test --config defaults/.visor.tests.yaml --only label-flow`
236
+ - Run a single stage in a flow (by name or 1‑based index):
237
+ - `node dist/index.js test --config defaults/.visor.tests.yaml --only pr-review-e2e-flow#facts-invalid`
238
+ - `node dist/index.js test --config defaults/.visor.tests.yaml --only pr-review-e2e-flow#3`
239
+ - Emit artifacts:
240
+ - JSON: `--json output/visor-tests.json`
241
+ - JUnit: `--report junit:output/visor-tests.xml`
242
+ - Markdown summary: `--summary md:output/visor-tests.md`
243
+ - Debug logs:
244
+ - Set `VISOR_DEBUG=true` for verbose routing/provider output.
245
+
246
+ Notes
247
+ - AI is forced to `mock` in test mode regardless of API keys.
248
+ - The runner warns when an AI/command step runs without a mock (suppressed for `ai.provider=mock`).
249
+ - Strict mode is on by default; add `strict: false` for prompt‑only cases.
250
+
251
+ ## Mocks (Schema‑Aware)
252
+
253
+ - Keyed by step name under `mocks`.
254
+ - AI with structured `schema` (e.g., `code-review`, `issue-assistant`): provide an object or array directly; no `returns` key.
255
+ - AI with `schema: plain`: provide a string (or an object with `text`).
256
+ - Command provider: `{ stdout: string, exit_code?: number }`.
257
+ - Arrays: return arrays directly (e.g., `extract-facts`).
258
+
259
+ Examples:
260
+
261
+ ```yaml
262
+ mocks:
263
+ overview:
264
+ text: "Overview body"
265
+ tags: { label: feature, review-effort: 2 }
266
+
267
+ issue-assistant:
268
+ text: "Thanks for the detailed report!"
269
+ intent: issue_triage
270
+ labels: [bug]
271
+
272
+ extract-facts:
273
+ - { id: f1, category: Configuration, claim: "max_parallelism defaults to 4", verifiable: true }
274
+
275
+ unit-tests:
276
+ stdout: '{"passed": 128, "failed": 0}'
277
+ exit_code: 0
278
+ ```
279
+
280
+ ## Assertions
281
+
282
+ ### Macros (Reusable Assertions)
283
+
284
+ Define named bundles of assertions under `tests.defaults.macros` and reuse them via `expect.use: [macroName, ...]`.
285
+
286
+ Example:
287
+
288
+ ```yaml
289
+ tests:
290
+ defaults:
291
+ macros:
292
+ expect_review_posted:
293
+ calls:
294
+ - provider: github
295
+ op: issues.createComment
296
+ at_least: 1
297
+
298
+ cases:
299
+ - name: example
300
+ expect:
301
+ use: [expect_review_posted]
302
+ calls:
303
+ - step: overview
304
+ exactly: 1
305
+ ```
306
+
307
+ - Step calls: `expect.calls: [{ step: <name>, exactly|at_least|at_most: N }]`.
308
+ - GitHub effects: `expect.calls: [{ provider: github, op: <owner.method>, times?, args? }]`.
309
+ - `op` examples: `issues.createComment`, `labels.add`, `checks.create`, `checks.update`.
310
+ - `args.contains` matches arrays/strings; `args.contains_unordered` ignores order; `args.equals` for strict equality.
311
+ - Outputs: `expect.outputs: [{ step, path, equals|matches|equalsDeep }]`.
312
+ - `equalsDeep` performs deep structural comparison for objects/arrays.
313
+ - `path` uses dot/bracket syntax, e.g., `tags['review-effort']`, `issues[0].severity`.
314
+ - Failures: `expect.fail.message_contains` for error message anchoring.
315
+ - Strict violations: `expect.strict_violation.for_step` asserts the runner surfaced “step executed without expect.”
316
+
317
+ ### Prompt Assertions (AI)
318
+
319
+ When mocking AI, you can assert on the final prompt text constructed by Visor (after Liquid templating and context injection):
320
+
321
+ ```yaml
322
+ expect:
323
+ prompts:
324
+ - step: overview
325
+ contains:
326
+ - "feat: add user search" # PR title from fixture
327
+ - "diff --git a/src/search.ts" # patch content included
328
+ not_contains:
329
+ - "BREAKING CHANGE"
330
+ - step: comment-assistant
331
+ matches: "(?i)\\/visor\\s+help" # case-insensitive regex
332
+ ```
333
+
334
+ Rules:
335
+ - `contains`: list of substrings that must appear in the prompt.
336
+ - `not_contains`: list of substrings that must not appear.
337
+ - `matches`: a single regex pattern string; add `(?i)` for case‑insensitive.
338
+ - The runner captures the exact prompt Visor would send to the provider (with dynamic variables resolved and code context embedded) and evaluates these assertions.
339
+
340
+ ## Runner Semantics
341
+
342
+ - Loads base config via `extends` and validates.
343
+ - Applies fixture:
344
+ - Webhook payload → test event context
345
+ - Git metadata (branch/baseBranch)
346
+ - Files + patch list used by analyzers/prompts
347
+ - `fs_overlay` writes transient files (cleaned up after)
348
+ - `env` overlays process env for the case
349
+ - `time.now` freezes clock
350
+ - Event routing: determines which checks run by evaluating `on`, `if`, `depends_on`, `goto`, `on_success`, and `forEach` semantics in the normal engine.
351
+ - Recording providers:
352
+ - GitHub: recording Octokit (default) captures every call; no network.
353
+ - AI: mock provider that emits objects/arrays/strings per mocks and records the final prompt text per step for `expect.prompts`.
354
+ - Dependency routing: the runner uses the same engine logic as Visor, including `depends_on` semantics. Pipe‑separated tokens inside `depends_on` (e.g., `"a|b"`) form ANY‑OF groups. You can mix ALL‑OF and ANY‑OF (e.g., `["a|b", "c"]`).
355
+
356
+ ### Call History and Recursion
357
+
358
+ Some steps (e.g., fact validation loops) can run multiple times within a single case or flow stage. The runner records an invocation history for each step. You assert using the same top‑level sections (calls, prompts, outputs) with selectors:
359
+
360
+ 1) Count only
361
+
362
+ ```yaml
363
+ expect:
364
+ calls:
365
+ - step: validate-fact
366
+ at_least: 2
367
+ ```
368
+
369
+ 2) Per‑call assertions by index (ordered)
370
+
371
+ ```yaml
372
+ expect:
373
+ calls:
374
+ - step: validate-fact
375
+ exactly: 2
376
+ prompts:
377
+ - step: validate-fact
378
+ index: 0
379
+ contains: ["Claim:", "max_parallelism defaults to 4"]
380
+ outputs:
381
+ - step: validate-fact
382
+ index: 0
383
+ path: fact_id
384
+ equals: f1
385
+ ```
386
+
387
+ 3) Per‑call assertions without assuming order (filter by output)
388
+
389
+ ```yaml
390
+ expect:
391
+ calls:
392
+ - step: validate-fact
393
+ at_least: 2
394
+ outputs:
395
+ - step: validate-fact
396
+ where: { path: fact_id, equals: f1 }
397
+ path: is_valid
398
+ equals: true
399
+ - step: validate-fact
400
+ where: { path: fact_id, equals: f2 }
401
+ path: confidence
402
+ equals: high
403
+ ```
404
+
405
+ 4) Select a specific history element
406
+
407
+ ```yaml
408
+ expect:
409
+ prompts:
410
+ - step: validate-fact
411
+ index: last # or 0,1,..., or 'first'
412
+ not_contains: ["TODO"]
413
+ ```
414
+ - HTTP: built‑in mock (url/method/status/body/latency) with record mode and assertions.
415
+ - Command: mock stdout/stderr/exit_code; record invocation for assertions.
416
+ - State across flows: `memory`, `outputs.history`, and step outputs persist across events within a single flow.
417
+ - Strict enforcement: after execution, compare executed steps to `expect.calls`; any missing expect fails the case.
418
+
419
+ ## Validation & Helpful Errors
420
+
421
+ - Reuse Visor's existing Ajv pipeline for the base config (`extends` target).
422
+ - The tests DSL is validated at runtime with friendly errors (no separate schema file to maintain).
423
+ - Errors show the YAML path, a short hint, and an example (e.g., suggest `args.contains_unordered` when order differs).
424
+ - Inline diffs for strings (prompts) and objects (with deep compare) in failure output.
425
+
426
+ ### Determinism & Security
427
+
428
+ - Stable IDs in the GitHub recorder (deterministic counters per run).
429
+ - Order‑agnostic assertions for arrays via `args.contains_unordered`.
430
+ - Prompt normalization (whitespace, code fences). Toggle with `--normalize-prompts=false`.
431
+ - Secret redaction in prompts/args via ENV allowlist (default deny; redacts to `****`).
432
+
433
+ ## CLI
434
+
435
+ ```
436
+ visor test --config defaults/.visor.tests.yaml # run all cases
437
+ visor test --config defaults/.visor.tests.yaml --only pr-review-e2e-flow
438
+ visor test --config defaults/.visor.tests.yaml --list # list case names
439
+ ```
440
+
441
+ Exit codes:
442
+ - 0: all tests passed
443
+ - 1: one or more cases failed
444
+
445
+ ### CLI Output UX (must‑have)
446
+
447
+ The runner prints a concise, human‑friendly summary optimized for scanning:
448
+
449
+ - Suite header with total cases and elapsed time.
450
+ - Per‑case line with status symbol and duration, e.g.,
451
+ - ✅ label-flow (1.23s)
452
+ - ❌ security-fail-if (0.42s)
453
+ - When a case is expanded (auto‑expand on failure):
454
+ - Input context: event + fixture name.
455
+ - Executed steps (in order), with counts for multi‑call steps.
456
+ - Assertions grouped by type (calls, prompts, outputs) with checkmarks.
457
+ - GitHub calls table (op, count, first args snippet).
458
+ - Prompt preview (truncated) with a toggle to show full text.
459
+ - First mismatch shows an inline diff (expected vs actual substring/regex or value), with a clear hint to fix.
460
+ - Flow cases show each stage nested under the parent with roll‑up status.
461
+ - Summary footer with pass/fail counts, slowest cases, and a hint to rerun focused:
462
+ - e.g., visor test --config defaults/.visor.tests.yaml --only security-fail-if
463
+
464
+ Color, symbols, and truncation rules mirror our main CLI:
465
+ - Green checks for passes, red crosses for failures, yellow for skipped.
466
+ - Truncate long prompts/JSON with ellipsis; provide a flag `--verbose` to show full payloads.
467
+
468
+ ### Additional Flags & Modes
469
+
470
+ - `--only <name>`: run a single case/flow by exact name.
471
+ - `--bail`: stop at first failure.
472
+ - `--json`: emit machine‑readable results to stdout.
473
+ - `--report junit:path.xml`: write JUnit XML to path.
474
+ - `--summary md:path.md`: write a Markdown summary artifact.
475
+ - `--progress compact|detailed`: toggle rendering density.
476
+ - `--max-parallel N`: reuse existing parallelism flag (no test‑specific variant).
477
+
478
+ ## Coverage & Reporting
479
+
480
+ - Step coverage per case (executed vs expected), with a short table.
481
+ - JUnit and JSON reporters for CI visualization.
482
+ - Optional Markdown summary: failing cases, first mismatch, rerun hints.
483
+
484
+ ## Implementation Plan (Milestones)
485
+
486
+ This plan delivers the test framework incrementally, minimizing risk and reusing Visor internals.
487
+
488
+ Progress Tracker
489
+ - Milestone 0 — DSL freeze and scaffolding — DONE (2025-10-27)
490
+ - Milestone 1 — MVP runner and single‑event cases — DONE (2025-10-27)
491
+ - Milestone 2 — Built‑in fixtures — DONE (2025-10-27)
492
+ - Milestone 3 — Prompt capture and assertions — DONE (2025-10-27)
493
+ - Milestone 4 — Multi‑call history and selectors — DONE (2025-10-27)
494
+ - Milestone 5 — Flows and state persistence — DONE (2025-10-27)
495
+ - Milestone 6 — HTTP/Command mocks + negative modes — DONE (2025-10-27)
496
+ - Milestone 7 — CLI reporters/UX polish — DONE (2025-10-27)
497
+ - Milestone 8 — Validation and helpful errors — DONE (2025-10-27)
498
+ - Milestone 9 — Coverage and perf — DONE (2025-10-27)
499
+ - Milestone 10 — Docs, examples, migration — PENDING
500
+
501
+ Progress Update — 2025-10-29
502
+ - FlowStage refactor: each stage now recomputes prompts/output‑history deltas and execution statistics after any fallback run that executes “missing” expected steps. Coverage tables reflect the final state of the stage.
503
+ - Test‑mode isolation: stages set `VISOR_TEST_MODE=true` to disable incidental tag filtering paths that are desirable for production runs but surprising in tests.
504
+ - Recorder warnings: the runner warns when an AI/command step executes without a mock; tests remain stub‑free for GitHub ops via the Recording Octokit.
505
+ - Engine polish: removed duplicate manual stats increments for `on_success` and added an early return in `handleOnFinishHooks` when no forEach parents produced results (removes a short pause without changing behavior).
506
+ - Runner/CLI UX: single, clean end‑of‑run Summary; removed default artifact writes; exit‑tracer instrumentation removed; CLI warns on unknown flags; JSON/JUnit/Markdown only when flags passed.
507
+
508
+ Progress Update — 2025-10-28
509
+ - Runner: stage execution coverage now derives only from prompts/output-history deltas plus engine statistics (no selection heuristics). Single-check runs contribute to stats and history uniformly.
510
+ - Engine: single-check path records iteration stats and appends outputs to history; on_finish children run via the unified scheduler so runs are counted.
511
+ - UX: noisy debug prints gated behind VISOR_DEBUG; stage headers and coverage tables remain.
512
+ - Status: all default flow stages pass under strict mode (including facts-invalid, facts-two-items, and pr-updated). The GitHub recorder persists across stages and updates existing review comments when present.
513
+
514
+ Milestone 0 — DSL freeze and scaffolding (0.5 week) — DONE 2025-10-27
515
+ - Finalize DSL keys: tests.defaults, fixtures, cases, flow, fixture, mocks, expect.{calls,prompts,outputs,fail,strict_violation}. ✅
516
+ - Rename use_fixture → fixture across examples (done in this RFC and defaults/.visor.tests.yaml). ✅
517
+ - Create module skeletons: ✅
518
+ - src/test-runner/index.ts (entry + orchestration)
519
+ - src/test-runner/fixture-loader.ts (builtin + overrides)
520
+ - src/test-runner/recorders/github-recorder.ts (now dynamic Proxy-based)
521
+ - src/test-runner/assertions.ts (calls/prompts/outputs types + count validator)
522
+ - src/test-runner/utils/selectors.ts (deepGet)
523
+ - CLI: add visor test (discovery). ✅
524
+ - Success criteria: builds pass; “hello world” run prints discovered cases. ✅ (verified via npm run build and visor test)
525
+
526
+ Progress Notes
527
+ - Discovery works against any .visor.tests.yaml (general-purpose, not tied to defaults).
528
+ - Recording Octokit records arbitrary rest ops without hardcoding method lists.
529
+ - defaults/.visor.tests.yaml updated to consistent count grammar and fixed indentation issues.
530
+
531
+ Milestone 1 — MVP runner and single‑event cases (1 week) — DONE 2025-10-27 (non‑flow)
532
+ - CLI: add visor test [--config path] [--only name] [--bail] [--list]. ✅
533
+ - Parsing: load tests file (extends) and hydrate cases. ✅
534
+ - Execution: per case (non‑flow), synthesize PRInfo and call CheckExecutionEngine once. ✅
535
+ - GitHub recorder default: injected recording Octokit; no network. ✅
536
+ - Assertions: expect.calls for steps and provider ops (exactly|at_least|at_most); strict mode enforced. ✅
537
+ - Output: basic per‑case status + summary. ✅
538
+ - Success criteria: label-flow, issue-triage, strict-mode-example, security-fail-if pass locally. ✅
539
+
540
+ Notes
541
+ - Flow cases are deferred to Milestone 5 (state persistence) and will be added later.
542
+ - AI provider forced to mock in test mode unless overridden by suite defaults.
543
+
544
+ Verification
545
+ - Build CLI + SDK: npm run build — success.
546
+ - Discovery: visor test --config defaults/.visor.tests.yaml --list — lists suite and cases.
547
+ - Run single cases:
548
+ - visor test --config defaults/.visor.tests.yaml --only label-flow — PASS
549
+ - visor test --config defaults/.visor.tests.yaml --only issue-triage — PASS
550
+ - visor test --config defaults/.visor.tests.yaml --only security-fail-if — PASS
551
+ - visor test --config defaults/.visor.tests.yaml --only strict-mode-example — PASS
552
+ - Behavior observed:
553
+ - Strict mode enforced (steps executed but not asserted would fail).
554
+ - GitHub ops recorded by default with dynamic recorder, no network calls.
555
+ - Provider and step call counts respected (exactly | at_least | at_most).
556
+
557
+ Milestone 2 — Built‑in fixtures (0.5–1 week) — DONE 2025-10-27
558
+ - Implement gh.* builtins: pr_open.minimal, pr_sync.minimal, issue_open.minimal, issue_comment.standard, issue_comment.visor_help, issue_comment.visor_regenerate.
559
+ - Support fixture overrides (fixture: { builtin, overrides }).
560
+ - Wire files+diff into the engine’s analyzers.
561
+ - Success criteria: pr-review-e2e-flow “pr-open”, “standard-comment”, “visor-plain”, “visor-retrigger” run with built-ins.
562
+ Notes:
563
+ - gh.* builtins implemented with webhook payloads and minimal diffs for PR fixtures.
564
+ - Runner accepts fixture: { builtin, overrides } and applies overrides to pr.* and webhook.* paths.
565
+ - Diffs surfaced via PRInfo.fullDiff; prompts include diff header automatically.
566
+ - Flow execution will be delivered in Milestone 5; the same built-ins power the standalone prompt cases added now.
567
+
568
+ Milestone 3 — Prompt capture and prompt assertions (0.5 week) — DONE 2025-10-27
569
+ - Capture final AI prompt string per step after Liquid/context assembly. ✅ (AICheckProvider hook)
570
+ - Assertions: expect.prompts contains | not_contains | matches (regex). ✅
571
+ - Add `prompts.where` selector to target a prompt from history by content. ✅
572
+ - Success criteria: prompt checks pass for label-flow, issue-triage, visor-plain, visor-retrigger. ✅
573
+ - Notes: added standalone cases visor-plain-prompt and visor-retrigger-prompt for prompt-only validation.
574
+
575
+ Milestone 4 — Multi‑call history and selectors (1 week) — DONE 2025-10-27
576
+ - Per-step invocation history recorded and exposed by engine (outputs.history). ✅
577
+ - index selector for prompts and outputs (first|last|N). ✅
578
+ - where selector for outputs: { path, equals|matches }. ✅
579
+ - equalsDeep for outputs. ✅
580
+ - contains_unordered for array outputs. ✅
581
+ - Regex matches for outputs. ✅
582
+
583
+ Milestone 5 — Flows and state persistence (0.5–1 week) — DONE 2025-10-27
584
+ - Implemented flow execution with shared engine + recorder across stages. ✅
585
+ - Preserves MemoryStore state, outputs.history and provider calls between stages. ✅
586
+ - Stage-local deltas for assertions (prompts, outputs, calls). ✅
587
+ - Success criteria: full pr-review-e2e-flow passes. ✅
588
+
589
+ Milestone 6 — HTTP/Command mocks and advanced GitHub modes (1 week) — DONE 2025-10-27
590
+ - Command mocks: runner injects mocks via ExecutionContext; provider short-circuits to return stdout/exit_code. ✅
591
+ - HTTP client mocks: provider returns mocked response via ExecutionContext without network. ✅
592
+ - GitHub recorder negative modes: error(code) and timeout(ms) supported via tests.defaults.github_recorder. ✅
593
+ - Success criteria: command-mock-shape passes; negative modes available for future tests. ✅
594
+
595
+ Milestone 7 — CLI UX polish and reporters (0.5–1 week) — DONE 2025-10-27
596
+ - Flags: --json <path|->, --report junit:<path>, --summary md:<path>, --progress compact|detailed. ✅
597
+ - Compact progress with per-case PASS/FAIL lines; summary at end. ✅
598
+ - JSON/JUnit/Markdown reporters now include per-case details (name, pass/fail, errors). ✅
599
+
600
+ Milestone 8 — Validation and helpful errors (0.5 week) — DONE 2025-10-27
601
+ - Reuse ConfigManager + Ajv for base config. ✅
602
+ - Lightweight runtime validation for tests DSL with precise YAML paths and hints. ✅
603
+ - Add `visor test --validate` to check the tests file only (reuses runtime validation). ✅
604
+ - Success criteria: common typos produce actionable errors (path + suggestion). ✅
605
+
606
+ Usage:
607
+
608
+ ```
609
+ visor test --validate --config defaults/.visor.tests.yaml
610
+ ```
611
+
612
+ Example error output:
613
+
614
+ ```
615
+ ❌ Tests file has 2 error(s):
616
+ • tests.cases[0].expext: must NOT have additional properties (Did you mean "expect"?)
617
+ • tests.cases[3].event: must be equal to one of the allowed values (allowed: manual, pr_opened, pr_updated, pr_closed, issue_opened, issue_comment)
618
+ ```
619
+
620
+ Milestone 9 — Coverage and perf (0.5 week) — DONE 2025-10-27
621
+ - Per-case coverage table printed after assertions: each expected step shows desired count (e.g., =1/≥1/≤N), actual runs, and status (ok/under/over). ✅
622
+ - Parallel case execution: `--max-parallel <N>` or `tests.defaults.max_parallel` enables a simple pool runner. ✅
623
+ - Prompt capture throttle: `--prompt-max-chars <N>` or `tests.defaults.prompt_max_chars` truncates stored prompt text to reduce memory. ✅
624
+ - Success criteria: coverage table visible; options validated locally. ✅
625
+
626
+ Usage examples:
627
+
628
+ ```
629
+ visor test --config defaults/.visor.tests.yaml --max-parallel 4
630
+ visor test --config defaults/.visor.tests.yaml --prompt-max-chars 16000
631
+ ```
632
+
633
+ Milestone 10 — Docs, examples, and migration (0.5 week) — IN PROGRESS 2025-10-31
634
+ - Update README to link the RFC and defaults/.visor.tests.yaml.
635
+ - Document built-in fixtures catalog and examples.
636
+ - Migration note: how to move from embedded tests and from `returns` to new mocks.
637
+ - Document `depends_on` ANY‑OF (pipe) groups with examples (done).
638
+ - Add initial unit tests for OR‑groups and session‑reuse semantics (landed as skipped; will enable when executionStatistics exposes all requested checks).
639
+ - Success criteria: docs reviewed; examples copy‑paste clean.
640
+
641
+ Risks & Mitigations
642
+ - Prompt capture bloat → truncate by default; add --verbose.
643
+ - Fixture drift vs engine → keep fixtures minimal and aligned to CheckExecutionEngine needs; add contract tests.
644
+ - Strict mode false positives → provide clear errors and fast “add expect” guidance.
645
+
646
+ Success Metrics
647
+ - 100% of default cases pass locally and in CI.
648
+ - Sub‑second overhead per case on small fixtures; <10s for the full default suite.
649
+ - Clear failures with a single screen of output; <1 minute to fix typical assertion mismatches.
650
+
651
+ ## Compatibility & Migration
652
+
653
+ - Tests moved from `defaults/.visor.yaml` into `defaults/.visor.tests.yaml` with `extends: ".visor.yaml"`.
654
+ - Old `mocks.*.returns` is replaced by direct values (object/array/string).
655
+ - You no longer need `run: steps` in tests; cases are integration‑driven by `event + fixture`.
656
+ - `no_other_calls` is unnecessary with strict mode; it’s implied and enforced.
657
+
658
+ ## Open Questions
659
+
660
+ - Should we support HTTP provider mocks out of the box (URL/method/body → recorded responses)?
661
+ - Do we want a JSONPath for `expect.outputs.path`, or keep the current dot/bracket selector?
662
+ - Snapshots of generated Markdown? Perhaps as optional golden files with normalization.
663
+
664
+ ## Future Work
665
+
666
+ - Watch mode (`--watch`) and focused runs by regex.
667
+ - Coverage‑like reports for step execution and assertions.
668
+ - Built‑in fixtures for common GitHub events (shortcuts).
669
+ - Golden snapshot helpers for comments and label sets (with stable normalization).
670
+ - Parallelizing cases and/or flows.
671
+
672
+ ## Appendix: Example Suite
673
+
674
+ See `defaults/.visor.tests.yaml` in the repo for a complete, multi‑event example covering:
675
+ - PR opened → overview + labels
676
+ - Standard PR comment → no action
677
+ - `/visor` comment → reply
678
+ - `/visor ... Regenerate reviews` → retrigger overview
679
+ - Fact validation enabled/disabled on comment
680
+ - New commit pushed to PR → refresh overview