import type { Runtime } from '../../runtime/base.ts';
import type { RouteDecision } from '../../runtime/types.ts';
import type { MountRegistry } from '../mount/registry.ts';
import type { SessionState } from '../session/session.ts';
import { Consumer } from './types.ts';
/**
 * Whether a command word is a tool the allow lists govern. Every named
 * command is a subject, shell builtins included: an allow list stating
 * `cat` leaves no `echo` and no `cd`. Two kinds of word are not,
 * because neither is a name the list could hold: a path being executed
 * (its lines are each checked as they run), and the agent's own
 * function where the function is what runs, which in this shell means
 * a name no builtin owns (builtins shadow functions), and its body's
 * lines each pass the gate themselves.
 */
export declare function isTool(name: string, session: SessionState): boolean;
/** Whether routing explicitly refused the external runtime for `name`. */
export declare function runtimeRefused(name: string, session: SessionState, registry: MountRegistry, routing?: RouteDecision<Runtime>): boolean;
/**
 * Route a command name to the layer that consumes it.
 *
 * Order mirrors dispatch precedence: shell builtins shadow functions,
 * functions shadow installed CLIs, CLIs shadow mount commands, and a
 * name nobody registers is UNKNOWN (command not found). Install-time
 * collision rules keep the CLI arm honest: a CLI may not take a shell
 * builtin's or a general command's name, so the only shadowing a CLI
 * can actually exert is over a mount-specific custom command.
 *
 * The full landscape, in precedence order. The column to watch is what
 * resolves the name: session or workspace state for the named layers,
 * operand paths for mounts:
 *
 *     Consumer   Example              Resolved by          Words
 *     SESSION    cd, echo, export     name in SHELL_NAMES  shell-expanded
 *     NAMESPACE  ln -s, readlink      NAMESPACE_COMMANDS   shell-expanded
 *     FUNCTION   deploy() {..}        session.functions    shell-expanded
 *     CLI        slack message send   registry.clis        shell-expanded
 *     MOUNT      grep, cat, du        operand paths        pushdown
 *     UNKNOWN    bogus                nobody               untouched, 127
 *
 * Named process captures select EXTERNAL before mount commands.
 * EXTERNAL_COMMANDS handles names no preceding layer owns.
 *
 * This is the winner only. A name can sit in more than one layer at once
 * (a function shadowing an installed CLI); `lookupAll` reports them all,
 * which is what `type -a` prints. Reading one item off the generator is
 * what makes that sharing free: the lookups after the winner never run,
 * so dispatch pays exactly what it did when this was a chain of `if`
 * arms.
 */
export declare function lookup(name: string, session: SessionState, registry: MountRegistry, routing?: RouteDecision<Runtime>): Consumer;
/**
 * Every layer holding the name, most-preferred first.
 *
 * Empty when nothing holds it, where `lookup` says UNKNOWN. Only
 * introspection (`type -a`, `which -a`) needs this: dispatch runs the
 * winner and never asks what it shadowed.
 */
export declare function lookupAll(name: string, session: SessionState, registry: MountRegistry): Consumer[];
/**
 * The layer a name runs from as a program, null when it is none.
 *
 * A program is what a real system ships as a file on PATH, so it has one
 * under `/usr/bin` here: every mount, namespace and CLI command, every
 * name a runtime captures by name, and each builtin a real system also
 * finds on disk (echo, test, xargs). The shell's own words (cd, export,
 * history: `SHELL_ONLY_BUILTINS`), reserved words, functions and aliases
 * have no file, and a shell word keeps none when a mount registers the
 * same name, since the builtin is what runs. Nor does a name only the
 * external fallback capture takes: it takes any word, so like bash's
 * `command_not_found_handle` it runs a name without making it a program.
 * An interpreter (python3, node) is a program only where a language
 * runtime is bound to it: without one it answers 127, as it does on a
 * system that never installed it. A function shadowing a program leaves
 * the file in place, as it does on PATH.
 */
export declare function program(name: string, session: SessionState, registry: MountRegistry): Consumer | null;
/**
 * Whether a builtin that execs its operand (xargs, timeout) finds it.
 *
 * GNU execs the name, so a shell word with no file on PATH (cd, export) is
 * missing there, as is a name nothing provides. A function runs too, where it
 * is what the name runs (a shell word shadows one): mirage runs the line in
 * the shell, which is how these reach it. A path is left to the run, which
 * reports on it.
 */
export declare function execs(name: string, session: SessionState, registry: MountRegistry): boolean;
/**
 * What a program's `/usr/bin` file says about it, null when the name is no
 * program.
 *
 * One line: what runs the name, and `--help` where the program's spec
 * answers it, which a mount command's and a CLI's do; a builtin's answer
 * varies (`ln --help` and `echo --help` print no help), so a builtin's
 * line names none.
 */
export declare function programNote(name: string, session: SessionState, registry: MountRegistry): string | null;
/**
 * The program a command word runs: a wrapper no mount registers (`egrep`)
 * runs the program it names, any other word itself.
 */
export declare function runsAs(name: string, registry: MountRegistry): string;
/**
 * Every program name the session can run, sorted: the `/usr/bin` listing.
 *
 * The names are gathered from each layer that can hold a program and
 * kept only where `program` says the name runs as one, so the listing and
 * a lookup never disagree. A name only the external fallback capture
 * would take cannot be listed, since that capture takes any word.
 */
export declare function programs(session: SessionState, registry: MountRegistry): string[];
//# sourceMappingURL=lookup.d.ts.map