@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.
- package/README.md +71 -2
- package/action.yml +1 -1
- package/defaults/code-refiner.yaml +114 -0
- package/defaults/{.visor.yaml → code-review.yaml} +35 -226
- package/defaults/override.yaml +52 -0
- package/defaults/task-refinement.yaml +624 -0
- package/defaults/visor.tests.yaml +685 -0
- package/defaults/visor.yaml +483 -0
- package/dist/action-cli-bridge.d.ts +11 -82
- package/dist/action-cli-bridge.d.ts.map +1 -1
- package/dist/ai-review-service.d.ts +28 -9
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/check-execution-engine.d.ts +19 -331
- package/dist/check-execution-engine.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/cron-scheduler.d.ts +3 -3
- package/dist/cron-scheduler.d.ts.map +1 -1
- package/dist/debug-visualizer/ws-server.d.ts +7 -1
- package/dist/debug-visualizer/ws-server.d.ts.map +1 -1
- package/dist/defaults/code-refiner.yaml +114 -0
- package/dist/defaults/{.visor.yaml → code-review.yaml} +35 -226
- package/dist/defaults/override.yaml +52 -0
- package/dist/defaults/task-refinement.yaml +624 -0
- package/dist/defaults/visor.tests.yaml +685 -0
- package/dist/defaults/visor.yaml +483 -0
- package/dist/docs/DEPLOYMENT.md +118 -0
- package/dist/docs/GITHUB_CHECKS.md +280 -0
- package/dist/docs/NPM_USAGE.md +208 -0
- package/dist/docs/action-reference.md +19 -0
- package/dist/docs/advanced-ai.md +237 -0
- package/dist/docs/ai-configuration.md +535 -0
- package/dist/docs/ai-custom-tools-usage.md +261 -0
- package/dist/docs/ai-custom-tools.md +392 -0
- package/dist/docs/author-permissions.md +610 -0
- package/dist/docs/bot-transports-rfc.md +23 -0
- package/dist/docs/ci-cli-mode.md +34 -0
- package/dist/docs/claude-code.md +74 -0
- package/dist/docs/command-provider.md +559 -0
- package/dist/docs/commands.md +8 -0
- package/dist/docs/configuration.md +324 -0
- package/dist/docs/custom-tools.md +424 -0
- package/dist/docs/dashboards/README.md +23 -0
- package/dist/docs/dashboards/grafana-visor-diagrams.json +20 -0
- package/dist/docs/dashboards/grafana-visor-overview.json +33 -0
- package/dist/docs/debug-visualizer-progress.md +572 -0
- package/dist/docs/debug-visualizer-rfc.md +691 -0
- package/dist/docs/debug-visualizer.md +114 -0
- package/dist/docs/debugging.md +636 -0
- package/dist/docs/default-output-schema.md +28 -0
- package/dist/docs/dependencies.md +369 -0
- package/dist/docs/dev-playbook.md +9 -0
- package/dist/docs/engine-pause-resume-rfc.md +192 -0
- package/dist/docs/engine-state-machine-plan.md +333 -0
- package/dist/docs/event-driven-github-integration-rfc.md +743 -0
- package/dist/docs/event-triggers.md +292 -0
- package/dist/docs/execution-statistics-rfc.md +290 -0
- package/dist/docs/fact-validator-gap-analysis.md +178 -0
- package/dist/docs/fact-validator-implementation-plan.md +1235 -0
- package/dist/docs/fail-if.md +95 -0
- package/dist/docs/failure-conditions-implementation.md +271 -0
- package/dist/docs/failure-conditions-schema.md +173 -0
- package/dist/docs/failure-routing-rfc.md +193 -0
- package/dist/docs/failure-routing.md +507 -0
- package/dist/docs/foreach-dependency-propagation.md +473 -0
- package/dist/docs/github-ops.md +89 -0
- package/dist/docs/goto-forward-run-plan.md +113 -0
- package/dist/docs/guides/criticality-modes.md +332 -0
- package/dist/docs/guides/fault-management-and-contracts.md +738 -0
- package/dist/docs/guides/workflow-style-guide.md +224 -0
- package/dist/docs/http.md +299 -0
- package/dist/docs/human-input-provider.md +372 -0
- package/dist/docs/lifecycle-hooks.md +253 -0
- package/dist/docs/limits.md +64 -0
- package/dist/docs/liquid-templates.md +490 -0
- package/dist/docs/loop-routing-refactor.md +89 -0
- package/dist/docs/mcp-provider.md +557 -0
- package/dist/docs/mcp.md +124 -0
- package/dist/docs/memory.md +903 -0
- package/dist/docs/observability.md +12 -0
- package/dist/docs/output-formats.md +20 -0
- package/dist/docs/output-formatting.md +29 -0
- package/dist/docs/output-history.md +383 -0
- package/dist/docs/performance.md +6 -0
- package/dist/docs/pluggable.md +124 -0
- package/dist/docs/proposals/snapshot-scope-execution.md +236 -0
- package/dist/docs/providers/git-checkout.md +589 -0
- package/dist/docs/recipes.md +474 -0
- package/dist/docs/rfc/git-checkout-step.md +601 -0
- package/dist/docs/rfc/on_init-hook.md +1294 -0
- package/dist/docs/rfc/workspace-isolation.md +216 -0
- package/dist/docs/roadmap/criticality-implementation-tasks.md +92 -0
- package/dist/docs/router-patterns.md +339 -0
- package/dist/docs/schema-next-pr.md +10 -0
- package/dist/docs/schema-templates.md +68 -0
- package/dist/docs/script.md +34 -0
- package/dist/docs/sdk.md +222 -0
- package/dist/docs/security.md +7 -0
- package/dist/docs/suppressions.md +89 -0
- package/dist/docs/tag-filtering.md +258 -0
- package/dist/docs/telemetry-setup.md +119 -0
- package/dist/docs/telemetry-tracing-rfc.md +275 -0
- package/dist/docs/test-framework-rfc.md +680 -0
- package/dist/docs/testing/assertions.md +85 -0
- package/dist/docs/testing/ci.md +44 -0
- package/dist/docs/testing/cli.md +41 -0
- package/dist/docs/testing/cookbook.md +172 -0
- package/dist/docs/testing/dsl-reference.md +199 -0
- package/dist/docs/testing/fixtures-and-mocks.md +91 -0
- package/dist/docs/testing/flows.md +92 -0
- package/dist/docs/testing/getting-started.md +93 -0
- package/dist/docs/testing/troubleshooting.md +55 -0
- package/dist/docs/timeouts.md +50 -0
- package/dist/docs/troubleshooting.md +7 -0
- package/dist/docs/visor-sdk-rfc.md +186 -0
- package/dist/docs/workflows.md +569 -0
- package/dist/engine/on-finish/orchestrator.d.ts +19 -0
- package/dist/engine/on-finish/orchestrator.d.ts.map +1 -0
- package/dist/engine/on-finish/utils.d.ts +44 -0
- package/dist/engine/on-finish/utils.d.ts.map +1 -0
- package/dist/event-bus/event-bus.d.ts +13 -0
- package/dist/event-bus/event-bus.d.ts.map +1 -0
- package/dist/event-bus/types.d.ts +71 -0
- package/dist/event-bus/types.d.ts.map +1 -0
- package/dist/examples/.claude/agents/code-reviewer.md +69 -0
- package/dist/examples/.mcp.json +34 -0
- package/dist/examples/CALCULATOR-SDK.md +364 -0
- package/dist/examples/README.md +384 -0
- package/dist/examples/ai-custom-tools-example.yaml +206 -0
- package/dist/examples/ai-custom-tools-simple.yaml +76 -0
- package/dist/examples/ai-retry-fallback-config.yaml +180 -0
- package/dist/examples/ai-with-bash.yaml +126 -0
- package/dist/examples/ai-with-mcp.yaml +82 -0
- package/dist/examples/basic-human-input.yaml +15 -0
- package/dist/examples/bedrock-config.yaml +77 -0
- package/dist/examples/calculator-config.yaml +133 -0
- package/dist/examples/calculator-json-output-guide.md +311 -0
- package/dist/examples/calculator-sdk-automated.ts +340 -0
- package/dist/examples/calculator-sdk-example.ts +275 -0
- package/dist/examples/calculator-sdk-json.ts +331 -0
- package/dist/examples/calculator-sdk-real.ts +374 -0
- package/dist/examples/calculator-sdk-test.ts +148 -0
- package/dist/examples/claude-code-config.yaml +191 -0
- package/dist/examples/cron-webhook-config.yaml +215 -0
- package/dist/examples/custom-template.liquid +57 -0
- package/dist/examples/custom-tools-example.yaml +281 -0
- package/dist/examples/enhanced-config.yaml +165 -0
- package/dist/examples/environments/visor.base.yaml +92 -0
- package/dist/examples/environments/visor.dev.yaml +33 -0
- package/dist/examples/environments/visor.prod.yaml +95 -0
- package/dist/examples/environments/visor.staging.yaml +46 -0
- package/dist/examples/fact-validator.yaml +361 -0
- package/dist/examples/fail-if-simple.yaml +90 -0
- package/dist/examples/failure-conditions-advanced.yaml +136 -0
- package/dist/examples/failure-conditions-basic.yaml +48 -0
- package/dist/examples/failure-conditions-github-style.yaml +119 -0
- package/dist/examples/failure-conditions-migration.yaml +74 -0
- package/dist/examples/for-loop-example.yaml +176 -0
- package/dist/examples/forEach-example.yaml +120 -0
- package/dist/examples/git-checkout-basic.yaml +32 -0
- package/dist/examples/git-checkout-compare.yaml +59 -0
- package/dist/examples/git-checkout-cross-repo.yaml +76 -0
- package/dist/examples/github-workflow-with-tags.yml +163 -0
- package/dist/examples/http-integration-config.yaml +240 -0
- package/dist/examples/https-server-config.yaml +209 -0
- package/dist/examples/human-input-example.yaml +63 -0
- package/dist/examples/if-conditions.yaml +173 -0
- package/dist/examples/jira-simple-example.yaml +56 -0
- package/dist/examples/jira-single-issue-workflow.yaml +166 -0
- package/dist/examples/jira-workflow-mcp.yaml +182 -0
- package/dist/examples/mcp/analyzer.py +119 -0
- package/dist/examples/mcp-provider-example.yaml +301 -0
- package/dist/examples/memory-counter.yaml +99 -0
- package/dist/examples/memory-error-collection.yaml +104 -0
- package/dist/examples/memory-exec-js.yaml +247 -0
- package/dist/examples/memory-namespace-isolation.yaml +184 -0
- package/dist/examples/memory-retry-counter.yaml +65 -0
- package/dist/examples/memory-state-machine.yaml +170 -0
- package/dist/examples/on-init-import-demo.yaml +179 -0
- package/dist/examples/outputs-raw-basic.yaml +26 -0
- package/dist/examples/project-with-tools.yaml +174 -0
- package/dist/examples/prompts/architecture-analysis.liquid +116 -0
- package/dist/examples/prompts/security-comprehensive.liquid +107 -0
- package/dist/examples/quick-start-tags.yaml +53 -0
- package/dist/examples/reusable-tools.yaml +92 -0
- package/dist/examples/reusable-workflows.yaml +88 -0
- package/dist/examples/routing-basic.yaml +35 -0
- package/dist/examples/routing-dynamic-js.yaml +46 -0
- package/dist/examples/routing-foreach.yaml +34 -0
- package/dist/examples/routing-goto-event.yaml +34 -0
- package/dist/examples/routing-on-success.yaml +25 -0
- package/dist/examples/run-calculator-demo.sh +71 -0
- package/dist/examples/sdk-basic.mjs +10 -0
- package/dist/examples/sdk-cjs.cjs +10 -0
- package/dist/examples/sdk-comprehensive.mjs +175 -0
- package/dist/examples/sdk-manual-config.mjs +65 -0
- package/dist/examples/sdk-typescript.js +81 -0
- package/dist/examples/sdk-typescript.ts +92 -0
- package/dist/examples/session-reuse-config.yaml +151 -0
- package/dist/examples/session-reuse-self.yaml +81 -0
- package/dist/examples/slack-simple-chat.yaml +775 -0
- package/dist/examples/templates/security-report.liquid +137 -0
- package/dist/examples/tools-library.yaml +281 -0
- package/dist/examples/transform-example.yaml +199 -0
- package/dist/examples/visor-with-tags.yaml +198 -0
- package/dist/examples/webhook-pipeline-config.yaml +218 -0
- package/dist/examples/workflows/calculator-workflow.yaml +163 -0
- package/dist/examples/workflows/code-quality.yaml +222 -0
- package/dist/examples/workflows/quick-pr-check.yaml +90 -0
- package/dist/examples/workflows/workflow-composition-example.yaml +130 -0
- package/dist/failure-condition-evaluator.d.ts +3 -0
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/frontends/github-frontend.d.ts +58 -0
- package/dist/frontends/github-frontend.d.ts.map +1 -0
- package/dist/frontends/host.d.ts +47 -0
- package/dist/frontends/host.d.ts.map +1 -0
- package/dist/frontends/ndjson-sink.d.ts +12 -0
- package/dist/frontends/ndjson-sink.d.ts.map +1 -0
- package/dist/frontends/slack-frontend.d.ts +58 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -0
- package/dist/generated/config-schema.d.ts +967 -57
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +1033 -56
- package/dist/github-check-service.d.ts +4 -6
- package/dist/github-check-service.d.ts.map +1 -1
- package/dist/github-comments.d.ts +2 -4
- package/dist/github-comments.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +134327 -99004
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/logger.d.ts +2 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/memory-store.d.ts +6 -0
- package/dist/memory-store.d.ts.map +1 -1
- package/dist/output/assistant-json/template.liquid +0 -0
- package/dist/output/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
- package/dist/output/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
- package/dist/output-formatters.d.ts +1 -1
- package/dist/output-formatters.d.ts.map +1 -1
- package/dist/providers/ai-check-provider.d.ts +12 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/check-provider-registry.d.ts +6 -0
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +43 -1
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/claude-code-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/custom-tool-executor.d.ts +61 -0
- package/dist/providers/custom-tool-executor.d.ts.map +1 -0
- package/dist/providers/git-checkout-provider.d.ts +25 -0
- package/dist/providers/git-checkout-provider.d.ts.map +1 -0
- package/dist/providers/github-ops-provider.d.ts.map +1 -1
- package/dist/providers/http-client-provider.d.ts +4 -4
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/human-input-check-provider.d.ts +5 -0
- package/dist/providers/human-input-check-provider.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts +2 -5
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +10 -4
- package/dist/providers/mcp-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts +66 -0
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -0
- package/dist/providers/memory-check-provider.d.ts +2 -8
- package/dist/providers/memory-check-provider.d.ts.map +1 -1
- package/dist/providers/script-check-provider.d.ts +25 -0
- package/dist/providers/script-check-provider.d.ts.map +1 -0
- package/dist/providers/workflow-check-provider.d.ts +56 -0
- package/dist/providers/workflow-check-provider.d.ts.map +1 -0
- package/dist/reviewer.d.ts +2 -1
- package/dist/reviewer.d.ts.map +1 -1
- package/dist/sdk/check-provider-registry-534KL5HT.mjs +27 -0
- package/dist/sdk/chunk-23L3QRYX.mjs +16872 -0
- package/dist/sdk/chunk-23L3QRYX.mjs.map +1 -0
- package/dist/sdk/{chunk-TUTOLSFV.mjs → chunk-3OMWVM6J.mjs} +11 -1
- package/dist/sdk/chunk-3OMWVM6J.mjs.map +1 -0
- package/dist/sdk/chunk-7UK3NIIT.mjs +482 -0
- package/dist/sdk/chunk-7UK3NIIT.mjs.map +1 -0
- package/dist/sdk/chunk-AGIZJ4UZ.mjs +173 -0
- package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +1 -0
- package/dist/sdk/chunk-AIVFBIS4.mjs +1371 -0
- package/dist/sdk/chunk-AIVFBIS4.mjs.map +1 -0
- package/dist/sdk/chunk-AK6BVWIT.mjs +426 -0
- package/dist/sdk/chunk-AK6BVWIT.mjs.map +1 -0
- package/dist/sdk/chunk-AUT26LHW.mjs +139 -0
- package/dist/sdk/chunk-AUT26LHW.mjs.map +1 -0
- package/dist/sdk/chunk-BOVFH3LI.mjs +232 -0
- package/dist/sdk/chunk-BOVFH3LI.mjs.map +1 -0
- package/dist/sdk/chunk-CNX7V5JK.mjs +89 -0
- package/dist/sdk/chunk-CNX7V5JK.mjs.map +1 -0
- package/dist/sdk/chunk-HTOKWMPO.mjs +157 -0
- package/dist/sdk/chunk-HTOKWMPO.mjs.map +1 -0
- package/dist/sdk/chunk-NAW3DB3I.mjs +197 -0
- package/dist/sdk/chunk-NAW3DB3I.mjs.map +1 -0
- package/dist/sdk/chunk-O5EZDNYL.mjs +274 -0
- package/dist/sdk/chunk-O5EZDNYL.mjs.map +1 -0
- package/dist/sdk/chunk-QR7MOMJH.mjs +558 -0
- package/dist/sdk/chunk-QR7MOMJH.mjs.map +1 -0
- package/dist/sdk/chunk-QY2XYPEV.mjs +3556 -0
- package/dist/sdk/chunk-QY2XYPEV.mjs.map +1 -0
- package/dist/sdk/chunk-S2RUE2RG.mjs +145 -0
- package/dist/sdk/chunk-S2RUE2RG.mjs.map +1 -0
- package/dist/sdk/chunk-SIWNBRTK.mjs +800 -0
- package/dist/sdk/chunk-SIWNBRTK.mjs.map +1 -0
- package/dist/sdk/chunk-YSN4G6CI.mjs +146 -0
- package/dist/sdk/chunk-YSN4G6CI.mjs.map +1 -0
- package/dist/sdk/chunk-ZYAUYXSW.mjs +206 -0
- package/dist/sdk/chunk-ZYAUYXSW.mjs.map +1 -0
- package/dist/sdk/command-executor-TYUV6HUS.mjs +14 -0
- package/dist/sdk/config-YNC2EOOT.mjs +16 -0
- package/dist/sdk/config-merger-PX3WIT57.mjs +10 -0
- package/dist/sdk/event-bus-5BEVPQ6T.mjs +35 -0
- package/dist/sdk/event-bus-5BEVPQ6T.mjs.map +1 -0
- package/dist/sdk/failure-condition-evaluator-YGTF2GHG.mjs +17 -0
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs +458 -0
- package/dist/sdk/git-repository-analyzer-HJC4MYW4.mjs.map +1 -0
- package/dist/sdk/github-frontend-SIAEOCON.mjs +1420 -0
- package/dist/sdk/github-frontend-SIAEOCON.mjs.map +1 -0
- package/dist/sdk/host-DXUYTNMU.mjs +52 -0
- package/dist/sdk/host-DXUYTNMU.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs → liquid-extensions-PKWCKK7E.mjs} +8 -2
- package/dist/sdk/memory-store-XGBB7LX7.mjs +12 -0
- package/dist/sdk/memory-store-XGBB7LX7.mjs.map +1 -0
- package/dist/sdk/metrics-7PP3EJUH.mjs +29 -0
- package/dist/sdk/metrics-7PP3EJUH.mjs.map +1 -0
- package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs +44 -0
- package/dist/sdk/ndjson-sink-B4V4NTAQ.mjs.map +1 -0
- package/dist/sdk/prompt-state-YRJY6QAL.mjs +16 -0
- package/dist/sdk/prompt-state-YRJY6QAL.mjs.map +1 -0
- package/dist/sdk/renderer-schema-LPKN5UJS.mjs +51 -0
- package/dist/sdk/renderer-schema-LPKN5UJS.mjs.map +1 -0
- package/dist/sdk/routing-6N45MJ4F.mjs +24 -0
- package/dist/sdk/routing-6N45MJ4F.mjs.map +1 -0
- package/dist/sdk/sdk.d.mts +541 -22
- package/dist/sdk/sdk.d.ts +541 -22
- package/dist/sdk/sdk.js +27963 -16505
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +1116 -2169
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/session-registry-4E6YRQ77.mjs +10 -0
- package/dist/sdk/session-registry-4E6YRQ77.mjs.map +1 -0
- package/dist/sdk/slack-frontend-BVKW3GD5.mjs +735 -0
- package/dist/sdk/slack-frontend-BVKW3GD5.mjs.map +1 -0
- package/dist/sdk/trace-helpers-VP6QYVBX.mjs +23 -0
- package/dist/sdk/trace-helpers-VP6QYVBX.mjs.map +1 -0
- package/dist/sdk/{tracer-init-WC75N5NW.mjs → tracer-init-GSLPPLCD.mjs} +2 -2
- package/dist/sdk/tracer-init-GSLPPLCD.mjs.map +1 -0
- package/dist/sdk/workflow-registry-R6KSACFR.mjs +12 -0
- package/dist/sdk/workflow-registry-R6KSACFR.mjs.map +1 -0
- package/dist/sdk.d.ts.map +1 -1
- package/dist/slack/adapter.d.ts +36 -0
- package/dist/slack/adapter.d.ts.map +1 -0
- package/dist/slack/cache-prewarmer.d.ts +31 -0
- package/dist/slack/cache-prewarmer.d.ts.map +1 -0
- package/dist/slack/client.d.ts +77 -0
- package/dist/slack/client.d.ts.map +1 -0
- package/dist/slack/markdown.d.ts +45 -0
- package/dist/slack/markdown.d.ts.map +1 -0
- package/dist/slack/prompt-state.d.ts +33 -0
- package/dist/slack/prompt-state.d.ts.map +1 -0
- package/dist/slack/rate-limiter.d.ts +56 -0
- package/dist/slack/rate-limiter.d.ts.map +1 -0
- package/dist/slack/signature.d.ts +2 -0
- package/dist/slack/signature.d.ts.map +1 -0
- package/dist/slack/socket-runner.d.ts +42 -0
- package/dist/slack/socket-runner.d.ts.map +1 -0
- package/dist/slack/thread-cache.d.ts +51 -0
- package/dist/slack/thread-cache.d.ts.map +1 -0
- package/dist/snapshot-store.d.ts +59 -0
- package/dist/snapshot-store.d.ts.map +1 -0
- package/dist/state-machine/context/build-engine-context.d.ts +17 -0
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -0
- package/dist/state-machine/dispatch/dependency-gating.d.ts +12 -0
- package/dist/state-machine/dispatch/dependency-gating.d.ts.map +1 -0
- package/dist/state-machine/dispatch/execution-invoker.d.ts +14 -0
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -0
- package/dist/state-machine/dispatch/foreach-processor.d.ts +8 -0
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -0
- package/dist/state-machine/dispatch/history-snapshot.d.ts +8 -0
- package/dist/state-machine/dispatch/history-snapshot.d.ts.map +1 -0
- package/dist/state-machine/dispatch/on-init-handlers.d.ts +43 -0
- package/dist/state-machine/dispatch/on-init-handlers.d.ts.map +1 -0
- package/dist/state-machine/dispatch/renderer-schema.d.ts +8 -0
- package/dist/state-machine/dispatch/renderer-schema.d.ts.map +1 -0
- package/dist/state-machine/dispatch/stats-manager.d.ts +15 -0
- package/dist/state-machine/dispatch/stats-manager.d.ts.map +1 -0
- package/dist/state-machine/dispatch/template-renderer.d.ts +7 -0
- package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -0
- package/dist/state-machine/execution/summary.d.ts +8 -0
- package/dist/state-machine/execution/summary.d.ts.map +1 -0
- package/dist/state-machine/runner.d.ts +79 -0
- package/dist/state-machine/runner.d.ts.map +1 -0
- package/dist/state-machine/states/check-running.d.ts +14 -0
- package/dist/state-machine/states/check-running.d.ts.map +1 -0
- package/dist/state-machine/states/completed.d.ts +12 -0
- package/dist/state-machine/states/completed.d.ts.map +1 -0
- package/dist/state-machine/states/error.d.ts +11 -0
- package/dist/state-machine/states/error.d.ts.map +1 -0
- package/dist/state-machine/states/init.d.ts +11 -0
- package/dist/state-machine/states/init.d.ts.map +1 -0
- package/dist/state-machine/states/level-dispatch.d.ts +17 -0
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -0
- package/dist/state-machine/states/plan-ready.d.ts +12 -0
- package/dist/state-machine/states/plan-ready.d.ts.map +1 -0
- package/dist/state-machine/states/routing.d.ts +52 -0
- package/dist/state-machine/states/routing.d.ts.map +1 -0
- package/dist/state-machine/states/wave-planning.d.ts +14 -0
- package/dist/state-machine/states/wave-planning.d.ts.map +1 -0
- package/dist/state-machine/workflow-projection.d.ts +47 -0
- package/dist/state-machine/workflow-projection.d.ts.map +1 -0
- package/dist/state-machine-execution-engine.d.ts +159 -0
- package/dist/state-machine-execution-engine.d.ts.map +1 -0
- package/dist/telemetry/opentelemetry.d.ts.map +1 -1
- package/dist/telemetry/state-capture.d.ts +5 -0
- package/dist/telemetry/state-capture.d.ts.map +1 -1
- package/dist/test-runner/assertions.d.ts +59 -0
- package/dist/test-runner/assertions.d.ts.map +1 -0
- package/dist/test-runner/core/environment.d.ts +8 -0
- package/dist/test-runner/core/environment.d.ts.map +1 -0
- package/dist/test-runner/core/fixture.d.ts +3 -0
- package/dist/test-runner/core/fixture.d.ts.map +1 -0
- package/dist/test-runner/core/flow-stage.d.ts +32 -0
- package/dist/test-runner/core/flow-stage.d.ts.map +1 -0
- package/dist/test-runner/core/mocks.d.ts +8 -0
- package/dist/test-runner/core/mocks.d.ts.map +1 -0
- package/dist/test-runner/core/test-execution-wrapper.d.ts +18 -0
- package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -0
- package/dist/test-runner/evaluators.d.ts +45 -0
- package/dist/test-runner/evaluators.d.ts.map +1 -0
- package/dist/test-runner/fixture-loader.d.ts +30 -0
- package/dist/test-runner/fixture-loader.d.ts.map +1 -0
- package/dist/test-runner/index.d.ts +127 -0
- package/dist/test-runner/index.d.ts.map +1 -0
- package/dist/test-runner/recorders/github-recorder.d.ts +23 -0
- package/dist/test-runner/recorders/github-recorder.d.ts.map +1 -0
- package/dist/test-runner/recorders/global-recorder.d.ts +4 -0
- package/dist/test-runner/recorders/global-recorder.d.ts.map +1 -0
- package/dist/test-runner/recorders/slack-recorder.d.ts +17 -0
- package/dist/test-runner/recorders/slack-recorder.d.ts.map +1 -0
- package/dist/test-runner/utils/selectors.d.ts +2 -0
- package/dist/test-runner/utils/selectors.d.ts.map +1 -0
- package/dist/test-runner/validator.d.ts +8 -0
- package/dist/test-runner/validator.d.ts.map +1 -0
- package/dist/traces/run-2026-01-20T19-22-58-043Z.ndjson +138 -0
- package/dist/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
- package/dist/types/bot.d.ts +109 -0
- package/dist/types/bot.d.ts.map +1 -0
- package/dist/types/cli.d.ts +8 -1
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +459 -9
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +177 -0
- package/dist/types/engine.d.ts.map +1 -0
- package/dist/types/execution.d.ts +73 -0
- package/dist/types/execution.d.ts.map +1 -0
- package/dist/types/git-checkout.d.ts +76 -0
- package/dist/types/git-checkout.d.ts.map +1 -0
- package/dist/types/github.d.ts +51 -0
- package/dist/types/github.d.ts.map +1 -0
- package/dist/types/workflow.d.ts +237 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/utils/command-executor.d.ts +43 -0
- package/dist/utils/command-executor.d.ts.map +1 -0
- package/dist/utils/comment-metadata.d.ts +21 -0
- package/dist/utils/comment-metadata.d.ts.map +1 -0
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-merger.d.ts.map +1 -1
- package/dist/utils/env-exposure.d.ts +3 -0
- package/dist/utils/env-exposure.d.ts.map +1 -0
- package/dist/utils/file-exclusion.d.ts.map +1 -1
- package/dist/utils/interactive-prompt.d.ts +1 -1
- package/dist/utils/interactive-prompt.d.ts.map +1 -1
- package/dist/utils/json-text-extractor.d.ts +17 -0
- package/dist/utils/json-text-extractor.d.ts.map +1 -0
- package/dist/utils/sandbox.d.ts +10 -0
- package/dist/utils/sandbox.d.ts.map +1 -1
- package/dist/utils/script-memory-ops.d.ts +21 -0
- package/dist/utils/script-memory-ops.d.ts.map +1 -0
- package/dist/utils/template-context.d.ts +8 -0
- package/dist/utils/template-context.d.ts.map +1 -0
- package/dist/utils/tracer-init.d.ts.map +1 -1
- package/dist/utils/workspace-manager.d.ts +118 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -0
- package/dist/utils/worktree-cleanup.d.ts +33 -0
- package/dist/utils/worktree-cleanup.d.ts.map +1 -0
- package/dist/utils/worktree-manager.d.ts +153 -0
- package/dist/utils/worktree-manager.d.ts.map +1 -0
- package/dist/webhook-server.d.ts +3 -3
- package/dist/webhook-server.d.ts.map +1 -1
- package/dist/workflow-executor.d.ts +81 -0
- package/dist/workflow-executor.d.ts.map +1 -0
- package/dist/workflow-registry.d.ts +79 -0
- package/dist/workflow-registry.d.ts.map +1 -0
- package/package.json +12 -5
- package/dist/output/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
- package/dist/sdk/check-execution-engine-2YYKUUSH.mjs +0 -11
- package/dist/sdk/check-execution-engine-6QJXYYON.mjs +0 -11
- package/dist/sdk/check-execution-engine-PJZ4ZOKG.mjs +0 -11
- package/dist/sdk/chunk-33QVZ2D4.mjs +0 -316
- package/dist/sdk/chunk-33QVZ2D4.mjs.map +0 -1
- package/dist/sdk/chunk-B5QBV2QJ.mjs +0 -752
- package/dist/sdk/chunk-B5QBV2QJ.mjs.map +0 -1
- package/dist/sdk/chunk-BVFNRCHT.mjs +0 -14129
- package/dist/sdk/chunk-BVFNRCHT.mjs.map +0 -1
- package/dist/sdk/chunk-KWZW23FG.mjs +0 -14129
- package/dist/sdk/chunk-KWZW23FG.mjs.map +0 -1
- package/dist/sdk/chunk-O4RP4BRH.mjs +0 -14092
- package/dist/sdk/chunk-O4RP4BRH.mjs.map +0 -1
- package/dist/sdk/chunk-TUTOLSFV.mjs.map +0 -1
- package/dist/sdk/chunk-U5D2LY66.mjs +0 -245
- package/dist/sdk/chunk-U5D2LY66.mjs.map +0 -1
- package/dist/sdk/chunk-U7X54EMV.mjs +0 -331
- package/dist/sdk/chunk-U7X54EMV.mjs.map +0 -1
- package/dist/sdk/config-merger-TWUBWFC2.mjs +0 -8
- package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs +0 -61
- package/dist/sdk/mermaid-telemetry-SN6A2TKW.mjs.map +0 -1
- package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs +0 -61
- package/dist/sdk/mermaid-telemetry-YCTIG76M.mjs.map +0 -1
- package/dist/traces/run-2025-10-22T18-22-56-873Z.ndjson +0 -218
- /package/dist/sdk/{check-execution-engine-2YYKUUSH.mjs.map → check-provider-registry-534KL5HT.mjs.map} +0 -0
- /package/dist/sdk/{check-execution-engine-6QJXYYON.mjs.map → command-executor-TYUV6HUS.mjs.map} +0 -0
- /package/dist/sdk/{check-execution-engine-PJZ4ZOKG.mjs.map → config-YNC2EOOT.mjs.map} +0 -0
- /package/dist/sdk/{config-merger-TWUBWFC2.mjs.map → config-merger-PX3WIT57.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-KVL4MKRH.mjs.map → failure-condition-evaluator-YGTF2GHG.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-WC75N5NW.mjs.map → liquid-extensions-PKWCKK7E.mjs.map} +0 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# ForEach Output: Validation, Dependent Propagation, and on_finish
|
|
2
|
+
|
|
3
|
+
This doc clarifies how `forEach` output is validated, how it affects dependent checks, and how to use the `on_finish` hook for aggregation and routing after all forEach iterations complete.
|
|
4
|
+
|
|
5
|
+
## Valid and invalid outputs
|
|
6
|
+
|
|
7
|
+
- `transform_js` or provider output must resolve to a value. If it is `undefined`, the engine emits an error:
|
|
8
|
+
- Issue: `forEach/undefined_output`
|
|
9
|
+
- Effect: direct dependents are skipped (`dependency_failed`).
|
|
10
|
+
- If the value is an array, the engine iterates items.
|
|
11
|
+
- If the value is a string, the engine tries to JSON.parse it; if it parses to an array, that array is used; otherwise it treats the string as a single item.
|
|
12
|
+
- If the value is `null`, it is normalized to an empty array (0 iterations).
|
|
13
|
+
|
|
14
|
+
## Empty arrays vs undefined
|
|
15
|
+
|
|
16
|
+
- `[]` (empty array): valid — the check runs zero iterations. Dependents that rely on items are effectively skipped (no provider execution), and you’ll see a log like:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
forEach: no items from "fetch-tickets", skipping check...
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- `undefined`: invalid — treated as a configuration/transform error. The engine emits a `forEach/undefined_output` issue and skips direct dependents.
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
```yaml
|
|
27
|
+
steps:
|
|
28
|
+
fetch-tickets:
|
|
29
|
+
type: command
|
|
30
|
+
exec: echo '{"tickets": []}'
|
|
31
|
+
transform_js: JSON.parse(output).tickets
|
|
32
|
+
forEach: true
|
|
33
|
+
|
|
34
|
+
analyze-ticket:
|
|
35
|
+
type: command
|
|
36
|
+
depends_on: [fetch-tickets]
|
|
37
|
+
exec: echo "TICKET: {{ outputs['fetch-tickets'].key }}"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
- If `tickets` is `[]`, `analyze-ticket` is effectively skipped (no per‑item execution).
|
|
41
|
+
- If `transform_js` returns `undefined`, the engine raises `forEach/undefined_output` and `analyze-ticket` is skipped due to a failed dependency.
|
|
42
|
+
|
|
43
|
+
## Output Access and History with forEach
|
|
44
|
+
|
|
45
|
+
When a check has `forEach: true`, three accessors are available:
|
|
46
|
+
- `outputs['check-name']` — nearest value in scope (inside an iteration, this is the current item).
|
|
47
|
+
- `outputs_raw['check-name']` — aggregate/parent value (the full array produced by the forEach parent).
|
|
48
|
+
- `outputs.history['check-name']` — all committed values up to the current snapshot (alias: `outputs_history['check-name']`).
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
steps:
|
|
52
|
+
process-items:
|
|
53
|
+
type: script
|
|
54
|
+
depends_on: [fetch-tickets]
|
|
55
|
+
forEach: true
|
|
56
|
+
content: |
|
|
57
|
+
const curr = outputs['fetch-tickets'];
|
|
58
|
+
return { itemId: curr.key, processed: true };
|
|
59
|
+
|
|
60
|
+
summarize:
|
|
61
|
+
type: script
|
|
62
|
+
depends_on: [process-items]
|
|
63
|
+
content: |
|
|
64
|
+
// Access all forEach iteration results
|
|
65
|
+
const allProcessed = outputs.history['process-items']; # or outputs_history['process-items']
|
|
66
|
+
return { totalProcessed: allProcessed.length };
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Precedence rules (summary):
|
|
70
|
+
- `outputs['x']` resolves to the nearest item if inside a per-item scope of `x`; otherwise to an ancestor value; otherwise to the latest committed.
|
|
71
|
+
- `outputs_raw['x']` resolves to the shallowest/aggregate scope of `x` (e.g., the full array for a forEach parent).
|
|
72
|
+
- `outputs.history['x']` returns all committed values for `x` in this session up to the snapshot.
|
|
73
|
+
|
|
74
|
+
Routing JS also gets `outputs_raw` with the same semantics, so you can branch on the aggregate even when you’re inside a per-item iteration.
|
|
75
|
+
|
|
76
|
+
See [Output History](./output-history.md) for more details on tracking outputs across iterations.
|
|
77
|
+
|
|
78
|
+
## The on_finish Hook: Lifecycle Extension
|
|
79
|
+
|
|
80
|
+
The `on_finish` hook is a special routing action that extends the forEach lifecycle. It triggers **once** after **all** dependent checks complete **all** their iterations, providing a single point for aggregation and routing decisions.
|
|
81
|
+
|
|
82
|
+
### Complete forEach Lifecycle
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
1. forEach Check Executes
|
|
86
|
+
└─> Outputs array: [item1, item2, item3]
|
|
87
|
+
|
|
88
|
+
2. Dependent Checks Execute (N iterations)
|
|
89
|
+
├─> dependent-check runs for item1
|
|
90
|
+
├─> dependent-check runs for item2
|
|
91
|
+
└─> dependent-check runs for item3
|
|
92
|
+
|
|
93
|
+
3. on_finish Hook Triggers (on the forEach check)
|
|
94
|
+
├─> on_finish.run executes (optional aggregation checks)
|
|
95
|
+
├─> on_finish.run_js evaluates (optional dynamic checks)
|
|
96
|
+
├─> on_finish.goto_js evaluates (optional routing decision)
|
|
97
|
+
└─> If goto returns a check name, jump to that ancestor
|
|
98
|
+
|
|
99
|
+
4. Downstream Checks Execute
|
|
100
|
+
└─> Checks that don't depend on the forEach check continue
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### When on_finish Triggers
|
|
104
|
+
|
|
105
|
+
- **Only** on checks with `forEach: true`
|
|
106
|
+
- **After** ALL dependent checks complete ALL iterations
|
|
107
|
+
- **Does not** trigger if forEach array is empty (`[]`)
|
|
108
|
+
- **Does not** trigger if output is `undefined` (error state)
|
|
109
|
+
- **Always** triggers after successful forEach propagation
|
|
110
|
+
|
|
111
|
+
### Configuration
|
|
112
|
+
|
|
113
|
+
```yaml
|
|
114
|
+
checks:
|
|
115
|
+
extract-facts:
|
|
116
|
+
type: ai
|
|
117
|
+
forEach: true
|
|
118
|
+
prompt: "Extract facts from {{ outputs.response }}"
|
|
119
|
+
transform_js: JSON.parse(output).facts
|
|
120
|
+
|
|
121
|
+
# on_finish runs after all validate-fact iterations complete
|
|
122
|
+
on_finish:
|
|
123
|
+
# Optional: Run aggregation checks
|
|
124
|
+
run: [aggregate-validations]
|
|
125
|
+
|
|
126
|
+
# Optional: Make routing decision
|
|
127
|
+
goto_js: |
|
|
128
|
+
const allValid = memory.get('all_facts_valid', 'validation');
|
|
129
|
+
const attempt = memory.get('fact_validation_attempt', 'validation') || 0;
|
|
130
|
+
|
|
131
|
+
if (allValid) {
|
|
132
|
+
return null; // Continue to downstream checks
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (attempt >= 1) {
|
|
136
|
+
return null; // Max attempts, give up
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
memory.increment('fact_validation_attempt', 1, 'validation');
|
|
140
|
+
return 'generate-response'; // Jump back to ancestor
|
|
141
|
+
|
|
142
|
+
# Optional: Override event for goto target
|
|
143
|
+
goto_event: issue_opened
|
|
144
|
+
|
|
145
|
+
validate-fact:
|
|
146
|
+
type: ai
|
|
147
|
+
depends_on: [extract-facts]
|
|
148
|
+
# Runs N times (once per fact)
|
|
149
|
+
|
|
150
|
+
aggregate-validations:
|
|
151
|
+
type: script
|
|
152
|
+
fanout: reduce # ensure single aggregation run after forEach
|
|
153
|
+
content: |
|
|
154
|
+
// Access all validation results
|
|
155
|
+
const validations = outputs.history['validate-fact'];
|
|
156
|
+
const allValid = validations.every(v => v.is_valid);
|
|
157
|
+
memory.set('all_facts_valid', allValid, 'validation');
|
|
158
|
+
return { total: validations.length, valid: allValid };
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Context Available in on_finish
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
{
|
|
165
|
+
step: {
|
|
166
|
+
id: 'extract-facts',
|
|
167
|
+
tags: [...],
|
|
168
|
+
group: '...'
|
|
169
|
+
},
|
|
170
|
+
attempt: 1, // Attempt number for this check
|
|
171
|
+
loop: 2, // Loop number in routing
|
|
172
|
+
outputs: {
|
|
173
|
+
'extract-facts': [...], // The forEach array
|
|
174
|
+
'validate-fact': [...], // Latest dependent results
|
|
175
|
+
},
|
|
176
|
+
outputs.history: {
|
|
177
|
+
'extract-facts': [[...], ...], // Historical forEach outputs
|
|
178
|
+
'validate-fact': [[...], ...], // ALL iteration results
|
|
179
|
+
},
|
|
180
|
+
forEach: {
|
|
181
|
+
total: 3, // Number of items processed
|
|
182
|
+
successful: 3, // Successful iterations
|
|
183
|
+
failed: 0, // Failed iterations
|
|
184
|
+
items: [...] // The forEach items array
|
|
185
|
+
},
|
|
186
|
+
memory, // Memory access functions
|
|
187
|
+
pr, // PR metadata
|
|
188
|
+
files, // Changed files
|
|
189
|
+
env // Environment variables
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Flow Diagram with on_finish
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
┌─────────────────────┐
|
|
197
|
+
│ forEach Check │
|
|
198
|
+
│ outputs: [1,2,3] │
|
|
199
|
+
└──────────┬──────────┘
|
|
200
|
+
│
|
|
201
|
+
├──────────────────────────────┐
|
|
202
|
+
│ │
|
|
203
|
+
▼ ▼
|
|
204
|
+
┌──────────────┐ ┌──────────────┐
|
|
205
|
+
│ Dependent A │ │ Dependent B │
|
|
206
|
+
│ (3 times) │ │ (3 times) │
|
|
207
|
+
└──────┬───────┘ └──────┬───────┘
|
|
208
|
+
│ │
|
|
209
|
+
└───────────┬───────────────┘
|
|
210
|
+
│
|
|
211
|
+
▼
|
|
212
|
+
┌─────────────────────┐
|
|
213
|
+
│ on_finish hook │
|
|
214
|
+
│ ┌─────────────┐ │
|
|
215
|
+
│ │ run: [] │ │
|
|
216
|
+
│ ├─────────────┤ │
|
|
217
|
+
│ │ goto_js │ │
|
|
218
|
+
│ └─────────────┘ │
|
|
219
|
+
└──────────┬──────────┘
|
|
220
|
+
│
|
|
221
|
+
┌─────────────┴──────────────┐
|
|
222
|
+
│ │
|
|
223
|
+
▼ ▼
|
|
224
|
+
goto target? Downstream
|
|
225
|
+
(ancestor) Checks
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Example: Validation with Retry
|
|
229
|
+
|
|
230
|
+
A complete example showing validation, aggregation, and retry:
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
checks:
|
|
234
|
+
# Step 1: Generate initial response
|
|
235
|
+
generate-response:
|
|
236
|
+
type: ai
|
|
237
|
+
prompt: "Generate response for: {{ event.issue.body }}"
|
|
238
|
+
|
|
239
|
+
# Step 2: Extract facts (forEach)
|
|
240
|
+
extract-facts:
|
|
241
|
+
type: ai
|
|
242
|
+
depends_on: [generate-response]
|
|
243
|
+
forEach: true
|
|
244
|
+
prompt: |
|
|
245
|
+
Extract verifiable facts from: {{ outputs['generate-response'] }}
|
|
246
|
+
Return JSON: [{"claim": "...", "category": "..."}]
|
|
247
|
+
transform_js: JSON.parse(output)
|
|
248
|
+
|
|
249
|
+
# Step 5: Aggregate and route
|
|
250
|
+
on_finish:
|
|
251
|
+
run: [aggregate-validations]
|
|
252
|
+
goto_js: |
|
|
253
|
+
const allValid = memory.get('all_valid', 'fact-validation');
|
|
254
|
+
const attempt = memory.get('attempt', 'fact-validation') || 0;
|
|
255
|
+
|
|
256
|
+
log('Validation complete:', {
|
|
257
|
+
allValid,
|
|
258
|
+
attempt,
|
|
259
|
+
forEach: forEach.total + ' facts checked'
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
if (allValid) {
|
|
263
|
+
log('All valid, proceeding to post');
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (attempt >= 1) {
|
|
268
|
+
log('Max attempts reached');
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
log('Retrying with validation context');
|
|
273
|
+
memory.increment('attempt', 1, 'fact-validation');
|
|
274
|
+
return 'generate-response';
|
|
275
|
+
|
|
276
|
+
# Step 3: Validate each fact (runs N times)
|
|
277
|
+
validate-fact:
|
|
278
|
+
type: ai
|
|
279
|
+
depends_on: [extract-facts]
|
|
280
|
+
prompt: |
|
|
281
|
+
Verify this fact using code search:
|
|
282
|
+
Claim: {{ outputs['extract-facts'].claim }}
|
|
283
|
+
Category: {{ outputs['extract-facts'].category }}
|
|
284
|
+
|
|
285
|
+
Return JSON: {"is_valid": true/false, "evidence": "..."}
|
|
286
|
+
transform_js: JSON.parse(output)
|
|
287
|
+
|
|
288
|
+
# Step 4: Aggregate all validation results
|
|
289
|
+
aggregate-validations:
|
|
290
|
+
type: script
|
|
291
|
+
content: |
|
|
292
|
+
// Get ALL validation results from forEach iterations
|
|
293
|
+
const validations = outputs.history['validate-fact'];
|
|
294
|
+
|
|
295
|
+
log('Aggregating', validations.length, 'validations');
|
|
296
|
+
|
|
297
|
+
const invalid = validations.filter(v => !v.is_valid);
|
|
298
|
+
const allValid = invalid.length === 0;
|
|
299
|
+
|
|
300
|
+
// Store for goto_js and downstream checks
|
|
301
|
+
memory.set('all_valid', allValid, 'fact-validation');
|
|
302
|
+
memory.set('invalid_count', invalid.length, 'fact-validation');
|
|
303
|
+
|
|
304
|
+
// Store issues for retry context
|
|
305
|
+
if (!allValid) {
|
|
306
|
+
memory.set('validation_issues', invalid, 'fact-validation');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return {
|
|
310
|
+
total: validations.length,
|
|
311
|
+
valid: validations.length - invalid.length,
|
|
312
|
+
invalid: invalid.length,
|
|
313
|
+
all_valid: allValid
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
# Step 6: Post response (only if valid)
|
|
317
|
+
post-response:
|
|
318
|
+
type: github
|
|
319
|
+
depends_on: [extract-facts]
|
|
320
|
+
if: "memory.get('all_valid', 'fact-validation') === true"
|
|
321
|
+
op: comment.create
|
|
322
|
+
value: "{{ outputs['generate-response'] }}"
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
**Flow:**
|
|
326
|
+
1. `generate-response` runs → outputs AI response
|
|
327
|
+
2. `extract-facts` runs → outputs `[fact1, fact2, fact3]`
|
|
328
|
+
3. `validate-fact` runs 3 times (once per fact)
|
|
329
|
+
4. **on_finish triggers:**
|
|
330
|
+
- `aggregate-validations` runs → stores results in memory
|
|
331
|
+
- `goto_js` evaluates → returns `'generate-response'` or `null`
|
|
332
|
+
5. If goto returned a check name:
|
|
333
|
+
- Jump to `generate-response` (with incremented attempt counter)
|
|
334
|
+
- Re-run the entire flow with validation context
|
|
335
|
+
6. If goto returned `null`:
|
|
336
|
+
- Continue to `post-response` (if validation passed)
|
|
337
|
+
|
|
338
|
+
### Multiple Dependents Pattern
|
|
339
|
+
|
|
340
|
+
The power of `on_finish` is aggregating across **multiple** dependent checks:
|
|
341
|
+
|
|
342
|
+
```yaml
|
|
343
|
+
checks:
|
|
344
|
+
extract-claims:
|
|
345
|
+
type: ai
|
|
346
|
+
forEach: true
|
|
347
|
+
on_finish:
|
|
348
|
+
run: [aggregate-all]
|
|
349
|
+
goto_js: |
|
|
350
|
+
const securityOk = memory.get('security_ok', 'validation');
|
|
351
|
+
const techOk = memory.get('tech_ok', 'validation');
|
|
352
|
+
return (securityOk && techOk) ? null : 'retry';
|
|
353
|
+
|
|
354
|
+
# Multiple dependents, all run N times
|
|
355
|
+
validate-security:
|
|
356
|
+
depends_on: [extract-claims]
|
|
357
|
+
|
|
358
|
+
validate-technical:
|
|
359
|
+
depends_on: [extract-claims]
|
|
360
|
+
|
|
361
|
+
validate-style:
|
|
362
|
+
depends_on: [extract-claims]
|
|
363
|
+
|
|
364
|
+
aggregate-all:
|
|
365
|
+
type: script
|
|
366
|
+
fanout: reduce
|
|
367
|
+
content: |
|
|
368
|
+
// Access ALL results from ALL dependent checks
|
|
369
|
+
const security = outputs.history['validate-security'];
|
|
370
|
+
const technical = outputs.history['validate-technical'];
|
|
371
|
+
const style = outputs.history['validate-style'];
|
|
372
|
+
|
|
373
|
+
memory.set('security_ok', security.every(r => r.valid), 'validation');
|
|
374
|
+
memory.set('tech_ok', technical.every(r => r.valid), 'validation');
|
|
375
|
+
memory.set('style_ok', style.every(r => r.valid), 'validation');
|
|
376
|
+
|
|
377
|
+
return { aggregated: true };
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
This is the **only way** to aggregate across multiple dependent checks after forEach completes.
|
|
381
|
+
|
|
382
|
+
### Error Handling in on_finish
|
|
383
|
+
|
|
384
|
+
- If `on_finish.run` checks fail, the forEach check is marked as failed
|
|
385
|
+
- If `goto_js` throws an error, the engine falls back to static `goto` (if present)
|
|
386
|
+
- If no fallback exists, the error is logged and execution continues
|
|
387
|
+
- Loop safety: `on_finish.goto` counts toward `routing.max_loops`
|
|
388
|
+
|
|
389
|
+
### Best Practices for on_finish
|
|
390
|
+
|
|
391
|
+
1. **Always Aggregate First**: Use `on_finish.run` to aggregate before `goto_js` runs
|
|
392
|
+
2. **Use outputs.history**: Access all iteration results with `outputs.history['check-name']`
|
|
393
|
+
3. **Store in Memory**: Pass aggregated state to `goto_js` and downstream checks via memory
|
|
394
|
+
4. **Limit Retries**: Track attempt counts in memory to prevent infinite loops
|
|
395
|
+
5. **Handle Empty Arrays**: Check `forEach.total` or array length before processing
|
|
396
|
+
6. **Log Decisions**: Use `log()` in JavaScript to debug routing decisions
|
|
397
|
+
7. **Check Multiple Dependents**: Perfect for scenarios with multiple dependent checks
|
|
398
|
+
|
|
399
|
+
### Common Pitfalls
|
|
400
|
+
|
|
401
|
+
❌ **Don't** use `on_finish` on non-forEach checks:
|
|
402
|
+
```yaml
|
|
403
|
+
regular-check:
|
|
404
|
+
type: command
|
|
405
|
+
on_finish: # ❌ ERROR: on_finish requires forEach: true
|
|
406
|
+
run: [something]
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
❌ **Don't** forget to return from `goto_js`:
|
|
410
|
+
```javascript
|
|
411
|
+
goto_js: |
|
|
412
|
+
const shouldRetry = memory.get('should_retry');
|
|
413
|
+
'retry-check'; // ❌ Missing return statement
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
✅ **Do** return explicitly:
|
|
417
|
+
```javascript
|
|
418
|
+
goto_js: |
|
|
419
|
+
const shouldRetry = memory.get('should_retry');
|
|
420
|
+
return shouldRetry ? 'retry-check' : null; // ✅ Explicit return
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
❌ **Don't** access `outputs['check']` for iteration results:
|
|
424
|
+
```javascript
|
|
425
|
+
// ❌ Only gives latest result
|
|
426
|
+
const results = outputs['validate-fact'];
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
✅ **Do** use `outputs.history` for all iterations:
|
|
430
|
+
```javascript
|
|
431
|
+
// ✅ All iteration results
|
|
432
|
+
const results = outputs.history['validate-fact'];
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Tips
|
|
436
|
+
|
|
437
|
+
- Always `return` from `transform_js`. Missing `return` is the most common cause of `undefined`.
|
|
438
|
+
- Prefer returning arrays directly from `transform_js` (avoid stringifying) to keep types clear and avoid parsing surprises.
|
|
439
|
+
- Use `outputs.history` to access all forEach iteration results in dependent checks and `on_finish` hooks.
|
|
440
|
+
- Use `on_finish` for aggregation after all forEach iterations complete.
|
|
441
|
+
- Store aggregated state in memory for use in `goto_js` and downstream checks.
|
|
442
|
+
- Track attempt counters in memory to prevent infinite retry loops.
|
|
443
|
+
|
|
444
|
+
## See Also
|
|
445
|
+
|
|
446
|
+
- [Failure Routing](./failure-routing.md) - Complete `on_finish` reference with examples
|
|
447
|
+
- [Dependencies](./dependencies.md) - `on_finish` with forEach propagation patterns
|
|
448
|
+
- [Output History](./output-history.md) - Accessing historical outputs across iterations
|
|
449
|
+
- [examples/fact-validator.yaml](../examples/fact-validator.yaml) - Complete working example
|
|
450
|
+
## Fan-out Control for Routing (Phase 5)
|
|
451
|
+
|
|
452
|
+
When routing from a forEach context, you can opt into per‑item runs without writing manual loops:
|
|
453
|
+
|
|
454
|
+
- Add `fanout: map` to the target check to schedule it once per item.
|
|
455
|
+
- Add `fanout: reduce` (or `reduce: true`) to run once at the parent scope (default).
|
|
456
|
+
|
|
457
|
+
This works with `on_success.run/goto`, `on_fail.run/goto`, and `on_finish.run/goto`.
|
|
458
|
+
|
|
459
|
+
Example:
|
|
460
|
+
```yaml
|
|
461
|
+
checks:
|
|
462
|
+
files:
|
|
463
|
+
type: command
|
|
464
|
+
exec: git ls-files '*.ts'
|
|
465
|
+
forEach: true
|
|
466
|
+
on_success:
|
|
467
|
+
run: [lint-file]
|
|
468
|
+
|
|
469
|
+
lint-file:
|
|
470
|
+
type: command
|
|
471
|
+
fanout: map
|
|
472
|
+
exec: eslint {{ outputs['files'] }}
|
|
473
|
+
```
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Native GitHub Provider
|
|
2
|
+
|
|
3
|
+
The `github` provider performs safe, native GitHub operations via Octokit — no shelling out to `gh`.
|
|
4
|
+
|
|
5
|
+
- Supported ops: `labels.add`, `labels.remove`, `comment.create`.
|
|
6
|
+
- Works on Pull Requests and Issues (uses the current PR/issue number from the event context).
|
|
7
|
+
- Returns provider issues on failures instead of crashing the run.
|
|
8
|
+
|
|
9
|
+
## Requirements
|
|
10
|
+
|
|
11
|
+
- `GITHUB_TOKEN` (or the Action input `github-token`) must be present.
|
|
12
|
+
- `GITHUB_REPOSITORY` is auto‑set in Actions.
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
steps:
|
|
18
|
+
apply-overview-labels:
|
|
19
|
+
type: github
|
|
20
|
+
group: github
|
|
21
|
+
tags: [github]
|
|
22
|
+
depends_on: [overview]
|
|
23
|
+
on: [pr_opened, pr_updated]
|
|
24
|
+
op: labels.add
|
|
25
|
+
values:
|
|
26
|
+
- "{{ outputs.overview.tags.label | default: '' | safe_label }}"
|
|
27
|
+
- "{{ outputs.overview.tags['review-effort'] | default: '' | prepend: 'review/effort:' | safe_label }}"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Notes:
|
|
31
|
+
- Empty strings are ignored automatically; no `value_js` needed to filter them out.
|
|
32
|
+
|
|
33
|
+
### Issues (Errors) Emitted
|
|
34
|
+
|
|
35
|
+
When the provider cannot perform an operation, it returns a synthetic issue in the check’s output:
|
|
36
|
+
|
|
37
|
+
- `github/missing_token` — no token available
|
|
38
|
+
- `github/missing_context` — missing owner/repo/PR number
|
|
39
|
+
- `github/unsupported_op` — unknown `op`
|
|
40
|
+
- `github/value_js_error` — exception thrown while evaluating `value_js`
|
|
41
|
+
- `github/op_failed` — Octokit call failed (includes error message)
|
|
42
|
+
|
|
43
|
+
These issues are visible in tables/markdown output and will not abort the whole workflow; use `fail_if` to control behavior.
|
|
44
|
+
|
|
45
|
+
## Labels: Sanitization
|
|
46
|
+
|
|
47
|
+
To prevent injection and ensure GitHub‑compatible labels, use Liquid filters:
|
|
48
|
+
|
|
49
|
+
- `safe_label` — keeps only `[A-Za-z0-9:/\- ]` (alphanumerics, colon, slash, hyphen, and space), collapses repeated `/`, and trims whitespace.
|
|
50
|
+
- `safe_label_list` — applies `safe_label` to arrays and removes empty values.
|
|
51
|
+
|
|
52
|
+
Examples:
|
|
53
|
+
```yaml
|
|
54
|
+
values:
|
|
55
|
+
- "{{ outputs['issue-assistant'].tags.label | safe_label }}"
|
|
56
|
+
- "{{ outputs.overview.tags['review-effort'] | prepend: 'review/effort:' | safe_label }}"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
> Important: Do not build shell commands from labels. The `github` provider calls the API directly.
|
|
60
|
+
|
|
61
|
+
## Creating Comments
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
steps:
|
|
65
|
+
post-note:
|
|
66
|
+
type: github
|
|
67
|
+
op: comment.create
|
|
68
|
+
values:
|
|
69
|
+
- "Automated note for PR #{{ pr.number }}"
|
|
70
|
+
- "\nDetails: {{ outputs.security.text | default: '' | unescape_newlines }}"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Removing Labels
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
steps:
|
|
77
|
+
cleanup-labels:
|
|
78
|
+
type: github
|
|
79
|
+
op: labels.remove
|
|
80
|
+
values:
|
|
81
|
+
- legacy/triage
|
|
82
|
+
- stale
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Tips
|
|
86
|
+
|
|
87
|
+
- Combine Liquid and `value_js` to build dynamic, multi‑label operations safely.
|
|
88
|
+
- Use `tags: [github]` to run these checks only in Actions (paired with `--tags github`).
|
|
89
|
+
- Pair with `if:` conditions to gate on prior outputs, e.g., apply labels only when `outputs.overview.tags.label` exists.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Visor Engine Plan: Use `goto` for Looping on Failures
|
|
2
|
+
|
|
3
|
+
This document captures the plan to simplify looping by using `goto` in `on_fail` and letting the engine re‑run the dependent chain deterministically.
|
|
4
|
+
|
|
5
|
+
## Background
|
|
6
|
+
|
|
7
|
+
Today, builder YAML uses `on_fail.run: [agent-refine, agent-write, config-lint, tests-validate, agent-verify-tests, …]` to bounce back through the pipeline. This is verbose and couples control‑flow to YAML.
|
|
8
|
+
|
|
9
|
+
Engine behavior:
|
|
10
|
+
- `on_success.goto` performs a forward‑run: it executes the `goto` target and all its dependents in topological order.
|
|
11
|
+
- `on_fail.goto` is currently limited to ancestor targets and does not forward‑run dependents.
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Allow clean, minimal YAML that uses only `goto` for looping:
|
|
16
|
+
- Validators: `on_fail: goto: agent-refine` (or directly `goto: agent-write`).
|
|
17
|
+
- Refine: `on_success: goto: agent-write`.
|
|
18
|
+
|
|
19
|
+
The engine should handle re‑running the necessary chain; YAML should not list the entire sequence.
|
|
20
|
+
|
|
21
|
+
## Proposed Engine Changes
|
|
22
|
+
|
|
23
|
+
1) Unify `goto` semantics across origins
|
|
24
|
+
- Make `goto` perform the same forward‑run whether invoked from `on_success`, `on_fail`, or `on_finish`.
|
|
25
|
+
- Factor shared code into a helper (e.g., `scheduleForwardRun(target, opts)`), currently implemented only inside the `on_success.goto` branch.
|
|
26
|
+
|
|
27
|
+
2) Relax ancestor‑only restriction for `on_fail.goto`
|
|
28
|
+
- Allow `goto` to any step in the DAG, not only ancestors.
|
|
29
|
+
- Keep safety guards (below) to prevent runaway loops.
|
|
30
|
+
|
|
31
|
+
3) Optional: Add anchors
|
|
32
|
+
- Introduce `anchor: true` (or `loop_anchor: true`) on steps like `agent-write`.
|
|
33
|
+
- If a validator has `on_fail` without explicit `goto`, engine can jump to the nearest anchor.
|
|
34
|
+
|
|
35
|
+
4) Loop safety and predictability
|
|
36
|
+
- Keep `routing.max_loops` budget (already implemented).
|
|
37
|
+
- Respect `one_shot` tag: skip re‑running steps with `tags: [one_shot]` that already executed in this run.
|
|
38
|
+
- Maintain per‑run statistics to avoid duplicate scheduling within a wave.
|
|
39
|
+
|
|
40
|
+
5) Forward‑run details
|
|
41
|
+
- From the target (e.g., `agent-write`), compute the dependent subgraph (topological order) honoring `depends_on` and event filters.
|
|
42
|
+
- Preserve current event by default; honor `goto_event` only when explicitly provided.
|
|
43
|
+
|
|
44
|
+
## YAML Patterns After the Change
|
|
45
|
+
|
|
46
|
+
Pattern A (pure goto):
|
|
47
|
+
- Validators (`config-lint`, `tests-validate`, `agent-verify-tests`):
|
|
48
|
+
```yaml
|
|
49
|
+
on_fail:
|
|
50
|
+
goto: agent-refine
|
|
51
|
+
```
|
|
52
|
+
- Refine:
|
|
53
|
+
```yaml
|
|
54
|
+
on_success:
|
|
55
|
+
goto: agent-write
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Pattern B (single hop to anchor):
|
|
59
|
+
- Validators:
|
|
60
|
+
```yaml
|
|
61
|
+
on_fail:
|
|
62
|
+
goto: agent-write
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Migration Plan
|
|
66
|
+
|
|
67
|
+
1) Engine implementation
|
|
68
|
+
- Unify forward‑run for `goto` in `on_fail` and `on_finish`.
|
|
69
|
+
- Remove ancestor‑only restriction or gate it behind a feature flag (e.g., `VISOR_GOTO_GLOBAL=true`).
|
|
70
|
+
- Extract forward‑run into a shared helper.
|
|
71
|
+
|
|
72
|
+
2) Builder YAML simplification
|
|
73
|
+
- Replace `on_fail.run: [ …full list… ]` with `on_fail: goto: agent-refine`.
|
|
74
|
+
- Keep `agent-refine on_success: goto: agent-write`.
|
|
75
|
+
|
|
76
|
+
3) Tests (exact counts only)
|
|
77
|
+
- Single‑invocation multi‑refine (3 cycles):
|
|
78
|
+
- `refine = 3`, `write/lint/validate = 4`, `verify-tests = 3`, `code-review/cleanup/finish = 1`.
|
|
79
|
+
- Flow tests (staged multi‑refine) remain for readability.
|
|
80
|
+
- Edge cases: loop budget exceeded, `one_shot` steps, event override.
|
|
81
|
+
|
|
82
|
+
## Code Pointers
|
|
83
|
+
|
|
84
|
+
File: `src/check-execution-engine.ts`
|
|
85
|
+
- `executeWithRouting` — handles `on_fail.run/goto` and `on_success.run/goto`:
|
|
86
|
+
- Unify forward‑run behavior for `goto` across origins.
|
|
87
|
+
- Current forward‑run logic lives in the `on_success.goto` branch (search for comments near topological ordering and `forwardSet`).
|
|
88
|
+
- `runNamedCheck` — respects `if` conditions and records stats; ensure forward‑run uses consistent overlays/results.
|
|
89
|
+
- Guards: `routing.max_loops`, `oncePerRun`/`one_shot` behavior, execution statistics.
|
|
90
|
+
|
|
91
|
+
Suggested refactor:
|
|
92
|
+
- Introduce `scheduleForwardRun(target, scope, opts)` used by all `goto` sites.
|
|
93
|
+
- Extract subgraph building + topo sort into a helper for reuse.
|
|
94
|
+
|
|
95
|
+
## Telemetry / Debug
|
|
96
|
+
- Add concise debug logs for `goto` forward‑run across all origins: target, number of dependents, topological order.
|
|
97
|
+
- Keep existing OTEL and NDJSON traces.
|
|
98
|
+
|
|
99
|
+
## Rollout
|
|
100
|
+
- Implemented without a feature flag. Old configs are not broken: `goto` to
|
|
101
|
+
ancestors preserves the previous “re-run ancestor only” behavior. New behavior
|
|
102
|
+
simply allows `goto` to any step and forward‑runs its dependents when routing
|
|
103
|
+
to a non‑ancestor.
|
|
104
|
+
- Builder YAML switched to pure `goto` in validators.
|
|
105
|
+
|
|
106
|
+
## Open Questions
|
|
107
|
+
- Should `goto` always forward‑run, or only when target is an anchor? (Leaning: always forward‑run for clarity.)
|
|
108
|
+
- Should we auto‑select an anchor when `goto` target is omitted? (Future convenience.)
|
|
109
|
+
|
|
110
|
+
## Acceptance Criteria
|
|
111
|
+
- Single‑run multi‑refine test passes with exact counts.
|
|
112
|
+
- Flow multi‑refine tests pass.
|
|
113
|
+
- No regression in existing suites; loop budget respected.
|