/**
 * Where a text the read plan (`shell-read-plan.ts`) plans starts: a nested text's start — its names, the deny floors the
 * words handing it on carry, the user its shell runs as, its standard input and its working directory — and where each
 * segment's standard input comes from. A nested plan parsed against the declarations' working directory is re-based onto
 * the segment it sits in ({@link rebasePlan}), unless it starts in a working directory of its own.
 */
import type { LexedSegment } from "../../shell/lex.js";
import type { BindingTable, FloorValue, InheritedFunctions, NameReader } from "./shell-read-bindings.js";
import type { TargetUser } from "./program-read-model.js";
import type { StdinText } from "./shell-reentry-text.js";
import type { ReadCandidate, ShellReadPlan } from "./shell-read-plan.js";
/** Where a nested text starts its names: a substitution body inherits the table of the segment it sits in (a subshell
 *  holds every variable of the shell that forks it); a text the shell runs later or elsewhere (a code body, `eval`'s
 *  text, a child shell's `-c`) starts from the text's own start — every name unknown, `HOME` the declared home unless
 *  the enclosing text binds it anywhere. `boundAnywhere` answers for the enclosing texts. */
export interface PlanStart {
    readonly initial: NameReader;
    readonly boundAnywhere: (name: string) => boolean;
    /** `HOME` may already hold something other than the declared home where the nested text starts. */
    readonly homeTouched: boolean;
    /** The attributes, name references and deny floors in force where the nested text starts. */
    readonly inherited: BindingTable["inherited"];
    /** The working directories it starts in, where they are not the enclosing segment's (a login shell starts in its user's
     *  home; `"unmodelled"` — a home the text does not settle). */
    readonly bases?: readonly string[] | "unmodelled";
    /** The thread of the shell that runs the text, where the text runs in that shell or a fork of it ({@link HeldThread}). */
    readonly thread?: HeldThread;
    /** What the shell around the text holds where the text runs in that shell or a fork of it — a literal `eval` text, a
     *  substitution body, a text run later (a `trap` action): each function and builtin key as it stands there
     *  ({@link InheritedFunctions}). A text a new process runs (a child shell's `-c`) holds none: every builtin enabled, no function. */
    readonly names?: InheritedFunctions;
    /** What arrives on its own standard input (the input of the shell running it). */
    readonly stdin?: readonly StdinText[];
}
/** The thread of the shell that runs a text, at the segment that hands it on: a literal `eval` text is not a new plan but the next
 *  segment of the same thread, so it starts in all of it and hands the working directory and the physical mode back; a substitution
 *  body (a fork) and a text run later start in what the shell holds and hand nothing back. `functions`: the names a call may mean
 *  (the shell's definition heads and the ones an `eval` text defines), `unread` those whose bodies the nested plan has not read — an
 *  `eval` text reads the shell's bodies through the names they bind, every other text has none of them in front of it. */
export interface HeldThread {
    readonly physical: boolean;
    readonly functions: ReadonlySet<string>;
    readonly unread: ReadonlySet<string>;
}
/** What a shell holds at a segment, for a text that runs in it or in a fork of it ({@link PlanStart.names}): each function and builtin key
 *  as it stands there, and the names a call to one of its functions may change — the ones the text reads a call of: an `eval` text names
 *  the shell's functions (`bound`: what a call to one of them changes); a substitution body and a text run later read none of their bodies
 *  (the shell's functions are {@link HeldThread.unread} there: a call to one makes every name unknown), so they name none. */
export declare function heldAt(table: BindingTable, bound?: InheritedFunctions["bound"]): InheritedFunctions;
/** What a segment says of the start of a text it hands a shell to run later: the deny floors of the words it holds as
 *  written, the user the shell runs as ({@link TargetUser}), and the shell's standard input. */
export interface NestedStart {
    readonly floors?: ReadonlyMap<string, readonly FloorValue[]>;
    readonly as?: TargetUser;
    readonly stdin?: readonly StdinText[];
}
/** Where a text run later starts ({@link NestedStart}): the later start, with the shell's standard input, the floors of the
 *  words that hand it on, and — run as another user — that user's `HOME` (the caller's, the target's, or either) and, for
 *  a login shell, the target's home as its working directory. */
export declare function startedAt(later: PlanStart, at: NestedStart | undefined): PlanStart;
/** A planner that plans each text once per start: a segment read in several readings hands most of its nested texts (a
 *  substitution's body, a launched shell's text) on alike in every reading. */
export declare function plannedOnce<K, P>(plan: (text: string, kind: K, at?: NestedStart) => P): (text: string, kind: K, at?: NestedStart) => P;
/**
 * What arrives on each segment's standard input: the pipe it is reached through (`piped`, what the segment before it
 * prints); else the input of the group (`{ …; }`, `( … )`) it stands in — a group a pipe feeds hands each member that
 * pipe; else the input the text itself was handed (`start`: a shell's `-c` text reads that shell's standard input).
 */
export declare function stdinFeeds(segments: readonly LexedSegment[], start: readonly StdinText[], piped: (si: number) => readonly StdinText[]): (si: number) => readonly StdinText[];
/**
 * A nested plan (a substitution body, a here-document's substitution, a launcher's command string) was parsed
 * against the declarations' working directory; the segment it sits in may stand elsewhere (`cd sub && cat <<EOF
 * $(cat secret)`), so its relative candidates are re-based onto the ENCLOSING segment's bases — every base the
 * nested text derived from the start is carried over by prefix, an unsettled enclosing base leaves every
 * relative candidate unplaced, and absolute candidates are untouched. Recursive: a nested plan's own nested plans
 * derive from the same start. A candidate left unplaced is judged where the text stood when it lost track (its floor,
 * {@link ReadCandidate.floorBases}): the places the nested text was in move with it like its bases, and an enclosing segment that
 * lost its base itself hands on its own floor (`floor`).
 */
export declare function rebasePlan(plan: ShellReadPlan, from: string, to: ReadCandidate["bases"], floor?: readonly string[]): ShellReadPlan;
