/**
 * tmux session and pane management utilities.
 *
 * Provides low-level tmux operations for the workflow runtime:
 * creating sessions, splitting panes, spawning commands, capturing output,
 * sending keystrokes, and pane state detection.
 */
import type { Subprocess } from "bun";
/** Dedicated tmux socket name — isolates Atomic sessions from the user's default server. */
export declare const SOCKET_NAME = "atomic";
/** Discriminated result from a tmux command execution. */
export type TmuxResult = {
    ok: true;
    stdout: string;
} | {
    ok: false;
    stderr: string;
};
/**
 * Resolve the terminal multiplexer binary for the current platform.
 *
 * On Windows, tries psmux → pmux. Do not accept arbitrary `tmux.exe` because
 * that can be a non-native shim and would prevent the psmux installer from
 * running.
 * On Unix/macOS, uses tmux directly.
 *
 * Returns the binary name (not the full path) or null if none is found.
 * The result is cached after the first call.
 */
export declare function getMuxBinary(): string | null;
/**
 * Reset the cached multiplexer binary resolution.
 * Call after installing tmux/psmux to force re-detection.
 */
export declare function resetMuxBinaryCache(): void;
/**
 * Check if tmux is installed and available.
 */
export declare function isTmuxInstalled(): boolean;
/**
 * Check if we're currently inside a tmux session.
 */
export declare function isInsideTmux(): boolean;
/**
 * Check if we're inside the atomic tmux socket specifically.
 *
 * The `TMUX` env var has the format `<socket_path>,<pid>,<index>`.
 * On Unix this looks like `/tmp/tmux-1000/atomic,12345,0` when the
 * socket name is "atomic".
 */
export declare function isInsideAtomicSocket(): boolean;
/**
 * Run a tmux command and return a result object.
 * Prefers this over the throwing `tmux()` for cases where callers
 * need to handle failure gracefully.
 */
export declare function tmuxRun(args: string[]): TmuxResult;
/**
 * Create a new tmux session with the given name.
 * The session starts detached with an initial command in the first pane.
 *
 * @param sessionName - Unique session name
 * @param initialCommand - Shell command to run in the initial pane
 * @param windowName - Optional name for the initial window
 * @param cwd - Optional working directory for the initial pane
 * @param envVars - Optional environment variables for the initial pane
 * @returns The pane ID of the initial pane (e.g., "%0")
 */
export declare function createSession(sessionName: string, initialCommand: string, windowName?: string, cwd?: string, envVars?: Record<string, string>): string;
export declare function buildKillSessionOnPaneExitHooks(sessionName: string, paneId: string, options?: {
    guardPaneExited?: boolean;
}): Array<{
    event: string;
    command: string;
}>;
/**
 * Install hooks that kill the entire session when the agent pane goes away.
 * Used by chat sessions so the session is torn down when the agent CLI exits
 * — whether via `/exit`, a deliberate double Ctrl+C, a crash, or a direct
 * pane close — without leaving the footer pane keeping the session alive.
 *
 * tmux fires `pane-exited` when a pane process exits; psmux also supports
 * that event, but does not currently populate tmux's `#{hook_pane}` format,
 * so the psmux hook is session-scoped. A direct pane close/kill fires
 * `after-kill-pane` instead. These session-scoped hooks are safe for chat
 * sessions: they only have the agent pane plus its footer, and closing either
 * should close the entire chat window.
 */
export declare function killSessionOnPaneExit(sessionName: string, paneId: string): void;
/**
 * Create a new window in an existing session without switching focus.
 *
 * @param sessionName - Target session name
 * @param windowName - Name for the new window
 * @param command - Shell command to run in the new window
 * @param cwd - Optional working directory for the new window
 * @param envVars - Optional environment variables for the new window
 * @returns The pane ID of the new window's pane
 */
export declare function createWindow(sessionName: string, windowName: string, command: string, cwd?: string, envVars?: Record<string, string>): string;
/**
 * Create a new pane in an existing session by splitting.
 *
 * @returns The pane ID of the new pane
 */
export declare function createPane(sessionName: string, command: string): string;
/**
 * Replace the running command in an existing pane with a new one.
 *
 * `-k` kills whatever is currently running in the pane (e.g. a still-initializing
 * shell) before tmux spawns the new command. Because tmux execs the command
 * itself rather than forwarding keystrokes through a shell line editor, there
 * is no shell-ready race and no ZLE TCSAFLUSH drop — callers can invoke this
 * immediately after pane creation without waiting for a prompt to appear.
 */
export declare function respawnPane(paneId: string, command: string): void;
/**
 * Send literal text to a tmux pane using `-l` flag (no special key interpretation).
 * Uses `--` to prevent text starting with `-` from being parsed as flags.
 *
 * For large text payloads, prefer {@link sendViaPasteBuffer} which bypasses
 * tmux's ~16 KB internal message buffer limit.
 */
export declare function sendLiteralText(paneId: string, text: string): void;
/**
 * Send text to a tmux pane via the paste buffer.
 *
 * More reliable than `send-keys -l` for large text:
 * - No OS ARG_MAX / MAX_ARG_STRLEN limits (text goes through a temp file)
 * - Atomic delivery — the entire text is pasted at once
 * - No chunking needed
 *
 * Newlines are normalized to spaces to prevent premature submission,
 * matching `sendLiteralText`'s behavior.
 */
export declare function sendViaPasteBuffer(paneId: string, text: string): void;
/**
 * Send a special key (C-m, C-c, C-u, Tab, etc.) to a tmux pane.
 */
export declare function sendSpecialKey(paneId: string, key: string): void;
/**
 * Capture the visible content of a tmux pane.
 *
 * @param paneId - The pane ID (e.g., "%0")
 * @param start - Start line (negative = from bottom, default: capture visible only)
 */
export declare function capturePane(paneId: string, start?: number): string;
/**
 * Capture only the visible portion of a pane (no scrollback).
 * Preferred for state detection (ready/busy) to avoid stale prompt lines
 * or old activity indicators in scrollback triggering false positives.
 * Returns empty string on failure instead of throwing.
 */
export declare function capturePaneVisible(paneId: string): string;
/**
 * Capture last N lines of scrollback from a pane.
 * Preferred for output collection where you need recent history.
 * Returns empty string on failure instead of throwing.
 */
export declare function capturePaneScrollback(paneId: string, lines?: number): string;
/**
 * Kill a tmux session.
 */
export declare function killSession(sessionName: string): void;
/** Kill a specific tmux window within a session. Silences errors if already dead. */
export declare function killWindow(sessionName: string, windowName: string): void;
/**
 * Check if a tmux session exists.
 */
export declare function sessionExists(sessionName: string): boolean;
/**
 * Set a session-level environment variable.
 * Uses `tmux set-environment -t <session>` so the value is scoped to
 * the individual session, not the global server environment.
 */
export declare function setSessionEnv(sessionName: string, key: string, value: string): void;
export declare function parseSessionEnvValue(stdout: string, key: string): string | null;
/**
 * Get the PID of the foreground process in a tmux pane.
 * Returns null if the pane no longer exists or the query fails.
 *
 * Note: this is the pane's "current" process — typically the agent
 * itself when the pane was created with the agent as the initial command.
 * If tmux exec'd a wrapper shell that then exec'd the agent, the PID
 * will refer to the same process (exec replaces in-place).
 */
export declare function getPanePid(paneId: string): number | null;
/**
 * Read a session-level environment variable.
 * Returns `null` when the session doesn't exist or the variable isn't set.
 */
export declare function getSessionEnv(sessionName: string, key: string): string | null;
/** Session type derived from the session name prefix. */
export type SessionType = "chat" | "workflow";
/**
 * Parse a session name into its type and agent.
 *
 * Naming conventions:
 *   Chat:     atomic-chat-<agent>-<id>
 *   Workflow:  atomic-wf-<agent>-<name>-<id>
 *
 * Agent names are a known, hyphen-free set (claude, copilot, opencode)
 * so parsing is unambiguous even when the workflow name contains hyphens.
 */
export declare function parseSessionName(name: string): {
    type?: SessionType;
    agent?: string;
};
/** A single tmux session on the atomic socket. */
export interface TmuxSession {
    /** Session name (e.g. "atomic-chat-claude-a1b2c3d4") */
    name: string;
    /** Number of windows in the session */
    windows: number;
    /** ISO 8601 creation timestamp */
    created: string;
    /** Whether a client is currently attached */
    attached: boolean;
    /** Session type derived from the name prefix */
    type?: SessionType;
    /** Agent backend that owns this session (e.g. "claude", "copilot", "opencode") */
    agent?: string;
}
export declare function parseListSessionsOutput(stdout: string, getEnv?: (sessionName: string, key: string) => string | null): TmuxSession[];
/**
 * List all sessions on the atomic tmux socket.
 *
 * Uses a custom format string so output is machine-parseable regardless of
 * locale. Returns an empty array when the server isn't running or has no
 * sessions (tmux exits non-zero in both cases).
 */
export declare function listSessions(): TmuxSession[];
/**
 * Attach to an existing tmux session (takes over the current terminal).
 */
export declare function attachSession(sessionName: string): void;
/**
 * Spawn an interactive attach-session process.
 * Encapsulates binary resolution, config injection, and socket isolation.
 * Used by all async attach call sites (executor, chat).
 */
export declare function spawnMuxAttach(sessionName: string): Subprocess;
/**
 * Switch the current tmux client to a different session.
 * Use this instead of `attachSession` when already inside tmux to avoid
 * creating a nested tmux client.
 */
export declare function switchClient(sessionName: string): void;
/**
 * Get the name of the current tmux session (when running inside tmux).
 * Returns null if not inside tmux or if the query fails.
 */
export declare function getCurrentSession(): string | null;
/**
 * Attach or switch to a tmux session depending on whether we're already
 * inside tmux. Avoids nested tmux clients.
 *
 * - Outside tmux: spawns `attach-session` (blocks until session ends).
 * - Inside tmux: runs `switch-client` (returns immediately).
 */
export declare function attachOrSwitch(sessionName: string): void;
/**
 * Detach every client currently attached to the given atomic-managed
 * tmux session. The session itself stays alive — only the clients are
 * disconnected. Mirrors {@link attachSession}: attach connects a client,
 * detachClients disconnects them.
 *
 * Best-effort: returns silently when the session has no attached clients
 * or has already been torn down.
 */
export declare function detachClients(sessionName: string): void;
/**
 * Detach from the user's current tmux session and replace the client
 * with an attach to a session on the atomic socket.
 *
 * Uses `detach-client -E` so the user's terminal seamlessly transitions
 * from their tmux session to the atomic session — no nesting.
 * Their original tmux session stays alive; they can re-attach with
 * `tmux attach` after leaving the atomic session.
 *
 * Only call when {@link isInsideTmux} returns `true`.
 */
export declare function detachAndAttachAtomic(sessionName: string): void;
/**
 * Select (switch to) a window within the current tmux session.
 */
export declare function selectWindow(target: string): void;
/**
 * Move the target session's current-window pointer forward by one.
 * Equivalent to the `Ctrl+\` binding inside an attached client, but
 * usable without a client and addressable by session name.
 */
export declare function nextWindow(sessionName: string): void;
/**
 * Move the target session's current-window pointer backward by one.
 */
export declare function previousWindow(sessionName: string): void;
/**
 * Collapse all whitespace to single spaces for robust capture comparison.
 * Prevents false negatives from tmux inserting/stripping whitespace.
 */
export declare function normalizeTmuxCapture(text: string): string;
/**
 * Normalize captured text preserving line structure (for display output).
 */
export declare function normalizeTmuxLines(text: string): string;
//# sourceMappingURL=tmux.d.ts.map