@probelabs/visor 0.1.148-ee → 0.1.149

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/defaults/assistant.yaml +2141 -0
  2. package/defaults/code-talk.yaml +1250 -0
  3. package/defaults/intent-router.yaml +478 -0
  4. package/dist/defaults/assistant.yaml +2141 -0
  5. package/dist/defaults/code-talk.yaml +1250 -0
  6. package/dist/defaults/intent-router.yaml +478 -0
  7. package/dist/index.js +38 -1722
  8. package/dist/output/traces/run-2026-03-03T07-19-07-543Z.ndjson +138 -0
  9. package/dist/output/traces/run-2026-03-03T07-19-50-933Z.ndjson +2121 -0
  10. package/dist/sdk/check-provider-registry-IYSUDKPB.mjs +29 -0
  11. package/dist/sdk/{check-provider-registry-AMYY2ZJY.mjs → check-provider-registry-LVLC4EPF.mjs} +4 -4
  12. package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs → check-provider-registry-X4OZJWPK.mjs} +4 -4
  13. package/dist/sdk/{chunk-75Q63UNX.mjs → chunk-6EXCUX7Y.mjs} +12 -12
  14. package/dist/sdk/{chunk-75Q63UNX.mjs.map → chunk-6EXCUX7Y.mjs.map} +1 -1
  15. package/dist/sdk/chunk-BR7DYA3S.mjs +739 -0
  16. package/dist/sdk/chunk-BR7DYA3S.mjs.map +1 -0
  17. package/dist/sdk/{chunk-DIND4ZCV.mjs → chunk-DNDS7R3N.mjs} +11 -1
  18. package/dist/sdk/{chunk-DIND4ZCV.mjs.map → chunk-DNDS7R3N.mjs.map} +1 -1
  19. package/dist/sdk/chunk-GFNXX64M.mjs +43159 -0
  20. package/dist/sdk/chunk-GFNXX64M.mjs.map +1 -0
  21. package/dist/sdk/chunk-Q6EPAJ6Z.mjs +1502 -0
  22. package/dist/sdk/chunk-Q6EPAJ6Z.mjs.map +1 -0
  23. package/dist/sdk/{chunk-H4AYMOAT.mjs → chunk-V6GI4U2M.mjs} +10 -10
  24. package/dist/sdk/chunk-VLUGLWLA.mjs +443 -0
  25. package/dist/sdk/chunk-VLUGLWLA.mjs.map +1 -0
  26. package/dist/sdk/{chunk-XNTBSV6M.mjs → chunk-YYZAN5NK.mjs} +3 -3
  27. package/dist/sdk/{config-G5UU4WXT.mjs → config-KQH254CA.mjs} +2 -2
  28. package/dist/sdk/failure-condition-evaluator-LZ2AG5PY.mjs +17 -0
  29. package/dist/sdk/github-frontend-S523EEJB.mjs +1368 -0
  30. package/dist/sdk/github-frontend-S523EEJB.mjs.map +1 -0
  31. package/dist/sdk/{host-NZXGBBJI.mjs → host-7YKRMOUJ.mjs} +2 -2
  32. package/dist/sdk/routing-ZMBKWMVI.mjs +25 -0
  33. package/dist/sdk/schedule-tool-CDVUSZEG.mjs +35 -0
  34. package/dist/sdk/{schedule-tool-4JMWZCCK.mjs → schedule-tool-EOMZFICZ.mjs} +4 -4
  35. package/dist/sdk/{schedule-tool-CONR4VW3.mjs → schedule-tool-NX75VKGA.mjs} +4 -4
  36. package/dist/sdk/schedule-tool-handler-3FJHDIPG.mjs +39 -0
  37. package/dist/sdk/{schedule-tool-handler-AXMR7NBI.mjs → schedule-tool-handler-KKN7XJYT.mjs} +4 -4
  38. package/dist/sdk/schedule-tool-handler-KKN7XJYT.mjs.map +1 -0
  39. package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs → schedule-tool-handler-QNZG55DX.mjs} +4 -4
  40. package/dist/sdk/schedule-tool-handler-QNZG55DX.mjs.map +1 -0
  41. package/dist/sdk/sdk.js +269 -1517
  42. package/dist/sdk/sdk.js.map +1 -1
  43. package/dist/sdk/sdk.mjs +6 -6
  44. package/dist/sdk/trace-helpers-EJUIOP6L.mjs +25 -0
  45. package/dist/sdk/trace-helpers-EJUIOP6L.mjs.map +1 -0
  46. package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs +29 -0
  47. package/dist/sdk/workflow-check-provider-6ERNNCNA.mjs.map +1 -0
  48. package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs → workflow-check-provider-AGZ5JY2I.mjs} +4 -4
  49. package/dist/sdk/workflow-check-provider-AGZ5JY2I.mjs.map +1 -0
  50. package/dist/sdk/{workflow-check-provider-MMB7L3YG.mjs → workflow-check-provider-PTNUWM5W.mjs} +4 -4
  51. package/dist/sdk/workflow-check-provider-PTNUWM5W.mjs.map +1 -0
  52. package/dist/sdk/{workflow-registry-AAD37XKZ.mjs → workflow-registry-MHUSKSD6.mjs} +2 -2
  53. package/dist/sdk/workflow-registry-MHUSKSD6.mjs.map +1 -0
  54. package/dist/traces/run-2026-03-03T07-19-07-543Z.ndjson +138 -0
  55. package/dist/traces/run-2026-03-03T07-19-50-933Z.ndjson +2121 -0
  56. package/dist/workflow-registry.d.ts.map +1 -1
  57. package/package.json +1 -1
  58. package/dist/sdk/knex-store-HPXJILBL.mjs +0 -411
  59. package/dist/sdk/knex-store-HPXJILBL.mjs.map +0 -1
  60. package/dist/sdk/loader-YSRMVXC3.mjs +0 -89
  61. package/dist/sdk/loader-YSRMVXC3.mjs.map +0 -1
  62. package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +0 -655
  63. package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs.map +0 -1
  64. package/dist/sdk/validator-XTZJZZJH.mjs +0 -134
  65. package/dist/sdk/validator-XTZJZZJH.mjs.map +0 -1
  66. /package/dist/sdk/{check-provider-registry-AMYY2ZJY.mjs.map → check-provider-registry-IYSUDKPB.mjs.map} +0 -0
  67. /package/dist/sdk/{check-provider-registry-DVQDGTOE.mjs.map → check-provider-registry-LVLC4EPF.mjs.map} +0 -0
  68. /package/dist/sdk/{config-G5UU4WXT.mjs.map → check-provider-registry-X4OZJWPK.mjs.map} +0 -0
  69. /package/dist/sdk/{chunk-H4AYMOAT.mjs.map → chunk-V6GI4U2M.mjs.map} +0 -0
  70. /package/dist/sdk/{chunk-XNTBSV6M.mjs.map → chunk-YYZAN5NK.mjs.map} +0 -0
  71. /package/dist/sdk/{schedule-tool-4JMWZCCK.mjs.map → config-KQH254CA.mjs.map} +0 -0
  72. /package/dist/sdk/{schedule-tool-CONR4VW3.mjs.map → failure-condition-evaluator-LZ2AG5PY.mjs.map} +0 -0
  73. /package/dist/sdk/{host-NZXGBBJI.mjs.map → host-7YKRMOUJ.mjs.map} +0 -0
  74. /package/dist/sdk/{schedule-tool-handler-AXMR7NBI.mjs.map → routing-ZMBKWMVI.mjs.map} +0 -0
  75. /package/dist/sdk/{schedule-tool-handler-YUC6CAXX.mjs.map → schedule-tool-CDVUSZEG.mjs.map} +0 -0
  76. /package/dist/sdk/{workflow-check-provider-DYSO3PML.mjs.map → schedule-tool-EOMZFICZ.mjs.map} +0 -0
  77. /package/dist/sdk/{workflow-check-provider-MMB7L3YG.mjs.map → schedule-tool-NX75VKGA.mjs.map} +0 -0
  78. /package/dist/sdk/{workflow-registry-AAD37XKZ.mjs.map → schedule-tool-handler-3FJHDIPG.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/failure-condition-evaluator.ts"],"sourcesContent":["/**\n * Failure condition evaluation engine using SandboxJS for secure expression evaluation\n */\n\nimport { ReviewSummary } from './reviewer';\nimport { addEvent } from './telemetry/trace-helpers';\nimport { addFailIfTriggered } from './telemetry/metrics';\nimport {\n FailureConditions,\n FailureCondition,\n FailureConditionContext,\n FailureConditionResult,\n FailureConditionSeverity,\n} from './types/config';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox } from './utils/sandbox';\nimport { createPermissionHelpers, detectLocalMode } from './utils/author-permissions';\nimport { MemoryStore } from './memory-store';\n\n/**\n * Evaluates failure conditions using SandboxJS for secure evaluation\n */\nexport class FailureConditionEvaluator {\n private sandbox?: Sandbox;\n\n constructor() {}\n\n /**\n * Create a secure sandbox with whitelisted functions and globals\n */\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n /**\n * Evaluate simple fail_if condition\n */\n async evaluateSimpleCondition(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n expression: string,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): Promise<boolean> {\n const context = this.buildEvaluationContext(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n previousOutputs,\n authorAssociation\n );\n\n try {\n try {\n const isObj = context.output && typeof context.output === 'object';\n const keys = isObj ? Object.keys(context.output as any).join(',') : typeof context.output;\n let errorVal: unknown = undefined;\n if (isObj && (context.output as any).error !== undefined)\n errorVal = (context.output as any).error;\n require('./logger').logger.debug(\n ` fail_if: evaluating '${expression}' with output keys=${keys} error=${String(errorVal)}`\n );\n } catch {}\n const res = this.evaluateExpression(expression, context);\n if (res === true) {\n try {\n addEvent('fail_if.triggered', {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression,\n severity: 'error',\n });\n } catch {}\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: checkName, scope: 'check', name: `${checkName}_fail_if` },\n [\n {\n name: 'fail_if.triggered',\n attrs: {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression,\n severity: 'error',\n },\n },\n ]\n );\n } catch {}\n }\n return res;\n } catch (error) {\n console.warn(`Failed to evaluate fail_if expression: ${error}`);\n return false; // Don't fail on evaluation errors\n }\n }\n\n /**\n * Determine if the event is related to pull requests\n */\n private determineIfPullRequest(eventType?: string): boolean {\n if (!eventType) return false;\n\n const prEvents = ['pr_opened', 'pr_updated', 'pr_closed', 'pull_request'];\n return prEvents.includes(eventType) || eventType.startsWith('pr_');\n }\n\n /**\n * Determine if the event is related to issues\n */\n private determineIfIssue(eventType?: string): boolean {\n if (!eventType) return false;\n\n const issueEvents = ['issue_opened', 'issue_comment', 'issues'];\n return issueEvents.includes(eventType) || eventType.startsWith('issue_');\n }\n\n /**\n * Evaluate if condition to determine whether a check should run\n */\n async evaluateIfCondition(\n checkName: string,\n expression: string,\n contextData?: {\n branch?: string;\n baseBranch?: string;\n filesChanged?: string[];\n event?: string;\n environment?: Record<string, string>;\n previousResults?: Map<string, ReviewSummary>;\n authorAssociation?: string;\n workflowInputs?: Record<string, unknown>;\n /** Current step's output for guarantee evaluation */\n output?: unknown;\n /** Conversation context for TUI/CLI/Slack messages */\n conversation?: {\n transport?: string;\n thread?: { id: string };\n messages?: Array<{ role: string; text: string; timestamp: string }>;\n current?: { role: string; text: string; timestamp: string };\n attributes?: Record<string, unknown>;\n };\n }\n ): Promise<boolean> {\n // Build context for if evaluation\n const context = {\n // Check metadata\n checkName,\n\n // Git context\n branch: contextData?.branch || 'unknown',\n baseBranch: contextData?.baseBranch || 'main',\n filesChanged: contextData?.filesChanged || [],\n filesCount: contextData?.filesChanged?.length || 0,\n\n // GitHub event context\n event: {\n event_name: contextData?.event || 'manual',\n action: undefined, // Would be populated from actual GitHub context\n repository: undefined, // Would be populated from actual GitHub context\n },\n\n // Environment variables\n env: contextData?.environment || {},\n\n // Previous check results (unwrap output field like templates do)\n outputs: contextData?.previousResults\n ? (() => {\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of contextData.previousResults) {\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 outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n return outputs;\n })()\n : {},\n\n // Workflow inputs (for workflows)\n inputs: contextData?.workflowInputs || {},\n\n // Output property: use provided output for guarantee evaluation, or empty for if conditions\n output:\n contextData?.output !== undefined &&\n contextData.output !== null &&\n typeof contextData.output === 'object'\n ? (contextData.output as Record<string, unknown>)\n : { issues: [] },\n // Author association (used by permission helpers)\n authorAssociation: contextData?.authorAssociation,\n\n // Utility metadata\n metadata: {\n checkName,\n schema: '',\n group: '',\n criticalIssues: 0,\n errorIssues: 0,\n warningIssues: 0,\n infoIssues: 0,\n totalIssues: 0,\n hasChanges: (contextData?.filesChanged?.length || 0) > 0,\n branch: contextData?.branch || 'unknown',\n event: contextData?.event || 'manual',\n },\n\n // Conversation context (for TUI/CLI/Slack)\n conversation: contextData?.conversation,\n };\n\n try {\n const res = this.evaluateExpression(expression, context);\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n // Debug if-eval output (only when VISOR_DEBUG enabled)\n const outputKeys = Object.keys(context.outputs || {});\n console.error(\n `[if-eval] check=${checkName} expr=\"${expression}\" result=${String(res)} outputKeys=[${outputKeys.join(',')}]`\n );\n }\n } catch {}\n return res;\n } catch (error) {\n console.warn(`Failed to evaluate if expression for check '${checkName}': ${error}`);\n // Fail-secure: do not run the check on evaluation errors\n return false;\n }\n }\n\n /**\n * Evaluate all failure conditions for a check result\n */\n async evaluateConditions(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n globalConditions?: FailureConditions,\n checkConditions?: FailureConditions,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): Promise<FailureConditionResult[]> {\n const context = this.buildEvaluationContext(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n previousOutputs,\n authorAssociation\n );\n\n const results: FailureConditionResult[] = [];\n\n // Evaluate global conditions first\n if (globalConditions) {\n const globalResults = await this.evaluateConditionSet(globalConditions, context, 'global');\n results.push(...globalResults);\n }\n\n // Evaluate check-specific conditions (these override global ones with same name)\n if (checkConditions) {\n const checkResults = await this.evaluateConditionSet(checkConditions, context, 'check');\n\n // Remove global conditions that are overridden by check-specific ones\n const overriddenConditions = new Set(Object.keys(checkConditions));\n const filteredResults = results.filter(\n result => !overriddenConditions.has(result.conditionName)\n );\n\n results.length = 0;\n results.push(...filteredResults, ...checkResults);\n }\n\n return results;\n }\n\n /**\n * Evaluate a set of failure conditions\n */\n private async evaluateConditionSet(\n conditions: FailureConditions,\n context: FailureConditionContext,\n source: 'global' | 'check'\n ): Promise<FailureConditionResult[]> {\n const results: FailureConditionResult[] = [];\n\n for (const [conditionName, condition] of Object.entries(conditions)) {\n try {\n addEvent('fail_if.evaluated', {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: this.extractExpression(condition),\n });\n } catch {}\n\n // File fallback: append an NDJSON span with the evaluation event\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: context.checkName || 'unknown', scope: source, name: conditionName },\n [\n {\n name: 'fail_if.evaluated',\n attrs: {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: this.extractExpression(condition),\n },\n },\n ]\n );\n } catch {}\n\n try {\n const result = await this.evaluateSingleCondition(conditionName, condition, context);\n results.push(result);\n\n if (result.failed) {\n try {\n addEvent('fail_if.triggered', {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: result.expression,\n severity: result.severity,\n halt_execution: result.haltExecution,\n });\n } catch {}\n try {\n addFailIfTriggered(context.checkName || 'unknown', source);\n } catch {}\n }\n } catch (error) {\n // If evaluation fails, create an error result\n results.push({\n conditionName,\n failed: false,\n expression: this.extractExpression(condition),\n severity: 'error',\n haltExecution: false,\n error: `Failed to evaluate ${source} condition '${conditionName}': ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Evaluate a single failure condition\n */\n private async evaluateSingleCondition(\n conditionName: string,\n condition: FailureCondition,\n context: FailureConditionContext\n ): Promise<FailureConditionResult> {\n const expression = this.extractExpression(condition);\n const config = this.extractConditionConfig(condition);\n\n try {\n const failed = this.evaluateExpression(expression, context);\n\n return {\n conditionName,\n failed,\n expression,\n message: config.message,\n severity: config.severity || 'error',\n haltExecution: config.halt_execution || false,\n };\n } catch (error) {\n throw new Error(\n `Expression evaluation error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Secure expression evaluation using SandboxJS\n * Supports the same GitHub Actions-style functions as the previous implementation\n */\n private evaluateExpression(condition: string, context: FailureConditionContext): boolean {\n try {\n // Normalize multi-line or semicolon-separated expressions.\n // Allows writing debug statements on separate lines, e.g.:\n // log(\"start\")\n // log(outputs)\n // outputs[\"fetch-tickets\"].issueType === 'Bug'\n // We convert to a single expression using the comma operator so the\n // final expression determines the boolean result.\n const normalize = (expr: string): string => {\n const trimmed = expr.trim();\n // If it's already a single-line expression without semicolons, keep it.\n if (!/[\\n;]/.test(trimmed)) return trimmed;\n\n // Split on newlines/semicolons, drop empty and comment-only lines.\n const parts = trimmed\n .split(/[\\n;]+/)\n .map(s => s.trim())\n .filter(s => s.length > 0 && !s.startsWith('//'));\n\n if (parts.length === 0) return 'true';\n\n // Support an explicit return in the last statement.\n const lastRaw = parts.pop() as string;\n const last = lastRaw.replace(/^return\\s+/i, '').trim();\n\n // Join leading statements with comma operator; last expression returns value.\n if (parts.length === 0) return last;\n return `(${parts.join(', ')}, ${last})`;\n };\n\n // note: normalization happens later only if raw compilation fails\n // Helper functions for GitHub Actions-style expressions\n const contains = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().includes(String(searchValue).toLowerCase());\n\n const startsWith = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().startsWith(String(searchValue).toLowerCase());\n\n const endsWith = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().endsWith(String(searchValue).toLowerCase());\n\n const length = (value: string | unknown[] | Record<string, unknown>): number => {\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length;\n }\n if (value && typeof value === 'object') {\n return Object.keys(value).length;\n }\n return 0;\n };\n\n const always = (): boolean => true;\n const success = (): boolean => true;\n const failure = (): boolean => false;\n\n // Debug logging function for printing to console\n const log = (...args: unknown[]): void => {\n console.log('🔍 Debug:', ...args);\n };\n\n // Helper functions for array operations\n const hasIssue = (issues: unknown[], field: string, value: unknown): boolean => {\n if (!Array.isArray(issues)) return false;\n return issues.some(issue => (issue as Record<string, unknown>)[field] === value);\n };\n\n const countIssues = (issues: unknown[], field: string, value: unknown): number => {\n if (!Array.isArray(issues)) return 0;\n return issues.filter(issue => (issue as Record<string, unknown>)[field] === value).length;\n };\n\n const hasFileMatching = (issues: unknown[], pattern: string): boolean => {\n if (!Array.isArray(issues)) return false;\n return issues.some(issue => (issue as { file?: string }).file?.includes(pattern));\n };\n\n // Backward compatibility aliases\n const hasIssueWith = hasIssue;\n const hasFileWith = hasFileMatching;\n\n // Permission helper functions\n const permissionHelpers = createPermissionHelpers(\n context.authorAssociation,\n detectLocalMode()\n );\n const hasMinPermission = permissionHelpers.hasMinPermission;\n const isOwner = permissionHelpers.isOwner;\n const isMember = permissionHelpers.isMember;\n const isCollaborator = permissionHelpers.isCollaborator;\n const isContributor = permissionHelpers.isContributor;\n const isFirstTimer = permissionHelpers.isFirstTimer;\n\n // Extract context variables\n const output = context.output || {};\n // Ensure issues is an array - it might be a JSON string from workflow outputs\n let issues = output.issues || [];\n if (typeof issues === 'string') {\n try {\n issues = JSON.parse(issues);\n } catch {\n issues = [];\n }\n }\n if (!Array.isArray(issues)) {\n issues = [];\n }\n\n // Backward compatibility: provide metadata for transition period\n // TODO: Remove after all configurations are updated\n const metadata = context.metadata || {\n checkName: context.checkName || '',\n schema: context.schema || '',\n group: context.group || '',\n criticalIssues: issues.filter((i: { severity?: string }) => i.severity === 'critical')\n .length,\n errorIssues: issues.filter((i: { severity?: string }) => i.severity === 'error').length,\n warningIssues: issues.filter((i: { severity?: string }) => i.severity === 'warning').length,\n infoIssues: issues.filter((i: { severity?: string }) => i.severity === 'info').length,\n totalIssues: issues.length,\n hasChanges: context.hasChanges || false,\n };\n\n // Do not mutate output shape here. Output contracts are defined by providers and\n // workflow outputs. Tests and expressions should rely on those schemas directly.\n\n // Legacy variables for backward compatibility\n const criticalIssues = metadata.criticalIssues;\n const errorIssues = metadata.errorIssues;\n const totalIssues = metadata.totalIssues;\n const warningIssues = metadata.warningIssues;\n const infoIssues = metadata.infoIssues;\n\n // Additional context for 'if' conditions and some failure conditions\n const checkName = context.checkName || '';\n const schema = context.schema || '';\n const group = context.group || '';\n const branch = context.branch || 'unknown';\n const baseBranch = context.baseBranch || 'main';\n const filesChanged = context.filesChanged || [];\n const filesCount = context.filesCount || 0;\n const event = context.event || 'manual';\n const env = context.env || {};\n const outputs = context.outputs || {};\n const inputs = context.inputs || {};\n const debugData = context.debug || null;\n const conversation = context.conversation || null;\n\n // Get memory store and create accessor for fail_if expressions\n const memoryStore = MemoryStore.getInstance();\n const memoryAccessor = {\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 };\n\n // Create scope with all context variables and helper functions\n const scope = {\n // Primary context variables\n output,\n outputs,\n debug: debugData,\n // Memory accessor for fail_if expressions\n memory: memoryAccessor,\n // Legacy compatibility variables\n issues,\n metadata,\n criticalIssues,\n errorIssues,\n totalIssues,\n warningIssues,\n infoIssues,\n // If condition context\n checkName,\n schema,\n group,\n branch,\n baseBranch,\n filesChanged,\n filesCount,\n event,\n env,\n inputs,\n // Conversation context (TUI/CLI/Slack)\n conversation,\n // Helper functions\n contains,\n startsWith,\n endsWith,\n length,\n always,\n success,\n failure,\n log,\n hasIssue,\n countIssues,\n hasFileMatching,\n hasIssueWith,\n hasFileWith,\n // Permission helpers\n hasMinPermission,\n isOwner,\n isMember,\n isCollaborator,\n isContributor,\n isFirstTimer,\n };\n\n // Compile and execute the expression in the sandbox\n const raw = condition.trim();\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n let exec: ReturnType<typeof this.sandbox.compile>;\n try {\n exec = this.sandbox.compile(`return (${raw});`);\n } catch {\n const normalizedExpr = normalize(condition);\n exec = this.sandbox.compile(`return (${normalizedExpr});`);\n }\n const result = exec(scope).run();\n try {\n require('./logger').logger.debug(` fail_if: result=${Boolean(result)}`);\n } catch {}\n // Ensure we return a boolean\n return Boolean(result);\n } catch (error) {\n console.error('❌ Failed to evaluate expression:', condition, error);\n // Re-throw the error so it can be caught by evaluateSingleCondition\n // and properly populate the error field in the result\n throw error;\n }\n }\n\n /**\n * Extract the expression from a failure condition\n */\n private extractExpression(condition: FailureCondition): string {\n if (typeof condition === 'string') {\n return condition;\n }\n return condition.condition;\n }\n\n /**\n * Extract configuration from a failure condition\n */\n private extractConditionConfig(condition: FailureCondition): {\n message?: string;\n severity?: FailureConditionSeverity;\n halt_execution?: boolean;\n } {\n if (typeof condition === 'string') {\n return {};\n }\n return {\n message: condition.message,\n severity: condition.severity,\n halt_execution: condition.halt_execution,\n };\n }\n\n /**\n * Build the evaluation context for expressions\n */\n private buildEvaluationContext(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): FailureConditionContext {\n const { issues, debug } = reviewSummary;\n const reviewSummaryWithOutput = reviewSummary as ReviewSummary & { output?: unknown };\n\n // Extract output field to avoid nesting (output.output)\n const {\n output: extractedOutput,\n // Exclude issues from otherFields since we handle it separately\n issues: _issues, // eslint-disable-line @typescript-eslint/no-unused-vars\n ...otherFields\n } = reviewSummaryWithOutput as any;\n\n // Build output object with safety for array-based outputs (forEach aggregation)\n const aggregatedOutput: Record<string, unknown> = {\n issues: (issues || []).map(issue => ({\n file: issue.file,\n line: issue.line,\n endLine: issue.endLine,\n ruleId: issue.ruleId,\n message: issue.message,\n severity: issue.severity,\n category: issue.category,\n group: issue.group,\n schema: issue.schema,\n suggestion: issue.suggestion,\n replacement: issue.replacement,\n })),\n // Include additional schema-specific data from reviewSummary\n ...otherFields,\n };\n\n if (Array.isArray(extractedOutput)) {\n // Preserve items array and lift common flags for convenience (e.g., output.error)\n aggregatedOutput.items = extractedOutput;\n const anyError = extractedOutput.find(\n it => it && typeof it === 'object' && (it as Record<string, unknown>).error\n ) as Record<string, unknown> | undefined;\n if (anyError && anyError.error !== undefined) {\n aggregatedOutput.error = anyError.error;\n }\n } else if (extractedOutput && typeof extractedOutput === 'object') {\n Object.assign(aggregatedOutput, extractedOutput as Record<string, unknown>);\n }\n\n // If provider attached a raw transform snapshot, merge its fields generically.\n try {\n const raw = (reviewSummaryWithOutput as any).__raw;\n if (raw && typeof raw === 'object') {\n Object.assign(aggregatedOutput, raw as Record<string, unknown>);\n }\n } catch {}\n\n // If output is a string, try to parse JSON (full or from end) to enrich context,\n // and also derive common boolean flags generically (e.g., key:true/false) for fail_if usage.\n try {\n if (typeof extractedOutput === 'string') {\n const parsed =\n this.tryExtractJsonFromEnd(extractedOutput) ??\n (() => {\n try {\n return JSON.parse(extractedOutput);\n } catch {\n return null;\n }\n })();\n if (parsed !== null) {\n if (Array.isArray(parsed)) {\n (aggregatedOutput as any).items = parsed;\n } else if (typeof parsed === 'object') {\n Object.assign(aggregatedOutput, parsed as Record<string, unknown>);\n }\n }\n // Generic boolean key extraction for simple text outputs (no special provider cases)\n const lower = extractedOutput.toLowerCase();\n const boolFrom = (key: string): boolean | null => {\n const reTrue = new RegExp(\n `(?:^|[^a-z0-9_])${key}[^a-z0-9_]*[:=][^a-z0-9_]*true(?:[^a-z0-9_]|$)`\n );\n const reFalse = new RegExp(\n `(?:^|[^a-z0-9_])${key}[^a-z0-9_]*[:=][^a-z0-9_]*false(?:[^a-z0-9_]|$)`\n );\n if (reTrue.test(lower)) return true;\n if (reFalse.test(lower)) return false;\n return null;\n };\n const keys = ['error'];\n for (const k of keys) {\n const v = boolFrom(k);\n if (v !== null && (aggregatedOutput as any)[k] === undefined) {\n (aggregatedOutput as any)[k] = v;\n }\n }\n }\n } catch {}\n\n // Try to parse JSON from content as a last resort when no structured output is present\n try {\n const rsAny = reviewSummaryWithOutput as any;\n const hasStructuredOutput = extractedOutput !== undefined && extractedOutput !== null;\n if (!hasStructuredOutput && typeof rsAny?.content === 'string') {\n const parsedFromContent = this.tryExtractJsonFromEnd(rsAny.content);\n if (parsedFromContent !== null && parsedFromContent !== undefined) {\n if (Array.isArray(parsedFromContent)) {\n (aggregatedOutput as any).items = parsedFromContent;\n } else if (typeof parsedFromContent === 'object') {\n Object.assign(aggregatedOutput, parsedFromContent as Record<string, unknown>);\n }\n }\n }\n } catch {}\n\n // Get memory store instance\n const memoryStore = MemoryStore.getInstance();\n\n const context: FailureConditionContext = {\n output: aggregatedOutput,\n outputs: (() => {\n if (!previousOutputs) return {};\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of Object.entries(previousOutputs)) {\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 outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n return outputs;\n })(),\n // Add memory accessor for fail_if expressions\n 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 any,\n // Add basic context info for failure conditions\n checkName: checkName,\n schema: checkSchema,\n group: checkGroup,\n authorAssociation: authorAssociation,\n };\n\n // Add debug information if available\n if (debug) {\n context.debug = {\n errors: debug.errors || [],\n processingTime: debug.processingTime || 0,\n provider: debug.provider || 'unknown',\n model: debug.model || 'unknown',\n };\n }\n\n return context;\n }\n\n // Minimal JSON-from-end extractor for fail_if context fallback\n private tryExtractJsonFromEnd(text: string): unknown | null {\n try {\n const lines = text.split('\\n');\n for (let i = lines.length - 1; i >= 0; i--) {\n const t = lines[i].trim();\n if (t.startsWith('{') || t.startsWith('[')) {\n const candidate = lines.slice(i).join('\\n').trim();\n if (\n (candidate.startsWith('{') && candidate.endsWith('}')) ||\n (candidate.startsWith('[') && candidate.endsWith(']'))\n ) {\n return JSON.parse(candidate);\n }\n }\n }\n } catch {}\n return null;\n }\n\n /**\n * Check if any failure condition requires halting execution\n */\n static shouldHaltExecution(results: FailureConditionResult[]): boolean {\n return results.some(result => result.failed && result.haltExecution);\n }\n\n /**\n * Get all failed conditions\n */\n static getFailedConditions(results: FailureConditionResult[]): FailureConditionResult[] {\n return results.filter(result => result.failed);\n }\n\n /**\n * Group results by severity\n */\n static groupResultsBySeverity(results: FailureConditionResult[]): {\n error: FailureConditionResult[];\n warning: FailureConditionResult[];\n info: FailureConditionResult[];\n } {\n return {\n // Only 'error' severity now (no backward compatibility needed here as this is internal)\n error: results.filter(r => r.severity === 'error'),\n warning: results.filter(r => r.severity === 'warning'),\n info: results.filter(r => r.severity === 'info'),\n };\n }\n\n /**\n * Format results for display\n */\n static formatResults(results: FailureConditionResult[]): string {\n const failed = FailureConditionEvaluator.getFailedConditions(results);\n\n if (failed.length === 0) {\n return '✅ All failure conditions passed';\n }\n\n const grouped = FailureConditionEvaluator.groupResultsBySeverity(failed);\n const sections: string[] = [];\n\n if (grouped.error.length > 0) {\n sections.push(`❌ **Error severity conditions (${grouped.error.length}):**`);\n grouped.error.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n if (grouped.warning.length > 0) {\n sections.push(`⚠️ **Warning conditions (${grouped.warning.length}):**`);\n grouped.warning.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n if (grouped.info.length > 0) {\n sections.push(`ℹ️ **Info conditions (${grouped.info.length}):**`);\n grouped.info.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n return sections.join('\\n');\n }\n}\n"],"mappings":"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","names":["checkName","issues"]}
@@ -521,6 +521,16 @@ var init_workflow_registry = __esm({
521
521
  */
522
522
  async loadWorkflowContent(source, basePath) {
523
523
  const baseIsUrl = basePath?.startsWith("http://") || basePath?.startsWith("https://");
524
+ if (source.startsWith("visor://") || source.startsWith("visor-ee://")) {
525
+ const relativePath = source.replace(/^visor(?:-ee)?:\/\//, "");
526
+ const defaultsDir = path.resolve(__dirname, "..", "defaults");
527
+ const filePath2 = path.resolve(defaultsDir, relativePath);
528
+ if (!filePath2.startsWith(defaultsDir + path.sep)) {
529
+ throw new Error(`Invalid visor:// path: resolved path escapes defaults directory`);
530
+ }
531
+ const content2 = await fs.readFile(filePath2, "utf-8");
532
+ return { content: content2, resolvedSource: filePath2, importBasePath: path.dirname(filePath2) };
533
+ }
524
534
  if (source.startsWith("http://") || source.startsWith("https://")) {
525
535
  const response = await fetch(source);
526
536
  if (!response.ok) {
@@ -603,4 +613,4 @@ export {
603
613
  WorkflowRegistry,
604
614
  init_workflow_registry
605
615
  };
606
- //# sourceMappingURL=chunk-DIND4ZCV.mjs.map
616
+ //# sourceMappingURL=chunk-DNDS7R3N.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/dependency-resolver.ts","../../src/workflow-registry.ts"],"sourcesContent":["/**\n * Dependency resolution and execution ordering for checks\n */\n\nexport interface CheckNode {\n id: string;\n dependencies: string[];\n dependents: string[];\n depth: number;\n}\n\nexport interface ExecutionGroup {\n /** Checks that can run in parallel */\n parallel: string[];\n /** Execution level/wave (0 = no dependencies, 1 = depends on level 0, etc.) */\n level: number;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, CheckNode>;\n executionOrder: ExecutionGroup[];\n hasCycles: boolean;\n cycleNodes?: string[];\n}\n\nexport class DependencyResolver {\n /**\n * Build dependency graph from check dependencies\n */\n static buildDependencyGraph(checkDependencies: Record<string, string[]>): DependencyGraph {\n const nodes = new Map<string, CheckNode>();\n\n // Initialize all nodes\n for (const checkId of Object.keys(checkDependencies)) {\n nodes.set(checkId, {\n id: checkId,\n dependencies: checkDependencies[checkId] || [],\n dependents: [],\n depth: 0,\n });\n }\n\n // Build bidirectional relationships\n for (const [checkId, dependencies] of Object.entries(checkDependencies)) {\n for (const depId of dependencies || []) {\n if (!nodes.has(depId)) {\n throw new Error(`Check \"${checkId}\" depends on \"${depId}\" but \"${depId}\" is not defined`);\n }\n\n const depNode = nodes.get(depId)!;\n depNode.dependents.push(checkId);\n }\n }\n\n // Detect cycles using DFS\n const cycleDetection = this.detectCycles(nodes);\n if (cycleDetection.hasCycles) {\n return {\n nodes,\n executionOrder: [],\n hasCycles: true,\n cycleNodes: cycleDetection.cycleNodes,\n };\n }\n\n // Calculate execution order using topological sort\n const executionOrder = this.topologicalSort(nodes);\n\n return {\n nodes,\n executionOrder,\n hasCycles: false,\n };\n }\n\n /**\n * Detect cycles in the dependency graph using DFS\n */\n private static detectCycles(nodes: Map<string, CheckNode>): {\n hasCycles: boolean;\n cycleNodes?: string[];\n } {\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cycleNodes: string[] = [];\n\n const dfs = (nodeId: string): boolean => {\n if (recursionStack.has(nodeId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n if (visited.has(nodeId)) {\n return false;\n }\n\n visited.add(nodeId);\n recursionStack.add(nodeId);\n\n const node = nodes.get(nodeId);\n if (node) {\n for (const depId of node.dependencies) {\n if (dfs(depId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n }\n }\n\n recursionStack.delete(nodeId);\n return false;\n };\n\n for (const nodeId of nodes.keys()) {\n if (!visited.has(nodeId)) {\n if (dfs(nodeId)) {\n return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };\n }\n }\n }\n\n return { hasCycles: false };\n }\n\n /**\n * Perform topological sort to determine execution order\n * Groups checks that can run in parallel at each level\n */\n private static topologicalSort(nodes: Map<string, CheckNode>): ExecutionGroup[] {\n const remainingNodes = new Map(nodes);\n const executionGroups: ExecutionGroup[] = [];\n let level = 0;\n\n while (remainingNodes.size > 0) {\n // Find nodes with no remaining dependencies\n const readyNodes: string[] = [];\n\n for (const [nodeId, node] of remainingNodes.entries()) {\n const unmetDependencies = node.dependencies.filter(depId => remainingNodes.has(depId));\n if (unmetDependencies.length === 0) {\n readyNodes.push(nodeId);\n }\n }\n\n if (readyNodes.length === 0) {\n // This shouldn't happen if cycle detection worked correctly\n throw new Error('Unable to resolve dependencies - possible circular dependency detected');\n }\n\n // Add this group to execution order\n executionGroups.push({\n parallel: readyNodes,\n level,\n });\n\n // Remove processed nodes\n for (const nodeId of readyNodes) {\n remainingNodes.delete(nodeId);\n }\n\n level++;\n }\n\n return executionGroups;\n }\n\n /**\n * Validate that all dependencies exist\n */\n static validateDependencies(\n checkIds: string[],\n dependencies: Record<string, string[]>\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const checkIdSet = new Set(checkIds);\n\n for (const [checkId, deps] of Object.entries(dependencies)) {\n if (!checkIdSet.has(checkId)) {\n errors.push(`Check \"${checkId}\" is not in the list of available checks`);\n continue;\n }\n\n for (const depId of deps || []) {\n if (!checkIdSet.has(depId)) {\n errors.push(`Check \"${checkId}\" depends on \"${depId}\" which is not available`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get all transitive dependencies (ancestors) for a given check\n * This returns all checks that must complete before the given check can run,\n * not just the direct dependencies.\n *\n * For example, if A -> B -> C, then:\n * - getAllDependencies(C) returns [A, B]\n * - getAllDependencies(B) returns [A]\n * - getAllDependencies(A) returns []\n *\n * @param checkId The check to find dependencies for\n * @param nodes The dependency graph nodes\n * @returns Array of all transitive dependency IDs\n */\n static getAllDependencies(checkId: string, nodes: Map<string, CheckNode>): string[] {\n const allDeps = new Set<string>();\n const visited = new Set<string>();\n\n const collectDependencies = (currentId: string) => {\n if (visited.has(currentId)) {\n return;\n }\n visited.add(currentId);\n\n const node = nodes.get(currentId);\n if (!node) {\n return;\n }\n\n // Add direct dependencies and recurse\n for (const depId of node.dependencies) {\n allDeps.add(depId);\n collectDependencies(depId);\n }\n };\n\n collectDependencies(checkId);\n return Array.from(allDeps);\n }\n\n /**\n * Get execution statistics for debugging\n */\n static getExecutionStats(graph: DependencyGraph): {\n totalChecks: number;\n parallelLevels: number;\n maxParallelism: number;\n averageParallelism: number;\n checksWithDependencies: number;\n } {\n const totalChecks = graph.nodes.size;\n const parallelLevels = graph.executionOrder.length;\n const maxParallelism = Math.max(...graph.executionOrder.map(group => group.parallel.length));\n const averageParallelism = totalChecks / parallelLevels;\n const checksWithDependencies = Array.from(graph.nodes.values()).filter(\n node => node.dependencies.length > 0\n ).length;\n\n return {\n totalChecks,\n parallelLevels,\n maxParallelism,\n averageParallelism,\n checksWithDependencies,\n };\n }\n}\n","/**\n * Workflow registry for managing reusable workflow definitions\n */\n\nimport {\n WorkflowDefinition,\n WorkflowRegistryEntry,\n WorkflowValidationResult,\n WorkflowImportOptions,\n JsonSchema,\n} from './types/workflow';\nimport { promises as fs } from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { logger } from './logger';\nimport { DependencyResolver } from './dependency-resolver';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\n\n/**\n * Registry for managing workflow definitions\n */\nexport class WorkflowRegistry {\n private static instance: WorkflowRegistry;\n private workflows: Map<string, WorkflowRegistryEntry> = new Map();\n private ajv: Ajv;\n\n private constructor() {\n this.ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(this.ajv);\n }\n\n /**\n * Get the singleton instance of the workflow registry\n */\n public static getInstance(): WorkflowRegistry {\n if (!WorkflowRegistry.instance) {\n WorkflowRegistry.instance = new WorkflowRegistry();\n }\n return WorkflowRegistry.instance;\n }\n\n /**\n * Register a workflow definition\n */\n public register(\n workflow: WorkflowDefinition,\n source: string = 'inline',\n options?: { override?: boolean }\n ): WorkflowValidationResult {\n // Validate the workflow\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n return validation;\n }\n\n // Check if workflow already exists\n if (this.workflows.has(workflow.id) && !options?.override) {\n return {\n valid: false,\n errors: [\n {\n path: 'id',\n message: `Workflow with ID '${workflow.id}' already exists`,\n value: workflow.id,\n },\n ],\n };\n }\n\n // Register the workflow\n this.workflows.set(workflow.id, {\n definition: workflow,\n source,\n registeredAt: new Date(),\n usage: {\n count: 0,\n },\n });\n\n logger.debug(`Registered workflow '${workflow.id}' from ${source}`);\n return { valid: true };\n }\n\n /**\n * Get a workflow by ID\n */\n public get(id: string): WorkflowDefinition | undefined {\n const entry = this.workflows.get(id);\n if (entry) {\n // Update usage statistics\n entry.usage = entry.usage || { count: 0 };\n entry.usage.count++;\n entry.usage.lastUsed = new Date();\n }\n return entry?.definition;\n }\n\n /**\n * Check if a workflow exists\n */\n public has(id: string): boolean {\n return this.workflows.has(id);\n }\n\n /**\n * List all registered workflows\n */\n public list(): WorkflowDefinition[] {\n return Array.from(this.workflows.values()).map(entry => entry.definition);\n }\n\n /**\n * Get workflow metadata\n */\n public getMetadata(id: string): WorkflowRegistryEntry | undefined {\n return this.workflows.get(id);\n }\n\n /**\n * Remove a workflow from the registry\n */\n public unregister(id: string): boolean {\n return this.workflows.delete(id);\n }\n\n /**\n * Clear all workflows\n */\n public clear(): void {\n this.workflows.clear();\n }\n\n /**\n * Import workflows from a file or URL\n */\n public async import(\n source: string,\n options?: WorkflowImportOptions\n ): Promise<WorkflowValidationResult[]> {\n return this.importInternal(source, options, new Set<string>());\n }\n\n private async importInternal(\n source: string,\n options: WorkflowImportOptions | undefined,\n visited: Set<string>\n ): Promise<WorkflowValidationResult[]> {\n const results: WorkflowValidationResult[] = [];\n\n try {\n // Load the workflow file\n const { content, resolvedSource, importBasePath } = await this.loadWorkflowContent(\n source,\n options?.basePath\n );\n const visitKey = resolvedSource || source;\n if (visited.has(visitKey)) {\n return results;\n }\n visited.add(visitKey);\n\n const data = this.parseWorkflowContent(content, resolvedSource || source);\n\n // Process top-level imports if present\n const topImports = !Array.isArray(data) ? (data as any)?.imports : undefined;\n if (Array.isArray(topImports)) {\n for (const childSource of topImports) {\n const childResults = await this.importInternal(\n childSource,\n { ...options, basePath: importBasePath },\n visited\n );\n results.push(...childResults);\n }\n }\n\n // Handle both single workflow and multiple workflows\n const workflows: WorkflowDefinition[] = Array.isArray(data) ? data : [data];\n\n for (const workflow of workflows) {\n const workflowImports = (workflow as any)?.imports;\n if (Array.isArray(workflowImports)) {\n for (const childSource of workflowImports) {\n const childResults = await this.importInternal(\n childSource,\n { ...options, basePath: importBasePath },\n visited\n );\n results.push(...childResults);\n }\n }\n\n // Validate if requested\n if (options?.validate !== false) {\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n results.push(validation);\n continue;\n }\n\n // Run custom validators if provided\n if (options?.validators) {\n for (const validator of options.validators) {\n const customValidation = validator(workflow);\n if (!customValidation.valid) {\n results.push(customValidation);\n continue;\n }\n }\n }\n }\n\n // Strip out fields before registering\n const workflowWithoutExtras = { ...workflow };\n delete (workflowWithoutExtras as any).tests;\n delete (workflowWithoutExtras as any).imports;\n\n // Register the workflow (without tests/imports)\n const result = this.register(workflowWithoutExtras, source, {\n override: options?.override,\n });\n results.push(result);\n }\n } catch (error) {\n results.push({\n valid: false,\n errors: [\n {\n path: 'source',\n message: `Failed to import workflows from '${source}': ${error instanceof Error ? error.message : String(error)}`,\n value: source,\n },\n ],\n });\n }\n\n return results;\n }\n\n /**\n * Import multiple workflow sources\n */\n public async importMany(\n sources: string[],\n options?: WorkflowImportOptions\n ): Promise<Map<string, WorkflowValidationResult[]>> {\n const results = new Map<string, WorkflowValidationResult[]>();\n\n for (const source of sources) {\n const importResults = await this.import(source, options);\n results.set(source, importResults);\n }\n\n return results;\n }\n\n /**\n * Validate a workflow definition\n */\n public validateWorkflow(workflow: WorkflowDefinition): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n const warnings: Array<{ path: string; message: string }> = [];\n\n // Validate required fields\n if (!workflow.id) {\n errors.push({ path: 'id', message: 'Workflow ID is required' });\n }\n\n if (!workflow.name) {\n errors.push({ path: 'name', message: 'Workflow name is required' });\n }\n\n if (!workflow.steps || Object.keys(workflow.steps).length === 0) {\n errors.push({ path: 'steps', message: 'Workflow must have at least one step' });\n }\n\n // Validate input parameters\n if (workflow.inputs) {\n for (let i = 0; i < workflow.inputs.length; i++) {\n const input = workflow.inputs[i];\n if (!input.name) {\n errors.push({ path: `inputs[${i}].name`, message: 'Input parameter name is required' });\n }\n if (!input.schema) {\n warnings.push({\n path: `inputs[${i}].schema`,\n message: 'Input parameter schema is recommended',\n });\n }\n }\n }\n\n // Validate output parameters\n if (workflow.outputs) {\n for (let i = 0; i < workflow.outputs.length; i++) {\n const output = workflow.outputs[i];\n if (!output.name) {\n errors.push({ path: `outputs[${i}].name`, message: 'Output parameter name is required' });\n }\n if (!output.value && !output.value_js) {\n errors.push({\n path: `outputs[${i}]`,\n message: 'Output parameter must have either value or value_js',\n });\n }\n }\n }\n\n // Validate steps\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Validate step dependencies\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (!workflow.steps[dep]) {\n errors.push({\n path: `steps.${stepId}.depends_on`,\n message: `Step '${stepId}' depends on non-existent step '${dep}'`,\n value: dep,\n });\n }\n }\n }\n\n // Validate input mappings\n if (step.inputs) {\n for (const [inputName, mapping] of Object.entries(step.inputs)) {\n if (typeof mapping === 'object' && mapping !== null && 'source' in mapping) {\n const typedMapping = mapping as any;\n if (typedMapping.source === 'step' && !typedMapping.stepId) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: 'Step input mapping with source \"step\" must have stepId',\n });\n }\n if (typedMapping.source === 'param') {\n // Validate that the parameter exists\n const paramExists = workflow.inputs?.some(p => p.name === typedMapping.value);\n if (!paramExists) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: `Step input references non-existent parameter '${typedMapping.value}'`,\n value: typedMapping.value,\n });\n }\n }\n }\n }\n }\n }\n\n // Check for circular dependencies\n const circularDeps = this.detectCircularDependencies(workflow);\n if (circularDeps.length > 0) {\n errors.push({\n path: 'steps',\n message: `Circular dependencies detected: ${circularDeps.join(' -> ')}`,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n }\n\n /**\n * Validate input values against workflow input schema\n */\n public validateInputs(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>\n ): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n\n if (!workflow.inputs) {\n return { valid: true };\n }\n\n // Check required inputs\n for (const param of workflow.inputs) {\n if (param.required !== false && !(param.name in inputs) && param.default === undefined) {\n errors.push({\n path: `inputs.${param.name}`,\n message: `Required input '${param.name}' is missing`,\n });\n }\n }\n\n // Validate input schemas\n for (const param of workflow.inputs) {\n if (param.name in inputs && param.schema) {\n const value = inputs[param.name];\n const valid = this.validateAgainstSchema(value, param.schema);\n if (!valid.valid) {\n errors.push({\n path: `inputs.${param.name}`,\n message: valid.error || 'Invalid input value',\n value,\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n /**\n * Load workflow content from file or URL\n */\n private async loadWorkflowContent(\n source: string,\n basePath?: string\n ): Promise<{ content: string; resolvedSource: string; importBasePath?: string }> {\n const baseIsUrl = basePath?.startsWith('http://') || basePath?.startsWith('https://');\n\n // Handle URLs\n if (source.startsWith('http://') || source.startsWith('https://')) {\n const response = await fetch(source);\n if (!response.ok) {\n throw new Error(`Failed to fetch workflow from ${source}: ${response.statusText}`);\n }\n const importBasePath = new URL('.', source).toString();\n return { content: await response.text(), resolvedSource: source, importBasePath };\n }\n\n // Handle relative URLs when basePath is a URL\n if (baseIsUrl) {\n const resolvedUrl = new URL(source, basePath).toString();\n const response = await fetch(resolvedUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch workflow from ${resolvedUrl}: ${response.statusText}`);\n }\n const importBasePath = new URL('.', resolvedUrl).toString();\n return { content: await response.text(), resolvedSource: resolvedUrl, importBasePath };\n }\n\n // Handle file paths\n const filePath = path.isAbsolute(source)\n ? source\n : path.resolve(basePath || process.cwd(), source);\n const content = await fs.readFile(filePath, 'utf-8');\n return { content, resolvedSource: filePath, importBasePath: path.dirname(filePath) };\n }\n\n /**\n * Parse workflow content (YAML or JSON)\n */\n private parseWorkflowContent(content: string, source: string): any {\n // Try JSON first\n try {\n return JSON.parse(content);\n } catch {\n // Try YAML\n try {\n return yaml.load(content);\n } catch (error) {\n throw new Error(\n `Failed to parse workflow file ${source}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n /**\n * Detect circular dependencies in workflow steps using DependencyResolver\n */\n private detectCircularDependencies(workflow: WorkflowDefinition): string[] {\n // Build dependency map\n const dependencies: Record<string, string[]> = {};\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Normalize depends_on to array (supports string | string[])\n const rawDeps = step.depends_on;\n dependencies[stepId] = Array.isArray(rawDeps) ? rawDeps : rawDeps ? [rawDeps] : [];\n }\n\n try {\n // Use DependencyResolver to check for cycles\n const graph = DependencyResolver.buildDependencyGraph(dependencies);\n\n if (graph.hasCycles && graph.cycleNodes) {\n return graph.cycleNodes;\n }\n\n return [];\n } catch {\n // DependencyResolver throws error for non-existent dependencies\n // This should be caught by the dependency validation in validateWorkflow\n // Return empty array here and let the validation handle it\n return [];\n }\n }\n\n /**\n * Validate a value against a JSON schema\n */\n private validateAgainstSchema(\n value: unknown,\n schema: JsonSchema\n ): { valid: boolean; error?: string } {\n try {\n const validate = this.ajv.compile(schema as any);\n const valid = validate(value);\n if (!valid) {\n const errors = validate.errors\n ?.map(e => `${e.instancePath || '/'}: ${e.message}`)\n .join(', ');\n return { valid: false, error: errors };\n }\n return { valid: true };\n } catch (error) {\n return { valid: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n}\n"],"mappings":";;;;;;;;;AAAA,IAyBa;AAzBb;AAAA;AAAA;AAyBO,IAAM,qBAAN,MAAyB;AAAA;AAAA;AAAA;AAAA,MAI9B,OAAO,qBAAqB,mBAA8D;AACxF,cAAM,QAAQ,oBAAI,IAAuB;AAGzC,mBAAW,WAAW,OAAO,KAAK,iBAAiB,GAAG;AACpD,gBAAM,IAAI,SAAS;AAAA,YACjB,IAAI;AAAA,YACJ,cAAc,kBAAkB,OAAO,KAAK,CAAC;AAAA,YAC7C,YAAY,CAAC;AAAA,YACb,OAAO;AAAA,UACT,CAAC;AAAA,QACH;AAGA,mBAAW,CAAC,SAAS,YAAY,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACvE,qBAAW,SAAS,gBAAgB,CAAC,GAAG;AACtC,gBAAI,CAAC,MAAM,IAAI,KAAK,GAAG;AACrB,oBAAM,IAAI,MAAM,UAAU,OAAO,iBAAiB,KAAK,UAAU,KAAK,kBAAkB;AAAA,YAC1F;AAEA,kBAAM,UAAU,MAAM,IAAI,KAAK;AAC/B,oBAAQ,WAAW,KAAK,OAAO;AAAA,UACjC;AAAA,QACF;AAGA,cAAM,iBAAiB,KAAK,aAAa,KAAK;AAC9C,YAAI,eAAe,WAAW;AAC5B,iBAAO;AAAA,YACL;AAAA,YACA,gBAAgB,CAAC;AAAA,YACjB,WAAW;AAAA,YACX,YAAY,eAAe;AAAA,UAC7B;AAAA,QACF;AAGA,cAAM,iBAAiB,KAAK,gBAAgB,KAAK;AAEjD,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,WAAW;AAAA,QACb;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,OAAe,aAAa,OAG1B;AACA,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,iBAAiB,oBAAI,IAAY;AACvC,cAAM,aAAuB,CAAC;AAE9B,cAAM,MAAM,CAAC,WAA4B;AACvC,cAAI,eAAe,IAAI,MAAM,GAAG;AAC9B,uBAAW,KAAK,MAAM;AACtB,mBAAO;AAAA,UACT;AACA,cAAI,QAAQ,IAAI,MAAM,GAAG;AACvB,mBAAO;AAAA,UACT;AAEA,kBAAQ,IAAI,MAAM;AAClB,yBAAe,IAAI,MAAM;AAEzB,gBAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,cAAI,MAAM;AACR,uBAAW,SAAS,KAAK,cAAc;AACrC,kBAAI,IAAI,KAAK,GAAG;AACd,2BAAW,KAAK,MAAM;AACtB,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAEA,yBAAe,OAAO,MAAM;AAC5B,iBAAO;AAAA,QACT;AAEA,mBAAW,UAAU,MAAM,KAAK,GAAG;AACjC,cAAI,CAAC,QAAQ,IAAI,MAAM,GAAG;AACxB,gBAAI,IAAI,MAAM,GAAG;AACf,qBAAO,EAAE,WAAW,MAAM,YAAY,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,EAAE;AAAA,YACjE;AAAA,UACF;AAAA,QACF;AAEA,eAAO,EAAE,WAAW,MAAM;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAe,gBAAgB,OAAiD;AAC9E,cAAM,iBAAiB,IAAI,IAAI,KAAK;AACpC,cAAM,kBAAoC,CAAC;AAC3C,YAAI,QAAQ;AAEZ,eAAO,eAAe,OAAO,GAAG;AAE9B,gBAAM,aAAuB,CAAC;AAE9B,qBAAW,CAAC,QAAQ,IAAI,KAAK,eAAe,QAAQ,GAAG;AACrD,kBAAM,oBAAoB,KAAK,aAAa,OAAO,WAAS,eAAe,IAAI,KAAK,CAAC;AACrF,gBAAI,kBAAkB,WAAW,GAAG;AAClC,yBAAW,KAAK,MAAM;AAAA,YACxB;AAAA,UACF;AAEA,cAAI,WAAW,WAAW,GAAG;AAE3B,kBAAM,IAAI,MAAM,wEAAwE;AAAA,UAC1F;AAGA,0BAAgB,KAAK;AAAA,YACnB,UAAU;AAAA,YACV;AAAA,UACF,CAAC;AAGD,qBAAW,UAAU,YAAY;AAC/B,2BAAe,OAAO,MAAM;AAAA,UAC9B;AAEA;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,qBACL,UACA,cACsC;AACtC,cAAM,SAAmB,CAAC;AAC1B,cAAM,aAAa,IAAI,IAAI,QAAQ;AAEnC,mBAAW,CAAC,SAAS,IAAI,KAAK,OAAO,QAAQ,YAAY,GAAG;AAC1D,cAAI,CAAC,WAAW,IAAI,OAAO,GAAG;AAC5B,mBAAO,KAAK,UAAU,OAAO,0CAA0C;AACvE;AAAA,UACF;AAEA,qBAAW,SAAS,QAAQ,CAAC,GAAG;AAC9B,gBAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,qBAAO,KAAK,UAAU,OAAO,iBAAiB,KAAK,0BAA0B;AAAA,YAC/E;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAgBA,OAAO,mBAAmB,SAAiB,OAAyC;AAClF,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,UAAU,oBAAI,IAAY;AAEhC,cAAM,sBAAsB,CAAC,cAAsB;AACjD,cAAI,QAAQ,IAAI,SAAS,GAAG;AAC1B;AAAA,UACF;AACA,kBAAQ,IAAI,SAAS;AAErB,gBAAM,OAAO,MAAM,IAAI,SAAS;AAChC,cAAI,CAAC,MAAM;AACT;AAAA,UACF;AAGA,qBAAW,SAAS,KAAK,cAAc;AACrC,oBAAQ,IAAI,KAAK;AACjB,gCAAoB,KAAK;AAAA,UAC3B;AAAA,QACF;AAEA,4BAAoB,OAAO;AAC3B,eAAO,MAAM,KAAK,OAAO;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,kBAAkB,OAMvB;AACA,cAAM,cAAc,MAAM,MAAM;AAChC,cAAM,iBAAiB,MAAM,eAAe;AAC5C,cAAM,iBAAiB,KAAK,IAAI,GAAG,MAAM,eAAe,IAAI,WAAS,MAAM,SAAS,MAAM,CAAC;AAC3F,cAAM,qBAAqB,cAAc;AACzC,cAAM,yBAAyB,MAAM,KAAK,MAAM,MAAM,OAAO,CAAC,EAAE;AAAA,UAC9D,UAAQ,KAAK,aAAa,SAAS;AAAA,QACrC,EAAE;AAEF,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACzPA,SAAS,YAAY,UAAU;AAC/B,YAAY,UAAU;AACtB,YAAY,UAAU;AAGtB,OAAO,SAAS;AAChB,OAAO,gBAAgB;AAjBvB,IAsBa;AAtBb;AAAA;AAcA;AACA;AAOO,IAAM,mBAAN,MAAM,kBAAiB;AAAA,MAC5B,OAAe;AAAA,MACP,YAAgD,oBAAI,IAAI;AAAA,MACxD;AAAA,MAEA,cAAc;AACpB,aAAK,MAAM,IAAI,IAAI,EAAE,WAAW,MAAM,QAAQ,MAAM,CAAC;AACrD,mBAAW,KAAK,GAAG;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,OAAc,cAAgC;AAC5C,YAAI,CAAC,kBAAiB,UAAU;AAC9B,4BAAiB,WAAW,IAAI,kBAAiB;AAAA,QACnD;AACA,eAAO,kBAAiB;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKO,SACL,UACA,SAAiB,UACjB,SAC0B;AAE1B,cAAM,aAAa,KAAK,iBAAiB,QAAQ;AACjD,YAAI,CAAC,WAAW,OAAO;AACrB,iBAAO;AAAA,QACT;AAGA,YAAI,KAAK,UAAU,IAAI,SAAS,EAAE,KAAK,CAAC,SAAS,UAAU;AACzD,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,cACN;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,qBAAqB,SAAS,EAAE;AAAA,gBACzC,OAAO,SAAS;AAAA,cAClB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,aAAK,UAAU,IAAI,SAAS,IAAI;AAAA,UAC9B,YAAY;AAAA,UACZ;AAAA,UACA,cAAc,oBAAI,KAAK;AAAA,UACvB,OAAO;AAAA,YACL,OAAO;AAAA,UACT;AAAA,QACF,CAAC;AAED,eAAO,MAAM,wBAAwB,SAAS,EAAE,UAAU,MAAM,EAAE;AAClE,eAAO,EAAE,OAAO,KAAK;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA,MAKO,IAAI,IAA4C;AACrD,cAAM,QAAQ,KAAK,UAAU,IAAI,EAAE;AACnC,YAAI,OAAO;AAET,gBAAM,QAAQ,MAAM,SAAS,EAAE,OAAO,EAAE;AACxC,gBAAM,MAAM;AACZ,gBAAM,MAAM,WAAW,oBAAI,KAAK;AAAA,QAClC;AACA,eAAO,OAAO;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA,MAKO,IAAI,IAAqB;AAC9B,eAAO,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKO,OAA6B;AAClC,eAAO,MAAM,KAAK,KAAK,UAAU,OAAO,CAAC,EAAE,IAAI,WAAS,MAAM,UAAU;AAAA,MAC1E;AAAA;AAAA;AAAA;AAAA,MAKO,YAAY,IAA+C;AAChE,eAAO,KAAK,UAAU,IAAI,EAAE;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKO,WAAW,IAAqB;AACrC,eAAO,KAAK,UAAU,OAAO,EAAE;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKO,QAAc;AACnB,aAAK,UAAU,MAAM;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA,MAKA,MAAa,OACX,QACA,SACqC;AACrC,eAAO,KAAK,eAAe,QAAQ,SAAS,oBAAI,IAAY,CAAC;AAAA,MAC/D;AAAA,MAEA,MAAc,eACZ,QACA,SACA,SACqC;AACrC,cAAM,UAAsC,CAAC;AAE7C,YAAI;AAEF,gBAAM,EAAE,SAAS,gBAAgB,eAAe,IAAI,MAAM,KAAK;AAAA,YAC7D;AAAA,YACA,SAAS;AAAA,UACX;AACA,gBAAM,WAAW,kBAAkB;AACnC,cAAI,QAAQ,IAAI,QAAQ,GAAG;AACzB,mBAAO;AAAA,UACT;AACA,kBAAQ,IAAI,QAAQ;AAEpB,gBAAM,OAAO,KAAK,qBAAqB,SAAS,kBAAkB,MAAM;AAGxE,gBAAM,aAAa,CAAC,MAAM,QAAQ,IAAI,IAAK,MAAc,UAAU;AACnE,cAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,uBAAW,eAAe,YAAY;AACpC,oBAAM,eAAe,MAAM,KAAK;AAAA,gBAC9B;AAAA,gBACA,EAAE,GAAG,SAAS,UAAU,eAAe;AAAA,gBACvC;AAAA,cACF;AACA,sBAAQ,KAAK,GAAG,YAAY;AAAA,YAC9B;AAAA,UACF;AAGA,gBAAM,YAAkC,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AAE1E,qBAAW,YAAY,WAAW;AAChC,kBAAM,kBAAmB,UAAkB;AAC3C,gBAAI,MAAM,QAAQ,eAAe,GAAG;AAClC,yBAAW,eAAe,iBAAiB;AACzC,sBAAM,eAAe,MAAM,KAAK;AAAA,kBAC9B;AAAA,kBACA,EAAE,GAAG,SAAS,UAAU,eAAe;AAAA,kBACvC;AAAA,gBACF;AACA,wBAAQ,KAAK,GAAG,YAAY;AAAA,cAC9B;AAAA,YACF;AAGA,gBAAI,SAAS,aAAa,OAAO;AAC/B,oBAAM,aAAa,KAAK,iBAAiB,QAAQ;AACjD,kBAAI,CAAC,WAAW,OAAO;AACrB,wBAAQ,KAAK,UAAU;AACvB;AAAA,cACF;AAGA,kBAAI,SAAS,YAAY;AACvB,2BAAW,aAAa,QAAQ,YAAY;AAC1C,wBAAM,mBAAmB,UAAU,QAAQ;AAC3C,sBAAI,CAAC,iBAAiB,OAAO;AAC3B,4BAAQ,KAAK,gBAAgB;AAC7B;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,kBAAM,wBAAwB,EAAE,GAAG,SAAS;AAC5C,mBAAQ,sBAA8B;AACtC,mBAAQ,sBAA8B;AAGtC,kBAAM,SAAS,KAAK,SAAS,uBAAuB,QAAQ;AAAA,cAC1D,UAAU,SAAS;AAAA,YACrB,CAAC;AACD,oBAAQ,KAAK,MAAM;AAAA,UACrB;AAAA,QACF,SAAS,OAAO;AACd,kBAAQ,KAAK;AAAA,YACX,OAAO;AAAA,YACP,QAAQ;AAAA,cACN;AAAA,gBACE,MAAM;AAAA,gBACN,SAAS,oCAAoC,MAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,gBAC/G,OAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAa,WACX,SACA,SACkD;AAClD,cAAM,UAAU,oBAAI,IAAwC;AAE5D,mBAAW,UAAU,SAAS;AAC5B,gBAAM,gBAAgB,MAAM,KAAK,OAAO,QAAQ,OAAO;AACvD,kBAAQ,IAAI,QAAQ,aAAa;AAAA,QACnC;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKO,iBAAiB,UAAwD;AAC9E,cAAM,SAAoE,CAAC;AAC3E,cAAM,WAAqD,CAAC;AAG5D,YAAI,CAAC,SAAS,IAAI;AAChB,iBAAO,KAAK,EAAE,MAAM,MAAM,SAAS,0BAA0B,CAAC;AAAA,QAChE;AAEA,YAAI,CAAC,SAAS,MAAM;AAClB,iBAAO,KAAK,EAAE,MAAM,QAAQ,SAAS,4BAA4B,CAAC;AAAA,QACpE;AAEA,YAAI,CAAC,SAAS,SAAS,OAAO,KAAK,SAAS,KAAK,EAAE,WAAW,GAAG;AAC/D,iBAAO,KAAK,EAAE,MAAM,SAAS,SAAS,uCAAuC,CAAC;AAAA,QAChF;AAGA,YAAI,SAAS,QAAQ;AACnB,mBAAS,IAAI,GAAG,IAAI,SAAS,OAAO,QAAQ,KAAK;AAC/C,kBAAM,QAAQ,SAAS,OAAO,CAAC;AAC/B,gBAAI,CAAC,MAAM,MAAM;AACf,qBAAO,KAAK,EAAE,MAAM,UAAU,CAAC,UAAU,SAAS,mCAAmC,CAAC;AAAA,YACxF;AACA,gBAAI,CAAC,MAAM,QAAQ;AACjB,uBAAS,KAAK;AAAA,gBACZ,MAAM,UAAU,CAAC;AAAA,gBACjB,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,YAAI,SAAS,SAAS;AACpB,mBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,QAAQ,KAAK;AAChD,kBAAM,SAAS,SAAS,QAAQ,CAAC;AACjC,gBAAI,CAAC,OAAO,MAAM;AAChB,qBAAO,KAAK,EAAE,MAAM,WAAW,CAAC,UAAU,SAAS,oCAAoC,CAAC;AAAA,YAC1F;AACA,gBAAI,CAAC,OAAO,SAAS,CAAC,OAAO,UAAU;AACrC,qBAAO,KAAK;AAAA,gBACV,MAAM,WAAW,CAAC;AAAA,gBAClB,SAAS;AAAA,cACX,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,GAAG;AAEjE,cAAI,KAAK,YAAY;AACnB,uBAAW,OAAO,KAAK,YAAY;AACjC,kBAAI,CAAC,SAAS,MAAM,GAAG,GAAG;AACxB,uBAAO,KAAK;AAAA,kBACV,MAAM,SAAS,MAAM;AAAA,kBACrB,SAAS,SAAS,MAAM,mCAAmC,GAAG;AAAA,kBAC9D,OAAO;AAAA,gBACT,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAGA,cAAI,KAAK,QAAQ;AACf,uBAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AAC9D,kBAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,YAAY,SAAS;AAC1E,sBAAM,eAAe;AACrB,oBAAI,aAAa,WAAW,UAAU,CAAC,aAAa,QAAQ;AAC1D,yBAAO,KAAK;AAAA,oBACV,MAAM,SAAS,MAAM,WAAW,SAAS;AAAA,oBACzC,SAAS;AAAA,kBACX,CAAC;AAAA,gBACH;AACA,oBAAI,aAAa,WAAW,SAAS;AAEnC,wBAAM,cAAc,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,aAAa,KAAK;AAC5E,sBAAI,CAAC,aAAa;AAChB,2BAAO,KAAK;AAAA,sBACV,MAAM,SAAS,MAAM,WAAW,SAAS;AAAA,sBACzC,SAAS,iDAAiD,aAAa,KAAK;AAAA,sBAC5E,OAAO,aAAa;AAAA,oBACtB,CAAC;AAAA,kBACH;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,eAAe,KAAK,2BAA2B,QAAQ;AAC7D,YAAI,aAAa,SAAS,GAAG;AAC3B,iBAAO,KAAK;AAAA,YACV,MAAM;AAAA,YACN,SAAS,mCAAmC,aAAa,KAAK,MAAM,CAAC;AAAA,UACvE,CAAC;AAAA,QACH;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB,QAAQ,OAAO,SAAS,IAAI,SAAS;AAAA,UACrC,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,QAC7C;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKO,eACL,UACA,QAC0B;AAC1B,cAAM,SAAoE,CAAC;AAE3E,YAAI,CAAC,SAAS,QAAQ;AACpB,iBAAO,EAAE,OAAO,KAAK;AAAA,QACvB;AAGA,mBAAW,SAAS,SAAS,QAAQ;AACnC,cAAI,MAAM,aAAa,SAAS,EAAE,MAAM,QAAQ,WAAW,MAAM,YAAY,QAAW;AACtF,mBAAO,KAAK;AAAA,cACV,MAAM,UAAU,MAAM,IAAI;AAAA,cAC1B,SAAS,mBAAmB,MAAM,IAAI;AAAA,YACxC,CAAC;AAAA,UACH;AAAA,QACF;AAGA,mBAAW,SAAS,SAAS,QAAQ;AACnC,cAAI,MAAM,QAAQ,UAAU,MAAM,QAAQ;AACxC,kBAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,kBAAM,QAAQ,KAAK,sBAAsB,OAAO,MAAM,MAAM;AAC5D,gBAAI,CAAC,MAAM,OAAO;AAChB,qBAAO,KAAK;AAAA,gBACV,MAAM,UAAU,MAAM,IAAI;AAAA,gBAC1B,SAAS,MAAM,SAAS;AAAA,gBACxB;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,UACL,OAAO,OAAO,WAAW;AAAA,UACzB,QAAQ,OAAO,SAAS,IAAI,SAAS;AAAA,QACvC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,oBACZ,QACA,UAC+E;AAC/E,cAAM,YAAY,UAAU,WAAW,SAAS,KAAK,UAAU,WAAW,UAAU;AAGpF,YAAI,OAAO,WAAW,SAAS,KAAK,OAAO,WAAW,UAAU,GAAG;AACjE,gBAAM,WAAW,MAAM,MAAM,MAAM;AACnC,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,iCAAiC,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,UACnF;AACA,gBAAM,iBAAiB,IAAI,IAAI,KAAK,MAAM,EAAE,SAAS;AACrD,iBAAO,EAAE,SAAS,MAAM,SAAS,KAAK,GAAG,gBAAgB,QAAQ,eAAe;AAAA,QAClF;AAGA,YAAI,WAAW;AACb,gBAAM,cAAc,IAAI,IAAI,QAAQ,QAAQ,EAAE,SAAS;AACvD,gBAAM,WAAW,MAAM,MAAM,WAAW;AACxC,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,iCAAiC,WAAW,KAAK,SAAS,UAAU,EAAE;AAAA,UACxF;AACA,gBAAM,iBAAiB,IAAI,IAAI,KAAK,WAAW,EAAE,SAAS;AAC1D,iBAAO,EAAE,SAAS,MAAM,SAAS,KAAK,GAAG,gBAAgB,aAAa,eAAe;AAAA,QACvF;AAGA,cAAM,WAAgB,gBAAW,MAAM,IACnC,SACK,aAAQ,YAAY,QAAQ,IAAI,GAAG,MAAM;AAClD,cAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,eAAO,EAAE,SAAS,gBAAgB,UAAU,gBAAqB,aAAQ,QAAQ,EAAE;AAAA,MACrF;AAAA;AAAA;AAAA;AAAA,MAKQ,qBAAqB,SAAiB,QAAqB;AAEjE,YAAI;AACF,iBAAO,KAAK,MAAM,OAAO;AAAA,QAC3B,QAAQ;AAEN,cAAI;AACF,mBAAY,UAAK,OAAO;AAAA,UAC1B,SAAS,OAAO;AACd,kBAAM,IAAI;AAAA,cACR,iCAAiC,MAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,YACpG;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,2BAA2B,UAAwC;AAEzE,cAAM,eAAyC,CAAC;AAChD,mBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO,QAAQ,SAAS,SAAS,CAAC,CAAC,GAAG;AAEjE,gBAAM,UAAU,KAAK;AACrB,uBAAa,MAAM,IAAI,MAAM,QAAQ,OAAO,IAAI,UAAU,UAAU,CAAC,OAAO,IAAI,CAAC;AAAA,QACnF;AAEA,YAAI;AAEF,gBAAM,QAAQ,mBAAmB,qBAAqB,YAAY;AAElE,cAAI,MAAM,aAAa,MAAM,YAAY;AACvC,mBAAO,MAAM;AAAA,UACf;AAEA,iBAAO,CAAC;AAAA,QACV,QAAQ;AAIN,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,sBACN,OACA,QACoC;AACpC,YAAI;AACF,gBAAM,WAAW,KAAK,IAAI,QAAQ,MAAa;AAC/C,gBAAM,QAAQ,SAAS,KAAK;AAC5B,cAAI,CAAC,OAAO;AACV,kBAAM,SAAS,SAAS,QACpB,IAAI,OAAK,GAAG,EAAE,gBAAgB,GAAG,KAAK,EAAE,OAAO,EAAE,EAClD,KAAK,IAAI;AACZ,mBAAO,EAAE,OAAO,OAAO,OAAO,OAAO;AAAA,UACvC;AACA,iBAAO,EAAE,OAAO,KAAK;AAAA,QACvB,SAAS,OAAO;AACd,iBAAO,EAAE,OAAO,OAAO,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE;AAAA,QACvF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/dependency-resolver.ts","../../src/workflow-registry.ts"],"sourcesContent":["/**\n * Dependency resolution and execution ordering for checks\n */\n\nexport interface CheckNode {\n id: string;\n dependencies: string[];\n dependents: string[];\n depth: number;\n}\n\nexport interface ExecutionGroup {\n /** Checks that can run in parallel */\n parallel: string[];\n /** Execution level/wave (0 = no dependencies, 1 = depends on level 0, etc.) */\n level: number;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, CheckNode>;\n executionOrder: ExecutionGroup[];\n hasCycles: boolean;\n cycleNodes?: string[];\n}\n\nexport class DependencyResolver {\n /**\n * Build dependency graph from check dependencies\n */\n static buildDependencyGraph(checkDependencies: Record<string, string[]>): DependencyGraph {\n const nodes = new Map<string, CheckNode>();\n\n // Initialize all nodes\n for (const checkId of Object.keys(checkDependencies)) {\n nodes.set(checkId, {\n id: checkId,\n dependencies: checkDependencies[checkId] || [],\n dependents: [],\n depth: 0,\n });\n }\n\n // Build bidirectional relationships\n for (const [checkId, dependencies] of Object.entries(checkDependencies)) {\n for (const depId of dependencies || []) {\n if (!nodes.has(depId)) {\n throw new Error(`Check \"${checkId}\" depends on \"${depId}\" but \"${depId}\" is not defined`);\n }\n\n const depNode = nodes.get(depId)!;\n depNode.dependents.push(checkId);\n }\n }\n\n // Detect cycles using DFS\n const cycleDetection = this.detectCycles(nodes);\n if (cycleDetection.hasCycles) {\n return {\n nodes,\n executionOrder: [],\n hasCycles: true,\n cycleNodes: cycleDetection.cycleNodes,\n };\n }\n\n // Calculate execution order using topological sort\n const executionOrder = this.topologicalSort(nodes);\n\n return {\n nodes,\n executionOrder,\n hasCycles: false,\n };\n }\n\n /**\n * Detect cycles in the dependency graph using DFS\n */\n private static detectCycles(nodes: Map<string, CheckNode>): {\n hasCycles: boolean;\n cycleNodes?: string[];\n } {\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cycleNodes: string[] = [];\n\n const dfs = (nodeId: string): boolean => {\n if (recursionStack.has(nodeId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n if (visited.has(nodeId)) {\n return false;\n }\n\n visited.add(nodeId);\n recursionStack.add(nodeId);\n\n const node = nodes.get(nodeId);\n if (node) {\n for (const depId of node.dependencies) {\n if (dfs(depId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n }\n }\n\n recursionStack.delete(nodeId);\n return false;\n };\n\n for (const nodeId of nodes.keys()) {\n if (!visited.has(nodeId)) {\n if (dfs(nodeId)) {\n return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };\n }\n }\n }\n\n return { hasCycles: false };\n }\n\n /**\n * Perform topological sort to determine execution order\n * Groups checks that can run in parallel at each level\n */\n private static topologicalSort(nodes: Map<string, CheckNode>): ExecutionGroup[] {\n const remainingNodes = new Map(nodes);\n const executionGroups: ExecutionGroup[] = [];\n let level = 0;\n\n while (remainingNodes.size > 0) {\n // Find nodes with no remaining dependencies\n const readyNodes: string[] = [];\n\n for (const [nodeId, node] of remainingNodes.entries()) {\n const unmetDependencies = node.dependencies.filter(depId => remainingNodes.has(depId));\n if (unmetDependencies.length === 0) {\n readyNodes.push(nodeId);\n }\n }\n\n if (readyNodes.length === 0) {\n // This shouldn't happen if cycle detection worked correctly\n throw new Error('Unable to resolve dependencies - possible circular dependency detected');\n }\n\n // Add this group to execution order\n executionGroups.push({\n parallel: readyNodes,\n level,\n });\n\n // Remove processed nodes\n for (const nodeId of readyNodes) {\n remainingNodes.delete(nodeId);\n }\n\n level++;\n }\n\n return executionGroups;\n }\n\n /**\n * Validate that all dependencies exist\n */\n static validateDependencies(\n checkIds: string[],\n dependencies: Record<string, string[]>\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const checkIdSet = new Set(checkIds);\n\n for (const [checkId, deps] of Object.entries(dependencies)) {\n if (!checkIdSet.has(checkId)) {\n errors.push(`Check \"${checkId}\" is not in the list of available checks`);\n continue;\n }\n\n for (const depId of deps || []) {\n if (!checkIdSet.has(depId)) {\n errors.push(`Check \"${checkId}\" depends on \"${depId}\" which is not available`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get all transitive dependencies (ancestors) for a given check\n * This returns all checks that must complete before the given check can run,\n * not just the direct dependencies.\n *\n * For example, if A -> B -> C, then:\n * - getAllDependencies(C) returns [A, B]\n * - getAllDependencies(B) returns [A]\n * - getAllDependencies(A) returns []\n *\n * @param checkId The check to find dependencies for\n * @param nodes The dependency graph nodes\n * @returns Array of all transitive dependency IDs\n */\n static getAllDependencies(checkId: string, nodes: Map<string, CheckNode>): string[] {\n const allDeps = new Set<string>();\n const visited = new Set<string>();\n\n const collectDependencies = (currentId: string) => {\n if (visited.has(currentId)) {\n return;\n }\n visited.add(currentId);\n\n const node = nodes.get(currentId);\n if (!node) {\n return;\n }\n\n // Add direct dependencies and recurse\n for (const depId of node.dependencies) {\n allDeps.add(depId);\n collectDependencies(depId);\n }\n };\n\n collectDependencies(checkId);\n return Array.from(allDeps);\n }\n\n /**\n * Get execution statistics for debugging\n */\n static getExecutionStats(graph: DependencyGraph): {\n totalChecks: number;\n parallelLevels: number;\n maxParallelism: number;\n averageParallelism: number;\n checksWithDependencies: number;\n } {\n const totalChecks = graph.nodes.size;\n const parallelLevels = graph.executionOrder.length;\n const maxParallelism = Math.max(...graph.executionOrder.map(group => group.parallel.length));\n const averageParallelism = totalChecks / parallelLevels;\n const checksWithDependencies = Array.from(graph.nodes.values()).filter(\n node => node.dependencies.length > 0\n ).length;\n\n return {\n totalChecks,\n parallelLevels,\n maxParallelism,\n averageParallelism,\n checksWithDependencies,\n };\n }\n}\n","/**\n * Workflow registry for managing reusable workflow definitions\n */\n\nimport {\n WorkflowDefinition,\n WorkflowRegistryEntry,\n WorkflowValidationResult,\n WorkflowImportOptions,\n JsonSchema,\n} from './types/workflow';\nimport { promises as fs } from 'fs';\nimport * as path from 'path';\nimport * as yaml from 'js-yaml';\nimport { logger } from './logger';\nimport { DependencyResolver } from './dependency-resolver';\nimport Ajv from 'ajv';\nimport addFormats from 'ajv-formats';\n\n/**\n * Registry for managing workflow definitions\n */\nexport class WorkflowRegistry {\n private static instance: WorkflowRegistry;\n private workflows: Map<string, WorkflowRegistryEntry> = new Map();\n private ajv: Ajv;\n\n private constructor() {\n this.ajv = new Ajv({ allErrors: true, strict: false });\n addFormats(this.ajv);\n }\n\n /**\n * Get the singleton instance of the workflow registry\n */\n public static getInstance(): WorkflowRegistry {\n if (!WorkflowRegistry.instance) {\n WorkflowRegistry.instance = new WorkflowRegistry();\n }\n return WorkflowRegistry.instance;\n }\n\n /**\n * Register a workflow definition\n */\n public register(\n workflow: WorkflowDefinition,\n source: string = 'inline',\n options?: { override?: boolean }\n ): WorkflowValidationResult {\n // Validate the workflow\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n return validation;\n }\n\n // Check if workflow already exists\n if (this.workflows.has(workflow.id) && !options?.override) {\n return {\n valid: false,\n errors: [\n {\n path: 'id',\n message: `Workflow with ID '${workflow.id}' already exists`,\n value: workflow.id,\n },\n ],\n };\n }\n\n // Register the workflow\n this.workflows.set(workflow.id, {\n definition: workflow,\n source,\n registeredAt: new Date(),\n usage: {\n count: 0,\n },\n });\n\n logger.debug(`Registered workflow '${workflow.id}' from ${source}`);\n return { valid: true };\n }\n\n /**\n * Get a workflow by ID\n */\n public get(id: string): WorkflowDefinition | undefined {\n const entry = this.workflows.get(id);\n if (entry) {\n // Update usage statistics\n entry.usage = entry.usage || { count: 0 };\n entry.usage.count++;\n entry.usage.lastUsed = new Date();\n }\n return entry?.definition;\n }\n\n /**\n * Check if a workflow exists\n */\n public has(id: string): boolean {\n return this.workflows.has(id);\n }\n\n /**\n * List all registered workflows\n */\n public list(): WorkflowDefinition[] {\n return Array.from(this.workflows.values()).map(entry => entry.definition);\n }\n\n /**\n * Get workflow metadata\n */\n public getMetadata(id: string): WorkflowRegistryEntry | undefined {\n return this.workflows.get(id);\n }\n\n /**\n * Remove a workflow from the registry\n */\n public unregister(id: string): boolean {\n return this.workflows.delete(id);\n }\n\n /**\n * Clear all workflows\n */\n public clear(): void {\n this.workflows.clear();\n }\n\n /**\n * Import workflows from a file or URL\n */\n public async import(\n source: string,\n options?: WorkflowImportOptions\n ): Promise<WorkflowValidationResult[]> {\n return this.importInternal(source, options, new Set<string>());\n }\n\n private async importInternal(\n source: string,\n options: WorkflowImportOptions | undefined,\n visited: Set<string>\n ): Promise<WorkflowValidationResult[]> {\n const results: WorkflowValidationResult[] = [];\n\n try {\n // Load the workflow file\n const { content, resolvedSource, importBasePath } = await this.loadWorkflowContent(\n source,\n options?.basePath\n );\n const visitKey = resolvedSource || source;\n if (visited.has(visitKey)) {\n return results;\n }\n visited.add(visitKey);\n\n const data = this.parseWorkflowContent(content, resolvedSource || source);\n\n // Process top-level imports if present\n const topImports = !Array.isArray(data) ? (data as any)?.imports : undefined;\n if (Array.isArray(topImports)) {\n for (const childSource of topImports) {\n const childResults = await this.importInternal(\n childSource,\n { ...options, basePath: importBasePath },\n visited\n );\n results.push(...childResults);\n }\n }\n\n // Handle both single workflow and multiple workflows\n const workflows: WorkflowDefinition[] = Array.isArray(data) ? data : [data];\n\n for (const workflow of workflows) {\n const workflowImports = (workflow as any)?.imports;\n if (Array.isArray(workflowImports)) {\n for (const childSource of workflowImports) {\n const childResults = await this.importInternal(\n childSource,\n { ...options, basePath: importBasePath },\n visited\n );\n results.push(...childResults);\n }\n }\n\n // Validate if requested\n if (options?.validate !== false) {\n const validation = this.validateWorkflow(workflow);\n if (!validation.valid) {\n results.push(validation);\n continue;\n }\n\n // Run custom validators if provided\n if (options?.validators) {\n for (const validator of options.validators) {\n const customValidation = validator(workflow);\n if (!customValidation.valid) {\n results.push(customValidation);\n continue;\n }\n }\n }\n }\n\n // Strip out fields before registering\n const workflowWithoutExtras = { ...workflow };\n delete (workflowWithoutExtras as any).tests;\n delete (workflowWithoutExtras as any).imports;\n\n // Register the workflow (without tests/imports)\n const result = this.register(workflowWithoutExtras, source, {\n override: options?.override,\n });\n results.push(result);\n }\n } catch (error) {\n results.push({\n valid: false,\n errors: [\n {\n path: 'source',\n message: `Failed to import workflows from '${source}': ${error instanceof Error ? error.message : String(error)}`,\n value: source,\n },\n ],\n });\n }\n\n return results;\n }\n\n /**\n * Import multiple workflow sources\n */\n public async importMany(\n sources: string[],\n options?: WorkflowImportOptions\n ): Promise<Map<string, WorkflowValidationResult[]>> {\n const results = new Map<string, WorkflowValidationResult[]>();\n\n for (const source of sources) {\n const importResults = await this.import(source, options);\n results.set(source, importResults);\n }\n\n return results;\n }\n\n /**\n * Validate a workflow definition\n */\n public validateWorkflow(workflow: WorkflowDefinition): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n const warnings: Array<{ path: string; message: string }> = [];\n\n // Validate required fields\n if (!workflow.id) {\n errors.push({ path: 'id', message: 'Workflow ID is required' });\n }\n\n if (!workflow.name) {\n errors.push({ path: 'name', message: 'Workflow name is required' });\n }\n\n if (!workflow.steps || Object.keys(workflow.steps).length === 0) {\n errors.push({ path: 'steps', message: 'Workflow must have at least one step' });\n }\n\n // Validate input parameters\n if (workflow.inputs) {\n for (let i = 0; i < workflow.inputs.length; i++) {\n const input = workflow.inputs[i];\n if (!input.name) {\n errors.push({ path: `inputs[${i}].name`, message: 'Input parameter name is required' });\n }\n if (!input.schema) {\n warnings.push({\n path: `inputs[${i}].schema`,\n message: 'Input parameter schema is recommended',\n });\n }\n }\n }\n\n // Validate output parameters\n if (workflow.outputs) {\n for (let i = 0; i < workflow.outputs.length; i++) {\n const output = workflow.outputs[i];\n if (!output.name) {\n errors.push({ path: `outputs[${i}].name`, message: 'Output parameter name is required' });\n }\n if (!output.value && !output.value_js) {\n errors.push({\n path: `outputs[${i}]`,\n message: 'Output parameter must have either value or value_js',\n });\n }\n }\n }\n\n // Validate steps\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Validate step dependencies\n if (step.depends_on) {\n for (const dep of step.depends_on) {\n if (!workflow.steps[dep]) {\n errors.push({\n path: `steps.${stepId}.depends_on`,\n message: `Step '${stepId}' depends on non-existent step '${dep}'`,\n value: dep,\n });\n }\n }\n }\n\n // Validate input mappings\n if (step.inputs) {\n for (const [inputName, mapping] of Object.entries(step.inputs)) {\n if (typeof mapping === 'object' && mapping !== null && 'source' in mapping) {\n const typedMapping = mapping as any;\n if (typedMapping.source === 'step' && !typedMapping.stepId) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: 'Step input mapping with source \"step\" must have stepId',\n });\n }\n if (typedMapping.source === 'param') {\n // Validate that the parameter exists\n const paramExists = workflow.inputs?.some(p => p.name === typedMapping.value);\n if (!paramExists) {\n errors.push({\n path: `steps.${stepId}.inputs.${inputName}`,\n message: `Step input references non-existent parameter '${typedMapping.value}'`,\n value: typedMapping.value,\n });\n }\n }\n }\n }\n }\n }\n\n // Check for circular dependencies\n const circularDeps = this.detectCircularDependencies(workflow);\n if (circularDeps.length > 0) {\n errors.push({\n path: 'steps',\n message: `Circular dependencies detected: ${circularDeps.join(' -> ')}`,\n });\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n }\n\n /**\n * Validate input values against workflow input schema\n */\n public validateInputs(\n workflow: WorkflowDefinition,\n inputs: Record<string, unknown>\n ): WorkflowValidationResult {\n const errors: Array<{ path: string; message: string; value?: unknown }> = [];\n\n if (!workflow.inputs) {\n return { valid: true };\n }\n\n // Check required inputs\n for (const param of workflow.inputs) {\n if (param.required !== false && !(param.name in inputs) && param.default === undefined) {\n errors.push({\n path: `inputs.${param.name}`,\n message: `Required input '${param.name}' is missing`,\n });\n }\n }\n\n // Validate input schemas\n for (const param of workflow.inputs) {\n if (param.name in inputs && param.schema) {\n const value = inputs[param.name];\n const valid = this.validateAgainstSchema(value, param.schema);\n if (!valid.valid) {\n errors.push({\n path: `inputs.${param.name}`,\n message: valid.error || 'Invalid input value',\n value,\n });\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n };\n }\n\n /**\n * Load workflow content from file or URL\n */\n private async loadWorkflowContent(\n source: string,\n basePath?: string\n ): Promise<{ content: string; resolvedSource: string; importBasePath?: string }> {\n const baseIsUrl = basePath?.startsWith('http://') || basePath?.startsWith('https://');\n\n // Handle visor:// and visor-ee:// built-in workflow URLs\n // Resolves to the defaults/ directory shipped with the package\n if (source.startsWith('visor://') || source.startsWith('visor-ee://')) {\n const relativePath = source.replace(/^visor(?:-ee)?:\\/\\//, '');\n const defaultsDir = path.resolve(__dirname, '..', 'defaults');\n const filePath = path.resolve(defaultsDir, relativePath);\n // Prevent path traversal outside defaults directory\n if (!filePath.startsWith(defaultsDir + path.sep)) {\n throw new Error(`Invalid visor:// path: resolved path escapes defaults directory`);\n }\n const content = await fs.readFile(filePath, 'utf-8');\n return { content, resolvedSource: filePath, importBasePath: path.dirname(filePath) };\n }\n\n // Handle URLs\n if (source.startsWith('http://') || source.startsWith('https://')) {\n const response = await fetch(source);\n if (!response.ok) {\n throw new Error(`Failed to fetch workflow from ${source}: ${response.statusText}`);\n }\n const importBasePath = new URL('.', source).toString();\n return { content: await response.text(), resolvedSource: source, importBasePath };\n }\n\n // Handle relative URLs when basePath is a URL\n if (baseIsUrl) {\n const resolvedUrl = new URL(source, basePath).toString();\n const response = await fetch(resolvedUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch workflow from ${resolvedUrl}: ${response.statusText}`);\n }\n const importBasePath = new URL('.', resolvedUrl).toString();\n return { content: await response.text(), resolvedSource: resolvedUrl, importBasePath };\n }\n\n // Handle file paths\n const filePath = path.isAbsolute(source)\n ? source\n : path.resolve(basePath || process.cwd(), source);\n const content = await fs.readFile(filePath, 'utf-8');\n return { content, resolvedSource: filePath, importBasePath: path.dirname(filePath) };\n }\n\n /**\n * Parse workflow content (YAML or JSON)\n */\n private parseWorkflowContent(content: string, source: string): any {\n // Try JSON first\n try {\n return JSON.parse(content);\n } catch {\n // Try YAML\n try {\n return yaml.load(content);\n } catch (error) {\n throw new Error(\n `Failed to parse workflow file ${source}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n /**\n * Detect circular dependencies in workflow steps using DependencyResolver\n */\n private detectCircularDependencies(workflow: WorkflowDefinition): string[] {\n // Build dependency map\n const dependencies: Record<string, string[]> = {};\n for (const [stepId, step] of Object.entries(workflow.steps || {})) {\n // Normalize depends_on to array (supports string | string[])\n const rawDeps = step.depends_on;\n dependencies[stepId] = Array.isArray(rawDeps) ? rawDeps : rawDeps ? [rawDeps] : [];\n }\n\n try {\n // Use DependencyResolver to check for cycles\n const graph = DependencyResolver.buildDependencyGraph(dependencies);\n\n if (graph.hasCycles && graph.cycleNodes) {\n return graph.cycleNodes;\n }\n\n return [];\n } catch {\n // DependencyResolver throws error for non-existent dependencies\n // This should be caught by the dependency validation in validateWorkflow\n // Return empty array here and let the validation handle it\n return [];\n }\n }\n\n /**\n * Validate a value against a JSON schema\n */\n private validateAgainstSchema(\n value: unknown,\n schema: JsonSchema\n ): { valid: boolean; error?: string } {\n try {\n const validate = this.ajv.compile(schema as any);\n const valid = validate(value);\n if (!valid) {\n const errors = validate.errors\n ?.map(e => `${e.instancePath || '/'}: ${e.message}`)\n .join(', ');\n return { valid: false, error: errors };\n }\n return { valid: true };\n } catch (error) {\n return { valid: false, error: error instanceof Error ? error.message : String(error) };\n }\n }\n}\n"],"mappings":"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","names":["filePath","content"]}