import type { Accessor } from '../accessor/base.ts';
import { type ByteSource, type CommandOutput } from '../io/types.ts';
import type { EntryGate } from '../policy/types.ts';
import type { ProcessView } from '../process/view.ts';
import type { DiffComputer } from '../rs/diff_types.ts';
import type { FindExpr } from '../rs/find.ts';
import type { CommandRuntime, ShellFn } from '../runtime/types.ts';
import type { Limit, PathSpec } from '../types.ts';
import type { IdSource } from '../utils/ids.ts';
import type { SessionView } from '../view/types.ts';
import type { Files } from '../workspace/files.ts';
import type { AggregateResult } from './builtin/aggregators.ts';
import type { CommandSpec, FlagValue } from './spec/types.ts';
/**
 * Everything a handler gets besides its handle and its operands.
 *
 * A command handler is `fn(accessor, paths, texts, ctx)` and a CLI leaf too,
 * with the install's accessor: the same `ctx`, the facts a runtime execution
 * takes too. Files are reached through `vfs`, the session's files, which
 * judge every call at the workspace dispatcher, as `session.vfs` and a
 * policy's `ctx.vfs` do; the session through `session`. A handler reads the
 * fields it needs and ignores the rest; the workspace builds one per command
 * or CLI, and `Mount.runCommand` adds the grammar it resolved (`spec`).
 * Mirrors Python's `Context`.
 */
export interface Context {
    diff?: DiffComputer;
    /**
     * Where the command draws generated names and random values (`mktemp`,
     * `shuf`): the workspace's source, so a seeded workspace replays them.
     * Omitted means the system source.
     */
    ids?: IdSource;
    /** Piped standard input, if any. */
    stdin: ByteSource | null;
    /** The parsed flags. Read them through a spec-bound `FlagView`. */
    flags: Record<string, FlagValue>;
    /** The working directory. */
    cwd: PathSpec;
    /** A snapshot of the session environment; live access uses `session`. */
    env?: Record<string, string>;
    /**
     * The words after the head as typed, for a diagnostic that quotes one
     * (`cmp: missing operand after '-s'`). Absent when a line runs split per
     * operand or per mount.
     */
    argv?: readonly string[];
    /** The resolved grammar; its `name` is the command's. */
    spec?: CommandSpec;
    /** The session's files, run as the line's session. */
    vfs?: Files;
    /** The live session, with policy applied to writes; `env` stays the snapshot. */
    session?: SessionView;
    /** The session's processes. */
    processes?: ProcessView;
    /** Run a nested line in the calling session, as `sh -c` would (awk's pipes and `system()`). */
    shell?: ShellFn;
    admission?: EntryGate | null;
    /**
     * Where an interpreter command runs its code, and what policy lets that
     * code start and load.
     */
    runtime?: CommandRuntime;
    /**
     * find's expression, read once by mirage-rs for the whole line; `find`
     * reads it in place of its words.
     */
    find?: FindExpr;
    signal?: AbortSignal;
    timeoutSeconds?: number;
}
export type CommandFnResult = CommandOutput | null;
/**
 * A command handler: `(accessor, paths, texts, ctx)`. Generic on the
 * accessor so a backend's handler can take its own accessor type.
 */
export type CommandFn<A extends Accessor = Accessor> = (accessor: A, paths: PathSpec[], texts: string[], ctx: Context) => Promise<CommandFnResult> | CommandFnResult;
export type AggregateFn = (results: AggregateResult[]) => Uint8Array;
/**
 * One command as a mount registers it: the grammar (with `--help` and
 * `--version` added), the backend it belongs to, the file extension it
 * handles (null for every file), the handler, how to merge a run split
 * across mounts, whether it changes files, and its output limit.
 */
export declare class Command {
    readonly name: string;
    readonly spec: CommandSpec;
    readonly vfs: string | null;
    readonly filetype: string | null;
    readonly fn: CommandFn;
    readonly aggregate: AggregateFn | null;
    readonly write: boolean;
    readonly limit: Limit | null;
    constructor(init: Pick<Command, 'name' | 'spec' | 'vfs' | 'fn'> & Partial<Pick<Command, 'filetype' | 'aggregate' | 'write' | 'limit'>>);
}
/** A fixed list of commands, looked up by name and file extension. */
export declare class CommandCatalog extends Array<Command> {
    #private;
    constructor(commands: readonly Command[]);
    get size(): number;
    toArray(): readonly Command[];
    get(name: string, filetype?: string | null): Command | null;
    require(name: string, filetype?: string | null): Command;
    private static key;
    static get [Symbol.species](): ArrayConstructor;
}
export interface CommandOptions<A extends Accessor = Accessor> {
    name: string;
    vfs: string | string[] | null;
    spec: CommandSpec;
    fn: CommandFn<A>;
    filetype?: string | null;
    aggregate?: AggregateFn | null;
    write?: boolean;
    limit?: Limit | null;
}
/**
 * Register a handler as a command of one or more VFSes: one
 * `Command` per VFS, with the handler wrapped to answer `--help`
 * and `--version`.
 */
export declare function command<A extends Accessor = Accessor>(options: CommandOptions<A>): Command[];
//# sourceMappingURL=config.d.ts.map