export interface TmuxExecResult { stdout: string; stderr: string; status: number; } export type TmuxExec = (args: string[]) => TmuxExecResult; /** Default exec: forks real tmux via spawnSync. Tests inject a mock exec to avoid touching the real tmux server. */ export declare const defaultTmuxExec: TmuxExec; export interface NewSessionOptions { /** tmux session name, e.g. "cortex-claude-" */ name: string; /** Command argv to run inside the session, e.g. ['claude', '--session-id', '...'] */ command: string[]; /** Working directory for the spawned shell/command (tmux -c) */ cwd: string; /** Extra environment variables surfaced to the child via tmux -e (each entry becomes "-e KEY=VAL") */ env?: Record; /** Pane columns (tmux -x). Default 200. */ cols?: number; /** Pane rows (tmux -y). Default 50. */ rows?: number; } /** * Stateless tmux command wrapper. All side effects flow through the injected exec — tests inject mocks, * production uses {@link defaultTmuxExec}. No internal state means safe concurrent use. * * @see DR-0012 §3.1 (architecture) — this is the bottom-most utility used by adapter-tui. */ export declare class TmuxControl { private readonly exec; constructor(exec?: TmuxExec); /** Returns true iff `tmux has-session -t ` exits 0. */ hasSession(name: string): boolean; /** * Create a detached tmux session running the given command in the given cwd. * Throws on tmux non-zero exit (e.g. duplicate session name). * * Env + command are NOT placed on the tmux command line. tmux packs the whole new-session * invocation (argv + every `-e KEY=VAL`) into a single control-socket imsg with a ~16KB ceiling; * the agent-server's full environment (~8KB+) plus claude's long `--append-system-prompt` / * `--settings` arguments blow past it ("command too long"). Instead we stage a launcher script * that exports the env and `exec`s the command, so the tmux command line stays a few dozen bytes. * @see DR-0012 — TUI command-length fix. */ newSession(opts: NewSessionOptions): void; /** Kill a tmux session. Idempotent: missing session is not an error (matches tmux's own semantics for our use case). */ killSession(name: string): void; /** * Send one or more tmux key tokens to the session. Tokens are passed verbatim to tmux, * so callers can use 'Enter', 'Escape', 'C-u', etc. No-op when no keys supplied. */ sendKeys(name: string, ...keys: string[]): void; /** * Paste arbitrary text without exposing it in process argv. A unique 0600 tempfile feeds a named * tmux buffer; cleanup explicitly removes both artifacts on success and every failure path. * Does not submit Enter. `-p` supplies the bracketed-paste sequences required by Claude's Ink TUI. */ pasteText(name: string, text: string): void; /** Read visible pane content for TUI diagnostics and bounded authentication parsing. */ capturePane(name: string): string; /** * List all tmux session names on the server, optionally filtered by prefix. * Returns [] if no tmux server is running (status != 0) — graceful for the "agent-server startup * with no prior tmux state" case. * * @see DR-0012 §3.6 — used at agent-server startup to discover orphan TUI sessions for re-adoption. */ listSessions(prefix?: string): string[]; } /** * Write a self-deleting bash launcher that exports `env` then `exec`s `command`, returning its path. * On Linux the open file descriptor keeps the script readable after `rm "$0"`, so bash finishes * reading the remaining lines from the still-open inode (verified). The caller runs it via * `tmux new-session -- bash `; on a failed spawn the caller unlinks it instead. */ export declare function writeLauncherScript(env: Record, command: string[]): string;