@sema-agent/core
Version:
Stateless, task-oriented AI agent core
66 lines (65 loc) • 5.26 kB
TypeScript
/**
* The candidate readers' VIEW of a word — what the read plan names a candidate by, read off the one lexer's facts.
* Every reader of `shell-read-plan.ts` walks these, never a raw or folded string of its own: the two spellings
* (the home-directory word spelled with the declared home, as bash hands it to the program), and what the shell
* does to the word before the program sees it.
*/
import { type LexedCommand, type LexedToken, type LexedWord, type WordPiece } from "../../shell/lex.js";
/** `"glob"` = an unquoted pathname-expansion character; `"unresolvable"` = the shell rewrites the word (a brace,
* variable or command substitution) so its text is not the path. The read candidate's own field, spelled here. */
export type WordExpands = false | "glob" | "unresolvable";
/** A word as the candidate readers name it: the lexer's word, the two spellings (the home-directory word spelled
* with the declared home — {@link homeExpansionOf} — as bash hands it to the program), and what the shell does
* to it before the program sees it. */
export interface Read {
readonly word: LexedWord;
readonly raw: string;
readonly folded: string;
readonly expands: WordExpands;
/** The word spells the declared home: its one expansion IS the spelling above. */
readonly homeSpelled?: true;
}
export declare function readsOf(words: readonly LexedWord[], home: string | undefined): Read[];
/** The shell REWRITES this read's word before the program sees it (a parameter, command, process, arithmetic or
* brace expansion, or the character of one) — the home word excepted, whose one expansion is its spelling. */
export declare const rewritten: (r: Read) => boolean;
/** The reading of a text that came out of a word (a sed script's file operand): one shell word, or unresolvable. */
export declare function readOfText(text: string): Read;
/** A home-rooted candidate spelled with `home`: a leading `~` / `~/` — the shell's expansion, or the literal-tilde
* spelling `./~` of one it leaves alone (quoted, escaped, after an option's `=`), which the program it reaches may
* expand itself — or a `$HOME` / `${HOME}` word as {@link homeExpansionOf} reads it, read off the VALUE's pieces when
* the word is assignment-shaped (`A="$HOME/x"`, `dd if="$HOME/x"`: the candidate is the value, quotes kept);
* `undefined` for any other (`~user`, a word that is no home word). */
export declare function spelledWithHome(spelled: string, raw: string, home: string): string | undefined;
/** A function definition's head names nothing that runs here and is dropped from a segment's tokens, in place:
* `NAME ( )` (an identifier), and `function NAME [( )]` — a bare `function` at command position, a name of any
* spelling. The lexer puts the body's compound command back at command position after the head, so a definition
* nested in a body is dropped the same way; after a drop the token that moved up is looked at again. */
export declare function dropDefinitionHeads(tokens: LexedToken[]): void;
/** Why a lexed text's reads cannot all be named — the plan's `unreadable` floor, or `undefined`: the first word whose
* value the text does not contain (an unresolved word), or an unquoted extended-glob opener anywhere a word, a
* redirection target or a here-document delimiter stands (`pack@(age.json)`, `<<@(x)`). After `shopt -s extglob`
* bash expands the pattern (or reads another delimiter) where the lexer reads a split word, so what the text opens is
* not what the plan names: the whole text asks, and a deny hit anywhere still refuses. `globs: false` = the text is an
* arithmetic expression (`$((2*(3+4)))`), which bash evaluates and never globs. */
export declare function unreadableSentenceOf(lexed: LexedCommand, text: string, globs?: boolean): string | undefined;
/** The elements of a compound array value `(e1 [k]=e2 …)`, read with the one lexer as the words bash assigns (a
* `[k]=` subscript prefix dropped): each is a value spelling the deny judge reads, as a scalar value is. The list is
* words across lines and comments, so every segment's words count, whatever else a segment carries (a word bash
* would reject leaves its siblings readable). None when the list does not lex — the value stays the unread list. */
export declare function compoundArrayElements(value: {
readonly raw: string;
}): readonly (Read & {
readonly denyOnly?: true;
})[];
/** An `$((…))` body the shell reads as ARITHMETIC: one parenthesised group spanning the whole body (`(2*(3+4))`),
* its bounds read off the lexer's structure — a quoted, escaped or commented parenthesis is text, not a bound — across
* the segments the lexer cuts at `&&` `||` `&` `|` and line breaks (operators arithmetic shares with the shell).
* `$((cat x); :)` opens the same way but its first group closes early: a command substitution holding a subshell. */
export declare function isArithmeticBody(body: string): boolean;
/** What the shell does to a word (or an assignment's value) before the program sees it, read off its pieces. */
export declare function expandsOf(w: {
readonly pieces: readonly WordPiece[];
readonly raw: string;
readonly folded: string;
}): WordExpands;