UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

85 lines (84 loc) • 7.04 kB
/** * 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;