@jeffreycao/copilot-api 1.12.8 → 1.12.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -35
- package/README.zh-CN.md +37 -35
- package/dist/{auth-BMROoous.js → auth-15xzL-eW.js} +138 -5
- package/dist/auth-15xzL-eW.js.map +1 -0
- package/dist/{check-usage-7Dxi5XkE.js → check-usage-Bu9w7RbA.js} +2 -2
- package/dist/{check-usage-7Dxi5XkE.js.map → check-usage-Bu9w7RbA.js.map} +1 -1
- package/dist/electron-fetch-DPhDE6JE.js +22 -0
- package/dist/electron-fetch-DPhDE6JE.js.map +1 -0
- package/dist/main.js +6 -23
- package/dist/main.js.map +1 -1
- package/dist/{mcp-CTb-DbQH.js → mcp-BseuqgHR.js} +2 -2
- package/dist/{mcp-CTb-DbQH.js.map → mcp-BseuqgHR.js.map} +1 -1
- package/dist/{server-DQXpAOIW.js → server-34rnRg4k.js} +2 -2
- package/dist/{server-DQXpAOIW.js.map → server-34rnRg4k.js.map} +1 -1
- package/dist/{start-BW-kr6B8.js → start-8y_02ZHG.js} +3 -3
- package/dist/{start-BW-kr6B8.js.map → start-8y_02ZHG.js.map} +1 -1
- package/dist/{tls-CaLAeSaF.js → tls-BniQ6Rel.js} +1 -1
- package/dist/{tls-CaLAeSaF.js.map → tls-BniQ6Rel.js.map} +1 -1
- package/dist/{tool-search-D3SN0jX-.js → tool-search-OX6iPJ9D.js} +1 -1
- package/dist/{tool-search-D3SN0jX-.js.map → tool-search-OX6iPJ9D.js.map} +1 -1
- package/package.json +1 -1
- package/dist/auth-BMROoous.js.map +0 -1
package/README.md
CHANGED
|
@@ -168,11 +168,13 @@ The following command line options are available for the `start` command:
|
|
|
168
168
|
|
|
169
169
|
| Option | Description | Default | Alias |
|
|
170
170
|
| ------------ | ------------------------- | ------- | ----- |
|
|
171
|
-
| --provider | Provider to log in with or configure (`copilot`, `codex`, or `custom`) | prompt | none |
|
|
171
|
+
| --provider | Provider to log in with or configure (`copilot`, `codex`, `deepseek`, `dashscope`, `openrouter`, or `custom`) | prompt | none |
|
|
172
172
|
| --verbose | Enable verbose logging | false | -v |
|
|
173
173
|
| --show-token | Show GitHub token on auth | false | none |
|
|
174
174
|
|
|
175
|
-
Use `copilot-api auth login --provider
|
|
175
|
+
Use `copilot-api auth login --provider deepseek`, `--provider dashscope`, or `--provider openrouter` to add or update those common third-party providers from the CLI. DeepSeek and DashScope prompt for masked `apiKey`, provider `type` (default `openai-compatible`), and `baseUrl` with the provider default prefilled. OpenRouter prompts for masked `apiKey` and prefilled `baseUrl` only, and writes `type: "anthropic"`.
|
|
176
|
+
|
|
177
|
+
Use `copilot-api auth login --provider custom` to add or update another third-party provider from the CLI. The command prompts for the provider name, supported type (`anthropic`, `openai-compatible`, or `openai-responses`), `baseUrl`, masked `apiKey`, and `authType`; `authType` may be left as the type default or set to `x-api-key` / `authorization`.
|
|
176
178
|
|
|
177
179
|
### Debug Command Options
|
|
178
180
|
|
|
@@ -190,39 +192,7 @@ Use `copilot-api auth login --provider custom` to add or update a third-party pr
|
|
|
190
192
|
"apiKeys": [],
|
|
191
193
|
"adminApiKey": "<auto-generated-on-startup>"
|
|
192
194
|
},
|
|
193
|
-
"providers": {
|
|
194
|
-
"custom": {
|
|
195
|
-
"type": "anthropic",
|
|
196
|
-
"enabled": true,
|
|
197
|
-
"baseUrl": "your-base-url",
|
|
198
|
-
"apiKey": "sk-your-provider-key",
|
|
199
|
-
"authType": "x-api-key"
|
|
200
|
-
},
|
|
201
|
-
"dashscope": {
|
|
202
|
-
"type": "openai-compatible",
|
|
203
|
-
"enabled": true,
|
|
204
|
-
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode",
|
|
205
|
-
"apiKey": "sk-your-dashscope-key",
|
|
206
|
-
"models": {
|
|
207
|
-
"qwen3.6-plus": {
|
|
208
|
-
"temperature": 1,
|
|
209
|
-
"topP": 0.95,
|
|
210
|
-
"topK": 20,
|
|
211
|
-
"extraBody": {
|
|
212
|
-
"preserve_thinking": true
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
"glm-5.1": {
|
|
216
|
-
"temperature": 0.7,
|
|
217
|
-
"topP": 0.95,
|
|
218
|
-
"contextCache": true,
|
|
219
|
-
"extraBody": {
|
|
220
|
-
"preserve_thinking": true
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
},
|
|
195
|
+
"providers": {},
|
|
226
196
|
"modelMappings": {},
|
|
227
197
|
"extraPrompts": {
|
|
228
198
|
"gpt-5-mini": "<built-in exploration prompt>",
|
|
@@ -267,6 +237,38 @@ Use `copilot-api auth login --provider custom` to add or update a third-party pr
|
|
|
267
237
|
- `contextCache` (optional): Defaults to `true` for OpenAI-compatible providers. This enables Alibaba Cloud Model Studio/DashScope explicit context cache by injecting `cache_control: { "type": "ephemeral" }` on up to 4 content blocks using the Context Cache format. The cache breakpoint strategy matches opencode's main provider flow: the first 2 system messages plus the last 2 non-system messages. Marked string content is converted to text content part arrays for `system` / `user` / `assistant` / `tool` messages; existing array content is marked on the last part. Set this to `false` when the model already supports implicit caching, or when the upstream does not accept this explicit-cache extension field.
|
|
268
238
|
- `supportPdf` (optional): Controls whether the model supports PDF/document content. Defaults to `false`; unsupported PDFs are converted to a text notice. Set it to `true` to send PDF/document blocks as OpenAI Chat Completions file parts.
|
|
269
239
|
- `toolContentSupportType` (optional): Tool result content capabilities for that model, as an array of `array`, `image`, and `pdf`. Provider routes default to string-only tool content when omitted. If `supportPdf` is `true` but this list does not include `pdf`, file parts in tool results are moved to user role messages. This provider default does not change the Copilot main flow, which continues to support array + image and not PDF.
|
|
240
|
+
|
|
241
|
+
Example DashScope model settings:
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"providers": {
|
|
245
|
+
"dashscope": {
|
|
246
|
+
"type": "openai-compatible",
|
|
247
|
+
"enabled": true,
|
|
248
|
+
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode",
|
|
249
|
+
"apiKey": "sk-your-dashscope-key",
|
|
250
|
+
"models": {
|
|
251
|
+
"qwen3.6-plus": {
|
|
252
|
+
"temperature": 1,
|
|
253
|
+
"topP": 0.95,
|
|
254
|
+
"topK": 20,
|
|
255
|
+
"extraBody": {
|
|
256
|
+
"preserve_thinking": true
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"glm-5.1": {
|
|
260
|
+
"temperature": 0.7,
|
|
261
|
+
"topP": 0.95,
|
|
262
|
+
"contextCache": true,
|
|
263
|
+
"extraBody": {
|
|
264
|
+
"preserve_thinking": true
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
270
272
|
- **smallModel:** Fallback model used for tool-less warmup messages (e.g., Claude Code probe requests); defaults to gpt-5-mini.
|
|
271
273
|
- **useResponsesApiContextManagement:** When `true`, the proxy adds Responses API `context_management` compaction instructions. Defaults to `true`. Set it to `false` to disable this globally. When enabled, the request includes `context_management` in the body and keeps only the latest compaction carrier on follow-up turns. This is especially useful for long-running tasks.
|
|
272
274
|
- **modelResponsesApiCompactThresholds:** Per-model Responses API `compact_threshold` overrides used when the proxy adds `context_management`. These values take precedence over the fallback threshold from `resolveResponsesCompactThreshold` (`max_prompt_tokens * ratio`, or the default fallback). Defaults set `gpt-5.4` and `gpt-5.5` to `217600` (`272000 * 0.8`). Models not listed continue to use the normal fallback logic.
|
package/README.zh-CN.md
CHANGED
|
@@ -168,11 +168,13 @@ Copilot API 现在使用子命令结构,主要命令包括:
|
|
|
168
168
|
|
|
169
169
|
| 选项 | 说明 | 默认值 | 别名 |
|
|
170
170
|
| --- | --- | --- | --- |
|
|
171
|
-
| --provider | 要登录或配置的 provider(`copilot`、`codex` 或 `custom`) | 交互选择 | 无 |
|
|
171
|
+
| --provider | 要登录或配置的 provider(`copilot`、`codex`、`deepseek`、`dashscope`、`openrouter` 或 `custom`) | 交互选择 | 无 |
|
|
172
172
|
| --verbose | 启用详细日志 | false | -v |
|
|
173
173
|
| --show-token | 认证时显示 GitHub token | false | 无 |
|
|
174
174
|
|
|
175
|
-
使用 `copilot-api auth login --provider
|
|
175
|
+
使用 `copilot-api auth login --provider deepseek`、`--provider dashscope` 或 `--provider openrouter` 可以通过 CLI 快速新增或更新这些常用第三方 provider。DeepSeek 和 DashScope 会提示输入掩码显示的 `apiKey`、provider `type`(默认 `openai-compatible`)和预填默认值的 `baseUrl`。OpenRouter 只提示输入掩码显示的 `apiKey` 和预填默认值的 `baseUrl`,并固定写入 `type: "anthropic"`。
|
|
176
|
+
|
|
177
|
+
使用 `copilot-api auth login --provider custom` 可以通过 CLI 新增或更新其他第三方 provider。命令会依次提示输入 provider name、项目支持的 type(`anthropic`、`openai-compatible` 或 `openai-responses`)、`baseUrl`、掩码显示的 `apiKey` 和 `authType`;`authType` 可保持 type 默认值,也可选择 `x-api-key` / `authorization`。
|
|
176
178
|
|
|
177
179
|
### Debug 命令选项
|
|
178
180
|
|
|
@@ -192,39 +194,7 @@ Copilot API 现在使用子命令结构,主要命令包括:
|
|
|
192
194
|
"apiKeys": [],
|
|
193
195
|
"adminApiKey": "<startup 自动生成>"
|
|
194
196
|
},
|
|
195
|
-
"providers": {
|
|
196
|
-
"custom": {
|
|
197
|
-
"type": "anthropic",
|
|
198
|
-
"enabled": true,
|
|
199
|
-
"baseUrl": "your-base-url",
|
|
200
|
-
"apiKey": "sk-your-provider-key",
|
|
201
|
-
"authType": "x-api-key"
|
|
202
|
-
},
|
|
203
|
-
"dashscope": {
|
|
204
|
-
"type": "openai-compatible",
|
|
205
|
-
"enabled": true,
|
|
206
|
-
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode",
|
|
207
|
-
"apiKey": "sk-your-dashscope-key",
|
|
208
|
-
"models": {
|
|
209
|
-
"qwen3.6-plus": {
|
|
210
|
-
"temperature": 1,
|
|
211
|
-
"topP": 0.95,
|
|
212
|
-
"topK": 20,
|
|
213
|
-
"extraBody": {
|
|
214
|
-
"preserve_thinking": true
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
"glm-5.1": {
|
|
218
|
-
"temperature": 0.7,
|
|
219
|
-
"topP": 0.95,
|
|
220
|
-
"contextCache": true,
|
|
221
|
-
"extraBody": {
|
|
222
|
-
"preserve_thinking": true
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
},
|
|
197
|
+
"providers": {},
|
|
228
198
|
"modelMappings": {},
|
|
229
199
|
"extraPrompts": {
|
|
230
200
|
"gpt-5-mini": "<built-in exploration prompt>",
|
|
@@ -269,6 +239,38 @@ Copilot API 现在使用子命令结构,主要命令包括:
|
|
|
269
239
|
- `contextCache`:可选,OpenAI 兼容 provider 默认 `true`,用于启用阿里云百炼/DashScope 的显式缓存(explicit context cache),会按其 Context Cache 格式在最多 4 个 content block 上注入 `cache_control: { "type": "ephemeral" }`。缓存断点策略与 opencode 主链路保持一致:前 2 条 system 消息 + 最后 2 条非 system 消息。标记字符串 content 时会把 `system` / `user` / `assistant` / `tool` 消息转换为 text content part 数组;已有数组 content 则标记最后一个 part。如果模型本身已经支持隐式缓存,或上游不支持该显式缓存扩展字段,可在模型配置中设为 `false`。
|
|
270
240
|
- `supportPdf`:可选,控制该模型是否支持 PDF/document content。默认 `false`,不支持时会把 PDF 转成提示文本;设为 `true` 时会把 PDF/document 转成 OpenAI Chat Completions 的 file part。
|
|
271
241
|
- `toolContentSupportType`:可选,配置该模型的 tool result content 支持能力,值为 `array`、`image`、`pdf` 的数组。provider 侧未配置时默认只发送 string tool content。若 `supportPdf` 为 `true` 但这里不包含 `pdf`,tool result 里的 file part 会被转成 user role 消息。Copilot 主链路不使用这个 provider 默认,仍按 array + image 且不支持 PDF 的能力处理。
|
|
242
|
+
|
|
243
|
+
DashScope 模型配置示例:
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"providers": {
|
|
247
|
+
"dashscope": {
|
|
248
|
+
"type": "openai-compatible",
|
|
249
|
+
"enabled": true,
|
|
250
|
+
"baseUrl": "https://dashscope.aliyuncs.com/compatible-mode",
|
|
251
|
+
"apiKey": "sk-your-dashscope-key",
|
|
252
|
+
"models": {
|
|
253
|
+
"qwen3.6-plus": {
|
|
254
|
+
"temperature": 1,
|
|
255
|
+
"topP": 0.95,
|
|
256
|
+
"topK": 20,
|
|
257
|
+
"extraBody": {
|
|
258
|
+
"preserve_thinking": true
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"glm-5.1": {
|
|
262
|
+
"temperature": 0.7,
|
|
263
|
+
"topP": 0.95,
|
|
264
|
+
"contextCache": true,
|
|
265
|
+
"extraBody": {
|
|
266
|
+
"preserve_thinking": true
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
```
|
|
272
274
|
- **smallModel:** 无工具预热消息的回退模型(例如 Claude Code 的探测请求);默认是 `gpt-5-mini`。
|
|
273
275
|
- **useResponsesApiContextManagement:** 当为 `true` 时,代理会为 Responses API 附加 `context_management` 压缩指令。默认值为 `true`。如需全局关闭,可设为 `false`。启用后,请求体会带上 `context_management`,并在后续轮次中仅保留最新的压缩承载内容,因此特别适合长任务场景。
|
|
274
276
|
- **modelResponsesApiCompactThresholds:** 按模型覆盖 Responses API 的 `compact_threshold`,仅在代理自动附加 `context_management` 时使用。它的优先级高于 `resolveResponsesCompactThreshold` 基于 `max_prompt_tokens * ratio` 的兜底阈值。默认将 `gpt-5.4` 和 `gpt-5.5` 设为 `217600`(`272000 * 0.8`)。未列出的模型继续使用原有兜底逻辑。
|
|
@@ -6,7 +6,7 @@ import consola from "consola";
|
|
|
6
6
|
const authArgs = {
|
|
7
7
|
provider: {
|
|
8
8
|
type: "string",
|
|
9
|
-
description: "Provider to log in with or configure (copilot, codex, custom)"
|
|
9
|
+
description: "Provider to log in with or configure (copilot, codex, deepseek, dashscope, openrouter, custom)"
|
|
10
10
|
},
|
|
11
11
|
verbose: {
|
|
12
12
|
alias: "v",
|
|
@@ -20,12 +20,39 @@ const authArgs = {
|
|
|
20
20
|
description: "Show provider access token on auth"
|
|
21
21
|
}
|
|
22
22
|
};
|
|
23
|
-
const
|
|
23
|
+
const BUILTIN_PROVIDER_NAMES = ["copilot", "codex"];
|
|
24
|
+
const QUICK_PROVIDER_CONFIGS = {
|
|
25
|
+
deepseek: {
|
|
26
|
+
type: "openai-compatible",
|
|
27
|
+
baseUrl: "https://api.deepseek.com",
|
|
28
|
+
editableType: true
|
|
29
|
+
},
|
|
30
|
+
dashscope: {
|
|
31
|
+
type: "openai-compatible",
|
|
32
|
+
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode",
|
|
33
|
+
editableType: true
|
|
34
|
+
},
|
|
35
|
+
openrouter: {
|
|
36
|
+
type: "anthropic",
|
|
37
|
+
baseUrl: "https://openrouter.ai/api",
|
|
38
|
+
editableType: false
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const QUICK_PROVIDER_NAMES = Object.keys(QUICK_PROVIDER_CONFIGS);
|
|
42
|
+
const AUTH_PROVIDER_NAMES = [
|
|
43
|
+
...BUILTIN_PROVIDER_NAMES,
|
|
44
|
+
...QUICK_PROVIDER_NAMES,
|
|
45
|
+
"custom"
|
|
46
|
+
];
|
|
24
47
|
const CUSTOM_PROVIDER_AUTH_TYPE_OPTION = "__default__";
|
|
48
|
+
const QUICK_PROVIDER_DEFAULT_TYPE_OPTION = "__default__";
|
|
25
49
|
const CUSTOM_PROVIDER_AUTH_TYPES = ["x-api-key", "authorization"];
|
|
26
50
|
const AUTH_PROVIDER_LABELS = {
|
|
27
51
|
copilot: "GitHub Copilot",
|
|
28
52
|
codex: "OpenAI Codex",
|
|
53
|
+
deepseek: "DeepSeek",
|
|
54
|
+
dashscope: "DashScope",
|
|
55
|
+
openrouter: "OpenRouter",
|
|
29
56
|
custom: "Custom provider"
|
|
30
57
|
};
|
|
31
58
|
function isAuthProviderName(providerName) {
|
|
@@ -34,6 +61,9 @@ function isAuthProviderName(providerName) {
|
|
|
34
61
|
function isCustomProviderAuthType(value) {
|
|
35
62
|
return CUSTOM_PROVIDER_AUTH_TYPES.includes(value);
|
|
36
63
|
}
|
|
64
|
+
function isQuickProviderName(providerName) {
|
|
65
|
+
return QUICK_PROVIDER_NAMES.includes(providerName);
|
|
66
|
+
}
|
|
37
67
|
async function resolveProviderSelection(providerArg) {
|
|
38
68
|
const availableProviders = [...AUTH_PROVIDER_NAMES];
|
|
39
69
|
if (providerArg !== void 0) {
|
|
@@ -63,6 +93,68 @@ async function promptRequiredText(message, fieldName) {
|
|
|
63
93
|
if (!normalizedValue) throw new Error(`${fieldName} must be a non-empty string`);
|
|
64
94
|
return normalizedValue;
|
|
65
95
|
}
|
|
96
|
+
function canUseMaskedPrompt() {
|
|
97
|
+
return Boolean(process.stdin.isTTY && process.stdout.isTTY && typeof process.stdin.setRawMode === "function");
|
|
98
|
+
}
|
|
99
|
+
async function promptMaskedText(message) {
|
|
100
|
+
if (!canUseMaskedPrompt()) {
|
|
101
|
+
const value = await consola.prompt(message, { type: "text" });
|
|
102
|
+
return typeof value === "string" ? value : "";
|
|
103
|
+
}
|
|
104
|
+
return await new Promise((resolve, reject) => {
|
|
105
|
+
let value = "";
|
|
106
|
+
const rawModeWasEnabled = process.stdin.isRaw === true;
|
|
107
|
+
function cleanup() {
|
|
108
|
+
process.stdin.off("data", onData);
|
|
109
|
+
process.stdin.setRawMode(rawModeWasEnabled);
|
|
110
|
+
process.stdin.pause();
|
|
111
|
+
}
|
|
112
|
+
function finish() {
|
|
113
|
+
cleanup();
|
|
114
|
+
process.stdout.write("\n");
|
|
115
|
+
resolve(value);
|
|
116
|
+
}
|
|
117
|
+
function cancel() {
|
|
118
|
+
cleanup();
|
|
119
|
+
process.stdout.write("\n");
|
|
120
|
+
reject(/* @__PURE__ */ new Error("Prompt cancelled"));
|
|
121
|
+
}
|
|
122
|
+
function onData(chunk) {
|
|
123
|
+
const input = chunk.toString("utf8");
|
|
124
|
+
if (input.startsWith("\x1B")) return;
|
|
125
|
+
for (const char of input) {
|
|
126
|
+
if (char === "") {
|
|
127
|
+
cancel();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (char === "\r" || char === "\n") {
|
|
131
|
+
finish();
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (char === "\b" || char === "") {
|
|
135
|
+
if (value.length > 0) {
|
|
136
|
+
value = value.slice(0, -1);
|
|
137
|
+
process.stdout.write("\b \b");
|
|
138
|
+
}
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (char >= " ") {
|
|
142
|
+
value += char;
|
|
143
|
+
process.stdout.write("*");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
process.stdout.write(`${message}: `);
|
|
148
|
+
process.stdin.setRawMode(true);
|
|
149
|
+
process.stdin.resume();
|
|
150
|
+
process.stdin.on("data", onData);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async function promptRequiredSecret(message, fieldName) {
|
|
154
|
+
const normalizedValue = (await promptMaskedText(message)).trim();
|
|
155
|
+
if (!normalizedValue) throw new Error(`${fieldName} must be a non-empty string`);
|
|
156
|
+
return normalizedValue;
|
|
157
|
+
}
|
|
66
158
|
async function promptCustomProviderName() {
|
|
67
159
|
const providerName = await promptRequiredText("Enter provider name", "Provider name");
|
|
68
160
|
assertCustomProviderName(providerName);
|
|
@@ -79,6 +171,21 @@ async function promptCustomProviderType() {
|
|
|
79
171
|
if (typeof providerType !== "string" || !isSupportedProviderType(providerType)) throw new Error("No provider type selected");
|
|
80
172
|
return providerType;
|
|
81
173
|
}
|
|
174
|
+
async function promptQuickProviderType(defaultType) {
|
|
175
|
+
const providerType = await consola.prompt(`Select provider type (default: ${defaultType})`, {
|
|
176
|
+
type: "select",
|
|
177
|
+
options: [{
|
|
178
|
+
label: `Default (${defaultType})`,
|
|
179
|
+
value: QUICK_PROVIDER_DEFAULT_TYPE_OPTION
|
|
180
|
+
}, ...SUPPORTED_PROVIDER_TYPES.map((type) => ({
|
|
181
|
+
label: type,
|
|
182
|
+
value: type
|
|
183
|
+
}))]
|
|
184
|
+
});
|
|
185
|
+
if (providerType === QUICK_PROVIDER_DEFAULT_TYPE_OPTION) return defaultType;
|
|
186
|
+
if (typeof providerType === "string" && isSupportedProviderType(providerType)) return providerType;
|
|
187
|
+
throw new Error("No provider type selected");
|
|
188
|
+
}
|
|
82
189
|
function getDefaultProviderAuthType(providerType) {
|
|
83
190
|
return providerType === "anthropic" ? "x-api-key" : "authorization";
|
|
84
191
|
}
|
|
@@ -98,6 +205,16 @@ async function promptCustomProviderAuthType(providerType) {
|
|
|
98
205
|
if (typeof authType === "string" && isCustomProviderAuthType(authType)) return authType;
|
|
99
206
|
throw new Error("No provider auth type selected");
|
|
100
207
|
}
|
|
208
|
+
async function promptQuickProviderBaseUrl(defaultBaseUrl) {
|
|
209
|
+
const value = await consola.prompt(`Enter provider baseUrl (default: ${defaultBaseUrl})`, {
|
|
210
|
+
type: "text",
|
|
211
|
+
default: defaultBaseUrl,
|
|
212
|
+
initial: defaultBaseUrl
|
|
213
|
+
});
|
|
214
|
+
const baseUrl = normalizeProviderBaseUrl(typeof value === "string" && value.trim() ? value : defaultBaseUrl);
|
|
215
|
+
if (!baseUrl) throw new Error("baseUrl must be a non-empty string");
|
|
216
|
+
return baseUrl;
|
|
217
|
+
}
|
|
101
218
|
function buildCustomProviderConfig(existingProviderConfig, options) {
|
|
102
219
|
return {
|
|
103
220
|
type: options.type,
|
|
@@ -113,7 +230,7 @@ async function configureCustomProvider() {
|
|
|
113
230
|
const type = await promptCustomProviderType();
|
|
114
231
|
const baseUrl = normalizeProviderBaseUrl(await promptRequiredText("Enter provider baseUrl", "baseUrl"));
|
|
115
232
|
if (!baseUrl) throw new Error("baseUrl must be a non-empty string");
|
|
116
|
-
const apiKey = await
|
|
233
|
+
const apiKey = await promptRequiredSecret("Enter provider apiKey", "apiKey");
|
|
117
234
|
const authType = await promptCustomProviderAuthType(type);
|
|
118
235
|
setProviderConfig(providerName, buildCustomProviderConfig(getRawProviderConfig(providerName) ?? {}, {
|
|
119
236
|
apiKey,
|
|
@@ -123,6 +240,18 @@ async function configureCustomProvider() {
|
|
|
123
240
|
}));
|
|
124
241
|
consola.success(`Custom provider '${providerName}' written to ${PATHS.CONFIG_PATH}`);
|
|
125
242
|
}
|
|
243
|
+
async function configureQuickProvider(providerName) {
|
|
244
|
+
const defaultProviderConfig = QUICK_PROVIDER_CONFIGS[providerName];
|
|
245
|
+
const apiKey = await promptRequiredSecret(`Enter ${providerName} apiKey`, "apiKey");
|
|
246
|
+
const type = defaultProviderConfig.editableType ? await promptQuickProviderType(defaultProviderConfig.type) : defaultProviderConfig.type;
|
|
247
|
+
const baseUrl = await promptQuickProviderBaseUrl(defaultProviderConfig.baseUrl);
|
|
248
|
+
setProviderConfig(providerName, buildCustomProviderConfig(getRawProviderConfig(providerName) ?? {}, {
|
|
249
|
+
apiKey,
|
|
250
|
+
baseUrl,
|
|
251
|
+
type
|
|
252
|
+
}));
|
|
253
|
+
consola.success(`${AUTH_PROVIDER_LABELS[providerName]} provider '${providerName}' written to ${PATHS.CONFIG_PATH}`);
|
|
254
|
+
}
|
|
126
255
|
async function loginWithCodex() {
|
|
127
256
|
await persistCodexCredentials(await loginCodex({
|
|
128
257
|
onAuth(info) {
|
|
@@ -149,10 +278,14 @@ async function loginWithProvider(provider) {
|
|
|
149
278
|
await loginWithCodex();
|
|
150
279
|
return;
|
|
151
280
|
}
|
|
281
|
+
if (isQuickProviderName(provider)) {
|
|
282
|
+
await configureQuickProvider(provider);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
152
285
|
await configureCustomProvider();
|
|
153
286
|
}
|
|
154
287
|
async function runAuthLogin(options) {
|
|
155
|
-
(await import("./tls-
|
|
288
|
+
(await import("./tls-BniQ6Rel.js")).enableSystemCACompat();
|
|
156
289
|
if (options.verbose) {
|
|
157
290
|
consola.level = 5;
|
|
158
291
|
consola.info("Verbose logging enabled");
|
|
@@ -195,4 +328,4 @@ const auth = defineCommand({
|
|
|
195
328
|
//#endregion
|
|
196
329
|
export { auth };
|
|
197
330
|
|
|
198
|
-
//# sourceMappingURL=auth-
|
|
331
|
+
//# sourceMappingURL=auth-15xzL-eW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-15xzL-eW.js","names":[],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n getRawProviderConfig,\n isSupportedProviderType,\n normalizeProviderBaseUrl,\n setProviderConfig,\n SUPPORTED_PROVIDER_TYPES,\n type ProviderAuthType,\n type ProviderConfig,\n type ProviderType,\n} from \"./lib/config\"\nimport { loginCodex } from \"./lib/oauth/codex\"\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { persistCodexCredentials, setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\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, deepseek, dashscope, openrouter, custom)\",\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_CONFIGS = {\n deepseek: {\n type: \"openai-compatible\",\n baseUrl: \"https://api.deepseek.com\",\n editableType: true,\n },\n dashscope: {\n type: \"openai-compatible\",\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode\",\n editableType: true,\n },\n openrouter: {\n type: \"anthropic\",\n baseUrl: \"https://openrouter.ai/api\",\n editableType: false,\n },\n} satisfies Record<\n string,\n {\n type: ProviderType\n baseUrl: string\n editableType: boolean\n }\n>\nconst QUICK_PROVIDER_NAMES = Object.keys(QUICK_PROVIDER_CONFIGS) as Array<\n keyof typeof QUICK_PROVIDER_CONFIGS\n>\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 QuickProviderName = (typeof QUICK_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 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 consola.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 (providerName === \"copilot\" || providerName === \"codex\") {\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 consola.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 consola.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(): Promise<string> {\n const providerName = await promptRequiredText(\n \"Enter provider name\",\n \"Provider name\",\n )\n assertCustomProviderName(providerName)\n return providerName\n}\n\nasync function promptCustomProviderType(): Promise<ProviderType> {\n const providerType = await consola.prompt(\"Select provider type\", {\n type: \"select\",\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 promptQuickProviderType(\n defaultType: ProviderType,\n): Promise<ProviderType> {\n const providerType = await consola.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 consola.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 consola.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 type: ProviderType\n },\n): ProviderConfig {\n return {\n type: options.type,\n enabled: true,\n baseUrl: options.baseUrl,\n apiKey: options.apiKey,\n ...(options.authType ? { authType: options.authType } : {}),\n ...(existingProviderConfig.models ?\n { models: existingProviderConfig.models }\n : {}),\n }\n}\n\nasync function configureCustomProvider(): Promise<void> {\n const providerName = await promptCustomProviderName()\n const type = await promptCustomProviderType()\n const baseUrl = 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 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 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(): 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 consola.prompt(message, {\n type: \"text\",\n })\n },\n onProgress(message) {\n consola.debug(message)\n },\n })\n\n await persistCodexCredentials(credentials, { enableProvider: true })\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(provider: AuthProviderName): Promise<void> {\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()\n return\n }\n\n if (isQuickProviderName(provider)) {\n await configureQuickProvider(provider)\n return\n }\n\n await configureCustomProvider()\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)\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 provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\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 login: authLogin,\n },\n run({ args }) {\n if ((args._[0] ?? \"\").trim()) {\n return\n }\n\n return runAuthLogin({\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ const checkUsage = defineCommand({
|
|
|
9
9
|
description: "Show current GitHub Copilot usage/quota information"
|
|
10
10
|
},
|
|
11
11
|
async run() {
|
|
12
|
-
(await import("./tls-
|
|
12
|
+
(await import("./tls-BniQ6Rel.js")).enableSystemCACompat();
|
|
13
13
|
await ensurePaths();
|
|
14
14
|
await setupGitHubToken();
|
|
15
15
|
try {
|
|
@@ -40,4 +40,4 @@ const checkUsage = defineCommand({
|
|
|
40
40
|
//#endregion
|
|
41
41
|
export { checkUsage };
|
|
42
42
|
|
|
43
|
-
//# sourceMappingURL=check-usage-
|
|
43
|
+
//# sourceMappingURL=check-usage-Bu9w7RbA.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-usage-
|
|
1
|
+
{"version":3,"file":"check-usage-Bu9w7RbA.js","names":[],"sources":["../src/check-usage.ts"],"sourcesContent":["import { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { ensurePaths } from \"./lib/paths\"\nimport { setupGitHubToken } from \"./lib/token\"\nimport {\n getCopilotUsage,\n type QuotaDetail,\n} from \"./services/github/get-copilot-usage\"\n\nexport const checkUsage = defineCommand({\n meta: {\n name: \"check-usage\",\n description: \"Show current GitHub Copilot usage/quota information\",\n },\n async run() {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n await ensurePaths()\n await setupGitHubToken()\n try {\n const usage = await getCopilotUsage()\n const premium = usage.quota_snapshots.premium_interactions\n const premiumTotal = premium.entitlement\n const premiumUsed = premiumTotal - premium.remaining\n const premiumPercentUsed =\n premiumTotal > 0 ? (premiumUsed / premiumTotal) * 100 : 0\n const premiumPercentRemaining = premium.percent_remaining\n\n // Helper to summarize a quota snapshot\n function summarizeQuota(name: string, snap: QuotaDetail | undefined) {\n if (!snap) return `${name}: N/A`\n const total = snap.entitlement\n const used = total - snap.remaining\n const percentUsed = total > 0 ? (used / total) * 100 : 0\n const percentRemaining = snap.percent_remaining\n return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`\n }\n\n const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`\n const chatLine = summarizeQuota(\"Chat\", usage.quota_snapshots.chat)\n const completionsLine = summarizeQuota(\n \"Completions\",\n usage.quota_snapshots.completions,\n )\n\n consola.box(\n `Copilot Usage (plan: ${usage.copilot_plan})\\n`\n + `Quota resets: ${usage.quota_reset_date}\\n`\n + `\\nQuotas:\\n`\n + ` ${premiumLine}\\n`\n + ` ${chatLine}\\n`\n + ` ${completionsLine}`,\n )\n } catch (err) {\n consola.error(\"Failed to fetch Copilot usage:\", err)\n process.exit(1)\n }\n },\n})\n"],"mappings":";;;;;AAUA,MAAa,aAAa,cAAc;CACtC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM,MAAM;EAEV,CAAA,MADwB,OAAO,sBACrB,sBAAsB;EAEhC,MAAM,aAAa;EACnB,MAAM,kBAAkB;EACxB,IAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;IACnE,IAAI,CAAC,MAAM,OAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;IAC9B,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;GAED,QAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;GACZ,QAAQ,MAAM,kCAAkC,IAAI;GACpD,QAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import consola from "consola";
|
|
3
|
+
//#region src/lib/electron-fetch.ts
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
function bindElectronFetch() {
|
|
6
|
+
if (!process.versions.electron) return false;
|
|
7
|
+
try {
|
|
8
|
+
const electronModule = require("electron");
|
|
9
|
+
const netFetch = electronModule.net?.fetch;
|
|
10
|
+
if (typeof netFetch !== "function") return false;
|
|
11
|
+
globalThis.fetch = netFetch.bind(electronModule.net);
|
|
12
|
+
consola.log("Successfully bound Electron's net.fetch to global fetch.");
|
|
13
|
+
return true;
|
|
14
|
+
} catch {
|
|
15
|
+
consola.log("Failed to bind Electron's net.fetch. Falling back to global fetch.");
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { bindElectronFetch };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=electron-fetch-DPhDE6JE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"electron-fetch-DPhDE6JE.js","names":[],"sources":["../src/lib/electron-fetch.ts"],"sourcesContent":["import consola from \"consola\"\nimport { createRequire } from \"node:module\"\n\ntype ElectronModule = {\n net?: {\n fetch?: typeof fetch\n }\n}\n\nconst require = createRequire(import.meta.url)\n\nexport function bindElectronFetch(): boolean {\n if (!process.versions.electron) return false\n\n try {\n const electronModule = require(\"electron\") as ElectronModule\n const netFetch = electronModule.net?.fetch\n\n if (typeof netFetch !== \"function\") return false\n\n globalThis.fetch = netFetch.bind(electronModule.net)\n consola.log(\"Successfully bound Electron's net.fetch to global fetch.\")\n return true\n } catch {\n consola.log(\n \"Failed to bind Electron's net.fetch. Falling back to global fetch.\",\n )\n return false\n }\n}\n"],"mappings":";;;AASA,MAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAE9C,SAAgB,oBAA6B;CAC3C,IAAI,CAAC,QAAQ,SAAS,UAAU,OAAO;CAEvC,IAAI;EACF,MAAM,iBAAiB,QAAQ,WAAW;EAC1C,MAAM,WAAW,eAAe,KAAK;EAErC,IAAI,OAAO,aAAa,YAAY,OAAO;EAE3C,WAAW,QAAQ,SAAS,KAAK,eAAe,IAAI;EACpD,QAAQ,IAAI,2DAA2D;EACvE,OAAO;SACD;EACN,QAAQ,IACN,qEACD;EACD,OAAO"}
|
package/dist/main.js
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
2
|
import { defineCommand, parseArgs, runMain } from "citty";
|
|
4
|
-
import consola from "consola";
|
|
5
|
-
//#region src/lib/electron-fetch.ts
|
|
6
|
-
const require = createRequire(import.meta.url);
|
|
7
|
-
function bindElectronFetch() {
|
|
8
|
-
if (!process.versions.electron) return false;
|
|
9
|
-
try {
|
|
10
|
-
const electronModule = require("electron");
|
|
11
|
-
const netFetch = electronModule.net?.fetch;
|
|
12
|
-
if (typeof netFetch !== "function") return false;
|
|
13
|
-
globalThis.fetch = netFetch.bind(electronModule.net);
|
|
14
|
-
consola.log("Successfully bound Electron's net.fetch to global fetch.");
|
|
15
|
-
return true;
|
|
16
|
-
} catch {
|
|
17
|
-
consola.log("Failed to bind Electron's net.fetch. Falling back to global fetch.");
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
3
|
//#region src/main.ts
|
|
23
4
|
const cliArgs = {
|
|
24
5
|
"api-home": {
|
|
@@ -38,12 +19,14 @@ const args = parseArgs(process.argv, cliArgs);
|
|
|
38
19
|
if (typeof args["api-home"] === "string") process.env.COPILOT_API_HOME = args["api-home"];
|
|
39
20
|
if (typeof args["oauth-app"] === "string") process.env.COPILOT_API_OAUTH_APP = args["oauth-app"];
|
|
40
21
|
if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRISE_URL = args["enterprise-url"];
|
|
22
|
+
if (process.platform === "win32" && process.stdout.isTTY && !process.env.WT_SESSION) process.env.WT_SESSION = "copilot-api";
|
|
23
|
+
const { bindElectronFetch } = await import("./electron-fetch-DPhDE6JE.js");
|
|
41
24
|
bindElectronFetch();
|
|
42
|
-
const { auth } = await import("./auth-
|
|
43
|
-
const { checkUsage } = await import("./check-usage-
|
|
25
|
+
const { auth } = await import("./auth-15xzL-eW.js");
|
|
26
|
+
const { checkUsage } = await import("./check-usage-Bu9w7RbA.js");
|
|
44
27
|
const { debug } = await import("./debug-TyT2u9dt.js");
|
|
45
|
-
const { mcp } = await import("./mcp-
|
|
46
|
-
const { start } = await import("./start-
|
|
28
|
+
const { mcp } = await import("./mcp-BseuqgHR.js");
|
|
29
|
+
const { start } = await import("./start-8y_02ZHG.js");
|
|
47
30
|
await runMain(defineCommand({
|
|
48
31
|
meta: {
|
|
49
32
|
name: "copilot-api",
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","names":[],"sources":["../src/
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand, runMain, parseArgs } from \"citty\"\n\nconst cliArgs = {\n \"api-home\": {\n type: \"string\",\n description: \"Path to the API home directory.\",\n },\n \"oauth-app\": {\n type: \"string\",\n description: \"OAuth app identifier.\",\n },\n \"enterprise-url\": {\n type: \"string\",\n description: \"Enterprise URL for GitHub.\",\n },\n} as const\n\nconst args = parseArgs(process.argv, cliArgs)\n\n// Set environment variables before loading other modules\nif (typeof args[\"api-home\"] === \"string\") {\n process.env.COPILOT_API_HOME = args[\"api-home\"]\n}\nif (typeof args[\"oauth-app\"] === \"string\") {\n process.env.COPILOT_API_OAUTH_APP = args[\"oauth-app\"]\n}\nif (typeof args[\"enterprise-url\"] === \"string\") {\n process.env.COPILOT_API_ENTERPRISE_URL = args[\"enterprise-url\"]\n}\n\n// Work around unjs/consola#392 until consola ships the upstream fix.\nif (\n process.platform === \"win32\"\n && process.stdout.isTTY\n && !process.env.WT_SESSION\n) {\n process.env.WT_SESSION = \"copilot-api\"\n}\n\nconst { bindElectronFetch } = await import(\"./lib/electron-fetch\")\nbindElectronFetch()\n\n// Dynamically import other modules to ensure environment variables are set\nconst { auth } = await import(\"./auth\")\nconst { checkUsage } = await import(\"./check-usage\")\nconst { debug } = await import(\"./debug\")\nconst { mcp } = await import(\"./mcp\")\nconst { start } = await import(\"./start\")\n\nconst main = defineCommand({\n meta: {\n name: \"copilot-api\",\n description:\n \"A wrapper around GitHub Copilot API to make it OpenAI compatible, making it usable for other tools.\",\n },\n subCommands: { auth, start, \"check-usage\": checkUsage, debug, mcp },\n args: cliArgs,\n})\n\nawait runMain(main)\n"],"mappings":";;;AAIA,MAAM,UAAU;CACd,YAAY;EACV,MAAM;EACN,aAAa;EACd;CACD,aAAa;EACX,MAAM;EACN,aAAa;EACd;CACD,kBAAkB;EAChB,MAAM;EACN,aAAa;EACd;CACF;AAED,MAAM,OAAO,UAAU,QAAQ,MAAM,QAAQ;AAG7C,IAAI,OAAO,KAAK,gBAAgB,UAC9B,QAAQ,IAAI,mBAAmB,KAAK;AAEtC,IAAI,OAAO,KAAK,iBAAiB,UAC/B,QAAQ,IAAI,wBAAwB,KAAK;AAE3C,IAAI,OAAO,KAAK,sBAAsB,UACpC,QAAQ,IAAI,6BAA6B,KAAK;AAIhD,IACE,QAAQ,aAAa,WAClB,QAAQ,OAAO,SACf,CAAC,QAAQ,IAAI,YAEhB,QAAQ,IAAI,aAAa;AAG3B,MAAM,EAAE,sBAAsB,MAAM,OAAO;AAC3C,mBAAmB;AAGnB,MAAM,EAAE,SAAS,MAAM,OAAO;AAC9B,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,MAAM,EAAE,QAAQ,MAAM,OAAO;AAC7B,MAAM,EAAE,UAAU,MAAM,OAAO;AAY/B,MAAM,QAVO,cAAc;CACzB,MAAM;EACJ,MAAM;EACN,aACE;EACH;CACD,aAAa;EAAE;EAAM;EAAO,eAAe;EAAY;EAAO;EAAK;CACnE,MAAM;CACP,CAEiB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createMcpToolSearchSentinel } from "./tool-search-
|
|
1
|
+
import { n as createMcpToolSearchSentinel } from "./tool-search-OX6iPJ9D.js";
|
|
2
2
|
import { defineCommand } from "citty";
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -34,4 +34,4 @@ const mcp = defineCommand({
|
|
|
34
34
|
//#endregion
|
|
35
35
|
export { mcp };
|
|
36
36
|
|
|
37
|
-
//# sourceMappingURL=mcp-
|
|
37
|
+
//# sourceMappingURL=mcp-BseuqgHR.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-
|
|
1
|
+
{"version":3,"file":"mcp-BseuqgHR.js","names":[],"sources":["../src/mcp.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\"\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\"\nimport { defineCommand } from \"citty\"\nimport { z } from \"zod\"\n\nimport { createMcpToolSearchSentinel } from \"./lib/tool-search\"\n\nconst SERVER_NAME = \"tool_search\"\nconst SERVER_VERSION = \"1.0.0\"\n\nexport const runMcpServer = async (): Promise<void> => {\n const server = new McpServer({\n name: SERVER_NAME,\n version: SERVER_VERSION,\n })\n\n server.registerTool(\n \"search\",\n {\n title: \"Tool Search Bridge\",\n description:\n \"Load deferred tools by exact name through the Copilot API tool_search bridge.\",\n inputSchema: {\n names: z\n .string()\n .describe(\n 'Comma-separated exact deferred tool names to load, for example \"TaskList,TaskGet,mcp__fetch__fetch\".',\n ),\n },\n _meta: {\n \"anthropic/alwaysLoad\": true,\n },\n },\n ({ names }) => ({\n content: [\n {\n type: \"text\",\n text: createMcpToolSearchSentinel(names),\n },\n ],\n }),\n )\n\n await server.connect(new StdioServerTransport())\n}\n\nexport const mcp = defineCommand({\n meta: {\n name: \"mcp\",\n description: \"Start the Copilot API MCP tool_search bridge over stdio\",\n },\n run() {\n return runMcpServer()\n },\n})\n"],"mappings":";;;;;;AASA,MAAM,cAAc;AACpB,MAAM,iBAAiB;AAEvB,MAAa,eAAe,YAA2B;CACrD,MAAM,SAAS,IAAI,UAAU;EAC3B,MAAM;EACN,SAAS;EACV,CAAC;CAEF,OAAO,aACL,UACA;EACE,OAAO;EACP,aACE;EACF,aAAa,EACX,OAAO,EACJ,QAAQ,CACR,SACC,yGACD,EACJ;EACD,OAAO,EACL,wBAAwB,MACzB;EACF,GACA,EAAE,aAAa,EACd,SAAS,CACP;EACE,MAAM;EACN,MAAM,4BAA4B,MAAM;EACzC,CACF,EACF,EACF;CAED,MAAM,OAAO,QAAQ,IAAI,sBAAsB,CAAC;;AAGlD,MAAa,MAAM,cAAc;CAC/B,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,OAAO,cAAc;;CAExB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as setModelMappings, S as resolveMappedModel, T as PATHS, _ as isResponsesApiWebSocketEnabled, a as getExtraPromptForModel, c as getModelResponsesApiCompactThreshold$1, d as getReasoningEffortForModel, f as getSmallModel, g as isResponsesApiWebSearchEnabled, h as isResponsesApiContextManagementEnabled, i as getConfig, l as getProviderConfig, m as isMessagesApiEnabled, n as getAnthropicApiKey, o as getMessageApiWebSearchModel, r as getClaudeTokenMultiplier, s as getModelMappings, u as getRawProviderConfig } from "./config-B71_S_hQ.js";
|
|
2
2
|
import { C as prepareMessageProxyHeaders, E as compactMessageSections, F as createPooledWebSocketStream, I as createWebSocketUrl, L as state, M as generateTraceId, N as requestContext, O as compactSystemPromptStarts, P as resolveTraceId$1, R as HTTPError, S as prepareInteractionHeaders, T as compactAutoContinuePromptStarts, _ as getCopilotUsage, b as copilotWebSocketHeaders, d as generateRequestIdFromPayload, f as getRootSessionId, g as sleep, h as parseUserIdMetadata, j as forwardCodexResponses, m as isNullish, p as getUUID, r as setupCodexToken, s as cacheModels, v as copilotBaseUrl, x as prepareForCompact, y as copilotHeaders, z as forwardError } from "./token-fpw8tAQS.js";
|
|
3
|
-
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-
|
|
3
|
+
import { a as isDeferredToolName, c as parseMcpToolSearchSentinel, d as shouldEnableResponsesToolSearch, i as isBridgeToolSearchName, l as resolveBridgeToolSearchName, o as listDeferredToolNames, r as formatToolSearchBridgeArguments, s as normalizeToolSearchBridgeArguments, t as BRIDGE_TOOL_SEARCH_NAME, u as selectDeferredToolsByNames } from "./tool-search-OX6iPJ9D.js";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import { createHash } from "node:crypto";
|
|
6
6
|
import fs, { readFileSync } from "node:fs";
|
|
@@ -6254,4 +6254,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
|
|
|
6254
6254
|
//#endregion
|
|
6255
6255
|
export { server };
|
|
6256
6256
|
|
|
6257
|
-
//# sourceMappingURL=server-
|
|
6257
|
+
//# sourceMappingURL=server-34rnRg4k.js.map
|