import { IPty } from 'node-pty'; /** * State machine for persistent PTY lifecycle */ export declare enum PtyState { SPAWNING = "spawning",// PTY starting up, waiting for first prompt IDLE = "idle",// Showing prompt, ready for input PROCESSING = "processing",// Tool is generating a response ATTACHED = "attached",// User is in interactive mode DEAD = "dead" } /** * Configuration for a persistent PTY session */ export interface PtyConfig { /** Tool name (e.g., 'claude', 'gemini') */ name: string; /** Command to run (e.g., 'claude', 'gemini') */ command: string; /** Arguments for the command */ args: string[]; /** Regex pattern to detect when tool is ready for input */ promptPattern: RegExp; /** Fallback timeout in ms - if no output for this long, assume response complete */ idleTimeout: number; /** Function to clean response output (remove UI noise) */ cleanResponse: (raw: string) => string; /** ANSI color for this tool */ color: string; /** Display name for this tool */ displayName: string; } /** * Callback types for PTY events */ export interface PtyCallbacks { /** Called when PTY process exits */ onExit?: (exitCode: number) => void; /** Called when state changes */ onStateChange?: (state: PtyState) => void; } /** * Manages a persistent PTY session for a single tool. * * The PTY runs continuously in the background: * - Regular messages: Write to stdin, capture response via prompt detection * - Interactive mode: Attach (forward stdin/stdout), detach (keep running) */ export declare class PersistentPtyManager { private config; private pty; private state; private outputBuffer; private currentCapture; private callbacks; private cwd; private headlessTerminal; private serializeAddon; private isAttached; private attachedOutputHandler; private isReady; private readyPromise; private readyResolve; private suppressExitMessage; private lastSavedBufferLength; constructor(config: PtyConfig); /** * Initialize the headless terminal for screen state tracking. * This is used to properly capture output when tools use cursor positioning * to redraw content (like Gemini's streaming). */ private initHeadlessTerminal; /** * Get current state */ getState(): PtyState; /** * Check if PTY is dead and needs respawn */ isDead(): boolean; /** * Check if PTY is processing a response */ isProcessing(): boolean; /** * Check if user is currently attached */ isUserAttached(): boolean; /** * Get the output buffer (for reattach screen restore) * Uses the headless terminal to get the actual visible screen content. */ getOutputBuffer(): string; /** * Clear the output buffer (used after sending a prompt to avoid capturing the typed input) */ clearOutputBuffer(): void; /** * Get only the NEW output since the last time we saved to history. * This prevents forwarding the entire session when detaching. */ getNewOutputSinceLastSave(): string; /** * Mark the current buffer position as saved. * Call this after saving content to conversation history. */ markBufferAsSaved(): void; /** * Set callbacks */ setCallbacks(callbacks: PtyCallbacks): void; /** * Spawn the PTY process * @param cwd Working directory * @param waitForReady If false, returns immediately after spawning (for interactive mode) */ spawn(cwd: string, waitForReady?: boolean): Promise; /** * Handle incoming data from PTY */ private handleData; /** * Reset the idle timeout (called on each output chunk) */ private resetIdleTimeout; /** * Complete the current response capture */ private completeCapture; /** * Handle PTY exit */ private handleExit; /** * Set state and notify callback */ private setState; /** * Send a message and capture the response. * Waits for prompt detection or idle timeout to know when complete. */ sendAndCapture(message: string, timeout?: number): Promise; /** * Write directly to PTY (for interactive mode) */ write(data: string): void; /** * Attach to PTY - forward output to stdout, allow stdin forwarding */ attach(): void; /** * Detach from PTY - stop forwarding, PTY keeps running */ detach(): void; /** * Kill the PTY process * @param silent If true, suppress the onExit callback (for intentional kills) */ kill(silent?: boolean): void; /** * Get the underlying PTY for advanced operations */ getPty(): IPty | null; } //# sourceMappingURL=persistent-pty.d.ts.map