@nick3/copilot-api 1.10.8 → 1.10.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +141 -46
  2. package/README.zh-CN.md +141 -46
  3. package/dist/{account-COtMmvzU.js → account-DpW8RaT6.js} +3 -3
  4. package/dist/{account-COtMmvzU.js.map → account-DpW8RaT6.js.map} +1 -1
  5. package/dist/admin/AGENTS.md +19 -0
  6. package/dist/auth-nO-eHeO_.js +327 -0
  7. package/dist/auth-nO-eHeO_.js.map +1 -0
  8. package/dist/{check-usage-DdevqHE5.js → check-usage-ZifYvA3w.js} +4 -42
  9. package/dist/check-usage-ZifYvA3w.js.map +1 -0
  10. package/dist/config-CmhIPHn_.js +578 -0
  11. package/dist/config-CmhIPHn_.js.map +1 -0
  12. package/dist/{debug-BMo6ltbp.js → debug-DvpksqEL.js} +18 -7
  13. package/dist/debug-DvpksqEL.js.map +1 -0
  14. package/dist/main.js +5 -10
  15. package/dist/main.js.map +1 -1
  16. package/dist/mcp-http-BhELuvog.js +2 -0
  17. package/dist/mcp-http-DI4Vz01p.js +82 -0
  18. package/dist/mcp-http-DI4Vz01p.js.map +1 -0
  19. package/dist/mcp-http-config-DMdUDz1D.js +39 -0
  20. package/dist/mcp-http-config-DMdUDz1D.js.map +1 -0
  21. package/dist/mcp-pLTPS0tO.js +79 -0
  22. package/dist/mcp-pLTPS0tO.js.map +1 -0
  23. package/dist/{tool-search-BrN7M0Dd.js → mcp-server-DEqHrXFq.js} +25 -2
  24. package/dist/mcp-server-DEqHrXFq.js.map +1 -0
  25. package/dist/{paths-CclKwouX.js → paths-Bpsb62LK.js} +3 -1
  26. package/dist/paths-Bpsb62LK.js.map +1 -0
  27. package/dist/{poll-access-token-BAgM2-7k.js → poll-access-token-GzVkiTH8.js} +71 -4
  28. package/dist/poll-access-token-GzVkiTH8.js.map +1 -0
  29. package/dist/{request-outbound-BJjWS_jF.js → request-outbound-BkEA8Wgb.js} +1 -1
  30. package/dist/{request-outbound-Pu1kp2x8.js → request-outbound-DZTxxtcx.js} +3 -3
  31. package/dist/{request-outbound-Pu1kp2x8.js.map → request-outbound-DZTxxtcx.js.map} +1 -1
  32. package/dist/{proxy-_U-hgwIn.js → responses-bridge-registry-BJ5Sbh6-.js} +116 -577
  33. package/dist/responses-bridge-registry-BJ5Sbh6-.js.map +1 -0
  34. package/dist/{server-DulP9mYd.js → server-DJ3_UGc4.js} +339 -168
  35. package/dist/server-DJ3_UGc4.js.map +1 -0
  36. package/dist/start-DaB0AcjZ.js +526 -0
  37. package/dist/start-DaB0AcjZ.js.map +1 -0
  38. package/dist/token-DrFDLVxa.js +365 -0
  39. package/dist/token-DrFDLVxa.js.map +1 -0
  40. package/package.json +1 -1
  41. package/dist/auth-B0y-2njL.js +0 -226
  42. package/dist/auth-B0y-2njL.js.map +0 -1
  43. package/dist/check-usage-DdevqHE5.js.map +0 -1
  44. package/dist/debug-BMo6ltbp.js.map +0 -1
  45. package/dist/get-copilot-token-8Rm-rVsp.js +0 -17
  46. package/dist/get-copilot-token-8Rm-rVsp.js.map +0 -1
  47. package/dist/mcp-9Hgepkc5.js +0 -37
  48. package/dist/mcp-9Hgepkc5.js.map +0 -1
  49. package/dist/paths-CclKwouX.js.map +0 -1
  50. package/dist/poll-access-token-BAgM2-7k.js.map +0 -1
  51. package/dist/proxy-_U-hgwIn.js.map +0 -1
  52. package/dist/server-DulP9mYd.js.map +0 -1
  53. package/dist/start-CtEoE2gt.js +0 -274
  54. package/dist/start-CtEoE2gt.js.map +0 -1
  55. package/dist/tool-search-BrN7M0Dd.js.map +0 -1
@@ -1,274 +0,0 @@
1
- import { A as state, F as initOpencodeVersion, a as cacheVsCodeSessionId, h as getDeviceCode, i as cacheVsCodeDeviceId, m as getGitHubUser, n as cacheMacMachineId, r as cacheVSCodeVersion, t as pollAccessToken } from "./poll-access-token-BAgM2-7k.js";
2
- import { h as saveAccountToken, n as parseAccountType, r as addAccountToRegistry } from "./account-COtMmvzU.js";
3
- import { r as ensurePaths } from "./paths-CclKwouX.js";
4
- import { A as getModelRefreshIntervalMs, P as isAccountAffinityEnabled, V as mergeConfigWithDefaults, a as stopQuotaRefreshScheduler, c as applySharedSessionAffinityRetention, i as startQuotaRefreshSchedulerFromConfig, n as initProxyFromEnv, r as registerQuotaRefreshSchedulerShutdownCleanup, s as accountsManager } from "./proxy-_U-hgwIn.js";
5
- import { defineCommand } from "citty";
6
- import consola from "consola";
7
- import { execSync } from "node:child_process";
8
- import clipboard from "clipboardy";
9
- import { serve } from "srvx";
10
- import process$1 from "node:process";
11
- //#region src/lib/shell.ts
12
- function getShell() {
13
- const { platform, ppid, env } = process$1;
14
- if (platform === "win32") {
15
- try {
16
- if (execSync(`wmic process get ParentProcessId,Name | findstr "${ppid}"`, { stdio: "pipe" }).toString().toLowerCase().includes("powershell.exe")) return "powershell";
17
- } catch {
18
- return "cmd";
19
- }
20
- return "cmd";
21
- } else {
22
- const shellPath = env.SHELL;
23
- if (shellPath) {
24
- if (shellPath.endsWith("zsh")) return "zsh";
25
- if (shellPath.endsWith("fish")) return "fish";
26
- if (shellPath.endsWith("bash")) return "bash";
27
- }
28
- return "sh";
29
- }
30
- }
31
- /**
32
- * Generates a copy-pasteable script to set multiple environment variables
33
- * and run a subsequent command.
34
- * @param {EnvVars} envVars - An object of environment variables to set.
35
- * @param {string} commandToRun - The command to run after setting the variables.
36
- * @returns {string} The formatted script string.
37
- */
38
- function generateEnvScript(envVars, commandToRun = "") {
39
- const shell = getShell();
40
- const filteredEnvVars = Object.entries(envVars).filter(([, value]) => value !== void 0);
41
- let commandBlock;
42
- switch (shell) {
43
- case "powershell":
44
- commandBlock = filteredEnvVars.map(([key, value]) => `$env:${key} = ${value}`).join("; ");
45
- break;
46
- case "cmd":
47
- commandBlock = filteredEnvVars.map(([key, value]) => `set ${key}=${value}`).join(" & ");
48
- break;
49
- case "fish":
50
- commandBlock = filteredEnvVars.map(([key, value]) => `set -gx ${key} ${value}`).join("; ");
51
- break;
52
- default: {
53
- const assignments = filteredEnvVars.map(([key, value]) => `${key}=${value}`).join(" ");
54
- commandBlock = filteredEnvVars.length > 0 ? `export ${assignments}` : "";
55
- break;
56
- }
57
- }
58
- if (commandBlock && commandToRun) return `${commandBlock}${shell === "cmd" ? " & " : " && "}${commandToRun}`;
59
- return commandBlock || commandToRun;
60
- }
61
- //#endregion
62
- //#region src/start.ts
63
- /**
64
- * Run the interactive authentication flow to add a new account.
65
- * Called automatically when no accounts are found.
66
- */
67
- async function runAuthFlow(accountType) {
68
- consola.warn("No accounts found. Starting authentication flow...");
69
- const deviceResponse = await getDeviceCode();
70
- consola.info(`Please enter the code "${deviceResponse.user_code}" at ${deviceResponse.verification_uri}`);
71
- const token = await pollAccessToken(deviceResponse);
72
- if (state.showToken) consola.info("GitHub token:", token);
73
- const accountId = (await getGitHubUser({
74
- githubToken: token,
75
- accountType
76
- })).login;
77
- await saveAccountToken(accountId, token);
78
- await addAccountToRegistry({
79
- id: accountId,
80
- accountType,
81
- addedAt: Date.now()
82
- });
83
- consola.success(`Account "${accountId}" added successfully!`);
84
- }
85
- function logClaudeCodeTip() {
86
- consola.log("\n💡 Tip: The --claude-code flag simply generates a clipboard command for launching Claude Code. \nAll models remain fully accessible without this flag, just configure the model ID directly in your settings.json file.");
87
- }
88
- async function setupClaudeCode(models, serverUrl) {
89
- const selectedModel = await consola.prompt("Select a model to use with Claude Code", {
90
- type: "select",
91
- options: models.data.map((model) => model.id)
92
- });
93
- const command = generateEnvScript({
94
- ANTHROPIC_BASE_URL: serverUrl,
95
- ANTHROPIC_AUTH_TOKEN: "dummy",
96
- ANTHROPIC_MODEL: selectedModel,
97
- ANTHROPIC_DEFAULT_SONNET_MODEL: selectedModel,
98
- ANTHROPIC_DEFAULT_HAIKU_MODEL: await consola.prompt("Select a small model to use with Claude Code", {
99
- type: "select",
100
- options: models.data.map((model) => model.id)
101
- }),
102
- DISABLE_NON_ESSENTIAL_MODEL_CALLS: "1",
103
- CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1",
104
- CLAUDE_CODE_ATTRIBUTION_HEADER: "0",
105
- CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: "false",
106
- CLAUDE_CODE_DISABLE_TERMINAL_TITLE: "true",
107
- CLAUDE_CODE_ENABLE_AWAY_SUMMARY: "0",
108
- CLAUDE_PLUGIN_ENABLE_QUESTION_RULES: "true"
109
- }, "claude");
110
- try {
111
- clipboard.writeSync(command);
112
- consola.success("Copied Claude Code command to clipboard!");
113
- } catch {
114
- consola.warn("Failed to copy to clipboard. Here is the Claude Code command:");
115
- consola.log(command);
116
- }
117
- }
118
- async function runServer(options) {
119
- consola.options.throttle = 0;
120
- mergeConfigWithDefaults();
121
- accountsManager.setAccountAffinityEnabled(isAccountAffinityEnabled());
122
- accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs());
123
- await initOpencodeVersion();
124
- if (options.proxyEnv) initProxyFromEnv();
125
- state.verbose = options.verbose;
126
- if (options.verbose) {
127
- consola.level = 5;
128
- consola.info("Verbose logging enabled");
129
- }
130
- state.accountType = options.accountType;
131
- if (options.accountType !== "individual") consola.info(`Using ${options.accountType} plan GitHub account`);
132
- state.manualApprove = options.manual;
133
- state.rateLimitSeconds = options.rateLimit;
134
- state.rateLimitWait = options.rateLimitWait;
135
- state.showToken = options.showToken;
136
- await ensurePaths();
137
- applySharedSessionAffinityRetention();
138
- await cacheVSCodeVersion();
139
- cacheMacMachineId();
140
- cacheVsCodeSessionId();
141
- await cacheVsCodeDeviceId();
142
- await accountsManager.initialize(state.vsCodeVersion);
143
- if (options.githubToken) {
144
- await accountsManager.setTemporaryAccount(options.githubToken, options.accountType);
145
- consola.info("Using provided GitHub token as temporary account");
146
- }
147
- if (!accountsManager.hasAccounts()) if (options.skipAuth) consola.warn("No accounts found. Skipping auth flow (--skip-auth). Add accounts via the Admin UI.");
148
- else try {
149
- await runAuthFlow(options.accountType);
150
- accountsManager.shutdown();
151
- stopQuotaRefreshScheduler();
152
- await accountsManager.initialize(state.vsCodeVersion);
153
- accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs());
154
- } catch (error) {
155
- consola.error("Failed to add account:", error);
156
- process.exit(1);
157
- }
158
- startQuotaRefreshSchedulerFromConfig();
159
- registerQuotaRefreshSchedulerShutdownCleanup();
160
- const models = accountsManager.getFirstAccountModels();
161
- consola.info(`Available models: \n${models?.data.map((model) => `- ${model.id}`).join("\n") ?? "(no models loaded)"}`);
162
- const serverUrl = `http://localhost:${options.port}`;
163
- if (options.claudeCode) {
164
- logClaudeCodeTip();
165
- if (!models?.data.length) {
166
- consola.error("Claude Code requires available models. Add an account via the Admin UI or remove --claude-code.");
167
- process.exit(1);
168
- }
169
- await setupClaudeCode(models, serverUrl);
170
- }
171
- consola.box(`🌐 Admin UI: ${serverUrl}/admin`);
172
- const { server } = await import("./server-DulP9mYd.js");
173
- serve({
174
- fetch: server.fetch,
175
- port: options.port,
176
- bun: { idleTimeout: 0 }
177
- });
178
- }
179
- const start = defineCommand({
180
- meta: {
181
- name: "start",
182
- description: "Start the Copilot API server"
183
- },
184
- args: {
185
- port: {
186
- alias: "p",
187
- type: "string",
188
- default: "4141",
189
- description: "Port to listen on"
190
- },
191
- verbose: {
192
- alias: "v",
193
- type: "boolean",
194
- default: false,
195
- description: "Enable verbose logging"
196
- },
197
- "account-type": {
198
- alias: "a",
199
- type: "string",
200
- default: "individual",
201
- description: "Account type to use (individual, business, enterprise)"
202
- },
203
- manual: {
204
- type: "boolean",
205
- default: false,
206
- description: "Enable manual request approval"
207
- },
208
- "rate-limit": {
209
- alias: "r",
210
- type: "string",
211
- description: "Rate limit in seconds between requests"
212
- },
213
- wait: {
214
- alias: "w",
215
- type: "boolean",
216
- default: false,
217
- description: "Wait instead of error when rate limit is hit. Has no effect if rate limit is not set"
218
- },
219
- "github-token": {
220
- alias: "g",
221
- type: "string",
222
- description: "Provide GitHub token directly (must be generated using the `auth` subcommand)"
223
- },
224
- "claude-code": {
225
- alias: "c",
226
- type: "boolean",
227
- default: false,
228
- description: "Generate a command to launch Claude Code with Copilot API config"
229
- },
230
- "show-token": {
231
- type: "boolean",
232
- default: false,
233
- description: "Show GitHub and Copilot tokens on fetch and refresh"
234
- },
235
- "proxy-env": {
236
- type: "boolean",
237
- default: false,
238
- description: "Initialize proxy from environment variables"
239
- },
240
- "skip-auth": {
241
- type: "boolean",
242
- default: false,
243
- description: "Skip the initial CLI auth flow when no accounts are found. Use this to add accounts via the Admin UI instead."
244
- }
245
- },
246
- run({ args }) {
247
- const rateLimitRaw = args["rate-limit"];
248
- const rateLimit = rateLimitRaw === void 0 ? void 0 : Number.parseInt(rateLimitRaw, 10);
249
- let accountType;
250
- try {
251
- accountType = parseAccountType(args["account-type"]);
252
- } catch (error) {
253
- consola.error(error instanceof Error ? error.message : String(error));
254
- process.exit(1);
255
- }
256
- return runServer({
257
- port: Number.parseInt(args.port, 10),
258
- verbose: args.verbose,
259
- accountType,
260
- manual: args.manual,
261
- rateLimit,
262
- rateLimitWait: args.wait,
263
- githubToken: args["github-token"],
264
- claudeCode: args["claude-code"],
265
- showToken: args["show-token"],
266
- proxyEnv: args["proxy-env"],
267
- skipAuth: args["skip-auth"]
268
- });
269
- }
270
- });
271
- //#endregion
272
- export { start };
273
-
274
- //# sourceMappingURL=start-CtEoE2gt.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"start-CtEoE2gt.js","names":["process"],"sources":["../src/lib/shell.ts","../src/start.ts"],"sourcesContent":["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 } from \"srvx\"\n\nimport {\n registerQuotaRefreshSchedulerShutdownCleanup,\n startQuotaRefreshSchedulerFromConfig,\n stopQuotaRefreshScheduler,\n} from \"~/lib/quota-refresh-scheduler-runtime\"\n\nimport { accountsManager } from \"./lib/accounts-manager\"\nimport { addAccountToRegistry, saveAccountToken } from \"./lib/accounts-registry\"\nimport {\n getModelRefreshIntervalMs,\n isAccountAffinityEnabled,\n mergeConfigWithDefaults,\n} from \"./lib/config\"\nimport { initOpencodeVersion } from \"./lib/opencode\"\nimport { ensurePaths } from \"./lib/paths\"\nimport { initProxyFromEnv } from \"./lib/proxy\"\nimport { applySharedSessionAffinityRetention } from \"./lib/session-affinity-store\"\nimport { generateEnvScript } from \"./lib/shell\"\nimport { state } from \"./lib/state\"\nimport { parseAccountType, type AccountType } from \"./lib/types/account\"\nimport {\n cacheMacMachineId,\n cacheVSCodeVersion,\n cacheVsCodeSessionId,\n cacheVsCodeDeviceId,\n} from \"./lib/utils\"\nimport { getDeviceCode } from \"./services/github/get-device-code\"\nimport { getGitHubUser } from \"./services/github/get-user\"\nimport { pollAccessToken } from \"./services/github/poll-access-token\"\n\ninterface RunServerOptions {\n port: number\n verbose: boolean\n accountType: AccountType\n manual: boolean\n rateLimit?: number\n rateLimitWait: boolean\n githubToken?: string\n claudeCode: boolean\n showToken: boolean\n proxyEnv: boolean\n skipAuth: boolean\n}\n\n/**\n * Run the interactive authentication flow to add a new account.\n * Called automatically when no accounts are found.\n */\nasync function runAuthFlow(accountType: AccountType): Promise<void> {\n consola.warn(\"No accounts found. Starting authentication flow...\")\n\n // Start device code flow\n const deviceResponse = await getDeviceCode()\n consola.info(\n `Please enter the code \"${deviceResponse.user_code}\" at ${deviceResponse.verification_uri}`,\n )\n\n // Poll for access token\n const token = await pollAccessToken(deviceResponse)\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n\n // Get user info to determine account ID\n const user = await getGitHubUser({\n githubToken: token,\n accountType,\n })\n const accountId = user.login\n\n // Save token and add to registry\n await saveAccountToken(accountId, token)\n await addAccountToRegistry({\n id: accountId,\n accountType,\n addedAt: Date.now(),\n })\n\n consola.success(`Account \"${accountId}\" added successfully!`)\n}\n\nfunction logClaudeCodeTip(): void {\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\ntype AvailableModels = NonNullable<\n ReturnType<typeof accountsManager.getFirstAccountModels>\n>\n\nasync function setupClaudeCode(\n models: AvailableModels,\n serverUrl: string,\n): Promise<void> {\n const selectedModel = await consola.prompt(\n \"Select a model to use with Claude Code\",\n {\n type: \"select\",\n options: 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: 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\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 accountsManager.setAccountAffinityEnabled(isAccountAffinityEnabled())\n accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs())\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 applySharedSessionAffinityRetention()\n await cacheVSCodeVersion()\n cacheMacMachineId()\n cacheVsCodeSessionId()\n await cacheVsCodeDeviceId()\n\n // Initialize accounts manager with VS Code version\n await accountsManager.initialize(state.vsCodeVersion)\n\n // If --github-token is provided, set it as a temporary (high priority) account\n if (options.githubToken) {\n await accountsManager.setTemporaryAccount(\n options.githubToken,\n options.accountType,\n )\n consola.info(\"Using provided GitHub token as temporary account\")\n }\n\n // Check if we have any accounts, if not, start the auth flow\n if (!accountsManager.hasAccounts()) {\n if (options.skipAuth) {\n consola.warn(\n \"No accounts found. Skipping auth flow (--skip-auth). Add accounts via the Admin UI.\",\n )\n } else {\n try {\n await runAuthFlow(options.accountType)\n\n // Re-initialize accounts manager with the new account\n accountsManager.shutdown()\n stopQuotaRefreshScheduler()\n await accountsManager.initialize(state.vsCodeVersion)\n accountsManager.setModelsRefreshIntervalMs(getModelRefreshIntervalMs())\n } catch (error) {\n consola.error(\"Failed to add account:\", error)\n process.exit(1)\n }\n }\n }\n\n startQuotaRefreshSchedulerFromConfig()\n registerQuotaRefreshSchedulerShutdownCleanup()\n\n // Get models from the first available account\n const models = accountsManager.getFirstAccountModels()\n\n consola.info(\n `Available models: \\n${models?.data.map((model) => `- ${model.id}`).join(\"\\n\") ?? \"(no models loaded)\"}`,\n )\n\n const serverUrl = `http://localhost:${options.port}`\n\n if (options.claudeCode) {\n logClaudeCodeTip()\n if (!models?.data.length) {\n consola.error(\n \"Claude Code requires available models. Add an account via the Admin UI or remove --claude-code.\",\n )\n process.exit(1)\n }\n await setupClaudeCode(models, serverUrl)\n }\n\n consola.box(`🌐 Admin UI: ${serverUrl}/admin`)\n\n const { server } = await import(\"./server\")\n\n serve({\n fetch: server.fetch,\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 \"skip-auth\": {\n type: \"boolean\",\n default: false,\n description:\n \"Skip the initial CLI auth flow when no accounts are found. Use this to add accounts via the Admin UI instead.\",\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 let accountType: AccountType\n try {\n accountType = parseAccountType(args[\"account-type\"])\n } catch (error) {\n consola.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n\n return runServer({\n port: Number.parseInt(args.port, 10),\n verbose: args.verbose,\n accountType,\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 skipAuth: args[\"skip-auth\"],\n })\n },\n})\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tool-search-BrN7M0Dd.js","names":["record"],"sources":["../src/lib/tool-search.ts"],"sourcesContent":["export const BRIDGE_TOOL_SEARCH_NAME = \"mcp__tool_search__search\"\nexport const BRIDGE_TOOL_SEARCH_ALIASES = [\n BRIDGE_TOOL_SEARCH_NAME,\n \"tool_search_search\",\n \"mcp__plugin_tool-search_tool_search__search\",\n] as const\nexport const MCP_TOOL_SEARCH_SENTINEL_TYPE = \"copilot_api_tool_search\"\n\nexport const ALWAYS_LOADED_TOOL_NAMES = [\n \"Agent\",\n \"AskUserQuestion\",\n \"Bash\",\n \"Edit\",\n \"EnterPlanMode\",\n \"ExitPlanMode\",\n \"Glob\",\n \"Grep\",\n \"Read\",\n \"Skill\",\n \"TodoWrite\",\n \"ToolSearch\",\n \"WebFetch\",\n \"Write\",\n \"apply_patch\",\n \"bash\",\n \"glob\",\n \"grep\",\n \"plan_exit\",\n \"question\",\n \"read\",\n \"skill\",\n \"task\",\n \"todowrite\",\n \"webfetch\",\n] as const\n\nconst alwaysLoadedToolNameSet = new Set<string>(ALWAYS_LOADED_TOOL_NAMES)\nconst bridgeToolSearchNameSet = new Set<string>(BRIDGE_TOOL_SEARCH_ALIASES)\n\nexport interface ToolSearchToolLike {\n name: string\n description?: string\n input_schema?: Record<string, unknown>\n defer_loading?: boolean\n}\n\nexport interface McpToolSearchSentinel {\n type: typeof MCP_TOOL_SEARCH_SENTINEL_TYPE\n names: Array<string>\n}\n\nexport const isBridgeToolSearchName = (name: string): boolean =>\n bridgeToolSearchNameSet.has(name)\n\nexport const isAlwaysLoadedToolName = (name: string): boolean =>\n alwaysLoadedToolNameSet.has(name)\n\nexport const isDeferredToolName = (name: string): boolean =>\n !isBridgeToolSearchName(name) && !isAlwaysLoadedToolName(name)\n\nexport const supportsResponsesToolSearchModel = (model: string): boolean => {\n const match = /^gpt-(\\d+)(?:\\.(\\d+))?/iu.exec(model)\n if (!match) {\n return false\n }\n\n const major = Number.parseInt(match[1], 10)\n const minor = match[2] ? Number.parseInt(match[2], 10) : 0\n\n return major > 5 || (major === 5 && minor >= 4)\n}\n\nexport const hasBridgeToolSearchTool = (\n tools: Array<ToolSearchToolLike> | undefined,\n): boolean =>\n Array.isArray(tools)\n && tools.some((tool) => isBridgeToolSearchName(tool.name))\n\nexport const resolveBridgeToolSearchName = (\n tools: Array<ToolSearchToolLike> | undefined,\n): string => {\n if (!Array.isArray(tools)) {\n return BRIDGE_TOOL_SEARCH_NAME\n }\n\n return (\n tools.find((tool) => isBridgeToolSearchName(tool.name))?.name\n ?? BRIDGE_TOOL_SEARCH_NAME\n )\n}\n\nexport const hasDeferredToolCandidate = (\n tools: Array<ToolSearchToolLike> | undefined,\n): boolean =>\n Array.isArray(tools) && tools.some((tool) => isDeferredToolName(tool.name))\n\nexport const shouldEnableResponsesToolSearch = (params: {\n model: string\n tools?: Array<ToolSearchToolLike>\n}): boolean =>\n supportsResponsesToolSearchModel(params.model)\n && hasBridgeToolSearchTool(params.tools)\n && hasDeferredToolCandidate(params.tools)\n\nexport const hasDeferredNamespaceTool = (\n tools: Array<unknown> | null | undefined,\n): boolean =>\n Array.isArray(tools)\n && tools.some((tool) => {\n if (!tool || typeof tool !== \"object\") {\n return false\n }\n\n const record = tool as Record<string, unknown>\n if (record.type !== \"namespace\" || typeof record.name !== \"string\") {\n return false\n }\n\n if (!isDeferredToolName(record.name)) {\n return false\n }\n\n const namespaceTools = record.tools\n return (\n Array.isArray(namespaceTools)\n && namespaceTools.some(\n (entry) =>\n entry\n && typeof entry === \"object\"\n && (entry as Record<string, unknown>).defer_loading === true,\n )\n )\n })\n\nexport const listDeferredToolNames = (\n tools: Array<ToolSearchToolLike>,\n): Array<string> => [\n ...new Set(\n tools\n .filter((tool) => isDeferredToolName(tool.name))\n .map((tool) => tool.name),\n ),\n]\n\nconst extractDeferredToolNamesSource = (\n record: Record<string, unknown>,\n): unknown => record.names ?? record.query ?? record.paths\n\nexport const parseDeferredToolNames = (names: unknown): Array<string> => {\n let rawNames: Array<string> = []\n\n if (typeof names === \"string\") {\n rawNames = names.split(\",\")\n } else if (Array.isArray(names)) {\n rawNames = names.flatMap((name) =>\n typeof name === \"string\" ? name.split(\",\") : [],\n )\n }\n\n return [\n ...new Set(\n rawNames.map((name) => name.trim()).filter((name) => name.length > 0),\n ),\n ]\n}\n\nexport const createMcpToolSearchSentinel = (names: unknown): string =>\n JSON.stringify({\n type: MCP_TOOL_SEARCH_SENTINEL_TYPE,\n names: parseDeferredToolNames(names),\n } satisfies McpToolSearchSentinel)\n\nexport const parseMcpToolSearchSentinel = (\n text: string,\n): McpToolSearchSentinel | null => {\n try {\n const parsed: unknown = JSON.parse(text)\n if (!parsed || typeof parsed !== \"object\") {\n return null\n }\n\n const record = parsed as Record<string, unknown>\n if (record.type !== MCP_TOOL_SEARCH_SENTINEL_TYPE) {\n return null\n }\n\n const names = parseDeferredToolNames(extractDeferredToolNamesSource(record))\n if (names.length === 0) {\n return null\n }\n\n return {\n type: MCP_TOOL_SEARCH_SENTINEL_TYPE,\n names,\n }\n } catch {\n return null\n }\n}\n\nexport const normalizeToolSearchBridgeArguments = (\n argumentsValue: Record<string, unknown> | string,\n): Record<string, unknown> => {\n if (typeof argumentsValue !== \"string\") {\n const names = parseDeferredToolNames(\n extractDeferredToolNamesSource(argumentsValue),\n )\n return names.length > 0 ? { names } : {}\n }\n\n try {\n const parsed: unknown = JSON.parse(argumentsValue)\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n const record = parsed as Record<string, unknown>\n const names = parseDeferredToolNames(\n extractDeferredToolNamesSource(record),\n )\n return names.length > 0 ? { names } : {}\n }\n } catch {\n // Treat a raw string as the comma-separated protocol payload.\n }\n\n const names = parseDeferredToolNames(argumentsValue)\n return names.length > 0 ? { names } : {}\n}\n\nexport const formatToolSearchBridgeArguments = (\n argumentsValue: Record<string, unknown> | string,\n): Record<string, unknown> => {\n const normalized = normalizeToolSearchBridgeArguments(argumentsValue)\n const names = normalized.names\n\n if (!Array.isArray(names) || names.length === 0) {\n return {}\n }\n\n return { names: names.join(\",\") }\n}\n\nexport const selectDeferredToolsByNames = (\n names: unknown,\n tools: Array<ToolSearchToolLike>,\n): Array<ToolSearchToolLike> => {\n const requestedNames = parseDeferredToolNames(names)\n if (requestedNames.length === 0) {\n return []\n }\n\n const deferredToolByName = new Map(\n tools\n .filter((tool) => isDeferredToolName(tool.name))\n .map((tool) => [tool.name, tool]),\n )\n\n return requestedNames.flatMap((name) => {\n const tool = deferredToolByName.get(name)\n return tool ? [tool] : []\n })\n}\n\nexport const hasDeferredMcpNamespaceTool = hasDeferredNamespaceTool\n"],"mappings":"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"}