opencode-cursor-proxy 1.0.1

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 (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/README.zh-CN.md +136 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/api/agent-service.d.ts +136 -0
  8. package/dist/lib/api/agent-service.js +938 -0
  9. package/dist/lib/api/agent-service.js.map +1 -0
  10. package/dist/lib/api/ai-service.d.ts +26 -0
  11. package/dist/lib/api/ai-service.js +38 -0
  12. package/dist/lib/api/ai-service.js.map +1 -0
  13. package/dist/lib/api/cursor-client.d.ts +119 -0
  14. package/dist/lib/api/cursor-client.js +511 -0
  15. package/dist/lib/api/cursor-client.js.map +1 -0
  16. package/dist/lib/api/cursor-models.d.ts +13 -0
  17. package/dist/lib/api/cursor-models.js +34 -0
  18. package/dist/lib/api/cursor-models.js.map +1 -0
  19. package/dist/lib/api/openai-compat.d.ts +10 -0
  20. package/dist/lib/api/openai-compat.js +262 -0
  21. package/dist/lib/api/openai-compat.js.map +1 -0
  22. package/dist/lib/api/proto/agent-messages.d.ts +25 -0
  23. package/dist/lib/api/proto/agent-messages.js +132 -0
  24. package/dist/lib/api/proto/agent-messages.js.map +1 -0
  25. package/dist/lib/api/proto/bidi.d.ts +17 -0
  26. package/dist/lib/api/proto/bidi.js +24 -0
  27. package/dist/lib/api/proto/bidi.js.map +1 -0
  28. package/dist/lib/api/proto/decoding.d.ts +19 -0
  29. package/dist/lib/api/proto/decoding.js +118 -0
  30. package/dist/lib/api/proto/decoding.js.map +1 -0
  31. package/dist/lib/api/proto/encoding.d.ts +64 -0
  32. package/dist/lib/api/proto/encoding.js +180 -0
  33. package/dist/lib/api/proto/encoding.js.map +1 -0
  34. package/dist/lib/api/proto/exec.d.ts +12 -0
  35. package/dist/lib/api/proto/exec.js +383 -0
  36. package/dist/lib/api/proto/exec.js.map +1 -0
  37. package/dist/lib/api/proto/index.d.ts +13 -0
  38. package/dist/lib/api/proto/index.js +10 -0
  39. package/dist/lib/api/proto/index.js.map +1 -0
  40. package/dist/lib/api/proto/interaction.d.ts +15 -0
  41. package/dist/lib/api/proto/interaction.js +99 -0
  42. package/dist/lib/api/proto/interaction.js.map +1 -0
  43. package/dist/lib/api/proto/kv.d.ts +52 -0
  44. package/dist/lib/api/proto/kv.js +156 -0
  45. package/dist/lib/api/proto/kv.js.map +1 -0
  46. package/dist/lib/api/proto/tool-calls.d.ts +9 -0
  47. package/dist/lib/api/proto/tool-calls.js +144 -0
  48. package/dist/lib/api/proto/tool-calls.js.map +1 -0
  49. package/dist/lib/api/proto/types.d.ts +201 -0
  50. package/dist/lib/api/proto/types.js +10 -0
  51. package/dist/lib/api/proto/types.js.map +1 -0
  52. package/dist/lib/auth/helpers.d.ts +40 -0
  53. package/dist/lib/auth/helpers.js +103 -0
  54. package/dist/lib/auth/helpers.js.map +1 -0
  55. package/dist/lib/auth/index.d.ts +7 -0
  56. package/dist/lib/auth/index.js +10 -0
  57. package/dist/lib/auth/index.js.map +1 -0
  58. package/dist/lib/auth/login.d.ts +55 -0
  59. package/dist/lib/auth/login.js +184 -0
  60. package/dist/lib/auth/login.js.map +1 -0
  61. package/dist/lib/config.d.ts +153 -0
  62. package/dist/lib/config.js +182 -0
  63. package/dist/lib/config.js.map +1 -0
  64. package/dist/lib/openai-compat/handler.d.ts +40 -0
  65. package/dist/lib/openai-compat/handler.js +808 -0
  66. package/dist/lib/openai-compat/handler.js.map +1 -0
  67. package/dist/lib/openai-compat/index.d.ts +9 -0
  68. package/dist/lib/openai-compat/index.js +13 -0
  69. package/dist/lib/openai-compat/index.js.map +1 -0
  70. package/dist/lib/openai-compat/types.d.ts +127 -0
  71. package/dist/lib/openai-compat/types.js +6 -0
  72. package/dist/lib/openai-compat/types.js.map +1 -0
  73. package/dist/lib/openai-compat/utils.d.ts +143 -0
  74. package/dist/lib/openai-compat/utils.js +348 -0
  75. package/dist/lib/openai-compat/utils.js.map +1 -0
  76. package/dist/lib/session-reuse.d.ts +88 -0
  77. package/dist/lib/session-reuse.js +198 -0
  78. package/dist/lib/session-reuse.js.map +1 -0
  79. package/dist/lib/storage.d.ts +55 -0
  80. package/dist/lib/storage.js +159 -0
  81. package/dist/lib/storage.js.map +1 -0
  82. package/dist/lib/utils/cache.d.ts +131 -0
  83. package/dist/lib/utils/cache.js +297 -0
  84. package/dist/lib/utils/cache.js.map +1 -0
  85. package/dist/lib/utils/fetch.d.ts +84 -0
  86. package/dist/lib/utils/fetch.js +261 -0
  87. package/dist/lib/utils/fetch.js.map +1 -0
  88. package/dist/lib/utils/index.d.ts +13 -0
  89. package/dist/lib/utils/index.js +22 -0
  90. package/dist/lib/utils/index.js.map +1 -0
  91. package/dist/lib/utils/jwt.d.ts +40 -0
  92. package/dist/lib/utils/jwt.js +102 -0
  93. package/dist/lib/utils/jwt.js.map +1 -0
  94. package/dist/lib/utils/logger.d.ts +107 -0
  95. package/dist/lib/utils/logger.js +227 -0
  96. package/dist/lib/utils/logger.js.map +1 -0
  97. package/dist/lib/utils/model-resolver.d.ts +49 -0
  98. package/dist/lib/utils/model-resolver.js +503 -0
  99. package/dist/lib/utils/model-resolver.js.map +1 -0
  100. package/dist/lib/utils/request-pool.d.ts +38 -0
  101. package/dist/lib/utils/request-pool.js +105 -0
  102. package/dist/lib/utils/request-pool.js.map +1 -0
  103. package/dist/lib/utils/request-transformer.d.ts +87 -0
  104. package/dist/lib/utils/request-transformer.js +154 -0
  105. package/dist/lib/utils/request-transformer.js.map +1 -0
  106. package/dist/lib/utils/tokenizer.d.ts +14 -0
  107. package/dist/lib/utils/tokenizer.js +76 -0
  108. package/dist/lib/utils/tokenizer.js.map +1 -0
  109. package/dist/plugin/index.d.ts +8 -0
  110. package/dist/plugin/index.js +9 -0
  111. package/dist/plugin/index.js.map +1 -0
  112. package/dist/plugin/plugin.d.ts +21 -0
  113. package/dist/plugin/plugin.js +309 -0
  114. package/dist/plugin/plugin.js.map +1 -0
  115. package/dist/plugin/types.d.ts +120 -0
  116. package/dist/plugin/types.js +7 -0
  117. package/dist/plugin/types.js.map +1 -0
  118. package/dist/server.d.ts +15 -0
  119. package/dist/server.js +95 -0
  120. package/dist/server.js.map +1 -0
  121. package/package.json +79 -0
@@ -0,0 +1,511 @@
1
+ /**
2
+ * Cursor API Client
3
+ *
4
+ * Implements the Cursor API communication using the Connect-RPC protocol.
5
+ * This is a simplified implementation that handles chat completions.
6
+ */
7
+ import { randomUUID, createHash } from "node:crypto";
8
+ // --- Constants ---
9
+ export const CURSOR_API_URL = "https://api2.cursor.sh";
10
+ export const CURSOR_CHAT_ENDPOINT = "/aiserver.v1.AiService/StreamChat";
11
+ // Role mapping for protobuf: user=1, assistant=2, system=3
12
+ const ROLE_MAP = {
13
+ user: 1,
14
+ assistant: 2,
15
+ system: 3,
16
+ };
17
+ // --- Protobuf Helpers ---
18
+ /**
19
+ * Encode a varint (variable-length integer)
20
+ */
21
+ function encodeVarint(value) {
22
+ const bytes = [];
23
+ while (value > 127) {
24
+ bytes.push((value & 0x7f) | 0x80);
25
+ value >>>= 7;
26
+ }
27
+ bytes.push(value);
28
+ return new Uint8Array(bytes);
29
+ }
30
+ /**
31
+ * Encode a string field in protobuf format
32
+ * Field format: (field_number << 3) | wire_type
33
+ * String wire type = 2
34
+ */
35
+ function encodeStringField(fieldNumber, value) {
36
+ if (!value)
37
+ return new Uint8Array(0);
38
+ const fieldTag = (fieldNumber << 3) | 2; // wire type 2 = length-delimited
39
+ const encoded = new TextEncoder().encode(value);
40
+ const length = encodeVarint(encoded.length);
41
+ const result = new Uint8Array(1 + length.length + encoded.length);
42
+ result[0] = fieldTag;
43
+ result.set(length, 1);
44
+ result.set(encoded, 1 + length.length);
45
+ return result;
46
+ }
47
+ /**
48
+ * Encode an int32 field in protobuf format
49
+ * Wire type = 0 (varint)
50
+ */
51
+ function encodeInt32Field(fieldNumber, value) {
52
+ if (value === 0)
53
+ return new Uint8Array(0);
54
+ const fieldTag = (fieldNumber << 3) | 0; // wire type 0 = varint
55
+ const encoded = encodeVarint(value);
56
+ const result = new Uint8Array(1 + encoded.length);
57
+ result[0] = fieldTag;
58
+ result.set(encoded, 1);
59
+ return result;
60
+ }
61
+ /**
62
+ * Encode a nested message field
63
+ */
64
+ function encodeMessageField(fieldNumber, data) {
65
+ if (data.length === 0)
66
+ return new Uint8Array(0);
67
+ const fieldTag = (fieldNumber << 3) | 2; // wire type 2 = length-delimited
68
+ const length = encodeVarint(data.length);
69
+ const result = new Uint8Array(1 + length.length + data.length);
70
+ result[0] = fieldTag;
71
+ result.set(length, 1);
72
+ result.set(data, 1 + length.length);
73
+ return result;
74
+ }
75
+ /**
76
+ * Concatenate multiple Uint8Arrays
77
+ */
78
+ function concatBytes(...arrays) {
79
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
80
+ const result = new Uint8Array(totalLength);
81
+ let offset = 0;
82
+ for (const arr of arrays) {
83
+ result.set(arr, offset);
84
+ offset += arr.length;
85
+ }
86
+ return result;
87
+ }
88
+ // --- Cursor Message Encoding ---
89
+ /**
90
+ * Encode a single user message for the Cursor API
91
+ *
92
+ * Message structure (based on OpenCursor's message.proto):
93
+ * - content: field 1 (string)
94
+ * - role: field 2 (int32)
95
+ * - messageId: field 13 (string)
96
+ */
97
+ function encodeUserMessage(message, messageId) {
98
+ return concatBytes(encodeStringField(1, message.content), encodeInt32Field(2, ROLE_MAP[message.role] ?? 1), encodeStringField(13, messageId));
99
+ }
100
+ /**
101
+ * Encode instructions (system prompt)
102
+ * - instruction: field 1 (string)
103
+ */
104
+ function encodeInstructions(systemPrompt) {
105
+ return encodeStringField(1, systemPrompt);
106
+ }
107
+ /**
108
+ * Encode model info
109
+ * - name: field 1 (string)
110
+ * - empty: field 4 (string) - always empty
111
+ */
112
+ function encodeModel(modelName) {
113
+ return concatBytes(encodeStringField(1, modelName), encodeStringField(4, ""));
114
+ }
115
+ /**
116
+ * Encode a complete ChatMessage for the Cursor API
117
+ *
118
+ * ChatMessage structure:
119
+ * - messages: field 2 (repeated UserMessage)
120
+ * - instructions: field 4 (Instructions)
121
+ * - projectPath: field 5 (string)
122
+ * - model: field 7 (Model)
123
+ * - requestId: field 9 (string)
124
+ * - summary: field 11 (string)
125
+ * - conversationId: field 15 (string)
126
+ */
127
+ export function encodeChatRequest(request) {
128
+ const requestId = randomUUID();
129
+ const conversationId = randomUUID();
130
+ // Find system message for instructions
131
+ const systemMessage = request.messages.find(m => m.role === "system");
132
+ const chatMessages = request.messages.filter(m => m.role !== "system");
133
+ // Encode all user/assistant messages
134
+ const encodedMessages = chatMessages.map((msg) => encodeMessageField(2, encodeUserMessage(msg, randomUUID())));
135
+ // Encode instructions if present
136
+ const encodedInstructions = systemMessage
137
+ ? encodeMessageField(4, encodeInstructions(systemMessage.content))
138
+ : new Uint8Array(0);
139
+ // Encode model
140
+ const encodedModel = encodeMessageField(7, encodeModel(request.model));
141
+ // Combine all fields
142
+ const messageBody = concatBytes(...encodedMessages, encodedInstructions, encodeStringField(5, "/project"), encodedModel, encodeStringField(9, requestId), encodeStringField(11, ""), encodeStringField(15, conversationId));
143
+ return messageBody;
144
+ }
145
+ /**
146
+ * Add Connect-RPC envelope (5-byte header)
147
+ * Format: [flags: 1 byte][length: 4 bytes big-endian][payload]
148
+ */
149
+ export function addConnectEnvelope(data, flags = 0) {
150
+ const result = new Uint8Array(5 + data.length);
151
+ result[0] = flags;
152
+ result[1] = (data.length >> 24) & 0xff;
153
+ result[2] = (data.length >> 16) & 0xff;
154
+ result[3] = (data.length >> 8) & 0xff;
155
+ result[4] = data.length & 0xff;
156
+ result.set(data, 5);
157
+ return result;
158
+ }
159
+ // --- Response Decoding ---
160
+ /**
161
+ * Decode a varint from a buffer
162
+ */
163
+ function decodeVarint(data, offset) {
164
+ let value = 0;
165
+ let shift = 0;
166
+ let bytesRead = 0;
167
+ while (offset + bytesRead < data.length) {
168
+ const byte = data[offset + bytesRead];
169
+ value |= (byte & 0x7f) << shift;
170
+ bytesRead++;
171
+ if ((byte & 0x80) === 0) {
172
+ break;
173
+ }
174
+ shift += 7;
175
+ }
176
+ return { value, bytesRead };
177
+ }
178
+ /**
179
+ * Decode a string from protobuf data
180
+ */
181
+ function decodeString(data, offset, length) {
182
+ return new TextDecoder().decode(data.slice(offset, offset + length));
183
+ }
184
+ /**
185
+ * Decode a ResMessage from protobuf
186
+ * ResMessage: msg is field 1 (string)
187
+ */
188
+ function decodeResMessage(data) {
189
+ let offset = 0;
190
+ let result = "";
191
+ while (offset < data.length) {
192
+ const fieldInfo = decodeVarint(data, offset);
193
+ offset += fieldInfo.bytesRead;
194
+ const fieldNumber = fieldInfo.value >> 3;
195
+ const wireType = fieldInfo.value & 0x7;
196
+ if (wireType === 2) { // length-delimited
197
+ const lengthInfo = decodeVarint(data, offset);
198
+ offset += lengthInfo.bytesRead;
199
+ if (fieldNumber === 1) { // msg field
200
+ result = decodeString(data, offset, lengthInfo.value);
201
+ }
202
+ offset += lengthInfo.value;
203
+ }
204
+ else if (wireType === 0) { // varint
205
+ const valueInfo = decodeVarint(data, offset);
206
+ offset += valueInfo.bytesRead;
207
+ }
208
+ else {
209
+ // Unknown wire type, try to skip
210
+ break;
211
+ }
212
+ }
213
+ return result;
214
+ }
215
+ /**
216
+ * Parse Connect-RPC streaming response chunks
217
+ */
218
+ export function parseStreamChunks(buffer) {
219
+ const chunks = [];
220
+ let offset = 0;
221
+ while (offset + 5 <= buffer.length) {
222
+ const flags = buffer[offset];
223
+ const length = (buffer[offset + 1] << 24) |
224
+ (buffer[offset + 2] << 16) |
225
+ (buffer[offset + 3] << 8) |
226
+ buffer[offset + 4];
227
+ offset += 5;
228
+ if (offset + length > buffer.length) {
229
+ break;
230
+ }
231
+ const messageData = buffer.slice(offset, offset + length);
232
+ offset += length;
233
+ // Check for error flag (0x02)
234
+ if (flags === 0x02) {
235
+ try {
236
+ const errorText = new TextDecoder().decode(messageData);
237
+ chunks.push({ type: "error", error: errorText });
238
+ }
239
+ catch {
240
+ chunks.push({ type: "error", error: "Unknown error" });
241
+ }
242
+ continue;
243
+ }
244
+ // Normal message - decode as ResMessage
245
+ try {
246
+ const content = decodeResMessage(messageData);
247
+ if (content) {
248
+ chunks.push({ type: "delta", content });
249
+ }
250
+ }
251
+ catch {
252
+ // Skip malformed messages
253
+ }
254
+ }
255
+ return chunks;
256
+ }
257
+ // --- Checksum Generation ---
258
+ /**
259
+ * Generate checksum for Cursor API requests
260
+ * Based on OpenCursor's implementation
261
+ */
262
+ export function generateChecksum(token) {
263
+ const salt = token.split(".");
264
+ // XOR-based obfuscation
265
+ const calc = (data) => {
266
+ let t = 165;
267
+ for (let i = 0; i < data.length; i++) {
268
+ data[i] = ((data[i] ^ t) + i) & 0xff;
269
+ t = data[i];
270
+ }
271
+ };
272
+ // Timestamp rounded to 30-minute intervals
273
+ const now = new Date();
274
+ now.setMinutes(30 * Math.floor(now.getMinutes() / 30), 0, 0);
275
+ const timestamp = Math.floor(now.getTime() / 1e6);
276
+ // Create timestamp buffer
277
+ const timestampBuffer = Buffer.alloc(6);
278
+ let temp = timestamp;
279
+ for (let i = 5; i >= 0; i--) {
280
+ timestampBuffer[i] = temp & 0xff;
281
+ temp = Math.floor(temp / 256);
282
+ }
283
+ calc(timestampBuffer);
284
+ // SHA-256 hashes
285
+ const calcHex = (input) => {
286
+ return createHash("sha256").update(input).digest("hex").slice(0, 8);
287
+ };
288
+ const hex1 = salt[1] ? calcHex(salt[1]) : "00000000";
289
+ const hex2 = calcHex(token);
290
+ return `${timestampBuffer.toString("base64url")}${hex1}/${hex2}`;
291
+ }
292
+ export class CursorClient {
293
+ baseUrl;
294
+ accessToken;
295
+ headers;
296
+ constructor(accessToken, options = {}) {
297
+ this.accessToken = accessToken;
298
+ this.baseUrl = options.baseUrl ?? CURSOR_API_URL;
299
+ this.headers = options.headers ?? {};
300
+ }
301
+ /**
302
+ * Expose the configured base URL (needed for ancillary Cursor calls).
303
+ */
304
+ getBaseUrl() {
305
+ return this.baseUrl;
306
+ }
307
+ /**
308
+ * Get request headers for Cursor API
309
+ *
310
+ * IMPORTANT: Cursor's API requires `application/grpc-web+proto` content-type.
311
+ * Using `application/connect+proto` returns 415 Unsupported Media Type.
312
+ */
313
+ getHeaders() {
314
+ const checksum = generateChecksum(this.accessToken);
315
+ return {
316
+ "authorization": `Bearer ${this.accessToken}`,
317
+ "content-type": "application/grpc-web+proto",
318
+ "user-agent": "connect-es/1.4.0",
319
+ "x-cursor-checksum": checksum,
320
+ "x-cursor-client-version": "cli-2025.11.25-d5b3271",
321
+ "x-cursor-client-type": "cli",
322
+ "x-cursor-timezone": Intl.DateTimeFormat().resolvedOptions().timeZone,
323
+ "x-ghost-mode": "true",
324
+ "x-request-id": randomUUID(),
325
+ "host": new URL(this.baseUrl).host,
326
+ ...this.headers,
327
+ };
328
+ }
329
+ /**
330
+ * Build request headers with optional overrides.
331
+ */
332
+ buildHeaders(extra = {}) {
333
+ return { ...this.getHeaders(), ...extra };
334
+ }
335
+ /**
336
+ * Send a chat completion request (non-streaming)
337
+ */
338
+ async chat(request) {
339
+ const messageBody = encodeChatRequest(request);
340
+ const envelope = addConnectEnvelope(messageBody);
341
+ const response = await fetch(`${this.baseUrl}${CURSOR_CHAT_ENDPOINT}`, {
342
+ method: "POST",
343
+ headers: this.getHeaders(),
344
+ body: Buffer.from(envelope),
345
+ });
346
+ if (!response.ok) {
347
+ const errorText = await response.text();
348
+ throw new Error(`Cursor API error: ${response.status} - ${errorText}`);
349
+ }
350
+ const buffer = new Uint8Array(await response.arrayBuffer());
351
+ const chunks = parseStreamChunks(buffer);
352
+ // Combine all content
353
+ let result = "";
354
+ for (const chunk of chunks) {
355
+ if (chunk.type === "error") {
356
+ throw new Error(chunk.error ?? "Unknown error");
357
+ }
358
+ if (chunk.type === "delta" && chunk.content) {
359
+ result += chunk.content;
360
+ }
361
+ }
362
+ return result;
363
+ }
364
+ /**
365
+ * Send a streaming chat completion request
366
+ */
367
+ async *chatStream(request) {
368
+ const messageBody = encodeChatRequest(request);
369
+ const envelope = addConnectEnvelope(messageBody);
370
+ const response = await fetch(`${this.baseUrl}${CURSOR_CHAT_ENDPOINT}`, {
371
+ method: "POST",
372
+ headers: this.getHeaders(),
373
+ body: Buffer.from(envelope),
374
+ });
375
+ if (!response.ok) {
376
+ const errorText = await response.text();
377
+ throw new Error(`Cursor API error: ${response.status} - ${errorText}`);
378
+ }
379
+ if (!response.body) {
380
+ throw new Error("No response body");
381
+ }
382
+ const reader = response.body.getReader();
383
+ let buffer = new Uint8Array(0);
384
+ try {
385
+ while (true) {
386
+ const { done, value } = await reader.read();
387
+ if (done) {
388
+ // Process remaining buffer
389
+ if (buffer.length > 0) {
390
+ const chunks = parseStreamChunks(buffer);
391
+ for (const chunk of chunks) {
392
+ yield chunk;
393
+ }
394
+ }
395
+ yield { type: "done" };
396
+ break;
397
+ }
398
+ // Append to buffer
399
+ const newBuffer = new Uint8Array(buffer.length + value.length);
400
+ newBuffer.set(buffer);
401
+ newBuffer.set(value, buffer.length);
402
+ buffer = newBuffer;
403
+ // Try to parse complete messages
404
+ const chunks = parseStreamChunks(buffer);
405
+ for (const chunk of chunks) {
406
+ yield chunk;
407
+ }
408
+ // Note: In a production implementation, we'd track how much was consumed
409
+ // and keep the remaining partial message in the buffer
410
+ }
411
+ }
412
+ finally {
413
+ reader.releaseLock();
414
+ }
415
+ }
416
+ /**
417
+ * Fetch available models from the Cursor API.
418
+ * This is a working endpoint that returns the list of models available to the user.
419
+ */
420
+ async getModels() {
421
+ const emptyPayload = addConnectEnvelope(new Uint8Array(0), 0);
422
+ const response = await fetch(`${this.baseUrl}/aiserver.v1.AiService/GetUsableModels`, {
423
+ method: "POST",
424
+ headers: this.getHeaders(),
425
+ body: Buffer.from(emptyPayload),
426
+ });
427
+ if (!response.ok) {
428
+ const errorText = await response.text();
429
+ throw new Error(`Cursor API error: ${response.status} - ${errorText}`);
430
+ }
431
+ const buffer = new Uint8Array(await response.arrayBuffer());
432
+ // Parse gRPC-web frame
433
+ if (buffer.length < 5) {
434
+ return { models: [] };
435
+ }
436
+ const flags = buffer[0];
437
+ const length = (buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) | buffer[4];
438
+ // Check for trailer frame (flags=128)
439
+ if (flags === 128) {
440
+ // Trailer frame - parse error if present
441
+ const trailerData = buffer.slice(5, 5 + length);
442
+ const trailerText = new TextDecoder().decode(trailerData);
443
+ if (trailerText.includes('grpc-status:') && !trailerText.includes('grpc-status: 0')) {
444
+ throw new Error(`gRPC error: ${trailerText}`);
445
+ }
446
+ return { models: [] };
447
+ }
448
+ // For now, return raw proto data indicator - proper parsing requires proto definitions
449
+ // The response is a GetUsableModelsResponse protobuf message
450
+ return {
451
+ models: [{ raw: true, size: length }]
452
+ };
453
+ }
454
+ /**
455
+ * Fetch the default model for CLI usage.
456
+ */
457
+ async getDefaultModel() {
458
+ const emptyPayload = addConnectEnvelope(new Uint8Array(0), 0);
459
+ const response = await fetch(`${this.baseUrl}/aiserver.v1.AiService/GetDefaultModelForCli`, {
460
+ method: "POST",
461
+ headers: this.getHeaders(),
462
+ body: Buffer.from(emptyPayload),
463
+ });
464
+ if (!response.ok) {
465
+ const errorText = await response.text();
466
+ throw new Error(`Cursor API error: ${response.status} - ${errorText}`);
467
+ }
468
+ const buffer = new Uint8Array(await response.arrayBuffer());
469
+ if (buffer.length < 5) {
470
+ return { model: null };
471
+ }
472
+ const flags = buffer[0];
473
+ const length = (buffer[1] << 24) | (buffer[2] << 16) | (buffer[3] << 8) | buffer[4];
474
+ if (flags === 128 || length === 0) {
475
+ return { model: null };
476
+ }
477
+ // Return raw proto data indicator
478
+ return {
479
+ model: { raw: true, size: length }
480
+ };
481
+ }
482
+ /**
483
+ * Health check endpoint.
484
+ */
485
+ async healthCheck() {
486
+ const emptyPayload = addConnectEnvelope(new Uint8Array(0), 0);
487
+ const response = await fetch(`${this.baseUrl}/aiserver.v1.AiService/HealthCheck`, {
488
+ method: "POST",
489
+ headers: this.getHeaders(),
490
+ body: Buffer.from(emptyPayload),
491
+ });
492
+ return response.ok;
493
+ }
494
+ }
495
+ /**
496
+ * Create a Cursor API client
497
+ *
498
+ * NOTE: As of late 2024, Cursor has deprecated the legacy StreamChat endpoint.
499
+ * Chat functionality now requires the AgentService with bidirectional streaming.
500
+ * The client currently supports:
501
+ * - getModels() - Fetch available models
502
+ * - getDefaultModel() - Get default model for CLI
503
+ * - healthCheck() - Check API health
504
+ *
505
+ * For chat completions, you need to use the AgentService endpoints which require
506
+ * proper proto message construction and bidirectional streaming support.
507
+ */
508
+ export function createCursorClient(accessToken, options) {
509
+ return new CursorClient(accessToken, options);
510
+ }
511
+ //# sourceMappingURL=cursor-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-client.js","sourceRoot":"","sources":["../../../src/lib/api/cursor-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { CursorClient } from "./cursor-client";
2
+ export interface CursorModelInfo {
3
+ modelId: string;
4
+ displayModelId?: string;
5
+ aliases: string[];
6
+ displayName?: string;
7
+ displayNameShort?: string;
8
+ }
9
+ /**
10
+ * List available Cursor models using the GetUsableModels RPC over Connect JSON.
11
+ * Falls back to an empty list on errors.
12
+ */
13
+ export declare function listCursorModels(cursorClient: CursorClient): Promise<CursorModelInfo[]>;
@@ -0,0 +1,34 @@
1
+ import { CursorClient } from "./cursor-client";
2
+ import { AiServiceClient } from "./ai-service";
3
+ /**
4
+ * List available Cursor models using the GetUsableModels RPC over Connect JSON.
5
+ * Falls back to an empty list on errors.
6
+ */
7
+ export async function listCursorModels(cursorClient) {
8
+ try {
9
+ const aiService = new AiServiceClient(cursorClient);
10
+ const models = await aiService.getUsableModels();
11
+ const result = [];
12
+ for (const m of models) {
13
+ const modelId = typeof m?.modelId === "string" ? m.modelId : undefined;
14
+ const displayModelId = typeof m?.displayModelId === "string" ? m.displayModelId : undefined;
15
+ if (!modelId && !displayModelId) {
16
+ continue;
17
+ }
18
+ result.push({
19
+ modelId: modelId ?? displayModelId ?? "",
20
+ displayModelId,
21
+ aliases: Array.isArray(m?.aliases)
22
+ ? (m?.aliases).filter((a) => typeof a === "string")
23
+ : [],
24
+ displayName: typeof m?.displayName === "string" ? m.displayName : undefined,
25
+ displayNameShort: typeof m?.displayNameShort === "string" ? m.displayNameShort : undefined,
26
+ });
27
+ }
28
+ return result;
29
+ }
30
+ catch {
31
+ return [];
32
+ }
33
+ }
34
+ //# sourceMappingURL=cursor-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-models.js","sourceRoot":"","sources":["../../../src/lib/api/cursor-models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAU/C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,YAA0B;IAC/D,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,eAAe,CAAC,YAAY,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,eAAe,EAAE,CAAC;QACjD,MAAM,MAAM,GAAsB,EAAE,CAAC;QAErC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,OAAO,CAAC,EAAE,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,MAAM,cAAc,GAClB,OAAO,CAAC,EAAE,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;YACvE,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;gBAChC,SAAS;YACX,CAAC;YACD,MAAM,CAAC,IAAI,CAAC;gBACV,OAAO,EAAE,OAAO,IAAI,cAAc,IAAI,EAAE;gBACxC,cAAc;gBACd,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC;oBAChC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAqB,CAAA,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;oBAC7E,CAAC,CAAC,EAAE;gBACN,WAAW,EAAE,OAAO,CAAC,EAAE,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;gBAC3E,gBAAgB,EACd,OAAO,CAAC,EAAE,gBAAgB,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS;aAC3E,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { CursorClient } from "./cursor-client";
2
+ /**
3
+ * Detects OpenAI-style chat completion requests.
4
+ */
5
+ export declare function isOpenAIChatCompletionsRequest(input: string | Request | URL): input is string;
6
+ /**
7
+ * Handles OpenAI-compatible chat completion requests by routing them to Cursor.
8
+ * Returns a Response when the request is handled; otherwise returns null.
9
+ */
10
+ export declare function handleOpenAIChatCompletions(input: string | Request | URL, init: RequestInit | undefined, client: CursorClient): Promise<Response | null>;