@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.4 → 2.0.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.
@@ -2,8 +2,8 @@
2
2
  "arch": "x64",
3
3
  "archive": {
4
4
  "name": "usagestat-linux-x86_64.tar.gz",
5
- "sha256": "b8c064fa4002e5bef1de88e3da90d6e1b4c34bfcae029cd9e45a220667cfe2cc",
6
- "size": 12744844
5
+ "sha256": "adabb318a816967f269dd1fded375ff594794e4d6d8d8d998691607843444c75",
6
+ "size": 12859996
7
7
  },
8
8
  "buildSystem": "Linux-6.17.0-1022-azure-x86_64-with-glibc2.39",
9
9
  "dependencies": [
@@ -49,13 +49,13 @@
49
49
  "format": "elf",
50
50
  "machine": 62,
51
51
  "requiredGlibc": "2.39",
52
- "version": "2.0.0-alpha.4"
52
+ "version": "2.0.0"
53
53
  },
54
54
  "usagestatd": {
55
55
  "format": "elf",
56
56
  "machine": 62,
57
57
  "requiredGlibc": "2.39",
58
- "version": "2.0.0-alpha.4"
58
+ "version": "2.0.0"
59
59
  }
60
60
  },
61
61
  "files": [
@@ -176,7 +176,7 @@
176
176
  {
177
177
  "executable": false,
178
178
  "path": "plugins/aixy/plugin.json",
179
- "sha256": "c23f7b4ad78b643b9f7e78858c33ebe519980bf53770f77340a4869fc1b616e3",
179
+ "sha256": "2db33152ed4ff201cfa58b8f55f07642c20a183a5ee8855cf34037ad9183aaab",
180
180
  "size": 612
181
181
  },
182
182
  {
@@ -272,8 +272,8 @@
272
272
  {
273
273
  "executable": false,
274
274
  "path": "plugins/antigravity-cli/plugin.js",
275
- "sha256": "832f94f373aa28595473ce0440b5aabc5014079da7a8d1beb2b2ef4a0e5a3de1",
276
- "size": 19063
275
+ "sha256": "05f8afa20c932381090074dadda7d615b6dac0da41ba5e337eee1884036eb99d",
276
+ "size": 19527
277
277
  },
278
278
  {
279
279
  "executable": false,
@@ -296,8 +296,8 @@
296
296
  {
297
297
  "executable": false,
298
298
  "path": "plugins/antigravity-ide/plugin.js",
299
- "sha256": "451675333621529e4c68f9d1e779d7b0dcb4a9f2262b534055ad11fc6f395fd2",
300
- "size": 9329
299
+ "sha256": "120e636fe7a7554da35e439ae684d4ccc574b7b8ce05e52d9fd4a5ae3b283f7b",
300
+ "size": 9716
301
301
  },
302
302
  {
303
303
  "executable": false,
@@ -326,8 +326,8 @@
326
326
  {
327
327
  "executable": false,
328
328
  "path": "plugins/antigravity/plugin.js",
329
- "sha256": "de6a94dd87cc4196ba0525dd6e8914c5994622870e5ea32225f67a74e8872268",
330
- "size": 32083
329
+ "sha256": "9956e232bf6e6fb84047b45b51691a85b0cda59ea1dedff74ca7f744cad44722",
330
+ "size": 33250
331
331
  },
332
332
  {
333
333
  "executable": false,
@@ -362,7 +362,7 @@
362
362
  {
363
363
  "executable": false,
364
364
  "path": "plugins/atlascloud/plugin.json",
365
- "sha256": "8eab1d0b0eb55485b5775f46d52c88bbfe712035f9c9a51eb5d7e79bb198089f",
365
+ "sha256": "d4e20e1f4198d588cbaf60553f0196c73990c9cf108688b8b294bbd4d62c5245",
366
366
  "size": 620
367
367
  },
368
368
  {
@@ -452,7 +452,7 @@
452
452
  {
453
453
  "executable": false,
454
454
  "path": "plugins/bifrost/plugin.json",
455
- "sha256": "9f3f7aaf87e6bd76b8b3a89b565d93ae40c8a4fa481023fab85fc8ac52c06c25",
455
+ "sha256": "c7c54fe9dd37ccf4ca63c4067389c0f891a5d54f8e4b342673d1d5d8a5dc7c7b",
456
456
  "size": 571
457
457
  },
458
458
  {
@@ -848,7 +848,7 @@
848
848
  {
849
849
  "executable": false,
850
850
  "path": "plugins/devpass/plugin.json",
851
- "sha256": "14ae049ea0bd49d9f9d38c319fd60658c874abea00426138e25e9332e579ce0b",
851
+ "sha256": "e8428951def1df7c8d9f3e51f0de262fc646123eb99ab217aa6e240544119c64",
852
852
  "size": 613
853
853
  },
854
854
  {
@@ -1034,7 +1034,7 @@
1034
1034
  {
1035
1035
  "executable": false,
1036
1036
  "path": "plugins/gitkraken/plugin.json",
1037
- "sha256": "7699e58eb5e046e6a0872bf4b5dce449cd5470ee6e533698ef9afaf8dca15b31",
1037
+ "sha256": "849acb7cc3b0adcbdcadc2b14641f1ef72c6bf1d395d744de6c1e8d46dacb6ca",
1038
1038
  "size": 649
1039
1039
  },
1040
1040
  {
@@ -1100,7 +1100,7 @@
1100
1100
  {
1101
1101
  "executable": false,
1102
1102
  "path": "plugins/helmcode/plugin.json",
1103
- "sha256": "ea257bb0617b528f43c169be0776f0ba7e46524512a3c91938a9c10f04798a79",
1103
+ "sha256": "8d56bc4986643e414ca91b21aa9ea070779d046e6190455ce8a01cd73836a579",
1104
1104
  "size": 649
1105
1105
  },
1106
1106
  {
@@ -1130,7 +1130,7 @@
1130
1130
  {
1131
1131
  "executable": false,
1132
1132
  "path": "plugins/huggingface/plugin.json",
1133
- "sha256": "b7d653ee499c1f4ae6a208d53b5f9851353e42fe03106c28b0515030408c2fde",
1133
+ "sha256": "328bf38bd9ebbde209259fd3808a62df95d8ca5b2e28aceee37f7ab0ce42349c",
1134
1134
  "size": 683
1135
1135
  },
1136
1136
  {
@@ -1148,7 +1148,7 @@
1148
1148
  {
1149
1149
  "executable": false,
1150
1150
  "path": "plugins/hyper/plugin.json",
1151
- "sha256": "f08b2f8f0400b4dc748874e9b24e950f6194064a70459b06cf73aa7e8893bce0",
1151
+ "sha256": "7e7009af27f793bb579bedfe7e51de3ba0f41e971cd1cd096cf512c9e31f8bda",
1152
1152
  "size": 667
1153
1153
  },
1154
1154
  {
@@ -1358,7 +1358,7 @@
1358
1358
  {
1359
1359
  "executable": false,
1360
1360
  "path": "plugins/llmman/plugin.json",
1361
- "sha256": "1c2583d0d8b4ba536ae1a15e1165feebc65ac94c347f69627197b3c96ae2edf0",
1361
+ "sha256": "df91632fffe8f4bad5732fa6ca2af1462a921f752080bcff3e505fb789046fac",
1362
1362
  "size": 562
1363
1363
  },
1364
1364
  {
@@ -1478,8 +1478,8 @@
1478
1478
  {
1479
1479
  "executable": false,
1480
1480
  "path": "plugins/mistral/plugin.js",
1481
- "sha256": "5473b779cbb612eee2752bc5d4650d07b4236abbb4020576f328a3cea0993d48",
1482
- "size": 11181
1481
+ "sha256": "72673a6f395feb742a434089409dfa500e46e9bf2b10879356c4d23bf496b298",
1482
+ "size": 12931
1483
1483
  },
1484
1484
  {
1485
1485
  "executable": false,
@@ -1520,13 +1520,13 @@
1520
1520
  {
1521
1521
  "executable": false,
1522
1522
  "path": "plugins/muse/plugin.js",
1523
- "sha256": "85bc5e0c0d12d71d4e08ec5347cb7b60db567445a5e845c2abb879f1d22e8ba4",
1524
- "size": 14626
1523
+ "sha256": "1bb53d687b1ce19a0a5ac4f58ed7a0d762465e5deff2cdf1b8bf41bfdf049dd1",
1524
+ "size": 14654
1525
1525
  },
1526
1526
  {
1527
1527
  "executable": false,
1528
1528
  "path": "plugins/muse/plugin.json",
1529
- "sha256": "3f0b23b68af707f88c40d7d9e444e0c7696d27c491875566a37331c9c1a100ce",
1529
+ "sha256": "4c47425f1e5947fd6b354ec320f0e7f2e8152f973c83bd9d1f4e6fb5d6953814",
1530
1530
  "size": 669
1531
1531
  },
1532
1532
  {
@@ -1616,7 +1616,7 @@
1616
1616
  {
1617
1617
  "executable": false,
1618
1618
  "path": "plugins/nous/plugin.json",
1619
- "sha256": "83368dca145e023e027ffc9dfb28f7964b1315ce724158cc3f87af58217aacfd",
1619
+ "sha256": "f6365f4c7d786ee42a97b62251df0a5ee8c66b2db3c09f3abef6b5b136ba43f2",
1620
1620
  "size": 636
1621
1621
  },
1622
1622
  {
@@ -1856,13 +1856,13 @@
1856
1856
  {
1857
1857
  "executable": false,
1858
1858
  "path": "plugins/raycast/plugin.js",
1859
- "sha256": "239d60b2111645707fec1a16f03415934b0dd59a8534be123599f9cf9c806651",
1860
- "size": 7192
1859
+ "sha256": "70e92a070c748b435f10a7a65fcca9bdc670a9689d9535e32ea4c4197a706b35",
1860
+ "size": 7220
1861
1861
  },
1862
1862
  {
1863
1863
  "executable": false,
1864
1864
  "path": "plugins/raycast/plugin.json",
1865
- "sha256": "eb781c6270b5a3c5b7e60ac25466964ab50b0d4bc3170fdfde7ff12bd2728135",
1865
+ "sha256": "0c93302b898cb0c6f64b9486f7c568b34573e9b783a4214f932932b97b1a6644",
1866
1866
  "size": 640
1867
1867
  },
1868
1868
  {
@@ -1892,7 +1892,7 @@
1892
1892
  {
1893
1893
  "executable": false,
1894
1894
  "path": "plugins/replicate/plugin.json",
1895
- "sha256": "3c0c0547562b6f789d95f9ca8ca275103ae10cd3c432992e40597157d35e89df",
1895
+ "sha256": "64b1466259bd3c07df9d7561dc63faac3e8598c9c876534101231ac5f66abecd",
1896
1896
  "size": 655
1897
1897
  },
1898
1898
  {
@@ -2024,7 +2024,7 @@
2024
2024
  {
2025
2025
  "executable": false,
2026
2026
  "path": "plugins/typesafe/plugin.json",
2027
- "sha256": "2c251666a116dbe854d7dd7e4641ba4fa20af5890cbd8622225095b92832a935",
2027
+ "sha256": "ef13ae937833da47fe812dcc9a6ff6acc5c6a67141406f7dbe529b9b8d87ef18",
2028
2028
  "size": 653
2029
2029
  },
2030
2030
  {
@@ -2054,7 +2054,7 @@
2054
2054
  {
2055
2055
  "executable": false,
2056
2056
  "path": "plugins/v0/plugin.json",
2057
- "sha256": "885d515b63213f5b890c7aaec37199ce2c96230db2ab5152e4485c72f8754dac",
2057
+ "sha256": "e890781cdc0494968ca94f6c4a9b6a50fd1d3b6f3129035dd18b35b4d37d1e6e",
2058
2058
  "size": 601
2059
2059
  },
2060
2060
  {
@@ -2108,7 +2108,7 @@
2108
2108
  {
2109
2109
  "executable": false,
2110
2110
  "path": "plugins/vercel/plugin.json",
2111
- "sha256": "62019e82d3e9c86474e1d84d0c4d96c299fe8808f0fa75527c79b936fe177ebc",
2111
+ "sha256": "1d1a6de2ac852b3f8dd88ec171ee75cdab6fa910973696c12d1fcf42e0ec095d",
2112
2112
  "size": 641
2113
2113
  },
2114
2114
  {
@@ -2246,7 +2246,7 @@
2246
2246
  {
2247
2247
  "executable": false,
2248
2248
  "path": "plugins/xkiro/plugin.json",
2249
- "sha256": "4a86ec75d0d442ff9a828768d0be259e8b0ffc2711e7c8fdc776c12352b08d99",
2249
+ "sha256": "ec85b34efb7ba42990e94bff74855a6312667e8a33e93ba842ad7407989ed5f7",
2250
2250
  "size": 583
2251
2251
  },
2252
2252
  {
@@ -2270,8 +2270,8 @@
2270
2270
  {
2271
2271
  "executable": false,
2272
2272
  "path": "plugins/zai/plugin.js",
2273
- "sha256": "4e88d1a07226c08d85ca30c30027a381643ddc71704ad245b09a16ec1c705221",
2274
- "size": 7083
2273
+ "sha256": "f363ca91d2fd28f20a71e7c513847be98859616d4df075992bb8ba3009f4173a",
2274
+ "size": 7354
2275
2275
  },
2276
2276
  {
2277
2277
  "executable": false,
@@ -2342,14 +2342,14 @@
2342
2342
  {
2343
2343
  "executable": true,
2344
2344
  "path": "usagestat",
2345
- "sha256": "b7b66dee335b1a0217671332fa2d308461fd490ecfc05450ac04cd2c93ebffd8",
2346
- "size": 15221312
2345
+ "sha256": "69575b2cceae2e5b741e9b31abc6c73ca63a4ec0efbb92b2e2ef382654150a0f",
2346
+ "size": 15219888
2347
2347
  },
2348
2348
  {
2349
2349
  "executable": true,
2350
2350
  "path": "usagestatd",
2351
- "sha256": "7e7833a1168f1f802983721e87589a701d40e454aeba915ddd46afb2636136ba",
2352
- "size": 14749304
2351
+ "sha256": "dc3338f29b111e629191ac1d196dc39c51f71ac016881dd3f960add59af3acb9",
2352
+ "size": 15078080
2353
2353
  }
2354
2354
  ],
2355
2355
  "libc": "glibc",
@@ -2357,12 +2357,12 @@
2357
2357
  "minimumSystemQualified": true,
2358
2358
  "os": "linux",
2359
2359
  "package": "usagestat",
2360
- "resourcesSha256": "b11bb5bcb286e4e44f8ade7d27c34cea4064cb3e02782eb9a76899d2507971b5",
2360
+ "resourcesSha256": "d03362c9d6104bd044c9b5530f129bc2e4ca613090edc4eb470122375bc3e4d5",
2361
2361
  "schemaVersion": 1,
2362
2362
  "signing": "unsigned",
2363
- "sourceCommit": "bd5b7a162d7a3ddcf17995d3d20cb4b8cbd6d64b",
2363
+ "sourceCommit": "fbf84796d80fd5567516cec2e11b0784e7c187db",
2364
2364
  "sourceDirty": false,
2365
2365
  "target": "x86_64-unknown-linux-gnu",
2366
2366
  "toolchain": "rustc 1.89.0 (29483883e 2025-08-04)\nbinary: rustc\ncommit-hash: 29483883eed69d5fb4db01964cdf2af4d86e9cb2\ncommit-date: 2025-08-04\nhost: x86_64-unknown-linux-gnu\nrelease: 1.89.0\nLLVM version: 20.1.7",
2367
- "version": "2.0.0-alpha.4"
2367
+ "version": "2.0.0"
2368
2368
  }
package/package.json CHANGED
@@ -409,5 +409,5 @@
409
409
  "type": "git",
410
410
  "url": "https://github.com/hashimkarim/usagestat.git"
411
411
  },
412
- "version": "2.0.0-alpha.4"
412
+ "version": "2.0.0"
413
413
  }
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/aixy.js",
21
21
  "sha256": "975d98525503e286f9425c2a1d64fe00da8e2fdc0b00890e15c2cbcb9a37c125",
22
22
  "license": "MIT"
@@ -371,8 +371,9 @@
371
371
  function probeAgyToken(ctx, token) {
372
372
  var quota = probeAgyCloudCode(ctx, token)
373
373
  if (quota && !quota._authFailed) return quota
374
- var models = probeCloudCode(ctx, token)
374
+ var models = probeCloudCode(ctx, token, "agy", true)
375
375
  if (models && !models._authFailed) {
376
+ if (models._summaryLines) return { plan: null, lines: models._summaryLines }
376
377
  var lines = buildModelLines(ctx, parseCloudCodeModels(models))
377
378
  if (lines.length > 0) return { plan: null, lines: lines }
378
379
  return null
@@ -447,7 +448,7 @@
447
448
  return null
448
449
  }
449
450
 
450
- function callLs(ctx, port, scheme, csrf, method, body) {
451
+ function callLs(ctx, port, scheme, csrf, method, body, timeoutMs) {
451
452
  var resp = ctx.host.http.request({
452
453
  method: "POST",
453
454
  url: scheme + "://127.0.0.1:" + port + "/" + LS_SERVICE + "/" + method,
@@ -457,7 +458,7 @@
457
458
  "x-codeium-csrf-token": csrf,
458
459
  },
459
460
  bodyText: JSON.stringify(body || {}),
460
- timeoutMs: 10000,
461
+ timeoutMs: timeoutMs || 10000,
461
462
  dangerouslyIgnoreTls: scheme === "https",
462
463
  })
463
464
  if (resp.status < 200 || resp.status >= 300) {
@@ -514,7 +515,8 @@
514
515
  var label = (typeof c.label === "string") ? c.label.trim() : ""
515
516
  if (!label) continue
516
517
  var qi = c.quotaInfo
517
- var frac = (qi && typeof qi.remainingFraction === "number") ? qi.remainingFraction : 0
518
+ if (!qi || !Number.isFinite(qi.remainingFraction)) continue
519
+ var frac = qi.remainingFraction
518
520
  var rtime = (qi && qi.resetTime) || undefined
519
521
  var pool = poolLabel(normalizeLabel(label))
520
522
  if (!deduped[pool] || frac < deduped[pool].remainingFraction) {
@@ -547,7 +549,7 @@
547
549
 
548
550
  // --- Cloud Code API ---
549
551
 
550
- function requestCloudCodeJson(ctx, path, token, userAgent, body) {
552
+ function requestCloudCodeJson(ctx, path, token, userAgent, body, timeoutMs) {
551
553
  for (var i = 0; i < CLOUD_CODE_URLS.length; i++) {
552
554
  try {
553
555
  var resp = ctx.host.http.request({
@@ -560,7 +562,7 @@
560
562
  "User-Agent": userAgent || "antigravity",
561
563
  },
562
564
  bodyText: JSON.stringify(body || {}),
563
- timeoutMs: 15000,
565
+ timeoutMs: timeoutMs || 15000,
564
566
  })
565
567
  if (!resp || typeof resp.status !== "number" || !Number.isFinite(resp.status)) {
566
568
  ctx.host.log.warn("Cloud Code returned invalid response shape (" + CLOUD_CODE_URLS[i] + ")")
@@ -582,7 +584,12 @@
582
584
  return null
583
585
  }
584
586
 
585
- function probeCloudCode(ctx, token, userAgent) {
587
+ function probeCloudCode(ctx, token, userAgent, skipSummary) {
588
+ if (!skipSummary) {
589
+ var summary = requestCloudCodeJson(ctx, "/v1internal:retrieveUserQuotaSummary", token, userAgent, {}, 2000)
590
+ var lines = ctx.util.groupedQuotaLines(summary)
591
+ if (lines.length) return { _summaryLines: lines }
592
+ }
586
593
  return requestCloudCodeJson(ctx, FETCH_MODELS_PATH, token, userAgent, {})
587
594
  }
588
595
 
@@ -603,7 +610,8 @@
603
610
  ""
604
611
  if (!displayName) continue
605
612
  var qi = m.quotaInfo
606
- var frac = (qi && typeof qi.remainingFraction === "number") ? qi.remainingFraction : 0
613
+ if (!qi || !Number.isFinite(qi.remainingFraction)) continue
614
+ var frac = qi.remainingFraction
607
615
  var rtime = (qi && qi.resetTime) || undefined
608
616
  configs.push({
609
617
  label: displayName,
@@ -634,7 +642,8 @@
634
642
  if (!bucket || typeof bucket !== "object") continue
635
643
  var modelId = (typeof bucket.modelId === "string" && bucket.modelId.trim()) || ""
636
644
  if (!modelId) continue
637
- var frac = (typeof bucket.remainingFraction === "number") ? bucket.remainingFraction : 0
645
+ if (!Number.isFinite(bucket.remainingFraction)) continue
646
+ var frac = bucket.remainingFraction
638
647
  configs.push({
639
648
  label: modelId,
640
649
  quotaInfo: { remainingFraction: frac, resetTime: bucket.resetTime || undefined },
@@ -652,6 +661,9 @@
652
661
  ? loadData.cloudaicompanionProject.trim()
653
662
  : null
654
663
  var quotaData = null
664
+ var summary = requestCloudCodeJson(ctx, "/v1internal:retrieveUserQuotaSummary", token, "agy", project ? { project: project } : {}, 2000)
665
+ var summaryLines = ctx.util.groupedQuotaLines(summary)
666
+ if (summaryLines.length) return { plan: readAgyPlan(loadData), lines: summaryLines }
655
667
  if (project) {
656
668
  quotaData = requestCloudCodeJson(ctx, RETRIEVE_QUOTA_PATH, token, "agy", { project: project })
657
669
  }
@@ -682,7 +694,13 @@
682
694
  locale: "en",
683
695
  }
684
696
 
685
- // Try GetUserStatus first, fall back to GetCommandModelConfigs
697
+ var summaryLines = []
698
+ try {
699
+ summaryLines = ctx.util.groupedQuotaLines(callLs(ctx, found.port, found.scheme, discovery.csrf,
700
+ "RetrieveUserQuotaSummary", { forceRefresh: true }, 2000))
701
+ } catch (_) {}
702
+
703
+ // GetUserStatus also supplies identity when grouped quota is available.
686
704
  var data = null
687
705
  try {
688
706
  data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetUserStatus", { metadata: metadata })
@@ -691,7 +709,7 @@
691
709
  }
692
710
  var hasUserStatus = data && data.userStatus
693
711
 
694
- if (!hasUserStatus) {
712
+ if (!hasUserStatus && !summaryLines.length) {
695
713
  ctx.host.log.warn("GetUserStatus failed, trying GetCommandModelConfigs")
696
714
  data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetCommandModelConfigs", { metadata: metadata })
697
715
  }
@@ -702,6 +720,8 @@
702
720
  configs = (data.userStatus.cascadeModelConfigData || {}).clientModelConfigs || []
703
721
  } else if (data && data.clientModelConfigs) {
704
722
  configs = data.clientModelConfigs
723
+ } else if (summaryLines.length) {
724
+ configs = []
705
725
  } else {
706
726
  return null
707
727
  }
@@ -713,7 +733,7 @@
713
733
  filtered.push(configs[j])
714
734
  }
715
735
 
716
- var lines = buildModelLines(ctx, filtered)
736
+ var lines = summaryLines.length ? summaryLines : buildModelLines(ctx, filtered)
717
737
  if (lines.length === 0) return null
718
738
 
719
739
  var plan = null
@@ -817,6 +837,7 @@
817
837
  }
818
838
 
819
839
  if (ccData && !ccData._authFailed) {
840
+ if (ccData._summaryLines) return { plan: null, lines: ccData._summaryLines }
820
841
  var configs = parseCloudCodeModels(ccData)
821
842
  var lines = buildModelLines(ctx, configs)
822
843
  if (lines.length > 0) return { plan: null, lines: lines }
@@ -294,7 +294,7 @@
294
294
  "User-Agent": "agy",
295
295
  },
296
296
  bodyText: JSON.stringify(body || {}),
297
- timeoutMs: 15000,
297
+ timeoutMs: opts.timeoutMs || 15000,
298
298
  })
299
299
  } catch (e) {
300
300
  if (opts.optional) {
@@ -540,6 +540,12 @@
540
540
  if (!loadData) throw REQUEST_FAILED_MESSAGE
541
541
  var plan = readPlan(loadData)
542
542
 
543
+ var project = typeof loadData.cloudaicompanionProject === "string" ? loadData.cloudaicompanionProject.trim() : ""
544
+ var summary = requestJsonAcrossBases(ctx, "/v1internal:retrieveUserQuotaSummary", authState.token,
545
+ project ? { project: project } : {}, { optional: true, timeoutMs: 2000 })
546
+ var summaryLines = ctx.util.groupedQuotaLines(summary)
547
+ if (summaryLines.length) return { plan: plan || undefined, lines: summaryLines }
548
+
543
549
  var buckets = []
544
550
  // fetchAvailableModels rejects `metadata` in the body (HTTP 400); use {} like Antigravity IDE.
545
551
  var fetchData = requestJsonAcrossBases(ctx, FETCH_MODELS_PATH, authState.token, {}, {
@@ -82,7 +82,7 @@
82
82
  return null
83
83
  }
84
84
 
85
- function callLs(ctx, port, scheme, csrf, method, body) {
85
+ function callLs(ctx, port, scheme, csrf, method, body, timeoutMs) {
86
86
  var resp = ctx.host.http.request({
87
87
  method: "POST",
88
88
  url: scheme + "://127.0.0.1:" + port + "/" + LS_SERVICE + "/" + method,
@@ -92,7 +92,7 @@
92
92
  "x-codeium-csrf-token": csrf,
93
93
  },
94
94
  bodyText: JSON.stringify(body || {}),
95
- timeoutMs: 10000,
95
+ timeoutMs: timeoutMs || 10000,
96
96
  dangerouslyIgnoreTls: scheme === "https",
97
97
  })
98
98
  if (resp.status < 200 || resp.status >= 300) {
@@ -149,7 +149,8 @@
149
149
  var label = (typeof c.label === "string") ? c.label.trim() : ""
150
150
  if (!label) continue
151
151
  var qi = c.quotaInfo
152
- var frac = (qi && typeof qi.remainingFraction === "number") ? qi.remainingFraction : 0
152
+ if (!qi || !Number.isFinite(qi.remainingFraction)) continue
153
+ var frac = qi.remainingFraction
153
154
  var rtime = (qi && qi.resetTime) || undefined
154
155
  var pool = poolLabel(normalizeLabel(label))
155
156
  if (!deduped[pool] || frac < deduped[pool].remainingFraction) {
@@ -198,7 +199,13 @@
198
199
  locale: "en",
199
200
  }
200
201
 
201
- // Try GetUserStatus first, fall back to GetCommandModelConfigs
202
+ var summaryLines = []
203
+ try {
204
+ summaryLines = ctx.util.groupedQuotaLines(callLs(ctx, found.port, found.scheme, discovery.csrf,
205
+ "RetrieveUserQuotaSummary", { forceRefresh: true }, 2000))
206
+ } catch (_) {}
207
+
208
+ // GetUserStatus also supplies identity when grouped quota is available.
202
209
  var data = null
203
210
  try {
204
211
  data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetUserStatus", { metadata: metadata })
@@ -207,7 +214,7 @@
207
214
  }
208
215
  var hasUserStatus = data && data.userStatus
209
216
 
210
- if (!hasUserStatus) {
217
+ if (!hasUserStatus && !summaryLines.length) {
211
218
  ctx.host.log.warn("GetUserStatus failed, trying GetCommandModelConfigs")
212
219
  data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetCommandModelConfigs", { metadata: metadata })
213
220
  }
@@ -218,6 +225,8 @@
218
225
  configs = (data.userStatus.cascadeModelConfigData || {}).clientModelConfigs || []
219
226
  } else if (data && data.clientModelConfigs) {
220
227
  configs = data.clientModelConfigs
228
+ } else if (summaryLines.length) {
229
+ configs = []
221
230
  } else {
222
231
  throw "Start Antigravity IDE and try again."
223
232
  }
@@ -229,7 +238,7 @@
229
238
  filtered.push(configs[j])
230
239
  }
231
240
 
232
- var lines = buildModelLines(ctx, filtered)
241
+ var lines = summaryLines.length ? summaryLines : buildModelLines(ctx, filtered)
233
242
  if (lines.length === 0) throw "Start Antigravity IDE and try again."
234
243
 
235
244
  var plan = null
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/atlascloud.js",
20
20
  "sha256": "852fb78abaf4fcdbbfbfeac0b60d6b82a9ca9b1d1d2f9014f6e5299b41ac47fa",
21
21
  "license": "MIT"
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/bifrost.js",
20
20
  "sha256": "b7576d59ccd077c812118cf09d282042589a80df470c621e414583050f03aa07",
21
21
  "license": "MIT"
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/devpass.js",
20
20
  "sha256": "6fdfab17f543fc88f28b90f76fbe6edc6db3f4d3c7fa657a899c573d363a0886",
21
21
  "license": "MIT"
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/gitkraken.js",
21
21
  "sha256": "c583890b74fc4c054cd818e560b30a17dd716c7611b554bd5b559f533a824ca2",
22
22
  "license": "MIT"
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/helmcode.js",
21
21
  "sha256": "475a2002673d59b95ef4da487639f8e2574ba07a0e31e80f10ea3556eeb3427e",
22
22
  "license": "MIT"
@@ -17,7 +17,7 @@
17
17
  ],
18
18
  "upstream": {
19
19
  "repository": "https://github.com/steipete/CodexBar",
20
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
20
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
21
21
  "path": "Sources/CodexBarCore/Resources/Plugins/huggingface.js",
22
22
  "sha256": "78cb1bb09535c71f7cb9d1a6336efb4ead44b36a1d4716602c1f7a1e35821291",
23
23
  "license": "MIT"
@@ -18,7 +18,7 @@
18
18
  ],
19
19
  "upstream": {
20
20
  "repository": "https://github.com/steipete/CodexBar",
21
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
21
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
22
22
  "path": "Sources/CodexBarCore/Resources/Plugins/hyper.js",
23
23
  "sha256": "893e1a9a91e7af57522bcc39791d77d6fe3b8ae0d61384aee1768f5f419636cd",
24
24
  "license": "MIT"
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/llmman.js",
20
20
  "sha256": "eb48d35bb101fda0e3bf122eea358c6e16ea937ac72376e6e4ede52e7828d209",
21
21
  "license": "MIT"
@@ -29,34 +29,51 @@
29
29
  return { month: now.getUTCMonth() + 1, year: now.getUTCFullYear() }
30
30
  }
31
31
 
32
- function aggregateModels(models, prices) {
32
+ function aggregateModels(models, prices, countsTokens) {
33
33
  var total = 0
34
+ var complete = true
34
35
  var inputTokens = 0
35
36
  var outputTokens = 0
36
- if (!models) return { cost: 0, inputTokens: 0, outputTokens: 0 }
37
+ if (!models) return { cost: 0, complete: true, inputTokens: 0, outputTokens: 0 }
37
38
  var keys = Object.keys(models)
38
39
  for (var i = 0; i < keys.length; i++) {
39
40
  var data = models[keys[i]]
40
- total += sumEntries(data.input, prices)
41
- total += sumEntries(data.output, prices)
42
- total += sumEntries(data.cached, prices)
43
- inputTokens += countEntries(data.input)
44
- outputTokens += countEntries(data.output)
41
+ for (var entries of [data.input, data.output, data.cached]) {
42
+ var sum = sumEntries(entries, prices)
43
+ total += sum.cost
44
+ complete = complete && sum.complete
45
+ }
46
+ if (countsTokens !== false) {
47
+ inputTokens += countEntries(data.input)
48
+ outputTokens += countEntries(data.output)
49
+ }
45
50
  }
46
- return { cost: total, inputTokens: inputTokens, outputTokens: outputTokens }
51
+ if (!Number.isFinite(total)) throw new Error('Invalid Mistral billing total.')
52
+ return { cost: total, complete: complete, inputTokens: inputTokens, outputTokens: outputTokens }
53
+ }
54
+
55
+ function priceKey(entry, unqualified) {
56
+ return JSON.stringify([entry.event_type ?? null, entry.billing_metric ?? null, entry.billing_group ?? null,
57
+ unqualified ? null : entry.api_zone ?? null, unqualified ? null : entry.service_tier ?? null])
47
58
  }
48
59
 
49
60
  function sumEntries(entries, prices) {
50
- if (!entries) return 0
61
+ if (!entries) return { cost: 0, complete: true }
51
62
  var total = 0
63
+ var complete = true
52
64
  for (var i = 0; i < entries.length; i++) {
53
65
  var e = entries[i]
54
66
  var paid = e.value_paid != null ? e.value_paid : (e.value || 0)
55
- var key = e.billing_metric + "::" + e.billing_group
56
- var price = prices[key] || 0
57
- total += paid * price
67
+ if (typeof paid !== 'number' || !Number.isFinite(paid) || paid < 0)
68
+ throw new Error('Invalid Mistral billed quantity.')
69
+ if (paid === 0) continue
70
+ // A different event type, region or tier must never supply the price.
71
+ // Legacy unqualified rows are the only supported fallback.
72
+ var price = prices.get(priceKey(e, false)) ?? prices.get(priceKey(e, true))
73
+ if (price === undefined) complete = false
74
+ else total += paid * price
58
75
  }
59
- return total
76
+ return { cost: total, complete: complete }
60
77
  }
61
78
 
62
79
  function countEntries(entries) {
@@ -71,13 +88,14 @@
71
88
  }
72
89
 
73
90
  function buildPriceIndex(prices) {
74
- var index = {}
91
+ var index = new Map()
75
92
  if (!prices) return index
76
93
  for (var i = 0; i < prices.length; i++) {
77
94
  var p = prices[i]
78
- if (p.billing_metric && p.billing_group && p.price) {
79
- var key = p.billing_metric + "::" + p.billing_group
80
- index[key] = parseFloat(p.price) || 0
95
+ var validPrice = typeof p.price === 'number' || (typeof p.price === 'string' && p.price.trim() !== '')
96
+ var price = validPrice ? Number(p.price) : NaN
97
+ if (p.billing_metric && p.billing_group && Number.isFinite(price) && price >= 0) {
98
+ index.set(priceKey(p, false), price)
81
99
  }
82
100
  }
83
101
  return index
@@ -217,6 +235,7 @@
217
235
  var symbol = billing.currency_symbol || "€"
218
236
 
219
237
  var totalCost = 0
238
+ var completeCost = true
220
239
  var totalInput = 0
221
240
  var totalOutput = 0
222
241
 
@@ -225,26 +244,39 @@
225
244
  if (!completions[c] || !completions[c].models) continue
226
245
  var r = aggregateModels(completions[c].models, prices)
227
246
  totalCost += r.cost; totalInput += r.inputTokens; totalOutput += r.outputTokens
247
+ completeCost = completeCost && r.complete
228
248
  }
229
249
 
230
250
  var extras = [billing.ocr, billing.connectors, billing.audio]
231
251
  for (var i = 0; i < extras.length; i++) {
232
252
  if (extras[i] && extras[i].models) {
233
- totalCost += aggregateModels(extras[i].models, prices).cost
253
+ var extra = aggregateModels(extras[i].models, prices, false)
254
+ totalCost += extra.cost
255
+ completeCost = completeCost && extra.complete
234
256
  }
235
257
  }
236
258
 
237
259
  if (billing.libraries_api) {
238
260
  var lib = billing.libraries_api
239
- if (lib.pages && lib.pages.models) totalCost += aggregateModels(lib.pages.models, prices).cost
240
- if (lib.tokens && lib.tokens.models) totalCost += aggregateModels(lib.tokens.models, prices).cost
261
+ for (var category of [lib.pages, lib.tokens]) {
262
+ var extra = aggregateModels(category && category.models, prices, false)
263
+ totalCost += extra.cost
264
+ completeCost = completeCost && extra.complete
265
+ }
241
266
  }
242
267
 
243
- var costStr = symbol + totalCost.toFixed(4) + " this month (" + currency + ")"
268
+ if (billing.fine_tuning) for (var category of [billing.fine_tuning.training, billing.fine_tuning.storage]) {
269
+ var extra = aggregateModels(category, prices, false)
270
+ totalCost += extra.cost
271
+ completeCost = completeCost && extra.complete
272
+ }
273
+ if (!Number.isFinite(totalCost)) throw new Error('Invalid Mistral billing total.')
274
+ var costStr = symbol + totalCost.toFixed(4) + (completeCost ? "" : "+") + " this month (" + currency + ")"
244
275
  var tokenDetail = totalInput + " in / " + totalOutput + " out tokens"
245
276
 
246
277
  var lines = [
247
- ctx.line.text({ label: "Monthly spend", value: costStr }),
278
+ ctx.line.text({ label: "Monthly spend", value: costStr,
279
+ subtitle: completeCost ? undefined : "Partial total: some billing rows have no matching price." }),
248
280
  ctx.line.text({ label: "Tokens", value: tokenDetail }),
249
281
  ]
250
282
 
@@ -135,7 +135,7 @@ defineProvider({
135
135
  for await (const session of ctx.browser.sessions("dev.meta.ai")) {
136
136
  if (requestsLeft <= 0) break;
137
137
  let rejected = false;
138
- const headers = { Cookie: session.header, "User-Agent": "CodexBar" };
138
+ const headers = { Cookie: _nullishCoalesce(session.header, () => ""), "User-Agent": "CodexBar" };
139
139
  const get = async (path) => {
140
140
  if (requestsLeft-- <= 0) throw new Error("Muse browser request budget exhausted");
141
141
  const response = await ctx.http.get(`https://dev.meta.ai${path}`, { headers, timeoutSeconds: 8 });
@@ -18,9 +18,9 @@
18
18
  ],
19
19
  "upstream": {
20
20
  "repository": "https://github.com/steipete/CodexBar",
21
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
21
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
22
22
  "path": "Sources/CodexBarCore/Resources/Plugins/muse.js",
23
- "sha256": "80ddeae2d6f2fb90b22b3a978dfdd5f8904a1766687a19bc93c8108fd5a7dc41",
23
+ "sha256": "aa5cb7f56d51c03534cd30f45e45fb457e7c2493eb6c318d4929dac33563577d",
24
24
  "license": "MIT"
25
25
  }
26
26
  }
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/nous.js",
21
21
  "sha256": "160f5329bf4895a061d3bed74d0476283d3abad47e071fb868d667c0c5cb485e",
22
22
  "license": "MIT"
@@ -32,7 +32,7 @@ defineProvider({
32
32
  let response;
33
33
  let rejected = false;
34
34
  for await (const session of ctx.browser.sessions(domain)) {
35
- const cookie = session.header
35
+ const cookie = _nullishCoalesce(session.header, () => "")
36
36
  .split(";")
37
37
  .map((part) => part.trim())
38
38
  .filter((part) => /^(?:__raycast_session|csrf_token)=/.test(part))
@@ -16,9 +16,9 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/raycast.js",
21
- "sha256": "1f93bd240923c8427615b2de3a40d46f167b907864c01475754b115b804c3ee4",
21
+ "sha256": "df8f6d185cb67fd9ec9b622d2321a6d4e5395576b9ab54b1725aac272c95ecb7",
22
22
  "license": "MIT"
23
23
  }
24
24
  }
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/replicate.js",
21
21
  "sha256": "d240c36fa142ee91ce90ae52a2c6814613d2d5533a00c8a4c7ecec2f9386006c",
22
22
  "license": "MIT"
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/typesafe.js",
21
21
  "sha256": "eb3941346a966b3f5f9e0010f17edaeed7dfb6c8b0331319a86f26da10d51980",
22
22
  "license": "MIT"
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "upstream": {
18
18
  "repository": "https://github.com/steipete/CodexBar",
19
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
19
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
20
20
  "path": "Sources/CodexBarCore/Resources/Plugins/v0.js",
21
21
  "sha256": "5f54a9329dca35d59d76e427c34d4d9db8d3400d0b38c5fcee8899928a900019",
22
22
  "license": "MIT"
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/vercel.js",
20
20
  "sha256": "27b39f42709e93a2cfbf850171f198069553c99967f9b7ba6d16614862cb084a",
21
21
  "license": "MIT"
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "upstream": {
17
17
  "repository": "https://github.com/steipete/CodexBar",
18
- "revision": "78ba5a1e65e6859da59a21b799df95ab91bc0b89",
18
+ "revision": "25bba9b7fd9ce83c33053958f7366e23b2dc8a82",
19
19
  "path": "Sources/CodexBarCore/Resources/Plugins/xkiro.js",
20
20
  "sha256": "03bfcb8e518577ee18dd335e4e1e1f7d629d3e5abdf2216b187b1cba8b683853",
21
21
  "license": "MIT"
@@ -106,7 +106,11 @@
106
106
  format: { kind: "count", suffix: "searches" }, periodDurationMs: MONTH_MS,
107
107
  resetsAt: reset(ctx, mcp, MONTH_MS) }))
108
108
  }
109
- if (!lines.length) lines.push(ctx.line.badge({ label: "Status", text: "No usage data", color: "#a3a3a3" }))
109
+ const recognized = limits.filter((item) => ["TOKENS_LIMIT", "CREDIT_LIMIT", "TIME_LIMIT"].includes(item.type || item.name))
110
+ if (!quota.length || recognized.length !== limits.length) lines.push(ctx.line.text({
111
+ label: quota.length ? "Additional quota" : "Coding Plan usage", value: "Unavailable",
112
+ subtitle: "Check Usage Dashboard for complete plan usage.",
113
+ }))
110
114
 
111
115
  if (quota.some((item) => (item.type || item.name) === "CREDIT_LIMIT")) {
112
116
  const now = new Date(ctx.nowIso)
package/usagestat CHANGED
Binary file
package/usagestatd CHANGED
Binary file