@eddyskywalker/dsh-chatgpt-subscription 0.8.1 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +65 -0
  3. package/lib/client.js +1510 -303
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +4723 -1640
  6. package/lib/types/client/ProviderHubSection.d.ts.map +1 -1
  7. package/lib/types/client/antigravity/locales.d.ts +2 -2
  8. package/lib/types/client/command-code/locales.d.ts +2 -2
  9. package/lib/types/client/index.d.ts +1 -0
  10. package/lib/types/client/index.d.ts.map +1 -1
  11. package/lib/types/client/kimi-code/locales.d.ts +2 -2
  12. package/lib/types/client/locales.d.ts +1 -1
  13. package/lib/types/client/workbuddy/WorkBuddySection.d.ts.map +1 -1
  14. package/lib/types/client/workbuddy/locales.d.ts +60 -0
  15. package/lib/types/client/workbuddy/locales.d.ts.map +1 -1
  16. package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts +26 -0
  17. package/lib/types/client/zhipu/ZhipuComposerQuota.d.ts.map +1 -0
  18. package/lib/types/client/zhipu/ZhipuSection.d.ts +11 -0
  19. package/lib/types/client/zhipu/ZhipuSection.d.ts.map +1 -0
  20. package/lib/types/client/zhipu/locales.d.ts +275 -0
  21. package/lib/types/client/zhipu/locales.d.ts.map +1 -0
  22. package/lib/types/client/zhipu/styles.d.ts +12 -0
  23. package/lib/types/client/zhipu/styles.d.ts.map +1 -0
  24. package/lib/types/host/workbuddy/checkin.d.ts +134 -0
  25. package/lib/types/host/workbuddy/checkin.d.ts.map +1 -0
  26. package/lib/types/host/workbuddy/routes.d.ts +3 -0
  27. package/lib/types/host/workbuddy/routes.d.ts.map +1 -1
  28. package/lib/types/host/workbuddy/token-store.d.ts +24 -1
  29. package/lib/types/host/workbuddy/token-store.d.ts.map +1 -1
  30. package/lib/types/host/zhipu/account-pool.d.ts +43 -0
  31. package/lib/types/host/zhipu/account-pool.d.ts.map +1 -0
  32. package/lib/types/host/zhipu/adapter.d.ts +93 -0
  33. package/lib/types/host/zhipu/adapter.d.ts.map +1 -0
  34. package/lib/types/host/zhipu/client.d.ts +153 -0
  35. package/lib/types/host/zhipu/client.d.ts.map +1 -0
  36. package/lib/types/host/zhipu/mapper.d.ts +111 -0
  37. package/lib/types/host/zhipu/mapper.d.ts.map +1 -0
  38. package/lib/types/host/zhipu/model-catalog.d.ts +73 -0
  39. package/lib/types/host/zhipu/model-catalog.d.ts.map +1 -0
  40. package/lib/types/host/zhipu/routes.d.ts +33 -0
  41. package/lib/types/host/zhipu/routes.d.ts.map +1 -0
  42. package/lib/types/host/zhipu/token-store.d.ts +112 -0
  43. package/lib/types/host/zhipu/token-store.d.ts.map +1 -0
  44. package/lib/types/host/zhipu/types.d.ts +125 -0
  45. package/lib/types/host/zhipu/types.d.ts.map +1 -0
  46. package/lib/types/index.d.ts +8 -0
  47. package/lib/types/index.d.ts.map +1 -1
  48. package/lib/types/shared/workbuddy-contracts.d.ts +40 -0
  49. package/lib/types/shared/workbuddy-contracts.d.ts.map +1 -1
  50. package/lib/types/shared/zhipu-contracts.d.ts +156 -0
  51. package/lib/types/shared/zhipu-contracts.d.ts.map +1 -0
  52. package/package.json +31 -31
package/lib/client.js CHANGED
@@ -56,7 +56,7 @@ window.__ModuleLoader__.load({
56
56
  //#endregion
57
57
  //#region src/client/CodexComposerQuota.tsx
58
58
  function CodexComposerQuota({ api, directory, loadModelDirectory, t }) {
59
- const modelState = useStore$4(directory);
59
+ const modelState = useStore$5(directory);
60
60
  const [status, setStatus] = (0, react.useState)(null);
61
61
  const [loading, setLoading] = (0, react.useState)(false);
62
62
  const mountedRef = (0, react.useRef)(false);
@@ -103,7 +103,7 @@ window.__ModuleLoader__.load({
103
103
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("quickQuotaLabel") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota === null ? loading ? t("quickQuotaLoading") : "—" : formatPercent$1(quota.remainingPercent) })]
104
104
  });
105
105
  }
106
- function useStore$4(store) {
106
+ function useStore$5(store) {
107
107
  return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
108
108
  }
109
109
  function formatPercent$1(value) {
@@ -179,7 +179,7 @@ window.__ModuleLoader__.load({
179
179
  });
180
180
  }
181
181
  function promptFromBlock(block) {
182
- const raw = "kind" in block ? block.call?.argsRaw : block.argsRaw;
182
+ const raw = "kind" in block ? block.call?.argsRaw : dispatchedArgsRaw(block);
183
183
  if (typeof raw !== "string" || raw.trim() === "") return null;
184
184
  try {
185
185
  const value = JSON.parse(raw);
@@ -188,6 +188,16 @@ window.__ModuleLoader__.load({
188
188
  return null;
189
189
  }
190
190
  }
191
+ /**
192
+ * Arguments of a dispatched call that has no result yet.
193
+ *
194
+ * Harness 0.1.7-rc.1 dispatches a view as soon as its call starts *preparing*,
195
+ * before the arguments exist, so the preparing shape carries no `argsRaw` at
196
+ * all. Older generations only ever sent the dispatched shape.
197
+ */
198
+ function dispatchedArgsRaw(block) {
199
+ return "argsRaw" in block ? block.argsRaw : void 0;
200
+ }
191
201
  function imageBlocks(blocks) {
192
202
  const result = [];
193
203
  for (const block of blocks) {
@@ -839,7 +849,7 @@ window.__ModuleLoader__.load({
839
849
  await updatePreferences({ contextWindowOverrides: { [model]: null } });
840
850
  setContextDrafts((drafts) => ({
841
851
  ...drafts,
842
- [model]: formatCapacity$4(resolveCodexCatalogEntry(model).contextWindow)
852
+ [model]: formatCapacity$5(resolveCodexCatalogEntry(model).contextWindow)
843
853
  }));
844
854
  };
845
855
  /** Clear every stored override, including models the picker no longer shows. */
@@ -1053,7 +1063,7 @@ window.__ModuleLoader__.load({
1053
1063
  }),
1054
1064
  connection !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(InfoRow, {
1055
1065
  label: t("latency"),
1056
- value: `${connection.latencyMs} ms · ${formatDate$3(connection.checkedAt)}`
1066
+ value: `${connection.latencyMs} ms · ${formatDate$4(connection.checkedAt)}`
1057
1067
  }) : null,
1058
1068
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
1059
1069
  className: "dsha-muted dsha-models-hint",
@@ -1333,7 +1343,7 @@ window.__ModuleLoader__.load({
1333
1343
  id: inputId,
1334
1344
  type: "text",
1335
1345
  inputMode: "numeric",
1336
- value: draft ?? formatCapacity$4(fallback),
1346
+ value: draft ?? formatCapacity$5(fallback),
1337
1347
  disabled: busy !== null,
1338
1348
  "aria-label": entry.name + " " + t("contextWindow"),
1339
1349
  onChange: (event) => {
@@ -1465,7 +1475,7 @@ window.__ModuleLoader__.load({
1465
1475
  children: [
1466
1476
  t("updated"),
1467
1477
  ": ",
1468
- formatDate$3(quota.fetchedAt)
1478
+ formatDate$4(quota.fetchedAt)
1469
1479
  ]
1470
1480
  }) : null
1471
1481
  ]
@@ -1557,7 +1567,7 @@ window.__ModuleLoader__.load({
1557
1567
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("small", { children: [
1558
1568
  t("resetCreditExpires"),
1559
1569
  ": ",
1560
- resetCredits.expiresAt == null ? t("unknown") : formatReset$3(resetCredits.expiresAt)
1570
+ resetCredits.expiresAt == null ? t("unknown") : formatReset$4(resetCredits.expiresAt)
1561
1571
  ] })
1562
1572
  ]
1563
1573
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
@@ -1590,7 +1600,7 @@ window.__ModuleLoader__.load({
1590
1600
  }),
1591
1601
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1592
1602
  className: "dsh-codex-meter-meta",
1593
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window?.resetsAt == null ? "—" : `${t("resets")}: ${formatReset$3(window.resetsAt)}` })]
1603
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: percent >= 100 ? `${t("exhausted")} · ${formatPercent(remaining)} ${t("remaining")}` : `${formatPercent(percent)} ${t("used")} · ${formatPercent(remaining)} ${t("remaining")}` }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window?.resetsAt == null ? "—" : `${t("resets")}: ${formatReset$4(window.resetsAt)}` })]
1594
1604
  })
1595
1605
  ]
1596
1606
  });
@@ -1616,7 +1626,7 @@ window.__ModuleLoader__.load({
1616
1626
  return `${value} ${t("limitWindow")}`;
1617
1627
  }
1618
1628
  }
1619
- function parsePositiveCapacity$4(value) {
1629
+ function parsePositiveCapacity$5(value) {
1620
1630
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
1621
1631
  if (matched === null) return null;
1622
1632
  const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
@@ -1624,10 +1634,10 @@ window.__ModuleLoader__.load({
1624
1634
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
1625
1635
  }
1626
1636
  function parseCapacity(value, maxContextWindow = GPT_56_MAX_CONTEXT_WINDOW) {
1627
- const parsed = parsePositiveCapacity$4(value);
1637
+ const parsed = parsePositiveCapacity$5(value);
1628
1638
  return parsed !== null && parsed <= maxContextWindow ? parsed : null;
1629
1639
  }
1630
- function formatCapacity$4(value) {
1640
+ function formatCapacity$5(value) {
1631
1641
  if (value % 1e3 === 0) return `${value / 1e3}K`;
1632
1642
  return String(value);
1633
1643
  }
@@ -1644,11 +1654,11 @@ window.__ModuleLoader__.load({
1644
1654
  limit.remainingPercent !== null && limit.remainingPercent !== void 0 ? `${formatPercent(limit.remainingPercent)} ${t("remaining")}` : null,
1645
1655
  limit.limit !== null && limit.limit !== void 0 ? `${t("limit")}: ${limit.limit}` : null,
1646
1656
  limit.used !== null && limit.used !== void 0 ? `${t("used")}: ${limit.used}` : null,
1647
- limit.resetsAt !== null && limit.resetsAt !== void 0 ? `${t("resets")}: ${formatReset$3(limit.resetsAt)}` : null
1657
+ limit.resetsAt !== null && limit.resetsAt !== void 0 ? `${t("resets")}: ${formatReset$4(limit.resetsAt)}` : null
1648
1658
  ].filter((part) => part !== null);
1649
1659
  return parts.length > 0 ? parts.join(" · ") : t("unknown");
1650
1660
  }
1651
- function formatDate$3(seconds) {
1661
+ function formatDate$4(seconds) {
1652
1662
  if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
1653
1663
  const ms = seconds > 1e10 ? seconds : seconds * 1e3;
1654
1664
  try {
@@ -1660,10 +1670,10 @@ window.__ModuleLoader__.load({
1660
1670
  return "—";
1661
1671
  }
1662
1672
  }
1663
- function formatReset$3(seconds) {
1673
+ function formatReset$4(seconds) {
1664
1674
  if (seconds === void 0 || seconds === null || typeof seconds !== "number" || !Number.isFinite(seconds) || seconds <= 0) return "—";
1665
1675
  const ms = seconds > 1e10 ? seconds : seconds * 1e3;
1666
- const absolute = formatDate$3(seconds);
1676
+ const absolute = formatDate$4(seconds);
1667
1677
  const diff = ms - Date.now();
1668
1678
  const abs = Math.abs(diff);
1669
1679
  const [amount, unit] = abs >= 864e5 ? [Math.round(diff / 864e5), "day"] : abs >= 36e5 ? [Math.round(diff / 36e5), "hour"] : [Math.round(diff / 6e4), "minute"];
@@ -1679,7 +1689,7 @@ window.__ModuleLoader__.load({
1679
1689
  //#endregion
1680
1690
  //#region src/client/antigravity/locales.ts
1681
1691
  const NS_ANTIGRAVITY = "dsh-antigravity";
1682
- const zh$4 = {
1692
+ const zh$5 = {
1683
1693
  ...accountPoolZh,
1684
1694
  title: "Antigravity",
1685
1695
  pageDesc: "登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。",
@@ -1749,7 +1759,7 @@ window.__ModuleLoader__.load({
1749
1759
  loginFailed: "登录失败",
1750
1760
  tokens: "tokens"
1751
1761
  };
1752
- const en$4 = {
1762
+ const en$5 = {
1753
1763
  ...accountPoolEn,
1754
1764
  title: "Antigravity",
1755
1765
  pageDesc: "Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.",
@@ -1819,17 +1829,17 @@ window.__ModuleLoader__.load({
1819
1829
  loginFailed: "Login failed",
1820
1830
  tokens: "tokens"
1821
1831
  };
1822
- const dictionaries$4 = {
1823
- zh: zh$4,
1824
- "zh-CN": zh$4,
1825
- en: en$4,
1826
- "en-US": en$4
1832
+ const dictionaries$5 = {
1833
+ zh: zh$5,
1834
+ "zh-CN": zh$5,
1835
+ en: en$5,
1836
+ "en-US": en$5
1827
1837
  };
1828
1838
  //#endregion
1829
1839
  //#region src/client/antigravity/AntigravitySection.tsx
1830
- const API$7 = "/antigravity/api";
1831
- async function fetchApi$7(path, options) {
1832
- const res = await fetch(`${API$7}${path}`, {
1840
+ const API$9 = "/antigravity/api";
1841
+ async function fetchApi$9(path, options) {
1842
+ const res = await fetch(`${API$9}${path}`, {
1833
1843
  ...options,
1834
1844
  headers: {
1835
1845
  "Content-Type": "application/json",
@@ -1840,14 +1850,14 @@ window.__ModuleLoader__.load({
1840
1850
  if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
1841
1851
  return json.value;
1842
1852
  }
1843
- function parsePositiveCapacity$3(value) {
1853
+ function parsePositiveCapacity$4(value) {
1844
1854
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
1845
1855
  if (matched === null) return null;
1846
1856
  const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
1847
1857
  const parsed = Number(matched[1]) * multiplier;
1848
1858
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
1849
1859
  }
1850
- function formatCapacity$3(value) {
1860
+ function formatCapacity$4(value) {
1851
1861
  if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
1852
1862
  if (value % 1e3 === 0) return `${value / 1e3}K`;
1853
1863
  return String(value);
@@ -1857,9 +1867,9 @@ window.__ModuleLoader__.load({
1857
1867
  * toggle: a model that was just enabled has no draft yet, and the context
1858
1868
  * window section only renders enabled models.
1859
1869
  */
1860
- function contextDraftsFor$3(status) {
1870
+ function contextDraftsFor$4(status) {
1861
1871
  const drafts = {};
1862
- for (const model of status.models) drafts[model.id] = formatCapacity$3(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
1872
+ for (const model of status.models) drafts[model.id] = formatCapacity$4(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
1863
1873
  return drafts;
1864
1874
  }
1865
1875
  function formatResetTime(resetTime) {
@@ -1873,7 +1883,7 @@ window.__ModuleLoader__.load({
1873
1883
  if (hours > 0) return `${hours}h ${mins % 60}m`;
1874
1884
  return `${mins}m`;
1875
1885
  }
1876
- function formatDate$2(ms) {
1886
+ function formatDate$3(ms) {
1877
1887
  if (!ms || ms <= 0) return "—";
1878
1888
  try {
1879
1889
  return new Intl.DateTimeFormat(void 0, {
@@ -1893,7 +1903,7 @@ window.__ModuleLoader__.load({
1893
1903
  const [loginProgress, setLoginProgress] = (0, react.useState)(null);
1894
1904
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
1895
1905
  const [savingModel, setSavingModel] = (0, react.useState)(null);
1896
- const t = zh$4;
1906
+ const t = zh$5;
1897
1907
  const notifyChange = (0, react.useCallback)(() => {
1898
1908
  onModelChange?.();
1899
1909
  loadModelDirectory?.();
@@ -1904,9 +1914,9 @@ window.__ModuleLoader__.load({
1904
1914
  setValidationUrl(null);
1905
1915
  }
1906
1916
  try {
1907
- const data = await fetchApi$7("/status");
1917
+ const data = await fetchApi$9("/status");
1908
1918
  setStatus(data);
1909
- setContextDrafts(contextDraftsFor$3(data));
1919
+ setContextDrafts(contextDraftsFor$4(data));
1910
1920
  } catch (err) {
1911
1921
  if (!quiet) setError(err instanceof Error ? err.message : String(err));
1912
1922
  } finally {
@@ -1931,11 +1941,11 @@ window.__ModuleLoader__.load({
1931
1941
  setError(null);
1932
1942
  setValidationUrl(null);
1933
1943
  setLoginProgress(null);
1934
- const flow = await fetchApi$7("/login", { method: "POST" });
1944
+ const flow = await fetchApi$9("/login", { method: "POST" });
1935
1945
  if (flow.authUrl) window.open(flow.authUrl, "_blank");
1936
1946
  const pollTimer = setInterval(async () => {
1937
1947
  try {
1938
- const pollStatus = await fetchApi$7("/login/status");
1948
+ const pollStatus = await fetchApi$9("/login/status");
1939
1949
  if (pollStatus.progress) setLoginProgress(pollStatus.progress);
1940
1950
  if (pollStatus.status === "complete") {
1941
1951
  clearInterval(pollTimer);
@@ -1967,7 +1977,7 @@ window.__ModuleLoader__.load({
1967
1977
  try {
1968
1978
  setBusy("quota");
1969
1979
  setError(null);
1970
- const updated = await fetchApi$7("/quota", { method: "POST" });
1980
+ const updated = await fetchApi$9("/quota", { method: "POST" });
1971
1981
  setStatus(updated);
1972
1982
  } catch (err) {
1973
1983
  setError(err instanceof Error ? err.message : String(err));
@@ -1979,7 +1989,7 @@ window.__ModuleLoader__.load({
1979
1989
  try {
1980
1990
  setBusy(`primary-${accountId}`);
1981
1991
  setError(null);
1982
- const updated = await fetchApi$7("/accounts", {
1992
+ const updated = await fetchApi$9("/accounts", {
1983
1993
  method: "POST",
1984
1994
  body: JSON.stringify({
1985
1995
  action: "set-primary",
@@ -1998,7 +2008,7 @@ window.__ModuleLoader__.load({
1998
2008
  try {
1999
2009
  setBusy(`delete-${accountId}`);
2000
2010
  setError(null);
2001
- const updated = await fetchApi$7("/accounts", {
2011
+ const updated = await fetchApi$9("/accounts", {
2002
2012
  method: "POST",
2003
2013
  body: JSON.stringify({
2004
2014
  action: "delete",
@@ -2017,7 +2027,7 @@ window.__ModuleLoader__.load({
2017
2027
  try {
2018
2028
  setBusy(`cooldown-${accountId}`);
2019
2029
  setError(null);
2020
- const updated = await fetchApi$7("/accounts", {
2030
+ const updated = await fetchApi$9("/accounts", {
2021
2031
  method: "POST",
2022
2032
  body: JSON.stringify({
2023
2033
  action: "clear-cooldown",
@@ -2035,7 +2045,7 @@ window.__ModuleLoader__.load({
2035
2045
  try {
2036
2046
  setBusy("strategy");
2037
2047
  setError(null);
2038
- const updated = await fetchApi$7("/accounts", {
2048
+ const updated = await fetchApi$9("/accounts", {
2039
2049
  method: "POST",
2040
2050
  body: JSON.stringify({
2041
2051
  action: "strategy",
@@ -2055,7 +2065,7 @@ window.__ModuleLoader__.load({
2055
2065
  enabled
2056
2066
  } : prev);
2057
2067
  try {
2058
- const updated = await fetchApi$7("/settings", {
2068
+ const updated = await fetchApi$9("/settings", {
2059
2069
  method: "POST",
2060
2070
  body: JSON.stringify({ enabled })
2061
2071
  });
@@ -2071,12 +2081,12 @@ window.__ModuleLoader__.load({
2071
2081
  const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id);
2072
2082
  const nextEnabled = checked ? [.../* @__PURE__ */ new Set([...currentEnabled, modelId])] : currentEnabled.filter((id) => id !== modelId);
2073
2083
  try {
2074
- const updated = await fetchApi$7("/models", {
2084
+ const updated = await fetchApi$9("/models", {
2075
2085
  method: "POST",
2076
2086
  body: JSON.stringify({ enabledModelIds: nextEnabled })
2077
2087
  });
2078
2088
  setStatus(updated);
2079
- setContextDrafts(contextDraftsFor$3(updated));
2089
+ setContextDrafts(contextDraftsFor$4(updated));
2080
2090
  notifyChange();
2081
2091
  } catch (err) {
2082
2092
  setError(err instanceof Error ? err.message : String(err));
@@ -2086,12 +2096,12 @@ window.__ModuleLoader__.load({
2086
2096
  if (!status) return;
2087
2097
  const nextEnabled = selectAll ? status.models.map((m) => m.id) : [];
2088
2098
  try {
2089
- const updated = await fetchApi$7("/models", {
2099
+ const updated = await fetchApi$9("/models", {
2090
2100
  method: "POST",
2091
2101
  body: JSON.stringify({ enabledModelIds: nextEnabled })
2092
2102
  });
2093
2103
  setStatus(updated);
2094
- setContextDrafts(contextDraftsFor$3(updated));
2104
+ setContextDrafts(contextDraftsFor$4(updated));
2095
2105
  notifyChange();
2096
2106
  } catch (err) {
2097
2107
  setError(err instanceof Error ? err.message : String(err));
@@ -2099,7 +2109,7 @@ window.__ModuleLoader__.load({
2099
2109
  };
2100
2110
  const handleUpdateEffort = async (effort) => {
2101
2111
  try {
2102
- const updated = await fetchApi$7("/settings", {
2112
+ const updated = await fetchApi$9("/settings", {
2103
2113
  method: "POST",
2104
2114
  body: JSON.stringify({ defaultReasoningEffort: effort })
2105
2115
  });
@@ -2111,7 +2121,7 @@ window.__ModuleLoader__.load({
2111
2121
  };
2112
2122
  const handleSaveContextWindow = async (modelId) => {
2113
2123
  const raw = contextDrafts[modelId] || "";
2114
- const parsed = parsePositiveCapacity$3(raw);
2124
+ const parsed = parsePositiveCapacity$4(raw);
2115
2125
  if (parsed === null) {
2116
2126
  setError(`无效的上下文容量值: ${raw}`);
2117
2127
  return;
@@ -2119,14 +2129,14 @@ window.__ModuleLoader__.load({
2119
2129
  try {
2120
2130
  setSavingModel(modelId);
2121
2131
  setError(null);
2122
- const updated = await fetchApi$7("/settings", {
2132
+ const updated = await fetchApi$9("/settings", {
2123
2133
  method: "POST",
2124
2134
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
2125
2135
  });
2126
2136
  setStatus(updated);
2127
2137
  setContextDrafts((prev) => ({
2128
2138
  ...prev,
2129
- [modelId]: formatCapacity$3(parsed)
2139
+ [modelId]: formatCapacity$4(parsed)
2130
2140
  }));
2131
2141
  notifyChange();
2132
2142
  } catch (err) {
@@ -2140,7 +2150,7 @@ window.__ModuleLoader__.load({
2140
2150
  try {
2141
2151
  setSavingModel(modelId);
2142
2152
  setError(null);
2143
- const updated = await fetchApi$7("/settings", {
2153
+ const updated = await fetchApi$9("/settings", {
2144
2154
  method: "POST",
2145
2155
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
2146
2156
  });
@@ -2149,7 +2159,7 @@ window.__ModuleLoader__.load({
2149
2159
  const model = updated.models.find((candidate) => candidate.id === modelId);
2150
2160
  return model === void 0 ? prev : {
2151
2161
  ...prev,
2152
- [modelId]: formatCapacity$3(model.defaultContextWindow)
2162
+ [modelId]: formatCapacity$4(model.defaultContextWindow)
2153
2163
  };
2154
2164
  });
2155
2165
  notifyChange();
@@ -2167,12 +2177,12 @@ window.__ModuleLoader__.load({
2167
2177
  try {
2168
2178
  setBusy("context");
2169
2179
  setError(null);
2170
- const updated = await fetchApi$7("/settings", {
2180
+ const updated = await fetchApi$9("/settings", {
2171
2181
  method: "POST",
2172
2182
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
2173
2183
  });
2174
2184
  setStatus(updated);
2175
- setContextDrafts(contextDraftsFor$3(updated));
2185
+ setContextDrafts(contextDraftsFor$4(updated));
2176
2186
  notifyChange();
2177
2187
  } catch (err) {
2178
2188
  setError(err instanceof Error ? err.message : String(err));
@@ -2221,12 +2231,12 @@ window.__ModuleLoader__.load({
2221
2231
  account.expiresAt && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2222
2232
  t.expires,
2223
2233
  ": ",
2224
- formatDate$2(account.expiresAt)
2234
+ formatDate$3(account.expiresAt)
2225
2235
  ] }),
2226
2236
  account.lastUsedAt && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
2227
2237
  t.lastUsed,
2228
2238
  ": ",
2229
- formatDate$2(account.lastUsedAt)
2239
+ formatDate$3(account.lastUsedAt)
2230
2240
  ] })
2231
2241
  ] })
2232
2242
  }),
@@ -2505,7 +2515,7 @@ window.__ModuleLoader__.load({
2505
2515
  //#endregion
2506
2516
  //#region src/client/command-code/locales.ts
2507
2517
  const NS_COMMAND_CODE = "dsh-command-code";
2508
- const zh$3 = {
2518
+ const zh$4 = {
2509
2519
  ...accountPoolZh,
2510
2520
  title: "Command Code",
2511
2521
  pageDesc: "登录 Command Code,管理可用模型、上下文窗口与额度。",
@@ -2577,7 +2587,7 @@ window.__ModuleLoader__.load({
2577
2587
  loginFailed: "登录失败",
2578
2588
  tokens: "tokens"
2579
2589
  };
2580
- const en$3 = {
2590
+ const en$4 = {
2581
2591
  ...accountPoolEn,
2582
2592
  title: "Command Code",
2583
2593
  pageDesc: "Sign in to Command Code and manage models, context windows, and quota.",
@@ -2649,11 +2659,11 @@ window.__ModuleLoader__.load({
2649
2659
  loginFailed: "Sign-in failed",
2650
2660
  tokens: "tokens"
2651
2661
  };
2652
- const dictionaries$3 = {
2653
- zh: zh$3,
2654
- "zh-CN": zh$3,
2655
- en: en$3,
2656
- "en-US": en$3
2662
+ const dictionaries$4 = {
2663
+ zh: zh$4,
2664
+ "zh-CN": zh$4,
2665
+ en: en$4,
2666
+ "en-US": en$4
2657
2667
  };
2658
2668
  //#endregion
2659
2669
  //#region src/client/command-code/CommandCodeSection.tsx
@@ -2661,7 +2671,7 @@ window.__ModuleLoader__.load({
2661
2671
  * Display label per reasoning level. The locale dictionary only accepts flat
2662
2672
  * string values, so this nested table lives with the control that renders it.
2663
2673
  */
2664
- const EFFORT_LABELS$1 = {
2674
+ const EFFORT_LABELS$2 = {
2665
2675
  minimal: "Minimal",
2666
2676
  low: "Low",
2667
2677
  medium: "Medium",
@@ -2669,9 +2679,9 @@ window.__ModuleLoader__.load({
2669
2679
  xhigh: "X-High",
2670
2680
  max: "Max"
2671
2681
  };
2672
- const API$6 = "/command-code/api";
2673
- async function fetchApi$6(path, options) {
2674
- const res = await fetch(`${API$6}${path}`, {
2682
+ const API$8 = "/command-code/api";
2683
+ async function fetchApi$8(path, options) {
2684
+ const res = await fetch(`${API$8}${path}`, {
2675
2685
  ...options,
2676
2686
  headers: {
2677
2687
  "Content-Type": "application/json",
@@ -2683,14 +2693,14 @@ window.__ModuleLoader__.load({
2683
2693
  return json.value;
2684
2694
  }
2685
2695
  /** Parse "1M", "512K", "200000" into a positive integer token count. */
2686
- function parsePositiveCapacity$2(value) {
2696
+ function parsePositiveCapacity$3(value) {
2687
2697
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
2688
2698
  if (matched === null) return null;
2689
2699
  const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
2690
2700
  const parsed = Number(matched[1]) * multiplier;
2691
2701
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
2692
2702
  }
2693
- function formatCapacity$2(value) {
2703
+ function formatCapacity$3(value) {
2694
2704
  if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
2695
2705
  if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
2696
2706
  return String(value);
@@ -2700,12 +2710,12 @@ window.__ModuleLoader__.load({
2700
2710
  * toggle: a model that was just enabled has no draft yet, and the context
2701
2711
  * window section only renders enabled models.
2702
2712
  */
2703
- function contextDraftsFor$2(status) {
2713
+ function contextDraftsFor$3(status) {
2704
2714
  const drafts = {};
2705
- for (const model of status.models) drafts[model.id] = formatCapacity$2(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
2715
+ for (const model of status.models) drafts[model.id] = formatCapacity$3(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
2706
2716
  return drafts;
2707
2717
  }
2708
- function formatReset$2(resetsAt) {
2718
+ function formatReset$3(resetsAt) {
2709
2719
  if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
2710
2720
  const diff = resetsAt - Date.now();
2711
2721
  if (diff <= 0) return "now";
@@ -2725,7 +2735,7 @@ window.__ModuleLoader__.load({
2725
2735
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
2726
2736
  const [savingModel, setSavingModel] = (0, react.useState)(null);
2727
2737
  const [apiKey, setApiKey] = (0, react.useState)("");
2728
- const t = zh$3;
2738
+ const t = zh$4;
2729
2739
  const notifyChange = (0, react.useCallback)(() => {
2730
2740
  onModelChange?.();
2731
2741
  loadModelDirectory?.();
@@ -2733,9 +2743,9 @@ window.__ModuleLoader__.load({
2733
2743
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
2734
2744
  if (!quiet) setError(null);
2735
2745
  try {
2736
- const data = await fetchApi$6("/status");
2746
+ const data = await fetchApi$8("/status");
2737
2747
  setStatus(data);
2738
- setContextDrafts(contextDraftsFor$2(data));
2748
+ setContextDrafts(contextDraftsFor$3(data));
2739
2749
  } catch (err) {
2740
2750
  if (!quiet) setError(err instanceof Error ? err.message : String(err));
2741
2751
  } finally {
@@ -2759,12 +2769,12 @@ window.__ModuleLoader__.load({
2759
2769
  setBusy("login");
2760
2770
  setError(null);
2761
2771
  setLoginProgress(null);
2762
- const flow = await fetchApi$6("/login", { method: "POST" });
2772
+ const flow = await fetchApi$8("/login", { method: "POST" });
2763
2773
  if (flow.authUrl) window.open(flow.authUrl, "_blank");
2764
2774
  const pollTimer = window.setInterval(() => {
2765
2775
  (async () => {
2766
2776
  try {
2767
- const poll = await fetchApi$6("/login/status");
2777
+ const poll = await fetchApi$8("/login/status");
2768
2778
  if (poll.progress) setLoginProgress(poll.progress);
2769
2779
  if (poll.status === "complete") {
2770
2780
  window.clearInterval(pollTimer);
@@ -2796,7 +2806,7 @@ window.__ModuleLoader__.load({
2796
2806
  try {
2797
2807
  setBusy("apikey");
2798
2808
  setError(null);
2799
- const updated = await fetchApi$6("/login/apikey", {
2809
+ const updated = await fetchApi$8("/login/apikey", {
2800
2810
  method: "POST",
2801
2811
  body: JSON.stringify({ apiKey })
2802
2812
  });
@@ -2814,7 +2824,7 @@ window.__ModuleLoader__.load({
2814
2824
  try {
2815
2825
  setBusy(`${action}-${accountId}`);
2816
2826
  setError(null);
2817
- const updated = await fetchApi$6("/accounts", {
2827
+ const updated = await fetchApi$8("/accounts", {
2818
2828
  method: "POST",
2819
2829
  body: JSON.stringify({
2820
2830
  action,
@@ -2833,7 +2843,7 @@ window.__ModuleLoader__.load({
2833
2843
  try {
2834
2844
  setBusy("strategy");
2835
2845
  setError(null);
2836
- const updated = await fetchApi$6("/accounts", {
2846
+ const updated = await fetchApi$8("/accounts", {
2837
2847
  method: "POST",
2838
2848
  body: JSON.stringify({
2839
2849
  action: "strategy",
@@ -2856,7 +2866,7 @@ window.__ModuleLoader__.load({
2856
2866
  const handleRelogin = (accountId) => {
2857
2867
  (async () => {
2858
2868
  try {
2859
- const updated = await fetchApi$6("/accounts", {
2869
+ const updated = await fetchApi$8("/accounts", {
2860
2870
  method: "POST",
2861
2871
  body: JSON.stringify({
2862
2872
  action: "relogin",
@@ -2875,7 +2885,7 @@ window.__ModuleLoader__.load({
2875
2885
  try {
2876
2886
  setBusy("quota");
2877
2887
  setError(null);
2878
- const updated = await fetchApi$6("/quota", { method: "POST" });
2888
+ const updated = await fetchApi$8("/quota", { method: "POST" });
2879
2889
  setStatus(updated);
2880
2890
  } catch (err) {
2881
2891
  setError(err instanceof Error ? err.message : String(err));
@@ -2887,9 +2897,9 @@ window.__ModuleLoader__.load({
2887
2897
  try {
2888
2898
  setBusy("catalog");
2889
2899
  setError(null);
2890
- const updated = await fetchApi$6("/catalog/refresh", { method: "POST" });
2900
+ const updated = await fetchApi$8("/catalog/refresh", { method: "POST" });
2891
2901
  setStatus(updated);
2892
- setContextDrafts(contextDraftsFor$2(updated));
2902
+ setContextDrafts(contextDraftsFor$3(updated));
2893
2903
  notifyChange();
2894
2904
  } catch (err) {
2895
2905
  setError(err instanceof Error ? err.message : String(err));
@@ -2901,7 +2911,7 @@ window.__ModuleLoader__.load({
2901
2911
  try {
2902
2912
  setBusy("connection");
2903
2913
  setError(null);
2904
- await fetchApi$6("/connection/test", { method: "POST" });
2914
+ await fetchApi$8("/connection/test", { method: "POST" });
2905
2915
  await loadStatus(true);
2906
2916
  } catch (err) {
2907
2917
  setError(err instanceof Error ? err.message : String(err));
@@ -2911,12 +2921,12 @@ window.__ModuleLoader__.load({
2911
2921
  };
2912
2922
  const applyEnabled = async (enabledModelIds) => {
2913
2923
  try {
2914
- const updated = await fetchApi$6("/models", {
2924
+ const updated = await fetchApi$8("/models", {
2915
2925
  method: "POST",
2916
2926
  body: JSON.stringify({ enabledModelIds })
2917
2927
  });
2918
2928
  setStatus(updated);
2919
- setContextDrafts(contextDraftsFor$2(updated));
2929
+ setContextDrafts(contextDraftsFor$3(updated));
2920
2930
  notifyChange();
2921
2931
  } catch (err) {
2922
2932
  setError(err instanceof Error ? err.message : String(err));
@@ -2928,7 +2938,7 @@ window.__ModuleLoader__.load({
2928
2938
  enabled
2929
2939
  } : prev);
2930
2940
  try {
2931
- const updated = await fetchApi$6("/settings", {
2941
+ const updated = await fetchApi$8("/settings", {
2932
2942
  method: "POST",
2933
2943
  body: JSON.stringify({ enabled })
2934
2944
  });
@@ -2951,7 +2961,7 @@ window.__ModuleLoader__.load({
2951
2961
  };
2952
2962
  const handleUpdateEffort = async (effort) => {
2953
2963
  try {
2954
- const updated = await fetchApi$6("/settings", {
2964
+ const updated = await fetchApi$8("/settings", {
2955
2965
  method: "POST",
2956
2966
  body: JSON.stringify({ defaultReasoningEffort: effort })
2957
2967
  });
@@ -2963,7 +2973,7 @@ window.__ModuleLoader__.load({
2963
2973
  };
2964
2974
  const handleSaveContextWindow = async (modelId) => {
2965
2975
  const raw = contextDrafts[modelId] || "";
2966
- const parsed = parsePositiveCapacity$2(raw);
2976
+ const parsed = parsePositiveCapacity$3(raw);
2967
2977
  if (parsed === null) {
2968
2978
  setError(`Invalid context capacity: ${raw}`);
2969
2979
  return;
@@ -2971,14 +2981,14 @@ window.__ModuleLoader__.load({
2971
2981
  try {
2972
2982
  setSavingModel(modelId);
2973
2983
  setError(null);
2974
- const updated = await fetchApi$6("/settings", {
2984
+ const updated = await fetchApi$8("/settings", {
2975
2985
  method: "POST",
2976
2986
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
2977
2987
  });
2978
2988
  setStatus(updated);
2979
2989
  setContextDrafts((prev) => ({
2980
2990
  ...prev,
2981
- [modelId]: formatCapacity$2(parsed)
2991
+ [modelId]: formatCapacity$3(parsed)
2982
2992
  }));
2983
2993
  notifyChange();
2984
2994
  } catch (err) {
@@ -2992,7 +3002,7 @@ window.__ModuleLoader__.load({
2992
3002
  try {
2993
3003
  setSavingModel(modelId);
2994
3004
  setError(null);
2995
- const updated = await fetchApi$6("/settings", {
3005
+ const updated = await fetchApi$8("/settings", {
2996
3006
  method: "POST",
2997
3007
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
2998
3008
  });
@@ -3001,7 +3011,7 @@ window.__ModuleLoader__.load({
3001
3011
  const model = updated.models.find((candidate) => candidate.id === modelId);
3002
3012
  return model === void 0 ? prev : {
3003
3013
  ...prev,
3004
- [modelId]: formatCapacity$2(model.defaultContextWindow)
3014
+ [modelId]: formatCapacity$3(model.defaultContextWindow)
3005
3015
  };
3006
3016
  });
3007
3017
  notifyChange();
@@ -3019,12 +3029,12 @@ window.__ModuleLoader__.load({
3019
3029
  try {
3020
3030
  setBusy("context");
3021
3031
  setError(null);
3022
- const updated = await fetchApi$6("/settings", {
3032
+ const updated = await fetchApi$8("/settings", {
3023
3033
  method: "POST",
3024
3034
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
3025
3035
  });
3026
3036
  setStatus(updated);
3027
- setContextDrafts(contextDraftsFor$2(updated));
3037
+ setContextDrafts(contextDraftsFor$3(updated));
3028
3038
  notifyChange();
3029
3039
  } catch (err) {
3030
3040
  setError(err instanceof Error ? err.message : String(err));
@@ -3221,7 +3231,7 @@ window.__ModuleLoader__.load({
3221
3231
  children: t.defaultEffortAuto
3222
3232
  }), COMMAND_CODE_REASONING_EFFORTS.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
3223
3233
  value: effort,
3224
- children: EFFORT_LABELS$1[effort]
3234
+ children: EFFORT_LABELS$2[effort]
3225
3235
  }, effort))]
3226
3236
  })]
3227
3237
  })]
@@ -3338,7 +3348,7 @@ window.__ModuleLoader__.load({
3338
3348
  }),
3339
3349
  window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3340
3350
  className: "dsha-meter-meta",
3341
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$2(window.resetsAt)] })
3351
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$3(window.resetsAt)] })
3342
3352
  })
3343
3353
  ]
3344
3354
  }, window.id)),
@@ -3363,7 +3373,7 @@ window.__ModuleLoader__.load({
3363
3373
  meter.used ?? "—",
3364
3374
  " / ",
3365
3375
  meter.limit ?? "—"
3366
- ] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$2(meter.resetsAt)] })]
3376
+ ] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["Reset: ", formatReset$3(meter.resetsAt)] })]
3367
3377
  }) : meter.description !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3368
3378
  className: "dsha-meter-meta",
3369
3379
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.description })
@@ -3402,7 +3412,7 @@ window.__ModuleLoader__.load({
3402
3412
  //#endregion
3403
3413
  //#region src/client/kimi-code/locales.ts
3404
3414
  const NS_KIMI_CODE = "dsh-kimi-code";
3405
- const zh$2 = {
3415
+ const zh$3 = {
3406
3416
  ...accountPoolZh,
3407
3417
  title: "Kimi Code",
3408
3418
  pageDesc: "登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。",
@@ -3526,7 +3536,7 @@ window.__ModuleLoader__.load({
3526
3536
  requests: "次请求",
3527
3537
  tokens: "tokens"
3528
3538
  };
3529
- const en$2 = {
3539
+ const en$3 = {
3530
3540
  ...accountPoolEn,
3531
3541
  title: "Kimi Code",
3532
3542
  pageDesc: "Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.",
@@ -3650,11 +3660,11 @@ window.__ModuleLoader__.load({
3650
3660
  requests: "requests",
3651
3661
  tokens: "tokens"
3652
3662
  };
3653
- const dictionaries$2 = {
3654
- zh: zh$2,
3655
- "zh-CN": zh$2,
3656
- en: en$2,
3657
- "en-US": en$2
3663
+ const dictionaries$3 = {
3664
+ zh: zh$3,
3665
+ "zh-CN": zh$3,
3666
+ en: en$3,
3667
+ "en-US": en$3
3658
3668
  };
3659
3669
  //#endregion
3660
3670
  //#region src/client/kimi-code/KimiModelCapabilities.tsx
@@ -3667,7 +3677,7 @@ window.__ModuleLoader__.load({
3667
3677
  * Capabilities are now short tags in their own columns, with the per-model
3668
3678
  * detail kept in a hover title.
3669
3679
  */
3670
- const t = zh$2;
3680
+ const t = zh$3;
3671
3681
  function KimiModelCapabilities({ models }) {
3672
3682
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3673
3683
  className: "dsha-cap-table",
@@ -3711,9 +3721,9 @@ window.__ModuleLoader__.load({
3711
3721
  }
3712
3722
  //#endregion
3713
3723
  //#region src/client/kimi-code/KimiCodeSection.tsx
3714
- const API$5 = "/kimi-code/api";
3715
- async function fetchApi$5(path, options) {
3716
- const res = await fetch(`${API$5}${path}`, {
3724
+ const API$7 = "/kimi-code/api";
3725
+ async function fetchApi$7(path, options) {
3726
+ const res = await fetch(`${API$7}${path}`, {
3717
3727
  ...options,
3718
3728
  headers: {
3719
3729
  "Content-Type": "application/json",
@@ -3725,14 +3735,14 @@ window.__ModuleLoader__.load({
3725
3735
  return json.value;
3726
3736
  }
3727
3737
  /** Parse "1M", "512K", "200000" into a positive integer token count. */
3728
- function parsePositiveCapacity$1(value) {
3738
+ function parsePositiveCapacity$2(value) {
3729
3739
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
3730
3740
  if (matched === null) return null;
3731
3741
  const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
3732
3742
  const parsed = Number(matched[1]) * multiplier;
3733
3743
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
3734
3744
  }
3735
- function formatCapacity$1(value) {
3745
+ function formatCapacity$2(value) {
3736
3746
  if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
3737
3747
  if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
3738
3748
  return String(value);
@@ -3742,12 +3752,12 @@ window.__ModuleLoader__.load({
3742
3752
  * toggle: a model that was just enabled has no draft yet, and the context
3743
3753
  * window section only renders enabled models.
3744
3754
  */
3745
- function contextDraftsFor$1(status) {
3755
+ function contextDraftsFor$2(status) {
3746
3756
  const drafts = {};
3747
- for (const model of status.models) drafts[model.id] = formatCapacity$1(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
3757
+ for (const model of status.models) drafts[model.id] = formatCapacity$2(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
3748
3758
  return drafts;
3749
3759
  }
3750
- function formatDate$1(ms) {
3760
+ function formatDate$2(ms) {
3751
3761
  if (ms === void 0 || ms === null || ms <= 0) return "—";
3752
3762
  try {
3753
3763
  return new Intl.DateTimeFormat(void 0, {
@@ -3758,7 +3768,7 @@ window.__ModuleLoader__.load({
3758
3768
  return "—";
3759
3769
  }
3760
3770
  }
3761
- function formatReset$1(resetsAt) {
3771
+ function formatReset$2(resetsAt) {
3762
3772
  if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
3763
3773
  const diff = resetsAt - Date.now();
3764
3774
  if (diff <= 0) return "now";
@@ -3783,10 +3793,10 @@ window.__ModuleLoader__.load({
3783
3793
  }
3784
3794
  }
3785
3795
  const EFFORT_LABEL = {
3786
- low: zh$2.effortLow,
3787
- high: zh$2.effortHigh,
3788
- max: zh$2.effortMax,
3789
- none: zh$2.effortNone
3796
+ low: zh$3.effortLow,
3797
+ high: zh$3.effortHigh,
3798
+ max: zh$3.effortMax,
3799
+ none: zh$3.effortNone
3790
3800
  };
3791
3801
  /** Human label for the last request's prefix-drift cause. */
3792
3802
  function driftLabel(cause, t) {
@@ -3810,7 +3820,7 @@ window.__ModuleLoader__.load({
3810
3820
  const [savingModel, setSavingModel] = (0, react.useState)(null);
3811
3821
  const [copied, setCopied] = (0, react.useState)(false);
3812
3822
  const [connectionNotice, setConnectionNotice] = (0, react.useState)(null);
3813
- const t = zh$2;
3823
+ const t = zh$3;
3814
3824
  const notifyChange = (0, react.useCallback)(() => {
3815
3825
  onModelChange?.();
3816
3826
  loadModelDirectory?.();
@@ -3818,9 +3828,9 @@ window.__ModuleLoader__.load({
3818
3828
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
3819
3829
  if (!quiet) setError(null);
3820
3830
  try {
3821
- const data = await fetchApi$5("/status");
3831
+ const data = await fetchApi$7("/status");
3822
3832
  setStatus(data);
3823
- setContextDrafts(contextDraftsFor$1(data));
3833
+ setContextDrafts(contextDraftsFor$2(data));
3824
3834
  } catch (err) {
3825
3835
  if (!quiet) setError(err instanceof Error ? err.message : String(err));
3826
3836
  } finally {
@@ -3844,7 +3854,7 @@ window.__ModuleLoader__.load({
3844
3854
  const timer = window.setInterval(() => {
3845
3855
  (async () => {
3846
3856
  try {
3847
- const poll = await fetchApi$5("/login/status");
3857
+ const poll = await fetchApi$7("/login/status");
3848
3858
  setFlow(poll);
3849
3859
  if (poll.status === "complete") {
3850
3860
  await loadStatus();
@@ -3865,7 +3875,7 @@ window.__ModuleLoader__.load({
3865
3875
  setBusy("login");
3866
3876
  setError(null);
3867
3877
  setCopied(false);
3868
- const next = await fetchApi$5("/login", {
3878
+ const next = await fetchApi$7("/login", {
3869
3879
  method: "POST",
3870
3880
  body: JSON.stringify({})
3871
3881
  });
@@ -3878,7 +3888,7 @@ window.__ModuleLoader__.load({
3878
3888
  };
3879
3889
  const handleCancelLogin = async () => {
3880
3890
  try {
3881
- await fetchApi$5("/login/cancel", { method: "POST" });
3891
+ await fetchApi$7("/login/cancel", { method: "POST" });
3882
3892
  setFlow({ status: "idle" });
3883
3893
  } catch (err) {
3884
3894
  setError(err instanceof Error ? err.message : String(err));
@@ -3898,7 +3908,7 @@ window.__ModuleLoader__.load({
3898
3908
  try {
3899
3909
  setBusy(`${action}-${accountId}`);
3900
3910
  setError(null);
3901
- const updated = await fetchApi$5("/accounts", {
3911
+ const updated = await fetchApi$7("/accounts", {
3902
3912
  method: "POST",
3903
3913
  body: JSON.stringify({
3904
3914
  action,
@@ -3918,7 +3928,7 @@ window.__ModuleLoader__.load({
3918
3928
  try {
3919
3929
  setBusy("strategy");
3920
3930
  setError(null);
3921
- const updated = await fetchApi$5("/accounts", {
3931
+ const updated = await fetchApi$7("/accounts", {
3922
3932
  method: "POST",
3923
3933
  body: JSON.stringify({
3924
3934
  action: "strategy",
@@ -3941,7 +3951,7 @@ window.__ModuleLoader__.load({
3941
3951
  const handleRelogin = (accountId) => {
3942
3952
  (async () => {
3943
3953
  try {
3944
- const updated = await fetchApi$5("/accounts", {
3954
+ const updated = await fetchApi$7("/accounts", {
3945
3955
  method: "POST",
3946
3956
  body: JSON.stringify({
3947
3957
  action: "relogin",
@@ -3960,7 +3970,7 @@ window.__ModuleLoader__.load({
3960
3970
  try {
3961
3971
  setBusy("quota");
3962
3972
  setError(null);
3963
- const updated = await fetchApi$5("/quota", { method: "POST" });
3973
+ const updated = await fetchApi$7("/quota", { method: "POST" });
3964
3974
  setStatus(updated);
3965
3975
  } catch (err) {
3966
3976
  setError(err instanceof Error ? err.message : String(err));
@@ -3973,9 +3983,9 @@ window.__ModuleLoader__.load({
3973
3983
  try {
3974
3984
  setBusy("catalog");
3975
3985
  setError(null);
3976
- const updated = await fetchApi$5("/catalog/refresh", { method: "POST" });
3986
+ const updated = await fetchApi$7("/catalog/refresh", { method: "POST" });
3977
3987
  setStatus(updated);
3978
- setContextDrafts(contextDraftsFor$1(updated));
3988
+ setContextDrafts(contextDraftsFor$2(updated));
3979
3989
  notifyChange();
3980
3990
  } catch (err) {
3981
3991
  setError(err instanceof Error ? err.message : String(err));
@@ -3988,7 +3998,7 @@ window.__ModuleLoader__.load({
3988
3998
  setBusy("connection");
3989
3999
  setError(null);
3990
4000
  setConnectionNotice(null);
3991
- const result = await fetchApi$5("/connection/test", { method: "POST" });
4001
+ const result = await fetchApi$7("/connection/test", { method: "POST" });
3992
4002
  setConnectionNotice(result.connected ? `${t.testSuccess} · ${result.latencyMs} ms` : t.testFailed);
3993
4003
  await loadStatus(true);
3994
4004
  } catch (err) {
@@ -3999,12 +4009,12 @@ window.__ModuleLoader__.load({
3999
4009
  };
4000
4010
  const applyEnabled = async (enabledModelIds) => {
4001
4011
  try {
4002
- const updated = await fetchApi$5("/models", {
4012
+ const updated = await fetchApi$7("/models", {
4003
4013
  method: "POST",
4004
4014
  body: JSON.stringify({ enabledModelIds })
4005
4015
  });
4006
4016
  setStatus(updated);
4007
- setContextDrafts(contextDraftsFor$1(updated));
4017
+ setContextDrafts(contextDraftsFor$2(updated));
4008
4018
  notifyChange();
4009
4019
  } catch (err) {
4010
4020
  setError(err instanceof Error ? err.message : String(err));
@@ -4016,7 +4026,7 @@ window.__ModuleLoader__.load({
4016
4026
  enabled
4017
4027
  } : prev);
4018
4028
  try {
4019
- const updated = await fetchApi$5("/settings", {
4029
+ const updated = await fetchApi$7("/settings", {
4020
4030
  method: "POST",
4021
4031
  body: JSON.stringify({ enabled })
4022
4032
  });
@@ -4039,7 +4049,7 @@ window.__ModuleLoader__.load({
4039
4049
  };
4040
4050
  const handleUpdateEffort = async (effort) => {
4041
4051
  try {
4042
- const updated = await fetchApi$5("/settings", {
4052
+ const updated = await fetchApi$7("/settings", {
4043
4053
  method: "POST",
4044
4054
  body: JSON.stringify({ defaultReasoningEffort: effort })
4045
4055
  });
@@ -4051,7 +4061,7 @@ window.__ModuleLoader__.load({
4051
4061
  };
4052
4062
  const handleSaveContextWindow = async (modelId) => {
4053
4063
  const raw = contextDrafts[modelId] || "";
4054
- const parsed = parsePositiveCapacity$1(raw);
4064
+ const parsed = parsePositiveCapacity$2(raw);
4055
4065
  if (parsed === null) {
4056
4066
  setError(`Invalid context capacity: ${raw}`);
4057
4067
  return;
@@ -4059,14 +4069,14 @@ window.__ModuleLoader__.load({
4059
4069
  try {
4060
4070
  setSavingModel(modelId);
4061
4071
  setError(null);
4062
- const updated = await fetchApi$5("/settings", {
4072
+ const updated = await fetchApi$7("/settings", {
4063
4073
  method: "POST",
4064
4074
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
4065
4075
  });
4066
4076
  setStatus(updated);
4067
4077
  setContextDrafts((prev) => ({
4068
4078
  ...prev,
4069
- [modelId]: formatCapacity$1(parsed)
4079
+ [modelId]: formatCapacity$2(parsed)
4070
4080
  }));
4071
4081
  notifyChange();
4072
4082
  } catch (err) {
@@ -4080,7 +4090,7 @@ window.__ModuleLoader__.load({
4080
4090
  try {
4081
4091
  setSavingModel(modelId);
4082
4092
  setError(null);
4083
- const updated = await fetchApi$5("/settings", {
4093
+ const updated = await fetchApi$7("/settings", {
4084
4094
  method: "POST",
4085
4095
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
4086
4096
  });
@@ -4089,7 +4099,7 @@ window.__ModuleLoader__.load({
4089
4099
  const model = updated.models.find((candidate) => candidate.id === modelId);
4090
4100
  return model === void 0 ? prev : {
4091
4101
  ...prev,
4092
- [modelId]: formatCapacity$1(model.defaultContextWindow)
4102
+ [modelId]: formatCapacity$2(model.defaultContextWindow)
4093
4103
  };
4094
4104
  });
4095
4105
  notifyChange();
@@ -4107,12 +4117,12 @@ window.__ModuleLoader__.load({
4107
4117
  try {
4108
4118
  setBusy("context");
4109
4119
  setError(null);
4110
- const updated = await fetchApi$5("/settings", {
4120
+ const updated = await fetchApi$7("/settings", {
4111
4121
  method: "POST",
4112
4122
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
4113
4123
  });
4114
4124
  setStatus(updated);
4115
- setContextDrafts(contextDraftsFor$1(updated));
4125
+ setContextDrafts(contextDraftsFor$2(updated));
4116
4126
  notifyChange();
4117
4127
  } catch (err) {
4118
4128
  setError(err instanceof Error ? err.message : String(err));
@@ -4200,7 +4210,7 @@ window.__ModuleLoader__.load({
4200
4210
  children: t.codeExpires
4201
4211
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4202
4212
  className: "dsha-value",
4203
- children: formatDate$1(flow?.expiresAt)
4213
+ children: formatDate$2(flow?.expiresAt)
4204
4214
  })]
4205
4215
  }),
4206
4216
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
@@ -4481,7 +4491,7 @@ window.__ModuleLoader__.load({
4481
4491
  title: model.id,
4482
4492
  children: [model.name, model.defaultContextWindow < model.contextWindow && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4483
4493
  className: "dsha-model-meta",
4484
- children: formatCapacity$1(model.contextWindow)
4494
+ children: formatCapacity$2(model.contextWindow)
4485
4495
  })]
4486
4496
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4487
4497
  className: "dsha-capacity-control",
@@ -4584,7 +4594,7 @@ window.__ModuleLoader__.load({
4584
4594
  window.limit ?? "—",
4585
4595
  " ",
4586
4596
  t.requests
4587
- ] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.resetAt.replace("{time}", formatReset$1(window.resetsAt)) })]
4597
+ ] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.resetAt.replace("{time}", formatReset$2(window.resetsAt)) })]
4588
4598
  })
4589
4599
  ]
4590
4600
  }, window.id);
@@ -4636,7 +4646,7 @@ window.__ModuleLoader__.load({
4636
4646
  //#endregion
4637
4647
  //#region src/client/workbuddy/locales.ts
4638
4648
  const NS_WORKBUDDY = "dsh-workbuddy";
4639
- const zh$1 = {
4649
+ const zh$2 = {
4640
4650
  title: "WorkBuddy",
4641
4651
  pageDesc: "复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。",
4642
4652
  account: "账号",
@@ -4718,9 +4728,19 @@ window.__ModuleLoader__.load({
4718
4728
  updatedAt: "更新时间:{time}",
4719
4729
  loading: "加载中...",
4720
4730
  credits: "credits",
4721
- composerLabel: "额度"
4731
+ composerLabel: "额度",
4732
+ dailyCheckin: "每日签到",
4733
+ checkinHint: "仅国区账号参与;DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。",
4734
+ checkinAuto: "自动签到",
4735
+ checkinToday: "今日已签 {done}/{total}",
4736
+ checkinSkipped: "{count} 个无签到活动",
4737
+ checkinFailed: "{count} 个失败",
4738
+ checkinLastRun: "上次运行:{time}",
4739
+ checkinNever: "尚未运行",
4740
+ checkinNow: "立即签到",
4741
+ checkinRunning: "签到中…"
4722
4742
  };
4723
- const en$1 = {
4743
+ const en$2 = {
4724
4744
  title: "WorkBuddy",
4725
4745
  pageDesc: "Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.",
4726
4746
  account: "Account",
@@ -4802,13 +4822,23 @@ window.__ModuleLoader__.load({
4802
4822
  updatedAt: "Updated at: {time}",
4803
4823
  loading: "Loading...",
4804
4824
  credits: "credits",
4805
- composerLabel: "Quota"
4825
+ composerLabel: "Quota",
4826
+ dailyCheckin: "Daily check-in",
4827
+ checkinHint: "CN-region accounts only. The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.",
4828
+ checkinAuto: "Auto check-in",
4829
+ checkinToday: "Checked in today {done}/{total}",
4830
+ checkinSkipped: "{count} with no activity",
4831
+ checkinFailed: "{count} failed",
4832
+ checkinLastRun: "Last run: {time}",
4833
+ checkinNever: "Never run",
4834
+ checkinNow: "Check in now",
4835
+ checkinRunning: "Checking in…"
4806
4836
  };
4807
- const dictionaries$1 = {
4808
- zh: zh$1,
4809
- "zh-CN": zh$1,
4810
- en: en$1,
4811
- "en-US": en$1
4837
+ const dictionaries$2 = {
4838
+ zh: zh$2,
4839
+ "zh-CN": zh$2,
4840
+ en: en$2,
4841
+ "en-US": en$2
4812
4842
  };
4813
4843
  //#endregion
4814
4844
  //#region src/client/workbuddy/WorkBuddySection.tsx
@@ -4816,7 +4846,7 @@ window.__ModuleLoader__.load({
4816
4846
  * Display label per reasoning level. The locale dictionary only accepts flat
4817
4847
  * string values, so this nested table lives with the control that renders it.
4818
4848
  */
4819
- const EFFORT_LABELS = {
4849
+ const EFFORT_LABELS$1 = {
4820
4850
  minimal: "Minimal",
4821
4851
  low: "Low",
4822
4852
  medium: "Medium",
@@ -4824,7 +4854,7 @@ window.__ModuleLoader__.load({
4824
4854
  xhigh: "X-High",
4825
4855
  max: "Max"
4826
4856
  };
4827
- const API$4 = "/workbuddy/api";
4857
+ const API$6 = "/workbuddy/api";
4828
4858
  /**
4829
4859
  * The shared card's label set.
4830
4860
  *
@@ -4850,8 +4880,8 @@ window.__ModuleLoader__.load({
4850
4880
  * process (a stale Host has no route to answer), so the error is reported as
4851
4881
  * such instead of as a credential problem.
4852
4882
  */
4853
- async function fetchApi$4(path, options) {
4854
- const res = await fetch(`${API$4}${path}`, {
4883
+ async function fetchApi$6(path, options) {
4884
+ const res = await fetch(`${API$6}${path}`, {
4855
4885
  ...options,
4856
4886
  headers: {
4857
4887
  "Content-Type": "application/json",
@@ -4870,14 +4900,14 @@ window.__ModuleLoader__.load({
4870
4900
  return json.value;
4871
4901
  }
4872
4902
  /** Parse "1M", "512K", "200000" into a positive integer token count. */
4873
- function parsePositiveCapacity(value) {
4903
+ function parsePositiveCapacity$1(value) {
4874
4904
  const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
4875
4905
  if (matched === null) return null;
4876
4906
  const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
4877
4907
  const parsed = Number(matched[1]) * multiplier;
4878
4908
  return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
4879
4909
  }
4880
- function formatCapacity(value) {
4910
+ function formatCapacity$1(value) {
4881
4911
  if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
4882
4912
  if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
4883
4913
  return String(value);
@@ -4887,12 +4917,12 @@ window.__ModuleLoader__.load({
4887
4917
  * toggle: a model that was just enabled has no draft yet, and the context
4888
4918
  * window section only renders enabled models.
4889
4919
  */
4890
- function contextDraftsFor(status) {
4920
+ function contextDraftsFor$1(status) {
4891
4921
  const drafts = {};
4892
- for (const model of status.models) drafts[model.id] = formatCapacity(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
4922
+ for (const model of status.models) drafts[model.id] = formatCapacity$1(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
4893
4923
  return drafts;
4894
4924
  }
4895
- function formatDate(ms) {
4925
+ function formatDate$1(ms) {
4896
4926
  if (ms === void 0 || ms === null || ms <= 0) return "—";
4897
4927
  try {
4898
4928
  return new Intl.DateTimeFormat(void 0, {
@@ -4903,7 +4933,7 @@ window.__ModuleLoader__.load({
4903
4933
  return "—";
4904
4934
  }
4905
4935
  }
4906
- function formatReset(resetsAt) {
4936
+ function formatReset$1(resetsAt) {
4907
4937
  if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
4908
4938
  const diff = resetsAt - Date.now();
4909
4939
  if (diff <= 0) return "now";
@@ -4980,7 +5010,7 @@ window.__ModuleLoader__.load({
4980
5010
  const loginTimeoutRef = (0, react.useRef)(null);
4981
5011
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
4982
5012
  const [savingModel, setSavingModel] = (0, react.useState)(null);
4983
- const t = zh$1;
5013
+ const t = zh$2;
4984
5014
  const notifyChange = (0, react.useCallback)(() => {
4985
5015
  onModelChange?.();
4986
5016
  loadModelDirectory?.();
@@ -4992,10 +5022,10 @@ window.__ModuleLoader__.load({
4992
5022
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
4993
5023
  if (!quiet) setError(null);
4994
5024
  try {
4995
- const normalized = normalizeStatus(await fetchApi$4("/status"));
5025
+ const normalized = normalizeStatus(await fetchApi$6("/status"));
4996
5026
  setStatus(normalized);
4997
5027
  setStatusFailed(false);
4998
- setContextDrafts(contextDraftsFor(normalized));
5028
+ setContextDrafts(contextDraftsFor$1(normalized));
4999
5029
  } catch (err) {
5000
5030
  setStatusFailed(true);
5001
5031
  if (!quiet) setError(err instanceof Error ? err.message : String(err));
@@ -5019,7 +5049,7 @@ window.__ModuleLoader__.load({
5019
5049
  try {
5020
5050
  setBusy("rescan");
5021
5051
  setError(null);
5022
- const updated = await fetchApi$4("/rescan", { method: "POST" });
5052
+ const updated = await fetchApi$6("/rescan", { method: "POST" });
5023
5053
  setStatus(normalizeStatus(updated));
5024
5054
  notifyChange();
5025
5055
  } catch (err) {
@@ -5033,7 +5063,7 @@ window.__ModuleLoader__.load({
5033
5063
  setBusy(`login:${region}`);
5034
5064
  setError(null);
5035
5065
  setLoginProgress(t.loginWaiting);
5036
- const flow = await fetchApi$4("/accounts/login", {
5066
+ const flow = await fetchApi$6("/accounts/login", {
5037
5067
  method: "POST",
5038
5068
  body: JSON.stringify({ region })
5039
5069
  });
@@ -5043,7 +5073,7 @@ window.__ModuleLoader__.load({
5043
5073
  const timer = window.setInterval(() => {
5044
5074
  (async () => {
5045
5075
  try {
5046
- const poll = await fetchApi$4("/accounts/login/status");
5076
+ const poll = await fetchApi$6("/accounts/login/status");
5047
5077
  if (poll.progress) setLoginProgress(poll.progress);
5048
5078
  if (poll.status === "complete") {
5049
5079
  window.clearInterval(timer);
@@ -5052,7 +5082,7 @@ window.__ModuleLoader__.load({
5052
5082
  loginTimeoutRef.current = null;
5053
5083
  setBusy(null);
5054
5084
  setLoginProgress(null);
5055
- if (poll.accountId) await fetchApi$4("/settings", {
5085
+ if (poll.accountId) await fetchApi$6("/settings", {
5056
5086
  method: "POST",
5057
5087
  body: JSON.stringify({ selectedAccountId: poll.accountId })
5058
5088
  });
@@ -5092,7 +5122,7 @@ window.__ModuleLoader__.load({
5092
5122
  try {
5093
5123
  setBusy(`${action}:${accountId}`);
5094
5124
  setError(null);
5095
- const updated = await fetchApi$4("/accounts/action", {
5125
+ const updated = await fetchApi$6("/accounts/action", {
5096
5126
  method: "POST",
5097
5127
  body: JSON.stringify({
5098
5128
  action,
@@ -5115,7 +5145,7 @@ window.__ModuleLoader__.load({
5115
5145
  try {
5116
5146
  setBusy("strategy");
5117
5147
  setError(null);
5118
- const updated = await fetchApi$4("/accounts/strategy", {
5148
+ const updated = await fetchApi$6("/accounts/strategy", {
5119
5149
  method: "POST",
5120
5150
  body: JSON.stringify({ strategy })
5121
5151
  });
@@ -5130,7 +5160,7 @@ window.__ModuleLoader__.load({
5130
5160
  try {
5131
5161
  setBusy("connection");
5132
5162
  setError(null);
5133
- setConnection(await fetchApi$4("/connection/test", { method: "POST" }));
5163
+ setConnection(await fetchApi$6("/connection/test", { method: "POST" }));
5134
5164
  } catch (err) {
5135
5165
  setError(err instanceof Error ? err.message : String(err));
5136
5166
  } finally {
@@ -5141,7 +5171,7 @@ window.__ModuleLoader__.load({
5141
5171
  try {
5142
5172
  setBusy("quota");
5143
5173
  setError(null);
5144
- const updated = await fetchApi$4("/quota", { method: "POST" });
5174
+ const updated = await fetchApi$6("/quota", { method: "POST" });
5145
5175
  setStatus(updated);
5146
5176
  } catch (err) {
5147
5177
  setError(err instanceof Error ? err.message : String(err));
@@ -5149,11 +5179,38 @@ window.__ModuleLoader__.load({
5149
5179
  setBusy(null);
5150
5180
  }
5151
5181
  };
5182
+ const handleCheckinNow = async () => {
5183
+ try {
5184
+ setBusy("checkin");
5185
+ setError(null);
5186
+ const updated = await fetchApi$6("/checkin/now", { method: "POST" });
5187
+ setStatus(normalizeStatus(updated));
5188
+ } catch (err) {
5189
+ setError(err instanceof Error ? err.message : String(err));
5190
+ } finally {
5191
+ setBusy(null);
5192
+ }
5193
+ };
5194
+ const handleCheckinPatch = async (checkin) => {
5195
+ try {
5196
+ setBusy("checkin");
5197
+ setError(null);
5198
+ const updated = await fetchApi$6("/settings", {
5199
+ method: "POST",
5200
+ body: JSON.stringify({ checkin })
5201
+ });
5202
+ setStatus(normalizeStatus(updated));
5203
+ } catch (err) {
5204
+ setError(err instanceof Error ? err.message : String(err));
5205
+ } finally {
5206
+ setBusy(null);
5207
+ }
5208
+ };
5152
5209
  const toggleEnabled = async (enabled) => {
5153
5210
  try {
5154
5211
  setBusy("enabled");
5155
5212
  setError(null);
5156
- const updated = await fetchApi$4("/settings", {
5213
+ const updated = await fetchApi$6("/settings", {
5157
5214
  method: "POST",
5158
5215
  body: JSON.stringify({ enabled })
5159
5216
  });
@@ -5172,12 +5229,12 @@ window.__ModuleLoader__.load({
5172
5229
  try {
5173
5230
  setBusy(`model:${modelId}`);
5174
5231
  setError(null);
5175
- const normalized = normalizeStatus(await fetchApi$4("/settings", {
5232
+ const normalized = normalizeStatus(await fetchApi$6("/settings", {
5176
5233
  method: "POST",
5177
5234
  body: JSON.stringify({ enabledModelIds: next })
5178
5235
  }));
5179
5236
  setStatus(normalized);
5180
- setContextDrafts(contextDraftsFor(normalized));
5237
+ setContextDrafts(contextDraftsFor$1(normalized));
5181
5238
  notifyChange();
5182
5239
  } catch (err) {
5183
5240
  setError(err instanceof Error ? err.message : String(err));
@@ -5190,12 +5247,12 @@ window.__ModuleLoader__.load({
5190
5247
  try {
5191
5248
  setBusy("models-all");
5192
5249
  setError(null);
5193
- const normalized = normalizeStatus(await fetchApi$4("/settings", {
5250
+ const normalized = normalizeStatus(await fetchApi$6("/settings", {
5194
5251
  method: "POST",
5195
5252
  body: JSON.stringify({ enabledModelIds: enabled ? status.models.map((model) => model.id) : [] })
5196
5253
  }));
5197
5254
  setStatus(normalized);
5198
- setContextDrafts(contextDraftsFor(normalized));
5255
+ setContextDrafts(contextDraftsFor$1(normalized));
5199
5256
  notifyChange();
5200
5257
  } catch (err) {
5201
5258
  setError(err instanceof Error ? err.message : String(err));
@@ -5207,7 +5264,7 @@ window.__ModuleLoader__.load({
5207
5264
  try {
5208
5265
  setBusy("effort");
5209
5266
  setError(null);
5210
- const updated = await fetchApi$4("/settings", {
5267
+ const updated = await fetchApi$6("/settings", {
5211
5268
  method: "POST",
5212
5269
  body: JSON.stringify({ defaultReasoningEffort: effort })
5213
5270
  });
@@ -5223,9 +5280,9 @@ window.__ModuleLoader__.load({
5223
5280
  try {
5224
5281
  setBusy("catalog");
5225
5282
  setError(null);
5226
- const normalized = normalizeStatus(await fetchApi$4("/catalog/refresh", { method: "POST" }));
5283
+ const normalized = normalizeStatus(await fetchApi$6("/catalog/refresh", { method: "POST" }));
5227
5284
  setStatus(normalized);
5228
- setContextDrafts(contextDraftsFor(normalized));
5285
+ setContextDrafts(contextDraftsFor$1(normalized));
5229
5286
  notifyChange();
5230
5287
  } catch (err) {
5231
5288
  setError(err instanceof Error ? err.message : String(err));
@@ -5235,7 +5292,7 @@ window.__ModuleLoader__.load({
5235
5292
  };
5236
5293
  const handleSaveContextWindow = async (modelId) => {
5237
5294
  const raw = contextDrafts[modelId] || "";
5238
- const parsed = parsePositiveCapacity(raw);
5295
+ const parsed = parsePositiveCapacity$1(raw);
5239
5296
  if (parsed === null) {
5240
5297
  setError(`Invalid context capacity: ${raw}`);
5241
5298
  return;
@@ -5243,14 +5300,14 @@ window.__ModuleLoader__.load({
5243
5300
  try {
5244
5301
  setSavingModel(modelId);
5245
5302
  setError(null);
5246
- const updated = await fetchApi$4("/settings", {
5303
+ const updated = await fetchApi$6("/settings", {
5247
5304
  method: "POST",
5248
5305
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
5249
5306
  });
5250
5307
  setStatus(updated);
5251
5308
  setContextDrafts((prev) => ({
5252
5309
  ...prev,
5253
- [modelId]: formatCapacity(parsed)
5310
+ [modelId]: formatCapacity$1(parsed)
5254
5311
  }));
5255
5312
  notifyChange();
5256
5313
  } catch (err) {
@@ -5264,7 +5321,7 @@ window.__ModuleLoader__.load({
5264
5321
  try {
5265
5322
  setSavingModel(modelId);
5266
5323
  setError(null);
5267
- const updated = normalizeStatus(await fetchApi$4("/settings", {
5324
+ const updated = normalizeStatus(await fetchApi$6("/settings", {
5268
5325
  method: "POST",
5269
5326
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
5270
5327
  }));
@@ -5273,7 +5330,7 @@ window.__ModuleLoader__.load({
5273
5330
  const model = updated.models.find((candidate) => candidate.id === modelId);
5274
5331
  return model === void 0 ? prev : {
5275
5332
  ...prev,
5276
- [modelId]: formatCapacity(model.defaultContextWindow)
5333
+ [modelId]: formatCapacity$1(model.defaultContextWindow)
5277
5334
  };
5278
5335
  });
5279
5336
  notifyChange();
@@ -5291,12 +5348,12 @@ window.__ModuleLoader__.load({
5291
5348
  try {
5292
5349
  setBusy("context");
5293
5350
  setError(null);
5294
- const updated = normalizeStatus(await fetchApi$4("/settings", {
5351
+ const updated = normalizeStatus(await fetchApi$6("/settings", {
5295
5352
  method: "POST",
5296
5353
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
5297
5354
  }));
5298
5355
  setStatus(updated);
5299
- setContextDrafts(contextDraftsFor(updated));
5356
+ setContextDrafts(contextDraftsFor$1(updated));
5300
5357
  notifyChange();
5301
5358
  } catch (err) {
5302
5359
  setError(err instanceof Error ? err.message : String(err));
@@ -5419,62 +5476,113 @@ window.__ModuleLoader__.load({
5419
5476
  })
5420
5477
  ]
5421
5478
  }),
5422
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5479
+ status?.checkin != null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5423
5480
  className: "dsha-group",
5424
5481
  children: [
5425
5482
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5426
5483
  className: "dsha-grouphead",
5427
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.connection })
5484
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.dailyCheckin })
5485
+ }),
5486
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5487
+ className: "dsha-muted",
5488
+ children: t.checkinHint
5428
5489
  }),
5429
5490
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5430
5491
  className: "dsha-row",
5431
- style: { marginBottom: 12 },
5492
+ style: { marginBottom: 8 },
5432
5493
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5433
5494
  className: "dsha-label",
5434
5495
  style: { fontWeight: 600 },
5435
- children: t.enableProvider
5496
+ children: t.checkinAuto
5436
5497
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
5437
5498
  type: "checkbox",
5438
- checked: status?.enabled !== false,
5499
+ checked: status.checkin.enabled,
5439
5500
  disabled: busy !== null,
5440
- onChange: (e) => void toggleEnabled(e.currentTarget.checked)
5441
- })]
5442
- }),
5443
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5444
- className: "dsha-row",
5445
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5446
- className: "dsha-label",
5447
- children: t.provider
5448
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5449
- className: "dsha-value",
5450
- children: t.providerValue
5501
+ onChange: (event) => void handleCheckinPatch({ enabled: event.currentTarget.checked })
5451
5502
  })]
5452
5503
  }),
5453
5504
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5454
5505
  className: "dsha-row",
5455
5506
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5456
5507
  className: "dsha-label",
5457
- children: t.connectionState
5508
+ children: t.dailyCheckin
5458
5509
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5459
5510
  className: "dsha-value",
5460
- children: [connection?.connected ? t.connected : authenticated ? t.untested : t.signedOut, connection?.connected ? ` · ${connection.latencyMs}ms · ${connection.model}` : ""]
5511
+ children: [
5512
+ t.checkinToday.replace("{done}", String(status.checkin.doneToday)).replace("{total}", String(status.checkin.totalAccounts)),
5513
+ status.checkin.skippedToday > 0 ? ` · ${t.checkinSkipped.replace("{count}", String(status.checkin.skippedToday))}` : "",
5514
+ status.checkin.failedToday > 0 ? ` · ${t.checkinFailed.replace("{count}", String(status.checkin.failedToday))}` : "",
5515
+ ` · ${status.checkin.lastRunAt === null ? t.checkinNever : t.checkinLastRun.replace("{time}", new Date(status.checkin.lastRunAt).toLocaleString())}`
5516
+ ]
5461
5517
  })]
5462
5518
  }),
5463
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5464
- className: "dsha-notice",
5465
- children: status?.serving === false && status.conflict ? t.routeConflict.replace("{detail}", status.conflict) : t.routeOwned
5466
- }),
5467
5519
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5468
5520
  className: "dsha-actions",
5469
5521
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5470
5522
  className: "dsha-btn",
5471
- disabled: busy !== null || !authenticated,
5472
- onClick: () => void handleTestConnection(),
5473
- children: busy === "connection" ? t.testingConnection : t.testConnection
5523
+ disabled: busy !== null,
5524
+ onClick: () => void handleCheckinNow(),
5525
+ children: busy === "checkin" ? t.checkinRunning : t.checkinNow
5474
5526
  })
5475
5527
  })
5476
5528
  ]
5477
- }),
5529
+ }) : null,
5530
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5531
+ className: "dsha-group",
5532
+ children: [
5533
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5534
+ className: "dsha-grouphead",
5535
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.connection })
5536
+ }),
5537
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5538
+ className: "dsha-row",
5539
+ style: { marginBottom: 12 },
5540
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5541
+ className: "dsha-label",
5542
+ style: { fontWeight: 600 },
5543
+ children: t.enableProvider
5544
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
5545
+ type: "checkbox",
5546
+ checked: status?.enabled !== false,
5547
+ disabled: busy !== null,
5548
+ onChange: (e) => void toggleEnabled(e.currentTarget.checked)
5549
+ })]
5550
+ }),
5551
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5552
+ className: "dsha-row",
5553
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5554
+ className: "dsha-label",
5555
+ children: t.provider
5556
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5557
+ className: "dsha-value",
5558
+ children: t.providerValue
5559
+ })]
5560
+ }),
5561
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5562
+ className: "dsha-row",
5563
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5564
+ className: "dsha-label",
5565
+ children: t.connectionState
5566
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5567
+ className: "dsha-value",
5568
+ children: [connection?.connected ? t.connected : authenticated ? t.untested : t.signedOut, connection?.connected ? ` · ${connection.latencyMs}ms · ${connection.model}` : ""]
5569
+ })]
5570
+ }),
5571
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5572
+ className: "dsha-notice",
5573
+ children: status?.serving === false && status.conflict ? t.routeConflict.replace("{detail}", status.conflict) : t.routeOwned
5574
+ }),
5575
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5576
+ className: "dsha-actions",
5577
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5578
+ className: "dsha-btn",
5579
+ disabled: busy !== null || !authenticated,
5580
+ onClick: () => void handleTestConnection(),
5581
+ children: busy === "connection" ? t.testingConnection : t.testConnection
5582
+ })
5583
+ })
5584
+ ]
5585
+ }),
5478
5586
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5479
5587
  className: "dsha-group",
5480
5588
  children: [
@@ -5498,7 +5606,7 @@ window.__ModuleLoader__.load({
5498
5606
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
5499
5607
  title: [
5500
5608
  model.id,
5501
- formatCapacity(model.contextWindow),
5609
+ formatCapacity$1(model.contextWindow),
5502
5610
  model.supportsImage ? t.imageSupport : t.textOnly,
5503
5611
  ...model.reasoningEfforts && model.reasoningEfforts.length > 0 ? [model.reasoningEfforts.join("/")] : []
5504
5612
  ].join(" · "),
@@ -5562,11 +5670,11 @@ window.__ModuleLoader__.load({
5562
5670
  }),
5563
5671
  strayEffort !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5564
5672
  value: strayEffort,
5565
- children: `${EFFORT_LABELS[strayEffort]} (${t.effortUnsupported})`
5673
+ children: `${EFFORT_LABELS$1[strayEffort]} (${t.effortUnsupported})`
5566
5674
  }) : null,
5567
5675
  effortChoices.map((choice) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
5568
5676
  value: choice.value,
5569
- children: choice.models.length === allModels.length ? EFFORT_LABELS[choice.value] : `${EFFORT_LABELS[choice.value]} (${choice.models.length}/${allModels.length})`
5677
+ children: choice.models.length === allModels.length ? EFFORT_LABELS$1[choice.value] : `${EFFORT_LABELS$1[choice.value]} (${choice.models.length}/${allModels.length})`
5570
5678
  }, choice.value))
5571
5679
  ]
5572
5680
  })]
@@ -5615,7 +5723,933 @@ window.__ModuleLoader__.load({
5615
5723
  if (event.key === "Enter") handleSaveContextWindow(model.id);
5616
5724
  }
5617
5725
  }),
5618
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "tokens" }),
5726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: "tokens" }),
5727
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5728
+ type: "button",
5729
+ className: "dsha-context-save",
5730
+ disabled: savingModel === model.id,
5731
+ onClick: () => void handleSaveContextWindow(model.id),
5732
+ children: savingModel === model.id ? t.saving : t.save
5733
+ }),
5734
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5735
+ type: "button",
5736
+ className: "dsha-context-save dsha-context-reset",
5737
+ "aria-label": `${model.name} ${t.contextWindowReset}`,
5738
+ disabled: savingModel === model.id || status?.contextWindowOverrides[model.id] === void 0,
5739
+ onClick: () => void handleResetContextWindow(model.id),
5740
+ children: t.contextWindowReset
5741
+ })
5742
+ ]
5743
+ })]
5744
+ }, model.id)),
5745
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5746
+ className: "dsha-actions",
5747
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5748
+ className: "dsha-btn",
5749
+ disabled: busy !== null || overrideCount === 0,
5750
+ onClick: () => void handleResetAllContextWindows(),
5751
+ children: t.contextWindowResetAll
5752
+ })
5753
+ })
5754
+ ]
5755
+ })
5756
+ ]
5757
+ }),
5758
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
5759
+ className: "dsha-group",
5760
+ children: [
5761
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5762
+ className: "dsha-grouphead",
5763
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5764
+ className: "dsha-btn",
5765
+ disabled: busy !== null || !authenticated,
5766
+ onClick: () => void handleRefreshQuota(),
5767
+ children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
5768
+ })]
5769
+ }),
5770
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
5771
+ className: "dsha-muted",
5772
+ children: t.quotaDesc
5773
+ }),
5774
+ !authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5775
+ className: "dsha-empty",
5776
+ children: t.signedOut
5777
+ }) : quota === null || quota === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5778
+ className: "dsha-empty",
5779
+ children: busy === "quota" ? t.refreshingQuota : t.quotaEmpty
5780
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5781
+ className: "dsha-quota-card",
5782
+ children: [
5783
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5784
+ className: "dsha-quota-title",
5785
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.packageName || t.quotaPackage }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.remainingCredits !== null ? `${quota.remainingCredits} ${t.credits}` : "—" })]
5786
+ }),
5787
+ quota.cycleUsedCredits !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5788
+ className: "dsha-row",
5789
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5790
+ className: "dsha-label",
5791
+ children: t.quotaCycle
5792
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5793
+ className: "dsha-value",
5794
+ children: [
5795
+ quota.cycleUsedCredits,
5796
+ quota.cycleCredits !== null ? ` / ${quota.cycleCredits}` : "",
5797
+ ` ${t.credits}`
5798
+ ]
5799
+ })]
5800
+ }),
5801
+ quota.cycleEndsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5802
+ className: "dsha-row",
5803
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5804
+ className: "dsha-label",
5805
+ children: t.quotaReset
5806
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5807
+ className: "dsha-value",
5808
+ children: [formatDate$1(quota.cycleEndsAt), formatReset$1(quota.cycleEndsAt) ? ` · ${formatReset$1(quota.cycleEndsAt)}` : ""]
5809
+ })]
5810
+ }),
5811
+ quota.meters.map((meter) => {
5812
+ const remaining = meter.remainingFraction;
5813
+ const percent = remaining === null ? null : Math.round(remaining * 100);
5814
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5815
+ className: "dsha-meter-wrap",
5816
+ children: [
5817
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5818
+ className: "dsha-meter-label",
5819
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? meter.limit ?? "—" : `${percent}% left` })]
5820
+ }),
5821
+ percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5822
+ className: "dsha-meter dsha-meter-green",
5823
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${percent}%` } })
5824
+ }),
5825
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5826
+ className: "dsha-meter-meta",
5827
+ children: [meter.used !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5828
+ meter.used,
5829
+ " / ",
5830
+ meter.limit ?? "—"
5831
+ ] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5832
+ t.quotaReset,
5833
+ ": ",
5834
+ formatReset$1(meter.resetsAt)
5835
+ ] })]
5836
+ })
5837
+ ]
5838
+ }, meter.id);
5839
+ }),
5840
+ quota.meters.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5841
+ className: "dsha-empty",
5842
+ children: t.quotaEmpty
5843
+ }),
5844
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5845
+ className: "dsha-timestamp",
5846
+ children: t.updatedAt.replace("{time}", new Date(quota.fetchedAt).toLocaleString())
5847
+ })
5848
+ ]
5849
+ })
5850
+ ]
5851
+ }),
5852
+ error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5853
+ className: "dsha-error",
5854
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: error })
5855
+ })
5856
+ ]
5857
+ });
5858
+ }
5859
+ //#endregion
5860
+ //#region src/shared/zhipu-contracts.ts
5861
+ /** Every level this route can name, in escalating order (the card's sort key). */
5862
+ const ZHIPU_REASONING_EFFORTS = [
5863
+ "low",
5864
+ "high",
5865
+ "max"
5866
+ ];
5867
+ ({
5868
+ none: 0,
5869
+ minimal: 1,
5870
+ low: 2,
5871
+ medium: 3,
5872
+ high: 4,
5873
+ xhigh: 5,
5874
+ max: 6
5875
+ }).high;
5876
+ //#endregion
5877
+ //#region src/client/zhipu/locales.ts
5878
+ const NS_ZHIPU = "dsh-zhipu";
5879
+ const zh$1 = {
5880
+ ...accountPoolZh,
5881
+ title: "GLM(智谱 Coding Plan)",
5882
+ pageDesc: "添加智谱 / Z.ai 的 GLM Coding Plan API Key,管理可用模型、上下文窗口与额度。",
5883
+ account: "账号",
5884
+ signedIn: "已登录",
5885
+ signedOut: "未登录",
5886
+ region: "区域",
5887
+ regionIntl: "国际区 (api.z.ai)",
5888
+ regionCn: "国区 (open.bigmodel.cn)",
5889
+ keyHint: "Key 尾号",
5890
+ plan: "套餐",
5891
+ planUnknown: "—",
5892
+ renews: "续费于",
5893
+ authenticatedAt: "添加时间",
5894
+ storage: "凭据存储",
5895
+ storageNotice: "API Key 由 Host 保存于本地加密存储,不会进入浏览器。",
5896
+ signOut: "注销",
5897
+ addKeySection: "添加 API Key",
5898
+ addKeyHint: "在对应开放平台的「API Keys」页创建 Key 后粘贴到此处。它必须来自你订阅 Coding Plan 的那个平台:国区 Key 与国际区 Key 互不通用,开放平台(/api/paas/v4)的通用 Key 在订阅接口上会被拒绝。",
5899
+ keyPlaceholder: "粘贴 GLM Coding Plan API Key",
5900
+ keySave: "保存并验证",
5901
+ keySaving: "验证中...",
5902
+ keySaved: "已保存",
5903
+ connection: "连接",
5904
+ provider: "Provider",
5905
+ providerValue: "GLM(智谱 Coding Plan)· zhipu-coding-plan",
5906
+ connectionState: "连接状态",
5907
+ connected: "已连接",
5908
+ untested: "未测试",
5909
+ testConnection: "测试连接",
5910
+ testingConnection: "测试中...",
5911
+ routeOwned: "模型路由由本插件提供",
5912
+ routeConflict: "模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。",
5913
+ modelsSection: "模型",
5914
+ enableProvider: "启用此供应商",
5915
+ modelsHint: "勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。",
5916
+ refreshCatalog: "刷新模型目录",
5917
+ refreshingCatalog: "刷新中...",
5918
+ selectAll: "全选",
5919
+ unselectAll: "全不选",
5920
+ effectiveWindow: "有效窗口",
5921
+ enhanced: "增强功能",
5922
+ defaultReasoningEffort: "默认思考深度",
5923
+ defaultReasoningEffortHint: "仅对声明了思考档位的模型生效。上游只接受 low / high / max,其余档位会收敛到最近的可用档位后发出(不支持的档位会直接报错)。",
5924
+ defaultEffortAuto: "使用 Provider 默认值",
5925
+ contextWindowSection: "模型上下文窗口",
5926
+ contextWindowHint: "默认取该模型官方声明的上下文窗口;可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。",
5927
+ contextWindowReset: "恢复默认",
5928
+ contextWindowResetAll: "全部恢复默认",
5929
+ contextWindowResetAllConfirm: "确定把已改过的模型上下文窗口全部恢复为默认值吗?",
5930
+ contextWindowNoneEnabled: "还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。",
5931
+ save: "保存",
5932
+ saved: "已保存",
5933
+ saving: "保存中...",
5934
+ quotaSection: "用量与配额",
5935
+ quotaDesc: "数据来自 GLM Coding Plan 的用量接口,页面可见时最多每 60 秒刷新一次。Coding Plan 同时受 5 小时额度与每周额度限制。",
5936
+ refreshQuota: "刷新用量",
5937
+ refreshingQuota: "刷新中...",
5938
+ quotaEmpty: "暂无配额数据,点击「刷新用量」重试。",
5939
+ quotaUnavailable: "该账号没有可用的配额数据(通常是套餐未生效,或 Key 不属于 Coding Plan)。",
5940
+ quotaError: "配额读取失败",
5941
+ updatedAt: "更新时间:{time}",
5942
+ loading: "加载中...",
5943
+ tokens: "tokens",
5944
+ left: "剩余",
5945
+ resetAt: "重置于",
5946
+ now: "即将重置"
5947
+ };
5948
+ const en$1 = {
5949
+ ...accountPoolEn,
5950
+ title: "GLM (Zhipu Coding Plan)",
5951
+ pageDesc: "Add a GLM Coding Plan API key for Zhipu / Z.ai and manage models, context windows, and quota.",
5952
+ account: "Account",
5953
+ signedIn: "Signed in",
5954
+ signedOut: "Not signed in",
5955
+ region: "Region",
5956
+ regionIntl: "International (api.z.ai)",
5957
+ regionCn: "China (open.bigmodel.cn)",
5958
+ keyHint: "Key suffix",
5959
+ plan: "Plan",
5960
+ planUnknown: "—",
5961
+ renews: "renews",
5962
+ authenticatedAt: "Added at",
5963
+ storage: "Credential storage",
5964
+ storageNotice: "The API key is stored locally by the Host in encrypted storage and never reaches the browser.",
5965
+ signOut: "Sign out",
5966
+ addKeySection: "Add an API key",
5967
+ addKeyHint: "Create a key on the console’s API Keys page and paste it here. It must come from the platform your Coding Plan was bought on: China and international keys are not interchangeable, and a general open-platform key (/api/paas/v4) is rejected by the subscription surface.",
5968
+ keyPlaceholder: "Paste a GLM Coding Plan API key",
5969
+ keySave: "Save and verify",
5970
+ keySaving: "Verifying...",
5971
+ keySaved: "Saved",
5972
+ connection: "Connection",
5973
+ provider: "Provider",
5974
+ providerValue: "GLM (Zhipu Coding Plan) · zhipu-coding-plan",
5975
+ connectionState: "Connection state",
5976
+ connected: "Connected",
5977
+ untested: "Untested",
5978
+ testConnection: "Test connection",
5979
+ testingConnection: "Testing...",
5980
+ routeOwned: "This plugin serves the model route",
5981
+ routeConflict: "Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.",
5982
+ modelsSection: "Models",
5983
+ enableProvider: "Enable this provider",
5984
+ modelsHint: "Checked models appear in the DSH conversation model list; unchecking all or turning off the switch hides this provider.",
5985
+ refreshCatalog: "Refresh catalog",
5986
+ refreshingCatalog: "Refreshing...",
5987
+ selectAll: "Select all",
5988
+ unselectAll: "Deselect all",
5989
+ effectiveWindow: "Effective window",
5990
+ enhanced: "Enhanced features",
5991
+ defaultReasoningEffort: "Default reasoning effort",
5992
+ defaultReasoningEffortHint: "Applies only to models that declare a reasoning ladder. The provider accepts low / high / max; any other level is converged onto the nearest supported one before it is sent, because an unsupported level is rejected outright.",
5993
+ defaultEffortAuto: "Use provider default",
5994
+ contextWindowSection: "Model context window",
5995
+ contextWindowHint: "Defaults to the window the model itself declares; override it with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).",
5996
+ contextWindowReset: "Restore default",
5997
+ contextWindowResetAll: "Restore all defaults",
5998
+ contextWindowResetAllConfirm: "Restore every changed model context window to its default?",
5999
+ contextWindowNoneEnabled: "No model is checked yet. Check one above and its context window setting appears here.",
6000
+ save: "Save",
6001
+ saved: "Saved",
6002
+ saving: "Saving...",
6003
+ quotaSection: "Usage & quota",
6004
+ quotaDesc: "Read from the GLM Coding Plan usage endpoints; refreshes at most once every 60 seconds while visible. A Coding Plan is bounded by both a 5-hour and a weekly allowance.",
6005
+ refreshQuota: "Refresh quota",
6006
+ refreshingQuota: "Refreshing...",
6007
+ quotaEmpty: "No quota data yet — use “Refresh quota” to retry.",
6008
+ quotaUnavailable: "This account reports no usable quota (usually an inactive plan, or a key that is not a Coding Plan key).",
6009
+ quotaError: "Quota lookup failed",
6010
+ updatedAt: "Updated at: {time}",
6011
+ loading: "Loading...",
6012
+ tokens: "tokens",
6013
+ left: "left",
6014
+ resetAt: "Resets at",
6015
+ now: "resetting now"
6016
+ };
6017
+ const dictionaries$1 = {
6018
+ zh: zh$1,
6019
+ "zh-CN": zh$1,
6020
+ en: en$1,
6021
+ "en-US": en$1
6022
+ };
6023
+ //#endregion
6024
+ //#region src/client/zhipu/ZhipuSection.tsx
6025
+ /**
6026
+ * Display label per reasoning level. The locale dictionary only accepts flat
6027
+ * string values, so this table lives with the control that renders it.
6028
+ */
6029
+ const EFFORT_LABELS = {
6030
+ low: "Low",
6031
+ high: "High",
6032
+ max: "Max"
6033
+ };
6034
+ const API$5 = "/zhipu/api";
6035
+ async function fetchApi$5(path, options) {
6036
+ const res = await fetch(`${API$5}${path}`, {
6037
+ ...options,
6038
+ headers: {
6039
+ "Content-Type": "application/json",
6040
+ ...options?.headers
6041
+ }
6042
+ });
6043
+ const json = await res.json();
6044
+ if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
6045
+ return json.value;
6046
+ }
6047
+ /** Parse "1M", "512K", "200000" into a positive integer token count. */
6048
+ function parsePositiveCapacity(value) {
6049
+ const matched = value.trim().toLowerCase().replace(/[,_\s]/g, "").match(/^(\d+(?:\.\d+)?)(k|m)?$/);
6050
+ if (matched === null) return null;
6051
+ const multiplier = matched[2] === "m" ? 1e6 : matched[2] === "k" ? 1e3 : 1;
6052
+ const parsed = Number(matched[1]) * multiplier;
6053
+ return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null;
6054
+ }
6055
+ function formatCapacity(value) {
6056
+ if (value >= 1e6 && value % 1e5 === 0) return `${value / 1e6}M`;
6057
+ if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
6058
+ return String(value);
6059
+ }
6060
+ /**
6061
+ * Seed one draft per model from a status payload. Also run after a model
6062
+ * toggle: a model that was just enabled has no draft yet, and the context
6063
+ * window section only renders enabled models.
6064
+ */
6065
+ function contextDraftsFor(status) {
6066
+ const drafts = {};
6067
+ for (const model of status.models) drafts[model.id] = formatCapacity(status.contextWindowOverrides[model.id] || model.defaultContextWindow);
6068
+ return drafts;
6069
+ }
6070
+ function formatDate(ms) {
6071
+ if (ms === void 0 || ms === null || ms <= 0) return "—";
6072
+ try {
6073
+ return new Intl.DateTimeFormat(void 0, {
6074
+ dateStyle: "medium",
6075
+ timeStyle: "short"
6076
+ }).format(ms);
6077
+ } catch {
6078
+ return "—";
6079
+ }
6080
+ }
6081
+ function formatReset(resetsAt, nowLabel = "now") {
6082
+ if (resetsAt === void 0 || resetsAt === null || resetsAt <= 0) return "";
6083
+ const diff = resetsAt - Date.now();
6084
+ if (diff <= 0) return nowLabel;
6085
+ const mins = Math.floor(diff / 6e4);
6086
+ const hours = Math.floor(mins / 60);
6087
+ const days = Math.floor(hours / 24);
6088
+ if (days > 0) return `${days}d ${hours % 24}h`;
6089
+ if (hours > 0) return `${hours}h ${mins % 60}m`;
6090
+ return `${mins}m`;
6091
+ }
6092
+ function ZhipuSection({ onModelChange, loadModelDirectory }) {
6093
+ const [status, setStatus] = (0, react.useState)(null);
6094
+ const [loading, setLoading] = (0, react.useState)(true);
6095
+ const [busy, setBusy] = (0, react.useState)(null);
6096
+ const [error, setError] = (0, react.useState)(null);
6097
+ const [contextDrafts, setContextDrafts] = (0, react.useState)({});
6098
+ const [savingModel, setSavingModel] = (0, react.useState)(null);
6099
+ const [apiKey, setApiKey] = (0, react.useState)("");
6100
+ const [region, setRegion] = (0, react.useState)("intl");
6101
+ const t = zh$1;
6102
+ const notifyChange = (0, react.useCallback)(() => {
6103
+ onModelChange?.();
6104
+ loadModelDirectory?.();
6105
+ }, [onModelChange, loadModelDirectory]);
6106
+ const loadStatus = (0, react.useCallback)(async (quiet = false) => {
6107
+ if (!quiet) setError(null);
6108
+ try {
6109
+ const data = await fetchApi$5("/status");
6110
+ setStatus(data);
6111
+ setContextDrafts(contextDraftsFor(data));
6112
+ } catch (err) {
6113
+ if (!quiet) setError(err instanceof Error ? err.message : String(err));
6114
+ } finally {
6115
+ setLoading(false);
6116
+ }
6117
+ }, []);
6118
+ (0, react.useEffect)(() => {
6119
+ loadStatus();
6120
+ const refreshWhenVisible = () => {
6121
+ if (document.visibilityState === "visible") loadStatus(true);
6122
+ };
6123
+ document.addEventListener("visibilitychange", refreshWhenVisible);
6124
+ const timer = window.setInterval(refreshWhenVisible, 6e4);
6125
+ return () => {
6126
+ window.clearInterval(timer);
6127
+ document.removeEventListener("visibilitychange", refreshWhenVisible);
6128
+ };
6129
+ }, [loadStatus]);
6130
+ /**
6131
+ * Save one pasted key.
6132
+ *
6133
+ * The host verifies it against the deployment before persisting, so a key
6134
+ * from the wrong console fails here with a message naming the console it
6135
+ * belongs to rather than inside a conversation later.
6136
+ */
6137
+ const handleAddKey = async () => {
6138
+ try {
6139
+ setBusy("apikey");
6140
+ setError(null);
6141
+ const updated = await fetchApi$5("/accounts/add", {
6142
+ method: "POST",
6143
+ body: JSON.stringify({
6144
+ apiKey,
6145
+ region
6146
+ })
6147
+ });
6148
+ setStatus(updated);
6149
+ setContextDrafts(contextDraftsFor(updated));
6150
+ setApiKey("");
6151
+ notifyChange();
6152
+ } catch (err) {
6153
+ setError(err instanceof Error ? err.message : String(err));
6154
+ } finally {
6155
+ setBusy(null);
6156
+ }
6157
+ };
6158
+ /** One account-level action on the shared pool card. */
6159
+ const handleAccountAction = async (action, accountId) => {
6160
+ try {
6161
+ setBusy(`${action}-${accountId}`);
6162
+ setError(null);
6163
+ const updated = await fetchApi$5("/accounts/action", {
6164
+ method: "POST",
6165
+ body: JSON.stringify({
6166
+ action,
6167
+ accountId
6168
+ })
6169
+ });
6170
+ setStatus(updated);
6171
+ notifyChange();
6172
+ } catch (err) {
6173
+ setError(err instanceof Error ? err.message : String(err));
6174
+ } finally {
6175
+ setBusy(null);
6176
+ }
6177
+ };
6178
+ const handleSetStrategy = async (strategy) => {
6179
+ try {
6180
+ setBusy("strategy");
6181
+ setError(null);
6182
+ const updated = await fetchApi$5("/accounts/action", {
6183
+ method: "POST",
6184
+ body: JSON.stringify({
6185
+ action: "strategy",
6186
+ strategy
6187
+ })
6188
+ });
6189
+ setStatus(updated);
6190
+ } catch (err) {
6191
+ setError(err instanceof Error ? err.message : String(err));
6192
+ } finally {
6193
+ setBusy(null);
6194
+ }
6195
+ };
6196
+ const handleRefreshQuota = async () => {
6197
+ try {
6198
+ setBusy("quota");
6199
+ setError(null);
6200
+ const updated = await fetchApi$5("/quota", { method: "POST" });
6201
+ setStatus(updated);
6202
+ } catch (err) {
6203
+ setError(err instanceof Error ? err.message : String(err));
6204
+ } finally {
6205
+ setBusy(null);
6206
+ }
6207
+ };
6208
+ const handleRefreshCatalog = async () => {
6209
+ try {
6210
+ setBusy("catalog");
6211
+ setError(null);
6212
+ const updated = await fetchApi$5("/catalog/refresh", { method: "POST" });
6213
+ setStatus(updated);
6214
+ setContextDrafts(contextDraftsFor(updated));
6215
+ notifyChange();
6216
+ } catch (err) {
6217
+ setError(err instanceof Error ? err.message : String(err));
6218
+ } finally {
6219
+ setBusy(null);
6220
+ }
6221
+ };
6222
+ const handleTestConnection = async () => {
6223
+ try {
6224
+ setBusy("connection");
6225
+ setError(null);
6226
+ await fetchApi$5("/connection/test", { method: "POST" });
6227
+ await loadStatus(true);
6228
+ } catch (err) {
6229
+ setError(err instanceof Error ? err.message : String(err));
6230
+ } finally {
6231
+ setBusy(null);
6232
+ }
6233
+ };
6234
+ const applyEnabled = async (enabledModelIds) => {
6235
+ try {
6236
+ const updated = await fetchApi$5("/models", {
6237
+ method: "POST",
6238
+ body: JSON.stringify({ enabledModelIds })
6239
+ });
6240
+ setStatus(updated);
6241
+ setContextDrafts(contextDraftsFor(updated));
6242
+ notifyChange();
6243
+ } catch (err) {
6244
+ setError(err instanceof Error ? err.message : String(err));
6245
+ }
6246
+ };
6247
+ const toggleEnabled = async (enabled) => {
6248
+ setStatus((prev) => prev ? {
6249
+ ...prev,
6250
+ enabled
6251
+ } : prev);
6252
+ try {
6253
+ const updated = await fetchApi$5("/settings", {
6254
+ method: "POST",
6255
+ body: JSON.stringify({ enabled })
6256
+ });
6257
+ setStatus(updated);
6258
+ notifyChange();
6259
+ } catch (err) {
6260
+ setError(err instanceof Error ? err.message : String(err));
6261
+ loadStatus(true);
6262
+ }
6263
+ };
6264
+ const toggleModel = (modelId, checked) => {
6265
+ if (!status) return;
6266
+ const current = status.models.filter((model) => model.enabled).map((model) => model.id);
6267
+ const next = checked ? [.../* @__PURE__ */ new Set([...current, modelId])] : current.filter((id) => id !== modelId);
6268
+ applyEnabled(next);
6269
+ };
6270
+ const setAllModels = (selectAll) => {
6271
+ if (!status || status.models.length === 0) return;
6272
+ applyEnabled(selectAll ? status.models.map((model) => model.id) : []);
6273
+ };
6274
+ const handleUpdateEffort = async (effort) => {
6275
+ try {
6276
+ const updated = await fetchApi$5("/settings", {
6277
+ method: "POST",
6278
+ body: JSON.stringify({ defaultReasoningEffort: effort })
6279
+ });
6280
+ setStatus(updated);
6281
+ notifyChange();
6282
+ } catch (err) {
6283
+ setError(err instanceof Error ? err.message : String(err));
6284
+ }
6285
+ };
6286
+ const handleSaveContextWindow = async (modelId) => {
6287
+ const raw = contextDrafts[modelId] || "";
6288
+ const parsed = parsePositiveCapacity(raw);
6289
+ if (parsed === null) {
6290
+ setError(`Invalid context capacity: ${raw}`);
6291
+ return;
6292
+ }
6293
+ try {
6294
+ setSavingModel(modelId);
6295
+ setError(null);
6296
+ const updated = await fetchApi$5("/settings", {
6297
+ method: "POST",
6298
+ body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
6299
+ });
6300
+ setStatus(updated);
6301
+ setContextDrafts((prev) => ({
6302
+ ...prev,
6303
+ [modelId]: formatCapacity(parsed)
6304
+ }));
6305
+ notifyChange();
6306
+ } catch (err) {
6307
+ setError(err instanceof Error ? err.message : String(err));
6308
+ } finally {
6309
+ setSavingModel(null);
6310
+ }
6311
+ };
6312
+ /** Clear one override; the row falls back to the declared window. */
6313
+ const handleResetContextWindow = async (modelId) => {
6314
+ try {
6315
+ setSavingModel(modelId);
6316
+ setError(null);
6317
+ const updated = await fetchApi$5("/settings", {
6318
+ method: "POST",
6319
+ body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
6320
+ });
6321
+ setStatus(updated);
6322
+ setContextDrafts((prev) => {
6323
+ const model = updated.models.find((candidate) => candidate.id === modelId);
6324
+ return model === void 0 ? prev : {
6325
+ ...prev,
6326
+ [modelId]: formatCapacity(model.defaultContextWindow)
6327
+ };
6328
+ });
6329
+ notifyChange();
6330
+ } catch (err) {
6331
+ setError(err instanceof Error ? err.message : String(err));
6332
+ } finally {
6333
+ setSavingModel(null);
6334
+ }
6335
+ };
6336
+ /** Clear every stored override, including models the picker no longer shows. */
6337
+ const handleResetAllContextWindows = async () => {
6338
+ const models = Object.keys(status?.contextWindowOverrides ?? {});
6339
+ if (models.length === 0) return;
6340
+ if (typeof window !== "undefined" && !window.confirm(t.contextWindowResetAllConfirm)) return;
6341
+ try {
6342
+ setBusy("context");
6343
+ setError(null);
6344
+ const updated = await fetchApi$5("/settings", {
6345
+ method: "POST",
6346
+ body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
6347
+ });
6348
+ setStatus(updated);
6349
+ setContextDrafts(contextDraftsFor(updated));
6350
+ notifyChange();
6351
+ } catch (err) {
6352
+ setError(err instanceof Error ? err.message : String(err));
6353
+ } finally {
6354
+ setBusy(null);
6355
+ }
6356
+ };
6357
+ if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6358
+ className: "dsha-page",
6359
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6360
+ className: "dsha-empty",
6361
+ children: t.loading
6362
+ })
6363
+ });
6364
+ const contextModels = status?.models.filter((model) => model.enabled) ?? [];
6365
+ const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length;
6366
+ const quota = status?.quota;
6367
+ const account = status?.account;
6368
+ const hasMeters = (quota?.meters.length ?? 0) > 0;
6369
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6370
+ className: "dsha-page",
6371
+ children: [
6372
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
6373
+ accounts: status?.accounts ?? [],
6374
+ activeAccountId: status?.activeAccountId,
6375
+ rotationStrategy: status?.rotationStrategy ?? "sequential",
6376
+ busy,
6377
+ labels: t,
6378
+ onLogin: () => {
6379
+ document.querySelector(`.dsha-page input[type=password]`)?.focus();
6380
+ },
6381
+ onSetPrimary: (accountId) => void handleAccountAction("set-primary", accountId),
6382
+ onDelete: (accountId) => void handleAccountAction("delete", accountId),
6383
+ onClearCooldown: (accountId) => void handleAccountAction("clear-cooldown", accountId),
6384
+ onSetStrategy: (strategy) => void handleSetStrategy(strategy),
6385
+ storageValue: status?.storagePath || "—",
6386
+ renderDetails: (entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
6387
+ entry.keyHint && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6388
+ t.keyHint,
6389
+ ": ",
6390
+ entry.keyHint
6391
+ ] }),
6392
+ entry.region && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6393
+ t.region,
6394
+ ": ",
6395
+ entry.region === "cn" ? t.regionCn : t.regionIntl
6396
+ ] }),
6397
+ entry.planLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6398
+ t.plan,
6399
+ ": ",
6400
+ entry.planLabel
6401
+ ] })
6402
+ ] }),
6403
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6404
+ className: "dsha-muted",
6405
+ style: { paddingTop: 12 },
6406
+ children: t.addKeyHint
6407
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6408
+ className: "dsha-capacity-control dshzp-keyrow",
6409
+ children: [
6410
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
6411
+ className: "dsha-select",
6412
+ "aria-label": t.region,
6413
+ value: region,
6414
+ onChange: (event) => setRegion(event.currentTarget.value === "cn" ? "cn" : "intl"),
6415
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
6416
+ value: "intl",
6417
+ children: t.regionIntl
6418
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
6419
+ value: "cn",
6420
+ children: t.regionCn
6421
+ })]
6422
+ }),
6423
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6424
+ type: "password",
6425
+ "aria-label": t.addKeySection,
6426
+ placeholder: t.keyPlaceholder,
6427
+ value: apiKey,
6428
+ onChange: (event) => setApiKey(event.currentTarget.value),
6429
+ onKeyDown: (event) => {
6430
+ if (event.key === "Enter" && apiKey.trim() !== "") handleAddKey();
6431
+ }
6432
+ }),
6433
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6434
+ type: "button",
6435
+ className: "dsha-context-save",
6436
+ disabled: busy !== null || apiKey.trim() === "",
6437
+ onClick: () => void handleAddKey(),
6438
+ children: busy === "apikey" ? t.keySaving : t.keySave
6439
+ })
6440
+ ]
6441
+ })]
6442
+ }),
6443
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
6444
+ className: "dsha-group",
6445
+ children: [
6446
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6447
+ className: "dsha-grouphead",
6448
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.connection })
6449
+ }),
6450
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6451
+ className: "dsha-row",
6452
+ style: { marginBottom: 12 },
6453
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6454
+ className: "dsha-label",
6455
+ style: { fontWeight: 600 },
6456
+ children: t.enableProvider
6457
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6458
+ type: "checkbox",
6459
+ checked: status?.enabled !== false,
6460
+ disabled: busy !== null,
6461
+ onChange: (e) => void toggleEnabled(e.currentTarget.checked)
6462
+ })]
6463
+ }),
6464
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6465
+ className: "dsha-row",
6466
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6467
+ className: "dsha-label",
6468
+ children: t.provider
6469
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6470
+ className: "dsha-value",
6471
+ children: t.providerValue
6472
+ })]
6473
+ }),
6474
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6475
+ className: "dsha-row",
6476
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6477
+ className: "dsha-label",
6478
+ children: t.connectionState
6479
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6480
+ className: "dsha-value",
6481
+ children: status?.authenticated ? t.connected : t.untested
6482
+ })]
6483
+ }),
6484
+ account && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6485
+ className: "dsha-row",
6486
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6487
+ className: "dsha-label",
6488
+ children: t.account
6489
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6490
+ className: "dsha-value",
6491
+ children: [
6492
+ account.keyHint,
6493
+ " · ",
6494
+ account.region === "cn" ? t.regionCn : t.regionIntl
6495
+ ]
6496
+ })]
6497
+ }),
6498
+ account?.planLabel && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6499
+ className: "dsha-row",
6500
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6501
+ className: "dsha-label",
6502
+ children: t.plan
6503
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6504
+ className: "dsha-value",
6505
+ children: account.planLabel
6506
+ })]
6507
+ }),
6508
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6509
+ className: "dsha-row",
6510
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6511
+ className: "dsha-label",
6512
+ children: t.storage
6513
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6514
+ className: "dsha-value",
6515
+ children: status?.storagePath ?? "—"
6516
+ })]
6517
+ }),
6518
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6519
+ className: "dsha-notice",
6520
+ children: status?.serving === false && status.conflict ? t.routeConflict.replace("{detail}", status.conflict) : t.routeOwned
6521
+ }),
6522
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6523
+ className: "dsha-actions",
6524
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6525
+ className: "dsha-btn",
6526
+ disabled: busy !== null || !status?.authenticated,
6527
+ onClick: () => void handleTestConnection(),
6528
+ children: busy === "connection" ? t.testingConnection : t.testConnection
6529
+ })
6530
+ })
6531
+ ]
6532
+ }),
6533
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
6534
+ className: "dsha-group",
6535
+ children: [
6536
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6537
+ className: "dsha-grouphead",
6538
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.modelsSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6539
+ className: "dsha-btn",
6540
+ disabled: busy !== null,
6541
+ onClick: () => void handleRefreshCatalog(),
6542
+ children: busy === "catalog" ? t.refreshingCatalog : t.refreshCatalog
6543
+ })]
6544
+ }),
6545
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6546
+ className: "dsha-muted dsha-models-hint",
6547
+ children: t.modelsHint
6548
+ }),
6549
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6550
+ className: "dsha-models",
6551
+ "aria-label": "GLM Coding Plan Models",
6552
+ children: status?.models.map((model) => {
6553
+ const capabilities = [
6554
+ model.supportsImage ? "image" : null,
6555
+ model.reasoningEfforts.length > 0 ? model.reasoningEfforts.join("/") : null,
6556
+ `${t.effectiveWindow} ${formatCapacity(model.contextWindow)}`
6557
+ ].filter((part) => part !== null).join(" · ");
6558
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
6559
+ title: `${model.id} · ${capabilities}`,
6560
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6561
+ type: "checkbox",
6562
+ checked: model.enabled,
6563
+ disabled: busy !== null,
6564
+ onChange: (event) => toggleModel(model.id, event.currentTarget.checked)
6565
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name })]
6566
+ }, model.id);
6567
+ })
6568
+ }),
6569
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6570
+ className: "dsha-actions",
6571
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6572
+ className: "dsha-btn",
6573
+ disabled: busy !== null,
6574
+ onClick: () => setAllModels(true),
6575
+ children: t.selectAll
6576
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
6577
+ className: "dsha-btn",
6578
+ disabled: busy !== null,
6579
+ onClick: () => setAllModels(false),
6580
+ children: t.unselectAll
6581
+ })]
6582
+ })
6583
+ ]
6584
+ }),
6585
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
6586
+ className: "dsha-group",
6587
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6588
+ className: "dsha-grouphead",
6589
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.enhanced })
6590
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6591
+ className: "dsha-pref-row",
6592
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: t.defaultReasoningEffort }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6593
+ className: "dsha-muted",
6594
+ children: t.defaultReasoningEffortHint
6595
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
6596
+ className: "dsha-select",
6597
+ "aria-label": t.defaultReasoningEffort,
6598
+ value: status?.defaultReasoningEffort ?? "",
6599
+ disabled: busy !== null,
6600
+ onChange: (event) => {
6601
+ const value = event.currentTarget.value;
6602
+ handleUpdateEffort(value === "" ? null : value);
6603
+ },
6604
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
6605
+ value: "",
6606
+ children: t.defaultEffortAuto
6607
+ }), ZHIPU_REASONING_EFFORTS.map((effort) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
6608
+ value: effort,
6609
+ children: EFFORT_LABELS[effort]
6610
+ }, effort))]
6611
+ })]
6612
+ })]
6613
+ }),
6614
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
6615
+ className: "dsha-group",
6616
+ children: [
6617
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6618
+ className: "dsha-grouphead",
6619
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.contextWindowSection })
6620
+ }),
6621
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6622
+ className: "dsha-muted",
6623
+ children: t.contextWindowHint
6624
+ }),
6625
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6626
+ className: "dsha-context-settings",
6627
+ children: [
6628
+ contextModels.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
6629
+ className: "dsha-muted",
6630
+ children: t.contextWindowNoneEnabled
6631
+ }),
6632
+ contextModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6633
+ className: "dsha-context-row",
6634
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
6635
+ title: model.id,
6636
+ children: model.name
6637
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6638
+ className: "dsha-capacity-control",
6639
+ children: [
6640
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
6641
+ type: "text",
6642
+ "aria-label": `${model.name} context window`,
6643
+ value: contextDrafts[model.id] ?? "",
6644
+ onChange: (event) => setContextDrafts({
6645
+ ...contextDrafts,
6646
+ [model.id]: event.currentTarget.value
6647
+ }),
6648
+ onKeyDown: (event) => {
6649
+ if (event.key === "Enter") handleSaveContextWindow(model.id);
6650
+ }
6651
+ }),
6652
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t.tokens }),
5619
6653
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5620
6654
  type: "button",
5621
6655
  className: "dsha-context-save",
@@ -5654,7 +6688,7 @@ window.__ModuleLoader__.load({
5654
6688
  className: "dsha-grouphead",
5655
6689
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
5656
6690
  className: "dsha-btn",
5657
- disabled: busy !== null || !authenticated,
6691
+ disabled: busy !== null || !status?.authenticated,
5658
6692
  onClick: () => void handleRefreshQuota(),
5659
6693
  children: busy === "quota" ? t.refreshingQuota : t.refreshQuota
5660
6694
  })]
@@ -5663,81 +6697,100 @@ window.__ModuleLoader__.load({
5663
6697
  className: "dsha-muted",
5664
6698
  children: t.quotaDesc
5665
6699
  }),
5666
- !authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6700
+ !status?.authenticated ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5667
6701
  className: "dsha-empty",
5668
6702
  children: t.signedOut
5669
6703
  }) : quota === null || quota === void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5670
6704
  className: "dsha-empty",
5671
- children: busy === "quota" ? t.refreshingQuota : t.quotaEmpty
6705
+ children: busy === "quota" ? t.refreshingQuota : status.quotaError ?? t.quotaEmpty
5672
6706
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5673
6707
  className: "dsha-quota-card",
5674
6708
  children: [
5675
6709
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5676
6710
  className: "dsha-quota-title",
5677
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.packageName || t.quotaPackage }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.remainingCredits !== null ? `${quota.remainingCredits} ${t.credits}` : "—" })]
6711
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: quota.planName ?? t.quotaSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: quota.planLevel ?? t.planUnknown })]
5678
6712
  }),
5679
- quota.cycleUsedCredits !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5680
- className: "dsha-row",
5681
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5682
- className: "dsha-label",
5683
- children: t.quotaCycle
5684
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5685
- className: "dsha-value",
6713
+ quota.renewsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6714
+ className: "dsha-meter-meta",
6715
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6716
+ t.renews,
6717
+ ": ",
6718
+ formatDate(quota.renewsAt)
6719
+ ] })
6720
+ }),
6721
+ quota.windows.map((window) => {
6722
+ const percent = window.remainingFraction === null ? null : Math.round(window.remainingFraction * 100);
6723
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6724
+ className: "dsha-meter-wrap",
5686
6725
  children: [
5687
- quota.cycleUsedCredits,
5688
- quota.cycleCredits !== null ? ` / ${quota.cycleCredits}` : "",
5689
- ` ${t.credits}`
6726
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6727
+ className: "dsha-meter-label",
6728
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: window.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? "—" : `${percent}% ${t.left}` })]
6729
+ }),
6730
+ percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6731
+ className: "dsha-meter dsha-meter-green",
6732
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.max(0, percent)}%` } })
6733
+ }),
6734
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
6735
+ className: "dsha-meter-meta",
6736
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6737
+ window.used ?? "—",
6738
+ " / ",
6739
+ window.limit ?? "—"
6740
+ ] }), window.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6741
+ t.resetAt,
6742
+ ": ",
6743
+ formatReset(window.resetsAt, t.now)
6744
+ ] })]
6745
+ })
5690
6746
  ]
5691
- })]
5692
- }),
5693
- quota.cycleEndsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5694
- className: "dsha-row",
5695
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
5696
- className: "dsha-label",
5697
- children: t.quotaReset
5698
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
5699
- className: "dsha-value",
5700
- children: [formatDate(quota.cycleEndsAt), formatReset(quota.cycleEndsAt) ? ` · ${formatReset(quota.cycleEndsAt)}` : ""]
5701
- })]
6747
+ }, window.id);
5702
6748
  }),
5703
- quota.meters.map((meter) => {
5704
- const remaining = meter.remainingFraction;
5705
- const percent = remaining === null ? null : Math.round(remaining * 100);
6749
+ quota.meters.filter((meter) => !quota.windows.some((window) => window.id === meter.id)).map((meter) => {
6750
+ const percent = meter.remainingFraction === null ? null : Math.round(meter.remainingFraction * 100);
5706
6751
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5707
6752
  className: "dsha-meter-wrap",
5708
6753
  children: [
5709
6754
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5710
6755
  className: "dsha-meter-label",
5711
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? meter.limit ?? "—" : `${percent}% left` })]
6756
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: meter.label }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: percent === null ? "—" : `${percent}% ${t.left}` })]
5712
6757
  }),
5713
6758
  percent !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5714
- className: "dsha-meter dsha-meter-green",
5715
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${percent}%` } })
6759
+ className: "dsha-meter dsha-meter-cyan",
6760
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: { width: `${Math.max(0, percent)}%` } })
5716
6761
  }),
5717
6762
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
5718
6763
  className: "dsha-meter-meta",
5719
- children: [meter.used !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5720
- meter.used,
6764
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
6765
+ meter.used ?? "—",
5721
6766
  " / ",
5722
6767
  meter.limit ?? "—"
5723
6768
  ] }), meter.resetsAt !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
5724
- t.quotaReset,
6769
+ t.resetAt,
5725
6770
  ": ",
5726
- formatReset(meter.resetsAt)
6771
+ formatReset(meter.resetsAt, t.now)
5727
6772
  ] })]
5728
6773
  })
5729
6774
  ]
5730
6775
  }, meter.id);
5731
6776
  }),
5732
- quota.meters.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6777
+ !hasMeters && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5733
6778
  className: "dsha-empty",
5734
- children: t.quotaEmpty
6779
+ children: t.quotaUnavailable
5735
6780
  }),
5736
6781
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
5737
6782
  className: "dsha-timestamp",
5738
6783
  children: t.updatedAt.replace("{time}", new Date(quota.fetchedAt).toLocaleString())
5739
6784
  })
5740
6785
  ]
6786
+ }),
6787
+ status?.quotaError && quota !== null && quota !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
6788
+ className: "dsha-muted",
6789
+ children: [
6790
+ t.quotaError,
6791
+ ": ",
6792
+ status.quotaError
6793
+ ]
5741
6794
  })
5742
6795
  ]
5743
6796
  }),
@@ -5770,6 +6823,10 @@ window.__ModuleLoader__.load({
5770
6823
  {
5771
6824
  id: "workbuddy",
5772
6825
  label: "WorkBuddy"
6826
+ },
6827
+ {
6828
+ id: "zhipu",
6829
+ label: "GLM"
5773
6830
  }
5774
6831
  ];
5775
6832
  /**
@@ -5828,7 +6885,8 @@ window.__ModuleLoader__.load({
5828
6885
  active === "antigravity" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AntigravitySection, { onModelChange }) : null,
5829
6886
  active === "command-code" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommandCodeSection, { onModelChange }) : null,
5830
6887
  active === "kimi-code" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(KimiCodeSection, { onModelChange }) : null,
5831
- active === "workbuddy" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkBuddySection, { onModelChange }) : null
6888
+ active === "workbuddy" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkBuddySection, { onModelChange }) : null,
6889
+ active === "zhipu" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ZhipuSection, { onModelChange }) : null
5832
6890
  ]
5833
6891
  })
5834
6892
  ]
@@ -6107,7 +7165,7 @@ window.__ModuleLoader__.load({
6107
7165
  };
6108
7166
  //#endregion
6109
7167
  //#region src/client/styles.ts
6110
- const STYLE_ID$3 = "@eddyskywalker/dsh-chatgpt-subscription/main";
7168
+ const STYLE_ID$4 = "@eddyskywalker/dsh-chatgpt-subscription/main";
6111
7169
  const CSS = `
6112
7170
  .dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
6113
7171
  .dsh-codex-page *{box-sizing:border-box}
@@ -6216,21 +7274,21 @@ window.__ModuleLoader__.load({
6216
7274
  @media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}
6217
7275
  `;
6218
7276
  function installStyles() {
6219
- if (document.querySelector(`style[data-plugin-css="${STYLE_ID$3}"]`) !== null) return () => void 0;
7277
+ if (document.querySelector(`style[data-plugin-css="${STYLE_ID$4}"]`) !== null) return () => void 0;
6220
7278
  const element = document.createElement("style");
6221
7279
  element.dataset.plugin = "@eddyskywalker/dsh-chatgpt-subscription";
6222
- element.dataset.pluginCss = STYLE_ID$3;
7280
+ element.dataset.pluginCss = STYLE_ID$4;
6223
7281
  element.textContent = CSS;
6224
7282
  document.head.appendChild(element);
6225
7283
  return () => element.remove();
6226
7284
  }
6227
7285
  //#endregion
6228
7286
  //#region src/client/antigravity/styles.ts
6229
- const STYLE_ID$2 = "dsh-antigravity-settings-style";
7287
+ const STYLE_ID$3 = "dsh-antigravity-settings-style";
6230
7288
  function installAntigravityStyles() {
6231
7289
  if (typeof document === "undefined" || document.getElementById("dsh-antigravity-settings-style")) return;
6232
7290
  const style = document.createElement("style");
6233
- style.id = STYLE_ID$2;
7291
+ style.id = STYLE_ID$3;
6234
7292
  style.textContent = `
6235
7293
  .dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}
6236
7294
  .dsha-page *{box-sizing:border-box}
@@ -6331,9 +7389,9 @@ window.__ModuleLoader__.load({
6331
7389
  }
6332
7390
  //#endregion
6333
7391
  //#region src/client/antigravity/AntigravityComposerQuota.tsx
6334
- const API$3 = "/antigravity/api";
6335
- async function fetchApi$3(path, options) {
6336
- const res = await fetch(`${API$3}${path}`, {
7392
+ const API$4 = "/antigravity/api";
7393
+ async function fetchApi$4(path, options) {
7394
+ const res = await fetch(`${API$4}${path}`, {
6337
7395
  ...options,
6338
7396
  headers: {
6339
7397
  "Content-Type": "application/json",
@@ -6374,7 +7432,7 @@ window.__ModuleLoader__.load({
6374
7432
  }
6375
7433
  }
6376
7434
  function AntigravityComposerQuota({ directory, loadModelDirectory }) {
6377
- const modelState = useStore$3(directory);
7435
+ const modelState = useStore$4(directory);
6378
7436
  const [status, setStatus] = (0, react.useState)(null);
6379
7437
  const [loading, setLoading] = (0, react.useState)(false);
6380
7438
  const mountedRef = (0, react.useRef)(false);
@@ -6393,7 +7451,7 @@ window.__ModuleLoader__.load({
6393
7451
  if (!mountedRef.current) return;
6394
7452
  setLoading(true);
6395
7453
  try {
6396
- const data = refresh ? await fetchApi$3("/quota", { method: "POST" }) : await fetchApi$3("/status");
7454
+ const data = refresh ? await fetchApi$4("/quota", { method: "POST" }) : await fetchApi$4("/status");
6397
7455
  if (mountedRef.current) setStatus(data);
6398
7456
  } catch {} finally {
6399
7457
  if (mountedRef.current) setLoading(false);
@@ -6431,14 +7489,14 @@ window.__ModuleLoader__.load({
6431
7489
  })]
6432
7490
  });
6433
7491
  }
6434
- function useStore$3(store) {
7492
+ function useStore$4(store) {
6435
7493
  return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
6436
7494
  }
6437
7495
  //#endregion
6438
7496
  //#region src/client/command-code/CommandCodeComposerQuota.tsx
6439
- const API$2 = "/command-code/api";
6440
- async function fetchApi$2(path, options) {
6441
- const res = await fetch(`${API$2}${path}`, {
7497
+ const API$3 = "/command-code/api";
7498
+ async function fetchApi$3(path, options) {
7499
+ const res = await fetch(`${API$3}${path}`, {
6442
7500
  ...options,
6443
7501
  headers: {
6444
7502
  "Content-Type": "application/json",
@@ -6455,7 +7513,7 @@ window.__ModuleLoader__.load({
6455
7513
  * A bounded usage window is the number a user actually spends down, so it wins
6456
7514
  * over a credit balance; the balance shows only when no window is reported.
6457
7515
  */
6458
- function selectBadgeFacts$2(status) {
7516
+ function selectBadgeFacts$3(status) {
6459
7517
  const quota = status?.quota;
6460
7518
  if (quota === null || quota === void 0) return {
6461
7519
  text: "—",
@@ -6497,7 +7555,7 @@ window.__ModuleLoader__.load({
6497
7555
  };
6498
7556
  }
6499
7557
  function CommandCodeComposerQuota({ directory, loadModelDirectory }) {
6500
- const modelState = useStore$2(directory);
7558
+ const modelState = useStore$3(directory);
6501
7559
  const [status, setStatus] = (0, react.useState)(null);
6502
7560
  const [loading, setLoading] = (0, react.useState)(false);
6503
7561
  const mountedRef = (0, react.useRef)(false);
@@ -6515,7 +7573,7 @@ window.__ModuleLoader__.load({
6515
7573
  if (!mountedRef.current) return;
6516
7574
  setLoading(true);
6517
7575
  try {
6518
- const data = refresh ? await fetchApi$2("/quota", { method: "POST" }) : await fetchApi$2("/status");
7576
+ const data = refresh ? await fetchApi$3("/quota", { method: "POST" }) : await fetchApi$3("/status");
6519
7577
  if (mountedRef.current) setStatus(data);
6520
7578
  } catch {} finally {
6521
7579
  if (mountedRef.current) setLoading(false);
@@ -6531,7 +7589,7 @@ window.__ModuleLoader__.load({
6531
7589
  window.clearInterval(timer);
6532
7590
  };
6533
7591
  }, [fetchStatus, isCommandCode]);
6534
- const facts = (0, react.useMemo)(() => selectBadgeFacts$2(status), [status]);
7592
+ const facts = (0, react.useMemo)(() => selectBadgeFacts$3(status), [status]);
6535
7593
  if (!isCommandCode || !status?.authenticated || facts === null) return null;
6536
7594
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6537
7595
  className: "dsha-composer-quota",
@@ -6548,14 +7606,14 @@ window.__ModuleLoader__.load({
6548
7606
  })]
6549
7607
  });
6550
7608
  }
6551
- function useStore$2(store) {
7609
+ function useStore$3(store) {
6552
7610
  return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
6553
7611
  }
6554
7612
  //#endregion
6555
7613
  //#region src/client/kimi-code/KimiCodeComposerQuota.tsx
6556
- const API$1 = "/kimi-code/api";
6557
- async function fetchApi$1(path, options) {
6558
- const res = await fetch(`${API$1}${path}`, {
7614
+ const API$2 = "/kimi-code/api";
7615
+ async function fetchApi$2(path, options) {
7616
+ const res = await fetch(`${API$2}${path}`, {
6559
7617
  ...options,
6560
7618
  headers: {
6561
7619
  "Content-Type": "application/json",
@@ -6573,7 +7631,7 @@ window.__ModuleLoader__.load({
6573
7631
  * blocks work soonest, so it wins over the longer pools; the 7-day allowance
6574
7632
  * shows only when no 5-hour window is reported.
6575
7633
  */
6576
- function selectBadgeFacts$1(status) {
7634
+ function selectBadgeFacts$2(status) {
6577
7635
  const quota = status?.quota;
6578
7636
  if (quota === null || quota === void 0) return {
6579
7637
  text: "—",
@@ -6605,7 +7663,7 @@ window.__ModuleLoader__.load({
6605
7663
  };
6606
7664
  }
6607
7665
  function KimiCodeComposerQuota({ directory, loadModelDirectory }) {
6608
- const modelState = useStore$1(directory);
7666
+ const modelState = useStore$2(directory);
6609
7667
  const [status, setStatus] = (0, react.useState)(null);
6610
7668
  const [loading, setLoading] = (0, react.useState)(false);
6611
7669
  const mountedRef = (0, react.useRef)(false);
@@ -6623,7 +7681,7 @@ window.__ModuleLoader__.load({
6623
7681
  if (!mountedRef.current) return;
6624
7682
  setLoading(true);
6625
7683
  try {
6626
- const data = refresh ? await fetchApi$1("/quota", { method: "POST" }) : await fetchApi$1("/status");
7684
+ const data = refresh ? await fetchApi$2("/quota", { method: "POST" }) : await fetchApi$2("/status");
6627
7685
  if (mountedRef.current) setStatus(data);
6628
7686
  } catch {} finally {
6629
7687
  if (mountedRef.current) setLoading(false);
@@ -6639,7 +7697,7 @@ window.__ModuleLoader__.load({
6639
7697
  window.clearInterval(timer);
6640
7698
  };
6641
7699
  }, [fetchStatus, isKimiCode]);
6642
- const facts = (0, react.useMemo)(() => selectBadgeFacts$1(status), [status]);
7700
+ const facts = (0, react.useMemo)(() => selectBadgeFacts$2(status), [status]);
6643
7701
  if (!isKimiCode || !status?.authenticated || facts === null) return null;
6644
7702
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6645
7703
  className: "dsha-composer-quota",
@@ -6656,12 +7714,12 @@ window.__ModuleLoader__.load({
6656
7714
  })]
6657
7715
  });
6658
7716
  }
6659
- function useStore$1(store) {
7717
+ function useStore$2(store) {
6660
7718
  return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
6661
7719
  }
6662
7720
  //#endregion
6663
7721
  //#region src/client/kimi-code/styles.ts
6664
- const STYLE_ID$1 = "dsh-kimi-code-settings-style";
7722
+ const STYLE_ID$2 = "dsh-kimi-code-settings-style";
6665
7723
  /**
6666
7724
  * Node the base control styles come from.
6667
7725
  *
@@ -6753,15 +7811,15 @@ window.__ModuleLoader__.load({
6753
7811
  function installKimiCodeStyles() {
6754
7812
  if (typeof document === "undefined" || document.getElementById("dsh-kimi-code-settings-style")) return;
6755
7813
  const style = document.createElement("style");
6756
- style.id = STYLE_ID$1;
7814
+ style.id = STYLE_ID$2;
6757
7815
  style.textContent = BASE;
6758
7816
  document.head.appendChild(style);
6759
7817
  }
6760
7818
  //#endregion
6761
7819
  //#region src/client/workbuddy/WorkBuddyComposerQuota.tsx
6762
- const API = "/workbuddy/api";
6763
- async function fetchApi(path, options) {
6764
- const res = await fetch(`${API}${path}`, {
7820
+ const API$1 = "/workbuddy/api";
7821
+ async function fetchApi$1(path, options) {
7822
+ const res = await fetch(`${API$1}${path}`, {
6765
7823
  ...options,
6766
7824
  headers: {
6767
7825
  "Content-Type": "application/json",
@@ -6780,7 +7838,7 @@ window.__ModuleLoader__.load({
6780
7838
  * payload reports both a cycle meter and a package meter, and the cycle meter
6781
7839
  * is the one that actually resets, so it is preferred when both exist.
6782
7840
  */
6783
- function selectBadgeFacts(status) {
7841
+ function selectBadgeFacts$1(status) {
6784
7842
  const quota = status?.quota;
6785
7843
  if (quota === null || quota === void 0) return {
6786
7844
  text: "—",
@@ -6808,7 +7866,7 @@ window.__ModuleLoader__.load({
6808
7866
  };
6809
7867
  }
6810
7868
  function WorkBuddyComposerQuota({ directory, loadModelDirectory }) {
6811
- const modelState = useStore(directory);
7869
+ const modelState = useStore$1(directory);
6812
7870
  const [status, setStatus] = (0, react.useState)(null);
6813
7871
  const [loading, setLoading] = (0, react.useState)(false);
6814
7872
  const mountedRef = (0, react.useRef)(false);
@@ -6826,7 +7884,7 @@ window.__ModuleLoader__.load({
6826
7884
  if (!mountedRef.current) return;
6827
7885
  setLoading(true);
6828
7886
  try {
6829
- const data = refresh ? await fetchApi("/quota", { method: "POST" }) : await fetchApi("/status");
7887
+ const data = refresh ? await fetchApi$1("/quota", { method: "POST" }) : await fetchApi$1("/status");
6830
7888
  if (mountedRef.current) setStatus(data);
6831
7889
  } catch {} finally {
6832
7890
  if (mountedRef.current) setLoading(false);
@@ -6842,7 +7900,7 @@ window.__ModuleLoader__.load({
6842
7900
  window.clearInterval(timer);
6843
7901
  };
6844
7902
  }, [fetchStatus, isWorkBuddy]);
6845
- const facts = (0, react.useMemo)(() => selectBadgeFacts(status), [status]);
7903
+ const facts = (0, react.useMemo)(() => selectBadgeFacts$1(status), [status]);
6846
7904
  if (!isWorkBuddy || !status?.authenticated || facts === null) return null;
6847
7905
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
6848
7906
  className: "dsha-composer-quota",
@@ -6859,12 +7917,12 @@ window.__ModuleLoader__.load({
6859
7917
  })]
6860
7918
  });
6861
7919
  }
6862
- function useStore(store) {
7920
+ function useStore$1(store) {
6863
7921
  return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
6864
7922
  }
6865
7923
  //#endregion
6866
7924
  //#region src/client/workbuddy/styles.ts
6867
- const STYLE_ID = "dsh-workbuddy-settings-style";
7925
+ const STYLE_ID$1 = "dsh-workbuddy-settings-style";
6868
7926
  /**
6869
7927
  * WorkBuddy-only additions to the shared settings design system.
6870
7928
  *
@@ -6880,12 +7938,141 @@ window.__ModuleLoader__.load({
6880
7938
  function installWorkBuddyStyles() {
6881
7939
  if (typeof document === "undefined" || document.getElementById("dsh-workbuddy-settings-style")) return;
6882
7940
  const style = document.createElement("style");
6883
- style.id = STYLE_ID;
7941
+ style.id = STYLE_ID$1;
6884
7942
  style.textContent = `
6885
7943
  .dshwb-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}
6886
7944
  .dsha-account-add-actions{display:flex;flex-wrap:wrap;gap:8px}
6887
7945
  .dsha-account-add-actions .dsha-btn{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}
6888
7946
  .dsha-account-add-actions .dsha-btn:hover:not(:disabled){opacity:.9;background:var(--dsw-alias-button-info-fill,#397ee8)}
7947
+ `;
7948
+ document.head.append(style);
7949
+ }
7950
+ //#endregion
7951
+ //#region src/client/zhipu/ZhipuComposerQuota.tsx
7952
+ const API = "/zhipu/api";
7953
+ async function fetchApi(path, options) {
7954
+ const res = await fetch(`${API}${path}`, {
7955
+ ...options,
7956
+ headers: {
7957
+ "Content-Type": "application/json",
7958
+ ...options?.headers
7959
+ }
7960
+ });
7961
+ const json = await res.json();
7962
+ if (!res.ok || !json.ok) throw new Error(json.error || `HTTP ${res.status}`);
7963
+ return json.value;
7964
+ }
7965
+ /**
7966
+ * Pick the most meaningful number for the badge.
7967
+ *
7968
+ * A Coding Plan is bounded by two windows at once, and the one closer to
7969
+ * exhaustion is what the user needs to see: the 5-hour window can be spent
7970
+ * while the weekly one has room, and the reverse. So the tightest *remaining*
7971
+ * fraction wins, and its window names the tooltip.
7972
+ */
7973
+ function selectBadgeFacts(status) {
7974
+ const quota = status?.quota;
7975
+ if (quota === null || quota === void 0) return {
7976
+ text: "—",
7977
+ tooltip: "GLM Coding Plan quota unavailable — click to refresh",
7978
+ level: "normal"
7979
+ };
7980
+ let tightest = null;
7981
+ for (const window of quota.windows) {
7982
+ if (window.remainingFraction === null) continue;
7983
+ if (tightest === null || window.remainingFraction < tightest.remaining) tightest = {
7984
+ label: window.label,
7985
+ remaining: window.remainingFraction
7986
+ };
7987
+ }
7988
+ if (tightest === null) return {
7989
+ text: "—",
7990
+ tooltip: "GLM Coding Plan quota unavailable — click to refresh",
7991
+ level: "normal"
7992
+ };
7993
+ const remaining = Math.round(tightest.remaining * 100);
7994
+ return {
7995
+ text: `${remaining}%`,
7996
+ tooltip: `[GLM Coding Plan] ${tightest.label}: ${remaining}% left`,
7997
+ level: remaining <= 5 ? "danger" : remaining <= 20 ? "warning" : "normal"
7998
+ };
7999
+ }
8000
+ function ZhipuComposerQuota({ directory, loadModelDirectory }) {
8001
+ const modelState = useStore(directory);
8002
+ const [status, setStatus] = (0, react.useState)(null);
8003
+ const [loading, setLoading] = (0, react.useState)(false);
8004
+ const mountedRef = (0, react.useRef)(false);
8005
+ const isZhipu = modelState.current?.provider === "zhipu-coding-plan";
8006
+ (0, react.useEffect)(() => {
8007
+ loadModelDirectory();
8008
+ }, [loadModelDirectory]);
8009
+ (0, react.useEffect)(() => {
8010
+ mountedRef.current = true;
8011
+ return () => {
8012
+ mountedRef.current = false;
8013
+ };
8014
+ }, []);
8015
+ const fetchStatus = (0, react.useCallback)(async (refresh = false) => {
8016
+ if (!mountedRef.current) return;
8017
+ setLoading(true);
8018
+ try {
8019
+ const data = refresh ? await fetchApi("/quota", { method: "POST" }) : await fetchApi("/status");
8020
+ if (mountedRef.current) setStatus(data);
8021
+ } catch {} finally {
8022
+ if (mountedRef.current) setLoading(false);
8023
+ }
8024
+ }, []);
8025
+ (0, react.useEffect)(() => {
8026
+ if (!isZhipu) return;
8027
+ fetchStatus(false);
8028
+ const timer = window.setInterval(() => {
8029
+ if (document.visibilityState === "visible") fetchStatus(false);
8030
+ }, 6e4);
8031
+ return () => {
8032
+ window.clearInterval(timer);
8033
+ };
8034
+ }, [fetchStatus, isZhipu]);
8035
+ const facts = (0, react.useMemo)(() => selectBadgeFacts(status), [status]);
8036
+ if (!isZhipu || !status?.authenticated || facts === null) return null;
8037
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
8038
+ className: "dsha-composer-quota",
8039
+ "data-level": facts.level,
8040
+ title: facts.tooltip,
8041
+ "aria-label": facts.tooltip,
8042
+ onClick: () => void fetchStatus(true),
8043
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
8044
+ className: "dsha-composer-quota-label",
8045
+ children: "额度"
8046
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", {
8047
+ className: "dsha-composer-quota-val",
8048
+ children: loading ? "…" : facts.text
8049
+ })]
8050
+ });
8051
+ }
8052
+ function useStore(store) {
8053
+ return (0, react.useSyncExternalStore)((listener) => store.subscribe(listener), () => store.getSnapshot(), () => store.getSnapshot());
8054
+ }
8055
+ //#endregion
8056
+ //#region src/client/zhipu/styles.ts
8057
+ const STYLE_ID = "dsh-zhipu-settings-style";
8058
+ /**
8059
+ * GLM Coding Plan additions to the shared settings design system.
8060
+ *
8061
+ * The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, the
8062
+ * account card, the meters, …) come from the stylesheets the sibling routes
8063
+ * install, in the same order the client installs them, so this file declares
8064
+ * only what stays unique to this card: the key-hint line and the region
8065
+ * selector that sits beside the key input.
8066
+ */
8067
+ function installZhipuStyles() {
8068
+ if (typeof document === "undefined" || document.getElementById("dsh-zhipu-settings-style")) return;
8069
+ const style = document.createElement("style");
8070
+ style.id = STYLE_ID;
8071
+ style.textContent = `
8072
+ .dshzp-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}
8073
+ .dshzp-keyrow{display:flex;flex-wrap:wrap;gap:8px;align-items:center}
8074
+ .dshzp-keyrow .dsha-select{min-width:190px}
8075
+ .dshzp-keyrow input[type=password]{flex:1 1 260px;min-width:200px}
6889
8076
  `;
6890
8077
  document.head.append(style);
6891
8078
  }
@@ -7232,22 +8419,27 @@ window.__ModuleLoader__.load({
7232
8419
  function apply(ctx) {
7233
8420
  ctx.effect(() => ctx.locale.register(NS, dictionaries), "dsh-chatgpt-subscription: dictionaries");
7234
8421
  ctx.effect(() => installStyles(), "dsh-chatgpt-subscription: styles");
7235
- ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$4), "dsh-antigravity: dictionaries");
8422
+ ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$5), "dsh-antigravity: dictionaries");
7236
8423
  ctx.effect(() => {
7237
8424
  installAntigravityStyles();
7238
8425
  return () => {};
7239
8426
  }, "dsh-antigravity: styles");
7240
- ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$3), "dsh-command-code: dictionaries");
7241
- ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$2), "dsh-kimi-code: dictionaries");
8427
+ ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$4), "dsh-command-code: dictionaries");
8428
+ ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$3), "dsh-kimi-code: dictionaries");
7242
8429
  ctx.effect(() => {
7243
8430
  installKimiCodeStyles();
7244
8431
  return () => {};
7245
8432
  }, "dsh-kimi-code: styles");
7246
- ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$1), "dsh-workbuddy: dictionaries");
8433
+ ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$2), "dsh-workbuddy: dictionaries");
7247
8434
  ctx.effect(() => {
7248
8435
  installWorkBuddyStyles();
7249
8436
  return () => {};
7250
8437
  }, "dsh-workbuddy: styles");
8438
+ ctx.effect(() => ctx.locale.register(NS_ZHIPU, dictionaries$1), "dsh-zhipu: dictionaries");
8439
+ ctx.effect(() => {
8440
+ installZhipuStyles();
8441
+ return () => {};
8442
+ }, "dsh-zhipu: styles");
7251
8443
  ctx.effect(() => {
7252
8444
  installPoolStyles();
7253
8445
  return () => {};
@@ -7350,6 +8542,21 @@ window.__ModuleLoader__.load({
7350
8542
  };
7351
8543
  }
7352
8544
  }, WorkBuddyComposerQuota));
8545
+ ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
8546
+ name: "conversation.input.right",
8547
+ id: "zhipu-quota",
8548
+ order: 40,
8549
+ locale: NS_ZHIPU,
8550
+ inject: (sessionId) => {
8551
+ const directory = ctx.modelDirectories.directoryFor(sessionId);
8552
+ return {
8553
+ directory: directory.store,
8554
+ loadModelDirectory: () => {
8555
+ directory.load().catch(() => void 0);
8556
+ }
8557
+ };
8558
+ }
8559
+ }, ZhipuComposerQuota));
7353
8560
  ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
7354
8561
  name: "tool.call.toolview",
7355
8562
  key: CODEX_IMAGE_TOOL_NAME,