@jeffreycao/copilot-api 1.8.0 → 1.9.0
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 +10 -0
- package/README.zh-CN.md +10 -0
- package/dist/{auth-C9jquVrb.js → auth-C3UbfaIB.js} +3 -3
- package/dist/{auth-C9jquVrb.js.map → auth-C3UbfaIB.js.map} +1 -1
- package/dist/{check-usage-Ct5MACB6.js → check-usage-CELArOu5.js} +3 -3
- package/dist/{check-usage-Ct5MACB6.js.map → check-usage-CELArOu5.js.map} +1 -1
- package/dist/main.js +24 -3
- package/dist/main.js.map +1 -1
- package/dist/{server-CsVIHpFX.js → server-CA39Gy7x.js} +2 -2
- package/dist/{server-CsVIHpFX.js.map → server-CA39Gy7x.js.map} +1 -1
- package/dist/{start-BpU8ZccW.js → start-DKwPr9vl.js} +4 -4
- package/dist/{start-BpU8ZccW.js.map → start-DKwPr9vl.js.map} +1 -1
- package/dist/{token-D1pIdFn1.js → token-CIwAFD_6.js} +15 -5
- package/dist/token-CIwAFD_6.js.map +1 -0
- package/dist/{utils-BOfWR1uT.js → utils-DG6CB51Z.js} +10 -3
- package/dist/utils-DG6CB51Z.js.map +1 -0
- package/package.json +2 -1
- package/dist/token-D1pIdFn1.js.map +0 -1
- package/dist/utils-BOfWR1uT.js.map +0 -1
package/README.md
CHANGED
|
@@ -165,6 +165,16 @@ For authentication only:
|
|
|
165
165
|
npx @jeffreycao/copilot-api@latest auth
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
+
## Electron Desktop App
|
|
169
|
+
|
|
170
|
+
If you prefer a GUI, this repository also includes an Electron desktop app in `desktop/`. It supports GitHub Copilot sign-in or manual token entry, can start and stop the local proxy with one click, and shows the local endpoint, auth header, available models, usage, and logs in the app.
|
|
171
|
+
|
|
172
|
+
The settings screen also exposes `OAuth App`, `API Home`, `Enterprise URL`, verbose logging, and minimize-to-tray. Desktop packages are published in GitHub Releases:
|
|
173
|
+
|
|
174
|
+
https://github.com/caozhiyuan/copilot-api/releases
|
|
175
|
+
|
|
176
|
+
Download the installer for your platform, sign in inside the app, choose a port, start the server, then point your client at the local endpoint shown in the app.
|
|
177
|
+
|
|
168
178
|
## Using with Docker
|
|
169
179
|
|
|
170
180
|
Build image
|
package/README.zh-CN.md
CHANGED
|
@@ -167,6 +167,16 @@ npx @jeffreycao/copilot-api@latest start --port 8080
|
|
|
167
167
|
npx @jeffreycao/copilot-api@latest auth
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
+
## Electron 桌面应用
|
|
171
|
+
|
|
172
|
+
如果你更喜欢图形界面,仓库里还提供了位于 `desktop/` 的 Electron 桌面应用。它支持 GitHub Copilot 登录或手动填入 token,可以一键启动或停止本地代理,并在界面里直接查看本地端点、鉴权 Header、可用模型、额度和日志。
|
|
173
|
+
|
|
174
|
+
设置页还可以配置 `OAuth App`、`API Home`、`Enterprise URL`、详细日志以及最小化到托盘。桌面安装包发布在 GitHub Releases:
|
|
175
|
+
|
|
176
|
+
https://github.com/caozhiyuan/copilot-api/releases
|
|
177
|
+
|
|
178
|
+
下载对应平台的安装包后,在应用内登录、选择端口并启动服务,再把你的客户端指向应用里显示的本地端点即可。
|
|
179
|
+
|
|
170
180
|
## 配合 Docker 使用
|
|
171
181
|
|
|
172
182
|
构建镜像:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PATHS, ensurePaths } from "./paths-Cla6y5eD.js";
|
|
2
|
-
import { state } from "./utils-
|
|
3
|
-
import { setupGitHubToken } from "./token-
|
|
2
|
+
import { state } from "./utils-DG6CB51Z.js";
|
|
3
|
+
import { setupGitHubToken } from "./token-CIwAFD_6.js";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import consola from "consola";
|
|
6
6
|
|
|
@@ -43,4 +43,4 @@ const auth = defineCommand({
|
|
|
43
43
|
|
|
44
44
|
//#endregion
|
|
45
45
|
export { auth };
|
|
46
|
-
//# sourceMappingURL=auth-
|
|
46
|
+
//# sourceMappingURL=auth-C3UbfaIB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-
|
|
1
|
+
{"version":3,"file":"auth-C3UbfaIB.js","names":[],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { setupGitHubToken } from \"./lib/token\"\n\ninterface RunAuthOptions {\n verbose: boolean\n showToken: boolean\n}\n\nexport async function runAuth(options: RunAuthOptions): Promise<void> {\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 await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n}\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run GitHub auth flow without running the server\",\n },\n args: {\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 GitHub token on auth\",\n },\n },\n run({ args }) {\n return runAuth({\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":";;;;;;;AAcA,eAAsB,QAAQ,SAAwC;AACpE,KAAI,QAAQ,SAAS;AACnB,UAAQ,QAAQ;AAChB,UAAQ,KAAK,0BAA0B;;AAGzC,OAAM,YAAY,QAAQ;AAE1B,OAAM,aAAa;AACnB,OAAM,iBAAiB,EAAE,OAAO,MAAM,CAAC;AACvC,SAAQ,QAAQ,2BAA2B,MAAM,kBAAkB;;AAGrE,MAAa,OAAO,cAAc;CAChC,MAAM;EACJ,MAAM;EACN,aAAa;EACd;CACD,MAAM;EACJ,SAAS;GACP,OAAO;GACP,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACD,cAAc;GACZ,MAAM;GACN,SAAS;GACT,aAAa;GACd;EACF;CACD,IAAI,EAAE,QAAQ;AACZ,SAAO,QAAQ;GACb,SAAS,KAAK;GACd,WAAW,KAAK;GACjB,CAAC;;CAEL,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ensurePaths } from "./paths-Cla6y5eD.js";
|
|
2
|
-
import { getCopilotUsage } from "./utils-
|
|
3
|
-
import { setupGitHubToken } from "./token-
|
|
2
|
+
import { getCopilotUsage } from "./utils-DG6CB51Z.js";
|
|
3
|
+
import { setupGitHubToken } from "./token-CIwAFD_6.js";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import consola from "consola";
|
|
6
6
|
|
|
@@ -41,4 +41,4 @@ const checkUsage = defineCommand({
|
|
|
41
41
|
|
|
42
42
|
//#endregion
|
|
43
43
|
export { checkUsage };
|
|
44
|
-
//# sourceMappingURL=check-usage-
|
|
44
|
+
//# sourceMappingURL=check-usage-CELArOu5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-usage-
|
|
1
|
+
{"version":3,"file":"check-usage-CELArOu5.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 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;AACV,QAAM,aAAa;AACnB,QAAM,kBAAkB;AACxB,MAAI;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;AACnE,QAAI,CAAC,KAAM,QAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;AAC9B,WAAO,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;AAED,WAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;AACZ,WAAQ,MAAM,kCAAkC,IAAI;AACpD,WAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
|
package/dist/main.js
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { defineCommand, parseArgs, runMain } from "citty";
|
|
4
|
+
import consola from "consola";
|
|
3
5
|
|
|
6
|
+
//#region src/lib/electron-fetch.ts
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
function bindElectronFetch() {
|
|
9
|
+
if (!process.versions.electron) return false;
|
|
10
|
+
try {
|
|
11
|
+
const electronModule = require("electron");
|
|
12
|
+
const netFetch = electronModule.net?.fetch;
|
|
13
|
+
if (typeof netFetch !== "function") return false;
|
|
14
|
+
globalThis.fetch = netFetch.bind(electronModule.net);
|
|
15
|
+
consola.info("Successfully bound Electron's net.fetch to global fetch.");
|
|
16
|
+
return true;
|
|
17
|
+
} catch {
|
|
18
|
+
consola.info("Failed to bind Electron's net.fetch. Falling back to global fetch.");
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
4
24
|
//#region src/main.ts
|
|
5
25
|
const cliArgs = {
|
|
6
26
|
"api-home": {
|
|
@@ -20,10 +40,11 @@ const args = parseArgs(process.argv, cliArgs);
|
|
|
20
40
|
if (typeof args["api-home"] === "string") process.env.COPILOT_API_HOME = args["api-home"];
|
|
21
41
|
if (typeof args["oauth-app"] === "string") process.env.COPILOT_API_OAUTH_APP = args["oauth-app"];
|
|
22
42
|
if (typeof args["enterprise-url"] === "string") process.env.COPILOT_API_ENTERPRISE_URL = args["enterprise-url"];
|
|
23
|
-
|
|
24
|
-
const {
|
|
43
|
+
bindElectronFetch();
|
|
44
|
+
const { auth } = await import("./auth-C3UbfaIB.js");
|
|
45
|
+
const { checkUsage } = await import("./check-usage-CELArOu5.js");
|
|
25
46
|
const { debug } = await import("./debug-DcC7ZPH0.js");
|
|
26
|
-
const { start } = await import("./start-
|
|
47
|
+
const { start } = await import("./start-DKwPr9vl.js");
|
|
27
48
|
const main = defineCommand({
|
|
28
49
|
meta: {
|
|
29
50
|
name: "copilot-api",
|
package/dist/main.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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// 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 { 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 },\n args: cliArgs,\n})\n\nawait runMain(main)\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"main.js","names":[],"sources":["../src/lib/electron-fetch.ts","../src/main.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.info(\"Successfully bound Electron's net.fetch to global fetch.\")\n return true\n } catch {\n consola.info(\n \"Failed to bind Electron's net.fetch. Falling back to global fetch.\",\n )\n return false\n }\n}\n","#!/usr/bin/env node\n\nimport { defineCommand, runMain, parseArgs } from \"citty\"\n\nimport { bindElectronFetch } from \"./lib/electron-fetch\"\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\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 { 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 },\n args: cliArgs,\n})\n\nawait runMain(main)\n"],"mappings":";;;;;;AASA,MAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAE9C,SAAgB,oBAA6B;AAC3C,KAAI,CAAC,QAAQ,SAAS,SAAU,QAAO;AAEvC,KAAI;EACF,MAAM,iBAAiB,QAAQ,WAAW;EAC1C,MAAM,WAAW,eAAe,KAAK;AAErC,MAAI,OAAO,aAAa,WAAY,QAAO;AAE3C,aAAW,QAAQ,SAAS,KAAK,eAAe,IAAI;AACpD,UAAQ,KAAK,2DAA2D;AACxE,SAAO;SACD;AACN,UAAQ,KACN,qEACD;AACD,SAAO;;;;;;ACrBX,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,SAC9B,SAAQ,IAAI,mBAAmB,KAAK;AAEtC,IAAI,OAAO,KAAK,iBAAiB,SAC/B,SAAQ,IAAI,wBAAwB,KAAK;AAE3C,IAAI,OAAO,KAAK,sBAAsB,SACpC,SAAQ,IAAI,6BAA6B,KAAK;AAGhD,mBAAmB;AAGnB,MAAM,EAAE,SAAS,MAAM,OAAO;AAC9B,MAAM,EAAE,eAAe,MAAM,OAAO;AACpC,MAAM,EAAE,UAAU,MAAM,OAAO;AAC/B,MAAM,EAAE,UAAU,MAAM,OAAO;AAE/B,MAAM,OAAO,cAAc;CACzB,MAAM;EACJ,MAAM;EACN,aACE;EACH;CACD,aAAa;EAAE;EAAM;EAAO,eAAe;EAAY;EAAO;CAC9D,MAAM;CACP,CAAC;AAEF,MAAM,QAAQ,KAAK"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PATHS } from "./paths-Cla6y5eD.js";
|
|
2
|
-
import { COMPACT_AUTO_CONTINUE, COMPACT_REQUEST, HTTPError, cacheModels, compactAutoContinuePromptStarts, compactMessageSections, compactSummaryPromptStart, compactSystemPromptStarts, compactTextOnlyGuard, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getCopilotUsage, getRootSessionId, getUUID, isNullish, parseUserIdMetadata, prepareForCompact, prepareInteractionHeaders, prepareMessageProxyHeaders, requestContext, resolveTraceId, sleep, state } from "./utils-
|
|
2
|
+
import { COMPACT_AUTO_CONTINUE, COMPACT_REQUEST, HTTPError, cacheModels, compactAutoContinuePromptStarts, compactMessageSections, compactSummaryPromptStart, compactSystemPromptStarts, compactTextOnlyGuard, copilotBaseUrl, copilotHeaders, forwardError, generateRequestIdFromPayload, getCopilotUsage, getRootSessionId, getUUID, isNullish, parseUserIdMetadata, prepareForCompact, prepareInteractionHeaders, prepareMessageProxyHeaders, requestContext, resolveTraceId, sleep, state } from "./utils-DG6CB51Z.js";
|
|
3
3
|
import { getAnthropicApiKey, getClaudeTokenMultiplier, getConfig, getExtraPromptForModel, getProviderConfig, getReasoningEffortForModel, getSmallModel, isMessagesApiEnabled, isResponsesApiContextManagementModel, isResponsesApiWebSearchEnabled } from "./config-BQvWqYh_.js";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
import path from "node:path";
|
|
@@ -3222,4 +3222,4 @@ server.route("/:provider/v1/models", providerModelRoutes);
|
|
|
3222
3222
|
|
|
3223
3223
|
//#endregion
|
|
3224
3224
|
export { server };
|
|
3225
|
-
//# sourceMappingURL=server-
|
|
3225
|
+
//# sourceMappingURL=server-CA39Gy7x.js.map
|