/**
 * WorkflowRunner — parses relay.yaml, validates config, resolves templates,
 * executes steps (sequential/parallel/DAG), runs verification checks,
 * persists state to DB, and supports pause/resume/abort with retries.
 */
import type { BrokerEvent } from '../protocol.js';
import { type CliSessionReport } from './cli-session-collector.js';
import { type VariableContext } from './template-resolver.js';
import type { AgentCli, AgentDefinition, DryRunReport, RelayYamlConfig, StepCompletionEvidence, WorkflowRunRow, WorkflowStep, WorkflowExecuteOptions, WorkflowStepRow, ProcessBackend } from './types.js';
import { AgentRelay } from '../relay.js';
import type { AgentRelayOptions } from '../relay.js';
/** Minimal DB adapter so the runner is not coupled to a specific driver. */
export interface WorkflowDb {
    insertRun(run: WorkflowRunRow): Promise<void>;
    updateRun(id: string, patch: Partial<WorkflowRunRow>): Promise<void>;
    getRun(id: string): Promise<WorkflowRunRow | null>;
    insertStep(step: WorkflowStepRow): Promise<void>;
    updateStep(id: string, patch: Partial<WorkflowStepRow>): Promise<void>;
    getStepsByRunId(runId: string): Promise<WorkflowStepRow[]>;
}
export type WorkflowEvent = {
    type: 'run:started';
    runId: string;
} | {
    type: 'run:completed';
    runId: string;
} | {
    type: 'run:failed';
    runId: string;
    error: string;
} | {
    type: 'run:cancelled';
    runId: string;
} | {
    type: 'broker:event';
    runId: string;
    event: BrokerEvent;
} | {
    type: 'step:started';
    runId: string;
    stepName: string;
} | {
    type: 'step:owner-assigned';
    runId: string;
    stepName: string;
    ownerName: string;
    specialistName: string;
} | {
    type: 'step:completed';
    runId: string;
    stepName: string;
    output?: string;
    exitCode?: number;
    exitSignal?: string;
} | {
    type: 'step:review-completed';
    runId: string;
    stepName: string;
    reviewerName: string;
    decision: 'approved' | 'rejected';
} | {
    type: 'step:owner-timeout';
    runId: string;
    stepName: string;
    ownerName: string;
} | {
    type: 'step:agent-report';
    runId: string;
    stepName: string;
    report: CliSessionReport;
} | {
    type: 'step:failed';
    runId: string;
    stepName: string;
    error: string;
    exitCode?: number;
    exitSignal?: string;
} | {
    type: 'step:skipped';
    runId: string;
    stepName: string;
} | {
    type: 'step:retrying';
    runId: string;
    stepName: string;
    attempt: number;
} | {
    type: 'step:nudged';
    runId: string;
    stepName: string;
    nudgeCount: number;
} | {
    type: 'step:force-released';
    runId: string;
    stepName: string;
};
export type WorkflowEventListener = (event: WorkflowEvent) => void;
export interface WorkflowRunnerOptions {
    db?: WorkflowDb;
    workspaceId?: string;
    relay?: AgentRelayOptions;
    cwd?: string;
    summaryDir?: string;
    executor?: RunnerStepExecutor;
    envSecrets?: Record<string, string>;
    /**
     * Process backend for remote execution environments.
     * When set without an explicit executor, the runner wraps it in a
     * RunnerStepExecutor that creates isolated environments for agent and
     * deterministic steps. The runner builds CLI commands and passes auth env,
     * cwd, and timeout; the backend provides create/exec/destroy primitives.
     *
     * When both executor and processBackend are set, executor takes precedence.
     * When neither is set, the broker spawns local child processes (default).
     */
    processBackend?: ProcessBackend;
}
/**
 * Extension point for delegating step execution to an external backend
 * (e.g. Daytona sandboxes) while keeping the runner's DAG/retry/verification
 * machinery intact.
 */
export interface RunnerStepExecutor {
    executeAgentStep(step: WorkflowStep, agentDef: AgentDefinition, resolvedTask: string, timeoutMs?: number): Promise<string>;
    executeDeterministicStep?(step: WorkflowStep, resolvedCommand: string, cwd: string): Promise<{
        output: string;
        exitCode: number;
    }>;
    executeIntegrationStep?(step: WorkflowStep, resolvedParams: Record<string, string>, context: {
        workspaceId?: string;
    }): Promise<{
        output: string;
        success: boolean;
    }>;
}
export declare class WorkflowRunner {
    private readonly db;
    private readonly workspaceId;
    private readonly relayOptions;
    private readonly cwd;
    private readonly summaryDir;
    private executor?;
    private readonly envSecrets?;
    private readonly templateResolver;
    private readonly channelMessenger;
    /** @internal exposed for CLI signal-handler shutdown only */
    relay?: AgentRelay;
    private relaycast?;
    private relaycastAgent?;
    private relayApiKey?;
    private relayApiKeyAutoCreated;
    private channel?;
    private trajectory?;
    private abortController?;
    private paused;
    private pauseResolver?;
    private listeners;
    /** Current config for the active run, so spawnAndWait can access swarm config. */
    private currentConfig?;
    /** Current run ID for event emission from spawnAndWait context. */
    private currentRunId?;
    /** Live Agent handles keyed by name, for hub-mediated nudging. */
    private readonly activeAgentHandles;
    /** Per-agent workflow tokens for relay/relayfile auth across spawn modes. */
    private readonly agentTokens;
    /** Per-agent credential proxy tokens keyed by logical agent definition name. */
    private readonly proxyTokens;
    /** Per-agent relayfile mounts keyed by logical agent definition name. */
    private readonly agentMounts;
    private readonly ptyOutputBuffers;
    /** Snapshot of PTY output from the most recent failed attempt, keyed by step name. */
    private readonly lastFailedStepOutput;
    /** Most recent custom verification failure details, keyed by step name. */
    private readonly lastCustomVerificationFailure;
    private readonly ptyListeners;
    private readonly ptyLogStreams;
    /** Path to workers.json so `agents:kill` can find workflow-spawned agents */
    private readonly workersPath;
    /** In-memory tracking of active workers to avoid race conditions on workers.json */
    private readonly activeWorkers;
    /** Mutex for serializing workers.json file access */
    private workersFileLock;
    /** Timestamp when the current workflow run started, for elapsed-time logging. */
    private runStartTime?;
    /** Unsubscribe handle for broker stderr listener wired during a run. */
    private unsubBrokerStderr?;
    /** Tracks last idle log time per agent to debounce idle warnings (30s multiples). */
    private readonly lastIdleLog;
    /** Tracks last logged activity type per agent to avoid duplicate status lines. */
    private readonly lastActivity;
    /** Runtime-name lookup for agents participating in supervised owner flows. */
    private readonly supervisedRuntimeAgents;
    /** Runtime-name lookup for active step agents so channel messages can be attributed to a step. */
    private readonly runtimeStepAgents;
    /** Per-step completion evidence collected across output, channel, files, and tool side-effects. */
    private readonly stepCompletionEvidence;
    /** Expected owner/worker identities per step so coordination signals can be validated by sender. */
    private readonly stepSignalParticipants;
    /** Resolved named paths from the top-level `paths` config, keyed by name → absolute directory. */
    private resolvedPaths;
    /** Tracks agent names currently assigned as reviewers (ref-counted to handle concurrent usage). */
    private readonly activeReviewers;
    /** Structured CLI session reports captured during the current run, keyed by step name. */
    private readonly agentReports;
    /** Optional per-run token budget tracker; only created when budgets are configured. */
    private budgetTracker?;
    private static readonly PTY_TASK_ARG_SIZE_LIMIT;
    private readonly processBackend?;
    constructor(options?: WorkflowRunnerOptions);
    /** Expand environment variables like $HOME or $VAR in a path string. */
    private static resolveEnvVars;
    /**
     * Resolve and validate the top-level `paths` definitions from the config.
     * Returns a map of name → absolute directory path.
     * Throws if a required path does not exist.
     */
    private resolvePathDefinitions;
    private initializeBudgetTracker;
    private ensureBudgetAllowsSpawn;
    private getTotalReportTokens;
    private validatePermissions;
    private mergePermissionLists;
    private mergePermissionFiles;
    private mergePermissionProfile;
    private applyPermissionProfiles;
    /**
     * Resolve an agent's effective working directory, considering `workdir` (named path reference)
     * and `cwd` (explicit path). `workdir` takes precedence when both are set.
     */
    private resolveAgentCwd;
    /**
     * Resolve a step's working directory from its `workdir` field (named path reference).
     * Returns undefined if no workdir is set.
     */
    private resolveStepWorkdir;
    private resolveEffectiveCwd;
    private resolveMountedCwd;
    private resolveExecutionCwd;
    private stopProvisionedMounts;
    private static readonly EVIDENCE_IGNORED_DIRS;
    getStepCompletionEvidence(stepName: string): StepCompletionEvidence | undefined;
    private getOrCreateStepEvidenceRecord;
    private initializeStepSignalParticipants;
    private rememberStepSignalSender;
    private resolveSignalParticipantKind;
    private isSignalFromExpectedSender;
    private filterStepEvidenceBySignalProvenance;
    private beginStepEvidence;
    private captureStepTerminalEvidence;
    private finalizeStepEvidence;
    private recordStepToolSideEffect;
    private recordChannelEvidence;
    private extractCompletionSignals;
    private inferStepNameFromChannelText;
    private uniqueEvidenceRoots;
    private captureFileSnapshot;
    private diffFileSnapshots;
    private normalizeEvidencePath;
    private buildStepCompletionDecision;
    private buildTrajectoryCompletionEvidence;
    /** Log a progress message with elapsed time since run start. */
    private log;
    /**
     * Ensure a Relaycast workspace API key is available for the broker.
     * Resolution order:
     *   1. RELAY_API_KEY environment variable (explicit override)
     *   2. Auto-create a fresh workspace via the Relaycast API
     *
     * Each workflow run gets its own isolated workspace — no caching, no sharing.
     */
    private ensureRelaycastApiKey;
    private loadCredentialProxyModule;
    private resolveCredentialProxyProvider;
    private resolveCredentialProxySecret;
    private mintAgentProxyToken;
    private resolveAgentProxyMode;
    private getMergedRelayEnvSource;
    private getRelayEnv;
    private provisionAgents;
    private getRelaycastBaseUrl;
    private getRelaycastClient;
    private ensureRelaycastRunnerAgent;
    private createAndJoinRelaycastChannel;
    private registerRelaycastExternalAgent;
    private startRelaycastHeartbeat;
    on(listener: WorkflowEventListener): () => void;
    private emit;
    /** Parse a relay.yaml file from disk. */
    parseYamlFile(filePath: string): Promise<RelayYamlConfig>;
    /** Parse a relay.yaml string. */
    parseYamlString(raw: string, source?: string): RelayYamlConfig;
    private normalizeLegacyPermissionConfig;
    /** Validate a config object against the RelayYamlConfig shape. */
    validateConfig(config: unknown, source?: string): asserts config is RelayYamlConfig;
    /**
     * Validate a workflow config and simulate execution waves without spawning agents.
     * Returns a DryRunReport with DAG analysis, agent summary, and wave breakdown.
     */
    dryRun(config: RelayYamlConfig, workflowName?: string, vars?: VariableContext): DryRunReport;
    private validateWorkflow;
    private detectCycles;
    private detectLeadWorkerDeadlock;
    /** Resolve {{variable}} placeholders in all task strings. */
    resolveVariables(config: RelayYamlConfig, vars: VariableContext): RelayYamlConfig;
    private interpolate;
    private resolveDotPath;
    /** Build a nested context from completed step outputs for {{steps.X.output}} resolution. */
    private buildStepOutputContext;
    /** Interpolate step-output variables, silently skipping unresolved ones (they may be user vars). */
    private interpolateStepTask;
    private createStepLifecycleExecutor;
    /** Execute a named workflow from a validated config. */
    execute(config: RelayYamlConfig, workflowName?: string, vars?: VariableContext, executeOptions?: WorkflowExecuteOptions): Promise<WorkflowRunRow>;
    /** Resume a previously paused or partially completed run. */
    resume(runId: string, vars?: VariableContext, config?: RelayYamlConfig): Promise<WorkflowRunRow>;
    private runWorkflowCore;
    /** Pause execution. Currently-running steps will finish but no new steps start. */
    pause(): void;
    /** Resume after a pause(). */
    unpause(): void;
    /** Abort the current run. Running agents are released. */
    abort(): void;
    private executeSteps;
    private findReadySteps;
    /**
     * Execute preflight checks before any workflow steps.
     * All checks must pass or the workflow fails immediately.
     */
    private runPreflightChecks;
    /** Check if a step is deterministic (shell command) vs agent (LLM-powered). */
    private isDeterministicStep;
    /** Check if a step is a worktree (git worktree setup) step. */
    private isWorktreeStep;
    /** Check if a step is an integration (external service) step. */
    private isIntegrationStep;
    private executeStep;
    /**
     * Execute a deterministic step (shell command).
     * Fast, reliable, $0 LLM cost.
     */
    private executeDeterministicStep;
    /**
     * Execute a worktree step (git worktree setup).
     * Fast, reliable, $0 LLM cost.
     * Outputs the worktree path for downstream steps to use.
     */
    private executeWorktreeStep;
    /**
     * Execute an integration step (external service interaction via executor).
     */
    private executeIntegrationStep;
    /**
     * Execute an agent step (LLM-powered).
     */
    private executeAgentStep;
    private runDiagnosticAgent;
    private buildOwnerRetryBudgetExceededMessage;
    private injectStepOwnerContract;
    private buildOwnerSupervisorTask;
    private buildWorkerHandoffTask;
    private buildWorkflowRuntimeAgentBaseName;
    private releaseStaleRetryAgents;
    private buildSupervisorVerificationGuide;
    private executeSupervisedAgentStep;
    private forwardAgentChunkToChannel;
    private recordOwnerMonitoringChunk;
    private resolveAutoStepOwner;
    private resolveAutoReviewAgent;
    private isExplicitInteractiveWorker;
    private resolveOwnerCompletionDecision;
    private hasExplicitInteractiveWorkerCompletionEvidence;
    private hasOwnerCompletionMarker;
    private parseOwnerDecision;
    private stripEchoedPromptLines;
    private outputContainsVerificationToken;
    private prepareInteractiveSpawnTask;
    private firstMeaningfulLine;
    private judgeOwnerCompletionByEvidence;
    /**
     * Process-exit fallback: when agent exits with code 0 but posts no coordination
     * signal, check if verification passes (or no verification is configured) and
     * infer completion. This is the key mechanism for reducing agent compliance
     * dependence — the runner trusts a clean exit + passing verification over
     * requiring exact signal text.
     */
    private tryProcessExitFallback;
    private runStepReviewGate;
    private parseReviewDecision;
    private parseStrictReviewDecision;
    private parseTolerantReviewDecision;
    private normalizeReviewDecisionCandidate;
    private parseReviewReason;
    private judgeReviewDecisionFromEvidence;
    private combineStepAndReviewOutput;
    /**
     * Build the CLI command and arguments for a non-interactive agent execution.
     * Delegates to the consolidated CLI registry for per-CLI arg formats.
     */
    static buildNonInteractiveCommand(cli: AgentCli, task: string, extraArgs?: string[]): {
        cmd: string;
        args: string[];
    };
    /**
     * Apply preset defaults to an agent definition.
     * Explicit fields on the definition always win over preset-inferred defaults.
     */
    private static resolveAgentDef;
    /**
     * Returns a preset-specific prefix that is prepended to the non-interactive
     * enforcement block in execNonInteractive.
     */
    /**
     * Returns a prefix injected into the task prompt for non-interactive agents.
     * Lead agents are always interactive (PTY), so they never reach execNonInteractive
     * and there is no 'lead' case here.
     */
    private buildPresetInjection;
    /**
     * Execute an agent as a non-interactive subprocess.
     * No PTY, no relay messaging, no /exit injection. The process receives its task
     * as a CLI argument and stdout is captured as the step output.
     */
    private execNonInteractive;
    private spawnAndWait;
    /** Patterns where a hub agent coordinates spoke agents. */
    private static readonly HUB_PATTERNS;
    /** Roles that indicate a coordinator/lead agent (eligible for delegation guidance). */
    private static readonly HUB_ROLES;
    private isLeadLikeAgent;
    private shouldPreserveIdleSupervisor;
    /**
     * Wait for agent exit with idle detection and nudging.
     * If no idle nudge config is set, falls through to simple waitForExit.
     */
    private waitForExitWithIdleNudging;
    /**
     * Send a nudge to an idle agent. Uses hub-mediated nudge for hub patterns,
     * or direct system injection otherwise.
     */
    private nudgeIdleAgent;
    /**
     * Find the hub agent for hub-mediated nudging.
     * Returns the hub's live Agent handle if this is a hub pattern and the idle agent is not the hub.
     */
    private resolveHubForNudge;
    private runVerification;
    private updateCustomVerificationFailure;
    private updateRunStatus;
    private markStepFailed;
    private captureAgentReport;
    private markDownstreamSkipped;
    /**
     * Walk the dependsOn graph backwards from a target step to collect ALL
     * transitive dependencies (i.e. every step that must complete before
     * the target step can run). The target step itself is NOT included.
     */
    private collectTransitiveDeps;
    private checkAborted;
    private waitIfPaused;
    private delay;
    /**
     * Build a metadata note about non-interactive workers for inclusion in interactive agent tasks.
     * Returns undefined if there are no non-interactive agents.
     */
    private buildNonInteractiveAwareness;
    /**
     * Build guidance that encourages agents to autonomously delegate subtasks
     * to helper agents when work is too complex for a single pass.
     */
    /**
     * Returns a relay registration preamble for CLIs that don't auto-call
     * `register` via the MCP system prompt (everyone except claude).
     *
     * Claude reads the Relaycast system prompt and registers on its own.
     * Codex, gemini, etc. have the MCP server configured with the workspace
     * key, but they won't call `register` unless explicitly told to.
     */
    private buildRelayRegistrationNote;
    private buildDelegationGuidance;
    /** Post a message to the workflow channel. Fire-and-forget — never throws or blocks. */
    private postToChannel;
    /** Post a rich completion report to the channel. */
    private postCompletionReport;
    /** Post a failure report to the channel. */
    private postFailureReport;
    /**
     * Log a human-readable run summary to the console after completion or failure.
     * Extracts the last meaningful lines from each step's raw PTY output.
     */
    private logRunSummary;
    /**
     * Extract a useful excerpt from raw PTY output.
     * Looks for the agent's final text output (ignoring ANSI, system prompts, tool calls).
     */
    private extractOutputExcerpt;
    /** Analyze DAG structure for trajectory context. */
    private analyzeDAG;
    /** Collect step outcomes for trajectory synthesis. */
    private collectOutcomes;
    private persistRunIdHint;
    private generateId;
    private generateShortId;
    /** Strip ANSI escape codes from terminal output — delegates to pty.ts canonical regex. */
    private static stripAnsi;
    /**
     * Strip TUI chrome from PTY-captured output before posting to a channel.
     * Removes: ANSI codes, unicode spinner/thinking characters, cursor-movement
     * artifacts, and collapses runs of blank lines to a single blank line.
     * The raw (ANSI-stripped) output is still written to disk for step chaining.
     */
    private static scrubForChannel;
    /** Sanitize a workflow name into a valid channel name. */
    private sanitizeChannelName;
    /** Validate that a runId is safe for use in file paths (no traversal). */
    private validateRunId;
    /** Directory for persisted step outputs: .agent-relay/step-outputs/{runId}/ */
    private getStepOutputDir;
    /** Persist step output to disk and post full output as a channel message. */
    private persistStepOutput;
    private persistAgentReport;
    /** Scan .agent-relay/step-outputs/ for the most recent run directory containing the needed steps. */
    private findMostRecentRunWithSteps;
    /** Load persisted step output from disk. */
    private loadStepOutput;
    /** Match the best workflow from config given a set of cached step names. */
    private matchWorkflowFromCache;
    private reconstructRunFromCache;
    /** Get or create the worker logs directory (.agent-relay/team/worker-logs) */
    private getWorkerLogsDir;
    /** Register a spawned agent in workers.json so `agents:kill` can find it. */
    private registerWorker;
    /** Remove a spawned agent from workers.json after it exits. */
    private unregisterWorker;
    private readWorkers;
    private writeWorkers;
}
//# sourceMappingURL=runner.d.ts.map