/**
 * Provider Output Contracts — Output contracts all providers must conform to
 *
 * Design principles:
 * - Only output format is standardized; implementation is free
 * - Common across all categories (cli, ide, extension)
 * - User custom providers use the same contracts
 */
import type { ProviderSummaryMetadata } from '../shared-types.js';
import type { ChatMessageKind } from './chat-message-normalization.js';
export type ReadChatTurnStatus = 'open' | 'waiting_approval' | 'complete' | 'error';
export interface ReadChatResult {
    messages: ChatMessage[];
    status: AgentStatus;
    activeModal?: ModalInfo | null;
    /** IDE/Extension only: session info */
    id?: string;
    title?: string;
    /** Authoritative transcript turn identity when available. */
    currentTurnId?: string;
    turnStatus?: ReadChatTurnStatus;
    /** Extension only: additional metadata */
    agentType?: string;
    agentName?: string;
    extensionId?: string;
    /** Status metadata */
    isVisible?: boolean;
    isWelcomeScreen?: boolean;
    inputContent?: string;
    /** Explicit dynamic control values returned by the provider */
    controlValues?: Record<string, string | number | boolean>;
    /** Flexible always-visible metadata for compact/live surfaces. */
    summaryMetadata?: ProviderSummaryMetadata;
    /** Provider-owned transcript authority/coverage hints for daemon/dashboard sync. */
    transcriptAuthority?: 'provider' | 'daemon';
    coverage?: 'full' | 'tail' | 'current-turn';
    /** Provider-driven UI effects derived from chat state */
    effects?: ProviderEffect[];
}
import type { ChatMessage } from '../types.js';
export { flattenMessageParts, normalizeInputEnvelope, normalizeMessageParts, } from './io-contracts.js';
import type { InputEnvelope, InputPart, MessagePart } from './io-contracts.js';
export type { ChatMessage, InputEnvelope, InputPart, MessagePart };
export type AgentStatus = 'idle' | 'generating' | 'waiting_approval' | 'error' | 'panel_hidden' | 'streaming';
export interface ModalInfo {
    message: string;
    buttons: string[];
    width?: number;
    height?: number;
}
export interface ProviderEffectMessage {
    role?: 'system' | 'assistant' | 'user';
    content: string | MessagePart[];
    kind?: ChatMessageKind;
    senderName?: string;
}
export interface ProviderEffectToast {
    level?: 'info' | 'success' | 'warning';
    message: string;
}
export type ProviderNotificationPreferenceKey = 'disconnect' | 'completion' | 'approval' | 'browser';
export type ProviderNotificationChannel = 'bubble' | 'toast' | 'browser';
export interface ProviderEffectNotification {
    title?: string;
    body: string;
    level?: 'info' | 'success' | 'warning';
    channels?: ProviderNotificationChannel[];
    preferenceKey?: ProviderNotificationPreferenceKey;
    bubbleContent?: string | MessagePart[];
    bubbleKind?: ChatMessageKind;
    bubbleRole?: 'system' | 'assistant' | 'user';
    bubbleSenderName?: string;
}
export interface ProviderEffect {
    type: 'message' | 'toast' | 'notification';
    /** Stable dedup key; falls back to a content hash when omitted */
    id?: string;
    /** Default immediate. turn_completed fires only on generating/waiting -> idle transitions. */
    when?: 'immediate' | 'turn_completed';
    /** Default true. False keeps the effect UI-only. */
    persist?: boolean;
    message?: ProviderEffectMessage;
    toast?: ProviderEffectToast;
    notification?: ProviderEffectNotification;
}
/**
 * ContentBlock — ACP ContentBlock union type
 * Represents displayable content in messages, tool call results, etc.
 */
export type ContentBlock = TextBlock | ImageBlock | AudioBlock | ResourceLinkBlock | ResourceBlock;
/** Text content — ACP TextContent */
export interface TextBlock {
    type: 'text';
    text: string;
    annotations?: ContentAnnotations;
}
/** Image content — ACP ImageContent */
export interface ImageBlock {
    type: 'image';
    data: string;
    mimeType: string;
    uri?: string;
    annotations?: ContentAnnotations;
}
/** Audio content — ACP AudioContent */
export interface AudioBlock {
    type: 'audio';
    data: string;
    mimeType: string;
    annotations?: ContentAnnotations;
}
/** Resource link (file reference) — ACP ResourceLink */
export interface ResourceLinkBlock {
    type: 'resource_link';
    uri: string;
    name: string;
    title?: string;
    description?: string;
    mimeType?: string;
    size?: number;
    annotations?: ContentAnnotations;
}
/** Embedded resource (inline file) — ACP EmbeddedResource */
export interface ResourceBlock {
    type: 'resource';
    resource: TextResourceContents | BlobResourceContents;
    annotations?: ContentAnnotations;
}
export interface TextResourceContents {
    uri: string;
    text: string;
    mimeType?: string | null;
}
export interface BlobResourceContents {
    uri: string;
    blob: string;
    mimeType?: string | null;
}
export interface ContentAnnotations {
    audience?: ('user' | 'assistant')[];
    priority?: number;
}
/** Tool call info — ACP ToolCall */
export interface ToolCallInfo {
    toolCallId: string;
    title: string;
    kind?: ToolKind;
    status?: ToolCallStatus;
    rawInput?: unknown;
    rawOutput?: unknown;
    content?: ToolCallContent[];
    locations?: ToolCallLocation[];
}
export type ToolKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'think' | 'fetch' | 'switch_mode' | 'other';
export type ToolCallStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
/** Content produced by a tool call — ACP ToolCallContent */
export type ToolCallContent = {
    type: 'content';
    content: ContentBlock;
} | {
    type: 'diff';
    path: string;
    oldText?: string;
    newText: string;
} | {
    type: 'terminal';
    terminalId: string;
};
export interface ToolCallLocation {
    path: string;
    line?: number | null;
}
/** Normalize content into canonical message parts */
export declare function normalizeContent(content: string | MessagePart[] | ContentBlock[]): MessagePart[];
/** Flatten canonical/legacy content into a plain-text fallback string */
export declare function flattenContent(content: string | MessagePart[] | ContentBlock[]): string;
/** SendMessage params — canonical input envelope with legacy text/prompt compatibility */
export interface SendMessageParams {
    /** Shortcut: text-only message */
    text?: string;
    /** Rich content blocks (legacy ACP ContentBlock[]) */
    prompt?: ContentBlock[];
    /** Canonical multipart runtime input */
    input?: InputEnvelope;
}
export interface SendMessageResult {
    sent: boolean;
    error?: string;
    /** When CDP Input API is needed (Lexical editor etc) */
    needsTypeAndSend?: boolean;
    selector?: string;
}
export interface ListSessionsResult {
    sessions: SessionInfo[];
}
export interface SessionInfo {
    id: string;
    title: string;
    time?: string;
}
export interface SwitchSessionResult {
    switched: boolean;
    /** When CDP click coordinates are needed (Antigravity QuickInput etc) */
    action?: 'click';
    clickX?: number;
    clickY?: number;
    error?: string;
}
export interface FocusEditorResult {
    focused: boolean;
    error?: string;
}
export interface OpenPanelResult {
    opened: boolean;
    visible: boolean;
    focused?: boolean;
    error?: string;
}
/**
 * Method 1: Script-Click — script calls el.click() directly
 * Cursor Suitable for IDEs using div.cursor-pointer elements.
 */
export interface ResolveActionScriptClick {
    resolved: boolean;
    clicked?: string;
    available?: string[];
    error?: string;
}
/**
 * Method 2: Coordinate-Click — returns coordinates, daemon performs CDP mouse click
 * Antigravity Suitable for IDEs where el.click() does not work.
 */
export interface ResolveActionCoordinateClick {
    found: boolean;
    text?: string;
    x?: number;
    y?: number;
    w?: number;
    h?: number;
}
export type ResolveActionResult = ResolveActionScriptClick | ResolveActionCoordinateClick;
export type ProviderCategory = 'cli' | 'ide' | 'extension' | 'acp';
/**
 * Type of object exported by module.exports in provider.js.
 *
 * Each provider.js is fully independent and does not import other providers.
 * Helpers (_helpers/) can be optionally used.
 */
/**
 * Provider-configurable CDP target filter.
 * Used by DaemonCdpManager to select the correct page/tab to connect to.
 * Without this, the manager uses a hardcoded default filter.
 */
export interface CdpTargetFilter {
    /** URL must include this string (e.g. 'workbench.html') */
    urlIncludes?: string;
    /** URL must NOT include any of these strings */
    urlExcludes?: string[];
    /** Page title regex pattern for titles to EXCLUDE (e.g. 'Debug Console|Output') */
    titleExcludes?: string;
}
export type ProviderVersionCommand = string | Partial<Record<string, string>>;
export interface ProviderCompatibilityEntry {
    ideVersion: string;
    scriptDir: string;
}
export interface ProviderModule {
    /** Unique identifier (e.g. 'cline', 'cursor', 'gemini-cli') */
    type: string;
    /** Display name (e.g. 'Cline', 'Cursor') */
    name: string;
    /** Category: determines execution method */
    category: ProviderCategory;
    /** Alias list — allows users to invoke by alternate names (e.g. ['claude', 'claude-code']) */
    aliases?: string[];
    /** CDP ports [primary, secondary] (IDE category only) */
    cdpPorts?: [number, number];
    /** CDP target filter — controls which page/tab to connect to (IDE category only) */
    targetFilter?: CdpTargetFilter;
    /** CLI command (e.g. 'cursor', 'code') */
    cli?: string;
    /** Display icon */
    icon?: string;
    /** Display name (short name) */
    displayName?: string;
    /** Provider-definition version maintained in adhdev-providers */
    providerVersion?: string;
    /** Inventory/support status label maintained in adhdev-providers */
    status?: string;
    /** Inventory/support detail string maintained in adhdev-providers */
    details?: string;
    /** Install instructions (shown when command is missing) */
    install?: string;
    /** Custom version detection command (e.g. 'cursor --version', 'claude -v') */
    versionCommand?: ProviderVersionCommand;
    /** Versions tested by provider maintainer (informational) */
    testedVersions?: string[];
    /** Per-OS process names — used by launch.ts to detect/kill IDE processes */
    processNames?: {
        darwin?: string;
        win32?: string[];
        linux?: string[];
        [key: string]: string | string[] | undefined;
    };
    /**
     * IDE launch preferences.
     * Lets each provider choose how its GUI app should be started per platform.
     */
    launch?: {
        /**
         * Preferred launch method by platform.
         * - 'cli': use the IDE CLI wrapper/binary
         * - 'app': use platform app launcher (e.g. `open -a` on macOS)
         * - 'auto': let core choose a sensible default
         */
        prefer?: {
            darwin?: 'auto' | 'cli' | 'app';
            win32?: 'auto' | 'cli' | 'app';
            linux?: 'auto' | 'cli' | 'app';
            [key: string]: 'auto' | 'cli' | 'app' | undefined;
        };
        /**
         * Override how long core waits for CDP to come up after launch.
         */
        cdpStartupTimeoutMs?: number;
    };
    /** Per-OS install paths — used by detector.ts to detect IDE installation */
    paths?: {
        darwin?: string[];
        win32?: string[];
        linux?: string[];
        [key: string]: string[] | undefined;
    };
    extensionId?: string;
    extensionIdPattern?: RegExp;
    extensionIdPattern_flags?: string;
    compatibility?: ProviderCompatibilityEntry[];
    defaultScriptDir?: string;
    /**
     * Scripts that can run at the IDE main-page level (not just inside the extension webview session frame).
     * Default: ['listModes', 'setMode', 'listModels', 'setModel'].
     * Add extra scripts here if the provider supports them at the IDE level (e.g. 'setModelGui').
     * Replaces hardcoded claude-code-vscode special-case in stream-commands.ts.
     */
    ideLevelScripts?: string[];
    binary?: string;
    spawn?: {
        command: string;
        args?: string[];
        shell?: boolean;
        env?: Record<string, string>;
        /** Auto-implement spawn config — controls how this provider is invoked for autonomous script generation */
        autoImpl?: ProviderAutoImplSpawnConfig;
    };
    /** Delay before submitting typed CLI input (provider-specific TUI tuning) */
    sendDelayMs?: number;
    /** Submit key used after typing into CLI PTY (default: carriage return) */
    sendKey?: string;
    /** How the CLI adapter decides when to submit typed input */
    submitStrategy?: 'wait_for_echo' | 'immediate';
    /** Keep this provider out of the upstream auto-updated bundle */
    /** @deprecated Machine-level provider source policy now lives in config.providerSourceMode. Local overrides shadow upstream by root precedence and should not rely on provider-level disableUpstream. */
    disableUpstream?: boolean;
    approvalKeys?: Record<number, string>;
    patterns?: {
        prompt?: RegExp[];
        generating?: RegExp[];
        approval?: RegExp[];
        ready?: RegExp[];
    };
    cleanOutput?: (raw: string, lastUserInput?: string) => string;
    resume?: ProviderResumeCapability;
    /** Session ID probe config — auto-discovers provider session ID from local SQLite DB */
    sessionProbe?: ProviderSessionProbe;
    /** Allow sending another prompt while the CLI is still generating so users can intervene mid-turn. */
    allowInputDuringGeneration?: boolean;
    /** Approval button priority hints used when auto-approve must pick a positive action */
    approvalPositiveHints?: string[];
    /**
     * Regex pattern (as string) that a valid provider session ID must match.
     * If set and the ID doesn't match, it is rejected (treated as invalid).
     * Replaces hardcoded HERMES_SESSION_ID_RE / CLAUDE_SESSION_ID_RE checks.
     */
    sessionIdPattern?: string;
    /** History behavior config — controls message filtering and collapse during replay */
    historyBehavior?: ProviderHistoryBehavior;
    /**
     * Canonical history sync config — for providers that maintain native history files.
     * When set, daemon syncs from native format into ADHDev JSONL store on each tick.
     */
    canonicalHistory?: ProviderCanonicalHistoryConfig;
    /**
     * Auto-fix verification profile — provider-specific test expectations for `provider fix`.
     * If not set, provider fix runs without pre/post verification.
     */
    autoFixProfile?: ProviderAutoFixProfile;
    scripts?: ProviderScripts;
    vscodeCommands?: {
        focusPanel?: string;
        openPanel?: string;
        [key: string]: string | undefined;
    };
    inputMethod?: 'cdp-type-and-send' | 'script';
    inputSelector?: string;
    /** webview iframe match text (must be contained in body) */
    webviewMatchText?: string;
    os?: {
        [platform: string]: Partial<Pick<ProviderModule, 'scripts' | 'inputMethod' | 'inputSelector'>>;
    };
    /** Key: semver range string (e.g. '< 1.107.0', '>= 2.0.0') */
    versions?: {
        [versionRange: string]: Partial<Pick<ProviderModule, 'scripts'>> & {
            /**
             * Load scripts from a subdirectory instead of scripts.js root.
             * Path is relative to the provider directory (e.g. 'scripts/legacy').
             * The subdirectory should contain its own scripts.js or individual .js files.
             */
            __dir?: string;
        };
    };
    overrides?: Array<{
        when: {
            os?: string;
            version?: string;
        };
        scripts?: Partial<ProviderScripts>;
        /** Load scripts from a subdirectory for this OS+version combination */
        __dir?: string;
    }>;
    settings?: Record<string, ProviderSettingDef>;
    /** Dynamic controls declared by provider — rendered in chat panel bar/header */
    controls?: ProviderControlDef[];
    /** Static options used when agent does not provide configOptions */
    staticConfigOptions?: Array<{
        category: 'model' | 'mode' | 'thought_level' | 'other';
        configId: string;
        defaultValue?: string;
        options: Array<{
            value: string;
            name: string;
            description?: string;
            group?: string;
        }>;
    }>;
    /** Function to convert selected config values to spawn args (applied via process restart when config/* not supported) */
    spawnArgBuilder?: (config: Record<string, string>) => string[];
    /** ACP agent auth methods (multiple supported — in priority order) */
    auth?: AcpAuthMethod[];
    contractVersion?: number;
    capabilities?: {
        input?: {
            multipart?: boolean;
            mediaTypes?: Array<'text' | 'image' | 'audio' | 'video' | 'resource'>;
        };
        output?: {
            richContent?: boolean;
            mediaTypes?: Array<'text' | 'image' | 'audio' | 'video' | 'resource'>;
        };
        controls?: {
            typedResults?: boolean;
        };
    };
}
export interface ProviderResumeCapability {
    supported: boolean;
    stopStrategy?: 'command' | 'ctrl_c';
    stopCommand?: string;
    shutdownGraceMs?: number;
    /** Delay (ms) between Ctrl+C interrupt and stop command (default 500ms) */
    interruptGraceMs?: number;
    resumeArgs?: string[];
    resumeSessionArgs?: string[];
    newSessionArgs?: string[];
    sessionIdFormat?: 'uuid' | 'string';
    /** Skip session ID probing when launchMode is 'new' — for providers that manage their own session IDs on new sessions */
    skipProbeOnNewSession?: boolean;
    /**
     * Subcommands that carry a session ID as their next positional argument.
     * e.g. ['resume', 'fork'] for codex-cli (codex resume <id> / codex fork <id>).
     * Replaces the hardcoded readCodexResumeSessionId check in cli-manager.ts.
     */
    sessionIdFromSubcommand?: string[];
    /**
     * When --session-id is present without an explicit resume flag, treat as 'new' rather than 'resume'.
     * e.g. goose-cli passes --session-id on new sessions but requires --resume/-r to actually resume.
     * Replaces the hardcoded goose-cli check in cli-manager.ts.
     */
    sessionIdIsNewByDefault?: boolean;
}
/**
 * History behavior config — controls how history messages are processed for this provider.
 * Replaces hardcoded agentType checks in chat-history.ts.
 */
export interface ProviderHistoryBehavior {
    /** Collapse consecutive assistant turns during history replay (e.g. codex-cli shows replayed intermediate turns) */
    collapseConsecutiveAssistantTurns?: boolean;
    /** Regex patterns (as strings) to filter out from assistant messages — e.g. CLI starter prompt suggestions */
    filterAssistantPatterns?: string[];
    /** If true, session ID must match sessionIdPattern exactly — reject and return '' if it doesn't match */
    requireStrictSessionIdFormat?: boolean;
}
/**
 * Provider-owned native history script names.
 *
 * These functions live in the provider's versioned CLI script bundle, not in
 * daemon-core. They let each provider own native transcript file discovery and
 * parsing while daemon-core only validates/pages the normalized result.
 */
export interface ProviderCanonicalHistoryScriptsConfig {
    /** Reads one native session. Default: 'readNativeHistory'. */
    readSession?: string;
    /** Lists native sessions with summary metadata. Default: 'listNativeHistory'. */
    listSessions?: string;
}
/**
 * Canonical history sync config — for providers that maintain their own native history files.
 *
 * Preferred mode is provider-owned scripts via `scripts`. `format` is now an
 * opaque provider label retained for diagnostics/backward compatibility; daemon
 * live paths must not branch on provider-specific format values.
 */
export interface ProviderCanonicalHistoryConfig {
    /** Opaque provider-owned history format label. */
    format?: string;
    /** Optional native history glob/template for diagnostics only. */
    watchPath?: string;
    /** Provider-owned script entry points for native transcript list/read. */
    scripts?: ProviderCanonicalHistoryScriptsConfig;
    /**
     * How ADHDev should use native history.
     * - 'native-source': provider-native files are canonical; ADHDev reads them directly and keeps only in-memory/thin projections.
     * - 'materialized-mirror': transitional compatibility mode; native files are rewritten into ~/.adhdev/history before read/list.
     * - 'disabled': ignore native history and use ADHDev mirror only.
     *
     * Omitted mode defaults to 'native-source'.
     */
    mode?: 'native-source' | 'materialized-mirror' | 'disabled';
}
/**
 * Auto-implement spawn config — controls how the provider is spawned for autonomous AI-driven
 * provider script implementation (dev-auto-implement.ts).
 * Replaces hardcoded per-command branching.
 */
export interface ProviderAutoImplSpawnConfig {
    /**
     * How the meta-prompt is passed to the agent.
     * - 'flag': passed via a CLI flag (e.g. `claude -p "..."`)
     * - 'stdin': piped via stdin (generic fallback)
     * - 'subcommand': prepended as a subcommand (e.g. `codex exec "..."`)
     */
    promptMode: 'flag' | 'stdin' | 'subcommand';
    /** CLI flag used to pass the prompt (promptMode: 'flag') — e.g. '-p' */
    promptFlag?: string;
    /** Subcommand prepended before the prompt (promptMode: 'subcommand') — e.g. 'exec' */
    subcommand?: string;
    /** Extra args appended in auto-impl mode — e.g. ['--dangerously-skip-permissions'] */
    extraArgs?: string[];
    /** Custom meta-prompt template; use {{promptFile}} placeholder. If omitted, generic prompt is used. */
    metaPrompt?: string;
    /**
     * If true, schedule an auto-stop timer when the agent output goes quiet during verification.
     * Replaces the hardcoded `command !== 'codex'` check in dev-auto-implement.ts.
     */
    autoStopOnQuiet?: boolean;
}
/**
 * Auto-fix verification profile — provider-specific test expectations for `provider fix`.
 * Replaces the hardcoded CLI_AUTO_FIX_VERIFICATION_PROFILES record in provider-commands.ts.
 */
export interface ProviderAutoFixProfile {
    fixtureName: string;
    description: string;
    inspectFields?: string[];
    focusAreas?: string[];
    lastAssistantMustContainAny?: string[];
    lastAssistantMustNotContainAny?: string[];
    timeoutMs?: number;
}
/**
 * Declarative session ID probe config for CLI providers.
 * Instead of hardcoded probe functions, providers declare their SQLite schema.
 *
 * Example (OpenCode):
 * ```
 * sessionProbe: {
 *   dbPath: '~/.local/share/opencode/opencode.db',
 *   query: 'SELECT id FROM session WHERE directory IN ({dirs}) AND time_created >= ? AND time_archived IS NULL ORDER BY time_updated DESC LIMIT 1',
 *   timestampFormat: 'unix_ms',
 * }
 * ```
 */
export interface ProviderSessionProbe {
    /**
     * Path to SQLite database. Supports ~ for home directory.
     * Supports platform-specific paths via {platform} placeholder.
     */
    dbPath: string;
    /**
     * SQL query to find the session ID.
     * Use {dirs} placeholder for the directory IN-clause parameters.
     * The query must SELECT a column named 'id'.
     * A '?' placeholder after {dirs} receives the min-created-at timestamp.
     */
    query: string;
    /**
     * How the provider stores timestamps.
     * - 'unix_ms': milliseconds since epoch (default)
     * - 'unix_s': seconds since epoch
     * - 'iso': ISO 8601 string (YYYY-MM-DD HH:MM:SS)
     */
    timestampFormat?: 'unix_ms' | 'unix_s' | 'iso';
}
/** ACP auth method — based on ACP official spec */
export type AcpAuthMethod = AcpAuthEnvVar | AcpAuthAgent | AcpAuthTerminal;
/** Environment variable-based auth (API keys etc) */
export interface AcpAuthEnvVar {
    type: 'env_var';
    id: string;
    name: string;
    vars: Array<{
        name: string;
        label?: string;
        secret?: boolean;
        optional?: boolean;
    }>;
    link?: string;
}
/** Agent self-auth (OAuth, browser-based etc) */
export interface AcpAuthAgent {
    type: 'agent';
    id: string;
    name: string;
    description?: string;
}
/** Terminal command-based auth (runs setup command) */
export interface AcpAuthTerminal {
    type: 'terminal';
    id: string;
    name: string;
    description?: string;
    args?: string[];
    env?: Record<string, string>;
}
/**
 * CDP script functions.
 * Each function takes a params object and returns a JS code string for CDP evaluate.
 * The JS execution result must conform to the Output Contract.
 *
 * Custom scripts can be added via index signature in addition to built-in scripts.
 * All scripts can receive params: Record<string, any>,
 * backward compatible with legacy single-argument style (e.g. sendMessage(text)).
 */
export interface ProviderScripts {
    readChat?: (params?: Record<string, any>) => string;
    sendMessage?: (params?: Record<string, any>) => string;
    listSessions?: (params?: Record<string, any>) => string;
    switchSession?: (params?: Record<string, any>) => string;
    newSession?: (params?: Record<string, any>) => string;
    focusEditor?: (params?: Record<string, any>) => string;
    openPanel?: (params?: Record<string, any>) => string;
    /** List available models → { models: string[], current: string } */
    listModels?: (params?: Record<string, any>) => string;
    /** Change model → { success: boolean } */
    setModel?: (params?: Record<string, any>) => string;
    /** List available modes → { modes: string[], current: string } */
    listModes?: (params?: Record<string, any>) => string;
    /** Change mode → { success: boolean } */
    setMode?: (params?: Record<string, any>) => string;
    /** params: { action: 'approve'|'reject'|'custom', button?: string } */
    resolveAction?: (params?: Record<string, any>) => string;
    webviewResolveAction?: (params?: Record<string, any>) => string;
    listNotifications?: (params?: Record<string, any>) => string;
    dismissNotification?: (params?: Record<string, any>) => string;
    [scriptName: string]: ((params?: Record<string, any>) => string) | undefined;
}
/**
 * ProviderLoader.resolve() result: Final provider with OS/version overrides applied
 */
export interface ResolvedProvider extends ProviderModule {
    /** OS applied during resolve */
    _resolvedOs?: string;
    /** Version applied during resolve */
    _resolvedVersion?: string;
    /** Warning when detected version is not in compatibility matrix */
    _versionWarning?: string;
    /** On-disk provider directory selected by ProviderLoader */
    _resolvedProviderDir?: string;
    /** Script directory selected by compatibility/default resolution */
    _resolvedScriptDir?: string;
    /** scripts.js path or fallback script directory used to build runtime scripts */
    _resolvedScriptsPath?: string;
    /** Why this script selection was chosen */
    _resolvedScriptsSource?: string;
}
/** Setting variable definition declared by provider */
export interface ProviderSettingDef {
    type: 'boolean' | 'number' | 'string' | 'select';
    default: any;
    /** true = controllable from dashboard UI */
    public: boolean;
    /** UI label */
    label?: string;
    /** UI description */
    description?: string;
    /** Minimum value for number type */
    min?: number;
    /** Maximum value for number type */
    max?: number;
    /** Options for select type */
    options?: string[];
}
/** Public settings schema (for dashboard transmission) */
export interface ProviderSettingSchema extends ProviderSettingDef {
    key: string;
}
/**
 * Control types:
 * - 'select'  — dropdown list (model picker, mode picker)
 * - 'toggle'  — on/off switch (compact mode, auto-approve)
 * - 'cycle'   — click-to-cycle through options (thinking level: low→med→high)
 * - 'slider'  — numeric range (temperature: 0–2)
 * - 'action'  — one-shot button (show usage, restart, clear context)
 */
export type ProviderControlType = 'select' | 'toggle' | 'cycle' | 'slider' | 'action' | 'display';
/**
 * Where the control appears in the chat UI:
 * - 'bar'    — thin strip below/above the chat input (always visible)
 * - 'header' — in the agent header area
 * - 'menu'   — inside a ⋯ overflow menu
 */
export type ProviderControlPlacement = 'bar' | 'header' | 'menu';
/** Static option for select/cycle controls */
export interface ProviderControlOption {
    value: string;
    label: string;
    description?: string;
    group?: string;
}
export interface ControlListResult {
    options: ProviderControlOption[];
    currentValue?: string | number | boolean;
    error?: string;
}
export interface ControlSetResult {
    ok: boolean;
    currentValue?: string | number | boolean;
    effects?: ProviderEffect[];
    error?: string;
}
export interface ControlInvokeResult {
    ok: boolean;
    currentValue?: string | number | boolean;
    effects?: ProviderEffect[];
    error?: string;
}
/**
 * ProviderControlDef — A single interactive control declared by a provider.
 *
 * Controls are different from Settings:
 * - Settings: background config, infrequently changed, managed in settings page
 * - Controls: interactive, changed during chat, rendered inside chat panel
 *
 * Each control maps to provider scripts for get/set operations.
 * The frontend renders controls automatically based on this schema —
 * no hardcoded model/mode assumptions needed.
 *
 * For 'action' type:
 * - Renders as a button. On click → calls invokeScript.
 * - No value state. Optionally shows result via toast/inline.
 */
export interface ProviderControlDef {
    /** Unique identifier (e.g. 'model', 'mode', 'thinking', 'usage') */
    id: string;
    /** Control type */
    type: ProviderControlType;
    /** Display label */
    label: string;
    /** Icon (emoji or icon name) */
    icon?: string;
    /** Where to show this control in the UI */
    placement: ProviderControlPlacement;
    /** Static options — used when the list is known at definition time */
    options?: ProviderControlOption[];
    /** Dynamic options — load via script at runtime */
    dynamic?: boolean;
    /** Script name to list options (e.g. 'listModels') — required when dynamic=true */
    listScript?: string;
    /** Script name to change value (e.g. 'setModel') — required for value-based controls */
    setScript?: string;
    /** Field name in readChat() result to read current value (e.g. 'model', 'mode') */
    readFrom?: string;
    /** Default value */
    defaultValue?: string | number | boolean;
    /** Script name to invoke (one-shot call, no value) */
    invokeScript?: string;
    /** How to display action result: 'toast' = notification, 'inline' = show in bar, 'none' = silent */
    resultDisplay?: 'toast' | 'inline' | 'none';
    /** Optional confirmation title shown before invoking a destructive or disruptive action */
    confirmTitle?: string;
    /** Optional confirmation message shown before invoking a destructive or disruptive action */
    confirmMessage?: string;
    /** Optional confirmation button label */
    confirmLabel?: string;
    min?: number;
    max?: number;
    step?: number;
    /** Sort order within placement group (lower = first) */
    order?: number;
    /** Hide this control when condition not met */
    hidden?: boolean;
}
