/**
 * Background commands (N4) — run a command detached, bank every byte it
 * writes, monitor it while it runs.
 *
 * A reviewing agent has to run real commands — a build, a test suite, a linter
 * whose output IS the evidence for a finding — and the naive shapes both fail.
 * `bashTool` blocks the loop, hands the model a shell, and truncates its own
 * output at 100 KB. A `child_process` call with a string command is a shell
 * injection with extra steps.
 *
 * This module keeps three promises instead:
 *
 *  - **Detached.** `startBackgroundCommand` returns a `taskId` immediately; the
 *    agent keeps working and asks about the command when it wants to.
 *  - **Nothing discarded.** Both streams are written straight to files as they
 *    arrive and the COMPLETE files are banked as artifacts (N3) when the
 *    command settles. The conversation gets a bounded tail plus a read-back
 *    call. The single bound is `maxOutputBytes`, and reaching it is a state
 *    (`output-limit`) the caller can see, not a silent cut.
 *  - **Hardened by contract.** argv arrays with `shell: false`, an exact-match
 *    executable allowlist, a cwd that must resolve through symlinks inside a
 *    declared root, and a timeout that escalates SIGTERM → SIGKILL.
 *
 * Completion reaches the model the same way a delegate's does (N2.3): the
 * `running` / `finished` counters ride on every command tool result and — via
 * the checklist — on every `tasks_list`. The core generate loop is untouched.
 *
 * @module agent/backgroundCommands
 */
import type { NeuroLink } from "../neurolink.js";
import type { BackgroundCommandCounts, BackgroundCommandHandle, BackgroundCommandOptions, BackgroundCommandOutputPage, BackgroundCommandPageRequest, BackgroundCommandPolicy, BackgroundCommandStatus, MCPExecutableTool } from "../types/index.js";
/**
 * Declare what this host may execute. There is no default: until this is
 * called, every start is refused, because "run whatever the model asks" is not
 * a defensible default for a primitive that spawns processes.
 */
export declare function setBackgroundCommandPolicy(host: NeuroLink, policy: BackgroundCommandPolicy): void;
/** The policy in force for a host, or undefined when none was declared. */
export declare function getBackgroundCommandPolicy(host: NeuroLink): BackgroundCommandPolicy | undefined;
/**
 * Commands for a host's session: `running` have not settled, `finished` have.
 * Carried on every command tool result and on every `ChecklistToolResult`, so
 * the model learns a build finished without polling for it.
 */
export declare function backgroundCommandCounts(host: NeuroLink, sessionId?: string): BackgroundCommandCounts;
/**
 * Start a command in the background and get its task id immediately.
 *
 * @throws when no policy is set, argv is malformed, the executable is not
 *         allowlisted, the policy vetoes the command, or the cwd escapes the
 *         sandbox root. Every message names its own recovery step.
 */
export declare function startBackgroundCommand(host: NeuroLink, argv: string[], options: BackgroundCommandOptions): Promise<BackgroundCommandHandle>;
/**
 * Everything known about one command right now — synchronous, because the
 * job state is live and a monitor that has to be awaited is a monitor nobody
 * calls mid-loop.
 *
 * @throws when the task id is unknown to this host
 */
export declare function getBackgroundCommandStatus(host: NeuroLink, taskId: string): BackgroundCommandStatus;
/**
 * Wait for a command to settle.
 *
 * `timeoutMs` bounds the WAIT, not the command: when it elapses the current
 * (still running) status is returned rather than throwing, so a caller can
 * poll in bounded steps without ever losing the job.
 *
 * @throws when the task id is unknown to this host
 */
export declare function awaitBackgroundCommand(host: NeuroLink, taskId: string, opts?: {
    timeoutMs?: number;
}): Promise<BackgroundCommandStatus>;
/**
 * Kill a running command: SIGTERM (or the signal you name), SIGKILL five
 * seconds later if it is still there. Resolves with the settled status, so a
 * caller never has to guess whether the output was banked yet.
 *
 * Killing an already-settled command is a no-op that returns its status —
 * the outcome is not discarded.
 *
 * @throws when the task id is unknown to this host
 */
export declare function killBackgroundCommand(host: NeuroLink, taskId: string, signal?: NodeJS.Signals): Promise<BackgroundCommandStatus>;
/**
 * Kill every unsettled command this host started. Host lifecycle only
 * (`shutdown()`/`dispose()`): a disposed instance must not leave child
 * processes running with nobody left to collect them.
 *
 * @returns how many commands were signalled
 */
export declare function killAllBackgroundCommands(host: NeuroLink): Promise<number>;
/**
 * Read one character window of a command's output, straight from its log file.
 *
 * Works while the command is still running — that is the monitor case — and
 * after it settled. Character offsets, `totalSize` and `hasMore` match
 * `retrieve_context` exactly, so paging code written for one works on the
 * other.
 *
 * @throws when the task id is unknown to this host
 */
export declare function readBackgroundCommandOutput(host: NeuroLink, taskId: string, page: BackgroundCommandPageRequest): Promise<BackgroundCommandOutputPage>;
/**
 * The four model-facing command tools, bound to `host`. Register them with
 * `host.registerTool()` (see `NeuroLink.registerBackgroundCommandTools()`),
 * never on the tool registry directly: only the "user-defined" category
 * reaches the LLM's tool schema.
 */
export declare function createBackgroundCommandTools(host: NeuroLink): Record<string, MCPExecutableTool>;
