@jeffreycao/copilot-api 2.7.17 → 2.7.19
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 +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/{auth-sKq0qru1.js → auth-BI9j5Vof.js} +10 -5
- package/dist/auth-BI9j5Vof.js.map +1 -0
- package/dist/auth-Dv6K056n.js +2 -0
- package/dist/{config-BKA4Y1t8.js → config-0pYepRvK.js} +15 -8
- package/dist/config-0pYepRvK.js.map +1 -0
- package/dist/{config-store-CC5TNG7V.js → config-store-DeipVulH.js} +3 -2
- package/dist/config-store-DeipVulH.js.map +1 -0
- package/dist/{copilot-runtime-XKDhY-sV.js → copilot-runtime-D7uXIiMk.js} +3 -3
- package/dist/{copilot-runtime-XKDhY-sV.js.map → copilot-runtime-D7uXIiMk.js.map} +1 -1
- package/dist/{debug-BPNjSHgl.js → debug-C26JAmhE.js} +3 -3
- package/dist/{debug-BPNjSHgl.js.map → debug-C26JAmhE.js.map} +1 -1
- package/dist/main.js +4 -4
- package/dist/{provider-Dg-3-rrN.js → provider-BkN9E04x.js} +2 -2
- package/dist/{provider-Dg-3-rrN.js.map → provider-BkN9E04x.js.map} +1 -1
- package/dist/{provider-management-CBrc2nDg.js → provider-management-CLV6-gBT.js} +2 -2
- package/dist/{provider-management-CBrc2nDg.js.map → provider-management-CLV6-gBT.js.map} +1 -1
- package/dist/{server-04fZfBz1.js → server-DneVQ_F8.js} +696 -105
- package/dist/server-DneVQ_F8.js.map +1 -0
- package/dist/{start-qcGeG0TU.js → start-BiKN2HN7.js} +7 -7
- package/dist/{start-qcGeG0TU.js.map → start-BiKN2HN7.js.map} +1 -1
- package/dist/{token-CWFRUUIv.js → token-OftpnSxC.js} +3 -3
- package/dist/{token-CWFRUUIv.js.map → token-OftpnSxC.js.map} +1 -1
- package/package.json +1 -1
- package/pages/index.html +193 -23
- package/dist/auth-DuGyJdjW.js +0 -2
- package/dist/auth-sKq0qru1.js.map +0 -1
- package/dist/config-BKA4Y1t8.js.map +0 -1
- package/dist/config-store-CC5TNG7V.js.map +0 -1
- package/dist/server-04fZfBz1.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@jeffreycao/copilot-api",
|
|
4
|
-
"version": "2.7.
|
|
4
|
+
"version": "2.7.19",
|
|
5
5
|
"description": "GitHub Copilot, OpenAI Codex, OpenCode Go, and third-party AI provider gateway with OpenAI and Anthropic API compatibility.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"github-copilot",
|
package/pages/index.html
CHANGED
|
@@ -306,6 +306,44 @@
|
|
|
306
306
|
font-weight: 750;
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
+
.collapse-toggle {
|
|
310
|
+
display: inline-flex;
|
|
311
|
+
align-items: center;
|
|
312
|
+
gap: 6px;
|
|
313
|
+
padding: 0;
|
|
314
|
+
border: 0;
|
|
315
|
+
background: none;
|
|
316
|
+
color: inherit;
|
|
317
|
+
font: inherit;
|
|
318
|
+
text-align: left;
|
|
319
|
+
cursor: pointer;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
.collapse-toggle:focus-visible {
|
|
323
|
+
outline: 2px solid var(--color-blue);
|
|
324
|
+
outline-offset: 2px;
|
|
325
|
+
border-radius: 4px;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.collapse-chevron {
|
|
329
|
+
width: 16px;
|
|
330
|
+
height: 16px;
|
|
331
|
+
flex-shrink: 0;
|
|
332
|
+
color: var(--color-gray);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.collapse-toggle[aria-expanded="false"] .collapse-chevron {
|
|
336
|
+
transform: rotate(-90deg);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.collapse-body[hidden] {
|
|
340
|
+
display: none !important;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.panel-header:has(+ .collapse-body[hidden]) {
|
|
344
|
+
border-bottom-color: transparent;
|
|
345
|
+
}
|
|
346
|
+
|
|
309
347
|
.section-subtitle {
|
|
310
348
|
margin-top: -4px;
|
|
311
349
|
margin-bottom: 8px;
|
|
@@ -700,6 +738,7 @@
|
|
|
700
738
|
tokenUsageTrendDay: null,
|
|
701
739
|
tokenUsageTrendMetric: ALL_METRICS_VALUE,
|
|
702
740
|
tokenUsageTrendModel: ALL_MODELS_VALUE,
|
|
741
|
+
collapsedSections: {},
|
|
703
742
|
};
|
|
704
743
|
|
|
705
744
|
// --- Rendering Logic ---
|
|
@@ -1230,6 +1269,110 @@
|
|
|
1230
1269
|
createIcons();
|
|
1231
1270
|
}
|
|
1232
1271
|
|
|
1272
|
+
// --- Collapsible Sections ---
|
|
1273
|
+
const COLLAPSED_SECTIONS_STORAGE_KEY =
|
|
1274
|
+
"copilot-api:usage-viewer:collapsed";
|
|
1275
|
+
const COLLAPSIBLE_SECTION_KEYS = new Set([
|
|
1276
|
+
"tokenUsage",
|
|
1277
|
+
"modelBreakdown",
|
|
1278
|
+
"sessionBreakdown",
|
|
1279
|
+
"requestEvents",
|
|
1280
|
+
"copilotQuotas",
|
|
1281
|
+
"usageApiResponse",
|
|
1282
|
+
]);
|
|
1283
|
+
|
|
1284
|
+
function readCollapsedSections() {
|
|
1285
|
+
try {
|
|
1286
|
+
const raw = window.localStorage.getItem(
|
|
1287
|
+
COLLAPSED_SECTIONS_STORAGE_KEY
|
|
1288
|
+
);
|
|
1289
|
+
const parsed = raw ? JSON.parse(raw) : null;
|
|
1290
|
+
const collapsed = {};
|
|
1291
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
1292
|
+
for (const key of COLLAPSIBLE_SECTION_KEYS) {
|
|
1293
|
+
if (parsed[key] === true) {
|
|
1294
|
+
collapsed[key] = true;
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
return collapsed;
|
|
1299
|
+
} catch (error) {
|
|
1300
|
+
console.warn(
|
|
1301
|
+
"Could not read collapsed sections:",
|
|
1302
|
+
getErrorMessage(error)
|
|
1303
|
+
);
|
|
1304
|
+
return {};
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
function writeCollapsedSections() {
|
|
1309
|
+
try {
|
|
1310
|
+
window.localStorage.setItem(
|
|
1311
|
+
COLLAPSED_SECTIONS_STORAGE_KEY,
|
|
1312
|
+
JSON.stringify(state.collapsedSections)
|
|
1313
|
+
);
|
|
1314
|
+
} catch (error) {
|
|
1315
|
+
console.warn(
|
|
1316
|
+
"Could not store collapsed sections:",
|
|
1317
|
+
getErrorMessage(error)
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
function isSectionCollapsed(key) {
|
|
1323
|
+
return state.collapsedSections[key] === true;
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
function getCollapseBodyId(key) {
|
|
1327
|
+
return `collapse-body-${key}`;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
/**
|
|
1331
|
+
* Renders the toggle button (chevron + label) shown in a section header.
|
|
1332
|
+
* @param {string} key - A COLLAPSIBLE_SECTION_KEYS entry.
|
|
1333
|
+
* @param {string} labelHtml - Trusted HTML for the toggle label.
|
|
1334
|
+
*/
|
|
1335
|
+
function renderCollapseToggle(key, labelHtml) {
|
|
1336
|
+
return `<button type="button" class="collapse-toggle" data-collapse-toggle="${key}" aria-expanded="${!isSectionCollapsed(key)}" aria-controls="${getCollapseBodyId(key)}"><i data-lucide="chevron-down" class="collapse-chevron"></i>${labelHtml}</button>`;
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
/**
|
|
1340
|
+
* Opens a section body wrapper that is hidden while the section is
|
|
1341
|
+
* collapsed. Pair with renderCollapseBodyEnd() for multi-part bodies.
|
|
1342
|
+
* @param {string} key - A COLLAPSIBLE_SECTION_KEYS entry.
|
|
1343
|
+
* @param {string} className - Optional extra classes for the wrapper.
|
|
1344
|
+
*/
|
|
1345
|
+
function renderCollapseBodyStart(key, className = "") {
|
|
1346
|
+
return `<div id="${getCollapseBodyId(key)}" class="collapse-body ${className}" ${isSectionCollapsed(key) ? "hidden" : ""}>`;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
function renderCollapseBodyEnd() {
|
|
1350
|
+
return "</div>";
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
function renderCollapseBody(key, bodyHtml, className = "") {
|
|
1354
|
+
return `${renderCollapseBodyStart(key, className)}${bodyHtml}${renderCollapseBodyEnd()}`;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
function toggleCollapsedSection(button) {
|
|
1358
|
+
const key = button.dataset.collapseToggle;
|
|
1359
|
+
if (!COLLAPSIBLE_SECTION_KEYS.has(key)) {
|
|
1360
|
+
return;
|
|
1361
|
+
}
|
|
1362
|
+
const collapsed = !isSectionCollapsed(key);
|
|
1363
|
+
if (collapsed) {
|
|
1364
|
+
state.collapsedSections[key] = true;
|
|
1365
|
+
} else {
|
|
1366
|
+
delete state.collapsedSections[key];
|
|
1367
|
+
}
|
|
1368
|
+
const body = document.getElementById(getCollapseBodyId(key));
|
|
1369
|
+
if (body) {
|
|
1370
|
+
body.hidden = collapsed;
|
|
1371
|
+
}
|
|
1372
|
+
button.setAttribute("aria-expanded", String(!collapsed));
|
|
1373
|
+
writeCollapsedSections();
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1233
1376
|
function getModelField(model, fields) {
|
|
1234
1377
|
for (const field of fields) {
|
|
1235
1378
|
if (typeof model?.[field] === "string" && model[field].trim()) {
|
|
@@ -1464,12 +1607,12 @@
|
|
|
1464
1607
|
return `
|
|
1465
1608
|
<section id="usage-quotas" class="dashboard-section">
|
|
1466
1609
|
<h2 class="section-heading">
|
|
1467
|
-
|
|
1468
|
-
|
|
1610
|
+
${renderCollapseToggle(
|
|
1611
|
+
"copilotQuotas",
|
|
1612
|
+
`<i data-lucide="gauge" class="h-5 w-5" style="color: var(--color-blue);"></i><span>Copilot Quotas</span>`
|
|
1613
|
+
)}
|
|
1469
1614
|
</h2>
|
|
1470
|
-
|
|
1471
|
-
${quotaCards}
|
|
1472
|
-
</div>
|
|
1615
|
+
${renderCollapseBody("copilotQuotas", quotaCards, "metric-grid")}
|
|
1473
1616
|
</section>
|
|
1474
1617
|
`;
|
|
1475
1618
|
}
|
|
@@ -1482,10 +1625,15 @@
|
|
|
1482
1625
|
return `
|
|
1483
1626
|
<section id="usage-quotas" class="dashboard-section">
|
|
1484
1627
|
<h2 class="section-heading">
|
|
1485
|
-
|
|
1486
|
-
|
|
1628
|
+
${renderCollapseToggle(
|
|
1629
|
+
"copilotQuotas",
|
|
1630
|
+
`<i data-lucide="gauge" class="h-5 w-5" style="color: var(--color-blue);"></i><span>Copilot Quotas</span>`
|
|
1631
|
+
)}
|
|
1487
1632
|
</h2>
|
|
1488
|
-
${
|
|
1633
|
+
${renderCollapseBody(
|
|
1634
|
+
"copilotQuotas",
|
|
1635
|
+
renderError(state.error, "Usage request failed")
|
|
1636
|
+
)}
|
|
1489
1637
|
</section>
|
|
1490
1638
|
`;
|
|
1491
1639
|
}
|
|
@@ -1620,12 +1768,17 @@
|
|
|
1620
1768
|
return `
|
|
1621
1769
|
<section id="detailed-data" class="dashboard-section">
|
|
1622
1770
|
<h2 class="section-heading">
|
|
1623
|
-
|
|
1624
|
-
|
|
1771
|
+
${renderCollapseToggle(
|
|
1772
|
+
"usageApiResponse",
|
|
1773
|
+
`<i data-lucide="file-text" class="h-5 w-5" style="color: var(--color-blue);"></i><span>Copilot Usage API Response</span>`
|
|
1774
|
+
)}
|
|
1625
1775
|
</h2>
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1776
|
+
${renderCollapseBody(
|
|
1777
|
+
"usageApiResponse",
|
|
1778
|
+
`<div class="panel p-4 relative font-mono text-xs code-block overflow-auto" style="max-height: 420px;">
|
|
1779
|
+
${formattedDetails}
|
|
1780
|
+
</div>`
|
|
1781
|
+
)}
|
|
1629
1782
|
</section>
|
|
1630
1783
|
`;
|
|
1631
1784
|
}
|
|
@@ -1665,8 +1818,10 @@
|
|
|
1665
1818
|
<div class="mb-2 flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
|
|
1666
1819
|
<div>
|
|
1667
1820
|
<h2 class="section-heading mb-1">
|
|
1668
|
-
|
|
1669
|
-
|
|
1821
|
+
${renderCollapseToggle(
|
|
1822
|
+
"tokenUsage",
|
|
1823
|
+
`<i data-lucide="database" class="h-5 w-5" style="color: var(--color-blue);"></i><span>Token Usage</span>`
|
|
1824
|
+
)}
|
|
1670
1825
|
</h2>
|
|
1671
1826
|
<p class="section-subtitle mb-0">${escapeHtml(
|
|
1672
1827
|
renderTokenUsageRangeText(state.tokenUsagePeriod, activeRange)
|
|
@@ -1686,6 +1841,7 @@
|
|
|
1686
1841
|
</div>
|
|
1687
1842
|
</div>
|
|
1688
1843
|
|
|
1844
|
+
${renderCollapseBodyStart("tokenUsage")}
|
|
1689
1845
|
${
|
|
1690
1846
|
state.tokenUsageSummaryError
|
|
1691
1847
|
? renderError(
|
|
@@ -1791,17 +1947,20 @@
|
|
|
1791
1947
|
<div class="panel">
|
|
1792
1948
|
<div class="panel-header">
|
|
1793
1949
|
<div>
|
|
1794
|
-
<p class="panel-title">Model Breakdown</p>
|
|
1950
|
+
<p class="panel-title">${renderCollapseToggle("modelBreakdown", "<span>Model Breakdown</span>")}</p>
|
|
1795
1951
|
<p class="panel-meta">${summary ? `${formatNumber(summary.byModel.length)} models` : "No summary rows loaded."}</p>
|
|
1796
1952
|
</div>
|
|
1797
1953
|
</div>
|
|
1798
|
-
${
|
|
1954
|
+
${renderCollapseBody(
|
|
1955
|
+
"modelBreakdown",
|
|
1956
|
+
renderTokenUsageModelBreakdown(summary)
|
|
1957
|
+
)}
|
|
1799
1958
|
</div>
|
|
1800
1959
|
|
|
1801
1960
|
<div class="panel">
|
|
1802
1961
|
<div class="panel-header">
|
|
1803
1962
|
<div>
|
|
1804
|
-
<p class="panel-title">Session Breakdown</p>
|
|
1963
|
+
<p class="panel-title">${renderCollapseToggle("sessionBreakdown", "<span>Session Breakdown</span>")}</p>
|
|
1805
1964
|
<p class="panel-meta">${sessionsPage ? `Page ${sessionsPage.page} / ${sessionsPage.total_pages} - ${formatNumber(sessionsPage.total)} sessions` : "No session rows loaded."}</p>
|
|
1806
1965
|
</div>
|
|
1807
1966
|
<div class="flex items-center gap-2">
|
|
@@ -1809,6 +1968,7 @@
|
|
|
1809
1968
|
<button type="button" data-session-page="1" class="pill-button px-3 py-1.5 text-xs font-semibold" ${!sessionsPage || state.isSessionsLoading || sessionsPage.page >= sessionsPage.total_pages ? "disabled" : ""}>Next</button>
|
|
1810
1969
|
</div>
|
|
1811
1970
|
</div>
|
|
1971
|
+
${renderCollapseBodyStart("sessionBreakdown")}
|
|
1812
1972
|
${
|
|
1813
1973
|
state.tokenUsageSessionsError
|
|
1814
1974
|
? `<div class="p-4">${renderError(
|
|
@@ -1818,12 +1978,13 @@
|
|
|
1818
1978
|
: ""
|
|
1819
1979
|
}
|
|
1820
1980
|
${renderTokenUsageModelBreakdown({ bySession: sessionsPage?.items }, "session")}
|
|
1981
|
+
${renderCollapseBodyEnd()}
|
|
1821
1982
|
</div>
|
|
1822
1983
|
|
|
1823
1984
|
<div class="panel">
|
|
1824
1985
|
<div class="panel-header flex-col items-start sm:flex-row sm:items-center">
|
|
1825
1986
|
<div>
|
|
1826
|
-
<p class="panel-title">Request Events</p>
|
|
1987
|
+
<p class="panel-title">${renderCollapseToggle("requestEvents", "<span>Request Events</span>")}</p>
|
|
1827
1988
|
<p class="panel-meta">${escapeHtml(eventsMeta)}</p>
|
|
1828
1989
|
</div>
|
|
1829
1990
|
<div class="flex items-center gap-2">
|
|
@@ -1841,6 +2002,7 @@
|
|
|
1841
2002
|
)}
|
|
1842
2003
|
</div>
|
|
1843
2004
|
</div>
|
|
2005
|
+
${renderCollapseBodyStart("requestEvents")}
|
|
1844
2006
|
${
|
|
1845
2007
|
state.tokenUsageEventsError
|
|
1846
2008
|
? `<div class="p-4">${renderError(
|
|
@@ -1850,8 +2012,10 @@
|
|
|
1850
2012
|
: ""
|
|
1851
2013
|
}
|
|
1852
2014
|
${renderTokenUsageEventsTable(eventsPage)}
|
|
2015
|
+
${renderCollapseBodyEnd()}
|
|
1853
2016
|
</div>
|
|
1854
2017
|
</div>
|
|
2018
|
+
${renderCollapseBodyEnd()}
|
|
1855
2019
|
</section>
|
|
1856
2020
|
`;
|
|
1857
2021
|
}
|
|
@@ -2298,7 +2462,7 @@
|
|
|
2298
2462
|
const name = formatCellText(by === "session" ? model.session_id : model.model);
|
|
2299
2463
|
return `
|
|
2300
2464
|
<tr class="border-b last:border-b-0" style="border-color: var(--color-bg-light-1);">
|
|
2301
|
-
<td class="px-4 py-2
|
|
2465
|
+
<td class="px-4 py-2 truncate${by === "session" ? " font-mono" : ""}" style="color: var(--color-fg-lightest);" title="${escapeHtml(
|
|
2302
2466
|
name
|
|
2303
2467
|
)}">${escapeHtml(name)}</td>
|
|
2304
2468
|
<td class="px-4 py-2 text-right" style="color: var(--color-fg-dark);">${formatNumber(
|
|
@@ -2331,11 +2495,11 @@
|
|
|
2331
2495
|
.join("");
|
|
2332
2496
|
|
|
2333
2497
|
return `
|
|
2334
|
-
<div class="overflow-auto ${state.isTokenUsageLoading ? "opacity-60" : ""}">
|
|
2335
|
-
<table class="data-table min-w-[960px] text-left">
|
|
2498
|
+
<div class="overflow-auto [scrollbar-gutter:stable] ${state.isTokenUsageLoading ? "opacity-60" : ""}">
|
|
2499
|
+
<table class="data-table min-w-[960px] table-fixed text-left">
|
|
2336
2500
|
<thead>
|
|
2337
2501
|
<tr>
|
|
2338
|
-
<th class="px-4 py-2 font-semibold">${by === "session" ? "Session" : "Model"}</th>
|
|
2502
|
+
<th class="w-[270px] px-4 py-2 font-semibold">${by === "session" ? "Session" : "Model"}</th>
|
|
2339
2503
|
<th class="px-4 py-2 text-right font-semibold">Requests</th>
|
|
2340
2504
|
<th class="px-4 py-2 text-right font-semibold">Input</th>
|
|
2341
2505
|
<th class="px-4 py-2 text-right font-semibold">Output</th>
|
|
@@ -2817,6 +2981,11 @@
|
|
|
2817
2981
|
void copyModelId(copyButton.dataset.modelCopy);
|
|
2818
2982
|
return;
|
|
2819
2983
|
}
|
|
2984
|
+
const collapseToggle = event.target.closest("[data-collapse-toggle]");
|
|
2985
|
+
if (collapseToggle) {
|
|
2986
|
+
toggleCollapsedSection(collapseToggle);
|
|
2987
|
+
return;
|
|
2988
|
+
}
|
|
2820
2989
|
const detailsButton = event.target.closest("[data-model-details]");
|
|
2821
2990
|
if (detailsButton) {
|
|
2822
2991
|
const details = document.getElementById(
|
|
@@ -2945,6 +3114,7 @@
|
|
|
2945
3114
|
endpointUrlInput.value = initialEndpoint;
|
|
2946
3115
|
migrateLegacyApiKey(initialEndpoint);
|
|
2947
3116
|
syncEndpointCredential();
|
|
3117
|
+
state.collapsedSections = readCollapsedSections();
|
|
2948
3118
|
|
|
2949
3119
|
if (endpointFromUrl) {
|
|
2950
3120
|
void fetchData();
|
package/dist/auth-DuGyJdjW.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-sKq0qru1.js","names":[],"sources":["../src/lib/quick-providers.ts","../src/lib/interactive-prompt.ts","../src/auth.ts"],"sourcesContent":["import type { ProviderType } from \"./config\"\n\ninterface QuickProviderConfig {\n type: ProviderType\n baseUrl: string\n pricingCurrency: string\n editableType: boolean\n}\n\nexport const QUICK_PROVIDER_CONFIGS = {\n \"opencode-go\": {\n type: \"openai-compatible\",\n baseUrl: \"https://opencode.ai/zen/go\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n kimi: {\n type: \"openai-compatible\",\n baseUrl: \"https://api.kimi.com/coding\",\n pricingCurrency: \"USD\",\n editableType: true,\n },\n deepseek: {\n type: \"anthropic\",\n baseUrl: \"https://api.deepseek.com/anthropic\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n dashscope: {\n type: \"openai-compatible\",\n baseUrl: \"https://dashscope.aliyuncs.com/compatible-mode\",\n pricingCurrency: \"CNY\",\n editableType: true,\n },\n openrouter: {\n type: \"anthropic\",\n baseUrl: \"https://openrouter.ai/api\",\n pricingCurrency: \"USD\",\n editableType: false,\n },\n} satisfies Record<string, QuickProviderConfig>\n\nexport type QuickProviderName = keyof typeof QUICK_PROVIDER_CONFIGS\n","import consola from \"consola\"\n\ninterface PromptSelectOption {\n label: string\n value: string\n hint?: string\n}\n\ninterface TextPromptOptions {\n type?: \"text\"\n default?: string\n initial?: string\n placeholder?: string\n}\n\ninterface SelectPromptOptions {\n type: \"select\"\n initial?: string\n options: Array<string | PromptSelectOption>\n}\n\nexport type InteractivePromptOptions = SelectPromptOptions | TextPromptOptions\n\ninterface ClackSelectOptions {\n message: string\n initialValue?: string\n options: Array<PromptSelectOption>\n}\n\ninterface ClackTextOptions {\n message: string\n defaultValue?: string\n initialValue?: string\n placeholder?: string\n}\n\nexport interface ClackPromptBackend {\n isCancel(value: unknown): boolean\n select(options: ClackSelectOptions): Promise<string | symbol>\n text(options: ClackTextOptions): Promise<string | symbol>\n}\n\ninterface PromptRuntime {\n bunVersion?: string\n platform: NodeJS.Platform\n stdinIsTTY?: boolean\n stdoutIsTTY?: boolean\n stdoutIsTTYStream?: boolean\n}\n\n// Consola 3.4.2 bundles a prompt implementation that writes keyboard input to\n// tty fd 0. Bun treats that as a real stdin write on Windows and throws EPIPE.\nexport function shouldUseClackPrompt(\n runtime: PromptRuntime = {\n bunVersion: process.versions.bun,\n platform: process.platform,\n stdinIsTTY: process.stdin.isTTY,\n stdoutIsTTY: process.stdout.isTTY,\n stdoutIsTTYStream: typeof process.stdout.getColorDepth === \"function\",\n },\n): boolean {\n return Boolean(\n runtime.platform === \"win32\"\n && runtime.bunVersion\n && runtime.stdinIsTTY\n && runtime.stdoutIsTTY\n && runtime.stdoutIsTTYStream,\n )\n}\n\nfunction getCancelValue(options: InteractivePromptOptions): string | undefined {\n return options.type === \"select\" ?\n options.initial\n : (options.default ?? options.initial)\n}\n\nexport async function promptWithClack(\n message: string,\n options: InteractivePromptOptions,\n backend: ClackPromptBackend,\n): Promise<string | undefined> {\n if (options.type === \"select\") {\n const value = await backend.select({\n message,\n options: options.options.map((option) =>\n typeof option === \"string\" ? { label: option, value: option } : option,\n ),\n initialValue: options.initial,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n }\n\n const value = await backend.text({\n message,\n defaultValue: options.default,\n initialValue: options.initial,\n placeholder: options.placeholder,\n })\n if (backend.isCancel(value)) {\n return getCancelValue(options)\n }\n return typeof value === \"string\" ? value : undefined\n}\n\nexport async function prompt(\n message: string,\n options: InteractivePromptOptions,\n): Promise<string | undefined> {\n if (!shouldUseClackPrompt()) {\n if (options.type === \"select\") {\n const value = await consola.prompt(message, options)\n return typeof value === \"string\" ? value : undefined\n }\n return await consola.prompt(message, options)\n }\n\n const clack = await import(\"@clack/prompts\")\n return await promptWithClack(message, options, clack)\n}\n","#!/usr/bin/env node\n\nimport { defineCommand } from \"citty\"\nimport consola from \"consola\"\n\nimport {\n getRawProviderConfig,\n isSupportedProviderType,\n normalizeProviderBaseUrl,\n setProviderConfig,\n setConfiguredApiKeys,\n SUPPORTED_PROVIDER_TYPES,\n type ProviderAuthType,\n type ProviderConfig,\n type ProviderType,\n} from \"./lib/config\"\nimport { loginCodex } from \"./lib/oauth/codex\"\nimport { loginXai } from \"./lib/oauth/xai\"\nimport {\n persistXaiCredentials,\n getXaiAccounts,\n selectXaiAccount,\n removeXaiAccount,\n} from \"./lib/xai-token\"\nimport {\n loadModelsDevProviderOptions,\n type ModelsDevProviderOption,\n} from \"./lib/models-dev-cache\"\nimport { PATHS, ensurePaths } from \"./lib/paths\"\nimport { getConfiguredApiKeys } from \"./lib/request-auth\"\nimport {\n QUICK_PROVIDER_CONFIGS,\n type QuickProviderName,\n} from \"./lib/quick-providers\"\nimport { prompt } from \"./lib/interactive-prompt\"\nimport { state } from \"./lib/state\"\nimport {\n getCodexAccounts,\n persistCodexCredentials,\n removeCodexAccount,\n selectCodexAccount,\n setupGitHubToken,\n type CodexAccountSummary,\n} from \"./lib/token\"\n\ninterface RunAuthOptions {\n alias?: string\n provider?: string\n verbose: boolean\n showToken: boolean\n}\n\nconst authArgs = {\n provider: {\n type: \"string\",\n description:\n \"Provider to log in with or configure (copilot, codex, xai, opencode-go, kimi, deepseek, dashscope, openrouter, custom)\",\n },\n alias: {\n type: \"string\",\n description: \"Optional alias for a Codex or xAI account\",\n },\n verbose: {\n alias: \"v\",\n type: \"boolean\",\n default: false,\n description: \"Enable verbose logging\",\n },\n \"show-token\": {\n type: \"boolean\",\n default: false,\n description: \"Show provider access token on auth\",\n },\n} as const\n\nconst BUILTIN_PROVIDER_NAMES = [\"copilot\", \"codex\", \"xai\"] as const\nconst QUICK_PROVIDER_NAMES = Object.keys(\n QUICK_PROVIDER_CONFIGS,\n) as Array<QuickProviderName>\nconst AUTH_PROVIDER_NAMES = [\n ...BUILTIN_PROVIDER_NAMES,\n ...QUICK_PROVIDER_NAMES,\n \"custom\",\n] as const\nconst CUSTOM_PROVIDER_AUTH_TYPE_OPTION = \"__default__\"\nconst QUICK_PROVIDER_DEFAULT_TYPE_OPTION = \"__default__\"\nconst CUSTOM_PROVIDER_AUTH_TYPES = [\"x-api-key\", \"authorization\"] as const\n\ntype BuiltinProviderName = (typeof BUILTIN_PROVIDER_NAMES)[number]\ntype AuthProviderName = (typeof AUTH_PROVIDER_NAMES)[number]\ntype CustomProviderAuthType = (typeof CUSTOM_PROVIDER_AUTH_TYPES)[number]\n\nconst BUILTIN_PROVIDER_LABELS: Record<BuiltinProviderName, string> = {\n copilot: \"GitHub Copilot\",\n codex: \"OpenAI Codex\",\n xai: \"xAI (SuperGrok Subscription)\",\n}\nconst AUTH_PROVIDER_LABELS: Record<AuthProviderName, string> = {\n ...BUILTIN_PROVIDER_LABELS,\n \"opencode-go\": \"OpenCode Go\",\n kimi: \"Kimi\",\n deepseek: \"DeepSeek\",\n dashscope: \"DashScope\",\n openrouter: \"OpenRouter\",\n custom: \"Custom provider\",\n}\n\nfunction isAuthProviderName(\n providerName: string,\n): providerName is AuthProviderName {\n return AUTH_PROVIDER_NAMES.includes(providerName as AuthProviderName)\n}\n\nfunction isCustomProviderAuthType(\n value: string,\n): value is CustomProviderAuthType {\n return CUSTOM_PROVIDER_AUTH_TYPES.includes(value as CustomProviderAuthType)\n}\n\nfunction isQuickProviderName(\n providerName: AuthProviderName,\n): providerName is QuickProviderName {\n return QUICK_PROVIDER_NAMES.includes(providerName as QuickProviderName)\n}\n\nasync function resolveProviderSelection(\n providerArg: string | undefined,\n): Promise<AuthProviderName> {\n const availableProviders = [...AUTH_PROVIDER_NAMES]\n\n if (providerArg !== undefined) {\n const providerName = providerArg.trim()\n if (!isAuthProviderName(providerName)) {\n throw new Error(\n `Unknown provider '${providerArg}'. Expected one of: ${availableProviders.join(\", \")}`,\n )\n }\n return providerName\n }\n\n if (availableProviders.length === 1) {\n return availableProviders[0]\n }\n\n const provider = await prompt(\"Select a provider to log in with\", {\n type: \"select\",\n options: availableProviders.map((providerName) => ({\n label: `${AUTH_PROVIDER_LABELS[providerName]} (${providerName})`,\n value: providerName,\n })),\n })\n\n if (!provider || !isAuthProviderName(provider)) {\n throw new Error(\"No provider selected\")\n }\n\n return provider\n}\n\nfunction assertCustomProviderName(providerName: string): void {\n if (!providerName) {\n throw new Error(\"Provider name must be a non-empty string\")\n }\n\n if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(providerName)) {\n throw new Error(\n \"Provider name must start with a letter or number and contain only letters, numbers, underscores, or hyphens\",\n )\n }\n\n if (\n providerName === \"copilot\"\n || providerName === \"github-copilot\"\n || providerName === \"codex\"\n ) {\n throw new Error(\n `Provider name '${providerName}' is reserved for a builtin provider`,\n )\n }\n}\n\nasync function promptRequiredText(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await prompt(message, { type: \"text\" })\n const normalizedValue = typeof value === \"string\" ? value.trim() : \"\"\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nfunction canUseMaskedPrompt(): boolean {\n return Boolean(\n process.stdin.isTTY\n && process.stdout.isTTY\n && typeof process.stdin.setRawMode === \"function\",\n )\n}\n\nasync function promptMaskedText(message: string): Promise<string> {\n if (!canUseMaskedPrompt()) {\n const value = await prompt(message, { type: \"text\" })\n return typeof value === \"string\" ? value : \"\"\n }\n\n return await new Promise<string>((resolve, reject) => {\n let value = \"\"\n const rawModeWasEnabled = process.stdin.isRaw === true\n\n function cleanup(): void {\n process.stdin.off(\"data\", onData)\n process.stdin.setRawMode(rawModeWasEnabled)\n process.stdin.pause()\n }\n\n function finish(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n resolve(value)\n }\n\n function cancel(): void {\n cleanup()\n process.stdout.write(\"\\n\")\n reject(new Error(\"Prompt cancelled\"))\n }\n\n function onData(chunk: Buffer): void {\n const input = chunk.toString(\"utf8\")\n\n if (input.startsWith(\"\\u001B\")) {\n return\n }\n\n for (const char of input) {\n if (char === \"\\u0003\") {\n cancel()\n return\n }\n\n if (char === \"\\r\" || char === \"\\n\") {\n finish()\n return\n }\n\n if (char === \"\\b\" || char === \"\\u007F\") {\n if (value.length > 0) {\n value = value.slice(0, -1)\n process.stdout.write(\"\\b \\b\")\n }\n continue\n }\n\n if (char >= \" \") {\n value += char\n process.stdout.write(\"*\")\n }\n }\n }\n\n process.stdout.write(`${message}: `)\n process.stdin.setRawMode(true)\n process.stdin.resume()\n process.stdin.on(\"data\", onData)\n })\n}\n\nasync function promptRequiredSecret(\n message: string,\n fieldName: string,\n): Promise<string> {\n const value = await promptMaskedText(message)\n const normalizedValue = value.trim()\n if (!normalizedValue) {\n throw new Error(`${fieldName} must be a non-empty string`)\n }\n return normalizedValue\n}\n\nasync function promptCustomProviderName(defaultName?: string): Promise<string> {\n const value = await prompt(\"Enter provider name\", {\n type: \"text\",\n ...(defaultName ? { default: defaultName, initial: defaultName } : {}),\n })\n const providerName = (value || defaultName || \"\").trim()\n assertCustomProviderName(providerName)\n return providerName\n}\n\nasync function promptCustomProviderType(\n defaultType?: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\"Select provider type\", {\n type: \"select\",\n initial: defaultType,\n options: SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n })\n\n if (\n typeof providerType !== \"string\"\n || !isSupportedProviderType(providerType)\n ) {\n throw new Error(\"No provider type selected\")\n }\n\n return providerType\n}\n\nasync function promptModelsDevProvider(): Promise<\n ModelsDevProviderOption | undefined\n> {\n const source = await prompt(\"Choose custom provider source\", {\n type: \"select\",\n options: [\n { label: \"Enter manually\", value: \"manual\" },\n { label: \"Choose from models.dev\", value: \"models-dev\" },\n ],\n })\n if (source === \"manual\") return undefined\n if (source !== \"models-dev\") throw new Error(\"No provider source selected\")\n\n const providers = await loadModelsDevProviderOptions()\n const query = (\n (await prompt(\"Search models.dev providers (blank to list all)\", {\n type: \"text\",\n })) ?? \"\"\n )\n .trim()\n .toLowerCase()\n const matches = providers.filter(\n (provider) =>\n provider.id.toLowerCase().includes(query)\n || provider.name.toLowerCase().includes(query),\n )\n if (matches.length === 0) {\n throw new Error(\"No matching models.dev providers with a supported API URL\")\n }\n const selectedId = await prompt(\"Select a models.dev provider\", {\n type: \"select\",\n options: matches.map((provider) => ({\n label: `${provider.name} (${provider.id}) — ${provider.type}`,\n value: provider.id,\n })),\n })\n const selectedProvider = matches.find(\n (provider) => provider.id === selectedId,\n )\n if (!selectedProvider) throw new Error(\"No models.dev provider selected\")\n return selectedProvider\n}\n\nasync function promptQuickProviderType(\n defaultType: ProviderType,\n): Promise<ProviderType> {\n const providerType = await prompt(\n `Select provider type (default: ${defaultType})`,\n {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultType})`,\n value: QUICK_PROVIDER_DEFAULT_TYPE_OPTION,\n },\n ...SUPPORTED_PROVIDER_TYPES.map((type) => ({\n label: type,\n value: type,\n })),\n ],\n },\n )\n\n if (providerType === QUICK_PROVIDER_DEFAULT_TYPE_OPTION) {\n return defaultType\n }\n\n if (\n typeof providerType === \"string\"\n && isSupportedProviderType(providerType)\n ) {\n return providerType\n }\n\n throw new Error(\"No provider type selected\")\n}\n\nfunction getDefaultProviderAuthType(\n providerType: ProviderType,\n): ProviderAuthType {\n return providerType === \"anthropic\" ? \"x-api-key\" : \"authorization\"\n}\n\nasync function promptCustomProviderAuthType(\n providerType: ProviderType,\n): Promise<ProviderAuthType | undefined> {\n const defaultAuthType = getDefaultProviderAuthType(providerType)\n const authType = await prompt(\"Select provider auth type\", {\n type: \"select\",\n options: [\n {\n label: `Default (${defaultAuthType})`,\n value: CUSTOM_PROVIDER_AUTH_TYPE_OPTION,\n },\n ...CUSTOM_PROVIDER_AUTH_TYPES.map((value) => ({\n label: value,\n value,\n })),\n ],\n })\n\n if (authType === CUSTOM_PROVIDER_AUTH_TYPE_OPTION) {\n return undefined\n }\n\n if (typeof authType === \"string\" && isCustomProviderAuthType(authType)) {\n return authType\n }\n\n throw new Error(\"No provider auth type selected\")\n}\n\nasync function promptQuickProviderBaseUrl(\n defaultBaseUrl: string,\n): Promise<string> {\n const value = await prompt(\n `Enter provider baseUrl (default: ${defaultBaseUrl})`,\n {\n type: \"text\",\n default: defaultBaseUrl,\n initial: defaultBaseUrl,\n },\n )\n const baseUrl = normalizeProviderBaseUrl(\n typeof value === \"string\" && value.trim() ? value : defaultBaseUrl,\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n return baseUrl\n}\n\nfunction buildCustomProviderConfig(\n existingProviderConfig: ProviderConfig,\n options: {\n apiKey: string\n authType?: ProviderAuthType\n baseUrl: string\n pricingCurrency?: string\n type: ProviderType\n modelsDevProviderId?: string\n },\n): ProviderConfig {\n return {\n type: options.type,\n enabled: true,\n baseUrl: options.baseUrl,\n ...(options.modelsDevProviderId && {\n modelsDevProviderId: options.modelsDevProviderId,\n }),\n apiKey: options.apiKey,\n ...(options.authType ? { authType: options.authType } : {}),\n pricingCurrency:\n options.pricingCurrency ?? existingProviderConfig.pricingCurrency,\n ...(existingProviderConfig.agentsModels !== undefined ?\n { agentsModels: existingProviderConfig.agentsModels }\n : {}),\n ...(existingProviderConfig.models ?\n { models: existingProviderConfig.models }\n : {}),\n }\n}\n\nasync function configureCustomProvider(): Promise<void> {\n const catalogProvider = await promptModelsDevProvider()\n const providerName = await promptCustomProviderName(catalogProvider?.id)\n const type = await promptCustomProviderType(catalogProvider?.type)\n const baseUrl =\n catalogProvider ?\n await promptQuickProviderBaseUrl(catalogProvider.api)\n : normalizeProviderBaseUrl(\n await promptRequiredText(\"Enter provider baseUrl\", \"baseUrl\"),\n )\n if (!baseUrl) {\n throw new Error(\"baseUrl must be a non-empty string\")\n }\n\n const apiKey = await promptRequiredSecret(\"Enter provider apiKey\", \"apiKey\")\n const authType = await promptCustomProviderAuthType(type)\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n authType,\n baseUrl,\n modelsDevProviderId: catalogProvider?.id,\n type,\n }),\n )\n\n consola.success(\n `Custom provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function configureQuickProvider(\n providerName: QuickProviderName,\n): Promise<void> {\n const defaultProviderConfig = QUICK_PROVIDER_CONFIGS[providerName]\n const apiKey = await promptRequiredSecret(\n `Enter ${providerName} apiKey`,\n \"apiKey\",\n )\n const type =\n defaultProviderConfig.editableType ?\n await promptQuickProviderType(defaultProviderConfig.type)\n : defaultProviderConfig.type\n const baseUrl = await promptQuickProviderBaseUrl(\n defaultProviderConfig.baseUrl,\n )\n const existingProviderConfig = getRawProviderConfig(providerName) ?? {}\n\n setProviderConfig(\n providerName,\n buildCustomProviderConfig(existingProviderConfig, {\n apiKey,\n baseUrl,\n pricingCurrency: defaultProviderConfig.pricingCurrency,\n type,\n }),\n )\n\n consola.success(\n `${AUTH_PROVIDER_LABELS[providerName]} provider '${providerName}' written to ${PATHS.CONFIG_PATH}`,\n )\n}\n\nasync function loginWithCodex(alias?: string): Promise<void> {\n const credentials = await loginCodex({\n onAuth(info) {\n consola.info(\"Open the following URL to authenticate with Codex:\")\n consola.log(info.url)\n if (info.instructions) {\n consola.info(info.instructions)\n }\n },\n onPrompt(message) {\n return prompt(message, { type: \"text\" }).then((value) => value ?? \"\")\n },\n onProgress(message) {\n consola.debug(message)\n },\n })\n\n await persistCodexCredentials(credentials, {\n activateAccount: true,\n alias,\n enableProvider: true,\n })\n consola.success(\n `Codex provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.CODEX_CREDENTIAL_PATH}`,\n )\n}\n\nasync function loginWithProvider(\n provider: AuthProviderName,\n alias?: string,\n): Promise<void> {\n if (alias !== undefined && provider !== \"codex\" && provider !== \"xai\") {\n throw new Error(\"--alias is only supported with the codex or xai provider\")\n }\n\n if (provider === \"copilot\") {\n await setupGitHubToken({ force: true })\n consola.success(\"GitHub token written to\", PATHS.GITHUB_TOKEN_PATH)\n return\n }\n\n if (provider === \"codex\") {\n await loginWithCodex(alias)\n return\n }\n\n if (provider === \"xai\") {\n const credentials = await loginXai({\n onAuth(info) {\n consola.info(\"Open the following URL to authenticate with xAI:\")\n consola.log(info.url)\n consola.info(\n `Open ${info.verificationUri} on any device and enter code: ${info.userCode}`,\n )\n },\n })\n await persistXaiCredentials(credentials, { alias })\n consola.success(\n `xAI provider config written to ${PATHS.CONFIG_PATH} and credentials written to ${PATHS.XAI_CREDENTIAL_PATH}`,\n )\n return\n }\n\n if (isQuickProviderName(provider)) {\n await configureQuickProvider(provider)\n return\n }\n\n await configureCustomProvider()\n}\n\nexport async function runProviderSetup(): Promise<void> {\n const provider = await resolveProviderSelection(undefined)\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider)\n}\n\nexport async function runAuthLogin(options: RunAuthOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n if (options.verbose) {\n consola.level = 5\n consola.info(\"Verbose logging enabled\")\n }\n\n state.showToken = options.showToken\n\n await ensurePaths()\n const provider = await resolveProviderSelection(options.provider)\n\n consola.info(`Logging in with ${AUTH_PROVIDER_LABELS[provider]}`)\n await loginWithProvider(provider, options.alias)\n}\n\nconst authAccountArgs = {\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List stored OAuth accounts\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description:\n \"Remove an OAuth account by alias or account id; the account in use cannot be removed\",\n },\n use: {\n alias: \"u\",\n type: \"string\",\n description: \"Select an OAuth account by alias or account id\",\n },\n} as const\n\ninterface RunAuthAccountsOptions {\n list?: boolean\n remove?: string\n use?: string\n}\n\nfunction formatOAuthAccountName(\n account: Pick<CodexAccountSummary, \"accountId\" | \"alias\">,\n): string {\n return account.alias ?\n `${account.alias} (${account.accountId})`\n : account.accountId\n}\n\nfunction formatOAuthAccount(account: CodexAccountSummary): string {\n return `${account.active ? \"*\" : \"-\"} ${formatOAuthAccountName(account)}`\n}\n\nexport async function runAuthCodex(\n options: RunAuthAccountsOptions,\n): Promise<void> {\n return await runAuthAccounts(\"codex\", options)\n}\n\nexport async function runAuthAccounts(\n provider: \"codex\" | \"xai\",\n options: RunAuthAccountsOptions,\n): Promise<void> {\n const label = provider === \"codex\" ? \"Codex\" : \"xAI\"\n const accountsApi =\n provider === \"codex\" ?\n {\n list: getCodexAccounts,\n select: selectCodexAccount,\n remove: removeCodexAccount,\n }\n : {\n list: getXaiAccounts,\n select: selectXaiAccount,\n remove: removeXaiAccount,\n }\n await ensurePaths()\n\n const operationCount = [\n options.list === true,\n options.use !== undefined,\n options.remove !== undefined,\n ].filter(Boolean).length\n if (operationCount > 1) {\n throw new Error(\"Use only one of --list, --use, or --remove per invocation\")\n }\n\n if (options.use !== undefined) {\n const account = await accountsApi.select(options.use)\n consola.success(\n `Selected ${label} account ${formatOAuthAccountName(account)}`,\n )\n consola.info(`Restart the server to use the selected ${label} account.`)\n return\n }\n\n if (options.remove !== undefined) {\n const account = await accountsApi.remove(options.remove)\n consola.success(\n `Removed ${label} account ${formatOAuthAccountName(account)}`,\n )\n return\n }\n\n const accounts = await accountsApi.list()\n if (accounts.length === 0) {\n consola.info(\n `No ${label} accounts configured. Run \\`copilot-api auth login --provider ${provider}\\` to add one.`,\n )\n return\n }\n\n consola.info(`Configured ${label} accounts:`)\n for (const account of accounts) {\n consola.info(formatOAuthAccount(account))\n }\n}\n\nconst authKeysArgs = {\n add: {\n alias: \"a\",\n type: \"string\",\n description: \"Add an API key for gateway authentication\",\n },\n remove: {\n alias: \"r\",\n type: \"string\",\n description: \"Remove an API key\",\n },\n list: {\n alias: \"l\",\n type: \"boolean\",\n default: false,\n description: \"List configured API keys\",\n },\n clear: {\n type: \"boolean\",\n default: false,\n description: \"Remove all configured API keys\",\n },\n} as const\n\ninterface RunAuthKeysOptions {\n add?: string\n remove?: string\n list?: boolean\n clear?: boolean\n}\n\nfunction normalizeAuthKeyValue(value: string): string {\n const normalizedKey = value.trim()\n if (!normalizedKey) {\n throw new Error(\"API key must be a non-empty string\")\n }\n return normalizedKey\n}\n\nexport async function runAuthKeys(options: RunAuthKeysOptions): Promise<void> {\n const tlsModule = await import(\"./lib/tls\")\n tlsModule.enableSystemCACompat()\n\n await ensurePaths()\n\n const operations = [\n ...(options.add !== undefined ? [\"add\"] : []),\n ...(options.remove !== undefined ? [\"remove\"] : []),\n ...(options.list ? [\"list\"] : []),\n ...(options.clear ? [\"clear\"] : []),\n ]\n if (operations.length > 1) {\n throw new Error(\n \"Use only one of --add, --remove, --list, or --clear per invocation\",\n )\n }\n\n const operation = operations[0] ?? \"list\"\n\n if (operation === \"add\") {\n const apiKey = normalizeAuthKeyValue(options.add ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.includes(apiKey)) {\n consola.info(\n `API key already configured. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys([...currentKeys, apiKey])\n consola.success(\n `API key added to ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"remove\") {\n const apiKey = normalizeAuthKeyValue(options.remove ?? \"\")\n const currentKeys = getConfiguredApiKeys()\n if (!currentKeys.includes(apiKey)) {\n consola.info(\n `API key not found. ${currentKeys.length} API key(s) configured.`,\n )\n return\n }\n const storedKeys = setConfiguredApiKeys(\n currentKeys.filter((key) => key !== apiKey),\n )\n consola.success(\n `API key removed from ${PATHS.CONFIG_PATH}. ${storedKeys.length} API key(s) configured.`,\n )\n return\n }\n\n if (operation === \"clear\") {\n setConfiguredApiKeys([])\n consola.success(`Removed all API keys from ${PATHS.CONFIG_PATH}.`)\n return\n }\n\n const currentKeys = getConfiguredApiKeys()\n if (currentKeys.length === 0) {\n consola.info(\n \"No API keys configured. Run `npx @jeffreycao/copilot-api@latest auth keys --add <key>` to add one.\",\n )\n return\n }\n consola.info(\"Configured API keys:\")\n for (const key of currentKeys) {\n consola.info(`- ${key}`)\n }\n}\n\nconst authLogin = defineCommand({\n meta: {\n name: \"login\",\n description:\n \"Authenticate or configure a provider without running the server\",\n },\n args: authArgs,\n run({ args }) {\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n\nconst authKeys = defineCommand({\n meta: {\n name: \"keys\",\n description: \"Manage gateway API keys (auth.apiKeys) in the config\",\n },\n args: authKeysArgs,\n run({ args }) {\n return runAuthKeys({\n add: args.add,\n remove: args.remove,\n list: args.list,\n clear: args.clear,\n })\n },\n})\n\nconst authCodex = defineCommand({\n meta: {\n name: \"codex\",\n description: \"List, select, or remove stored Codex accounts\",\n },\n args: authAccountArgs,\n run({ args }) {\n return runAuthCodex({\n list: args.list,\n remove: args.remove,\n use: args.use,\n })\n },\n})\n\nexport const auth = defineCommand({\n meta: {\n name: \"auth\",\n description: \"Run authentication flows without running the server\",\n },\n args: authArgs,\n subCommands: {\n codex: authCodex,\n xai: defineCommand({\n meta: { name: \"xai\", description: \"Manage stored xAI accounts\" },\n args: authAccountArgs,\n run({ args }) {\n return runAuthAccounts(\"xai\", {\n list: args.list,\n remove: args.remove,\n use: args.use,\n })\n },\n }),\n login: authLogin,\n keys: authKeys,\n },\n run({ args }) {\n if ((args._[0] ?? \"\").trim()) {\n return\n }\n\n return runAuthLogin({\n alias: args.alias,\n provider: args.provider,\n verbose: args.verbose,\n showToken: args[\"show-token\"],\n })\n },\n})\n"],"mappings":"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"}
|