@kaitranntt/ccs 7.54.0-dev.1 → 7.54.0-dev.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 (55) hide show
  1. package/README.md +1 -0
  2. package/dist/cursor/cursor-anthropic-response.d.ts +6 -0
  3. package/dist/cursor/cursor-anthropic-response.d.ts.map +1 -0
  4. package/dist/cursor/cursor-anthropic-response.js +190 -0
  5. package/dist/cursor/cursor-anthropic-response.js.map +1 -0
  6. package/dist/cursor/cursor-anthropic-translator.d.ts +11 -0
  7. package/dist/cursor/cursor-anthropic-translator.d.ts.map +1 -0
  8. package/dist/cursor/cursor-anthropic-translator.js +167 -0
  9. package/dist/cursor/cursor-anthropic-translator.js.map +1 -0
  10. package/dist/cursor/cursor-anthropic-types.d.ts +46 -0
  11. package/dist/cursor/cursor-anthropic-types.d.ts.map +1 -0
  12. package/dist/cursor/cursor-anthropic-types.js +3 -0
  13. package/dist/cursor/cursor-anthropic-types.js.map +1 -0
  14. package/dist/cursor/cursor-daemon-entry.d.ts.map +1 -1
  15. package/dist/cursor/cursor-daemon-entry.js +53 -24
  16. package/dist/cursor/cursor-daemon-entry.js.map +1 -1
  17. package/dist/cursor/cursor-models.d.ts.map +1 -1
  18. package/dist/cursor/cursor-models.js +36 -2
  19. package/dist/cursor/cursor-models.js.map +1 -1
  20. package/dist/glmt/sse-parser.d.ts +2 -0
  21. package/dist/glmt/sse-parser.d.ts.map +1 -1
  22. package/dist/glmt/sse-parser.js +4 -0
  23. package/dist/glmt/sse-parser.js.map +1 -1
  24. package/dist/shared/provider-preset-catalog.d.ts +1 -1
  25. package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
  26. package/dist/shared/provider-preset-catalog.js +15 -0
  27. package/dist/shared/provider-preset-catalog.js.map +1 -1
  28. package/dist/ui/assets/{accounts-CZEg1_PX.js → accounts-CrNRfOOP.js} +1 -1
  29. package/dist/ui/assets/{alert-dialog-DhwS38kc.js → alert-dialog-0GYXcDLu.js} +1 -1
  30. package/dist/ui/assets/{api-sWNND4wP.js → api-Du9rjWhx.js} +1 -1
  31. package/dist/ui/assets/{auth-section-nJIpOcnm.js → auth-section-DMcsqZyo.js} +1 -1
  32. package/dist/ui/assets/{backups-section-D3A6hmrU.js → backups-section-Bu4mUdGV.js} +1 -1
  33. package/dist/ui/assets/{checkbox-CZrxD1iS.js → checkbox-DiyJL_k4.js} +1 -1
  34. package/dist/ui/assets/{claude-extension-BjInaILv.js → claude-extension-CUlLIos9.js} +1 -1
  35. package/dist/ui/assets/{cliproxy-BGiSCGkl.js → cliproxy-DS95Joc9.js} +1 -1
  36. package/dist/ui/assets/{cliproxy-control-panel-CKO2Sn9B.js → cliproxy-control-panel-BNUMUGIt.js} +1 -1
  37. package/dist/ui/assets/{confirm-dialog-DTKxwrat.js → confirm-dialog-DTWvVQlx.js} +1 -1
  38. package/dist/ui/assets/{copilot-CuRngdBg.js → copilot-p2K9Y5LR.js} +1 -1
  39. package/dist/ui/assets/{cursor-Dxo0uIiU.js → cursor-5SbcR5sW.js} +1 -1
  40. package/dist/ui/assets/{droid-Cl8QsJJL.js → droid-DxdiLHHD.js} +1 -1
  41. package/dist/ui/assets/{globalenv-section-C3dxxoD9.js → globalenv-section-B9l_4XUg.js} +1 -1
  42. package/dist/ui/assets/{health-BUifaDU7.js → health-DDs2IlMm.js} +1 -1
  43. package/dist/ui/assets/{index-CYo-E5rU.js → index-Cy76XBS9.js} +1 -1
  44. package/dist/ui/assets/{index-xayyyR26.js → index-D3yHEBlf.js} +1 -1
  45. package/dist/ui/assets/{index-Cw9Urr0S.js → index-JgHDFSHt.js} +3 -3
  46. package/dist/ui/assets/{index-CPdceT1C.js → index-X7b7NDPo.js} +1 -1
  47. package/dist/ui/assets/{index-BOsbrhaa.js → index-awSrtRcI.js} +1 -1
  48. package/dist/ui/assets/{proxy-status-widget-D94htBPb.js → proxy-status-widget-DEkHz7X-.js} +1 -1
  49. package/dist/ui/assets/{separator-3fBbTn-V.js → separator-BFr5KvfF.js} +1 -1
  50. package/dist/ui/assets/{shared-q_FNNbjD.js → shared-BwP9MOQi.js} +1 -1
  51. package/dist/ui/assets/{switch-5N8qBdBr.js → switch-w7IoOY5x.js} +1 -1
  52. package/dist/ui/assets/{updates-CubQ54J0.js → updates--SN_PZnJ.js} +1 -1
  53. package/dist/ui/icons/novita.svg +9 -0
  54. package/dist/ui/index.html +1 -1
  55. package/package.json +1 -1
package/README.md CHANGED
@@ -110,6 +110,7 @@ The dashboard provides visual management for all account types:
110
110
  | **Azure Foundry** | API Key | `ccs foundry` | Claude via Microsoft Azure |
111
111
  | **Minimax** | API Key | `ccs mm` | M2 series, 1M context |
112
112
  | **DeepSeek** | API Key | `ccs deepseek` | V3.2 and R1 reasoning |
113
+ | **Novita AI** | API Key | `ccs api create --preset novita` | Anthropic-compatible Novita endpoint for Claude Code |
113
114
  | **Qwen (OAuth)** | OAuth | `ccs qwen` | Qwen Code via CLIProxy |
114
115
  | **Qwen API** | API Key | `ccs api create --preset qwen` | DashScope Anthropic-compatible API |
115
116
  | **Alibaba Coding Plan** | API Key | `ccs api create --preset alibaba-coding-plan` | Model Studio Coding Plan endpoint |
@@ -0,0 +1,6 @@
1
+ /// <reference types="node" />
2
+ type ResponseHeaders = Headers | Record<string, string> | Array<[string, string]>;
3
+ export declare function createAnthropicErrorResponse(status: number, type: string, message: string, headers?: ResponseHeaders): Response;
4
+ export declare function createAnthropicProxyResponse(response: Response): Promise<Response>;
5
+ export {};
6
+ //# sourceMappingURL=cursor-anthropic-response.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-response.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-response.ts"],"names":[],"mappings":";AAOA,KAAK,eAAe,GAAG,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAoClF,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,eAAe,GACxB,QAAQ,CASV;AAmLD,wBAAsB,4BAA4B,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAYxF"}
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAnthropicProxyResponse = exports.createAnthropicErrorResponse = void 0;
4
+ const delta_accumulator_1 = require("../glmt/delta-accumulator");
5
+ const glmt_transformer_1 = require("../glmt/glmt-transformer");
6
+ const sse_parser_1 = require("../glmt/sse-parser");
7
+ const JSON_TRANSLATION_ERROR_MESSAGE = 'Failed to translate Cursor JSON response';
8
+ const STREAM_TRANSLATION_ERROR_MESSAGE = 'Failed to translate Cursor SSE response';
9
+ function createAnthropicErrorPayload(type, message) {
10
+ return {
11
+ type: 'error',
12
+ error: {
13
+ type,
14
+ message,
15
+ },
16
+ };
17
+ }
18
+ function formatErrorForLog(error) {
19
+ if (error instanceof Error) {
20
+ return error.message;
21
+ }
22
+ try {
23
+ return JSON.stringify(error);
24
+ }
25
+ catch {
26
+ return String(error);
27
+ }
28
+ }
29
+ function logTranslationError(context, error) {
30
+ console.error(`[cursor-anthropic-response] ${context}: ${formatErrorForLog(error)}`);
31
+ }
32
+ function createAnthropicErrorResponse(status, type, message, headers) {
33
+ const responseHeaders = new Headers(headers);
34
+ responseHeaders.set('Content-Type', 'application/json');
35
+ responseHeaders.delete('Content-Length');
36
+ return new Response(JSON.stringify(createAnthropicErrorPayload(type, message)), {
37
+ status,
38
+ headers: responseHeaders,
39
+ });
40
+ }
41
+ exports.createAnthropicErrorResponse = createAnthropicErrorResponse;
42
+ function formatSseEvent(event, data) {
43
+ return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
44
+ }
45
+ function hasTranslatableChoices(value) {
46
+ if (typeof value !== 'object' || value === null) {
47
+ return false;
48
+ }
49
+ const { choices } = value;
50
+ if (!Array.isArray(choices) || choices.length === 0) {
51
+ return false;
52
+ }
53
+ const firstChoice = choices[0];
54
+ if (typeof firstChoice !== 'object' || firstChoice === null) {
55
+ return false;
56
+ }
57
+ const message = firstChoice.message;
58
+ return typeof message === 'object' && message !== null;
59
+ }
60
+ function isSyntheticTransformationFallback(value) {
61
+ return (typeof value === 'object' &&
62
+ value !== null &&
63
+ typeof value.id === 'string' &&
64
+ value.id.startsWith('msg_error_'));
65
+ }
66
+ async function createAnthropicErrorProxyResponse(response) {
67
+ const headers = new Headers(response.headers);
68
+ headers.delete('Content-Type');
69
+ headers.delete('Content-Length');
70
+ let type = response.status === 401
71
+ ? 'authentication_error'
72
+ : response.status === 429
73
+ ? 'rate_limit_error'
74
+ : response.status >= 400 && response.status < 500
75
+ ? 'invalid_request_error'
76
+ : 'api_error';
77
+ let message = `Cursor request failed with status ${response.status}`;
78
+ try {
79
+ const contentType = (response.headers.get('content-type') || '').toLowerCase();
80
+ if (contentType.includes('application/json')) {
81
+ const payload = (await response.json());
82
+ if (typeof payload?.error?.type === 'string' && payload.error.type.trim().length > 0) {
83
+ type = payload.error.type;
84
+ }
85
+ if (typeof payload?.error?.message === 'string' && payload.error.message.trim().length > 0) {
86
+ message = payload.error.message;
87
+ }
88
+ else if (typeof payload?.message === 'string' && payload.message.trim().length > 0) {
89
+ message = payload.message;
90
+ }
91
+ }
92
+ else {
93
+ const text = (await response.text()).trim();
94
+ if (text.length > 0) {
95
+ message = text;
96
+ }
97
+ }
98
+ }
99
+ catch (error) {
100
+ logTranslationError('Failed to parse Cursor error response', error);
101
+ }
102
+ return createAnthropicErrorResponse(response.status, type, message, headers);
103
+ }
104
+ async function createAnthropicJsonResponse(response) {
105
+ try {
106
+ const openAiResponse = await response.json();
107
+ if (!hasTranslatableChoices(openAiResponse)) {
108
+ return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
109
+ }
110
+ const anthropicResponse = new glmt_transformer_1.GlmtTransformer().transformResponse(openAiResponse);
111
+ if (isSyntheticTransformationFallback(anthropicResponse)) {
112
+ logTranslationError('Cursor JSON translation produced synthetic fallback response', anthropicResponse);
113
+ return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
114
+ }
115
+ return new Response(JSON.stringify(anthropicResponse), {
116
+ status: response.status,
117
+ headers: { 'Content-Type': 'application/json' },
118
+ });
119
+ }
120
+ catch (error) {
121
+ logTranslationError('Cursor JSON translation failed', error);
122
+ return createAnthropicErrorResponse(502, 'api_error', JSON_TRANSLATION_ERROR_MESSAGE);
123
+ }
124
+ }
125
+ function createAnthropicStreamingResponse(response) {
126
+ const body = response.body;
127
+ if (!body) {
128
+ return createAnthropicErrorResponse(502, 'api_error', 'Cursor stream ended before a response body was available');
129
+ }
130
+ const parser = new sse_parser_1.SSEParser({ throwOnMalformedJson: true });
131
+ const transformer = new glmt_transformer_1.GlmtTransformer();
132
+ const accumulator = new delta_accumulator_1.DeltaAccumulator({});
133
+ const encoder = new TextEncoder();
134
+ const readable = new ReadableStream({
135
+ async start(controller) {
136
+ const reader = body.getReader();
137
+ try {
138
+ while (true) {
139
+ const { done, value } = await reader.read();
140
+ if (done) {
141
+ break;
142
+ }
143
+ if (!value) {
144
+ continue;
145
+ }
146
+ const events = parser.parse(Buffer.from(value));
147
+ events.forEach((event) => {
148
+ const anthropicEvents = transformer.transformDelta(event, accumulator);
149
+ anthropicEvents.forEach((anthropicEvent) => {
150
+ controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
151
+ });
152
+ });
153
+ }
154
+ if (!accumulator.isFinalized() && accumulator.isMessageStarted()) {
155
+ transformer.finalizeDelta(accumulator).forEach((anthropicEvent) => {
156
+ controller.enqueue(encoder.encode(formatSseEvent(anthropicEvent.event, anthropicEvent.data)));
157
+ });
158
+ }
159
+ }
160
+ catch (error) {
161
+ logTranslationError('Cursor SSE translation failed', error);
162
+ controller.enqueue(encoder.encode(formatSseEvent('error', createAnthropicErrorPayload('api_error', STREAM_TRANSLATION_ERROR_MESSAGE))));
163
+ }
164
+ finally {
165
+ reader.releaseLock();
166
+ controller.close();
167
+ }
168
+ },
169
+ });
170
+ return new Response(readable, {
171
+ status: response.status,
172
+ headers: {
173
+ 'Content-Type': 'text/event-stream',
174
+ 'Cache-Control': 'no-cache',
175
+ Connection: 'keep-alive',
176
+ },
177
+ });
178
+ }
179
+ async function createAnthropicProxyResponse(response) {
180
+ if (!response.ok) {
181
+ return createAnthropicErrorProxyResponse(response);
182
+ }
183
+ const contentType = (response.headers.get('content-type') || '').toLowerCase();
184
+ const isEventStream = contentType === 'text/event-stream' || contentType.startsWith('text/event-stream;');
185
+ return isEventStream
186
+ ? createAnthropicStreamingResponse(response)
187
+ : createAnthropicJsonResponse(response);
188
+ }
189
+ exports.createAnthropicProxyResponse = createAnthropicProxyResponse;
190
+ //# sourceMappingURL=cursor-anthropic-response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-response.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { CursorTool } from './cursor-protobuf-schema';
2
+ import type { CursorOpenAIMessage } from './cursor-anthropic-types';
3
+ export interface TranslatedAnthropicRequest {
4
+ model?: string;
5
+ stream: boolean;
6
+ reasoning_effort?: string;
7
+ tools?: CursorTool[];
8
+ messages: CursorOpenAIMessage[];
9
+ }
10
+ export declare function translateAnthropicRequest(raw: unknown): TranslatedAnthropicRequest;
11
+ //# sourceMappingURL=cursor-anthropic-translator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-translator.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-translator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC;AA0ED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,OAAO,GAAG,0BAA0B,CAgIlF"}
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.translateAnthropicRequest = void 0;
4
+ const TOOL_RESULT_SERIALIZATION_FALLBACK = '[unserializable content]';
5
+ const TOOL_USE_ARGUMENTS_FALLBACK = '{}';
6
+ function assertObject(value, label) {
7
+ if (typeof value !== 'object' || value === null) {
8
+ throw new Error(`${label} must be an object`);
9
+ }
10
+ return value;
11
+ }
12
+ function safeJsonStringify(value, fallback) {
13
+ try {
14
+ const serialized = JSON.stringify(value);
15
+ return typeof serialized === 'string' ? serialized : fallback;
16
+ }
17
+ catch {
18
+ return fallback;
19
+ }
20
+ }
21
+ function createFallbackToolId(messageIndex, blockIndex) {
22
+ return `toolu_ccs_fallback_${messageIndex}_${blockIndex}`;
23
+ }
24
+ function flattenTextContent(content, label) {
25
+ if (typeof content === 'string') {
26
+ return content;
27
+ }
28
+ if (!Array.isArray(content)) {
29
+ throw new Error(`${label} must be a string or content block array`);
30
+ }
31
+ return content
32
+ .map((block, index) => {
33
+ const parsed = assertObject(block, `${label}[${index}]`);
34
+ if (parsed.type !== 'text') {
35
+ throw new Error(`${label}[${index}].type "${String(parsed.type)}" is not supported`);
36
+ }
37
+ return typeof parsed.text === 'string' ? parsed.text : '';
38
+ })
39
+ .join('\n');
40
+ }
41
+ function toToolResultContent(content, label) {
42
+ if (content === undefined) {
43
+ return '';
44
+ }
45
+ if (typeof content === 'string') {
46
+ return content;
47
+ }
48
+ if (Array.isArray(content)) {
49
+ return flattenTextContent(content, label);
50
+ }
51
+ return safeJsonStringify(content, TOOL_RESULT_SERIALIZATION_FALLBACK);
52
+ }
53
+ function mapThinkingToReasoningEffort(thinking) {
54
+ if (!thinking) {
55
+ return undefined;
56
+ }
57
+ if (thinking.type === 'disabled') {
58
+ return undefined;
59
+ }
60
+ if (thinking.type !== 'enabled') {
61
+ throw new Error('thinking.type must be "enabled" or "disabled"');
62
+ }
63
+ return typeof thinking.budget_tokens === 'number' && thinking.budget_tokens >= 8192
64
+ ? 'high'
65
+ : 'medium';
66
+ }
67
+ function translateAnthropicRequest(raw) {
68
+ const request = assertObject(raw, 'request');
69
+ const translatedMessages = [];
70
+ if (request.system !== undefined) {
71
+ translatedMessages.push({
72
+ role: 'system',
73
+ content: flattenTextContent(request.system, 'system'),
74
+ });
75
+ }
76
+ if (!Array.isArray(request.messages)) {
77
+ throw new Error('messages must be an array');
78
+ }
79
+ request.messages.forEach((message, messageIndex) => {
80
+ const role = message.role;
81
+ if (role !== 'user' && role !== 'assistant') {
82
+ throw new Error(`messages[${messageIndex}].role must be "user" or "assistant"`);
83
+ }
84
+ const content = message.content;
85
+ if (typeof content === 'string') {
86
+ translatedMessages.push({ role, content });
87
+ return;
88
+ }
89
+ if (!Array.isArray(content)) {
90
+ throw new Error(`messages[${messageIndex}].content must be a string or array`);
91
+ }
92
+ const textParts = [];
93
+ const toolCalls = [];
94
+ let sawToolResult = false;
95
+ content.forEach((block, blockIndex) => {
96
+ const parsed = assertObject(block, `messages[${messageIndex}].content[${blockIndex}]`);
97
+ if (parsed.type === 'text') {
98
+ textParts.push(typeof parsed.text === 'string' ? parsed.text : '');
99
+ return;
100
+ }
101
+ if (parsed.type === 'tool_use') {
102
+ if (role !== 'assistant') {
103
+ throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_use requires assistant role`);
104
+ }
105
+ toolCalls.push({
106
+ id: typeof parsed.id === 'string' && parsed.id.length > 0
107
+ ? parsed.id
108
+ : createFallbackToolId(messageIndex, blockIndex),
109
+ type: 'function',
110
+ function: {
111
+ name: typeof parsed.name === 'string' ? parsed.name : 'tool',
112
+ arguments: safeJsonStringify(parsed.input ?? {}, TOOL_USE_ARGUMENTS_FALLBACK),
113
+ },
114
+ });
115
+ return;
116
+ }
117
+ if (parsed.type === 'tool_result') {
118
+ if (role !== 'user') {
119
+ throw new Error(`messages[${messageIndex}].content[${blockIndex}] tool_result requires user role`);
120
+ }
121
+ if (typeof parsed.tool_use_id !== 'string' || parsed.tool_use_id.trim().length === 0) {
122
+ throw new Error(`messages[${messageIndex}].content[${blockIndex}].tool_use_id must be a non-empty string`);
123
+ }
124
+ sawToolResult = true;
125
+ if (textParts.length > 0) {
126
+ translatedMessages.push({
127
+ role,
128
+ content: textParts.join('\n'),
129
+ });
130
+ textParts.length = 0;
131
+ }
132
+ translatedMessages.push({
133
+ role: 'tool',
134
+ tool_call_id: parsed.tool_use_id,
135
+ content: toToolResultContent(parsed.content, `messages[${messageIndex}].content[${blockIndex}].content`),
136
+ });
137
+ return;
138
+ }
139
+ throw new Error(`messages[${messageIndex}].content[${blockIndex}].type "${String(parsed.type)}" is not supported`);
140
+ });
141
+ if (role === 'assistant') {
142
+ translatedMessages.push({
143
+ role,
144
+ content: textParts.join('\n'),
145
+ tool_calls: toolCalls.length > 0 ? toolCalls : undefined,
146
+ });
147
+ return;
148
+ }
149
+ if (textParts.length > 0 || !sawToolResult) {
150
+ translatedMessages.push({
151
+ role,
152
+ content: textParts.join('\n'),
153
+ });
154
+ }
155
+ });
156
+ return {
157
+ model: typeof request.model === 'string' && request.model.trim().length > 0
158
+ ? request.model
159
+ : undefined,
160
+ stream: request.stream === true,
161
+ reasoning_effort: mapThinkingToReasoningEffort(request.thinking),
162
+ tools: Array.isArray(request.tools) ? request.tools : undefined,
163
+ messages: translatedMessages,
164
+ };
165
+ }
166
+ exports.translateAnthropicRequest = translateAnthropicRequest;
167
+ //# sourceMappingURL=cursor-anthropic-translator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-translator.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-translator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { CursorTool } from './cursor-protobuf-schema';
2
+ export interface CursorOpenAIMessage {
3
+ role: string;
4
+ content: string;
5
+ name?: string;
6
+ tool_call_id?: string;
7
+ tool_calls?: Array<{
8
+ id: string;
9
+ type: string;
10
+ function: {
11
+ name: string;
12
+ arguments: string;
13
+ };
14
+ }>;
15
+ }
16
+ export interface AnthropicTextBlock {
17
+ type: 'text';
18
+ text?: string;
19
+ }
20
+ export interface AnthropicToolUseBlock {
21
+ type: 'tool_use';
22
+ id?: string;
23
+ name?: string;
24
+ input?: Record<string, unknown>;
25
+ }
26
+ export interface AnthropicToolResultBlock {
27
+ type: 'tool_result';
28
+ tool_use_id?: string;
29
+ content?: unknown;
30
+ }
31
+ export type AnthropicContentBlock = AnthropicTextBlock | AnthropicToolUseBlock | AnthropicToolResultBlock;
32
+ export interface CursorAnthropicRequest {
33
+ model?: string;
34
+ messages?: Array<{
35
+ role?: string;
36
+ content?: string | AnthropicContentBlock[];
37
+ }>;
38
+ system?: string | AnthropicTextBlock[];
39
+ stream?: boolean;
40
+ tools?: CursorTool[];
41
+ thinking?: {
42
+ type?: string;
43
+ budget_tokens?: number;
44
+ };
45
+ }
46
+ //# sourceMappingURL=cursor-anthropic-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-types.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;KAC/C,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,qBAAqB,GACrB,wBAAwB,CAAC;AAE7B,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,qBAAqB,EAAE,CAAA;KAAE,CAAC,CAAC;IAChF,MAAM,CAAC,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;CACH"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=cursor-anthropic-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-anthropic-types.js","sourceRoot":"","sources":["../../src/cursor/cursor-anthropic-types.ts"],"names":[],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"cursor-daemon-entry.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-daemon-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAO7B,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AA4KD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAkIlF"}
1
+ {"version":3,"file":"cursor-daemon-entry.d.ts","sourceRoot":"","sources":["../../src/cursor/cursor-daemon-entry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAY7B,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AA4KD,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC,MAAM,CAoKlF"}
@@ -32,6 +32,8 @@ exports.startCursorDaemonServer = void 0;
32
32
  const http = __importStar(require("http"));
33
33
  const stream_1 = require("stream");
34
34
  const cursor_executor_1 = require("./cursor-executor");
35
+ const cursor_anthropic_response_1 = require("./cursor-anthropic-response");
36
+ const cursor_anthropic_translator_1 = require("./cursor-anthropic-translator");
35
37
  const cursor_auth_1 = require("./cursor-auth");
36
38
  const cursor_models_1 = require("./cursor-models");
37
39
  const MAX_BODY_SIZE = 10 * 1024 * 1024; // 10MB
@@ -155,9 +157,11 @@ function parseArgs(argv) {
155
157
  function startCursorDaemonServer(options) {
156
158
  const executor = new cursor_executor_1.CursorExecutor();
157
159
  const server = http.createServer(async (req, res) => {
160
+ const method = req.method || 'GET';
161
+ const requestUrl = req.url || '/';
162
+ const isOpenAiRoute = method === 'POST' && requestUrl === '/v1/chat/completions';
163
+ const isAnthropicRoute = method === 'POST' && requestUrl === '/v1/messages';
158
164
  try {
159
- const method = req.method || 'GET';
160
- const requestUrl = req.url || '/';
161
165
  if (method === 'GET' && requestUrl === '/health') {
162
166
  writeJson(res, 200, { ok: true, service: 'cursor-daemon' });
163
167
  return;
@@ -182,33 +186,49 @@ function startCursorDaemonServer(options) {
182
186
  writeJson(res, 200, { object: 'list', data });
183
187
  return;
184
188
  }
185
- if (method !== 'POST' || requestUrl !== '/v1/chat/completions') {
189
+ if (!isOpenAiRoute && !isAnthropicRoute) {
186
190
  writeJson(res, 404, { error: 'Not found' });
187
191
  return;
188
192
  }
189
- const parsedBody = (await readJsonBody(req));
190
- const messages = normalizeMessages(parsedBody.messages);
193
+ const rawBody = await readJsonBody(req);
194
+ const anthropicBody = isAnthropicRoute ? (0, cursor_anthropic_translator_1.translateAnthropicRequest)(rawBody) : undefined;
195
+ const parsedBody = anthropicBody ?? (rawBody || {});
196
+ const messages = anthropicBody
197
+ ? anthropicBody.messages
198
+ : normalizeMessages(parsedBody.messages);
191
199
  const requestedModel = typeof parsedBody.model === 'string' && parsedBody.model.trim().length > 0
192
200
  ? parsedBody.model.trim()
193
201
  : undefined;
194
202
  const stream = parsedBody.stream === true;
195
203
  const authStatus = (0, cursor_auth_1.checkAuthStatus)();
196
204
  if (!authStatus.authenticated || !authStatus.credentials) {
197
- writeJson(res, 401, {
198
- error: {
199
- type: 'authentication_error',
200
- message: 'Cursor credentials not found. Run `ccs cursor auth` first.',
201
- },
202
- });
205
+ const message = 'Cursor credentials not found. Run `ccs cursor auth` first.';
206
+ if (isAnthropicRoute) {
207
+ await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(401, 'authentication_error', message), res);
208
+ }
209
+ else {
210
+ writeJson(res, 401, {
211
+ error: {
212
+ type: 'authentication_error',
213
+ message,
214
+ },
215
+ });
216
+ }
203
217
  return;
204
218
  }
205
219
  if (authStatus.expired) {
206
- writeJson(res, 401, {
207
- error: {
208
- type: 'authentication_error',
209
- message: 'Cursor credentials expired. Run `ccs cursor auth` again.',
210
- },
211
- });
220
+ const message = 'Cursor credentials expired. Run `ccs cursor auth` again.';
221
+ if (isAnthropicRoute) {
222
+ await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(401, 'authentication_error', message), res);
223
+ }
224
+ else {
225
+ writeJson(res, 401, {
226
+ error: {
227
+ type: 'authentication_error',
228
+ message,
229
+ },
230
+ });
231
+ }
212
232
  return;
213
233
  }
214
234
  const daemonCredentials = {
@@ -247,17 +267,26 @@ function startCursorDaemonServer(options) {
247
267
  : undefined,
248
268
  },
249
269
  });
250
- await pipeWebResponseToNode(result.response, res);
270
+ const outgoingResponse = isAnthropicRoute
271
+ ? await (0, cursor_anthropic_response_1.createAnthropicProxyResponse)(result.response)
272
+ : result.response;
273
+ await pipeWebResponseToNode(outgoingResponse, res);
251
274
  }
252
275
  catch (error) {
253
276
  const message = error instanceof Error ? error.message : 'Unknown error';
254
277
  const isPayloadTooLarge = message.includes('Request body too large');
255
- writeJson(res, isPayloadTooLarge ? 413 : 400, {
256
- error: {
257
- type: 'invalid_request_error',
258
- message,
259
- },
260
- });
278
+ const status = isPayloadTooLarge ? 413 : 400;
279
+ if (isAnthropicRoute) {
280
+ await pipeWebResponseToNode((0, cursor_anthropic_response_1.createAnthropicErrorResponse)(status, 'invalid_request_error', message), res);
281
+ }
282
+ else {
283
+ writeJson(res, status, {
284
+ error: {
285
+ type: 'invalid_request_error',
286
+ message,
287
+ },
288
+ });
289
+ }
261
290
  }
262
291
  });
263
292
  server.listen(options.port, '127.0.0.1');