import { CommandSpec } from '../../../commands/spec/types.ts';
import { PathSpec, type Limit } from '../../../types.ts';
import type { ProcessView } from '../../../process/view.ts';
import type { CLI, CLIHandler } from '../../../commands/cli/types.ts';
import type { CommandFnResult, Context } from '../../../commands/config.ts';
import { type ShellFn } from '../../../runtime/types.ts';
import type { FollowOperands, SessionView } from '../../../view/types.ts';
import type { Files } from '../../files.ts';
import { type FlagValue } from '../../../commands/spec/types.ts';
import { IOResult, type ByteSource } from '../../../io/types.ts';
import type { CLIInstall } from '../../cli/types.ts';
import type { MountEntry } from '../../mount/mount.ts';
import type { SessionState } from '../../session/session.ts';
import { ExecutionNode } from '../../types.ts';
import type { RouteDecision } from '../../../runtime/types.ts';
import type { Runtime } from '../../../runtime/base.ts';
import type { IdSource } from '../../../utils/ids.ts';
/**
 * Workspace facts the dispatcher can offer but most CLIs do not want: an API
 * client needs no filesystem, while `git` is nothing but one. Forwarded whole
 * onto the leaf's opts bag, so a leaf that does not read them ignores them and
 * there is no allowlist of filesystem-aware CLIs to keep in step (the same rule
 * `links` follows for mount commands).
 */
export interface CLIContext {
    shell?: ShellFn;
    signal?: AbortSignal;
    commandLimits?: Readonly<Record<string, Limit>>;
    /**
     * The workspace's ordered runtime world, which a script leaf selects
     * its interpreter from; absent (outside a workspace) refuses script
     * installs.
     */
    entries?: readonly Runtime[];
    /**
     * The session's files, run as the line's session with the command's gate,
     * for a CLI whose subject is files rather than an API.
     */
    vfs?: Files;
    session?: SessionView;
    processes?: ProcessView;
    /** The line's placement, which a script leaf runs its program under. */
    routing?: RouteDecision<Runtime>;
    /**
     * Lands what a script leaf's runtime holds and drops the caches its
     * program may have gone past; absent outside a workspace.
     */
    settle?: (runtime: Runtime) => Promise<void>;
    /** The workspace's source, which the leaf's `ctx.ids` draws from. */
    ids?: IdSource;
}
/**
 * Whether this CLI reaches a service past the dispatcher.
 *
 * Its write verbs then go past the dispatcher's per-path invalidation, so the
 * mounts its client may reach drop their caches after one
 * (`MountRegistry.dropCaches`). Two roots do that: one with a `configModel`
 * (an account CLI, initialized from it) and a script root, whose config is
 * opaque by construction and whose program may reach anything. A root with
 * neither (`git`) has no service to reach; its writes go through the
 * dispatcher, which invalidates as it goes, so a blanket drop would only cost
 * every other mount a reload. Mirrors Python's `reaches_service`.
 */
export declare function reachesService(spec: CLI): boolean;
/**
 * Execute a line whose head word is an installed CLI.
 *
 * Dispatch is by NAME: the install resolves the program tree and the
 * validated config; no mount is consulted and no operand path picks a
 * backend (the one executor divergence from mount commands). The walk
 * consumes subcommand words and group options; the leaf's own argv
 * uses the shared CommandSpec parser. The leaf gets the line's one Context,
 * built here and nowhere else: an fn leaf runs as
 * `fn(accessor, paths, texts, ctx)`, a script
 * leaf runs its embedded program on a workspace runtime
 * (scriptOutput), so usage refusals, limits, and classification all
 * happen in front of either tier. Help too, for every node that declared
 * a grammar to render it from (parseSpecFor). The workspace facts in
 * `context` reach a verb on its `ctx`, so a verb that never reads `ctx.vfs`
 * cannot touch a mount.
 */
export declare function handleCli(install: CLIInstall, parts: readonly (string | PathSpec)[], session: SessionState, stdin?: ByteSource | null, context?: CLIContext, dropCaches?: (() => Promise<void>) | null): Promise<[ByteSource | null, IOResult, ExecutionNode]>;
/**
 * A line a command tree's walk resolved to one leaf, parsed and ready to
 * run. Mirrors Python's `LeafCall`.
 */
export interface LeafCall {
    /** The line's words as typed, for the record. */
    cmdStr: string;
    /** The words after the head as typed. */
    argv: readonly string[];
    /** The head and the verb path, the name a message, a limit and the output guards read. */
    prog: string;
    /** The canonical verb path below the head. */
    path: readonly string[];
    leaf: CommandSpec;
    handler: CLIHandler;
    /** The group and leaf flags, one bag. */
    flags: Record<string, FlagValue>;
    paths: PathSpec[];
    texts: string[];
    /** What the parse warned about, said ahead of the leaf's own stderr. */
    warnings: readonly string[];
}
/**
 * Walk a line down a command tree to the leaf it names and parse the
 * leaf's words, or answer the line without running anything.
 *
 * The walk consumes subcommand words and group options; the leaf's own argv
 * uses the shared CommandSpec parser. Help, usage refusals and an operand
 * base that is no directory are answered here, for an installed CLI and a
 * tree a mount serves alike. Mirrors Python's `walk_leaf`.
 */
export declare function walkLeaf(name: string, cli: CLI, parts: readonly (string | PathSpec)[], session: SessionState, vfs: Files | undefined): Promise<LeafCall | [ByteSource | null, IOResult, ExecutionNode]>;
/**
 * Execute a line whose head word names a command tree a mount serves.
 *
 * The tree a VFS was handed (or one registered on its mount) is walked
 * exactly as an installed CLI's is (`walkLeaf`: verbs, help, usage
 * refusals, the leaf's parse); the leaf then runs on the mount, on its
 * accessor and under its refusals (`MountEntry.runLeaf`), with its own
 * limit: the profile's, then the mount's and the workspace's entry for the
 * verb path, then the leaf's declared one. A tree runs on the mount serving
 * its name, never by operand path, and its leaf keys that mount's accessor by
 * each operand: the operands the leaf parse resolved are followed through the
 * link table as the router follows a mount command's (`follow`), and one
 * another mount holds (`owner`) is refused before the leaf runs. Mirrors
 * Python's `handle_mount_cli`.
 */
export declare function handleMountCli(mount: MountEntry, cli: CLI, parts: readonly (string | PathSpec)[], session: SessionState, stdin?: ByteSource | null, context?: CLIContext, owner?: (path: string) => MountEntry | null, follow?: FollowOperands, prepared?: LeafCall): Promise<[ByteSource | null, IOResult, ExecutionNode]>;
/**
 * Run a walked leaf with the one Context a leaf gets, and record it.
 *
 * The leaf's declared limit caps its output, exactly like mount dispatch.
 * A failure the runner framed is recorded as it is; an answer gets the
 * parse's warnings ahead of its stderr. Mirrors Python's `run_walked`.
 */
export declare function runWalked(walked: LeafCall, session: SessionState, stdin: ByteSource | null, context: CLIContext, limit: Limit | null, run: (ctx: Context) => Promise<CommandFnResult>): Promise<[ByteSource | null, IOResult, ExecutionNode]>;
//# sourceMappingURL=cli.d.ts.map