import type { SessionBackend, SpawnOpts, SessionProbe } from './types.js';
/**
 * ZellijBackend — session backend using zellij for process persistence.
 *
 * Architecture: pty-under-zellij (the "B route"), the zellij analogue of the
 * legacy TmuxBackend (pty-under-tmux):
 *   - A node-pty process runs `zellij --session … --layout-string …` (fresh)
 *     or `zellij attach …` (reattach). The node-pty is the only zellij client.
 *   - All output flows through the pty (onData/onExit work unchanged) — we get
 *     the raw rendered byte stream for free, sidestepping zellij `subscribe`'s
 *     "whole-viewport-snapshot" model that doesn't fit botmux's xterm pipeline.
 *   - Input goes through pty.write(). We start zellij in **locked mode with
 *     keybindings cleared** (generated config), so every byte we write —
 *     including Ctrl-C, arrows, bracketed-paste markers — passes straight to
 *     the focused CLI pane with zero keybinding interception (the moral
 *     equivalent of tmux's single prefix key, but with nothing reserved).
 *   - resize() is pty.resize(): the attached client's size drives the pane, so
 *     the headless-default 25-column problem never bites (the pty is the size).
 *   - kill() only detaches (kills the pty client); the zellij server keeps the
 *     CLI running, so a daemon restart re-attaches with `zellij attach`.
 *   - destroySession() runs `zellij delete-session -f` (kill + purge the
 *     resurrectable corpse) on explicit /close.
 *
 * Naming: zellij sessions are named `bmx-<sessionId.slice(0,8)>`, same as tmux.
 */
export declare class ZellijBackend implements SessionBackend {
    private process;
    private readonly sessionName;
    private readonly ownsSession;
    private reattaching;
    private configPath;
    private tmpConfigDir;
    /** Set by kill()/destroySession() so the pty-client exit they cause (an
     *  intentional detach/teardown — the zellij session survives) is NOT
     *  reported as a CLI exit. A real CLI exit leaves this false. */
    private intentionalExit;
    /** Cached CLI pid. The CLI subprocess starts asynchronously after spawn(),
     *  so the first getChildPid() may be null; once resolved it's stable for the
     *  session lifetime (single CLI pane → pane exit ends the session). */
    private resolvedCliPid;
    /** Explicit pane target for adopt mode (e.g. "terminal_2"). When null,
     *  zellij `action` commands address the focused pane — correct for managed
     *  mode where the single CLI pane is always focused. */
    private readonly paneId;
    claudeJsonlPath?: string;
    cliPid?: number;
    cliCwd?: string;
    constructor(sessionName: string, opts?: {
        ownsSession?: boolean;
        isReattach?: boolean;
        paneId?: string;
    });
    static isAvailable(): boolean;
    static sessionName(sessionId: string): string;
    /** Names of LIVE (non-exited) zellij sessions. A killed-but-serialised
     *  session lingers in `list-sessions` as "(EXITED - attach to resurrect)";
     *  we must not treat those as reattachable, so filter them out. */
    static liveSessions(): string[];
    /** Like liveSessions(), but distinguishes "command failed/timed out" ({ok:false})
     *  from "command succeeded, zero live sessions" ({ok:true, sessions:[]}). The
     *  tri-state probe builds on this so a transient `list-sessions` failure isn't
     *  read as "session gone". */
    static probeLiveSessions(): {
        ok: true;
        sessions: string[];
    } | {
        ok: false;
    };
    static hasSession(name: string): boolean;
    static probeSession(name: string): SessionProbe;
    /** Kill + purge a session (so no resurrectable corpse accumulates). */
    static killSession(name: string): void;
    static listBotmuxSessions(): string[];
    spawn(bin: string, args: string[], opts: SpawnOpts): void;
    /** Write the per-session config (locked mode + cleared keybinds so pty.write
     *  passes through untouched, no startup tips / pane frames) and, for a fresh
     *  spawn, the single-pane layout file. Both live in one temp dir cleaned on
     *  kill(). On reattach the layout file is unused but harmless. */
    private writeRuntimeFiles;
    get isReattach(): boolean;
    write(data: string): void;
    /** Literal text, no Enter. */
    sendText(text: string): void;
    /** Special keys by tmux-style name (Enter, Escape, C-c, M-Enter, …). */
    sendSpecialKeys(...keys: string[]): void;
    /** Bracketed paste: wrap with \e[200~ … \e[201~ so TUIs (CoCo/Ink/Codex)
     *  detect the paste boundary and don't treat embedded \n as Enter. Mirrors
     *  `tmux paste-buffer -p`. */
    pasteText(text: string): void;
    resize(cols: number, rows: number): void;
    /** Must be called AFTER spawn(). */
    onData(cb: (data: string) => void): void;
    /** Must be called AFTER spawn(). */
    onExit(cb: (code: number | null, signal: string | null) => void): void;
    /** CLI pid. May be null immediately after spawn() (the CLI subprocess starts
     *  asynchronously); the worker retries. Cached once resolved. */
    getChildPid(): number | null;
    /** Detach only — kills the pty client, leaves the zellij session running. */
    kill(): void;
    /** Kill the zellij session permanently (explicit /close). */
    destroySession(): void;
    private cleanupConfig;
}
/**
 * Locked mode + cleared keybinds => the client pty forwards every byte to the
 * focused pane with no zellij interception. No startup tips / pane frames so
 * the captured stream is just the CLI (we don't need to hide chrome, but a
 * clean single pane keeps screenshots faithful and the renderer simple).
 */
export declare const ZELLIJ_CONFIG_KDL = "// botmux-generated \u2014 do not edit\nshow_startup_tips false\npane_frames false\ndefault_mode \"locked\"\nkeybinds clear-defaults=true {\n}\n";
/** Escape a string for a KDL double-quoted value. */
export declare function kdlString(s: string): string;
/**
 * Build the `--layout-string` KDL: a single full-screen pane that execs the CLI
 * through the user's shell (same wrapper TmuxBackend uses, so PATH / NVM / pnpm
 * / mise shims load from rcfiles). Command + args go in via execvp semantics —
 * no shell-quoting needed (KDL strings carry spaces/quotes), only KDL escaping.
 *
 *   pane command="<shell>" close_on_exit=true {
 *       args "<flag>"… "-c" "<script>" "_" "<cwd>" "KEY=VAL"… "<bin>" "<arg>"…
 *   }
 */
export declare function buildLayoutString(bin: string, args: string[], opts: SpawnOpts): string;
/**
 * Map a tmux-style key name to the raw bytes a terminal emits for it. Covers
 * the names botmux's adapters / worker actually send (Enter, Escape, C-<x>,
 * M-<x>, arrows, Tab, BSpace, …). Unknown names fall back to the literal string
 * so a missing mapping degrades to "typed as-is" rather than dropping input.
 */
export declare function tmuxKeyToBytes(key: string): string;
/**
 * Find the zellij `--server …/<sessionName>` process pid. The session name is
 * the trailing path component of the server's socket argument, so we match the
 * cmdline ending in `/<sessionName>`.
 */
export declare function findServerPid(sessionName: string): number | null;
/**
 * Best-effort CLI pid for the managed pane. With the SHELL_WRAPPER_SCRIPT's
 * `exec /usr/bin/env "$@"`, the CLI replaces the shell and becomes a direct
 * child of the zellij server, so the server's lone non-zellij child is the CLI.
 */
export declare function findPaneCliPid(sessionName: string, _binBasename: string): number | null;
//# sourceMappingURL=zellij-backend.d.ts.map