dsh-connect-trae 3.4.2 → 3.5.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.
- package/CHANGELOG.md +121 -0
- package/README.en.md +2 -0
- package/README.md +2 -0
- package/lib/client.js +796 -504
- package/lib/index.d.ts +81 -1
- package/lib/index.js +50 -2
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -203,6 +203,39 @@ window.__ModuleLoader__.load({
|
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
205
|
/**
|
|
206
|
+
* Which seat one region's readout uses, defaulting to the composer row.
|
|
207
|
+
*
|
|
208
|
+
* Anything other than an explicit `'stats'` reads as `'composer'`, which covers
|
|
209
|
+
* the two cases that matter: a profile written BEFORE this setting existed (the
|
|
210
|
+
* composer row was the only seat, so an upgrade moves nothing on screen), and a
|
|
211
|
+
* hand-edited value the schema does not know. Falling back rather than
|
|
212
|
+
* rendering nowhere is deliberate — an unrecognized value must not make the
|
|
213
|
+
* readout disappear, which is the very defect this setting exists to fix.
|
|
214
|
+
*
|
|
215
|
+
* `value` may be the whole settings section or the `regions` map (see
|
|
216
|
+
* {@link regionsMapOf}).
|
|
217
|
+
*/
|
|
218
|
+
function regionCreditPositionOf(value, region) {
|
|
219
|
+
return regionSlotOf(value, region)["creditPosition"] === "stats" ? "stats" : "composer";
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Build the next `regions` settings value for one region's credit seat.
|
|
223
|
+
*
|
|
224
|
+
* Same merge rule as every sibling region write: only the target region's
|
|
225
|
+
* `creditPosition` changes, so a seat change cannot drop that slot's model
|
|
226
|
+
* directory, selection, budgets or enabled flag, nor touch the other region.
|
|
227
|
+
*
|
|
228
|
+
* `value` may be the whole settings section or the `regions` map; the RETURN
|
|
229
|
+
* value is always the `regions` map, i.e. exactly what `settingsScope.set(
|
|
230
|
+
* 'regions', ...)` needs.
|
|
231
|
+
*/
|
|
232
|
+
function nextRegionCreditPosition(value, region, position) {
|
|
233
|
+
return nextRegionSlots(regionsMapOf(value), region, {
|
|
234
|
+
...regionSlotOf(value, region),
|
|
235
|
+
creditPosition: position
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
206
239
|
* Whether Trae's plan identity says this account is on a paying plan.
|
|
207
240
|
*
|
|
208
241
|
* `has_package` alone is NOT that question — it reports whether a package
|
|
@@ -299,6 +332,16 @@ window.__ModuleLoader__.load({
|
|
|
299
332
|
.dsm-trae-pref b{font-weight:500;color:var(--dsw-alias-label-primary,#e6e6e6)}
|
|
300
333
|
.dsm-trae-pref-hint{color:var(--dsw-alias-label-tertiary,#9aa0a8)}
|
|
301
334
|
.dsm-trae-pref span{min-width:0}
|
|
335
|
+
/* The credit readout's seat picker (learned from workbuddy #62). Its OWN label
|
|
336
|
+
class, deliberately not the plain .dsm-trae-pref the two checkboxes use: a
|
|
337
|
+
query for "the composer-credits switch" must not be able to pick this control
|
|
338
|
+
up, because the two are different widgets and a test selecting by position
|
|
339
|
+
would otherwise start asserting about a <select>.
|
|
340
|
+
The select keeps its own class for the same reason, and takes the checkbox
|
|
341
|
+
column's width so it reads as a sibling of the box rather than a stray row. */
|
|
342
|
+
.dsm-trae-credit-position-pref{align-items:flex-start}
|
|
343
|
+
.dsm-trae-credit-position{flex:none;max-width:150px;margin-top:-1px;padding:2px 6px;font-size:12px}
|
|
344
|
+
.dsm-trae-credit-position:disabled{cursor:default}
|
|
302
345
|
/* The card's checkboxes are the platform's own, styled only with
|
|
303
346
|
accent-color 鈥?the SAME idiom .dsm-trae-mainui-switch-label above already
|
|
304
347
|
uses for the composer-line switch, and the one the sibling
|
|
@@ -478,6 +521,51 @@ window.__ModuleLoader__.load({
|
|
|
478
521
|
an error: it is Trae's one-per-device-per-day rule, and the day is simply
|
|
479
522
|
spent. Rendering it in the error colour would read as a plugin fault. */
|
|
480
523
|
.dsm-trae-checkin-note{margin:8px 0 0;font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#c6c9d0)}
|
|
524
|
+
/* The busy veil: one overlay for every account write whose result only lands
|
|
525
|
+
after the Host re-reads its settings document. Fixed so it covers the card
|
|
526
|
+
no matter which section started the operation, and translucent so the table
|
|
527
|
+
stays visible underneath — the user is watching a specific row change, and
|
|
528
|
+
hiding it would defeat the point.
|
|
529
|
+
|
|
530
|
+
The mask and card surface are the HOST's own tokens, not this file's
|
|
531
|
+
invention. --dsw-alias-bg-mask-1 + --dsw-mask-blur is exactly what the
|
|
532
|
+
host's own overlays use, so the veil dims the way every other overlay in the
|
|
533
|
+
shell does instead of laying its own black wash on top. A hardcoded flat
|
|
534
|
+
black mask (e.g. a mid-transparency black) was tuned against neither theme:
|
|
535
|
+
too weak next to the host's .24 mask in light mode, and it ignored the
|
|
536
|
+
host's blur entirely.
|
|
537
|
+
|
|
538
|
+
bg-layer-2 (not bg-primary, which does not exist in the host's token set at
|
|
539
|
+
all and therefore always fell through to this file's near-black #1b1c20) is
|
|
540
|
+
the same surface the host puts behind its panels — that near-black fallback
|
|
541
|
+
is what made the veil read as a black slab with unreadable text on it. */
|
|
542
|
+
.dsm-trae-veil{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.32));backdrop-filter:var(--dsw-mask-blur);cursor:progress}
|
|
543
|
+
/* --dsw-elevation-prominent is the host's own panel shadow (a hairline stroke
|
|
544
|
+
plus two soft layers); a hand-rolled drop shadow read as a heavy grey box. */
|
|
545
|
+
.dsm-trae-veil-card{display:flex;flex-direction:column;align-items:center;gap:8px;max-width:min(340px,80vw);padding:16px 20px;border:1px solid var(--dsw-alias-border-l2,#0000001a);border-radius:12px;background:var(--dsw-alias-bg-layer-2,#fff);box-shadow:var(--dsw-elevation-prominent,0 8px 28px rgba(0,0,0,.35))}
|
|
546
|
+
.dsm-trae-veil-text{font-size:13px;line-height:20px;color:var(--dsw-alias-label-primary,#0f1115);text-align:center}
|
|
547
|
+
/* label-secondary, not label-tertiary: this line carries the operation's
|
|
548
|
+
detail and must stay legible. tertiary is the host's dimmest tier
|
|
549
|
+
(neutral-bluish-600 on light, neutral-bluish-400 on dark) and is meant for
|
|
550
|
+
metadata, not for a sentence the user has to read while waiting. */
|
|
551
|
+
.dsm-trae-veil-hint{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary,#61666b);text-align:center}
|
|
552
|
+
/* The spinner proves the UI is alive when the row under it has not changed yet
|
|
553
|
+
— which is precisely the confusion the veil exists to remove. It follows the
|
|
554
|
+
host's own state spinner (dsh's _dsh-state-dot-spin): an SVG arc whose dash
|
|
555
|
+
breathes while it turns, currentColor so it inherits the tier it sits in,
|
|
556
|
+
and the same 1.5s beat. The previous 18px border-ring at .7s was roughly
|
|
557
|
+
twice the host's speed and visibly out of step with every other spinner in
|
|
558
|
+
the shell — that mismatch, more than the shape itself, is what made it look
|
|
559
|
+
cheap.
|
|
560
|
+
|
|
561
|
+
Reduced-motion users get the static arc rather than a frozen ring, matching
|
|
562
|
+
how the host degrades its own spinner. */
|
|
563
|
+
.dsm-trae-veil-spinner{width:20px;height:20px;color:var(--dsw-alias-label-secondary,#61666b);animation:dsm-trae-veil-spin 1.5s linear infinite}
|
|
564
|
+
.dsm-trae-veil-spinner-track{opacity:.25}
|
|
565
|
+
.dsm-trae-veil-spinner-arc{stroke-dasharray:12 150;animation:dsm-trae-veil-dash 1.5s ease-in-out infinite}
|
|
566
|
+
@keyframes dsm-trae-veil-spin{to{transform:rotate(360deg)}}
|
|
567
|
+
@keyframes dsm-trae-veil-dash{0%{stroke-dasharray:12 150;stroke-dashoffset:0}50%{stroke-dasharray:24 150;stroke-dashoffset:-6}to{stroke-dasharray:12 150;stroke-dashoffset:0}}
|
|
568
|
+
@media (prefers-reduced-motion: reduce){.dsm-trae-veil-spinner{animation:none}.dsm-trae-veil-spinner-arc{animation:none;stroke-dasharray:18 150;stroke-dashoffset:-3}}
|
|
481
569
|
`;
|
|
482
570
|
/**
|
|
483
571
|
* Composer-row readout styles, injected by the readout itself.
|
|
@@ -626,6 +714,76 @@ window.__ModuleLoader__.load({
|
|
|
626
714
|
}
|
|
627
715
|
.dsm-trae-expiry-detail{font-size:11px;line-height:16px;opacity:.85}
|
|
628
716
|
`;
|
|
717
|
+
//#endregion
|
|
718
|
+
//#region src/client/BusyOverlay.tsx
|
|
719
|
+
/**
|
|
720
|
+
* The shared busy veil's spinner: an arc that breathes while it turns.
|
|
721
|
+
*
|
|
722
|
+
* Deliberately the host's own state-spinner shape (dsh's `_dsh-state-dot-spin`)
|
|
723
|
+
* rather than a border-ring: a two-tone CSS ring at .7s read as a loading
|
|
724
|
+
* indicator from another decade and was out of step with every spinner in the
|
|
725
|
+
* shell. The motion lives in CSS (`dsm-trae-veil-spin` / `-dash`), so this
|
|
726
|
+
* element only describes the geometry; `currentColor` lets it inherit whatever
|
|
727
|
+
* tier it sits in.
|
|
728
|
+
*
|
|
729
|
+
* `aria-hidden` because the veil's `role="status"` already announces the
|
|
730
|
+
* message — a second announcement from a decorative arc is noise.
|
|
731
|
+
*/
|
|
732
|
+
function VeilSpinner() {
|
|
733
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
734
|
+
className: "dsm-trae-veil-spinner",
|
|
735
|
+
viewBox: "0 0 20 20",
|
|
736
|
+
"aria-hidden": "true",
|
|
737
|
+
focusable: "false",
|
|
738
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
739
|
+
className: "dsm-trae-veil-spinner-track",
|
|
740
|
+
cx: "10",
|
|
741
|
+
cy: "10",
|
|
742
|
+
r: "8",
|
|
743
|
+
fill: "none",
|
|
744
|
+
stroke: "currentColor",
|
|
745
|
+
strokeWidth: "2"
|
|
746
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
747
|
+
className: "dsm-trae-veil-spinner-arc",
|
|
748
|
+
cx: "10",
|
|
749
|
+
cy: "10",
|
|
750
|
+
r: "8",
|
|
751
|
+
fill: "none",
|
|
752
|
+
stroke: "currentColor",
|
|
753
|
+
strokeWidth: "2",
|
|
754
|
+
strokeLinecap: "round"
|
|
755
|
+
})]
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* The veil. Deliberately NOT a modal dialog: it carries no focusable control
|
|
760
|
+
* and no dismissal — there is nothing for the user to decide, only a step to
|
|
761
|
+
* wait through. `aria-busy` plus a polite live region state that to screen
|
|
762
|
+
* readers, which is the whole accessibility contract a wait screen needs.
|
|
763
|
+
*/
|
|
764
|
+
function BusyOverlay({ message, hint, visible }) {
|
|
765
|
+
if (!visible) return null;
|
|
766
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
767
|
+
className: "dsm-trae-veil",
|
|
768
|
+
role: "status",
|
|
769
|
+
"aria-busy": "true",
|
|
770
|
+
"aria-live": "polite",
|
|
771
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
772
|
+
className: "dsm-trae-veil-card",
|
|
773
|
+
children: [
|
|
774
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(VeilSpinner, {}),
|
|
775
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
776
|
+
className: "dsm-trae-veil-text",
|
|
777
|
+
children: message
|
|
778
|
+
}),
|
|
779
|
+
hint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
780
|
+
className: "dsm-trae-veil-hint",
|
|
781
|
+
children: hint
|
|
782
|
+
})
|
|
783
|
+
]
|
|
784
|
+
})
|
|
785
|
+
});
|
|
786
|
+
}
|
|
629
787
|
//#endregion
|
|
630
788
|
//#region src/client/plan-text.ts
|
|
631
789
|
/**
|
|
@@ -1008,6 +1166,49 @@ window.__ModuleLoader__.load({
|
|
|
1008
1166
|
setSettingsRevision((value) => value + 1);
|
|
1009
1167
|
}), [settingsScope]);
|
|
1010
1168
|
/**
|
|
1169
|
+
* WHERE the active tab's credit readout sits (learned from workbuddy #62).
|
|
1170
|
+
*
|
|
1171
|
+
* Read from the committed SETTINGS document, through the same
|
|
1172
|
+
* `regionCreditPositionOf` helper the Host uses — so the control reads
|
|
1173
|
+
* instantly and can never disagree with the readout's own gate, which reads
|
|
1174
|
+
* the same scope. This mirrors how the show/hide box beside it works
|
|
1175
|
+
* (`committedSettings`), rather than how the sibling workbuddy card does it:
|
|
1176
|
+
* that card reads the Host's usage answer because a measured defect on its
|
|
1177
|
+
* 0.1.7 deployments left the browser settings mirror for its namespace STALE.
|
|
1178
|
+
* No such staleness is reproducible here, and reading the mirror eagerly is
|
|
1179
|
+
* what keeps this control correct on first paint — a picker fed only by the
|
|
1180
|
+
* usage document would sit on the default until a fetch landed, which is the
|
|
1181
|
+
* "looks like it did nothing" failure this control must not have.
|
|
1182
|
+
*
|
|
1183
|
+
* `settingsRevision` is read through the setter above, and the whole block
|
|
1184
|
+
* re-renders when the scope notifies, so a write made elsewhere (another
|
|
1185
|
+
* window, the DSH settings form) converges here.
|
|
1186
|
+
*/
|
|
1187
|
+
const creditPositionOn = (item) => regionCreditPositionOf(settingsScope?.getSnapshot().value, item);
|
|
1188
|
+
/**
|
|
1189
|
+
* Move one region's credit readout between its two seats.
|
|
1190
|
+
*
|
|
1191
|
+
* Same shape as every other region write on this card: the whole target slot
|
|
1192
|
+
* goes in (so a seat change cannot drop that region's model picks, budgets or
|
|
1193
|
+
* enabled flag, nor touch the sibling region), the write is read-back
|
|
1194
|
+
* verified, and the Host is re-read afterwards. The re-read is load-bearing
|
|
1195
|
+
* here — the control renders the Host's answer, so without it the picker
|
|
1196
|
+
* keeps showing the seat it had and the change looks like it did nothing.
|
|
1197
|
+
*/
|
|
1198
|
+
const changeCreditPosition = async (item, position) => {
|
|
1199
|
+
if (settingsScope === void 0 || settingsScope.getSnapshot().writable !== true) return;
|
|
1200
|
+
setSavingSettings(true);
|
|
1201
|
+
setWriteError(void 0);
|
|
1202
|
+
try {
|
|
1203
|
+
await writeSettingsField(settingsScope, "regions", nextRegionCreditPosition(settingsScope.getSnapshot().value, item, position), (readBack) => regionCreditPositionOf(readBack, item) === position);
|
|
1204
|
+
await refreshUsage(item);
|
|
1205
|
+
} catch (error) {
|
|
1206
|
+
if (mounted.current) setWriteError(error instanceof Error ? error.message : t("row.requestFailed"));
|
|
1207
|
+
} finally {
|
|
1208
|
+
if (mounted.current) setSavingSettings(false);
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
/**
|
|
1011
1212
|
* Whether one region's provider is switched on, read off the SAME committed
|
|
1012
1213
|
* settings document the Host reads (`regionEnabledOf` mirrors the Host's
|
|
1013
1214
|
* `regionStateOf` opt-out rule: only an explicit `false` disables). Reading
|
|
@@ -1706,539 +1907,576 @@ window.__ModuleLoader__.load({
|
|
|
1706
1907
|
const label = status.status === "signed-in" ? t("row.signedIn", { accountName: status.accountName }) : status.status === "error" ? t("row.requestFailed") : t("row.signedOut");
|
|
1707
1908
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
|
|
1708
1909
|
className: `dsm-plugin-card${open ? " dsm-plugin-card-open" : ""}`,
|
|
1709
|
-
children: [
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1719
|
-
className: "dsm-plugin-card-icon",
|
|
1720
|
-
src: TRAE_PLUGIN_ICON,
|
|
1721
|
-
alt: ""
|
|
1722
|
-
}),
|
|
1723
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1724
|
-
className: "dsm-plugin-card-head",
|
|
1725
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1726
|
-
className: "dsm-plugin-card-title",
|
|
1727
|
-
children: title
|
|
1728
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1729
|
-
className: "dsm-plugin-card-description",
|
|
1730
|
-
children: t("row.desc")
|
|
1731
|
-
})]
|
|
1732
|
-
}),
|
|
1733
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1734
|
-
"aria-hidden": "true",
|
|
1735
|
-
className: `dsm-plugin-card-chevron${open ? " dsm-plugin-card-chevron-open" : ""}`
|
|
1736
|
-
})
|
|
1737
|
-
]
|
|
1738
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1739
|
-
className: "dsm-plugin-card-body",
|
|
1740
|
-
hidden: !open,
|
|
1741
|
-
children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1742
|
-
className: "dsm-trae-usage",
|
|
1910
|
+
children: [
|
|
1911
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1912
|
+
type: "button",
|
|
1913
|
+
className: "dsm-plugin-card-header",
|
|
1914
|
+
"aria-expanded": open,
|
|
1915
|
+
"aria-label": `${t(open ? "row.collapse" : "row.expand")}: ${title}`,
|
|
1916
|
+
onClick: () => {
|
|
1917
|
+
setOpen(!open);
|
|
1918
|
+
},
|
|
1743
1919
|
children: [
|
|
1744
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
1745
|
-
className: "dsm-
|
|
1746
|
-
|
|
1747
|
-
"
|
|
1748
|
-
children: TRAE_REGIONS.map((item) => {
|
|
1749
|
-
const regionStatus = statusByRegion[item];
|
|
1750
|
-
const on = regionOn(item);
|
|
1751
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1752
|
-
className: "dsm-trae-tab-cell",
|
|
1753
|
-
role: "presentation",
|
|
1754
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1755
|
-
type: "button",
|
|
1756
|
-
role: "tab",
|
|
1757
|
-
"aria-selected": item === activeRegion,
|
|
1758
|
-
className: `dsm-trae-tab${item === activeRegion ? " dsm-trae-tab-active" : ""}${on ? "" : " dsm-trae-tab-off"}`,
|
|
1759
|
-
onClick: () => {
|
|
1760
|
-
setActiveRegion(item);
|
|
1761
|
-
},
|
|
1762
|
-
children: [regionStatus === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1763
|
-
"aria-hidden": "true",
|
|
1764
|
-
className: "dsm-trae-tab-dot",
|
|
1765
|
-
style: dotStyle(regionStatus.status)
|
|
1766
|
-
}), item === "cn" ? t("row.tabCn") : t("row.tabAi")]
|
|
1767
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1768
|
-
className: "dsm-trae-switch dsm-trae-tab-switch",
|
|
1769
|
-
title: t("row.tabSwitchHint"),
|
|
1770
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1771
|
-
type: "checkbox",
|
|
1772
|
-
checked: on,
|
|
1773
|
-
disabled: settingsScope?.getSnapshot().writable !== true || togglingRegion !== void 0,
|
|
1774
|
-
"aria-label": t("row.tabSwitchAria", { region: item === "cn" ? t("row.tabCn") : t("row.tabAi") }),
|
|
1775
|
-
onChange: (event) => {
|
|
1776
|
-
toggleRegion(item, event.currentTarget.checked);
|
|
1777
|
-
}
|
|
1778
|
-
})
|
|
1779
|
-
})]
|
|
1780
|
-
}, item);
|
|
1781
|
-
})
|
|
1782
|
-
}),
|
|
1783
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1784
|
-
className: "dsm-trae-tab-hint",
|
|
1785
|
-
children: t("row.tabHint")
|
|
1920
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
1921
|
+
className: "dsm-plugin-card-icon",
|
|
1922
|
+
src: TRAE_PLUGIN_ICON,
|
|
1923
|
+
alt: ""
|
|
1786
1924
|
}),
|
|
1787
|
-
|
|
1788
|
-
className: "dsm-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
children: t("row.tabOffNotice")
|
|
1796
|
-
}),
|
|
1797
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1798
|
-
className: "dsm-trae-prefs",
|
|
1799
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1800
|
-
className: "dsm-trae-pref",
|
|
1801
|
-
title: t("row.followAppLoginHint"),
|
|
1802
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1803
|
-
type: "checkbox",
|
|
1804
|
-
checked: settingsEdits.followAppLogin,
|
|
1805
|
-
disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
|
|
1806
|
-
"aria-describedby": followHintId,
|
|
1807
|
-
onChange: (event) => {
|
|
1808
|
-
writePreference("followAppLogin", event.currentTarget.checked);
|
|
1809
|
-
}
|
|
1810
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1811
|
-
id: followHintId,
|
|
1812
|
-
children: [
|
|
1813
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
1814
|
-
id: followLabelId,
|
|
1815
|
-
children: t("row.followAppLogin")
|
|
1816
|
-
}),
|
|
1817
|
-
" ",
|
|
1818
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1819
|
-
className: "dsm-trae-pref-hint",
|
|
1820
|
-
children: t("row.followAppLoginHint")
|
|
1821
|
-
})
|
|
1822
|
-
]
|
|
1823
|
-
})]
|
|
1824
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
1825
|
-
className: "dsm-trae-pref",
|
|
1826
|
-
title: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi"),
|
|
1827
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1828
|
-
type: "checkbox",
|
|
1829
|
-
checked: settingsEdits.showPointsInMainUi,
|
|
1830
|
-
disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
|
|
1831
|
-
"aria-describedby": creditsHintId,
|
|
1832
|
-
onChange: (event) => {
|
|
1833
|
-
writePreference("showPointsInMainUi", event.currentTarget.checked);
|
|
1834
|
-
}
|
|
1835
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1836
|
-
id: creditsHintId,
|
|
1837
|
-
children: [
|
|
1838
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
1839
|
-
id: creditsLabelId,
|
|
1840
|
-
children: t("row.showPointsInMainUi")
|
|
1841
|
-
}),
|
|
1842
|
-
" ",
|
|
1843
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1844
|
-
className: "dsm-trae-pref-hint",
|
|
1845
|
-
children: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi")
|
|
1846
|
-
})
|
|
1847
|
-
]
|
|
1848
|
-
})]
|
|
1925
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1926
|
+
className: "dsm-plugin-card-head",
|
|
1927
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1928
|
+
className: "dsm-plugin-card-title",
|
|
1929
|
+
children: title
|
|
1930
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1931
|
+
className: "dsm-plugin-card-description",
|
|
1932
|
+
children: t("row.desc")
|
|
1849
1933
|
})]
|
|
1850
1934
|
}),
|
|
1851
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1852
|
-
|
|
1853
|
-
"
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1935
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1936
|
+
"aria-hidden": "true",
|
|
1937
|
+
className: `dsm-plugin-card-chevron${open ? " dsm-plugin-card-chevron-open" : ""}`
|
|
1938
|
+
})
|
|
1939
|
+
]
|
|
1940
|
+
}),
|
|
1941
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1942
|
+
className: "dsm-plugin-card-body",
|
|
1943
|
+
hidden: !open,
|
|
1944
|
+
children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1945
|
+
className: "dsm-trae-usage",
|
|
1946
|
+
children: [
|
|
1947
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1948
|
+
className: "dsm-trae-tabs",
|
|
1949
|
+
role: "tablist",
|
|
1950
|
+
"aria-label": title,
|
|
1951
|
+
children: TRAE_REGIONS.map((item) => {
|
|
1952
|
+
const regionStatus = statusByRegion[item];
|
|
1953
|
+
const on = regionOn(item);
|
|
1954
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1955
|
+
className: "dsm-trae-tab-cell",
|
|
1956
|
+
role: "presentation",
|
|
1957
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1958
|
+
type: "button",
|
|
1959
|
+
role: "tab",
|
|
1960
|
+
"aria-selected": item === activeRegion,
|
|
1961
|
+
className: `dsm-trae-tab${item === activeRegion ? " dsm-trae-tab-active" : ""}${on ? "" : " dsm-trae-tab-off"}`,
|
|
1962
|
+
onClick: () => {
|
|
1963
|
+
setActiveRegion(item);
|
|
1964
|
+
},
|
|
1965
|
+
children: [regionStatus === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1881
1966
|
"aria-hidden": "true",
|
|
1882
|
-
className: "dsm-trae-
|
|
1883
|
-
style: dotStyle(
|
|
1884
|
-
}),
|
|
1885
|
-
}),
|
|
1886
|
-
className: "dsm-trae-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1967
|
+
className: "dsm-trae-tab-dot",
|
|
1968
|
+
style: dotStyle(regionStatus.status)
|
|
1969
|
+
}), item === "cn" ? t("row.tabCn") : t("row.tabAi")]
|
|
1970
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
1971
|
+
className: "dsm-trae-switch dsm-trae-tab-switch",
|
|
1972
|
+
title: t("row.tabSwitchHint"),
|
|
1973
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1974
|
+
type: "checkbox",
|
|
1975
|
+
checked: on,
|
|
1976
|
+
disabled: settingsScope?.getSnapshot().writable !== true || togglingRegion !== void 0,
|
|
1977
|
+
"aria-label": t("row.tabSwitchAria", { region: item === "cn" ? t("row.tabCn") : t("row.tabAi") }),
|
|
1978
|
+
onChange: (event) => {
|
|
1979
|
+
toggleRegion(item, event.currentTarget.checked);
|
|
1980
|
+
}
|
|
1981
|
+
})
|
|
1982
|
+
})]
|
|
1983
|
+
}, item);
|
|
1984
|
+
})
|
|
1985
|
+
}),
|
|
1986
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1987
|
+
className: "dsm-trae-tab-hint",
|
|
1988
|
+
children: t("row.tabHint")
|
|
1989
|
+
}),
|
|
1990
|
+
writeError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1991
|
+
className: "dsm-trae-usage-error",
|
|
1992
|
+
role: "alert",
|
|
1993
|
+
children: t("row.settingsWriteFailed", { message: writeError })
|
|
1994
|
+
}),
|
|
1995
|
+
regionOn(activeRegion) ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1996
|
+
className: "dsm-trae-tab-off-notice",
|
|
1997
|
+
role: "status",
|
|
1998
|
+
children: t("row.tabOffNotice")
|
|
1999
|
+
}),
|
|
2000
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2001
|
+
className: "dsm-trae-prefs",
|
|
2002
|
+
children: [
|
|
2003
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2004
|
+
className: "dsm-trae-pref",
|
|
2005
|
+
title: t("row.followAppLoginHint"),
|
|
2006
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2007
|
+
type: "checkbox",
|
|
2008
|
+
checked: settingsEdits.followAppLogin,
|
|
2009
|
+
disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
|
|
2010
|
+
"aria-describedby": followHintId,
|
|
2011
|
+
onChange: (event) => {
|
|
2012
|
+
writePreference("followAppLogin", event.currentTarget.checked);
|
|
2013
|
+
}
|
|
2014
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2015
|
+
id: followHintId,
|
|
1908
2016
|
children: [
|
|
1909
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1910
|
-
|
|
1911
|
-
children:
|
|
1912
|
-
"aria-hidden": "true",
|
|
1913
|
-
className: "dsm-trae-usage-dot",
|
|
1914
|
-
style: dotStyle(account.selected ? "signed-in" : "signed-out")
|
|
1915
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1916
|
-
className: "dsm-trae-account-name",
|
|
1917
|
-
children: [
|
|
1918
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: account.accountName }),
|
|
1919
|
-
current ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1920
|
-
className: "dsm-trae-account-badge",
|
|
1921
|
-
children: t("row.accountCurrentBadge")
|
|
1922
|
-
}) : null,
|
|
1923
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1924
|
-
className: "dsm-trae-account-meta",
|
|
1925
|
-
children: [
|
|
1926
|
-
editionLabel(account.edition),
|
|
1927
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", {
|
|
1928
|
-
"aria-hidden": "true",
|
|
1929
|
-
children: "·"
|
|
1930
|
-
}),
|
|
1931
|
-
sourceLabel(account.source)
|
|
1932
|
-
]
|
|
1933
|
-
}),
|
|
1934
|
-
error === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1935
|
-
className: "dsm-trae-account-note",
|
|
1936
|
-
role: "alert",
|
|
1937
|
-
children: t("row.checkinError", { message: error })
|
|
1938
|
-
})
|
|
1939
|
-
]
|
|
1940
|
-
})]
|
|
2017
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
2018
|
+
id: followLabelId,
|
|
2019
|
+
children: t("row.followAppLogin")
|
|
1941
2020
|
}),
|
|
2021
|
+
" ",
|
|
1942
2022
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1943
|
-
className: "dsm-trae-
|
|
1944
|
-
children:
|
|
2023
|
+
className: "dsm-trae-pref-hint",
|
|
2024
|
+
children: t("row.followAppLoginHint")
|
|
2025
|
+
})
|
|
2026
|
+
]
|
|
2027
|
+
})]
|
|
2028
|
+
}),
|
|
2029
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2030
|
+
className: "dsm-trae-pref",
|
|
2031
|
+
title: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi"),
|
|
2032
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2033
|
+
type: "checkbox",
|
|
2034
|
+
checked: settingsEdits.showPointsInMainUi,
|
|
2035
|
+
disabled: settingsScope?.getSnapshot().writable !== true || savingSettings,
|
|
2036
|
+
"aria-describedby": creditsHintId,
|
|
2037
|
+
onChange: (event) => {
|
|
2038
|
+
writePreference("showPointsInMainUi", event.currentTarget.checked);
|
|
2039
|
+
}
|
|
2040
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2041
|
+
id: creditsHintId,
|
|
2042
|
+
children: [
|
|
2043
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", {
|
|
2044
|
+
id: creditsLabelId,
|
|
2045
|
+
children: t("row.showPointsInMainUi")
|
|
1945
2046
|
}),
|
|
1946
|
-
|
|
1947
|
-
className: "dsm-trae-account-checkin-cell",
|
|
1948
|
-
children: checkinControl(account, state)
|
|
1949
|
-
}) : null,
|
|
2047
|
+
" ",
|
|
1950
2048
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1951
|
-
className: "dsm-trae-
|
|
1952
|
-
children:
|
|
1953
|
-
type: "button",
|
|
1954
|
-
className: "dsm-btn dsm-btn-outline dsm-trae-account-switch",
|
|
1955
|
-
disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
|
|
1956
|
-
onClick: () => {
|
|
1957
|
-
switchAccount(account.id);
|
|
1958
|
-
},
|
|
1959
|
-
children: switchingAccount ? t("row.accountSwitching") : t("row.accountSwitch")
|
|
1960
|
-
})
|
|
2049
|
+
className: "dsm-trae-pref-hint",
|
|
2050
|
+
children: t(activeRegion === "cn" ? "row.showPointsInMainUiHint" : "row.showPointsInMainUiHintAi")
|
|
1961
2051
|
})
|
|
1962
2052
|
]
|
|
1963
|
-
}
|
|
1964
|
-
})
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
t("row.
|
|
2053
|
+
})]
|
|
2054
|
+
}),
|
|
2055
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2056
|
+
className: "dsm-trae-pref dsm-trae-credit-position-pref",
|
|
2057
|
+
title: t("row.creditPositionHint"),
|
|
2058
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2059
|
+
className: "dsm-trae-credit-position",
|
|
2060
|
+
value: activeRegionOn ? creditPositionOn(activeRegion) : "composer",
|
|
2061
|
+
disabled: !activeRegionOn || settingsScope?.getSnapshot().writable !== true || savingSettings,
|
|
2062
|
+
"aria-label": t("row.creditPositionAria", { region: activeRegion === "cn" ? t("row.tabCn") : t("row.tabAi") }),
|
|
2063
|
+
onChange: (event) => {
|
|
2064
|
+
changeCreditPosition(activeRegion, event.currentTarget.value === "stats" ? "stats" : "composer");
|
|
2065
|
+
},
|
|
2066
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2067
|
+
value: "composer",
|
|
2068
|
+
children: t("row.creditPositionComposer")
|
|
2069
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2070
|
+
value: "stats",
|
|
2071
|
+
children: t("row.creditPositionStats")
|
|
2072
|
+
})]
|
|
2073
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
2074
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: t("row.creditPositionLabel") }),
|
|
1973
2075
|
" ",
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
const target = status.alternatives?.[0];
|
|
1982
|
-
if (target !== void 0) switchAccount(target.id);
|
|
1983
|
-
},
|
|
1984
|
-
children: t("row.creditsAlternativeSwitch")
|
|
1985
|
-
})]
|
|
1986
|
-
}) : null,
|
|
1987
|
-
status.status === "signed-in" && status.credits?.expiry !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpiryNotice, {
|
|
1988
|
-
expiry: status.credits.expiry,
|
|
1989
|
-
t,
|
|
1990
|
-
formatNumber,
|
|
1991
|
-
formatDateTime
|
|
1992
|
-
}) : null,
|
|
1993
|
-
status.status === "signed-in" && status.appLogin !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1994
|
-
className: "dsm-trae-usage-alternative",
|
|
1995
|
-
role: "status",
|
|
1996
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1997
|
-
className: "dsm-trae-usage-alternative-text",
|
|
1998
|
-
children: t("row.appLoginMismatch", {
|
|
1999
|
-
account: status.appLogin.accountName,
|
|
2000
|
-
bound: status.accountName
|
|
2001
|
-
})
|
|
2002
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2003
|
-
type: "button",
|
|
2004
|
-
className: "dsm-trae-usage-switch-button",
|
|
2005
|
-
disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
|
|
2006
|
-
onClick: () => {
|
|
2007
|
-
followAppLogin();
|
|
2008
|
-
},
|
|
2009
|
-
children: t("row.appLoginFollow", { account: status.appLogin.accountName })
|
|
2010
|
-
})]
|
|
2011
|
-
}) : null,
|
|
2012
|
-
rescanNote === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2013
|
-
className: "dsm-trae-usage-note",
|
|
2014
|
-
role: "status",
|
|
2015
|
-
children: rescanNote
|
|
2016
|
-
})
|
|
2017
|
-
]
|
|
2018
|
-
}),
|
|
2019
|
-
status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2020
|
-
status.checkin !== void 0 && !status.checkin.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2021
|
-
className: "dsm-trae-usage-error",
|
|
2022
|
-
children: t("row.checkinDisabled")
|
|
2023
|
-
}) : null,
|
|
2024
|
-
status.checkinError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2025
|
-
className: "dsm-trae-usage-error",
|
|
2026
|
-
children: t("row.checkinError", { message: status.checkinError })
|
|
2076
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2077
|
+
className: "dsm-trae-pref-hint",
|
|
2078
|
+
children: t("row.creditPositionHint")
|
|
2079
|
+
})
|
|
2080
|
+
] })]
|
|
2081
|
+
})
|
|
2082
|
+
]
|
|
2027
2083
|
}),
|
|
2028
2084
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2029
|
-
className: "dsm-trae-
|
|
2030
|
-
"aria-label": t("row.
|
|
2085
|
+
className: "dsm-trae-accounts",
|
|
2086
|
+
"aria-label": t("row.accountsTitle"),
|
|
2031
2087
|
children: [
|
|
2032
2088
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2033
|
-
className: "dsm-trae-
|
|
2089
|
+
className: "dsm-trae-accounts-head",
|
|
2034
2090
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2035
|
-
className: "dsm-trae-
|
|
2036
|
-
children: t("row.
|
|
2091
|
+
className: "dsm-trae-accounts-title",
|
|
2092
|
+
children: t("row.accountsTitle")
|
|
2037
2093
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2038
|
-
className: "dsm-trae-
|
|
2039
|
-
children: t("row.
|
|
2040
|
-
})] }), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
refreshModels();
|
|
2049
|
-
},
|
|
2050
|
-
children: busy ? t("row.modelsRefreshing") : t("row.modelsRefresh")
|
|
2051
|
-
}),
|
|
2052
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2053
|
-
type: "button",
|
|
2054
|
-
className: "dsm-btn dsm-btn-outline",
|
|
2055
|
-
disabled: busy || testing !== void 0 || activeEnabledIds.size === 0,
|
|
2056
|
-
title: t("row.modelsTestHint"),
|
|
2057
|
-
onClick: () => {
|
|
2058
|
-
testEnabledModels();
|
|
2059
|
-
},
|
|
2060
|
-
children: testing === void 0 ? t("row.modelsTestEnabled") : t("row.modelsTesting", {
|
|
2061
|
-
done: testing.done,
|
|
2062
|
-
total: testing.total
|
|
2063
|
-
})
|
|
2064
|
-
}),
|
|
2065
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2066
|
-
type: "button",
|
|
2067
|
-
className: "dsm-btn dsm-btn-outline",
|
|
2068
|
-
disabled: busy || testing !== void 0 || visibleModels.length === 0,
|
|
2069
|
-
title: t("row.modelsTestAllHint"),
|
|
2070
|
-
onClick: () => {
|
|
2071
|
-
testAllModels();
|
|
2072
|
-
},
|
|
2073
|
-
children: testing === void 0 ? t("row.modelsTestAll") : t("row.modelsTesting", {
|
|
2074
|
-
done: testing.done,
|
|
2075
|
-
total: testing.total
|
|
2076
|
-
})
|
|
2077
|
-
})
|
|
2078
|
-
]
|
|
2094
|
+
className: "dsm-trae-accounts-hint",
|
|
2095
|
+
children: t("row.accountsHint")
|
|
2096
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2097
|
+
type: "button",
|
|
2098
|
+
className: "dsm-btn dsm-btn-outline",
|
|
2099
|
+
disabled: busy,
|
|
2100
|
+
onClick: () => {
|
|
2101
|
+
rescanAccounts();
|
|
2102
|
+
},
|
|
2103
|
+
children: busy ? t("row.accountsScanning") : t("row.refreshTokens")
|
|
2079
2104
|
})]
|
|
2080
2105
|
}),
|
|
2081
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
2082
|
-
className: "dsm-trae-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
className: "dsm-trae-models-summary",
|
|
2087
|
-
children: testSummary
|
|
2088
|
-
}),
|
|
2089
|
-
testError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2090
|
-
className: "dsm-trae-usage-error",
|
|
2091
|
-
role: "alert",
|
|
2092
|
-
children: testError
|
|
2093
|
-
}),
|
|
2094
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2095
|
-
className: "dsm-trae-model-list",
|
|
2096
|
-
children: visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2097
|
-
className: `dsm-trae-model${activeEnabledIds.has(model.id) ? "" : " dsm-trae-model-disabled"}`,
|
|
2106
|
+
status.status !== "signed-in" || status.accounts.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2107
|
+
className: "dsm-trae-usage-account",
|
|
2108
|
+
role: "status",
|
|
2109
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2110
|
+
className: "dsm-trae-usage-account-copy",
|
|
2098
2111
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2099
|
-
className: "dsm-trae-
|
|
2100
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2112
|
+
className: "dsm-trae-usage-status",
|
|
2113
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2114
|
+
"aria-hidden": "true",
|
|
2115
|
+
className: "dsm-trae-usage-dot",
|
|
2116
|
+
style: dotStyle(status.status)
|
|
2117
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
2118
|
+
}), status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2119
|
+
className: "dsm-trae-usage-expiry",
|
|
2120
|
+
children: t("row.tokenExpiry", { expiresAt: formatDateTime(status.tokenExpiresAtMs) })
|
|
2121
|
+
}) : null]
|
|
2122
|
+
})
|
|
2123
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2124
|
+
className: `dsm-trae-account-table${activeRegion === "cn" ? " dsm-trae-account-table-checkin" : ""}`,
|
|
2125
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2126
|
+
className: "dsm-trae-account-row dsm-trae-account-row-head",
|
|
2127
|
+
role: "row",
|
|
2128
|
+
children: [
|
|
2129
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnAccount") }),
|
|
2130
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnValue") }),
|
|
2131
|
+
activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.accountColumnCheckin") }) : null,
|
|
2132
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {})
|
|
2133
|
+
]
|
|
2134
|
+
}), status.accounts.map((account) => {
|
|
2135
|
+
const current = status.status === "signed-in" && account.id === status.accountId;
|
|
2136
|
+
const state = accountStatusByRegion[activeRegion][account.id];
|
|
2137
|
+
const error = claimErrorByRegion[activeRegion][account.id];
|
|
2138
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2139
|
+
className: `dsm-trae-account-row${current ? " dsm-trae-account-row-current" : ""}`,
|
|
2140
|
+
role: "row",
|
|
2141
|
+
children: [
|
|
2142
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2143
|
+
className: "dsm-trae-account-who",
|
|
2144
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2145
|
+
"aria-hidden": "true",
|
|
2146
|
+
className: "dsm-trae-usage-dot",
|
|
2147
|
+
style: dotStyle(account.selected ? "signed-in" : "signed-out")
|
|
2148
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2149
|
+
className: "dsm-trae-account-name",
|
|
2113
2150
|
children: [
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
className: "dsm-trae-
|
|
2117
|
-
children:
|
|
2151
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: account.accountName }),
|
|
2152
|
+
current ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2153
|
+
className: "dsm-trae-account-badge",
|
|
2154
|
+
children: t("row.accountCurrentBadge")
|
|
2155
|
+
}) : null,
|
|
2156
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2157
|
+
className: "dsm-trae-account-meta",
|
|
2158
|
+
children: [
|
|
2159
|
+
editionLabel(account.edition),
|
|
2160
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", {
|
|
2161
|
+
"aria-hidden": "true",
|
|
2162
|
+
children: "·"
|
|
2163
|
+
}),
|
|
2164
|
+
sourceLabel(account.source)
|
|
2165
|
+
]
|
|
2118
2166
|
}),
|
|
2119
|
-
|
|
2167
|
+
error === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2168
|
+
className: "dsm-trae-account-note",
|
|
2169
|
+
role: "alert",
|
|
2170
|
+
children: t("row.checkinError", { message: error })
|
|
2171
|
+
})
|
|
2120
2172
|
]
|
|
2173
|
+
})]
|
|
2174
|
+
}),
|
|
2175
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2176
|
+
className: "dsm-trae-account-worth",
|
|
2177
|
+
children: rowValue(state)
|
|
2178
|
+
}),
|
|
2179
|
+
activeRegion === "cn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2180
|
+
className: "dsm-trae-account-checkin-cell",
|
|
2181
|
+
children: checkinControl(account, state)
|
|
2182
|
+
}) : null,
|
|
2183
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2184
|
+
className: "dsm-trae-account-actions",
|
|
2185
|
+
children: current ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2186
|
+
type: "button",
|
|
2187
|
+
className: "dsm-btn dsm-btn-outline dsm-trae-account-switch",
|
|
2188
|
+
disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
|
|
2189
|
+
onClick: () => {
|
|
2190
|
+
switchAccount(account.id);
|
|
2191
|
+
},
|
|
2192
|
+
children: switchingAccount ? t("row.accountSwitching") : t("row.accountSwitch")
|
|
2121
2193
|
})
|
|
2122
|
-
})
|
|
2123
|
-
|
|
2124
|
-
|
|
2194
|
+
})
|
|
2195
|
+
]
|
|
2196
|
+
}, account.id);
|
|
2197
|
+
})]
|
|
2198
|
+
}),
|
|
2199
|
+
status.status === "signed-in" && status.alternatives !== void 0 && status.alternatives.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2200
|
+
className: "dsm-trae-usage-alternative",
|
|
2201
|
+
role: "status",
|
|
2202
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
2203
|
+
className: "dsm-trae-usage-alternative-text",
|
|
2204
|
+
children: [
|
|
2205
|
+
t("row.creditsExhausted", { account: status.accountName }),
|
|
2206
|
+
" ",
|
|
2207
|
+
t("row.creditsAlternative", { accounts: status.alternatives.map((alt) => `${alt.accountName}(${t(`row.edition${alt.edition === "cn" ? "Cn" : alt.edition === "sg" ? "Sg" : alt.edition === "solo" ? "Solo" : "SoloSg"}`)}:${formatNumber(alt.workAvailable + alt.generalAvailable)})`).join("、") })
|
|
2208
|
+
]
|
|
2209
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2210
|
+
type: "button",
|
|
2211
|
+
className: "dsm-trae-usage-switch-button",
|
|
2212
|
+
disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
|
|
2213
|
+
onClick: () => {
|
|
2214
|
+
const target = status.alternatives?.[0];
|
|
2215
|
+
if (target !== void 0) switchAccount(target.id);
|
|
2216
|
+
},
|
|
2217
|
+
children: t("row.creditsAlternativeSwitch")
|
|
2218
|
+
})]
|
|
2219
|
+
}) : null,
|
|
2220
|
+
status.status === "signed-in" && status.credits?.expiry !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ExpiryNotice, {
|
|
2221
|
+
expiry: status.credits.expiry,
|
|
2222
|
+
t,
|
|
2223
|
+
formatNumber,
|
|
2224
|
+
formatDateTime
|
|
2225
|
+
}) : null,
|
|
2226
|
+
status.status === "signed-in" && status.appLogin !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2227
|
+
className: "dsm-trae-usage-alternative",
|
|
2228
|
+
role: "status",
|
|
2229
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2230
|
+
className: "dsm-trae-usage-alternative-text",
|
|
2231
|
+
children: t("row.appLoginMismatch", {
|
|
2232
|
+
account: status.appLogin.accountName,
|
|
2233
|
+
bound: status.accountName
|
|
2234
|
+
})
|
|
2235
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2236
|
+
type: "button",
|
|
2237
|
+
className: "dsm-trae-usage-switch-button",
|
|
2238
|
+
disabled: switchingAccount || settingsScope?.getSnapshot()?.writable !== true,
|
|
2239
|
+
onClick: () => {
|
|
2240
|
+
followAppLogin();
|
|
2241
|
+
},
|
|
2242
|
+
children: t("row.appLoginFollow", { account: status.appLogin.accountName })
|
|
2243
|
+
})]
|
|
2244
|
+
}) : null,
|
|
2245
|
+
rescanNote === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2246
|
+
className: "dsm-trae-usage-note",
|
|
2247
|
+
role: "status",
|
|
2248
|
+
children: rescanNote
|
|
2249
|
+
})
|
|
2250
|
+
]
|
|
2251
|
+
}),
|
|
2252
|
+
status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2253
|
+
status.checkin !== void 0 && !status.checkin.enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2254
|
+
className: "dsm-trae-usage-error",
|
|
2255
|
+
children: t("row.checkinDisabled")
|
|
2256
|
+
}) : null,
|
|
2257
|
+
status.checkinError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2258
|
+
className: "dsm-trae-usage-error",
|
|
2259
|
+
children: t("row.checkinError", { message: status.checkinError })
|
|
2260
|
+
}),
|
|
2261
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2262
|
+
className: "dsm-trae-models",
|
|
2263
|
+
"aria-label": t("row.modelsTitle"),
|
|
2264
|
+
children: [
|
|
2265
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2266
|
+
className: "dsm-trae-models-head",
|
|
2267
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2268
|
+
className: "dsm-trae-models-title",
|
|
2269
|
+
children: t("row.modelsTitle")
|
|
2270
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2271
|
+
className: "dsm-trae-models-summary",
|
|
2272
|
+
children: t("row.modelsSummary", { count: activeEnabledIds.size })
|
|
2273
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2274
|
+
className: "dsm-trae-models-actions",
|
|
2275
|
+
children: [
|
|
2276
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2277
|
+
type: "button",
|
|
2278
|
+
className: "dsm-btn dsm-btn-outline",
|
|
2279
|
+
disabled: busy,
|
|
2280
|
+
onClick: () => {
|
|
2281
|
+
refreshModels();
|
|
2282
|
+
},
|
|
2283
|
+
children: busy ? t("row.modelsRefreshing") : t("row.modelsRefresh")
|
|
2284
|
+
}),
|
|
2285
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2286
|
+
type: "button",
|
|
2287
|
+
className: "dsm-btn dsm-btn-outline",
|
|
2288
|
+
disabled: busy || testing !== void 0 || activeEnabledIds.size === 0,
|
|
2289
|
+
title: t("row.modelsTestHint"),
|
|
2290
|
+
onClick: () => {
|
|
2291
|
+
testEnabledModels();
|
|
2292
|
+
},
|
|
2293
|
+
children: testing === void 0 ? t("row.modelsTestEnabled") : t("row.modelsTesting", {
|
|
2294
|
+
done: testing.done,
|
|
2295
|
+
total: testing.total
|
|
2296
|
+
})
|
|
2297
|
+
}),
|
|
2298
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2299
|
+
type: "button",
|
|
2300
|
+
className: "dsm-btn dsm-btn-outline",
|
|
2301
|
+
disabled: busy || testing !== void 0 || visibleModels.length === 0,
|
|
2302
|
+
title: t("row.modelsTestAllHint"),
|
|
2303
|
+
onClick: () => {
|
|
2304
|
+
testAllModels();
|
|
2305
|
+
},
|
|
2306
|
+
children: testing === void 0 ? t("row.modelsTestAll") : t("row.modelsTesting", {
|
|
2307
|
+
done: testing.done,
|
|
2308
|
+
total: testing.total
|
|
2309
|
+
})
|
|
2310
|
+
})
|
|
2311
|
+
]
|
|
2312
|
+
})]
|
|
2313
|
+
}),
|
|
2314
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2315
|
+
className: "dsm-trae-models-hint",
|
|
2316
|
+
children: t("row.modelsTestHint")
|
|
2317
|
+
}),
|
|
2318
|
+
testSummary === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2319
|
+
className: "dsm-trae-models-summary",
|
|
2320
|
+
children: testSummary
|
|
2321
|
+
}),
|
|
2322
|
+
testError === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2323
|
+
className: "dsm-trae-usage-error",
|
|
2324
|
+
role: "alert",
|
|
2325
|
+
children: testError
|
|
2326
|
+
}),
|
|
2327
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2328
|
+
className: "dsm-trae-model-list",
|
|
2329
|
+
children: visibleModels.map((model) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2330
|
+
className: `dsm-trae-model${activeEnabledIds.has(model.id) ? "" : " dsm-trae-model-disabled"}`,
|
|
2331
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2332
|
+
className: "dsm-trae-model-head",
|
|
2125
2333
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2126
|
-
className: "dsm-trae-model-
|
|
2334
|
+
className: "dsm-trae-model-enabled",
|
|
2127
2335
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2128
2336
|
type: "checkbox",
|
|
2129
|
-
checked:
|
|
2130
|
-
disabled: rowImageIsAutomatic(model) || settingsScope?.getSnapshot().writable !== true || saving,
|
|
2131
|
-
title: rowImageIsAutomatic(model) ? t("row.modelImageAuto") : void 0,
|
|
2132
|
-
onChange: () => {
|
|
2133
|
-
toggleImage(model.id);
|
|
2134
|
-
}
|
|
2135
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelImage") })]
|
|
2136
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
|
|
2137
|
-
className: "dsm-trae-context-budget",
|
|
2138
|
-
"aria-label": t("row.contextBudget"),
|
|
2139
|
-
children: [model.maxContextWindow !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2140
|
-
type: "radio",
|
|
2141
|
-
name: `context-${model.id}`,
|
|
2142
|
-
checked: activeContextBudgets[model.id] !== model.maxContextWindow,
|
|
2337
|
+
checked: activeEnabledIds.has(model.id),
|
|
2143
2338
|
disabled: settingsScope?.getSnapshot().writable !== true || saving,
|
|
2144
2339
|
onChange: () => {
|
|
2145
|
-
|
|
2146
|
-
}
|
|
2147
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.contextWindow, t("row.modelUnknown")) })] }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2148
|
-
type: "radio",
|
|
2149
|
-
name: `context-${model.id}`,
|
|
2150
|
-
checked: model.maxContextWindow === void 0 || activeContextBudgets[model.id] === model.maxContextWindow,
|
|
2151
|
-
disabled: model.maxContextWindow === void 0 || settingsScope?.getSnapshot().writable !== true || saving,
|
|
2152
|
-
onChange: () => {
|
|
2153
|
-
setContextBudget(model.id, model.maxContextWindow);
|
|
2340
|
+
toggleModel(model.id);
|
|
2154
2341
|
}
|
|
2155
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2342
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2343
|
+
className: "dsm-trae-model-copy",
|
|
2344
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2345
|
+
className: "dsm-trae-model-name",
|
|
2346
|
+
children: [
|
|
2347
|
+
model.name,
|
|
2348
|
+
model.creditMultiplier === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2349
|
+
className: "dsm-trae-model-name-rate",
|
|
2350
|
+
children: ["· x", model.creditMultiplier.toFixed(2)]
|
|
2351
|
+
}),
|
|
2352
|
+
probeBadge(probeByRegion[activeRegion][model.id], t)
|
|
2353
|
+
]
|
|
2354
|
+
})
|
|
2355
|
+
})]
|
|
2356
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2357
|
+
className: "dsm-trae-model-options",
|
|
2358
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2359
|
+
className: "dsm-trae-model-image",
|
|
2360
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2361
|
+
type: "checkbox",
|
|
2362
|
+
checked: rowAcceptsImage(model),
|
|
2363
|
+
disabled: rowImageIsAutomatic(model) || settingsScope?.getSnapshot().writable !== true || saving,
|
|
2364
|
+
title: rowImageIsAutomatic(model) ? t("row.modelImageAuto") : void 0,
|
|
2365
|
+
onChange: () => {
|
|
2366
|
+
toggleImage(model.id);
|
|
2367
|
+
}
|
|
2368
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelImage") })]
|
|
2369
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("fieldset", {
|
|
2370
|
+
className: "dsm-trae-context-budget",
|
|
2371
|
+
"aria-label": t("row.contextBudget"),
|
|
2372
|
+
children: [model.maxContextWindow !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2373
|
+
type: "radio",
|
|
2374
|
+
name: `context-${model.id}`,
|
|
2375
|
+
checked: activeContextBudgets[model.id] !== model.maxContextWindow,
|
|
2376
|
+
disabled: settingsScope?.getSnapshot().writable !== true || saving,
|
|
2377
|
+
onChange: () => {
|
|
2378
|
+
setContextBudget(model.id, model.contextWindow);
|
|
2379
|
+
}
|
|
2380
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.contextWindow, t("row.modelUnknown")) })] }) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
2381
|
+
type: "radio",
|
|
2382
|
+
name: `context-${model.id}`,
|
|
2383
|
+
checked: model.maxContextWindow === void 0 || activeContextBudgets[model.id] === model.maxContextWindow,
|
|
2384
|
+
disabled: model.maxContextWindow === void 0 || settingsScope?.getSnapshot().writable !== true || saving,
|
|
2385
|
+
onChange: () => {
|
|
2386
|
+
setContextBudget(model.id, model.maxContextWindow);
|
|
2387
|
+
}
|
|
2388
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) })] })]
|
|
2389
|
+
})]
|
|
2156
2390
|
})]
|
|
2391
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2392
|
+
className: "dsm-trae-model-meta",
|
|
2393
|
+
children: [
|
|
2394
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelContext", { context: formatCapacity(model.maxContextWindow ?? model.contextWindow, t("row.modelUnknown")) }) }),
|
|
2395
|
+
model.maxTokens === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelOutput", { output: formatCapacity(model.maxTokens, t("row.modelUnknown")) }) }),
|
|
2396
|
+
model.reasoning === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("row.modelReasoning", { efforts: model.reasoning.supported.join(" / ") }) })
|
|
2397
|
+
]
|
|
2398
|
+
})]
|
|
2399
|
+
}, model.id))
|
|
2400
|
+
}),
|
|
2401
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2402
|
+
className: "dsm-trae-model-capability-note",
|
|
2403
|
+
children: t("row.modelCapabilityPending")
|
|
2404
|
+
}),
|
|
2405
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2406
|
+
className: "dsm-trae-model-actions",
|
|
2407
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("a", {
|
|
2408
|
+
className: "dsm-trae-usage-cheer",
|
|
2409
|
+
href: TRAE_GITHUB_URL,
|
|
2410
|
+
target: "_blank",
|
|
2411
|
+
rel: "noopener noreferrer",
|
|
2412
|
+
children: [t("row.cheer"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2413
|
+
className: "dsm-trae-usage-cheer-star",
|
|
2414
|
+
"aria-hidden": "true",
|
|
2415
|
+
children: "★"
|
|
2157
2416
|
})]
|
|
2158
2417
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2159
|
-
className: "dsm-trae-model-
|
|
2160
|
-
children: [
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2418
|
+
className: "dsm-trae-model-actions-buttons",
|
|
2419
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2420
|
+
type: "button",
|
|
2421
|
+
className: "dsm-btn dsm-btn-outline",
|
|
2422
|
+
disabled: !dirty || saving,
|
|
2423
|
+
onClick: discardModels,
|
|
2424
|
+
children: t("row.discard")
|
|
2425
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2426
|
+
type: "button",
|
|
2427
|
+
className: "dsm-btn dsm-btn-primary",
|
|
2428
|
+
disabled: !dirty || saving || activeEnabledIds.size === 0,
|
|
2429
|
+
onClick: () => {
|
|
2430
|
+
saveModels();
|
|
2431
|
+
},
|
|
2432
|
+
children: saving ? t("row.saving") : t("row.save")
|
|
2433
|
+
})]
|
|
2165
2434
|
})]
|
|
2166
|
-
}
|
|
2167
|
-
|
|
2435
|
+
})
|
|
2436
|
+
]
|
|
2437
|
+
})
|
|
2438
|
+
] }) : null,
|
|
2439
|
+
status.status === "signed-out" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2440
|
+
className: "dsm-trae-usage-text",
|
|
2441
|
+
children: status.message ?? t("row.signedOutHint")
|
|
2442
|
+
}), status.searched && status.searched.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2443
|
+
className: "dsm-trae-searched",
|
|
2444
|
+
children: [
|
|
2445
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("summary", { children: [
|
|
2446
|
+
t("row.searchedTitle"),
|
|
2447
|
+
" (",
|
|
2448
|
+
status.searched.length,
|
|
2449
|
+
")"
|
|
2450
|
+
] }),
|
|
2168
2451
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2169
|
-
className: "dsm-trae-
|
|
2170
|
-
children: t("row.
|
|
2452
|
+
className: "dsm-trae-searched-hint",
|
|
2453
|
+
children: t("row.searchedHint")
|
|
2171
2454
|
}),
|
|
2172
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
2173
|
-
className: "dsm-trae-
|
|
2174
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("
|
|
2175
|
-
className: "dsm-trae-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
children: "★"
|
|
2183
|
-
})]
|
|
2184
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2185
|
-
className: "dsm-trae-model-actions-buttons",
|
|
2186
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2187
|
-
type: "button",
|
|
2188
|
-
className: "dsm-btn dsm-btn-outline",
|
|
2189
|
-
disabled: !dirty || saving,
|
|
2190
|
-
onClick: discardModels,
|
|
2191
|
-
children: t("row.discard")
|
|
2192
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2193
|
-
type: "button",
|
|
2194
|
-
className: "dsm-btn dsm-btn-primary",
|
|
2195
|
-
disabled: !dirty || saving || activeEnabledIds.size === 0,
|
|
2196
|
-
onClick: () => {
|
|
2197
|
-
saveModels();
|
|
2198
|
-
},
|
|
2199
|
-
children: saving ? t("row.saving") : t("row.save")
|
|
2200
|
-
})]
|
|
2201
|
-
})]
|
|
2455
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
2456
|
+
className: "dsm-trae-searched-list",
|
|
2457
|
+
children: status.searched.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: item.path }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2458
|
+
className: "dsm-trae-searched-reason",
|
|
2459
|
+
children: [
|
|
2460
|
+
t(item.source === "cli" ? "row.sourceCli" : "row.sourceDesktop"),
|
|
2461
|
+
" · ",
|
|
2462
|
+
t(item.reason === "missing" ? "row.reasonMissing" : item.reason === "unreadable" ? "row.reasonUnreadable" : "row.reasonInvalid")
|
|
2463
|
+
]
|
|
2464
|
+
})] }, `${item.source}:${item.path}`))
|
|
2202
2465
|
})
|
|
2203
2466
|
]
|
|
2204
|
-
})
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
] }),
|
|
2218
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2219
|
-
className: "dsm-trae-searched-hint",
|
|
2220
|
-
children: t("row.searchedHint")
|
|
2221
|
-
}),
|
|
2222
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
2223
|
-
className: "dsm-trae-searched-list",
|
|
2224
|
-
children: status.searched.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", { children: item.path }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2225
|
-
className: "dsm-trae-searched-reason",
|
|
2226
|
-
children: [
|
|
2227
|
-
t(item.source === "cli" ? "row.sourceCli" : "row.sourceDesktop"),
|
|
2228
|
-
" · ",
|
|
2229
|
-
t(item.reason === "missing" ? "row.reasonMissing" : item.reason === "unreadable" ? "row.reasonUnreadable" : "row.reasonInvalid")
|
|
2230
|
-
]
|
|
2231
|
-
})] }, `${item.source}:${item.path}`))
|
|
2232
|
-
})
|
|
2233
|
-
]
|
|
2234
|
-
}) : null] }) : null,
|
|
2235
|
-
status.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2236
|
-
className: "dsm-trae-usage-error",
|
|
2237
|
-
children: status.message
|
|
2238
|
-
}) : null
|
|
2239
|
-
]
|
|
2240
|
-
}) : null
|
|
2241
|
-
})]
|
|
2467
|
+
}) : null] }) : null,
|
|
2468
|
+
status.status === "error" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2469
|
+
className: "dsm-trae-usage-error",
|
|
2470
|
+
children: status.message
|
|
2471
|
+
}) : null
|
|
2472
|
+
]
|
|
2473
|
+
}) : null
|
|
2474
|
+
}),
|
|
2475
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(BusyOverlay, {
|
|
2476
|
+
visible: saving || savingSettings,
|
|
2477
|
+
message: t("row.veilSaving")
|
|
2478
|
+
})
|
|
2479
|
+
]
|
|
2242
2480
|
});
|
|
2243
2481
|
}
|
|
2244
2482
|
//#endregion
|
|
@@ -2853,6 +3091,23 @@ window.__ModuleLoader__.load({
|
|
|
2853
3091
|
* row is shared with the shell's own permission/agent/model controls, so the
|
|
2854
3092
|
* readout must be asked for, not imposed — 2.13.0 rendered it unconditionally
|
|
2855
3093
|
* and 2.13.3 restored the opt-in after the user went looking for the switch.
|
|
3094
|
+
*
|
|
3095
|
+
* WHY THERE IS A SECOND SEAT (learned from dsh-connect-workbuddy issue #62).
|
|
3096
|
+
* That row is a LIST seat, so it is shared not only with the shell's own
|
|
3097
|
+
* controls but with any other plugin that registers there — and one report is
|
|
3098
|
+
* exactly that: with a third-party plugin installed the readout stopped
|
|
3099
|
+
* appearing. A list seat cannot promise that every occupant is visible, so the
|
|
3100
|
+
* seat becomes the USER's choice: `composer` (default, unchanged for anyone who
|
|
3101
|
+
* does not choose) or `stats`, the ambient dock below the composer card where
|
|
3102
|
+
* the shell renders its own round/step/token pills. This plugin has already
|
|
3103
|
+
* lost this readout once to a shared seat — it used to live at the sidebar
|
|
3104
|
+
* foot, where it was clipped to "Tr" beside dsh-connect-workbuddy's rows.
|
|
3105
|
+
*
|
|
3106
|
+
* The gate is registered in BOTH seats and renders in the one the setting
|
|
3107
|
+
* names, which keeps the decision in ONE function instead of re-registering
|
|
3108
|
+
* slots when the setting changes — and this repository already documents that
|
|
3109
|
+
* kind of binding as fragile (the rc.6→rc.7 `id`/`order` → `key`/`priority`
|
|
3110
|
+
* rename). Registration is unconditional; only the render is conditional.
|
|
2856
3111
|
*/
|
|
2857
3112
|
/**
|
|
2858
3113
|
* The provider route the session is currently pointed at.
|
|
@@ -2865,6 +3120,17 @@ window.__ModuleLoader__.load({
|
|
|
2865
3120
|
return typeof provider === "string" && provider !== "" ? provider : void 0;
|
|
2866
3121
|
}
|
|
2867
3122
|
/**
|
|
3123
|
+
* The settings tree this plugin writes, unwrapped to a plain object.
|
|
3124
|
+
*
|
|
3125
|
+
* `unwrapVolatileDeep` first: on DSH 0.1.7 the scope's value is a live
|
|
3126
|
+
* cosmokit reference, and reading a field off it without unwrapping yields a
|
|
3127
|
+
* proxy whose `===` comparison against a string is false — which would make the
|
|
3128
|
+
* seat test below reject EVERY seat and silently hide the readout.
|
|
3129
|
+
*/
|
|
3130
|
+
function scopeValueOf(scope) {
|
|
3131
|
+
return scope === void 0 ? void 0 : unwrapVolatileDeep(scope.getSnapshot().value);
|
|
3132
|
+
}
|
|
3133
|
+
/**
|
|
2868
3134
|
* Read the composer-readout switch out of a committed settings snapshot.
|
|
2869
3135
|
*
|
|
2870
3136
|
* Absent means OFF, matching the host default (`false`): a scope that has not
|
|
@@ -2872,11 +3138,10 @@ window.__ModuleLoader__.load({
|
|
|
2872
3138
|
* the composer toolbar that the user never asked for.
|
|
2873
3139
|
*/
|
|
2874
3140
|
function composerPointsEnabledOf(scope) {
|
|
2875
|
-
|
|
2876
|
-
return unwrapVolatileDeep(scope.getSnapshot().value)?.showPointsInMainUi === true;
|
|
3141
|
+
return scopeValueOf(scope)?.showPointsInMainUi === true;
|
|
2877
3142
|
}
|
|
2878
3143
|
function ComposerPointsGate(props) {
|
|
2879
|
-
const { t, settingsScope, useProjection } = props;
|
|
3144
|
+
const { t, position, settingsScope, useProjection } = props;
|
|
2880
3145
|
const [enabled, setEnabled] = (0, react.useState)(() => composerPointsEnabledOf(settingsScope));
|
|
2881
3146
|
(0, react.useEffect)(() => settingsScope?.subscribe(() => {
|
|
2882
3147
|
setEnabled(composerPointsEnabledOf(settingsScope));
|
|
@@ -2886,6 +3151,8 @@ window.__ModuleLoader__.load({
|
|
|
2886
3151
|
const provider = selectedProviderOf(projection);
|
|
2887
3152
|
const region = provider === void 0 ? void 0 : TRAE_COMPOSER_PROVIDERS[provider];
|
|
2888
3153
|
if (region === void 0) return null;
|
|
3154
|
+
if (!regionEnabledOf(scopeValueOf(settingsScope), region)) return null;
|
|
3155
|
+
if (regionCreditPositionOf(scopeValueOf(settingsScope), region) !== (position ?? "composer")) return null;
|
|
2889
3156
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ComposerPoints, {
|
|
2890
3157
|
t,
|
|
2891
3158
|
provider,
|
|
@@ -2981,6 +3248,11 @@ window.__ModuleLoader__.load({
|
|
|
2981
3248
|
"row.showPointsInMainUi": "Show credits in the composer row",
|
|
2982
3249
|
"row.showPointsInMainUiHint": "A clickable readout in the composer tool row while a model from this plugin is selected: Trae CN · <balance> on the CN side, Trae Global · <plan> on the international one.",
|
|
2983
3250
|
"row.showPointsInMainUiHintAi": "A clickable readout in the composer tool row while a model from this plugin is selected: Trae Global · <plan>.",
|
|
3251
|
+
"row.creditPositionLabel": "position",
|
|
3252
|
+
"row.creditPositionComposer": "composer toolbar",
|
|
3253
|
+
"row.creditPositionStats": "below the input box",
|
|
3254
|
+
"row.creditPositionAria": "Credit readout position for {region}",
|
|
3255
|
+
"row.creditPositionHint": "Where the credit readout sits. \"composer toolbar\" is the default (the row with the model picker). Choose \"below the input box\" — the row carrying the round / step / token statistics — if another plugin occupies the composer toolbar and the readout does not appear.",
|
|
2984
3256
|
"composer.switchTo": "Switch to {account}",
|
|
2985
3257
|
"composer.noAccounts": "No account in this region",
|
|
2986
3258
|
"composer.panelTitle": "Trae credits",
|
|
@@ -3029,6 +3301,7 @@ window.__ModuleLoader__.load({
|
|
|
3029
3301
|
"row.discard": "Discard changes",
|
|
3030
3302
|
"row.save": "Save",
|
|
3031
3303
|
"row.saving": "Saving…",
|
|
3304
|
+
"row.veilSaving": "Saving changes…",
|
|
3032
3305
|
"row.modelContext": "Max context {context}",
|
|
3033
3306
|
"row.contextBudget": "DSH context budget",
|
|
3034
3307
|
"row.modelOutput": "Output {output}",
|
|
@@ -3122,6 +3395,11 @@ window.__ModuleLoader__.load({
|
|
|
3122
3395
|
"row.showPointsInMainUi": "在输入框工具栏显示积分读数",
|
|
3123
3396
|
"row.showPointsInMainUiHint": "在输入框工具栏显示可点击读数(选中本插件模型时出现):国内版为「Trae CN · 余额」,国际版为「Trae 国际版 · 套餐」。",
|
|
3124
3397
|
"row.showPointsInMainUiHintAi": "在输入框工具栏显示可点击读数(选中本插件模型时出现):国际版为「Trae 国际版 · 套餐」。",
|
|
3398
|
+
"row.creditPositionLabel": "显示位置",
|
|
3399
|
+
"row.creditPositionComposer": "输入框工具栏",
|
|
3400
|
+
"row.creditPositionStats": "输入框下方",
|
|
3401
|
+
"row.creditPositionAria": "{region} 的积分显示位置",
|
|
3402
|
+
"row.creditPositionHint": "积分显示在哪里。「输入框工具栏」是默认位置(与模型选择同一行)。如果装了别的插件后读数不显示,改成「输入框下方」—— 那是「轮次 / 步数 / token」统计所在的那一行。",
|
|
3125
3403
|
"composer.switchTo": "切换到 {account}",
|
|
3126
3404
|
"composer.noAccounts": "该区域暂无账号",
|
|
3127
3405
|
"composer.panelTitle": "Trae 积分",
|
|
@@ -3170,6 +3448,7 @@ window.__ModuleLoader__.load({
|
|
|
3170
3448
|
"row.discard": "放弃修改",
|
|
3171
3449
|
"row.save": "保存",
|
|
3172
3450
|
"row.saving": "保存中…",
|
|
3451
|
+
"row.veilSaving": "正在保存更改…",
|
|
3173
3452
|
"row.modelContext": "最大上下文 {context}",
|
|
3174
3453
|
"row.contextBudget": "DSH 上下文预算",
|
|
3175
3454
|
"row.modelOutput": "最大输出 {output}",
|
|
@@ -3320,24 +3599,37 @@ window.__ModuleLoader__.load({
|
|
|
3320
3599
|
* Registration is unconditional; the gate reads the Host's modelSelection
|
|
3321
3600
|
* projection and returns null for every other provider, so nothing is drawn
|
|
3322
3601
|
* and no fetch loop starts while another provider is selected.
|
|
3602
|
+
*
|
|
3603
|
+
* THE SAME READOUT IS REGISTERED IN TWO SEATS (learned from workbuddy issue
|
|
3604
|
+
* #62), and BOTH registrations are unconditional too. Which one actually
|
|
3605
|
+
* draws is decided inside the gate by the per-region `creditPosition`
|
|
3606
|
+
* setting, so changing the setting is a settings write rather than a slot
|
|
3607
|
+
* re-registration — this file's own header records how fragile rebinding a
|
|
3608
|
+
* slot is across DSH lines (the rc.6→rc.7 `id`/`order` → `key`/`priority`
|
|
3609
|
+
* rename). The composer row is a LIST seat shared with every other bundle,
|
|
3610
|
+
* so a third party parking something there can crowd this readout out of
|
|
3611
|
+
* existence; the second seat is what keeps one plugin's presence from
|
|
3612
|
+
* deciding another's.
|
|
3323
3613
|
*/
|
|
3324
|
-
const
|
|
3614
|
+
const registerPointsSlot = (slotName, id, order, position) => {
|
|
3325
3615
|
try {
|
|
3326
|
-
ctx.slots.inject(
|
|
3327
|
-
name:
|
|
3328
|
-
id
|
|
3329
|
-
order
|
|
3616
|
+
ctx.slots.inject(slotName, () => ctx.slots.register({
|
|
3617
|
+
name: slotName,
|
|
3618
|
+
id,
|
|
3619
|
+
order,
|
|
3330
3620
|
locale: namespace,
|
|
3331
3621
|
inject: () => ({
|
|
3332
3622
|
t,
|
|
3333
|
-
settingsScope
|
|
3623
|
+
settingsScope,
|
|
3624
|
+
position
|
|
3334
3625
|
})
|
|
3335
3626
|
}, ComposerPointsGate));
|
|
3336
3627
|
} catch (error) {
|
|
3337
|
-
console.error(
|
|
3628
|
+
console.error(`[dsh-connect-trae] points slot "${slotName}" failed to register (host provider unaffected):`, error);
|
|
3338
3629
|
}
|
|
3339
3630
|
};
|
|
3340
|
-
|
|
3631
|
+
registerPointsSlot("conversation.input.left", "dsh-connect-trae-composer-points", 4, "composer");
|
|
3632
|
+
registerPointsSlot("conversation.composer.dock", "dsh-connect-trae-stats-points", 10, "stats");
|
|
3341
3633
|
} catch (error) {
|
|
3342
3634
|
console.error("[dsh-connect-trae] client card failed to load (host provider unaffected):", error);
|
|
3343
3635
|
}
|