/** * PTY Terminal Buffer Module * * Provides a virtual terminal buffer using @xterm/headless for parsing ANSI sequences * and maintaining output history with memory bounds. * * @module pty-terminal-buffer */ /** * Terminal buffer manager using @xterm/headless. * * This class wraps @xterm/headless to provide: * - ANSI sequence parsing for accurate text extraction * - Parsed terminal content retrieval * - Raw output history for replay * - Memory-bounded storage * * @example * ```typescript * const buffer = new PtyTerminalBuffer(120, 40); * * // Write data (including ANSI sequences) * buffer.write('\x1b[32mHello, World!\x1b[0m\r\n'); * * // Get parsed content * const content = buffer.getContent(50); * console.log(content); // "Hello, World!" * * // Get raw history for replay * const history = buffer.getHistoryAsString(); * ``` */ export declare class PtyTerminalBuffer { /** * Handles both ESM named export and CJS default export interop in tests/runtime. */ private static readonly TerminalCtor; /** * The @xterm/headless Terminal instance */ private terminal; /** * Raw output history as buffer chunks */ private outputHistory; /** * Current total size of output history in bytes */ private currentHistorySize; /** * Maximum history size in bytes */ private readonly maxHistorySize; /** * Whether the buffer has been disposed */ private disposed; /** * Latest OSC 0/2 window title the program set ('' until one is set). * Codex uses it to signal "Action Required"; see services/monitoring/agent-attention. */ private title; /** * Create a new terminal buffer. * * @param cols - Number of columns (width). Defaults to 80. * @param rows - Number of rows (height). Defaults to 24. * @param maxHistorySize - Maximum history size in bytes. Defaults to 10MB. * * @example * ```typescript * // Default size terminal * const buffer1 = new PtyTerminalBuffer(); * * // Custom size with custom history limit * const buffer2 = new PtyTerminalBuffer(120, 40, 5 * 1024 * 1024); * ``` */ constructor(cols?: number, rows?: number, maxHistorySize?: number); /** * Get the latest window title the program set with OSC 0 or OSC 2. * * @returns The title, or '' if none has been set * * @example * ```typescript * buffer.write('\x1b]0;[ ! ] Action Required | repo\x07'); * await buffer.flush(); * buffer.getTitle(); // '[ ! ] Action Required | repo' * ``` */ getTitle(): string; /** * Write data to the terminal buffer. * * The data is written to both the xterm terminal (for parsing) and * the raw history buffer (for replay). * * @param data - String data to write (may include ANSI sequences) * @throws Error if buffer has been disposed * * @example * ```typescript * buffer.write('\x1b[32mGreen text\x1b[0m\r\n'); * buffer.write('Plain text\r\n'); * ``` */ write(data: string): void; /** * Get parsed terminal content. * * This extracts the visible text from the terminal buffer, with ANSI * sequences parsed and removed. The result is the actual displayed text. * * @param maxLines - Maximum number of lines to retrieve. Defaults to 100. * @returns Parsed terminal content as a string * * @example * ```typescript * const content = buffer.getContent(50); * console.log('Last 50 lines:', content); * ``` */ getContent(maxLines?: number): string; /** * Get recent terminal content with faint (dim) cells blanked out. * * Runtimes paint "ghost" text in faint style: Claude Code's prompt * suggestion (a predicted next user message, accepted by Tab), Codex's * rotating composer placeholder, Gemini's "Type your message" hint. In * plain text that ghost text is indistinguishable from typed input, which * is how a predicted "owner" message once got submitted (2026-10-03). * This view keeps only what is really there, so the input guard can read * the true contents of an input box. * * A fake cursor (an inverse cell) sitting on the first character of ghost * text is blanked too. * * @param maxLines - Maximum number of lines to return (default: 100) * @returns Terminal content without faint text */ getContentWithoutFaint(maxLines?: number): string; /** * The visible screen with faint text blanked, plus where the terminal * cursor is — what the input guard reads. The cursor tells where a * runtime's composer ends (Codex keeps it at the end of the typed text). * * @returns Screen rows (faint blanked) and the cursor's row in them */ getInputView(): { lines: string[]; cursorRow: number; }; /** * One buffer line with faint cells (and a fake inverse cursor over faint * text) replaced by spaces, trailing whitespace trimmed. * * @param index - Buffer line index * @returns The line */ private solidLine; /** * Get all available terminal content. * * @returns All parsed terminal content */ getAllContent(): string; /** * Get the current cursor position. * * @returns Object with x (column) and y (row) cursor position */ getCursorPosition(): { x: number; y: number; }; /** * Resize the terminal buffer. * * @param cols - New number of columns * @param rows - New number of rows * @throws Error if buffer has been disposed * * @example * ```typescript * buffer.resize(120, 40); * ``` */ resize(cols: number, rows: number): void; /** * Get current terminal dimensions. * * @returns Object with cols and rows */ getDimensions(): { cols: number; rows: number; }; /** * Get raw output history as buffer chunks. * * This returns the raw bytes written to the buffer, including ANSI * sequences. Useful for replaying the session. * * @returns Array of Buffer chunks representing raw output * * @example * ```typescript * const chunks = buffer.getHistory(); * const totalSize = chunks.reduce((sum, b) => sum + b.length, 0); * ``` */ getHistory(): Buffer[]; /** * Get raw output history as a single string. * * This concatenates all history chunks and returns them as a string. * The result includes ANSI sequences and can be used for replay. * * @returns Complete raw output history as a string * * @example * ```typescript * const history = buffer.getHistoryAsString(); * // Can be written to another terminal for replay * otherTerminal.write(history); * ``` */ getHistoryAsString(): string; /** * Flush pending writes to the headless terminal. * @xterm/headless processes write() asynchronously. This ensures * all queued data has been processed before reading terminal state. * * @returns Promise that resolves when all pending writes are processed */ flush(): Promise; /** * Serialize the current terminal visual state as plain text. * * Unlike getHistoryAsString() which returns the raw byte stream (including * cursor movement sequences that cause corruption at different dimensions), * this returns the rendered visual state — the final text as displayed after * all cursor movements and erases have been processed by the headless terminal. * * Must be called after flush() to ensure all pending writes are processed. * Colors are not preserved in the serialized output, but live streaming * output will have full color support. * * @returns Terminal visual state as plain text safe for replay at any dimensions */ serialize(): string; /** * Flush pending writes and return the serialized terminal visual state. * Convenience method combining flush() + serialize(). * * @returns Promise resolving to terminal visual state as plain text */ serializeAsync(): Promise; /** * Get the current history size in bytes. * * @returns Current history size in bytes */ getHistorySize(): number; /** * Get the maximum history size in bytes. * * @returns Maximum history size in bytes */ getMaxHistorySize(): number; /** * Clear the terminal buffer and history. * * This resets the terminal to its initial state and clears all history. * * @example * ```typescript * buffer.clear(); * ``` */ clear(): void; /** * Dispose the terminal buffer and release resources. * * After disposal, the buffer cannot be used anymore. */ dispose(): void; /** * Check if the buffer has been disposed. * * @returns true if disposed */ isDisposed(): boolean; /** * Append data to the raw history buffer. * * This maintains the memory bound by trimming old data when necessary. * * @param data - String data to append */ private appendHistory; /** * Search for a pattern in the terminal content. * * @param pattern - String or RegExp pattern to search for * @returns true if pattern is found * * @example * ```typescript * if (buffer.contains('error')) { * console.log('Error found in output'); * } * ``` */ contains(pattern: string | RegExp): boolean; /** * Get lines matching a pattern. * * @param pattern - String or RegExp pattern to match * @returns Array of matching lines * * @example * ```typescript * const errors = buffer.findLines(/error/i); * ``` */ findLines(pattern: string | RegExp): string[]; } //# sourceMappingURL=pty-terminal-buffer.d.ts.map