@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/config-merger.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { VisorConfig, CheckConfig } from '../types/config';\n\n/**\n * Utility class for merging Visor configurations with proper override semantics\n */\nexport class ConfigMerger {\n /**\n * Merge two configurations with child overriding parent\n * @param parent - Base configuration\n * @param child - Configuration to merge on top\n * @returns Merged configuration\n */\n public merge(parent: Partial<VisorConfig>, child: Partial<VisorConfig>): Partial<VisorConfig> {\n // Start with a deep copy of parent\n const result: Partial<VisorConfig> = this.deepCopy(parent);\n\n // Merge simple properties (child overrides parent)\n if (child.version !== undefined) result.version = child.version;\n if (child.ai_model !== undefined) result.ai_model = child.ai_model;\n if (child.ai_provider !== undefined) result.ai_provider = child.ai_provider;\n if (child.max_parallelism !== undefined) result.max_parallelism = child.max_parallelism;\n if (child.fail_fast !== undefined) result.fail_fast = child.fail_fast;\n if (child.fail_if !== undefined) result.fail_if = child.fail_if;\n if (child.failure_conditions !== undefined)\n result.failure_conditions = child.failure_conditions;\n\n // Merge environment variables (deep merge)\n if (child.env) {\n result.env = this.mergeObjects(parent.env || {}, child.env);\n }\n\n // Merge output configuration (deep merge)\n if (child.output) {\n result.output = this.mergeOutputConfig(parent.output, child.output);\n }\n\n // Merge checks (special handling)\n if (child.checks) {\n result.checks = this.mergeChecks(parent.checks || {}, child.checks);\n }\n\n // Merge steps as well (some configs provide only 'steps' and rely on normalization later)\n // This preserves step definitions across extends chains before normalization.\n if ((child as any).steps) {\n const parentSteps = ((parent as any).steps || {}) as Record<string, CheckConfig>;\n const childSteps = ((child as any).steps || {}) as Record<string, CheckConfig>;\n (result as any).steps = this.mergeChecks(parentSteps, childSteps);\n }\n\n // Merge custom tools\n if (child.tools) {\n result.tools = this.mergeObjects(parent.tools || {}, child.tools);\n }\n\n // Merge workflow imports (concatenate arrays)\n if (child.imports) {\n const parentImports = parent.imports || [];\n const childImports = child.imports || [];\n // Combine and deduplicate\n result.imports = [...new Set([...parentImports, ...childImports])];\n }\n\n // Note: extends/include should not be in the final merged config\n // They are only used during the loading process\n\n return result;\n }\n\n /**\n * Deep copy an object\n */\n private deepCopy<T>(obj: T): T {\n if (obj === null || obj === undefined) {\n return obj;\n }\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n if (obj instanceof Array) {\n const copy: unknown[] = [];\n for (const item of obj) {\n copy.push(this.deepCopy(item));\n }\n return copy as unknown as T;\n }\n if (obj instanceof Object) {\n const copy = {} as Record<string, unknown>;\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n copy[key] = this.deepCopy((obj as any)[key]);\n }\n }\n return copy as T;\n }\n return obj;\n }\n\n /**\n * Merge two objects (child overrides parent)\n */\n private mergeObjects<T extends Record<string, any>>(parent: T, child: T): T {\n const result: any = { ...parent };\n\n for (const key in child) {\n if (Object.prototype.hasOwnProperty.call(child, key)) {\n const parentValue = parent[key];\n const childValue = child[key];\n\n if (childValue === null || childValue === undefined) {\n // null/undefined in child removes the key\n delete result[key];\n } else if (\n typeof parentValue === 'object' &&\n typeof childValue === 'object' &&\n !Array.isArray(parentValue) &&\n !Array.isArray(childValue) &&\n parentValue !== null &&\n childValue !== null\n ) {\n // Deep merge objects\n result[key] = this.mergeObjects(\n parentValue as Record<string, any>,\n childValue as Record<string, any>\n );\n } else {\n // Child overrides parent (including arrays)\n result[key] = this.deepCopy(childValue);\n }\n }\n }\n\n return result;\n }\n\n /**\n * Merge output configurations\n */\n private mergeOutputConfig(\n parent?: Partial<VisorConfig>['output'],\n child?: Partial<VisorConfig>['output']\n ): Partial<VisorConfig>['output'] {\n if (!child) return parent;\n if (!parent) return child;\n\n const result: any = this.deepCopy(parent);\n\n // Merge pr_comment\n if (child.pr_comment) {\n result.pr_comment = this.mergeObjects(\n (parent.pr_comment || {}) as Record<string, any>,\n child.pr_comment as Record<string, any>\n ) as any;\n }\n\n // Merge file_comment\n if (child.file_comment !== undefined) {\n if (child.file_comment === null) {\n delete result.file_comment;\n } else {\n result.file_comment = this.mergeObjects(\n (parent.file_comment || {}) as Record<string, any>,\n child.file_comment as Record<string, any>\n ) as any;\n }\n }\n\n // Merge github_checks\n if (child.github_checks !== undefined) {\n if (child.github_checks === null) {\n delete result.github_checks;\n } else {\n result.github_checks = this.mergeObjects(\n (parent.github_checks || {}) as Record<string, any>,\n child.github_checks as Record<string, any>\n ) as any;\n }\n }\n\n return result;\n }\n\n /**\n * Merge check configurations with special handling\n */\n private mergeChecks(\n parent: Record<string, CheckConfig>,\n child: Record<string, CheckConfig>\n ): Record<string, CheckConfig> {\n const result: Record<string, CheckConfig> = {};\n\n // Start with all parent checks\n for (const [checkName, checkConfig] of Object.entries(parent)) {\n result[checkName] = this.deepCopy(checkConfig);\n }\n\n // Process child checks\n for (const [checkName, childConfig] of Object.entries(child)) {\n const parentConfig = parent[checkName];\n\n if (!parentConfig) {\n // New check - need to process appendPrompt even without parent\n const copiedConfig = this.deepCopy(childConfig);\n\n // Default to 'ai' type if not specified\n if (!copiedConfig.type) {\n copiedConfig.type = 'ai';\n }\n\n // Default 'on' to ['manual'] if not specified\n if (!copiedConfig.on) {\n copiedConfig.on = ['manual'];\n }\n\n // Handle appendPrompt for new checks (convert to prompt)\n if (copiedConfig.appendPrompt !== undefined) {\n // If there's no parent, appendPrompt becomes the prompt\n if (!copiedConfig.prompt) {\n copiedConfig.prompt = copiedConfig.appendPrompt;\n } else {\n // If both prompt and appendPrompt exist in child, append them\n copiedConfig.prompt = copiedConfig.prompt + '\\n\\n' + copiedConfig.appendPrompt;\n }\n // Remove appendPrompt from final config\n delete copiedConfig.appendPrompt;\n }\n\n result[checkName] = copiedConfig;\n } else {\n // Merge existing check\n result[checkName] = this.mergeCheckConfig(parentConfig, childConfig);\n }\n }\n\n return result;\n }\n\n /**\n * Merge individual check configurations\n */\n private mergeCheckConfig(parent: CheckConfig, child: CheckConfig): CheckConfig {\n const result: CheckConfig = this.deepCopy(parent);\n\n // Simple properties (child overrides parent)\n if (child.type !== undefined) result.type = child.type;\n\n // Default to 'ai' type if not specified in either parent or child\n if (!result.type) {\n result.type = 'ai';\n }\n if (child.prompt !== undefined) result.prompt = child.prompt;\n\n // Handle appendPrompt - append to existing prompt\n if (child.appendPrompt !== undefined) {\n if (result.prompt) {\n // Append with a newline separator if parent has a prompt\n result.prompt = result.prompt + '\\n\\n' + child.appendPrompt;\n } else {\n // If no parent prompt, appendPrompt becomes the prompt\n result.prompt = child.appendPrompt;\n }\n // Don't carry forward appendPrompt to avoid re-appending\n delete result.appendPrompt;\n }\n\n if (child.exec !== undefined) result.exec = child.exec;\n if (child.stdin !== undefined) result.stdin = child.stdin;\n if (child.url !== undefined) result.url = child.url;\n if (child.focus !== undefined) result.focus = child.focus;\n if (child.command !== undefined) result.command = child.command;\n if (child.ai_model !== undefined) result.ai_model = child.ai_model;\n if (child.ai_provider !== undefined) result.ai_provider = child.ai_provider;\n if (child.group !== undefined) result.group = child.group;\n if (child.schema !== undefined) result.schema = child.schema;\n if (child.if !== undefined) result.if = child.if;\n if (child.reuse_ai_session !== undefined) result.reuse_ai_session = child.reuse_ai_session;\n if (child.fail_if !== undefined) result.fail_if = child.fail_if;\n if (child.failure_conditions !== undefined)\n result.failure_conditions = child.failure_conditions;\n\n // Special handling for 'on' array\n if (child.on !== undefined) {\n if (Array.isArray(child.on) && child.on.length === 0) {\n // Empty array disables the check\n result.on = [];\n } else {\n // Replace parent's on array\n result.on = [...child.on];\n }\n }\n\n // Default 'on' to ['manual'] if still not specified\n if (!result.on) {\n result.on = ['manual'];\n }\n\n // Arrays that get replaced (not concatenated)\n if (child.triggers !== undefined) {\n result.triggers = child.triggers ? [...child.triggers] : undefined;\n }\n if (child.depends_on !== undefined) {\n result.depends_on = child.depends_on ? [...child.depends_on] : undefined;\n }\n\n // Deep merge objects\n if (child.env) {\n result.env = this.mergeObjects(\n (parent.env || {}) as Record<string, any>,\n child.env as Record<string, any>\n );\n }\n if (child.ai) {\n result.ai = this.mergeObjects(\n (parent.ai || {}) as Record<string, any>,\n child.ai as Record<string, any>\n );\n }\n if (child.template) {\n result.template = this.mergeObjects(\n (parent.template || {}) as Record<string, any>,\n child.template as Record<string, any>\n );\n }\n\n return result;\n }\n\n /**\n * Check if a check is disabled (has empty 'on' array)\n */\n public isCheckDisabled(check: CheckConfig): boolean {\n return Array.isArray(check.on) && check.on.length === 0;\n }\n\n /**\n * Remove disabled checks from the configuration\n */\n public removeDisabledChecks(config: Partial<VisorConfig>): Partial<VisorConfig> {\n if (!config.checks) return config;\n\n const result = this.deepCopy(config);\n const enabledChecks: Record<string, CheckConfig> = {};\n\n for (const [checkName, checkConfig] of Object.entries(result.checks!)) {\n if (!this.isCheckDisabled(checkConfig)) {\n enabledChecks[checkName] = checkConfig;\n } else {\n console.log(`ℹ️ Check '${checkName}' is disabled (empty 'on' array)`);\n }\n }\n\n result.checks = enabledChecks;\n return result;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
import {
|
|
2
|
+
init_logger,
|
|
3
|
+
logger
|
|
4
|
+
} from "./chunk-AGIZJ4UZ.mjs";
|
|
5
|
+
import {
|
|
6
|
+
__esm
|
|
7
|
+
} from "./chunk-WMJKH4XE.mjs";
|
|
8
|
+
|
|
9
|
+
// src/dependency-resolver.ts
|
|
10
|
+
var DependencyResolver;
|
|
11
|
+
var init_dependency_resolver = __esm({
|
|
12
|
+
"src/dependency-resolver.ts"() {
|
|
13
|
+
"use strict";
|
|
14
|
+
DependencyResolver = class {
|
|
15
|
+
/**
|
|
16
|
+
* Build dependency graph from check dependencies
|
|
17
|
+
*/
|
|
18
|
+
static buildDependencyGraph(checkDependencies) {
|
|
19
|
+
const nodes = /* @__PURE__ */ new Map();
|
|
20
|
+
for (const checkId of Object.keys(checkDependencies)) {
|
|
21
|
+
nodes.set(checkId, {
|
|
22
|
+
id: checkId,
|
|
23
|
+
dependencies: checkDependencies[checkId] || [],
|
|
24
|
+
dependents: [],
|
|
25
|
+
depth: 0
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
for (const [checkId, dependencies] of Object.entries(checkDependencies)) {
|
|
29
|
+
for (const depId of dependencies || []) {
|
|
30
|
+
if (!nodes.has(depId)) {
|
|
31
|
+
throw new Error(`Check "${checkId}" depends on "${depId}" but "${depId}" is not defined`);
|
|
32
|
+
}
|
|
33
|
+
const depNode = nodes.get(depId);
|
|
34
|
+
depNode.dependents.push(checkId);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const cycleDetection = this.detectCycles(nodes);
|
|
38
|
+
if (cycleDetection.hasCycles) {
|
|
39
|
+
return {
|
|
40
|
+
nodes,
|
|
41
|
+
executionOrder: [],
|
|
42
|
+
hasCycles: true,
|
|
43
|
+
cycleNodes: cycleDetection.cycleNodes
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const executionOrder = this.topologicalSort(nodes);
|
|
47
|
+
return {
|
|
48
|
+
nodes,
|
|
49
|
+
executionOrder,
|
|
50
|
+
hasCycles: false
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Detect cycles in the dependency graph using DFS
|
|
55
|
+
*/
|
|
56
|
+
static detectCycles(nodes) {
|
|
57
|
+
const visited = /* @__PURE__ */ new Set();
|
|
58
|
+
const recursionStack = /* @__PURE__ */ new Set();
|
|
59
|
+
const cycleNodes = [];
|
|
60
|
+
const dfs = (nodeId) => {
|
|
61
|
+
if (recursionStack.has(nodeId)) {
|
|
62
|
+
cycleNodes.push(nodeId);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
if (visited.has(nodeId)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
visited.add(nodeId);
|
|
69
|
+
recursionStack.add(nodeId);
|
|
70
|
+
const node = nodes.get(nodeId);
|
|
71
|
+
if (node) {
|
|
72
|
+
for (const depId of node.dependencies) {
|
|
73
|
+
if (dfs(depId)) {
|
|
74
|
+
cycleNodes.push(nodeId);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
recursionStack.delete(nodeId);
|
|
80
|
+
return false;
|
|
81
|
+
};
|
|
82
|
+
for (const nodeId of nodes.keys()) {
|
|
83
|
+
if (!visited.has(nodeId)) {
|
|
84
|
+
if (dfs(nodeId)) {
|
|
85
|
+
return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return { hasCycles: false };
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Perform topological sort to determine execution order
|
|
93
|
+
* Groups checks that can run in parallel at each level
|
|
94
|
+
*/
|
|
95
|
+
static topologicalSort(nodes) {
|
|
96
|
+
const remainingNodes = new Map(nodes);
|
|
97
|
+
const executionGroups = [];
|
|
98
|
+
let level = 0;
|
|
99
|
+
while (remainingNodes.size > 0) {
|
|
100
|
+
const readyNodes = [];
|
|
101
|
+
for (const [nodeId, node] of remainingNodes.entries()) {
|
|
102
|
+
const unmetDependencies = node.dependencies.filter((depId) => remainingNodes.has(depId));
|
|
103
|
+
if (unmetDependencies.length === 0) {
|
|
104
|
+
readyNodes.push(nodeId);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (readyNodes.length === 0) {
|
|
108
|
+
throw new Error("Unable to resolve dependencies - possible circular dependency detected");
|
|
109
|
+
}
|
|
110
|
+
executionGroups.push({
|
|
111
|
+
parallel: readyNodes,
|
|
112
|
+
level
|
|
113
|
+
});
|
|
114
|
+
for (const nodeId of readyNodes) {
|
|
115
|
+
remainingNodes.delete(nodeId);
|
|
116
|
+
}
|
|
117
|
+
level++;
|
|
118
|
+
}
|
|
119
|
+
return executionGroups;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Validate that all dependencies exist
|
|
123
|
+
*/
|
|
124
|
+
static validateDependencies(checkIds, dependencies) {
|
|
125
|
+
const errors = [];
|
|
126
|
+
const checkIdSet = new Set(checkIds);
|
|
127
|
+
for (const [checkId, deps] of Object.entries(dependencies)) {
|
|
128
|
+
if (!checkIdSet.has(checkId)) {
|
|
129
|
+
errors.push(`Check "${checkId}" is not in the list of available checks`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
for (const depId of deps || []) {
|
|
133
|
+
if (!checkIdSet.has(depId)) {
|
|
134
|
+
errors.push(`Check "${checkId}" depends on "${depId}" which is not available`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
valid: errors.length === 0,
|
|
140
|
+
errors
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get all transitive dependencies (ancestors) for a given check
|
|
145
|
+
* This returns all checks that must complete before the given check can run,
|
|
146
|
+
* not just the direct dependencies.
|
|
147
|
+
*
|
|
148
|
+
* For example, if A -> B -> C, then:
|
|
149
|
+
* - getAllDependencies(C) returns [A, B]
|
|
150
|
+
* - getAllDependencies(B) returns [A]
|
|
151
|
+
* - getAllDependencies(A) returns []
|
|
152
|
+
*
|
|
153
|
+
* @param checkId The check to find dependencies for
|
|
154
|
+
* @param nodes The dependency graph nodes
|
|
155
|
+
* @returns Array of all transitive dependency IDs
|
|
156
|
+
*/
|
|
157
|
+
static getAllDependencies(checkId, nodes) {
|
|
158
|
+
const allDeps = /* @__PURE__ */ new Set();
|
|
159
|
+
const visited = /* @__PURE__ */ new Set();
|
|
160
|
+
const collectDependencies = (currentId) => {
|
|
161
|
+
if (visited.has(currentId)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
visited.add(currentId);
|
|
165
|
+
const node = nodes.get(currentId);
|
|
166
|
+
if (!node) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
for (const depId of node.dependencies) {
|
|
170
|
+
allDeps.add(depId);
|
|
171
|
+
collectDependencies(depId);
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
collectDependencies(checkId);
|
|
175
|
+
return Array.from(allDeps);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get execution statistics for debugging
|
|
179
|
+
*/
|
|
180
|
+
static getExecutionStats(graph) {
|
|
181
|
+
const totalChecks = graph.nodes.size;
|
|
182
|
+
const parallelLevels = graph.executionOrder.length;
|
|
183
|
+
const maxParallelism = Math.max(...graph.executionOrder.map((group) => group.parallel.length));
|
|
184
|
+
const averageParallelism = totalChecks / parallelLevels;
|
|
185
|
+
const checksWithDependencies = Array.from(graph.nodes.values()).filter(
|
|
186
|
+
(node) => node.dependencies.length > 0
|
|
187
|
+
).length;
|
|
188
|
+
return {
|
|
189
|
+
totalChecks,
|
|
190
|
+
parallelLevels,
|
|
191
|
+
maxParallelism,
|
|
192
|
+
averageParallelism,
|
|
193
|
+
checksWithDependencies
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// src/workflow-registry.ts
|
|
201
|
+
import { promises as fs } from "fs";
|
|
202
|
+
import * as path from "path";
|
|
203
|
+
import * as yaml from "js-yaml";
|
|
204
|
+
import Ajv from "ajv";
|
|
205
|
+
import addFormats from "ajv-formats";
|
|
206
|
+
var WorkflowRegistry;
|
|
207
|
+
var init_workflow_registry = __esm({
|
|
208
|
+
"src/workflow-registry.ts"() {
|
|
209
|
+
init_logger();
|
|
210
|
+
init_dependency_resolver();
|
|
211
|
+
WorkflowRegistry = class _WorkflowRegistry {
|
|
212
|
+
static instance;
|
|
213
|
+
workflows = /* @__PURE__ */ new Map();
|
|
214
|
+
ajv;
|
|
215
|
+
constructor() {
|
|
216
|
+
this.ajv = new Ajv({ allErrors: true, strict: false });
|
|
217
|
+
addFormats(this.ajv);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get the singleton instance of the workflow registry
|
|
221
|
+
*/
|
|
222
|
+
static getInstance() {
|
|
223
|
+
if (!_WorkflowRegistry.instance) {
|
|
224
|
+
_WorkflowRegistry.instance = new _WorkflowRegistry();
|
|
225
|
+
}
|
|
226
|
+
return _WorkflowRegistry.instance;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Register a workflow definition
|
|
230
|
+
*/
|
|
231
|
+
register(workflow, source = "inline", options) {
|
|
232
|
+
const validation = this.validateWorkflow(workflow);
|
|
233
|
+
if (!validation.valid) {
|
|
234
|
+
return validation;
|
|
235
|
+
}
|
|
236
|
+
if (this.workflows.has(workflow.id) && !options?.override) {
|
|
237
|
+
return {
|
|
238
|
+
valid: false,
|
|
239
|
+
errors: [
|
|
240
|
+
{
|
|
241
|
+
path: "id",
|
|
242
|
+
message: `Workflow with ID '${workflow.id}' already exists`,
|
|
243
|
+
value: workflow.id
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
this.workflows.set(workflow.id, {
|
|
249
|
+
definition: workflow,
|
|
250
|
+
source,
|
|
251
|
+
registeredAt: /* @__PURE__ */ new Date(),
|
|
252
|
+
usage: {
|
|
253
|
+
count: 0
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
logger.debug(`Registered workflow '${workflow.id}' from ${source}`);
|
|
257
|
+
return { valid: true };
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Get a workflow by ID
|
|
261
|
+
*/
|
|
262
|
+
get(id) {
|
|
263
|
+
const entry = this.workflows.get(id);
|
|
264
|
+
if (entry) {
|
|
265
|
+
entry.usage = entry.usage || { count: 0 };
|
|
266
|
+
entry.usage.count++;
|
|
267
|
+
entry.usage.lastUsed = /* @__PURE__ */ new Date();
|
|
268
|
+
}
|
|
269
|
+
return entry?.definition;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Check if a workflow exists
|
|
273
|
+
*/
|
|
274
|
+
has(id) {
|
|
275
|
+
return this.workflows.has(id);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* List all registered workflows
|
|
279
|
+
*/
|
|
280
|
+
list() {
|
|
281
|
+
return Array.from(this.workflows.values()).map((entry) => entry.definition);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Get workflow metadata
|
|
285
|
+
*/
|
|
286
|
+
getMetadata(id) {
|
|
287
|
+
return this.workflows.get(id);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Remove a workflow from the registry
|
|
291
|
+
*/
|
|
292
|
+
unregister(id) {
|
|
293
|
+
return this.workflows.delete(id);
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Clear all workflows
|
|
297
|
+
*/
|
|
298
|
+
clear() {
|
|
299
|
+
this.workflows.clear();
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Import workflows from a file or URL
|
|
303
|
+
*/
|
|
304
|
+
async import(source, options) {
|
|
305
|
+
const results = [];
|
|
306
|
+
try {
|
|
307
|
+
const content = await this.loadWorkflowContent(source, options?.basePath);
|
|
308
|
+
const data = this.parseWorkflowContent(content, source);
|
|
309
|
+
const workflows = Array.isArray(data) ? data : [data];
|
|
310
|
+
for (const workflow of workflows) {
|
|
311
|
+
if (options?.validate !== false) {
|
|
312
|
+
const validation = this.validateWorkflow(workflow);
|
|
313
|
+
if (!validation.valid) {
|
|
314
|
+
results.push(validation);
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
if (options?.validators) {
|
|
318
|
+
for (const validator of options.validators) {
|
|
319
|
+
const customValidation = validator(workflow);
|
|
320
|
+
if (!customValidation.valid) {
|
|
321
|
+
results.push(customValidation);
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
const workflowWithoutTests = { ...workflow };
|
|
328
|
+
delete workflowWithoutTests.tests;
|
|
329
|
+
const result = this.register(workflowWithoutTests, source, { override: options?.override });
|
|
330
|
+
results.push(result);
|
|
331
|
+
}
|
|
332
|
+
} catch (error) {
|
|
333
|
+
results.push({
|
|
334
|
+
valid: false,
|
|
335
|
+
errors: [
|
|
336
|
+
{
|
|
337
|
+
path: "source",
|
|
338
|
+
message: `Failed to import workflows from '${source}': ${error instanceof Error ? error.message : String(error)}`,
|
|
339
|
+
value: source
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
return results;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Import multiple workflow sources
|
|
348
|
+
*/
|
|
349
|
+
async importMany(sources, options) {
|
|
350
|
+
const results = /* @__PURE__ */ new Map();
|
|
351
|
+
for (const source of sources) {
|
|
352
|
+
const importResults = await this.import(source, options);
|
|
353
|
+
results.set(source, importResults);
|
|
354
|
+
}
|
|
355
|
+
return results;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Validate a workflow definition
|
|
359
|
+
*/
|
|
360
|
+
validateWorkflow(workflow) {
|
|
361
|
+
const errors = [];
|
|
362
|
+
const warnings = [];
|
|
363
|
+
if (!workflow.id) {
|
|
364
|
+
errors.push({ path: "id", message: "Workflow ID is required" });
|
|
365
|
+
}
|
|
366
|
+
if (!workflow.name) {
|
|
367
|
+
errors.push({ path: "name", message: "Workflow name is required" });
|
|
368
|
+
}
|
|
369
|
+
if (!workflow.steps || Object.keys(workflow.steps).length === 0) {
|
|
370
|
+
errors.push({ path: "steps", message: "Workflow must have at least one step" });
|
|
371
|
+
}
|
|
372
|
+
if (workflow.inputs) {
|
|
373
|
+
for (let i = 0; i < workflow.inputs.length; i++) {
|
|
374
|
+
const input = workflow.inputs[i];
|
|
375
|
+
if (!input.name) {
|
|
376
|
+
errors.push({ path: `inputs[${i}].name`, message: "Input parameter name is required" });
|
|
377
|
+
}
|
|
378
|
+
if (!input.schema) {
|
|
379
|
+
warnings.push({
|
|
380
|
+
path: `inputs[${i}].schema`,
|
|
381
|
+
message: "Input parameter schema is recommended"
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (workflow.outputs) {
|
|
387
|
+
for (let i = 0; i < workflow.outputs.length; i++) {
|
|
388
|
+
const output = workflow.outputs[i];
|
|
389
|
+
if (!output.name) {
|
|
390
|
+
errors.push({ path: `outputs[${i}].name`, message: "Output parameter name is required" });
|
|
391
|
+
}
|
|
392
|
+
if (!output.value && !output.value_js) {
|
|
393
|
+
errors.push({
|
|
394
|
+
path: `outputs[${i}]`,
|
|
395
|
+
message: "Output parameter must have either value or value_js"
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
for (const [stepId, step] of Object.entries(workflow.steps || {})) {
|
|
401
|
+
if (step.depends_on) {
|
|
402
|
+
for (const dep of step.depends_on) {
|
|
403
|
+
if (!workflow.steps[dep]) {
|
|
404
|
+
errors.push({
|
|
405
|
+
path: `steps.${stepId}.depends_on`,
|
|
406
|
+
message: `Step '${stepId}' depends on non-existent step '${dep}'`,
|
|
407
|
+
value: dep
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (step.inputs) {
|
|
413
|
+
for (const [inputName, mapping] of Object.entries(step.inputs)) {
|
|
414
|
+
if (typeof mapping === "object" && mapping !== null && "source" in mapping) {
|
|
415
|
+
const typedMapping = mapping;
|
|
416
|
+
if (typedMapping.source === "step" && !typedMapping.stepId) {
|
|
417
|
+
errors.push({
|
|
418
|
+
path: `steps.${stepId}.inputs.${inputName}`,
|
|
419
|
+
message: 'Step input mapping with source "step" must have stepId'
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
if (typedMapping.source === "param") {
|
|
423
|
+
const paramExists = workflow.inputs?.some((p) => p.name === typedMapping.value);
|
|
424
|
+
if (!paramExists) {
|
|
425
|
+
errors.push({
|
|
426
|
+
path: `steps.${stepId}.inputs.${inputName}`,
|
|
427
|
+
message: `Step input references non-existent parameter '${typedMapping.value}'`,
|
|
428
|
+
value: typedMapping.value
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
const circularDeps = this.detectCircularDependencies(workflow);
|
|
437
|
+
if (circularDeps.length > 0) {
|
|
438
|
+
errors.push({
|
|
439
|
+
path: "steps",
|
|
440
|
+
message: `Circular dependencies detected: ${circularDeps.join(" -> ")}`
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
return {
|
|
444
|
+
valid: errors.length === 0,
|
|
445
|
+
errors: errors.length > 0 ? errors : void 0,
|
|
446
|
+
warnings: warnings.length > 0 ? warnings : void 0
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Validate input values against workflow input schema
|
|
451
|
+
*/
|
|
452
|
+
validateInputs(workflow, inputs) {
|
|
453
|
+
const errors = [];
|
|
454
|
+
if (!workflow.inputs) {
|
|
455
|
+
return { valid: true };
|
|
456
|
+
}
|
|
457
|
+
for (const param of workflow.inputs) {
|
|
458
|
+
if (param.required !== false && !(param.name in inputs) && param.default === void 0) {
|
|
459
|
+
errors.push({
|
|
460
|
+
path: `inputs.${param.name}`,
|
|
461
|
+
message: `Required input '${param.name}' is missing`
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
for (const param of workflow.inputs) {
|
|
466
|
+
if (param.name in inputs && param.schema) {
|
|
467
|
+
const value = inputs[param.name];
|
|
468
|
+
const valid = this.validateAgainstSchema(value, param.schema);
|
|
469
|
+
if (!valid.valid) {
|
|
470
|
+
errors.push({
|
|
471
|
+
path: `inputs.${param.name}`,
|
|
472
|
+
message: valid.error || "Invalid input value",
|
|
473
|
+
value
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
valid: errors.length === 0,
|
|
480
|
+
errors: errors.length > 0 ? errors : void 0
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Load workflow content from file or URL
|
|
485
|
+
*/
|
|
486
|
+
async loadWorkflowContent(source, basePath) {
|
|
487
|
+
if (source.startsWith("http://") || source.startsWith("https://")) {
|
|
488
|
+
const response = await fetch(source);
|
|
489
|
+
if (!response.ok) {
|
|
490
|
+
throw new Error(`Failed to fetch workflow from ${source}: ${response.statusText}`);
|
|
491
|
+
}
|
|
492
|
+
return await response.text();
|
|
493
|
+
}
|
|
494
|
+
const filePath = path.isAbsolute(source) ? source : path.resolve(basePath || process.cwd(), source);
|
|
495
|
+
return await fs.readFile(filePath, "utf-8");
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Parse workflow content (YAML or JSON)
|
|
499
|
+
*/
|
|
500
|
+
parseWorkflowContent(content, source) {
|
|
501
|
+
try {
|
|
502
|
+
return JSON.parse(content);
|
|
503
|
+
} catch {
|
|
504
|
+
try {
|
|
505
|
+
return yaml.load(content);
|
|
506
|
+
} catch (error) {
|
|
507
|
+
throw new Error(
|
|
508
|
+
`Failed to parse workflow file ${source}: ${error instanceof Error ? error.message : String(error)}`
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Detect circular dependencies in workflow steps using DependencyResolver
|
|
515
|
+
*/
|
|
516
|
+
detectCircularDependencies(workflow) {
|
|
517
|
+
const dependencies = {};
|
|
518
|
+
for (const [stepId, step] of Object.entries(workflow.steps || {})) {
|
|
519
|
+
const rawDeps = step.depends_on;
|
|
520
|
+
dependencies[stepId] = Array.isArray(rawDeps) ? rawDeps : rawDeps ? [rawDeps] : [];
|
|
521
|
+
}
|
|
522
|
+
try {
|
|
523
|
+
const graph = DependencyResolver.buildDependencyGraph(dependencies);
|
|
524
|
+
if (graph.hasCycles && graph.cycleNodes) {
|
|
525
|
+
return graph.cycleNodes;
|
|
526
|
+
}
|
|
527
|
+
return [];
|
|
528
|
+
} catch {
|
|
529
|
+
return [];
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Validate a value against a JSON schema
|
|
534
|
+
*/
|
|
535
|
+
validateAgainstSchema(value, schema) {
|
|
536
|
+
try {
|
|
537
|
+
const validate = this.ajv.compile(schema);
|
|
538
|
+
const valid = validate(value);
|
|
539
|
+
if (!valid) {
|
|
540
|
+
const errors = validate.errors?.map((e) => `${e.instancePath || "/"}: ${e.message}`).join(", ");
|
|
541
|
+
return { valid: false, error: errors };
|
|
542
|
+
}
|
|
543
|
+
return { valid: true };
|
|
544
|
+
} catch (error) {
|
|
545
|
+
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
export {
|
|
553
|
+
DependencyResolver,
|
|
554
|
+
init_dependency_resolver,
|
|
555
|
+
WorkflowRegistry,
|
|
556
|
+
init_workflow_registry
|
|
557
|
+
};
|
|
558
|
+
//# sourceMappingURL=chunk-QR7MOMJH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/dependency-resolver.ts","../../src/workflow-registry.ts"],"sourcesContent":["/**\n * Dependency resolution and execution ordering for checks\n */\n\nexport interface CheckNode {\n id: string;\n dependencies: string[];\n dependents: string[];\n depth: number;\n}\n\nexport interface ExecutionGroup {\n /** Checks that can run in parallel */\n parallel: string[];\n /** Execution level/wave (0 = no dependencies, 1 = depends on level 0, etc.) */\n level: number;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, CheckNode>;\n executionOrder: ExecutionGroup[];\n hasCycles: boolean;\n cycleNodes?: string[];\n}\n\nexport class DependencyResolver {\n /**\n * Build dependency graph from check dependencies\n */\n static buildDependencyGraph(checkDependencies: Record<string, string[]>): DependencyGraph {\n const nodes = new Map<string, CheckNode>();\n\n // Initialize all nodes\n for (const checkId of Object.keys(checkDependencies)) {\n nodes.set(checkId, {\n id: checkId,\n dependencies: checkDependencies[checkId] || [],\n dependents: [],\n depth: 0,\n });\n }\n\n // Build bidirectional relationships\n for (const [checkId, dependencies] of Object.entries(checkDependencies)) {\n for (const depId of dependencies || []) {\n if (!nodes.has(depId)) {\n throw new Error(`Check \"${checkId}\" depends on \"${depId}\" but \"${depId}\" is not defined`);\n }\n\n const depNode = nodes.get(depId)!;\n depNode.dependents.push(checkId);\n }\n }\n\n // Detect cycles using DFS\n const cycleDetection = this.detectCycles(nodes);\n if (cycleDetection.hasCycles) {\n return {\n nodes,\n executionOrder: [],\n hasCycles: true,\n cycleNodes: cycleDetection.cycleNodes,\n };\n }\n\n // Calculate execution order using topological sort\n const executionOrder = this.topologicalSort(nodes);\n\n return {\n nodes,\n executionOrder,\n hasCycles: false,\n };\n }\n\n /**\n * Detect cycles in the dependency graph using DFS\n */\n private static detectCycles(nodes: Map<string, CheckNode>): {\n hasCycles: boolean;\n cycleNodes?: string[];\n } {\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cycleNodes: string[] = [];\n\n const dfs = (nodeId: string): boolean => {\n if (recursionStack.has(nodeId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n if (visited.has(nodeId)) {\n return false;\n }\n\n visited.add(nodeId);\n recursionStack.add(nodeId);\n\n const node = nodes.get(nodeId);\n if (node) {\n for (const depId of node.dependencies) {\n if (dfs(depId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n }\n }\n\n recursionStack.delete(nodeId);\n return false;\n };\n\n for (const nodeId of nodes.keys()) {\n if (!visited.has(nodeId)) {\n if (dfs(nodeId)) {\n return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };\n }\n }\n }\n\n return { hasCycles: false };\n }\n\n /**\n * Perform topological sort to determine execution order\n * Groups checks that can run in parallel at each level\n */\n private static topologicalSort(nodes: Map<string, CheckNode>): ExecutionGroup[] {\n const remainingNodes = new Map(nodes);\n const executionGroups: ExecutionGroup[] = [];\n let level = 0;\n\n while (remainingNodes.size > 0) {\n // Find nodes with no remaining dependencies\n const readyNodes: string[] = [];\n\n for (const [nodeId, node] of remainingNodes.entries()) {\n const unmetDependencies = node.dependencies.filter(depId => remainingNodes.has(depId));\n if (unmetDependencies.length === 0) {\n readyNodes.push(nodeId);\n }\n }\n\n if (readyNodes.length === 0) {\n // This shouldn't happen if cycle detection worked correctly\n throw new Error('Unable to resolve dependencies - possible circular dependency detected');\n }\n\n // Add this group to execution order\n executionGroups.push({\n parallel: readyNodes,\n level,\n });\n\n // Remove processed nodes\n for (const nodeId of readyNodes) {\n remainingNodes.delete(nodeId);\n }\n\n level++;\n }\n\n return executionGroups;\n }\n\n /**\n * Validate that all dependencies exist\n */\n static validateDependencies(\n checkIds: string[],\n dependencies: Record<string, string[]>\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const checkIdSet = new Set(checkIds);\n\n for (const [checkId, deps] of Object.entries(dependencies)) {\n if (!checkIdSet.has(checkId)) {\n errors.push(`Check \"${checkId}\" is not in the list of available checks`);\n continue;\n }\n\n for (const depId of deps || []) {\n if (!checkIdSet.has(depId)) {\n errors.push(`Check \"${checkId}\" depends on \"${depId}\" which is not available`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get all transitive dependencies (ancestors) for a given check\n * This returns all checks that must complete before the given check can run,\n * not just the direct dependencies.\n *\n * For example, if A -> B -> C, then:\n * - getAllDependencies(C) returns [A, B]\n * - getAllDependencies(B) returns [A]\n * - getAllDependencies(A) returns []\n *\n * @param checkId The check to find dependencies for\n * @param nodes The dependency graph nodes\n * @returns Array of all transitive dependency IDs\n */\n static getAllDependencies(checkId: string, nodes: Map<string, CheckNode>): string[] {\n const allDeps = new Set<string>();\n const visited = new Set<string>();\n\n const collectDependencies = (currentId: string) => {\n if (visited.has(currentId)) {\n return;\n }\n visited.add(currentId);\n\n const node = nodes.get(currentId);\n if (!node) {\n return;\n }\n\n // Add direct dependencies and recurse\n for (const depId of node.dependencies) {\n allDeps.add(depId);\n collectDependencies(depId);\n }\n };\n\n collectDependencies(checkId);\n return Array.from(allDeps);\n }\n\n /**\n * Get execution statistics for debugging\n */\n static getExecutionStats(graph: DependencyGraph): {\n totalChecks: number;\n parallelLevels: number;\n maxParallelism: number;\n averageParallelism: number;\n checksWithDependencies: number;\n } {\n const totalChecks = graph.nodes.size;\n const parallelLevels = graph.executionOrder.length;\n const maxParallelism = Math.max(...graph.executionOrder.map(group => group.parallel.length));\n const averageParallelism = totalChecks / parallelLevels;\n const checksWithDependencies = Array.from(graph.nodes.values()).filter(\n node => node.dependencies.length > 0\n ).length;\n\n return {\n totalChecks,\n parallelLevels,\n maxParallelism,\n averageParallelism,\n checksWithDependencies,\n };\n }\n}\n","/**\n * Workflow registry for managing reusable workflow definitions\n */\n\nimport {\n WorkflowDefinition,\n WorkflowRegistryEntry,\n WorkflowValidationResult,\n WorkflowImportOptions,\n JsonSchema,\n} from './types/workflow';\nimport { promises as fs } from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { logger } from './logger';\nimport { DependencyResolver } from './dependency-resolver';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\n\n/**\n * Registry for managing workflow definitions\n */\nexport class WorkflowRegistry {\n private static instance: WorkflowRegistry;\n private workflows: Map<string, WorkflowRegistryEntry> = new Map();\n private ajv: Ajv;\n\n private constructor() {\n this.ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(this.ajv);\n }\n\n /**\n * Get the singleton instance of the workflow registry\n */\n public static getInstance(): WorkflowRegistry {\n if (!WorkflowRegistry.instance) {\n WorkflowRegistry.instance = new WorkflowRegistry();\n }\n return WorkflowRegistry.instance;\n }\n\n /**\n * Register a workflow definition\n */\n public register(\n workflow: WorkflowDefinition,\n source: string = 'inline',\n options?: { override?: boolean }\n ): WorkflowValidationResult {\n // Validate the workflow\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n return validation;\n }\n\n // Check if workflow already exists\n if (this.workflows.has(workflow.id) && !options?.override) {\n return {\n valid: false,\n errors: [\n {\n path: 'id',\n message: `Workflow with ID '${workflow.id}' already exists`,\n value: workflow.id,\n },\n ],\n };\n }\n\n // Register the workflow\n this.workflows.set(workflow.id, {\n definition: workflow,\n source,\n registeredAt: new Date(),\n usage: {\n count: 0,\n },\n });\n\n logger.debug(`Registered workflow '${workflow.id}' from ${source}`);\n return { valid: true };\n }\n\n /**\n * Get a workflow by ID\n */\n public get(id: string): WorkflowDefinition | undefined {\n const entry = this.workflows.get(id);\n if (entry) {\n // Update usage statistics\n entry.usage = entry.usage || { count: 0 };\n entry.usage.count++;\n entry.usage.lastUsed = new Date();\n }\n return entry?.definition;\n }\n\n /**\n * Check if a workflow exists\n */\n public has(id: string): boolean {\n return this.workflows.has(id);\n }\n\n /**\n * List all registered workflows\n */\n public list(): WorkflowDefinition[] {\n return Array.from(this.workflows.values()).map(entry => entry.definition);\n }\n\n /**\n * Get workflow metadata\n */\n public getMetadata(id: string): WorkflowRegistryEntry | undefined {\n return this.workflows.get(id);\n }\n\n /**\n * Remove a workflow from the registry\n */\n public unregister(id: string): boolean {\n return this.workflows.delete(id);\n }\n\n /**\n * Clear all workflows\n */\n public clear(): void {\n this.workflows.clear();\n }\n\n /**\n * Import workflows from a file or URL\n */\n public async import(\n source: string,\n options?: WorkflowImportOptions\n ): Promise<WorkflowValidationResult[]> {\n const results: WorkflowValidationResult[] = [];\n\n try {\n // Load the workflow file\n const content = await this.loadWorkflowContent(source, options?.basePath);\n const data = this.parseWorkflowContent(content, source);\n\n // Handle both single workflow and multiple workflows\n const workflows: WorkflowDefinition[] = Array.isArray(data) ? data : [data];\n\n for (const workflow of workflows) {\n // Validate if requested\n if (options?.validate !== false) {\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n results.push(validation);\n continue;\n }\n\n // Run custom validators if provided\n if (options?.validators) {\n for (const validator of options.validators) {\n const customValidation = validator(workflow);\n if (!customValidation.valid) {\n results.push(customValidation);\n continue;\n }\n }\n }\n }\n\n // Strip out 'tests' field before registering - tests are only for standalone execution\n const workflowWithoutTests = { ...workflow };\n delete (workflowWithoutTests as any).tests;\n\n // Register the workflow (without tests)\n const result = this.register(workflowWithoutTests, source, { override: options?.override });\n results.push(result);\n }\n } catch (error) {\n results.push({\n valid: false,\n errors: [\n {\n path: 'source',\n message: `Failed to import workflows from '${source}': ${error instanceof Error ? error.message : String(error)}`,\n value: source,\n },\n ],\n });\n }\n\n return results;\n }\n\n /**\n * Import multiple workflow sources\n */\n public async importMany(\n sources: string[],\n options?: WorkflowImportOptions\n ): Promise<Map<string, WorkflowValidationResult[]>> {\n const results = new Map<string, WorkflowValidationResult[]>();\n\n for (const source of sources) {\n const importResults = await this.import(source, options);\n results.set(source, importResults);\n }\n\n return results;\n }\n\n /**\n * Validate a workflow definition\n */\n public validateWorkflow(workflow: WorkflowDefinition): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n const warnings: Array<{ path: string; message: string }> = [];\n\n // Validate required fields\n if (!workflow.id) {\n errors.push({ path: 'id', message: 'Workflow ID is required' });\n }\n\n if (!workflow.name) {\n errors.push({ path: 'name', message: 'Workflow name is required' });\n }\n\n if (!workflow.steps || Object.keys(workflow.steps).length === 0) {\n errors.push({ path: 'steps', message: 'Workflow must have at least one step' });\n }\n\n // Validate input parameters\n if (workflow.inputs) {\n for (let i = 0; i < workflow.inputs.length; i++) {\n const input = workflow.inputs[i];\n if (!input.name) {\n errors.push({ path: `inputs[${i}].name`, message: 'Input parameter name is required' });\n }\n if (!input.schema) {\n warnings.push({\n path: `inputs[${i}].schema`,\n message: 'Input parameter schema is recommended',\n });\n }\n }\n }\n\n // Validate output parameters\n if (workflow.outputs) {\n for (let i = 0; i < workflow.outputs.length; i++) {\n const output = workflow.outputs[i];\n if (!output.name) {\n errors.push({ path: `outputs[${i}].name`, message: 'Output parameter name is required' });\n }\n if (!output.value && !output.value_js) {\n errors.push({\n path: `outputs[${i}]`,\n message: 'Output parameter must have either value or value_js',\n });\n }\n }\n }\n\n // Validate steps\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Validate step dependencies\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (!workflow.steps[dep]) {\n errors.push({\n path: `steps.${stepId}.depends_on`,\n message: `Step '${stepId}' depends on non-existent step '${dep}'`,\n value: dep,\n });\n }\n }\n }\n\n // Validate input mappings\n if (step.inputs) {\n for (const [inputName, mapping] of Object.entries(step.inputs)) {\n if (typeof mapping === 'object' && mapping !== null && 'source' in mapping) {\n const typedMapping = mapping as any;\n if (typedMapping.source === 'step' && !typedMapping.stepId) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: 'Step input mapping with source \"step\" must have stepId',\n });\n }\n if (typedMapping.source === 'param') {\n // Validate that the parameter exists\n const paramExists = workflow.inputs?.some(p => p.name === typedMapping.value);\n if (!paramExists) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: `Step input references non-existent parameter '${typedMapping.value}'`,\n value: typedMapping.value,\n });\n }\n }\n }\n }\n }\n }\n\n // Check for circular dependencies\n const circularDeps = this.detectCircularDependencies(workflow);\n if (circularDeps.length > 0) {\n errors.push({\n path: 'steps',\n message: `Circular dependencies detected: ${circularDeps.join(' -> ')}`,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n }\n\n /**\n * Validate input values against workflow input schema\n */\n public validateInputs(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>\n ): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n\n if (!workflow.inputs) {\n return { valid: true };\n }\n\n // Check required inputs\n for (const param of workflow.inputs) {\n if (param.required !== false && !(param.name in inputs) && param.default === undefined) {\n errors.push({\n path: `inputs.${param.name}`,\n message: `Required input '${param.name}' is missing`,\n });\n }\n }\n\n // Validate input schemas\n for (const param of workflow.inputs) {\n if (param.name in inputs && param.schema) {\n const value = inputs[param.name];\n const valid = this.validateAgainstSchema(value, param.schema);\n if (!valid.valid) {\n errors.push({\n path: `inputs.${param.name}`,\n message: valid.error || 'Invalid input value',\n value,\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n /**\n * Load workflow content from file or URL\n */\n private async loadWorkflowContent(source: string, basePath?: string): Promise<string> {\n // Handle URLs\n if (source.startsWith('http://') || source.startsWith('https://')) {\n const response = await fetch(source);\n if (!response.ok) {\n throw new Error(`Failed to fetch workflow from ${source}: ${response.statusText}`);\n }\n return await response.text();\n }\n\n // Handle file paths\n const filePath = path.isAbsolute(source)\n ? source\n : path.resolve(basePath || process.cwd(), source);\n return await fs.readFile(filePath, 'utf-8');\n }\n\n /**\n * Parse workflow content (YAML or JSON)\n */\n private parseWorkflowContent(content: string, source: string): any {\n // Try JSON first\n try {\n return JSON.parse(content);\n } catch {\n // Try YAML\n try {\n return yaml.load(content);\n } catch (error) {\n throw new Error(\n `Failed to parse workflow file ${source}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n /**\n * Detect circular dependencies in workflow steps using DependencyResolver\n */\n private detectCircularDependencies(workflow: WorkflowDefinition): string[] {\n // Build dependency map\n const dependencies: Record<string, string[]> = {};\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Normalize depends_on to array (supports string | string[])\n const rawDeps = step.depends_on;\n dependencies[stepId] = Array.isArray(rawDeps) ? rawDeps : rawDeps ? [rawDeps] : [];\n }\n\n try {\n // Use DependencyResolver to check for cycles\n const graph = DependencyResolver.buildDependencyGraph(dependencies);\n\n if (graph.hasCycles && graph.cycleNodes) {\n return graph.cycleNodes;\n }\n\n return [];\n } catch {\n // DependencyResolver throws error for non-existent dependencies\n // This should be caught by the dependency validation in validateWorkflow\n // Return empty array here and let the validation handle it\n return [];\n }\n }\n\n /**\n * Validate a value against a JSON schema\n */\n private validateAgainstSchema(\n value: unknown,\n schema: JsonSchema\n ): { valid: boolean; error?: string } {\n try {\n const validate = this.ajv.compile(schema as any);\n const valid = validate(value);\n if (!valid) {\n const errors = validate.errors\n ?.map(e => `${e.instancePath || '/'}: ${e.message}`)\n .join(', ');\n return { valid: false, error: errors };\n }\n return { valid: true };\n } catch (error) {\n return { valid: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n}\n"],"mappings":";;;;;;;;;AAAA,IAyBa;AAzBb;AAAA;AAAA;AAyBO,IAAM,qBAAN,MAAyB;AAAA;AAAA;AAAA;AAAA,MAI9B,OAAO,qBAAqB,mBAA8D;AACxF,cAAM,QAAQ,oBAAI,IAAuB;AAGzC,mBAAW,WAAW,OAAO,KAAK,iBAAiB,GAAG;AACpD,gBAAM,IAAI,SAAS;AAAA,YACjB,IAAI;AAAA,YACJ,cAAc,kBAAkB,OAAO,KAAK,CAAC;AAAA,YAC7C,YAAY,CAAC;AAAA,YACb,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAGA,mBAAW,CAAC,SAAS,YAAY,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACvE,qBAAW,SAAS,gBAAgB,CAAC,GAAG;AACtC,gBAAI,CAAC,MAAM,IAAI,KAAK,GAAG;AACrB,oBAAM,IAAI,MAAM,UAAU,OAAO,iBAAiB,KAAK,UAAU,KAAK,kBAAkB;AAAA,YAC1F;AAEA,kBAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,oBAAQ,WAAW,KAAK,OAAO;AAAA,UACjC;AAAA,QACF;AAGA,cAAM,iBAAiB,KAAK,aAAa,KAAK;AAC9C,YAAI,eAAe,WAAW;AAC5B,iBAAO;AAAA,YACL;AAAA,YACA,gBAAgB,CAAC;AAAA,YACjB,WAAW;AAAA,YACX,YAAY,eAAe;AAAA,UAC7B;AAAA,QACF;AAGA,cAAM,iBAAiB,KAAK,gBAAgB,KAAK;AAEjD,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,aAAa,OAG1B;AACA,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,iBAAiB,oBAAI,IAAY;AACvC,cAAM,aAAuB,CAAC;AAE9B,cAAM,MAAM,CAAC,WAA4B;AACvC,cAAI,eAAe,IAAI,MAAM,GAAG;AAC9B,uBAAW,KAAK,MAAM;AACtB,mBAAO;AAAA,UACT;AACA,cAAI,QAAQ,IAAI,MAAM,GAAG;AACvB,mBAAO;AAAA,UACT;AAEA,kBAAQ,IAAI,MAAM;AAClB,yBAAe,IAAI,MAAM;AAEzB,gBAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,cAAI,MAAM;AACR,uBAAW,SAAS,KAAK,cAAc;AACrC,kBAAI,IAAI,KAAK,GAAG;AACd,2BAAW,KAAK,MAAM;AACtB,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAEA,yBAAe,OAAO,MAAM;AAC5B,iBAAO;AAAA,QACT;AAEA,mBAAW,UAAU,MAAM,KAAK,GAAG;AACjC,cAAI,CAAC,QAAQ,IAAI,MAAM,GAAG;AACxB,gBAAI,IAAI,MAAM,GAAG;AACf,qBAAO,EAAE,WAAW,MAAM,YAAY,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,EAAE;AAAA,YACjE;AAAA,UACF;AAAA,QACF;AAEA,eAAO,EAAE,WAAW,MAAM;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAe,gBAAgB,OAAiD;AAC9E,cAAM,iBAAiB,IAAI,IAAI,KAAK;AACpC,cAAM,kBAAoC,CAAC;AAC3C,YAAI,QAAQ;AAEZ,eAAO,eAAe,OAAO,GAAG;AAE9B,gBAAM,aAAuB,CAAC;AAE9B,qBAAW,CAAC,QAAQ,IAAI,KAAK,eAAe,QAAQ,GAAG;AACrD,kBAAM,oBAAoB,KAAK,aAAa,OAAO,WAAS,eAAe,IAAI,KAAK,CAAC;AACrF,gBAAI,kBAAkB,WAAW,GAAG;AAClC,yBAAW,KAAK,MAAM;AAAA,YACxB;AAAA,UACF;AAEA,cAAI,WAAW,WAAW,GAAG;AAE3B,kBAAM,IAAI,MAAM,wEAAwE;AAAA,UAC1F;AAGA,0BAAgB,KAAK;AAAA,YACnB,UAAU;AAAA,YACV;AAAA,UACF,CAAC;AAGD,qBAAW,UAAU,YAAY;AAC/B,2BAAe,OAAO,MAAM;AAAA,UAC9B;AAEA;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,qBACL,UACA,cACsC;AACtC,cAAM,SAAmB,CAAC;AAC1B,cAAM,aAAa,IAAI,IAAI,QAAQ;AAEnC,mBAAW,CAAC,SAAS,IAAI,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC1D,cAAI,CAAC,WAAW,IAAI,OAAO,GAAG;AAC5B,mBAAO,KAAK,UAAU,OAAO,0CAA0C;AACvE;AAAA,UACF;AAEA,qBAAW,SAAS,QAAQ,CAAC,GAAG;AAC9B,gBAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,qBAAO,KAAK,UAAU,OAAO,iBAAiB,KAAK,0BAA0B;AAAA,YAC/E;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,OAAO,mBAAmB,SAAiB,OAAyC;AAClF,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,UAAU,oBAAI,IAAY;AAEhC,cAAM,sBAAsB,CAAC,cAAsB;AACjD,cAAI,QAAQ,IAAI,SAAS,GAAG;AAC1B;AAAA,UACF;AACA,kBAAQ,IAAI,SAAS;AAErB,gBAAM,OAAO,MAAM,IAAI,SAAS;AAChC,cAAI,CAAC,MAAM;AACT;AAAA,UACF;AAGA,qBAAW,SAAS,KAAK,cAAc;AACrC,oBAAQ,IAAI,KAAK;AACjB,gCAAoB,KAAK;AAAA,UAC3B;AAAA,QACF;AAEA,4BAAoB,OAAO;AAC3B,eAAO,MAAM,KAAK,OAAO;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,kBAAkB,OAMvB;AACA,cAAM,cAAc,MAAM,MAAM;AAChC,cAAM,iBAAiB,MAAM,eAAe;AAC5C,cAAM,iBAAiB,KAAK,IAAI,GAAG,MAAM,eAAe,IAAI,WAAS,MAAM,SAAS,MAAM,CAAC;AAC3F,cAAM,qBAAqB,cAAc;AACzC,cAAM,yBAAyB,MAAM,KAAK,MAAM,MAAM,OAAO,CAAC,EAAE;AAAA,UAC9D,UAAQ,KAAK,aAAa,SAAS;AAAA,QACrC,EAAE;AAEF,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACzPA,SAAS,YAAY,UAAU;AAC/B,YAAY,UAAU;AACtB,YAAY,UAAU;AAGtB,OAAO,SAAS;AAChB,OAAO,gBAAgB;AAjBvB,IAsBa;AAtBb;AAAA;AAcA;AACA;AAOO,IAAM,mBAAN,MAAM,kBAAiB;AAAA,MAC5B,OAAe;AAAA,MACP,YAAgD,oBAAI,IAAI;AAAA,MACxD;AAAA,MAEA,cAAc;AACpB,aAAK,MAAM,IAAI,IAAI,EAAE,WAAW,MAAM,QAAQ,MAAM,CAAC;AACrD,mBAAW,KAAK,GAAG;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAc,cAAgC;AAC5C,YAAI,CAAC,kBAAiB,UAAU;AAC9B,4BAAiB,WAAW,IAAI,kBAAiB;AAAA,QACnD;AACA,eAAO,kBAAiB;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKO,SACL,UACA,SAAiB,UACjB,SAC0B;AAE1B,cAAM,aAAa,KAAK,iBAAiB,QAAQ;AACjD,YAAI,CAAC,WAAW,OAAO;AACrB,iBAAO;AAAA,QACT;AAGA,YAAI,KAAK,UAAU,IAAI,SAAS,EAAE,KAAK,CAAC,SAAS,UAAU;AACzD,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,cACN;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,qBAAqB,SAAS,EAAE;AAAA,gBACzC,OAAO,SAAS;AAAA,cAClB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,aAAK,UAAU,IAAI,SAAS,IAAI;AAAA,UAC9B,YAAY;AAAA,UACZ;AAAA,UACA,cAAc,oBAAI,KAAK;AAAA,UACvB,OAAO;AAAA,YACL,OAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,eAAO,MAAM,wBAAwB,SAAS,EAAE,UAAU,MAAM,EAAE;AAClE,eAAO,EAAE,OAAO,KAAK;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA,MAKO,IAAI,IAA4C;AACrD,cAAM,QAAQ,KAAK,UAAU,IAAI,EAAE;AACnC,YAAI,OAAO;AAET,gBAAM,QAAQ,MAAM,SAAS,EAAE,OAAO,EAAE;AACxC,gBAAM,MAAM;AACZ,gBAAM,MAAM,WAAW,oBAAI,KAAK;AAAA,QAClC;AACA,eAAO,OAAO;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA,MAKO,IAAI,IAAqB;AAC9B,eAAO,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKO,OAA6B;AAClC,eAAO,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC,EAAE,IAAI,WAAS,MAAM,UAAU;AAAA,MAC1E;AAAA;AAAA;AAAA;AAAA,MAKO,YAAY,IAA+C;AAChE,eAAO,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKO,WAAW,IAAqB;AACrC,eAAO,KAAK,UAAU,OAAO,EAAE;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKO,QAAc;AACnB,aAAK,UAAU,MAAM;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA,MAKA,MAAa,OACX,QACA,SACqC;AACrC,cAAM,UAAsC,CAAC;AAE7C,YAAI;AAEF,gBAAM,UAAU,MAAM,KAAK,oBAAoB,QAAQ,SAAS,QAAQ;AACxE,gBAAM,OAAO,KAAK,qBAAqB,SAAS,MAAM;AAGtD,gBAAM,YAAkC,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAE1E,qBAAW,YAAY,WAAW;AAEhC,gBAAI,SAAS,aAAa,OAAO;AAC/B,oBAAM,aAAa,KAAK,iBAAiB,QAAQ;AACjD,kBAAI,CAAC,WAAW,OAAO;AACrB,wBAAQ,KAAK,UAAU;AACvB;AAAA,cACF;AAGA,kBAAI,SAAS,YAAY;AACvB,2BAAW,aAAa,QAAQ,YAAY;AAC1C,wBAAM,mBAAmB,UAAU,QAAQ;AAC3C,sBAAI,CAAC,iBAAiB,OAAO;AAC3B,4BAAQ,KAAK,gBAAgB;AAC7B;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,kBAAM,uBAAuB,EAAE,GAAG,SAAS;AAC3C,mBAAQ,qBAA6B;AAGrC,kBAAM,SAAS,KAAK,SAAS,sBAAsB,QAAQ,EAAE,UAAU,SAAS,SAAS,CAAC;AAC1F,oBAAQ,KAAK,MAAM;AAAA,UACrB;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,KAAK;AAAA,YACX,OAAO;AAAA,YACP,QAAQ;AAAA,cACN;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,oCAAoC,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,gBAC/G,OAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAa,WACX,SACA,SACkD;AAClD,cAAM,UAAU,oBAAI,IAAwC;AAE5D,mBAAW,UAAU,SAAS;AAC5B,gBAAM,gBAAgB,MAAM,KAAK,OAAO,QAAQ,OAAO;AACvD,kBAAQ,IAAI,QAAQ,aAAa;AAAA,QACnC;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKO,iBAAiB,UAAwD;AAC9E,cAAM,SAAoE,CAAC;AAC3E,cAAM,WAAqD,CAAC;AAG5D,YAAI,CAAC,SAAS,IAAI;AAChB,iBAAO,KAAK,EAAE,MAAM,MAAM,SAAS,0BAA0B,CAAC;AAAA,QAChE;AAEA,YAAI,CAAC,SAAS,MAAM;AAClB,iBAAO,KAAK,EAAE,MAAM,QAAQ,SAAS,4BAA4B,CAAC;AAAA,QACpE;AAEA,YAAI,CAAC,SAAS,SAAS,OAAO,KAAK,SAAS,KAAK,EAAE,WAAW,GAAG;AAC/D,iBAAO,KAAK,EAAE,MAAM,SAAS,SAAS,uCAAuC,CAAC;AAAA,QAChF;AAGA,YAAI,SAAS,QAAQ;AACnB,mBAAS,IAAI,GAAG,IAAI,SAAS,OAAO,QAAQ,KAAK;AAC/C,kBAAM,QAAQ,SAAS,OAAO,CAAC;AAC/B,gBAAI,CAAC,MAAM,MAAM;AACf,qBAAO,KAAK,EAAE,MAAM,UAAU,CAAC,UAAU,SAAS,mCAAmC,CAAC;AAAA,YACxF;AACA,gBAAI,CAAC,MAAM,QAAQ;AACjB,uBAAS,KAAK;AAAA,gBACZ,MAAM,UAAU,CAAC;AAAA,gBACjB,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,YAAI,SAAS,SAAS;AACpB,mBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,QAAQ,KAAK;AAChD,kBAAM,SAAS,SAAS,QAAQ,CAAC;AACjC,gBAAI,CAAC,OAAO,MAAM;AAChB,qBAAO,KAAK,EAAE,MAAM,WAAW,CAAC,UAAU,SAAS,oCAAoC,CAAC;AAAA,YAC1F;AACA,gBAAI,CAAC,OAAO,SAAS,CAAC,OAAO,UAAU;AACrC,qBAAO,KAAK;AAAA,gBACV,MAAM,WAAW,CAAC;AAAA,gBAClB,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,GAAG;AAEjE,cAAI,KAAK,YAAY;AACnB,uBAAW,OAAO,KAAK,YAAY;AACjC,kBAAI,CAAC,SAAS,MAAM,GAAG,GAAG;AACxB,uBAAO,KAAK;AAAA,kBACV,MAAM,SAAS,MAAM;AAAA,kBACrB,SAAS,SAAS,MAAM,mCAAmC,GAAG;AAAA,kBAC9D,OAAO;AAAA,gBACT,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAGA,cAAI,KAAK,QAAQ;AACf,uBAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AAC9D,kBAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,YAAY,SAAS;AAC1E,sBAAM,eAAe;AACrB,oBAAI,aAAa,WAAW,UAAU,CAAC,aAAa,QAAQ;AAC1D,yBAAO,KAAK;AAAA,oBACV,MAAM,SAAS,MAAM,WAAW,SAAS;AAAA,oBACzC,SAAS;AAAA,kBACX,CAAC;AAAA,gBACH;AACA,oBAAI,aAAa,WAAW,SAAS;AAEnC,wBAAM,cAAc,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,aAAa,KAAK;AAC5E,sBAAI,CAAC,aAAa;AAChB,2BAAO,KAAK;AAAA,sBACV,MAAM,SAAS,MAAM,WAAW,SAAS;AAAA,sBACzC,SAAS,iDAAiD,aAAa,KAAK;AAAA,sBAC5E,OAAO,aAAa;AAAA,oBACtB,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,eAAe,KAAK,2BAA2B,QAAQ;AAC7D,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,SAAS,mCAAmC,aAAa,KAAK,MAAM,CAAC;AAAA,UACvE,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB,QAAQ,OAAO,SAAS,IAAI,SAAS;AAAA,UACrC,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC7C;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKO,eACL,UACA,QAC0B;AAC1B,cAAM,SAAoE,CAAC;AAE3E,YAAI,CAAC,SAAS,QAAQ;AACpB,iBAAO,EAAE,OAAO,KAAK;AAAA,QACvB;AAGA,mBAAW,SAAS,SAAS,QAAQ;AACnC,cAAI,MAAM,aAAa,SAAS,EAAE,MAAM,QAAQ,WAAW,MAAM,YAAY,QAAW;AACtF,mBAAO,KAAK;AAAA,cACV,MAAM,UAAU,MAAM,IAAI;AAAA,cAC1B,SAAS,mBAAmB,MAAM,IAAI;AAAA,YACxC,CAAC;AAAA,UACH;AAAA,QACF;AAGA,mBAAW,SAAS,SAAS,QAAQ;AACnC,cAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ;AACxC,kBAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,kBAAM,QAAQ,KAAK,sBAAsB,OAAO,MAAM,MAAM;AAC5D,gBAAI,CAAC,MAAM,OAAO;AAChB,qBAAO,KAAK;AAAA,gBACV,MAAM,UAAU,MAAM,IAAI;AAAA,gBAC1B,SAAS,MAAM,SAAS;AAAA,gBACxB;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB,QAAQ,OAAO,SAAS,IAAI,SAAS;AAAA,QACvC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,oBAAoB,QAAgB,UAAoC;AAEpF,YAAI,OAAO,WAAW,SAAS,KAAK,OAAO,WAAW,UAAU,GAAG;AACjE,gBAAM,WAAW,MAAM,MAAM,MAAM;AACnC,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,iCAAiC,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,UACnF;AACA,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B;AAGA,cAAM,WAAgB,gBAAW,MAAM,IACnC,SACK,aAAQ,YAAY,QAAQ,IAAI,GAAG,MAAM;AAClD,eAAO,MAAM,GAAG,SAAS,UAAU,OAAO;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA,MAKQ,qBAAqB,SAAiB,QAAqB;AAEjE,YAAI;AACF,iBAAO,KAAK,MAAM,OAAO;AAAA,QAC3B,QAAQ;AAEN,cAAI;AACF,mBAAY,UAAK,OAAO;AAAA,UAC1B,SAAS,OAAO;AACd,kBAAM,IAAI;AAAA,cACR,iCAAiC,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,YACpG;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,2BAA2B,UAAwC;AAEzE,cAAM,eAAyC,CAAC;AAChD,mBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,GAAG;AAEjE,gBAAM,UAAU,KAAK;AACrB,uBAAa,MAAM,IAAI,MAAM,QAAQ,OAAO,IAAI,UAAU,UAAU,CAAC,OAAO,IAAI,CAAC;AAAA,QACnF;AAEA,YAAI;AAEF,gBAAM,QAAQ,mBAAmB,qBAAqB,YAAY;AAElE,cAAI,MAAM,aAAa,MAAM,YAAY;AACvC,mBAAO,MAAM;AAAA,UACf;AAEA,iBAAO,CAAC;AAAA,QACV,QAAQ;AAIN,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,sBACN,OACA,QACoC;AACpC,YAAI;AACF,gBAAM,WAAW,KAAK,IAAI,QAAQ,MAAa;AAC/C,gBAAM,QAAQ,SAAS,KAAK;AAC5B,cAAI,CAAC,OAAO;AACV,kBAAM,SAAS,SAAS,QACpB,IAAI,OAAK,GAAG,EAAE,gBAAgB,GAAG,KAAK,EAAE,OAAO,EAAE,EAClD,KAAK,IAAI;AACZ,mBAAO,EAAE,OAAO,OAAO,OAAO,OAAO;AAAA,UACvC;AACA,iBAAO,EAAE,OAAO,KAAK;AAAA,QACvB,SAAS,OAAO;AACd,iBAAO,EAAE,OAAO,OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;","names":[]}
|