omk-ai 1.2.4 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/image-models.generated.d.ts +45 -0
- package/dist/image-models.generated.d.ts.map +1 -1
- package/dist/image-models.generated.js +45 -0
- package/dist/image-models.generated.js.map +1 -1
- package/dist/models.generated.d.ts +1509 -864
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +1215 -709
- package/dist/models.generated.js.map +1 -1
- package/dist/providers/cursor-connect.d.ts +3 -0
- package/dist/providers/cursor-connect.d.ts.map +1 -0
- package/dist/providers/cursor-connect.js +9 -0
- package/dist/providers/cursor-connect.js.map +1 -0
- package/dist/providers/cursor.d.ts.map +1 -1
- package/dist/providers/cursor.js +17 -13
- package/dist/providers/cursor.js.map +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +6 -0
- package/dist/stream.js.map +1 -1
- package/dist/utils/provider-retry-delay.d.ts +4 -0
- package/dist/utils/provider-retry-delay.d.ts.map +1 -0
- package/dist/utils/provider-retry-delay.js +53 -0
- package/dist/utils/provider-retry-delay.js.map +1 -0
- package/dist/utils/provider-retry-sleep.d.ts +6 -0
- package/dist/utils/provider-retry-sleep.d.ts.map +1 -0
- package/dist/utils/provider-retry-sleep.js +51 -0
- package/dist/utils/provider-retry-sleep.js.map +1 -0
- package/dist/utils/provider-retry.d.ts.map +1 -1
- package/dist/utils/provider-retry.js +6 -44
- package/dist/utils/provider-retry.js.map +1 -1
- package/dist/utils/retry-backoff.d.ts +8 -0
- package/dist/utils/retry-backoff.d.ts.map +1 -0
- package/dist/utils/retry-backoff.js +19 -0
- package/dist/utils/retry-backoff.js.map +1 -0
- package/dist/utils/retry.d.ts +11 -3
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +13 -5
- package/dist/utils/retry.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-connect.d.ts","sourceRoot":"","sources":["../../src/providers/cursor-connect.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,SAAI,GAAG,MAAM,CAMvE","sourcesContent":["/** Encode one Connect RPC frame for Cursor's bidirectional HTTP/2 transport. */\nexport function frameConnectMessage(data: Uint8Array, flags = 0): Buffer {\n\tconst frame = Buffer.alloc(5 + data.length);\n\tframe[0] = flags;\n\tframe.writeUInt32BE(data.length, 1);\n\tframe.set(data, 5);\n\treturn frame;\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Encode one Connect RPC frame for Cursor's bidirectional HTTP/2 transport. */
|
|
2
|
+
export function frameConnectMessage(data, flags = 0) {
|
|
3
|
+
const frame = Buffer.alloc(5 + data.length);
|
|
4
|
+
frame[0] = flags;
|
|
5
|
+
frame.writeUInt32BE(data.length, 1);
|
|
6
|
+
frame.set(data, 5);
|
|
7
|
+
return frame;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=cursor-connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-connect.js","sourceRoot":"","sources":["../../src/providers/cursor-connect.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,UAAU,mBAAmB,CAAC,IAAgB,EAAE,KAAK,GAAG,CAAC,EAAU;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACjB,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnB,OAAO,KAAK,CAAC;AAAA,CACb","sourcesContent":["/** Encode one Connect RPC frame for Cursor's bidirectional HTTP/2 transport. */\nexport function frameConnectMessage(data: Uint8Array, flags = 0): Buffer {\n\tconst frame = Buffer.alloc(5 + data.length);\n\tframe[0] = flags;\n\tframe.writeUInt32BE(data.length, 1);\n\tframe.set(data, 5);\n\treturn frame;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,KAAK,EAMX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAGb,MAAM,aAAa,CAAC;AAIrB,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AA2F9D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAejG;AA0QD,MAAM,WAAW,aAAc,SAAQ,aAAa;CAAG;AAOvD,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,cAAc,EAAE,aAAa,CAqUtE,CAAC;AAoDF,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,cAAc,EAAE,mBAAmB,CAC7C,CAAC","sourcesContent":["/**\n * Cursor subscription adapter (`cursor-agent` API).\n *\n * Implements the `agent.v1.AgentService/Run` bidirectional RPC over HTTP/2 at\n * https://api2.cursor.sh with Connect-framed protobuf, following the same\n * reverse-engineered protocol notes as the Devin adapter (see DEVIN-NOTICE).\n *\n * Turn model: each `stream()` call is one `Run` with a `userMessageAction` (or a\n * `resumeAction` when the last message is not a user turn). Conversation history\n * is replayed through `conversationState.rootPromptMessagesJson` — SHA256-keyed\n * JSON message blobs the server fetches back through the kv channel\n * (`getBlobArgs` → `getBlobResult`). System prompts ride `requestContext.rules`\n * in the exec handshake (`requestContextArgs` → `requestContextResult`).\n *\n * Scope: text and thinking deltas, token usage, blob/context/interaction\n * handshakes, and graceful rejection of tool execution frames. OMK tools are\n * intentionally not advertised in `requestContext.tools` — a frame the server\n * sends for client-side execution is answered with the protocol's `throw`\n * failure channel instead of being run unguarded inside the provider. Wiring\n * exec frames through governed OMK tools is a coding-agent bridge feature, not\n * provider scope.\n */\n\nimport { createHash } from \"node:crypto\";\nimport http2 from \"node:http2\";\nimport { getEnvApiKey } from \"../env-api-keys.ts\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tToolResultMessage,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { field, ProtoMessage } from \"./devin-protobuf.ts\";\n\nexport const CURSOR_API_URL = \"https://api2.cursor.sh\";\nexport const CURSOR_CLIENT_VERSION = \"cli-2026.02.13-41ac335\";\nconst CURSOR_RUN_PATH = \"/agent.v1.AgentService/Run\";\nconst CONNECT_END_STREAM_FLAG = 0b00000010;\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\nconst REJECTED_SUFFIX = \"not implemented by this client\";\nconst CURSOR_DEBUG = process.env.OMK_DEBUG_CURSOR === \"1\";\n\n// ---------------------------------------------------------------------------\n// Protobuf wire helpers (field numbers from the Cursor agent.v1 schema)\n// ---------------------------------------------------------------------------\n\nfunction frameConnectMessage(data: Uint8Array, flags = 0): Buffer {\n\tconst frame = Buffer.alloc(5 + data.length);\n\tframe[0] = flags;\n\tframe.writeUInt32BE(data.length, 1);\n\tframe.set(data, 5);\n\treturn frame;\n}\n\nfunction blobId(data: Uint8Array): Uint8Array {\n\treturn new Uint8Array(createHash(\"sha256\").update(data).digest());\n}\n\n/** Raw blob for pre-encoded payload bytes (system prompt JSON strings). */\nfunction rawBlob(store: Map<string, Uint8Array>, data: Uint8Array): Uint8Array {\n\tconst id = blobId(data);\n\tstore.set(Buffer.from(id).toString(\"hex\"), data);\n\treturn id;\n}\n\n/** JSON message blob for `rootPromptMessagesJson` (Vercel-AI-SDK-shaped). */\nfunction jsonBlob(store: Map<string, Uint8Array>, value: unknown): Uint8Array {\n\treturn rawBlob(store, new TextEncoder().encode(JSON.stringify(value)));\n}\n\nfunction readBlob(store: Map<string, Uint8Array>, id: Uint8Array): Uint8Array | undefined {\n\treturn store.get(Buffer.from(id).toString(\"hex\"));\n}\n\nfunction normalizeToolCallId(id: string): string {\n\tconst cleaned = id.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\treturn cleaned || crypto.randomUUID();\n}\n\nfunction normalizeCursorArgs(value: unknown, seen = new Set<object>()): unknown {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (typeof value !== \"object\" || seen.has(value)) return undefined;\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return value.map((item) => normalizeCursorArgs(item, seen) ?? null);\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tconst normalized = normalizeCursorArgs(item, seen);\n\t\t\tif (normalized !== undefined) out[key] = normalized;\n\t\t}\n\t\treturn out;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Request building\n// ---------------------------------------------------------------------------\n\nconst OPENAI_WIRE_PREFIX = /^(gpt-|composer|o\\d)/i;\n// Longest match first: `extra-high` must precede `high`, `xhigh` before `high`.\nconst EFFORT_SUFFIXES = [\"extra-high\", \"minimal\", \"xhigh\", \"medium\", \"high\", \"low\", \"max\", \"none\"] as const;\ntype CursorEffort = (typeof EFFORT_SUFFIXES)[number];\n\nfunction splitEffortSuffix(id: string): { base: string; effort?: CursorEffort; fast: boolean } {\n\tlet rest = id;\n\tlet fast = false;\n\tif (rest.endsWith(\"-fast\")) {\n\t\tfast = true;\n\t\trest = rest.slice(0, -5);\n\t}\n\tfor (const suffix of EFFORT_SUFFIXES) {\n\t\tif (rest.endsWith(`-${suffix}`)) {\n\t\t\treturn { base: rest.slice(0, -(suffix.length + 1)), effort: suffix, fast };\n\t\t}\n\t}\n\treturn { base: id, fast };\n}\n\nfunction isOpenAiFamily(id: string): boolean {\n\treturn OPENAI_WIRE_PREFIX.test(id) && !id.startsWith(\"composer\");\n}\n\n/**\n * Resolve the wire `model_id` and effort `parameters`. Cursor's Run endpoint\n * rejects effort sibling slugs for OpenAI-family ids (`resource_exhausted`);\n * the official agent splits the slug into the base id plus a `reasoning`\n * parameter. Non-OpenAI ids pass through whole. A bare `composer-2.5` pins\n * `fast=false` because the server resolves it to the Fast tier otherwise.\n */\nexport function resolveCursorWireModel(modelId: string): { modelId: string; parameters: Buffer[] } {\n\tconst { base, effort, fast } = splitEffortSuffix(modelId);\n\tif (effort !== undefined && isOpenAiFamily(base)) {\n\t\tif (effort === \"none\") return { modelId: fast ? `${base}-fast` : base, parameters: [] };\n\t\t// `extra-high` is the display suffix for the `xhigh` wire tier.\n\t\tconst wireEffort = effort === \"extra-high\" ? \"xhigh\" : effort;\n\t\treturn {\n\t\t\tmodelId: fast ? `${base}-fast` : base,\n\t\t\tparameters: [Buffer.concat([field(1, \"reasoning\"), field(2, wireEffort)])],\n\t\t};\n\t}\n\tif (modelId === \"composer-2.5\") {\n\t\treturn { modelId, parameters: [Buffer.concat([field(1, \"fast\"), field(2, \"false\")])] };\n\t}\n\treturn { modelId, parameters: [] };\n}\n\nfunction systemPromptJsons(systemPrompt: string | undefined): string[] {\n\tconst prompts = (systemPrompt ?? \"\")\n\t\t.split(/\\n{3,}/)\n\t\t.map((part) => part.trim())\n\t\t.filter(Boolean);\n\tif (prompts.length === 0) return [JSON.stringify({ role: \"system\", content: \"You are a helpful assistant.\" })];\n\treturn prompts.map((content) => JSON.stringify({ role: \"system\", content }));\n}\n\nfunction rootPromptContent(content: Message[\"content\"]): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof content === \"string\") {\n\t\tconst text = content.trim();\n\t\tif (text) parts.push({ type: \"text\", text });\n\t\treturn parts;\n\t}\n\tfor (const item of content) {\n\t\tif (item.type === \"text\") {\n\t\t\tconst text = (item as TextContent).text.trim();\n\t\t\tif (text) parts.push({ type: \"text\", text });\n\t\t} else if (item.type === \"image\") {\n\t\t\tconst image = item as ImageContent;\n\t\t\tparts.push({ type: \"image\", image: `data:${image.mimeType};base64,${image.data}`, mediaType: image.mimeType });\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction assistantContent(msg: Message, targetModelId: string): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof msg.content === \"string\") {\n\t\tif (msg.content.trim()) parts.push({ type: \"text\", text: msg.content });\n\t\treturn parts;\n\t}\n\tfor (const item of msg.content) {\n\t\tif (item.type === \"text\" && item.text) {\n\t\t\tparts.push({ type: \"text\", text: item.text });\n\t\t} else if (item.type === \"thinking\" && item.thinking) {\n\t\t\t// Replay reasoning only for blocks this provider produced for the same\n\t\t\t// wire model; foreign-provider thinking goes out unsigned and can get\n\t\t\t// the whole Run rejected.\n\t\t\tconst msgModel = (msg as AssistantMessage).model;\n\t\t\tif ((msg as AssistantMessage).provider === \"cursor\" && msgModel === targetModelId) {\n\t\t\t\tparts.push({\n\t\t\t\t\ttype: \"reasoning\",\n\t\t\t\t\ttext: item.thinking,\n\t\t\t\t\tproviderOptions: { cursor: { modelName: msgModel } },\n\t\t\t\t\t...(item.thinkingSignature ? { signature: item.thinkingSignature } : {}),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (item.type === \"toolCall\") {\n\t\t\tparts.push({\n\t\t\t\ttype: \"tool-call\",\n\t\t\t\ttoolCallId: normalizeToolCallId(item.id),\n\t\t\t\ttoolName: item.name,\n\t\t\t\targs: normalizeCursorArgs(item.arguments) ?? {},\n\t\t\t});\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction toolResultText(result: ToolResultMessage): string {\n\treturn result.content\n\t\t.map((item) => (item.type === \"text\" ? item.text : `[${(item as ImageContent).mimeType} image]`))\n\t\t.join(\"\\n\");\n}\n\nfunction buildRootPromptBlobIds(\n\tmessages: Message[],\n\tsystemPromptIds: Uint8Array[],\n\tblobStore: Map<string, Uint8Array>,\n\thistoryEnd: number,\n\ttargetModelId: string,\n): Uint8Array[] {\n\tconst ids = [...systemPromptIds];\n\tconst pairedToolCallIds = new Set<string>();\n\tfor (let i = 0; i < historyEnd; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const item of Array.isArray(msg.content) ? msg.content : []) {\n\t\t\t\tif (item.type === \"toolCall\") pairedToolCallIds.add(item.id);\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = 0; i < historyEnd && i < messages.length; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"user\") {\n\t\t\tconst content = rootPromptContent(msg.content);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"user\", content }));\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst content = assistantContent(msg, targetModelId);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"assistant\", content }));\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst result = msg as ToolResultMessage;\n\t\t\tif (!pairedToolCallIds.has(result.toolCallId)) {\n\t\t\t\tids.push(\n\t\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `${result.isError ? \"[Tool Error]\" : \"[Tool Result]\"}\\n${toolResultText(result) || \"(empty result)\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst toolCallId = normalizeToolCallId(result.toolCallId);\n\t\t\tids.push(\n\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\tid: toolCallId,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool-result\",\n\t\t\t\t\t\t\ttoolName: result.toolName,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tresult: toolResultText(result),\n\t\t\t\t\t\t\t...(result.isError ? { isError: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\treturn ids;\n}\n\nfunction userMessageProto(content: Message[\"content\"], text: string): Buffer {\n\tconst images = Array.isArray(content) ? (content.filter((c) => c.type === \"image\") as ImageContent[]) : [];\n\tconst fields = [field(1, text), field(2, crypto.randomUUID())];\n\tif (images.length > 0) {\n\t\tconst selected = images.map((image) =>\n\t\t\tBuffer.concat([\n\t\t\t\tfield(2, crypto.randomUUID()),\n\t\t\t\tfield(7, image.mimeType),\n\t\t\t\tfield(8, Buffer.from(image.data, \"base64\")),\n\t\t\t]),\n\t\t);\n\t\tfields.push(field(3, Buffer.concat(selected.map((img) => field(1, img)))));\n\t}\n\treturn Buffer.concat(fields);\n}\n\nfunction cursorRule(index: number, content: string): Buffer {\n\treturn Buffer.concat([\n\t\tfield(1, `/omk/system-prompt/${index}.mdc`),\n\t\tfield(2, content),\n\t\tfield(3, field(1, new Uint8Array(0))), // type: global {}\n\t\tfield(4, 2), // source: USER\n\t]);\n}\n\nfunction buildRequestContext(systemPrompt: string | undefined): Buffer {\n\tconst rules = systemPromptJsons(systemPrompt).map((json, index) => {\n\t\tconst content = (JSON.parse(json) as { content: string }).content;\n\t\treturn field(2, cursorRule(index, content));\n\t});\n\treturn Buffer.concat(rules);\n}\n\ninterface CursorTransportRequest {\n\tbytes: Uint8Array;\n\tblobStore: Map<string, Uint8Array>;\n}\n\nfunction buildRunRequest(\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions,\n): CursorTransportRequest {\n\tconst blobStore = new Map<string, Uint8Array>();\n\tconst systemPromptIds = systemPromptJsons(context.systemPrompt).map((json) =>\n\t\trawBlob(blobStore, new TextEncoder().encode(json)),\n\t);\n\tconst activeIndex = context.messages.length - 1;\n\tconst active = context.messages[activeIndex];\n\tconst activeUser = active && active.role === \"user\" ? active : undefined;\n\tconst userText = activeUser\n\t\t? typeof activeUser.content === \"string\"\n\t\t\t? activeUser.content.trim()\n\t\t\t: activeUser.content\n\t\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t.trim()\n\t\t: \"\";\n\tconst hasImages =\n\t\tactiveUser && Array.isArray(activeUser.content) ? activeUser.content.some((c) => c.type === \"image\") : false;\n\tconst historyEnd = activeUser ? activeIndex : context.messages.length;\n\tconst rootIds = buildRootPromptBlobIds(context.messages, systemPromptIds, blobStore, historyEnd, model.id);\n\n\tconst conversationState = Buffer.concat(rootIds.map((id) => field(1, id)));\n\tconst action =\n\t\tactiveUser && (userText.length > 0 || hasImages)\n\t\t\t? field(1, field(1, userMessageProto(activeUser.content, userText)))\n\t\t\t: field(2, new Uint8Array(0)); // resumeAction {}\n\n\tconst { modelId: wireModelId, parameters } = resolveCursorWireModel(model.id);\n\tconst maxMode = cursorMaxModeFor(model.id);\n\tconst modelDetails = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\tfield(3, model.id),\n\t\tfield(4, model.name),\n\t\t...(maxMode ? [field(7, true)] : []),\n\t]);\n\tconst requestedModel = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\t...(maxMode ? [field(2, true)] : []),\n\t\t...parameters.map((parameter) => field(3, parameter)),\n\t]);\n\n\tconst runRequest = Buffer.concat([\n\t\tfield(1, conversationState),\n\t\tfield(2, action),\n\t\tfield(3, modelDetails),\n\t\tfield(9, requestedModel),\n\t\tfield(5, options.sessionId ?? crypto.randomUUID()),\n\t]);\n\treturn { bytes: field(1, runRequest), blobStore };\n}\n\n/** Mirror the server-declared `maxMode` flag (fast Claude lanes). */\nfunction cursorMaxModeFor(modelId: string): boolean {\n\treturn /^claude-.*-fast$/.test(modelId);\n}\n\n// ---------------------------------------------------------------------------\n// Outbound client messages\n// ---------------------------------------------------------------------------\n\nfunction execClientResult(id: number, execId: string, caseNo: number, result: Buffer): Buffer {\n\tconst execMessage = Buffer.concat([field(1, id), field(15, execId), field(caseNo, result)]);\n\treturn frameConnectMessage(field(2, execMessage));\n}\n\nfunction execThrow(id: number, _execId: string, error: string): Buffer[] {\n\tconst throwMsg = field(5, Buffer.concat([field(2, Buffer.concat([field(1, id), field(2, error)]))]));\n\tconst closeMsg = field(5, field(1, field(1, id)));\n\treturn [frameConnectMessage(throwMsg), frameConnectMessage(closeMsg)];\n}\n\nfunction kvBlobResult(id: number, blobData: Uint8Array | undefined): Buffer {\n\tconst kv = Buffer.concat([field(1, id), field(2, blobData ? field(1, blobData) : new Uint8Array(0))]);\n\treturn frameConnectMessage(field(3, kv));\n}\n\nfunction kvSetBlobResult(id: number): Buffer {\n\treturn frameConnectMessage(field(3, Buffer.concat([field(1, id), field(3, new Uint8Array(0))])));\n}\n\nfunction interactionResponse(id: number, fieldNo: number, payload: Buffer): Buffer {\n\tconst response = Buffer.concat([field(1, id), field(fieldNo, payload)]);\n\treturn frameConnectMessage(field(6, response));\n}\n\n// ---------------------------------------------------------------------------\n// Stream adapter\n// ---------------------------------------------------------------------------\n\nexport interface CursorOptions extends StreamOptions {}\n\ninterface TextBlock {\n\tindex: number;\n\ttext: string;\n}\n\nexport const streamCursor: StreamFunction<\"cursor-agent\", CursorOptions> = (\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions = {},\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tcontent: [],\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\n\t(async () => {\n\t\tconst controller = new AbortController();\n\t\tconst signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;\n\t\tconst timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 600_000);\n\t\tlet h2Client: http2.ClientHttp2Session | undefined;\n\t\tlet h2Request: http2.ClientHttp2Stream | undefined;\n\t\tlet heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n\t\tlet sawTurnEnded = false;\n\t\tlet endStreamError: Error | undefined;\n\t\tconst write = (frame: Buffer | undefined) => {\n\t\t\tif (frame && h2Request && !h2Request.closed && !h2Request.destroyed) h2Request.write(frame);\n\t\t};\n\n\t\ttry {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst token = (options.apiKey ?? getEnvApiKey(\"cursor\") ?? \"\").trim();\n\t\t\tif (!token) throw new Error(\"Missing Cursor access token; run /login cursor\");\n\t\t\tconst baseUrl = (model.baseUrl || CURSOR_API_URL).replace(/\\/+$/, \"\");\n\t\t\tif (\n\t\t\t\t!/^https:\\/\\/[a-z0-9.-]*cursor\\.(sh|com|dev)(:\\d+)?$/.test(baseUrl) &&\n\t\t\t\t!/^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(baseUrl)\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Cursor subscription credentials require a *.cursor.sh/cursor.com HTTPS origin\");\n\t\t\t}\n\n\t\t\tconst built = buildRunRequest(model, context, options);\n\t\t\tconst requestContext = buildRequestContext(context.systemPrompt);\n\t\t\tconst request = await options.onPayload?.(built.bytes, model);\n\t\t\tconst payload = request === undefined ? built.bytes : request;\n\t\t\tif (!(payload instanceof Uint8Array) || new ProtoMessage(payload).messages(1).length !== 1)\n\t\t\t\tthrow new Error(\"Cursor payload hook must return protobuf bytes for a single runRequest\");\n\n\t\t\th2Client = http2.connect(baseUrl);\n\t\t\th2Client.on(\"error\", (error) => {\n\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t});\n\t\t\tconst requestHeaders = {\n\t\t\t\t\":method\": \"POST\",\n\t\t\t\t\":path\": CURSOR_RUN_PATH,\n\t\t\t\t\"content-type\": \"application/connect+proto\",\n\t\t\t\t\"connect-protocol-version\": \"1\",\n\t\t\t\tte: \"trailers\",\n\t\t\t\tauthorization: `Bearer ${token}`,\n\t\t\t\t\"x-ghost-mode\": \"true\",\n\t\t\t\t\"x-cursor-client-version\": CURSOR_CLIENT_VERSION,\n\t\t\t\t\"x-cursor-client-type\": \"cli\",\n\t\t\t\t\"x-request-id\": crypto.randomUUID(),\n\t\t\t\t...(options.headers ?? {}),\n\t\t\t};\n\t\t\th2Request = h2Client.request(requestHeaders);\n\t\t\th2Request.on(\"response\", (headers) => {\n\t\t\t\tvoid options.onResponse?.(\n\t\t\t\t\t{ status: Number(headers[\":status\"] ?? 0), headers: headers as Record<string, string> },\n\t\t\t\t\tmodel,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tlet textBlock: TextBlock | undefined;\n\t\t\tlet thinkingBlock: TextBlock | undefined;\n\t\t\tconst endText = () => {\n\t\t\t\tif (!textBlock) return;\n\t\t\t\tstream.push({ type: \"text_end\", contentIndex: textBlock.index, content: textBlock.text, partial: output });\n\t\t\t\ttextBlock = undefined;\n\t\t\t};\n\t\t\tconst endThinking = () => {\n\t\t\t\tif (!thinkingBlock) return;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: thinkingBlock.index,\n\t\t\t\t\tcontent: thinkingBlock.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\tthinkingBlock = undefined;\n\t\t\t};\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\th2Request.write(frameConnectMessage(payload));\n\t\t\theartbeatTimer = setInterval(\n\t\t\t\t() => write(frameConnectMessage(field(7, new Uint8Array(0)))),\n\t\t\t\tHEARTBEAT_INTERVAL_MS,\n\t\t\t);\n\t\t\tif (options.signal) {\n\t\t\t\toptions.signal.addEventListener(\"abort\", () => h2Request?.close(), { once: true });\n\t\t\t}\n\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tlet pending: Buffer = Buffer.alloc(0);\n\t\t\t\th2Request!.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tpending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);\n\t\t\t\t\twhile (pending.length >= 5) {\n\t\t\t\t\t\tconst flags = pending[0];\n\t\t\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\t\t\tif (length > MAX_FRAME_BYTES) {\n\t\t\t\t\t\t\tendStreamError ??= new Error(`Cursor frame exceeds ${MAX_FRAME_BYTES} bytes`);\n\t\t\t\t\t\t\th2Request?.close();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pending.length < 5 + length) break;\n\t\t\t\t\t\tconst messageBytes = pending.subarray(5, 5 + length);\n\t\t\t\t\t\tpending = pending.subarray(5 + length);\n\t\t\t\t\t\tif (flags & CONNECT_END_STREAM_FLAG) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst payload = JSON.parse(new TextDecoder().decode(messageBytes)) as {\n\t\t\t\t\t\t\t\t\terror?: { code?: string; message?: string };\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (payload.error) {\n\t\t\t\t\t\t\t\t\tendStreamError = new Error(\n\t\t\t\t\t\t\t\t\t\t`Cursor ${payload.error.code ?? \"error\"}: ${payload.error.message ?? \"unknown error\"}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tendStreamError = new Error(\"Failed to parse Cursor end-stream trailer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tdispatchServerMessage(new ProtoMessage(messageBytes));\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!endStreamError) endStreamError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"trailers\", (trailers) => {\n\t\t\t\t\tconst status = trailers[\"grpc-status\"];\n\t\t\t\t\tconst message = trailers[\"grpc-message\"];\n\t\t\t\t\tif (status && status !== \"0\") {\n\t\t\t\t\t\tendStreamError ??= new Error(\n\t\t\t\t\t\t\t`Cursor gRPC error ${status}: ${decodeURIComponent(String(message ?? \"\"))}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"end\", resolve);\n\t\t\t\th2Request!.on(\"error\", (error) => {\n\t\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"close\", resolve);\n\t\t\t});\n\n\t\t\tfunction dispatchServerMessage(message: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 7].filter((n) => message.has(n));\n\t\t\t\t\tconsole.error(`[cursor] server cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tif (message.has(1)) {\n\t\t\t\t\tfor (const update of message.messages(1)) handleInteractionUpdate(update);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(2)) {\n\t\t\t\t\tfor (const exec of message.messages(2)) handleExecMessage(exec);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(4)) {\n\t\t\t\t\tfor (const kv of message.messages(4)) {\n\t\t\t\t\t\tconst id = kv.number(1);\n\t\t\t\t\t\tfor (const getBlob of kv.messages(2)) {\n\t\t\t\t\t\t\tconst blobIdBytes = getBlob.bytes(1) ?? new Uint8Array(0);\n\t\t\t\t\t\t\tconst data = readBlob(built.blobStore, blobIdBytes);\n\t\t\t\t\t\t\tif (CURSOR_DEBUG)\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t`[cursor] kv getBlob id=${id} blob=${Buffer.from(blobIdBytes).toString(\"hex\").slice(0, 16)} found=${!!data}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twrite(kvBlobResult(id, data));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const setBlob of kv.messages(3)) {\n\t\t\t\t\t\t\tconst blobIdBytes = setBlob.bytes(1);\n\t\t\t\t\t\t\tconst blobData = setBlob.bytes(2);\n\t\t\t\t\t\t\tif (blobIdBytes && blobData) {\n\t\t\t\t\t\t\t\tbuilt.blobStore.set(Buffer.from(blobIdBytes).toString(\"hex\"), blobData);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrite(kvSetBlobResult(id));\n\t\t\t\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] kv setBlob id=${id}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(5)) {\n\t\t\t\t\t// execServerControlMessage: abort/stop signals — treat as turn end.\n\t\t\t\t\tfor (const control of message.messages(5)) {\n\t\t\t\t\t\tif (control.has(1)) sawTurnEnded = true;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(7)) {\n\t\t\t\t\tfor (const query of message.messages(7)) handleInteractionQuery(query);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionUpdate(update: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17].filter((n) => update.has(n));\n\t\t\t\t\tconsole.error(`[cursor] update cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(1)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!textBlock) {\n\t\t\t\t\t\ttextBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"text\", text: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: textBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\ttextBlock.text += text;\n\t\t\t\t\t(output.content[textBlock.index] as TextContent).text = textBlock.text;\n\t\t\t\t\tstream.push({ type: \"text_delta\", contentIndex: textBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(4)) {\n\t\t\t\t\tendText();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!thinkingBlock) {\n\t\t\t\t\t\tthinkingBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"thinking\", thinking: \"\", thinkingSignature: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: thinkingBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tthinkingBlock.text += text;\n\t\t\t\t\t(output.content[thinkingBlock.index] as { thinking: string }).thinking = thinkingBlock.text;\n\t\t\t\t\tstream.push({ type: \"thinking_delta\", contentIndex: thinkingBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const tokens of update.messages(8)) {\n\t\t\t\t\toutput.usage.output += tokens.number(1);\n\t\t\t\t}\n\t\t\t\tif (update.has(14)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tendText();\n\t\t\t\t\tsawTurnEnded = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleExecMessage(exec: ProtoMessage): void {\n\t\t\t\tconst id = exec.number(1);\n\t\t\t\tconst execId = exec.string(15);\n\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] exec id=${id} execId=${execId} case=${execCaseName(exec)}`);\n\t\t\t\tif (exec.has(10)) {\n\t\t\t\t\t// requestContextArgs — the exec handshake carrying rules/tools.\n\t\t\t\t\tconst result = field(1, field(1, requestContext));\n\t\t\t\t\twrite(execClientResult(id, execId, 10, result));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const frame of execThrow(id, execId, `Cursor ${execCaseName(exec)} execution is ${REJECTED_SUFFIX}`)) {\n\t\t\t\t\twrite(frame);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionQuery(query: ProtoMessage): void {\n\t\t\t\tconst id = query.number(1);\n\t\t\t\tconst approved = field(1, new Uint8Array(0));\n\t\t\t\tfor (const fieldNo of [2, 5, 6, 9]) {\n\t\t\t\t\tif (query.has(fieldNo)) {\n\t\t\t\t\t\twrite(interactionResponse(id, fieldNo, approved));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (query.has(3)) {\n\t\t\t\t\twrite(interactionResponse(id, 3, field(3, field(1, `Interactive questions are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(4)) {\n\t\t\t\t\twrite(interactionResponse(id, 4, field(2, field(1, `Mode switches are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(7)) {\n\t\t\t\t\t// createPlan → result{ error{ error } }\n\t\t\t\t\twrite(interactionResponse(id, 7, field(1, field(2, field(1, `Plan files are ${REJECTED_SUFFIX}`)))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// setupVmEnvironmentArgs (8) is intentionally left unanswered rather\n\t\t\t\t// than reporting a fake success.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t} finally {\n\t\t\tif (heartbeatTimer) clearInterval(heartbeatTimer);\n\t\t\t// `end()` (graceful half-close) flushes exec/throw frames still queued\n\t\t\t// behind processed data; `close()` is reserved for aborts.\n\t\t\tif (options.signal?.aborted) h2Request?.close();\n\t\t\telse h2Request?.end();\n\t\t\th2Client?.close();\n\t\t\tclearTimeout(timer);\n\t\t}\n\n\t\t// Finalize outside the try so close-flush always runs once.\n\t\ttry {\n\t\t\tif (endStreamError) throw endStreamError;\n\t\t\tif (!sawTurnEnded) {\n\t\t\t\tthrow options.signal?.aborted\n\t\t\t\t\t? Object.assign(new Error(\"aborted\"), { name: \"AbortError\" })\n\t\t\t\t\t: new Error(\"Cursor stream ended before the turn completed\");\n\t\t\t}\n\t\t\toutput.stopReason = \"stop\";\n\t\t\toutput.usage.totalTokens =\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t\tstream.push({ type: \"done\", reason: \"stop\", message: output });\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : \"Cursor request failed\";\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\tstream.end(output);\n\t\t}\n\t})();\n\treturn stream;\n};\n\nfunction execCaseName(exec: ProtoMessage): string {\n\tfor (const [no, name] of EXEC_CASE_NAMES) {\n\t\tif (exec.has(no)) return name;\n\t}\n\treturn \"exec\";\n}\n\nconst EXEC_CASE_NAMES: ReadonlyArray<readonly [number, string]> = [\n\t[2, \"shell\"],\n\t[3, \"write\"],\n\t[4, \"delete\"],\n\t[5, \"grep\"],\n\t[7, \"read\"],\n\t[8, \"ls\"],\n\t[9, \"diagnostics\"],\n\t[10, \"requestContext\"],\n\t[11, \"mcp\"],\n\t[14, \"shellStream\"],\n\t[16, \"backgroundShellSpawn\"],\n\t[17, \"listMcpResources\"],\n\t[18, \"readMcpResource\"],\n\t[20, \"fetch\"],\n\t[21, \"recordScreen\"],\n\t[22, \"computerUse\"],\n\t[23, \"writeShellStdin\"],\n\t[29, \"redactedRead\"],\n\t[36, \"mcpState\"],\n\t[27, \"executeHook\"],\n\t[28, \"subagent\"],\n\t[30, \"forceBackgroundShell\"],\n\t[31, \"forceBackgroundSubagent\"],\n\t[37, \"subagentAwait\"],\n\t[38, \"smartModeClassifier\"],\n\t[40, \"canvasDiagnostics\"],\n\t[41, \"shellAllowlistPrecheck\"],\n\t[42, \"mcpAllowlistPrecheck\"],\n\t[43, \"webFetchAllowlistPrecheck\"],\n\t[44, \"gitDiff\"],\n\t[45, \"piRead\"],\n\t[46, \"piBash\"],\n\t[47, \"piEdit\"],\n\t[48, \"piWrite\"],\n\t[49, \"piGrep\"],\n\t[50, \"piFind\"],\n\t[51, \"piLs\"],\n\t[52, \"conversationSearch\"],\n\t[54, \"agentStoreConflict\"],\n\t[56, \"miniSweAgentBash\"],\n];\n\nexport const streamSimpleCursor: StreamFunction<\"cursor-agent\", SimpleStreamOptions> = (model, context, options) =>\n\tstreamCursor(model, context, options);\n"]}
|
|
1
|
+
{"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAMH,OAAO,KAAK,EAMX,mBAAmB,EACnB,cAAc,EACd,aAAa,EAGb,MAAM,aAAa,CAAC;AAKrB,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,qBAAqB,2BAA2B,CAAC;AAmF9D;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAejG;AA0QD,MAAM,WAAW,aAAc,SAAQ,aAAa;CAAG;AAOvD,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,cAAc,EAAE,aAAa,CA4UtE,CAAC;AAoDF,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,cAAc,EAAE,mBAAmB,CAC7C,CAAC","sourcesContent":["/**\n * Cursor subscription adapter (`cursor-agent` API).\n *\n * Implements the `agent.v1.AgentService/Run` bidirectional RPC over HTTP/2 at\n * https://api2.cursor.sh with Connect-framed protobuf, following the same\n * reverse-engineered protocol notes as the Devin adapter (see DEVIN-NOTICE).\n *\n * Turn model: each `stream()` call is one `Run` with a `userMessageAction` (or a\n * `resumeAction` when the last message is not a user turn). Conversation history\n * is replayed through `conversationState.rootPromptMessagesJson` — SHA256-keyed\n * JSON message blobs the server fetches back through the kv channel\n * (`getBlobArgs` → `getBlobResult`). System prompts ride `requestContext.rules`\n * in the exec handshake (`requestContextArgs` → `requestContextResult`).\n *\n * Scope: text and thinking deltas, token usage, blob/context/interaction\n * handshakes, and graceful rejection of tool execution frames. OMK tools are\n * intentionally not advertised in `requestContext.tools` — a frame the server\n * sends for client-side execution is answered with the protocol's `throw`\n * failure channel instead of being run unguarded inside the provider. Wiring\n * exec frames through governed OMK tools is a coding-agent bridge feature, not\n * provider scope.\n */\n\nimport { createHash } from \"node:crypto\";\nimport http2 from \"node:http2\";\nimport { getEnvApiKey } from \"../env-api-keys.ts\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tToolResultMessage,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { frameConnectMessage } from \"./cursor-connect.ts\";\nimport { field, ProtoMessage } from \"./devin-protobuf.ts\";\n\nexport const CURSOR_API_URL = \"https://api2.cursor.sh\";\nexport const CURSOR_CLIENT_VERSION = \"cli-2026.02.13-41ac335\";\nconst CURSOR_RUN_PATH = \"/agent.v1.AgentService/Run\";\nconst CONNECT_END_STREAM_FLAG = 0b00000010;\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\nconst REJECTED_SUFFIX = \"not implemented by this client\";\nconst CURSOR_DEBUG = process.env.OMK_DEBUG_CURSOR === \"1\";\n\n// ---------------------------------------------------------------------------\n// Protobuf wire helpers (field numbers from the Cursor agent.v1 schema)\n// ---------------------------------------------------------------------------\n\nfunction blobId(data: Uint8Array): Uint8Array {\n\treturn new Uint8Array(createHash(\"sha256\").update(data).digest());\n}\n\n/** Raw blob for pre-encoded payload bytes (system prompt JSON strings). */\nfunction rawBlob(store: Map<string, Uint8Array>, data: Uint8Array): Uint8Array {\n\tconst id = blobId(data);\n\tstore.set(Buffer.from(id).toString(\"hex\"), data);\n\treturn id;\n}\n\n/** JSON message blob for `rootPromptMessagesJson` (Vercel-AI-SDK-shaped). */\nfunction jsonBlob(store: Map<string, Uint8Array>, value: unknown): Uint8Array {\n\treturn rawBlob(store, new TextEncoder().encode(JSON.stringify(value)));\n}\n\nfunction readBlob(store: Map<string, Uint8Array>, id: Uint8Array): Uint8Array | undefined {\n\treturn store.get(Buffer.from(id).toString(\"hex\"));\n}\n\nfunction normalizeToolCallId(id: string): string {\n\tconst cleaned = id.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\treturn cleaned || crypto.randomUUID();\n}\n\nfunction normalizeCursorArgs(value: unknown, seen = new Set<object>()): unknown {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (typeof value !== \"object\" || seen.has(value)) return undefined;\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return value.map((item) => normalizeCursorArgs(item, seen) ?? null);\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tconst normalized = normalizeCursorArgs(item, seen);\n\t\t\tif (normalized !== undefined) out[key] = normalized;\n\t\t}\n\t\treturn out;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Request building\n// ---------------------------------------------------------------------------\n\nconst OPENAI_WIRE_PREFIX = /^(gpt-|composer|o\\d)/i;\n// Longest match first: `extra-high` must precede `high`, `xhigh` before `high`.\nconst EFFORT_SUFFIXES = [\"extra-high\", \"minimal\", \"xhigh\", \"medium\", \"high\", \"low\", \"max\", \"none\"] as const;\ntype CursorEffort = (typeof EFFORT_SUFFIXES)[number];\n\nfunction splitEffortSuffix(id: string): { base: string; effort?: CursorEffort; fast: boolean } {\n\tlet rest = id;\n\tlet fast = false;\n\tif (rest.endsWith(\"-fast\")) {\n\t\tfast = true;\n\t\trest = rest.slice(0, -5);\n\t}\n\tfor (const suffix of EFFORT_SUFFIXES) {\n\t\tif (rest.endsWith(`-${suffix}`)) {\n\t\t\treturn { base: rest.slice(0, -(suffix.length + 1)), effort: suffix, fast };\n\t\t}\n\t}\n\treturn { base: id, fast };\n}\n\nfunction isOpenAiFamily(id: string): boolean {\n\treturn OPENAI_WIRE_PREFIX.test(id) && !id.startsWith(\"composer\");\n}\n\n/**\n * Resolve the wire `model_id` and effort `parameters`. Cursor's Run endpoint\n * rejects effort sibling slugs for OpenAI-family ids (`resource_exhausted`);\n * the official agent splits the slug into the base id plus a `reasoning`\n * parameter. Non-OpenAI ids pass through whole. A bare `composer-2.5` pins\n * `fast=false` because the server resolves it to the Fast tier otherwise.\n */\nexport function resolveCursorWireModel(modelId: string): { modelId: string; parameters: Buffer[] } {\n\tconst { base, effort, fast } = splitEffortSuffix(modelId);\n\tif (effort !== undefined && isOpenAiFamily(base)) {\n\t\tif (effort === \"none\") return { modelId: fast ? `${base}-fast` : base, parameters: [] };\n\t\t// `extra-high` is the display suffix for the `xhigh` wire tier.\n\t\tconst wireEffort = effort === \"extra-high\" ? \"xhigh\" : effort;\n\t\treturn {\n\t\t\tmodelId: fast ? `${base}-fast` : base,\n\t\t\tparameters: [Buffer.concat([field(1, \"reasoning\"), field(2, wireEffort)])],\n\t\t};\n\t}\n\tif (modelId === \"composer-2.5\") {\n\t\treturn { modelId, parameters: [Buffer.concat([field(1, \"fast\"), field(2, \"false\")])] };\n\t}\n\treturn { modelId, parameters: [] };\n}\n\nfunction systemPromptJsons(systemPrompt: string | undefined): string[] {\n\tconst prompts = (systemPrompt ?? \"\")\n\t\t.split(/\\n{3,}/)\n\t\t.map((part) => part.trim())\n\t\t.filter(Boolean);\n\tif (prompts.length === 0) return [JSON.stringify({ role: \"system\", content: \"You are a helpful assistant.\" })];\n\treturn prompts.map((content) => JSON.stringify({ role: \"system\", content }));\n}\n\nfunction rootPromptContent(content: Message[\"content\"]): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof content === \"string\") {\n\t\tconst text = content.trim();\n\t\tif (text) parts.push({ type: \"text\", text });\n\t\treturn parts;\n\t}\n\tfor (const item of content) {\n\t\tif (item.type === \"text\") {\n\t\t\tconst text = (item as TextContent).text.trim();\n\t\t\tif (text) parts.push({ type: \"text\", text });\n\t\t} else if (item.type === \"image\") {\n\t\t\tconst image = item as ImageContent;\n\t\t\tparts.push({ type: \"image\", image: `data:${image.mimeType};base64,${image.data}`, mediaType: image.mimeType });\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction assistantContent(msg: Message, targetModelId: string): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof msg.content === \"string\") {\n\t\tif (msg.content.trim()) parts.push({ type: \"text\", text: msg.content });\n\t\treturn parts;\n\t}\n\tfor (const item of msg.content) {\n\t\tif (item.type === \"text\" && item.text) {\n\t\t\tparts.push({ type: \"text\", text: item.text });\n\t\t} else if (item.type === \"thinking\" && item.thinking) {\n\t\t\t// Replay reasoning only for blocks this provider produced for the same\n\t\t\t// wire model; foreign-provider thinking goes out unsigned and can get\n\t\t\t// the whole Run rejected.\n\t\t\tconst msgModel = (msg as AssistantMessage).model;\n\t\t\tif ((msg as AssistantMessage).provider === \"cursor\" && msgModel === targetModelId) {\n\t\t\t\tparts.push({\n\t\t\t\t\ttype: \"reasoning\",\n\t\t\t\t\ttext: item.thinking,\n\t\t\t\t\tproviderOptions: { cursor: { modelName: msgModel } },\n\t\t\t\t\t...(item.thinkingSignature ? { signature: item.thinkingSignature } : {}),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (item.type === \"toolCall\") {\n\t\t\tparts.push({\n\t\t\t\ttype: \"tool-call\",\n\t\t\t\ttoolCallId: normalizeToolCallId(item.id),\n\t\t\t\ttoolName: item.name,\n\t\t\t\targs: normalizeCursorArgs(item.arguments) ?? {},\n\t\t\t});\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction toolResultText(result: ToolResultMessage): string {\n\treturn result.content\n\t\t.map((item) => (item.type === \"text\" ? item.text : `[${(item as ImageContent).mimeType} image]`))\n\t\t.join(\"\\n\");\n}\n\nfunction buildRootPromptBlobIds(\n\tmessages: Message[],\n\tsystemPromptIds: Uint8Array[],\n\tblobStore: Map<string, Uint8Array>,\n\thistoryEnd: number,\n\ttargetModelId: string,\n): Uint8Array[] {\n\tconst ids = [...systemPromptIds];\n\tconst pairedToolCallIds = new Set<string>();\n\tfor (let i = 0; i < historyEnd; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const item of Array.isArray(msg.content) ? msg.content : []) {\n\t\t\t\tif (item.type === \"toolCall\") pairedToolCallIds.add(item.id);\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = 0; i < historyEnd && i < messages.length; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"user\") {\n\t\t\tconst content = rootPromptContent(msg.content);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"user\", content }));\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst content = assistantContent(msg, targetModelId);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"assistant\", content }));\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst result = msg as ToolResultMessage;\n\t\t\tif (!pairedToolCallIds.has(result.toolCallId)) {\n\t\t\t\tids.push(\n\t\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `${result.isError ? \"[Tool Error]\" : \"[Tool Result]\"}\\n${toolResultText(result) || \"(empty result)\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst toolCallId = normalizeToolCallId(result.toolCallId);\n\t\t\tids.push(\n\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\tid: toolCallId,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool-result\",\n\t\t\t\t\t\t\ttoolName: result.toolName,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tresult: toolResultText(result),\n\t\t\t\t\t\t\t...(result.isError ? { isError: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\treturn ids;\n}\n\nfunction userMessageProto(content: Message[\"content\"], text: string): Buffer {\n\tconst images = Array.isArray(content) ? (content.filter((c) => c.type === \"image\") as ImageContent[]) : [];\n\tconst fields = [field(1, text), field(2, crypto.randomUUID())];\n\tif (images.length > 0) {\n\t\tconst selected = images.map((image) =>\n\t\t\tBuffer.concat([\n\t\t\t\tfield(2, crypto.randomUUID()),\n\t\t\t\tfield(7, image.mimeType),\n\t\t\t\tfield(8, Buffer.from(image.data, \"base64\")),\n\t\t\t]),\n\t\t);\n\t\tfields.push(field(3, Buffer.concat(selected.map((img) => field(1, img)))));\n\t}\n\treturn Buffer.concat(fields);\n}\n\nfunction cursorRule(index: number, content: string): Buffer {\n\treturn Buffer.concat([\n\t\tfield(1, `/omk/system-prompt/${index}.mdc`),\n\t\tfield(2, content),\n\t\tfield(3, field(1, new Uint8Array(0))), // type: global {}\n\t\tfield(4, 2), // source: USER\n\t]);\n}\n\nfunction buildRequestContext(systemPrompt: string | undefined): Buffer {\n\tconst rules = systemPromptJsons(systemPrompt).map((json, index) => {\n\t\tconst content = (JSON.parse(json) as { content: string }).content;\n\t\treturn field(2, cursorRule(index, content));\n\t});\n\treturn Buffer.concat(rules);\n}\n\ninterface CursorTransportRequest {\n\tbytes: Uint8Array;\n\tblobStore: Map<string, Uint8Array>;\n}\n\nfunction buildRunRequest(\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions,\n): CursorTransportRequest {\n\tconst blobStore = new Map<string, Uint8Array>();\n\tconst systemPromptIds = systemPromptJsons(context.systemPrompt).map((json) =>\n\t\trawBlob(blobStore, new TextEncoder().encode(json)),\n\t);\n\tconst activeIndex = context.messages.length - 1;\n\tconst active = context.messages[activeIndex];\n\tconst activeUser = active && active.role === \"user\" ? active : undefined;\n\tconst userText = activeUser\n\t\t? typeof activeUser.content === \"string\"\n\t\t\t? activeUser.content.trim()\n\t\t\t: activeUser.content\n\t\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t.trim()\n\t\t: \"\";\n\tconst hasImages =\n\t\tactiveUser && Array.isArray(activeUser.content) ? activeUser.content.some((c) => c.type === \"image\") : false;\n\tconst historyEnd = activeUser ? activeIndex : context.messages.length;\n\tconst rootIds = buildRootPromptBlobIds(context.messages, systemPromptIds, blobStore, historyEnd, model.id);\n\n\tconst conversationState = Buffer.concat(rootIds.map((id) => field(1, id)));\n\tconst action =\n\t\tactiveUser && (userText.length > 0 || hasImages)\n\t\t\t? field(1, field(1, userMessageProto(activeUser.content, userText)))\n\t\t\t: field(2, new Uint8Array(0)); // resumeAction {}\n\n\tconst { modelId: wireModelId, parameters } = resolveCursorWireModel(model.id);\n\tconst maxMode = cursorMaxModeFor(model.id);\n\tconst modelDetails = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\tfield(3, model.id),\n\t\tfield(4, model.name),\n\t\t...(maxMode ? [field(7, true)] : []),\n\t]);\n\tconst requestedModel = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\t...(maxMode ? [field(2, true)] : []),\n\t\t...parameters.map((parameter) => field(3, parameter)),\n\t]);\n\n\tconst runRequest = Buffer.concat([\n\t\tfield(1, conversationState),\n\t\tfield(2, action),\n\t\tfield(3, modelDetails),\n\t\tfield(9, requestedModel),\n\t\tfield(5, options.sessionId ?? crypto.randomUUID()),\n\t]);\n\treturn { bytes: field(1, runRequest), blobStore };\n}\n\n/** Mirror the server-declared `maxMode` flag (fast Claude lanes). */\nfunction cursorMaxModeFor(modelId: string): boolean {\n\treturn /^claude-.*-fast$/.test(modelId);\n}\n\n// ---------------------------------------------------------------------------\n// Outbound client messages\n// ---------------------------------------------------------------------------\n\nfunction execClientResult(id: number, execId: string, caseNo: number, result: Buffer): Buffer {\n\tconst execMessage = Buffer.concat([field(1, id), field(15, execId), field(caseNo, result)]);\n\treturn frameConnectMessage(field(2, execMessage));\n}\n\nfunction execThrow(id: number, _execId: string, error: string): Buffer[] {\n\tconst throwMsg = field(5, Buffer.concat([field(2, Buffer.concat([field(1, id), field(2, error)]))]));\n\tconst closeMsg = field(5, field(1, field(1, id)));\n\treturn [frameConnectMessage(throwMsg), frameConnectMessage(closeMsg)];\n}\n\nfunction kvBlobResult(id: number, blobData: Uint8Array | undefined): Buffer {\n\tconst kv = Buffer.concat([field(1, id), field(2, blobData ? field(1, blobData) : new Uint8Array(0))]);\n\treturn frameConnectMessage(field(3, kv));\n}\n\nfunction kvSetBlobResult(id: number): Buffer {\n\treturn frameConnectMessage(field(3, Buffer.concat([field(1, id), field(3, new Uint8Array(0))])));\n}\n\nfunction interactionResponse(id: number, fieldNo: number, payload: Buffer): Buffer {\n\tconst response = Buffer.concat([field(1, id), field(fieldNo, payload)]);\n\treturn frameConnectMessage(field(6, response));\n}\n\n// ---------------------------------------------------------------------------\n// Stream adapter\n// ---------------------------------------------------------------------------\n\nexport interface CursorOptions extends StreamOptions {}\n\ninterface TextBlock {\n\tindex: number;\n\ttext: string;\n}\n\nexport const streamCursor: StreamFunction<\"cursor-agent\", CursorOptions> = (\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions = {},\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tcontent: [],\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\n\t(async () => {\n\t\tconst controller = new AbortController();\n\t\tconst signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;\n\t\tconst timeoutMs = options.timeoutMs ?? 600_000;\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\tlet h2Client: http2.ClientHttp2Session | undefined;\n\t\tlet h2Request: http2.ClientHttp2Stream | undefined;\n\t\tlet heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n\t\tlet sawTurnEnded = false;\n\t\tlet endStreamError: Error | undefined;\n\t\t// Close on the combined signal so the internal deadline also ends a silent peer.\n\t\t// The deadline is a request error; a caller abort keeps the aborted result.\n\t\tconst onAbort = () => {\n\t\t\tif (controller.signal.aborted) endStreamError ??= new Error(`Cursor timed out after ${timeoutMs}ms`);\n\t\t\th2Request?.close();\n\t\t};\n\t\tconst write = (frame: Buffer | undefined) => {\n\t\t\tif (frame && h2Request && !h2Request.closed && !h2Request.destroyed) h2Request.write(frame);\n\t\t};\n\n\t\ttry {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst token = (options.apiKey ?? getEnvApiKey(\"cursor\") ?? \"\").trim();\n\t\t\tif (!token) throw new Error(\"Missing Cursor access token; run /login cursor\");\n\t\t\tconst baseUrl = (model.baseUrl || CURSOR_API_URL).replace(/\\/+$/, \"\");\n\t\t\tif (\n\t\t\t\t!/^https:\\/\\/[a-z0-9.-]*cursor\\.(sh|com|dev)(:\\d+)?$/.test(baseUrl) &&\n\t\t\t\t!/^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(baseUrl)\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Cursor subscription credentials require a *.cursor.sh/cursor.com HTTPS origin\");\n\t\t\t}\n\n\t\t\tconst built = buildRunRequest(model, context, options);\n\t\t\tconst requestContext = buildRequestContext(context.systemPrompt);\n\t\t\tconst request = await options.onPayload?.(built.bytes, model);\n\t\t\tconst payload = request === undefined ? built.bytes : request;\n\t\t\tif (!(payload instanceof Uint8Array) || new ProtoMessage(payload).messages(1).length !== 1)\n\t\t\t\tthrow new Error(\"Cursor payload hook must return protobuf bytes for a single runRequest\");\n\t\t\tsignal.throwIfAborted();\n\n\t\t\th2Client = http2.connect(baseUrl);\n\t\t\th2Client.on(\"error\", (error) => {\n\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t});\n\t\t\tconst requestHeaders = {\n\t\t\t\t\":method\": \"POST\",\n\t\t\t\t\":path\": CURSOR_RUN_PATH,\n\t\t\t\t\"content-type\": \"application/connect+proto\",\n\t\t\t\t\"connect-protocol-version\": \"1\",\n\t\t\t\tte: \"trailers\",\n\t\t\t\tauthorization: `Bearer ${token}`,\n\t\t\t\t\"x-ghost-mode\": \"true\",\n\t\t\t\t\"x-cursor-client-version\": CURSOR_CLIENT_VERSION,\n\t\t\t\t\"x-cursor-client-type\": \"cli\",\n\t\t\t\t\"x-request-id\": crypto.randomUUID(),\n\t\t\t\t...(options.headers ?? {}),\n\t\t\t};\n\t\t\th2Request = h2Client.request(requestHeaders);\n\t\t\th2Request.on(\"response\", (headers) => {\n\t\t\t\tvoid options.onResponse?.(\n\t\t\t\t\t{ status: Number(headers[\":status\"] ?? 0), headers: headers as Record<string, string> },\n\t\t\t\t\tmodel,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tlet textBlock: TextBlock | undefined;\n\t\t\tlet thinkingBlock: TextBlock | undefined;\n\t\t\tconst endText = () => {\n\t\t\t\tif (!textBlock) return;\n\t\t\t\tstream.push({ type: \"text_end\", contentIndex: textBlock.index, content: textBlock.text, partial: output });\n\t\t\t\ttextBlock = undefined;\n\t\t\t};\n\t\t\tconst endThinking = () => {\n\t\t\t\tif (!thinkingBlock) return;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: thinkingBlock.index,\n\t\t\t\t\tcontent: thinkingBlock.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\tthinkingBlock = undefined;\n\t\t\t};\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\th2Request.write(frameConnectMessage(payload));\n\t\t\theartbeatTimer = setInterval(\n\t\t\t\t() => write(frameConnectMessage(field(7, new Uint8Array(0)))),\n\t\t\t\tHEARTBEAT_INTERVAL_MS,\n\t\t\t);\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tlet pending: Buffer = Buffer.alloc(0);\n\t\t\t\th2Request!.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tpending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);\n\t\t\t\t\twhile (pending.length >= 5) {\n\t\t\t\t\t\tconst flags = pending[0];\n\t\t\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\t\t\tif (length > MAX_FRAME_BYTES) {\n\t\t\t\t\t\t\tendStreamError ??= new Error(`Cursor frame exceeds ${MAX_FRAME_BYTES} bytes`);\n\t\t\t\t\t\t\th2Request?.close();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pending.length < 5 + length) break;\n\t\t\t\t\t\tconst messageBytes = pending.subarray(5, 5 + length);\n\t\t\t\t\t\tpending = pending.subarray(5 + length);\n\t\t\t\t\t\tif (flags & CONNECT_END_STREAM_FLAG) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst payload = JSON.parse(new TextDecoder().decode(messageBytes)) as {\n\t\t\t\t\t\t\t\t\terror?: { code?: string; message?: string };\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (payload.error) {\n\t\t\t\t\t\t\t\t\tendStreamError = new Error(\n\t\t\t\t\t\t\t\t\t\t`Cursor ${payload.error.code ?? \"error\"}: ${payload.error.message ?? \"unknown error\"}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tendStreamError = new Error(\"Failed to parse Cursor end-stream trailer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tdispatchServerMessage(new ProtoMessage(messageBytes));\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!endStreamError) endStreamError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"trailers\", (trailers) => {\n\t\t\t\t\tconst status = trailers[\"grpc-status\"];\n\t\t\t\t\tconst message = trailers[\"grpc-message\"];\n\t\t\t\t\tif (status && status !== \"0\") {\n\t\t\t\t\t\tendStreamError ??= new Error(\n\t\t\t\t\t\t\t`Cursor gRPC error ${status}: ${decodeURIComponent(String(message ?? \"\"))}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"end\", resolve);\n\t\t\t\th2Request!.on(\"error\", (error) => {\n\t\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"close\", resolve);\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t});\n\n\t\t\tfunction dispatchServerMessage(message: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 7].filter((n) => message.has(n));\n\t\t\t\t\tconsole.error(`[cursor] server cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tif (message.has(1)) {\n\t\t\t\t\tfor (const update of message.messages(1)) handleInteractionUpdate(update);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(2)) {\n\t\t\t\t\tfor (const exec of message.messages(2)) handleExecMessage(exec);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(4)) {\n\t\t\t\t\tfor (const kv of message.messages(4)) {\n\t\t\t\t\t\tconst id = kv.number(1);\n\t\t\t\t\t\tfor (const getBlob of kv.messages(2)) {\n\t\t\t\t\t\t\tconst blobIdBytes = getBlob.bytes(1) ?? new Uint8Array(0);\n\t\t\t\t\t\t\tconst data = readBlob(built.blobStore, blobIdBytes);\n\t\t\t\t\t\t\tif (CURSOR_DEBUG)\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t`[cursor] kv getBlob id=${id} blob=${Buffer.from(blobIdBytes).toString(\"hex\").slice(0, 16)} found=${!!data}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twrite(kvBlobResult(id, data));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const setBlob of kv.messages(3)) {\n\t\t\t\t\t\t\tconst blobIdBytes = setBlob.bytes(1);\n\t\t\t\t\t\t\tconst blobData = setBlob.bytes(2);\n\t\t\t\t\t\t\tif (blobIdBytes && blobData) {\n\t\t\t\t\t\t\t\tbuilt.blobStore.set(Buffer.from(blobIdBytes).toString(\"hex\"), blobData);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrite(kvSetBlobResult(id));\n\t\t\t\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] kv setBlob id=${id}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(5)) {\n\t\t\t\t\t// execServerControlMessage: abort/stop signals — treat as turn end.\n\t\t\t\t\tfor (const control of message.messages(5)) {\n\t\t\t\t\t\tif (control.has(1)) sawTurnEnded = true;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(7)) {\n\t\t\t\t\tfor (const query of message.messages(7)) handleInteractionQuery(query);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionUpdate(update: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17].filter((n) => update.has(n));\n\t\t\t\t\tconsole.error(`[cursor] update cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(1)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!textBlock) {\n\t\t\t\t\t\ttextBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"text\", text: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: textBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\ttextBlock.text += text;\n\t\t\t\t\t(output.content[textBlock.index] as TextContent).text = textBlock.text;\n\t\t\t\t\tstream.push({ type: \"text_delta\", contentIndex: textBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(4)) {\n\t\t\t\t\tendText();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!thinkingBlock) {\n\t\t\t\t\t\tthinkingBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"thinking\", thinking: \"\", thinkingSignature: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: thinkingBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tthinkingBlock.text += text;\n\t\t\t\t\t(output.content[thinkingBlock.index] as { thinking: string }).thinking = thinkingBlock.text;\n\t\t\t\t\tstream.push({ type: \"thinking_delta\", contentIndex: thinkingBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const tokens of update.messages(8)) {\n\t\t\t\t\toutput.usage.output += tokens.number(1);\n\t\t\t\t}\n\t\t\t\tif (update.has(14)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tendText();\n\t\t\t\t\tsawTurnEnded = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleExecMessage(exec: ProtoMessage): void {\n\t\t\t\tconst id = exec.number(1);\n\t\t\t\tconst execId = exec.string(15);\n\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] exec id=${id} execId=${execId} case=${execCaseName(exec)}`);\n\t\t\t\tif (exec.has(10)) {\n\t\t\t\t\t// requestContextArgs — the exec handshake carrying rules/tools.\n\t\t\t\t\tconst result = field(1, field(1, requestContext));\n\t\t\t\t\twrite(execClientResult(id, execId, 10, result));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const frame of execThrow(id, execId, `Cursor ${execCaseName(exec)} execution is ${REJECTED_SUFFIX}`)) {\n\t\t\t\t\twrite(frame);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionQuery(query: ProtoMessage): void {\n\t\t\t\tconst id = query.number(1);\n\t\t\t\tconst approved = field(1, new Uint8Array(0));\n\t\t\t\tfor (const fieldNo of [2, 5, 6, 9]) {\n\t\t\t\t\tif (query.has(fieldNo)) {\n\t\t\t\t\t\twrite(interactionResponse(id, fieldNo, approved));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (query.has(3)) {\n\t\t\t\t\twrite(interactionResponse(id, 3, field(3, field(1, `Interactive questions are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(4)) {\n\t\t\t\t\twrite(interactionResponse(id, 4, field(2, field(1, `Mode switches are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(7)) {\n\t\t\t\t\t// createPlan → result{ error{ error } }\n\t\t\t\t\twrite(interactionResponse(id, 7, field(1, field(2, field(1, `Plan files are ${REJECTED_SUFFIX}`)))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// setupVmEnvironmentArgs (8) is intentionally left unanswered rather\n\t\t\t\t// than reporting a fake success.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t} finally {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tif (heartbeatTimer) clearInterval(heartbeatTimer);\n\t\t\t// `end()` (graceful half-close) flushes exec/throw frames still queued\n\t\t\t// behind processed data; `close()` is reserved for aborts and the deadline.\n\t\t\tif (signal.aborted) h2Request?.close();\n\t\t\telse h2Request?.end();\n\t\t\th2Client?.close();\n\t\t\tclearTimeout(timer);\n\t\t}\n\n\t\t// Finalize outside the try so close-flush always runs once.\n\t\ttry {\n\t\t\tif (endStreamError) throw endStreamError;\n\t\t\tif (!sawTurnEnded) {\n\t\t\t\tthrow options.signal?.aborted\n\t\t\t\t\t? Object.assign(new Error(\"aborted\"), { name: \"AbortError\" })\n\t\t\t\t\t: new Error(\"Cursor stream ended before the turn completed\");\n\t\t\t}\n\t\t\toutput.stopReason = \"stop\";\n\t\t\toutput.usage.totalTokens =\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t\tstream.push({ type: \"done\", reason: \"stop\", message: output });\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : \"Cursor request failed\";\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\tstream.end(output);\n\t\t}\n\t})();\n\treturn stream;\n};\n\nfunction execCaseName(exec: ProtoMessage): string {\n\tfor (const [no, name] of EXEC_CASE_NAMES) {\n\t\tif (exec.has(no)) return name;\n\t}\n\treturn \"exec\";\n}\n\nconst EXEC_CASE_NAMES: ReadonlyArray<readonly [number, string]> = [\n\t[2, \"shell\"],\n\t[3, \"write\"],\n\t[4, \"delete\"],\n\t[5, \"grep\"],\n\t[7, \"read\"],\n\t[8, \"ls\"],\n\t[9, \"diagnostics\"],\n\t[10, \"requestContext\"],\n\t[11, \"mcp\"],\n\t[14, \"shellStream\"],\n\t[16, \"backgroundShellSpawn\"],\n\t[17, \"listMcpResources\"],\n\t[18, \"readMcpResource\"],\n\t[20, \"fetch\"],\n\t[21, \"recordScreen\"],\n\t[22, \"computerUse\"],\n\t[23, \"writeShellStdin\"],\n\t[29, \"redactedRead\"],\n\t[36, \"mcpState\"],\n\t[27, \"executeHook\"],\n\t[28, \"subagent\"],\n\t[30, \"forceBackgroundShell\"],\n\t[31, \"forceBackgroundSubagent\"],\n\t[37, \"subagentAwait\"],\n\t[38, \"smartModeClassifier\"],\n\t[40, \"canvasDiagnostics\"],\n\t[41, \"shellAllowlistPrecheck\"],\n\t[42, \"mcpAllowlistPrecheck\"],\n\t[43, \"webFetchAllowlistPrecheck\"],\n\t[44, \"gitDiff\"],\n\t[45, \"piRead\"],\n\t[46, \"piBash\"],\n\t[47, \"piEdit\"],\n\t[48, \"piWrite\"],\n\t[49, \"piGrep\"],\n\t[50, \"piFind\"],\n\t[51, \"piLs\"],\n\t[52, \"conversationSearch\"],\n\t[54, \"agentStoreConflict\"],\n\t[56, \"miniSweAgentBash\"],\n];\n\nexport const streamSimpleCursor: StreamFunction<\"cursor-agent\", SimpleStreamOptions> = (model, context, options) =>\n\tstreamCursor(model, context, options);\n"]}
|
package/dist/providers/cursor.js
CHANGED
|
@@ -25,6 +25,7 @@ import http2 from "node:http2";
|
|
|
25
25
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
26
26
|
import { calculateCost } from "../models.js";
|
|
27
27
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
28
|
+
import { frameConnectMessage } from "./cursor-connect.js";
|
|
28
29
|
import { field, ProtoMessage } from "./devin-protobuf.js";
|
|
29
30
|
export const CURSOR_API_URL = "https://api2.cursor.sh";
|
|
30
31
|
export const CURSOR_CLIENT_VERSION = "cli-2026.02.13-41ac335";
|
|
@@ -37,13 +38,6 @@ const CURSOR_DEBUG = process.env.OMK_DEBUG_CURSOR === "1";
|
|
|
37
38
|
// ---------------------------------------------------------------------------
|
|
38
39
|
// Protobuf wire helpers (field numbers from the Cursor agent.v1 schema)
|
|
39
40
|
// ---------------------------------------------------------------------------
|
|
40
|
-
function frameConnectMessage(data, flags = 0) {
|
|
41
|
-
const frame = Buffer.alloc(5 + data.length);
|
|
42
|
-
frame[0] = flags;
|
|
43
|
-
frame.writeUInt32BE(data.length, 1);
|
|
44
|
-
frame.set(data, 5);
|
|
45
|
-
return frame;
|
|
46
|
-
}
|
|
47
41
|
function blobId(data) {
|
|
48
42
|
return new Uint8Array(createHash("sha256").update(data).digest());
|
|
49
43
|
}
|
|
@@ -384,12 +378,20 @@ export const streamCursor = (model, context, options = {}) => {
|
|
|
384
378
|
(async () => {
|
|
385
379
|
const controller = new AbortController();
|
|
386
380
|
const signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;
|
|
387
|
-
const
|
|
381
|
+
const timeoutMs = options.timeoutMs ?? 600_000;
|
|
382
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
388
383
|
let h2Client;
|
|
389
384
|
let h2Request;
|
|
390
385
|
let heartbeatTimer;
|
|
391
386
|
let sawTurnEnded = false;
|
|
392
387
|
let endStreamError;
|
|
388
|
+
// Close on the combined signal so the internal deadline also ends a silent peer.
|
|
389
|
+
// The deadline is a request error; a caller abort keeps the aborted result.
|
|
390
|
+
const onAbort = () => {
|
|
391
|
+
if (controller.signal.aborted)
|
|
392
|
+
endStreamError ??= new Error(`Cursor timed out after ${timeoutMs}ms`);
|
|
393
|
+
h2Request?.close();
|
|
394
|
+
};
|
|
393
395
|
const write = (frame) => {
|
|
394
396
|
if (frame && h2Request && !h2Request.closed && !h2Request.destroyed)
|
|
395
397
|
h2Request.write(frame);
|
|
@@ -410,6 +412,7 @@ export const streamCursor = (model, context, options = {}) => {
|
|
|
410
412
|
const payload = request === undefined ? built.bytes : request;
|
|
411
413
|
if (!(payload instanceof Uint8Array) || new ProtoMessage(payload).messages(1).length !== 1)
|
|
412
414
|
throw new Error("Cursor payload hook must return protobuf bytes for a single runRequest");
|
|
415
|
+
signal.throwIfAborted();
|
|
413
416
|
h2Client = http2.connect(baseUrl);
|
|
414
417
|
h2Client.on("error", (error) => {
|
|
415
418
|
endStreamError ??= error instanceof Error ? error : new Error(String(error));
|
|
@@ -453,9 +456,6 @@ export const streamCursor = (model, context, options = {}) => {
|
|
|
453
456
|
stream.push({ type: "start", partial: output });
|
|
454
457
|
h2Request.write(frameConnectMessage(payload));
|
|
455
458
|
heartbeatTimer = setInterval(() => write(frameConnectMessage(field(7, new Uint8Array(0)))), HEARTBEAT_INTERVAL_MS);
|
|
456
|
-
if (options.signal) {
|
|
457
|
-
options.signal.addEventListener("abort", () => h2Request?.close(), { once: true });
|
|
458
|
-
}
|
|
459
459
|
await new Promise((resolve) => {
|
|
460
460
|
let pending = Buffer.alloc(0);
|
|
461
461
|
h2Request.on("data", (chunk) => {
|
|
@@ -506,6 +506,9 @@ export const streamCursor = (model, context, options = {}) => {
|
|
|
506
506
|
resolve();
|
|
507
507
|
});
|
|
508
508
|
h2Request.on("close", resolve);
|
|
509
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
510
|
+
if (signal.aborted)
|
|
511
|
+
onAbort();
|
|
509
512
|
});
|
|
510
513
|
function dispatchServerMessage(message) {
|
|
511
514
|
if (CURSOR_DEBUG) {
|
|
@@ -641,11 +644,12 @@ export const streamCursor = (model, context, options = {}) => {
|
|
|
641
644
|
endStreamError ??= error instanceof Error ? error : new Error(String(error));
|
|
642
645
|
}
|
|
643
646
|
finally {
|
|
647
|
+
signal.removeEventListener("abort", onAbort);
|
|
644
648
|
if (heartbeatTimer)
|
|
645
649
|
clearInterval(heartbeatTimer);
|
|
646
650
|
// `end()` (graceful half-close) flushes exec/throw frames still queued
|
|
647
|
-
// behind processed data; `close()` is reserved for aborts.
|
|
648
|
-
if (
|
|
651
|
+
// behind processed data; `close()` is reserved for aborts and the deadline.
|
|
652
|
+
if (signal.aborted)
|
|
649
653
|
h2Request?.close();
|
|
650
654
|
else
|
|
651
655
|
h2Request?.end();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cursor subscription adapter (`cursor-agent` API).\n *\n * Implements the `agent.v1.AgentService/Run` bidirectional RPC over HTTP/2 at\n * https://api2.cursor.sh with Connect-framed protobuf, following the same\n * reverse-engineered protocol notes as the Devin adapter (see DEVIN-NOTICE).\n *\n * Turn model: each `stream()` call is one `Run` with a `userMessageAction` (or a\n * `resumeAction` when the last message is not a user turn). Conversation history\n * is replayed through `conversationState.rootPromptMessagesJson` — SHA256-keyed\n * JSON message blobs the server fetches back through the kv channel\n * (`getBlobArgs` → `getBlobResult`). System prompts ride `requestContext.rules`\n * in the exec handshake (`requestContextArgs` → `requestContextResult`).\n *\n * Scope: text and thinking deltas, token usage, blob/context/interaction\n * handshakes, and graceful rejection of tool execution frames. OMK tools are\n * intentionally not advertised in `requestContext.tools` — a frame the server\n * sends for client-side execution is answered with the protocol's `throw`\n * failure channel instead of being run unguarded inside the provider. Wiring\n * exec frames through governed OMK tools is a coding-agent bridge feature, not\n * provider scope.\n */\n\nimport { createHash } from \"node:crypto\";\nimport http2 from \"node:http2\";\nimport { getEnvApiKey } from \"../env-api-keys.ts\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tToolResultMessage,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { field, ProtoMessage } from \"./devin-protobuf.ts\";\n\nexport const CURSOR_API_URL = \"https://api2.cursor.sh\";\nexport const CURSOR_CLIENT_VERSION = \"cli-2026.02.13-41ac335\";\nconst CURSOR_RUN_PATH = \"/agent.v1.AgentService/Run\";\nconst CONNECT_END_STREAM_FLAG = 0b00000010;\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\nconst REJECTED_SUFFIX = \"not implemented by this client\";\nconst CURSOR_DEBUG = process.env.OMK_DEBUG_CURSOR === \"1\";\n\n// ---------------------------------------------------------------------------\n// Protobuf wire helpers (field numbers from the Cursor agent.v1 schema)\n// ---------------------------------------------------------------------------\n\nfunction frameConnectMessage(data: Uint8Array, flags = 0): Buffer {\n\tconst frame = Buffer.alloc(5 + data.length);\n\tframe[0] = flags;\n\tframe.writeUInt32BE(data.length, 1);\n\tframe.set(data, 5);\n\treturn frame;\n}\n\nfunction blobId(data: Uint8Array): Uint8Array {\n\treturn new Uint8Array(createHash(\"sha256\").update(data).digest());\n}\n\n/** Raw blob for pre-encoded payload bytes (system prompt JSON strings). */\nfunction rawBlob(store: Map<string, Uint8Array>, data: Uint8Array): Uint8Array {\n\tconst id = blobId(data);\n\tstore.set(Buffer.from(id).toString(\"hex\"), data);\n\treturn id;\n}\n\n/** JSON message blob for `rootPromptMessagesJson` (Vercel-AI-SDK-shaped). */\nfunction jsonBlob(store: Map<string, Uint8Array>, value: unknown): Uint8Array {\n\treturn rawBlob(store, new TextEncoder().encode(JSON.stringify(value)));\n}\n\nfunction readBlob(store: Map<string, Uint8Array>, id: Uint8Array): Uint8Array | undefined {\n\treturn store.get(Buffer.from(id).toString(\"hex\"));\n}\n\nfunction normalizeToolCallId(id: string): string {\n\tconst cleaned = id.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\treturn cleaned || crypto.randomUUID();\n}\n\nfunction normalizeCursorArgs(value: unknown, seen = new Set<object>()): unknown {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (typeof value !== \"object\" || seen.has(value)) return undefined;\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return value.map((item) => normalizeCursorArgs(item, seen) ?? null);\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tconst normalized = normalizeCursorArgs(item, seen);\n\t\t\tif (normalized !== undefined) out[key] = normalized;\n\t\t}\n\t\treturn out;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Request building\n// ---------------------------------------------------------------------------\n\nconst OPENAI_WIRE_PREFIX = /^(gpt-|composer|o\\d)/i;\n// Longest match first: `extra-high` must precede `high`, `xhigh` before `high`.\nconst EFFORT_SUFFIXES = [\"extra-high\", \"minimal\", \"xhigh\", \"medium\", \"high\", \"low\", \"max\", \"none\"] as const;\ntype CursorEffort = (typeof EFFORT_SUFFIXES)[number];\n\nfunction splitEffortSuffix(id: string): { base: string; effort?: CursorEffort; fast: boolean } {\n\tlet rest = id;\n\tlet fast = false;\n\tif (rest.endsWith(\"-fast\")) {\n\t\tfast = true;\n\t\trest = rest.slice(0, -5);\n\t}\n\tfor (const suffix of EFFORT_SUFFIXES) {\n\t\tif (rest.endsWith(`-${suffix}`)) {\n\t\t\treturn { base: rest.slice(0, -(suffix.length + 1)), effort: suffix, fast };\n\t\t}\n\t}\n\treturn { base: id, fast };\n}\n\nfunction isOpenAiFamily(id: string): boolean {\n\treturn OPENAI_WIRE_PREFIX.test(id) && !id.startsWith(\"composer\");\n}\n\n/**\n * Resolve the wire `model_id` and effort `parameters`. Cursor's Run endpoint\n * rejects effort sibling slugs for OpenAI-family ids (`resource_exhausted`);\n * the official agent splits the slug into the base id plus a `reasoning`\n * parameter. Non-OpenAI ids pass through whole. A bare `composer-2.5` pins\n * `fast=false` because the server resolves it to the Fast tier otherwise.\n */\nexport function resolveCursorWireModel(modelId: string): { modelId: string; parameters: Buffer[] } {\n\tconst { base, effort, fast } = splitEffortSuffix(modelId);\n\tif (effort !== undefined && isOpenAiFamily(base)) {\n\t\tif (effort === \"none\") return { modelId: fast ? `${base}-fast` : base, parameters: [] };\n\t\t// `extra-high` is the display suffix for the `xhigh` wire tier.\n\t\tconst wireEffort = effort === \"extra-high\" ? \"xhigh\" : effort;\n\t\treturn {\n\t\t\tmodelId: fast ? `${base}-fast` : base,\n\t\t\tparameters: [Buffer.concat([field(1, \"reasoning\"), field(2, wireEffort)])],\n\t\t};\n\t}\n\tif (modelId === \"composer-2.5\") {\n\t\treturn { modelId, parameters: [Buffer.concat([field(1, \"fast\"), field(2, \"false\")])] };\n\t}\n\treturn { modelId, parameters: [] };\n}\n\nfunction systemPromptJsons(systemPrompt: string | undefined): string[] {\n\tconst prompts = (systemPrompt ?? \"\")\n\t\t.split(/\\n{3,}/)\n\t\t.map((part) => part.trim())\n\t\t.filter(Boolean);\n\tif (prompts.length === 0) return [JSON.stringify({ role: \"system\", content: \"You are a helpful assistant.\" })];\n\treturn prompts.map((content) => JSON.stringify({ role: \"system\", content }));\n}\n\nfunction rootPromptContent(content: Message[\"content\"]): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof content === \"string\") {\n\t\tconst text = content.trim();\n\t\tif (text) parts.push({ type: \"text\", text });\n\t\treturn parts;\n\t}\n\tfor (const item of content) {\n\t\tif (item.type === \"text\") {\n\t\t\tconst text = (item as TextContent).text.trim();\n\t\t\tif (text) parts.push({ type: \"text\", text });\n\t\t} else if (item.type === \"image\") {\n\t\t\tconst image = item as ImageContent;\n\t\t\tparts.push({ type: \"image\", image: `data:${image.mimeType};base64,${image.data}`, mediaType: image.mimeType });\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction assistantContent(msg: Message, targetModelId: string): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof msg.content === \"string\") {\n\t\tif (msg.content.trim()) parts.push({ type: \"text\", text: msg.content });\n\t\treturn parts;\n\t}\n\tfor (const item of msg.content) {\n\t\tif (item.type === \"text\" && item.text) {\n\t\t\tparts.push({ type: \"text\", text: item.text });\n\t\t} else if (item.type === \"thinking\" && item.thinking) {\n\t\t\t// Replay reasoning only for blocks this provider produced for the same\n\t\t\t// wire model; foreign-provider thinking goes out unsigned and can get\n\t\t\t// the whole Run rejected.\n\t\t\tconst msgModel = (msg as AssistantMessage).model;\n\t\t\tif ((msg as AssistantMessage).provider === \"cursor\" && msgModel === targetModelId) {\n\t\t\t\tparts.push({\n\t\t\t\t\ttype: \"reasoning\",\n\t\t\t\t\ttext: item.thinking,\n\t\t\t\t\tproviderOptions: { cursor: { modelName: msgModel } },\n\t\t\t\t\t...(item.thinkingSignature ? { signature: item.thinkingSignature } : {}),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (item.type === \"toolCall\") {\n\t\t\tparts.push({\n\t\t\t\ttype: \"tool-call\",\n\t\t\t\ttoolCallId: normalizeToolCallId(item.id),\n\t\t\t\ttoolName: item.name,\n\t\t\t\targs: normalizeCursorArgs(item.arguments) ?? {},\n\t\t\t});\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction toolResultText(result: ToolResultMessage): string {\n\treturn result.content\n\t\t.map((item) => (item.type === \"text\" ? item.text : `[${(item as ImageContent).mimeType} image]`))\n\t\t.join(\"\\n\");\n}\n\nfunction buildRootPromptBlobIds(\n\tmessages: Message[],\n\tsystemPromptIds: Uint8Array[],\n\tblobStore: Map<string, Uint8Array>,\n\thistoryEnd: number,\n\ttargetModelId: string,\n): Uint8Array[] {\n\tconst ids = [...systemPromptIds];\n\tconst pairedToolCallIds = new Set<string>();\n\tfor (let i = 0; i < historyEnd; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const item of Array.isArray(msg.content) ? msg.content : []) {\n\t\t\t\tif (item.type === \"toolCall\") pairedToolCallIds.add(item.id);\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = 0; i < historyEnd && i < messages.length; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"user\") {\n\t\t\tconst content = rootPromptContent(msg.content);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"user\", content }));\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst content = assistantContent(msg, targetModelId);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"assistant\", content }));\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst result = msg as ToolResultMessage;\n\t\t\tif (!pairedToolCallIds.has(result.toolCallId)) {\n\t\t\t\tids.push(\n\t\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `${result.isError ? \"[Tool Error]\" : \"[Tool Result]\"}\\n${toolResultText(result) || \"(empty result)\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst toolCallId = normalizeToolCallId(result.toolCallId);\n\t\t\tids.push(\n\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\tid: toolCallId,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool-result\",\n\t\t\t\t\t\t\ttoolName: result.toolName,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tresult: toolResultText(result),\n\t\t\t\t\t\t\t...(result.isError ? { isError: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\treturn ids;\n}\n\nfunction userMessageProto(content: Message[\"content\"], text: string): Buffer {\n\tconst images = Array.isArray(content) ? (content.filter((c) => c.type === \"image\") as ImageContent[]) : [];\n\tconst fields = [field(1, text), field(2, crypto.randomUUID())];\n\tif (images.length > 0) {\n\t\tconst selected = images.map((image) =>\n\t\t\tBuffer.concat([\n\t\t\t\tfield(2, crypto.randomUUID()),\n\t\t\t\tfield(7, image.mimeType),\n\t\t\t\tfield(8, Buffer.from(image.data, \"base64\")),\n\t\t\t]),\n\t\t);\n\t\tfields.push(field(3, Buffer.concat(selected.map((img) => field(1, img)))));\n\t}\n\treturn Buffer.concat(fields);\n}\n\nfunction cursorRule(index: number, content: string): Buffer {\n\treturn Buffer.concat([\n\t\tfield(1, `/omk/system-prompt/${index}.mdc`),\n\t\tfield(2, content),\n\t\tfield(3, field(1, new Uint8Array(0))), // type: global {}\n\t\tfield(4, 2), // source: USER\n\t]);\n}\n\nfunction buildRequestContext(systemPrompt: string | undefined): Buffer {\n\tconst rules = systemPromptJsons(systemPrompt).map((json, index) => {\n\t\tconst content = (JSON.parse(json) as { content: string }).content;\n\t\treturn field(2, cursorRule(index, content));\n\t});\n\treturn Buffer.concat(rules);\n}\n\ninterface CursorTransportRequest {\n\tbytes: Uint8Array;\n\tblobStore: Map<string, Uint8Array>;\n}\n\nfunction buildRunRequest(\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions,\n): CursorTransportRequest {\n\tconst blobStore = new Map<string, Uint8Array>();\n\tconst systemPromptIds = systemPromptJsons(context.systemPrompt).map((json) =>\n\t\trawBlob(blobStore, new TextEncoder().encode(json)),\n\t);\n\tconst activeIndex = context.messages.length - 1;\n\tconst active = context.messages[activeIndex];\n\tconst activeUser = active && active.role === \"user\" ? active : undefined;\n\tconst userText = activeUser\n\t\t? typeof activeUser.content === \"string\"\n\t\t\t? activeUser.content.trim()\n\t\t\t: activeUser.content\n\t\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t.trim()\n\t\t: \"\";\n\tconst hasImages =\n\t\tactiveUser && Array.isArray(activeUser.content) ? activeUser.content.some((c) => c.type === \"image\") : false;\n\tconst historyEnd = activeUser ? activeIndex : context.messages.length;\n\tconst rootIds = buildRootPromptBlobIds(context.messages, systemPromptIds, blobStore, historyEnd, model.id);\n\n\tconst conversationState = Buffer.concat(rootIds.map((id) => field(1, id)));\n\tconst action =\n\t\tactiveUser && (userText.length > 0 || hasImages)\n\t\t\t? field(1, field(1, userMessageProto(activeUser.content, userText)))\n\t\t\t: field(2, new Uint8Array(0)); // resumeAction {}\n\n\tconst { modelId: wireModelId, parameters } = resolveCursorWireModel(model.id);\n\tconst maxMode = cursorMaxModeFor(model.id);\n\tconst modelDetails = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\tfield(3, model.id),\n\t\tfield(4, model.name),\n\t\t...(maxMode ? [field(7, true)] : []),\n\t]);\n\tconst requestedModel = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\t...(maxMode ? [field(2, true)] : []),\n\t\t...parameters.map((parameter) => field(3, parameter)),\n\t]);\n\n\tconst runRequest = Buffer.concat([\n\t\tfield(1, conversationState),\n\t\tfield(2, action),\n\t\tfield(3, modelDetails),\n\t\tfield(9, requestedModel),\n\t\tfield(5, options.sessionId ?? crypto.randomUUID()),\n\t]);\n\treturn { bytes: field(1, runRequest), blobStore };\n}\n\n/** Mirror the server-declared `maxMode` flag (fast Claude lanes). */\nfunction cursorMaxModeFor(modelId: string): boolean {\n\treturn /^claude-.*-fast$/.test(modelId);\n}\n\n// ---------------------------------------------------------------------------\n// Outbound client messages\n// ---------------------------------------------------------------------------\n\nfunction execClientResult(id: number, execId: string, caseNo: number, result: Buffer): Buffer {\n\tconst execMessage = Buffer.concat([field(1, id), field(15, execId), field(caseNo, result)]);\n\treturn frameConnectMessage(field(2, execMessage));\n}\n\nfunction execThrow(id: number, _execId: string, error: string): Buffer[] {\n\tconst throwMsg = field(5, Buffer.concat([field(2, Buffer.concat([field(1, id), field(2, error)]))]));\n\tconst closeMsg = field(5, field(1, field(1, id)));\n\treturn [frameConnectMessage(throwMsg), frameConnectMessage(closeMsg)];\n}\n\nfunction kvBlobResult(id: number, blobData: Uint8Array | undefined): Buffer {\n\tconst kv = Buffer.concat([field(1, id), field(2, blobData ? field(1, blobData) : new Uint8Array(0))]);\n\treturn frameConnectMessage(field(3, kv));\n}\n\nfunction kvSetBlobResult(id: number): Buffer {\n\treturn frameConnectMessage(field(3, Buffer.concat([field(1, id), field(3, new Uint8Array(0))])));\n}\n\nfunction interactionResponse(id: number, fieldNo: number, payload: Buffer): Buffer {\n\tconst response = Buffer.concat([field(1, id), field(fieldNo, payload)]);\n\treturn frameConnectMessage(field(6, response));\n}\n\n// ---------------------------------------------------------------------------\n// Stream adapter\n// ---------------------------------------------------------------------------\n\nexport interface CursorOptions extends StreamOptions {}\n\ninterface TextBlock {\n\tindex: number;\n\ttext: string;\n}\n\nexport const streamCursor: StreamFunction<\"cursor-agent\", CursorOptions> = (\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions = {},\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tcontent: [],\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\n\t(async () => {\n\t\tconst controller = new AbortController();\n\t\tconst signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;\n\t\tconst timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 600_000);\n\t\tlet h2Client: http2.ClientHttp2Session | undefined;\n\t\tlet h2Request: http2.ClientHttp2Stream | undefined;\n\t\tlet heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n\t\tlet sawTurnEnded = false;\n\t\tlet endStreamError: Error | undefined;\n\t\tconst write = (frame: Buffer | undefined) => {\n\t\t\tif (frame && h2Request && !h2Request.closed && !h2Request.destroyed) h2Request.write(frame);\n\t\t};\n\n\t\ttry {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst token = (options.apiKey ?? getEnvApiKey(\"cursor\") ?? \"\").trim();\n\t\t\tif (!token) throw new Error(\"Missing Cursor access token; run /login cursor\");\n\t\t\tconst baseUrl = (model.baseUrl || CURSOR_API_URL).replace(/\\/+$/, \"\");\n\t\t\tif (\n\t\t\t\t!/^https:\\/\\/[a-z0-9.-]*cursor\\.(sh|com|dev)(:\\d+)?$/.test(baseUrl) &&\n\t\t\t\t!/^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(baseUrl)\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Cursor subscription credentials require a *.cursor.sh/cursor.com HTTPS origin\");\n\t\t\t}\n\n\t\t\tconst built = buildRunRequest(model, context, options);\n\t\t\tconst requestContext = buildRequestContext(context.systemPrompt);\n\t\t\tconst request = await options.onPayload?.(built.bytes, model);\n\t\t\tconst payload = request === undefined ? built.bytes : request;\n\t\t\tif (!(payload instanceof Uint8Array) || new ProtoMessage(payload).messages(1).length !== 1)\n\t\t\t\tthrow new Error(\"Cursor payload hook must return protobuf bytes for a single runRequest\");\n\n\t\t\th2Client = http2.connect(baseUrl);\n\t\t\th2Client.on(\"error\", (error) => {\n\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t});\n\t\t\tconst requestHeaders = {\n\t\t\t\t\":method\": \"POST\",\n\t\t\t\t\":path\": CURSOR_RUN_PATH,\n\t\t\t\t\"content-type\": \"application/connect+proto\",\n\t\t\t\t\"connect-protocol-version\": \"1\",\n\t\t\t\tte: \"trailers\",\n\t\t\t\tauthorization: `Bearer ${token}`,\n\t\t\t\t\"x-ghost-mode\": \"true\",\n\t\t\t\t\"x-cursor-client-version\": CURSOR_CLIENT_VERSION,\n\t\t\t\t\"x-cursor-client-type\": \"cli\",\n\t\t\t\t\"x-request-id\": crypto.randomUUID(),\n\t\t\t\t...(options.headers ?? {}),\n\t\t\t};\n\t\t\th2Request = h2Client.request(requestHeaders);\n\t\t\th2Request.on(\"response\", (headers) => {\n\t\t\t\tvoid options.onResponse?.(\n\t\t\t\t\t{ status: Number(headers[\":status\"] ?? 0), headers: headers as Record<string, string> },\n\t\t\t\t\tmodel,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tlet textBlock: TextBlock | undefined;\n\t\t\tlet thinkingBlock: TextBlock | undefined;\n\t\t\tconst endText = () => {\n\t\t\t\tif (!textBlock) return;\n\t\t\t\tstream.push({ type: \"text_end\", contentIndex: textBlock.index, content: textBlock.text, partial: output });\n\t\t\t\ttextBlock = undefined;\n\t\t\t};\n\t\t\tconst endThinking = () => {\n\t\t\t\tif (!thinkingBlock) return;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: thinkingBlock.index,\n\t\t\t\t\tcontent: thinkingBlock.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\tthinkingBlock = undefined;\n\t\t\t};\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\th2Request.write(frameConnectMessage(payload));\n\t\t\theartbeatTimer = setInterval(\n\t\t\t\t() => write(frameConnectMessage(field(7, new Uint8Array(0)))),\n\t\t\t\tHEARTBEAT_INTERVAL_MS,\n\t\t\t);\n\t\t\tif (options.signal) {\n\t\t\t\toptions.signal.addEventListener(\"abort\", () => h2Request?.close(), { once: true });\n\t\t\t}\n\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tlet pending: Buffer = Buffer.alloc(0);\n\t\t\t\th2Request!.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tpending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);\n\t\t\t\t\twhile (pending.length >= 5) {\n\t\t\t\t\t\tconst flags = pending[0];\n\t\t\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\t\t\tif (length > MAX_FRAME_BYTES) {\n\t\t\t\t\t\t\tendStreamError ??= new Error(`Cursor frame exceeds ${MAX_FRAME_BYTES} bytes`);\n\t\t\t\t\t\t\th2Request?.close();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pending.length < 5 + length) break;\n\t\t\t\t\t\tconst messageBytes = pending.subarray(5, 5 + length);\n\t\t\t\t\t\tpending = pending.subarray(5 + length);\n\t\t\t\t\t\tif (flags & CONNECT_END_STREAM_FLAG) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst payload = JSON.parse(new TextDecoder().decode(messageBytes)) as {\n\t\t\t\t\t\t\t\t\terror?: { code?: string; message?: string };\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (payload.error) {\n\t\t\t\t\t\t\t\t\tendStreamError = new Error(\n\t\t\t\t\t\t\t\t\t\t`Cursor ${payload.error.code ?? \"error\"}: ${payload.error.message ?? \"unknown error\"}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tendStreamError = new Error(\"Failed to parse Cursor end-stream trailer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tdispatchServerMessage(new ProtoMessage(messageBytes));\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!endStreamError) endStreamError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"trailers\", (trailers) => {\n\t\t\t\t\tconst status = trailers[\"grpc-status\"];\n\t\t\t\t\tconst message = trailers[\"grpc-message\"];\n\t\t\t\t\tif (status && status !== \"0\") {\n\t\t\t\t\t\tendStreamError ??= new Error(\n\t\t\t\t\t\t\t`Cursor gRPC error ${status}: ${decodeURIComponent(String(message ?? \"\"))}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"end\", resolve);\n\t\t\t\th2Request!.on(\"error\", (error) => {\n\t\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"close\", resolve);\n\t\t\t});\n\n\t\t\tfunction dispatchServerMessage(message: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 7].filter((n) => message.has(n));\n\t\t\t\t\tconsole.error(`[cursor] server cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tif (message.has(1)) {\n\t\t\t\t\tfor (const update of message.messages(1)) handleInteractionUpdate(update);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(2)) {\n\t\t\t\t\tfor (const exec of message.messages(2)) handleExecMessage(exec);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(4)) {\n\t\t\t\t\tfor (const kv of message.messages(4)) {\n\t\t\t\t\t\tconst id = kv.number(1);\n\t\t\t\t\t\tfor (const getBlob of kv.messages(2)) {\n\t\t\t\t\t\t\tconst blobIdBytes = getBlob.bytes(1) ?? new Uint8Array(0);\n\t\t\t\t\t\t\tconst data = readBlob(built.blobStore, blobIdBytes);\n\t\t\t\t\t\t\tif (CURSOR_DEBUG)\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t`[cursor] kv getBlob id=${id} blob=${Buffer.from(blobIdBytes).toString(\"hex\").slice(0, 16)} found=${!!data}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twrite(kvBlobResult(id, data));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const setBlob of kv.messages(3)) {\n\t\t\t\t\t\t\tconst blobIdBytes = setBlob.bytes(1);\n\t\t\t\t\t\t\tconst blobData = setBlob.bytes(2);\n\t\t\t\t\t\t\tif (blobIdBytes && blobData) {\n\t\t\t\t\t\t\t\tbuilt.blobStore.set(Buffer.from(blobIdBytes).toString(\"hex\"), blobData);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrite(kvSetBlobResult(id));\n\t\t\t\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] kv setBlob id=${id}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(5)) {\n\t\t\t\t\t// execServerControlMessage: abort/stop signals — treat as turn end.\n\t\t\t\t\tfor (const control of message.messages(5)) {\n\t\t\t\t\t\tif (control.has(1)) sawTurnEnded = true;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(7)) {\n\t\t\t\t\tfor (const query of message.messages(7)) handleInteractionQuery(query);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionUpdate(update: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17].filter((n) => update.has(n));\n\t\t\t\t\tconsole.error(`[cursor] update cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(1)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!textBlock) {\n\t\t\t\t\t\ttextBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"text\", text: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: textBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\ttextBlock.text += text;\n\t\t\t\t\t(output.content[textBlock.index] as TextContent).text = textBlock.text;\n\t\t\t\t\tstream.push({ type: \"text_delta\", contentIndex: textBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(4)) {\n\t\t\t\t\tendText();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!thinkingBlock) {\n\t\t\t\t\t\tthinkingBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"thinking\", thinking: \"\", thinkingSignature: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: thinkingBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tthinkingBlock.text += text;\n\t\t\t\t\t(output.content[thinkingBlock.index] as { thinking: string }).thinking = thinkingBlock.text;\n\t\t\t\t\tstream.push({ type: \"thinking_delta\", contentIndex: thinkingBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const tokens of update.messages(8)) {\n\t\t\t\t\toutput.usage.output += tokens.number(1);\n\t\t\t\t}\n\t\t\t\tif (update.has(14)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tendText();\n\t\t\t\t\tsawTurnEnded = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleExecMessage(exec: ProtoMessage): void {\n\t\t\t\tconst id = exec.number(1);\n\t\t\t\tconst execId = exec.string(15);\n\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] exec id=${id} execId=${execId} case=${execCaseName(exec)}`);\n\t\t\t\tif (exec.has(10)) {\n\t\t\t\t\t// requestContextArgs — the exec handshake carrying rules/tools.\n\t\t\t\t\tconst result = field(1, field(1, requestContext));\n\t\t\t\t\twrite(execClientResult(id, execId, 10, result));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const frame of execThrow(id, execId, `Cursor ${execCaseName(exec)} execution is ${REJECTED_SUFFIX}`)) {\n\t\t\t\t\twrite(frame);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionQuery(query: ProtoMessage): void {\n\t\t\t\tconst id = query.number(1);\n\t\t\t\tconst approved = field(1, new Uint8Array(0));\n\t\t\t\tfor (const fieldNo of [2, 5, 6, 9]) {\n\t\t\t\t\tif (query.has(fieldNo)) {\n\t\t\t\t\t\twrite(interactionResponse(id, fieldNo, approved));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (query.has(3)) {\n\t\t\t\t\twrite(interactionResponse(id, 3, field(3, field(1, `Interactive questions are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(4)) {\n\t\t\t\t\twrite(interactionResponse(id, 4, field(2, field(1, `Mode switches are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(7)) {\n\t\t\t\t\t// createPlan → result{ error{ error } }\n\t\t\t\t\twrite(interactionResponse(id, 7, field(1, field(2, field(1, `Plan files are ${REJECTED_SUFFIX}`)))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// setupVmEnvironmentArgs (8) is intentionally left unanswered rather\n\t\t\t\t// than reporting a fake success.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t} finally {\n\t\t\tif (heartbeatTimer) clearInterval(heartbeatTimer);\n\t\t\t// `end()` (graceful half-close) flushes exec/throw frames still queued\n\t\t\t// behind processed data; `close()` is reserved for aborts.\n\t\t\tif (options.signal?.aborted) h2Request?.close();\n\t\t\telse h2Request?.end();\n\t\t\th2Client?.close();\n\t\t\tclearTimeout(timer);\n\t\t}\n\n\t\t// Finalize outside the try so close-flush always runs once.\n\t\ttry {\n\t\t\tif (endStreamError) throw endStreamError;\n\t\t\tif (!sawTurnEnded) {\n\t\t\t\tthrow options.signal?.aborted\n\t\t\t\t\t? Object.assign(new Error(\"aborted\"), { name: \"AbortError\" })\n\t\t\t\t\t: new Error(\"Cursor stream ended before the turn completed\");\n\t\t\t}\n\t\t\toutput.stopReason = \"stop\";\n\t\t\toutput.usage.totalTokens =\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t\tstream.push({ type: \"done\", reason: \"stop\", message: output });\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : \"Cursor request failed\";\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\tstream.end(output);\n\t\t}\n\t})();\n\treturn stream;\n};\n\nfunction execCaseName(exec: ProtoMessage): string {\n\tfor (const [no, name] of EXEC_CASE_NAMES) {\n\t\tif (exec.has(no)) return name;\n\t}\n\treturn \"exec\";\n}\n\nconst EXEC_CASE_NAMES: ReadonlyArray<readonly [number, string]> = [\n\t[2, \"shell\"],\n\t[3, \"write\"],\n\t[4, \"delete\"],\n\t[5, \"grep\"],\n\t[7, \"read\"],\n\t[8, \"ls\"],\n\t[9, \"diagnostics\"],\n\t[10, \"requestContext\"],\n\t[11, \"mcp\"],\n\t[14, \"shellStream\"],\n\t[16, \"backgroundShellSpawn\"],\n\t[17, \"listMcpResources\"],\n\t[18, \"readMcpResource\"],\n\t[20, \"fetch\"],\n\t[21, \"recordScreen\"],\n\t[22, \"computerUse\"],\n\t[23, \"writeShellStdin\"],\n\t[29, \"redactedRead\"],\n\t[36, \"mcpState\"],\n\t[27, \"executeHook\"],\n\t[28, \"subagent\"],\n\t[30, \"forceBackgroundShell\"],\n\t[31, \"forceBackgroundSubagent\"],\n\t[37, \"subagentAwait\"],\n\t[38, \"smartModeClassifier\"],\n\t[40, \"canvasDiagnostics\"],\n\t[41, \"shellAllowlistPrecheck\"],\n\t[42, \"mcpAllowlistPrecheck\"],\n\t[43, \"webFetchAllowlistPrecheck\"],\n\t[44, \"gitDiff\"],\n\t[45, \"piRead\"],\n\t[46, \"piBash\"],\n\t[47, \"piEdit\"],\n\t[48, \"piWrite\"],\n\t[49, \"piGrep\"],\n\t[50, \"piFind\"],\n\t[51, \"piLs\"],\n\t[52, \"conversationSearch\"],\n\t[54, \"agentStoreConflict\"],\n\t[56, \"miniSweAgentBash\"],\n];\n\nexport const streamSimpleCursor: StreamFunction<\"cursor-agent\", SimpleStreamOptions> = (model, context, options) =>\n\tstreamCursor(model, context, options);\n"]}
|
|
1
|
+
{"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/providers/cursor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Cursor subscription adapter (`cursor-agent` API).\n *\n * Implements the `agent.v1.AgentService/Run` bidirectional RPC over HTTP/2 at\n * https://api2.cursor.sh with Connect-framed protobuf, following the same\n * reverse-engineered protocol notes as the Devin adapter (see DEVIN-NOTICE).\n *\n * Turn model: each `stream()` call is one `Run` with a `userMessageAction` (or a\n * `resumeAction` when the last message is not a user turn). Conversation history\n * is replayed through `conversationState.rootPromptMessagesJson` — SHA256-keyed\n * JSON message blobs the server fetches back through the kv channel\n * (`getBlobArgs` → `getBlobResult`). System prompts ride `requestContext.rules`\n * in the exec handshake (`requestContextArgs` → `requestContextResult`).\n *\n * Scope: text and thinking deltas, token usage, blob/context/interaction\n * handshakes, and graceful rejection of tool execution frames. OMK tools are\n * intentionally not advertised in `requestContext.tools` — a frame the server\n * sends for client-side execution is answered with the protocol's `throw`\n * failure channel instead of being run unguarded inside the provider. Wiring\n * exec frames through governed OMK tools is a coding-agent bridge feature, not\n * provider scope.\n */\n\nimport { createHash } from \"node:crypto\";\nimport http2 from \"node:http2\";\nimport { getEnvApiKey } from \"../env-api-keys.ts\";\nimport { calculateCost } from \"../models.ts\";\nimport type {\n\tAssistantMessage,\n\tContext,\n\tImageContent,\n\tMessage,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n\tTextContent,\n\tToolResultMessage,\n} from \"../types.ts\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.ts\";\nimport { frameConnectMessage } from \"./cursor-connect.ts\";\nimport { field, ProtoMessage } from \"./devin-protobuf.ts\";\n\nexport const CURSOR_API_URL = \"https://api2.cursor.sh\";\nexport const CURSOR_CLIENT_VERSION = \"cli-2026.02.13-41ac335\";\nconst CURSOR_RUN_PATH = \"/agent.v1.AgentService/Run\";\nconst CONNECT_END_STREAM_FLAG = 0b00000010;\nconst HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\nconst REJECTED_SUFFIX = \"not implemented by this client\";\nconst CURSOR_DEBUG = process.env.OMK_DEBUG_CURSOR === \"1\";\n\n// ---------------------------------------------------------------------------\n// Protobuf wire helpers (field numbers from the Cursor agent.v1 schema)\n// ---------------------------------------------------------------------------\n\nfunction blobId(data: Uint8Array): Uint8Array {\n\treturn new Uint8Array(createHash(\"sha256\").update(data).digest());\n}\n\n/** Raw blob for pre-encoded payload bytes (system prompt JSON strings). */\nfunction rawBlob(store: Map<string, Uint8Array>, data: Uint8Array): Uint8Array {\n\tconst id = blobId(data);\n\tstore.set(Buffer.from(id).toString(\"hex\"), data);\n\treturn id;\n}\n\n/** JSON message blob for `rootPromptMessagesJson` (Vercel-AI-SDK-shaped). */\nfunction jsonBlob(store: Map<string, Uint8Array>, value: unknown): Uint8Array {\n\treturn rawBlob(store, new TextEncoder().encode(JSON.stringify(value)));\n}\n\nfunction readBlob(store: Map<string, Uint8Array>, id: Uint8Array): Uint8Array | undefined {\n\treturn store.get(Buffer.from(id).toString(\"hex\"));\n}\n\nfunction normalizeToolCallId(id: string): string {\n\tconst cleaned = id.replace(/[^a-zA-Z0-9_-]/g, \"\");\n\treturn cleaned || crypto.randomUUID();\n}\n\nfunction normalizeCursorArgs(value: unknown, seen = new Set<object>()): unknown {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return value;\n\tif (typeof value === \"number\") return Number.isFinite(value) ? value : null;\n\tif (typeof value !== \"object\" || seen.has(value)) return undefined;\n\tseen.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) return value.map((item) => normalizeCursorArgs(item, seen) ?? null);\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tconst normalized = normalizeCursorArgs(item, seen);\n\t\t\tif (normalized !== undefined) out[key] = normalized;\n\t\t}\n\t\treturn out;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Request building\n// ---------------------------------------------------------------------------\n\nconst OPENAI_WIRE_PREFIX = /^(gpt-|composer|o\\d)/i;\n// Longest match first: `extra-high` must precede `high`, `xhigh` before `high`.\nconst EFFORT_SUFFIXES = [\"extra-high\", \"minimal\", \"xhigh\", \"medium\", \"high\", \"low\", \"max\", \"none\"] as const;\ntype CursorEffort = (typeof EFFORT_SUFFIXES)[number];\n\nfunction splitEffortSuffix(id: string): { base: string; effort?: CursorEffort; fast: boolean } {\n\tlet rest = id;\n\tlet fast = false;\n\tif (rest.endsWith(\"-fast\")) {\n\t\tfast = true;\n\t\trest = rest.slice(0, -5);\n\t}\n\tfor (const suffix of EFFORT_SUFFIXES) {\n\t\tif (rest.endsWith(`-${suffix}`)) {\n\t\t\treturn { base: rest.slice(0, -(suffix.length + 1)), effort: suffix, fast };\n\t\t}\n\t}\n\treturn { base: id, fast };\n}\n\nfunction isOpenAiFamily(id: string): boolean {\n\treturn OPENAI_WIRE_PREFIX.test(id) && !id.startsWith(\"composer\");\n}\n\n/**\n * Resolve the wire `model_id` and effort `parameters`. Cursor's Run endpoint\n * rejects effort sibling slugs for OpenAI-family ids (`resource_exhausted`);\n * the official agent splits the slug into the base id plus a `reasoning`\n * parameter. Non-OpenAI ids pass through whole. A bare `composer-2.5` pins\n * `fast=false` because the server resolves it to the Fast tier otherwise.\n */\nexport function resolveCursorWireModel(modelId: string): { modelId: string; parameters: Buffer[] } {\n\tconst { base, effort, fast } = splitEffortSuffix(modelId);\n\tif (effort !== undefined && isOpenAiFamily(base)) {\n\t\tif (effort === \"none\") return { modelId: fast ? `${base}-fast` : base, parameters: [] };\n\t\t// `extra-high` is the display suffix for the `xhigh` wire tier.\n\t\tconst wireEffort = effort === \"extra-high\" ? \"xhigh\" : effort;\n\t\treturn {\n\t\t\tmodelId: fast ? `${base}-fast` : base,\n\t\t\tparameters: [Buffer.concat([field(1, \"reasoning\"), field(2, wireEffort)])],\n\t\t};\n\t}\n\tif (modelId === \"composer-2.5\") {\n\t\treturn { modelId, parameters: [Buffer.concat([field(1, \"fast\"), field(2, \"false\")])] };\n\t}\n\treturn { modelId, parameters: [] };\n}\n\nfunction systemPromptJsons(systemPrompt: string | undefined): string[] {\n\tconst prompts = (systemPrompt ?? \"\")\n\t\t.split(/\\n{3,}/)\n\t\t.map((part) => part.trim())\n\t\t.filter(Boolean);\n\tif (prompts.length === 0) return [JSON.stringify({ role: \"system\", content: \"You are a helpful assistant.\" })];\n\treturn prompts.map((content) => JSON.stringify({ role: \"system\", content }));\n}\n\nfunction rootPromptContent(content: Message[\"content\"]): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof content === \"string\") {\n\t\tconst text = content.trim();\n\t\tif (text) parts.push({ type: \"text\", text });\n\t\treturn parts;\n\t}\n\tfor (const item of content) {\n\t\tif (item.type === \"text\") {\n\t\t\tconst text = (item as TextContent).text.trim();\n\t\t\tif (text) parts.push({ type: \"text\", text });\n\t\t} else if (item.type === \"image\") {\n\t\t\tconst image = item as ImageContent;\n\t\t\tparts.push({ type: \"image\", image: `data:${image.mimeType};base64,${image.data}`, mediaType: image.mimeType });\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction assistantContent(msg: Message, targetModelId: string): unknown[] {\n\tconst parts: unknown[] = [];\n\tif (typeof msg.content === \"string\") {\n\t\tif (msg.content.trim()) parts.push({ type: \"text\", text: msg.content });\n\t\treturn parts;\n\t}\n\tfor (const item of msg.content) {\n\t\tif (item.type === \"text\" && item.text) {\n\t\t\tparts.push({ type: \"text\", text: item.text });\n\t\t} else if (item.type === \"thinking\" && item.thinking) {\n\t\t\t// Replay reasoning only for blocks this provider produced for the same\n\t\t\t// wire model; foreign-provider thinking goes out unsigned and can get\n\t\t\t// the whole Run rejected.\n\t\t\tconst msgModel = (msg as AssistantMessage).model;\n\t\t\tif ((msg as AssistantMessage).provider === \"cursor\" && msgModel === targetModelId) {\n\t\t\t\tparts.push({\n\t\t\t\t\ttype: \"reasoning\",\n\t\t\t\t\ttext: item.thinking,\n\t\t\t\t\tproviderOptions: { cursor: { modelName: msgModel } },\n\t\t\t\t\t...(item.thinkingSignature ? { signature: item.thinkingSignature } : {}),\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (item.type === \"toolCall\") {\n\t\t\tparts.push({\n\t\t\t\ttype: \"tool-call\",\n\t\t\t\ttoolCallId: normalizeToolCallId(item.id),\n\t\t\t\ttoolName: item.name,\n\t\t\t\targs: normalizeCursorArgs(item.arguments) ?? {},\n\t\t\t});\n\t\t}\n\t}\n\treturn parts;\n}\n\nfunction toolResultText(result: ToolResultMessage): string {\n\treturn result.content\n\t\t.map((item) => (item.type === \"text\" ? item.text : `[${(item as ImageContent).mimeType} image]`))\n\t\t.join(\"\\n\");\n}\n\nfunction buildRootPromptBlobIds(\n\tmessages: Message[],\n\tsystemPromptIds: Uint8Array[],\n\tblobStore: Map<string, Uint8Array>,\n\thistoryEnd: number,\n\ttargetModelId: string,\n): Uint8Array[] {\n\tconst ids = [...systemPromptIds];\n\tconst pairedToolCallIds = new Set<string>();\n\tfor (let i = 0; i < historyEnd; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"assistant\") {\n\t\t\tfor (const item of Array.isArray(msg.content) ? msg.content : []) {\n\t\t\t\tif (item.type === \"toolCall\") pairedToolCallIds.add(item.id);\n\t\t\t}\n\t\t}\n\t}\n\tfor (let i = 0; i < historyEnd && i < messages.length; i++) {\n\t\tconst msg = messages[i];\n\t\tif (msg.role === \"user\") {\n\t\t\tconst content = rootPromptContent(msg.content);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"user\", content }));\n\t\t} else if (msg.role === \"assistant\") {\n\t\t\tconst content = assistantContent(msg, targetModelId);\n\t\t\tif (content.length === 0) continue;\n\t\t\tids.push(jsonBlob(blobStore, { role: \"assistant\", content }));\n\t\t} else if (msg.role === \"toolResult\") {\n\t\t\tconst result = msg as ToolResultMessage;\n\t\t\tif (!pairedToolCallIds.has(result.toolCallId)) {\n\t\t\t\tids.push(\n\t\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\ttext: `${result.isError ? \"[Tool Error]\" : \"[Tool Result]\"}\\n${toolResultText(result) || \"(empty result)\"}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t}),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst toolCallId = normalizeToolCallId(result.toolCallId);\n\t\t\tids.push(\n\t\t\t\tjsonBlob(blobStore, {\n\t\t\t\t\trole: \"tool\",\n\t\t\t\t\tid: toolCallId,\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"tool-result\",\n\t\t\t\t\t\t\ttoolName: result.toolName,\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\tresult: toolResultText(result),\n\t\t\t\t\t\t\t...(result.isError ? { isError: true } : {}),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\t}\n\treturn ids;\n}\n\nfunction userMessageProto(content: Message[\"content\"], text: string): Buffer {\n\tconst images = Array.isArray(content) ? (content.filter((c) => c.type === \"image\") as ImageContent[]) : [];\n\tconst fields = [field(1, text), field(2, crypto.randomUUID())];\n\tif (images.length > 0) {\n\t\tconst selected = images.map((image) =>\n\t\t\tBuffer.concat([\n\t\t\t\tfield(2, crypto.randomUUID()),\n\t\t\t\tfield(7, image.mimeType),\n\t\t\t\tfield(8, Buffer.from(image.data, \"base64\")),\n\t\t\t]),\n\t\t);\n\t\tfields.push(field(3, Buffer.concat(selected.map((img) => field(1, img)))));\n\t}\n\treturn Buffer.concat(fields);\n}\n\nfunction cursorRule(index: number, content: string): Buffer {\n\treturn Buffer.concat([\n\t\tfield(1, `/omk/system-prompt/${index}.mdc`),\n\t\tfield(2, content),\n\t\tfield(3, field(1, new Uint8Array(0))), // type: global {}\n\t\tfield(4, 2), // source: USER\n\t]);\n}\n\nfunction buildRequestContext(systemPrompt: string | undefined): Buffer {\n\tconst rules = systemPromptJsons(systemPrompt).map((json, index) => {\n\t\tconst content = (JSON.parse(json) as { content: string }).content;\n\t\treturn field(2, cursorRule(index, content));\n\t});\n\treturn Buffer.concat(rules);\n}\n\ninterface CursorTransportRequest {\n\tbytes: Uint8Array;\n\tblobStore: Map<string, Uint8Array>;\n}\n\nfunction buildRunRequest(\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions,\n): CursorTransportRequest {\n\tconst blobStore = new Map<string, Uint8Array>();\n\tconst systemPromptIds = systemPromptJsons(context.systemPrompt).map((json) =>\n\t\trawBlob(blobStore, new TextEncoder().encode(json)),\n\t);\n\tconst activeIndex = context.messages.length - 1;\n\tconst active = context.messages[activeIndex];\n\tconst activeUser = active && active.role === \"user\" ? active : undefined;\n\tconst userText = activeUser\n\t\t? typeof activeUser.content === \"string\"\n\t\t\t? activeUser.content.trim()\n\t\t\t: activeUser.content\n\t\t\t\t\t.filter((c): c is TextContent => c.type === \"text\")\n\t\t\t\t\t.map((c) => c.text)\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t\t\t.trim()\n\t\t: \"\";\n\tconst hasImages =\n\t\tactiveUser && Array.isArray(activeUser.content) ? activeUser.content.some((c) => c.type === \"image\") : false;\n\tconst historyEnd = activeUser ? activeIndex : context.messages.length;\n\tconst rootIds = buildRootPromptBlobIds(context.messages, systemPromptIds, blobStore, historyEnd, model.id);\n\n\tconst conversationState = Buffer.concat(rootIds.map((id) => field(1, id)));\n\tconst action =\n\t\tactiveUser && (userText.length > 0 || hasImages)\n\t\t\t? field(1, field(1, userMessageProto(activeUser.content, userText)))\n\t\t\t: field(2, new Uint8Array(0)); // resumeAction {}\n\n\tconst { modelId: wireModelId, parameters } = resolveCursorWireModel(model.id);\n\tconst maxMode = cursorMaxModeFor(model.id);\n\tconst modelDetails = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\tfield(3, model.id),\n\t\tfield(4, model.name),\n\t\t...(maxMode ? [field(7, true)] : []),\n\t]);\n\tconst requestedModel = Buffer.concat([\n\t\tfield(1, wireModelId),\n\t\t...(maxMode ? [field(2, true)] : []),\n\t\t...parameters.map((parameter) => field(3, parameter)),\n\t]);\n\n\tconst runRequest = Buffer.concat([\n\t\tfield(1, conversationState),\n\t\tfield(2, action),\n\t\tfield(3, modelDetails),\n\t\tfield(9, requestedModel),\n\t\tfield(5, options.sessionId ?? crypto.randomUUID()),\n\t]);\n\treturn { bytes: field(1, runRequest), blobStore };\n}\n\n/** Mirror the server-declared `maxMode` flag (fast Claude lanes). */\nfunction cursorMaxModeFor(modelId: string): boolean {\n\treturn /^claude-.*-fast$/.test(modelId);\n}\n\n// ---------------------------------------------------------------------------\n// Outbound client messages\n// ---------------------------------------------------------------------------\n\nfunction execClientResult(id: number, execId: string, caseNo: number, result: Buffer): Buffer {\n\tconst execMessage = Buffer.concat([field(1, id), field(15, execId), field(caseNo, result)]);\n\treturn frameConnectMessage(field(2, execMessage));\n}\n\nfunction execThrow(id: number, _execId: string, error: string): Buffer[] {\n\tconst throwMsg = field(5, Buffer.concat([field(2, Buffer.concat([field(1, id), field(2, error)]))]));\n\tconst closeMsg = field(5, field(1, field(1, id)));\n\treturn [frameConnectMessage(throwMsg), frameConnectMessage(closeMsg)];\n}\n\nfunction kvBlobResult(id: number, blobData: Uint8Array | undefined): Buffer {\n\tconst kv = Buffer.concat([field(1, id), field(2, blobData ? field(1, blobData) : new Uint8Array(0))]);\n\treturn frameConnectMessage(field(3, kv));\n}\n\nfunction kvSetBlobResult(id: number): Buffer {\n\treturn frameConnectMessage(field(3, Buffer.concat([field(1, id), field(3, new Uint8Array(0))])));\n}\n\nfunction interactionResponse(id: number, fieldNo: number, payload: Buffer): Buffer {\n\tconst response = Buffer.concat([field(1, id), field(fieldNo, payload)]);\n\treturn frameConnectMessage(field(6, response));\n}\n\n// ---------------------------------------------------------------------------\n// Stream adapter\n// ---------------------------------------------------------------------------\n\nexport interface CursorOptions extends StreamOptions {}\n\ninterface TextBlock {\n\tindex: number;\n\ttext: string;\n}\n\nexport const streamCursor: StreamFunction<\"cursor-agent\", CursorOptions> = (\n\tmodel: Model<\"cursor-agent\">,\n\tcontext: Context,\n\toptions: CursorOptions = {},\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\tconst output: AssistantMessage = {\n\t\trole: \"assistant\",\n\t\tapi: model.api,\n\t\tprovider: model.provider,\n\t\tmodel: model.id,\n\t\tcontent: [],\n\t\tusage: {\n\t\t\tinput: 0,\n\t\t\toutput: 0,\n\t\t\tcacheRead: 0,\n\t\t\tcacheWrite: 0,\n\t\t\ttotalTokens: 0,\n\t\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n\t\t},\n\t\tstopReason: \"stop\",\n\t\ttimestamp: Date.now(),\n\t};\n\n\t(async () => {\n\t\tconst controller = new AbortController();\n\t\tconst signal = options.signal ? AbortSignal.any([controller.signal, options.signal]) : controller.signal;\n\t\tconst timeoutMs = options.timeoutMs ?? 600_000;\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\tlet h2Client: http2.ClientHttp2Session | undefined;\n\t\tlet h2Request: http2.ClientHttp2Stream | undefined;\n\t\tlet heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n\t\tlet sawTurnEnded = false;\n\t\tlet endStreamError: Error | undefined;\n\t\t// Close on the combined signal so the internal deadline also ends a silent peer.\n\t\t// The deadline is a request error; a caller abort keeps the aborted result.\n\t\tconst onAbort = () => {\n\t\t\tif (controller.signal.aborted) endStreamError ??= new Error(`Cursor timed out after ${timeoutMs}ms`);\n\t\t\th2Request?.close();\n\t\t};\n\t\tconst write = (frame: Buffer | undefined) => {\n\t\t\tif (frame && h2Request && !h2Request.closed && !h2Request.destroyed) h2Request.write(frame);\n\t\t};\n\n\t\ttry {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst token = (options.apiKey ?? getEnvApiKey(\"cursor\") ?? \"\").trim();\n\t\t\tif (!token) throw new Error(\"Missing Cursor access token; run /login cursor\");\n\t\t\tconst baseUrl = (model.baseUrl || CURSOR_API_URL).replace(/\\/+$/, \"\");\n\t\t\tif (\n\t\t\t\t!/^https:\\/\\/[a-z0-9.-]*cursor\\.(sh|com|dev)(:\\d+)?$/.test(baseUrl) &&\n\t\t\t\t!/^https?:\\/\\/(localhost|127\\.0\\.0\\.1)(:\\d+)?$/.test(baseUrl)\n\t\t\t) {\n\t\t\t\tthrow new Error(\"Cursor subscription credentials require a *.cursor.sh/cursor.com HTTPS origin\");\n\t\t\t}\n\n\t\t\tconst built = buildRunRequest(model, context, options);\n\t\t\tconst requestContext = buildRequestContext(context.systemPrompt);\n\t\t\tconst request = await options.onPayload?.(built.bytes, model);\n\t\t\tconst payload = request === undefined ? built.bytes : request;\n\t\t\tif (!(payload instanceof Uint8Array) || new ProtoMessage(payload).messages(1).length !== 1)\n\t\t\t\tthrow new Error(\"Cursor payload hook must return protobuf bytes for a single runRequest\");\n\t\t\tsignal.throwIfAborted();\n\n\t\t\th2Client = http2.connect(baseUrl);\n\t\t\th2Client.on(\"error\", (error) => {\n\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t});\n\t\t\tconst requestHeaders = {\n\t\t\t\t\":method\": \"POST\",\n\t\t\t\t\":path\": CURSOR_RUN_PATH,\n\t\t\t\t\"content-type\": \"application/connect+proto\",\n\t\t\t\t\"connect-protocol-version\": \"1\",\n\t\t\t\tte: \"trailers\",\n\t\t\t\tauthorization: `Bearer ${token}`,\n\t\t\t\t\"x-ghost-mode\": \"true\",\n\t\t\t\t\"x-cursor-client-version\": CURSOR_CLIENT_VERSION,\n\t\t\t\t\"x-cursor-client-type\": \"cli\",\n\t\t\t\t\"x-request-id\": crypto.randomUUID(),\n\t\t\t\t...(options.headers ?? {}),\n\t\t\t};\n\t\t\th2Request = h2Client.request(requestHeaders);\n\t\t\th2Request.on(\"response\", (headers) => {\n\t\t\t\tvoid options.onResponse?.(\n\t\t\t\t\t{ status: Number(headers[\":status\"] ?? 0), headers: headers as Record<string, string> },\n\t\t\t\t\tmodel,\n\t\t\t\t);\n\t\t\t});\n\n\t\t\tlet textBlock: TextBlock | undefined;\n\t\t\tlet thinkingBlock: TextBlock | undefined;\n\t\t\tconst endText = () => {\n\t\t\t\tif (!textBlock) return;\n\t\t\t\tstream.push({ type: \"text_end\", contentIndex: textBlock.index, content: textBlock.text, partial: output });\n\t\t\t\ttextBlock = undefined;\n\t\t\t};\n\t\t\tconst endThinking = () => {\n\t\t\t\tif (!thinkingBlock) return;\n\t\t\t\tstream.push({\n\t\t\t\t\ttype: \"thinking_end\",\n\t\t\t\t\tcontentIndex: thinkingBlock.index,\n\t\t\t\t\tcontent: thinkingBlock.text,\n\t\t\t\t\tpartial: output,\n\t\t\t\t});\n\t\t\t\tthinkingBlock = undefined;\n\t\t\t};\n\n\t\t\tstream.push({ type: \"start\", partial: output });\n\t\t\th2Request.write(frameConnectMessage(payload));\n\t\t\theartbeatTimer = setInterval(\n\t\t\t\t() => write(frameConnectMessage(field(7, new Uint8Array(0)))),\n\t\t\t\tHEARTBEAT_INTERVAL_MS,\n\t\t\t);\n\t\t\tawait new Promise<void>((resolve) => {\n\t\t\t\tlet pending: Buffer = Buffer.alloc(0);\n\t\t\t\th2Request!.on(\"data\", (chunk: Buffer) => {\n\t\t\t\t\tpending = pending.length === 0 ? chunk : Buffer.concat([pending, chunk]);\n\t\t\t\t\twhile (pending.length >= 5) {\n\t\t\t\t\t\tconst flags = pending[0];\n\t\t\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\t\t\tif (length > MAX_FRAME_BYTES) {\n\t\t\t\t\t\t\tendStreamError ??= new Error(`Cursor frame exceeds ${MAX_FRAME_BYTES} bytes`);\n\t\t\t\t\t\t\th2Request?.close();\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (pending.length < 5 + length) break;\n\t\t\t\t\t\tconst messageBytes = pending.subarray(5, 5 + length);\n\t\t\t\t\t\tpending = pending.subarray(5 + length);\n\t\t\t\t\t\tif (flags & CONNECT_END_STREAM_FLAG) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tconst payload = JSON.parse(new TextDecoder().decode(messageBytes)) as {\n\t\t\t\t\t\t\t\t\terror?: { code?: string; message?: string };\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tif (payload.error) {\n\t\t\t\t\t\t\t\t\tendStreamError = new Error(\n\t\t\t\t\t\t\t\t\t\t`Cursor ${payload.error.code ?? \"error\"}: ${payload.error.message ?? \"unknown error\"}`,\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\t\tendStreamError = new Error(\"Failed to parse Cursor end-stream trailer\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tdispatchServerMessage(new ProtoMessage(messageBytes));\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tif (!endStreamError) endStreamError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"trailers\", (trailers) => {\n\t\t\t\t\tconst status = trailers[\"grpc-status\"];\n\t\t\t\t\tconst message = trailers[\"grpc-message\"];\n\t\t\t\t\tif (status && status !== \"0\") {\n\t\t\t\t\t\tendStreamError ??= new Error(\n\t\t\t\t\t\t\t`Cursor gRPC error ${status}: ${decodeURIComponent(String(message ?? \"\"))}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"end\", resolve);\n\t\t\t\th2Request!.on(\"error\", (error) => {\n\t\t\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t\t\t\tresolve();\n\t\t\t\t});\n\t\t\t\th2Request!.on(\"close\", resolve);\n\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\tif (signal.aborted) onAbort();\n\t\t\t});\n\n\t\t\tfunction dispatchServerMessage(message: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 7].filter((n) => message.has(n));\n\t\t\t\t\tconsole.error(`[cursor] server cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tif (message.has(1)) {\n\t\t\t\t\tfor (const update of message.messages(1)) handleInteractionUpdate(update);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(2)) {\n\t\t\t\t\tfor (const exec of message.messages(2)) handleExecMessage(exec);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(4)) {\n\t\t\t\t\tfor (const kv of message.messages(4)) {\n\t\t\t\t\t\tconst id = kv.number(1);\n\t\t\t\t\t\tfor (const getBlob of kv.messages(2)) {\n\t\t\t\t\t\t\tconst blobIdBytes = getBlob.bytes(1) ?? new Uint8Array(0);\n\t\t\t\t\t\t\tconst data = readBlob(built.blobStore, blobIdBytes);\n\t\t\t\t\t\t\tif (CURSOR_DEBUG)\n\t\t\t\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t\t\t\t`[cursor] kv getBlob id=${id} blob=${Buffer.from(blobIdBytes).toString(\"hex\").slice(0, 16)} found=${!!data}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\twrite(kvBlobResult(id, data));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor (const setBlob of kv.messages(3)) {\n\t\t\t\t\t\t\tconst blobIdBytes = setBlob.bytes(1);\n\t\t\t\t\t\t\tconst blobData = setBlob.bytes(2);\n\t\t\t\t\t\t\tif (blobIdBytes && blobData) {\n\t\t\t\t\t\t\t\tbuilt.blobStore.set(Buffer.from(blobIdBytes).toString(\"hex\"), blobData);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\twrite(kvSetBlobResult(id));\n\t\t\t\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] kv setBlob id=${id}`);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(5)) {\n\t\t\t\t\t// execServerControlMessage: abort/stop signals — treat as turn end.\n\t\t\t\t\tfor (const control of message.messages(5)) {\n\t\t\t\t\t\tif (control.has(1)) sawTurnEnded = true;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.has(7)) {\n\t\t\t\t\tfor (const query of message.messages(7)) handleInteractionQuery(query);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionUpdate(update: ProtoMessage): void {\n\t\t\t\tif (CURSOR_DEBUG) {\n\t\t\t\t\tconst cases = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17].filter((n) => update.has(n));\n\t\t\t\t\tconsole.error(`[cursor] update cases=${cases.join(\",\")}`);\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(1)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!textBlock) {\n\t\t\t\t\t\ttextBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"text\", text: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"text_start\", contentIndex: textBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\ttextBlock.text += text;\n\t\t\t\t\t(output.content[textBlock.index] as TextContent).text = textBlock.text;\n\t\t\t\t\tstream.push({ type: \"text_delta\", contentIndex: textBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const delta of update.messages(4)) {\n\t\t\t\t\tendText();\n\t\t\t\t\tconst text = delta.string(1);\n\t\t\t\t\tif (!thinkingBlock) {\n\t\t\t\t\t\tthinkingBlock = { index: output.content.length, text: \"\" };\n\t\t\t\t\t\toutput.content.push({ type: \"thinking\", thinking: \"\", thinkingSignature: \"\" });\n\t\t\t\t\t\tstream.push({ type: \"thinking_start\", contentIndex: thinkingBlock.index, partial: output });\n\t\t\t\t\t}\n\t\t\t\t\tthinkingBlock.text += text;\n\t\t\t\t\t(output.content[thinkingBlock.index] as { thinking: string }).thinking = thinkingBlock.text;\n\t\t\t\t\tstream.push({ type: \"thinking_delta\", contentIndex: thinkingBlock.index, delta: text, partial: output });\n\t\t\t\t}\n\t\t\t\tfor (const tokens of update.messages(8)) {\n\t\t\t\t\toutput.usage.output += tokens.number(1);\n\t\t\t\t}\n\t\t\t\tif (update.has(14)) {\n\t\t\t\t\tendThinking();\n\t\t\t\t\tendText();\n\t\t\t\t\tsawTurnEnded = true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleExecMessage(exec: ProtoMessage): void {\n\t\t\t\tconst id = exec.number(1);\n\t\t\t\tconst execId = exec.string(15);\n\t\t\t\tif (CURSOR_DEBUG) console.error(`[cursor] exec id=${id} execId=${execId} case=${execCaseName(exec)}`);\n\t\t\t\tif (exec.has(10)) {\n\t\t\t\t\t// requestContextArgs — the exec handshake carrying rules/tools.\n\t\t\t\t\tconst result = field(1, field(1, requestContext));\n\t\t\t\t\twrite(execClientResult(id, execId, 10, result));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tfor (const frame of execThrow(id, execId, `Cursor ${execCaseName(exec)} execution is ${REJECTED_SUFFIX}`)) {\n\t\t\t\t\twrite(frame);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfunction handleInteractionQuery(query: ProtoMessage): void {\n\t\t\t\tconst id = query.number(1);\n\t\t\t\tconst approved = field(1, new Uint8Array(0));\n\t\t\t\tfor (const fieldNo of [2, 5, 6, 9]) {\n\t\t\t\t\tif (query.has(fieldNo)) {\n\t\t\t\t\t\twrite(interactionResponse(id, fieldNo, approved));\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (query.has(3)) {\n\t\t\t\t\twrite(interactionResponse(id, 3, field(3, field(1, `Interactive questions are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(4)) {\n\t\t\t\t\twrite(interactionResponse(id, 4, field(2, field(1, `Mode switches are ${REJECTED_SUFFIX}`))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (query.has(7)) {\n\t\t\t\t\t// createPlan → result{ error{ error } }\n\t\t\t\t\twrite(interactionResponse(id, 7, field(1, field(2, field(1, `Plan files are ${REJECTED_SUFFIX}`)))));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// setupVmEnvironmentArgs (8) is intentionally left unanswered rather\n\t\t\t\t// than reporting a fake success.\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tendStreamError ??= error instanceof Error ? error : new Error(String(error));\n\t\t} finally {\n\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\tif (heartbeatTimer) clearInterval(heartbeatTimer);\n\t\t\t// `end()` (graceful half-close) flushes exec/throw frames still queued\n\t\t\t// behind processed data; `close()` is reserved for aborts and the deadline.\n\t\t\tif (signal.aborted) h2Request?.close();\n\t\t\telse h2Request?.end();\n\t\t\th2Client?.close();\n\t\t\tclearTimeout(timer);\n\t\t}\n\n\t\t// Finalize outside the try so close-flush always runs once.\n\t\ttry {\n\t\t\tif (endStreamError) throw endStreamError;\n\t\t\tif (!sawTurnEnded) {\n\t\t\t\tthrow options.signal?.aborted\n\t\t\t\t\t? Object.assign(new Error(\"aborted\"), { name: \"AbortError\" })\n\t\t\t\t\t: new Error(\"Cursor stream ended before the turn completed\");\n\t\t\t}\n\t\t\toutput.stopReason = \"stop\";\n\t\t\toutput.usage.totalTokens =\n\t\t\t\toutput.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;\n\t\t\tcalculateCost(model, output.usage);\n\t\t\tstream.push({ type: \"done\", reason: \"stop\", message: output });\n\t\t} catch (error) {\n\t\t\toutput.stopReason = options.signal?.aborted ? \"aborted\" : \"error\";\n\t\t\toutput.errorMessage = error instanceof Error ? error.message : \"Cursor request failed\";\n\t\t\tstream.push({ type: \"error\", reason: output.stopReason, error: output });\n\t\t} finally {\n\t\t\tstream.end(output);\n\t\t}\n\t})();\n\treturn stream;\n};\n\nfunction execCaseName(exec: ProtoMessage): string {\n\tfor (const [no, name] of EXEC_CASE_NAMES) {\n\t\tif (exec.has(no)) return name;\n\t}\n\treturn \"exec\";\n}\n\nconst EXEC_CASE_NAMES: ReadonlyArray<readonly [number, string]> = [\n\t[2, \"shell\"],\n\t[3, \"write\"],\n\t[4, \"delete\"],\n\t[5, \"grep\"],\n\t[7, \"read\"],\n\t[8, \"ls\"],\n\t[9, \"diagnostics\"],\n\t[10, \"requestContext\"],\n\t[11, \"mcp\"],\n\t[14, \"shellStream\"],\n\t[16, \"backgroundShellSpawn\"],\n\t[17, \"listMcpResources\"],\n\t[18, \"readMcpResource\"],\n\t[20, \"fetch\"],\n\t[21, \"recordScreen\"],\n\t[22, \"computerUse\"],\n\t[23, \"writeShellStdin\"],\n\t[29, \"redactedRead\"],\n\t[36, \"mcpState\"],\n\t[27, \"executeHook\"],\n\t[28, \"subagent\"],\n\t[30, \"forceBackgroundShell\"],\n\t[31, \"forceBackgroundSubagent\"],\n\t[37, \"subagentAwait\"],\n\t[38, \"smartModeClassifier\"],\n\t[40, \"canvasDiagnostics\"],\n\t[41, \"shellAllowlistPrecheck\"],\n\t[42, \"mcpAllowlistPrecheck\"],\n\t[43, \"webFetchAllowlistPrecheck\"],\n\t[44, \"gitDiff\"],\n\t[45, \"piRead\"],\n\t[46, \"piBash\"],\n\t[47, \"piEdit\"],\n\t[48, \"piWrite\"],\n\t[49, \"piGrep\"],\n\t[50, \"piFind\"],\n\t[51, \"piLs\"],\n\t[52, \"conversationSearch\"],\n\t[54, \"agentStoreConflict\"],\n\t[56, \"miniSweAgentBash\"],\n];\n\nexport const streamSimpleCursor: StreamFunction<\"cursor-agent\", SimpleStreamOptions> = (model, context, options) =>\n\tstreamCursor(model, context, options);\n"]}
|