cursor-api-proxy 0.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 (80) hide show
  1. package/README.md +219 -0
  2. package/dist/cli.d.ts +5 -0
  3. package/dist/cli.js +53 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/client.d.ts +95 -0
  6. package/dist/client.js +316 -0
  7. package/dist/client.js.map +1 -0
  8. package/dist/lib/agent-cmd-args.d.ts +5 -0
  9. package/dist/lib/agent-cmd-args.js +24 -0
  10. package/dist/lib/agent-cmd-args.js.map +1 -0
  11. package/dist/lib/agent-runner.d.ts +12 -0
  12. package/dist/lib/agent-runner.js +38 -0
  13. package/dist/lib/agent-runner.js.map +1 -0
  14. package/dist/lib/anthropic.d.ts +26 -0
  15. package/dist/lib/anthropic.js +59 -0
  16. package/dist/lib/anthropic.js.map +1 -0
  17. package/dist/lib/cli-stream-parser.d.ts +8 -0
  18. package/dist/lib/cli-stream-parser.js +46 -0
  19. package/dist/lib/cli-stream-parser.js.map +1 -0
  20. package/dist/lib/config.d.ts +28 -0
  21. package/dist/lib/config.js +24 -0
  22. package/dist/lib/config.js.map +1 -0
  23. package/dist/lib/cursor-cli.d.ts +9 -0
  24. package/dist/lib/cursor-cli.js +30 -0
  25. package/dist/lib/cursor-cli.js.map +1 -0
  26. package/dist/lib/cursorCli.d.ts +9 -0
  27. package/dist/lib/cursorCli.js +30 -0
  28. package/dist/lib/cursorCli.js.map +1 -0
  29. package/dist/lib/env.d.ts +41 -0
  30. package/dist/lib/env.js +138 -0
  31. package/dist/lib/env.js.map +1 -0
  32. package/dist/lib/handlers/anthropic-messages.d.ts +9 -0
  33. package/dist/lib/handlers/anthropic-messages.js +124 -0
  34. package/dist/lib/handlers/anthropic-messages.js.map +1 -0
  35. package/dist/lib/handlers/chat-completions.d.ts +9 -0
  36. package/dist/lib/handlers/chat-completions.js +98 -0
  37. package/dist/lib/handlers/chat-completions.js.map +1 -0
  38. package/dist/lib/handlers/health.d.ts +7 -0
  39. package/dist/lib/handlers/health.js +15 -0
  40. package/dist/lib/handlers/health.js.map +1 -0
  41. package/dist/lib/handlers/models.d.ts +14 -0
  42. package/dist/lib/handlers/models.js +34 -0
  43. package/dist/lib/handlers/models.js.map +1 -0
  44. package/dist/lib/http.d.ts +5 -0
  45. package/dist/lib/http.js +32 -0
  46. package/dist/lib/http.js.map +1 -0
  47. package/dist/lib/max-mode-preflight.d.ts +5 -0
  48. package/dist/lib/max-mode-preflight.js +56 -0
  49. package/dist/lib/max-mode-preflight.js.map +1 -0
  50. package/dist/lib/model-map.d.ts +17 -0
  51. package/dist/lib/model-map.js +62 -0
  52. package/dist/lib/model-map.js.map +1 -0
  53. package/dist/lib/modelMap.d.ts +17 -0
  54. package/dist/lib/modelMap.js +62 -0
  55. package/dist/lib/modelMap.js.map +1 -0
  56. package/dist/lib/openai.d.ts +7 -0
  57. package/dist/lib/openai.js +59 -0
  58. package/dist/lib/openai.js.map +1 -0
  59. package/dist/lib/process.d.ts +19 -0
  60. package/dist/lib/process.js +92 -0
  61. package/dist/lib/process.js.map +1 -0
  62. package/dist/lib/request-listener.d.ts +7 -0
  63. package/dist/lib/request-listener.js +70 -0
  64. package/dist/lib/request-listener.js.map +1 -0
  65. package/dist/lib/request-log.d.ts +13 -0
  66. package/dist/lib/request-log.js +110 -0
  67. package/dist/lib/request-log.js.map +1 -0
  68. package/dist/lib/requestLog.d.ts +2 -0
  69. package/dist/lib/requestLog.js +19 -0
  70. package/dist/lib/requestLog.js.map +1 -0
  71. package/dist/lib/resolve-model.d.ts +8 -0
  72. package/dist/lib/resolve-model.js +18 -0
  73. package/dist/lib/resolve-model.js.map +1 -0
  74. package/dist/lib/server.d.ts +8 -0
  75. package/dist/lib/server.js +35 -0
  76. package/dist/lib/server.js.map +1 -0
  77. package/dist/lib/workspace.d.ts +6 -0
  78. package/dist/lib/workspace.js +15 -0
  79. package/dist/lib/workspace.js.map +1 -0
  80. package/package.json +50 -0
package/dist/client.js ADDED
@@ -0,0 +1,316 @@
1
+ /**
2
+ * SDK for calling cursor-api-proxy from another project.
3
+ *
4
+ * When startProxy is true (default), the SDK will start the proxy in the
5
+ * background if it is not already reachable. Prerequisites: Cursor agent CLI
6
+ * must be installed and set up separately (see README).
7
+ */
8
+ const DEFAULT_BASE_URL = "http://127.0.0.1:8765";
9
+ const HEALTH_PATH = "/health";
10
+ const PROXY_START_TIMEOUT_MS = 15_000;
11
+ const PROXY_POLL_MS = 200;
12
+ const PROXY_STOP_TIMEOUT_MS = 5_000;
13
+ const SHUTDOWN_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP", "SIGBREAK"];
14
+ let _proxyProcess = null;
15
+ let _managedProxyStartupPromise = null;
16
+ let _managedProxyStartedBySdk = false;
17
+ let _shutdownHandlersInstalled = false;
18
+ let _signalCleanupInProgress = false;
19
+ function killManagedProxySync() {
20
+ const child = _proxyProcess;
21
+ if (!child || !_managedProxyStartedBySdk)
22
+ return;
23
+ if (child.exitCode == null) {
24
+ try {
25
+ child.kill("SIGTERM");
26
+ }
27
+ catch { }
28
+ }
29
+ _proxyProcess = null;
30
+ _managedProxyStartedBySdk = false;
31
+ _managedProxyStartupPromise = null;
32
+ }
33
+ function installShutdownHandlers() {
34
+ if (_shutdownHandlersInstalled ||
35
+ typeof process === "undefined" ||
36
+ !process?.on) {
37
+ return;
38
+ }
39
+ _shutdownHandlersInstalled = true;
40
+ process.on("exit", () => {
41
+ killManagedProxySync();
42
+ });
43
+ const handleSignal = async (signal) => {
44
+ if (_signalCleanupInProgress) {
45
+ return;
46
+ }
47
+ _signalCleanupInProgress = true;
48
+ try {
49
+ await stopManagedProxy();
50
+ }
51
+ finally {
52
+ for (const value of SHUTDOWN_SIGNALS) {
53
+ process.removeListener(value, signalHandlers[value]);
54
+ }
55
+ _signalCleanupInProgress = false;
56
+ try {
57
+ process.kill(process.pid, signal);
58
+ }
59
+ catch {
60
+ process.exit(1);
61
+ }
62
+ }
63
+ };
64
+ const signalHandlers = {
65
+ SIGINT: () => {
66
+ void handleSignal("SIGINT");
67
+ },
68
+ SIGTERM: () => {
69
+ void handleSignal("SIGTERM");
70
+ },
71
+ SIGHUP: () => {
72
+ void handleSignal("SIGHUP");
73
+ },
74
+ SIGBREAK: () => {
75
+ void handleSignal("SIGBREAK");
76
+ },
77
+ };
78
+ for (const signal of SHUTDOWN_SIGNALS) {
79
+ process.on(signal, signalHandlers[signal]);
80
+ }
81
+ }
82
+ function isDefaultBaseUrl(baseUrl) {
83
+ const u = baseUrl.replace(/\/$/, "");
84
+ return u === DEFAULT_BASE_URL || u === "http://127.0.0.1:8765" || u === "http://localhost:8765";
85
+ }
86
+ async function pingHealth(baseUrl) {
87
+ const url = `${baseUrl.replace(/\/$/, "")}${HEALTH_PATH}`;
88
+ try {
89
+ const res = await fetch(url, { method: "GET" });
90
+ return res.ok;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ /**
97
+ * Ensures the proxy is running at the given base URL. If the URL is the default
98
+ * and the proxy is not reachable, starts it in the background (Node.js only).
99
+ * Resolves when /health returns 200 or rejects on timeout.
100
+ */
101
+ export async function ensureProxyRunning(options = {}) {
102
+ const baseUrl = options.baseUrl ??
103
+ ((typeof process !== "undefined" && process.env?.CURSOR_PROXY_URL) ||
104
+ DEFAULT_BASE_URL);
105
+ const root = baseUrl.replace(/\/$/, "");
106
+ const timeoutMs = options.timeoutMs ?? PROXY_START_TIMEOUT_MS;
107
+ if (await pingHealth(root)) {
108
+ return root;
109
+ }
110
+ if (!isDefaultBaseUrl(root)) {
111
+ throw new Error(`cursor-api-proxy is not reachable at ${root}. Start it manually (e.g. npx cursor-api-proxy) or use the default URL for auto-start.`);
112
+ }
113
+ const isNode = typeof process !== "undefined" &&
114
+ process.versions?.node &&
115
+ typeof globalThis.fetch !== "undefined";
116
+ if (!isNode) {
117
+ throw new Error("cursor-api-proxy is not reachable. Start it manually (e.g. npx cursor-api-proxy). Auto-start is only available in Node.js.");
118
+ }
119
+ if (_managedProxyStartupPromise) {
120
+ return _managedProxyStartupPromise;
121
+ }
122
+ const startupPromise = (async () => {
123
+ const { spawn } = await import("node:child_process");
124
+ const pathMod = await import("node:path");
125
+ const path = pathMod.default;
126
+ const { fileURLToPath } = await import("node:url");
127
+ const clientDir = path.dirname(fileURLToPath(import.meta.url));
128
+ const cliPath = path.join(clientDir, "cli.js");
129
+ const child = spawn(process.execPath, [cliPath], {
130
+ stdio: "ignore",
131
+ detached: false,
132
+ cwd: process.cwd(),
133
+ env: process.env,
134
+ });
135
+ child.unref();
136
+ installShutdownHandlers();
137
+ _proxyProcess = child;
138
+ _managedProxyStartedBySdk = true;
139
+ let exitCode = null;
140
+ child.on("error", () => {
141
+ _proxyProcess = null;
142
+ _managedProxyStartedBySdk = false;
143
+ });
144
+ child.on("exit", (code) => {
145
+ exitCode = code ?? null;
146
+ _proxyProcess = null;
147
+ _managedProxyStartedBySdk = false;
148
+ });
149
+ const deadline = Date.now() + timeoutMs;
150
+ while (Date.now() < deadline) {
151
+ await new Promise((r) => setTimeout(r, PROXY_POLL_MS));
152
+ if (await pingHealth(root)) {
153
+ return root;
154
+ }
155
+ if (exitCode != null) {
156
+ _proxyProcess = null;
157
+ _managedProxyStartedBySdk = false;
158
+ throw new Error(`cursor-api-proxy process exited with code ${exitCode} before becoming ready. Ensure Cursor CLI is installed (agent login).`);
159
+ }
160
+ }
161
+ if (_proxyProcess) {
162
+ _proxyProcess.kill();
163
+ _proxyProcess = null;
164
+ }
165
+ _managedProxyStartedBySdk = false;
166
+ throw new Error(`cursor-api-proxy did not become ready within ${timeoutMs}ms. Ensure Cursor CLI is installed (agent login).`);
167
+ })();
168
+ _managedProxyStartupPromise = startupPromise;
169
+ try {
170
+ return await startupPromise;
171
+ }
172
+ finally {
173
+ if (_managedProxyStartupPromise === startupPromise) {
174
+ _managedProxyStartupPromise = null;
175
+ }
176
+ }
177
+ }
178
+ export async function stopManagedProxy(options = {}) {
179
+ const child = _proxyProcess;
180
+ if (!child || !_managedProxyStartedBySdk) {
181
+ return false;
182
+ }
183
+ const timeoutMs = options.timeoutMs ?? PROXY_STOP_TIMEOUT_MS;
184
+ _managedProxyStartupPromise = null;
185
+ if (child.exitCode != null) {
186
+ _proxyProcess = null;
187
+ _managedProxyStartedBySdk = false;
188
+ return true;
189
+ }
190
+ const exitPromise = new Promise((resolve) => {
191
+ child.once("exit", () => resolve());
192
+ child.once("error", () => resolve());
193
+ });
194
+ child.kill("SIGTERM");
195
+ const exited = await Promise.race([
196
+ exitPromise.then(() => true),
197
+ new Promise((resolve) => {
198
+ setTimeout(() => resolve(false), timeoutMs);
199
+ }),
200
+ ]);
201
+ if (!exited && child.exitCode == null) {
202
+ child.kill("SIGKILL");
203
+ await exitPromise;
204
+ }
205
+ _proxyProcess = null;
206
+ _managedProxyStartedBySdk = false;
207
+ return true;
208
+ }
209
+ /**
210
+ * Options suitable for the OpenAI SDK constructor.
211
+ * Use: new OpenAI(getOpenAIOptions())
212
+ * For auto-starting the proxy first, use getOpenAIOptionsAsync() and await it.
213
+ */
214
+ export function getOpenAIOptions(options = {}) {
215
+ const baseUrl = options.baseUrl ??
216
+ ((typeof process !== "undefined" && process.env?.CURSOR_PROXY_URL) ||
217
+ DEFAULT_BASE_URL);
218
+ const baseURL = baseUrl.endsWith("/v1") ? baseUrl : `${baseUrl.replace(/\/$/, "")}/v1`;
219
+ const apiKey = options.apiKey ??
220
+ ((typeof process !== "undefined" && process.env?.CURSOR_BRIDGE_API_KEY) ||
221
+ "unused");
222
+ return { baseURL, apiKey };
223
+ }
224
+ /**
225
+ * Like getOpenAIOptions but ensures the proxy is running first (starts it in the background if needed).
226
+ * Use: new OpenAI(await getOpenAIOptionsAsync())
227
+ */
228
+ export async function getOpenAIOptionsAsync(options = {}) {
229
+ const startProxy = options.startProxy !== false;
230
+ const baseUrl = options.baseUrl ??
231
+ ((typeof process !== "undefined" && process.env?.CURSOR_PROXY_URL) ||
232
+ DEFAULT_BASE_URL);
233
+ const root = baseUrl.replace(/\/$/, "");
234
+ if (startProxy && isDefaultBaseUrl(root)) {
235
+ await ensureProxyRunning({ baseUrl: root, timeoutMs: options.timeoutMs });
236
+ }
237
+ return getOpenAIOptions(options);
238
+ }
239
+ /**
240
+ * Minimal client to call the proxy HTTP API.
241
+ * When startProxy is true (default), the proxy is started in the background on first request if not reachable.
242
+ */
243
+ export function createCursorProxyClient(options = {}) {
244
+ const startProxy = options.startProxy !== false;
245
+ const baseUrl = options.baseUrl ??
246
+ ((typeof process !== "undefined" && process.env?.CURSOR_PROXY_URL) ||
247
+ DEFAULT_BASE_URL);
248
+ const root = baseUrl.replace(/\/$/, "");
249
+ const apiKeyRaw = options.apiKey ??
250
+ (typeof process !== "undefined" ? process.env?.CURSOR_BRIDGE_API_KEY : undefined);
251
+ const apiKey = typeof apiKeyRaw === "string" ? apiKeyRaw : undefined;
252
+ const headers = {
253
+ "Content-Type": "application/json",
254
+ ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
255
+ };
256
+ async function ensureThenRequest(path, init) {
257
+ const url = path.startsWith("http")
258
+ ? path
259
+ : `${root}${path.startsWith("/") ? "" : "/"}${path}`;
260
+ if (startProxy && isDefaultBaseUrl(root)) {
261
+ await ensureProxyRunning({ baseUrl: root });
262
+ }
263
+ return fetch(url, init);
264
+ }
265
+ return {
266
+ /** Base URL of the proxy (no /v1 suffix) */
267
+ baseUrl: root,
268
+ /** Headers to send (Content-Type and optional Authorization) */
269
+ headers,
270
+ /** Get options for the OpenAI SDK constructor */
271
+ getOpenAIOptions: () => getOpenAIOptions({ baseUrl: root, apiKey: apiKey ?? "unused" }),
272
+ /**
273
+ * POST to a path (e.g. /v1/chat/completions). Body is JSON-serialized.
274
+ */
275
+ async request(path, body) {
276
+ const url = path.startsWith("http")
277
+ ? path
278
+ : `${root}${path.startsWith("/") ? "" : "/"}${path}`;
279
+ const res = await ensureThenRequest(url, {
280
+ method: "POST",
281
+ headers,
282
+ body: JSON.stringify(body),
283
+ });
284
+ const data = (await res.json().catch(() => ({})));
285
+ return { data, ok: res.ok, status: res.status };
286
+ },
287
+ /** OpenAI-style chat completions (non-streaming). */
288
+ async chatCompletionsCreate(params) {
289
+ const { data, ok, status } = await this.request("/v1/chat/completions", {
290
+ model: params.model ?? "auto",
291
+ messages: params.messages,
292
+ stream: false,
293
+ });
294
+ if (!ok) {
295
+ const err = data?.error?.message ?? JSON.stringify(data);
296
+ throw new Error(`cursor-api-proxy error (${status}): ${err}`);
297
+ }
298
+ return data;
299
+ },
300
+ /**
301
+ * Use for streaming: returns a fetch Response so you can read the body stream.
302
+ * Ensures the proxy is running first when startProxy is true.
303
+ */
304
+ async fetch(path, init = {}) {
305
+ const url = path.startsWith("http")
306
+ ? path
307
+ : `${root}${path.startsWith("/") ? "" : "/"}${path}`;
308
+ const merged = new Headers(init.headers);
309
+ merged.set("Content-Type", "application/json");
310
+ if (apiKey)
311
+ merged.set("Authorization", `Bearer ${apiKey}`);
312
+ return ensureThenRequest(url, { ...init, headers: merged });
313
+ },
314
+ };
315
+ }
316
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { BridgeConfig } from "./config.js";
2
+ /**
3
+ * Build CLI arguments for running the Cursor agent.
4
+ */
5
+ export declare function buildAgentCmdArgs(config: BridgeConfig, workspaceDir: string, model: string, prompt: string, stream: boolean): string[];
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Build CLI arguments for running the Cursor agent.
3
+ */
4
+ export function buildAgentCmdArgs(config, workspaceDir, model, prompt, stream) {
5
+ const args = ["--print"];
6
+ if (config.approveMcps)
7
+ args.push("--approve-mcps");
8
+ if (config.force)
9
+ args.push("--force");
10
+ if (config.chatOnlyWorkspace)
11
+ args.push("--trust");
12
+ args.push("--mode", "ask");
13
+ args.push("--workspace", workspaceDir);
14
+ args.push("--model", model);
15
+ if (stream) {
16
+ args.push("--stream-partial-output", "--output-format", "stream-json");
17
+ }
18
+ else {
19
+ args.push("--output-format", "text");
20
+ }
21
+ args.push(prompt);
22
+ return args;
23
+ }
24
+ //# sourceMappingURL=agent-cmd-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-cmd-args.js","sourceRoot":"","sources":["../../src/lib/agent-cmd-args.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAoB,EACpB,YAAoB,EACpB,KAAa,EACb,MAAc,EACd,MAAe;IAEf,MAAM,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IACzB,IAAI,MAAM,CAAC,WAAW;QAAE,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,iBAAiB;QAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5B,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,iBAAiB,EAAE,aAAa,CAAC,CAAC;IACzE,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { BridgeConfig } from "./config.js";
2
+ export type AgentRunResult = {
3
+ code: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ };
7
+ export declare function runAgentSync(config: BridgeConfig, workspaceDir: string, cmdArgs: string[], tempDir?: string): Promise<AgentRunResult>;
8
+ export type StreamLineHandler = (line: string) => void;
9
+ export declare function runAgentStream(config: BridgeConfig, workspaceDir: string, cmdArgs: string[], onLine: StreamLineHandler, tempDir?: string): Promise<{
10
+ code: number;
11
+ stderr: string;
12
+ }>;
@@ -0,0 +1,38 @@
1
+ import * as fs from "node:fs";
2
+ import { run, runStreaming } from "./process.js";
3
+ export function runAgentSync(config, workspaceDir, cmdArgs, tempDir) {
4
+ return run(config.agentBin, cmdArgs, {
5
+ cwd: workspaceDir,
6
+ timeoutMs: config.timeoutMs,
7
+ maxMode: config.maxMode,
8
+ }).then((out) => {
9
+ if (tempDir) {
10
+ try {
11
+ fs.rmSync(tempDir, { recursive: true, force: true });
12
+ }
13
+ catch {
14
+ /* ignore */
15
+ }
16
+ }
17
+ return out;
18
+ });
19
+ }
20
+ export function runAgentStream(config, workspaceDir, cmdArgs, onLine, tempDir) {
21
+ return runStreaming(config.agentBin, cmdArgs, {
22
+ cwd: workspaceDir,
23
+ timeoutMs: config.timeoutMs,
24
+ maxMode: config.maxMode,
25
+ onLine,
26
+ }).then((result) => {
27
+ if (tempDir) {
28
+ try {
29
+ fs.rmSync(tempDir, { recursive: true, force: true });
30
+ }
31
+ catch {
32
+ /* ignore */
33
+ }
34
+ }
35
+ return result;
36
+ });
37
+ }
38
+ //# sourceMappingURL=agent-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../src/lib/agent-runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAQjD,MAAM,UAAU,YAAY,CAC1B,MAAoB,EACpB,YAAoB,EACpB,OAAiB,EACjB,OAAgB;IAEhB,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE;QACnC,GAAG,EAAE,YAAY;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;KACxB,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;QACd,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAID,MAAM,UAAU,cAAc,CAC5B,MAAoB,EACpB,YAAoB,EACpB,OAAiB,EACjB,MAAyB,EACzB,OAAgB;IAEhB,OAAO,YAAY,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE;QAC5C,GAAG,EAAE,YAAY;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM;KACP,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QACjB,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC;gBACH,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Anthropic Messages API support.
3
+ * Converts Anthropic request format to the prompt format used by Cursor CLI.
4
+ */
5
+ export type AnthropicMessageParam = {
6
+ role: "user" | "assistant";
7
+ content: string | Array<{
8
+ type?: string;
9
+ text?: string;
10
+ }>;
11
+ };
12
+ export type AnthropicMessagesRequest = {
13
+ model?: string;
14
+ max_tokens: number;
15
+ messages: AnthropicMessageParam[];
16
+ system?: string | Array<{
17
+ type?: string;
18
+ text?: string;
19
+ }>;
20
+ stream?: boolean;
21
+ };
22
+ /**
23
+ * Convert Anthropic messages + optional system prompt to the prompt format
24
+ * expected by buildPromptFromMessages (OpenAI-style messages array).
25
+ */
26
+ export declare function buildPromptFromAnthropicMessages(messages: AnthropicMessageParam[] | undefined, system?: AnthropicMessagesRequest["system"]): string;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Anthropic Messages API support.
3
+ * Converts Anthropic request format to the prompt format used by Cursor CLI.
4
+ */
5
+ import { buildPromptFromMessages } from "./openai.js";
6
+ function systemToText(system) {
7
+ if (system == null)
8
+ return "";
9
+ if (typeof system === "string")
10
+ return system.trim();
11
+ if (!Array.isArray(system))
12
+ return "";
13
+ return system
14
+ .map((p) => {
15
+ if (!p || typeof p !== "object")
16
+ return "";
17
+ if (p.type === "text" && typeof p.text === "string")
18
+ return p.text;
19
+ return "";
20
+ })
21
+ .join("\n");
22
+ }
23
+ function anthropicContentToText(content) {
24
+ if (typeof content === "string")
25
+ return content;
26
+ if (!Array.isArray(content))
27
+ return "";
28
+ return content
29
+ .map((p) => {
30
+ if (!p)
31
+ return "";
32
+ if (typeof p === "string")
33
+ return p;
34
+ if (p.type === "text" && typeof p.text === "string")
35
+ return p.text;
36
+ return "";
37
+ })
38
+ .join("");
39
+ }
40
+ /**
41
+ * Convert Anthropic messages + optional system prompt to the prompt format
42
+ * expected by buildPromptFromMessages (OpenAI-style messages array).
43
+ */
44
+ export function buildPromptFromAnthropicMessages(messages, system) {
45
+ const openaiMessages = [];
46
+ const systemText = systemToText(system);
47
+ if (systemText) {
48
+ openaiMessages.push({ role: "system", content: systemText });
49
+ }
50
+ for (const m of messages || []) {
51
+ const text = anthropicContentToText(m.content);
52
+ if (!text)
53
+ continue;
54
+ const role = m.role === "user" || m.role === "assistant" ? m.role : "user";
55
+ openaiMessages.push({ role, content: text });
56
+ }
57
+ return buildPromptFromMessages(openaiMessages);
58
+ }
59
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/lib/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAetD,SAAS,YAAY,CAAC,MAA0C;IAC9D,IAAI,MAAM,IAAI,IAAI;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACrD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAC3C,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAyC;IACvE,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QAClB,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gCAAgC,CAC9C,QAA6C,EAC7C,MAA2C;IAE3C,MAAM,cAAc,GAA6C,EAAE,CAAC;IAEpE,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,UAAU,EAAE,CAAC;QACf,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,QAAQ,IAAI,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,sBAAsB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3E,cAAc,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,uBAAuB,CAAC,cAAc,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Create a stateful stream parser for Cursor CLI stream-json output.
3
+ *
4
+ * The CLI emits individual assistant delta chunks and then a final assistant
5
+ * message containing the full accumulated text. We track what we've already
6
+ * emitted so the final duplicate is skipped.
7
+ */
8
+ export declare function createStreamParser(onText: (text: string) => void, onDone: () => void): (line: string) => void;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Create a stateful stream parser for Cursor CLI stream-json output.
3
+ *
4
+ * The CLI emits individual assistant delta chunks and then a final assistant
5
+ * message containing the full accumulated text. We track what we've already
6
+ * emitted so the final duplicate is skipped.
7
+ */
8
+ export function createStreamParser(onText, onDone) {
9
+ let accumulated = "";
10
+ let done = false;
11
+ return (line) => {
12
+ if (done)
13
+ return;
14
+ try {
15
+ const obj = JSON.parse(line);
16
+ if (obj.type === "assistant" && obj.message?.content) {
17
+ const text = obj.message.content
18
+ .filter((p) => p.type === "text" && p.text)
19
+ .map((p) => p.text)
20
+ .join("");
21
+ if (!text)
22
+ return;
23
+ if (text === accumulated)
24
+ return;
25
+ if (text.startsWith(accumulated) && accumulated.length > 0) {
26
+ const delta = text.slice(accumulated.length);
27
+ if (delta)
28
+ onText(delta);
29
+ accumulated = text;
30
+ }
31
+ else {
32
+ onText(text);
33
+ accumulated += text;
34
+ }
35
+ }
36
+ if (obj.type === "result" && obj.subtype === "success") {
37
+ done = true;
38
+ onDone();
39
+ }
40
+ }
41
+ catch {
42
+ /* ignore parse errors for non-JSON lines */
43
+ }
44
+ };
45
+ }
46
+ //# sourceMappingURL=cli-stream-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-stream-parser.js","sourceRoot":"","sources":["../../src/lib/cli-stream-parser.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA8B,EAC9B,MAAkB;IAElB,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,OAAO,CAAC,IAAY,EAAE,EAAE;QACtB,IAAI,IAAI;YAAE,OAAO;QACjB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAI1B,CAAC;YAEF,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,IAAI,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;gBACrD,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO;qBAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;qBAC1C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAK,CAAC;qBACnB,IAAI,CAAC,EAAE,CAAC,CAAC;gBACZ,IAAI,CAAC,IAAI;oBAAE,OAAO;gBAElB,IAAI,IAAI,KAAK,WAAW;oBAAE,OAAO;gBAEjC,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAC7C,IAAI,KAAK;wBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;oBACzB,WAAW,GAAG,IAAI,CAAC;gBACrB,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,CAAC;oBACb,WAAW,IAAI,IAAI,CAAC;gBACtB,CAAC;YACH,CAAC;YAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACvD,IAAI,GAAG,IAAI,CAAC;gBACZ,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,4CAA4C;QAC9C,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type EnvOptions } from "./env.js";
2
+ export type CursorExecutionMode = "agent" | "ask" | "plan";
3
+ export type BridgeConfig = {
4
+ agentBin: string;
5
+ host: string;
6
+ port: number;
7
+ requiredKey?: string;
8
+ defaultModel: string;
9
+ mode: CursorExecutionMode;
10
+ force: boolean;
11
+ approveMcps: boolean;
12
+ strictModel: boolean;
13
+ workspace: string;
14
+ timeoutMs: number;
15
+ /** Path to TLS certificate file (e.g. Tailscale cert). When set with tlsKeyPath, server uses HTTPS. */
16
+ tlsCertPath?: string;
17
+ /** Path to TLS private key file. When set with tlsCertPath, server uses HTTPS. */
18
+ tlsKeyPath?: string;
19
+ /** Path to sessions log file; each request is appended as a line. Default: sessions.log in cwd. */
20
+ sessionsLogPath: string;
21
+ /** When true (default), run CLI in an empty temp dir so it cannot read or write the real project. Pure chat only. */
22
+ chatOnlyWorkspace: boolean;
23
+ /** When true, print full request/response content to stdout for each completion. */
24
+ verbose: boolean;
25
+ /** When true, enable Cursor Max Mode (larger context, more tool calls) via cli-config.json preflight. */
26
+ maxMode: boolean;
27
+ };
28
+ export declare function loadBridgeConfig(opts?: EnvOptions): BridgeConfig;
@@ -0,0 +1,24 @@
1
+ import { loadEnvConfig } from "./env.js";
2
+ export function loadBridgeConfig(opts = {}) {
3
+ const env = loadEnvConfig(opts);
4
+ return {
5
+ agentBin: env.agentBin,
6
+ host: env.host,
7
+ port: env.port,
8
+ requiredKey: env.requiredKey,
9
+ defaultModel: env.defaultModel,
10
+ mode: "ask", // proxy is chat-only; CURSOR_BRIDGE_MODE is ignored
11
+ force: env.force,
12
+ approveMcps: env.approveMcps,
13
+ strictModel: env.strictModel,
14
+ workspace: env.workspace,
15
+ timeoutMs: env.timeoutMs,
16
+ tlsCertPath: env.tlsCertPath,
17
+ tlsKeyPath: env.tlsKeyPath,
18
+ sessionsLogPath: env.sessionsLogPath,
19
+ chatOnlyWorkspace: env.chatOnlyWorkspace,
20
+ verbose: env.verbose,
21
+ maxMode: env.maxMode,
22
+ };
23
+ }
24
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAmB,MAAM,UAAU,CAAC;AA8B1D,MAAM,UAAU,gBAAgB,CAAC,OAAmB,EAAE;IACpD,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEhC,OAAO;QACL,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,IAAI,EAAE,KAAK,EAAE,oDAAoD;QACjE,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;QACxC,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,OAAO,EAAE,GAAG,CAAC,OAAO;KACrB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ export type CursorCliModel = {
2
+ id: string;
3
+ name: string;
4
+ };
5
+ export declare function parseCursorCliModels(output: string): CursorCliModel[];
6
+ export declare function listCursorCliModels(args: {
7
+ agentBin: string;
8
+ timeoutMs: number;
9
+ }): Promise<CursorCliModel[]>;