/**
 * @fileoverview Interactive output masking utilities for CLI tools.
 * Provides output control with keyboard toggling (ctrl+o).
 *
 * ANSI Escape Sequences Used:
 * - '\r': Carriage return - moves cursor to beginning of current line.
 * - '\x1b[K' or '\x1b[0K': CSI K (erase line) - clear from cursor to end of line.
 * - '\x1b[2K': CSI 2K - erase entire line.
 * - '\x1b[1A': CSI A - move cursor up 1 line.
 *
 * Terminal Control:
 * - Raw mode (setRawMode(true)): Captures keypresses immediately without buffering.
 * - TTY detection: Ensures terminal manipulation only occurs in interactive terminals.
 *
 * Key Features:
 * - Output buffering: Stores up to 1000 lines when masked to prevent memory issues.
 * - Graceful cleanup: Always restores terminal to normal mode on exit/error.
 * - Visual feedback: Uses spinner to indicate process is running when output is masked.
 */
import type { ChildProcess, SpawnOptions } from 'child_process';
import readline from 'readline';
export interface OutputMaskOptions {
    /**
     * Current working directory for spawned process.
     * @default process.cwd()
     */
    cwd?: string | undefined;
    /**
     * Environment variables for spawned process.
     * @default process.env
     */
    env?: NodeJS.ProcessEnv | undefined;
    /**
     * Filter output before displaying or buffering.
     * Return `false` to skip the line, `true` to include it.
     *
     * Useful for filtering non-fatal warnings or noise from test runners.
     * The filter runs on every chunk of output before display/buffering.
     *
     * @param text - The output text chunk (may include ANSI codes)
     * @param stream - Whether this came from 'stdout' or 'stderr'
     * @returns `true` to include this output, `false` to skip it
     *
     * @example
     * ```ts
     * filterOutput: (text, stream) => {
     *   // Skip vitest worker termination errors
     *   if (text.includes('Terminating worker thread')) return false
     *   return true
     * }
     * ```
     */
    filterOutput?: ((text: string, stream: 'stdout' | 'stderr') => boolean) | undefined;
    /**
     * Progress message to display in spinner.
     * @default 'Running…'
     */
    message?: string | undefined;
    /**
     * Override the exit code based on captured output.
     *
     * Useful for handling non-fatal errors that shouldn't fail the build.
     * Called after the process exits with the original code and all captured output.
     * Return a number to override the exit code, or `undefined` to keep original.
     *
     * @param code - Original exit code from the process
     * @param stdout - All captured stdout (even filtered lines are captured)
     * @param stderr - All captured stderr (even filtered lines are captured)
     * @returns New exit code, or `undefined` to keep original
     *
     * @example
     * ```ts
     * overrideExitCode: (code, stdout, stderr) => {
     *   // If only worker termination errors, treat as success
     *   const output = stdout + stderr
     *   const hasWorkerError = output.includes('Terminating worker thread')
     *   const hasRealFailure = output.includes('FAIL')
     *   if (code !== 0 && hasWorkerError && !hasRealFailure) {
     *     return 0 // Override to success
     *   }
     *   return undefined // Keep original
     * }
     * ```
     */
    overrideExitCode?: ((code: number, stdout: string, stderr: string) => number | undefined) | undefined;
    /**
     * Start with output visible instead of masked.
     * When `true`, output shows immediately without needing ctrl+o.
     * @default false
     */
    showOutput?: boolean | undefined;
    /**
     * Text to show after "ctrl+o" in spinner message.
     * @default 'to see full output'
     */
    toggleText?: string | undefined;
}
export interface OutputMask {
    /** Whether spinner is currently active */
    isSpinning: boolean;
    /** Buffered output lines */
    outputBuffer: string[];
    /** All stderr captured (for exit code override) */
    stderrCapture: string;
    /** All stdout captured (for exit code override) */
    stdoutCapture: string;
    /** Whether output is currently visible */
    verbose: boolean;
}
/**
 * Create an output mask for controlling command output visibility.
 * The mask tracks whether output should be shown or hidden (buffered).
 * When hidden, output is buffered and a spinner is shown instead.
 */
export declare function createOutputMask(options?: OutputMaskOptions): OutputMask;
/**
 * Create a keyboard handler for toggling output visibility.
 * Handles two key combinations:
 * - ctrl+o: Toggle between showing and hiding output.
 * - ctrl+c: Cancel the running process.
 * The handler manipulates terminal state using ANSI escape sequences.
 */
export declare function createKeyboardHandler(mask: OutputMask, child: ChildProcess, options?: OutputMaskOptions): (_str: string, key: readline.Key) => void;
/**
 * Attach output masking to a child process.
 * Returns a promise that resolves with the exit code.
 * This function:
 * - Sets up keyboard input handling in raw mode for immediate key capture.
 * - Buffers stdout/stderr when not in verbose mode.
 * - Shows a spinner when output is masked.
 * - Allows toggling between masked and unmasked output with ctrl+o.
 */
export declare function attachOutputMask(child: ChildProcess, options?: OutputMaskOptions): Promise<number>;
/**
 * Run a command with interactive output masking.
 * Convenience wrapper around spawn + attachOutputMask.
 * Spawns a child process and attaches the output masking system to it.
 * stdin is inherited, stdout and stderr are piped for masking control.
 */
export declare function runWithMask(command: string, args?: string[], options?: OutputMaskOptions & SpawnOptions): Promise<number>;
