@nick3/copilot-api 1.10.8 → 1.10.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -46
- package/README.zh-CN.md +141 -46
- package/dist/{account-COtMmvzU.js → account-DpW8RaT6.js} +3 -3
- package/dist/{account-COtMmvzU.js.map → account-DpW8RaT6.js.map} +1 -1
- package/dist/admin/AGENTS.md +19 -0
- package/dist/auth-nO-eHeO_.js +327 -0
- package/dist/auth-nO-eHeO_.js.map +1 -0
- package/dist/{check-usage-DdevqHE5.js → check-usage-ZifYvA3w.js} +4 -42
- package/dist/check-usage-ZifYvA3w.js.map +1 -0
- package/dist/config-CmhIPHn_.js +578 -0
- package/dist/config-CmhIPHn_.js.map +1 -0
- package/dist/{debug-BMo6ltbp.js → debug-DvpksqEL.js} +18 -7
- package/dist/debug-DvpksqEL.js.map +1 -0
- package/dist/main.js +5 -10
- package/dist/main.js.map +1 -1
- package/dist/mcp-http-BhELuvog.js +2 -0
- package/dist/mcp-http-DI4Vz01p.js +82 -0
- package/dist/mcp-http-DI4Vz01p.js.map +1 -0
- package/dist/mcp-http-config-DMdUDz1D.js +39 -0
- package/dist/mcp-http-config-DMdUDz1D.js.map +1 -0
- package/dist/mcp-pLTPS0tO.js +79 -0
- package/dist/mcp-pLTPS0tO.js.map +1 -0
- package/dist/{tool-search-BrN7M0Dd.js → mcp-server-DEqHrXFq.js} +25 -2
- package/dist/mcp-server-DEqHrXFq.js.map +1 -0
- package/dist/{paths-CclKwouX.js → paths-Bpsb62LK.js} +3 -1
- package/dist/paths-Bpsb62LK.js.map +1 -0
- package/dist/{poll-access-token-BAgM2-7k.js → poll-access-token-GzVkiTH8.js} +71 -4
- package/dist/poll-access-token-GzVkiTH8.js.map +1 -0
- package/dist/{request-outbound-BJjWS_jF.js → request-outbound-BkEA8Wgb.js} +1 -1
- package/dist/{request-outbound-Pu1kp2x8.js → request-outbound-DZTxxtcx.js} +3 -3
- package/dist/{request-outbound-Pu1kp2x8.js.map → request-outbound-DZTxxtcx.js.map} +1 -1
- package/dist/{proxy-_U-hgwIn.js → responses-bridge-registry-BJ5Sbh6-.js} +116 -577
- package/dist/responses-bridge-registry-BJ5Sbh6-.js.map +1 -0
- package/dist/{server-DulP9mYd.js → server-DJ3_UGc4.js} +339 -168
- package/dist/server-DJ3_UGc4.js.map +1 -0
- package/dist/start-DaB0AcjZ.js +526 -0
- package/dist/start-DaB0AcjZ.js.map +1 -0
- package/dist/token-DrFDLVxa.js +365 -0
- package/dist/token-DrFDLVxa.js.map +1 -0
- package/package.json +1 -1
- package/dist/auth-B0y-2njL.js +0 -226
- package/dist/auth-B0y-2njL.js.map +0 -1
- package/dist/check-usage-DdevqHE5.js.map +0 -1
- package/dist/debug-BMo6ltbp.js.map +0 -1
- package/dist/get-copilot-token-8Rm-rVsp.js +0 -17
- package/dist/get-copilot-token-8Rm-rVsp.js.map +0 -1
- package/dist/mcp-9Hgepkc5.js +0 -37
- package/dist/mcp-9Hgepkc5.js.map +0 -1
- package/dist/paths-CclKwouX.js.map +0 -1
- package/dist/poll-access-token-BAgM2-7k.js.map +0 -1
- package/dist/proxy-_U-hgwIn.js.map +0 -1
- package/dist/server-DulP9mYd.js.map +0 -1
- package/dist/start-CtEoE2gt.js +0 -274
- package/dist/start-CtEoE2gt.js.map +0 -1
- package/dist/tool-search-BrN7M0Dd.js.map +0 -1
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { g as getCopilotUsage, h as getDeviceCode, j as state, m as getGitHubUser, t as pollAccessToken } from "./poll-access-token-GzVkiTH8.js";
|
|
2
|
+
import { d as loadRegistry, g as saveRegistry, h as saveAccountToken, l as listAccountsFromRegistry, m as removeAccountToken, n as parseAccountType, p as removeAccountFromRegistry, r as addAccountToRegistry, u as loadAccountToken } from "./account-DpW8RaT6.js";
|
|
3
|
+
import { r as ensurePaths, t as PATHS } from "./paths-Bpsb62LK.js";
|
|
4
|
+
import { n as setupGitHubToken, r as loginCodex, t as persistCodexCredentials } from "./token-DrFDLVxa.js";
|
|
5
|
+
import { defineCommand } from "citty";
|
|
6
|
+
import consola from "consola";
|
|
7
|
+
//#region src/auth.ts
|
|
8
|
+
/**
|
|
9
|
+
* Fetch quota info for an account (used by auth ls -q)
|
|
10
|
+
*/
|
|
11
|
+
async function fetchQuotaInfo(account) {
|
|
12
|
+
try {
|
|
13
|
+
const token = await loadAccountToken(account.id);
|
|
14
|
+
if (!token) return " | Quota: (no token)";
|
|
15
|
+
const premium = (await getCopilotUsage({
|
|
16
|
+
githubToken: token,
|
|
17
|
+
accountType: account.accountType
|
|
18
|
+
})).quota_snapshots.premium_interactions;
|
|
19
|
+
return premium.unlimited ? " | Quota: unlimited" : ` | Quota: ${premium.remaining}/${premium.entitlement}`;
|
|
20
|
+
} catch (error) {
|
|
21
|
+
consola.debug(`Failed to fetch quota for ${account.id}:`, error);
|
|
22
|
+
return " | Quota: (failed to fetch)";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* auth add - Add a new GitHub Copilot account
|
|
27
|
+
*/
|
|
28
|
+
const authAdd = defineCommand({
|
|
29
|
+
meta: {
|
|
30
|
+
name: "add",
|
|
31
|
+
description: "Add a new GitHub Copilot account"
|
|
32
|
+
},
|
|
33
|
+
args: {
|
|
34
|
+
"account-type": {
|
|
35
|
+
alias: "a",
|
|
36
|
+
type: "string",
|
|
37
|
+
default: "individual",
|
|
38
|
+
description: "Account type (individual, business, enterprise)"
|
|
39
|
+
},
|
|
40
|
+
verbose: {
|
|
41
|
+
alias: "v",
|
|
42
|
+
type: "boolean",
|
|
43
|
+
default: false,
|
|
44
|
+
description: "Enable verbose logging"
|
|
45
|
+
},
|
|
46
|
+
"show-token": {
|
|
47
|
+
type: "boolean",
|
|
48
|
+
default: false,
|
|
49
|
+
description: "Show GitHub token after auth"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
async run({ args }) {
|
|
53
|
+
if (args.verbose) {
|
|
54
|
+
consola.level = 5;
|
|
55
|
+
consola.info("Verbose logging enabled");
|
|
56
|
+
}
|
|
57
|
+
state.showToken = args["show-token"];
|
|
58
|
+
let accountType;
|
|
59
|
+
try {
|
|
60
|
+
accountType = parseAccountType(args["account-type"]);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
consola.error(error instanceof Error ? error.message : String(error));
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
await ensurePaths();
|
|
66
|
+
consola.info("Starting GitHub device code authentication...");
|
|
67
|
+
const deviceResponse = await getDeviceCode();
|
|
68
|
+
consola.debug("Device code response:", deviceResponse);
|
|
69
|
+
consola.info(`Please enter the code "${deviceResponse.user_code}" at ${deviceResponse.verification_uri}`);
|
|
70
|
+
const token = await pollAccessToken(deviceResponse);
|
|
71
|
+
if (state.showToken) consola.info("GitHub token:", token);
|
|
72
|
+
const accountId = (await getGitHubUser({
|
|
73
|
+
githubToken: token,
|
|
74
|
+
accountType
|
|
75
|
+
})).login;
|
|
76
|
+
await saveAccountToken(accountId, token);
|
|
77
|
+
if ((await listAccountsFromRegistry()).some((acc) => acc.id === accountId)) {
|
|
78
|
+
await saveRegistry(await loadRegistry());
|
|
79
|
+
consola.success(`Account "${accountId}" already exists. Token has been updated.`);
|
|
80
|
+
} else {
|
|
81
|
+
await addAccountToRegistry({
|
|
82
|
+
id: accountId,
|
|
83
|
+
accountType,
|
|
84
|
+
addedAt: Date.now()
|
|
85
|
+
});
|
|
86
|
+
consola.success(`Account "${accountId}" added successfully!`);
|
|
87
|
+
}
|
|
88
|
+
consola.info(`Account type: ${accountType}`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
/**
|
|
92
|
+
* auth ls - List all registered accounts
|
|
93
|
+
*/
|
|
94
|
+
const authLs = defineCommand({
|
|
95
|
+
meta: {
|
|
96
|
+
name: "ls",
|
|
97
|
+
description: "List all registered accounts"
|
|
98
|
+
},
|
|
99
|
+
args: {
|
|
100
|
+
"show-quota": {
|
|
101
|
+
alias: "q",
|
|
102
|
+
type: "boolean",
|
|
103
|
+
default: false,
|
|
104
|
+
description: "Show quota information (requires API call)"
|
|
105
|
+
},
|
|
106
|
+
verbose: {
|
|
107
|
+
alias: "v",
|
|
108
|
+
type: "boolean",
|
|
109
|
+
default: false,
|
|
110
|
+
description: "Enable verbose logging"
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
async run({ args }) {
|
|
114
|
+
if (args.verbose) consola.level = 5;
|
|
115
|
+
await ensurePaths();
|
|
116
|
+
const accounts = await listAccountsFromRegistry();
|
|
117
|
+
if (accounts.length === 0) {
|
|
118
|
+
consola.info("No accounts registered. Use 'auth add' to add an account.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
consola.info(`Found ${accounts.length} account(s):\n`);
|
|
122
|
+
for (const [i, account] of accounts.entries()) {
|
|
123
|
+
const addedDate = new Date(account.addedAt).toLocaleString();
|
|
124
|
+
const quotaInfo = args["show-quota"] ? await fetchQuotaInfo(account) : "";
|
|
125
|
+
console.log(` ${i + 1}. ${account.id} (${account.accountType})${quotaInfo}`);
|
|
126
|
+
console.log(` Added: ${addedDate}\n`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* auth rm - Remove an account
|
|
132
|
+
*/
|
|
133
|
+
const authRm = defineCommand({
|
|
134
|
+
meta: {
|
|
135
|
+
name: "rm",
|
|
136
|
+
description: "Remove an account"
|
|
137
|
+
},
|
|
138
|
+
args: {
|
|
139
|
+
target: {
|
|
140
|
+
type: "positional",
|
|
141
|
+
description: "Account ID or index (1-based)",
|
|
142
|
+
required: true
|
|
143
|
+
},
|
|
144
|
+
force: {
|
|
145
|
+
alias: "f",
|
|
146
|
+
type: "boolean",
|
|
147
|
+
default: false,
|
|
148
|
+
description: "Skip confirmation prompt"
|
|
149
|
+
},
|
|
150
|
+
verbose: {
|
|
151
|
+
alias: "v",
|
|
152
|
+
type: "boolean",
|
|
153
|
+
default: false,
|
|
154
|
+
description: "Enable verbose logging"
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
async run({ args }) {
|
|
158
|
+
if (args.verbose) consola.level = 5;
|
|
159
|
+
await ensurePaths();
|
|
160
|
+
const target = args.target;
|
|
161
|
+
const accounts = await listAccountsFromRegistry();
|
|
162
|
+
if (accounts.length === 0) {
|
|
163
|
+
consola.error("No accounts to remove.");
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
let accountToRemove;
|
|
167
|
+
const index = Number.parseInt(target, 10);
|
|
168
|
+
if (!Number.isNaN(index) && index >= 1 && index <= accounts.length) accountToRemove = {
|
|
169
|
+
id: accounts[index - 1].id,
|
|
170
|
+
index: index - 1
|
|
171
|
+
};
|
|
172
|
+
else {
|
|
173
|
+
const foundIndex = accounts.findIndex((acc) => acc.id === target);
|
|
174
|
+
if (foundIndex !== -1) accountToRemove = {
|
|
175
|
+
id: accounts[foundIndex].id,
|
|
176
|
+
index: foundIndex
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (!accountToRemove) {
|
|
180
|
+
consola.error(`Account "${target}" not found.`);
|
|
181
|
+
consola.info("Use 'auth ls' to see available accounts.");
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (!args.force) {
|
|
185
|
+
if (!await consola.prompt(`Are you sure you want to remove account "${accountToRemove.id}"?`, { type: "confirm" })) {
|
|
186
|
+
consola.info("Cancelled.");
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
await removeAccountToken(accountToRemove.id);
|
|
191
|
+
await removeAccountFromRegistry(accountToRemove.id);
|
|
192
|
+
consola.success(`Account "${accountToRemove.id}" removed.`);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
const authLoginArgs = {
|
|
196
|
+
provider: {
|
|
197
|
+
type: "string",
|
|
198
|
+
description: "Provider to log in with (copilot or codex)"
|
|
199
|
+
},
|
|
200
|
+
verbose: {
|
|
201
|
+
alias: "v",
|
|
202
|
+
type: "boolean",
|
|
203
|
+
default: false,
|
|
204
|
+
description: "Enable verbose logging"
|
|
205
|
+
},
|
|
206
|
+
"show-token": {
|
|
207
|
+
type: "boolean",
|
|
208
|
+
default: false,
|
|
209
|
+
description: "Show provider access token on auth"
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const BUILTIN_PROVIDER_NAMES = ["copilot", "codex"];
|
|
213
|
+
const BUILTIN_PROVIDER_LABELS = {
|
|
214
|
+
copilot: "GitHub Copilot",
|
|
215
|
+
codex: "OpenAI Codex"
|
|
216
|
+
};
|
|
217
|
+
function isBuiltinProviderName(providerName) {
|
|
218
|
+
return BUILTIN_PROVIDER_NAMES.includes(providerName);
|
|
219
|
+
}
|
|
220
|
+
async function resolveProviderSelection(providerArg) {
|
|
221
|
+
const availableProviders = [...BUILTIN_PROVIDER_NAMES];
|
|
222
|
+
if (providerArg !== void 0) {
|
|
223
|
+
const providerName = providerArg.trim();
|
|
224
|
+
if (!isBuiltinProviderName(providerName)) throw new Error(`Unknown provider '${providerArg}'. Expected one of: ${availableProviders.join(", ")}`);
|
|
225
|
+
return providerName;
|
|
226
|
+
}
|
|
227
|
+
if (availableProviders.length === 1) return availableProviders[0];
|
|
228
|
+
const provider = await consola.prompt("Select a provider to log in with", {
|
|
229
|
+
type: "select",
|
|
230
|
+
options: availableProviders.map((providerName) => ({
|
|
231
|
+
label: `${BUILTIN_PROVIDER_LABELS[providerName]} (${providerName})`,
|
|
232
|
+
value: providerName
|
|
233
|
+
}))
|
|
234
|
+
});
|
|
235
|
+
if (!provider || !isBuiltinProviderName(provider)) throw new Error("No provider selected");
|
|
236
|
+
return provider;
|
|
237
|
+
}
|
|
238
|
+
async function loginWithCodex() {
|
|
239
|
+
await persistCodexCredentials(await loginCodex({
|
|
240
|
+
onAuth(info) {
|
|
241
|
+
consola.info("Open the following URL to authenticate with Codex:");
|
|
242
|
+
consola.log(info.url);
|
|
243
|
+
if (info.instructions) consola.info(info.instructions);
|
|
244
|
+
},
|
|
245
|
+
onPrompt(message) {
|
|
246
|
+
return consola.prompt(message, { type: "text" });
|
|
247
|
+
},
|
|
248
|
+
onProgress(message) {
|
|
249
|
+
consola.debug(message);
|
|
250
|
+
}
|
|
251
|
+
}), { enableProvider: true });
|
|
252
|
+
consola.success(`Codex provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.CODEX_CREDENTIAL_PATH}`);
|
|
253
|
+
}
|
|
254
|
+
async function loginWithProvider(provider) {
|
|
255
|
+
if (provider === "copilot") {
|
|
256
|
+
await setupGitHubToken({ force: true });
|
|
257
|
+
consola.success("GitHub token written to", PATHS.GITHUB_TOKEN_PATH);
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
await loginWithCodex();
|
|
261
|
+
}
|
|
262
|
+
async function runAuthLogin(options) {
|
|
263
|
+
if (options.verbose) {
|
|
264
|
+
consola.level = 5;
|
|
265
|
+
consola.info("Verbose logging enabled");
|
|
266
|
+
}
|
|
267
|
+
state.showToken = options.showToken;
|
|
268
|
+
await ensurePaths();
|
|
269
|
+
const provider = await resolveProviderSelection(options.provider);
|
|
270
|
+
consola.info(`Logging in with ${BUILTIN_PROVIDER_LABELS[provider]}`);
|
|
271
|
+
await loginWithProvider(provider);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Main auth command with subcommands
|
|
275
|
+
*/
|
|
276
|
+
const auth = defineCommand({
|
|
277
|
+
meta: {
|
|
278
|
+
name: "auth",
|
|
279
|
+
description: "Manage GitHub Copilot accounts"
|
|
280
|
+
},
|
|
281
|
+
subCommands: {
|
|
282
|
+
add: authAdd,
|
|
283
|
+
ls: authLs,
|
|
284
|
+
rm: authRm,
|
|
285
|
+
login: defineCommand({
|
|
286
|
+
meta: {
|
|
287
|
+
name: "login",
|
|
288
|
+
description: "Authenticate a builtin provider without running the server"
|
|
289
|
+
},
|
|
290
|
+
args: authLoginArgs,
|
|
291
|
+
run({ args }) {
|
|
292
|
+
return runAuthLogin({
|
|
293
|
+
provider: args.provider,
|
|
294
|
+
verbose: args.verbose,
|
|
295
|
+
showToken: args["show-token"]
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
},
|
|
300
|
+
args: {
|
|
301
|
+
"account-type": {
|
|
302
|
+
alias: "a",
|
|
303
|
+
type: "string",
|
|
304
|
+
default: "individual",
|
|
305
|
+
description: "Account type (individual, business, enterprise)"
|
|
306
|
+
},
|
|
307
|
+
verbose: {
|
|
308
|
+
alias: "v",
|
|
309
|
+
type: "boolean",
|
|
310
|
+
default: false,
|
|
311
|
+
description: "Enable verbose logging"
|
|
312
|
+
},
|
|
313
|
+
"show-token": {
|
|
314
|
+
type: "boolean",
|
|
315
|
+
default: false,
|
|
316
|
+
description: "Show GitHub token after auth"
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
async run(ctx) {
|
|
320
|
+
const firstArg = ctx.rawArgs[0];
|
|
321
|
+
if (!(firstArg === "add" || firstArg === "ls" || firstArg === "rm" || firstArg === "login") && authAdd.run) await authAdd.run(ctx);
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
//#endregion
|
|
325
|
+
export { auth };
|
|
326
|
+
|
|
327
|
+
//# sourceMappingURL=auth-nO-eHeO_.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-nO-eHeO_.js","names":[],"sources":["../src/auth.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n addAccountToRegistry,\n listAccountsFromRegistry,\n loadAccountToken,\n loadRegistry,\n removeAccountFromRegistry,\n removeAccountToken,\n saveAccountToken,\n saveRegistry,\n} from \"./lib/accounts-registry\"\nimport { loginCodex } from \"./lib/oauth/codex\"\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { state } from \"./lib/state\"\nimport { persistCodexCredentials, setupGitHubToken } from \"./lib/token\"\nimport {\n parseAccountType,\n type AccountMeta,\n type AccountType,\n} from \"./lib/types/account\"\nimport { getCopilotUsage } from \"./services/github/get-copilot-usage\"\nimport { getDeviceCode } from \"./services/github/get-device-code\"\nimport { getGitHubUser } from \"./services/github/get-user\"\nimport { pollAccessToken } from \"./services/github/poll-access-token\"\n\n/**\n * Fetch quota info for an account (used by auth ls -q)\n */\nasync function fetchQuotaInfo(account: AccountMeta): Promise<string> {\n try {\n const token = await loadAccountToken(account.id)\n if (!token) {\n return \" | Quota: (no token)\"\n }\n\n const usage = await getCopilotUsage({\n githubToken: token,\n accountType: account.accountType,\n })\n const premium = usage.quota_snapshots.premium_interactions\n\n return premium.unlimited ?\n \" | Quota: unlimited\"\n : ` | Quota: ${premium.remaining}/${premium.entitlement}`\n } catch (error) {\n consola.debug(`Failed to fetch quota for ${account.id}:`, error)\n return \" | Quota: (failed to fetch)\"\n }\n}\n\n/**\n * auth add - Add a new GitHub Copilot account\n */\nconst authAdd = defineCommand({\n meta: {\n name: \"add\",\n description: \"Add a new GitHub Copilot account\",\n },\n args: {\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = args[\"show-token\"]\n\n let accountType: AccountType\n try {\n accountType = parseAccountType(args[\"account-type\"])\n } catch (error) {\n consola.error(error instanceof Error ? error.message : String(error))\n process.exit(1)\n }\n\n await ensurePaths()\n\n // Start device code flow\n consola.info(\"Starting GitHub device code authentication...\")\n const deviceResponse = await getDeviceCode()\n consola.debug(\"Device code response:\", deviceResponse)\n\n consola.info(\n `Please enter the code \"${deviceResponse.user_code}\" at ${deviceResponse.verification_uri}`,\n )\n\n // Poll for access token\n const token = await pollAccessToken(deviceResponse)\n\n if (state.showToken) {\n consola.info(\"GitHub token:\", token)\n }\n\n // Get user info to determine account ID\n const user = await getGitHubUser({ githubToken: token, accountType })\n const accountId = user.login\n\n // Save token and check if account already exists\n await saveAccountToken(accountId, token)\n const existingAccounts = await listAccountsFromRegistry()\n const alreadyExists = existingAccounts.some((acc) => acc.id === accountId)\n\n if (alreadyExists) {\n // Touch registry file so a running server can hot-reload updated tokens.\n await saveRegistry(await loadRegistry())\n\n consola.success(\n `Account \"${accountId}\" already exists. Token has been updated.`,\n )\n } else {\n await addAccountToRegistry({\n id: accountId,\n accountType,\n addedAt: Date.now(),\n })\n consola.success(`Account \"${accountId}\" added successfully!`)\n }\n\n consola.info(`Account type: ${accountType}`)\n },\n})\n\n/**\n * auth ls - List all registered accounts\n */\nconst authLs = defineCommand({\n meta: {\n name: \"ls\",\n description: \"List all registered accounts\",\n },\n args: {\n \"show-quota\": {\n alias: \"q\",\n type: \"boolean\",\n default: false,\n description: \"Show quota information (requires API call)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.info(\"No accounts registered. Use 'auth add' to add an account.\")\n return\n }\n\n consola.info(`Found ${accounts.length} account(s):\\n`)\n\n for (const [i, account] of accounts.entries()) {\n const addedDate = new Date(account.addedAt).toLocaleString()\n\n const quotaInfo = args[\"show-quota\"] ? await fetchQuotaInfo(account) : \"\"\n\n console.log(\n ` ${i + 1}. ${account.id} (${account.accountType})${quotaInfo}`,\n )\n console.log(` Added: ${addedDate}\\n`)\n }\n },\n})\n\n/**\n * auth rm - Remove an account\n */\nconst authRm = defineCommand({\n meta: {\n name: \"rm\",\n description: \"Remove an account\",\n },\n args: {\n target: {\n type: \"positional\",\n description: \"Account ID or index (1-based)\",\n required: true,\n },\n force: {\n alias: \"f\",\n type: \"boolean\",\n default: false,\n description: \"Skip confirmation prompt\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n },\n async run({ args }) {\n if (args.verbose) {\n consola.level = 5\n }\n\n await ensurePaths()\n\n const target = args.target\n const accounts = await listAccountsFromRegistry()\n\n if (accounts.length === 0) {\n consola.error(\"No accounts to remove.\")\n return\n }\n\n // Determine account to remove (by ID or index)\n let accountToRemove: { id: string; index: number } | undefined\n\n // Try parsing as index (1-based)\n const index = Number.parseInt(target, 10)\n if (!Number.isNaN(index) && index >= 1 && index <= accounts.length) {\n accountToRemove = { id: accounts[index - 1].id, index: index - 1 }\n } else {\n // Try finding by ID\n const foundIndex = accounts.findIndex((acc) => acc.id === target)\n if (foundIndex !== -1) {\n accountToRemove = { id: accounts[foundIndex].id, index: foundIndex }\n }\n }\n\n if (!accountToRemove) {\n consola.error(`Account \"${target}\" not found.`)\n consola.info(\"Use 'auth ls' to see available accounts.\")\n return\n }\n\n // Confirmation\n if (!args.force) {\n const confirmed = await consola.prompt(\n `Are you sure you want to remove account \"${accountToRemove.id}\"?`,\n { type: \"confirm\" },\n )\n if (!confirmed) {\n consola.info(\"Cancelled.\")\n return\n }\n }\n\n // Remove token file and registry entry\n await removeAccountToken(accountToRemove.id)\n await removeAccountFromRegistry(accountToRemove.id)\n\n consola.success(`Account \"${accountToRemove.id}\" removed.`)\n },\n})\n\ninterface RunAuthOptions {\n provider?: string\n verbose: boolean\n showToken: boolean\n}\n\nconst authLoginArgs = {\n provider: {\n type: \"string\",\n description: \"Provider to log in with (copilot or codex)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show provider access token on auth\",\n },\n} as const\n\nconst BUILTIN_PROVIDER_NAMES = [\"copilot\", \"codex\"] as const\n\ntype BuiltinProviderName = (typeof BUILTIN_PROVIDER_NAMES)[number]\n\nconst BUILTIN_PROVIDER_LABELS: Record<BuiltinProviderName, string> = {\n copilot: \"GitHub Copilot\",\n codex: \"OpenAI Codex\",\n}\n\nfunction isBuiltinProviderName(\n providerName: string,\n): providerName is BuiltinProviderName {\n return BUILTIN_PROVIDER_NAMES.includes(providerName as BuiltinProviderName)\n}\n\nasync function resolveProviderSelection(\n providerArg: string | undefined,\n): Promise<BuiltinProviderName> {\n const availableProviders = [...BUILTIN_PROVIDER_NAMES]\n\n if (providerArg !== undefined) {\n const providerName = providerArg.trim()\n if (!isBuiltinProviderName(providerName)) {\n throw new Error(\n `Unknown provider '${providerArg}'. Expected one of: ${availableProviders.join(\", \")}`,\n )\n }\n return providerName\n }\n\n if (availableProviders.length === 1) {\n return availableProviders[0]\n }\n\n const provider = await consola.prompt(\"Select a provider to log in with\", {\n type: \"select\",\n options: availableProviders.map((providerName) => ({\n label: `${BUILTIN_PROVIDER_LABELS[providerName]} (${providerName})`,\n value: providerName,\n })),\n })\n\n if (!provider || !isBuiltinProviderName(provider)) {\n throw new Error(\"No provider selected\")\n }\n\n return provider\n}\n\nasync function loginWithCodex(): Promise<void> {\n const credentials = await loginCodex({\n onAuth(info) {\n consola.info(\"Open the following URL to authenticate with Codex:\")\n consola.log(info.url)\n if (info.instructions) {\n consola.info(info.instructions)\n }\n },\n onPrompt(message) {\n return consola.prompt(message, {\n type: \"text\",\n })\n },\n onProgress(message) {\n consola.debug(message)\n },\n })\n\n await persistCodexCredentials(credentials, { enableProvider: true })\n consola.success(\n `Codex provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.CODEX_CREDENTIAL_PATH}`,\n )\n}\n\nasync function loginWithProvider(provider: BuiltinProviderName): Promise<void> {\n if (provider === \"copilot\") {\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n return\n }\n\n await loginWithCodex()\n}\n\nexport async function runAuthLogin(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 const provider = await resolveProviderSelection(options.provider)\n\n consola.info(`Logging in with ${BUILTIN_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider)\n}\n\nconst authLogin = defineCommand({\n meta: {\n name: \"login\",\n description: \"Authenticate a builtin provider without running the server\",\n },\n args: authLoginArgs,\n run({ args }) {\n return runAuthLogin({\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n\n/**\n * Main auth command with subcommands\n */\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Manage GitHub Copilot accounts\",\n },\n subCommands: {\n add: authAdd,\n ls: authLs,\n rm: authRm,\n login: authLogin,\n },\n args: {\n // Legacy args for backward compatibility (when no subcommand)\n \"account-type\": {\n alias: \"a\",\n type: \"string\",\n default: \"individual\",\n description: \"Account type (individual, business, enterprise)\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show GitHub token after auth\",\n },\n },\n async run(ctx) {\n // Check if a subcommand was specified in rawArgs.\n // Only treat the *first* raw arg as a subcommand to avoid false positives\n // when flags accept values like \"add\"/\"ls\"/\"rm\".\n const firstArg = ctx.rawArgs[0]\n const hasSubCommand =\n firstArg === \"add\"\n || firstArg === \"ls\"\n || firstArg === \"rm\"\n || firstArg === \"login\"\n\n // Backward compatibility: if no subcommand, run 'add'\n if (!hasSubCommand && authAdd.run) {\n await authAdd.run(ctx)\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,46 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as ensurePaths
|
|
3
|
-
import "./
|
|
1
|
+
import { g as getCopilotUsage } from "./poll-access-token-GzVkiTH8.js";
|
|
2
|
+
import { r as ensurePaths } from "./paths-Bpsb62LK.js";
|
|
3
|
+
import { n as setupGitHubToken } from "./token-DrFDLVxa.js";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
import consola from "consola";
|
|
6
|
-
import fs from "node:fs/promises";
|
|
7
|
-
//#region src/lib/token.ts
|
|
8
|
-
const readGithubToken = () => fs.readFile(PATHS.GITHUB_TOKEN_PATH, "utf8");
|
|
9
|
-
const writeGithubToken = (token) => fs.writeFile(PATHS.GITHUB_TOKEN_PATH, token);
|
|
10
|
-
async function setupGitHubToken(options) {
|
|
11
|
-
try {
|
|
12
|
-
const githubToken = await readGithubToken();
|
|
13
|
-
if (githubToken && !options?.force) {
|
|
14
|
-
state.githubToken = githubToken;
|
|
15
|
-
if (state.showToken) consola.info("GitHub token:", githubToken);
|
|
16
|
-
await logUser();
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
consola.info("Not logged in, getting new access token");
|
|
20
|
-
const response = await getDeviceCode();
|
|
21
|
-
consola.debug("Device code response:", response);
|
|
22
|
-
consola.info(`Please enter the code "${response.user_code}" in ${response.verification_uri}`);
|
|
23
|
-
const token = await pollAccessToken(response);
|
|
24
|
-
await writeGithubToken(token);
|
|
25
|
-
state.githubToken = token;
|
|
26
|
-
if (state.showToken) consola.info("GitHub token:", token);
|
|
27
|
-
await logUser();
|
|
28
|
-
} catch (error) {
|
|
29
|
-
if (error instanceof HTTPError) {
|
|
30
|
-
consola.error("Failed to get GitHub token:", await error.response.json());
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
33
|
-
consola.error("Failed to get GitHub token:", error);
|
|
34
|
-
throw error;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
async function logUser() {
|
|
38
|
-
const user = await getGitHubUser();
|
|
39
|
-
state.userName = user.login;
|
|
40
|
-
consola.info(`Logged in as ${user.login}`);
|
|
41
|
-
state.copilotApiUrl = (await getCopilotUsage()).endpoints.api;
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
6
|
//#region src/check-usage.ts
|
|
45
7
|
const checkUsage = defineCommand({
|
|
46
8
|
meta: {
|
|
@@ -78,4 +40,4 @@ const checkUsage = defineCommand({
|
|
|
78
40
|
//#endregion
|
|
79
41
|
export { checkUsage };
|
|
80
42
|
|
|
81
|
-
//# sourceMappingURL=check-usage-
|
|
43
|
+
//# sourceMappingURL=check-usage-ZifYvA3w.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-usage-ZifYvA3w.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;EACV,MAAM,aAAa;EACnB,MAAM,kBAAkB;EACxB,IAAI;GACF,MAAM,QAAQ,MAAM,iBAAiB;GACrC,MAAM,UAAU,MAAM,gBAAgB;GACtC,MAAM,eAAe,QAAQ;GAC7B,MAAM,cAAc,eAAe,QAAQ;GAC3C,MAAM,qBACJ,eAAe,IAAK,cAAc,eAAgB,MAAM;GAC1D,MAAM,0BAA0B,QAAQ;GAGxC,SAAS,eAAe,MAAc,MAA+B;IACnE,IAAI,CAAC,MAAM,OAAO,GAAG,KAAK;IAC1B,MAAM,QAAQ,KAAK;IACnB,MAAM,OAAO,QAAQ,KAAK;IAC1B,MAAM,cAAc,QAAQ,IAAK,OAAO,QAAS,MAAM;IACvD,MAAM,mBAAmB,KAAK;IAC9B,OAAO,GAAG,KAAK,IAAI,KAAK,GAAG,MAAM,SAAS,YAAY,QAAQ,EAAE,CAAC,UAAU,iBAAiB,QAAQ,EAAE,CAAC;;GAGzG,MAAM,cAAc,YAAY,YAAY,GAAG,aAAa,SAAS,mBAAmB,QAAQ,EAAE,CAAC,UAAU,wBAAwB,QAAQ,EAAE,CAAC;GAChJ,MAAM,WAAW,eAAe,QAAQ,MAAM,gBAAgB,KAAK;GACnE,MAAM,kBAAkB,eACtB,eACA,MAAM,gBAAgB,YACvB;GAED,QAAQ,IACN,wBAAwB,MAAM,aAAa,mBACtB,MAAM,iBAAiB,iBAEnC,YAAY,MACZ,SAAS,MACT,kBACV;WACM,KAAK;GACZ,QAAQ,MAAM,kCAAkC,IAAI;GACpD,QAAQ,KAAK,EAAE;;;CAGpB,CAAC"}
|