@nick3/copilot-api 1.4.9 → 1.5.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.
- package/README.md +5 -3
- package/dist/account-BMFr8t9b.js +362 -0
- package/dist/account-BMFr8t9b.js.map +1 -0
- package/dist/{accounts-manager-Cjrd_el_.js → accounts-manager-DgQH4KtO.js} +114 -13
- package/dist/accounts-manager-DgQH4KtO.js.map +1 -0
- package/dist/admin/assets/index-519a65q_.js +66 -0
- package/dist/admin/assets/index-ChMaMig2.css +1 -0
- package/dist/admin/index.html +2 -2
- package/dist/{auth-1gAffrpI.js → auth-DipSy-jV.js} +6 -12
- package/dist/auth-DipSy-jV.js.map +1 -0
- package/dist/{check-usage-CsRu467P.js → check-usage-Dbjs73E0.js} +5 -5
- package/dist/check-usage-Dbjs73E0.js.map +1 -0
- package/dist/{debug-BzR5ZQUk.js → debug-BJfZVBB7.js} +2 -2
- package/dist/{debug-BzR5ZQUk.js.map → debug-BJfZVBB7.js.map} +1 -1
- package/dist/{get-copilot-token-BbpphnmV.js → get-copilot-token-DoK8Ia3u.js} +2 -2
- package/dist/{get-copilot-token-BbpphnmV.js.map → get-copilot-token-DoK8Ia3u.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{paths-Cvzy-eLX.js → paths-DGlr310R.js} +2 -2
- package/dist/{paths-Cvzy-eLX.js.map → paths-DGlr310R.js.map} +1 -1
- package/dist/{utils-DY-jLXwO.js → poll-access-token-BzenaGHn.js} +352 -52
- package/dist/poll-access-token-BzenaGHn.js.map +1 -0
- package/dist/{server-DqwhClJ-.js → server-DzE_zmUf.js} +498 -136
- package/dist/server-DzE_zmUf.js.map +1 -0
- package/dist/{start-B1_Ols5Z.js → start-DEugVHqn.js} +26 -15
- package/dist/start-DEugVHqn.js.map +1 -0
- package/package.json +1 -1
- package/dist/account-CipKmikF.js +0 -17
- package/dist/account-CipKmikF.js.map +0 -1
- package/dist/accounts-manager-Cjrd_el_.js.map +0 -1
- package/dist/accounts-registry-CQYvRe65.js +0 -180
- package/dist/accounts-registry-CQYvRe65.js.map +0 -1
- package/dist/admin/assets/index-BFvCJZIK.js +0 -57
- package/dist/admin/assets/index-CsAeel_7.css +0 -1
- package/dist/auth-1gAffrpI.js.map +0 -1
- package/dist/check-usage-CsRu467P.js.map +0 -1
- package/dist/poll-access-token-CGfLFzMq.js +0 -52
- package/dist/poll-access-token-CGfLFzMq.js.map +0 -1
- package/dist/server-DqwhClJ-.js.map +0 -1
- package/dist/start-B1_Ols5Z.js.map +0 -1
- package/dist/utils-DY-jLXwO.js.map +0 -1
|
@@ -1,32 +1,45 @@
|
|
|
1
|
-
import { t as PATHS } from "./paths-
|
|
1
|
+
import { t as PATHS } from "./paths-DGlr310R.js";
|
|
2
2
|
import consola from "consola";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
|
-
import { networkInterfaces } from "node:os";
|
|
3
|
+
import fs, { readFile } from "node:fs/promises";
|
|
5
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
5
|
+
import { exec } from "node:child_process";
|
|
6
|
+
import path from "node:path";
|
|
6
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
+
import { networkInterfaces } from "node:os";
|
|
7
9
|
|
|
8
|
-
//#region src/lib/
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
//#region src/lib/opencode.ts
|
|
11
|
+
const execAsync = (command) => {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
exec(command, (error, stdout) => {
|
|
14
|
+
if (error) {
|
|
15
|
+
reject(error);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
resolve(stdout);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
15
21
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
22
|
+
let opencodeVersionCache;
|
|
23
|
+
const getGlobalNpmRoot = async () => {
|
|
24
|
+
return (await execAsync("npm root -g")).trim();
|
|
25
|
+
};
|
|
26
|
+
async function resolveOpencodeVersion() {
|
|
27
|
+
try {
|
|
28
|
+
const npmRootPath = await getGlobalNpmRoot();
|
|
29
|
+
const packageJson = await readFile(path.join(npmRootPath, "opencode-ai", "package.json"), "utf8");
|
|
30
|
+
const { version } = JSON.parse(packageJson);
|
|
31
|
+
opencodeVersionCache = version;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
consola.warn(`Failed to resolve opencode version`, error);
|
|
34
|
+
}
|
|
29
35
|
}
|
|
36
|
+
const initOpencodeVersion = () => {
|
|
37
|
+
if (process.env.COPILOT_API_OAUTH_APP?.trim() !== "opencode") return Promise.resolve();
|
|
38
|
+
return resolveOpencodeVersion();
|
|
39
|
+
};
|
|
40
|
+
const getCachedOpencodeVersion = () => {
|
|
41
|
+
return opencodeVersionCache;
|
|
42
|
+
};
|
|
30
43
|
|
|
31
44
|
//#endregion
|
|
32
45
|
//#region src/lib/request-context.ts
|
|
@@ -46,6 +59,35 @@ function resolveTraceId(traceId) {
|
|
|
46
59
|
return candidate;
|
|
47
60
|
}
|
|
48
61
|
|
|
62
|
+
//#endregion
|
|
63
|
+
//#region src/lib/state.ts
|
|
64
|
+
const state = {
|
|
65
|
+
accountType: "individual",
|
|
66
|
+
manualApprove: false,
|
|
67
|
+
rateLimitWait: false,
|
|
68
|
+
showToken: false,
|
|
69
|
+
verbose: false,
|
|
70
|
+
vsCodeDeviceId: randomUUID()
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Create an AccountContext from the current global state.
|
|
74
|
+
* This is a compatibility layer for transitioning to multi-account support.
|
|
75
|
+
* @throws Error if githubToken is not set in state
|
|
76
|
+
*/
|
|
77
|
+
function accountFromState() {
|
|
78
|
+
if (!state.githubToken) throw new Error("GitHub token not set in state");
|
|
79
|
+
return {
|
|
80
|
+
githubToken: state.githubToken,
|
|
81
|
+
copilotToken: state.copilotToken,
|
|
82
|
+
...state.copilotApiUrl !== void 0 ? { copilotApiUrl: state.copilotApiUrl } : {},
|
|
83
|
+
accountType: state.accountType,
|
|
84
|
+
vsCodeVersion: state.vsCodeVersion,
|
|
85
|
+
clientDeviceId: state.vsCodeDeviceId,
|
|
86
|
+
clientMachineId: state.macMachineId,
|
|
87
|
+
clientSessionId: state.vsCodeSessionId
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
49
91
|
//#endregion
|
|
50
92
|
//#region src/lib/api-config.ts
|
|
51
93
|
const isOpencodeOauthApp = () => {
|
|
@@ -71,7 +113,14 @@ const getOpencodeOauthHeaders = () => {
|
|
|
71
113
|
return {
|
|
72
114
|
Accept: "application/json",
|
|
73
115
|
"Content-Type": "application/json",
|
|
74
|
-
"User-Agent":
|
|
116
|
+
"User-Agent": getOpencodeVersion()
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
const getOpencodeLLMHeaders = () => {
|
|
120
|
+
return {
|
|
121
|
+
Accept: "application/json",
|
|
122
|
+
"Content-Type": "application/json",
|
|
123
|
+
"User-Agent": OPENCODE_LLM_USER_AGENT
|
|
75
124
|
};
|
|
76
125
|
};
|
|
77
126
|
const normalizeOpencodeUserAgent = (userAgent) => {
|
|
@@ -114,33 +163,82 @@ const standardHeaders = () => ({
|
|
|
114
163
|
"content-type": "application/json",
|
|
115
164
|
accept: "application/json"
|
|
116
165
|
});
|
|
117
|
-
const
|
|
166
|
+
const getOpencodeVersion = () => {
|
|
167
|
+
const version = getCachedOpencodeVersion();
|
|
168
|
+
if (version) return "opencode/" + version;
|
|
169
|
+
return OPENCODE_VERSION;
|
|
170
|
+
};
|
|
171
|
+
const OPENCODE_VERSION = "opencode/1.3.15";
|
|
172
|
+
const OPENCODE_LLM_USER_AGENT = "opencode/1.3.15 ai-sdk/provider-utils/4.0.21 runtime/bun/1.3.11, opencode/1.3.15";
|
|
173
|
+
const COPILOT_VERSION = "0.42.3";
|
|
118
174
|
const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
|
|
119
175
|
const USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`;
|
|
176
|
+
const CLAUDE_AGENT_USER_AGENT = "vscode_claude_code/2.1.81 (external, sdk-ts, agent-sdk/0.2.81)";
|
|
120
177
|
const API_VERSION = "2025-10-01";
|
|
121
178
|
const copilotBaseUrl = (account) => {
|
|
122
179
|
const enterpriseDomain = getEnterpriseDomain();
|
|
123
180
|
if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;
|
|
181
|
+
if (isOpencodeOauthApp()) return "https://api.githubcopilot.com";
|
|
182
|
+
if (account.copilotApiUrl) return account.copilotApiUrl;
|
|
124
183
|
return account.accountType === "individual" ? "https://api.githubcopilot.com" : `https://api.${account.accountType}.githubcopilot.com`;
|
|
125
184
|
};
|
|
185
|
+
const prepareMessageProxyHeaders = (headers) => {
|
|
186
|
+
if (isOpencodeOauthApp()) return;
|
|
187
|
+
const requestIdValue = randomUUID();
|
|
188
|
+
headers["x-agent-task-id"] = requestIdValue;
|
|
189
|
+
headers["x-request-id"] = requestIdValue;
|
|
190
|
+
headers["x-interaction-type"] = "messages-proxy";
|
|
191
|
+
headers["openai-intent"] = "messages-proxy";
|
|
192
|
+
headers["user-agent"] = CLAUDE_AGENT_USER_AGENT;
|
|
193
|
+
};
|
|
194
|
+
const githubUserHeaders = (account) => {
|
|
195
|
+
if (isOpencodeOauthApp()) return {
|
|
196
|
+
Authorization: `Bearer ${account.githubToken}`,
|
|
197
|
+
"User-Agent": getOpencodeVersion()
|
|
198
|
+
};
|
|
199
|
+
return {
|
|
200
|
+
accept: "application/vnd.github+json",
|
|
201
|
+
authorization: `token ${account.githubToken}`,
|
|
202
|
+
"user-agent": USER_AGENT,
|
|
203
|
+
"x-github-api-version": "2022-11-28",
|
|
204
|
+
"x-vscode-user-agent-library-version": "electron-fetch"
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
const copilotModelsHeaders = (account) => {
|
|
208
|
+
if (isOpencodeOauthApp()) return {
|
|
209
|
+
Authorization: `Bearer ${account.copilotToken ?? account.githubToken}`,
|
|
210
|
+
"User-Agent": getOpencodeVersion()
|
|
211
|
+
};
|
|
212
|
+
return githubCopilotHeaders(account);
|
|
213
|
+
};
|
|
126
214
|
const copilotHeaders = (account, vision = false, requestId) => {
|
|
127
215
|
if (isOpencodeOauthApp()) {
|
|
128
|
-
const headers
|
|
216
|
+
const headers = {
|
|
129
217
|
Authorization: `Bearer ${account.copilotToken ?? account.githubToken}`,
|
|
130
|
-
...
|
|
218
|
+
...getOpencodeLLMHeaders(),
|
|
131
219
|
"Openai-Intent": "conversation-edits"
|
|
132
220
|
};
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
221
|
+
const store = requestContext.getStore();
|
|
222
|
+
const userAgent = store?.userAgent.trim();
|
|
223
|
+
if (userAgent?.startsWith("opencode/")) headers["User-Agent"] = normalizeOpencodeUserAgent(userAgent);
|
|
224
|
+
if (store?.sessionAffinity) headers["x-session-affinity"] = store.sessionAffinity;
|
|
225
|
+
if (store?.parentSessionId) headers["x-parent-session-id"] = store.parentSessionId;
|
|
226
|
+
if (vision) headers["Copilot-Vision-Request"] = "true";
|
|
227
|
+
return headers;
|
|
137
228
|
}
|
|
229
|
+
return githubCopilotHeaders(account, requestId, vision);
|
|
230
|
+
};
|
|
231
|
+
const githubCopilotHeaders = (account, requestId, vision = false) => {
|
|
138
232
|
const resolvedRequestId = requestId ?? randomUUID();
|
|
233
|
+
const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId;
|
|
234
|
+
const resolvedMachineId = account.clientMachineId ?? state.macMachineId;
|
|
235
|
+
const resolvedSessionId = account.clientSessionId ?? state.vsCodeSessionId;
|
|
139
236
|
const headers = {
|
|
140
237
|
Authorization: `Bearer ${account.copilotToken}`,
|
|
141
238
|
"content-type": standardHeaders()["content-type"],
|
|
142
239
|
"copilot-integration-id": "vscode-chat",
|
|
143
240
|
"editor-version": `vscode/${account.vsCodeVersion}`,
|
|
241
|
+
"editor-device-id": resolvedDeviceId,
|
|
144
242
|
"editor-plugin-version": EDITOR_PLUGIN_VERSION,
|
|
145
243
|
"user-agent": USER_AGENT,
|
|
146
244
|
"openai-intent": "conversation-agent",
|
|
@@ -151,20 +249,26 @@ const copilotHeaders = (account, vision = false, requestId) => {
|
|
|
151
249
|
"x-interaction-type": "conversation-agent"
|
|
152
250
|
};
|
|
153
251
|
if (vision) headers["copilot-vision-request"] = "true";
|
|
154
|
-
if (
|
|
155
|
-
if (
|
|
252
|
+
if (resolvedMachineId) headers["vscode-machineid"] = resolvedMachineId;
|
|
253
|
+
if (resolvedSessionId) headers["vscode-sessionid"] = resolvedSessionId;
|
|
156
254
|
return headers;
|
|
157
255
|
};
|
|
158
256
|
const GITHUB_API_BASE_URL = "https://api.github.com";
|
|
159
|
-
const githubHeaders = (account) =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
257
|
+
const githubHeaders = (account) => {
|
|
258
|
+
if (isOpencodeOauthApp()) return {
|
|
259
|
+
Authorization: `Bearer ${account.githubToken}`,
|
|
260
|
+
...getOpencodeOauthHeaders()
|
|
261
|
+
};
|
|
262
|
+
return {
|
|
263
|
+
...standardHeaders(),
|
|
264
|
+
authorization: `token ${account.githubToken}`,
|
|
265
|
+
"editor-version": `vscode/${account.vsCodeVersion}`,
|
|
266
|
+
"editor-plugin-version": EDITOR_PLUGIN_VERSION,
|
|
267
|
+
"user-agent": USER_AGENT,
|
|
268
|
+
"x-github-api-version": API_VERSION,
|
|
269
|
+
"x-vscode-user-agent-library-version": "electron-fetch"
|
|
270
|
+
};
|
|
271
|
+
};
|
|
168
272
|
const GITHUB_BASE_URL = "https://github.com";
|
|
169
273
|
const GITHUB_CLIENT_ID = "Iv1.b507a08c87ecfe98";
|
|
170
274
|
const GITHUB_APP_SCOPES = ["read:user"].join(" ");
|
|
@@ -179,6 +283,7 @@ var HTTPError = class extends Error {
|
|
|
179
283
|
this.response = response;
|
|
180
284
|
}
|
|
181
285
|
};
|
|
286
|
+
var CancelledError = class extends Error {};
|
|
182
287
|
async function forwardError(c, error) {
|
|
183
288
|
consola.error("Error occurred:", error);
|
|
184
289
|
if (error instanceof HTTPError) {
|
|
@@ -214,15 +319,33 @@ const getCopilotUsage = async (account) => {
|
|
|
214
319
|
return await response.json();
|
|
215
320
|
};
|
|
216
321
|
|
|
322
|
+
//#endregion
|
|
323
|
+
//#region src/services/github/get-device-code.ts
|
|
324
|
+
async function getDeviceCode(options) {
|
|
325
|
+
const { clientId, headers, scope } = getOauthAppConfig();
|
|
326
|
+
const { deviceCodeUrl } = options?.overrideUrls ?? getOauthUrls();
|
|
327
|
+
const response = await fetch(deviceCodeUrl, {
|
|
328
|
+
method: "POST",
|
|
329
|
+
headers,
|
|
330
|
+
body: JSON.stringify({
|
|
331
|
+
client_id: clientId,
|
|
332
|
+
scope
|
|
333
|
+
})
|
|
334
|
+
});
|
|
335
|
+
if (!response.ok) throw new HTTPError("Failed to get device code", response);
|
|
336
|
+
return await response.json();
|
|
337
|
+
}
|
|
338
|
+
|
|
217
339
|
//#endregion
|
|
218
340
|
//#region src/services/github/get-user.ts
|
|
341
|
+
const resolveGitHubUserAccount = (account) => {
|
|
342
|
+
if (account) return account;
|
|
343
|
+
if (!state.githubToken) throw new Error("GitHub token not set");
|
|
344
|
+
return accountFromState();
|
|
345
|
+
};
|
|
219
346
|
async function getGitHubUser(account) {
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
const response = await fetch(`${getGitHubApiBaseUrl()}/user`, { headers: {
|
|
223
|
-
authorization: `token ${token}`,
|
|
224
|
-
...standardHeaders()
|
|
225
|
-
} });
|
|
347
|
+
const resolvedAccount = resolveGitHubUserAccount(account);
|
|
348
|
+
const response = await fetch(`${getGitHubApiBaseUrl()}/user`, { headers: githubUserHeaders(resolvedAccount) });
|
|
226
349
|
if (!response.ok) throw new HTTPError("Failed to get GitHub user", response);
|
|
227
350
|
return await response.json();
|
|
228
351
|
}
|
|
@@ -231,7 +354,7 @@ async function getGitHubUser(account) {
|
|
|
231
354
|
//#region src/services/copilot/get-models.ts
|
|
232
355
|
const getModels = async (account) => {
|
|
233
356
|
const ctx = account ?? accountFromState();
|
|
234
|
-
const response = await fetch(`${copilotBaseUrl(ctx)}/models`, { headers:
|
|
357
|
+
const response = await fetch(`${copilotBaseUrl(ctx)}/models`, { headers: copilotModelsHeaders(ctx) });
|
|
235
358
|
if (!response.ok) throw new HTTPError("Failed to get models", response);
|
|
236
359
|
const models = await response.json();
|
|
237
360
|
try {
|
|
@@ -246,12 +369,153 @@ const getModels = async (account) => {
|
|
|
246
369
|
|
|
247
370
|
//#endregion
|
|
248
371
|
//#region src/services/get-vscode-version.ts
|
|
249
|
-
const FALLBACK = "1.
|
|
372
|
+
const FALLBACK = "1.114.0";
|
|
250
373
|
async function getVSCodeVersion() {
|
|
251
374
|
await Promise.resolve();
|
|
252
375
|
return FALLBACK;
|
|
253
376
|
}
|
|
254
377
|
|
|
378
|
+
//#endregion
|
|
379
|
+
//#region src/lib/deviceid.ts
|
|
380
|
+
const WINDOWS_DEVICE_ID_KEY = String.raw`\SOFTWARE\Microsoft\DeveloperTools`;
|
|
381
|
+
const WINDOWS_DEVICE_ID_NAME = "deviceid";
|
|
382
|
+
const windows64Architectures = new Set([
|
|
383
|
+
"AMD64",
|
|
384
|
+
"ARM64",
|
|
385
|
+
"IA64"
|
|
386
|
+
]);
|
|
387
|
+
const getPosixHomeDir = () => {
|
|
388
|
+
if (!process.env.HOME) throw new Error("Home directory not found");
|
|
389
|
+
return process.env.HOME;
|
|
390
|
+
};
|
|
391
|
+
const getDeviceIdFilePath = () => {
|
|
392
|
+
let folder;
|
|
393
|
+
switch (process.platform) {
|
|
394
|
+
case "darwin":
|
|
395
|
+
folder = path.posix.join(getPosixHomeDir(), "Library", "Application Support");
|
|
396
|
+
break;
|
|
397
|
+
case "linux":
|
|
398
|
+
folder = process.env.XDG_CACHE_HOME ?? path.posix.join(getPosixHomeDir(), ".cache");
|
|
399
|
+
break;
|
|
400
|
+
default: throw new Error("Unsupported platform");
|
|
401
|
+
}
|
|
402
|
+
return path.posix.join(folder, "Microsoft", "DeveloperTools", "deviceid");
|
|
403
|
+
};
|
|
404
|
+
const isMissingFileError = (error) => {
|
|
405
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
406
|
+
};
|
|
407
|
+
const readStoredDeviceIdFile = async (filePath) => {
|
|
408
|
+
const { readFile: readFile$1 } = await import("node:fs/promises");
|
|
409
|
+
try {
|
|
410
|
+
return await readFile$1(filePath, "utf8");
|
|
411
|
+
} catch (error) {
|
|
412
|
+
if (isMissingFileError(error)) return;
|
|
413
|
+
throw error;
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
const writeStoredDeviceIdFile = async (filePath, deviceId) => {
|
|
417
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
418
|
+
await mkdir(path.posix.dirname(filePath), { recursive: true });
|
|
419
|
+
await writeFile(filePath, deviceId, "utf8");
|
|
420
|
+
};
|
|
421
|
+
const getWindowsRegistryArch = () => {
|
|
422
|
+
const architecture = (process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE)?.toUpperCase();
|
|
423
|
+
return architecture && windows64Architectures.has(architecture) ? "x64" : void 0;
|
|
424
|
+
};
|
|
425
|
+
const loadWinreg = async () => {
|
|
426
|
+
const module = await import("winreg");
|
|
427
|
+
return "default" in module ? module.default : module;
|
|
428
|
+
};
|
|
429
|
+
const isMissingRegistryError = (error) => {
|
|
430
|
+
if (!error) return false;
|
|
431
|
+
const errorCode = Number(error.code);
|
|
432
|
+
return Number.isFinite(errorCode) && errorCode === 1;
|
|
433
|
+
};
|
|
434
|
+
const createWindowsRegistry = async () => {
|
|
435
|
+
const Winreg = await loadWinreg();
|
|
436
|
+
return {
|
|
437
|
+
registry: new Winreg({
|
|
438
|
+
hive: Winreg.HKCU,
|
|
439
|
+
key: WINDOWS_DEVICE_ID_KEY,
|
|
440
|
+
arch: getWindowsRegistryArch()
|
|
441
|
+
}),
|
|
442
|
+
regSz: Winreg.REG_SZ
|
|
443
|
+
};
|
|
444
|
+
};
|
|
445
|
+
const readRegistryString = async (registry, name) => {
|
|
446
|
+
return new Promise((resolve, reject) => {
|
|
447
|
+
registry.get(name, (error, item) => {
|
|
448
|
+
if (isMissingRegistryError(error)) {
|
|
449
|
+
resolve(void 0);
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
if (error) {
|
|
453
|
+
reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
resolve(item?.value);
|
|
457
|
+
});
|
|
458
|
+
});
|
|
459
|
+
};
|
|
460
|
+
const writeRegistryString = async ({ registry, regSz, name, value }) => {
|
|
461
|
+
return new Promise((resolve, reject) => {
|
|
462
|
+
registry.set(name, regSz, value, (error) => {
|
|
463
|
+
if (error) {
|
|
464
|
+
reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
resolve();
|
|
468
|
+
});
|
|
469
|
+
});
|
|
470
|
+
};
|
|
471
|
+
const getStoredVSCodeDeviceId = async () => {
|
|
472
|
+
switch (process.platform) {
|
|
473
|
+
case "win32": {
|
|
474
|
+
const { registry } = await createWindowsRegistry();
|
|
475
|
+
return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME);
|
|
476
|
+
}
|
|
477
|
+
case "darwin":
|
|
478
|
+
case "linux": return readStoredDeviceIdFile(getDeviceIdFilePath());
|
|
479
|
+
default: throw new Error("Unsupported platform");
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
const setStoredVSCodeDeviceId = async (deviceId) => {
|
|
483
|
+
switch (process.platform) {
|
|
484
|
+
case "win32": {
|
|
485
|
+
const { registry, regSz } = await createWindowsRegistry();
|
|
486
|
+
await writeRegistryString({
|
|
487
|
+
registry,
|
|
488
|
+
regSz,
|
|
489
|
+
name: WINDOWS_DEVICE_ID_NAME,
|
|
490
|
+
value: deviceId
|
|
491
|
+
});
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
case "darwin":
|
|
495
|
+
case "linux":
|
|
496
|
+
await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId);
|
|
497
|
+
return;
|
|
498
|
+
default: throw new Error("Unsupported platform");
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
const createVSCodeDeviceId = () => randomUUID().toLowerCase();
|
|
502
|
+
async function getVSCodeDeviceId() {
|
|
503
|
+
let deviceId;
|
|
504
|
+
try {
|
|
505
|
+
deviceId = await getStoredVSCodeDeviceId();
|
|
506
|
+
} catch (error) {
|
|
507
|
+
consola.debug("Failed to read VSCode device id", error);
|
|
508
|
+
}
|
|
509
|
+
if (deviceId) return deviceId;
|
|
510
|
+
const newDeviceId = createVSCodeDeviceId();
|
|
511
|
+
try {
|
|
512
|
+
await setStoredVSCodeDeviceId(newDeviceId);
|
|
513
|
+
} catch (error) {
|
|
514
|
+
consola.warn("Failed to persist VSCode device id, using ephemeral id", error);
|
|
515
|
+
}
|
|
516
|
+
return newDeviceId;
|
|
517
|
+
}
|
|
518
|
+
|
|
255
519
|
//#endregion
|
|
256
520
|
//#region src/lib/utils.ts
|
|
257
521
|
const sleep = (ms) => new Promise((resolve) => {
|
|
@@ -294,6 +558,10 @@ const cacheMacMachineId = () => {
|
|
|
294
558
|
state.macMachineId = createHash("sha256").update(macAddress, "utf8").digest("hex");
|
|
295
559
|
consola.debug(`Using machine ID: ${state.macMachineId}`);
|
|
296
560
|
};
|
|
561
|
+
const cacheVsCodeDeviceId = async () => {
|
|
562
|
+
state.vsCodeDeviceId = await getVSCodeDeviceId();
|
|
563
|
+
consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`);
|
|
564
|
+
};
|
|
297
565
|
const SESSION_REFRESH_BASE_MS = 3600 * 1e3;
|
|
298
566
|
const SESSION_REFRESH_JITTER_MS = 1200 * 1e3;
|
|
299
567
|
let vsCodeSessionRefreshTimer = null;
|
|
@@ -390,5 +658,37 @@ const getUUID = (content) => {
|
|
|
390
658
|
};
|
|
391
659
|
|
|
392
660
|
//#endregion
|
|
393
|
-
|
|
394
|
-
|
|
661
|
+
//#region src/services/github/poll-access-token.ts
|
|
662
|
+
async function pollAccessToken(deviceCode, options) {
|
|
663
|
+
const { clientId, headers } = getOauthAppConfig();
|
|
664
|
+
const { accessTokenUrl } = options?.overrideUrls ?? getOauthUrls();
|
|
665
|
+
const sleepDuration = (deviceCode.interval + 1) * 1e3;
|
|
666
|
+
consola.debug(`Polling access token with interval of ${sleepDuration}ms`);
|
|
667
|
+
while (true) {
|
|
668
|
+
if (options?.signal?.aborted) throw new CancelledError("Authentication cancelled");
|
|
669
|
+
const response = await fetch(accessTokenUrl, {
|
|
670
|
+
method: "POST",
|
|
671
|
+
headers,
|
|
672
|
+
body: JSON.stringify({
|
|
673
|
+
client_id: clientId,
|
|
674
|
+
device_code: deviceCode.device_code,
|
|
675
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
676
|
+
}),
|
|
677
|
+
signal: options?.signal
|
|
678
|
+
});
|
|
679
|
+
if (!response.ok) {
|
|
680
|
+
await sleep(sleepDuration);
|
|
681
|
+
consola.error("Failed to poll access token:", await response.text());
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
const json = await response.json();
|
|
685
|
+
consola.debug("Polling access token response:", json);
|
|
686
|
+
const { access_token } = json;
|
|
687
|
+
if (access_token) return access_token;
|
|
688
|
+
else await sleep(sleepDuration);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
//#endregion
|
|
693
|
+
export { resolveTraceId as A, normalizeDomain as C, accountFromState as D, prepareMessageProxyHeaders as E, state as O, githubHeaders as S, prepareInteractionHeaders as T, HTTPError as _, cacheVsCodeDeviceId as a, copilotHeaders as b, getRootSessionId as c, parseUserIdMetadata as d, sleep as f, getCopilotUsage as g, getDeviceCode as h, cacheVSCodeVersion as i, initOpencodeVersion as j, requestContext as k, getUUID as l, getGitHubUser as m, cacheMacMachineId as n, cacheVsCodeSessionId as o, getModels as p, cacheModels as r, generateRequestIdFromPayload as s, pollAccessToken as t, isNullish as u, forwardError as v, prepareForCompact as w, getGitHubApiBaseUrl as x, copilotBaseUrl as y };
|
|
694
|
+
//# sourceMappingURL=poll-access-token-BzenaGHn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll-access-token-BzenaGHn.js","names":["opencodeVersionCache: string | undefined","state: State","headers: Record<string, string>","errorJson: unknown","folder: string","readFile","deviceId: string | undefined","vsCodeSessionRefreshTimer: ReturnType<typeof setTimeout> | null","parsed: unknown"],"sources":["../src/lib/opencode.ts","../src/lib/request-context.ts","../src/lib/state.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-usage.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/services/copilot/get-models.ts","../src/services/get-vscode-version.ts","../src/lib/deviceid.ts","../src/lib/utils.ts","../src/services/github/poll-access-token.ts"],"sourcesContent":["import consola from \"consola\"\nimport { exec } from \"node:child_process\"\nimport { readFile } from \"node:fs/promises\"\nimport path from \"node:path\"\n\nconst execAsync = (command: string): Promise<string> => {\n return new Promise((resolve, reject) => {\n exec(command, (error, stdout) => {\n if (error) {\n reject(error)\n return\n }\n\n resolve(stdout)\n })\n })\n}\n\nlet opencodeVersionCache: string | undefined\n\nconst getGlobalNpmRoot = async (): Promise<string> => {\n const stdout = await execAsync(\"npm root -g\")\n return stdout.trim()\n}\n\nasync function resolveOpencodeVersion(): Promise<void> {\n try {\n const npmRootPath = await getGlobalNpmRoot()\n const opencodePackagePath = path.join(\n npmRootPath,\n \"opencode-ai\",\n \"package.json\",\n )\n const packageJson = await readFile(opencodePackagePath, \"utf8\")\n const { version } = JSON.parse(packageJson) as { version: string }\n opencodeVersionCache = version\n } catch (error) {\n consola.warn(`Failed to resolve opencode version`, error)\n }\n}\n\nexport const initOpencodeVersion = (): Promise<void> => {\n if (process.env.COPILOT_API_OAUTH_APP?.trim() !== \"opencode\") {\n return Promise.resolve()\n }\n return resolveOpencodeVersion()\n}\n\nexport const getCachedOpencodeVersion = (): string | undefined => {\n return opencodeVersionCache\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\"\n\nexport interface RequestContext {\n traceId: string\n startTime: number\n userAgent: string\n sessionAffinity: string | undefined\n parentSessionId: string | undefined\n}\n\nconst TRACE_ID_MAX_LENGTH = 64\nconst TRACE_ID_PATTERN = /^\\w[\\w.-]*$/\n\nconst asyncLocalStorage = new AsyncLocalStorage<RequestContext>()\n\nexport const requestContext = {\n getStore: () => asyncLocalStorage.getStore(),\n run: <T>(context: RequestContext, callback: () => T) =>\n asyncLocalStorage.run(context, callback),\n}\n\nexport function generateTraceId(): string {\n const timestamp = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${timestamp}-${random}`\n}\n\nexport function resolveTraceId(traceId: string | null | undefined): string {\n const candidate = traceId?.trim()\n\n if (\n !candidate\n || candidate.length > TRACE_ID_MAX_LENGTH\n || !TRACE_ID_PATTERN.test(candidate)\n ) {\n return generateTraceId()\n }\n\n return candidate\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { ModelsResponse } from \"~/services/copilot/get-models\"\n\nimport type { AccountContext, AccountType } from \"./types/account\"\n\nexport interface State {\n githubToken?: string\n copilotToken?: string\n\n accountType: AccountType\n models?: ModelsResponse\n vsCodeVersion?: string\n\n macMachineId?: string\n vsCodeSessionId?: string\n vsCodeDeviceId: string\n\n manualApprove: boolean\n rateLimitWait: boolean\n showToken: boolean\n\n // Rate limiting configuration\n rateLimitSeconds?: number\n lastRequestTimestamp?: number\n verbose: boolean\n\n copilotApiUrl?: string\n}\n\nexport const state: State = {\n accountType: \"individual\",\n manualApprove: false,\n rateLimitWait: false,\n showToken: false,\n verbose: false,\n vsCodeDeviceId: randomUUID(),\n}\n\n/**\n * Create an AccountContext from the current global state.\n * This is a compatibility layer for transitioning to multi-account support.\n * @throws Error if githubToken is not set in state\n */\nexport function accountFromState(): AccountContext {\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set in state\")\n }\n return {\n githubToken: state.githubToken,\n copilotToken: state.copilotToken,\n ...(state.copilotApiUrl !== undefined ?\n { copilotApiUrl: state.copilotApiUrl }\n : {}),\n accountType: state.accountType,\n vsCodeVersion: state.vsCodeVersion,\n clientDeviceId: state.vsCodeDeviceId,\n clientMachineId: state.macMachineId,\n clientSessionId: state.vsCodeSessionId,\n }\n}\n","import { randomUUID } from \"node:crypto\"\n\nimport type { AccountContext } from \"./types/account\"\n\nimport { getCachedOpencodeVersion } from \"./opencode\"\nimport { requestContext } from \"./request-context\"\nimport { state } from \"./state\"\n\nexport const isOpencodeOauthApp = (): boolean => {\n return process.env.COPILOT_API_OAUTH_APP?.trim() === \"opencode\"\n}\n\nexport const normalizeDomain = (input: string): string => {\n return input\n .trim()\n .replace(/^https?:\\/\\//u, \"\")\n .replace(/\\/+$/u, \"\")\n}\n\nexport const getEnterpriseDomain = (): string | null => {\n const raw = (process.env.COPILOT_API_ENTERPRISE_URL ?? \"\").trim()\n if (!raw) return null\n const normalized = normalizeDomain(raw)\n return normalized || null\n}\n\nexport const getGitHubBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://${resolvedDomain}` : GITHUB_BASE_URL\n}\n\nexport const getGitHubApiBaseUrl = (): string => {\n const resolvedDomain = getEnterpriseDomain()\n return resolvedDomain ? `https://api.${resolvedDomain}` : GITHUB_API_BASE_URL\n}\n\nconst getOpencodeOauthHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": getOpencodeVersion(),\n }\n}\n\nconst getOpencodeLLMHeaders = (): Record<string, string> => {\n return {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": OPENCODE_LLM_USER_AGENT,\n }\n}\n\nconst normalizeOpencodeUserAgent = (userAgent: string): string => {\n const candidate = userAgent.trim()\n const opencodeProduct = candidate.match(/^opencode\\/[^\\s,]+/u)?.[0]\n\n if (!opencodeProduct || candidate.includes(`, ${opencodeProduct}`)) {\n return candidate\n }\n\n return `${candidate}, ${opencodeProduct}`\n}\n\nexport const getOauthUrls = (): {\n deviceCodeUrl: string\n accessTokenUrl: string\n} => {\n const githubBaseUrl = getGitHubBaseUrl()\n\n return {\n deviceCodeUrl: `${githubBaseUrl}/login/device/code`,\n accessTokenUrl: `${githubBaseUrl}/login/oauth/access_token`,\n }\n}\n\ninterface OauthAppConfig {\n clientId: string\n headers: Record<string, string>\n scope: string\n}\n\nexport const getOauthAppConfig = (): OauthAppConfig => {\n if (isOpencodeOauthApp()) {\n return {\n clientId: OPENCODE_GITHUB_CLIENT_ID,\n headers: getOpencodeOauthHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n }\n\n return {\n clientId: GITHUB_CLIENT_ID,\n headers: standardHeaders(),\n scope: GITHUB_APP_SCOPES,\n }\n}\n\nexport const prepareForCompact = (\n headers: Record<string, string>,\n isCompact?: boolean,\n) => {\n if (isCompact) {\n headers[\"x-initiator\"] = \"agent\"\n }\n}\n\nexport const prepareInteractionHeaders = (\n sessionId: string | undefined,\n isSubagent: boolean,\n headers: Record<string, string>,\n) => {\n const sendInteractionHeaders = !isOpencodeOauthApp()\n\n if (isSubagent) {\n headers[\"x-initiator\"] = \"agent\"\n if (sendInteractionHeaders) {\n headers[\"x-interaction-type\"] = \"conversation-subagent\"\n }\n }\n\n if (sessionId && sendInteractionHeaders) {\n headers[\"x-interaction-id\"] = sessionId\n }\n}\n\nexport const standardHeaders = () => ({\n \"content-type\": \"application/json\",\n accept: \"application/json\",\n})\n\nexport const getOpencodeVersion = () => {\n const version = getCachedOpencodeVersion()\n if (version) {\n return \"opencode/\" + version\n }\n return OPENCODE_VERSION\n}\n\nconst OPENCODE_VERSION = \"opencode/1.3.15\"\nconst OPENCODE_LLM_USER_AGENT =\n \"opencode/1.3.15 ai-sdk/provider-utils/4.0.21 runtime/bun/1.3.11, opencode/1.3.15\"\n\nconst COPILOT_VERSION = \"0.42.3\"\nconst EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`\nconst USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`\nconst CLAUDE_AGENT_USER_AGENT =\n \"vscode_claude_code/2.1.81 (external, sdk-ts, agent-sdk/0.2.81)\"\n\nconst API_VERSION = \"2025-10-01\"\n\nexport const copilotBaseUrl = (account: AccountContext): string => {\n const enterpriseDomain = getEnterpriseDomain()\n if (enterpriseDomain) {\n return `https://copilot-api.${enterpriseDomain}`\n }\n\n if (isOpencodeOauthApp()) {\n return \"https://api.githubcopilot.com\"\n }\n\n if (account.copilotApiUrl) {\n return account.copilotApiUrl\n }\n\n return account.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${account.accountType}.githubcopilot.com`\n}\n\nexport const prepareMessageProxyHeaders = (headers: Record<string, string>) => {\n if (isOpencodeOauthApp()) {\n return\n }\n\n // vscode copilot claude agent regenerates request id for\n // each request, keeping it consistent\n const requestIdValue = randomUUID()\n headers[\"x-agent-task-id\"] = requestIdValue\n headers[\"x-request-id\"] = requestIdValue\n\n // Consistent with vscode copilot claude agent\n headers[\"x-interaction-type\"] = \"messages-proxy\"\n headers[\"openai-intent\"] = \"messages-proxy\"\n headers[\"user-agent\"] = CLAUDE_AGENT_USER_AGENT\n}\n\nexport const githubUserHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n\n return {\n accept: \"application/vnd.github+json\",\n authorization: `token ${account.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": \"2022-11-28\",\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const copilotModelsHeaders = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n return {\n Authorization: `Bearer ${token}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n\n return githubCopilotHeaders(account)\n}\n\nexport const copilotHeaders = (\n account: AccountContext,\n vision: boolean = false,\n requestId?: string,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n const token = account.copilotToken ?? account.githubToken\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n ...getOpencodeLLMHeaders(),\n \"Openai-Intent\": \"conversation-edits\",\n }\n\n const store = requestContext.getStore()\n const userAgent = store?.userAgent.trim()\n // Real opencode traffic already carries a versioned opencode/* UA,\n // so prefer the inbound header to keep upstream behavior aligned.\n if (userAgent?.startsWith(\"opencode/\")) {\n headers[\"User-Agent\"] = normalizeOpencodeUserAgent(userAgent)\n }\n\n if (store?.sessionAffinity) {\n headers[\"x-session-affinity\"] = store.sessionAffinity\n }\n\n if (store?.parentSessionId) {\n headers[\"x-parent-session-id\"] = store.parentSessionId\n }\n\n if (vision) headers[\"Copilot-Vision-Request\"] = \"true\"\n\n return headers\n }\n\n return githubCopilotHeaders(account, requestId, vision)\n}\n\nconst githubCopilotHeaders = (\n account: AccountContext,\n requestId?: string,\n vision: boolean = false,\n): Record<string, string> => {\n const resolvedRequestId = requestId ?? randomUUID()\n const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId\n const resolvedMachineId = account.clientMachineId ?? state.macMachineId\n const resolvedSessionId = account.clientSessionId ?? state.vsCodeSessionId\n const headers: Record<string, string> = {\n Authorization: `Bearer ${account.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-version\": `vscode/${account.vsCodeVersion}`,\n \"editor-device-id\": resolvedDeviceId,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"openai-intent\": \"conversation-agent\",\n \"x-github-api-version\": API_VERSION,\n \"x-request-id\": resolvedRequestId,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n \"x-agent-task-id\": resolvedRequestId,\n \"x-interaction-type\": \"conversation-agent\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n if (resolvedMachineId) {\n headers[\"vscode-machineid\"] = resolvedMachineId\n }\n\n if (resolvedSessionId) {\n headers[\"vscode-sessionid\"] = resolvedSessionId\n }\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (account: AccountContext) => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n ...getOpencodeOauthHeaders(),\n }\n }\n\n return {\n ...standardHeaders(),\n authorization: `token ${account.githubToken}`,\n \"editor-version\": `vscode/${account.vsCodeVersion}`,\n \"editor-plugin-version\": EDITOR_PLUGIN_VERSION,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": API_VERSION,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n }\n}\n\nexport const GITHUB_BASE_URL = \"https://github.com\"\nexport const GITHUB_CLIENT_ID = \"Iv1.b507a08c87ecfe98\"\nexport const GITHUB_APP_SCOPES = [\"read:user\"].join(\" \")\nexport const OPENCODE_GITHUB_CLIENT_ID = \"Ov23li8tweQw6odWQebz\"\n","import type { Context } from \"hono\"\nimport type { ContentfulStatusCode } from \"hono/utils/http-status\"\n\nimport consola from \"consola\"\n\nexport class HTTPError extends Error {\n response: Response\n\n constructor(message: string, response: Response) {\n super(message)\n this.response = response\n }\n}\n\nexport class CancelledError extends Error {}\n\nexport async function forwardError(c: Context, error: unknown) {\n consola.error(\"Error occurred:\", error)\n\n if (error instanceof HTTPError) {\n if (error.response.status === 429) {\n for (const [name, value] of error.response.headers) {\n const lowerName = name.toLowerCase()\n if (lowerName === \"retry-after\" || lowerName.startsWith(\"x-\")) {\n c.header(name, value)\n }\n }\n }\n\n const errorText = await error.response.text()\n let errorJson: unknown\n try {\n errorJson = JSON.parse(errorText)\n } catch {\n errorJson = errorText\n }\n consola.error(\"HTTP error:\", errorJson)\n return c.json(\n {\n error: {\n message: errorText,\n type: \"error\",\n },\n },\n error.response.status as ContentfulStatusCode,\n )\n }\n\n return c.json(\n {\n error: {\n message: (error as Error).message,\n type: \"error\",\n },\n },\n 500,\n )\n}\n","import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getCopilotUsage = async (\n account?: AccountContext,\n): Promise<CopilotUsageResponse> => {\n const ctx = account ?? accountFromState()\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/user`,\n {\n headers: githubHeaders(ctx),\n },\n )\n\n if (!response.ok) {\n throw new HTTPError(\"Failed to get Copilot usage\", response)\n }\n\n return (await response.json()) as CopilotUsageResponse\n}\n\nexport interface QuotaDetail {\n entitlement: number\n overage_count: number\n overage_permitted: boolean\n percent_remaining: number\n quota_id: string\n quota_remaining: number\n remaining: number\n unlimited: boolean\n}\n\ninterface QuotaSnapshots {\n chat: QuotaDetail\n completions: QuotaDetail\n premium_interactions: QuotaDetail\n}\n\ninterface CopilotUsageResponse {\n login: string\n access_type_sku: string\n analytics_tracking_id: string\n assigned_date: string\n can_signup_for_limited: boolean\n chat_enabled: boolean\n copilot_plan: string\n organization_login_list: Array<unknown>\n organization_list: Array<unknown>\n quota_reset_date: string\n quota_snapshots: QuotaSnapshots\n endpoints: {\n api: string\n telemetry: string\n }\n}\n","import { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport interface DeviceCodeOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n}\n\nexport async function getDeviceCode(\n options?: DeviceCodeOptions,\n): Promise<DeviceCodeResponse> {\n const { clientId, headers, scope } = getOauthAppConfig()\n const { deviceCodeUrl } = options?.overrideUrls ?? getOauthUrls()\n\n const response = await fetch(deviceCodeUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n scope,\n }),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get device code\", response)\n\n return (await response.json()) as DeviceCodeResponse\n}\n\nexport interface DeviceCodeResponse {\n device_code: string\n user_code: string\n verification_uri: string\n expires_in: number\n interval: number\n}\n","import type { AccountContext } from \"~/lib/types/account\"\n\nimport { getGitHubApiBaseUrl, githubUserHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { accountFromState, state } from \"~/lib/state\"\n\nconst resolveGitHubUserAccount = (account?: AccountContext): AccountContext => {\n if (account) {\n return account\n }\n\n if (!state.githubToken) {\n throw new Error(\"GitHub token not set\")\n }\n\n return accountFromState()\n}\n\nexport async function getGitHubUser(account?: AccountContext) {\n const resolvedAccount = resolveGitHubUserAccount(account)\n\n const response = await fetch(`${getGitHubApiBaseUrl()}/user`, {\n headers: githubUserHeaders(resolvedAccount),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get GitHub user\", response)\n\n return (await response.json()) as GithubUserResponse\n}\n\n// Trimmed for the sake of simplicity\nexport interface GithubUserResponse {\n login: string\n}\n","import fs from \"node:fs/promises\"\n\nimport type { AccountContext } from \"~/lib/types/account\"\n\nimport { copilotBaseUrl, copilotModelsHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { PATHS } from \"~/lib/paths\"\nimport { accountFromState } from \"~/lib/state\"\n\nexport const getModels = async (account?: AccountContext) => {\n const ctx = account ?? accountFromState()\n const response = await fetch(`${copilotBaseUrl(ctx)}/models`, {\n headers: copilotModelsHeaders(ctx),\n })\n\n if (!response.ok) throw new HTTPError(\"Failed to get models\", response)\n\n const models = (await response.json()) as ModelsResponse\n\n // Persist models response for debugging/inspection.\n // Best effort: do not fail startup if the local write fails.\n try {\n await fs.mkdir(PATHS.APP_DIR, { recursive: true })\n await fs.writeFile(\n PATHS.MODELS_PATH,\n `${JSON.stringify(models, null, 2)}\\n`,\n {\n encoding: \"utf8\",\n mode: 0o600,\n },\n )\n } catch {\n // ignore\n }\n\n return models\n}\n\nexport interface ModelsResponse {\n data: Array<Model>\n object: string\n}\n\ninterface ModelLimits {\n max_context_window_tokens?: number\n max_output_tokens?: number\n max_prompt_tokens?: number\n max_inputs?: number\n}\n\ninterface ModelSupports {\n max_thinking_budget?: number\n min_thinking_budget?: number\n tool_calls?: boolean\n parallel_tool_calls?: boolean\n dimensions?: boolean\n streaming?: boolean\n structured_outputs?: boolean\n vision?: boolean\n adaptive_thinking?: boolean\n}\n\ninterface ModelCapabilities {\n family: string\n limits: ModelLimits\n object: string\n supports: ModelSupports\n tokenizer: string\n type: string\n}\n\ninterface ModelBilling {\n is_premium?: boolean\n multiplier?: number\n}\n\nexport interface Model {\n billing?: ModelBilling\n capabilities: ModelCapabilities\n id: string\n model_picker_enabled: boolean\n name: string\n object: string\n preview: boolean\n vendor: string\n version: string\n policy?: {\n state: string\n terms: string\n }\n supported_endpoints?: Array<string>\n}\n","const FALLBACK = \"1.114.0\"\n\nexport async function getVSCodeVersion() {\n await Promise.resolve()\n return FALLBACK\n}\n","import consola from \"consola\"\nimport { randomUUID } from \"node:crypto\"\nimport path from \"node:path\"\n\nconst WINDOWS_DEVICE_ID_KEY = String.raw`\\SOFTWARE\\Microsoft\\DeveloperTools`\nconst WINDOWS_DEVICE_ID_NAME = \"deviceid\"\n\ntype RegistryArch = \"x86\" | \"x64\"\n\ninterface WinregConstructor {\n new (options: {\n hive: string\n key: string\n arch?: RegistryArch\n }): WinregRegistry\n HKCU: string\n REG_SZ: string\n}\n\ninterface WinregRegistry {\n get(\n name: string,\n callback: (error: RegistryError | null, item: RegistryItem | null) => void,\n ): void\n set(\n name: string,\n type: string,\n value: string,\n callback: (error: RegistryError | null) => void,\n ): void\n}\n\ninterface RegistryItem {\n value?: string\n}\n\ninterface RegistryError extends Error {\n code?: number | string\n}\n\nconst windows64Architectures = new Set([\"AMD64\", \"ARM64\", \"IA64\"])\n\nconst getPosixHomeDir = (): string => {\n if (!process.env.HOME) {\n throw new Error(\"Home directory not found\")\n }\n\n return process.env.HOME\n}\n\nconst getDeviceIdFilePath = (): string => {\n let folder: string\n\n switch (process.platform) {\n case \"darwin\": {\n folder = path.posix.join(\n getPosixHomeDir(),\n \"Library\",\n \"Application Support\",\n )\n break\n }\n case \"linux\": {\n folder =\n process.env.XDG_CACHE_HOME\n ?? path.posix.join(getPosixHomeDir(), \".cache\")\n break\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n\n return path.posix.join(folder, \"Microsoft\", \"DeveloperTools\", \"deviceid\")\n}\n\nconst isMissingFileError = (error: unknown): error is NodeJS.ErrnoException => {\n return error instanceof Error && \"code\" in error && error.code === \"ENOENT\"\n}\n\nconst readStoredDeviceIdFile = async (\n filePath: string,\n): Promise<string | undefined> => {\n const { readFile } = await import(\"node:fs/promises\")\n\n try {\n return await readFile(filePath, \"utf8\")\n } catch (error) {\n if (isMissingFileError(error)) {\n return undefined\n }\n\n throw error\n }\n}\n\nconst writeStoredDeviceIdFile = async (\n filePath: string,\n deviceId: string,\n): Promise<void> => {\n const { mkdir, writeFile } = await import(\"node:fs/promises\")\n\n await mkdir(path.posix.dirname(filePath), { recursive: true })\n await writeFile(filePath, deviceId, \"utf8\")\n}\n\nconst getWindowsRegistryArch = (): RegistryArch | undefined => {\n const architecture = (\n process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE\n )?.toUpperCase()\n\n return architecture && windows64Architectures.has(architecture) ?\n \"x64\"\n : undefined\n}\n\nconst loadWinreg = async (): Promise<WinregConstructor> => {\n const module = await import(\"winreg\")\n const winreg =\n \"default\" in module ? (module.default as unknown) : (module as unknown)\n\n return winreg as WinregConstructor\n}\n\nconst isMissingRegistryError = (error: RegistryError | null): boolean => {\n if (!error) {\n return false\n }\n\n const errorCode = Number(error.code)\n\n return Number.isFinite(errorCode) && errorCode === 1\n}\n\nconst createWindowsRegistry = async (): Promise<{\n registry: WinregRegistry\n regSz: string\n}> => {\n const Winreg = await loadWinreg()\n\n return {\n registry: new Winreg({\n hive: Winreg.HKCU,\n key: WINDOWS_DEVICE_ID_KEY,\n arch: getWindowsRegistryArch(),\n }),\n regSz: Winreg.REG_SZ,\n }\n}\n\nconst readRegistryString = async (\n registry: WinregRegistry,\n name: string,\n): Promise<string | undefined> => {\n return new Promise((resolve, reject) => {\n registry.get(name, (error, item) => {\n if (isMissingRegistryError(error)) {\n resolve(undefined)\n return\n }\n\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve(item?.value)\n })\n })\n}\n\nconst writeRegistryString = async ({\n registry,\n regSz,\n name,\n value,\n}: {\n registry: WinregRegistry\n regSz: string\n name: string\n value: string\n}): Promise<void> => {\n return new Promise((resolve, reject) => {\n registry.set(name, regSz, value, (error) => {\n if (error) {\n reject(\n error instanceof Error ? error : new Error(\"Unknown registry error\"),\n )\n return\n }\n\n resolve()\n })\n })\n}\n\nexport const getStoredVSCodeDeviceId = async (): Promise<\n string | undefined\n> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry } = await createWindowsRegistry()\n\n return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME)\n }\n case \"darwin\":\n case \"linux\": {\n return readStoredDeviceIdFile(getDeviceIdFilePath())\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst setStoredVSCodeDeviceId = async (deviceId: string): Promise<void> => {\n switch (process.platform) {\n case \"win32\": {\n const { registry, regSz } = await createWindowsRegistry()\n\n await writeRegistryString({\n registry,\n regSz,\n name: WINDOWS_DEVICE_ID_NAME,\n value: deviceId,\n })\n return\n }\n case \"darwin\":\n case \"linux\": {\n await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId)\n return\n }\n default: {\n throw new Error(\"Unsupported platform\")\n }\n }\n}\n\nconst createVSCodeDeviceId = (): string => randomUUID().toLowerCase()\n\nexport async function getVSCodeDeviceId(): Promise<string> {\n let deviceId: string | undefined\n\n try {\n deviceId = await getStoredVSCodeDeviceId()\n } catch (error) {\n consola.debug(\"Failed to read VSCode device id\", error)\n }\n\n if (deviceId) {\n return deviceId\n }\n\n const newDeviceId = createVSCodeDeviceId()\n\n try {\n await setStoredVSCodeDeviceId(newDeviceId)\n } catch (error) {\n consola.warn(\n \"Failed to persist VSCode device id, using ephemeral id\",\n error,\n )\n }\n\n return newDeviceId\n}\n","import type { Context } from \"hono\"\n\nimport consola from \"consola\"\nimport { createHash, randomUUID } from \"node:crypto\"\nimport { networkInterfaces } from \"node:os\"\n\nimport type { AnthropicMessagesPayload } from \"~/routes/messages/anthropic-types\"\n\nimport { getModels } from \"~/services/copilot/get-models\"\nimport { getVSCodeVersion } from \"~/services/get-vscode-version\"\n\nimport { getVSCodeDeviceId } from \"./deviceid\"\nimport { state } from \"./state\"\n\nexport const sleep = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms)\n })\n\nexport const isNullish = (value: unknown): value is null | undefined =>\n value === null || value === undefined\n\nexport async function cacheModels(): Promise<void> {\n const models = await getModels()\n state.models = {\n ...models,\n data: models.data.filter(\n (model) =>\n model.model_picker_enabled || model.capabilities.type === \"embeddings\",\n ),\n }\n}\n\nexport const cacheVSCodeVersion = async () => {\n const response = await getVSCodeVersion()\n state.vsCodeVersion = response\n\n consola.info(`Using VSCode version: ${response}`)\n}\n\nconst invalidMacAddresses = new Set([\n \"00:00:00:00:00:00\",\n \"ff:ff:ff:ff:ff:ff\",\n \"ac:de:48:00:11:22\",\n])\n\nfunction validateMacAddress(candidate: string): boolean {\n const tempCandidate = candidate.replaceAll(\"-\", \":\").toLowerCase()\n return !invalidMacAddresses.has(tempCandidate)\n}\n\nexport function getMac(): string | null {\n const ifaces = networkInterfaces()\n // eslint-disable-next-line guard-for-in\n for (const name in ifaces) {\n const networkInterface = ifaces[name]\n if (networkInterface) {\n for (const { mac } of networkInterface) {\n if (validateMacAddress(mac)) {\n return mac\n }\n }\n }\n }\n return null\n}\n\nexport const cacheMacMachineId = () => {\n const macAddress = getMac() ?? randomUUID()\n state.macMachineId = createHash(\"sha256\")\n .update(macAddress, \"utf8\")\n .digest(\"hex\")\n consola.debug(`Using machine ID: ${state.macMachineId}`)\n}\n\nexport const cacheVsCodeDeviceId = async () => {\n state.vsCodeDeviceId = await getVSCodeDeviceId()\n consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`)\n}\n\nconst SESSION_REFRESH_BASE_MS = 60 * 60 * 1000\nconst SESSION_REFRESH_JITTER_MS = 20 * 60 * 1000\nlet vsCodeSessionRefreshTimer: ReturnType<typeof setTimeout> | null = null\n\nconst generateSessionId = () => {\n state.vsCodeSessionId = randomUUID() + Date.now().toString()\n consola.debug(`Generated VSCode session ID: ${state.vsCodeSessionId}`)\n}\n\nexport const stopVsCodeSessionRefreshLoop = () => {\n if (vsCodeSessionRefreshTimer) {\n clearTimeout(vsCodeSessionRefreshTimer)\n vsCodeSessionRefreshTimer = null\n }\n}\n\nconst scheduleSessionIdRefresh = () => {\n const randomDelay = Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS)\n const delay = SESSION_REFRESH_BASE_MS + randomDelay\n consola.debug(\n `Scheduling next VSCode session ID refresh in ${Math.round(\n delay / 1000,\n )} seconds`,\n )\n\n stopVsCodeSessionRefreshLoop()\n vsCodeSessionRefreshTimer = setTimeout(() => {\n try {\n generateSessionId()\n } catch (error) {\n consola.error(\"Failed to refresh session ID, rescheduling...\", error)\n } finally {\n scheduleSessionIdRefresh()\n }\n }, delay)\n}\n\nexport const cacheVsCodeSessionId = () => {\n stopVsCodeSessionRefreshLoop()\n generateSessionId()\n scheduleSessionIdRefresh()\n}\n\ninterface PayloadMessage {\n role?: string\n content?: string | Array<{ type?: string; text?: string }> | null\n type?: string\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null\n\nconst getUserIdJsonField = (\n userIdPayload: Record<string, unknown> | null,\n field: string,\n): string | null => {\n const value = userIdPayload?.[field]\n return typeof value === \"string\" && value.length > 0 ? value : null\n}\n\nconst parseJsonUserId = (userId: string): Record<string, unknown> | null => {\n try {\n const parsed: unknown = JSON.parse(userId)\n return isRecord(parsed) ? parsed : null\n } catch {\n return null\n }\n}\n\nexport const parseUserIdMetadata = (\n userId: string | undefined,\n): { safetyIdentifier: string | null; sessionId: string | null } => {\n if (!userId || typeof userId !== \"string\") {\n return { safetyIdentifier: null, sessionId: null }\n }\n\n const legacySafetyIdentifier =\n userId.match(/user_([^_]+)_account/)?.[1] ?? null\n const legacySessionId = userId.match(/_session_(.+)$/)?.[1] ?? null\n\n const parsedUserId =\n legacySafetyIdentifier && legacySessionId ? null : parseJsonUserId(userId)\n\n const safetyIdentifier =\n legacySafetyIdentifier\n ?? getUserIdJsonField(parsedUserId, \"device_id\")\n ?? getUserIdJsonField(parsedUserId, \"account_uuid\")\n const sessionId =\n legacySessionId ?? getUserIdJsonField(parsedUserId, \"session_id\")\n\n return { safetyIdentifier, sessionId }\n}\n\nconst findLastUserContent = (\n messages: Array<PayloadMessage>,\n): string | null => {\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i]\n if (msg.role === \"user\" && msg.content) {\n if (typeof msg.content === \"string\") {\n return msg.content\n } else if (Array.isArray(msg.content)) {\n const array = msg.content\n .filter((n) => n.type !== \"tool_result\")\n .map((n) => ({ ...n, cache_control: undefined }))\n if (array.length > 0) {\n return JSON.stringify(array)\n }\n }\n }\n }\n return null\n}\n\nexport const generateRequestIdFromPayload = (\n payload: {\n messages: string | Array<PayloadMessage> | undefined\n },\n sessionId?: string,\n): string => {\n const messages = payload.messages\n if (messages) {\n const lastUserContent =\n typeof messages === \"string\" ? messages : findLastUserContent(messages)\n\n if (lastUserContent) {\n return getUUID(\n (sessionId ?? \"\") + (state.macMachineId ?? \"\") + lastUserContent,\n )\n }\n }\n\n return randomUUID()\n}\n\nexport const getRootSessionId = (\n anthropicPayload: AnthropicMessagesPayload,\n c: Context,\n): string | undefined => {\n const userId = anthropicPayload.metadata?.user_id\n const sessionId =\n userId ?\n parseUserIdMetadata(userId).sessionId || undefined\n : c.req.header(\"x-session-id\")\n\n return sessionId ? getUUID(sessionId) : sessionId\n}\n\nexport const getUUID = (content: string): string => {\n const uuidBytes = createHash(\"sha256\")\n .update(content)\n .digest()\n .subarray(0, 16)\n\n uuidBytes[6] = (uuidBytes[6] & 0x0f) | 0x40\n uuidBytes[8] = (uuidBytes[8] & 0x3f) | 0x80\n\n const uuidHex = uuidBytes.toString(\"hex\")\n\n return `${uuidHex.slice(0, 8)}-${uuidHex.slice(8, 12)}-${uuidHex.slice(12, 16)}-${uuidHex.slice(16, 20)}-${uuidHex.slice(20)}`\n}\n","import consola from \"consola\"\n\nimport { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { CancelledError } from \"~/lib/error\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport interface PollAccessTokenOptions {\n overrideUrls?: {\n deviceCodeUrl: string\n accessTokenUrl: string\n }\n signal?: AbortSignal\n}\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n options?: PollAccessTokenOptions,\n): Promise<string> {\n const { clientId, headers } = getOauthAppConfig()\n const { accessTokenUrl } = options?.overrideUrls ?? getOauthUrls()\n\n // Interval is in seconds, we need to multiply by 1000 to get milliseconds\n // I'm also adding another second, just to be safe\n const sleepDuration = (deviceCode.interval + 1) * 1000\n consola.debug(`Polling access token with interval of ${sleepDuration}ms`)\n\n while (true) {\n if (options?.signal?.aborted) {\n throw new CancelledError(\"Authentication cancelled\")\n }\n\n const response = await fetch(accessTokenUrl, {\n method: \"POST\",\n headers,\n body: JSON.stringify({\n client_id: clientId,\n device_code: deviceCode.device_code,\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n }),\n signal: options?.signal,\n })\n\n if (!response.ok) {\n await sleep(sleepDuration)\n consola.error(\"Failed to poll access token:\", await response.text())\n\n continue\n }\n\n const json = await response.json()\n consola.debug(\"Polling access token response:\", json)\n\n const { access_token } = json as AccessTokenResponse\n\n if (access_token) {\n return access_token\n } else {\n await sleep(sleepDuration)\n }\n }\n}\n\ninterface AccessTokenResponse {\n access_token: string\n token_type: string\n scope: string\n}\n"],"mappings":"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"}
|