/** * Terminal string operations — regex-free replacements for terminal processing. * * Every function in this module uses only string primitives (indexOf, includes, * startsWith, charCodeAt, character iteration) — NO regex. This makes the * codebase immune to ReDoS by construction. * * @module terminal-string-ops */ import { type RuntimeType } from '../constants.js'; /** * Strip ANSI escape codes from PTY output using a single-pass state machine. * * Handles CSI sequences, OSC sequences, single-char escapes, and orphaned * CSI fragments from PTY buffer boundary splits. Cursor-forward (C) sequences * are replaced with a space to preserve word boundaries. * * O(n) time, O(n) space. No regex. * * @param content - Raw PTY output containing ANSI codes * @returns Clean text with ANSI codes removed */ export declare function stripAnsiCodes(content: string): string; /** * Strip box-drawing characters and decorative borders from both ends of a line. * * @param line - A single terminal line * @returns The line with leading/trailing box-drawing chars and whitespace removed */ export declare function stripBoxDrawing(line: string): string; /** * Strip TUI line border characters (│ ┃ ║ |) and surrounding whitespace * from both ends of a line. * * @param line - A single terminal line * @returns The line with leading/trailing border chars removed */ export declare function stripTuiLineBorders(line: string): string; /** * Check if a line matches the pattern of a TUI prompt line: optional border * chars, then > followed by content. Returns the content after > prompt or null. * * Replaces the prompt line regex. * * @param line - A single terminal line * @returns The content after > prompt, or null if not a prompt line */ export declare function matchTuiPromptLine(line: string): string | null; /** * Check if a single line looks like an agent prompt. * * Claude Code: ❯, ⏵, $ alone (or with box-drawing), or ❯❯ * Gemini CLI: > or ! or bordered │ >, or "Type your message" / "YOLO mode" * Codex CLI: › or bordered │ › * OpenCode: no prompt glyph — the input box shows the `Ask anything…` * placeholder (or `Run a command…` in shell mode) when empty * Antigravity: no usable glyph — the `? for shortcuts` idle footer * * @param line - A single non-empty terminal line (already stripped of ANSI) * @param runtimeType - The agent runtime type * @returns true if the line looks like a prompt */ export declare function isPromptLine(line: string, runtimeType?: RuntimeType): boolean; /** * Check if the agent appears to be at an input prompt by scanning terminal output. * * Scans the last 10 non-empty lines for prompt patterns, then checks for busy * indicators to distinguish idle-at-prompt from actively-processing. * * @param output - Terminal output text (already stripped of ANSI codes) * @param runtimeType - The agent runtime type * @returns true if the agent appears idle at a prompt */ export declare function isAgentAtPrompt(output: string, runtimeType?: RuntimeType): boolean; /** * Check if text contains spinner characters or the working indicator (⏺). * This is the "spinner-only" check (no keyword matching). * * Replaces TERMINAL_PATTERNS.PROCESSING regex. * * @param text - Text to check * @returns true if any spinner/working indicator character is found */ export declare function containsSpinnerOrWorkingIndicator(text: string): boolean; /** * Check if text contains processing indicators including spinner chars, * working indicator (⏺), AND status keywords. * * Replaces TERMINAL_PATTERNS.PROCESSING_WITH_TEXT regex. * * @param text - Text to check * @returns true if any processing indicator is found */ export declare function containsProcessingIndicator(text: string): boolean; /** * Check if text contains the "esc to interrupt" busy status bar. * * Replaces TERMINAL_PATTERNS.BUSY_STATUS_BAR regex. * Manually matches "esc" then whitespace then "to" then whitespace then "interrupt". * * @param text - Text to check * @returns true if the busy status bar text is found */ export declare function containsBusyStatusBar(text: string): boolean; /** * Check if text contains Claude Code's Rewind mode. * * Replaces TERMINAL_PATTERNS.REWIND_MODE regex. * Checks for "Rewind" then "Restore the code" appearing after it. * * @param text - Text to check * @returns true if Rewind mode is detected */ export declare function containsRewindMode(text: string): boolean; /** * Check if text contains Gemini CLI processing keywords. * * Replaces inline Gemini keyword regex in sendMessageWithRetry. * * @param text - Text to check * @returns true if any Gemini processing keyword is found */ export declare function containsGeminiProcessingKeywords(text: string): boolean; /** A block extracted from terminal output bounded by open/close tags. */ export interface MarkerBlock { /** The content between the open and close tags (trimmed) */ content: string; /** Start index of the open tag in the original buffer */ startIndex: number; /** End index (exclusive) of the close tag in the original buffer */ endIndex: number; } /** * Extract all marker blocks bounded by open/close tag pairs from a buffer. * * Replaces NOTIFY/SLACK_NOTIFY marker regex patterns. * * @param buf - The text buffer to search * @param openTag - Opening tag string (e.g., "[NOTIFY]") * @param closeTag - Closing tag string (e.g., "[/NOTIFY]") * @returns Array of extracted marker blocks */ export declare function extractMarkerBlocks(buf: string, openTag: string, closeTag: string): MarkerBlock[]; /** A legacy [CHAT_RESPONSE] block with optional embedded conversation ID. */ export interface ChatResponseBlock { /** Optional conversation ID from [CHAT_RESPONSE:convId] */ conversationId: string | null; /** The response content between tags */ content: string; /** Start index of the open tag in the original buffer */ startIndex: number; /** End index (exclusive) of the close tag in the original buffer */ endIndex: number; } /** * Extract all [CHAT_RESPONSE]...[/CHAT_RESPONSE] blocks from a buffer. * Handles the optional :conversationId suffix: [CHAT_RESPONSE:abc123]. * * Replaces the CHAT_RESPONSE regex pattern. * * @param buf - The text buffer to search * @returns Array of extracted chat response blocks */ export declare function extractChatResponseBlocks(buf: string): ChatResponseBlock[]; /** * Extract conversation ID from a [CHAT:convId] or [GCHAT:convId] marker in text. * * Replaces CHAT_ROUTING_CONSTANTS.CONVERSATION_ID_PATTERN regex. * * @param text - Text to search * @returns The conversation ID or null if not found */ export declare function extractConversationId(text: string): string | null; /** * Extract and remove the [CHAT:convId] or [GCHAT:convId] prefix from a message. * * Replaces the CHAT prefix regex. * * @param message - Message that may start with [CHAT:...] or [GCHAT:...] * @returns Object with the prefix length (0 if no prefix) and the content after prefix */ export declare function extractChatPrefix(message: string): { prefixLength: number; content: string; }; //# sourceMappingURL=terminal-string-ops.d.ts.map