@probelabs/visor 0.1.107 → 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 +6 -0
- package/defaults/task-refinement.yaml +7 -3
- package/defaults/visor.tests.yaml +13 -2
- package/defaults/visor.yaml +1 -0
- package/dist/663.index.js +3 -2
- package/dist/80.index.js +3 -2
- package/dist/ai-review-service.d.ts +13 -9
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/config.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/task-refinement.yaml +7 -3
- package/dist/defaults/visor.tests.yaml +13 -2
- package/dist/defaults/visor.yaml +1 -0
- package/dist/docs/advanced-ai.md +60 -1
- package/dist/docs/ai-configuration.md +67 -0
- package/dist/docs/ai-custom-tools-usage.md +261 -0
- package/dist/docs/ai-custom-tools.md +392 -0
- package/dist/docs/bot-transports-rfc.md +23 -0
- package/dist/docs/configuration.md +21 -0
- package/dist/docs/engine-pause-resume-rfc.md +192 -0
- package/dist/docs/lifecycle-hooks.md +253 -0
- package/dist/docs/liquid-templates.md +143 -0
- package/dist/docs/providers/git-checkout.md +589 -0
- package/dist/docs/recipes.md +458 -5
- 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/router-patterns.md +339 -0
- package/dist/event-bus/types.d.ts +14 -0
- package/dist/event-bus/types.d.ts.map +1 -1
- package/dist/examples/ai-custom-tools-example.yaml +206 -0
- package/dist/examples/ai-custom-tools-simple.yaml +76 -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/on-init-import-demo.yaml +179 -0
- package/dist/examples/reusable-tools.yaml +92 -0
- package/dist/examples/reusable-workflows.yaml +88 -0
- package/dist/examples/session-reuse-self.yaml +81 -0
- package/dist/examples/slack-simple-chat.yaml +775 -0
- package/dist/failure-condition-evaluator.d.ts +2 -0
- package/dist/failure-condition-evaluator.d.ts.map +1 -1
- package/dist/frontends/github-frontend.d.ts +20 -0
- package/dist/frontends/github-frontend.d.ts.map +1 -1
- package/dist/frontends/host.d.ts +4 -0
- package/dist/frontends/host.d.ts.map +1 -1
- 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 +409 -41
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +436 -47
- package/dist/github-comments.d.ts +2 -0
- package/dist/github-comments.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83587 -56085
- package/dist/liquid-extensions.d.ts.map +1 -1
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/output/traces/{run-2025-11-21T11-50-46-505Z.ndjson → run-2026-01-20T19-22-58-043Z.ndjson} +91 -91
- package/dist/output/traces/run-2026-01-20T19-23-52-175Z.ndjson +1067 -0
- 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.map +1 -1
- package/dist/providers/check-provider.interface.d.ts +9 -0
- package/dist/providers/check-provider.interface.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/custom-tool-executor.d.ts.map +1 -1
- package/dist/providers/git-checkout-provider.d.ts +25 -0
- package/dist/providers/git-checkout-provider.d.ts.map +1 -0
- package/dist/providers/http-client-provider.d.ts +3 -0
- package/dist/providers/http-client-provider.d.ts.map +1 -1
- package/dist/providers/human-input-check-provider.d.ts +2 -0
- package/dist/providers/human-input-check-provider.d.ts.map +1 -1
- package/dist/providers/log-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +1 -1
- 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.map +1 -1
- package/dist/providers/script-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -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-OOZITMRU.mjs → chunk-3OMWVM6J.mjs} +11 -1
- package/dist/sdk/{chunk-OOZITMRU.mjs.map → chunk-3OMWVM6J.mjs.map} +1 -1
- package/dist/sdk/{chunk-37ZSCMFC.mjs → chunk-7UK3NIIT.mjs} +2 -2
- package/dist/sdk/{chunk-VMPLF6FT.mjs → chunk-AGIZJ4UZ.mjs} +50 -4
- package/dist/sdk/chunk-AGIZJ4UZ.mjs.map +1 -0
- package/dist/sdk/{chunk-IEO6CFLG.mjs → chunk-AIVFBIS4.mjs} +161 -5
- 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-HTOKWMPO.mjs +157 -0
- package/dist/sdk/chunk-HTOKWMPO.mjs.map +1 -0
- package/dist/sdk/{chunk-6Y4YTKCF.mjs → chunk-NAW3DB3I.mjs} +2 -2
- package/dist/sdk/{chunk-OWUVOILT.mjs → chunk-QR7MOMJH.mjs} +4 -3
- package/dist/sdk/{chunk-OWUVOILT.mjs.map → chunk-QR7MOMJH.mjs.map} +1 -1
- package/dist/sdk/{chunk-PTL3K3PN.mjs → chunk-QY2XYPEV.mjs} +488 -60
- package/dist/sdk/chunk-QY2XYPEV.mjs.map +1 -0
- package/dist/sdk/{chunk-OZJ263FM.mjs → chunk-SIWNBRTK.mjs} +29 -215
- package/dist/sdk/chunk-SIWNBRTK.mjs.map +1 -0
- package/dist/sdk/command-executor-TYUV6HUS.mjs +14 -0
- package/dist/sdk/{config-M4ZNO6NU.mjs → config-YNC2EOOT.mjs} +5 -3
- package/dist/sdk/{failure-condition-evaluator-NBO5YRXW.mjs → failure-condition-evaluator-YGTF2GHG.mjs} +6 -5
- package/dist/sdk/{github-frontend-4AWRJT7D.mjs → github-frontend-SIAEOCON.mjs} +190 -12
- package/dist/sdk/github-frontend-SIAEOCON.mjs.map +1 -0
- package/dist/sdk/{host-7GBC3S7L.mjs → host-DXUYTNMU.mjs} +5 -2
- package/dist/sdk/host-DXUYTNMU.mjs.map +1 -0
- package/dist/sdk/{liquid-extensions-C7EG3YKH.mjs → liquid-extensions-PKWCKK7E.mjs} +5 -4
- package/dist/sdk/memory-store-XGBB7LX7.mjs +12 -0
- package/dist/sdk/prompt-state-YRJY6QAL.mjs +16 -0
- package/dist/sdk/{renderer-schema-6RF26VUS.mjs → renderer-schema-LPKN5UJS.mjs} +3 -2
- package/dist/sdk/{renderer-schema-6RF26VUS.mjs.map → renderer-schema-LPKN5UJS.mjs.map} +1 -1
- package/dist/sdk/{routing-RP56JTV2.mjs → routing-6N45MJ4F.mjs} +7 -6
- package/dist/sdk/sdk.d.mts +219 -5
- package/dist/sdk/sdk.d.ts +219 -5
- package/dist/sdk/sdk.js +21329 -14908
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +407 -12874
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{session-registry-N5FFYFTM.mjs → session-registry-4E6YRQ77.mjs} +2 -2
- 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/{tracer-init-WP4X46IF.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/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/state-machine/context/build-engine-context.d.ts +8 -0
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
- 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/stats-manager.d.ts.map +1 -1
- package/dist/state-machine/dispatch/template-renderer.d.ts.map +1 -1
- package/dist/state-machine/runner.d.ts +6 -0
- package/dist/state-machine/runner.d.ts.map +1 -1
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/state-machine/states/plan-ready.d.ts.map +1 -1
- package/dist/state-machine/states/routing.d.ts.map +1 -1
- package/dist/state-machine/states/wave-planning.d.ts.map +1 -1
- package/dist/state-machine/workflow-projection.d.ts.map +1 -1
- package/dist/state-machine-execution-engine.d.ts +21 -9
- package/dist/state-machine-execution-engine.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/core/flow-stage.d.ts.map +1 -1
- package/dist/test-runner/core/test-execution-wrapper.d.ts.map +1 -1
- package/dist/test-runner/evaluators.d.ts +37 -4
- package/dist/test-runner/evaluators.d.ts.map +1 -1
- package/dist/test-runner/index.d.ts +7 -0
- package/dist/test-runner/index.d.ts.map +1 -1
- 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/validator.d.ts.map +1 -1
- package/dist/traces/{run-2025-11-21T11-50-46-505Z.ndjson → run-2026-01-20T19-22-58-043Z.ndjson} +91 -91
- 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 +4 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +182 -5
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/engine.d.ts +5 -0
- package/dist/types/engine.d.ts.map +1 -1
- package/dist/types/git-checkout.d.ts +76 -0
- package/dist/types/git-checkout.d.ts.map +1 -0
- 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/template-context.d.ts +1 -0
- package/dist/utils/template-context.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/workflow-executor.d.ts.map +1 -1
- package/dist/workflow-registry.d.ts.map +1 -1
- package/package.json +4 -2
- package/dist/output/traces/run-2025-11-21T11-51-33-674Z.ndjson +0 -839
- package/dist/sdk/chunk-IEO6CFLG.mjs.map +0 -1
- package/dist/sdk/chunk-JEHPDJIF.mjs +0 -223
- package/dist/sdk/chunk-JEHPDJIF.mjs.map +0 -1
- package/dist/sdk/chunk-OZJ263FM.mjs.map +0 -1
- package/dist/sdk/chunk-PTL3K3PN.mjs.map +0 -1
- package/dist/sdk/chunk-VMPLF6FT.mjs.map +0 -1
- package/dist/sdk/github-frontend-4AWRJT7D.mjs.map +0 -1
- package/dist/sdk/host-7GBC3S7L.mjs.map +0 -1
- package/dist/sdk/memory-store-GJACZC2A.mjs +0 -11
- package/dist/sdk/workflow-registry-2YIIXQCK.mjs +0 -11
- package/dist/traces/run-2025-11-21T11-51-33-674Z.ndjson +0 -839
- /package/dist/sdk/{config-M4ZNO6NU.mjs.map → check-provider-registry-534KL5HT.mjs.map} +0 -0
- /package/dist/sdk/{chunk-37ZSCMFC.mjs.map → chunk-7UK3NIIT.mjs.map} +0 -0
- /package/dist/sdk/{chunk-6Y4YTKCF.mjs.map → chunk-NAW3DB3I.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-NBO5YRXW.mjs.map → command-executor-TYUV6HUS.mjs.map} +0 -0
- /package/dist/sdk/{liquid-extensions-C7EG3YKH.mjs.map → config-YNC2EOOT.mjs.map} +0 -0
- /package/dist/sdk/{memory-store-GJACZC2A.mjs.map → failure-condition-evaluator-YGTF2GHG.mjs.map} +0 -0
- /package/dist/sdk/{routing-RP56JTV2.mjs.map → liquid-extensions-PKWCKK7E.mjs.map} +0 -0
- /package/dist/sdk/{session-registry-N5FFYFTM.mjs.map → memory-store-XGBB7LX7.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-WP4X46IF.mjs.map → prompt-state-YRJY6QAL.mjs.map} +0 -0
- /package/dist/sdk/{workflow-registry-2YIIXQCK.mjs.map → routing-6N45MJ4F.mjs.map} +0 -0
package/dist/sdk/sdk.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/state-machine/states/init.ts","../../src/state-machine/states/plan-ready.ts","../../src/state-machine/states/wave-planning.ts","../../src/utils/mermaid-telemetry.ts","../../src/providers/check-provider.interface.ts","../../src/utils/diff-processor.ts","../../src/utils/comment-metadata.ts","../../src/ai-review-service.ts","../../src/utils/env-resolver.ts","../../src/issue-filter.ts","../../src/telemetry/state-capture.ts","../../src/providers/ai-check-provider.ts","../../src/providers/http-check-provider.ts","../../src/providers/http-input-provider.ts","../../src/providers/http-client-provider.ts","../../src/providers/noop-check-provider.ts","../../src/providers/log-check-provider.ts","../../src/test-runner/recorders/global-recorder.ts","../../src/providers/github-ops-provider.ts","../../src/providers/claude-code-types.ts","../../src/providers/claude-code-check-provider.ts","../../src/utils/command-executor.ts","../../src/utils/env-exposure.ts","../../src/providers/command-check-provider.ts","../../src/utils/template-context.ts","../../src/utils/script-memory-ops.ts","../../src/providers/memory-check-provider.ts","../../src/providers/custom-tool-executor.ts","../../src/providers/mcp-check-provider.ts","../../src/utils/interactive-prompt.ts","../../src/utils/stdin-reader.ts","../../src/providers/human-input-check-provider.ts","../../src/providers/script-check-provider.ts","../../src/workflow-executor.ts","../../src/state-machine/workflow-projection.ts","../../src/providers/workflow-check-provider.ts","../../src/providers/check-provider-registry.ts","../../src/state-machine/states/level-dispatch.ts","../../src/state-machine/states/check-running.ts","../../src/state-machine/states/completed.ts","../../src/state-machine/states/error.ts","../../src/state-machine/runner.ts","../../src/state-machine/context/build-engine-context.ts","../../src/state-machine/execution/summary.ts","../../src/state-machine-execution-engine.ts","../../src/sdk.ts"],"sourcesContent":["/**\n * Init State Handler\n *\n * Responsibilities:\n * - Validate configuration\n * - Initialize services (journal, memory, GitHub checks)\n * - Transition to PlanReady\n */\n\nimport type { EngineContext, RunState, EngineState } from '../../types/engine';\nimport { logger } from '../../logger';\n\nexport async function handleInit(\n context: EngineContext,\n state: RunState,\n transition: (newState: EngineState) => void\n): Promise<void> {\n if (context.debug) {\n logger.info('[Init] Initializing state machine...');\n }\n\n // Validate configuration\n if (!context.config) {\n throw new Error('Configuration is required');\n }\n\n // Initialize memory store if needed\n if (context.memory) {\n await context.memory.initialize();\n }\n\n // Initialize GitHub checks if configured\n if (context.gitHubChecks) {\n // GitHub check initialization happens in the main engine\n // We just validate it's available here\n if (context.debug) {\n logger.info('[Init] GitHub checks service available');\n }\n }\n\n // Reset journal for this session\n if (context.debug) {\n logger.info(`[Init] Session ID: ${context.sessionId}`);\n }\n\n // Transition to PlanReady\n transition('PlanReady');\n}\n","/**\n * PlanReady State Handler\n *\n * Responsibilities:\n * - Build dependency graph using DependencyResolver\n * - Validate graph (check for cycles)\n * - Compute check metadata (tags, sessions, triggers)\n * - Transition to WavePlanning\n */\n\nimport type { EngineContext, RunState, EngineState } from '../../types/engine';\nimport { DependencyResolver } from '../../dependency-resolver';\nimport { logger } from '../../logger';\n\nexport async function handlePlanReady(\n context: EngineContext,\n state: RunState,\n transition: (newState: EngineState) => void\n): Promise<void> {\n if (context.debug) {\n logger.info('[PlanReady] Building dependency graph...');\n if (context.requestedChecks) {\n logger.info(`[PlanReady] Requested checks: ${context.requestedChecks.join(', ')}`);\n }\n if (context.config.tag_filter) {\n logger.info(\n `[PlanReady] Tag filter: include=${JSON.stringify(context.config.tag_filter.include)}, exclude=${JSON.stringify(context.config.tag_filter.exclude)}`\n );\n } else {\n logger.info('[PlanReady] No tag filter specified - will include only untagged checks');\n }\n }\n\n // Filter checks based on requested checks list, event triggers, and tags BEFORE building dependency graph\n //\n // Filtering order (matches legacy engine):\n // 1. Explicit check list (requestedChecks) - if provided, expand with transitive dependencies first\n // 2. Event filtering: Only include checks where:\n // - checkConfig.on is undefined (runs on any event), OR\n // - checkConfig.on includes context.event\n // 3. Tag filtering (matches legacy engine behavior):\n // - When no tag filter is specified, include only untagged checks by default\n // - Tagged checks are opt-in unless tag_filter is provided\n // - If exclude tags specified, exclude checks with any matching tag\n // - If include tags specified, include checks with at least one matching tag OR untagged checks\n const eventTrigger = context.event;\n const tagFilter = context.config.tag_filter;\n\n // Expand requested checks with transitive dependencies (matches legacy engine)\n const expandWithTransitives = (rootChecks: string[]): Set<string> | null => {\n const expanded = new Set<string>(rootChecks);\n\n const allowByTags = (checkId: string): boolean => {\n if (!tagFilter) return true;\n const cfg = context.config.checks?.[checkId];\n const tags: string[] = cfg?.tags || [];\n if (tagFilter.exclude && tagFilter.exclude.some(t => tags.includes(t))) return false;\n if (tagFilter.include && tagFilter.include.length > 0) {\n return tagFilter.include.some(t => tags.includes(t));\n }\n return true;\n };\n\n const allowByEvent = (checkId: string): boolean => {\n const cfg = context.config.checks?.[checkId];\n const triggers = cfg?.on || [];\n if (!triggers || triggers.length === 0) return true;\n const current = eventTrigger || 'manual';\n return triggers.includes(current as any);\n };\n\n const visit = (checkId: string): string | null => {\n const cfg = context.config.checks?.[checkId];\n if (!cfg || !cfg.depends_on) return null;\n\n const depTokens = Array.isArray(cfg.depends_on) ? cfg.depends_on : [cfg.depends_on];\n const expandDep = (tok: string): string[] => {\n if (tok.includes('|')) {\n return tok\n .split('|')\n .map(s => s.trim())\n .filter(Boolean);\n }\n return [tok];\n };\n\n const deps = depTokens.flatMap(expandDep);\n for (const depId of deps) {\n // Check if dependency exists - if not, return error\n if (!context.config.checks?.[depId]) {\n return `Check \"${checkId}\" depends on \"${depId}\" but \"${depId}\" is not defined`;\n }\n if (!allowByTags(depId)) continue;\n if (!allowByEvent(depId)) continue;\n if (!expanded.has(depId)) {\n expanded.add(depId);\n const err = visit(depId);\n if (err) return err;\n }\n }\n return null;\n };\n\n for (const checkId of rootChecks) {\n const err = visit(checkId);\n if (err) {\n // Record validation error\n const validationIssue: any = {\n file: 'system',\n line: 0,\n message: err,\n category: 'logic',\n severity: 'error',\n ruleId: 'system/error',\n };\n\n context.journal.commitEntry({\n sessionId: context.sessionId,\n scope: [],\n checkId: 'system',\n result: {\n issues: [validationIssue],\n output: undefined,\n },\n });\n\n return null; // Signal error by returning null\n }\n }\n\n return expanded;\n };\n\n const requestedChecksSet = context.requestedChecks\n ? expandWithTransitives(context.requestedChecks)\n : undefined;\n\n // Check if dependency validation failed during expansion\n if (context.requestedChecks && requestedChecksSet === null) {\n logger.error(`[PlanReady] Dependency validation failed during expansion`);\n // Transition to Completed since error was already recorded\n state.currentState = 'Completed';\n return;\n }\n\n if (context.debug && requestedChecksSet && context.requestedChecks) {\n const added = Array.from(requestedChecksSet).filter(c => !context.requestedChecks!.includes(c));\n if (added.length > 0) {\n logger.info(\n `[PlanReady] Expanded requested checks with transitive dependencies: ${added.join(', ')}`\n );\n }\n }\n\n const filteredChecks: Record<string, import('../../types/config').CheckConfig> = {};\n\n // Identify checks that are only meant to run via routing (on_* .run targets).\n // These should not be part of the initial graph unless explicitly requested.\n const routingRunTargets = new Set<string>();\n for (const [, cfg] of Object.entries(context.config.checks || {})) {\n const onFinish = (cfg as any).on_finish || {};\n const onSuccess = (cfg as any).on_success || {};\n const onFail = (cfg as any).on_fail || {};\n const collect = (arr?: string[]) => {\n if (Array.isArray(arr)) {\n for (const t of arr) if (typeof t === 'string' && t) routingRunTargets.add(t);\n }\n };\n collect(onFinish.run);\n collect(onSuccess.run);\n collect(onFail.run);\n }\n\n for (const [checkId, checkConfig] of Object.entries(context.config.checks || {})) {\n // 1. Filter by explicit check list (if provided, now includes transitive dependencies)\n if (requestedChecksSet && !requestedChecksSet.has(checkId)) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Skipping check '${checkId}': not in expanded requested checks list`\n );\n }\n continue;\n }\n // 1b. Exclude checks that are intended to be started by routing (run targets)\n // unless they were explicitly requested. This avoids running aggregators/routers\n // at wave 0; they will be scheduled by ForwardRunRequested from on_* handlers.\n if (!requestedChecksSet && routingRunTargets.has(checkId)) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Skipping check '${checkId}': routing-run target (will be scheduled by on_*.run)`\n );\n }\n continue;\n }\n // Check if event trigger matches (same logic as event-mapper.ts shouldRunCheck)\n // If 'on' is not specified, the check can run on any event\n if (checkConfig.on && eventTrigger && !checkConfig.on.includes(eventTrigger)) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Skipping check '${checkId}': on=${JSON.stringify(checkConfig.on)}, event=${eventTrigger}`\n );\n }\n continue;\n }\n\n // Tag filtering (matches legacy CheckExecutionEngine.filterChecksByTags logic)\n const checkTags = checkConfig.tags || [];\n const isTagged = checkTags.length > 0;\n\n if (tagFilter) {\n // Check exclude tags first (if any exclude tag matches, skip the check)\n if (tagFilter.exclude && tagFilter.exclude.length > 0) {\n const hasExcludedTag = tagFilter.exclude.some(tag => checkTags.includes(tag));\n if (hasExcludedTag) {\n if (context.debug) {\n logger.info(`[PlanReady] Skipping check '${checkId}': excluded by tag filter`);\n }\n continue;\n }\n }\n\n // Check include tags (if specified, at least one must match OR check is untagged)\n if (tagFilter.include && tagFilter.include.length > 0) {\n const hasIncludedTag = tagFilter.include.some(tag => checkTags.includes(tag));\n if (!hasIncludedTag && isTagged) {\n if (context.debug) {\n logger.info(`[PlanReady] Skipping check '${checkId}': not included by tag filter`);\n }\n continue;\n }\n }\n } else {\n // No tag filter specified: include only untagged checks by default\n // Tagged checks are opt-in unless tag_filter is provided\n if (isTagged) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Skipping check '${checkId}': tagged but no tag filter specified`\n );\n }\n continue;\n }\n }\n\n filteredChecks[checkId] = checkConfig;\n }\n\n if (context.debug) {\n const totalChecks = Object.keys(context.config.checks || {}).length;\n const filteredCount = Object.keys(filteredChecks).length;\n logger.info(\n `[PlanReady] Filtered ${totalChecks} checks to ${filteredCount} based on event=${eventTrigger}`\n );\n }\n\n // Forward-closure across dependents is useful when running “all” checks with no explicit roots,\n // but it must NOT run when the caller provided an explicit requested list (tests that expect\n // only a subset would be surprised). Only apply this when no requestedChecks are set.\n if (!context.requestedChecks || context.requestedChecks.length === 0) {\n const dependentsMap = new Map<string, string[]>();\n for (const [cid, cfg] of Object.entries(context.config.checks || {})) {\n const deps = (cfg.depends_on || []) as string[];\n const depList = Array.isArray(deps) ? deps : [deps];\n for (const raw of depList) {\n if (typeof raw !== 'string') continue;\n const tokens = raw.includes('|')\n ? raw\n .split('|')\n .map(s => s.trim())\n .filter(Boolean)\n : [raw];\n for (const dep of tokens) {\n if (!dependentsMap.has(dep)) dependentsMap.set(dep, []);\n dependentsMap.get(dep)!.push(cid);\n }\n }\n }\n\n const queue: string[] = Object.keys(filteredChecks);\n const seenForward = new Set(queue);\n while (queue.length > 0) {\n const cur = queue.shift()!;\n const kids = dependentsMap.get(cur) || [];\n for (const child of kids) {\n if (seenForward.has(child)) continue;\n // Only add child if it passes event/tag filtering (reuse policy)\n const cfg = context.config.checks?.[child];\n if (!cfg) continue;\n if (cfg.on && eventTrigger && !cfg.on.includes(eventTrigger)) continue;\n const tags = cfg.tags || [];\n const isTagged = tags.length > 0;\n if (!tagFilter && isTagged) continue;\n if (tagFilter) {\n if (tagFilter.exclude && tagFilter.exclude.length > 0) {\n const hasExcluded = tagFilter.exclude.some(t => tags.includes(t));\n if (hasExcluded) continue;\n }\n if (tagFilter.include && tagFilter.include.length > 0) {\n const hasIncluded = tagFilter.include.some(t => tags.includes(t));\n if (!hasIncluded && isTagged) continue;\n }\n }\n filteredChecks[child] = cfg;\n seenForward.add(child);\n queue.push(child);\n if (context.debug)\n logger.info(`[PlanReady] Added dependent '${child}' via forward-closure from '${cur}'`);\n }\n }\n }\n\n // Helper to check if dependencies are satisfied\n // For OR dependencies (pipe syntax), at least one must be in filteredChecks\n const areDependenciesSatisfied = (dependencies: string[]): boolean => {\n for (const dep of dependencies) {\n // Check for OR dependency (pipe syntax)\n if (dep.includes('|')) {\n const orOptions = dep\n .split('|')\n .map(s => s.trim())\n .filter(Boolean);\n // At least one option must exist in filtered checks\n const hasAtLeastOne = orOptions.some(opt => filteredChecks[opt] !== undefined);\n if (!hasAtLeastOne) {\n return false;\n }\n } else {\n // Regular dependency - must exist in filtered checks\n if (filteredChecks[dep] === undefined) {\n return false;\n }\n }\n }\n return true;\n };\n\n // Second pass: Remove checks whose dependencies are not satisfied\n // Note: When tag filtering is active, we allow soft dependencies - checks can run\n // even if some dependencies are filtered out by tags. They just won't have those outputs.\n const finalChecks: Record<string, import('../../types/config').CheckConfig> = {};\n for (const [checkId, checkConfig] of Object.entries(filteredChecks)) {\n const dependencies = checkConfig.depends_on || [];\n\n // Only enforce dependency satisfaction when NO tag filter is active\n // When tag filtering is active, allow checks to run with partial dependencies (soft dependencies)\n if (dependencies.length > 0 && !tagFilter && !areDependenciesSatisfied(dependencies)) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Skipping check '${checkId}': unsatisfied dependencies ${JSON.stringify(dependencies)}`\n );\n }\n continue;\n }\n finalChecks[checkId] = checkConfig;\n }\n\n if (context.debug && Object.keys(finalChecks).length !== Object.keys(filteredChecks).length) {\n logger.info(\n `[PlanReady] Removed ${Object.keys(filteredChecks).length - Object.keys(finalChecks).length} checks due to unsatisfied dependencies`\n );\n }\n\n // Extract dependencies from final filtered check configurations\n const checkDependencies: Record<string, string[]> = {};\n\n for (const [checkId, checkConfig] of Object.entries(finalChecks)) {\n // Expand OR groups (pipe syntax) for dependency resolution\n // For OR groups, only include options that exist in finalChecks\n // e.g., \"issue-assistant|comment-assistant\" becomes [\"comment-assistant\"] if issue-assistant was filtered out\n // For regular dependencies, also filter to only include checks that exist (soft dependencies when tag filtering)\n const dependencies = (checkConfig.depends_on || []).flatMap((d: string) => {\n if (typeof d === 'string' && d.includes('|')) {\n // OR dependency - filter to only include available checks\n const orOptions = d\n .split('|')\n .map(s => s.trim())\n .filter(Boolean)\n .filter(opt => finalChecks[opt] !== undefined); // Only include if check exists\n return orOptions;\n } else {\n // Regular dependency - when tag filtering is active, filter to only available checks (soft dependencies)\n // When no tag filtering, include all dependencies (validation happens in graph builder)\n if (tagFilter && finalChecks[d] === undefined) {\n if (context.debug) {\n logger.info(\n `[PlanReady] Soft dependency '${d}' of check '${checkId}' filtered out by tags - check will run without it`\n );\n }\n return []; // Filter out unavailable dependency\n }\n return [d];\n }\n });\n checkDependencies[checkId] = dependencies;\n }\n\n // Build dependency graph\n let graph;\n try {\n graph = DependencyResolver.buildDependencyGraph(checkDependencies);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`[PlanReady] Dependency validation failed: ${errorMsg}`);\n\n // Record validation error as an issue\n const validationIssue: any = {\n file: 'system',\n line: 0,\n message: errorMsg,\n category: 'logic',\n severity: 'error',\n ruleId: 'system/error',\n };\n\n // Record in journal as a system check\n context.journal.commitEntry({\n sessionId: context.sessionId,\n scope: [],\n checkId: 'system',\n result: {\n issues: [validationIssue],\n output: undefined,\n },\n });\n\n // Transition to Completed\n state.currentState = 'Completed';\n return;\n }\n\n // Validate graph - check for cycles\n if (graph.hasCycles) {\n const cycleNodes = graph.cycleNodes?.join(' -> ') || 'unknown';\n const errorMsg = `Dependency cycle detected: ${cycleNodes}`;\n logger.error(`[PlanReady] ${errorMsg}`);\n\n // Record cycle error as an issue\n const cycleIssue: any = {\n file: 'system',\n line: 0,\n message: errorMsg,\n category: 'logic',\n severity: 'error',\n ruleId: 'system/error',\n };\n\n // Record in journal as a system check\n context.journal.commitEntry({\n sessionId: context.sessionId,\n scope: [],\n checkId: 'system',\n result: {\n issues: [cycleIssue],\n output: undefined,\n },\n });\n\n // Transition to Completed\n state.currentState = 'Completed';\n return;\n }\n\n if (context.debug) {\n logger.info(\n `[PlanReady] Graph built with ${graph.nodes.size} checks, ${graph.executionOrder.length} levels`\n );\n }\n\n // Store graph in context (mutate for now, can refactor later)\n (context as any).dependencyGraph = graph;\n\n // Initialize wave 0\n state.wave = 0;\n\n // Transition to WavePlanning\n transition('WavePlanning');\n}\n","/**\n * WavePlanning State Handler\n *\n * Responsibilities:\n * - Inspect event queue for forward runs, goto events, etc.\n * - Determine next wave's execution levels\n * - Queue topological levels for execution\n * - Transition to LevelDispatch or Completed\n *\n * M2: Adds goto/on_finish/on_fail routing with deduplication\n */\n\nimport type { EngineContext, RunState, EngineState, EngineEvent } from '../../types/engine';\nimport { logger } from '../../logger';\nimport { DependencyResolver } from '../../dependency-resolver';\n\nexport async function handleWavePlanning(\n context: EngineContext,\n state: RunState,\n transition: (newState: EngineState) => void\n): Promise<void> {\n if (context.debug) {\n logger.info(`[WavePlanning] Planning wave ${state.wave}...`);\n }\n\n // Reset forward-run active flag at the beginning of each planning cycle.\n // It will be set to true only when we schedule a wave spawned by a forward-run request.\n try {\n (state as any).flags = (state as any).flags || {};\n (state as any).flags.forwardRunActive = false;\n } catch {}\n\n // Check if we have a dependency graph\n if (!context.dependencyGraph) {\n throw new Error('Dependency graph not available');\n }\n\n // M3: Process bubbled events from child workflows\n const bubbledEvents = (context as any)._bubbledEvents || [];\n if (bubbledEvents.length > 0) {\n if (context.debug) {\n logger.info(\n `[WavePlanning] Processing ${bubbledEvents.length} bubbled events from child workflows`\n );\n }\n\n // Merge bubbled events into our event queue\n for (const event of bubbledEvents) {\n state.eventQueue.push(event);\n }\n\n // Clear bubbled events\n (context as any)._bubbledEvents = [];\n }\n\n // M2: Process event queue for forward run requests\n // IMPORTANT: Only process forward run requests if the current wave's levelQueue is empty\n // This ensures we complete all scheduled checks before processing routing events\n const forwardRunRequests = state.eventQueue.filter(\n e => e.type === 'ForwardRunRequested'\n ) as Array<Extract<EngineEvent, { type: 'ForwardRunRequested' }>>;\n\n // Process forward-run requests.\n // - GOTO-originated requests (goto/goto_js) preempt remaining work to jump back.\n // - RUN-originated requests (run/run_js) are processed after the current wave drains,\n // so dependents in this wave (e.g., validate-fact after extract-facts) still run first.\n if (\n forwardRunRequests.length > 0 &&\n (state.levelQueue.length === 0 ||\n forwardRunRequests.some(r => r.origin === 'goto' || r.origin === 'goto_js'))\n ) {\n if (state.levelQueue.length > 0) {\n if (context.debug) {\n logger.info(\n `[WavePlanning] Preempting ${state.levelQueue.length} remaining levels due to goto forward-run request`\n );\n }\n // Clear remaining work; the next wave will be rebuilt\n state.levelQueue = [];\n }\n if (context.debug) {\n logger.info(`[WavePlanning] Processing ${forwardRunRequests.length} forward run requests`);\n }\n\n // Clear processed events from queue\n state.eventQueue = state.eventQueue.filter(e => e.type !== 'ForwardRunRequested');\n\n // Build set of checks to execute with deduplication\n const checksToRun = new Set<string>();\n // Collect per-check scopes for map-fanout runs\n if (!state.pendingRunScopes) state.pendingRunScopes = new Map();\n const eventOverrides = new Map<string, string>();\n\n for (const request of forwardRunRequests) {\n const { target, gotoEvent } = request;\n\n // Deduplication: check if we've already requested this target in this wave\n const scopeKey =\n (request as any).scope && Array.isArray((request as any).scope)\n ? JSON.stringify((request as any).scope)\n : 'root';\n const dedupeKey = `${target}:${gotoEvent || 'default'}:${state.wave}:${scopeKey}`;\n if (state.forwardRunGuards.has(dedupeKey)) {\n if (context.debug) {\n logger.info(`[WavePlanning] Skipping duplicate forward run: ${target}`);\n }\n continue;\n }\n\n // Add to dedupe guard\n state.forwardRunGuards.add(dedupeKey);\n\n // Add target to execution set\n checksToRun.add(target);\n\n // Record requested scope (if any) for per-item fanout scheduling\n try {\n const scope = (request as any).scope as\n | import('../../snapshot-store').ScopePath\n | undefined;\n if (scope && scope.length > 0) {\n const arr = state.pendingRunScopes.get(target) || [];\n // Deduplicate scopes\n const key = (s: any[]) => JSON.stringify(s);\n if (!arr.some(s => key(s) === key(scope))) arr.push(scope);\n state.pendingRunScopes.set(target, arr);\n }\n } catch {}\n\n // Store event override if specified\n if (gotoEvent) {\n eventOverrides.set(target, gotoEvent);\n }\n\n // Find all transitive dependencies (parents) of target\n const dependencies = findTransitiveDependencies(target, context);\n for (const dep of dependencies) {\n checksToRun.add(dep);\n }\n\n // Find all transitive dependents (children) of target\n const dependents = findTransitiveDependents(target, context, gotoEvent);\n for (const dep of dependents) {\n checksToRun.add(dep);\n }\n }\n\n if (checksToRun.size > 0) {\n // Build subgraph for checks to run\n const subgraphChecks = Array.from(checksToRun);\n\n // Build dependency map for subgraph (expand OR tokens)\n const subDeps: Record<string, string[]> = {};\n for (const checkId of subgraphChecks) {\n const checkConfig = context.config.checks?.[checkId];\n if (!checkConfig) continue;\n\n const deps = checkConfig.depends_on || [];\n const depList = Array.isArray(deps) ? deps : [deps];\n\n // Expand OR tokens (e.g., \"A|B\") and include only dependencies present in the subgraph\n const expanded = depList.flatMap((d: string) =>\n typeof d === 'string' && d.includes('|')\n ? d\n .split('|')\n .map(s => s.trim())\n .filter(Boolean)\n : [d]\n );\n\n subDeps[checkId] = expanded.filter((d: string) => checksToRun.has(d));\n }\n\n // Build execution order for subgraph\n const subGraph = DependencyResolver.buildDependencyGraph(subDeps);\n\n // Check for cycles in forward-run subset\n if (subGraph.hasCycles) {\n const cycleNodes = subGraph.cycleNodes?.join(' -> ') || 'unknown';\n const errorMsg = `Cycle detected in forward-run dependency subset: ${cycleNodes}`;\n logger.error(`[WavePlanning] ${errorMsg}`);\n\n // Mark execution as failed by adding a failed check to stats\n // This allows tests to detect the cycle via statistics.failedExecutions\n const firstCycleCheck = subGraph.cycleNodes?.[0];\n if (firstCycleCheck) {\n const checkStats: any = {\n checkName: firstCycleCheck,\n totalRuns: 1, // Count as 1 execution attempt\n successfulRuns: 0,\n failedRuns: 1,\n skippedRuns: 0,\n skipped: false,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: {\n critical: 0,\n error: 1,\n warning: 0,\n info: 0,\n },\n errorMessage: errorMsg,\n };\n state.stats.set(firstCycleCheck, checkStats);\n }\n\n // Transition to Completed (nothing more to execute)\n transition('Completed');\n return;\n }\n\n // Queue levels for execution\n state.levelQueue = [...subGraph.executionOrder];\n\n if (context.debug) {\n const planned = subgraphChecks.join(', ');\n logger.info(\n `[WavePlanning] Forward-run planning: checks=[${planned}] levels=${state.levelQueue.length}`\n );\n }\n\n if (context.debug) {\n logger.info(\n `[WavePlanning] Queued ${state.levelQueue.length} levels for ${checksToRun.size} checks (forward run)`\n );\n }\n\n // Increment wave counter\n state.wave++;\n\n // Reset wave-scoped state to allow routing retries\n (state as any).currentWaveCompletions = new Set<string>();\n (state as any).failedChecks = new Set<string>();\n\n // Clear forward run flag since we're processing them\n state.flags.forwardRunRequested = false;\n\n // Mark this wave as a forward-run wave so guards (if/assume) may consult\n // prior outputs from the journal when evaluating conditions.\n try {\n (state as any).flags.forwardRunActive = true;\n (state as any).flags.waveKind = 'forward';\n } catch {}\n\n // Transition to LevelDispatch\n transition('LevelDispatch');\n return;\n }\n }\n\n // M2: Check for WaveRetry events (from on_finish)\n const waveRetryEvents = state.eventQueue.filter(e => e.type === 'WaveRetry');\n if (\n waveRetryEvents.length > 0 &&\n state.levelQueue.length === 0 &&\n !state.eventQueue.some(e => e.type === 'ForwardRunRequested')\n ) {\n logger.info(`[WavePlanning] Processing wave retry requests (${waveRetryEvents.length} events)`);\n\n // Clear wave retry events\n state.eventQueue = state.eventQueue.filter(e => e.type !== 'WaveRetry');\n\n // Strategy: Only re-run checks that were previously skipped due to `if`\n // gating. This avoids re-running forEach parents and heavy dependency\n // trees while allowing post-aggregation checks to re-evaluate.\n const skippedIfChecks = new Set<string>();\n logger.info(`[WavePlanning] Scanning ${state.stats.size} stat entries for skipped-if checks`);\n for (const [name, stats] of state.stats.entries()) {\n logger.info(\n `[WavePlanning] Check ${name}: skipped=${(stats as any).skipped}, skipReason=${(stats as any).skipReason}`\n );\n if ((stats as any).skipped === true && (stats as any).skipReason === 'if_condition') {\n skippedIfChecks.add(name);\n logger.info(`[WavePlanning] Found skipped-if check for retry: ${name}`);\n }\n }\n logger.info(`[WavePlanning] Total skipped-if checks: ${skippedIfChecks.size}`);\n\n if (skippedIfChecks.size === 0) {\n // Nothing to retry; mark completed\n transition('Completed');\n return;\n }\n\n // Build subgraph only for the skipped-if checks; do not include forEach parents.\n const checksToRun = Array.from(skippedIfChecks).filter(\n id => !(context.config.checks?.[id] as any)?.forEach\n );\n const subDeps: Record<string, string[]> = {};\n for (const id of checksToRun) {\n // Only include dependencies that are within the same subset (often none).\n const cfg = context.config.checks?.[id];\n const deps = (cfg?.depends_on || []).filter((d: string) => checksToRun.includes(d));\n subDeps[id] = deps as string[];\n }\n\n const subGraph = DependencyResolver.buildDependencyGraph(subDeps);\n\n state.levelQueue = [...subGraph.executionOrder];\n\n if (context.debug) {\n logger.info(\n `[WavePlanning] Wave retry queued ${checksToRun.length} skipped-if check(s) in ${state.levelQueue.length} level(s)`\n );\n }\n\n // Increment wave and reset wave-scoped state\n state.wave++;\n\n // Reset wave-scoped state to allow retry evaluation\n (state as any).currentWaveCompletions = new Set<string>();\n (state as any).failedChecks = new Set<string>();\n\n // Mark this wave as a forward-style evaluation wave so guards (if/assume)\n // can consult latest outputs/memory across the journal. This mirrors the\n // behavior we enable for forward runs, and is necessary for patterns like\n // on_finish.run → aggregate sets memory flags → skipped-if checks re-run.\n try {\n (state as any).flags = (state as any).flags || {};\n (state as any).flags.forwardRunActive = true;\n (state as any).flags.waveKind = 'retry';\n } catch {}\n\n transition('LevelDispatch');\n return;\n }\n\n // (Removed) opportunistic on_finish processing; handled in LevelDispatch and routing.\n\n // Initial wave: queue all execution levels\n if (state.wave === 0 && state.levelQueue.length === 0) {\n state.levelQueue = [...context.dependencyGraph.executionOrder];\n\n if (context.debug) {\n logger.info(\n `[WavePlanning] Queued ${state.levelQueue.length} levels for execution (initial wave)`\n );\n }\n\n // Increment wave to prevent re-queueing the same levels\n state.wave++;\n\n // Initialize current wave state\n (state as any).currentWaveCompletions = new Set<string>();\n (state as any).failedChecks = new Set<string>();\n }\n\n // Check if there are levels to execute\n if (state.levelQueue.length > 0) {\n // Transition to LevelDispatch\n transition('LevelDispatch');\n } else {\n // No more work - check if we have pending events\n if (state.eventQueue.length > 0) {\n if (context.debug) {\n logger.warn(\n `[WavePlanning] Event queue not empty (${state.eventQueue.length} events) but no work scheduled`\n );\n }\n }\n\n // All work complete\n if (context.debug) {\n logger.info('[WavePlanning] All waves complete');\n }\n transition('Completed');\n }\n}\n\n/**\n * Find all transitive dependencies (parents) of a check\n */\nfunction findTransitiveDependencies(target: string, context: EngineContext): Set<string> {\n const dependencies = new Set<string>();\n const checks = context.config.checks || {};\n const visited = new Set<string>();\n\n const dfs = (checkId: string) => {\n if (visited.has(checkId)) return;\n visited.add(checkId);\n\n const checkConfig = checks[checkId];\n if (!checkConfig) return;\n\n const deps = checkConfig.depends_on || [];\n const depList = Array.isArray(deps) ? deps : [deps];\n\n for (const depId of depList) {\n if (typeof depId !== 'string') continue;\n\n // Handle OR dependencies (pipe syntax) - add all options\n if (depId.includes('|')) {\n const orOptions = depId\n .split('|')\n .map(s => s.trim())\n .filter(Boolean);\n for (const opt of orOptions) {\n if (checks[opt]) {\n // Exclude pure memory initializers from forward-run dependency subset\n const optCfg: any = checks[opt];\n if (\n String(optCfg?.type || '').toLowerCase() === 'memory' &&\n String(optCfg?.operation || '').toLowerCase() === 'set'\n ) {\n continue;\n }\n dependencies.add(opt);\n dfs(opt);\n }\n }\n } else {\n if (checks[depId]) {\n // Exclude pure memory initializers from forward-run dependency subset\n const dCfg: any = checks[depId];\n if (\n String(dCfg?.type || '').toLowerCase() === 'memory' &&\n String(dCfg?.operation || '').toLowerCase() === 'set'\n ) {\n continue;\n }\n dependencies.add(depId);\n dfs(depId);\n }\n }\n }\n };\n\n dfs(target);\n return dependencies;\n}\n\n/**\n * Find all transitive dependents of a check that should run for a given event\n */\nfunction findTransitiveDependents(\n target: string,\n context: EngineContext,\n gotoEvent?: string\n): Set<string> {\n const dependents = new Set<string>();\n const checks = context.config.checks || {};\n\n if (context.debug) {\n logger.info(\n `[WavePlanning] findTransitiveDependents called for target=${target}, gotoEvent=${gotoEvent}`\n );\n }\n\n // Helper to check if a check depends on another\n const dependsOn = (checkId: string, depId: string): boolean => {\n const visited = new Set<string>();\n\n const dfs = (current: string): boolean => {\n if (visited.has(current)) return false;\n visited.add(current);\n\n const checkConfig = checks[current];\n if (!checkConfig) return false;\n\n const deps = checkConfig.depends_on || [];\n const depList = Array.isArray(deps) ? deps : [deps];\n\n // Check direct dependency or OR dependency (pipe syntax)\n for (const dep of depList) {\n if (typeof dep !== 'string') continue;\n\n // Handle OR dependencies (pipe syntax)\n if (dep.includes('|')) {\n const orOptions = dep.split('|').map(s => s.trim());\n if (orOptions.includes(depId)) return true;\n } else {\n if (dep === depId) return true;\n }\n }\n\n for (const d of depList) {\n if (dfs(d)) return true;\n }\n\n return false;\n };\n\n return dfs(checkId);\n };\n\n // Find all checks that depend on target\n for (const checkId of Object.keys(checks)) {\n if (checkId === target) continue;\n\n const checkConfig = checks[checkId];\n if (!checkConfig) continue;\n\n // Check if this check depends on target\n const isDep = dependsOn(checkId, target);\n if (context.debug && isDep) {\n logger.info(`[WavePlanning] findTransitiveDependents: ${checkId} depends on ${target}`);\n }\n if (!isDep) continue;\n\n // If gotoEvent specified, filter by event triggers\n if (gotoEvent) {\n const triggers = checkConfig.on;\n if (Array.isArray(triggers) && triggers.length > 0) {\n if (!triggers.includes(gotoEvent as any)) {\n // This check doesn't run for the specified event\n if (context.debug) {\n logger.info(`[WavePlanning] Skipping ${checkId}: doesn't run for event ${gotoEvent}`);\n }\n continue;\n }\n }\n }\n\n // Add to dependents\n dependents.add(checkId);\n if (context.debug) {\n logger.info(`[WavePlanning] Added dependent: ${checkId}`);\n }\n }\n\n return dependents;\n}\n","import { addEvent } from '../telemetry/trace-helpers';\nimport { addDiagramBlock } from '../telemetry/metrics';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\nconst MERMAID_RE = /```mermaid\\s*\\n([\\s\\S]*?)\\n```/gi;\n\nexport type DiagramOrigin = 'content' | 'issue';\n\nexport function emitMermaidFromMarkdown(\n checkName: string,\n markdown: string,\n origin: DiagramOrigin\n): number {\n if (!markdown || typeof markdown !== 'string') return 0;\n let m: RegExpExecArray | null;\n let count = 0;\n MERMAID_RE.lastIndex = 0;\n while ((m = MERMAID_RE.exec(markdown)) != null) {\n const code = (m[1] || '').trim();\n if (code) {\n try {\n addEvent('diagram.block', { check: checkName, origin, code });\n addDiagramBlock(origin);\n // Fallback writer for environments where OTel SDK isn't active\n if (process.env.VISOR_TRACE_REPORT === 'true') {\n const outDir =\n process.env.VISOR_TRACE_DIR || path.join(process.cwd(), 'output', 'traces');\n try {\n if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n const jsonPath = path.join(outDir, `${ts}.trace.json`);\n const htmlPath = path.join(outDir, `${ts}.report.html`);\n // Append or create minimal trace JSON\n let data: {\n spans: Array<{ events: Array<{ name: string; attrs: Record<string, unknown> }> }>;\n } = { spans: [] };\n if (fs.existsSync(jsonPath)) {\n try {\n data = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));\n } catch {\n data = { spans: [] };\n }\n }\n data.spans.push({\n events: [{ name: 'diagram.block', attrs: { check: checkName, origin, code } }],\n });\n fs.writeFileSync(jsonPath, JSON.stringify(data, null, 2), 'utf8');\n // Ensure minimal HTML report exists\n if (!fs.existsSync(htmlPath)) {\n fs.writeFileSync(\n htmlPath,\n '<!doctype html><html><head><meta charset=\"utf-8\"/><title>Visor Trace Report</title></head><body><h2>Visor Trace Report</h2></body></html>',\n 'utf8'\n );\n }\n } catch {}\n }\n count++;\n } catch {\n // ignore telemetry failures\n }\n }\n }\n return count;\n}\n","import { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { EnvConfig, HumanInputRequest } from '../types/config';\n\n/**\n * Configuration for a check provider\n */\nexport interface CheckProviderConfig {\n type: string;\n prompt?: string;\n eventContext?: Record<string, unknown>;\n focus?: string;\n command?: string; // For PR comment triggers\n exec?: string; // For command execution (supports Liquid templates)\n stdin?: string; // Optional stdin input (supports Liquid templates)\n args?: string[] | Record<string, unknown>; // string[] deprecated for command args; Record for workflow inputs\n command_args?: string[]; // MCP stdio command arguments\n interpreter?: string;\n url?: string;\n method?: string;\n headers?: Record<string, string>;\n timeout?: number;\n metadata?: Record<string, unknown>;\n workingDirectory?: string;\n env?: EnvConfig;\n ai?: import('../types/config').AIProviderConfig;\n /** AI model to use for this check - overrides global setting */\n ai_model?: string;\n /** AI provider to use for this check - overrides global setting */\n ai_provider?: 'google' | 'anthropic' | 'openai' | string;\n /** Check name for sessionID and logging purposes */\n checkName?: string;\n /** Session ID for AI session management */\n sessionId?: string;\n /** Script content for 'script' provider */\n content?: string;\n [key: string]: unknown;\n}\n\n/**\n * Execution context passed to check providers\n */\nexport interface ExecutionContext {\n /** Session information for AI session reuse */\n parentSessionId?: string;\n reuseSession?: boolean;\n /** CLI message value (from --message argument) */\n cliMessage?: string;\n /**\n * Stage-local baseline of output history lengths per check name.\n * When present, providers should expose an `outputs_history_stage` object in\n * Liquid/JS contexts that slices the global history from this baseline.\n * This enables stage-scoped assertions in the YAML test runner without\n * relying on global execution history.\n */\n stageHistoryBase?: Record<string, number>;\n /** Workflow inputs - available when executing within a workflow */\n workflowInputs?: Record<string, unknown>;\n /** SDK hooks for human input */\n hooks?: {\n onHumanInput?: (request: HumanInputRequest) => Promise<string>;\n onPromptCaptured?: (info: { step: string; provider: string; prompt: string }) => void;\n mockForStep?: (step: string) => unknown | undefined;\n };\n /**\n * Optional execution mode hints. The core engine does not read environment\n * variables directly; callers (CLI, test runner) can set these flags to\n * request certain behaviors without polluting core logic with test-specific\n * branches.\n */\n mode?: {\n /** true when running under the YAML test runner */\n test?: boolean;\n /** post review comments from grouped execution paths (used by tests) */\n postGroupedComments?: boolean;\n /** reset per-run guard state before grouped execution */\n resetPerRunState?: boolean;\n };\n}\n\n/**\n * Abstract base class for all check providers\n * Implementing classes provide specific check functionality (AI, tool, script, etc.)\n */\nexport abstract class CheckProvider {\n /**\n * Get the unique name/type of this provider\n */\n abstract getName(): string;\n\n /**\n * Get a human-readable description of this provider\n */\n abstract getDescription(): string;\n\n /**\n * Validate provider-specific configuration\n * @param config The configuration to validate\n * @returns true if configuration is valid, false otherwise\n */\n abstract validateConfig(config: unknown): Promise<boolean>;\n\n /**\n * Execute the check on the given PR information\n * @param prInfo Information about the pull request\n * @param config Provider-specific configuration\n * @param dependencyResults Optional results from dependency checks that this check depends on\n * @param context Optional execution context with session info, hooks, and CLI state\n * @returns Review summary with scores, issues, and comments\n */\n abstract execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary>;\n\n /**\n * Get the list of configuration keys this provider supports\n * Used for documentation and validation\n */\n abstract getSupportedConfigKeys(): string[];\n\n /**\n * Check if this provider is available (e.g., has required API keys)\n * @returns true if provider can be used, false otherwise\n */\n abstract isAvailable(): Promise<boolean>;\n\n /**\n * Get provider requirements (e.g., environment variables needed)\n */\n abstract getRequirements(): string[];\n\n /**\n * Set webhook context for providers that need access to webhook data\n * This is optional and only used by http_input providers\n * @param webhookContext Map of endpoint paths to webhook data\n */\n setWebhookContext?(webhookContext: Map<string, unknown>): void;\n}\n","import { extract } from '@probelabs/probe';\nimport * as path from 'path';\n\n/**\n * Process diff content using the outline-diff format from @probelabs/probe\n * This extracts a structured outline from the diff without requiring a temporary file\n */\nexport async function processDiffWithOutline(diffContent: string): Promise<string> {\n if (!diffContent || diffContent.trim().length === 0) {\n return diffContent;\n }\n\n try {\n // Set PROBE_PATH to use the bundled binary with outline-diff support\n // The SDK by default may download an older binary that doesn't support outline-diff\n const originalProbePath = process.env.PROBE_PATH;\n\n // Try multiple possible locations for the probe binary\n // When bundled with ncc, __dirname may not be reliable\n const fs = require('fs');\n const possiblePaths = [\n // Relative to current working directory (most common in production)\n path.join(process.cwd(), 'node_modules/@probelabs/probe/bin/probe-binary'),\n // Relative to __dirname (for unbundled development)\n path.join(__dirname, '../..', 'node_modules/@probelabs/probe/bin/probe-binary'),\n // Relative to dist directory (for bundled CLI)\n path.join(__dirname, 'node_modules/@probelabs/probe/bin/probe-binary'),\n ];\n\n let probeBinaryPath: string | undefined;\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n probeBinaryPath = candidatePath;\n break;\n }\n }\n\n // Only process if binary exists, otherwise fall back to original diff\n if (!probeBinaryPath) {\n if (process.env.DEBUG === '1' || process.env.VERBOSE === '1') {\n console.error('Probe binary not found. Tried:', possiblePaths);\n }\n return diffContent;\n }\n\n process.env.PROBE_PATH = probeBinaryPath;\n\n // Use extract with content parameter (can be string or Buffer)\n // The TypeScript types haven't been updated yet, but the runtime supports it\n // Add timeout to avoid hanging\n const extractPromise = (extract as any)({\n content: diffContent,\n format: 'outline-diff',\n allowTests: true, // Allow test files and test code blocks in extraction results\n });\n\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Extract timeout after 30s')), 30000);\n });\n\n const result = await Promise.race([extractPromise, timeoutPromise]);\n\n // Restore original PROBE_PATH\n if (originalProbePath !== undefined) {\n process.env.PROBE_PATH = originalProbePath;\n } else {\n delete process.env.PROBE_PATH;\n }\n\n // Return the processed outline diff\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n // If outline-diff processing fails, fall back to the original diff\n // Use console.error instead of console.warn to avoid polluting JSON output\n if (process.env.DEBUG === '1' || process.env.VERBOSE === '1') {\n console.error('Failed to process diff with outline-diff format:', error);\n }\n return diffContent;\n }\n}\n","/**\n * Utility functions for parsing and handling Visor comment metadata\n */\n\n/**\n * Parse visor:thread metadata from a comment body\n * Reuses the same regex pattern from github-frontend.ts for consistency\n */\nexport function parseVisorThreadMetadata(\n commentBody: string\n): { group?: string; [key: string]: any } | null {\n const headerRe = /<!--\\s*visor:thread=(\\{[\\s\\S]*?\\})\\s*-->/m;\n const match = headerRe.exec(commentBody);\n\n if (!match) {\n return null;\n }\n\n try {\n const metadata = JSON.parse(match[1]);\n return metadata && typeof metadata === 'object' && !Array.isArray(metadata) ? metadata : null;\n } catch {\n // If parsing fails, return null (graceful handling)\n return null;\n }\n}\n\n/**\n * Check if a comment should be filtered out when building AI context for code reviews.\n * This filters Visor's own review comments to avoid bias, while keeping user comments\n * and non-review Visor comments (like overview).\n *\n * @param commentBody - The body text of the comment\n * @returns true if the comment should be filtered out (excluded from AI context)\n */\nexport function shouldFilterVisorReviewComment(commentBody: string | undefined): boolean {\n if (!commentBody) {\n return false;\n }\n\n // Old format: check for visor-comment-id:pr-review- pattern\n if (commentBody.includes('visor-comment-id:pr-review-')) {\n return true;\n }\n\n // New format: check for visor:thread metadata with group=\"review\"\n const metadata = parseVisorThreadMetadata(commentBody);\n if (metadata && metadata.group === 'review') {\n return true;\n }\n\n return false;\n}\n","import { ProbeAgent } from '@probelabs/probe';\nimport type { ProbeAgentOptions } from '@probelabs/probe';\nimport { PRInfo } from './pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from './reviewer';\nimport { SessionRegistry } from './session-registry';\nimport { logger } from './logger';\nimport { initializeTracer } from './utils/tracer-init';\nimport { processDiffWithOutline } from './utils/diff-processor';\nimport { shouldFilterVisorReviewComment } from './utils/comment-metadata';\n\n/**\n * Helper function to log debug messages using the centralized logger\n */\nfunction log(...args: unknown[]): void {\n logger.debug(args.join(' '));\n}\n\n/**\n * Extended ProbeAgent interface that includes tracing properties\n */\ninterface TracedProbeAgent extends ProbeAgent {\n tracer?: unknown; // SimpleTelemetry tracer (probe removed AppTracer)\n _telemetryConfig?: unknown; // SimpleTelemetry config (probe removed TelemetryConfig)\n _traceFilePath?: string;\n}\n\n/**\n * Extended ProbeAgentOptions interface that includes tracing properties\n */\ninterface TracedProbeAgentOptions extends ProbeAgentOptions {\n tracer?: unknown; // SimpleTelemetry tracer\n _telemetryConfig?: unknown; // SimpleTelemetry config\n _traceFilePath?: string;\n customPrompt?: string;\n}\n\nexport interface AIReviewConfig {\n apiKey?: string; // From env: GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, CLAUDE_CODE_API_KEY, or AWS credentials\n model?: string; // From env: MODEL_NAME (e.g., gemini-2.5-pro-preview-06-05)\n timeout?: number; // Default: 600000ms (10 minutes)\n provider?: 'google' | 'anthropic' | 'openai' | 'bedrock' | 'mock' | 'claude-code';\n debug?: boolean; // Enable debug mode\n tools?: Array<{ name: string; [key: string]: unknown }>; // (unused) Legacy tool listing\n // Pass-through MCP server configuration for ProbeAgent\n mcpServers?: Record<string, import('./types/config').McpServerConfig>;\n // Enable delegate tool for task distribution to subagents\n enableDelegate?: boolean;\n // ProbeAgent persona/prompt family (e.g., 'engineer', 'code-review', 'architect')\n promptType?: string;\n // System prompt to prepend (baseline/preamble). Replaces legacy customPrompt\n systemPrompt?: string;\n // Backward-compat: legacy key still accepted internally\n customPrompt?: string;\n // Retry configuration for AI provider calls\n retry?: import('./types/config').AIRetryConfig;\n // Fallback configuration for provider failures\n fallback?: import('./types/config').AIFallbackConfig;\n // Enable Edit and Create tools for file modification\n allowEdit?: boolean;\n // Filter allowed tools - supports whitelist, exclusion (!prefix), or raw AI mode (empty array)\n allowedTools?: string[];\n // Disable all tools for raw AI mode (alternative to allowedTools: [])\n disableTools?: boolean;\n // Enable bash command execution (shorthand for bashConfig.enabled)\n allowBash?: boolean;\n // Advanced bash command execution configuration\n bashConfig?: import('./types/config').BashConfig;\n}\n\nexport interface AIDebugInfo {\n /** The prompt sent to the AI */\n prompt: string;\n /** Raw response from the AI service */\n rawResponse: string;\n /** Provider used (google, anthropic, openai) */\n provider: string;\n /** Model used */\n model: string;\n /** API key source (for privacy, just show which env var) */\n apiKeySource: string;\n /** Processing time in milliseconds */\n processingTime: number;\n /** Prompt length in characters */\n promptLength: number;\n /** Response length in characters */\n responseLength: number;\n /** Any errors encountered */\n errors?: string[];\n /** Whether JSON parsing succeeded */\n jsonParseSuccess: boolean;\n /** Schema used for response validation */\n schema?: string;\n /** Schema name/type requested */\n schemaName?: string;\n /** Checks executed during this review */\n checksExecuted?: string[];\n /** Whether parallel execution was used */\n parallelExecution?: boolean;\n /** Timestamp when request was made */\n timestamp: string;\n /** Total API calls made */\n totalApiCalls?: number;\n /** Details about API calls made */\n apiCallDetails?: Array<{\n checkName: string;\n provider: string;\n model: string;\n processingTime: number;\n success: boolean;\n }>;\n}\n\n// REMOVED: ReviewFocus type - only use custom prompts from .visor.yaml\n\ninterface AIResponseFormat {\n // Array of issues for code review\n issues?: Array<{\n file: string;\n line: number;\n endLine?: number;\n ruleId: string;\n message: string;\n severity: 'info' | 'warning' | 'error' | 'critical';\n category: 'security' | 'performance' | 'style' | 'logic' | 'documentation';\n suggestion?: string;\n replacement?: string;\n }>;\n}\n\nexport class AIReviewService {\n private config: AIReviewConfig;\n private sessionRegistry: SessionRegistry;\n\n constructor(config: AIReviewConfig = {}) {\n this.config = {\n timeout: 600000, // Increased timeout to 10 minutes for AI responses\n ...config,\n };\n\n this.sessionRegistry = SessionRegistry.getInstance();\n\n // If debug was not explicitly provided, honor standard env flags so tests/CLI\n // can enable provider-level debug without modifying per-check configs.\n if (typeof this.config.debug === 'undefined') {\n try {\n if (process.env.VISOR_PROVIDER_DEBUG === 'true' || process.env.VISOR_DEBUG === 'true') {\n this.config.debug = true;\n }\n } catch {}\n }\n\n // Respect explicit provider if set (e.g., 'mock' during tests) — do not override from env\n const providerExplicit =\n typeof this.config.provider === 'string' && this.config.provider.length > 0;\n\n // Auto-detect provider and API key from environment only when provider not explicitly set\n if (!providerExplicit) {\n if (!this.config.apiKey) {\n if (process.env.CLAUDE_CODE_API_KEY) {\n this.config.apiKey = process.env.CLAUDE_CODE_API_KEY;\n this.config.provider = 'claude-code';\n } else if (process.env.GOOGLE_API_KEY) {\n this.config.apiKey = process.env.GOOGLE_API_KEY;\n this.config.provider = 'google';\n } else if (process.env.ANTHROPIC_API_KEY) {\n this.config.apiKey = process.env.ANTHROPIC_API_KEY;\n this.config.provider = 'anthropic';\n } else if (process.env.OPENAI_API_KEY) {\n this.config.apiKey = process.env.OPENAI_API_KEY;\n this.config.provider = 'openai';\n } else if (\n // Check for AWS Bedrock credentials\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_BEDROCK_API_KEY\n ) {\n // For Bedrock, we don't set apiKey as it uses AWS credentials\n // ProbeAgent will handle the authentication internally\n this.config.provider = 'bedrock';\n // Set a placeholder to pass validation\n this.config.apiKey = 'AWS_CREDENTIALS';\n }\n }\n }\n\n // Auto-detect model from environment\n if (!this.config.model && process.env.MODEL_NAME) {\n this.config.model = process.env.MODEL_NAME;\n }\n }\n\n // NOTE: per request, no additional redaction/encryption helpers are used.\n\n /**\n * Execute AI review using probe agent\n */\n async executeReview(\n prInfo: PRInfo,\n customPrompt: string,\n schema?: string | Record<string, unknown>,\n checkName?: string,\n sessionId?: string\n ): Promise<ReviewSummary> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Build prompt from custom instructions\n // Respect provider-level skip_code_context by skipping PR context wrapper when requested\n const prompt = await this.buildCustomPrompt(prInfo, customPrompt, schema, {\n skipPRContext: (this.config as any)?.skip_code_context === true,\n });\n\n log(`Executing AI review with ${this.config.provider} provider...`);\n log(`🔧 Debug: Raw schema parameter: ${JSON.stringify(schema)} (type: ${typeof schema})`);\n log(`Schema type: ${schema || 'none (no schema)'}`);\n\n let debugInfo: AIDebugInfo | undefined;\n if (this.config.debug) {\n debugInfo = {\n prompt,\n rawResponse: '',\n provider: this.config.provider || 'unknown',\n model: this.config.model || 'default',\n apiKeySource: this.getApiKeySource(),\n processingTime: 0,\n promptLength: prompt.length,\n responseLength: 0,\n errors: [],\n jsonParseSuccess: false,\n timestamp,\n schemaName: typeof schema === 'object' ? 'custom' : schema,\n schema: undefined, // Will be populated when schema is loaded\n };\n }\n\n // Handle mock model/provider first (no API key needed)\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n log('🎭 Using mock AI model/provider for testing - skipping API key validation');\n } else {\n // Hydrate API key from environment even when provider is explicitly set\n if (!this.config.apiKey) {\n try {\n if (this.config.provider === 'google' && process.env.GOOGLE_API_KEY) {\n this.config.apiKey = process.env.GOOGLE_API_KEY;\n } else if (this.config.provider === 'anthropic' && process.env.ANTHROPIC_API_KEY) {\n this.config.apiKey = process.env.ANTHROPIC_API_KEY;\n } else if (this.config.provider === 'openai' && process.env.OPENAI_API_KEY) {\n this.config.apiKey = process.env.OPENAI_API_KEY;\n } else if (this.config.provider === 'claude-code' && process.env.CLAUDE_CODE_API_KEY) {\n this.config.apiKey = process.env.CLAUDE_CODE_API_KEY;\n }\n } catch {}\n }\n // Check if API key is available for real AI models\n if (!this.config.apiKey) {\n const errorMessage =\n 'No API key configured. Please set GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY environment variable, or configure AWS credentials for Bedrock (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY).';\n\n // In debug mode, proceed to call the (mocked) provider so tests can assert prompt/session behavior\n if (debugInfo) {\n debugInfo.errors = [errorMessage];\n debugInfo.rawResponse = 'API call attempted in debug without API key (test mode)';\n // Continue without returning; ProbeAgent is typically mocked under tests.\n } else {\n throw new Error(errorMessage);\n }\n }\n }\n\n try {\n const call = this.callProbeAgent(prompt, schema, debugInfo, checkName, sessionId);\n const timeoutMs = Math.max(0, this.config.timeout || 0);\n const { response, effectiveSchema } =\n timeoutMs > 0 ? await this.withTimeout(call, timeoutMs, 'AI review') : await call;\n const processingTime = Date.now() - startTime;\n\n if (debugInfo) {\n debugInfo.rawResponse = response;\n debugInfo.responseLength = response.length;\n debugInfo.processingTime = processingTime;\n }\n\n const result = this.parseAIResponse(response, debugInfo, effectiveSchema);\n\n if (debugInfo) {\n result.debug = debugInfo;\n }\n\n return result;\n } catch (error) {\n if (debugInfo) {\n debugInfo.errors = [error instanceof Error ? error.message : String(error)];\n debugInfo.processingTime = Date.now() - startTime;\n\n // In debug mode, return a review with the error captured\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'system/ai-execution-error',\n message: error instanceof Error ? error.message : String(error),\n severity: 'error',\n category: 'logic',\n },\n ],\n debug: debugInfo,\n };\n }\n throw error;\n }\n }\n\n /**\n * Execute AI review using session reuse - reuses an existing ProbeAgent session\n * @param sessionMode - 'clone' (default) clones history, 'append' shares history\n */\n async executeReviewWithSessionReuse(\n prInfo: PRInfo,\n customPrompt: string,\n parentSessionId: string,\n schema?: string | Record<string, unknown>,\n checkName?: string,\n sessionMode: 'clone' | 'append' = 'clone'\n ): Promise<ReviewSummary> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Ensure API key is hydrated from environment for explicit providers\n if (!this.config.apiKey) {\n try {\n if (this.config.provider === 'google' && process.env.GOOGLE_API_KEY) {\n this.config.apiKey = process.env.GOOGLE_API_KEY;\n } else if (this.config.provider === 'anthropic' && process.env.ANTHROPIC_API_KEY) {\n this.config.apiKey = process.env.ANTHROPIC_API_KEY;\n } else if (this.config.provider === 'openai' && process.env.OPENAI_API_KEY) {\n this.config.apiKey = process.env.OPENAI_API_KEY;\n } else if (this.config.provider === 'claude-code' && process.env.CLAUDE_CODE_API_KEY) {\n this.config.apiKey = process.env.CLAUDE_CODE_API_KEY;\n }\n } catch {}\n }\n // Get the existing session\n const existingAgent = this.sessionRegistry.getSession(parentSessionId);\n if (!existingAgent) {\n throw new Error(\n `Session not found for reuse: ${parentSessionId}. Ensure the parent check completed successfully.`\n );\n }\n\n // Build prompt from custom instructions\n // When reusing session, skip PR context since it's already in the conversation history\n const prompt = await this.buildCustomPrompt(prInfo, customPrompt, schema, {\n skipPRContext: true,\n });\n\n // Determine which agent to use based on session mode\n let agentToUse: typeof existingAgent;\n let currentSessionId: string;\n\n if (sessionMode === 'clone') {\n // Clone the session - creates a new agent with copied history\n // Include check name in the session ID for better tracing\n currentSessionId = `${checkName}-session-${Date.now()}`;\n log(\n `📋 Cloning AI session ${parentSessionId} → ${currentSessionId} for ${checkName} check...`\n );\n\n const clonedAgent = await this.sessionRegistry.cloneSession(\n parentSessionId,\n currentSessionId,\n checkName // Pass checkName for tracing\n );\n if (!clonedAgent) {\n throw new Error(`Failed to clone session ${parentSessionId}`);\n }\n agentToUse = clonedAgent;\n } else {\n // Append mode - use the same agent instance\n log(`🔄 Appending to AI session ${parentSessionId} (shared history)...`);\n agentToUse = existingAgent;\n currentSessionId = parentSessionId;\n }\n\n log(`🔧 Debug: Raw schema parameter: ${JSON.stringify(schema)} (type: ${typeof schema})`);\n log(`📋 Schema for this check: ${schema || 'none (no schema)'}`);\n if (sessionMode === 'clone') {\n log(`✅ Cloned agent will use NEW schema (${schema}) - parent schema does not persist`);\n log(`🔄 Clone operation ensures fresh agent with copied history but new configuration`);\n } else {\n log(`🔄 Append mode - using existing agent instance with shared history and configuration`);\n }\n\n let debugInfo: AIDebugInfo | undefined;\n if (this.config.debug) {\n debugInfo = {\n prompt,\n rawResponse: '',\n provider: this.config.provider || 'unknown',\n model: this.config.model || 'default',\n apiKeySource: this.getApiKeySource(),\n processingTime: 0,\n promptLength: prompt.length,\n responseLength: 0,\n errors: [],\n jsonParseSuccess: false,\n timestamp,\n schemaName: typeof schema === 'object' ? 'custom' : schema,\n schema: undefined, // Will be populated when schema is loaded\n };\n }\n\n try {\n // Use the determined agent (cloned or original)\n const call = this.callProbeAgentWithExistingSession(\n agentToUse,\n prompt,\n schema,\n debugInfo,\n checkName\n );\n const timeoutMs = Math.max(0, this.config.timeout || 0);\n const { response, effectiveSchema } =\n timeoutMs > 0 ? await this.withTimeout(call, timeoutMs, 'AI review (session)') : await call;\n const processingTime = Date.now() - startTime;\n\n if (debugInfo) {\n debugInfo.rawResponse = response;\n debugInfo.responseLength = response.length;\n debugInfo.processingTime = processingTime;\n }\n\n const result = this.parseAIResponse(response, debugInfo, effectiveSchema);\n\n // Expose the session ID used for this call so the engine can clean it up\n try {\n (result as any).sessionId = currentSessionId;\n } catch {}\n\n if (debugInfo) {\n result.debug = debugInfo;\n }\n\n // Include the session ID in the result for cleanup tracking\n // Only include if we created a new cloned session\n if (sessionMode === 'clone' && currentSessionId !== parentSessionId) {\n result.sessionId = currentSessionId;\n }\n\n return result;\n } catch (error) {\n if (debugInfo) {\n debugInfo.errors = [error instanceof Error ? error.message : String(error)];\n debugInfo.processingTime = Date.now() - startTime;\n\n // In debug mode, return a review with the error captured\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'system/ai-session-reuse-error',\n message: error instanceof Error ? error.message : String(error),\n severity: 'error',\n category: 'logic',\n },\n ],\n debug: debugInfo,\n };\n }\n throw error;\n }\n }\n\n /**\n * Promise timeout helper that rejects after ms if unresolved\n */\n private async withTimeout<T>(p: Promise<T>, ms: number, label = 'operation'): Promise<T> {\n let timer: NodeJS.Timeout | undefined;\n try {\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);\n });\n return (await Promise.race([p, timeout])) as T;\n } finally {\n if (timer) clearTimeout(timer);\n }\n }\n\n /**\n * Register a new AI session in the session registry\n */\n registerSession(sessionId: string, agent: TracedProbeAgent): void {\n this.sessionRegistry.registerSession(sessionId, agent);\n }\n\n /**\n * Cleanup a session from the registry\n */\n cleanupSession(sessionId: string): void {\n this.sessionRegistry.unregisterSession(sessionId);\n }\n\n /**\n * Build a custom prompt for AI review with XML-formatted data\n */\n private async buildCustomPrompt(\n prInfo: PRInfo,\n customInstructions: string,\n schema?: string | Record<string, unknown>,\n options?: { skipPRContext?: boolean; checkName?: string }\n ): Promise<string> {\n // When reusing sessions, skip PR context to avoid sending duplicate diff data\n const skipPRContext = options?.skipPRContext === true;\n\n // Check if we're using the code-review schema\n const isCodeReviewSchema = schema === 'code-review';\n\n const prContext = skipPRContext ? '' : await this.formatPRContext(prInfo, isCodeReviewSchema);\n const isIssue = (prInfo as PRInfo & { isIssue?: boolean }).isIssue === true;\n\n if (isIssue) {\n // Issue context - no code analysis needed\n if (skipPRContext) {\n // Session reuse: just send new instructions\n return `<instructions>\n${customInstructions}\n</instructions>`;\n }\n\n return `<review_request>\n <instructions>\n${customInstructions}\n </instructions>\n\n <context>\n${prContext}\n </context>\n\n <rules>\n <rule>Understand the issue context and requirements from the XML data structure</rule>\n <rule>Provide helpful, actionable guidance based on the issue details</rule>\n <rule>Be constructive and supportive in your analysis</rule>\n <rule>Consider project conventions and patterns when making recommendations</rule>\n <rule>Suggest practical solutions or next steps that address the specific concern</rule>\n <rule>Focus on addressing the specific concern raised in the issue</rule>\n <rule>Reference relevant XML elements like metadata, description, labels, assignees when providing context</rule>\n </rules>\n</review_request>`;\n }\n\n // Only add review_request wrapper and PR-specific rules for code-review schema\n if (isCodeReviewSchema) {\n // PR context with code-review schema - structured XML format\n const analysisType = prInfo.isIncremental ? 'INCREMENTAL' : 'FULL';\n\n if (skipPRContext) {\n // Session reuse: just send new instructions without repeating the context\n return `<instructions>\n${customInstructions}\n</instructions>\n\n<reminder>\n <rule>The code context and diff were provided in the previous message</rule>\n <rule>Focus on the new analysis instructions above</rule>\n <rule>Only analyze code that appears with + (additions) or - (deletions) in the diff sections</rule>\n <rule>STRICT OUTPUT POLICY: Report only actual problems, risks, or deficiencies</rule>\n <rule>SEVERITY ASSIGNMENT: Assign severity ONLY to problems introduced or left unresolved by this change</rule>\n</reminder>`;\n }\n\n return `<review_request>\n <analysis_type>${analysisType}</analysis_type>\n\n <analysis_focus>\n ${\n analysisType === 'INCREMENTAL'\n ? 'You are analyzing a NEW COMMIT added to an existing PR. Focus on the changes in the commit_diff section for this specific commit.'\n : 'You are analyzing the COMPLETE PR. Review all changes in the full_diff section.'\n }\n </analysis_focus>\n\n <instructions>\n${customInstructions}\n </instructions>\n\n <context>\n${prContext}\n </context>\n\n <rules>\n <rule>Only analyze code that appears with + (additions) or - (deletions) in the diff sections</rule>\n <rule>Ignore unchanged code unless directly relevant to understanding a change</rule>\n <rule>Line numbers in your response should match actual file line numbers from the diff</rule>\n <rule>Focus on real issues, not nitpicks or cosmetic concerns</rule>\n <rule>Provide actionable, specific feedback with clear remediation steps</rule>\n <rule>For INCREMENTAL analysis, ONLY review changes in commit_diff section</rule>\n <rule>For FULL analysis, review all changes in full_diff section</rule>\n <rule>Reference specific XML elements like files_summary, metadata when providing context</rule>\n <rule>STRICT OUTPUT POLICY: Report only actual problems, risks, or deficiencies. Do not write praise, congratulations, or celebratory text. Do not create issues that merely restate improvements or say \"no action needed\".</rule>\n <rule>SEVERITY ASSIGNMENT: Assign severity ONLY to problems introduced or left unresolved by this change (critical/error/warning/info as appropriate). Do NOT create issue entries solely to acknowledge improvements; if no problems exist, return zero issues.</rule>\n </rules>\n</review_request>`;\n }\n\n // For non-code-review schemas, just provide instructions and context without review-specific wrapper\n if (skipPRContext) {\n // Session reuse: just send new instructions\n return `<instructions>\n${customInstructions}\n</instructions>`;\n }\n\n return `<instructions>\n${customInstructions}\n</instructions>\n\n<context>\n${prContext}\n</context>`;\n }\n\n // REMOVED: Built-in prompts - only use custom prompts from .visor.yaml\n\n // REMOVED: getFocusInstructions - only use custom prompts from .visor.yaml\n\n /**\n * Format PR or Issue context for the AI using XML structure\n */\n private async formatPRContext(prInfo: PRInfo, isCodeReviewSchema?: boolean): Promise<string> {\n // Check if this is an issue (not a PR)\n const prContextInfo = prInfo as PRInfo & {\n isPRContext?: boolean;\n includeCodeContext?: boolean;\n };\n const isIssue = prContextInfo.isIssue === true;\n\n // Check if we should include code context (diffs)\n const isPRContext = prContextInfo.isPRContext === true;\n // In PR context, always include diffs. Otherwise check the flag.\n const includeCodeContext = isPRContext || prContextInfo.includeCodeContext !== false;\n\n // Log the decision for transparency (debug level)\n if (isPRContext) {\n log('🔍 Including full code diffs in AI context (PR mode)');\n } else if (!includeCodeContext) {\n log('📊 Including only file summary in AI context (no diffs)');\n } else {\n log('🔍 Including code diffs in AI context');\n }\n\n if (isIssue) {\n // Format as issue context\n let context = `<issue>\n <!-- Core issue metadata including identification, status, and timeline information -->\n <metadata>\n <number>${prInfo.number}</number>\n <title>${this.escapeXml(prInfo.title)}</title>\n <author>${prInfo.author}</author>\n <state>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; created_at?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.state || 'open'}</state>\n <created_at>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; created_at?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.created_at || ''}</created_at>\n <updated_at>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.updated_at || ''}</updated_at>\n <comments_count>${(prInfo as PRInfo & { eventContext?: { issue?: { comments?: number } } }).eventContext?.issue?.comments || 0}</comments_count>\n </metadata>`;\n\n // Add issue body/description if available\n if (prInfo.body) {\n context += `\n <!-- Full issue description and body text provided by the issue author -->\n <description>\n${this.escapeXml(prInfo.body)}\n </description>`;\n }\n\n // Add labels if available\n const eventContext = prInfo as PRInfo & {\n eventContext?: { issue?: { labels?: Array<{ name?: string } | string> } };\n };\n const labels = eventContext.eventContext?.issue?.labels;\n if (labels && labels.length > 0) {\n context += `\n <!-- Applied labels for issue categorization and organization -->\n <labels>`;\n labels.forEach((label: { name?: string } | string) => {\n const labelName = typeof label === 'string' ? label : label.name || 'unknown';\n context += `\n <label>${this.escapeXml(labelName)}</label>`;\n });\n context += `\n </labels>`;\n }\n\n // Add assignees if available\n const assignees = (\n prInfo as PRInfo & {\n eventContext?: { issue?: { assignees?: Array<{ login?: string } | string> } };\n }\n ).eventContext?.issue?.assignees;\n if (assignees && assignees.length > 0) {\n context += `\n <!-- Users assigned to work on this issue -->\n <assignees>`;\n assignees.forEach((assignee: { login?: string } | string) => {\n const assigneeName =\n typeof assignee === 'string' ? assignee : assignee.login || 'unknown';\n context += `\n <assignee>${this.escapeXml(assigneeName)}</assignee>`;\n });\n context += `\n </assignees>`;\n }\n\n // Add milestone if available\n const milestone = (\n prInfo as PRInfo & {\n eventContext?: {\n issue?: { milestone?: { title?: string; state?: string; due_on?: string } };\n };\n }\n ).eventContext?.issue?.milestone;\n if (milestone) {\n context += `\n <!-- Associated project milestone information -->\n <milestone>\n <title>${this.escapeXml(milestone.title || '')}</title>\n <state>${milestone.state || 'open'}</state>\n <due_on>${milestone.due_on || ''}</due_on>\n </milestone>`;\n }\n\n // Add current/triggering comment if this is a comment event\n const triggeringComment = (\n prInfo as PRInfo & {\n eventContext?: {\n comment?: {\n user?: { login?: string };\n created_at?: string;\n body?: string;\n id?: number;\n };\n };\n }\n ).eventContext?.comment;\n if (triggeringComment) {\n context += `\n <!-- The comment that triggered this analysis -->\n <triggering_comment>\n <author>${this.escapeXml(triggeringComment.user?.login || 'unknown')}</author>\n <created_at>${triggeringComment.created_at || ''}</created_at>\n <body>${this.escapeXml(triggeringComment.body || '')}</body>\n </triggering_comment>`;\n }\n\n // Add comment history (excluding the current comment if it exists)\n const issueComments = (\n prInfo as PRInfo & {\n comments?: Array<{ id?: number; author?: string; body?: string; createdAt?: string }>;\n }\n ).comments;\n if (issueComments && issueComments.length > 0) {\n // Filter out the triggering comment from history if present\n let historicalComments = triggeringComment\n ? issueComments.filter(c => c.id !== triggeringComment.id)\n : issueComments;\n\n // For code-review schema checks, filter out previous Visor code-review comments to avoid self-bias\n // Old format: <!-- visor-comment-id:pr-review-244-review -->\n // New format: <!-- visor:thread={\"key\":\"...\",\"group\":\"review\",...} -->\n if (isCodeReviewSchema) {\n historicalComments = historicalComments.filter(\n c => !shouldFilterVisorReviewComment(c.body)\n );\n }\n\n if (historicalComments.length > 0) {\n context += `\n <!-- Previous comments in chronological order (excluding triggering comment) -->\n <comment_history>`;\n historicalComments.forEach(comment => {\n context += `\n <comment>\n <author>${this.escapeXml(comment.author || 'unknown')}</author>\n <created_at>${comment.createdAt || ''}</created_at>\n <body>${this.escapeXml(comment.body || '')}</body>\n </comment>`;\n });\n context += `\n </comment_history>`;\n }\n }\n\n // Close the issue tag\n context += `\n</issue>`;\n\n return context;\n }\n\n // Original PR context formatting\n let context = `<pull_request>\n <!-- Core pull request metadata including identification, branches, and change statistics -->\n <metadata>\n <number>${prInfo.number}</number>\n <title>${this.escapeXml(prInfo.title)}</title>\n <author>${prInfo.author}</author>\n <base_branch>${prInfo.base}</base_branch>\n <target_branch>${prInfo.head}</target_branch>\n <total_additions>${prInfo.totalAdditions}</total_additions>\n <total_deletions>${prInfo.totalDeletions}</total_deletions>\n <files_changed_count>${prInfo.files.length}</files_changed_count>\n </metadata>`;\n\n // Include a small raw diff header snippet for compatibility with tools/tests\n try {\n const firstFile = (prInfo.files || [])[0];\n if (firstFile && firstFile.filename) {\n context += `\\n <raw_diff_header>\\n${this.escapeXml(`diff --git a/${firstFile.filename} b/${firstFile.filename}`)}\\n </raw_diff_header>`;\n }\n } catch {}\n\n // Add PR description if available\n if (prInfo.body) {\n context += `\n <!-- Full pull request description provided by the author -->\n <description>\n${this.escapeXml(prInfo.body)}\n </description>`;\n }\n\n // Add diffs only if includeCodeContext is true (or in PR mode)\n if (includeCodeContext) {\n // Add full diff if available (for complete PR review)\n if (prInfo.fullDiff) {\n // Process the diff with outline-diff format for better structure\n const processedFullDiff = await processDiffWithOutline(prInfo.fullDiff);\n context += `\n <!-- Complete unified diff showing all changes in the pull request (processed with outline-diff) -->\n <full_diff>\n${this.escapeXml(processedFullDiff)}\n </full_diff>`;\n }\n\n // Add incremental commit diff if available (for new commit analysis)\n if (prInfo.isIncremental) {\n if (prInfo.commitDiff && prInfo.commitDiff.length > 0) {\n // Process the commit diff with outline-diff format for better structure\n const processedCommitDiff = await processDiffWithOutline(prInfo.commitDiff);\n context += `\n <!-- Diff of only the latest commit for incremental analysis (processed with outline-diff) -->\n <commit_diff>\n${this.escapeXml(processedCommitDiff)}\n </commit_diff>`;\n } else {\n // Process the fallback full diff with outline-diff format\n const processedFallbackDiff = prInfo.fullDiff\n ? await processDiffWithOutline(prInfo.fullDiff)\n : '';\n context += `\n <!-- Commit diff could not be retrieved - falling back to full diff analysis (processed with outline-diff) -->\n <commit_diff>\n${this.escapeXml(processedFallbackDiff)}\n </commit_diff>`;\n }\n }\n } else {\n // When not including diffs, add a note about it\n context += `\n <!-- Code diffs excluded to reduce token usage (no code-review schema detected or disabled by flag) -->`;\n }\n\n // Add file summary for context\n if (prInfo.files.length > 0) {\n context += `\n <!-- Summary of all files changed with statistics -->\n <files_summary>`;\n prInfo.files.forEach(file => {\n context += `\n <file>\n <filename>${this.escapeXml(file.filename)}</filename>\n <status>${file.status}</status>\n <additions>${file.additions}</additions>\n <deletions>${file.deletions}</deletions>\n </file>`;\n });\n context += `\n </files_summary>`;\n }\n\n // Add current/triggering comment if this is a comment event\n const triggeringComment = (\n prInfo as PRInfo & {\n eventContext?: {\n comment?: { user?: { login?: string }; created_at?: string; body?: string; id?: number };\n };\n }\n ).eventContext?.comment;\n if (triggeringComment) {\n context += `\n <!-- The comment that triggered this analysis -->\n <triggering_comment>\n <author>${this.escapeXml(triggeringComment.user?.login || 'unknown')}</author>\n <created_at>${triggeringComment.created_at || ''}</created_at>\n <body>${this.escapeXml(triggeringComment.body || '')}</body>\n </triggering_comment>`;\n }\n\n // Add comment history (excluding the current comment if it exists)\n const prComments = (\n prInfo as PRInfo & {\n comments?: Array<{ id?: number; author?: string; body?: string; createdAt?: string }>;\n }\n ).comments;\n if (prComments && prComments.length > 0) {\n // Filter out the triggering comment from history if present\n let historicalComments = triggeringComment\n ? prComments.filter(c => c.id !== triggeringComment.id)\n : prComments;\n\n // For code-review schema checks, filter out previous Visor code-review comments to avoid self-bias\n // Old format: <!-- visor-comment-id:pr-review-244-review -->\n // New format: <!-- visor:thread={\"key\":\"...\",\"group\":\"review\",...} -->\n if (isCodeReviewSchema) {\n historicalComments = historicalComments.filter(\n c => !shouldFilterVisorReviewComment(c.body)\n );\n }\n\n if (historicalComments.length > 0) {\n context += `\n <!-- Previous PR comments in chronological order (excluding triggering comment) -->\n <comment_history>`;\n historicalComments.forEach(comment => {\n context += `\n <comment>\n <author>${this.escapeXml(comment.author || 'unknown')}</author>\n <created_at>${comment.createdAt || ''}</created_at>\n <body>${this.escapeXml(comment.body || '')}</body>\n </comment>`;\n });\n context += `\n </comment_history>`;\n }\n }\n\n context += `\n</pull_request>`;\n\n return context;\n }\n\n /**\n * No longer escaping XML - returning text as-is\n */\n private escapeXml(text: string): string {\n return text;\n }\n\n /**\n * Call ProbeAgent with an existing session\n */\n private async callProbeAgentWithExistingSession(\n agent: TracedProbeAgent,\n prompt: string,\n schema?: string | Record<string, unknown>,\n debugInfo?: AIDebugInfo,\n _checkName?: string\n ): Promise<{ response: string; effectiveSchema?: string }> {\n // Handle mock model/provider for testing\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n log('🎭 Using mock AI model/provider for testing (session reuse)');\n const response = await this.generateMockResponse(prompt, _checkName, schema);\n return { response, effectiveSchema: typeof schema === 'object' ? 'custom' : schema };\n }\n\n log('🔄 Reusing existing ProbeAgent session for AI review...');\n log(`📝 Prompt length: ${prompt.length} characters`);\n log(`⚙️ Model: ${this.config.model || 'default'}, Provider: ${this.config.provider || 'auto'}`);\n\n try {\n log('🚀 Calling existing ProbeAgent with answer()...');\n\n // Load and pass the actual schema content if provided (skip for plain schema)\n let schemaString: string | undefined = undefined;\n let effectiveSchema: string | undefined = typeof schema === 'object' ? 'custom' : schema;\n\n if (schema && schema !== 'plain') {\n try {\n schemaString = await this.loadSchemaContent(schema);\n log(`📋 Loaded schema content for: ${schema}`);\n log(`📄 Raw schema JSON:\\n${schemaString}`);\n } catch (error) {\n log(`⚠️ Failed to load schema ${schema}, proceeding without schema:`, error);\n schemaString = undefined;\n effectiveSchema = undefined; // Schema loading failed, treat as no schema\n if (debugInfo && debugInfo.errors) {\n debugInfo.errors.push(`Failed to load schema: ${error}`);\n }\n }\n } else if (schema === 'plain') {\n log(`📋 Using plain schema - no JSON validation will be applied`);\n }\n\n // Pass schema in options object with 'schema' property\n const schemaOptions = schemaString ? { schema: schemaString } : undefined;\n\n // Store the exact schema options being passed to ProbeAgent in debug info\n if (debugInfo && schemaOptions) {\n debugInfo.schema = JSON.stringify(schemaOptions, null, 2);\n }\n\n // Log the schema options being passed to ProbeAgent\n if (schemaOptions) {\n log(`🎯 Schema options passed to ProbeAgent.answer() (session reuse):`);\n log(JSON.stringify(schemaOptions, null, 2));\n }\n\n // Save prompt and debug info for session reuse too (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const provider = this.config.provider || 'auto';\n const model = this.config.model || 'default';\n\n // Try to extract conversation history from ProbeAgent\n let conversationHistory: any[] = [];\n try {\n // ProbeAgent stores history in different ways depending on version\n const agentAny = agent as any;\n if (agentAny.history) {\n conversationHistory = agentAny.history;\n } else if (agentAny.messages) {\n conversationHistory = agentAny.messages;\n } else if (agentAny._messages) {\n conversationHistory = agentAny._messages;\n }\n } catch {\n // Ignore if we can't access history\n }\n\n const debugData = {\n timestamp: timestamp,\n checkName: _checkName || 'unknown',\n provider: provider,\n model: model,\n schema: effectiveSchema,\n schemaOptions: schemaOptions || 'none',\n sessionInfo: {\n isSessionReuse: true,\n historyMessageCount: conversationHistory.length,\n },\n currentPromptLength: prompt.length,\n currentPrompt: prompt,\n conversationHistory: conversationHistory,\n };\n\n const debugJson = JSON.stringify(debugData, null, 2);\n\n // Also create a human-readable version with clear separators\n let readableVersion = `=============================================================\\n`;\n readableVersion += `VISOR DEBUG REPORT - SESSION REUSE\\n`;\n readableVersion += `=============================================================\\n`;\n readableVersion += `Timestamp: ${timestamp}\\n`;\n readableVersion += `Check Name: ${_checkName || 'unknown'}\\n`;\n readableVersion += `Provider: ${provider}\\n`;\n readableVersion += `Model: ${model}\\n`;\n readableVersion += `Schema: ${effectiveSchema}\\n`;\n readableVersion += `Schema Options: ${schemaOptions ? 'provided' : 'none'}\\n`;\n readableVersion += `History Messages: ${conversationHistory.length}\\n`;\n readableVersion += `=============================================================\\n\\n`;\n\n // Add schema details if provided\n if (schemaOptions) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `SCHEMA CONFIGURATION\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += JSON.stringify(schemaOptions, null, 2);\n readableVersion += `\\n`;\n }\n\n // Add conversation history with clear separators\n if (conversationHistory.length > 0) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `CONVERSATION HISTORY (${conversationHistory.length} messages)\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n conversationHistory.forEach((msg: any, index: number) => {\n readableVersion += `\\n${'-'.repeat(60)}\\n`;\n readableVersion += `MESSAGE #${index + 1}\\n`;\n readableVersion += `Role: ${msg.role || 'unknown'}\\n`;\n if (msg.content) {\n const contentStr =\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content, null, 2);\n readableVersion += `Length: ${contentStr.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${contentStr}\\n`;\n }\n });\n }\n\n // Add current prompt\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `CURRENT PROMPT (NEW MESSAGE)\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += `Length: ${prompt.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${prompt}\\n`;\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `END OF DEBUG REPORT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n if (!fs.existsSync(debugArtifactsDir)) {\n fs.mkdirSync(debugArtifactsDir, { recursive: true });\n }\n\n // Save JSON version\n const debugFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.json`\n );\n fs.writeFileSync(debugFile, debugJson, 'utf-8');\n\n // Save readable version\n const readableFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n fs.writeFileSync(readableFile, readableVersion, 'utf-8');\n\n log(`\\n💾 Full debug info saved to:`);\n log(` JSON: ${debugFile}`);\n log(` TXT: ${readableFile}`);\n log(` - Includes: full conversation history, schema, current prompt`);\n } catch (error) {\n log(`⚠️ Could not save debug file: ${error}`);\n }\n }\n\n // Use existing agent's answer method - this reuses the conversation context\n // Wrap in a span for hierarchical tracing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const agentAny = agent as any;\n let response: string;\n if (agentAny.tracer && typeof agentAny.tracer.withSpan === 'function') {\n response = await agentAny.tracer.withSpan(\n 'visor.ai_check_reuse',\n async () => {\n return await agent.answer(prompt, undefined, schemaOptions);\n },\n {\n 'check.name': _checkName || 'unknown',\n 'check.mode': 'session_reuse',\n 'prompt.length': prompt.length,\n 'schema.type': effectiveSchema || 'none',\n }\n );\n } else {\n response = schemaOptions\n ? await agent.answer(prompt, undefined, schemaOptions)\n : await agent.answer(prompt);\n }\n\n log('✅ ProbeAgent session reuse completed successfully');\n log(`📤 Response length: ${response.length} characters`);\n\n // Save COMPLETE conversation history AFTER AI response (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Extract FULL conversation history AFTER the AI call\n const agentAny = agent as any;\n let fullHistory: any[] = [];\n\n // Try multiple properties to get complete history\n if (agentAny.history) {\n fullHistory = agentAny.history;\n } else if (agentAny.messages) {\n fullHistory = agentAny.messages;\n } else if (agentAny._messages) {\n fullHistory = agentAny._messages;\n }\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n // do not enforce directory perms here\n\n // Save complete session history (all messages sent and received)\n const sessionBase = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}`\n );\n const sessionData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider: this.config.provider || 'auto',\n model: this.config.model || 'default',\n schema: effectiveSchema,\n totalMessages: fullHistory.length,\n };\n fs.writeFileSync(sessionBase + '.json', JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Redacted textual summary\n let readable = `=============================================================\n`;\n readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)\n`;\n readable += `=============================================================\n`;\n readable += `Timestamp: ${timestamp}\n`;\n readable += `Check: ${_checkName || 'unknown'}\n`;\n readable += `Total Messages: ${fullHistory.length}\n`;\n readable += `=============================================================\n\n`;\n fullHistory.forEach((msg: any, idx: number) => {\n const role = msg.role || 'unknown';\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += `\n${'='.repeat(60)}\nMESSAGE ${idx + 1}/${fullHistory.length}\nRole: ${role}\n${'='.repeat(60)}\n`;\n readable += content + '\\n';\n });\n fs.writeFileSync(sessionBase + '.summary.txt', readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n // (paths omitted)\n log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);\n } catch (error) {\n log(`⚠️ Could not save complete session history: ${error}`);\n }\n }\n\n // Save response if debug is enabled\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Create a response file with the same timestamp pattern\n const responseFile = path.join(\n debugArtifactsDir,\n `response-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n\n let responseContent = `=============================================================\\n`;\n responseContent += `VISOR AI RESPONSE - SESSION REUSE\\n`;\n responseContent += `=============================================================\\n`;\n responseContent += `Timestamp: ${timestamp}\\n`;\n responseContent += `Check Name: ${_checkName || 'unknown'}\\n`;\n responseContent += `Response Length: ${response.length} characters\\n`;\n responseContent += `=============================================================\\n\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += `AI RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += response;\n responseContent += `\\n${'='.repeat(60)}\\n`;\n responseContent += `END OF RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n\n fs.writeFileSync(responseFile, responseContent, 'utf-8');\n log(`💾 Response saved to: ${responseFile}`);\n } catch (error) {\n log(`⚠️ Could not save response file: ${error}`);\n }\n }\n\n // Finalize and save trace if this is a cloned session with tracing enabled\n // Properly flush and shutdown OpenTelemetry to ensure all spans are exported\n if (agentAny._traceFilePath && agentAny._telemetryConfig) {\n try {\n // First flush the tracer to export pending spans\n if (agentAny.tracer && typeof agentAny.tracer.flush === 'function') {\n await agentAny.tracer.flush();\n log(`🔄 Flushed tracer spans for cloned session`);\n }\n\n // Then shutdown the telemetry config to finalize all exporters\n if (\n agentAny._telemetryConfig &&\n typeof agentAny._telemetryConfig.shutdown === 'function'\n ) {\n await agentAny._telemetryConfig.shutdown();\n log(`📊 OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);\n\n // In GitHub Actions, also log file size for verification\n if (process.env.GITHUB_ACTIONS) {\n const fs = require('fs');\n if (fs.existsSync(agentAny._traceFilePath)) {\n const stats = fs.statSync(agentAny._traceFilePath);\n console.log(\n `::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`\n );\n }\n }\n } else if (agentAny.tracer && typeof agentAny.tracer.shutdown === 'function') {\n // Fallback for SimpleTelemetry\n await agentAny.tracer.shutdown();\n log(`📊 Trace saved to: ${agentAny._traceFilePath}`);\n }\n } catch (exportError) {\n logger.warn(`⚠️ Warning: Failed to export trace for cloned session: ${exportError}`);\n }\n }\n\n return { response, effectiveSchema };\n } catch (error) {\n logger.error(\n `❌ ProbeAgent session reuse failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n throw new Error(\n `ProbeAgent session reuse failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Call ProbeAgent SDK with built-in schema validation\n */\n private async callProbeAgent(\n prompt: string,\n schema?: string | Record<string, unknown>,\n debugInfo?: AIDebugInfo,\n _checkName?: string,\n providedSessionId?: string\n ): Promise<{ response: string; effectiveSchema?: string }> {\n // Handle mock model/provider\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n const inJest = !!process.env.JEST_WORKER_ID;\n log('🎭 Using mock AI model/provider');\n if (!inJest) {\n // Fast path for CLI/integration: synthesize a mock response without invoking ProbeAgent\n const response = await this.generateMockResponse(prompt, _checkName, schema);\n return { response, effectiveSchema: typeof schema === 'object' ? 'custom' : schema };\n }\n // In unit tests, still invoke ProbeAgent so tests can assert on options (schema) passed in\n // Fall through to normal flow below\n }\n\n // Create ProbeAgent instance with proper options\n const sessionId =\n providedSessionId ||\n (() => {\n const timestamp = new Date().toISOString();\n return `visor-${timestamp.replace(/[:.]/g, '-')}-${_checkName || 'unknown'}`;\n })();\n\n log('🤖 Creating ProbeAgent for AI review...');\n log(`🆔 Session ID: ${sessionId}`);\n log(`📝 Prompt length: ${prompt.length} characters`);\n log(`⚙️ Model: ${this.config.model || 'default'}, Provider: ${this.config.provider || 'auto'}`);\n\n // Store original env vars to restore later\n const originalEnv: Record<string, string | undefined> = {\n CLAUDE_CODE_API_KEY: process.env.CLAUDE_CODE_API_KEY,\n GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n };\n\n try {\n // Set environment variables for ProbeAgent\n // ProbeAgent SDK expects these to be in the environment\n if (this.config.provider === 'claude-code' && this.config.apiKey) {\n process.env.CLAUDE_CODE_API_KEY = this.config.apiKey;\n // Also set ANTHROPIC_API_KEY as fallback since Claude Code uses Anthropic API\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'google' && this.config.apiKey) {\n process.env.GOOGLE_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'anthropic' && this.config.apiKey) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'openai' && this.config.apiKey) {\n process.env.OPENAI_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'bedrock') {\n // For Bedrock, ProbeAgent will use AWS credentials from environment\n // No need to set apiKey as it uses AWS SDK authentication\n // ProbeAgent will check for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.\n }\n const explicitPromptType = (process.env.VISOR_PROMPT_TYPE || '').trim();\n const options: TracedProbeAgentOptions = {\n sessionId: sessionId,\n // Prefer config promptType, then env override, else fallback to code-review when schema is set\n promptType:\n this.config.promptType && this.config.promptType.trim()\n ? (this.config.promptType.trim() as any)\n : explicitPromptType\n ? (explicitPromptType as any)\n : schema === 'code-review'\n ? ('code-review-template' as any)\n : undefined,\n allowEdit: false, // We don't want the agent to modify files\n debug: this.config.debug || false,\n // Map systemPrompt to Probe customPrompt until SDK exposes a first-class field\n customPrompt: this.config.systemPrompt || this.config.customPrompt,\n };\n\n // Enable tracing in debug mode for better diagnostics\n // This uses SimpleTelemetry for lightweight tracing\n let traceFilePath = '';\n let telemetryConfig: unknown = null;\n if (this.config.debug) {\n const tracerResult = await initializeTracer(sessionId, _checkName);\n if (tracerResult) {\n options.tracer = tracerResult.tracer;\n telemetryConfig = tracerResult.telemetryConfig;\n traceFilePath = tracerResult.filePath;\n }\n }\n\n // Wire MCP configuration when provided\n if (this.config.mcpServers && Object.keys(this.config.mcpServers).length > 0) {\n (options as any).enableMcp = true;\n (options as any).mcpConfig = { mcpServers: this.config.mcpServers };\n }\n\n // Enable delegate tool if configured\n if (this.config.enableDelegate !== undefined) {\n (options as any).enableDelegate = this.config.enableDelegate;\n }\n\n // Pass retry configuration to ProbeAgent\n if (this.config.retry) {\n (options as any).retry = this.config.retry;\n }\n\n // Pass fallback configuration to ProbeAgent\n if (this.config.fallback) {\n (options as any).fallback = this.config.fallback;\n }\n\n // Enable Edit and Create tools if configured\n if (this.config.allowEdit !== undefined) {\n (options as any).allowEdit = this.config.allowEdit;\n }\n\n // Pass tool filtering options to ProbeAgent\n if (this.config.allowedTools !== undefined) {\n (options as any).allowedTools = this.config.allowedTools;\n }\n if (this.config.disableTools !== undefined) {\n (options as any).disableTools = this.config.disableTools;\n }\n\n // Pass bash command execution configuration to ProbeAgent\n // Pass allowBash and bashConfig separately (following allowEdit pattern)\n if (this.config.allowBash !== undefined) {\n (options as any).allowBash = this.config.allowBash;\n }\n if (this.config.bashConfig !== undefined) {\n (options as any).bashConfig = this.config.bashConfig;\n }\n\n // Add provider-specific options if configured\n if (this.config.provider) {\n // Map claude-code to anthropic for ProbeAgent compatibility\n // Map bedrock to anthropic temporarily until ProbeAgent adds bedrock type\n const providerOverride: ProbeAgentOptions['provider'] | undefined =\n this.config.provider === 'claude-code' || this.config.provider === 'bedrock'\n ? 'anthropic'\n : this.config.provider === 'anthropic' ||\n this.config.provider === 'openai' ||\n this.config.provider === 'google'\n ? this.config.provider\n : undefined;\n\n if (providerOverride) {\n options.provider = providerOverride;\n }\n }\n if (this.config.model) {\n options.model = this.config.model;\n }\n\n const agent = new ProbeAgent(options);\n\n log('🚀 Calling ProbeAgent...');\n // Load and pass the actual schema content if provided (skip for plain schema)\n let schemaString: string | undefined = undefined;\n let effectiveSchema: string | undefined = typeof schema === 'object' ? 'custom' : schema;\n\n if (schema && schema !== 'plain') {\n try {\n schemaString = await this.loadSchemaContent(schema);\n log(`📋 Loaded schema content for: ${schema}`);\n log(`📄 Raw schema JSON:\\n${schemaString}`);\n } catch (error) {\n log(`⚠️ Failed to load schema ${schema}, proceeding without schema:`, error);\n schemaString = undefined;\n effectiveSchema = undefined; // Schema loading failed, treat as no schema\n if (debugInfo && debugInfo.errors) {\n debugInfo.errors.push(`Failed to load schema: ${error}`);\n }\n }\n } else if (schema === 'plain') {\n log(`📋 Using plain schema - no JSON validation will be applied`);\n }\n\n // ProbeAgent now handles schema formatting internally!\n // Pass schema in options object with 'schema' property\n const schemaOptions = schemaString ? { schema: schemaString } : undefined;\n\n // Store the exact schema options being passed to ProbeAgent in debug info\n if (debugInfo && schemaOptions) {\n debugInfo.schema = JSON.stringify(schemaOptions, null, 2);\n }\n\n // Log the schema options being passed to ProbeAgent\n if (schemaOptions) {\n log(`🎯 Schema options passed to ProbeAgent.answer():`);\n log(JSON.stringify(schemaOptions, null, 2));\n }\n\n // Log the equivalent CLI command for local reproduction\n const provider = this.config.provider || 'auto';\n const model = this.config.model || 'default';\n\n // Save prompt to a temp file AND debug artifacts for easier reproduction (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const os = require('os');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Prepare debug info with full details\n const debugData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider,\n model,\n schema: effectiveSchema,\n schemaOptions: schemaOptions || 'none',\n sessionInfo: {\n isSessionReuse: false,\n isNewSession: true,\n },\n promptLength: prompt.length,\n prompt: prompt,\n };\n\n const debugJson = JSON.stringify(debugData, null, 2);\n\n // Create human-readable version with clear separators\n let readableVersion = `=============================================================\\n`;\n readableVersion += `VISOR DEBUG REPORT - NEW SESSION\\n`;\n readableVersion += `=============================================================\\n`;\n readableVersion += `Timestamp: ${timestamp}\\n`;\n readableVersion += `Check Name: ${_checkName || 'unknown'}\\n`;\n readableVersion += `Provider: ${provider}\\n`;\n readableVersion += `Model: ${model}\\n`;\n readableVersion += `Schema: ${effectiveSchema}\\n`;\n readableVersion += `Schema Options: ${schemaOptions ? 'provided' : 'none'}\\n`;\n readableVersion += `Session Type: New Session (no history)\\n`;\n readableVersion += `=============================================================\\n\\n`;\n\n // Add schema details if provided\n if (schemaOptions) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `SCHEMA CONFIGURATION\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += JSON.stringify(schemaOptions, null, 2);\n readableVersion += `\\n`;\n }\n\n // Add prompt\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `PROMPT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += `Length: ${prompt.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${prompt}\\n`;\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `END OF DEBUG REPORT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n\n // Save to temp directory\n const tempDir = os.tmpdir();\n const promptFile = path.join(tempDir, `visor-prompt-${timestamp}.txt`);\n fs.writeFileSync(promptFile, prompt, 'utf-8');\n log(`\\n💾 Prompt saved to: ${promptFile}`);\n\n // Also save to debug-artifacts directory if available\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n try {\n // do not enforce fs permissions here\n const base = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}`\n );\n fs.writeFileSync(base + '.json', debugJson, 'utf-8');\n fs.writeFileSync(base + '.summary.txt', readableVersion, 'utf-8');\n log(`\n💾 Full debug info saved to directory: ${debugArtifactsDir}`);\n } catch {\n // Ignore if we can't write to debug-artifacts\n }\n\n log(`\\n📝 To reproduce locally, run:`);\n\n let cliCommand = `npx @probelabs/probe@latest agent`;\n cliCommand += ` --provider ${provider}`;\n if (model !== 'default') {\n cliCommand += ` --model ${model}`;\n }\n if (schema) {\n cliCommand += ` --schema output/${schema}/schema.json`;\n }\n cliCommand += ` \"${promptFile}\"`;\n\n log(`\\n$ ${cliCommand}\\n`);\n } catch (error) {\n log(`⚠️ Could not save prompt file: ${error}`);\n }\n }\n\n // Wrap the agent.answer() call in a span for hierarchical tracing\n // This creates a parent span that will contain all ProbeAgent's child spans\n let response: string;\n const tracer = options.tracer as {\n withSpan?: (\n name: string,\n fn: () => Promise<string>,\n attrs?: Record<string, unknown>\n ) => Promise<string>;\n };\n if (tracer && typeof tracer.withSpan === 'function') {\n response = await tracer.withSpan(\n 'visor.ai_check',\n async () => {\n return await agent.answer(prompt, undefined, schemaOptions);\n },\n {\n 'check.name': _checkName || 'unknown',\n 'check.session_id': sessionId,\n 'prompt.length': prompt.length,\n 'schema.type': effectiveSchema || 'none',\n }\n );\n } else {\n response = schemaOptions\n ? await agent.answer(prompt, undefined, schemaOptions)\n : await agent.answer(prompt);\n }\n\n log('✅ ProbeAgent completed successfully');\n log(`📤 Response length: ${response.length} characters`);\n\n // Save COMPLETE conversation history AFTER AI response (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Extract FULL conversation history AFTER the AI call\n const agentAny = agent as any;\n let fullHistory: any[] = [];\n\n // Try multiple properties to get complete history\n if (agentAny.history) {\n fullHistory = agentAny.history;\n } else if (agentAny.messages) {\n fullHistory = agentAny.messages;\n } else if (agentAny._messages) {\n fullHistory = agentAny._messages;\n }\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n // do not enforce fs permissions here\n\n // Save complete session history (all messages sent and received)\n const sessionBase = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}`\n );\n const sessionData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider: this.config.provider || 'auto',\n model: this.config.model || 'default',\n schema: effectiveSchema,\n totalMessages: fullHistory.length,\n };\n fs.writeFileSync(sessionBase + '.json', JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Redacted textual summary\n let readable = `=============================================================\n`;\n readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)\n`;\n readable += `=============================================================\n`;\n readable += `Timestamp: ${timestamp}\n`;\n readable += `Check: ${_checkName || 'unknown'}\n`;\n readable += `Total Messages: ${fullHistory.length}\n`;\n readable += `=============================================================\n\n`;\n fullHistory.forEach((msg: any, idx: number) => {\n const role = msg.role || 'unknown';\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += `\n${'='.repeat(60)}\nMESSAGE ${idx + 1}/${fullHistory.length}\nRole: ${role}\n${'='.repeat(60)}\n`;\n readable += content + '\\n';\n });\n fs.writeFileSync(sessionBase + '.summary.txt', readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n // (paths omitted)\n log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);\n } catch (error) {\n log(`⚠️ Could not save complete session history: ${error}`);\n }\n }\n\n // Save response if debug is enabled\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Create a response file\n const responseFile = path.join(\n debugArtifactsDir,\n `response-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n\n let responseContent = `=============================================================\\n`;\n responseContent += `VISOR AI RESPONSE - NEW SESSION\\n`;\n responseContent += `=============================================================\\n`;\n responseContent += `Timestamp: ${timestamp}\\n`;\n responseContent += `Check Name: ${_checkName || 'unknown'}\\n`;\n responseContent += `Response Length: ${response.length} characters\\n`;\n responseContent += `=============================================================\\n\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += `AI RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += response;\n responseContent += `\\n${'='.repeat(60)}\\n`;\n responseContent += `END OF RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n\n fs.writeFileSync(responseFile, responseContent, 'utf-8');\n log(`💾 Response saved to: ${responseFile}`);\n } catch (error) {\n log(`⚠️ Could not save response file: ${error}`);\n }\n }\n\n // Finalize and save trace if enabled\n // Properly flush and shutdown telemetry to ensure all spans are exported\n if (traceFilePath && telemetryConfig) {\n try {\n // Cast telemetryConfig to have optional methods\n const telemetry = telemetryConfig as {\n flush?: () => Promise<void>;\n shutdown?: () => Promise<void>;\n };\n const tracerWithMethods = tracer as {\n flush?: () => Promise<void>;\n shutdown?: () => Promise<void>;\n };\n\n // First flush the tracer to export pending spans\n if (tracerWithMethods && typeof tracerWithMethods.flush === 'function') {\n await tracerWithMethods.flush();\n log(`🔄 Flushed tracer spans`);\n }\n\n // Then shutdown the telemetry config to finalize all exporters\n if (telemetry && typeof telemetry.shutdown === 'function') {\n await telemetry.shutdown();\n log(`📊 OpenTelemetry trace saved to: ${traceFilePath}`);\n\n // In GitHub Actions, also log file size for verification\n if (process.env.GITHUB_ACTIONS) {\n const fs = require('fs');\n if (fs.existsSync(traceFilePath)) {\n const stats = fs.statSync(traceFilePath);\n console.log(\n `::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`\n );\n }\n }\n } else if (tracerWithMethods && typeof tracerWithMethods.shutdown === 'function') {\n // Fallback for SimpleTelemetry\n await tracerWithMethods.shutdown();\n log(`📊 Trace saved to: ${traceFilePath}`);\n }\n } catch (exportError) {\n logger.warn(`⚠️ Warning: Failed to export trace: ${exportError}`);\n }\n }\n\n // Register the session for potential reuse by dependent checks\n if (_checkName) {\n // ProbeAgent.clone() will handle history filtering when this session is cloned\n this.registerSession(sessionId, agent);\n log(`🔧 Debug: Registered AI session for potential reuse: ${sessionId}`);\n }\n\n return { response, effectiveSchema };\n } catch (error) {\n console.error('❌ ProbeAgent failed:', error);\n throw new Error(\n `ProbeAgent execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n } finally {\n // Restore original environment variables\n Object.keys(originalEnv).forEach(key => {\n if (originalEnv[key] === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalEnv[key];\n }\n });\n }\n }\n\n /**\n * Load schema content from schema files or inline definitions\n */\n private async loadSchemaContent(schema: string | Record<string, unknown>): Promise<string> {\n const fs = require('fs').promises;\n const path = require('path');\n\n // Check if schema is already an object (inline definition from YAML)\n if (typeof schema === 'object' && schema !== null) {\n // It's already a schema object, convert to JSON string\n log('📋 Using inline schema object from configuration');\n return JSON.stringify(schema);\n }\n\n // Check if schema string is already a JSON schema (inline JSON string)\n // This happens when a schema is passed directly as JSON instead of a reference\n try {\n const parsed = JSON.parse(schema);\n if (typeof parsed === 'object' && parsed !== null) {\n // It's already a valid JSON schema, return it as-is\n log('📋 Using inline schema JSON string');\n return schema;\n }\n } catch {\n // Not JSON, treat as schema name reference or file path\n }\n\n // Check if it's a file path (starts with ./ or contains .json but not absolute paths)\n if ((schema.startsWith('./') || schema.includes('.json')) && !path.isAbsolute(schema)) {\n // It's a relative file path to a custom schema\n // Validate the path to prevent traversal attacks\n if (schema.includes('..') || schema.includes('\\x00')) {\n throw new Error('Invalid schema path: path traversal not allowed');\n }\n\n try {\n const schemaPath = path.resolve(process.cwd(), schema);\n log(`📋 Loading custom schema from file: ${schemaPath}`);\n const schemaContent = await fs.readFile(schemaPath, 'utf-8');\n return schemaContent.trim();\n } catch (error) {\n throw new Error(\n `Failed to load custom schema from ${schema}: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n // Otherwise, treat as a built-in schema name\n // Sanitize schema name to prevent path traversal attacks\n const sanitizedSchemaName = schema.replace(/[^a-zA-Z0-9-]/g, '');\n if (!sanitizedSchemaName || sanitizedSchemaName !== schema) {\n throw new Error('Invalid schema name');\n }\n\n // Built-in schemas are bundled under dist/output when running as a GitHub Action.\n // In local dev (ts-node/jest), schemas may live under project/output.\n // Try dist-relative first, then fall back to CWD.\n const candidatePaths = [\n // GitHub Action bundle location\n path.join(__dirname, 'output', sanitizedSchemaName, 'schema.json'),\n // Historical fallback when src/output was inadvertently bundled as output1/\n path.join(__dirname, 'output1', sanitizedSchemaName, 'schema.json'),\n // Local dev (repo root)\n path.join(process.cwd(), 'output', sanitizedSchemaName, 'schema.json'),\n ];\n\n for (const schemaPath of candidatePaths) {\n try {\n const schemaContent = await fs.readFile(schemaPath, 'utf-8');\n return schemaContent.trim();\n } catch {\n // try next\n }\n }\n\n // If neither path works, surface a helpful error\n const distPath = path.join(__dirname, 'output', sanitizedSchemaName, 'schema.json');\n const distAltPath = path.join(__dirname, 'output1', sanitizedSchemaName, 'schema.json');\n const cwdPath = path.join(process.cwd(), 'output', sanitizedSchemaName, 'schema.json');\n throw new Error(\n `Failed to load schema '${sanitizedSchemaName}'. Tried: ${distPath}, ${distAltPath}, and ${cwdPath}. ` +\n `Ensure build copies 'output/' into dist (build:cli), or provide a custom schema file/path.`\n );\n }\n\n /**\n * Parse AI response JSON\n */\n private parseAIResponse(\n response: string,\n debugInfo?: AIDebugInfo,\n _schema?: string\n ): ReviewSummary {\n log('🔍 Parsing AI response...');\n log(`📊 Raw response length: ${response.length} characters`);\n\n // Log first and last 200 chars for debugging\n if (response.length > 400) {\n log('📋 Response preview (first 200 chars):', response.substring(0, 200));\n log('📋 Response preview (last 200 chars):', response.substring(response.length - 200));\n } else {\n log('📋 Full response preview:', response);\n }\n\n // Note: Removed overly aggressive Liquid template check that was causing false positives\n // JSON parsing below will catch actual malformed responses\n\n try {\n // Handle different schema types differently\n let reviewData: AIResponseFormat;\n\n // Handle plain schema or no schema - no JSON parsing, return response as-is\n if (_schema === 'plain' || !_schema) {\n log(\n `📋 ${_schema === 'plain' ? 'Plain' : 'No'} schema detected - returning raw response without JSON parsing`\n );\n\n // For plain schema, return the raw response as an issue\n\n return {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n debug: debugInfo,\n };\n }\n\n {\n // For other schemas (code-review, etc.), extract and parse JSON with boundary detection\n log('🔍 Extracting JSON from AI response...');\n\n // Try direct parsing first - if AI returned pure JSON\n try {\n reviewData = JSON.parse(response.trim());\n log('✅ Successfully parsed direct JSON response');\n if (debugInfo) debugInfo.jsonParseSuccess = true;\n } catch {\n log('🔍 Direct parsing failed, trying to extract JSON from response...');\n\n // If the response starts with \"I cannot\" or similar, it's likely a refusal\n if (\n response.toLowerCase().includes('i cannot') ||\n response.toLowerCase().includes('unable to')\n ) {\n console.error('🚫 AI refused to analyze - returning empty result');\n return {\n issues: [],\n };\n }\n\n // Try to extract JSON using improved method with proper bracket matching\n const jsonString = this.extractJsonFromResponse(response);\n\n if (jsonString) {\n try {\n reviewData = JSON.parse(jsonString);\n log('✅ Successfully parsed extracted JSON');\n if (debugInfo) debugInfo.jsonParseSuccess = true;\n } catch {\n log('🔧 Extracted JSON parsing failed, falling back to plain text handling...');\n\n // Check if response is plain text and doesn't contain structured data\n if (!response.includes('{') && !response.includes('}')) {\n log('🔧 Plain text response detected, creating structured fallback...');\n\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n } else {\n // Fallback: treat the entire response as an issue\n log('🔧 Creating fallback response from non-JSON content...');\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n }\n }\n } else {\n // No JSON found at all - treat as plain text response\n log('🔧 No JSON found in response, treating as plain text...');\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n }\n }\n }\n\n // Decide how to interpret the parsed JSON based on the effective schema and the shape of data\n // Built-ins:\n // - 'code-review' → expects { issues: [...] }\n // - 'overview' / assistants → expects { text: string, ... }\n // - 'plain' → handled earlier\n // - custom (object/file path) → free-form object, ensure output.text fallback\n const looksLikeTextOutput =\n reviewData &&\n typeof reviewData === 'object' &&\n typeof (reviewData as any).text === 'string' &&\n String((reviewData as any).text).trim().length > 0;\n\n // Treat as custom/text-style when:\n // - explicit custom schema\n // - schema is any non code-review built-in like 'overview', 'issue-assistant', 'comment-assistant'\n // - or schema is unknown/undefined but the payload clearly contains a text field\n const isCustomSchema =\n _schema === 'custom' ||\n (_schema && (_schema.startsWith('./') || _schema.endsWith('.json'))) ||\n (_schema && _schema !== 'code-review' && !_schema.includes('output/')) ||\n (!_schema && looksLikeTextOutput);\n\n const _debugSchemaLogging =\n this.config.debug === true || process.env.VISOR_DEBUG_AI_SESSIONS === 'true';\n if (_debugSchemaLogging) {\n const details = {\n schema: _schema,\n isCustomSchema,\n isCustomLiteral: _schema === 'custom',\n startsWithDotSlash: typeof _schema === 'string' ? _schema.startsWith('./') : false,\n endsWithJson: typeof _schema === 'string' ? _schema.endsWith('.json') : false,\n notCodeReview: _schema !== 'code-review',\n noOutputPrefix: typeof _schema === 'string' ? !_schema.includes('output/') : false,\n };\n try {\n log(`🔍 Schema detection: ${JSON.stringify(details)}`);\n } catch {\n // Fallback if JSON.stringify throws on unexpected values\n log(\n `🔍 Schema detection: _schema=\"${String(_schema)}\", isCustomSchema=${isCustomSchema}`\n );\n }\n }\n\n if (isCustomSchema) {\n // For custom schemas, preserve ALL fields from the parsed JSON and make sure\n // we always have something renderable in templates (e.g., output.text).\n log('📋 Custom schema detected - preserving all fields from parsed JSON');\n log(`📊 Schema: ${_schema}`);\n try {\n log(`📊 Custom schema keys: ${Object.keys(reviewData).join(', ')}`);\n } catch {}\n\n // Ensure \"output\" is an object and has a sensible text fallback for templates\n const out: Record<string, unknown> =\n reviewData && typeof reviewData === 'object' ? (reviewData as any) : ({} as any);\n\n const hasText =\n typeof (out as any).text === 'string' && String((out as any).text).trim().length > 0;\n if (!hasText) {\n // Build a fallback string from the raw response or issue messages if available\n let fallbackText = '';\n try {\n if (\n Array.isArray((reviewData as any)?.issues) &&\n (reviewData as any).issues.length > 0\n ) {\n // Join issue messages into a readable block\n fallbackText = (reviewData as any).issues\n .map((i: any) => (i && (i.message || i.text || i.response)) as string)\n .filter((s: any) => typeof s === 'string' && s.trim().length > 0)\n .join('\\n');\n }\n } catch {}\n if (!fallbackText && typeof response === 'string' && response.trim()) {\n // Use raw provider response (trim and bound length for safety)\n fallbackText = response.trim().slice(0, 60000);\n }\n if (fallbackText) {\n (out as any).text = fallbackText;\n }\n }\n\n const result: ReviewSummary & { output?: unknown } = {\n // Keep issues empty for custom-schema rendering; consumers read from output.*\n issues: [],\n output: out,\n };\n\n log(\n '✅ Successfully created ReviewSummary with custom schema output (with fallback text when needed)'\n );\n return result;\n }\n\n // Standard code-review schema processing (only when schema is explicitly code-review\n // or when the payload clearly has an issues array)\n log('🔍 Validating parsed review data...');\n log(`📊 Overall score: ${0}`);\n log(`📋 Total issues: ${reviewData.issues?.length || 0}`);\n log(\n `🚨 Critical issues: ${reviewData.issues?.filter((i: { severity?: string }) => i.severity === 'critical').length || 0}`\n );\n log(`💬 Comments count: ${Array.isArray(reviewData.issues) ? reviewData.issues.length : 0}`);\n\n // Process issues from the simplified format; if we don't have issues and the\n // data looks like a text-style output, route through the custom path above.\n const processedIssues = Array.isArray((reviewData as any).issues)\n ? (reviewData as any).issues.map((issue: any, index: number) => {\n log(`🔍 Processing issue ${index + 1}:`, issue);\n return {\n file: issue.file || 'unknown',\n line: issue.line || 1,\n endLine: issue.endLine,\n ruleId: issue.ruleId || `${issue.category || 'general'}/unknown`,\n message: issue.message || '',\n severity: issue.severity,\n category: issue.category,\n suggestion: issue.suggestion,\n replacement: issue.replacement,\n } as ReviewIssue;\n })\n : [];\n\n // Validate and convert to ReviewSummary format\n const result: ReviewSummary = {\n issues: processedIssues,\n };\n\n // Log issue counts\n const criticalCount = (result.issues || []).filter(i => i.severity === 'critical').length;\n if (criticalCount > 0) {\n log(`🚨 Found ${criticalCount} critical severity issue(s)`);\n }\n log(`📈 Total issues: ${(result.issues || []).length}`);\n\n log('✅ Successfully created ReviewSummary');\n return result;\n } catch (error) {\n const detailed = this.config.debug === true || process.env.VISOR_DEBUG_AI_SESSIONS === 'true';\n const message = error instanceof Error ? error.message : String(error);\n\n if (detailed) {\n logger.debug(`❌ Failed to parse AI response: ${message}`);\n logger.debug('📄 FULL RAW RESPONSE:');\n logger.debug('='.repeat(80));\n logger.debug(response);\n logger.debug('='.repeat(80));\n logger.debug(`📏 Response length: ${response.length} characters`);\n\n if (error instanceof SyntaxError) {\n logger.debug('🔍 JSON parsing error - the response may not be valid JSON');\n logger.debug(`🔍 Error details: ${error.message}`);\n\n const errorMatch = error.message.match(/position (\\d+)/);\n if (errorMatch) {\n const position = parseInt(errorMatch[1]);\n logger.debug(`🔍 Error at position ${position}:`);\n const start = Math.max(0, position - 50);\n const end = Math.min(response.length, position + 50);\n logger.debug(`🔍 Context: \"${response.substring(start, end)}\"`);\n logger.debug(`🔍 Response beginning: \"${response.substring(0, 100)}\"`);\n }\n\n if (response.includes('I cannot')) {\n logger.debug('🔍 Response appears to be a refusal/explanation rather than JSON');\n }\n if (response.includes('```')) {\n logger.debug('🔍 Response appears to contain markdown code blocks');\n }\n if (response.startsWith('<')) {\n logger.debug('🔍 Response appears to start with XML/HTML');\n }\n }\n } else {\n logger.error(`❌ Failed to parse AI response: ${message}`);\n }\n\n throw new Error(\n `Invalid AI response format: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Extract JSON from a response that might contain surrounding text\n * Uses proper bracket matching to find valid JSON objects or arrays\n */\n private extractJsonFromResponse(response: string): string | null {\n const text = response.trim();\n\n // Try to find JSON objects first (higher priority)\n let bestJson = this.findJsonWithBracketMatching(text, '{', '}');\n\n // If no object found, try arrays\n if (!bestJson) {\n bestJson = this.findJsonWithBracketMatching(text, '[', ']');\n }\n\n return bestJson;\n }\n\n /**\n * Find JSON with proper bracket matching to avoid false positives\n */\n private findJsonWithBracketMatching(\n text: string,\n openChar: string,\n closeChar: string\n ): string | null {\n const firstIndex = text.indexOf(openChar);\n if (firstIndex === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escaping = false;\n\n for (let i = firstIndex; i < text.length; i++) {\n const char = text[i];\n\n if (escaping) {\n escaping = false;\n continue;\n }\n\n if (char === '\\\\' && inString) {\n escaping = true;\n continue;\n }\n\n if (char === '\"' && !escaping) {\n inString = !inString;\n continue;\n }\n\n if (!inString) {\n if (char === openChar) {\n depth++;\n } else if (char === closeChar) {\n depth--;\n if (depth === 0) {\n // Found matching closing bracket\n const candidate = text.substring(firstIndex, i + 1);\n try {\n JSON.parse(candidate); // Validate it's actually valid JSON\n return candidate;\n } catch {\n // This wasn't valid JSON, keep looking\n break;\n }\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Generate mock response for testing\n */\n private async generateMockResponse(\n _prompt: string,\n _checkName?: string,\n _schema?: string | Record<string, unknown>\n ): Promise<string> {\n // Simulate some processing time\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Schema-accurate mocks for default flows\n const name = (_checkName || '').toLowerCase();\n if (name.includes('extract-facts')) {\n const arr = Array.from({ length: 6 }, (_, i) => ({\n id: `fact-${i + 1}`,\n category: 'Feature',\n claim: `claim-${i + 1}`,\n verifiable: true,\n refs: [{ path: 'src/check-execution-engine.ts', lines: '6400-6460' }],\n }));\n return JSON.stringify(arr);\n }\n if (name.includes('validate-fact')) {\n const idMatch = _prompt.match(/Fact ID:\\s*([\\w\\-]+)/i);\n const claimMatch = _prompt.match(/\\*\\*Claim:\\*\\*\\s*(.+)/i);\n const attemptMatch = _prompt.match(/Attempt:\\s*(\\d+)/i);\n const factId = idMatch ? idMatch[1] : 'fact-1';\n const claim = claimMatch ? claimMatch[1].trim() : 'unknown-claim';\n const n = Number(factId.split('-')[1] || '0');\n const attempt = attemptMatch ? Number(attemptMatch[1]) : 0;\n const isValid = attempt >= 1 ? true : !(n >= 1 && n <= 3);\n return JSON.stringify({\n fact_id: factId,\n claim,\n is_valid: isValid,\n confidence: 'high',\n evidence: isValid ? 'verified' : 'not found',\n correction: isValid ? null : `correct ${claim}`,\n });\n }\n if (name.includes('issue-assistant') || name.includes('comment-assistant')) {\n const text = '### Assistant Reply';\n const intent = name.includes('issue') ? 'issue_triage' : 'comment_reply';\n return JSON.stringify({ text, intent });\n }\n // Fallback\n const mockResponse = { content: JSON.stringify({ issues: [], summary: { totalIssues: 0 } }) };\n return JSON.stringify(mockResponse);\n }\n\n /**\n * Get the API key source for debugging (without revealing the key)\n */\n private getApiKeySource(): string {\n if (process.env.CLAUDE_CODE_API_KEY && this.config.provider === 'claude-code') {\n return 'CLAUDE_CODE_API_KEY';\n }\n if (process.env.GOOGLE_API_KEY && this.config.provider === 'google') {\n return 'GOOGLE_API_KEY';\n }\n if (process.env.ANTHROPIC_API_KEY && this.config.provider === 'anthropic') {\n return 'ANTHROPIC_API_KEY';\n }\n if (process.env.OPENAI_API_KEY && this.config.provider === 'openai') {\n return 'OPENAI_API_KEY';\n }\n if (this.config.provider === 'bedrock') {\n if (process.env.AWS_BEDROCK_API_KEY) {\n return 'AWS_BEDROCK_API_KEY';\n }\n if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {\n return 'AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY';\n }\n }\n return 'unknown';\n }\n}\n","/**\n * Environment variable resolution utilities\n * Supports GitHub Actions-like syntax for referencing environment variables\n */\n\nimport { EnvConfig } from '../types/config';\n\n/**\n * Resolves environment variables in configuration values\n * Supports the following syntaxes:\n * - ${{ env.VARIABLE_NAME }} (GitHub Actions style)\n * - ${VARIABLE_NAME} (shell style)\n * - $VARIABLE_NAME (simple shell style)\n * - Direct environment variable names\n */\nexport class EnvironmentResolver {\n /**\n * Resolves a single configuration value that may contain environment variable references\n */\n static resolveValue(value: string | number | boolean): string | number | boolean {\n if (typeof value !== 'string') {\n return value;\n }\n\n // GitHub Actions style: ${{ env.VARIABLE_NAME }}\n let resolved = value.replace(/\\$\\{\\{\\s*env\\.([A-Z_][A-Z0-9_]*)\\s*\\}\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Shell style: ${VARIABLE_NAME}\n resolved = resolved.replace(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Simple shell style: $VARIABLE_NAME\n resolved = resolved.replace(/\\$([A-Z_][A-Z0-9_]*)/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n return resolved;\n }\n\n /**\n * Resolves all environment variables in an EnvConfig object\n */\n static resolveEnvConfig(envConfig: EnvConfig): EnvConfig {\n const resolved: EnvConfig = {};\n\n for (const [key, value] of Object.entries(envConfig)) {\n resolved[key] = this.resolveValue(value);\n }\n\n return resolved;\n }\n\n /**\n * Applies environment configuration to the process environment\n * This allows checks to access their specific environment variables\n */\n static applyEnvConfig(envConfig: EnvConfig): void {\n const resolved = this.resolveEnvConfig(envConfig);\n\n for (const [key, value] of Object.entries(resolved)) {\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n }\n\n /**\n * Creates a temporary environment for a specific check execution\n * Returns a cleanup function to restore the original environment\n */\n static withTemporaryEnv<T>(envConfig: EnvConfig, callback: () => T | Promise<T>): T | Promise<T> {\n const resolved = this.resolveEnvConfig(envConfig);\n const originalValues: Record<string, string | undefined> = {};\n\n // Store original values and apply new ones\n for (const [key, value] of Object.entries(resolved)) {\n originalValues[key] = process.env[key];\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n\n try {\n const result = callback();\n\n // If callback returns a promise, handle cleanup after it resolves\n if (result instanceof Promise) {\n return result.finally(() => {\n // Restore original values\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n });\n }\n\n // Restore original values immediately for sync callbacks\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n\n return result;\n } catch (error) {\n // Restore original values on error\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n throw error;\n }\n }\n\n /**\n * Validates that all required environment variables are available\n */\n static validateRequiredEnvVars(envConfig: EnvConfig, requiredVars: string[]): string[] {\n const resolved = this.resolveEnvConfig(envConfig);\n const missing: string[] = [];\n\n for (const varName of requiredVars) {\n const value = resolved[varName] || process.env[varName];\n if (!value) {\n missing.push(varName);\n }\n }\n\n return missing;\n }\n\n /**\n * Resolves environment variables in HTTP headers\n * Each header value is processed through resolveValue to replace env var references\n */\n static resolveHeaders(headers: Record<string, string>): Record<string, string> {\n const resolved: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n resolved[key] = String(this.resolveValue(value));\n }\n return resolved;\n }\n\n /**\n * Sanitizes headers for logging/telemetry by redacting sensitive values\n * Headers like Authorization, API keys, and cookies are replaced with [REDACTED]\n */\n static sanitizeHeaders(headers: Record<string, string>): Record<string, string> {\n const sensitiveHeaders = ['authorization', 'x-api-key', 'cookie', 'set-cookie'];\n const sanitized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (sensitiveHeaders.includes(key.toLowerCase())) {\n sanitized[key] = '[REDACTED]';\n } else {\n sanitized[key] = value;\n }\n }\n\n return sanitized;\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { ReviewIssue } from './reviewer';\n\n/**\n * Filter for suppressing Visor issues based on special comments in code\n */\nexport class IssueFilter {\n private fileCache: Map<string, string[]> = new Map();\n private suppressionEnabled: boolean;\n\n constructor(suppressionEnabled: boolean = true) {\n this.suppressionEnabled = suppressionEnabled;\n }\n\n /**\n * Filter out issues that have suppression comments\n * @param issues Array of issues to filter\n * @param workingDir Working directory for resolving file paths\n * @returns Filtered array of issues with suppressed ones removed\n */\n public filterIssues(issues: ReviewIssue[], workingDir: string = process.cwd()): ReviewIssue[] {\n if (!this.suppressionEnabled || !issues || issues.length === 0) {\n return issues;\n }\n\n const filteredIssues: ReviewIssue[] = [];\n const suppressedCount: { [file: string]: number } = {};\n\n for (const issue of issues) {\n if (this.shouldSuppressIssue(issue, workingDir)) {\n // Track suppressed issues for logging\n suppressedCount[issue.file] = (suppressedCount[issue.file] || 0) + 1;\n } else {\n filteredIssues.push(issue);\n }\n }\n\n // Log suppression summary if any issues were suppressed\n const totalSuppressed = Object.values(suppressedCount).reduce((sum, count) => sum + count, 0);\n if (totalSuppressed > 0) {\n console.log(`🔇 Suppressed ${totalSuppressed} issue(s) via visor-disable comments:`);\n for (const [file, count] of Object.entries(suppressedCount)) {\n console.log(` - ${file}: ${count} issue(s)`);\n }\n }\n\n return filteredIssues;\n }\n\n /**\n * Check if an issue should be suppressed based on comments in the file\n */\n private shouldSuppressIssue(issue: ReviewIssue, workingDir: string): boolean {\n // Skip system-level issues or issues without file/line info\n if (!issue.file || issue.file === 'system' || issue.file === 'webhook' || issue.line === 0) {\n return false;\n }\n\n const lines = this.getFileLines(issue.file, workingDir);\n if (!lines || lines.length === 0) {\n return false;\n }\n\n // Check for file-level suppression (visor-disable-file in first 5 lines)\n const firstFiveLines = lines.slice(0, 5).join('\\n').toLowerCase();\n if (firstFiveLines.includes('visor-disable-file')) {\n return true;\n }\n\n // Check for line-level suppression (visor-disable within ±2 lines)\n const lineIndex = issue.line - 1; // Convert to 0-based index\n const startLine = Math.max(0, lineIndex - 2);\n const endLine = Math.min(lines.length - 1, lineIndex + 2);\n\n for (let i = startLine; i <= endLine; i++) {\n if (lines[i].toLowerCase().includes('visor-disable')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get file lines from cache or read from disk\n */\n private getFileLines(filePath: string, workingDir: string): string[] | null {\n // Check cache first\n if (this.fileCache.has(filePath)) {\n return this.fileCache.get(filePath)!;\n }\n\n try {\n // Resolve the file path\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(workingDir, filePath);\n\n if (!fs.existsSync(resolvedPath)) {\n // Try without working directory if the file doesn't exist\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, 'utf8');\n const lines = content.split('\\n');\n this.fileCache.set(filePath, lines);\n return lines;\n }\n return null;\n }\n\n const content = fs.readFileSync(resolvedPath, 'utf8');\n const lines = content.split('\\n');\n this.fileCache.set(filePath, lines);\n return lines;\n } catch {\n // Silently skip files that can't be read\n return null;\n }\n }\n\n /**\n * Clear the file cache (useful for testing or long-running processes)\n */\n public clearCache(): void {\n this.fileCache.clear();\n }\n}\n","/**\n * Enhanced state capture for OTEL spans to enable interactive debugging.\n *\n * This module provides utilities to capture complete execution state in span\n * attributes, enabling time-travel debugging and full state inspection.\n */\n\nimport { Span } from './lazy-otel';\n\nconst MAX_ATTRIBUTE_LENGTH = 10000; // Truncate large values\nconst MAX_ARRAY_ITEMS = 100; // Limit array size in attributes\n\n/**\n * Safely serialize a value for OTEL span attributes.\n * Handles truncation, circular refs, and type conversions.\n */\nfunction safeSerialize(value: unknown, maxLength = MAX_ATTRIBUTE_LENGTH): string {\n try {\n if (value === undefined || value === null) return String(value);\n\n // Detect circular references\n const seen = new WeakSet();\n const json = JSON.stringify(value, (key, val) => {\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n // Truncate long strings\n if (typeof val === 'string' && val.length > maxLength) {\n return val.substring(0, maxLength) + '...[truncated]';\n }\n return val;\n });\n\n if (json.length > maxLength) {\n return json.substring(0, maxLength) + '...[truncated]';\n }\n return json;\n } catch (err) {\n return `[Error serializing: ${err instanceof Error ? err.message : String(err)}]`;\n }\n}\n\n/**\n * Capture check input context (Liquid template variables) in span.\n */\nexport function captureCheckInputContext(span: Span, context: Record<string, unknown>): void {\n try {\n // Capture key context variables\n const keys = Object.keys(context);\n span.setAttribute('visor.check.input.keys', keys.join(','));\n span.setAttribute('visor.check.input.count', keys.length);\n\n // Capture full context as JSON (with size limit)\n span.setAttribute('visor.check.input.context', safeSerialize(context));\n\n // Capture specific important variables separately for easy querying\n if (context.pr) {\n span.setAttribute('visor.check.input.pr', safeSerialize(context.pr, 1000));\n }\n if (context.outputs) {\n span.setAttribute('visor.check.input.outputs', safeSerialize(context.outputs, 5000));\n }\n if (context.env) {\n span.setAttribute('visor.check.input.env_keys', Object.keys(context.env as object).join(','));\n }\n } catch (err) {\n try {\n span.setAttribute('visor.check.input.error', String(err));\n } catch {\n // Ignore if we can't even set the error attribute\n }\n }\n}\n\n/**\n * Capture check output in span.\n */\nexport function captureCheckOutput(span: Span, output: unknown): void {\n try {\n span.setAttribute('visor.check.output.type', typeof output);\n\n if (Array.isArray(output)) {\n span.setAttribute('visor.check.output.length', output.length);\n // Store first few items for preview\n const preview = output.slice(0, 10);\n span.setAttribute('visor.check.output.preview', safeSerialize(preview, 2000));\n }\n\n // Full output (truncated if needed)\n span.setAttribute('visor.check.output', safeSerialize(output));\n } catch (err) {\n try {\n span.setAttribute('visor.check.output.error', String(err));\n } catch {\n // Ignore if we can't even set the error attribute\n }\n }\n}\n\n/**\n * Capture forEach iteration state.\n */\nexport function captureForEachState(\n span: Span,\n items: unknown[],\n index: number,\n currentItem: unknown\n): void {\n try {\n span.setAttribute('visor.foreach.total', items.length);\n span.setAttribute('visor.foreach.index', index);\n span.setAttribute('visor.foreach.current_item', safeSerialize(currentItem, 500));\n\n // Store all items if not too large\n if (items.length <= MAX_ARRAY_ITEMS) {\n span.setAttribute('visor.foreach.items', safeSerialize(items));\n } else {\n span.setAttribute(\n 'visor.foreach.items.preview',\n safeSerialize(items.slice(0, MAX_ARRAY_ITEMS))\n );\n span.setAttribute('visor.foreach.items.truncated', true);\n }\n } catch (err) {\n span.setAttribute('visor.foreach.error', String(err));\n }\n}\n\n/**\n * Capture Liquid template evaluation details.\n */\nexport function captureLiquidEvaluation(\n span: Span,\n template: string,\n context: Record<string, unknown>,\n result: string\n): void {\n try {\n span.setAttribute('visor.liquid.template', template.substring(0, 1000));\n span.setAttribute('visor.liquid.template.length', template.length);\n span.setAttribute('visor.liquid.result', result.substring(0, 2000));\n span.setAttribute('visor.liquid.result.length', result.length);\n span.setAttribute('visor.liquid.context', safeSerialize(context, 3000));\n } catch (err) {\n span.setAttribute('visor.liquid.error', String(err));\n }\n}\n\n/**\n * Capture JavaScript transform execution.\n */\nexport function captureTransformJS(\n span: Span,\n code: string,\n input: unknown,\n output: unknown\n): void {\n try {\n // Truncate long code while keeping plain string (no JSON quoting)\n const codePreview = code.length > 2000 ? code.substring(0, 2000) + '...[truncated]' : code;\n span.setAttribute('visor.transform.code', codePreview);\n span.setAttribute('visor.transform.code.length', code.length);\n span.setAttribute('visor.transform.input', safeSerialize(input, 2000));\n span.setAttribute('visor.transform.output', safeSerialize(output, 2000));\n } catch (err) {\n span.setAttribute('visor.transform.error', String(err));\n }\n}\n\n/**\n * Capture provider request/response summary (safe, no raw AI content).\n */\nexport function captureProviderCall(\n span: Span,\n providerType: string,\n request: { prompt?: string; model?: string; [key: string]: unknown },\n response: { content?: string; tokens?: number; [key: string]: unknown }\n): void {\n try {\n span.setAttribute('visor.provider.type', providerType);\n\n // Request summary\n if (request.model) span.setAttribute('visor.provider.request.model', String(request.model));\n if (request.prompt) {\n span.setAttribute('visor.provider.request.prompt.length', request.prompt.length);\n span.setAttribute('visor.provider.request.prompt.preview', request.prompt.substring(0, 500));\n }\n\n // Response summary\n if (response.content) {\n span.setAttribute('visor.provider.response.length', response.content.length);\n span.setAttribute('visor.provider.response.preview', response.content.substring(0, 500));\n }\n if (response.tokens) {\n span.setAttribute('visor.provider.response.tokens', response.tokens);\n }\n } catch (err) {\n span.setAttribute('visor.provider.error', String(err));\n }\n}\n\n/**\n * Capture conditional evaluation (if/fail_if).\n */\nexport function captureConditionalEvaluation(\n span: Span,\n condition: string,\n result: boolean,\n context: Record<string, unknown>\n): void {\n try {\n span.setAttribute('visor.condition.expression', condition.substring(0, 500));\n span.setAttribute('visor.condition.result', result);\n span.setAttribute('visor.condition.context', safeSerialize(context, 2000));\n } catch (err) {\n span.setAttribute('visor.condition.error', String(err));\n }\n}\n\n/**\n * Capture routing decision (retry/goto/run).\n */\nexport function captureRoutingDecision(\n span: Span,\n action: 'retry' | 'goto' | 'run',\n target: string | string[],\n condition?: string\n): void {\n try {\n span.setAttribute('visor.routing.action', action);\n span.setAttribute('visor.routing.target', Array.isArray(target) ? target.join(',') : target);\n if (condition) {\n span.setAttribute('visor.routing.condition', condition.substring(0, 500));\n }\n } catch (err) {\n span.setAttribute('visor.routing.error', String(err));\n }\n}\n\n/**\n * Create a snapshot of the entire execution state at a point in time.\n * This is added as a span event for time-travel debugging.\n */\nexport function captureStateSnapshot(\n span: Span,\n checkId: string,\n outputs: Record<string, unknown>,\n memory: Record<string, unknown>\n): void {\n try {\n span.addEvent('state.snapshot', {\n 'visor.snapshot.check_id': checkId,\n 'visor.snapshot.outputs': safeSerialize(outputs, 5000),\n 'visor.snapshot.memory': safeSerialize(memory, 5000),\n 'visor.snapshot.timestamp': new Date().toISOString(),\n });\n } catch (err) {\n span.setAttribute('visor.snapshot.error', String(err));\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { AIReviewService, AIReviewConfig } from '../ai-review-service';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { IssueFilter } from '../issue-filter';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { trace, context as otContext } from '../telemetry/lazy-otel';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureProviderCall,\n} from '../telemetry/state-capture';\n\n/**\n * AI-powered check provider using probe agent\n */\nexport class AICheckProvider extends CheckProvider {\n private aiReviewService: AIReviewService;\n private liquidEngine: ReturnType<typeof createExtendedLiquid>;\n\n constructor() {\n super();\n this.aiReviewService = new AIReviewService();\n this.liquidEngine = createExtendedLiquid();\n }\n\n getName(): string {\n return 'ai';\n }\n\n getDescription(): string {\n return 'AI-powered code review using Google Gemini, Anthropic Claude, OpenAI GPT, or AWS Bedrock models';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'ai'\n if (cfg.type !== 'ai') {\n return false;\n }\n\n // Check for prompt or focus\n const prompt = cfg.prompt || cfg.focus;\n if (typeof prompt !== 'string') {\n return false;\n }\n\n // Focus is now config-driven - any string value is acceptable\n // No validation needed here as focus is just a hint to the AI\n\n // Validate AI provider config if present\n if (cfg.ai) {\n if (\n cfg.ai.provider &&\n !['google', 'anthropic', 'openai', 'bedrock', 'mock'].includes(cfg.ai.provider as string)\n ) {\n return false;\n }\n\n // Validate mcpServers if present\n if (cfg.ai.mcpServers) {\n if (!this.validateMcpServers(cfg.ai.mcpServers)) {\n return false;\n }\n }\n }\n\n // Validate check-level MCP servers if present\n const checkLevelMcpServers = (cfg as CheckProviderConfig & { ai_mcp_servers?: unknown })\n .ai_mcp_servers;\n if (checkLevelMcpServers) {\n if (!this.validateMcpServers(checkLevelMcpServers)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Validate MCP servers configuration\n */\n private validateMcpServers(mcpServers: unknown): boolean {\n if (typeof mcpServers !== 'object' || mcpServers === null) {\n return false;\n }\n\n for (const serverConfig of Object.values(mcpServers)) {\n if (!serverConfig || typeof serverConfig !== 'object') {\n return false;\n }\n const config = serverConfig as { command?: unknown; args?: unknown };\n if (typeof config.command !== 'string') {\n return false;\n }\n if (config.args !== undefined && !Array.isArray(config.args)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Group files by their file extension for template context\n */\n private groupFilesByExtension(\n files: import('../pr-analyzer').PRFile[]\n ): Record<string, import('../pr-analyzer').PRFile[]> {\n const grouped: Record<string, import('../pr-analyzer').PRFile[]> = {};\n\n files.forEach(file => {\n const parts = file.filename.split('.');\n const ext = parts.length > 1 ? parts.pop()?.toLowerCase() || 'noext' : 'noext';\n if (!grouped[ext]) {\n grouped[ext] = [];\n }\n grouped[ext].push(file);\n });\n\n return grouped;\n }\n\n /**\n * Process prompt configuration to resolve final prompt string\n */\n private async processPrompt(\n promptConfig: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>,\n outputHistory?: Map<string, unknown[]>\n ): Promise<string> {\n let promptContent: string;\n\n // Auto-detect if it's a file path or inline content\n if (await this.isFilePath(promptConfig)) {\n promptContent = await this.loadPromptFromFile(promptConfig);\n } else {\n promptContent = promptConfig;\n }\n\n // Process Liquid templates in the prompt\n return await this.renderPromptTemplate(\n promptContent,\n prInfo,\n eventContext,\n dependencyResults,\n outputHistory\n );\n }\n\n /**\n * Detect if a string is likely a file path and if the file exists\n */\n private async isFilePath(str: string): Promise<boolean> {\n // Quick checks to exclude obvious non-file-path content\n if (!str || str.trim() !== str || str.length > 512) {\n return false;\n }\n\n // Exclude strings that are clearly content (contain common content indicators)\n // But be more careful with paths that might contain common words as directory names\n if (\n /\\s{2,}/.test(str) || // Multiple consecutive spaces\n /\\n/.test(str) || // Contains newlines\n /^(please|analyze|review|check|find|identify|look|search)/i.test(str.trim()) || // Starts with command words\n str.split(' ').length > 8 // Too many words for a typical file path\n ) {\n return false;\n }\n\n // For strings with path separators, be more lenient about common words\n // as they might be legitimate directory names\n if (!/[\\/\\\\]/.test(str)) {\n // Only apply strict English word filter to non-path strings\n if (/\\b(the|and|or|but|for|with|by|from|in|on|at|as)\\b/i.test(str)) {\n return false;\n }\n }\n\n // Positive indicators for file paths\n const hasFileExtension = /\\.[a-zA-Z0-9]{1,10}$/i.test(str);\n const hasPathSeparators = /[\\/\\\\]/.test(str);\n const isRelativePath = /^\\.{1,2}\\//.test(str);\n const isAbsolutePath = path.isAbsolute(str);\n const hasTypicalFileChars = /^[a-zA-Z0-9._\\-\\/\\\\:~]+$/.test(str);\n\n // Must have at least one strong indicator\n if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {\n return false;\n }\n\n // Must contain only typical file path characters\n if (!hasTypicalFileChars) {\n return false;\n }\n\n // Additional validation for suspected file paths\n try {\n // Try to resolve and check if file exists\n let resolvedPath: string;\n\n if (path.isAbsolute(str)) {\n resolvedPath = path.normalize(str);\n } else {\n // Resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), str);\n }\n\n // Check if file exists\n const fs = require('fs').promises;\n try {\n const stat = await fs.stat(resolvedPath);\n return stat.isFile();\n } catch {\n // File doesn't exist, but might still be a valid file path format\n // Return true if it has strong file path indicators\n return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);\n }\n } catch {\n return false;\n }\n }\n\n /**\n * Load prompt content from file with security validation\n */\n private async loadPromptFromFile(promptPath: string): Promise<string> {\n // Enforce .liquid file extension for all prompt files\n if (!promptPath.endsWith('.liquid')) {\n throw new Error('Prompt file must have .liquid extension');\n }\n\n let resolvedPath: string;\n\n if (path.isAbsolute(promptPath)) {\n // Absolute path - use as-is\n resolvedPath = promptPath;\n } else {\n // Relative path - resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), promptPath);\n }\n\n // Security: For relative paths, ensure they don't escape the current directory\n if (!path.isAbsolute(promptPath)) {\n const normalizedPath = path.normalize(resolvedPath);\n const currentDir = path.resolve(process.cwd());\n if (!normalizedPath.startsWith(currentDir)) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n }\n\n // Security: Check for obvious path traversal patterns\n if (promptPath.includes('../..')) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n\n try {\n const promptContent = await fs.readFile(resolvedPath, 'utf-8');\n return promptContent;\n } catch (error) {\n throw new Error(\n `Failed to load prompt from ${resolvedPath}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Render Liquid template in prompt with comprehensive event context\n */\n private async renderPromptTemplate(\n promptContent: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>,\n outputHistory?: Map<string, unknown[]>\n ): Promise<string> {\n // Build outputs_raw from -raw keys (aggregate parent values)\n const outputsRaw: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [k, v] of dependencyResults.entries()) {\n if (typeof k !== 'string') continue;\n if (k.endsWith('-raw')) {\n const name = k.slice(0, -4);\n const summary = v as ReviewSummary & { output?: unknown };\n outputsRaw[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n }\n\n // Note: We intentionally do NOT expose any special `fact_validation` object\n // in the template context. Templates should derive everything from\n // outputs / outputs_history / memory helpers to avoid hidden magic.\n\n // Create comprehensive template context with PR and event information\n const templateContext = {\n // PR Information\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n baseBranch: prInfo.base,\n headBranch: prInfo.head,\n isIncremental: prInfo.isIncremental,\n filesChanged: prInfo.files?.map(f => f.filename) || [],\n totalAdditions: prInfo.files?.reduce((sum, f) => sum + f.additions, 0) || 0,\n totalDeletions: prInfo.files?.reduce((sum, f) => sum + f.deletions, 0) || 0,\n totalChanges: prInfo.files?.reduce((sum, f) => sum + f.changes, 0) || 0,\n base: prInfo.base,\n head: prInfo.head,\n },\n\n // File Details\n files: prInfo.files || [],\n description: prInfo.body || '',\n\n // GitHub Event Context\n event: eventContext\n ? {\n name: eventContext.event_name || 'unknown',\n action: eventContext.action,\n isPullRequest: !prInfo.isIssue, // Set based on whether this is a PR or an issue\n\n // Repository Info\n repository: eventContext.repository\n ? {\n owner: (eventContext.repository as { owner?: { login?: string } })?.owner?.login,\n name: (eventContext.repository as { name?: string })?.name,\n fullName: eventContext.repository\n ? `${(eventContext.repository as { owner?: { login?: string } })?.owner?.login}/${(eventContext.repository as { name?: string })?.name}`\n : undefined,\n }\n : undefined,\n\n // Comment Data (for comment events)\n comment: eventContext.comment\n ? {\n body: (eventContext.comment as { body?: string })?.body,\n author: (eventContext.comment as { user?: { login?: string } })?.user?.login,\n }\n : undefined,\n\n // Issue Data (for issue events)\n issue: eventContext.issue\n ? {\n number: (eventContext.issue as { number?: number })?.number,\n title: (eventContext.issue as { title?: string })?.title,\n body: (eventContext.issue as { body?: string })?.body,\n state: (eventContext.issue as { state?: string })?.state,\n author: (eventContext.issue as { user?: { login?: string } })?.user?.login,\n labels: (eventContext.issue as { labels?: unknown[] })?.labels || [],\n assignees:\n (\n eventContext as { issue?: { assignees?: Array<{ login: string }> } }\n )?.issue?.assignees?.map(a => a.login) || [],\n createdAt: (eventContext.issue as { created_at?: string })?.created_at,\n updatedAt: (eventContext.issue as { updated_at?: string })?.updated_at,\n isPullRequest: !!(eventContext.issue as { pull_request?: unknown })?.pull_request,\n }\n : undefined,\n\n // Pull Request Event Data\n pullRequest: eventContext.pull_request\n ? {\n number: (eventContext.pull_request as { number?: number })?.number,\n state: (eventContext.pull_request as { state?: string })?.state,\n draft: (eventContext.pull_request as { draft?: boolean })?.draft,\n headSha: (eventContext.pull_request as { head?: { sha?: string } })?.head?.sha,\n headRef: (eventContext.pull_request as { head?: { ref?: string } })?.head?.ref,\n baseSha: (eventContext.pull_request as { base?: { sha?: string } })?.base?.sha,\n baseRef: (eventContext.pull_request as { base?: { ref?: string } })?.base?.ref,\n }\n : undefined,\n\n // Raw event payload for advanced use cases\n payload: eventContext,\n }\n : undefined,\n\n // Utility data for templates\n utils: {\n // Date/time helpers\n now: new Date().toISOString(),\n today: new Date().toISOString().split('T')[0],\n\n // Dynamic file grouping by extension\n filesByExtension: this.groupFilesByExtension(prInfo.files || []),\n\n // File status categorizations\n addedFiles: (prInfo.files || []).filter(f => f.status === 'added'),\n modifiedFiles: (prInfo.files || []).filter(f => f.status === 'modified'),\n removedFiles: (prInfo.files || []).filter(f => f.status === 'removed'),\n renamedFiles: (prInfo.files || []).filter(f => f.status === 'renamed'),\n\n // Change analysis\n hasLargeChanges: (prInfo.files || []).some(f => f.changes > 50),\n totalFiles: (prInfo.files || []).length,\n },\n\n // Previous check outputs (dependency results)\n // Expose raw output directly if available, otherwise expose the result as-is\n outputs: dependencyResults\n ? Object.fromEntries(\n Array.from(dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n (() => {\n const summary = result as ReviewSummary & { output?: unknown };\n return summary.output !== undefined ? summary.output : summary;\n })(),\n ])\n )\n : {},\n // Alias for consistency with other providers\n outputs_history: (() => {\n const hist: Record<string, unknown[]> = {};\n if (outputHistory) {\n for (const [k, v] of outputHistory.entries()) hist[k] = v;\n }\n return hist;\n })(),\n // Stage-scoped history slice calculated from baseline captured by the flow runner.\n outputs_history_stage: (() => {\n const stage: Record<string, unknown[]> = {};\n try {\n const base = (eventContext as any)?.__stageHistoryBase as\n | Record<string, number>\n | undefined;\n if (!outputHistory || !base) return stage;\n for (const [k, v] of outputHistory.entries()) {\n const start = base[k] || 0;\n const arr = Array.isArray(v) ? (v as unknown[]) : [];\n stage[k] = arr.slice(start);\n }\n } catch {}\n return stage;\n })(),\n // New: outputs_raw exposes aggregate values (e.g., full arrays for forEach parents)\n outputs_raw: outputsRaw,\n };\n\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n const outKeys = Object.keys((templateContext as any).outputs || {}).join(', ');\n const histKeys = Object.keys((templateContext as any).outputs_history || {}).join(', ');\n console.error(`[prompt-ctx] outputs.keys=${outKeys} hist.keys=${histKeys}`);\n }\n } catch {}\n\n try {\n return await this.liquidEngine.parseAndRender(promptContent, templateContext);\n } catch (error) {\n // Always show a helpful snippet with a caret, similar to YAML errors\n const err: any = error || {};\n const lines = String(promptContent || '').split(/\\r?\\n/);\n const lineNum: number = Number(err.line || err?.token?.line || err?.location?.line || 0);\n const colNum: number = Number(err.col || err?.token?.col || err?.location?.col || 0);\n let snippet = '';\n if (lineNum > 0) {\n const start = Math.max(1, lineNum - 3);\n const end = Math.max(lineNum + 2, lineNum);\n const width = String(end).length;\n for (let i = start; i <= Math.min(end, lines.length); i++) {\n const ln = `${String(i).padStart(width, ' ')} | ${lines[i - 1] ?? ''}`;\n snippet += ln + '\\n';\n if (i === lineNum) {\n const caretPad = ' '.repeat(Math.max(0, colNum > 1 ? colNum - 1 : 0) + width + 3);\n snippet += caretPad + '^\\n';\n }\n }\n } else {\n // Fallback preview of the first 20 lines\n const preview = lines\n .slice(0, 20)\n .map((l, i) => `${(i + 1).toString().padStart(3, ' ')} | ${l}`)\n .join('\\n');\n snippet = preview + '\\n';\n }\n const msg = `Failed to render prompt template: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`;\n // Print a clear, user-friendly error with context\n try {\n console.error('\\n[prompt-error] ' + msg + '\\n' + snippet);\n } catch {}\n throw new Error(msg);\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Apply environment configuration if present\n if (config.env) {\n const result = EnvironmentResolver.withTemporaryEnv(config.env, () => {\n // This will be executed with the temporary environment\n return this.executeWithConfig(prInfo, config, _dependencyResults, sessionInfo);\n });\n\n if (result instanceof Promise) {\n return result;\n }\n return result;\n }\n\n return this.executeWithConfig(prInfo, config, _dependencyResults, sessionInfo);\n }\n\n private async executeWithConfig(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: {\n parentSessionId?: string;\n reuseSession?: boolean;\n } & import('./check-provider.interface').ExecutionContext\n ): Promise<ReviewSummary> {\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n console.error(`[ai-exec] step=${String((config as any).checkName || 'unknown')}`);\n }\n } catch {}\n // Extract AI configuration - only set properties that are explicitly provided\n const aiConfig: AIReviewConfig = {};\n\n // Check-level AI configuration (ai object)\n if (config.ai) {\n // Only set properties that are actually defined to avoid overriding env vars\n if (config.ai.apiKey !== undefined) {\n aiConfig.apiKey = config.ai.apiKey as string;\n }\n if (config.ai.model !== undefined) {\n aiConfig.model = config.ai.model as string;\n }\n if (config.ai.timeout !== undefined) {\n aiConfig.timeout = config.ai.timeout as number;\n }\n if (config.ai.provider !== undefined) {\n aiConfig.provider = config.ai.provider as\n | 'google'\n | 'anthropic'\n | 'openai'\n | 'bedrock'\n | 'mock';\n }\n if (config.ai.debug !== undefined) {\n aiConfig.debug = config.ai.debug as boolean;\n }\n if (config.ai.enableDelegate !== undefined) {\n aiConfig.enableDelegate = config.ai.enableDelegate as boolean;\n }\n if (config.ai.allowEdit !== undefined) {\n aiConfig.allowEdit = config.ai.allowEdit as boolean;\n }\n if (config.ai.allowedTools !== undefined) {\n aiConfig.allowedTools = config.ai.allowedTools as string[];\n }\n if (config.ai.disableTools !== undefined) {\n aiConfig.disableTools = config.ai.disableTools as boolean;\n }\n if (config.ai.allowBash !== undefined) {\n aiConfig.allowBash = config.ai.allowBash as boolean;\n }\n if (config.ai.bashConfig !== undefined) {\n aiConfig.bashConfig = config.ai.bashConfig as import('../types/config').BashConfig;\n }\n if (config.ai.skip_code_context !== undefined) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (aiConfig as any).skip_code_context = config.ai.skip_code_context as boolean;\n }\n if (config.ai.retry !== undefined) {\n aiConfig.retry = config.ai.retry as import('../types/config').AIRetryConfig;\n }\n if (config.ai.fallback !== undefined) {\n aiConfig.fallback = config.ai.fallback as import('../types/config').AIFallbackConfig;\n }\n }\n\n // Check-level AI model and provider (top-level properties)\n if (config.ai_model !== undefined) {\n aiConfig.model = config.ai_model as string;\n }\n if (config.ai_provider !== undefined) {\n aiConfig.provider = config.ai_provider as\n | 'google'\n | 'anthropic'\n | 'openai'\n | 'bedrock'\n | 'mock';\n }\n\n // Get custom prompt from config - REQUIRED, no fallbacks\n const customPrompt = config.prompt;\n\n if (!customPrompt) {\n throw new Error(\n `No prompt defined for check. All checks must have prompts defined in .visor.yaml configuration.`\n );\n }\n\n // Setup MCP tools from multiple configuration levels\n const mcpServers: Record<string, import('../types/config').McpServerConfig> = {};\n\n // 1. Start with global MCP servers (from visor config root)\n const globalConfig = config as CheckProviderConfig & {\n ai_mcp_servers?: Record<string, import('../types/config').McpServerConfig>;\n };\n if (globalConfig.ai_mcp_servers) {\n Object.assign(mcpServers, globalConfig.ai_mcp_servers);\n }\n\n // 2. Add check-level MCP servers (overrides global)\n if (config.ai_mcp_servers) {\n Object.assign(mcpServers, config.ai_mcp_servers);\n }\n\n // 3. Add ai.mcpServers (overrides everything)\n if (config.ai?.mcpServers) {\n Object.assign(mcpServers, config.ai.mcpServers);\n }\n\n // Pass MCP server config directly to AI service (unless tools are disabled)\n if (Object.keys(mcpServers).length > 0 && !config.ai?.disableTools) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (aiConfig as any).mcpServers = mcpServers;\n // no noisy diagnostics here\n } else if (config.ai?.disableTools) {\n // silently skip MCP when tools disabled\n }\n\n // Build template context for state capture\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n outputs: _dependencyResults\n ? Object.fromEntries(\n Array.from(_dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n (result as any).output !== undefined ? (result as any).output : result,\n ])\n )\n : {},\n };\n\n // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for input context (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const ctxJson = JSON.stringify(templateContext);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.input.context': ctxJson },\n []\n );\n } catch {}\n\n // Process prompt with Liquid templates and file loading\n // Do NOT strip event context on skip_code_context — that flag only controls\n // whether we embed PR diffs/large code context later in AIReviewService.\n // Keep repository/comment metadata available for prompts and tests.\n const eventContext = config.eventContext || {};\n // Thread stageHistoryBase via eventContext for prompt rendering so\n // Liquid templates can get outputs_history_stage (computed from baseline).\n const ctxWithStage = {\n ...(eventContext || {}),\n __stageHistoryBase: (sessionInfo as any)?.stageHistoryBase as\n | Record<string, number>\n | undefined,\n } as Record<string, unknown>;\n\n const processedPrompt = await this.processPrompt(\n customPrompt,\n prInfo,\n ctxWithStage,\n _dependencyResults,\n (config as any).__outputHistory as Map<string, unknown[]> | undefined\n );\n\n // Optional persona (vendor extension): ai.ai_persona or ai_persona.\n // This is a light-weight preamble, not a rewriting of the user's prompt.\n const aiAny = (config.ai || {}) as any;\n // Persona (underscore only)\n const persona = (aiAny?.ai_persona || (config as any).ai_persona || '').toString().trim();\n const finalPrompt = persona ? `Persona: ${persona}\\n\\n${processedPrompt}` : processedPrompt;\n // Expose promptType to AIReviewService via env (bridge until ProbeAgent supports it in our SDK surface)\n try {\n const pt = ((config.ai as any)?.promptType || (config as any).ai_prompt_type || '')\n .toString()\n .trim();\n if (pt) process.env.VISOR_PROMPT_TYPE = pt;\n } catch {}\n\n // Test hook: capture the FINAL prompt (with PR context) before provider invocation\n try {\n const stepName = (config as any).checkName || 'unknown';\n const serviceForCapture = new AIReviewService(aiConfig);\n const finalPromptCapture = await (serviceForCapture as any).buildCustomPrompt(\n prInfo,\n finalPrompt,\n config.schema,\n {\n checkName: (config as any).checkName,\n skipPRContext: (config.ai as any)?.skip_code_context === true,\n }\n );\n sessionInfo?.hooks?.onPromptCaptured?.({\n step: String(stepName),\n provider: 'ai',\n prompt: finalPromptCapture,\n });\n // capture hook retained; no extra console diagnostics\n } catch {}\n\n // Test hook: mock output for this step (short-circuit provider)\n try {\n const stepName = (config as any).checkName || 'unknown';\n const mock = sessionInfo?.hooks?.mockForStep?.(String(stepName));\n if (mock !== undefined) {\n // If the mock looks like a ReviewSummary (has issues/content), use it directly\n if (\n mock &&\n typeof mock === 'object' &&\n ('issues' in (mock as any) || 'content' in (mock as any))\n ) {\n return mock as unknown as ReviewSummary;\n }\n // Otherwise treat it as provider output payload\n return { issues: [], output: mock } as ReviewSummary & { output: unknown };\n }\n } catch {}\n\n // Create AI service with config - environment variables will be used if aiConfig is empty\n try {\n const pt = (aiAny?.prompt_type || (config as any).ai_prompt_type || '').toString().trim();\n if (pt) (aiConfig as any).promptType = pt;\n // Prefer new system_prompt; fall back to legacy custom_prompt for backward compatibility\n const sys = (aiAny?.system_prompt || (config as any).ai_system_prompt || '')\n .toString()\n .trim();\n const legacy = (aiAny?.custom_prompt || (config as any).ai_custom_prompt || '')\n .toString()\n .trim();\n if (sys) (aiConfig as any).systemPrompt = sys;\n else if (legacy) (aiConfig as any).systemPrompt = legacy;\n } catch {}\n const service = new AIReviewService(aiConfig);\n\n // Pass the custom prompt and schema - no fallbacks\n const schema = config.schema as string | Record<string, unknown> | undefined;\n\n // Removed verbose AICheckProvider console diagnostics; rely on logger.debug when needed\n\n try {\n // No extra console diagnostics here\n\n let result: ReviewSummary;\n\n // Check if we should use session reuse (only if explicitly enabled on this check)\n // No extra reuse_ai_session console diagnostics\n const reuseEnabled =\n (config as any).reuse_ai_session === true ||\n typeof (config as any).reuse_ai_session === 'string';\n if (sessionInfo?.reuseSession && sessionInfo.parentSessionId && reuseEnabled) {\n // Safety: only reuse if the parent session actually exists\n try {\n const { SessionRegistry } = require('../session-registry');\n const reg = SessionRegistry.getInstance();\n if (!reg.hasSession(sessionInfo.parentSessionId)) {\n if (aiConfig.debug || process.env.VISOR_DEBUG === 'true') {\n console.warn(\n `⚠️ Parent session ${sessionInfo.parentSessionId} not found; creating a new session for ${config.checkName}`\n );\n }\n // Fall back to new session\n const fresh = await service.executeReview(\n prInfo,\n processedPrompt,\n schema,\n config.checkName,\n config.sessionId\n );\n return {\n ...fresh,\n issues: new IssueFilter(config.suppressionEnabled !== false).filterIssues(\n fresh.issues || [],\n process.cwd()\n ),\n };\n }\n } catch {}\n // Get session_mode from config, default to 'clone'\n const sessionMode = (config.session_mode as 'clone' | 'append') || 'clone';\n\n if (aiConfig.debug) {\n console.error(\n `🔄 Debug: Using session reuse with parent session: ${sessionInfo.parentSessionId} (mode: ${sessionMode})`\n );\n }\n result = await service.executeReviewWithSessionReuse(\n prInfo,\n processedPrompt,\n sessionInfo.parentSessionId,\n schema,\n config.checkName,\n sessionMode\n );\n } else {\n if (aiConfig.debug) {\n console.error(`🆕 Debug: Creating new AI session for check: ${config.checkName}`);\n }\n result = await service.executeReview(\n prInfo,\n finalPrompt,\n schema,\n config.checkName,\n config.sessionId\n );\n }\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n const finalResult = {\n ...result,\n issues: filteredIssues,\n };\n\n // Capture AI provider call and output in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureProviderCall(\n span,\n 'ai',\n {\n prompt: processedPrompt.substring(0, 500), // Preview only\n model: aiConfig.model,\n },\n {\n content: JSON.stringify(finalResult).substring(0, 500),\n tokens: (result as any).usage?.totalTokens,\n }\n );\n const outputForSpan = (finalResult as { output?: unknown }).output ?? finalResult;\n captureCheckOutput(span, outputForSpan);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for output (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const outJson = JSON.stringify((finalResult as any).output ?? finalResult);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.output': outJson },\n []\n );\n } catch {}\n\n return finalResult;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Log detailed error information\n console.error(`❌ AI Check Provider Error for check: ${errorMessage}`);\n\n // Check if this is a critical error (authentication, rate limits, etc)\n const isCriticalError =\n errorMessage.includes('API rate limit') ||\n errorMessage.includes('403') ||\n errorMessage.includes('401') ||\n errorMessage.includes('authentication') ||\n errorMessage.includes('API key');\n\n if (isCriticalError) {\n console.error(`🚨 CRITICAL ERROR: AI provider authentication or rate limit issue detected`);\n console.error(`🚨 This check cannot proceed without valid API credentials`);\n }\n\n // Re-throw with more context\n throw new Error(`AI analysis failed: ${errorMessage}`);\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'focus',\n 'schema',\n 'group',\n 'ai.provider',\n 'ai.model',\n 'ai.apiKey',\n 'ai.timeout',\n 'ai.mcpServers',\n 'ai.enableDelegate',\n // legacy persona/prompt keys supported in config\n 'ai_persona',\n 'ai_prompt_type',\n 'ai_custom_prompt',\n 'ai_system_prompt',\n // new provider resilience and tools toggles\n 'ai.retry',\n 'ai.fallback',\n 'ai.allowEdit',\n 'ai.allowedTools',\n 'ai.disableTools',\n 'ai.allowBash',\n 'ai.bashConfig',\n 'ai_model',\n 'ai_provider',\n 'ai_mcp_servers',\n 'env',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Check if any AI API key is available\n return !!(\n process.env.GOOGLE_API_KEY ||\n process.env.ANTHROPIC_API_KEY ||\n process.env.OPENAI_API_KEY ||\n // AWS Bedrock credentials check\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_BEDROCK_API_KEY\n );\n }\n\n getRequirements(): string[] {\n return [\n 'At least one of: GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, or AWS credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)',\n 'Optional: MODEL_NAME environment variable',\n 'Optional: AWS_REGION for Bedrock provider',\n 'Network access to AI provider APIs',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { IssueFilter } from '../issue-filter';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { trace, context as otContext } from '../telemetry/lazy-otel';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureProviderCall,\n} from '../telemetry/state-capture';\nimport { EnvironmentResolver } from '../utils/env-resolver';\n\n/**\n * Check provider that sends data to an HTTP endpoint, typically used as an output/notification provider\n */\nexport class HttpCheckProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n getName(): string {\n return 'http';\n }\n\n getDescription(): string {\n return 'Send data to external HTTP endpoint for notifications or integration';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http'\n if (cfg.type !== 'http') {\n return false;\n }\n\n // Must have URL specified\n if (typeof cfg.url !== 'string' || !cfg.url) {\n return false;\n }\n\n // Must have body template specified\n if (typeof cfg.body !== 'string' || !cfg.body) {\n return false;\n }\n\n // Validate URL format\n try {\n new URL(cfg.url as string);\n return true;\n } catch {\n return false;\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const url = config.url as string;\n const bodyTemplate = config.body as string;\n const method = (config.method as string) || 'POST';\n const headers = (config.headers as Record<string, string>) || {};\n const timeout = (config.timeout as number) || 30000;\n\n // Prepare template context with all available data\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n },\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n patch: f.patch,\n })),\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n metadata: config.metadata || {},\n };\n\n // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\n }\n\n // Render the body template\n let payload: Record<string, unknown>;\n try {\n const renderedBody = await this.liquid.parseAndRender(bodyTemplate, templateContext);\n // Try to parse as JSON, otherwise send as plain text\n try {\n payload = JSON.parse(renderedBody);\n } catch {\n payload = { message: renderedBody };\n }\n } catch (error) {\n return this.createErrorResult(\n url,\n new Error(\n `Template rendering failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n );\n }\n\n try {\n // Resolve environment variables in headers\n const resolvedHeaders = EnvironmentResolver.resolveHeaders(headers);\n\n // Send webhook request\n const response = await this.sendWebhookRequest(\n url,\n method,\n resolvedHeaders,\n payload,\n timeout\n );\n\n // Parse webhook response\n const result = this.parseWebhookResponse(response, url);\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n const finalResult = {\n ...result,\n issues: filteredIssues,\n };\n\n // Capture HTTP provider call and output in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n // Sanitize headers for telemetry to avoid exposing sensitive data\n const sanitizedHeaders = EnvironmentResolver.sanitizeHeaders(resolvedHeaders);\n captureProviderCall(\n span,\n 'http',\n {\n url,\n method,\n headers: sanitizedHeaders,\n body: JSON.stringify(payload).substring(0, 500),\n },\n {\n content: JSON.stringify(response).substring(0, 500),\n }\n );\n const outputForSpan = (finalResult as { output?: unknown }).output ?? finalResult;\n captureCheckOutput(span, outputForSpan);\n }\n } catch {\n // Ignore telemetry errors\n }\n\n return finalResult;\n } catch (error) {\n return this.createErrorResult(url, error);\n }\n }\n\n private async sendWebhookRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n payload: Record<string, unknown>,\n timeout: number\n ): Promise<Record<string, unknown>> {\n // Check if fetch is available (Node 18+)\n if (typeof fetch === 'undefined') {\n throw new Error('Webhook provider requires Node.js 18+ or node-fetch package');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Webhook returned ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as Record<string, unknown>;\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Webhook request timed out after ${timeout}ms`);\n }\n\n throw error;\n }\n }\n\n private parseWebhookResponse(response: Record<string, unknown>, url: string): ReviewSummary {\n // Validate and normalize the webhook response\n if (!response || typeof response !== 'object') {\n return this.createErrorResult(url, new Error('Invalid webhook response format'));\n }\n\n const issues: ReviewIssue[] = Array.isArray(response.comments)\n ? (response.comments as Array<Record<string, unknown>>).map(c => ({\n file: (c.file as string) || 'unknown',\n line: (c.line as number) || 0,\n endLine: c.endLine as number | undefined,\n ruleId: (c.ruleId as string) || `webhook/${this.validateCategory(c.category)}`,\n message: (c.message as string) || '',\n severity: this.validateSeverity(c.severity),\n category: this.validateCategory(c.category),\n suggestion: c.suggestion as string | undefined,\n replacement: c.replacement as string | undefined,\n }))\n : [];\n\n return {\n issues,\n };\n }\n\n private createErrorResult(url: string, error: unknown): ReviewSummary {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n return {\n issues: [\n {\n file: 'webhook',\n line: 0,\n endLine: undefined,\n ruleId: 'webhook/error',\n message: `Webhook execution error: ${errorMessage}`,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n };\n }\n\n private validateSeverity(severity: unknown): 'info' | 'warning' | 'error' | 'critical' {\n const valid = ['info', 'warning', 'error', 'critical'];\n return valid.includes(severity as string)\n ? (severity as 'info' | 'warning' | 'error' | 'critical')\n : 'info';\n }\n\n private validateCategory(\n category: unknown\n ): 'security' | 'performance' | 'style' | 'logic' | 'documentation' {\n const valid = ['security', 'performance', 'style', 'logic', 'documentation'];\n return valid.includes(category as string)\n ? (category as 'security' | 'performance' | 'style' | 'logic' | 'documentation')\n : 'logic';\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'url',\n 'body',\n 'method',\n 'headers',\n 'timeout',\n 'metadata',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'schedule',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // HTTP provider is available if fetch is available\n return typeof fetch !== 'undefined';\n }\n\n getRequirements(): string[] {\n return [\n 'Valid HTTP URL',\n 'Body template (Liquid) for payload construction',\n 'Network access to HTTP endpoint',\n 'Optional: Dependencies for accessing their outputs in templates',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\n\n/**\n * Check provider that receives input from HTTP webhooks and makes it available to dependent checks\n */\nexport class HttpInputProvider extends CheckProvider {\n private liquid: Liquid;\n private webhookContext?: Map<string, unknown>;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n\n /**\n * Set webhook context for accessing webhook data\n */\n setWebhookContext(webhookContext: Map<string, unknown>): void {\n this.webhookContext = webhookContext;\n }\n\n getName(): string {\n return 'http_input';\n }\n\n getDescription(): string {\n return 'Receive and process HTTP webhook input data for use by dependent checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http_input'\n if (cfg.type !== 'http_input') {\n return false;\n }\n\n // Must have endpoint specified\n if (typeof cfg.endpoint !== 'string' || !cfg.endpoint) {\n return false;\n }\n\n // Transform is optional but must be string if provided\n if (cfg.transform !== undefined && typeof cfg.transform !== 'string') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const endpoint = config.endpoint as string;\n const transform = config.transform as string | undefined;\n\n // In actual implementation, this would receive data from the webhook server\n // For now, we'll check if there's webhook data in the execution context\n const webhookData = this.getWebhookData(endpoint);\n\n if (!webhookData) {\n return {\n issues: [],\n };\n }\n\n // Apply transformation if specified\n let processedData = webhookData;\n if (transform) {\n try {\n const templateContext = {\n webhook: webhookData,\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n },\n };\n const rendered = await this.liquid.parseAndRender(transform, templateContext);\n processedData = JSON.parse(rendered);\n logger.verbose(`✓ Applied webhook transform successfully`);\n } catch (error) {\n logger.error(\n `✗ Failed to transform webhook data: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'webhook_input',\n line: 0,\n ruleId: 'webhook_input/transform_error',\n message: `Failed to transform webhook data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Return the processed data as a custom field for dependent checks to access\n // This will be available in outputs for dependent checks\n return {\n issues: [],\n // Add custom data field that will be passed through\n data: processedData,\n } as ReviewSummary & { data: unknown };\n }\n\n private getWebhookData(endpoint: string): Record<string, unknown> | null {\n // Use webhook context if available (preferred method)\n if (this.webhookContext) {\n return (this.webhookContext.get(endpoint) as Record<string, unknown>) || null;\n }\n\n // Fallback to global store for backwards compatibility\n // This should be removed once all usages are migrated\n const globalWebhookStore = (global as Record<string, unknown>).__visor_webhook_data as\n | Map<string, Record<string, unknown>>\n | undefined;\n if (globalWebhookStore && globalWebhookStore.get) {\n console.warn(\n 'HttpInputProvider: Using deprecated global webhook store. Please use webhook context instead.'\n );\n return globalWebhookStore.get(endpoint) || null;\n }\n\n return null;\n }\n\n getSupportedConfigKeys(): string[] {\n return ['type', 'endpoint', 'transform', 'on', 'depends_on', 'if', 'group'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Available if webhook server is configured and running\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'HTTP server must be configured and running',\n 'Valid endpoint path specified',\n 'Optional: Transform template for data processing',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { EnvironmentResolver } from '../utils/env-resolver';\n\n/**\n * Check provider that fetches data from HTTP endpoints\n */\nexport class HttpClientProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n\n getName(): string {\n return 'http_client';\n }\n\n getDescription(): string {\n return 'Fetch data from HTTP endpoints for use by dependent checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http_client'\n if (cfg.type !== 'http_client') {\n return false;\n }\n\n // Must have URL specified\n if (typeof cfg.url !== 'string' || !cfg.url) {\n return false;\n }\n\n // Validate URL format\n try {\n new URL(cfg.url as string);\n return true;\n } catch {\n return false;\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: import('./check-provider.interface').ExecutionContext\n ): Promise<ReviewSummary> {\n const url = config.url as string;\n const method = (config.method as string) || 'GET';\n const headers = (config.headers as Record<string, string>) || {};\n const timeout = (config.timeout as number) || 30000;\n const transform = config.transform as string | undefined;\n const bodyTemplate = config.body as string | undefined;\n\n try {\n // Prepare template context for URL and body\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n },\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n env: process.env,\n };\n\n // Render URL with template if it contains liquid syntax\n let renderedUrl = url;\n if (url.includes('{{') || url.includes('{%')) {\n renderedUrl = await this.liquid.parseAndRender(url, templateContext);\n }\n\n // Prepare request body if provided\n let requestBody: string | undefined;\n if (bodyTemplate) {\n const renderedBody = await this.liquid.parseAndRender(bodyTemplate, templateContext);\n requestBody = renderedBody;\n }\n\n // Resolve environment variables in headers\n const resolvedHeaders = EnvironmentResolver.resolveHeaders(headers);\n\n // Test hook: mock HTTP response for this step\n const stepName = (config as any).checkName || 'unknown';\n const mock = context?.hooks?.mockForStep?.(String(stepName));\n const data =\n mock !== undefined\n ? mock\n : await this.fetchData(renderedUrl, method, resolvedHeaders, requestBody, timeout);\n\n // Apply transformation if specified\n let processedData = data;\n if (transform) {\n try {\n const transformContext = {\n response: data,\n pr: templateContext.pr,\n outputs: templateContext.outputs,\n };\n const rendered = await this.liquid.parseAndRender(transform, transformContext);\n // Try to parse as JSON if the transform result looks like JSON\n if (rendered.trim().startsWith('{') || rendered.trim().startsWith('[')) {\n processedData = JSON.parse(rendered);\n } else {\n processedData = rendered;\n }\n } catch (error) {\n return {\n issues: [\n {\n file: 'http_client',\n line: 0,\n ruleId: 'http_client/transform_error',\n message: `Failed to transform response data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Return the fetched data as a custom field for dependent checks to access\n return {\n issues: [],\n // Add custom data field that will be passed through to dependent checks\n data: processedData,\n } as ReviewSummary & { data: unknown };\n } catch (error) {\n return {\n issues: [\n {\n file: 'http_client',\n line: 0,\n ruleId: 'http_client/fetch_error',\n message: `Failed to fetch from ${url}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n private async fetchData(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: string,\n timeout: number = 30000\n ): Promise<unknown> {\n // Check if fetch is available (Node 18+)\n if (typeof fetch === 'undefined') {\n throw new Error('HTTP client provider requires Node.js 18+ or node-fetch package');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const requestOptions: RequestInit = {\n method,\n headers: {\n ...headers,\n },\n signal: controller.signal,\n };\n\n // Add body for non-GET requests\n if (method !== 'GET' && body) {\n requestOptions.body = body;\n // Set Content-Type if not already set\n if (!headers['Content-Type'] && !headers['content-type']) {\n requestOptions.headers = {\n ...requestOptions.headers,\n 'Content-Type': 'application/json',\n };\n }\n }\n\n const response = await fetch(url, requestOptions);\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Try to parse as JSON first\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n return await response.json();\n }\n\n // Otherwise return as text\n const text = await response.text();\n\n // Try to parse as JSON if it looks like JSON\n if (text.trim().startsWith('{') || text.trim().startsWith('[')) {\n try {\n return JSON.parse(text);\n } catch {\n // Not JSON, return as text\n return text;\n }\n }\n\n return text;\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${timeout}ms`);\n }\n\n throw error;\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'url',\n 'method',\n 'headers',\n 'body',\n 'transform',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'schedule',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // HTTP client is available if fetch is available\n return typeof fetch !== 'undefined';\n }\n\n getRequirements(): string[] {\n return [\n 'Valid HTTP/HTTPS URL to fetch from',\n 'Network access to the endpoint',\n 'Optional: Transform template for processing response data',\n 'Optional: Body template for POST/PUT requests',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\n\n/**\n * No-operation check provider that doesn't perform any analysis.\n *\n * This provider is designed for command orchestration - it allows creating\n * checks that exist purely to trigger other checks through dependencies.\n *\n * Example use case: A \"/review\" command that triggers multiple analysis checks\n * without performing any analysis itself.\n */\nexport class NoopCheckProvider extends CheckProvider {\n getName(): string {\n return 'noop';\n }\n\n getDescription(): string {\n return 'No-operation provider for command orchestration and dependency triggering';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'noop'\n if (cfg.type !== 'noop') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n _prInfo: PRInfo,\n _config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Noop provider doesn't perform any analysis\n // It exists purely for command orchestration and dependency triggering\n return {\n issues: [],\n };\n }\n\n getSupportedConfigKeys(): string[] {\n return ['type', 'command', 'depends_on', 'on', 'if', 'group'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Noop provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for command orchestration and dependency triggering',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig, ExecutionContext } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\n\n/**\n * Log levels supported by the log provider\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Check provider that outputs debugging and logging information.\n * Useful for troubleshooting check workflows and understanding execution flow.\n */\nexport class LogCheckProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n strictVariables: false,\n strictFilters: false,\n });\n }\n\n getName(): string {\n return 'log';\n }\n\n getDescription(): string {\n return 'Output debugging and logging information for troubleshooting check workflows';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'log'\n if (cfg.type !== 'log') {\n return false;\n }\n\n // Message is required\n if (!cfg.message || typeof cfg.message !== 'string') {\n return false;\n }\n\n // Validate log level if provided\n if (cfg.level && !['debug', 'info', 'warn', 'error'].includes(cfg.level as string)) {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n const message = config.message as string;\n const level = (config.level as LogLevel) || 'info';\n const includePrContext = config.include_pr_context !== false;\n const includeDependencies = config.include_dependencies !== false;\n const includeMetadata = config.include_metadata !== false;\n\n // Prepare template context\n const templateContext = this.buildTemplateContext(\n prInfo,\n dependencyResults,\n includePrContext,\n includeDependencies,\n includeMetadata,\n config.__outputHistory as Map<string, unknown[]> | undefined,\n context\n );\n\n // Render the log message template\n const renderedMessage = await this.liquid.parseAndRender(message, templateContext);\n\n // Build the log output\n const logOutput = this.formatLogOutput(\n level,\n renderedMessage,\n templateContext,\n includePrContext,\n includeDependencies,\n includeMetadata\n );\n\n // Route through centralized logger to keep stdout clean in JSON/SARIF\n if (level === 'error') logger.error(logOutput);\n else if (level === 'warn') logger.warn(logOutput);\n else if (level === 'debug') logger.debug(logOutput);\n else logger.info(logOutput);\n\n // Return with the log content as custom data for dependent checks\n return {\n issues: [],\n // Add log output as custom field\n logOutput,\n } as ReviewSummary & { logOutput: string };\n }\n\n private buildTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n _includePrContext: boolean = true,\n _includeDependencies: boolean = true,\n includeMetadata: boolean = true,\n outputHistory?: Map<string, unknown[]>,\n executionContext?: ExecutionContext\n ): Record<string, unknown> {\n const context: Record<string, unknown> = {};\n\n // Always provide pr context for template rendering\n context.pr = {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n })),\n };\n\n // Add convenience data\n context.filenames = prInfo.files.map(f => f.filename);\n context.fileCount = prInfo.files.length;\n\n // Always provide dependency data for template rendering\n if (dependencyResults) {\n const dependencies: Record<string, unknown> = {};\n const outputs: Record<string, unknown> = {};\n const outputsRaw: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n context.dependencyCount = dependencyResults.size;\n\n for (const [checkName, result] of dependencyResults.entries()) {\n if (typeof checkName !== 'string') continue;\n dependencies[checkName] = {\n issueCount: result.issues?.length || 0,\n suggestionCount: 0,\n issues: result.issues || [],\n };\n\n // Add outputs namespace for accessing dependency results directly\n const summary = result as import('../reviewer').ReviewSummary & { output?: unknown };\n if (typeof checkName === 'string' && checkName.endsWith('-raw')) {\n const name = checkName.slice(0, -4);\n outputsRaw[name] = summary.output !== undefined ? summary.output : summary;\n } else {\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n }\n\n // Add history for each check if available\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n history[checkName] = historyArray;\n }\n }\n\n // Attach history to the outputs object\n (outputs as any).history = history;\n\n context.dependencies = dependencies;\n context.outputs = outputs;\n // Alias: outputs_history mirrors outputs.history for consistency\n (context as any).outputs_history = history;\n // New: outputs_raw exposes aggregate values (e.g., arrays) for forEach parents\n (context as any).outputs_raw = outputsRaw;\n }\n\n if (includeMetadata) {\n context.metadata = {\n timestamp: new Date().toISOString(),\n executionTime: Date.now(),\n nodeVersion: process.version,\n platform: process.platform,\n workingDirectory: process.cwd(),\n };\n }\n\n // Add workflow inputs if available\n const workflowInputs = executionContext?.workflowInputs || {};\n logger.debug(\n `[LogProvider] Adding ${Object.keys(workflowInputs).length} workflow inputs to context`\n );\n context.inputs = workflowInputs;\n\n return context;\n }\n\n private formatLogOutput(\n level: LogLevel,\n message: string,\n templateContext: Record<string, unknown>,\n includePrContext: boolean,\n includeDependencies: boolean,\n includeMetadata: boolean\n ): string {\n const sections: string[] = [];\n\n // Log level and message\n const levelEmoji = this.getLevelEmoji(level);\n sections.push(`${levelEmoji} **${level.toUpperCase()}**: ${message}`);\n\n // PR context section\n if (includePrContext && templateContext.pr) {\n const pr = templateContext.pr as Record<string, unknown>;\n sections.push('');\n sections.push('### PR Context');\n sections.push(`- **PR #${pr.number}**: ${pr.title}`);\n sections.push(`- **Author**: ${pr.author}`);\n sections.push(`- **Base**: ${pr.base} → **Head**: ${pr.head}`);\n sections.push(`- **Changes**: +${pr.totalAdditions} -${pr.totalDeletions}`);\n sections.push(`- **Files Modified**: ${templateContext.fileCount}`);\n }\n\n // Dependencies section\n if (includeDependencies && templateContext.dependencies) {\n const deps = templateContext.dependencies as Record<string, Record<string, unknown>>;\n sections.push('');\n sections.push('### Dependency Results');\n\n if (Object.keys(deps).length === 0) {\n sections.push('- No dependency results available');\n } else {\n for (const [checkName, result] of Object.entries(deps)) {\n sections.push(\n `- **${checkName}**: ${result.issueCount} issues, ${result.suggestionCount} suggestions`\n );\n }\n }\n }\n\n // Metadata section\n if (includeMetadata && templateContext.metadata) {\n const meta = templateContext.metadata as Record<string, unknown>;\n sections.push('');\n sections.push('### Execution Metadata');\n sections.push(`- **Timestamp**: ${meta.timestamp}`);\n sections.push(`- **Node Version**: ${meta.nodeVersion}`);\n sections.push(`- **Platform**: ${meta.platform}`);\n sections.push(`- **Working Directory**: ${meta.workingDirectory}`);\n }\n\n return sections.join('\\n');\n }\n\n private getLevelEmoji(level: LogLevel): string {\n switch (level) {\n case 'debug':\n return '🐛';\n case 'info':\n return 'ℹ️';\n case 'warn':\n return '⚠️';\n case 'error':\n return '❌';\n default:\n return 'ℹ️';\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'message',\n 'level',\n 'include_pr_context',\n 'include_dependencies',\n 'include_metadata',\n 'group',\n 'command',\n 'depends_on',\n 'on',\n 'if',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Log provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for debugging and logging check execution flow',\n ];\n }\n}\n","import type { RecordingOctokit } from './github-recorder';\n\nlet __rec: RecordingOctokit | null = null;\n\nexport function setGlobalRecorder(r: RecordingOctokit | null): void {\n __rec = r;\n}\n\nexport function getGlobalRecorder(): RecordingOctokit | null {\n return __rec;\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox } from '../utils/sandbox';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\n\nexport class GitHubOpsProvider extends CheckProvider {\n private sandbox?: Sandbox;\n\n getName(): string {\n return 'github';\n }\n\n getDescription(): string {\n return 'Native GitHub operations (labels, comments, reviewers) executed via Octokit';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') return false;\n const cfg = config as CheckProviderConfig & { op?: string };\n return typeof cfg.op === 'string' && cfg.op.length > 0;\n }\n\n getSupportedConfigKeys(): string[] {\n return ['op', 'values', 'value'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Available when running in GitHub context or when a token is provided\n return Boolean(\n process.env.GITHUB_TOKEN || process.env['INPUT_GITHUB-TOKEN'] || process.env.GITHUB_REPOSITORY\n );\n }\n\n getRequirements(): string[] {\n return ['GITHUB_TOKEN or INPUT_GITHUB-TOKEN', 'GITHUB_REPOSITORY'];\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<ReviewSummary> {\n const cfg = config as CheckProviderConfig & {\n op: string;\n values?: string[] | string;\n value?: string;\n };\n\n // IMPORTANT: Always prefer authenticated octokit from event context (GitHub App or token)\n // This ensures proper bot identity in reactions, labels, and comments\n let octokit: import('@octokit/rest').Octokit | undefined = config.eventContext?.octokit as\n | import('@octokit/rest').Octokit\n | undefined;\n if (process.env.VISOR_DEBUG === 'true') {\n try {\n logger.debug(`[github-ops] pre-fallback octokit? ${!!octokit}`);\n } catch {}\n }\n // Test runner fallback: use global recorder if eventContext is missing octokit\n if (!octokit) {\n try {\n const { getGlobalRecorder } = require('../test-runner/recorders/global-recorder');\n const rec = getGlobalRecorder && getGlobalRecorder();\n if (rec) octokit = rec as any;\n } catch {}\n }\n\n if (!octokit) {\n if (process.env.VISOR_DEBUG === 'true') {\n try {\n console.error('[github-ops] missing octokit after fallback — returning issue');\n } catch {}\n }\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/missing_octokit',\n message:\n 'No authenticated Octokit instance available in event context. GitHub operations require proper authentication context.',\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n const repoEnv = process.env.GITHUB_REPOSITORY || '';\n let owner = '';\n let repo = '';\n if (repoEnv.includes('/')) {\n [owner, repo] = repoEnv.split('/') as [string, string];\n } else {\n try {\n const ec: any = config.eventContext || {};\n owner = ec?.repository?.owner?.login || owner;\n repo = ec?.repository?.name || repo;\n } catch {}\n }\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n logger.info(\n `[github-ops] context octokit? ${!!octokit} repo=${owner}/${repo} pr#=${prInfo?.number}`\n );\n }\n } catch {}\n if (!owner || !repo || !prInfo?.number) {\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/missing_context',\n message: 'Missing owner/repo or PR number; GitHub operations require Action context',\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n // Build values list (allow string or array), render Liquid templates if present, and normalize\n let valuesRaw: string[] = [];\n if (Array.isArray(cfg.values)) valuesRaw = (cfg.values as unknown[]).map(v => String(v));\n else if (typeof cfg.values === 'string') valuesRaw = [cfg.values];\n else if (typeof cfg.value === 'string') valuesRaw = [cfg.value];\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n logger.info(`[github-ops] op=${cfg.op} valuesRaw(before)=${JSON.stringify(valuesRaw)}`);\n }\n } catch {}\n\n // Liquid render helper for values\n const renderValues = async (arr: string[]): Promise<string[]> => {\n if (!arr || arr.length === 0) return [];\n const liq = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n const outputs: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [name, result] of dependencyResults.entries()) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n // Fallback: if outputs missing but engine provided history, use last output snapshot\n try {\n const hist = (config as any).__outputHistory as Map<string, unknown[]> | undefined;\n if (hist) {\n for (const [name, arr] of hist.entries()) {\n if (!outputs[name] && Array.isArray(arr) && arr.length > 0) {\n outputs[name] = arr[arr.length - 1];\n }\n }\n }\n } catch {}\n const ctx = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n authorAssociation: prInfo.authorAssociation,\n },\n outputs,\n };\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n logger.info(`[github-ops] deps keys=${Object.keys(outputs).join(', ')}`);\n const ov = outputs['overview'] as any;\n if (ov) {\n logger.info(`[github-ops] outputs.overview.keys=${Object.keys(ov).join(',')}`);\n if (ov.tags) {\n logger.info(\n `[github-ops] outputs.overview.tags keys=${Object.keys(ov.tags).join(',')}`\n );\n try {\n logger.info(\n `[github-ops] outputs.overview.tags['review-effort']=${String(ov.tags['review-effort'])}`\n );\n } catch {}\n }\n }\n }\n } catch {}\n const out: string[] = [];\n for (const item of arr) {\n if (typeof item === 'string' && (item.includes('{{') || item.includes('{%'))) {\n try {\n const rendered = await liq.parseAndRender(item, ctx);\n out.push(rendered);\n } catch (e) {\n // If Liquid fails, surface as a provider error\n const msg = e instanceof Error ? e.message : String(e);\n if (process.env.VISOR_DEBUG === 'true') {\n logger.warn(`[github-ops] liquid_render_error: ${msg}`);\n }\n return Promise.reject({\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/liquid_render_error',\n message: `Failed to render template: ${msg}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n } as ReviewSummary);\n }\n } else {\n out.push(String(item));\n }\n }\n return out;\n };\n\n let values: string[] = await renderValues(valuesRaw);\n\n // Flatten helpers: allow a single Liquid-rendered value to represent\n // a JSON array (e.g., \"{{ outputs['issue-assistant'].labels | json }}\")\n // or a newline-separated list. This makes explicit YAML configs expressive\n // without re-introducing value_js.\n try {\n const flattened: string[] = [];\n for (const v of values) {\n const t = String(v ?? '').trim();\n if (!t) continue;\n let expanded = false;\n // JSON array expansion\n if (t.startsWith('[') && t.endsWith(']')) {\n try {\n const arr = JSON.parse(t);\n if (Array.isArray(arr)) {\n for (const x of arr) flattened.push(String(x ?? ''));\n expanded = true;\n }\n } catch {}\n }\n if (expanded) continue;\n // Newline-separated fallback (one per line)\n if (t.includes('\\n')) {\n for (const line of t.split('\\n')) {\n const s = line.trim();\n if (s) flattened.push(s);\n }\n expanded = true;\n }\n if (!expanded) flattened.push(t);\n }\n values = flattened;\n } catch {}\n\n // Expose dependency outputs to value_js for convenience (generic map)\n const depOutputs: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [name, result] of dependencyResults.entries()) {\n const summary = result as ReviewSummary & { output?: unknown };\n depOutputs[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n\n // Provider-side normalization replaces legacy value_js usage\n const sanitizeLabel = (s: string) =>\n s\n .replace(/[^A-Za-z0-9:\\/\\- ]/g, '')\n .replace(/\\/{2,}/g, '/')\n .trim();\n values = (Array.isArray(values) ? values : [])\n .map(v => String(v ?? ''))\n .map(sanitizeLabel)\n .filter(Boolean);\n\n // Fallback: if values are still empty, try deriving from dependency outputs\n // 1) Common pattern: outputs.<dep>.labels (e.g., from issue-assistant)\n if (values.length === 0 && Object.keys(depOutputs).length > 0) {\n try {\n const lbls: string[] = [];\n for (const obj of Object.values(depOutputs)) {\n const labelsAny = (obj as any)?.labels;\n if (Array.isArray(labelsAny)) {\n for (const v of labelsAny) lbls.push(String(v ?? ''));\n }\n }\n const norm = lbls\n .map(s => s.trim())\n .filter(Boolean)\n .map(s => s.replace(/[^A-Za-z0-9:\\/\\- ]/g, '').replace(/\\/{2,}/g, '/'));\n values = Array.from(new Set(norm));\n if (process.env.VISOR_DEBUG === 'true') {\n logger.info(`[github-ops] derived values from deps.labels: ${JSON.stringify(values)}`);\n }\n } catch {}\n }\n\n // 2) Fallback: outputs.<dep>.tags based derivation (overview-style)\n // Fallback: if values are still empty, try deriving from dependency outputs (common pattern: outputs.<dep>.tags)\n if (values.length === 0 && dependencyResults && dependencyResults.size > 0) {\n try {\n const derived: string[] = [];\n for (const result of dependencyResults.values()) {\n const out = (result as ReviewSummary & { output?: unknown })?.output ?? result;\n const tags = (out as Record<string, unknown>)?.['tags'] as\n | Record<string, unknown>\n | undefined;\n if (tags && typeof tags === 'object') {\n const label = tags['label'];\n const effort = (tags as Record<string, unknown>)['review-effort'];\n if (label != null) derived.push(String(label));\n if (effort !== undefined && effort !== null)\n derived.push(`review/effort:${String(effort)}`);\n }\n }\n values = derived;\n if (process.env.VISOR_DEBUG === 'true') {\n logger.info(`[github-ops] derived values from deps: ${JSON.stringify(values)}`);\n }\n } catch {}\n }\n\n // Trim (already sanitized), drop empty, and de-duplicate values regardless of source\n values = Array.from(new Set(values));\n\n try {\n // Minimal debug to help diagnose label flow under tests\n if (process.env.NODE_ENV === 'test' || process.env.VISOR_DEBUG === 'true') {\n logger.info(`[github-ops] ${cfg.op} resolved values: ${JSON.stringify(values)}`);\n }\n } catch {}\n\n try {\n switch (cfg.op) {\n case 'labels.add': {\n if (values.length === 0) break; // no-op if nothing to add\n try {\n if (process.env.VISOR_OUTPUT_FORMAT !== 'json')\n logger.step(`[github-ops] labels.add -> ${JSON.stringify(values)}`);\n } catch {}\n await octokit.rest.issues.addLabels({\n owner,\n repo,\n issue_number: prInfo.number,\n labels: values,\n });\n break;\n }\n case 'labels.remove': {\n for (const l of values) {\n await octokit.rest.issues.removeLabel({\n owner,\n repo,\n issue_number: prInfo.number,\n name: l,\n });\n }\n break;\n }\n case 'comment.create': {\n const body = values.join('\\n').trim();\n if (body)\n await octokit.rest.issues.createComment({\n owner,\n repo,\n issue_number: prInfo.number,\n body,\n });\n break;\n }\n default:\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/unsupported_op',\n message: `Unsupported GitHub op: ${cfg.op}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n return { issues: [] };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n try {\n logger.error(`[github-ops] op_failed ${cfg.op}: ${msg}`);\n } catch {}\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/op_failed',\n message: `GitHub operation failed (${cfg.op}): ${msg}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n /**\n * Create a secure sandbox for evaluating small expressions without access to process/env\n */\n private getSecureSandbox(): Sandbox {\n if (this.sandbox) return this.sandbox;\n this.sandbox = createSecureSandbox();\n return this.sandbox;\n }\n}\n","/**\n * Type definitions for Claude Code SDK and MCP SDK\n * These are placeholder types for when the packages aren't installed\n */\n\n// Claude Code SDK types\nexport interface ClaudeCodeQuery {\n query: string;\n tools?: Array<{\n name: string;\n [key: string]: unknown;\n }>;\n subagent?: string;\n maxTurns?: number;\n systemPrompt?: string;\n sessionId?: string;\n}\n\nexport interface ClaudeCodeResponse {\n content: string;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n };\n turn_count?: number;\n session_id?: string;\n}\n\nexport interface ClaudeCodeClient {\n query(options: ClaudeCodeQuery): Promise<ClaudeCodeResponse>;\n}\n\n// MCP Server configuration interface\nexport interface McpServerConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n// MCP Tool interface\nexport interface McpTool {\n name: string;\n description?: string;\n inputSchema?: Record<string, unknown>;\n handler?: (args: Record<string, unknown>) => Promise<unknown>;\n}\n\n// MCP Server interface\nexport interface McpServer {\n name: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n tools?: McpTool[];\n}\n\n// MCP Server Instance interface\nexport interface McpServerInstance {\n name: string;\n listTools(): Promise<McpTool[]>;\n callTool(name: string, args: Record<string, unknown>): Promise<unknown>;\n close(): Promise<void>;\n}\n\n// Claude Code configuration interface\nexport interface ClaudeCodeConfig {\n allowedTools?: string[];\n maxTurns?: number;\n systemPrompt?: string;\n mcpServers?: Record<string, McpServerConfig>;\n subagent?: string;\n hooks?: {\n onStart?: string;\n onEnd?: string;\n onError?: string;\n };\n}\n\n/**\n * Utility function to safely import optional dependencies\n */\nexport async function safeImport<T>(moduleName: string): Promise<T | null> {\n try {\n return await import(moduleName);\n } catch {\n return null;\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { IssueFilter } from '../issue-filter';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport {\n ClaudeCodeQuery,\n ClaudeCodeResponse,\n ClaudeCodeConfig,\n ClaudeCodeClient,\n safeImport,\n} from './claude-code-types';\n\ntype ClaudeCodeConstructor = new (options: { apiKey: string }) => ClaudeCodeClient;\n\nfunction isClaudeCodeConstructor(value: unknown): value is ClaudeCodeConstructor {\n return typeof value === 'function';\n}\n\n/**\n * Error thrown when Claude Code SDK is not installed\n */\nexport class ClaudeCodeSDKNotInstalledError extends Error {\n constructor() {\n super(\n 'Claude Code SDK is not installed. Install with: npm install @anthropic/claude-code-sdk @modelcontextprotocol/sdk'\n );\n this.name = 'ClaudeCodeSDKNotInstalledError';\n }\n}\n\n/**\n * Error thrown when Claude Code API key is not configured\n */\nexport class ClaudeCodeAPIKeyMissingError extends Error {\n constructor() {\n super(\n 'No API key found for Claude Code provider. Set CLAUDE_CODE_API_KEY or ANTHROPIC_API_KEY environment variable.'\n );\n this.name = 'ClaudeCodeAPIKeyMissingError';\n }\n}\n\n/**\n * Claude Code check provider using the Claude Code TypeScript SDK\n * Supports MCP tools and streaming responses\n */\nexport class ClaudeCodeCheckProvider extends CheckProvider {\n private liquidEngine: Liquid;\n private claudeCodeClient: ClaudeCodeClient | null = null;\n\n constructor() {\n super();\n this.liquidEngine = createExtendedLiquid();\n }\n\n getName(): string {\n return 'claude-code';\n }\n\n getDescription(): string {\n return 'AI-powered code review using Claude Code with MCP tools support';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'claude-code'\n if (cfg.type !== 'claude-code') {\n return false;\n }\n\n // Check for prompt\n if (!cfg.prompt || typeof cfg.prompt !== 'string') {\n return false;\n }\n\n // Validate Claude Code specific configuration\n if (cfg.claude_code) {\n const claudeCodeConfig = cfg.claude_code as ClaudeCodeConfig;\n\n // Validate allowedTools if present\n if (claudeCodeConfig.allowedTools && !Array.isArray(claudeCodeConfig.allowedTools)) {\n return false;\n }\n\n // Validate maxTurns if present\n if (claudeCodeConfig.maxTurns && typeof claudeCodeConfig.maxTurns !== 'number') {\n return false;\n }\n\n // Validate systemPrompt if present\n if (claudeCodeConfig.systemPrompt && typeof claudeCodeConfig.systemPrompt !== 'string') {\n return false;\n }\n\n // Validate mcpServers if present\n if (claudeCodeConfig.mcpServers) {\n if (typeof claudeCodeConfig.mcpServers !== 'object') {\n return false;\n }\n\n for (const serverConfig of Object.values(claudeCodeConfig.mcpServers)) {\n if (!serverConfig.command || typeof serverConfig.command !== 'string') {\n return false;\n }\n if (serverConfig.args && !Array.isArray(serverConfig.args)) {\n return false;\n }\n }\n }\n }\n\n return true;\n }\n\n /**\n * Initialize Claude Code SDK client\n */\n private async initializeClaudeCodeClient(): Promise<ClaudeCodeClient> {\n if (this.claudeCodeClient) {\n return this.claudeCodeClient;\n }\n\n // Use safe import to avoid TypeScript compilation errors\n const claudeCodeModule = await safeImport<{\n ClaudeCode?: unknown;\n default?: { ClaudeCode?: unknown };\n }>('@anthropic/claude-code-sdk');\n\n if (!claudeCodeModule) {\n throw new ClaudeCodeSDKNotInstalledError();\n }\n\n const ClaudeCodeCtor = claudeCodeModule.ClaudeCode || claudeCodeModule.default?.ClaudeCode;\n\n if (!isClaudeCodeConstructor(ClaudeCodeCtor)) {\n throw new Error('ClaudeCode class not found in @anthropic/claude-code-sdk');\n }\n\n // Initialize with API key from environment\n const apiKey = process.env.CLAUDE_CODE_API_KEY || process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new ClaudeCodeAPIKeyMissingError();\n }\n\n try {\n const client = new ClaudeCodeCtor({\n apiKey,\n }) as ClaudeCodeClient;\n\n this.claudeCodeClient = client;\n return client;\n } catch (error) {\n throw new Error(\n `Failed to initialize Claude Code SDK: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Group files by their file extension for template context\n */\n private groupFilesByExtension(\n files: import('../pr-analyzer').PRFile[]\n ): Record<string, import('../pr-analyzer').PRFile[]> {\n const grouped: Record<string, import('../pr-analyzer').PRFile[]> = {};\n\n files.forEach(file => {\n const parts = file.filename.split('.');\n const ext = parts.length > 1 ? parts.pop()?.toLowerCase() || 'noext' : 'noext';\n if (!grouped[ext]) {\n grouped[ext] = [];\n }\n grouped[ext].push(file);\n });\n\n return grouped;\n }\n\n /**\n * Process prompt configuration to resolve final prompt string\n */\n private async processPrompt(\n promptConfig: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n let promptContent: string;\n\n // Auto-detect if it's a file path or inline content\n if (await this.isFilePath(promptConfig)) {\n promptContent = await this.loadPromptFromFile(promptConfig);\n } else {\n promptContent = promptConfig;\n }\n\n // Process Liquid templates in the prompt\n return await this.renderPromptTemplate(promptContent, prInfo, eventContext, dependencyResults);\n }\n\n /**\n * Detect if a string is likely a file path and if the file exists\n */\n private async isFilePath(str: string): Promise<boolean> {\n // Quick checks to exclude obvious non-file-path content\n if (!str || str.trim() !== str || str.length > 512) {\n return false;\n }\n\n // Exclude strings that are clearly content (contain common content indicators)\n if (\n /\\s{2,}/.test(str) || // Multiple consecutive spaces\n /\\n/.test(str) || // Contains newlines\n /^(please|analyze|review|check|find|identify|look|search)/i.test(str.trim()) || // Starts with command words\n str.split(' ').length > 8 // Too many words for a typical file path\n ) {\n return false;\n }\n\n // For strings with path separators, be more lenient about common words\n if (!/[\\/\\\\]/.test(str)) {\n // Only apply strict English word filter to non-path strings\n if (/\\b(the|and|or|but|for|with|by|from|in|on|at|as)\\b/i.test(str)) {\n return false;\n }\n }\n\n // Positive indicators for file paths\n const hasFileExtension = /\\.[a-zA-Z0-9]{1,10}$/i.test(str);\n const hasPathSeparators = /[\\/\\\\]/.test(str);\n const isRelativePath = /^\\.{1,2}\\//.test(str);\n const isAbsolutePath = path.isAbsolute(str);\n const hasTypicalFileChars = /^[a-zA-Z0-9._\\-\\/\\\\:~]+$/.test(str);\n\n // Must have at least one strong indicator\n if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {\n return false;\n }\n\n // Must contain only typical file path characters\n if (!hasTypicalFileChars) {\n return false;\n }\n\n // Additional validation for suspected file paths\n try {\n // Try to resolve and check if file exists\n let resolvedPath: string;\n\n if (path.isAbsolute(str)) {\n resolvedPath = path.normalize(str);\n } else {\n // Resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), str);\n }\n\n // Check if file exists\n try {\n const stat = await fs.stat(resolvedPath);\n return stat.isFile();\n } catch {\n // File doesn't exist, but might still be a valid file path format\n return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);\n }\n } catch {\n return false;\n }\n }\n\n /**\n * Load prompt content from file with security validation\n */\n private async loadPromptFromFile(promptPath: string): Promise<string> {\n // Enforce .liquid file extension for all prompt files\n if (!promptPath.endsWith('.liquid')) {\n throw new Error('Prompt file must have .liquid extension');\n }\n\n let resolvedPath: string;\n\n if (path.isAbsolute(promptPath)) {\n // Absolute path - use as-is\n resolvedPath = promptPath;\n } else {\n // Relative path - resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), promptPath);\n }\n\n // Security: For relative paths, ensure they don't escape the current directory\n if (!path.isAbsolute(promptPath)) {\n const normalizedPath = path.normalize(resolvedPath);\n const currentDir = path.resolve(process.cwd());\n if (!normalizedPath.startsWith(currentDir)) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n }\n\n // Security: Check for obvious path traversal patterns\n if (promptPath.includes('../..')) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n\n try {\n const promptContent = await fs.readFile(resolvedPath, 'utf-8');\n return promptContent;\n } catch (error) {\n throw new Error(\n `Failed to load prompt from ${resolvedPath}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Render Liquid template in prompt with comprehensive context\n */\n private async renderPromptTemplate(\n promptContent: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n // Create comprehensive template context with PR and event information\n const templateContext = {\n // PR Information\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n baseBranch: prInfo.base,\n headBranch: prInfo.head,\n isIncremental: prInfo.isIncremental,\n filesChanged: prInfo.files?.map(f => f.filename) || [],\n totalAdditions: prInfo.files?.reduce((sum, f) => sum + f.additions, 0) || 0,\n totalDeletions: prInfo.files?.reduce((sum, f) => sum + f.deletions, 0) || 0,\n totalChanges: prInfo.files?.reduce((sum, f) => sum + f.changes, 0) || 0,\n base: prInfo.base,\n head: prInfo.head,\n },\n\n // File Details\n files: prInfo.files || [],\n description: prInfo.body || '',\n\n // GitHub Event Context\n event: eventContext\n ? {\n name: eventContext.event_name || 'unknown',\n action: eventContext.action,\n isPullRequest: !prInfo.isIssue,\n\n // Repository Info\n repository: eventContext.repository\n ? {\n owner: (eventContext.repository as { owner?: { login?: string } })?.owner?.login,\n name: (eventContext.repository as { name?: string })?.name,\n fullName: eventContext.repository\n ? `${(eventContext.repository as { owner?: { login?: string } })?.owner?.login}/${(eventContext.repository as { name?: string })?.name}`\n : undefined,\n }\n : undefined,\n\n // Comment Data (for comment events)\n comment: eventContext.comment\n ? {\n body: (eventContext.comment as { body?: string })?.body,\n author: (eventContext.comment as { user?: { login?: string } })?.user?.login,\n }\n : undefined,\n\n // Raw event payload for advanced use cases\n payload: eventContext,\n }\n : undefined,\n\n // Utility data for templates\n utils: {\n // Date/time helpers\n now: new Date().toISOString(),\n today: new Date().toISOString().split('T')[0],\n\n // Dynamic file grouping by extension\n filesByExtension: this.groupFilesByExtension(prInfo.files || []),\n\n // File status categorizations\n addedFiles: (prInfo.files || []).filter(f => f.status === 'added'),\n modifiedFiles: (prInfo.files || []).filter(f => f.status === 'modified'),\n removedFiles: (prInfo.files || []).filter(f => f.status === 'removed'),\n renamedFiles: (prInfo.files || []).filter(f => f.status === 'renamed'),\n\n // Change analysis\n hasLargeChanges: (prInfo.files || []).some(f => f.changes > 50),\n totalFiles: (prInfo.files || []).length,\n },\n\n // Previous check outputs (dependency results)\n // Expose raw output directly if available, otherwise expose the result as-is\n outputs: dependencyResults\n ? Object.fromEntries(\n Array.from(dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result\n (() => {\n const summary = result as ReviewSummary & { output?: unknown };\n return summary.output !== undefined ? summary.output : summary;\n })(),\n ])\n )\n : {},\n };\n\n try {\n return await this.liquidEngine.parseAndRender(promptContent, templateContext);\n } catch (error) {\n throw new Error(\n `Failed to render prompt template: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Parse structured response from Claude Code\n */\n private parseStructuredResponse(content: string): ReviewSummary {\n try {\n // Try to parse as JSON first\n const parsed = JSON.parse(content);\n\n // Convert to ReviewSummary format\n return {\n issues: parsed.issues || [],\n };\n } catch {\n // If not JSON, treat as plain text comment\n return {\n issues: [],\n };\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Apply environment configuration if present\n if (config.env) {\n const result = EnvironmentResolver.withTemporaryEnv(config.env, () => {\n return this.executeWithConfig(prInfo, config, dependencyResults, sessionInfo);\n });\n\n if (result instanceof Promise) {\n return result;\n }\n return result;\n }\n\n return this.executeWithConfig(prInfo, config, dependencyResults, sessionInfo);\n }\n\n private async executeWithConfig(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Test hook: allow short-circuiting provider with mock output (YAML tests)\n try {\n const stepName = (config as any).checkName || 'claude-code';\n const mock = (sessionInfo as any)?.hooks?.mockForStep?.(String(stepName));\n if (mock !== undefined) {\n if (mock && typeof mock === 'object' && 'issues' in (mock as any)) {\n return mock as unknown as ReviewSummary;\n }\n return { issues: [], output: mock as unknown } as ReviewSummary & { output: unknown };\n }\n } catch {}\n // Extract Claude Code configuration\n const claudeCodeConfig = (config.claude_code as ClaudeCodeConfig) || {};\n\n // Get custom prompt from config - REQUIRED\n const customPrompt = config.prompt;\n if (!customPrompt) {\n throw new Error(\n `No prompt defined for check. All checks must have prompts defined in .visor.yaml configuration.`\n );\n }\n\n // Process prompt with Liquid templates and file loading\n const processedPrompt = await this.processPrompt(\n customPrompt,\n prInfo,\n config.eventContext,\n dependencyResults\n );\n\n const startTime = Date.now();\n\n try {\n // Initialize Claude Code client\n const client = await this.initializeClaudeCodeClient();\n\n // Prepare query object with MCP servers passed directly to SDK\n const query: ClaudeCodeQuery = {\n query: processedPrompt,\n maxTurns: claudeCodeConfig.maxTurns || 5,\n systemPrompt: claudeCodeConfig.systemPrompt,\n subagent: claudeCodeConfig.subagent,\n };\n\n // Add allowed tools if specified\n if (claudeCodeConfig.allowedTools && claudeCodeConfig.allowedTools.length > 0) {\n query.tools = claudeCodeConfig.allowedTools.map(name => ({ name }));\n }\n\n // Pass MCP servers directly to the SDK - let it handle spawning and tool discovery\n if (claudeCodeConfig.mcpServers && Object.keys(claudeCodeConfig.mcpServers).length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (query as any).mcpServers = claudeCodeConfig.mcpServers;\n }\n\n // Execute query with Claude Code\n let response: ClaudeCodeResponse;\n\n if (sessionInfo?.reuseSession && sessionInfo.parentSessionId) {\n // Use session reuse if available\n response = await client.query({\n ...query,\n sessionId: sessionInfo.parentSessionId,\n });\n } else {\n // Create new session\n response = await client.query(query);\n }\n\n // Parse the response\n const result = this.parseStructuredResponse(response.content) as ReviewSummary & {\n debug?: import('../ai-review-service').AIDebugInfo & {\n sessionId?: string;\n turnCount?: number;\n usage?: unknown;\n toolsUsed?: string[];\n };\n };\n\n result.debug = {\n prompt: processedPrompt,\n rawResponse: response.content,\n provider: 'claude-code',\n model: 'claude-code',\n apiKeySource: 'CLAUDE_CODE_API_KEY',\n processingTime: Date.now() - startTime,\n promptLength: processedPrompt.length,\n responseLength: response.content.length,\n jsonParseSuccess: true,\n errors: [],\n checksExecuted: [config.checkName || 'claude-code-check'],\n parallelExecution: false,\n timestamp: new Date().toISOString(),\n // Claude Code specific debug info\n sessionId: response.session_id,\n turnCount: response.turn_count,\n usage: response.usage,\n };\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n return {\n ...result,\n issues: filteredIssues,\n };\n } catch (error) {\n // Re-throw setup/configuration errors that should terminate the application\n if (\n error instanceof ClaudeCodeSDKNotInstalledError ||\n error instanceof ClaudeCodeAPIKeyMissingError\n ) {\n throw error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Log detailed error information\n console.error(`❌ Claude Code Check Provider Error: ${errorMessage}`);\n\n // Check if this is a critical error\n const isCriticalError =\n errorMessage.includes('API rate limit') ||\n errorMessage.includes('403') ||\n errorMessage.includes('401') ||\n errorMessage.includes('authentication');\n\n if (isCriticalError) {\n console.error(\n `🚨 CRITICAL ERROR: Claude Code provider authentication or setup issue detected`\n );\n console.error(\n `🚨 This check cannot proceed without valid API credentials and SDK installation`\n );\n }\n\n // Re-throw with more context\n throw new Error(`Claude Code analysis failed: ${errorMessage}`);\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'claude_code.allowedTools',\n 'claude_code.maxTurns',\n 'claude_code.systemPrompt',\n 'claude_code.mcpServers',\n 'claude_code.subagent',\n 'claude_code.hooks',\n 'env',\n 'checkName',\n 'sessionId',\n 'suppressionEnabled',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n // Check if Claude Code API key is available\n const hasApiKey = !!(process.env.CLAUDE_CODE_API_KEY || process.env.ANTHROPIC_API_KEY);\n\n if (!hasApiKey) {\n return false;\n }\n\n // Try to import the SDK to check if it's installed\n const claudeCodeModule = await safeImport<{\n ClaudeCode?: unknown;\n default?: { ClaudeCode?: unknown };\n }>('@anthropic/claude-code-sdk');\n if (!claudeCodeModule) {\n return false;\n }\n const ClaudeCode = claudeCodeModule.ClaudeCode || claudeCodeModule.default?.ClaudeCode;\n\n return !!ClaudeCode;\n } catch {\n // If import fails, the SDK is not installed\n return false;\n }\n }\n\n getRequirements(): string[] {\n return [\n 'CLAUDE_CODE_API_KEY or ANTHROPIC_API_KEY environment variable',\n '@anthropic/claude-code-sdk npm package',\n '@modelcontextprotocol/sdk npm package (for MCP support)',\n 'Network access to Claude Code API',\n ];\n }\n}\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { logger } from '../logger';\n\nexport interface CommandExecutionOptions {\n stdin?: string;\n cwd?: string;\n env?: Record<string, string>;\n timeout?: number;\n}\n\nexport interface CommandExecutionResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\n/**\n * Shared utility for executing shell commands\n * Used by both CommandCheckProvider and CustomToolExecutor\n */\nexport class CommandExecutor {\n private static instance: CommandExecutor;\n\n private constructor() {}\n\n static getInstance(): CommandExecutor {\n if (!CommandExecutor.instance) {\n CommandExecutor.instance = new CommandExecutor();\n }\n return CommandExecutor.instance;\n }\n\n /**\n * Execute a shell command with optional stdin, environment, and timeout\n */\n async execute(\n command: string,\n options: CommandExecutionOptions = {}\n ): Promise<CommandExecutionResult> {\n const execAsync = promisify(exec);\n const timeout = options.timeout || 30000;\n\n // If stdin is provided, we need to handle it differently\n if (options.stdin) {\n return this.executeWithStdin(command, options);\n }\n\n // For commands without stdin, use the simpler promisified version\n try {\n const result = await execAsync(command, {\n cwd: options.cwd,\n env: options.env as NodeJS.ProcessEnv,\n timeout,\n });\n\n return {\n stdout: result.stdout || '',\n stderr: result.stderr || '',\n exitCode: 0,\n };\n } catch (error) {\n return this.handleExecutionError(error, timeout);\n }\n }\n\n /**\n * Execute command with stdin input\n */\n private executeWithStdin(\n command: string,\n options: CommandExecutionOptions\n ): Promise<CommandExecutionResult> {\n return new Promise((resolve, reject) => {\n const childProcess = exec(\n command,\n {\n cwd: options.cwd,\n env: options.env as NodeJS.ProcessEnv,\n timeout: options.timeout || 30000,\n },\n (error, stdout, stderr) => {\n // Check if the process was killed due to timeout\n if (\n error &&\n error.killed &&\n ((error as NodeJS.ErrnoException).code === 'ETIMEDOUT' || error.signal === 'SIGTERM')\n ) {\n reject(new Error(`Command timed out after ${options.timeout || 30000}ms`));\n } else {\n resolve({\n stdout: stdout || '',\n stderr: stderr || '',\n exitCode: error ? error.code || 1 : 0,\n });\n }\n }\n );\n\n // Write stdin and close\n if (options.stdin && childProcess.stdin) {\n childProcess.stdin.write(options.stdin);\n childProcess.stdin.end();\n }\n });\n }\n\n /**\n * Handle execution errors consistently\n */\n private handleExecutionError(error: unknown, timeout: number): CommandExecutionResult {\n const execError = error as NodeJS.ErrnoException & {\n stdout?: string;\n stderr?: string;\n killed?: boolean;\n code?: string | number;\n signal?: string;\n };\n\n // Check if the process was killed due to timeout\n // Node.js sets killed: true and signal: 'SIGTERM' when timeout expires\n if (execError.killed && (execError.code === 'ETIMEDOUT' || execError.signal === 'SIGTERM')) {\n throw new Error(`Command timed out after ${timeout}ms`);\n }\n\n // Extract exit code - it might be a string or number\n let exitCode = 1;\n if (execError.code) {\n exitCode = typeof execError.code === 'string' ? parseInt(execError.code, 10) : execError.code;\n }\n\n return {\n stdout: execError.stdout || '',\n stderr: execError.stderr || '',\n exitCode,\n };\n }\n\n /**\n * Build safe environment variables by merging process.env with custom env\n * Ensures all values are strings (no undefined)\n */\n buildEnvironment(\n baseEnv: NodeJS.ProcessEnv = process.env,\n ...customEnvs: Array<Record<string, string> | undefined>\n ): Record<string, string> {\n const result: Record<string, string> = {};\n\n // Start with base environment, filtering out undefined values\n for (const [key, value] of Object.entries(baseEnv)) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n // Merge custom environments\n for (const customEnv of customEnvs) {\n if (customEnv) {\n Object.assign(result, customEnv);\n }\n }\n\n return result;\n }\n\n /**\n * Log command execution for debugging\n */\n logExecution(command: string, options: CommandExecutionOptions): void {\n const debugInfo = [\n `Executing command: ${command}`,\n options.cwd ? `cwd: ${options.cwd}` : null,\n options.stdin ? 'with stdin' : null,\n options.timeout ? `timeout: ${options.timeout}ms` : null,\n options.env ? `env vars: ${Object.keys(options.env).length}` : null,\n ]\n .filter(Boolean)\n .join(', ');\n\n logger.debug(debugInfo);\n }\n}\n\n// Export singleton instance for convenience\nexport const commandExecutor = CommandExecutor.getInstance();\n","export type EnvMap = Record<string, string>;\n\n// Default: expose all env vars except a conservative denylist.\n// If VISOR_ALLOW_ENV is set and not '*', restrict to that allowlist.\n// VISOR_DENY_ENV can further mask exact keys or prefix* patterns.\nexport function buildSandboxEnv(input: NodeJS.ProcessEnv): EnvMap {\n const denyDefaults = [\n 'GITHUB_TOKEN',\n 'INPUT_GITHUB-TOKEN',\n 'ACTIONS_RUNTIME_TOKEN',\n 'ACTIONS_ID_TOKEN_REQUEST_TOKEN',\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AZURE_CLIENT_SECRET',\n 'GOOGLE_APPLICATION_CREDENTIALS',\n 'OPENAI_API_KEY',\n 'ANTHROPIC_API_KEY',\n 'HUGGINGFACE_API_KEY',\n 'CLAUDE_CODE_API_KEY',\n 'PROBE_API_KEY',\n ];\n\n const denyExtra = (input.VISOR_DENY_ENV || '')\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n const deny = Array.from(new Set([...denyDefaults, ...denyExtra]));\n const allowSpec = (input.VISOR_ALLOW_ENV || '*').trim();\n\n const denyMatch = (key: string): boolean => {\n for (const pat of deny) {\n if (!pat) continue;\n if (pat.endsWith('*')) {\n const prefix = pat.slice(0, -1);\n if (key.startsWith(prefix)) return true;\n } else if (key === pat) {\n return true;\n }\n }\n if (/(_TOKEN|_SECRET|_PASSWORD|_PRIVATE_KEY)$/i.test(key)) return true;\n return false;\n };\n\n const out: EnvMap = {};\n if (allowSpec !== '*') {\n const allow = allowSpec\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n for (const key of allow) {\n const val = input[key];\n if (key && val !== undefined && !denyMatch(key)) out[key] = String(val);\n }\n return out;\n }\n\n for (const [k, v] of Object.entries(input)) {\n if (v === undefined || v === null) continue;\n if (denyMatch(k)) continue;\n out[k] = String(v);\n }\n return out;\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport { commandExecutor } from '../utils/command-executor';\nimport {\n createPermissionHelpers,\n detectLocalMode,\n resolveAssociationFromEvent,\n} from '../utils/author-permissions';\nimport { trace, context as otContext } from '../telemetry/lazy-otel';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureTransformJS,\n} from '../telemetry/state-capture';\n\n/**\n * Check provider that executes shell commands and captures their output\n * Supports JSON parsing and integration with forEach functionality\n */\nexport class CommandCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n // Lazily create sandbox only when transform_js is used\n }\n\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n getName(): string {\n return 'command';\n }\n\n getDescription(): string {\n return 'Execute shell commands and capture output for processing';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Must have exec specified\n if (!cfg.exec || typeof cfg.exec !== 'string') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: import('./check-provider.interface').ExecutionContext\n ): Promise<ReviewSummary> {\n try {\n logger.info(\n ` command provider: executing check=${String((config as any).checkName || config.type)} hasTransformJs=${Boolean(\n (config as any).transform_js\n )}`\n );\n } catch {}\n const command = config.exec as string;\n const transform = config.transform as string | undefined;\n const transformJs = config.transform_js as string | undefined;\n\n // Prepare template context for Liquid rendering\n const outputsObj = this.buildOutputContext(\n dependencyResults,\n config.__outputHistory as Map<string, unknown[]> | undefined\n );\n\n // Build outputs_raw from -raw keys in dependencyResults\n const outputsRaw: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [key, value] of dependencyResults.entries()) {\n if (typeof key !== 'string') continue;\n if (key.endsWith('-raw')) {\n const name = key.slice(0, -4);\n const summary = value as ReviewSummary & { output?: unknown };\n outputsRaw[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n }\n\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n fileCount: prInfo.files.length,\n outputs: outputsObj,\n // Alias: outputs_history mirrors outputs.history for consistency\n outputs_history: (outputsObj as any).history || {},\n // Stage-scoped history slice based on baseline provided by runner\n outputs_history_stage: (() => {\n const stage: Record<string, unknown[]> = {};\n try {\n const base = (context as any)?.stageHistoryBase as Record<string, number> | undefined;\n const histMap = (config as any).__outputHistory as Map<string, unknown[]> | undefined;\n if (!base || !histMap) return stage;\n for (const [k, v] of histMap.entries()) {\n const start = base[k] || 0;\n const arr = Array.isArray(v) ? (v as unknown[]) : [];\n stage[k] = arr.slice(start);\n }\n } catch {}\n return stage;\n })(),\n // New: outputs_raw exposes aggregate values (e.g., full arrays for forEach parents)\n outputs_raw: outputsRaw,\n // Workflow inputs (when executing within a workflow)\n inputs: context?.workflowInputs || {},\n env: this.getSafeEnvironmentVariables(),\n };\n\n logger.debug(\n `🔧 Debug: Template outputs keys: ${Object.keys(templateContext.outputs || {}).join(', ')}`\n );\n\n // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for input context (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const ctxJson = JSON.stringify(templateContext);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n // Emit both start and completion markers together for deterministic E2E assertions\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.input.context': ctxJson },\n [{ name: 'check.started' }, { name: 'check.completed' }]\n );\n } catch {}\n\n // Test hook: mock output for this step (short-circuit execution)\n try {\n const stepName = (config as any).checkName || 'unknown';\n const rawMock = context?.hooks?.mockForStep?.(String(stepName));\n if (rawMock !== undefined) {\n // Normalize primitive mocks into object form\n let mock: any;\n if (typeof rawMock === 'number') {\n mock = { exit_code: Number(rawMock) };\n } else if (typeof rawMock === 'string') {\n mock = { stdout: String(rawMock) };\n } else {\n mock = rawMock as Record<string, unknown>;\n }\n const m = mock as { stdout?: string; stderr?: string; exit_code?: number; exit?: number };\n let out: unknown = m.stdout ?? '';\n try {\n if (\n typeof out === 'string' &&\n (out.trim().startsWith('{') || out.trim().startsWith('['))\n ) {\n out = JSON.parse(out);\n }\n } catch {}\n const code =\n typeof m.exit_code === 'number' ? m.exit_code : typeof m.exit === 'number' ? m.exit : 0;\n if (code !== 0) {\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/execution_error',\n message: `Mocked command exited with code ${code}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n output: out,\n } as any;\n }\n return { issues: [], output: out } as any;\n }\n } catch {}\n\n try {\n // Render the command with Liquid templates if needed\n let renderedCommand = command;\n if (command.includes('{{') || command.includes('{%')) {\n renderedCommand = await this.renderCommandTemplate(command, templateContext);\n }\n logger.debug(`🔧 Debug: Rendered command: ${renderedCommand}`);\n\n // Prepare environment variables - convert all to strings\n const scriptEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined) {\n scriptEnv[key] = value;\n }\n }\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n if (value !== undefined && value !== null) {\n scriptEnv[key] = String(value);\n }\n }\n }\n\n // Get timeout from config (in seconds) or use default (60 seconds)\n const timeoutSeconds = (config.timeout as number) || 60;\n const timeoutMs = timeoutSeconds * 1000;\n\n // Normalize only the eval payload for `node -e|--eval` invocations that may contain\n // literal newlines due to YAML processing (\"\\n\" -> newline). We re-escape newlines\n // inside the quoted eval argument to keep JS string literals valid, without touching\n // the rest of the command.\n const normalizeNodeEval = (cmd: string): string => {\n const re =\n /^(?<prefix>\\s*(?:\\/usr\\/bin\\/env\\s+)?node(?:\\.exe)?\\s+(?:-e|--eval)\\s+)(['\"])([\\s\\S]*?)\\2(?<suffix>\\s|$)/;\n const m = cmd.match(re) as\n | (RegExpMatchArray & { groups?: { prefix: string; suffix?: string } })\n | null;\n if (!m || !m.groups) return cmd;\n const prefix = m.groups.prefix;\n const quote = m[2];\n const code = m[3];\n const suffix = m.groups.suffix || '';\n if (!code.includes('\\n')) return cmd;\n const escaped = code.replace(/\\n/g, '\\\\n');\n return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);\n };\n\n const safeCommand = normalizeNodeEval(renderedCommand);\n\n // Use shared command executor\n const execResult = await commandExecutor.execute(safeCommand, {\n env: scriptEnv,\n timeout: timeoutMs,\n });\n\n const { stdout, stderr, exitCode } = execResult;\n\n if (stderr) {\n logger.debug(`Command stderr: ${stderr}`);\n }\n\n // Check for non-zero exit code\n if (exitCode !== 0) {\n const errorMessage = stderr || `Command exited with code ${exitCode}`;\n logger.error(`Command failed with exit code ${exitCode}: ${errorMessage}`);\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/execution_error',\n message: `Command execution failed: ${errorMessage}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n // Keep raw output for transforms\n const rawOutput = stdout.trim();\n\n // Try to parse output as JSON for default behavior\n // no debug\n let output: unknown = rawOutput;\n try {\n // Attempt to parse as JSON\n const parsed = JSON.parse(rawOutput);\n output = parsed;\n logger.debug(`🔧 Debug: Parsed entire output as JSON successfully`);\n } catch {\n // Try to extract JSON from the end of output (for commands with debug logs)\n const extractedTail = this.extractJsonFromEnd(rawOutput);\n if (extractedTail) {\n try {\n output = JSON.parse(extractedTail);\n } catch {\n output = rawOutput;\n }\n } else {\n // Try to extract any balanced JSON substring anywhere\n const extractedAny = this.extractJsonAnywhere(rawOutput);\n if (extractedAny) {\n try {\n output = JSON.parse(extractedAny);\n } catch {\n output = rawOutput;\n }\n } else {\n // Last resort: detect common boolean flags like error:true or error=false for fail_if gating\n const m = /\\berror\\b\\s*[:=]\\s*(true|false)/i.exec(rawOutput);\n if (m) {\n output = { error: m[1].toLowerCase() === 'true' } as any;\n } else {\n output = rawOutput;\n }\n }\n }\n }\n\n // Log the parsed structure for debugging\n // no debug\n\n // Apply transform if specified (Liquid or JavaScript)\n let finalOutput = output;\n\n // First apply Liquid transform if present\n if (transform) {\n try {\n const transformContext = {\n ...templateContext,\n output: output, // Use parsed output for Liquid (object if JSON, string otherwise)\n };\n const rendered = await this.liquid.parseAndRender(transform, transformContext);\n\n // Try to parse the transformed result as JSON\n try {\n finalOutput = JSON.parse(rendered.trim());\n logger.verbose(`✓ Applied Liquid transform successfully (parsed as JSON)`);\n } catch {\n finalOutput = rendered.trim();\n logger.verbose(`✓ Applied Liquid transform successfully (string output)`);\n }\n\n // Capture Liquid transform in telemetry\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n const { captureLiquidEvaluation } = require('../telemetry/state-capture');\n captureLiquidEvaluation(span, transform, transformContext, rendered);\n }\n } catch {\n // Ignore telemetry errors\n }\n } catch (error) {\n logger.error(\n `✗ Failed to apply Liquid transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/transform_error',\n message: `Failed to apply Liquid transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Then apply JavaScript transform if present\n if (transformJs) {\n try {\n // For transform_js, provide a JSON-smart wrapper that:\n // - behaves like a string when coerced (so JSON.parse(output) still works)\n // - exposes parsed JSON properties if stdout is valid JSON (so output.key works)\n const jsContext = {\n output: this.makeJsonSmart(rawOutput),\n pr: templateContext.pr,\n files: templateContext.files,\n outputs: this.makeOutputsJsonSmart(templateContext.outputs),\n inputs: templateContext.inputs || {},\n env: templateContext.env,\n permissions: createPermissionHelpers(\n resolveAssociationFromEvent((prInfo as any).eventContext, prInfo.authorAssociation),\n detectLocalMode()\n ),\n };\n\n // Compile and execute the JavaScript expression\n // Use direct property access instead of destructuring to avoid syntax issues\n const trimmedTransform = transformJs.trim();\n // Build a safe function body that supports statements + implicit last-expression return.\n const buildBodyWithReturn = (raw: string): string => {\n const t = raw.trim();\n // Find last non-empty line\n const lines = t.split(/\\n/);\n let i = lines.length - 1;\n while (i >= 0 && lines[i].trim().length === 0) i--;\n if (i < 0) return 'return undefined;';\n const lastLine = lines[i].trim();\n if (/^return\\b/i.test(lastLine)) {\n return t;\n }\n const idx = t.lastIndexOf(lastLine);\n const head = idx >= 0 ? t.slice(0, idx) : '';\n const lastExpr = lastLine.replace(/;\\s*$/, '');\n return `${head}\\nreturn (${lastExpr});`;\n };\n const bodyWithReturn = buildBodyWithReturn(trimmedTransform);\n\n const code = `\n const output = scope.output;\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const inputs = scope.inputs;\n const env = scope.env;\n const log = (...args) => { console.log('🔍 Debug:', ...args); };\n const hasMinPermission = scope.permissions.hasMinPermission;\n const isOwner = scope.permissions.isOwner;\n const isMember = scope.permissions.isMember;\n const isCollaborator = scope.permissions.isCollaborator;\n const isContributor = scope.permissions.isContributor;\n const isFirstTimer = scope.permissions.isFirstTimer;\n const __result = (function(){\n${bodyWithReturn}\n })();\n return __result;\n `;\n\n // Execute user code exclusively inside the sandbox\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n // Try to serialize result to JSON string inside sandbox to preserve primitives like booleans\n let parsedFromSandboxJson: any = undefined;\n try {\n const stringifyCode = `\n const output = scope.output;\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const env = scope.env;\n const log = (...args) => { console.log('🔍 Debug:', ...args); };\n const hasMinPermission = scope.permissions.hasMinPermission;\n const isOwner = scope.permissions.isOwner;\n const isMember = scope.permissions.isMember;\n const isCollaborator = scope.permissions.isCollaborator;\n const isContributor = scope.permissions.isContributor;\n const isFirstTimer = scope.permissions.isFirstTimer;\n const __ret = (function(){\n${bodyWithReturn}\n })();\n return typeof __ret === 'object' && __ret !== null ? JSON.stringify(__ret) : null;\n `;\n const stringifyExec = this.sandbox.compile(stringifyCode);\n const jsonStr = stringifyExec({ scope: jsContext }).run();\n if (typeof jsonStr === 'string' && jsonStr.trim().startsWith('{')) {\n parsedFromSandboxJson = JSON.parse(jsonStr);\n }\n } catch {}\n\n if (parsedFromSandboxJson !== undefined) {\n finalOutput = parsedFromSandboxJson;\n } else {\n finalOutput = compileAndRun<unknown>(\n this.sandbox,\n code,\n { scope: jsContext },\n { injectLog: false, wrapFunction: false }\n );\n }\n\n // Fallback: if sandbox could not preserve primitives (e.g., booleans lost),\n // attempt to re-evaluate the transform in a locked Node VM context to get plain JS values.\n try {\n if (\n finalOutput &&\n typeof finalOutput === 'object' &&\n !Array.isArray(finalOutput) &&\n ((finalOutput as any).error === undefined ||\n (finalOutput as any).issues === undefined)\n ) {\n const vm = await import('node:vm');\n const vmContext = vm.createContext({ scope: jsContext });\n const vmCode = `\n (function(){\n const output = scope.output; const pr = scope.pr; const files = scope.files; const outputs = scope.outputs; const env = scope.env; const log = ()=>{};\n${bodyWithReturn}\n })()\n `;\n const vmResult = vm.runInContext(vmCode, vmContext, { timeout: 1000 });\n if (vmResult && typeof vmResult === 'object') {\n finalOutput = vmResult;\n }\n }\n } catch {}\n // Create a plain JSON snapshot of the transform result to avoid proxy/getter surprises\n // Prefer JSON stringify inside the sandbox realm (so it knows how to serialize its own objects),\n // then fall back to host-side JSON clone and finally to a shallow copy of own enumerable properties.\n let finalSnapshot: Record<string, unknown> | null = null;\n try {\n if (finalOutput && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n // Try realm-local stringify first\n try {\n const stringifyExec = this.sandbox!.compile('return JSON.stringify(scope.obj);');\n const jsonStr = stringifyExec({ obj: finalOutput }).run();\n if (typeof jsonStr === 'string' && jsonStr.trim().startsWith('{')) {\n finalSnapshot = JSON.parse(jsonStr);\n }\n } catch {}\n if (!finalSnapshot) {\n try {\n finalSnapshot = JSON.parse(JSON.stringify(finalOutput));\n } catch {}\n }\n if (!finalSnapshot) {\n const tmp: Record<string, unknown> = {};\n for (const k of Object.keys(finalOutput as Record<string, unknown>)) {\n (tmp as any)[k] = (finalOutput as any)[k];\n }\n finalSnapshot = tmp;\n }\n }\n } catch {}\n // @ts-ignore store for later extraction path\n (this as any).__lastTransformSnapshot = finalSnapshot;\n try {\n const isObj =\n finalOutput && typeof finalOutput === 'object' && !Array.isArray(finalOutput);\n const keys = isObj\n ? Object.keys(finalOutput as Record<string, unknown>).join(',')\n : typeof finalOutput;\n logger.debug(\n ` transform_js: output typeof=${Array.isArray(finalOutput) ? 'array' : typeof finalOutput} keys=${keys}`\n );\n if (isObj && (finalOutput as any).issues) {\n const mi: any = (finalOutput as any).issues;\n logger.debug(\n ` transform_js: issues typeof=${Array.isArray(mi) ? 'array' : typeof mi} len=${(mi && mi.length) || 0}`\n );\n }\n try {\n if (isObj)\n logger.debug(` transform_js: error value=${String((finalOutput as any).error)}`);\n } catch {}\n } catch {}\n\n logger.verbose(`✓ Applied JavaScript transform successfully`);\n // Already normalized in sandbox result\n // no debug\n } catch (error) {\n logger.error(\n `✗ Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/transform_js_error',\n message: `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Extract structured issues when the command returns them (skip for forEach parents)\n // no debug\n let issues: ReviewIssue[] = [];\n let outputForDependents: unknown = finalOutput;\n // Capture a shallow snapshot created earlier if available (within transform_js path)\n // @ts-ignore - finalSnapshot is defined in the transform_js scope above when applicable\n // @ts-ignore retrieve snapshot captured after transform_js (if any)\n const snapshotForExtraction: Record<string, unknown> | null =\n (this as any).__lastTransformSnapshot || null;\n try {\n if (snapshotForExtraction) {\n logger.debug(` provider: snapshot keys=${Object.keys(snapshotForExtraction).join(',')}`);\n } else {\n logger.debug(` provider: snapshot is null`);\n }\n } catch {}\n // Some shells may wrap JSON output inside a one-element array due to quoting.\n // If we see a single-element array containing a JSON string or object, unwrap it.\n try {\n if (Array.isArray(outputForDependents) && (outputForDependents as unknown[]).length === 1) {\n const first = (outputForDependents as unknown[])[0];\n if (typeof first === 'string') {\n try {\n outputForDependents = JSON.parse(first);\n } catch {}\n } else if (first && typeof first === 'object') {\n outputForDependents = first as unknown;\n }\n }\n } catch {}\n\n let content: string | undefined;\n let extracted: { issues: ReviewIssue[]; remainingOutput: unknown } | null = null;\n\n const trimmedRawOutput = typeof rawOutput === 'string' ? rawOutput.trim() : undefined;\n\n const commandConfig = config as CheckProviderConfig & { forEach?: boolean };\n const isForEachParent = commandConfig.forEach === true;\n\n if (!isForEachParent) {\n // Generic: if transform output is an object and contains an 'issues' field,\n // expose all other fields to dependents regardless of whether we successfully\n // normalized the issues array. This preserves flags like 'error' for fail_if.\n try {\n const baseObj = (snapshotForExtraction || (finalOutput as any)) as Record<\n string,\n unknown\n >;\n if (\n baseObj &&\n typeof baseObj === 'object' &&\n Object.prototype.hasOwnProperty.call(baseObj, 'issues')\n ) {\n const remaining = { ...baseObj } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n try {\n const k =\n outputForDependents && typeof outputForDependents === 'object'\n ? Object.keys(outputForDependents as any).join(',')\n : String(outputForDependents);\n logger.debug(` provider: generic-remaining keys=${k}`);\n } catch {}\n }\n } catch {}\n // Fast path for transform_js objects that include an issues array (realm-agnostic)\n const objForExtraction = (snapshotForExtraction || (finalOutput as any)) as Record<\n string,\n unknown\n >;\n if (objForExtraction && typeof objForExtraction === 'object') {\n try {\n const rec = objForExtraction;\n const maybeIssues: any = (rec as any).issues;\n const toPlainArray = (v: any): any[] | null => {\n if (Array.isArray(v)) return v;\n try {\n if (v && typeof v === 'object' && typeof v[Symbol.iterator] === 'function') {\n return Array.from(v);\n }\n } catch {}\n const len = Number((v || {}).length);\n if (Number.isFinite(len) && len >= 0) {\n const arr: any[] = [];\n for (let i = 0; i < len; i++) arr.push(v[i]);\n return arr;\n }\n try {\n const cloned = JSON.parse(JSON.stringify(v));\n return Array.isArray(cloned) ? cloned : null;\n } catch {\n return null;\n }\n };\n try {\n const ctor =\n maybeIssues && (maybeIssues as any).constructor\n ? (maybeIssues as any).constructor.name\n : 'unknown';\n logger.debug(\n ` provider: issues inspect typeof=${typeof maybeIssues} Array.isArray=${Array.isArray(\n maybeIssues\n )} ctor=${ctor} keys=${Object.keys((maybeIssues || {}) as any).join(',')}`\n );\n } catch {}\n const arr = toPlainArray(maybeIssues);\n if (arr) {\n const norm = this.normalizeIssueArray(arr);\n if (norm) {\n issues = norm;\n const remaining = { ...rec } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n try {\n const keys =\n outputForDependents && typeof outputForDependents === 'object'\n ? Object.keys(outputForDependents as any).join(',')\n : String(outputForDependents);\n logger.info(\n ` provider: fast-path issues=${issues.length} remaining keys=${keys}`\n );\n } catch {}\n } else {\n try {\n logger.info(' provider: fast-path norm failed');\n } catch {}\n }\n } else {\n try {\n logger.info(' provider: fast-path arr unavailable');\n } catch {}\n }\n } catch {}\n }\n // Normalize extraction target: unwrap one-element arrays like [\"{...}\"] or [{...}]\n let extractionTarget: unknown = snapshotForExtraction || finalOutput;\n try {\n if (Array.isArray(extractionTarget) && (extractionTarget as unknown[]).length === 1) {\n const first = (extractionTarget as unknown[])[0];\n if (typeof first === 'string') {\n try {\n extractionTarget = JSON.parse(first);\n } catch {\n extractionTarget = first;\n }\n } else if (first && typeof first === 'object') {\n extractionTarget = first as unknown;\n }\n }\n } catch {}\n extracted = this.extractIssuesFromOutput(extractionTarget);\n try {\n if (extractionTarget !== (snapshotForExtraction || finalOutput)) {\n finalOutput = extractionTarget;\n }\n } catch {}\n // no debug\n // Handle cross-realm Arrays from sandbox: issues may look like an array but fail Array.isArray\n if (!extracted && finalOutput && typeof finalOutput === 'object') {\n try {\n const rec = finalOutput as Record<string, unknown>;\n const maybeIssues: any = (rec as any).issues;\n if (maybeIssues && typeof maybeIssues === 'object') {\n let arr: any[] | null = null;\n // Prefer iterator if present\n try {\n if (typeof maybeIssues[Symbol.iterator] === 'function') {\n arr = Array.from(maybeIssues);\n }\n } catch {}\n // Fallback to length-based copy\n if (!arr) {\n const len = Number((maybeIssues as any).length);\n if (Number.isFinite(len) && len >= 0) {\n arr = [];\n for (let i = 0; i < len; i++) arr.push(maybeIssues[i]);\n }\n }\n // Last resort: JSON clone\n if (!arr) {\n try {\n arr = JSON.parse(JSON.stringify(maybeIssues));\n } catch {}\n }\n if (arr && Array.isArray(arr)) {\n const norm = this.normalizeIssueArray(arr);\n if (norm) {\n issues = norm;\n const remaining = { ...rec } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n }\n }\n }\n } catch {}\n }\n if (!extracted && typeof finalOutput === 'string') {\n // Attempt to parse string output as JSON and extract issues again\n try {\n const parsed = JSON.parse(finalOutput);\n extracted = this.extractIssuesFromOutput(parsed);\n if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n // If remainingOutput carries a content field, pick it up\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n } catch {\n // Try to salvage JSON from anywhere within the string (stripped logs/ansi)\n try {\n const any = this.extractJsonAnywhere(finalOutput);\n if (any) {\n const parsed = JSON.parse(any);\n extracted = this.extractIssuesFromOutput(parsed);\n if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n }\n } catch {\n // leave as-is\n }\n }\n } else if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n // Also propagate embedded content when remainingOutput is an object { content, ... }\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n\n if (!issues.length && this.shouldTreatAsTextOutput(trimmedRawOutput)) {\n content = trimmedRawOutput;\n } else if (issues.length && typeof extracted?.remainingOutput === 'string') {\n const trimmed = extracted.remainingOutput.trim();\n if (trimmed) {\n content = trimmed;\n }\n }\n\n // Generic fallback: if issues are still empty, try to parse raw stdout as JSON and extract issues.\n if (!issues.length && typeof trimmedRawOutput === 'string') {\n try {\n const tryParsed = JSON.parse(trimmedRawOutput);\n const reextract = this.extractIssuesFromOutput(tryParsed);\n if (reextract && reextract.issues && reextract.issues.length) {\n issues = reextract.issues;\n if (!outputForDependents && reextract.remainingOutput) {\n outputForDependents = reextract.remainingOutput;\n }\n } else if (Array.isArray(tryParsed)) {\n // Treat parsed array as potential issues array or array of { issues: [...] }\n const first = tryParsed[0];\n if (first && typeof first === 'object' && Array.isArray((first as any).issues)) {\n const merged: unknown[] = [];\n for (const el of tryParsed as unknown[]) {\n if (el && typeof el === 'object' && Array.isArray((el as any).issues)) {\n merged.push(...((el as any).issues as unknown[]));\n }\n }\n const flat = this.normalizeIssueArray(merged);\n if (flat) issues = flat;\n } else {\n // Try to parse string elements into JSON objects and extract\n const converted: unknown[] = [];\n for (const el of tryParsed as unknown[]) {\n if (typeof el === 'string') {\n try {\n const obj = JSON.parse(el);\n converted.push(obj);\n } catch {\n // keep as-is\n }\n } else {\n converted.push(el);\n }\n }\n const flat = this.normalizeIssueArray(converted as unknown[]);\n if (flat) issues = flat;\n }\n }\n } catch {}\n if (!issues.length) {\n try {\n const any = this.extractJsonAnywhere(trimmedRawOutput);\n if (any) {\n const tryParsed = JSON.parse(any);\n const reextract = this.extractIssuesFromOutput(tryParsed);\n if (reextract && reextract.issues && reextract.issues.length) {\n issues = reextract.issues;\n if (!outputForDependents && reextract.remainingOutput) {\n outputForDependents = reextract.remainingOutput;\n }\n }\n }\n } catch {}\n }\n }\n\n // Preserve all primitive flags (boolean/number/string) from original transform output\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (\n outputForDependents &&\n typeof outputForDependents === 'object' &&\n srcObj &&\n typeof srcObj === 'object'\n ) {\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean' || typeof v === 'number' || typeof v === 'string') {\n (outputForDependents as any)[k] = v;\n }\n }\n }\n } catch {}\n\n // Normalize output object to a plain shallow object (avoid JSON stringify drop of false booleans)\n try {\n if (\n outputForDependents &&\n typeof outputForDependents === 'object' &&\n !Array.isArray(outputForDependents)\n ) {\n const plain: Record<string, unknown> = {};\n for (const k of Object.keys(outputForDependents as any)) {\n (plain as any)[k] = (outputForDependents as any)[k];\n }\n outputForDependents = plain;\n }\n } catch {}\n }\n\n if (!content && this.shouldTreatAsTextOutput(trimmedRawOutput) && !isForEachParent) {\n content = trimmedRawOutput;\n }\n\n // Normalize output object to plain JSON to avoid cross-realm proxy quirks\n try {\n if (outputForDependents && typeof outputForDependents === 'object') {\n outputForDependents = JSON.parse(JSON.stringify(outputForDependents));\n }\n } catch {}\n\n // Promote primitive flags from original transform output to top-level result fields (schema-agnostic)\n const promoted: Record<string, unknown> = {};\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (srcObj && typeof srcObj === 'object') {\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean') {\n if (v === true && promoted[k] === undefined) promoted[k] = true;\n } else if (\n (typeof v === 'number' || typeof v === 'string') &&\n promoted[k] === undefined\n ) {\n promoted[k] = v;\n }\n }\n }\n } catch {}\n\n // Return the output and issues as part of the review summary so dependent checks can use them\n const result = {\n issues,\n output: outputForDependents,\n ...(content ? { content } : {}),\n ...promoted,\n } as ReviewSummary;\n\n // Capture output and transform details in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckOutput(span, outputForDependents);\n if (transformJs && output !== finalOutput) {\n captureTransformJS(span, transformJs, output, finalOutput);\n }\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for output (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const outJson = JSON.stringify((result as any).output ?? result);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.output': outJson },\n [{ name: 'check.started' }, { name: 'check.completed' }]\n );\n } catch {}\n\n // Attach raw transform object only when transform_js was used (avoid polluting plain command outputs)\n try {\n if (transformJs) {\n const rawObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (rawObj && typeof rawObj === 'object') {\n (result as any).__raw = rawObj;\n }\n }\n } catch {}\n\n // Final safeguard: ensure primitive flags from original transform output are present in result.output.\n // Do this without dropping explicit false values (important for fail_if like `output.error`).\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n const srcErr = ((): boolean | undefined => {\n try {\n if (\n snapshotForExtraction &&\n typeof snapshotForExtraction === 'object' &&\n (snapshotForExtraction as any).error !== undefined\n ) {\n return Boolean((snapshotForExtraction as any).error);\n }\n if (\n finalOutput &&\n typeof finalOutput === 'object' &&\n (finalOutput as any).error !== undefined\n ) {\n return Boolean((finalOutput as any).error);\n }\n } catch {}\n return undefined;\n })();\n const dst = (result as any).output;\n if (srcObj && typeof srcObj === 'object' && dst && typeof dst === 'object') {\n try {\n logger.debug(\n ` provider: safeguard src.error typeof=${typeof (srcObj as any).error} val=${String((srcObj as any).error)} dst.hasErrorBefore=${String((dst as any).error !== undefined)}`\n );\n } catch {}\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean' || typeof v === 'number' || typeof v === 'string') {\n (dst as any)[k] = v;\n }\n }\n // Explicitly normalize a common flag used in tests/pipelines\n if (srcErr !== undefined && (dst as any).error === undefined) {\n (dst as any).error = srcErr;\n try {\n const k = Object.keys(dst as any).join(',');\n logger.debug(\n ` provider: safeguard merged error -> output keys=${k} val=${String((dst as any).error)}`\n );\n } catch {}\n }\n }\n } catch {}\n\n try {\n const out: any = (result as any).output;\n if (out && typeof out === 'object') {\n const k = Object.keys(out as Record<string, unknown>).join(',');\n logger.debug(` provider: return output keys=${k}`);\n } else {\n logger.debug(` provider: return output type=${typeof out}`);\n }\n } catch {}\n\n // no debug\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n // Check if this is a timeout error\n let isTimeout = false;\n if (error && typeof error === 'object') {\n const execError = error as { killed?: boolean; signal?: string; code?: string | number };\n // Node's child_process sets killed=true and signal='SIGTERM' on timeout\n if (execError.killed && execError.signal === 'SIGTERM') {\n isTimeout = true;\n }\n // Some versions may also set code to 'ETIMEDOUT'\n if (execError.code === 'ETIMEDOUT') {\n isTimeout = true;\n }\n }\n\n // Extract stderr from the error if available (child_process errors include stdout/stderr)\n let stderrOutput = '';\n if (error && typeof error === 'object') {\n const execError = error as { stderr?: string; stdout?: string };\n if (execError.stderr) {\n stderrOutput = execError.stderr.trim();\n }\n }\n\n // Construct detailed error message\n let detailedMessage: string;\n let ruleId: string;\n\n if (isTimeout) {\n const timeoutSeconds = (config.timeout as number) || 60;\n detailedMessage = `Command execution timed out after ${timeoutSeconds} seconds`;\n if (stderrOutput) {\n detailedMessage += `\\n\\nStderr output:\\n${stderrOutput}`;\n }\n ruleId = 'command/timeout';\n } else {\n detailedMessage = stderrOutput\n ? `Command execution failed: ${errorMessage}\\n\\nStderr output:\\n${stderrOutput}`\n : `Command execution failed: ${errorMessage}`;\n ruleId = 'command/execution_error';\n }\n\n logger.error(`✗ ${detailedMessage}`);\n\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId,\n message: detailedMessage,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n private buildOutputContext(\n dependencyResults?: Map<string, ReviewSummary>,\n outputHistory?: Map<string, unknown[]>\n ): Record<string, unknown> {\n if (!dependencyResults) {\n return {};\n }\n\n const outputs: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n\n for (const [checkName, result] of dependencyResults) {\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result as-is\n const summary = result as ReviewSummary & { output?: unknown };\n const value = summary.output !== undefined ? summary.output : summary;\n outputs[checkName] = this.makeJsonSmart(value);\n }\n\n // Add history for each check if available\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n history[checkName] = historyArray.map(val => this.makeJsonSmart(val));\n }\n }\n\n // Attach history to the outputs object\n (outputs as any).history = history;\n\n return outputs;\n }\n\n /**\n * Wrap a value with JSON-smart behavior:\n * - If it's a JSON string, expose parsed properties via Proxy (e.g., value.key)\n * - When coerced to string (toString/valueOf/Symbol.toPrimitive), return the original raw string\n * - If parsing fails or value is not a string, return the value unchanged\n * - Attempts to extract JSON from the end of the output if full parse fails\n */\n private makeJsonSmart<T = unknown>(value: T): T | any {\n if (typeof value !== 'string') {\n return value;\n }\n\n const raw = value as unknown as string;\n let parsed: any;\n\n // First try: parse the entire string as JSON\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Second try: extract JSON from the end of the output\n // Look for { or [ at the start of a line and take everything after it\n const jsonMatch = this.extractJsonFromEnd(raw);\n if (jsonMatch) {\n try {\n parsed = JSON.parse(jsonMatch);\n logger.debug(\n `🔧 Debug: Extracted JSON from end of output (${jsonMatch.length} chars from ${raw.length} total)`\n );\n } catch {\n // Not valid JSON even after extraction, return original string\n return raw;\n }\n } else {\n // Not JSON, return original string\n return raw;\n }\n }\n\n // Use a boxed string so string methods still work via Proxy fallback\n const boxed = new String(raw);\n const handler: ProxyHandler<any> = {\n get(target, prop, receiver) {\n if (prop === 'toString' || prop === 'valueOf') {\n return () => raw;\n }\n if (prop === Symbol.toPrimitive) {\n return () => raw;\n }\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n if (prop in parsed) {\n return (parsed as any)[prop as any];\n }\n }\n return Reflect.get(target, prop, receiver);\n },\n has(_target, prop) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n if (prop in parsed) return true;\n }\n return false;\n },\n ownKeys(_target) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n try {\n return Reflect.ownKeys(parsed);\n } catch {\n return [];\n }\n }\n return [];\n },\n getOwnPropertyDescriptor(_target, prop) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n const descriptor = Object.getOwnPropertyDescriptor(parsed, prop as any);\n if (descriptor) return descriptor;\n }\n return {\n configurable: true,\n enumerable: true,\n writable: false,\n value: undefined,\n };\n },\n };\n return new Proxy(boxed, handler);\n }\n\n /**\n * Extract JSON from the end of a string that may contain logs/debug output\n * Looks for the last occurrence of { or [ and tries to parse from there\n */\n private extractJsonFromEnd(text: string): string | null {\n // Robust strategy: find the last closing brace/bracket, then walk backwards to the matching opener\n const lastBrace = Math.max(text.lastIndexOf('}'), text.lastIndexOf(']'));\n if (lastBrace === -1) return null;\n // Scan backwards to find matching opener with a simple counter\n let open = 0;\n for (let i = lastBrace; i >= 0; i--) {\n const ch = text[i];\n if (ch === '}' || ch === ']') open++;\n else if (ch === '{' || ch === '[') open--;\n if (open === 0 && (ch === '{' || ch === '[')) {\n const candidate = text.slice(i, lastBrace + 1).trim();\n try {\n JSON.parse(candidate);\n return candidate;\n } catch {\n return null;\n }\n }\n }\n return null;\n }\n\n // Extract any balanced JSON object/array substring from anywhere in the text\n private extractJsonAnywhere(text: string): string | null {\n const n = text.length;\n let best: string | null = null;\n for (let i = 0; i < n; i++) {\n const start = text[i];\n if (start !== '{' && start !== '[') continue;\n let open = 0;\n let inString = false;\n let escape = false;\n for (let j = i; j < n; j++) {\n const ch = text[j];\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = !inString;\n continue;\n }\n if (inString) continue;\n if (ch === '{' || ch === '[') open++;\n else if (ch === '}' || ch === ']') open--;\n if (open === 0 && (ch === '}' || ch === ']')) {\n const candidate = text.slice(i, j + 1).trim();\n try {\n JSON.parse(candidate);\n best = candidate; // keep the last valid one we find\n } catch {\n // Try a loose-to-strict conversion (quote keys and barewords)\n const strict = this.looseJsonToStrict(candidate);\n if (strict) {\n try {\n JSON.parse(strict);\n best = strict;\n } catch {}\n }\n }\n break;\n }\n }\n }\n return best;\n }\n\n // Best-effort conversion of object-literal-like strings to strict JSON\n private looseJsonToStrict(candidate: string): string | null {\n try {\n let s = candidate.trim();\n // Convert single quotes to double quotes conservatively\n s = s.replace(/'/g, '\"');\n // Quote unquoted keys: {key: ...} or ,key: ...\n s = s.replace(/([\\{,]\\s*)([A-Za-z_][A-Za-z0-9_-]*)\\s*:/g, '$1\"$2\":');\n // Quote bareword values except true/false/null and numbers\n s = s.replace(/:\\s*([A-Za-z_][A-Za-z0-9_-]*)\\s*(?=[,}])/g, (m, word) => {\n const lw = String(word).toLowerCase();\n if (lw === 'true' || lw === 'false' || lw === 'null') return `:${lw}`;\n return `:\"${word}\"`;\n });\n return s;\n } catch {\n return null;\n }\n }\n\n /**\n * Recursively apply JSON-smart wrapper to outputs object values\n */\n private makeOutputsJsonSmart(outputs: Record<string, unknown>): Record<string, unknown> {\n const wrapped: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(outputs || {})) {\n wrapped[k] = this.makeJsonSmart(v);\n }\n return wrapped;\n }\n\n private getSafeEnvironmentVariables(): Record<string, string> {\n const safeVars: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const allowedPrefixes: string[] = []; // replaced by buildSandboxEnv\n\n const { buildSandboxEnv } = require('../utils/env-exposure');\n const merged = buildSandboxEnv(process.env);\n for (const [key, value] of Object.entries(merged)) {\n safeVars[key] = String(value);\n }\n\n // Add current working directory\n safeVars['PWD'] = process.cwd();\n\n return safeVars;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'exec',\n 'transform',\n 'transform_js',\n 'env',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'forEach',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Command provider is always available as long as we can execute commands\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'Valid shell command to execute',\n 'Shell environment available',\n 'Optional: Transform template for processing output',\n ];\n }\n\n private extractIssuesFromOutput(\n output: unknown\n ): { issues: ReviewIssue[]; remainingOutput: unknown } | null {\n try {\n logger.info(\n ` extractIssuesFromOutput: typeof=${Array.isArray(output) ? 'array' : typeof output}`\n );\n if (typeof output === 'object' && output) {\n const rec = output as Record<string, unknown>;\n logger.info(\n ` extractIssuesFromOutput: keys=${Object.keys(rec).join(',')} issuesIsArray=${Array.isArray(\n (rec as any).issues\n )}`\n );\n }\n } catch {}\n if (output === null || output === undefined) {\n return null;\n }\n\n // If output is already a string, do not treat it as issues here (caller may try parsing JSON)\n if (typeof output === 'string') {\n return null;\n }\n\n if (Array.isArray(output)) {\n // Two supported shapes:\n // 1) Array<ReviewIssue-like>\n // 2) Array<{ issues: Array<ReviewIssue-like> }>\n const first = output[0];\n if (\n first &&\n typeof first === 'object' &&\n !Array.isArray((first as any).message) &&\n Array.isArray((first as any).issues)\n ) {\n // flatten nested issues arrays\n const merged: unknown[] = [];\n for (const el of output as unknown[]) {\n if (el && typeof el === 'object' && Array.isArray((el as any).issues)) {\n merged.push(...((el as any).issues as unknown[]));\n }\n }\n const flat = this.normalizeIssueArray(merged);\n if (flat) return { issues: flat, remainingOutput: undefined };\n } else {\n const issues = this.normalizeIssueArray(output);\n if (issues) {\n return { issues, remainingOutput: undefined };\n }\n }\n return null;\n }\n\n if (typeof output === 'object') {\n const record = output as Record<string, unknown>;\n\n if (Array.isArray(record.issues)) {\n const issues = this.normalizeIssueArray(record.issues);\n if (!issues) {\n return null;\n }\n\n const remaining = { ...record };\n delete (remaining as { issues?: unknown }).issues;\n\n const remainingKeys = Object.keys(remaining);\n const remainingOutput = remainingKeys.length > 0 ? remaining : undefined;\n\n return {\n issues,\n remainingOutput,\n };\n }\n\n const singleIssue = this.normalizeIssue(record);\n if (singleIssue) {\n return { issues: [singleIssue], remainingOutput: undefined };\n }\n }\n\n return null;\n }\n\n private shouldTreatAsTextOutput(value?: string): value is string {\n if (!value) {\n return false;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n return false;\n }\n\n // Heuristic: consider it JSON-like if it starts with { or [ and ends with } or ]\n const startsJson =\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'));\n\n return !startsJson;\n }\n\n private normalizeIssueArray(values: unknown[]): ReviewIssue[] | null {\n const normalized: ReviewIssue[] = [];\n\n for (const value of values) {\n const issue = this.normalizeIssue(value);\n if (!issue) {\n return null;\n }\n normalized.push(issue);\n }\n\n return normalized;\n }\n\n private normalizeIssue(raw: unknown): ReviewIssue | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const data = raw as Record<string, unknown>;\n\n const message = this.toTrimmedString(\n data.message || data.text || data.description || data.summary\n );\n if (!message) {\n return null;\n }\n\n const allowedSeverities = new Set(['info', 'warning', 'error', 'critical']);\n const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);\n let severity: ReviewIssue['severity'] = 'warning';\n if (severityRaw) {\n const lower = severityRaw.toLowerCase();\n if (allowedSeverities.has(lower)) {\n severity = lower as ReviewIssue['severity'];\n } else if (['fatal', 'high'].includes(lower)) {\n severity = 'error';\n } else if (['medium', 'moderate'].includes(lower)) {\n severity = 'warning';\n } else if (['low', 'minor'].includes(lower)) {\n severity = 'info';\n }\n }\n\n const allowedCategories = new Set([\n 'security',\n 'performance',\n 'style',\n 'logic',\n 'documentation',\n ]);\n const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);\n let category: ReviewIssue['category'] = 'logic';\n if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {\n category = categoryRaw.toLowerCase() as ReviewIssue['category'];\n }\n\n const file = this.toTrimmedString(data.file || data.path || data.filename) || 'system';\n\n const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;\n const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);\n\n const suggestion = this.toTrimmedString(data.suggestion);\n const replacement = this.toTrimmedString(data.replacement);\n\n const ruleId =\n this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || 'command';\n\n return {\n file,\n line,\n endLine: endLine ?? undefined,\n ruleId,\n message,\n severity,\n category,\n suggestion: suggestion || undefined,\n replacement: replacement || undefined,\n };\n }\n\n private toTrimmedString(value: unknown): string | null {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n if (value !== null && value !== undefined && typeof value.toString === 'function') {\n const converted = String(value).trim();\n return converted.length > 0 ? converted : null;\n }\n return null;\n }\n\n private toNumber(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = Number(value);\n if (Number.isFinite(num)) {\n return Math.trunc(num);\n }\n return null;\n }\n\n private async renderCommandTemplate(\n template: string,\n context: {\n pr: Record<string, unknown>;\n files: unknown[];\n outputs: Record<string, unknown>;\n env: Record<string, string>;\n }\n ): Promise<string> {\n try {\n // Best-effort compatibility: allow double-quoted bracket keys inside Liquid tags.\n // e.g., {{ outputs[\"fetch-tickets\"].key }} → {{ outputs['fetch-tickets'].key }}\n let tpl = template;\n if (tpl.includes('{{')) {\n tpl = tpl.replace(/\\{\\{([\\s\\S]*?)\\}\\}/g, (_m, inner) => {\n const fixed = String(inner).replace(/\\[\\\"/g, \"['\").replace(/\\\"\\]/g, \"']\");\n return `{{ ${fixed} }}`;\n });\n }\n let rendered = await this.liquid.parseAndRender(tpl, context);\n // If Liquid left unresolved tags (common when users write JS expressions inside {{ }}),\n // fall back to a safe JS-expression renderer for the remaining tags.\n if (/\\{\\{[\\s\\S]*?\\}\\}/.test(rendered)) {\n try {\n rendered = this.renderWithJsExpressions(rendered, context);\n } catch {\n // keep Liquid-rendered result as-is\n }\n }\n return rendered;\n } catch (error) {\n logger.debug(`🔧 Debug: Liquid templating failed, trying JS-expression fallback: ${error}`);\n try {\n return this.renderWithJsExpressions(template, context);\n } catch {\n return template;\n }\n }\n }\n\n private renderWithJsExpressions(\n template: string,\n context: {\n pr: Record<string, unknown>;\n files: unknown[];\n outputs: Record<string, unknown>;\n env: Record<string, string>;\n }\n ): string {\n const scope = {\n pr: context.pr,\n files: context.files,\n outputs: context.outputs,\n env: context.env,\n };\n\n const expressionRegex = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n return template.replace(expressionRegex, (_match, expr) => {\n const expression = String(expr).trim();\n if (!expression) return '';\n try {\n const evalCode = `\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const env = scope.env;\n return (${expression});\n `;\n if (!this.sandbox) this.sandbox = this.createSecureSandbox();\n const evaluator = this.sandbox.compile(evalCode);\n const result = evaluator({ scope }).run();\n return result === undefined || result === null ? '' : String(result);\n } catch {\n return '';\n }\n });\n }\n}\n","import type { PRInfo } from '../pr-analyzer';\nimport type { ReviewSummary } from '../reviewer';\nimport { MemoryStore } from '../memory-store';\n\n/**\n * Build a common provider template context with PR info, outputs (current),\n * outputs.history (all runs), outputs_raw (aggregate -raw deps) and an alias\n * outputs_history / outputs_history_stage. Optionally attaches read-only\n * memory helpers (get/has/list/getAll).\n */\nconst PR_CACHE_LIMIT = 16;\nconst prCache = new Map<string, any>();\n\nfunction prCacheKey(pr: PRInfo): string {\n // Hash on stable fields + file list summary to avoid rebuilding the same structure repeatedly\n let sum = 0;\n for (const f of pr.files) sum += (f.additions || 0) + (f.deletions || 0) + (f.changes || 0);\n return [pr.number, pr.title, pr.author, pr.base, pr.head, pr.files.length, sum].join('|');\n}\n\nexport function buildProviderTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n memoryStore?: MemoryStore,\n outputHistory?: Map<string, unknown[]>,\n stageHistoryBase?: Record<string, number>,\n opts: { attachMemoryReadHelpers?: boolean } = { attachMemoryReadHelpers: true }\n): Record<string, unknown> {\n const context: Record<string, unknown> = {};\n\n // PR context with tiny cache\n const key = prCacheKey(prInfo);\n let prObj = prCache.get(key);\n if (!prObj) {\n prObj = {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n })),\n };\n prCache.set(key, prObj);\n if (prCache.size > PR_CACHE_LIMIT) {\n const first = prCache.keys().next();\n if (!first.done) prCache.delete(first.value);\n }\n }\n context.pr = prObj;\n\n // outputs and history\n const outputs: Record<string, unknown> = {};\n const outputsRaw: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n\n if (dependencyResults) {\n for (const [checkName, result] of dependencyResults.entries()) {\n if (typeof checkName !== 'string') continue;\n const summary = result as ReviewSummary & { output?: unknown };\n if (checkName.endsWith('-raw')) {\n const name = checkName.slice(0, -4);\n outputsRaw[name] = summary.output !== undefined ? summary.output : summary;\n } else {\n const extracted = summary.output !== undefined ? summary.output : summary;\n outputs[checkName] = extracted;\n }\n }\n }\n\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n const arr = Array.isArray(historyArray) ? (historyArray as unknown[]) : [];\n // Filter out aggregated forEach metadata objects to keep history aligned\n // with per-item outputs. This mirrors provider-side history builder\n // behavior and prevents scripts from accidentally counting aggregated\n // results as items.\n const filtered = arr.filter(v => {\n try {\n if (!v || typeof v !== 'object') return true;\n const obj = v as Record<string, unknown>;\n if (Array.isArray((obj as any).forEachItems)) return false;\n if ((obj as any).isForEach === true && (obj as any).forEachItems !== undefined)\n return false;\n } catch {}\n return true;\n });\n history[checkName] = filtered;\n }\n }\n\n const historyStage: Record<string, unknown[]> = {};\n try {\n if (outputHistory && stageHistoryBase) {\n for (const [checkName, historyArray] of outputHistory) {\n const start = stageHistoryBase[checkName] || 0;\n const arr = Array.isArray(historyArray) ? (historyArray as unknown[]) : [];\n historyStage[checkName] = arr.slice(start);\n }\n }\n } catch {}\n\n (outputs as any).history = history;\n context.outputs = outputs;\n (context as any).outputs_history = history;\n (context as any).outputs_history_stage = historyStage;\n (context as any).outputs_raw = outputsRaw;\n\n if (opts.attachMemoryReadHelpers && memoryStore) {\n context.memory = {\n get: (key: string, ns?: string) => memoryStore.get(key, ns),\n has: (key: string, ns?: string) => memoryStore.has(key, ns),\n list: (ns?: string) => memoryStore.list(ns),\n getAll: (ns?: string) => memoryStore.getAll(ns),\n } as Record<string, unknown>;\n }\n\n return context;\n}\n","import { MemoryStore } from '../memory-store';\n\n/**\n * Create synchronous memory helpers for sandboxed script execution. These mirror\n * the legacy behavior previously used for in-provider scripting: mutate in-memory state\n * synchronously and perform at most one save() afterward if needed.\n */\nexport function createSyncMemoryOps(store: MemoryStore): {\n ops: {\n get: (key: string, ns?: string) => unknown;\n has: (key: string, ns?: string) => boolean;\n list: (ns?: string) => string[];\n getAll: (ns?: string) => Record<string, unknown>;\n set: (key: string, value: unknown, ns?: string) => unknown;\n append: (key: string, value: unknown, ns?: string) => unknown[];\n increment: (key: string, amount?: number, ns?: string) => number;\n delete: (key: string, ns?: string) => boolean;\n clear: (ns?: string) => void;\n };\n needsSave: () => boolean;\n} {\n let saveNeeded = false;\n\n const ensureNs = (ns?: string) => {\n const nsName = ns || store.getDefaultNamespace();\n const anyStore = store as unknown as { data: Map<string, Map<string, unknown>> };\n if (!anyStore['data'].has(nsName)) {\n anyStore['data'].set(nsName, new Map());\n }\n return nsName;\n };\n\n const ops = {\n get: (key: string, ns?: string) => store.get(key, ns),\n has: (key: string, ns?: string) => store.has(key, ns),\n list: (ns?: string) => store.list(ns),\n getAll: (ns?: string) => store.getAll(ns),\n set: (key: string, value: unknown, ns?: string) => {\n const nsName = ensureNs(ns);\n (store as any)['data'].get(nsName)!.set(key, value);\n saveNeeded = true;\n return value;\n },\n append: (key: string, value: unknown, ns?: string) => {\n const existing = store.get(key, ns);\n let newValue: unknown[];\n if (existing === undefined) newValue = [value];\n else if (Array.isArray(existing)) newValue = [...existing, value];\n else newValue = [existing, value];\n const nsName = ensureNs(ns);\n (store as any)['data'].get(nsName)!.set(key, newValue);\n saveNeeded = true;\n return newValue;\n },\n increment: (key: string, amount = 1, ns?: string) => {\n const nsName = ensureNs(ns);\n const current = store.get(key, nsName);\n const numCurrent = typeof current === 'number' ? (current as number) : 0;\n const newValue = numCurrent + amount;\n (store as any)['data'].get(nsName)!.set(key, newValue);\n saveNeeded = true;\n return newValue;\n },\n delete: (key: string, ns?: string) => {\n const nsName = ensureNs(ns);\n const d = (store as any)['data'].get(nsName)?.delete(key) || false;\n if (d) saveNeeded = true;\n return d;\n },\n clear: (ns?: string) => {\n if (ns) (store as any)['data'].delete(ns);\n else (store as any)['data'].clear();\n saveNeeded = true;\n },\n } as const;\n\n return { ops: ops as any, needsSave: () => saveNeeded };\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { MemoryStore } from '../memory-store';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { buildProviderTemplateContext } from '../utils/template-context';\nimport { createSyncMemoryOps } from '../utils/script-memory-ops';\n\n/**\n * Memory operation types\n */\nexport type MemoryOperation = 'get' | 'set' | 'append' | 'increment' | 'delete' | 'clear' | 'list';\n\n/**\n * Check provider for memory/state management\n * Supports in-memory and persistent storage with namespace isolation\n */\nexport class MemoryCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n strictVariables: false,\n strictFilters: false,\n });\n }\n\n /**\n * Create a secure sandbox for JavaScript execution\n */\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n getName(): string {\n return 'memory';\n }\n\n getDescription(): string {\n return 'Memory/state management provider for persistent key-value storage across checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'memory'\n if (cfg.type !== 'memory') {\n return false;\n }\n\n // Operation is required\n if (!cfg.operation || typeof cfg.operation !== 'string') {\n return false;\n }\n\n const operation = cfg.operation as string;\n const validOps = ['get', 'set', 'append', 'increment', 'delete', 'clear', 'list'];\n if (!validOps.includes(operation)) {\n return false;\n }\n\n // Key is required for get, set, append, increment, delete\n if (['get', 'set', 'append', 'increment', 'delete'].includes(operation)) {\n if (!cfg.key || typeof cfg.key !== 'string') {\n return false;\n }\n }\n\n // Value or value_js is required for set and append\n if (['set', 'append'].includes(operation)) {\n if (cfg.value === undefined && !cfg.value_js) {\n return false;\n }\n }\n\n // For custom scripting use the ScriptCheckProvider (type: 'script').\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: {\n parentSessionId?: string;\n reuseSession?: boolean;\n } & import('./check-provider.interface').ExecutionContext\n ): Promise<ReviewSummary> {\n const operation = config.operation as MemoryOperation | undefined;\n const key = config.key as string | undefined;\n const namespace = config.namespace as string | undefined;\n\n // Get memory store instance\n const memoryStore = MemoryStore.getInstance();\n\n // Build template context for value computation\n const templateContext = this.buildTemplateContext(\n prInfo,\n dependencyResults,\n memoryStore,\n config.__outputHistory as Map<string, unknown[]> | undefined,\n (_sessionInfo as any)?.stageHistoryBase as Record<string, number> | undefined\n );\n\n let result: unknown;\n\n // No implicit fallbacks; operation must be explicitly provided.\n\n try {\n switch (operation) {\n case 'get':\n result = await this.handleGet(memoryStore, key!, namespace);\n break;\n case 'set':\n result = await this.handleSet(memoryStore, key!, config, namespace, templateContext);\n break;\n case 'append':\n result = await this.handleAppend(memoryStore, key!, config, namespace, templateContext);\n break;\n case 'increment':\n result = await this.handleIncrement(\n memoryStore,\n key!,\n config,\n namespace,\n templateContext\n );\n break;\n case 'delete':\n result = await this.handleDelete(memoryStore, key!, namespace);\n break;\n case 'clear':\n result = await this.handleClear(memoryStore, namespace);\n break;\n case 'list':\n result = await this.handleList(memoryStore, namespace);\n break;\n default:\n throw new Error(`Unknown memory operation: ${operation}`);\n }\n\n // Return result as output\n return {\n issues: [],\n output: result,\n } as ReviewSummary & { output: unknown };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error in memory operation';\n logger.error(`Memory operation failed: ${errorMsg}`);\n\n return {\n issues: [],\n output: null,\n error: errorMsg,\n } as ReviewSummary & { output: null; error: string };\n }\n }\n\n private async handleGet(store: MemoryStore, key: string, namespace?: string): Promise<unknown> {\n const value = store.get(key, namespace);\n logger.debug(\n `Memory GET: ${namespace || store.getDefaultNamespace()}.${key} = ${JSON.stringify(value)}`\n );\n return value;\n }\n\n private async handleSet(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<unknown> {\n const value = await this.computeValue(config, context);\n await store.set(key, value, namespace);\n logger.debug(\n `Memory SET: ${namespace || store.getDefaultNamespace()}.${key} = ${JSON.stringify(value)}`\n );\n return value;\n }\n\n private async handleAppend(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<unknown> {\n const value = await this.computeValue(config, context);\n await store.append(key, value, namespace);\n const result = store.get(key, namespace);\n logger.debug(\n `Memory APPEND: ${namespace || store.getDefaultNamespace()}.${key} += ${JSON.stringify(value)} (now: ${JSON.stringify(result)})`\n );\n return result;\n }\n\n private async handleIncrement(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<number> {\n // Compute amount - default to 1 if not specified\n let amount = 1;\n if (config.value !== undefined || config.value_js) {\n const computedValue = await this.computeValue(config, context);\n if (typeof computedValue === 'number') {\n amount = computedValue;\n } else {\n throw new Error(`Increment amount must be a number, got ${typeof computedValue}`);\n }\n }\n\n const result = await store.increment(key, amount, namespace);\n logger.debug(\n `Memory INCREMENT: ${namespace || store.getDefaultNamespace()}.${key} += ${amount} (now: ${result})`\n );\n return result;\n }\n\n private async handleDelete(\n store: MemoryStore,\n key: string,\n namespace?: string\n ): Promise<boolean> {\n const deleted = await store.delete(key, namespace);\n logger.debug(\n `Memory DELETE: ${namespace || store.getDefaultNamespace()}.${key} (deleted: ${deleted})`\n );\n return deleted;\n }\n\n private async handleClear(store: MemoryStore, namespace?: string): Promise<void> {\n await store.clear(namespace);\n logger.debug(`Memory CLEAR: ${namespace ? `namespace ${namespace}` : 'all namespaces'}`);\n }\n\n private async handleList(store: MemoryStore, namespace?: string): Promise<string[]> {\n const keys = store.list(namespace);\n logger.debug(`Memory LIST: ${namespace || store.getDefaultNamespace()} (${keys.length} keys)`);\n return keys;\n }\n\n // For custom JavaScript execution use ScriptCheckProvider.\n\n /**\n * Compute value from config using value, value_js, transform, or transform_js\n */\n private async computeValue(\n config: CheckProviderConfig,\n context: Record<string, unknown>\n ): Promise<unknown> {\n let value: unknown;\n\n // Start with direct value or value_js\n if (config.value_js && typeof config.value_js === 'string') {\n value = this.evaluateJavaScript(config.value_js, context);\n } else {\n value = config.value;\n }\n\n // Apply transform template if provided\n if (config.transform && typeof config.transform === 'string') {\n const rendered = await this.liquid.parseAndRender(config.transform, {\n ...context,\n value,\n });\n value = rendered;\n }\n\n // Apply transform_js if provided\n if (config.transform_js && typeof config.transform_js === 'string') {\n value = this.evaluateJavaScript(config.transform_js, { ...context, value });\n }\n\n return value;\n }\n\n /**\n * Evaluate JavaScript expression in context using SandboxJS for secure execution\n */\n private evaluateJavaScript(expression: string, context: Record<string, unknown>): unknown {\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n\n try {\n const scope: Record<string, unknown> = { ...context };\n return compileAndRun<unknown>(this.sandbox, `return (${expression});`, scope, {\n injectLog: true,\n wrapFunction: false,\n logPrefix: '[memory:value_js]',\n });\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to evaluate value_js: ${errorMsg}`);\n }\n }\n\n // No full-script execution in memory provider. Use ScriptCheckProvider.\n\n /**\n * Build template context for Liquid and JS evaluation\n */\n private buildTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n memoryStore?: MemoryStore,\n outputHistory?: Map<string, unknown[]>,\n stageHistoryBase?: Record<string, number>\n ): Record<string, unknown> {\n const base = buildProviderTemplateContext(\n prInfo,\n dependencyResults,\n memoryStore,\n outputHistory as Map<string, unknown[]> | undefined,\n stageHistoryBase\n );\n if (memoryStore) {\n const { ops } = createSyncMemoryOps(memoryStore);\n (base as any).memory = ops;\n }\n return base;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'operation',\n 'key',\n 'value',\n 'value_js',\n 'transform',\n 'transform_js',\n 'namespace',\n 'depends_on',\n 'group',\n 'command',\n 'on',\n 'if',\n 'fail_if',\n 'on_fail',\n 'on_success',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Memory provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for state management and persistent storage across checks',\n ];\n }\n}\n","import { CustomToolDefinition } from '../types/config';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { logger } from '../logger';\nimport { commandExecutor } from '../utils/command-executor';\nimport Ajv from 'ajv';\n\n/**\n * Executes custom tools defined in YAML configuration\n * These tools can be used in MCP blocks as if they were native MCP tools\n */\nexport class CustomToolExecutor {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n private tools: Map<string, CustomToolDefinition>;\n private ajv: Ajv;\n\n constructor(tools?: Record<string, CustomToolDefinition>) {\n this.liquid = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n this.tools = new Map(Object.entries(tools || {}));\n this.ajv = new Ajv({ allErrors: true, verbose: true });\n }\n\n /**\n * Register a custom tool\n */\n registerTool(tool: CustomToolDefinition): void {\n if (!tool.name) {\n throw new Error('Tool must have a name');\n }\n this.tools.set(tool.name, tool);\n }\n\n /**\n * Register multiple tools\n */\n registerTools(tools: Record<string, CustomToolDefinition>): void {\n for (const [name, tool] of Object.entries(tools)) {\n // Ensure tool has the correct name\n tool.name = tool.name || name;\n this.registerTool(tool);\n }\n }\n\n /**\n * Get all registered tools\n */\n getTools(): CustomToolDefinition[] {\n return Array.from(this.tools.values());\n }\n\n /**\n * Get a specific tool by name\n */\n getTool(name: string): CustomToolDefinition | undefined {\n return this.tools.get(name);\n }\n\n /**\n * Validate tool input against schema using ajv\n */\n private validateInput(tool: CustomToolDefinition, input: Record<string, unknown>): void {\n if (!tool.inputSchema) {\n return;\n }\n\n // Compile and cache the schema validator for this tool\n const validate = this.ajv.compile(tool.inputSchema);\n\n // Validate the input\n const valid = validate(input);\n\n if (!valid) {\n // Format validation errors for better readability\n const errors = validate.errors\n ?.map(err => {\n if (err.instancePath) {\n return `${err.instancePath}: ${err.message}`;\n }\n return err.message;\n })\n .join(', ');\n\n throw new Error(`Input validation failed for tool '${tool.name}': ${errors}`);\n }\n }\n\n /**\n * Execute a custom tool\n */\n async execute(\n toolName: string,\n args: Record<string, unknown>,\n context?: {\n pr?: {\n number: number;\n title: string;\n author: string;\n branch: string;\n base: string;\n };\n files?: unknown[];\n outputs?: Record<string, unknown>;\n env?: Record<string, string>;\n }\n ): Promise<unknown> {\n const tool = this.tools.get(toolName);\n if (!tool) {\n throw new Error(`Tool not found: ${toolName}`);\n }\n\n // Validate input\n this.validateInput(tool, args);\n\n // Build template context\n const templateContext = {\n ...context,\n args,\n input: args,\n };\n\n // Render command with Liquid\n const command = await this.liquid.parseAndRender(tool.exec, templateContext);\n\n // Render stdin if provided\n let stdin: string | undefined;\n if (tool.stdin) {\n stdin = await this.liquid.parseAndRender(tool.stdin, templateContext);\n }\n\n // Execute the command using shared executor\n const env = commandExecutor.buildEnvironment(process.env, tool.env, context?.env);\n const result = await commandExecutor.execute(command, {\n stdin,\n cwd: tool.cwd,\n env,\n timeout: tool.timeout || 30000,\n });\n\n // Parse JSON if requested\n let output: unknown = result.stdout;\n if (tool.parseJson) {\n try {\n output = JSON.parse(result.stdout);\n } catch (e) {\n logger.warn(`Failed to parse tool output as JSON: ${e}`);\n }\n }\n\n // Apply transform if specified\n if (tool.transform) {\n const transformContext = {\n ...templateContext,\n output,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n };\n const transformed = await this.liquid.parseAndRender(tool.transform, transformContext);\n // Try to parse as JSON if it looks like JSON\n if (typeof transformed === 'string' && transformed.trim().startsWith('{')) {\n try {\n output = JSON.parse(transformed);\n } catch {\n output = transformed;\n }\n } else {\n output = transformed;\n }\n }\n\n // Apply JavaScript transform if specified\n if (tool.transform_js) {\n output = await this.applyJavaScriptTransform(tool.transform_js, output, {\n ...templateContext,\n stdout: result.stdout,\n stderr: result.stderr,\n exitCode: result.exitCode,\n });\n }\n\n return output;\n }\n\n /**\n * Apply JavaScript transform to output\n */\n private async applyJavaScriptTransform(\n transformJs: string,\n output: unknown,\n context: Record<string, unknown>\n ): Promise<unknown> {\n if (!this.sandbox) {\n this.sandbox = createSecureSandbox();\n }\n\n const code = `\n const output = ${JSON.stringify(output)};\n const context = ${JSON.stringify(context)};\n const args = context.args || {};\n const pr = context.pr || {};\n const files = context.files || [];\n const outputs = context.outputs || {};\n const env = context.env || {};\n\n ${transformJs}\n `;\n\n try {\n return await compileAndRun(this.sandbox, code, { timeout: 5000 });\n } catch (error) {\n logger.error(`JavaScript transform error: ${error}`);\n throw error;\n }\n }\n\n /**\n * Convert custom tools to MCP tool format\n */\n toMcpTools(): Array<{\n name: string;\n description?: string;\n inputSchema?: Record<string, unknown>;\n handler: (args: Record<string, unknown>) => Promise<unknown>;\n }> {\n return Array.from(this.tools.values()).map(tool => ({\n name: tool.name,\n description: tool.description,\n inputSchema: tool.inputSchema as Record<string, unknown>,\n handler: async (args: Record<string, unknown>) => {\n return this.execute(tool.name, args);\n },\n }));\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { logger } from '../logger';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { CustomToolExecutor } from './custom-tool-executor';\nimport { CustomToolDefinition } from '../types/config';\n\n/**\n * MCP Check Provider Configuration\n */\nexport interface McpCheckConfig extends CheckProviderConfig {\n /** Transport type: stdio (default), sse (legacy), http (streamable HTTP), or custom (YAML-defined tools) */\n transport?: 'stdio' | 'sse' | 'http' | 'custom';\n /** Command to execute (for stdio transport) */\n command?: string;\n /** Command arguments (for stdio transport) */\n args?: string[];\n /** Environment variables (for stdio transport) */\n env?: Record<string, string>;\n /** Working directory (for stdio transport) */\n workingDirectory?: string;\n /** URL for SSE/HTTP transport */\n url?: string;\n /** HTTP headers (for SSE/HTTP transport) */\n headers?: Record<string, string>;\n /** Session ID for HTTP transport (optional, server may generate one) */\n sessionId?: string;\n /** MCP method/tool to call */\n method: string;\n /** Arguments to pass to the MCP method (supports Liquid templates) */\n methodArgs?: Record<string, unknown>;\n /** Transform template for method arguments (Liquid) */\n argsTransform?: string;\n /** Transform template for output (Liquid) */\n transform?: string;\n /** Transform using JavaScript expressions */\n transform_js?: string;\n /** Timeout in seconds */\n timeout?: number;\n}\n\n/**\n * Check provider that calls MCP tools directly\n * Supports stdio, SSE (legacy), Streamable HTTP transports, and custom YAML-defined tools\n */\nexport class McpCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n private customToolExecutor?: CustomToolExecutor;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n }\n\n /**\n * Set custom tools for this provider\n */\n setCustomTools(tools: Record<string, CustomToolDefinition>): void {\n if (!this.customToolExecutor) {\n this.customToolExecutor = new CustomToolExecutor(tools);\n } else {\n this.customToolExecutor.registerTools(tools);\n }\n }\n\n /**\n * Create a secure sandbox for JavaScript execution\n * - Uses Sandbox.SAFE_GLOBALS which excludes: Function, eval, require, process, etc.\n * - Only allows explicitly whitelisted prototype methods\n * - No access to filesystem, network, or system resources\n */\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n getName(): string {\n return 'mcp';\n }\n\n getDescription(): string {\n return 'Call MCP tools directly using stdio, SSE, HTTP, or custom YAML-defined tools';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as McpCheckConfig;\n\n // Method is required\n if (!cfg.method || typeof cfg.method !== 'string') {\n logger.error('MCP check requires a method name');\n return false;\n }\n\n const transport = cfg.transport || 'stdio';\n\n // Validate transport-specific requirements\n if (transport === 'stdio') {\n if (!cfg.command || typeof cfg.command !== 'string') {\n logger.error('MCP stdio transport requires a command');\n return false;\n }\n\n // Basic command injection prevention - check for shell metacharacters\n // Allow common safe commands like 'npx', 'node', 'python', etc.\n if (/[;&|`$(){}[\\]]/.test(cfg.command)) {\n logger.error('MCP stdio command contains potentially unsafe characters');\n return false;\n }\n } else if (transport === 'sse' || transport === 'http') {\n if (!cfg.url || typeof cfg.url !== 'string') {\n logger.error(`MCP ${transport} transport requires a URL`);\n return false;\n }\n\n // Validate URL format\n try {\n const parsedUrl = new URL(cfg.url);\n // Only allow http and https protocols\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n logger.error(\n `Invalid URL protocol for MCP ${transport} transport: ${parsedUrl.protocol}. Only http: and https: are allowed.`\n );\n return false;\n }\n } catch {\n logger.error(`Invalid URL format for MCP ${transport} transport: ${cfg.url}`);\n return false;\n }\n } else if (transport === 'custom') {\n // For custom transport, validation is delegated to CustomToolExecutor\n // The tool must exist in the configuration's tools section\n // This will be validated at execution time when the tool is looked up\n logger.debug(`MCP custom transport will validate tool '${cfg.method}' at execution time`);\n } else {\n logger.error(\n `Invalid MCP transport: ${transport}. Must be 'stdio', 'sse', 'http', or 'custom'`\n );\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<ReviewSummary> {\n const cfg = config as McpCheckConfig;\n\n try {\n // Prepare template context\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n fileCount: prInfo.files.length,\n outputs: this.buildOutputContext(dependencyResults),\n env: this.getSafeEnvironmentVariables(),\n };\n\n // Render method arguments if needed\n let methodArgs = cfg.methodArgs || {};\n if (cfg.argsTransform) {\n const rendered = await this.liquid.parseAndRender(cfg.argsTransform, templateContext);\n try {\n methodArgs = JSON.parse(rendered);\n } catch (error) {\n logger.error(`Failed to parse argsTransform as JSON: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/args_transform_error',\n message: `Failed to parse argsTransform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Create MCP client and execute method\n const result = await this.executeMcpMethod(cfg, methodArgs, prInfo, dependencyResults);\n\n // Apply transforms if specified\n let finalOutput = result;\n\n // Apply Liquid transform\n if (cfg.transform) {\n try {\n const transformContext = {\n ...templateContext,\n output: result,\n };\n const rendered = await this.liquid.parseAndRender(cfg.transform, transformContext);\n try {\n finalOutput = JSON.parse(rendered.trim());\n } catch {\n finalOutput = rendered.trim();\n }\n } catch (error) {\n logger.error(`Failed to apply Liquid transform: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/transform_error',\n message: `Failed to apply transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Apply JavaScript transform using secure sandbox\n if (cfg.transform_js) {\n try {\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n\n // Build scope with all context variables\n const scope = {\n output: finalOutput,\n pr: templateContext.pr,\n files: templateContext.files,\n outputs: templateContext.outputs,\n env: templateContext.env,\n };\n\n // Compile and execute the transform in sandboxed environment\n finalOutput = compileAndRun<unknown>(\n this.sandbox,\n `return (${cfg.transform_js});`,\n scope,\n { injectLog: true, wrapFunction: false, logPrefix: '[mcp:transform_js]' }\n );\n } catch (error) {\n logger.error(`Failed to apply JavaScript transform: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/transform_js_error',\n message: `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Extract issues from output\n const extracted = this.extractIssuesFromOutput(finalOutput);\n if (extracted) {\n return {\n issues: extracted.issues,\n ...(extracted.remainingOutput ? { output: extracted.remainingOutput } : {}),\n } as ReviewSummary;\n }\n\n // Return output directly\n return {\n issues: [],\n ...(finalOutput ? { output: finalOutput } : {}),\n } as ReviewSummary;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n logger.error(`MCP check failed: ${errorMessage}`);\n\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/execution_error',\n message: `MCP check failed: ${errorMessage}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n /**\n * Execute an MCP method using the configured transport\n */\n private async executeMcpMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n prInfo?: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<unknown> {\n const transport = config.transport || 'stdio';\n const timeout = (config.timeout || 60) * 1000; // Convert to milliseconds\n\n if (transport === 'custom') {\n // Execute custom YAML-defined tool\n if (!this.customToolExecutor) {\n throw new Error(\n 'No custom tools available. Define tools in the \"tools\" section of your configuration.'\n );\n }\n\n const tool = this.customToolExecutor.getTool(config.method);\n if (!tool) {\n throw new Error(\n `Custom tool not found: ${config.method}. Available tools: ${this.customToolExecutor\n .getTools()\n .map(t => t.name)\n .join(', ')}`\n );\n }\n\n // Build context for custom tool execution\n const context = {\n pr: prInfo\n ? {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n }\n : undefined,\n files: prInfo?.files,\n outputs: this.buildOutputContext(dependencyResults),\n env: this.getSafeEnvironmentVariables(),\n };\n\n return await this.customToolExecutor.execute(config.method, methodArgs, context);\n } else if (transport === 'stdio') {\n return await this.executeStdioMethod(config, methodArgs, timeout);\n } else if (transport === 'sse') {\n return await this.executeSseMethod(config, methodArgs, timeout);\n } else if (transport === 'http') {\n return await this.executeHttpMethod(config, methodArgs, timeout);\n } else {\n throw new Error(`Unsupported transport: ${transport}`);\n }\n }\n\n /**\n * Generic method to execute MCP method with any transport\n */\n private async executeWithTransport(\n transport: StdioClientTransport | SSEClientTransport | StreamableHTTPClientTransport,\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number,\n transportName: string\n ): Promise<unknown> {\n // Create client\n const client = new Client(\n {\n name: 'visor-mcp-client',\n version: '1.0.0',\n },\n {\n capabilities: {},\n }\n );\n\n try {\n // Connect with timeout\n let timeoutId: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n client.connect(transport),\n new Promise((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error('Connection timeout')), timeout);\n }),\n ]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n logger.debug(`Connected to MCP server via ${transportName}`);\n\n // Log session ID for HTTP transport\n if (transport instanceof StreamableHTTPClientTransport && transport.sessionId) {\n logger.debug(`MCP Session ID: ${transport.sessionId}`);\n }\n\n // List available tools (for debugging)\n try {\n const toolsResult = await client.listTools();\n logger.debug(`Available MCP tools: ${JSON.stringify(toolsResult?.tools || [])}`);\n } catch (error) {\n logger.debug(`Could not list MCP tools: ${error}`);\n }\n\n // Call the tool with timeout\n let callTimeoutId: NodeJS.Timeout | undefined;\n try {\n const result = await Promise.race([\n client.callTool({\n name: config.method,\n arguments: methodArgs,\n }),\n new Promise((_, reject) => {\n callTimeoutId = setTimeout(() => reject(new Error('Request timeout')), timeout);\n }),\n ]);\n\n logger.debug(`MCP method result: ${JSON.stringify(result)}`);\n return result;\n } finally {\n if (callTimeoutId) {\n clearTimeout(callTimeoutId);\n }\n }\n } finally {\n try {\n await client.close();\n } catch (error) {\n logger.debug(`Error closing MCP client: ${error}`);\n }\n }\n }\n\n /**\n * Execute MCP method using stdio transport\n */\n private async executeStdioMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const transport = new StdioClientTransport({\n command: config.command!,\n args: config.command_args as string[] | undefined,\n env: config.env,\n cwd: config.workingDirectory,\n });\n\n return this.executeWithTransport(\n transport,\n config,\n methodArgs,\n timeout,\n `stdio: ${config.command}`\n );\n }\n\n /**\n * Execute MCP method using SSE transport\n */\n private async executeSseMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const requestInit: RequestInit = {};\n if (config.headers) {\n requestInit.headers = EnvironmentResolver.resolveHeaders(config.headers);\n }\n\n const transport = new SSEClientTransport(new URL(config.url!), {\n requestInit,\n });\n\n return this.executeWithTransport(transport, config, methodArgs, timeout, `SSE: ${config.url}`);\n }\n\n /**\n * Execute MCP method using Streamable HTTP transport\n */\n private async executeHttpMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const requestInit: RequestInit = {};\n if (config.headers) {\n requestInit.headers = EnvironmentResolver.resolveHeaders(config.headers);\n }\n\n const transport = new StreamableHTTPClientTransport(new URL(config.url!), {\n requestInit,\n sessionId: config.sessionId,\n });\n\n return this.executeWithTransport(\n transport,\n config,\n methodArgs,\n timeout,\n `Streamable HTTP: ${config.url}`\n );\n }\n\n /**\n * Build output context from dependency results\n */\n private buildOutputContext(\n dependencyResults?: Map<string, ReviewSummary>\n ): Record<string, unknown> {\n if (!dependencyResults) {\n return {};\n }\n\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of dependencyResults) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n\n return outputs;\n }\n\n /**\n * Get safe environment variables\n */\n private getSafeEnvironmentVariables(): Record<string, string> {\n const safeVars: Record<string, string> = {};\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const allowedPrefixes: string[] = []; // replaced by buildSandboxEnv\n\n const { buildSandboxEnv } = require('../utils/env-exposure');\n const merged = buildSandboxEnv(process.env);\n for (const [key, value] of Object.entries(merged)) {\n safeVars[key] = String(value);\n }\n safeVars['PWD'] = process.cwd();\n return safeVars;\n }\n\n /**\n * Extract issues from MCP output\n */\n private extractIssuesFromOutput(\n output: unknown\n ): { issues: ReviewIssue[]; remainingOutput: unknown } | null {\n if (output === null || output === undefined) {\n return null;\n }\n\n // If output is a string, try to parse as JSON\n if (typeof output === 'string') {\n try {\n const parsed = JSON.parse(output);\n return this.extractIssuesFromOutput(parsed);\n } catch {\n return null;\n }\n }\n\n // If output is an array of issues\n if (Array.isArray(output)) {\n const issues = this.normalizeIssueArray(output);\n if (issues) {\n return { issues, remainingOutput: undefined };\n }\n return null;\n }\n\n // If output is an object with issues property\n if (typeof output === 'object') {\n const record = output as Record<string, unknown>;\n\n if (Array.isArray(record.issues)) {\n const issues = this.normalizeIssueArray(record.issues);\n if (!issues) {\n return null;\n }\n\n const remaining = { ...record };\n delete (remaining as { issues?: unknown }).issues;\n\n return {\n issues,\n remainingOutput: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n }\n\n // Check if output itself is a single issue\n const singleIssue = this.normalizeIssue(record);\n if (singleIssue) {\n return { issues: [singleIssue], remainingOutput: undefined };\n }\n }\n\n return null;\n }\n\n /**\n * Normalize an array of issues\n */\n private normalizeIssueArray(values: unknown[]): ReviewIssue[] | null {\n const normalized: ReviewIssue[] = [];\n\n for (const value of values) {\n const issue = this.normalizeIssue(value);\n if (!issue) {\n return null;\n }\n normalized.push(issue);\n }\n\n return normalized;\n }\n\n /**\n * Normalize a single issue\n */\n private normalizeIssue(raw: unknown): ReviewIssue | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const data = raw as Record<string, unknown>;\n\n const message = this.toTrimmedString(\n data.message || data.text || data.description || data.summary\n );\n if (!message) {\n return null;\n }\n\n const allowedSeverities = new Set(['info', 'warning', 'error', 'critical']);\n const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);\n let severity: ReviewIssue['severity'] = 'warning';\n if (severityRaw) {\n const lower = severityRaw.toLowerCase();\n if (allowedSeverities.has(lower)) {\n severity = lower as ReviewIssue['severity'];\n }\n }\n\n const allowedCategories = new Set([\n 'security',\n 'performance',\n 'style',\n 'logic',\n 'documentation',\n ]);\n const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);\n let category: ReviewIssue['category'] = 'logic';\n if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {\n category = categoryRaw.toLowerCase() as ReviewIssue['category'];\n }\n\n const file = this.toTrimmedString(data.file || data.path || data.filename) || 'system';\n const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;\n const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);\n const suggestion = this.toTrimmedString(data.suggestion);\n const replacement = this.toTrimmedString(data.replacement);\n const ruleId = this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || 'mcp';\n\n return {\n file,\n line,\n endLine: endLine ?? undefined,\n ruleId,\n message,\n severity,\n category,\n suggestion: suggestion || undefined,\n replacement: replacement || undefined,\n };\n }\n\n private toTrimmedString(value: unknown): string | null {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n if (value !== null && value !== undefined && typeof value.toString === 'function') {\n const converted = String(value).trim();\n return converted.length > 0 ? converted : null;\n }\n return null;\n }\n\n private toNumber(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = Number(value);\n if (Number.isFinite(num)) {\n return Math.trunc(num);\n }\n return null;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'transport',\n 'command',\n 'command_args',\n 'env',\n 'workingDirectory',\n 'url',\n 'headers',\n 'sessionId',\n 'method',\n 'methodArgs',\n 'argsTransform',\n 'transform',\n 'transform_js',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // MCP SDK is now a required dependency, so always available\n return true;\n }\n\n getRequirements(): string[] {\n return ['MCP method name specified', 'Transport configuration (stdio: command, sse/http: url)'];\n }\n}\n","/**\n * Interactive terminal prompting (minimal TTY UI)\n */\n\nimport * as readline from 'readline';\n\n// Global, process-wide guard to ensure we never open two readline prompts at once.\n// This is crucial because the engine may (due to routing) attempt to schedule\n// a second human-input step while the first is still waiting. Two concurrent\n// readline instances on the same TTY cause duplicated keystrokes and other\n// erratic behavior. We serialize prompts with a tiny async mutex.\nlet activePrompt = false;\nconst waiters: Array<() => void> = [];\n\nasync function acquirePromptLock(): Promise<void> {\n if (!activePrompt) {\n activePrompt = true;\n return;\n }\n await new Promise<void>(resolve => waiters.push(resolve));\n activePrompt = true;\n}\n\nfunction releasePromptLock(): void {\n activePrompt = false;\n const next = waiters.shift();\n if (next) next();\n}\n\nexport interface PromptOptions {\n /** The prompt text to display */\n prompt: string;\n /** Placeholder text (shown in dim color) */\n placeholder?: string;\n /** Allow multiline input (Ctrl+D to finish) */\n multiline?: boolean;\n /** Timeout in milliseconds */\n timeout?: number;\n /** Default value if timeout occurs */\n defaultValue?: string;\n /** Allow empty input */\n allowEmpty?: boolean;\n}\n/**\n * Prompt user for input with a beautiful interactive UI\n */\nexport async function interactivePrompt(options: PromptOptions): Promise<string> {\n await acquirePromptLock();\n return new Promise((resolve, reject) => {\n const dbg = process.env.VISOR_DEBUG === 'true';\n try {\n if (dbg) {\n const counts: Record<string, number> = {\n data: process.stdin.listenerCount('data'),\n end: process.stdin.listenerCount('end'),\n error: process.stdin.listenerCount('error'),\n readable: process.stdin.listenerCount('readable'),\n close: process.stdin.listenerCount('close'),\n } as any;\n console.error(\n `[human-input] starting prompt: isTTY=${!!process.stdin.isTTY} active=${activePrompt} waiters=${waiters.length} listeners=${JSON.stringify(counts)}`\n );\n }\n } catch {}\n // Ensure stdin is in a sane state for a fresh interactive session\n try {\n if (process.stdin.isTTY && typeof (process.stdin as any).setRawMode === 'function') {\n // We use line-based input; disable raw mode just in case\n (process.stdin as any).setRawMode(false);\n }\n // Always resume stdin before creating the interface\n process.stdin.resume();\n } catch {}\n\n // Ensure encoding is set for predictable behavior\n try {\n process.stdin.setEncoding('utf8');\n } catch {}\n\n let rl: readline.Interface | undefined;\n\n const allowEmpty = options.allowEmpty ?? false;\n const multiline = options.multiline ?? false;\n const defaultValue = options.defaultValue;\n\n let timeoutId: NodeJS.Timeout | undefined;\n const cleanup = () => {\n if (timeoutId) clearTimeout(timeoutId);\n try {\n rl?.removeAllListeners();\n } catch {}\n try {\n rl?.close();\n } catch {}\n // Hardening: make sure no stray listeners remain on stdin between loops\n // Do not blanket-remove listeners from process.stdin; a fresh readline\n // instance will manage its own listeners. Over-removing here can leave\n // the next interface in a bad state (no keypress events).\n try {\n if (process.stdin.isTTY && typeof (process.stdin as any).setRawMode === 'function') {\n (process.stdin as any).setRawMode(false);\n }\n } catch {}\n try {\n process.stdin.pause();\n } catch {}\n // Release the global lock so a queued prompt (if any) may proceed\n try {\n releasePromptLock();\n } catch {}\n // If stdout/stderr were temporarily wrapped by the question handler, restore them now\n try {\n if ((process.stdout as any).__restoreWrites) {\n (process.stdout as any).__restoreWrites();\n }\n } catch {}\n try {\n if ((process.stderr as any).__restoreWrites) {\n (process.stderr as any).__restoreWrites();\n }\n } catch {}\n try {\n if (dbg) {\n const counts: Record<string, number> = {\n data: process.stdin.listenerCount('data'),\n end: process.stdin.listenerCount('end'),\n error: process.stdin.listenerCount('error'),\n readable: process.stdin.listenerCount('readable'),\n close: process.stdin.listenerCount('close'),\n } as any;\n console.error(\n `[human-input] cleanup: isTTY=${!!process.stdin.isTTY} active=false waiters=${waiters.length} listeners=${JSON.stringify(counts)}`\n );\n }\n } catch {}\n };\n const finish = (value: string) => {\n cleanup();\n resolve(value);\n };\n\n // Optional timeout (no default)\n if (options.timeout && options.timeout > 0) {\n timeoutId = setTimeout(() => {\n cleanup();\n if (defaultValue !== undefined) return resolve(defaultValue);\n return reject(new Error('Input timeout'));\n }, options.timeout);\n }\n\n // Print minimal header with dashed separators\n const header: string[] = [];\n if (options.prompt && options.prompt.trim()) header.push(options.prompt.trim());\n if (multiline) header.push('(Ctrl+D to submit)');\n if (options.placeholder && !multiline) header.push(options.placeholder);\n const width = Math.max(\n 20,\n Math.min((process.stdout && (process.stdout as any).columns) || 80, 100)\n );\n const dash = '-'.repeat(width);\n try {\n console.log('\\n' + dash);\n if (header.length) console.log(header.join('\\n'));\n console.log(dash);\n } catch {}\n\n // No echo-suppression hacks — we fix the root cause below by using raw-mode\n // input for single-line prompts, so the terminal never replays the line.\n\n if (multiline) {\n rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n let buf = '';\n process.stdout.write('> ');\n rl.on('line', line => {\n buf += (buf ? '\\n' : '') + line;\n process.stdout.write('> ');\n });\n rl.on('close', () => {\n const trimmed = buf.trim();\n if (!trimmed && !allowEmpty && defaultValue === undefined) {\n return reject(new Error('Empty input not allowed'));\n }\n return finish(trimmed || defaultValue || '');\n });\n rl.on('SIGINT', () => {\n try {\n // Print a clean newline and exit immediately with 130 (SIGINT)\n process.stdout.write('\\n');\n } catch {}\n cleanup();\n process.exit(130);\n });\n } else {\n // Root cause fix: raw-mode single-line input without readline echo.\n const readLineRaw = async (): Promise<string> => {\n return new Promise<string>(resolveRaw => {\n let buf = '';\n const onData = (chunk: Buffer) => {\n const s = chunk.toString('utf8');\n for (let i = 0; i < s.length; i++) {\n const ch = s[i];\n const code = s.charCodeAt(i);\n if (ch === '\\n' || ch === '\\r') {\n try {\n process.stdout.write('\\n');\n } catch {}\n teardown();\n resolveRaw(buf);\n return;\n }\n if (ch === '\\b' || code === 127) {\n if (buf.length > 0) {\n buf = buf.slice(0, -1);\n try {\n process.stdout.write('\\b \\b');\n } catch {}\n }\n continue;\n }\n if (code === 3) {\n // Ctrl+C\n try {\n process.stdout.write('\\n');\n } catch {}\n teardown();\n process.exit(130);\n }\n if (code >= 32) {\n buf += ch;\n try {\n process.stdout.write(ch);\n } catch {}\n }\n }\n };\n const teardown = () => {\n try {\n process.stdin.off('data', onData);\n } catch {}\n try {\n if (process.stdin.isTTY && typeof (process.stdin as any).setRawMode === 'function') {\n (process.stdin as any).setRawMode(false);\n }\n } catch {}\n };\n try {\n if (process.stdin.isTTY && typeof (process.stdin as any).setRawMode === 'function') {\n (process.stdin as any).setRawMode(true);\n }\n } catch {}\n process.stdin.on('data', onData);\n try {\n process.stdout.write('> ');\n } catch {}\n });\n };\n (async () => {\n const answer = await readLineRaw();\n const trimmed = (answer || '').trim();\n if (!trimmed && !allowEmpty && defaultValue === undefined) {\n cleanup();\n return reject(new Error('Empty input not allowed'));\n }\n return finish(trimmed || defaultValue || '');\n })().catch(err => {\n cleanup();\n reject(err);\n });\n }\n });\n}\n\n/**\n * Simple prompt without fancy UI (for non-TTY environments)\n */\nexport async function simplePrompt(prompt: string): Promise<string> {\n return new Promise(resolve => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.on('SIGINT', () => {\n try {\n process.stdout.write('\\n');\n } catch {}\n rl.close();\n process.exit(130);\n });\n\n rl.question(`${prompt}\\n> `, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n","/**\n * Utilities for reading from stdin\n */\n\n/**\n * Check if stdin has data available (is being piped)\n */\nexport function isStdinAvailable(): boolean {\n // Check if stdin is a TTY (interactive terminal)\n // If it's not a TTY, it means data is being piped\n return !process.stdin.isTTY;\n}\n\n/**\n * Read all data from stdin\n * @param timeout Optional timeout in milliseconds\n * @param maxSize Maximum size in bytes (default: 1MB)\n * @returns Promise that resolves with the stdin content\n */\nexport async function readStdin(timeout?: number, maxSize: number = 1024 * 1024): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n let timeoutId: NodeJS.Timeout | undefined;\n\n if (timeout) {\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error(`Stdin read timeout after ${timeout}ms`));\n }, timeout);\n }\n\n const cleanup = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n process.stdin.removeListener('data', onData);\n process.stdin.removeListener('end', onEnd);\n process.stdin.removeListener('error', onError);\n // Pause stdin to prevent resource leaks\n process.stdin.pause();\n };\n\n const onData = (chunk: Buffer) => {\n data += chunk.toString();\n // Security: Prevent DoS through large input\n if (data.length > maxSize) {\n cleanup();\n reject(new Error(`Input exceeds maximum size of ${maxSize} bytes`));\n }\n };\n\n const onEnd = () => {\n cleanup();\n resolve(data.trim());\n };\n\n const onError = (err: Error) => {\n cleanup();\n reject(err);\n };\n\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', onData);\n process.stdin.on('end', onEnd);\n process.stdin.on('error', onError);\n\n // Resume stdin in case it's paused\n process.stdin.resume();\n });\n}\n\n/**\n * Try to read from stdin if available, otherwise return null\n * @param timeout Optional timeout in milliseconds\n * @param maxSize Maximum size in bytes (default: 1MB)\n * @returns Promise that resolves with stdin content or null if not available\n */\nexport async function tryReadStdin(\n timeout?: number,\n maxSize: number = 1024 * 1024\n): Promise<string | null> {\n if (!isStdinAvailable()) {\n return null;\n }\n\n try {\n return await readStdin(timeout, maxSize);\n } catch {\n // If reading fails, return null\n return null;\n }\n}\n","import { CheckProvider, CheckProviderConfig, ExecutionContext } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { HumanInputRequest } from '../types/config';\nimport { interactivePrompt, simplePrompt } from '../utils/interactive-prompt';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { tryReadStdin } from '../utils/stdin-reader';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Human input check provider that pauses workflow to request user input.\n *\n * Supports four modes:\n * 1. CLI with --message argument (inline or file path)\n * 2. CLI with piped stdin\n * 3. CLI interactive mode (beautiful terminal UI)\n * 4. SDK mode with onHumanInput hook\n *\n * Example config:\n * ```yaml\n * checks:\n * approval:\n * type: human-input\n * prompt: \"Do you approve? (yes/no)\"\n * allow_empty: false\n * timeout: 300000\n * ```\n */\nexport class HumanInputCheckProvider extends CheckProvider {\n private liquid?: Liquid;\n /**\n * @deprecated Use ExecutionContext.cliMessage instead\n * Kept for backward compatibility\n */\n private static cliMessage: string | undefined;\n\n /**\n * @deprecated Use ExecutionContext.hooks instead\n * Kept for backward compatibility\n */\n private static hooks: { onHumanInput?: (request: HumanInputRequest) => Promise<string> } = {};\n\n /**\n * Set the CLI message value (from --message argument)\n * @deprecated Use ExecutionContext.cliMessage instead\n */\n static setCLIMessage(message: string | undefined): void {\n HumanInputCheckProvider.cliMessage = message;\n }\n\n /**\n * Get the current CLI message value\n * @deprecated Use ExecutionContext.cliMessage instead\n */\n static getCLIMessage(): string | undefined {\n return HumanInputCheckProvider.cliMessage;\n }\n\n /**\n * Set hooks for SDK mode\n * @deprecated Use ExecutionContext.hooks instead\n */\n static setHooks(hooks: { onHumanInput?: (request: HumanInputRequest) => Promise<string> }): void {\n HumanInputCheckProvider.hooks = hooks;\n }\n\n getName(): string {\n return 'human-input';\n }\n\n getDescription(): string {\n return 'Prompts for human input during workflow execution (CLI interactive or SDK hook)';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'human-input'\n if (cfg.type !== 'human-input') {\n return false;\n }\n\n // Prompt is required\n if (!cfg.prompt || typeof cfg.prompt !== 'string') {\n console.error('human-input check requires a \"prompt\" field');\n return false;\n }\n\n return true;\n }\n\n /** Build a template context for Liquid rendering */\n private buildTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n outputHistory?: Map<string, unknown[]>,\n _context?: ExecutionContext\n ): Record<string, unknown> {\n const ctx: Record<string, unknown> = {};\n // pr context\n try {\n ctx.pr = {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n files: (prInfo.files || []).map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n })),\n };\n } catch {}\n // event + env\n try {\n const safeEnv = (() => {\n try {\n const { buildSandboxEnv } = require('../utils/env-exposure');\n return buildSandboxEnv(process.env);\n } catch {\n return {} as Record<string, string>;\n }\n })();\n (ctx as any).event = { event_name: (prInfo as any)?.eventType || 'manual' };\n (ctx as any).env = safeEnv;\n } catch {}\n // utils helpers\n (ctx as any).utils = {\n now: new Date().toISOString(),\n today: new Date().toISOString().split('T')[0],\n };\n // outputs: expose raw outputs from dependency results\n const outputs: Record<string, unknown> = {};\n const outputsRaw: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [name, res] of dependencyResults.entries()) {\n const summary = res as ReviewSummary & { output?: unknown };\n if (typeof name === 'string' && name.endsWith('-raw')) {\n outputsRaw[name.slice(0, -4)] = summary.output !== undefined ? summary.output : summary;\n } else {\n outputs[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n }\n ctx.outputs = outputs;\n (ctx as any).outputs_raw = outputsRaw;\n // outputs_history: expose full history if available\n const hist: Record<string, unknown[]> = {};\n if (outputHistory) {\n for (const [k, v] of outputHistory.entries()) hist[k] = Array.isArray(v) ? v : [];\n }\n (ctx as any).outputs_history = hist;\n return ctx;\n }\n\n /**\n * Check if a string looks like a file path\n */\n private looksLikePath(str: string): boolean {\n return str.includes('/') || str.includes('\\\\');\n }\n\n /**\n * Sanitize user input to prevent injection attacks in dependent checks\n * Removes potentially dangerous characters while preserving useful input\n */\n private sanitizeInput(input: string): string {\n // Heuristic: collapse accidental per-character duplication (\"stutter\") often caused by\n // TTY echo races. We only apply this when most adjacent ASCII chars are doubled.\n const collapseStutter = (s: string): string => {\n if (!s || s.length < 4) return s;\n let dupPairs = 0;\n let pairs = 0;\n for (let i = 0; i + 1 < s.length; i++) {\n const a = s[i];\n const b = s[i + 1];\n if (/^[\\x20-\\x7E]$/.test(a) && /^[\\x20-\\x7E]$/.test(b)) {\n pairs++;\n if (a === b) dupPairs++;\n }\n }\n const ratio = pairs > 0 ? dupPairs / pairs : 0;\n if (ratio < 0.5) return s; // keep as-is unless roughly half of pairs are doubled\n let out = '';\n for (let i = 0; i < s.length; i++) {\n const a = s[i];\n const b = i + 1 < s.length ? s[i + 1] : '';\n if (b && a === b) {\n out += a;\n i++; // skip the duplicate\n } else {\n out += a;\n }\n }\n return out;\n };\n\n input = collapseStutter(input);\n // Remove null bytes (C-string injection)\n let sanitized = input.replace(/\\0/g, '');\n\n // Remove control characters except newlines and tabs\n sanitized = sanitized.replace(/[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\n // Limit length to prevent memory issues (100KB max)\n const maxLength = 100 * 1024;\n if (sanitized.length > maxLength) {\n sanitized = sanitized.substring(0, maxLength);\n }\n\n return sanitized;\n }\n\n /**\n * Try to read message from file if it exists\n * Validates path to prevent directory traversal attacks\n */\n private async tryReadFile(filePath: string): Promise<string | null> {\n try {\n // Handle both absolute and relative paths\n const absolutePath = path.isAbsolute(filePath)\n ? filePath\n : path.resolve(process.cwd(), filePath);\n\n // Normalize path to resolve .. and . components\n const normalizedPath = path.normalize(absolutePath);\n\n // Security: Prevent path traversal attacks\n // Only allow files within current working directory or its subdirectories\n const cwd = process.cwd();\n if (!normalizedPath.startsWith(cwd + path.sep) && normalizedPath !== cwd) {\n // Path is outside working directory\n return null;\n }\n\n // Use async file access check instead of sync existsSync\n try {\n await fs.promises.access(normalizedPath, fs.constants.R_OK);\n const stats = await fs.promises.stat(normalizedPath);\n\n // Only read regular files, not directories or special files\n if (!stats.isFile()) {\n return null;\n }\n\n const content = await fs.promises.readFile(normalizedPath, 'utf-8');\n return content.trim();\n } catch {\n // File doesn't exist or isn't readable\n return null;\n }\n } catch {\n // If file read fails, treat as literal string\n }\n return null;\n }\n\n /**\n * Get user input through various methods\n */\n private async getUserInput(\n checkName: string,\n config: CheckProviderConfig,\n context?: ExecutionContext\n ): Promise<string> {\n // Test runner mock support: if a mock is provided for this step, use it\n try {\n const mockVal = context?.hooks?.mockForStep?.(checkName);\n if (mockVal !== undefined && mockVal !== null) {\n const s = String(mockVal);\n return s;\n }\n } catch {}\n const prompt = (config.prompt as string) || 'Please provide input:';\n const placeholder = (config.placeholder as string | undefined) || 'Enter your response...';\n const allowEmpty = (config.allow_empty as boolean | undefined) ?? false;\n const multiline = (config.multiline as boolean | undefined) ?? false;\n const timeout = config.timeout ? config.timeout * 1000 : undefined; // Convert to ms\n const defaultValue = config.default as string | undefined;\n\n // In test/CI modes, never block for input. Use default or empty string.\n const testMode = String(process.env.VISOR_TEST_MODE || '').toLowerCase() === 'true';\n const ciMode =\n String(process.env.CI || '').toLowerCase() === 'true' ||\n String(process.env.GITHUB_ACTIONS || '').toLowerCase() === 'true';\n if (testMode || ciMode) {\n const val = (config.default as string | undefined) || '';\n return val;\n }\n\n // Get cliMessage from context (new way) or static property (backward compat)\n const cliMessage = context?.cliMessage ?? HumanInputCheckProvider.cliMessage;\n\n // Priority 1: Check for --message CLI argument\n if (cliMessage !== undefined) {\n const message = cliMessage;\n\n // Check if it looks like a path and try to read the file\n if (this.looksLikePath(message)) {\n const fileContent = await this.tryReadFile(message);\n if (fileContent !== null) {\n return fileContent;\n }\n }\n\n // Otherwise, use as literal message\n return message;\n }\n\n // Priority 2: Check for piped stdin\n const stdinInput = await tryReadStdin(timeout);\n if (stdinInput !== null && stdinInput.length > 0) {\n return stdinInput;\n }\n\n // Priority 3: SDK hook mode\n // Get hooks from context (new way) or static property (backward compat)\n const hooks = context?.hooks ?? HumanInputCheckProvider.hooks;\n\n if (hooks?.onHumanInput) {\n const request: HumanInputRequest = {\n checkId: checkName,\n prompt,\n placeholder,\n allowEmpty,\n multiline,\n timeout,\n default: defaultValue,\n };\n\n try {\n const result = await hooks.onHumanInput(request);\n return result;\n } catch (error) {\n throw new Error(\n `Hook onHumanInput failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n // Priority 4: Interactive terminal prompt (if TTY available)\n if (process.stdin.isTTY) {\n try {\n const result = await interactivePrompt({\n prompt,\n placeholder,\n multiline,\n timeout,\n defaultValue,\n allowEmpty,\n });\n return result;\n } catch (error) {\n throw new Error(\n `Interactive prompt failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n // Priority 5: Simple prompt (fallback for non-TTY)\n try {\n const result = await simplePrompt(prompt);\n if (!result && !allowEmpty && !defaultValue) {\n throw new Error('Empty input not allowed');\n }\n return result || defaultValue || '';\n } catch (error) {\n throw new Error(\n `Simple prompt failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async execute(\n _prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n const checkName = config.checkName || 'human-input';\n\n try {\n // Render Liquid templates in prompt/placeholder if any\n try {\n this.liquid =\n this.liquid || createExtendedLiquid({ strictVariables: false, strictFilters: false });\n const tctx = this.buildTemplateContext(\n _prInfo,\n _dependencyResults,\n (config as any).__outputHistory as Map<string, unknown[]> | undefined,\n context\n );\n if (typeof config.prompt === 'string') {\n let rendered = await this.liquid.parseAndRender(config.prompt, tctx);\n // If Liquid markers remain (e.g., due to nested/guarded templates), try a second pass\n if (/\\{\\{|\\{%/.test(rendered)) {\n try {\n rendered = await this.liquid.parseAndRender(rendered, tctx);\n } catch {}\n }\n // Expose the final rendered prompt to the test runner (like AI provider does)\n try {\n const stepName = (config as any).checkName || 'unknown';\n context?.hooks?.onPromptCaptured?.({\n step: String(stepName),\n provider: 'human-input',\n prompt: rendered,\n });\n } catch {}\n config = { ...config, prompt: rendered };\n }\n if (typeof config.placeholder === 'string') {\n let ph = await this.liquid.parseAndRender(config.placeholder as string, tctx);\n if (/\\{\\{|\\{%/.test(ph)) {\n try {\n ph = await this.liquid.parseAndRender(ph, tctx);\n } catch {}\n }\n (config as any).placeholder = ph;\n }\n } catch (e) {\n // Always show Liquid errors with a helpful snippet and caret\n const err: any = e || {};\n const raw = String((config as any)?.prompt || '');\n const lines = raw.split(/\\r?\\n/);\n const lineNum: number = Number(err.line || err?.token?.line || err?.location?.line || 0);\n const colNum: number = Number(err.col || err?.token?.col || err?.location?.col || 0);\n let snippet = '';\n if (lineNum > 0) {\n const start = Math.max(1, lineNum - 3);\n const end = Math.max(lineNum + 2, lineNum);\n const width = String(end).length;\n for (let i = start; i <= Math.min(end, lines.length); i++) {\n const ln = `${String(i).padStart(width, ' ')} | ${lines[i - 1] ?? ''}`;\n snippet += ln + '\\n';\n if (i === lineNum) {\n const caretPad = ' '.repeat(Math.max(0, colNum > 1 ? colNum - 1 : 0) + width + 3);\n snippet += caretPad + '^\\n';\n }\n }\n }\n try {\n console.error(\n `⚠️ human-input: Liquid render failed: ${\n e instanceof Error ? e.message : String(e)\n }\\n${snippet}`\n );\n } catch {}\n // Continue with raw strings as a fallback\n }\n // Get user input (pass context for non-static state)\n const userInput = await this.getUserInput(checkName, config, context);\n\n // Sanitize input to prevent injection attacks in dependent checks\n const sanitizedInput = this.sanitizeInput(userInput);\n\n // Return structured output with timestamp for consistent history/merging\n return {\n issues: [],\n output: { text: sanitizedInput, ts: Date.now() },\n } as ReviewSummary & { output: { text: string; ts: number } };\n } catch (error) {\n // If there's an error getting input, return an error issue\n return {\n issues: [\n {\n file: '',\n line: 0,\n ruleId: 'human-input-error',\n message: `Failed to get user input: ${\n error instanceof Error ? error.message : String(error)\n }`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'placeholder',\n 'allow_empty',\n 'multiline',\n 'timeout',\n 'default',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Human input provider is always available\n // It will fall back to simple prompts if interactive mode isn't available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Works in CLI mode with --message argument, piped stdin, or interactive prompts',\n 'SDK mode requires onHumanInput hook to be configured',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport { MemoryStore } from '../memory-store';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { buildProviderTemplateContext } from '../utils/template-context';\nimport { createSyncMemoryOps } from '../utils/script-memory-ops';\n\n/**\n * Provider that executes JavaScript in a secure sandbox using\n * a first-class step: `type: 'script'` + `content: | ...`.\n */\nexport class ScriptCheckProvider extends CheckProvider {\n private liquid: ReturnType<typeof createExtendedLiquid>;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n strictVariables: false,\n strictFilters: false,\n });\n }\n\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n getName(): string {\n return 'script';\n }\n\n getDescription(): string {\n return 'Execute JavaScript with access to PR context, dependency outputs, and memory.';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') return false;\n const cfg = config as CheckProviderConfig & { content?: string };\n if (typeof cfg.content !== 'string') return false;\n const trimmed = cfg.content.trim();\n if (trimmed.length === 0) return false;\n try {\n const bytes = Buffer.byteLength(cfg.content, 'utf8');\n if (bytes > 1024 * 1024) return false; // 1MB cap\n } catch {}\n if (cfg.content.indexOf('\\u0000') >= 0) return false;\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig & { content?: string },\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: {\n parentSessionId?: string;\n reuseSession?: boolean;\n } & import('./check-provider.interface').ExecutionContext\n ): Promise<ReviewSummary> {\n const script = String(config.content || '');\n const memoryStore = MemoryStore.getInstance();\n const ctx = buildProviderTemplateContext(\n prInfo,\n dependencyResults,\n memoryStore,\n (config as any).__outputHistory as Map<string, unknown[]> | undefined,\n (_sessionInfo as any)?.stageHistoryBase as Record<string, number> | undefined,\n { attachMemoryReadHelpers: false }\n );\n // Keep provider quiet by default; no step-specific debug\n // (historical ad-hoc logs removed to avoid hardcoding step names).\n\n // Attach synchronous memory ops consistent with memory provider\n const { ops, needsSave } = createSyncMemoryOps(memoryStore);\n (ctx as any).memory = ops as unknown as Record<string, unknown>;\n\n // Evaluate the script in a secure sandbox (per-execution instance)\n const sandbox = this.createSecureSandbox();\n let result: unknown;\n try {\n result = compileAndRun<unknown>(\n sandbox,\n script,\n { ...ctx },\n {\n injectLog: true,\n wrapFunction: true,\n logPrefix: '[script]',\n }\n );\n } catch (error) {\n const msg = error instanceof Error ? error.message : 'Unknown error';\n logger.error(`[script] execution error: ${msg}`);\n return {\n issues: [\n {\n file: 'script',\n line: 0,\n ruleId: 'script/execution_error',\n message: msg,\n severity: 'error',\n category: 'logic',\n },\n ],\n output: null,\n } as ReviewSummary;\n }\n\n // Persist file-backed memory once if needed\n try {\n if (\n needsSave() &&\n memoryStore.getConfig().storage === 'file' &&\n memoryStore.getConfig().auto_save\n ) {\n await memoryStore.save();\n }\n } catch (e) {\n logger.warn(`[script] memory save failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n const name = String((config as any).checkName || '');\n const t = typeof result;\n // Generic, step-agnostic debug\n console.error(\n `[script-return] ${name} outputType=${t} hasArray=${Array.isArray(result)} hasObj=${\n result && typeof result === 'object'\n }`\n );\n }\n } catch {}\n const out: any = { issues: [], output: result } as ReviewSummary & { output: unknown };\n try {\n (out as any).__histTracked = true;\n } catch {}\n return out;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'content',\n 'depends_on',\n 'group',\n 'on',\n 'if',\n 'fail_if',\n 'on_fail',\n 'on_success',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n return true;\n }\n\n getRequirements(): string[] {\n return ['No external dependencies required'];\n }\n\n // No local buildTemplateContext; uses shared builder above\n}\n","/**\n * Workflow executor for running workflow definitions\n */\n\nimport {\n WorkflowDefinition,\n WorkflowExecutionContext,\n WorkflowStep,\n WorkflowInputMapping,\n WorkflowExecutionOptions,\n} from './types/workflow';\nimport { PRInfo } from './pr-analyzer';\nimport { ReviewSummary } from './reviewer';\nimport { CheckProviderRegistry } from './providers/check-provider-registry';\nimport { CheckProviderConfig, ExecutionContext } from './providers/check-provider.interface';\nimport { DependencyResolver } from './dependency-resolver';\nimport { logger } from './logger';\nimport { createSecureSandbox, compileAndRun } from './utils/sandbox';\nimport { Liquid } from 'liquidjs';\n\n/**\n * Workflow execution result\n */\nexport interface WorkflowExecutionResult {\n success: boolean;\n score?: number;\n confidence?: 'high' | 'medium' | 'low';\n issues?: any[];\n comments?: any[];\n output?: Record<string, unknown>;\n status: 'completed' | 'failed' | 'skipped';\n duration?: number;\n error?: string;\n stepSummaries?: Array<{\n stepId: string;\n status: 'success' | 'failed' | 'skipped';\n issues?: any[];\n output?: unknown;\n }>;\n}\n\n/**\n * Execution options passed to workflow executor\n */\ninterface WorkflowRunOptions {\n prInfo: PRInfo;\n dependencyResults?: Map<string, ReviewSummary>;\n context?: ExecutionContext;\n options?: WorkflowExecutionOptions;\n}\n\n/**\n * Executes workflow definitions\n */\nexport class WorkflowExecutor {\n private providerRegistry: CheckProviderRegistry | null = null;\n private liquid: Liquid;\n\n constructor() {\n // Don't call CheckProviderRegistry.getInstance() here to avoid circular dependency\n // during registry initialization (since WorkflowCheckProvider is registered in the registry)\n this.liquid = new Liquid();\n }\n\n /**\n * Lazy-load the provider registry to avoid circular dependency during initialization\n */\n private getProviderRegistry(): CheckProviderRegistry {\n if (!this.providerRegistry) {\n this.providerRegistry = CheckProviderRegistry.getInstance();\n }\n return this.providerRegistry;\n }\n\n /**\n * Execute a workflow\n */\n public async execute(\n workflow: WorkflowDefinition,\n executionContext: WorkflowExecutionContext,\n runOptions: WorkflowRunOptions\n ): Promise<WorkflowExecutionResult> {\n const startTime = Date.now();\n executionContext.metadata = {\n startTime,\n status: 'running',\n };\n\n try {\n // Resolve step execution order\n const executionOrder = this.resolveExecutionOrder(workflow);\n logger.debug(`Workflow ${workflow.id} execution order: ${executionOrder.join(' -> ')}`);\n\n // Execute steps in order\n const stepResults = new Map<string, ReviewSummary>();\n const stepSummaries: Array<{\n stepId: string;\n status: 'success' | 'failed' | 'skipped';\n issues?: any[];\n output?: unknown;\n }> = [];\n\n for (const stepId of executionOrder) {\n const step = workflow.steps[stepId];\n\n // Check if step should be executed (evaluate 'if' condition)\n if (step.if) {\n const shouldRun = this.evaluateCondition(step.if, {\n inputs: executionContext.inputs,\n outputs: Object.fromEntries(stepResults),\n pr: runOptions.prInfo,\n });\n\n if (!shouldRun) {\n logger.info(`Skipping step '${stepId}' due to condition: ${step.if}`);\n stepSummaries.push({\n stepId,\n status: 'skipped',\n });\n continue;\n }\n }\n\n // Prepare step configuration\n const stepConfig = await this.prepareStepConfig(\n step,\n stepId,\n executionContext,\n stepResults,\n workflow\n );\n\n // Execute the step\n try {\n logger.info(`Executing workflow step '${stepId}'`);\n // Extend context with workflow inputs\n const stepContext: ExecutionContext = {\n ...runOptions.context,\n workflowInputs: executionContext.inputs,\n };\n const result = await this.executeStep(\n stepConfig,\n runOptions.prInfo,\n stepResults,\n stepContext\n );\n\n stepResults.set(stepId, result);\n stepSummaries.push({\n stepId,\n status: 'success',\n issues: result.issues,\n output: (result as any).output,\n });\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n logger.error(`Step '${stepId}' failed: ${errorMessage}`);\n\n stepSummaries.push({\n stepId,\n status: 'failed',\n output: { error: errorMessage },\n });\n\n if (!runOptions.options?.continueOnError) {\n throw new Error(`Workflow step '${stepId}' failed: ${errorMessage}`);\n }\n }\n }\n\n // Compute workflow outputs\n const outputs = await this.computeOutputs(\n workflow,\n executionContext,\n stepResults,\n runOptions.prInfo\n );\n executionContext.outputs = outputs;\n\n // Aggregate results\n const aggregated = this.aggregateResults(stepResults);\n\n const endTime = Date.now();\n executionContext.metadata.endTime = endTime;\n executionContext.metadata.duration = endTime - startTime;\n executionContext.metadata.status = 'completed';\n\n return {\n success: true,\n score: aggregated.score,\n confidence: aggregated.confidence,\n issues: aggregated.issues,\n comments: aggregated.comments,\n output: outputs,\n status: 'completed',\n duration: endTime - startTime,\n stepSummaries,\n };\n } catch (error) {\n const endTime = Date.now();\n executionContext.metadata.endTime = endTime;\n executionContext.metadata.duration = endTime - startTime;\n executionContext.metadata.status = 'failed';\n executionContext.metadata.error = error instanceof Error ? error.message : String(error);\n\n return {\n success: false,\n status: 'failed',\n duration: endTime - startTime,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Resolve step execution order based on dependencies\n */\n private resolveExecutionOrder(workflow: WorkflowDefinition): string[] {\n // Build dependency map\n const dependencies: Record<string, string[]> = {};\n for (const [stepId, step] of Object.entries(workflow.steps)) {\n dependencies[stepId] = step.depends_on || [];\n }\n\n // Use static DependencyResolver\n const graph = DependencyResolver.buildDependencyGraph(dependencies);\n\n if (graph.hasCycles) {\n throw new Error(\n `Circular dependency detected in workflow steps: ${graph.cycleNodes?.join(' -> ')}`\n );\n }\n\n // Flatten execution groups to get linear order\n const order: string[] = [];\n for (const group of graph.executionOrder) {\n order.push(...group.parallel);\n }\n\n return order;\n }\n\n /**\n * Prepare step configuration with input mappings\n */\n private async prepareStepConfig(\n step: WorkflowStep,\n stepId: string,\n executionContext: WorkflowExecutionContext,\n stepResults: Map<string, ReviewSummary>,\n workflow: WorkflowDefinition\n ): Promise<CheckProviderConfig> {\n const config: CheckProviderConfig = {\n ...step,\n type: step.type || 'ai',\n checkName: `${executionContext.instanceId}:${stepId}`,\n };\n\n // Process input mappings\n if (step.inputs) {\n for (const [inputName, mapping] of Object.entries(step.inputs)) {\n const value = await this.resolveInputMapping(\n mapping,\n executionContext,\n stepResults,\n workflow\n );\n (config as any)[inputName] = value;\n }\n }\n\n return config;\n }\n\n /**\n * Resolve input mapping to actual value\n */\n private async resolveInputMapping(\n mapping: string | WorkflowInputMapping,\n executionContext: WorkflowExecutionContext,\n stepResults: Map<string, ReviewSummary>,\n _workflow: WorkflowDefinition\n ): Promise<unknown> {\n // Simple string mapping - treat as parameter reference\n if (typeof mapping === 'string') {\n return executionContext.inputs[mapping];\n }\n\n // Complex mapping\n if (typeof mapping === 'object' && mapping !== null && 'source' in mapping) {\n const typedMapping = mapping as WorkflowInputMapping;\n\n switch (typedMapping.source) {\n case 'param':\n // Reference to workflow input parameter\n return executionContext.inputs[String(typedMapping.value)];\n\n case 'step':\n // Reference to another step's output\n if (!typedMapping.stepId) {\n throw new Error('Step input mapping requires stepId');\n }\n const stepResult = stepResults.get(typedMapping.stepId);\n if (!stepResult) {\n throw new Error(`Step '${typedMapping.stepId}' has not been executed yet`);\n }\n const output = (stepResult as any).output;\n if (typedMapping.outputParam && output) {\n return output[typedMapping.outputParam];\n }\n return output;\n\n case 'constant':\n // Constant value\n return typedMapping.value;\n\n case 'expression':\n // JavaScript expression\n if (!typedMapping.expression) {\n throw new Error('Expression mapping requires expression field');\n }\n const sandbox = createSecureSandbox();\n return compileAndRun(\n sandbox,\n typedMapping.expression,\n {\n inputs: executionContext.inputs,\n outputs: Object.fromEntries(stepResults),\n steps: Object.fromEntries(\n Array.from(stepResults.entries()).map(([id, result]) => [\n id,\n (result as any).output,\n ])\n ),\n },\n { injectLog: true, logPrefix: 'workflow.input.expression' }\n );\n\n default:\n throw new Error(`Unknown input mapping source: ${typedMapping.source}`);\n }\n }\n\n // Handle Liquid template in mapping\n if (typeof mapping === 'object' && mapping !== null && 'template' in mapping) {\n const typedMapping = mapping as WorkflowInputMapping;\n if (typedMapping.template) {\n return await this.liquid.parseAndRender(typedMapping.template, {\n inputs: executionContext.inputs,\n outputs: Object.fromEntries(stepResults),\n });\n }\n }\n\n // Return as-is\n return mapping;\n }\n\n /**\n * Execute a single step\n */\n private async executeStep(\n config: CheckProviderConfig,\n prInfo: PRInfo,\n dependencyResults: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n const provider = await this.getProviderRegistry().getProvider(config.type);\n if (!provider) {\n throw new Error(`Provider '${config.type}' not found`);\n }\n\n return await provider.execute(prInfo, config, dependencyResults, context);\n }\n\n /**\n * Compute workflow outputs\n */\n private async computeOutputs(\n workflow: WorkflowDefinition,\n executionContext: WorkflowExecutionContext,\n stepResults: Map<string, ReviewSummary>,\n prInfo: PRInfo\n ): Promise<Record<string, unknown>> {\n const outputs: Record<string, unknown> = {};\n\n if (!workflow.outputs) {\n return outputs;\n }\n\n for (const output of workflow.outputs) {\n if (output.value_js) {\n // JavaScript expression\n const sandbox = createSecureSandbox();\n outputs[output.name] = compileAndRun(\n sandbox,\n output.value_js,\n {\n inputs: executionContext.inputs,\n steps: Object.fromEntries(\n Array.from(stepResults.entries()).map(([id, result]) => [id, (result as any).output])\n ),\n outputs: Object.fromEntries(stepResults),\n pr: prInfo,\n },\n { injectLog: true, logPrefix: `workflow.output.${output.name}` }\n );\n } else if (output.value) {\n // Liquid template\n outputs[output.name] = await this.liquid.parseAndRender(output.value, {\n inputs: executionContext.inputs,\n steps: Object.fromEntries(\n Array.from(stepResults.entries()).map(([id, result]) => [id, (result as any).output])\n ),\n outputs: Object.fromEntries(stepResults),\n pr: prInfo,\n });\n }\n }\n\n return outputs;\n }\n\n /**\n * Aggregate results from all steps\n */\n private aggregateResults(stepResults: Map<string, ReviewSummary>): {\n score: number;\n confidence: 'high' | 'medium' | 'low';\n issues: any[];\n comments: any[];\n } {\n let totalScore = 0;\n let scoreCount = 0;\n const allIssues: any[] = [];\n const allComments: any[] = [];\n let minConfidence: 'high' | 'medium' | 'low' = 'high';\n\n for (const result of stepResults.values()) {\n const extResult = result as any;\n if (typeof extResult.score === 'number') {\n totalScore += extResult.score;\n scoreCount++;\n }\n\n if (result.issues) {\n allIssues.push(...result.issues);\n }\n\n if (extResult.comments) {\n allComments.push(...extResult.comments);\n }\n\n if (extResult.confidence) {\n if (\n extResult.confidence === 'low' ||\n (extResult.confidence === 'medium' && minConfidence === 'high')\n ) {\n minConfidence = extResult.confidence;\n }\n }\n }\n\n return {\n score: scoreCount > 0 ? Math.round(totalScore / scoreCount) : 0,\n confidence: minConfidence,\n issues: allIssues,\n comments: allComments,\n };\n }\n\n /**\n * Evaluate a condition expression\n */\n private evaluateCondition(condition: string, context: any): boolean {\n try {\n const sandbox = createSecureSandbox();\n const result = compileAndRun(sandbox, condition, context, {\n injectLog: true,\n logPrefix: 'workflow.condition',\n });\n return Boolean(result);\n } catch (error) {\n logger.warn(`Failed to evaluate condition '${condition}': ${error}`);\n return false;\n }\n }\n}\n","/**\n * Workflow Projection - Convert WorkflowDefinition to DependencyGraph\n *\n * This module handles projecting workflow definitions into dependency graphs\n * that can be executed by the state machine engine.\n */\n\nimport type { WorkflowDefinition } from '../types/workflow';\nimport type { CheckMetadata } from '../types/engine';\nimport type { VisorConfig } from '../types/config';\nimport { logger } from '../logger';\n\n/**\n * Project a workflow definition into a dependency graph structure\n * that can be executed by the state machine\n */\nexport function projectWorkflowToGraph(\n workflow: WorkflowDefinition,\n workflowInputs: Record<string, unknown>,\n _parentCheckId: string\n): {\n config: VisorConfig;\n checks: Record<string, CheckMetadata>;\n} {\n if (!workflow.steps || Object.keys(workflow.steps).length === 0) {\n throw new Error(`Workflow '${workflow.id}' has no steps`);\n }\n\n // Build a pseudo-config that represents the workflow as checks\n const checks: Record<string, any> = {};\n const checksMetadata: Record<string, CheckMetadata> = {};\n\n for (const [stepId, step] of Object.entries(workflow.steps)) {\n // Inside a nested workflow engine instance, step IDs do not need parent scoping.\n // Keep them unscoped to provide a clean, black‑box view.\n const scopedCheckId = stepId;\n\n // Build check configuration from workflow step\n checks[scopedCheckId] = {\n type: step.type || 'ai',\n ...step,\n // Store workflow inputs in the check config so they're accessible\n workflowInputs,\n // Mark this as a workflow step\n _workflowStep: true,\n _workflowId: workflow.id,\n _stepId: stepId,\n };\n\n // Build check metadata\n checksMetadata[scopedCheckId] = {\n tags: step.tags || workflow.tags || [],\n triggers: step.on || workflow.on || [],\n group: step.group,\n providerType: step.type || 'ai',\n dependencies: (step.depends_on || []).map(dep => dep),\n };\n }\n\n // Create a synthetic config for this workflow\n const config: VisorConfig = {\n checks,\n version: '1.0',\n output: {\n pr_comment: {\n format: 'table',\n group_by: 'check',\n collapse: false,\n },\n },\n };\n\n if ((logger as any).isDebugEnabled?.()) {\n logger.debug(\n `[WorkflowProjection] Projected workflow '${workflow.id}' with ${Object.keys(checks).length} steps`\n );\n }\n\n return { config, checks: checksMetadata };\n}\n\n/**\n * Validate workflow depth to prevent infinite recursion\n */\nexport function validateWorkflowDepth(\n currentDepth: number,\n maxDepth: number,\n workflowId: string\n): void {\n if (currentDepth >= maxDepth) {\n throw new Error(\n `Workflow nesting depth limit exceeded (${maxDepth}) for workflow '${workflowId}'. ` +\n `This may indicate a circular workflow reference or excessive nesting.`\n );\n }\n}\n\n/**\n * Build a scoped path for workflow steps\n */\nexport function buildWorkflowScope(\n parentScope: Array<{ check: string; index: number }> | undefined,\n workflowCheckId: string,\n stepId: string,\n foreachIndex?: number\n): Array<{ check: string; index: number }> {\n const scope = parentScope ? [...parentScope] : [];\n scope.push({\n check: `${workflowCheckId}:${stepId}`,\n index: foreachIndex ?? 0,\n });\n return scope;\n}\n\n/**\n * Extract parent scope from a scoped check ID\n */\nexport function extractParentScope(\n scopedCheckId: string\n): { parentCheckId: string; stepId: string } | null {\n const lastColonIndex = scopedCheckId.lastIndexOf(':');\n if (lastColonIndex === -1) {\n return null; // Not a scoped check\n }\n\n return {\n parentCheckId: scopedCheckId.substring(0, lastColonIndex),\n stepId: scopedCheckId.substring(lastColonIndex + 1),\n };\n}\n\n/**\n * Check if a check ID represents a workflow step\n */\nexport function isWorkflowStep(checkId: string): boolean {\n return checkId.includes(':');\n}\n\n/**\n * Get the workflow ID from a scoped check ID\n */\nexport function getWorkflowIdFromScope(scopedCheckId: string): string | null {\n const parts = scopedCheckId.split(':');\n if (parts.length >= 2) {\n return parts[0]; // First part is the parent workflow check ID\n }\n return null;\n}\n","/**\n * Workflow check provider - executes reusable workflows as checks\n */\n\nimport { CheckProvider, CheckProviderConfig, ExecutionContext } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { WorkflowRegistry } from '../workflow-registry';\nimport { WorkflowExecutor } from '../workflow-executor';\nimport { logger } from '../logger';\nimport { WorkflowDefinition, WorkflowExecutionContext } from '../types/workflow';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { Liquid } from 'liquidjs';\n\n/**\n * Provider that executes workflows as checks\n */\nexport class WorkflowCheckProvider extends CheckProvider {\n private registry: WorkflowRegistry;\n private executor: WorkflowExecutor;\n private liquid: Liquid;\n\n constructor() {\n super();\n this.registry = WorkflowRegistry.getInstance();\n this.executor = new WorkflowExecutor();\n this.liquid = new Liquid();\n }\n\n getName(): string {\n return 'workflow';\n }\n\n getDescription(): string {\n return 'Executes reusable workflow definitions as checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n const cfg = config as CheckProviderConfig & { workflow?: string; config?: string };\n\n // Two supported modes:\n // 1) workflow: <id> (pre-registered in WorkflowRegistry via imports)\n // 2) config: <path|url> (load a Visor config file and execute its steps as a workflow)\n if (!cfg.workflow && !cfg.config) {\n logger.error('Workflow provider requires either \"workflow\" (id) or \"config\" (path)');\n return false;\n }\n\n // If using workflow id, verify presence in registry now\n if (cfg.workflow) {\n if (!this.registry.has(cfg.workflow as string)) {\n logger.error(`Workflow '${cfg.workflow}' not found in registry`);\n return false;\n }\n }\n\n // For config path mode we cannot fully validate existence here (no base path);\n // execution will resolve it relative to the parent working directory and fail fast if missing.\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n const cfg = config as CheckProviderConfig & { workflow?: string; config?: string };\n const isConfigPathMode = !!cfg.config && !cfg.workflow;\n\n // Test harness support: allow mocking workflow checks as a black box.\n // If a mock is provided for this step, short-circuit nested execution and\n // return a ReviewSummary with optional output field.\n try {\n const stepName = (config as any).checkName || cfg.workflow || cfg.config || 'workflow';\n // test-runner passes hooks on execution context\n const mock = (context as any)?.hooks?.mockForStep?.(String(stepName));\n if (mock !== undefined) {\n const ms = mock as any;\n const issuesArr = Array.isArray(ms?.issues) ? (ms.issues as any[]) : [];\n // Prefer explicit output if provided; otherwise treat the mock object itself as output\n const out = ms && typeof ms === 'object' && 'output' in ms ? ms.output : ms;\n const summary: ReviewSummary & { output?: unknown } = {\n issues: issuesArr,\n output: out,\n ...(typeof ms?.content === 'string' ? { content: String(ms.content) } : {}),\n } as any;\n return summary;\n }\n } catch {}\n\n // Resolve workflow definition\n let workflow: WorkflowDefinition | undefined;\n let workflowId = cfg.workflow as string | undefined;\n\n if (isConfigPathMode) {\n const parentCwd = ((context as any)?._parentContext?.workingDirectory ||\n (context as any)?.workingDirectory ||\n process.cwd()) as string;\n workflow = await this.loadWorkflowFromConfigPath(String(cfg.config), parentCwd);\n workflowId = workflow.id;\n logger.info(`Executing workflow from config '${cfg.config}' as '${workflowId}'`);\n } else {\n workflowId = String(cfg.workflow);\n workflow = this.registry.get(workflowId);\n if (!workflow) {\n throw new Error(`Workflow '${workflowId}' not found in registry`);\n }\n logger.info(`Executing workflow '${workflowId}'`);\n }\n\n // Prepare inputs\n const inputs = await this.prepareInputs(workflow, config, prInfo, dependencyResults);\n\n // Validate inputs\n const validation = this.registry.validateInputs(workflow, inputs);\n if (!validation.valid) {\n const errors = validation.errors?.map(e => `${e.path}: ${e.message}`).join(', ');\n throw new Error(`Invalid workflow inputs: ${errors}`);\n }\n\n // Apply overrides to workflow steps if specified\n const modifiedWorkflow = this.applyOverrides(workflow, config);\n\n // M3: Check if we're in state-machine mode and should delegate to engine\n const engineMode = (context as any)?._engineMode;\n if (engineMode === 'state-machine') {\n // Delegate to state machine engine for nested workflow execution\n logger.info(`[WorkflowProvider] Delegating workflow '${workflowId}' to state machine engine`);\n return await this.executeViaStateMachine(\n modifiedWorkflow,\n inputs,\n config,\n prInfo,\n dependencyResults,\n context\n );\n }\n\n // Legacy mode: Execute the workflow using WorkflowExecutor\n const executionContext: WorkflowExecutionContext = {\n instanceId: `${workflowId}-${Date.now()}`,\n parentCheckId: config.checkName,\n inputs,\n stepResults: new Map(),\n };\n\n const result = await this.executor.execute(modifiedWorkflow, executionContext, {\n prInfo,\n dependencyResults,\n context,\n });\n\n // Map outputs\n const outputs = this.mapOutputs(result, config.output_mapping as Record<string, string>);\n\n // Return the review summary with extended fields\n // Note: These extra fields are used by the execution engine but not part of the base interface\n const summary: ReviewSummary = {\n issues: result.issues || [],\n };\n\n // Add extended fields as needed by the engine\n (summary as any).score = result.score || 0;\n (summary as any).confidence = result.confidence || 'medium';\n (summary as any).comments = result.comments || [];\n (summary as any).output = outputs;\n (summary as any).content = this.formatWorkflowResult(workflow, result, outputs);\n\n return summary;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'workflow',\n 'config',\n 'args',\n 'overrides',\n 'output_mapping',\n 'timeout',\n 'env',\n 'checkName',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n return true; // Always available\n }\n\n getRequirements(): string[] {\n return [];\n }\n\n /**\n * Prepare inputs for workflow execution\n */\n private async prepareInputs(\n workflow: WorkflowDefinition,\n config: CheckProviderConfig,\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<Record<string, unknown>> {\n const inputs: Record<string, unknown> = {};\n\n // Start with default values from workflow definition\n if (workflow.inputs) {\n for (const param of workflow.inputs) {\n if (param.default !== undefined) {\n inputs[param.name] = param.default;\n }\n }\n }\n\n // Apply user-provided inputs (args)\n const userInputs = config.args || config.workflow_inputs; // Support both for compatibility\n if (userInputs) {\n for (const [key, value] of Object.entries(userInputs)) {\n // Process value if it's a template or expression\n if (typeof value === 'string') {\n // Check if it's a Liquid template\n if (value.includes('{{') || value.includes('{%')) {\n inputs[key] = await this.liquid.parseAndRender(value, {\n pr: prInfo,\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n env: process.env,\n });\n } else {\n inputs[key] = value;\n }\n } else if (typeof value === 'object' && value !== null && 'expression' in value) {\n // JavaScript expression\n const exprValue = value as { expression: string };\n const sandbox = createSecureSandbox();\n inputs[key] = compileAndRun(\n sandbox,\n exprValue.expression,\n {\n pr: prInfo,\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n env: process.env,\n },\n { injectLog: true, logPrefix: `workflow.input.${key}` }\n );\n } else {\n inputs[key] = value;\n }\n }\n }\n\n return inputs;\n }\n\n /**\n * Apply overrides to workflow steps\n */\n private applyOverrides(\n workflow: WorkflowDefinition,\n config: CheckProviderConfig\n ): WorkflowDefinition {\n const overrideConfig = config.overrides || config.workflow_overrides; // Support both for compatibility\n if (!overrideConfig) {\n return workflow;\n }\n\n // Deep clone the workflow\n const modified = JSON.parse(JSON.stringify(workflow));\n\n // Apply overrides\n for (const [stepId, overrides] of Object.entries(overrideConfig)) {\n if (modified.steps[stepId]) {\n // Merge overrides with existing step config\n modified.steps[stepId] = {\n ...modified.steps[stepId],\n ...overrides,\n };\n } else {\n logger.warn(`Cannot override non-existent step '${stepId}' in workflow '${workflow.id}'`);\n }\n }\n\n return modified;\n }\n\n /**\n * Map workflow outputs to check outputs\n */\n private mapOutputs(result: any, outputMapping?: Record<string, string>): Record<string, unknown> {\n if (!outputMapping) {\n return result.output || {};\n }\n\n const mapped: Record<string, unknown> = {};\n const workflowOutputs = result.output || {};\n\n for (const [checkOutput, workflowOutput] of Object.entries(outputMapping)) {\n if (workflowOutput in workflowOutputs) {\n mapped[checkOutput] = workflowOutputs[workflowOutput];\n } else if (workflowOutput.includes('.')) {\n // Handle nested paths\n const parts = workflowOutput.split('.');\n let value = workflowOutputs;\n for (const part of parts) {\n value = value?.[part];\n if (value === undefined) break;\n }\n mapped[checkOutput] = value;\n }\n }\n\n return mapped;\n }\n\n /**\n * Format workflow execution result for display\n */\n /**\n * Execute workflow via state machine engine (M3: nested workflows)\n */\n private async executeViaStateMachine(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>,\n config: CheckProviderConfig,\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n // Import state machine components\n const {\n projectWorkflowToGraph,\n validateWorkflowDepth,\n } = require('../state-machine/workflow-projection');\n const { StateMachineRunner } = require('../state-machine/runner');\n const { ExecutionJournal } = require('../snapshot-store');\n const { MemoryStore } = require('../memory-store');\n const { v4: uuidv4 } = require('uuid');\n\n // Extract parent context if available\n const parentContext = (context as any)?._parentContext;\n const parentState = (context as any)?._parentState;\n\n // Validate workflow depth\n const currentDepth = parentState?.flags?.currentWorkflowDepth || 0;\n // Prefer parent state's configured limit; fall back to config.limits if present; else default 3\n const maxDepth =\n parentState?.flags?.maxWorkflowDepth ??\n parentContext?.config?.limits?.max_workflow_depth ??\n 3;\n validateWorkflowDepth(currentDepth, maxDepth, workflow.id);\n\n // Project workflow to dependency graph\n const { config: workflowConfig, checks: checksMetadata } = projectWorkflowToGraph(\n workflow,\n inputs,\n config.checkName || workflow.id\n );\n\n // Build isolated child engine context (separate journal/memory to avoid state contamination)\n // Reuse parent's memory config if available, but never the instance\n const parentMemoryCfg =\n (parentContext?.memory &&\n parentContext.memory.getConfig &&\n parentContext.memory.getConfig()) ||\n parentContext?.config?.memory;\n\n const childJournal = new ExecutionJournal();\n const childMemory = MemoryStore.createIsolated(parentMemoryCfg);\n try {\n await childMemory.initialize();\n } catch {}\n\n const childContext = {\n mode: 'state-machine' as const,\n config: workflowConfig,\n checks: checksMetadata,\n journal: childJournal,\n memory: childMemory,\n workingDirectory: parentContext?.workingDirectory || process.cwd(),\n // Always use a fresh session for nested workflows to isolate history\n sessionId: uuidv4(),\n event: parentContext?.event || prInfo.eventType,\n debug: parentContext?.debug || false,\n maxParallelism: parentContext?.maxParallelism,\n failFast: parentContext?.failFast,\n // Propagate execution hooks (mocks, octokit, etc.) into the child so\n // nested steps can be mocked/observed by the YAML test runner.\n executionContext: (parentContext as any)?.executionContext,\n // Ensure all workflow steps are considered requested to avoid tag/event filtering surprises\n requestedChecks: Object.keys(checksMetadata),\n };\n\n // Create child runner with inherited context\n const runner = new StateMachineRunner(childContext);\n const childState = runner.getState();\n\n // Set workflow depth for child\n childState.flags.currentWorkflowDepth = currentDepth + 1;\n childState.flags.maxWorkflowDepth = maxDepth;\n\n // Set parent references\n childState.parentContext = parentContext;\n childState.parentScope = parentState?.parentScope;\n\n // Execute the child workflow\n logger.info(\n `[WorkflowProvider] Executing nested workflow '${workflow.id}' at depth ${currentDepth + 1}`\n );\n const result = await runner.run();\n\n // M3: Check for bubbled events and propagate them to parent\n const bubbledEvents = (childContext as any)._bubbledEvents || [];\n if (bubbledEvents.length > 0 && parentContext) {\n if (parentContext.debug) {\n logger.info(`[WorkflowProvider] Bubbling ${bubbledEvents.length} events to parent context`);\n }\n\n // Propagate bubbled events to parent\n if (!parentContext._bubbledEvents) {\n (parentContext as any)._bubbledEvents = [];\n }\n (parentContext as any)._bubbledEvents.push(...bubbledEvents);\n }\n\n // Aggregate results from all workflow steps\n const allIssues: any[] = [];\n let totalScore = 0;\n let scoreCount = 0;\n\n for (const stepResult of Object.values(result.results)) {\n const typedResult = stepResult as any;\n if (typedResult.issues) {\n allIssues.push(...typedResult.issues);\n }\n if (typedResult.score) {\n totalScore += typedResult.score;\n scoreCount++;\n }\n }\n\n // Compute workflow outputs\n const outputs = await this.computeWorkflowOutputsFromState(\n workflow,\n inputs,\n result.results,\n prInfo\n );\n\n // Map outputs if output_mapping is specified\n const mappedOutputs = this.mapOutputs(\n { output: outputs },\n config.output_mapping as Record<string, string>\n );\n\n // Build aggregated summary\n const summary: ReviewSummary = {\n issues: allIssues,\n };\n\n (summary as any).score = scoreCount > 0 ? Math.round(totalScore / scoreCount) : 0;\n (summary as any).confidence = 'medium';\n (summary as any).output = mappedOutputs;\n (summary as any).content = this.formatWorkflowResultFromStateMachine(\n workflow,\n result,\n mappedOutputs\n );\n\n return summary;\n }\n\n /**\n * Compute workflow outputs from state machine execution results\n */\n private async computeWorkflowOutputsFromState(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>,\n groupedResults: Record<string, Array<{ checkName: string; output?: unknown; issues?: any[] }>>,\n prInfo: PRInfo\n ): Promise<Record<string, unknown>> {\n const outputs: Record<string, unknown> = {};\n\n if (!workflow.outputs) {\n return outputs;\n }\n\n const sandbox = createSecureSandbox();\n\n // Flatten GroupedCheckResults (group -> CheckResult[]) to a simple map\n // of checkName -> { output, issues } so workflow-level value_js can\n // reference outputs[\"security\"].issues, etc.\n const flat: Record<string, { output?: unknown; issues?: any[] }> = {};\n try {\n for (const arr of Object.values(groupedResults || {})) {\n for (const item of arr || []) {\n if (!item) continue;\n const name = (item as any).checkName || (item as any).name;\n if (typeof name === 'string' && name) {\n flat[name] = { output: (item as any).output, issues: (item as any).issues };\n }\n }\n }\n } catch {}\n\n for (const output of workflow.outputs) {\n if (output.value_js) {\n // JavaScript expression\n outputs[output.name] = compileAndRun(\n sandbox,\n output.value_js,\n {\n inputs,\n steps: Object.fromEntries(\n Object.entries(flat).map(([id, result]) => [id, (result as any).output])\n ),\n outputs: flat,\n pr: prInfo,\n },\n { injectLog: true, logPrefix: `workflow.output.${output.name}` }\n );\n } else if (output.value) {\n // Liquid template\n outputs[output.name] = await this.liquid.parseAndRender(output.value, {\n inputs,\n steps: Object.fromEntries(\n Object.entries(flat).map(([id, result]) => [id, (result as any).output])\n ),\n outputs: flat,\n pr: prInfo,\n });\n }\n }\n\n return outputs;\n }\n\n /**\n * Format workflow result from state machine execution\n */\n private formatWorkflowResultFromStateMachine(\n workflow: WorkflowDefinition,\n result: any,\n outputs: Record<string, unknown>\n ): string {\n const lines: string[] = [];\n\n lines.push(`Workflow: ${workflow.name}`);\n if (workflow.description) {\n lines.push(`Description: ${workflow.description}`);\n }\n\n lines.push('');\n lines.push('Execution Summary (State Machine):');\n lines.push(`- Total Steps: ${Object.keys(result.results || {}).length}`);\n lines.push(`- Duration: ${result.statistics?.totalDuration || 0}ms`);\n\n if (Object.keys(outputs).length > 0) {\n lines.push('');\n lines.push('Outputs:');\n for (const [key, value] of Object.entries(outputs)) {\n const formatted =\n typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value);\n lines.push(`- ${key}: ${formatted}`);\n }\n }\n\n return lines.join('\\n');\n }\n\n private formatWorkflowResult(\n workflow: WorkflowDefinition,\n result: any,\n outputs: Record<string, unknown>\n ): string {\n const lines: string[] = [];\n\n lines.push(`Workflow: ${workflow.name}`);\n if (workflow.description) {\n lines.push(`Description: ${workflow.description}`);\n }\n\n lines.push('');\n lines.push('Execution Summary:');\n lines.push(`- Status: ${result.status || 'completed'}`);\n lines.push(`- Score: ${result.score || 0}`);\n lines.push(`- Issues Found: ${result.issues?.length || 0}`);\n\n if (result.duration) {\n lines.push(`- Duration: ${result.duration}ms`);\n }\n\n if (Object.keys(outputs).length > 0) {\n lines.push('');\n lines.push('Outputs:');\n for (const [key, value] of Object.entries(outputs)) {\n const formatted =\n typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value);\n lines.push(`- ${key}: ${formatted}`);\n }\n }\n\n if (result.stepSummaries && result.stepSummaries.length > 0) {\n lines.push('');\n lines.push('Step Results:');\n for (const summary of result.stepSummaries) {\n lines.push(\n `- ${summary.stepId}: ${summary.status} (${summary.issues?.length || 0} issues)`\n );\n }\n }\n\n return lines.join('\\n');\n }\n\n /**\n * Load a Visor config file (with steps/checks) and wrap it as a WorkflowDefinition\n * so it can be executed by the state machine as a nested workflow.\n */\n private async loadWorkflowFromConfigPath(\n sourcePath: string,\n baseDir: string\n ): Promise<WorkflowDefinition> {\n const path = require('node:path');\n const fs = require('node:fs');\n const resolved = path.isAbsolute(sourcePath) ? sourcePath : path.resolve(baseDir, sourcePath);\n if (!fs.existsSync(resolved)) {\n throw new Error(`Workflow config not found at: ${resolved}`);\n }\n\n const { ConfigManager } = require('../config');\n const mgr = new ConfigManager();\n // Load as-is without merging bundled defaults; keep child config pure\n const loaded = await mgr.loadConfig(resolved, { validate: false, mergeDefaults: false });\n\n const steps: Record<string, any> = (loaded as any).steps || (loaded as any).checks || {};\n if (!steps || Object.keys(steps).length === 0) {\n throw new Error(`Config '${resolved}' does not contain any steps to execute as a workflow`);\n }\n\n const id = path.basename(resolved).replace(/\\.(ya?ml)$/i, '');\n const name = (loaded as any).name || `Workflow from ${path.basename(resolved)}`;\n\n const workflowDef: WorkflowDefinition = {\n id,\n name,\n version: (loaded as any).version || '1.0',\n steps,\n description: (loaded as any).description,\n // Inherit optional triggers if present (not required)\n on: (loaded as any).on,\n // Carry over optional inputs/outputs if present so callers can consume them\n inputs: (loaded as any).inputs,\n outputs: (loaded as any).outputs,\n } as WorkflowDefinition;\n\n return workflowDef;\n }\n}\n","import { CheckProvider } from './check-provider.interface';\nimport { AICheckProvider } from './ai-check-provider';\nimport { HttpCheckProvider } from './http-check-provider';\nimport { HttpInputProvider } from './http-input-provider';\nimport { HttpClientProvider } from './http-client-provider';\nimport { NoopCheckProvider } from './noop-check-provider';\nimport { LogCheckProvider } from './log-check-provider';\nimport { GitHubOpsProvider } from './github-ops-provider';\nimport { ClaudeCodeCheckProvider } from './claude-code-check-provider';\nimport { CommandCheckProvider } from './command-check-provider';\nimport { MemoryCheckProvider } from './memory-check-provider';\nimport { McpCheckProvider } from './mcp-check-provider';\nimport { HumanInputCheckProvider } from './human-input-check-provider';\nimport { ScriptCheckProvider } from './script-check-provider';\nimport { WorkflowCheckProvider } from './workflow-check-provider';\nimport { CustomToolDefinition } from '../types/config';\n\n/**\n * Registry for managing check providers\n */\nexport class CheckProviderRegistry {\n private providers: Map<string, CheckProvider> = new Map();\n private static instance: CheckProviderRegistry;\n private customTools?: Record<string, CustomToolDefinition>;\n\n private constructor() {\n // Register default providers\n this.registerDefaultProviders();\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): CheckProviderRegistry {\n if (!CheckProviderRegistry.instance) {\n CheckProviderRegistry.instance = new CheckProviderRegistry();\n }\n return CheckProviderRegistry.instance;\n }\n\n /**\n * Register default built-in providers\n */\n private registerDefaultProviders(): void {\n // Register all built-in providers\n this.register(new AICheckProvider());\n this.register(new CommandCheckProvider());\n this.register(new ScriptCheckProvider());\n this.register(new HttpCheckProvider());\n this.register(new HttpInputProvider());\n this.register(new HttpClientProvider());\n this.register(new NoopCheckProvider());\n this.register(new LogCheckProvider());\n this.register(new MemoryCheckProvider());\n this.register(new GitHubOpsProvider());\n this.register(new HumanInputCheckProvider());\n this.register(new WorkflowCheckProvider());\n\n // Try to register ClaudeCodeCheckProvider - it may fail if dependencies are missing\n try {\n this.register(new ClaudeCodeCheckProvider());\n } catch (error) {\n console.error(\n `Warning: Failed to register ClaudeCodeCheckProvider: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n\n // Try to register McpCheckProvider - it may fail if dependencies are missing\n try {\n const mcpProvider = new McpCheckProvider();\n // Set custom tools if available\n if (this.customTools) {\n mcpProvider.setCustomTools(this.customTools);\n }\n this.register(mcpProvider);\n } catch (error) {\n console.error(\n `Warning: Failed to register McpCheckProvider: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Register a check provider\n */\n register(provider: CheckProvider): void {\n const name = provider.getName();\n if (this.providers.has(name)) {\n throw new Error(`Provider '${name}' is already registered`);\n }\n this.providers.set(name, provider);\n // Only log provider registration in debug mode to avoid contaminating output\n if (process.env.VISOR_DEBUG === 'true') {\n console.error(`Registered check provider: ${name}`);\n }\n }\n\n /**\n * Unregister a check provider\n */\n unregister(name: string): void {\n if (!this.providers.has(name)) {\n throw new Error(`Provider '${name}' not found`);\n }\n this.providers.delete(name);\n // Send provider unregistration messages to stderr to avoid contaminating JSON output\n console.error(`Unregistered check provider: ${name}`);\n }\n\n /**\n * Get a provider by name\n */\n getProvider(name: string): CheckProvider | undefined {\n return this.providers.get(name);\n }\n\n /**\n * Get provider or throw if not found\n */\n getProviderOrThrow(name: string): CheckProvider {\n const provider = this.providers.get(name);\n if (!provider) {\n throw new Error(\n `Check provider '${name}' not found. Available providers: ${this.getAvailableProviders().join(', ')}`\n );\n }\n return provider;\n }\n\n /**\n * Check if a provider exists\n */\n hasProvider(name: string): boolean {\n return this.providers.has(name);\n }\n\n /**\n * Get all registered provider names\n */\n getAvailableProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get all providers\n */\n getAllProviders(): CheckProvider[] {\n return Array.from(this.providers.values());\n }\n\n /**\n * Set custom tools that can be used by the MCP provider\n */\n setCustomTools(tools: Record<string, CustomToolDefinition>): void {\n this.customTools = tools;\n\n // Update MCP provider if already registered\n const mcpProvider = this.providers.get('mcp') as McpCheckProvider | undefined;\n if (mcpProvider) {\n mcpProvider.setCustomTools(tools);\n }\n }\n\n /**\n * Get providers that are currently available (have required dependencies)\n */\n async getActiveProviders(): Promise<CheckProvider[]> {\n const providers = this.getAllProviders();\n const activeProviders: CheckProvider[] = [];\n\n for (const provider of providers) {\n if (await provider.isAvailable()) {\n activeProviders.push(provider);\n }\n }\n\n return activeProviders;\n }\n\n /**\n * List provider information\n */\n async listProviders(): Promise<\n Array<{\n name: string;\n description: string;\n available: boolean;\n requirements: string[];\n }>\n > {\n const providers = this.getAllProviders();\n const info = [];\n\n for (const provider of providers) {\n info.push({\n name: provider.getName(),\n description: provider.getDescription(),\n available: await provider.isAvailable(),\n requirements: provider.getRequirements(),\n });\n }\n\n return info;\n }\n\n /**\n * Reset registry (mainly for testing)\n */\n reset(): void {\n this.providers.clear();\n this.registerDefaultProviders();\n }\n\n /**\n * Clear singleton instance (for testing)\n */\n static clearInstance(): void {\n CheckProviderRegistry.instance = undefined!;\n }\n}\n","/**\n * LevelDispatch State Handler\n *\n * Responsibilities:\n * - Pop next topological level from queue\n * - Spawn tasks up to maxParallelism\n * - Handle session reuse barriers\n * - Support fail-fast\n * - Support debug pause\n * - Execute actual provider logic\n * - Transition back to WavePlanning or handle errors\n *\n * M2: Integrates actual provider execution and routing\n */\n\nimport type {\n EngineContext,\n RunState,\n EngineState,\n EngineEvent,\n DispatchRecord,\n} from '../../types/engine';\nimport { logger } from '../../logger';\nimport type { ReviewSummary, ReviewIssue } from '../../reviewer';\nimport type { CheckExecutionStats } from '../../types/execution';\nimport type { CheckProviderConfig } from '../../providers/check-provider.interface';\nimport type { CheckConfig } from '../../types/config';\nimport { handleRouting, checkLoopBudget } from './routing';\nimport { withActiveSpan } from '../../telemetry/trace-helpers';\nimport { emitMermaidFromMarkdown } from '../../utils/mermaid-telemetry';\nimport { emitNdjsonSpanWithEvents, emitNdjsonFallback } from '../../telemetry/fallback-ndjson';\nimport { FailureConditionEvaluator } from '../../failure-condition-evaluator';\n\n/**\n * Map check name to focus for AI provider\n * This is a fallback when focus is not explicitly configured\n */\nfunction mapCheckNameToFocus(checkName: string): string {\n const focusMap: Record<string, string> = {\n security: 'security',\n performance: 'performance',\n style: 'style',\n architecture: 'architecture',\n };\n\n return focusMap[checkName] || 'all';\n}\n\n/**\n * Build output history Map from journal for template rendering\n * This matches the format expected by AI providers\n */\nfunction buildOutputHistoryFromJournal(context: EngineContext): Map<string, unknown[]> {\n const outputHistory = new Map<string, unknown[]>();\n\n try {\n const snapshot = context.journal.beginSnapshot();\n const allEntries = context.journal.readVisible(context.sessionId, snapshot, undefined);\n\n // Group by checkId and extract outputs\n for (const entry of allEntries) {\n const checkId = entry.checkId;\n if (!outputHistory.has(checkId)) {\n outputHistory.set(checkId, []);\n }\n // Prefer explicit output; otherwise use the full result (for schemas like\n // code-review where issues are returned directly). This ensures\n // outputs_history['security'].last.issues[...] works in prompts and tests.\n const payload =\n entry.result.output !== undefined ? entry.result.output : (entry.result as unknown);\n if (payload !== undefined) outputHistory.get(checkId)!.push(payload);\n }\n } catch (error) {\n // Silently fail - return empty map\n logger.debug(`[LevelDispatch] Error building output history: ${error}`);\n }\n\n return outputHistory;\n}\n\n/**\n * Evaluate 'if' condition for a check\n *\n * Note: For routing loops to work correctly, 'outputs' should only include\n * results from the CURRENT wave, not from previous waves. This allows\n * checks to re-execute after routing (goto/on_fail/on_success) triggers.\n */\nasync function evaluateIfCondition(\n checkId: string,\n checkConfig: CheckConfig,\n context: EngineContext,\n state: RunState\n): Promise<boolean> {\n const ifExpression = checkConfig.if;\n if (!ifExpression) {\n return true; // No condition means always run\n }\n\n try {\n const evaluator = new FailureConditionEvaluator();\n\n // Build previous results for condition evaluation\n // Default: include only results from the CURRENT wave. This prevents\n // stale data from causing routing loops in normal execution.\n const previousResults = new Map<string, ReviewSummary>();\n\n const currentWaveCompletions = (state as any).currentWaveCompletions as Set<string> | undefined;\n const useGlobalOutputsFlag = !!((state as any).flags && (state as any).flags.forwardRunActive);\n const waveKind = ((state as any).flags && (state as any).flags.waveKind) || undefined;\n // Heuristic: only allow global outputs for guards on checks that actually\n // have dependencies. Checks without deps (e.g., top-level prompts like\n // 'ask') should continue to see an empty outputs set so they can re-run\n // during forward-run waves triggered by goto/on_fail.\n const hasDeps = (() => {\n try {\n const deps = (checkConfig as any)?.depends_on;\n if (!deps) return false;\n if (Array.isArray(deps)) return deps.length > 0;\n return typeof deps === 'string' ? deps.trim().length > 0 : false;\n } catch {\n return false;\n }\n })();\n // In forward-run waves (from on_success/on_fail goto), guards should see the\n // latest global outputs even if the check has no explicit dependencies.\n // In wave-retry (from on_finish), restrict to checks with dependencies to\n // avoid wrongly skipping top-level prompts like 'ask'.\n const useGlobalOutputs =\n (useGlobalOutputsFlag && waveKind === 'forward') || (useGlobalOutputsFlag && hasDeps);\n\n if (useGlobalOutputs) {\n // Forward-run wave: allow guards to consult latest outputs from the entire\n // journal so follow-up steps (e.g., post-verified after run-review) can\n // see the outputs produced in the prior wave that scheduled this forward-run.\n try {\n const snapshotId = context.journal.beginSnapshot();\n const ContextView = require('../../snapshot-store').ContextView;\n const contextView = new ContextView(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n for (const key of Object.keys(context.checks || {})) {\n const jr = contextView.get(key);\n if (jr) previousResults.set(key, jr as ReviewSummary);\n }\n } catch {\n // Fallback to current-wave only if any error occurs\n }\n } else if (currentWaveCompletions) {\n // Current-wave-only results\n for (const key of currentWaveCompletions) {\n try {\n const snapshotId = context.journal.beginSnapshot();\n const ContextView = require('../../snapshot-store').ContextView;\n const contextView = new ContextView(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const journalResult = contextView.get(key);\n if (journalResult) {\n previousResults.set(key, journalResult as ReviewSummary);\n }\n } catch {\n // Silently skip - will use empty result\n }\n }\n }\n // Fallback: if no wave tracking, use empty outputs (allows all checks to run)\n\n // Build context data for if condition evaluation\n // Create a snapshot of process.env to ensure current values are captured\n // This is critical for test stages that set environment variables dynamically\n const envSnapshot: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined) {\n envSnapshot[key] = value;\n }\n }\n\n // Merge config.env into environment (config.env takes precedence)\n if (context.config.env) {\n for (const [key, value] of Object.entries(context.config.env)) {\n if (value !== undefined && value !== null) {\n envSnapshot[key] = String(value);\n }\n }\n }\n\n const contextData = {\n previousResults,\n event: context.event || 'manual',\n branch: (context.prInfo as any)?.branch,\n baseBranch: (context.prInfo as any)?.baseBranch,\n filesChanged: context.prInfo?.files?.map(f => f.filename),\n environment: envSnapshot,\n };\n\n const shouldRun = await evaluator.evaluateIfCondition(checkId, ifExpression, contextData);\n return shouldRun;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`Failed to evaluate if expression for check '${checkId}': ${msg}`);\n // Fail-secure: if condition evaluation fails, skip execution\n return false;\n }\n}\n\nexport async function handleLevelDispatch(\n context: EngineContext,\n state: RunState,\n transition: (newState: EngineState) => void,\n emitEvent: (event: EngineEvent) => void\n): Promise<void> {\n // Pop next level from queue\n const level = state.levelQueue.shift();\n\n if (!level) {\n // No more levels - go back to wave planning\n if (context.debug) {\n logger.info('[LevelDispatch] No more levels in queue');\n }\n transition('WavePlanning');\n return;\n }\n\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Executing level ${level.level} with ${level.parallel.length} checks`\n );\n }\n\n // Update current level tracking\n state.currentLevel = level.level;\n state.currentLevelChecks = new Set(level.parallel);\n\n // Emit level ready event\n emitEvent({ type: 'LevelReady', level, wave: state.wave });\n\n const maxParallelism = context.maxParallelism || 10;\n const results: Array<{ checkId: string; result: ReviewSummary; error?: Error }> = [];\n\n // Group checks by session provider to enforce session reuse barriers\n const sessionGroups = groupBySession(level.parallel, context);\n\n // Execute each session group sequentially, but checks within group in parallel\n for (const group of sessionGroups) {\n const groupResults = await executeCheckGroup(\n group,\n context,\n state,\n maxParallelism,\n emitEvent,\n transition\n );\n results.push(...groupResults);\n\n // Check fail-fast\n if (context.failFast && shouldFailFast(results)) {\n logger.warn('[LevelDispatch] Fail-fast triggered');\n state.flags.failFastTriggered = true;\n break;\n }\n }\n\n // Emit level depleted event\n emitEvent({ type: 'LevelDepleted', level: level.level, wave: state.wave });\n\n // Update stats - exclude only aggregated forEach results and explicit skip stubs\n // Previously skipped checks that now execute must be included so updateStats can\n // clear the skipped flag and count this run.\n const nonForEachResults = results.filter(r => {\n if ((r.result as any).isForEach) return false;\n if ((r.result as any).__skipped) return false;\n return true;\n });\n updateStats(nonForEachResults, state);\n\n // Check if fail-fast was triggered\n if (state.flags.failFastTriggered) {\n // Skip remaining levels\n state.levelQueue = [];\n if (context.debug) {\n logger.info('[LevelDispatch] Fail-fast triggered, clearing level queue');\n }\n }\n\n // Clear current level tracking\n state.currentLevelChecks.clear();\n\n // Transition back to WavePlanning\n transition('WavePlanning');\n}\n\n/**\n * Group checks by session provider to enforce sequential execution\n */\nfunction groupBySession(checks: string[], context: EngineContext): string[][] {\n // M2: Group checks that share a session provider\n const sessionProviderMap = new Map<string, string[]>();\n const noSessionChecks: string[] = [];\n\n for (const checkId of checks) {\n const metadata = context.checks[checkId];\n const sessionProvider = metadata?.sessionProvider;\n\n if (sessionProvider) {\n const group = sessionProviderMap.get(sessionProvider) || [];\n group.push(checkId);\n sessionProviderMap.set(sessionProvider, group);\n } else {\n noSessionChecks.push(checkId);\n }\n }\n\n // Return groups: first all session groups (sequential), then independent checks\n const groups: string[][] = [];\n\n // Add session groups (each group runs sequentially relative to other session groups)\n for (const group of sessionProviderMap.values()) {\n groups.push(group);\n }\n\n // Add independent checks as one group (can run in parallel)\n if (noSessionChecks.length > 0) {\n groups.push(noSessionChecks);\n }\n\n return groups;\n}\n\n/**\n * Execute a group of checks in parallel (up to maxParallelism)\n */\nasync function executeCheckGroup(\n checks: string[],\n context: EngineContext,\n state: RunState,\n maxParallelism: number,\n emitEvent: (event: EngineEvent) => void,\n transition: (newState: EngineState) => void\n): Promise<Array<{ checkId: string; result: ReviewSummary; error?: Error; duration?: number }>> {\n const results: Array<{\n checkId: string;\n result: ReviewSummary;\n error?: Error;\n duration?: number;\n }> = [];\n\n // Deduplicate checks within the same level to avoid double execution when\n // routing or OR-dependency expansion accidentally introduces duplicates.\n const seen = new Set<string>();\n const uniqueChecks: string[] = [];\n for (const id of checks) {\n if (!seen.has(id)) {\n seen.add(id);\n uniqueChecks.push(id);\n }\n }\n\n // Execute with limited parallelism\n const pool: Promise<void>[] = [];\n\n for (const checkId of uniqueChecks) {\n // If forward-run provided explicit per-item scopes, schedule one execution per scope\n const scopedRuns: Array<Array<{ check: string; index: number }>> =\n (state.pendingRunScopes && state.pendingRunScopes.get(checkId)) || [];\n // Guard: do not execute the same check more than once within a single wave\n try {\n const currentWaveCompletions = (state as any).currentWaveCompletions as\n | Set<string>\n | undefined;\n if (currentWaveCompletions && currentWaveCompletions.has(checkId)) {\n if (context.debug) {\n logger.info(`[LevelDispatch] Skipping ${checkId}: already completed in current wave`);\n }\n continue;\n }\n } catch {}\n\n // Wait if pool is full\n if (pool.length >= maxParallelism) {\n await Promise.race(pool);\n // Remove completed promises\n pool.splice(\n 0,\n pool.length,\n ...pool.filter(p => {\n const settled = (p as any)._settled;\n return !settled;\n })\n );\n }\n\n const runOnce = async (scopeOverride?: Array<{ check: string; index: number }>) => {\n const startTime = Date.now();\n try {\n const result = await executeSingleCheck(\n checkId,\n context,\n state,\n emitEvent,\n transition,\n scopeOverride\n );\n const duration = Date.now() - startTime;\n results.push({ checkId, result, duration });\n } catch (error) {\n const duration = Date.now() - startTime;\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error(`[LevelDispatch] Error executing check ${checkId}: ${err.message}`);\n results.push({ checkId, result: { issues: [] }, error: err, duration });\n }\n };\n\n // If we have explicit scopes, schedule one run per scope; otherwise run once (default scope)\n const promise = (async () => {\n if (scopedRuns.length > 0) {\n for (const sc of scopedRuns) {\n await runOnce(sc);\n }\n // Clear consumed scopes\n try {\n state.pendingRunScopes?.delete(checkId);\n } catch {}\n } else {\n await runOnce();\n }\n })();\n\n // Mark promise as settled when done\n promise\n .then(() => {\n (promise as any)._settled = true;\n })\n .catch(() => {\n (promise as any)._settled = true;\n });\n\n pool.push(promise);\n }\n\n // Wait for all remaining checks\n await Promise.all(pool);\n\n return results;\n}\n\n/**\n * Execute a check multiple times for forEach items\n */\nasync function executeCheckWithForEachItems(\n checkId: string,\n forEachParent: string,\n forEachItems: unknown[],\n context: EngineContext,\n state: RunState,\n emitEvent: (event: EngineEvent) => void,\n transition: (newState: EngineState) => void\n): Promise<ReviewSummary> {\n // Tactical correctness fix: re-read the parent's aggregated forEachItems\n // from a fresh journal snapshot to avoid stale items during goto/on_finish\n // retries. Prefer the shallowest (root-scope) entry via getRaw().\n try {\n const snapId = context.journal.beginSnapshot();\n // Read latest aggregated (root-scope) parent entry directly from journal.\n // ContextView.getRaw() returns the shallowest entry but not necessarily the latest;\n // here we explicitly pick the last committed root-scope entry for correctness.\n const visible = context.journal.readVisible(context.sessionId, snapId, context.event as any);\n let latestItems: unknown[] | undefined;\n for (let i = visible.length - 1; i >= 0; i--) {\n const e = visible[i];\n if (e.checkId === forEachParent && Array.isArray(e.scope) && e.scope.length === 0) {\n const r: any = e.result;\n if (r && Array.isArray(r.forEachItems)) {\n latestItems = r.forEachItems as unknown[];\n break;\n }\n }\n }\n if (Array.isArray(latestItems)) {\n if (context.debug) {\n try {\n const prevLen = Array.isArray(forEachItems) ? (forEachItems as any[]).length : 0;\n const newLen = latestItems.length;\n if (prevLen !== newLen) {\n logger.info(\n `[LevelDispatch] Refreshing forEachItems for ${checkId}: ` +\n `from parent '${forEachParent}' latestItems=${newLen} (was ${prevLen})`\n );\n }\n } catch {}\n }\n forEachItems = latestItems as unknown[];\n }\n } catch (e) {\n // Non-fatal: proceed with provided forEachItems\n if (context.debug) {\n logger.warn(\n `[LevelDispatch] Failed to refresh forEachItems from journal for ${forEachParent}: ${e}`\n );\n }\n }\n const checkConfig = context.config.checks?.[checkId];\n if (!checkConfig) {\n throw new Error(`Check configuration not found: ${checkId}`);\n }\n\n // DEBUG: Log forEach execution\n logger.info(\n `[LevelDispatch][DEBUG] executeCheckWithForEachItems: checkId=${checkId}, forEachParent=${forEachParent}, items=${forEachItems.length}`\n );\n logger.info(\n `[LevelDispatch][DEBUG] forEachItems: ${JSON.stringify(forEachItems).substring(0, 200)}`\n );\n\n const allIssues: ReviewIssue[] = [];\n const perItemResults: ReviewSummary[] = [];\n const allOutputs: unknown[] = [];\n const allContents: string[] = [];\n const perIterationDurations: number[] = [];\n\n // Execute check once per forEach item\n for (let itemIndex = 0; itemIndex < forEachItems.length; itemIndex++) {\n const iterationStartMs = Date.now();\n const scope: Array<{ check: string; index: number }> = [\n { check: forEachParent, index: itemIndex },\n ];\n\n const forEachItem = forEachItems[itemIndex];\n logger.info(\n `[LevelDispatch][DEBUG] Starting iteration ${itemIndex} of ${checkId}, parent=${forEachParent}, item=${JSON.stringify(forEachItem)?.substring(0, 100)}`\n );\n\n // Check if the forEach item indicates a failure\n // When a check fails (via fail_if or execution error), it may set a flag in the output\n // Skip this iteration if the parent iteration failed\n const shouldSkipDueToParentFailure =\n (forEachItem as any)?.__failed === true || (forEachItem as any)?.__skip === true;\n\n if (shouldSkipDueToParentFailure) {\n // Parent iteration failed - skip this iteration\n logger.info(\n `⏭ Skipped ${checkId} iteration ${itemIndex} (forEach parent \"${forEachParent}\" iteration ${itemIndex} marked as failed)`\n );\n\n // Track this as a skipped iteration in stats\n const iterationDurationMs = Date.now() - iterationStartMs;\n perIterationDurations.push(iterationDurationMs);\n\n // Add empty result to maintain array alignment\n perItemResults.push({ issues: [] });\n // Propagate an explicit skip marker so downstream dependents can also skip this branch\n allOutputs.push({ __skip: true });\n\n continue; // Skip to next iteration\n }\n\n // Emit visor.foreach.item span for telemetry\n try {\n emitNdjsonSpanWithEvents(\n 'visor.foreach.item',\n {\n 'visor.check.id': checkId,\n 'visor.foreach.index': itemIndex,\n 'visor.foreach.total': forEachItems.length,\n },\n []\n );\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to emit foreach.item span: ${error}`);\n }\n\n // Emit scheduled event\n emitEvent({ type: 'CheckScheduled', checkId, scope });\n\n // Create dispatch record\n const dispatch: DispatchRecord = {\n id: `${checkId}-${itemIndex}-${Date.now()}`,\n checkId,\n scope,\n provider: context.checks[checkId]?.providerType || 'unknown',\n startMs: Date.now(),\n attempts: 1,\n foreachIndex: itemIndex,\n };\n\n state.activeDispatches.set(`${checkId}-${itemIndex}`, dispatch);\n\n try {\n // Get provider\n const providerType = checkConfig.type || 'ai';\n const providerRegistry =\n require('../../providers/check-provider-registry').CheckProviderRegistry.getInstance();\n const provider = providerRegistry.getProviderOrThrow(providerType);\n\n // Build output history for template rendering\n const outputHistory = buildOutputHistoryFromJournal(context);\n\n // Build provider configuration\n const providerConfig: CheckProviderConfig = {\n type: providerType,\n checkName: checkId,\n prompt: checkConfig.prompt,\n exec: checkConfig.exec,\n schema: checkConfig.schema,\n group: checkConfig.group,\n focus: checkConfig.focus || mapCheckNameToFocus(checkId),\n transform: checkConfig.transform,\n transform_js: checkConfig.transform_js,\n env: checkConfig.env,\n forEach: checkConfig.forEach,\n ...checkConfig,\n eventContext: (context.prInfo as any)?.eventContext || {},\n __outputHistory: outputHistory,\n ai: {\n ...(checkConfig.ai || {}),\n timeout: checkConfig.ai?.timeout || 600000,\n debug: !!context.debug,\n },\n };\n\n // Propagate authenticated Octokit (v2 frontends / Action mode)\n try {\n const maybeOctokit = (context.executionContext as any)?.octokit;\n if (maybeOctokit) {\n (providerConfig as any).eventContext = {\n ...(providerConfig as any).eventContext,\n octokit: maybeOctokit,\n };\n }\n } catch {}\n\n // Build dependency results with scope\n const dependencyResults = buildDependencyResultsWithScope(\n checkId,\n checkConfig,\n context,\n scope\n );\n\n // Per-item dependency gating for map fanout: honor OR dependencies and continue_on_failure\n try {\n const rawDeps = (checkConfig as any)?.depends_on || [];\n const depList = Array.isArray(rawDeps) ? rawDeps : [rawDeps];\n if (depList.length > 0) {\n const groupSatisfied = (token: string): boolean => {\n if (typeof token !== 'string') return true;\n const orOptions = token.includes('|')\n ? token\n .split('|')\n .map(s => s.trim())\n .filter(Boolean)\n : [token];\n for (const opt of orOptions) {\n const dr = dependencyResults.get(opt) as ReviewSummary | undefined;\n const depCfg = context.config.checks?.[opt];\n const cont = !!(depCfg && (depCfg as any).continue_on_failure === true);\n let failed = false;\n let skipped = false;\n if (!dr) {\n failed = true; // missing result => not satisfied\n } else {\n const out: any = (dr as any).output;\n const fatal = hasFatalIssues(dr as any);\n failed = fatal || (!!out && typeof out === 'object' && out.__failed === true);\n skipped = !!(out && typeof out === 'object' && out.__skip === true);\n }\n const satisfied = !skipped && (!failed || cont);\n if (satisfied) return true; // any option satisfies the group\n }\n return false;\n };\n\n let allSatisfied = true;\n for (const token of depList) {\n if (!groupSatisfied(token as any)) {\n allSatisfied = false;\n break;\n }\n }\n\n if (!allSatisfied) {\n // Skip this iteration without executing provider; maintain per-item alignment\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Skipping ${checkId} iteration ${itemIndex} due to unsatisfied dependency group(s)`\n );\n }\n const iterationDurationMs = Date.now() - iterationStartMs;\n perIterationDurations.push(iterationDurationMs);\n perItemResults.push({ issues: [] });\n allOutputs.push({ __skip: true });\n // Do not call updateStats here: iteration did not execute\n continue;\n }\n }\n } catch {}\n\n // Build PR info (use real prInfo from context if available, otherwise use defaults)\n const prInfo: any = context.prInfo || {\n number: 1,\n title: 'State Machine Execution',\n author: 'system',\n eventType: context.event || 'manual',\n eventContext: {},\n files: [],\n commits: [],\n };\n\n // Build execution context\n const executionContext = {\n ...context.executionContext,\n _engineMode: context.mode,\n _parentContext: context,\n _parentState: state,\n };\n\n // Evaluate assume contract for this iteration (design-by-contract)\n try {\n const assumeExpr = (checkConfig as any)?.assume as string | string[] | undefined;\n if (assumeExpr) {\n const evaluator = new FailureConditionEvaluator();\n const exprs = Array.isArray(assumeExpr) ? assumeExpr : [assumeExpr];\n let ok = true;\n for (const ex of exprs) {\n const res = await evaluator.evaluateIfCondition(checkId, ex, {\n event: context.event || 'manual',\n previousResults: dependencyResults as any,\n } as any);\n if (!res) {\n ok = false;\n break;\n }\n }\n if (!ok) {\n logger.info(\n `⏭ Skipped (assume: ${String(Array.isArray(assumeExpr) ? assumeExpr[0] : assumeExpr).substring(0, 40)}${String(Array.isArray(assumeExpr) ? assumeExpr[0] : assumeExpr).length > 40 ? '...' : ''})`\n );\n const iterationDurationMs = Date.now() - iterationStartMs;\n perIterationDurations.push(iterationDurationMs);\n perItemResults.push({ issues: [] });\n allOutputs.push({ __skip: true });\n continue;\n }\n }\n } catch {}\n\n // Emit provider telemetry\n try {\n emitNdjsonFallback('visor.provider', {\n 'visor.check.id': checkId,\n 'visor.provider.type': providerType,\n });\n } catch {}\n\n // Execute provider with telemetry\n const itemResult = await withActiveSpan(\n `visor.check.${checkId}`,\n {\n 'visor.check.id': checkId,\n 'visor.check.type': providerType,\n 'visor.foreach.index': itemIndex,\n },\n async () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)\n );\n\n // Enrich issues\n const enrichedIssues = (itemResult.issues || []).map((issue: ReviewIssue) => ({\n ...issue,\n checkName: checkId,\n ruleId: `${checkId}/${issue.ruleId || 'unknown'}`,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n template: checkConfig.template,\n timestamp: Date.now(),\n }));\n\n // Track output BEFORE creating enrichedResult\n let output = (itemResult as any).output;\n let content = (itemResult as any).content;\n\n // Generate default content from issues if no content was provided\n if (!content && enrichedIssues.length > 0) {\n content = enrichedIssues\n .map(\n (i: ReviewIssue) =>\n `- **${i.severity.toUpperCase()}**: ${i.message} (${i.file}:${i.line})`\n )\n .join('\\n');\n }\n\n // Check if this iteration has fatal issues (execution failures)\n const iterationHasFatalIssues = enrichedIssues.some((issue: ReviewIssue) => {\n const ruleId = issue.ruleId || '';\n return (\n ruleId.endsWith('/error') || // System errors\n ruleId.includes('/execution_error') || // Command failures\n ruleId.endsWith('_fail_if') // fail_if triggered\n );\n });\n\n // If this iteration failed, mark the output so dependent forEach iterations can skip it\n if (\n iterationHasFatalIssues &&\n output !== undefined &&\n output !== null &&\n typeof output === 'object'\n ) {\n output = { ...output, __failed: true };\n } else if (iterationHasFatalIssues) {\n // If output is primitive or undefined, wrap it in an object with __failed flag\n output = { __value: output, __failed: true };\n }\n\n // DEBUG: Log output for this iteration\n logger.info(\n `[LevelDispatch][DEBUG] Iteration ${itemIndex}: output=${JSON.stringify(output)?.substring(0, 100)}, hasFatalIssues=${iterationHasFatalIssues}`\n );\n\n const enrichedResult: ReviewSummary = {\n ...itemResult,\n issues: enrichedIssues,\n ...(content ? { content } : {}),\n };\n\n // JSON Schema validation for per-item outputs when a schema is provided\n try {\n let schemaObj =\n (typeof checkConfig.schema === 'object' ? (checkConfig.schema as any) : undefined) ||\n (checkConfig as any).output_schema;\n // If schema is a known renderer string, attempt to load its JSON Schema\n if (!schemaObj && typeof (checkConfig as any).schema === 'string') {\n try {\n const { loadRendererSchema } = await import('../dispatch/renderer-schema');\n schemaObj = await loadRendererSchema((checkConfig as any).schema as string);\n } catch {}\n }\n const itemOutput = output;\n if (schemaObj && itemOutput !== undefined) {\n const Ajv = require('ajv');\n const ajv = new Ajv({ allErrors: true, allowUnionTypes: true, strict: false });\n const validate = ajv.compile(schemaObj);\n const valid = validate(itemOutput);\n if (!valid) {\n const errs = (validate.errors || [])\n .slice(0, 3)\n .map((e: any) => e.message)\n .join('; ');\n const issue: ReviewIssue = {\n file: 'contract',\n line: 0,\n ruleId: `contract/schema_validation_failed`,\n message: `Output schema validation failed${errs ? `: ${errs}` : ''}`,\n severity: 'error',\n category: 'logic',\n checkName: checkId,\n group: checkConfig.group,\n schema: 'json-schema',\n timestamp: Date.now(),\n } as any;\n enrichedResult.issues = [...(enrichedResult.issues || []), issue];\n if (Array.isArray(enrichedIssues)) {\n enrichedIssues.push(issue);\n }\n }\n }\n } catch {}\n\n // Evaluate guarantee contract (non-fatal): append error issues on violation\n try {\n const guaranteeExpr = (checkConfig as any)?.guarantee as string | string[] | undefined;\n if (guaranteeExpr) {\n const evaluator = new FailureConditionEvaluator();\n const exprs = Array.isArray(guaranteeExpr) ? guaranteeExpr : [guaranteeExpr];\n for (const ex of exprs) {\n const holds = await evaluator.evaluateIfCondition(checkId, ex, {\n previousResults: dependencyResults as any,\n event: context.event || 'manual',\n } as any);\n if (!holds) {\n const issue: ReviewIssue = {\n file: 'contract',\n line: 0,\n ruleId: `contract/guarantee_failed`,\n message: `Guarantee failed: ${ex}`,\n severity: 'error',\n category: 'logic',\n checkName: checkId,\n group: checkConfig.group,\n schema:\n typeof checkConfig.schema === 'object' ? 'custom' : (checkConfig.schema as any),\n timestamp: Date.now(),\n } as any;\n enrichedResult.issues = [...(enrichedResult.issues || []), issue];\n }\n }\n }\n } catch {}\n\n // Evaluate fail_if for this forEach iteration\n if (checkConfig.fail_if) {\n try {\n const evaluator = new FailureConditionEvaluator();\n // Build outputs map for fail_if evaluation (use dependency results as previous outputs)\n const failed = await evaluator.evaluateSimpleCondition(\n checkId,\n typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema || '',\n checkConfig.group || '',\n enrichedResult,\n checkConfig.fail_if,\n Object.fromEntries(dependencyResults.entries()) as Record<string, ReviewSummary>\n );\n\n if (failed) {\n logger.warn(\n `[LevelDispatch] fail_if triggered for ${checkId} iteration ${itemIndex}: ${checkConfig.fail_if}`\n );\n\n // Add fail_if issue to the result\n const failIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${checkId}/${checkId}_fail_if`,\n message: `Check failure condition met: ${checkConfig.fail_if}`,\n severity: 'error',\n category: 'logic',\n checkName: checkId,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n timestamp: Date.now(),\n };\n\n enrichedResult.issues = [...(enrichedResult.issues || []), failIssue];\n enrichedIssues.push(failIssue);\n allIssues.push(failIssue);\n\n // Re-check if iteration has fatal issues after adding fail_if issue\n const nowHasFatalIssues = enrichedResult.issues.some((issue: ReviewIssue) => {\n const ruleId = issue.ruleId || '';\n return (\n ruleId.endsWith('/error') ||\n ruleId.includes('/execution_error') ||\n ruleId.endsWith('_fail_if')\n );\n });\n\n // Update output with __failed flag if needed\n if (\n nowHasFatalIssues &&\n output !== undefined &&\n output !== null &&\n typeof output === 'object' &&\n !(output as any).__failed\n ) {\n output = { ...output, __failed: true };\n } else if (nowHasFatalIssues && !(output as any)?.__failed) {\n output = { __value: output, __failed: true };\n }\n }\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(\n `[LevelDispatch] Error evaluating fail_if for ${checkId} iteration ${itemIndex}: ${msg}`\n );\n }\n }\n\n // Store per-item result\n perItemResults.push(enrichedResult);\n allIssues.push(...enrichedIssues);\n allOutputs.push(output);\n\n // Track content\n if (typeof content === 'string' && content.trim()) {\n allContents.push(content.trim());\n }\n\n // Store in journal with scope - EXPLICITLY include output field\n try {\n const journalEntry = {\n sessionId: context.sessionId,\n checkId,\n result: { ...enrichedResult, output } as any,\n event: context.event || 'manual',\n scope,\n };\n // DEBUG: Log journal entry\n logger.info(\n `[LevelDispatch][DEBUG] Committing to journal: checkId=${checkId}, scope=${JSON.stringify(scope)}, hasOutput=${output !== undefined}`\n );\n context.journal.commitEntry(journalEntry);\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit to journal: ${error}`);\n }\n\n state.activeDispatches.delete(`${checkId}-${itemIndex}`);\n\n // Emit completed event\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope,\n result: {\n ...enrichedResult,\n output,\n },\n });\n\n // Track duration for this iteration\n const iterationDurationMs = Date.now() - iterationStartMs;\n perIterationDurations.push(iterationDurationMs);\n\n // Track statistics for this forEach iteration\n updateStats(\n [{ checkId, result: enrichedResult, duration: iterationDurationMs }],\n state,\n true\n );\n } catch (error) {\n // Track duration for failed iteration\n const iterationDurationMs = Date.now() - iterationStartMs;\n perIterationDurations.push(iterationDurationMs);\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error(\n `[LevelDispatch] Error executing check ${checkId} item ${itemIndex}: ${err.message}`\n );\n\n state.activeDispatches.delete(`${checkId}-${itemIndex}`);\n\n // Emit error event\n emitEvent({\n type: 'CheckErrored',\n checkId,\n scope,\n error: {\n message: err.message,\n stack: err.stack,\n name: err.name,\n },\n });\n\n // Add error to results\n const errorIssue: ReviewIssue = {\n file: '',\n line: 0,\n ruleId: `${checkId}/error`,\n message: err.message,\n severity: 'error',\n category: 'logic',\n };\n\n allIssues.push(errorIssue);\n perItemResults.push({ issues: [errorIssue] });\n\n // Track statistics for this failed forEach iteration\n updateStats(\n [{ checkId, result: { issues: [errorIssue] }, error: err, duration: iterationDurationMs }],\n state,\n true\n );\n }\n }\n\n // Mark as completed\n state.completedChecks.add(checkId);\n\n // Update forEach metadata in stats\n const checkStats = state.stats.get(checkId);\n if (checkStats) {\n checkStats.outputsProduced = allOutputs.length;\n checkStats.perIterationDuration = perIterationDurations;\n\n // Create preview of forEach items (first 3 + indicator for more)\n const previewItems = allOutputs.slice(0, 3).map(item => {\n const str = typeof item === 'string' ? item : (JSON.stringify(item) ?? 'undefined');\n return str.length > 50 ? str.substring(0, 50) + '...' : str;\n });\n\n if (allOutputs.length > 3) {\n checkStats.forEachPreview = [...previewItems, `...${allOutputs.length - 3} more`];\n } else {\n checkStats.forEachPreview = previewItems;\n }\n\n state.stats.set(checkId, checkStats);\n\n // Check if ALL iterations failed (complete failure)\n // If so, mark check as failed so dependents can be skipped\n if (checkStats.totalRuns > 0 && checkStats.failedRuns === checkStats.totalRuns) {\n logger.info(\n `[LevelDispatch] forEach check ${checkId} failed completely (${checkStats.failedRuns}/${checkStats.totalRuns} iterations failed)`\n );\n // Mark in state so dependents know this check failed\n if (!(state as any).failedChecks) {\n (state as any).failedChecks = new Set<string>();\n }\n (state as any).failedChecks.add(checkId);\n }\n }\n\n // Return aggregated result\n const aggregatedResult: any = {\n issues: allIssues,\n isForEach: true,\n forEachItems: allOutputs,\n forEachItemResults: perItemResults,\n // Include aggregated content from all iterations\n ...(allContents.length > 0 ? { content: allContents.join('\\n') } : {}),\n };\n\n // DEBUG: Log aggregated result\n logger.info(\n `[LevelDispatch][DEBUG] Aggregated result for ${checkId}: forEachItems.length=${allOutputs.length}, results=${perItemResults.length}`\n );\n logger.info(`[LevelDispatch][DEBUG] allOutputs: ${JSON.stringify(allOutputs).substring(0, 200)}`);\n\n // Store aggregated result in journal (without scope - this is the parent-level result)\n // Before storing, process routing for the aggregated child check so on_success/on_fail\n // can schedule follow-up actions (e.g., per-item remediation) based on forEach results.\n try {\n logger.info(`[LevelDispatch] Calling handleRouting for ${checkId}`);\n } catch {}\n try {\n // Mark completion prior to routing so guards see this as completed in the wave\n state.completedChecks.add(checkId);\n const currentWaveCompletions = (state as any).currentWaveCompletions as Set<string> | undefined;\n if (currentWaveCompletions) currentWaveCompletions.add(checkId);\n\n await handleRouting(context, state, transition, emitEvent, {\n checkId,\n scope: [],\n result: aggregatedResult as any,\n checkConfig: checkConfig as any,\n success: !hasFatalIssues(aggregatedResult as any),\n });\n } catch (error) {\n logger.warn(`[LevelDispatch] Routing error for aggregated forEach ${checkId}: ${error}`);\n }\n\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: aggregatedResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n logger.info(`[LevelDispatch][DEBUG] Committed aggregated result to journal with scope=[]`);\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit aggregated forEach result to journal: ${error}`);\n }\n\n // Note: We intentionally do not increment totals here for the aggregated\n // child invocation; per-iteration stats were recorded above via updateStats.\n // Each iteration was counted separately, so the totalRuns already reflects\n // the correct number of executions.\n\n // Emit completed event for aggregated result\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope: [],\n result: aggregatedResult,\n });\n\n const parentCheckConfig = context.config.checks?.[forEachParent];\n\n // Process on_finish for forEach PARENT after all forEach children complete\n // The forEach parent is the one that produced the forEachItems\n logger.info(\n `[LevelDispatch][DEBUG] Checking on_finish for forEach parent ${forEachParent}: has_on_finish=${!!parentCheckConfig?.on_finish}, is_forEach=${!!parentCheckConfig?.forEach}`\n );\n\n if (parentCheckConfig?.on_finish && parentCheckConfig.forEach) {\n logger.info(\n `[LevelDispatch] Processing on_finish for forEach parent ${forEachParent} after children complete`\n );\n\n // Get the parent check's result from journal\n try {\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const parentResult = contextView.get(forEachParent);\n\n if (parentResult) {\n logger.info(\n `[LevelDispatch] Found parent result for ${forEachParent}, evaluating on_finish`\n );\n\n // Evaluate on_finish routing (goto/goto_js) for the forEach parent\n const onFinish = parentCheckConfig.on_finish;\n\n // Process on_finish.run (if any). When we enqueue forward runs via\n // on_finish from within LevelDispatch (i.e., forEach parent path), we\n // must also request a WaveRetry so that checks whose execution depends\n // on updated memory/side-effects (but are not direct dependents of the\n // scheduled target) can re-evaluate their `if` conditions next wave.\n // This mirrors routing.ts behavior and is necessary for flows where an\n // aggregator sets flags consumed by later checks (e.g., posting steps).\n let queuedForward = false;\n logger.info(\n `[LevelDispatch] on_finish.run: ${onFinish.run?.length || 0} targets, targets=${JSON.stringify(onFinish.run || [])}`\n );\n if (onFinish.run && onFinish.run.length > 0) {\n for (const targetCheck of onFinish.run) {\n logger.info(`[LevelDispatch] Processing on_finish.run target: ${targetCheck}`);\n logger.info(\n `[LevelDispatch] Loop budget check: routingLoopCount=${state.routingLoopCount}, max_loops=${context.config.routing?.max_loops ?? 10}`\n );\n // Check loop budget before scheduling\n if (checkLoopBudget(context, state, 'on_finish', 'run')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${forEachParent}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_finish run`,\n severity: 'error',\n category: 'logic',\n };\n // Add error to parent result (not child aggregatedResult)\n parentResult.issues = [...(parentResult.issues || []), errorIssue];\n // Update parent result in journal with the error\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId: forEachParent,\n result: parentResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (err) {\n logger.warn(\n `[LevelDispatch] Failed to commit parent result with loop budget error: ${err}`\n );\n }\n return aggregatedResult; // ABORT\n }\n\n // Increment loop count\n state.routingLoopCount++;\n\n emitEvent({\n type: 'ForwardRunRequested',\n target: targetCheck,\n scope: [],\n origin: 'run',\n });\n queuedForward = true;\n }\n }\n\n // Declarative transitions override goto/goto_js when present.\n // Mirror routing.ts behavior for the forEach-parent on_finish path.\n try {\n const { evaluateTransitions } = await import('./routing');\n const transTarget = await evaluateTransitions(\n (onFinish as any).transitions,\n forEachParent,\n parentCheckConfig as any,\n parentResult as any,\n context,\n state\n );\n if (transTarget !== undefined) {\n if (transTarget) {\n // Loop budget guard\n if (checkLoopBudget(context, state, 'on_finish', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${forEachParent}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_finish transitions`,\n severity: 'error',\n category: 'logic',\n };\n parentResult.issues = [...(parentResult.issues || []), errorIssue];\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId: forEachParent,\n result: parentResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch {}\n return aggregatedResult; // abort further routing\n }\n state.routingLoopCount++;\n emitEvent({\n type: 'ForwardRunRequested',\n target: transTarget.to,\n scope: [],\n origin: 'goto_js',\n gotoEvent: (transTarget as any).goto_event,\n });\n queuedForward = true;\n }\n // Whether null (explicit no-op) or a target, transitions override goto/goto_js\n // Also request a WaveRetry if we queued something (handled below)\n if (queuedForward) {\n // no-op here; WaveRetry emitted after this block\n }\n return aggregatedResult;\n }\n } catch (e) {\n logger.error(\n `[LevelDispatch] Error evaluating on_finish transitions for ${forEachParent}: ${e instanceof Error ? e.message : String(e)}`\n );\n }\n\n // Evaluate goto_js and schedule routing if transitions did not match\n const { evaluateGoto } = await import('./routing');\n\n // Debug logging for forEach on_finish.goto_js evaluation\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Evaluating on_finish.goto_js for forEach parent: ${forEachParent}`\n );\n if (onFinish.goto_js) {\n logger.info(`[LevelDispatch] goto_js code: ${onFinish.goto_js.substring(0, 200)}`);\n }\n try {\n const snapshotId = context.journal.beginSnapshot();\n const all = context.journal.readVisible(context.sessionId, snapshotId, undefined);\n const keys = Array.from(new Set(all.map((e: any) => e.checkId)));\n logger.info(`[LevelDispatch] history keys: ${keys.join(', ')}`);\n } catch {}\n }\n\n const gotoTarget = await (evaluateGoto as any)(\n onFinish.goto_js,\n onFinish.goto,\n forEachParent,\n parentCheckConfig,\n parentResult,\n context,\n state\n );\n\n if (context.debug) {\n logger.info(`[LevelDispatch] goto_js evaluation result: ${gotoTarget || 'null'}`);\n }\n\n if (gotoTarget) {\n // If we also queued on_finish.run and the goto target is the same\n // forEach parent, defer this self-goto to avoid premature preemption\n // before reducers (on_finish.run) have updated shared state (e.g.,\n // memory). The goto will be scheduled AFTER the WaveRetry completes\n // and checks can re-evaluate their conditions.\n if (queuedForward && gotoTarget === forEachParent) {\n logger.info(\n `[LevelDispatch] on_finish.goto to self (${gotoTarget}) deferred, will process after WaveRetry`\n );\n // Still schedule the goto, but it will execute after aggregate completes\n // and WaveRetry processes. This ensures the goto happens AFTER memory\n // is updated by aggregate.\n // Note: We don't schedule it immediately to avoid preemption, but we\n // DO schedule it so it processes after the wave retry.\n }\n // Always schedule the goto (even if deferred) - it will execute in order\n // Check loop budget before scheduling goto\n if (checkLoopBudget(context, state, 'on_finish', 'goto')) {\n const errorIssue: ReviewIssue = {\n file: 'system',\n line: 0,\n ruleId: `${forEachParent}/routing/loop_budget_exceeded`,\n message: `Routing loop budget exceeded (max_loops=${context.config.routing?.max_loops ?? 10}) during on_finish goto`,\n severity: 'error',\n category: 'logic',\n };\n // Add error to parent result (not child aggregatedResult)\n parentResult.issues = [...(parentResult.issues || []), errorIssue];\n // Update parent result in journal with the error\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId: forEachParent,\n result: parentResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (err) {\n logger.warn(\n `[LevelDispatch] Failed to commit parent result with loop budget error: ${err}`\n );\n }\n return aggregatedResult; // ABORT\n }\n\n logger.info(`[LevelDispatch] on_finish for ${forEachParent} routing to: ${gotoTarget}`);\n\n // Increment loop count\n state.routingLoopCount++;\n\n emitEvent({\n type: 'ForwardRunRequested',\n target: gotoTarget,\n scope: [],\n origin: 'goto_js',\n gotoEvent: context.event as any,\n });\n state.flags.forwardRunRequested = true;\n // Also request a WaveRetry so planning occurs promptly even when preemption\n // does not immediately rebuild a wave in some schedules.\n try {\n const guardKeyGoto = `waveRetry:on_finish:${forEachParent}:wave:${state.wave}`;\n if (!(state as any).forwardRunGuards?.has(guardKeyGoto)) {\n (state as any).forwardRunGuards?.add(guardKeyGoto);\n emitEvent({ type: 'WaveRetry', reason: 'on_finish' });\n }\n } catch {}\n } else {\n logger.info(`[LevelDispatch] on_finish for ${forEachParent} returned null, no routing`);\n }\n\n // If we enqueued any on_finish.run targets, request a WaveRetry so the\n // next wave re-evaluates guards/ifs across the full plan. Guard to\n // avoid duplicate retries for the same parent within the same wave.\n if (queuedForward) {\n const guardKey = `waveRetry:on_finish:${forEachParent}:wave:${state.wave}`;\n logger.info(\n `[LevelDispatch] Checking WaveRetry guard: ${guardKey}, has=${!!(state as any).forwardRunGuards?.has(guardKey)}`\n );\n if (!(state as any).forwardRunGuards?.has(guardKey)) {\n (state as any).forwardRunGuards?.add(guardKey);\n logger.info(`[LevelDispatch] Emitting WaveRetry event for on_finish.run targets`);\n emitEvent({ type: 'WaveRetry', reason: 'on_finish' });\n }\n } else {\n // We may still have scheduled a goto above; in that case the guard\n // block there has already emitted WaveRetry. Nothing to do here.\n }\n\n // No WaveRetry needed when goto was scheduled; the planner preempts\n // remaining work and rebuilds the next wave around the goto target.\n } else {\n logger.warn(`[LevelDispatch] Could not find parent result for ${forEachParent} in journal`);\n }\n } catch (error) {\n logger.error(\n `[LevelDispatch] Error processing on_finish for forEach parent ${forEachParent}: ${error}`\n );\n }\n }\n\n return aggregatedResult;\n}\n\n/**\n * Execute a single check with provider integration\n */\nasync function executeSingleCheck(\n checkId: string,\n context: EngineContext,\n state: RunState,\n emitEvent: (event: EngineEvent) => void,\n transition: (newState: EngineState) => void,\n scopeOverride?: Array<{ check: string; index: number }>\n): Promise<ReviewSummary> {\n // Check if this check depends on a forEach parent\n const checkConfig = context.config.checks?.[checkId];\n\n // Evaluate 'if' condition before execution\n if (checkConfig?.if) {\n const shouldRun = await evaluateIfCondition(checkId, checkConfig, context, state);\n\n if (!shouldRun) {\n // Log skip message at info level (visible without debug mode)\n // Message format intentionally omits check name to satisfy e2e expectations.\n logger.info(\n `⏭ Skipped (if: ${checkConfig.if.substring(0, 40)}${checkConfig.if.length > 40 ? '...' : ''})`\n );\n\n // Return empty result and mark as completed (tag as internal-skip for stats filtering)\n const emptyResult: ReviewSummary = { issues: [] };\n try {\n Object.defineProperty(emptyResult as any, '__skipped', {\n value: 'if_condition',\n enumerable: false,\n });\n } catch {}\n\n state.completedChecks.add(checkId);\n\n // Track skip statistics\n const stats: CheckExecutionStats = {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: true,\n skipReason: 'if_condition',\n skipCondition: checkConfig.if,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: {\n critical: 0,\n error: 0,\n warning: 0,\n info: 0,\n },\n };\n state.stats.set(checkId, stats);\n logger.info(`[LevelDispatch] Recorded skip stats for ${checkId}: skipReason=if_condition`);\n\n // Store empty result in journal\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: emptyResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit skipped result to journal: ${error}`);\n }\n\n // Emit completed event\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope: [],\n result: emptyResult,\n });\n\n return emptyResult;\n }\n }\n\n const dependencies = checkConfig?.depends_on || [];\n const depList = Array.isArray(dependencies) ? dependencies : [dependencies];\n\n // Dependency gating with continue_on_failure and OR groups (\"A|B\")\n const failedChecks = (state as any).failedChecks as Set<string> | undefined;\n const tokens = depList.filter(Boolean) as string[];\n const groupSatisfied = (token: string): boolean => {\n const options = token.includes('|')\n ? token\n .split('|')\n .map(s => s.trim())\n .filter(Boolean)\n : [token];\n for (const opt of options) {\n const depCfg: any = context.config.checks?.[opt];\n const cont = !!(depCfg && depCfg.continue_on_failure === true);\n const st = state.stats.get(opt);\n const wasMarkedFailed = !!(failedChecks && failedChecks.has(opt));\n const skipped = !!(st && (st as any).skipped === true);\n const failedOnly = !!(st && (st.failedRuns || 0) > 0 && (st.successfulRuns || 0) === 0);\n const satisfied = !skipped && ((!failedOnly && !wasMarkedFailed) || cont);\n if (satisfied) return true;\n }\n return false;\n };\n\n if (tokens.length > 0) {\n let allOk = true;\n for (const t of tokens) {\n if (!groupSatisfied(t)) {\n allOk = false;\n break;\n }\n }\n if (!allOk) {\n const emptyResult: ReviewSummary = { issues: [] };\n try {\n Object.defineProperty(emptyResult as any, '__skipped', {\n value: 'dependency_failed',\n enumerable: false,\n });\n } catch {}\n state.completedChecks.add(checkId);\n if (!(state as any).failedChecks) (state as any).failedChecks = new Set<string>();\n (state as any).failedChecks.add(checkId);\n const stats: CheckExecutionStats = {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: true,\n skipReason: 'dependency_failed',\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: { critical: 0, error: 0, warning: 0, info: 0 },\n };\n state.stats.set(checkId, stats);\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: emptyResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit empty result to journal: ${error}`);\n }\n emitEvent({ type: 'CheckCompleted', checkId, scope: [], result: emptyResult });\n return emptyResult;\n }\n }\n\n let forEachParent: string | undefined;\n let forEachItems: unknown[] | undefined;\n\n // Find if any dependency is a forEach parent with items\n for (const depId of depList) {\n if (!depId) continue;\n\n try {\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const depResult: any = contextView.get(depId);\n\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Checking dependency ${depId} for ${checkId}: has forEachItems=${!!depResult?.forEachItems}, isArray=${Array.isArray(depResult?.forEachItems)}`\n );\n if (depResult?.forEachItems) {\n logger.info(\n `[LevelDispatch] forEachItems length: ${depResult.forEachItems.length}, items: ${JSON.stringify(depResult.forEachItems).substring(0, 200)}`\n );\n }\n }\n\n if (depResult?.forEachItems && Array.isArray(depResult.forEachItems)) {\n forEachParent = depId;\n forEachItems = depResult.forEachItems;\n if (context.debug && forEachItems) {\n logger.info(\n `[LevelDispatch] Detected forEach parent ${depId} with ${forEachItems.length} items for check ${checkId}`\n );\n }\n break;\n }\n } catch (error) {\n if (context.debug) {\n logger.warn(`[LevelDispatch] Error checking forEach parent ${depId}: ${error}`);\n }\n }\n }\n\n // If there's a forEach parent, decide fanout behavior:\n // - fanout: 'map' => run once per item\n // - fanout: 'reduce' (default) => run once at parent scope\n if (forEachParent && forEachItems !== undefined) {\n // Determine fanout mode\n let fanoutMode: 'map' | 'reduce' = 'reduce';\n const explicit = (checkConfig as any)?.fanout as 'map' | 'reduce' | undefined;\n if (explicit === 'map' || explicit === 'reduce') {\n fanoutMode = explicit;\n } else {\n // Heuristic default: most providers (command, ai, http, etc.) map per item.\n // Aggregator-style providers (log, memory, script, workflow/noop) default to reduce.\n const providerType = context.checks[checkId]?.providerType || '';\n const reduceProviders = new Set(['log', 'memory', 'script', 'workflow', 'noop']);\n fanoutMode = reduceProviders.has(providerType) ? 'reduce' : 'map';\n }\n if (fanoutMode === 'map') {\n // Per-item execution\n if (forEachItems.length === 0) {\n // forEach parent has zero items - skip this check entirely\n // Log skip message at info level (visible without debug mode)\n logger.info(`⏭ Skipped (forEach parent \"${forEachParent}\" has 0 items)`);\n\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Skipping check ${checkId}: forEach parent ${forEachParent} has zero items`\n );\n }\n\n // Return empty result\n const emptyResult: ReviewSummary = { issues: [] };\n try {\n Object.defineProperty(emptyResult as any, '__skipped', {\n value: 'forEach_empty',\n enumerable: false,\n });\n } catch {}\n\n // Mark as completed\n state.completedChecks.add(checkId);\n\n // Mark this check as failed so downstream dependencies also skip\n // This enables cascade skipping when a forEach parent has no items\n if (!(state as any).failedChecks) {\n (state as any).failedChecks = new Set<string>();\n }\n (state as any).failedChecks.add(checkId);\n\n // Determine skip reason: if the parent failed, prefer dependency_failed over forEach_empty\n let derivedSkipReason: 'forEach_empty' | 'dependency_failed' = 'forEach_empty';\n try {\n const parentFailed =\n !!((state as any).failedChecks && (state as any).failedChecks.has(forEachParent)) ||\n (() => {\n const s = state.stats.get(forEachParent);\n return !!(s && (s.failedRuns || 0) > 0);\n })();\n if (parentFailed) derivedSkipReason = 'dependency_failed';\n } catch {}\n\n // Update stats to record skip\n const stats: CheckExecutionStats = {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: true,\n skipReason: derivedSkipReason,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: {\n critical: 0,\n error: 0,\n warning: 0,\n info: 0,\n },\n };\n state.stats.set(checkId, stats);\n\n // Store empty result in journal\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: emptyResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit empty result to journal: ${error}`);\n }\n\n // Emit completed event\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope: [],\n result: emptyResult,\n });\n\n return emptyResult;\n }\n\n return await executeCheckWithForEachItems(\n checkId,\n forEachParent,\n forEachItems,\n context,\n state,\n emitEvent,\n transition\n );\n }\n // fanout reduce: fall through to normal single execution below\n }\n\n // Normal execution without forEach\n const scope: Array<{ check: string; index: number }> = scopeOverride || [];\n\n // Emit scheduled event\n emitEvent({ type: 'CheckScheduled', checkId, scope });\n\n // Track start time for duration calculation\n const startTime = Date.now();\n\n // Create dispatch record\n const dispatch: DispatchRecord = {\n id: `${checkId}-${Date.now()}`,\n checkId,\n scope,\n provider: context.checks[checkId]?.providerType || 'unknown',\n startMs: startTime,\n attempts: 1,\n };\n\n state.activeDispatches.set(checkId, dispatch);\n\n try {\n // Get check configuration\n const checkConfig = context.config.checks?.[checkId];\n if (!checkConfig) {\n throw new Error(`Check configuration not found: ${checkId}`);\n }\n\n // Get provider\n const providerType = checkConfig.type || 'ai';\n const providerRegistry =\n require('../../providers/check-provider-registry').CheckProviderRegistry.getInstance();\n const provider = providerRegistry.getProviderOrThrow(providerType);\n\n // Build output history for template rendering\n const outputHistory = buildOutputHistoryFromJournal(context);\n\n // Build provider configuration\n const providerConfig: CheckProviderConfig = {\n type: providerType,\n checkName: checkId,\n prompt: checkConfig.prompt,\n exec: checkConfig.exec,\n schema: checkConfig.schema,\n group: checkConfig.group,\n focus: checkConfig.focus || mapCheckNameToFocus(checkId),\n transform: checkConfig.transform,\n transform_js: checkConfig.transform_js,\n env: checkConfig.env,\n forEach: checkConfig.forEach,\n ...checkConfig,\n eventContext: (context.prInfo as any)?.eventContext || {},\n __outputHistory: outputHistory,\n ai: {\n ...(checkConfig.ai || {}),\n timeout: checkConfig.ai?.timeout || 600000,\n debug: !!context.debug,\n },\n };\n\n // Propagate authenticated Octokit (v2 frontends / Action mode)\n try {\n const maybeOctokit = (context.executionContext as any)?.octokit;\n if (maybeOctokit) {\n (providerConfig as any).eventContext = {\n ...(providerConfig as any).eventContext,\n octokit: maybeOctokit,\n };\n }\n } catch {}\n\n // Build dependency results\n const dependencyResults = buildDependencyResults(checkId, checkConfig, context, state);\n\n // Build PR info (use real prInfo from context if available, otherwise use defaults)\n const prInfo: any = context.prInfo || {\n number: 1,\n title: 'State Machine Execution',\n author: 'system',\n eventType: context.event || 'manual',\n eventContext: {},\n files: [],\n commits: [],\n };\n\n // Build execution context with engine mode and parent context (M3: nested workflows)\n const executionContext = {\n ...context.executionContext,\n _engineMode: context.mode,\n _parentContext: context,\n _parentState: state,\n };\n\n // Evaluate assume contract (design-by-contract) before executing\n try {\n const assumeExpr = (checkConfig as any)?.assume as string | string[] | undefined;\n if (assumeExpr) {\n const evaluator = new FailureConditionEvaluator();\n const exprs = Array.isArray(assumeExpr) ? assumeExpr : [assumeExpr];\n let ok = true;\n for (const ex of exprs) {\n const res = await evaluator.evaluateIfCondition(checkId, ex, {\n event: context.event || 'manual',\n previousResults: dependencyResults as any,\n } as any);\n if (!res) {\n ok = false;\n break;\n }\n }\n if (!ok) {\n logger.info(\n `⏭ Skipped (assume: ${String(Array.isArray(assumeExpr) ? assumeExpr[0] : assumeExpr).substring(0, 40)}${String(Array.isArray(assumeExpr) ? assumeExpr[0] : assumeExpr).length > 40 ? '...' : ''})`\n );\n // Mark as completed and record skip stats\n state.completedChecks.add(checkId);\n const stats: CheckExecutionStats = {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: true,\n skipReason: 'assume',\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: { critical: 0, error: 0, warning: 0, info: 0 },\n };\n state.stats.set(checkId, stats);\n const emptyResult: ReviewSummary = { issues: [] };\n try {\n Object.defineProperty(emptyResult as any, '__skipped', {\n value: 'assume',\n enumerable: false,\n });\n } catch {}\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: emptyResult as any,\n event: context.event || 'manual',\n scope,\n });\n } catch {}\n emitEvent({ type: 'CheckCompleted', checkId, scope, result: emptyResult });\n return emptyResult;\n }\n }\n } catch {}\n\n // Emit provider telemetry\n try {\n emitNdjsonFallback('visor.provider', {\n 'visor.check.id': checkId,\n 'visor.provider.type': providerType,\n });\n } catch {}\n\n // Execute provider with telemetry\n const result = await withActiveSpan(\n `visor.check.${checkId}`,\n { 'visor.check.id': checkId, 'visor.check.type': providerType },\n async () => provider.execute(prInfo, providerConfig, dependencyResults, executionContext)\n );\n\n // Enrich issues with metadata\n const enrichedIssues = (result.issues || []).map((issue: ReviewIssue) => ({\n ...issue,\n checkName: checkId,\n ruleId: `${checkId}/${issue.ruleId || 'unknown'}`,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n template: checkConfig.template,\n timestamp: Date.now(),\n }));\n\n const enrichedResult: any = {\n ...result,\n issues: enrichedIssues,\n };\n\n // Validate output against JSON Schema if provided (non-fatal contract)\n try {\n let schemaObj =\n (typeof checkConfig.schema === 'object' ? (checkConfig.schema as any) : undefined) ||\n (checkConfig as any).output_schema;\n if (!schemaObj && typeof (checkConfig as any).schema === 'string') {\n try {\n const { loadRendererSchema } = await import('../dispatch/renderer-schema');\n schemaObj = await loadRendererSchema((checkConfig as any).schema as string);\n } catch {}\n }\n if (schemaObj && (enrichedResult as any)?.output !== undefined) {\n const Ajv = require('ajv');\n const ajv = new Ajv({ allErrors: true, allowUnionTypes: true, strict: false });\n const validate = ajv.compile(schemaObj);\n const valid = validate((enrichedResult as any).output);\n if (!valid) {\n const errs = (validate.errors || [])\n .slice(0, 3)\n .map((e: any) => e.message)\n .join('; ');\n const issue: ReviewIssue = {\n file: 'contract',\n line: 0,\n ruleId: `contract/schema_validation_failed`,\n message: `Output schema validation failed${errs ? `: ${errs}` : ''}`,\n severity: 'error',\n category: 'logic',\n checkName: checkId,\n group: checkConfig.group,\n schema: 'json-schema',\n timestamp: Date.now(),\n } as any;\n enrichedResult.issues = [...(enrichedResult.issues || []), issue];\n }\n }\n } catch {}\n\n // Evaluate guarantee contract after execution (non-fatal)\n try {\n const guaranteeExpr = (checkConfig as any)?.guarantee as string | string[] | undefined;\n if (guaranteeExpr) {\n const evaluator = new FailureConditionEvaluator();\n const exprs = Array.isArray(guaranteeExpr) ? guaranteeExpr : [guaranteeExpr];\n for (const ex of exprs) {\n const holds = await evaluator.evaluateIfCondition(checkId, ex, {\n previousResults: dependencyResults as any,\n event: context.event || 'manual',\n } as any);\n if (!holds) {\n const issue: ReviewIssue = {\n file: 'contract',\n line: 0,\n ruleId: `contract/guarantee_failed`,\n message: `Guarantee failed: ${ex}`,\n severity: 'error',\n category: 'logic',\n checkName: checkId,\n group: checkConfig.group,\n schema:\n typeof checkConfig.schema === 'object' ? 'custom' : (checkConfig.schema as any),\n timestamp: Date.now(),\n } as any;\n enrichedResult.issues = [...(enrichedResult.issues || []), issue];\n }\n }\n }\n } catch {}\n\n // Handle forEach: true checks - convert output array to forEachItems\n let isForEach = (result as any).isForEach;\n let forEachItems = (result as any).forEachItems;\n\n // DEBUG: Log forEach handling\n logger.info(\n `[LevelDispatch][DEBUG] After execution ${checkId}: checkConfig.forEach=${checkConfig.forEach}, output type=${typeof (result as any).output}, isArray=${Array.isArray((result as any).output)}`\n );\n\n if (checkConfig.forEach === true) {\n const output = (result as any).output;\n logger.info(\n `[LevelDispatch][DEBUG] Processing forEach=true for ${checkId}, output=${JSON.stringify(output)?.substring(0, 200)}`\n );\n\n // Validate forEach output (must not be undefined)\n if (output === undefined) {\n logger.error(`[LevelDispatch] forEach check \"${checkId}\" produced undefined output`);\n const undefinedError: ReviewIssue = {\n file: 'system',\n line: 0,\n // Mark as execution failure so dependents treat this as failed dependency\n ruleId: 'forEach/execution_error',\n message: `forEach check \"${checkId}\" produced undefined output. Verify your command outputs valid data and your transform_js returns a value.`,\n severity: 'error',\n category: 'logic',\n };\n enrichedResult.issues = [...(enrichedResult.issues || []), undefinedError];\n // Mark as forEach with empty items to skip dependent iterations\n isForEach = true;\n forEachItems = [];\n enrichedResult.isForEach = true;\n enrichedResult.forEachItems = [];\n // Also mark this check as failed so downstream dependents skip with dependency_failed\n try {\n if (!(state as any).failedChecks) {\n (state as any).failedChecks = new Set<string>();\n }\n (state as any).failedChecks.add(checkId);\n } catch {}\n // Early exit: persist result and stop further processing to avoid\n // undefined-state follow-on work (routing/template/per-item commits).\n try {\n // Record completion BEFORE storing\n state.completedChecks.add(checkId);\n const currentWaveCompletions = (state as any).currentWaveCompletions as\n | Set<string>\n | undefined;\n if (currentWaveCompletions) currentWaveCompletions.add(checkId);\n\n // Update aggregated stats for forEach parent (failed run, 0 outputs)\n const existing = state.stats.get(checkId);\n const aggStats: CheckExecutionStats = existing || {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: false,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: { critical: 0, error: 0, warning: 0, info: 0 },\n };\n aggStats.totalRuns++;\n aggStats.failedRuns++;\n aggStats.outputsProduced = 0;\n state.stats.set(checkId, aggStats);\n\n // Store in journal\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: enrichedResult as any,\n event: context.event || 'manual',\n scope: [],\n });\n } catch (err) {\n logger.warn(`[LevelDispatch] Failed to persist undefined forEach result: ${err}`);\n }\n\n // Clear active dispatch and emit completion event\n try {\n state.activeDispatches.delete(checkId);\n } catch {}\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope: [],\n result: enrichedResult,\n });\n return enrichedResult as ReviewSummary;\n } else if (Array.isArray(output)) {\n isForEach = true;\n forEachItems = output;\n enrichedResult.isForEach = true;\n enrichedResult.forEachItems = output;\n\n // Log forEach items count (always log, not just in debug mode)\n logger.info(` Found ${output.length} items for forEach iteration`);\n\n if (context.debug) {\n logger.info(\n `[LevelDispatch] Check ${checkId} is forEach parent with ${output.length} items`\n );\n }\n } else {\n // forEach check but output is not an array - convert to single-item array\n if (context.debug) {\n logger.warn(\n `[LevelDispatch] Check ${checkId} has forEach:true but output is not an array: ${typeof output}, converting to single-item array`\n );\n }\n isForEach = true;\n forEachItems = [output];\n enrichedResult.isForEach = true;\n enrichedResult.forEachItems = [output];\n }\n }\n\n // Also preserve forEach metadata if already present (from provider)\n if ((result as any).isForEach) {\n enrichedResult.isForEach = true;\n }\n if ((result as any).forEachItems) {\n enrichedResult.forEachItems = (result as any).forEachItems;\n }\n if ((result as any).forEachItemResults) {\n enrichedResult.forEachItemResults = (result as any).forEachItemResults;\n }\n if ((result as any).forEachFatalMask) {\n enrichedResult.forEachFatalMask = (result as any).forEachFatalMask;\n }\n\n // Render template content and emit Mermaid diagrams\n let renderedContent: string | undefined;\n try {\n renderedContent = await renderTemplateContent(checkId, checkConfig, enrichedResult);\n if (renderedContent) {\n // Emit Mermaid diagram events from the rendered content\n emitMermaidFromMarkdown(checkId, renderedContent, 'content');\n }\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to render template for ${checkId}: ${error}`);\n }\n\n // Generate default content from issues if no template content was rendered\n if (!renderedContent && enrichedIssues.length > 0) {\n renderedContent = enrichedIssues\n .map(\n (i: ReviewIssue) =>\n `- **${i.severity.toUpperCase()}**: ${i.message} (${i.file}:${i.line})`\n )\n .join('\\n');\n }\n\n // Add timestamp to output if it exists and is an object\n // For primitive outputs (number, string, boolean), preserve them as-is\n let outputWithTimestamp: any = undefined;\n if ((result as any).output !== undefined) {\n const output = (result as any).output;\n if (output !== null && typeof output === 'object' && !Array.isArray(output)) {\n // Only add timestamp to plain objects\n outputWithTimestamp = { ...output, ts: Date.now() };\n } else {\n // Preserve primitives, arrays, and null as-is\n outputWithTimestamp = output;\n }\n }\n\n // Add rendered content to the result\n const enrichedResultWithContent = renderedContent\n ? { ...enrichedResult, content: renderedContent }\n : enrichedResult;\n\n const enrichedResultWithTimestamp =\n outputWithTimestamp !== undefined\n ? { ...enrichedResultWithContent, output: outputWithTimestamp }\n : enrichedResultWithContent;\n\n // Record completion BEFORE routing (so routing can see it as completed)\n state.completedChecks.add(checkId);\n\n // Track wave-specific completion for 'if' condition evaluation\n const currentWaveCompletions = (state as any).currentWaveCompletions as Set<string> | undefined;\n if (currentWaveCompletions) {\n currentWaveCompletions.add(checkId);\n }\n\n // Process routing (fail_if, on_success, on_fail) BEFORE storing in journal\n // This allows routing errors to be included in the stored result\n try {\n logger.info(`[LevelDispatch] Calling handleRouting for ${checkId}`);\n } catch {}\n await handleRouting(context, state, transition, emitEvent, {\n checkId,\n scope,\n result: enrichedResult,\n checkConfig: checkConfig as CheckConfig,\n success: !hasFatalIssues(enrichedResult),\n });\n\n // NOW store in journal with routing-side mutations included (e.g., fail_if issues)\n // Rebuild the commit payload from the possibly mutated enrichedResult so new issues are captured.\n try {\n const commitResult: any = {\n ...enrichedResult,\n ...(renderedContent ? { content: renderedContent } : {}),\n ...((result as any).output !== undefined\n ? outputWithTimestamp !== undefined\n ? { output: outputWithTimestamp }\n : { output: (result as any).output }\n : {}),\n };\n\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: commitResult,\n event: context.event || 'manual',\n scope,\n });\n } catch (error) {\n logger.warn(`[LevelDispatch] Failed to commit to journal: ${error}`);\n }\n\n // For forEach parent checks (this check produced forEachItems), record a single aggregated run in stats\n if (isForEach) {\n try {\n const existing = state.stats.get(checkId);\n const aggStats: CheckExecutionStats = existing || {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: false,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: { critical: 0, error: 0, warning: 0, info: 0 },\n };\n aggStats.totalRuns++;\n const hasFatal = hasFatalIssues(enrichedResultWithTimestamp as any);\n if (hasFatal) aggStats.failedRuns++;\n else aggStats.successfulRuns++;\n // outputsProduced for parent equals number of items\n const items = (enrichedResultWithTimestamp as any).forEachItems;\n if (Array.isArray(items)) aggStats.outputsProduced = items.length;\n state.stats.set(checkId, aggStats);\n } catch {}\n }\n\n // If this is a forEach check, also commit per-item results\n if (isForEach && forEachItems && Array.isArray(forEachItems)) {\n for (let itemIndex = 0; itemIndex < forEachItems.length; itemIndex++) {\n const itemScope: Array<{ check: string; index: number }> = [\n { check: checkId, index: itemIndex },\n ];\n const item = forEachItems[itemIndex];\n\n try {\n context.journal.commitEntry({\n sessionId: context.sessionId,\n checkId,\n result: { issues: [], output: item } as any,\n event: context.event || 'manual',\n scope: itemScope,\n });\n } catch (error) {\n logger.warn(\n `[LevelDispatch] Failed to commit per-item journal for ${checkId} item ${itemIndex}: ${error}`\n );\n }\n }\n }\n\n state.activeDispatches.delete(checkId);\n\n // Emit completed event with full result (including routing errors)\n emitEvent({\n type: 'CheckCompleted',\n checkId,\n scope,\n result: {\n ...enrichedResult,\n output: (result as any).output,\n content: renderedContent || (result as any).content,\n },\n });\n\n return enrichedResult;\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error(`[LevelDispatch] Error executing check ${checkId}: ${err.message}`);\n\n state.activeDispatches.delete(checkId);\n\n // Emit error event\n emitEvent({\n type: 'CheckErrored',\n checkId,\n scope,\n error: {\n message: err.message,\n stack: err.stack,\n name: err.name,\n },\n });\n // Re-throw so the caller records the failure in statistics and surfaces\n // a single top-level system/error issue via statistics aggregation.\n throw err;\n }\n}\n\n/**\n * Build dependency results for a check with scope\n */\nfunction buildDependencyResultsWithScope(\n checkId: string,\n checkConfig: any,\n context: EngineContext,\n scope: Array<{ check: string; index: number }>\n): Map<string, ReviewSummary> {\n const dependencyResults = new Map<string, ReviewSummary>();\n\n // Get dependencies from configuration\n const dependencies = checkConfig.depends_on || [];\n const depList = Array.isArray(dependencies) ? dependencies : [dependencies];\n\n // Determine current forEach index from scope (if any)\n const currentIndex = scope.length > 0 ? scope[scope.length - 1].index : undefined;\n\n // First, populate explicit dependencies\n for (const depId of depList) {\n if (!depId) continue;\n\n // Try to get the LATEST result from journal for this exact scope\n try {\n const snapshotId = context.journal.beginSnapshot();\n const visible = context.journal.readVisible(\n context.sessionId,\n snapshotId,\n context.event as any\n );\n const sameScope = (\n a: Array<{ check: string; index: number }>,\n b: Array<{ check: string; index: number }>\n ): boolean => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++)\n if (a[i].check !== b[i].check || a[i].index !== b[i].index) return false;\n return true;\n };\n const matches = visible.filter(e => e.checkId === depId && sameScope(e.scope as any, scope));\n let journalResult = (\n matches.length > 0 ? matches[matches.length - 1].result : undefined\n ) as any;\n\n // If we couldn't resolve a scoped result OR we received an aggregated\n // forEach result, reconstruct a per-item view using forEachItemResults\n if (\n journalResult &&\n Array.isArray(journalResult.forEachItems) &&\n currentIndex !== undefined\n ) {\n const perItemSummary: any = (journalResult.forEachItemResults &&\n journalResult.forEachItemResults[currentIndex]) || { issues: [] };\n const perItemOutput = journalResult.forEachItems[currentIndex];\n const combined = { ...perItemSummary, output: perItemOutput } as ReviewSummary;\n dependencyResults.set(depId, combined);\n continue;\n }\n\n if (!journalResult) {\n // Fallback: try raw (aggregate) view and slice out current index if possible\n try {\n const rawView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const rawResult = rawView.get(depId) as any | undefined;\n if (rawResult && Array.isArray(rawResult.forEachItems) && currentIndex !== undefined) {\n const perItemSummary: any = (rawResult.forEachItemResults &&\n rawResult.forEachItemResults[currentIndex]) || { issues: [] };\n const perItemOutput = rawResult.forEachItems[currentIndex];\n const combined = { ...perItemSummary, output: perItemOutput } as ReviewSummary;\n dependencyResults.set(depId, combined);\n continue;\n }\n journalResult = rawResult;\n } catch {\n // ignore\n }\n }\n\n if (journalResult) {\n dependencyResults.set(depId, journalResult as ReviewSummary);\n continue;\n }\n } catch {\n // Fall through to other sources\n }\n\n // Fall back to empty result\n dependencyResults.set(depId, { issues: [] });\n }\n\n // Also populate ALL other executed checks from journal (for global outputs namespace)\n // This provides access to all outputs via {{ outputs[\"check-name\"] }} in templates\n try {\n const snapshotId = context.journal.beginSnapshot();\n const contextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n scope,\n context.event\n );\n\n // Get all check names from the config\n const allCheckNames = Object.keys(context.config.checks || {});\n for (const checkName of allCheckNames) {\n // Skip if already in dependencies\n if (dependencyResults.has(checkName)) continue;\n\n // Try to get result from journal\n let jr: any | undefined = contextView.get(checkName);\n\n // If this is an aggregated forEach result and we have an index in scope,\n // expose the per-item view to make `outputs[\"name\"]` reflect the current branch item.\n if (jr && Array.isArray(jr.forEachItems) && currentIndex !== undefined) {\n const perItemSummary: any = (jr.forEachItemResults &&\n jr.forEachItemResults[currentIndex]) || { issues: [] };\n const perItemOutput = jr.forEachItems[currentIndex];\n const combined = { ...perItemSummary, output: perItemOutput } as ReviewSummary;\n dependencyResults.set(checkName, combined);\n continue;\n }\n\n if (!jr) {\n // Fallback to raw aggregate and slice current index if possible\n try {\n const rawView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [],\n context.event\n );\n const raw = rawView.get(checkName) as any | undefined;\n if (raw && Array.isArray(raw.forEachItems) && currentIndex !== undefined) {\n const perItemSummary: any = (raw.forEachItemResults &&\n raw.forEachItemResults[currentIndex]) || { issues: [] };\n const perItemOutput = raw.forEachItems[currentIndex];\n const combined = { ...perItemSummary, output: perItemOutput } as ReviewSummary;\n dependencyResults.set(checkName, combined);\n continue;\n }\n jr = raw;\n } catch {\n // ignore\n }\n }\n\n if (jr) {\n dependencyResults.set(checkName, jr as ReviewSummary);\n }\n }\n\n // Add raw array access for forEach checks\n // For each check with forEach:true, also provide <checkName>-raw key with the full array\n for (const checkName of allCheckNames) {\n const checkCfg = context.config.checks?.[checkName];\n if (checkCfg?.forEach) {\n // Get the check result (without scope) to access the full forEachItems array\n try {\n const rawContextView = new (require('../../snapshot-store').ContextView)(\n context.journal,\n context.sessionId,\n snapshotId,\n [], // No scope - get parent-level result with forEachItems\n context.event\n );\n const rawResult = rawContextView.get(checkName);\n if (rawResult && (rawResult as any).forEachItems) {\n // Add -raw key with full array\n const rawKey = `${checkName}-raw`;\n dependencyResults.set(rawKey, {\n issues: [],\n output: (rawResult as any).forEachItems,\n } as ReviewSummary);\n }\n } catch {\n // Silently skip - raw access is optional\n }\n }\n }\n } catch {\n // Silently fail - we'll just have the explicit dependencies\n }\n\n return dependencyResults;\n}\n\n/**\n * Build dependency results for a check\n */\nfunction buildDependencyResults(\n checkId: string,\n checkConfig: any,\n context: EngineContext,\n _state: RunState\n): Map<string, ReviewSummary> {\n return buildDependencyResultsWithScope(checkId, checkConfig, context, []);\n}\n\n/**\n * Check if fail-fast should be triggered based on results\n */\nfunction shouldFailFast(\n results: Array<{ checkId: string; result: ReviewSummary; error?: Error }>\n): boolean {\n // Fail-fast if any check has critical or error severity issues\n for (const { result } of results) {\n if (!result || !result.issues) continue;\n\n if (hasFatalIssues(result)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if result has fatal issues (execution failures, not code quality issues)\n *\n * Fatal issues are those indicating the check itself failed to execute properly:\n * - ruleId ends with '/error' (system errors, exceptions)\n * - ruleId contains '/execution_error' (command failures)\n * - ruleId ends with '_fail_if' (fail_if condition triggered)\n *\n * Regular error/critical severity issues (e.g., security vulnerabilities found in code)\n * are NOT fatal - they represent successful execution that found issues.\n */\nfunction hasFatalIssues(result: ReviewSummary): boolean {\n if (!result.issues) {\n return false;\n }\n\n // Check for execution failure indicators in ruleId\n return result.issues.some(issue => {\n const ruleId = issue.ruleId || '';\n return (\n ruleId.endsWith('/error') || // System errors\n ruleId.includes('/execution_error') || // Command failures\n (ruleId.endsWith('_fail_if') && ruleId !== 'global_fail_if') // check-level fail_if only\n );\n });\n}\n\n/**\n * Update execution stats\n */\nfunction updateStats(\n results: Array<{ checkId: string; result: ReviewSummary; error?: Error; duration?: number }>,\n state: RunState,\n isForEachIteration: boolean = false\n): void {\n for (const { checkId, result, error, duration } of results) {\n const existing = state.stats.get(checkId);\n\n const stats: CheckExecutionStats = existing || {\n checkName: checkId,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skippedRuns: 0,\n skipped: false,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: {\n critical: 0,\n error: 0,\n warning: 0,\n info: 0,\n },\n };\n\n // DEBUG: Log when updateStats is called for post-response\n if (checkId === 'post-response') {\n logger.info(\n `[updateStats] Called for post-response: existing.skipped=${existing?.skipped}, stats.skipped=${stats.skipped}, skipReason=${(stats as any).skipReason}`\n );\n }\n\n // If check was previously skipped but is now executing, clear the skipped flag\n if (stats.skipped) {\n stats.skipped = false;\n if (checkId === 'post-response') {\n logger.info(\n `[updateStats] Clearing skipped flag for post-response (was skipped, now executing)`\n );\n }\n }\n\n // Increment totalRuns for all executions including forEach iterations\n // isForEachIteration=true means this is a single iteration of a forEach child check\n // We count these as separate executions\n stats.totalRuns++;\n\n // Track duration if provided\n if (duration !== undefined) {\n stats.totalDuration += duration;\n }\n\n // Check if this is an execution failure (not a code quality finding)\n // Execution failures have specific ruleId patterns that indicate the check itself failed\n const hasExecutionFailure = result.issues?.some(issue => {\n const ruleId = issue.ruleId || '';\n return (\n ruleId.endsWith('/error') || // System errors, exceptions\n ruleId.includes('/execution_error') || // Command failures\n (ruleId.endsWith('_fail_if') && ruleId !== 'global_fail_if') // check-level fail_if only\n );\n });\n\n if (error) {\n // Exception during execution\n stats.failedRuns++;\n stats.errorMessage = error.message;\n // Mark check as failed so dependents can be skipped\n // Note: forEach iteration failures are tracked per-iteration, but the check\n // is only marked as completely failed if ALL iterations fail (handled in executeCheckWithForEachItems)\n if (!isForEachIteration) {\n if (!(state as any).failedChecks) {\n (state as any).failedChecks = new Set<string>();\n }\n (state as any).failedChecks.add(checkId);\n }\n } else if (hasExecutionFailure) {\n // Execution failure (command error, fail_if triggered, etc.)\n stats.failedRuns++;\n // Note: We do NOT set stats.errorMessage here because the check already produced\n // error issues as part of its normal output. Setting errorMessage would cause\n // convertGroupedResultsToReviewSummary to create a duplicate system/error issue.\n // errorMessage should only be set for exceptional errors (caught exceptions).\n\n // Mark check as failed so dependents can be skipped\n // Note: forEach iteration failures are tracked per-iteration, but the check\n // is only marked as completely failed if ALL iterations fail (handled in executeCheckWithForEachItems)\n if (!isForEachIteration) {\n if (!(state as any).failedChecks) {\n (state as any).failedChecks = new Set<string>();\n }\n (state as any).failedChecks.add(checkId);\n }\n } else {\n stats.successfulRuns++;\n }\n\n // Count issues\n if (result.issues) {\n stats.issuesFound += result.issues.length;\n\n for (const issue of result.issues) {\n if (issue.severity === 'critical') stats.issuesBySeverity.critical++;\n else if (issue.severity === 'error') stats.issuesBySeverity.error++;\n else if (issue.severity === 'warning') stats.issuesBySeverity.warning++;\n else if (issue.severity === 'info') stats.issuesBySeverity.info++;\n }\n }\n\n // Track outputsProduced if result has output\n // For forEach parent checks, use the length of forEachItems\n // For regular checks, count is 1\n if (stats.outputsProduced === undefined) {\n const forEachItems = (result as any).forEachItems;\n if (Array.isArray(forEachItems)) {\n stats.outputsProduced = forEachItems.length;\n } else if ((result as any).output !== undefined) {\n stats.outputsProduced = 1;\n }\n }\n\n state.stats.set(checkId, stats);\n }\n}\n\n/**\n * Render template content for a check\n * Similar to legacy engine's renderCheckContent method\n */\nasync function renderTemplateContent(\n checkId: string,\n checkConfig: any,\n reviewSummary: ReviewSummary\n): Promise<string | undefined> {\n try {\n const { createExtendedLiquid } = await import('../../liquid-extensions');\n const fs = await import('fs/promises');\n const path = await import('path');\n\n // Determine template source: explicit template (content/file) or built-in by schema\n const schemaRaw = checkConfig.schema || 'plain';\n const schema = typeof schemaRaw === 'string' ? schemaRaw : 'code-review';\n\n let templateContent: string | undefined;\n\n if (checkConfig.template && checkConfig.template.content) {\n templateContent = String(checkConfig.template.content);\n } else if (checkConfig.template && checkConfig.template.file) {\n // Securely resolve relative file path\n const file = String(checkConfig.template.file);\n const resolved = path.resolve(process.cwd(), file);\n templateContent = await fs.readFile(resolved, 'utf-8');\n } else if (schema && schema !== 'plain') {\n // Built-in schema template fallback\n const sanitized = String(schema).replace(/[^a-zA-Z0-9-]/g, '');\n if (sanitized) {\n // When bundled with ncc, __dirname is dist/ and output/ is at dist/output/\n // When running from source, __dirname is src/state-machine/states/ and output/ is at output/\n const candidatePaths = [\n path.join(__dirname, 'output', sanitized, 'template.liquid'), // bundled: dist/output/\n path.join(__dirname, '..', '..', 'output', sanitized, 'template.liquid'), // source (from state-machine/states)\n path.join(__dirname, '..', '..', '..', 'output', sanitized, 'template.liquid'), // source (alternate)\n path.join(process.cwd(), 'output', sanitized, 'template.liquid'), // fallback: cwd/output/\n path.join(process.cwd(), 'dist', 'output', sanitized, 'template.liquid'), // fallback: cwd/dist/output/\n ];\n for (const p of candidatePaths) {\n try {\n templateContent = await fs.readFile(p, 'utf-8');\n if (templateContent) break;\n } catch {\n // try next\n }\n }\n }\n }\n\n if (!templateContent) {\n // No template to render\n return undefined;\n }\n\n // Use extended Liquid with our custom filters/tags\n const liquid = createExtendedLiquid({\n trimTagLeft: false,\n trimTagRight: false,\n trimOutputLeft: false,\n trimOutputRight: false,\n greedy: false,\n });\n\n const templateData: Record<string, unknown> = {\n issues: reviewSummary.issues || [],\n checkName: checkId,\n output: (reviewSummary as any).output,\n };\n\n const rendered = await liquid.parseAndRender(templateContent, templateData);\n return rendered.trim();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`[LevelDispatch] Failed to render template for ${checkId}: ${msg}`);\n return undefined;\n }\n}\n","/**\n * CheckRunning State Handler\n *\n * Responsibilities:\n * - Execute provider logic for a check\n * - Assemble CheckResult\n * - Transition to Routing state\n *\n * M1: This state is handled inline by LevelDispatch\n * M2: Will be a proper state when we add routing\n */\n\nimport type { EngineContext, RunState, EngineState, EngineEvent } from '../../types/engine';\n\nexport async function handleCheckRunning(\n _context: EngineContext,\n _state: RunState,\n transition: (newState: EngineState) => void,\n _emitEvent: (event: EngineEvent) => void\n): Promise<void> {\n // M2: This state is not used yet - LevelDispatch handles execution inline with routing\n // The routing happens directly in LevelDispatch after check execution\n transition('WavePlanning');\n}\n","/**\n * Completed State Handler\n *\n * Responsibilities:\n * - Finalize stats\n * - Flush telemetry\n * - Update GitHub CheckRuns\n * - Terminal state\n */\n\nimport type { EngineContext, RunState } from '../../types/engine';\nimport { logger } from '../../logger';\n\nexport async function handleCompleted(context: EngineContext, state: RunState): Promise<void> {\n if (context.debug) {\n logger.info('[Completed] Execution complete');\n logger.info(`[Completed] Total waves: ${state.wave + 1}`);\n logger.info(`[Completed] Checks completed: ${state.completedChecks.size}`);\n logger.info(`[Completed] Stats collected: ${state.stats.size}`);\n }\n\n // Finalize GitHub checks if configured\n if (context.gitHubChecks) {\n // GitHub check finalization happens in the main engine\n if (context.debug) {\n logger.info('[Completed] GitHub checks will be finalized by main engine');\n }\n }\n\n // Flush telemetry\n // M4: Will add structured event streaming to debug visualizer\n\n // Terminal state - no transition\n}\n","/**\n * Error State Handler\n *\n * Responsibilities:\n * - Capture fatal errors\n * - Unwind gracefully\n * - Terminal state\n */\n\nimport type { EngineContext, RunState } from '../../types/engine';\nimport { logger } from '../../logger';\n\nexport async function handleError(context: EngineContext, state: RunState): Promise<void> {\n logger.error('[Error] State machine entered error state');\n\n // Check if there's an error in the event queue\n const errorEvent = state.eventQueue.find(e => e.type === 'Shutdown' && e.error);\n if (errorEvent && errorEvent.type === 'Shutdown' && errorEvent.error) {\n logger.error(`[Error] Fatal error: ${errorEvent.error.message}`);\n if (errorEvent.error.stack) {\n logger.error(`[Error] Stack: ${errorEvent.error.stack}`);\n }\n }\n\n // Log stats for debugging\n if (context.debug) {\n logger.info(`[Error] Completed ${state.completedChecks.size} checks before error`);\n logger.info(`[Error] Active dispatches: ${state.activeDispatches.size}`);\n }\n\n // Terminal state - no transition\n}\n","/**\n * State Machine Runner - Core orchestration\n *\n * Implements the main event loop that drives state transitions.\n * Supports OTEL telemetry and debug visualizer event streaming (M4).\n */\n\nimport type {\n EngineContext,\n RunState,\n EngineEvent,\n EngineState,\n SerializedError,\n} from '../types/engine';\nimport { v4 as uuidv4 } from 'uuid';\nimport type { EventEnvelope } from '../event-bus/types';\nimport { logger } from '../logger';\nimport type { ExecutionResult } from '../types/execution';\nimport { GroupedCheckResults } from '../reviewer';\nimport { withActiveSpan, addEvent as addOtelEvent } from '../telemetry/trace-helpers';\nimport type { DebugVisualizerServer } from '../debug-visualizer/ws-server';\n\n// Import state handlers\nimport { handleInit } from './states/init';\nimport { handlePlanReady } from './states/plan-ready';\nimport { handleWavePlanning } from './states/wave-planning';\nimport { handleLevelDispatch } from './states/level-dispatch';\nimport { handleCheckRunning } from './states/check-running';\nimport { handleCompleted } from './states/completed';\nimport { handleError } from './states/error';\n\n/**\n * Main state machine runner\n */\nexport class StateMachineRunner {\n private context: EngineContext;\n private state: RunState;\n private debugServer?: DebugVisualizerServer;\n\n constructor(context: EngineContext, debugServer?: DebugVisualizerServer) {\n this.context = context;\n this.state = this.initializeState();\n this.debugServer = debugServer;\n }\n\n /**\n * Initialize the run state\n */\n private initializeState(): RunState {\n // Pull defaults from config where available\n const DEFAULT_MAX_WORKFLOW_DEPTH = 3;\n const configuredMaxDepth =\n (this.context && this.context.config && this.context.config.limits\n ? this.context.config.limits.max_workflow_depth\n : undefined) ?? DEFAULT_MAX_WORKFLOW_DEPTH;\n return {\n currentState: 'Init',\n wave: 0,\n levelQueue: [],\n eventQueue: [],\n activeDispatches: new Map(),\n completedChecks: new Set(),\n flags: {\n failFastTriggered: false,\n forwardRunRequested: false,\n // Maximum nesting depth for nested workflows (configurable)\n maxWorkflowDepth: configuredMaxDepth,\n currentWorkflowDepth: 0, // Start at root level\n },\n stats: new Map(),\n historyLog: [],\n forwardRunGuards: new Set(),\n currentLevelChecks: new Set(),\n routingLoopCount: 0,\n pendingRunScopes: new Map(),\n };\n }\n\n /**\n * Execute the state machine\n */\n async run(): Promise<ExecutionResult> {\n try {\n // Emit initial state transition event\n this.emitEvent({ type: 'StateTransition', from: 'Init', to: 'Init' });\n\n // Main event loop\n while (!this.isTerminalState(this.state.currentState)) {\n const currentState = this.state.currentState;\n\n if (this.context.debug) {\n logger.info(`[StateMachine] State: ${currentState}, Wave: ${this.state.wave}`);\n }\n\n // Execute current state handler\n await this.executeState(currentState);\n\n // Check for errors\n if (this.state.currentState === 'Error') {\n break;\n }\n }\n\n // Return final results\n return this.buildExecutionResult();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`[StateMachine] Fatal error: ${errorMsg}`);\n const serializedError: SerializedError = {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n name: error instanceof Error ? error.name : undefined,\n };\n this.emitEvent({ type: 'Shutdown', error: serializedError });\n throw error;\n }\n }\n\n /**\n * Execute a specific state handler\n * M4: Wraps each state execution in an OTEL span for observability\n */\n private async executeState(state: EngineState): Promise<void> {\n // M4: Wrap state execution in OTEL span\n return withActiveSpan(\n `engine.state.${state.toLowerCase()}`,\n {\n state: state,\n engine_mode: this.context.mode,\n wave: this.state.wave,\n session_id: this.context.sessionId,\n },\n async () => {\n try {\n switch (state) {\n case 'Init':\n await handleInit(this.context, this.state, this.transition.bind(this));\n break;\n case 'PlanReady':\n await handlePlanReady(this.context, this.state, this.transition.bind(this));\n break;\n case 'WavePlanning':\n await handleWavePlanning(this.context, this.state, this.transition.bind(this));\n break;\n case 'LevelDispatch':\n await handleLevelDispatch(\n this.context,\n this.state,\n this.transition.bind(this),\n this.emitEvent.bind(this)\n );\n break;\n case 'CheckRunning':\n await handleCheckRunning(\n this.context,\n this.state,\n this.transition.bind(this),\n this.emitEvent.bind(this)\n );\n break;\n case 'Routing':\n // Routing is handled inline by CheckRunning for now\n throw new Error('Routing state should be handled by CheckRunning');\n case 'Completed':\n await handleCompleted(this.context, this.state);\n break;\n case 'Error':\n await handleError(this.context, this.state);\n break;\n default:\n throw new Error(`Unknown state: ${state}`);\n }\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`[StateMachine] Error in state ${state}: ${errorMsg}`);\n const serializedError: SerializedError = {\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n name: error instanceof Error ? error.name : undefined,\n };\n this.emitEvent({ type: 'Shutdown', error: serializedError });\n this.state.currentState = 'Error';\n throw error; // Re-throw to trigger span error recording\n }\n }\n );\n }\n\n /**\n * Transition to a new state\n * M4: Emits OTEL span for the transition with state metadata\n */\n private transition(newState: EngineState): void {\n const oldState = this.state.currentState;\n this.state.currentState = newState;\n\n // Emit state transition event\n const transitionEvent = { type: 'StateTransition' as const, from: oldState, to: newState };\n this.emitEvent(transitionEvent);\n\n // M4: Emit OTEL event for state transition\n try {\n addOtelEvent('engine.state_transition', {\n state_from: oldState,\n state_to: newState,\n engine_mode: this.context.mode,\n wave: this.state.wave,\n session_id: this.context.sessionId,\n });\n } catch (_err) {\n // Ignore telemetry errors\n }\n\n if (this.context.debug) {\n logger.info(`[StateMachine] Transition: ${oldState} -> ${newState}`);\n }\n }\n\n /**\n * Emit an engine event\n * M4: Streams events to debug visualizer for time-travel debugging\n */\n private emitEvent(event: EngineEvent): void {\n this.state.historyLog.push(event);\n\n // Queue events that require processing by WavePlanning\n if (event.type === 'ForwardRunRequested' || event.type === 'WaveRetry') {\n this.state.eventQueue.push(event);\n }\n\n // M4: Stream event to debug visualizer for live monitoring\n if (this.debugServer) {\n try {\n this.streamEventToDebugServer(event);\n } catch (_err) {\n // Ignore debug server errors\n }\n }\n\n // Optional: publish to event bus if present in context (no-ops otherwise)\n try {\n const bus: any = (this.context as any).eventBus;\n if (bus && typeof bus.emit === 'function') {\n const envelope: EventEnvelope<EngineEvent> = {\n id: uuidv4(),\n version: 1,\n timestamp: new Date().toISOString(),\n runId: this.context.sessionId,\n workflowId: (this.context as any).workflowId,\n wave: this.state.wave,\n payload: event,\n };\n void bus.emit(envelope);\n }\n } catch {}\n\n if (this.context.debug && event.type !== 'StateTransition') {\n logger.debug(`[StateMachine] Event: ${event.type}`);\n }\n }\n\n /**\n * Stream an engine event to debug visualizer (M4)\n * Converts EngineEvent to ProcessedSpan format for visualization\n */\n private streamEventToDebugServer(event: EngineEvent): void {\n if (!this.debugServer) return;\n\n // Convert EngineEvent to a ProcessedSpan-like structure\n const timestamp = process.hrtime();\n const span = {\n traceId: this.context.sessionId,\n spanId: `${event.type}-${Date.now()}`,\n name: `engine.event.${event.type.toLowerCase()}`,\n startTime: timestamp,\n endTime: timestamp,\n duration: 0,\n attributes: {\n event_type: event.type,\n engine_mode: this.context.mode,\n wave: this.state.wave,\n session_id: this.context.sessionId,\n ...this.extractEventAttributes(event),\n },\n events: [],\n status: 'ok' as const,\n };\n\n this.debugServer.emitSpan(span);\n }\n\n /**\n * Extract type-specific attributes from engine events\n */\n private extractEventAttributes(event: EngineEvent): Record<string, any> {\n switch (event.type) {\n case 'StateTransition':\n return { state_from: event.from, state_to: event.to };\n case 'CheckScheduled':\n case 'CheckCompleted':\n case 'CheckErrored':\n return {\n check_id: event.checkId,\n scope: event.scope?.join('.') || '',\n };\n case 'ForwardRunRequested':\n return {\n target: event.target,\n goto_event: event.gotoEvent,\n scope: event.scope?.join('.') || '',\n };\n case 'WaveRetry':\n return { reason: event.reason };\n case 'Shutdown':\n return {\n error: event.error?.message,\n };\n default:\n return {};\n }\n }\n\n /**\n * Check if a state is terminal\n */\n private isTerminalState(state: EngineState): boolean {\n return state === 'Completed' || state === 'Error';\n }\n\n /**\n * Build the final execution result\n */\n private buildExecutionResult(): ExecutionResult {\n const stats = Array.from(this.state.stats.values());\n // Surface execution errors first for clearer reporting and to satisfy\n // tests that read the first entry for error messages.\n stats.sort((a, b) => (b.errorMessage ? 1 : 0) - (a.errorMessage ? 1 : 0));\n\n // Build results from completed checks by reading from journal\n const results: GroupedCheckResults = this.aggregateResultsFromJournal();\n\n // Aggregate total duration\n let totalDuration = 0;\n for (const stat of stats) {\n totalDuration = Math.max(totalDuration, stat.totalDuration);\n }\n\n // Normalize statistics: ensure successfulRuns + failedRuns == totalRuns\n // The updateStats function in level-dispatch.ts already counts all executions correctly,\n // including forEach iterations, retries, and goto re-runs. We just need to ensure consistency.\n try {\n for (const s of stats) {\n // Final clamp: ensure successfulRuns + failedRuns == totalRuns\n // Prefer to preserve failures and adjust successes accordingly.\n const sumSF = (s.successfulRuns || 0) + (s.failedRuns || 0);\n if (s.totalRuns !== undefined && sumSF !== s.totalRuns) {\n if (sumSF > s.totalRuns) {\n // Too many counted: clamp successes to fill remaining after failures\n const failures = Math.min(s.failedRuns || 0, s.totalRuns);\n s.failedRuns = failures;\n s.successfulRuns = Math.max(0, s.totalRuns - failures);\n } else {\n // Not enough counted: assume remaining were successful\n s.successfulRuns = (s.successfulRuns || 0) + (s.totalRuns - sumSF);\n }\n }\n }\n } catch {}\n\n // Debug: log stats breakdown for debugging\n if (this.context.debug) {\n logger.info('[StateMachine][Stats] Final statistics breakdown:');\n for (const s of stats) {\n logger.info(\n ` ${s.checkName}: totalRuns=${s.totalRuns}, successful=${s.successfulRuns}, failed=${s.failedRuns}`\n );\n }\n logger.info(\n `[StateMachine][Stats] Total: ${this.state.stats.size} configured, ${stats.reduce((sum, s) => sum + s.totalRuns, 0)} executions`\n );\n }\n\n return {\n results,\n statistics: {\n totalChecksConfigured: this.state.stats.size,\n totalExecutions: stats.reduce((sum, s) => sum + s.totalRuns, 0),\n successfulExecutions: stats.reduce((sum, s) => sum + s.successfulRuns, 0),\n failedExecutions: stats.reduce((sum, s) => sum + s.failedRuns, 0),\n skippedChecks: stats.filter(s => s.skipped).length,\n totalDuration,\n checks: stats,\n },\n };\n }\n\n /**\n * Aggregate results from journal into GroupedCheckResults format\n * This matches the format returned by the legacy engine\n */\n private aggregateResultsFromJournal(): GroupedCheckResults {\n const groupedResults: GroupedCheckResults = {};\n\n // Read all journal entries for this session\n const allEntries = this.context.journal.readVisible(\n this.context.sessionId,\n this.context.journal.beginSnapshot(),\n undefined\n );\n\n // Group entries by check ID to handle forEach iterations\n const checkEntries = new Map<string, typeof allEntries>();\n for (const entry of allEntries) {\n const existing = checkEntries.get(entry.checkId) || [];\n existing.push(entry);\n checkEntries.set(entry.checkId, existing);\n }\n\n // Process each check\n for (const [checkId, entries] of checkEntries) {\n const checkConfig = this.context.config.checks?.[checkId];\n\n // Special handling for system errors (validation, cycles, etc.)\n if (!checkConfig && checkId === 'system') {\n const latestEntry = entries[entries.length - 1];\n if (latestEntry && latestEntry.result.issues) {\n // Add system issues to a 'system' group\n if (!groupedResults['system']) {\n groupedResults['system'] = [];\n }\n groupedResults['system'].push({\n checkName: 'system',\n content: '',\n group: 'system',\n output: undefined,\n debug: undefined,\n issues: latestEntry.result.issues,\n });\n }\n continue;\n }\n\n if (!checkConfig) continue;\n\n // Determine group: use explicit group or fall back to check name\n const group = checkConfig.group || checkId;\n\n // For forEach checks, we aggregate all iterations\n // For non-forEach, we take the latest entry\n let content = '';\n let output: unknown = undefined;\n const allIssues: any[] = [];\n let debug: any = undefined;\n\n if (checkConfig.forEach && entries.length > 1) {\n // Aggregate all forEach iterations\n const contents: string[] = [];\n for (const entry of entries) {\n if (entry.result.content) {\n contents.push(entry.result.content);\n }\n if (entry.result.issues) {\n allIssues.push(...entry.result.issues);\n }\n if (entry.result.debug) {\n debug = entry.result.debug;\n }\n // For forEach, output is typically an array from the last iteration\n if (entry.result.output !== undefined) {\n output = entry.result.output;\n }\n }\n content = contents.join('\\n');\n } else {\n // For non-forEach or single-entry forEach, take the latest entry\n const latestEntry = entries[entries.length - 1];\n if (latestEntry) {\n content = latestEntry.result.content || '';\n output = latestEntry.result.output;\n if (latestEntry.result.issues) {\n allIssues.push(...latestEntry.result.issues);\n }\n debug = latestEntry.result.debug;\n }\n }\n\n // Create CheckResult\n const checkResult: import('../reviewer').CheckResult = {\n checkName: checkId,\n content,\n group,\n output,\n debug,\n issues: allIssues,\n };\n\n // Add to appropriate group\n if (!groupedResults[group]) {\n groupedResults[group] = [];\n }\n groupedResults[group].push(checkResult);\n }\n\n // Apply issue suppression if enabled\n const suppressionEnabled = this.context.config.output?.suppressionEnabled ?? true;\n if (suppressionEnabled) {\n const { IssueFilter } = require('../issue-filter');\n const filter = new IssueFilter(true);\n\n // Filter issues in each check result\n for (const group of Object.keys(groupedResults)) {\n for (const checkResult of groupedResults[group]) {\n if (checkResult.issues && checkResult.issues.length > 0) {\n checkResult.issues = filter.filterIssues(\n checkResult.issues,\n this.context.workingDirectory\n );\n }\n }\n }\n }\n\n return groupedResults;\n }\n\n /**\n * Get current run state (for debugging/testing)\n */\n getState(): RunState {\n return this.state;\n }\n\n /**\n * Bubble an event to parent context (nested workflows support)\n * This allows nested workflows to trigger re-runs in parent workflows\n */\n bubbleEventToParent(event: EngineEvent): void {\n if (this.state.parentContext && this.state.parentContext.mode === 'state-machine') {\n // Emit event to parent's event queue\n if (this.context.debug) {\n logger.info(`[StateMachine] Bubbling event to parent: ${event.type}`);\n }\n\n // We need to access the parent runner to bubble events\n // For now, we'll store events in a queue that can be retrieved\n // The parent will poll for bubbled events after child execution\n if (!this.state.parentContext._bubbledEvents) {\n (this.state.parentContext as any)._bubbledEvents = [];\n }\n (this.state.parentContext as any)._bubbledEvents.push(event);\n }\n }\n}\n","import type { VisorConfig, EventTrigger } from '../../types/config';\nimport type { PRInfo } from '../../pr-analyzer';\nimport type { EngineContext, CheckMetadata } from '../../types/engine';\nimport { ExecutionJournal } from '../../snapshot-store';\nimport { MemoryStore } from '../../memory-store';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from '../../logger';\nimport type { VisorConfig as VCfg, CheckConfig as CfgCheck } from '../../types/config';\n\n/**\n * Apply minimal criticality defaults in-place.\n * This is a no-behavior-change scaffold: we only default missing\n * check.criticality to 'policy' so downstream code can rely on a value.\n * Future mapping (retries/loop budgets) can build on this without\n * changing existing behavior.\n */\nfunction applyCriticalityDefaults(cfg: VCfg): void {\n const checks = cfg.checks || {};\n for (const id of Object.keys(checks)) {\n const c: CfgCheck = (checks as any)[id] as CfgCheck;\n if (!c.criticality) (c.criticality as any) = 'policy';\n // For 'info' checks, default continue_on_failure to true if unset.\n if (c.criticality === 'info' && typeof c.continue_on_failure === 'undefined')\n c.continue_on_failure = true;\n }\n}\n\n/**\n * Pure helper to build an EngineContext for a state-machine run.\n * Extracted to reduce StateMachineExecutionEngine size; behavior unchanged.\n */\nexport function buildEngineContextForRun(\n workingDirectory: string,\n config: VisorConfig,\n prInfo: PRInfo,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n requestedChecks?: string[]\n): EngineContext {\n // Deep clone provided config to avoid cross-run mutations between tests/runs\n const clonedConfig: VisorConfig = JSON.parse(JSON.stringify(config));\n\n // Build check metadata\n const checks: Record<string, CheckMetadata> = {};\n\n // Fill in minimal defaults derived from criticality (no behavior change)\n applyCriticalityDefaults(clonedConfig);\n\n // If config has checks, use them\n for (const [checkId, checkConfig] of Object.entries(clonedConfig.checks || {})) {\n checks[checkId] = {\n tags: checkConfig.tags || [],\n triggers: (Array.isArray(checkConfig.on) ? checkConfig.on : [checkConfig.on]).filter(\n Boolean\n ) as EventTrigger[],\n group: checkConfig.group,\n providerType: checkConfig.type || 'ai',\n dependencies: checkConfig.depends_on || [],\n };\n }\n\n // Backward compatibility: synthesize minimal check configs for requested checks\n // that don't exist in the config (e.g., legacy test mode with empty config)\n if (requestedChecks && requestedChecks.length > 0) {\n for (const checkName of requestedChecks) {\n if (!checks[checkName] && !clonedConfig.checks?.[checkName]) {\n // Synthesize a minimal check config for this legacy check name\n logger.debug(`[StateMachine] Synthesizing minimal config for legacy check: ${checkName}`);\n\n // Add to config.checks so providers can find it\n if (!clonedConfig.checks) {\n clonedConfig.checks = {};\n }\n clonedConfig.checks[checkName] = {\n type: 'ai',\n prompt: `Perform ${checkName} analysis`,\n } as any;\n\n // Add metadata\n checks[checkName] = {\n tags: [],\n triggers: [],\n group: 'default',\n providerType: 'ai',\n dependencies: [],\n };\n }\n }\n }\n\n // Initialize journal and memory\n const journal = new ExecutionJournal();\n const memory = MemoryStore.getInstance(clonedConfig.memory);\n\n return {\n mode: 'state-machine',\n config: clonedConfig,\n checks,\n journal,\n memory,\n workingDirectory,\n sessionId: uuidv4(),\n event: prInfo.eventType,\n debug,\n maxParallelism,\n failFast,\n requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : undefined,\n // Store prInfo for later access (e.g., in getOutputHistorySnapshot)\n prInfo,\n };\n}\n","import type { ReviewIssue, GroupedCheckResults, ReviewSummary } from '../../reviewer';\nimport type { ExecutionStatistics } from '../../types/execution';\n\n/**\n * Pure helper to convert grouped results + statistics into a flat ReviewSummary.\n * Extracted to reduce StateMachineExecutionEngine size; behavior unchanged.\n */\nexport function convertToReviewSummary(\n groupedResults: GroupedCheckResults,\n statistics?: ExecutionStatistics\n): ReviewSummary {\n const allIssues: ReviewIssue[] = [];\n\n // Aggregate issues from all check results\n for (const checkResults of Object.values(groupedResults)) {\n for (const checkResult of checkResults) {\n if (checkResult.issues && checkResult.issues.length > 0) {\n allIssues.push(...checkResult.issues);\n }\n }\n }\n\n // Convert errors from execution statistics into issues\n if (statistics) {\n for (const checkStats of statistics.checks) {\n if (checkStats.errorMessage) {\n allIssues.push({\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: 'system/error',\n message: checkStats.errorMessage,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n });\n }\n }\n }\n\n return {\n issues: allIssues,\n };\n}\n","import type { CheckExecutionOptions, ExecutionResult } from './types/execution';\nimport { AnalysisResult } from './output-formatters';\nimport type { VisorConfig } from './types/config';\nimport type { PRInfo } from './pr-analyzer';\nimport { StateMachineRunner } from './state-machine/runner';\nimport type { EngineContext } from './types/engine';\nimport { ExecutionJournal } from './snapshot-store';\nimport { logger } from './logger';\nimport type { DebugVisualizerServer } from './debug-visualizer/ws-server';\n\n/**\n * State machine-based execution engine\n *\n * Production-ready state machine implementation with full observability support.\n * M4: Includes OTEL telemetry and debug visualizer event streaming.\n */\nexport class StateMachineExecutionEngine {\n private workingDirectory: string;\n private executionContext?: import('./providers/check-provider.interface').ExecutionContext;\n private debugServer?: DebugVisualizerServer;\n private _lastContext?: EngineContext;\n private _lastRunner?: StateMachineRunner;\n\n constructor(\n workingDirectory?: string,\n octokit?: import('@octokit/rest').Octokit,\n debugServer?: DebugVisualizerServer\n ) {\n this.workingDirectory = workingDirectory || process.cwd();\n this.debugServer = debugServer;\n }\n\n /**\n * Execute checks using the state machine engine\n *\n * Converts CheckExecutionOptions -> executeGroupedChecks() -> AnalysisResult\n */\n async executeChecks(options: CheckExecutionOptions): Promise<AnalysisResult> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n try {\n // Initialize memory store if configured\n if (options.config?.memory) {\n const { MemoryStore } = await import('./memory-store');\n const memoryStore = MemoryStore.getInstance(options.config.memory);\n await memoryStore.initialize();\n logger.debug('Memory store initialized');\n }\n\n // Analyze the repository\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const gitAnalyzer = new GitRepositoryAnalyzer(options.workingDirectory);\n logger.info('Analyzing local git repository...');\n const repositoryInfo = await gitAnalyzer.analyzeRepository();\n\n if (!repositoryInfo.isGitRepository) {\n return this.createErrorResult(\n repositoryInfo,\n 'Not a git repository or no changes found',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // Convert to PRInfo format for compatibility\n const prInfo = gitAnalyzer.toPRInfo(repositoryInfo);\n\n // Propagate event type if provided\n try {\n const evt = (options.webhookContext as any)?.eventType;\n if (evt) (prInfo as any).eventType = evt;\n } catch {}\n\n // Apply tag filtering if specified\n const filteredChecks = this.filterChecksByTags(\n options.checks,\n options.config,\n options.tagFilter || options.config?.tag_filter\n );\n\n if (filteredChecks.length === 0) {\n logger.warn('No checks match the tag filter criteria');\n return this.createErrorResult(\n repositoryInfo,\n 'No checks match the tag filter criteria',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // Execute checks using state machine\n logger.info(`Executing checks: ${filteredChecks.join(', ')}`);\n const executionResult = await this.executeGroupedChecks(\n prInfo,\n filteredChecks,\n options.timeout,\n options.config,\n options.outputFormat,\n options.debug,\n options.maxParallelism,\n options.failFast,\n options.tagFilter\n );\n\n // Convert ExecutionResult to AnalysisResult format\n const executionTime = Date.now() - startTime;\n\n // Extract review summary from grouped results\n const reviewSummary = this.convertGroupedResultsToReviewSummary(\n executionResult.results,\n executionResult.statistics\n );\n\n // Collect debug information when debug mode is enabled\n let debugInfo: import('./output-formatters').DebugInfo | undefined;\n if (options.debug && reviewSummary.debug) {\n debugInfo = {\n provider: reviewSummary.debug.provider,\n model: reviewSummary.debug.model,\n processingTime: reviewSummary.debug.processingTime,\n parallelExecution: options.checks.length > 1,\n checksExecuted: options.checks,\n totalApiCalls: reviewSummary.debug.totalApiCalls || options.checks.length,\n apiCallDetails: reviewSummary.debug.apiCallDetails,\n };\n }\n\n // Expose output history snapshot\n try {\n const histSnap = this.getOutputHistorySnapshot();\n (reviewSummary as any).history = histSnap;\n } catch {}\n\n return {\n repositoryInfo,\n reviewSummary,\n executionTime,\n timestamp,\n checksExecuted: filteredChecks,\n executionStatistics: executionResult.statistics,\n debug: debugInfo,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error occurred';\n logger.error('Error executing checks: ' + message);\n\n // In strict test modes, surface errors to callers\n const strictEnv = process.env.VISOR_STRICT_ERRORS === 'true';\n if (strictEnv) {\n throw error;\n }\n\n const fallbackRepositoryInfo: import('./git-repository-analyzer').GitRepositoryInfo = {\n title: 'Error during analysis',\n body: `Error: ${message || 'Unknown error'}`,\n author: 'system',\n base: 'main',\n head: 'HEAD',\n files: [],\n totalAdditions: 0,\n totalDeletions: 0,\n isGitRepository: false,\n workingDirectory: options.workingDirectory || process.cwd(),\n };\n\n return this.createErrorResult(\n fallbackRepositoryInfo,\n message || 'Unknown error occurred',\n startTime,\n timestamp,\n options.checks\n );\n }\n }\n\n /**\n * Get execution context (used by state machine to propagate hooks)\n */\n protected getExecutionContext():\n | import('./providers/check-provider.interface').ExecutionContext\n | undefined {\n return this.executionContext;\n }\n\n /**\n * Set execution context for external callers\n */\n public setExecutionContext(\n context: import('./providers/check-provider.interface').ExecutionContext | undefined\n ): void {\n this.executionContext = context;\n }\n\n /**\n * Reset per-run state (no-op for state machine engine)\n *\n * The state machine engine is stateless per-run by design.\n * Each execution creates a fresh journal and context.\n * This method exists only for backward compatibility with test framework.\n *\n * @deprecated This is a no-op. State machine engine doesn't maintain per-run state.\n */\n public resetPerRunState(): void {\n // No-op: State machine engine is stateless per-run\n // Each execution creates a fresh journal and context\n }\n\n /**\n * Execute grouped checks using the state machine engine\n *\n * M4: Production-ready with full telemetry and debug server support\n */\n async executeGroupedChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: VisorConfig,\n outputFormat?: string,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n tagFilter?: import('./types/config').TagFilter,\n _pauseGate?: () => Promise<void>\n ): Promise<ExecutionResult> {\n if (debug) {\n logger.info('[StateMachine] Using state machine engine');\n }\n\n // Create minimal default config if none provided (backward compatibility)\n if (!config) {\n const { ConfigManager } = await import('./config');\n const configManager = new ConfigManager();\n config = await configManager.getDefaultConfig();\n logger.debug('[StateMachine] Using default configuration (no config provided)');\n }\n\n // Merge tagFilter into config if provided (test runner passes it separately)\n const configWithTagFilter = tagFilter\n ? {\n ...config,\n tag_filter: tagFilter,\n }\n : config;\n\n // Build engine context\n const context = this.buildEngineContext(\n configWithTagFilter,\n prInfo,\n debug,\n maxParallelism,\n failFast,\n checks // Pass the explicit checks list\n );\n\n // Copy execution context (hooks, etc.) from legacy engine\n context.executionContext = this.getExecutionContext();\n\n // Store context for later access (e.g., getOutputHistorySnapshot)\n this._lastContext = context;\n\n // Optionally enable event-driven frontends if configured\n let frontendsHost: any | undefined;\n if (\n Array.isArray((configWithTagFilter as any).frontends) &&\n (configWithTagFilter as any).frontends.length > 0\n ) {\n try {\n const { EventBus } = await import('./event-bus/event-bus');\n const { FrontendsHost } = await import('./frontends/host');\n const bus = new EventBus();\n (context as any).eventBus = bus;\n frontendsHost = new FrontendsHost(bus, logger);\n await frontendsHost.load((configWithTagFilter as any).frontends);\n // Derive repo/pr/headSha and octokit if available\n let owner: string | undefined;\n let name: string | undefined;\n let prNum: number | undefined;\n let headSha: string | undefined;\n try {\n const anyInfo: any = prInfo as any;\n owner =\n anyInfo?.eventContext?.repository?.owner?.login ||\n process.env.GITHUB_REPOSITORY?.split('/')?.[0];\n name =\n anyInfo?.eventContext?.repository?.name ||\n process.env.GITHUB_REPOSITORY?.split('/')?.[1];\n prNum = typeof anyInfo?.number === 'number' ? anyInfo.number : undefined;\n headSha = anyInfo?.eventContext?.pull_request?.head?.sha || process.env.GITHUB_SHA;\n } catch {}\n const repoObj = owner && name ? { owner, name } : undefined;\n const octokit = (this.executionContext as any)?.octokit;\n // Fallback: if headSha is missing but we have PR info and octokit, fetch it\n if (\n !headSha &&\n repoObj &&\n prNum &&\n octokit &&\n typeof octokit.rest?.pulls?.get === 'function'\n ) {\n try {\n const { data } = await octokit.rest.pulls.get({\n owner: repoObj.owner,\n repo: repoObj.name,\n pull_number: prNum,\n });\n headSha = (data && (data as any).head && (data as any).head.sha) || headSha;\n } catch {\n // ignore; headSha remains undefined\n }\n }\n await frontendsHost.startAll(() => ({\n eventBus: bus,\n logger,\n // Provide the active (possibly tag-filtered) config so frontends can read groups, etc.\n config: configWithTagFilter,\n run: {\n runId: (context as any).sessionId,\n repo: repoObj,\n pr: prNum,\n headSha,\n event: (context as any).event || (prInfo as any)?.eventType,\n actor:\n (prInfo as any)?.eventContext?.sender?.login ||\n (typeof process.env.GITHUB_ACTOR === 'string' ? process.env.GITHUB_ACTOR : undefined),\n },\n octokit,\n }));\n } catch (err) {\n logger.warn(\n `[Frontends] Failed to initialize frontends: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // Create and run state machine with debug server support (M4)\n const runner = new StateMachineRunner(context, this.debugServer);\n this._lastRunner = runner;\n const result = await runner.run();\n\n // Stop frontends if started\n if (frontendsHost && typeof frontendsHost.stopAll === 'function') {\n try {\n await frontendsHost.stopAll();\n } catch {}\n }\n\n if (debug) {\n logger.info('[StateMachine] Execution complete');\n }\n\n // Post-grouped comments via legacy reviewer is removed; GitHub frontend handles comments\n\n // Cleanup AI sessions after execution\n try {\n const { SessionRegistry } = await import('./session-registry');\n const sessionRegistry = SessionRegistry.getInstance();\n sessionRegistry.clearAllSessions();\n } catch (error) {\n logger.debug(`[StateMachine] Failed to cleanup sessions: ${error}`);\n }\n\n return result;\n }\n\n /**\n * Build the engine context for state machine execution\n */\n private buildEngineContext(\n config: VisorConfig,\n prInfo: PRInfo,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n requestedChecks?: string[]\n ): EngineContext {\n const { buildEngineContextForRun } = require('./state-machine/context/build-engine-context');\n return buildEngineContextForRun(\n this.workingDirectory,\n config,\n prInfo,\n debug,\n maxParallelism,\n failFast,\n requestedChecks\n );\n }\n\n /**\n * Get output history snapshot for test framework compatibility\n * Extracts output history from the journal\n */\n public getOutputHistorySnapshot(): Record<string, unknown[]> {\n // Get the journal from the last execution context\n const journal = (this as any)._lastContext?.journal as ExecutionJournal | undefined;\n if (!journal) {\n logger.debug('[StateMachine][DEBUG] getOutputHistorySnapshot: No journal found');\n return {};\n }\n\n const sessionId = (this as any)._lastContext?.sessionId as string | undefined;\n if (!sessionId) {\n logger.debug('[StateMachine][DEBUG] getOutputHistorySnapshot: No sessionId found');\n return {};\n }\n\n // Read all journal entries for this session\n const snapshot = journal.beginSnapshot();\n const allEntries = journal.readVisible(sessionId, snapshot, undefined);\n\n logger.debug(\n `[StateMachine][DEBUG] getOutputHistorySnapshot: Found ${allEntries.length} journal entries`\n );\n\n // Group by checkId and extract outputs\n const outputHistory: Record<string, unknown[]> = {};\n for (const entry of allEntries) {\n const checkId = entry.checkId;\n\n if (!outputHistory[checkId]) {\n outputHistory[checkId] = [];\n }\n // Skip journal stubs for skipped checks\n try {\n if (entry && typeof entry.result === 'object' && (entry.result as any).__skipped) {\n continue;\n }\n } catch {}\n\n // Prefer explicit .output; fall back to the full result (issues/content)\n // so tests and templates can reference paths like issues[0].severity for\n // code-review schema steps which do not set a separate output object.\n const payload =\n entry.result.output !== undefined ? entry.result.output : (entry.result as unknown);\n\n // Filter out forEach aggregation metadata objects (which contain a\n // forEachItems array) to avoid double-counting per-item executions in\n // tests. The actual per-item outputs are committed as separate entries\n // and should be used for history-based assertions and routing.\n try {\n if (\n payload &&\n typeof payload === 'object' &&\n (payload as any).forEachItems &&\n Array.isArray((payload as any).forEachItems)\n ) {\n continue;\n }\n } catch {}\n\n if (payload !== undefined) outputHistory[checkId].push(payload);\n }\n\n logger.debug(\n `[StateMachine][DEBUG] getOutputHistorySnapshot result: ${JSON.stringify(Object.keys(outputHistory))}`\n );\n for (const [checkId, outputs] of Object.entries(outputHistory)) {\n logger.debug(`[StateMachine][DEBUG] ${checkId}: ${outputs.length} outputs`);\n }\n\n return outputHistory;\n }\n\n /**\n * Save a JSON snapshot of the last run's state and journal to a file (experimental).\n * Does not include secrets. Intended for debugging and future resume support.\n */\n public async saveSnapshotToFile(filePath: string): Promise<void> {\n const fs = await import('fs/promises');\n const ctx = this._lastContext;\n const runner = this._lastRunner;\n if (!ctx || !runner) {\n throw new Error('No prior execution context to snapshot');\n }\n const journal = (ctx as any).journal as ExecutionJournal;\n const snapshotId = journal.beginSnapshot();\n const entries = journal.readVisible(ctx.sessionId, snapshotId, undefined);\n const state = runner.getState();\n const serializableState = serializeRunState(state);\n const payload = {\n version: 1,\n sessionId: ctx.sessionId,\n event: ctx.event,\n wave: state.wave,\n state: serializableState,\n journal: entries,\n requestedChecks: (ctx as any).requestedChecks || [],\n } as const;\n await fs.writeFile(filePath, JSON.stringify(payload, null, 2), 'utf8');\n }\n\n /**\n * Load a snapshot JSON from file and return it. Resume support can build on this.\n */\n public async loadSnapshotFromFile<T = unknown>(filePath: string): Promise<T> {\n const fs = await import('fs/promises');\n const raw = await fs.readFile(filePath, 'utf8');\n return JSON.parse(raw) as T;\n }\n\n /**\n * Filter checks by tag filter\n */\n private filterChecksByTags(\n checks: string[],\n config: VisorConfig | undefined,\n tagFilter: import('./types/config').TagFilter | undefined\n ): string[] {\n // When no tag filter is specified, include only untagged checks by default.\n // Tagged checks are opt-in unless tag_filter is provided.\n return checks.filter(checkName => {\n const checkConfig = config?.checks?.[checkName];\n if (!checkConfig) {\n // If no config for this check, include it by default\n return true;\n }\n\n const checkTags = checkConfig.tags || [];\n\n // If no tag filter is specified, include only untagged checks.\n if (!tagFilter || (!tagFilter.include && !tagFilter.exclude)) {\n return checkTags.length === 0;\n }\n\n // If check has no tags and a tag filter is specified, include it (untagged checks always run)\n if (checkTags.length === 0) {\n return true;\n }\n\n // Check exclude tags first (if any exclude tag matches, skip the check)\n if (tagFilter.exclude && tagFilter.exclude.length > 0) {\n const hasExcludedTag = tagFilter.exclude.some(tag => checkTags.includes(tag));\n if (hasExcludedTag) return false;\n }\n\n // Check include tags (if specified, at least one must match)\n if (tagFilter.include && tagFilter.include.length > 0) {\n const hasIncludedTag = tagFilter.include.some(tag => checkTags.includes(tag));\n if (!hasIncludedTag) return false;\n }\n\n return true;\n });\n }\n\n /**\n * Create an error result in AnalysisResult format\n */\n private createErrorResult(\n repositoryInfo: import('./git-repository-analyzer').GitRepositoryInfo,\n errorMessage: string,\n startTime: number,\n timestamp: string,\n checksExecuted: string[]\n ): AnalysisResult {\n const executionTime = Date.now() - startTime;\n\n return {\n repositoryInfo,\n reviewSummary: {\n issues: [\n {\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: 'system/error',\n message: errorMessage,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n },\n executionTime,\n timestamp,\n checksExecuted,\n };\n }\n\n /**\n * Convert GroupedCheckResults to ReviewSummary\n * Aggregates all check results into a single ReviewSummary\n */\n private convertGroupedResultsToReviewSummary(\n groupedResults: import('./reviewer').GroupedCheckResults,\n statistics?: import('./types/execution').ExecutionStatistics\n ): import('./reviewer').ReviewSummary {\n const { convertToReviewSummary } = require('./state-machine/execution/summary');\n return (convertToReviewSummary as any)(groupedResults as any, statistics as any) as any;\n }\n\n /**\n * Evaluate failure conditions for a check result\n *\n * This method provides backward compatibility with the legacy engine by\n * delegating to the FailureConditionEvaluator.\n *\n * @param checkName - The name of the check being evaluated\n * @param reviewSummary - The review summary containing check results\n * @param config - The Visor configuration containing failure conditions\n * @param previousOutputs - Optional previous check outputs for cross-check conditions\n * @param authorAssociation - Optional GitHub author association for permission checks\n * @returns Array of failure condition evaluation results\n */\n async evaluateFailureConditions(\n checkName: string,\n reviewSummary: import('./reviewer').ReviewSummary,\n config: VisorConfig,\n previousOutputs?: Record<string, import('./reviewer').ReviewSummary>,\n authorAssociation?: string\n ): Promise<import('./types/config').FailureConditionResult[]> {\n const { FailureConditionEvaluator } = await import('./failure-condition-evaluator');\n const evaluator = new FailureConditionEvaluator();\n const { addEvent } = await import('./telemetry/trace-helpers');\n const { addFailIfTriggered } = await import('./telemetry/metrics');\n\n // Extract check configuration\n const checkConfig = config.checks?.[checkName];\n if (!checkConfig) {\n return [];\n }\n\n // Schema can be string or Record<string, unknown>, convert to string for evaluation\n const rawSchema = checkConfig.schema || 'code-review';\n const checkSchema = typeof rawSchema === 'string' ? rawSchema : 'code-review';\n const checkGroup = checkConfig.group || 'default';\n\n // Handle both fail_if (simple string) and failure_conditions (complex object)\n const results: import('./types/config').FailureConditionResult[] = [];\n\n // Evaluate global fail_if\n if (config.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n config.fail_if,\n previousOutputs || {}\n );\n\n // Telemetry events + metric\n try {\n addEvent('fail_if.evaluated', {\n 'visor.check.id': checkName,\n scope: 'global',\n expression: String(config.fail_if),\n result: failed ? 'triggered' : 'not_triggered',\n });\n if (failed) {\n addEvent('fail_if.triggered', {\n 'visor.check.id': checkName,\n scope: 'global',\n expression: String(config.fail_if),\n });\n addFailIfTriggered(checkName, 'global');\n }\n } catch {}\n\n results.push({\n conditionName: 'global_fail_if',\n failed,\n expression: config.fail_if,\n message: failed ? `Global failure condition met: ${config.fail_if}` : undefined,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n // Evaluate check-specific fail_if (overrides global if present)\n if (checkConfig.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n checkConfig.fail_if,\n previousOutputs || {}\n );\n\n // Telemetry events + metric\n try {\n addEvent('fail_if.evaluated', {\n 'visor.check.id': checkName,\n scope: 'check',\n expression: String(checkConfig.fail_if),\n result: failed ? 'triggered' : 'not_triggered',\n });\n if (failed) {\n addEvent('fail_if.triggered', {\n 'visor.check.id': checkName,\n scope: 'check',\n expression: String(checkConfig.fail_if),\n });\n addFailIfTriggered(checkName, 'check');\n }\n } catch {}\n\n results.push({\n conditionName: `${checkName}_fail_if`,\n failed,\n expression: checkConfig.fail_if,\n message: failed ? `Check failure condition met: ${checkConfig.fail_if}` : undefined,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n // Also evaluate legacy failure_conditions if present\n const globalConditions = config.failure_conditions;\n const checkConditions = checkConfig.failure_conditions;\n\n if (globalConditions || checkConditions) {\n const legacyResults = await evaluator.evaluateConditions(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n globalConditions,\n checkConditions,\n previousOutputs,\n authorAssociation\n );\n results.push(...legacyResults);\n }\n\n return results;\n }\n\n /**\n * Get repository status\n * @returns Repository status information\n */\n async getRepositoryStatus(): Promise<{\n isGitRepository: boolean;\n branch?: string;\n hasChanges: boolean;\n filesChanged?: number;\n }> {\n try {\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const analyzer = new GitRepositoryAnalyzer(this.workingDirectory);\n const info = await analyzer.analyzeRepository();\n\n return {\n isGitRepository: info.isGitRepository,\n branch: info.head, // Use head as branch name\n hasChanges: info.isGitRepository && (info.files?.length > 0 || false),\n filesChanged: info.isGitRepository ? info.files?.length || 0 : 0,\n };\n } catch {\n return {\n isGitRepository: false,\n hasChanges: false,\n };\n }\n }\n\n /**\n * Check if current directory is a git repository\n * @returns True if git repository, false otherwise\n */\n async isGitRepository(): Promise<boolean> {\n const status = await this.getRepositoryStatus();\n return status.isGitRepository;\n }\n\n /**\n * Get list of available check types\n * @returns Array of check type names\n */\n static getAvailableCheckTypes(): string[] {\n const { CheckProviderRegistry } = require('./providers/check-provider-registry');\n const registry = CheckProviderRegistry.getInstance();\n return registry.getAvailableProviders();\n }\n\n /**\n * Validate check types and return valid/invalid lists\n * @param checks - Array of check type names to validate\n * @returns Object with valid and invalid check types\n */\n static validateCheckTypes(checks: string[]): { valid: string[]; invalid: string[] } {\n const availableTypes = StateMachineExecutionEngine.getAvailableCheckTypes();\n const valid: string[] = [];\n const invalid: string[] = [];\n\n for (const check of checks) {\n if (availableTypes.includes(check)) {\n valid.push(check);\n } else {\n invalid.push(check);\n }\n }\n\n return { valid, invalid };\n }\n\n /**\n * Render check content using the appropriate template\n *\n * This method handles template rendering for check results, supporting:\n * - Plain schema: returns raw content without template processing\n * - Custom templates: from inline content or file\n * - Built-in schema templates: from output/{schema}/template.liquid\n */\n private async renderCheckContent(\n checkName: string,\n reviewSummary: import('./reviewer').ReviewSummary,\n checkConfig: any,\n _prInfo?: PRInfo\n ): Promise<string> {\n // Import the liquid template system\n const { createExtendedLiquid } = await import('./liquid-extensions');\n const fs = await import('fs/promises');\n const path = await import('path');\n\n // Determine template to use\n const schema = checkConfig.schema || 'plain';\n let templateContent: string | undefined;\n\n if (checkConfig.template) {\n // Custom template\n if (checkConfig.template.content) {\n templateContent = checkConfig.template.content;\n } else if (checkConfig.template.file) {\n // Validate template file path for security\n const templateFile = checkConfig.template.file;\n\n // Check for absolute paths\n if (path.isAbsolute(templateFile)) {\n throw new Error('Template path must be relative to project directory');\n }\n\n // Check for .. segments\n if (templateFile.includes('..')) {\n throw new Error('Template path cannot contain \"..\" segments');\n }\n\n // Check for home directory references\n if (templateFile.startsWith('~')) {\n throw new Error('Template path cannot reference home directory');\n }\n\n // Check for null bytes\n if (templateFile.includes('\\0')) {\n throw new Error('Template path contains invalid characters');\n }\n\n // Check for whitespace-only paths\n if (templateFile.trim() === '') {\n throw new Error('Template path must be a non-empty string');\n }\n\n // Check for .liquid extension\n if (!templateFile.endsWith('.liquid')) {\n throw new Error('Template file must have .liquid extension');\n }\n\n // Resolve path relative to working directory\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const gitAnalyzer = new GitRepositoryAnalyzer(this.workingDirectory);\n const repoInfo = await gitAnalyzer.analyzeRepository();\n const workingDir = repoInfo.workingDirectory;\n\n const resolvedPath = path.resolve(workingDir, templateFile);\n templateContent = await fs.readFile(resolvedPath, 'utf-8');\n } else {\n throw new Error('Custom template must specify either \"file\" or \"content\"');\n }\n } else if (schema === 'plain') {\n // Plain schema - return raw content directly\n return reviewSummary.issues?.[0]?.message || '';\n } else {\n // Use built-in schema template\n const sanitizedSchema = schema.replace(/[^a-zA-Z0-9-]/g, '');\n if (!sanitizedSchema) {\n throw new Error('Invalid schema name');\n }\n // When bundled with ncc, __dirname is dist/ and output/ is at dist/output/\n // When running from source, __dirname varies based on build location\n const candidatePaths = [\n path.join(__dirname, `output/${sanitizedSchema}/template.liquid`), // bundled: dist/output/\n path.join(__dirname, '..', `output/${sanitizedSchema}/template.liquid`), // source fallback\n path.join(process.cwd(), `output/${sanitizedSchema}/template.liquid`), // cwd/output/\n path.join(process.cwd(), `dist/output/${sanitizedSchema}/template.liquid`), // cwd/dist/output/\n ];\n\n for (const templatePath of candidatePaths) {\n try {\n const content = await fs.readFile(templatePath, 'utf-8');\n if (content) {\n templateContent = content;\n break;\n }\n } catch {\n // try next\n }\n }\n\n if (!templateContent) {\n throw new Error(`Template not found for schema: ${sanitizedSchema}`);\n }\n }\n\n if (!templateContent) {\n throw new Error('No template content available');\n }\n\n // Create liquid instance with extended functionality\n const liquid = createExtendedLiquid({\n trimTagLeft: false,\n trimTagRight: false,\n trimOutputLeft: false,\n trimOutputRight: false,\n greedy: false,\n });\n\n // Prepare template data\n const templateData = {\n issues: reviewSummary.issues || [],\n checkName: checkName,\n };\n\n const rendered = await liquid.parseAndRender(templateContent, templateData);\n return rendered.trim();\n }\n\n /**\n * Format the status column for execution statistics\n * Used by execution-statistics-formatting tests\n */\n private formatStatusColumn(stats: import('./types/execution').CheckExecutionStats): string {\n if (stats.skipped) {\n // Format skip reason\n if (stats.skipReason === 'if_condition') {\n return '⏭ if';\n } else if (stats.skipReason === 'fail_fast') {\n return '⏭ ff';\n } else if (stats.skipReason === 'dependency_failed') {\n return '⏭ dep';\n }\n return '⏭';\n }\n\n const totalRuns = stats.totalRuns;\n const successfulRuns = stats.successfulRuns;\n const failedRuns = stats.failedRuns;\n\n if (failedRuns > 0 && successfulRuns > 0) {\n // Mixed results\n return `✔/✖ ${successfulRuns}/${totalRuns}`;\n } else if (failedRuns > 0) {\n // All failed\n return totalRuns === 1 ? '✖' : `✖ ×${totalRuns}`;\n } else {\n // All successful\n return totalRuns === 1 ? '✔' : `✔ ×${totalRuns}`;\n }\n }\n\n /**\n * Format the details column for execution statistics\n * Used by execution-statistics-formatting tests\n */\n private formatDetailsColumn(stats: import('./types/execution').CheckExecutionStats): string {\n const parts: string[] = [];\n\n // Add outputs produced\n if (stats.outputsProduced !== undefined && stats.outputsProduced > 0) {\n parts.push(`→${stats.outputsProduced}`);\n }\n\n // Add critical issues\n if (stats.issuesBySeverity.critical > 0) {\n parts.push(`${stats.issuesBySeverity.critical}🔴`);\n }\n\n // Add error issues (only if no critical)\n if (stats.issuesBySeverity.error > 0 && stats.issuesBySeverity.critical === 0) {\n parts.push(`${stats.issuesBySeverity.error}❌`);\n }\n\n // Add warnings\n if (stats.issuesBySeverity.warning > 0) {\n parts.push(`${stats.issuesBySeverity.warning}⚠️`);\n }\n\n // Add info issues (only if no critical/error/warning)\n if (\n stats.issuesBySeverity.info > 0 &&\n stats.issuesBySeverity.critical === 0 &&\n stats.issuesBySeverity.error === 0 &&\n stats.issuesBySeverity.warning === 0\n ) {\n parts.push(`${stats.issuesBySeverity.info}💡`);\n }\n\n // Add error message if present\n if (stats.errorMessage) {\n parts.push(this.truncate(stats.errorMessage, 40));\n }\n\n // Add skip condition if present\n if (stats.skipCondition) {\n parts.push(this.truncate(stats.skipCondition, 40));\n }\n\n return parts.join(' ');\n }\n\n /**\n * Truncate a string to a maximum length\n * Used by formatDetailsColumn\n */\n private truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength - 3) + '...';\n }\n}\n\n/** Convert RunState with Maps/Sets into a JSON-safe form */\nfunction serializeRunState(state: import('./types/engine').RunState) {\n return {\n ...state,\n levelQueue: state.levelQueue,\n eventQueue: state.eventQueue,\n activeDispatches: Array.from(state.activeDispatches.entries()),\n completedChecks: Array.from(state.completedChecks.values()),\n stats: Array.from(state.stats.entries()),\n historyLog: state.historyLog,\n forwardRunGuards: Array.from(state.forwardRunGuards.values()),\n currentLevelChecks: Array.from(state.currentLevelChecks.values()),\n pendingRunScopes: Array.from((state.pendingRunScopes || new Map()).entries()).map(([k, v]) => [\n k,\n v,\n ]),\n };\n}\n","/*\n Thin SDK façade for programmatic use of Visor.\n - No new execution logic; delegates to existing engine and config manager.\n - Dual ESM/CJS bundle via tsup.\n*/\n\nimport { StateMachineExecutionEngine } from './state-machine-execution-engine';\nimport { ConfigManager } from './config';\nimport type { AnalysisResult } from './output-formatters';\nimport type { VisorConfig, TagFilter, HumanInputRequest } from './types/config';\nimport type { ExecutionContext } from './providers/check-provider.interface';\n\nexport type { VisorConfig, TagFilter, HumanInputRequest, ExecutionContext };\n\nexport interface VisorOptions {\n cwd?: string;\n debug?: boolean;\n maxParallelism?: number;\n failFast?: boolean;\n tagFilter?: TagFilter;\n}\n\nexport interface RunOptions extends VisorOptions {\n config?: VisorConfig;\n configPath?: string;\n checks?: string[]; // default: all checks from config\n timeoutMs?: number;\n output?: { format?: 'table' | 'json' | 'markdown' | 'sarif' };\n /** Strict mode: treat config warnings (like unknown keys) as errors (default: false) */\n strictValidation?: boolean;\n /** Execution context for providers (CLI message, hooks, etc.) */\n executionContext?: ExecutionContext;\n}\n\n/**\n * Load and validate a Visor config.\n * @param configOrPath - Config object, file path, or omit to discover defaults\n * @param options - Validation options\n * @returns Validated config with defaults applied\n */\nexport async function loadConfig(\n configOrPath?: string | Partial<VisorConfig>,\n options?: { strict?: boolean }\n): Promise<VisorConfig> {\n const cm = new ConfigManager();\n\n // If it's an object, validate and return with defaults\n if (typeof configOrPath === 'object' && configOrPath !== null) {\n cm.validateConfig(configOrPath, options?.strict ?? false);\n\n // Apply lightweight defaults without expensive file system operations\n const defaultConfig: Partial<VisorConfig> = {\n version: '1.0',\n checks: {},\n max_parallelism: 3,\n fail_fast: false,\n };\n\n return {\n ...defaultConfig,\n ...configOrPath,\n checks: configOrPath.checks || {},\n } as VisorConfig;\n }\n\n // If it's a string, load from file\n if (typeof configOrPath === 'string') {\n return cm.loadConfig(configOrPath);\n }\n\n // Otherwise discover default config file\n return cm.findAndLoadConfig();\n}\n\n/** Expand check IDs by including their dependencies (shallow->deep). */\nexport function resolveChecks(checkIds: string[], config: VisorConfig | undefined): string[] {\n if (!config?.checks) return Array.from(new Set(checkIds));\n const resolved = new Set<string>();\n const visiting = new Set<string>();\n const result: string[] = [];\n\n const dfs = (id: string, stack: string[] = []) => {\n if (resolved.has(id)) return;\n if (visiting.has(id)) {\n const cycle = [...stack, id].join(' -> ');\n throw new Error(`Circular dependency detected involving check: ${id} (path: ${cycle})`);\n }\n visiting.add(id);\n const deps = config.checks![id]?.depends_on || [];\n for (const d of deps) dfs(d, [...stack, id]);\n if (!result.includes(id)) result.push(id);\n visiting.delete(id);\n resolved.add(id);\n };\n\n for (const id of checkIds) dfs(id);\n return result;\n}\n\n/**\n * Run Visor checks programmatically. Returns the same AnalysisResult shape used by the CLI.\n * Thin wrapper around CheckExecutionEngine.executeChecks.\n */\nexport async function runChecks(opts: RunOptions = {}): Promise<AnalysisResult> {\n const cm = new ConfigManager();\n let config: VisorConfig;\n\n if (opts.config) {\n // Validate manually constructed config\n // In strict mode, unknown keys are treated as errors\n cm.validateConfig(opts.config, opts.strictValidation ?? false);\n config = opts.config;\n } else if (opts.configPath) {\n config = await cm.loadConfig(opts.configPath);\n } else {\n config = await cm.findAndLoadConfig();\n }\n\n const checks =\n opts.checks && opts.checks.length > 0\n ? resolveChecks(opts.checks, config)\n : Object.keys(config.checks || {});\n\n // Always use StateMachineExecutionEngine\n const engine = new StateMachineExecutionEngine(opts.cwd);\n\n // Set execution context if provided\n if (opts.executionContext) {\n engine.setExecutionContext(opts.executionContext);\n }\n\n const result = await engine.executeChecks({\n checks,\n workingDirectory: opts.cwd,\n timeout: opts.timeoutMs,\n maxParallelism: opts.maxParallelism,\n failFast: opts.failFast,\n outputFormat: opts.output?.format,\n config,\n debug: opts.debug,\n tagFilter: opts.tagFilter,\n });\n\n return result;\n}\n"],"mappings":"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","names":["context","context","context","path","fs","context","triggeringComment","fs","path","agentAny","result","resolve","fs","path","content","lines","context","fs","path","emitNdjsonSpanWithEvents","SessionRegistry","context","context","getGlobalRecorder","arr","fs","path","resolve","context","emitNdjsonSpanWithEvents","captureLiquidEvaluation","arr","buildSandboxEnv","context","key","context","context","context","buildSandboxEnv","resolve","resolve","fs","path","buildSandboxEnv","context","context","Liquid","context","summary","projectWorkflowToGraph","validateWorkflowDepth","StateMachineRunner","ExecutionJournal","MemoryStore","uuidv4","path","fs","ConfigManager","context","iterationDurationMs","Ajv","snapshotId","checkConfig","forEachItems","currentWaveCompletions","createExtendedLiquid","fs","path","context","context","context","IssueFilter","uuidv4","MemoryStore","context","ConfigManager","SessionRegistry","buildEngineContextForRun","fs","convertToReviewSummary","FailureConditionEvaluator","addEvent","CheckProviderRegistry","createExtendedLiquid","path"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/workspace-manager.ts","../../src/state-machine/context/build-engine-context.ts","../../src/state-machine/execution/summary.ts","../../src/state-machine-execution-engine.ts","../../src/sdk.ts"],"sourcesContent":["/**\n * Workspace Manager\n *\n * Provides full isolation between parallel visor runs with human-readable project names.\n * Each run gets its own workspace in /tmp containing worktrees for all projects.\n */\n\nimport * as fsp from 'fs/promises';\nimport * as path from 'path';\nimport { commandExecutor } from './command-executor';\nimport { logger } from '../logger';\n\n/**\n * Escape a string for safe use in shell commands.\n * Uses single quotes and escapes any embedded single quotes.\n */\nfunction shellEscape(str: string): string {\n // Replace single quotes with '\\'' (end quote, escaped quote, start quote)\n // Then wrap the whole thing in single quotes\n return \"'\" + str.replace(/'/g, \"'\\\\''\") + \"'\";\n}\n\n/**\n * Sanitize a path component to prevent path traversal attacks.\n * Removes directory separators and parent directory references.\n */\nfunction sanitizePathComponent(name: string): string {\n return (\n name\n .replace(/\\.\\./g, '') // Remove parent directory references\n .replace(/[\\/\\\\]/g, '-') // Replace path separators with dashes\n .replace(/^\\.+/, '') // Remove leading dots\n .trim() || 'unnamed'\n ); // Ensure non-empty result\n}\n\nexport interface WorkspaceConfig {\n enabled: boolean;\n basePath: string;\n cleanupOnExit: boolean;\n}\n\nexport interface WorkspaceInfo {\n sessionId: string;\n workspacePath: string;\n mainProjectPath: string;\n mainProjectName: string;\n originalPath: string;\n}\n\nexport interface ProjectInfo {\n name: string;\n path: string;\n worktreePath: string;\n repository: string;\n}\n\n/**\n * WorkspaceManager creates isolated workspaces for parallel visor runs.\n * Each run gets a unique workspace directory containing worktrees for all projects.\n */\nexport class WorkspaceManager {\n private static instances: Map<string, WorkspaceManager> = new Map();\n\n private sessionId: string;\n private basePath: string;\n private workspacePath: string;\n private originalPath: string;\n private config: WorkspaceConfig;\n private initialized: boolean = false;\n private mainProjectInfo: WorkspaceInfo | null = null;\n private projects: Map<string, ProjectInfo> = new Map();\n private cleanupHandlersRegistered: boolean = false;\n private usedNames: Set<string> = new Set();\n\n private constructor(sessionId: string, originalPath: string, config?: Partial<WorkspaceConfig>) {\n this.sessionId = sessionId;\n this.originalPath = originalPath;\n\n // Default configuration\n this.config = {\n enabled: true,\n basePath: process.env.VISOR_WORKSPACE_PATH || '/tmp/visor-workspaces',\n cleanupOnExit: true,\n ...config,\n };\n\n this.basePath = this.config.basePath;\n this.workspacePath = path.join(this.basePath, sanitizePathComponent(this.sessionId));\n }\n\n /**\n * Get or create a WorkspaceManager instance for a session\n */\n static getInstance(\n sessionId: string,\n originalPath: string,\n config?: Partial<WorkspaceConfig>\n ): WorkspaceManager {\n if (!WorkspaceManager.instances.has(sessionId)) {\n WorkspaceManager.instances.set(\n sessionId,\n new WorkspaceManager(sessionId, originalPath, config)\n );\n }\n return WorkspaceManager.instances.get(sessionId)!;\n }\n\n /**\n * Clear all instances (for testing)\n */\n static clearInstances(): void {\n WorkspaceManager.instances.clear();\n }\n\n /**\n * Check if workspace isolation is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled;\n }\n\n /**\n * Get the workspace path\n */\n getWorkspacePath(): string {\n return this.workspacePath;\n }\n\n /**\n * Get the original working directory\n */\n getOriginalPath(): string {\n return this.originalPath;\n }\n\n /**\n * Get workspace info (only available after initialize)\n */\n getWorkspaceInfo(): WorkspaceInfo | null {\n return this.mainProjectInfo;\n }\n\n /**\n * Initialize the workspace - creates workspace directory and main project worktree\n */\n async initialize(): Promise<WorkspaceInfo> {\n if (!this.config.enabled) {\n throw new Error('Workspace isolation is not enabled');\n }\n\n if (this.initialized && this.mainProjectInfo) {\n return this.mainProjectInfo;\n }\n\n logger.info(`Initializing workspace: ${this.workspacePath}`);\n\n // Create workspace directory (mkdir with recursive handles existing dirs)\n await fsp.mkdir(this.workspacePath, { recursive: true });\n logger.debug(`Created workspace directory: ${this.workspacePath}`);\n\n // Extract main project name from original path (sanitize for defense in depth)\n const mainProjectName = sanitizePathComponent(this.extractProjectName(this.originalPath));\n this.usedNames.add(mainProjectName);\n\n // Create worktree for main project\n const mainProjectPath = path.join(this.workspacePath, mainProjectName);\n\n // Check if original path is a git repository\n const isGitRepo = await this.isGitRepository(this.originalPath);\n\n if (isGitRepo) {\n // Create worktree for main project\n await this.createMainProjectWorktree(mainProjectPath);\n } else {\n // If not a git repo, create a symlink instead\n logger.debug(`Original path is not a git repo, creating symlink`);\n try {\n await fsp.symlink(this.originalPath, mainProjectPath);\n } catch (error) {\n throw new Error(`Failed to create symlink for main project: ${error}`);\n }\n }\n\n // Register cleanup handlers\n this.registerCleanupHandlers();\n\n this.mainProjectInfo = {\n sessionId: this.sessionId,\n workspacePath: this.workspacePath,\n mainProjectPath,\n mainProjectName,\n originalPath: this.originalPath,\n };\n\n this.initialized = true;\n logger.info(`Workspace initialized: ${this.workspacePath}`);\n\n return this.mainProjectInfo;\n }\n\n /**\n * Add a project to the workspace (creates symlink to worktree)\n */\n async addProject(\n repository: string,\n worktreePath: string,\n description?: string\n ): Promise<string> {\n if (!this.initialized) {\n throw new Error('Workspace not initialized. Call initialize() first.');\n }\n\n // Extract project name and sanitize to prevent path traversal\n let projectName = sanitizePathComponent(description || this.extractRepoName(repository));\n\n // Handle duplicate names\n projectName = this.getUniqueName(projectName);\n this.usedNames.add(projectName);\n\n // Create symlink in workspace\n const workspacePath = path.join(this.workspacePath, projectName);\n\n // Remove existing symlink/directory if present (rm with force handles non-existent)\n await fsp.rm(workspacePath, { recursive: true, force: true });\n\n try {\n await fsp.symlink(worktreePath, workspacePath);\n } catch (error) {\n throw new Error(`Failed to create symlink for project ${projectName}: ${error}`);\n }\n\n // Track project\n this.projects.set(projectName, {\n name: projectName,\n path: workspacePath,\n worktreePath,\n repository,\n });\n\n logger.info(`Added project to workspace: ${projectName} -> ${worktreePath}`);\n\n return workspacePath;\n }\n\n /**\n * List all projects in the workspace\n */\n listProjects(): ProjectInfo[] {\n return Array.from(this.projects.values());\n }\n\n /**\n * Cleanup the workspace\n */\n async cleanup(): Promise<void> {\n logger.info(`Cleaning up workspace: ${this.workspacePath}`);\n\n try {\n // Remove main project worktree if it exists\n if (this.mainProjectInfo) {\n const mainProjectPath = this.mainProjectInfo.mainProjectPath;\n\n // Check if path exists and if it's a worktree (not a symlink)\n try {\n const stats = await fsp.lstat(mainProjectPath);\n if (!stats.isSymbolicLink()) {\n await this.removeMainProjectWorktree(mainProjectPath);\n }\n } catch {\n // Path doesn't exist, nothing to clean up\n }\n }\n\n // Remove workspace directory\n await fsp.rm(this.workspacePath, { recursive: true, force: true });\n logger.debug(`Removed workspace directory: ${this.workspacePath}`);\n\n // Remove from instances\n WorkspaceManager.instances.delete(this.sessionId);\n\n this.initialized = false;\n this.mainProjectInfo = null;\n this.projects.clear();\n this.usedNames.clear();\n\n logger.info(`Workspace cleanup completed: ${this.sessionId}`);\n } catch (error) {\n logger.warn(`Failed to cleanup workspace: ${error}`);\n }\n }\n\n /**\n * Create worktree for the main project\n *\n * visor-disable: architecture - Not using WorktreeManager here because:\n * 1. WorktreeManager expects remote URLs and clones to bare repos first\n * 2. This operates on the LOCAL repo we're already in (no cloning needed)\n * 3. Adding a \"local mode\" to WorktreeManager would add complexity for minimal benefit\n * The git commands here are simpler (just rev-parse + worktree add) vs WorktreeManager's\n * full clone/bare-repo/fetch/worktree pipeline.\n */\n private async createMainProjectWorktree(targetPath: string): Promise<void> {\n logger.debug(`Creating main project worktree: ${targetPath}`);\n\n // Get current HEAD\n const headResult = await commandExecutor.execute(\n `git -C ${shellEscape(this.originalPath)} rev-parse HEAD`,\n {\n timeout: 10000,\n }\n );\n\n if (headResult.exitCode !== 0) {\n throw new Error(`Failed to get HEAD: ${headResult.stderr}`);\n }\n\n const headRef = headResult.stdout.trim();\n\n // Create worktree using detached HEAD to avoid branch conflicts\n const createCmd = `git -C ${shellEscape(this.originalPath)} worktree add --detach ${shellEscape(targetPath)} ${shellEscape(headRef)}`;\n const result = await commandExecutor.execute(createCmd, { timeout: 60000 });\n\n if (result.exitCode !== 0) {\n throw new Error(`Failed to create main project worktree: ${result.stderr}`);\n }\n\n logger.debug(`Created main project worktree at ${targetPath}`);\n }\n\n /**\n * Remove main project worktree\n */\n private async removeMainProjectWorktree(worktreePath: string): Promise<void> {\n logger.debug(`Removing main project worktree: ${worktreePath}`);\n\n const removeCmd = `git -C ${shellEscape(this.originalPath)} worktree remove ${shellEscape(worktreePath)} --force`;\n const result = await commandExecutor.execute(removeCmd, { timeout: 30000 });\n\n if (result.exitCode !== 0) {\n logger.warn(`Failed to remove worktree via git: ${result.stderr}`);\n // Directory will be removed with the workspace anyway\n }\n }\n\n /**\n * Check if a path is a git repository\n */\n private async isGitRepository(dirPath: string): Promise<boolean> {\n try {\n const result = await commandExecutor.execute(\n `git -C ${shellEscape(dirPath)} rev-parse --git-dir`,\n {\n timeout: 5000,\n }\n );\n return result.exitCode === 0;\n } catch {\n return false;\n }\n }\n\n /**\n * Extract project name from path\n */\n private extractProjectName(dirPath: string): string {\n return path.basename(dirPath);\n }\n\n /**\n * Extract repository name from owner/repo format\n */\n private extractRepoName(repository: string): string {\n // Handle URLs\n if (repository.includes('://') || repository.startsWith('git@')) {\n // Extract from URL\n const match = repository.match(/[/:]([^/:]+\\/[^/:]+?)(?:\\.git)?$/);\n if (match) {\n return match[1].split('/').pop() || repository;\n }\n }\n\n // Handle owner/repo format\n if (repository.includes('/')) {\n return repository.split('/').pop() || repository;\n }\n\n return repository;\n }\n\n /**\n * Get a unique name by appending a number if needed\n */\n private getUniqueName(baseName: string): string {\n if (!this.usedNames.has(baseName)) {\n return baseName;\n }\n\n let counter = 2;\n let uniqueName = `${baseName}-${counter}`;\n while (this.usedNames.has(uniqueName)) {\n counter++;\n uniqueName = `${baseName}-${counter}`;\n }\n\n return uniqueName;\n }\n\n /**\n * Register cleanup handlers for process exit\n */\n private registerCleanupHandlers(): void {\n if (this.cleanupHandlersRegistered || !this.config.cleanupOnExit) {\n return;\n }\n\n // Note: We don't register on 'exit' as it must be synchronous\n // SIGINT and SIGTERM handlers are already registered by WorktreeManager\n // We rely on explicit cleanup call or process handlers from the engine\n\n this.cleanupHandlersRegistered = true;\n }\n}\n","import type { VisorConfig, EventTrigger } from '../../types/config';\nimport type { PRInfo } from '../../pr-analyzer';\nimport type { EngineContext, CheckMetadata } from '../../types/engine';\nimport { ExecutionJournal } from '../../snapshot-store';\nimport { MemoryStore } from '../../memory-store';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from '../../logger';\nimport type { VisorConfig as VCfg, CheckConfig as CfgCheck } from '../../types/config';\nimport { WorkspaceManager } from '../../utils/workspace-manager';\n\n/**\n * Apply minimal criticality defaults in-place.\n * This is a no-behavior-change scaffold: we only default missing\n * check.criticality to 'policy' so downstream code can rely on a value.\n * Future mapping (retries/loop budgets) can build on this without\n * changing existing behavior.\n */\nfunction applyCriticalityDefaults(cfg: VCfg): void {\n const checks = cfg.checks || {};\n for (const id of Object.keys(checks)) {\n const c: CfgCheck = (checks as any)[id] as CfgCheck;\n if (!c.criticality) (c.criticality as any) = 'policy';\n // For 'info' checks, default continue_on_failure to true if unset.\n if (c.criticality === 'info' && typeof c.continue_on_failure === 'undefined')\n c.continue_on_failure = true;\n }\n}\n\n/**\n * Pure helper to build an EngineContext for a state-machine run.\n * Extracted to reduce StateMachineExecutionEngine size; behavior unchanged.\n */\nexport function buildEngineContextForRun(\n workingDirectory: string,\n config: VisorConfig,\n prInfo: PRInfo,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n requestedChecks?: string[]\n): EngineContext {\n // Deep clone provided config to avoid cross-run mutations between tests/runs\n const clonedConfig: VisorConfig = JSON.parse(JSON.stringify(config));\n\n // Build check metadata\n const checks: Record<string, CheckMetadata> = {};\n\n // Fill in minimal defaults derived from criticality (no behavior change)\n applyCriticalityDefaults(clonedConfig);\n\n // If config has checks, use them\n for (const [checkId, checkConfig] of Object.entries(clonedConfig.checks || {})) {\n checks[checkId] = {\n tags: checkConfig.tags || [],\n triggers: (Array.isArray(checkConfig.on) ? checkConfig.on : [checkConfig.on]).filter(\n Boolean\n ) as EventTrigger[],\n group: checkConfig.group,\n providerType: checkConfig.type || 'ai',\n // Normalize depends_on to array (supports string | string[])\n dependencies: Array.isArray(checkConfig.depends_on)\n ? checkConfig.depends_on\n : checkConfig.depends_on\n ? [checkConfig.depends_on]\n : [],\n };\n }\n\n // Backward compatibility: synthesize minimal check configs for requested checks\n // that don't exist in the config (e.g., legacy test mode with empty config)\n if (requestedChecks && requestedChecks.length > 0) {\n for (const checkName of requestedChecks) {\n if (!checks[checkName] && !clonedConfig.checks?.[checkName]) {\n // Synthesize a minimal check config for this legacy check name\n logger.debug(`[StateMachine] Synthesizing minimal config for legacy check: ${checkName}`);\n\n // Add to config.checks so providers can find it\n if (!clonedConfig.checks) {\n clonedConfig.checks = {};\n }\n clonedConfig.checks[checkName] = {\n type: 'ai',\n prompt: `Perform ${checkName} analysis`,\n } as any;\n\n // Add metadata\n checks[checkName] = {\n tags: [],\n triggers: [],\n group: 'default',\n providerType: 'ai',\n dependencies: [],\n };\n }\n }\n }\n\n // Initialize journal and memory\n const journal = new ExecutionJournal();\n const memory = MemoryStore.getInstance(clonedConfig.memory);\n\n return {\n mode: 'state-machine',\n config: clonedConfig,\n checks,\n journal,\n memory,\n workingDirectory,\n originalWorkingDirectory: workingDirectory,\n sessionId: uuidv4(),\n event: prInfo.eventType,\n debug,\n maxParallelism,\n failFast,\n requestedChecks: requestedChecks && requestedChecks.length > 0 ? requestedChecks : undefined,\n // Store prInfo for later access (e.g., in getOutputHistorySnapshot)\n prInfo,\n };\n}\n\n/**\n * Initialize workspace isolation for an engine context.\n * Creates an isolated workspace with the main project worktree.\n *\n * @param context - Engine context to update with workspace\n * @returns Updated context (same object, mutated)\n */\nexport async function initializeWorkspace(context: EngineContext): Promise<EngineContext> {\n // Check if workspace isolation is enabled via config or env\n const workspaceConfig = (context.config as any).workspace;\n const isEnabled =\n workspaceConfig?.enabled !== false && process.env.VISOR_WORKSPACE_ENABLED !== 'false';\n\n if (!isEnabled) {\n logger.debug('[Workspace] Workspace isolation is disabled');\n return context;\n }\n\n const originalPath = context.workingDirectory || process.cwd();\n\n try {\n // Check if workspace should be kept (for debugging)\n const keepWorkspace = process.env.VISOR_KEEP_WORKSPACE === 'true';\n\n // Create workspace manager\n const workspace = WorkspaceManager.getInstance(context.sessionId, originalPath, {\n enabled: true,\n basePath:\n workspaceConfig?.base_path || process.env.VISOR_WORKSPACE_PATH || '/tmp/visor-workspaces',\n cleanupOnExit: keepWorkspace ? false : workspaceConfig?.cleanup_on_exit !== false,\n });\n\n // Initialize workspace (creates main project worktree)\n const info = await workspace.initialize();\n\n // Update context with workspace info\n context.workspace = workspace;\n context.workingDirectory = info.mainProjectPath;\n context.originalWorkingDirectory = originalPath;\n\n logger.info(`[Workspace] Initialized workspace: ${info.workspacePath}`);\n logger.debug(`[Workspace] Main project at: ${info.mainProjectPath}`);\n if (keepWorkspace) {\n logger.info(`[Workspace] Keeping workspace after execution (--keep-workspace)`);\n }\n\n return context;\n } catch (error) {\n // Log warning but continue without workspace isolation\n logger.warn(`[Workspace] Failed to initialize workspace: ${error}`);\n logger.debug('[Workspace] Continuing without workspace isolation');\n return context;\n }\n}\n","import type { ReviewIssue, GroupedCheckResults, ReviewSummary } from '../../reviewer';\nimport type { ExecutionStatistics } from '../../types/execution';\n\n/**\n * Pure helper to convert grouped results + statistics into a flat ReviewSummary.\n * Extracted to reduce StateMachineExecutionEngine size; behavior unchanged.\n */\nexport function convertToReviewSummary(\n groupedResults: GroupedCheckResults,\n statistics?: ExecutionStatistics\n): ReviewSummary {\n const allIssues: ReviewIssue[] = [];\n\n // Aggregate issues from all check results\n for (const checkResults of Object.values(groupedResults)) {\n for (const checkResult of checkResults) {\n if (checkResult.issues && checkResult.issues.length > 0) {\n allIssues.push(...checkResult.issues);\n }\n }\n }\n\n // Convert errors from execution statistics into issues\n if (statistics) {\n for (const checkStats of statistics.checks) {\n if (checkStats.errorMessage) {\n allIssues.push({\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: 'system/error',\n message: checkStats.errorMessage,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n });\n }\n }\n }\n\n return {\n issues: allIssues,\n };\n}\n","import type { CheckExecutionOptions, ExecutionResult } from './types/execution';\nimport { AnalysisResult } from './output-formatters';\nimport type { VisorConfig } from './types/config';\nimport type { PRInfo } from './pr-analyzer';\nimport { StateMachineRunner } from './state-machine/runner';\nimport type { EngineContext } from './types/engine';\nimport { ExecutionJournal } from './snapshot-store';\nimport { logger } from './logger';\nimport type { DebugVisualizerServer } from './debug-visualizer/ws-server';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\n/**\n * State machine-based execution engine\n *\n * Production-ready state machine implementation with full observability support.\n * M4: Includes OTEL telemetry and debug visualizer event streaming.\n */\nexport class StateMachineExecutionEngine {\n private workingDirectory: string;\n private executionContext?: import('./providers/check-provider.interface').ExecutionContext;\n private debugServer?: DebugVisualizerServer;\n private _lastContext?: EngineContext;\n private _lastRunner?: StateMachineRunner;\n\n constructor(\n workingDirectory?: string,\n octokit?: import('@octokit/rest').Octokit,\n debugServer?: DebugVisualizerServer\n ) {\n this.workingDirectory = workingDirectory || process.cwd();\n this.debugServer = debugServer;\n }\n\n /**\n * Execute checks using the state machine engine\n *\n * Converts CheckExecutionOptions -> executeGroupedChecks() -> AnalysisResult\n */\n async executeChecks(options: CheckExecutionOptions): Promise<AnalysisResult> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n try {\n // Initialize memory store if configured\n if (options.config?.memory) {\n const { MemoryStore } = await import('./memory-store');\n const memoryStore = MemoryStore.getInstance(options.config.memory);\n await memoryStore.initialize();\n logger.debug('Memory store initialized');\n }\n\n // Analyze the repository\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const gitAnalyzer = new GitRepositoryAnalyzer(options.workingDirectory);\n logger.info('Analyzing local git repository...');\n const repositoryInfo = await gitAnalyzer.analyzeRepository();\n\n if (!repositoryInfo.isGitRepository) {\n return this.createErrorResult(\n repositoryInfo,\n 'Not a git repository or no changes found',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // Convert to PRInfo format for compatibility\n const prInfo = gitAnalyzer.toPRInfo(repositoryInfo);\n\n // Propagate event type if provided\n try {\n const evt = (options.webhookContext as any)?.eventType;\n if (evt) (prInfo as any).eventType = evt;\n } catch {}\n\n // Apply tag filtering if specified\n const filteredChecks = this.filterChecksByTags(\n options.checks,\n options.config,\n options.tagFilter || options.config?.tag_filter\n );\n\n if (filteredChecks.length === 0) {\n logger.warn('No checks match the tag filter criteria');\n return this.createErrorResult(\n repositoryInfo,\n 'No checks match the tag filter criteria',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // If a webhook context is provided (from WebhookServer or Slack socket),\n // attach it to the http_input provider so http_input checks can read data.\n try {\n const map = (options as any)?.webhookContext?.webhookData as\n | Map<string, unknown>\n | undefined;\n if (map) {\n const { CheckProviderRegistry } = await import('./providers/check-provider-registry');\n const reg = CheckProviderRegistry.getInstance();\n const p: any = reg.getProvider('http_input');\n if (p && typeof p.setWebhookContext === 'function') p.setWebhookContext(map);\n const prev: any = this.executionContext || {};\n this.setExecutionContext({ ...prev, webhookContext: { webhookData: map } } as any);\n }\n } catch {}\n\n // Execute checks using state machine\n logger.info(`Executing checks: ${filteredChecks.join(', ')}`);\n const executionResult = await this.executeGroupedChecks(\n prInfo,\n filteredChecks,\n options.timeout,\n options.config,\n options.outputFormat,\n options.debug,\n options.maxParallelism,\n options.failFast,\n options.tagFilter\n );\n\n // Convert ExecutionResult to AnalysisResult format\n const executionTime = Date.now() - startTime;\n\n // Extract review summary from grouped results\n const reviewSummary = this.convertGroupedResultsToReviewSummary(\n executionResult.results,\n executionResult.statistics\n );\n\n // Collect debug information when debug mode is enabled\n let debugInfo: import('./output-formatters').DebugInfo | undefined;\n if (options.debug && reviewSummary.debug) {\n debugInfo = {\n provider: reviewSummary.debug.provider,\n model: reviewSummary.debug.model,\n processingTime: reviewSummary.debug.processingTime,\n parallelExecution: options.checks.length > 1,\n checksExecuted: options.checks,\n totalApiCalls: reviewSummary.debug.totalApiCalls || options.checks.length,\n apiCallDetails: reviewSummary.debug.apiCallDetails,\n };\n }\n\n // Expose output history snapshot\n try {\n const histSnap = this.getOutputHistorySnapshot();\n (reviewSummary as any).history = histSnap;\n } catch {}\n\n return {\n repositoryInfo,\n reviewSummary,\n executionTime,\n timestamp,\n checksExecuted: filteredChecks,\n executionStatistics: executionResult.statistics,\n debug: debugInfo,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error occurred';\n logger.error('Error executing checks: ' + message);\n\n // In strict test modes, surface errors to callers\n const strictEnv = process.env.VISOR_STRICT_ERRORS === 'true';\n if (strictEnv) {\n throw error;\n }\n\n const fallbackRepositoryInfo: import('./git-repository-analyzer').GitRepositoryInfo = {\n title: 'Error during analysis',\n body: `Error: ${message || 'Unknown error'}`,\n author: 'system',\n base: 'main',\n head: 'HEAD',\n files: [],\n totalAdditions: 0,\n totalDeletions: 0,\n isGitRepository: false,\n workingDirectory: options.workingDirectory || process.cwd(),\n };\n\n return this.createErrorResult(\n fallbackRepositoryInfo,\n message || 'Unknown error occurred',\n startTime,\n timestamp,\n options.checks\n );\n }\n }\n\n /**\n * Get execution context (used by state machine to propagate hooks)\n */\n protected getExecutionContext():\n | import('./providers/check-provider.interface').ExecutionContext\n | undefined {\n return this.executionContext;\n }\n\n /**\n * Set execution context for external callers\n */\n public setExecutionContext(\n context: import('./providers/check-provider.interface').ExecutionContext | undefined\n ): void {\n this.executionContext = context;\n }\n\n /**\n * Reset per-run state (no-op for state machine engine)\n *\n * The state machine engine is stateless per-run by design.\n * Each execution creates a fresh journal and context.\n * This method exists only for backward compatibility with test framework.\n *\n * @deprecated This is a no-op. State machine engine doesn't maintain per-run state.\n */\n public resetPerRunState(): void {\n // No-op: State machine engine is stateless per-run\n // Each execution creates a fresh journal and context\n }\n\n /**\n * Execute grouped checks using the state machine engine\n *\n * M4: Production-ready with full telemetry and debug server support\n */\n async executeGroupedChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: VisorConfig,\n outputFormat?: string,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n tagFilter?: import('./types/config').TagFilter,\n _pauseGate?: () => Promise<void>\n ): Promise<ExecutionResult> {\n if (debug) {\n logger.info('[StateMachine] Using state machine engine');\n }\n\n // Create minimal default config if none provided (backward compatibility)\n if (!config) {\n const { ConfigManager } = await import('./config');\n const configManager = new ConfigManager();\n config = await configManager.getDefaultConfig();\n logger.debug('[StateMachine] Using default configuration (no config provided)');\n }\n\n // Merge tagFilter into config if provided (test runner passes it separately)\n const configWithTagFilter = tagFilter\n ? {\n ...config,\n tag_filter: tagFilter,\n }\n : config;\n\n // Build engine context\n const context = this.buildEngineContext(\n configWithTagFilter,\n prInfo,\n debug,\n maxParallelism,\n failFast,\n checks // Pass the explicit checks list\n );\n\n // Initialize workspace isolation (if enabled)\n const { initializeWorkspace } = require('./state-machine/context/build-engine-context');\n await initializeWorkspace(context);\n\n // Copy execution context (hooks, etc.) from legacy engine\n context.executionContext = this.getExecutionContext();\n\n // Store context for later access (e.g., getOutputHistorySnapshot)\n this._lastContext = context;\n\n // Optionally enable event-driven frontends if configured\n let frontendsHost: any | undefined;\n if (\n Array.isArray((configWithTagFilter as any).frontends) &&\n (configWithTagFilter as any).frontends.length > 0\n ) {\n try {\n const { EventBus } = await import('./event-bus/event-bus');\n const { FrontendsHost } = await import('./frontends/host');\n const bus = new EventBus();\n (context as any).eventBus = bus;\n frontendsHost = new FrontendsHost(bus, logger);\n if (process.env.VISOR_DEBUG === 'true') {\n try {\n const fns = ((configWithTagFilter as any).frontends || []).map((f: any) => ({\n name: f?.name,\n hasConfig: !!f?.config,\n cfg: f?.config || undefined,\n }));\n logger.info(`[Frontends] Loading specs: ${JSON.stringify(fns)}`);\n } catch {}\n }\n await frontendsHost.load((configWithTagFilter as any).frontends);\n // Derive repo/pr/headSha and octokit if available\n let owner: string | undefined;\n let name: string | undefined;\n let prNum: number | undefined;\n let headSha: string | undefined;\n try {\n const anyInfo: any = prInfo as any;\n owner =\n anyInfo?.eventContext?.repository?.owner?.login ||\n process.env.GITHUB_REPOSITORY?.split('/')?.[0];\n name =\n anyInfo?.eventContext?.repository?.name ||\n process.env.GITHUB_REPOSITORY?.split('/')?.[1];\n prNum = typeof anyInfo?.number === 'number' ? anyInfo.number : undefined;\n headSha = anyInfo?.eventContext?.pull_request?.head?.sha || process.env.GITHUB_SHA;\n } catch {}\n const repoObj = owner && name ? { owner, name } : undefined;\n const octokit = (this.executionContext as any)?.octokit;\n // Fallback: if headSha is missing but we have PR info and octokit, fetch it\n if (\n !headSha &&\n repoObj &&\n prNum &&\n octokit &&\n typeof octokit.rest?.pulls?.get === 'function'\n ) {\n try {\n const { data } = await octokit.rest.pulls.get({\n owner: repoObj.owner,\n repo: repoObj.name,\n pull_number: prNum,\n });\n headSha = (data && (data as any).head && (data as any).head.sha) || headSha;\n } catch {\n // ignore; headSha remains undefined\n }\n }\n // Make the event bus available to providers via executionContext\n try {\n const prev: any = this.getExecutionContext() || {};\n this.setExecutionContext({ ...prev, eventBus: bus });\n // Also reflect it into the active engine context so downstream providers see it\n try {\n (context as any).executionContext = this.getExecutionContext();\n } catch {}\n } catch {}\n\n await frontendsHost.startAll(() => ({\n eventBus: bus,\n logger,\n // Provide the active (possibly tag-filtered) config so frontends can read groups, etc.\n config: configWithTagFilter,\n run: {\n runId: (context as any).sessionId,\n repo: repoObj,\n pr: prNum,\n headSha,\n event: (context as any).event || (prInfo as any)?.eventType,\n actor:\n (prInfo as any)?.eventContext?.sender?.login ||\n (typeof process.env.GITHUB_ACTOR === 'string' ? process.env.GITHUB_ACTOR : undefined),\n },\n octokit,\n webhookContext: (this.executionContext as any)?.webhookContext,\n // Surface any injected test doubles for Slack as well\n slack:\n (this.executionContext as any)?.slack || (this.executionContext as any)?.slackClient,\n }));\n\n // Phase 1: Snapshot on HumanInputRequested (experimental pause support)\n try {\n bus.on('HumanInputRequested', async (envelope: any) => {\n try {\n const ev = (envelope && envelope.payload) || envelope;\n // Determine channel/thread from event or inbound payload\n let channel: string | undefined = ev?.channel;\n let threadTs: string | undefined = ev?.threadTs;\n if (!channel || !threadTs) {\n try {\n const anyCfg: any = configWithTagFilter || {};\n const slackCfg: any = anyCfg.slack || {};\n const endpoint: string = slackCfg.endpoint || '/bots/slack/support';\n const map = (this.executionContext as any)?.webhookContext?.webhookData as\n | Map<string, unknown>\n | undefined;\n const payload: any = map?.get(endpoint);\n const e: any = payload?.event;\n const derivedTs = String(e?.thread_ts || e?.ts || e?.event_ts || '');\n const derivedCh = String(e?.channel || '');\n if (derivedCh && derivedTs) {\n channel = channel || derivedCh;\n threadTs = threadTs || derivedTs;\n }\n } catch {}\n }\n\n const checkId = String(ev?.checkId || 'unknown');\n const threadKey =\n ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : 'session');\n const baseDir =\n process.env.VISOR_SNAPSHOT_DIR ||\n path.resolve(process.cwd(), '.visor', 'snapshots');\n fs.mkdirSync(baseDir, { recursive: true });\n const filePath = path.join(baseDir, `${threadKey}-${checkId}.json`);\n await this.saveSnapshotToFile(filePath);\n logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);\n try {\n await bus.emit({\n type: 'SnapshotSaved',\n checkId: ev?.checkId || 'unknown',\n channel,\n threadTs,\n threadKey,\n filePath,\n });\n } catch {}\n } catch (e) {\n logger.warn(\n `[Snapshot] Failed to save snapshot on HumanInputRequested: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n });\n } catch {}\n } catch (err) {\n logger.warn(\n `[Frontends] Failed to initialize frontends: ${err instanceof Error ? err.message : String(err)}`\n );\n }\n }\n\n // Create and run state machine with debug server support (M4)\n const runner = new StateMachineRunner(context, this.debugServer);\n this._lastRunner = runner;\n const result = await runner.run();\n\n // Stop frontends if started\n if (frontendsHost && typeof frontendsHost.stopAll === 'function') {\n try {\n await frontendsHost.stopAll();\n } catch {}\n }\n\n if (debug) {\n logger.info('[StateMachine] Execution complete');\n }\n\n // Post-grouped comments via legacy reviewer is removed; GitHub frontend handles comments\n\n // Cleanup AI sessions after execution\n try {\n const { SessionRegistry } = await import('./session-registry');\n const sessionRegistry = SessionRegistry.getInstance();\n sessionRegistry.clearAllSessions();\n } catch (error) {\n logger.debug(`[StateMachine] Failed to cleanup sessions: ${error}`);\n }\n\n // Cleanup workspace if enabled\n if (context.workspace) {\n try {\n await context.workspace.cleanup();\n } catch (error) {\n logger.debug(`[StateMachine] Failed to cleanup workspace: ${error}`);\n }\n }\n\n return result;\n }\n\n /**\n * Build the engine context for state machine execution\n */\n private buildEngineContext(\n config: VisorConfig,\n prInfo: PRInfo,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n requestedChecks?: string[]\n ): EngineContext {\n const { buildEngineContextForRun } = require('./state-machine/context/build-engine-context');\n return buildEngineContextForRun(\n this.workingDirectory,\n config,\n prInfo,\n debug,\n maxParallelism,\n failFast,\n requestedChecks\n );\n }\n\n /**\n * Get output history snapshot for test framework compatibility\n * Extracts output history from the journal\n */\n public getOutputHistorySnapshot(): Record<string, unknown[]> {\n // Get the journal from the last execution context\n const journal = (this as any)._lastContext?.journal as ExecutionJournal | undefined;\n if (!journal) {\n logger.debug('[StateMachine][DEBUG] getOutputHistorySnapshot: No journal found');\n return {};\n }\n\n const sessionId = (this as any)._lastContext?.sessionId as string | undefined;\n if (!sessionId) {\n logger.debug('[StateMachine][DEBUG] getOutputHistorySnapshot: No sessionId found');\n return {};\n }\n\n // Read all journal entries for this session\n const snapshot = journal.beginSnapshot();\n const allEntries = journal.readVisible(sessionId, snapshot, undefined);\n\n logger.debug(\n `[StateMachine][DEBUG] getOutputHistorySnapshot: Found ${allEntries.length} journal entries`\n );\n\n // Group by checkId and extract outputs\n const outputHistory: Record<string, unknown[]> = {};\n for (const entry of allEntries) {\n const checkId = entry.checkId;\n\n if (!outputHistory[checkId]) {\n outputHistory[checkId] = [];\n }\n // Skip journal stubs for skipped checks\n try {\n if (entry && typeof entry.result === 'object' && (entry.result as any).__skipped) {\n continue;\n }\n } catch {}\n\n // Prefer explicit .output; fall back to the full result (issues/content)\n // so tests and templates can reference paths like issues[0].severity for\n // code-review schema steps which do not set a separate output object.\n const payload =\n entry.result.output !== undefined ? entry.result.output : (entry.result as unknown);\n\n // Filter out forEach aggregation metadata objects (which contain a\n // forEachItems array) to avoid double-counting per-item executions in\n // tests. The actual per-item outputs are committed as separate entries\n // and should be used for history-based assertions and routing.\n try {\n if (\n payload &&\n typeof payload === 'object' &&\n (payload as any).forEachItems &&\n Array.isArray((payload as any).forEachItems)\n ) {\n continue;\n }\n } catch {}\n\n if (payload !== undefined) outputHistory[checkId].push(payload);\n }\n\n logger.debug(\n `[StateMachine][DEBUG] getOutputHistorySnapshot result: ${JSON.stringify(Object.keys(outputHistory))}`\n );\n for (const [checkId, outputs] of Object.entries(outputHistory)) {\n logger.debug(`[StateMachine][DEBUG] ${checkId}: ${outputs.length} outputs`);\n }\n\n return outputHistory;\n }\n\n /**\n * Save a JSON snapshot of the last run's state and journal to a file (experimental).\n * Does not include secrets. Intended for debugging and future resume support.\n */\n public async saveSnapshotToFile(filePath: string): Promise<void> {\n const fs = await import('fs/promises');\n const ctx = this._lastContext;\n const runner = this._lastRunner;\n if (!ctx || !runner) {\n throw new Error('No prior execution context to snapshot');\n }\n const journal = (ctx as any).journal as ExecutionJournal;\n const snapshotId = journal.beginSnapshot();\n const entries = journal.readVisible(ctx.sessionId, snapshotId, undefined);\n const state = runner.getState();\n const serializableState = serializeRunState(state);\n const payload = {\n version: 1,\n sessionId: ctx.sessionId,\n event: ctx.event,\n wave: state.wave,\n state: serializableState,\n journal: entries,\n requestedChecks: (ctx as any).requestedChecks || [],\n } as const;\n await fs.writeFile(filePath, JSON.stringify(payload, null, 2), 'utf8');\n }\n\n /**\n * Load a snapshot JSON from file and return it. Resume support can build on this.\n */\n public async loadSnapshotFromFile<T = unknown>(filePath: string): Promise<T> {\n const fs = await import('fs/promises');\n const raw = await fs.readFile(filePath, 'utf8');\n return JSON.parse(raw) as T;\n }\n\n /**\n * Filter checks by tag filter\n */\n private filterChecksByTags(\n checks: string[],\n config: VisorConfig | undefined,\n tagFilter: import('./types/config').TagFilter | undefined\n ): string[] {\n // When no tag filter is specified, include only untagged checks by default.\n // Tagged checks are opt-in unless tag_filter is provided.\n return checks.filter(checkName => {\n const checkConfig = config?.checks?.[checkName];\n if (!checkConfig) {\n // If no config for this check, include it by default\n return true;\n }\n\n const checkTags = checkConfig.tags || [];\n\n // If no tag filter is specified, include only untagged checks.\n if (!tagFilter || (!tagFilter.include && !tagFilter.exclude)) {\n return checkTags.length === 0;\n }\n\n // If check has no tags and a tag filter is specified, include it (untagged checks always run)\n if (checkTags.length === 0) {\n return true;\n }\n\n // Check exclude tags first (if any exclude tag matches, skip the check)\n if (tagFilter.exclude && tagFilter.exclude.length > 0) {\n const hasExcludedTag = tagFilter.exclude.some(tag => checkTags.includes(tag));\n if (hasExcludedTag) return false;\n }\n\n // Check include tags (if specified, at least one must match)\n if (tagFilter.include && tagFilter.include.length > 0) {\n const hasIncludedTag = tagFilter.include.some(tag => checkTags.includes(tag));\n if (!hasIncludedTag) return false;\n }\n\n return true;\n });\n }\n\n /**\n * Create an error result in AnalysisResult format\n */\n private createErrorResult(\n repositoryInfo: import('./git-repository-analyzer').GitRepositoryInfo,\n errorMessage: string,\n startTime: number,\n timestamp: string,\n checksExecuted: string[]\n ): AnalysisResult {\n const executionTime = Date.now() - startTime;\n\n return {\n repositoryInfo,\n reviewSummary: {\n issues: [\n {\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: 'system/error',\n message: errorMessage,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n },\n executionTime,\n timestamp,\n checksExecuted,\n };\n }\n\n /**\n * Convert GroupedCheckResults to ReviewSummary\n * Aggregates all check results into a single ReviewSummary\n */\n private convertGroupedResultsToReviewSummary(\n groupedResults: import('./reviewer').GroupedCheckResults,\n statistics?: import('./types/execution').ExecutionStatistics\n ): import('./reviewer').ReviewSummary {\n const { convertToReviewSummary } = require('./state-machine/execution/summary');\n return (convertToReviewSummary as any)(groupedResults as any, statistics as any) as any;\n }\n\n /**\n * Evaluate failure conditions for a check result\n *\n * This method provides backward compatibility with the legacy engine by\n * delegating to the FailureConditionEvaluator.\n *\n * @param checkName - The name of the check being evaluated\n * @param reviewSummary - The review summary containing check results\n * @param config - The Visor configuration containing failure conditions\n * @param previousOutputs - Optional previous check outputs for cross-check conditions\n * @param authorAssociation - Optional GitHub author association for permission checks\n * @returns Array of failure condition evaluation results\n */\n async evaluateFailureConditions(\n checkName: string,\n reviewSummary: import('./reviewer').ReviewSummary,\n config: VisorConfig,\n previousOutputs?: Record<string, import('./reviewer').ReviewSummary>,\n authorAssociation?: string\n ): Promise<import('./types/config').FailureConditionResult[]> {\n const { FailureConditionEvaluator } = await import('./failure-condition-evaluator');\n const evaluator = new FailureConditionEvaluator();\n const { addEvent } = await import('./telemetry/trace-helpers');\n const { addFailIfTriggered } = await import('./telemetry/metrics');\n\n // Extract check configuration\n const checkConfig = config.checks?.[checkName];\n if (!checkConfig) {\n return [];\n }\n\n // Schema can be string or Record<string, unknown>, convert to string for evaluation\n const rawSchema = checkConfig.schema || 'code-review';\n const checkSchema = typeof rawSchema === 'string' ? rawSchema : 'code-review';\n const checkGroup = checkConfig.group || 'default';\n\n // Handle both fail_if (simple string) and failure_conditions (complex object)\n const results: import('./types/config').FailureConditionResult[] = [];\n\n // Evaluate global fail_if\n if (config.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n config.fail_if,\n previousOutputs || {}\n );\n\n // Telemetry events + metric\n try {\n addEvent('fail_if.evaluated', {\n 'visor.check.id': checkName,\n scope: 'global',\n expression: String(config.fail_if),\n result: failed ? 'triggered' : 'not_triggered',\n });\n if (failed) {\n addEvent('fail_if.triggered', {\n 'visor.check.id': checkName,\n scope: 'global',\n expression: String(config.fail_if),\n });\n addFailIfTriggered(checkName, 'global');\n }\n } catch {}\n\n results.push({\n conditionName: 'global_fail_if',\n failed,\n expression: config.fail_if,\n message: failed ? `Global failure condition met: ${config.fail_if}` : undefined,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n // Evaluate check-specific fail_if (overrides global if present)\n if (checkConfig.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n checkConfig.fail_if,\n previousOutputs || {}\n );\n\n // Telemetry events + metric\n try {\n addEvent('fail_if.evaluated', {\n 'visor.check.id': checkName,\n scope: 'check',\n expression: String(checkConfig.fail_if),\n result: failed ? 'triggered' : 'not_triggered',\n });\n if (failed) {\n addEvent('fail_if.triggered', {\n 'visor.check.id': checkName,\n scope: 'check',\n expression: String(checkConfig.fail_if),\n });\n addFailIfTriggered(checkName, 'check');\n }\n } catch {}\n\n results.push({\n conditionName: `${checkName}_fail_if`,\n failed,\n expression: checkConfig.fail_if,\n message: failed ? `Check failure condition met: ${checkConfig.fail_if}` : undefined,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n // Also evaluate legacy failure_conditions if present\n const globalConditions = config.failure_conditions;\n const checkConditions = checkConfig.failure_conditions;\n\n if (globalConditions || checkConditions) {\n const legacyResults = await evaluator.evaluateConditions(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n globalConditions,\n checkConditions,\n previousOutputs,\n authorAssociation\n );\n results.push(...legacyResults);\n }\n\n return results;\n }\n\n /**\n * Get repository status\n * @returns Repository status information\n */\n async getRepositoryStatus(): Promise<{\n isGitRepository: boolean;\n branch?: string;\n hasChanges: boolean;\n filesChanged?: number;\n }> {\n try {\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const analyzer = new GitRepositoryAnalyzer(this.workingDirectory);\n const info = await analyzer.analyzeRepository();\n\n return {\n isGitRepository: info.isGitRepository,\n branch: info.head, // Use head as branch name\n hasChanges: info.isGitRepository && (info.files?.length > 0 || false),\n filesChanged: info.isGitRepository ? info.files?.length || 0 : 0,\n };\n } catch {\n return {\n isGitRepository: false,\n hasChanges: false,\n };\n }\n }\n\n /**\n * Check if current directory is a git repository\n * @returns True if git repository, false otherwise\n */\n async isGitRepository(): Promise<boolean> {\n const status = await this.getRepositoryStatus();\n return status.isGitRepository;\n }\n\n /**\n * Get list of available check types\n * @returns Array of check type names\n */\n static getAvailableCheckTypes(): string[] {\n const { CheckProviderRegistry } = require('./providers/check-provider-registry');\n const registry = CheckProviderRegistry.getInstance();\n return registry.getAvailableProviders();\n }\n\n /**\n * Validate check types and return valid/invalid lists\n * @param checks - Array of check type names to validate\n * @returns Object with valid and invalid check types\n */\n static validateCheckTypes(checks: string[]): { valid: string[]; invalid: string[] } {\n const availableTypes = StateMachineExecutionEngine.getAvailableCheckTypes();\n const valid: string[] = [];\n const invalid: string[] = [];\n\n for (const check of checks) {\n if (availableTypes.includes(check)) {\n valid.push(check);\n } else {\n invalid.push(check);\n }\n }\n\n return { valid, invalid };\n }\n\n /**\n * Format the status column for execution statistics\n * Used by execution-statistics-formatting tests\n */\n private formatStatusColumn(stats: import('./types/execution').CheckExecutionStats): string {\n if (stats.skipped) {\n // Format skip reason\n if (stats.skipReason === 'if_condition') {\n return '⏭ if';\n } else if (stats.skipReason === 'fail_fast') {\n return '⏭ ff';\n } else if (stats.skipReason === 'dependency_failed') {\n return '⏭ dep';\n }\n return '⏭';\n }\n\n const totalRuns = stats.totalRuns;\n const successfulRuns = stats.successfulRuns;\n const failedRuns = stats.failedRuns;\n\n if (failedRuns > 0 && successfulRuns > 0) {\n // Mixed results\n return `✔/✖ ${successfulRuns}/${totalRuns}`;\n } else if (failedRuns > 0) {\n // All failed\n return totalRuns === 1 ? '✖' : `✖ ×${totalRuns}`;\n } else {\n // All successful\n return totalRuns === 1 ? '✔' : `✔ ×${totalRuns}`;\n }\n }\n\n /**\n * Format the details column for execution statistics\n * Used by execution-statistics-formatting tests\n */\n private formatDetailsColumn(stats: import('./types/execution').CheckExecutionStats): string {\n const parts: string[] = [];\n\n // Add outputs produced\n if (stats.outputsProduced !== undefined && stats.outputsProduced > 0) {\n parts.push(`→${stats.outputsProduced}`);\n }\n\n // Add critical issues\n if (stats.issuesBySeverity.critical > 0) {\n parts.push(`${stats.issuesBySeverity.critical}🔴`);\n }\n\n // Add error issues (only if no critical)\n if (stats.issuesBySeverity.error > 0 && stats.issuesBySeverity.critical === 0) {\n parts.push(`${stats.issuesBySeverity.error}❌`);\n }\n\n // Add warnings\n if (stats.issuesBySeverity.warning > 0) {\n parts.push(`${stats.issuesBySeverity.warning}⚠️`);\n }\n\n // Add info issues (only if no critical/error/warning)\n if (\n stats.issuesBySeverity.info > 0 &&\n stats.issuesBySeverity.critical === 0 &&\n stats.issuesBySeverity.error === 0 &&\n stats.issuesBySeverity.warning === 0\n ) {\n parts.push(`${stats.issuesBySeverity.info}💡`);\n }\n\n // Add error message if present\n if (stats.errorMessage) {\n parts.push(this.truncate(stats.errorMessage, 40));\n }\n\n // Add skip condition if present\n if (stats.skipCondition) {\n parts.push(this.truncate(stats.skipCondition, 40));\n }\n\n return parts.join(' ');\n }\n\n /**\n * Truncate a string to a maximum length\n * Used by formatDetailsColumn\n */\n private truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) {\n return str;\n }\n return str.substring(0, maxLength - 3) + '...';\n }\n}\n\n/** Convert RunState with Maps/Sets into a JSON-safe form */\nfunction serializeRunState(state: import('./types/engine').RunState) {\n return {\n ...state,\n levelQueue: state.levelQueue,\n eventQueue: state.eventQueue,\n activeDispatches: Array.from(state.activeDispatches.entries()),\n completedChecks: Array.from(state.completedChecks.values()),\n stats: Array.from(state.stats.entries()),\n historyLog: state.historyLog,\n forwardRunGuards: Array.from(state.forwardRunGuards.values()),\n currentLevelChecks: Array.from(state.currentLevelChecks.values()),\n currentWaveCompletions: Array.from(\n ((state as any).currentWaveCompletions as Set<string> | undefined) || []\n ),\n // failedChecks is an internal Set added by stats/dispatch layers; keep it if present\n failedChecks: Array.from(((state as any).failedChecks as Set<string> | undefined) || []),\n pendingRunScopes: Array.from((state.pendingRunScopes || new Map()).entries()).map(([k, v]) => [\n k,\n v,\n ]),\n };\n}\n\nexport type SnapshotJson = {\n version: number;\n sessionId: string;\n event?: import('./types/config').EventTrigger;\n wave?: number;\n state: any;\n journal: import('./snapshot-store').JournalEntry[];\n requestedChecks?: string[];\n meta?: Record<string, unknown>;\n};\n\n/**\n * Resume execution from a previously saved snapshot (experimental).\n * Frontends are started to mirror executeGroupedChecks behavior so integrations\n * like Slack can handle CheckCompleted/HumanInputRequested events during resume.\n */\nexport async function resumeFromSnapshot(\n engine: StateMachineExecutionEngine,\n snapshot: SnapshotJson,\n config: VisorConfig,\n opts?: { debug?: boolean; maxParallelism?: number; failFast?: boolean; webhookContext?: any }\n): Promise<import('./types/execution').ExecutionResult> {\n // Recompute PRInfo from the current repository\n const { GitRepositoryAnalyzer } = await import('./git-repository-analyzer');\n const analyzer = new GitRepositoryAnalyzer(process.cwd());\n const repoInfo = await analyzer.analyzeRepository();\n const prInfo = analyzer.toPRInfo(repoInfo);\n\n const context = (engine as any).buildEngineContext(\n config,\n prInfo,\n opts?.debug,\n opts?.maxParallelism,\n opts?.failFast,\n snapshot.requestedChecks\n ) as import('./types/engine').EngineContext;\n\n // Initialize workspace isolation (if enabled) - same as executeGroupedChecks\n const { initializeWorkspace } = require('./state-machine/context/build-engine-context');\n await initializeWorkspace(context);\n\n // Propagate existing executionContext (hooks, octokit, webhookContext, slack, etc.)\n try {\n const prevExecCtx: any = (engine as any).getExecutionContext?.() || {};\n (context as any).executionContext = prevExecCtx;\n } catch {}\n\n // Restore journal entries\n try {\n const journal = (context as any).journal as ExecutionJournal;\n for (const e of snapshot.journal || []) {\n journal.commitEntry({\n // Re-hydrate all entries under the NEW sessionId for this resume run.\n // This ensures helpers like output history and chat_history see both\n // pre-snapshot and post-resume outputs as a single logical session.\n sessionId: (context as any).sessionId,\n scope: e.scope,\n checkId: e.checkId,\n result: e.result,\n event: e.event,\n });\n }\n } catch {}\n\n // Adopt webhookContext and other execution context patches if provided\n try {\n const prev: any = (engine as any).getExecutionContext?.() || {};\n (engine as any).setExecutionContext?.({ ...prev, webhookContext: opts?.webhookContext });\n // Reflect merged executionContext into active engine context\n try {\n (context as any).executionContext = (engine as any).getExecutionContext?.();\n } catch {}\n } catch {}\n\n // Optional frontends (Slack, GitHub, etc.) – mirror executeGroupedChecks\n let frontendsHost: any | undefined;\n if (Array.isArray((config as any).frontends) && (config as any).frontends.length > 0) {\n try {\n const { EventBus } = await import('./event-bus/event-bus');\n const { FrontendsHost } = await import('./frontends/host');\n const bus = new EventBus();\n (context as any).eventBus = bus;\n frontendsHost = new FrontendsHost(bus, logger);\n\n if (process.env.VISOR_DEBUG === 'true') {\n try {\n const fns = ((config as any).frontends || []).map((f: any) => ({\n name: f?.name,\n hasConfig: !!f?.config,\n cfg: f?.config || undefined,\n }));\n logger.info(`[Frontends] Loading specs: ${JSON.stringify(fns)}`);\n } catch {}\n }\n\n await frontendsHost.load((config as any).frontends);\n\n // Derive repo/pr/headSha and octokit if available\n let owner: string | undefined;\n let name: string | undefined;\n let prNum: number | undefined;\n let headSha: string | undefined;\n try {\n const anyInfo: any = prInfo as any;\n owner =\n anyInfo?.eventContext?.repository?.owner?.login ||\n process.env.GITHUB_REPOSITORY?.split('/')?.[0];\n name =\n anyInfo?.eventContext?.repository?.name || process.env.GITHUB_REPOSITORY?.split('/')?.[1];\n prNum = typeof anyInfo?.number === 'number' ? anyInfo.number : undefined;\n headSha = anyInfo?.eventContext?.pull_request?.head?.sha || process.env.GITHUB_SHA;\n } catch {}\n const repoObj = owner && name ? { owner, name } : undefined;\n const octokit = (engine as any).getExecutionContext?.()?.octokit;\n\n // Fallback: if headSha is missing but we have PR info and octokit, fetch it\n if (\n !headSha &&\n repoObj &&\n prNum &&\n octokit &&\n typeof octokit.rest?.pulls?.get === 'function'\n ) {\n try {\n const { data } = await octokit.rest.pulls.get({\n owner: repoObj.owner,\n repo: repoObj.name,\n pull_number: prNum,\n });\n headSha = (data && (data as any).head && (data as any).head.sha) || headSha;\n } catch {\n // ignore; headSha remains undefined\n }\n }\n\n // Make the event bus available to providers via executionContext\n try {\n const prevExec: any = (engine as any).getExecutionContext?.() || {};\n (engine as any).setExecutionContext?.({ ...prevExec, eventBus: bus });\n try {\n (context as any).executionContext = (engine as any).getExecutionContext?.();\n } catch {}\n } catch {}\n\n await frontendsHost.startAll(() => ({\n eventBus: bus,\n logger,\n // Provide the active config so frontends can read groups, etc.\n config,\n run: {\n runId: (context as any).sessionId,\n repo: repoObj,\n pr: prNum,\n headSha,\n event: (context as any).event || (prInfo as any)?.eventType,\n actor:\n (prInfo as any)?.eventContext?.sender?.login ||\n (typeof process.env.GITHUB_ACTOR === 'string' ? process.env.GITHUB_ACTOR : undefined),\n },\n octokit,\n webhookContext: (engine as any).getExecutionContext?.()?.webhookContext,\n // Surface any injected test doubles for Slack as well\n slack:\n (engine as any).getExecutionContext?.()?.slack ||\n (engine as any).getExecutionContext?.()?.slackClient,\n }));\n\n // Snapshot-on-human-input support for resumed runs\n try {\n bus.on('HumanInputRequested', async (envelope: any) => {\n try {\n const ev = (envelope && envelope.payload) || envelope;\n // Determine channel/thread from event or inbound payload\n let channel: string | undefined = ev?.channel;\n let threadTs: string | undefined = ev?.threadTs;\n if (!channel || !threadTs) {\n try {\n const anyCfg: any = config || {};\n const slackCfg: any = anyCfg.slack || {};\n const endpoint: string = slackCfg.endpoint || '/bots/slack/support';\n const map = (engine as any).getExecutionContext?.()?.webhookContext?.webhookData as\n | Map<string, unknown>\n | undefined;\n const payload: any = map?.get(endpoint);\n const e: any = payload?.event;\n const derivedTs = String(e?.thread_ts || e?.ts || e?.event_ts || '');\n const derivedCh = String(e?.channel || '');\n if (derivedCh && derivedTs) {\n channel = channel || derivedCh;\n threadTs = threadTs || derivedTs;\n }\n } catch {}\n }\n\n const checkId = String(ev?.checkId || 'unknown');\n const threadKey =\n ev?.threadKey || (channel && threadTs ? `${channel}:${threadTs}` : 'session');\n const baseDir =\n process.env.VISOR_SNAPSHOT_DIR || path.resolve(process.cwd(), '.visor', 'snapshots');\n fs.mkdirSync(baseDir, { recursive: true });\n const filePath = path.join(baseDir, `${threadKey}-${checkId}.json`);\n await engine.saveSnapshotToFile(filePath);\n logger.info(`[Snapshot] Saved run snapshot: ${filePath}`);\n try {\n await bus.emit({\n type: 'SnapshotSaved',\n checkId: ev?.checkId || 'unknown',\n channel,\n threadTs,\n threadKey,\n filePath,\n });\n } catch {}\n } catch (e) {\n logger.warn(\n `[Snapshot] Failed to save snapshot on HumanInputRequested: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n });\n } catch {}\n } catch (err) {\n logger.warn(\n `[Frontends] Failed to initialize frontends (resumeFromSnapshot): ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n }\n }\n\n // Create runner and hydrate state\n // For resume flows, we treat the snapshot's journal as prior history and\n // start a fresh run from the normal Init → PlanReady → WavePlanning cycle.\n // This avoids resuming mid-wave and accidentally re-running stale checks\n // (e.g., chat replies) before new input is incorporated.\n const runner = new (require('./state-machine/runner').StateMachineRunner)(\n context,\n (engine as any).debugServer\n );\n (engine as any)._lastContext = context;\n (engine as any)._lastRunner = runner;\n\n const result = await runner.run();\n\n // Stop frontends if started\n if (frontendsHost && typeof frontendsHost.stopAll === 'function') {\n try {\n await frontendsHost.stopAll();\n } catch {}\n }\n\n // Cleanup AI sessions after execution\n try {\n const { SessionRegistry } = await import('./session-registry');\n const sessionRegistry = SessionRegistry.getInstance();\n sessionRegistry.clearAllSessions();\n } catch (error) {\n logger.debug(`[StateMachine] Failed to cleanup sessions: ${error}`);\n }\n\n return result;\n}\n","/*\n Thin SDK façade for programmatic use of Visor.\n - No new execution logic; delegates to existing engine and config manager.\n - Dual ESM/CJS bundle via tsup.\n*/\n\nimport { StateMachineExecutionEngine } from './state-machine-execution-engine';\nimport { ConfigManager } from './config';\nimport type { AnalysisResult } from './output-formatters';\nimport type { VisorConfig, TagFilter, HumanInputRequest } from './types/config';\nimport type { ExecutionContext } from './providers/check-provider.interface';\n\nexport type { VisorConfig, TagFilter, HumanInputRequest, ExecutionContext };\n\nexport interface VisorOptions {\n cwd?: string;\n debug?: boolean;\n maxParallelism?: number;\n failFast?: boolean;\n tagFilter?: TagFilter;\n}\n\nexport interface RunOptions extends VisorOptions {\n config?: VisorConfig;\n configPath?: string;\n checks?: string[]; // default: all checks from config\n timeoutMs?: number;\n output?: { format?: 'table' | 'json' | 'markdown' | 'sarif' };\n /** Strict mode: treat config warnings (like unknown keys) as errors (default: false) */\n strictValidation?: boolean;\n /** Execution context for providers (CLI message, hooks, etc.) */\n executionContext?: ExecutionContext;\n}\n\n/**\n * Load and validate a Visor config.\n * @param configOrPath - Config object, file path, or omit to discover defaults\n * @param options - Validation options\n * @returns Validated config with defaults applied\n */\nexport async function loadConfig(\n configOrPath?: string | Partial<VisorConfig>,\n options?: { strict?: boolean }\n): Promise<VisorConfig> {\n const cm = new ConfigManager();\n\n // If it's an object, validate and return with defaults\n if (typeof configOrPath === 'object' && configOrPath !== null) {\n cm.validateConfig(configOrPath, options?.strict ?? false);\n\n // Apply lightweight defaults without expensive file system operations\n const defaultConfig: Partial<VisorConfig> = {\n version: '1.0',\n checks: {},\n max_parallelism: 3,\n fail_fast: false,\n };\n\n return {\n ...defaultConfig,\n ...configOrPath,\n checks: configOrPath.checks || {},\n } as VisorConfig;\n }\n\n // If it's a string, load from file\n if (typeof configOrPath === 'string') {\n return cm.loadConfig(configOrPath);\n }\n\n // Otherwise discover default config file\n return cm.findAndLoadConfig();\n}\n\n/** Expand check IDs by including their dependencies (shallow->deep). */\nexport function resolveChecks(checkIds: string[], config: VisorConfig | undefined): string[] {\n if (!config?.checks) return Array.from(new Set(checkIds));\n const resolved = new Set<string>();\n const visiting = new Set<string>();\n const result: string[] = [];\n\n const dfs = (id: string, stack: string[] = []) => {\n if (resolved.has(id)) return;\n if (visiting.has(id)) {\n const cycle = [...stack, id].join(' -> ');\n throw new Error(`Circular dependency detected involving check: ${id} (path: ${cycle})`);\n }\n visiting.add(id);\n const deps = config.checks![id]?.depends_on || [];\n for (const d of deps) dfs(d, [...stack, id]);\n if (!result.includes(id)) result.push(id);\n visiting.delete(id);\n resolved.add(id);\n };\n\n for (const id of checkIds) dfs(id);\n return result;\n}\n\n/**\n * Run Visor checks programmatically. Returns the same AnalysisResult shape used by the CLI.\n * Thin wrapper around CheckExecutionEngine.executeChecks.\n */\nexport async function runChecks(opts: RunOptions = {}): Promise<AnalysisResult> {\n const cm = new ConfigManager();\n let config: VisorConfig;\n\n if (opts.config) {\n // Validate manually constructed config\n // In strict mode, unknown keys are treated as errors\n cm.validateConfig(opts.config, opts.strictValidation ?? false);\n config = opts.config;\n } else if (opts.configPath) {\n config = await cm.loadConfig(opts.configPath);\n } else {\n config = await cm.findAndLoadConfig();\n }\n\n const checks =\n opts.checks && opts.checks.length > 0\n ? resolveChecks(opts.checks, config)\n : Object.keys(config.checks || {});\n\n // Always use StateMachineExecutionEngine\n const engine = new StateMachineExecutionEngine(opts.cwd);\n\n // Set execution context if provided\n if (opts.executionContext) {\n engine.setExecutionContext(opts.executionContext);\n }\n\n const result = await engine.executeChecks({\n checks,\n workingDirectory: opts.cwd,\n timeout: opts.timeoutMs,\n maxParallelism: opts.maxParallelism,\n failFast: opts.failFast,\n outputFormat: opts.output?.format,\n config,\n debug: opts.debug,\n tagFilter: opts.tagFilter,\n });\n\n return result;\n}\n"],"mappings":"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","names":["path","MemoryStore","ConfigManager","initializeWorkspace","buildEngineContextForRun","fs","convertToReviewSummary"]}
|