import type { LanguageModelV3 } from '@ai-sdk/provider';
/**
 * True when an error message indicates a recoverable session-state failure
 * from claude-cli:
 *   - "Session ID already in use" — externally-managed sessionId collided
 *     with a still-live invocation (concurrent harness runs are the typical
 *     trigger).
 *   - "Session not found" / similar — `--resume` of a non-existent session,
 *     usually when our `initialized` flag is stale (the underlying
 *     claude-cli process exited and forgot the session, but the flag still
 *     says "resume me").
 *
 * Exported for unit testing and so harness code can apply the same predicate
 * if it wants to wrap calls at a higher level.
 */
export declare function isSessionError(message: string): boolean;
/**
 * Engines 6.30.5+. Detect responses that look like meta-conversation
 * rather than actual generation: short replies where the model thinks
 * it's between calls in a session (e.g. "Ready for the next microcall.",
 * "Awaiting the next action.", "What's next?"). Surfaces under
 * concurrent dispatch when claude-cli's `--resume` feeds stale
 * conversation state to the model and the model replies to THAT instead
 * of the actual prompt.
 *
 * Heuristic: trimmed response under 250 chars AND no fenced code block
 * AND matches one of the known meta-conversation patterns. Conservative
 * — must hit BOTH the length gate AND the pattern. False positives
 * would only trigger an unnecessary fresh-session retry, not a wrong
 * answer.
 *
 * Exported for testing.
 */
export declare function isMetaConversationResponse(text: string): boolean;
export interface ClaudeCliOptions {
    /** Explicit path to the claude binary. Auto-detected if omitted. */
    claudePath?: string;
    /** Model override (e.g. "claude-opus-4", "claude-sonnet-4-5"). Defaults to whatever claude CLI picks. */
    model?: string;
    /** Timeout in milliseconds for each call. Default: 120_000. */
    timeout?: number;
    /**
     * Externally-managed session ID for cross-process session caching. When
     * provided, this UUID is used instead of a freshly-generated one — so
     * multiple processes (e.g. `spv ai analyse` invoked N times by a harness)
     * can share claude-cli's session state and the ~75% input-token reduction
     * that goes with it.
     *
     * If omitted, a fresh UUID is generated per factory call (original
     * in-process behavior).
     */
    sessionId?: string;
}
/**
 * Find the first working `claude` binary. Tries:
 *   1. Explicit path override if given
 *   2. ~/.claude/local/claude (Claude Code's user install)
 *   3. `claude` on PATH (Homebrew / manual installs)
 * Returns null if none respond to `--version`.
 */
export declare function detectClaudePath(override?: string): string | null;
/** True if any candidate claude binary responds to --version. */
export declare function isClaudeCliAvailable(override?: string): boolean;
/**
 * Factory for a claude-cli-backed LanguageModelV3. Session state is held
 * inside the closure, so each call to claudeCli() gets its own session.
 */
export declare function claudeCli(options?: ClaudeCliOptions): LanguageModelV3;
/**
 * Parse a single stream-json line from claude-cli's --output-format
 * stream-json mode. Returns the extracted text delta or null when the
 * line doesn't contain user-visible text (system messages, init blocks,
 * malformed JSON, etc.).
 *
 * Handles the three message shapes claude-cli emits:
 *   - `assistant` messages with content blocks (full content snapshot)
 *   - `content_block_delta` (token-level deltas — primary streaming path)
 *   - `stream_event` wrapper with delta.type=text_delta
 *
 * Exported for unit testing.
 */
export declare function extractTextFromStreamJsonLine(line: string): string | null;
//# sourceMappingURL=claude-cli.d.ts.map