/**
 * TrackRunner — thin wrapper around train-lang's runFile that wires
 * the CcwebTrainAdapter + WorkflowDataWatcher + writeProtocolHint into
 * a single ergonomic API for the rest of the ccweb backend.
 *
 * Lifecycle:
 *   const runner = createTrackRunner({ ... deps ... })
 *   const result = await runner.run(absTrackPath)
 *   // result.ok / result.value / result.error
 *
 * Cancel mid-run: runner.cancel() → AbortController fires → train
 * short-circuits next fai dispatch + adapter reports FaiCancelled.
 *
 * train-lang is ESM and ccweb backend is CommonJS, so we use a
 * dynamic import (cached at first call). This is the standard
 * CJS→ESM interop pattern.
 *
 * 详见 ~/Obsidian/Base/cc-web/工作轨重构规划.md §9 T0。
 */
import { type CcwebAdapterDeps } from './ccweb-train-adapter';
import type { WorkflowDataWatcher } from './workflow-data-watcher';
import type { TrackRunState } from './types';
import { type AskUserBridge } from './ask-user-bridge';
export interface TrackRunnerDeps {
    projectId: string;
    injector: CcwebAdapterDeps['injector'];
    watcher: WorkflowDataWatcher;
    /** Total fai attempts per call. Default 3. */
    maxFaiAttempts?: number;
    /** Per-fai-call timeout (ms). Default 600_000. */
    defaultFaiTimeoutMs?: number;
    /** Logger (pino). */
    logger?: CcwebAdapterDeps['logger'];
    /** Optional extra trace listener for UI progress. */
    onState?: (state: TrackRunState) => void;
    /**
     * Bridge for __ccweb_ask_user builtin. When provided, .tr code can
     * call __ccweb_ask_user({fields:[...]}) to suspend on user input.
     * Without a bridge, the builtin is not registered; calls fail with
     * "Undefined identifier '__ccweb_ask_user'".
     */
    askUserBridge?: AskUserBridge;
    /**
     * Pre-allocated runId. The caller (registry) needs to know the runId
     * synchronously before run() awaits, so it can route submitInput /
     * getPendingAskUser to the right bridge entry. If omitted, runner
     * generates one. Used so registry.entry.runId === bridge pending key.
     */
    runId?: string;
}
export interface TrackRunResult {
    ok: boolean;
    value: unknown;
    error?: {
        errorType: string;
        message: string;
        code?: string;
    };
}
export interface TrackRunner {
    /** Run a .tr file. Resolves when the track terminates (success/fail/cancel). */
    run(absTrackPath: string, args?: unknown[]): Promise<TrackRunResult>;
    /** Cancel an in-flight run. */
    cancel(): void;
    /** Current state snapshot. */
    getState(): TrackRunState | null;
}
export declare function createTrackRunner(deps: TrackRunnerDeps): TrackRunner;
//# sourceMappingURL=track-runner.d.ts.map