dsh-connect-trae 3.4.2 → 3.4.3

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 (3) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/lib/client.js +618 -494
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,61 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.4.3 (2026-10-13)
4
+
5
+ > **保存模型列表时终于有了「正在进行」的反馈。** 本版对齐同族 `dsh-connect-workbuddy` 4.4.2
6
+ > 对忙碌遮罩做的修正(该处修的是同族共有的缺陷),并把当初核实过的依据一并带过来。
7
+
8
+ ### 新增
9
+
10
+ - **保存 / 写设置时有一层忙碌遮罩**(新增 `src/client/BusyOverlay.tsx`,共用组件):
11
+ - **此前完全没有。** 保存状态只表现为控件变灰加按钮文案从「保存」变「保存中…」——
12
+ 用户盯着某个具体行等它落地时,屏幕上没有任何「正在进行」的迹象。
13
+ - 遮罩由卡片的**两条**写路径共同驱动:`saveModels` 的 `saving`(保存模型列表)与
14
+ `writePreference` 的 `savingSettings`(跟随登录 / 输入框读数两个开关)。
15
+ - 遮罩在该写路径的 `finally` 里随忙碌标记一起落下,也就是 **Host 重读落地的时刻**——
16
+ 延迟从「看不见」变成「看着它发生」。
17
+
18
+ ### 修复
19
+
20
+ - **遮罩的配色与动效改用宿主自己的令牌与节奏**(对齐同族 workbuddy 4.4.2):
21
+ - **遮罩卡片底色**若沿用同族的旧值 `--dsw-alias-bg-primary`,那个变量**在宿主令牌集里根本不存在**
22
+ (实测宿主 bundle 零命中;宿主只有 `bg-base` / `bg-layer-1..3` / `bg-module-platform` / `bg-overlay` 等),
23
+ 于是一路回退到写死的近黑 —— 卡片变成一块黑板子,上面的字看不清。现改用宿主给弹层用的
24
+ `--dsw-alias-bg-layer-2`,亮暗两套主题各自成立;阴影也从手写的 drop shadow 换成宿主的
25
+ `--dsw-elevation-prominent`。
26
+ - **遮罩底色**原写死 `rgba(0,0,0,.38)`,既不跟随主题、也没有宿主的模糊。改用宿主自己遮罩用的
27
+ `--dsw-alias-bg-mask-1`(亮 `.24` / 暗 `.5`)+ `--dsw-mask-blur`,与外壳里其他遮罩一致。
28
+ - **提示行**用 `label-secondary` —— 原先的 `label-tertiary` 是宿主最暗的一档
29
+ (亮 `neutral-bluish-600`、暗 `neutral-bluish-400`),给元数据用的,不该承载一句要等的人必须读的话。
30
+ - **spinner 换成宿主同款弧线**。此前那种 18px 的 CSS border 环、`.7s` 匀速转,比宿主自己的状态
31
+ 转圈(`_dsh-state-dot-spin`:SVG 弧线 + dash 呼吸、`1.5s`)快了近一倍 —— 比起形状本身,
32
+ **这个速度差才是它看着廉价的主因**。现按宿主 bundle 实测到的几何逐条对齐:
33
+ `viewBox 0 0 20 20`、`r=8`、`stroke-width 2`、track `opacity .25`、弧线 `stroke-dasharray 12 150`
34
+ 与 dash 呼吸、`1.5s`、`currentColor` 继承所在层级;reduced-motion 降级为**静态弧线**
35
+ (与宿主降级方式一致),并补 `aria-hidden`,免得 `role="status"` 之外多报一次。
36
+
37
+ ### 测试
38
+
39
+ - **+4**(`tests/card-styles.spec.tsx` 5 → 9,全仓 **594 → 598**):
40
+ - 遮罩选择器守卫:逐条钉住五个遮罩规则,且要求整条 `{` 结尾匹配,避免改名前缀后被子串误判为存在。
41
+ - 弧线节奏守卫:钉住 `dsm-trae-veil-dash` 关键帧与 reduced-motion 降级,防止退回到自绘 border 环。
42
+ - **渲染守卫(唯一能证明「遮罩真的出现」的断言)**:jsdom 不做层叠,前几条都只证明样式表里有这些
43
+ 名字。这条在 `scope.set` 挂起的条件下点「跟随 Trae 当前登录的账号」,断言遮罩确实进 DOM
44
+ (`role=status` / `aria-busy=true` / `aria-live=polite`)、文案为 `row.veilSaving`、弧线与卡片都在,
45
+ 写盘落地后卸载。
46
+ - 令牌白名单补三条(`--dsw-alias-bg-mask-1` / `--dsw-mask-blur` / `--dsw-elevation-prominent`),
47
+ 三者均经宿主 bundle 实测存在。白名单断言「大小必须等于实际用到的令牌数」,遮罩引入新令牌后必须同步补齐。
48
+ - 变异验证(各自变红后恢复):把 `.dsm-trae-veil{` 改成 `.dsm-trae-veilz{` → 仅选择器守卫变红;
49
+ 把 `visible={saving || savingSettings}` 改成 `visible={false}` → 仅渲染守卫变红。
50
+ - **一处诚实记录,不夸大守卫能力**:本仓库的 `vite/oxc` 与 `tsdown` 比 workbuddy 严格,模板字符串被
51
+ 反引号截断后会**直接报解析错误**(构建同样失败),所以「顶层语句数」那条截断守卫在本仓库
52
+ 不会比它们更早报警。真正拦不住截断的是 `tsc`(实测被截断的文件 `tsc` 仍 `exit 0`)——
53
+ 这正是同族当初能静默中招的原因。那条守卫作为「解析器不再拦时的兜底」保留。
54
+
55
+ ### 文档
56
+
57
+ - 无。本版只含上述新增、修复与配套测试。
58
+
3
59
  ## 3.4.2 (2026-10-13)
4
60
 
5
61
  > **插件现在与它自己解析到的那份 `@earendil-works/pi-ai` 代数对齐了**——这是 [issue #27](https://github.com/dingminhua/dsh-connect-trae/issues/27)
package/lib/client.js CHANGED
@@ -478,6 +478,51 @@ window.__ModuleLoader__.load({
478
478
  an error: it is Trae's one-per-device-per-day rule, and the day is simply
479
479
  spent. Rendering it in the error colour would read as a plugin fault. */
480
480
  .dsm-trae-checkin-note{margin:8px 0 0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#c6c9d0)}
481
+ /* The busy veil: one overlay for every account write whose result only lands
482
+ after the Host re-reads its settings document. Fixed so it covers the card
483
+ no matter which section started the operation, and translucent so the table
484
+ stays visible underneath — the user is watching a specific row change, and
485
+ hiding it would defeat the point.
486
+
487
+ The mask and card surface are the HOST's own tokens, not this file's
488
+ invention. --dsw-alias-bg-mask-1 + --dsw-mask-blur is exactly what the
489
+ host's own overlays use, so the veil dims the way every other overlay in the
490
+ shell does instead of laying its own black wash on top. A hardcoded flat
491
+ black mask (e.g. a mid-transparency black) was tuned against neither theme:
492
+ too weak next to the host's .24 mask in light mode, and it ignored the
493
+ host's blur entirely.
494
+
495
+ bg-layer-2 (not bg-primary, which does not exist in the host's token set at
496
+ all and therefore always fell through to this file's near-black #1b1c20) is
497
+ the same surface the host puts behind its panels — that near-black fallback
498
+ is what made the veil read as a black slab with unreadable text on it. */
499
+ .dsm-trae-veil{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.32));backdrop-filter:var(--dsw-mask-blur);cursor:progress}
500
+ /* --dsw-elevation-prominent is the host's own panel shadow (a hairline stroke
501
+ plus two soft layers); a hand-rolled drop shadow read as a heavy grey box. */
502
+ .dsm-trae-veil-card{display:flex;flex-direction:column;align-items:center;gap:8px;max-width:min(340px,80vw);padding:16px 20px;border:1px solid var(--dsw-alias-border-l2,#0000001a);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:var(--dsw-elevation-prominent,0 8px 28px rgba(0,0,0,.35))}
503
+ .dsm-trae-veil-text{font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#0f1115);text-align:center}
504
+ /* label-secondary, not label-tertiary: this line carries the operation's
505
+ detail and must stay legible. tertiary is the host's dimmest tier
506
+ (neutral-bluish-600 on light, neutral-bluish-400 on dark) and is meant for
507
+ metadata, not for a sentence the user has to read while waiting. */
508
+ .dsm-trae-veil-hint{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#61666b);text-align:center}
509
+ /* The spinner proves the UI is alive when the row under it has not changed yet
510
+ — which is precisely the confusion the veil exists to remove. It follows the
511
+ host's own state spinner (dsh's _dsh-state-dot-spin): an SVG arc whose dash
512
+ breathes while it turns, currentColor so it inherits the tier it sits in,
513
+ and the same 1.5s beat. The previous 18px border-ring at .7s was roughly
514
+ twice the host's speed and visibly out of step with every other spinner in
515
+ the shell — that mismatch, more than the shape itself, is what made it look
516
+ cheap.
517
+
518
+ Reduced-motion users get the static arc rather than a frozen ring, matching
519
+ how the host degrades its own spinner. */
520
+ .dsm-trae-veil-spinner{width:20px;height:20px;color:var(--dsw-alias-label-secondary,#61666b);animation:dsm-trae-veil-spin 1.5s linear infinite}
521
+ .dsm-trae-veil-spinner-track{opacity:.25}
522
+ .dsm-trae-veil-spinner-arc{stroke-dasharray:12 150;animation:dsm-trae-veil-dash 1.5s ease-in-out infinite}
523
+ @keyframes dsm-trae-veil-spin{to{transform:rotate(360deg)}}
524
+ @keyframes dsm-trae-veil-dash{0%{stroke-dasharray:12 150;stroke-dashoffset:0}50%{stroke-dasharray:24 150;stroke-dashoffset:-6}to{stroke-dasharray:12 150;stroke-dashoffset:0}}
525
+ @media (prefers-reduced-motion: reduce){.dsm-trae-veil-spinner{animation:none}.dsm-trae-veil-spinner-arc{animation:none;stroke-dasharray:18 150;stroke-dashoffset:-3}}
481
526
  `;
482
527
  /**
483
528
  * Composer-row readout styles, injected by the readout itself.
@@ -626,6 +671,76 @@ window.__ModuleLoader__.load({
626
671
  }
627
672
  .dsm-trae-expiry-detail{font-size:11px;line-height:16px;opacity:.85}
628
673
  `;
674
+ //#endregion
675
+ //#region src/client/BusyOverlay.tsx
676
+ /**
677
+ * The shared busy veil's spinner: an arc that breathes while it turns.
678
+ *
679
+ * Deliberately the host's own state-spinner shape (dsh's `_dsh-state-dot-spin`)
680
+ * rather than a border-ring: a two-tone CSS ring at .7s read as a loading
681
+ * indicator from another decade and was out of step with every spinner in the
682
+ * shell. The motion lives in CSS (`dsm-trae-veil-spin` / `-dash`), so this
683
+ * element only describes the geometry; `currentColor` lets it inherit whatever
684
+ * tier it sits in.
685
+ *
686
+ * `aria-hidden` because the veil's `role="status"` already announces the
687
+ * message — a second announcement from a decorative arc is noise.
688
+ */
689
+ function VeilSpinner() {
690
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
691
+ className: "dsm-trae-veil-spinner",
692
+ viewBox: "0 0 20 20",
693
+ "aria-hidden": "true",
694
+ focusable: "false",
695
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
696
+ className: "dsm-trae-veil-spinner-track",
697
+ cx: "10",
698
+ cy: "10",
699
+ r: "8",
700
+ fill: "none",
701
+ stroke: "currentColor",
702
+ strokeWidth: "2"
703
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
704
+ className: "dsm-trae-veil-spinner-arc",
705
+ cx: "10",
706
+ cy: "10",
707
+ r: "8",
708
+ fill: "none",
709
+ stroke: "currentColor",
710
+ strokeWidth: "2",
711
+ strokeLinecap: "round"
712
+ })]
713
+ });
714
+ }
715
+ /**
716
+ * The veil. Deliberately NOT a modal dialog: it carries no focusable control
717
+ * and no dismissal — there is nothing for the user to decide, only a step to
718
+ * wait through. `aria-busy` plus a polite live region state that to screen
719
+ * readers, which is the whole accessibility contract a wait screen needs.
720
+ */
721
+ function BusyOverlay({ message, hint, visible }) {
722
+ if (!visible) return null;
723
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
724
+ className: "dsm-trae-veil",
725
+ role: "status",
726
+ "aria-busy": "true",
727
+ "aria-live": "polite",
728
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
729
+ className: "dsm-trae-veil-card",
730
+ children: [
731
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(VeilSpinner, {}),
732
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
733
+ className: "dsm-trae-veil-text",
734
+ children: message
735
+ }),
736
+ hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
737
+ className: "dsm-trae-veil-hint",
738
+ children: hint
739
+ })
740
+ ]
741
+ })
742
+ });
743
+ }
629
744
  //#endregion
630
745
  //#region src/client/plan-text.ts
631
746
  /**
@@ -1706,539 +1821,546 @@ window.__ModuleLoader__.load({
1706
1821
  const label = status.status === "signed-in" ? t("row.signedIn", { accountName: status.accountName }) : status.status === "error" ? t("row.requestFailed") : t("row.signedOut");
1707
1822
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
1708
1823
  className: `dsm-plugin-card${open ? " dsm-plugin-card-open" : ""}`,
1709
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1710
- type: "button",
1711
- className: "dsm-plugin-card-header",
1712
- "aria-expanded": open,
1713
- "aria-label": `${t(open ? "row.collapse" : "row.expand")}: ${title}`,
1714
- onClick: () => {
1715
- setOpen(!open);
1716
- },
1717
- children: [
1718
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1719
- className: "dsm-plugin-card-icon",
1720
- src: TRAE_PLUGIN_ICON,
1721
- alt: ""
1722
- }),
1723
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1724
- className: "dsm-plugin-card-head",
1725
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1726
- className: "dsm-plugin-card-title",
1727
- children: title
1728
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1729
- className: "dsm-plugin-card-description",
1730
- children: t("row.desc")
1731
- })]
1732
- }),
1733
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1734
- "aria-hidden": "true",
1735
- className: `dsm-plugin-card-chevron${open ? " dsm-plugin-card-chevron-open" : ""}`
1736
- })
1737
- ]
1738
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1739
- className: "dsm-plugin-card-body",
1740
- hidden: !open,
1741
- children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1742
- className: "dsm-trae-usage",
1824
+ children: [
1825
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1826
+ type: "button",
1827
+ className: "dsm-plugin-card-header",
1828
+ "aria-expanded": open,
1829
+ "aria-label": `${t(open ? "row.collapse" : "row.expand")}: ${title}`,
1830
+ onClick: () => {
1831
+ setOpen(!open);
1832
+ },
1743
1833
  children: [
1744
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1745
- className: "dsm-trae-tabs",
1746
- role: "tablist",
1747
- "aria-label": title,
1748
- children: TRAE_REGIONS.map((item) => {
1749
- const regionStatus = statusByRegion[item];
1750
- const on = regionOn(item);
1751
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1752
- className: "dsm-trae-tab-cell",
1753
- role: "presentation",
1754
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1755
- type: "button",
1756
- role: "tab",
1757
- "aria-selected": item === activeRegion,
1758
- className: `dsm-trae-tab${item === activeRegion ? " dsm-trae-tab-active" : ""}${on ? "" : " dsm-trae-tab-off"}`,
1759
- onClick: () => {
1760
- setActiveRegion(item);
1761
- },
1762
- children: [regionStatus === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1763
- "aria-hidden": "true",
1764
- className: "dsm-trae-tab-dot",
1765
- style: dotStyle(regionStatus.status)
1766
- }), item === "cn" ? t("row.tabCn") : t("row.tabAi")]
1767
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1768
- className: "dsm-trae-switch dsm-trae-tab-switch",
1769
- title: t("row.tabSwitchHint"),
1770
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1771
- type: "checkbox",
1772
- checked: on,
1773
- disabled: settingsScope?.getSnapshot().writable !== true || togglingRegion !== void 0,
1774
- "aria-label": t("row.tabSwitchAria", { region: item === "cn" ? t("row.tabCn") : t("row.tabAi") }),
1775
- onChange: (event) => {
1776
- toggleRegion(item, event.currentTarget.checked);
1777
- }
1778
- })
1779
- })]
1780
- }, item);
1781
- })
1782
- }),
1783
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1784
- className: "dsm-trae-tab-hint",
1785
- children: t("row.tabHint")
1834
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
1835
+ className: "dsm-plugin-card-icon",
1836
+ src: TRAE_PLUGIN_ICON,
1837
+ alt: ""
1786
1838
  }),
1787
- writeError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1788
- className: "dsm-trae-usage-error",
1789
- role: "alert",
1790
- children: t("row.settingsWriteFailed", { message: writeError })
1791
- }),
1792
- regionOn(activeRegion) ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1793
- className: "dsm-trae-tab-off-notice",
1794
- role: "status",
1795
- children: t("row.tabOffNotice")
1796
- }),
1797
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1798
- className: "dsm-trae-prefs",
1799
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1800
- className: "dsm-trae-pref",
1801
- title: t("row.followAppLoginHint"),
1802
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1803
- type: "checkbox",
1804
- checked: settingsEdits.followAppLogin,
1805
- disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
1806
- "aria-describedby": followHintId,
1807
- onChange: (event) => {
1808
- writePreference("followAppLogin", event.currentTarget.checked);
1809
- }
1810
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1811
- id: followHintId,
1812
- children: [
1813
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
1814
- id: followLabelId,
1815
- children: t("row.followAppLogin")
1816
- }),
1817
- " ",
1818
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1819
- className: "dsm-trae-pref-hint",
1820
- children: t("row.followAppLoginHint")
1821
- })
1822
- ]
1823
- })]
1824
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1825
- className: "dsm-trae-pref",
1826
- title: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi"),
1827
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1828
- type: "checkbox",
1829
- checked: settingsEdits.showPointsInMainUi,
1830
- disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
1831
- "aria-describedby": creditsHintId,
1832
- onChange: (event) => {
1833
- writePreference("showPointsInMainUi", event.currentTarget.checked);
1834
- }
1835
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1836
- id: creditsHintId,
1837
- children: [
1838
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
1839
- id: creditsLabelId,
1840
- children: t("row.showPointsInMainUi")
1841
- }),
1842
- " ",
1843
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1844
- className: "dsm-trae-pref-hint",
1845
- children: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi")
1846
- })
1847
- ]
1848
- })]
1839
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1840
+ className: "dsm-plugin-card-head",
1841
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1842
+ className: "dsm-plugin-card-title",
1843
+ children: title
1844
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1845
+ className: "dsm-plugin-card-description",
1846
+ children: t("row.desc")
1849
1847
  })]
1850
1848
  }),
1851
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
1852
- className: "dsm-trae-accounts",
1853
- "aria-label": t("row.accountsTitle"),
1854
- children: [
1855
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1856
- className: "dsm-trae-accounts-head",
1857
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
1858
- className: "dsm-trae-accounts-title",
1859
- children: t("row.accountsTitle")
1860
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1861
- className: "dsm-trae-accounts-hint",
1862
- children: t("row.accountsHint")
1863
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1864
- type: "button",
1865
- className: "dsm-btn dsm-btn-outline",
1866
- disabled: busy,
1867
- onClick: () => {
1868
- rescanAccounts();
1869
- },
1870
- children: busy ? t("row.accountsScanning") : t("row.refreshTokens")
1871
- })]
1872
- }),
1873
- status.status !== "signed-in" || status.accounts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1874
- className: "dsm-trae-usage-account",
1875
- role: "status",
1876
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1877
- className: "dsm-trae-usage-account-copy",
1878
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1879
- className: "dsm-trae-usage-status",
1880
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1849
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1850
+ "aria-hidden": "true",
1851
+ className: `dsm-plugin-card-chevron${open ? " dsm-plugin-card-chevron-open" : ""}`
1852
+ })
1853
+ ]
1854
+ }),
1855
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1856
+ className: "dsm-plugin-card-body",
1857
+ hidden: !open,
1858
+ children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1859
+ className: "dsm-trae-usage",
1860
+ children: [
1861
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1862
+ className: "dsm-trae-tabs",
1863
+ role: "tablist",
1864
+ "aria-label": title,
1865
+ children: TRAE_REGIONS.map((item) => {
1866
+ const regionStatus = statusByRegion[item];
1867
+ const on = regionOn(item);
1868
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1869
+ className: "dsm-trae-tab-cell",
1870
+ role: "presentation",
1871
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
1872
+ type: "button",
1873
+ role: "tab",
1874
+ "aria-selected": item === activeRegion,
1875
+ className: `dsm-trae-tab${item === activeRegion ? " dsm-trae-tab-active" : ""}${on ? "" : " dsm-trae-tab-off"}`,
1876
+ onClick: () => {
1877
+ setActiveRegion(item);
1878
+ },
1879
+ children: [regionStatus === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1881
1880
  "aria-hidden": "true",
1882
- className: "dsm-trae-usage-dot",
1883
- style: dotStyle(status.status)
1884
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
1885
- }), status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1886
- className: "dsm-trae-usage-expiry",
1887
- children: t("row.tokenExpiry", { expiresAt: formatDateTime(status.tokenExpiresAtMs) })
1888
- }) : null]
1889
- })
1890
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1891
- className: `dsm-trae-account-table${activeRegion === "cn" ? " dsm-trae-account-table-checkin" : ""}`,
1892
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1893
- className: "dsm-trae-account-row dsm-trae-account-row-head",
1894
- role: "row",
1881
+ className: "dsm-trae-tab-dot",
1882
+ style: dotStyle(regionStatus.status)
1883
+ }), item === "cn" ? t("row.tabCn") : t("row.tabAi")]
1884
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
1885
+ className: "dsm-trae-switch dsm-trae-tab-switch",
1886
+ title: t("row.tabSwitchHint"),
1887
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1888
+ type: "checkbox",
1889
+ checked: on,
1890
+ disabled: settingsScope?.getSnapshot().writable !== true || togglingRegion !== void 0,
1891
+ "aria-label": t("row.tabSwitchAria", { region: item === "cn" ? t("row.tabCn") : t("row.tabAi") }),
1892
+ onChange: (event) => {
1893
+ toggleRegion(item, event.currentTarget.checked);
1894
+ }
1895
+ })
1896
+ })]
1897
+ }, item);
1898
+ })
1899
+ }),
1900
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1901
+ className: "dsm-trae-tab-hint",
1902
+ children: t("row.tabHint")
1903
+ }),
1904
+ writeError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1905
+ className: "dsm-trae-usage-error",
1906
+ role: "alert",
1907
+ children: t("row.settingsWriteFailed", { message: writeError })
1908
+ }),
1909
+ regionOn(activeRegion) ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1910
+ className: "dsm-trae-tab-off-notice",
1911
+ role: "status",
1912
+ children: t("row.tabOffNotice")
1913
+ }),
1914
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1915
+ className: "dsm-trae-prefs",
1916
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1917
+ className: "dsm-trae-pref",
1918
+ title: t("row.followAppLoginHint"),
1919
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1920
+ type: "checkbox",
1921
+ checked: settingsEdits.followAppLogin,
1922
+ disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
1923
+ "aria-describedby": followHintId,
1924
+ onChange: (event) => {
1925
+ writePreference("followAppLogin", event.currentTarget.checked);
1926
+ }
1927
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1928
+ id: followHintId,
1895
1929
  children: [
1896
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnAccount") }),
1897
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnValue") }),
1898
- activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnCheckin") }) : null,
1899
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})
1930
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
1931
+ id: followLabelId,
1932
+ children: t("row.followAppLogin")
1933
+ }),
1934
+ " ",
1935
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1936
+ className: "dsm-trae-pref-hint",
1937
+ children: t("row.followAppLoginHint")
1938
+ })
1900
1939
  ]
1901
- }), status.accounts.map((account) => {
1902
- const current = status.status === "signed-in" && account.id === status.accountId;
1903
- const state = accountStatusByRegion[activeRegion][account.id];
1904
- const error = claimErrorByRegion[activeRegion][account.id];
1905
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1906
- className: `dsm-trae-account-row${current ? " dsm-trae-account-row-current" : ""}`,
1907
- role: "row",
1908
- children: [
1909
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1910
- className: "dsm-trae-account-who",
1911
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1912
- "aria-hidden": "true",
1913
- className: "dsm-trae-usage-dot",
1914
- style: dotStyle(account.selected ? "signed-in" : "signed-out")
1915
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1916
- className: "dsm-trae-account-name",
1917
- children: [
1918
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: account.accountName }),
1919
- current ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1920
- className: "dsm-trae-account-badge",
1921
- children: t("row.accountCurrentBadge")
1922
- }) : null,
1923
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1924
- className: "dsm-trae-account-meta",
1925
- children: [
1926
- editionLabel(account.edition),
1927
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", {
1928
- "aria-hidden": "true",
1929
- children: "·"
1930
- }),
1931
- sourceLabel(account.source)
1932
- ]
1933
- }),
1934
- error === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1935
- className: "dsm-trae-account-note",
1936
- role: "alert",
1937
- children: t("row.checkinError", { message: error })
1938
- })
1939
- ]
1940
- })]
1941
- }),
1942
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1943
- className: "dsm-trae-account-worth",
1944
- children: rowValue(state)
1945
- }),
1946
- activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1947
- className: "dsm-trae-account-checkin-cell",
1948
- children: checkinControl(account, state)
1949
- }) : null,
1950
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1951
- className: "dsm-trae-account-actions",
1952
- children: current ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1953
- type: "button",
1954
- className: "dsm-btn dsm-btn-outline dsm-trae-account-switch",
1955
- disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
1956
- onClick: () => {
1957
- switchAccount(account.id);
1958
- },
1959
- children: switchingAccount ? t("row.accountSwitching") : t("row.accountSwitch")
1960
- })
1961
- })
1962
- ]
1963
- }, account.id);
1964
1940
  })]
1965
- }),
1966
- status.status === "signed-in" && status.alternatives !== void 0 && status.alternatives.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1967
- className: "dsm-trae-usage-alternative",
1968
- role: "status",
1969
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
1970
- className: "dsm-trae-usage-alternative-text",
1941
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
1942
+ className: "dsm-trae-pref",
1943
+ title: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi"),
1944
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1945
+ type: "checkbox",
1946
+ checked: settingsEdits.showPointsInMainUi,
1947
+ disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
1948
+ "aria-describedby": creditsHintId,
1949
+ onChange: (event) => {
1950
+ writePreference("showPointsInMainUi", event.currentTarget.checked);
1951
+ }
1952
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
1953
+ id: creditsHintId,
1971
1954
  children: [
1972
- t("row.creditsExhausted", { account: status.accountName }),
1955
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
1956
+ id: creditsLabelId,
1957
+ children: t("row.showPointsInMainUi")
1958
+ }),
1973
1959
  " ",
1974
- t("row.creditsAlternative", { accounts: status.alternatives.map((alt) => `${alt.accountName}(${t(`row.edition${alt.edition === "cn" ? "Cn" : alt.edition === "sg" ? "Sg" : alt.edition === "solo" ? "Solo" : "SoloSg"}`)}:${formatNumber(alt.workAvailable + alt.generalAvailable)})`).join("、") })
1960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1961
+ className: "dsm-trae-pref-hint",
1962
+ children: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi")
1963
+ })
1975
1964
  ]
1976
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1977
- type: "button",
1978
- className: "dsm-trae-usage-switch-button",
1979
- disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
1980
- onClick: () => {
1981
- const target = status.alternatives?.[0];
1982
- if (target !== void 0) switchAccount(target.id);
1983
- },
1984
- children: t("row.creditsAlternativeSwitch")
1985
1965
  })]
1986
- }) : null,
1987
- status.status === "signed-in" && status.credits?.expiry !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpiryNotice, {
1988
- expiry: status.credits.expiry,
1989
- t,
1990
- formatNumber,
1991
- formatDateTime
1992
- }) : null,
1993
- status.status === "signed-in" && status.appLogin !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1994
- className: "dsm-trae-usage-alternative",
1995
- role: "status",
1996
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1997
- className: "dsm-trae-usage-alternative-text",
1998
- children: t("row.appLoginMismatch", {
1999
- account: status.appLogin.accountName,
2000
- bound: status.accountName
2001
- })
2002
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2003
- type: "button",
2004
- className: "dsm-trae-usage-switch-button",
2005
- disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
2006
- onClick: () => {
2007
- followAppLogin();
2008
- },
2009
- children: t("row.appLoginFollow", { account: status.appLogin.accountName })
2010
- })]
2011
- }) : null,
2012
- rescanNote === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2013
- className: "dsm-trae-usage-note",
2014
- role: "status",
2015
- children: rescanNote
2016
- })
2017
- ]
2018
- }),
2019
- status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2020
- status.checkin !== void 0 && !status.checkin.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2021
- className: "dsm-trae-usage-error",
2022
- children: t("row.checkinDisabled")
2023
- }) : null,
2024
- status.checkinError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2025
- className: "dsm-trae-usage-error",
2026
- children: t("row.checkinError", { message: status.checkinError })
1966
+ })]
2027
1967
  }),
2028
1968
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2029
- className: "dsm-trae-models",
2030
- "aria-label": t("row.modelsTitle"),
1969
+ className: "dsm-trae-accounts",
1970
+ "aria-label": t("row.accountsTitle"),
2031
1971
  children: [
2032
1972
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2033
- className: "dsm-trae-models-head",
1973
+ className: "dsm-trae-accounts-head",
2034
1974
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2035
- className: "dsm-trae-models-title",
2036
- children: t("row.modelsTitle")
1975
+ className: "dsm-trae-accounts-title",
1976
+ children: t("row.accountsTitle")
2037
1977
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2038
- className: "dsm-trae-models-summary",
2039
- children: t("row.modelsSummary", { count: activeEnabledIds.size })
2040
- })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2041
- className: "dsm-trae-models-actions",
2042
- children: [
2043
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2044
- type: "button",
2045
- className: "dsm-btn dsm-btn-outline",
2046
- disabled: busy,
2047
- onClick: () => {
2048
- refreshModels();
2049
- },
2050
- children: busy ? t("row.modelsRefreshing") : t("row.modelsRefresh")
2051
- }),
2052
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2053
- type: "button",
2054
- className: "dsm-btn dsm-btn-outline",
2055
- disabled: busy || testing !== void 0 || activeEnabledIds.size === 0,
2056
- title: t("row.modelsTestHint"),
2057
- onClick: () => {
2058
- testEnabledModels();
2059
- },
2060
- children: testing === void 0 ? t("row.modelsTestEnabled") : t("row.modelsTesting", {
2061
- done: testing.done,
2062
- total: testing.total
2063
- })
2064
- }),
2065
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2066
- type: "button",
2067
- className: "dsm-btn dsm-btn-outline",
2068
- disabled: busy || testing !== void 0 || visibleModels.length === 0,
2069
- title: t("row.modelsTestAllHint"),
2070
- onClick: () => {
2071
- testAllModels();
2072
- },
2073
- children: testing === void 0 ? t("row.modelsTestAll") : t("row.modelsTesting", {
2074
- done: testing.done,
2075
- total: testing.total
2076
- })
2077
- })
2078
- ]
1978
+ className: "dsm-trae-accounts-hint",
1979
+ children: t("row.accountsHint")
1980
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1981
+ type: "button",
1982
+ className: "dsm-btn dsm-btn-outline",
1983
+ disabled: busy,
1984
+ onClick: () => {
1985
+ rescanAccounts();
1986
+ },
1987
+ children: busy ? t("row.accountsScanning") : t("row.refreshTokens")
2079
1988
  })]
2080
1989
  }),
2081
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2082
- className: "dsm-trae-models-hint",
2083
- children: t("row.modelsTestHint")
2084
- }),
2085
- testSummary === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2086
- className: "dsm-trae-models-summary",
2087
- children: testSummary
2088
- }),
2089
- testError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2090
- className: "dsm-trae-usage-error",
2091
- role: "alert",
2092
- children: testError
2093
- }),
2094
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2095
- className: "dsm-trae-model-list",
2096
- children: visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2097
- className: `dsm-trae-model${activeEnabledIds.has(model.id) ? "" : " dsm-trae-model-disabled"}`,
1990
+ status.status !== "signed-in" || status.accounts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1991
+ className: "dsm-trae-usage-account",
1992
+ role: "status",
1993
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1994
+ className: "dsm-trae-usage-account-copy",
2098
1995
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2099
- className: "dsm-trae-model-head",
2100
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2101
- className: "dsm-trae-model-enabled",
2102
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2103
- type: "checkbox",
2104
- checked: activeEnabledIds.has(model.id),
2105
- disabled: settingsScope?.getSnapshot().writable !== true || saving,
2106
- onChange: () => {
2107
- toggleModel(model.id);
2108
- }
2109
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2110
- className: "dsm-trae-model-copy",
2111
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2112
- className: "dsm-trae-model-name",
1996
+ className: "dsm-trae-usage-status",
1997
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1998
+ "aria-hidden": "true",
1999
+ className: "dsm-trae-usage-dot",
2000
+ style: dotStyle(status.status)
2001
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
2002
+ }), status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2003
+ className: "dsm-trae-usage-expiry",
2004
+ children: t("row.tokenExpiry", { expiresAt: formatDateTime(status.tokenExpiresAtMs) })
2005
+ }) : null]
2006
+ })
2007
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2008
+ className: `dsm-trae-account-table${activeRegion === "cn" ? " dsm-trae-account-table-checkin" : ""}`,
2009
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2010
+ className: "dsm-trae-account-row dsm-trae-account-row-head",
2011
+ role: "row",
2012
+ children: [
2013
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnAccount") }),
2014
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnValue") }),
2015
+ activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnCheckin") }) : null,
2016
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})
2017
+ ]
2018
+ }), status.accounts.map((account) => {
2019
+ const current = status.status === "signed-in" && account.id === status.accountId;
2020
+ const state = accountStatusByRegion[activeRegion][account.id];
2021
+ const error = claimErrorByRegion[activeRegion][account.id];
2022
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2023
+ className: `dsm-trae-account-row${current ? " dsm-trae-account-row-current" : ""}`,
2024
+ role: "row",
2025
+ children: [
2026
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2027
+ className: "dsm-trae-account-who",
2028
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2029
+ "aria-hidden": "true",
2030
+ className: "dsm-trae-usage-dot",
2031
+ style: dotStyle(account.selected ? "signed-in" : "signed-out")
2032
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2033
+ className: "dsm-trae-account-name",
2113
2034
  children: [
2114
- model.name,
2115
- model.creditMultiplier === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2116
- className: "dsm-trae-model-name-rate",
2117
- children: ["· x", model.creditMultiplier.toFixed(2)]
2035
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: account.accountName }),
2036
+ current ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2037
+ className: "dsm-trae-account-badge",
2038
+ children: t("row.accountCurrentBadge")
2039
+ }) : null,
2040
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2041
+ className: "dsm-trae-account-meta",
2042
+ children: [
2043
+ editionLabel(account.edition),
2044
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", {
2045
+ "aria-hidden": "true",
2046
+ children: "·"
2047
+ }),
2048
+ sourceLabel(account.source)
2049
+ ]
2118
2050
  }),
2119
- probeBadge(probeByRegion[activeRegion][model.id], t)
2051
+ error === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2052
+ className: "dsm-trae-account-note",
2053
+ role: "alert",
2054
+ children: t("row.checkinError", { message: error })
2055
+ })
2120
2056
  ]
2057
+ })]
2058
+ }),
2059
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2060
+ className: "dsm-trae-account-worth",
2061
+ children: rowValue(state)
2062
+ }),
2063
+ activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2064
+ className: "dsm-trae-account-checkin-cell",
2065
+ children: checkinControl(account, state)
2066
+ }) : null,
2067
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2068
+ className: "dsm-trae-account-actions",
2069
+ children: current ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2070
+ type: "button",
2071
+ className: "dsm-btn dsm-btn-outline dsm-trae-account-switch",
2072
+ disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
2073
+ onClick: () => {
2074
+ switchAccount(account.id);
2075
+ },
2076
+ children: switchingAccount ? t("row.accountSwitching") : t("row.accountSwitch")
2121
2077
  })
2122
- })]
2123
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2124
- className: "dsm-trae-model-options",
2078
+ })
2079
+ ]
2080
+ }, account.id);
2081
+ })]
2082
+ }),
2083
+ status.status === "signed-in" && status.alternatives !== void 0 && status.alternatives.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2084
+ className: "dsm-trae-usage-alternative",
2085
+ role: "status",
2086
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
2087
+ className: "dsm-trae-usage-alternative-text",
2088
+ children: [
2089
+ t("row.creditsExhausted", { account: status.accountName }),
2090
+ " ",
2091
+ t("row.creditsAlternative", { accounts: status.alternatives.map((alt) => `${alt.accountName}(${t(`row.edition${alt.edition === "cn" ? "Cn" : alt.edition === "sg" ? "Sg" : alt.edition === "solo" ? "Solo" : "SoloSg"}`)}:${formatNumber(alt.workAvailable + alt.generalAvailable)})`).join("、") })
2092
+ ]
2093
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2094
+ type: "button",
2095
+ className: "dsm-trae-usage-switch-button",
2096
+ disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
2097
+ onClick: () => {
2098
+ const target = status.alternatives?.[0];
2099
+ if (target !== void 0) switchAccount(target.id);
2100
+ },
2101
+ children: t("row.creditsAlternativeSwitch")
2102
+ })]
2103
+ }) : null,
2104
+ status.status === "signed-in" && status.credits?.expiry !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpiryNotice, {
2105
+ expiry: status.credits.expiry,
2106
+ t,
2107
+ formatNumber,
2108
+ formatDateTime
2109
+ }) : null,
2110
+ status.status === "signed-in" && status.appLogin !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2111
+ className: "dsm-trae-usage-alternative",
2112
+ role: "status",
2113
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2114
+ className: "dsm-trae-usage-alternative-text",
2115
+ children: t("row.appLoginMismatch", {
2116
+ account: status.appLogin.accountName,
2117
+ bound: status.accountName
2118
+ })
2119
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2120
+ type: "button",
2121
+ className: "dsm-trae-usage-switch-button",
2122
+ disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
2123
+ onClick: () => {
2124
+ followAppLogin();
2125
+ },
2126
+ children: t("row.appLoginFollow", { account: status.appLogin.accountName })
2127
+ })]
2128
+ }) : null,
2129
+ rescanNote === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2130
+ className: "dsm-trae-usage-note",
2131
+ role: "status",
2132
+ children: rescanNote
2133
+ })
2134
+ ]
2135
+ }),
2136
+ status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
2137
+ status.checkin !== void 0 && !status.checkin.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2138
+ className: "dsm-trae-usage-error",
2139
+ children: t("row.checkinDisabled")
2140
+ }) : null,
2141
+ status.checkinError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2142
+ className: "dsm-trae-usage-error",
2143
+ children: t("row.checkinError", { message: status.checkinError })
2144
+ }),
2145
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
2146
+ className: "dsm-trae-models",
2147
+ "aria-label": t("row.modelsTitle"),
2148
+ children: [
2149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2150
+ className: "dsm-trae-models-head",
2151
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
2152
+ className: "dsm-trae-models-title",
2153
+ children: t("row.modelsTitle")
2154
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2155
+ className: "dsm-trae-models-summary",
2156
+ children: t("row.modelsSummary", { count: activeEnabledIds.size })
2157
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2158
+ className: "dsm-trae-models-actions",
2159
+ children: [
2160
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2161
+ type: "button",
2162
+ className: "dsm-btn dsm-btn-outline",
2163
+ disabled: busy,
2164
+ onClick: () => {
2165
+ refreshModels();
2166
+ },
2167
+ children: busy ? t("row.modelsRefreshing") : t("row.modelsRefresh")
2168
+ }),
2169
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2170
+ type: "button",
2171
+ className: "dsm-btn dsm-btn-outline",
2172
+ disabled: busy || testing !== void 0 || activeEnabledIds.size === 0,
2173
+ title: t("row.modelsTestHint"),
2174
+ onClick: () => {
2175
+ testEnabledModels();
2176
+ },
2177
+ children: testing === void 0 ? t("row.modelsTestEnabled") : t("row.modelsTesting", {
2178
+ done: testing.done,
2179
+ total: testing.total
2180
+ })
2181
+ }),
2182
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2183
+ type: "button",
2184
+ className: "dsm-btn dsm-btn-outline",
2185
+ disabled: busy || testing !== void 0 || visibleModels.length === 0,
2186
+ title: t("row.modelsTestAllHint"),
2187
+ onClick: () => {
2188
+ testAllModels();
2189
+ },
2190
+ children: testing === void 0 ? t("row.modelsTestAll") : t("row.modelsTesting", {
2191
+ done: testing.done,
2192
+ total: testing.total
2193
+ })
2194
+ })
2195
+ ]
2196
+ })]
2197
+ }),
2198
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2199
+ className: "dsm-trae-models-hint",
2200
+ children: t("row.modelsTestHint")
2201
+ }),
2202
+ testSummary === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2203
+ className: "dsm-trae-models-summary",
2204
+ children: testSummary
2205
+ }),
2206
+ testError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2207
+ className: "dsm-trae-usage-error",
2208
+ role: "alert",
2209
+ children: testError
2210
+ }),
2211
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2212
+ className: "dsm-trae-model-list",
2213
+ children: visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2214
+ className: `dsm-trae-model${activeEnabledIds.has(model.id) ? "" : " dsm-trae-model-disabled"}`,
2215
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2216
+ className: "dsm-trae-model-head",
2125
2217
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2126
- className: "dsm-trae-model-image",
2218
+ className: "dsm-trae-model-enabled",
2127
2219
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2128
2220
  type: "checkbox",
2129
- checked: rowAcceptsImage(model),
2130
- disabled: rowImageIsAutomatic(model) || settingsScope?.getSnapshot().writable !== true || saving,
2131
- title: rowImageIsAutomatic(model) ? t("row.modelImageAuto") : void 0,
2132
- onChange: () => {
2133
- toggleImage(model.id);
2134
- }
2135
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelImage") })]
2136
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2137
- className: "dsm-trae-context-budget",
2138
- "aria-label": t("row.contextBudget"),
2139
- children: [model.maxContextWindow !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2140
- type: "radio",
2141
- name: `context-${model.id}`,
2142
- checked: activeContextBudgets[model.id] !== model.maxContextWindow,
2221
+ checked: activeEnabledIds.has(model.id),
2143
2222
  disabled: settingsScope?.getSnapshot().writable !== true || saving,
2144
2223
  onChange: () => {
2145
- setContextBudget(model.id, model.contextWindow);
2146
- }
2147
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.contextWindow, t("row.modelUnknown")) })] }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2148
- type: "radio",
2149
- name: `context-${model.id}`,
2150
- checked: model.maxContextWindow === void 0 || activeContextBudgets[model.id] === model.maxContextWindow,
2151
- disabled: model.maxContextWindow === void 0 || settingsScope?.getSnapshot().writable !== true || saving,
2152
- onChange: () => {
2153
- setContextBudget(model.id, model.maxContextWindow);
2224
+ toggleModel(model.id);
2154
2225
  }
2155
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) })] })]
2226
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2227
+ className: "dsm-trae-model-copy",
2228
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2229
+ className: "dsm-trae-model-name",
2230
+ children: [
2231
+ model.name,
2232
+ model.creditMultiplier === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2233
+ className: "dsm-trae-model-name-rate",
2234
+ children: ["· x", model.creditMultiplier.toFixed(2)]
2235
+ }),
2236
+ probeBadge(probeByRegion[activeRegion][model.id], t)
2237
+ ]
2238
+ })
2239
+ })]
2240
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2241
+ className: "dsm-trae-model-options",
2242
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
2243
+ className: "dsm-trae-model-image",
2244
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2245
+ type: "checkbox",
2246
+ checked: rowAcceptsImage(model),
2247
+ disabled: rowImageIsAutomatic(model) || settingsScope?.getSnapshot().writable !== true || saving,
2248
+ title: rowImageIsAutomatic(model) ? t("row.modelImageAuto") : void 0,
2249
+ onChange: () => {
2250
+ toggleImage(model.id);
2251
+ }
2252
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelImage") })]
2253
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
2254
+ className: "dsm-trae-context-budget",
2255
+ "aria-label": t("row.contextBudget"),
2256
+ children: [model.maxContextWindow !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2257
+ type: "radio",
2258
+ name: `context-${model.id}`,
2259
+ checked: activeContextBudgets[model.id] !== model.maxContextWindow,
2260
+ disabled: settingsScope?.getSnapshot().writable !== true || saving,
2261
+ onChange: () => {
2262
+ setContextBudget(model.id, model.contextWindow);
2263
+ }
2264
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.contextWindow, t("row.modelUnknown")) })] }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2265
+ type: "radio",
2266
+ name: `context-${model.id}`,
2267
+ checked: model.maxContextWindow === void 0 || activeContextBudgets[model.id] === model.maxContextWindow,
2268
+ disabled: model.maxContextWindow === void 0 || settingsScope?.getSnapshot().writable !== true || saving,
2269
+ onChange: () => {
2270
+ setContextBudget(model.id, model.maxContextWindow);
2271
+ }
2272
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) })] })]
2273
+ })]
2156
2274
  })]
2275
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2276
+ className: "dsm-trae-model-meta",
2277
+ children: [
2278
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelContext", { context: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) }) }),
2279
+ model.maxTokens === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelOutput", { output: formatCapacity(model.maxTokens, t("row.modelUnknown")) }) }),
2280
+ model.reasoning === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelReasoning", { efforts: model.reasoning.supported.join(" / ") }) })
2281
+ ]
2282
+ })]
2283
+ }, model.id))
2284
+ }),
2285
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2286
+ className: "dsm-trae-model-capability-note",
2287
+ children: t("row.modelCapabilityPending")
2288
+ }),
2289
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2290
+ className: "dsm-trae-model-actions",
2291
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
2292
+ className: "dsm-trae-usage-cheer",
2293
+ href: TRAE_GITHUB_URL,
2294
+ target: "_blank",
2295
+ rel: "noopener noreferrer",
2296
+ children: [t("row.cheer"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2297
+ className: "dsm-trae-usage-cheer-star",
2298
+ "aria-hidden": "true",
2299
+ children: "★"
2157
2300
  })]
2158
2301
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2159
- className: "dsm-trae-model-meta",
2160
- children: [
2161
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelContext", { context: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) }) }),
2162
- model.maxTokens === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelOutput", { output: formatCapacity(model.maxTokens, t("row.modelUnknown")) }) }),
2163
- model.reasoning === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelReasoning", { efforts: model.reasoning.supported.join(" / ") }) })
2164
- ]
2302
+ className: "dsm-trae-model-actions-buttons",
2303
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2304
+ type: "button",
2305
+ className: "dsm-btn dsm-btn-outline",
2306
+ disabled: !dirty || saving,
2307
+ onClick: discardModels,
2308
+ children: t("row.discard")
2309
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2310
+ type: "button",
2311
+ className: "dsm-btn dsm-btn-primary",
2312
+ disabled: !dirty || saving || activeEnabledIds.size === 0,
2313
+ onClick: () => {
2314
+ saveModels();
2315
+ },
2316
+ children: saving ? t("row.saving") : t("row.save")
2317
+ })]
2165
2318
  })]
2166
- }, model.id))
2167
- }),
2319
+ })
2320
+ ]
2321
+ })
2322
+ ] }) : null,
2323
+ status.status === "signed-out" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2324
+ className: "dsm-trae-usage-text",
2325
+ children: status.message ?? t("row.signedOutHint")
2326
+ }), status.searched && status.searched.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
2327
+ className: "dsm-trae-searched",
2328
+ children: [
2329
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", { children: [
2330
+ t("row.searchedTitle"),
2331
+ " (",
2332
+ status.searched.length,
2333
+ ")"
2334
+ ] }),
2168
2335
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2169
- className: "dsm-trae-model-capability-note",
2170
- children: t("row.modelCapabilityPending")
2336
+ className: "dsm-trae-searched-hint",
2337
+ children: t("row.searchedHint")
2171
2338
  }),
2172
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2173
- className: "dsm-trae-model-actions",
2174
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
2175
- className: "dsm-trae-usage-cheer",
2176
- href: TRAE_GITHUB_URL,
2177
- target: "_blank",
2178
- rel: "noopener noreferrer",
2179
- children: [t("row.cheer"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2180
- className: "dsm-trae-usage-cheer-star",
2181
- "aria-hidden": "true",
2182
- children: "★"
2183
- })]
2184
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2185
- className: "dsm-trae-model-actions-buttons",
2186
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2187
- type: "button",
2188
- className: "dsm-btn dsm-btn-outline",
2189
- disabled: !dirty || saving,
2190
- onClick: discardModels,
2191
- children: t("row.discard")
2192
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2193
- type: "button",
2194
- className: "dsm-btn dsm-btn-primary",
2195
- disabled: !dirty || saving || activeEnabledIds.size === 0,
2196
- onClick: () => {
2197
- saveModels();
2198
- },
2199
- children: saving ? t("row.saving") : t("row.save")
2200
- })]
2201
- })]
2339
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
2340
+ className: "dsm-trae-searched-list",
2341
+ children: status.searched.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: item.path }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2342
+ className: "dsm-trae-searched-reason",
2343
+ children: [
2344
+ t(item.source === "cli" ? "row.sourceCli" : "row.sourceDesktop"),
2345
+ " · ",
2346
+ t(item.reason === "missing" ? "row.reasonMissing" : item.reason === "unreadable" ? "row.reasonUnreadable" : "row.reasonInvalid")
2347
+ ]
2348
+ })] }, `${item.source}:${item.path}`))
2202
2349
  })
2203
2350
  ]
2204
- })
2205
- ] }) : null,
2206
- status.status === "signed-out" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2207
- className: "dsm-trae-usage-text",
2208
- children: status.message ?? t("row.signedOutHint")
2209
- }), status.searched && status.searched.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
2210
- className: "dsm-trae-searched",
2211
- children: [
2212
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", { children: [
2213
- t("row.searchedTitle"),
2214
- " (",
2215
- status.searched.length,
2216
- ")"
2217
- ] }),
2218
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2219
- className: "dsm-trae-searched-hint",
2220
- children: t("row.searchedHint")
2221
- }),
2222
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
2223
- className: "dsm-trae-searched-list",
2224
- children: status.searched.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: item.path }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2225
- className: "dsm-trae-searched-reason",
2226
- children: [
2227
- t(item.source === "cli" ? "row.sourceCli" : "row.sourceDesktop"),
2228
- " · ",
2229
- t(item.reason === "missing" ? "row.reasonMissing" : item.reason === "unreadable" ? "row.reasonUnreadable" : "row.reasonInvalid")
2230
- ]
2231
- })] }, `${item.source}:${item.path}`))
2232
- })
2233
- ]
2234
- }) : null] }) : null,
2235
- status.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2236
- className: "dsm-trae-usage-error",
2237
- children: status.message
2238
- }) : null
2239
- ]
2240
- }) : null
2241
- })]
2351
+ }) : null] }) : null,
2352
+ status.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2353
+ className: "dsm-trae-usage-error",
2354
+ children: status.message
2355
+ }) : null
2356
+ ]
2357
+ }) : null
2358
+ }),
2359
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BusyOverlay, {
2360
+ visible: saving || savingSettings,
2361
+ message: t("row.veilSaving")
2362
+ })
2363
+ ]
2242
2364
  });
2243
2365
  }
2244
2366
  //#endregion
@@ -3029,6 +3151,7 @@ window.__ModuleLoader__.load({
3029
3151
  "row.discard": "Discard changes",
3030
3152
  "row.save": "Save",
3031
3153
  "row.saving": "Saving…",
3154
+ "row.veilSaving": "Saving changes…",
3032
3155
  "row.modelContext": "Max context {context}",
3033
3156
  "row.contextBudget": "DSH context budget",
3034
3157
  "row.modelOutput": "Output {output}",
@@ -3170,6 +3293,7 @@ window.__ModuleLoader__.load({
3170
3293
  "row.discard": "放弃修改",
3171
3294
  "row.save": "保存",
3172
3295
  "row.saving": "保存中…",
3296
+ "row.veilSaving": "正在保存更改…",
3173
3297
  "row.modelContext": "最大上下文 {context}",
3174
3298
  "row.contextBudget": "DSH 上下文预算",
3175
3299
  "row.modelOutput": "最大输出 {output}",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "dsh-connect-trae",
3
3
  "displayName": "DSH Connect Trae",
4
4
  "description": "把本机登录的 Trae 模型接入 DeepSeek Harness:国内版与国际版双供应商并行,提供用量/积分概览与每日签到领取。",
5
- "version": "3.4.2",
5
+ "version": "3.4.3",
6
6
  "author": "dingminhua",
7
7
  "copyright": "Copyright (c) 2026 LaoDing",
8
8
  "license": "MIT",