@expiren/opencode-antigravity-auth 1.6.17 → 1.6.18
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/dist/index.js +583 -59
- package/dist/index.js.map +4 -4
- package/dist/src/constants.d.ts +13 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +19 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/plugin/auth-doctor.d.ts +30 -0
- package/dist/src/plugin/auth-doctor.d.ts.map +1 -0
- package/dist/src/plugin/auth-doctor.js +144 -0
- package/dist/src/plugin/auth-doctor.js.map +1 -0
- package/dist/src/plugin/auth-drift.d.ts +13 -0
- package/dist/src/plugin/auth-drift.d.ts.map +1 -0
- package/dist/src/plugin/auth-drift.js +70 -0
- package/dist/src/plugin/auth-drift.js.map +1 -0
- package/dist/src/plugin/cli.d.ts +11 -2
- package/dist/src/plugin/cli.d.ts.map +1 -1
- package/dist/src/plugin/cli.js +31 -3
- package/dist/src/plugin/cli.js.map +1 -1
- package/dist/src/plugin/config/models.d.ts +2 -32
- package/dist/src/plugin/config/models.d.ts.map +1 -1
- package/dist/src/plugin/config/models.js +1 -113
- package/dist/src/plugin/config/models.js.map +1 -1
- package/dist/src/plugin/config/schema.js +2 -2
- package/dist/src/plugin/config/schema.js.map +1 -1
- package/dist/src/plugin/model-registry.d.ts +46 -0
- package/dist/src/plugin/model-registry.d.ts.map +1 -0
- package/dist/src/plugin/model-registry.js +180 -0
- package/dist/src/plugin/model-registry.js.map +1 -0
- package/dist/src/plugin/quota.d.ts +1 -0
- package/dist/src/plugin/quota.d.ts.map +1 -1
- package/dist/src/plugin/quota.js +8 -5
- package/dist/src/plugin/quota.js.map +1 -1
- package/dist/src/plugin/request.d.ts.map +1 -1
- package/dist/src/plugin/request.js +8 -5
- package/dist/src/plugin/request.js.map +1 -1
- package/dist/src/plugin/transform/model-resolver.d.ts.map +1 -1
- package/dist/src/plugin/transform/model-resolver.js +4 -26
- package/dist/src/plugin/transform/model-resolver.js.map +1 -1
- package/dist/src/plugin/ui/auth-menu.d.ts +25 -1
- package/dist/src/plugin/ui/auth-menu.d.ts.map +1 -1
- package/dist/src/plugin/ui/auth-menu.js +64 -13
- package/dist/src/plugin/ui/auth-menu.js.map +1 -1
- package/dist/src/plugin/ui/quota-status.d.ts +67 -0
- package/dist/src/plugin/ui/quota-status.d.ts.map +1 -0
- package/dist/src/plugin/ui/quota-status.js +194 -0
- package/dist/src/plugin/ui/quota-status.js.map +1 -0
- package/dist/src/plugin/version.d.ts +8 -1
- package/dist/src/plugin/version.d.ts.map +1 -1
- package/dist/src/plugin/version.js +8 -1
- package/dist/src/plugin/version.js.map +1 -1
- package/dist/src/plugin.d.ts.map +1 -1
- package/dist/src/plugin.js +66 -5
- package/dist/src/plugin.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -66,6 +66,14 @@ var ANTIGRAVITY_HEADERS = {
|
|
|
66
66
|
"X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
|
67
67
|
"Client-Metadata": `{"ideType":"ANTIGRAVITY","platform":"${process.platform === "win32" ? "WINDOWS" : "MACOS"}","pluginType":"GEMINI"}`
|
|
68
68
|
};
|
|
69
|
+
var GEMINI_CLI_VERSION = "1.0.0";
|
|
70
|
+
var GEMINI_CLI_DEFAULT_MODEL = "gemini-2.5-pro";
|
|
71
|
+
function buildGeminiCliUserAgent(model) {
|
|
72
|
+
const effectiveModel = model || GEMINI_CLI_DEFAULT_MODEL;
|
|
73
|
+
const platform = process.platform || "darwin";
|
|
74
|
+
const arch = process.arch || "arm64";
|
|
75
|
+
return `GeminiCLI/${GEMINI_CLI_VERSION}/${effectiveModel} (${platform}; ${arch})`;
|
|
76
|
+
}
|
|
69
77
|
var GEMINI_CLI_HEADERS = {
|
|
70
78
|
"User-Agent": "google-api-nodejs-client/9.15.1",
|
|
71
79
|
"X-Goog-Api-Client": "gl-node/22.17.0",
|
|
@@ -83,7 +91,7 @@ function randomFrom(arr) {
|
|
|
83
91
|
function getRandomizedHeaders(style, model) {
|
|
84
92
|
if (style === "gemini-cli") {
|
|
85
93
|
return {
|
|
86
|
-
"User-Agent":
|
|
94
|
+
"User-Agent": buildGeminiCliUserAgent(model),
|
|
87
95
|
"X-Goog-Api-Client": GEMINI_CLI_HEADERS["X-Goog-Api-Client"],
|
|
88
96
|
"Client-Metadata": GEMINI_CLI_HEADERS["Client-Metadata"]
|
|
89
97
|
};
|
|
@@ -1574,6 +1582,129 @@ async function confirm(message, defaultYes = false) {
|
|
|
1574
1582
|
return result ?? false;
|
|
1575
1583
|
}
|
|
1576
1584
|
|
|
1585
|
+
// src/plugin/ui/quota-status.ts
|
|
1586
|
+
function formatWaitDuration(ms) {
|
|
1587
|
+
if (ms < 1e3) return `${ms}ms`;
|
|
1588
|
+
const seconds = Math.ceil(ms / 1e3);
|
|
1589
|
+
if (seconds < 60) return `${seconds}s`;
|
|
1590
|
+
const minutes = Math.floor(seconds / 60);
|
|
1591
|
+
const remainingSeconds = seconds % 60;
|
|
1592
|
+
if (minutes < 60) {
|
|
1593
|
+
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
|
|
1594
|
+
}
|
|
1595
|
+
const hours = Math.floor(minutes / 60);
|
|
1596
|
+
const remainingMinutes = minutes % 60;
|
|
1597
|
+
return remainingMinutes > 0 ? `${hours}h ${remainingMinutes}m` : `${hours}h`;
|
|
1598
|
+
}
|
|
1599
|
+
function classifyGroupStatus(group) {
|
|
1600
|
+
if (!group) {
|
|
1601
|
+
return { label: "READY" };
|
|
1602
|
+
}
|
|
1603
|
+
const remaining = group.remainingFraction;
|
|
1604
|
+
if (typeof remaining !== "number" || !Number.isFinite(remaining)) {
|
|
1605
|
+
return { label: "READY" };
|
|
1606
|
+
}
|
|
1607
|
+
if (remaining <= 0) {
|
|
1608
|
+
const waitMs = parseResetTimeToMs(group.resetTime);
|
|
1609
|
+
if (waitMs !== null && waitMs > 0) {
|
|
1610
|
+
return { label: "EXHAUSTED", waitMs };
|
|
1611
|
+
}
|
|
1612
|
+
return { label: "EXHAUSTED" };
|
|
1613
|
+
}
|
|
1614
|
+
if (remaining < 0.2) {
|
|
1615
|
+
return { label: "LOW" };
|
|
1616
|
+
}
|
|
1617
|
+
return { label: "READY" };
|
|
1618
|
+
}
|
|
1619
|
+
function parseResetTimeToMs(resetTime) {
|
|
1620
|
+
if (!resetTime) return null;
|
|
1621
|
+
const timestamp = Date.parse(resetTime);
|
|
1622
|
+
if (!Number.isFinite(timestamp)) return null;
|
|
1623
|
+
const ms = timestamp - Date.now();
|
|
1624
|
+
return ms > 0 ? ms : null;
|
|
1625
|
+
}
|
|
1626
|
+
function buildCooldownStatus(cooldownMs, reason) {
|
|
1627
|
+
return {
|
|
1628
|
+
label: "COOLDOWN",
|
|
1629
|
+
waitMs: cooldownMs > 0 ? cooldownMs : void 0,
|
|
1630
|
+
cooldownReason: reason
|
|
1631
|
+
};
|
|
1632
|
+
}
|
|
1633
|
+
function formatQuotaStatusBadge(status) {
|
|
1634
|
+
switch (status.label) {
|
|
1635
|
+
case "READY":
|
|
1636
|
+
return `${ANSI.green}[READY]${ANSI.reset}`;
|
|
1637
|
+
case "LOW":
|
|
1638
|
+
return `${ANSI.yellow}[LOW]${ANSI.reset}`;
|
|
1639
|
+
case "WAIT": {
|
|
1640
|
+
const suffix = status.waitMs ? ` ${formatWaitDuration(status.waitMs)}` : "";
|
|
1641
|
+
return `${ANSI.yellow}[WAIT${suffix}]${ANSI.reset}`;
|
|
1642
|
+
}
|
|
1643
|
+
case "EXHAUSTED": {
|
|
1644
|
+
const suffix = status.waitMs ? ` resets in ${formatWaitDuration(status.waitMs)}` : "";
|
|
1645
|
+
return `${ANSI.red}[EXHAUSTED${suffix}]${ANSI.reset}`;
|
|
1646
|
+
}
|
|
1647
|
+
case "COOLDOWN": {
|
|
1648
|
+
const parts = ["COOLDOWN"];
|
|
1649
|
+
if (status.cooldownReason) {
|
|
1650
|
+
parts.push(status.cooldownReason);
|
|
1651
|
+
}
|
|
1652
|
+
if (status.waitMs) {
|
|
1653
|
+
parts.push(formatWaitDuration(status.waitMs));
|
|
1654
|
+
}
|
|
1655
|
+
return `${ANSI.red}[${parts.join(" ")}]${ANSI.reset}`;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
function formatQuotaStatusPlain(status) {
|
|
1660
|
+
switch (status.label) {
|
|
1661
|
+
case "READY":
|
|
1662
|
+
return "READY";
|
|
1663
|
+
case "LOW":
|
|
1664
|
+
return "LOW";
|
|
1665
|
+
case "WAIT": {
|
|
1666
|
+
const suffix = status.waitMs ? ` ${formatWaitDuration(status.waitMs)}` : "";
|
|
1667
|
+
return `WAIT${suffix}`;
|
|
1668
|
+
}
|
|
1669
|
+
case "EXHAUSTED": {
|
|
1670
|
+
const suffix = status.waitMs ? ` resets in ${formatWaitDuration(status.waitMs)}` : "";
|
|
1671
|
+
return `EXHAUSTED${suffix}`;
|
|
1672
|
+
}
|
|
1673
|
+
case "COOLDOWN": {
|
|
1674
|
+
const parts = ["COOLDOWN"];
|
|
1675
|
+
if (status.cooldownReason) {
|
|
1676
|
+
parts.push(status.cooldownReason);
|
|
1677
|
+
}
|
|
1678
|
+
if (status.waitMs) {
|
|
1679
|
+
parts.push(formatWaitDuration(status.waitMs));
|
|
1680
|
+
}
|
|
1681
|
+
return parts.join(" ");
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
function formatCachedQuotaWithStatus(cachedQuota) {
|
|
1686
|
+
if (!cachedQuota) {
|
|
1687
|
+
return void 0;
|
|
1688
|
+
}
|
|
1689
|
+
const entries = [
|
|
1690
|
+
{ key: "claude", label: "Claude" },
|
|
1691
|
+
{ key: "gemini-pro", label: "Gemini Pro" },
|
|
1692
|
+
{ key: "gemini-flash", label: "Gemini Flash" }
|
|
1693
|
+
].flatMap(({ key, label }) => {
|
|
1694
|
+
const value = cachedQuota[key]?.remainingFraction;
|
|
1695
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
1696
|
+
return [];
|
|
1697
|
+
}
|
|
1698
|
+
const pct = Math.round(Math.max(0, Math.min(1, value)) * 100);
|
|
1699
|
+
const status = classifyGroupStatus(cachedQuota[key]);
|
|
1700
|
+
if (status.label === "READY") {
|
|
1701
|
+
return [`${label} ${pct}%`];
|
|
1702
|
+
}
|
|
1703
|
+
return [`${label} ${formatQuotaStatusPlain(status)} ${pct}%`];
|
|
1704
|
+
});
|
|
1705
|
+
return entries.length > 0 ? entries.join(", ") : void 0;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1577
1708
|
// src/plugin/ui/auth-menu.ts
|
|
1578
1709
|
function formatRelativeTime(timestamp) {
|
|
1579
1710
|
if (!timestamp) return "never";
|
|
@@ -1588,16 +1719,20 @@ function formatDate(timestamp) {
|
|
|
1588
1719
|
if (!timestamp) return "unknown";
|
|
1589
1720
|
return new Date(timestamp).toLocaleDateString();
|
|
1590
1721
|
}
|
|
1591
|
-
function getStatusBadge(status) {
|
|
1722
|
+
function getStatusBadge(status, account) {
|
|
1723
|
+
if (account?.cooldownMs !== void 0 && account.cooldownMs > 0) {
|
|
1724
|
+
const cooldownStatus = buildCooldownStatus(account.cooldownMs, account.cooldownReason);
|
|
1725
|
+
return ` ${formatQuotaStatusBadge(cooldownStatus)}`;
|
|
1726
|
+
}
|
|
1592
1727
|
switch (status) {
|
|
1593
1728
|
case "active":
|
|
1594
|
-
return
|
|
1729
|
+
return ` ${ANSI.green}[active]${ANSI.reset}`;
|
|
1595
1730
|
case "rate-limited":
|
|
1596
|
-
return
|
|
1731
|
+
return ` ${ANSI.yellow}[rate-limited]${ANSI.reset}`;
|
|
1597
1732
|
case "expired":
|
|
1598
|
-
return
|
|
1733
|
+
return ` ${ANSI.red}[expired]${ANSI.reset}`;
|
|
1599
1734
|
case "verification-required":
|
|
1600
|
-
return
|
|
1735
|
+
return ` ${ANSI.red}[needs verification]${ANSI.reset}`;
|
|
1601
1736
|
default:
|
|
1602
1737
|
return "";
|
|
1603
1738
|
}
|
|
@@ -1606,22 +1741,25 @@ async function showAuthMenu(accounts) {
|
|
|
1606
1741
|
const items = [
|
|
1607
1742
|
{ label: "Actions", value: { type: "cancel" }, kind: "heading" },
|
|
1608
1743
|
{ label: "Add account", value: { type: "add" }, color: "cyan" },
|
|
1744
|
+
{ label: "Auth current", value: { type: "current" }, color: "cyan" },
|
|
1609
1745
|
{ label: "Check quotas", value: { type: "check" }, color: "cyan" },
|
|
1746
|
+
{ label: "Repair auth", value: { type: "repair" }, color: "yellow" },
|
|
1747
|
+
{ label: "Auth doctor", value: { type: "doctor" }, color: "cyan" },
|
|
1610
1748
|
{ label: "Verify one account", value: { type: "verify" }, color: "cyan" },
|
|
1611
1749
|
{ label: "Verify all accounts", value: { type: "verify-all" }, color: "cyan" },
|
|
1612
1750
|
{ label: "Configure models in opencode.json", value: { type: "configure-models" }, color: "cyan" },
|
|
1613
1751
|
{ label: "", value: { type: "cancel" }, separator: true },
|
|
1614
1752
|
{ label: "Accounts", value: { type: "cancel" }, kind: "heading" },
|
|
1615
1753
|
...accounts.map((account) => {
|
|
1616
|
-
const statusBadge = getStatusBadge(account.status);
|
|
1754
|
+
const statusBadge = getStatusBadge(account.status, account);
|
|
1617
1755
|
const currentBadge = account.isCurrentAccount ? ` ${ANSI.cyan}[current]${ANSI.reset}` : "";
|
|
1618
1756
|
const disabledBadge = account.enabled === false ? ` ${ANSI.red}[disabled]${ANSI.reset}` : "";
|
|
1619
1757
|
const baseLabel = account.email || `Account ${account.index + 1}`;
|
|
1620
1758
|
const numbered = `${account.index + 1}. ${baseLabel}`;
|
|
1621
|
-
const fullLabel = `${numbered}${currentBadge}${statusBadge
|
|
1759
|
+
const fullLabel = `${numbered}${currentBadge}${statusBadge}${disabledBadge}`;
|
|
1622
1760
|
return {
|
|
1623
1761
|
label: fullLabel,
|
|
1624
|
-
hint: account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : "",
|
|
1762
|
+
hint: account.quotaSummary ?? (account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : ""),
|
|
1625
1763
|
value: { type: "select-account", account }
|
|
1626
1764
|
};
|
|
1627
1765
|
}),
|
|
@@ -1643,23 +1781,69 @@ async function showAuthMenu(accounts) {
|
|
|
1643
1781
|
return result;
|
|
1644
1782
|
}
|
|
1645
1783
|
}
|
|
1784
|
+
function formatFingerprintReason(reason) {
|
|
1785
|
+
switch (reason) {
|
|
1786
|
+
case "initial":
|
|
1787
|
+
return "initial";
|
|
1788
|
+
case "regenerated":
|
|
1789
|
+
return "regenerated";
|
|
1790
|
+
case "restored":
|
|
1791
|
+
return "restored";
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
async function showFingerprintHistory(history, accountLabel) {
|
|
1795
|
+
const items = [
|
|
1796
|
+
{ label: "Back", value: null },
|
|
1797
|
+
{ label: "", value: null, separator: true },
|
|
1798
|
+
{ label: "Fingerprint history", value: null, kind: "heading" },
|
|
1799
|
+
...history.map((entry, index) => {
|
|
1800
|
+
const deviceShort = entry.deviceId.slice(0, 8);
|
|
1801
|
+
const reasonBadge = `${ANSI.dim}[${formatFingerprintReason(entry.reason)}]${ANSI.reset}`;
|
|
1802
|
+
const label = `${index + 1}. ${deviceShort}... ${reasonBadge}`;
|
|
1803
|
+
const hint = formatRelativeTime(entry.timestamp);
|
|
1804
|
+
return {
|
|
1805
|
+
label,
|
|
1806
|
+
hint,
|
|
1807
|
+
value: index,
|
|
1808
|
+
color: "cyan"
|
|
1809
|
+
};
|
|
1810
|
+
})
|
|
1811
|
+
];
|
|
1812
|
+
const result = await select(items, {
|
|
1813
|
+
message: `Restore fingerprint \u2014 ${accountLabel}`,
|
|
1814
|
+
subtitle: "Select a previous fingerprint to restore",
|
|
1815
|
+
clearScreen: true
|
|
1816
|
+
});
|
|
1817
|
+
return result ?? null;
|
|
1818
|
+
}
|
|
1646
1819
|
async function showAccountDetails(account) {
|
|
1647
1820
|
const label = account.email || `Account ${account.index + 1}`;
|
|
1648
|
-
const badge = getStatusBadge(account.status);
|
|
1821
|
+
const badge = getStatusBadge(account.status, account);
|
|
1649
1822
|
const disabledBadge = account.enabled === false ? ` ${ANSI.red}[disabled]${ANSI.reset}` : "";
|
|
1650
|
-
const header = `${label}${badge
|
|
1823
|
+
const header = `${label}${badge}${disabledBadge}`;
|
|
1651
1824
|
const subtitleParts = [
|
|
1652
1825
|
`Added: ${formatDate(account.addedAt)}`,
|
|
1653
1826
|
`Last used: ${formatRelativeTime(account.lastUsed)}`
|
|
1654
1827
|
];
|
|
1828
|
+
const hasHistory = (account.fingerprintHistory?.length ?? 0) > 0;
|
|
1655
1829
|
while (true) {
|
|
1656
|
-
const
|
|
1830
|
+
const menuItems = [
|
|
1657
1831
|
{ label: "Back", value: "back" },
|
|
1658
1832
|
{ label: "Verify account access", value: "verify", color: "cyan" },
|
|
1659
1833
|
{ label: account.enabled === false ? "Enable account" : "Disable account", value: "toggle", color: account.enabled === false ? "green" : "yellow" },
|
|
1660
|
-
{ label: "Refresh token", value: "refresh", color: "cyan" }
|
|
1834
|
+
{ label: "Refresh token", value: "refresh", color: "cyan" }
|
|
1835
|
+
];
|
|
1836
|
+
if (hasHistory) {
|
|
1837
|
+
menuItems.push({
|
|
1838
|
+
label: `Restore fingerprint (${account.fingerprintHistory.length} saved)`,
|
|
1839
|
+
value: "restore-fingerprint",
|
|
1840
|
+
color: "cyan"
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
menuItems.push(
|
|
1661
1844
|
{ label: "Delete this account", value: "delete", color: "red" }
|
|
1662
|
-
|
|
1845
|
+
);
|
|
1846
|
+
const result = await select(menuItems, {
|
|
1663
1847
|
message: header,
|
|
1664
1848
|
subtitle: subtitleParts.join(" | "),
|
|
1665
1849
|
clearScreen: true
|
|
@@ -1681,12 +1865,14 @@ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync
|
|
|
1681
1865
|
import { join as join3, dirname as dirname2 } from "node:path";
|
|
1682
1866
|
import { homedir as homedir3 } from "node:os";
|
|
1683
1867
|
|
|
1684
|
-
// src/plugin/
|
|
1868
|
+
// src/plugin/model-registry.ts
|
|
1685
1869
|
var DEFAULT_MODALITIES = {
|
|
1686
1870
|
input: ["text", "image", "pdf"],
|
|
1687
1871
|
output: ["text"]
|
|
1688
1872
|
};
|
|
1689
1873
|
var MODEL_RELEASE_DATE = "";
|
|
1874
|
+
var DEFAULT_COST = { input: 0, output: 0 };
|
|
1875
|
+
var DEFAULT_OPTIONS = {};
|
|
1690
1876
|
function defineModel(id, model) {
|
|
1691
1877
|
return {
|
|
1692
1878
|
id,
|
|
@@ -1694,10 +1880,12 @@ function defineModel(id, model) {
|
|
|
1694
1880
|
attachment: model.modalities.input.some((modality) => modality !== "text"),
|
|
1695
1881
|
temperature: true,
|
|
1696
1882
|
tool_call: true,
|
|
1883
|
+
cost: { ...DEFAULT_COST },
|
|
1884
|
+
options: { ...DEFAULT_OPTIONS },
|
|
1697
1885
|
...model
|
|
1698
1886
|
};
|
|
1699
1887
|
}
|
|
1700
|
-
var
|
|
1888
|
+
var PUBLIC_MODEL_DEFINITIONS = {
|
|
1701
1889
|
"antigravity-gemini-3.1-pro": defineModel("antigravity-gemini-3.1-pro", {
|
|
1702
1890
|
name: "Gemini 3.1 Pro (Antigravity)",
|
|
1703
1891
|
reasoning: true,
|
|
@@ -1796,6 +1984,63 @@ var OPENCODE_MODEL_DEFINITIONS = {
|
|
|
1796
1984
|
modalities: DEFAULT_MODALITIES
|
|
1797
1985
|
})
|
|
1798
1986
|
};
|
|
1987
|
+
var RESOLVER_ALIASES = {
|
|
1988
|
+
"gemini-3.1-pro-low": "gemini-3.1-pro",
|
|
1989
|
+
"gemini-3.1-pro-high": "gemini-3.1-pro",
|
|
1990
|
+
"gemini-3-flash-low": "gemini-3-flash",
|
|
1991
|
+
"gemini-3-flash-medium": "gemini-3-flash",
|
|
1992
|
+
"gemini-3-flash-high": "gemini-3-flash",
|
|
1993
|
+
"gemini-3.5-flash-low": "gemini-3.5-flash",
|
|
1994
|
+
"gemini-3.5-flash-medium": "gemini-3.5-flash",
|
|
1995
|
+
"gemini-3.5-flash-high": "gemini-3.5-flash",
|
|
1996
|
+
"gemini-claude-opus-4-6-thinking-low": "claude-opus-4-6-thinking",
|
|
1997
|
+
"gemini-claude-opus-4-6-thinking-medium": "claude-opus-4-6-thinking",
|
|
1998
|
+
"gemini-claude-opus-4-6-thinking-high": "claude-opus-4-6-thinking",
|
|
1999
|
+
"gemini-claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6-thinking",
|
|
2000
|
+
"gemini-claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6-thinking",
|
|
2001
|
+
"gemini-claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6-thinking",
|
|
2002
|
+
"gemini-claude-sonnet-4-6": "claude-sonnet-4-6-thinking"
|
|
2003
|
+
};
|
|
2004
|
+
var GEMINI_35_FLASH_ROUTES = {
|
|
2005
|
+
antigravity: {
|
|
2006
|
+
defaultModel: "gemini-3-flash-agent",
|
|
2007
|
+
byTier: {
|
|
2008
|
+
low: "gemini-3.5-flash-low",
|
|
2009
|
+
medium: "gemini-3.5-flash-low",
|
|
2010
|
+
high: "gemini-3-flash-agent"
|
|
2011
|
+
}
|
|
2012
|
+
},
|
|
2013
|
+
geminiCliFallbackModel: "gemini-3-flash-preview"
|
|
2014
|
+
};
|
|
2015
|
+
var QUOTA_GROUP_BY_MODEL_ID = {
|
|
2016
|
+
"claude-opus-4-6-thinking": "claude",
|
|
2017
|
+
"claude-opus-4-6": "claude",
|
|
2018
|
+
"claude-sonnet-4-6-thinking": "claude",
|
|
2019
|
+
"claude-sonnet-4-6": "claude",
|
|
2020
|
+
"gemini-pro-agent": "gemini-pro",
|
|
2021
|
+
"gemini-3.1-pro": "gemini-pro",
|
|
2022
|
+
"gemini-3.1-pro-low": "gemini-pro",
|
|
2023
|
+
"gemini-3.1-pro-high": "gemini-pro",
|
|
2024
|
+
"gemini-3-flash": "gemini-flash",
|
|
2025
|
+
"gemini-3-flash-agent": "gemini-flash",
|
|
2026
|
+
"gemini-3.5-flash-low": "gemini-flash"
|
|
2027
|
+
};
|
|
2028
|
+
var OPENCODE_MODEL_DEFINITIONS = PUBLIC_MODEL_DEFINITIONS;
|
|
2029
|
+
function getResolverAliasMap() {
|
|
2030
|
+
return RESOLVER_ALIASES;
|
|
2031
|
+
}
|
|
2032
|
+
function getGemini35FlashAntigravityModel(tier) {
|
|
2033
|
+
if (!tier) {
|
|
2034
|
+
return GEMINI_35_FLASH_ROUTES.antigravity.defaultModel;
|
|
2035
|
+
}
|
|
2036
|
+
return GEMINI_35_FLASH_ROUTES.antigravity.byTier[tier] ?? GEMINI_35_FLASH_ROUTES.antigravity.defaultModel;
|
|
2037
|
+
}
|
|
2038
|
+
function getGemini35FlashGeminiCliFallbackModel() {
|
|
2039
|
+
return GEMINI_35_FLASH_ROUTES.geminiCliFallbackModel;
|
|
2040
|
+
}
|
|
2041
|
+
function getQuotaGroupForModel(modelId) {
|
|
2042
|
+
return QUOTA_GROUP_BY_MODEL_ID[modelId.toLowerCase()];
|
|
2043
|
+
}
|
|
1799
2044
|
|
|
1800
2045
|
// src/plugin/config/updater.ts
|
|
1801
2046
|
var PLUGIN_NAME = "@expiren/opencode-antigravity-auth@latest";
|
|
@@ -1906,7 +2151,7 @@ ${existingAccounts.length} account(s) saved:`);
|
|
|
1906
2151
|
}
|
|
1907
2152
|
console.log("");
|
|
1908
2153
|
while (true) {
|
|
1909
|
-
const answer = await rl.question("(a)dd new, (f)resh start, (c)heck quotas, (v)erify account, (va) verify all? [a/f/c/v/va]: ");
|
|
2154
|
+
const answer = await rl.question("(a)dd new, (f)resh start, (c)heck quotas, auth (d)octor, (v)erify account, (va) verify all? [a/f/c/d/v/va]: ");
|
|
1910
2155
|
const normalized = answer.trim().toLowerCase();
|
|
1911
2156
|
if (normalized === "a" || normalized === "add") {
|
|
1912
2157
|
return { mode: "add" };
|
|
@@ -1917,13 +2162,16 @@ ${existingAccounts.length} account(s) saved:`);
|
|
|
1917
2162
|
if (normalized === "c" || normalized === "check") {
|
|
1918
2163
|
return { mode: "check" };
|
|
1919
2164
|
}
|
|
2165
|
+
if (normalized === "d" || normalized === "doctor" || normalized === "auth-doctor") {
|
|
2166
|
+
return { mode: "doctor" };
|
|
2167
|
+
}
|
|
1920
2168
|
if (normalized === "v" || normalized === "verify") {
|
|
1921
2169
|
return { mode: "verify" };
|
|
1922
2170
|
}
|
|
1923
2171
|
if (normalized === "va" || normalized === "verify-all" || normalized === "all") {
|
|
1924
2172
|
return { mode: "verify-all", verifyAll: true };
|
|
1925
2173
|
}
|
|
1926
|
-
console.log("Please enter 'a', 'f', 'c', 'v', or 'va'.");
|
|
2174
|
+
console.log("Please enter 'a', 'f', 'c', 'd', 'v', or 'va'.");
|
|
1927
2175
|
}
|
|
1928
2176
|
} finally {
|
|
1929
2177
|
rl.close();
|
|
@@ -1940,7 +2188,12 @@ async function promptLoginMode(existingAccounts) {
|
|
|
1940
2188
|
lastUsed: acc.lastUsed,
|
|
1941
2189
|
status: acc.status,
|
|
1942
2190
|
isCurrentAccount: acc.isCurrentAccount,
|
|
1943
|
-
enabled: acc.enabled
|
|
2191
|
+
enabled: acc.enabled,
|
|
2192
|
+
quotaSummary: acc.quotaSummary,
|
|
2193
|
+
cooldownMs: acc.cooldownMs,
|
|
2194
|
+
cooldownReason: acc.cooldownReason,
|
|
2195
|
+
cachedQuota: acc.cachedQuota,
|
|
2196
|
+
fingerprintHistory: acc.fingerprintHistory
|
|
1944
2197
|
}));
|
|
1945
2198
|
console.log("");
|
|
1946
2199
|
while (true) {
|
|
@@ -1950,6 +2203,12 @@ async function promptLoginMode(existingAccounts) {
|
|
|
1950
2203
|
return { mode: "add" };
|
|
1951
2204
|
case "check":
|
|
1952
2205
|
return { mode: "check" };
|
|
2206
|
+
case "doctor":
|
|
2207
|
+
return { mode: "doctor" };
|
|
2208
|
+
case "repair":
|
|
2209
|
+
return { mode: "repair" };
|
|
2210
|
+
case "current":
|
|
2211
|
+
return { mode: "current" };
|
|
1953
2212
|
case "verify":
|
|
1954
2213
|
return { mode: "verify" };
|
|
1955
2214
|
case "verify-all":
|
|
@@ -1968,6 +2227,18 @@ async function promptLoginMode(existingAccounts) {
|
|
|
1968
2227
|
if (accountAction === "verify") {
|
|
1969
2228
|
return { mode: "verify", verifyAccountIndex: action.account.index };
|
|
1970
2229
|
}
|
|
2230
|
+
if (accountAction === "restore-fingerprint") {
|
|
2231
|
+
const history = action.account.fingerprintHistory;
|
|
2232
|
+
if (!history || history.length === 0) continue;
|
|
2233
|
+
const accountLabel = action.account.email || `Account ${action.account.index + 1}`;
|
|
2234
|
+
const historyIndex = await showFingerprintHistory(history, accountLabel);
|
|
2235
|
+
if (historyIndex === null) continue;
|
|
2236
|
+
return {
|
|
2237
|
+
mode: "restore-fingerprint",
|
|
2238
|
+
restoreFingerprintAccountIndex: action.account.index,
|
|
2239
|
+
restoreFingerprintHistoryIndex: historyIndex
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
1971
2242
|
continue;
|
|
1972
2243
|
}
|
|
1973
2244
|
case "delete-all":
|
|
@@ -2750,9 +3021,9 @@ var AntigravityConfigSchema = z2.object({
|
|
|
2750
3021
|
* When false: Only shows toast notification, user must manually continue.
|
|
2751
3022
|
* When true: Automatically sends "continue" to resume the session.
|
|
2752
3023
|
*
|
|
2753
|
-
* @default
|
|
3024
|
+
* @default true
|
|
2754
3025
|
*/
|
|
2755
|
-
auto_resume: z2.boolean().default(
|
|
3026
|
+
auto_resume: z2.boolean().default(true),
|
|
2756
3027
|
/**
|
|
2757
3028
|
* Custom text to send when auto-resuming after recovery.
|
|
2758
3029
|
* Only used when auto_resume is enabled.
|
|
@@ -5762,31 +6033,7 @@ var THINKING_TIER_BUDGETS = {
|
|
|
5762
6033
|
"gemini-2.5-flash": { low: 6144, medium: 12288, high: 24576 },
|
|
5763
6034
|
default: { low: 4096, medium: 8192, high: 16384 }
|
|
5764
6035
|
};
|
|
5765
|
-
var MODEL_ALIASES =
|
|
5766
|
-
// Gemini 3.x variants - for Gemini CLI only (tier stripped, thinkingLevel used)
|
|
5767
|
-
// For Antigravity, these are bypassed and full model name is kept
|
|
5768
|
-
"gemini-3.1-pro-low": "gemini-3.1-pro",
|
|
5769
|
-
"gemini-3.1-pro-high": "gemini-3.1-pro",
|
|
5770
|
-
"gemini-3-flash-low": "gemini-3-flash",
|
|
5771
|
-
"gemini-3-flash-medium": "gemini-3-flash",
|
|
5772
|
-
"gemini-3-flash-high": "gemini-3-flash",
|
|
5773
|
-
// Gemini 3.5 Flash variants
|
|
5774
|
-
"gemini-3.5-flash-low": "gemini-3.5-flash",
|
|
5775
|
-
"gemini-3.5-flash-medium": "gemini-3.5-flash",
|
|
5776
|
-
"gemini-3.5-flash-high": "gemini-3.5-flash",
|
|
5777
|
-
// Claude proxy names (gemini- prefix for compatibility)
|
|
5778
|
-
"gemini-claude-opus-4-6-thinking-low": "claude-opus-4-6-thinking",
|
|
5779
|
-
"gemini-claude-opus-4-6-thinking-medium": "claude-opus-4-6-thinking",
|
|
5780
|
-
"gemini-claude-opus-4-6-thinking-high": "claude-opus-4-6-thinking",
|
|
5781
|
-
"gemini-claude-sonnet-4-6-thinking-low": "claude-sonnet-4-6-thinking",
|
|
5782
|
-
"gemini-claude-sonnet-4-6-thinking-medium": "claude-sonnet-4-6-thinking",
|
|
5783
|
-
"gemini-claude-sonnet-4-6-thinking-high": "claude-sonnet-4-6-thinking",
|
|
5784
|
-
"gemini-claude-sonnet-4-6": "claude-sonnet-4-6-thinking"
|
|
5785
|
-
// Image generation models
|
|
5786
|
-
// gemini-3.1-flash-image (Nano Banana 2) - available via Antigravity API and Gemini CLI
|
|
5787
|
-
// gemini-2.5-flash-image (Nano Banana) - NOT supported by Antigravity, only Google AI API
|
|
5788
|
-
// Reference: Antigravity-Manager/src-tauri/src/proxy/common/model_mapping.rs
|
|
5789
|
-
};
|
|
6036
|
+
var MODEL_ALIASES = getResolverAliasMap();
|
|
5790
6037
|
var TIER_REGEX = /-(minimal|low|medium|high)$/;
|
|
5791
6038
|
var QUOTA_PREFIX_REGEX = /^antigravity-/i;
|
|
5792
6039
|
var GEMINI_3_PRO_REGEX = /^gemini-3(?:\.\d+)?-pro/i;
|
|
@@ -5829,7 +6076,7 @@ function isGemini35FlashModel(model) {
|
|
|
5829
6076
|
return /^gemini-3\.5-flash/i.test(model);
|
|
5830
6077
|
}
|
|
5831
6078
|
function resolveGemini35FlashAntigravityModel(tier) {
|
|
5832
|
-
return tier
|
|
6079
|
+
return getGemini35FlashAntigravityModel(tier);
|
|
5833
6080
|
}
|
|
5834
6081
|
function resolveModelWithTier(requestedModel, options = {}) {
|
|
5835
6082
|
const isAntigravity = QUOTA_PREFIX_REGEX.test(requestedModel);
|
|
@@ -5956,7 +6203,7 @@ function resolveModelForHeaderStyle(requestedModel, headerStyle) {
|
|
|
5956
6203
|
const hasPreviewSuffix = /-preview($|-)/i.test(transformedModel);
|
|
5957
6204
|
const isGemini35Flash = isGemini35FlashModel(transformedModel);
|
|
5958
6205
|
if (isGemini35Flash) {
|
|
5959
|
-
transformedModel =
|
|
6206
|
+
transformedModel = getGemini35FlashGeminiCliFallbackModel();
|
|
5960
6207
|
} else if (!hasPreviewSuffix) {
|
|
5961
6208
|
transformedModel = `${transformedModel}-preview`;
|
|
5962
6209
|
}
|
|
@@ -7539,9 +7786,10 @@ function prepareAntigravityRequest(input2, init, accessToken, projectId, endpoin
|
|
|
7539
7786
|
const fingerprintHeaders = buildFingerprintHeaders(fingerprint);
|
|
7540
7787
|
headers.set("User-Agent", fingerprintHeaders["User-Agent"] || selectedHeaders["User-Agent"]);
|
|
7541
7788
|
} else {
|
|
7542
|
-
|
|
7543
|
-
headers.set("
|
|
7544
|
-
headers.set("Client
|
|
7789
|
+
const geminiCliHeaders = getRandomizedHeaders("gemini-cli", requestedModel);
|
|
7790
|
+
headers.set("User-Agent", geminiCliHeaders["User-Agent"]);
|
|
7791
|
+
if (geminiCliHeaders["X-Goog-Api-Client"]) headers.set("X-Goog-Api-Client", geminiCliHeaders["X-Goog-Api-Client"]);
|
|
7792
|
+
if (geminiCliHeaders["Client-Metadata"]) headers.set("Client-Metadata", geminiCliHeaders["Client-Metadata"]);
|
|
7545
7793
|
}
|
|
7546
7794
|
return {
|
|
7547
7795
|
request: transformedUrl,
|
|
@@ -9681,6 +9929,219 @@ async function showLocalDevToast(client, version) {
|
|
|
9681
9929
|
logAutoUpdate(`Local dev toast shown: v${version}`);
|
|
9682
9930
|
}
|
|
9683
9931
|
|
|
9932
|
+
// src/plugin/auth-drift.ts
|
|
9933
|
+
function isAccountEnabled(account) {
|
|
9934
|
+
return account.enabled !== false;
|
|
9935
|
+
}
|
|
9936
|
+
function selectRestorableAccount(storage) {
|
|
9937
|
+
if (!storage || storage.accounts.length === 0) {
|
|
9938
|
+
return void 0;
|
|
9939
|
+
}
|
|
9940
|
+
const activeAccount = storage.accounts[storage.activeIndex];
|
|
9941
|
+
if (activeAccount && isAccountEnabled(activeAccount)) {
|
|
9942
|
+
return activeAccount;
|
|
9943
|
+
}
|
|
9944
|
+
return storage.accounts.find(isAccountEnabled);
|
|
9945
|
+
}
|
|
9946
|
+
function buildAuthFromStoredAccount(account) {
|
|
9947
|
+
return {
|
|
9948
|
+
type: "oauth",
|
|
9949
|
+
refresh: formatRefreshParts({
|
|
9950
|
+
refreshToken: account.refreshToken,
|
|
9951
|
+
projectId: account.projectId,
|
|
9952
|
+
managedProjectId: account.managedProjectId
|
|
9953
|
+
}),
|
|
9954
|
+
access: "",
|
|
9955
|
+
expires: 0
|
|
9956
|
+
};
|
|
9957
|
+
}
|
|
9958
|
+
function detectAuthStorageDrift(auth, storage) {
|
|
9959
|
+
if (!storage || storage.accounts.length === 0) {
|
|
9960
|
+
return {
|
|
9961
|
+
status: "unavailable",
|
|
9962
|
+
reason: "no-account-storage"
|
|
9963
|
+
};
|
|
9964
|
+
}
|
|
9965
|
+
const restorableAccount = selectRestorableAccount(storage);
|
|
9966
|
+
if (!restorableAccount) {
|
|
9967
|
+
return {
|
|
9968
|
+
status: "unavailable",
|
|
9969
|
+
reason: "no-enabled-accounts"
|
|
9970
|
+
};
|
|
9971
|
+
}
|
|
9972
|
+
if (!auth) {
|
|
9973
|
+
return {
|
|
9974
|
+
status: "restorable",
|
|
9975
|
+
reason: "missing-opencode-auth",
|
|
9976
|
+
account: restorableAccount
|
|
9977
|
+
};
|
|
9978
|
+
}
|
|
9979
|
+
if (!isOAuthAuth(auth)) {
|
|
9980
|
+
return {
|
|
9981
|
+
status: "restorable",
|
|
9982
|
+
reason: "non-oauth-opencode-auth",
|
|
9983
|
+
account: restorableAccount
|
|
9984
|
+
};
|
|
9985
|
+
}
|
|
9986
|
+
const authRefreshToken = parseRefreshParts(auth.refresh).refreshToken;
|
|
9987
|
+
const matchedAccount = storage.accounts.find((account) => account.refreshToken === authRefreshToken);
|
|
9988
|
+
if (matchedAccount) {
|
|
9989
|
+
return {
|
|
9990
|
+
status: "healthy",
|
|
9991
|
+
reason: "auth-matches-storage",
|
|
9992
|
+
account: matchedAccount
|
|
9993
|
+
};
|
|
9994
|
+
}
|
|
9995
|
+
return {
|
|
9996
|
+
status: "drifted",
|
|
9997
|
+
reason: "refresh-token-not-in-storage",
|
|
9998
|
+
account: restorableAccount
|
|
9999
|
+
};
|
|
10000
|
+
}
|
|
10001
|
+
|
|
10002
|
+
// src/plugin/auth-doctor.ts
|
|
10003
|
+
function isEnabled(account) {
|
|
10004
|
+
return account.enabled !== false;
|
|
10005
|
+
}
|
|
10006
|
+
function statusFromFindings(findings) {
|
|
10007
|
+
if (findings.some((finding) => finding.repair && finding.severity === "error")) {
|
|
10008
|
+
return "repairable";
|
|
10009
|
+
}
|
|
10010
|
+
if (findings.some((finding) => finding.severity === "error")) {
|
|
10011
|
+
return "error";
|
|
10012
|
+
}
|
|
10013
|
+
if (findings.some((finding) => finding.severity === "warning")) {
|
|
10014
|
+
return "warning";
|
|
10015
|
+
}
|
|
10016
|
+
return "ok";
|
|
10017
|
+
}
|
|
10018
|
+
function summaryFromStatus(status) {
|
|
10019
|
+
switch (status) {
|
|
10020
|
+
case "ok":
|
|
10021
|
+
return "OpenCode auth and Antigravity account storage are in sync.";
|
|
10022
|
+
case "repairable":
|
|
10023
|
+
return "Auth drift detected. One or more safe repairs are available.";
|
|
10024
|
+
case "warning":
|
|
10025
|
+
return "Auth is usable, but one or more accounts need attention.";
|
|
10026
|
+
case "error":
|
|
10027
|
+
return "Auth state is not usable and no safe automatic repair is available.";
|
|
10028
|
+
}
|
|
10029
|
+
}
|
|
10030
|
+
function createAuthDoctorReport(input2) {
|
|
10031
|
+
const findings = [];
|
|
10032
|
+
const drift = detectAuthStorageDrift(input2.auth, input2.storage);
|
|
10033
|
+
switch (drift.reason) {
|
|
10034
|
+
case "auth-matches-storage":
|
|
10035
|
+
findings.push({
|
|
10036
|
+
code: "auth-matches-storage",
|
|
10037
|
+
severity: "info",
|
|
10038
|
+
message: "OpenCode OAuth refresh token exists in Antigravity account storage.",
|
|
10039
|
+
accountEmail: drift.account?.email
|
|
10040
|
+
});
|
|
10041
|
+
break;
|
|
10042
|
+
case "missing-opencode-auth":
|
|
10043
|
+
findings.push({
|
|
10044
|
+
code: "missing-opencode-auth",
|
|
10045
|
+
severity: "error",
|
|
10046
|
+
message: "OpenCode auth.json has no Google OAuth entry, but Antigravity account storage has a restorable account.",
|
|
10047
|
+
repair: "restore-opencode-auth",
|
|
10048
|
+
accountEmail: drift.account?.email
|
|
10049
|
+
});
|
|
10050
|
+
break;
|
|
10051
|
+
case "non-oauth-opencode-auth":
|
|
10052
|
+
findings.push({
|
|
10053
|
+
code: "non-oauth-opencode-auth",
|
|
10054
|
+
severity: "error",
|
|
10055
|
+
message: "OpenCode Google auth is not OAuth, but Antigravity account storage has a restorable OAuth account.",
|
|
10056
|
+
repair: "restore-opencode-auth",
|
|
10057
|
+
accountEmail: drift.account?.email
|
|
10058
|
+
});
|
|
10059
|
+
break;
|
|
10060
|
+
case "refresh-token-not-in-storage":
|
|
10061
|
+
findings.push({
|
|
10062
|
+
code: "refresh-token-not-in-storage",
|
|
10063
|
+
severity: "error",
|
|
10064
|
+
message: "OpenCode Google OAuth refresh token does not match any stored Antigravity account.",
|
|
10065
|
+
repair: "restore-opencode-auth",
|
|
10066
|
+
accountEmail: drift.account?.email
|
|
10067
|
+
});
|
|
10068
|
+
break;
|
|
10069
|
+
case "no-account-storage":
|
|
10070
|
+
findings.push({
|
|
10071
|
+
code: "no-account-storage",
|
|
10072
|
+
severity: "error",
|
|
10073
|
+
message: "No Antigravity account storage was found."
|
|
10074
|
+
});
|
|
10075
|
+
break;
|
|
10076
|
+
case "no-enabled-accounts":
|
|
10077
|
+
findings.push({
|
|
10078
|
+
code: "no-enabled-accounts",
|
|
10079
|
+
severity: "error",
|
|
10080
|
+
message: "Antigravity account storage exists, but all accounts are disabled."
|
|
10081
|
+
});
|
|
10082
|
+
break;
|
|
10083
|
+
}
|
|
10084
|
+
const storage = input2.storage;
|
|
10085
|
+
if (storage && storage.accounts.length > 0) {
|
|
10086
|
+
if (!Number.isInteger(storage.activeIndex) || storage.activeIndex < 0 || storage.activeIndex >= storage.accounts.length) {
|
|
10087
|
+
findings.push({
|
|
10088
|
+
code: "active-index-out-of-range",
|
|
10089
|
+
severity: "error",
|
|
10090
|
+
message: `Active account index ${storage.activeIndex} is outside the stored account range.`,
|
|
10091
|
+
repair: "clamp-active-index"
|
|
10092
|
+
});
|
|
10093
|
+
} else {
|
|
10094
|
+
const activeAccount = storage.accounts[storage.activeIndex];
|
|
10095
|
+
if (activeAccount && !isEnabled(activeAccount) && storage.accounts.some(isEnabled)) {
|
|
10096
|
+
findings.push({
|
|
10097
|
+
code: "active-account-disabled",
|
|
10098
|
+
severity: "error",
|
|
10099
|
+
message: "The active account is disabled while another enabled account is available.",
|
|
10100
|
+
repair: "select-enabled-account",
|
|
10101
|
+
accountEmail: activeAccount.email
|
|
10102
|
+
});
|
|
10103
|
+
}
|
|
10104
|
+
}
|
|
10105
|
+
for (const account of storage.accounts) {
|
|
10106
|
+
if (account.verificationRequired) {
|
|
10107
|
+
findings.push({
|
|
10108
|
+
code: "verification-required",
|
|
10109
|
+
severity: "warning",
|
|
10110
|
+
message: account.verificationRequiredReason ?? "Account requires Google verification before it can be used.",
|
|
10111
|
+
repair: "verify-account",
|
|
10112
|
+
accountEmail: account.email
|
|
10113
|
+
});
|
|
10114
|
+
}
|
|
10115
|
+
}
|
|
10116
|
+
}
|
|
10117
|
+
const status = statusFromFindings(findings);
|
|
10118
|
+
return {
|
|
10119
|
+
status,
|
|
10120
|
+
summary: summaryFromStatus(status),
|
|
10121
|
+
findings,
|
|
10122
|
+
runtime: input2.runtime
|
|
10123
|
+
};
|
|
10124
|
+
}
|
|
10125
|
+
function formatAuthDoctorReport(report) {
|
|
10126
|
+
const lines = [
|
|
10127
|
+
"Antigravity auth doctor",
|
|
10128
|
+
`Status: ${report.status}`,
|
|
10129
|
+
report.summary,
|
|
10130
|
+
""
|
|
10131
|
+
];
|
|
10132
|
+
if (report.runtime) {
|
|
10133
|
+
lines.push(`Antigravity version: ${report.runtime.antigravityVersion} (${report.runtime.antigravityVersionSource})`);
|
|
10134
|
+
lines.push("");
|
|
10135
|
+
}
|
|
10136
|
+
for (const finding of report.findings) {
|
|
10137
|
+
const repair = finding.repair ? ` | repair: ${finding.repair}` : "";
|
|
10138
|
+
const account = finding.accountEmail ? ` | account: ${finding.accountEmail}` : "";
|
|
10139
|
+
lines.push(`- [${finding.severity}] ${finding.code}${account}${repair}`);
|
|
10140
|
+
lines.push(` ${finding.message}`);
|
|
10141
|
+
}
|
|
10142
|
+
return lines.join("\n");
|
|
10143
|
+
}
|
|
10144
|
+
|
|
9684
10145
|
// src/plugin/quota.ts
|
|
9685
10146
|
var FETCH_TIMEOUT_MS2 = 1e4;
|
|
9686
10147
|
function buildAuthFromAccount(account) {
|
|
@@ -9712,6 +10173,10 @@ function parseResetTime(resetTime) {
|
|
|
9712
10173
|
return timestamp;
|
|
9713
10174
|
}
|
|
9714
10175
|
function classifyQuotaGroup(modelName, displayName) {
|
|
10176
|
+
const registryGroup = getQuotaGroupForModel(modelName);
|
|
10177
|
+
if (registryGroup) {
|
|
10178
|
+
return registryGroup;
|
|
10179
|
+
}
|
|
9715
10180
|
const combined = `${modelName} ${displayName ?? ""}`.toLowerCase();
|
|
9716
10181
|
if (combined.includes("claude")) {
|
|
9717
10182
|
return "claude";
|
|
@@ -9796,9 +10261,7 @@ async function fetchAvailableModels(accessToken, projectId) {
|
|
|
9796
10261
|
}
|
|
9797
10262
|
async function fetchGeminiCliQuota(accessToken, projectId) {
|
|
9798
10263
|
const endpoint = ANTIGRAVITY_ENDPOINT_PROD;
|
|
9799
|
-
const
|
|
9800
|
-
const arch = process.arch || "arm64";
|
|
9801
|
-
const geminiCliUserAgent = `GeminiCLI/1.0.0/gemini-2.5-pro (${platform}; ${arch})`;
|
|
10264
|
+
const geminiCliUserAgent = buildGeminiCliUserAgent();
|
|
9802
10265
|
const body = projectId ? { project: projectId } : {};
|
|
9803
10266
|
try {
|
|
9804
10267
|
const response = await fetchWithTimeout2(`${endpoint}/v1internal:retrieveUserQuota`, {
|
|
@@ -10130,6 +10593,7 @@ var CHANGELOG_URL = "https://antigravity.google/changelog";
|
|
|
10130
10593
|
var FETCH_TIMEOUT_MS3 = 5e3;
|
|
10131
10594
|
var CHANGELOG_SCAN_CHARS = 5e3;
|
|
10132
10595
|
var VERSION_REGEX = /\d+\.\d+\.\d+/;
|
|
10596
|
+
var lastResolution = null;
|
|
10133
10597
|
function parseVersion(text) {
|
|
10134
10598
|
const match = text.match(VERSION_REGEX);
|
|
10135
10599
|
return match ? match[0] : null;
|
|
@@ -10149,6 +10613,9 @@ async function tryFetchVersion(url, maxChars) {
|
|
|
10149
10613
|
clearTimeout(timeout);
|
|
10150
10614
|
}
|
|
10151
10615
|
}
|
|
10616
|
+
function getAntigravityVersionResolution() {
|
|
10617
|
+
return lastResolution ?? { version: getAntigravityVersion(), source: "fallback" };
|
|
10618
|
+
}
|
|
10152
10619
|
async function initAntigravityVersion() {
|
|
10153
10620
|
const log11 = createLogger("version");
|
|
10154
10621
|
const fallback = getAntigravityVersion();
|
|
@@ -10165,7 +10632,8 @@ async function initAntigravityVersion() {
|
|
|
10165
10632
|
source = "fallback";
|
|
10166
10633
|
setAntigravityVersion(fallback);
|
|
10167
10634
|
log11.info("version-fetch-failed", { fallback });
|
|
10168
|
-
|
|
10635
|
+
lastResolution = { version: fallback, source };
|
|
10636
|
+
return lastResolution;
|
|
10169
10637
|
}
|
|
10170
10638
|
}
|
|
10171
10639
|
if (version !== fallback) {
|
|
@@ -10174,6 +10642,8 @@ async function initAntigravityVersion() {
|
|
|
10174
10642
|
log11.debug("version-unchanged", { version, source });
|
|
10175
10643
|
}
|
|
10176
10644
|
setAntigravityVersion(version);
|
|
10645
|
+
lastResolution = { version, source };
|
|
10646
|
+
return lastResolution;
|
|
10177
10647
|
}
|
|
10178
10648
|
|
|
10179
10649
|
// src/plugin/search.ts
|
|
@@ -10966,6 +11436,13 @@ function buildAuthSuccessFromStoredAccount(account) {
|
|
|
10966
11436
|
projectId: account.projectId ?? ""
|
|
10967
11437
|
};
|
|
10968
11438
|
}
|
|
11439
|
+
function formatCachedQuotaSummary(account) {
|
|
11440
|
+
const quota = account.cachedQuota;
|
|
11441
|
+
if (!quota) {
|
|
11442
|
+
return void 0;
|
|
11443
|
+
}
|
|
11444
|
+
return formatCachedQuotaWithStatus(quota);
|
|
11445
|
+
}
|
|
10969
11446
|
function retryAfterMsFromResponse(response, defaultRetryMs = 6e4) {
|
|
10970
11447
|
const retryAfterMsHeader = response.headers.get("retry-after-ms");
|
|
10971
11448
|
if (retryAfterMsHeader) {
|
|
@@ -11317,7 +11794,33 @@ var createAntigravityPlugin = (providerId) => async ({ client, directory }) => {
|
|
|
11317
11794
|
provider: providerId,
|
|
11318
11795
|
loader: async (getAuth, provider) => {
|
|
11319
11796
|
cachedGetAuth = getAuth;
|
|
11320
|
-
|
|
11797
|
+
let auth = await getAuth();
|
|
11798
|
+
if (!isOAuthAuth(auth)) {
|
|
11799
|
+
const storedAccounts2 = await loadAccounts();
|
|
11800
|
+
const drift = detectAuthStorageDrift(auth, storedAccounts2);
|
|
11801
|
+
if (drift.status === "restorable" && drift.account) {
|
|
11802
|
+
auth = buildAuthFromStoredAccount(drift.account);
|
|
11803
|
+
try {
|
|
11804
|
+
await client.auth.set({
|
|
11805
|
+
path: { id: providerId },
|
|
11806
|
+
body: {
|
|
11807
|
+
type: "oauth",
|
|
11808
|
+
refresh: auth.refresh,
|
|
11809
|
+
access: auth.access ?? "",
|
|
11810
|
+
expires: auth.expires ?? 0
|
|
11811
|
+
}
|
|
11812
|
+
});
|
|
11813
|
+
log10.info("Restored Antigravity OAuth auth from account storage", {
|
|
11814
|
+
reason: drift.reason,
|
|
11815
|
+
email: drift.account.email
|
|
11816
|
+
});
|
|
11817
|
+
} catch (storeError) {
|
|
11818
|
+
log10.warn("Failed to restore Antigravity OAuth auth from account storage", {
|
|
11819
|
+
error: String(storeError)
|
|
11820
|
+
});
|
|
11821
|
+
}
|
|
11822
|
+
}
|
|
11823
|
+
}
|
|
11321
11824
|
if (!isOAuthAuth(auth)) {
|
|
11322
11825
|
try {
|
|
11323
11826
|
await clearAccounts();
|
|
@@ -12225,7 +12728,8 @@ Alternatively, you can:
|
|
|
12225
12728
|
lastUsed: acc.lastUsed,
|
|
12226
12729
|
status,
|
|
12227
12730
|
isCurrentAccount: idx === (existingStorage2.activeIndex ?? 0),
|
|
12228
|
-
enabled: acc.enabled !== false
|
|
12731
|
+
enabled: acc.enabled !== false,
|
|
12732
|
+
quotaSummary: formatCachedQuotaSummary(acc)
|
|
12229
12733
|
};
|
|
12230
12734
|
});
|
|
12231
12735
|
menuResult = await promptLoginMode(existingAccounts);
|
|
@@ -12294,8 +12798,10 @@ Alternatively, you can:
|
|
|
12294
12798
|
const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
|
|
12295
12799
|
const bar = createProgressBar(model.remainingFraction);
|
|
12296
12800
|
const reset = formatReset(model.resetTime);
|
|
12801
|
+
const status = classifyGroupStatus({ remainingFraction: model.remainingFraction, resetTime: model.resetTime, modelCount: 1 });
|
|
12802
|
+
const badge = formatQuotaStatusBadge(status);
|
|
12297
12803
|
const modelName = model.modelId.padEnd(29);
|
|
12298
|
-
console.log(` \u2502 ${connector} ${modelName} ${bar}${reset}`);
|
|
12804
|
+
console.log(` \u2502 ${connector} ${modelName} ${bar} ${badge}${reset}`);
|
|
12299
12805
|
});
|
|
12300
12806
|
}
|
|
12301
12807
|
const hasAntigravity = res.quota && Object.keys(res.quota.groups).length > 0;
|
|
@@ -12316,8 +12822,10 @@ Alternatively, you can:
|
|
|
12316
12822
|
const connector = isLast ? "\u2514\u2500" : "\u251C\u2500";
|
|
12317
12823
|
const bar = createProgressBar(g.data.remainingFraction);
|
|
12318
12824
|
const reset = formatReset(g.data.resetTime);
|
|
12825
|
+
const status = classifyGroupStatus(g.data);
|
|
12826
|
+
const badge = formatQuotaStatusBadge(status);
|
|
12319
12827
|
const modelName = g.name.padEnd(29);
|
|
12320
|
-
console.log(` ${connector} ${modelName} ${bar}${reset}`);
|
|
12828
|
+
console.log(` ${connector} ${modelName} ${bar} ${badge}${reset}`);
|
|
12321
12829
|
});
|
|
12322
12830
|
}
|
|
12323
12831
|
console.log("");
|
|
@@ -12344,6 +12852,22 @@ Alternatively, you can:
|
|
|
12344
12852
|
console.log("");
|
|
12345
12853
|
continue;
|
|
12346
12854
|
}
|
|
12855
|
+
if (menuResult.mode === "doctor") {
|
|
12856
|
+
const auth = cachedGetAuth ? await cachedGetAuth().catch(() => void 0) : void 0;
|
|
12857
|
+
const versionResolution = getAntigravityVersionResolution();
|
|
12858
|
+
const report = createAuthDoctorReport({
|
|
12859
|
+
auth,
|
|
12860
|
+
storage: existingStorage2,
|
|
12861
|
+
runtime: {
|
|
12862
|
+
antigravityVersion: versionResolution.version,
|
|
12863
|
+
antigravityVersionSource: versionResolution.source
|
|
12864
|
+
}
|
|
12865
|
+
});
|
|
12866
|
+
console.log(`
|
|
12867
|
+
${formatAuthDoctorReport(report)}
|
|
12868
|
+
`);
|
|
12869
|
+
continue;
|
|
12870
|
+
}
|
|
12347
12871
|
if (menuResult.mode === "manage") {
|
|
12348
12872
|
if (menuResult.toggleAccountIndex !== void 0) {
|
|
12349
12873
|
const acc = existingStorage2.accounts[menuResult.toggleAccountIndex];
|