@jeffreycao/copilot-api 2.6.23 → 2.6.25

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 (33) hide show
  1. package/README.md +2 -2
  2. package/README.zh-CN.md +2 -2
  3. package/dist/{auth-DvEHwSn1.js → auth-BM1NSmaY.js} +6 -4
  4. package/dist/auth-BM1NSmaY.js.map +1 -0
  5. package/dist/auth-DGt1r0Ik.js +2 -0
  6. package/dist/{config-B_pC8QXv.js → config-AlcbghlW.js} +24 -370
  7. package/dist/config-AlcbghlW.js.map +1 -0
  8. package/dist/config-store--1vrPTFC.js +363 -0
  9. package/dist/config-store--1vrPTFC.js.map +1 -0
  10. package/dist/{debug-C4rsL806.js → debug-Cykqg-GL.js} +3 -2
  11. package/dist/{debug-C4rsL806.js.map → debug-Cykqg-GL.js.map} +1 -1
  12. package/dist/github-copilot-provider-BWQdEbDy.js +79 -0
  13. package/dist/github-copilot-provider-BWQdEbDy.js.map +1 -0
  14. package/dist/main.js +6 -4
  15. package/dist/main.js.map +1 -1
  16. package/dist/{models-DNaL0mbS.js → models-DKDMBzWM.js} +2 -2
  17. package/dist/{models-DNaL0mbS.js.map → models-DKDMBzWM.js.map} +1 -1
  18. package/dist/provider-C38mrz76.js +36 -0
  19. package/dist/provider-C38mrz76.js.map +1 -0
  20. package/dist/provider-management-B8wlMJ5F.js +61 -0
  21. package/dist/provider-management-B8wlMJ5F.js.map +1 -0
  22. package/dist/{server-Bn-3LVLI.js → server-ihCUW7FV.js} +144 -27
  23. package/dist/server-ihCUW7FV.js.map +1 -0
  24. package/dist/{start-C20b41ZA.js → start-lTEXu1xj.js} +12 -9
  25. package/dist/{start-C20b41ZA.js.map → start-lTEXu1xj.js.map} +1 -1
  26. package/dist/{token-Datq4t9R.js → token-CnzxfSWL.js} +60 -74
  27. package/dist/token-CnzxfSWL.js.map +1 -0
  28. package/package.json +2 -1
  29. package/dist/auth-DvEHwSn1.js.map +0 -1
  30. package/dist/auth-EY18m6_Q.js +0 -2
  31. package/dist/config-B_pC8QXv.js.map +0 -1
  32. package/dist/server-Bn-3LVLI.js.map +0 -1
  33. package/dist/token-Datq4t9R.js.map +0 -1
package/README.md CHANGED
@@ -91,7 +91,7 @@ Windows x64 (`.exe`), macOS Apple Silicon (`.dmg`), and Linux x64 (`.AppImage`)
91
91
  | [Installation and Startup](docs/guides/en/getting-started.md) | Prerequisites, project overview, `npx` and source runs, provider-only mode without Copilot, and gateway API key setup |
92
92
  | [Claude Code](docs/guides/en/claude-code.md) | The `--claude-code` interactive launcher, `.claude/settings.json` environment variables, opus / sonnet / haiku tier mapping, auto-compact window, and WebSearch behavior |
93
93
  | [OpenCode](docs/guides/en/opencode.md) | OpenCode OAuth login, the `@ai-sdk/anthropic` provider in `opencode.json`, `baseURL` conventions, model context limits, and thinking options |
94
- | [Codex](docs/guides/en/codex.md) | A full `config.toml` provider block, auto-review model mapping, generating `model_catalog.json`, and the merged model picker catalog with protocol adapters |
94
+ | [Codex](docs/guides/en/codex.md) | A full `config.toml` provider block, `GITHUB_COPILOT_API_KEY` environment variable setup, auto-review model mapping, generating `model_catalog.json`, and the merged model picker catalog with protocol adapters |
95
95
  | [Docker](docs/guides/en/docker.md) | Docker Compose quick start, the `/data` persistent mount and its ownership repair, supported environment variables, and host interface binding |
96
96
  | [Desktop App](docs/guides/en/desktop.md) | Copilot sign-in, Codex OAuth account switching, API-key providers, one-click start / stop, shared model mappings, advanced settings, and per-platform installers |
97
97
  | [Plugins and Tool Search](docs/guides/en/integrations.md) | The Responses `tool_search` MCP bridge (not needed on opencode v2, which already defers tools through Code Mode), Claude Code `agent-inject` and `tool-search` marketplace plugins, and the opencode subagent marker plugin |
@@ -99,6 +99,6 @@ Windows x64 (`.exe`), macOS Apple Silicon (`.dmg`), and Linux x64 (`.AppImage`)
99
99
  | [CLI Reference](docs/guides/en/cli.md) | Command structure, global options, and the full option sets for the `start`, `auth`, and `debug` subcommands with example usage |
100
100
  | [Configuration Reference](docs/guides/en/configuration.md) | Every `config.json` field: gateway and admin API keys, provider definitions, model mappings, WebSocket and HTTP transport, timeouts, and context management |
101
101
  | [API and Authentication](docs/guides/en/api.md) | Allowed auth headers and CORS rules, OpenAI, Codex backend, and Anthropic endpoints, usage monitoring routes, and admin configuration endpoints |
102
- | [Troubleshooting](docs/guides/en/troubleshooting.md) | Known issues with workarounds, including the Copilot encrypted output decryption failure and the `useResponsesApiWebSocket` HTTP fallback |
102
+ | [Troubleshooting](docs/guides/en/troubleshooting.md) | Fixes for Copilot encrypted output failures and missing Claude models |
103
103
 
104
104
  Before using GitHub Copilot, read the [GitHub Copilot Security Notice](NOTICE.md#github-copilot-security-notice).
package/README.zh-CN.md CHANGED
@@ -99,7 +99,7 @@ Windows x64(`.exe`)、macOS Apple Silicon(`.dmg`)和 Linux x64(`.AppIm
99
99
  | [安装与启动](docs/guides/zh-CN/getting-started.md) | 环境要求、项目概览、npx 与源码运行、无 Copilot 时的 provider-only 模式,以及网关 API Key 配置 |
100
100
  | [Claude Code](docs/guides/zh-CN/claude-code.md) | `--claude-code` 交互式启动器、`.claude/settings.json` 环境变量、opus / sonnet / haiku 档位映射、自动压缩窗口与 WebSearch 行为 |
101
101
  | [OpenCode](docs/guides/zh-CN/opencode.md) | OpenCode OAuth 登录、`opencode.json` 中的 `@ai-sdk/anthropic` provider、`baseURL` 约定、模型上下文上限与思考选项 |
102
- | [Codex](docs/guides/zh-CN/codex.md) | 完整的 `config.toml` provider 配置块、自动审核模型映射、生成 `model_catalog.json`,以及合并后的模型选择器目录与协议适配 |
102
+ | [Codex](docs/guides/zh-CN/codex.md) | 完整的 `config.toml` provider 配置块、`GITHUB_COPILOT_API_KEY` 环境变量设置、自动审核模型映射、生成 `model_catalog.json`,以及合并后的模型选择器目录与协议适配 |
103
103
  | [Docker](docs/guides/zh-CN/docker.md) | Docker Compose 快速启动、`/data` 持久化挂载与属主修复、支持的环境变量,以及监听所有网卡地址 |
104
104
  | [桌面应用](docs/guides/zh-CN/desktop.md) | Copilot 登录、Codex OAuth 账号切换、API Key provider、一键启停、共享模型映射、高级设置与各平台安装包 |
105
105
  | [插件与工具搜索](docs/guides/zh-CN/integrations.md) | Responses `tool_search` MCP 桥接(opencode v2 已通过 Code Mode 延迟加载工具,不需要)、Claude Code 的 `agent-inject` 与 `tool-search` 市场插件,以及 opencode 子代理标记插件 |
@@ -107,6 +107,6 @@ Windows x64(`.exe`)、macOS Apple Silicon(`.dmg`)和 Linux x64(`.AppIm
107
107
  | [命令行参考](docs/guides/zh-CN/cli.md) | 命令结构、全局选项,以及 `start`、`auth`、`debug` 子命令的完整参数与使用示例 |
108
108
  | [配置参考](docs/guides/zh-CN/configuration.md) | `config.json` 全部配置项:网关与管理 API Key、provider 定义、模型映射、WebSocket 与 HTTP 传输、超时与上下文管理 |
109
109
  | [API 与认证](docs/guides/zh-CN/api.md) | 支持的认证请求头与 CORS 规则、OpenAI / Codex 后端 / Anthropic 端点、用量监控接口与管理配置接口 |
110
- | [故障排查](docs/guides/zh-CN/troubleshooting.md) | 已知问题与处理方法,包括 Copilot 加密输出解密失败,以及通过 `useResponsesApiWebSocket` 回退到 HTTP |
110
+ | [故障排查](docs/guides/zh-CN/troubleshooting.md) | Copilot 加密输出失败与 Claude 模型缺失的处理方法 |
111
111
 
112
112
  使用 GitHub Copilot 前请阅读 [GitHub Copilot 安全提示](NOTICE.md#github-copilot-security-notice)。
@@ -1,5 +1,6 @@
1
- import { B as PATHS, T as SUPPORTED_PROVIDER_TYPES, V as ensurePaths, a as normalizeProviderBaseUrl, c as setProviderConfig, f as loadModelsDevProviderOptions, n as getRawProviderConfig, r as isSupportedProviderType, z as setConfiguredApiKeys } from "./config-B_pC8QXv.js";
2
- import { F as getConfiguredApiKeys, L as loginCodex, Z as state, a as selectCodexAccount, c as setupGitHubToken, i as removeCodexAccount, r as persistCodexCredentials, t as getCodexAccounts } from "./token-Datq4t9R.js";
1
+ import { S as ensurePaths, t as SUPPORTED_PROVIDER_TYPES, x as PATHS, y as setConfiguredApiKeys } from "./config-store--1vrPTFC.js";
2
+ import { a as normalizeProviderBaseUrl, c as setProviderConfig, f as loadModelsDevProviderOptions, n as getRawProviderConfig, r as isSupportedProviderType } from "./config-AlcbghlW.js";
3
+ import { F as getConfiguredApiKeys, L as loginCodex, Z as state, a as selectCodexAccount, c as setupGitHubToken, i as removeCodexAccount, r as persistCodexCredentials, t as getCodexAccounts } from "./token-CnzxfSWL.js";
3
4
  import { defineCommand } from "citty";
4
5
  import consola from "consola";
5
6
  //#region src/lib/quick-providers.ts
@@ -154,7 +155,7 @@ async function resolveProviderSelection(providerArg) {
154
155
  function assertCustomProviderName(providerName) {
155
156
  if (!providerName) throw new Error("Provider name must be a non-empty string");
156
157
  if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(providerName)) throw new Error("Provider name must start with a letter or number and contain only letters, numbers, underscores, or hyphens");
157
- if (providerName === "copilot" || providerName === "codex") throw new Error(`Provider name '${providerName}' is reserved for a builtin provider`);
158
+ if (providerName === "copilot" || providerName === "github-copilot" || providerName === "codex") throw new Error(`Provider name '${providerName}' is reserved for a builtin provider`);
158
159
  }
159
160
  async function promptRequiredText(message, fieldName) {
160
161
  const value = await prompt(message, { type: "text" });
@@ -327,6 +328,7 @@ function buildCustomProviderConfig(existingProviderConfig, options) {
327
328
  apiKey: options.apiKey,
328
329
  ...options.authType ? { authType: options.authType } : {},
329
330
  pricingCurrency: options.pricingCurrency ?? existingProviderConfig.pricingCurrency,
331
+ ...existingProviderConfig.codexModels !== void 0 ? { codexModels: existingProviderConfig.codexModels } : {},
330
332
  ...existingProviderConfig.models ? { models: existingProviderConfig.models } : {}
331
333
  };
332
334
  }
@@ -609,4 +611,4 @@ const auth = defineCommand({
609
611
  //#endregion
610
612
  export { runProviderSetup as a, runAuthLogin as i, runAuthCodex as n, runAuthKeys as r, auth as t };
611
613
 
612
- //# sourceMappingURL=auth-DvEHwSn1.js.map
614
+ //# sourceMappingURL=auth-BM1NSmaY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-BM1NSmaY.js","names":[],"sources":["../src/lib/quick-providers.ts","../src/lib/interactive-prompt.ts","../src/auth.ts"],"sourcesContent":["import type { ProviderType } from \"./config\"\n\ninterface QuickProviderConfig {\n type: ProviderType\n baseUrl: string\n pricingCurrency: string\n editableType: boolean\n}\n\nexport const QUICK_PROVIDER_CONFIGS = {\n \"opencode-go\": {\n type: \"openai-compatible\",\n baseUrl: \"https://opencode.ai/zen/go\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n kimi: {\n type: \"openai-compatible\",\n baseUrl: \"https://api.kimi.com/coding\",\n pricingCurrency: \"USD\",\n editableType: true,\n },\n deepseek: {\n type: \"anthropic\",\n baseUrl: \"https://api.deepseek.com/anthropic\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n dashscope: {\n type: \"openai-compatible\",\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n openrouter: {\n type: \"anthropic\",\n baseUrl: \"https://openrouter.ai/api\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n} satisfies Record<string, QuickProviderConfig>\n\nexport type QuickProviderName = keyof typeof QUICK_PROVIDER_CONFIGS\n","import consola from \"consola\"\n\ninterface PromptSelectOption {\n label: string\n value: string\n hint?: string\n}\n\ninterface TextPromptOptions {\n type?: \"text\"\n default?: string\n initial?: string\n placeholder?: string\n}\n\ninterface SelectPromptOptions {\n type: \"select\"\n initial?: string\n options: Array<string | PromptSelectOption>\n}\n\nexport type InteractivePromptOptions = SelectPromptOptions | TextPromptOptions\n\ninterface ClackSelectOptions {\n message: string\n initialValue?: string\n options: Array<PromptSelectOption>\n}\n\ninterface ClackTextOptions {\n message: string\n defaultValue?: string\n initialValue?: string\n placeholder?: string\n}\n\nexport interface ClackPromptBackend {\n isCancel(value: unknown): boolean\n select(options: ClackSelectOptions): Promise<string | symbol>\n text(options: ClackTextOptions): Promise<string | symbol>\n}\n\ninterface PromptRuntime {\n bunVersion?: string\n platform: NodeJS.Platform\n stdinIsTTY?: boolean\n stdoutIsTTY?: boolean\n stdoutIsTTYStream?: boolean\n}\n\n// Consola 3.4.2 bundles a prompt implementation that writes keyboard input to\n// tty fd 0. Bun treats that as a real stdin write on Windows and throws EPIPE.\nexport function shouldUseClackPrompt(\n runtime: PromptRuntime = {\n bunVersion: process.versions.bun,\n platform: process.platform,\n stdinIsTTY: process.stdin.isTTY,\n stdoutIsTTY: process.stdout.isTTY,\n stdoutIsTTYStream: typeof process.stdout.getColorDepth === \"function\",\n },\n): boolean {\n return Boolean(\n runtime.platform === \"win32\"\n && runtime.bunVersion\n && runtime.stdinIsTTY\n && runtime.stdoutIsTTY\n && runtime.stdoutIsTTYStream,\n )\n}\n\nfunction getCancelValue(options: InteractivePromptOptions): string | undefined {\n return options.type === \"select\" ?\n options.initial\n : (options.default ?? options.initial)\n}\n\nexport async function promptWithClack(\n message: string,\n options: InteractivePromptOptions,\n backend: ClackPromptBackend,\n): Promise<string | undefined> {\n if (options.type === \"select\") {\n const value = await backend.select({\n message,\n options: options.options.map((option) =>\n typeof option === \"string\" ? { label: option, value: option } : option,\n ),\n initialValue: options.initial,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n }\n\n const value = await backend.text({\n message,\n defaultValue: options.default,\n initialValue: options.initial,\n placeholder: options.placeholder,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n}\n\nexport async function prompt(\n message: string,\n options: InteractivePromptOptions,\n): Promise<string | undefined> {\n if (!shouldUseClackPrompt()) {\n if (options.type === \"select\") {\n const value = await consola.prompt(message, options)\n return typeof value === \"string\" ? value : undefined\n }\n return await consola.prompt(message, options)\n }\n\n const clack = await import(\"@clack/prompts\")\n return await promptWithClack(message, options, clack)\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n getRawProviderConfig,\n isSupportedProviderType,\n normalizeProviderBaseUrl,\n setProviderConfig,\n setConfiguredApiKeys,\n SUPPORTED_PROVIDER_TYPES,\n type ProviderAuthType,\n type ProviderConfig,\n type ProviderType,\n} from \"./lib/config\"\nimport { loginCodex } from \"./lib/oauth/codex\"\nimport {\n loadModelsDevProviderOptions,\n type ModelsDevProviderOption,\n} from \"./lib/models-dev-cache\"\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { getConfiguredApiKeys } from \"./lib/request-auth\"\nimport {\n QUICK_PROVIDER_CONFIGS,\n type QuickProviderName,\n} from \"./lib/quick-providers\"\nimport { prompt } from \"./lib/interactive-prompt\"\nimport { state } from \"./lib/state\"\nimport {\n getCodexAccounts,\n persistCodexCredentials,\n removeCodexAccount,\n selectCodexAccount,\n setupGitHubToken,\n type CodexAccountSummary,\n} from \"./lib/token\"\n\ninterface RunAuthOptions {\n alias?: string\n provider?: string\n verbose: boolean\n showToken: boolean\n}\n\nconst authArgs = {\n provider: {\n type: \"string\",\n description:\n \"Provider to log in with or configure (copilot, codex, opencode-go, kimi, deepseek, dashscope, openrouter, custom)\",\n },\n alias: {\n type: \"string\",\n description: \"Optional alias for a Codex account\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show provider access token on auth\",\n },\n} as const\n\nconst BUILTIN_PROVIDER_NAMES = [\"copilot\", \"codex\"] as const\nconst QUICK_PROVIDER_NAMES = Object.keys(\n QUICK_PROVIDER_CONFIGS,\n) as Array<QuickProviderName>\nconst AUTH_PROVIDER_NAMES = [\n ...BUILTIN_PROVIDER_NAMES,\n ...QUICK_PROVIDER_NAMES,\n \"custom\",\n] as const\nconst CUSTOM_PROVIDER_AUTH_TYPE_OPTION = \"__default__\"\nconst QUICK_PROVIDER_DEFAULT_TYPE_OPTION = \"__default__\"\nconst CUSTOM_PROVIDER_AUTH_TYPES = [\"x-api-key\", \"authorization\"] as const\n\ntype BuiltinProviderName = (typeof BUILTIN_PROVIDER_NAMES)[number]\ntype AuthProviderName = (typeof AUTH_PROVIDER_NAMES)[number]\ntype CustomProviderAuthType = (typeof CUSTOM_PROVIDER_AUTH_TYPES)[number]\n\nconst BUILTIN_PROVIDER_LABELS: Record<BuiltinProviderName, string> = {\n copilot: \"GitHub Copilot\",\n codex: \"OpenAI Codex\",\n}\nconst AUTH_PROVIDER_LABELS: Record<AuthProviderName, string> = {\n ...BUILTIN_PROVIDER_LABELS,\n \"opencode-go\": \"OpenCode Go\",\n kimi: \"Kimi\",\n deepseek: \"DeepSeek\",\n dashscope: \"DashScope\",\n openrouter: \"OpenRouter\",\n custom: \"Custom provider\",\n}\n\nfunction isAuthProviderName(\n providerName: string,\n): providerName is AuthProviderName {\n return AUTH_PROVIDER_NAMES.includes(providerName as AuthProviderName)\n}\n\nfunction isCustomProviderAuthType(\n value: string,\n): value is CustomProviderAuthType {\n return CUSTOM_PROVIDER_AUTH_TYPES.includes(value as CustomProviderAuthType)\n}\n\nfunction isQuickProviderName(\n providerName: AuthProviderName,\n): providerName is QuickProviderName {\n return QUICK_PROVIDER_NAMES.includes(providerName as QuickProviderName)\n}\n\nasync function resolveProviderSelection(\n providerArg: string | undefined,\n): Promise<AuthProviderName> {\n const availableProviders = [...AUTH_PROVIDER_NAMES]\n\n if (providerArg !== undefined) {\n const providerName = providerArg.trim()\n if (!isAuthProviderName(providerName)) {\n throw new Error(\n `Unknown provider '${providerArg}'. Expected one of: ${availableProviders.join(\", \")}`,\n )\n }\n return providerName\n }\n\n if (availableProviders.length === 1) {\n return availableProviders[0]\n }\n\n const provider = await prompt(\"Select a provider to log in with\", {\n type: \"select\",\n options: availableProviders.map((providerName) => ({\n label: `${AUTH_PROVIDER_LABELS[providerName]} (${providerName})`,\n value: providerName,\n })),\n })\n\n if (!provider || !isAuthProviderName(provider)) {\n throw new Error(\"No provider selected\")\n }\n\n return provider\n}\n\nfunction assertCustomProviderName(providerName: string): void {\n if (!providerName) {\n throw new Error(\"Provider name must be a non-empty string\")\n }\n\n if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(providerName)) {\n throw new Error(\n \"Provider name must start with a letter or number and contain only letters, numbers, underscores, or hyphens\",\n )\n }\n\n if (\n providerName === \"copilot\"\n || providerName === \"github-copilot\"\n || providerName === \"codex\"\n ) {\n throw new Error(\n `Provider name '${providerName}' is reserved for a builtin provider`,\n )\n }\n}\n\nasync function promptRequiredText(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await prompt(message, { type: \"text\" })\n const normalizedValue = typeof value === \"string\" ? value.trim() : \"\"\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nfunction canUseMaskedPrompt(): boolean {\n return Boolean(\n process.stdin.isTTY\n && process.stdout.isTTY\n && typeof process.stdin.setRawMode === \"function\",\n )\n}\n\nasync function promptMaskedText(message: string): Promise<string> {\n if (!canUseMaskedPrompt()) {\n const value = await prompt(message, { type: \"text\" })\n return typeof value === \"string\" ? value : \"\"\n }\n\n return await new Promise<string>((resolve, reject) => {\n let value = \"\"\n const rawModeWasEnabled = process.stdin.isRaw === true\n\n function cleanup(): void {\n process.stdin.off(\"data\", onData)\n process.stdin.setRawMode(rawModeWasEnabled)\n process.stdin.pause()\n }\n\n function finish(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n resolve(value)\n }\n\n function cancel(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n reject(new Error(\"Prompt cancelled\"))\n }\n\n function onData(chunk: Buffer): void {\n const input = chunk.toString(\"utf8\")\n\n if (input.startsWith(\"\\u001B\")) {\n return\n }\n\n for (const char of input) {\n if (char === \"\\u0003\") {\n cancel()\n return\n }\n\n if (char === \"\\r\" || char === \"\\n\") {\n finish()\n return\n }\n\n if (char === \"\\b\" || char === \"\\u007F\") {\n if (value.length > 0) {\n value = value.slice(0, -1)\n process.stdout.write(\"\\b \\b\")\n }\n continue\n }\n\n if (char >= \" \") {\n value += char\n process.stdout.write(\"*\")\n }\n }\n }\n\n process.stdout.write(`${message}: `)\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on(\"data\", onData)\n })\n}\n\nasync function promptRequiredSecret(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await promptMaskedText(message)\n const normalizedValue = value.trim()\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nasync function promptCustomProviderName(defaultName?: string): Promise<string> {\n const value = await prompt(\"Enter provider name\", {\n type: \"text\",\n ...(defaultName ? { default: defaultName, initial: defaultName } : {}),\n })\n const providerName = (value || defaultName || \"\").trim()\n assertCustomProviderName(providerName)\n return providerName\n}\n\nasync function promptCustomProviderType(\n defaultType?: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\"Select provider type\", {\n type: \"select\",\n initial: defaultType,\n options: SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n })\n\n if (\n typeof providerType !== \"string\"\n || !isSupportedProviderType(providerType)\n ) {\n throw new Error(\"No provider type selected\")\n }\n\n return providerType\n}\n\nasync function promptModelsDevProvider(): Promise<\n ModelsDevProviderOption | undefined\n> {\n const source = await prompt(\"Choose custom provider source\", {\n type: \"select\",\n options: [\n { label: \"Enter manually\", value: \"manual\" },\n { label: \"Choose from models.dev\", value: \"models-dev\" },\n ],\n })\n if (source === \"manual\") return undefined\n if (source !== \"models-dev\") throw new Error(\"No provider source selected\")\n\n const providers = await loadModelsDevProviderOptions()\n const query = (\n (await prompt(\"Search models.dev providers (blank to list all)\", {\n type: \"text\",\n })) ?? \"\"\n )\n .trim()\n .toLowerCase()\n const matches = providers.filter(\n (provider) =>\n provider.id.toLowerCase().includes(query)\n || provider.name.toLowerCase().includes(query),\n )\n if (matches.length === 0) {\n throw new Error(\"No matching models.dev providers with a supported API URL\")\n }\n const selectedId = await prompt(\"Select a models.dev provider\", {\n type: \"select\",\n options: matches.map((provider) => ({\n label: `${provider.name} (${provider.id}) — ${provider.type}`,\n value: provider.id,\n })),\n })\n const selectedProvider = matches.find(\n (provider) => provider.id === selectedId,\n )\n if (!selectedProvider) throw new Error(\"No models.dev provider selected\")\n return selectedProvider\n}\n\nasync function promptQuickProviderType(\n defaultType: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\n `Select provider type (default: ${defaultType})`,\n {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultType})`,\n value: QUICK_PROVIDER_DEFAULT_TYPE_OPTION,\n },\n ...SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n ],\n },\n )\n\n if (providerType === QUICK_PROVIDER_DEFAULT_TYPE_OPTION) {\n return defaultType\n }\n\n if (\n typeof providerType === \"string\"\n && isSupportedProviderType(providerType)\n ) {\n return providerType\n }\n\n throw new Error(\"No provider type selected\")\n}\n\nfunction getDefaultProviderAuthType(\n providerType: ProviderType,\n): ProviderAuthType {\n return providerType === \"anthropic\" ? \"x-api-key\" : \"authorization\"\n}\n\nasync function promptCustomProviderAuthType(\n providerType: ProviderType,\n): Promise<ProviderAuthType | undefined> {\n const defaultAuthType = getDefaultProviderAuthType(providerType)\n const authType = await prompt(\"Select provider auth type\", {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultAuthType})`,\n value: CUSTOM_PROVIDER_AUTH_TYPE_OPTION,\n },\n ...CUSTOM_PROVIDER_AUTH_TYPES.map((value) => ({\n label: value,\n value,\n })),\n ],\n })\n\n if (authType === CUSTOM_PROVIDER_AUTH_TYPE_OPTION) {\n return undefined\n }\n\n if (typeof authType === \"string\" && isCustomProviderAuthType(authType)) {\n return authType\n }\n\n throw new Error(\"No provider auth type selected\")\n}\n\nasync function promptQuickProviderBaseUrl(\n defaultBaseUrl: string,\n): Promise<string> {\n const value = await prompt(\n `Enter provider baseUrl (default: ${defaultBaseUrl})`,\n {\n type: \"text\",\n default: defaultBaseUrl,\n initial: defaultBaseUrl,\n },\n )\n const baseUrl = normalizeProviderBaseUrl(\n typeof value === \"string\" && value.trim() ? value : defaultBaseUrl,\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n return baseUrl\n}\n\nfunction buildCustomProviderConfig(\n existingProviderConfig: ProviderConfig,\n options: {\n apiKey: string\n authType?: ProviderAuthType\n baseUrl: string\n pricingCurrency?: string\n type: ProviderType\n modelsDevProviderId?: string\n },\n): ProviderConfig {\n return {\n type: options.type,\n enabled: true,\n baseUrl: options.baseUrl,\n ...(options.modelsDevProviderId && {\n modelsDevProviderId: options.modelsDevProviderId,\n }),\n apiKey: options.apiKey,\n ...(options.authType ? { authType: options.authType } : {}),\n pricingCurrency:\n options.pricingCurrency ?? existingProviderConfig.pricingCurrency,\n ...(existingProviderConfig.codexModels !== undefined ?\n { codexModels: existingProviderConfig.codexModels }\n : {}),\n ...(existingProviderConfig.models ?\n { models: existingProviderConfig.models }\n : {}),\n }\n}\n\nasync function configureCustomProvider(): Promise<void> {\n const catalogProvider = await promptModelsDevProvider()\n const providerName = await promptCustomProviderName(catalogProvider?.id)\n const type = await promptCustomProviderType(catalogProvider?.type)\n const baseUrl =\n catalogProvider ?\n await promptQuickProviderBaseUrl(catalogProvider.api)\n : normalizeProviderBaseUrl(\n await promptRequiredText(\"Enter provider baseUrl\", \"baseUrl\"),\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n const apiKey = await promptRequiredSecret(\"Enter provider apiKey\", \"apiKey\")\n const authType = await promptCustomProviderAuthType(type)\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n authType,\n baseUrl,\n modelsDevProviderId: catalogProvider?.id,\n type,\n }),\n )\n\n consola.success(\n `Custom provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function configureQuickProvider(\n providerName: QuickProviderName,\n): Promise<void> {\n const defaultProviderConfig = QUICK_PROVIDER_CONFIGS[providerName]\n const apiKey = await promptRequiredSecret(\n `Enter ${providerName} apiKey`,\n \"apiKey\",\n )\n const type =\n defaultProviderConfig.editableType ?\n await promptQuickProviderType(defaultProviderConfig.type)\n : defaultProviderConfig.type\n const baseUrl = await promptQuickProviderBaseUrl(\n defaultProviderConfig.baseUrl,\n )\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n baseUrl,\n pricingCurrency: defaultProviderConfig.pricingCurrency,\n type,\n }),\n )\n\n consola.success(\n `${AUTH_PROVIDER_LABELS[providerName]} provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function loginWithCodex(alias?: string): Promise<void> {\n const credentials = await loginCodex({\n onAuth(info) {\n consola.info(\"Open the following URL to authenticate with Codex:\")\n consola.log(info.url)\n if (info.instructions) {\n consola.info(info.instructions)\n }\n },\n onPrompt(message) {\n return prompt(message, { type: \"text\" }).then((value) => value ?? \"\")\n },\n onProgress(message) {\n consola.debug(message)\n },\n })\n\n await persistCodexCredentials(credentials, {\n activateAccount: true,\n alias,\n enableProvider: true,\n })\n consola.success(\n `Codex provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.CODEX_CREDENTIAL_PATH}`,\n )\n}\n\nasync function loginWithProvider(\n provider: AuthProviderName,\n alias?: string,\n): Promise<void> {\n if (alias !== undefined && provider !== \"codex\") {\n throw new Error(\"--alias is only supported with the codex provider\")\n }\n\n if (provider === \"copilot\") {\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n return\n }\n\n if (provider === \"codex\") {\n await loginWithCodex(alias)\n return\n }\n\n if (isQuickProviderName(provider)) {\n await configureQuickProvider(provider)\n return\n }\n\n await configureCustomProvider()\n}\n\nexport async function runProviderSetup(): Promise<void> {\n const provider = await resolveProviderSelection(undefined)\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider)\n}\n\nexport async function runAuthLogin(options: RunAuthOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n const provider = await resolveProviderSelection(options.provider)\n\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider, options.alias)\n}\n\nconst authCodexArgs = {\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List stored Codex accounts\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description:\n \"Remove a Codex account by alias or account id; the account in use cannot be removed\",\n },\n use: {\n alias: \"u\",\n type: \"string\",\n description: \"Select a Codex account by alias or account id\",\n },\n} as const\n\ninterface RunAuthCodexOptions {\n list?: boolean\n remove?: string\n use?: string\n}\n\nfunction formatCodexAccountName(\n account: Pick<CodexAccountSummary, \"accountId\" | \"alias\">,\n): string {\n return account.alias ?\n `${account.alias} (${account.accountId})`\n : account.accountId\n}\n\nfunction formatCodexAccount(account: CodexAccountSummary): string {\n return `${account.active ? \"*\" : \"-\"} ${formatCodexAccountName(account)}`\n}\n\nexport async function runAuthCodex(\n options: RunAuthCodexOptions,\n): Promise<void> {\n await ensurePaths()\n\n const operationCount = [\n options.list === true,\n options.use !== undefined,\n options.remove !== undefined,\n ].filter(Boolean).length\n if (operationCount > 1) {\n throw new Error(\"Use only one of --list, --use, or --remove per invocation\")\n }\n\n if (options.use !== undefined) {\n const account = await selectCodexAccount(options.use)\n consola.success(`Selected Codex account ${formatCodexAccountName(account)}`)\n consola.info(\"Restart the server to use the selected Codex account.\")\n return\n }\n\n if (options.remove !== undefined) {\n const account = await removeCodexAccount(options.remove)\n consola.success(`Removed Codex account ${formatCodexAccountName(account)}`)\n return\n }\n\n const accounts = await getCodexAccounts()\n if (accounts.length === 0) {\n consola.info(\n \"No Codex accounts configured. Run `copilot-api auth login --provider codex` to add one.\",\n )\n return\n }\n\n consola.info(\"Configured Codex accounts:\")\n for (const account of accounts) {\n consola.info(formatCodexAccount(account))\n }\n}\n\nconst authKeysArgs = {\n add: {\n alias: \"a\",\n type: \"string\",\n description: \"Add an API key for gateway authentication\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description: \"Remove an API key\",\n },\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List configured API keys\",\n },\n clear: {\n type: \"boolean\",\n default: false,\n description: \"Remove all configured API keys\",\n },\n} as const\n\ninterface RunAuthKeysOptions {\n add?: string\n remove?: string\n list?: boolean\n clear?: boolean\n}\n\nfunction normalizeAuthKeyValue(value: string): string {\n const normalizedKey = value.trim()\n if (!normalizedKey) {\n throw new Error(\"API key must be a non-empty string\")\n }\n return normalizedKey\n}\n\nexport async function runAuthKeys(options: RunAuthKeysOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n await ensurePaths()\n\n const operations = [\n ...(options.add !== undefined ? [\"add\"] : []),\n ...(options.remove !== undefined ? [\"remove\"] : []),\n ...(options.list ? [\"list\"] : []),\n ...(options.clear ? [\"clear\"] : []),\n ]\n if (operations.length > 1) {\n throw new Error(\n \"Use only one of --add, --remove, --list, or --clear per invocation\",\n )\n }\n\n const operation = operations[0] ?? \"list\"\n\n if (operation === \"add\") {\n const apiKey = normalizeAuthKeyValue(options.add ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.includes(apiKey)) {\n consola.info(\n `API key already configured. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys([...currentKeys, apiKey])\n consola.success(\n `API key added to ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"remove\") {\n const apiKey = normalizeAuthKeyValue(options.remove ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (!currentKeys.includes(apiKey)) {\n consola.info(\n `API key not found. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys(\n currentKeys.filter((key) => key !== apiKey),\n )\n consola.success(\n `API key removed from ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"clear\") {\n setConfiguredApiKeys([])\n consola.success(`Removed all API keys from ${PATHS.CONFIG_PATH}.`)\n return\n }\n\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.length === 0) {\n consola.info(\n \"No API keys configured. Run `npx @jeffreycao/copilot-api@latest auth keys --add <key>` to add one.\",\n )\n return\n }\n consola.info(\"Configured API keys:\")\n for (const key of currentKeys) {\n consola.info(`- ${key}`)\n }\n}\n\nconst authLogin = defineCommand({\n meta: {\n name: \"login\",\n description:\n \"Authenticate or configure a provider without running the server\",\n },\n args: authArgs,\n run({ args }) {\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n\nconst authKeys = defineCommand({\n meta: {\n name: \"keys\",\n description: \"Manage gateway API keys (auth.apiKeys) in the config\",\n },\n args: authKeysArgs,\n run({ args }) {\n return runAuthKeys({\n add: args.add,\n remove: args.remove,\n list: args.list,\n clear: args.clear,\n })\n },\n})\n\nconst authCodex = defineCommand({\n meta: {\n name: \"codex\",\n description: \"List, select, or remove stored Codex accounts\",\n },\n args: authCodexArgs,\n run({ args }) {\n return runAuthCodex({\n list: args.list,\n remove: args.remove,\n use: args.use,\n })\n },\n})\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run authentication flows without running the server\",\n },\n args: authArgs,\n subCommands: {\n codex: authCodex,\n login: authLogin,\n keys: authKeys,\n },\n run({ args }) {\n if ((args._[0] ?? \"\").trim()) {\n return\n }\n\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":";;;;;;AASA,MAAa,yBAAyB;CACpC,eAAe;EACb,MAAM;EACN,SAAS;EACT,iBAAiB;EACjB,cAAc;CAChB;CACA,MAAM;EACJ,MAAM;EACN,SAAS;EACT,iBAAiB;EACjB,cAAc;CAChB;CACA,UAAU;EACR,MAAM;EACN,SAAS;EACT,iBAAiB;EACjB,cAAc;CAChB;CACA,WAAW;EACT,MAAM;EACN,SAAS;EACT,iBAAiB;EACjB,cAAc;CAChB;CACA,YAAY;EACV,MAAM;EACN,SAAS;EACT,iBAAiB;EACjB,cAAc;CAChB;AACF;;;ACYA,SAAgB,qBACd,UAAyB;CACvB,YAAY,QAAQ,SAAS;CAC7B,UAAU,QAAQ;CAClB,YAAY,QAAQ,MAAM;CAC1B,aAAa,QAAQ,OAAO;CAC5B,mBAAmB,OAAO,QAAQ,OAAO,kBAAkB;AAC7D,GACS;CACT,OAAO,QACL,QAAQ,aAAa,WAChB,QAAQ,cACR,QAAQ,cACR,QAAQ,eACR,QAAQ,iBACf;AACF;AAEA,SAAS,eAAe,SAAuD;CAC7E,OAAO,QAAQ,SAAS,WACpB,QAAQ,UACP,QAAQ,WAAW,QAAQ;AAClC;AAEA,eAAsB,gBACpB,SACA,SACA,SAC6B;CAC7B,IAAI,QAAQ,SAAS,UAAU;EAC7B,MAAM,QAAQ,MAAM,QAAQ,OAAO;GACjC;GACA,SAAS,QAAQ,QAAQ,KAAK,WAC5B,OAAO,WAAW,WAAW;IAAE,OAAO;IAAQ,OAAO;GAAO,IAAI,MAClE;GACA,cAAc,QAAQ;EACxB,CAAC;EACD,IAAI,QAAQ,SAAS,KAAK,GACxB,OAAO,eAAe,OAAO;EAE/B,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;CAC7C;CAEA,MAAM,QAAQ,MAAM,QAAQ,KAAK;EAC/B;EACA,cAAc,QAAQ;EACtB,cAAc,QAAQ;EACtB,aAAa,QAAQ;CACvB,CAAC;CACD,IAAI,QAAQ,SAAS,KAAK,GACxB,OAAO,eAAe,OAAO;CAE/B,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;AAEA,eAAsB,OACpB,SACA,SAC6B;CAC7B,IAAI,CAAC,qBAAqB,GAAG;EAC3B,IAAI,QAAQ,SAAS,UAAU;GAC7B,MAAM,QAAQ,MAAM,QAAQ,OAAO,SAAS,OAAO;GACnD,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;EAC7C;EACA,OAAO,MAAM,QAAQ,OAAO,SAAS,OAAO;CAC9C;CAGA,OAAO,MAAM,gBAAgB,SAAS,SAAS,MAD3B,OAAO,iBACyB;AACtD;;;AC5EA,MAAM,WAAW;CACf,UAAU;EACR,MAAM;EACN,aACE;CACJ;CACA,OAAO;EACL,MAAM;EACN,aAAa;CACf;CACA,SAAS;EACP,OAAO;EACP,MAAM;EACN,SAAS;EACT,aAAa;CACf;CACA,cAAc;EACZ,MAAM;EACN,SAAS;EACT,aAAa;CACf;AACF;AAEA,MAAM,yBAAyB,CAAC,WAAW,OAAO;AAClD,MAAM,uBAAuB,OAAO,KAClC,sBACF;AACA,MAAM,sBAAsB;CAC1B,GAAG;CACH,GAAG;CACH;AACF;AACA,MAAM,mCAAmC;AACzC,MAAM,qCAAqC;AAC3C,MAAM,6BAA6B,CAAC,aAAa,eAAe;AAUhE,MAAM,uBAAyD;CAH7D,SAAS;CACT,OAAO;CAIP,eAAe;CACf,MAAM;CACN,UAAU;CACV,WAAW;CACX,YAAY;CACZ,QAAQ;AACV;AAEA,SAAS,mBACP,cACkC;CAClC,OAAO,oBAAoB,SAAS,YAAgC;AACtE;AAEA,SAAS,yBACP,OACiC;CACjC,OAAO,2BAA2B,SAAS,KAA+B;AAC5E;AAEA,SAAS,oBACP,cACmC;CACnC,OAAO,qBAAqB,SAAS,YAAiC;AACxE;AAEA,eAAe,yBACb,aAC2B;CAC3B,MAAM,qBAAqB,CAAC,GAAG,mBAAmB;CAElD,IAAI,gBAAgB,KAAA,GAAW;EAC7B,MAAM,eAAe,YAAY,KAAK;EACtC,IAAI,CAAC,mBAAmB,YAAY,GAClC,MAAM,IAAI,MACR,qBAAqB,YAAY,sBAAsB,mBAAmB,KAAK,IAAI,GACrF;EAEF,OAAO;CACT;CAEA,IAAI,mBAAmB,WAAW,GAChC,OAAO,mBAAmB;CAG5B,MAAM,WAAW,MAAM,OAAO,oCAAoC;EAChE,MAAM;EACN,SAAS,mBAAmB,KAAK,kBAAkB;GACjD,OAAO,GAAG,qBAAqB,cAAc,IAAI,aAAa;GAC9D,OAAO;EACT,EAAE;CACJ,CAAC;CAED,IAAI,CAAC,YAAY,CAAC,mBAAmB,QAAQ,GAC3C,MAAM,IAAI,MAAM,sBAAsB;CAGxC,OAAO;AACT;AAEA,SAAS,yBAAyB,cAA4B;CAC5D,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,0CAA0C;CAG5D,IAAI,CAAC,+BAA+B,KAAK,YAAY,GACnD,MAAM,IAAI,MACR,6GACF;CAGF,IACE,iBAAiB,aACd,iBAAiB,oBACjB,iBAAiB,SAEpB,MAAM,IAAI,MACR,kBAAkB,aAAa,qCACjC;AAEJ;AAEA,eAAe,mBACb,SACA,WACiB;CACjB,MAAM,QAAQ,MAAM,OAAO,SAAS,EAAE,MAAM,OAAO,CAAC;CACpD,MAAM,kBAAkB,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;CACnE,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,GAAG,UAAU,4BAA4B;CAE3D,OAAO;AACT;AAEA,SAAS,qBAA8B;CACrC,OAAO,QACL,QAAQ,MAAM,SACT,QAAQ,OAAO,SACf,OAAO,QAAQ,MAAM,eAAe,UAC3C;AACF;AAEA,eAAe,iBAAiB,SAAkC;CAChE,IAAI,CAAC,mBAAmB,GAAG;EACzB,MAAM,QAAQ,MAAM,OAAO,SAAS,EAAE,MAAM,OAAO,CAAC;EACpD,OAAO,OAAO,UAAU,WAAW,QAAQ;CAC7C;CAEA,OAAO,MAAM,IAAI,SAAiB,SAAS,WAAW;EACpD,IAAI,QAAQ;EACZ,MAAM,oBAAoB,QAAQ,MAAM,UAAU;EAElD,SAAS,UAAgB;GACvB,QAAQ,MAAM,IAAI,QAAQ,MAAM;GAChC,QAAQ,MAAM,WAAW,iBAAiB;GAC1C,QAAQ,MAAM,MAAM;EACtB;EAEA,SAAS,SAAe;GACtB,QAAQ;GACR,QAAQ,OAAO,MAAM,IAAI;GACzB,QAAQ,KAAK;EACf;EAEA,SAAS,SAAe;GACtB,QAAQ;GACR,QAAQ,OAAO,MAAM,IAAI;GACzB,uBAAO,IAAI,MAAM,kBAAkB,CAAC;EACtC;EAEA,SAAS,OAAO,OAAqB;GACnC,MAAM,QAAQ,MAAM,SAAS,MAAM;GAEnC,IAAI,MAAM,WAAW,MAAQ,GAC3B;GAGF,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,SAAS,KAAU;KACrB,OAAO;KACP;IACF;IAEA,IAAI,SAAS,QAAQ,SAAS,MAAM;KAClC,OAAO;KACP;IACF;IAEA,IAAI,SAAS,QAAQ,SAAS,KAAU;KACtC,IAAI,MAAM,SAAS,GAAG;MACpB,QAAQ,MAAM,MAAM,GAAG,EAAE;MACzB,QAAQ,OAAO,MAAM,OAAO;KAC9B;KACA;IACF;IAEA,IAAI,QAAQ,KAAK;KACf,SAAS;KACT,QAAQ,OAAO,MAAM,GAAG;IAC1B;GACF;EACF;EAEA,QAAQ,OAAO,MAAM,GAAG,QAAQ,GAAG;EACnC,QAAQ,MAAM,WAAW,IAAI;EAC7B,QAAQ,MAAM,OAAO;EACrB,QAAQ,MAAM,GAAG,QAAQ,MAAM;CACjC,CAAC;AACH;AAEA,eAAe,qBACb,SACA,WACiB;CAEjB,MAAM,mBAAkB,MADJ,iBAAiB,OAAO,EAAA,CACd,KAAK;CACnC,IAAI,CAAC,iBACH,MAAM,IAAI,MAAM,GAAG,UAAU,4BAA4B;CAE3D,OAAO;AACT;AAEA,eAAe,yBAAyB,aAAuC;CAK7E,MAAM,gBAAgB,MAJF,OAAO,uBAAuB;EAChD,MAAM;EACN,GAAI,cAAc;GAAE,SAAS;GAAa,SAAS;EAAY,IAAI,CAAC;CACtE,CAAC,KAC8B,eAAe,GAAA,CAAI,KAAK;CACvD,yBAAyB,YAAY;CACrC,OAAO;AACT;AAEA,eAAe,yBACb,aACuB;CACvB,MAAM,eAAe,MAAM,OAAO,wBAAwB;EACxD,MAAM;EACN,SAAS;EACT,SAAS,yBAAyB,KAAK,UAAU;GAC/C,OAAO;GACP,OAAO;EACT,EAAE;CACJ,CAAC;CAED,IACE,OAAO,iBAAiB,YACrB,CAAC,wBAAwB,YAAY,GAExC,MAAM,IAAI,MAAM,2BAA2B;CAG7C,OAAO;AACT;AAEA,eAAe,0BAEb;CACA,MAAM,SAAS,MAAM,OAAO,iCAAiC;EAC3D,MAAM;EACN,SAAS,CACP;GAAE,OAAO;GAAkB,OAAO;EAAS,GAC3C;GAAE,OAAO;GAA0B,OAAO;EAAa,CACzD;CACF,CAAC;CACD,IAAI,WAAW,UAAU,OAAO,KAAA;CAChC,IAAI,WAAW,cAAc,MAAM,IAAI,MAAM,6BAA6B;CAE1E,MAAM,YAAY,MAAM,6BAA6B;CACrD,MAAM,SACH,MAAM,OAAO,mDAAmD,EAC/D,MAAM,OACR,CAAC,KAAM,GAAA,CAEN,KAAK,CAAC,CACN,YAAY;CACf,MAAM,UAAU,UAAU,QACvB,aACC,SAAS,GAAG,YAAY,CAAC,CAAC,SAAS,KAAK,KACrC,SAAS,KAAK,YAAY,CAAC,CAAC,SAAS,KAAK,CACjD;CACA,IAAI,QAAQ,WAAW,GACrB,MAAM,IAAI,MAAM,2DAA2D;CAE7E,MAAM,aAAa,MAAM,OAAO,gCAAgC;EAC9D,MAAM;EACN,SAAS,QAAQ,KAAK,cAAc;GAClC,OAAO,GAAG,SAAS,KAAK,IAAI,SAAS,GAAG,MAAM,SAAS;GACvD,OAAO,SAAS;EAClB,EAAE;CACJ,CAAC;CACD,MAAM,mBAAmB,QAAQ,MAC9B,aAAa,SAAS,OAAO,UAChC;CACA,IAAI,CAAC,kBAAkB,MAAM,IAAI,MAAM,iCAAiC;CACxE,OAAO;AACT;AAEA,eAAe,wBACb,aACuB;CACvB,MAAM,eAAe,MAAM,OACzB,kCAAkC,YAAY,IAC9C;EACE,MAAM;EACN,SAAS,CACP;GACE,OAAO,YAAY,YAAY;GAC/B,OAAO;EACT,GACA,GAAG,yBAAyB,KAAK,UAAU;GACzC,OAAO;GACP,OAAO;EACT,EAAE,CACJ;CACF,CACF;CAEA,IAAI,iBAAiB,oCACnB,OAAO;CAGT,IACE,OAAO,iBAAiB,YACrB,wBAAwB,YAAY,GAEvC,OAAO;CAGT,MAAM,IAAI,MAAM,2BAA2B;AAC7C;AAEA,SAAS,2BACP,cACkB;CAClB,OAAO,iBAAiB,cAAc,cAAc;AACtD;AAEA,eAAe,6BACb,cACuC;CAEvC,MAAM,WAAW,MAAM,OAAO,6BAA6B;EACzD,MAAM;EACN,SAAS,CACP;GACE,OAAO,YALW,2BAA2B,YAK1B,EAAgB;GACnC,OAAO;EACT,GACA,GAAG,2BAA2B,KAAK,WAAW;GAC5C,OAAO;GACP;EACF,EAAE,CACJ;CACF,CAAC;CAED,IAAI,aAAa,kCACf;CAGF,IAAI,OAAO,aAAa,YAAY,yBAAyB,QAAQ,GACnE,OAAO;CAGT,MAAM,IAAI,MAAM,gCAAgC;AAClD;AAEA,eAAe,2BACb,gBACiB;CACjB,MAAM,QAAQ,MAAM,OAClB,oCAAoC,eAAe,IACnD;EACE,MAAM;EACN,SAAS;EACT,SAAS;CACX,CACF;CACA,MAAM,UAAU,yBACd,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,QAAQ,cACtD;CACA,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oCAAoC;CAGtD,OAAO;AACT;AAEA,SAAS,0BACP,wBACA,SAQgB;CAChB,OAAO;EACL,MAAM,QAAQ;EACd,SAAS;EACT,SAAS,QAAQ;EACjB,GAAI,QAAQ,uBAAuB,EACjC,qBAAqB,QAAQ,oBAC/B;EACA,QAAQ,QAAQ;EAChB,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;EACzD,iBACE,QAAQ,mBAAmB,uBAAuB;EACpD,GAAI,uBAAuB,gBAAgB,KAAA,IACzC,EAAE,aAAa,uBAAuB,YAAY,IAClD,CAAC;EACH,GAAI,uBAAuB,SACzB,EAAE,QAAQ,uBAAuB,OAAO,IACxC,CAAC;CACL;AACF;AAEA,eAAe,0BAAyC;CACtD,MAAM,kBAAkB,MAAM,wBAAwB;CACtD,MAAM,eAAe,MAAM,yBAAyB,iBAAiB,EAAE;CACvE,MAAM,OAAO,MAAM,yBAAyB,iBAAiB,IAAI;CACjE,MAAM,UACJ,kBACE,MAAM,2BAA2B,gBAAgB,GAAG,IACpD,yBACE,MAAM,mBAAmB,0BAA0B,SAAS,CAC9D;CACJ,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,oCAAoC;CAGtD,MAAM,SAAS,MAAM,qBAAqB,yBAAyB,QAAQ;CAC3E,MAAM,WAAW,MAAM,6BAA6B,IAAI;CACxD,MAAM,yBAAyB,qBAAqB,YAAY,KAAK,CAAC;CAEtE,kBACE,cACA,0BAA0B,wBAAwB;EAChD;EACA;EACA;EACA,qBAAqB,iBAAiB;EACtC;CACF,CAAC,CACH;CAEA,QAAQ,QACN,oBAAoB,aAAa,eAAe,MAAM,aACxD;AACF;AAEA,eAAe,uBACb,cACe;CACf,MAAM,wBAAwB,uBAAuB;CACrD,MAAM,SAAS,MAAM,qBACnB,SAAS,aAAa,UACtB,QACF;CACA,MAAM,OACJ,sBAAsB,eACpB,MAAM,wBAAwB,sBAAsB,IAAI,IACxD,sBAAsB;CAC1B,MAAM,UAAU,MAAM,2BACpB,sBAAsB,OACxB;CACA,MAAM,yBAAyB,qBAAqB,YAAY,KAAK,CAAC;CAEtE,kBACE,cACA,0BAA0B,wBAAwB;EAChD;EACA;EACA,iBAAiB,sBAAsB;EACvC;CACF,CAAC,CACH;CAEA,QAAQ,QACN,GAAG,qBAAqB,cAAc,aAAa,aAAa,eAAe,MAAM,aACvF;AACF;AAEA,eAAe,eAAe,OAA+B;CAC3D,MAAM,cAAc,MAAM,WAAW;EACnC,OAAO,MAAM;GACX,QAAQ,KAAK,oDAAoD;GACjE,QAAQ,IAAI,KAAK,GAAG;GACpB,IAAI,KAAK,cACP,QAAQ,KAAK,KAAK,YAAY;EAElC;EACA,SAAS,SAAS;GAChB,OAAO,OAAO,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,UAAU,SAAS,EAAE;EACtE;EACA,WAAW,SAAS;GAClB,QAAQ,MAAM,OAAO;EACvB;CACF,CAAC;CAED,MAAM,wBAAwB,aAAa;EACzC,iBAAiB;EACjB;EACA,gBAAgB;CAClB,CAAC;CACD,QAAQ,QACN,oCAAoC,MAAM,YAAY,8BAA8B,MAAM,uBAC5F;AACF;AAEA,eAAe,kBACb,UACA,OACe;CACf,IAAI,UAAU,KAAA,KAAa,aAAa,SACtC,MAAM,IAAI,MAAM,mDAAmD;CAGrE,IAAI,aAAa,WAAW;EAC1B,MAAM,iBAAiB,EAAE,OAAO,KAAK,CAAC;EACtC,QAAQ,QAAQ,2BAA2B,MAAM,iBAAiB;EAClE;CACF;CAEA,IAAI,aAAa,SAAS;EACxB,MAAM,eAAe,KAAK;EAC1B;CACF;CAEA,IAAI,oBAAoB,QAAQ,GAAG;EACjC,MAAM,uBAAuB,QAAQ;EACrC;CACF;CAEA,MAAM,wBAAwB;AAChC;AAEA,eAAsB,mBAAkC;CACtD,MAAM,WAAW,MAAM,yBAAyB,KAAA,CAAS;CACzD,QAAQ,KAAK,mBAAmB,qBAAqB,WAAW;CAChE,MAAM,kBAAkB,QAAQ;AAClC;AAEA,eAAsB,aAAa,SAAwC;CAEzE,CAAA,MADwB,OAAO,qBAAA,CACrB,qBAAqB;CAE/B,IAAI,QAAQ,SAAS;EACnB,QAAQ,QAAQ;EAChB,QAAQ,KAAK,yBAAyB;CACxC;CAEA,MAAM,YAAY,QAAQ;CAE1B,MAAM,YAAY;CAClB,MAAM,WAAW,MAAM,yBAAyB,QAAQ,QAAQ;CAEhE,QAAQ,KAAK,mBAAmB,qBAAqB,WAAW;CAChE,MAAM,kBAAkB,UAAU,QAAQ,KAAK;AACjD;AAEA,MAAM,gBAAgB;CACpB,MAAM;EACJ,OAAO;EACP,MAAM;EACN,SAAS;EACT,aAAa;CACf;CACA,QAAQ;EACN,OAAO;EACP,MAAM;EACN,aACE;CACJ;CACA,KAAK;EACH,OAAO;EACP,MAAM;EACN,aAAa;CACf;AACF;AAQA,SAAS,uBACP,SACQ;CACR,OAAO,QAAQ,QACX,GAAG,QAAQ,MAAM,IAAI,QAAQ,UAAU,KACvC,QAAQ;AACd;AAEA,SAAS,mBAAmB,SAAsC;CAChE,OAAO,GAAG,QAAQ,SAAS,MAAM,IAAI,GAAG,uBAAuB,OAAO;AACxE;AAEA,eAAsB,aACpB,SACe;CACf,MAAM,YAAY;CAOlB,IALuB;EACrB,QAAQ,SAAS;EACjB,QAAQ,QAAQ,KAAA;EAChB,QAAQ,WAAW,KAAA;CACrB,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,SACG,GACnB,MAAM,IAAI,MAAM,2DAA2D;CAG7E,IAAI,QAAQ,QAAQ,KAAA,GAAW;EAC7B,MAAM,UAAU,MAAM,mBAAmB,QAAQ,GAAG;EACpD,QAAQ,QAAQ,0BAA0B,uBAAuB,OAAO,GAAG;EAC3E,QAAQ,KAAK,uDAAuD;EACpE;CACF;CAEA,IAAI,QAAQ,WAAW,KAAA,GAAW;EAChC,MAAM,UAAU,MAAM,mBAAmB,QAAQ,MAAM;EACvD,QAAQ,QAAQ,yBAAyB,uBAAuB,OAAO,GAAG;EAC1E;CACF;CAEA,MAAM,WAAW,MAAM,iBAAiB;CACxC,IAAI,SAAS,WAAW,GAAG;EACzB,QAAQ,KACN,yFACF;EACA;CACF;CAEA,QAAQ,KAAK,4BAA4B;CACzC,KAAK,MAAM,WAAW,UACpB,QAAQ,KAAK,mBAAmB,OAAO,CAAC;AAE5C;AAEA,MAAM,eAAe;CACnB,KAAK;EACH,OAAO;EACP,MAAM;EACN,aAAa;CACf;CACA,QAAQ;EACN,OAAO;EACP,MAAM;EACN,aAAa;CACf;CACA,MAAM;EACJ,OAAO;EACP,MAAM;EACN,SAAS;EACT,aAAa;CACf;CACA,OAAO;EACL,MAAM;EACN,SAAS;EACT,aAAa;CACf;AACF;AASA,SAAS,sBAAsB,OAAuB;CACpD,MAAM,gBAAgB,MAAM,KAAK;CACjC,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,oCAAoC;CAEtD,OAAO;AACT;AAEA,eAAsB,YAAY,SAA4C;CAE5E,CAAA,MADwB,OAAO,qBAAA,CACrB,qBAAqB;CAE/B,MAAM,YAAY;CAElB,MAAM,aAAa;EACjB,GAAI,QAAQ,QAAQ,KAAA,IAAY,CAAC,KAAK,IAAI,CAAC;EAC3C,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,QAAQ,IAAI,CAAC;EACjD,GAAI,QAAQ,OAAO,CAAC,MAAM,IAAI,CAAC;EAC/B,GAAI,QAAQ,QAAQ,CAAC,OAAO,IAAI,CAAC;CACnC;CACA,IAAI,WAAW,SAAS,GACtB,MAAM,IAAI,MACR,oEACF;CAGF,MAAM,YAAY,WAAW,MAAM;CAEnC,IAAI,cAAc,OAAO;EACvB,MAAM,SAAS,sBAAsB,QAAQ,OAAO,EAAE;EACtD,MAAM,cAAc,qBAAqB;EACzC,IAAI,YAAY,SAAS,MAAM,GAAG;GAChC,QAAQ,KACN,+BAA+B,YAAY,OAAO,wBACpD;GACA;EACF;EACA,MAAM,aAAa,qBAAqB,CAAC,GAAG,aAAa,MAAM,CAAC;EAChE,QAAQ,QACN,oBAAoB,MAAM,YAAY,IAAI,WAAW,OAAO,wBAC9D;EACA;CACF;CAEA,IAAI,cAAc,UAAU;EAC1B,MAAM,SAAS,sBAAsB,QAAQ,UAAU,EAAE;EACzD,MAAM,cAAc,qBAAqB;EACzC,IAAI,CAAC,YAAY,SAAS,MAAM,GAAG;GACjC,QAAQ,KACN,sBAAsB,YAAY,OAAO,wBAC3C;GACA;EACF;EACA,MAAM,aAAa,qBACjB,YAAY,QAAQ,QAAQ,QAAQ,MAAM,CAC5C;EACA,QAAQ,QACN,wBAAwB,MAAM,YAAY,IAAI,WAAW,OAAO,wBAClE;EACA;CACF;CAEA,IAAI,cAAc,SAAS;EACzB,qBAAqB,CAAC,CAAC;EACvB,QAAQ,QAAQ,6BAA6B,MAAM,YAAY,EAAE;EACjE;CACF;CAEA,MAAM,cAAc,qBAAqB;CACzC,IAAI,YAAY,WAAW,GAAG;EAC5B,QAAQ,KACN,oGACF;EACA;CACF;CACA,QAAQ,KAAK,sBAAsB;CACnC,KAAK,MAAM,OAAO,aAChB,QAAQ,KAAK,KAAK,KAAK;AAE3B;AAEA,MAAM,YAAY,cAAc;CAC9B,MAAM;EACJ,MAAM;EACN,aACE;CACJ;CACA,MAAM;CACN,IAAI,EAAE,QAAQ;EACZ,OAAO,aAAa;GAClB,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,SAAS,KAAK;GACd,WAAW,KAAK;EAClB,CAAC;CACH;AACF,CAAC;AAED,MAAM,WAAW,cAAc;CAC7B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;CACN,IAAI,EAAE,QAAQ;EACZ,OAAO,YAAY;GACjB,KAAK,KAAK;GACV,QAAQ,KAAK;GACb,MAAM,KAAK;GACX,OAAO,KAAK;EACd,CAAC;CACH;AACF,CAAC;AAED,MAAM,YAAY,cAAc;CAC9B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;CACN,IAAI,EAAE,QAAQ;EACZ,OAAO,aAAa;GAClB,MAAM,KAAK;GACX,QAAQ,KAAK;GACb,KAAK,KAAK;EACZ,CAAC;CACH;AACF,CAAC;AAED,MAAa,OAAO,cAAc;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;CACN,aAAa;EACX,OAAO;EACP,OAAO;EACP,MAAM;CACR;CACA,IAAI,EAAE,QAAQ;EACZ,KAAK,KAAK,EAAE,MAAM,GAAA,CAAI,KAAK,GACzB;EAGF,OAAO,aAAa;GAClB,OAAO,KAAK;GACZ,UAAU,KAAK;GACf,SAAS,KAAK;GACd,WAAW,KAAK;EAClB,CAAC;CACH;AACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { t as auth } from "./auth-BM1NSmaY.js";
2
+ export { auth };
@@ -1,357 +1,8 @@
1
+ import { _ as readEditableConfigFromDisk, b as writeConfigToDisk, c as getConfig, n as defaultConfig, r as defaultContextManagement, t as SUPPORTED_PROVIDER_TYPES, v as reloadConfig, x as PATHS } from "./config-store--1vrPTFC.js";
1
2
  import consola from "consola";
2
- import { createHash, randomBytes, randomUUID } from "node:crypto";
3
- import fs from "node:fs";
3
+ import { createHash, randomUUID } from "node:crypto";
4
4
  import path from "node:path";
5
- import fs$1 from "node:fs/promises";
6
- import os from "node:os";
7
- //#region src/lib/atomic-file.ts
8
- const TEMP_FILE_RANDOM_BYTES = 8;
9
- const fsyncDirectory = (directory) => {
10
- if (process.platform === "win32") return;
11
- let directoryFd;
12
- try {
13
- directoryFd = fs.openSync(directory, "r");
14
- fs.fsyncSync(directoryFd);
15
- } catch (error) {
16
- console.warn(`Failed to fsync directory: ${directory}`, error);
17
- } finally {
18
- if (directoryFd !== void 0) try {
19
- fs.closeSync(directoryFd);
20
- } catch {}
21
- }
22
- };
23
- function writeFileAtomically(filePath, content) {
24
- const directory = path.dirname(filePath);
25
- const tempPath = path.join(directory, `.${path.basename(filePath)}.${process.pid}.${randomBytes(TEMP_FILE_RANDOM_BYTES).toString("hex")}.tmp`);
26
- fs.mkdirSync(directory, { recursive: true });
27
- let fileDescriptor;
28
- let tempFileCreated = false;
29
- try {
30
- fileDescriptor = fs.openSync(tempPath, "wx", 384);
31
- tempFileCreated = true;
32
- fs.writeFileSync(fileDescriptor, content, "utf8");
33
- fs.fsyncSync(fileDescriptor);
34
- fs.closeSync(fileDescriptor);
35
- fileDescriptor = void 0;
36
- fs.renameSync(tempPath, filePath);
37
- tempFileCreated = false;
38
- fsyncDirectory(directory);
39
- } catch (error) {
40
- if (fileDescriptor !== void 0) try {
41
- fs.closeSync(fileDescriptor);
42
- } catch {}
43
- if (tempFileCreated) try {
44
- fs.rmSync(tempPath, { force: true });
45
- } catch {}
46
- throw error;
47
- }
48
- }
49
- //#endregion
50
- //#region src/lib/paths.ts
51
- const AUTH_APP = process.env.COPILOT_API_OAUTH_APP?.trim() || "";
52
- const ENTERPRISE_PREFIX = process.env.COPILOT_API_ENTERPRISE_URL ? "ent_" : "";
53
- const DEFAULT_DIR = path.join(os.homedir(), ".local", "share", "copilot-api");
54
- const APP_DIR = process.env.COPILOT_API_HOME || DEFAULT_DIR;
55
- const PATHS = {
56
- APP_DIR,
57
- GITHUB_TOKEN_PATH: path.join(APP_DIR, AUTH_APP, ENTERPRISE_PREFIX + "github_token"),
58
- CODEX_CREDENTIAL_PATH: path.join(APP_DIR, "codex_credentials.json"),
59
- CONFIG_PATH: path.join(APP_DIR, "config.json")
60
- };
61
- async function ensurePaths() {
62
- await fs$1.mkdir(path.join(PATHS.APP_DIR, AUTH_APP), { recursive: true });
63
- await ensureFile(PATHS.GITHUB_TOKEN_PATH);
64
- await ensureFile(PATHS.CONFIG_PATH);
65
- }
66
- async function ensureFile(filePath) {
67
- try {
68
- await fs$1.access(filePath, fs$1.constants.W_OK);
69
- } catch {
70
- await fs$1.writeFile(filePath, "");
71
- await fs$1.chmod(filePath, 384);
72
- }
73
- }
74
- //#endregion
75
- //#region src/lib/config-store.ts
76
- const defaultUpstreamTransportConfig = {
77
- headersTimeoutMs: 3e5,
78
- streamInactivityTimeoutMs: 3e5,
79
- websocketMaxBufferedBytes: 8388608,
80
- websocketMaxBufferedMessages: 1024,
81
- websocketOpenTimeoutMs: 3e4,
82
- websocketPoolIdleTimeoutMs: 6e4
83
- };
84
- const SUPPORTED_PROVIDER_TYPES = [
85
- "anthropic",
86
- "openai-compatible",
87
- "openai-responses"
88
- ];
89
- const modelResponsesApiCompactThresholds = {
90
- "gpt-5.4": 217600,
91
- "gpt-5.5": 217600
92
- };
93
- const defaultContextManagement = {
94
- messages: true,
95
- responses: false
96
- };
97
- const defaultConfig = {
98
- auth: { apiKeys: [] },
99
- providers: {},
100
- modelMappings: {},
101
- smallModels: {
102
- codex: "gpt-6-luna",
103
- copilot: "gpt-6-luna"
104
- },
105
- contextManagement: defaultContextManagement,
106
- modelResponsesApiCompactThresholds,
107
- useMessagesApi: true,
108
- useResponsesApiWebSocket: true,
109
- upstreamTransport: defaultUpstreamTransportConfig,
110
- useResponsesApiWebSearch: true,
111
- alphaSearchCodexPriority: true,
112
- alphaSearchModel: "gpt-6-luna",
113
- messageApiWebSearchModel: "gpt-6-luna"
114
- };
115
- let cachedConfig = null;
116
- function normalizeAdminApiKey(adminApiKey) {
117
- if (typeof adminApiKey !== "string") {
118
- if (adminApiKey !== void 0) consola.warn("Invalid auth.adminApiKey config. Expected a non-empty string.");
119
- return null;
120
- }
121
- const normalizedAdminApiKey = adminApiKey.trim();
122
- if (!normalizedAdminApiKey) {
123
- consola.warn("Invalid auth.adminApiKey config. Expected a non-empty string.");
124
- return null;
125
- }
126
- return normalizedAdminApiKey;
127
- }
128
- function generateAdminApiKey() {
129
- return randomBytes(32).toString("hex");
130
- }
131
- function isNodeError(error) {
132
- return error instanceof Error && "code" in error;
133
- }
134
- function ensureConfigFile() {
135
- try {
136
- fs.accessSync(PATHS.CONFIG_PATH, fs.constants.F_OK);
137
- } catch (error) {
138
- if (!isNodeError(error) || error.code !== "ENOENT") throw error;
139
- writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`);
140
- }
141
- }
142
- function readConfigFromDisk() {
143
- ensureConfigFile();
144
- const raw = fs.readFileSync(PATHS.CONFIG_PATH, "utf8");
145
- if (!raw.trim()) {
146
- writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(defaultConfig, null, 2)}\n`);
147
- return defaultConfig;
148
- }
149
- try {
150
- return JSON.parse(raw);
151
- } catch (error) {
152
- const message = `Config file is not valid JSON: ${PATHS.CONFIG_PATH}. Refusing to start with the default config. Fix the JSON syntax or delete the file to regenerate a fresh config.`;
153
- consola.error(message, error);
154
- throw new Error(message, { cause: error });
155
- }
156
- }
157
- function readEditableConfigFromDisk() {
158
- try {
159
- const raw = fs.readFileSync(PATHS.CONFIG_PATH, "utf8");
160
- if (!raw.trim()) return {};
161
- return JSON.parse(raw);
162
- } catch (error) {
163
- if (isNodeError(error) && error.code === "ENOENT") return {};
164
- if (error instanceof SyntaxError) throw new Error(`Config file is not valid JSON: ${PATHS.CONFIG_PATH}`);
165
- throw error;
166
- }
167
- }
168
- function writeConfigToDisk(config) {
169
- writeFileAtomically(PATHS.CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`);
170
- }
171
- function setConfiguredApiKeys(apiKeys) {
172
- const normalizedKeys = apiKeys.map((key) => key.trim()).filter((key) => key.length > 0);
173
- const uniqueKeys = [...new Set(normalizedKeys)];
174
- const editableConfig = readEditableConfigFromDisk();
175
- writeConfigToDisk({
176
- ...editableConfig,
177
- auth: {
178
- ...editableConfig.auth,
179
- apiKeys: uniqueKeys
180
- }
181
- });
182
- reloadConfig();
183
- return [...uniqueKeys];
184
- }
185
- function mergeDefaultConfig(config) {
186
- const extraPrompts = config.extraPrompts ?? {};
187
- const defaultExtraPrompts = defaultConfig.extraPrompts ?? {};
188
- const responsesApiCompactThresholds = config.modelResponsesApiCompactThresholds ?? {};
189
- const defaultResponsesApiCompactThresholds = defaultConfig.modelResponsesApiCompactThresholds ?? {};
190
- const modelReasoningEfforts = config.modelReasoningEfforts ?? {};
191
- const defaultModelReasoningEfforts = defaultConfig.modelReasoningEfforts ?? {};
192
- const contextManagement = normalizeContextManagementConfig(config.contextManagement);
193
- const { changed: upstreamTransportMigrated, migrated: migratedUpstreamTransport } = migrateUpstreamTransportConfig(config);
194
- const upstreamTransport = normalizeUpstreamTransportConfig(migratedUpstreamTransport);
195
- const defaultContextManagementConfig = defaultConfig.contextManagement ?? {};
196
- const missingExtraPromptModels = Object.keys(defaultExtraPrompts).filter((model) => !Object.hasOwn(extraPrompts, model));
197
- const missingReasoningEffortModels = Object.keys(defaultModelReasoningEfforts).filter((model) => !Object.hasOwn(modelReasoningEfforts, model));
198
- const missingResponsesApiCompactThresholdModels = Object.keys(defaultResponsesApiCompactThresholds).filter((model) => !Object.hasOwn(responsesApiCompactThresholds, model));
199
- const missingContextManagementKeys = Object.keys(defaultContextManagementConfig).filter((key) => !Object.hasOwn(contextManagement, key));
200
- const hasExtraPromptChanges = missingExtraPromptModels.length > 0;
201
- const hasReasoningEffortChanges = missingReasoningEffortModels.length > 0;
202
- const hasResponsesApiCompactThresholdChanges = missingResponsesApiCompactThresholdModels.length > 0;
203
- const hasContextManagementChanges = missingContextManagementKeys.length > 0;
204
- const hasUpstreamTransportChanges = Object.entries(upstreamTransport).some(([key, value]) => migratedUpstreamTransport[key] !== value);
205
- if (!hasExtraPromptChanges && !hasReasoningEffortChanges && !hasResponsesApiCompactThresholdChanges && !hasContextManagementChanges && !hasUpstreamTransportChanges && !upstreamTransportMigrated) return {
206
- mergedConfig: config,
207
- changed: false
208
- };
209
- const { responsesTransport: _legacyResponsesTransport, ...persistedConfig } = config;
210
- return {
211
- mergedConfig: {
212
- ...persistedConfig,
213
- contextManagement: {
214
- ...defaultContextManagementConfig,
215
- ...contextManagement
216
- },
217
- extraPrompts: {
218
- ...defaultExtraPrompts,
219
- ...extraPrompts
220
- },
221
- modelResponsesApiCompactThresholds: {
222
- ...defaultResponsesApiCompactThresholds,
223
- ...responsesApiCompactThresholds
224
- },
225
- modelReasoningEfforts: {
226
- ...defaultModelReasoningEfforts,
227
- ...modelReasoningEfforts
228
- },
229
- upstreamTransport
230
- },
231
- changed: true
232
- };
233
- }
234
- function normalizeContextManagementConfig(value) {
235
- if (!value || typeof value !== "object") return {};
236
- return {
237
- ...typeof value.messages === "boolean" ? { messages: value.messages } : {},
238
- ...typeof value.responses === "boolean" ? { responses: value.responses } : {}
239
- };
240
- }
241
- const migrateUpstreamTransportConfig = (config) => {
242
- const legacyBlock = config.responsesTransport;
243
- const { headersTimeoutMsV2, ...migrated } = config.upstreamTransport ?? legacyBlock ?? {};
244
- const hasLegacyBlock = legacyBlock !== void 0;
245
- const hasLegacyHeadersTimeout = headersTimeoutMsV2 !== void 0;
246
- if (!hasLegacyBlock && !hasLegacyHeadersTimeout) return {
247
- changed: false,
248
- migrated
249
- };
250
- consola.info("Migrating deprecated transport config: responsesTransport -> upstreamTransport, headersTimeoutMsV2 -> headersTimeoutMs");
251
- return {
252
- changed: true,
253
- migrated: migrated.headersTimeoutMs === void 0 && hasLegacyHeadersTimeout ? {
254
- ...migrated,
255
- headersTimeoutMs: headersTimeoutMsV2
256
- } : migrated
257
- };
258
- };
259
- function ensureAdminApiKey(config) {
260
- const normalizedAdminApiKey = normalizeAdminApiKey(config.auth?.adminApiKey);
261
- if (normalizedAdminApiKey) {
262
- if (config.auth?.adminApiKey === normalizedAdminApiKey) return {
263
- mergedConfig: config,
264
- changed: false
265
- };
266
- return {
267
- mergedConfig: {
268
- ...config,
269
- auth: {
270
- ...config.auth,
271
- adminApiKey: normalizedAdminApiKey
272
- }
273
- },
274
- changed: true
275
- };
276
- }
277
- const editableConfig = readEditableConfigFromDisk();
278
- const { mergedConfig } = mergeDefaultConfig({
279
- ...editableConfig,
280
- auth: {
281
- ...editableConfig.auth,
282
- adminApiKey: generateAdminApiKey()
283
- }
284
- });
285
- return {
286
- mergedConfig,
287
- changed: true
288
- };
289
- }
290
- function mergeConfigWithDefaults() {
291
- const { mergedConfig, changed } = mergeDefaultConfig(readConfigFromDisk());
292
- const { mergedConfig: mergedConfigWithAdminApiKey, changed: adminApiKeyChanged } = ensureAdminApiKey(mergedConfig);
293
- if (changed || adminApiKeyChanged) try {
294
- writeConfigToDisk(mergedConfigWithAdminApiKey);
295
- } catch (writeError) {
296
- if (adminApiKeyChanged) throw writeError;
297
- consola.warn("Failed to write merged default config to config file", writeError);
298
- }
299
- cachedConfig = mergedConfigWithAdminApiKey;
300
- return mergedConfigWithAdminApiKey;
301
- }
302
- function getConfig() {
303
- cachedConfig ??= mergeDefaultConfig(readConfigFromDisk()).mergedConfig;
304
- return cachedConfig;
305
- }
306
- function reloadConfig() {
307
- return mergeConfigWithDefaults();
308
- }
309
- function isMessagesApiEnabled() {
310
- return getConfig().useMessagesApi ?? true;
311
- }
312
- function isResponsesApiWebSocketEnabled() {
313
- return getConfig().useResponsesApiWebSocket ?? true;
314
- }
315
- function getUpstreamTransportConfig() {
316
- return normalizeUpstreamTransportConfig(getConfig().upstreamTransport);
317
- }
318
- const normalizeUpstreamTransportConfig = (configured) => ({
319
- headersTimeoutMs: positiveIntegerOrDefault(configured?.headersTimeoutMs, defaultUpstreamTransportConfig.headersTimeoutMs),
320
- streamInactivityTimeoutMs: positiveIntegerOrDefault(configured?.streamInactivityTimeoutMs, defaultUpstreamTransportConfig.streamInactivityTimeoutMs),
321
- websocketMaxBufferedBytes: positiveIntegerOrDefault(configured?.websocketMaxBufferedBytes, defaultUpstreamTransportConfig.websocketMaxBufferedBytes),
322
- websocketMaxBufferedMessages: positiveIntegerOrDefault(configured?.websocketMaxBufferedMessages, defaultUpstreamTransportConfig.websocketMaxBufferedMessages),
323
- websocketOpenTimeoutMs: positiveIntegerOrDefault(configured?.websocketOpenTimeoutMs, defaultUpstreamTransportConfig.websocketOpenTimeoutMs),
324
- websocketPoolIdleTimeoutMs: positiveIntegerOrDefault(configured?.websocketPoolIdleTimeoutMs, defaultUpstreamTransportConfig.websocketPoolIdleTimeoutMs)
325
- });
326
- const positiveIntegerOrDefault = (value, fallback) => {
327
- if (typeof value !== "number" || !Number.isFinite(value)) return fallback;
328
- const normalized = Math.floor(value);
329
- return normalized > 0 ? normalized : fallback;
330
- };
331
- function getAnthropicApiKey() {
332
- return getConfig().anthropicApiKey ?? process.env.ANTHROPIC_API_KEY ?? void 0;
333
- }
334
- function isResponsesApiWebSearchEnabled() {
335
- return getConfig().useResponsesApiWebSearch ?? true;
336
- }
337
- function isAlphaSearchCodexPriorityEnabled() {
338
- return getConfig().alphaSearchCodexPriority ?? true;
339
- }
340
- function getAlphaSearchModel() {
341
- return (getConfig().alphaSearchModel ?? "gpt-6-luna").trim() || void 0;
342
- }
343
- function getMessageApiWebSearchModel() {
344
- const model = getConfig().messageApiWebSearchModel ?? "gpt-6-luna";
345
- return model && model.trim().length > 0 ? model : void 0;
346
- }
347
- function getClaudeAutoModel() {
348
- const model = getConfig().claudeAutoModel;
349
- return model && model.trim().length > 0 ? model.trim() : void 0;
350
- }
351
- function getClaudeTokenMultiplier() {
352
- return getConfig().claudeTokenMultiplier ?? 1.15;
353
- }
354
- //#endregion
5
+ import fs from "node:fs/promises";
355
6
  //#region src/lib/model-policy.ts
356
7
  const GPT_MODEL_PATTERN = /^gpt-(\d+)(?:\.(\d+))?/;
357
8
  function isGpt53OrAbove(model) {
@@ -413,10 +64,11 @@ function validateModelMappings(modelMappings) {
413
64
  return validatedMappings;
414
65
  }
415
66
  function setModelMappings(modelMappings) {
416
- writeConfigToDisk({
67
+ const nextConfig = {
417
68
  ...readEditableConfigFromDisk(),
418
69
  modelMappings: validateModelMappings(modelMappings)
419
- });
70
+ };
71
+ writeConfigToDisk(nextConfig);
420
72
  reloadConfig();
421
73
  return getModelMappings();
422
74
  }
@@ -704,7 +356,7 @@ async function stopModelsDevRefreshLoop() {
704
356
  async function loadDiskCache(cachePath) {
705
357
  let body;
706
358
  try {
707
- body = await fs$1.readFile(cachePath, "utf8");
359
+ body = await fs.readFile(cachePath, "utf8");
708
360
  installModelsDevCatalog(JSON.parse(body));
709
361
  cachedBodyHash = hashBody(body);
710
362
  } catch (error) {
@@ -713,7 +365,7 @@ async function loadDiskCache(cachePath) {
713
365
  return;
714
366
  }
715
367
  try {
716
- const metadata = JSON.parse(await fs$1.readFile(getMetadataPath(cachePath), "utf8"));
368
+ const metadata = JSON.parse(await fs.readFile(getMetadataPath(cachePath), "utf8"));
717
369
  if (isRecord(metadata) && metadata.sha256 === cachedBodyHash) responseValidator = {
718
370
  etag: typeof metadata.etag === "string" && metadata.etag.trim() ? metadata.etag : void 0,
719
371
  lastModified: typeof metadata.lastModified === "string" && metadata.lastModified.trim() ? metadata.lastModified : void 0
@@ -727,24 +379,24 @@ async function persistMetadata(cachePath, sha256, validator) {
727
379
  const metadataPath = getMetadataPath(cachePath);
728
380
  const temporaryPath = `${metadataPath}.${randomUUID()}.tmp`;
729
381
  try {
730
- await fs$1.writeFile(temporaryPath, JSON.stringify({
382
+ await fs.writeFile(temporaryPath, JSON.stringify({
731
383
  sha256,
732
384
  ...validator
733
385
  }), { mode: 384 });
734
- await fs$1.rename(temporaryPath, metadataPath);
386
+ await fs.rename(temporaryPath, metadataPath);
735
387
  } finally {
736
- await fs$1.rm(temporaryPath, { force: true });
388
+ await fs.rm(temporaryPath, { force: true });
737
389
  }
738
390
  }
739
391
  async function persistCache(cachePath, body, sha256, validator) {
740
- await fs$1.mkdir(path.dirname(cachePath), { recursive: true });
392
+ await fs.mkdir(path.dirname(cachePath), { recursive: true });
741
393
  const temporaryPath = `${cachePath}.${randomUUID()}.tmp`;
742
394
  try {
743
- await fs$1.writeFile(temporaryPath, body, { mode: 384 });
744
- await fs$1.rename(temporaryPath, cachePath);
395
+ await fs.writeFile(temporaryPath, body, { mode: 384 });
396
+ await fs.rename(temporaryPath, cachePath);
745
397
  await persistMetadata(cachePath, sha256, validator);
746
398
  } finally {
747
- await fs$1.rm(temporaryPath, { force: true });
399
+ await fs.rm(temporaryPath, { force: true });
748
400
  }
749
401
  }
750
402
  async function refreshCatalog(cachePath, fetcher, signal, generation) {
@@ -864,13 +516,14 @@ function setProviderConfig(name, provider) {
864
516
  if (!providerName) throw new Error("Provider name must be a non-empty string");
865
517
  if (isReservedProviderName(providerName)) throw new Error(`Provider ${providerName} is reserved and cannot be configured in config.providers`);
866
518
  const editableConfig = readEditableConfigFromDisk();
867
- writeConfigToDisk({
519
+ const nextConfig = {
868
520
  ...editableConfig,
869
521
  providers: {
870
522
  ...editableConfig.providers,
871
523
  [providerName]: provider
872
524
  }
873
- });
525
+ };
526
+ writeConfigToDisk(nextConfig);
874
527
  reloadConfig();
875
528
  return getRawProviderConfig(providerName) ?? provider;
876
529
  }
@@ -906,7 +559,8 @@ function getProviderConfig(name) {
906
559
  authType,
907
560
  authTypeExplicit: provider.authType !== void 0,
908
561
  pricingCurrency: normalizePricingCurrency(provider.pricingCurrency),
909
- models: provider.models
562
+ models: provider.models,
563
+ codexModels: provider.codexModels
910
564
  };
911
565
  }
912
566
  function resolveEffectiveProviderType(providerConfig, model) {
@@ -949,12 +603,12 @@ function normalizePricingCurrency(value) {
949
603
  }
950
604
  function listEnabledProviders() {
951
605
  const config = getConfig();
952
- return Object.keys(config.providers ?? {}).filter((name) => getProviderConfig(name) !== null);
606
+ return Object.keys(config.providers ?? {}).filter((name) => !isReservedProviderName(name) && getProviderConfig(name) !== null);
953
607
  }
954
608
  function isReservedProviderName(name) {
955
- return name.trim() === "copilot";
609
+ return name.trim() === "copilot" || name.trim() === "github-copilot";
956
610
  }
957
611
  //#endregion
958
- export { getConfig as A, PATHS as B, resolveMappedModel as C, getAnthropicApiKey as D, getAlphaSearchModel as E, isResponsesApiWebSearchEnabled as F, writeFileAtomically as H, isResponsesApiWebSocketEnabled as I, mergeConfigWithDefaults as L, getUpstreamTransportConfig as M, isAlphaSearchCodexPriorityEnabled as N, getClaudeAutoModel as O, isMessagesApiEnabled as P, readEditableConfigFromDisk as R, isGpt56OrAbove as S, SUPPORTED_PROVIDER_TYPES as T, ensurePaths as V, getReasoningEffortForModel as _, normalizeProviderBaseUrl as a, isContextManagementEnabledForMessages as b, setProviderConfig as c, getOpencodeGoModelRecords as d, loadModelsDevProviderOptions as f, getModelResponsesApiCompactThreshold as g, getModelMappings as h, listEnabledProviders as i, getMessageApiWebSearchModel as j, getClaudeTokenMultiplier as k, getOpencodeGoModelConfig as l, getExtraPromptForModel as m, getRawProviderConfig as n, resolveEffectiveProviderType as o, startModelsDevCache as p, isSupportedProviderType as r, resolveProviderConfigForModel as s, getProviderConfig as t, getOpencodeGoModelIds as u, getSmallModel as v, setModelMappings as w, isContextManagementEnabledForResponses as x, getSmallModelForProvider as y, setConfiguredApiKeys as z };
612
+ export { resolveMappedModel as C, isGpt56OrAbove as S, getReasoningEffortForModel as _, normalizeProviderBaseUrl as a, isContextManagementEnabledForMessages as b, setProviderConfig as c, getOpencodeGoModelRecords as d, loadModelsDevProviderOptions as f, getModelResponsesApiCompactThreshold as g, getModelMappings as h, listEnabledProviders as i, getOpencodeGoModelConfig as l, getExtraPromptForModel as m, getRawProviderConfig as n, resolveEffectiveProviderType as o, startModelsDevCache as p, isSupportedProviderType as r, resolveProviderConfigForModel as s, getProviderConfig as t, getOpencodeGoModelIds as u, getSmallModel as v, setModelMappings as w, isContextManagementEnabledForResponses as x, getSmallModelForProvider as y };
959
613
 
960
- //# sourceMappingURL=config-B_pC8QXv.js.map
614
+ //# sourceMappingURL=config-AlcbghlW.js.map