@hashimkarim/usagestat-linux-x64-gnu 2.1.0 → 2.2.0
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/native-manifest.json +197 -89
- package/package.json +19 -1
- package/plugins/abliteration/plugin.json +1 -1
- package/plugins/aerostack/plugin.json +1 -1
- package/plugins/aixy/plugin.json +1 -1
- package/plugins/atlascloud/plugin.json +1 -1
- package/plugins/bifrost/plugin.json +1 -1
- package/plugins/chatbox/plugin.json +1 -1
- package/plugins/claudeplatform/plugin.json +1 -1
- package/plugins/codex/plugin.js +11 -6
- package/plugins/codex/plugin.json +10 -1
- package/plugins/cosmic/plugin.json +1 -1
- package/plugins/cursor/plugin.js +18 -6
- package/plugins/devpass/plugin.json +1 -1
- package/plugins/exa/plugin.json +1 -1
- package/plugins/fal/plugin.json +1 -1
- package/plugins/flora/plugin.json +1 -1
- package/plugins/futureagi/plugin.json +1 -1
- package/plugins/gemini-apps/plugin.json +1 -1
- package/plugins/gitkraken/plugin.json +1 -1
- package/plugins/googledeveloper/LICENSE +21 -0
- package/plugins/googledeveloper/icon.svg +3 -0
- package/plugins/googledeveloper/plugin.js +204 -0
- package/plugins/googledeveloper/plugin.json +25 -0
- package/plugins/helmcode/plugin.js +80 -23
- package/plugins/helmcode/plugin.json +2 -2
- package/plugins/huggingface/plugin.json +1 -1
- package/plugins/hyper/plugin.json +1 -1
- package/plugins/jetbrains-ai-assistant/LICENSE +22 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +502 -16
- package/plugins/jetbrains-ai-assistant/plugin.json +27 -4
- package/plugins/kimi/plugin.js +16 -1
- package/plugins/kimi/plugin.json +46 -6
- package/plugins/langdock/plugin.json +1 -1
- package/plugins/linkup/plugin.json +1 -1
- package/plugins/lithosai/plugin.json +1 -1
- package/plugins/llmman/plugin.json +1 -1
- package/plugins/munito/plugin.json +1 -1
- package/plugins/muse/plugin.json +1 -1
- package/plugins/museai/plugin.js +5 -3
- package/plugins/museai/plugin.json +2 -2
- package/plugins/nous/plugin.json +1 -1
- package/plugins/opencode-go/plugin.js +4 -3
- package/plugins/opendesign/LICENSE +21 -0
- package/plugins/opendesign/icon.svg +4 -0
- package/plugins/opendesign/plugin.js +108 -0
- package/plugins/opendesign/plugin.json +25 -0
- package/plugins/parallel/plugin.json +1 -1
- package/plugins/perplexity/LICENSE +22 -0
- package/plugins/perplexity/plugin.js +122 -0
- package/plugins/perplexity/plugin.json +36 -7
- package/plugins/qwencloud/plugin.json +1 -1
- package/plugins/raycast/plugin.json +1 -1
- package/plugins/replicate/plugin.json +1 -1
- package/plugins/sailresearch/plugin.json +1 -1
- package/plugins/siliconflow/LICENSE +21 -0
- package/plugins/siliconflow/icon.svg +3 -0
- package/plugins/siliconflow/plugin.js +87 -0
- package/plugins/siliconflow/plugin.json +32 -0
- package/plugins/sofya/plugin.json +1 -1
- package/plugins/soniox/plugin.json +1 -1
- package/plugins/synthetic/plugin.js +12 -0
- package/plugins/synthetic/plugin.json +51 -9
- package/plugins/tavily/plugin.json +1 -1
- package/plugins/tinyapi/plugin.json +1 -1
- package/plugins/traecn/plugin.js +10 -11
- package/plugins/traecn/plugin.json +2 -2
- package/plugins/tripo/LICENSE +21 -0
- package/plugins/tripo/icon.svg +4 -0
- package/plugins/tripo/plugin.js +60 -0
- package/plugins/tripo/plugin.json +24 -0
- package/plugins/typesafe/plugin.js +63 -112
- package/plugins/typesafe/plugin.json +2 -2
- package/plugins/v0/plugin.json +1 -1
- package/plugins/vercel/plugin.json +2 -2
- package/plugins/workbuddy/plugin.js +103 -17
- package/plugins/workbuddy/plugin.json +14 -2
- package/plugins/xapi/plugin.json +1 -1
- package/plugins/xkiro/plugin.json +1 -1
- package/usagestat +0 -0
- package/usagestatd +0 -0
package/package.json
CHANGED
|
@@ -212,6 +212,10 @@
|
|
|
212
212
|
"plugins/gitkraken/icon.svg",
|
|
213
213
|
"plugins/gitkraken/plugin.js",
|
|
214
214
|
"plugins/gitkraken/plugin.json",
|
|
215
|
+
"plugins/googledeveloper/LICENSE",
|
|
216
|
+
"plugins/googledeveloper/icon.svg",
|
|
217
|
+
"plugins/googledeveloper/plugin.js",
|
|
218
|
+
"plugins/googledeveloper/plugin.json",
|
|
215
219
|
"plugins/grok/icon-color.svg",
|
|
216
220
|
"plugins/grok/icon.svg",
|
|
217
221
|
"plugins/grok/plugin.js",
|
|
@@ -235,6 +239,7 @@
|
|
|
235
239
|
"plugins/ibmbob/icon.svg",
|
|
236
240
|
"plugins/ibmbob/plugin.js",
|
|
237
241
|
"plugins/ibmbob/plugin.json",
|
|
242
|
+
"plugins/jetbrains-ai-assistant/LICENSE",
|
|
238
243
|
"plugins/jetbrains-ai-assistant/icon-color.svg",
|
|
239
244
|
"plugins/jetbrains-ai-assistant/icon-conflict.svg",
|
|
240
245
|
"plugins/jetbrains-ai-assistant/icon.svg",
|
|
@@ -349,6 +354,10 @@
|
|
|
349
354
|
"plugins/opencode/icon.svg",
|
|
350
355
|
"plugins/opencode/plugin.js",
|
|
351
356
|
"plugins/opencode/plugin.json",
|
|
357
|
+
"plugins/opendesign/LICENSE",
|
|
358
|
+
"plugins/opendesign/icon.svg",
|
|
359
|
+
"plugins/opendesign/plugin.js",
|
|
360
|
+
"plugins/opendesign/plugin.json",
|
|
352
361
|
"plugins/openrouter/icon-color.svg",
|
|
353
362
|
"plugins/openrouter/icon.svg",
|
|
354
363
|
"plugins/openrouter/plugin.js",
|
|
@@ -357,6 +366,7 @@
|
|
|
357
366
|
"plugins/parallel/icon.svg",
|
|
358
367
|
"plugins/parallel/plugin.js",
|
|
359
368
|
"plugins/parallel/plugin.json",
|
|
369
|
+
"plugins/perplexity/LICENSE",
|
|
360
370
|
"plugins/perplexity/icon-color.svg",
|
|
361
371
|
"plugins/perplexity/icon-conflict.svg",
|
|
362
372
|
"plugins/perplexity/icon.svg",
|
|
@@ -391,6 +401,10 @@
|
|
|
391
401
|
"plugins/sakana/icon.svg",
|
|
392
402
|
"plugins/sakana/plugin.js",
|
|
393
403
|
"plugins/sakana/plugin.json",
|
|
404
|
+
"plugins/siliconflow/LICENSE",
|
|
405
|
+
"plugins/siliconflow/icon.svg",
|
|
406
|
+
"plugins/siliconflow/plugin.js",
|
|
407
|
+
"plugins/siliconflow/plugin.json",
|
|
394
408
|
"plugins/sofya/LICENSE",
|
|
395
409
|
"plugins/sofya/icon.svg",
|
|
396
410
|
"plugins/sofya/plugin.js",
|
|
@@ -427,6 +441,10 @@
|
|
|
427
441
|
"plugins/traecn/icon.svg",
|
|
428
442
|
"plugins/traecn/plugin.js",
|
|
429
443
|
"plugins/traecn/plugin.json",
|
|
444
|
+
"plugins/tripo/LICENSE",
|
|
445
|
+
"plugins/tripo/icon.svg",
|
|
446
|
+
"plugins/tripo/plugin.js",
|
|
447
|
+
"plugins/tripo/plugin.json",
|
|
430
448
|
"plugins/typesafe/LICENSE",
|
|
431
449
|
"plugins/typesafe/icon.svg",
|
|
432
450
|
"plugins/typesafe/plugin.js",
|
|
@@ -513,5 +531,5 @@
|
|
|
513
531
|
"type": "git",
|
|
514
532
|
"url": "https://github.com/hashimkarim/usagestat.git"
|
|
515
533
|
},
|
|
516
|
-
"version": "2.
|
|
534
|
+
"version": "2.2.0"
|
|
517
535
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/abliteration.js",
|
|
21
21
|
"sha256": "16982dfb14ae7e1181c688f5084e6b17ea84f72a28c1a98623ebc03c1dff5516",
|
|
22
22
|
"license": "MIT"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/aerostack.js",
|
|
21
21
|
"sha256": "f0ead202fc5ee40481ea22122b7f4d9238013cbc68cb6b218592d6a64439a9f3",
|
|
22
22
|
"license": "MIT"
|
package/plugins/aixy/plugin.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/aixy.js",
|
|
29
29
|
"sha256": "975d98525503e286f9425c2a1d64fe00da8e2fdc0b00890e15c2cbcb9a37c125",
|
|
30
30
|
"license": "MIT"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/atlascloud.js",
|
|
21
21
|
"sha256": "852fb78abaf4fcdbbfbfeac0b60d6b82a9ca9b1d1d2f9014f6e5299b41ac47fa",
|
|
22
22
|
"license": "MIT"
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
],
|
|
24
24
|
"upstream": {
|
|
25
25
|
"repository": "https://github.com/steipete/CodexBar",
|
|
26
|
-
"revision": "
|
|
26
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
27
27
|
"path": "Sources/CodexBarCore/Resources/Plugins/bifrost.js",
|
|
28
28
|
"sha256": "b7576d59ccd077c812118cf09d282042589a80df470c621e414583050f03aa07",
|
|
29
29
|
"license": "MIT"
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/chatbox.js",
|
|
21
21
|
"sha256": "cf0ae84410aa3794635c0df1edf4936ae514a070968a189dc6ef613c5445f957",
|
|
22
22
|
"license": "MIT"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"setupFields": [],
|
|
18
18
|
"upstream": {
|
|
19
19
|
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
-
"revision": "
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
21
|
"path": "Sources/CodexBarCore/Resources/Plugins/claudeplatform.js",
|
|
22
22
|
"sha256": "d3c61855621fd4e5b5b753bdd223524e0ee7f4b55cfd63f24f23516ac33027e8",
|
|
23
23
|
"license": "MIT"
|
package/plugins/codex/plugin.js
CHANGED
|
@@ -382,6 +382,11 @@
|
|
|
382
382
|
return ctx.fmt.planLabel(rawPlan) || null
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
function reportedPeriod(window, fallback) {
|
|
386
|
+
const seconds = window && window.limit_window_seconds
|
|
387
|
+
return typeof seconds === "number" && Number.isFinite(seconds) && seconds > 0 ? seconds * 1000 : fallback
|
|
388
|
+
}
|
|
389
|
+
|
|
385
390
|
function getResetsAtIso(ctx, nowSec, window) {
|
|
386
391
|
if (!window) return null
|
|
387
392
|
if (typeof window.reset_at === "number") {
|
|
@@ -780,12 +785,12 @@
|
|
|
780
785
|
|
|
781
786
|
if (headerPrimary !== null) {
|
|
782
787
|
lines.push(ctx.line.progress({
|
|
783
|
-
label: "Session",
|
|
788
|
+
label: reportedPeriod(primaryWindow, PERIOD_SESSION_MS) === 30*86400000 ? "Monthly" : "Session",
|
|
784
789
|
used: headerPrimary,
|
|
785
790
|
limit: 100,
|
|
786
791
|
format: { kind: "percent" },
|
|
787
792
|
resetsAt: getResetsAtIso(ctx, nowSec, primaryWindow),
|
|
788
|
-
periodDurationMs: PERIOD_SESSION_MS
|
|
793
|
+
periodDurationMs: reportedPeriod(primaryWindow, PERIOD_SESSION_MS)
|
|
789
794
|
}))
|
|
790
795
|
}
|
|
791
796
|
if (headerSecondary !== null) {
|
|
@@ -795,19 +800,19 @@
|
|
|
795
800
|
limit: 100,
|
|
796
801
|
format: { kind: "percent" },
|
|
797
802
|
resetsAt: getResetsAtIso(ctx, nowSec, secondaryWindow),
|
|
798
|
-
periodDurationMs: PERIOD_WEEKLY_MS
|
|
803
|
+
periodDurationMs: reportedPeriod(secondaryWindow, PERIOD_WEEKLY_MS)
|
|
799
804
|
}))
|
|
800
805
|
}
|
|
801
806
|
|
|
802
807
|
if (lines.length === 0 && data.rate_limit) {
|
|
803
808
|
if (data.rate_limit.primary_window && typeof data.rate_limit.primary_window.used_percent === "number") {
|
|
804
809
|
lines.push(ctx.line.progress({
|
|
805
|
-
label: "Session",
|
|
810
|
+
label: reportedPeriod(primaryWindow, PERIOD_SESSION_MS) === 30*86400000 ? "Monthly" : "Session",
|
|
806
811
|
used: data.rate_limit.primary_window.used_percent,
|
|
807
812
|
limit: 100,
|
|
808
813
|
format: { kind: "percent" },
|
|
809
814
|
resetsAt: getResetsAtIso(ctx, nowSec, primaryWindow),
|
|
810
|
-
periodDurationMs: PERIOD_SESSION_MS
|
|
815
|
+
periodDurationMs: reportedPeriod(primaryWindow, PERIOD_SESSION_MS)
|
|
811
816
|
}))
|
|
812
817
|
}
|
|
813
818
|
if (data.rate_limit.secondary_window && typeof data.rate_limit.secondary_window.used_percent === "number") {
|
|
@@ -817,7 +822,7 @@
|
|
|
817
822
|
limit: 100,
|
|
818
823
|
format: { kind: "percent" },
|
|
819
824
|
resetsAt: getResetsAtIso(ctx, nowSec, secondaryWindow),
|
|
820
|
-
periodDurationMs: PERIOD_WEEKLY_MS
|
|
825
|
+
periodDurationMs: reportedPeriod(secondaryWindow, PERIOD_WEEKLY_MS)
|
|
821
826
|
}))
|
|
822
827
|
}
|
|
823
828
|
}
|
|
@@ -16,7 +16,11 @@
|
|
|
16
16
|
"url": "https://chatgpt.com/settings/usage?tab=overview"
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
|
-
"supportedModes": [
|
|
19
|
+
"supportedModes": [
|
|
20
|
+
"oauth",
|
|
21
|
+
"local",
|
|
22
|
+
"web"
|
|
23
|
+
],
|
|
20
24
|
"autoMode": "oauth",
|
|
21
25
|
"webUrl": "https://chatgpt.com",
|
|
22
26
|
"lines": [
|
|
@@ -77,6 +81,11 @@
|
|
|
77
81
|
"type": "barChart",
|
|
78
82
|
"label": "Usage Trend",
|
|
79
83
|
"scope": "detail"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"type": "progress",
|
|
87
|
+
"label": "Monthly",
|
|
88
|
+
"scope": "overview"
|
|
80
89
|
}
|
|
81
90
|
]
|
|
82
91
|
}
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/cosmic.js",
|
|
29
29
|
"sha256": "eb869360f719b3b3b96311617c173e624efa05b91c0f7d31ce985f0a3a77d7a6",
|
|
30
30
|
"license": "MIT"
|
package/plugins/cursor/plugin.js
CHANGED
|
@@ -197,15 +197,16 @@
|
|
|
197
197
|
const injected = readInjectedCredential(ctx)
|
|
198
198
|
if (injected) return injected
|
|
199
199
|
|
|
200
|
-
const
|
|
201
|
-
const
|
|
200
|
+
const usable = value => typeof value === "string" && value.trim() && !value.trim().startsWith("cursor-safe-storage:") ? value.trim() : null
|
|
201
|
+
const sqliteAccessToken = usable(readStateValue(ctx, "cursorAuth/accessToken"))
|
|
202
|
+
const sqliteRefreshToken = usable(readStateValue(ctx, "cursorAuth/refreshToken"))
|
|
202
203
|
if (sqliteAccessToken || sqliteRefreshToken) {
|
|
203
204
|
return { accessToken: sqliteAccessToken, refreshToken: sqliteRefreshToken, source: "sqlite" }
|
|
204
205
|
}
|
|
205
206
|
// Generic CLI keychain targets are shared, not tied to an IDE variant.
|
|
206
207
|
// They cannot represent Nightly or an explicitly selected database profile.
|
|
207
|
-
const keychainAccessToken = sharedCredentialsAllowed(ctx) ? readKeychainValue(ctx, KEYCHAIN_ACCESS_TOKEN_SERVICE) : null
|
|
208
|
-
const keychainRefreshToken = sharedCredentialsAllowed(ctx) ? readKeychainValue(ctx, KEYCHAIN_REFRESH_TOKEN_SERVICE) : null
|
|
208
|
+
const keychainAccessToken = sharedCredentialsAllowed(ctx) ? usable(readKeychainValue(ctx, KEYCHAIN_ACCESS_TOKEN_SERVICE)) : null
|
|
209
|
+
const keychainRefreshToken = sharedCredentialsAllowed(ctx) ? usable(readKeychainValue(ctx, KEYCHAIN_REFRESH_TOKEN_SERVICE)) : null
|
|
209
210
|
|
|
210
211
|
if (keychainAccessToken || keychainRefreshToken) {
|
|
211
212
|
return {
|
|
@@ -215,6 +216,13 @@
|
|
|
215
216
|
}
|
|
216
217
|
}
|
|
217
218
|
|
|
219
|
+
if (sharedCredentialsAllowed(ctx) && (!ctx.provider?.instanceId || ctx.provider.instanceId === "cursor") && ctx.host.cursorPaths?.readCliAuth) {
|
|
220
|
+
try {
|
|
221
|
+
const cli = ctx.util.tryParseJson(ctx.host.cursorPaths.readCliAuth())
|
|
222
|
+
if (cli && (usable(cli.accessToken) || usable(cli.refreshToken)))
|
|
223
|
+
return {accessToken:usable(cli.accessToken),refreshToken:usable(cli.refreshToken),source:"cli-file"}
|
|
224
|
+
} catch (_) {}
|
|
225
|
+
}
|
|
218
226
|
return {
|
|
219
227
|
accessToken: null,
|
|
220
228
|
refreshToken: null,
|
|
@@ -231,6 +239,8 @@
|
|
|
231
239
|
if (!credential) return null
|
|
232
240
|
const accessToken = String(credential.accessToken || credential.sessionKey || "").trim()
|
|
233
241
|
const refreshToken = String(credential.refreshToken || "").trim()
|
|
242
|
+
if (accessToken.startsWith("cursor-safe-storage:") || refreshToken.startsWith("cursor-safe-storage:"))
|
|
243
|
+
throw {code:"credential-malformed",message:"Cursor safe-storage values are encrypted, not provider access tokens."}
|
|
234
244
|
if (!accessToken && !refreshToken) return null
|
|
235
245
|
return {
|
|
236
246
|
accessToken: accessToken || null,
|
|
@@ -238,6 +248,7 @@
|
|
|
238
248
|
source: "provider-account",
|
|
239
249
|
}
|
|
240
250
|
} catch (e) {
|
|
251
|
+
if (e && e.code) throw e
|
|
241
252
|
ctx.host.log.warn("provider account credential read failed: " + String(e))
|
|
242
253
|
return null
|
|
243
254
|
}
|
|
@@ -312,6 +323,7 @@
|
|
|
312
323
|
}
|
|
313
324
|
|
|
314
325
|
function persistAccessToken(ctx, source, accessToken) {
|
|
326
|
+
if (source === "cli-file") return false // The Cursor CLI owns its credential file.
|
|
315
327
|
if (source === "provider-account") {
|
|
316
328
|
try {
|
|
317
329
|
if (ctx.host.credentials && typeof ctx.host.credentials.update === "function") {
|
|
@@ -1180,7 +1192,7 @@
|
|
|
1180
1192
|
|
|
1181
1193
|
if (!accessToken && !refreshTokenValue) {
|
|
1182
1194
|
ctx.host.log.error("probe failed: no access or refresh token in sqlite/keychain")
|
|
1183
|
-
throw "Not logged in. " + LOGIN_HINT
|
|
1195
|
+
throw "Not logged in. Cursor encrypted sign-ins require `agent login` for the stable CLI, or explicit provider credentials. " + LOGIN_HINT
|
|
1184
1196
|
}
|
|
1185
1197
|
|
|
1186
1198
|
ctx.host.log.info("tokens loaded from " + authSource + ": accessToken=" + (accessToken ? "yes" : "no") + " refreshToken=" + (refreshTokenValue ? "yes" : "no"))
|
|
@@ -1202,7 +1214,7 @@
|
|
|
1202
1214
|
accessToken = refreshed
|
|
1203
1215
|
} else if (!accessToken) {
|
|
1204
1216
|
ctx.host.log.error("refresh failed and no access token available")
|
|
1205
|
-
throw "Not logged in. " + LOGIN_HINT
|
|
1217
|
+
throw "Not logged in. Cursor encrypted sign-ins require `agent login` for the stable CLI, or explicit provider credentials. " + LOGIN_HINT
|
|
1206
1218
|
}
|
|
1207
1219
|
}
|
|
1208
1220
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/devpass.js",
|
|
21
21
|
"sha256": "6fdfab17f543fc88f28b90f76fbe6edc6db3f4d3c7fa657a899c573d363a0886",
|
|
22
22
|
"license": "MIT"
|
package/plugins/exa/plugin.json
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/exa.js",
|
|
29
29
|
"sha256": "36d2cbf9973e160f2e0d2548ff1f9bbf254f94c9a09710004c0718749e5cdfbd",
|
|
30
30
|
"license": "MIT"
|
package/plugins/fal/plugin.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"setupFields": [],
|
|
17
17
|
"upstream": {
|
|
18
18
|
"repository": "https://github.com/steipete/CodexBar",
|
|
19
|
-
"revision": "
|
|
19
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
20
20
|
"path": "Sources/CodexBarCore/Resources/Plugins/fal.js",
|
|
21
21
|
"sha256": "5c3607c74508d8fcabe8fd04fbf6ed5edfec5364c24454a7dc9e8ab0ccedd30c",
|
|
22
22
|
"license": "MIT"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/flora.js",
|
|
29
29
|
"sha256": "451732a2e088769dcd023770cfa378c2c386eea8fad137c6db676b6e305e569f",
|
|
30
30
|
"license": "MIT"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/futureagi.js",
|
|
29
29
|
"sha256": "48c4e8b36e4556bc56dfe16f954e180aba0e11fb4111e382049fe015b4340c42",
|
|
30
30
|
"license": "MIT"
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"setupFields": [],
|
|
18
18
|
"upstream": {
|
|
19
19
|
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
-
"revision": "
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
21
|
"path": "Sources/CodexBarCore/Resources/Plugins/gemini-web.js",
|
|
22
22
|
"sha256": "7c71195603b2051ad74d85c0acc523546cf5ec62a600ae4900a1d7e54be7b02e",
|
|
23
23
|
"license": "MIT"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"upstream": {
|
|
26
26
|
"repository": "https://github.com/steipete/CodexBar",
|
|
27
|
-
"revision": "
|
|
27
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
28
28
|
"path": "Sources/CodexBarCore/Resources/Plugins/gitkraken.js",
|
|
29
29
|
"sha256": "c583890b74fc4c054cd818e560b30a17dd716c7611b554bd5b559f533a824ca2",
|
|
30
30
|
"license": "MIT"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter Steinberger
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// Generated by tools/vendor-codexbar-providers.cjs; see LICENSE.
|
|
2
|
+
globalThis.__usagestat_bundled_options = {"labels":["Credits","Additional","Additional"],"defaults":{},"autoMode":"web","balanceOnly":true};
|
|
3
|
+
(function(defineProvider) {
|
|
4
|
+
// BEGIN UPSTREAM Sources/CodexBarCore/Resources/Plugins/googledeveloper.js
|
|
5
|
+
function _nullishCoalesce(lhs, rhsFn) {
|
|
6
|
+
if (lhs != null) {
|
|
7
|
+
return lhs;
|
|
8
|
+
} else {
|
|
9
|
+
return rhsFn();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
defineProvider({
|
|
13
|
+
id: "googledeveloper",
|
|
14
|
+
name: "Google Developer Program",
|
|
15
|
+
settings: [{ key: "MESSAGES", title: "Google Developer Program", type: "plain" }],
|
|
16
|
+
endpoints: ["https://me.developers.google.com"],
|
|
17
|
+
capabilities: ["browser-cookies", "http-status"],
|
|
18
|
+
cookieDomains: ["me.developers.google.com", "google.com"],
|
|
19
|
+
cookiePolicy: { selection: "request-url", cache: "nonpersistent", imports: "access-gated" },
|
|
20
|
+
async fetchUsage(ctx) {
|
|
21
|
+
const domain = "me.developers.google.com";
|
|
22
|
+
const origin = `https://${domain}`;
|
|
23
|
+
const messages = JSON.parse(ctx.settings.get("MESSAGES") || "{}");
|
|
24
|
+
const message = (key, ...values) => {
|
|
25
|
+
let text = messages[key] || key;
|
|
26
|
+
for (const value of values) text = text.replace("%@", () => value);
|
|
27
|
+
return text;
|
|
28
|
+
};
|
|
29
|
+
const signIn = message(
|
|
30
|
+
"No Google Developer Program session cookies found. Sign in at me.developers.google.com/benefits or paste a Cookie header.",
|
|
31
|
+
);
|
|
32
|
+
if (ctx.browser.availability(domain) === "off")
|
|
33
|
+
throw ctx.fail.missingCredential(message("%@ cookies are disabled.", "Google Developer Program"));
|
|
34
|
+
const invalid = () => {
|
|
35
|
+
throw ctx.fail.parseFailure(
|
|
36
|
+
message("Google Developer Program returned an unrecognized response. Update CodexBar and try again."),
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
const json = (text) => {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(text);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
void error;
|
|
44
|
+
return invalid();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const array = (value) => (Array.isArray(value) ? value : invalid());
|
|
48
|
+
// Google Money arrays omit zero units and nanos.
|
|
49
|
+
const integer = (value) =>
|
|
50
|
+
value === null || value === undefined
|
|
51
|
+
? 0
|
|
52
|
+
: typeof value === "number" && Number.isSafeInteger(value)
|
|
53
|
+
? value
|
|
54
|
+
: invalid();
|
|
55
|
+
const money = (value) => {
|
|
56
|
+
const [currency, units, nanos] = array(value);
|
|
57
|
+
if (typeof currency !== "string" || !/^[A-Z]{3}$/.test(currency)) return invalid();
|
|
58
|
+
return { currency, amount: integer(units) + integer(nanos) / 1e9 };
|
|
59
|
+
};
|
|
60
|
+
// A malformed timestamp means an unknown date, never a failed refresh.
|
|
61
|
+
const date = (value) => {
|
|
62
|
+
const seconds = Array.isArray(value) ? value[0] : undefined;
|
|
63
|
+
return typeof seconds === "number" && Number.isSafeInteger(seconds) && seconds > 0
|
|
64
|
+
? ctx.date.unixSeconds(seconds)
|
|
65
|
+
: undefined;
|
|
66
|
+
};
|
|
67
|
+
const day = (value) =>
|
|
68
|
+
`${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, "0")}-${String(value.getDate()).padStart(2, "0")}`;
|
|
69
|
+
// WIZ_global_data values are JSON string literals.
|
|
70
|
+
const pageValue = (html, key) => {
|
|
71
|
+
const literal = ctx.html.matchFirst(html, `"${key}":("(?:[^"\\\\]|\\\\.)*")`);
|
|
72
|
+
return literal ? json(literal) : undefined;
|
|
73
|
+
};
|
|
74
|
+
// Signed-out requests redirect to accounts.google.com, which the host refuses, or answer 401 or 403.
|
|
75
|
+
const denied = (response) => {
|
|
76
|
+
if ((response.status >= 300 && response.status < 400) || response.status === 401 || response.status === 403)
|
|
77
|
+
return true;
|
|
78
|
+
if (response.status === 429) {
|
|
79
|
+
throw ctx.fail.rateLimited(message("Google Developer Program is rate limiting requests. Try again later."));
|
|
80
|
+
}
|
|
81
|
+
if (response.status >= 500) {
|
|
82
|
+
throw ctx.fail.providerUnavailable(message("Google Developer Program request failed. Try refreshing later."));
|
|
83
|
+
}
|
|
84
|
+
if (response.status !== 200) {
|
|
85
|
+
throw ctx.fail.apiFailure(message("Google Developer Program request failed. Try refreshing later."));
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
};
|
|
89
|
+
let unapplied;
|
|
90
|
+
let signedIn = false;
|
|
91
|
+
let rejected = false;
|
|
92
|
+
for await (const session of ctx.browser.sessions(domain)) {
|
|
93
|
+
const emails = [];
|
|
94
|
+
// Each authuser index is one signed-in Google account, and only one of them may hold the credit.
|
|
95
|
+
for (let account = 0; account < 8; account += 1) {
|
|
96
|
+
const page = await ctx.http.get(`${origin}/benefits?authuser=${account}`, {
|
|
97
|
+
cookieSession: session.id,
|
|
98
|
+
headers: { Accept: "text/html" },
|
|
99
|
+
retryPolicy: "transientIdempotent",
|
|
100
|
+
});
|
|
101
|
+
if (denied(page)) break;
|
|
102
|
+
// Signed-out pages also omit the page tokens.
|
|
103
|
+
const token = pageValue(page.bodyText, "SNlM0e");
|
|
104
|
+
const email = pageValue(page.bodyText, "oPEP7c");
|
|
105
|
+
if (!token || !email || emails.includes(email)) break;
|
|
106
|
+
|
|
107
|
+
const response = await ctx.http.post(
|
|
108
|
+
`${origin}/_/GoogleDeveloperProfile/data/batchexecute` +
|
|
109
|
+
`?rpcids=Ro0AYc&source-path=%2Fbenefits&hl=en&authuser=${account}&rt=c`,
|
|
110
|
+
{
|
|
111
|
+
cookieSession: session.id,
|
|
112
|
+
form: { "f.req": JSON.stringify([[["Ro0AYc", "[]", null, "generic"]]]), at: token },
|
|
113
|
+
headers: { Origin: origin, Referer: `${origin}/benefits` },
|
|
114
|
+
},
|
|
115
|
+
);
|
|
116
|
+
if (denied(response)) break;
|
|
117
|
+
emails.push(email);
|
|
118
|
+
signedIn = true;
|
|
119
|
+
// The chunked envelope alternates length lines with JSON chunks. Only the Ro0AYc result matters.
|
|
120
|
+
const result = response.bodyText
|
|
121
|
+
.split("\n")
|
|
122
|
+
.filter((line) => line.startsWith("["))
|
|
123
|
+
.flatMap((line) => array(json(line)))
|
|
124
|
+
.find((entry) => Array.isArray(entry) && entry[0] === "wrb.fr" && entry[1] === "Ro0AYc");
|
|
125
|
+
if (!result) return invalid();
|
|
126
|
+
// A per-account RPC error has no string payload, so try the next account.
|
|
127
|
+
if (typeof result[2] !== "string") continue;
|
|
128
|
+
const list = array(json(result[2]))[0];
|
|
129
|
+
// Benefit type 19 is the monthly Gen AI & Cloud credit of Google AI Pro and Ultra.
|
|
130
|
+
const credit = array(_nullishCoalesce(list, () => []))
|
|
131
|
+
.map((benefit) => array(benefit))
|
|
132
|
+
.find((benefit) => benefit[0] === 19);
|
|
133
|
+
if (!credit) continue;
|
|
134
|
+
const offer = array(_nullishCoalesce(credit[9], () => []));
|
|
135
|
+
// A credit that is not applied to a billing account yet has no money fields.
|
|
136
|
+
if (offer[6] === null || offer[6] === undefined) {
|
|
137
|
+
unapplied ??= email;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const billing = array(offer[6]);
|
|
141
|
+
const granted = money(billing[0]);
|
|
142
|
+
const remaining = money(billing[1]);
|
|
143
|
+
if (granted.amount <= 0) return invalid();
|
|
144
|
+
if (remaining.currency !== granted.currency) return invalid();
|
|
145
|
+
const currency = granted.currency;
|
|
146
|
+
const left = Math.max(0, remaining.amount);
|
|
147
|
+
const expiresAt = date(offer[1]);
|
|
148
|
+
const grantedAt = date(offer[16]);
|
|
149
|
+
const amounts = message(
|
|
150
|
+
"%@ of %@ left",
|
|
151
|
+
ctx.format.currency(left, currency),
|
|
152
|
+
ctx.format.currency(granted.amount, currency),
|
|
153
|
+
);
|
|
154
|
+
// The billing account is display-only, so an unexpected format never fails the refresh.
|
|
155
|
+
const rows =
|
|
156
|
+
typeof billing[2] === "string"
|
|
157
|
+
? [{ label: "Billing account", value: billing[2].replace(/^billingAccounts\//, "") }]
|
|
158
|
+
: [];
|
|
159
|
+
if (grantedAt) rows.push({ label: "Granted", value: day(grantedAt) });
|
|
160
|
+
return {
|
|
161
|
+
primary: {
|
|
162
|
+
usedPercent: ctx.pct(granted.amount - left, granted.amount),
|
|
163
|
+
resetDescription: expiresAt ? `${amounts} · ${message("Expires %@", day(expiresAt))}` : amounts,
|
|
164
|
+
},
|
|
165
|
+
cost: { used: left, currency, period: "Monthly credits", balance: left },
|
|
166
|
+
details: [{ title: "Billing", rows }],
|
|
167
|
+
identity: { email, loginMethod: message("Browser session") },
|
|
168
|
+
dataConfidence: "exact",
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (signedIn) break;
|
|
172
|
+
// A session whose first account fails the page or the RPC is signed out.
|
|
173
|
+
ctx.browser.rejectCookie(domain, session);
|
|
174
|
+
rejected = true;
|
|
175
|
+
}
|
|
176
|
+
if (unapplied) {
|
|
177
|
+
return {
|
|
178
|
+
details: [
|
|
179
|
+
{
|
|
180
|
+
title: "Cloud credits",
|
|
181
|
+
rows: [
|
|
182
|
+
{
|
|
183
|
+
label: "Status",
|
|
184
|
+
value: message("Not applied"),
|
|
185
|
+
secondaryValue: "me.developers.google.com/benefits",
|
|
186
|
+
},
|
|
187
|
+
],
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
identity: { email: unapplied, loginMethod: message("Browser session") },
|
|
191
|
+
dataConfidence: "exact",
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
if (signedIn)
|
|
195
|
+
throw ctx.fail.permissionDenied(message("No Cloud credit found. Check your Google Developer Program benefits."));
|
|
196
|
+
if (rejected) throw ctx.fail.authenticationExpired(`${message("Google session expired or invalid.")} ${signIn}`);
|
|
197
|
+
throw ctx.fail.missingCredential(
|
|
198
|
+
`${signIn} ${message("Supported browsers: %@. Use Manual for other browsers.", ctx.browser.supportedBrowsers)}`,
|
|
199
|
+
);
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// END UPSTREAM
|
|
204
|
+
})(globalThis.defineProvider);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "googledeveloper",
|
|
4
|
+
"name": "Google Developer Program",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"enabledByDefault": false,
|
|
8
|
+
"supportedModes": [
|
|
9
|
+
"web"
|
|
10
|
+
],
|
|
11
|
+
"autoMode": "web",
|
|
12
|
+
"usageDashboardUrl": "https://me.developers.google.com/benefits",
|
|
13
|
+
"webUrl": "https://me.developers.google.com",
|
|
14
|
+
"envVars": [
|
|
15
|
+
"GOOGLEDEVELOPER_COOKIE"
|
|
16
|
+
],
|
|
17
|
+
"setupFields": [],
|
|
18
|
+
"upstream": {
|
|
19
|
+
"repository": "https://github.com/steipete/CodexBar",
|
|
20
|
+
"revision": "1f6da9bec44455288ddee5ef6f3617a803d8eb2a",
|
|
21
|
+
"path": "Sources/CodexBarCore/Resources/Plugins/googledeveloper.js",
|
|
22
|
+
"sha256": "16f97c5fa06d7f4b4255f1e0413af01fa9a0ee7af03243701a40b0f6294564c0",
|
|
23
|
+
"license": "MIT"
|
|
24
|
+
}
|
|
25
|
+
}
|