dsh-subscriptions 0.3.0 → 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.
- package/README.md +2 -2
- package/lib/client/SubscriptionUsageBadge.d.ts +7 -1
- package/lib/client/SubscriptionUsageBadge.js +23 -4
- package/lib/client/locales.d.ts +2 -0
- package/lib/client/locales.js +2 -0
- package/lib/client.js +59 -29
- package/lib/client.js.map +1 -1
- package/lib/index.js +43 -30
- package/lib/providers/claude.d.ts +3 -1
- package/lib/providers/claude.js +2 -2
- package/lib/providers/pool-usage.d.ts +10 -9
- package/lib/providers/pool-usage.js +30 -19
- package/lib/providers/pool.d.ts +6 -6
- package/lib/providers/pool.js +24 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -161,8 +161,8 @@ text. No live account was used to verify what Anthropic returns. See
|
|
|
161
161
|
|
|
162
162
|
## Install
|
|
163
163
|
|
|
164
|
-
Current source is tested with DSH `0.1.7-rc.2`, `0.2.0-rc.2`, `0.2.1-rc.
|
|
165
|
-
`0.2.
|
|
164
|
+
Current source is tested with DSH `0.1.7-rc.2`, `0.2.0-rc.2`, `0.2.1-rc.5`, and
|
|
165
|
+
`0.2.2-rc.1`. The package's peers admit `>=0.1.7-rc.2 <0.3.0-0`: untested
|
|
166
166
|
versions inside that range install but are unsupported, and versions outside it
|
|
167
167
|
need an explicit `dsh plugin allow-version` exemption. `dsh plugin add` checks
|
|
168
168
|
those ranges with `includePrerelease` semantics, so the admitted set covers
|
|
@@ -68,6 +68,7 @@ export declare function groupUsageDisplays(roster: readonly UsageRosterEntry[],
|
|
|
68
68
|
export declare function loadBadgeRoster(rpc: ConnectionHandle['rpc']): Promise<{
|
|
69
69
|
roster: UsageRosterEntry[];
|
|
70
70
|
refreshed: Set<BadgeProvider>;
|
|
71
|
+
visibleModels: Map<BadgeProvider, string[]>;
|
|
71
72
|
}>;
|
|
72
73
|
export declare function usageOf(rpc: ConnectionHandle['rpc'], { provider, account }: UsageRosterEntry): Promise<ProviderUsage>;
|
|
73
74
|
/**
|
|
@@ -119,7 +120,12 @@ export declare function rotatingDisplay(displays: readonly ProviderUsageDisplay[
|
|
|
119
120
|
export declare function expandedDisplays(displays: readonly ProviderUsageDisplay[], current: string | undefined): readonly ProviderUsageDisplay[];
|
|
120
121
|
type Translate = (key: SubscriptionsKey, params?: Record<string, unknown>) => string;
|
|
121
122
|
export declare function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs, }: SubscriptionUsageBadgeProps): import("react").JSX.Element;
|
|
122
|
-
/**
|
|
123
|
+
/** Warn only when every displayed Codex account has a known exhausted window. */
|
|
124
|
+
export declare function CodexExhaustionNotice({ display, translate, }: {
|
|
125
|
+
display: ProviderUsageDisplay;
|
|
126
|
+
translate: Translate;
|
|
127
|
+
}): import("react").JSX.Element | null;
|
|
128
|
+
/** Preview each account independently; remaining visible quotas stay accessible. */
|
|
123
129
|
export declare function AccountWindows({ windows, model, provider, translate, observedAt, stale, }: {
|
|
124
130
|
windows: readonly UsageWindow[];
|
|
125
131
|
model: string | undefined;
|
|
@@ -35,6 +35,7 @@ import { en } from './locales.js';
|
|
|
35
35
|
import { hostIcon } from './host-icons.js';
|
|
36
36
|
import { HOST_CONTRACT, markerSelector } from './host-contract.js';
|
|
37
37
|
import { USAGE_BADGE_REFRESH_EVENT, useUsageBadgeMode, } from './usage-badge-preferences.js';
|
|
38
|
+
import { visibleUsageWindows } from './usage-window-filter.js';
|
|
38
39
|
/** DSH renamed the data icon in 0.1.7; retain older supported hosts too. */
|
|
39
40
|
export function usageBadgeIcon(icons) {
|
|
40
41
|
return hostIcon(icons, 'DataOutline');
|
|
@@ -115,6 +116,7 @@ export async function loadBadgeRoster(rpc) {
|
|
|
115
116
|
]);
|
|
116
117
|
const roster = [];
|
|
117
118
|
const refreshed = new Set();
|
|
119
|
+
const visibleModels = new Map();
|
|
118
120
|
if (subscriptions.status === 'fulfilled') {
|
|
119
121
|
for (const provider of [
|
|
120
122
|
'codex',
|
|
@@ -124,6 +126,9 @@ export async function loadBadgeRoster(rpc) {
|
|
|
124
126
|
'antigravity',
|
|
125
127
|
]) {
|
|
126
128
|
refreshed.add(provider);
|
|
129
|
+
const visible = subscriptions.value.providers[provider]?.visibleModels;
|
|
130
|
+
if (visible !== undefined)
|
|
131
|
+
visibleModels.set(provider, visible);
|
|
127
132
|
for (const account of accountsOf(subscriptions.value.providers[provider]))
|
|
128
133
|
roster.push({ provider, account });
|
|
129
134
|
}
|
|
@@ -144,7 +149,7 @@ export async function loadBadgeRoster(rpc) {
|
|
|
144
149
|
});
|
|
145
150
|
}
|
|
146
151
|
}
|
|
147
|
-
return { roster, refreshed };
|
|
152
|
+
return { roster, refreshed, visibleModels };
|
|
148
153
|
}
|
|
149
154
|
export async function usageOf(rpc, { provider, account }) {
|
|
150
155
|
if (provider === 'opencode-go' ||
|
|
@@ -370,7 +375,7 @@ export function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs, }) {
|
|
|
370
375
|
return;
|
|
371
376
|
inflightRef.current = true;
|
|
372
377
|
try {
|
|
373
|
-
const { roster, refreshed } = await loadBadgeRoster(rpc);
|
|
378
|
+
const { roster, refreshed, visibleModels } = await loadBadgeRoster(rpc);
|
|
374
379
|
if (!mountedRef.current)
|
|
375
380
|
return;
|
|
376
381
|
const lastKnown = lastKnownRef.current;
|
|
@@ -421,6 +426,9 @@ export function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs, }) {
|
|
|
421
426
|
...display,
|
|
422
427
|
accounts: display.accounts.map((account) => ({
|
|
423
428
|
...account,
|
|
429
|
+
// Filter only the display row, not lastKnown: restoring visibility
|
|
430
|
+
// must work even when the next usage request fails and uses cache.
|
|
431
|
+
windows: visibleUsageWindows(display.provider, account.windows, visibleModels.get(display.provider)),
|
|
424
432
|
...observationsRef.current.get(`${display.provider}:${account.key}`),
|
|
425
433
|
})),
|
|
426
434
|
})),
|
|
@@ -612,7 +620,7 @@ export function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs, }) {
|
|
|
612
620
|
}, onMouseLeave: () => {
|
|
613
621
|
setHover(false);
|
|
614
622
|
}, onClick: toggle, children: [_jsx(UsageBadgeIcon, {}), _jsx("span", { style: styles.label, children: label })] }), open &&
|
|
615
|
-
createPortal(_jsxs("div", { ref: panelRef, role: "dialog", "aria-label": title, className: "dsh-subscription-usage-panel", style: { ...styles.panel, ...(pos ?? MEASURE_STYLE) }, children: [_jsx("div", { style: styles.title, children: _jsxs("span", { style: styles.titleLabel, children: [_jsx(UsageBadgeIcon, {}), title] }) }), _jsx("div", { style: styles.titleRule, "aria-hidden": true }), expanded.map((d, index) => (_jsxs("section", { style: index === 0 ? undefined : styles.section, children: [_jsxs("div", { style: styles.providerRow, children: [_jsxs("span", { style: styles.providerName, children: [d.name, d.provider === current && (_jsx("span", { style: styles.currentTag, children: translate('usageBadgeCurrent') }))] }), d.accounts.length === 1 && (_jsx(AccountMeta, { account: d.accounts[0], translate: translate }))] }), d.accounts.map((account, accountIndex) => (_jsxs("div", { style: accountIndex === 0 ? undefined : styles.accountBlock, children: [d.accounts.length > 1 && (_jsx("div", { style: styles.accountRow, children: _jsx(AccountMeta, { account: account, translate: translate }) })), _jsx(AccountWindows, { windows: account.windows, observedAt: account.observedAt, stale: account.stale, model: d.provider === dialogProvider ? dialogModel : undefined, provider: d.provider, translate: translate }, `${d.provider}:${dialogModel ?? ''}`)] }, account.key)))] }, d.provider)))] }), document.body)] }));
|
|
623
|
+
createPortal(_jsxs("div", { ref: panelRef, role: "dialog", "aria-label": title, className: "dsh-subscription-usage-panel", style: { ...styles.panel, ...(pos ?? MEASURE_STYLE) }, children: [_jsx("div", { style: styles.title, children: _jsxs("span", { style: styles.titleLabel, children: [_jsx(UsageBadgeIcon, {}), title] }) }), _jsx("div", { style: styles.titleRule, "aria-hidden": true }), expanded.map((d, index) => (_jsxs("section", { style: index === 0 ? undefined : styles.section, children: [_jsxs("div", { style: styles.providerRow, children: [_jsxs("span", { style: styles.providerName, children: [d.name, d.provider === current && (_jsx("span", { style: styles.currentTag, children: translate('usageBadgeCurrent') }))] }), d.accounts.length === 1 && (_jsx(AccountMeta, { account: d.accounts[0], translate: translate }))] }), _jsx(CodexExhaustionNotice, { display: d, translate: translate }), d.accounts.map((account, accountIndex) => (_jsxs("div", { style: accountIndex === 0 ? undefined : styles.accountBlock, children: [d.accounts.length > 1 && (_jsx("div", { style: styles.accountRow, children: _jsx(AccountMeta, { account: account, translate: translate }) })), _jsx(AccountWindows, { windows: account.windows, observedAt: account.observedAt, stale: account.stale, model: d.provider === dialogProvider ? dialogModel : undefined, provider: d.provider, translate: translate }, `${d.provider}:${dialogModel ?? ''}`)] }, account.key)))] }, d.provider)))] }), document.body)] }));
|
|
616
624
|
return (_jsxs(_Fragment, { children: [seat, statsRow !== null && statsRow.isConnected
|
|
617
625
|
? createPortal(pill, statsRow)
|
|
618
626
|
: pill] }));
|
|
@@ -635,6 +643,15 @@ function statsScopeOf(seat) {
|
|
|
635
643
|
}
|
|
636
644
|
return seat.parentElement;
|
|
637
645
|
}
|
|
646
|
+
/** Warn only when every displayed Codex account has a known exhausted window. */
|
|
647
|
+
export function CodexExhaustionNotice({ display, translate, }) {
|
|
648
|
+
if (display.provider !== 'codex' ||
|
|
649
|
+
display.accounts.length === 0 ||
|
|
650
|
+
display.accounts.some((account) => account.windows.length === 0 ||
|
|
651
|
+
!account.windows.some((window) => window.usedPercent >= 100)))
|
|
652
|
+
return null;
|
|
653
|
+
return (_jsx("p", { role: "status", style: { ...styles.providerMeta, margin: '8px 0 0' }, children: translate('usageBadgeAllCodexExhausted') }));
|
|
654
|
+
}
|
|
638
655
|
/**
|
|
639
656
|
* One account's handle and plan: `★ ys@example.com · 计划:pro`. The star
|
|
640
657
|
* marks the default account (the one direct routes serve and the collapsed
|
|
@@ -649,8 +666,10 @@ function AccountMeta({ account, translate, }) {
|
|
|
649
666
|
].filter((part) => part !== undefined && part !== '');
|
|
650
667
|
return (_jsxs("span", { style: styles.providerMeta, title: account.account, children: [account.isDefault && (_jsxs("span", { style: styles.defaultStar, "aria-label": "default", children: ["\u2605", ' '] })), parts.join(' · ')] }));
|
|
651
668
|
}
|
|
652
|
-
/** Preview each account independently;
|
|
669
|
+
/** Preview each account independently; remaining visible quotas stay accessible. */
|
|
653
670
|
export function AccountWindows({ windows, model, provider, translate, observedAt, stale, }) {
|
|
671
|
+
if (windows.length === 0)
|
|
672
|
+
return (_jsx("p", { style: styles.providerMeta, children: translate('usageNoVisibleModels') }));
|
|
654
673
|
const { shown, hidden } = previewWindows(windows, model, provider);
|
|
655
674
|
const rows = (items) => (_jsx("dl", { style: styles.details, children: items.map((w, i) => (_jsx(WindowRow, { label: `${usageWindowLabel(translate, w)}${model !== undefined && w.scope === model ? ` · ${translate('usageBadgeCurrent')}` : ''}`, window: w, t: translate, observedAt: observedAt, stale: stale }, i))) }));
|
|
656
675
|
return (_jsxs(_Fragment, { children: [rows(shown), hidden.length > 0 && (_jsxs("details", { style: styles.moreWindows, children: [_jsx("summary", { style: styles.moreSummary, children: translate('usageBadgeMoreWindows', { count: hidden.length }) }), rows(hidden)] }))] }));
|
package/lib/client/locales.d.ts
CHANGED
|
@@ -188,6 +188,7 @@ export declare const en: {
|
|
|
188
188
|
usageBadgeModelCount: string;
|
|
189
189
|
usageBadgeModelUnavailable: string;
|
|
190
190
|
usageBadgeMoreWindows: string;
|
|
191
|
+
usageBadgeAllCodexExhausted: string;
|
|
191
192
|
speed: string;
|
|
192
193
|
speedStandard: string;
|
|
193
194
|
speedStandardDescription: string;
|
|
@@ -418,6 +419,7 @@ export declare const zh: {
|
|
|
418
419
|
usageBadgeModelCount: string;
|
|
419
420
|
usageBadgeModelUnavailable: string;
|
|
420
421
|
usageBadgeMoreWindows: string;
|
|
422
|
+
usageBadgeAllCodexExhausted: string;
|
|
421
423
|
speed: string;
|
|
422
424
|
speedStandard: string;
|
|
423
425
|
speedStandardDescription: string;
|
package/lib/client/locales.js
CHANGED
|
@@ -188,6 +188,7 @@ export const en = {
|
|
|
188
188
|
usageBadgeModelCount: '{count} model quotas',
|
|
189
189
|
usageBadgeModelUnavailable: 'Current model quota unavailable',
|
|
190
190
|
usageBadgeMoreWindows: 'More quota windows ({count})',
|
|
191
|
+
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.',
|
|
191
192
|
speed: 'Speed',
|
|
192
193
|
speedStandard: 'Standard',
|
|
193
194
|
speedStandardDescription: 'Default speed',
|
|
@@ -426,6 +427,7 @@ export const zh = {
|
|
|
426
427
|
usageBadgeModelCount: '{count} 个模型配额',
|
|
427
428
|
usageBadgeModelUnavailable: '当前模型暂无配额数据',
|
|
428
429
|
usageBadgeMoreWindows: '更多配额窗口({count})',
|
|
430
|
+
usageBadgeAllCodexExhausted: '当前显示的所有 Codex 账号都报告订阅额度已耗尽。新请求会在消耗付费额度前停止;外部额度重置后,请使用“设置 > 订阅 > 刷新”重新检查用量。',
|
|
429
431
|
speed: '速度',
|
|
430
432
|
speedStandard: '标准',
|
|
431
433
|
speedStandardDescription: '默认速度',
|
package/lib/client.js
CHANGED
|
@@ -223,6 +223,7 @@ const en = {
|
|
|
223
223
|
usageBadgeModelCount: "{count} model quotas",
|
|
224
224
|
usageBadgeModelUnavailable: "Current model quota unavailable",
|
|
225
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.",
|
|
226
227
|
speed: "Speed",
|
|
227
228
|
speedStandard: "Standard",
|
|
228
229
|
speedStandardDescription: "Default speed",
|
|
@@ -453,6 +454,7 @@ const zh = {
|
|
|
453
454
|
usageBadgeModelCount: "{count} 个模型配额",
|
|
454
455
|
usageBadgeModelUnavailable: "当前模型暂无配额数据",
|
|
455
456
|
usageBadgeMoreWindows: "更多配额窗口({count})",
|
|
457
|
+
usageBadgeAllCodexExhausted: "当前显示的所有 Codex 账号都报告订阅额度已耗尽。新请求会在消耗付费额度前停止;外部额度重置后,请使用“设置 > 订阅 > 刷新”重新检查用量。",
|
|
456
458
|
speed: "速度",
|
|
457
459
|
speedStandard: "标准",
|
|
458
460
|
speedStandardDescription: "默认速度",
|
|
@@ -5793,6 +5795,7 @@ async function loadBadgeRoster(rpc) {
|
|
|
5793
5795
|
const [subscriptions, external] = await Promise.allSettled([callSubscriptionsAuth(rpc, "status", {}), callSubscriptionsAuth(rpc, "externalStatus", {})]);
|
|
5794
5796
|
const roster = [];
|
|
5795
5797
|
const refreshed = /* @__PURE__ */ new Set();
|
|
5798
|
+
const visibleModels = /* @__PURE__ */ new Map();
|
|
5796
5799
|
if (subscriptions.status === "fulfilled") for (const provider of [
|
|
5797
5800
|
"codex",
|
|
5798
5801
|
"claude",
|
|
@@ -5801,6 +5804,8 @@ async function loadBadgeRoster(rpc) {
|
|
|
5801
5804
|
"antigravity"
|
|
5802
5805
|
]) {
|
|
5803
5806
|
refreshed.add(provider);
|
|
5807
|
+
const visible = subscriptions.value.providers[provider]?.visibleModels;
|
|
5808
|
+
if (visible !== void 0) visibleModels.set(provider, visible);
|
|
5804
5809
|
for (const account of accountsOf(subscriptions.value.providers[provider])) roster.push({
|
|
5805
5810
|
provider,
|
|
5806
5811
|
account
|
|
@@ -5824,7 +5829,8 @@ async function loadBadgeRoster(rpc) {
|
|
|
5824
5829
|
}
|
|
5825
5830
|
return {
|
|
5826
5831
|
roster,
|
|
5827
|
-
refreshed
|
|
5832
|
+
refreshed,
|
|
5833
|
+
visibleModels
|
|
5828
5834
|
};
|
|
5829
5835
|
}
|
|
5830
5836
|
async function usageOf(rpc, { provider, account }) {
|
|
@@ -5993,7 +5999,7 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
|
|
|
5993
5999
|
if (rpc === void 0 || inflightRef.current) return;
|
|
5994
6000
|
inflightRef.current = true;
|
|
5995
6001
|
try {
|
|
5996
|
-
const { roster, refreshed } = await loadBadgeRoster(rpc);
|
|
6002
|
+
const { roster, refreshed, visibleModels } = await loadBadgeRoster(rpc);
|
|
5997
6003
|
if (!mountedRef.current) return;
|
|
5998
6004
|
const lastKnown = lastKnownRef.current;
|
|
5999
6005
|
const live = new Set(roster.map(({ provider, account }) => usageKeyOf(provider, account)));
|
|
@@ -6040,6 +6046,7 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
|
|
|
6040
6046
|
...display,
|
|
6041
6047
|
accounts: display.accounts.map((account) => ({
|
|
6042
6048
|
...account,
|
|
6049
|
+
windows: visibleUsageWindows(display.provider, account.windows, visibleModels.get(display.provider)),
|
|
6043
6050
|
...observationsRef.current.get(`${display.provider}:${account.key}`)
|
|
6044
6051
|
}))
|
|
6045
6052
|
})), ...previous.filter((display) => !refreshed.has(display.provider)).map((display) => ({
|
|
@@ -6226,35 +6233,42 @@ function SubscriptionUsageBadge({ rpc, currentModel, t, rotationMs }) {
|
|
|
6226
6233
|
}),
|
|
6227
6234
|
expanded.map((d, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
6228
6235
|
style: index === 0 ? void 0 : styles.section,
|
|
6229
|
-
children: [
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
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
|
|
6236
6248
|
})]
|
|
6237
|
-
}),
|
|
6238
|
-
|
|
6249
|
+
}),
|
|
6250
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexExhaustionNotice, {
|
|
6251
|
+
display: d,
|
|
6239
6252
|
translate
|
|
6240
|
-
})
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
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,
|
|
6247
6268
|
translate
|
|
6248
|
-
})
|
|
6249
|
-
}
|
|
6250
|
-
|
|
6251
|
-
observedAt: account.observedAt,
|
|
6252
|
-
stale: account.stale,
|
|
6253
|
-
model: d.provider === dialogProvider ? dialogModel : void 0,
|
|
6254
|
-
provider: d.provider,
|
|
6255
|
-
translate
|
|
6256
|
-
}, `${d.provider}:${dialogModel ?? ""}`)]
|
|
6257
|
-
}, account.key))]
|
|
6269
|
+
}, `${d.provider}:${dialogModel ?? ""}`)]
|
|
6270
|
+
}, account.key))
|
|
6271
|
+
]
|
|
6258
6272
|
}, d.provider))
|
|
6259
6273
|
]
|
|
6260
6274
|
}), document.body)
|
|
@@ -6279,6 +6293,18 @@ function statsScopeOf(seat) {
|
|
|
6279
6293
|
}
|
|
6280
6294
|
return seat.parentElement;
|
|
6281
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
|
+
}
|
|
6282
6308
|
/**
|
|
6283
6309
|
* One account's handle and plan: `★ ys@example.com · 计划:pro`. The star
|
|
6284
6310
|
* marks the default account (the one direct routes serve and the collapsed
|
|
@@ -6296,8 +6322,12 @@ function AccountMeta({ account, translate }) {
|
|
|
6296
6322
|
}), parts.join(" · ")]
|
|
6297
6323
|
});
|
|
6298
6324
|
}
|
|
6299
|
-
/** Preview each account independently;
|
|
6325
|
+
/** Preview each account independently; remaining visible quotas stay accessible. */
|
|
6300
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
|
+
});
|
|
6301
6331
|
const { shown, hidden } = previewWindows(windows, model, provider);
|
|
6302
6332
|
const rows = (items) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("dl", {
|
|
6303
6333
|
style: styles.details,
|