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