dsh-connect-trae 3.4.1 → 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.
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}",