dsh-subscriptions 0.1.5 → 0.2.2

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 (110) hide show
  1. package/README.md +212 -154
  2. package/lib/auth/claude-code-creds.js +31 -9
  3. package/lib/auth/device-flow.js +16 -9
  4. package/lib/auth/oauth-flow.js +13 -10
  5. package/lib/auth/rpc.d.ts +73 -2
  6. package/lib/auth/rpc.js +124 -23
  7. package/lib/auth/store.js +80 -31
  8. package/lib/client/CursorCard.d.ts +1 -1
  9. package/lib/client/CursorCard.js +50 -16
  10. package/lib/client/ExternalUsageCards.d.ts +1 -1
  11. package/lib/client/ExternalUsageCards.js +37 -16
  12. package/lib/client/ImageGallery.d.ts +2 -2
  13. package/lib/client/ImageGallery.js +92 -33
  14. package/lib/client/ImageGenerateToolview.js +50 -14
  15. package/lib/client/OllamaCard.d.ts +13 -0
  16. package/lib/client/OllamaCard.js +94 -0
  17. package/lib/client/OllamaSettingsManager.d.ts +24 -0
  18. package/lib/client/OllamaSettingsManager.js +329 -0
  19. package/lib/client/ProviderAccountManager.d.ts +1 -1
  20. package/lib/client/ProviderAccountManager.js +164 -49
  21. package/lib/client/ProviderModelEditor.js +109 -26
  22. package/lib/client/SpeedSelect.d.ts +62 -14
  23. package/lib/client/SpeedSelect.js +257 -46
  24. package/lib/client/SubscriptionUsageBadge.d.ts +5 -11
  25. package/lib/client/SubscriptionUsageBadge.js +301 -112
  26. package/lib/client/SubscriptionsSection.d.ts +2 -0
  27. package/lib/client/SubscriptionsSection.js +259 -85
  28. package/lib/client/UsageBadgeDisplaySetting.js +35 -12
  29. package/lib/client/UsageMeter.d.ts +1 -1
  30. package/lib/client/UsageMeter.js +69 -27
  31. package/lib/client/VideoGenerateToolview.js +69 -17
  32. package/lib/client/account-preferences.d.ts +8 -0
  33. package/lib/client/account-preferences.js +20 -5
  34. package/lib/client/host-contract.d.ts +11 -2
  35. package/lib/client/host-contract.js +20 -3
  36. package/lib/client/index.d.ts +5 -5
  37. package/lib/client/index.js +34 -12
  38. package/lib/client/locales.d.ts +78 -0
  39. package/lib/client/locales.js +121 -34
  40. package/lib/client/ollama-draft.d.ts +229 -0
  41. package/lib/client/ollama-draft.js +255 -0
  42. package/lib/client/reset-action.js +6 -4
  43. package/lib/client/reset-credits-view.d.ts +1 -1
  44. package/lib/client/reset-credits-view.js +66 -17
  45. package/lib/client/subscription-card-styles.js +94 -24
  46. package/lib/client/usage-color-preferences.js +4 -2
  47. package/lib/client/usage-pace.d.ts +7 -0
  48. package/lib/client/usage-pace.js +43 -10
  49. package/lib/client.js +1647 -266
  50. package/lib/client.js.map +1 -1
  51. package/lib/http.js +1 -1
  52. package/lib/index.d.ts +28 -3
  53. package/lib/index.js +9329 -8217
  54. package/lib/model-defaults.js +4 -2
  55. package/lib/provider-settings.d.ts +14 -1
  56. package/lib/provider-settings.js +64 -20
  57. package/lib/providers/account-preferences.js +51 -22
  58. package/lib/providers/accounts.js +15 -9
  59. package/lib/providers/antigravity-oauth-client.js +2 -2
  60. package/lib/providers/antigravity.js +141 -68
  61. package/lib/providers/catalog-store.js +120 -41
  62. package/lib/providers/claude-cli-version.js +3 -3
  63. package/lib/providers/claude.d.ts +23 -3
  64. package/lib/providers/claude.js +167 -92
  65. package/lib/providers/codex-client-version.js +3 -3
  66. package/lib/providers/codex-search.js +40 -13
  67. package/lib/providers/codex.js +196 -112
  68. package/lib/providers/common.d.ts +14 -0
  69. package/lib/providers/common.js +118 -38
  70. package/lib/providers/copilot.js +143 -82
  71. package/lib/providers/cursor-adapter.js +42 -18
  72. package/lib/providers/cursor-auth.d.ts +1 -1
  73. package/lib/providers/cursor-auth.js +69 -24
  74. package/lib/providers/cursor-model-settings.js +14 -5
  75. package/lib/providers/cursor-usage.js +27 -13
  76. package/lib/providers/external-usage-controller.d.ts +9 -2
  77. package/lib/providers/external-usage-controller.js +30 -7
  78. package/lib/providers/external-usage.d.ts +8 -0
  79. package/lib/providers/external-usage.js +140 -20
  80. package/lib/providers/grok.js +152 -89
  81. package/lib/providers/image-pool.js +29 -11
  82. package/lib/providers/minimax-usage.js +31 -11
  83. package/lib/providers/npm-cli-version.js +10 -3
  84. package/lib/providers/ollama-settings.d.ts +90 -0
  85. package/lib/providers/ollama-settings.js +213 -0
  86. package/lib/providers/ollama-web.d.ts +46 -0
  87. package/lib/providers/ollama-web.js +231 -0
  88. package/lib/providers/ollama.d.ts +107 -0
  89. package/lib/providers/ollama.js +608 -0
  90. package/lib/providers/pool-family.js +11 -3
  91. package/lib/providers/pool-health.js +28 -8
  92. package/lib/providers/pool-usage.js +16 -9
  93. package/lib/providers/pool.d.ts +8 -0
  94. package/lib/providers/pool.js +81 -42
  95. package/lib/providers/rate-limit.js +8 -2
  96. package/lib/providers/replay.js +40 -17
  97. package/lib/providers/reset-redemption.js +18 -6
  98. package/lib/tools/image-generate.js +123 -65
  99. package/lib/tools/registration.js +5 -2
  100. package/lib/tools/video-generate.js +51 -31
  101. package/lib/tools/x-search.js +50 -22
  102. package/lib/translate/anthropic.js +85 -37
  103. package/lib/translate/antigravity-schema.js +71 -28
  104. package/lib/translate/antigravity-thinking.js +22 -9
  105. package/lib/translate/antigravity.js +141 -50
  106. package/lib/translate/chat-completions.js +67 -23
  107. package/lib/translate/resolved.js +55 -21
  108. package/lib/translate/responses.js +69 -29
  109. package/lib/translate/sse.js +4 -1
  110. package/package.json +26 -4
@@ -33,6 +33,8 @@ export interface UsageWindow {
33
33
  startsAt?: number;
34
34
  windowDurationMs?: number;
35
35
  fixedWindow?: boolean;
36
+ /** Display-only assumed start; the marker rides it, never pace. */
37
+ displayStartsAt?: number;
36
38
  }
37
39
  /** `usage` endpoint value: the node half owns this shape. */
38
40
  export interface ProviderUsage {
@@ -19,13 +19,14 @@ import { ProviderAccountManager } from './ProviderAccountManager.js';
19
19
  import { providerSettingsCss } from './provider-settings-styles.js';
20
20
  import { ExternalUsageCards } from './ExternalUsageCards.js';
21
21
  import { CursorCard } from './CursorCard.js';
22
+ import { OllamaCard } from './OllamaCard.js';
22
23
  import { UsageMeter } from './UsageMeter.js';
23
- import { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits } from './reset-credits-view.js';
24
+ import { ResetCreditsDisclosure, ResetCreditsErrorLine, showsResetCredits, } from './reset-credits-view.js';
24
25
  import { displayUsedPercent } from './usage-pace.js';
25
26
  import { UsageBadgeDisplaySetting } from './UsageBadgeDisplaySetting.js';
26
27
  import { USAGE_BADGE_REFRESH_EVENT } from './usage-badge-preferences.js';
27
28
  import { subscriptionCardStyles as cardStyles } from './subscription-card-styles.js';
28
- import { callSubscriptionsAuth, SubscriptionsAuthError } from './subscriptions-rpc.js';
29
+ import { callSubscriptionsAuth, SubscriptionsAuthError, } from './subscriptions-rpc.js';
29
30
  export { callSubscriptionsAuth } from './subscriptions-rpc.js';
30
31
  /** Poll cadence while a provider login attempt is busy. */
31
32
  const POLL_INTERVAL_MS = 2000;
@@ -49,7 +50,7 @@ function messageOf(error) {
49
50
  }
50
51
  /** Copy a keyed map without the entries whose key is not in `live`. */
51
52
  function dropStale(map, live) {
52
- const stale = Object.keys(map).filter(key => !live.has(key));
53
+ const stale = Object.keys(map).filter((key) => !live.has(key));
53
54
  if (stale.length === 0)
54
55
  return map;
55
56
  const next = { ...map };
@@ -73,61 +74,128 @@ function fallbackTranslate(key, params) {
73
74
  }
74
75
  const styles = {
75
76
  section: {
76
- display: 'flex', flexDirection: 'column', gap: 12, maxWidth: 560,
77
+ display: 'flex',
78
+ flexDirection: 'column',
79
+ gap: 12,
80
+ maxWidth: 560,
77
81
  color: 'var(--dsw-alias-label-primary)',
78
82
  },
79
- intro: { margin: 0, color: 'var(--dsw-alias-label-tertiary)', fontSize: 14, lineHeight: '22px' },
80
- card: { ...cardStyles.card,
83
+ intro: {
84
+ margin: 0,
85
+ color: 'var(--dsw-alias-label-tertiary)',
86
+ fontSize: 14,
87
+ lineHeight: '22px',
88
+ },
89
+ card: {
90
+ ...cardStyles.card,
81
91
  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))',
92
+ borderRadius: 'var(--dsw-radius-xl, 20px)',
93
+ background: 'var(--dsw-alias-settings-card-fill, var(--dsw-alias-bg-layer-2))',
83
94
  },
84
95
  cardHeader: cardStyles.header,
85
96
  dot: cardStyles.dot,
86
97
  name: cardStyles.name,
87
98
  statusLine: cardStyles.status,
88
- clientVersion: { fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)', fontVariantNumeric: 'tabular-nums' },
99
+ clientVersion: {
100
+ fontSize: 12,
101
+ lineHeight: '18px',
102
+ color: 'var(--dsw-alias-label-tertiary)',
103
+ fontVariantNumeric: 'tabular-nums',
104
+ },
89
105
  errorLine: cardStyles.error,
90
106
  actions: cardStyles.actions,
91
- usage: { ...cardStyles.usage, borderTop: '0.5px solid var(--dsw-alias-border-l2)' },
107
+ usage: {
108
+ ...cardStyles.usage,
109
+ borderTop: '0.5px solid var(--dsw-alias-border-l2)',
110
+ },
92
111
  usageHeader: cardStyles.usageHeader,
93
112
  usageTitle: cardStyles.usageTitle,
94
113
  usagePlan: cardStyles.usagePlan,
95
- usageRefresh: { minHeight: 22, height: 22, padding: '0 8px', marginLeft: 'auto' },
114
+ usageRefresh: {
115
+ minHeight: 22,
116
+ height: 22,
117
+ padding: '0 8px',
118
+ marginLeft: 'auto',
119
+ },
96
120
  usageRow: cardStyles.usageRow,
97
121
  usageMeta: cardStyles.usageMeta,
98
- accountRow: { ...cardStyles.account, border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)' },
122
+ accountRow: {
123
+ ...cardStyles.account,
124
+ border: '0.5px solid var(--dsw-alias-border-l2)',
125
+ borderRadius: 'var(--dsw-radius-lg, 16px)',
126
+ },
99
127
  accountHeader: cardStyles.accountHeader,
100
128
  accountName: cardStyles.accountName,
101
129
  starButton: {
102
- border: 'none', padding: 0, width: 28,
103
- font: 'inherit', fontSize: 14, lineHeight: '20px', cursor: 'pointer',
130
+ border: 'none',
131
+ padding: 0,
132
+ width: 28,
133
+ font: 'inherit',
134
+ fontSize: 14,
135
+ lineHeight: '20px',
136
+ cursor: 'pointer',
104
137
  color: 'var(--dsw-alias-state-warn-label)',
105
138
  },
106
139
  deviceCode: {
107
- marginTop: 4, display: 'flex', flexDirection: 'column', gap: 6,
108
- border: '0.5px solid var(--dsw-alias-border-l2)', borderRadius: 'var(--dsw-radius-lg, 16px)',
109
- padding: '10px 12px', background: 'var(--dsw-alias-bg-layer-1)',
140
+ marginTop: 4,
141
+ display: 'flex',
142
+ flexDirection: 'column',
143
+ gap: 6,
144
+ border: '0.5px solid var(--dsw-alias-border-l2)',
145
+ borderRadius: 'var(--dsw-radius-lg, 16px)',
146
+ padding: '10px 12px',
147
+ background: 'var(--dsw-alias-bg-layer-1)',
110
148
  },
111
149
  deviceCodeText: {
112
- fontFamily: 'monospace', fontSize: 18, lineHeight: '24px', letterSpacing: 2,
113
- color: 'var(--dsw-alias-label-primary)', userSelect: 'all',
150
+ fontFamily: 'monospace',
151
+ fontSize: 18,
152
+ lineHeight: '24px',
153
+ letterSpacing: 2,
154
+ color: 'var(--dsw-alias-label-primary)',
155
+ userSelect: 'all',
114
156
  },
115
157
  manual: { fontSize: 13, lineHeight: '20px' },
116
- manualRow: { display: 'flex', flexWrap: 'wrap', gap: 8, alignItems: 'center', marginTop: 8 },
158
+ manualRow: {
159
+ display: 'flex',
160
+ flexWrap: 'wrap',
161
+ gap: 8,
162
+ alignItems: 'center',
163
+ marginTop: 8,
164
+ },
117
165
  manualInput: { flex: '1 1 200px', minWidth: 0 },
118
166
  modalOverlay: {
119
- position: 'fixed', inset: 0, zIndex: 1000,
120
- display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16,
121
- background: 'var(--dsw-alias-bg-mask-1, #0006)', backdropFilter: 'var(--dsw-mask-blur, none)',
167
+ position: 'fixed',
168
+ inset: 0,
169
+ zIndex: 1000,
170
+ display: 'flex',
171
+ alignItems: 'center',
172
+ justifyContent: 'center',
173
+ padding: 16,
174
+ background: 'var(--dsw-alias-bg-mask-1, #0006)',
175
+ backdropFilter: 'var(--dsw-mask-blur, none)',
122
176
  },
123
177
  modal: {
124
- width: 460, maxWidth: '100%', maxHeight: '90vh', overflowY: 'auto',
125
- boxSizing: 'border-box', display: 'flex', flexDirection: 'column', gap: 12,
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)',
178
+ width: 460,
179
+ maxWidth: '100%',
180
+ maxHeight: '90vh',
181
+ overflowY: 'auto',
182
+ boxSizing: 'border-box',
183
+ display: 'flex',
184
+ flexDirection: 'column',
185
+ gap: 12,
186
+ padding: '16px 18px',
187
+ borderRadius: 'var(--dsw-radius-panel, 28px)',
188
+ background: 'var(--dsw-alias-bg-layer-2)',
189
+ border: 0,
190
+ boxShadow: 'var(--dsw-elevation-prominent)',
128
191
  },
129
192
  modalHeader: { display: 'flex', alignItems: 'center', gap: 8 },
130
- modalTitle: { fontWeight: 500, fontSize: 16, lineHeight: '24px', color: 'var(--dsw-alias-label-primary)' },
193
+ modalTitle: {
194
+ fontWeight: 500,
195
+ fontSize: 16,
196
+ lineHeight: '24px',
197
+ color: 'var(--dsw-alias-label-primary)',
198
+ },
131
199
  };
132
200
  /** Status dot color for one provider state. */
133
201
  function dotColor(status) {
@@ -137,16 +205,6 @@ function dotColor(status) {
137
205
  return 'var(--dsw-alias-state-success-primary)';
138
206
  return 'var(--dsw-alias-label-dimmed)';
139
207
  }
140
- /**
141
- * Whether a provider has at least one connected account. Multi-account made
142
- * "logged in" a property of the account list rather than a flag, so every
143
- * logged-in test goes through this one predicate.
144
- * @param status - the provider's last reported state, possibly absent.
145
- * @returns true when the provider serves at least one account.
146
- */
147
- function hasAccount(status) {
148
- return (status?.accounts.length ?? 0) > 0;
149
- }
150
208
  /**
151
209
  * One-line status text for one provider state.
152
210
  * @param t - section translate.
@@ -171,7 +229,10 @@ function statusText(t, status) {
171
229
  export function clientVersionText(t, clientVersion) {
172
230
  if (clientVersion === undefined)
173
231
  return '';
174
- return t('clientVersion', { version: clientVersion.version, source: t(CLIENT_VERSION_SOURCES[clientVersion.source]) });
232
+ return t('clientVersion', {
233
+ version: clientVersion.version,
234
+ source: t(CLIENT_VERSION_SOURCES[clientVersion.source]),
235
+ });
175
236
  }
176
237
  /**
177
238
  * Localized label of one usage window (kind, plus the model scope when named).
@@ -182,8 +243,12 @@ export function clientVersionText(t, clientVersion) {
182
243
  function usageWindowLabel(t, window) {
183
244
  const base = window.kind === 'session'
184
245
  ? t('usageSession')
185
- : window.kind === 'weekly' ? t('usageWeekly') : t('usageWindow');
186
- return window.scope !== undefined && window.scope !== '' ? `${base} · ${window.scope}` : base;
246
+ : window.kind === 'weekly'
247
+ ? t('usageWeekly')
248
+ : t('usageWindow');
249
+ return window.scope !== undefined && window.scope !== ''
250
+ ? `${base} · ${window.scope}`
251
+ : base;
187
252
  }
188
253
  /** Meter fill color lives with the pace logic: fresh 90%+ is red, pace presets add a yellow lead threshold. */
189
254
  export { usageBarColor } from './usage-pace.js';
@@ -198,7 +263,11 @@ export function SubscriptionsSection(props) {
198
263
  const [statuses, setStatuses] = useState({});
199
264
  const [errors, setErrors] = useState({});
200
265
  const [manualDrafts, setManualDrafts] = useState({
201
- codex: '', claude: '', grok: '', copilot: '', antigravity: '',
266
+ codex: '',
267
+ claude: '',
268
+ grok: '',
269
+ copilot: '',
270
+ antigravity: '',
202
271
  });
203
272
  /** Pending device-flow codes (copilot), shown while the attempt polls. */
204
273
  const [deviceCodes, setDeviceCodes] = useState({});
@@ -268,7 +337,8 @@ export function SubscriptionsSection(props) {
268
337
  return;
269
338
  setStatuses(response.providers);
270
339
  const signature = PROVIDERS.map(({ id }) => `${id}:${response.providers[id].accounts
271
- .map(account => `${account.key}:${account.isDefault}`).join(',')}`).join(';');
340
+ .map((account) => `${account.key}:${account.isDefault}`)
341
+ .join(',')}`).join(';');
272
342
  if (signature !== usageRosterSignatureRef.current) {
273
343
  usageRosterSignatureRef.current = signature;
274
344
  window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
@@ -294,7 +364,9 @@ export function SubscriptionsSection(props) {
294
364
  const startPolling = useCallback((provider) => {
295
365
  if (pollersRef.current.has(provider))
296
366
  return;
297
- pollersRef.current.set(provider, setInterval(() => { void refresh(); }, POLL_INTERVAL_MS));
367
+ pollersRef.current.set(provider, setInterval(() => {
368
+ void refresh();
369
+ }, POLL_INTERVAL_MS));
298
370
  }, [refresh]);
299
371
  // Initial load; every busy provider (e.g. an attempt started before a page
300
372
  // reload) resumes polling. Teardown clears pollers and the mounted guard.
@@ -313,6 +385,9 @@ export function SubscriptionsSection(props) {
313
385
  });
314
386
  return () => {
315
387
  mountedRef.current = false;
388
+ // The ref holds pollers started after this effect began. Copying .current
389
+ // at setup would clear an empty set and leave those intervals running.
390
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- read the live set at unmount
316
391
  for (const poller of pollersRef.current.values())
317
392
  clearInterval(poller);
318
393
  pollersRef.current.clear();
@@ -336,13 +411,16 @@ export function SubscriptionsSection(props) {
336
411
  if (rpc === undefined || usageInflightRef.current.has(key))
337
412
  return;
338
413
  const read = (async () => {
339
- setUsageLoading(prev => ({ ...prev, [key]: true }));
414
+ setUsageLoading((prev) => ({ ...prev, [key]: true }));
340
415
  try {
341
- const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account, ...force ? { force: true } : {} });
416
+ const usage = await callSubscriptionsAuth(rpc, 'usage', { provider, account, ...(force ? { force: true } : {}) });
342
417
  if (!mountedRef.current)
343
418
  return;
344
- setUsages(prev => ({ ...prev, [key]: usage }));
345
- setObservedAt(prev => ({ ...prev, [key]: usage.observedAt ?? Date.now() }));
419
+ setUsages((prev) => ({ ...prev, [key]: usage }));
420
+ setObservedAt((prev) => ({
421
+ ...prev,
422
+ [key]: usage.observedAt ?? Date.now(),
423
+ }));
346
424
  window.dispatchEvent(new Event(USAGE_BADGE_REFRESH_EVENT));
347
425
  setUsageErrors((prev) => {
348
426
  const next = { ...prev };
@@ -352,12 +430,12 @@ export function SubscriptionsSection(props) {
352
430
  }
353
431
  catch (error) {
354
432
  if (mountedRef.current)
355
- setUsageErrors(prev => ({ ...prev, [key]: messageOf(error) }));
433
+ setUsageErrors((prev) => ({ ...prev, [key]: messageOf(error) }));
356
434
  }
357
435
  finally {
358
436
  usageInflightRef.current.delete(key);
359
437
  if (mountedRef.current)
360
- setUsageLoading(prev => ({ ...prev, [key]: false }));
438
+ setUsageLoading((prev) => ({ ...prev, [key]: false }));
361
439
  }
362
440
  })();
363
441
  usageInflightRef.current.set(key, read);
@@ -385,7 +463,10 @@ export function SubscriptionsSection(props) {
385
463
  }
386
464
  }
387
465
  async function consumeReset() {
388
- if (!rpc || !resetConfirmation || !resetAcknowledged || resetInflight.current)
466
+ if (!rpc ||
467
+ !resetConfirmation ||
468
+ !resetAcknowledged ||
469
+ resetInflight.current)
389
470
  return;
390
471
  const { account, ticket } = resetConfirmation;
391
472
  resetInflight.current = true;
@@ -417,8 +498,8 @@ export function SubscriptionsSection(props) {
417
498
  void loadUsage(id, account.key);
418
499
  }
419
500
  }
420
- setUsages(prev => dropStale(prev, live));
421
- setUsageErrors(prev => dropStale(prev, live));
501
+ setUsages((prev) => dropStale(prev, live));
502
+ setUsageErrors((prev) => dropStale(prev, live));
422
503
  }, [statuses, usages, usageErrors, loadUsage]);
423
504
  const login = useCallback(async (provider, method) => {
424
505
  if (rpc === undefined)
@@ -427,9 +508,10 @@ export function SubscriptionsSection(props) {
427
508
  try {
428
509
  const response = await callSubscriptionsAuth(rpc, 'login', {
429
510
  provider,
430
- ...method === undefined ? {} : { method },
511
+ ...(method === undefined ? {} : { method }),
431
512
  });
432
- if (typeof response.authorizeUrl === 'string' && response.authorizeUrl === '') {
513
+ if (typeof response.authorizeUrl === 'string' &&
514
+ response.authorizeUrl === '') {
433
515
  // Instant login (e.g. imported from Claude Code credentials)
434
516
  await refresh();
435
517
  return;
@@ -440,14 +522,25 @@ export function SubscriptionsSection(props) {
440
522
  if (!mountedRef.current)
441
523
  return;
442
524
  // Optimistic busy so Cancel and the manual fallback appear before the first poll tick.
443
- setStatuses(prev => ({
525
+ setStatuses((prev) => ({
444
526
  ...prev,
445
- [provider]: { accounts: prev[provider]?.accounts ?? [], ...prev[provider], busy: true },
527
+ [provider]: {
528
+ accounts: prev[provider]?.accounts ?? [],
529
+ ...prev[provider],
530
+ busy: true,
531
+ },
446
532
  }));
447
- if (typeof response.userCode === 'string' && response.userCode.length > 0) {
533
+ if (typeof response.userCode === 'string' &&
534
+ response.userCode.length > 0) {
448
535
  // Device flow: show the code card instead of opening the page blind —
449
536
  // the user copies the code first, then opens the verification page.
450
- setDeviceCodes(prev => ({ ...prev, [provider]: { userCode: response.userCode, verificationUrl: response.authorizeUrl } }));
537
+ setDeviceCodes((prev) => ({
538
+ ...prev,
539
+ [provider]: {
540
+ userCode: response.userCode,
541
+ verificationUrl: response.authorizeUrl,
542
+ },
543
+ }));
451
544
  }
452
545
  else {
453
546
  window.open(response.authorizeUrl, '_blank', 'noopener');
@@ -457,7 +550,7 @@ export function SubscriptionsSection(props) {
457
550
  catch (error) {
458
551
  setProviderError(provider, messageOf(error));
459
552
  }
460
- }, [rpc, t, setProviderError, startPolling]);
553
+ }, [rpc, t, setProviderError, startPolling, refresh]);
461
554
  const cancel = useCallback(async (provider) => {
462
555
  if (rpc === undefined)
463
556
  return;
@@ -478,9 +571,12 @@ export function SubscriptionsSection(props) {
478
571
  return;
479
572
  setProviderError(provider, undefined);
480
573
  try {
481
- await callSubscriptionsAuth(rpc, 'manual', { provider, input });
574
+ await callSubscriptionsAuth(rpc, 'manual', {
575
+ provider,
576
+ input,
577
+ });
482
578
  if (mountedRef.current)
483
- setManualDrafts(prev => ({ ...prev, [provider]: '' }));
579
+ setManualDrafts((prev) => ({ ...prev, [provider]: '' }));
484
580
  }
485
581
  catch (error) {
486
582
  setProviderError(provider, messageOf(error));
@@ -494,7 +590,10 @@ export function SubscriptionsSection(props) {
494
590
  return;
495
591
  setProviderError(provider, undefined);
496
592
  try {
497
- await callSubscriptionsAuth(rpc, 'logout', { provider, account });
593
+ await callSubscriptionsAuth(rpc, 'logout', {
594
+ provider,
595
+ account,
596
+ });
498
597
  }
499
598
  catch (error) {
500
599
  setProviderError(provider, messageOf(error));
@@ -506,7 +605,10 @@ export function SubscriptionsSection(props) {
506
605
  return;
507
606
  setProviderError(provider, undefined);
508
607
  try {
509
- await callSubscriptionsAuth(rpc, 'setDefault', { provider, account });
608
+ await callSubscriptionsAuth(rpc, 'setDefault', {
609
+ provider,
610
+ account,
611
+ });
510
612
  }
511
613
  catch (error) {
512
614
  setProviderError(provider, messageOf(error));
@@ -514,16 +616,19 @@ export function SubscriptionsSection(props) {
514
616
  await refresh();
515
617
  }, [rpc, setProviderError, refresh]);
516
618
  const copyDeviceCode = useCallback((provider, userCode) => {
517
- void navigator.clipboard?.writeText(userCode).then(() => {
619
+ void navigator.clipboard
620
+ ?.writeText(userCode)
621
+ .then(() => {
518
622
  if (!mountedRef.current)
519
623
  return;
520
624
  setCopiedCode(provider);
521
625
  setTimeout(() => {
522
626
  if (mountedRef.current) {
523
- setCopiedCode(current => current === provider ? undefined : current);
627
+ setCopiedCode((current) => current === provider ? undefined : current);
524
628
  }
525
629
  }, 1500);
526
- }).catch(() => undefined);
630
+ })
631
+ .catch(() => undefined);
527
632
  }, []);
528
633
  if (rpc === undefined) {
529
634
  return _jsx("p", { style: styles.intro, children: t('unavailable') });
@@ -533,34 +638,103 @@ export function SubscriptionsSection(props) {
533
638
  const busy = status?.busy === true;
534
639
  const deviceCode = deviceCodes[id];
535
640
  const accounts = status?.accounts ?? [];
536
- return (_jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("span", { style: { ...styles.dot, background: dotColor(status) } }), _jsx("span", { style: styles.name, children: name }), status?.clientVersion !== undefined && (_jsx("span", { style: styles.clientVersion, title: t('clientVersionHint'), children: clientVersionText(t, status.clientVersion) }))] }), _jsx("p", { style: styles.statusLine, children: statusText(t, status) }), status?.detail !== undefined && status.detail !== '' && (_jsx("p", { style: styles.statusLine, children: status.detail })), errors[id] !== undefined && _jsx("p", { style: styles.errorLine, children: errors[id] }), accounts.map((account) => {
641
+ return (_jsxs("div", { style: styles.card, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("span", { style: { ...styles.dot, background: dotColor(status) } }), _jsx("span", { style: styles.name, children: name }), status?.clientVersion !== undefined && (_jsx("span", { style: styles.clientVersion, title: t('clientVersionHint'), children: clientVersionText(t, status.clientVersion) }))] }), _jsx("p", { style: styles.statusLine, children: statusText(t, status) }), status?.detail !== undefined && status.detail !== '' && (_jsx("p", { style: styles.statusLine, children: status.detail })), errors[id] !== undefined && (_jsx("p", { style: styles.errorLine, children: errors[id] })), accounts.map((account) => {
537
642
  const usageKey = `${id}:${account.key}`;
538
643
  const usage = usages[usageKey];
539
644
  const usageError = usageErrors[usageKey];
540
645
  const display = account.account ?? account.key;
541
646
  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';
647
+ const nextReset = sortedCredits.find((c) => c.expiresAt === undefined || c.expiresAt > Date.now());
648
+ const resetBlock = usage
649
+ ? resetActionBlock(usage)
650
+ : 'resetUseRefresh';
544
651
  const resetDisabled = resetBusy || resetBlock !== undefined;
545
652
  // Providers without a usage endpoint answer supported:false — no block.
546
- const showUsage = usage?.supported !== false
547
- && (usage !== undefined || usageError !== undefined || usageLoading[usageKey] === true);
653
+ const showUsage = usage?.supported !== false &&
654
+ (usage !== undefined ||
655
+ usageError !== undefined ||
656
+ usageLoading[usageKey] === true);
548
657
  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: () => {
549
658
  if (!account.isDefault)
550
659
  void setDefault(id, account.key);
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) => {
660
+ }, 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', {
661
+ date: new Date(account.expiresAt).toLocaleString(),
662
+ }) })), _jsx("button", { type: "button", style: { marginLeft: 'auto', flexShrink: 0 }, onClick: () => {
663
+ void logout(id, account.key, display, name);
664
+ }, 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: () => {
665
+ void loadUsage(id, account.key, true);
666
+ }, 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 &&
667
+ usage.windows.length === 0 && (_jsx("p", { style: styles.statusLine, children: t('usageEmpty') })), (usage?.windows ?? []).map((window, index) => {
552
668
  const percent = displayUsedPercent(window.usedPercent);
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
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));
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') })] })] }) })] }));
669
+ return (_jsxs("div", { style: styles.usageRow, children: [_jsxs("div", { style: styles.usageMeta, children: [_jsx("span", { children: usageWindowLabel(t, window) }), _jsxs("span", { children: [percent === undefined
670
+ ? t('usageMeterInvalid')
671
+ : `${percent}%`, window.resetsAt !== undefined &&
672
+ ` · ${t('usageResets', { date: new Date(window.resetsAt).toLocaleString() })}`] })] }), _jsx(UsageMeter, { window: window, t: t, observedAt: observedAt[usageKey], stale: usageError !== undefined || usage.stale === true })] }, index));
673
+ }), (id === 'codex' || id === 'claude') &&
674
+ usage?.resetCreditsError !== undefined && (_jsx(ResetCreditsErrorLine, { provider: id, message: usage.resetCreditsError, t: t })), (id === 'codex' || id === 'claude') &&
675
+ showsResetCredits(id, usage?.resetCredits) && (_jsx(ResetCreditsDisclosure, { mode: id === 'claude' ? 'grants' : 'credits', credits: sortedCredits, t: t, ...(nextReset !== undefined
676
+ ? { nextCredit: nextReset }
677
+ : {}), ...(id === 'codex'
678
+ ? {
679
+ useAction: {
680
+ accountKey: account.key,
681
+ busy: resetBusy && resetAccount === account.key,
682
+ disabled: resetDisabled,
683
+ title: t(resetBusy
684
+ ? 'resetUseChecking'
685
+ : (resetBlock ?? 'resetUseReady')),
686
+ label: t('resetUseButton'),
687
+ onUse: () => {
688
+ if (!resetDisabled)
689
+ void prepareReset(account.key);
690
+ },
691
+ },
692
+ }
693
+ : {}), ...(resetAccount === account.key &&
694
+ resetMessage !== ''
695
+ ? { statusMessage: resetMessage }
696
+ : {}) }))] }))] }, account.key));
697
+ }), _jsxs("div", { style: styles.actions, children: [!busy && accounts.length === 0 && (_jsx("button", { type: "button", onClick: () => {
698
+ void login(id);
699
+ }, children: t('login') })), !busy && accounts.length > 0 && id === 'claude' && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => {
700
+ void login(id, 'oauth');
701
+ }, children: t('addAccountOAuth') }), _jsx("button", { type: "button", onClick: () => {
702
+ void login(id, 'keychain');
703
+ }, children: t('addAccountKeychain') })] })), !busy && accounts.length > 0 && id !== 'claude' && (_jsx("button", { type: "button", onClick: () => {
704
+ void login(id);
705
+ }, children: t('addAccount') })), _jsx("button", { type: "button", "aria-haspopup": "dialog", onClick: () => setManagedProvider({ id, name }), children: t('accountsManage') }), busy && (_jsx("button", { type: "button", onClick: () => {
706
+ void cancel(id);
707
+ }, 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: () => {
708
+ copyDeviceCode(id, deviceCode.userCode);
709
+ }, children: copiedCode === id
710
+ ? t('deviceCodeCopied')
711
+ : t('deviceCodeCopy') }), _jsx("button", { type: "button", onClick: () => {
712
+ window.open(deviceCode.verificationUrl, '_blank', 'noopener');
713
+ }, 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) => ({
714
+ ...prev,
715
+ [id]: event.target.value,
716
+ })) }), _jsx("button", { type: "button", onClick: () => {
717
+ void submitManual(id);
718
+ }, children: t('submit') })] })] }))] }, id));
719
+ }), _jsx(CursorCard, { rpc: rpc, t: t }), _jsx(OllamaCard, { 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: {
720
+ ...styles.modal,
721
+ display: resetConfirmation ? 'flex' : 'none',
722
+ margin: 'auto',
723
+ color: 'var(--dsw-alias-label-primary)',
724
+ }, 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
725
+ ? t('resetCreditExpiryUnknown')
726
+ : t('resetCreditExpires', {
727
+ date: new Date(resetConfirmation.creditExpiresAt).toLocaleString(),
728
+ }) }) }), _jsx("p", { style: { ...styles.statusLine, margin: '4px 0' }, children: t('resetUseWarning') }), _jsxs("label", { style: {
729
+ display: 'flex',
730
+ gap: 8,
731
+ alignItems: 'flex-start',
732
+ fontSize: 12,
733
+ }, children: [_jsx("input", { type: "checkbox", checked: resetAcknowledged, onChange: (e) => setResetAcknowledged(e.target.checked) }), t('resetUseAcknowledge')] }), _jsxs("div", { className: "dsh-subscription-dialog-actions", style: {
734
+ ...styles.actions,
735
+ justifyContent: 'flex-end',
736
+ marginTop: 8,
737
+ }, 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: () => {
738
+ void consumeReset();
739
+ }, children: t('resetUseConfirm') })] })] })) })] }));
566
740
  }