/** * Fix DAG Runner * * Executes an array of `Fix` definitions as a dependency graph instead of * a flat ordered list. Each fix can declare: * - `requires: string[]` — ids that must succeed first. Skipped prereq → * this fix is marked skipped (not failed), so one upstream failure * doesn't cascade into a noisy list of doomed fixes. * - `serializeOn: string[]` — named resources. Fixes sharing any resource * id run serially w.r.t. each other; everything else is parallel. * * The runner is intentionally decoupled from scan.ts / fix.ts / deploy.ts — * they stay on the existing multi-pass flow until individual scanfix groups * migrate. New scanfixes that want the DAG can be handed to `runFixDAG` * directly; consumers accumulate results and print them at the end. */ import type { Fix, FactiiiConfig } from '../types/index.js'; export type FixStatus = 'ok' | 'fixed' | 'failed' | 'skipped' | 'manual'; export interface FixOutcome { id: string; status: FixStatus; /** Reason for a non-`ok` outcome — error message, "prereq X skipped", etc. */ reason?: string; /** True when scan detected an issue. False means "no issue found; fix not run." */ issueDetected: boolean; /** Duration in ms for scan + fix combined. */ durationMs: number; } export interface DAGResult { outcomes: Map; orderedIds: string[]; hasFailures: boolean; hasSkipped: boolean; } export interface RunOptions { rootDir: string; config: FactiiiConfig; /** When false (default), do not invoke `fix` functions — only scan. */ applyFixes?: boolean; /** Called as each fix completes. For streaming UI. */ onOutcome?: (outcome: FixOutcome, fix: Fix) => void; } declare class CycleError extends Error { readonly cycleIds: string[]; constructor(cycleIds: string[]); } /** * Topological sort via DFS with cycle detection. Stable: preserves input * order for fixes with equal dependencies so runs are reproducible. */ export declare function topoSort(fixes: Fix[]): Fix[]; /** * Build the lookup of unmet transitive dependencies per fix. Returns null * if every `requires` id exists in the fix set; otherwise a map of fixId → * missing ids so the runner can mark those fixes skipped with a clear reason. */ export declare function missingRequires(fixes: Fix[]): Map; /** * Execute the DAG. Currently single-threaded within a `serializeOn` group * and across the whole DAG — parallelism is the next step once every * scanfix declares its shared-resource ids honestly. Correct ordering + * skip propagation is the hard part and is done here. */ export declare function runFixDAG(fixes: Fix[], options: RunOptions): Promise; export { CycleError }; //# sourceMappingURL=dag-runner.d.ts.map