import type { CommandDispatcher, CustomResolver } from '../../../types'; import type { PluginRegistry } from '../../../plugin/registry'; import type { RoutineDefinition, RoutineStep } from '../../../routine/types'; import type { RoutineResult } from '../../../routine/executor'; export interface RoutineTestDeps { loadSpec: () => RoutineDefinition | null; validateRoutine: (def: RoutineDefinition) => string[]; executeRoutine: (def: RoutineDefinition, overrides: Record, dispatch: CommandDispatcher, opts: { customResolvers?: Map; pluginRegistry?: PluginRegistry; onStep?: RoutineTestDeps['onStep']; onIteration?: RoutineTestDeps['onIteration'] }) => Promise; dispatch: CommandDispatcher; overrides: Record; customResolvers?: Map; pluginRegistry?: PluginRegistry; routineName?: string; onStep?: (step: RoutineStep, i: number, total: number) => void; onIteration?: (step: RoutineStep, current: number, total: number, stepIndex: number, stepTotal: number) => void; } export async function routineTestAction(deps: RoutineTestDeps): Promise<{ success: boolean; stepsRun: number; stepsSkipped: number; stepsFailed: number }> { const spec = deps.loadSpec(); if (!spec) { throw new Error(`No spec.yaml found for routine "${deps.routineName}".`); } const errors = deps.validateRoutine(spec); if (errors.length > 0) { throw new Error(`Spec validation errors:\n${errors.map(e => ` - ${e}`).join('\n')}`); } return deps.executeRoutine(spec, deps.overrides, deps.dispatch, { customResolvers: deps.customResolvers, pluginRegistry: deps.pluginRegistry, onStep: deps.onStep, onIteration: deps.onIteration, }); }