/**
 * The boot context — the immutable value the {@link import("./pipeline").Stage}
 * pipeline assembles and the runners consume.
 *
 * A {@link BootContext} is everything a runner needs to drive the agent and
 * nothing it needs to recompute: the parsed {@link Invocation}, the resolved
 * {@link Settings} and {@link Locator}, the chosen model id and working
 * directory, a ready-to-call agent factory, the two I/O seams a runner talks to,
 * and the list of resource teardowns to invoke on exit.
 *
 * The context is built up stage by stage. Early stages have only the seed fields
 * populated; each later stage returns a copy with one more field filled in. By
 * the time the pipeline finishes, every field is present. Rather than thread a
 * dozen partially-filled variants through the type system, we model the context
 * as a single fully-typed shape and rely on the stage order to populate it — the
 * concrete builder seeds the I/O and invocation fields and lets the stages do
 * the rest.
 *
 * The two I/O fields ({@link BootContext.output}, {@link BootContext.input}) are
 * deliberately narrow seams, not concrete terminals. The shell app's interactive
 * surface is out of scope for this phase; a richer terminal UI can later supply
 * its own implementations of these interfaces without this module changing.
 */
import type { Invocation } from "../invocation/parse";
import type { Locator, Settings } from "../config";
import type { Agent, AgentDeps } from "../../runtime";
/**
 * A line-oriented output sink the runners write user-facing text to.
 *
 * Kept to the bare minimum a one-shot or wire runner needs. A production binding
 * writes to a stream (stdout/stderr); a test binding captures lines in an array.
 * The interactive runner layers a richer view on top of this seam rather than
 * widening it.
 */
export interface OutputSink {
    /** Emit one line of normal output (a trailing newline is implied). */
    write(line: string): void;
    /** Emit one line of diagnostic/error output, routed apart from normal output. */
    writeError(line: string): void;
}
/**
 * A line-oriented input source the interactive runner reads prompts from.
 *
 * `nextLine` resolves the next line the user supplied, or `null` at end of
 * input (the stream closed / EOF). The production binding wraps a readline
 * interface over stdin; a test binding replays a scripted list. Non-interactive
 * runners (one-shot, wire) take their input from the invocation and never call
 * this.
 */
export interface InputSource {
    /** Resolve the next input line, or `null` once the source is exhausted. */
    nextLine(): Promise<string | null>;
}
/**
 * The pair of I/O seams a runner is given. Passed into the boot builder so the
 * pipeline can thread them onto the context without reaching for `process`.
 */
export interface BootIo {
    /** Where runners send user-facing and diagnostic output. */
    readonly output: OutputSink;
    /** Where the interactive runner reads its prompts. */
    readonly input: InputSource;
}
/**
 * A deferred teardown for a resource opened during boot.
 *
 * Stages that open long-lived resources (an MCP server fleet, a session store
 * handle) push one of these onto {@link BootContext.closables}; the launcher
 * invokes them in reverse order on shutdown. Each returns a promise so async
 * teardown can be awaited.
 */
export type Closable = () => Promise<void>;
/**
 * The fully-assembled startup context.
 *
 * Produced by running the boot stages over a seed context. Once assembled, it is
 * the single argument the runners (one-shot / wire / repl) need: it tells them
 * what the user asked for, how the agent is wired, and where to read and write.
 */
export interface BootContext {
    /** What the user invoked us with: parsed flags, positionals, prompt, mode. */
    readonly invocation: Invocation;
    /** The effective, merged configuration (defaults ← global ← project). */
    readonly settings: Settings;
    /** Where on-disk state lives; the single source of path truth. */
    readonly locator: Locator;
    /** The validated model id every run binds to. */
    readonly modelId: string;
    /** The absolute working directory the agent and tools are rooted at. */
    readonly cwd: string;
    /**
     * Construct a fresh agent over the assembled configuration.
     *
     * `deps` lets a runner inject collaborators — most usefully a scripted model
     * invoker or a session store — without the factory leaking how the agent is
     * configured. Called once per logical session.
     */
    makeAgent(deps?: AgentDeps): Agent;
    /** The output seam the runner writes to. */
    readonly output: OutputSink;
    /** The input seam the interactive runner reads from. */
    readonly input: InputSource;
    /**
     * Resource teardowns to run on shutdown, in the order they were registered.
     * The launcher invokes them (conventionally in reverse) before exiting.
     */
    readonly closables: Closable[];
}
