omk-ai 1.2.3 → 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.
Files changed (45) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/image-models.generated.d.ts +45 -0
  3. package/dist/image-models.generated.d.ts.map +1 -1
  4. package/dist/image-models.generated.js +45 -0
  5. package/dist/image-models.generated.js.map +1 -1
  6. package/dist/models.generated.d.ts +1509 -864
  7. package/dist/models.generated.d.ts.map +1 -1
  8. package/dist/models.generated.js +1215 -709
  9. package/dist/models.generated.js.map +1 -1
  10. package/dist/providers/anthropic.d.ts.map +1 -1
  11. package/dist/providers/anthropic.js +5 -0
  12. package/dist/providers/anthropic.js.map +1 -1
  13. package/dist/providers/cursor-connect.d.ts +3 -0
  14. package/dist/providers/cursor-connect.d.ts.map +1 -0
  15. package/dist/providers/cursor-connect.js +9 -0
  16. package/dist/providers/cursor-connect.js.map +1 -0
  17. package/dist/providers/cursor.d.ts.map +1 -1
  18. package/dist/providers/cursor.js +17 -13
  19. package/dist/providers/cursor.js.map +1 -1
  20. package/dist/providers/devin-connect-stream.d.ts.map +1 -1
  21. package/dist/providers/devin-connect-stream.js +3 -1
  22. package/dist/providers/devin-connect-stream.js.map +1 -1
  23. package/dist/stream.d.ts.map +1 -1
  24. package/dist/stream.js +6 -0
  25. package/dist/stream.js.map +1 -1
  26. package/dist/utils/provider-retry-delay.d.ts +4 -0
  27. package/dist/utils/provider-retry-delay.d.ts.map +1 -0
  28. package/dist/utils/provider-retry-delay.js +53 -0
  29. package/dist/utils/provider-retry-delay.js.map +1 -0
  30. package/dist/utils/provider-retry-sleep.d.ts +6 -0
  31. package/dist/utils/provider-retry-sleep.d.ts.map +1 -0
  32. package/dist/utils/provider-retry-sleep.js +51 -0
  33. package/dist/utils/provider-retry-sleep.js.map +1 -0
  34. package/dist/utils/provider-retry.d.ts.map +1 -1
  35. package/dist/utils/provider-retry.js +6 -44
  36. package/dist/utils/provider-retry.js.map +1 -1
  37. package/dist/utils/retry-backoff.d.ts +8 -0
  38. package/dist/utils/retry-backoff.d.ts.map +1 -0
  39. package/dist/utils/retry-backoff.js +19 -0
  40. package/dist/utils/retry-backoff.js.map +1 -0
  41. package/dist/utils/retry.d.ts +11 -3
  42. package/dist/utils/retry.d.ts.map +1 -1
  43. package/dist/utils/retry.js +13 -5
  44. package/dist/utils/retry.js.map +1 -1
  45. package/package.json +1 -1
@@ -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"]}
@@ -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 timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 600_000);
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 (options.signal?.aborted)
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"]}
@@ -1 +1 @@
1
- {"version":3,"file":"devin-connect-stream.d.ts","sourceRoot":"","sources":["../../src/providers/devin-connect-stream.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsCH,oFAAoF;AACpF,wBAAuB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,CA6C5G","sourcesContent":["/**\n * Connect streaming frames for the Devin chat call. Node-only: gzip frames\n * need `node:zlib`, so this module stays off the browser-safe static path\n * (`devin-api.ts` only needs the unary reader in `devin-connect.ts`).\n */\n\nimport { gunzipSync } from \"node:zlib\";\n\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\n\nfunction checkTrailer(payload: Buffer): void {\n\tlet trailer: unknown;\n\ttry {\n\t\ttrailer = JSON.parse(payload.toString(\"utf8\"));\n\t} catch {\n\t\tthrow new Error(\"Invalid Devin Connect trailer\");\n\t}\n\tif (!trailer || typeof trailer !== \"object\" || Array.isArray(trailer))\n\t\tthrow new Error(\"Invalid Devin Connect trailer\");\n\tif (!(\"error\" in trailer) || !trailer.error) return;\n\tconst error = trailer.error;\n\tconst code =\n\t\ttypeof error === \"object\" &&\n\t\t\"code\" in error &&\n\t\ttypeof error.code === \"string\" &&\n\t\t/^[a-z_]{1,40}$/.test(error.code)\n\t\t\t? error.code\n\t\t\t: \"unknown\";\n\tconst message =\n\t\ttypeof error === \"object\" && \"message\" in error && typeof error.message === \"string\" ? error.message : \"\";\n\t// Classify evidence without returning a remote body that may echo secrets or prompts.\n\tif (code === \"resource_exhausted\") throw new Error(\"Devin quota or rate limit exceeded\");\n\tif (code === \"unauthenticated\") throw new Error(\"Devin authentication failed; run /login devin\");\n\tif (\n\t\tcode === \"invalid_argument\" &&\n\t\t/context[_ ]length[_ ]exceeded|prompt is too long|too many tokens|exceeds the context window/i.test(message)\n\t)\n\t\tthrow new Error(\"Devin context_length_exceeded\");\n\tconst traceId = /\\btrace ID:\\s*([a-f0-9]{16,64})(?=[)\\s.,]|$)/i.exec(message)?.[1];\n\tthrow new Error(`Devin stream error: ${code}${traceId ? ` (trace ID: ${traceId})` : \"\"}`);\n}\n\n/** Connect requires an explicit final trailer; an HTTP EOF alone is not success. */\nexport async function* readConnectFrames(response: Response, signal: AbortSignal): AsyncGenerator<Uint8Array> {\n\tif (!response.ok) {\n\t\tawait response.body?.cancel();\n\t\tthrow new Error(`Devin chat failed (HTTP ${response.status})`);\n\t}\n\tif (!response.body) throw new Error(\"Devin returned an empty stream\");\n\tconst reader = response.body.getReader();\n\tlet pending: Buffer = Buffer.alloc(0);\n\tlet ended = false;\n\tconst abort = () => {\n\t\treader.cancel().catch(() => {});\n\t};\n\tsignal.addEventListener(\"abort\", abort, { once: true });\n\ttry {\n\t\tfor (;;) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tsignal.throwIfAborted();\n\t\t\tif (value?.length) pending = Buffer.concat([pending, value]);\n\t\t\twhile (pending.length >= 5) {\n\t\t\t\tif (ended) throw new Error(\"Devin sent data after its terminal trailer\");\n\t\t\t\tconst flags = pending[0];\n\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\tif (flags & ~3) throw new Error(\"Invalid Devin Connect flags\");\n\t\t\t\tif (length > MAX_FRAME_BYTES) throw new Error(\"Devin Connect frame exceeds size limit\");\n\t\t\t\tif (pending.length < length + 5) break;\n\t\t\t\tlet payload = pending.subarray(5, length + 5);\n\t\t\t\tpending = pending.subarray(length + 5);\n\t\t\t\tif (flags & 1) payload = gunzipSync(payload, { maxOutputLength: MAX_FRAME_BYTES });\n\t\t\t\tif (flags & 2) {\n\t\t\t\t\tcheckTrailer(payload);\n\t\t\t\t\tended = true;\n\t\t\t\t} else {\n\t\t\t\t\tyield payload;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (done) break;\n\t\t}\n\t\tif (pending.length) throw new Error(\"Truncated Devin Connect frame\");\n\t\tif (!ended) throw new Error(\"Devin stream missing terminal trailer\");\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", abort);\n\t\tawait reader.cancel();\n\t\treader.releaseLock();\n\t}\n}\n"]}
1
+ {"version":3,"file":"devin-connect-stream.d.ts","sourceRoot":"","sources":["../../src/providers/devin-connect-stream.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwCH,oFAAoF;AACpF,wBAAuB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC,UAAU,CAAC,CA6C5G","sourcesContent":["/**\n * Connect streaming frames for the Devin chat call. Node-only: gzip frames\n * need `node:zlib`, so this module stays off the browser-safe static path\n * (`devin-api.ts` only needs the unary reader in `devin-connect.ts`).\n */\n\nimport { gunzipSync } from \"node:zlib\";\n\nconst MAX_FRAME_BYTES = 16 * 1024 * 1024;\n\nfunction checkTrailer(payload: Buffer): void {\n\tlet trailer: unknown;\n\ttry {\n\t\ttrailer = JSON.parse(payload.toString(\"utf8\"));\n\t} catch {\n\t\tthrow new Error(\"Invalid Devin Connect trailer\");\n\t}\n\tif (!trailer || typeof trailer !== \"object\" || Array.isArray(trailer))\n\t\tthrow new Error(\"Invalid Devin Connect trailer\");\n\tif (!(\"error\" in trailer) || !trailer.error) return;\n\tconst error = trailer.error;\n\tconst code =\n\t\ttypeof error === \"object\" &&\n\t\t\"code\" in error &&\n\t\ttypeof error.code === \"string\" &&\n\t\t/^[a-z_]{1,40}$/.test(error.code)\n\t\t\t? error.code\n\t\t\t: \"unknown\";\n\tconst message =\n\t\ttypeof error === \"object\" && \"message\" in error && typeof error.message === \"string\" ? error.message : \"\";\n\t// Classify evidence without returning a remote body that may echo secrets or prompts.\n\t// Quota wording, not \"rate limit\": the latter is retried in place and skips\n\t// failover and compaction trim. The trailer body is not echoed.\n\tif (code === \"resource_exhausted\") throw new Error(\"Devin quota exceeded\");\n\tif (code === \"unauthenticated\") throw new Error(\"Devin authentication failed; run /login devin\");\n\tif (\n\t\tcode === \"invalid_argument\" &&\n\t\t/context[_ ]length[_ ]exceeded|prompt is too long|too many tokens|exceeds the context window/i.test(message)\n\t)\n\t\tthrow new Error(\"Devin context_length_exceeded\");\n\tconst traceId = /\\btrace ID:\\s*([a-f0-9]{16,64})(?=[)\\s.,]|$)/i.exec(message)?.[1];\n\tthrow new Error(`Devin stream error: ${code}${traceId ? ` (trace ID: ${traceId})` : \"\"}`);\n}\n\n/** Connect requires an explicit final trailer; an HTTP EOF alone is not success. */\nexport async function* readConnectFrames(response: Response, signal: AbortSignal): AsyncGenerator<Uint8Array> {\n\tif (!response.ok) {\n\t\tawait response.body?.cancel();\n\t\tthrow new Error(`Devin chat failed (HTTP ${response.status})`);\n\t}\n\tif (!response.body) throw new Error(\"Devin returned an empty stream\");\n\tconst reader = response.body.getReader();\n\tlet pending: Buffer = Buffer.alloc(0);\n\tlet ended = false;\n\tconst abort = () => {\n\t\treader.cancel().catch(() => {});\n\t};\n\tsignal.addEventListener(\"abort\", abort, { once: true });\n\ttry {\n\t\tfor (;;) {\n\t\t\tsignal.throwIfAborted();\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tsignal.throwIfAborted();\n\t\t\tif (value?.length) pending = Buffer.concat([pending, value]);\n\t\t\twhile (pending.length >= 5) {\n\t\t\t\tif (ended) throw new Error(\"Devin sent data after its terminal trailer\");\n\t\t\t\tconst flags = pending[0];\n\t\t\t\tconst length = pending.readUInt32BE(1);\n\t\t\t\tif (flags & ~3) throw new Error(\"Invalid Devin Connect flags\");\n\t\t\t\tif (length > MAX_FRAME_BYTES) throw new Error(\"Devin Connect frame exceeds size limit\");\n\t\t\t\tif (pending.length < length + 5) break;\n\t\t\t\tlet payload = pending.subarray(5, length + 5);\n\t\t\t\tpending = pending.subarray(length + 5);\n\t\t\t\tif (flags & 1) payload = gunzipSync(payload, { maxOutputLength: MAX_FRAME_BYTES });\n\t\t\t\tif (flags & 2) {\n\t\t\t\t\tcheckTrailer(payload);\n\t\t\t\t\tended = true;\n\t\t\t\t} else {\n\t\t\t\t\tyield payload;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (done) break;\n\t\t}\n\t\tif (pending.length) throw new Error(\"Truncated Devin Connect frame\");\n\t\tif (!ended) throw new Error(\"Devin stream missing terminal trailer\");\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", abort);\n\t\tawait reader.cancel();\n\t\treader.releaseLock();\n\t}\n}\n"]}
@@ -26,8 +26,10 @@ function checkTrailer(payload) {
26
26
  : "unknown";
27
27
  const message = typeof error === "object" && "message" in error && typeof error.message === "string" ? error.message : "";
28
28
  // Classify evidence without returning a remote body that may echo secrets or prompts.
29
+ // Quota wording, not "rate limit": the latter is retried in place and skips
30
+ // failover and compaction trim. The trailer body is not echoed.
29
31
  if (code === "resource_exhausted")
30
- throw new Error("Devin quota or rate limit exceeded");
32
+ throw new Error("Devin quota exceeded");
31
33
  if (code === "unauthenticated")
32
34
  throw new Error("Devin authentication failed; run /login devin");
33
35
  if (code === "invalid_argument" &&