@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1
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/LICENSE +57744 -0
- package/native-manifest.json +1414 -0
- package/package.json +254 -0
- package/plugins/abacus-ai/icon.svg +18 -0
- package/plugins/abacus-ai/plugin.js +121 -0
- package/plugins/abacus-ai/plugin.json +17 -0
- package/plugins/alibaba/icon-color.svg +1 -0
- package/plugins/alibaba/icon.svg +1 -0
- package/plugins/alibaba/plugin.js +322 -0
- package/plugins/alibaba/plugin.json +20 -0
- package/plugins/alibaba-token-plan/icon-color.svg +1 -0
- package/plugins/alibaba-token-plan/icon.svg +1 -0
- package/plugins/alibaba-token-plan/plugin.js +544 -0
- package/plugins/alibaba-token-plan/plugin.json +19 -0
- package/plugins/amp/icon-color.svg +1 -0
- package/plugins/amp/icon-conflict.svg +6 -0
- package/plugins/amp/icon.svg +1 -0
- package/plugins/amp/plugin.js +175 -0
- package/plugins/amp/plugin.json +16 -0
- package/plugins/antigravity/icon-color.svg +1 -0
- package/plugins/antigravity/icon-conflict.svg +3 -0
- package/plugins/antigravity/icon.svg +1 -0
- package/plugins/antigravity/plugin.js +739 -0
- package/plugins/antigravity/plugin.json +31 -0
- package/plugins/antigravity-cli/icon.svg +3 -0
- package/plugins/antigravity-cli/plugin.js +570 -0
- package/plugins/antigravity-cli/plugin.json +16 -0
- package/plugins/antigravity-ide/icon.svg +3 -0
- package/plugins/antigravity-ide/plugin.js +257 -0
- package/plugins/antigravity-ide/plugin.json +29 -0
- package/plugins/augment/icon.svg +14 -0
- package/plugins/augment/plugin.js +59 -0
- package/plugins/augment/plugin.json +18 -0
- package/plugins/aws-bedrock/icon-color.svg +1 -0
- package/plugins/aws-bedrock/icon.svg +1 -0
- package/plugins/aws-bedrock/plugin.js +206 -0
- package/plugins/aws-bedrock/plugin.json +18 -0
- package/plugins/azure-openai/icon-color.svg +1 -0
- package/plugins/azure-openai/icon.svg +1 -0
- package/plugins/azure-openai/plugin.js +145 -0
- package/plugins/azure-openai/plugin.json +17 -0
- package/plugins/chutes/icon.svg +7 -0
- package/plugins/chutes/plugin.js +236 -0
- package/plugins/chutes/plugin.json +19 -0
- package/plugins/claude/icon-color.svg +1 -0
- package/plugins/claude/icon.svg +1 -0
- package/plugins/claude/plugin.js +1723 -0
- package/plugins/claude/plugin.json +30 -0
- package/plugins/codebuff/icon.svg +92 -0
- package/plugins/codebuff/plugin.js +113 -0
- package/plugins/codebuff/plugin.json +17 -0
- package/plugins/codex/icon-color.svg +5 -0
- package/plugins/codex/icon.svg +1 -0
- package/plugins/codex/plugin.js +1009 -0
- package/plugins/codex/plugin.json +82 -0
- package/plugins/command-code/icon.svg +3 -0
- package/plugins/command-code/plugin.js +184 -0
- package/plugins/command-code/plugin.json +20 -0
- package/plugins/copilot/icon-color.svg +1 -0
- package/plugins/copilot/icon.svg +1 -0
- package/plugins/copilot/plugin.js +684 -0
- package/plugins/copilot/plugin.json +21 -0
- package/plugins/crof/icon.svg +3 -0
- package/plugins/crof/plugin.js +53 -0
- package/plugins/crof/plugin.json +17 -0
- package/plugins/crofai/icon.svg +16 -0
- package/plugins/crofai/plugin.js +81 -0
- package/plugins/crofai/plugin.json +18 -0
- package/plugins/cursor/icon-conflict.svg +3 -0
- package/plugins/cursor/icon.svg +1 -0
- package/plugins/cursor/plugin.js +1379 -0
- package/plugins/cursor/plugin.json +23 -0
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +1379 -0
- package/plugins/cursor-nightly/plugin.json +23 -0
- package/plugins/deepgram/icon.svg +1 -0
- package/plugins/deepgram/plugin.js +20 -0
- package/plugins/deepgram/plugin.json +17 -0
- package/plugins/deepseek/icon-color.svg +1 -0
- package/plugins/deepseek/icon.svg +1 -0
- package/plugins/deepseek/plugin.js +71 -0
- package/plugins/deepseek/plugin.json +17 -0
- package/plugins/devin/icon.svg +5 -0
- package/plugins/devin/plugin.js +341 -0
- package/plugins/devin/plugin.json +16 -0
- package/plugins/doubao/icon-color.svg +1 -0
- package/plugins/doubao/icon.svg +1 -0
- package/plugins/doubao/plugin.js +92 -0
- package/plugins/doubao/plugin.json +17 -0
- package/plugins/droid/icon.svg +1 -0
- package/plugins/droid/plugin.json +20 -0
- package/plugins/elevenlabs/icon.svg +4 -0
- package/plugins/elevenlabs/plugin.js +48 -0
- package/plugins/elevenlabs/plugin.json +18 -0
- package/plugins/factory/icon-conflict.svg +1 -0
- package/plugins/factory/icon.svg +1 -0
- package/plugins/factory/plugin.js +487 -0
- package/plugins/factory/plugin.json +15 -0
- package/plugins/fireworks-ai/icon.svg +6 -0
- package/plugins/fireworks-ai/plugin.js +370 -0
- package/plugins/fireworks-ai/plugin.json +19 -0
- package/plugins/gemini/icon-color.svg +1 -0
- package/plugins/gemini/icon.svg +1 -0
- package/plugins/gemini/plugin.js +460 -0
- package/plugins/gemini/plugin.json +16 -0
- package/plugins/grok/icon.svg +1 -0
- package/plugins/grok/plugin.js +297 -0
- package/plugins/grok/plugin.json +19 -0
- package/plugins/groqcloud/icon.svg +1 -0
- package/plugins/groqcloud/plugin.js +117 -0
- package/plugins/groqcloud/plugin.json +19 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +14 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +3 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +14 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +313 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +16 -0
- package/plugins/kilo/icon.svg +1 -0
- package/plugins/kilo/plugin.js +111 -0
- package/plugins/kilo/plugin.json +19 -0
- package/plugins/kimi/icon-color.svg +1 -0
- package/plugins/kimi/icon-conflict.svg +3 -0
- package/plugins/kimi/icon.svg +1 -0
- package/plugins/kimi/plugin.js +358 -0
- package/plugins/kimi/plugin.json +15 -0
- package/plugins/kimi-k2/icon-color.svg +1 -0
- package/plugins/kimi-k2/icon.svg +1 -0
- package/plugins/kimi-k2/plugin.js +58 -0
- package/plugins/kimi-k2/plugin.json +18 -0
- package/plugins/kiro/icon-color.svg +5 -0
- package/plugins/kiro/icon-conflict.svg +1 -0
- package/plugins/kiro/icon.svg +4 -0
- package/plugins/kiro/plugin.js +390 -0
- package/plugins/kiro/plugin.json +16 -0
- package/plugins/litellm/icon.svg +16 -0
- package/plugins/litellm/plugin.js +199 -0
- package/plugins/litellm/plugin.json +16 -0
- package/plugins/llm-proxy/icon.svg +1 -0
- package/plugins/llm-proxy/plugin.js +40 -0
- package/plugins/llm-proxy/plugin.json +17 -0
- package/plugins/manus/icon.svg +6 -0
- package/plugins/manus/plugin.js +50 -0
- package/plugins/manus/plugin.json +17 -0
- package/plugins/mimo/icon.svg +1 -0
- package/plugins/mimo/plugin.js +177 -0
- package/plugins/mimo/plugin.json +19 -0
- package/plugins/minimax/icon-color.svg +1 -0
- package/plugins/minimax/icon-conflict.svg +4 -0
- package/plugins/minimax/icon.svg +1 -0
- package/plugins/minimax/plugin.js +453 -0
- package/plugins/minimax/plugin.json +14 -0
- package/plugins/mistral/icon-color.svg +1 -0
- package/plugins/mistral/icon.svg +1 -0
- package/plugins/mistral/plugin.js +152 -0
- package/plugins/mistral/plugin.json +18 -0
- package/plugins/moonshot/icon.svg +1 -0
- package/plugins/moonshot/plugin.js +43 -0
- package/plugins/moonshot/plugin.json +16 -0
- package/plugins/nanogpt/icon-color.svg +17 -0
- package/plugins/nanogpt/icon.svg +10 -0
- package/plugins/nanogpt/plugin.js +80 -0
- package/plugins/nanogpt/plugin.json +17 -0
- package/plugins/neuralwatt/icon.svg +3 -0
- package/plugins/neuralwatt/plugin.js +152 -0
- package/plugins/neuralwatt/plugin.json +17 -0
- package/plugins/ollama/icon.svg +1 -0
- package/plugins/ollama/plugin.js +92 -0
- package/plugins/ollama/plugin.json +20 -0
- package/plugins/openai-api/icon.svg +1 -0
- package/plugins/openai-api/plugin.js +533 -0
- package/plugins/openai-api/plugin.json +26 -0
- package/plugins/opencode/icon.svg +1 -0
- package/plugins/opencode/plugin.js +342 -0
- package/plugins/opencode/plugin.json +19 -0
- package/plugins/opencode-go/icon-conflict.svg +1 -0
- package/plugins/opencode-go/icon.svg +1 -0
- package/plugins/opencode-go/plugin.js +617 -0
- package/plugins/opencode-go/plugin.json +50 -0
- package/plugins/openrouter/icon.svg +1 -0
- package/plugins/openrouter/plugin.js +156 -0
- package/plugins/openrouter/plugin.json +8 -0
- package/plugins/perplexity/icon-color.svg +1 -0
- package/plugins/perplexity/icon-conflict.svg +1 -0
- package/plugins/perplexity/icon.svg +1 -0
- package/plugins/perplexity/plugin.js +425 -0
- package/plugins/perplexity/plugin.json +19 -0
- package/plugins/poe/icon.svg +1 -0
- package/plugins/poe/plugin.js +190 -0
- package/plugins/poe/plugin.json +19 -0
- package/plugins/stepfun/icon-color.svg +1 -0
- package/plugins/stepfun/icon.svg +1 -0
- package/plugins/stepfun/plugin.js +155 -0
- package/plugins/stepfun/plugin.json +18 -0
- package/plugins/synthetic/icon-conflict.svg +12 -0
- package/plugins/synthetic/icon.svg +14 -0
- package/plugins/synthetic/plugin.js +331 -0
- package/plugins/synthetic/plugin.json +23 -0
- package/plugins/t3chat/icon-color.svg +28 -0
- package/plugins/t3chat/icon.svg +4 -0
- package/plugins/t3chat/plugin.js +243 -0
- package/plugins/t3chat/plugin.json +20 -0
- package/plugins/venice/icon-color.svg +1 -0
- package/plugins/venice/icon.svg +1 -0
- package/plugins/venice/plugin.js +69 -0
- package/plugins/venice/plugin.json +16 -0
- package/plugins/vertex-ai/icon-color.svg +1 -0
- package/plugins/vertex-ai/icon.svg +1 -0
- package/plugins/vertex-ai/plugin.js +172 -0
- package/plugins/vertex-ai/plugin.json +18 -0
- package/plugins/warp/icon-color.svg +10 -0
- package/plugins/warp/icon.svg +6 -0
- package/plugins/warp/plugin.js +108 -0
- package/plugins/warp/plugin.json +18 -0
- package/plugins/windsurf/icon-conflict.svg +3 -0
- package/plugins/windsurf/icon.svg +1 -0
- package/plugins/windsurf/plugin.js +208 -0
- package/plugins/windsurf/plugin.json +16 -0
- package/plugins/zai/icon-conflict.svg +5 -0
- package/plugins/zai/icon.svg +1 -0
- package/plugins/zai/plugin.js +188 -0
- package/plugins/zai/plugin.json +16 -0
- package/plugins/zed/icon.svg +4 -0
- package/plugins/zed/plugin.js +270 -0
- package/plugins/zed/plugin.json +19 -0
- package/usagestat +0 -0
- package/usagestatd +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "antigravity",
|
|
4
|
+
"name": "Antigravity",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"icon": "icon.svg",
|
|
8
|
+
"brandColor": "#4285F4",
|
|
9
|
+
"supportedModes": ["oauth", "local"],
|
|
10
|
+
"autoMode": "oauth",
|
|
11
|
+
"lines": [
|
|
12
|
+
{
|
|
13
|
+
"type": "progress",
|
|
14
|
+
"label": "Gemini Pro",
|
|
15
|
+
"scope": "overview",
|
|
16
|
+
"primaryOrder": 1
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "progress",
|
|
20
|
+
"label": "Gemini Flash",
|
|
21
|
+
"scope": "overview",
|
|
22
|
+
"primaryOrder": 2
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "progress",
|
|
26
|
+
"label": "Claude",
|
|
27
|
+
"scope": "overview",
|
|
28
|
+
"primaryOrder": 3
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M85.2843 88.0301C90.1329 91.6664 97.4057 89.2422 90.7389 82.5755C70.7389 63.1816 74.9813 9.84827 50.1329 9.84827C25.2843 9.84827 29.5267 63.1816 9.52673 82.5755C2.25402 89.8483 10.1328 91.6664 14.9813 88.0301C33.7692 75.3028 32.5571 52.8786 50.1329 52.8786C67.7086 52.8786 66.4965 75.3028 85.2843 88.0301Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|
|
@@ -0,0 +1,570 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
const PROVIDER_ID = "antigravity-cli"
|
|
3
|
+
const CLI_STATE_DIR = "~/.gemini/antigravity-cli"
|
|
4
|
+
const KEYCHAIN_SERVICE = "gemini"
|
|
5
|
+
const KEYCHAIN_ACCOUNT = "antigravity"
|
|
6
|
+
const LOGIN_MESSAGE = "Not logged in. Run `agy` and complete Google sign-in first."
|
|
7
|
+
const SESSION_EXPIRED_MESSAGE =
|
|
8
|
+
"Google sign-in expired. Run `agy` and complete Google sign-in again."
|
|
9
|
+
const REQUEST_FAILED_MESSAGE = "Antigravity CLI quota request failed. Check your connection and try again."
|
|
10
|
+
const GOOGLE_OAUTH_URL = "https://oauth2.googleapis.com/token"
|
|
11
|
+
const GOOGLE_CLIENT_ID =
|
|
12
|
+
"1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com"
|
|
13
|
+
const GOOGLE_CLIENT_SECRET = "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"
|
|
14
|
+
const TOKEN_EXPIRY_SKEW_MS = 60 * 1000
|
|
15
|
+
|
|
16
|
+
const CLOUD_CODE_BASES = [
|
|
17
|
+
"https://daily-cloudcode-pa.googleapis.com",
|
|
18
|
+
"https://cloudcode-pa.googleapis.com",
|
|
19
|
+
]
|
|
20
|
+
const LOAD_CODE_ASSIST_PATH = "/v1internal:loadCodeAssist"
|
|
21
|
+
const FETCH_MODELS_PATH = "/v1internal:fetchAvailableModels"
|
|
22
|
+
const RETRIEVE_QUOTA_PATH = "/v1internal:retrieveUserQuota"
|
|
23
|
+
const QUOTA_PERIOD_MS = 5 * 60 * 60 * 1000
|
|
24
|
+
|
|
25
|
+
const IDE_METADATA = {
|
|
26
|
+
ideType: "IDE_UNSPECIFIED",
|
|
27
|
+
platform: "PLATFORM_UNSPECIFIED",
|
|
28
|
+
pluginType: "GEMINI",
|
|
29
|
+
duetProject: "default",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function trimString(value) {
|
|
33
|
+
return typeof value === "string" ? value.trim() : ""
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function decodeBase64(ctx, text) {
|
|
37
|
+
try {
|
|
38
|
+
return ctx.base64.decode(text)
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return null
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function readKeychainValue(ctx) {
|
|
45
|
+
if (!ctx.host.keychain || typeof ctx.host.keychain.readGenericPassword !== "function") {
|
|
46
|
+
return null
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
return ctx.host.keychain.readGenericPassword(KEYCHAIN_SERVICE, KEYCHAIN_ACCOUNT)
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (/credential-(denied|unavailable|account-mismatch|malformed):/.test(String(e))) throw e
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function unwrapKeychainText(ctx, raw) {
|
|
58
|
+
var text = trimString(raw)
|
|
59
|
+
if (!text) return null
|
|
60
|
+
if (text.indexOf("go-keyring-base64:") === 0) {
|
|
61
|
+
var decoded = decodeBase64(ctx, text.slice("go-keyring-base64:".length))
|
|
62
|
+
text = trimString(decoded)
|
|
63
|
+
}
|
|
64
|
+
return text || null
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function extractTokenFromObject(obj) {
|
|
68
|
+
if (!obj || typeof obj !== "object") return null
|
|
69
|
+
|
|
70
|
+
var directKeys = [
|
|
71
|
+
"access_token",
|
|
72
|
+
"accessToken",
|
|
73
|
+
"token",
|
|
74
|
+
"id_token",
|
|
75
|
+
"idToken",
|
|
76
|
+
"bearerToken",
|
|
77
|
+
"auth_token",
|
|
78
|
+
"authToken",
|
|
79
|
+
]
|
|
80
|
+
for (var i = 0; i < directKeys.length; i += 1) {
|
|
81
|
+
var value = obj[directKeys[i]]
|
|
82
|
+
if (typeof value === "string" && value.trim()) return value.trim()
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var nestedKeys = ["token", "tokens", "oauth", "oauth2", "credentials", "auth"]
|
|
86
|
+
for (var j = 0; j < nestedKeys.length; j += 1) {
|
|
87
|
+
var nested = extractTokenFromObject(obj[nestedKeys[j]])
|
|
88
|
+
if (nested) return nested
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function parseKeychainPayload(ctx, raw) {
|
|
95
|
+
var text = unwrapKeychainText(ctx, raw)
|
|
96
|
+
if (!text) return { text: null, parsed: null }
|
|
97
|
+
var parsed = ctx.util.tryParseJson(text)
|
|
98
|
+
if (typeof parsed === "string" && parsed.trim()) {
|
|
99
|
+
return { text: parsed.trim(), parsed: null, rawToken: parsed.trim() }
|
|
100
|
+
}
|
|
101
|
+
if (parsed && typeof parsed === "object") {
|
|
102
|
+
return { text: text, parsed: parsed, rawToken: null }
|
|
103
|
+
}
|
|
104
|
+
if (text.indexOf("Bearer ") === 0) {
|
|
105
|
+
return { text: text, parsed: null, rawToken: text.slice("Bearer ".length).trim() || null }
|
|
106
|
+
}
|
|
107
|
+
return { text: text, parsed: null, rawToken: text }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function extractAccessToken(ctx, raw) {
|
|
111
|
+
var payload = parseKeychainPayload(ctx, raw)
|
|
112
|
+
if (payload.rawToken && !payload.parsed) return payload.rawToken
|
|
113
|
+
if (payload.parsed) {
|
|
114
|
+
var token = extractTokenFromObject(payload.parsed)
|
|
115
|
+
if (token) return token
|
|
116
|
+
}
|
|
117
|
+
return payload.rawToken || null
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function readRefreshToken(parsed) {
|
|
121
|
+
if (!parsed || typeof parsed !== "object") return null
|
|
122
|
+
var keys = ["refresh_token", "refreshToken"]
|
|
123
|
+
for (var i = 0; i < keys.length; i += 1) {
|
|
124
|
+
var direct = parsed[keys[i]]
|
|
125
|
+
if (typeof direct === "string" && direct.trim()) return direct.trim()
|
|
126
|
+
}
|
|
127
|
+
var nestedKeys = ["token", "tokens", "oauth", "oauth2", "credentials", "auth"]
|
|
128
|
+
for (var j = 0; j < nestedKeys.length; j += 1) {
|
|
129
|
+
var nested = readRefreshToken(parsed[nestedKeys[j]])
|
|
130
|
+
if (nested) return nested
|
|
131
|
+
}
|
|
132
|
+
return null
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function parseExpiryMs(value) {
|
|
136
|
+
if (value == null) return null
|
|
137
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
138
|
+
return value < 1e12 ? value * 1000 : value
|
|
139
|
+
}
|
|
140
|
+
if (typeof value === "string" && value.trim()) {
|
|
141
|
+
var asNum = Number(value)
|
|
142
|
+
if (Number.isFinite(asNum)) return asNum < 1e12 ? asNum * 1000 : asNum
|
|
143
|
+
var parsed = Date.parse(value)
|
|
144
|
+
if (Number.isFinite(parsed)) return parsed
|
|
145
|
+
}
|
|
146
|
+
return null
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function readExpiryMs(parsed) {
|
|
150
|
+
if (!parsed || typeof parsed !== "object") return null
|
|
151
|
+
var keys = ["expiry", "expires_at", "expiresAt", "expires", "exp"]
|
|
152
|
+
for (var i = 0; i < keys.length; i += 1) {
|
|
153
|
+
var ms = parseExpiryMs(parsed[keys[i]])
|
|
154
|
+
if (ms != null) return ms
|
|
155
|
+
}
|
|
156
|
+
var nestedKeys = ["token", "tokens", "oauth", "oauth2", "credentials", "auth"]
|
|
157
|
+
for (var j = 0; j < nestedKeys.length; j += 1) {
|
|
158
|
+
var nested = readExpiryMs(parsed[nestedKeys[j]])
|
|
159
|
+
if (nested != null) return nested
|
|
160
|
+
}
|
|
161
|
+
return null
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function isAccessTokenExpired(expiryMs) {
|
|
165
|
+
if (expiryMs == null) return false
|
|
166
|
+
return expiryMs <= Date.now() + TOKEN_EXPIRY_SKEW_MS
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function writeKeychainAuth(ctx, serialized) {
|
|
170
|
+
if (
|
|
171
|
+
!ctx.host.keychain ||
|
|
172
|
+
typeof ctx.host.keychain.writeGenericPasswordForAccount !== "function"
|
|
173
|
+
) {
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
ctx.host.keychain.writeGenericPasswordForAccount(
|
|
178
|
+
KEYCHAIN_SERVICE,
|
|
179
|
+
KEYCHAIN_ACCOUNT,
|
|
180
|
+
serialized
|
|
181
|
+
)
|
|
182
|
+
} catch (e) {
|
|
183
|
+
ctx.host.log.warn("antigravity-cli keychain write failed: " + String(e))
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function mergeRefreshedToken(parsed, accessToken, expiresInSeconds) {
|
|
188
|
+
var root = parsed && typeof parsed === "object" ? parsed : {}
|
|
189
|
+
var token =
|
|
190
|
+
root.token && typeof root.token === "object" ? Object.assign({}, root.token) : {}
|
|
191
|
+
token.access_token = accessToken
|
|
192
|
+
token.token_type = token.token_type || "Bearer"
|
|
193
|
+
token.expiry = new Date(
|
|
194
|
+
Date.now() + (typeof expiresInSeconds === "number" ? expiresInSeconds : 3600) * 1000
|
|
195
|
+
).toISOString()
|
|
196
|
+
root.token = token
|
|
197
|
+
return root
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function refreshAccessToken(ctx, refreshTokenValue, parsed) {
|
|
201
|
+
if (!refreshTokenValue) return null
|
|
202
|
+
ctx.host.log.info("antigravity-cli attempting Google OAuth token refresh")
|
|
203
|
+
var resp
|
|
204
|
+
try {
|
|
205
|
+
resp = ctx.host.http.request({
|
|
206
|
+
method: "POST",
|
|
207
|
+
url: GOOGLE_OAUTH_URL,
|
|
208
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
209
|
+
bodyText:
|
|
210
|
+
"client_id=" +
|
|
211
|
+
encodeURIComponent(GOOGLE_CLIENT_ID) +
|
|
212
|
+
"&client_secret=" +
|
|
213
|
+
encodeURIComponent(GOOGLE_CLIENT_SECRET) +
|
|
214
|
+
"&refresh_token=" +
|
|
215
|
+
encodeURIComponent(refreshTokenValue) +
|
|
216
|
+
"&grant_type=refresh_token",
|
|
217
|
+
timeoutMs: 15000,
|
|
218
|
+
})
|
|
219
|
+
} catch (e) {
|
|
220
|
+
ctx.host.log.warn("antigravity-cli OAuth refresh failed: " + String(e))
|
|
221
|
+
return null
|
|
222
|
+
}
|
|
223
|
+
if (!resp || resp.status < 200 || resp.status >= 300) {
|
|
224
|
+
ctx.host.log.warn(
|
|
225
|
+
"antigravity-cli OAuth refresh HTTP " + String(resp && resp.status)
|
|
226
|
+
)
|
|
227
|
+
return null
|
|
228
|
+
}
|
|
229
|
+
var body = ctx.util.tryParseJson(resp.bodyText)
|
|
230
|
+
if (!body || typeof body.access_token !== "string" || !body.access_token.trim()) {
|
|
231
|
+
ctx.host.log.warn("antigravity-cli OAuth refresh missing access_token")
|
|
232
|
+
return null
|
|
233
|
+
}
|
|
234
|
+
var accessToken = body.access_token.trim()
|
|
235
|
+
var expiresIn = typeof body.expires_in === "number" ? body.expires_in : 3600
|
|
236
|
+
if (parsed && typeof parsed === "object") {
|
|
237
|
+
var merged = mergeRefreshedToken(parsed, accessToken, expiresIn)
|
|
238
|
+
writeKeychainAuth(ctx, JSON.stringify(merged))
|
|
239
|
+
}
|
|
240
|
+
return accessToken
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function resolveAccessToken(ctx) {
|
|
244
|
+
var raw = readKeychainValue(ctx)
|
|
245
|
+
var payload = parseKeychainPayload(ctx, raw)
|
|
246
|
+
var parsed = payload.parsed
|
|
247
|
+
var accessToken = extractAccessToken(ctx, raw)
|
|
248
|
+
var refreshToken = readRefreshToken(parsed)
|
|
249
|
+
var expiryMs = readExpiryMs(parsed)
|
|
250
|
+
|
|
251
|
+
if (accessToken && !isAccessTokenExpired(expiryMs)) return accessToken
|
|
252
|
+
|
|
253
|
+
if (refreshToken) {
|
|
254
|
+
var refreshed = refreshAccessToken(ctx, refreshToken, parsed)
|
|
255
|
+
if (refreshed) return refreshed
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (accessToken && isAccessTokenExpired(expiryMs)) {
|
|
259
|
+
throw SESSION_EXPIRED_MESSAGE
|
|
260
|
+
}
|
|
261
|
+
return accessToken
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function readNonSecretCliContext(ctx) {
|
|
265
|
+
var context = {}
|
|
266
|
+
try {
|
|
267
|
+
if (ctx.host.fs.exists(CLI_STATE_DIR)) {
|
|
268
|
+
context.hasStateDir = true
|
|
269
|
+
}
|
|
270
|
+
} catch (e) {
|
|
271
|
+
context.hasStateDir = false
|
|
272
|
+
}
|
|
273
|
+
return context
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function cloudCodeUrls(path) {
|
|
277
|
+
var urls = []
|
|
278
|
+
for (var i = 0; i < CLOUD_CODE_BASES.length; i += 1) {
|
|
279
|
+
urls.push(CLOUD_CODE_BASES[i] + path)
|
|
280
|
+
}
|
|
281
|
+
return urls
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function requestJson(ctx, url, token, body, options) {
|
|
285
|
+
var opts = options || {}
|
|
286
|
+
var request = ctx.host.http && typeof ctx.host.http.request === "function"
|
|
287
|
+
? ctx.host.http.request
|
|
288
|
+
: ctx.util.request
|
|
289
|
+
var resp
|
|
290
|
+
try {
|
|
291
|
+
resp = request({
|
|
292
|
+
method: "POST",
|
|
293
|
+
url: url,
|
|
294
|
+
headers: {
|
|
295
|
+
Authorization: "Bearer " + token,
|
|
296
|
+
Accept: "application/json",
|
|
297
|
+
"Content-Type": "application/json",
|
|
298
|
+
"User-Agent": "agy",
|
|
299
|
+
},
|
|
300
|
+
bodyText: JSON.stringify(body || {}),
|
|
301
|
+
timeoutMs: 15000,
|
|
302
|
+
})
|
|
303
|
+
} catch (e) {
|
|
304
|
+
if (opts.optional) {
|
|
305
|
+
ctx.host.log.warn("antigravity-cli request failed: " + String(e))
|
|
306
|
+
return null
|
|
307
|
+
}
|
|
308
|
+
throw REQUEST_FAILED_MESSAGE
|
|
309
|
+
}
|
|
310
|
+
if (!resp || typeof resp.status !== "number" || !Number.isFinite(resp.status)) {
|
|
311
|
+
if (opts.optional) return null
|
|
312
|
+
throw REQUEST_FAILED_MESSAGE
|
|
313
|
+
}
|
|
314
|
+
if (ctx.util.isAuthStatus(resp.status)) {
|
|
315
|
+
if (opts.optional) {
|
|
316
|
+
ctx.host.log.warn(
|
|
317
|
+
"antigravity-cli optional request HTTP " +
|
|
318
|
+
String(resp.status) +
|
|
319
|
+
" for " +
|
|
320
|
+
url +
|
|
321
|
+
" (ignored)"
|
|
322
|
+
)
|
|
323
|
+
return null
|
|
324
|
+
}
|
|
325
|
+
if (opts.onAuthFailure) {
|
|
326
|
+
var recovered = opts.onAuthFailure()
|
|
327
|
+
if (recovered) {
|
|
328
|
+
return requestJson(ctx, url, recovered, body, Object.assign({}, opts, { onAuthFailure: null }))
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
throw opts.authFailureMessage || LOGIN_MESSAGE
|
|
332
|
+
}
|
|
333
|
+
if (resp.status < 200 || resp.status >= 300) {
|
|
334
|
+
if (opts.optional) {
|
|
335
|
+
ctx.host.log.warn(
|
|
336
|
+
"antigravity-cli optional request HTTP " + String(resp.status) + " for " + url
|
|
337
|
+
)
|
|
338
|
+
return null
|
|
339
|
+
}
|
|
340
|
+
throw "Antigravity CLI quota request failed (HTTP " + String(resp.status) + "). Try again later."
|
|
341
|
+
}
|
|
342
|
+
var data = ctx.util.tryParseJson(resp.bodyText)
|
|
343
|
+
return data && typeof data === "object" ? data : null
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function requestJsonAcrossBases(ctx, path, token, body, options) {
|
|
347
|
+
var urls = cloudCodeUrls(path)
|
|
348
|
+
for (var i = 0; i < urls.length; i += 1) {
|
|
349
|
+
var data = requestJson(ctx, urls[i], token, body, options)
|
|
350
|
+
if (data) return data
|
|
351
|
+
}
|
|
352
|
+
return null
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function makeAuthRetry(ctx, authState) {
|
|
356
|
+
return function onAuthFailure() {
|
|
357
|
+
if (authState.retried) return null
|
|
358
|
+
authState.retried = true
|
|
359
|
+
var raw = readKeychainValue(ctx)
|
|
360
|
+
var payload = parseKeychainPayload(ctx, raw)
|
|
361
|
+
var refreshToken = readRefreshToken(payload.parsed)
|
|
362
|
+
if (!refreshToken) return null
|
|
363
|
+
var refreshed = refreshAccessToken(ctx, refreshToken, payload.parsed)
|
|
364
|
+
if (refreshed) {
|
|
365
|
+
authState.token = refreshed
|
|
366
|
+
return refreshed
|
|
367
|
+
}
|
|
368
|
+
return null
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function readFirstStringDeep(value, keys) {
|
|
373
|
+
if (!value || typeof value !== "object") return null
|
|
374
|
+
for (var i = 0; i < keys.length; i += 1) {
|
|
375
|
+
var v = value[keys[i]]
|
|
376
|
+
if (typeof v === "string" && v.trim()) return v.trim()
|
|
377
|
+
}
|
|
378
|
+
var values = Object.values(value)
|
|
379
|
+
for (var j = 0; j < values.length; j += 1) {
|
|
380
|
+
var found = readFirstStringDeep(values[j], keys)
|
|
381
|
+
if (found) return found
|
|
382
|
+
}
|
|
383
|
+
return null
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function readPlan(loadCodeAssistData) {
|
|
387
|
+
var current = loadCodeAssistData && loadCodeAssistData.currentTier
|
|
388
|
+
if (current && typeof current.name === "string" && current.name.trim()) {
|
|
389
|
+
return current.name.trim()
|
|
390
|
+
}
|
|
391
|
+
var direct = loadCodeAssistData && loadCodeAssistData.userTier
|
|
392
|
+
if (direct && typeof direct.name === "string" && direct.name.trim()) return direct.name.trim()
|
|
393
|
+
var equivalent = readTierObjectName(loadCodeAssistData)
|
|
394
|
+
if (equivalent) return equivalent
|
|
395
|
+
return readFirstStringDeep(loadCodeAssistData, ["userTierName", "tierName", "planName"])
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function readTierObjectName(value) {
|
|
399
|
+
if (!value || typeof value !== "object") return null
|
|
400
|
+
var tierKeys = ["userTier", "tier", "subscriptionTier", "plan"]
|
|
401
|
+
for (var i = 0; i < tierKeys.length; i += 1) {
|
|
402
|
+
var tier = value[tierKeys[i]]
|
|
403
|
+
if (tier && typeof tier === "object" && typeof tier.name === "string" && tier.name.trim()) {
|
|
404
|
+
return tier.name.trim()
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
var values = Object.values(value)
|
|
408
|
+
for (var j = 0; j < values.length; j += 1) {
|
|
409
|
+
var found = readTierObjectName(values[j])
|
|
410
|
+
if (found) return found
|
|
411
|
+
}
|
|
412
|
+
return null
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function modelText(value) {
|
|
416
|
+
var parts = []
|
|
417
|
+
if (!value || typeof value !== "object") return ""
|
|
418
|
+
var keys = ["label", "displayName", "name", "model", "modelId", "model_id", "id"]
|
|
419
|
+
for (var i = 0; i < keys.length; i += 1) {
|
|
420
|
+
if (typeof value[keys[i]] === "string") parts.push(value[keys[i]])
|
|
421
|
+
}
|
|
422
|
+
return parts.join(" ").toLowerCase()
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function poolForText(text) {
|
|
426
|
+
var lower = String(text || "").toLowerCase()
|
|
427
|
+
if (lower.indexOf("gemini") !== -1 && lower.indexOf("pro") !== -1) return "Gemini Pro"
|
|
428
|
+
if (lower.indexOf("gemini") !== -1 && lower.indexOf("flash") !== -1) return "Gemini Flash"
|
|
429
|
+
if (lower.indexOf("gemini") !== -1) return null
|
|
430
|
+
if (lower) return "Claude"
|
|
431
|
+
return null
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function pushBucket(out, pool, remainingFraction, resetTime) {
|
|
435
|
+
if (!pool || !Number.isFinite(remainingFraction)) return
|
|
436
|
+
out.push({
|
|
437
|
+
pool: pool,
|
|
438
|
+
remainingFraction: remainingFraction,
|
|
439
|
+
resetTime: resetTime || null,
|
|
440
|
+
})
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
function collectFetchModelBuckets(value, out) {
|
|
444
|
+
if (Array.isArray(value)) {
|
|
445
|
+
for (var i = 0; i < value.length; i += 1) collectFetchModelBuckets(value[i], out)
|
|
446
|
+
return
|
|
447
|
+
}
|
|
448
|
+
if (!value || typeof value !== "object") return
|
|
449
|
+
if (value.isInternal) return
|
|
450
|
+
|
|
451
|
+
var quota = value.quotaInfo || value.quota || null
|
|
452
|
+
var remaining = quota && typeof quota.remainingFraction === "number"
|
|
453
|
+
? quota.remainingFraction
|
|
454
|
+
: typeof value.remainingFraction === "number"
|
|
455
|
+
? value.remainingFraction
|
|
456
|
+
: null
|
|
457
|
+
if (remaining !== null) {
|
|
458
|
+
var text = modelText(value)
|
|
459
|
+
if (text) {
|
|
460
|
+
pushBucket(out, poolForText(text), remaining, (quota && (quota.resetTime || quota.reset_time)) || value.resetTime || value.reset_time)
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
var children = Object.values(value)
|
|
465
|
+
for (var j = 0; j < children.length; j += 1) collectFetchModelBuckets(children[j], out)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function collectQuotaBuckets(value, out, inheritedText) {
|
|
469
|
+
if (Array.isArray(value)) {
|
|
470
|
+
for (var i = 0; i < value.length; i += 1) collectQuotaBuckets(value[i], out, inheritedText)
|
|
471
|
+
return
|
|
472
|
+
}
|
|
473
|
+
if (!value || typeof value !== "object") return
|
|
474
|
+
|
|
475
|
+
var text = (inheritedText || "") + " " + modelText(value)
|
|
476
|
+
if (typeof value.remainingFraction === "number") {
|
|
477
|
+
pushBucket(out, poolForText(text), value.remainingFraction, value.resetTime || value.reset_time)
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
var entries = Object.keys(value)
|
|
481
|
+
for (var j = 0; j < entries.length; j += 1) {
|
|
482
|
+
var key = entries[j]
|
|
483
|
+
collectQuotaBuckets(value[key], out, text + " " + key)
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function dedupeBuckets(buckets) {
|
|
488
|
+
var byPool = {}
|
|
489
|
+
for (var i = 0; i < buckets.length; i += 1) {
|
|
490
|
+
var bucket = buckets[i]
|
|
491
|
+
if (!byPool[bucket.pool] || bucket.remainingFraction < byPool[bucket.pool].remainingFraction) {
|
|
492
|
+
byPool[bucket.pool] = bucket
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
return byPool
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function lineForBucket(ctx, label, bucket) {
|
|
499
|
+
var clamped = Math.max(0, Math.min(1, Number(bucket.remainingFraction)))
|
|
500
|
+
var opts = {
|
|
501
|
+
label: label,
|
|
502
|
+
used: Math.round((1 - clamped) * 100),
|
|
503
|
+
limit: 100,
|
|
504
|
+
format: { kind: "percent" },
|
|
505
|
+
periodDurationMs: QUOTA_PERIOD_MS,
|
|
506
|
+
}
|
|
507
|
+
if (bucket.resetTime) {
|
|
508
|
+
var iso = ctx.util.toIso ? ctx.util.toIso(bucket.resetTime) : bucket.resetTime
|
|
509
|
+
if (iso) opts.resetsAt = iso
|
|
510
|
+
}
|
|
511
|
+
return ctx.line.progress(opts)
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function buildLines(ctx, buckets) {
|
|
515
|
+
var byPool = dedupeBuckets(buckets)
|
|
516
|
+
var order = ["Gemini Pro", "Gemini Flash", "Claude"]
|
|
517
|
+
var lines = []
|
|
518
|
+
for (var i = 0; i < order.length; i += 1) {
|
|
519
|
+
var label = order[i]
|
|
520
|
+
if (byPool[label]) lines.push(lineForBucket(ctx, label, byPool[label]))
|
|
521
|
+
}
|
|
522
|
+
return lines
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
function probe(ctx) {
|
|
526
|
+
readNonSecretCliContext(ctx)
|
|
527
|
+
|
|
528
|
+
var token = resolveAccessToken(ctx)
|
|
529
|
+
if (!token) throw LOGIN_MESSAGE
|
|
530
|
+
|
|
531
|
+
var authState = { token: token, retried: false }
|
|
532
|
+
var authOpts = {
|
|
533
|
+
onAuthFailure: makeAuthRetry(ctx, authState),
|
|
534
|
+
authFailureMessage: SESSION_EXPIRED_MESSAGE,
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
var loadData = requestJsonAcrossBases(
|
|
538
|
+
ctx,
|
|
539
|
+
LOAD_CODE_ASSIST_PATH,
|
|
540
|
+
authState.token,
|
|
541
|
+
{ metadata: IDE_METADATA },
|
|
542
|
+
authOpts
|
|
543
|
+
)
|
|
544
|
+
if (!loadData) throw REQUEST_FAILED_MESSAGE
|
|
545
|
+
var plan = readPlan(loadData)
|
|
546
|
+
|
|
547
|
+
var buckets = []
|
|
548
|
+
// fetchAvailableModels rejects `metadata` in the body (HTTP 400); use {} like Antigravity IDE.
|
|
549
|
+
var fetchData = requestJsonAcrossBases(ctx, FETCH_MODELS_PATH, authState.token, {}, {
|
|
550
|
+
optional: true,
|
|
551
|
+
onAuthFailure: authOpts.onAuthFailure,
|
|
552
|
+
authFailureMessage: authOpts.authFailureMessage,
|
|
553
|
+
})
|
|
554
|
+
if (fetchData) collectFetchModelBuckets(fetchData, buckets)
|
|
555
|
+
|
|
556
|
+
if (buckets.length === 0) {
|
|
557
|
+
var quotaData = requestJsonAcrossBases(ctx, RETRIEVE_QUOTA_PATH, authState.token, {}, authOpts)
|
|
558
|
+
if (quotaData) collectQuotaBuckets(quotaData, buckets, "")
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
var lines = buildLines(ctx, buckets)
|
|
562
|
+
if (lines.length === 0) {
|
|
563
|
+
lines.push(ctx.line.badge({ label: "Status", text: "No quota data", color: "#a3a3a3" }))
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return { plan: plan || undefined, lines: lines }
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
globalThis.__openusage_plugin = { id: PROVIDER_ID, probe: probe }
|
|
570
|
+
})()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "antigravity-cli",
|
|
4
|
+
"name": "Antigravity CLI",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"icon": "icon.svg",
|
|
8
|
+
"brandColor": "#4285F4",
|
|
9
|
+
"supportedModes": ["oauth", "local"],
|
|
10
|
+
"autoMode": "oauth",
|
|
11
|
+
"lines": [
|
|
12
|
+
{ "type": "progress", "label": "Gemini Pro", "scope": "overview", "primaryOrder": 1 },
|
|
13
|
+
{ "type": "progress", "label": "Gemini Flash", "scope": "overview", "primaryOrder": 2 },
|
|
14
|
+
{ "type": "progress", "label": "Claude", "scope": "overview", "primaryOrder": 3 }
|
|
15
|
+
]
|
|
16
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M85.2843 88.0301C90.1329 91.6664 97.4057 89.2422 90.7389 82.5755C70.7389 63.1816 74.9813 9.84827 50.1329 9.84827C25.2843 9.84827 29.5267 63.1816 9.52673 82.5755C2.25402 89.8483 10.1328 91.6664 14.9813 88.0301C33.7692 75.3028 32.5571 52.8786 50.1329 52.8786C67.7086 52.8786 66.4965 75.3028 85.2843 88.0301Z" fill="currentColor"/>
|
|
3
|
+
</svg>
|