import { type AskQuestionArgs, type AskQuestionResult, type ConversationStateStructure, type CustomSubagent, type ExecServerMessage, type ExecServerControlMessage, type InteractionQuery, type McpToolDefinition, type RequestContext } from "./proto/agent_pb"; import type { GrepArgs, HookAdditionalContext } from "./proto/agent_pb"; import type { CursorModelParameter } from "./models"; import { type WorkspaceContext, type WorkspaceContextOptions } from "./workspace-context"; import { CodeSession, buildCodeToolDescription, codeToolParameters, type CodeToolCatalogEntry, type CodeToolResultInput } from "./code-session"; import { resolveAdvertisedToolName, rekeyArgsForSchema } from "./tool-roles"; import { coerceStringifiedArgs } from "./arg-coerce"; import { type ReasoningTailState } from "./reasoning-tail"; import { type HarnessFrameState } from "./harness-frames"; import { type ThinkingExhaustionState } from "./thinking-exhaustion"; import type { OpenCodeConversationSearchResult } from "./opencode-conversation-search"; import type { OpenCodeToolResultEntry, OpenCodeToolResultLedger } from "./opencode-tool-result-ledger"; import { salvageTruncatedCodeInput, normalizeFilesShape, emptyScriptCoachMessage, salvageCodeScript, salvageExpressionReturn, rewriteJsonParseOnText, planScriptReroute, healDirectChainCatch, incompleteSyntaxAtEof, incompleteScriptCoachMessage } from "./script-salvage"; import { normalizeReadResultText } from "./read-render"; import { tryHealEditArgs } from "./edit-heal"; import { toolContractFromSchema, missingRequiredKeys, formatMissingRequiredError, legacyNormalizeFileToolArgs, argKeyList, type ToolContract, type ToolResultContentBlock, type ToolResultIR } from "./tool-contract"; import type { CursorNativePolicy } from "./config"; /** * Decompress a Connect envelope payload whose compressed flag (0x01) is set. * cursor-agent advertises `connect-accept-encoding: gzip, br`, so the server * may compress per-frame. The daemon forwards raw response bytes without the * Connect-Content-Encoding header, so detect gzip by magic bytes (1f 8b) and * fall back to brotli. On any failure return the bytes unchanged so a decode * error surfaces rather than a crash. */ declare function decompressConnectFrame(bytes: Uint8Array, maxOutputLength?: number, onError?: () => void): Uint8Array; declare function resolveCursorClientVersion(env?: NodeJS.ProcessEnv, installedVersions?: readonly string[]): string; /** Default identity headers applied to every bridge spawn; per-call headers win. */ declare function withDefaultBridgeHeaders(extra?: Record): Record; /** * Headers that restrict Cursor's ToolCall surface for a code-mode Agent Run. * Mirrors cursor-agent --allowed-tools mcpToolCall. */ declare function codeModeToolControlHeaders(): Record; /** * Headers that restrict Cursor's ToolCall surface for normal-mode (/v1) Runs. * Same control plane as code mode; allowlist is the tools we handle. * When the capture-gated native Write adapter is active for this Run, append * writeToolCall exactly once; retries/resumes must reuse the same snapshot. */ declare function normalModeToolControlHeaders(options?: { nativeWriteActive?: boolean; allowedToolCalls?: readonly string[]; }): Record; /** Required filePath/path + content for the capture-gated native Write adapter. */ declare function isNativeWriteSchemaCompatible(contract: ToolContract): boolean; /** * Exactly one advertised tool with semantic role `write` and compatible required * schema keys, else null (zero/ambiguous/incompatible keep MCP write visible). */ declare function resolveUniqueCompatibleWriteTool(tools: OpenAIToolDef[]): string | null; declare function countWriteLinesCreated(text: string): number; interface ToolBridgeWireEvent { phase: "toolCall" | "exec" | "result" | "checkpoint"; caseName: string; callId?: string; updateCase?: string; id?: number; execId?: string; toolCallId?: string; args?: Record; result?: Record; } declare function snapshotRuntime(sourcePath: string): string | null; declare function resolveRuntimePath(original: string, snapshot: string | null): string; declare function resolveStreamInactivityTimeoutMs(raw?: string | undefined): number; declare function resolveClientStallTimeoutMs(raw?: string | undefined): number; interface OpenAIToolCall { id: string; type: "function"; function: { name: string; arguments: string; }; } /** A single element in an OpenAI multi-part content array. */ interface ContentPart { type: string; text?: string; /** OpenAI image part: string data URL or { url, detail }. Only data: URLs are accepted. */ image_url?: string | { url?: string; detail?: string; }; } interface OpenAIMessage { role: "system" | "user" | "assistant" | "tool"; content: string | null | ContentPart[]; tool_call_id?: string; tool_calls?: OpenAIToolCall[]; } interface OpenAIToolDef { type: "function"; function: { name: string; description?: string; parameters?: Record; }; } type NativeToolRole = "read" | "grep" | "shell" | "glob" | "question" | "task" | "lsp" | "write" | "apply_patch"; interface NativeToolBinding { role: NativeToolRole; toolName: string; tool: McpToolDefinition; } interface RunToolPlan { policy: CursorNativePolicy; modelMcpTools: McpToolDefinition[]; executionTools: McpToolDefinition[]; nativeBindings: ReadonlyMap; allowedToolCalls: string[]; capabilityInstructions: string[]; serverWebSearchEnabled: boolean; } interface CursorRequestPayload { requestBytes: Uint8Array; blobStore: Map; mcpTools: McpToolDefinition[]; requestContext: RequestContext; /** Immutable copy of the Run's inline-context rollback decision. */ includeInlineContext: boolean; clientHistory: ClientHistoryTurn[]; /** Immutable per-Run snapshot: native Write adapter armed for this Run. */ nativeWriteActive: boolean; /** Exact allowed-tools header snapshot for this Run (retries/resumes reuse it). */ toolControlHeaders: Record; /** Immutable declaration/binding/header source for this physical Run. */ toolPlan: RunToolPlan; effectiveSystemPrompt: string; workspacePath: string; worktreePath: string; } interface RunProtocolContext { mcpTools: McpToolDefinition[]; executionMcpTools?: McpToolDefinition[]; requestContext: RequestContext; includeInlineContext: boolean; toolPlan?: RunToolPlan; } /** A pending tool execution waiting for results from the caller. */ interface PendingExec { execId: string; execMsgId: number; toolCallId: string; toolName: string; /** Decoded arguments JSON string for SSE tool_calls emission. */ decodedArgs: string; /** Cursor can carry model-only context beside this exec result. */ acceptHookAdditionalContexts?: boolean; /** Normalization/preflight failure observed on the exec lane. The shared * accumulator may still heal it from a richer final interaction update. */ preflightError?: string; /** How the result must be encoded back to Cursor. Native shell execs * (shellArgs / shellStreamArgs) are bridged to the caller's bash tool but * must be answered with shell result frames, not mcpResult. AskQuestion * interaction queries are answered with interactionResponse. Native Write * must be answered with writeResult. Native filesystem tools delegate to * the caller's permission-owning read/grep tools, then expect their native * Cursor result variants. */ resultKind: "mcp" | "shell" | "shellStream" | "miniSweBash" | "askQuestion" | "write" | "read" | "redactedRead" | "ls" | "grep" | "delete" | "fetch" | "listMcpResources" | "readMcpResource" | "subagent" | "diagnostics" | "piRead" | "piBash" | "piEdit" | "piWrite" | "piGrep" | "piFind" | "piLs"; /** Original native-shell metadata (echoed back in shell results). */ shellCommand?: string; shellCwd?: string; shellTimeoutMs?: number; /** Original WriteArgs path (echoed in writeResult). */ writePath?: string; /** Whether WriteSuccess should include file_content_after_write. */ writeReturnContent?: boolean; /** Expected text for read-only post-write verification (never re-written). */ writeExpectedText?: string; /** Original native Read metadata (echoed in readResult). */ readPath?: string; /** Absolute path used only after OpenCode approved the corresponding read. */ readResolvedPath?: string; readOffset?: number; readLimit?: number; readEncodingHint?: string; /** Original native Ls metadata used to translate OpenCode directory Read. */ lsPath?: string; lsIgnore?: string[]; /** Original native Grep args used to translate OpenCode grep output. */ grepArgs?: GrepArgs; grepWorkspacePath?: string; /** Adapter-specific source arguments needed to translate OpenCode output. */ adapterArgs?: Record; /** InteractionQuery id for askQuestion resultKind (not an exec id). */ interactionQueryId?: number; /** Cursor question ids + option id maps for round-tripping OpenCode answers. */ askQuestionMeta?: { questionIds: string[]; /** questionId → option label → option id */ optionIdByQuestion: Record>; }; askQuestionAsync?: { originalToolCallId: string; originalArgs: AskQuestionArgs; }; } interface LogicalToolCall { toolCallId: string; exposure: "exposed" | "deferred"; exec?: PendingExec; bufferedResult?: ToolResultInfo; answered?: boolean; toolName?: string; decodedArgs?: string; } type RunTerminalCause = "user_cancel" | "proxy_watchdog" | "retry_teardown" | "parked_teardown" | "transport_failure"; interface RunCleanupOwner { token: string; cleanup: (cause: RunTerminalCause) => void; responseClosed: () => boolean; /** Clears only this response's local timers; never shared heartbeat/exec/bridge. */ retire: () => void; retired: boolean; } interface PhysicalRunState { token: string; userCancelled: boolean; terminalCause?: RunTerminalCause; cleanup: (cause: RunTerminalCause) => void; cleanupOwner?: RunCleanupOwner; cleanupDone?: boolean; } declare function createPhysicalRunState(token?: string): PhysicalRunState; declare function markRunTerminalCause(runState: PhysicalRunState, cause: RunTerminalCause): void; /** A bridge kept alive across requests for tool result continuation. */ interface ActiveBridge { bridge: ReturnType; heartbeatTimer: NodeJS.Timeout; blobStore: Map; mcpTools: McpToolDefinition[]; requestContext: RequestContext; execLifecycle: ExecLifecycleRegistry; clientHistory: ClientHistoryTurn[]; pendingExecs: PendingExec[]; callLedger?: Map; convKey: string; lastAccessMs: number; /** Preserved across shell-bridge parks so later native execs stay code-only. */ codeMode?: CodeModeCtx; /** Immutable workspace/session identity captured when this turn began. */ requestScope: RequestScope; /** Immutable native-Write arming snapshot for this Run (not recomputed). */ nativeWriteActive?: boolean; /** Immutable declaration/binding/header source for this physical Run. */ toolPlan?: RunToolPlan; /** Rebuild this Run from either its original action or a supplied checkpoint. */ respawn?: BridgeRespawn; /** Unique physical Run ownership shared by every response wrapper. */ runState: PhysicalRunState; } type BridgeRespawn = (checkpoint?: Uint8Array) => { bridge: ReturnType; heartbeatTimer: NodeJS.Timeout; }; /** Ownership phase for a dual-parked code session. * - starting: registered before the first sandbox event (cancel/abort can find it) * - parked: awaiting client tool results for the current wave * - resuming: delivering results / awaiting the next sandbox event (rejects concurrent resume) */ type CodeSessionPhase = "starting" | "parked" | "resuming"; /** A code-mode session parked awaiting client tool results for its current * wave. The composer bridge is held HERE (not in activeBridges) so the * follow-up tool-result request routes to the sandbox, not to composer. */ interface ActiveCodeSession { session: CodeSession; /** Code-mode context (client tool names) carried across composer resumes so * a follow-up `code` call on the resumed bridge is still intercepted. */ codeMode: CodeModeCtx; /** The parked composer bridge whose single pending exec is the `code` call. */ composerBridge: ActiveBridge; /** The composer `code` exec to answer with the script's return value on done. */ codeExec: PendingExec; /** The wave the sandbox is currently parked on (awaiting client results). */ currentWave: number; /** Normalized wave calls aligned with pendingToolCallIds (client slots only). */ pendingWaveCalls: Array<{ name: string; args: Record; }>; /** * Full wave slot map: client tool_call ids + synthetic errors for unknown * tools (so sandbox always receives one result per wave call). */ pendingWaveSlots: Array<{ kind: "client"; id: string; call: { name: string; args: Record; }; } | { kind: "error"; error: string; call: { name: string; args: Record; }; }>; /** Edit-heal auto-retries already spent for the current wave (max 1). */ editHealAttempts: number; /** Requested model id, for model-gated result conditioning (composer-2.5). */ modelId: string; /** Explicit ownership phase so startup/resume cannot race map membership. */ phase: CodeSessionPhase; lastAccessMs: number; } /** Displace a PARKED admission owner for this conversation. A fresh Run in * the same conversation means the client abandoned that parked turn (its * tool results will never arrive — OpenCode moved on to a new turn), so the * parked bridge / parked code session must not wedge the conversation until * the idle TTL. Owners that are actively streaming (not parked in either * map) or mid sandbox turn keep their admission and the caller 409s. */ declare function displaceParkedAdmissionOwner(convKey: string): boolean; declare function sameRequestOwner(active: RequestScope, incoming: RequestScope): boolean; declare function parkedTurnExpired(lastAccessMs: number, now?: number): boolean; /** CancelAction → abort owned execs → drop heartbeats → close transport. */ declare function teardownParkedBridge(active: ActiveBridge, mode?: "end" | "abort"): void; declare function findPendingContinuation(toolResults: ToolResultInfo[], scope: RequestScope): { bridgeKey: string; convKey: string; } | null | undefined; /** Detect client tool failure from content and optional message flags. */ declare function detectToolResultError(content: string, explicit?: boolean): boolean; /** Convert one client ToolResultInfo into the sandbox's ToolResult input shape, * applying read-render normalization when the call was a read-role tool. */ declare function toolResultInfoToCodeInput(result: ToolResultInfo, toolName?: string, callArgs?: Record): CodeToolResultInput; /** * Normalize one code-mode sandbox wave call: * 1. heal dialect tool name (Bash→bash, Shell→bash, StrReplace→edit) * 2. role-fold + schema re-key args (file_path→filePath, …) * 3. snake/camel + alias normalize * 4. coerce stringified structured args when schema excludes string * * Returns { name, args } on success, or { error } when the tool is unknown * (caller should not emit a client tool_call for that slot). */ declare function normalizeWaveCall(call: { name: string; args: Record; }, codeMode: CodeModeCtx, workspaceRoot?: string): NormalizedClientToolCall; interface ToolCatalog { toolNames: readonly string[]; toolContractsByName: Map; } type NormalizedClientToolCall = { name: string; args: Record; error?: undefined; errorKind?: undefined; } | { name: string; args: Record; error: string; errorKind: "unknown_tool" | "missing_required" | "invalid_arguments"; }; /** * Shared client-tool heal used by code-mode waves AND normal-mode MCP execs. * Never emits a name outside the advertised catalog. After alias/coerce, runs a * required-key preflight against the tool schema so structurally incomplete * calls (e.g. Edit missing newString) fail here with actionable diagnostics * instead of crossing into OpenCode as a late SchemaError. */ declare function normalizeClientToolCall(call: { name: string; args: Record; }, catalog: ToolCatalog, workspaceRoot?: string): NormalizedClientToolCall; /** Build a heal catalog from advertised MCP tool defs (normal mode). */ declare function catalogFromMcpTools(mcpTools: McpToolDefinition[]): { toolNames: string[]; toolContractsByName: Map; }; /** Build the composer-facing mcpResult for a finished code script. */ declare function codeDoneToMcpResult(value: string | undefined, error: string | undefined, logs?: string[]): import("./proto/agent_pb").McpResult; /** Select a single tool result for one-shot edit-heal. * Exact tool_call_id wins (last duplicate). Otherwise only a lone blank-id * result is compatible — nonempty rewritten/unknown ids must not heal. */ declare function selectSingleToolResult(expectedId: string | undefined, toolResults: ToolResultInfo[]): ToolResultInfo | undefined; /** Pair code-wave slots with client tool results (pure, testable). * Error slots keep their synthetic error and do not count as client slots. * Exact tool_call_id matches win (last-duplicate-wins via byId). Positional * blank-id fallback is permitted only when there are zero exact matches, * client-slot/result counts are equal, and every candidate id is blank — * matching pairToolResultsWithExecs. Partial identity overlap, mixed * blank+rewritten batches, and blank count mismatches yield explicit * "(tool result not provided)" sentinels for unmatched client slots. */ declare function pairWaveSlotResults(slots: ActiveCodeSession["pendingWaveSlots"], toolResults: ToolResultInfo[], toInput: (r: ToolResultInfo, toolName: string, args: Record) => CodeToolResultInput): CodeToolResultInput[]; declare function handleCodeSessionResume(active: ActiveCodeSession, toolResults: ToolResultInfo[], modelId: string, bridgeKey: string, convKey: string): Promise; /** Build pending wave slots from raw sandbox calls (heal + unknown→error). */ declare function buildWaveSlots(calls: { name: string; args: Record; }[], codeMode: CodeModeCtx, workspaceRoot?: string): ActiveCodeSession["pendingWaveSlots"]; /** Emit one code-session wave as an OpenAI tool_calls SSE turn and re-park the * session under bridgeKey so the follow-up tool-result request finds it. */ declare function buildCodeWaveResponse(active: ActiveCodeSession, wave: number, calls: { name: string; args: Record; }[], modelId: string, bridgeKey: string, convKey: string): Response; interface StoredConversation { conversationId: string; checkpoint: Uint8Array | null; checkpointWorkspaceIdentity?: string; checkpointClientHistory?: ClientHistoryTurn[]; hadCheckpoint: boolean; workspaceIdentity: string; turnLedger: TurnLedgerEntry[]; checkpointLossNotified?: CheckpointLossReason; blobStore: Map; /** B4: memo of historical-turn content -> turn blob id, so long sessions * don't re-serialize + re-hash every prior turn on each request. */ turnBlobMemo: Map; /** Reasoning-tail capture/stash for runaway-reasoning models (TTL-swept with the conversation). */ reasoningTail: ReasoningTailState; /** Harness-frame cadence state (continuity throttle). */ harnessFrames: HarnessFrameState; /** Thinking-exhaustion arm/streak (never-executes containment). */ thinkingExhaustion: ThinkingExhaustionState; lastAccessMs: number; } type CheckpointLossReason = "missing" | "decode_failed" | "blobs_missing" | "workspace_mismatch" | "history_diverged"; interface ClientHistoryTurn { userText: string; assistantText: string; } interface TurnLedgerEntry { id: string; userText: string; assistantText: string; } declare function mergeTurnLedger(existing: TurnLedgerEntry[], turns: Array<{ userText: string; assistantText: string; }>): TurnLedgerEntry[]; declare function buildCheckpointRecoveryMarker(reason: CheckpointLossReason, ledger: TurnLedgerEntry[]): string; declare function applyCheckpointRecoveryMarker(userText: string, loss: CheckpointLossReason | undefined, ledger: TurnLedgerEntry[], lastNotified: CheckpointLossReason | undefined): { userText: string; notified?: CheckpointLossReason; added: boolean; }; /** Connect protocol frame: [1-byte flags][4-byte BE length][payload] */ declare function frameConnectMessage(data: Uint8Array, flags?: number): Buffer; /** * Spawn the Node H2 bridge and return read/write handles. * The bridge uses length-prefixed framing on stdin/stdout. */ interface SpawnBridgeOptions { accessToken: string; rpcPath: string; url?: string; /** When true, use application/proto for unary RPCs instead of Connect streaming. */ unary?: boolean; headers?: Record; } interface BridgeCloseInfo { phase?: string; reason?: string; status?: number; errorCode?: string; h2Code?: number; } declare function parseBridgeCloseInfo(metadata: Buffer): BridgeCloseInfo | undefined; /** Transport-neutral bridge handle. Backed either by a per-request node * subprocess (spawnBridgeLegacy) or a multiplexed channel on the shared * h2 daemon (spawnBridgeDaemon). */ interface BridgeHandle { /** Subprocess handle when legacy; undefined when daemon-backed. */ proc?: ReturnType; /** Cursor Run correlation id, assigned by startBridge. */ requestId?: string; write: (data: Uint8Array) => void; /** Half-close the request stream. */ end: () => void; /** Abort the channel/stream immediately (timeouts, cancellation). */ abort: (cause?: RunTerminalCause) => void; onData: (cb: (chunk: Buffer) => void) => void; onClose: (cb: (code: number, info?: BridgeCloseInfo) => void) => void; /** True while the underlying transport is still alive. */ get alive(): boolean; } /** Legacy per-request node subprocess bridge (h2-bridge.mjs). Used when the * daemon is disabled, unavailable, or has failed permanently this session. */ declare function spawnBridgeLegacy(options: SpawnBridgeOptions): BridgeHandle; /** * Acquire an H2 bridge handle. Routes through the shared daemon by default, * falling back to a legacy per-request subprocess when the daemon is disabled * (CURSOR_OPENCODE_NO_DAEMON=1) or has failed permanently this session. */ declare function spawnBridge(options: SpawnBridgeOptions): BridgeHandle; interface CursorUnaryRpcOptions { accessToken: string; rpcPath: string; requestBody: Uint8Array; url?: string; timeoutMs?: number; headers?: Record; /** When aborted, abort only this unary bridge/channel (no retry). */ signal?: AbortSignal; /** Maximum response bytes retained by this unary call. */ maxResponseBytes?: number; /** When true, use Connect server-streaming (application/connect+proto) and * wrap the request body in a Connect envelope. The response is buffered the * same way as unary — the caller splits Connect stream frames. */ streaming?: boolean; } export declare function callCursorUnaryRpc(options: CursorUnaryRpcOptions): Promise<{ body: Uint8Array; exitCode: number; timedOut: boolean; }>; /** Optional per-context policy snapshot captured at startProxy registration. */ export interface ProxyRuntimeOptions { codeModeEnabled?: boolean; skillsEnabled?: boolean; inlineRequestContext?: boolean; nativePolicy?: CursorNativePolicy; /** Capture-gated native Write adapter; default false. Consumed by later Write wave. */ nativeWriteEnabled?: boolean; /** Plugin registration concern; snapshotted for Run isolation. Default false. */ generateImageEnabled?: boolean; /** Plugin registration concern; snapshotted for Run isolation. Default false. */ backgroundShellEnabled?: boolean; /** Plugin-hook metadata bridge for translating OpenCode tool outcomes. */ toolResultLedger?: OpenCodeToolResultLedger; /** Current-workspace OpenCode conversation search adapter. */ conversationSearchEnabled?: boolean; searchConversations?: (input: { directory: string; activeSessionId?: string; query: string; limit?: number; }) => Promise; /** Read-only OpenCode SDK adapter used by Cursor subagent_await. */ awaitSubagent?: (input: { directory: string; sessionId: string; timeoutMs: number; }) => Promise; } declare function nativeWriteCaptureRuntimeOptionsForTest(runtimeOptions: ProxyRuntimeOptions): ProxyRuntimeOptions; declare function nativeTodoCaptureRuntimeOptionsForTest(runtimeOptions: ProxyRuntimeOptions): ProxyRuntimeOptions; declare function nativeLspDiagnosticsCaptureRuntimeOptionsForTest(runtimeOptions: ProxyRuntimeOptions): ProxyRuntimeOptions; export type ProxySubagentAwaitResult = { status: "complete"; finalMessage?: string; toolCallCount: number; } | { status: "still_running"; } | { status: "not_found"; } | { status: "error"; error: string; }; interface ProxyContextRegistration { id: string; getAccessToken: () => Promise; workspaceOptions: WorkspaceContextOptions; /** Kill switch: when false, /v1/code cannot activate code mode for this context. */ codeModeEnabled: boolean; /** Kill switch: when false, strip OpenCode lowercase `skill` for this context. */ skillsEnabled: boolean; /** Rollback gate for Run-level tools and inline request context. */ inlineRequestContext: boolean; /** Native declaration policy for this context (circuit may force legacy). */ nativePolicy: CursorNativePolicy; /** Mutable per-context circuit; tripped independently of other contexts. */ nativePolicyCircuitOpen: boolean; /** Tool-bridge enable flags; registration-local, not rewritten by setProxy* setters. */ nativeWriteEnabled: boolean; nativeLspDiagnosticsEnabled: boolean; generateImageEnabled: boolean; backgroundShellEnabled: boolean; toolResultLedger?: OpenCodeToolResultLedger; conversationSearchEnabled: boolean; searchConversations?: NonNullable; awaitSubagent?: NonNullable; /** Non-serializable live-capture override; never populated by plugin config. */ captureAllowedToolCalls?: readonly string[]; } interface RequestScope { contextId: string; sessionId?: string; agentId?: string; mode: "normal" | "code"; workspaceOptions: WorkspaceContextOptions; workspace: WorkspaceContext; workspaceIdentity: string; workspaceAvailable: boolean; /** Immutable policy snapshot from the owning registration at request start. */ codeModeEnabled: boolean; skillsEnabled: boolean; inlineRequestContext: boolean; nativePolicy: CursorNativePolicy; /** Immutable tool-bridge enable snapshot for this Run (retries/resumes reuse it). */ nativeWriteEnabled: boolean; nativeLspDiagnosticsEnabled: boolean; generateImageEnabled: boolean; backgroundShellEnabled: boolean; toolResultLedger?: OpenCodeToolResultLedger; conversationSearchEnabled: boolean; searchConversations?: NonNullable; awaitSubagent?: NonNullable; captureAllowedToolCalls?: readonly string[]; } declare function requestScopeFromRegistration(registration: ProxyContextRegistration, sessionId: string | undefined, wantCode: boolean, agentId?: string): RequestScope; /** Build a registration from token/workspace plus current module defaults (or overrides). */ declare function makeProxyContextRegistration(id: string, getAccessToken: () => Promise, workspaceOptions: WorkspaceContextOptions, runtimeOptions?: ProxyRuntimeOptions): ProxyContextRegistration; /** Set the code-mode kill switch (defaults + existing registrations). */ export declare function setProxyCodeMode(enabled: boolean): void; /** Set the OpenCode skills kill switch (defaults + existing registrations). */ export declare function setProxySkillsEnabled(enabled: boolean): void; /** Rollback gate for Run-level tools and inline request context. Refresh replies remain enabled. */ export declare function setProxyInlineRequestContext(enabled: boolean): void; export declare function setProxyNativePolicy(policy: CursorNativePolicy): void; declare function effectiveNativePolicy(contextId?: string): CursorNativePolicy; declare function tripNativePolicyCircuit(reason: string, contextId?: string): void; /** * Per-request code-mode gate (dual providers): the request path selects intent * (wantCode), the kill switch can only force OFF, and code mode stays * streaming-only with at least one real client tool advertised. * `codeModeEnabled` defaults to the module kill switch for legacy callers/tests. */ declare function resolveCodeModeActive(wantCode: boolean, stream: boolean | undefined, toolCount: number, codeModeEnabled?: boolean): boolean; interface RequestedCursorModelSelection { /** OpenCode-facing request id (base or legacy slug) — echoed in SSE/completions. */ publicId: string; /** * Cursor ModelDetails.modelId / displayModelId. Must be a known AvailableModels * public variant slug (e.g. `grok-4.5-fast-medium`), never a collapsed base id. * Sending the base (`grok-4.5-fast`) yields Connect `not_found`. */ detailsModelId: string; /** Cursor RequestedModel.modelId (server model name, often shared across variants). */ cursorModelId: string; displayName: string; parameters: CursorModelParameter[]; maxMode: boolean; } declare function resolveRequestedModel(modelId: string, effort?: string | null): RequestedCursorModelSelection; export declare function getProxyPort(): number | undefined; export declare function startProxy(getAccessToken: () => Promise, workspaceOptions?: WorkspaceContextOptions, contextId?: string, runtimeOptions?: ProxyRuntimeOptions): Promise; export declare function stopProxy(): void; declare function buildFreshToolPlan(params: { tools: OpenAIToolDef[]; modelId: string; scope: RequestScope; codeModeActive: boolean; }): { toolPlan: RunToolPlan; nativeWriteActive: boolean; skillToolRoute: OpenCodeSkillRoute; openCodeCustomSubagents: ReturnType; }; interface ToolResultInfo { toolCallId: string; content: string; /** True when the client marked the tool result as an error (or content looks like one). */ isError?: boolean; ir?: ToolResultIR; openCode?: OpenCodeToolResultEntry; } interface ParsedMessages { systemPrompt: string; userText: string; turns: Array<{ userText: string; assistantText: string; }>; toolResults: ToolResultInfo[]; /** Decoded images from the current (trailing) user message only. */ userImages: ParsedUserImage[]; } /** One validated inbound user image: decoded bytes plus agreed MIME. */ interface ParsedUserImage { data: Uint8Array; mimeType: McpImageMimeType; } /** Result of scanning one user message's content parts for images. */ interface ParsedUserImageBatch { images: ParsedUserImage[]; /** Count of image_url parts rejected by validation or the count/byte caps. */ dropped: number; } declare function parseUserImageParts(content: OpenAIMessage["content"]): ParsedUserImageBatch; /** Normalize OpenAI message content to a plain string. */ declare function textContent(content: OpenAIMessage["content"]): string; declare function parseMessages(messages: OpenAIMessage[], scope?: RequestScope): ParsedMessages; declare function openCodeCustomSubagentsFromTools(tools: readonly OpenAIToolDef[]): CustomSubagent[]; /** * Authoritative OpenCode skill catalog from system prompt. * The final complete `` block wins (not a union of stale blocks), * even when that block is empty or malformed — stale earlier names are revoked. */ declare function availableSkillNames(systemPrompt: string): string[]; /** * Fail-closed OpenCode skill policy: * - skills disabled or catalog absent/empty/malformed → strip `skill` entirely * - catalog present → enum = catalog ∩ client enum (catalog may narrow, never widen) * Never leaves a free-string skill schema when the catalog is missing. */ declare function constrainSkillTools(tools: OpenAIToolDef[], systemPrompt: string, skillsEnabled?: boolean): OpenAIToolDef[]; declare function selectToolCatalogs(tools: OpenAIToolDef[], codeTool: OpenAIToolDef, codeMode: boolean, policy?: CursorNativePolicy, options?: { hideExactToolName?: string | null; }): { declaration: OpenAIToolDef[]; execution: OpenAIToolDef[]; }; /** Convert OpenAI tool definitions to Cursor's MCP tool protobuf format. */ declare function buildMcpToolDefinitions(tools: OpenAIToolDef[]): McpToolDefinition[]; declare function knownToolParams(mcpTools: McpToolDefinition[], toolName: string): Set | undefined; /** * Rename model-emitted argument keys to the names the tool actually declares. * * Cursor-hosted models are trained on Cursor's native snake_case parameters * (new_string, old_string, file_path, ...), while OpenCode tools declare * camelCase (newString, oldString, filePath, ...). When the tool's JSON * schema is available we rename any key whose snake/camel twin (or known * alias) exists in the schema — invisibly to the model, for every tool, in * both directions. Keys already matching the schema are never touched. */ declare function normalizeMcpArgsForOpenCode(toolName: string, args: Record, knownParams?: Set): Record; declare function buildRepositoryIndexingInfo(context: WorkspaceContext): import("./proto/agent_pb").RepositoryIndexingInfo; /** Match cursor-agent's `GitRepoInfo.is_origin_backed` producer semantics. */ declare function isCursorOriginBackedRemote(remoteUrl: string | undefined): boolean; /** * Assemble the model-visible system prompt after caveman compression: * append authoritative workspace identity and capability boundaries, then the * reasoning guard. * Exported via __test so smoke can assert the bake without a live Run. */ type OpenCodeSkillRoute = "none" | "mcp" | "code"; declare function buildEffectiveSystemPrompt(compressedSystemPrompt: string, modelId: string, workspaceOptions?: WorkspaceContextOptions, resolvedWorkspace?: WorkspaceContext, skillRoute?: OpenCodeSkillRoute): string; type RequestContextMode = "normal" | "code"; /** Map a `$SHELL` path to the kind token cursor-agent emits. */ declare function resolveShellKind(shellPath: string): string; declare function buildRequestContext(mcpTools: McpToolDefinition[], workspaceOptions?: WorkspaceContextOptions, resolvedWorkspace?: WorkspaceContext, mode?: RequestContextMode, skillRoute?: OpenCodeSkillRoute, conversationSearchEnabled?: boolean, capabilityInstructions?: readonly string[], serverWebSearchEnabled?: boolean, customSubagents?: readonly CustomSubagent[]): RequestContext; declare function rebaseCheckpointSystemBlocks(checkpoint: ConversationStateStructure, systemPrompt: string, blobStore: Map, workspacePath?: string, worktreePath?: string): ConversationStateStructure | undefined; declare function evaluateCheckpoint(checkpoint: Uint8Array | null, blobStore: Map, options: { hadCheckpoint: boolean; checkpointWorkspaceIdentity?: string; workspaceIdentity: string; checkpointClientHistory?: ClientHistoryTurn[]; currentClientHistory?: ClientHistoryTurn[]; }): { state?: ConversationStateStructure; loss?: CheckpointLossReason; }; /** Replace an existing Run's state/action with cursor-agent's checkpoint * ResumeAction while preserving model, conversation, and the immutable * request-context/rollback decision captured for the original physical Run. */ declare function buildResumeRunRequest(originalRequestBytes: Uint8Array, checkpointBytes: Uint8Array, requestContext?: RequestContext, includeInlineContext?: boolean): Uint8Array; type ResumeRunRequestResult = { kind: "safe"; requestBytes: Uint8Array; } | { kind: "unsafe"; }; declare function buildResumeRunRequestFromPayload(payload: Pick, checkpointBytes: Uint8Array): ResumeRunRequestResult; declare function makeCancelActionBytes(): Uint8Array; /** * Create a stateful parser for Connect protocol frames. * Handles buffering partial data across chunks. */ declare function createConnectFrameParser(onMessage: (bytes: Uint8Array) => void, onEndStream: (bytes: Uint8Array) => void, options?: { maxBytes?: number; onInvalidFrame?: () => void; }): (incoming: Buffer) => void; /** * Strip thinking tags from streamed text, routing tagged content to reasoning. * Buffers partial tags across chunk boundaries. */ declare function createThinkingTagFilter(): { process(text: string): { content: string; reasoning: string; }; flush(): { content: string; reasoning: string; }; }; interface StreamState { toolCallIndex: number; pendingExecs: PendingExec[]; outputTokens: number; totalTokens: number; /** Run terminal authority is independent from OpenAI SSE segment closure. */ runTerminal?: "turn_ended" | "failed"; runError?: string; runErrorEmitted?: boolean; /** Prompt tokens frozen at the first conversationCheckpointUpdate * (usedTokens minus completion accrued by then). Cursor's * ConversationTokenDetails exposes no direct prompt/input field, so this * first-checkpoint snapshot is the most accurate derivation available — * later checkpoints grow usedTokens with completion, which would * otherwise inflate a naive total-minus-completion estimate. */ promptTokens?: number; /** E1 debug counter: toolCall* interaction updates that look like a * GENUINE unrouted call — a new call id carrying args but no result and * no matching exec message. Cursor echoes every exec-path MCP call back * as toolCallStarted/Completed bookkeeping updates (Completed even * carries the mcpResult we answered with), and a tool-result resume * stream begins with those echoes; counting them produced false * "tool calls may be dropped" warnings on healthy turns. */ ignoredToolCallUpdates?: number; /** Call ids already seen via exec mcpArgs or earlier interaction updates * this stream (echo suppression for the E1 counter). */ seenToolCallIds?: Set; /** Thinking-exhaustion evidence: chars of thinkingDelta seen this turn. */ thinkingChars?: number; /** Thinking-exhaustion evidence: last thinkingCompleted duration (ms). */ thinkingDurationMs?: number; /** Wall-clock when the first thinkingDelta arrived (fallback duration). */ thinkingStartedAtMs?: number; /** One source of truth for exec + interaction observations, keyed by the * upstream call id. Calls validate and emit exactly once. */ toolCalls?: Map; /** Key-only telemetry: callId → arg key sets observed from mcpArgs vs * interaction updates (no values — avoids logging file contents). */ toolCallArgKeyTelemetry?: Map; /** Tool-lane activity can precede an authoritative exec/interaction call. */ toolActivityStartedAt?: number; lastToolActivityAt?: number; maxToolActivityGapMs?: number; toolActivitySlowLogged?: boolean; } interface ToolCallAccumulator { callId: string; modelCallId?: string; exec?: PendingExec; interaction?: CapturedInteractionToolCall; resultEcho: boolean; rejectedError?: string; emitted: boolean; firstSeenAt: number; lastSeenAt: number; } declare function computeUsage(state: StreamState): { prompt_tokens: number; completion_tokens: number; total_tokens: number; }; declare function handleExecControlMessage(control: ExecServerControlMessage, lifecycle?: ExecLifecycleRegistry): boolean; /** Accepted MIME types for MCP image projection (matches OpenCode media-ingest ceiling). */ declare const MCP_IMAGE_MIME_TYPES: readonly ["image/png", "image/jpeg", "image/webp"]; type McpImageMimeType = (typeof MCP_IMAGE_MIME_TYPES)[number]; /** Map Cursor AskQuestionArgs → OpenCode `question` tool args. */ declare function mapAskQuestionArgsToOpenCode(args: AskQuestionArgs | undefined): { openCodeArgs: Record; questionIds: string[]; optionIdByQuestion: Record>; }; declare function parseOpenCodeQuestionAnswers(content: string, meta: NonNullable): Array<{ questionId: string; selectedOptionIds: string[]; }>; declare function sendAsyncAskQuestionCompletion(asyncMeta: NonNullable, result: AskQuestionResult, sendFrame: (data: Uint8Array) => void): void; declare function rejectInteractionQuery(query: InteractionQuery, sendFrame: (data: Uint8Array) => void, reason?: string): void; /** * Handle Cursor InteractionQuery frames. * AskQuestion → bridge to OpenCode `question` when advertised; otherwise reject. * WebSearch → auto-approve (Cursor server executes). * All other query types are rejected so the Run does not stall. */ declare function handleInteractionQuery(query: InteractionQuery, mcpTools: McpToolDefinition[], sendFrame: (data: Uint8Array) => void, onMcpExec: (exec: PendingExec) => void, codeMode?: CodeModeCtx, toolPlan?: RunToolPlan, requestScope?: RequestScope): void; declare function handleInteractionUpdate(update: any, state: StreamState, onText: (text: string, isThinking?: boolean) => void, mcpTools?: McpToolDefinition[], codeMode?: CodeModeCtx, workspaceRoot?: string, onToolObservation?: () => void): void; /** An MCP tool call extracted from a tool-call interaction update (E1). */ interface CapturedInteractionToolCall { callId: string; modelCallId?: string; toolName: string; /** JSON string of decoded/normalized arguments. */ decodedArgs: string; validJson: boolean; validationError?: string; /** True when sourced from toolCallCompleted (final arguments). */ final: boolean; } declare function resolveShellToolName(mcpTools: McpToolDefinition[], codeMode?: CodeModeCtx): string | undefined; declare function portableToolCallId(rawId: string): string; interface ExecLifecycleRegistry { start(exec: ExecServerMessage): boolean; complete(exec: ExecServerMessage): boolean; fail(exec: ExecServerMessage, error: string): boolean; abort(id: number): boolean; abortAll(): void; setAbortOwner(id: number, owner: () => void): void; isActive(id: number): boolean; hasActive(): boolean; dispose(permanent?: boolean): void; } declare function createExecLifecycle(sendFrame: (data: Uint8Array) => void, heartbeatIntervalMs?: number): ExecLifecycleRegistry; declare function handleExecMessage(execMsg: ExecServerMessage, mcpTools: McpToolDefinition[], sendFrame: (data: Uint8Array) => void, onMcpExec: (exec: PendingExec) => void, codeMode?: CodeModeCtx, onMcpRejected?: (callId: string, error: string) => void, requestScope?: RequestScope, requestContext?: RequestContext, execLifecycle?: ExecLifecycleRegistry, nativeWriteActive?: boolean, toolPlan?: RunToolPlan): void; /** Native WebFetch stays MCP-only: precheck always reports allowlisted=false + one close. */ declare function handleWebFetchAllowlistPrecheck(execMsg: ExecServerMessage, sendFrame: (data: Uint8Array) => void, execLifecycle?: ExecLifecycleRegistry): void; /** Test seam: tool names advertised for a request path (no network). */ declare function resolveAdvertisedToolNamesForTest(wantCode: boolean, stream: boolean | undefined, clientToolNames: string[]): string[]; export declare const __test: { textContent: typeof textContent; pairToolResultsWithExecs: typeof pairToolResultsWithExecs; pairWaveSlotResults: typeof pairWaveSlotResults; selectSingleToolResult: typeof selectSingleToolResult; computeUsageForTest: typeof computeUsage; createConnectFrameParserForTest: typeof createConnectFrameParser; decompressConnectFrameForTest: typeof decompressConnectFrame; CONNECT_COMPRESSED_FLAG_FOR_TEST: number; handleInteractionUpdateForTest: typeof handleInteractionUpdate; createExecLifecycleForTest: typeof createExecLifecycle; handleToolResultResumeForTest: typeof handleToolResultResume; handleExecControlMessageForTest: typeof handleExecControlMessage; makeCancelActionBytesForTest: typeof makeCancelActionBytes; resolveNativeShellCwdForTest: typeof resolveNativeShellCwd; buildFreshToolPlanForTest: typeof buildFreshToolPlan; CODE_TOOL_NAME: string; buildCodeToolDescription: typeof buildCodeToolDescription; codeToolParameters: typeof codeToolParameters; codeDoneToMcpResultForTest: typeof codeDoneToMcpResult; portableToolCallId: typeof portableToolCallId; setProxyCodeMode: typeof setProxyCodeMode; setProxySkillsEnabled: typeof setProxySkillsEnabled; setProxyInlineRequestContext: typeof setProxyInlineRequestContext; setProxyNativePolicy: typeof setProxyNativePolicy; getEffectiveNativePolicyForTest: typeof effectiveNativePolicy; tripNativePolicyCircuitForTest: typeof tripNativePolicyCircuit; selectToolCatalogsForTest: typeof selectToolCatalogs; buildRunToolPlanForTest: (input: { tools: OpenAIToolDef[]; codeTool: OpenAIToolDef; codeMode?: boolean; nativePolicy?: CursorNativePolicy; conversationSearchEnabled?: boolean; additionalNativeRoles?: readonly NativeToolRole[]; nativeLspDiagnosticsEnabled?: boolean; }) => RunToolPlan; resolveUniqueCompatibleWriteToolForTest: typeof resolveUniqueCompatibleWriteTool; openCodeCustomSubagentsFromToolsForTest: typeof openCodeCustomSubagentsFromTools; isNativeWriteSchemaCompatibleForTest: typeof isNativeWriteSchemaCompatible; countWriteLinesCreatedForTest: typeof countWriteLinesCreated; answerPendingExecFromResultForTest: typeof answerPendingExecFromResult; answerWritePendingExecForTest: typeof answerWritePendingExec; verifyNativeWriteResultForTest: typeof verifyNativeWriteResult; NATIVE_WRITE_UNAVAILABLE_REASON: string; NATIVE_WRITE_BINARY_REJECT_REASON: string; NATIVE_WRITE_VERIFY_FAIL_PREFIX: string; CODE_ONLY_EXEC_REASON: string; nativeWriteCaptureRuntimeOptionsForTest: typeof nativeWriteCaptureRuntimeOptionsForTest; nativeTodoCaptureRuntimeOptionsForTest: typeof nativeTodoCaptureRuntimeOptionsForTest; nativeLspDiagnosticsCaptureRuntimeOptionsForTest: typeof nativeLspDiagnosticsCaptureRuntimeOptionsForTest; setToolBridgeWireObserverForTest: (observer: ((event: ToolBridgeWireEvent) => void) | undefined) => (() => void); buildNativeWritePlaneForTest: (input: { tools: OpenAIToolDef[]; nativeWriteEnabled: boolean; codeMode?: boolean; nativePolicy?: CursorNativePolicy; }) => { nativeWriteActive: boolean; compatibleWriteName: string | null; declarationNames: string[]; executionNames: string[]; nativeBindings: { [k: string]: string; }; toolControlHeaders: Record; allowedToolsHeader: string; }; constrainSkillToolsForTest: typeof constrainSkillTools; availableSkillNamesForTest: typeof availableSkillNames; getProxyCodeModeForTest: () => boolean; getProxySkillsEnabledForTest: () => boolean; getProxyInlineRequestContextForTest: () => boolean; resolveCursorClientVersionForTest: typeof resolveCursorClientVersion; SUPPORTED_CURSOR_CLIENT_VERSION_FOR_TEST: "cli-2026.07.20-8cc9c0b"; resolveCodeModeActiveForTest: typeof resolveCodeModeActive; resolveAdvertisedToolNamesForTest: typeof resolveAdvertisedToolNamesForTest; sandboxPathForTest: () => string; snapshotRuntimeForTest: typeof snapshotRuntime; resolveRuntimePathForTest: typeof resolveRuntimePath; buildMcpToolDefinitionsForTest: typeof buildMcpToolDefinitions; codeModeToolControlHeaders: typeof codeModeToolControlHeaders; normalModeToolControlHeaders: typeof normalModeToolControlHeaders; CURSOR_AGENT_ALLOWED_TOOLS_HEADER: string; CURSOR_AGENT_EXCLUDE_TOOLS_HEADER: string; CODE_MODE_ALLOWED_TOOL_CALLS: string; NORMAL_MODE_ALLOWED_TOOL_CALLS: string; getCodeModeNativeExecCountForTest: () => number; resetCodeModeNativeExecCountForTest: () => void; getExecCaseCountsForTest: () => { [k: string]: number; }; resetExecCaseCountsForTest: () => void; withDefaultBridgeHeadersForTest: typeof withDefaultBridgeHeaders; buildCursorRequestForTest(modelId: string, effort?: string | null): Uint8Array; buildCursorRequestFullForTest: (args: { modelId: string; effort?: string | null; systemPrompt?: string; userText?: string; conversationId?: string; checkpoint?: Uint8Array | null; blobStore?: Map; turnBlobMemo?: Map; protocolContext?: RunProtocolContext; workspacePath?: string; worktreePath?: string; userImages?: Array<{ data: Uint8Array; mimeType: "image/png" | "image/jpeg" | "image/webp"; }>; }) => { requestBytes: Uint8Array; blobStore: Map; }; buildRunRequestForTest(args: { modelId: string; effort?: string | null; systemPrompt: string; userText: string; turns?: Array<{ userText: string; assistantText: string; }>; conversationId: string; checkpoint?: Uint8Array | null; }): { requestBytes: Uint8Array; blobStore: Map; }; ensureStoredConversationForTest: (convKey: string) => StoredConversation; createThinkingTagFilterForTest: typeof createThinkingTagFilter; parseBridgeCloseInfoForTest: typeof parseBridgeCloseInfo; finalizeBridgeCloseWithPendingToolsForTest: typeof finalizeBridgeCloseWithPendingTools; createBridgeStreamResponseForTest: (bridge: ReturnType, heartbeatTimer: NodeJS.Timeout, blobStore: Map, mcpTools: McpToolDefinition[], modelId: string, bridgeKey: string, convKey: string, codeMode?: CodeModeCtx, respawn?: BridgeRespawn, runState?: PhysicalRunState, execLifecycle?: ExecLifecycleRegistry) => Response; frameConnectMessageForTest: typeof frameConnectMessage; buildResumeRunRequestForTest: typeof buildResumeRunRequest; buildResumeRunRequestFromPayloadForTest: typeof buildResumeRunRequestFromPayload; resolveRequestedModelForTest: typeof resolveRequestedModel; buildRunRequestWithStateForTest(args: { modelId: string; effort?: string | null; systemPrompt: string; userText: string; turns?: Array<{ userText: string; assistantText: string; }>; conversationId: string; checkpoint?: Uint8Array | null; blobStore?: Map; turnBlobMemo?: Map; mcpTools?: McpToolDefinition[]; requestContext?: RequestContext; includeInlineContext?: boolean; workspacePath?: string; worktreePath?: string; }): Pick; buildRepositoryIndexingInfo: typeof buildRepositoryIndexingInfo; isCursorOriginBackedRemoteForTest: typeof isCursorOriginBackedRemote; buildRequestContext: typeof buildRequestContext; setRequestContextTransformForTest(transform: ((context: RequestContext) => void) | undefined): () => void; resolveShellKindForTest: typeof resolveShellKind; patchCheckpointSystemIdentityForTest: typeof rebaseCheckpointSystemBlocks; rebaseCheckpointSystemBlocksForTest: typeof rebaseCheckpointSystemBlocks; parseMessages: typeof parseMessages; mergeTurnLedgerForTest: typeof mergeTurnLedger; buildCheckpointRecoveryMarkerForTest: typeof buildCheckpointRecoveryMarker; applyCheckpointRecoveryMarkerForTest: typeof applyCheckpointRecoveryMarker; evaluateCheckpointForTest: typeof evaluateCheckpoint; normalizeMcpArgsForOpenCode: typeof normalizeMcpArgsForOpenCode; knownToolParams: typeof knownToolParams; buildMcpToolDefinitions: typeof buildMcpToolDefinitions; buildToolContractsByName: typeof buildToolContractsByName; isCodeToolName: typeof isCodeToolName; normalizeWaveCall: typeof normalizeWaveCall; normalizeClientToolCall: typeof normalizeClientToolCall; catalogFromMcpTools: typeof catalogFromMcpTools; missingRequiredKeys: typeof missingRequiredKeys; formatMissingRequiredError: typeof formatMissingRequiredError; legacyNormalizeFileToolArgs: typeof legacyNormalizeFileToolArgs; argKeyList: typeof argKeyList; toolContractFromSchema: typeof toolContractFromSchema; mapAskQuestionArgsToOpenCode: typeof mapAskQuestionArgsToOpenCode; parseOpenCodeQuestionAnswers: typeof parseOpenCodeQuestionAnswers; handleInteractionQueryForTest: typeof handleInteractionQuery; sendAsyncAskQuestionCompletionForTest: typeof sendAsyncAskQuestionCompletion; handleExecMessageForTest: typeof handleExecMessage; handleWebFetchAllowlistPrecheckForTest: typeof handleWebFetchAllowlistPrecheck; rejectInteractionQueryForTest: typeof rejectInteractionQuery; NATIVE_WEB_FETCH_REJECT_REASON: string; NATIVE_GENERATE_IMAGE_REJECT_REASON: string; buildMcpResultFromToolResultForTest: typeof buildMcpResultFromToolResult; tryProjectMcpImageFromContentBlockForTest: typeof tryProjectMcpImageFromContentBlock; MCP_IMAGE_MAX_DECODED_BYTES_FOR_TEST: number; parseUserImagePartsForTest: typeof parseUserImageParts; parseMessagesForTest: (messages: OpenAIMessage[]) => ParsedMessages; setSpawnBridgeForTest(fn: ((options: SpawnBridgeOptions) => BridgeHandle) | null): void; callCursorUnaryRpcForTest: typeof callCursorUnaryRpc; detectToolResultError: typeof detectToolResultError; toolResultInfoToCodeInput: typeof toolResultInfoToCodeInput; resolveAdvertisedToolName: typeof resolveAdvertisedToolName; rekeyArgsForSchema: typeof rekeyArgsForSchema; coerceStringifiedArgs: typeof coerceStringifiedArgs; salvageTruncatedCodeInput: typeof salvageTruncatedCodeInput; salvageCodeScript: typeof salvageCodeScript; salvageExpressionReturn: typeof salvageExpressionReturn; rewriteJsonParseOnText: typeof rewriteJsonParseOnText; planScriptReroute: typeof planScriptReroute; healDirectChainCatch: typeof healDirectChainCatch; incompleteSyntaxAtEof: typeof incompleteSyntaxAtEof; incompleteScriptCoachMessage: typeof incompleteScriptCoachMessage; normalizeFilesShape: typeof normalizeFilesShape; emptyScriptCoachMessage: typeof emptyScriptCoachMessage; normalizeReadResultText: typeof normalizeReadResultText; tryHealEditArgs: typeof tryHealEditArgs; resolveShellToolName: typeof resolveShellToolName; buildWaveSlots: typeof buildWaveSlots; createPhysicalRunStateForTest: typeof createPhysicalRunState; markRunTerminalCauseForTest: typeof markRunTerminalCause; installRunCleanupOwnerForTest: (runState: PhysicalRunState, owner: { token?: string; isRetired: () => boolean; cleanup: () => void; retire?: () => void; }) => string; setStreamInactivityTimeoutForTest: (timeoutMs: number) => () => void; resolveStreamInactivityTimeoutMsForTest: typeof resolveStreamInactivityTimeoutMs; resolveClientStallTimeoutMsForTest: typeof resolveClientStallTimeoutMs; setClientStallTimeoutForTest: (timeoutMs: number) => () => void; activeCodeSessionCountForTest: () => number; insertActiveCodeSessionForTest: (key: string, lastAccessMs: number) => void; disposeCodeSessionForTest: (key: string) => void; getActiveCodeSessionForTest: (key: string) => ActiveCodeSession | undefined; tryAdmitInitialRunForTest: (convKey: string, bridgeKey: string, now?: number) => boolean; releaseRunAdmissionForTest: (convKey: string, bridgeKey?: string) => void; touchRunAdmissionForTest: (convKey: string, bridgeKey?: string, now?: number) => void; displaceParkedAdmissionOwnerForTest: typeof displaceParkedAdmissionOwner; hasRunAdmissionForTest: (convKey: string, bridgeKey?: string) => boolean; runStateForAdmissionForTest: (convKey: string) => PhysicalRunState | undefined; clearRunAdmissionsForTest: () => void; getCodeSessionPhaseForTest: (key: string) => CodeSessionPhase | undefined; setCodeSessionPhaseForTest: (key: string, phase: CodeSessionPhase) => void; /** Mirror parkExecBridge displacement: teardown the prior owner with abort. */ parkExecBridgeReplaceForTest: (bridgeKey: string, entry: Omit & { runState?: PhysicalRunState; }) => void; buildCodeWaveResponseForTest: typeof buildCodeWaveResponse; handleCodeSessionResumeForTest: typeof handleCodeSessionResume; teardownParkedBridgeForTest: typeof teardownParkedBridge; spawnBridgeLegacyForTest: typeof spawnBridgeLegacy; daemonSocketPath: () => string; daemonPidPath: () => string; daemonDisabled: () => boolean; resetDaemonClientForTest: () => void; markDaemonClientFailedForTest: (at?: number) => void; daemonClientFailedForTest: () => boolean; daemonRetryBackoffMsForTest: () => number; insertActiveBridgeForTest: (key: string, lastAccessMs: number, options?: { scope?: RequestScope; pendingIds?: string[]; convKey?: string; }) => void; activeBridgeCountForTest: () => number; /** Test-only: inspect a parked/active bridge without mutating ownership. */ getActiveBridgeForTest: (key: string) => ActiveBridge | undefined; /** Test-only: take ownership of a parked bridge entry (get + delete). */ takeActiveBridgeForTest: (key: string) => ActiveBridge | undefined; evictStaleBridgesForTest: () => void; setBridgeIdleTtlForTest: (ms: number) => (() => void); setToolCallTurnQuietMsForTest: (ms: number) => (() => void); sameRequestOwnerForTest: typeof sameRequestOwner; parkedTurnExpiredForTest: typeof parkedTurnExpired; deriveBridgeKeyForTest: (modelId: string, messages: OpenAIMessage[], userDiscriminator?: string, scope?: RequestScope) => string; deriveConversationKeyForTest: (messages: OpenAIMessage[], userDiscriminator?: string, scope?: RequestScope) => string; requestScopeForTest: (input: { contextId: string; sessionId?: string; agentId?: string; workspacePath: string; worktreePath?: string; mode?: "normal" | "code"; codeModeEnabled?: boolean; skillsEnabled?: boolean; inlineRequestContext?: boolean; nativePolicy?: CursorNativePolicy; nativeWriteEnabled?: boolean; nativeLspDiagnosticsEnabled?: boolean; generateImageEnabled?: boolean; backgroundShellEnabled?: boolean; toolResultLedger?: OpenCodeToolResultLedger; conversationSearchEnabled?: boolean; searchConversations?: NonNullable; awaitSubagent?: NonNullable; }) => RequestScope; requestScopeFromRegistrationForTest: typeof requestScopeFromRegistration; makeProxyContextRegistrationForTest: typeof makeProxyContextRegistration; getProxyContextRegistrationForTest: (contextId: string) => ProxyContextRegistration | undefined; findPendingContinuationForTest: typeof findPendingContinuation; setProxyWorkspaceOptionsForTest(options: WorkspaceContextOptions): () => void; /** Assemble post-caveman system prompt (workspace identity + reasoning guard). */ buildEffectiveSystemPromptForTest: typeof buildEffectiveSystemPrompt; setMaxConversationCapsForTest(count: number, bytes: number): () => void; insertConversationForTest(key: string, blobBytes?: number): void; conversationStatesSizeForTest: () => number; totalBlobBytesForTest: () => number; clearConversationsForTest: () => void; /** Drive one streaming AgentService/Run turn and resolve with the assistant * text, server checkpoint (if any), and end-stream error. Test/repro only. */ runCursorTurnForTest: (accessToken: string, requestBytes: Uint8Array, opts?: { timeoutMs?: number; headers?: Record; requestContext?: RequestContext; }) => Promise<{ text: string; checkpoint: Uint8Array | null; endError: Error | null; bridgeExitCode: number | null; }>; }; /** Test seam for the production shell cwd preflight. */ declare function resolveNativeShellCwd(raw: string | undefined, workspaceRoot?: string): string | undefined; /** * Project a recognized OpenCode image/file content block into McpImageContent. * Supports only explicit known shapes with inline base64 or matching data URL. * Ignores file paths, arbitrary URLs, MIME mismatches, zero-byte, and oversized media. */ declare function tryProjectMcpImageFromContentBlock(block: ToolResultContentBlock): { data: Uint8Array; mimeType: McpImageMimeType; } | null; declare function buildMcpResultFromToolResult(result: ToolResultInfo | undefined): import("./proto/agent_pb").McpResult; /** Read-only verification of the exact path OpenCode just reported writing. */ declare function verifyNativeWriteResult(resolvedPath: string, expectedText: string, _workspaceRoot: string | undefined): { ok: true; content: string; size: number; lines: number; } | { ok: false; reason: string; }; declare function answerWritePendingExec(exec: PendingExec, result: ToolResultInfo | undefined, sendFrame: (data: Uint8Array) => void, lifecycle: ExecLifecycleRegistry | undefined, fakeExecMsg: ExecServerMessage, requestScope?: RequestScope): void; declare function answerPendingExecFromResult(exec: PendingExec, result: ToolResultInfo | undefined, sendFrame: (data: Uint8Array) => void, lifecycle?: ExecLifecycleRegistry, requestScope?: RequestScope, hookAdditionalContexts?: HookAdditionalContext[]): void; declare function finalizeBridgeCloseWithPendingTools(args: { code: number; closeDetail: string; isClosed: () => boolean; bridgeKey: string; convKey: string; bridge: ReturnType; runState: PhysicalRunState; toolCallsFlushTimer: unknown; flushToolCallsNow: () => void; clearToolCallsFlush: () => void; sendSSE: (data: object) => void; sendDone: () => void; closeController: () => void; }): void; interface CodeModeCtx extends ToolCatalog { /** Real client tool names the sandbox may call via tools.X(). */ toolNames: string[]; /** Client tool docs, so codemode.describe/search answer from real bytes. */ catalog?: CodeToolCatalogEntry[]; } /** Build the single per-tool contract index from OpenAI tool defs. */ declare function buildToolContractsByName(tools: OpenAIToolDef[]): Map; /** True when the MCP tool name is the code-mode entrypoint. Cursor may echo * the bare name (`code`) or a provider-qualified form (`mcp_opencode_code`). */ declare function isCodeToolName(name: string | undefined): boolean; declare function pairToolResultsWithExecs(pendingExecs: T[], toolResults: ToolResultInfo[]): Map; /** Resume a paused bridge by sending MCP results and continuing to stream. */ declare function handleToolResultResume(active: ActiveBridge, toolResults: ToolResultInfo[], modelId: string, bridgeKey: string, convKey: string): Response; export {};