import { type ProcessPermissions } from './config.ts';
import type { PathSpec } from '../types.ts';
import { ProcessHandle, type ExecutionBind } from './handle.ts';
import type { ProcessInfo, ProcessRunner } from './types.ts';
import type { ProcessView } from './view.ts';
import type { IdSource } from '../utils/ids.ts';
/** Workspace-owned live runners; exited handles retain their own results. */
export declare class ProcessTable {
    private readonly bind;
    private readonly ids?;
    private readonly changed?;
    private readonly now;
    private nextPid;
    private readonly runners;
    private readonly ancestors;
    private readonly generations;
    private stopped;
    /**
     * @param bind runs each runner as part of its execution, so what it
     *   records names it; the workspace hands over the caller's
     *   `runWithExecution`. Without one a runner runs as it is.
     */
    /**
     * @param bind runs a process's body under its execution id.
     * @param ids where a process's execution id is drawn when its caller names
     *   none; omitted means the system source.
     * @param changed called once a runner is started, so whoever publishes the
     *   live runners knows to.
     * @param now the epoch seconds a process starts at, which `ps` shows;
     *   omitted means the running workspace's system time.
     */
    constructor(bind?: ExecutionBind, ids?: IdSource | undefined, changed?: (() => void) | undefined, now?: () => number);
    /** Whether a runner that was started has yet to begin. */
    queued(): boolean;
    /**
     * Host-only: the supplied runner must admit commands before effects.
     * `limit` is the most runners the session may hold, this one included;
     * stopping runners count until they finish cleanup and leave the live registry.
     * Past it this throws EAGAIN, what fork(2) answers at `ulimit -u`.
     * `started` is what the caller sets up from the process's identity before
     * its runner runs (the session's `$BASHPID`); a caller that passes it has
     * nothing left to do first, so the runner then starts at once, unless a
     * runner started before it has yet to begin: runners begin in the order
     * they were started, so a job's redirect lands before the line that
     * started it reads the file.
     */
    start(init: {
        sessionId: string;
        command: string;
        cwd: PathSpec;
        run: ProcessRunner;
        cancel: () => void;
        parentPid?: number | null;
        limit?: number | null;
        executionId?: string;
        started?: (info: ProcessInfo) => void;
    }): ProcessHandle;
    /**
     * Request cancellation of every live runner whose parent is `pid` or
     * an ancestor further up, so grandchildren are reached after an
     * intermediate runner has exited.
     *
     * @param signal what the stop stands for, as the parent's.
     */
    terminateChildren(pid: number, signal?: number): void;
    view(sessionId: string, permissions?: () => ProcessPermissions): ProcessView;
    /**
     * Revoke the session's views and cancel its runners. A closed session's
     * ID can be reused and a replaced profile grants a new view, so neither
     * may keep an entry point, or a runner admitted under the old grants.
     */
    revokeSession(sessionId: string): void;
    /** Host-only inventory, including disowned and stopping runners. */
    live(): readonly ProcessHandle[];
    /** Join managed runners before releasing their workspace resources. */
    drain(): Promise<void>;
    /** Close admission and request cancellation; stopping is not completion. */
    stop(): void;
}
//# sourceMappingURL=table.d.ts.map