cursor-composer-in-claude 0.7.3

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 (104) hide show
  1. package/README.md +303 -0
  2. package/dist/cli/accounts.d.ts +18 -0
  3. package/dist/cli/accounts.js +149 -0
  4. package/dist/cli/accounts.js.map +1 -0
  5. package/dist/cli/args.d.ts +14 -0
  6. package/dist/cli/args.js +93 -0
  7. package/dist/cli/args.js.map +1 -0
  8. package/dist/cli/constants.d.ts +1 -0
  9. package/dist/cli/constants.js +4 -0
  10. package/dist/cli/constants.js.map +1 -0
  11. package/dist/cli/login.d.ts +1 -0
  12. package/dist/cli/login.js +143 -0
  13. package/dist/cli/login.js.map +1 -0
  14. package/dist/cli/reset-hwid.d.ts +24 -0
  15. package/dist/cli/reset-hwid.js +286 -0
  16. package/dist/cli/reset-hwid.js.map +1 -0
  17. package/dist/cli/usage.d.ts +27 -0
  18. package/dist/cli/usage.js +177 -0
  19. package/dist/cli/usage.js.map +1 -0
  20. package/dist/cli.d.ts +2 -0
  21. package/dist/cli.js +58 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/client.d.ts +95 -0
  24. package/dist/client.js +316 -0
  25. package/dist/client.js.map +1 -0
  26. package/dist/lib/account-pool.d.ts +35 -0
  27. package/dist/lib/account-pool.js +143 -0
  28. package/dist/lib/account-pool.js.map +1 -0
  29. package/dist/lib/acp-client.d.ts +53 -0
  30. package/dist/lib/acp-client.js +517 -0
  31. package/dist/lib/acp-client.js.map +1 -0
  32. package/dist/lib/agent-cmd-args.d.ts +9 -0
  33. package/dist/lib/agent-cmd-args.js +29 -0
  34. package/dist/lib/agent-cmd-args.js.map +1 -0
  35. package/dist/lib/agent-runner.d.ts +12 -0
  36. package/dist/lib/agent-runner.js +144 -0
  37. package/dist/lib/agent-runner.js.map +1 -0
  38. package/dist/lib/anthropic.d.ts +26 -0
  39. package/dist/lib/anthropic.js +70 -0
  40. package/dist/lib/anthropic.js.map +1 -0
  41. package/dist/lib/cli-stream-parser.d.ts +8 -0
  42. package/dist/lib/cli-stream-parser.js +46 -0
  43. package/dist/lib/cli-stream-parser.js.map +1 -0
  44. package/dist/lib/config.d.ts +52 -0
  45. package/dist/lib/config.js +47 -0
  46. package/dist/lib/config.js.map +1 -0
  47. package/dist/lib/cursor-cli.d.ts +9 -0
  48. package/dist/lib/cursor-cli.js +30 -0
  49. package/dist/lib/cursor-cli.js.map +1 -0
  50. package/dist/lib/env.d.ts +54 -0
  51. package/dist/lib/env.js +247 -0
  52. package/dist/lib/env.js.map +1 -0
  53. package/dist/lib/handlers/anthropic-messages.d.ts +9 -0
  54. package/dist/lib/handlers/anthropic-messages.js +281 -0
  55. package/dist/lib/handlers/anthropic-messages.js.map +1 -0
  56. package/dist/lib/handlers/chat-completions.d.ts +9 -0
  57. package/dist/lib/handlers/chat-completions.js +275 -0
  58. package/dist/lib/handlers/chat-completions.js.map +1 -0
  59. package/dist/lib/handlers/health.d.ts +7 -0
  60. package/dist/lib/handlers/health.js +15 -0
  61. package/dist/lib/handlers/health.js.map +1 -0
  62. package/dist/lib/handlers/models.d.ts +15 -0
  63. package/dist/lib/handlers/models.js +44 -0
  64. package/dist/lib/handlers/models.js.map +1 -0
  65. package/dist/lib/http.d.ts +5 -0
  66. package/dist/lib/http.js +36 -0
  67. package/dist/lib/http.js.map +1 -0
  68. package/dist/lib/max-mode-preflight.d.ts +5 -0
  69. package/dist/lib/max-mode-preflight.js +62 -0
  70. package/dist/lib/max-mode-preflight.js.map +1 -0
  71. package/dist/lib/model-map.d.ts +17 -0
  72. package/dist/lib/model-map.js +62 -0
  73. package/dist/lib/model-map.js.map +1 -0
  74. package/dist/lib/openai.d.ts +17 -0
  75. package/dist/lib/openai.js +111 -0
  76. package/dist/lib/openai.js.map +1 -0
  77. package/dist/lib/process.d.ts +32 -0
  78. package/dist/lib/process.js +174 -0
  79. package/dist/lib/process.js.map +1 -0
  80. package/dist/lib/request-listener.d.ts +7 -0
  81. package/dist/lib/request-listener.js +99 -0
  82. package/dist/lib/request-listener.js.map +1 -0
  83. package/dist/lib/request-log.d.ts +16 -0
  84. package/dist/lib/request-log.js +147 -0
  85. package/dist/lib/request-log.js.map +1 -0
  86. package/dist/lib/resolve-model.d.ts +8 -0
  87. package/dist/lib/resolve-model.js +18 -0
  88. package/dist/lib/resolve-model.js.map +1 -0
  89. package/dist/lib/sanitize.d.ts +21 -0
  90. package/dist/lib/sanitize.js +79 -0
  91. package/dist/lib/sanitize.js.map +1 -0
  92. package/dist/lib/server.d.ts +13 -0
  93. package/dist/lib/server.js +118 -0
  94. package/dist/lib/server.js.map +1 -0
  95. package/dist/lib/token-cache.d.ts +10 -0
  96. package/dist/lib/token-cache.js +35 -0
  97. package/dist/lib/token-cache.js.map +1 -0
  98. package/dist/lib/win-cmdline-limit.d.ts +32 -0
  99. package/dist/lib/win-cmdline-limit.js +92 -0
  100. package/dist/lib/win-cmdline-limit.js.map +1 -0
  101. package/dist/lib/workspace.d.ts +19 -0
  102. package/dist/lib/workspace.js +77 -0
  103. package/dist/lib/workspace.js.map +1 -0
  104. package/package.json +51 -0
@@ -0,0 +1,111 @@
1
+ export function normalizeModelId(raw) {
2
+ if (!raw)
3
+ return undefined;
4
+ const trimmed = raw.trim();
5
+ if (!trimmed)
6
+ return undefined;
7
+ const parts = trimmed.split("/");
8
+ return parts[parts.length - 1] || undefined;
9
+ }
10
+ function imageUrlToText(imageUrl) {
11
+ if (!imageUrl)
12
+ return "[Image]";
13
+ const url = typeof imageUrl === "string"
14
+ ? imageUrl
15
+ : typeof imageUrl?.url === "string"
16
+ ? imageUrl.url
17
+ : "";
18
+ if (!url)
19
+ return "[Image]";
20
+ if (url.startsWith("data:")) {
21
+ const mime = url.slice(5, url.indexOf(";")) || "image";
22
+ return `[Image: base64 ${mime}]`;
23
+ }
24
+ return `[Image: ${url}]`;
25
+ }
26
+ function messageContentToText(content) {
27
+ if (typeof content === "string")
28
+ return content;
29
+ if (Array.isArray(content)) {
30
+ return content
31
+ .map((p) => {
32
+ if (!p)
33
+ return "";
34
+ if (typeof p === "string")
35
+ return p;
36
+ if (p.type === "text" && typeof p.text === "string")
37
+ return p.text;
38
+ if (p.type === "image_url")
39
+ return imageUrlToText(p.image_url);
40
+ if (p.type === "image")
41
+ return imageUrlToText(p.source?.url ?? p.url ?? p.source);
42
+ return "";
43
+ })
44
+ .filter(Boolean)
45
+ .join(" ");
46
+ }
47
+ return "";
48
+ }
49
+ /**
50
+ * Serialise tool/function schemas into a text block for the system prompt.
51
+ * This allows the model to be aware of available tools even though we can't
52
+ * return tool_call deltas natively.
53
+ */
54
+ export function toolsToSystemText(tools, functions) {
55
+ const defs = [];
56
+ if (tools && tools.length > 0) {
57
+ for (const t of tools) {
58
+ const fn = t?.type === "function" ? t.function : t;
59
+ if (fn)
60
+ defs.push(fn);
61
+ }
62
+ }
63
+ if (functions && functions.length > 0) {
64
+ defs.push(...functions);
65
+ }
66
+ if (defs.length === 0)
67
+ return undefined;
68
+ const lines = [
69
+ "Available tools (respond with a JSON object to call one):",
70
+ "",
71
+ ...defs.map((fn) => {
72
+ const params = fn.parameters
73
+ ? JSON.stringify(fn.parameters, null, 2)
74
+ : "{}";
75
+ return `Function: ${fn.name}\nDescription: ${fn.description ?? ""}\nParameters: ${params}`;
76
+ }),
77
+ ];
78
+ return lines.join("\n");
79
+ }
80
+ export function buildPromptFromMessages(messages) {
81
+ const systemParts = [];
82
+ const convo = [];
83
+ for (const m of messages || []) {
84
+ const role = m?.role;
85
+ const text = messageContentToText(m?.content);
86
+ if (!text)
87
+ continue;
88
+ if (role === "system" || role === "developer") {
89
+ systemParts.push(text);
90
+ continue;
91
+ }
92
+ if (role === "user") {
93
+ convo.push(`User: ${text}`);
94
+ continue;
95
+ }
96
+ if (role === "assistant") {
97
+ convo.push(`Assistant: ${text}`);
98
+ continue;
99
+ }
100
+ if (role === "tool" || role === "function") {
101
+ convo.push(`Tool: ${text}`);
102
+ continue;
103
+ }
104
+ }
105
+ const system = systemParts.length
106
+ ? `System:\n${systemParts.join("\n\n")}\n\n`
107
+ : "";
108
+ const transcript = convo.join("\n\n");
109
+ return system + transcript + "\n\nAssistant:";
110
+ }
111
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/lib/openai.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ export type RunResult = {
3
+ code: number;
4
+ stdout: string;
5
+ stderr: string;
6
+ };
7
+ export type RunOptions = {
8
+ cwd?: string;
9
+ timeoutMs?: number;
10
+ /** Enable Cursor Max Mode (preflight writes maxMode to cli-config.json). */
11
+ maxMode?: boolean;
12
+ /** When set, pass this string to the child process stdin and close it (avoids long prompt in argv on Windows). */
13
+ stdinContent?: string;
14
+ /** Env overrides for the child (e.g. HOME, CURSOR_CONFIG_DIR to isolate from global rules). */
15
+ envOverrides?: Record<string, string>;
16
+ /** Custom config dir for round-robin account rotation */
17
+ configDir?: string;
18
+ /** Abort signal — when aborted, the child process is killed immediately */
19
+ signal?: AbortSignal;
20
+ };
21
+ export type RunStreamingOptions = RunOptions & {
22
+ onLine: (line: string) => void;
23
+ };
24
+ /** Kill all in-flight agent child processes. Called on server shutdown. */
25
+ export declare function killAllChildProcesses(): void;
26
+ /** Register a child (e.g. ACP) for graceful shutdown; removed on close. */
27
+ export declare function trackChildProcess(child: ChildProcess): void;
28
+ export declare function runStreaming(cmd: string, args: string[], opts: RunStreamingOptions): Promise<{
29
+ code: number;
30
+ stderr: string;
31
+ }>;
32
+ export declare function run(cmd: string, args: string[], opts?: RunOptions): Promise<RunResult>;
@@ -0,0 +1,174 @@
1
+ import { spawn } from "node:child_process";
2
+ import { resolveAgentCommand } from "./env.js";
3
+ import { runMaxModePreflight } from "./max-mode-preflight.js";
4
+ // ---------------------------------------------------------------------------
5
+ // Global child process registry — used for graceful shutdown
6
+ // ---------------------------------------------------------------------------
7
+ const activeChildren = new Set();
8
+ /** Kill all in-flight agent child processes. Called on server shutdown. */
9
+ export function killAllChildProcesses() {
10
+ for (const child of activeChildren) {
11
+ try {
12
+ child.kill("SIGTERM");
13
+ }
14
+ catch {
15
+ /* already exited */
16
+ }
17
+ }
18
+ activeChildren.clear();
19
+ }
20
+ /** Register a child (e.g. ACP) for graceful shutdown; removed on close. */
21
+ export function trackChildProcess(child) {
22
+ activeChildren.add(child);
23
+ child.once("close", () => {
24
+ activeChildren.delete(child);
25
+ });
26
+ }
27
+ // ---------------------------------------------------------------------------
28
+ // Internal helpers
29
+ // ---------------------------------------------------------------------------
30
+ function spawnChild(cmd, args, opts) {
31
+ const resolved = resolveAgentCommand(cmd, args);
32
+ if (opts?.maxMode) {
33
+ runMaxModePreflight(resolved.agentScriptPath, opts?.configDir);
34
+ }
35
+ const env = { ...resolved.env, CURSOR_SKIP_KEYCHAIN: "1" };
36
+ if (opts?.configDir) {
37
+ env.CURSOR_CONFIG_DIR = opts.configDir;
38
+ }
39
+ else if (resolved.configDir && !env.CURSOR_CONFIG_DIR) {
40
+ env.CURSOR_CONFIG_DIR = resolved.configDir;
41
+ }
42
+ if (opts?.envOverrides) {
43
+ Object.assign(env, opts.envOverrides);
44
+ }
45
+ const useStdin = typeof opts?.stdinContent === "string";
46
+ const child = spawn(resolved.command, resolved.args, {
47
+ cwd: opts?.cwd,
48
+ env,
49
+ stdio: useStdin ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"],
50
+ windowsVerbatimArguments: resolved.windowsVerbatimArguments,
51
+ });
52
+ if (useStdin && opts.stdinContent !== undefined && child.stdin) {
53
+ child.stdin.write(opts.stdinContent, "utf8");
54
+ child.stdin.end();
55
+ }
56
+ return child;
57
+ }
58
+ // ---------------------------------------------------------------------------
59
+ // Public API
60
+ // ---------------------------------------------------------------------------
61
+ export function runStreaming(cmd, args, opts) {
62
+ return new Promise((resolve, reject) => {
63
+ const child = spawnChild(cmd, args, {
64
+ cwd: opts.cwd,
65
+ maxMode: opts.maxMode,
66
+ stdinContent: opts.stdinContent,
67
+ envOverrides: opts.envOverrides,
68
+ configDir: opts.configDir,
69
+ });
70
+ activeChildren.add(child);
71
+ const timeoutMs = opts.timeoutMs;
72
+ const timeout = typeof timeoutMs === "number" && timeoutMs > 0
73
+ ? setTimeout(() => {
74
+ child.kill("SIGKILL");
75
+ }, timeoutMs)
76
+ : undefined;
77
+ // Abort signal support — kill child when client disconnects
78
+ const onAbort = () => child.kill("SIGTERM");
79
+ if (opts.signal) {
80
+ if (opts.signal.aborted) {
81
+ child.kill("SIGTERM");
82
+ }
83
+ else {
84
+ opts.signal.addEventListener("abort", onAbort, { once: true });
85
+ }
86
+ }
87
+ let stderr = "";
88
+ let lineBuffer = "";
89
+ child.stderr.setEncoding("utf8");
90
+ child.stderr.on("data", (c) => (stderr += c));
91
+ child.stdout.setEncoding("utf8");
92
+ child.stdout.on("data", (chunk) => {
93
+ lineBuffer += chunk;
94
+ const lines = lineBuffer.split("\n");
95
+ lineBuffer = lines.pop() ?? "";
96
+ for (const line of lines) {
97
+ if (line.trim())
98
+ opts.onLine(line);
99
+ }
100
+ });
101
+ child.on("error", (err) => {
102
+ if (timeout)
103
+ clearTimeout(timeout);
104
+ opts.signal?.removeEventListener("abort", onAbort);
105
+ activeChildren.delete(child);
106
+ if (err?.code === "ENOENT") {
107
+ reject(new Error(`Command not found: ${cmd}. Install Cursor CLI (agent) or set CURSOR_AGENT_BIN to its path.`));
108
+ return;
109
+ }
110
+ reject(err);
111
+ });
112
+ child.on("close", (code, signal) => {
113
+ if (timeout)
114
+ clearTimeout(timeout);
115
+ opts.signal?.removeEventListener("abort", onAbort);
116
+ activeChildren.delete(child);
117
+ if (lineBuffer.trim())
118
+ opts.onLine(lineBuffer.trim());
119
+ resolve({ code: code ?? (signal ? -1 : 0), stderr });
120
+ });
121
+ });
122
+ }
123
+ export function run(cmd, args, opts = {}) {
124
+ return new Promise((resolve, reject) => {
125
+ const child = spawnChild(cmd, args, {
126
+ cwd: opts.cwd,
127
+ maxMode: opts.maxMode,
128
+ stdinContent: opts.stdinContent,
129
+ envOverrides: opts.envOverrides,
130
+ configDir: opts.configDir,
131
+ });
132
+ activeChildren.add(child);
133
+ const timeoutMs = opts.timeoutMs;
134
+ const timeout = typeof timeoutMs === "number" && timeoutMs > 0
135
+ ? setTimeout(() => {
136
+ child.kill("SIGKILL");
137
+ }, timeoutMs)
138
+ : undefined;
139
+ const onAbort = () => child.kill("SIGTERM");
140
+ if (opts.signal) {
141
+ if (opts.signal.aborted) {
142
+ child.kill("SIGTERM");
143
+ }
144
+ else {
145
+ opts.signal.addEventListener("abort", onAbort, { once: true });
146
+ }
147
+ }
148
+ let stdout = "";
149
+ let stderr = "";
150
+ child.stdout.setEncoding("utf8");
151
+ child.stderr.setEncoding("utf8");
152
+ child.stdout.on("data", (c) => (stdout += c));
153
+ child.stderr.on("data", (c) => (stderr += c));
154
+ child.on("error", (err) => {
155
+ if (timeout)
156
+ clearTimeout(timeout);
157
+ opts.signal?.removeEventListener("abort", onAbort);
158
+ activeChildren.delete(child);
159
+ if (err?.code === "ENOENT") {
160
+ reject(new Error(`Command not found: ${cmd}. Install Cursor CLI (agent) or set CURSOR_AGENT_BIN to its path.`));
161
+ return;
162
+ }
163
+ reject(err);
164
+ });
165
+ child.on("close", (code, signal) => {
166
+ if (timeout)
167
+ clearTimeout(timeout);
168
+ opts.signal?.removeEventListener("abort", onAbort);
169
+ activeChildren.delete(child);
170
+ resolve({ code: code ?? (signal ? -1 : 0), stdout, stderr });
171
+ });
172
+ });
173
+ }
174
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/lib/process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import * as http from "node:http";
2
+ import type { BridgeConfig } from "./config.js";
3
+ export type BridgeServerOptions = {
4
+ version: string;
5
+ config: BridgeConfig;
6
+ };
7
+ export declare function createRequestListener(opts: BridgeServerOptions): (req: http.IncomingMessage, res: http.ServerResponse) => Promise<void>;
@@ -0,0 +1,99 @@
1
+ import * as crypto from "node:crypto";
2
+ import * as fs from "node:fs";
3
+ import { handleHealth } from "./handlers/health.js";
4
+ import { handleModels } from "./handlers/models.js";
5
+ import { handleChatCompletions } from "./handlers/chat-completions.js";
6
+ import { handleAnthropicMessages } from "./handlers/anthropic-messages.js";
7
+ import { extractBearerToken, json, readBody } from "./http.js";
8
+ import { appendSessionLine, logIncoming } from "./request-log.js";
9
+ export function createRequestListener(opts) {
10
+ const { config } = opts;
11
+ const modelCacheRef = { current: undefined };
12
+ const lastRequestedModelRef = {};
13
+ return async (req, res) => {
14
+ const protocol = config.tlsCertPath && config.tlsKeyPath ? "https" : "http";
15
+ const url = new URL(req.url || "/", `${protocol}://${req.headers.host || "localhost"}`);
16
+ const remoteAddress = req.socket?.remoteAddress ?? "unknown";
17
+ const method = req.method ?? "?";
18
+ const pathname = url.pathname;
19
+ logIncoming(method, pathname, remoteAddress);
20
+ res.on("finish", () => {
21
+ appendSessionLine(config.sessionsLogPath, method, pathname, remoteAddress, res.statusCode);
22
+ });
23
+ try {
24
+ if (config.requiredKey) {
25
+ const token = extractBearerToken(req) ?? "";
26
+ const expected = config.requiredKey;
27
+ const a = Buffer.from(token, "utf8");
28
+ const b = Buffer.from(expected, "utf8");
29
+ const match = a.length === b.length && crypto.timingSafeEqual(a, b);
30
+ if (!match) {
31
+ json(res, 401, {
32
+ error: { message: "Invalid API key", code: "unauthorized" },
33
+ });
34
+ return;
35
+ }
36
+ }
37
+ if (req.method === "GET" && pathname === "/health") {
38
+ handleHealth(res, { version: opts.version, config });
39
+ return;
40
+ }
41
+ if (req.method === "GET" && pathname === "/v1/models") {
42
+ await handleModels(res, { config, modelCacheRef });
43
+ return;
44
+ }
45
+ if (req.method === "POST" && pathname === "/v1/chat/completions") {
46
+ const raw = await readBody(req);
47
+ await handleChatCompletions(req, res, { config, lastRequestedModelRef }, raw, method, pathname, remoteAddress);
48
+ return;
49
+ }
50
+ if (req.method === "POST" && pathname === "/v1/messages") {
51
+ const raw = await readBody(req);
52
+ await handleAnthropicMessages(req, res, { config, lastRequestedModelRef }, raw, method, pathname, remoteAddress);
53
+ return;
54
+ }
55
+ if ((req.method === "POST" || req.method === "GET") &&
56
+ pathname === "/v1/completions") {
57
+ json(res, 404, {
58
+ error: {
59
+ message: "Legacy completions endpoint is not supported. Use POST /v1/chat/completions instead.",
60
+ code: "not_found",
61
+ },
62
+ });
63
+ }
64
+ else if (pathname === "/v1/embeddings") {
65
+ json(res, 404, {
66
+ error: {
67
+ message: "Embeddings are not supported by this proxy.",
68
+ code: "not_found",
69
+ },
70
+ });
71
+ }
72
+ else {
73
+ json(res, 404, { error: { message: "Not found", code: "not_found" } });
74
+ }
75
+ }
76
+ catch (err) {
77
+ const msg = err instanceof Error ? err.message : String(err);
78
+ console.error(`[${new Date().toISOString()}] Proxy error: ${msg}`);
79
+ if (err instanceof Error && err.stack) {
80
+ console.error(err.stack);
81
+ }
82
+ try {
83
+ fs.appendFileSync(config.sessionsLogPath, `${new Date().toISOString()} ERROR ${method} ${pathname} ${remoteAddress} ${msg.slice(0, 200).replace(/\n/g, " ")}\n`);
84
+ }
85
+ catch {
86
+ /* ignore */
87
+ }
88
+ if (!res.headersSent) {
89
+ json(res, 500, {
90
+ error: { message: msg, code: "internal_error" },
91
+ });
92
+ }
93
+ else {
94
+ res.end();
95
+ }
96
+ }
97
+ };
98
+ }
99
+ //# sourceMappingURL=request-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-listener.js","sourceRoot":"","sources":["../../src/lib/request-listener.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { AccountStat } from "./account-pool.js";
2
+ export declare function logIncoming(method: string, pathname: string, remoteAddress: string): void;
3
+ export type TrafficMessage = {
4
+ role: string;
5
+ content: string;
6
+ };
7
+ export declare function logAccountAssigned(configDir: string | undefined): void;
8
+ export declare function logAccountStats(verbose: boolean, stats: AccountStat[]): void;
9
+ export declare function logTrafficRequest(verbose: boolean, model: string, messages: TrafficMessage[], isStream: boolean): void;
10
+ export declare function logTrafficResponse(verbose: boolean, model: string, text: string, isStream: boolean): void;
11
+ export declare function appendSessionLine(logPath: string, method: string, pathname: string, remoteAddress: string, statusCode: number): void;
12
+ /**
13
+ * Log an agent execution error to console and sessions log.
14
+ * Returns the error message for use in API responses.
15
+ */
16
+ export declare function logAgentError(logPath: string, method: string, pathname: string, remoteAddress: string, exitCode: number, stderr: string): string;
@@ -0,0 +1,147 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ export function logIncoming(method, pathname, remoteAddress) {
4
+ console.log(`[${new Date().toISOString()}] Incoming: ${method} ${pathname} (from ${remoteAddress})`);
5
+ }
6
+ // ANSI color helpers
7
+ const C = {
8
+ reset: "\x1b[0m",
9
+ bold: "\x1b[1m",
10
+ dim: "\x1b[2m",
11
+ cyan: "\x1b[36m",
12
+ bCyan: "\x1b[1;96m",
13
+ green: "\x1b[32m",
14
+ bGreen: "\x1b[1;92m",
15
+ yellow: "\x1b[33m",
16
+ magenta: "\x1b[35m",
17
+ bMagenta: "\x1b[1;95m",
18
+ red: "\x1b[31m",
19
+ gray: "\x1b[90m",
20
+ white: "\x1b[97m",
21
+ };
22
+ const ROLE_STYLE = {
23
+ system: C.yellow,
24
+ user: C.cyan,
25
+ assistant: C.green,
26
+ };
27
+ const ROLE_EMOJI = {
28
+ system: "🔧",
29
+ user: "👤",
30
+ assistant: "🤖",
31
+ };
32
+ function ts() {
33
+ return `${C.gray}${new Date().toISOString()}${C.reset}`;
34
+ }
35
+ function truncate(s, max) {
36
+ if (s.length <= max)
37
+ return s;
38
+ const head = Math.floor(max * 0.6);
39
+ const tail = max - head;
40
+ const omitted = s.length - head - tail;
41
+ return (s.slice(0, head) +
42
+ `${C.dim} … (${omitted} chars omitted) … ` +
43
+ s.slice(s.length - tail) +
44
+ C.reset);
45
+ }
46
+ function hr(char = "─", len = 60) {
47
+ return C.gray + char.repeat(len) + C.reset;
48
+ }
49
+ export function logAccountAssigned(configDir) {
50
+ if (!configDir)
51
+ return;
52
+ const name = path.basename(configDir);
53
+ console.log(`[${new Date().toISOString()}] ${C.bCyan}→ account${C.reset} ${C.bold}${name}${C.reset}`);
54
+ }
55
+ export function logAccountStats(verbose, stats) {
56
+ if (!verbose || stats.length === 0)
57
+ return;
58
+ const now = Date.now();
59
+ const lines = [];
60
+ for (const s of stats) {
61
+ const name = path.basename(s.configDir).padEnd(20);
62
+ const active = s.activeRequests > 0
63
+ ? `${C.bCyan}active:${s.activeRequests}${C.reset}`
64
+ : `${C.dim}active:0${C.reset}`;
65
+ const total = `total:${C.bold}${s.totalRequests}${C.reset}`;
66
+ const ok = `${C.green}ok:${s.totalSuccess}${C.reset}`;
67
+ const err = s.totalErrors > 0
68
+ ? `${C.red}err:${s.totalErrors}${C.reset}`
69
+ : `${C.dim}err:0${C.reset}`;
70
+ const rl = s.totalRateLimits > 0
71
+ ? `${C.yellow}rl:${s.totalRateLimits}${C.reset}`
72
+ : `${C.dim}rl:0${C.reset}`;
73
+ const avg = s.totalRequests > 0
74
+ ? `avg:${Math.round(s.totalLatencyMs / s.totalRequests)}ms`
75
+ : `avg:-`;
76
+ const status = s.isRateLimited
77
+ ? `${C.red}⛔ rate-limited (recovers ${new Date(s.rateLimitUntil).toISOString()})${C.reset}`
78
+ : `${C.green}✓${C.reset}`;
79
+ lines.push(` ${C.bold}${name}${C.reset} ${active} ${total} ${ok} ${err} ${rl} ${C.dim}${avg}${C.reset} ${status}`);
80
+ }
81
+ console.log(`${C.gray}┌─ Account Stats ${"─".repeat(44)}┐${C.reset}`);
82
+ for (const l of lines)
83
+ console.log(l);
84
+ console.log(`${C.gray}└${"─".repeat(60)}┘${C.reset}`);
85
+ }
86
+ export function logTrafficRequest(verbose, model, messages, isStream) {
87
+ if (!verbose)
88
+ return;
89
+ const modeTag = isStream
90
+ ? `${C.bCyan}⚡ stream${C.reset}`
91
+ : `${C.dim}sync${C.reset}`;
92
+ const modelStr = `${C.bMagenta}✦ ${model}${C.reset}`;
93
+ console.log(hr());
94
+ console.log(`${ts()} 📤 ${C.bCyan}${C.bold}REQUEST${C.reset} ${modelStr} ${modeTag}`);
95
+ for (const m of messages) {
96
+ const roleColor = ROLE_STYLE[m.role] ?? C.white;
97
+ const emoji = ROLE_EMOJI[m.role] ?? "💬";
98
+ const label = `${roleColor}${C.bold}[${m.role}]${C.reset}`;
99
+ const charCount = `${C.dim}(${m.content.length} chars)${C.reset}`;
100
+ const preview = truncate(m.content.replace(/\n/g, "↵ "), 280);
101
+ console.log(` ${emoji} ${label} ${charCount}`);
102
+ console.log(` ${C.dim}${preview}${C.reset}`);
103
+ }
104
+ }
105
+ export function logTrafficResponse(verbose, model, text, isStream) {
106
+ if (!verbose)
107
+ return;
108
+ const modeTag = isStream
109
+ ? `${C.bGreen}⚡ stream${C.reset}`
110
+ : `${C.dim}sync${C.reset}`;
111
+ const modelStr = `${C.bMagenta}✦ ${model}${C.reset}`;
112
+ const charCount = `${C.bold}${text.length}${C.reset}${C.dim} chars${C.reset}`;
113
+ const preview = truncate(text.replace(/\n/g, "↵ "), 480);
114
+ console.log(`${ts()} 📥 ${C.bGreen}${C.bold}RESPONSE${C.reset} ${modelStr} ${modeTag} ${charCount}`);
115
+ console.log(` 🤖 ${C.green}${preview}${C.reset}`);
116
+ console.log(hr("─", 60));
117
+ }
118
+ export function appendSessionLine(logPath, method, pathname, remoteAddress, statusCode) {
119
+ const line = `${new Date().toISOString()} ${method} ${pathname} ${remoteAddress} ${statusCode}\n`;
120
+ try {
121
+ const dir = path.dirname(logPath);
122
+ if (!fs.existsSync(dir)) {
123
+ fs.mkdirSync(dir, { recursive: true });
124
+ }
125
+ fs.appendFileSync(logPath, line);
126
+ }
127
+ catch (err) {
128
+ console.error("Failed to write sessions log:", err);
129
+ }
130
+ }
131
+ /**
132
+ * Log an agent execution error to console and sessions log.
133
+ * Returns the error message for use in API responses.
134
+ */
135
+ export function logAgentError(logPath, method, pathname, remoteAddress, exitCode, stderr) {
136
+ const errMsg = `Cursor CLI failed (exit ${exitCode}): ${stderr.trim()}`;
137
+ console.error(`[${new Date().toISOString()}] Agent error: ${errMsg}`);
138
+ try {
139
+ const truncated = stderr.trim().slice(0, 200).replace(/\n/g, " ");
140
+ fs.appendFileSync(logPath, `${new Date().toISOString()} ERROR ${method} ${pathname} ${remoteAddress} agent_exit_${exitCode} ${truncated}\n`);
141
+ }
142
+ catch {
143
+ /* ignore */
144
+ }
145
+ return `The Cursor agent process exited with code ${exitCode}. See server logs for details.`;
146
+ }
147
+ //# sourceMappingURL=request-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-log.js","sourceRoot":"","sources":["../../src/lib/request-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { BridgeConfig } from "./config.js";
2
+ /**
3
+ * Resolve the requested model (already normalized) to the final model string,
4
+ * applying strictModel and lastRequestedModelRef semantics.
5
+ */
6
+ export declare function resolveModel(requested: string | undefined, lastRequestedModelRef: {
7
+ current?: string;
8
+ }, config: BridgeConfig): string;