opencode-cursor-proxy 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/README.zh-CN.md +136 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/api/agent-service.d.ts +136 -0
  8. package/dist/lib/api/agent-service.js +938 -0
  9. package/dist/lib/api/agent-service.js.map +1 -0
  10. package/dist/lib/api/ai-service.d.ts +26 -0
  11. package/dist/lib/api/ai-service.js +38 -0
  12. package/dist/lib/api/ai-service.js.map +1 -0
  13. package/dist/lib/api/cursor-client.d.ts +119 -0
  14. package/dist/lib/api/cursor-client.js +511 -0
  15. package/dist/lib/api/cursor-client.js.map +1 -0
  16. package/dist/lib/api/cursor-models.d.ts +13 -0
  17. package/dist/lib/api/cursor-models.js +34 -0
  18. package/dist/lib/api/cursor-models.js.map +1 -0
  19. package/dist/lib/api/openai-compat.d.ts +10 -0
  20. package/dist/lib/api/openai-compat.js +262 -0
  21. package/dist/lib/api/openai-compat.js.map +1 -0
  22. package/dist/lib/api/proto/agent-messages.d.ts +25 -0
  23. package/dist/lib/api/proto/agent-messages.js +132 -0
  24. package/dist/lib/api/proto/agent-messages.js.map +1 -0
  25. package/dist/lib/api/proto/bidi.d.ts +17 -0
  26. package/dist/lib/api/proto/bidi.js +24 -0
  27. package/dist/lib/api/proto/bidi.js.map +1 -0
  28. package/dist/lib/api/proto/decoding.d.ts +19 -0
  29. package/dist/lib/api/proto/decoding.js +118 -0
  30. package/dist/lib/api/proto/decoding.js.map +1 -0
  31. package/dist/lib/api/proto/encoding.d.ts +64 -0
  32. package/dist/lib/api/proto/encoding.js +180 -0
  33. package/dist/lib/api/proto/encoding.js.map +1 -0
  34. package/dist/lib/api/proto/exec.d.ts +12 -0
  35. package/dist/lib/api/proto/exec.js +383 -0
  36. package/dist/lib/api/proto/exec.js.map +1 -0
  37. package/dist/lib/api/proto/index.d.ts +13 -0
  38. package/dist/lib/api/proto/index.js +10 -0
  39. package/dist/lib/api/proto/index.js.map +1 -0
  40. package/dist/lib/api/proto/interaction.d.ts +15 -0
  41. package/dist/lib/api/proto/interaction.js +99 -0
  42. package/dist/lib/api/proto/interaction.js.map +1 -0
  43. package/dist/lib/api/proto/kv.d.ts +52 -0
  44. package/dist/lib/api/proto/kv.js +156 -0
  45. package/dist/lib/api/proto/kv.js.map +1 -0
  46. package/dist/lib/api/proto/tool-calls.d.ts +9 -0
  47. package/dist/lib/api/proto/tool-calls.js +144 -0
  48. package/dist/lib/api/proto/tool-calls.js.map +1 -0
  49. package/dist/lib/api/proto/types.d.ts +201 -0
  50. package/dist/lib/api/proto/types.js +10 -0
  51. package/dist/lib/api/proto/types.js.map +1 -0
  52. package/dist/lib/auth/helpers.d.ts +40 -0
  53. package/dist/lib/auth/helpers.js +103 -0
  54. package/dist/lib/auth/helpers.js.map +1 -0
  55. package/dist/lib/auth/index.d.ts +7 -0
  56. package/dist/lib/auth/index.js +10 -0
  57. package/dist/lib/auth/index.js.map +1 -0
  58. package/dist/lib/auth/login.d.ts +55 -0
  59. package/dist/lib/auth/login.js +184 -0
  60. package/dist/lib/auth/login.js.map +1 -0
  61. package/dist/lib/config.d.ts +153 -0
  62. package/dist/lib/config.js +182 -0
  63. package/dist/lib/config.js.map +1 -0
  64. package/dist/lib/openai-compat/handler.d.ts +40 -0
  65. package/dist/lib/openai-compat/handler.js +808 -0
  66. package/dist/lib/openai-compat/handler.js.map +1 -0
  67. package/dist/lib/openai-compat/index.d.ts +9 -0
  68. package/dist/lib/openai-compat/index.js +13 -0
  69. package/dist/lib/openai-compat/index.js.map +1 -0
  70. package/dist/lib/openai-compat/types.d.ts +127 -0
  71. package/dist/lib/openai-compat/types.js +6 -0
  72. package/dist/lib/openai-compat/types.js.map +1 -0
  73. package/dist/lib/openai-compat/utils.d.ts +143 -0
  74. package/dist/lib/openai-compat/utils.js +348 -0
  75. package/dist/lib/openai-compat/utils.js.map +1 -0
  76. package/dist/lib/session-reuse.d.ts +88 -0
  77. package/dist/lib/session-reuse.js +198 -0
  78. package/dist/lib/session-reuse.js.map +1 -0
  79. package/dist/lib/storage.d.ts +55 -0
  80. package/dist/lib/storage.js +159 -0
  81. package/dist/lib/storage.js.map +1 -0
  82. package/dist/lib/utils/cache.d.ts +131 -0
  83. package/dist/lib/utils/cache.js +297 -0
  84. package/dist/lib/utils/cache.js.map +1 -0
  85. package/dist/lib/utils/fetch.d.ts +84 -0
  86. package/dist/lib/utils/fetch.js +261 -0
  87. package/dist/lib/utils/fetch.js.map +1 -0
  88. package/dist/lib/utils/index.d.ts +13 -0
  89. package/dist/lib/utils/index.js +22 -0
  90. package/dist/lib/utils/index.js.map +1 -0
  91. package/dist/lib/utils/jwt.d.ts +40 -0
  92. package/dist/lib/utils/jwt.js +102 -0
  93. package/dist/lib/utils/jwt.js.map +1 -0
  94. package/dist/lib/utils/logger.d.ts +107 -0
  95. package/dist/lib/utils/logger.js +227 -0
  96. package/dist/lib/utils/logger.js.map +1 -0
  97. package/dist/lib/utils/model-resolver.d.ts +49 -0
  98. package/dist/lib/utils/model-resolver.js +503 -0
  99. package/dist/lib/utils/model-resolver.js.map +1 -0
  100. package/dist/lib/utils/request-pool.d.ts +38 -0
  101. package/dist/lib/utils/request-pool.js +105 -0
  102. package/dist/lib/utils/request-pool.js.map +1 -0
  103. package/dist/lib/utils/request-transformer.d.ts +87 -0
  104. package/dist/lib/utils/request-transformer.js +154 -0
  105. package/dist/lib/utils/request-transformer.js.map +1 -0
  106. package/dist/lib/utils/tokenizer.d.ts +14 -0
  107. package/dist/lib/utils/tokenizer.js +76 -0
  108. package/dist/lib/utils/tokenizer.js.map +1 -0
  109. package/dist/plugin/index.d.ts +8 -0
  110. package/dist/plugin/index.js +9 -0
  111. package/dist/plugin/index.js.map +1 -0
  112. package/dist/plugin/plugin.d.ts +21 -0
  113. package/dist/plugin/plugin.js +309 -0
  114. package/dist/plugin/plugin.js.map +1 -0
  115. package/dist/plugin/types.d.ts +120 -0
  116. package/dist/plugin/types.js +7 -0
  117. package/dist/plugin/types.js.map +1 -0
  118. package/dist/server.d.ts +15 -0
  119. package/dist/server.js +95 -0
  120. package/dist/server.js.map +1 -0
  121. package/package.json +79 -0
@@ -0,0 +1,201 @@
1
+ export declare enum AgentMode {
2
+ UNSPECIFIED = 0,
3
+ AGENT = 1,
4
+ ASK = 2,
5
+ PLAN = 3,
6
+ DEBUG = 4,
7
+ TRIAGE = 5
8
+ }
9
+ export interface OpenAIToolDefinition {
10
+ type: "function";
11
+ function: {
12
+ name: string;
13
+ description?: string;
14
+ parameters?: Record<string, unknown>;
15
+ };
16
+ }
17
+ export interface McpExecRequest {
18
+ id: number;
19
+ execId?: string;
20
+ name: string;
21
+ args: Record<string, unknown>;
22
+ toolCallId: string;
23
+ providerIdentifier: string;
24
+ toolName: string;
25
+ }
26
+ export interface ShellExecRequest {
27
+ type: 'shell';
28
+ id: number;
29
+ execId?: string;
30
+ command: string;
31
+ cwd?: string;
32
+ }
33
+ export interface LsExecRequest {
34
+ type: 'ls';
35
+ id: number;
36
+ execId?: string;
37
+ path: string;
38
+ }
39
+ export interface RequestContextExecRequest {
40
+ type: 'request_context';
41
+ id: number;
42
+ execId?: string;
43
+ }
44
+ export interface ReadExecRequest {
45
+ type: 'read';
46
+ id: number;
47
+ execId?: string;
48
+ path: string;
49
+ }
50
+ export interface GrepExecRequest {
51
+ type: 'grep';
52
+ id: number;
53
+ execId?: string;
54
+ pattern: string;
55
+ path?: string;
56
+ glob?: string;
57
+ }
58
+ export interface WriteExecRequest {
59
+ type: 'write';
60
+ id: number;
61
+ execId?: string;
62
+ path: string;
63
+ fileText: string;
64
+ toolCallId?: string;
65
+ returnFileContentAfterWrite?: boolean;
66
+ fileBytes?: Uint8Array;
67
+ }
68
+ export type ExecRequest = (McpExecRequest & {
69
+ type: 'mcp';
70
+ }) | ShellExecRequest | LsExecRequest | RequestContextExecRequest | ReadExecRequest | GrepExecRequest | WriteExecRequest;
71
+ export interface KvServerMessage {
72
+ id: number;
73
+ messageType: 'get_blob_args' | 'set_blob_args' | 'unknown';
74
+ blobId?: Uint8Array;
75
+ blobData?: Uint8Array;
76
+ }
77
+ export interface ToolCallInfo {
78
+ callId: string;
79
+ modelCallId?: string;
80
+ toolType: string;
81
+ name: string;
82
+ arguments: string;
83
+ }
84
+ export interface ParsedToolCall {
85
+ toolType: string;
86
+ name: string;
87
+ arguments: Record<string, unknown>;
88
+ }
89
+ export interface ParsedToolCallStarted {
90
+ callId: string;
91
+ modelCallId: string;
92
+ toolCall: ParsedToolCall | null;
93
+ }
94
+ export interface ParsedPartialToolCall {
95
+ callId: string;
96
+ modelCallId: string;
97
+ argsTextDelta: string;
98
+ toolCall: ParsedToolCall | null;
99
+ }
100
+ export interface AgentStreamChunk {
101
+ type: "text" | "thinking" | "token" | "checkpoint" | "done" | "error" | "tool_call_started" | "tool_call_completed" | "partial_tool_call" | "exec_request" | "heartbeat" | "exec_server_abort" | "interaction_query" | "kv_blob_assistant";
102
+ content?: string;
103
+ error?: string;
104
+ toolCall?: ToolCallInfo;
105
+ partialArgs?: string;
106
+ execRequest?: ExecRequest;
107
+ queryId?: number;
108
+ queryType?: string;
109
+ blobContent?: string;
110
+ }
111
+ export interface ChatTimingMetrics {
112
+ requestStart: number;
113
+ messageBuildMs?: number;
114
+ sseConnectionMs?: number;
115
+ firstBidiAppendMs?: number;
116
+ firstChunkMs?: number;
117
+ firstTextMs?: number;
118
+ firstToolCallMs?: number;
119
+ turnEndedMs?: number;
120
+ totalMs?: number;
121
+ chunkCount: number;
122
+ textChunks: number;
123
+ toolCalls: number;
124
+ execRequests: number;
125
+ kvMessages: number;
126
+ heartbeats: number;
127
+ }
128
+ export interface AgentServiceOptions {
129
+ baseUrl?: string;
130
+ privacyMode?: boolean;
131
+ workspacePath?: string;
132
+ }
133
+ export interface AgentChatRequest {
134
+ message: string;
135
+ model?: string;
136
+ mode?: AgentMode;
137
+ conversationId?: string;
138
+ tools?: OpenAIToolDefinition[];
139
+ }
140
+ export interface McpResult {
141
+ success?: {
142
+ content: string;
143
+ isError?: boolean;
144
+ };
145
+ error?: string;
146
+ }
147
+ export interface ShellOutcome {
148
+ command: string;
149
+ cwd: string;
150
+ stdout: string;
151
+ stderr: string;
152
+ exitCode: number;
153
+ executionTimeMs?: number;
154
+ }
155
+ export interface WriteResult {
156
+ success?: {
157
+ path: string;
158
+ linesCreated: number;
159
+ fileSize: number;
160
+ fileContentAfterWrite?: string;
161
+ };
162
+ error?: {
163
+ path: string;
164
+ error: string;
165
+ };
166
+ }
167
+ export interface BlobAnalysis {
168
+ type: 'json' | 'text' | 'protobuf' | 'binary';
169
+ json?: unknown;
170
+ text?: string;
171
+ protoFields?: Array<{
172
+ num: number;
173
+ wire: number;
174
+ size: number;
175
+ text?: string;
176
+ }>;
177
+ }
178
+ export interface ParsedInteractionUpdate {
179
+ text: string | null;
180
+ thinking: string | null;
181
+ isComplete: boolean;
182
+ isHeartbeat: boolean;
183
+ toolCallStarted: {
184
+ callId: string;
185
+ modelCallId: string;
186
+ toolType: string;
187
+ name: string;
188
+ arguments: string;
189
+ } | null;
190
+ toolCallCompleted: {
191
+ callId: string;
192
+ modelCallId: string;
193
+ toolType: string;
194
+ name: string;
195
+ arguments: string;
196
+ } | null;
197
+ partialToolCall: {
198
+ callId: string;
199
+ argsTextDelta: string;
200
+ } | null;
201
+ }
@@ -0,0 +1,10 @@
1
+ export var AgentMode;
2
+ (function (AgentMode) {
3
+ AgentMode[AgentMode["UNSPECIFIED"] = 0] = "UNSPECIFIED";
4
+ AgentMode[AgentMode["AGENT"] = 1] = "AGENT";
5
+ AgentMode[AgentMode["ASK"] = 2] = "ASK";
6
+ AgentMode[AgentMode["PLAN"] = 3] = "PLAN";
7
+ AgentMode[AgentMode["DEBUG"] = 4] = "DEBUG";
8
+ AgentMode[AgentMode["TRIAGE"] = 5] = "TRIAGE";
9
+ })(AgentMode || (AgentMode = {}));
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/api/proto/types.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,SAOX;AAPD,WAAY,SAAS;IACnB,uDAAe,CAAA;IACf,2CAAS,CAAA;IACT,uCAAO,CAAA;IACP,yCAAQ,CAAA;IACR,2CAAS,CAAA;IACT,6CAAU,CAAA;AACZ,CAAC,EAPW,SAAS,KAAT,SAAS,QAOpB"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Auth Helper Functions
3
+ *
4
+ * Higher-level authentication functions that combine storage and login
5
+ * functionality for common auth operations.
6
+ */
7
+ import { type CredentialManager, type StoredCredentials } from "../storage";
8
+ /**
9
+ * Refresh an access token using the refresh token
10
+ */
11
+ export declare function refreshAccessToken(refreshToken: string, endpoint?: string): Promise<{
12
+ accessToken: string;
13
+ refreshToken: string;
14
+ } | null>;
15
+ /**
16
+ * Get a valid access token, refreshing if necessary
17
+ */
18
+ export declare function getValidAccessToken(credentialManager: CredentialManager, endpoint?: string): Promise<string | null>;
19
+ /**
20
+ * Authenticate using an API key
21
+ */
22
+ export declare function authenticateWithApiKey(credentialManager: CredentialManager, apiKey: string, options?: {
23
+ endpoint?: string;
24
+ }): Promise<boolean>;
25
+ /**
26
+ * Authenticate using a direct token (no refresh token)
27
+ */
28
+ export declare function authenticateWithToken(credentialManager: CredentialManager, token: string): Promise<void>;
29
+ /**
30
+ * Check if the user is authenticated with a valid token
31
+ */
32
+ export declare function isAuthenticated(credentialManager: CredentialManager): Promise<boolean>;
33
+ /**
34
+ * Get stored credentials
35
+ */
36
+ export declare function getStoredCredentials(credentialManager: CredentialManager): Promise<StoredCredentials>;
37
+ /**
38
+ * Clear all credentials
39
+ */
40
+ export declare function clearCredentials(credentialManager: CredentialManager): Promise<void>;
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Auth Helper Functions
3
+ *
4
+ * Higher-level authentication functions that combine storage and login
5
+ * functionality for common auth operations.
6
+ */
7
+ import { isTokenExpiringSoon, isTokenExpired } from "../utils/jwt";
8
+ import {} from "../storage";
9
+ import { LoginManager, CURSOR_API_BASE_URL } from "./login";
10
+ // --- Token Refresh ---
11
+ const REFRESH_ENDPOINT = "/auth/refresh";
12
+ /**
13
+ * Refresh an access token using the refresh token
14
+ */
15
+ export async function refreshAccessToken(refreshToken, endpoint = CURSOR_API_BASE_URL) {
16
+ try {
17
+ const response = await fetch(`${endpoint}${REFRESH_ENDPOINT}`, {
18
+ method: "POST",
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ Authorization: `Bearer ${refreshToken}`,
22
+ },
23
+ body: JSON.stringify({}),
24
+ });
25
+ if (!response.ok) {
26
+ return null;
27
+ }
28
+ const result = await response.json();
29
+ if (typeof result === "object" &&
30
+ result !== null &&
31
+ "accessToken" in result &&
32
+ "refreshToken" in result) {
33
+ return result;
34
+ }
35
+ }
36
+ catch {
37
+ // Refresh failed
38
+ }
39
+ return null;
40
+ }
41
+ // --- High-Level Auth Functions ---
42
+ /**
43
+ * Get a valid access token, refreshing if necessary
44
+ */
45
+ export async function getValidAccessToken(credentialManager, endpoint = CURSOR_API_BASE_URL) {
46
+ const accessToken = await credentialManager.getAccessToken();
47
+ // Check if we have a valid token
48
+ if (accessToken && !isTokenExpiringSoon(accessToken)) {
49
+ return accessToken;
50
+ }
51
+ // Try to refresh
52
+ const refreshToken = await credentialManager.getRefreshToken();
53
+ if (refreshToken) {
54
+ const refreshed = await refreshAccessToken(refreshToken, endpoint);
55
+ if (refreshed) {
56
+ await credentialManager.setAuthentication(refreshed.accessToken, refreshed.refreshToken);
57
+ return refreshed.accessToken;
58
+ }
59
+ }
60
+ // Return possibly expired token (let the API reject if needed)
61
+ return accessToken ?? null;
62
+ }
63
+ /**
64
+ * Authenticate using an API key
65
+ */
66
+ export async function authenticateWithApiKey(credentialManager, apiKey, options) {
67
+ const loginManager = new LoginManager();
68
+ const result = await loginManager.loginWithApiKey(apiKey, options);
69
+ if (result) {
70
+ await credentialManager.setAuthentication(result.accessToken, result.refreshToken, apiKey);
71
+ return true;
72
+ }
73
+ return false;
74
+ }
75
+ /**
76
+ * Authenticate using a direct token (no refresh token)
77
+ */
78
+ export async function authenticateWithToken(credentialManager, token) {
79
+ // Store token without refresh token
80
+ await credentialManager.setAuthentication(token, "");
81
+ }
82
+ /**
83
+ * Check if the user is authenticated with a valid token
84
+ */
85
+ export async function isAuthenticated(credentialManager) {
86
+ const token = await credentialManager.getAccessToken();
87
+ if (!token)
88
+ return false;
89
+ return !isTokenExpired(token);
90
+ }
91
+ /**
92
+ * Get stored credentials
93
+ */
94
+ export async function getStoredCredentials(credentialManager) {
95
+ return credentialManager.getAllCredentials();
96
+ }
97
+ /**
98
+ * Clear all credentials
99
+ */
100
+ export async function clearCredentials(credentialManager) {
101
+ return credentialManager.clearAuthentication();
102
+ }
103
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../src/lib/auth/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Auth Module
3
+ *
4
+ * Re-exports all auth-related functionality
5
+ */
6
+ export { refreshAccessToken, getValidAccessToken, authenticateWithApiKey, authenticateWithToken, isAuthenticated, getStoredCredentials, clearCredentials, } from "./helpers";
7
+ export { LoginManager, CURSOR_API_BASE_URL, CURSOR_WEBSITE_URL, POLLING_ENDPOINT, generateAuthParams, openBrowser, type AuthResult, type AuthParams, type LoginMetadata, } from "./login";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Auth Module
3
+ *
4
+ * Re-exports all auth-related functionality
5
+ */
6
+ // Re-export helpers
7
+ export { refreshAccessToken, getValidAccessToken, authenticateWithApiKey, authenticateWithToken, isAuthenticated, getStoredCredentials, clearCredentials, } from "./helpers";
8
+ // Re-export login manager and related
9
+ export { LoginManager, CURSOR_API_BASE_URL, CURSOR_WEBSITE_URL, POLLING_ENDPOINT, generateAuthParams, openBrowser, } from "./login";
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/auth/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oBAAoB;AACpB,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAEnB,sCAAsC;AACtC,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,GAIZ,MAAM,SAAS,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Login Manager
3
+ *
4
+ * Handles the OAuth PKCE login flow and API key authentication
5
+ * for Cursor's authentication system.
6
+ */
7
+ export declare const CURSOR_WEBSITE_URL = "https://cursor.com";
8
+ export declare const CURSOR_API_BASE_URL = "https://api2.cursor.sh";
9
+ export declare const POLLING_ENDPOINT = "https://api2.cursor.sh/auth/poll";
10
+ export interface AuthResult {
11
+ accessToken: string;
12
+ refreshToken: string;
13
+ }
14
+ export interface AuthParams {
15
+ uuid: string;
16
+ challenge: string;
17
+ verifier: string;
18
+ loginUrl: string;
19
+ }
20
+ export interface LoginMetadata {
21
+ uuid: string;
22
+ verifier: string;
23
+ }
24
+ /**
25
+ * Generate authentication parameters (PKCE flow)
26
+ */
27
+ export declare function generateAuthParams(): AuthParams;
28
+ /**
29
+ * Open a URL in the default browser
30
+ */
31
+ export declare function openBrowser(url: string): Promise<void>;
32
+ export declare class LoginManager {
33
+ /**
34
+ * Start the OAuth login flow
35
+ * Returns metadata needed for polling and the URL to open in browser
36
+ */
37
+ startLogin(): {
38
+ metadata: LoginMetadata;
39
+ loginUrl: string;
40
+ };
41
+ /**
42
+ * Poll for authentication result
43
+ * This waits for the user to complete the browser login
44
+ */
45
+ waitForResult(metadata: LoginMetadata, options?: {
46
+ maxAttempts?: number;
47
+ onProgress?: (attempt: number) => void;
48
+ }): Promise<AuthResult | null>;
49
+ /**
50
+ * Exchange API key for access/refresh tokens
51
+ */
52
+ loginWithApiKey(apiKey: string, options?: {
53
+ endpoint?: string;
54
+ }): Promise<AuthResult | null>;
55
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Login Manager
3
+ *
4
+ * Handles the OAuth PKCE login flow and API key authentication
5
+ * for Cursor's authentication system.
6
+ */
7
+ import { createHash, randomBytes, randomUUID } from "node:crypto";
8
+ import { platform } from "node:os";
9
+ import { exec } from "node:child_process";
10
+ // --- Configuration ---
11
+ export const CURSOR_WEBSITE_URL = "https://cursor.com";
12
+ export const CURSOR_API_BASE_URL = "https://api2.cursor.sh";
13
+ export const POLLING_ENDPOINT = `${CURSOR_API_BASE_URL}/auth/poll`;
14
+ // --- Helper Functions ---
15
+ /**
16
+ * Base64 URL encode a buffer (RFC 4648)
17
+ */
18
+ function base64URLEncode(buffer) {
19
+ return buffer
20
+ .toString("base64")
21
+ .replace(/\+/g, "-")
22
+ .replace(/\//g, "_")
23
+ .replace(/=/g, "");
24
+ }
25
+ /**
26
+ * Generate a SHA-256 hash of the input string
27
+ */
28
+ function sha256(data) {
29
+ return createHash("sha256").update(data).digest();
30
+ }
31
+ /**
32
+ * Generate authentication parameters (PKCE flow)
33
+ */
34
+ export function generateAuthParams() {
35
+ // Generate a 32-byte random verifier
36
+ const verifierArray = randomBytes(32);
37
+ const verifier = base64URLEncode(verifierArray);
38
+ // Generate challenge by SHA-256 hashing the verifier
39
+ const challengeHash = sha256(verifier);
40
+ const challenge = base64URLEncode(challengeHash);
41
+ // Generate a UUID
42
+ const uuid = randomUUID();
43
+ // Construct the login URL
44
+ const loginUrl = `${CURSOR_WEBSITE_URL}/loginDeepControl?challenge=${challenge}&uuid=${uuid}&mode=login&redirectTarget=cli`;
45
+ return {
46
+ uuid,
47
+ challenge,
48
+ verifier,
49
+ loginUrl,
50
+ };
51
+ }
52
+ /**
53
+ * Open a URL in the default browser
54
+ */
55
+ export function openBrowser(url) {
56
+ return new Promise((resolve, reject) => {
57
+ const command = platform() === "darwin"
58
+ ? `open "${url}"`
59
+ : platform() === "win32"
60
+ ? `start "" "${url}"`
61
+ : `xdg-open "${url}"`;
62
+ exec(command, (error) => {
63
+ if (error) {
64
+ reject(error);
65
+ }
66
+ else {
67
+ resolve();
68
+ }
69
+ });
70
+ });
71
+ }
72
+ /**
73
+ * Sleep for a given number of milliseconds
74
+ */
75
+ function sleep(ms) {
76
+ return new Promise((resolve) => setTimeout(resolve, ms));
77
+ }
78
+ // --- LoginManager ---
79
+ export class LoginManager {
80
+ /**
81
+ * Start the OAuth login flow
82
+ * Returns metadata needed for polling and the URL to open in browser
83
+ */
84
+ startLogin() {
85
+ const authParams = generateAuthParams();
86
+ return {
87
+ metadata: {
88
+ uuid: authParams.uuid,
89
+ verifier: authParams.verifier,
90
+ },
91
+ loginUrl: authParams.loginUrl,
92
+ };
93
+ }
94
+ /**
95
+ * Poll for authentication result
96
+ * This waits for the user to complete the browser login
97
+ */
98
+ async waitForResult(metadata, options) {
99
+ const maxAttempts = options?.maxAttempts ?? 150;
100
+ const baseDelay = 1000; // 1 second base delay
101
+ const maxDelay = 10000; // 10 seconds maximum delay
102
+ const backoffMultiplier = 1.2; // Gentle exponential backoff
103
+ const maxConsecutiveErrors = 3;
104
+ let consecutiveErrors = 0;
105
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
106
+ try {
107
+ const url = `${POLLING_ENDPOINT}?uuid=${metadata.uuid}&verifier=${metadata.verifier}`;
108
+ const response = await fetch(url, {
109
+ headers: {
110
+ "Content-Type": "application/json",
111
+ },
112
+ });
113
+ // 404 means authentication is still pending
114
+ if (response.status === 404) {
115
+ consecutiveErrors = 0;
116
+ const delay = Math.min(baseDelay * Math.pow(backoffMultiplier, attempt), maxDelay);
117
+ options?.onProgress?.(attempt);
118
+ await sleep(delay);
119
+ continue;
120
+ }
121
+ // Check for other error statuses
122
+ if (!response.ok) {
123
+ consecutiveErrors++;
124
+ if (consecutiveErrors >= maxConsecutiveErrors) {
125
+ return null;
126
+ }
127
+ const delay = Math.min(baseDelay * Math.pow(backoffMultiplier, attempt), maxDelay);
128
+ await sleep(delay);
129
+ continue;
130
+ }
131
+ // Success case
132
+ consecutiveErrors = 0;
133
+ const authResult = await response.json();
134
+ if (typeof authResult === "object" &&
135
+ authResult !== null &&
136
+ "accessToken" in authResult &&
137
+ "refreshToken" in authResult) {
138
+ return authResult;
139
+ }
140
+ return null;
141
+ }
142
+ catch {
143
+ consecutiveErrors++;
144
+ if (consecutiveErrors >= maxConsecutiveErrors) {
145
+ return null;
146
+ }
147
+ const delay = Math.min(baseDelay * Math.pow(backoffMultiplier, attempt), maxDelay);
148
+ await sleep(delay);
149
+ }
150
+ }
151
+ return null;
152
+ }
153
+ /**
154
+ * Exchange API key for access/refresh tokens
155
+ */
156
+ async loginWithApiKey(apiKey, options) {
157
+ const baseUrl = options?.endpoint ?? CURSOR_API_BASE_URL;
158
+ try {
159
+ const response = await fetch(`${baseUrl}/auth/exchange_user_api_key`, {
160
+ method: "POST",
161
+ headers: {
162
+ "Content-Type": "application/json",
163
+ Authorization: `Bearer ${apiKey}`,
164
+ },
165
+ body: JSON.stringify({}),
166
+ });
167
+ if (!response.ok) {
168
+ return null;
169
+ }
170
+ const authResult = await response.json();
171
+ if (typeof authResult === "object" &&
172
+ authResult !== null &&
173
+ "accessToken" in authResult &&
174
+ "refreshToken" in authResult) {
175
+ return authResult;
176
+ }
177
+ }
178
+ catch {
179
+ // API key exchange error
180
+ }
181
+ return null;
182
+ }
183
+ }
184
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/lib/auth/login.ts"],"names":[],"mappings":"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"}