@nick3/copilot-api 1.5.2 → 1.5.5
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-AacnHem5.js +362 -0
- package/dist/account-AacnHem5.js.map +1 -0
- package/dist/{accounts-manager-DhwGrhHF.js → accounts-manager-BevCBoaF.js} +96 -7
- package/dist/accounts-manager-BevCBoaF.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-BtUQnU2m.js → auth-B7x3wjry.js} +6 -12
- package/dist/auth-B7x3wjry.js.map +1 -0
- package/dist/{check-usage-DiomC9Dl.js → check-usage-B1cbDEOI.js} +4 -5
- package/dist/{check-usage-DiomC9Dl.js.map → check-usage-B1cbDEOI.js.map} +1 -1
- 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-DN1P6qll.js → get-copilot-token-cha9rQwA.js} +2 -2
- package/dist/{get-copilot-token-DN1P6qll.js.map → get-copilot-token-cha9rQwA.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-53JWve7i.js → poll-access-token-DFooFWhY.js} +339 -46
- package/dist/poll-access-token-DFooFWhY.js.map +1 -0
- package/dist/{server-D9M_wFyO.js → server-CuXJhEMC.js} +495 -140
- package/dist/server-CuXJhEMC.js.map +1 -0
- package/dist/{start-D3yEfZnW.js → start-D6O1XcfI.js} +26 -15
- package/dist/start-D6O1XcfI.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-DhwGrhHF.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-B-G_GrPI.js +0 -57
- package/dist/admin/assets/index-CsAeel_7.css +0 -1
- package/dist/auth-BtUQnU2m.js.map +0 -1
- package/dist/poll-access-token-BrRUFB1F.js +0 -52
- package/dist/poll-access-token-BrRUFB1F.js.map +0 -1
- package/dist/server-D9M_wFyO.js.map +0 -1
- package/dist/start-D3yEfZnW.js.map +0 -1
- package/dist/utils-53JWve7i.js.map +0 -1
|
@@ -1,17 +1,73 @@
|
|
|
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";
|
|
9
|
+
|
|
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
|
+
});
|
|
21
|
+
};
|
|
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
|
+
}
|
|
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
|
+
};
|
|
43
|
+
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/lib/request-context.ts
|
|
46
|
+
const TRACE_ID_MAX_LENGTH = 64;
|
|
47
|
+
const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
|
|
48
|
+
const asyncLocalStorage = new AsyncLocalStorage();
|
|
49
|
+
const requestContext = {
|
|
50
|
+
getStore: () => asyncLocalStorage.getStore(),
|
|
51
|
+
run: (context, callback) => asyncLocalStorage.run(context, callback)
|
|
52
|
+
};
|
|
53
|
+
function generateTraceId() {
|
|
54
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
55
|
+
}
|
|
56
|
+
function resolveTraceId(traceId) {
|
|
57
|
+
const candidate = traceId?.trim();
|
|
58
|
+
if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
|
|
59
|
+
return candidate;
|
|
60
|
+
}
|
|
7
61
|
|
|
62
|
+
//#endregion
|
|
8
63
|
//#region src/lib/state.ts
|
|
9
64
|
const state = {
|
|
10
65
|
accountType: "individual",
|
|
11
66
|
manualApprove: false,
|
|
12
67
|
rateLimitWait: false,
|
|
13
68
|
showToken: false,
|
|
14
|
-
verbose: false
|
|
69
|
+
verbose: false,
|
|
70
|
+
vsCodeDeviceId: randomUUID()
|
|
15
71
|
};
|
|
16
72
|
/**
|
|
17
73
|
* Create an AccountContext from the current global state.
|
|
@@ -25,28 +81,13 @@ function accountFromState() {
|
|
|
25
81
|
copilotToken: state.copilotToken,
|
|
26
82
|
...state.copilotApiUrl !== void 0 ? { copilotApiUrl: state.copilotApiUrl } : {},
|
|
27
83
|
accountType: state.accountType,
|
|
28
|
-
vsCodeVersion: state.vsCodeVersion
|
|
84
|
+
vsCodeVersion: state.vsCodeVersion,
|
|
85
|
+
clientDeviceId: state.vsCodeDeviceId,
|
|
86
|
+
clientMachineId: state.macMachineId,
|
|
87
|
+
clientSessionId: state.vsCodeSessionId
|
|
29
88
|
};
|
|
30
89
|
}
|
|
31
90
|
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/lib/request-context.ts
|
|
34
|
-
const TRACE_ID_MAX_LENGTH = 64;
|
|
35
|
-
const TRACE_ID_PATTERN = /^\w[\w.-]*$/;
|
|
36
|
-
const asyncLocalStorage = new AsyncLocalStorage();
|
|
37
|
-
const requestContext = {
|
|
38
|
-
getStore: () => asyncLocalStorage.getStore(),
|
|
39
|
-
run: (context, callback) => asyncLocalStorage.run(context, callback)
|
|
40
|
-
};
|
|
41
|
-
function generateTraceId() {
|
|
42
|
-
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
43
|
-
}
|
|
44
|
-
function resolveTraceId(traceId) {
|
|
45
|
-
const candidate = traceId?.trim();
|
|
46
|
-
if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
|
|
47
|
-
return candidate;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
91
|
//#endregion
|
|
51
92
|
//#region src/lib/api-config.ts
|
|
52
93
|
const isOpencodeOauthApp = () => {
|
|
@@ -72,7 +113,14 @@ const getOpencodeOauthHeaders = () => {
|
|
|
72
113
|
return {
|
|
73
114
|
Accept: "application/json",
|
|
74
115
|
"Content-Type": "application/json",
|
|
75
|
-
"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
|
|
76
124
|
};
|
|
77
125
|
};
|
|
78
126
|
const normalizeOpencodeUserAgent = (userAgent) => {
|
|
@@ -115,9 +163,17 @@ const standardHeaders = () => ({
|
|
|
115
163
|
"content-type": "application/json",
|
|
116
164
|
accept: "application/json"
|
|
117
165
|
});
|
|
118
|
-
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";
|
|
119
174
|
const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
|
|
120
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)";
|
|
121
177
|
const API_VERSION = "2025-10-01";
|
|
122
178
|
const copilotBaseUrl = (account) => {
|
|
123
179
|
const enterpriseDomain = getEnterpriseDomain();
|
|
@@ -126,24 +182,68 @@ const copilotBaseUrl = (account) => {
|
|
|
126
182
|
if (account.copilotApiUrl) return account.copilotApiUrl;
|
|
127
183
|
return account.accountType === "individual" ? "https://api.githubcopilot.com" : `https://api.${account.accountType}.githubcopilot.com`;
|
|
128
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
|
+
const headers = githubCopilotHeaders(account);
|
|
213
|
+
headers["x-interaction-type"] = "model-access";
|
|
214
|
+
headers["openai-intent"] = "model-access";
|
|
215
|
+
delete headers["x-interaction-id"];
|
|
216
|
+
delete headers["content-type"];
|
|
217
|
+
return headers;
|
|
218
|
+
};
|
|
129
219
|
const copilotHeaders = (account, vision = false, requestId) => {
|
|
130
220
|
if (isOpencodeOauthApp()) {
|
|
131
|
-
const headers
|
|
221
|
+
const headers = {
|
|
132
222
|
Authorization: `Bearer ${account.copilotToken ?? account.githubToken}`,
|
|
133
|
-
...
|
|
223
|
+
...getOpencodeLLMHeaders(),
|
|
134
224
|
"Openai-Intent": "conversation-edits"
|
|
135
225
|
};
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
if (
|
|
139
|
-
|
|
226
|
+
const store = requestContext.getStore();
|
|
227
|
+
const userAgent = store?.userAgent.trim();
|
|
228
|
+
if (userAgent?.startsWith("opencode/")) headers["User-Agent"] = normalizeOpencodeUserAgent(userAgent);
|
|
229
|
+
if (store?.sessionAffinity) headers["x-session-affinity"] = store.sessionAffinity;
|
|
230
|
+
if (store?.parentSessionId) headers["x-parent-session-id"] = store.parentSessionId;
|
|
231
|
+
if (vision) headers["Copilot-Vision-Request"] = "true";
|
|
232
|
+
return headers;
|
|
140
233
|
}
|
|
234
|
+
return githubCopilotHeaders(account, requestId, vision);
|
|
235
|
+
};
|
|
236
|
+
const githubCopilotHeaders = (account, requestId, vision = false) => {
|
|
141
237
|
const resolvedRequestId = requestId ?? randomUUID();
|
|
238
|
+
const resolvedDeviceId = account.clientDeviceId ?? state.vsCodeDeviceId;
|
|
239
|
+
const resolvedMachineId = account.clientMachineId ?? state.macMachineId;
|
|
240
|
+
const resolvedSessionId = account.clientSessionId ?? state.vsCodeSessionId;
|
|
142
241
|
const headers = {
|
|
143
242
|
Authorization: `Bearer ${account.copilotToken}`,
|
|
144
243
|
"content-type": standardHeaders()["content-type"],
|
|
145
244
|
"copilot-integration-id": "vscode-chat",
|
|
146
245
|
"editor-version": `vscode/${account.vsCodeVersion}`,
|
|
246
|
+
"editor-device-id": resolvedDeviceId,
|
|
147
247
|
"editor-plugin-version": EDITOR_PLUGIN_VERSION,
|
|
148
248
|
"user-agent": USER_AGENT,
|
|
149
249
|
"openai-intent": "conversation-agent",
|
|
@@ -154,8 +254,8 @@ const copilotHeaders = (account, vision = false, requestId) => {
|
|
|
154
254
|
"x-interaction-type": "conversation-agent"
|
|
155
255
|
};
|
|
156
256
|
if (vision) headers["copilot-vision-request"] = "true";
|
|
157
|
-
if (
|
|
158
|
-
if (
|
|
257
|
+
if (resolvedMachineId) headers["vscode-machineid"] = resolvedMachineId;
|
|
258
|
+
if (resolvedSessionId) headers["vscode-sessionid"] = resolvedSessionId;
|
|
159
259
|
return headers;
|
|
160
260
|
};
|
|
161
261
|
const GITHUB_API_BASE_URL = "https://api.github.com";
|
|
@@ -165,10 +265,7 @@ const githubHeaders = (account) => {
|
|
|
165
265
|
...getOpencodeOauthHeaders()
|
|
166
266
|
};
|
|
167
267
|
return {
|
|
168
|
-
...standardHeaders(),
|
|
169
268
|
authorization: `token ${account.githubToken}`,
|
|
170
|
-
"editor-version": `vscode/${account.vsCodeVersion}`,
|
|
171
|
-
"editor-plugin-version": EDITOR_PLUGIN_VERSION,
|
|
172
269
|
"user-agent": USER_AGENT,
|
|
173
270
|
"x-github-api-version": API_VERSION,
|
|
174
271
|
"x-vscode-user-agent-library-version": "electron-fetch"
|
|
@@ -188,6 +285,7 @@ var HTTPError = class extends Error {
|
|
|
188
285
|
this.response = response;
|
|
189
286
|
}
|
|
190
287
|
};
|
|
288
|
+
var CancelledError = class extends Error {};
|
|
191
289
|
async function forwardError(c, error) {
|
|
192
290
|
consola.error("Error occurred:", error);
|
|
193
291
|
if (error instanceof HTTPError) {
|
|
@@ -223,15 +321,33 @@ const getCopilotUsage = async (account) => {
|
|
|
223
321
|
return await response.json();
|
|
224
322
|
};
|
|
225
323
|
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/services/github/get-device-code.ts
|
|
326
|
+
async function getDeviceCode(options) {
|
|
327
|
+
const { clientId, headers, scope } = getOauthAppConfig();
|
|
328
|
+
const { deviceCodeUrl } = options?.overrideUrls ?? getOauthUrls();
|
|
329
|
+
const response = await fetch(deviceCodeUrl, {
|
|
330
|
+
method: "POST",
|
|
331
|
+
headers,
|
|
332
|
+
body: JSON.stringify({
|
|
333
|
+
client_id: clientId,
|
|
334
|
+
scope
|
|
335
|
+
})
|
|
336
|
+
});
|
|
337
|
+
if (!response.ok) throw new HTTPError("Failed to get device code", response);
|
|
338
|
+
return await response.json();
|
|
339
|
+
}
|
|
340
|
+
|
|
226
341
|
//#endregion
|
|
227
342
|
//#region src/services/github/get-user.ts
|
|
343
|
+
const resolveGitHubUserAccount = (account) => {
|
|
344
|
+
if (account) return account;
|
|
345
|
+
if (!state.githubToken) throw new Error("GitHub token not set");
|
|
346
|
+
return accountFromState();
|
|
347
|
+
};
|
|
228
348
|
async function getGitHubUser(account) {
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
const response = await fetch(`${getGitHubApiBaseUrl()}/user`, { headers: {
|
|
232
|
-
authorization: `token ${token}`,
|
|
233
|
-
...standardHeaders()
|
|
234
|
-
} });
|
|
349
|
+
const resolvedAccount = resolveGitHubUserAccount(account);
|
|
350
|
+
const response = await fetch(`${getGitHubApiBaseUrl()}/user`, { headers: githubUserHeaders(resolvedAccount) });
|
|
235
351
|
if (!response.ok) throw new HTTPError("Failed to get GitHub user", response);
|
|
236
352
|
return await response.json();
|
|
237
353
|
}
|
|
@@ -240,7 +356,7 @@ async function getGitHubUser(account) {
|
|
|
240
356
|
//#region src/services/copilot/get-models.ts
|
|
241
357
|
const getModels = async (account) => {
|
|
242
358
|
const ctx = account ?? accountFromState();
|
|
243
|
-
const response = await fetch(`${copilotBaseUrl(ctx)}/models`, { headers:
|
|
359
|
+
const response = await fetch(`${copilotBaseUrl(ctx)}/models`, { headers: copilotModelsHeaders(ctx) });
|
|
244
360
|
if (!response.ok) throw new HTTPError("Failed to get models", response);
|
|
245
361
|
const models = await response.json();
|
|
246
362
|
try {
|
|
@@ -255,12 +371,153 @@ const getModels = async (account) => {
|
|
|
255
371
|
|
|
256
372
|
//#endregion
|
|
257
373
|
//#region src/services/get-vscode-version.ts
|
|
258
|
-
const FALLBACK = "1.
|
|
374
|
+
const FALLBACK = "1.114.0";
|
|
259
375
|
async function getVSCodeVersion() {
|
|
260
376
|
await Promise.resolve();
|
|
261
377
|
return FALLBACK;
|
|
262
378
|
}
|
|
263
379
|
|
|
380
|
+
//#endregion
|
|
381
|
+
//#region src/lib/deviceid.ts
|
|
382
|
+
const WINDOWS_DEVICE_ID_KEY = String.raw`\SOFTWARE\Microsoft\DeveloperTools`;
|
|
383
|
+
const WINDOWS_DEVICE_ID_NAME = "deviceid";
|
|
384
|
+
const windows64Architectures = new Set([
|
|
385
|
+
"AMD64",
|
|
386
|
+
"ARM64",
|
|
387
|
+
"IA64"
|
|
388
|
+
]);
|
|
389
|
+
const getPosixHomeDir = () => {
|
|
390
|
+
if (!process.env.HOME) throw new Error("Home directory not found");
|
|
391
|
+
return process.env.HOME;
|
|
392
|
+
};
|
|
393
|
+
const getDeviceIdFilePath = () => {
|
|
394
|
+
let folder;
|
|
395
|
+
switch (process.platform) {
|
|
396
|
+
case "darwin":
|
|
397
|
+
folder = path.posix.join(getPosixHomeDir(), "Library", "Application Support");
|
|
398
|
+
break;
|
|
399
|
+
case "linux":
|
|
400
|
+
folder = process.env.XDG_CACHE_HOME ?? path.posix.join(getPosixHomeDir(), ".cache");
|
|
401
|
+
break;
|
|
402
|
+
default: throw new Error("Unsupported platform");
|
|
403
|
+
}
|
|
404
|
+
return path.posix.join(folder, "Microsoft", "DeveloperTools", "deviceid");
|
|
405
|
+
};
|
|
406
|
+
const isMissingFileError = (error) => {
|
|
407
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
408
|
+
};
|
|
409
|
+
const readStoredDeviceIdFile = async (filePath) => {
|
|
410
|
+
const { readFile: readFile$1 } = await import("node:fs/promises");
|
|
411
|
+
try {
|
|
412
|
+
return await readFile$1(filePath, "utf8");
|
|
413
|
+
} catch (error) {
|
|
414
|
+
if (isMissingFileError(error)) return;
|
|
415
|
+
throw error;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const writeStoredDeviceIdFile = async (filePath, deviceId) => {
|
|
419
|
+
const { mkdir, writeFile } = await import("node:fs/promises");
|
|
420
|
+
await mkdir(path.posix.dirname(filePath), { recursive: true });
|
|
421
|
+
await writeFile(filePath, deviceId, "utf8");
|
|
422
|
+
};
|
|
423
|
+
const getWindowsRegistryArch = () => {
|
|
424
|
+
const architecture = (process.env.PROCESSOR_ARCHITEW6432 ?? process.env.PROCESSOR_ARCHITECTURE)?.toUpperCase();
|
|
425
|
+
return architecture && windows64Architectures.has(architecture) ? "x64" : void 0;
|
|
426
|
+
};
|
|
427
|
+
const loadWinreg = async () => {
|
|
428
|
+
const module = await import("winreg");
|
|
429
|
+
return "default" in module ? module.default : module;
|
|
430
|
+
};
|
|
431
|
+
const isMissingRegistryError = (error) => {
|
|
432
|
+
if (!error) return false;
|
|
433
|
+
const errorCode = Number(error.code);
|
|
434
|
+
return Number.isFinite(errorCode) && errorCode === 1;
|
|
435
|
+
};
|
|
436
|
+
const createWindowsRegistry = async () => {
|
|
437
|
+
const Winreg = await loadWinreg();
|
|
438
|
+
return {
|
|
439
|
+
registry: new Winreg({
|
|
440
|
+
hive: Winreg.HKCU,
|
|
441
|
+
key: WINDOWS_DEVICE_ID_KEY,
|
|
442
|
+
arch: getWindowsRegistryArch()
|
|
443
|
+
}),
|
|
444
|
+
regSz: Winreg.REG_SZ
|
|
445
|
+
};
|
|
446
|
+
};
|
|
447
|
+
const readRegistryString = async (registry, name) => {
|
|
448
|
+
return new Promise((resolve, reject) => {
|
|
449
|
+
registry.get(name, (error, item) => {
|
|
450
|
+
if (isMissingRegistryError(error)) {
|
|
451
|
+
resolve(void 0);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
if (error) {
|
|
455
|
+
reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
resolve(item?.value);
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
};
|
|
462
|
+
const writeRegistryString = async ({ registry, regSz, name, value }) => {
|
|
463
|
+
return new Promise((resolve, reject) => {
|
|
464
|
+
registry.set(name, regSz, value, (error) => {
|
|
465
|
+
if (error) {
|
|
466
|
+
reject(error instanceof Error ? error : /* @__PURE__ */ new Error("Unknown registry error"));
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
resolve();
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
};
|
|
473
|
+
const getStoredVSCodeDeviceId = async () => {
|
|
474
|
+
switch (process.platform) {
|
|
475
|
+
case "win32": {
|
|
476
|
+
const { registry } = await createWindowsRegistry();
|
|
477
|
+
return readRegistryString(registry, WINDOWS_DEVICE_ID_NAME);
|
|
478
|
+
}
|
|
479
|
+
case "darwin":
|
|
480
|
+
case "linux": return readStoredDeviceIdFile(getDeviceIdFilePath());
|
|
481
|
+
default: throw new Error("Unsupported platform");
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
const setStoredVSCodeDeviceId = async (deviceId) => {
|
|
485
|
+
switch (process.platform) {
|
|
486
|
+
case "win32": {
|
|
487
|
+
const { registry, regSz } = await createWindowsRegistry();
|
|
488
|
+
await writeRegistryString({
|
|
489
|
+
registry,
|
|
490
|
+
regSz,
|
|
491
|
+
name: WINDOWS_DEVICE_ID_NAME,
|
|
492
|
+
value: deviceId
|
|
493
|
+
});
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
case "darwin":
|
|
497
|
+
case "linux":
|
|
498
|
+
await writeStoredDeviceIdFile(getDeviceIdFilePath(), deviceId);
|
|
499
|
+
return;
|
|
500
|
+
default: throw new Error("Unsupported platform");
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
const createVSCodeDeviceId = () => randomUUID().toLowerCase();
|
|
504
|
+
async function getVSCodeDeviceId() {
|
|
505
|
+
let deviceId;
|
|
506
|
+
try {
|
|
507
|
+
deviceId = await getStoredVSCodeDeviceId();
|
|
508
|
+
} catch (error) {
|
|
509
|
+
consola.debug("Failed to read VSCode device id", error);
|
|
510
|
+
}
|
|
511
|
+
if (deviceId) return deviceId;
|
|
512
|
+
const newDeviceId = createVSCodeDeviceId();
|
|
513
|
+
try {
|
|
514
|
+
await setStoredVSCodeDeviceId(newDeviceId);
|
|
515
|
+
} catch (error) {
|
|
516
|
+
consola.warn("Failed to persist VSCode device id, using ephemeral id", error);
|
|
517
|
+
}
|
|
518
|
+
return newDeviceId;
|
|
519
|
+
}
|
|
520
|
+
|
|
264
521
|
//#endregion
|
|
265
522
|
//#region src/lib/utils.ts
|
|
266
523
|
const sleep = (ms) => new Promise((resolve) => {
|
|
@@ -303,6 +560,10 @@ const cacheMacMachineId = () => {
|
|
|
303
560
|
state.macMachineId = createHash("sha256").update(macAddress, "utf8").digest("hex");
|
|
304
561
|
consola.debug(`Using machine ID: ${state.macMachineId}`);
|
|
305
562
|
};
|
|
563
|
+
const cacheVsCodeDeviceId = async () => {
|
|
564
|
+
state.vsCodeDeviceId = await getVSCodeDeviceId();
|
|
565
|
+
consola.debug(`Using VSCode device ID: ${state.vsCodeDeviceId}`);
|
|
566
|
+
};
|
|
306
567
|
const SESSION_REFRESH_BASE_MS = 3600 * 1e3;
|
|
307
568
|
const SESSION_REFRESH_JITTER_MS = 1200 * 1e3;
|
|
308
569
|
let vsCodeSessionRefreshTimer = null;
|
|
@@ -399,5 +660,37 @@ const getUUID = (content) => {
|
|
|
399
660
|
};
|
|
400
661
|
|
|
401
662
|
//#endregion
|
|
402
|
-
|
|
403
|
-
|
|
663
|
+
//#region src/services/github/poll-access-token.ts
|
|
664
|
+
async function pollAccessToken(deviceCode, options) {
|
|
665
|
+
const { clientId, headers } = getOauthAppConfig();
|
|
666
|
+
const { accessTokenUrl } = options?.overrideUrls ?? getOauthUrls();
|
|
667
|
+
const sleepDuration = (deviceCode.interval + 1) * 1e3;
|
|
668
|
+
consola.debug(`Polling access token with interval of ${sleepDuration}ms`);
|
|
669
|
+
while (true) {
|
|
670
|
+
if (options?.signal?.aborted) throw new CancelledError("Authentication cancelled");
|
|
671
|
+
const response = await fetch(accessTokenUrl, {
|
|
672
|
+
method: "POST",
|
|
673
|
+
headers,
|
|
674
|
+
body: JSON.stringify({
|
|
675
|
+
client_id: clientId,
|
|
676
|
+
device_code: deviceCode.device_code,
|
|
677
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code"
|
|
678
|
+
}),
|
|
679
|
+
signal: options?.signal
|
|
680
|
+
});
|
|
681
|
+
if (!response.ok) {
|
|
682
|
+
await sleep(sleepDuration);
|
|
683
|
+
consola.error("Failed to poll access token:", await response.text());
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
const json = await response.json();
|
|
687
|
+
consola.debug("Polling access token response:", json);
|
|
688
|
+
const { access_token } = json;
|
|
689
|
+
if (access_token) return access_token;
|
|
690
|
+
else await sleep(sleepDuration);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
//#endregion
|
|
695
|
+
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 };
|
|
696
|
+
//# sourceMappingURL=poll-access-token-DFooFWhY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll-access-token-DFooFWhY.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 const headers = githubCopilotHeaders(account)\n headers[\"x-interaction-type\"] = \"model-access\"\n headers[\"openai-intent\"] = \"model-access\"\n delete headers[\"x-interaction-id\"]\n delete headers[\"content-type\"]\n return headers\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 = (\n account: AccountContext,\n): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${account.githubToken}`,\n ...getOpencodeOauthHeaders(),\n }\n }\n\n return {\n authorization: `token ${account.githubToken}`,\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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"}
|