dsh-subscriptions 0.2.3 → 0.3.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.
Files changed (41) hide show
  1. package/README.md +9 -21
  2. package/lib/auth/rpc.d.ts +2 -20
  3. package/lib/auth/rpc.js +3 -49
  4. package/lib/client/ProviderAccountManager.d.ts +1 -1
  5. package/lib/client/ProviderAccountManager.js +86 -110
  6. package/lib/client/ProviderModelEditor.d.ts +1 -1
  7. package/lib/client/ProviderModelEditor.js +2 -6
  8. package/lib/client/SubscriptionUsageBadge.d.ts +8 -2
  9. package/lib/client/SubscriptionUsageBadge.js +24 -17
  10. package/lib/client/SubscriptionsSection.js +1 -2
  11. package/lib/client/locales.d.ts +2 -32
  12. package/lib/client/locales.js +2 -32
  13. package/lib/client/model-filter.js +1 -1
  14. package/lib/client/subscription-card-styles.d.ts +1 -1
  15. package/lib/client/subscription-card-styles.js +1 -1
  16. package/lib/client.js +234 -518
  17. package/lib/client.js.map +1 -1
  18. package/lib/index.js +208 -3305
  19. package/lib/providers/claude.d.ts +3 -1
  20. package/lib/providers/claude.js +2 -2
  21. package/lib/providers/ollama-settings.d.ts +1 -1
  22. package/lib/providers/ollama-settings.js +1 -1
  23. package/lib/providers/pool-usage.d.ts +10 -9
  24. package/lib/providers/pool-usage.js +30 -19
  25. package/lib/providers/pool.d.ts +6 -6
  26. package/lib/providers/pool.js +24 -12
  27. package/package.json +1 -7
  28. package/lib/client/CursorCard.d.ts +0 -9
  29. package/lib/client/CursorCard.js +0 -151
  30. package/lib/providers/cursor-adapter.d.ts +0 -50
  31. package/lib/providers/cursor-adapter.js +0 -304
  32. package/lib/providers/cursor-auth.d.ts +0 -43
  33. package/lib/providers/cursor-auth.js +0 -221
  34. package/lib/providers/cursor-model-settings.d.ts +0 -15
  35. package/lib/providers/cursor-model-settings.js +0 -60
  36. package/lib/providers/cursor-usage.d.ts +0 -9
  37. package/lib/providers/cursor-usage.js +0 -131
  38. package/vendor/cursor/LICENSE +0 -21
  39. package/vendor/cursor/index.d.ts +0 -18
  40. package/vendor/cursor/index.js +0 -3574
  41. package/vendor/cursor/proto.js +0 -254
package/lib/client.js CHANGED
@@ -183,22 +183,6 @@ const en = {
183
183
  externalUsageApiKey: "API key",
184
184
  externalUsageConfigure: "No API key found at {ref}. Add one in Settings → Models.",
185
185
  externalUsageUnavailable: "Usage status unavailable: {message}",
186
- cursorTitle: "Cursor",
187
- cursorOpenLogin: "Open Cursor sign-in",
188
- cursorWaiting: "Waiting for Cursor sign-in…",
189
- cursorConnected: "Connected",
190
- cursorManageTitle: "Manage Cursor",
191
- cursorManageSignIn: "Sign in to see the models available to this Cursor account.",
192
- cursorAccountsHint: "Cursor uses one connected account. Choose which of its models appear in the model picker.",
193
- cursorManageHint: "Choose model visibility here. Refresh fetches the current models from Cursor; Save changes updates the model picker.",
194
- cursorFilterModels: "Filter models",
195
- cursorModelsLoading: "Loading Cursor models…",
196
- cursorModelsError: "Could not load Cursor models: {message}",
197
- cursorModelsCount: "{count} models available",
198
- cursorIncluded: "Included usage",
199
- cursorModels: "Cursor Models",
200
- cursorOtherModels: "Other Models",
201
- cursorIncludedRequests: "Included requests",
202
186
  modelDefaultsTitle: "Default reasoning effort",
203
187
  modelDefaultsHint: "The model picker preselects this level when you switch to the model; models without levels always follow the provider.",
204
188
  modelDefaultsFollowProvider: "Follow provider",
@@ -239,6 +223,7 @@ const en = {
239
223
  usageBadgeModelCount: "{count} model quotas",
240
224
  usageBadgeModelUnavailable: "Current model quota unavailable",
241
225
  usageBadgeMoreWindows: "More quota windows ({count})",
226
+ usageBadgeAllCodexExhausted: "All displayed Codex accounts report exhausted subscription quota. New requests stop before spending paid credits. After an external reset, use Settings > Subscriptions > Refresh to re-check usage.",
242
227
  speed: "Speed",
243
228
  speedStandard: "Standard",
244
229
  speedStandardDescription: "Default speed",
@@ -429,22 +414,6 @@ const zh = {
429
414
  externalUsageApiKey: "API 密钥",
430
415
  externalUsageConfigure: "未在 {ref} 找到 API 密钥。请在「设置 → 模型」中添加。",
431
416
  externalUsageUnavailable: "无法获取用量状态:{message}",
432
- cursorTitle: "Cursor",
433
- cursorOpenLogin: "打开 Cursor 登录页面",
434
- cursorWaiting: "等待 Cursor 登录…",
435
- cursorConnected: "已连接",
436
- cursorManageTitle: "管理 Cursor",
437
- cursorManageSignIn: "登录后可查看此 Cursor 账号可用的模型。",
438
- cursorAccountsHint: "Cursor 使用一个已连接账号。可在此选择模型选择器中显示的模型。",
439
- cursorManageHint: "在此选择模型是否显示。刷新可从 Cursor 获取当前模型;保存更改后更新模型选择器。",
440
- cursorFilterModels: "筛选模型",
441
- cursorModelsLoading: "正在加载 Cursor 模型…",
442
- cursorModelsError: "无法加载 Cursor 模型:{message}",
443
- cursorModelsCount: "可用模型:{count} 个",
444
- cursorIncluded: "套餐内用量",
445
- cursorModels: "Cursor 模型",
446
- cursorOtherModels: "其他模型",
447
- cursorIncludedRequests: "套餐内请求",
448
417
  modelDefaultsTitle: "默认推理档",
449
418
  modelDefaultsHint: "切换到该模型时,模型选择器会预选此档位;没有推理档的模型始终跟随服务商默认。",
450
419
  modelDefaultsFollowProvider: "跟随服务商",
@@ -485,6 +454,7 @@ const zh = {
485
454
  usageBadgeModelCount: "{count} 个模型配额",
486
455
  usageBadgeModelUnavailable: "当前模型暂无配额数据",
487
456
  usageBadgeMoreWindows: "更多配额窗口({count})",
457
+ usageBadgeAllCodexExhausted: "当前显示的所有 Codex 账号都报告订阅额度已耗尽。新请求会在消耗付费额度前停止;外部额度重置后,请使用“设置 > 订阅 > 刷新”重新检查用量。",
488
458
  speed: "速度",
489
459
  speedStandard: "标准",
490
460
  speedStandardDescription: "默认速度",
@@ -717,7 +687,7 @@ const ProviderModelEditor = (0, react.forwardRef)(function ProviderModelEditor$1
717
687
  setBusy(true);
718
688
  setError("");
719
689
  try {
720
- const data = await callSubscriptionsAuth(rpc, provider === "cursor-subscription" ? "cursorSettings" : "providerSettings", {
690
+ const data = await callSubscriptionsAuth(rpc, "providerSettings", {
721
691
  provider,
722
692
  force
723
693
  });
@@ -803,7 +773,7 @@ const ProviderModelEditor = (0, react.forwardRef)(function ProviderModelEditor$1
803
773
  children: [
804
774
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
805
775
  className: "dsh-subscription-hint",
806
- children: t(provider === "cursor-subscription" ? "cursorManageHint" : "modelsHint")
776
+ children: t("modelsHint")
807
777
  }),
808
778
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
809
779
  role: "alert",
@@ -1294,7 +1264,7 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1294
1264
  let current = true;
1295
1265
  setLoading(true);
1296
1266
  setError("");
1297
- callSubscriptionsAuth(rpc, provider === "cursor-subscription" ? "cursorSettings" : "providerSettings", { provider }).then((data) => {
1267
+ callSubscriptionsAuth(rpc, "providerSettings", { provider }).then((data) => {
1298
1268
  if (current) {
1299
1269
  setCatalog(data);
1300
1270
  setTtlDraft(data.settings.promptCacheTtl);
@@ -1333,7 +1303,7 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1333
1303
  setSaveError("");
1334
1304
  let savedEfforts = 0;
1335
1305
  try {
1336
- if (provider !== "cursor-subscription") for (const { model, effort } of models.efforts) {
1306
+ for (const { model, effort } of models.efforts) {
1337
1307
  await callSubscriptionsAuth(rpc, "setModelDefault", {
1338
1308
  provider,
1339
1309
  model,
@@ -1342,18 +1312,17 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1342
1312
  savedEfforts++;
1343
1313
  if (!alive.current) return;
1344
1314
  }
1345
- const latest = await callSubscriptionsAuth(rpc, provider === "cursor-subscription" ? "cursorSettings" : "providerSettings", { provider });
1315
+ const latest = await callSubscriptionsAuth(rpc, "providerSettings", { provider });
1346
1316
  if (!alive.current) return;
1347
- if (provider === "cursor-subscription") await callSubscriptionsAuth(rpc, "cursorSetSettings", { settings: models.settings ?? latest.settings });
1348
- else await callSubscriptionsAuth(rpc, "setProviderSettings", {
1317
+ await callSubscriptionsAuth(rpc, "setProviderSettings", {
1349
1318
  provider,
1350
1319
  settings: mergeAccountChanges(mergePromptCacheTtl(models.settings === void 0 ? latest.settings : mergeLatestAccounts(models.settings, latest.settings), ttlDirty ? ttlDraft : latest.settings.promptCacheTtl), changes)
1351
1320
  });
1352
1321
  if (alive.current) onClose();
1353
1322
  } catch (error$1) {
1354
1323
  if (alive.current) {
1355
- const message$3 = error$1 instanceof Error ? error$1.message : String(error$1);
1356
- setSaveError((savedEfforts ? t("modelsPartialSave") + " " : "") + t("accountsSaveFailed", { message: message$3 }));
1324
+ const message$2 = error$1 instanceof Error ? error$1.message : String(error$1);
1325
+ setSaveError((savedEfforts ? t("modelsPartialSave") + " " : "") + t("accountsSaveFailed", { message: message$2 }));
1357
1326
  }
1358
1327
  } finally {
1359
1328
  saveLock.current = false;
@@ -1401,7 +1370,7 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1401
1370
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1402
1371
  id: description,
1403
1372
  className: "dsh-subscription-hint",
1404
- children: t(provider === "cursor-subscription" ? "cursorAccountsHint" : "accountsHint")
1373
+ children: t("accountsHint")
1405
1374
  }),
1406
1375
  error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1407
1376
  role: "alert",
@@ -1425,190 +1394,173 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1425
1394
  margin: 0,
1426
1395
  padding: 0
1427
1396
  },
1428
- children: [
1429
- catalog.accounts.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1430
- className: "dsh-subscription-hint",
1431
- children: t(provider === "cursor-subscription" ? "cursorManageSignIn" : "accountsEmpty")
1432
- }),
1433
- provider === "cursor-subscription" && catalog.accounts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
1397
+ children: [catalog.accounts.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1398
+ className: "dsh-subscription-hint",
1399
+ children: t("accountsEmpty")
1400
+ }), catalog.accounts.map((account) => {
1401
+ const preferences = changes[account.key] ?? catalog.settings.accounts?.[account.key] ?? {};
1402
+ const selected = accountPoolSelection(preferences, account.models);
1403
+ const models = accountModelRows(account, preferences);
1404
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
1434
1405
  style: {
1406
+ ...stack$1,
1435
1407
  border: border$1,
1436
1408
  borderRadius: "var(--dsw-radius-lg, 12px)",
1437
- padding: 14
1409
+ padding: 14,
1410
+ margin: 0
1438
1411
  },
1439
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
1440
- style: { padding: "0 6px" },
1441
- children: name
1442
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1443
- className: "dsh-subscription-hint",
1444
- children: t("cursorConnected")
1445
- })]
1446
- }),
1447
- provider !== "cursor-subscription" && catalog.accounts.map((account) => {
1448
- const preferences = changes[account.key] ?? catalog.settings.accounts?.[account.key] ?? {};
1449
- const selected = accountPoolSelection(preferences, account.models);
1450
- const models = accountModelRows(account, preferences);
1451
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
1452
- style: {
1453
- ...stack$1,
1454
- border: border$1,
1455
- borderRadius: "var(--dsw-radius-lg, 12px)",
1456
- padding: 14,
1457
- margin: 0
1458
- },
1459
- children: [
1460
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
1461
- style: {
1462
- padding: "0 6px",
1463
- overflowWrap: "anywhere",
1464
- maxWidth: "100%"
1465
- },
1466
- children: account.label
1467
- }),
1468
- account.unavailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1469
- className: "dsh-subscription-hint",
1470
- children: t("accountsCatalogUnavailable")
1412
+ children: [
1413
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("legend", {
1414
+ style: {
1415
+ padding: "0 6px",
1416
+ overflowWrap: "anywhere",
1417
+ maxWidth: "100%"
1418
+ },
1419
+ children: account.label
1420
+ }),
1421
+ account.unavailable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1422
+ className: "dsh-subscription-hint",
1423
+ children: t("accountsCatalogUnavailable")
1424
+ }),
1425
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1426
+ style: {
1427
+ ...stack$1,
1428
+ gap: 6
1429
+ },
1430
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1431
+ className: "dsh-subscription-label",
1432
+ children: t("accountsAlias")
1433
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1434
+ value: preferences.alias ?? "",
1435
+ placeholder: account.label,
1436
+ onChange: (event) => {
1437
+ const next = { ...preferences };
1438
+ if (event.target.value.trim()) next.alias = event.target.value;
1439
+ else delete next.alias;
1440
+ edit(account.key, next);
1441
+ }
1442
+ })]
1443
+ }),
1444
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1445
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1446
+ type: "checkbox",
1447
+ checked: preferences.poolEnabled !== false,
1448
+ onChange: (event) => edit(account.key, {
1449
+ ...preferences,
1450
+ poolEnabled: event.target.checked
1451
+ })
1471
1452
  }),
1472
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1473
- style: {
1474
- ...stack$1,
1475
- gap: 6
1476
- },
1477
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1478
- className: "dsh-subscription-label",
1479
- children: t("accountsAlias")
1480
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1481
- value: preferences.alias ?? "",
1482
- placeholder: account.label,
1483
- onChange: (event) => {
1484
- const next = { ...preferences };
1485
- if (event.target.value.trim()) next.alias = event.target.value;
1486
- else delete next.alias;
1487
- edit(account.key, next);
1488
- }
1489
- })]
1453
+ " ",
1454
+ t("accountsPoolEnabled")
1455
+ ] }),
1456
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1457
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1458
+ type: "checkbox",
1459
+ checked: preferences.independentEntry === true,
1460
+ onChange: (event) => edit(account.key, {
1461
+ ...preferences,
1462
+ independentEntry: event.target.checked
1463
+ })
1490
1464
  }),
1491
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1492
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1493
- type: "checkbox",
1494
- checked: preferences.poolEnabled !== false,
1495
- onChange: (event) => edit(account.key, {
1496
- ...preferences,
1497
- poolEnabled: event.target.checked
1498
- })
1499
- }),
1465
+ " ",
1466
+ t("accountsIndependent")
1467
+ ] }),
1468
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1469
+ className: "dsh-subscription-hint",
1470
+ children: t("accountsIndependentHint")
1471
+ }),
1472
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
1473
+ style: {
1474
+ cursor: "pointer",
1475
+ fontSize: 13
1476
+ },
1477
+ children: [
1478
+ t("accountsModels"),
1479
+ " ·",
1500
1480
  " ",
1501
- t("accountsPoolEnabled")
1502
- ] }),
1503
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1504
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1505
- type: "checkbox",
1506
- checked: preferences.independentEntry === true,
1507
- onChange: (event) => edit(account.key, {
1508
- ...preferences,
1509
- independentEntry: event.target.checked
1510
- })
1481
+ preferences.poolModels === void 0 ? t("accountsModelsAll") : t("accountsModelsCount", { count: preferences.poolModels.length })
1482
+ ]
1483
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1484
+ style: {
1485
+ ...stack$1,
1486
+ marginTop: 12
1487
+ },
1488
+ children: [
1489
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1490
+ className: "dsh-subscription-hint",
1491
+ children: t("accountsModelsHint")
1511
1492
  }),
1512
- " ",
1513
- t("accountsIndependent")
1514
- ] }),
1515
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1516
- className: "dsh-subscription-hint",
1517
- children: t("accountsIndependentHint")
1518
- }),
1519
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", {
1520
- style: {
1521
- cursor: "pointer",
1522
- fontSize: 13
1523
- },
1524
- children: [
1525
- t("accountsModels"),
1526
- " ·",
1527
- " ",
1528
- preferences.poolModels === void 0 ? t("accountsModelsAll") : t("accountsModelsCount", { count: preferences.poolModels.length })
1529
- ]
1530
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1531
- style: {
1532
- ...stack$1,
1533
- marginTop: 12
1534
- },
1535
- children: [
1536
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1537
- className: "dsh-subscription-hint",
1538
- children: t("accountsModelsHint")
1493
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1494
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1495
+ type: "checkbox",
1496
+ checked: preferences.poolModels === void 0,
1497
+ onChange: (event) => {
1498
+ const next = { ...preferences };
1499
+ if (event.target.checked) delete next.poolModels;
1500
+ else next.poolModels = account.models.map((model) => model.id);
1501
+ edit(account.key, next);
1502
+ }
1539
1503
  }),
1540
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [
1541
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1542
- type: "checkbox",
1543
- checked: preferences.poolModels === void 0,
1544
- onChange: (event) => {
1545
- const next = { ...preferences };
1546
- if (event.target.checked) delete next.poolModels;
1547
- else next.poolModels = account.models.map((model) => model.id);
1548
- edit(account.key, next);
1549
- }
1504
+ " ",
1505
+ t("accountsModelsAutomatic")
1506
+ ] }),
1507
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1508
+ style: actions$1,
1509
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1510
+ type: "button",
1511
+ onClick: () => edit(account.key, {
1512
+ ...preferences,
1513
+ poolModels: models.map((model) => model.id)
1550
1514
  }),
1551
- " ",
1552
- t("accountsModelsAutomatic")
1553
- ] }),
1554
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1555
- style: actions$1,
1556
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1557
- type: "button",
1558
- onClick: () => edit(account.key, {
1559
- ...preferences,
1560
- poolModels: models.map((model) => model.id)
1561
- }),
1562
- children: t("modelsSelectAll")
1563
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1564
- type: "button",
1565
- onClick: () => edit(account.key, {
1566
- ...preferences,
1567
- poolModels: []
1515
+ children: t("modelsSelectAll")
1516
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1517
+ type: "button",
1518
+ onClick: () => edit(account.key, {
1519
+ ...preferences,
1520
+ poolModels: []
1521
+ }),
1522
+ children: t("modelsSelectNone")
1523
+ })]
1524
+ }),
1525
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1526
+ style: {
1527
+ ...stack$1,
1528
+ gap: 8,
1529
+ maxHeight: 240,
1530
+ overflowY: "auto"
1531
+ },
1532
+ children: [models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1533
+ style: { overflowWrap: "anywhere" },
1534
+ children: [
1535
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1536
+ type: "checkbox",
1537
+ checked: selected.has(model.id),
1538
+ onChange: (event) => {
1539
+ const next = new Set(selected);
1540
+ if (event.target.checked) next.add(model.id);
1541
+ else next.delete(model.id);
1542
+ edit(account.key, {
1543
+ ...preferences,
1544
+ poolModels: [...next]
1545
+ });
1546
+ }
1568
1547
  }),
1569
- children: t("modelsSelectNone")
1570
- })]
1571
- }),
1572
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1573
- style: {
1574
- ...stack$1,
1575
- gap: 8,
1576
- maxHeight: 240,
1577
- overflowY: "auto"
1578
- },
1579
- children: [models.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1580
- style: { overflowWrap: "anywhere" },
1581
- children: [
1582
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1583
- type: "checkbox",
1584
- checked: selected.has(model.id),
1585
- onChange: (event) => {
1586
- const next = new Set(selected);
1587
- if (event.target.checked) next.add(model.id);
1588
- else next.delete(model.id);
1589
- edit(account.key, {
1590
- ...preferences,
1591
- poolModels: [...next]
1592
- });
1593
- }
1594
- }),
1595
- " ",
1596
- model.name,
1597
- model.unavailable && ` (${t("modelsUnavailable")})`
1598
- ]
1599
- }, model.id)), models.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1600
- className: "dsh-subscription-hint",
1601
- children: t("accountsNoModels")
1602
- })]
1603
- })
1604
- ]
1605
- })] })
1606
- ]
1607
- }, account.key);
1608
- })
1609
- ]
1548
+ " ",
1549
+ model.name,
1550
+ model.unavailable && ` (${t("modelsUnavailable")})`
1551
+ ]
1552
+ }, model.id)), models.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1553
+ className: "dsh-subscription-hint",
1554
+ children: t("accountsNoModels")
1555
+ })]
1556
+ })
1557
+ ]
1558
+ })] })
1559
+ ]
1560
+ }, account.key);
1561
+ })]
1610
1562
  }),
1611
- (provider !== "cursor-subscription" || (catalog?.accounts.length ?? 0) > 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderModelEditor, {
1563
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderModelEditor, {
1612
1564
  ref: editor,
1613
1565
  provider,
1614
1566
  rpc,
@@ -1703,7 +1655,7 @@ function ProviderAccountManager({ provider, name, rpc, t, onClose }) {
1703
1655
 
1704
1656
  //#endregion
1705
1657
  //#region src/client/subscription-card-styles.ts
1706
- /** Shared visual language for OAuth, Cursor, and built-in provider cards. */
1658
+ /** Shared visual language for OAuth and built-in provider cards. */
1707
1659
  const subscriptionCardStyles = {
1708
1660
  card: {
1709
1661
  border: "1px solid var(--dsw-alias-border-l2)",
@@ -2286,250 +2238,6 @@ function ExternalUsageCards({ rpc, t }) {
2286
2238
  }) });
2287
2239
  }
2288
2240
 
2289
- //#endregion
2290
- //#region src/client/CursorCard.tsx
2291
- function message$2(error) {
2292
- return error instanceof Error ? error.message : String(error);
2293
- }
2294
- /** Cursor's single connected account, rendered with the same card and Manage dialog as the other providers. */
2295
- function CursorCard({ rpc, t }) {
2296
- const [status, setStatus] = (0, react.useState)();
2297
- const [usage, setUsage] = (0, react.useState)();
2298
- const [observedAt, setObservedAt] = (0, react.useState)();
2299
- const [usageStale, setUsageStale] = (0, react.useState)(false);
2300
- const [authorizeUrl, setAuthorizeUrl] = (0, react.useState)();
2301
- const [error, setError] = (0, react.useState)();
2302
- const [loading, setLoading] = (0, react.useState)(false);
2303
- const [manage, setManage] = (0, react.useState)(false);
2304
- const authenticated = (0, react.useRef)();
2305
- const refreshStatus = (0, react.useCallback)(async () => {
2306
- try {
2307
- const value = await callSubscriptionsAuth(rpc, "cursorStatus", {});
2308
- setStatus(value);
2309
- if (authenticated.current !== value.authenticated) {
2310
- authenticated.current = value.authenticated;
2311
- window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
2312
- }
2313
- if (value.authenticated) setAuthorizeUrl(void 0);
2314
- if (value.error) setError(value.error);
2315
- } catch (failure) {
2316
- setError(message$2(failure));
2317
- }
2318
- }, [rpc]);
2319
- const refreshUsage = (0, react.useCallback)(async () => {
2320
- setLoading(true);
2321
- try {
2322
- const value = await callSubscriptionsAuth(rpc, "cursorUsage", {});
2323
- setUsage(value);
2324
- setObservedAt(value.observedAt ?? Date.now());
2325
- setUsageStale(value.stale === true);
2326
- setError(void 0);
2327
- window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
2328
- } catch (failure) {
2329
- setError(message$2(failure));
2330
- setUsageStale(true);
2331
- } finally {
2332
- setLoading(false);
2333
- }
2334
- }, [rpc]);
2335
- (0, react.useEffect)(() => {
2336
- refreshStatus();
2337
- }, [refreshStatus]);
2338
- (0, react.useEffect)(() => {
2339
- if (status?.busy !== true) return;
2340
- const timer = setInterval(() => {
2341
- refreshStatus();
2342
- }, 2e3);
2343
- return () => clearInterval(timer);
2344
- }, [status?.busy, refreshStatus]);
2345
- (0, react.useEffect)(() => {
2346
- if (status?.authenticated === true) refreshUsage();
2347
- }, [status?.authenticated, refreshUsage]);
2348
- const login = async () => {
2349
- setError(void 0);
2350
- try {
2351
- const value = await callSubscriptionsAuth(rpc, "cursorLogin", {});
2352
- setAuthorizeUrl(value.authorizeUrl);
2353
- window.open(value.authorizeUrl, "_blank", "noopener");
2354
- await refreshStatus();
2355
- } catch (failure) {
2356
- setError(message$2(failure));
2357
- }
2358
- };
2359
- const cancel = async () => {
2360
- try {
2361
- await callSubscriptionsAuth(rpc, "cursorCancel", {});
2362
- setAuthorizeUrl(void 0);
2363
- await refreshStatus();
2364
- } catch (failure) {
2365
- setError(message$2(failure));
2366
- }
2367
- };
2368
- const logout = async () => {
2369
- if (!window.confirm(t("logoutAccountConfirm", {
2370
- account: "Cursor",
2371
- provider: "Cursor"
2372
- }))) return;
2373
- try {
2374
- await callSubscriptionsAuth(rpc, "cursorLogout", {});
2375
- setUsage(void 0);
2376
- setObservedAt(void 0);
2377
- setUsageStale(false);
2378
- await refreshStatus();
2379
- } catch (failure) {
2380
- setError(message$2(failure));
2381
- }
2382
- };
2383
- const connected = status?.authenticated === true;
2384
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2385
- style: subscriptionCardStyles.card,
2386
- children: [
2387
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2388
- style: subscriptionCardStyles.header,
2389
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
2390
- ...subscriptionCardStyles.dot,
2391
- background: status?.busy ? "var(--dsw-alias-state-warn-label)" : connected ? "var(--dsw-alias-state-success-primary)" : "var(--dsw-alias-label-dimmed)"
2392
- } }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2393
- style: subscriptionCardStyles.name,
2394
- children: t("cursorTitle")
2395
- })]
2396
- }),
2397
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2398
- style: subscriptionCardStyles.status,
2399
- children: status === void 0 ? t("checking") : status.busy ? t("loginInProgress") : connected ? t("loggedInCount", { count: 1 }) : t("notLoggedIn")
2400
- }),
2401
- error !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2402
- style: subscriptionCardStyles.error,
2403
- children: error
2404
- }),
2405
- connected && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2406
- style: subscriptionCardStyles.account,
2407
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2408
- style: subscriptionCardStyles.accountHeader,
2409
- children: [
2410
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2411
- style: subscriptionCardStyles.defaultStar,
2412
- title: t("defaultBadge"),
2413
- children: "★"
2414
- }),
2415
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2416
- style: subscriptionCardStyles.accountName,
2417
- children: "Cursor"
2418
- }),
2419
- status.expiresAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2420
- style: subscriptionCardStyles.status,
2421
- children: t("accountExpires", { date: new Date(status.expiresAt).toLocaleString() })
2422
- }),
2423
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2424
- type: "button",
2425
- style: {
2426
- ...subscriptionCardStyles.button,
2427
- marginLeft: "auto",
2428
- flexShrink: 0
2429
- },
2430
- onClick: () => {
2431
- logout();
2432
- },
2433
- children: t("logout")
2434
- })
2435
- ]
2436
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2437
- style: subscriptionCardStyles.usage,
2438
- children: [
2439
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2440
- style: subscriptionCardStyles.usageHeader,
2441
- children: [
2442
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2443
- style: subscriptionCardStyles.usageTitle,
2444
- children: t("usageTitle")
2445
- }),
2446
- usage?.plan !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2447
- style: subscriptionCardStyles.status,
2448
- children: t("usagePlan", { plan: usage.plan })
2449
- }),
2450
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2451
- type: "button",
2452
- style: subscriptionCardStyles.usageRefresh,
2453
- disabled: loading,
2454
- onClick: () => {
2455
- refreshUsage();
2456
- },
2457
- children: t("usageRefresh")
2458
- })
2459
- ]
2460
- }),
2461
- loading && usage === void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2462
- style: subscriptionCardStyles.status,
2463
- children: t("usageLoading")
2464
- }),
2465
- usage?.windows?.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2466
- style: subscriptionCardStyles.status,
2467
- children: t("usageEmpty")
2468
- }),
2469
- usage?.windows?.map((window$1, index) => {
2470
- const percent = displayUsedPercent(window$1.usedPercent);
2471
- const label = window$1.scope === "Included" ? t("cursorIncluded") : window$1.scope === "Cursor Models" ? t("cursorModels") : window$1.scope === "Other Models" ? t("cursorOtherModels") : window$1.scope === "Included requests" ? t("cursorIncludedRequests") : window$1.scope ?? t("usageWindow");
2472
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2473
- style: subscriptionCardStyles.usageRow,
2474
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2475
- style: subscriptionCardStyles.usageMeta,
2476
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [percent === void 0 ? t("usageMeterInvalid") : `${percent}%`, window$1.resetsAt === void 0 ? "" : ` · ${t("usageResets", { date: new Date(window$1.resetsAt).toLocaleString() })}`] })]
2477
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageMeter, {
2478
- window: window$1,
2479
- t,
2480
- observedAt,
2481
- stale: usageStale
2482
- })]
2483
- }, index);
2484
- })
2485
- ]
2486
- })]
2487
- }),
2488
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2489
- style: subscriptionCardStyles.actions,
2490
- children: [
2491
- status?.authenticated === false && !status.busy && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2492
- type: "button",
2493
- style: subscriptionCardStyles.button,
2494
- onClick: () => {
2495
- login();
2496
- },
2497
- children: t("login")
2498
- }),
2499
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2500
- type: "button",
2501
- style: subscriptionCardStyles.button,
2502
- "aria-haspopup": "dialog",
2503
- onClick: () => setManage(true),
2504
- children: t("accountsManage")
2505
- }),
2506
- status?.busy === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2507
- type: "button",
2508
- style: subscriptionCardStyles.button,
2509
- onClick: () => {
2510
- cancel();
2511
- },
2512
- children: t("cancel")
2513
- })
2514
- ]
2515
- }),
2516
- status?.busy === true && authorizeUrl !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
2517
- href: authorizeUrl,
2518
- target: "_blank",
2519
- rel: "noopener noreferrer",
2520
- children: t("cursorOpenLogin")
2521
- }),
2522
- manage && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderAccountManager, {
2523
- provider: "cursor-subscription",
2524
- name: "Cursor",
2525
- rpc,
2526
- t,
2527
- onClose: () => setManage(false)
2528
- })
2529
- ]
2530
- });
2531
- }
2532
-
2533
2241
  //#endregion
2534
2242
  //#region src/client/ollama-draft.ts
2535
2243
  /**
@@ -3646,15 +3354,15 @@ function showsResetCredits(provider, credits) {
3646
3354
  return (credits?.length ?? 0) > 0;
3647
3355
  }
3648
3356
  /** The error line the settings card mounts. Claude never interpolates provider text. */
3649
- function ResetCreditsErrorLine({ provider, message: message$3, t }) {
3357
+ function ResetCreditsErrorLine({ provider, message: message$2, t }) {
3650
3358
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3651
3359
  style: subscriptionCardStyles.error,
3652
- children: resetCreditsErrorText(provider, message$3, t)
3360
+ children: resetCreditsErrorText(provider, message$2, t)
3653
3361
  });
3654
3362
  }
3655
3363
  /** Fixed sentence for Claude. Codex may include the lookup message; Claude must not. */
3656
- function resetCreditsErrorText(provider, message$3, t) {
3657
- return provider === "claude" ? t("resetCreditsErrorFixed") : t("resetCreditsError", { message: message$3 });
3364
+ function resetCreditsErrorText(provider, message$2, t) {
3365
+ return provider === "claude" ? t("resetCreditsErrorFixed") : t("resetCreditsError", { message: message$2 });
3658
3366
  }
3659
3367
  const summaryStyle = {
3660
3368
  ...subscriptionCardStyles.usageMeta,
@@ -4190,12 +3898,12 @@ function SubscriptionsSection(props) {
4190
3898
  const usageInflightRef = (0, react.useRef)(/* @__PURE__ */ new Map());
4191
3899
  const usageRosterSignatureRef = (0, react.useRef)();
4192
3900
  const [managedProvider, setManagedProvider] = (0, react.useState)();
4193
- const setProviderError = (0, react.useCallback)((provider, message$3) => {
3901
+ const setProviderError = (0, react.useCallback)((provider, message$2) => {
4194
3902
  if (!mountedRef.current) return;
4195
3903
  setErrors((prev) => {
4196
3904
  const next = { ...prev };
4197
- if (message$3 === void 0) delete next[provider];
4198
- else next[provider] = message$3;
3905
+ if (message$2 === void 0) delete next[provider];
3906
+ else next[provider] = message$2;
4199
3907
  return next;
4200
3908
  });
4201
3909
  }, []);
@@ -4213,8 +3921,8 @@ function SubscriptionsSection(props) {
4213
3921
  try {
4214
3922
  response = await callSubscriptionsAuth(rpc, "status", {});
4215
3923
  } catch (error) {
4216
- const message$3 = error instanceof Error ? error.message : String(error);
4217
- for (const { id } of PROVIDERS) setProviderError(id, message$3);
3924
+ const message$2 = error instanceof Error ? error.message : String(error);
3925
+ for (const { id } of PROVIDERS) setProviderError(id, message$2);
4218
3926
  return;
4219
3927
  }
4220
3928
  if (!mountedRef.current) return;
@@ -4786,10 +4494,6 @@ function SubscriptionsSection(props) {
4786
4494
  ]
4787
4495
  }, id);
4788
4496
  }),
4789
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CursorCard, {
4790
- rpc,
4791
- t
4792
- }),
4793
4497
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OllamaCard, {
4794
4498
  rpc,
4795
4499
  t
@@ -6042,7 +5746,6 @@ const PROVIDER_NAMES = {
6042
5746
  grok: "Grok",
6043
5747
  copilot: "Copilot",
6044
5748
  antigravity: "Antigravity",
6045
- "cursor-subscription": "Cursor",
6046
5749
  "opencode-go": "OpenCode Go",
6047
5750
  "kimi-coding": "Kimi Code",
6048
5751
  minimax: "MiniMax",
@@ -6089,13 +5792,10 @@ function groupUsageDisplays(roster, windowsOf, plans) {
6089
5792
  }
6090
5793
  /** Read each account source independently so a failing endpoint cannot hide the others. */
6091
5794
  async function loadBadgeRoster(rpc) {
6092
- const [subscriptions, cursor, external] = await Promise.allSettled([
6093
- callSubscriptionsAuth(rpc, "status", {}),
6094
- callSubscriptionsAuth(rpc, "cursorStatus", {}),
6095
- callSubscriptionsAuth(rpc, "externalStatus", {})
6096
- ]);
5795
+ const [subscriptions, external] = await Promise.allSettled([callSubscriptionsAuth(rpc, "status", {}), callSubscriptionsAuth(rpc, "externalStatus", {})]);
6097
5796
  const roster = [];
6098
5797
  const refreshed = /* @__PURE__ */ new Set();
5798
+ const visibleModels = /* @__PURE__ */ new Map();
6099
5799
  if (subscriptions.status === "fulfilled") for (const provider of [
6100
5800
  "codex",
6101
5801
  "claude",
@@ -6104,21 +5804,13 @@ async function loadBadgeRoster(rpc) {
6104
5804
  "antigravity"
6105
5805
  ]) {
6106
5806
  refreshed.add(provider);
5807
+ const visible = subscriptions.value.providers[provider]?.visibleModels;
5808
+ if (visible !== void 0) visibleModels.set(provider, visible);
6107
5809
  for (const account of accountsOf(subscriptions.value.providers[provider])) roster.push({
6108
5810
  provider,
6109
5811
  account
6110
5812
  });
6111
5813
  }
6112
- if (cursor.status === "fulfilled") {
6113
- refreshed.add("cursor-subscription");
6114
- if (cursor.value.authenticated) roster.push({
6115
- provider: "cursor-subscription",
6116
- account: {
6117
- key: "cursor",
6118
- isDefault: true
6119
- }
6120
- });
6121
- }
6122
5814
  if (external.status === "fulfilled") for (const [source, provider] of [
6123
5815
  ["opencode-go", "opencode-go"],
6124
5816
  ["kimi-code", "kimi-coding"],
@@ -6137,11 +5829,11 @@ async function loadBadgeRoster(rpc) {
6137
5829
  }
6138
5830
  return {
6139
5831
  roster,
6140
- refreshed
5832
+ refreshed,
5833
+ visibleModels
6141
5834
  };
6142
5835
  }
6143
5836
  async function usageOf(rpc, { provider, account }) {
6144
- if (provider === "cursor-subscription") return callSubscriptionsAuth(rpc, "cursorUsage", {});
6145
5837
  if (provider === "opencode-go" || provider === "kimi-coding" || provider === "minimax" || provider === "minimax-cn" || provider === "ollama-cloud") return callSubscriptionsAuth(rpc, "externalUsage", { source: provider === "kimi-coding" ? "kimi-code" : provider });
6146
5838
  return callSubscriptionsAuth(rpc, "usage", {
6147
5839
  provider,
@@ -6307,7 +5999,7 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
6307
5999
  if (rpc === void 0 || inflightRef.current) return;
6308
6000
  inflightRef.current = true;
6309
6001
  try {
6310
- const { roster, refreshed } = await loadBadgeRoster(rpc);
6002
+ const { roster, refreshed, visibleModels } = await loadBadgeRoster(rpc);
6311
6003
  if (!mountedRef.current) return;
6312
6004
  const lastKnown = lastKnownRef.current;
6313
6005
  const live = new Set(roster.map(({ provider, account }) => usageKeyOf(provider, account)));
@@ -6354,6 +6046,7 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
6354
6046
  ...display,
6355
6047
  accounts: display.accounts.map((account) => ({
6356
6048
  ...account,
6049
+ windows: visibleUsageWindows(display.provider, account.windows, visibleModels.get(display.provider)),
6357
6050
  ...observationsRef.current.get(`${display.provider}:${account.key}`)
6358
6051
  }))
6359
6052
  })), ...previous.filter((display) => !refreshed.has(display.provider)).map((display) => ({
@@ -6540,35 +6233,42 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
6540
6233
  }),
6541
6234
  expanded.map((d, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
6542
6235
  style: index === 0 ? void 0 : styles.section,
6543
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6544
- style: styles.providerRow,
6545
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6546
- style: styles.providerName,
6547
- children: [d.name, d.provider === current && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6548
- style: styles.currentTag,
6549
- children: translate("usageBadgeCurrent")
6236
+ children: [
6237
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6238
+ style: styles.providerRow,
6239
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6240
+ style: styles.providerName,
6241
+ children: [d.name, d.provider === current && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6242
+ style: styles.currentTag,
6243
+ children: translate("usageBadgeCurrent")
6244
+ })]
6245
+ }), d.accounts.length === 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountMeta, {
6246
+ account: d.accounts[0],
6247
+ translate
6550
6248
  })]
6551
- }), d.accounts.length === 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountMeta, {
6552
- account: d.accounts[0],
6249
+ }),
6250
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexExhaustionNotice, {
6251
+ display: d,
6553
6252
  translate
6554
- })]
6555
- }), d.accounts.map((account, accountIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6556
- style: accountIndex === 0 ? void 0 : styles.accountBlock,
6557
- children: [d.accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6558
- style: styles.accountRow,
6559
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountMeta, {
6560
- account,
6253
+ }),
6254
+ d.accounts.map((account, accountIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6255
+ style: accountIndex === 0 ? void 0 : styles.accountBlock,
6256
+ children: [d.accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6257
+ style: styles.accountRow,
6258
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountMeta, {
6259
+ account,
6260
+ translate
6261
+ })
6262
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountWindows, {
6263
+ windows: account.windows,
6264
+ observedAt: account.observedAt,
6265
+ stale: account.stale,
6266
+ model: d.provider === dialogProvider ? dialogModel : void 0,
6267
+ provider: d.provider,
6561
6268
  translate
6562
- })
6563
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountWindows, {
6564
- windows: account.windows,
6565
- observedAt: account.observedAt,
6566
- stale: account.stale,
6567
- model: d.provider === dialogProvider ? dialogModel : void 0,
6568
- provider: d.provider,
6569
- translate
6570
- }, `${d.provider}:${dialogModel ?? ""}`)]
6571
- }, account.key))]
6269
+ }, `${d.provider}:${dialogModel ?? ""}`)]
6270
+ }, account.key))
6271
+ ]
6572
6272
  }, d.provider))
6573
6273
  ]
6574
6274
  }), document.body)
@@ -6593,6 +6293,18 @@ function statsScopeOf(seat) {
6593
6293
  }
6594
6294
  return seat.parentElement;
6595
6295
  }
6296
+ /** Warn only when every displayed Codex account has a known exhausted window. */
6297
+ function CodexExhaustionNotice({ display, translate }) {
6298
+ if (display.provider !== "codex" || display.accounts.length === 0 || display.accounts.some((account) => account.windows.length === 0 || !account.windows.some((window$1) => window$1.usedPercent >= 100))) return null;
6299
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6300
+ role: "status",
6301
+ style: {
6302
+ ...styles.providerMeta,
6303
+ margin: "8px 0 0"
6304
+ },
6305
+ children: translate("usageBadgeAllCodexExhausted")
6306
+ });
6307
+ }
6596
6308
  /**
6597
6309
  * One account's handle and plan: `★ ys@example.com · 计划:pro`. The star
6598
6310
  * marks the default account (the one direct routes serve and the collapsed
@@ -6610,8 +6322,12 @@ function AccountMeta({ account, translate }) {
6610
6322
  }), parts.join(" · ")]
6611
6323
  });
6612
6324
  }
6613
- /** Preview each account independently; all remaining quotas stay accessible. */
6325
+ /** Preview each account independently; remaining visible quotas stay accessible. */
6614
6326
  function AccountWindows({ windows, model, provider, translate, observedAt, stale }) {
6327
+ if (windows.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6328
+ style: styles.providerMeta,
6329
+ children: translate("usageNoVisibleModels")
6330
+ });
6615
6331
  const { shown, hidden } = previewWindows(windows, model, provider);
6616
6332
  const rows = (items) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
6617
6333
  style: styles.details,