@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,372 @@
1
+ # Human Input Provider
2
+
3
+ The human-input provider pauses workflow execution to request input from a human user. This enables interactive workflows, approval gates, and dynamic parameter collection.
4
+
5
+ ## Table of Contents
6
+ - [Overview](#overview)
7
+ - [Configuration](#configuration)
8
+ - [Input Methods](#input-methods)
9
+ - [Examples](#examples)
10
+ - [SDK Usage](#sdk-usage)
11
+ - [Security](#security)
12
+
13
+ ## Overview
14
+
15
+ The human-input provider supports four input methods, prioritized as follows:
16
+
17
+ 1. **CLI with `--message` argument** - Inline text or file path
18
+ 2. **Piped stdin** - Input from pipe or file redirect
19
+ 3. **SDK hook** - Custom `onHumanInput` callback
20
+ 4. **Interactive prompt** - Beautiful terminal UI (when TTY available)
21
+
22
+ ## Configuration
23
+
24
+ ### Basic Configuration
25
+
26
+ ```yaml
27
+ checks:
28
+ approval:
29
+ type: human-input
30
+ prompt: "Do you approve this deployment? (yes/no)"
31
+ ```
32
+
33
+ ### Full Configuration Options
34
+
35
+ ```yaml
36
+ checks:
37
+ approval:
38
+ type: human-input
39
+ prompt: "Enter approval decision" # Required: prompt text
40
+ placeholder: "Type yes or no..." # Optional: placeholder text
41
+ allow_empty: false # Optional: allow empty input (default: false)
42
+ multiline: false # Optional: enable multiline input (default: false)
43
+ timeout: 300 # Optional: timeout in seconds
44
+ default: "no" # Optional: default value
45
+ ```
46
+
47
+ ### Using Input in Dependent Checks
48
+
49
+ The user's input is available to dependent checks via the `outputs` variable. By default (no schema), human-input returns an object `{ text: string, ts: number }` where `ts` is the timestamp (milliseconds since epoch):
50
+
51
+ ```yaml
52
+ checks:
53
+ get-version:
54
+ type: human-input
55
+ prompt: "Enter version number"
56
+
57
+ tag-release:
58
+ type: command
59
+ depends_on: [get-version]
60
+ exec: |
61
+ # Prefer .text to read the string payload
62
+ git tag v{{ outputs['get-version'].text | default: outputs['get-version'] }}
63
+ git push origin v{{ outputs['get-version'].text | default: outputs['get-version'] }}
64
+
65
+ > See also: [Default Output Schema](./default-output-schema.md)
66
+ ```
67
+
68
+ ## Input Methods
69
+
70
+ ### 1. CLI with --message
71
+
72
+ Provide input directly via command line:
73
+
74
+ ```bash
75
+ # Inline message
76
+ visor --check approval --message "yes"
77
+
78
+ # From file
79
+ visor --check approval --message ./approval.txt
80
+ ```
81
+
82
+ ### 2. Piped stdin
83
+
84
+ Pipe input from another command or file:
85
+
86
+ ```bash
87
+ # From echo
88
+ echo "yes" | visor --check approval
89
+
90
+ # From file
91
+ visor --check approval < approval.txt
92
+
93
+ # From command
94
+ curl https://api.example.com/approval | visor --check approval
95
+ ```
96
+
97
+ ### 3. SDK Hook
98
+
99
+ Use a custom hook for programmatic input:
100
+
101
+ ```typescript
102
+ import { runChecks, HumanInputCheckProvider } from '@probelabs/visor';
103
+
104
+ // Option 1: Using deprecated static method (backward compatible)
105
+ HumanInputCheckProvider.setHooks({
106
+ onHumanInput: async (request) => {
107
+ console.log(`Prompt: ${request.prompt}`);
108
+ return 'yes';
109
+ }
110
+ });
111
+
112
+ await runChecks({ config });
113
+
114
+ // Option 2: Using new ExecutionContext (recommended)
115
+ await runChecks({
116
+ config,
117
+ executionContext: {
118
+ hooks: {
119
+ onHumanInput: async (request) => {
120
+ console.log(`Prompt: ${request.prompt}`);
121
+ return 'yes';
122
+ }
123
+ }
124
+ }
125
+ });
126
+ ```
127
+
128
+ The `HumanInputRequest` interface:
129
+
130
+ ```typescript
131
+ interface HumanInputRequest {
132
+ checkId: string; // Check name/ID
133
+ prompt: string; // Prompt text
134
+ placeholder?: string; // Placeholder text
135
+ allowEmpty?: boolean; // Allow empty input
136
+ multiline?: boolean; // Multiline mode
137
+ timeout?: number; // Timeout in milliseconds
138
+ default?: string; // Default value
139
+ }
140
+ ```
141
+
142
+ ### 4. Interactive Terminal Prompt
143
+
144
+ When running in a TTY (interactive terminal), a beautiful prompt appears:
145
+
146
+ ```
147
+ ┌─────────────────────────────────────────────┐
148
+ │ Enter approval decision │
149
+ ├─────────────────────────────────────────────┤
150
+ │ Type yes or no... │
151
+ │ │
152
+ │ Press Ctrl+D when done (or Ctrl+C to exit) │
153
+ └─────────────────────────────────────────────┘
154
+ ```
155
+
156
+ ## Examples
157
+
158
+ ### Simple Approval Gate
159
+
160
+ ```yaml
161
+ checks:
162
+ manual-approval:
163
+ type: human-input
164
+ prompt: "Approve deployment to production? (yes/no)"
165
+ allow_empty: false
166
+
167
+ deploy:
168
+ type: command
169
+ depends_on: [manual-approval]
170
+ fail_if: |
171
+ outputs['manual-approval'].toLowerCase() !== 'yes'
172
+ exec: ./deploy.sh production
173
+ ```
174
+
175
+ ### Version Input
176
+
177
+ ```yaml
178
+ checks:
179
+ get-version:
180
+ type: human-input
181
+ prompt: "Enter version number (e.g., 1.2.3)"
182
+
183
+ validate-version:
184
+ type: javascript
185
+ depends_on: [get-version]
186
+ exec: |
187
+ const version = outputs['get-version'];
188
+ const valid = /^\d+\.\d+\.\d+$/.test(version);
189
+ if (!valid) throw new Error('Invalid version format');
190
+ ```
191
+
192
+ ### Multi-step Input
193
+
194
+ ```yaml
195
+ checks:
196
+ get-feature:
197
+ type: human-input
198
+ prompt: "Enter feature name"
199
+
200
+ get-description:
201
+ type: human-input
202
+ prompt: "Enter feature description"
203
+ multiline: true
204
+ depends_on: [get-feature]
205
+
206
+ create-issue:
207
+ type: command
208
+ depends_on: [get-feature, get-description]
209
+ exec: |
210
+ gh issue create \
211
+ --title "{{ outputs['get-feature'] }}" \
212
+ --body "{{ outputs['get-description'] }}"
213
+ ```
214
+
215
+ ### Calculator Example
216
+
217
+ See [examples/calculator-sdk-real.ts](../examples/calculator-sdk-real.ts) for a complete working example with:
218
+ - Multiple human-input checks in sequence
219
+ - Output passing between checks
220
+ - JavaScript execution with user input
221
+ - Memory storage
222
+
223
+ ## SDK Usage
224
+
225
+ ### Basic SDK Usage
226
+
227
+ ```typescript
228
+ import { runChecks } from '@probelabs/visor';
229
+
230
+ const config = {
231
+ version: '1.0',
232
+ checks: {
233
+ approval: {
234
+ type: 'human-input',
235
+ prompt: 'Approve? (yes/no)'
236
+ }
237
+ }
238
+ };
239
+
240
+ // Run with execution context (recommended)
241
+ const result = await runChecks({
242
+ config,
243
+ executionContext: {
244
+ hooks: {
245
+ onHumanInput: async (request) => {
246
+ // Your custom input logic
247
+ return await getUserInput(request.prompt);
248
+ }
249
+ }
250
+ }
251
+ });
252
+ ```
253
+
254
+ ### With CLI Message
255
+
256
+ ```typescript
257
+ import { CheckExecutionEngine } from '@probelabs/visor';
258
+
259
+ const engine = new CheckExecutionEngine();
260
+
261
+ // Set execution context
262
+ engine.setExecutionContext({
263
+ cliMessage: 'yes' // Simulates --message flag
264
+ });
265
+
266
+ const result = await engine.executeChecks({
267
+ checks: ['approval'],
268
+ config
269
+ });
270
+ ```
271
+
272
+ ### Automated Testing
273
+
274
+ ```typescript
275
+ const testInputs = {
276
+ 'get-number1': '42',
277
+ 'get-number2': '7',
278
+ 'get-operation': '+'
279
+ };
280
+
281
+ await runChecks({
282
+ config,
283
+ executionContext: {
284
+ hooks: {
285
+ onHumanInput: async (request) => {
286
+ return testInputs[request.checkId] || '';
287
+ }
288
+ }
289
+ }
290
+ });
291
+ ```
292
+
293
+ ## Security
294
+
295
+ The human-input provider includes several security features:
296
+
297
+ ### Input Sanitization
298
+
299
+ All user input is automatically sanitized before being passed to dependent checks:
300
+
301
+ - **Null bytes removed** - Prevents C-string injection
302
+ - **Control characters removed** - Except newlines and tabs
303
+ - **Size limit** - Maximum 100KB per input
304
+
305
+ ### Path Traversal Protection
306
+
307
+ When using `--message` with file paths:
308
+
309
+ - **Path normalization** - Resolves `..` components
310
+ - **Directory restriction** - Only reads files within current working directory
311
+ - **File type validation** - Only reads regular files
312
+ - **Async operations** - Non-blocking file I/O
313
+
314
+ ### DoS Prevention
315
+
316
+ Stdin input has protection against denial-of-service:
317
+
318
+ - **Size limit** - Default 1MB maximum
319
+ - **Timeout support** - Configurable timeout
320
+ - **Resource cleanup** - Proper cleanup with `stdin.pause()`
321
+
322
+ ### Execution Context Isolation
323
+
324
+ The new ExecutionContext pattern eliminates global state:
325
+
326
+ - **Thread-safe** - No global mutable state
327
+ - **Test isolation** - Each execution has isolated context
328
+ - **Concurrent safe** - Safe for parallel execution
329
+
330
+ ## Migration Guide
331
+
332
+ ### From Static API to ExecutionContext
333
+
334
+ **Old way (still works but deprecated):**
335
+
336
+ ```typescript
337
+ import { HumanInputCheckProvider, runChecks } from '@probelabs/visor';
338
+
339
+ HumanInputCheckProvider.setHooks({
340
+ onHumanInput: async (request) => 'yes'
341
+ });
342
+
343
+ await runChecks({ config });
344
+ ```
345
+
346
+ **New way (recommended):**
347
+
348
+ ```typescript
349
+ import { runChecks } from '@probelabs/visor';
350
+
351
+ await runChecks({
352
+ config,
353
+ executionContext: {
354
+ hooks: {
355
+ onHumanInput: async (request) => 'yes'
356
+ }
357
+ }
358
+ });
359
+ ```
360
+
361
+ Benefits of the new approach:
362
+ - Thread-safe (no global state)
363
+ - Better for concurrent executions
364
+ - Easier to test
365
+ - More flexible
366
+
367
+ ## See Also
368
+
369
+ - [Calculator SDK Example](../examples/calculator-sdk-real.ts) - Complete working example
370
+ - [Debugging Guide](./debugging.md) - Debugging techniques
371
+ - [Command Provider](./command-provider.md) - Executing shell commands
372
+ - [MCP Provider](./mcp-provider.md) - MCP integration
@@ -0,0 +1,253 @@
1
+ # Lifecycle Hooks
2
+
3
+ Lifecycle hooks allow you to execute preprocessing or setup tasks automatically before a step runs. This is particularly useful for enriching context, fetching external data, or preparing the environment.
4
+
5
+ ## `on_init` Hook
6
+
7
+ The `on_init` hook runs **before** a step executes, allowing you to:
8
+ - Fetch external data (JIRA issues, metrics, configuration)
9
+ - Enrich AI prompts with additional context
10
+ - Execute setup tasks or validation
11
+ - Invoke custom tools, steps, or workflows
12
+
13
+ ### Basic Usage
14
+
15
+ ```yaml
16
+ steps:
17
+ my-check:
18
+ type: ai
19
+ on_init:
20
+ run:
21
+ - tool: fetch-jira-issue
22
+ with:
23
+ issue_key: "PROJ-123"
24
+ as: jira-data
25
+ prompt: |
26
+ Review this PR considering JIRA issue: {{ outputs['jira-data'] | json }}
27
+ ```
28
+
29
+ ### Features
30
+
31
+ #### 1. Multiple Invocations
32
+
33
+ Execute multiple tools, steps, or workflows in sequence:
34
+
35
+ ```yaml
36
+ on_init:
37
+ run:
38
+ - tool: fetch-user-data
39
+ as: users
40
+ - tool: fetch-config
41
+ as: config
42
+ - workflow: validate-environment
43
+ as: validation
44
+ ```
45
+
46
+ #### 2. Custom Arguments
47
+
48
+ Pass arguments to tools and workflows using `with`:
49
+
50
+ ```yaml
51
+ on_init:
52
+ run:
53
+ - tool: fetch-external-data
54
+ with:
55
+ source: metrics-api
56
+ format: json
57
+ as: metrics
58
+ ```
59
+
60
+ #### 3. Custom Output Names
61
+
62
+ Store outputs with custom names using `as`:
63
+
64
+ ```yaml
65
+ on_init:
66
+ run:
67
+ - tool: fetch-jira-issue
68
+ with:
69
+ issue_key: "PROJ-456"
70
+ as: jira-context # Access via {{ outputs['jira-context'] }}
71
+ ```
72
+
73
+ #### 4. Dynamic Preprocessing
74
+
75
+ Use `run_js` for conditional preprocessing based on PR context:
76
+
77
+ ```yaml
78
+ on_init:
79
+ run_js: |
80
+ const items = [];
81
+
82
+ // Fetch JIRA only if PR title contains issue key
83
+ const jiraMatch = pr.title.match(/PROJ-\d+/);
84
+ if (jiraMatch) {
85
+ items.push({
86
+ tool: 'fetch-jira-issue',
87
+ with: { issue_key: jiraMatch[0] },
88
+ as: 'jira-data'
89
+ });
90
+ }
91
+
92
+ // Fetch metrics if backend files changed
93
+ if (files.some(f => f.filename.includes('backend/'))) {
94
+ items.push({
95
+ tool: 'fetch-metrics',
96
+ as: 'backend-metrics'
97
+ });
98
+ }
99
+
100
+ return items;
101
+ ```
102
+
103
+ ### Invocation Types
104
+
105
+ #### Tool Invocation
106
+
107
+ Execute a custom MCP tool:
108
+
109
+ ```yaml
110
+ on_init:
111
+ run:
112
+ - tool: my-custom-tool
113
+ with:
114
+ param1: value1
115
+ as: tool-output
116
+ ```
117
+
118
+ #### Step Invocation
119
+
120
+ Execute another step:
121
+
122
+ ```yaml
123
+ on_init:
124
+ run:
125
+ - step: preprocessing-step
126
+ with:
127
+ input: "{{ pr.title }}"
128
+ as: preprocessed
129
+ ```
130
+
131
+ #### Workflow Invocation
132
+
133
+ Execute a workflow:
134
+
135
+ ```yaml
136
+ on_init:
137
+ run:
138
+ - workflow: data-enrichment
139
+ with:
140
+ source: production
141
+ as: enriched-data
142
+ ```
143
+
144
+ ### Accessing Outputs
145
+
146
+ Outputs from `on_init` items are available in the step's execution context:
147
+
148
+ ```yaml
149
+ steps:
150
+ my-check:
151
+ type: command
152
+ on_init:
153
+ run:
154
+ - tool: fetch-data
155
+ as: external-data
156
+ exec: |
157
+ echo "Fetched data: {{ outputs['external-data'] | json }}"
158
+ ```
159
+
160
+ ### Reusable Tools and Workflows
161
+
162
+ Define tools and workflows in separate files and import them:
163
+
164
+ **reusable-tools.yaml:**
165
+ ```yaml
166
+ version: "1.0"
167
+ tools:
168
+ fetch-jira-issue:
169
+ name: fetch-jira-issue
170
+ exec: |
171
+ # Fetch JIRA issue...
172
+ parseJson: true
173
+ steps: {}
174
+ ```
175
+
176
+ **Main configuration:**
177
+ ```yaml
178
+ version: "1.0"
179
+ extends:
180
+ - ./reusable-tools.yaml
181
+
182
+ steps:
183
+ ai-review:
184
+ type: ai
185
+ on_init:
186
+ run:
187
+ - tool: fetch-jira-issue
188
+ with:
189
+ issue_key: "{{ pr.title | regex_search: '[A-Z]+-[0-9]+' }}"
190
+ as: jira
191
+ prompt: "Review considering: {{ outputs.jira | json }}"
192
+ ```
193
+
194
+ ### Loop Protection
195
+
196
+ To prevent infinite loops and excessive preprocessing:
197
+
198
+ - **Maximum 50 items**: `on_init` can execute at most 50 items (configurable via `MAX_ON_INIT_ITEMS`)
199
+ - **No nested execution**: `on_init` hooks within `on_init` items are skipped
200
+ - **Separate from routing loops**: `on_init` loop protection is independent of `on_success`/`on_fail` routing
201
+
202
+ ### forEach Integration
203
+
204
+ **How on_init works with forEach**: When a check uses `forEach`, the `on_init` hook runs **once before the forEach loop starts**, not once per item:
205
+
206
+ ```yaml
207
+ steps:
208
+ analyze-files:
209
+ type: ai
210
+ forEach: file-list
211
+ on_init: # Runs ONCE before processing all files
212
+ run:
213
+ - tool: fetch-project-config
214
+ as: config
215
+ prompt: |
216
+ Analyze {{ item }} using config: {{ outputs.config }}
217
+ # outputs.config is available to ALL forEach iterations
218
+ ```
219
+
220
+ This design allows you to:
221
+ - Fetch shared data once that all iterations can use
222
+ - Avoid redundant preprocessing for each item
223
+ - Keep forEach loops efficient
224
+
225
+ If you need per-item preprocessing, add `on_init` to child steps that depend on the forEach check.
226
+
227
+ ### Examples
228
+
229
+ See the `examples/` directory for comprehensive examples:
230
+
231
+ - **examples/reusable-tools.yaml** - Reusable tool library with 3 custom tools (fetch-jira-issue, fetch-external-data, validate-data)
232
+ - **examples/reusable-workflows.yaml** - Reusable workflow library with 3 workflows (data-enrichment, issue-triage, multi-step-validation)
233
+ - **examples/on-init-import-demo.yaml** - Complete demonstration showing:
234
+ - Using multiple imported tools in on_init
235
+ - Invoking imported workflows
236
+ - Chaining tools and workflows together
237
+ - Reusing the same tool multiple times with different parameters
238
+ - Includes 4 passing test cases
239
+
240
+ ### Best Practices
241
+
242
+ 1. **Keep preprocessing lightweight**: `on_init` runs before every step execution
243
+ 2. **Use custom output names**: Make outputs easy to identify with descriptive `as` names
244
+ 3. **Leverage reusability**: Define common tools/workflows once and import them
245
+ 4. **Use `run_js` for conditionals**: Avoid fetching unnecessary data
246
+ 5. **Handle failures gracefully**: Consider what happens if preprocessing fails
247
+
248
+ ### See Also
249
+
250
+ - [Custom Tools](./custom-tools.md) - Define reusable MCP tools
251
+ - [Workflows](./workflows.md) - Create reusable workflows
252
+ - [Liquid Templates](./liquid-templates.md) - Template syntax for dynamic values
253
+ - [RFC: on_init Hook](./rfc/on_init-hook.md) - Design proposal and rationale
@@ -0,0 +1,64 @@
1
+ ## 🚦 Execution Limits (Run Caps)
2
+
3
+ This feature protects workflows from accidental infinite loops by capping how many times a step may execute in a single engine run. It complements (but is different from) routing loop budgets.
4
+
5
+ ### Why this exists
6
+
7
+ - Complex `on_fail`/`on_success` routing can create feedback loops when a remediation step immediately routes back to its source.
8
+ - The cap provides a hard stop with a clear error if a step keeps re-running without converging.
9
+
10
+ ### Configuration
11
+
12
+ Global (default is 50 if omitted):
13
+
14
+ ```yaml
15
+ version: "1.0"
16
+
17
+ limits:
18
+ max_runs_per_check: 50 # Applies to every step unless overridden
19
+ ```
20
+
21
+ Per-step override:
22
+
23
+ ```yaml
24
+ steps:
25
+ refine:
26
+ type: ai
27
+ max_runs: 10 # Hard cap for this step within one engine run
28
+ ```
29
+
30
+ Disable cap for a specific step (not recommended unless you know it converges quickly):
31
+
32
+ ```yaml
33
+ steps:
34
+ extract:
35
+ type: command
36
+ max_runs: 0 # or any negative value
37
+ ```
38
+
39
+ ### Behavior
40
+
41
+ - The engine counts executions per step. For `forEach` children, the counter is tracked per item scope (each item has its own budget).
42
+ - When the cap is exceeded, the step fails immediately with a single error issue:
43
+ - `ruleId`: `<step-id>/limits/max_runs_exceeded`
44
+ - `severity`: `error`
45
+ - `message` includes the scope and attempt number
46
+ - Dependents are gated as with any error unless the dependency declares `continue_on_failure: true`.
47
+
48
+ ### How this differs from `routing.max_loops`
49
+
50
+ - `routing.max_loops` caps routing transitions (e.g., goto/retry waves) per scope.
51
+ - `limits.max_runs_per_check` caps actual step executions per step (also per scope for `forEach`).
52
+ - Both guard rails can be used together: set a modest routing budget (e.g., 5–10) and leave the execution cap at the default (50) or tailor per step.
53
+
54
+ ### Recommendations
55
+
56
+ - Keep `routing.max_loops` small for fast feedback (5–10).
57
+ - Use per-step `max_runs` on chat-like loops or known retryers if you need tighter control.
58
+ - Prefer fixing the loop logic (conditions/routing) over raising the caps.
59
+
60
+ ### Troubleshooting
61
+
62
+ - If you hit `.../limits/max_runs_exceeded` immediately, check if a step is routed back without changing state.
63
+ - For `forEach` flows, confirm whether the error is tied to a specific item scope; fix that item’s remediation path.
64
+