@alumnium/cursor 0.0.0-stage → 0.24.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +2 -2
- package/package.json +39 -4
- package/src/index.cjs +1194 -0
- package/src/index.cjs.map +16 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +1069 -0
- package/src/index.js.map +16 -0
- package/src/llm/CursorLanguageModel.d.ts +27 -0
- package/src/llm/cursorProviders.d.ts +2 -0
- package/src/standalone/cursorSdkManifest.d.ts +20 -0
- package/src/standalone/cursorSdkResolver.d.ts +17 -0
- package/src/standalone/cursorSdkVendorManifest.d.ts +2 -0
- package/src/standalone/installCursorSdk.d.ts +38 -0
- package/src/standalone/untar.d.ts +8 -0
package/src/index.cjs
ADDED
|
@@ -0,0 +1,1194 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode
|
|
16
|
+
? (__toESMCache_node ??= new WeakMap())
|
|
17
|
+
: (__toESMCache_esm ??= new WeakMap());
|
|
18
|
+
var cached = cache.get(mod);
|
|
19
|
+
if (cached) return cached;
|
|
20
|
+
}
|
|
21
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
|
+
const to =
|
|
23
|
+
isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default")
|
|
24
|
+
? __defProp(target, "default", { value: mod, enumerable: true })
|
|
25
|
+
: target;
|
|
26
|
+
if ((mod && typeof mod === "object") || typeof mod === "function") {
|
|
27
|
+
for (let key of __getOwnPropNames(mod))
|
|
28
|
+
if (!__hasOwnProp.call(to, key))
|
|
29
|
+
__defProp(to, key, {
|
|
30
|
+
get: __accessProp.bind(mod, key),
|
|
31
|
+
enumerable: true,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (canCache) cache.set(mod, to);
|
|
35
|
+
return to;
|
|
36
|
+
};
|
|
37
|
+
var __toCommonJS = (from) => {
|
|
38
|
+
var entry = (__moduleCache ??= new WeakMap()).get(from),
|
|
39
|
+
desc;
|
|
40
|
+
if (entry) return entry;
|
|
41
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
42
|
+
if ((from && typeof from === "object") || typeof from === "function") {
|
|
43
|
+
for (var key of __getOwnPropNames(from))
|
|
44
|
+
if (!__hasOwnProp.call(entry, key))
|
|
45
|
+
__defProp(entry, key, {
|
|
46
|
+
get: __accessProp.bind(from, key),
|
|
47
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
__moduleCache.set(from, entry);
|
|
51
|
+
return entry;
|
|
52
|
+
};
|
|
53
|
+
var __moduleCache;
|
|
54
|
+
var __returnValue = (v) => v;
|
|
55
|
+
function __exportSetter(name, newValue) {
|
|
56
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
57
|
+
}
|
|
58
|
+
var __export = (target, all) => {
|
|
59
|
+
for (var name in all)
|
|
60
|
+
__defProp(target, name, {
|
|
61
|
+
get: all[name],
|
|
62
|
+
enumerable: true,
|
|
63
|
+
configurable: true,
|
|
64
|
+
set: __exportSetter.bind(all, name),
|
|
65
|
+
});
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// cursor/src/index.ts
|
|
69
|
+
var exports_src = {};
|
|
70
|
+
__export(exports_src, {
|
|
71
|
+
CursorLanguageModel: () => CursorLanguageModel,
|
|
72
|
+
cursorProviders: () => cursorProviders,
|
|
73
|
+
});
|
|
74
|
+
module.exports = __toCommonJS(exports_src);
|
|
75
|
+
|
|
76
|
+
// cursor/src/llm/CursorLanguageModel.ts
|
|
77
|
+
var import_promises = __toESM(require("node:fs/promises"), 1);
|
|
78
|
+
var import_node_os = __toESM(require("node:os"), 1);
|
|
79
|
+
var import_node_path = __toESM(require("node:path"), 1);
|
|
80
|
+
var import_provider = require("@ai-sdk/provider");
|
|
81
|
+
var import_zod = require("zod");
|
|
82
|
+
var import_internal = require("@alumnium/core/internal");
|
|
83
|
+
var logger = import_internal.Logger.get(
|
|
84
|
+
"packages/typescript/cursor/src/llm/CursorLanguageModel.ts",
|
|
85
|
+
);
|
|
86
|
+
var CHAT_CONTEXT = `# Execution context
|
|
87
|
+
You are used as a chat completion model inside another application.
|
|
88
|
+
Do NOT read or write files, run terminal commands, search the web, or use any
|
|
89
|
+
built-in or MCP tools. Reply with a single final assistant message directly.`;
|
|
90
|
+
var ToolCallsResponse = import_zod.z.object({
|
|
91
|
+
tool_calls: import_zod.z.array(
|
|
92
|
+
import_zod.z.object({
|
|
93
|
+
name: import_zod.z.string(),
|
|
94
|
+
arguments: import_zod.z
|
|
95
|
+
.record(import_zod.z.string(), import_zod.z.unknown())
|
|
96
|
+
.optional(),
|
|
97
|
+
args: import_zod.z
|
|
98
|
+
.record(import_zod.z.string(), import_zod.z.unknown())
|
|
99
|
+
.optional(),
|
|
100
|
+
}),
|
|
101
|
+
),
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
class CursorLanguageModel {
|
|
105
|
+
specificationVersion = "v4";
|
|
106
|
+
provider = "cursor";
|
|
107
|
+
modelId;
|
|
108
|
+
supportedUrls = {};
|
|
109
|
+
#options;
|
|
110
|
+
#sandbox = true;
|
|
111
|
+
constructor(options) {
|
|
112
|
+
this.modelId = options.modelId;
|
|
113
|
+
this.#options = options;
|
|
114
|
+
}
|
|
115
|
+
async doGenerate(options) {
|
|
116
|
+
const abort = createAbortScope(options.abortSignal);
|
|
117
|
+
try {
|
|
118
|
+
return await this.#generateOnce(options, abort);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
options.abortSignal?.throwIfAborted();
|
|
121
|
+
if (
|
|
122
|
+
this.#sandbox &&
|
|
123
|
+
error instanceof Error &&
|
|
124
|
+
error.name === "ConfigurationError" &&
|
|
125
|
+
/sandbox/i.test(error.message)
|
|
126
|
+
) {
|
|
127
|
+
logger.warn(
|
|
128
|
+
"Cursor SDK sandboxing is not supported; retrying without it.",
|
|
129
|
+
);
|
|
130
|
+
this.#sandbox = false;
|
|
131
|
+
return await this.doGenerate(options);
|
|
132
|
+
}
|
|
133
|
+
if (
|
|
134
|
+
error instanceof Error &&
|
|
135
|
+
(error.name === "RateLimitError" ||
|
|
136
|
+
error.name === "TimeoutError" ||
|
|
137
|
+
("isRetryable" in error && error.isRetryable === true))
|
|
138
|
+
) {
|
|
139
|
+
throw new import_provider.APICallError({
|
|
140
|
+
message: error.message,
|
|
141
|
+
url: "cursor://local",
|
|
142
|
+
requestBodyValues: { model: this.modelId },
|
|
143
|
+
isRetryable: true,
|
|
144
|
+
cause: error,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
} finally {
|
|
149
|
+
abort.dispose();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async doStream(options) {
|
|
153
|
+
const result = await this.doGenerate(options);
|
|
154
|
+
return {
|
|
155
|
+
stream: new ReadableStream({
|
|
156
|
+
start(controller) {
|
|
157
|
+
controller.enqueue({
|
|
158
|
+
type: "stream-start",
|
|
159
|
+
warnings: result.warnings,
|
|
160
|
+
});
|
|
161
|
+
controller.enqueue({ type: "response-metadata", ...result.response });
|
|
162
|
+
for (const part of result.content) {
|
|
163
|
+
if (part.type === "text") {
|
|
164
|
+
const id = crypto.randomUUID();
|
|
165
|
+
controller.enqueue({ type: "text-start", id });
|
|
166
|
+
controller.enqueue({ type: "text-delta", id, delta: part.text });
|
|
167
|
+
controller.enqueue({ type: "text-end", id });
|
|
168
|
+
} else if (part.type === "tool-call") {
|
|
169
|
+
controller.enqueue(part);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
controller.enqueue({
|
|
173
|
+
type: "finish",
|
|
174
|
+
usage: result.usage,
|
|
175
|
+
finishReason: result.finishReason,
|
|
176
|
+
});
|
|
177
|
+
controller.close();
|
|
178
|
+
},
|
|
179
|
+
}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
async #generateOnce(options, abort) {
|
|
183
|
+
const signal = options.abortSignal;
|
|
184
|
+
signal?.throwIfAborted();
|
|
185
|
+
const prompt = serializePrompt(options);
|
|
186
|
+
const contract = responseContract(options);
|
|
187
|
+
const sdk = await abort.run((this.#options.sdkLoader ?? loadCursorSdk)());
|
|
188
|
+
const root = await import_promises.default.mkdtemp(
|
|
189
|
+
import_node_path.default.join(
|
|
190
|
+
import_node_os.default.tmpdir(),
|
|
191
|
+
"alumnium-cursor-",
|
|
192
|
+
),
|
|
193
|
+
);
|
|
194
|
+
let agent;
|
|
195
|
+
try {
|
|
196
|
+
const cwd = import_node_path.default.join(root, "workspace");
|
|
197
|
+
await import_promises.default.mkdir(cwd);
|
|
198
|
+
const store = new sdk.JsonlLocalAgentStore(
|
|
199
|
+
import_node_path.default.join(root, "store"),
|
|
200
|
+
);
|
|
201
|
+
signal?.throwIfAborted();
|
|
202
|
+
agent = await abort.run(
|
|
203
|
+
sdk.Agent.create({
|
|
204
|
+
...(this.#options.apiKey ? { apiKey: this.#options.apiKey } : {}),
|
|
205
|
+
model: { id: this.modelId },
|
|
206
|
+
local: {
|
|
207
|
+
cwd,
|
|
208
|
+
settingSources: [],
|
|
209
|
+
sandboxOptions: { enabled: this.#sandbox },
|
|
210
|
+
store,
|
|
211
|
+
},
|
|
212
|
+
}),
|
|
213
|
+
async (lateAgent) => {
|
|
214
|
+
try {
|
|
215
|
+
lateAgent.close();
|
|
216
|
+
} finally {
|
|
217
|
+
await import_promises.default.rm(root, {
|
|
218
|
+
recursive: true,
|
|
219
|
+
force: true,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
);
|
|
224
|
+
const first = await send(
|
|
225
|
+
agent,
|
|
226
|
+
{
|
|
227
|
+
text: [prompt.text, CHAT_CONTEXT, contract].filter(Boolean).join(`
|
|
228
|
+
|
|
229
|
+
`),
|
|
230
|
+
images: prompt.images,
|
|
231
|
+
},
|
|
232
|
+
abort,
|
|
233
|
+
);
|
|
234
|
+
const usages = [first.usage];
|
|
235
|
+
let content;
|
|
236
|
+
try {
|
|
237
|
+
content = parseResponse(first.result ?? "", options);
|
|
238
|
+
} catch (error) {
|
|
239
|
+
const retry = await send(
|
|
240
|
+
agent,
|
|
241
|
+
{
|
|
242
|
+
text: `Your previous reply was invalid: ${error instanceof Error ? error.message : String(error)}
|
|
243
|
+
Respond again following this contract exactly:
|
|
244
|
+
${contract}`,
|
|
245
|
+
},
|
|
246
|
+
abort,
|
|
247
|
+
);
|
|
248
|
+
usages.push(retry.usage);
|
|
249
|
+
content = parseResponse(retry.result ?? "", options);
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
content,
|
|
253
|
+
finishReason: {
|
|
254
|
+
unified: content.some((part) => part.type === "tool-call")
|
|
255
|
+
? "tool-calls"
|
|
256
|
+
: "stop",
|
|
257
|
+
raw: "finished",
|
|
258
|
+
},
|
|
259
|
+
usage: toUsage(usages),
|
|
260
|
+
warnings: [],
|
|
261
|
+
response: { id: first.id, modelId: this.modelId },
|
|
262
|
+
};
|
|
263
|
+
} finally {
|
|
264
|
+
try {
|
|
265
|
+
agent?.close();
|
|
266
|
+
} finally {
|
|
267
|
+
await import_promises.default.rm(root, {
|
|
268
|
+
recursive: true,
|
|
269
|
+
force: true,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
async function loadCursorSdk() {
|
|
276
|
+
return import("@cursor/sdk");
|
|
277
|
+
}
|
|
278
|
+
function serializePrompt(options) {
|
|
279
|
+
const images = [];
|
|
280
|
+
const sections = options.prompt.map((message) => {
|
|
281
|
+
const text =
|
|
282
|
+
message.role === "system"
|
|
283
|
+
? message.content
|
|
284
|
+
: message.content.map((part) => {
|
|
285
|
+
if (part.type === "text" || part.type === "reasoning")
|
|
286
|
+
return part.text;
|
|
287
|
+
if (part.type === "tool-call")
|
|
288
|
+
return JSON.stringify({
|
|
289
|
+
tool_call_id: part.toolCallId,
|
|
290
|
+
name: part.toolName,
|
|
291
|
+
arguments: part.input,
|
|
292
|
+
});
|
|
293
|
+
if (part.type === "tool-result")
|
|
294
|
+
return JSON.stringify({
|
|
295
|
+
tool_call_id: part.toolCallId,
|
|
296
|
+
name: part.toolName,
|
|
297
|
+
output: part.output,
|
|
298
|
+
});
|
|
299
|
+
if (part.type === "file" && part.mediaType.startsWith("image/")) {
|
|
300
|
+
if (part.data.type === "url") return part.data.url.toString();
|
|
301
|
+
if (part.data.type === "data") {
|
|
302
|
+
images.push({
|
|
303
|
+
mimeType: part.mediaType,
|
|
304
|
+
data:
|
|
305
|
+
typeof part.data.data === "string"
|
|
306
|
+
? part.data.data
|
|
307
|
+
: Buffer.from(part.data.data).toString("base64"),
|
|
308
|
+
});
|
|
309
|
+
return `[image ${images.length} attached]`;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
throw new import_provider.UnsupportedFunctionalityError({
|
|
313
|
+
functionality: `Cursor prompt part: ${part.type}`,
|
|
314
|
+
});
|
|
315
|
+
}).join(`
|
|
316
|
+
`);
|
|
317
|
+
const role = message.role === "tool" ? "tool_result" : message.role;
|
|
318
|
+
return `<${role}>
|
|
319
|
+
${text}
|
|
320
|
+
</${role}>`;
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
text: sections.join(`
|
|
324
|
+
|
|
325
|
+
`),
|
|
326
|
+
images,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function responseContract(options) {
|
|
330
|
+
if (options.responseFormat?.type === "json") {
|
|
331
|
+
return `# Structured output
|
|
332
|
+
Respond with ONLY valid JSON, with no other text.
|
|
333
|
+
${options.responseFormat.description ?? ""}
|
|
334
|
+
JSON schema: ${JSON.stringify(options.responseFormat.schema ?? {})}`;
|
|
335
|
+
}
|
|
336
|
+
const tools = activeTools(options);
|
|
337
|
+
if (!tools.length) return "";
|
|
338
|
+
return `# Tool calling
|
|
339
|
+
Decide which of these tools to call to fulfill the request. Do not execute them yourself.
|
|
340
|
+
Available tools (JSON schema per tool):
|
|
341
|
+
${JSON.stringify(tools)}
|
|
342
|
+
Respond with ONLY a JSON object of this exact shape and no other text:
|
|
343
|
+
{"tool_calls": [{"name": "<tool_name>", "arguments": {<parameters>}}]}
|
|
344
|
+
List multiple entries when several calls are needed, in execution order.
|
|
345
|
+
${options.toolChoice?.type === "required" || options.toolChoice?.type === "tool" ? "You MUST call at least one of the listed tools." : 'If no tool applies, respond with {"tool_calls": []}.'}`;
|
|
346
|
+
}
|
|
347
|
+
function activeTools(options) {
|
|
348
|
+
if (options.toolChoice?.type === "none") return [];
|
|
349
|
+
return (options.tools ?? [])
|
|
350
|
+
.map((tool) => {
|
|
351
|
+
if (tool.type !== "function")
|
|
352
|
+
throw new import_provider.UnsupportedFunctionalityError({
|
|
353
|
+
functionality: "Cursor provider-defined tools",
|
|
354
|
+
});
|
|
355
|
+
return tool;
|
|
356
|
+
})
|
|
357
|
+
.filter(
|
|
358
|
+
(tool) =>
|
|
359
|
+
options.toolChoice?.type !== "tool" ||
|
|
360
|
+
tool.name === options.toolChoice.toolName,
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
function parseResponse(text, options) {
|
|
364
|
+
if (options.responseFormat?.type === "json")
|
|
365
|
+
return [{ type: "text", text: JSON.stringify(parseJson(text)) }];
|
|
366
|
+
const tools = activeTools(options);
|
|
367
|
+
if (!tools.length) return [{ type: "text", text }];
|
|
368
|
+
const calls = ToolCallsResponse.parse(parseJson(text)).tool_calls;
|
|
369
|
+
if (
|
|
370
|
+
!calls.length &&
|
|
371
|
+
(options.toolChoice?.type === "required" ||
|
|
372
|
+
options.toolChoice?.type === "tool")
|
|
373
|
+
)
|
|
374
|
+
throw new Error("At least one tool call is required");
|
|
375
|
+
return calls.map((call) => {
|
|
376
|
+
if (!tools.some((tool) => tool.name === call.name))
|
|
377
|
+
throw new Error(`Unknown or disallowed tool: ${call.name}`);
|
|
378
|
+
return {
|
|
379
|
+
type: "tool-call",
|
|
380
|
+
toolCallId: `call_${crypto.randomUUID()}`,
|
|
381
|
+
toolName: call.name,
|
|
382
|
+
input: JSON.stringify(call.arguments ?? call.args ?? {}),
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
function parseJson(text) {
|
|
387
|
+
try {
|
|
388
|
+
return JSON.parse(text);
|
|
389
|
+
} catch {}
|
|
390
|
+
const start = text.search(/[[{]/);
|
|
391
|
+
let depth = 0;
|
|
392
|
+
let quoted = false;
|
|
393
|
+
let escaped = false;
|
|
394
|
+
for (let index = start; index >= 0 && index < text.length; index++) {
|
|
395
|
+
const char = text[index];
|
|
396
|
+
if (escaped) escaped = false;
|
|
397
|
+
else if (quoted && char === "\\") escaped = true;
|
|
398
|
+
else if (char === '"') quoted = !quoted;
|
|
399
|
+
else if (!quoted) {
|
|
400
|
+
if (char === "{" || char === "[") depth++;
|
|
401
|
+
else if ((char === "}" || char === "]") && --depth === 0)
|
|
402
|
+
return JSON.parse(text.slice(start, index + 1));
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
throw new Error("Response does not contain valid JSON");
|
|
406
|
+
}
|
|
407
|
+
async function send(agent, payload, abort) {
|
|
408
|
+
abort.signal?.throwIfAborted();
|
|
409
|
+
const run = await abort.run(agent.send(payload), (lateRun) => {
|
|
410
|
+
lateRun.cancel().catch(() => {});
|
|
411
|
+
});
|
|
412
|
+
let result;
|
|
413
|
+
try {
|
|
414
|
+
result = await abort.run(run.wait());
|
|
415
|
+
} catch (error) {
|
|
416
|
+
run.cancel().catch(() => {});
|
|
417
|
+
throw error;
|
|
418
|
+
}
|
|
419
|
+
if (result.status !== "finished")
|
|
420
|
+
throw new Error(
|
|
421
|
+
`Cursor agent run ${result.status}: ${result.error?.message ?? "no error details"}`,
|
|
422
|
+
);
|
|
423
|
+
return result;
|
|
424
|
+
}
|
|
425
|
+
function createAbortScope(signal) {
|
|
426
|
+
signal?.throwIfAborted();
|
|
427
|
+
let onAbort = () => {};
|
|
428
|
+
const aborted = new Promise((_, reject) => {
|
|
429
|
+
onAbort = () => reject(signal?.reason);
|
|
430
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
431
|
+
});
|
|
432
|
+
return {
|
|
433
|
+
signal,
|
|
434
|
+
async run(promise, onLateResult) {
|
|
435
|
+
if (!signal) return promise;
|
|
436
|
+
return Promise.race([
|
|
437
|
+
promise.then(async (value) => {
|
|
438
|
+
if (signal.aborted) {
|
|
439
|
+
await onLateResult?.(value);
|
|
440
|
+
signal.throwIfAborted();
|
|
441
|
+
}
|
|
442
|
+
return value;
|
|
443
|
+
}),
|
|
444
|
+
aborted,
|
|
445
|
+
]);
|
|
446
|
+
},
|
|
447
|
+
dispose() {
|
|
448
|
+
signal?.removeEventListener("abort", onAbort);
|
|
449
|
+
},
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
function toUsage(usages) {
|
|
453
|
+
const reported = usages.filter((usage) => usage !== undefined);
|
|
454
|
+
function sum(key) {
|
|
455
|
+
return reported.some((usage) => usage[key] !== undefined)
|
|
456
|
+
? reported.reduce((total, usage) => total + (usage[key] ?? 0), 0)
|
|
457
|
+
: undefined;
|
|
458
|
+
}
|
|
459
|
+
const noCache = sum("inputTokens");
|
|
460
|
+
const cacheRead = sum("cacheReadTokens");
|
|
461
|
+
const cacheWrite = sum("cacheWriteTokens");
|
|
462
|
+
return {
|
|
463
|
+
inputTokens: {
|
|
464
|
+
total:
|
|
465
|
+
noCache === undefined
|
|
466
|
+
? undefined
|
|
467
|
+
: noCache + (cacheRead ?? 0) + (cacheWrite ?? 0),
|
|
468
|
+
noCache,
|
|
469
|
+
cacheRead,
|
|
470
|
+
cacheWrite,
|
|
471
|
+
},
|
|
472
|
+
outputTokens: {
|
|
473
|
+
total: sum("outputTokens"),
|
|
474
|
+
text: undefined,
|
|
475
|
+
reasoning: sum("reasoningTokens"),
|
|
476
|
+
},
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
// cursor/src/llm/cursorProviders.ts
|
|
480
|
+
var import_internal3 = require("@alumnium/core/internal");
|
|
481
|
+
|
|
482
|
+
// cursor/src/standalone/installCursorSdk.ts
|
|
483
|
+
var import_node_crypto = require("node:crypto");
|
|
484
|
+
var import_promises3 = __toESM(require("node:fs/promises"), 1);
|
|
485
|
+
var import_node_module2 = require("node:module");
|
|
486
|
+
var import_node_os2 = __toESM(require("node:os"), 1);
|
|
487
|
+
var import_node_path4 = __toESM(require("node:path"), 1);
|
|
488
|
+
var import_node_zlib = require("node:zlib");
|
|
489
|
+
var import_internal2 = require("@alumnium/core/internal");
|
|
490
|
+
|
|
491
|
+
// cursor/src/standalone/cursorSdkManifest.ts
|
|
492
|
+
var CURSOR_SDK_PACKAGE_NAME = "@cursor/sdk";
|
|
493
|
+
|
|
494
|
+
// cursor/src/standalone/cursorSdkResolver.ts
|
|
495
|
+
var import_node_fs = __toESM(require("node:fs"), 1);
|
|
496
|
+
var import_node_module = __toESM(require("node:module"), 1);
|
|
497
|
+
var import_node_path2 = __toESM(require("node:path"), 1);
|
|
498
|
+
var installedVendorRoots = new Map();
|
|
499
|
+
function installVendorResolveHook(vendorRoot, packageNames) {
|
|
500
|
+
const existing = installedVendorRoots.get(vendorRoot);
|
|
501
|
+
if (existing) return existing;
|
|
502
|
+
const vendorNodeModules = import_node_path2.default.join(
|
|
503
|
+
vendorRoot,
|
|
504
|
+
"node_modules",
|
|
505
|
+
);
|
|
506
|
+
const vendorPrefix = vendorRoot + import_node_path2.default.sep;
|
|
507
|
+
const resolutionCache = new Map();
|
|
508
|
+
const moduleWithResolveFilename = import_node_module.default;
|
|
509
|
+
const resolveFilename = moduleWithResolveFilename._resolveFilename;
|
|
510
|
+
moduleWithResolveFilename._resolveFilename = function (...args) {
|
|
511
|
+
const [request, parent] = args;
|
|
512
|
+
if (
|
|
513
|
+
typeof request === "string" &&
|
|
514
|
+
isBareSpecifier(request) &&
|
|
515
|
+
parent?.filename?.startsWith(vendorPrefix)
|
|
516
|
+
) {
|
|
517
|
+
let resolved = resolutionCache.get(request);
|
|
518
|
+
if (!resolutionCache.has(request)) {
|
|
519
|
+
const { packageName, subpath } = splitBareSpecifier(request);
|
|
520
|
+
resolved = packageNames.has(packageName)
|
|
521
|
+
? resolvePackageEntry(vendorNodeModules, packageName, subpath)
|
|
522
|
+
: undefined;
|
|
523
|
+
resolutionCache.set(request, resolved);
|
|
524
|
+
}
|
|
525
|
+
if (resolved) return resolved;
|
|
526
|
+
}
|
|
527
|
+
return resolveFilename.call(this, ...args);
|
|
528
|
+
};
|
|
529
|
+
const handle = {
|
|
530
|
+
uninstall() {
|
|
531
|
+
moduleWithResolveFilename._resolveFilename = resolveFilename;
|
|
532
|
+
installedVendorRoots.delete(vendorRoot);
|
|
533
|
+
},
|
|
534
|
+
};
|
|
535
|
+
installedVendorRoots.set(vendorRoot, handle);
|
|
536
|
+
return handle;
|
|
537
|
+
}
|
|
538
|
+
function isBareSpecifier(request) {
|
|
539
|
+
return (
|
|
540
|
+
!request.startsWith(".") &&
|
|
541
|
+
!import_node_path2.default.isAbsolute(request) &&
|
|
542
|
+
!request.startsWith("node:") &&
|
|
543
|
+
!request.startsWith("bun:")
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
function splitBareSpecifier(request) {
|
|
547
|
+
const segments = request.split("/");
|
|
548
|
+
const nameLength = request.startsWith("@") ? 2 : 1;
|
|
549
|
+
return {
|
|
550
|
+
packageName: segments.slice(0, nameLength).join("/"),
|
|
551
|
+
subpath:
|
|
552
|
+
segments.length > nameLength
|
|
553
|
+
? `./${segments.slice(nameLength).join("/")}`
|
|
554
|
+
: ".",
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
function resolvePackageEntry(vendorNodeModules, packageName, subpath) {
|
|
558
|
+
const packageDir = import_node_path2.default.join(
|
|
559
|
+
vendorNodeModules,
|
|
560
|
+
packageName,
|
|
561
|
+
);
|
|
562
|
+
const manifest = readPackageManifest(packageDir);
|
|
563
|
+
if (!manifest) return;
|
|
564
|
+
if (manifest.exports != null) {
|
|
565
|
+
const target = lookupExports(manifest.exports, subpath);
|
|
566
|
+
return target === undefined
|
|
567
|
+
? undefined
|
|
568
|
+
: resolveExportTarget(packageDir, target);
|
|
569
|
+
}
|
|
570
|
+
const candidate =
|
|
571
|
+
subpath === "."
|
|
572
|
+
? typeof manifest.main === "string"
|
|
573
|
+
? manifest.main
|
|
574
|
+
: "index.js"
|
|
575
|
+
: subpath;
|
|
576
|
+
return probeFile(import_node_path2.default.join(packageDir, candidate));
|
|
577
|
+
}
|
|
578
|
+
var manifestCache = new Map();
|
|
579
|
+
function readPackageManifest(packageDir) {
|
|
580
|
+
if (!manifestCache.has(packageDir)) {
|
|
581
|
+
let manifest;
|
|
582
|
+
try {
|
|
583
|
+
manifest = JSON.parse(
|
|
584
|
+
import_node_fs.default.readFileSync(
|
|
585
|
+
import_node_path2.default.join(packageDir, "package.json"),
|
|
586
|
+
"utf-8",
|
|
587
|
+
),
|
|
588
|
+
);
|
|
589
|
+
} catch {
|
|
590
|
+
manifest = undefined;
|
|
591
|
+
}
|
|
592
|
+
manifestCache.set(packageDir, manifest);
|
|
593
|
+
}
|
|
594
|
+
return manifestCache.get(packageDir);
|
|
595
|
+
}
|
|
596
|
+
function lookupExports(exports2, subpath) {
|
|
597
|
+
const isSubpathMap =
|
|
598
|
+
typeof exports2 === "object" &&
|
|
599
|
+
exports2 !== null &&
|
|
600
|
+
!Array.isArray(exports2) &&
|
|
601
|
+
Object.keys(exports2).every((key) => key === "." || key.startsWith("./"));
|
|
602
|
+
if (!isSubpathMap) return subpath === "." ? exports2 : undefined;
|
|
603
|
+
const map = exports2;
|
|
604
|
+
if (subpath in map) return map[subpath];
|
|
605
|
+
for (const [key, value] of Object.entries(map)) {
|
|
606
|
+
const asterisk = key.indexOf("*");
|
|
607
|
+
if (asterisk < 0 || key.indexOf("*", asterisk + 1) >= 0) continue;
|
|
608
|
+
const prefix = key.slice(0, asterisk);
|
|
609
|
+
const suffix = key.slice(asterisk + 1);
|
|
610
|
+
if (
|
|
611
|
+
subpath.length > prefix.length + suffix.length &&
|
|
612
|
+
subpath.startsWith(prefix) &&
|
|
613
|
+
subpath.endsWith(suffix)
|
|
614
|
+
) {
|
|
615
|
+
const wildcard = subpath.slice(
|
|
616
|
+
prefix.length,
|
|
617
|
+
subpath.length - suffix.length,
|
|
618
|
+
);
|
|
619
|
+
return typeof value === "string"
|
|
620
|
+
? value.replaceAll("*", wildcard)
|
|
621
|
+
: value;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
var ACCEPTED_CONDITIONS = new Set(["require", "node", "default"]);
|
|
627
|
+
function resolveExportTarget(packageDir, target) {
|
|
628
|
+
if (typeof target === "string") {
|
|
629
|
+
if (!target.startsWith("./")) return;
|
|
630
|
+
const resolved = import_node_path2.default.join(packageDir, target);
|
|
631
|
+
return isFile(resolved) ? resolved : undefined;
|
|
632
|
+
}
|
|
633
|
+
if (Array.isArray(target)) {
|
|
634
|
+
for (const entry of target) {
|
|
635
|
+
const resolved = resolveExportTarget(packageDir, entry);
|
|
636
|
+
if (resolved) return resolved;
|
|
637
|
+
}
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
if (typeof target === "object" && target !== null) {
|
|
641
|
+
for (const [condition, value] of Object.entries(target)) {
|
|
642
|
+
if (!ACCEPTED_CONDITIONS.has(condition)) continue;
|
|
643
|
+
const resolved = resolveExportTarget(packageDir, value);
|
|
644
|
+
if (resolved) return resolved;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
return;
|
|
648
|
+
}
|
|
649
|
+
function probeFile(candidate) {
|
|
650
|
+
for (const probe of [
|
|
651
|
+
candidate,
|
|
652
|
+
`${candidate}.js`,
|
|
653
|
+
`${candidate}.json`,
|
|
654
|
+
import_node_path2.default.join(candidate, "index.js"),
|
|
655
|
+
import_node_path2.default.join(candidate, "index.json"),
|
|
656
|
+
]) {
|
|
657
|
+
if (isFile(probe)) return probe;
|
|
658
|
+
}
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
function isFile(filePath) {
|
|
662
|
+
try {
|
|
663
|
+
return import_node_fs.default.statSync(filePath).isFile();
|
|
664
|
+
} catch {
|
|
665
|
+
return false;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// cursor/src/standalone/cursorSdkVendorManifest.ts
|
|
670
|
+
var cursorSdkVendorManifest = {
|
|
671
|
+
sdkVersion: "1.0.30",
|
|
672
|
+
packages: [
|
|
673
|
+
{
|
|
674
|
+
name: "@bufbuild/protobuf",
|
|
675
|
+
version: "1.10.0",
|
|
676
|
+
integrity:
|
|
677
|
+
"sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag==",
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: "@connectrpc/connect",
|
|
681
|
+
version: "1.7.0",
|
|
682
|
+
integrity:
|
|
683
|
+
"sha512-iNKdJRi69YP3mq6AePRT8F/HrxWCewrhxnLMNm0vpqXAR8biwzRtO6Hjx80C6UvtKJ5sFmffQT7I4Baecz389w==",
|
|
684
|
+
},
|
|
685
|
+
{
|
|
686
|
+
name: "@connectrpc/connect-node",
|
|
687
|
+
version: "1.7.0",
|
|
688
|
+
integrity:
|
|
689
|
+
"sha512-6vaPIkG/NyhxlYgytLoR9KYbPhczEboFB2OYWkA9qvUz1K7efXfeGrlRxoLtpa+r8VxyIOw73w5ktNe743nD+A==",
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "@connectrpc/connect-web",
|
|
693
|
+
version: "1.7.0",
|
|
694
|
+
integrity:
|
|
695
|
+
"sha512-qyP0YOnUPRWwCc/VfsoydMJvkb7EyUPr2q9sHgBuJzbADjiqck1gKH5V5ZPzPhTLBvmz5UvG+wiZ5sMRQHU1MQ==",
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
name: "@cursor/sdk",
|
|
699
|
+
version: "1.0.30",
|
|
700
|
+
integrity:
|
|
701
|
+
"sha512-s3gIXfTD3w8ys+KFE81JjjoiJcynkHsf/JCDyXrnbliIac3dkT59hwYZII3XhsT1DlXIfqg+YzSMru6w1CkZow==",
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
name: "@cursor/sdk-darwin-arm64",
|
|
705
|
+
version: "1.0.30",
|
|
706
|
+
integrity:
|
|
707
|
+
"sha512-O0w2fLd6jxrvAUOJGsKBs8VSi5OojqqEOMFBzHTHS82wU/DX3ZlizK3czzCXxDKs3l8j/BVQwVCxP9jMFcf41Q==",
|
|
708
|
+
os: "darwin",
|
|
709
|
+
cpu: "arm64",
|
|
710
|
+
bin: {
|
|
711
|
+
rg: "bin/rg",
|
|
712
|
+
},
|
|
713
|
+
},
|
|
714
|
+
{
|
|
715
|
+
name: "@cursor/sdk-darwin-x64",
|
|
716
|
+
version: "1.0.30",
|
|
717
|
+
integrity:
|
|
718
|
+
"sha512-TdjreV7V6gtSKbUaXDarfE1735PES6uzLgLxp42E5kT6EXpjQhKsifdsYOMdsO/RBw166kya/XxG24L/FUfEHA==",
|
|
719
|
+
os: "darwin",
|
|
720
|
+
cpu: "x64",
|
|
721
|
+
bin: {
|
|
722
|
+
rg: "bin/rg",
|
|
723
|
+
},
|
|
724
|
+
},
|
|
725
|
+
{
|
|
726
|
+
name: "@cursor/sdk-linux-arm64",
|
|
727
|
+
version: "1.0.30",
|
|
728
|
+
integrity:
|
|
729
|
+
"sha512-1+bsmri6vJ2YuqL/SQ6QSx/ymu2eBzjGgT1bTgN47tCzxDgNOKacXtghpx4zdHM5AmOtT+aLXVVxXjStXmNtcA==",
|
|
730
|
+
os: "linux",
|
|
731
|
+
cpu: "arm64",
|
|
732
|
+
bin: {
|
|
733
|
+
rg: "bin/rg",
|
|
734
|
+
},
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
name: "@cursor/sdk-linux-x64",
|
|
738
|
+
version: "1.0.30",
|
|
739
|
+
integrity:
|
|
740
|
+
"sha512-5TRAM1xNwVr0Lox2ay5U5h+VY1OeqJLgnS28da7mx+ZkmeAU+hzuUFq2/lcIqoJrp2qBRdUH5WzI44JNtjBKmg==",
|
|
741
|
+
os: "linux",
|
|
742
|
+
cpu: "x64",
|
|
743
|
+
bin: {
|
|
744
|
+
rg: "bin/rg",
|
|
745
|
+
},
|
|
746
|
+
},
|
|
747
|
+
{
|
|
748
|
+
name: "@cursor/sdk-win32-x64",
|
|
749
|
+
version: "1.0.30",
|
|
750
|
+
integrity:
|
|
751
|
+
"sha512-kVjpWmLTFLL131TQm3ytz1HbAeyjBRAHMtr6vyLtbBMuLBb0la5igvt58Xi8mXwekymWXim1+rZj7ZYUO3K1rw==",
|
|
752
|
+
os: "win32",
|
|
753
|
+
cpu: "x64",
|
|
754
|
+
bin: {
|
|
755
|
+
rg: "bin/rg.exe",
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
name: "@fastify/busboy",
|
|
760
|
+
version: "2.1.1",
|
|
761
|
+
integrity:
|
|
762
|
+
"sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==",
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
name: "@statsig/client-core",
|
|
766
|
+
version: "3.31.0",
|
|
767
|
+
integrity:
|
|
768
|
+
"sha512-SuxQD6TmVszPG7FoMKwTk/uyBuVFk7XnxI3T/E0uyb7PL7GNjONtfsoh+NqBBVUJVse0CUeSFfgJPoZy1ZOslQ==",
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
name: "@statsig/js-client",
|
|
772
|
+
version: "3.31.0",
|
|
773
|
+
integrity:
|
|
774
|
+
"sha512-LFa5E0LjT6sTfZv3sNGoyRLSZ1078+agdgOA+Vm1ecjG+KbSOfBLTW7hMwimrJ29slRwbYDzbtKaPJo/R37N2g==",
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
name: "undici",
|
|
778
|
+
version: "5.29.0",
|
|
779
|
+
integrity:
|
|
780
|
+
"sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==",
|
|
781
|
+
},
|
|
782
|
+
{
|
|
783
|
+
name: "zod",
|
|
784
|
+
version: "3.25.76",
|
|
785
|
+
integrity:
|
|
786
|
+
"sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
|
|
787
|
+
},
|
|
788
|
+
],
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
// cursor/src/standalone/untar.ts
|
|
792
|
+
var import_promises2 = __toESM(require("node:fs/promises"), 1);
|
|
793
|
+
var import_node_path3 = __toESM(require("node:path"), 1);
|
|
794
|
+
var BLOCK_SIZE = 512;
|
|
795
|
+
var OFFSETS = {
|
|
796
|
+
name: [0, 100],
|
|
797
|
+
mode: [100, 8],
|
|
798
|
+
size: [124, 12],
|
|
799
|
+
checksum: [148, 8],
|
|
800
|
+
typeflag: 156,
|
|
801
|
+
prefix: [345, 155],
|
|
802
|
+
};
|
|
803
|
+
async function untarInto(tarBytes, destDir) {
|
|
804
|
+
let offset = 0;
|
|
805
|
+
let pendingPath;
|
|
806
|
+
while (offset + BLOCK_SIZE <= tarBytes.length) {
|
|
807
|
+
const header = tarBytes.subarray(offset, offset + BLOCK_SIZE);
|
|
808
|
+
if (isZeroBlock(header)) break;
|
|
809
|
+
verifyChecksum(header);
|
|
810
|
+
const size = readNumeric(header, ...OFFSETS.size);
|
|
811
|
+
const dataStart = offset + BLOCK_SIZE;
|
|
812
|
+
if (dataStart + size > tarBytes.length) {
|
|
813
|
+
throw new Error("Truncated tar archive");
|
|
814
|
+
}
|
|
815
|
+
const data = tarBytes.subarray(dataStart, dataStart + size);
|
|
816
|
+
offset = dataStart + Math.ceil(size / BLOCK_SIZE) * BLOCK_SIZE;
|
|
817
|
+
const typeflag = String.fromCharCode(header[OFFSETS.typeflag] ?? 0);
|
|
818
|
+
if (typeflag === "x") {
|
|
819
|
+
pendingPath = parsePaxPath(data) ?? pendingPath;
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
if (typeflag === "L") {
|
|
823
|
+
pendingPath = decodeToNul(data);
|
|
824
|
+
continue;
|
|
825
|
+
}
|
|
826
|
+
if (typeflag === "1" || typeflag === "2") {
|
|
827
|
+
throw new Error(
|
|
828
|
+
`Tar entry "${decodeToNul(header.subarray(...spanOf(OFFSETS.name)))}" is a link; links are not allowed in npm tarballs`,
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
if (typeflag !== "0" && typeflag !== "\x00" && typeflag !== "5") {
|
|
832
|
+
pendingPath = undefined;
|
|
833
|
+
continue;
|
|
834
|
+
}
|
|
835
|
+
const entryPath = pendingPath ?? ustarPath(header);
|
|
836
|
+
pendingPath = undefined;
|
|
837
|
+
const segments = sanitizedSegments(entryPath).slice(1);
|
|
838
|
+
if (!segments.length) continue;
|
|
839
|
+
const target = import_node_path3.default.join(destDir, ...segments);
|
|
840
|
+
if (typeflag === "5") {
|
|
841
|
+
await import_promises2.default.mkdir(target, { recursive: true });
|
|
842
|
+
continue;
|
|
843
|
+
}
|
|
844
|
+
await import_promises2.default.mkdir(
|
|
845
|
+
import_node_path3.default.dirname(target),
|
|
846
|
+
{ recursive: true },
|
|
847
|
+
);
|
|
848
|
+
const mode = readNumeric(header, ...OFFSETS.mode);
|
|
849
|
+
await import_promises2.default.writeFile(target, data, {
|
|
850
|
+
mode: mode & 73 ? 493 : 420,
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
function spanOf(field) {
|
|
855
|
+
return [field[0], field[0] + field[1]];
|
|
856
|
+
}
|
|
857
|
+
function isZeroBlock(block) {
|
|
858
|
+
return block.every((byte) => byte === 0);
|
|
859
|
+
}
|
|
860
|
+
function verifyChecksum(header) {
|
|
861
|
+
const stored = readNumeric(header, ...OFFSETS.checksum);
|
|
862
|
+
const [checksumStart, checksumEnd] = spanOf(OFFSETS.checksum);
|
|
863
|
+
let computed = 0;
|
|
864
|
+
for (let index = 0; index < BLOCK_SIZE; index++) {
|
|
865
|
+
computed +=
|
|
866
|
+
index >= checksumStart && index < checksumEnd ? 32 : header[index];
|
|
867
|
+
}
|
|
868
|
+
if (computed !== stored) {
|
|
869
|
+
throw new Error("Tar header checksum mismatch — the archive is corrupted");
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
function readNumeric(header, start, length) {
|
|
873
|
+
const first = header[start];
|
|
874
|
+
if (first & 128) {
|
|
875
|
+
let value = first & 127;
|
|
876
|
+
for (let index = start + 1; index < start + length; index++) {
|
|
877
|
+
value = value * 256 + header[index];
|
|
878
|
+
}
|
|
879
|
+
return value;
|
|
880
|
+
}
|
|
881
|
+
const text = decodeToNul(header.subarray(start, start + length)).trim();
|
|
882
|
+
return text ? Number.parseInt(text, 8) : 0;
|
|
883
|
+
}
|
|
884
|
+
function decodeToNul(bytes) {
|
|
885
|
+
const nul = bytes.indexOf(0);
|
|
886
|
+
return new TextDecoder().decode(nul < 0 ? bytes : bytes.subarray(0, nul));
|
|
887
|
+
}
|
|
888
|
+
function ustarPath(header) {
|
|
889
|
+
const name = decodeToNul(header.subarray(...spanOf(OFFSETS.name)));
|
|
890
|
+
const prefix = decodeToNul(header.subarray(...spanOf(OFFSETS.prefix)));
|
|
891
|
+
return prefix ? `${prefix}/${name}` : name;
|
|
892
|
+
}
|
|
893
|
+
function parsePaxPath(data) {
|
|
894
|
+
const text = Buffer.from(data).toString("latin1");
|
|
895
|
+
let cursor = 0;
|
|
896
|
+
let result;
|
|
897
|
+
while (cursor < text.length) {
|
|
898
|
+
const lengthEnd = text.indexOf(" ", cursor);
|
|
899
|
+
if (lengthEnd < 0) break;
|
|
900
|
+
const recordLength = Number(text.slice(cursor, lengthEnd));
|
|
901
|
+
if (!Number.isInteger(recordLength) || recordLength <= 0) break;
|
|
902
|
+
const recordEnd = cursor + recordLength;
|
|
903
|
+
const equals = text.indexOf("=", lengthEnd + 1);
|
|
904
|
+
if (equals > 0 && equals < recordEnd) {
|
|
905
|
+
const key = text.slice(lengthEnd + 1, equals);
|
|
906
|
+
if (key === "path") {
|
|
907
|
+
const value = text.slice(equals + 1, recordEnd - 1);
|
|
908
|
+
result = Buffer.from(value, "latin1").toString("utf8");
|
|
909
|
+
}
|
|
910
|
+
}
|
|
911
|
+
cursor = recordEnd;
|
|
912
|
+
}
|
|
913
|
+
return result;
|
|
914
|
+
}
|
|
915
|
+
function sanitizedSegments(entryPath) {
|
|
916
|
+
if (entryPath.startsWith("/") || /^[A-Za-z]:/.test(entryPath)) {
|
|
917
|
+
throw new Error(`Tar entry "${entryPath}" has an absolute path`);
|
|
918
|
+
}
|
|
919
|
+
const segments = entryPath
|
|
920
|
+
.split("/")
|
|
921
|
+
.filter((segment) => segment !== "" && segment !== ".");
|
|
922
|
+
for (const segment of segments) {
|
|
923
|
+
if (segment === ".." || segment.includes("\\") || segment.includes(":")) {
|
|
924
|
+
throw new Error(`Tar entry "${entryPath}" has an unsafe path`);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return segments;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// cursor/src/standalone/installCursorSdk.ts
|
|
931
|
+
var logger2 = import_internal2.Logger.get(
|
|
932
|
+
"packages/typescript/cursor/src/standalone/installCursorSdk.ts",
|
|
933
|
+
);
|
|
934
|
+
var MARKER_FILENAME = ".alumnium-complete";
|
|
935
|
+
var STALE_PARTIAL_AGE_MS = 24 * 60 * 60 * 1000;
|
|
936
|
+
var loadPromise;
|
|
937
|
+
function loadVendoredCursorSdk() {
|
|
938
|
+
loadPromise ??= loadVendoredCursorSdkInternal().catch((error) => {
|
|
939
|
+
loadPromise = undefined;
|
|
940
|
+
throw error;
|
|
941
|
+
});
|
|
942
|
+
return loadPromise;
|
|
943
|
+
}
|
|
944
|
+
async function loadVendoredCursorSdkInternal() {
|
|
945
|
+
const manifest = cursorSdkVendorManifest;
|
|
946
|
+
const explicitDir = import_internal2.Env.ALUMNIUM_CURSOR_SDK_DIR;
|
|
947
|
+
let vendorRoot;
|
|
948
|
+
if (explicitDir) {
|
|
949
|
+
vendorRoot = import_node_path4.default.resolve(explicitDir);
|
|
950
|
+
await assertExplicitVendorDir(vendorRoot, manifest);
|
|
951
|
+
} else {
|
|
952
|
+
vendorRoot = import_node_path4.default.join(
|
|
953
|
+
import_node_os2.default.homedir(),
|
|
954
|
+
".alumnium",
|
|
955
|
+
"vendor",
|
|
956
|
+
"cursor-sdk",
|
|
957
|
+
manifest.sdkVersion,
|
|
958
|
+
);
|
|
959
|
+
await ensureVendorTree(manifest, vendorRoot);
|
|
960
|
+
}
|
|
961
|
+
return loadSdkFromVendorRoot(manifest, vendorRoot);
|
|
962
|
+
}
|
|
963
|
+
async function ensureVendorTree(manifest, vendorRoot) {
|
|
964
|
+
const markerPath = import_node_path4.default.join(
|
|
965
|
+
vendorRoot,
|
|
966
|
+
MARKER_FILENAME,
|
|
967
|
+
);
|
|
968
|
+
if (await pathExists(markerPath)) return;
|
|
969
|
+
await import_promises3.default.rm(vendorRoot, {
|
|
970
|
+
recursive: true,
|
|
971
|
+
force: true,
|
|
972
|
+
});
|
|
973
|
+
const packages = packagesForPlatform(manifest);
|
|
974
|
+
logger2.info(
|
|
975
|
+
`Downloading the Cursor SDK (~24 MB, one time) from registry.npmjs.org into ${vendorRoot}`,
|
|
976
|
+
);
|
|
977
|
+
const partialDir = `${vendorRoot}.partial-${process.pid}-${crypto.randomUUID().slice(0, 8)}`;
|
|
978
|
+
try {
|
|
979
|
+
for (const pkg of packages) {
|
|
980
|
+
try {
|
|
981
|
+
await import_internal2.retry({ maxAttempts: 3, backOff: 500 }, () =>
|
|
982
|
+
downloadAndExtract(pkg, partialDir),
|
|
983
|
+
);
|
|
984
|
+
} catch (error) {
|
|
985
|
+
throw new Error(
|
|
986
|
+
`Failed to download Cursor SDK package ${pkg.name}@${pkg.version} from registry.npmjs.org: ` +
|
|
987
|
+
`${error instanceof Error ? error.message : String(error)}. ` +
|
|
988
|
+
"The Cursor provider performs a one-time ~24 MB download on first use. " +
|
|
989
|
+
"Check network/proxy settings (HTTPS_PROXY is honored), or point " +
|
|
990
|
+
"ALUMNIUM_CURSOR_SDK_DIR at a pre-installed node_modules tree.",
|
|
991
|
+
{ cause: error },
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
await import_promises3.default.writeFile(
|
|
996
|
+
import_node_path4.default.join(partialDir, MARKER_FILENAME),
|
|
997
|
+
JSON.stringify(
|
|
998
|
+
{
|
|
999
|
+
sdkVersion: manifest.sdkVersion,
|
|
1000
|
+
installedAt: new Date().toISOString(),
|
|
1001
|
+
platform: `${process.platform}-${process.arch}`,
|
|
1002
|
+
},
|
|
1003
|
+
null,
|
|
1004
|
+
2,
|
|
1005
|
+
),
|
|
1006
|
+
);
|
|
1007
|
+
await promoteToVendorRoot(partialDir, markerPath, vendorRoot);
|
|
1008
|
+
} finally {
|
|
1009
|
+
await import_promises3.default
|
|
1010
|
+
.rm(partialDir, { recursive: true, force: true })
|
|
1011
|
+
.catch(() => {});
|
|
1012
|
+
await sweepStalePartials(vendorRoot);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function packagesForPlatform(
|
|
1016
|
+
manifest,
|
|
1017
|
+
platform = process.platform,
|
|
1018
|
+
arch = process.arch,
|
|
1019
|
+
) {
|
|
1020
|
+
const [universal, platformSpecific] = manifest.packages.reduce(
|
|
1021
|
+
([plain, restricted], pkg) => {
|
|
1022
|
+
(pkg.os || pkg.cpu ? restricted : plain).push(pkg);
|
|
1023
|
+
return [plain, restricted];
|
|
1024
|
+
},
|
|
1025
|
+
[[], []],
|
|
1026
|
+
);
|
|
1027
|
+
const ripgrep =
|
|
1028
|
+
platformSpecific.find((pkg) => pkg.os === platform && pkg.cpu === arch) ??
|
|
1029
|
+
(platform === "win32"
|
|
1030
|
+
? platformSpecific.find((pkg) => pkg.os === "win32" && pkg.cpu === "x64")
|
|
1031
|
+
: undefined);
|
|
1032
|
+
if (!ripgrep) {
|
|
1033
|
+
logger2.warn(
|
|
1034
|
+
`No Cursor ripgrep package for ${platform}-${arch}; Cursor agent file-search tools may be unavailable.`,
|
|
1035
|
+
);
|
|
1036
|
+
return universal;
|
|
1037
|
+
}
|
|
1038
|
+
return [...universal, ripgrep];
|
|
1039
|
+
}
|
|
1040
|
+
async function downloadAndExtract(pkg, partialDir) {
|
|
1041
|
+
const basename = pkg.name.split("/").pop();
|
|
1042
|
+
const url = `https://registry.npmjs.org/${pkg.name}/-/${basename}-${pkg.version}.tgz`;
|
|
1043
|
+
const response = await fetch(url);
|
|
1044
|
+
if (!response.ok) {
|
|
1045
|
+
throw new Error(`HTTP ${response.status} fetching ${url}`);
|
|
1046
|
+
}
|
|
1047
|
+
const tgzBytes = new Uint8Array(await response.arrayBuffer());
|
|
1048
|
+
const digest = import_node_crypto
|
|
1049
|
+
.createHash("sha512")
|
|
1050
|
+
.update(tgzBytes)
|
|
1051
|
+
.digest("base64");
|
|
1052
|
+
const expected = pkg.integrity.slice("sha512-".length);
|
|
1053
|
+
if (digest !== expected) {
|
|
1054
|
+
throw new Error(
|
|
1055
|
+
`Integrity check failed for ${pkg.name}@${pkg.version} (expected sha512-${expected}, got sha512-${digest}) — ` +
|
|
1056
|
+
"the download may be corrupted or tampered with; report at " +
|
|
1057
|
+
"https://github.com/alumnium-hq/alumnium/issues if it persists",
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
1060
|
+
await untarInto(
|
|
1061
|
+
import_node_zlib.gunzipSync(tgzBytes),
|
|
1062
|
+
import_node_path4.default.join(partialDir, "node_modules", pkg.name),
|
|
1063
|
+
);
|
|
1064
|
+
}
|
|
1065
|
+
async function promoteToVendorRoot(partialDir, markerPath, vendorRoot) {
|
|
1066
|
+
for (let attempt = 1; ; attempt++) {
|
|
1067
|
+
try {
|
|
1068
|
+
await import_promises3.default.rename(partialDir, vendorRoot);
|
|
1069
|
+
return;
|
|
1070
|
+
} catch (error) {
|
|
1071
|
+
if (await pathExists(markerPath)) return;
|
|
1072
|
+
if (attempt >= 3) throw error;
|
|
1073
|
+
await new Promise((resolve) => setTimeout(resolve, 200 * attempt));
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
async function sweepStalePartials(vendorRoot) {
|
|
1078
|
+
try {
|
|
1079
|
+
const parentDir = import_node_path4.default.dirname(vendorRoot);
|
|
1080
|
+
const prefix = `${import_node_path4.default.basename(vendorRoot)}.partial-`;
|
|
1081
|
+
for (const entry of await import_promises3.default.readdir(parentDir)) {
|
|
1082
|
+
if (!entry.startsWith(prefix)) continue;
|
|
1083
|
+
const entryPath = import_node_path4.default.join(parentDir, entry);
|
|
1084
|
+
const { mtimeMs } = await import_promises3.default.stat(entryPath);
|
|
1085
|
+
if (Date.now() - mtimeMs > STALE_PARTIAL_AGE_MS) {
|
|
1086
|
+
await import_promises3.default.rm(entryPath, {
|
|
1087
|
+
recursive: true,
|
|
1088
|
+
force: true,
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
} catch {}
|
|
1093
|
+
}
|
|
1094
|
+
async function assertExplicitVendorDir(vendorRoot, manifest) {
|
|
1095
|
+
const manifestPath = import_node_path4.default.join(
|
|
1096
|
+
vendorRoot,
|
|
1097
|
+
"node_modules",
|
|
1098
|
+
CURSOR_SDK_PACKAGE_NAME,
|
|
1099
|
+
"package.json",
|
|
1100
|
+
);
|
|
1101
|
+
let installedVersion;
|
|
1102
|
+
try {
|
|
1103
|
+
installedVersion = JSON.parse(
|
|
1104
|
+
await import_promises3.default.readFile(manifestPath, "utf-8"),
|
|
1105
|
+
).version;
|
|
1106
|
+
} catch (error) {
|
|
1107
|
+
throw new Error(
|
|
1108
|
+
`ALUMNIUM_CURSOR_SDK_DIR is set to ${vendorRoot} but ${manifestPath} cannot be read`,
|
|
1109
|
+
{ cause: error },
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
if (installedVersion !== manifest.sdkVersion) {
|
|
1113
|
+
logger2.warn(
|
|
1114
|
+
`ALUMNIUM_CURSOR_SDK_DIR holds @cursor/sdk@${installedVersion}, but this Alumnium build expects ${manifest.sdkVersion}`,
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
async function loadSdkFromVendorRoot(manifest, vendorRoot) {
|
|
1119
|
+
const vendorNodeModules = import_node_path4.default.join(
|
|
1120
|
+
vendorRoot,
|
|
1121
|
+
"node_modules",
|
|
1122
|
+
);
|
|
1123
|
+
installVendorResolveHook(
|
|
1124
|
+
vendorRoot,
|
|
1125
|
+
new Set(manifest.packages.map((pkg) => pkg.name)),
|
|
1126
|
+
);
|
|
1127
|
+
const ripgrep = packagesForPlatform(manifest).find((pkg) => pkg.bin);
|
|
1128
|
+
const ripgrepRelPath =
|
|
1129
|
+
ripgrep?.bin?.rg ?? Object.values(ripgrep?.bin ?? {})[0];
|
|
1130
|
+
if (ripgrep && ripgrepRelPath) {
|
|
1131
|
+
const ripgrepPath = import_node_path4.default.join(
|
|
1132
|
+
vendorNodeModules,
|
|
1133
|
+
ripgrep.name,
|
|
1134
|
+
ripgrepRelPath,
|
|
1135
|
+
);
|
|
1136
|
+
if (await pathExists(ripgrepPath)) {
|
|
1137
|
+
if (process.platform !== "win32")
|
|
1138
|
+
await import_promises3.default.chmod(ripgrepPath, 493);
|
|
1139
|
+
process.env.CURSOR_RIPGREP_PATH ??= ripgrepPath;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
const entryPath = resolvePackageEntry(
|
|
1143
|
+
vendorNodeModules,
|
|
1144
|
+
CURSOR_SDK_PACKAGE_NAME,
|
|
1145
|
+
".",
|
|
1146
|
+
);
|
|
1147
|
+
if (!entryPath) {
|
|
1148
|
+
throw new Error(
|
|
1149
|
+
`Vendored Cursor SDK at ${vendorRoot} is missing or unreadable; delete the directory to reinstall`,
|
|
1150
|
+
);
|
|
1151
|
+
}
|
|
1152
|
+
const requireFromVendor = import_node_module2.createRequire(
|
|
1153
|
+
import_node_path4.default.join(
|
|
1154
|
+
vendorNodeModules,
|
|
1155
|
+
CURSOR_SDK_PACKAGE_NAME,
|
|
1156
|
+
"package.json",
|
|
1157
|
+
),
|
|
1158
|
+
);
|
|
1159
|
+
return requireFromVendor(entryPath);
|
|
1160
|
+
}
|
|
1161
|
+
async function pathExists(target) {
|
|
1162
|
+
try {
|
|
1163
|
+
await import_promises3.default.access(target);
|
|
1164
|
+
return true;
|
|
1165
|
+
} catch {
|
|
1166
|
+
return false;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
// cursor/src/llm/cursorProviders.ts
|
|
1171
|
+
var logger3 = import_internal3.Logger.get(
|
|
1172
|
+
"packages/typescript/cursor/src/llm/cursorProviders.ts",
|
|
1173
|
+
);
|
|
1174
|
+
var cursorProviders = {
|
|
1175
|
+
cursor: (model) => {
|
|
1176
|
+
logger3.debug(`Creating Cursor LLM with model ${model.name}`);
|
|
1177
|
+
const apiKey = import_internal3.Env.CURSOR_API_KEY;
|
|
1178
|
+
if (apiKey)
|
|
1179
|
+
logger3.debug(
|
|
1180
|
+
`Cursor API Key is set: ${import_internal3.maskString(apiKey)}`,
|
|
1181
|
+
);
|
|
1182
|
+
return new CursorLanguageModel({
|
|
1183
|
+
modelId: model.name,
|
|
1184
|
+
...(apiKey ? { apiKey } : {}),
|
|
1185
|
+
...(import_internal3.isSingleFileExecutable()
|
|
1186
|
+
? { sdkLoader: loadVendoredCursorSdk }
|
|
1187
|
+
: {}),
|
|
1188
|
+
});
|
|
1189
|
+
},
|
|
1190
|
+
};
|
|
1191
|
+
import_internal3.LlmFactory.register(cursorProviders);
|
|
1192
|
+
|
|
1193
|
+
//# debugId=AC468DAB1BED071964756E2164756E21
|
|
1194
|
+
//# sourceMappingURL=index.cjs.map
|