@jeffreycao/copilot-api 1.9.11 → 1.9.13
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/dist/{auth-CWEhhJYn.js → auth-DEUCqXMV.js} +5 -6
- package/dist/{auth-CWEhhJYn.js.map → auth-DEUCqXMV.js.map} +1 -1
- package/dist/{check-usage-B5yr4fpk.js → check-usage-OcW_3tEg.js} +5 -6
- package/dist/{check-usage-B5yr4fpk.js.map → check-usage-OcW_3tEg.js.map} +1 -1
- package/dist/{config-BJt9unC0.js → config-DrfmMOO-.js} +5 -7
- package/dist/config-DrfmMOO-.js.map +1 -0
- package/dist/{debug-DcC7ZPH0.js → debug-CIXXx_bq.js} +3 -4
- package/dist/{debug-DcC7ZPH0.js.map → debug-CIXXx_bq.js.map} +1 -1
- package/dist/main.js +8 -11
- package/dist/main.js.map +1 -1
- package/dist/{paths-Cla6y5eD.js → paths-DC-mqCY3.js} +5 -8
- package/dist/{paths-Cla6y5eD.js.map → paths-DC-mqCY3.js.map} +1 -1
- package/dist/{server-D4pg54e1.js → server-DkUKa2I6.js} +370 -419
- package/dist/server-DkUKa2I6.js.map +1 -0
- package/dist/{start-D2K2jpHF.js → start-DFJynp4A.js} +12 -17
- package/dist/start-DFJynp4A.js.map +1 -0
- package/dist/{token-rgdB2YWP.js → token-BOwQe3TO.js} +5 -10
- package/dist/token-BOwQe3TO.js.map +1 -0
- package/dist/{utils-DEJvF68W.js → utils-Cj-ToKA6.js} +36 -62
- package/dist/utils-Cj-ToKA6.js.map +1 -0
- package/package.json +11 -5
- package/dist/config-BJt9unC0.js.map +0 -1
- package/dist/server-D4pg54e1.js.map +0 -1
- package/dist/start-D2K2jpHF.js.map +0 -1
- package/dist/token-rgdB2YWP.js.map +0 -1
- package/dist/utils-DEJvF68W.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ensurePaths } from "./paths-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { mergeConfigWithDefaults } from "./config-
|
|
1
|
+
import { n as ensurePaths } from "./paths-DC-mqCY3.js";
|
|
2
|
+
import { F as state, a as cacheVsCodeSessionId, i as cacheVsCodeDeviceId, k as initOpencodeVersion, n as cacheModels, r as cacheVSCodeVersion, t as cacheMacMachineId } from "./utils-Cj-ToKA6.js";
|
|
3
|
+
import { n as setupCopilotToken, r as setupGitHubToken, t as logUser } from "./token-BOwQe3TO.js";
|
|
4
|
+
import { d as mergeConfigWithDefaults } from "./config-DrfmMOO-.js";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
6
6
|
import consola from "consola";
|
|
7
7
|
import { execSync } from "node:child_process";
|
|
@@ -11,7 +11,6 @@ import invariant from "tiny-invariant";
|
|
|
11
11
|
import { getProxyForUrl } from "proxy-from-env";
|
|
12
12
|
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
13
13
|
import process from "node:process";
|
|
14
|
-
|
|
15
14
|
//#region src/lib/proxy.ts
|
|
16
15
|
function initProxyFromEnv() {
|
|
17
16
|
if (typeof Bun !== "undefined") return;
|
|
@@ -56,15 +55,13 @@ function initProxyFromEnv() {
|
|
|
56
55
|
consola.debug("Proxy setup skipped:", err);
|
|
57
56
|
}
|
|
58
57
|
}
|
|
59
|
-
|
|
60
58
|
//#endregion
|
|
61
59
|
//#region src/lib/shell.ts
|
|
62
60
|
function getShell() {
|
|
63
61
|
const { platform, ppid, env } = process;
|
|
64
62
|
if (platform === "win32") {
|
|
65
63
|
try {
|
|
66
|
-
|
|
67
|
-
if (execSync(command, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
|
|
64
|
+
if (execSync(`wmic process get ParentProcessId,Name | findstr "${ppid}"`, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
|
|
68
65
|
} catch {
|
|
69
66
|
return "cmd";
|
|
70
67
|
}
|
|
@@ -109,7 +106,6 @@ function generateEnvScript(envVars, commandToRun = "") {
|
|
|
109
106
|
if (commandBlock && commandToRun) return `${commandBlock}${shell === "cmd" ? " & " : " && "}${commandToRun}`;
|
|
110
107
|
return commandBlock || commandToRun;
|
|
111
108
|
}
|
|
112
|
-
|
|
113
109
|
//#endregion
|
|
114
110
|
//#region src/start.ts
|
|
115
111
|
async function runServer(options) {
|
|
@@ -149,16 +145,15 @@ async function runServer(options) {
|
|
|
149
145
|
type: "select",
|
|
150
146
|
options: state.models.data.map((model) => model.id)
|
|
151
147
|
});
|
|
152
|
-
const selectedSmallModel = await consola.prompt("Select a small model to use with Claude Code", {
|
|
153
|
-
type: "select",
|
|
154
|
-
options: state.models.data.map((model) => model.id)
|
|
155
|
-
});
|
|
156
148
|
const command = generateEnvScript({
|
|
157
149
|
ANTHROPIC_BASE_URL: serverUrl,
|
|
158
150
|
ANTHROPIC_AUTH_TOKEN: "dummy",
|
|
159
151
|
ANTHROPIC_MODEL: selectedModel,
|
|
160
152
|
ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,
|
|
161
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL:
|
|
153
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: await consola.prompt("Select a small model to use with Claude Code", {
|
|
154
|
+
type: "select",
|
|
155
|
+
options: state.models.data.map((model) => model.id)
|
|
156
|
+
}),
|
|
162
157
|
DISABLE_NON_ESSENTIAL_MODEL_CALLS: "1",
|
|
163
158
|
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
|
|
164
159
|
CLAUDE_CODE_ATTRIBUTION_HEADER: "0",
|
|
@@ -176,7 +171,7 @@ async function runServer(options) {
|
|
|
176
171
|
}
|
|
177
172
|
}
|
|
178
173
|
consola.box(`🌐 Usage Viewer: ${serverUrl}/usage-viewer?endpoint=${serverUrl}/usage`);
|
|
179
|
-
const { server } = await import("./server-
|
|
174
|
+
const { server } = await import("./server-DkUKa2I6.js");
|
|
180
175
|
serve({
|
|
181
176
|
fetch: server.fetch,
|
|
182
177
|
port: options.port,
|
|
@@ -262,7 +257,7 @@ const start = defineCommand({
|
|
|
262
257
|
});
|
|
263
258
|
}
|
|
264
259
|
});
|
|
265
|
-
|
|
266
260
|
//#endregion
|
|
267
261
|
export { start };
|
|
268
|
-
|
|
262
|
+
|
|
263
|
+
//# sourceMappingURL=start-DFJynp4A.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-DFJynp4A.js","names":["get"],"sources":["../src/lib/proxy.ts","../src/lib/shell.ts","../src/start.ts"],"sourcesContent":["import consola from \"consola\"\nimport { getProxyForUrl } from \"proxy-from-env\"\nimport { Agent, ProxyAgent, setGlobalDispatcher, type Dispatcher } from \"undici\"\n\nexport function initProxyFromEnv(): void {\n if (typeof Bun !== \"undefined\") return\n\n try {\n const direct = new Agent()\n const proxies = new Map<string, ProxyAgent>()\n\n // We only need a minimal dispatcher that implements `dispatch` at runtime.\n // Typing the object as `Dispatcher` forces TypeScript to require many\n // additional methods. Instead, keep a plain object and cast when passing\n // to `setGlobalDispatcher`.\n const dispatcher = {\n dispatch(\n options: Dispatcher.DispatchOptions,\n handler: Dispatcher.DispatchHandler,\n ) {\n try {\n const origin =\n typeof options.origin === \"string\" ?\n new URL(options.origin)\n : (options.origin as URL)\n const get = getProxyForUrl as unknown as (\n u: string,\n ) => string | undefined\n const raw = get(origin.toString())\n const proxyUrl = raw && raw.length > 0 ? raw : undefined\n if (!proxyUrl) {\n consola.debug(`HTTP proxy bypass: ${origin.hostname}`)\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n let agent = proxies.get(proxyUrl)\n if (!agent) {\n agent = new ProxyAgent(proxyUrl)\n proxies.set(proxyUrl, agent)\n }\n let label = proxyUrl\n try {\n const u = new URL(proxyUrl)\n label = `${u.protocol}//${u.host}`\n } catch {\n /* noop */\n }\n consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`)\n return (agent as unknown as Dispatcher).dispatch(options, handler)\n } catch {\n return (direct as unknown as Dispatcher).dispatch(options, handler)\n }\n },\n close() {\n return direct.close()\n },\n destroy() {\n return direct.destroy()\n },\n }\n\n setGlobalDispatcher(dispatcher as unknown as Dispatcher)\n consola.debug(\"HTTP proxy configured from environment (per-URL)\")\n } catch (err) {\n consola.debug(\"Proxy setup skipped:\", err)\n }\n}\n","import { execSync } from \"node:child_process\"\nimport process from \"node:process\"\n\ntype ShellName = \"bash\" | \"zsh\" | \"fish\" | \"powershell\" | \"cmd\" | \"sh\"\ntype EnvVars = Record<string, string | undefined>\n\nfunction getShell(): ShellName {\n const { platform, ppid, env } = process\n\n if (platform === \"win32\") {\n try {\n const command = `wmic process get ParentProcessId,Name | findstr \"${ppid}\"`\n const parentProcess = execSync(command, { stdio: \"pipe\" }).toString()\n\n if (parentProcess.toLowerCase().includes(\"powershell.exe\")) {\n return \"powershell\"\n }\n } catch {\n return \"cmd\"\n }\n\n return \"cmd\"\n } else {\n const shellPath = env.SHELL\n if (shellPath) {\n if (shellPath.endsWith(\"zsh\")) return \"zsh\"\n if (shellPath.endsWith(\"fish\")) return \"fish\"\n if (shellPath.endsWith(\"bash\")) return \"bash\"\n }\n\n return \"sh\"\n }\n}\n\n/**\n * Generates a copy-pasteable script to set multiple environment variables\n * and run a subsequent command.\n * @param {EnvVars} envVars - An object of environment variables to set.\n * @param {string} commandToRun - The command to run after setting the variables.\n * @returns {string} The formatted script string.\n */\nexport function generateEnvScript(\n envVars: EnvVars,\n commandToRun: string = \"\",\n): string {\n const shell = getShell()\n const filteredEnvVars = Object.entries(envVars).filter(\n ([, value]) => value !== undefined,\n ) as Array<[string, string]>\n\n let commandBlock: string\n\n switch (shell) {\n case \"powershell\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `$env:${key} = ${value}`)\n .join(\"; \")\n break\n }\n case \"cmd\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set ${key}=${value}`)\n .join(\" & \")\n break\n }\n case \"fish\": {\n commandBlock = filteredEnvVars\n .map(([key, value]) => `set -gx ${key} ${value}`)\n .join(\"; \")\n break\n }\n default: {\n // bash, zsh, sh\n const assignments = filteredEnvVars\n .map(([key, value]) => `${key}=${value}`)\n .join(\" \")\n commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : \"\"\n break\n }\n }\n\n if (commandBlock && commandToRun) {\n const separator = shell === \"cmd\" ? \" & \" : \" && \"\n return `${commandBlock}${separator}${commandToRun}`\n }\n\n return commandBlock || commandToRun\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport clipboard from \"clipboardy\"\nimport consola from \"consola\"\nimport { serve, type ServerHandler } from \"srvx\"\nimport invariant from \"tiny-invariant\"\n\nimport { mergeConfigWithDefaults } from \"./lib/config\"\nimport { initOpencodeVersion } from \"./lib/opencode\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { logUser, setupCopilotToken, setupGitHubToken } from \"./lib/token\"\nimport {\n cacheMacMachineId,\n cacheModels,\n cacheVSCodeVersion,\n cacheVsCodeSessionId,\n cacheVsCodeDeviceId,\n} from \"./lib/utils\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: string\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n}\n\nexport async function runServer(options: RunServerOptions): Promise<void> {\n // Work around unjs/consola#357 until a release includes PR #359.\n consola.options.throttle = 0\n\n // Ensure config is merged with defaults at startup\n mergeConfigWithDefaults()\n\n await initOpencodeVersion()\n\n if (options.proxyEnv) {\n initProxyFromEnv()\n }\n\n state.verbose = options.verbose\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.accountType = options.accountType\n if (options.accountType !== \"individual\") {\n consola.info(`Using ${options.accountType} plan GitHub account`)\n }\n\n state.manualApprove = options.manual\n state.rateLimitSeconds = options.rateLimit\n state.rateLimitWait = options.rateLimitWait\n state.showToken = options.showToken\n\n await ensurePaths()\n await cacheVSCodeVersion()\n cacheMacMachineId()\n cacheVsCodeSessionId()\n await cacheVsCodeDeviceId()\n\n if (options.githubToken) {\n state.githubToken = options.githubToken\n consola.info(\"Using provided GitHub token\")\n await logUser()\n } else {\n await setupGitHubToken()\n }\n\n await setupCopilotToken()\n await cacheModels()\n\n consola.info(\n `Available models: \\n${state.models?.data.map((model) => `- ${model.id}`).join(\"\\n\")}`,\n )\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n consola.log(\n \"\\n💡 Tip: The --claude-code flag simply generates a clipboard command for launching Claude Code. \\n\"\n + \"All models remain fully accessible without this flag, just configure the model ID directly in your settings.json file.\",\n )\n\n invariant(state.models, \"Models should be loaded by now\")\n\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: state.models.data.map((model) => model.id),\n },\n )\n\n const selectedSmallModel = await consola.prompt(\n \"Select a small model to use with Claude Code\",\n {\n type: \"select\",\n options: state.models.data.map((model) => model.id),\n },\n )\n\n const command = generateEnvScript(\n {\n ANTHROPIC_BASE_URL: serverUrl,\n ANTHROPIC_AUTH_TOKEN: \"dummy\",\n ANTHROPIC_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,\n ANTHROPIC_DEFAULT_HAIKU_MODEL: selectedSmallModel,\n DISABLE_NON_ESSENTIAL_MODEL_CALLS: \"1\",\n CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: \"1\",\n CLAUDE_CODE_ATTRIBUTION_HEADER: \"0\",\n CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: \"false\",\n CLAUDE_CODE_DISABLE_TERMINAL_TITLE: \"true\",\n CLAUDE_CODE_ENABLE_AWAY_SUMMARY: \"0\",\n CLAUDE_PLUGIN_ENABLE_QUESTION_RULES: \"true\",\n },\n \"claude\",\n )\n\n try {\n clipboard.writeSync(command)\n consola.success(\"Copied Claude Code command to clipboard!\")\n } catch {\n consola.warn(\n \"Failed to copy to clipboard. Here is the Claude Code command:\",\n )\n consola.log(command)\n }\n }\n\n consola.box(\n `🌐 Usage Viewer: ${serverUrl}/usage-viewer?endpoint=${serverUrl}/usage`,\n )\n\n const { server } = await import(\"./server\")\n\n serve({\n fetch: server.fetch as ServerHandler,\n port: options.port,\n bun: {\n idleTimeout: 0,\n },\n })\n}\n\nexport const start = defineCommand({\n meta: {\n name: \"start\",\n description: \"Start the Copilot API server\",\n },\n args: {\n port: {\n alias: \"p\",\n type: \"string\",\n default: \"4141\",\n description: \"Port to listen on\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type to use (individual, business, enterprise)\",\n },\n manual: {\n type: \"boolean\",\n default: false,\n description: \"Enable manual request approval\",\n },\n \"rate-limit\": {\n alias: \"r\",\n type: \"string\",\n description: \"Rate limit in seconds between requests\",\n },\n wait: {\n alias: \"w\",\n type: \"boolean\",\n default: false,\n description:\n \"Wait instead of error when rate limit is hit. Has no effect if rate limit is not set\",\n },\n \"github-token\": {\n alias: \"g\",\n type: \"string\",\n description:\n \"Provide GitHub token directly (must be generated using the `auth` subcommand)\",\n },\n \"claude-code\": {\n alias: \"c\",\n type: \"boolean\",\n default: false,\n description:\n \"Generate a command to launch Claude Code with Copilot API config\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub and Copilot tokens on fetch and refresh\",\n },\n \"proxy-env\": {\n type: \"boolean\",\n default: false,\n description: \"Initialize proxy from environment variables\",\n },\n },\n run({ args }) {\n const rateLimitRaw = args[\"rate-limit\"]\n const rateLimit =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n rateLimitRaw === undefined ? undefined : Number.parseInt(rateLimitRaw, 10)\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType: args[\"account-type\"],\n manual: args.manual,\n rateLimit,\n rateLimitWait: args.wait,\n githubToken: args[\"github-token\"],\n claudeCode: args[\"claude-code\"],\n showToken: args[\"show-token\"],\n proxyEnv: args[\"proxy-env\"],\n })\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { PATHS } from "./paths-
|
|
2
|
-
import {
|
|
1
|
+
import { t as PATHS } from "./paths-DC-mqCY3.js";
|
|
2
|
+
import { F as state, S as isOpencodeOauthApp, _ as getGitHubApiBaseUrl, b as githubHeaders, d as sleep, f as getCopilotUsage, p as HTTPError, v as getOauthAppConfig, x as githubUserHeaders, y as getOauthUrls } from "./utils-Cj-ToKA6.js";
|
|
3
3
|
import consola from "consola";
|
|
4
4
|
import fs from "node:fs/promises";
|
|
5
5
|
import { setTimeout } from "node:timers/promises";
|
|
6
|
-
|
|
7
6
|
//#region src/services/github/get-copilot-token.ts
|
|
8
7
|
const getCopilotToken = async () => {
|
|
9
8
|
const response = await fetch(`${getGitHubApiBaseUrl()}/copilot_internal/v2/token`, { headers: githubHeaders(state) });
|
|
@@ -14,7 +13,6 @@ const getCopilotToken = async () => {
|
|
|
14
13
|
}
|
|
15
14
|
return await response.json();
|
|
16
15
|
};
|
|
17
|
-
|
|
18
16
|
//#endregion
|
|
19
17
|
//#region src/services/github/get-device-code.ts
|
|
20
18
|
async function getDeviceCode() {
|
|
@@ -31,7 +29,6 @@ async function getDeviceCode() {
|
|
|
31
29
|
if (!response.ok) throw new HTTPError("Failed to get device code", response);
|
|
32
30
|
return await response.json();
|
|
33
31
|
}
|
|
34
|
-
|
|
35
32
|
//#endregion
|
|
36
33
|
//#region src/services/github/get-user.ts
|
|
37
34
|
async function getGitHubUser(githubToken) {
|
|
@@ -45,7 +42,6 @@ async function getGitHubUser(githubToken) {
|
|
|
45
42
|
if (!response.ok) throw new HTTPError("Failed to get GitHub user", response);
|
|
46
43
|
return await response.json();
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
//#endregion
|
|
50
46
|
//#region src/services/github/poll-access-token.ts
|
|
51
47
|
async function pollAccessToken(deviceCode) {
|
|
@@ -75,7 +71,6 @@ async function pollAccessToken(deviceCode) {
|
|
|
75
71
|
else await sleep(sleepDuration);
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
|
-
|
|
79
74
|
//#endregion
|
|
80
75
|
//#region src/lib/token.ts
|
|
81
76
|
let copilotRefreshLoopController = null;
|
|
@@ -169,7 +164,7 @@ async function logUser() {
|
|
|
169
164
|
consola.info(`Logged in as ${user.login}`);
|
|
170
165
|
state.copilotApiUrl = (await getCopilotUsage()).endpoints.api;
|
|
171
166
|
}
|
|
172
|
-
|
|
173
167
|
//#endregion
|
|
174
|
-
export {
|
|
175
|
-
|
|
168
|
+
export { setupCopilotToken as n, setupGitHubToken as r, logUser as t };
|
|
169
|
+
|
|
170
|
+
//# sourceMappingURL=token-BOwQe3TO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-BOwQe3TO.js","names":["delay"],"sources":["../src/services/github/get-copilot-token.ts","../src/services/github/get-device-code.ts","../src/services/github/get-user.ts","../src/services/github/poll-access-token.ts","../src/lib/token.ts"],"sourcesContent":["import consola from \"consola\"\n\nimport { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getCopilotToken = async () => {\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/v2/token`,\n {\n headers: githubHeaders(state),\n },\n )\n\n if (!response.ok) {\n const errorText = await response.clone().text()\n consola.error(\"Failed to get Copilot token response body\", errorText)\n\n throw new HTTPError(\"Failed to get Copilot token\", response)\n }\n\n return (await response.json()) as GetCopilotTokenResponse\n}\n\n// Trimmed for the sake of simplicity\ninterface GetCopilotTokenResponse {\n expires_at: number\n refresh_in: number\n token: string\n}\n","import { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\n\nexport async function getDeviceCode(): Promise<DeviceCodeResponse> {\n const { clientId, headers, scope } = getOauthAppConfig()\n const { deviceCodeUrl } = 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 { getGitHubApiBaseUrl, githubUserHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport async function getGitHubUser(githubToken?: string) {\n const resolvedGithubToken = githubToken ?? state.githubToken\n if (!resolvedGithubToken) {\n throw new Error(\"GitHub token not found\")\n }\n\n const authState = { ...state, githubToken: resolvedGithubToken }\n const response = await fetch(`${getGitHubApiBaseUrl()}/user`, {\n headers: githubUserHeaders(authState),\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\ninterface GithubUserResponse {\n login: string\n}\n","import consola from \"consola\"\n\nimport { getOauthAppConfig, getOauthUrls } from \"~/lib/api-config\"\nimport { sleep } from \"~/lib/utils\"\n\nimport type { DeviceCodeResponse } from \"./get-device-code\"\n\nexport async function pollAccessToken(\n deviceCode: DeviceCodeResponse,\n): Promise<string> {\n const { clientId, headers } = getOauthAppConfig()\n const { accessTokenUrl } = 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 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 })\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","import consola from \"consola\"\nimport fs from \"node:fs/promises\"\nimport { setTimeout as delay } from \"node:timers/promises\"\n\nimport { isOpencodeOauthApp } from \"~/lib/api-config\"\nimport { PATHS } from \"~/lib/paths\"\nimport { getCopilotToken } from \"~/services/github/get-copilot-token\"\nimport { getCopilotUsage } from \"~/services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"~/services/github/get-device-code\"\nimport { getGitHubUser } from \"~/services/github/get-user\"\nimport { pollAccessToken } from \"~/services/github/poll-access-token\"\n\nimport { HTTPError } from \"./error\"\nimport { state } from \"./state\"\n\nlet copilotRefreshLoopController: AbortController | null = null\n\nexport const stopCopilotRefreshLoop = () => {\n if (!copilotRefreshLoopController) {\n return\n }\n\n copilotRefreshLoopController.abort()\n copilotRefreshLoopController = null\n}\n\nconst readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, \"utf8\")\n\nconst writeGithubToken = (token: string) =>\n fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token)\n\nexport const setupCopilotToken = async () => {\n if (isOpencodeOauthApp()) {\n if (!state.githubToken) throw new Error(`opencode token not found`)\n\n state.copilotToken = state.githubToken\n\n consola.debug(\"GitHub Copilot token set from opencode auth token\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", state.copilotToken)\n }\n\n stopCopilotRefreshLoop()\n return\n }\n\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n\n // Display the Copilot token to the screen\n consola.debug(\"GitHub Copilot Token fetched successfully!\")\n if (state.showToken) {\n consola.info(\"Copilot token:\", token)\n }\n\n stopCopilotRefreshLoop()\n\n const controller = new AbortController()\n copilotRefreshLoopController = controller\n\n runCopilotRefreshLoop(refresh_in, controller.signal)\n .catch(() => {\n consola.warn(\"Copilot token refresh loop stopped\")\n })\n .finally(() => {\n if (copilotRefreshLoopController === controller) {\n copilotRefreshLoopController = null\n }\n })\n}\n\nconst REFRESH_POLL_INTERVAL_MS = 15_000\nconst EARLY_REFRESH_BUFFER_MS = 60_000\nconst RETRY_REFRESH_DELAY_MS = 15_000\nconst MIN_REFRESH_DELAY_MS = 1_000\n\nexport const getRefreshDeadlineMs = (\n refreshIn: number,\n nowMs: number = Date.now(),\n) =>\n nowMs\n + Math.max(refreshIn * 1000 - EARLY_REFRESH_BUFFER_MS, MIN_REFRESH_DELAY_MS)\n\n// Use short wall-clock chunks so the next wake after sleep notices elapsed time\n// quickly, without relying on the server's absolute expires_at matching local time.\nexport const getRefreshPollDelayMs = (\n refreshAtMs: number,\n nowMs: number = Date.now(),\n) => Math.min(Math.max(refreshAtMs - nowMs, 0), REFRESH_POLL_INTERVAL_MS)\n\nconst runCopilotRefreshLoop = async (\n refreshIn: number,\n signal: AbortSignal,\n) => {\n let refreshAtMs = getRefreshDeadlineMs(refreshIn)\n\n while (!signal.aborted) {\n const nextDelayMs = getRefreshPollDelayMs(refreshAtMs)\n if (nextDelayMs > 0) {\n await delay(nextDelayMs, undefined, { signal })\n continue\n }\n\n consola.debug(\"Refreshing Copilot token\")\n\n try {\n const { token, refresh_in } = await getCopilotToken()\n state.copilotToken = token\n refreshAtMs = getRefreshDeadlineMs(refresh_in)\n consola.debug(\"Copilot token refreshed\")\n if (state.showToken) {\n consola.info(\"Refreshed Copilot token:\", token)\n }\n } catch (error) {\n consola.error(\"Failed to refresh Copilot token:\", error)\n refreshAtMs = Date.now() + RETRY_REFRESH_DELAY_MS\n consola.warn(\n `Retrying Copilot token refresh in ${RETRY_REFRESH_DELAY_MS / 1000}s`,\n )\n }\n }\n}\n\ninterface SetupGitHubTokenOptions {\n force?: boolean\n}\n\nexport async function setupGitHubToken(\n options?: SetupGitHubTokenOptions,\n): Promise<void> {\n try {\n const githubToken = await readGithubToken()\n\n if (githubToken && !options?.force) {\n state.githubToken = githubToken\n if (state.showToken) {\n consola.info(\"GitHub token:\", githubToken)\n }\n await logUser()\n\n return\n }\n\n consola.info(\"Not logged in, getting new access token\")\n const response = await getDeviceCode()\n consola.debug(\"Device code response:\", response)\n\n consola.info(\n `Please enter the code \"${response.user_code}\" in ${response.verification_uri}`,\n )\n\n const token = await pollAccessToken(response)\n await writeGithubToken(token)\n state.githubToken = token\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n await logUser()\n } catch (error) {\n if (error instanceof HTTPError) {\n consola.error(\"Failed to get GitHub token:\", await error.response.json())\n throw error\n }\n\n consola.error(\"Failed to get GitHub token:\", error)\n throw error\n }\n}\n\nexport async function logUser() {\n const user = await getGitHubUser()\n state.userName = user.login\n consola.info(`Logged in as ${user.login}`)\n\n const copilotUser = await getCopilotUsage()\n state.copilotApiUrl = copilotUser.endpoints.api\n}\n"],"mappings":"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"}
|
|
@@ -5,7 +5,6 @@ import path from "node:path";
|
|
|
5
5
|
import { createHash, randomUUID } from "node:crypto";
|
|
6
6
|
import { exec } from "node:child_process";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
-
|
|
9
8
|
//#region src/lib/state.ts
|
|
10
9
|
const state = {
|
|
11
10
|
accountType: "individual",
|
|
@@ -15,26 +14,15 @@ const state = {
|
|
|
15
14
|
verbose: false,
|
|
16
15
|
vsCodeDeviceId: randomUUID()
|
|
17
16
|
};
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
//#region src/lib/compact.ts
|
|
21
|
-
const COMPACT_REQUEST = 1;
|
|
22
|
-
const COMPACT_AUTO_CONTINUE = 2;
|
|
23
|
-
const compactSystemPromptStart = "You are a helpful AI assistant tasked with summarizing conversations";
|
|
24
|
-
const compactOpenCodeSystemPromptStart = "You are an anchored context summarization assistant for coding sessions.";
|
|
25
|
-
const compactSystemPromptStarts = [compactSystemPromptStart, compactOpenCodeSystemPromptStart];
|
|
17
|
+
const compactSystemPromptStarts = ["You are a helpful AI assistant tasked with summarizing conversations", "You are an anchored context summarization assistant for coding sessions."];
|
|
26
18
|
const compactTextOnlyGuard = "CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.";
|
|
27
19
|
const compactSummaryPromptStart = "Your task is to create a detailed summary of the conversation so far";
|
|
28
|
-
const compactAutoContinueClaudeCodePromptStart = "This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.";
|
|
29
|
-
const compactAutoContinueOpenCodePromptStart = "Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.";
|
|
30
|
-
const compactAutoContinueOpenCodePromptStart2 = "The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context.";
|
|
31
20
|
const compactAutoContinuePromptStarts = [
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
21
|
+
"This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.",
|
|
22
|
+
"Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.",
|
|
23
|
+
"The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context."
|
|
35
24
|
];
|
|
36
25
|
const compactMessageSections = ["Pending Tasks:", "Current Work:"];
|
|
37
|
-
|
|
38
26
|
//#endregion
|
|
39
27
|
//#region src/lib/opencode.ts
|
|
40
28
|
const execAsync = (command) => {
|
|
@@ -55,8 +43,7 @@ const getGlobalNpmRoot = async () => {
|
|
|
55
43
|
async function resolveOpencodeVersion() {
|
|
56
44
|
try {
|
|
57
45
|
const npmRootPath = await getGlobalNpmRoot();
|
|
58
|
-
const
|
|
59
|
-
const packageJson = await readFile(opencodePackagePath, "utf8");
|
|
46
|
+
const packageJson = await readFile(path.join(npmRootPath, "opencode-ai", "package.json"), "utf8");
|
|
60
47
|
const { version } = JSON.parse(packageJson);
|
|
61
48
|
opencodeVersionCache = version;
|
|
62
49
|
} catch (error) {
|
|
@@ -70,7 +57,6 @@ const initOpencodeVersion = () => {
|
|
|
70
57
|
const getCachedOpencodeVersion = () => {
|
|
71
58
|
return opencodeVersionCache;
|
|
72
59
|
};
|
|
73
|
-
|
|
74
60
|
//#endregion
|
|
75
61
|
//#region src/lib/request-context.ts
|
|
76
62
|
const TRACE_ID_MAX_LENGTH = 64;
|
|
@@ -81,16 +67,13 @@ const requestContext = {
|
|
|
81
67
|
run: (context, callback) => asyncLocalStorage.run(context, callback)
|
|
82
68
|
};
|
|
83
69
|
function generateTraceId() {
|
|
84
|
-
|
|
85
|
-
const random = Math.random().toString(36).slice(2, 8);
|
|
86
|
-
return `${timestamp}-${random}`;
|
|
70
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
87
71
|
}
|
|
88
72
|
function resolveTraceId(traceId) {
|
|
89
73
|
const candidate = traceId?.trim();
|
|
90
74
|
if (!candidate || candidate.length > TRACE_ID_MAX_LENGTH || !TRACE_ID_PATTERN.test(candidate)) return generateTraceId();
|
|
91
75
|
return candidate;
|
|
92
76
|
}
|
|
93
|
-
|
|
94
77
|
//#endregion
|
|
95
78
|
//#region src/lib/api-config.ts
|
|
96
79
|
const isOpencodeOauthApp = () => {
|
|
@@ -154,7 +137,7 @@ const getOauthAppConfig = () => {
|
|
|
154
137
|
const prepareForCompact = (headers, compactType) => {
|
|
155
138
|
if (compactType) {
|
|
156
139
|
headers["x-initiator"] = "agent";
|
|
157
|
-
if (!isOpencodeOauthApp() && compactType ===
|
|
140
|
+
if (!isOpencodeOauthApp() && compactType === 1) {
|
|
158
141
|
headers["x-interaction-type"] = "conversation-other";
|
|
159
142
|
headers["openai-intent"] = "conversation-other";
|
|
160
143
|
}
|
|
@@ -184,12 +167,12 @@ const EDITOR_PLUGIN_VERSION = `copilot-chat/${COPILOT_VERSION}`;
|
|
|
184
167
|
const USER_AGENT = `GitHubCopilotChat/${COPILOT_VERSION}`;
|
|
185
168
|
const CLAUDE_AGENT_USER_AGENT = "vscode_claude_code/2.1.112 (external, sdk-ts, agent-sdk/0.2.112)";
|
|
186
169
|
const API_VERSION = "2025-10-01";
|
|
187
|
-
const copilotBaseUrl = (state
|
|
170
|
+
const copilotBaseUrl = (state) => {
|
|
188
171
|
const enterpriseDomain = getEnterpriseDomain();
|
|
189
172
|
if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;
|
|
190
173
|
if (isOpencodeOauthApp()) return "https://api.githubcopilot.com";
|
|
191
|
-
if (state
|
|
192
|
-
return state
|
|
174
|
+
if (state.copilotApiUrl) return state.copilotApiUrl;
|
|
175
|
+
return state.accountType === "individual" ? "https://api.githubcopilot.com" : `https://api.${state.accountType}.githubcopilot.com`;
|
|
193
176
|
};
|
|
194
177
|
const prepareMessageProxyHeaders = (headers) => {
|
|
195
178
|
if (isOpencodeOauthApp()) return;
|
|
@@ -201,35 +184,35 @@ const prepareMessageProxyHeaders = (headers) => {
|
|
|
201
184
|
headers["user-agent"] = CLAUDE_AGENT_USER_AGENT;
|
|
202
185
|
delete headers["copilot-integration-id"];
|
|
203
186
|
};
|
|
204
|
-
const githubUserHeaders = (state
|
|
187
|
+
const githubUserHeaders = (state) => {
|
|
205
188
|
if (isOpencodeOauthApp()) return {
|
|
206
|
-
Authorization: `Bearer ${state
|
|
189
|
+
Authorization: `Bearer ${state.githubToken}`,
|
|
207
190
|
"User-Agent": getOpencodeVersion()
|
|
208
191
|
};
|
|
209
192
|
return {
|
|
210
193
|
accept: "application/vnd.github+json",
|
|
211
|
-
authorization: `token ${state
|
|
194
|
+
authorization: `token ${state.githubToken}`,
|
|
212
195
|
"user-agent": USER_AGENT,
|
|
213
196
|
"x-github-api-version": "2022-11-28",
|
|
214
197
|
"x-vscode-user-agent-library-version": "electron-fetch"
|
|
215
198
|
};
|
|
216
199
|
};
|
|
217
|
-
const copilotModelsHeaders = (state
|
|
200
|
+
const copilotModelsHeaders = (state) => {
|
|
218
201
|
if (isOpencodeOauthApp()) return {
|
|
219
|
-
Authorization: `Bearer ${state
|
|
202
|
+
Authorization: `Bearer ${state.copilotToken}`,
|
|
220
203
|
"User-Agent": getOpencodeVersion()
|
|
221
204
|
};
|
|
222
|
-
const headers = githubCopilotHeaders(state
|
|
205
|
+
const headers = githubCopilotHeaders(state);
|
|
223
206
|
headers["x-interaction-type"] = "model-access";
|
|
224
207
|
headers["openai-intent"] = "model-access";
|
|
225
208
|
delete headers["x-interaction-id"];
|
|
226
209
|
delete headers["content-type"];
|
|
227
210
|
return headers;
|
|
228
211
|
};
|
|
229
|
-
const copilotHeaders = (state
|
|
212
|
+
const copilotHeaders = (state, requestId, vision = false) => {
|
|
230
213
|
if (isOpencodeOauthApp()) {
|
|
231
214
|
const headers = {
|
|
232
|
-
Authorization: `Bearer ${state
|
|
215
|
+
Authorization: `Bearer ${state.copilotToken}`,
|
|
233
216
|
...getOpencodeLLMHeaders(),
|
|
234
217
|
"Openai-Intent": "conversation-edits"
|
|
235
218
|
};
|
|
@@ -241,16 +224,16 @@ const copilotHeaders = (state$1, requestId, vision = false) => {
|
|
|
241
224
|
if (vision) headers["Copilot-Vision-Request"] = "true";
|
|
242
225
|
return headers;
|
|
243
226
|
}
|
|
244
|
-
return githubCopilotHeaders(state
|
|
227
|
+
return githubCopilotHeaders(state, requestId, vision);
|
|
245
228
|
};
|
|
246
|
-
const githubCopilotHeaders = (state
|
|
229
|
+
const githubCopilotHeaders = (state, requestId, vision = false) => {
|
|
247
230
|
const requestIdValue = requestId ?? randomUUID();
|
|
248
231
|
const headers = {
|
|
249
|
-
Authorization: `Bearer ${state
|
|
232
|
+
Authorization: `Bearer ${state.copilotToken}`,
|
|
250
233
|
"content-type": standardHeaders()["content-type"],
|
|
251
234
|
"copilot-integration-id": "vscode-chat",
|
|
252
|
-
"editor-device-id": state
|
|
253
|
-
"editor-version": `vscode/${state
|
|
235
|
+
"editor-device-id": state.vsCodeDeviceId,
|
|
236
|
+
"editor-version": `vscode/${state.vsCodeVersion}`,
|
|
254
237
|
"editor-plugin-version": EDITOR_PLUGIN_VERSION,
|
|
255
238
|
"user-agent": USER_AGENT,
|
|
256
239
|
"openai-intent": "conversation-agent",
|
|
@@ -261,18 +244,18 @@ const githubCopilotHeaders = (state$1, requestId, vision = false) => {
|
|
|
261
244
|
"x-interaction-type": "conversation-agent"
|
|
262
245
|
};
|
|
263
246
|
if (vision) headers["copilot-vision-request"] = "true";
|
|
264
|
-
if (state
|
|
265
|
-
if (state
|
|
247
|
+
if (state.macMachineId) headers["vscode-machineid"] = state.macMachineId;
|
|
248
|
+
if (state.vsCodeSessionId) headers["vscode-sessionid"] = state.vsCodeSessionId;
|
|
266
249
|
return headers;
|
|
267
250
|
};
|
|
268
251
|
const GITHUB_API_BASE_URL = "https://api.github.com";
|
|
269
|
-
const githubHeaders = (state
|
|
252
|
+
const githubHeaders = (state) => {
|
|
270
253
|
if (isOpencodeOauthApp()) return {
|
|
271
|
-
Authorization: `Bearer ${state
|
|
254
|
+
Authorization: `Bearer ${state.githubToken}`,
|
|
272
255
|
...getOpencodeOauthHeaders()
|
|
273
256
|
};
|
|
274
257
|
return {
|
|
275
|
-
authorization: `token ${state
|
|
258
|
+
authorization: `token ${state.githubToken}`,
|
|
276
259
|
"user-agent": USER_AGENT,
|
|
277
260
|
"x-github-api-version": "2025-04-01",
|
|
278
261
|
"x-vscode-user-agent-library-version": "electron-fetch"
|
|
@@ -282,7 +265,6 @@ const GITHUB_BASE_URL = "https://github.com";
|
|
|
282
265
|
const GITHUB_CLIENT_ID = "Iv1.b507a08c87ecfe98";
|
|
283
266
|
const GITHUB_APP_SCOPES = ["read:user"].join(" ");
|
|
284
267
|
const OPENCODE_GITHUB_CLIENT_ID = "Ov23li8tweQw6odWQebz";
|
|
285
|
-
|
|
286
268
|
//#endregion
|
|
287
269
|
//#region src/lib/error.ts
|
|
288
270
|
var HTTPError = class extends Error {
|
|
@@ -317,7 +299,6 @@ async function forwardError(c, error) {
|
|
|
317
299
|
type: "error"
|
|
318
300
|
} }, 500);
|
|
319
301
|
}
|
|
320
|
-
|
|
321
302
|
//#endregion
|
|
322
303
|
//#region src/services/github/get-copilot-usage.ts
|
|
323
304
|
const getCopilotUsage = async (githubToken) => {
|
|
@@ -331,7 +312,6 @@ const getCopilotUsage = async (githubToken) => {
|
|
|
331
312
|
if (!response.ok) throw new HTTPError("Failed to get Copilot usage", response);
|
|
332
313
|
return await response.json();
|
|
333
314
|
};
|
|
334
|
-
|
|
335
315
|
//#endregion
|
|
336
316
|
//#region src/services/copilot/get-models.ts
|
|
337
317
|
const getModels = async () => {
|
|
@@ -344,7 +324,6 @@ const getModels = async () => {
|
|
|
344
324
|
}
|
|
345
325
|
return await response.json();
|
|
346
326
|
};
|
|
347
|
-
|
|
348
327
|
//#endregion
|
|
349
328
|
//#region src/services/get-vscode-version.ts
|
|
350
329
|
const FALLBACK = "1.118.0";
|
|
@@ -352,7 +331,6 @@ async function getVSCodeVersion() {
|
|
|
352
331
|
await Promise.resolve();
|
|
353
332
|
return FALLBACK;
|
|
354
333
|
}
|
|
355
|
-
|
|
356
334
|
//#endregion
|
|
357
335
|
//#region src/lib/deviceid.ts
|
|
358
336
|
const WINDOWS_DEVICE_ID_KEY = String.raw`\SOFTWARE\Microsoft\DeveloperTools`;
|
|
@@ -383,9 +361,9 @@ const isMissingFileError = (error) => {
|
|
|
383
361
|
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
384
362
|
};
|
|
385
363
|
const readStoredDeviceIdFile = async (filePath) => {
|
|
386
|
-
const { readFile
|
|
364
|
+
const { readFile } = await import("node:fs/promises");
|
|
387
365
|
try {
|
|
388
|
-
return await readFile
|
|
366
|
+
return await readFile(filePath, "utf8");
|
|
389
367
|
} catch (error) {
|
|
390
368
|
if (isMissingFileError(error)) return;
|
|
391
369
|
throw error;
|
|
@@ -493,7 +471,6 @@ async function getVSCodeDeviceId() {
|
|
|
493
471
|
}
|
|
494
472
|
return newDeviceId;
|
|
495
473
|
}
|
|
496
|
-
|
|
497
474
|
//#endregion
|
|
498
475
|
//#region src/lib/utils.ts
|
|
499
476
|
const sleep = (ms) => new Promise((resolve) => {
|
|
@@ -554,8 +531,7 @@ const stopVsCodeSessionRefreshLoop = () => {
|
|
|
554
531
|
}
|
|
555
532
|
};
|
|
556
533
|
const scheduleSessionIdRefresh = () => {
|
|
557
|
-
const
|
|
558
|
-
const delay = SESSION_REFRESH_BASE_MS + randomDelay;
|
|
534
|
+
const delay = SESSION_REFRESH_BASE_MS + Math.floor(Math.random() * SESSION_REFRESH_JITTER_MS);
|
|
559
535
|
consola.debug(`Scheduling next VSCode session ID refresh in ${Math.round(delay / 1e3)} seconds`);
|
|
560
536
|
stopVsCodeSessionRefreshLoop();
|
|
561
537
|
vsCodeSessionRefreshTimer = setTimeout(() => {
|
|
@@ -594,11 +570,9 @@ const parseUserIdMetadata = (userId) => {
|
|
|
594
570
|
const legacySafetyIdentifier = userId.match(/user_([^_]+)_account/)?.[1] ?? null;
|
|
595
571
|
const legacySessionId = userId.match(/_session_(.+)$/)?.[1] ?? null;
|
|
596
572
|
const parsedUserId = legacySafetyIdentifier && legacySessionId ? null : parseJsonUserId(userId);
|
|
597
|
-
const safetyIdentifier = legacySafetyIdentifier ?? getUserIdJsonField(parsedUserId, "device_id") ?? getUserIdJsonField(parsedUserId, "account_uuid");
|
|
598
|
-
const sessionId = legacySessionId ?? getUserIdJsonField(parsedUserId, "session_id");
|
|
599
573
|
return {
|
|
600
|
-
safetyIdentifier,
|
|
601
|
-
sessionId
|
|
574
|
+
safetyIdentifier: legacySafetyIdentifier ?? getUserIdJsonField(parsedUserId, "device_id") ?? getUserIdJsonField(parsedUserId, "account_uuid"),
|
|
575
|
+
sessionId: legacySessionId ?? getUserIdJsonField(parsedUserId, "session_id")
|
|
602
576
|
};
|
|
603
577
|
};
|
|
604
578
|
const findLastUserContent = (messages) => {
|
|
@@ -637,7 +611,7 @@ const getUUID = (content) => {
|
|
|
637
611
|
const uuidHex = uuidBytes.toString("hex");
|
|
638
612
|
return `${uuidHex.slice(0, 8)}-${uuidHex.slice(8, 12)}-${uuidHex.slice(12, 16)}-${uuidHex.slice(16, 20)}-${uuidHex.slice(20)}`;
|
|
639
613
|
};
|
|
640
|
-
|
|
641
614
|
//#endregion
|
|
642
|
-
export {
|
|
643
|
-
|
|
615
|
+
export { compactAutoContinuePromptStarts as A, prepareForCompact as C, requestContext as D, generateTraceId as E, state as F, compactSummaryPromptStart as M, compactSystemPromptStarts as N, resolveTraceId as O, compactTextOnlyGuard as P, isOpencodeOauthApp as S, prepareMessageProxyHeaders as T, getGitHubApiBaseUrl as _, cacheVsCodeSessionId as a, githubHeaders as b, getUUID as c, sleep as d, getCopilotUsage as f, copilotHeaders as g, copilotBaseUrl as h, cacheVsCodeDeviceId as i, compactMessageSections as j, initOpencodeVersion as k, isNullish as l, forwardError as m, cacheModels as n, generateRequestIdFromPayload as o, HTTPError as p, cacheVSCodeVersion as r, getRootSessionId as s, cacheMacMachineId as t, parseUserIdMetadata as u, getOauthAppConfig as v, prepareInteractionHeaders as w, githubUserHeaders as x, getOauthUrls as y };
|
|
616
|
+
|
|
617
|
+
//# sourceMappingURL=utils-Cj-ToKA6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils-Cj-ToKA6.js","names":[],"sources":["../src/lib/state.ts","../src/lib/compact.ts","../src/lib/opencode.ts","../src/lib/request-context.ts","../src/lib/api-config.ts","../src/lib/error.ts","../src/services/github/get-copilot-usage.ts","../src/services/copilot/get-models.ts","../src/services/get-vscode-version.ts","../src/lib/deviceid.ts","../src/lib/utils.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\"\n\nimport type { ModelsResponse } from \"~/services/copilot/get-models\"\n\nexport interface State {\n githubToken?: string\n userName?: string\n copilotToken?: string\n\n accountType: string\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","export const COMPACT_REQUEST = 1 as const\nexport const COMPACT_AUTO_CONTINUE = 2 as const\n\nexport const compactSystemPromptStart =\n \"You are a helpful AI assistant tasked with summarizing conversations\"\nexport const compactOpenCodeSystemPromptStart =\n \"You are an anchored context summarization assistant for coding sessions.\"\nexport const compactSystemPromptStarts = [\n compactSystemPromptStart,\n compactOpenCodeSystemPromptStart,\n] as const\nexport const compactTextOnlyGuard =\n \"CRITICAL: Respond with TEXT ONLY. Do NOT call any tools.\"\nexport const compactSummaryPromptStart =\n \"Your task is to create a detailed summary of the conversation so far\"\nexport const compactAutoContinueClaudeCodePromptStart =\n \"This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.\"\nexport const compactAutoContinueOpenCodePromptStart =\n \"Continue if you have next steps, or stop and ask for clarification if you are unsure how to proceed.\"\nexport const compactAutoContinueOpenCodePromptStart2 =\n \"The previous request exceeded the provider's size limit due to large media attachments. The conversation was compacted and media files were removed from context.\"\nexport const compactAutoContinuePromptStarts = [\n compactAutoContinueClaudeCodePromptStart,\n compactAutoContinueOpenCodePromptStart,\n compactAutoContinueOpenCodePromptStart2,\n] as const\nexport const compactMessageSections = [\n \"Pending Tasks:\",\n \"Current Work:\",\n] as const\n\nexport type CompactType =\n | 0\n | typeof COMPACT_REQUEST\n | typeof COMPACT_AUTO_CONTINUE\n","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 { COMPACT_REQUEST, type CompactType } from \"~/lib/compact\"\n\nimport type { State } from \"./state\"\n\nimport { getCachedOpencodeVersion } from \"./opencode\"\nimport { requestContext } from \"./request-context\"\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 compactType?: CompactType,\n) => {\n if (compactType) {\n headers[\"x-initiator\"] = \"agent\"\n if (!isOpencodeOauthApp() && compactType === COMPACT_REQUEST) {\n headers[\"x-interaction-type\"] = \"conversation-other\"\n headers[\"openai-intent\"] = \"conversation-other\"\n }\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.14.29\"\nconst OPENCODE_LLM_USER_AGENT =\n \"opencode/1.14.29 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.13, opencode/1.14.29\"\n\nconst COPILOT_VERSION = \"0.46.0\"\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.112 (external, sdk-ts, agent-sdk/0.2.112)\"\n\nconst API_VERSION = \"2025-10-01\"\n\nexport const copilotBaseUrl = (state: State) => {\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 (state.copilotApiUrl) {\n return state.copilotApiUrl\n }\n\n return state.accountType === \"individual\" ?\n \"https://api.githubcopilot.com\"\n : `https://api.${state.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 delete headers[\"copilot-integration-id\"]\n}\n\nexport const githubUserHeaders = (state: State): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${state.githubToken}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n return {\n accept: \"application/vnd.github+json\",\n authorization: `token ${state.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 = (state: State) => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${state.copilotToken}`,\n \"User-Agent\": getOpencodeVersion(),\n }\n }\n const headers = githubCopilotHeaders(state)\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 state: State,\n requestId?: string,\n vision: boolean = false,\n) => {\n if (isOpencodeOauthApp()) {\n const headers: Record<string, string> = {\n Authorization: `Bearer ${state.copilotToken}`,\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(state, requestId, vision)\n}\n\nconst githubCopilotHeaders = (\n state: State,\n requestId?: string,\n vision: boolean = false,\n) => {\n const requestIdValue = requestId ?? randomUUID()\n const headers: Record<string, string> = {\n Authorization: `Bearer ${state.copilotToken}`,\n \"content-type\": standardHeaders()[\"content-type\"],\n \"copilot-integration-id\": \"vscode-chat\",\n \"editor-device-id\": state.vsCodeDeviceId,\n \"editor-version\": `vscode/${state.vsCodeVersion}`,\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\": requestIdValue,\n \"x-vscode-user-agent-library-version\": \"electron-fetch\",\n \"x-agent-task-id\": requestIdValue,\n \"x-interaction-type\": \"conversation-agent\",\n }\n\n if (vision) headers[\"copilot-vision-request\"] = \"true\"\n\n if (state.macMachineId) {\n headers[\"vscode-machineid\"] = state.macMachineId\n }\n\n if (state.vsCodeSessionId) {\n headers[\"vscode-sessionid\"] = state.vsCodeSessionId\n }\n\n return headers\n}\n\nexport const GITHUB_API_BASE_URL = \"https://api.github.com\"\nexport const githubHeaders = (state: State): Record<string, string> => {\n if (isOpencodeOauthApp()) {\n return {\n Authorization: `Bearer ${state.githubToken}`,\n ...getOpencodeOauthHeaders(),\n }\n }\n return {\n authorization: `token ${state.githubToken}`,\n \"user-agent\": USER_AGENT,\n \"x-github-api-version\": \"2025-04-01\",\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 async function forwardError(\n c: Context,\n error: unknown,\n): Promise<Response> {\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 { getGitHubApiBaseUrl, githubHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport type CopilotAccountType = \"individual\" | \"business\" | \"enterprise\"\n\nexport const getCopilotUsage = async (\n githubToken?: string,\n): Promise<CopilotUsageResponse> => {\n const resolvedGithubToken = githubToken ?? state.githubToken\n if (!resolvedGithubToken) {\n throw new Error(\"GitHub token not found\")\n }\n\n const authState = { ...state, githubToken: resolvedGithubToken }\n const response = await fetch(\n `${getGitHubApiBaseUrl()}/copilot_internal/user`,\n {\n headers: githubHeaders(authState),\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 const getCopilotAccountType = async (\n githubToken?: string,\n): Promise<CopilotAccountType> => {\n const usage = await getCopilotUsage(githubToken)\n const plan = (usage.copilot_plan ?? \"\").toLowerCase()\n\n if (plan.includes(\"enterprise\")) return \"enterprise\"\n if (plan.includes(\"business\")) return \"business\"\n return \"individual\"\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 consola from \"consola\"\n\nimport { copilotBaseUrl, copilotModelsHeaders } from \"~/lib/api-config\"\nimport { HTTPError } from \"~/lib/error\"\nimport { state } from \"~/lib/state\"\n\nexport const getModels = async () => {\n consola.info(`Fetching models from ${copilotBaseUrl(state)}/models`)\n const response = await fetch(`${copilotBaseUrl(state)}/models`, {\n headers: copilotModelsHeaders(state),\n })\n\n if (!response.ok) {\n const errorText = await response.clone().text()\n\n consola.error(\"Failed to get models response body\", errorText)\n\n throw new HTTPError(\"Failed to get models\", response)\n }\n\n return (await response.json()) as ModelsResponse\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 reasoning_effort?: Array<string>\n}\n\ninterface ModelCapabilities {\n family: string\n limits: ModelLimits\n object: string\n supports: ModelSupports\n tokenizer: string\n type: string\n}\n\nexport interface Model {\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.118.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"],"mappings":";;;;;;;;AA6BA,MAAa,QAAe;CAC1B,aAAa;CACb,eAAe;CACf,eAAe;CACf,WAAW;CACX,SAAS;CACT,gBAAgB,YAAY;CAC7B;AC7BD,MAAa,4BAA4B,CACvC,wEACA,2EACD;AACD,MAAa,uBACX;AACF,MAAa,4BACX;AAOF,MAAa,kCAAkC;CAC7C;CACA;CACA;CACD;AACD,MAAa,yBAAyB,CACpC,kBACA,gBACD;;;ACxBD,MAAM,aAAa,YAAqC;CACtD,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,KAAK,UAAU,OAAO,WAAW;GAC/B,IAAI,OAAO;IACT,OAAO,MAAM;IACb;;GAGF,QAAQ,OAAO;IACf;GACF;;AAGJ,IAAI;AAEJ,MAAM,mBAAmB,YAA6B;CAEpD,QAAO,MADc,UAAU,cAAc,EAC/B,MAAM;;AAGtB,eAAe,yBAAwC;CACrD,IAAI;EACF,MAAM,cAAc,MAAM,kBAAkB;EAM5C,MAAM,cAAc,MAAM,SALE,KAAK,KAC/B,aACA,eACA,eAEoD,EAAE,OAAO;EAC/D,MAAM,EAAE,YAAY,KAAK,MAAM,YAAY;EAC3C,uBAAuB;UAChB,OAAO;EACd,QAAQ,KAAK,sCAAsC,MAAM;;;AAI7D,MAAa,4BAA2C;CACtD,IAAI,QAAQ,IAAI,uBAAuB,MAAM,KAAK,YAChD,OAAO,QAAQ,SAAS;CAE1B,OAAO,wBAAwB;;AAGjC,MAAa,iCAAqD;CAChE,OAAO;;;;ACvCT,MAAM,sBAAsB;AAC5B,MAAM,mBAAmB;AAEzB,MAAM,oBAAoB,IAAI,mBAAmC;AAEjE,MAAa,iBAAiB;CAC5B,gBAAgB,kBAAkB,UAAU;CAC5C,MAAS,SAAyB,aAChC,kBAAkB,IAAI,SAAS,SAAS;CAC3C;AAED,SAAgB,kBAA0B;CAGxC,OAAO,GAFW,KAAK,KAAK,CAAC,SAAS,GAEnB,CAAC,GADL,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EACtB;;AAG/B,SAAgB,eAAe,SAA4C;CACzE,MAAM,YAAY,SAAS,MAAM;CAEjC,IACE,CAAC,aACE,UAAU,SAAS,uBACnB,CAAC,iBAAiB,KAAK,UAAU,EAEpC,OAAO,iBAAiB;CAG1B,OAAO;;;;AC7BT,MAAa,2BAAoC;CAC/C,OAAO,QAAQ,IAAI,uBAAuB,MAAM,KAAK;;AAGvD,MAAa,mBAAmB,UAA0B;CACxD,OAAO,MACJ,MAAM,CACN,QAAQ,iBAAiB,GAAG,CAC5B,QAAQ,SAAS,GAAG;;AAGzB,MAAa,4BAA2C;CACtD,MAAM,OAAO,QAAQ,IAAI,8BAA8B,IAAI,MAAM;CACjE,IAAI,CAAC,KAAK,OAAO;CAEjB,OADmB,gBAAgB,IAClB,IAAI;;AAGvB,MAAa,yBAAiC;CAC5C,MAAM,iBAAiB,qBAAqB;CAC5C,OAAO,iBAAiB,WAAW,mBAAmB;;AAGxD,MAAa,4BAAoC;CAC/C,MAAM,iBAAiB,qBAAqB;CAC5C,OAAO,iBAAiB,eAAe,mBAAmB;;AAG5D,MAAM,gCAAwD;CAC5D,OAAO;EACL,QAAQ;EACR,gBAAgB;EAChB,cAAc,oBAAoB;EACnC;;AAGH,MAAM,8BAAsD;CAC1D,OAAO;EACL,QAAQ;EACR,gBAAgB;EAChB,cAAc;EACf;;AAGH,MAAM,8BAA8B,cAA8B;CAChE,MAAM,YAAY,UAAU,MAAM;CAClC,MAAM,kBAAkB,UAAU,MAAM,sBAAsB,GAAG;CAEjE,IAAI,CAAC,mBAAmB,UAAU,SAAS,KAAK,kBAAkB,EAChE,OAAO;CAGT,OAAO,GAAG,UAAU,IAAI;;AAG1B,MAAa,qBAGR;CACH,MAAM,gBAAgB,kBAAkB;CAExC,OAAO;EACL,eAAe,GAAG,cAAc;EAChC,gBAAgB,GAAG,cAAc;EAClC;;AASH,MAAa,0BAA0C;CACrD,IAAI,oBAAoB,EACtB,OAAO;EACL,UAAU;EACV,SAAS,yBAAyB;EAClC,OAAO;EACR;CAGH,OAAO;EACL,UAAU;EACV,SAAS,iBAAiB;EAC1B,OAAO;EACR;;AAGH,MAAa,qBACX,SACA,gBACG;CACH,IAAI,aAAa;EACf,QAAQ,iBAAiB;EACzB,IAAI,CAAC,oBAAoB,IAAI,gBAAA,GAAiC;GAC5D,QAAQ,wBAAwB;GAChC,QAAQ,mBAAmB;;;;AAKjC,MAAa,6BACX,WACA,YACA,YACG;CACH,MAAM,yBAAyB,CAAC,oBAAoB;CAEpD,IAAI,YAAY;EACd,QAAQ,iBAAiB;EACzB,IAAI,wBACF,QAAQ,wBAAwB;;CAIpC,IAAI,aAAa,wBACf,QAAQ,sBAAsB;;AAIlC,MAAa,yBAAyB;CACpC,gBAAgB;CAChB,QAAQ;CACT;AAED,MAAa,2BAA2B;CACtC,MAAM,UAAU,0BAA0B;CAC1C,IAAI,SACF,OAAO,cAAc;CAEvB,OAAO;;AAGT,MAAM,mBAAmB;AACzB,MAAM,0BACJ;AAEF,MAAM,kBAAkB;AACxB,MAAM,wBAAwB,gBAAgB;AAC9C,MAAM,aAAa,qBAAqB;AACxC,MAAM,0BACJ;AAEF,MAAM,cAAc;AAEpB,MAAa,kBAAkB,UAAiB;CAC9C,MAAM,mBAAmB,qBAAqB;CAC9C,IAAI,kBACF,OAAO,uBAAuB;CAGhC,IAAI,oBAAoB,EACtB,OAAO;CAGT,IAAI,MAAM,eACR,OAAO,MAAM;CAGf,OAAO,MAAM,gBAAgB,eACzB,kCACA,eAAe,MAAM,YAAY;;AAGvC,MAAa,8BAA8B,YAAoC;CAC7E,IAAI,oBAAoB,EACtB;CAKF,MAAM,iBAAiB,YAAY;CACnC,QAAQ,qBAAqB;CAC7B,QAAQ,kBAAkB;CAG1B,QAAQ,wBAAwB;CAChC,QAAQ,mBAAmB;CAC3B,QAAQ,gBAAgB;CAExB,OAAO,QAAQ;;AAGjB,MAAa,qBAAqB,UAAyC;CACzE,IAAI,oBAAoB,EACtB,OAAO;EACL,eAAe,UAAU,MAAM;EAC/B,cAAc,oBAAoB;EACnC;CAEH,OAAO;EACL,QAAQ;EACR,eAAe,SAAS,MAAM;EAC9B,cAAc;EACd,wBAAwB;EACxB,uCAAuC;EACxC;;AAGH,MAAa,wBAAwB,UAAiB;CACpD,IAAI,oBAAoB,EACtB,OAAO;EACL,eAAe,UAAU,MAAM;EAC/B,cAAc,oBAAoB;EACnC;CAEH,MAAM,UAAU,qBAAqB,MAAM;CAC3C,QAAQ,wBAAwB;CAChC,QAAQ,mBAAmB;CAC3B,OAAO,QAAQ;CACf,OAAO,QAAQ;CACf,OAAO;;AAGT,MAAa,kBACX,OACA,WACA,SAAkB,UACf;CACH,IAAI,oBAAoB,EAAE;EACxB,MAAM,UAAkC;GACtC,eAAe,UAAU,MAAM;GAC/B,GAAG,uBAAuB;GAC1B,iBAAiB;GAClB;EAED,MAAM,QAAQ,eAAe,UAAU;EACvC,MAAM,YAAY,OAAO,UAAU,MAAM;EAGzC,IAAI,WAAW,WAAW,YAAY,EACpC,QAAQ,gBAAgB,2BAA2B,UAAU;EAG/D,IAAI,OAAO,iBACT,QAAQ,wBAAwB,MAAM;EAGxC,IAAI,OAAO,iBACT,QAAQ,yBAAyB,MAAM;EAGzC,IAAI,QAAQ,QAAQ,4BAA4B;EAEhD,OAAO;;CAGT,OAAO,qBAAqB,OAAO,WAAW,OAAO;;AAGvD,MAAM,wBACJ,OACA,WACA,SAAkB,UACf;CACH,MAAM,iBAAiB,aAAa,YAAY;CAChD,MAAM,UAAkC;EACtC,eAAe,UAAU,MAAM;EAC/B,gBAAgB,iBAAiB,CAAC;EAClC,0BAA0B;EAC1B,oBAAoB,MAAM;EAC1B,kBAAkB,UAAU,MAAM;EAClC,yBAAyB;EACzB,cAAc;EACd,iBAAiB;EACjB,wBAAwB;EACxB,gBAAgB;EAChB,uCAAuC;EACvC,mBAAmB;EACnB,sBAAsB;EACvB;CAED,IAAI,QAAQ,QAAQ,4BAA4B;CAEhD,IAAI,MAAM,cACR,QAAQ,sBAAsB,MAAM;CAGtC,IAAI,MAAM,iBACR,QAAQ,sBAAsB,MAAM;CAGtC,OAAO;;AAGT,MAAa,sBAAsB;AACnC,MAAa,iBAAiB,UAAyC;CACrE,IAAI,oBAAoB,EACtB,OAAO;EACL,eAAe,UAAU,MAAM;EAC/B,GAAG,yBAAyB;EAC7B;CAEH,OAAO;EACL,eAAe,SAAS,MAAM;EAC9B,cAAc;EACd,wBAAwB;EACxB,uCAAuC;EACxC;;AAGH,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,oBAAoB,CAAC,YAAY,CAAC,KAAK,IAAI;AACxD,MAAa,4BAA4B;;;ACrTzC,IAAa,YAAb,cAA+B,MAAM;CACnC;CAEA,YAAY,SAAiB,UAAoB;EAC/C,MAAM,QAAQ;EACd,KAAK,WAAW;;;AAIpB,eAAsB,aACpB,GACA,OACmB;CACnB,QAAQ,MAAM,mBAAmB,MAAM;CAEvC,IAAI,iBAAiB,WAAW;EAC9B,IAAI,MAAM,SAAS,WAAW,KAC5B,KAAK,MAAM,CAAC,MAAM,UAAU,MAAM,SAAS,SAAS;GAClD,MAAM,YAAY,KAAK,aAAa;GACpC,IAAI,cAAc,iBAAiB,UAAU,WAAW,KAAK,EAC3D,EAAE,OAAO,MAAM,MAAM;;EAK3B,MAAM,YAAY,MAAM,MAAM,SAAS,MAAM;EAC7C,IAAI;EACJ,IAAI;GACF,YAAY,KAAK,MAAM,UAAU;UAC3B;GACN,YAAY;;EAEd,QAAQ,MAAM,eAAe,UAAU;EACvC,OAAO,EAAE,KACP,EACE,OAAO;GACL,SAAS;GACT,MAAM;GACP,EACF,EACD,MAAM,SAAS,OAChB;;CAGH,OAAO,EAAE,KACP,EACE,OAAO;EACL,SAAU,MAAgB;EAC1B,MAAM;EACP,EACF,EACD,IACD;;;;ACnDH,MAAa,kBAAkB,OAC7B,gBACkC;CAClC,MAAM,sBAAsB,eAAe,MAAM;CACjD,IAAI,CAAC,qBACH,MAAM,IAAI,MAAM,yBAAyB;CAG3C,MAAM,YAAY;EAAE,GAAG;EAAO,aAAa;EAAqB;CAChE,MAAM,WAAW,MAAM,MACrB,GAAG,qBAAqB,CAAC,yBACzB,EACE,SAAS,cAAc,UAAU,EAClC,CACF;CAED,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,UAAU,+BAA+B,SAAS;CAG9D,OAAQ,MAAM,SAAS,MAAM;;;;ACpB/B,MAAa,YAAY,YAAY;CACnC,QAAQ,KAAK,wBAAwB,eAAe,MAAM,CAAC,SAAS;CACpE,MAAM,WAAW,MAAM,MAAM,GAAG,eAAe,MAAM,CAAC,UAAU,EAC9D,SAAS,qBAAqB,MAAM,EACrC,CAAC;CAEF,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,YAAY,MAAM,SAAS,OAAO,CAAC,MAAM;EAE/C,QAAQ,MAAM,sCAAsC,UAAU;EAE9D,MAAM,IAAI,UAAU,wBAAwB,SAAS;;CAGvD,OAAQ,MAAM,SAAS,MAAM;;;;ACpB/B,MAAM,WAAW;AAEjB,eAAsB,mBAAmB;CACvC,MAAM,QAAQ,SAAS;CACvB,OAAO;;;;ACAT,MAAM,wBAAwB,OAAO,GAAG;AACxC,MAAM,yBAAyB;AAmC/B,MAAM,yBAAyB,IAAI,IAAI;CAAC;CAAS;CAAS;CAAO,CAAC;AAElE,MAAM,wBAAgC;CACpC,IAAI,CAAC,QAAQ,IAAI,MACf,MAAM,IAAI,MAAM,2BAA2B;CAG7C,OAAO,QAAQ,IAAI;;AAGrB,MAAM,4BAAoC;CACxC,IAAI;CAEJ,QAAQ,QAAQ,UAAhB;EACE,KAAK;GACH,SAAS,KAAK,MAAM,KAClB,iBAAiB,EACjB,WACA,sBACD;GACD;EAEF,KAAK;GACH,SACE,QAAQ,IAAI,kBACT,KAAK,MAAM,KAAK,iBAAiB,EAAE,SAAS;GACjD;EAEF,SACE,MAAM,IAAI,MAAM,uBAAuB;;CAI3C,OAAO,KAAK,MAAM,KAAK,QAAQ,aAAa,kBAAkB,WAAW;;AAG3E,MAAM,sBAAsB,UAAmD;CAC7E,OAAO,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS;;AAGrE,MAAM,yBAAyB,OAC7B,aACgC;CAChC,MAAM,EAAE,aAAa,MAAM,OAAO;CAElC,IAAI;EACF,OAAO,MAAM,SAAS,UAAU,OAAO;UAChC,OAAO;EACd,IAAI,mBAAmB,MAAM,EAC3B;EAGF,MAAM;;;AAIV,MAAM,0BAA0B,OAC9B,UACA,aACkB;CAClB,MAAM,EAAE,OAAO,cAAc,MAAM,OAAO;CAE1C,MAAM,MAAM,KAAK,MAAM,QAAQ,SAAS,EAAE,EAAE,WAAW,MAAM,CAAC;CAC9D,MAAM,UAAU,UAAU,UAAU,OAAO;;AAG7C,MAAM,+BAAyD;CAC7D,MAAM,gBACJ,QAAQ,IAAI,0BAA0B,QAAQ,IAAI,yBACjD,aAAa;CAEhB,OAAO,gBAAgB,uBAAuB,IAAI,aAAa,GAC3D,QACA,KAAA;;AAGN,MAAM,aAAa,YAAwC;CACzD,MAAM,SAAS,MAAM,OAAO;CAI5B,OAFE,aAAa,SAAU,OAAO,UAAuB;;AAKzD,MAAM,0BAA0B,UAAyC;CACvE,IAAI,CAAC,OACH,OAAO;CAGT,MAAM,YAAY,OAAO,MAAM,KAAK;CAEpC,OAAO,OAAO,SAAS,UAAU,IAAI,cAAc;;AAGrD,MAAM,wBAAwB,YAGxB;CACJ,MAAM,SAAS,MAAM,YAAY;CAEjC,OAAO;EACL,UAAU,IAAI,OAAO;GACnB,MAAM,OAAO;GACb,KAAK;GACL,MAAM,wBAAwB;GAC/B,CAAC;EACF,OAAO,OAAO;EACf;;AAGH,MAAM,qBAAqB,OACzB,UACA,SACgC;CAChC,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,SAAS,IAAI,OAAO,OAAO,SAAS;GAClC,IAAI,uBAAuB,MAAM,EAAE;IACjC,QAAQ,KAAA,EAAU;IAClB;;GAGF,IAAI,OAAO;IACT,OACE,iBAAiB,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,CACrE;IACD;;GAGF,QAAQ,MAAM,MAAM;IACpB;GACF;;AAGJ,MAAM,sBAAsB,OAAO,EACjC,UACA,OACA,MACA,YAMmB;CACnB,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,SAAS,IAAI,MAAM,OAAO,QAAQ,UAAU;GAC1C,IAAI,OAAO;IACT,OACE,iBAAiB,QAAQ,wBAAQ,IAAI,MAAM,yBAAyB,CACrE;IACD;;GAGF,SAAS;IACT;GACF;;AAGJ,MAAa,0BAA0B,YAElC;CACH,QAAQ,QAAQ,UAAhB;EACE,KAAK,SAAS;GACZ,MAAM,EAAE,aAAa,MAAM,uBAAuB;GAElD,OAAO,mBAAmB,UAAU,uBAAuB;;EAE7D,KAAK;EACL,KAAK,SACH,OAAO,uBAAuB,qBAAqB,CAAC;EAEtD,SACE,MAAM,IAAI,MAAM,uBAAuB;;;AAK7C,MAAM,0BAA0B,OAAO,aAAoC;CACzE,QAAQ,QAAQ,UAAhB;EACE,KAAK,SAAS;GACZ,MAAM,EAAE,UAAU,UAAU,MAAM,uBAAuB;GAEzD,MAAM,oBAAoB;IACxB;IACA;IACA,MAAM;IACN,OAAO;IACR,CAAC;GACF;;EAEF,KAAK;EACL,KAAK;GACH,MAAM,wBAAwB,qBAAqB,EAAE,SAAS;GAC9D;EAEF,SACE,MAAM,IAAI,MAAM,uBAAuB;;;AAK7C,MAAM,6BAAqC,YAAY,CAAC,aAAa;AAErE,eAAsB,oBAAqC;CACzD,IAAI;CAEJ,IAAI;EACF,WAAW,MAAM,yBAAyB;UACnC,OAAO;EACd,QAAQ,MAAM,mCAAmC,MAAM;;CAGzD,IAAI,UACF,OAAO;CAGT,MAAM,cAAc,sBAAsB;CAE1C,IAAI;EACF,MAAM,wBAAwB,YAAY;UACnC,OAAO;EACd,QAAQ,KACN,0DACA,MACD;;CAGH,OAAO;;;;AC7PT,MAAa,SAAS,OACpB,IAAI,SAAS,YAAY;CACvB,WAAW,SAAS,GAAG;EACvB;AAEJ,MAAa,aAAa,UACxB,UAAU,QAAQ,UAAU,KAAA;AAE9B,eAAsB,cAA6B;CACjD,MAAM,SAAS,MAAM,WAAW;CAChC,MAAM,SAAS;EACb,GAAG;EACH,MAAM,OAAO,KAAK,QACf,UACC,MAAM,wBAAwB,MAAM,aAAa,SAAS,aAC7D;EACF;;AAGH,MAAa,qBAAqB,YAAY;CAC5C,MAAM,WAAW,MAAM,kBAAkB;CACzC,MAAM,gBAAgB;CAEtB,QAAQ,KAAK,yBAAyB,WAAW;;AAGnD,MAAM,sBAAsB,IAAI,IAAI;CAClC;CACA;CACA;CACD,CAAC;AAEF,SAAS,mBAAmB,WAA4B;CACtD,MAAM,gBAAgB,UAAU,WAAW,KAAK,IAAI,CAAC,aAAa;CAClE,OAAO,CAAC,oBAAoB,IAAI,cAAc;;AAGhD,SAAgB,SAAwB;CACtC,MAAM,SAAS,mBAAmB;CAElC,KAAK,MAAM,QAAQ,QAAQ;EACzB,MAAM,mBAAmB,OAAO;EAChC,IAAI;QACG,MAAM,EAAE,SAAS,kBACpB,IAAI,mBAAmB,IAAI,EACzB,OAAO;;;CAKf,OAAO;;AAGT,MAAa,0BAA0B;CACrC,MAAM,aAAa,QAAQ,IAAI,YAAY;CAC3C,MAAM,eAAe,WAAW,SAAS,CACtC,OAAO,YAAY,OAAO,CAC1B,OAAO,MAAM;CAChB,QAAQ,MAAM,qBAAqB,MAAM,eAAe;;AAG1D,MAAa,sBAAsB,YAAY;CAC7C,MAAM,iBAAiB,MAAM,mBAAmB;CAChD,QAAQ,MAAM,2BAA2B,MAAM,iBAAiB;;AAGlE,MAAM,0BAA0B,OAAU;AAC1C,MAAM,4BAA4B,OAAU;AAC5C,IAAI,4BAAkE;AAEtE,MAAM,0BAA0B;CAC9B,MAAM,kBAAkB,YAAY,GAAG,KAAK,KAAK,CAAC,UAAU;CAC5D,QAAQ,MAAM,gCAAgC,MAAM,kBAAkB;;AAGxE,MAAa,qCAAqC;CAChD,IAAI,2BAA2B;EAC7B,aAAa,0BAA0B;EACvC,4BAA4B;;;AAIhC,MAAM,iCAAiC;CAErC,MAAM,QAAQ,0BADM,KAAK,MAAM,KAAK,QAAQ,GAAG,0BACI;CACnD,QAAQ,MACN,gDAAgD,KAAK,MACnD,QAAQ,IACT,CAAC,UACH;CAED,8BAA8B;CAC9B,4BAA4B,iBAAiB;EAC3C,IAAI;GACF,mBAAmB;WACZ,OAAO;GACd,QAAQ,MAAM,iDAAiD,MAAM;YAC7D;GACR,0BAA0B;;IAE3B,MAAM;;AAGX,MAAa,6BAA6B;CACxC,8BAA8B;CAC9B,mBAAmB;CACnB,0BAA0B;;AAS5B,MAAM,YAAY,UAChB,OAAO,UAAU,YAAY,UAAU;AAEzC,MAAM,sBACJ,eACA,UACkB;CAClB,MAAM,QAAQ,gBAAgB;CAC9B,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;;AAGjE,MAAM,mBAAmB,WAAmD;CAC1E,IAAI;EACF,MAAM,SAAkB,KAAK,MAAM,OAAO;EAC1C,OAAO,SAAS,OAAO,GAAG,SAAS;SAC7B;EACN,OAAO;;;AAIX,MAAa,uBACX,WACkE;CAClE,IAAI,CAAC,UAAU,OAAO,WAAW,UAC/B,OAAO;EAAE,kBAAkB;EAAM,WAAW;EAAM;CAGpD,MAAM,yBACJ,OAAO,MAAM,uBAAuB,GAAG,MAAM;CAC/C,MAAM,kBAAkB,OAAO,MAAM,iBAAiB,GAAG,MAAM;CAE/D,MAAM,eACJ,0BAA0B,kBAAkB,OAAO,gBAAgB,OAAO;CAS5E,OAAO;EAAE,kBANP,0BACG,mBAAmB,cAAc,YAAY,IAC7C,mBAAmB,cAAc,eAAe;EAI1B,WAFzB,mBAAmB,mBAAmB,cAAc,aAAa;EAE7B;;AAGxC,MAAM,uBACJ,aACkB;CAClB,KAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;EAC7C,MAAM,MAAM,SAAS;EACrB,IAAI,IAAI,SAAS,UAAU,IAAI;OACzB,OAAO,IAAI,YAAY,UACzB,OAAO,IAAI;QACN,IAAI,MAAM,QAAQ,IAAI,QAAQ,EAAE;IACrC,MAAM,QAAQ,IAAI,QACf,QAAQ,MAAM,EAAE,SAAS,cAAc,CACvC,KAAK,OAAO;KAAE,GAAG;KAAG,eAAe,KAAA;KAAW,EAAE;IACnD,IAAI,MAAM,SAAS,GACjB,OAAO,KAAK,UAAU,MAAM;;;;CAKpC,OAAO;;AAGT,MAAa,gCACX,SAGA,cACW;CACX,MAAM,WAAW,QAAQ;CACzB,IAAI,UAAU;EACZ,MAAM,kBACJ,OAAO,aAAa,WAAW,WAAW,oBAAoB,SAAS;EAEzE,IAAI,iBACF,OAAO,SACJ,aAAa,OAAO,MAAM,gBAAgB,MAAM,gBAClD;;CAIL,OAAO,YAAY;;AAGrB,MAAa,oBACX,kBACA,MACuB;CACvB,MAAM,SAAS,iBAAiB,UAAU;CAC1C,MAAM,YACJ,SACE,oBAAoB,OAAO,CAAC,aAAa,KAAA,IACzC,EAAE,IAAI,OAAO,eAAe;CAEhC,OAAO,YAAY,QAAQ,UAAU,GAAG;;AAG1C,MAAa,WAAW,YAA4B;CAClD,MAAM,YAAY,WAAW,SAAS,CACnC,OAAO,QAAQ,CACf,QAAQ,CACR,SAAS,GAAG,GAAG;CAElB,UAAU,KAAM,UAAU,KAAK,KAAQ;CACvC,UAAU,KAAM,UAAU,KAAK,KAAQ;CAEvC,MAAM,UAAU,UAAU,SAAS,MAAM;CAEzC,OAAO,GAAG,QAAQ,MAAM,GAAG,EAAE,CAAC,GAAG,QAAQ,MAAM,GAAG,GAAG,CAAC,GAAG,QAAQ,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,MAAM,GAAG"}
|