@sema-agent/core
Version:
Stateless, task-oriented AI agent core
85 lines (84 loc) • 7.04 kB
TypeScript
/**
* The candidates ONE program's words hand the read station — the program read model's rows read word by word: a
* listed reader's operands and option-value slots, an unlisted program's words (its own row read where it has one,
* read the speculative way where it has none), a subcommand's words by the subcommand's row, a module's program text,
* an assignment word's value. `shell-read-plan.ts` threads the segments and their bases; this module is what one
* segment's argv offers.
*/
import { type LexedWord } from "../../shell/lex.js";
import { type Read } from "./shell-read-word.js";
import { type BindingTable, type FloorValue } from "./shell-read-bindings.js";
import { subcommandOf, type ArgRole, type ProgramRow } from "./program-read-model.js";
import type { ReadCandidate, ReadCandidateProvenance } from "./shell-read-plan.js";
/** A candidate before the threading fills its bases. `floors`: the spellings its word's names left for the deny judge
* alone (a word whose names are unknown here). */
export type Bare = Omit<ReadCandidate, "bases"> & {
readonly floors?: readonly FloorValue[];
};
/** What reading a segment's words found beside its candidates. */
export interface WordContext {
/** The names at this segment. */
readonly table: BindingTable;
/** Shell text the arithmetic evaluator runs (a substitution in a subscript it evaluates): the segment re-enters it. */
readonly reentered: string[];
/** Why the segment's reads are not established — program text the station does not read (inline text in a language that
* may open files, or a program read from standard input), or the list its operands come from
* ({@link deliveredOperandsSentence}). */
programText?: string;
/** Some program text was found in a slot (whether or not it may open files). */
programTextSeen: boolean;
}
/** The subcommand whose row says how ITS words name paths (operands or a traversal of its own), or `undefined`: a
* subcommand whose row states only its grammar — its message slots, read by {@link messageWords} — leaves its words to
* the program's own reading. */
export declare function pathSubcommandOf(row: ProgramRow | undefined, args: readonly string[]): ReturnType<typeof subcommandOf>;
/** The sentence of inline program text the station does not read. */
export declare const programTextSentence: (language: string) => string;
/** One candidate without its bases (filled by the threading pass): the word's spelling — or `spelled`, a caller's
* reading of PART of it (an option payload, a `key=value` value) — with the word's own expansion facts. The word is read
* in one reading of the segment's names (`segmentReadingsOf`): its names hold one value each, or are unknown. */
export declare function bare(r: Read, provenance: ReadCandidateProvenance, spelled?: string): Bare;
/** The reads one value of a declared role hands over: a candidate per file it names, or — a value the program expands
* past the listed bound — the word itself, unresolvable. A mount source is a read the daemon makes of the whole tree
* under it (a read and a traversal root); an object path
* `<rev>:<path>` offers the word as a path and the `<path>` it spells to the deny judge; program text is never a path
* ({@link programTextReads}). `alsoOperand`: the walk read the option past the first operand, where the program may
* have stopped reading options — a path role is still offered (more candidates), but no program text is read there:
* the word is the operands' (the script's own argument), as the program's delivery reading says. */
export declare function roleReads(r: Read, provenance: ReadCandidateProvenance, value: string, role: ArgRole, globs: "expanded" | "literal", ctx: WordContext, alsoOperand?: boolean): Bare[];
/**
* The candidates a `NAME=value` word hands the judge, both facts about its VALUE (the word is a path to nobody):
* what path it NAMES, and what the text cannot SETTLE — placed as an operand is wherever an environment value
* names ONE path (a leading tilde against the declared home; a `:` joins a second). Where the text runs nothing able
* to open a file, {@link planShellReads} drops them: the value names a path to nobody.
*
* Bash applies its assignment-word expansion to such a word even when it is an ARGUMENT to a simple command, so
* the program receives `NAME=<expanded value>`, and a program that reads its value as a path (`dd if=…`, a build
* or tool variable, a launcher's environment word) opens what the value names. Two facts of the lexer's
* {@link AssignmentFact} are read: a tilde the shell EXPANDS in the value (at its start and after each `:`, where
* unquoted — `value.expansions`) leaves the path unsettled, and the append form (`NAME+=value`) names `<whatever
* NAME held>` + value, so the whole value is not in the text — but the text it appends IS, and an unset or empty
* NAME makes it the whole value, so it is a candidate too. A value that is a substitution is the nested plan
* its body already is, never a candidate of its own text (its placeholder is not a path).
*/
export declare function pushAssignment(reads: Bare[], w: LexedWord, provenance: ReadCandidateProvenance): void;
/** Every word of a segment whose program's grammar this parser does not model, from `from` onward: option
* payloads and path-shaped option words included, the launcher chain's own words excluded, a program declared
* to open no path operand handing only the environment words in front of it. A program with NO row is read the
* speculative way: every word is still handed over, but the filesystem decides it
* ({@link ReadCandidate.speculative}). */
export declare function unlistedWords(reads: Bare[], toks: readonly Read[], from: number, launcherIndices: ReadonlySet<number>, provenance: ReadCandidateProvenance, ctx: WordContext, program?: {
readonly index: number;
readonly basename: string;
}): void;
/** The positional operands and declared option-value slots of a listed reader — the program read model's argv walk,
* one candidate per word the program may open, plus the traversal roots of a recursive form. A subcommand's words
* are read by its own row; the words a module takes as its program text are program text. */
export declare function listedVerbCandidates(name: string, argReads: readonly Read[], reads: Bare[], ctx: WordContext): void;
/** The subscript of a variable-name word (`a[…]`), as the arithmetic text that is evaluated; the empty text for a plain
* name. */
export declare function subscriptOnly(word: string): string;
/** An assignment word's arithmetic: its own subscript (`a[$(…)]=1`, quoted or not — not for a builtin that takes the
* name `asWritten`), and its value where the name carries the integer attribute (`declare -i n; n='a[$(…)]'`, bash's
* own `OPTIND` / `RANDOM` / …). */
export declare function assignmentArithmetic(w: LexedWord, integer: boolean, ctx: WordContext, asWritten?: boolean): void;