dsh-subscriptions 0.1.3 → 0.1.5
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 +64 -0
- package/lib/auth/device-flow.js +6 -3
- package/lib/auth/oauth-flow.js +41 -8
- package/lib/auth/rpc.d.ts +3 -1
- package/lib/auth/rpc.js +10 -1
- package/lib/client/ProviderAccountManager.js +34 -41
- package/lib/client/ProviderModelEditor.js +5 -9
- package/lib/client/SpeedSelect.js +8 -7
- package/lib/client/SubscriptionUsageBadge.js +6 -5
- package/lib/client/SubscriptionsSection.d.ts +21 -73
- package/lib/client/SubscriptionsSection.js +130 -104
- package/lib/client/UsageBadgeDisplaySetting.js +4 -8
- package/lib/client/host-contract.d.ts +1 -1
- package/lib/client/host-contract.js +22 -0
- package/lib/client/locales.d.ts +58 -0
- package/lib/client/locales.js +58 -0
- package/lib/client/provider-settings-styles.d.ts +3 -0
- package/lib/client/provider-settings-styles.js +206 -0
- package/lib/client/reset-action.d.ts +14 -0
- package/lib/client/reset-action.js +15 -0
- package/lib/client/reset-credits-view.d.ts +53 -0
- package/lib/client/reset-credits-view.js +103 -0
- package/lib/client.js +937 -310
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +9 -0
- package/lib/index.js +6058 -5298
- package/lib/model-defaults.d.ts +4 -5
- package/lib/model-defaults.js +18 -14
- package/lib/providers/account-preferences.js +3 -2
- package/lib/providers/antigravity.d.ts +0 -2
- package/lib/providers/antigravity.js +5 -9
- package/lib/providers/catalog-store.d.ts +3 -2
- package/lib/providers/catalog-store.js +57 -26
- package/lib/providers/claude.d.ts +22 -3
- package/lib/providers/claude.js +118 -20
- package/lib/providers/codex-search.js +5 -2
- package/lib/providers/codex.d.ts +15 -2
- package/lib/providers/codex.js +77 -9
- package/lib/providers/common.d.ts +38 -0
- package/lib/providers/common.js +44 -18
- package/lib/providers/copilot.d.ts +2 -1
- package/lib/providers/copilot.js +13 -6
- package/lib/providers/cursor-adapter.d.ts +35 -0
- package/lib/providers/cursor-adapter.js +245 -4
- package/lib/providers/cursor-auth.js +11 -4
- package/lib/providers/cursor-usage.js +2 -1
- package/lib/providers/external-usage.js +2 -1
- package/lib/providers/grok.d.ts +2 -2
- package/lib/providers/grok.js +16 -11
- package/lib/providers/minimax-usage.js +2 -1
- package/lib/providers/pool-health.d.ts +2 -0
- package/lib/providers/pool-health.js +9 -0
- package/lib/providers/pool-usage.d.ts +13 -1
- package/lib/providers/pool-usage.js +39 -7
- package/lib/providers/pool.d.ts +7 -5
- package/lib/providers/pool.js +89 -12
- package/lib/providers/rate-limit.d.ts +0 -14
- package/lib/providers/rate-limit.js +0 -26
- package/lib/providers/replay.d.ts +4 -0
- package/lib/providers/replay.js +50 -0
- package/lib/providers/reset-redemption.d.ts +51 -0
- package/lib/providers/reset-redemption.js +102 -0
- package/lib/tools/image-generate.js +2 -1
- package/lib/tools/video-generate.d.ts +0 -5
- package/lib/tools/video-generate.js +25 -14
- package/lib/tools/x-search.js +2 -2
- package/lib/translate/anthropic.d.ts +21 -2
- package/lib/translate/anthropic.js +35 -11
- package/lib/translate/antigravity.js +13 -6
- package/lib/translate/chat-completions.js +1 -1
- package/lib/translate/resolved.d.ts +24 -0
- package/lib/translate/resolved.js +66 -3
- package/lib/translate/responses.js +8 -6
- package/lib/translate/sse.js +8 -0
- package/package.json +1 -1
|
@@ -41,23 +41,28 @@ export interface ProviderUsage {
|
|
|
41
41
|
supported: boolean;
|
|
42
42
|
windows?: UsageWindow[];
|
|
43
43
|
plan?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Banked limit-reset grants. Codex entries carry id/expiry only. Claude
|
|
46
|
+
* entries are one row per grant: `expiresAt` is when the grant expires, not
|
|
47
|
+
* a window reset, and `resetsLeft` is the remaining credit count.
|
|
48
|
+
*/
|
|
49
|
+
resetCredits?: ResetCreditView[];
|
|
50
|
+
resetCreditsError?: string;
|
|
44
51
|
}
|
|
45
|
-
/** One
|
|
46
|
-
export interface
|
|
47
|
-
id
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
provider: SubscriptionProvider;
|
|
60
|
-
models: ModelDefaultView[];
|
|
52
|
+
/** One banked reset grant as the usage RPC returns it. */
|
|
53
|
+
export interface ResetCreditView {
|
|
54
|
+
id?: string;
|
|
55
|
+
grantedAt?: number;
|
|
56
|
+
/** Epoch milliseconds when the grant expires. Never a periodic window reset. */
|
|
57
|
+
expiresAt?: number;
|
|
58
|
+
resetsTotal?: number;
|
|
59
|
+
resetsLeft?: number;
|
|
60
|
+
usableNow?: boolean;
|
|
61
|
+
paused?: boolean;
|
|
62
|
+
/** Server metadata only. Claude has no redemption control. */
|
|
63
|
+
claimable?: boolean;
|
|
64
|
+
/** Epoch milliseconds until which the grant is visible but not usable. */
|
|
65
|
+
cooldownUntil?: number;
|
|
61
66
|
}
|
|
62
67
|
/** Injected dependencies of {@link SubscriptionsSection} (slot `inject`). */
|
|
63
68
|
export interface SubscriptionsSectionInjected {
|
|
@@ -80,63 +85,6 @@ export type SubscriptionsSectionProps = Partial<SubscriptionsSectionInjected>;
|
|
|
80
85
|
export declare function clientVersionText(t: SubscriptionsSectionInjected['t'], clientVersion: ProviderStatus['clientVersion']): string;
|
|
81
86
|
/** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */
|
|
82
87
|
export { usageBarColor } from './usage-pace.js';
|
|
83
|
-
/** What one provider's collapsible default-effort section renders. */
|
|
84
|
-
export interface ModelDefaultsView {
|
|
85
|
-
/** Models with reasoning levels, after the name filter — one row each. */
|
|
86
|
-
shown: ModelDefaultView[];
|
|
87
|
-
/** Models with reasoning levels before filtering (the header total). */
|
|
88
|
-
total: number;
|
|
89
|
-
/** How many of those carry a user override (the header count). */
|
|
90
|
-
overridden: number;
|
|
91
|
-
/** Models without reasoning levels: one count line, never a row each. */
|
|
92
|
-
withoutEfforts: number;
|
|
93
|
-
/** Whether the list is long enough to deserve a filter box. */
|
|
94
|
-
showFilter: boolean;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Derive one provider's default-effort section from its catalog and filter.
|
|
98
|
-
* Pure so the collapsed-header counts and the filter stay testable without a
|
|
99
|
-
* DOM: rows come only from models that advertise levels, the count of the rest
|
|
100
|
-
* rides as one line, and the filter matches display name or model id.
|
|
101
|
-
* @param models - the provider's catalog models, or undefined while loading.
|
|
102
|
-
* @param filter - the raw filter input (trimmed and lowercased here).
|
|
103
|
-
* @returns the section's rows and header counts.
|
|
104
|
-
*/
|
|
105
|
-
export declare function deriveModelDefaultsView(models: readonly ModelDefaultView[] | undefined, filter: string): ModelDefaultsView;
|
|
106
|
-
/** Inputs of the default-effort fetch decision (see {@link shouldFetchModelDefaults}). */
|
|
107
|
-
export interface ModelDefaultsFetchInput {
|
|
108
|
-
/** Providers that currently have at least one account. */
|
|
109
|
-
loggedIn: readonly SubscriptionProvider[];
|
|
110
|
-
/** Providers whose disclosure is open. */
|
|
111
|
-
open: readonly SubscriptionProvider[];
|
|
112
|
-
/** The account signature the last completed fetch was answered for. */
|
|
113
|
-
loadedFor: string | undefined;
|
|
114
|
-
/** The account signature of the current status snapshot. */
|
|
115
|
-
signature: string;
|
|
116
|
-
/** Whether the last attempt failed (a failure latches until Retry). */
|
|
117
|
-
failed: boolean;
|
|
118
|
-
}
|
|
119
|
-
/**
|
|
120
|
-
* Whether the default-effort catalog needs (re)fetching.
|
|
121
|
-
*
|
|
122
|
-
* Fetching is gated on an *attempt* signature rather than on the payload
|
|
123
|
-
* being empty: an empty answer is a legitimate result (a narrowed
|
|
124
|
-
* `config.providers`, or a catalog that is momentarily unavailable), and
|
|
125
|
-
* treating it as "not loaded yet" re-ran this effect forever. The signature
|
|
126
|
-
* also covers the accounts, so logging a second provider in refetches
|
|
127
|
-
* instead of leaving that card on the previous answer.
|
|
128
|
-
* @param input - the decision inputs.
|
|
129
|
-
* @returns true when the caller should start a fetch.
|
|
130
|
-
*/
|
|
131
|
-
export declare function shouldFetchModelDefaults(input: ModelDefaultsFetchInput): boolean;
|
|
132
|
-
/**
|
|
133
|
-
* Stable signature of the accounts a catalog answer depends on. A change
|
|
134
|
-
* means a previous answer is stale (an account arrived or left), so the next
|
|
135
|
-
* open disclosure refetches.
|
|
136
|
-
* @param statuses - the per-provider status snapshot.
|
|
137
|
-
* @returns a signature string, stable across renders with equal accounts.
|
|
138
|
-
*/
|
|
139
|
-
export declare function modelDefaultsSignature(statuses: Partial<Record<SubscriptionProvider, ProviderStatus>>): string;
|
|
140
88
|
/**
|
|
141
89
|
* The Subscriptions settings page component.
|
|
142
90
|
* @param props - the slot inject face ({@link SubscriptionsSectionInjected}).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* Subscriptions settings section: one card per subscription provider with an
|
|
4
|
-
* OAuth login/logout flow driven by the node half's
|
|
5
|
-
*
|
|
4
|
+
* OAuth login/logout flow driven by the node half's
|
|
5
|
+
* `/api/subscriptions-auth.<endpoint>` RPC routes. Login state lives server-side; the page polls `status` only while
|
|
6
6
|
* a login attempt is busy, so an idle page never polls. All state is local
|
|
7
7
|
* React state — the page has no store.
|
|
8
8
|
*
|
|
@@ -10,15 +10,17 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
10
10
|
* design-platform.css values flip under `body[data-ds-dark-theme]`), and
|
|
11
11
|
* every user-visible string goes through the locale-bound `t` of the
|
|
12
12
|
* 'settings.subscriptions' namespace. Buttons and inputs take the
|
|
13
|
-
*
|
|
14
|
-
* express.
|
|
13
|
+
* native settings vocabulary with shared, scoped control states.
|
|
15
14
|
*/
|
|
16
15
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
17
16
|
import { en } from './locales.js';
|
|
17
|
+
import { resetActionBlock } from './reset-action.js';
|
|
18
18
|
import { ProviderAccountManager } from './ProviderAccountManager.js';
|
|
19
|
+
import { providerSettingsCss } from './provider-settings-styles.js';
|
|
19
20
|
import { ExternalUsageCards } from './ExternalUsageCards.js';
|
|
20
21
|
import { CursorCard } from './CursorCard.js';
|
|
21
22
|
import { UsageMeter } from './UsageMeter.js';
|
|
23
|
+
import { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits } from './reset-credits-view.js';
|
|
22
24
|
import { displayUsedPercent } from './usage-pace.js';
|
|
23
25
|
import { UsageBadgeDisplaySetting } from './UsageBadgeDisplaySetting.js';
|
|
24
26
|
import { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js';
|
|
@@ -27,11 +29,6 @@ import { callSubscriptionsAuth, SubscriptionsAuthError } from './subscriptions-r
|
|
|
27
29
|
export { callSubscriptionsAuth } from './subscriptions-rpc.js';
|
|
28
30
|
/** Poll cadence while a provider login attempt is busy. */
|
|
29
31
|
const POLL_INTERVAL_MS = 2000;
|
|
30
|
-
/**
|
|
31
|
-
* Model count above which the expanded default-effort list also offers a name
|
|
32
|
-
* filter; below it the list is short enough to scan.
|
|
33
|
-
*/
|
|
34
|
-
const MODEL_FILTER_THRESHOLD = 8;
|
|
35
32
|
const CLIENT_VERSION_SOURCES = {
|
|
36
33
|
npm: 'clientVersionNpm',
|
|
37
34
|
local: 'clientVersionLocal',
|
|
@@ -80,7 +77,10 @@ const styles = {
|
|
|
80
77
|
color: 'var(--dsw-alias-label-primary)',
|
|
81
78
|
},
|
|
82
79
|
intro: { margin: 0, color: 'var(--dsw-alias-label-tertiary)', fontSize: 14, lineHeight: '22px' },
|
|
83
|
-
card: cardStyles.card,
|
|
80
|
+
card: { ...cardStyles.card,
|
|
81
|
+
border: '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',
|
|
82
|
+
borderRadius: 'var(--dsw-radius-xl, 20px)', background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',
|
|
83
|
+
},
|
|
84
84
|
cardHeader: cardStyles.header,
|
|
85
85
|
dot: cardStyles.dot,
|
|
86
86
|
name: cardStyles.name,
|
|
@@ -88,44 +88,46 @@ const styles = {
|
|
|
88
88
|
clientVersion: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)', fontVariantNumeric: 'tabular-nums' },
|
|
89
89
|
errorLine: cardStyles.error,
|
|
90
90
|
actions: cardStyles.actions,
|
|
91
|
-
|
|
92
|
-
usage: cardStyles.usage,
|
|
91
|
+
usage: { ...cardStyles.usage, borderTop: '0.5px solid var(--dsw-alias-border-l2)' },
|
|
93
92
|
usageHeader: cardStyles.usageHeader,
|
|
94
93
|
usageTitle: cardStyles.usageTitle,
|
|
95
94
|
usagePlan: cardStyles.usagePlan,
|
|
96
|
-
usageRefresh:
|
|
95
|
+
usageRefresh: { minHeight: 22, height: 22, padding: '0 8px', marginLeft: 'auto' },
|
|
97
96
|
usageRow: cardStyles.usageRow,
|
|
98
97
|
usageMeta: cardStyles.usageMeta,
|
|
99
|
-
accountRow: cardStyles.account,
|
|
98
|
+
accountRow: { ...cardStyles.account, border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)' },
|
|
100
99
|
accountHeader: cardStyles.accountHeader,
|
|
101
100
|
accountName: cardStyles.accountName,
|
|
102
101
|
starButton: {
|
|
103
|
-
border: 'none',
|
|
102
|
+
border: 'none', padding: 0, width: 28,
|
|
104
103
|
font: 'inherit', fontSize: 14, lineHeight: '20px', cursor: 'pointer',
|
|
105
104
|
color: 'var(--dsw-alias-state-warn-label)',
|
|
106
105
|
},
|
|
107
106
|
deviceCode: {
|
|
108
107
|
marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6,
|
|
109
|
-
border: '
|
|
108
|
+
border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)',
|
|
110
109
|
padding: '10px 12px', background: 'var(--dsw-alias-bg-layer-1)',
|
|
111
110
|
},
|
|
112
111
|
deviceCodeText: {
|
|
113
112
|
fontFamily: 'monospace', fontSize: 18, lineHeight: '24px', letterSpacing: 2,
|
|
114
113
|
color: 'var(--dsw-alias-label-primary)', userSelect: 'all',
|
|
115
114
|
},
|
|
115
|
+
manual: { fontSize: 13, lineHeight: '20px' },
|
|
116
|
+
manualRow: { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginTop: 8 },
|
|
117
|
+
manualInput: { flex: '1 1 200px', minWidth: 0 },
|
|
116
118
|
modalOverlay: {
|
|
117
119
|
position: 'fixed', inset: 0, zIndex: 1000,
|
|
118
120
|
display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16,
|
|
119
|
-
background: '
|
|
121
|
+
background: 'var(--dsw-alias-bg-mask-1, #0006)', backdropFilter: 'var(--dsw-mask-blur, none)',
|
|
120
122
|
},
|
|
121
123
|
modal: {
|
|
122
124
|
width: 460, maxWidth: '100%', maxHeight: '90vh', overflowY: 'auto',
|
|
123
125
|
boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 12,
|
|
124
|
-
padding: '16px 18px', borderRadius:
|
|
125
|
-
background: 'var(--dsw-alias-bg-layer-
|
|
126
|
+
padding: '16px 18px', borderRadius: 'var(--dsw-radius-panel, 28px)',
|
|
127
|
+
background: 'var(--dsw-alias-bg-layer-2)', border: 0, boxShadow: 'var(--dsw-elevation-prominent)',
|
|
126
128
|
},
|
|
127
129
|
modalHeader: { display: 'flex', alignItems: 'center', gap: 8 },
|
|
128
|
-
modalTitle: { fontWeight:
|
|
130
|
+
modalTitle: { fontWeight: 500, fontSize: 16, lineHeight: '24px', color: 'var(--dsw-alias-label-primary)' },
|
|
129
131
|
};
|
|
130
132
|
/** Status dot color for one provider state. */
|
|
131
133
|
function dotColor(status) {
|
|
@@ -185,65 +187,6 @@ function usageWindowLabel(t, window) {
|
|
|
185
187
|
}
|
|
186
188
|
/** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */
|
|
187
189
|
export { usageBarColor } from './usage-pace.js';
|
|
188
|
-
/**
|
|
189
|
-
* Derive one provider's default-effort section from its catalog and filter.
|
|
190
|
-
* Pure so the collapsed-header counts and the filter stay testable without a
|
|
191
|
-
* DOM: rows come only from models that advertise levels, the count of the rest
|
|
192
|
-
* rides as one line, and the filter matches display name or model id.
|
|
193
|
-
* @param models - the provider's catalog models, or undefined while loading.
|
|
194
|
-
* @param filter - the raw filter input (trimmed and lowercased here).
|
|
195
|
-
* @returns the section's rows and header counts.
|
|
196
|
-
*/
|
|
197
|
-
export function deriveModelDefaultsView(models, filter) {
|
|
198
|
-
const all = models ?? [];
|
|
199
|
-
const withEfforts = all.filter(model => model.efforts.length > 0);
|
|
200
|
-
const query = filter.trim().toLowerCase();
|
|
201
|
-
const shown = query === ''
|
|
202
|
-
? withEfforts
|
|
203
|
-
: withEfforts.filter(model => model.name.toLowerCase().includes(query)
|
|
204
|
-
|| model.id.toLowerCase().includes(query));
|
|
205
|
-
return {
|
|
206
|
-
shown,
|
|
207
|
-
total: withEfforts.length,
|
|
208
|
-
overridden: withEfforts.filter(model => model.configured !== undefined).length,
|
|
209
|
-
withoutEfforts: all.length - withEfforts.length,
|
|
210
|
-
showFilter: withEfforts.length > MODEL_FILTER_THRESHOLD,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Whether the default-effort catalog needs (re)fetching.
|
|
215
|
-
*
|
|
216
|
-
* Fetching is gated on an *attempt* signature rather than on the payload
|
|
217
|
-
* being empty: an empty answer is a legitimate result (a narrowed
|
|
218
|
-
* `config.providers`, or a catalog that is momentarily unavailable), and
|
|
219
|
-
* treating it as "not loaded yet" re-ran this effect forever. The signature
|
|
220
|
-
* also covers the accounts, so logging a second provider in refetches
|
|
221
|
-
* instead of leaving that card on the previous answer.
|
|
222
|
-
* @param input - the decision inputs.
|
|
223
|
-
* @returns true when the caller should start a fetch.
|
|
224
|
-
*/
|
|
225
|
-
export function shouldFetchModelDefaults(input) {
|
|
226
|
-
if (input.failed)
|
|
227
|
-
return false;
|
|
228
|
-
if (input.loggedIn.length === 0)
|
|
229
|
-
return false;
|
|
230
|
-
// Only an open disclosure pays for the per-model live resolve.
|
|
231
|
-
if (!input.open.some(provider => input.loggedIn.includes(provider)))
|
|
232
|
-
return false;
|
|
233
|
-
return input.loadedFor !== input.signature;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Stable signature of the accounts a catalog answer depends on. A change
|
|
237
|
-
* means a previous answer is stale (an account arrived or left), so the next
|
|
238
|
-
* open disclosure refetches.
|
|
239
|
-
* @param statuses - the per-provider status snapshot.
|
|
240
|
-
* @returns a signature string, stable across renders with equal accounts.
|
|
241
|
-
*/
|
|
242
|
-
export function modelDefaultsSignature(statuses) {
|
|
243
|
-
return PROVIDERS
|
|
244
|
-
.map(({ id }) => `${id}:${(statuses[id]?.accounts ?? []).map(account => account.key).sort().join(',')}`)
|
|
245
|
-
.join('|');
|
|
246
|
-
}
|
|
247
190
|
/**
|
|
248
191
|
* The Subscriptions settings page component.
|
|
249
192
|
* @param props - the slot inject face ({@link SubscriptionsSectionInjected}).
|
|
@@ -265,10 +208,24 @@ export function SubscriptionsSection(props) {
|
|
|
265
208
|
const [observedAt, setObservedAt] = useState({});
|
|
266
209
|
const [usageErrors, setUsageErrors] = useState({});
|
|
267
210
|
const [usageLoading, setUsageLoading] = useState({});
|
|
211
|
+
const [resetConfirmation, setResetConfirmation] = useState();
|
|
212
|
+
const [resetBusy, setResetBusy] = useState(false);
|
|
213
|
+
const [resetAcknowledged, setResetAcknowledged] = useState(false);
|
|
214
|
+
const [resetMessage, setResetMessage] = useState('');
|
|
215
|
+
const [resetAccount, setResetAccount] = useState();
|
|
216
|
+
const resetDialogRef = useRef(null);
|
|
217
|
+
useEffect(() => {
|
|
218
|
+
if (resetConfirmation)
|
|
219
|
+
resetDialogRef.current?.showModal();
|
|
220
|
+
else
|
|
221
|
+
resetDialogRef.current?.close();
|
|
222
|
+
}, [resetConfirmation]);
|
|
223
|
+
const resetInflight = useRef(false);
|
|
268
224
|
const mountedRef = useRef(true);
|
|
269
225
|
const pollersRef = useRef(new Map());
|
|
270
226
|
/** Accounts with a `usage` call in flight; guards the auto-fetch effect against re-entry. */
|
|
271
|
-
|
|
227
|
+
/** In-flight usage reads per key, holding the promise so a forced read can wait one out. */
|
|
228
|
+
const usageInflightRef = useRef(new Map());
|
|
272
229
|
const usageRosterSignatureRef = useRef();
|
|
273
230
|
const [managedProvider, setManagedProvider] = useState();
|
|
274
231
|
const setProviderError = useCallback((provider, message) => {
|
|
@@ -362,34 +319,91 @@ export function SubscriptionsSection(props) {
|
|
|
362
319
|
};
|
|
363
320
|
}, [refresh, startPolling]);
|
|
364
321
|
const loadUsage = useCallback(async (provider, account, force = false) => {
|
|
322
|
+
if (rpc === undefined)
|
|
323
|
+
return;
|
|
365
324
|
const key = `${provider}:${account}`;
|
|
325
|
+
const pending = usageInflightRef.current.get(key);
|
|
326
|
+
// A forced read must never be dropped behind a poll that started before the
|
|
327
|
+
// state changed. The refresh after a credit redemption is the only thing
|
|
328
|
+
// that picks up the new numbers, and the next automatic poll is minutes
|
|
329
|
+
// away, so waiting the earlier read out is cheaper than showing a stale
|
|
330
|
+
// percentage next to a success message.
|
|
331
|
+
if (pending !== undefined) {
|
|
332
|
+
if (!force)
|
|
333
|
+
return;
|
|
334
|
+
await pending;
|
|
335
|
+
}
|
|
366
336
|
if (rpc === undefined || usageInflightRef.current.has(key))
|
|
367
337
|
return;
|
|
368
|
-
|
|
369
|
-
|
|
338
|
+
const read = (async () => {
|
|
339
|
+
setUsageLoading(prev => ({ ...prev, [key]: true }));
|
|
340
|
+
try {
|
|
341
|
+
const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account, ...force ? { force: true } : {} });
|
|
342
|
+
if (!mountedRef.current)
|
|
343
|
+
return;
|
|
344
|
+
setUsages(prev => ({ ...prev, [key]: usage }));
|
|
345
|
+
setObservedAt(prev => ({ ...prev, [key]: usage.observedAt ?? Date.now() }));
|
|
346
|
+
window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
|
|
347
|
+
setUsageErrors((prev) => {
|
|
348
|
+
const next = { ...prev };
|
|
349
|
+
delete next[key];
|
|
350
|
+
return next;
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
if (mountedRef.current)
|
|
355
|
+
setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }));
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
usageInflightRef.current.delete(key);
|
|
359
|
+
if (mountedRef.current)
|
|
360
|
+
setUsageLoading(prev => ({ ...prev, [key]: false }));
|
|
361
|
+
}
|
|
362
|
+
})();
|
|
363
|
+
usageInflightRef.current.set(key, read);
|
|
364
|
+
await read;
|
|
365
|
+
}, [rpc]);
|
|
366
|
+
async function prepareReset(account) {
|
|
367
|
+
if (!rpc || resetInflight.current)
|
|
368
|
+
return;
|
|
369
|
+
resetInflight.current = true;
|
|
370
|
+
setResetBusy(true);
|
|
371
|
+
setResetAccount(account);
|
|
372
|
+
setResetConfirmation(undefined);
|
|
373
|
+
setResetMessage('');
|
|
370
374
|
try {
|
|
371
|
-
const
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
setUsages(prev => ({ ...prev, [key]: usage }));
|
|
375
|
-
setObservedAt(prev => ({ ...prev, [key]: usage.observedAt ?? Date.now() }));
|
|
376
|
-
window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
|
|
377
|
-
setUsageErrors((prev) => {
|
|
378
|
-
const next = { ...prev };
|
|
379
|
-
delete next[key];
|
|
380
|
-
return next;
|
|
381
|
-
});
|
|
375
|
+
const result = await callSubscriptionsAuth(rpc, 'prepareReset', { account });
|
|
376
|
+
setResetAcknowledged(false);
|
|
377
|
+
setResetConfirmation({ ...result, account });
|
|
382
378
|
}
|
|
383
379
|
catch (error) {
|
|
384
|
-
|
|
385
|
-
setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }));
|
|
380
|
+
setResetMessage(messageOf(error));
|
|
386
381
|
}
|
|
387
382
|
finally {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
setUsageLoading(prev => ({ ...prev, [key]: false }));
|
|
383
|
+
resetInflight.current = false;
|
|
384
|
+
setResetBusy(false);
|
|
391
385
|
}
|
|
392
|
-
}
|
|
386
|
+
}
|
|
387
|
+
async function consumeReset() {
|
|
388
|
+
if (!rpc || !resetConfirmation || !resetAcknowledged || resetInflight.current)
|
|
389
|
+
return;
|
|
390
|
+
const { account, ticket } = resetConfirmation;
|
|
391
|
+
resetInflight.current = true;
|
|
392
|
+
setResetBusy(true);
|
|
393
|
+
setResetConfirmation(undefined);
|
|
394
|
+
try {
|
|
395
|
+
await callSubscriptionsAuth(rpc, 'consumeReset', { account, ticket });
|
|
396
|
+
setResetMessage(t('resetUseSuccess'));
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
setResetMessage(messageOf(error));
|
|
400
|
+
}
|
|
401
|
+
finally {
|
|
402
|
+
await loadUsage('codex', account, true);
|
|
403
|
+
resetInflight.current = false;
|
|
404
|
+
setResetBusy(false);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
393
407
|
// Fetch usage once an account is logged in; drop the snapshots of accounts
|
|
394
408
|
// that vanished so a re-login refetches. A failed lookup does not auto-retry
|
|
395
409
|
// — the per-account Refresh button is the retry path.
|
|
@@ -514,7 +528,7 @@ export function SubscriptionsSection(props) {
|
|
|
514
528
|
if (rpc === undefined) {
|
|
515
529
|
return _jsx("p", { style: styles.intro, children: t('unavailable') });
|
|
516
530
|
}
|
|
517
|
-
return (_jsxs("div", { style: styles.section, children: [_jsx("p", { style: styles.intro, children: t('intro') }), _jsx(UsageBadgeDisplaySetting, { t: t }), PROVIDERS.map(({ id, name }) => {
|
|
531
|
+
return (_jsxs("div", { className: "dsh-subscriptions-settings", style: styles.section, children: [_jsx("style", { children: providerSettingsCss }), _jsx("p", { style: styles.intro, children: t('intro') }), _jsx(UsageBadgeDisplaySetting, { t: t }), PROVIDERS.map(({ id, name }) => {
|
|
518
532
|
const status = statuses[id];
|
|
519
533
|
const busy = status?.busy === true;
|
|
520
534
|
const deviceCode = deviceCodes[id];
|
|
@@ -524,17 +538,29 @@ export function SubscriptionsSection(props) {
|
|
|
524
538
|
const usage = usages[usageKey];
|
|
525
539
|
const usageError = usageErrors[usageKey];
|
|
526
540
|
const display = account.account ?? account.key;
|
|
541
|
+
const sortedCredits = [...(usage?.resetCredits ?? [])].sort((a, b) => (a.expiresAt ?? Infinity) - (b.expiresAt ?? Infinity));
|
|
542
|
+
const nextReset = sortedCredits.find(c => c.expiresAt === undefined || c.expiresAt > Date.now());
|
|
543
|
+
const resetBlock = usage ? resetActionBlock(usage) : 'resetUseRefresh';
|
|
544
|
+
const resetDisabled = resetBusy || resetBlock !== undefined;
|
|
527
545
|
// Providers without a usage endpoint answer supported:false — no block.
|
|
528
546
|
const showUsage = usage?.supported !== false
|
|
529
547
|
&& (usage !== undefined || usageError !== undefined || usageLoading[usageKey] === true);
|
|
530
548
|
return (_jsxs("div", { style: styles.accountRow, children: [_jsxs("div", { style: styles.accountHeader, children: [_jsx("button", { type: "button", style: styles.starButton, title: account.isDefault ? t('defaultBadge') : t('setDefault'), onClick: () => {
|
|
531
549
|
if (!account.isDefault)
|
|
532
550
|
void setDefault(id, account.key);
|
|
533
|
-
}, children: account.isDefault ? '★' : '☆' }), _jsx("span", { style: styles.accountName, children: display }), account.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: account.plan })), account.expiresAt !== undefined && (_jsx("span", { style: styles.statusLine, children: t('accountExpires', { date: new Date(account.expiresAt).toLocaleString() }) })), _jsx("button", { type: "button", style: {
|
|
551
|
+
}, children: account.isDefault ? '★' : '☆' }), _jsx("span", { style: styles.accountName, children: display }), account.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: account.plan })), account.expiresAt !== undefined && (_jsx("span", { style: styles.statusLine, children: t('accountExpires', { date: new Date(account.expiresAt).toLocaleString() }) })), _jsx("button", { type: "button", style: { marginLeft: 'auto', flexShrink: 0 }, onClick: () => { void logout(id, account.key, display, name); }, children: t('logout') })] }), showUsage && (_jsxs("div", { style: styles.usage, children: [_jsxs("div", { style: styles.usageHeader, children: [_jsx("span", { style: styles.usageTitle, children: t('usageTitle') }), usage?.plan !== undefined && (_jsx("span", { style: styles.usagePlan, children: t('usagePlan', { plan: usage.plan }) })), _jsx("button", { type: "button", style: styles.usageRefresh, disabled: usageLoading[usageKey] === true, onClick: () => { void loadUsage(id, account.key, true); }, children: t('usageRefresh') })] }), usage === undefined && usageError === undefined && (_jsx("p", { style: styles.statusLine, children: t('usageLoading') })), usageError !== undefined && (_jsx("p", { style: styles.errorLine, children: t('usageError', { message: usageError }) })), usage?.windows !== undefined && usage.windows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageEmpty') })), (usage?.windows ?? []).map((window, index) => {
|
|
534
552
|
const percent = displayUsedPercent(window.usedPercent);
|
|
535
553
|
return (_jsxs("div", { style: styles.usageRow, children: [_jsxs("div", { style: styles.usageMeta, children: [_jsx("span", { children: usageWindowLabel(t, window) }), _jsxs("span", { children: [percent === undefined ? t('usageMeterInvalid') : `${percent}%`, window.resetsAt !== undefined
|
|
536
554
|
&& ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`] })] }), _jsx(UsageMeter, { window: window, t: t, observedAt: observedAt[usageKey], stale: usageError !== undefined || usage.stale === true })] }, index));
|
|
537
|
-
})
|
|
538
|
-
|
|
539
|
-
|
|
555
|
+
}), (id === 'codex' || id === 'claude') && usage?.resetCreditsError !== undefined && (_jsx(ResetCreditsErrorLine, { provider: id, message: usage.resetCreditsError, t: t })), (id === 'codex' || id === 'claude') && showsResetCredits(id, usage?.resetCredits) && (_jsx(ResetCreditsDisclosure, { mode: id === 'claude' ? 'grants' : 'credits', credits: sortedCredits, t: t, ...nextReset !== undefined ? { nextCredit: nextReset } : {}, ...id === 'codex' ? { useAction: {
|
|
556
|
+
accountKey: account.key,
|
|
557
|
+
busy: resetBusy && resetAccount === account.key,
|
|
558
|
+
disabled: resetDisabled,
|
|
559
|
+
title: t(resetBusy ? 'resetUseChecking' : resetBlock ?? 'resetUseReady'),
|
|
560
|
+
label: t('resetUseButton'),
|
|
561
|
+
onUse: () => { if (!resetDisabled)
|
|
562
|
+
void prepareReset(account.key); },
|
|
563
|
+
} } : {}, ...resetAccount === account.key && resetMessage !== '' ? { statusMessage: resetMessage } : {} }))] }))] }, account.key));
|
|
564
|
+
}), _jsxs("div", { style: styles.actions, children: [!busy && accounts.length === 0 && (_jsx("button", { type: "button", onClick: () => { void login(id); }, children: t('login') })), !busy && accounts.length > 0 && id === 'claude' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => { void login(id, 'oauth'); }, children: t('addAccountOAuth') }), _jsx("button", { type: "button", onClick: () => { void login(id, 'keychain'); }, children: t('addAccountKeychain') })] })), !busy && accounts.length > 0 && id !== 'claude' && (_jsx("button", { type: "button", onClick: () => { void login(id); }, children: t('addAccount') })), _jsx("button", { type: "button", "aria-haspopup": "dialog", onClick: () => setManagedProvider({ id, name }), children: t('accountsManage') }), busy && (_jsx("button", { type: "button", onClick: () => { void cancel(id); }, children: t('cancel') }))] }), !busy && accounts.length > 0 && (_jsx("p", { style: styles.statusLine, children: t('addAccountHint') })), busy && deviceCode !== undefined && (_jsxs("div", { style: styles.deviceCode, children: [_jsx("span", { style: styles.statusLine, children: t('deviceCodePrompt') }), _jsx("span", { style: styles.deviceCodeText, children: deviceCode.userCode }), _jsxs("div", { style: styles.actions, children: [_jsx("button", { type: "button", onClick: () => { copyDeviceCode(id, deviceCode.userCode); }, children: copiedCode === id ? t('deviceCodeCopied') : t('deviceCodeCopy') }), _jsx("button", { type: "button", onClick: () => { window.open(deviceCode.verificationUrl, '_blank', 'noopener'); }, children: t('deviceCodeOpenPage') })] })] })), busy && deviceCode === undefined && (_jsxs("details", { style: styles.manual, children: [_jsx("summary", { children: t('manualSummary') }), _jsxs("div", { style: styles.manualRow, children: [_jsx("input", { style: styles.manualInput, value: manualDrafts[id], placeholder: t('manualPlaceholder'), onChange: event => setManualDrafts(prev => ({ ...prev, [id]: event.target.value })) }), _jsx("button", { type: "button", onClick: () => { void submitManual(id); }, children: t('submit') })] })] }))] }, id));
|
|
565
|
+
}), _jsx(CursorCard, { rpc: rpc, t: t }), _jsx(ExternalUsageCards, { rpc: rpc, t: t }), managedProvider && _jsx(ProviderAccountManager, { provider: managedProvider.id, name: managedProvider.name, rpc: rpc, t: t, onClose: () => setManagedProvider(undefined) }), _jsx("style", { children: '.subscriptions-reset-dialog::backdrop { background: var(--dsw-alias-bg-mask-1, #0006); backdrop-filter: var(--dsw-mask-blur, none); }' }), _jsx("dialog", { ref: resetDialogRef, className: "subscriptions-reset-dialog", "aria-labelledby": "subscriptions-reset-title", onCancel: () => setResetConfirmation(undefined), onClose: () => setResetConfirmation(undefined), style: { ...styles.modal, display: resetConfirmation ? 'flex' : 'none', margin: 'auto', color: 'var(--dsw-alias-label-primary)' }, children: resetConfirmation && _jsxs(_Fragment, { children: [_jsx("h3", { id: "subscriptions-reset-title", style: { ...styles.modalTitle, margin: 0 }, children: t('resetUseConfirmTitle') }), _jsx("p", { style: { ...styles.statusLine, overflowWrap: 'anywhere' }, children: statuses.codex?.accounts.find(a => a.key === resetConfirmation.account)?.account ?? resetConfirmation.account }), _jsxs("div", { style: { ...styles.usageMeta, gap: 12 }, children: [_jsx("span", { children: t('usageWeekly') }), _jsxs("strong", { children: [Math.round(resetConfirmation.weeklyUsedPercent), "%"] })] }), _jsx("div", { style: styles.usageMeta, children: _jsx("span", { children: resetConfirmation.creditExpiresAt === undefined ? t('resetCreditExpiryUnknown') : t('resetCreditExpires', { date: new Date(resetConfirmation.creditExpiresAt).toLocaleString() }) }) }), _jsx("p", { style: { ...styles.statusLine, margin: '4px 0' }, children: t('resetUseWarning') }), _jsxs("label", { style: { display: 'flex', gap: 8, alignItems: 'flex-start', fontSize: 12 }, children: [_jsx("input", { type: "checkbox", checked: resetAcknowledged, onChange: e => setResetAcknowledged(e.target.checked) }), t('resetUseAcknowledge')] }), _jsxs("div", { className: "dsh-subscription-dialog-actions", style: { ...styles.actions, justifyContent: 'flex-end', marginTop: 8 }, children: [_jsx("button", { type: "button", autoFocus: true, onClick: () => setResetConfirmation(undefined), children: t('cancel') }), _jsx("button", { type: "button", className: "dsh-subscription-primary", disabled: !resetAcknowledged || resetBusy, onClick: () => { void consumeReset(); }, children: t('resetUseConfirm') })] })] }) })] }));
|
|
540
566
|
}
|
|
@@ -39,15 +39,11 @@ export function UsageBadgeDisplaySetting({ t }) {
|
|
|
39
39
|
}
|
|
40
40
|
const styles = {
|
|
41
41
|
card: {
|
|
42
|
-
border: '
|
|
42
|
+
border: '0.5px solid var(--dsw-alias-settings-card-stroke, var(--dsw-alias-border-l4))',
|
|
43
|
+
borderRadius: 'var(--dsw-radius-xl, 20px)', background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',
|
|
43
44
|
padding: '12px 14px', display: 'flex', flexDirection: 'column', gap: 6,
|
|
44
45
|
},
|
|
45
|
-
field: { display: 'flex', flexDirection: 'column', gap:
|
|
46
|
-
select: {
|
|
47
|
-
height: 32, width: '100%', boxSizing: 'border-box',
|
|
48
|
-
border: '1px solid var(--dsw-alias-border-l2)', borderRadius: 8,
|
|
49
|
-
padding: '0 10px', font: 'inherit',
|
|
50
|
-
background: 'var(--dsw-alias-bg-layer-1)', color: 'var(--dsw-alias-label-primary)',
|
|
51
|
-
},
|
|
46
|
+
field: { display: 'flex', flexDirection: 'column', gap: 6, fontSize: 13, fontWeight: 500, lineHeight: '20px' },
|
|
47
|
+
select: { width: '100%' },
|
|
52
48
|
hint: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' },
|
|
53
49
|
};
|
|
@@ -83,7 +83,7 @@ export declare const HOST_CONTRACT: {
|
|
|
83
83
|
/** Design tokens the client styles with; the host theme must define each one. */
|
|
84
84
|
readonly tokens: {
|
|
85
85
|
readonly package: "@deepseek-ai/dsh-client-ui-theme";
|
|
86
|
-
readonly names: readonly ["--dsw-alias-bg-layer-1", "--dsw-alias-bg-skeleton", "--dsw-alias-border-l2", "--dsw-alias-border-l2-darkmode-thin", "--dsw-alias-interactive-bg-hover", "--dsw-alias-interactive-bg-hover-solid", "--dsw-alias-label-dimmed", "--dsw-alias-label-primary", "--dsw-alias-label-secondary", "--dsw-alias-label-tertiary", "--dsw-alias-state-error-primary", "--dsw-alias-state-success-primary", "--dsw-alias-state-warn-label", "--dsw-elevation-prominent", "--dsw-menu-backdrop-filter", "--dsw-specific-menu"];
|
|
86
|
+
readonly names: readonly ["--dsw-alias-bg-layer-1", "--dsw-alias-bg-layer-2", "--dsw-alias-bg-layer-3", "--dsw-alias-bg-mask-1", "--dsw-alias-bg-skeleton", "--dsw-alias-border-l1", "--dsw-alias-border-l2", "--dsw-alias-border-l2-darkmode-thin", "--dsw-alias-border-l3", "--dsw-alias-border-l4", "--dsw-alias-brand-primary", "--dsw-alias-button-primary-fill", "--dsw-alias-button-primary-hover", "--dsw-alias-interactive-bg-active", "--dsw-alias-interactive-bg-hover", "--dsw-alias-interactive-bg-hover-solid", "--dsw-alias-label-dimmed", "--dsw-alias-label-primary", "--dsw-alias-label-primary-foreground", "--dsw-alias-label-secondary", "--dsw-alias-label-tertiary", "--dsw-alias-settings-card-fill", "--dsw-alias-settings-card-stroke", "--dsw-alias-state-business-primary", "--dsw-alias-state-error-primary", "--dsw-alias-state-success-primary", "--dsw-alias-state-warn-label", "--dsw-elevation-prominent", "--dsw-focus-ring-color", "--dsw-focus-ring-width", "--dsw-mask-blur", "--dsw-menu-backdrop-filter", "--dsw-radius-lg", "--dsw-radius-md", "--dsw-radius-panel", "--dsw-radius-sm", "--dsw-radius-xl", "--dsw-specific-menu"];
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
89
|
/** A glyph name listed in {@link HOST_CONTRACT}; hostIcon() accepts no other. */
|
|
@@ -82,20 +82,42 @@ export const HOST_CONTRACT = {
|
|
|
82
82
|
package: '@deepseek-ai/dsh-client-ui-theme',
|
|
83
83
|
names: [
|
|
84
84
|
'--dsw-alias-bg-layer-1',
|
|
85
|
+
'--dsw-alias-bg-layer-2',
|
|
86
|
+
'--dsw-alias-bg-layer-3',
|
|
87
|
+
'--dsw-alias-bg-mask-1',
|
|
85
88
|
'--dsw-alias-bg-skeleton',
|
|
89
|
+
'--dsw-alias-border-l1',
|
|
86
90
|
'--dsw-alias-border-l2',
|
|
87
91
|
'--dsw-alias-border-l2-darkmode-thin',
|
|
92
|
+
'--dsw-alias-border-l3',
|
|
93
|
+
'--dsw-alias-border-l4',
|
|
94
|
+
'--dsw-alias-brand-primary',
|
|
95
|
+
'--dsw-alias-button-primary-fill',
|
|
96
|
+
'--dsw-alias-button-primary-hover',
|
|
97
|
+
'--dsw-alias-interactive-bg-active',
|
|
88
98
|
'--dsw-alias-interactive-bg-hover',
|
|
89
99
|
'--dsw-alias-interactive-bg-hover-solid',
|
|
90
100
|
'--dsw-alias-label-dimmed',
|
|
91
101
|
'--dsw-alias-label-primary',
|
|
102
|
+
'--dsw-alias-label-primary-foreground',
|
|
92
103
|
'--dsw-alias-label-secondary',
|
|
93
104
|
'--dsw-alias-label-tertiary',
|
|
105
|
+
'--dsw-alias-settings-card-fill',
|
|
106
|
+
'--dsw-alias-settings-card-stroke',
|
|
107
|
+
'--dsw-alias-state-business-primary',
|
|
94
108
|
'--dsw-alias-state-error-primary',
|
|
95
109
|
'--dsw-alias-state-success-primary',
|
|
96
110
|
'--dsw-alias-state-warn-label',
|
|
97
111
|
'--dsw-elevation-prominent',
|
|
112
|
+
'--dsw-focus-ring-color',
|
|
113
|
+
'--dsw-focus-ring-width',
|
|
114
|
+
'--dsw-mask-blur',
|
|
98
115
|
'--dsw-menu-backdrop-filter',
|
|
116
|
+
'--dsw-radius-lg',
|
|
117
|
+
'--dsw-radius-md',
|
|
118
|
+
'--dsw-radius-panel',
|
|
119
|
+
'--dsw-radius-sm',
|
|
120
|
+
'--dsw-radius-xl',
|
|
99
121
|
'--dsw-specific-menu',
|
|
100
122
|
],
|
|
101
123
|
},
|
package/lib/client/locales.d.ts
CHANGED
|
@@ -104,6 +104,35 @@ export declare const en: {
|
|
|
104
104
|
usageColorPaceHint: string;
|
|
105
105
|
usageColorRemainingHint: string;
|
|
106
106
|
usagePlan: string;
|
|
107
|
+
resetCreditsTitle: string;
|
|
108
|
+
resetCreditsAvailable: string;
|
|
109
|
+
resetCreditsError: string;
|
|
110
|
+
resetCreditsErrorFixed: string;
|
|
111
|
+
resetCreditReadOnly: string;
|
|
112
|
+
resetCreditReadOnlyLabel: string;
|
|
113
|
+
resetCreditAvailable: string;
|
|
114
|
+
resetCreditNotUsable: string;
|
|
115
|
+
resetCreditPaused: string;
|
|
116
|
+
resetCreditExhausted: string;
|
|
117
|
+
resetCreditExpired: string;
|
|
118
|
+
resetCreditRemaining: string;
|
|
119
|
+
resetCreditLeft: string;
|
|
120
|
+
resetCreditRemainingUnknown: string;
|
|
121
|
+
resetCreditCooldownUntil: string;
|
|
122
|
+
resetUseButton: string;
|
|
123
|
+
resetUseChecking: string;
|
|
124
|
+
resetUseGuard: string;
|
|
125
|
+
resetUseRestart: string;
|
|
126
|
+
resetUseRefresh: string;
|
|
127
|
+
resetUseReady: string;
|
|
128
|
+
resetUseConfirmTitle: string;
|
|
129
|
+
resetUseWarning: string;
|
|
130
|
+
resetUseAcknowledge: string;
|
|
131
|
+
resetUseConfirm: string;
|
|
132
|
+
resetUseSuccess: string;
|
|
133
|
+
resetCreditFull: string;
|
|
134
|
+
resetCreditExpires: string;
|
|
135
|
+
resetCreditExpiryUnknown: string;
|
|
107
136
|
externalUsageTitle: string;
|
|
108
137
|
externalUsageConnected: string;
|
|
109
138
|
externalUsageNotConfigured: string;
|
|
@@ -276,6 +305,35 @@ export declare const zh: {
|
|
|
276
305
|
usageColorPaceHint: string;
|
|
277
306
|
usageColorRemainingHint: string;
|
|
278
307
|
usagePlan: string;
|
|
308
|
+
resetCreditsTitle: string;
|
|
309
|
+
resetCreditsAvailable: string;
|
|
310
|
+
resetCreditsError: string;
|
|
311
|
+
resetCreditsErrorFixed: string;
|
|
312
|
+
resetCreditReadOnly: string;
|
|
313
|
+
resetCreditReadOnlyLabel: string;
|
|
314
|
+
resetCreditAvailable: string;
|
|
315
|
+
resetCreditNotUsable: string;
|
|
316
|
+
resetCreditPaused: string;
|
|
317
|
+
resetCreditExhausted: string;
|
|
318
|
+
resetCreditExpired: string;
|
|
319
|
+
resetCreditRemaining: string;
|
|
320
|
+
resetCreditLeft: string;
|
|
321
|
+
resetCreditRemainingUnknown: string;
|
|
322
|
+
resetCreditCooldownUntil: string;
|
|
323
|
+
resetUseButton: string;
|
|
324
|
+
resetUseChecking: string;
|
|
325
|
+
resetUseGuard: string;
|
|
326
|
+
resetUseRestart: string;
|
|
327
|
+
resetUseRefresh: string;
|
|
328
|
+
resetUseReady: string;
|
|
329
|
+
resetUseConfirmTitle: string;
|
|
330
|
+
resetUseWarning: string;
|
|
331
|
+
resetUseAcknowledge: string;
|
|
332
|
+
resetUseConfirm: string;
|
|
333
|
+
resetUseSuccess: string;
|
|
334
|
+
resetCreditFull: string;
|
|
335
|
+
resetCreditExpires: string;
|
|
336
|
+
resetCreditExpiryUnknown: string;
|
|
279
337
|
externalUsageTitle: string;
|
|
280
338
|
externalUsageConnected: string;
|
|
281
339
|
externalUsageNotConfigured: string;
|