@eddyskywalker/dsh-chatgpt-subscription 0.19.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/lib/client.js +366 -93
  3. package/lib/client.js.map +1 -1
  4. package/lib/index.js +525 -155
  5. package/lib/types/client/glm-coding-plan/GlmCodingPlanSection.d.ts.map +1 -1
  6. package/lib/types/client/minimax-code/MinimaxCodeSection.d.ts.map +1 -1
  7. package/lib/types/client/minimax-code/api.d.ts +30 -0
  8. package/lib/types/client/minimax-code/api.d.ts.map +1 -1
  9. package/lib/types/client/minimax-code/locales.d.ts +62 -2
  10. package/lib/types/client/minimax-code/locales.d.ts.map +1 -1
  11. package/lib/types/client/minimax-code/styles.d.ts.map +1 -1
  12. package/lib/types/client/minimax-code/useMinimaxCodeSection.d.ts +50 -1
  13. package/lib/types/client/minimax-code/useMinimaxCodeSection.d.ts.map +1 -1
  14. package/lib/types/host/antigravity/adapter.d.ts.map +1 -1
  15. package/lib/types/host/claude/adapter.d.ts.map +1 -1
  16. package/lib/types/host/command-code/adapter.d.ts.map +1 -1
  17. package/lib/types/host/common/idle-watchdog.d.ts +13 -1
  18. package/lib/types/host/common/idle-watchdog.d.ts.map +1 -1
  19. package/lib/types/host/glm-coding-plan/adapter.d.ts.map +1 -1
  20. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  21. package/lib/types/host/minimax-code/adapter.d.ts.map +1 -1
  22. package/lib/types/host/minimax-code/reset-card.d.ts +136 -0
  23. package/lib/types/host/minimax-code/reset-card.d.ts.map +1 -0
  24. package/lib/types/host/minimax-code/routes.d.ts.map +1 -1
  25. package/lib/types/host/ollama/adapter.d.ts.map +1 -1
  26. package/lib/types/host/ollama/client.d.ts +8 -1
  27. package/lib/types/host/ollama/client.d.ts.map +1 -1
  28. package/lib/types/host/responses-client.d.ts +11 -1
  29. package/lib/types/host/responses-client.d.ts.map +1 -1
  30. package/lib/types/host/workbuddy/adapter.d.ts.map +1 -1
  31. package/lib/types/index.d.ts +8 -0
  32. package/lib/types/index.d.ts.map +1 -1
  33. package/lib/types/shared/minimax-code-contracts.d.ts +35 -0
  34. package/lib/types/shared/minimax-code-contracts.d.ts.map +1 -1
  35. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,40 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.20.0 - 2026-10-12
6
+ - **[MiniMax Code] 新增「限额重置卡」:查看可用卡与近 30 天流水,选卡确认后重置套餐限额**
7
+ - **能力来源**:MiniMax 官方桌面端 v3.1.1(2026-10-04)起提供「限额重置」——订阅用户可在用量页查看可用重置卡与近 30 天获得/使用记录,**选择一张卡并确认后**重置对应限额。本插件复刻它,接同一组上游接口。
8
+ - **上游事实(用真实账号实测确证,非推测)**:`GET /backend/account/reset_card/list`(可用卡)、`GET /backend/account/reset_card/flows`(流水)、`POST /backend/account/reset_card/use`(消费)。主机是插件**已在用**的 `api.minimax.cn` / `api.minimaxi.com`(即 `QUOTA_HOST_CANDIDATES`),认证是**现有**的 `Authorization: Bearer`。不需要新主机、不需要签名头、不需要新认证方式。
9
+ - **三处踩过的坑,都写进了实现**:
10
+ - **`flows` 必带 `create_time`**(起始毫秒,取 30 天前),否则上游返回 `2013 invalid params`。这不是可选参数,是硬要求。
11
+ - **消费成功靠原样回传卡上的 `source_type` + `out_biz_no`,绝不自己生成 request id。** 服务端以 `out_biz_no` 去重;自造一个 id 等于递给服务端一个它没记录过的键,第二次点击就会**真的多消费一张卡**——正是本线路契约警告的那种伤害。
12
+ - **`outcome` 必须原样透传,不能塌缩成布尔值。** 六个值里 `REPLAYED` / `LOCK_BUSY` / `RETRYABLE_FAIL` 三个的含义是「可能已消费,请用**同一张卡**确认」,界面必须据此劝用户重试同一张卡而非换卡。官方客户端也是这么处理的。
13
+ - **幂等键不出浏览器**:`POST /reset-cards/use` 只接受 `{ cardId }`。host 侧先读一次面板,从**自己刚读到**的那份数据里查出该卡的 `source_type`/`out_biz_no` 再调上游——浏览器无法指定幂等键,也就无法消费一张它没读过的卡。同源检查照旧。
14
+ - **不确定态不刷新列表**:`LOCK_BUSY` / `RETRYABLE_FAIL` 之后**故意不重读面板、不刷新用量**,否则会把那一行「让用户用同一张卡重试」的提示直接从屏幕上刷掉。已决的四个 outcome 才刷新。
15
+ - **测试**:host 20 例 + 客户端 15 例,全部 mock fetch,**没有任何一次真实 `/use` 调用**。host 侧六组变异(删 `create_time`、自造 request id、不容忍 flows 失败、放行任意 outcome、只试首个主机、路由信任浏览器传来的 `out_biz_no`)各自被对应用例捕获;客户端侧四组变异(改错不确定态文案、删二次确认守卫、按钮不禁用、去掉使用后刷新)同样如期变红,恢复后全绿。
16
+ - **复审时独立重做变异**:只把 `out_biz_no` 换成自造值(一处改动),4 个用例立刻失败——含「重试必须用同一张卡」这条安全关键用例;恢复后 20/20。
17
+ - **验证:`npx tsc -b --force` 0 错误;`npx tsc -p test/tsconfig.json` 0 错误;全量 `npx vitest run` 215 passed | 1 skipped(216 文件)、3483 passed | 7 skipped | 0 failed。**
18
+ - **诚实声明:没有跑过真实消费。** 全部 `/use` 路径都是 mock 验收——真实消费会消耗用户真实的重置卡,本轮刻意不做。`list`/`flows` 的响应形状是用真实账号只读实测过的。
19
+ - **遗留项(既有问题,非本次引入)**:`QUOTA_HOST_CANDIDATES.global` 只有一个候选 `api.minimax.io`,而该主机对国区凭据返回 401。国际区账号的可用主机仍未实测——这与本线路既有的配额读取是同一个未解问题。
20
+
21
+ - **[九条线路] 空闲超时把「没有可展示内容」误判成「连接已死」,长时间思考或上游持续心跳时整轮被判 TIMEOUT**
22
+ - **问题(issue #52)**:流式线路的空闲看门狗只对「解析器 yield 出的 `StreamChunk`」复位。Codex 线路的 `wrapStreamWithWatchdog` 包在 `parseResponsesStream()` 外面,于是两类完全正常的流量会被判成 5 分钟静默:① 上游持续发 `response.in_progress` 这类状态帧——它们走完 mapper 后**不产出任何 chunk**;② reasoning summary 超过 12000 字符展示上限被截断后继续发送摘要——`visibleReasoningDelta()` 返回空文本,且不够 768 字符的 flush 水位。同一条误判存在于其余八条自建流的线路(antigravity / claude / command-code / minimax / glm / kimi / workbuddy / ollama),共九条。
23
+ - **修法:把计时判据从「展示层产出」下沉到「传输层收到数据」。** 共享 seam `wrapStreamWithWatchdog` 新增可选第二参数 `StreamActivity`(`pulse()`),内部接 `@deepseek-ai/dsh-timeout` 的 `idleWatchdog.pulse()`——它只在 `next()` 挂起期间重新计时,正是「读操作在等、字节在到」这个场景。因为 TypeScript 里参数更少的函数可以赋值给参数更多的签名,历史单参调用点继续编译通过,八条线路因此各自独立接线、互不阻塞。每条线路在**两处**上报:`reader.read()` 返回非空字节时一次,每个完整 SSE 帧一次。第二处刻意放在 `data:` 过滤**之前**,所以 `: ping` / `: keep-alive` 这类纯注释心跳(Codex 解析器原本在 `data === ''` 处整个丢掉)同样算活动。**摘要上限与展示缓冲逐字未动**:截断只影响展示,不再影响活动判定,也没有生成任何假的界面文字。
24
+ - **Codex 线路另加可配置超时**:插件 Config 新增 `codexStreamIdleTimeoutMs`,默认仍是 300000,`min(1)` 且上限 `MAX_TIMER_DELAY_MS`——**0 不是关闭开关**,这条线是截止时间不是功能开关。该常量与 `pulse()` 在 `@deepseek-ai/dsh-timeout` 里自 0.1.2-alpha.5 起就存在(已核对该 tag 的源码),所以没有新增跨代兼容 seam。
25
+ - **测试**:新增 5 个文件、8 条线路各一例,全部不 mock `idle-watchdog`(要观察的正是它本身不肯触发)。每条线路的用例都是同一个实验:假响应体连续发送纯注释心跳帧、撑过数倍于空闲窗口的时间且**期间不产生任何可展示 chunk**,最后正常收尾——修复后必须正常完成,修复前必然 `stream idle timeout`。另各配一条反向用例:真正一个字节都不发时仍然抛 `TIMEOUT`,证明反向用例不是空转。摘要截断那一条显式断言 block-end 的 reasoning 仍含 `Reasoning summary truncated` 且长度 < 12100,排除「靠去掉上限过关」这条路。
26
+ - **变异验证(复审时独立重做)**:只把共享 seam 里 `pulse` 的实现置空(一处改动,不动任何线路),8 条线路的 12 条用例**全部**以真实 TIMEOUT 失败,反向静默用例仍通过;恢复后全绿。子代理另各自做过一次「注释掉本线路 `activity?.pulse()`」的变异,结论一致。
27
+ - **验证:`npx tsc -b --force` 0 错误;`npx tsc -p test/tsconfig.json` 0 错误;全量 `npx vitest run` 213 passed | 1 skipped(214 文件)、3448 passed | 7 skipped | 0 failed。** 本轮未复现历史记录里的 Windows host 端口保留类失败。
28
+ - **诚实声明:本轮全部为 mock SSE 验收,没有真实 ChatGPT 订阅账号参与。** 心跳形态只实测了 SSE 注释帧;「合法但被 mapper 丢弃的 `data:` 状态帧」由代码路径推断同样会 pulse(pulse 挂在每一帧上),但未单独构造该形态实测。issue 里并列出现的 `NGHTTP2_INTERNAL_ERROR` 属于 HTTP/2 传输层异常,本报告不声称本次改动能解决它。
29
+
30
+
31
+ ## 0.19.1 - 2026-10-11
32
+ - **[GLM(ZCode 账号)] 账号管理一行的三个按钮排不下,第三个被挤到下一行**
33
+ - **问题**:「账号管理(已登录 N 个账号)」与右侧按钮区共用一行(`.dsha-grouphead` 是 `justify-content:space-between`),而按钮容器带 `flex-wrap:wrap`。标题占掉宽度后,三个按钮(添加国区账号 / 添加国际区账号 / 导入本机 ZCode 登录态)里第三个必然折行。WorkBuddy 与 Claude 都只有两个按钮,所以这条线路是**唯一**有三个的,问题也只在它身上显形。
34
+ - **修法:按「同类操作聚在一起」重排,而不是去调共享样式。** 两个「添加账号」留在标题行,第三个下移到下面的「登录授权」区。理由是它本来就是**另一条登录路径**——浏览器授权与读本机已有登录态是同一件事的两种做法,放在同一个区才读得出「怎么登录」;位置取状态提示之后、手工粘贴之前,既不打断「流程状态 → 结果」的阅读顺序,又与同为免浏览器路径的手工粘贴相邻。导入结果的提示一并跟着移,否则用户点了按钮却在远处看到结果。
35
+ - **一处必要的连带改动**:登录区原先整块包在 `login !== null` 的判断里。按钮移进来后会跟着这个判断一起消失——host 一次流程状态都不报时,用户就再也点不到「导入本机 ZCode 登录态」。因此把判断收窄到只包住状态块,标题、导入按钮、导入结果、手工粘贴四样常驻。真实 host 永远会报 `login`(`routes.ts` 的 `loginStatusOf(null)` 返回 `idle`,且每次 `/status` 都带上它),所以**线上画面不变**,这个改动只是堵掉「入口会消失」这个洞。
36
+ - **测试**:改写原先断言「三个按钮都在标题行」的那条用例——它验的正是被推翻的布局。新护栏断言标题行**恰好两个**按钮,且导入按钮落在登录区内。护栏做过变异验证:把第三个按钮塞回标题行,该用例立刻失败。另新增一条断言导入结果与按钮同区、可当场关闭。
37
+ - **验证:`npm run typecheck` 0 错误;全量 `npm test` 208 passed | 1 skipped(209 文件)、3430 passed | 7 skipped | 0 failed。**
38
+
5
39
  ## 0.19.0 - 2026-10-11
6
40
  - **[GLM(ZCode 账号)] 新增第九条 Provider 线路:用 ZCode 账号 OAuth 登录 GLM Coding Plan,国区与国际区两套部署各自独立**
7
41
  - **问题:GLM Coding Plan 此前只能以「粘贴 API Key」的形态接入,而公开的 OpenAI 兼容面根本不生效套餐额度。** 官方文档的 Common mistakes 段写明走通用面 `/api/paas/v4` 会变成按量计费——用户明明买了订阅,却在一条声称提供 GLM 的线路上看着余额被扣。要拿到真正吃套餐额度的端点,必须先有 Coding Plan Key,而 Key 又只能由 ZCode **账号**授权换出来。
package/lib/client.js CHANGED
@@ -6290,6 +6290,26 @@ window.__ModuleLoader__.load({
6290
6290
  function messageOf$1(cause) {
6291
6291
  return cause instanceof Error ? cause.message : String(cause);
6292
6292
  }
6293
+ /**
6294
+ * The reset-card panel: the cards still held, plus the recent flow.
6295
+ *
6296
+ * Goes through the shared reader, so a host half that is older than this one
6297
+ * produces the reader's "restart DSH" sentence rather than a bare parse crash.
6298
+ */
6299
+ function fetchResetCards() {
6300
+ return get$1("/reset-cards");
6301
+ }
6302
+ /**
6303
+ * Spend one card.
6304
+ *
6305
+ * The body carries the `cardId` and nothing else — deliberately. The card's
6306
+ * idempotency key is a field the service de-duplicates on, so letting the
6307
+ * browser supply one would let a client spend a card it never read. The host
6308
+ * looks the card up and sends the key it found.
6309
+ */
6310
+ function useResetCard(cardId) {
6311
+ return post$2("/reset-cards/use", { cardId });
6312
+ }
6293
6313
  //#endregion
6294
6314
  //#region src/client/minimax-code/locales.ts
6295
6315
  const NS_MINIMAX_CODE = "dsh-minimax-code";
@@ -6359,6 +6379,26 @@ window.__ModuleLoader__.load({
6359
6379
  quotaUsedShare: "已用 {percent}%",
6360
6380
  quotaRefresh: "刷新用量",
6361
6381
  quotaRefreshing: "刷新中...",
6382
+ resetSection: "限额重置",
6383
+ resetHint: "订阅附带的限额重置卡可以立即重置用量限额。请先选择一张卡,再确认消费。",
6384
+ resetConfirm: "请选择一张卡并确认消费。完成后会重新读取用量,不会自动重发对话。",
6385
+ resetAvailable: "可用重置卡 {count} 张",
6386
+ resetNone: "当前没有可用的重置卡。",
6387
+ resetUnavailable: "暂时读不到重置卡(未登录,或该账号没有这个功能)。",
6388
+ resetExpires: "到期 {time}",
6389
+ resetUse: "使用",
6390
+ resetUsing: "重置中…",
6391
+ resetRefresh: "刷新重置卡",
6392
+ resetRefreshing: "读取中…",
6393
+ resetFlowTitle: "近 30 天记录",
6394
+ resetFlowEmpty: "近 30 天没有重置卡记录。",
6395
+ resetFlowGrant: "获得",
6396
+ resetFlowUse: "已使用",
6397
+ resetOutcomeSuccess: "重置成功。",
6398
+ resetOutcomeReplayed: "该卡已使用,限额状态已更新。",
6399
+ resetOutcomeUncertain: "结果不确定,请用同一张卡重试确认,不会重复扣卡——换一张卡会真的多消费一张。",
6400
+ resetOutcomeExpired: "该卡已过期,无法用于重置;列表已刷新。",
6401
+ resetOutcomeNotFound: "该卡不存在或已不可用;列表已刷新。",
6362
6402
  composerLabel: "额度",
6363
6403
  selectAll: "全选",
6364
6404
  unselectAll: "全不选",
@@ -6449,6 +6489,26 @@ window.__ModuleLoader__.load({
6449
6489
  quotaUsedShare: "{percent}% used",
6450
6490
  quotaRefresh: "Refresh usage",
6451
6491
  quotaRefreshing: "Refreshing...",
6492
+ resetSection: "Quota reset",
6493
+ resetHint: "Reset cards included with the subscription reset a usage limit immediately. Pick one card, then confirm spending it.",
6494
+ resetConfirm: "Select a card and confirm spending it. Usage is re-read afterwards; no conversation is resent.",
6495
+ resetAvailable: "{count} reset card(s) available",
6496
+ resetNone: "No reset card is available right now.",
6497
+ resetUnavailable: "Reset cards are unreadable right now (not signed in, or this account does not have the feature).",
6498
+ resetExpires: "Expires {time}",
6499
+ resetUse: "Use",
6500
+ resetUsing: "Resetting…",
6501
+ resetRefresh: "Refresh cards",
6502
+ resetRefreshing: "Reading...",
6503
+ resetFlowTitle: "Last 30 days",
6504
+ resetFlowEmpty: "No reset-card activity in the last 30 days.",
6505
+ resetFlowGrant: "Granted",
6506
+ resetFlowUse: "Used",
6507
+ resetOutcomeSuccess: "Reset succeeded.",
6508
+ resetOutcomeReplayed: "That card was already used; the limit state has been updated.",
6509
+ resetOutcomeUncertain: "The result is uncertain. Retry with the SAME card to confirm — retrying does not spend a second card, switching to another one does.",
6510
+ resetOutcomeExpired: "That card has expired and cannot reset the limit; the list has been refreshed.",
6511
+ resetOutcomeNotFound: "That card does not exist or is no longer usable; the list has been refreshed.",
6452
6512
  composerLabel: "Quota",
6453
6513
  selectAll: "Select all",
6454
6514
  unselectAll: "Unselect all",
@@ -6536,6 +6596,51 @@ window.__ModuleLoader__.load({
6536
6596
  composerLabel: t("composerLabel")
6537
6597
  };
6538
6598
  }
6599
+ /**
6600
+ * One reset-card panel read, defensively shaped.
6601
+ *
6602
+ * The route is new and the card renders whatever it is handed, so a half that
6603
+ * answers something else (a stale host, a route that 404s into an error body the
6604
+ * reader already raised) must not turn into a render crash on `cards.length`.
6605
+ * A missing list is an empty list, which is also the truthful reading: the user
6606
+ * can select nothing and the use button stays disabled.
6607
+ */
6608
+ function normalizeResetCards(value) {
6609
+ return {
6610
+ cards: Array.isArray(value?.cards) ? value.cards : [],
6611
+ flows: Array.isArray(value?.flows) ? value.flows : [],
6612
+ fetchedAtMs: typeof value?.fetchedAtMs === "number" && Number.isFinite(value.fetchedAtMs) ? value.fetchedAtMs : 0
6613
+ };
6614
+ }
6615
+ /**
6616
+ * What the card tells the user after a spend, one sentence per outcome.
6617
+ *
6618
+ * The six outcomes are not six flavours of the same answer. Two are certain
6619
+ * ("done"), two are refusals (the card is gone — re-read the list), and two are
6620
+ * `I did not find out`: the service de-duplicates on the card's own key, so
6621
+ * retrying THE SAME card costs nothing while picking another one really does
6622
+ * spend a second card. That is why the uncertain sentence names the same card.
6623
+ */
6624
+ function resetOutcomeNotice(outcome, t) {
6625
+ switch (outcome) {
6626
+ case "SUCCESS": return t("resetOutcomeSuccess");
6627
+ case "REPLAYED": return t("resetOutcomeReplayed");
6628
+ case "LOCK_BUSY":
6629
+ case "RETRYABLE_FAIL": return t("resetOutcomeUncertain");
6630
+ case "EXPIRED": return t("resetOutcomeExpired");
6631
+ case "NOT_FOUND": return t("resetOutcomeNotFound");
6632
+ }
6633
+ }
6634
+ /**
6635
+ * Whether an outcome leaves the spent card's fate decided.
6636
+ *
6637
+ * True for the four outcomes that will not change if the user waits: the card is
6638
+ * consumed or it is not usable. False for the two uncertain ones — refreshing
6639
+ * there would drop the very row the sentence tells the user to retry with.
6640
+ */
6641
+ function outcomeIsDecided(outcome) {
6642
+ return outcome !== "LOCK_BUSY" && outcome !== "RETRYABLE_FAIL";
6643
+ }
6539
6644
  /** Device-code poll cadence. The host owns the real expiry. */
6540
6645
  const LOGIN_POLL_INTERVAL_MS$1 = 2e3;
6541
6646
  function useMinimaxCodeSection({ onModelChange }) {
@@ -6550,6 +6655,9 @@ window.__ModuleLoader__.load({
6550
6655
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
6551
6656
  const [savingModel, setSavingModel] = (0, react.useState)(null);
6552
6657
  const [pool, setPool] = (0, react.useState)(void 0);
6658
+ const [resetCards, setResetCards] = (0, react.useState)(null);
6659
+ const [resetNotice, setResetNotice] = (0, react.useState)(null);
6660
+ const [selectedResetCardId, setSelectedResetCardId] = (0, react.useState)(null);
6553
6661
  const quotaFollowUp = (0, react.useRef)(void 0);
6554
6662
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
6555
6663
  if (!quiet) setError(null);
@@ -6636,6 +6744,64 @@ window.__ModuleLoader__.load({
6636
6744
  } catch {}
6637
6745
  })();
6638
6746
  }, [authenticated, status?.quota]);
6747
+ /**
6748
+ * Read the reset-card panel.
6749
+ *
6750
+ * Silent on failure, exactly like the pool read: this feature is absent on
6751
+ * accounts that never earned a card, and a settings card must not raise an
6752
+ * error banner for a route that has nothing to say.
6753
+ */
6754
+ const loadResetCards = (0, react.useCallback)(async () => {
6755
+ try {
6756
+ setResetCards(normalizeResetCards(await fetchResetCards()));
6757
+ } catch {
6758
+ setResetCards(null);
6759
+ }
6760
+ }, []);
6761
+ /**
6762
+ * The panel is read once the card knows there is an account to read it for.
6763
+ *
6764
+ * Reads before sign-in answer with a refusal, which is not a state the user
6765
+ * can act on, so the read waits for a signed-in account exactly as the usage
6766
+ * read below does.
6767
+ */
6768
+ (0, react.useEffect)(() => {
6769
+ if (!authenticated) return;
6770
+ loadResetCards();
6771
+ }, [authenticated, loadResetCards]);
6772
+ const refreshResetCards = async () => {
6773
+ await loadResetCards();
6774
+ };
6775
+ const selectResetCard = (cardId) => {
6776
+ setSelectedResetCardId(cardId);
6777
+ };
6778
+ /**
6779
+ * Spend one card, behind the confirmation the official client asks for.
6780
+ *
6781
+ * The confirmation lives here rather than in the view because "cancel" must
6782
+ * mean no request at all: the card may not even be sent when the user says no.
6783
+ * After a decided outcome the panel is re-read so the spent card leaves the
6784
+ * list; after an uncertain one it is deliberately left alone, because the row
6785
+ * the user is told to retry with is the one that would disappear.
6786
+ */
6787
+ const spendResetCard = async (cardId) => {
6788
+ if (typeof window !== "undefined" && !window.confirm(t("resetConfirm"))) return;
6789
+ try {
6790
+ setBusy("reset-card");
6791
+ setError(null);
6792
+ const result = await useResetCard(cardId);
6793
+ setResetCards(normalizeResetCards(result.cards));
6794
+ setResetNotice(resetOutcomeNotice(result.outcome, t));
6795
+ setSelectedResetCardId(null);
6796
+ if (!outcomeIsDecided(result.outcome)) return;
6797
+ await loadResetCards();
6798
+ await refreshQuota();
6799
+ } catch (cause) {
6800
+ setError(messageOf$1(cause));
6801
+ } finally {
6802
+ setBusy(null);
6803
+ }
6804
+ };
6639
6805
  const login = async () => {
6640
6806
  try {
6641
6807
  setBusy("login");
@@ -6901,7 +7067,10 @@ window.__ModuleLoader__.load({
6901
7067
  connectionNotice,
6902
7068
  contextDrafts,
6903
7069
  savingModel,
6904
- pool
7070
+ pool,
7071
+ resetCards,
7072
+ resetNotice,
7073
+ selectedResetCardId
6905
7074
  },
6906
7075
  derived: {
6907
7076
  authenticated,
@@ -6910,6 +7079,8 @@ window.__ModuleLoader__.load({
6910
7079
  models,
6911
7080
  contextModels,
6912
7081
  overrideCount,
7082
+ resetCardList: resetCards?.cards ?? [],
7083
+ resetCardFlows: resetCards?.flows ?? [],
6913
7084
  poolLabels: accountPoolLabelsFor$1(t)
6914
7085
  },
6915
7086
  actions: {
@@ -6928,6 +7099,9 @@ window.__ModuleLoader__.load({
6928
7099
  resetContextWindow,
6929
7100
  resetAllContextWindows,
6930
7101
  refreshQuota,
7102
+ refreshResetCards,
7103
+ selectResetCard,
7104
+ useResetCard: spendResetCard,
6931
7105
  testConnection,
6932
7106
  updateContextDraft
6933
7107
  }
@@ -6964,9 +7138,9 @@ window.__ModuleLoader__.load({
6964
7138
  }
6965
7139
  function MinimaxCodeSection({ onModelChange }) {
6966
7140
  const { state, derived, actions } = useMinimaxCodeSection({ onModelChange });
6967
- const { status, loading, busy, error, flow, copied, connectionNotice, contextDrafts, savingModel, pool } = state;
6968
- const { authenticated, account, quota, models, contextModels, overrideCount, poolLabels } = derived;
6969
- const { login, cancelLogin, copyCode, logout, poolAction, setStrategy, toggleModel, setAllModels, setCheckinEnabled, runCheckinNow, updateEffort, saveContextWindow, resetContextWindow, resetAllContextWindows, refreshQuota, testConnection, updateContextDraft } = actions;
7141
+ const { status, loading, busy, error, flow, copied, connectionNotice, contextDrafts, savingModel, pool, resetCards, resetNotice, selectedResetCardId } = state;
7142
+ const { authenticated, account, quota, models, contextModels, overrideCount, poolLabels, resetCardList, resetCardFlows } = derived;
7143
+ const { login, cancelLogin, copyCode, logout, poolAction, setStrategy, toggleModel, setAllModels, setCheckinEnabled, runCheckinNow, updateEffort, saveContextWindow, resetContextWindow, resetAllContextWindows, refreshQuota, refreshResetCards, selectResetCard, useResetCard, testConnection, updateContextDraft } = actions;
6970
7144
  const t = fallbackTranslate$1;
6971
7145
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6972
7146
  className: "dsha-page",
@@ -7350,6 +7524,98 @@ window.__ModuleLoader__.load({
7350
7524
  })
7351
7525
  ]
7352
7526
  }),
7527
+ resetCards !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
7528
+ className: "dsha-group",
7529
+ children: [
7530
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7531
+ className: "dsha-grouphead",
7532
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("resetSection") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7533
+ className: "dsha-btn",
7534
+ disabled: busy !== null,
7535
+ onClick: () => void refreshResetCards(),
7536
+ children: busy === "reset-card" ? t("resetRefreshing") : t("resetRefresh")
7537
+ })]
7538
+ }),
7539
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7540
+ className: "dsha-muted",
7541
+ children: t("resetHint")
7542
+ }),
7543
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7544
+ className: "dsha-row",
7545
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7546
+ className: "dsha-label",
7547
+ children: t("resetAvailable").replace("{count}", String(resetCardList.length))
7548
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7549
+ className: "dsha-value",
7550
+ children: formatDate(resetCards.fetchedAtMs)
7551
+ })]
7552
+ }),
7553
+ resetCardList.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7554
+ className: "dsha-empty",
7555
+ children: t("resetNone")
7556
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7557
+ className: "dshm-reset-list",
7558
+ children: resetCardList.map((card) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7559
+ className: "dsha-row dshm-reset-row",
7560
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7561
+ type: "button",
7562
+ className: "dsha-btn dshm-reset-pick",
7563
+ "aria-pressed": selectedResetCardId === card.cardId,
7564
+ disabled: busy !== null,
7565
+ onClick: () => selectResetCard(selectedResetCardId === card.cardId ? null : card.cardId),
7566
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7567
+ className: "dshm-mono",
7568
+ children: card.cardId
7569
+ })
7570
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7571
+ className: "dsha-value",
7572
+ children: t("resetExpires").replace("{time}", formatDate(card.expiresAtMs))
7573
+ })]
7574
+ }, card.cardId))
7575
+ }),
7576
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7577
+ className: "dsha-notice dshm-quota-note",
7578
+ children: t("resetConfirm")
7579
+ }),
7580
+ resetNotice !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7581
+ className: "dsha-notice dshm-quota-note",
7582
+ role: "status",
7583
+ children: resetNotice
7584
+ }),
7585
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7586
+ className: "dsha-actions",
7587
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
7588
+ className: "dsha-btn dsha-btn-primary",
7589
+ disabled: busy !== null || selectedResetCardId === null,
7590
+ onClick: () => {
7591
+ if (selectedResetCardId !== null) useResetCard(selectedResetCardId);
7592
+ },
7593
+ children: busy === "reset-card" ? t("resetUsing") : t("resetUse")
7594
+ })
7595
+ }),
7596
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
7597
+ className: "dsha-muted dshm-quota-note",
7598
+ children: t("resetFlowTitle")
7599
+ }),
7600
+ resetCardFlows.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7601
+ className: "dsha-empty",
7602
+ children: t("resetFlowEmpty")
7603
+ }) : resetCardFlows.map((entry, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
7604
+ className: "dsha-row",
7605
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
7606
+ className: "dsha-label",
7607
+ children: entry.eventType === "GRANT" ? t("resetFlowGrant") : t("resetFlowUse")
7608
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
7609
+ className: "dsha-value dshm-mono",
7610
+ children: [
7611
+ entry.cardId,
7612
+ " · ",
7613
+ formatDate(entry.createdAtMs)
7614
+ ]
7615
+ })]
7616
+ }, `${entry.cardId}:${entry.createdAtMs}:${index}`))
7617
+ ]
7618
+ }),
7353
7619
  error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
7354
7620
  className: "dsha-error",
7355
7621
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: error })
@@ -8111,7 +8377,7 @@ window.__ModuleLoader__.load({
8111
8377
  })]
8112
8378
  })]
8113
8379
  }),
8114
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
8380
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountPoolSection, {
8115
8381
  accounts,
8116
8382
  activeAccountId: status?.activeAccountId,
8117
8383
  rotationStrategy: status?.rotationStrategy ?? "sequential",
@@ -8126,26 +8392,17 @@ window.__ModuleLoader__.load({
8126
8392
  onSetStrategy: (strategy) => void setStrategy(strategy),
8127
8393
  renderLoginActions: () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8128
8394
  className: "dsha-account-add-actions",
8129
- children: [
8130
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8131
- className: "dsha-btn dsha-btn-primary",
8132
- disabled: busy !== null,
8133
- onClick: () => void startLogin("cn"),
8134
- children: busy === "login:cn" ? t.authorizing : t.addCnAccount
8135
- }),
8136
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8137
- className: "dsha-btn dsha-btn-primary",
8138
- disabled: busy !== null,
8139
- onClick: () => void startLogin("intl"),
8140
- children: busy === "login:intl" ? t.authorizing : t.addIntlAccount
8141
- }),
8142
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8143
- className: "dsha-btn",
8144
- disabled: busy !== null,
8145
- onClick: () => void adopt(),
8146
- children: busy === "adopt" ? t.adopting : t.adopt
8147
- })
8148
- ]
8395
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8396
+ className: "dsha-btn dsha-btn-primary",
8397
+ disabled: busy !== null,
8398
+ onClick: () => void startLogin("cn"),
8399
+ children: busy === "login:cn" ? t.authorizing : t.addCnAccount
8400
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8401
+ className: "dsha-btn dsha-btn-primary",
8402
+ disabled: busy !== null,
8403
+ onClick: () => void startLogin("intl"),
8404
+ children: busy === "login:intl" ? t.authorizing : t.addIntlAccount
8405
+ })]
8149
8406
  }),
8150
8407
  renderDetails: (account) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8151
8408
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
@@ -8160,82 +8417,105 @@ window.__ModuleLoader__.load({
8160
8417
  children: account.organizationId
8161
8418
  }) : null
8162
8419
  ] }),
8163
- children: [login !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8420
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8164
8421
  className: "dshglm-flow",
8165
8422
  children: [
8166
8423
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.loginSection }),
8167
- login.status === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8168
- className: "dsha-muted",
8169
- children: t.loginIdle
8170
- }),
8171
- login.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8172
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8424
+ login !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8425
+ login.status === "idle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8173
8426
  className: "dsha-muted",
8174
- children: t.loginPending
8427
+ children: t.loginIdle
8175
8428
  }),
8176
- login.authorizeUrl !== void 0 && login.authorizeUrl !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8177
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8178
- className: "dsha-label",
8179
- children: t.authorizeUrl
8180
- }),
8181
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
8182
- className: "dshglm-flow-url",
8183
- children: login.authorizeUrl
8429
+ login.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8430
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8431
+ className: "dsha-muted",
8432
+ children: t.loginPending
8184
8433
  }),
8185
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8186
- className: "dsha-actions",
8187
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
8188
- className: "dsha-btn",
8189
- href: login.authorizeUrl,
8190
- target: "_blank",
8191
- rel: "noreferrer noopener",
8192
- children: t.openAuthorizeUrl
8434
+ login.authorizeUrl !== void 0 && login.authorizeUrl !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
8435
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8436
+ className: "dsha-label",
8437
+ children: t.authorizeUrl
8438
+ }),
8439
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
8440
+ className: "dshglm-flow-url",
8441
+ children: login.authorizeUrl
8442
+ }),
8443
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8444
+ className: "dsha-actions",
8445
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
8446
+ className: "dsha-btn",
8447
+ href: login.authorizeUrl,
8448
+ target: "_blank",
8449
+ rel: "noreferrer noopener",
8450
+ children: t.openAuthorizeUrl
8451
+ })
8193
8452
  })
8453
+ ] }),
8454
+ login.progress !== void 0 && login.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8455
+ className: "dsha-row",
8456
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8457
+ className: "dsha-label",
8458
+ children: t.progress
8459
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8460
+ className: "dsha-value",
8461
+ children: login.progress
8462
+ })]
8463
+ }),
8464
+ login.pollIntervalSec !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8465
+ className: "dsha-muted",
8466
+ children: t.pollEvery.replace("{seconds}", String(login.pollIntervalSec))
8467
+ }),
8468
+ login.expiresAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8469
+ className: "dsha-muted",
8470
+ children: t.loginExpiresAt.replace("{time}", formatDate(login.expiresAt))
8194
8471
  })
8195
8472
  ] }),
8196
- login.progress !== void 0 && login.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8197
- className: "dsha-row",
8198
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8199
- className: "dsha-label",
8200
- children: t.progress
8201
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8202
- className: "dsha-value",
8203
- children: login.progress
8204
- })]
8205
- }),
8206
- login.pollIntervalSec !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8473
+ login.status === "complete" && !authenticated && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8207
8474
  className: "dsha-muted",
8208
- children: t.pollEvery.replace("{seconds}", String(login.pollIntervalSec))
8475
+ children: t.loginCompleteNoAccount
8209
8476
  }),
8210
- login.expiresAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8477
+ login.status === "complete" && authenticated && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
8478
+ className: "dsha-notice",
8479
+ children: [t.loginComplete, login.email !== void 0 && login.email !== "" ? ` ${login.email}` : ""]
8480
+ }), login.completedAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8211
8481
  className: "dsha-muted",
8212
- children: t.loginExpiresAt.replace("{time}", formatDate(login.expiresAt))
8482
+ children: t.loginCompletedAt.replace("{time}", formatDate(login.completedAt))
8483
+ })] }),
8484
+ login.status === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8485
+ className: "dsha-error",
8486
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: login.error !== void 0 && login.error !== "" ? `${t.loginError} ${login.error}` : t.loginError }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: login.retryable === true ? t.loginRetryable : t.loginNotRetryable })]
8487
+ }),
8488
+ login.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8489
+ className: "dsha-actions",
8490
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8491
+ className: "dsha-btn",
8492
+ disabled: busy !== null,
8493
+ onClick: () => void cancelLogin(),
8494
+ children: busy === "login:cancel" ? t.cancelLoginBusy : t.cancelLogin
8495
+ })
8213
8496
  })
8214
8497
  ] }),
8215
- login.status === "complete" && !authenticated && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8216
- className: "dsha-muted",
8217
- children: t.loginCompleteNoAccount
8218
- }),
8219
- login.status === "complete" && authenticated && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
8220
- className: "dsha-notice",
8221
- children: [t.loginComplete, login.email !== void 0 && login.email !== "" ? ` ${login.email}` : ""]
8222
- }), login.completedAt !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
8223
- className: "dsha-muted",
8224
- children: t.loginCompletedAt.replace("{time}", formatDate(login.completedAt))
8225
- })] }),
8226
- login.status === "error" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8227
- className: "dsha-error",
8228
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: login.error !== void 0 && login.error !== "" ? `${t.loginError} ${login.error}` : t.loginError }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: login.retryable === true ? t.loginRetryable : t.loginNotRetryable })]
8229
- }),
8230
- login.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8498
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
8231
8499
  className: "dsha-actions",
8232
8500
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8233
8501
  className: "dsha-btn",
8234
8502
  disabled: busy !== null,
8235
- onClick: () => void cancelLogin(),
8236
- children: busy === "login:cancel" ? t.cancelLoginBusy : t.cancelLogin
8503
+ onClick: () => void adopt(),
8504
+ children: busy === "adopt" ? t.adopting : t.adopt
8237
8505
  })
8238
8506
  }),
8507
+ adoptResult !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8508
+ className: "dsha-row",
8509
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8510
+ className: "dsha-value",
8511
+ children: adoptResult.adopted ? t.adoptAdopted.replace("{region}", regionLabel(adoptResult.region ?? region)) : adoptResult.reason === void 0 ? t.adoptNoAttempt : `${adoptReasonText(adoptResult.reason, t)} ${t.adoptFallback}`
8512
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8513
+ className: "dsha-btn",
8514
+ disabled: busy !== null,
8515
+ onClick: clearAdoptResult,
8516
+ children: t.dismiss
8517
+ })]
8518
+ }),
8239
8519
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8240
8520
  className: "dshglm-paste",
8241
8521
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
@@ -8273,18 +8553,7 @@ window.__ModuleLoader__.load({
8273
8553
  })]
8274
8554
  })
8275
8555
  ]
8276
- }), adoptResult !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
8277
- className: "dsha-row",
8278
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8279
- className: "dsha-value",
8280
- children: adoptResult.adopted ? t.adoptAdopted.replace("{region}", regionLabel(adoptResult.region ?? region)) : adoptResult.reason === void 0 ? t.adoptNoAttempt : `${adoptReasonText(adoptResult.reason, t)} ${t.adoptFallback}`
8281
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
8282
- className: "dsha-btn",
8283
- disabled: busy !== null,
8284
- onClick: clearAdoptResult,
8285
- children: t.dismiss
8286
- })]
8287
- })]
8556
+ })
8288
8557
  }),
8289
8558
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
8290
8559
  className: "dsha-group",
@@ -11774,6 +12043,10 @@ window.__ModuleLoader__.load({
11774
12043
  .dshm-model-list{display:flex;flex-wrap:wrap;gap:7px;padding-top:8px}
11775
12044
  .dshm-model-list code{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:5px 8px;white-space:nowrap}
11776
12045
  .dshm-quota-note{margin-top:12px}
12046
+ .dshm-reset-list{display:flex;flex-direction:column;gap:6px;padding-top:8px}
12047
+ .dshm-reset-row{align-items:center;justify-content:space-between}
12048
+ .dshm-reset-pick{background:none;border:0.5px solid var(--dsw-alias-border-l2);cursor:pointer;padding:4px 8px}
12049
+ .dshm-reset-pick[aria-pressed="true"]{border-color:var(--dsw-alias-border-focus,var(--dsw-alias-border-l3));background:var(--dsw-alias-bg-layer-2)}
11777
12050
  `, STYLE_ID$2);
11778
12051
  }
11779
12052
  //#endregion