@eddyskywalker/dsh-chatgpt-subscription 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +51 -110
  3. package/lib/client.js +1483 -335
  4. package/lib/client.js.map +1 -1
  5. package/lib/index.js +5934 -1974
  6. package/lib/types/client/common/format.d.ts +10 -0
  7. package/lib/types/client/common/format.d.ts.map +1 -1
  8. package/lib/types/client/hub/brand-icons.d.ts +2 -2
  9. package/lib/types/client/hub/brand-icons.d.ts.map +1 -1
  10. package/lib/types/client/hub/providers.d.ts.map +1 -1
  11. package/lib/types/client/index.d.ts +2 -0
  12. package/lib/types/client/index.d.ts.map +1 -1
  13. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts +20 -0
  14. package/lib/types/client/opendesign/OpenDesignComposerQuota.d.ts.map +1 -0
  15. package/lib/types/client/opendesign/OpenDesignSection.d.ts +18 -0
  16. package/lib/types/client/opendesign/OpenDesignSection.d.ts.map +1 -0
  17. package/lib/types/client/opendesign/api.d.ts +45 -0
  18. package/lib/types/client/opendesign/api.d.ts.map +1 -0
  19. package/lib/types/client/opendesign/locales.d.ts +689 -0
  20. package/lib/types/client/opendesign/locales.d.ts.map +1 -0
  21. package/lib/types/client/opendesign/styles.d.ts +11 -0
  22. package/lib/types/client/opendesign/styles.d.ts.map +1 -0
  23. package/lib/types/client/qoder/QoderSection.d.ts +12 -2
  24. package/lib/types/client/qoder/QoderSection.d.ts.map +1 -1
  25. package/lib/types/client/qoder/locales.d.ts +7 -1
  26. package/lib/types/client/qoder/locales.d.ts.map +1 -1
  27. package/lib/types/client/qoder/useQoderSection.d.ts.map +1 -1
  28. package/lib/types/host/common/model-request-control.d.ts +1 -1
  29. package/lib/types/host/common/model-request-control.d.ts.map +1 -1
  30. package/lib/types/host/common/request-diagnostics.d.ts +1 -1
  31. package/lib/types/host/common/request-diagnostics.d.ts.map +1 -1
  32. package/lib/types/host/kimi-code/adapter.d.ts +31 -0
  33. package/lib/types/host/kimi-code/adapter.d.ts.map +1 -1
  34. package/lib/types/host/kimi-code/mapper.d.ts +8 -0
  35. package/lib/types/host/kimi-code/mapper.d.ts.map +1 -1
  36. package/lib/types/host/kimi-code/types.d.ts +92 -0
  37. package/lib/types/host/kimi-code/types.d.ts.map +1 -1
  38. package/lib/types/host/opendesign/account-pool.d.ts +54 -0
  39. package/lib/types/host/opendesign/account-pool.d.ts.map +1 -0
  40. package/lib/types/host/opendesign/adapter.d.ts +69 -0
  41. package/lib/types/host/opendesign/adapter.d.ts.map +1 -0
  42. package/lib/types/host/opendesign/catalog.d.ts +44 -0
  43. package/lib/types/host/opendesign/catalog.d.ts.map +1 -0
  44. package/lib/types/host/opendesign/client.d.ts +148 -0
  45. package/lib/types/host/opendesign/client.d.ts.map +1 -0
  46. package/lib/types/host/opendesign/line.d.ts +49 -0
  47. package/lib/types/host/opendesign/line.d.ts.map +1 -0
  48. package/lib/types/host/opendesign/mapper.d.ts +128 -0
  49. package/lib/types/host/opendesign/mapper.d.ts.map +1 -0
  50. package/lib/types/host/opendesign/oauth.d.ts +105 -0
  51. package/lib/types/host/opendesign/oauth.d.ts.map +1 -0
  52. package/lib/types/host/opendesign/routes.d.ts +74 -0
  53. package/lib/types/host/opendesign/routes.d.ts.map +1 -0
  54. package/lib/types/host/opendesign/token-store.d.ts +154 -0
  55. package/lib/types/host/opendesign/token-store.d.ts.map +1 -0
  56. package/lib/types/host/opendesign/types.d.ts +180 -0
  57. package/lib/types/host/opendesign/types.d.ts.map +1 -0
  58. package/lib/types/host/qoder/adapter.d.ts +26 -2
  59. package/lib/types/host/qoder/adapter.d.ts.map +1 -1
  60. package/lib/types/host/qoder/client.d.ts +112 -0
  61. package/lib/types/host/qoder/client.d.ts.map +1 -1
  62. package/lib/types/host/qoder/model-catalog.d.ts +52 -6
  63. package/lib/types/host/qoder/model-catalog.d.ts.map +1 -1
  64. package/lib/types/host/qoder/routes.d.ts +23 -0
  65. package/lib/types/host/qoder/routes.d.ts.map +1 -1
  66. package/lib/types/host/qoder/token-store.d.ts +56 -7
  67. package/lib/types/host/qoder/token-store.d.ts.map +1 -1
  68. package/lib/types/index.d.ts +11 -1
  69. package/lib/types/index.d.ts.map +1 -1
  70. package/lib/types/shared/opendesign-contracts.d.ts +159 -0
  71. package/lib/types/shared/opendesign-contracts.d.ts.map +1 -0
  72. package/lib/types/shared/qoder-contracts.d.ts +40 -1
  73. package/lib/types/shared/qoder-contracts.d.ts.map +1 -1
  74. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -423,6 +423,10 @@ window.__ModuleLoader__.load({
423
423
  "cline-pass": {
424
424
  viewBox: "0 0 113 113",
425
425
  body: "<path d=\"M56.4998 8.99805L56.4999 5.29805H56.4998V8.99805ZM68.4998 20.708L72.1998 20.7081V20.708H68.4998ZM67.9929 25L64.3662 24.2671L63.4704 28.7H67.9929V25ZM84.4998 25L84.4998 21.3H84.4998V25ZM95.7 49.7998H92V51.2066L92.9346 52.258L95.7 49.7998ZM108.027 63.667L110.793 61.2088L110.792 61.2088L108.027 63.667ZM108.027 64.7305L110.792 67.1887L110.793 67.1883L108.027 64.7305ZM95.7 78.5977L92.9346 76.1394L92 77.1909V78.5977H95.7ZM95.7 92.2002L99.3999 92.2002V92.2002H95.7ZM84.4998 103.4V107.1H84.4998L84.4998 103.4ZM17.2996 92.2002H13.5996V92.2002L17.2996 92.2002ZM17.2996 78.5986H20.9996V77.1918L20.0649 76.1404L17.2996 78.5986ZM4.97144 64.7305L2.20602 67.1886L2.20611 67.1887L4.97144 64.7305ZM4.97144 63.667L7.73685 66.1251L7.73685 66.1251L4.97144 63.667ZM17.2996 49.7979L20.065 52.256L20.9996 51.2046V49.7979H17.2996ZM45.0066 25V28.7H49.5292L48.6333 24.267L45.0066 25ZM44.4998 20.708H40.7998V20.7081L44.4998 20.708ZM56.4998 8.99805L56.4996 12.698C61.1812 12.6982 64.7998 16.3247 64.7998 20.708H68.4998H72.1998C72.1998 12.0452 65.0728 5.29829 56.4999 5.29805L56.4998 8.99805ZM68.4998 20.708L64.7998 20.7079C64.7997 21.6154 64.6614 22.8066 64.3662 24.2671L67.9929 25L71.6196 25.7329C71.969 24.004 72.1997 22.2864 72.1998 20.7081L68.4998 20.708ZM67.9929 25V28.7H84.4998V25V21.3H67.9929V25ZM84.4998 25L84.4997 28.7C88.6419 28.7001 92 32.0582 92 36.2002H95.7H99.3999C99.3999 27.9712 92.7287 21.3001 84.4998 21.3L84.4998 25ZM95.7 36.2002H92V49.7998H95.7H99.3999V36.2002H95.7ZM95.7 49.7998L92.9346 52.258L105.262 66.1252L108.027 63.667L110.792 61.2088L98.4653 47.3416L95.7 49.7998ZM108.027 63.667L105.262 66.1251C104.285 65.026 104.285 63.371 105.261 62.2727L108.027 64.7305L110.793 67.1883C112.308 65.4837 112.308 62.9141 110.793 61.2088L108.027 63.667ZM108.027 64.7305L105.262 62.2722L92.9346 76.1394L95.7 78.5977L98.4653 81.0559L110.792 67.1887L108.027 64.7305ZM95.7 78.5977H92V92.2002H95.7H99.3999V78.5977H95.7ZM95.7 92.2002L92 92.2002C91.9999 96.3422 88.6418 99.7003 84.4997 99.7004L84.4998 103.4L84.4998 107.1C92.7287 107.1 99.3999 100.429 99.3999 92.2002L95.7 92.2002ZM84.4998 103.4V99.7004H28.4998V103.4V107.1H84.4998V103.4ZM28.4998 103.4V99.7004C24.3577 99.7004 20.9996 96.3423 20.9996 92.2002L17.2996 92.2002L13.5996 92.2002C13.5996 100.429 20.2707 107.1 28.4998 107.1V103.4ZM17.2996 92.2002H20.9996V78.5986H17.2996H13.5996V92.2002H17.2996ZM17.2996 78.5986L20.0649 76.1404L7.73676 62.2722L4.97144 64.7305L2.20611 67.1887L14.5342 81.0569L17.2996 78.5986ZM4.97144 64.7305L7.73685 62.2723C8.71353 63.3711 8.71353 65.0264 7.73685 66.1251L4.97144 63.667L2.20602 61.2088C0.690476 62.9138 0.690476 65.4836 2.20602 67.1886L4.97144 64.7305ZM4.97144 63.667L7.73685 66.1251L20.065 52.256L17.2996 49.7979L14.5341 47.3397L2.20602 61.2088L4.97144 63.667ZM17.2996 49.7979H20.9996V36.2002H17.2996H13.5996V49.7979H17.2996ZM17.2996 36.2002H20.9996C20.9996 32.0581 24.3576 28.7 28.4998 28.7V25V21.3C20.2707 21.3 13.5996 27.9712 13.5996 36.2002H17.2996ZM28.4998 25V28.7H45.0066V25V21.3H28.4998V25ZM45.0066 25L48.6333 24.267C48.3381 22.8066 48.1998 21.6154 48.1998 20.7079L44.4998 20.708L40.7998 20.7081C40.7998 22.2864 41.0305 24.0039 41.3799 25.733L45.0066 25ZM44.4998 20.708H48.1998C48.1998 16.3244 51.8182 12.698 56.4998 12.698V8.99805V5.29805C47.9264 5.29805 40.7998 12.0451 40.7998 20.708H44.4998Z\" fill=\"currentColor\"/><rect x=\"66.1001\" y=\"49.8008\" width=\"9.6\" height=\"28.8\" rx=\"4.8\" fill=\"currentColor\"/><rect x=\"37.3\" y=\"49.8008\" width=\"9.6\" height=\"28.8\" rx=\"4.8\" fill=\"currentColor\"/>"
426
+ },
427
+ opendesign: {
428
+ viewBox: "9 9 82 82",
429
+ body: "<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M49.8906 29.7598C61.0699 29.7598 70.1328 38.8226 70.1328 50.002C70.1327 61.1812 61.0699 70.2441 49.8906 70.2441C38.7113 70.2441 29.6485 61.1813 29.6484 50.002C29.6484 38.8226 38.7113 29.7598 49.8906 29.7598ZM41.6445 40.5283C40.9921 40.2762 40.3503 40.9204 40.5996 41.5771L48.3145 61.8779C48.6345 62.7203 49.877 62.4897 49.877 61.5879V49.957H61.665C62.5605 49.957 62.7908 48.7102 61.9551 48.3867L41.6445 40.5283Z\" fill=\"currentColor\"/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M50 9C85.5753 9 91 14.4247 91 50C91 85.5753 85.5753 91 50 91C14.4247 91 9 85.5753 9 50C9 14.4247 14.4247 9 50 9ZM49.8906 24.6992C35.9164 24.6992 24.5879 36.0277 24.5879 50.002C24.5879 55.0491 24.5879 66.2953 24.5879 71.9385C24.588 73.8015 26.091 75.3046 27.9541 75.3047H49.8906C63.8647 75.3046 75.1932 63.976 75.1934 50.002C75.1934 36.0278 63.8647 24.6993 49.8906 24.6992Z\" fill=\"currentColor\"/>"
426
430
  }
427
431
  };
428
432
  function artworkOf(mark) {
@@ -487,6 +491,11 @@ window.__ModuleLoader__.load({
487
491
  fit: "cover"
488
492
  },
489
493
  tile: "#F3F3F3"
494
+ },
495
+ opendesign: {
496
+ mark: "opendesign",
497
+ color: "#202020",
498
+ tile: "#EFF8E9"
490
499
  }
491
500
  };
492
501
  /** One brand mark at a given box size; the artwork is decorative. */
@@ -1109,6 +1118,22 @@ window.__ModuleLoader__.load({
1109
1118
  if (value >= 1e3 && value % 1e3 === 0) return `${value / 1e3}K`;
1110
1119
  return String(value);
1111
1120
  }
1121
+ /**
1122
+ * Render a token count as the compact figure a capability line carries.
1123
+ *
1124
+ * `formatCapacity` above is the capacity FIELD's seeder: it prints only exact
1125
+ * multiples, so 131072 seeds the input as "131072" (a precise draft for an
1126
+ * editable number, which is right). A summary line is a different job — vendor
1127
+ * windows and output caps are binary multiples and raw digits turn the line into
1128
+ * soup. One decimal tells 1M from 1.05M without pretending the figure is exact.
1129
+ */
1130
+ function formatTokenCount(value) {
1131
+ if (!Number.isFinite(value) || value <= 0) return "0";
1132
+ const trim = (text) => text.replace(/\.0+$/, "").replace(/(\.\d*[1-9])0+$/, "$1");
1133
+ if (value >= 1e6) return trim((value / 1e6).toFixed(2)) + "M";
1134
+ if (value >= 1e3) return Math.round(value / 1e3) + "k";
1135
+ return String(value);
1136
+ }
1112
1137
  /** A stamp in the reader's own locale, or an em dash when there is none. */
1113
1138
  function formatDate$1(ms) {
1114
1139
  if (ms === void 0 || ms === null || !Number.isFinite(ms) || ms <= 0) return "—";
@@ -1440,7 +1465,7 @@ window.__ModuleLoader__.load({
1440
1465
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1441
1466
  type: "button",
1442
1467
  className: "dsh-mcl-action",
1443
- disabled: busy || enabledCount === 0,
1468
+ disabled: busy,
1444
1469
  onClick: () => onToggleAll(false),
1445
1470
  children: labels.clearAll
1446
1471
  })]
@@ -2721,7 +2746,7 @@ window.__ModuleLoader__.load({
2721
2746
  //#endregion
2722
2747
  //#region src/client/antigravity/locales.ts
2723
2748
  const NS_ANTIGRAVITY = "dsh-antigravity";
2724
- const zh$12 = {
2749
+ const zh$13 = {
2725
2750
  ...accountPoolZh,
2726
2751
  title: "Antigravity",
2727
2752
  pageDesc: "登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。",
@@ -2799,7 +2824,7 @@ window.__ModuleLoader__.load({
2799
2824
  loginFailed: "登录失败",
2800
2825
  tokens: "tokens"
2801
2826
  };
2802
- const en$12 = {
2827
+ const en$13 = {
2803
2828
  ...accountPoolEn,
2804
2829
  title: "Antigravity",
2805
2830
  pageDesc: "Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.",
@@ -2877,15 +2902,15 @@ window.__ModuleLoader__.load({
2877
2902
  loginFailed: "Login failed",
2878
2903
  tokens: "tokens"
2879
2904
  };
2880
- const dictionaries$12 = {
2881
- zh: zh$12,
2882
- "zh-CN": zh$12,
2883
- en: en$12,
2884
- "en-US": en$12
2905
+ const dictionaries$13 = {
2906
+ zh: zh$13,
2907
+ "zh-CN": zh$13,
2908
+ en: en$13,
2909
+ "en-US": en$13
2885
2910
  };
2886
2911
  //#endregion
2887
2912
  //#region src/client/antigravity/AntigravitySection.tsx
2888
- const api$15 = createLineApi("/antigravity/api", "Antigravity");
2913
+ const api$16 = createLineApi("/antigravity/api", "Antigravity");
2889
2914
  /** A gap in human units, so the idle reading is legible without arithmetic. */
2890
2915
  function idleLabel(ms) {
2891
2916
  const seconds = Math.round(ms / 1e3);
@@ -2917,7 +2942,7 @@ window.__ModuleLoader__.load({
2917
2942
  const [savingModel, setSavingModel] = (0, react.useState)(null);
2918
2943
  /** Follow-up poll owed while the host refreshes the quota behind an answer. */
2919
2944
  const quotaFollowUp = (0, react.useRef)(null);
2920
- const t = zh$12;
2945
+ const t = zh$13;
2921
2946
  const notifyChange = (0, react.useCallback)(() => {
2922
2947
  onModelChange?.();
2923
2948
  loadModelDirectory?.();
@@ -2928,7 +2953,7 @@ window.__ModuleLoader__.load({
2928
2953
  setValidationUrl(null);
2929
2954
  }
2930
2955
  try {
2931
- const data = await api$15.request("/status");
2956
+ const data = await api$16.request("/status");
2932
2957
  setStatus(data);
2933
2958
  setContextDrafts(contextDraftsFor(data));
2934
2959
  quotaFollowUp.current ??= createQuotaFollowUp();
@@ -2960,11 +2985,11 @@ window.__ModuleLoader__.load({
2960
2985
  setError(null);
2961
2986
  setValidationUrl(null);
2962
2987
  setLoginProgress(null);
2963
- const flow = await api$15.request("/login", { method: "POST" });
2988
+ const flow = await api$16.request("/login", { method: "POST" });
2964
2989
  if (flow.authUrl) window.open(flow.authUrl, "_blank");
2965
2990
  const pollTimer = setInterval(async () => {
2966
2991
  try {
2967
- const pollStatus = await api$15.request("/login/status");
2992
+ const pollStatus = await api$16.request("/login/status");
2968
2993
  if (pollStatus.progress) setLoginProgress(pollStatus.progress);
2969
2994
  if (pollStatus.status === "complete") {
2970
2995
  clearInterval(pollTimer);
@@ -2996,7 +3021,7 @@ window.__ModuleLoader__.load({
2996
3021
  try {
2997
3022
  setBusy("quota");
2998
3023
  setError(null);
2999
- const updated = await api$15.request("/quota", { method: "POST" });
3024
+ const updated = await api$16.request("/quota", { method: "POST" });
3000
3025
  setStatus(updated);
3001
3026
  } catch (err) {
3002
3027
  setError(err instanceof Error ? err.message : String(err));
@@ -3008,7 +3033,7 @@ window.__ModuleLoader__.load({
3008
3033
  try {
3009
3034
  setBusy(`primary-${accountId}`);
3010
3035
  setError(null);
3011
- const updated = await api$15.request("/accounts", {
3036
+ const updated = await api$16.request("/accounts", {
3012
3037
  method: "POST",
3013
3038
  body: JSON.stringify({
3014
3039
  action: "set-primary",
@@ -3027,7 +3052,7 @@ window.__ModuleLoader__.load({
3027
3052
  try {
3028
3053
  setBusy(`delete-${accountId}`);
3029
3054
  setError(null);
3030
- const updated = await api$15.request("/accounts", {
3055
+ const updated = await api$16.request("/accounts", {
3031
3056
  method: "POST",
3032
3057
  body: JSON.stringify({
3033
3058
  action: "delete",
@@ -3046,7 +3071,7 @@ window.__ModuleLoader__.load({
3046
3071
  try {
3047
3072
  setBusy(`cooldown-${accountId}`);
3048
3073
  setError(null);
3049
- const updated = await api$15.request("/accounts", {
3074
+ const updated = await api$16.request("/accounts", {
3050
3075
  method: "POST",
3051
3076
  body: JSON.stringify({
3052
3077
  action: "clear-cooldown",
@@ -3064,7 +3089,7 @@ window.__ModuleLoader__.load({
3064
3089
  try {
3065
3090
  setBusy("strategy");
3066
3091
  setError(null);
3067
- const updated = await api$15.request("/accounts", {
3092
+ const updated = await api$16.request("/accounts", {
3068
3093
  method: "POST",
3069
3094
  body: JSON.stringify({
3070
3095
  action: "strategy",
@@ -3083,7 +3108,7 @@ window.__ModuleLoader__.load({
3083
3108
  const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id);
3084
3109
  const nextEnabled = checked ? [.../* @__PURE__ */ new Set([...currentEnabled, modelId])] : currentEnabled.filter((id) => id !== modelId);
3085
3110
  try {
3086
- const updated = await api$15.request("/models", {
3111
+ const updated = await api$16.request("/models", {
3087
3112
  method: "POST",
3088
3113
  body: JSON.stringify({ enabledModelIds: nextEnabled })
3089
3114
  });
@@ -3098,7 +3123,7 @@ window.__ModuleLoader__.load({
3098
3123
  if (!status) return;
3099
3124
  const nextEnabled = selectAll ? status.models.map((m) => m.id) : [];
3100
3125
  try {
3101
- const updated = await api$15.request("/models", {
3126
+ const updated = await api$16.request("/models", {
3102
3127
  method: "POST",
3103
3128
  body: JSON.stringify({ enabledModelIds: nextEnabled })
3104
3129
  });
@@ -3111,7 +3136,7 @@ window.__ModuleLoader__.load({
3111
3136
  };
3112
3137
  const handleUpdateEffort = async (effort) => {
3113
3138
  try {
3114
- const updated = await api$15.request("/settings", {
3139
+ const updated = await api$16.request("/settings", {
3115
3140
  method: "POST",
3116
3141
  body: JSON.stringify({ defaultReasoningEffort: effort })
3117
3142
  });
@@ -3131,7 +3156,7 @@ window.__ModuleLoader__.load({
3131
3156
  try {
3132
3157
  setSavingModel(modelId);
3133
3158
  setError(null);
3134
- const updated = await api$15.request("/settings", {
3159
+ const updated = await api$16.request("/settings", {
3135
3160
  method: "POST",
3136
3161
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
3137
3162
  });
@@ -3152,7 +3177,7 @@ window.__ModuleLoader__.load({
3152
3177
  try {
3153
3178
  setSavingModel(modelId);
3154
3179
  setError(null);
3155
- const updated = await api$15.request("/settings", {
3180
+ const updated = await api$16.request("/settings", {
3156
3181
  method: "POST",
3157
3182
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
3158
3183
  });
@@ -3179,7 +3204,7 @@ window.__ModuleLoader__.load({
3179
3204
  try {
3180
3205
  setBusy("context");
3181
3206
  setError(null);
3182
- const updated = await api$15.request("/settings", {
3207
+ const updated = await api$16.request("/settings", {
3183
3208
  method: "POST",
3184
3209
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
3185
3210
  });
@@ -3474,7 +3499,7 @@ window.__ModuleLoader__.load({
3474
3499
  //#endregion
3475
3500
  //#region src/client/command-code/locales.ts
3476
3501
  const NS_COMMAND_CODE = "dsh-command-code";
3477
- const zh$11 = {
3502
+ const zh$12 = {
3478
3503
  ...accountPoolZh,
3479
3504
  title: "Command Code",
3480
3505
  pageDesc: "登录 Command Code,管理可用模型、上下文窗口与额度。",
@@ -3542,7 +3567,7 @@ window.__ModuleLoader__.load({
3542
3567
  loginFailed: "登录失败",
3543
3568
  tokens: "tokens"
3544
3569
  };
3545
- const en$11 = {
3570
+ const en$12 = {
3546
3571
  ...accountPoolEn,
3547
3572
  title: "Command Code",
3548
3573
  pageDesc: "Sign in to Command Code and manage models, context windows, and quota.",
@@ -3610,11 +3635,11 @@ window.__ModuleLoader__.load({
3610
3635
  loginFailed: "Sign-in failed",
3611
3636
  tokens: "tokens"
3612
3637
  };
3613
- const dictionaries$11 = {
3614
- zh: zh$11,
3615
- "zh-CN": zh$11,
3616
- en: en$11,
3617
- "en-US": en$11
3638
+ const dictionaries$12 = {
3639
+ zh: zh$12,
3640
+ "zh-CN": zh$12,
3641
+ en: en$12,
3642
+ "en-US": en$12
3618
3643
  };
3619
3644
  //#endregion
3620
3645
  //#region src/client/command-code/CommandCodeSection.tsx
@@ -3631,7 +3656,7 @@ window.__ModuleLoader__.load({
3631
3656
  xhigh: "X-High",
3632
3657
  max: "Max"
3633
3658
  };
3634
- const api$14 = createLineApi("/command-code/api", "Command Code");
3659
+ const api$15 = createLineApi("/command-code/api", "Command Code");
3635
3660
  /**
3636
3661
  * Route name shown next to a model.
3637
3662
  *
@@ -3655,7 +3680,7 @@ window.__ModuleLoader__.load({
3655
3680
  const [apiKey, setApiKey] = (0, react.useState)("");
3656
3681
  /** Follow-up poll owed while the host refreshes the quota behind an answer. */
3657
3682
  const quotaFollowUp = (0, react.useRef)(null);
3658
- const t = zh$11;
3683
+ const t = zh$12;
3659
3684
  const notifyChange = (0, react.useCallback)(() => {
3660
3685
  onModelChange?.();
3661
3686
  loadModelDirectory?.();
@@ -3663,7 +3688,7 @@ window.__ModuleLoader__.load({
3663
3688
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
3664
3689
  if (!quiet) setError(null);
3665
3690
  try {
3666
- const data = await api$14.request("/status");
3691
+ const data = await api$15.request("/status");
3667
3692
  setStatus(data);
3668
3693
  setContextDrafts(contextDraftsFor(data));
3669
3694
  quotaFollowUp.current ??= createQuotaFollowUp();
@@ -3694,12 +3719,12 @@ window.__ModuleLoader__.load({
3694
3719
  setBusy("login");
3695
3720
  setError(null);
3696
3721
  setLoginProgress(null);
3697
- const flow = await api$14.request("/login", { method: "POST" });
3722
+ const flow = await api$15.request("/login", { method: "POST" });
3698
3723
  if (flow.authUrl) window.open(flow.authUrl, "_blank");
3699
3724
  const pollTimer = window.setInterval(() => {
3700
3725
  (async () => {
3701
3726
  try {
3702
- const poll = await api$14.request("/login/status");
3727
+ const poll = await api$15.request("/login/status");
3703
3728
  if (poll.progress) setLoginProgress(poll.progress);
3704
3729
  if (poll.status === "complete") {
3705
3730
  window.clearInterval(pollTimer);
@@ -3731,7 +3756,7 @@ window.__ModuleLoader__.load({
3731
3756
  try {
3732
3757
  setBusy("apikey");
3733
3758
  setError(null);
3734
- const updated = await api$14.request("/login/apikey", {
3759
+ const updated = await api$15.request("/login/apikey", {
3735
3760
  method: "POST",
3736
3761
  body: JSON.stringify({ apiKey })
3737
3762
  });
@@ -3749,7 +3774,7 @@ window.__ModuleLoader__.load({
3749
3774
  try {
3750
3775
  setBusy(`${action}-${accountId}`);
3751
3776
  setError(null);
3752
- const updated = await api$14.request("/accounts", {
3777
+ const updated = await api$15.request("/accounts", {
3753
3778
  method: "POST",
3754
3779
  body: JSON.stringify({
3755
3780
  action,
@@ -3768,7 +3793,7 @@ window.__ModuleLoader__.load({
3768
3793
  try {
3769
3794
  setBusy("strategy");
3770
3795
  setError(null);
3771
- const updated = await api$14.request("/accounts", {
3796
+ const updated = await api$15.request("/accounts", {
3772
3797
  method: "POST",
3773
3798
  body: JSON.stringify({
3774
3799
  action: "strategy",
@@ -3791,7 +3816,7 @@ window.__ModuleLoader__.load({
3791
3816
  const handleRelogin = (accountId) => {
3792
3817
  (async () => {
3793
3818
  try {
3794
- const updated = await api$14.request("/accounts", {
3819
+ const updated = await api$15.request("/accounts", {
3795
3820
  method: "POST",
3796
3821
  body: JSON.stringify({
3797
3822
  action: "relogin",
@@ -3810,7 +3835,7 @@ window.__ModuleLoader__.load({
3810
3835
  try {
3811
3836
  setBusy("quota");
3812
3837
  setError(null);
3813
- const updated = await api$14.request("/quota", { method: "POST" });
3838
+ const updated = await api$15.request("/quota", { method: "POST" });
3814
3839
  setStatus(updated);
3815
3840
  } catch (err) {
3816
3841
  setError(err instanceof Error ? err.message : String(err));
@@ -3822,7 +3847,7 @@ window.__ModuleLoader__.load({
3822
3847
  try {
3823
3848
  setBusy("catalog");
3824
3849
  setError(null);
3825
- const updated = await api$14.request("/catalog/refresh", { method: "POST" });
3850
+ const updated = await api$15.request("/catalog/refresh", { method: "POST" });
3826
3851
  setStatus(updated);
3827
3852
  setContextDrafts(contextDraftsFor(updated));
3828
3853
  notifyChange();
@@ -3836,7 +3861,7 @@ window.__ModuleLoader__.load({
3836
3861
  try {
3837
3862
  setBusy("connection");
3838
3863
  setError(null);
3839
- await api$14.post("/connection/test");
3864
+ await api$15.post("/connection/test");
3840
3865
  await loadStatus(true);
3841
3866
  } catch (err) {
3842
3867
  setError(err instanceof Error ? err.message : String(err));
@@ -3846,7 +3871,7 @@ window.__ModuleLoader__.load({
3846
3871
  };
3847
3872
  const applyEnabled = async (enabledModelIds) => {
3848
3873
  try {
3849
- const updated = await api$14.request("/models", {
3874
+ const updated = await api$15.request("/models", {
3850
3875
  method: "POST",
3851
3876
  body: JSON.stringify({ enabledModelIds })
3852
3877
  });
@@ -3869,7 +3894,7 @@ window.__ModuleLoader__.load({
3869
3894
  };
3870
3895
  const handleUpdateEffort = async (effort) => {
3871
3896
  try {
3872
- const updated = await api$14.request("/settings", {
3897
+ const updated = await api$15.request("/settings", {
3873
3898
  method: "POST",
3874
3899
  body: JSON.stringify({ defaultReasoningEffort: effort })
3875
3900
  });
@@ -3889,7 +3914,7 @@ window.__ModuleLoader__.load({
3889
3914
  try {
3890
3915
  setSavingModel(modelId);
3891
3916
  setError(null);
3892
- const updated = await api$14.request("/settings", {
3917
+ const updated = await api$15.request("/settings", {
3893
3918
  method: "POST",
3894
3919
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
3895
3920
  });
@@ -3910,7 +3935,7 @@ window.__ModuleLoader__.load({
3910
3935
  try {
3911
3936
  setSavingModel(modelId);
3912
3937
  setError(null);
3913
- const updated = await api$14.request("/settings", {
3938
+ const updated = await api$15.request("/settings", {
3914
3939
  method: "POST",
3915
3940
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
3916
3941
  });
@@ -3937,7 +3962,7 @@ window.__ModuleLoader__.load({
3937
3962
  try {
3938
3963
  setBusy("context");
3939
3964
  setError(null);
3940
- const updated = await api$14.request("/settings", {
3965
+ const updated = await api$15.request("/settings", {
3941
3966
  method: "POST",
3942
3967
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
3943
3968
  });
@@ -4236,7 +4261,7 @@ window.__ModuleLoader__.load({
4236
4261
  //#endregion
4237
4262
  //#region src/client/kimi-code/locales.ts
4238
4263
  const NS_KIMI_CODE = "dsh-kimi-code";
4239
- const zh$10 = {
4264
+ const zh$11 = {
4240
4265
  ...accountPoolZh,
4241
4266
  title: "Kimi Code",
4242
4267
  pageDesc: "登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。",
@@ -4359,7 +4384,7 @@ window.__ModuleLoader__.load({
4359
4384
  requests: "次请求",
4360
4385
  tokens: "tokens"
4361
4386
  };
4362
- const en$10 = {
4387
+ const en$11 = {
4363
4388
  ...accountPoolEn,
4364
4389
  title: "Kimi Code",
4365
4390
  pageDesc: "Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.",
@@ -4482,11 +4507,11 @@ window.__ModuleLoader__.load({
4482
4507
  requests: "requests",
4483
4508
  tokens: "tokens"
4484
4509
  };
4485
- const dictionaries$10 = {
4486
- zh: zh$10,
4487
- "zh-CN": zh$10,
4488
- en: en$10,
4489
- "en-US": en$10
4510
+ const dictionaries$11 = {
4511
+ zh: zh$11,
4512
+ "zh-CN": zh$11,
4513
+ en: en$11,
4514
+ "en-US": en$11
4490
4515
  };
4491
4516
  //#endregion
4492
4517
  //#region src/client/kimi-code/KimiModelCapabilities.tsx
@@ -4499,7 +4524,7 @@ window.__ModuleLoader__.load({
4499
4524
  * Capabilities are now short tags in their own columns, with the per-model
4500
4525
  * detail kept in a hover title.
4501
4526
  */
4502
- const t = zh$10;
4527
+ const t = zh$11;
4503
4528
  /**
4504
4529
  * Render one quota multiplier the way the official table states it: "2x", "3x".
4505
4530
  *
@@ -4564,7 +4589,7 @@ window.__ModuleLoader__.load({
4564
4589
  }
4565
4590
  //#endregion
4566
4591
  //#region src/client/kimi-code/KimiCodeSection.tsx
4567
- const api$13 = createLineApi("/kimi-code/api", "Kimi Code");
4592
+ const api$14 = createLineApi("/kimi-code/api", "Kimi Code");
4568
4593
  /** Money the service reports in minor units, rendered in its own currency. */
4569
4594
  function formatMoney(cents, currency) {
4570
4595
  if (cents === null) return "—";
@@ -4579,10 +4604,10 @@ window.__ModuleLoader__.load({
4579
4604
  }
4580
4605
  }
4581
4606
  const EFFORT_LABEL = {
4582
- low: zh$10.effortLow,
4583
- high: zh$10.effortHigh,
4584
- max: zh$10.effortMax,
4585
- none: zh$10.effortNone
4607
+ low: zh$11.effortLow,
4608
+ high: zh$11.effortHigh,
4609
+ max: zh$11.effortMax,
4610
+ none: zh$11.effortNone
4586
4611
  };
4587
4612
  /** Human label for the last request's prefix-drift cause. */
4588
4613
  function driftLabel(cause, t) {
@@ -4608,7 +4633,7 @@ window.__ModuleLoader__.load({
4608
4633
  const [connectionNotice, setConnectionNotice] = (0, react.useState)(null);
4609
4634
  /** Follow-up poll owed while the host refreshes the quota behind an answer. */
4610
4635
  const quotaFollowUp = (0, react.useRef)(null);
4611
- const t = zh$10;
4636
+ const t = zh$11;
4612
4637
  const notifyChange = (0, react.useCallback)(() => {
4613
4638
  onModelChange?.();
4614
4639
  loadModelDirectory?.();
@@ -4616,7 +4641,7 @@ window.__ModuleLoader__.load({
4616
4641
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
4617
4642
  if (!quiet) setError(null);
4618
4643
  try {
4619
- const data = await api$13.request("/status");
4644
+ const data = await api$14.request("/status");
4620
4645
  setStatus(data);
4621
4646
  setContextDrafts(contextDraftsFor(data));
4622
4647
  quotaFollowUp.current ??= createQuotaFollowUp();
@@ -4647,7 +4672,7 @@ window.__ModuleLoader__.load({
4647
4672
  const timer = window.setInterval(() => {
4648
4673
  (async () => {
4649
4674
  try {
4650
- const poll = await api$13.request("/login/status");
4675
+ const poll = await api$14.request("/login/status");
4651
4676
  setFlow(poll);
4652
4677
  if (poll.status === "complete") {
4653
4678
  await loadStatus();
@@ -4668,7 +4693,7 @@ window.__ModuleLoader__.load({
4668
4693
  setBusy("login");
4669
4694
  setError(null);
4670
4695
  setCopied(false);
4671
- const next = await api$13.request("/login", {
4696
+ const next = await api$14.request("/login", {
4672
4697
  method: "POST",
4673
4698
  body: JSON.stringify({})
4674
4699
  });
@@ -4681,7 +4706,7 @@ window.__ModuleLoader__.load({
4681
4706
  };
4682
4707
  const handleCancelLogin = async () => {
4683
4708
  try {
4684
- await api$13.request("/login/cancel", { method: "POST" });
4709
+ await api$14.request("/login/cancel", { method: "POST" });
4685
4710
  setFlow({ status: "idle" });
4686
4711
  } catch (err) {
4687
4712
  setError(err instanceof Error ? err.message : String(err));
@@ -4701,7 +4726,7 @@ window.__ModuleLoader__.load({
4701
4726
  try {
4702
4727
  setBusy(`${action}-${accountId}`);
4703
4728
  setError(null);
4704
- const updated = await api$13.request("/accounts", {
4729
+ const updated = await api$14.request("/accounts", {
4705
4730
  method: "POST",
4706
4731
  body: JSON.stringify({
4707
4732
  action,
@@ -4721,7 +4746,7 @@ window.__ModuleLoader__.load({
4721
4746
  try {
4722
4747
  setBusy("strategy");
4723
4748
  setError(null);
4724
- const updated = await api$13.request("/accounts", {
4749
+ const updated = await api$14.request("/accounts", {
4725
4750
  method: "POST",
4726
4751
  body: JSON.stringify({
4727
4752
  action: "strategy",
@@ -4744,7 +4769,7 @@ window.__ModuleLoader__.load({
4744
4769
  const handleRelogin = (accountId) => {
4745
4770
  (async () => {
4746
4771
  try {
4747
- const updated = await api$13.request("/accounts", {
4772
+ const updated = await api$14.request("/accounts", {
4748
4773
  method: "POST",
4749
4774
  body: JSON.stringify({
4750
4775
  action: "relogin",
@@ -4763,7 +4788,7 @@ window.__ModuleLoader__.load({
4763
4788
  try {
4764
4789
  setBusy("quota");
4765
4790
  setError(null);
4766
- const updated = await api$13.request("/quota", { method: "POST" });
4791
+ const updated = await api$14.request("/quota", { method: "POST" });
4767
4792
  setStatus(updated);
4768
4793
  } catch (err) {
4769
4794
  setError(err instanceof Error ? err.message : String(err));
@@ -4776,7 +4801,7 @@ window.__ModuleLoader__.load({
4776
4801
  try {
4777
4802
  setBusy("catalog");
4778
4803
  setError(null);
4779
- const updated = await api$13.request("/catalog/refresh", { method: "POST" });
4804
+ const updated = await api$14.request("/catalog/refresh", { method: "POST" });
4780
4805
  setStatus(updated);
4781
4806
  setContextDrafts(contextDraftsFor(updated));
4782
4807
  notifyChange();
@@ -4791,7 +4816,7 @@ window.__ModuleLoader__.load({
4791
4816
  setBusy("connection");
4792
4817
  setError(null);
4793
4818
  setConnectionNotice(null);
4794
- const result = await api$13.request("/connection/test", { method: "POST" });
4819
+ const result = await api$14.request("/connection/test", { method: "POST" });
4795
4820
  setConnectionNotice(result.connected ? `${t.testSuccess} · ${result.latencyMs} ms` : t.testFailed);
4796
4821
  await loadStatus(true);
4797
4822
  } catch (err) {
@@ -4802,7 +4827,7 @@ window.__ModuleLoader__.load({
4802
4827
  };
4803
4828
  const applyEnabled = async (enabledModelIds) => {
4804
4829
  try {
4805
- const updated = await api$13.request("/models", {
4830
+ const updated = await api$14.request("/models", {
4806
4831
  method: "POST",
4807
4832
  body: JSON.stringify({ enabledModelIds })
4808
4833
  });
@@ -4825,7 +4850,7 @@ window.__ModuleLoader__.load({
4825
4850
  };
4826
4851
  const handleUpdateEffort = async (effort) => {
4827
4852
  try {
4828
- const updated = await api$13.request("/settings", {
4853
+ const updated = await api$14.request("/settings", {
4829
4854
  method: "POST",
4830
4855
  body: JSON.stringify({ defaultReasoningEffort: effort })
4831
4856
  });
@@ -4837,7 +4862,7 @@ window.__ModuleLoader__.load({
4837
4862
  };
4838
4863
  const handleUpdateCacheTtl = async (ttl) => {
4839
4864
  try {
4840
- const updated = await api$13.request("/settings", {
4865
+ const updated = await api$14.request("/settings", {
4841
4866
  method: "POST",
4842
4867
  body: JSON.stringify({ cacheTtl: ttl })
4843
4868
  });
@@ -4857,7 +4882,7 @@ window.__ModuleLoader__.load({
4857
4882
  try {
4858
4883
  setSavingModel(modelId);
4859
4884
  setError(null);
4860
- const updated = await api$13.request("/settings", {
4885
+ const updated = await api$14.request("/settings", {
4861
4886
  method: "POST",
4862
4887
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
4863
4888
  });
@@ -4878,7 +4903,7 @@ window.__ModuleLoader__.load({
4878
4903
  try {
4879
4904
  setSavingModel(modelId);
4880
4905
  setError(null);
4881
- const updated = await api$13.request("/settings", {
4906
+ const updated = await api$14.request("/settings", {
4882
4907
  method: "POST",
4883
4908
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
4884
4909
  });
@@ -4905,7 +4930,7 @@ window.__ModuleLoader__.load({
4905
4930
  try {
4906
4931
  setBusy("context");
4907
4932
  setError(null);
4908
- const updated = await api$13.request("/settings", {
4933
+ const updated = await api$14.request("/settings", {
4909
4934
  method: "POST",
4910
4935
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
4911
4936
  });
@@ -5371,7 +5396,7 @@ window.__ModuleLoader__.load({
5371
5396
  //#endregion
5372
5397
  //#region src/client/workbuddy/locales.ts
5373
5398
  const NS_WORKBUDDY = "dsh-workbuddy";
5374
- const zh$9 = {
5399
+ const zh$10 = {
5375
5400
  title: "WorkBuddy",
5376
5401
  pageDesc: "复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。",
5377
5402
  account: "账号",
@@ -5476,7 +5501,7 @@ window.__ModuleLoader__.load({
5476
5501
  guardrailsDaily: "账号日 token",
5477
5502
  guardrailsModelDaily: "模型日 token"
5478
5503
  };
5479
- const en$9 = {
5504
+ const en$10 = {
5480
5505
  title: "WorkBuddy",
5481
5506
  pageDesc: "Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.",
5482
5507
  account: "Account",
@@ -5581,11 +5606,11 @@ window.__ModuleLoader__.load({
5581
5606
  guardrailsDaily: "Account daily tokens",
5582
5607
  guardrailsModelDaily: "Model daily tokens"
5583
5608
  };
5584
- const dictionaries$9 = {
5585
- zh: zh$9,
5586
- "zh-CN": zh$9,
5587
- en: en$9,
5588
- "en-US": en$9
5609
+ const dictionaries$10 = {
5610
+ zh: zh$10,
5611
+ "zh-CN": zh$10,
5612
+ en: en$10,
5613
+ "en-US": en$10
5589
5614
  };
5590
5615
  //#endregion
5591
5616
  //#region src/client/workbuddy/useWorkBuddySection.ts
@@ -5598,7 +5623,7 @@ window.__ModuleLoader__.load({
5598
5623
  * `WorkBuddySectionView` — so the contract between the two is visible here
5599
5624
  * rather than inferred from the JSX.
5600
5625
  */
5601
- const API$4 = "/workbuddy/api";
5626
+ const API$6 = "/workbuddy/api";
5602
5627
  /**
5603
5628
  * The shared card's label set.
5604
5629
  *
@@ -5622,7 +5647,7 @@ window.__ModuleLoader__.load({
5622
5647
  * is exactly what a stale host half produces) be reported as such instead of as
5623
5648
  * a bare "Unexpected end of JSON input".
5624
5649
  */
5625
- const api$12 = createLineApi(API$4, "WorkBuddy");
5650
+ const api$13 = createLineApi(API$6, "WorkBuddy");
5626
5651
  /**
5627
5652
  * Reasoning levels the default-effort control may offer.
5628
5653
  *
@@ -5679,7 +5704,7 @@ window.__ModuleLoader__.load({
5679
5704
  const quotaFollowUp = (0, react.useRef)(null);
5680
5705
  const [contextDrafts, setContextDrafts] = (0, react.useState)({});
5681
5706
  const [savingModel, setSavingModel] = (0, react.useState)(null);
5682
- const t = zh$9;
5707
+ const t = zh$10;
5683
5708
  const notifyChange = (0, react.useCallback)(() => {
5684
5709
  onModelChange?.();
5685
5710
  loadModelDirectory?.();
@@ -5691,7 +5716,7 @@ window.__ModuleLoader__.load({
5691
5716
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
5692
5717
  if (!quiet) setError(null);
5693
5718
  try {
5694
- const data = await api$12.request("/status");
5719
+ const data = await api$13.request("/status");
5695
5720
  const normalized = normalizeStatus(data);
5696
5721
  setStatus(normalized);
5697
5722
  setStatusFailed(false);
@@ -5726,7 +5751,7 @@ window.__ModuleLoader__.load({
5726
5751
  try {
5727
5752
  setBusy("rescan");
5728
5753
  setError(null);
5729
- const updated = await api$12.request("/rescan", { method: "POST" });
5754
+ const updated = await api$13.request("/rescan", { method: "POST" });
5730
5755
  setStatus(normalizeStatus(updated));
5731
5756
  notifyChange();
5732
5757
  } catch (err) {
@@ -5740,7 +5765,7 @@ window.__ModuleLoader__.load({
5740
5765
  setBusy(`login:${region}`);
5741
5766
  setError(null);
5742
5767
  setLoginProgress(t.loginWaiting);
5743
- const flow = await api$12.request("/accounts/login", {
5768
+ const flow = await api$13.request("/accounts/login", {
5744
5769
  method: "POST",
5745
5770
  body: JSON.stringify({ region })
5746
5771
  });
@@ -5750,7 +5775,7 @@ window.__ModuleLoader__.load({
5750
5775
  const timer = window.setInterval(() => {
5751
5776
  (async () => {
5752
5777
  try {
5753
- const poll = await api$12.request("/accounts/login/status");
5778
+ const poll = await api$13.request("/accounts/login/status");
5754
5779
  if (poll.progress) setLoginProgress(poll.progress);
5755
5780
  if (poll.status === "complete") {
5756
5781
  window.clearInterval(timer);
@@ -5759,7 +5784,7 @@ window.__ModuleLoader__.load({
5759
5784
  loginTimeoutRef.current = null;
5760
5785
  setBusy(null);
5761
5786
  setLoginProgress(null);
5762
- if (poll.accountId) await api$12.request("/settings", {
5787
+ if (poll.accountId) await api$13.request("/settings", {
5763
5788
  method: "POST",
5764
5789
  body: JSON.stringify({ selectedAccountId: poll.accountId })
5765
5790
  });
@@ -5799,7 +5824,7 @@ window.__ModuleLoader__.load({
5799
5824
  try {
5800
5825
  setBusy(`${action}:${accountId}`);
5801
5826
  setError(null);
5802
- const updated = await api$12.request("/accounts/action", {
5827
+ const updated = await api$13.request("/accounts/action", {
5803
5828
  method: "POST",
5804
5829
  body: JSON.stringify({
5805
5830
  action,
@@ -5822,7 +5847,7 @@ window.__ModuleLoader__.load({
5822
5847
  try {
5823
5848
  setBusy("strategy");
5824
5849
  setError(null);
5825
- const updated = await api$12.request("/accounts/strategy", {
5850
+ const updated = await api$13.request("/accounts/strategy", {
5826
5851
  method: "POST",
5827
5852
  body: JSON.stringify({ strategy })
5828
5853
  });
@@ -5837,7 +5862,7 @@ window.__ModuleLoader__.load({
5837
5862
  try {
5838
5863
  setBusy("connection");
5839
5864
  setError(null);
5840
- setConnection(await api$12.request("/connection/test", { method: "POST" }));
5865
+ setConnection(await api$13.request("/connection/test", { method: "POST" }));
5841
5866
  } catch (err) {
5842
5867
  setError(err instanceof Error ? err.message : String(err));
5843
5868
  } finally {
@@ -5848,7 +5873,7 @@ window.__ModuleLoader__.load({
5848
5873
  try {
5849
5874
  setBusy("quota");
5850
5875
  setError(null);
5851
- const updated = await api$12.request("/quota", { method: "POST" });
5876
+ const updated = await api$13.request("/quota", { method: "POST" });
5852
5877
  setStatus(updated);
5853
5878
  } catch (err) {
5854
5879
  setError(err instanceof Error ? err.message : String(err));
@@ -5860,7 +5885,7 @@ window.__ModuleLoader__.load({
5860
5885
  try {
5861
5886
  setBusy("checkin");
5862
5887
  setError(null);
5863
- const updated = await api$12.request("/checkin/now", { method: "POST" });
5888
+ const updated = await api$13.request("/checkin/now", { method: "POST" });
5864
5889
  setStatus(normalizeStatus(updated));
5865
5890
  } catch (err) {
5866
5891
  setError(err instanceof Error ? err.message : String(err));
@@ -5872,7 +5897,7 @@ window.__ModuleLoader__.load({
5872
5897
  try {
5873
5898
  setBusy("checkin");
5874
5899
  setError(null);
5875
- const updated = await api$12.request("/settings", {
5900
+ const updated = await api$13.request("/settings", {
5876
5901
  method: "POST",
5877
5902
  body: JSON.stringify({ checkin })
5878
5903
  });
@@ -5888,7 +5913,7 @@ window.__ModuleLoader__.load({
5888
5913
  try {
5889
5914
  setBusy("outbound");
5890
5915
  setError(null);
5891
- const updated = await api$12.request("/settings", {
5916
+ const updated = await api$13.request("/settings", {
5892
5917
  method: "POST",
5893
5918
  body: JSON.stringify({ outboundIdentity })
5894
5919
  });
@@ -5904,7 +5929,7 @@ window.__ModuleLoader__.load({
5904
5929
  try {
5905
5930
  setBusy("guardrails");
5906
5931
  setError(null);
5907
- const updated = await api$12.request("/settings", {
5932
+ const updated = await api$13.request("/settings", {
5908
5933
  method: "POST",
5909
5934
  body: JSON.stringify({ guardrails })
5910
5935
  });
@@ -5920,7 +5945,7 @@ window.__ModuleLoader__.load({
5920
5945
  try {
5921
5946
  setBusy("atrest");
5922
5947
  setError(null);
5923
- const updated = await api$12.request("/at-rest-key", {
5948
+ const updated = await api$13.request("/at-rest-key", {
5924
5949
  method: "POST",
5925
5950
  body: JSON.stringify({ key })
5926
5951
  });
@@ -5936,7 +5961,7 @@ window.__ModuleLoader__.load({
5936
5961
  try {
5937
5962
  setBusy("atrest");
5938
5963
  setError(null);
5939
- const updated = await api$12.request("/at-rest-key", { method: "DELETE" });
5964
+ const updated = await api$13.request("/at-rest-key", { method: "DELETE" });
5940
5965
  setStatus(normalizeStatus(updated));
5941
5966
  } catch (err) {
5942
5967
  setError(err instanceof Error ? err.message : String(err));
@@ -5951,7 +5976,7 @@ window.__ModuleLoader__.load({
5951
5976
  try {
5952
5977
  setBusy(`model:${modelId}`);
5953
5978
  setError(null);
5954
- const normalized = normalizeStatus(await api$12.request("/settings", {
5979
+ const normalized = normalizeStatus(await api$13.request("/settings", {
5955
5980
  method: "POST",
5956
5981
  body: JSON.stringify({ enabledModelIds: next })
5957
5982
  }));
@@ -5969,7 +5994,7 @@ window.__ModuleLoader__.load({
5969
5994
  try {
5970
5995
  setBusy("models-all");
5971
5996
  setError(null);
5972
- const normalized = normalizeStatus(await api$12.request("/settings", {
5997
+ const normalized = normalizeStatus(await api$13.request("/settings", {
5973
5998
  method: "POST",
5974
5999
  body: JSON.stringify({ enabledModelIds: enabled ? status.models.map((model) => model.id) : [] })
5975
6000
  }));
@@ -5986,7 +6011,7 @@ window.__ModuleLoader__.load({
5986
6011
  try {
5987
6012
  setBusy("effort");
5988
6013
  setError(null);
5989
- const updated = await api$12.request("/settings", {
6014
+ const updated = await api$13.request("/settings", {
5990
6015
  method: "POST",
5991
6016
  body: JSON.stringify({ defaultReasoningEffort: effort })
5992
6017
  });
@@ -6002,7 +6027,7 @@ window.__ModuleLoader__.load({
6002
6027
  try {
6003
6028
  setBusy("catalog");
6004
6029
  setError(null);
6005
- const normalized = normalizeStatus(await api$12.request("/catalog/refresh", { method: "POST" }));
6030
+ const normalized = normalizeStatus(await api$13.request("/catalog/refresh", { method: "POST" }));
6006
6031
  setStatus(normalized);
6007
6032
  setContextDrafts(contextDraftsFor(normalized));
6008
6033
  notifyChange();
@@ -6022,7 +6047,7 @@ window.__ModuleLoader__.load({
6022
6047
  try {
6023
6048
  setSavingModel(modelId);
6024
6049
  setError(null);
6025
- const updated = await api$12.request("/settings", {
6050
+ const updated = await api$13.request("/settings", {
6026
6051
  method: "POST",
6027
6052
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
6028
6053
  });
@@ -6043,7 +6068,7 @@ window.__ModuleLoader__.load({
6043
6068
  try {
6044
6069
  setSavingModel(modelId);
6045
6070
  setError(null);
6046
- const updated = normalizeStatus(await api$12.request("/settings", {
6071
+ const updated = normalizeStatus(await api$13.request("/settings", {
6047
6072
  method: "POST",
6048
6073
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
6049
6074
  }));
@@ -6070,7 +6095,7 @@ window.__ModuleLoader__.load({
6070
6095
  try {
6071
6096
  setBusy("context");
6072
6097
  setError(null);
6073
- const updated = normalizeStatus(await api$12.request("/settings", {
6098
+ const updated = normalizeStatus(await api$13.request("/settings", {
6074
6099
  method: "POST",
6075
6100
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
6076
6101
  }));
@@ -6226,7 +6251,7 @@ window.__ModuleLoader__.load({
6226
6251
  const { login, rescan, accountAction, deleteAccount, setStrategy, testConnection, refreshQuota, checkinNow, updateCheckin, toggleModel, setAllModels, updateEffort, refreshCatalog, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, updateOutboundIdentity, saveAtRestKey, clearAtRestKey, updateGuardrails } = actions;
6227
6252
  const [keyDraft, setKeyDraft] = (0, react.useState)("");
6228
6253
  const [guardrailDrafts, setGuardrailDrafts] = (0, react.useState)({});
6229
- const t = zh$9;
6254
+ const t = zh$10;
6230
6255
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
6231
6256
  className: "dsha-page",
6232
6257
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -6779,10 +6804,10 @@ window.__ModuleLoader__.load({
6779
6804
  * The names stay as they were so the hook that consumes them does not have to
6780
6805
  * change with the reader.
6781
6806
  */
6782
- const api$11 = createLineApi(MINIMAX_CODE_ROUTE_PREFIX, "MiniMax Code");
6783
- api$11.request;
6784
- const get$3 = api$11.get;
6785
- const post$4 = api$11.post;
6807
+ const api$12 = createLineApi(MINIMAX_CODE_ROUTE_PREFIX, "MiniMax Code");
6808
+ api$12.request;
6809
+ const get$3 = api$12.get;
6810
+ const post$4 = api$12.post;
6786
6811
  function messageOf$3(cause) {
6787
6812
  return cause instanceof Error ? cause.message : String(cause);
6788
6813
  }
@@ -6809,7 +6834,7 @@ window.__ModuleLoader__.load({
6809
6834
  //#endregion
6810
6835
  //#region src/client/minimax-code/locales.ts
6811
6836
  const NS_MINIMAX_CODE = "dsh-minimax-code";
6812
- const zh$8 = {
6837
+ const zh$9 = {
6813
6838
  ...accountPoolZh,
6814
6839
  title: "MiniMax Code",
6815
6840
  pageDesc: "登录 MiniMax Code 编程订阅(设备码 OAuth),复用本机 MiniMax Code 的登录态,管理账号、连接与模型。",
@@ -7007,7 +7032,7 @@ window.__ModuleLoader__.load({
7007
7032
  videoHistoryEncrypted: "已由系统凭据后端加密",
7008
7033
  videoHistoryPlain: "本机没有可用的凭据后端,记录为明文"
7009
7034
  };
7010
- const en$8 = {
7035
+ const en$9 = {
7011
7036
  ...accountPoolEn,
7012
7037
  title: "MiniMax Code",
7013
7038
  pageDesc: "Sign in to the MiniMax Code coding subscription (device-code OAuth) and reuse the local MiniMax Code sign-in to manage the account, connection, and models.",
@@ -7205,11 +7230,11 @@ window.__ModuleLoader__.load({
7205
7230
  videoHistoryEncrypted: "Encrypted by the platform credential backend",
7206
7231
  videoHistoryPlain: "No credential backend on this host; stored as plain text"
7207
7232
  };
7208
- const dictionaries$8 = {
7209
- zh: zh$8,
7210
- "zh-CN": zh$8,
7211
- en: en$8,
7212
- "en-US": en$8
7233
+ const dictionaries$9 = {
7234
+ zh: zh$9,
7235
+ "zh-CN": zh$9,
7236
+ en: en$9,
7237
+ "en-US": en$9
7213
7238
  };
7214
7239
  //#endregion
7215
7240
  //#region src/client/minimax-code/useMinimaxCodeSection.ts
@@ -7223,7 +7248,7 @@ window.__ModuleLoader__.load({
7223
7248
  * rather than inferred from the JSX.
7224
7249
  */
7225
7250
  /** The card's own dictionary; stable identity keeps effect dependencies intact. */
7226
- const fallbackTranslate$5 = (key) => zh$8[key];
7251
+ const fallbackTranslate$5 = (key) => zh$9[key];
7227
7252
  /**
7228
7253
  * The shared pool card's labels, resolved through this card's dictionary.
7229
7254
  *
@@ -9282,7 +9307,7 @@ window.__ModuleLoader__.load({
9282
9307
  * 键名重合的会被渲染成 ChatGPT 的措辞,不重合的会把键名本身打印出来)。
9283
9308
  */
9284
9309
  const NS_GLM_CODING_PLAN = "dsh-glm-coding-plan";
9285
- const zh$7 = {
9310
+ const zh$8 = {
9286
9311
  ...accountPoolZh,
9287
9312
  title: "GLM(ZCode 账号)",
9288
9313
  pageDesc: "用 ZCode 账号授权接入 GLM Coding Plan(国区 bigmodel.cn / 国际区 z.ai),管理账号池、套餐额度与模型勾选。两个区域的凭据各自独立,池内可以同时存在两区账号。",
@@ -9376,7 +9401,7 @@ window.__ModuleLoader__.load({
9376
9401
  quotaAllowanceUnknown: "未判定",
9377
9402
  quotaAllowanceHint: "登录时探活认定的额度来源。「免费体验额度」指新用户注册后自动获得、首次使用起 5 天内每天 800 万 token 的体验额度。"
9378
9403
  };
9379
- const en$7 = {
9404
+ const en$8 = {
9380
9405
  ...accountPoolEn,
9381
9406
  title: "GLM (ZCode account)",
9382
9407
  pageDesc: "Sign in with a ZCode account to reach GLM Coding Plan (China bigmodel.cn / International z.ai), and manage the account pool, plan quota and model selection. The two regions hold independent credentials, so a pool can carry accounts from both.",
@@ -9470,11 +9495,11 @@ window.__ModuleLoader__.load({
9470
9495
  quotaAllowanceUnknown: "Undetermined",
9471
9496
  quotaAllowanceHint: "The allowance source established by the sign-in probe. “Free trial allowance” means 8M tokens per day for 5 days from first use, granted automatically to new accounts."
9472
9497
  };
9473
- const dictionaries$7 = {
9474
- zh: zh$7,
9475
- "zh-CN": zh$7,
9476
- en: en$7,
9477
- "en-US": en$7
9498
+ const dictionaries$8 = {
9499
+ zh: zh$8,
9500
+ "zh-CN": zh$8,
9501
+ en: en$8,
9502
+ "en-US": en$8
9478
9503
  };
9479
9504
  /** 一个配额窗口的键到「窗口长度(分钟)」的映射。 */
9480
9505
  const QUOTA_WINDOW_MINUTES$1 = {
@@ -9533,9 +9558,9 @@ window.__ModuleLoader__.load({
9533
9558
  * 除 adopt 与 connection/test 外,全部走共享的 { ok, value } 信封,
9534
9559
  * 因此答案都是裸 DTO——createLineApi 已经把信封拆掉了。
9535
9560
  */
9536
- const api$10 = createLineApi(GLM_CODING_PLAN_ROUTE_PREFIX, "GLM(ZCode 账号)");
9537
- const get$2 = api$10.get;
9538
- const post$3 = api$10.post;
9561
+ const api$11 = createLineApi(GLM_CODING_PLAN_ROUTE_PREFIX, "GLM(ZCode 账号)");
9562
+ const get$2 = api$11.get;
9563
+ const post$3 = api$11.post;
9539
9564
  function messageOf$2(cause) {
9540
9565
  return cause instanceof Error ? cause.message : String(cause);
9541
9566
  }
@@ -9555,7 +9580,7 @@ window.__ModuleLoader__.load({
9555
9580
  /** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
9556
9581
  const LOGIN_POLL_INTERVAL_MS$2 = 2e3;
9557
9582
  /** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
9558
- const fallbackTranslate$4 = (key) => zh$7[key];
9583
+ const fallbackTranslate$4 = (key) => zh$8[key];
9559
9584
  /**
9560
9585
  * 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
9561
9586
  *
@@ -9975,14 +10000,14 @@ window.__ModuleLoader__.load({
9975
10000
  */
9976
10001
  /** 区域的人类可读名,登录与 adopt 两条入口的结果都要说清楚落在哪一区。 */
9977
10002
  function regionLabel$1(region) {
9978
- return region === "cn" ? zh$7.regionCn : zh$7.regionIntl;
10003
+ return region === "cn" ? zh$8.regionCn : zh$8.regionIntl;
9979
10004
  }
9980
10005
  function GlmCodingPlanSection({ onModelChange } = {}) {
9981
10006
  const { state, derived, actions } = useGlmCodingPlanSection({ onModelChange });
9982
10007
  const { status, loading, busy, error, connection, adoptResult, pasteValue, region, pasteOpen, contextDrafts, savingModel } = state;
9983
10008
  const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels } = derived;
9984
10009
  const { setRegion, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, refreshQuota, refreshCatalog, testConnection } = actions;
9985
- const t = zh$7;
10010
+ const t = zh$8;
9986
10011
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
9987
10012
  className: "dsha-page",
9988
10013
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -10447,7 +10472,7 @@ window.__ModuleLoader__.load({
10447
10472
  * provider — the same reason every sibling line has one.
10448
10473
  */
10449
10474
  const NS_CLAUDE = "dsh-claude";
10450
- const zh$6 = {
10475
+ const zh$7 = {
10451
10476
  ...accountPoolZh,
10452
10477
  title: "Claude(订阅)",
10453
10478
  pageDesc: "登录 Claude Pro/Max 订阅,管理模型、思考档位、上下文窗口与额度。",
@@ -10564,7 +10589,7 @@ window.__ModuleLoader__.load({
10564
10589
  copy: "复制",
10565
10590
  copied: "已复制"
10566
10591
  };
10567
- const en$6 = {
10592
+ const en$7 = {
10568
10593
  ...accountPoolEn,
10569
10594
  title: "Claude (subscription)",
10570
10595
  pageDesc: "Sign in to a Claude Pro/Max subscription and manage models, thinking levels, context windows and quota.",
@@ -10681,11 +10706,11 @@ window.__ModuleLoader__.load({
10681
10706
  copy: "Copy",
10682
10707
  copied: "Copied"
10683
10708
  };
10684
- const dictionaries$6 = {
10685
- zh: zh$6,
10686
- "zh-CN": zh$6,
10687
- en: en$6,
10688
- "en-US": en$6
10709
+ const dictionaries$7 = {
10710
+ zh: zh$7,
10711
+ "zh-CN": zh$7,
10712
+ en: en$7,
10713
+ "en-US": en$7
10689
10714
  };
10690
10715
  //#endregion
10691
10716
  //#region src/client/claude/useClaudeSection.ts
@@ -10698,7 +10723,7 @@ window.__ModuleLoader__.load({
10698
10723
  * `ClaudeSectionView` — so the contract between the two is visible here rather
10699
10724
  * than inferred from a thousand lines of JSX.
10700
10725
  */
10701
- const api$9 = createLineApi("/claude/api", "Claude");
10726
+ const api$10 = createLineApi("/claude/api", "Claude");
10702
10727
  /**
10703
10728
  * The poll cadence of a pending sign-in.
10704
10729
  *
@@ -10719,7 +10744,7 @@ window.__ModuleLoader__.load({
10719
10744
  const [connection, setConnection] = (0, react.useState)(null);
10720
10745
  /** Follow-up poll owed while the host refreshes the quota behind an answer. */
10721
10746
  const quotaFollowUp = (0, react.useRef)(null);
10722
- const t = zh$6;
10747
+ const t = zh$7;
10723
10748
  const notifyChange = (0, react.useCallback)(() => {
10724
10749
  onModelChange?.();
10725
10750
  loadModelDirectory?.();
@@ -10731,7 +10756,7 @@ window.__ModuleLoader__.load({
10731
10756
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
10732
10757
  if (!quiet) setError(null);
10733
10758
  try {
10734
- const data = await api$9.request("/status");
10759
+ const data = await api$10.request("/status");
10735
10760
  setStatus(data);
10736
10761
  setContextDrafts(contextDraftsFor(data));
10737
10762
  quotaFollowUp.current ??= createQuotaFollowUp();
@@ -10762,7 +10787,7 @@ window.__ModuleLoader__.load({
10762
10787
  const timer = window.setInterval(() => {
10763
10788
  (async () => {
10764
10789
  try {
10765
- const poll = await api$9.request("/login/status");
10790
+ const poll = await api$10.request("/login/status");
10766
10791
  setFlow(poll);
10767
10792
  if (poll.status === "complete") {
10768
10793
  setPasteValue("");
@@ -10784,7 +10809,7 @@ window.__ModuleLoader__.load({
10784
10809
  setBusy("login");
10785
10810
  setError(null);
10786
10811
  setPasteValue("");
10787
- const next = await api$9.request("/login", {
10812
+ const next = await api$10.request("/login", {
10788
10813
  method: "POST",
10789
10814
  body: JSON.stringify({})
10790
10815
  });
@@ -10798,7 +10823,7 @@ window.__ModuleLoader__.load({
10798
10823
  };
10799
10824
  const cancelLogin = async () => {
10800
10825
  try {
10801
- const next = await api$9.request("/login/cancel", { method: "POST" });
10826
+ const next = await api$10.request("/login/cancel", { method: "POST" });
10802
10827
  setFlow(next);
10803
10828
  } catch (err) {
10804
10829
  reportError(err);
@@ -10810,7 +10835,7 @@ window.__ModuleLoader__.load({
10810
10835
  try {
10811
10836
  setBusy("login-input");
10812
10837
  setError(null);
10813
- const updated = await api$9.request("/login/input", {
10838
+ const updated = await api$10.request("/login/input", {
10814
10839
  method: "POST",
10815
10840
  body: JSON.stringify({ input: pasteValue })
10816
10841
  });
@@ -10834,7 +10859,7 @@ window.__ModuleLoader__.load({
10834
10859
  try {
10835
10860
  setBusy("adopt");
10836
10861
  setError(null);
10837
- const updated = await api$9.request("/adopt", { method: "POST" });
10862
+ const updated = await api$10.request("/adopt", { method: "POST" });
10838
10863
  setStatus(updated);
10839
10864
  setContextDrafts(contextDraftsFor(updated));
10840
10865
  notifyChange();
@@ -10849,7 +10874,7 @@ window.__ModuleLoader__.load({
10849
10874
  try {
10850
10875
  setBusy(accountId === void 0 ? "adopt-disable" : `adopt-disable-${accountId}`);
10851
10876
  setError(null);
10852
- const updated = await api$9.request("/adopt/disable", {
10877
+ const updated = await api$10.request("/adopt/disable", {
10853
10878
  method: "POST",
10854
10879
  body: JSON.stringify(accountId === void 0 ? {} : { accountId })
10855
10880
  });
@@ -10866,7 +10891,7 @@ window.__ModuleLoader__.load({
10866
10891
  try {
10867
10892
  setBusy(`${action}-${accountId}`);
10868
10893
  setError(null);
10869
- const updated = await api$9.request("/accounts", {
10894
+ const updated = await api$10.request("/accounts", {
10870
10895
  method: "POST",
10871
10896
  body: JSON.stringify({
10872
10897
  action,
@@ -10885,7 +10910,7 @@ window.__ModuleLoader__.load({
10885
10910
  try {
10886
10911
  setBusy("strategy");
10887
10912
  setError(null);
10888
- const updated = await api$9.request("/accounts", {
10913
+ const updated = await api$10.request("/accounts", {
10889
10914
  method: "POST",
10890
10915
  body: JSON.stringify({
10891
10916
  action: "strategy",
@@ -10912,7 +10937,7 @@ window.__ModuleLoader__.load({
10912
10937
  setBusy(`relogin-${accountId}`);
10913
10938
  setError(null);
10914
10939
  setPasteValue("");
10915
- const next = await api$9.request("/login", {
10940
+ const next = await api$10.request("/login", {
10916
10941
  method: "POST",
10917
10942
  body: JSON.stringify({ accountId })
10918
10943
  });
@@ -10929,7 +10954,7 @@ window.__ModuleLoader__.load({
10929
10954
  try {
10930
10955
  setBusy("quota");
10931
10956
  setError(null);
10932
- const updated = await api$9.request("/quota", { method: "POST" });
10957
+ const updated = await api$10.request("/quota", { method: "POST" });
10933
10958
  setStatus(updated);
10934
10959
  } catch (err) {
10935
10960
  reportError(err);
@@ -10942,7 +10967,7 @@ window.__ModuleLoader__.load({
10942
10967
  try {
10943
10968
  setBusy("catalog");
10944
10969
  setError(null);
10945
- const updated = await api$9.request("/catalog/refresh", { method: "POST" });
10970
+ const updated = await api$10.request("/catalog/refresh", { method: "POST" });
10946
10971
  setStatus(updated);
10947
10972
  setContextDrafts(contextDraftsFor(updated));
10948
10973
  notifyChange();
@@ -10957,7 +10982,7 @@ window.__ModuleLoader__.load({
10957
10982
  setBusy("connection");
10958
10983
  setError(null);
10959
10984
  setConnection(null);
10960
- const result = await api$9.request("/connection/test", { method: "POST" });
10985
+ const result = await api$10.request("/connection/test", { method: "POST" });
10961
10986
  setConnection(result);
10962
10987
  await loadStatus(true);
10963
10988
  } catch (err) {
@@ -10968,7 +10993,7 @@ window.__ModuleLoader__.load({
10968
10993
  };
10969
10994
  const applyEnabled = async (enabledModelIds) => {
10970
10995
  try {
10971
- const updated = await api$9.request("/models", {
10996
+ const updated = await api$10.request("/models", {
10972
10997
  method: "POST",
10973
10998
  body: JSON.stringify({ enabledModelIds })
10974
10999
  });
@@ -10991,7 +11016,7 @@ window.__ModuleLoader__.load({
10991
11016
  };
10992
11017
  const updateEffort = async (effort) => {
10993
11018
  try {
10994
- const updated = await api$9.request("/settings", {
11019
+ const updated = await api$10.request("/settings", {
10995
11020
  method: "POST",
10996
11021
  body: JSON.stringify({ defaultReasoningEffort: effort })
10997
11022
  });
@@ -11003,7 +11028,7 @@ window.__ModuleLoader__.load({
11003
11028
  };
11004
11029
  const updateCacheTtl = async (ttl) => {
11005
11030
  try {
11006
- const updated = await api$9.request("/settings", {
11031
+ const updated = await api$10.request("/settings", {
11007
11032
  method: "POST",
11008
11033
  body: JSON.stringify({ cacheTtl: ttl })
11009
11034
  });
@@ -11023,7 +11048,7 @@ window.__ModuleLoader__.load({
11023
11048
  try {
11024
11049
  setSavingModel(modelId);
11025
11050
  setError(null);
11026
- const updated = await api$9.request("/settings", {
11051
+ const updated = await api$10.request("/settings", {
11027
11052
  method: "POST",
11028
11053
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } })
11029
11054
  });
@@ -11050,7 +11075,7 @@ window.__ModuleLoader__.load({
11050
11075
  try {
11051
11076
  setSavingModel(modelId);
11052
11077
  setError(null);
11053
- const updated = await api$9.request("/settings", {
11078
+ const updated = await api$10.request("/settings", {
11054
11079
  method: "POST",
11055
11080
  body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } })
11056
11081
  });
@@ -11077,7 +11102,7 @@ window.__ModuleLoader__.load({
11077
11102
  try {
11078
11103
  setBusy("context");
11079
11104
  setError(null);
11080
- const updated = await api$9.request("/settings", {
11105
+ const updated = await api$10.request("/settings", {
11081
11106
  method: "POST",
11082
11107
  body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })
11083
11108
  });
@@ -11166,11 +11191,11 @@ window.__ModuleLoader__.load({
11166
11191
  * out here would hide a choice the host would accept and a catalog may expose.
11167
11192
  */
11168
11193
  const EFFORT_LABELS$1 = {
11169
- low: zh$6.effortLow,
11170
- medium: zh$6.effortMedium,
11171
- high: zh$6.effortHigh,
11172
- xhigh: zh$6.effortXHigh,
11173
- max: zh$6.effortMax
11194
+ low: zh$7.effortLow,
11195
+ medium: zh$7.effortMedium,
11196
+ high: zh$7.effortHigh,
11197
+ xhigh: zh$7.effortXHigh,
11198
+ max: zh$7.effortMax
11174
11199
  };
11175
11200
  /** One-line capability summary shown as a model pill's hover title. */
11176
11201
  function modelFacts(model, t) {
@@ -11191,7 +11216,7 @@ window.__ModuleLoader__.load({
11191
11216
  const { status, loading, busy, error, flow, connection, pasteValue, contextDrafts, savingModel } = state;
11192
11217
  const { accounts, hasAdopted, contextModels, overrideCount, quota, windows, poolLabels } = derived;
11193
11218
  const { login, cancelLogin, submitPaste, adopt, stopImporting, accountAction, setStrategy, relogin, refreshQuota, refreshCatalog, testConnection, toggleModel, setAllModels, updateEffort, updateCacheTtl, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setPasteValue } = actions;
11194
- const t = zh$6;
11219
+ const t = zh$7;
11195
11220
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
11196
11221
  className: "dsha-page",
11197
11222
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -11673,7 +11698,7 @@ window.__ModuleLoader__.load({
11673
11698
  ];
11674
11699
  //#endregion
11675
11700
  //#region src/client/ollama/api.ts
11676
- const API$3 = "/ollama/api";
11701
+ const API$5 = "/ollama/api";
11677
11702
  /**
11678
11703
  * The Ollama settings API, as the card uses it.
11679
11704
  *
@@ -11682,7 +11707,7 @@ window.__ModuleLoader__.load({
11682
11707
  */
11683
11708
  var OllamaApi = class {
11684
11709
  status() {
11685
- return request(`${API$3}/status`);
11710
+ return request(`${API$5}/status`);
11686
11711
  }
11687
11712
  /**
11688
11713
  * One pool action, returning the refreshed status.
@@ -11691,13 +11716,13 @@ window.__ModuleLoader__.load({
11691
11716
  * never has to guess what the pool looks like after a change.
11692
11717
  */
11693
11718
  accountAction(action, body = {}) {
11694
- return post$2(`${API$3}/accounts`, {
11719
+ return post$2(`${API$5}/accounts`, {
11695
11720
  action,
11696
11721
  ...body
11697
11722
  });
11698
11723
  }
11699
11724
  refreshCatalog() {
11700
- return post$2(`${API$3}/catalog/refresh`, {});
11725
+ return post$2(`${API$5}/catalog/refresh`, {});
11701
11726
  }
11702
11727
  /**
11703
11728
  * Store the default thinking level, answering with the refreshed status.
@@ -11712,7 +11737,7 @@ window.__ModuleLoader__.load({
11712
11737
  * explicitly rather than left out of the body.
11713
11738
  */
11714
11739
  setDefaultReasoningEffort(effort) {
11715
- return post$2(`${API$3}/settings`, { defaultReasoningEffort: effort }).then(() => this.status());
11740
+ return post$2(`${API$5}/settings`, { defaultReasoningEffort: effort }).then(() => this.status());
11716
11741
  }
11717
11742
  /**
11718
11743
  * Replace the enabled-model selection.
@@ -11722,7 +11747,7 @@ window.__ModuleLoader__.load({
11722
11747
  * selection before it could answer 'turn this one off'.
11723
11748
  */
11724
11749
  setEnabledModels(enabledModelIds) {
11725
- return post$2(`${API$3}/models`, { enabledModelIds });
11750
+ return post$2(`${API$5}/models`, { enabledModelIds });
11726
11751
  }
11727
11752
  };
11728
11753
  async function post$2(url, body) {
@@ -11782,7 +11807,7 @@ window.__ModuleLoader__.load({
11782
11807
  //#endregion
11783
11808
  //#region src/client/ollama/locales.ts
11784
11809
  const NS_OLLAMA = "dsh-ollama";
11785
- const zh$5 = {
11810
+ const zh$6 = {
11786
11811
  ...accountPoolZh,
11787
11812
  relogin: "更换 Key",
11788
11813
  needsRelogin: "Key 已失效",
@@ -11834,7 +11859,7 @@ window.__ModuleLoader__.load({
11834
11859
  usageNone: "尚无请求",
11835
11860
  usageHint: "按 Ollama 每次响应自带的 token 计数本地累加。"
11836
11861
  };
11837
- const en$5 = {
11862
+ const en$6 = {
11838
11863
  ...accountPoolEn,
11839
11864
  relogin: "Replace Key",
11840
11865
  needsRelogin: "Key rejected",
@@ -11886,15 +11911,15 @@ window.__ModuleLoader__.load({
11886
11911
  usageNone: "No requests yet",
11887
11912
  usageHint: "Summed locally from the token counts Ollama returns on each response."
11888
11913
  };
11889
- const dictionaries$5 = {
11890
- zh: zh$5,
11891
- "zh-CN": zh$5,
11892
- en: en$5,
11893
- "en-US": en$5
11914
+ const dictionaries$6 = {
11915
+ zh: zh$6,
11916
+ "zh-CN": zh$6,
11917
+ en: en$6,
11918
+ "en-US": en$6
11894
11919
  };
11895
11920
  //#endregion
11896
11921
  //#region src/client/ollama/OllamaSection.tsx
11897
- const API$2 = new OllamaApi();
11922
+ const API$4 = new OllamaApi();
11898
11923
  /**
11899
11924
  * What each thinking level says in this card.
11900
11925
  *
@@ -11942,7 +11967,7 @@ window.__ModuleLoader__.load({
11942
11967
  const [enabled, setEnabled] = (0, react.useState)(null);
11943
11968
  const reload = (0, react.useCallback)(async () => {
11944
11969
  try {
11945
- const next = await API$2.status();
11970
+ const next = await API$4.status();
11946
11971
  setStatus(next);
11947
11972
  setEnabled(next.enabledModelIds == null ? null : new Set(next.enabledModelIds));
11948
11973
  } catch (cause) {
@@ -11969,7 +11994,7 @@ window.__ModuleLoader__.load({
11969
11994
  const trimmed = key.trim();
11970
11995
  if (trimmed === "") return;
11971
11996
  run("add", async () => {
11972
- const next = await API$2.accountAction("add", {
11997
+ const next = await API$4.accountAction("add", {
11973
11998
  apiKey: trimmed,
11974
11999
  ...alias.trim() === "" ? {} : { alias: alias.trim() }
11975
12000
  });
@@ -11985,8 +12010,8 @@ window.__ModuleLoader__.load({
11985
12010
  ]);
11986
12011
  const syncCatalog = (0, react.useCallback)(() => {
11987
12012
  run("catalog", async () => {
11988
- await API$2.refreshCatalog();
11989
- return API$2.status();
12013
+ await API$4.refreshCatalog();
12014
+ return API$4.status();
11990
12015
  });
11991
12016
  }, [run]);
11992
12017
  const isModelEnabled = (0, react.useCallback)((id) => {
@@ -11994,9 +12019,9 @@ window.__ModuleLoader__.load({
11994
12019
  }, [enabled]);
11995
12020
  const applyEnabled = (0, react.useCallback)((next) => {
11996
12021
  run("models", async () => {
11997
- const result = await API$2.setEnabledModels(next);
12022
+ const result = await API$4.setEnabledModels(next);
11998
12023
  setEnabled(result.enabledModelIds == null ? null : new Set(result.enabledModelIds));
11999
- return API$2.status();
12024
+ return API$4.status();
12000
12025
  });
12001
12026
  }, [run]);
12002
12027
  const toggleModel = (0, react.useCallback)((id, checked) => {
@@ -12014,9 +12039,9 @@ window.__ModuleLoader__.load({
12014
12039
  applyEnabled(selectAll ? null : []);
12015
12040
  }, [applyEnabled]);
12016
12041
  const setEffort = (0, react.useCallback)((value) => {
12017
- run("effort", () => API$2.setDefaultReasoningEffort(value === "" ? null : value));
12042
+ run("effort", () => API$4.setDefaultReasoningEffort(value === "" ? null : value));
12018
12043
  }, [run]);
12019
- const t = zh$5;
12044
+ const t = zh$6;
12020
12045
  const pool = status?.pool;
12021
12046
  const models = status?.models ?? [];
12022
12047
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [
@@ -12045,10 +12070,10 @@ window.__ModuleLoader__.load({
12045
12070
  labels: t,
12046
12071
  busy,
12047
12072
  onLogin: () => setShowKeyForm((value) => !value),
12048
- onSetPrimary: (id) => void run("set-primary", () => API$2.accountAction("set-primary", { accountId: id })),
12049
- onDelete: (id) => void run("delete", () => API$2.accountAction("delete", { accountId: id })),
12050
- onClearCooldown: (id) => void run("clear-cooldown", () => API$2.accountAction("clear-cooldown", { accountId: id })),
12051
- onSetStrategy: (strategy) => void run("strategy", () => API$2.accountAction("strategy", { strategy })),
12073
+ onSetPrimary: (id) => void run("set-primary", () => API$4.accountAction("set-primary", { accountId: id })),
12074
+ onDelete: (id) => void run("delete", () => API$4.accountAction("delete", { accountId: id })),
12075
+ onClearCooldown: (id) => void run("clear-cooldown", () => API$4.accountAction("clear-cooldown", { accountId: id })),
12076
+ onSetStrategy: (strategy) => void run("strategy", () => API$4.accountAction("strategy", { strategy })),
12052
12077
  renderDetails: (account) => {
12053
12078
  const usage = account.usage;
12054
12079
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [account.lastModelId !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
@@ -12131,7 +12156,7 @@ window.__ModuleLoader__.load({
12131
12156
  className: "dsha-btn",
12132
12157
  disabled: busy !== null,
12133
12158
  onClick: () => setShowKeyForm(false),
12134
- children: zh$5.deleteAccount
12159
+ children: zh$6.deleteAccount
12135
12160
  })]
12136
12161
  })
12137
12162
  ]
@@ -12251,7 +12276,7 @@ window.__ModuleLoader__.load({
12251
12276
  * 键名重合的会被渲染成 ChatGPT 的措辞,不重合的会把键名本身打印出来)。
12252
12277
  */
12253
12278
  const NS_STEP_CODE = "dsh-step-code";
12254
- const zh$4 = {
12279
+ const zh$5 = {
12255
12280
  ...accountPoolZh,
12256
12281
  title: "Step Code(Step Plan 订阅)",
12257
12282
  pageDesc: "用 StepFun 的 Step Plan 订阅(国区 api.stepfun.com / 国际区 api.stepfun.ai)或开放平台 API Key 接入,管理账号池、套餐额度、缓存用量与模型勾选。区域是凭据的属性,两区凭据互不通用,因此号池里可以同时存在两区账号。",
@@ -12420,7 +12445,7 @@ window.__ModuleLoader__.load({
12420
12445
  cacheEmpty: "本进程还没有任何请求回报过用量,跑一次对话后再看。",
12421
12446
  cacheHitRatioUnavailable: "—"
12422
12447
  };
12423
- const en$4 = {
12448
+ const en$5 = {
12424
12449
  ...accountPoolEn,
12425
12450
  title: "Step Code (Step Plan subscription)",
12426
12451
  pageDesc: "Reach StepFun with a Step Plan subscription (China api.stepfun.com / international api.stepfun.ai) or an open-platform API key, and manage the account pool, plan quota, cache usage and model selection. A region is a property of the credential and the two never share, so a pool can carry accounts from both.",
@@ -12587,11 +12612,11 @@ window.__ModuleLoader__.load({
12587
12612
  cacheEmpty: "No request on this machine has reported usage yet — run a conversation and look again.",
12588
12613
  cacheHitRatioUnavailable: "—"
12589
12614
  };
12590
- const dictionaries$4 = {
12591
- zh: zh$4,
12592
- "zh-CN": zh$4,
12593
- en: en$4,
12594
- "en-US": en$4
12615
+ const dictionaries$5 = {
12616
+ zh: zh$5,
12617
+ "zh-CN": zh$5,
12618
+ en: en$5,
12619
+ "en-US": en$5
12595
12620
  };
12596
12621
  /** 一个额度窗口的键到「窗口长度(分钟)」的映射。窗口名由共享组件按长度本地化。 */
12597
12622
  const QUOTA_WINDOW_MINUTES = {
@@ -12683,9 +12708,9 @@ window.__ModuleLoader__.load({
12683
12708
  * **仅有的两处**带秘密的形状,它们只在这两个函数调用点的字面量里出现,
12684
12709
  * 既不进 URL、也不进日志,卡片那边同样没有别的地方可以读到它们。
12685
12710
  */
12686
- const api$8 = createLineApi(STEP_CODE_ROUTE_PREFIX, STEP_CODE_PROVIDER_NAME);
12687
- const get$1 = api$8.get;
12688
- const post$1 = api$8.post;
12711
+ const api$9 = createLineApi(STEP_CODE_ROUTE_PREFIX, STEP_CODE_PROVIDER_NAME);
12712
+ const get$1 = api$9.get;
12713
+ const post$1 = api$9.post;
12689
12714
  function messageOf$1(cause) {
12690
12715
  return cause instanceof Error ? cause.message : String(cause);
12691
12716
  }
@@ -12709,7 +12734,7 @@ window.__ModuleLoader__.load({
12709
12734
  /** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
12710
12735
  const LOGIN_POLL_INTERVAL_MS$1 = 2e3;
12711
12736
  /** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
12712
- const fallbackTranslate$3 = (key) => zh$4[key];
12737
+ const fallbackTranslate$3 = (key) => zh$5[key];
12713
12738
  /**
12714
12739
  * 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
12715
12740
  *
@@ -13396,7 +13421,7 @@ window.__ModuleLoader__.load({
13396
13421
  const { status, loading, busy, error, connection, adoptResult, pasteValue, profile, pasteOpen, contextDrafts, savingModel, quotaAccount, quotaPassword, quotaToken } = state;
13397
13422
  const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels, cache, cacheHitRatio: hitRatio, quotaCredential } = derived;
13398
13423
  const { setProfile, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setDefaultReasoningEffort, setCacheRequestParams, refreshQuota, refreshCatalog, testConnection, setQuotaAccount, setQuotaPassword, setQuotaToken, submitQuotaPassword, submitQuotaToken, clearQuotaCredential } = actions;
13399
- const t = zh$4;
13424
+ const t = zh$5;
13400
13425
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
13401
13426
  className: "dsha-page",
13402
13427
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -14163,7 +14188,7 @@ window.__ModuleLoader__.load({
14163
14188
  }
14164
14189
  //#endregion
14165
14190
  //#region src/client/cline-pass/api.ts
14166
- const api$7 = createLineApi(CLINE_PASS_ROUTE_PREFIX, "Cline Pass");
14191
+ const api$8 = createLineApi(CLINE_PASS_ROUTE_PREFIX, "Cline Pass");
14167
14192
  /**
14168
14193
  * The Cline Pass settings API, as the card uses it.
14169
14194
  *
@@ -14172,92 +14197,92 @@ window.__ModuleLoader__.load({
14172
14197
  */
14173
14198
  var ClinePassApi = class {
14174
14199
  status() {
14175
- return api$7.get("/status");
14200
+ return api$8.get("/status");
14176
14201
  }
14177
14202
  updateSettings(patch) {
14178
- return api$7.post("/settings", patch).then(() => this.status());
14203
+ return api$8.post("/settings", patch).then(() => this.status());
14179
14204
  }
14180
14205
  accountAction(action, body = {}) {
14181
- return api$7.post("/accounts", {
14206
+ return api$8.post("/accounts", {
14182
14207
  action,
14183
14208
  ...body
14184
14209
  });
14185
14210
  }
14186
14211
  /** Verify a key without storing it; the host answers the verdict directly. */
14187
14212
  testKey(body) {
14188
- return api$7.post("/accounts", {
14213
+ return api$8.post("/accounts", {
14189
14214
  action: "test",
14190
14215
  ...body
14191
14216
  });
14192
14217
  }
14193
14218
  /** Start the Cline device-code sign-in. */
14194
14219
  startLogin() {
14195
- return api$7.post("/login/start", {});
14220
+ return api$8.post("/login/start", {});
14196
14221
  }
14197
14222
  /** One poll of the pending sign-in; the host throttles it to WorkOS's interval. */
14198
14223
  loginStatus(id) {
14199
- return api$7.get(`/login/status?id=${encodeURIComponent(id)}`);
14224
+ return api$8.get(`/login/status?id=${encodeURIComponent(id)}`);
14200
14225
  }
14201
14226
  cancelLogin(id) {
14202
- return api$7.post("/login/cancel", { id });
14227
+ return api$8.post("/login/cancel", { id });
14203
14228
  }
14204
14229
  setEnabledModels(enabledModelIds) {
14205
- return api$7.post("/models", { enabledModelIds });
14230
+ return api$8.post("/models", { enabledModelIds });
14206
14231
  }
14207
14232
  setContextWindow(model, contextWindow) {
14208
- return api$7.post("/models/context-window", {
14233
+ return api$8.post("/models/context-window", {
14209
14234
  model,
14210
14235
  contextWindow
14211
14236
  });
14212
14237
  }
14213
14238
  pinModel(model, pin) {
14214
- return api$7.post("/models/pin", {
14239
+ return api$8.post("/models/pin", {
14215
14240
  model,
14216
14241
  ...pin
14217
14242
  });
14218
14243
  }
14219
14244
  resetPin(model) {
14220
- return api$7.post("/models/reset", { model });
14245
+ return api$8.post("/models/reset", { model });
14221
14246
  }
14222
14247
  probe(model) {
14223
- return api$7.post("/models/probe", { model });
14248
+ return api$8.post("/models/probe", { model });
14224
14249
  }
14225
14250
  validate(model) {
14226
- return api$7.post("/models/validate", { model });
14251
+ return api$8.post("/models/validate", { model });
14227
14252
  }
14228
14253
  test(model, pin = {}) {
14229
- return api$7.post("/models/test", {
14254
+ return api$8.post("/models/test", {
14230
14255
  model,
14231
14256
  ...pin
14232
14257
  });
14233
14258
  }
14234
14259
  setVisibility(model, visible) {
14235
- return api$7.post("/models/visibility", {
14260
+ return api$8.post("/models/visibility", {
14236
14261
  model,
14237
14262
  visible
14238
14263
  });
14239
14264
  }
14240
14265
  setVisibilityAll(mode) {
14241
- return api$7.post("/models/visibility-all", { mode });
14266
+ return api$8.post("/models/visibility-all", { mode });
14242
14267
  }
14243
14268
  refreshCatalog() {
14244
- return api$7.post("/catalog/refresh", {});
14269
+ return api$8.post("/catalog/refresh", {});
14245
14270
  }
14246
14271
  readUsage() {
14247
- return api$7.post("/usage", {});
14272
+ return api$8.post("/usage", {});
14248
14273
  }
14249
14274
  history(limit = 25, model = "") {
14250
14275
  const query = new URLSearchParams({
14251
14276
  limit: String(limit),
14252
14277
  ...model === "" ? {} : { model }
14253
14278
  });
14254
- return api$7.get("/history?" + query.toString());
14279
+ return api$8.get("/history?" + query.toString());
14255
14280
  }
14256
14281
  };
14257
14282
  //#endregion
14258
14283
  //#region src/client/cline-pass/locales.ts
14259
14284
  const NS_CLINE_PASS = "dsh-cline-pass";
14260
- const zh$3 = {
14285
+ const zh$4 = {
14261
14286
  ...accountPoolZh,
14262
14287
  relogin: "重新登录",
14263
14288
  needsRelogin: "登录已失效",
@@ -14399,7 +14424,7 @@ window.__ModuleLoader__.load({
14399
14424
  limitRoute: "模型路由按 provider id 抢占:若已有其他插件占用 cline-pass,本卡仍可配置,但请求由对方服务。",
14400
14425
  limitQuota: "额度窗口来自网关的 usage-limits 接口;接口失败时卡片保留上一次读数并显示原因。"
14401
14426
  };
14402
- const en$3 = {
14427
+ const en$4 = {
14403
14428
  ...accountPoolEn,
14404
14429
  relogin: "Sign in again",
14405
14430
  needsRelogin: "Sign-in expired",
@@ -14541,17 +14566,17 @@ window.__ModuleLoader__.load({
14541
14566
  limitRoute: "The route is claimed by provider id: if another plugin already serves cline-pass, this card still configures the line but that provider answers the requests.",
14542
14567
  limitQuota: "Quota windows come from the gateway usage-limits endpoint; when it fails the card keeps the previous reading and says why."
14543
14568
  };
14544
- const dictionaries$3 = {
14545
- zh: zh$3,
14546
- "zh-CN": zh$3,
14547
- en: en$3,
14548
- "en-US": en$3
14569
+ const dictionaries$4 = {
14570
+ zh: zh$4,
14571
+ "zh-CN": zh$4,
14572
+ en: en$4,
14573
+ "en-US": en$4
14549
14574
  };
14550
14575
  //#endregion
14551
14576
  //#region src/client/cline-pass/ClinePassSection.tsx
14552
- const API$1 = new ClinePassApi();
14553
- const ERROR_DETAIL = zh$3.error.split("{detail}")[0] ?? "";
14554
- function detail(error) {
14577
+ const API$3 = new ClinePassApi();
14578
+ const ERROR_DETAIL$1 = zh$4.error.split("{detail}")[0] ?? "";
14579
+ function detail$1(error) {
14555
14580
  return error instanceof Error ? error.message : String(error);
14556
14581
  }
14557
14582
  function statusTone(status) {
@@ -14560,7 +14585,7 @@ window.__ModuleLoader__.load({
14560
14585
  if (status === "bad" || status === "auth") return "danger";
14561
14586
  return "neutral";
14562
14587
  }
14563
- function settingsFormOf(status) {
14588
+ function settingsFormOf$1(status) {
14564
14589
  return {
14565
14590
  baseURL: status.settings.baseURL,
14566
14591
  defaultContextWindow: String(status.settings.defaultContextWindow),
@@ -14598,12 +14623,12 @@ window.__ModuleLoader__.load({
14598
14623
  const [loginFlow, setLoginFlow] = (0, react.useState)(null);
14599
14624
  const reload = (0, react.useCallback)(async () => {
14600
14625
  try {
14601
- const next = await API$1.status();
14626
+ const next = await API$3.status();
14602
14627
  setStatus(next);
14603
- setSettingsForm((current) => current ?? (next.settings === void 0 ? null : settingsFormOf(next)));
14628
+ setSettingsForm((current) => current ?? (next.settings === void 0 ? null : settingsFormOf$1(next)));
14604
14629
  setError(null);
14605
14630
  } catch (cause) {
14606
- setError(detail(cause));
14631
+ setError(detail$1(cause));
14607
14632
  }
14608
14633
  }, []);
14609
14634
  (0, react.useEffect)(() => {
@@ -14631,14 +14656,14 @@ window.__ModuleLoader__.load({
14631
14656
  const flow = loginFlow;
14632
14657
  if (flow === null || flow.status !== "pending") return;
14633
14658
  const timer = window.setInterval(() => {
14634
- API$1.loginStatus(flow.id).then((next) => {
14659
+ API$3.loginStatus(flow.id).then((next) => {
14635
14660
  setLoginFlow(next);
14636
14661
  if (next.status === "complete") {
14637
- setNotice(zh$3.loginComplete.replace("{account}", next.accountAlias === "" ? "Cline Pass" : next.accountAlias));
14662
+ setNotice(zh$4.loginComplete.replace("{account}", next.accountAlias === "" ? "Cline Pass" : next.accountAlias));
14638
14663
  setShowKeyForm(false);
14639
14664
  reload();
14640
- } else if (next.status === "failed") setError(zh$3.loginFailed.replace("{detail}", next.error));
14641
- }).catch((cause) => setError(detail(cause)));
14665
+ } else if (next.status === "failed") setError(zh$4.loginFailed.replace("{detail}", next.error));
14666
+ }).catch((cause) => setError(detail$1(cause)));
14642
14667
  }, Math.max(2, flow.intervalSeconds) * 1e3);
14643
14668
  return () => window.clearInterval(timer);
14644
14669
  }, [loginFlow, reload]);
@@ -14646,21 +14671,21 @@ window.__ModuleLoader__.load({
14646
14671
  setBusy("login");
14647
14672
  setError(null);
14648
14673
  setNotice(null);
14649
- API$1.startLogin().then((flow) => {
14674
+ API$3.startLogin().then((flow) => {
14650
14675
  setLoginFlow(flow);
14651
14676
  if (flow.verificationUri !== "" && typeof window !== "undefined" && typeof window.open === "function") try {
14652
14677
  window.open(flow.verificationUri, "_blank", "noopener,noreferrer");
14653
14678
  } catch {}
14654
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14679
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14655
14680
  }, []);
14656
14681
  const cancelLogin = (0, react.useCallback)(() => {
14657
14682
  if (loginFlow === null) return;
14658
- API$1.cancelLogin(loginFlow.id).then(() => {
14683
+ API$3.cancelLogin(loginFlow.id).then(() => {
14659
14684
  setLoginFlow({
14660
14685
  ...loginFlow,
14661
14686
  status: "cancelled"
14662
14687
  });
14663
- }).catch((cause) => setError(detail(cause)));
14688
+ }).catch((cause) => setError(detail$1(cause)));
14664
14689
  }, [loginFlow]);
14665
14690
  const applyStatus = (0, react.useCallback)((next) => {
14666
14691
  setStatus(next);
@@ -14675,7 +14700,7 @@ window.__ModuleLoader__.load({
14675
14700
  const next = await action();
14676
14701
  applyStatus(next);
14677
14702
  } catch (cause) {
14678
- setError(detail(cause));
14703
+ setError(detail$1(cause));
14679
14704
  } finally {
14680
14705
  setBusy(null);
14681
14706
  }
@@ -14684,7 +14709,7 @@ window.__ModuleLoader__.load({
14684
14709
  const trimmed = key.trim();
14685
14710
  if (trimmed === "") return;
14686
14711
  run("add", async () => {
14687
- const next = await API$1.accountAction("add", {
14712
+ const next = await API$3.accountAction("add", {
14688
14713
  apiKey: trimmed,
14689
14714
  ...alias.trim() === "" ? {} : { alias: alias.trim() },
14690
14715
  ...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
@@ -14707,20 +14732,20 @@ window.__ModuleLoader__.load({
14707
14732
  setBusy("test-key");
14708
14733
  setError(null);
14709
14734
  setNotice(null);
14710
- API$1.testKey({
14735
+ API$3.testKey({
14711
14736
  apiKey: trimmed,
14712
14737
  ...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
14713
14738
  }).then((result) => {
14714
- setNotice(result.authorized ? zh$3.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$3.keyTestFailed.replace("{detail}", result.error));
14715
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14739
+ setNotice(result.authorized ? zh$4.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$4.keyTestFailed.replace("{detail}", result.error));
14740
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14716
14741
  }, [key, keyBaseURL]);
14717
14742
  const testStored = (0, react.useCallback)((accountId) => {
14718
14743
  setBusy("test:" + accountId);
14719
14744
  setError(null);
14720
14745
  setNotice(null);
14721
- API$1.testKey({ accountId }).then((result) => {
14722
- setNotice(result.authorized ? zh$3.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$3.keyTestFailed.replace("{detail}", result.error));
14723
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14746
+ API$3.testKey({ accountId }).then((result) => {
14747
+ setNotice(result.authorized ? zh$4.keyTestOk.replace("{ms}", String(Math.round(result.ms))) : zh$4.keyTestFailed.replace("{detail}", result.error));
14748
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14724
14749
  }, []);
14725
14750
  const enabledModels = (0, react.useMemo)(() => (status?.models ?? []).filter((model) => model.enabled), [status]);
14726
14751
  status?.models;
@@ -14730,14 +14755,14 @@ window.__ModuleLoader__.load({
14730
14755
  const current = status.models.filter((model) => model.enabled).map((model) => model.id);
14731
14756
  const next = checked ? [.../* @__PURE__ */ new Set([...current, id])] : current.filter((entry) => entry !== id);
14732
14757
  run("models", async () => {
14733
- if (checked) await API$1.setVisibility(id, true);
14734
- return await API$1.setEnabledModels(next.length === status.models.length ? null : next);
14758
+ if (checked) await API$3.setVisibility(id, true);
14759
+ return await API$3.setEnabledModels(next.length === status.models.length ? null : next);
14735
14760
  });
14736
14761
  }, [status, run]);
14737
14762
  const setAllModels = (0, react.useCallback)((selectAll) => {
14738
14763
  run("models", async () => {
14739
- if (selectAll) await API$1.setVisibilityAll("all");
14740
- return await API$1.setEnabledModels(selectAll ? null : []);
14764
+ if (selectAll) await API$3.setVisibilityAll("all");
14765
+ return await API$3.setEnabledModels(selectAll ? null : []);
14741
14766
  });
14742
14767
  }, [run]);
14743
14768
  const commitContext = (0, react.useCallback)((id) => {
@@ -14745,10 +14770,10 @@ window.__ModuleLoader__.load({
14745
14770
  if (model === void 0) return;
14746
14771
  const parsed = parsePositiveCapacity$1(drafts[id] ?? formatCapacity$1(model.contextWindow));
14747
14772
  if (parsed === null) {
14748
- setError(zh$3.error.replace("{detail}", zh$3.defaultContextWindow));
14773
+ setError(zh$4.error.replace("{detail}", zh$4.defaultContextWindow));
14749
14774
  return;
14750
14775
  }
14751
- run("ctx:" + id, () => API$1.setContextWindow(id, parsed));
14776
+ run("ctx:" + id, () => API$3.setContextWindow(id, parsed));
14752
14777
  }, [
14753
14778
  status,
14754
14779
  drafts,
@@ -14757,7 +14782,7 @@ window.__ModuleLoader__.load({
14757
14782
  const resetContext = (0, react.useCallback)((id) => {
14758
14783
  const fallback = status?.models.find((entry) => entry.id === id)?.defaultContextWindow;
14759
14784
  run("ctx:" + id, async () => {
14760
- const next = await API$1.setContextWindow(id, null);
14785
+ const next = await API$3.setContextWindow(id, null);
14761
14786
  if (fallback !== void 0) setDrafts((current) => ({
14762
14787
  ...current,
14763
14788
  [id]: formatCapacity$1(fallback)
@@ -14767,11 +14792,11 @@ window.__ModuleLoader__.load({
14767
14792
  }, [run, status]);
14768
14793
  const resetAllContext = (0, react.useCallback)(() => {
14769
14794
  if (status === null) return;
14770
- if (typeof window !== "undefined" && !window.confirm(zh$3.contextResetAll)) return;
14795
+ if (typeof window !== "undefined" && !window.confirm(zh$4.contextResetAll)) return;
14771
14796
  const overridden = status.models.filter((model) => model.contextWindowOverride !== void 0);
14772
14797
  run("ctx-all", async () => {
14773
14798
  let next = status;
14774
- for (const model of overridden) next = await API$1.setContextWindow(model.id, null);
14799
+ for (const model of overridden) next = await API$3.setContextWindow(model.id, null);
14775
14800
  setDrafts((current) => {
14776
14801
  const draftsNext = { ...current };
14777
14802
  for (const model of overridden) draftsNext[model.id] = formatCapacity$1(model.defaultContextWindow);
@@ -14781,19 +14806,19 @@ window.__ModuleLoader__.load({
14781
14806
  });
14782
14807
  }, [status, run]);
14783
14808
  const refreshCatalog = (0, react.useCallback)(() => {
14784
- run("catalog", async () => (await API$1.refreshCatalog()).status);
14809
+ run("catalog", async () => (await API$3.refreshCatalog()).status);
14785
14810
  }, [run]);
14786
14811
  const refreshUsage = (0, react.useCallback)(() => {
14787
14812
  run("usage", async () => {
14788
- const outcome = await API$1.readUsage();
14789
- setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$3.usageEmpty);
14813
+ const outcome = await API$3.readUsage();
14814
+ setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$4.usageEmpty);
14790
14815
  return outcome.status;
14791
14816
  });
14792
14817
  }, [run]);
14793
14818
  const loadHistory = (0, react.useCallback)(() => {
14794
14819
  setBusy("history");
14795
14820
  setError(null);
14796
- API$1.history(50).then(setHistory).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14821
+ API$3.history(50).then(setHistory).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14797
14822
  }, []);
14798
14823
  const saveSettings = (0, react.useCallback)(() => {
14799
14824
  if (settingsForm === null) return;
@@ -14806,34 +14831,34 @@ window.__ModuleLoader__.load({
14806
14831
  };
14807
14832
  const invalid = Object.entries(numbers).find(([, value]) => !Number.isSafeInteger(value) || value < 0);
14808
14833
  if (invalid !== void 0) {
14809
- setError(zh$3.error.replace("{detail}", invalid[0]));
14834
+ setError(zh$4.error.replace("{detail}", invalid[0]));
14810
14835
  return;
14811
14836
  }
14812
14837
  setBusy("settings");
14813
14838
  setError(null);
14814
- API$1.updateSettings({
14839
+ API$3.updateSettings({
14815
14840
  baseURL: settingsForm.baseURL,
14816
14841
  ...numbers,
14817
14842
  exposeCatalog: settingsForm.exposeCatalog,
14818
14843
  pinSpelling: settingsForm.pinSpelling
14819
14844
  }).then((next) => {
14820
14845
  applyStatus(next);
14821
- setSettingsForm(settingsFormOf(next));
14822
- setNotice(zh$3.saved);
14823
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14846
+ setSettingsForm(settingsFormOf$1(next));
14847
+ setNotice(zh$4.saved);
14848
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14824
14849
  }, [settingsForm, applyStatus]);
14825
14850
  const toggleTools = (0, react.useCallback)(() => {
14826
14851
  if (status === null) return;
14827
14852
  const value = !status.exposeTools;
14828
14853
  setBusy("tools");
14829
14854
  setError(null);
14830
- API$1.updateSettings({ exposeTools: value }).then((next) => {
14855
+ API$3.updateSettings({ exposeTools: value }).then((next) => {
14831
14856
  applyStatus(next);
14832
- setSettingsForm(settingsFormOf(next));
14833
- setNotice(zh$3.restartRequired);
14834
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14857
+ setSettingsForm(settingsFormOf$1(next));
14858
+ setNotice(zh$4.restartRequired);
14859
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14835
14860
  }, [status, applyStatus]);
14836
- const t = zh$3;
14861
+ const t = zh$4;
14837
14862
  const pool = status?.pool;
14838
14863
  const accounts = (0, react.useMemo)(() => {
14839
14864
  const raw = pool?.accounts ?? [];
@@ -14867,7 +14892,7 @@ window.__ModuleLoader__.load({
14867
14892
  const draft = pinDraftFor(model);
14868
14893
  setBusy("pin:" + model.id);
14869
14894
  setError(null);
14870
- API$1.pinModel(model.id, draft).then((outcome) => {
14895
+ API$3.pinModel(model.id, draft).then((outcome) => {
14871
14896
  applyStatus(outcome.status);
14872
14897
  setPinDrafts((current) => {
14873
14898
  const next = { ...current };
@@ -14881,12 +14906,12 @@ window.__ModuleLoader__.load({
14881
14906
  pinWarnings: outcome.warnings
14882
14907
  }
14883
14908
  }));
14884
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14909
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14885
14910
  }, [pinDraftFor, applyStatus]);
14886
14911
  const resetPin = (0, react.useCallback)((model) => {
14887
14912
  setBusy("pin:" + model.id);
14888
14913
  setError(null);
14889
- API$1.resetPin(model.id).then((outcome) => {
14914
+ API$3.resetPin(model.id).then((outcome) => {
14890
14915
  applyStatus(outcome.status);
14891
14916
  setPinDrafts((current) => {
14892
14917
  const next = { ...current };
@@ -14897,7 +14922,7 @@ window.__ModuleLoader__.load({
14897
14922
  ...current,
14898
14923
  [model.id]: {}
14899
14924
  }));
14900
- }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
14925
+ }).catch((cause) => setError(detail$1(cause))).finally(() => setBusy(null));
14901
14926
  }, [applyStatus]);
14902
14927
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
14903
14928
  className: "dsha-page",
@@ -14921,7 +14946,7 @@ window.__ModuleLoader__.load({
14921
14946
  error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
14922
14947
  className: "dsha-notice",
14923
14948
  style: { color: "var(--dsha-danger, #c0392b)" },
14924
- children: [ERROR_DETAIL, error]
14949
+ children: [ERROR_DETAIL$1, error]
14925
14950
  }),
14926
14951
  notice !== null && notice !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
14927
14952
  className: "dsha-notice",
@@ -14948,10 +14973,10 @@ window.__ModuleLoader__.load({
14948
14973
  onLogin: startLogin,
14949
14974
  loginBusyLabel: t.loggingIn,
14950
14975
  onRelogin: startLogin,
14951
- onSetPrimary: (id) => void run("set-primary", () => API$1.accountAction("set-primary", { accountId: id })),
14952
- onDelete: (id) => void run("delete", () => API$1.accountAction("delete", { accountId: id })),
14953
- onClearCooldown: (id) => void run("clear-cooldown", () => API$1.accountAction("clear-cooldown", { accountId: id })),
14954
- onSetStrategy: (strategy) => void run("strategy", () => API$1.accountAction("strategy", { strategy })),
14976
+ onSetPrimary: (id) => void run("set-primary", () => API$3.accountAction("set-primary", { accountId: id })),
14977
+ onDelete: (id) => void run("delete", () => API$3.accountAction("delete", { accountId: id })),
14978
+ onClearCooldown: (id) => void run("clear-cooldown", () => API$3.accountAction("clear-cooldown", { accountId: id })),
14979
+ onSetStrategy: (strategy) => void run("strategy", () => API$3.accountAction("strategy", { strategy })),
14955
14980
  renderAccountActions: (account) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
14956
14981
  className: "dsha-btn",
14957
14982
  disabled: busyAny,
@@ -15260,7 +15285,7 @@ window.__ModuleLoader__.load({
15260
15285
  onProbe: () => {
15261
15286
  setBusy("probe:" + model.id);
15262
15287
  setError(null);
15263
- API$1.probe(model.id).then((outcome) => {
15288
+ API$3.probe(model.id).then((outcome) => {
15264
15289
  applyStatus(outcome.status);
15265
15290
  setResults((current) => ({
15266
15291
  ...current,
@@ -15273,14 +15298,14 @@ window.__ModuleLoader__.load({
15273
15298
  ...current,
15274
15299
  [model.id]: {
15275
15300
  ...current[model.id],
15276
- error: detail(cause)
15301
+ error: detail$1(cause)
15277
15302
  }
15278
15303
  }))).finally(() => setBusy(null));
15279
15304
  },
15280
15305
  onValidate: () => {
15281
15306
  setBusy("validate:" + model.id);
15282
15307
  setError(null);
15283
- API$1.validate(model.id).then((outcome) => {
15308
+ API$3.validate(model.id).then((outcome) => {
15284
15309
  applyStatus(outcome.status);
15285
15310
  setResults((current) => ({
15286
15311
  ...current,
@@ -15293,7 +15318,7 @@ window.__ModuleLoader__.load({
15293
15318
  ...current,
15294
15319
  [model.id]: {
15295
15320
  ...current[model.id],
15296
- error: detail(cause)
15321
+ error: detail$1(cause)
15297
15322
  }
15298
15323
  }))).finally(() => setBusy(null));
15299
15324
  },
@@ -15301,7 +15326,7 @@ window.__ModuleLoader__.load({
15301
15326
  const draft = pinDraftFor(model);
15302
15327
  setBusy("test-model:" + model.id);
15303
15328
  setError(null);
15304
- API$1.test(model.id, {
15329
+ API$3.test(model.id, {
15305
15330
  ...draft.upstreams.length === 0 ? {} : { upstreams: draft.upstreams },
15306
15331
  ...draft.exclude.length === 0 ? {} : { exclude: draft.exclude }
15307
15332
  }).then((outcome) => {
@@ -15317,7 +15342,7 @@ window.__ModuleLoader__.load({
15317
15342
  ...current,
15318
15343
  [model.id]: {
15319
15344
  ...current[model.id],
15320
- error: detail(cause)
15345
+ error: detail$1(cause)
15321
15346
  }
15322
15347
  }))).finally(() => setBusy(null));
15323
15348
  },
@@ -15873,7 +15898,10 @@ window.__ModuleLoader__.load({
15873
15898
  * 'settings.section' 上的那张座位(那张座绑定的是 ChatGPT 的键集)。
15874
15899
  */
15875
15900
  const NS_QODER = "dsh-qoder";
15876
- const zh$2 = {
15901
+ const zh$3 = {
15902
+ modelRowEfforts: "档位 {list}",
15903
+ modelRowNoEfforts: "无档位",
15904
+ modelRowOutput: "输出 {cap}",
15877
15905
  ...accountPoolZh,
15878
15906
  title: "Qoder(订阅)",
15879
15907
  pageDesc: "用 Qoder 订阅接入(全球区 qoder.com / 中国站 qoder.com.cn),管理账号池、套餐额度、缓存用量与模型勾选。区域是凭据的属性,两区凭据互不通用,因此号池里可以同时存在两区账号。",
@@ -15936,8 +15964,8 @@ window.__ModuleLoader__.load({
15936
15964
  refreshingCatalog: "刷新中…",
15937
15965
  selectAll: "全选",
15938
15966
  unselectAll: "全不选",
15939
- modelChecklistCount: "已选 {selected} / {total}",
15940
- enabledModelIdsSemantics: "清空勾选等于「不过滤(全部可用)」,而不是「一个都不可用」;要停用整条线路请用 hub 卡片上的总开关。",
15967
+ modelChecklistCount: "已选 {count} / {total}",
15968
+ enabledModelIdsSemantics: "勾选全清 = 全部模型都不可用(不是「不过滤」);要恢复全部请点「全选」。",
15941
15969
  defaultEffort: "默认思考档位",
15942
15970
  defaultEffortHint: "会话没指定档位时用的档位;各模型有自己的默认时以模型为准。",
15943
15971
  defaultEffortHintExtra: "上游的档位是逐模型声明的(目录 thinking_config 的键集);这里选的一档会先收敛到该模型真实接受的梯子上再发出去,模型不认的档位永远不会被发出。",
@@ -15990,9 +16018,12 @@ window.__ModuleLoader__.load({
15990
16018
  quotaWindow: "额度窗口"
15991
16019
  };
15992
16020
  /** 两套字典。 */
15993
- const dictionaries$2 = {
15994
- zh: zh$2,
16021
+ const dictionaries$3 = {
16022
+ zh: zh$3,
15995
16023
  en: {
16024
+ modelRowEfforts: "efforts {list}",
16025
+ modelRowNoEfforts: "no efforts",
16026
+ modelRowOutput: "out {cap}",
15996
16027
  ...accountPoolEn,
15997
16028
  title: "Qoder (Subscription)",
15998
16029
  pageDesc: "Connect your Qoder subscription (Global qoder.com / China qoder.com.cn): manage the account pool, plan quota, cache usage and model selection. Region is a property of the credential; the two regions do not accept each other's tokens, so the pool may hold accounts from both.",
@@ -16053,8 +16084,8 @@ window.__ModuleLoader__.load({
16053
16084
  refreshingCatalog: "Refreshing…",
16054
16085
  selectAll: "All",
16055
16086
  unselectAll: "None",
16056
- modelChecklistCount: "{selected} / {total} selected",
16057
- enabledModelIdsSemantics: "Clearing every checkbox means \"no filter (all available)\", not \"none available\"; to switch the line off use the toggle on the hub card.",
16087
+ modelChecklistCount: "{count} / {total} selected",
16088
+ enabledModelIdsSemantics: "Clearing every checkbox makes every model unavailable (it is not \"no filter\"); to bring them all back, use \"All\".",
16058
16089
  defaultEffort: "Default thinking effort",
16059
16090
  defaultEffortHint: "Used when the session does not name one; a model's own default wins when it has one.",
16060
16091
  defaultEffortHintExtra: "Upstream efforts are declared per model (the catalog's thinking_config keys); the level chosen here is first snapped onto the ladder the model actually accepts, so a value the model rejects is never sent.",
@@ -16162,9 +16193,9 @@ window.__ModuleLoader__.load({
16162
16193
  * 凭据边界也写在这里:/login/manual 的请求体是本文件里**唯一**带秘密的形状,
16163
16194
  * 它只在这个函数调用点的字面量里出现,既不进 URL、也不进日志。
16164
16195
  */
16165
- const api$6 = createLineApi(QODER_ROUTE_PREFIX, QODER_PROVIDER_NAME);
16166
- const get = api$6.get;
16167
- const post = api$6.post;
16196
+ const api$7 = createLineApi(QODER_ROUTE_PREFIX, QODER_PROVIDER_NAME);
16197
+ const get = api$7.get;
16198
+ const post = api$7.post;
16168
16199
  function messageOf(cause) {
16169
16200
  return cause instanceof Error ? cause.message : String(cause);
16170
16201
  }
@@ -16186,7 +16217,7 @@ window.__ModuleLoader__.load({
16186
16217
  /** 登录状态机的轮询节奏。真实超时与间隔由 host 拥有,卡片只是跟随。 */
16187
16218
  const LOGIN_POLL_INTERVAL_MS = 2e3;
16188
16219
  /** 本卡片的字典;身份稳定,依赖它的 effect 才不会每次渲染重建。 */
16189
- const fallbackTranslate$2 = (key) => zh$2[key];
16220
+ const fallbackTranslate$2 = (key) => zh$3[key];
16190
16221
  /**
16191
16222
  * 共享账号池卡片需要的标签集,按本卡片的字典逐键查出来。
16192
16223
  *
@@ -16300,6 +16331,37 @@ window.__ModuleLoader__.load({
16300
16331
  const [savingModel, setSavingModel] = (0, react.useState)(null);
16301
16332
  const regionTouched = (0, react.useRef)(false);
16302
16333
  const quotaFollowUp = (0, react.useRef)(void 0);
16334
+ /**
16335
+ * 首屏那次目录补拉是否已经试过。**一次就够,且只试一次**。
16336
+ *
16337
+ * 用 ref 而不是 state:这个判断要在异步回调里立刻生效,state 的下一次渲染
16338
+ * 之前读到的还是旧值,那一拍足以让 60 秒轮询与首屏各拉一次。
16339
+ *
16340
+ * 为什么需要它而不是靠 catalogRefreshing:那个字段是**当下这一刻**的事实,
16341
+ * 一次失败的补拉之后它仍会是 true(缓存依然是空的),没有这个 ref 就会变成
16342
+ * 「每一拍都补拉一次」——把一次静默优化做成了对上游的压测。
16343
+ */
16344
+ const catalogPullAttempted = (0, react.useRef)(false);
16345
+ /**
16346
+ * 静默补拉一次模型目录。
16347
+ *
16348
+ * host 的 GET /status 只读缓存(缓存为空时选择器显示随包兜底表),真实目录
16349
+ * 的刷新排在应答背后——**这是对的**,但它意味着首屏拿到的很可能是兜底表,
16350
+ * 而要等 60 秒轮询才会被顶掉。这里补一次,让用户打开页面就看到真实目录。
16351
+ *
16352
+ * 与手动「刷新目录」按钮的唯一区别是**没有** busy 与 error:这条路径没有
16353
+ * 用户在看,失败时选择器继续用兜底表就够了(兜底表存在的理由就是这个)。
16354
+ * 失败也不重试:重试的责任在 60 秒轮询与用户手上的按钮。
16355
+ */
16356
+ const pullCatalogQuietly = (0, react.useCallback)(async () => {
16357
+ if (catalogPullAttempted.current) return;
16358
+ catalogPullAttempted.current = true;
16359
+ try {
16360
+ const next = await post("/catalog/refresh", {});
16361
+ setStatus(next);
16362
+ setContextDrafts(contextDraftsFor(next));
16363
+ } catch {}
16364
+ }, []);
16303
16365
  const loadStatus = (0, react.useCallback)(async (quiet = false) => {
16304
16366
  if (!quiet) setError(null);
16305
16367
  try {
@@ -16311,12 +16373,13 @@ window.__ModuleLoader__.load({
16311
16373
  quotaFollowUp.current.observe(next.quotaRefreshing === true, () => {
16312
16374
  loadStatus(true);
16313
16375
  });
16376
+ if (next.catalogRefreshing === true) pullCatalogQuietly();
16314
16377
  } catch (cause) {
16315
16378
  if (!quiet) setError(messageOf(cause));
16316
16379
  } finally {
16317
16380
  setLoading(false);
16318
16381
  }
16319
- }, []);
16382
+ }, [pullCatalogQuietly]);
16320
16383
  (0, react.useEffect)(() => {
16321
16384
  loadStatus();
16322
16385
  const refreshWhenVisible = () => {
@@ -16460,8 +16523,9 @@ window.__ModuleLoader__.load({
16460
16523
  /**
16461
16524
  * 一个模型勾选补丁;host 回整份新状态,卡片因此不必猜哪些 id 最终生效。
16462
16525
  *
16463
- * 语义:**缺省或空数组 = 不过滤(全部可用),非空 = 显式选择**。所以「全不选」
16464
- * 提交的是空数组,它的含义是**清除显式选择、回到不过滤**,而不是「一个模型都不可用」。
16526
+ * 语义是**三态**:`null` = 不过滤(全部可用),`[]` = 用户明确全关,
16527
+ * 非空 = 白名单。所以「全不选」提交的是空数组,它真的意味着**一个模型都不可用**;
16528
+ * 要恢复全部请点「全选」(提交目录里的全部 id)。
16465
16529
  */
16466
16530
  const applyEnabledModels = async (enabledModelIds) => {
16467
16531
  try {
@@ -16654,8 +16718,9 @@ window.__ModuleLoader__.load({
16654
16718
  *
16655
16719
  * 两条它自己负责的渲染规则:
16656
16720
  *
16657
- * 1. **能力只画契约里的字段**:图片输入、思考档位、上下文窗口全部来自 host 生成的
16658
- * hint,客户端不按模型名推断任何一项;同一事实只呈现一次;
16721
+ * 1. **能力只画契约里的字段**:图片输入、思考档位、上下文窗口、输出预算全部来自
16722
+ * DTO 字段(`supportsImages` / `reasoningEfforts` / `contextWindow` /
16723
+ * `defaultMaxTokens`),客户端不按模型名推断任何一项;同一事实只呈现一次;
16659
16724
  * 2. **额度画绝对量,缓存画 token 维度**:额度是三只桶的总量/已用/剩余(上游自述的
16660
16725
  * 单位),缺桶不画;缓存只有读入/写入/样本,没数据就是占位符;单价未公开,
16661
16726
  * 整页不出现任何金额。
@@ -16712,12 +16777,22 @@ window.__ModuleLoader__.load({
16712
16777
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: summary }), kept.map((line, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: line }, "note:" + index))]
16713
16778
  });
16714
16779
  }
16780
+ /**
16781
+ * 一行模型的能力摘要:`1M · text+image · 档位 low/high/max · 输出 131k`。
16782
+ *
16783
+ * 全部取自契约字段(窗口、`supportsImages`、`reasoningEfforts`、
16784
+ * `defaultMaxTokens`),客户端不按模型名推断任何一项。与 OpenDesign 卡同一写法:
16785
+ * 数据一行,散文进折叠区。
16786
+ */
16787
+ function qoderModelRowHint(model) {
16788
+ return `${formatTokenCount(model.contextWindow)} · ${model.supportsImages ? "text+image" : "text"} · ${model.reasoningEfforts.length === 0 ? zh$3.modelRowNoEfforts : zh$3.modelRowEfforts.replace("{list}", model.reasoningEfforts.join("/"))} · ${zh$3.modelRowOutput.replace("{cap}", formatTokenCount(model.defaultMaxTokens))}`;
16789
+ }
16715
16790
  function QoderSection({ onModelChange } = {}) {
16716
16791
  const { state, derived, actions } = useQoderSection({ onModelChange });
16717
16792
  const { status, loading, busy, error, connection, adoptResult, pasteValue, region, pasteOpen, contextDrafts, savingModel } = state;
16718
16793
  const { accounts, models, contextModels, overrideCount, login, quota, authenticated, poolLabels, cache, cacheHitRatio: hitRatio } = derived;
16719
16794
  const { setRegion, login: startLogin, cancelLogin, submitPaste, setPasteValue, togglePaste, adopt, clearAdoptResult, accountAction, setStrategy, toggleModel, setAllModels, saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft, setDefaultReasoningEffort, refreshQuota, refreshCatalog, testConnection } = actions;
16720
- const t = zh$2;
16795
+ const t = zh$3;
16721
16796
  if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
16722
16797
  className: "dsha-page",
16723
16798
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -17039,6 +17114,7 @@ window.__ModuleLoader__.load({
17039
17114
  items: models.map((model) => ({
17040
17115
  id: model.id,
17041
17116
  name: model.name,
17117
+ hint: qoderModelRowHint(model),
17042
17118
  enabled: model.enabled
17043
17119
  })),
17044
17120
  busy: busy !== null,
@@ -17217,6 +17293,986 @@ window.__ModuleLoader__.load({
17217
17293
  });
17218
17294
  }
17219
17295
  //#endregion
17296
+ //#region src/shared/opendesign-contracts.ts
17297
+ const OPENDESIGN_PROVIDER_NAME = "OpenDesign";
17298
+ const OPENDESIGN_ROUTE_PREFIX = "/opendesign/api";
17299
+ //#endregion
17300
+ //#region src/client/opendesign/api.ts
17301
+ const api$6 = createLineApi(OPENDESIGN_ROUTE_PREFIX, "OpenDesign");
17302
+ /**
17303
+ * The OpenDesign settings API, as the card uses it.
17304
+ *
17305
+ * Deliberately the same envelope and the same fetch shape every other provider
17306
+ * section uses, so the shared account-pool card and this helper read alike.
17307
+ */
17308
+ var OpenDesignApi = class {
17309
+ status() {
17310
+ return api$6.get("/status");
17311
+ }
17312
+ updateSettings(patch) {
17313
+ return api$6.post("/settings", patch).then(() => this.status());
17314
+ }
17315
+ accountAction(action, body = {}) {
17316
+ return api$6.post("/accounts", {
17317
+ action,
17318
+ ...body
17319
+ });
17320
+ }
17321
+ /** Verify a key without storing it; the host answers the verdict directly. */
17322
+ testKey(body) {
17323
+ return api$6.post("/accounts", {
17324
+ action: "test",
17325
+ ...body
17326
+ });
17327
+ }
17328
+ /** Start the browser device-authorization sign-in. */
17329
+ startLogin() {
17330
+ return api$6.post("/login/start", {});
17331
+ }
17332
+ /** One poll of the pending sign-in; the host throttles it to the advertised interval. */
17333
+ loginStatus(id) {
17334
+ return api$6.get(`/login/status?id=${encodeURIComponent(id)}`);
17335
+ }
17336
+ cancelLogin(id) {
17337
+ return api$6.post("/login/cancel", { id });
17338
+ }
17339
+ /** Read each OAuth account's wallet balance once (one upstream call per account). */
17340
+ readUsage() {
17341
+ return api$6.post("/usage", {});
17342
+ }
17343
+ setEnabledModels(enabledModelIds) {
17344
+ return api$6.post("/models", { enabledModelIds });
17345
+ }
17346
+ setContextWindow(model, contextWindow) {
17347
+ return api$6.post("/models/context-window", {
17348
+ model,
17349
+ contextWindow
17350
+ });
17351
+ }
17352
+ setVisibility(model, visible) {
17353
+ return api$6.post("/models/visibility", {
17354
+ model,
17355
+ visible
17356
+ });
17357
+ }
17358
+ setVisibilityAll(mode) {
17359
+ return api$6.post("/models/visibility-all", { mode });
17360
+ }
17361
+ refreshCatalog() {
17362
+ return api$6.post("/catalog/refresh", {});
17363
+ }
17364
+ };
17365
+ //#endregion
17366
+ //#region src/client/opendesign/locales.ts
17367
+ const NS_OPENDESIGN = "dsh-opendesign";
17368
+ const zh$2 = {
17369
+ ...accountPoolZh,
17370
+ relogin: "重新登录",
17371
+ needsRelogin: "登录已失效",
17372
+ addAccount: "添加 API Key",
17373
+ noAccounts: "暂无账号。点「登录 OpenDesign 账号」完成浏览器授权,或用「添加 API Key」粘贴控制台签发的 Key。",
17374
+ title: "OpenDesign",
17375
+ pageDesc: "接入 OpenDesign 订阅:浏览器授权登录(推荐,可同时读余额)或粘贴 Cloud 控制台的 API Key,即可用订阅额度调用其模型网关。多账号自动轮换。",
17376
+ login: "登录 OpenDesign 账号",
17377
+ loggingIn: "登录中...",
17378
+ loginHint: "在浏览器中打开激活页并确认下方代码;确认后账号会自动加入号池,无需再粘贴 Key。",
17379
+ loginCode: "授权代码",
17380
+ loginOpen: "打开激活页",
17381
+ loginWaiting: "等待浏览器确认…",
17382
+ loginCancel: "取消登录",
17383
+ loginIdle: "尚未开始登录。",
17384
+ loginHaveAccounts: "号池已有 {count} 个账号可用。",
17385
+ loginComplete: "已登录:{account}",
17386
+ loginCompleteNoAccount: "上次登录已完成,但当前号池中没有可用账号。",
17387
+ loginFailed: "登录失败:{detail}",
17388
+ useApiKey: "添加 API Key",
17389
+ oauthAccount: "浏览器授权",
17390
+ apiKeyAccount: "API Key",
17391
+ routeOwned: "模型路由由本插件提供",
17392
+ routeConflict: "模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。",
17393
+ error: "操作失败:{detail}",
17394
+ saved: "已保存",
17395
+ keySection: "添加 API Key",
17396
+ keyHint: "在 OpenDesign Cloud 控制台的工作区(API Keys)创建 Key 后粘贴到此处。",
17397
+ keyConsoleLink: "打开 OpenDesign Cloud 控制台",
17398
+ keyPlaceholder: "粘贴 OpenDesign API Key",
17399
+ keyAliasLabel: "备注名(可选)",
17400
+ keyAliasPlaceholder: "例如:主号、备用号",
17401
+ keyAliasHint: "网关不返回账号信息,多个 Key 靠备注名区分。",
17402
+ keyBaseUrlLabel: "网关地址覆盖(可选)",
17403
+ keyBaseUrlPlaceholder: "默认 https://amr-link.open-design.ai/v1",
17404
+ keySave: "添加",
17405
+ keySaving: "添加中...",
17406
+ keyTest: "测试 Key",
17407
+ cancel: "取消",
17408
+ keyTesting: "测试中...",
17409
+ keyTestOk: "Key 可用({ms}ms,可见 {count} 个模型)",
17410
+ keyTestFailed: "Key 不可用:{detail}",
17411
+ testSavedKey: "测试",
17412
+ modelsSection: "模型",
17413
+ modelsHint: "模型目录来自随包内置列表;添加 Key 后自动同步一次该 Key 可见的实时目录,也可手动刷新。未勾选的模型不会出现在模型选择器中。",
17414
+ modelChecklistCount: "已选 {count} / 共 {total} 个模型",
17415
+ selectAll: "全选",
17416
+ unselectAll: "全不选",
17417
+ catalogSync: "刷新模型目录",
17418
+ catalogSyncing: "刷新中...",
17419
+ catalogNeverSynced: "尚未同步实时目录:当前显示的是随包内置列表。添加 Key 后会自动同步一次,或点右上角「刷新模型目录」。",
17420
+ catalogSyncedNote: "实时目录已同步 {count} 个模型。",
17421
+ noModels: "暂无可用模型。",
17422
+ pricingNote: "价格为官方公开价目(美元 / 每百万 token,输入 / 输出)。",
17423
+ contextSection: "上下文窗口",
17424
+ contextHint: "官方未公布各模型的上下文窗口:默认按 128k 处理,可在这里按模型修正。留空或保存无效值会提示错误;恢复默认会清掉覆盖值。",
17425
+ tokens: "tokens",
17426
+ contextSave: "保存",
17427
+ contextOverridden: "已覆盖",
17428
+ contextSaving: "保存中",
17429
+ contextReset: "恢复默认",
17430
+ contextResetAll: "全部恢复默认",
17431
+ contextEmpty: "勾选至少一个模型后,这里会出现它的上下文窗口设置。",
17432
+ advancedSection: "高级设置",
17433
+ baseURL: "默认网关地址",
17434
+ defaultContextWindow: "默认上下文窗口",
17435
+ defaultMaxTokens: "默认输出预算",
17436
+ maxConcurrentRequests: "每账号并发流上限(0 = 不限)",
17437
+ streamIdleTimeoutMs: "流空闲超时(ms)",
17438
+ saveSettings: "保存设置",
17439
+ savingSettings: "保存中...",
17440
+ limitsSection: "说明",
17441
+ usageSection: "钱包余额",
17442
+ usageHint: "余额属于账号。浏览器授权登录的账号带控制 Key,可直接读;粘贴的 API Key 没有控制 Key,请在控制台查看。刷新会为每个可读的 OAuth 账号各发一次请求。",
17443
+ usageRefresh: "刷新余额",
17444
+ usageRefreshing: "刷新中...",
17445
+ usageEmpty: "尚未读取余额。",
17446
+ usageUnavailable: "读不到余额:{detail}",
17447
+ usageBalance: "余额 ${amount}",
17448
+ usageReadAt: "读取于 {time}",
17449
+ limitKey: "凭据存储在系统加密凭据库中,界面从不显示 Key 本身。",
17450
+ limitGateway: "请求由 OpenDesign 网关服务,实际上游由网关决定。",
17451
+ limitRoute: "模型路由按 provider id 抢占:若已有其他插件占用 opendesign,本卡仍可配置,但请求由对方服务。",
17452
+ limitQuota: "余额读取只覆盖浏览器授权登录的账号;粘贴的 API Key 请在 OpenDesign Cloud 控制台查看用量。"
17453
+ };
17454
+ const en$2 = {
17455
+ ...accountPoolEn,
17456
+ relogin: "Add again",
17457
+ needsRelogin: "Key invalid",
17458
+ addAccount: "Add API key",
17459
+ noAccounts: "No accounts yet. Click \"Add API key\" and paste a key created in the OpenDesign Cloud console.",
17460
+ title: "OpenDesign",
17461
+ pageDesc: "Connect an OpenDesign subscription: create an API key in the Cloud console and paste it here to call its model gateway on plan credits. Pooled accounts rotate automatically.",
17462
+ login: "Sign in to OpenDesign",
17463
+ loggingIn: "Signing in...",
17464
+ loginHint: "Open the activation page in your browser and confirm the code below; the account joins the pool automatically, with no key to paste.",
17465
+ loginCode: "Authorization code",
17466
+ loginOpen: "Open activation page",
17467
+ loginWaiting: "Waiting for browser confirmation…",
17468
+ loginCancel: "Cancel sign-in",
17469
+ loginIdle: "No sign-in started in this process yet.",
17470
+ loginHaveAccounts: "The pool already holds {count} usable account(s).",
17471
+ loginComplete: "Signed in as {account}",
17472
+ loginCompleteNoAccount: "The previous sign-in completed, but the pool currently holds no usable account.",
17473
+ loginFailed: "Sign-in failed: {detail}",
17474
+ useApiKey: "Add API key",
17475
+ oauthAccount: "Browser sign-in",
17476
+ apiKeyAccount: "API key",
17477
+ routeOwned: "Model route served by this plugin",
17478
+ routeConflict: "The model route is already owned by another provider: {detail}",
17479
+ error: "Action failed: {detail}",
17480
+ saved: "Saved",
17481
+ keySection: "Add an API key",
17482
+ keyHint: "Create a key in the OpenDesign Cloud console (workspace → API Keys) and paste it here.",
17483
+ keyConsoleLink: "Open the OpenDesign Cloud console",
17484
+ keyPlaceholder: "Paste an OpenDesign API key",
17485
+ keyAliasLabel: "Label (optional)",
17486
+ keyAliasPlaceholder: "e.g. primary, backup",
17487
+ keyAliasHint: "The gateway reports no account identity, so labels tell several keys apart.",
17488
+ keyBaseUrlLabel: "Gateway override (optional)",
17489
+ keyBaseUrlPlaceholder: "default: https://amr-link.open-design.ai/v1",
17490
+ keySave: "Add",
17491
+ keySaving: "Adding...",
17492
+ keyTest: "Test key",
17493
+ cancel: "Cancel",
17494
+ keyTesting: "Testing...",
17495
+ keyTestOk: "Key works ({ms}ms, {count} models visible)",
17496
+ keyTestFailed: "Key rejected: {detail}",
17497
+ testSavedKey: "Test",
17498
+ modelsSection: "Models",
17499
+ modelsHint: "The list starts from the bundled table; adding a key syncs the live catalog that key can see, and a manual refresh syncs it again. Unchecked models do not appear in the model picker.",
17500
+ modelChecklistCount: "{count} of {total} selected",
17501
+ selectAll: "Select all",
17502
+ unselectAll: "Clear all",
17503
+ catalogSync: "Refresh catalog",
17504
+ catalogSyncing: "Refreshing...",
17505
+ catalogNeverSynced: "The live catalog has not been synced yet, so the bundled table is listed. Adding a key syncs it once automatically; the refresh button syncs it again.",
17506
+ catalogSyncedNote: "Live catalog synced: {count} model(s).",
17507
+ noModels: "No models available.",
17508
+ pricingNote: "Prices are the official public list (USD per 1M tokens, input / output).",
17509
+ contextSection: "Context windows",
17510
+ contextHint: "The vendor publishes no per-model context windows, so models default to 128k; correct any model here. An invalid value is reported rather than saved; restoring clears the override.",
17511
+ tokens: "tokens",
17512
+ contextSave: "Save",
17513
+ contextOverridden: "overridden",
17514
+ contextSaving: "Saving",
17515
+ contextReset: "Restore default",
17516
+ contextResetAll: "Restore all defaults",
17517
+ contextEmpty: "Check at least one model to configure its context window here.",
17518
+ advancedSection: "Advanced",
17519
+ baseURL: "Default gateway",
17520
+ defaultContextWindow: "Default context window",
17521
+ defaultMaxTokens: "Default output budget",
17522
+ maxConcurrentRequests: "Streams per account (0 = unlimited)",
17523
+ streamIdleTimeoutMs: "Stream idle timeout (ms)",
17524
+ saveSettings: "Save settings",
17525
+ savingSettings: "Saving...",
17526
+ limitsSection: "Notes",
17527
+ usageSection: "Wallet balance",
17528
+ usageHint: "Balances belong to accounts. Browser-signed-in accounts carry a control key and can be read here; a pasted API key has none — check the console for it. Refreshing sends one request per readable OAuth account.",
17529
+ usageRefresh: "Refresh balance",
17530
+ usageRefreshing: "Refreshing...",
17531
+ usageEmpty: "No balance reading yet.",
17532
+ usageUnavailable: "Could not read the balance: {detail}",
17533
+ usageBalance: "Balance ${amount}",
17534
+ usageReadAt: "Read at {time}",
17535
+ limitKey: "API keys live in the OS credential store; the card never shows the key itself.",
17536
+ limitGateway: "Requests are served by the OpenDesign gateway, which chooses the actual upstream.",
17537
+ limitRoute: "The route is claimed by provider id: if another plugin already serves opendesign, this card still configures the line but that provider answers the requests.",
17538
+ limitQuota: "Balance reads cover browser-signed-in accounts only; for a pasted API key, see usage in the OpenDesign Cloud console."
17539
+ };
17540
+ const dictionaries$2 = {
17541
+ zh: zh$2,
17542
+ "zh-CN": zh$2,
17543
+ en: en$2,
17544
+ "en-US": en$2
17545
+ };
17546
+ //#endregion
17547
+ //#region src/client/opendesign/OpenDesignSection.tsx
17548
+ const API$2 = new OpenDesignApi();
17549
+ const ERROR_DETAIL = zh$2.error.split("{detail}")[0] ?? "";
17550
+ function detail(error) {
17551
+ return error instanceof Error ? error.message : String(error);
17552
+ }
17553
+ function settingsFormOf(status) {
17554
+ return {
17555
+ baseURL: status.settings.baseURL,
17556
+ defaultContextWindow: String(status.settings.defaultContextWindow),
17557
+ defaultMaxTokens: String(status.settings.defaultMaxTokens),
17558
+ maxConcurrentRequests: String(status.settings.maxConcurrentRequests),
17559
+ streamIdleTimeoutMs: String(status.settings.streamIdleTimeoutMs)
17560
+ };
17561
+ }
17562
+ /**
17563
+ * The OpenDesign tab.
17564
+ *
17565
+ * The account card, its badges and the rotation picker are the shared
17566
+ * {@link AccountPoolSection}, so this line looks like every other provider tab
17567
+ * by construction. What is written here is only what is genuinely OpenDesign's:
17568
+ * pasting a console-issued API key and the catalog sync. There is deliberately
17569
+ * no quota block: the gateway answers an API key no balance, and a card that
17570
+ * drew one would be inventing it.
17571
+ */
17572
+ function OpenDesignSection(props) {
17573
+ const [status, setStatus] = (0, react.useState)(null);
17574
+ const [busy, setBusy] = (0, react.useState)(null);
17575
+ const [error, setError] = (0, react.useState)(null);
17576
+ const [notice, setNotice] = (0, react.useState)(null);
17577
+ const [key, setKey] = (0, react.useState)("");
17578
+ const [alias, setAlias] = (0, react.useState)("");
17579
+ const [keyBaseURL, setKeyBaseURL] = (0, react.useState)("");
17580
+ const [showKeyForm, setShowKeyForm] = (0, react.useState)(false);
17581
+ const [drafts, setDrafts] = (0, react.useState)({});
17582
+ const [settingsForm, setSettingsForm] = (0, react.useState)(null);
17583
+ const [loginFlow, setLoginFlow] = (0, react.useState)(null);
17584
+ const reload = (0, react.useCallback)(async () => {
17585
+ try {
17586
+ const next = await API$2.status();
17587
+ setStatus(next);
17588
+ setSettingsForm((current) => current ?? (next.settings === void 0 ? null : settingsFormOf(next)));
17589
+ setError(null);
17590
+ } catch (cause) {
17591
+ setError(detail(cause));
17592
+ }
17593
+ }, []);
17594
+ (0, react.useEffect)(() => {
17595
+ reload();
17596
+ }, [reload]);
17597
+ (0, react.useEffect)(() => {
17598
+ if (status === null) return;
17599
+ setDrafts((current) => {
17600
+ let changed = false;
17601
+ const next = { ...current };
17602
+ for (const model of status.models) {
17603
+ if (!model.enabled || next[model.id] !== void 0) continue;
17604
+ next[model.id] = formatCapacity$1(model.contextWindow);
17605
+ changed = true;
17606
+ }
17607
+ return changed ? next : current;
17608
+ });
17609
+ }, [status]);
17610
+ (0, react.useEffect)(() => {
17611
+ const incoming = status?.login;
17612
+ if (incoming === void 0 || incoming === null) return;
17613
+ setLoginFlow((current) => current !== null && current.id === incoming.id && current.status !== "pending" ? current : incoming);
17614
+ }, [status]);
17615
+ (0, react.useEffect)(() => {
17616
+ const flow = loginFlow;
17617
+ if (flow === null || flow.status !== "pending") return;
17618
+ const timer = window.setInterval(() => {
17619
+ API$2.loginStatus(flow.id).then((next) => {
17620
+ setLoginFlow(next);
17621
+ if (next.status === "complete") {
17622
+ setNotice(zh$2.loginComplete.replace("{account}", next.accountAlias === "" ? "OpenDesign" : next.accountAlias));
17623
+ setShowKeyForm(false);
17624
+ reload();
17625
+ } else if (next.status === "failed") setError(zh$2.loginFailed.replace("{detail}", next.error));
17626
+ }).catch((cause) => setError(detail(cause)));
17627
+ }, Math.max(2, flow.intervalSeconds) * 1e3);
17628
+ return () => window.clearInterval(timer);
17629
+ }, [loginFlow, reload]);
17630
+ const applyStatus = (0, react.useCallback)((next) => {
17631
+ setStatus(next);
17632
+ props.onModelChange?.();
17633
+ props.loadModelDirectory?.();
17634
+ }, [props]);
17635
+ const startLogin = (0, react.useCallback)(() => {
17636
+ setBusy("login");
17637
+ setError(null);
17638
+ setNotice(null);
17639
+ API$2.startLogin().then((flow) => {
17640
+ setLoginFlow(flow);
17641
+ if (flow.verificationUri !== "" && typeof window !== "undefined" && typeof window.open === "function") try {
17642
+ window.open(flow.verificationUri, "_blank", "noopener,noreferrer");
17643
+ } catch {}
17644
+ }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
17645
+ }, []);
17646
+ const cancelLogin = (0, react.useCallback)(() => {
17647
+ if (loginFlow === null) return;
17648
+ API$2.cancelLogin(loginFlow.id).then(() => {
17649
+ setLoginFlow({
17650
+ ...loginFlow,
17651
+ status: "cancelled"
17652
+ });
17653
+ }).catch((cause) => setError(detail(cause)));
17654
+ }, [loginFlow]);
17655
+ const run = (0, react.useCallback)(async (label, action) => {
17656
+ setBusy(label);
17657
+ setError(null);
17658
+ setNotice(null);
17659
+ try {
17660
+ const next = await action();
17661
+ applyStatus(next);
17662
+ } catch (cause) {
17663
+ setError(detail(cause));
17664
+ } finally {
17665
+ setBusy(null);
17666
+ }
17667
+ }, [applyStatus]);
17668
+ const refreshUsage = (0, react.useCallback)(() => {
17669
+ run("usage", async () => {
17670
+ const outcome = await API$2.readUsage();
17671
+ setNotice(outcome.usage.accounts.some((account) => account.ok) ? "" : zh$2.usageEmpty);
17672
+ return outcome.status;
17673
+ });
17674
+ }, [run]);
17675
+ const addKey = (0, react.useCallback)(() => {
17676
+ const trimmed = key.trim();
17677
+ if (trimmed === "") return;
17678
+ run("add", async () => {
17679
+ const next = await API$2.accountAction("add", {
17680
+ apiKey: trimmed,
17681
+ ...alias.trim() === "" ? {} : { alias: alias.trim() },
17682
+ ...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
17683
+ });
17684
+ setKey("");
17685
+ setAlias("");
17686
+ setKeyBaseURL("");
17687
+ setShowKeyForm(false);
17688
+ return next;
17689
+ });
17690
+ }, [
17691
+ key,
17692
+ alias,
17693
+ keyBaseURL,
17694
+ run
17695
+ ]);
17696
+ const testTypedKey = (0, react.useCallback)(() => {
17697
+ const trimmed = key.trim();
17698
+ if (trimmed === "") return;
17699
+ setBusy("test-key");
17700
+ setError(null);
17701
+ setNotice(null);
17702
+ API$2.testKey({
17703
+ apiKey: trimmed,
17704
+ ...keyBaseURL.trim() === "" ? {} : { baseURL: keyBaseURL.trim() }
17705
+ }).then((result) => {
17706
+ setNotice(result.authorized ? zh$2.keyTestOk.replace("{ms}", String(Math.round(result.ms))).replace("{count}", String(result.modelCount)) : zh$2.keyTestFailed.replace("{detail}", result.error));
17707
+ }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
17708
+ }, [key, keyBaseURL]);
17709
+ const testStored = (0, react.useCallback)((accountId) => {
17710
+ setBusy("test:" + accountId);
17711
+ setError(null);
17712
+ setNotice(null);
17713
+ API$2.testKey({ accountId }).then((result) => {
17714
+ setNotice(result.authorized ? zh$2.keyTestOk.replace("{ms}", String(Math.round(result.ms))).replace("{count}", String(result.modelCount)) : zh$2.keyTestFailed.replace("{detail}", result.error));
17715
+ }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
17716
+ }, []);
17717
+ const enabledModels = (0, react.useMemo)(() => (status?.models ?? []).filter((model) => model.enabled), [status]);
17718
+ status?.models;
17719
+ const enabledCount = enabledModels.length;
17720
+ const toggleModel = (0, react.useCallback)((id, checked) => {
17721
+ if (status === null) return;
17722
+ const current = status.models.filter((model) => model.enabled).map((model) => model.id);
17723
+ const next = checked ? [.../* @__PURE__ */ new Set([...current, id])] : current.filter((entry) => entry !== id);
17724
+ run("models", async () => {
17725
+ if (checked) await API$2.setVisibility(id, true);
17726
+ return await API$2.setEnabledModels(next.length === status.models.length ? null : next);
17727
+ });
17728
+ }, [status, run]);
17729
+ const setAllModels = (0, react.useCallback)((selectAll) => {
17730
+ run("models", async () => {
17731
+ if (selectAll) await API$2.setVisibilityAll("all");
17732
+ return await API$2.setEnabledModels(selectAll ? null : []);
17733
+ });
17734
+ }, [run]);
17735
+ const commitContext = (0, react.useCallback)((id) => {
17736
+ const model = status?.models.find((entry) => entry.id === id);
17737
+ if (model === void 0) return;
17738
+ const parsed = parsePositiveCapacity$1(drafts[id] ?? formatCapacity$1(model.contextWindow));
17739
+ if (parsed === null) {
17740
+ setError(zh$2.error.replace("{detail}", zh$2.defaultContextWindow));
17741
+ return;
17742
+ }
17743
+ run("ctx:" + id, () => API$2.setContextWindow(id, parsed));
17744
+ }, [
17745
+ status,
17746
+ drafts,
17747
+ run
17748
+ ]);
17749
+ const resetContext = (0, react.useCallback)((id) => {
17750
+ const fallback = status?.models.find((entry) => entry.id === id)?.defaultContextWindow;
17751
+ run("ctx:" + id, async () => {
17752
+ const next = await API$2.setContextWindow(id, null);
17753
+ if (fallback !== void 0) setDrafts((current) => ({
17754
+ ...current,
17755
+ [id]: formatCapacity$1(fallback)
17756
+ }));
17757
+ return next;
17758
+ });
17759
+ }, [run, status]);
17760
+ const resetAllContext = (0, react.useCallback)(() => {
17761
+ if (status === null) return;
17762
+ if (typeof window !== "undefined" && !window.confirm(zh$2.contextResetAll)) return;
17763
+ const overridden = status.models.filter((model) => model.contextWindowOverride !== void 0);
17764
+ run("ctx-all", async () => {
17765
+ let next = status;
17766
+ for (const model of overridden) next = await API$2.setContextWindow(model.id, null);
17767
+ setDrafts((current) => {
17768
+ const draftsNext = { ...current };
17769
+ for (const model of overridden) draftsNext[model.id] = formatCapacity$1(model.defaultContextWindow);
17770
+ return draftsNext;
17771
+ });
17772
+ return next;
17773
+ });
17774
+ }, [status, run]);
17775
+ const refreshCatalog = (0, react.useCallback)(() => {
17776
+ run("catalog", async () => {
17777
+ const outcome = await API$2.refreshCatalog();
17778
+ setNotice(zh$2.catalogSyncedNote.replace("{count}", String(outcome.status.catalogCount)));
17779
+ return outcome.status;
17780
+ });
17781
+ }, [run]);
17782
+ const saveSettings = (0, react.useCallback)(() => {
17783
+ if (settingsForm === null) return;
17784
+ const numbers = {
17785
+ defaultContextWindow: Number(settingsForm.defaultContextWindow),
17786
+ defaultMaxTokens: Number(settingsForm.defaultMaxTokens),
17787
+ maxConcurrentRequests: Number(settingsForm.maxConcurrentRequests),
17788
+ streamIdleTimeoutMs: Number(settingsForm.streamIdleTimeoutMs)
17789
+ };
17790
+ const invalid = Object.entries(numbers).find(([, value]) => !Number.isSafeInteger(value) || value < 0);
17791
+ if (invalid !== void 0) {
17792
+ setError(zh$2.error.replace("{detail}", invalid[0]));
17793
+ return;
17794
+ }
17795
+ setBusy("settings");
17796
+ setError(null);
17797
+ API$2.updateSettings({
17798
+ baseURL: settingsForm.baseURL,
17799
+ ...numbers
17800
+ }).then((next) => {
17801
+ applyStatus(next);
17802
+ setSettingsForm(settingsFormOf(next));
17803
+ setNotice(zh$2.saved);
17804
+ }).catch((cause) => setError(detail(cause))).finally(() => setBusy(null));
17805
+ }, [settingsForm, applyStatus]);
17806
+ const t = zh$2;
17807
+ const pool = status?.pool;
17808
+ const accounts = pool?.accounts ?? [];
17809
+ const models = status?.models ?? [];
17810
+ const busyAny = busy !== null;
17811
+ const anyPricing = models.some((model) => model.pricing !== void 0);
17812
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17813
+ className: "dsha-page",
17814
+ children: [
17815
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17816
+ className: "dsha-muted",
17817
+ children: t.pageDesc
17818
+ }),
17819
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
17820
+ className: "dsha-group",
17821
+ children: [
17822
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17823
+ className: "dsha-grouphead",
17824
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.title })
17825
+ }),
17826
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17827
+ className: "dsha-muted",
17828
+ style: { fontSize: 12 },
17829
+ children: status?.serving === false && status.conflict !== null ? t.routeConflict.replace("{detail}", status.conflict) : t.routeOwned
17830
+ }),
17831
+ error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
17832
+ className: "dsha-notice",
17833
+ style: { color: "var(--dsha-danger, #c0392b)" },
17834
+ children: [ERROR_DETAIL, error]
17835
+ }),
17836
+ notice !== null && notice !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17837
+ className: "dsha-notice",
17838
+ children: notice
17839
+ }),
17840
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
17841
+ className: "dshod-details",
17842
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: t.limitsSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("ul", { children: [
17843
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t.limitKey }),
17844
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t.limitGateway }),
17845
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t.limitRoute }),
17846
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", { children: t.limitQuota })
17847
+ ] })]
17848
+ })
17849
+ ]
17850
+ }),
17851
+ pool !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(AccountPoolSection, {
17852
+ accounts,
17853
+ activeAccountId: pool.activeAccountId,
17854
+ rotationStrategy: pool.rotationStrategy,
17855
+ labels: t,
17856
+ busy,
17857
+ onLogin: startLogin,
17858
+ loginBusyLabel: t.loggingIn,
17859
+ onRelogin: startLogin,
17860
+ onSetPrimary: (id) => void run("set-primary", () => API$2.accountAction("set-primary", { accountId: id })),
17861
+ onDelete: (id) => void run("delete", () => API$2.accountAction("delete", { accountId: id })),
17862
+ onClearCooldown: (id) => void run("clear-cooldown", () => API$2.accountAction("clear-cooldown", { accountId: id })),
17863
+ onSetStrategy: (strategy) => void run("strategy", () => API$2.accountAction("strategy", { strategy })),
17864
+ renderAccountActions: (account) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17865
+ className: "dsha-btn",
17866
+ disabled: busyAny,
17867
+ onClick: () => testStored(account.id),
17868
+ children: busy === "test:" + account.id ? t.keyTesting : t.testSavedKey
17869
+ }),
17870
+ renderDetails: (account) => {
17871
+ const reading = status?.usage?.accounts.find((entry) => entry.accountId === account.id);
17872
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
17873
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [account.authKind === "oauth" ? t.oauthAccount : t.apiKeyAccount, account.plan !== void 0 && account.plan !== "" ? ` · ${account.plan}` : ""] }),
17874
+ reading !== void 0 && reading.ok && reading.balanceUsd !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
17875
+ t.usageBalance.replace("{amount}", reading.balanceUsd),
17876
+ " · ",
17877
+ t.usageReadAt.replace("{time}", formatAccountDate(reading.fetchedAt))
17878
+ ] }),
17879
+ reading !== void 0 && !reading.ok && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t.usageUnavailable.replace("{detail}", reading.error) })
17880
+ ] });
17881
+ },
17882
+ renderLoginActions: () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17883
+ className: "dsha-account-add-actions",
17884
+ style: {
17885
+ display: "flex",
17886
+ gap: 8
17887
+ },
17888
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17889
+ className: "dsha-btn dsha-btn-primary",
17890
+ disabled: busyAny || loginFlow?.status === "pending",
17891
+ onClick: startLogin,
17892
+ children: busy === "login" || loginFlow?.status === "pending" ? t.loggingIn : t.login
17893
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17894
+ className: "dsha-btn",
17895
+ disabled: busyAny,
17896
+ onClick: () => setShowKeyForm((value) => !value),
17897
+ children: t.useApiKey
17898
+ })]
17899
+ }),
17900
+ children: [
17901
+ loginFlow !== null && loginFlow.status !== "idle" && loginFlow.status !== "cancelled" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17902
+ className: "dshod-flow",
17903
+ children: [
17904
+ loginFlow.status === "pending" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
17905
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17906
+ className: "dsha-muted",
17907
+ style: { fontSize: 12 },
17908
+ children: t.loginHint
17909
+ }),
17910
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17911
+ className: "dshod-login-row",
17912
+ children: [
17913
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
17914
+ className: "dshod-login-code",
17915
+ "aria-label": t.loginCode,
17916
+ children: loginFlow.userCode
17917
+ }),
17918
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
17919
+ className: "dsha-btn",
17920
+ href: loginFlow.verificationUri,
17921
+ target: "_blank",
17922
+ rel: "noreferrer",
17923
+ children: t.loginOpen
17924
+ }),
17925
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
17926
+ className: "dsha-btn",
17927
+ disabled: busyAny,
17928
+ onClick: cancelLogin,
17929
+ children: t.loginCancel
17930
+ })
17931
+ ]
17932
+ }),
17933
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17934
+ className: "dsha-muted",
17935
+ style: { fontSize: 12 },
17936
+ children: t.loginWaiting
17937
+ })
17938
+ ] }),
17939
+ loginFlow.status === "complete" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17940
+ className: "dsha-muted",
17941
+ style: { fontSize: 12 },
17942
+ children: accounts.length > 0 ? t.loginComplete.replace("{account}", loginFlow.accountAlias === "" ? "OpenDesign" : loginFlow.accountAlias) : t.loginCompleteNoAccount
17943
+ }),
17944
+ loginFlow.status === "failed" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17945
+ className: "dshod-warning",
17946
+ children: t.loginFailed.replace("{detail}", loginFlow.error)
17947
+ })
17948
+ ]
17949
+ }),
17950
+ (loginFlow === null || loginFlow.status === "idle" || loginFlow.status === "cancelled") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
17951
+ className: "dshod-paste",
17952
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
17953
+ className: "dsha-muted dshod-paste-note",
17954
+ children: accounts.length > 0 ? t.loginHaveAccounts.replace("{count}", String(accounts.length)) : t.loginIdle
17955
+ })
17956
+ }),
17957
+ showKeyForm && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
17958
+ className: "dshod-keyform",
17959
+ children: [
17960
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
17961
+ className: "dsha-label",
17962
+ htmlFor: "opendesign-key",
17963
+ children: t.keySection
17964
+ }),
17965
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17966
+ id: "opendesign-key",
17967
+ className: "dshod-input",
17968
+ type: "password",
17969
+ value: key,
17970
+ placeholder: t.keyPlaceholder,
17971
+ autoComplete: "off",
17972
+ onChange: (event) => setKey(event.target.value)
17973
+ }),
17974
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
17975
+ className: "dsha-label",
17976
+ htmlFor: "opendesign-alias",
17977
+ children: t.keyAliasLabel
17978
+ }),
17979
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17980
+ id: "opendesign-alias",
17981
+ className: "dshod-input",
17982
+ value: alias,
17983
+ placeholder: t.keyAliasPlaceholder,
17984
+ onChange: (event) => setAlias(event.target.value)
17985
+ }),
17986
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
17987
+ className: "dsha-muted",
17988
+ style: { fontSize: 12 },
17989
+ children: t.keyAliasHint
17990
+ }),
17991
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
17992
+ className: "dsha-label",
17993
+ htmlFor: "opendesign-baseurl",
17994
+ children: t.keyBaseUrlLabel
17995
+ }),
17996
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
17997
+ id: "opendesign-baseurl",
17998
+ className: "dshod-input",
17999
+ value: keyBaseURL,
18000
+ placeholder: t.keyBaseUrlPlaceholder,
18001
+ onChange: (event) => setKeyBaseURL(event.target.value)
18002
+ }),
18003
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
18004
+ className: "dsha-muted",
18005
+ style: { fontSize: 12 },
18006
+ children: [
18007
+ t.keyHint,
18008
+ " ",
18009
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
18010
+ className: "dshod-link",
18011
+ href: "https://open-design.ai/cloud",
18012
+ target: "_blank",
18013
+ rel: "noreferrer",
18014
+ children: t.keyConsoleLink
18015
+ })
18016
+ ]
18017
+ }),
18018
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18019
+ className: "dshod-keyrow",
18020
+ children: [
18021
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18022
+ className: "dsha-btn dsha-btn-primary",
18023
+ disabled: busyAny || key.trim() === "",
18024
+ onClick: addKey,
18025
+ children: busy === "add" ? t.keySaving : t.keySave
18026
+ }),
18027
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18028
+ className: "dsha-btn",
18029
+ disabled: busyAny || key.trim() === "",
18030
+ onClick: testTypedKey,
18031
+ children: busy === "test-key" ? t.keyTesting : t.keyTest
18032
+ }),
18033
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18034
+ className: "dsha-btn",
18035
+ disabled: busyAny,
18036
+ onClick: () => setShowKeyForm(false),
18037
+ children: t.cancel
18038
+ })
18039
+ ]
18040
+ })
18041
+ ]
18042
+ })
18043
+ ]
18044
+ }),
18045
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
18046
+ className: "dsha-group",
18047
+ children: [
18048
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18049
+ className: "dsha-grouphead",
18050
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.modelsSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18051
+ className: "dsha-btn",
18052
+ disabled: busyAny,
18053
+ onClick: refreshCatalog,
18054
+ children: busy === "catalog" ? t.catalogSyncing : t.catalogSync
18055
+ })]
18056
+ }),
18057
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18058
+ className: "dsha-muted",
18059
+ style: { fontSize: 12 },
18060
+ children: t.modelsHint
18061
+ }),
18062
+ status !== null && models.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
18063
+ className: "dsha-empty",
18064
+ children: t.noModels
18065
+ }),
18066
+ status !== null && models.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
18067
+ !status.catalogSynced && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18068
+ className: "dsha-muted",
18069
+ style: { fontSize: 12 },
18070
+ children: t.catalogNeverSynced
18071
+ }),
18072
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelChecklist, {
18073
+ items: models.map((model) => ({
18074
+ id: model.id,
18075
+ name: model.name,
18076
+ hint: model.hint ?? `${formatCapacity$1(model.contextWindow)} · ${model.input.join("+")}${model.reasoning ? " · reasoning" : ""}`,
18077
+ enabled: model.enabled
18078
+ })),
18079
+ busy: busyAny,
18080
+ onToggle: (id, enabled) => toggleModel(id, enabled),
18081
+ onToggleAll: (enabled) => setAllModels(enabled),
18082
+ labels: {
18083
+ selectAll: t.selectAll,
18084
+ clearAll: t.unselectAll,
18085
+ countTemplate: t.modelChecklistCount,
18086
+ list: t.modelsSection
18087
+ }
18088
+ }),
18089
+ enabledCount === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18090
+ className: "dsha-muted",
18091
+ style: { fontSize: 12 },
18092
+ children: t.noModels
18093
+ }),
18094
+ anyPricing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18095
+ className: "dsha-muted",
18096
+ style: { fontSize: 12 },
18097
+ children: t.pricingNote
18098
+ })
18099
+ ] })
18100
+ ]
18101
+ }),
18102
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
18103
+ className: "dsha-group",
18104
+ children: [
18105
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
18106
+ className: "dsha-grouphead",
18107
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.contextSection })
18108
+ }),
18109
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18110
+ className: "dsha-muted",
18111
+ style: { fontSize: 12 },
18112
+ children: t.contextHint
18113
+ }),
18114
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ContextWindowEditor, {
18115
+ rows: enabledModels.map((model) => ({
18116
+ id: model.id,
18117
+ name: model.name,
18118
+ draft: drafts[model.id] ?? formatCapacity$1(model.contextWindow),
18119
+ ...model.contextWindowOverride === void 0 ? {} : { meta: `· ${t.contextOverridden}` },
18120
+ hasOverride: model.contextWindowOverride !== void 0,
18121
+ saving: busy === "ctx:" + model.id
18122
+ })),
18123
+ labels: {
18124
+ tokens: t.tokens,
18125
+ save: t.contextSave,
18126
+ saving: t.contextSaving,
18127
+ reset: t.contextReset,
18128
+ resetAll: t.contextResetAll,
18129
+ empty: t.contextEmpty
18130
+ },
18131
+ busy: busyAny,
18132
+ overrideCount: models.filter((model) => model.contextWindowOverride !== void 0).length,
18133
+ onDraftChange: (id, value) => setDrafts((current) => ({
18134
+ ...current,
18135
+ [id]: value
18136
+ })),
18137
+ onCommit: commitContext,
18138
+ onReset: resetContext,
18139
+ onResetAll: resetAllContext
18140
+ })
18141
+ ]
18142
+ }),
18143
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
18144
+ className: "dsha-group",
18145
+ children: [
18146
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18147
+ className: "dsha-grouphead",
18148
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.usageSection }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18149
+ className: "dsha-btn",
18150
+ disabled: busyAny,
18151
+ onClick: refreshUsage,
18152
+ children: busy === "usage" ? t.usageRefreshing : t.usageRefresh
18153
+ })]
18154
+ }),
18155
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
18156
+ className: "dsha-muted",
18157
+ style: { fontSize: 12 },
18158
+ children: t.usageHint
18159
+ }),
18160
+ (status?.usage === null || status?.usage === void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
18161
+ className: "dsha-empty",
18162
+ children: t.usageEmpty
18163
+ }),
18164
+ status?.usage !== null && status?.usage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: status.usage.accounts.filter((account) => !account.ok).map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
18165
+ className: "dshod-warning",
18166
+ children: [
18167
+ account.alias,
18168
+ ": ",
18169
+ t.usageUnavailable.replace("{detail}", account.error)
18170
+ ]
18171
+ }, account.accountId)) })
18172
+ ]
18173
+ }),
18174
+ settingsForm !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
18175
+ className: "dsha-group",
18176
+ children: [
18177
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
18178
+ className: "dsha-grouphead",
18179
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t.advancedSection })
18180
+ }),
18181
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18182
+ className: "dsha-row",
18183
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
18184
+ className: "dsha-label",
18185
+ htmlFor: "opendesign-baseurl-setting",
18186
+ children: t.baseURL
18187
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
18188
+ id: "opendesign-baseurl-setting",
18189
+ className: "dshod-input dshod-adv-control dshod-adv-mono",
18190
+ value: settingsForm.baseURL,
18191
+ onChange: (event) => setSettingsForm({
18192
+ ...settingsForm,
18193
+ baseURL: event.target.value
18194
+ })
18195
+ })]
18196
+ }),
18197
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18198
+ className: "dsha-row",
18199
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
18200
+ className: "dsha-label",
18201
+ htmlFor: "opendesign-default-window",
18202
+ children: t.defaultContextWindow
18203
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
18204
+ id: "opendesign-default-window",
18205
+ className: "dshod-input dshod-adv-control dshod-adv-num",
18206
+ value: settingsForm.defaultContextWindow,
18207
+ onChange: (event) => setSettingsForm({
18208
+ ...settingsForm,
18209
+ defaultContextWindow: event.target.value
18210
+ })
18211
+ })]
18212
+ }),
18213
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18214
+ className: "dsha-row",
18215
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
18216
+ className: "dsha-label",
18217
+ htmlFor: "opendesign-default-max",
18218
+ children: t.defaultMaxTokens
18219
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
18220
+ id: "opendesign-default-max",
18221
+ className: "dshod-input dshod-adv-control dshod-adv-num",
18222
+ value: settingsForm.defaultMaxTokens,
18223
+ onChange: (event) => setSettingsForm({
18224
+ ...settingsForm,
18225
+ defaultMaxTokens: event.target.value
18226
+ })
18227
+ })]
18228
+ }),
18229
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18230
+ className: "dsha-row",
18231
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
18232
+ className: "dsha-label",
18233
+ htmlFor: "opendesign-concurrency",
18234
+ children: t.maxConcurrentRequests
18235
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
18236
+ id: "opendesign-concurrency",
18237
+ className: "dshod-input dshod-adv-control dshod-adv-num",
18238
+ value: settingsForm.maxConcurrentRequests,
18239
+ onChange: (event) => setSettingsForm({
18240
+ ...settingsForm,
18241
+ maxConcurrentRequests: event.target.value
18242
+ })
18243
+ })]
18244
+ }),
18245
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
18246
+ className: "dsha-row",
18247
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
18248
+ className: "dsha-label",
18249
+ htmlFor: "opendesign-idle",
18250
+ children: t.streamIdleTimeoutMs
18251
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
18252
+ id: "opendesign-idle",
18253
+ className: "dshod-input dshod-adv-control dshod-adv-num",
18254
+ value: settingsForm.streamIdleTimeoutMs,
18255
+ onChange: (event) => setSettingsForm({
18256
+ ...settingsForm,
18257
+ streamIdleTimeoutMs: event.target.value
18258
+ })
18259
+ })]
18260
+ }),
18261
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
18262
+ className: "dsha-actions",
18263
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
18264
+ className: "dsha-btn dsha-btn-primary",
18265
+ disabled: busyAny,
18266
+ onClick: saveSettings,
18267
+ children: busy === "settings" ? t.savingSettings : t.saveSettings
18268
+ })
18269
+ })
18270
+ ]
18271
+ })
18272
+ ]
18273
+ });
18274
+ }
18275
+ //#endregion
17220
18276
  //#region src/client/hub/providers.tsx
17221
18277
  /** One POST to a line's settings endpoint, answered with that line's refreshed status. */
17222
18278
  async function postLineSettings(prefix, body) {
@@ -17318,6 +18374,12 @@ window.__ModuleLoader__.load({
17318
18374
  name: QODER_PROVIDER_NAME,
17319
18375
  setEnabled: (enabled) => postLineSettings(QODER_ROUTE_PREFIX, { enabled }),
17320
18376
  renderDetail: ({ onModelChange }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QoderSection, { onModelChange })
18377
+ },
18378
+ {
18379
+ id: "opendesign",
18380
+ name: OPENDESIGN_PROVIDER_NAME,
18381
+ setEnabled: (enabled) => postLineSettings(OPENDESIGN_ROUTE_PREFIX, { enabled }),
18382
+ renderDetail: ({ onModelChange }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenDesignSection, { onModelChange })
17321
18383
  }
17322
18384
  ];
17323
18385
  function hubProviderDescriptor(id) {
@@ -18851,7 +19913,7 @@ window.__ModuleLoader__.load({
18851
19913
  //#region src/client/minimax-code/MinimaxVideoDocumentBody.tsx
18852
19914
  /** 兜底翻译:只在没有 locale 座位时用到。 */
18853
19915
  function translate$1(key) {
18854
- return zh$8[key] ?? key;
19916
+ return zh$9[key] ?? key;
18855
19917
  }
18856
19918
  /**
18857
19919
  * 一个文件地址里的会话与路径。
@@ -18987,7 +20049,7 @@ window.__ModuleLoader__.load({
18987
20049
  */
18988
20050
  /** 兜底翻译:只在没有 locale 座位时用到,走同一份 zh 字典。 */
18989
20051
  function translate(key) {
18990
- return zh$8[key] ?? key;
20052
+ return zh$9[key] ?? key;
18991
20053
  }
18992
20054
  /**
18993
20055
  * 一张视频工具卡片。
@@ -19529,7 +20591,7 @@ window.__ModuleLoader__.load({
19529
20591
  * 没有快照、没有窗口、或全部窗口都没有百分比时返回 null,即**不渲染胶囊**:
19530
20592
  * 契约允许 quota 为 null,装一个占位数字比不显示更像坏了。
19531
20593
  */
19532
- function selectBadgeFacts$2(status, lookup = (key) => zh$7[key]) {
20594
+ function selectBadgeFacts$2(status, lookup = (key) => zh$8[key]) {
19533
20595
  const measured = (status?.quota?.windows ?? []).filter((window) => typeof window.usedPercent === "number" && Number.isFinite(window.usedPercent));
19534
20596
  if (measured.length === 0) return null;
19535
20597
  const tightest = measured.reduce((best, window) => {
@@ -19613,7 +20675,7 @@ window.__ModuleLoader__.load({
19613
20675
  *
19614
20676
  * 没有快照、没有窗口、或全部窗口都没有百分比时返回 null(见文件头)。
19615
20677
  */
19616
- function selectBadgeFacts$1(status, lookup = (key) => zh$4[key]) {
20678
+ function selectBadgeFacts$1(status, lookup = (key) => zh$5[key]) {
19617
20679
  const quota = status?.quota;
19618
20680
  if (quota === null || quota === void 0) return null;
19619
20681
  if (quota.kind !== "windowed") return null;
@@ -19745,7 +20807,7 @@ window.__ModuleLoader__.load({
19745
20807
  }
19746
20808
  //#endregion
19747
20809
  //#region src/client/cline-pass/ClinePassComposerQuota.tsx
19748
- const API = new ClinePassApi();
20810
+ const API$1 = new ClinePassApi();
19749
20811
  /**
19750
20812
  * The composer badge for this line.
19751
20813
  *
@@ -19759,8 +20821,8 @@ window.__ModuleLoader__.load({
19759
20821
  directory: props.directory,
19760
20822
  loadModelDirectory: props.loadModelDirectory,
19761
20823
  providerId: "cline-pass",
19762
- label: zh$3.composerLabel,
19763
- readStatus: () => API.status(),
20824
+ label: zh$4.composerLabel,
20825
+ readStatus: () => API$1.status(),
19764
20826
  selectFacts: selectClinePassFacts
19765
20827
  });
19766
20828
  }
@@ -19854,7 +20916,7 @@ window.__ModuleLoader__.load({
19854
20916
  * 另外那只可能还剩一大半。所以这里不平均、不取最小剩余,而是取最大已用比例。
19855
20917
  * 没有快照、没有桶、或全部桶都没有总额时返回 null(见文件头)。
19856
20918
  */
19857
- function selectBadgeFacts(status, lookup = (key) => zh$2[key]) {
20919
+ function selectBadgeFacts(status, lookup = (key) => zh$3[key]) {
19858
20920
  const quota = status?.quota;
19859
20921
  if (quota === null || quota === void 0) return null;
19860
20922
  const measurable = quota.buckets.filter((bucket) => bucket.total !== null && bucket.total > 0 && bucket.used !== null);
@@ -19864,7 +20926,7 @@ window.__ModuleLoader__.load({
19864
20926
  const remaining = Math.round((1 - used) * 100);
19865
20927
  const unit = tightest.unit !== null && tightest.unit !== "" ? " " + tightest.unit : "";
19866
20928
  const bucketLabel = quotaBucketText(tightest.kind, {
19867
- ...zh$2,
20929
+ ...zh$3,
19868
20930
  quotaBucketPersonal: lookup("quotaBucketPersonal"),
19869
20931
  quotaBucketAddOn: lookup("quotaBucketAddOn"),
19870
20932
  quotaBucketOrg: lookup("quotaBucketOrg")
@@ -19946,6 +21008,80 @@ window.__ModuleLoader__.load({
19946
21008
 
19947
21009
  .dsha-badge.dshq-adopted{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 16%,var(--dsw-alias-bg-layer-1));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary)}
19948
21010
  `, STYLE_ID);
21011
+ }
21012
+ //#endregion
21013
+ //#region src/client/opendesign/OpenDesignComposerQuota.tsx
21014
+ const API = new OpenDesignApi();
21015
+ /**
21016
+ * The composer badge for this line.
21017
+ *
21018
+ * Only OAuth accounts carry a control key, so only they have a wallet reading
21019
+ * at all; the badge shows the primary (else first) readable account's latest
21020
+ * balance and never triggers a read of its own — a poll must not fan out one
21021
+ * upstream call per account. A pasted-key-only pool renders nothing.
21022
+ */
21023
+ function OpenDesignComposerQuota(props) {
21024
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ComposerQuotaBadge, {
21025
+ directory: props.directory,
21026
+ loadModelDirectory: props.loadModelDirectory,
21027
+ providerId: "opendesign",
21028
+ label: zh$2.composerLabel,
21029
+ readStatus: () => API.status(),
21030
+ selectFacts: selectOpenDesignFacts
21031
+ });
21032
+ }
21033
+ /** The line's own number picker, exported so a test can pin the rule. */
21034
+ function selectOpenDesignFacts(status, _modelId) {
21035
+ if (status === null || !status.authenticated || status.usage === null) return null;
21036
+ const readings = status.usage.accounts.filter((account) => account.ok && account.balanceUsd !== null);
21037
+ if (readings.length === 0) return null;
21038
+ const primaryId = status.pool.activeAccountId ?? status.pool.accounts.find((account) => account.isPrimary)?.id;
21039
+ const reading = readings.find((account) => account.accountId === primaryId) ?? readings[0];
21040
+ const amount = reading.balanceUsd;
21041
+ const zero = Number(amount) === 0;
21042
+ return {
21043
+ text: `$${amount}`,
21044
+ tooltip: `${reading.alias} · ${zh$2.usageReadAt.replace("{time}", new Date(reading.fetchedAt).toLocaleTimeString())}`,
21045
+ level: zero ? "danger" : "normal"
21046
+ };
21047
+ }
21048
+ //#endregion
21049
+ //#region src/client/opendesign/styles.ts
21050
+ /**
21051
+ * OpenDesign's own prefixed classes only: the key form and the advanced
21052
+ * controls, which the shared `.dsha-*` vocabulary has no expression for.
21053
+ * Everything else on the tab reuses the shared card.
21054
+ *
21055
+ * `.dshod-input` mirrors the input styling another line declares under an
21056
+ * unprefixed name on purpose: that class is that line's own, and a prefix of
21057
+ * ours keeps this card's look from drifting with someone else's sheet.
21058
+ */
21059
+ function installOpenDesignStyles() {
21060
+ installPluginStyle("opendesign", `
21061
+ .dshod-input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 10px;box-sizing:border-box}
21062
+ .dshod-input:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:1px}
21063
+ .dshod-input:disabled{opacity:.5}
21064
+ .dshod-keyform{display:flex;flex-direction:column;gap:8px;align-items:stretch;margin-top:8px}
21065
+ .dshod-keyrow{display:flex;gap:8px;flex-wrap:wrap;margin-top:4px}
21066
+ .dshod-link{color:var(--dsw-alias-button-info-fill,#397ee8);font-size:12px;text-decoration:none}
21067
+ .dshod-link:hover{text-decoration:underline}
21068
+ .dshod-details{margin-top:8px;font-size:12px;color:var(--dsw-alias-label-tertiary)}
21069
+ .dshod-details>summary{cursor:pointer;color:var(--dsw-alias-label-secondary);user-select:none}
21070
+ .dshod-details ul{margin:6px 0 0;padding-left:18px;display:flex;flex-direction:column;gap:4px}
21071
+ .dshod-flow{border-top:0.5px solid var(--dsw-alias-border-l2);display:flex;flex-direction:column;gap:8px;margin-top:10px;padding-top:10px}
21072
+ .dshod-login-row{align-items:center;display:flex;gap:12px;flex-wrap:wrap;margin:4px 0}
21073
+ .dshod-login-code{border:0.5px solid var(--dsw-alias-brand-primary);border-radius:8px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:20px;font-weight:700;letter-spacing:.18em;padding:6px 14px}
21074
+ .dshod-paste{align-items:center;display:flex;flex-wrap:wrap;gap:8px;justify-content:space-between;margin-top:8px}
21075
+ .dshod-paste-note{font-size:12px}
21076
+ .dshod-warning{color:var(--dsw-alias-label-warning,#d9913b);font-size:12px}
21077
+ .dshod-adv-control{width:240px;max-width:100%;flex:none}
21078
+ .dshod-adv-control.dsha-select{max-width:240px;min-width:240px;width:240px}
21079
+ .dshod-adv-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}
21080
+ .dshod-adv-num{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;font-variant-numeric:tabular-nums}
21081
+ @media(max-width:720px){
21082
+ .dshod-adv-control,.dshod-adv-control.dsha-select{width:100%;max-width:none;min-width:0}
21083
+ }
21084
+ `);
19949
21085
  }
19950
21086
  //#endregion
19951
21087
  //#region src/client/mermaid/sanitize.ts
@@ -21710,7 +22846,7 @@ window.__ModuleLoader__.load({
21710
22846
  }
21711
22847
  /** 兜底翻译:只在没有 locale 服务时用到(测试、以及菜单渲染早于字典注册)。 */
21712
22848
  function fallbackTranslate$1(key, params) {
21713
- const template = zh$8[key] ?? key;
22849
+ const template = zh$9[key] ?? key;
21714
22850
  if (params === void 0) return template;
21715
22851
  return template.replace(/\{(\w+)\}/g, (_match, name) => String(params[name] ?? ""));
21716
22852
  }
@@ -50515,34 +51651,34 @@ window.__ModuleLoader__.load({
50515
51651
  installModelChecklistStyles();
50516
51652
  return () => {};
50517
51653
  }, "dsh-chatgpt-subscription: hub styles");
50518
- ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$12), "dsh-antigravity: dictionaries");
51654
+ ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, dictionaries$13), "dsh-antigravity: dictionaries");
50519
51655
  ctx.effect(() => {
50520
51656
  installAntigravityStyles();
50521
51657
  return () => {};
50522
51658
  }, "dsh-antigravity: styles");
50523
- ctx.effect(() => ctx.locale.register(NS_CLAUDE, dictionaries$6), "dsh-claude: dictionaries");
51659
+ ctx.effect(() => ctx.locale.register(NS_CLAUDE, dictionaries$7), "dsh-claude: dictionaries");
50524
51660
  ctx.effect(() => {
50525
51661
  installClaudeStyles();
50526
51662
  return () => {};
50527
51663
  }, "dsh-claude: styles");
50528
- ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$11), "dsh-command-code: dictionaries");
50529
- ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$10), "dsh-kimi-code: dictionaries");
51664
+ ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, dictionaries$12), "dsh-command-code: dictionaries");
51665
+ ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, dictionaries$11), "dsh-kimi-code: dictionaries");
50530
51666
  ctx.effect(() => {
50531
51667
  installKimiCodeStyles();
50532
51668
  return () => {};
50533
51669
  }, "dsh-kimi-code: styles");
50534
- ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, dictionaries$8), "dsh-minimax-code: dictionaries");
51670
+ ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, dictionaries$9), "dsh-minimax-code: dictionaries");
50535
51671
  ctx.effect(() => {
50536
51672
  installMinimaxCodeStyles();
50537
51673
  return () => {};
50538
51674
  }, "dsh-minimax-code: styles");
50539
- ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$9), "dsh-workbuddy: dictionaries");
50540
- ctx.effect(() => ctx.locale.register(NS_GLM_CODING_PLAN, dictionaries$7), "dsh-glm-coding-plan: dictionaries");
51675
+ ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, dictionaries$10), "dsh-workbuddy: dictionaries");
51676
+ ctx.effect(() => ctx.locale.register(NS_GLM_CODING_PLAN, dictionaries$8), "dsh-glm-coding-plan: dictionaries");
50541
51677
  ctx.effect(() => {
50542
51678
  installGlmCodingPlanStyles();
50543
51679
  return () => {};
50544
51680
  }, "dsh-glm-coding-plan: styles");
50545
- ctx.effect(() => ctx.locale.register(NS_OLLAMA, dictionaries$5), "dsh-ollama: dictionaries");
51681
+ ctx.effect(() => ctx.locale.register(NS_OLLAMA, dictionaries$6), "dsh-ollama: dictionaries");
50546
51682
  ctx.effect(() => {
50547
51683
  installWorkBuddyStyles();
50548
51684
  return () => {};
@@ -50552,21 +51688,26 @@ window.__ModuleLoader__.load({
50552
51688
  installProgressUpdatesStyles();
50553
51689
  return () => {};
50554
51690
  }, "dsh-progress-updates: styles");
50555
- ctx.effect(() => ctx.locale.register(NS_STEP_CODE, dictionaries$4), "dsh-step-code: dictionaries");
51691
+ ctx.effect(() => ctx.locale.register(NS_STEP_CODE, dictionaries$5), "dsh-step-code: dictionaries");
50556
51692
  ctx.effect(() => {
50557
51693
  installStepCodeStyles();
50558
51694
  return () => {};
50559
51695
  }, "dsh-step-code: styles");
50560
- ctx.effect(() => ctx.locale.register(NS_CLINE_PASS, dictionaries$3), "dsh-cline-pass: dictionaries");
51696
+ ctx.effect(() => ctx.locale.register(NS_CLINE_PASS, dictionaries$4), "dsh-cline-pass: dictionaries");
50561
51697
  ctx.effect(() => {
50562
51698
  installClinePassStyles();
50563
51699
  return () => {};
50564
51700
  }, "dsh-cline-pass: styles");
50565
- ctx.effect(() => ctx.locale.register(NS_QODER, dictionaries$2), "dsh-qoder: dictionaries");
51701
+ ctx.effect(() => ctx.locale.register(NS_QODER, dictionaries$3), "dsh-qoder: dictionaries");
50566
51702
  ctx.effect(() => {
50567
51703
  installQoderStyles();
50568
51704
  return () => {};
50569
51705
  }, "dsh-qoder: styles");
51706
+ ctx.effect(() => ctx.locale.register(NS_OPENDESIGN, dictionaries$2), "dsh-opendesign: dictionaries");
51707
+ ctx.effect(() => {
51708
+ installOpenDesignStyles();
51709
+ return () => {};
51710
+ }, "dsh-opendesign: styles");
50570
51711
  ctx.effect(() => {
50571
51712
  installPoolStyles();
50572
51713
  return () => {};
@@ -50670,6 +51811,13 @@ window.__ModuleLoader__.load({
50670
51811
  locale: NS_QODER,
50671
51812
  inject: (sessionId) => composerBadgeInject(ctx, sessionId)
50672
51813
  }, QoderComposerQuota));
51814
+ ctx.slots.inject("conversation.input.right", () => ctx.slots.register({
51815
+ name: "conversation.input.right",
51816
+ id: "opendesign-quota",
51817
+ order: 46,
51818
+ locale: NS_OPENDESIGN,
51819
+ inject: (sessionId) => composerBadgeInject(ctx, sessionId)
51820
+ }, OpenDesignComposerQuota));
50673
51821
  ctx.slots.inject("tool.call.toolview", () => ctx.slots.register({
50674
51822
  name: "tool.call.toolview",
50675
51823
  key: CODEX_IMAGE_TOOL_NAME,