UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

93 lines (92 loc) • 7.13 kB
/** * THE STANDARD DEVICES — the spellings a shell command names for its own standard streams and terminal, which the * containment question is not asked of, and which write nothing durable: ONE table, ONE predicate, read by every layer that * would otherwise treat the word as a path — the shell read station's entries (an output or input redirection's target, a read * operand, the content a program writes through an operand, a `git diff` operand) and the shape tier's two readings of "does * this redirection write" (the read-only reader, the classify faces' data-free redirections). * * The table is the reference implementation's own device predicate (CC 2.1.296 `wwe` (cli296.js:249645) @18511591): the null * device, the three standard streams, the terminal, any `/dev/fd/<digits>`, and `/proc/self/fd/{0,1,2}`. A word is such a * spelling AS WRITTEN (quotes removed, nothing folded: `/dev/./null` is a path, not the null device). * * What exempts a word is more than its spelling, on both counts: * · it is I/O THROUGH the node — a redirection, a read operand, the content a program writes by opening the path * (`ReadCandidate.through`). A program that creates, unlinks, renames or retargets the path's directory ENTRY * (`rm`, `mv`, `mkdir`, `touch`, an in-place edit) is judged as it judges any path, and so is a word of a program the * station has no row for (`ln`, `chmod`): nothing says that program only opens it; * · no redirection of the same text can have rebound the descriptor the spelling names. A descriptor spelling is a * name for whatever that descriptor is bound to WHEN THE WORD IS OPENED: `3< f` or `exec 3>f` before it makes * `/dev/fd/3` the file `f`, and `1<f > /dev/stdout` reopens `f` for writing. Such a descriptor is judged at its landing * like any path. (One step stricter than the reference, which exempts the spelling whatever the text does.) A text the * consumer cannot read in full may bind anything, so it exempts no descriptor spelling; the null device and the * terminal name no descriptor and are exempt always. * * Beside the table, the generator devices (`/dev/zero`, `/dev/random`, `/dev/urandom`, `/dev/full`) are not a stream of the * process: a read of one is no question only while the program read model knows the read is bounded * (`byteBoundIsSmall`: `head -c N`), the same fact the read-only classifier's endless-device arm reads. */ import type { ReadCandidate, ReadCandidateProvenance, ShellReadPlan } from "./shell-read-plan.js"; /** Is this word, as written, a standard device? `descriptor`: the descriptor number it names, when it names one. */ export declare function standardDeviceOf(spelled: string): { readonly descriptor?: number; } | undefined; /** The devices that PRODUCE data without end: read in bounded bytes they cost nothing, read unbounded they never finish. */ export declare const GENERATOR_DEVICES: ReadonlySet<string>; /** A redirection, as far as binding a descriptor goes: its operator and the number written in front of it (the lexer's * `LexedRedirect` and the plan's `ShellReadRedirect` both are one). */ export interface RedirectionBinding { readonly op: string; readonly fd?: number; } /** What a text does to its descriptors: how many redirections bind each (a count, so the one that IS the use of a spelling * can be taken out of it), and whether it may bind any it does not show. */ export interface LineDescriptors { /** Some part of the text the consumer cannot read in full may bind any descriptor (an unreadable text, a program or an * `eval` / `source` text it does not see, a numbered here-document whose number the lexer drops, a redirection whose number * the reader keeps no record of). */ unknown: boolean; /** A `{name}` word — bash allocates a descriptor from 10 up for a redirection written `{name}>f`. */ named: boolean; readonly bound: Map<number, number>; } export declare const newLineDescriptors: () => LineDescriptors; /** The descriptors one redirection binds: the number written in front of it, else the operator's own (`>` family: 1, * `<` family: 0, `&>`: both output streams). */ export declare function descriptorsBoundBy(r: RedirectionBinding): readonly number[]; export declare function bindDescriptors(into: LineDescriptors, r: RedirectionBinding): void; export declare const isNamedDescriptorWord: (raw: string) => boolean; /** * THE predicate for a word and the text it stands in: is it a standard device (the table, as written) whose descriptor — if it * names one — no redirection of the text rebinds? `self`: the descriptors the redirection that IS the use binds (a word that * is not a redirection's target passes none). */ export declare function standardDeviceUnrebound(spelled: string, text: LineDescriptors, self: readonly number[]): boolean; /** * The provenances whose word a program OPENS (or a redirection opens): a read operand or option value, an input * redirection's source, an output redirection's target, and a word of a program the deployment did not list as a reader but * whose row the station holds (`unlisted_word`, unless it waits for the filesystem — {@link ReadCandidate.speculative}: a * program with no row may do anything with the word), and the root of a tree walk (`grep -r`, `diff`: a standard device is * no directory to walk — an option that writes beyond the operands, `find -delete`, takes the exemption back, see * `judgedCandidatesOf`). Not a directory a program changes into (`cd_target`), not a program, an assignment's value or a * mount source. */ export declare const OPENED_PROVENANCES: ReadonlySet<ReadCandidateProvenance>; /** * Does the containment question go unasked of this candidate? The one predicate every entry of the station reads: the plan * marked the word a standard device no redirection of its text rebinds ({@link ReadCandidate.device}), and — for a word the * program WRITES — the program writes its content through the path ({@link ReadCandidate.through}), not its entry. */ export declare function passesUnasked(candidate: ReadCandidate): boolean; /** * What the whole text of a plan binds: every redirection of every segment — a single one, an `exec`'s, a `{name}` one included — * and whether the text may bind more than it shows. The ONE computation behind the station's rebinding rule * ({@link markStandardDevices}) and the shape tier's reading of a program's device operands (`tee /dev/fd/3`). */ export declare function descriptorsOfPlan(plan: ShellReadPlan): LineDescriptors; /** * Mark every candidate of a whole plan (the nested plans included) that names a standard device the containment question * is not asked of ({@link ReadCandidate.device}): the word is the table's, it is a word a program or a redirection opens, * and no redirection of the text rebinds the descriptor it names. Computed once, over the text as a whole: whether a * descriptor is rebound is a fact of the line, not of a segment. */ export declare function markStandardDevices(plan: ShellReadPlan): ShellReadPlan;