import type { ExtensionAPI, ExtensionCommandContext, ExtensionFactory } from "@earendil-works/pi-coding-agent";
import { type ForgeToolDefs } from "../forge-tools.js";
import { getSessionRegistry } from "../session-registry.js";
export declare function isNonInteractive(): boolean;
export interface PhaseDescriptor {
    /** Workflow role name (also used as key for summaries and iteration tracking). */
    role: string;
    /** Filename under .forge/workflows/ (without extension). */
    workflowFile: string;
    /** Persona noun passed to loadForgePersona. */
    personaNoun: string;
    /** When true: read summaries.<role>.verdict after dispatch. */
    isReview: boolean;
    /** Max revision iterations before escalation. */
    maxIterations: number;
}
export declare const PHASES: PhaseDescriptor[];
export declare const SUMMARY_KEY_BY_ROLE: Record<string, string | null>;
export interface RunTaskState {
    taskId: string;
    phaseIndex: number;
    iterationCounts: Record<string, number>;
    halted: boolean;
    /** Set on cancellation so the resume prompt can say "cancelled" vs "halted". */
    status?: "cancelled" | "halted" | "running";
    lastError?: string;
    savedAt: string;
}
/** Validate that an ID contains no path-traversal characters. */
export declare function validateId(id: string): boolean;
export declare function readState(cwd: string, taskId: string): RunTaskState | null;
export declare function writeState(cwd: string, state: RunTaskState): void;
export declare function deleteState(cwd: string, taskId: string): void;
export declare function isStateStale(state: RunTaskState): boolean;
/**
 * Format an ISO timestamp for human display in the user's local timezone.
 * Falls back to the raw ISO string if parsing fails.
 */
export declare function formatLocalTime(iso: string): string;
export interface RunTaskPipelineOptions {
    taskId: string;
    cwd: string;
    ctx: ExtensionCommandContext;
    forgeRoot: string;
    storeCli: string;
    preflightGate: string;
    registry: ReturnType<typeof getSessionRegistry>;
    /** When provided, pipeline starts from this state instead of phase 0.
     *  Used by run-sprint.ts for mid-task resume (REVIEW FIX #2, option b). */
    resumeFromState?: RunTaskState;
    /** Optional observer for phase events; called after emitEvent. */
    onPhaseEvent?: (event: Record<string, unknown>) => void;
    /**
     * Test-only seam (forge-cli#17). When set, each phase's `runForgeSubagent`
     * call receives `streamFn = streamFnFactory({...})`. Production callers
     * leave this undefined. See helpers/scripted-subagent.ts and
     * fixtures/sprint-fixture.ts.
     */
    streamFnFactory?: (ctx: {
        kind: "task-phase";
        persona: string;
        phase: string;
        taskId: string;
    }) => import("@earendil-works/pi-agent-core").StreamFn | undefined;
    /**
     * Optional AbortSignal from SessionRegistry. When provided, the pipeline
     * checks signal.aborted between phases and passes the signal to
     * runForgeSubagent so in-flight subagents can be aborted.
     */
    signal?: AbortSignal;
    forgeToolDefs?: ForgeToolDefs;
    /**
     * Extension factories forwarded to each subagent session via runForgeSubagent.
     * Used by Mechanism E (FORGE-S30-T07) to inject the Forge-aware compaction
     * handler when FORGE_CTX_GOVERNOR=1. No-op when undefined (default path unchanged).
     */
    extensionFactories?: ExtensionFactory[];
}
export type RunTaskPipelineStatus = "completed" | "halted" | "escalated" | "failed" | "cancelled";
export interface RunTaskPipelineResult {
    status: RunTaskPipelineStatus;
    lastPhaseIndex: number;
    iterationCounts: Record<string, number>;
    lastError?: string;
    /** Model captured from last successful phase's subagent result (REVIEW FIX #1). */
    model?: string;
    /** Provider captured from last successful phase's subagent result (REVIEW FIX #1). */
    provider?: string;
    /**
     * Project-local orchestrator JSONL path for this run
     * (.forge/transcripts/<taskId>/<ISO>__<taskId>__orchestrator.jsonl).
     * Callers (registerRunTask, run-sprint) hand it to archiveRun() to mirror
     * the run into the central transcript archive. Unset only when the
     * pipeline returned before the transcript writer was created (preflight).
     */
    orchestratorTranscriptPath?: string;
}
type Verdict = "approved" | "revision" | "n/a" | "missing";
export declare function readVerdict(taskId: string, phaseRole: string, storeCli: string, cwd: string): Verdict;
export interface TaskRecord {
    sprintId?: string;
    status?: string;
    summaries?: Record<string, unknown>;
}
export declare function readTaskRecord(taskId: string, storeCli: string, cwd: string): TaskRecord | null;
export declare function actionForRole(role: string): string;
export interface OrchestratorEmitContext {
    /** Entity identifier — required when entityType is "task". */
    taskId?: string;
    /** Entity identifier — required when entityType is "bug". */
    bugId?: string;
    /** Discriminator for entity-keyed event construction. */
    entityType: "task" | "bug";
    sprintId: string;
    phase: PhaseDescriptor;
    iteration: number;
    startMs: number;
    endMs: number;
    model: string;
    provider: string;
    usage: {
        input: number;
        output: number;
        cacheRead: number;
        cacheWrite: number;
    };
    judgement: Record<string, unknown> | undefined;
    storeCli: string;
    cwd: string;
}
export declare function isoCompact(ms: number): string;
export declare function buildPhaseEvent(ec: OrchestratorEmitContext): Record<string, unknown>;
export declare function emitEvent(storeCli: string, cwd: string, sprintId: string, event: Record<string, unknown>): {
    ok: boolean;
    stderr: string;
};
/**
 * Emit a phase event for an INCOMPLETE attempt (cancelled / failed) so its
 * provider-billed tokens reach the store. Bug B: the cancel and halt-on-failure
 * branches used to return without emitting, so collate's COST_REPORT
 * under-counted real spend by exactly the aborted passes (CART-S02-T03
 * baseline: 259,950 tokens across two aborted plan attempts, invisible).
 *
 * The event is the canonical phase event (schema-unchanged) with
 * `verdict: "aborted" | "failed"` marking the outcome.
 *
 * Zero-token attempts are skipped — there is no spend to account, and a
 * token-less event would be flagged as a husk by collate's ingestion-quality
 * pass. Never throws: emission must not perturb the cancel/halt return paths.
 *
 * @param opts.decorate  Optional event mutation hook applied before emit
 *                       (fix-bug uses it for the BUG_TYPE_TOKENS `type` field).
 * @returns true when the event was emitted and store-cli accepted it.
 */
export declare function emitIncompletePhaseEvent(opts: {
    emitCtx: OrchestratorEmitContext;
    outcome: "aborted" | "failed";
    notes?: string;
    decorate?: (event: Record<string, unknown>) => void;
    onDebug?: (rec: Record<string, unknown>) => void;
}): boolean;
export declare function judgementFromSummary(record: TaskRecord | null, phaseRole: string, summaryKeyByRole?: Record<string, string | null>): Record<string, unknown> | undefined;
export declare function drainFrictionFile(frictionPath: string, ec: OrchestratorEmitContext): {
    emitted: number;
    failed: number;
};
export declare function findPredecessorIndex(phases: PhaseDescriptor[], reviewIndex: number): number;
export declare function buildSummariesBlock(summaries: Record<string, unknown> | undefined): string;
export declare function composeTaskBody(subWorkflowMd: string, taskId: string, summariesBlock?: string): string;
export type PreflightResult = "proceed" | "halt" | "escalate";
/** Structured gate failure shape emitted by preflight-gate.cjs on stdout (exit 1). */
export interface GateFailureData {
    phase: string;
    reasonCode: string;
    detail: string;
    remediation: string;
}
/** Extended result carrying the structured failure alongside the status enum. */
export interface PreflightOutcome {
    result: PreflightResult;
    /** Parsed structured failure from stdout, or null on pass / escalate. */
    gateFailure: GateFailureData | null;
}
export declare function runPreflightGate(preflightGate: string, role: string, taskId: string, cwd: string, entityType?: "task" | "bug"): PreflightResult;
/**
 * Run postflight-gate.cjs after a phase subagent returns, before FSM advance.
 * Mirrors runPreflightGateWithData — same argv-array discipline, same structured-JSON
 * parsing from stdout on exit 1.
 *
 * Returns:
 *   "ok"          — gate passed (or no outputs block for this phase); advance may proceed.
 *   "unsatisfied" — gate failed; do NOT advance FSM; halt and call runHaltAdvisor.
 *   "error"       — gate binary missing or parse error; treat as pass-through (additive).
 */
export declare function runPostflightGate(postflightGate: string, role: string, taskId: string, cwd: string): {
    result: "ok" | "unsatisfied" | "error";
    gateFailure: GateFailureData | null;
};
/**
 * Upgraded variant that returns structured failure data alongside the status enum.
 * Callers that need the advisory data should use this function directly.
 */
export declare function runPreflightGateWithData(preflightGate: string, role: string, taskId: string, cwd: string, entityType?: "task" | "bug"): PreflightOutcome;
export { extractTurnPreview } from "../viewport/renderer.js";
/** Map a pipeline status to the orchestrator-transcript outcome vocabulary.
 *  Shared with fix-bug.ts (RunBugPipelineStatus is the same string union). */
export declare function transcriptOutcomeFor(status: RunTaskPipelineStatus): "complete" | "halted" | "cancelled" | "error";
export declare function runTaskPipeline(opts: RunTaskPipelineOptions): Promise<RunTaskPipelineResult>;
export interface RegisterRunTaskOptions {
    cwd?: string;
    forgeToolDefs?: ForgeToolDefs;
    /** Extension factories forwarded to each subagent (see RunTaskPipelineOptions). */
    extensionFactories?: ExtensionFactory[];
}
export declare function registerRunTask(pi: ExtensionAPI, options?: RegisterRunTaskOptions): void;
