@struktoai/mirage-core
Version:
A Unified Virtual Filesystem For AI Agents
123 lines • 8.02 kB
TypeScript
import type { RedirectResult } from '../../context/session_context.ts';
import { type SharedInput } from '../../io/async_line_iterator.ts';
import type { ByteSource } from '../../io/types.ts';
import { IOResult } from '../../io/types.ts';
import { type Decisions } from '../../policy/decisions.ts';
import type { HandOff } from '../../policy/types.ts';
import { CallStack } from '../../shell/call_stack.ts';
import { Channel, JobConsole } from '../../shell/console/index.ts';
import { type JobTable } from '../../shell/job_table/index.ts';
import type { TSNodeLike } from '../../shell/types.ts';
import type { SessionView } from '../../view/types.ts';
import { type EvaluationContext } from '../evaluation.ts';
import type { SessionState } from '../session/session.ts';
import { ExecutionNode } from '../types.ts';
import type { ExecuteNodeFn } from './command/types.ts';
/**
* Send a command's output to a console as chunks arrive.
*
* Consuming the stream piece by piece rather than materializing it whole
* is what lets a reader watch a running job. A command that computes its
* output eagerly still lands in one chunk, because there was nothing to
* observe before it finished. A pipe is drained before the next chunk is
* pulled, so a reader that closed stops the source before it fetches more.
*/
export declare function pump(console_: JobConsole, channel: Channel, stream: ByteSource | null): Promise<void>;
/**
* Write a finished statement's returned output to a sink, its stdout before
* its stderr, since one command keeps no order between them; what it already
* wrote there as it ran (a function body, a redirected group) came first. A
* read its stream fails is the statement's own failure (`failedRead`). The
* result carries no output, so nothing lands twice. Mirrors Python's drained.
*/
export declare function drained(sink: JobConsole, stdout: ByteSource | null, io: IOResult, execNode: ExecutionNode): Promise<[null, IOResult, ExecutionNode]>;
export declare function handleBackground(executeNode: ExecuteNodeFn, left: TSNodeLike, right: TSNodeLike | null, context: EvaluationContext, jobTable: JobTable, stdin?: ByteSource | null, callStack?: CallStack | null, handed?: HandOff | null, decisions?: Decisions | null): Promise<RedirectResult>;
/**
* Run one statement of a compound body, as a job when it ends in `&`.
*
* The program loop and the subshell body read the `&` off the token
* stream themselves; a loop body, an if/case arm, a brace group or a
* function body holds named nodes only, so the statement is asked about
* its own terminator. The launch is a statement in its own right and
* answers with status 0, as in bash, so `false &` inside a body trips
* neither `$?` nor `set -e`. A null `jobTable` means the caller wired no
* job plane, which is a programming error once a `&` shows up, not a
* reason to run it inline. `bound` is `fd0Binding` as the body started,
* so an `exec <` in it replaces `stdin` for the statements after it; a
* job still gets the body's own stdin.
*/
export declare function runStatement(executeNode: ExecuteNodeFn, node: TSNodeLike, context: EvaluationContext, stdin: ByteSource | null, bound: readonly [SharedInput | null, boolean], callStack: CallStack | null, jobTable: JobTable | null, handed?: HandOff | null, decisions?: Decisions | null): Promise<RedirectResult>;
/**
* Wait for background jobs, with bash's option surface. A job's output
* went where its shell writes as it was written, so `wait` prints none,
* as bash's does. Bare `wait` joins every job; `wait ID...` joins those
* and answers the last one's status; `-n` joins the first of the given jobs
* (or of all) to finish, 127 when there is nothing to wait for; `-p VAR`
* stores the id of the job whose status is answered, unsetting VAR when
* none is (which is the bare form, since it reports no one job); `-f` is
* accepted, since a mirage job cannot stop, only end.
*
* `-p` stores the managed PID, matching `$!` and `jobs -p`.
*/
export declare function handleWait(jobTable: JobTable, parts: string[], session?: SessionState | null, view?: SessionView | null, signal?: AbortSignal): Promise<RedirectResult>;
/**
* Drop jobs from the table without stopping them. No operand means the
* current job (the newest), `-a` every job, `-r` the running ones, and
* `%N`/`N` specs name jobs; `-h` marks a job to survive SIGHUP and leaves
* it in the table, a no-op here since no hangup is ever delivered. A spec
* naming no job is `no such job`, exit 1, and the others still drop.
*/
export declare function handleDisown(jobTable: JobTable, parts: string[], session?: SessionState | null, _view?: SessionView | null): Promise<RedirectResult>;
/**
* Foreground a background job: print its command line, then block on it
* and answer its exit code. Its output goes where it always went, as it
* is written, so the command line goes out first: to `sink`, where the
* statement writes, before the job's next bytes. With no operand it takes
* the newest running job, which is bash's current job; when none runs, it
* takes the newest finished one, as `fg %N` would.
*/
export declare function handleFg(jobTable: JobTable, parts: string[], session?: SessionState | null, _view?: SessionView | null, signal?: AbortSignal, sink?: JobConsole): Promise<RedirectResult>;
/**
* Signal managed runners with bash's kill surface. The signal comes from
* `-s`/`-n`, or from the first `-sigspec`; `0` probes and every other
* signal cancels the runner with it. Every operand is tried and each failure is
* named in bash's words; the status is 0 when any operand was signalled,
* as bash's is. A job spec is `%N`; a negative number is a process group,
* which no managed runner leads. `owner:pid` names another workspace's
* runner, as `ps` lists it: its owner stops it once it takes the stop.
*/
export declare function handleKill(jobTable: JobTable, parts: string[], session?: SessionState | null, _view?: SessionView | null): Promise<RedirectResult>;
/**
* List jobs, with bash's flags applied to mirage's row shape.
*
* `-p` prints the managed PID; `-s` lists nothing because suspended
* processes are unsupported. `-r` keeps running jobs, `-l` adds the PID, and
* `-n` lists only the jobs whose status changed since the last `jobs`
* (which is every completed one not yet reaped, since reaping is what a
* listing does). A jobspec operand (`%2` or `2`) filters to that job;
* one that names no job is `no such job`, exit 1. `-x` is not carried,
* and an unknown letter is GNU's usage line, exit 2.
*/
export declare function handleJobs(jobTable: JobTable, parts: string[], session?: SessionState | null, _view?: SessionView | null): Promise<RedirectResult>;
/**
* The shortest start of each owner's id, six characters at least, that no
* other owner's begins with, as `ps` names their processes.
*/
export declare function ownerTags(owners: readonly string[]): Map<string, string>;
/**
* List managed runners with procps's selection and `-o` columns. A runner
* has no CPU, RSS or TTY accounting, so without `-o` the rows stay mirage's
* compact `PID<TAB>COMMAND` and never broaden the profile's view. `-o` lays
* out procps-ng 4.0.4's columns, every key a runner can answer (PS_COLUMNS);
* a header row prints unless every header is empty. Selecting nothing (`-p`
* of an absent PID) exits 1, as procps does, and an option error is
* procps's message and usage.
*
* The runners other workspaces on a shared store run follow this
* workspace's, as `owner:pid` with the owner's id shortened as far as it
* stays unique, within the same view. In the compact rows each runner is followed by the native runs
* it has going, a host program by its host PID and a sandbox's by its
* runtime and tag, each as `-<TAB>└ where: command`.
*/
export declare function handlePs(jobTable: JobTable, parts: string[], session?: SessionState | null, _view?: SessionView | null): Promise<RedirectResult>;
//# sourceMappingURL=jobs.d.ts.map