copilot-api-plus 1.0.31 → 1.0.32
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 +30 -2
- package/dist/{auth-Ijg_vdBM.js → auth-B2lTFLSD.js} +3 -3
- package/dist/auth-CCwbOOQN.js +4 -0
- package/dist/{auth-y23hLerx.js → auth-CM_ilreU.js} +2 -2
- package/dist/{auth-y23hLerx.js.map → auth-CM_ilreU.js.map} +1 -1
- package/dist/{auth-OZNLGzjK.js → auth-T55-Bhoo.js} +2 -2
- package/dist/{auth-OZNLGzjK.js.map → auth-T55-Bhoo.js.map} +1 -1
- package/dist/get-models-CmDpYUV-.js +5 -0
- package/dist/{get-models-B5kAooWg.js → get-models-DMdiCNoU.js} +2 -2
- package/dist/{get-models-B5kAooWg.js.map → get-models-DMdiCNoU.js.map} +1 -1
- package/dist/main.js +1027 -901
- package/dist/main.js.map +1 -1
- package/dist/{paths-Ch0ixSo2.js → paths-CVYLp61D.js} +2 -2
- package/dist/{paths-Ch0ixSo2.js.map → paths-CVYLp61D.js.map} +1 -1
- package/dist/{token-BUmQ_BcM.js → token-ClgudjZm.js} +2 -2
- package/dist/{token-BUmQ_BcM.js.map → token-ClgudjZm.js.map} +1 -1
- package/dist/{token-DhdRMuOy.js → token-sYqHiHEd.js} +2 -2
- package/package.json +1 -1
- package/dist/auth-wHA1Oitm.js +0 -4
- package/dist/get-models-D9Mg0iWy.js +0 -5
package/dist/main.js
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { PATHS, ensurePaths } from "./paths-
|
|
2
|
+
import { PATHS, ensurePaths } from "./paths-CVYLp61D.js";
|
|
3
3
|
import { state } from "./state-CcLGr8VN.js";
|
|
4
4
|
import { GITHUB_API_BASE_URL, copilotBaseUrl, copilotHeaders, githubHeaders } from "./get-user-BzIEATcF.js";
|
|
5
5
|
import { HTTPError, forwardError } from "./error-CvU5otz-.js";
|
|
6
|
-
import { cacheModels, cacheVSCodeVersion, clearGithubToken, isNullish, setupCopilotToken, setupGitHubToken, sleep } from "./token-
|
|
7
|
-
import { clearAntigravityAuth, disableCurrentAccount, getAntigravityAuthPath, getApiKey, getValidAccessToken, rotateAccount } from "./auth-
|
|
8
|
-
import { clearZenAuth, getZenAuthPath } from "./auth-
|
|
9
|
-
import { getAntigravityModels, getAntigravityUsage, isThinkingModel } from "./get-models-
|
|
6
|
+
import { cacheModels, cacheVSCodeVersion, clearGithubToken, isNullish, setupCopilotToken, setupGitHubToken, sleep } from "./token-ClgudjZm.js";
|
|
7
|
+
import { clearAntigravityAuth, disableCurrentAccount, getAntigravityAuthPath, getApiKey, getValidAccessToken, rotateAccount } from "./auth-CM_ilreU.js";
|
|
8
|
+
import { clearZenAuth, getZenAuthPath } from "./auth-T55-Bhoo.js";
|
|
9
|
+
import { getAntigravityModels, getAntigravityUsage, isThinkingModel } from "./get-models-DMdiCNoU.js";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { defineCommand, runMain } from "citty";
|
|
12
12
|
import consola from "consola";
|
|
13
13
|
import fs from "node:fs/promises";
|
|
14
|
-
import os from "node:os";
|
|
15
14
|
import path from "node:path";
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import { getProxyForUrl } from "proxy-from-env";
|
|
17
|
+
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
16
18
|
import * as p from "@clack/prompts";
|
|
17
19
|
import clipboard from "clipboardy";
|
|
18
20
|
import { serve } from "srvx";
|
|
19
21
|
import invariant from "tiny-invariant";
|
|
20
|
-
import { getProxyForUrl } from "proxy-from-env";
|
|
21
|
-
import { Agent, ProxyAgent, setGlobalDispatcher } from "undici";
|
|
22
22
|
import { execSync } from "node:child_process";
|
|
23
23
|
import process$1 from "node:process";
|
|
24
24
|
import { Hono } from "hono";
|
|
@@ -35,951 +35,1076 @@ var __commonJS = (cb, mod) => function() {
|
|
|
35
35
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
36
36
|
|
|
37
37
|
//#endregion
|
|
38
|
-
//#region
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
description: "Enable verbose logging"
|
|
38
|
+
//#region node_modules/dotenv/package.json
|
|
39
|
+
var require_package = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/package.json": ((exports, module) => {
|
|
40
|
+
module.exports = {
|
|
41
|
+
"name": "dotenv",
|
|
42
|
+
"version": "17.2.3",
|
|
43
|
+
"description": "Loads environment variables from .env file",
|
|
44
|
+
"main": "lib/main.js",
|
|
45
|
+
"types": "lib/main.d.ts",
|
|
46
|
+
"exports": {
|
|
47
|
+
".": {
|
|
48
|
+
"types": "./lib/main.d.ts",
|
|
49
|
+
"require": "./lib/main.js",
|
|
50
|
+
"default": "./lib/main.js"
|
|
51
|
+
},
|
|
52
|
+
"./config": "./config.js",
|
|
53
|
+
"./config.js": "./config.js",
|
|
54
|
+
"./lib/env-options": "./lib/env-options.js",
|
|
55
|
+
"./lib/env-options.js": "./lib/env-options.js",
|
|
56
|
+
"./lib/cli-options": "./lib/cli-options.js",
|
|
57
|
+
"./lib/cli-options.js": "./lib/cli-options.js",
|
|
58
|
+
"./package.json": "./package.json"
|
|
60
59
|
},
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
function summarizeQuota(name, snap) {
|
|
101
|
-
if (!snap) return `${name}: N/A`;
|
|
102
|
-
const total = snap.entitlement;
|
|
103
|
-
const used = total - snap.remaining;
|
|
104
|
-
const percentUsed = total > 0 ? used / total * 100 : 0;
|
|
105
|
-
const percentRemaining = snap.percent_remaining;
|
|
106
|
-
return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`;
|
|
107
|
-
}
|
|
108
|
-
const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`;
|
|
109
|
-
const chatLine = summarizeQuota("Chat", usage.quota_snapshots.chat);
|
|
110
|
-
const completionsLine = summarizeQuota("Completions", usage.quota_snapshots.completions);
|
|
111
|
-
consola.box(`Copilot Usage (plan: ${usage.copilot_plan})\nQuota resets: ${usage.quota_reset_date}\n\nQuotas:\n ${premiumLine}\n ${chatLine}\n ${completionsLine}`);
|
|
112
|
-
} catch (err) {
|
|
113
|
-
consola.error("Failed to fetch Copilot usage:", err);
|
|
114
|
-
process.exit(1);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
});
|
|
60
|
+
"scripts": {
|
|
61
|
+
"dts-check": "tsc --project tests/types/tsconfig.json",
|
|
62
|
+
"lint": "standard",
|
|
63
|
+
"pretest": "npm run lint && npm run dts-check",
|
|
64
|
+
"test": "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
65
|
+
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
66
|
+
"prerelease": "npm test",
|
|
67
|
+
"release": "standard-version"
|
|
68
|
+
},
|
|
69
|
+
"repository": {
|
|
70
|
+
"type": "git",
|
|
71
|
+
"url": "git://github.com/motdotla/dotenv.git"
|
|
72
|
+
},
|
|
73
|
+
"homepage": "https://github.com/motdotla/dotenv#readme",
|
|
74
|
+
"funding": "https://dotenvx.com",
|
|
75
|
+
"keywords": [
|
|
76
|
+
"dotenv",
|
|
77
|
+
"env",
|
|
78
|
+
".env",
|
|
79
|
+
"environment",
|
|
80
|
+
"variables",
|
|
81
|
+
"config",
|
|
82
|
+
"settings"
|
|
83
|
+
],
|
|
84
|
+
"readmeFilename": "README.md",
|
|
85
|
+
"license": "BSD-2-Clause",
|
|
86
|
+
"devDependencies": {
|
|
87
|
+
"@types/node": "^18.11.3",
|
|
88
|
+
"decache": "^4.6.2",
|
|
89
|
+
"sinon": "^14.0.1",
|
|
90
|
+
"standard": "^17.0.0",
|
|
91
|
+
"standard-version": "^9.5.0",
|
|
92
|
+
"tap": "^19.2.0",
|
|
93
|
+
"typescript": "^4.8.4"
|
|
94
|
+
},
|
|
95
|
+
"engines": { "node": ">=12" },
|
|
96
|
+
"browser": { "fs": false }
|
|
97
|
+
};
|
|
98
|
+
}) });
|
|
118
99
|
|
|
119
100
|
//#endregion
|
|
120
|
-
//#region
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
101
|
+
//#region node_modules/dotenv/lib/main.js
|
|
102
|
+
var require_main = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/main.js": ((exports, module) => {
|
|
103
|
+
const fs$1 = __require("fs");
|
|
104
|
+
const path$1 = __require("path");
|
|
105
|
+
const os$1 = __require("os");
|
|
106
|
+
const crypto$1 = __require("crypto");
|
|
107
|
+
const version = require_package().version;
|
|
108
|
+
const TIPS = [
|
|
109
|
+
"🔐 encrypt with Dotenvx: https://dotenvx.com",
|
|
110
|
+
"🔐 prevent committing .env to code: https://dotenvx.com/precommit",
|
|
111
|
+
"🔐 prevent building .env in docker: https://dotenvx.com/prebuild",
|
|
112
|
+
"📡 add observability to secrets: https://dotenvx.com/ops",
|
|
113
|
+
"👥 sync secrets across teammates & machines: https://dotenvx.com/ops",
|
|
114
|
+
"🗂️ backup and recover secrets: https://dotenvx.com/ops",
|
|
115
|
+
"✅ audit secrets and track compliance: https://dotenvx.com/ops",
|
|
116
|
+
"🔄 add secrets lifecycle management: https://dotenvx.com/ops",
|
|
117
|
+
"🔑 add access controls to secrets: https://dotenvx.com/ops",
|
|
118
|
+
"🛠️ run anywhere with `dotenvx run -- yourcommand`",
|
|
119
|
+
"⚙️ specify custom .env file path with { path: '/custom/path/.env' }",
|
|
120
|
+
"⚙️ enable debug logging with { debug: true }",
|
|
121
|
+
"⚙️ override existing env vars with { override: true }",
|
|
122
|
+
"⚙️ suppress all logs with { quiet: true }",
|
|
123
|
+
"⚙️ write to custom object with { processEnv: myObject }",
|
|
124
|
+
"⚙️ load multiple .env files with { path: ['.env.local', '.env'] }"
|
|
125
|
+
];
|
|
126
|
+
function _getRandomTip() {
|
|
127
|
+
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
138
128
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Get proxy configuration
|
|
150
|
-
*/
|
|
151
|
-
async function getProxyConfig() {
|
|
152
|
-
return (await loadConfig()).proxy;
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* Save proxy configuration
|
|
156
|
-
*/
|
|
157
|
-
async function saveProxyConfig(proxyConfig) {
|
|
158
|
-
const config$1 = await loadConfig();
|
|
159
|
-
config$1.proxy = proxyConfig;
|
|
160
|
-
await saveConfig(config$1);
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Clear proxy configuration
|
|
164
|
-
*/
|
|
165
|
-
async function clearProxyConfig() {
|
|
166
|
-
const config$1 = await loadConfig();
|
|
167
|
-
delete config$1.proxy;
|
|
168
|
-
await saveConfig(config$1);
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Apply saved proxy configuration to environment variables
|
|
172
|
-
* This should be called at startup to restore proxy settings
|
|
173
|
-
*/
|
|
174
|
-
async function applyProxyConfig() {
|
|
175
|
-
const proxyConfig = await getProxyConfig();
|
|
176
|
-
if (!proxyConfig || !proxyConfig.enabled) return false;
|
|
177
|
-
if (proxyConfig.httpProxy) {
|
|
178
|
-
process.env.HTTP_PROXY = proxyConfig.httpProxy;
|
|
179
|
-
process.env.http_proxy = proxyConfig.httpProxy;
|
|
129
|
+
function parseBoolean(value) {
|
|
130
|
+
if (typeof value === "string") return ![
|
|
131
|
+
"false",
|
|
132
|
+
"0",
|
|
133
|
+
"no",
|
|
134
|
+
"off",
|
|
135
|
+
""
|
|
136
|
+
].includes(value.toLowerCase());
|
|
137
|
+
return Boolean(value);
|
|
180
138
|
}
|
|
181
|
-
|
|
182
|
-
process.
|
|
183
|
-
process.env.https_proxy = proxyConfig.httpsProxy;
|
|
139
|
+
function supportsAnsi() {
|
|
140
|
+
return process.stdout.isTTY;
|
|
184
141
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
process.env.no_proxy = proxyConfig.noProxy;
|
|
142
|
+
function dim(text) {
|
|
143
|
+
return supportsAnsi() ? `\x1b[2m${text}\x1b[0m` : text;
|
|
188
144
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
return {
|
|
209
|
-
name: isBun ? "bun" : "node",
|
|
210
|
-
version: isBun ? Bun.version : process.version.slice(1),
|
|
211
|
-
platform: os.platform(),
|
|
212
|
-
arch: os.arch()
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
async function checkTokenExists() {
|
|
216
|
-
try {
|
|
217
|
-
if (!(await fs.stat(PATHS.GITHUB_TOKEN_PATH)).isFile()) return false;
|
|
218
|
-
return (await fs.readFile(PATHS.GITHUB_TOKEN_PATH, "utf8")).trim().length > 0;
|
|
219
|
-
} catch {
|
|
220
|
-
return false;
|
|
145
|
+
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
|
|
146
|
+
function parse(src) {
|
|
147
|
+
const obj = {};
|
|
148
|
+
let lines = src.toString();
|
|
149
|
+
lines = lines.replace(/\r\n?/gm, "\n");
|
|
150
|
+
let match;
|
|
151
|
+
while ((match = LINE.exec(lines)) != null) {
|
|
152
|
+
const key = match[1];
|
|
153
|
+
let value = match[2] || "";
|
|
154
|
+
value = value.trim();
|
|
155
|
+
const maybeQuote = value[0];
|
|
156
|
+
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
157
|
+
if (maybeQuote === "\"") {
|
|
158
|
+
value = value.replace(/\\n/g, "\n");
|
|
159
|
+
value = value.replace(/\\r/g, "\r");
|
|
160
|
+
}
|
|
161
|
+
obj[key] = value;
|
|
162
|
+
}
|
|
163
|
+
return obj;
|
|
221
164
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
165
|
+
function _parseVault(options$1) {
|
|
166
|
+
options$1 = options$1 || {};
|
|
167
|
+
const vaultPath = _vaultPath(options$1);
|
|
168
|
+
options$1.path = vaultPath;
|
|
169
|
+
const result = DotenvModule.configDotenv(options$1);
|
|
170
|
+
if (!result.parsed) {
|
|
171
|
+
const err = /* @__PURE__ */ new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
172
|
+
err.code = "MISSING_DATA";
|
|
173
|
+
throw err;
|
|
174
|
+
}
|
|
175
|
+
const keys = _dotenvKey(options$1).split(",");
|
|
176
|
+
const length = keys.length;
|
|
177
|
+
let decrypted;
|
|
178
|
+
for (let i = 0; i < length; i++) try {
|
|
179
|
+
const key = keys[i].trim();
|
|
180
|
+
const attrs = _instructions(result, key);
|
|
181
|
+
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
182
|
+
break;
|
|
183
|
+
} catch (error) {
|
|
184
|
+
if (i + 1 >= length) throw error;
|
|
185
|
+
}
|
|
186
|
+
return DotenvModule.parse(decrypted);
|
|
229
187
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const zenAuthPath = getZenAuthPath();
|
|
233
|
-
const antigravityAuthPath = getAntigravityAuthPath();
|
|
234
|
-
const [version$1, githubExists, zenExists, antigravityExists, proxyConfig] = await Promise.all([
|
|
235
|
-
getPackageVersion(),
|
|
236
|
-
checkTokenExists(),
|
|
237
|
-
checkFileExists(zenAuthPath),
|
|
238
|
-
checkFileExists(antigravityAuthPath),
|
|
239
|
-
getProxyConfig()
|
|
240
|
-
]);
|
|
241
|
-
return {
|
|
242
|
-
version: version$1,
|
|
243
|
-
runtime: getRuntimeInfo(),
|
|
244
|
-
paths: {
|
|
245
|
-
APP_DIR: PATHS.APP_DIR,
|
|
246
|
-
GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,
|
|
247
|
-
ZEN_AUTH_PATH: zenAuthPath,
|
|
248
|
-
ANTIGRAVITY_AUTH_PATH: antigravityAuthPath
|
|
249
|
-
},
|
|
250
|
-
credentials: {
|
|
251
|
-
github: githubExists,
|
|
252
|
-
zen: zenExists,
|
|
253
|
-
antigravity: antigravityExists
|
|
254
|
-
},
|
|
255
|
-
proxy: proxyConfig
|
|
256
|
-
};
|
|
257
|
-
}
|
|
258
|
-
function printDebugInfoPlain(info) {
|
|
259
|
-
let proxyStatus = "Not configured";
|
|
260
|
-
if (info.proxy) proxyStatus = info.proxy.enabled ? `Enabled (${info.proxy.httpProxy || info.proxy.httpsProxy})` : "Disabled";
|
|
261
|
-
consola.info(`copilot-api-plus debug
|
|
262
|
-
|
|
263
|
-
Version: ${info.version}
|
|
264
|
-
Runtime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})
|
|
265
|
-
|
|
266
|
-
Paths:
|
|
267
|
-
APP_DIR: ${info.paths.APP_DIR}
|
|
268
|
-
GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}
|
|
269
|
-
ZEN_AUTH_PATH: ${info.paths.ZEN_AUTH_PATH}
|
|
270
|
-
ANTIGRAVITY_AUTH_PATH: ${info.paths.ANTIGRAVITY_AUTH_PATH}
|
|
271
|
-
|
|
272
|
-
Credentials:
|
|
273
|
-
GitHub Copilot: ${info.credentials.github ? "✅ Configured" : "❌ Not configured"}
|
|
274
|
-
OpenCode Zen: ${info.credentials.zen ? "✅ Configured" : "❌ Not configured"}
|
|
275
|
-
Google Antigravity: ${info.credentials.antigravity ? "✅ Configured" : "❌ Not configured"}
|
|
276
|
-
|
|
277
|
-
Proxy: ${proxyStatus}`);
|
|
278
|
-
}
|
|
279
|
-
function printDebugInfoJson(info) {
|
|
280
|
-
console.log(JSON.stringify(info, null, 2));
|
|
281
|
-
}
|
|
282
|
-
async function runDebug(options$1) {
|
|
283
|
-
const debugInfo = await getDebugInfo();
|
|
284
|
-
if (options$1.json) printDebugInfoJson(debugInfo);
|
|
285
|
-
else printDebugInfoPlain(debugInfo);
|
|
286
|
-
}
|
|
287
|
-
const debug = defineCommand({
|
|
288
|
-
meta: {
|
|
289
|
-
name: "debug",
|
|
290
|
-
description: "Print debug information about the application"
|
|
291
|
-
},
|
|
292
|
-
args: { json: {
|
|
293
|
-
type: "boolean",
|
|
294
|
-
default: false,
|
|
295
|
-
description: "Output debug information as JSON"
|
|
296
|
-
} },
|
|
297
|
-
run({ args }) {
|
|
298
|
-
return runDebug({ json: args.json });
|
|
188
|
+
function _warn(message) {
|
|
189
|
+
console.error(`[dotenv@${version}][WARN] ${message}`);
|
|
299
190
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
//#endregion
|
|
303
|
-
//#region src/logout.ts
|
|
304
|
-
async function runLogout(options$1) {
|
|
305
|
-
await ensurePaths();
|
|
306
|
-
if (options$1.all) {
|
|
307
|
-
await clearGithubToken();
|
|
308
|
-
await clearZenAuth();
|
|
309
|
-
await clearAntigravityAuth();
|
|
310
|
-
consola.success("Logged out from all services");
|
|
311
|
-
consola.info(`GitHub token: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
312
|
-
consola.info(`Zen API key: ${getZenAuthPath()}`);
|
|
313
|
-
consola.info(`Antigravity accounts: ${getAntigravityAuthPath()}`);
|
|
314
|
-
return;
|
|
191
|
+
function _debug(message) {
|
|
192
|
+
console.log(`[dotenv@${version}][DEBUG] ${message}`);
|
|
315
193
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
consola.success("Logged out from GitHub Copilot");
|
|
319
|
-
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
320
|
-
return;
|
|
194
|
+
function _log(message) {
|
|
195
|
+
console.log(`[dotenv@${version}] ${message}`);
|
|
321
196
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return;
|
|
197
|
+
function _dotenvKey(options$1) {
|
|
198
|
+
if (options$1 && options$1.DOTENV_KEY && options$1.DOTENV_KEY.length > 0) return options$1.DOTENV_KEY;
|
|
199
|
+
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) return process.env.DOTENV_KEY;
|
|
200
|
+
return "";
|
|
327
201
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
202
|
+
function _instructions(result, dotenvKey) {
|
|
203
|
+
let uri;
|
|
204
|
+
try {
|
|
205
|
+
uri = new URL(dotenvKey);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
if (error.code === "ERR_INVALID_URL") {
|
|
208
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
209
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
210
|
+
throw err;
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
const key = uri.password;
|
|
215
|
+
if (!key) {
|
|
216
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
217
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
218
|
+
throw err;
|
|
219
|
+
}
|
|
220
|
+
const environment = uri.searchParams.get("environment");
|
|
221
|
+
if (!environment) {
|
|
222
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
223
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
227
|
+
const ciphertext = result.parsed[environmentKey];
|
|
228
|
+
if (!ciphertext) {
|
|
229
|
+
const err = /* @__PURE__ */ new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
230
|
+
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
231
|
+
throw err;
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
ciphertext,
|
|
235
|
+
key
|
|
236
|
+
};
|
|
333
237
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
options
|
|
337
|
-
"
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
})) {
|
|
343
|
-
case "GitHub Copilot token":
|
|
344
|
-
await clearGithubToken();
|
|
345
|
-
consola.success("Logged out from GitHub Copilot");
|
|
346
|
-
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
347
|
-
break;
|
|
348
|
-
case "OpenCode Zen API key":
|
|
349
|
-
await clearZenAuth();
|
|
350
|
-
consola.success("Logged out from OpenCode Zen");
|
|
351
|
-
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
352
|
-
break;
|
|
353
|
-
case "Google Antigravity accounts":
|
|
354
|
-
await clearAntigravityAuth();
|
|
355
|
-
consola.success("Logged out from Google Antigravity");
|
|
356
|
-
consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`);
|
|
357
|
-
break;
|
|
358
|
-
case "All credentials":
|
|
359
|
-
await clearGithubToken();
|
|
360
|
-
await clearZenAuth();
|
|
361
|
-
await clearAntigravityAuth();
|
|
362
|
-
consola.success("Logged out from all services");
|
|
363
|
-
break;
|
|
238
|
+
function _vaultPath(options$1) {
|
|
239
|
+
let possibleVaultPath = null;
|
|
240
|
+
if (options$1 && options$1.path && options$1.path.length > 0) if (Array.isArray(options$1.path)) {
|
|
241
|
+
for (const filepath of options$1.path) if (fs$1.existsSync(filepath)) possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
242
|
+
} else possibleVaultPath = options$1.path.endsWith(".vault") ? options$1.path : `${options$1.path}.vault`;
|
|
243
|
+
else possibleVaultPath = path$1.resolve(process.cwd(), ".env.vault");
|
|
244
|
+
if (fs$1.existsSync(possibleVaultPath)) return possibleVaultPath;
|
|
245
|
+
return null;
|
|
364
246
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
meta: {
|
|
368
|
-
name: "logout",
|
|
369
|
-
description: "Clear stored credentials and logout"
|
|
370
|
-
},
|
|
371
|
-
args: {
|
|
372
|
-
github: {
|
|
373
|
-
alias: "g",
|
|
374
|
-
type: "boolean",
|
|
375
|
-
default: false,
|
|
376
|
-
description: "Clear only GitHub Copilot token"
|
|
377
|
-
},
|
|
378
|
-
zen: {
|
|
379
|
-
alias: "z",
|
|
380
|
-
type: "boolean",
|
|
381
|
-
default: false,
|
|
382
|
-
description: "Clear only OpenCode Zen API key"
|
|
383
|
-
},
|
|
384
|
-
antigravity: {
|
|
385
|
-
type: "boolean",
|
|
386
|
-
default: false,
|
|
387
|
-
description: "Clear only Google Antigravity accounts"
|
|
388
|
-
},
|
|
389
|
-
all: {
|
|
390
|
-
alias: "a",
|
|
391
|
-
type: "boolean",
|
|
392
|
-
default: false,
|
|
393
|
-
description: "Clear all credentials (GitHub, Zen, and Antigravity)"
|
|
394
|
-
}
|
|
395
|
-
},
|
|
396
|
-
run({ args }) {
|
|
397
|
-
return runLogout({
|
|
398
|
-
github: args.github,
|
|
399
|
-
zen: args.zen,
|
|
400
|
-
antigravity: args.antigravity,
|
|
401
|
-
all: args.all
|
|
402
|
-
});
|
|
247
|
+
function _resolveHome(envPath) {
|
|
248
|
+
return envPath[0] === "~" ? path$1.join(os$1.homedir(), envPath.slice(1)) : envPath;
|
|
403
249
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
},
|
|
429
|
-
clear: {
|
|
430
|
-
type: "boolean",
|
|
431
|
-
default: false,
|
|
432
|
-
description: "Clear all proxy settings"
|
|
433
|
-
},
|
|
434
|
-
show: {
|
|
435
|
-
type: "boolean",
|
|
436
|
-
default: false,
|
|
437
|
-
description: "Show current proxy configuration"
|
|
438
|
-
},
|
|
439
|
-
"http-proxy": {
|
|
440
|
-
type: "string",
|
|
441
|
-
description: "HTTP proxy URL (e.g., http://proxy:8080)"
|
|
442
|
-
},
|
|
443
|
-
"https-proxy": {
|
|
444
|
-
type: "string",
|
|
445
|
-
description: "HTTPS proxy URL (e.g., http://proxy:8080)"
|
|
446
|
-
},
|
|
447
|
-
"no-proxy": {
|
|
448
|
-
type: "string",
|
|
449
|
-
description: "Comma-separated list of hosts to bypass proxy"
|
|
450
|
-
}
|
|
451
|
-
},
|
|
452
|
-
async run({ args }) {
|
|
453
|
-
await ensurePaths();
|
|
454
|
-
if (args.show || !args.set && !args.enable && !args.disable && !args.clear && !args["http-proxy"] && !args["https-proxy"]) {
|
|
455
|
-
const config$1 = await getProxyConfig();
|
|
456
|
-
if (!config$1) {
|
|
457
|
-
consola.info("No proxy configuration saved.");
|
|
458
|
-
consola.info("");
|
|
459
|
-
consola.info("To configure proxy, use one of:");
|
|
460
|
-
consola.info(" copilot-api-plus proxy --set # Interactive setup");
|
|
461
|
-
consola.info(" copilot-api-plus proxy --http-proxy http://proxy:8080 # Direct set");
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
consola.info("Current proxy configuration:");
|
|
465
|
-
consola.info(` Status: ${config$1.enabled ? "✅ Enabled" : "❌ Disabled"}`);
|
|
466
|
-
if (config$1.httpProxy) consola.info(` HTTP_PROXY: ${config$1.httpProxy}`);
|
|
467
|
-
if (config$1.httpsProxy) consola.info(` HTTPS_PROXY: ${config$1.httpsProxy}`);
|
|
468
|
-
if (config$1.noProxy) consola.info(` NO_PROXY: ${config$1.noProxy}`);
|
|
469
|
-
return;
|
|
250
|
+
function _configVault(options$1) {
|
|
251
|
+
const debug$1 = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options$1 && options$1.debug);
|
|
252
|
+
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options$1 && options$1.quiet);
|
|
253
|
+
if (debug$1 || !quiet) _log("Loading env from encrypted .env.vault");
|
|
254
|
+
const parsed = DotenvModule._parseVault(options$1);
|
|
255
|
+
let processEnv = process.env;
|
|
256
|
+
if (options$1 && options$1.processEnv != null) processEnv = options$1.processEnv;
|
|
257
|
+
DotenvModule.populate(processEnv, parsed, options$1);
|
|
258
|
+
return { parsed };
|
|
259
|
+
}
|
|
260
|
+
function configDotenv(options$1) {
|
|
261
|
+
const dotenvPath = path$1.resolve(process.cwd(), ".env");
|
|
262
|
+
let encoding = "utf8";
|
|
263
|
+
let processEnv = process.env;
|
|
264
|
+
if (options$1 && options$1.processEnv != null) processEnv = options$1.processEnv;
|
|
265
|
+
let debug$1 = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options$1 && options$1.debug);
|
|
266
|
+
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options$1 && options$1.quiet);
|
|
267
|
+
if (options$1 && options$1.encoding) encoding = options$1.encoding;
|
|
268
|
+
else if (debug$1) _debug("No encoding is specified. UTF-8 is used by default");
|
|
269
|
+
let optionPaths = [dotenvPath];
|
|
270
|
+
if (options$1 && options$1.path) if (!Array.isArray(options$1.path)) optionPaths = [_resolveHome(options$1.path)];
|
|
271
|
+
else {
|
|
272
|
+
optionPaths = [];
|
|
273
|
+
for (const filepath of options$1.path) optionPaths.push(_resolveHome(filepath));
|
|
470
274
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
275
|
+
let lastError;
|
|
276
|
+
const parsedAll = {};
|
|
277
|
+
for (const path$2 of optionPaths) try {
|
|
278
|
+
const parsed = DotenvModule.parse(fs$1.readFileSync(path$2, { encoding }));
|
|
279
|
+
DotenvModule.populate(parsedAll, parsed, options$1);
|
|
280
|
+
} catch (e) {
|
|
281
|
+
if (debug$1) _debug(`Failed to load ${path$2} ${e.message}`);
|
|
282
|
+
lastError = e;
|
|
475
283
|
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
284
|
+
const populated = DotenvModule.populate(processEnv, parsedAll, options$1);
|
|
285
|
+
debug$1 = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug$1);
|
|
286
|
+
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
287
|
+
if (debug$1 || !quiet) {
|
|
288
|
+
const keysCount = Object.keys(populated).length;
|
|
289
|
+
const shortPaths = [];
|
|
290
|
+
for (const filePath of optionPaths) try {
|
|
291
|
+
const relative = path$1.relative(process.cwd(), filePath);
|
|
292
|
+
shortPaths.push(relative);
|
|
293
|
+
} catch (e) {
|
|
294
|
+
if (debug$1) _debug(`Failed to load ${filePath} ${e.message}`);
|
|
295
|
+
lastError = e;
|
|
481
296
|
}
|
|
482
|
-
|
|
483
|
-
await saveProxyConfig(config$1);
|
|
484
|
-
consola.success("Proxy enabled. It will be used on next server start.");
|
|
485
|
-
return;
|
|
297
|
+
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
486
298
|
}
|
|
487
|
-
if (
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
299
|
+
if (lastError) return {
|
|
300
|
+
parsed: parsedAll,
|
|
301
|
+
error: lastError
|
|
302
|
+
};
|
|
303
|
+
else return { parsed: parsedAll };
|
|
304
|
+
}
|
|
305
|
+
function config(options$1) {
|
|
306
|
+
if (_dotenvKey(options$1).length === 0) return DotenvModule.configDotenv(options$1);
|
|
307
|
+
const vaultPath = _vaultPath(options$1);
|
|
308
|
+
if (!vaultPath) {
|
|
309
|
+
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
310
|
+
return DotenvModule.configDotenv(options$1);
|
|
497
311
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
312
|
+
return DotenvModule._configVault(options$1);
|
|
313
|
+
}
|
|
314
|
+
function decrypt(encrypted, keyStr) {
|
|
315
|
+
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
316
|
+
let ciphertext = Buffer.from(encrypted, "base64");
|
|
317
|
+
const nonce = ciphertext.subarray(0, 12);
|
|
318
|
+
const authTag = ciphertext.subarray(-16);
|
|
319
|
+
ciphertext = ciphertext.subarray(12, -16);
|
|
320
|
+
try {
|
|
321
|
+
const aesgcm = crypto$1.createDecipheriv("aes-256-gcm", key, nonce);
|
|
322
|
+
aesgcm.setAuthTag(authTag);
|
|
323
|
+
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
324
|
+
} catch (error) {
|
|
325
|
+
const isRange = error instanceof RangeError;
|
|
326
|
+
const invalidKeyLength = error.message === "Invalid key length";
|
|
327
|
+
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
328
|
+
if (isRange || invalidKeyLength) {
|
|
329
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
330
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
331
|
+
throw err;
|
|
332
|
+
} else if (decryptionFailed) {
|
|
333
|
+
const err = /* @__PURE__ */ new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
334
|
+
err.code = "DECRYPTION_FAILED";
|
|
335
|
+
throw err;
|
|
336
|
+
} else throw error;
|
|
511
337
|
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
338
|
+
}
|
|
339
|
+
function populate(processEnv, parsed, options$1 = {}) {
|
|
340
|
+
const debug$1 = Boolean(options$1 && options$1.debug);
|
|
341
|
+
const override = Boolean(options$1 && options$1.override);
|
|
342
|
+
const populated = {};
|
|
343
|
+
if (typeof parsed !== "object") {
|
|
344
|
+
const err = /* @__PURE__ */ new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
345
|
+
err.code = "OBJECT_REQUIRED";
|
|
346
|
+
throw err;
|
|
347
|
+
}
|
|
348
|
+
for (const key of Object.keys(parsed)) if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
349
|
+
if (override === true) {
|
|
350
|
+
processEnv[key] = parsed[key];
|
|
351
|
+
populated[key] = parsed[key];
|
|
523
352
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
if (p.isCancel(httpsProxy)) {
|
|
530
|
-
p.cancel("Configuration cancelled.");
|
|
531
|
-
return;
|
|
532
|
-
}
|
|
533
|
-
const noProxy = await p.text({
|
|
534
|
-
message: "No Proxy (comma-separated hosts to bypass)",
|
|
535
|
-
placeholder: "localhost,127.0.0.1,.local",
|
|
536
|
-
initialValue: existingConfig?.noProxy || ""
|
|
537
|
-
});
|
|
538
|
-
if (p.isCancel(noProxy)) {
|
|
539
|
-
p.cancel("Configuration cancelled.");
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
const enable = await p.confirm({
|
|
543
|
-
message: "Enable proxy now?",
|
|
544
|
-
initialValue: true
|
|
545
|
-
});
|
|
546
|
-
if (p.isCancel(enable)) {
|
|
547
|
-
p.cancel("Configuration cancelled.");
|
|
548
|
-
return;
|
|
549
|
-
}
|
|
550
|
-
await saveProxyConfig({
|
|
551
|
-
enabled: enable,
|
|
552
|
-
httpProxy: httpProxy || void 0,
|
|
553
|
-
httpsProxy: httpsProxy || httpProxy || void 0,
|
|
554
|
-
noProxy: noProxy || void 0
|
|
555
|
-
});
|
|
556
|
-
p.outro(`Proxy configuration saved${enable ? " and enabled" : ""}.`);
|
|
353
|
+
if (debug$1) if (override === true) _debug(`"${key}" is already defined and WAS overwritten`);
|
|
354
|
+
else _debug(`"${key}" is already defined and was NOT overwritten`);
|
|
355
|
+
} else {
|
|
356
|
+
processEnv[key] = parsed[key];
|
|
357
|
+
populated[key] = parsed[key];
|
|
557
358
|
}
|
|
359
|
+
return populated;
|
|
558
360
|
}
|
|
559
|
-
|
|
361
|
+
const DotenvModule = {
|
|
362
|
+
configDotenv,
|
|
363
|
+
_configVault,
|
|
364
|
+
_parseVault,
|
|
365
|
+
config,
|
|
366
|
+
decrypt,
|
|
367
|
+
parse,
|
|
368
|
+
populate
|
|
369
|
+
};
|
|
370
|
+
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
371
|
+
module.exports._configVault = DotenvModule._configVault;
|
|
372
|
+
module.exports._parseVault = DotenvModule._parseVault;
|
|
373
|
+
module.exports.config = DotenvModule.config;
|
|
374
|
+
module.exports.decrypt = DotenvModule.decrypt;
|
|
375
|
+
module.exports.parse = DotenvModule.parse;
|
|
376
|
+
module.exports.populate = DotenvModule.populate;
|
|
377
|
+
module.exports = DotenvModule;
|
|
378
|
+
}) });
|
|
560
379
|
|
|
561
380
|
//#endregion
|
|
562
|
-
//#region node_modules/dotenv/
|
|
563
|
-
var
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
},
|
|
584
|
-
"
|
|
585
|
-
|
|
586
|
-
"lint": "standard",
|
|
587
|
-
"pretest": "npm run lint && npm run dts-check",
|
|
588
|
-
"test": "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
589
|
-
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
590
|
-
"prerelease": "npm test",
|
|
591
|
-
"release": "standard-version"
|
|
592
|
-
},
|
|
593
|
-
"repository": {
|
|
594
|
-
"type": "git",
|
|
595
|
-
"url": "git://github.com/motdotla/dotenv.git"
|
|
596
|
-
},
|
|
597
|
-
"homepage": "https://github.com/motdotla/dotenv#readme",
|
|
598
|
-
"funding": "https://dotenvx.com",
|
|
599
|
-
"keywords": [
|
|
600
|
-
"dotenv",
|
|
601
|
-
"env",
|
|
602
|
-
".env",
|
|
603
|
-
"environment",
|
|
604
|
-
"variables",
|
|
605
|
-
"config",
|
|
606
|
-
"settings"
|
|
607
|
-
],
|
|
608
|
-
"readmeFilename": "README.md",
|
|
609
|
-
"license": "BSD-2-Clause",
|
|
610
|
-
"devDependencies": {
|
|
611
|
-
"@types/node": "^18.11.3",
|
|
612
|
-
"decache": "^4.6.2",
|
|
613
|
-
"sinon": "^14.0.1",
|
|
614
|
-
"standard": "^17.0.0",
|
|
615
|
-
"standard-version": "^9.5.0",
|
|
616
|
-
"tap": "^19.2.0",
|
|
617
|
-
"typescript": "^4.8.4"
|
|
618
|
-
},
|
|
619
|
-
"engines": { "node": ">=12" },
|
|
620
|
-
"browser": { "fs": false }
|
|
381
|
+
//#region node_modules/dotenv/lib/env-options.js
|
|
382
|
+
var require_env_options = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/env-options.js": ((exports, module) => {
|
|
383
|
+
const options = {};
|
|
384
|
+
if (process.env.DOTENV_CONFIG_ENCODING != null) options.encoding = process.env.DOTENV_CONFIG_ENCODING;
|
|
385
|
+
if (process.env.DOTENV_CONFIG_PATH != null) options.path = process.env.DOTENV_CONFIG_PATH;
|
|
386
|
+
if (process.env.DOTENV_CONFIG_QUIET != null) options.quiet = process.env.DOTENV_CONFIG_QUIET;
|
|
387
|
+
if (process.env.DOTENV_CONFIG_DEBUG != null) options.debug = process.env.DOTENV_CONFIG_DEBUG;
|
|
388
|
+
if (process.env.DOTENV_CONFIG_OVERRIDE != null) options.override = process.env.DOTENV_CONFIG_OVERRIDE;
|
|
389
|
+
if (process.env.DOTENV_CONFIG_DOTENV_KEY != null) options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY;
|
|
390
|
+
module.exports = options;
|
|
391
|
+
}) });
|
|
392
|
+
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region node_modules/dotenv/lib/cli-options.js
|
|
395
|
+
var require_cli_options = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/cli-options.js": ((exports, module) => {
|
|
396
|
+
const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/;
|
|
397
|
+
module.exports = function optionMatcher(args) {
|
|
398
|
+
const options$1 = args.reduce(function(acc, cur) {
|
|
399
|
+
const matches = cur.match(re);
|
|
400
|
+
if (matches) acc[matches[1]] = matches[2];
|
|
401
|
+
return acc;
|
|
402
|
+
}, {});
|
|
403
|
+
if (!("quiet" in options$1)) options$1.quiet = "true";
|
|
404
|
+
return options$1;
|
|
621
405
|
};
|
|
622
406
|
}) });
|
|
623
407
|
|
|
624
408
|
//#endregion
|
|
625
|
-
//#region node_modules/dotenv/
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
];
|
|
650
|
-
function _getRandomTip() {
|
|
651
|
-
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
409
|
+
//#region node_modules/dotenv/config.js
|
|
410
|
+
(function() {
|
|
411
|
+
require_main().config(Object.assign({}, require_env_options(), require_cli_options()(process.argv)));
|
|
412
|
+
})();
|
|
413
|
+
|
|
414
|
+
//#endregion
|
|
415
|
+
//#region src/lib/config.ts
|
|
416
|
+
const CONFIG_FILENAME = "config.json";
|
|
417
|
+
/**
|
|
418
|
+
* Get the path to the config file
|
|
419
|
+
*/
|
|
420
|
+
function getConfigPath() {
|
|
421
|
+
return path.join(PATHS.DATA_DIR, CONFIG_FILENAME);
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Load configuration from file
|
|
425
|
+
*/
|
|
426
|
+
async function loadConfig() {
|
|
427
|
+
try {
|
|
428
|
+
const configPath = getConfigPath();
|
|
429
|
+
const content = await fs.readFile(configPath);
|
|
430
|
+
return JSON.parse(content);
|
|
431
|
+
} catch {
|
|
432
|
+
return {};
|
|
652
433
|
}
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Save configuration to file
|
|
437
|
+
*/
|
|
438
|
+
async function saveConfig(config$1) {
|
|
439
|
+
const configPath = getConfigPath();
|
|
440
|
+
await fs.writeFile(configPath, JSON.stringify(config$1, null, 2), "utf8");
|
|
441
|
+
consola.debug(`Configuration saved to ${configPath}`);
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Get proxy configuration
|
|
445
|
+
*/
|
|
446
|
+
async function getProxyConfig() {
|
|
447
|
+
return (await loadConfig()).proxy;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Save proxy configuration
|
|
451
|
+
*/
|
|
452
|
+
async function saveProxyConfig(proxyConfig) {
|
|
453
|
+
const config$1 = await loadConfig();
|
|
454
|
+
config$1.proxy = proxyConfig;
|
|
455
|
+
await saveConfig(config$1);
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Clear proxy configuration
|
|
459
|
+
*/
|
|
460
|
+
async function clearProxyConfig() {
|
|
461
|
+
const config$1 = await loadConfig();
|
|
462
|
+
delete config$1.proxy;
|
|
463
|
+
await saveConfig(config$1);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Apply saved proxy configuration to environment variables
|
|
467
|
+
* This should be called at startup to restore proxy settings
|
|
468
|
+
*/
|
|
469
|
+
async function applyProxyConfig() {
|
|
470
|
+
const proxyConfig = await getProxyConfig();
|
|
471
|
+
if (!proxyConfig || !proxyConfig.enabled) return false;
|
|
472
|
+
if (proxyConfig.httpProxy) {
|
|
473
|
+
process.env.HTTP_PROXY = proxyConfig.httpProxy;
|
|
474
|
+
process.env.http_proxy = proxyConfig.httpProxy;
|
|
662
475
|
}
|
|
663
|
-
|
|
664
|
-
|
|
476
|
+
if (proxyConfig.httpsProxy) {
|
|
477
|
+
process.env.HTTPS_PROXY = proxyConfig.httpsProxy;
|
|
478
|
+
process.env.https_proxy = proxyConfig.httpsProxy;
|
|
665
479
|
}
|
|
666
|
-
|
|
667
|
-
|
|
480
|
+
if (proxyConfig.noProxy) {
|
|
481
|
+
process.env.NO_PROXY = proxyConfig.noProxy;
|
|
482
|
+
process.env.no_proxy = proxyConfig.noProxy;
|
|
668
483
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
484
|
+
consola.info("Proxy configuration loaded from saved settings");
|
|
485
|
+
if (proxyConfig.httpProxy) consola.info(` HTTP_PROXY: ${proxyConfig.httpProxy}`);
|
|
486
|
+
if (proxyConfig.httpsProxy) consola.info(` HTTPS_PROXY: ${proxyConfig.httpsProxy}`);
|
|
487
|
+
if (proxyConfig.noProxy) consola.info(` NO_PROXY: ${proxyConfig.noProxy}`);
|
|
488
|
+
return true;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/lib/proxy.ts
|
|
493
|
+
function initProxyFromEnv() {
|
|
494
|
+
if (typeof Bun !== "undefined") return;
|
|
495
|
+
try {
|
|
496
|
+
const direct = new Agent();
|
|
497
|
+
const proxies = /* @__PURE__ */ new Map();
|
|
498
|
+
setGlobalDispatcher({
|
|
499
|
+
dispatch(options$1, handler) {
|
|
500
|
+
try {
|
|
501
|
+
const origin = typeof options$1.origin === "string" ? new URL(options$1.origin) : options$1.origin;
|
|
502
|
+
const raw = getProxyForUrl(origin.toString());
|
|
503
|
+
const proxyUrl = raw && raw.length > 0 ? raw : void 0;
|
|
504
|
+
if (!proxyUrl) {
|
|
505
|
+
consola.debug(`HTTP proxy bypass: ${origin.hostname}`);
|
|
506
|
+
return direct.dispatch(options$1, handler);
|
|
507
|
+
}
|
|
508
|
+
let agent = proxies.get(proxyUrl);
|
|
509
|
+
if (!agent) {
|
|
510
|
+
agent = new ProxyAgent(proxyUrl);
|
|
511
|
+
proxies.set(proxyUrl, agent);
|
|
512
|
+
}
|
|
513
|
+
let label = proxyUrl;
|
|
514
|
+
try {
|
|
515
|
+
const u = new URL(proxyUrl);
|
|
516
|
+
label = `${u.protocol}//${u.host}`;
|
|
517
|
+
} catch {}
|
|
518
|
+
consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`);
|
|
519
|
+
return agent.dispatch(options$1, handler);
|
|
520
|
+
} catch {
|
|
521
|
+
return direct.dispatch(options$1, handler);
|
|
522
|
+
}
|
|
523
|
+
},
|
|
524
|
+
close() {
|
|
525
|
+
return direct.close();
|
|
526
|
+
},
|
|
527
|
+
destroy() {
|
|
528
|
+
return direct.destroy();
|
|
684
529
|
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
530
|
+
});
|
|
531
|
+
consola.debug("HTTP proxy configured from environment (per-URL)");
|
|
532
|
+
} catch (err) {
|
|
533
|
+
consola.debug("Proxy setup skipped:", err);
|
|
688
534
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
for (let i = 0; i < length; i++) try {
|
|
703
|
-
const key = keys[i].trim();
|
|
704
|
-
const attrs = _instructions(result, key);
|
|
705
|
-
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
706
|
-
break;
|
|
707
|
-
} catch (error) {
|
|
708
|
-
if (i + 1 >= length) throw error;
|
|
709
|
-
}
|
|
710
|
-
return DotenvModule.parse(decrypted);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
//#endregion
|
|
538
|
+
//#region src/antigravity.ts
|
|
539
|
+
/**
|
|
540
|
+
* Add a new Antigravity account via OAuth
|
|
541
|
+
*/
|
|
542
|
+
async function addAccount() {
|
|
543
|
+
const { setupAntigravity, loadAntigravityAuth } = await import("./auth-B2lTFLSD.js");
|
|
544
|
+
const existingAuth = await loadAntigravityAuth();
|
|
545
|
+
if (existingAuth && existingAuth.accounts.length > 0) {
|
|
546
|
+
const enabledCount = existingAuth.accounts.filter((a) => a.enable).length;
|
|
547
|
+
consola.info(`Found ${existingAuth.accounts.length} existing accounts (${enabledCount} enabled)`);
|
|
711
548
|
}
|
|
712
|
-
|
|
713
|
-
|
|
549
|
+
await setupAntigravity();
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* List all Antigravity accounts
|
|
553
|
+
*/
|
|
554
|
+
async function listAccounts() {
|
|
555
|
+
const { loadAntigravityAuth } = await import("./auth-B2lTFLSD.js");
|
|
556
|
+
const auth$1 = await loadAntigravityAuth();
|
|
557
|
+
if (!auth$1 || auth$1.accounts.length === 0) {
|
|
558
|
+
consola.info("No Antigravity accounts configured");
|
|
559
|
+
return;
|
|
714
560
|
}
|
|
715
|
-
|
|
716
|
-
|
|
561
|
+
consola.info(`\nAntigravity Accounts (${auth$1.accounts.length} total):`);
|
|
562
|
+
consola.info("=".repeat(50));
|
|
563
|
+
for (let i = 0; i < auth$1.accounts.length; i++) {
|
|
564
|
+
const account = auth$1.accounts[i];
|
|
565
|
+
const isCurrent = i === auth$1.currentIndex;
|
|
566
|
+
const status = account.enable ? "enabled" : "disabled";
|
|
567
|
+
const marker = isCurrent ? "→ " : " ";
|
|
568
|
+
const projectId = account.project_id || "unknown";
|
|
569
|
+
consola.info(`${marker}[${i}] Project: ${projectId} | Status: ${status}${isCurrent ? " (current)" : ""}`);
|
|
717
570
|
}
|
|
718
|
-
|
|
719
|
-
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Remove an Antigravity account by index
|
|
574
|
+
*/
|
|
575
|
+
async function removeAccount(index) {
|
|
576
|
+
const { loadAntigravityAuth, saveAntigravityAuth } = await import("./auth-B2lTFLSD.js");
|
|
577
|
+
const auth$1 = await loadAntigravityAuth();
|
|
578
|
+
if (!auth$1 || auth$1.accounts.length === 0) {
|
|
579
|
+
consola.error("No Antigravity accounts configured");
|
|
580
|
+
return;
|
|
720
581
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
return "";
|
|
582
|
+
if (index < 0 || index >= auth$1.accounts.length) {
|
|
583
|
+
consola.error(`Invalid index. Must be between 0 and ${auth$1.accounts.length - 1}`);
|
|
584
|
+
return;
|
|
725
585
|
}
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
586
|
+
const removed = auth$1.accounts.splice(index, 1)[0];
|
|
587
|
+
if (auth$1.currentIndex >= auth$1.accounts.length) auth$1.currentIndex = Math.max(0, auth$1.accounts.length - 1);
|
|
588
|
+
await saveAntigravityAuth(auth$1);
|
|
589
|
+
consola.success(`Removed account ${index} (Project: ${removed.project_id || "unknown"})`);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Clear all Antigravity accounts
|
|
593
|
+
*/
|
|
594
|
+
async function clearAccounts() {
|
|
595
|
+
const { clearAntigravityAuth: clearAntigravityAuth$1 } = await import("./auth-B2lTFLSD.js");
|
|
596
|
+
if (await consola.prompt("Are you sure you want to remove all Antigravity accounts?", {
|
|
597
|
+
type: "confirm",
|
|
598
|
+
initial: false
|
|
599
|
+
})) await clearAntigravityAuth$1();
|
|
600
|
+
}
|
|
601
|
+
const antigravity = defineCommand({
|
|
602
|
+
meta: {
|
|
603
|
+
name: "antigravity",
|
|
604
|
+
description: "Manage Google Antigravity accounts"
|
|
605
|
+
},
|
|
606
|
+
subCommands: {
|
|
607
|
+
add: defineCommand({
|
|
608
|
+
meta: {
|
|
609
|
+
name: "add",
|
|
610
|
+
description: "Add a new Antigravity account via OAuth"
|
|
611
|
+
},
|
|
612
|
+
async run() {
|
|
613
|
+
await ensurePaths();
|
|
614
|
+
if (await applyProxyConfig()) initProxyFromEnv();
|
|
615
|
+
await addAccount();
|
|
735
616
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
617
|
+
}),
|
|
618
|
+
list: defineCommand({
|
|
619
|
+
meta: {
|
|
620
|
+
name: "list",
|
|
621
|
+
description: "List all Antigravity accounts"
|
|
622
|
+
},
|
|
623
|
+
async run() {
|
|
624
|
+
await ensurePaths();
|
|
625
|
+
await listAccounts();
|
|
626
|
+
}
|
|
627
|
+
}),
|
|
628
|
+
remove: defineCommand({
|
|
629
|
+
meta: {
|
|
630
|
+
name: "remove",
|
|
631
|
+
description: "Remove an Antigravity account by index"
|
|
632
|
+
},
|
|
633
|
+
args: { index: {
|
|
634
|
+
type: "positional",
|
|
635
|
+
description: "Account index to remove (use 'list' to see indexes)",
|
|
636
|
+
required: true
|
|
637
|
+
} },
|
|
638
|
+
async run({ args }) {
|
|
639
|
+
await ensurePaths();
|
|
640
|
+
const indexStr = String(args.index);
|
|
641
|
+
const index = Number.parseInt(indexStr, 10);
|
|
642
|
+
if (Number.isNaN(index)) {
|
|
643
|
+
consola.error("Index must be a number");
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
await removeAccount(index);
|
|
647
|
+
}
|
|
648
|
+
}),
|
|
649
|
+
clear: defineCommand({
|
|
650
|
+
meta: {
|
|
651
|
+
name: "clear",
|
|
652
|
+
description: "Remove all Antigravity accounts"
|
|
653
|
+
},
|
|
654
|
+
async run() {
|
|
655
|
+
await ensurePaths();
|
|
656
|
+
await clearAccounts();
|
|
657
|
+
}
|
|
658
|
+
})
|
|
761
659
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
//#endregion
|
|
663
|
+
//#region src/auth.ts
|
|
664
|
+
async function runAuth(options$1) {
|
|
665
|
+
if (options$1.verbose) {
|
|
666
|
+
consola.level = 5;
|
|
667
|
+
consola.info("Verbose logging enabled");
|
|
770
668
|
}
|
|
771
|
-
|
|
772
|
-
|
|
669
|
+
state.showToken = options$1.showToken;
|
|
670
|
+
await ensurePaths();
|
|
671
|
+
await setupGitHubToken({ force: true });
|
|
672
|
+
consola.success("GitHub token written to", PATHS.GITHUB_TOKEN_PATH);
|
|
673
|
+
}
|
|
674
|
+
const auth = defineCommand({
|
|
675
|
+
meta: {
|
|
676
|
+
name: "auth",
|
|
677
|
+
description: "Run GitHub auth flow without running the server"
|
|
678
|
+
},
|
|
679
|
+
args: {
|
|
680
|
+
verbose: {
|
|
681
|
+
alias: "v",
|
|
682
|
+
type: "boolean",
|
|
683
|
+
default: false,
|
|
684
|
+
description: "Enable verbose logging"
|
|
685
|
+
},
|
|
686
|
+
"show-token": {
|
|
687
|
+
type: "boolean",
|
|
688
|
+
default: false,
|
|
689
|
+
description: "Show GitHub token on auth"
|
|
690
|
+
}
|
|
691
|
+
},
|
|
692
|
+
run({ args }) {
|
|
693
|
+
return runAuth({
|
|
694
|
+
verbose: args.verbose,
|
|
695
|
+
showToken: args["show-token"]
|
|
696
|
+
});
|
|
773
697
|
}
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
//#endregion
|
|
701
|
+
//#region src/services/github/get-copilot-usage.ts
|
|
702
|
+
const getCopilotUsage = async () => {
|
|
703
|
+
const response = await fetch(`${GITHUB_API_BASE_URL}/copilot_internal/user`, { headers: githubHeaders(state) });
|
|
704
|
+
if (!response.ok) throw new HTTPError("Failed to get Copilot usage", response);
|
|
705
|
+
return await response.json();
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
//#endregion
|
|
709
|
+
//#region src/check-usage.ts
|
|
710
|
+
const checkUsage = defineCommand({
|
|
711
|
+
meta: {
|
|
712
|
+
name: "check-usage",
|
|
713
|
+
description: "Show current GitHub Copilot usage/quota information"
|
|
714
|
+
},
|
|
715
|
+
async run() {
|
|
716
|
+
await ensurePaths();
|
|
717
|
+
await setupGitHubToken();
|
|
718
|
+
try {
|
|
719
|
+
const usage = await getCopilotUsage();
|
|
720
|
+
const premium = usage.quota_snapshots.premium_interactions;
|
|
721
|
+
const premiumTotal = premium.entitlement;
|
|
722
|
+
const premiumUsed = premiumTotal - premium.remaining;
|
|
723
|
+
const premiumPercentUsed = premiumTotal > 0 ? premiumUsed / premiumTotal * 100 : 0;
|
|
724
|
+
const premiumPercentRemaining = premium.percent_remaining;
|
|
725
|
+
function summarizeQuota(name, snap) {
|
|
726
|
+
if (!snap) return `${name}: N/A`;
|
|
727
|
+
const total = snap.entitlement;
|
|
728
|
+
const used = total - snap.remaining;
|
|
729
|
+
const percentUsed = total > 0 ? used / total * 100 : 0;
|
|
730
|
+
const percentRemaining = snap.percent_remaining;
|
|
731
|
+
return `${name}: ${used}/${total} used (${percentUsed.toFixed(1)}% used, ${percentRemaining.toFixed(1)}% remaining)`;
|
|
732
|
+
}
|
|
733
|
+
const premiumLine = `Premium: ${premiumUsed}/${premiumTotal} used (${premiumPercentUsed.toFixed(1)}% used, ${premiumPercentRemaining.toFixed(1)}% remaining)`;
|
|
734
|
+
const chatLine = summarizeQuota("Chat", usage.quota_snapshots.chat);
|
|
735
|
+
const completionsLine = summarizeQuota("Completions", usage.quota_snapshots.completions);
|
|
736
|
+
consola.box(`Copilot Usage (plan: ${usage.copilot_plan})\nQuota resets: ${usage.quota_reset_date}\n\nQuotas:\n ${premiumLine}\n ${chatLine}\n ${completionsLine}`);
|
|
737
|
+
} catch (err) {
|
|
738
|
+
consola.error("Failed to fetch Copilot usage:", err);
|
|
739
|
+
process.exit(1);
|
|
740
|
+
}
|
|
783
741
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
//#endregion
|
|
745
|
+
//#region src/debug.ts
|
|
746
|
+
async function getPackageVersion() {
|
|
747
|
+
try {
|
|
748
|
+
const packageJsonPath = new URL("../package.json", import.meta.url).pathname;
|
|
749
|
+
return JSON.parse(await fs.readFile(packageJsonPath)).version;
|
|
750
|
+
} catch {
|
|
751
|
+
return "unknown";
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function getRuntimeInfo() {
|
|
755
|
+
const isBun = typeof Bun !== "undefined";
|
|
756
|
+
return {
|
|
757
|
+
name: isBun ? "bun" : "node",
|
|
758
|
+
version: isBun ? Bun.version : process.version.slice(1),
|
|
759
|
+
platform: os.platform(),
|
|
760
|
+
arch: os.arch()
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
async function checkTokenExists() {
|
|
764
|
+
try {
|
|
765
|
+
if (!(await fs.stat(PATHS.GITHUB_TOKEN_PATH)).isFile()) return false;
|
|
766
|
+
return (await fs.readFile(PATHS.GITHUB_TOKEN_PATH, "utf8")).trim().length > 0;
|
|
767
|
+
} catch {
|
|
768
|
+
return false;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
async function checkFileExists(path$2) {
|
|
772
|
+
try {
|
|
773
|
+
if (!(await fs.stat(path$2)).isFile()) return false;
|
|
774
|
+
return (await fs.readFile(path$2, "utf8")).trim().length > 0;
|
|
775
|
+
} catch {
|
|
776
|
+
return false;
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
async function getDebugInfo() {
|
|
780
|
+
const zenAuthPath = getZenAuthPath();
|
|
781
|
+
const antigravityAuthPath = getAntigravityAuthPath();
|
|
782
|
+
const [version$1, githubExists, zenExists, antigravityExists, proxyConfig] = await Promise.all([
|
|
783
|
+
getPackageVersion(),
|
|
784
|
+
checkTokenExists(),
|
|
785
|
+
checkFileExists(zenAuthPath),
|
|
786
|
+
checkFileExists(antigravityAuthPath),
|
|
787
|
+
getProxyConfig()
|
|
788
|
+
]);
|
|
789
|
+
return {
|
|
790
|
+
version: version$1,
|
|
791
|
+
runtime: getRuntimeInfo(),
|
|
792
|
+
paths: {
|
|
793
|
+
APP_DIR: PATHS.APP_DIR,
|
|
794
|
+
GITHUB_TOKEN_PATH: PATHS.GITHUB_TOKEN_PATH,
|
|
795
|
+
ZEN_AUTH_PATH: zenAuthPath,
|
|
796
|
+
ANTIGRAVITY_AUTH_PATH: antigravityAuthPath
|
|
797
|
+
},
|
|
798
|
+
credentials: {
|
|
799
|
+
github: githubExists,
|
|
800
|
+
zen: zenExists,
|
|
801
|
+
antigravity: antigravityExists
|
|
802
|
+
},
|
|
803
|
+
proxy: proxyConfig
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
function printDebugInfoPlain(info) {
|
|
807
|
+
let proxyStatus = "Not configured";
|
|
808
|
+
if (info.proxy) proxyStatus = info.proxy.enabled ? `Enabled (${info.proxy.httpProxy || info.proxy.httpsProxy})` : "Disabled";
|
|
809
|
+
consola.info(`copilot-api-plus debug
|
|
810
|
+
|
|
811
|
+
Version: ${info.version}
|
|
812
|
+
Runtime: ${info.runtime.name} ${info.runtime.version} (${info.runtime.platform} ${info.runtime.arch})
|
|
813
|
+
|
|
814
|
+
Paths:
|
|
815
|
+
APP_DIR: ${info.paths.APP_DIR}
|
|
816
|
+
GITHUB_TOKEN_PATH: ${info.paths.GITHUB_TOKEN_PATH}
|
|
817
|
+
ZEN_AUTH_PATH: ${info.paths.ZEN_AUTH_PATH}
|
|
818
|
+
ANTIGRAVITY_AUTH_PATH: ${info.paths.ANTIGRAVITY_AUTH_PATH}
|
|
819
|
+
|
|
820
|
+
Credentials:
|
|
821
|
+
GitHub Copilot: ${info.credentials.github ? "✅ Configured" : "❌ Not configured"}
|
|
822
|
+
OpenCode Zen: ${info.credentials.zen ? "✅ Configured" : "❌ Not configured"}
|
|
823
|
+
Google Antigravity: ${info.credentials.antigravity ? "✅ Configured" : "❌ Not configured"}
|
|
824
|
+
|
|
825
|
+
Proxy: ${proxyStatus}`);
|
|
826
|
+
}
|
|
827
|
+
function printDebugInfoJson(info) {
|
|
828
|
+
console.log(JSON.stringify(info, null, 2));
|
|
829
|
+
}
|
|
830
|
+
async function runDebug(options$1) {
|
|
831
|
+
const debugInfo = await getDebugInfo();
|
|
832
|
+
if (options$1.json) printDebugInfoJson(debugInfo);
|
|
833
|
+
else printDebugInfoPlain(debugInfo);
|
|
834
|
+
}
|
|
835
|
+
const debug = defineCommand({
|
|
836
|
+
meta: {
|
|
837
|
+
name: "debug",
|
|
838
|
+
description: "Print debug information about the application"
|
|
839
|
+
},
|
|
840
|
+
args: { json: {
|
|
841
|
+
type: "boolean",
|
|
842
|
+
default: false,
|
|
843
|
+
description: "Output debug information as JSON"
|
|
844
|
+
} },
|
|
845
|
+
run({ args }) {
|
|
846
|
+
return runDebug({ json: args.json });
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/logout.ts
|
|
852
|
+
async function runLogout(options$1) {
|
|
853
|
+
await ensurePaths();
|
|
854
|
+
if (options$1.all) {
|
|
855
|
+
await clearGithubToken();
|
|
856
|
+
await clearZenAuth();
|
|
857
|
+
await clearAntigravityAuth();
|
|
858
|
+
consola.success("Logged out from all services");
|
|
859
|
+
consola.info(`GitHub token: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
860
|
+
consola.info(`Zen API key: ${getZenAuthPath()}`);
|
|
861
|
+
consola.info(`Antigravity accounts: ${getAntigravityAuthPath()}`);
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
if (options$1.github) {
|
|
865
|
+
await clearGithubToken();
|
|
866
|
+
consola.success("Logged out from GitHub Copilot");
|
|
867
|
+
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
868
|
+
return;
|
|
869
|
+
}
|
|
870
|
+
if (options$1.zen) {
|
|
871
|
+
await clearZenAuth();
|
|
872
|
+
consola.success("Logged out from OpenCode Zen");
|
|
873
|
+
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
876
|
+
if (options$1.antigravity) {
|
|
877
|
+
await clearAntigravityAuth();
|
|
878
|
+
consola.success("Logged out from Google Antigravity");
|
|
879
|
+
consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
switch (await consola.prompt("Which credentials do you want to clear?", {
|
|
883
|
+
type: "select",
|
|
884
|
+
options: [
|
|
885
|
+
"GitHub Copilot token",
|
|
886
|
+
"OpenCode Zen API key",
|
|
887
|
+
"Google Antigravity accounts",
|
|
888
|
+
"All credentials"
|
|
889
|
+
]
|
|
890
|
+
})) {
|
|
891
|
+
case "GitHub Copilot token":
|
|
892
|
+
await clearGithubToken();
|
|
893
|
+
consola.success("Logged out from GitHub Copilot");
|
|
894
|
+
consola.info(`Token file location: ${PATHS.GITHUB_TOKEN_PATH}`);
|
|
895
|
+
break;
|
|
896
|
+
case "OpenCode Zen API key":
|
|
897
|
+
await clearZenAuth();
|
|
898
|
+
consola.success("Logged out from OpenCode Zen");
|
|
899
|
+
consola.info(`Zen API key location: ${getZenAuthPath()}`);
|
|
900
|
+
break;
|
|
901
|
+
case "Google Antigravity accounts":
|
|
902
|
+
await clearAntigravityAuth();
|
|
903
|
+
consola.success("Logged out from Google Antigravity");
|
|
904
|
+
consola.info(`Antigravity accounts location: ${getAntigravityAuthPath()}`);
|
|
905
|
+
break;
|
|
906
|
+
case "All credentials":
|
|
907
|
+
await clearGithubToken();
|
|
908
|
+
await clearZenAuth();
|
|
909
|
+
await clearAntigravityAuth();
|
|
910
|
+
consola.success("Logged out from all services");
|
|
911
|
+
break;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const logout = defineCommand({
|
|
915
|
+
meta: {
|
|
916
|
+
name: "logout",
|
|
917
|
+
description: "Clear stored credentials and logout"
|
|
918
|
+
},
|
|
919
|
+
args: {
|
|
920
|
+
github: {
|
|
921
|
+
alias: "g",
|
|
922
|
+
type: "boolean",
|
|
923
|
+
default: false,
|
|
924
|
+
description: "Clear only GitHub Copilot token"
|
|
925
|
+
},
|
|
926
|
+
zen: {
|
|
927
|
+
alias: "z",
|
|
928
|
+
type: "boolean",
|
|
929
|
+
default: false,
|
|
930
|
+
description: "Clear only OpenCode Zen API key"
|
|
931
|
+
},
|
|
932
|
+
antigravity: {
|
|
933
|
+
type: "boolean",
|
|
934
|
+
default: false,
|
|
935
|
+
description: "Clear only Google Antigravity accounts"
|
|
936
|
+
},
|
|
937
|
+
all: {
|
|
938
|
+
alias: "a",
|
|
939
|
+
type: "boolean",
|
|
940
|
+
default: false,
|
|
941
|
+
description: "Clear all credentials (GitHub, Zen, and Antigravity)"
|
|
807
942
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
943
|
+
},
|
|
944
|
+
run({ args }) {
|
|
945
|
+
return runLogout({
|
|
946
|
+
github: args.github,
|
|
947
|
+
zen: args.zen,
|
|
948
|
+
antigravity: args.antigravity,
|
|
949
|
+
all: args.all
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/proxy-config.ts
|
|
956
|
+
const proxy = defineCommand({
|
|
957
|
+
meta: {
|
|
958
|
+
name: "proxy",
|
|
959
|
+
description: "Configure proxy settings (persistent)"
|
|
960
|
+
},
|
|
961
|
+
args: {
|
|
962
|
+
set: {
|
|
963
|
+
type: "boolean",
|
|
964
|
+
default: false,
|
|
965
|
+
description: "Set proxy configuration interactively"
|
|
966
|
+
},
|
|
967
|
+
enable: {
|
|
968
|
+
type: "boolean",
|
|
969
|
+
default: false,
|
|
970
|
+
description: "Enable saved proxy configuration"
|
|
971
|
+
},
|
|
972
|
+
disable: {
|
|
973
|
+
type: "boolean",
|
|
974
|
+
default: false,
|
|
975
|
+
description: "Disable proxy (keep settings)"
|
|
976
|
+
},
|
|
977
|
+
clear: {
|
|
978
|
+
type: "boolean",
|
|
979
|
+
default: false,
|
|
980
|
+
description: "Clear all proxy settings"
|
|
981
|
+
},
|
|
982
|
+
show: {
|
|
983
|
+
type: "boolean",
|
|
984
|
+
default: false,
|
|
985
|
+
description: "Show current proxy configuration"
|
|
986
|
+
},
|
|
987
|
+
"http-proxy": {
|
|
988
|
+
type: "string",
|
|
989
|
+
description: "HTTP proxy URL (e.g., http://proxy:8080)"
|
|
990
|
+
},
|
|
991
|
+
"https-proxy": {
|
|
992
|
+
type: "string",
|
|
993
|
+
description: "HTTPS proxy URL (e.g., http://proxy:8080)"
|
|
994
|
+
},
|
|
995
|
+
"no-proxy": {
|
|
996
|
+
type: "string",
|
|
997
|
+
description: "Comma-separated list of hosts to bypass proxy"
|
|
822
998
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
999
|
+
},
|
|
1000
|
+
async run({ args }) {
|
|
1001
|
+
await ensurePaths();
|
|
1002
|
+
if (args.show || !args.set && !args.enable && !args.disable && !args.clear && !args["http-proxy"] && !args["https-proxy"]) {
|
|
1003
|
+
const config$1 = await getProxyConfig();
|
|
1004
|
+
if (!config$1) {
|
|
1005
|
+
consola.info("No proxy configuration saved.");
|
|
1006
|
+
consola.info("");
|
|
1007
|
+
consola.info("To configure proxy, use one of:");
|
|
1008
|
+
consola.info(" copilot-api-plus proxy --set # Interactive setup");
|
|
1009
|
+
consola.info(" copilot-api-plus proxy --http-proxy http://proxy:8080 # Direct set");
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
consola.info("Current proxy configuration:");
|
|
1013
|
+
consola.info(` Status: ${config$1.enabled ? "✅ Enabled" : "❌ Disabled"}`);
|
|
1014
|
+
if (config$1.httpProxy) consola.info(` HTTP_PROXY: ${config$1.httpProxy}`);
|
|
1015
|
+
if (config$1.httpsProxy) consola.info(` HTTPS_PROXY: ${config$1.httpsProxy}`);
|
|
1016
|
+
if (config$1.noProxy) consola.info(` NO_PROXY: ${config$1.noProxy}`);
|
|
1017
|
+
return;
|
|
835
1018
|
}
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
let ciphertext = Buffer.from(encrypted, "base64");
|
|
841
|
-
const nonce = ciphertext.subarray(0, 12);
|
|
842
|
-
const authTag = ciphertext.subarray(-16);
|
|
843
|
-
ciphertext = ciphertext.subarray(12, -16);
|
|
844
|
-
try {
|
|
845
|
-
const aesgcm = crypto$1.createDecipheriv("aes-256-gcm", key, nonce);
|
|
846
|
-
aesgcm.setAuthTag(authTag);
|
|
847
|
-
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
848
|
-
} catch (error) {
|
|
849
|
-
const isRange = error instanceof RangeError;
|
|
850
|
-
const invalidKeyLength = error.message === "Invalid key length";
|
|
851
|
-
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
852
|
-
if (isRange || invalidKeyLength) {
|
|
853
|
-
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
854
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
855
|
-
throw err;
|
|
856
|
-
} else if (decryptionFailed) {
|
|
857
|
-
const err = /* @__PURE__ */ new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
858
|
-
err.code = "DECRYPTION_FAILED";
|
|
859
|
-
throw err;
|
|
860
|
-
} else throw error;
|
|
1019
|
+
if (args.clear) {
|
|
1020
|
+
await clearProxyConfig();
|
|
1021
|
+
consola.success("Proxy configuration cleared.");
|
|
1022
|
+
return;
|
|
861
1023
|
}
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
1024
|
+
if (args.enable) {
|
|
1025
|
+
const config$1 = await getProxyConfig();
|
|
1026
|
+
if (!config$1) {
|
|
1027
|
+
consola.error("No proxy configuration saved. Use --set to configure first.");
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
config$1.enabled = true;
|
|
1031
|
+
await saveProxyConfig(config$1);
|
|
1032
|
+
consola.success("Proxy enabled. It will be used on next server start.");
|
|
1033
|
+
return;
|
|
871
1034
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
1035
|
+
if (args.disable) {
|
|
1036
|
+
const config$1 = await getProxyConfig();
|
|
1037
|
+
if (!config$1) {
|
|
1038
|
+
consola.info("No proxy configuration to disable.");
|
|
1039
|
+
return;
|
|
876
1040
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
populated[key] = parsed[key];
|
|
1041
|
+
config$1.enabled = false;
|
|
1042
|
+
await saveProxyConfig(config$1);
|
|
1043
|
+
consola.success("Proxy disabled. Settings are preserved.");
|
|
1044
|
+
return;
|
|
882
1045
|
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
if (process.env.DOTENV_CONFIG_ENCODING != null) options.encoding = process.env.DOTENV_CONFIG_ENCODING;
|
|
909
|
-
if (process.env.DOTENV_CONFIG_PATH != null) options.path = process.env.DOTENV_CONFIG_PATH;
|
|
910
|
-
if (process.env.DOTENV_CONFIG_QUIET != null) options.quiet = process.env.DOTENV_CONFIG_QUIET;
|
|
911
|
-
if (process.env.DOTENV_CONFIG_DEBUG != null) options.debug = process.env.DOTENV_CONFIG_DEBUG;
|
|
912
|
-
if (process.env.DOTENV_CONFIG_OVERRIDE != null) options.override = process.env.DOTENV_CONFIG_OVERRIDE;
|
|
913
|
-
if (process.env.DOTENV_CONFIG_DOTENV_KEY != null) options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY;
|
|
914
|
-
module.exports = options;
|
|
915
|
-
}) });
|
|
916
|
-
|
|
917
|
-
//#endregion
|
|
918
|
-
//#region node_modules/dotenv/lib/cli-options.js
|
|
919
|
-
var require_cli_options = /* @__PURE__ */ __commonJS({ "node_modules/dotenv/lib/cli-options.js": ((exports, module) => {
|
|
920
|
-
const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/;
|
|
921
|
-
module.exports = function optionMatcher(args) {
|
|
922
|
-
const options$1 = args.reduce(function(acc, cur) {
|
|
923
|
-
const matches = cur.match(re);
|
|
924
|
-
if (matches) acc[matches[1]] = matches[2];
|
|
925
|
-
return acc;
|
|
926
|
-
}, {});
|
|
927
|
-
if (!("quiet" in options$1)) options$1.quiet = "true";
|
|
928
|
-
return options$1;
|
|
929
|
-
};
|
|
930
|
-
}) });
|
|
931
|
-
|
|
932
|
-
//#endregion
|
|
933
|
-
//#region node_modules/dotenv/config.js
|
|
934
|
-
(function() {
|
|
935
|
-
require_main().config(Object.assign({}, require_env_options(), require_cli_options()(process.argv)));
|
|
936
|
-
})();
|
|
937
|
-
|
|
938
|
-
//#endregion
|
|
939
|
-
//#region src/lib/proxy.ts
|
|
940
|
-
function initProxyFromEnv() {
|
|
941
|
-
if (typeof Bun !== "undefined") return;
|
|
942
|
-
try {
|
|
943
|
-
const direct = new Agent();
|
|
944
|
-
const proxies = /* @__PURE__ */ new Map();
|
|
945
|
-
setGlobalDispatcher({
|
|
946
|
-
dispatch(options$1, handler) {
|
|
947
|
-
try {
|
|
948
|
-
const origin = typeof options$1.origin === "string" ? new URL(options$1.origin) : options$1.origin;
|
|
949
|
-
const raw = getProxyForUrl(origin.toString());
|
|
950
|
-
const proxyUrl = raw && raw.length > 0 ? raw : void 0;
|
|
951
|
-
if (!proxyUrl) {
|
|
952
|
-
consola.debug(`HTTP proxy bypass: ${origin.hostname}`);
|
|
953
|
-
return direct.dispatch(options$1, handler);
|
|
954
|
-
}
|
|
955
|
-
let agent = proxies.get(proxyUrl);
|
|
956
|
-
if (!agent) {
|
|
957
|
-
agent = new ProxyAgent(proxyUrl);
|
|
958
|
-
proxies.set(proxyUrl, agent);
|
|
959
|
-
}
|
|
960
|
-
let label = proxyUrl;
|
|
961
|
-
try {
|
|
962
|
-
const u = new URL(proxyUrl);
|
|
963
|
-
label = `${u.protocol}//${u.host}`;
|
|
964
|
-
} catch {}
|
|
965
|
-
consola.debug(`HTTP proxy route: ${origin.hostname} via ${label}`);
|
|
966
|
-
return agent.dispatch(options$1, handler);
|
|
967
|
-
} catch {
|
|
968
|
-
return direct.dispatch(options$1, handler);
|
|
969
|
-
}
|
|
970
|
-
},
|
|
971
|
-
close() {
|
|
972
|
-
return direct.close();
|
|
973
|
-
},
|
|
974
|
-
destroy() {
|
|
975
|
-
return direct.destroy();
|
|
1046
|
+
if (args["http-proxy"] || args["https-proxy"]) {
|
|
1047
|
+
const newConfig = {
|
|
1048
|
+
enabled: true,
|
|
1049
|
+
httpProxy: args["http-proxy"],
|
|
1050
|
+
httpsProxy: args["https-proxy"] || args["http-proxy"],
|
|
1051
|
+
noProxy: args["no-proxy"]
|
|
1052
|
+
};
|
|
1053
|
+
await saveProxyConfig(newConfig);
|
|
1054
|
+
consola.success("Proxy configuration saved and enabled.");
|
|
1055
|
+
consola.info(` HTTP_PROXY: ${newConfig.httpProxy || "(not set)"}`);
|
|
1056
|
+
consola.info(` HTTPS_PROXY: ${newConfig.httpsProxy || "(not set)"}`);
|
|
1057
|
+
if (newConfig.noProxy) consola.info(` NO_PROXY: ${newConfig.noProxy}`);
|
|
1058
|
+
return;
|
|
1059
|
+
}
|
|
1060
|
+
if (args.set) {
|
|
1061
|
+
p.intro("Proxy Configuration");
|
|
1062
|
+
const existingConfig = await getProxyConfig();
|
|
1063
|
+
const httpProxy = await p.text({
|
|
1064
|
+
message: "HTTP Proxy URL",
|
|
1065
|
+
placeholder: "http://proxy:8080",
|
|
1066
|
+
initialValue: existingConfig?.httpProxy || ""
|
|
1067
|
+
});
|
|
1068
|
+
if (p.isCancel(httpProxy)) {
|
|
1069
|
+
p.cancel("Configuration cancelled.");
|
|
1070
|
+
return;
|
|
976
1071
|
}
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1072
|
+
const httpsProxy = await p.text({
|
|
1073
|
+
message: "HTTPS Proxy URL (leave empty to use HTTP proxy)",
|
|
1074
|
+
placeholder: "http://proxy:8080",
|
|
1075
|
+
initialValue: existingConfig?.httpsProxy || ""
|
|
1076
|
+
});
|
|
1077
|
+
if (p.isCancel(httpsProxy)) {
|
|
1078
|
+
p.cancel("Configuration cancelled.");
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
const noProxy = await p.text({
|
|
1082
|
+
message: "No Proxy (comma-separated hosts to bypass)",
|
|
1083
|
+
placeholder: "localhost,127.0.0.1,.local",
|
|
1084
|
+
initialValue: existingConfig?.noProxy || ""
|
|
1085
|
+
});
|
|
1086
|
+
if (p.isCancel(noProxy)) {
|
|
1087
|
+
p.cancel("Configuration cancelled.");
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
const enable = await p.confirm({
|
|
1091
|
+
message: "Enable proxy now?",
|
|
1092
|
+
initialValue: true
|
|
1093
|
+
});
|
|
1094
|
+
if (p.isCancel(enable)) {
|
|
1095
|
+
p.cancel("Configuration cancelled.");
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
await saveProxyConfig({
|
|
1099
|
+
enabled: enable,
|
|
1100
|
+
httpProxy: httpProxy || void 0,
|
|
1101
|
+
httpsProxy: httpsProxy || httpProxy || void 0,
|
|
1102
|
+
noProxy: noProxy || void 0
|
|
1103
|
+
});
|
|
1104
|
+
p.outro(`Proxy configuration saved${enable ? " and enabled" : ""}.`);
|
|
1105
|
+
}
|
|
981
1106
|
}
|
|
982
|
-
}
|
|
1107
|
+
});
|
|
983
1108
|
|
|
984
1109
|
//#endregion
|
|
985
1110
|
//#region src/lib/shell.ts
|
|
@@ -3354,7 +3479,7 @@ async function runServer(options$1) {
|
|
|
3354
3479
|
state.zenApiKey = options$1.zenApiKey;
|
|
3355
3480
|
consola.info("Using provided Zen API key");
|
|
3356
3481
|
} else {
|
|
3357
|
-
const { setupZenApiKey, loadZenAuth } = await import("./auth-
|
|
3482
|
+
const { setupZenApiKey, loadZenAuth } = await import("./auth-CCwbOOQN.js");
|
|
3358
3483
|
const existingAuth = await loadZenAuth();
|
|
3359
3484
|
if (existingAuth) {
|
|
3360
3485
|
state.zenApiKey = existingAuth.apiKey;
|
|
@@ -3367,7 +3492,7 @@ async function runServer(options$1) {
|
|
|
3367
3492
|
} else if (options$1.antigravity) {
|
|
3368
3493
|
consola.info("Google Antigravity mode enabled");
|
|
3369
3494
|
state.antigravityMode = true;
|
|
3370
|
-
const { loadAntigravityAuth, setupAntigravity, getCurrentAccount, hasApiKey, getApiKey: getApiKey$1, setOAuthCredentials } = await import("./auth-
|
|
3495
|
+
const { loadAntigravityAuth, setupAntigravity, getCurrentAccount, hasApiKey, getApiKey: getApiKey$1, setOAuthCredentials } = await import("./auth-B2lTFLSD.js");
|
|
3371
3496
|
if (options$1.antigravityClientId && options$1.antigravityClientSecret) {
|
|
3372
3497
|
setOAuthCredentials(options$1.antigravityClientId, options$1.antigravityClientSecret);
|
|
3373
3498
|
consola.info("Using provided OAuth credentials from CLI");
|
|
@@ -3396,7 +3521,7 @@ async function runServer(options$1) {
|
|
|
3396
3521
|
}
|
|
3397
3522
|
if (!await getCurrentAccount() && !hasApiKey()) throw new Error("No enabled Antigravity accounts available");
|
|
3398
3523
|
}
|
|
3399
|
-
const { getAntigravityModels: getAntigravityModels$1 } = await import("./get-models-
|
|
3524
|
+
const { getAntigravityModels: getAntigravityModels$1 } = await import("./get-models-CmDpYUV-.js");
|
|
3400
3525
|
const models = await getAntigravityModels$1();
|
|
3401
3526
|
state.antigravityModels = models;
|
|
3402
3527
|
consola.info(`Available Antigravity models: \n${models.data.map((model) => `- ${model.id}`).join("\n")}`);
|
|
@@ -3420,7 +3545,7 @@ async function runServer(options$1) {
|
|
|
3420
3545
|
const { HTTPError: HTTPError$1 } = await import("./error-CsShqJjE.js");
|
|
3421
3546
|
if (error instanceof HTTPError$1 && error.response.status === 401) {
|
|
3422
3547
|
consola.error("Failed to get Copilot token - GitHub token may be invalid or Copilot access revoked");
|
|
3423
|
-
const { clearGithubToken: clearGithubToken$1 } = await import("./token-
|
|
3548
|
+
const { clearGithubToken: clearGithubToken$1 } = await import("./token-sYqHiHEd.js");
|
|
3424
3549
|
await clearGithubToken$1();
|
|
3425
3550
|
consola.info("Please restart to re-authenticate");
|
|
3426
3551
|
}
|
|
@@ -3592,6 +3717,7 @@ const main = defineCommand({
|
|
|
3592
3717
|
description: "A wrapper around GitHub Copilot API to make it OpenAI/Anthropic compatible. Fork with bug fixes and improvements."
|
|
3593
3718
|
},
|
|
3594
3719
|
subCommands: {
|
|
3720
|
+
antigravity,
|
|
3595
3721
|
auth,
|
|
3596
3722
|
start,
|
|
3597
3723
|
"check-usage": checkUsage,
|