@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.
Files changed (40) hide show
  1. package/README.md +5 -3
  2. package/dist/account-BMFr8t9b.js +362 -0
  3. package/dist/account-BMFr8t9b.js.map +1 -0
  4. package/dist/{accounts-manager-Cjrd_el_.js → accounts-manager-DgQH4KtO.js} +114 -13
  5. package/dist/accounts-manager-DgQH4KtO.js.map +1 -0
  6. package/dist/admin/assets/index-519a65q_.js +66 -0
  7. package/dist/admin/assets/index-ChMaMig2.css +1 -0
  8. package/dist/admin/index.html +2 -2
  9. package/dist/{auth-1gAffrpI.js → auth-DipSy-jV.js} +6 -12
  10. package/dist/auth-DipSy-jV.js.map +1 -0
  11. package/dist/{check-usage-CsRu467P.js → check-usage-Dbjs73E0.js} +5 -5
  12. package/dist/check-usage-Dbjs73E0.js.map +1 -0
  13. package/dist/{debug-BzR5ZQUk.js → debug-BJfZVBB7.js} +2 -2
  14. package/dist/{debug-BzR5ZQUk.js.map → debug-BJfZVBB7.js.map} +1 -1
  15. package/dist/{get-copilot-token-BbpphnmV.js → get-copilot-token-DoK8Ia3u.js} +2 -2
  16. package/dist/{get-copilot-token-BbpphnmV.js.map → get-copilot-token-DoK8Ia3u.js.map} +1 -1
  17. package/dist/main.js +4 -4
  18. package/dist/{paths-Cvzy-eLX.js → paths-DGlr310R.js} +2 -2
  19. package/dist/{paths-Cvzy-eLX.js.map → paths-DGlr310R.js.map} +1 -1
  20. package/dist/{utils-DY-jLXwO.js → poll-access-token-BzenaGHn.js} +352 -52
  21. package/dist/poll-access-token-BzenaGHn.js.map +1 -0
  22. package/dist/{server-DqwhClJ-.js → server-DzE_zmUf.js} +498 -136
  23. package/dist/server-DzE_zmUf.js.map +1 -0
  24. package/dist/{start-B1_Ols5Z.js → start-DEugVHqn.js} +26 -15
  25. package/dist/start-DEugVHqn.js.map +1 -0
  26. package/package.json +1 -1
  27. package/dist/account-CipKmikF.js +0 -17
  28. package/dist/account-CipKmikF.js.map +0 -1
  29. package/dist/accounts-manager-Cjrd_el_.js.map +0 -1
  30. package/dist/accounts-registry-CQYvRe65.js +0 -180
  31. package/dist/accounts-registry-CQYvRe65.js.map +0 -1
  32. package/dist/admin/assets/index-BFvCJZIK.js +0 -57
  33. package/dist/admin/assets/index-CsAeel_7.css +0 -1
  34. package/dist/auth-1gAffrpI.js.map +0 -1
  35. package/dist/check-usage-CsRu467P.js.map +0 -1
  36. package/dist/poll-access-token-CGfLFzMq.js +0 -52
  37. package/dist/poll-access-token-CGfLFzMq.js.map +0 -1
  38. package/dist/server-DqwhClJ-.js.map +0 -1
  39. package/dist/start-B1_Ols5Z.js.map +0 -1
  40. package/dist/utils-DY-jLXwO.js.map +0 -1
@@ -1,32 +1,45 @@
1
- import { t as PATHS } from "./paths-Cvzy-eLX.js";
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/state.ts
9
- const state = {
10
- accountType: "individual",
11
- manualApprove: false,
12
- rateLimitWait: false,
13
- showToken: false,
14
- verbose: false
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
- * Create an AccountContext from the current global state.
18
- * This is a compatibility layer for transitioning to multi-account support.
19
- * @throws Error if githubToken is not set in state
20
- */
21
- function accountFromState() {
22
- if (!state.githubToken) throw new Error("GitHub token not set in state");
23
- return {
24
- githubToken: state.githubToken,
25
- copilotToken: state.copilotToken,
26
- accountType: state.accountType,
27
- vsCodeVersion: state.vsCodeVersion
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": "opencode/1.3.9 ai-sdk/provider-utils/4.0.21 runtime/bun/1.3.11, opencode/1.3.9"
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 COPILOT_VERSION = "0.38.2";
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$1 = {
216
+ const headers = {
129
217
  Authorization: `Bearer ${account.copilotToken ?? account.githubToken}`,
130
- ...getOpencodeOauthHeaders(),
218
+ ...getOpencodeLLMHeaders(),
131
219
  "Openai-Intent": "conversation-edits"
132
220
  };
133
- const userAgent = requestContext.getStore()?.userAgent.trim();
134
- if (userAgent?.startsWith("opencode/")) headers$1["User-Agent"] = normalizeOpencodeUserAgent(userAgent);
135
- if (vision) headers$1["Copilot-Vision-Request"] = "true";
136
- return headers$1;
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 (state.macMachineId) headers["vscode-machineid"] = state.macMachineId;
155
- if (state.vsCodeSessionId) headers["vscode-sessionid"] = state.vsCodeSessionId;
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
- ...standardHeaders(),
161
- authorization: `token ${account.githubToken}`,
162
- "editor-version": `vscode/${account.vsCodeVersion}`,
163
- "editor-plugin-version": EDITOR_PLUGIN_VERSION,
164
- "user-agent": USER_AGENT,
165
- "x-github-api-version": API_VERSION,
166
- "x-vscode-user-agent-library-version": "electron-fetch"
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 token = account?.githubToken ?? state.githubToken;
221
- if (!token) throw new Error("GitHub token not set");
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: copilotHeaders(ctx) });
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.110.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
- export { prepareInteractionHeaders as C, state as D, accountFromState as E, prepareForCompact as S, resolveTraceId as T, copilotHeaders as _, generateRequestIdFromPayload as a, getOauthUrls as b, isNullish as c, getModels as d, getGitHubUser as f, copilotBaseUrl as g, forwardError as h, cacheVsCodeSessionId as i, parseUserIdMetadata as l, HTTPError as m, cacheModels as n, getRootSessionId as o, getCopilotUsage as p, cacheVSCodeVersion as r, getUUID as s, cacheMacMachineId as t, sleep as u, getGitHubApiBaseUrl as v, requestContext as w, githubHeaders as x, getOauthAppConfig as y };
394
- //# sourceMappingURL=utils-DY-jLXwO.js.map
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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"}