@mars-sea/dsh-commandcode-provider 0.11.9 → 0.11.11
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 +24 -1
- package/README.md +36 -6
- package/README.zh-CN.md +36 -6
- package/icon.svg +1 -5
- package/lib/client.js +244 -63
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +104 -11
- package/lib/index.js +1108 -58
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -586,6 +586,16 @@ window.__ModuleLoader__.load({
|
|
|
586
586
|
booleanField$1("filterModelsByPlan"),
|
|
587
587
|
booleanField$1("webSearch"),
|
|
588
588
|
booleanField$1("showSidebarQuota"),
|
|
589
|
+
booleanField$1("commandGuard"),
|
|
590
|
+
numberField$1("commandGuardThreshold", {
|
|
591
|
+
min: .5,
|
|
592
|
+
max: 1
|
|
593
|
+
}),
|
|
594
|
+
numberField$1("commandGuardTimeoutMs", {
|
|
595
|
+
min: 200,
|
|
596
|
+
max: 1e4
|
|
597
|
+
}),
|
|
598
|
+
booleanField$1("zdr"),
|
|
589
599
|
textField("activeAccount")
|
|
590
600
|
];
|
|
591
601
|
/** Whether two model-id lists are equal as sets (order-insensitive). */
|
|
@@ -740,6 +750,10 @@ window.__ModuleLoader__.load({
|
|
|
740
750
|
filterModelsByPlan: this.field("filterModelsByPlan"),
|
|
741
751
|
webSearch: this.field("webSearch"),
|
|
742
752
|
showSidebarQuota: this.field("showSidebarQuota"),
|
|
753
|
+
commandGuard: this.field("commandGuard"),
|
|
754
|
+
commandGuardThreshold: this.field("commandGuardThreshold"),
|
|
755
|
+
commandGuardTimeoutMs: this.field("commandGuardTimeoutMs"),
|
|
756
|
+
zdr: this.field("zdr"),
|
|
743
757
|
sidebarQuota: this.sectionValue("showSidebarQuota") === true,
|
|
744
758
|
activeAccount: this.field("activeAccount"),
|
|
745
759
|
accounts,
|
|
@@ -1789,6 +1803,21 @@ window.__ModuleLoader__.load({
|
|
|
1789
1803
|
};
|
|
1790
1804
|
//#endregion
|
|
1791
1805
|
//#region src/client/login.ts
|
|
1806
|
+
/** Keep one account's login status out of every other account's row. */
|
|
1807
|
+
function loginStateForTarget(state, targetRef) {
|
|
1808
|
+
if (state.targetRef === targetRef) return {
|
|
1809
|
+
visible: state,
|
|
1810
|
+
busyElsewhere: false
|
|
1811
|
+
};
|
|
1812
|
+
return {
|
|
1813
|
+
visible: {
|
|
1814
|
+
...state,
|
|
1815
|
+
phase: "idle",
|
|
1816
|
+
authUrl: void 0
|
|
1817
|
+
},
|
|
1818
|
+
busyElsewhere: state.phase === "starting" || state.phase === "waiting"
|
|
1819
|
+
};
|
|
1820
|
+
}
|
|
1792
1821
|
/** How often a live attempt is polled. */
|
|
1793
1822
|
const POLL_INTERVAL_MS = 1e3;
|
|
1794
1823
|
/**
|
|
@@ -1803,6 +1832,7 @@ window.__ModuleLoader__.load({
|
|
|
1803
1832
|
generation = 0;
|
|
1804
1833
|
disposed = false;
|
|
1805
1834
|
phase = "idle";
|
|
1835
|
+
targetRef;
|
|
1806
1836
|
authUrl;
|
|
1807
1837
|
userName;
|
|
1808
1838
|
keyName;
|
|
@@ -1821,6 +1851,7 @@ window.__ModuleLoader__.load({
|
|
|
1821
1851
|
state() {
|
|
1822
1852
|
return {
|
|
1823
1853
|
phase: this.phase,
|
|
1854
|
+
...this.targetRef === void 0 ? {} : { targetRef: this.targetRef },
|
|
1824
1855
|
authUrl: this.authUrl,
|
|
1825
1856
|
userName: this.userName,
|
|
1826
1857
|
keyName: this.keyName,
|
|
@@ -1829,9 +1860,10 @@ window.__ModuleLoader__.load({
|
|
|
1829
1860
|
};
|
|
1830
1861
|
}
|
|
1831
1862
|
/** Start (or rejoin) a login attempt and begin polling its status. */
|
|
1832
|
-
async begin() {
|
|
1863
|
+
async begin(targetRef) {
|
|
1833
1864
|
if (this.disposed || this.phase === "starting" || this.phase === "waiting") return;
|
|
1834
1865
|
const generation = ++this.generation;
|
|
1866
|
+
this.targetRef = targetRef;
|
|
1835
1867
|
this.set({
|
|
1836
1868
|
phase: "starting",
|
|
1837
1869
|
authUrl: void 0,
|
|
@@ -1854,7 +1886,7 @@ window.__ModuleLoader__.load({
|
|
|
1854
1886
|
}
|
|
1855
1887
|
let result;
|
|
1856
1888
|
try {
|
|
1857
|
-
result = await remote.loginBegin();
|
|
1889
|
+
result = await remote.loginBegin(targetRef);
|
|
1858
1890
|
} catch (error) {
|
|
1859
1891
|
result = {
|
|
1860
1892
|
ok: false,
|
|
@@ -2092,6 +2124,15 @@ window.__ModuleLoader__.load({
|
|
|
2092
2124
|
booleanField
|
|
2093
2125
|
};
|
|
2094
2126
|
}
|
|
2127
|
+
/** Use the same strict-codec shape for invocation parameters and results. */
|
|
2128
|
+
function makeStrictCodec(typeSymbol, schema) {
|
|
2129
|
+
return {
|
|
2130
|
+
mode: "strict",
|
|
2131
|
+
typeSymbol,
|
|
2132
|
+
schema,
|
|
2133
|
+
create: () => schema
|
|
2134
|
+
};
|
|
2135
|
+
}
|
|
2095
2136
|
/**
|
|
2096
2137
|
* Build one strict invocation descriptor. Every Command Code Remote shares the
|
|
2097
2138
|
* `commandcode` namespace, the `commandcodeUsage` service, and a strict
|
|
@@ -2100,12 +2141,7 @@ window.__ModuleLoader__.load({
|
|
|
2100
2141
|
* only its own facts.
|
|
2101
2142
|
*/
|
|
2102
2143
|
function makeRemoteDescriptor(endpoint, method, typeSymbol, schema) {
|
|
2103
|
-
const result =
|
|
2104
|
-
mode: "strict",
|
|
2105
|
-
typeSymbol,
|
|
2106
|
-
schema,
|
|
2107
|
-
create: () => schema
|
|
2108
|
-
};
|
|
2144
|
+
const result = makeStrictCodec(typeSymbol, schema);
|
|
2109
2145
|
return {
|
|
2110
2146
|
id: `${REMOTE_PACKAGE}#${endpoint}`,
|
|
2111
2147
|
service: REMOTE_SERVICE,
|
|
@@ -2158,7 +2194,7 @@ window.__ModuleLoader__.load({
|
|
|
2158
2194
|
const report = { failures };
|
|
2159
2195
|
if (source.blocked !== void 0) {
|
|
2160
2196
|
const blocked = source.blocked;
|
|
2161
|
-
if (blocked === "invalid-key" || blocked === "service-unavailable" || blocked === "network") report.blocked = blocked;
|
|
2197
|
+
if (blocked === "invalid-key" || blocked === "service-unavailable" || blocked === "invalid-response" || blocked === "network") report.blocked = blocked;
|
|
2162
2198
|
else reject$1("blocked");
|
|
2163
2199
|
}
|
|
2164
2200
|
if (source.account !== void 0) {
|
|
@@ -2374,9 +2410,24 @@ window.__ModuleLoader__.load({
|
|
|
2374
2410
|
}
|
|
2375
2411
|
/** The strict result codec shared by all three login endpoints. */
|
|
2376
2412
|
const loginStatusSchema = { parse: parseLoginStatus };
|
|
2377
|
-
/**
|
|
2413
|
+
/** Optional account target; the Host still checks it against saved slots. */
|
|
2414
|
+
const loginTargetSchema = { parse(value) {
|
|
2415
|
+
if (value === void 0 || typeof value === "string") return value;
|
|
2416
|
+
return reject("targetRef");
|
|
2417
|
+
} };
|
|
2418
|
+
/** Build one login invocation descriptor. Only begin accepts an account ref. */
|
|
2378
2419
|
function loginDescriptor(endpoint, method) {
|
|
2379
|
-
|
|
2420
|
+
const descriptor = makeRemoteDescriptor(endpoint, method, `${REMOTE_PACKAGE}#CommandCodeLoginStatus`, loginStatusSchema);
|
|
2421
|
+
return method === "loginBegin" ? {
|
|
2422
|
+
...descriptor,
|
|
2423
|
+
parameters: [{
|
|
2424
|
+
name: "targetRef",
|
|
2425
|
+
wire: "targetRef",
|
|
2426
|
+
source: "json",
|
|
2427
|
+
codec: makeStrictCodec(`${REMOTE_PACKAGE}#CommandCodeLoginTargetRef`, loginTargetSchema),
|
|
2428
|
+
acceptsUndefined: true
|
|
2429
|
+
}]
|
|
2430
|
+
} : descriptor;
|
|
2380
2431
|
}
|
|
2381
2432
|
/** The Client-face contribution fragment mounted on `ctx.remote`. */
|
|
2382
2433
|
const LOGIN_REMOTE_CONTRIBUTION = {
|
|
@@ -2390,9 +2441,10 @@ window.__ModuleLoader__.load({
|
|
|
2390
2441
|
//#endregion
|
|
2391
2442
|
//#region src/client/login-row.tsx
|
|
2392
2443
|
/** The sign-in alternative to pasting a key (settings page + Models card). */
|
|
2393
|
-
function LoginRow({ state, disabled, t, onBegin, onCancel }) {
|
|
2394
|
-
const
|
|
2395
|
-
const
|
|
2444
|
+
function LoginRow({ state, targetRef, disabled, disabledHint, t, onBegin, onCancel }) {
|
|
2445
|
+
const { visible: visibleState, busyElsewhere } = loginStateForTarget(state, targetRef);
|
|
2446
|
+
const busy = visibleState.phase === "starting" || visibleState.phase === "waiting";
|
|
2447
|
+
const hint = loginHint(visibleState, t);
|
|
2396
2448
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2397
2449
|
className: "cc-field",
|
|
2398
2450
|
children: [
|
|
@@ -2411,17 +2463,17 @@ window.__ModuleLoader__.load({
|
|
|
2411
2463
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2412
2464
|
type: "button",
|
|
2413
2465
|
className: "cc-reset",
|
|
2414
|
-
disabled,
|
|
2466
|
+
disabled: disabled || busyElsewhere,
|
|
2415
2467
|
onClick: onBegin,
|
|
2416
2468
|
children: t("loginButton")
|
|
2417
2469
|
})
|
|
2418
2470
|
})]
|
|
2419
2471
|
}),
|
|
2420
|
-
|
|
2472
|
+
visibleState.authUrl !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2421
2473
|
className: "cc-hint",
|
|
2422
2474
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2423
2475
|
className: "cc-loginLink",
|
|
2424
|
-
href:
|
|
2476
|
+
href: visibleState.authUrl,
|
|
2425
2477
|
target: "_blank",
|
|
2426
2478
|
rel: "noreferrer",
|
|
2427
2479
|
children: t("loginOpenLink")
|
|
@@ -2430,7 +2482,7 @@ window.__ModuleLoader__.load({
|
|
|
2430
2482
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2431
2483
|
className: hint.className,
|
|
2432
2484
|
title: hint.title,
|
|
2433
|
-
children: hint.text
|
|
2485
|
+
children: disabled && !busy && disabledHint !== void 0 ? disabledHint : hint.text
|
|
2434
2486
|
})
|
|
2435
2487
|
]
|
|
2436
2488
|
});
|
|
@@ -2579,7 +2631,7 @@ window.__ModuleLoader__.load({
|
|
|
2579
2631
|
}
|
|
2580
2632
|
//#endregion
|
|
2581
2633
|
//#region package.json
|
|
2582
|
-
var version = "0.11.
|
|
2634
|
+
var version = "0.11.11";
|
|
2583
2635
|
var repository = {
|
|
2584
2636
|
"type": "git",
|
|
2585
2637
|
"url": "git+https://github.com/Mars-Sea/dsh-commandcode-provider.git"
|
|
@@ -2781,7 +2833,11 @@ window.__ModuleLoader__.load({
|
|
|
2781
2833
|
"transportMaxRetries",
|
|
2782
2834
|
"filterModelsByPlan",
|
|
2783
2835
|
"webSearch",
|
|
2784
|
-
"showSidebarQuota"
|
|
2836
|
+
"showSidebarQuota",
|
|
2837
|
+
"commandGuard",
|
|
2838
|
+
"commandGuardThreshold",
|
|
2839
|
+
"commandGuardTimeoutMs",
|
|
2840
|
+
"zdr"
|
|
2785
2841
|
];
|
|
2786
2842
|
/** One labelled field row in the page body. */
|
|
2787
2843
|
function Field({ id, label, hint, state, disabled, numeric, placeholder, onEdit, onReset, t }) {
|
|
@@ -2967,6 +3023,49 @@ window.__ModuleLoader__.load({
|
|
|
2967
3023
|
onEdit: (text) => onEdit("showSidebarQuota", text),
|
|
2968
3024
|
onReset: () => onReset("showSidebarQuota"),
|
|
2969
3025
|
t
|
|
3026
|
+
}),
|
|
3027
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleField, {
|
|
3028
|
+
id: "cc-command-guard",
|
|
3029
|
+
label: t("commandGuard"),
|
|
3030
|
+
hint: t("commandGuardHint"),
|
|
3031
|
+
state: state.commandGuard,
|
|
3032
|
+
disabled,
|
|
3033
|
+
defaultChecked: false,
|
|
3034
|
+
onEdit: (text) => onEdit("commandGuard", text),
|
|
3035
|
+
onReset: () => onReset("commandGuard"),
|
|
3036
|
+
t
|
|
3037
|
+
}),
|
|
3038
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
3039
|
+
id: "cc-command-guard-threshold",
|
|
3040
|
+
label: t("commandGuardThreshold"),
|
|
3041
|
+
hint: t("commandGuardThresholdHint"),
|
|
3042
|
+
state: state.commandGuardThreshold,
|
|
3043
|
+
disabled,
|
|
3044
|
+
onEdit: (text) => onEdit("commandGuardThreshold", text),
|
|
3045
|
+
onReset: () => onReset("commandGuardThreshold"),
|
|
3046
|
+
t
|
|
3047
|
+
}),
|
|
3048
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Field, {
|
|
3049
|
+
id: "cc-command-guard-timeout",
|
|
3050
|
+
label: t("commandGuardTimeoutMs"),
|
|
3051
|
+
hint: t("commandGuardTimeoutMsHint"),
|
|
3052
|
+
state: state.commandGuardTimeoutMs,
|
|
3053
|
+
disabled,
|
|
3054
|
+
numeric: true,
|
|
3055
|
+
onEdit: (text) => onEdit("commandGuardTimeoutMs", text),
|
|
3056
|
+
onReset: () => onReset("commandGuardTimeoutMs"),
|
|
3057
|
+
t
|
|
3058
|
+
}),
|
|
3059
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToggleField, {
|
|
3060
|
+
id: "cc-zdr",
|
|
3061
|
+
label: t("zdr"),
|
|
3062
|
+
hint: t("zdrHint"),
|
|
3063
|
+
state: state.zdr,
|
|
3064
|
+
disabled,
|
|
3065
|
+
defaultChecked: false,
|
|
3066
|
+
onEdit: (text) => onEdit("zdr", text),
|
|
3067
|
+
onReset: () => onReset("zdr"),
|
|
3068
|
+
t
|
|
2970
3069
|
})
|
|
2971
3070
|
]
|
|
2972
3071
|
}) : null,
|
|
@@ -3337,12 +3436,14 @@ window.__ModuleLoader__.load({
|
|
|
3337
3436
|
function blockedTitle(reason, t) {
|
|
3338
3437
|
if (reason === "invalid-key") return t("usageKeyInvalid");
|
|
3339
3438
|
if (reason === "service-unavailable") return t("usageServiceUnavailable");
|
|
3439
|
+
if (reason === "invalid-response") return t("usageInvalidResponse");
|
|
3340
3440
|
return t("usageNetworkError");
|
|
3341
3441
|
}
|
|
3342
3442
|
/** The actionable hint under a blocked report's headline. */
|
|
3343
3443
|
function blockedHint(reason, t) {
|
|
3344
3444
|
if (reason === "invalid-key") return t("usageKeyInvalidHint");
|
|
3345
3445
|
if (reason === "service-unavailable") return t("usageServiceUnavailableHint");
|
|
3446
|
+
if (reason === "invalid-response") return t("usageInvalidResponseHint");
|
|
3346
3447
|
return t("usageNetworkHint");
|
|
3347
3448
|
}
|
|
3348
3449
|
/** The status dot on an account tab: cooling/invalid warn, everything else ok. */
|
|
@@ -3533,7 +3634,7 @@ window.__ModuleLoader__.load({
|
|
|
3533
3634
|
});
|
|
3534
3635
|
}
|
|
3535
3636
|
/** The multi-account card: the active-account selector + extra accounts in rotation order + add button. */
|
|
3536
|
-
function AccountsCard({ t, state, disabled, onAdd, onRemove, onLabel, onKey, onToggleClear, onActive, onActiveReset }) {
|
|
3637
|
+
function AccountsCard({ t, state, login, disabled, onAdd, onRemove, onLabel, onKey, onToggleClear, onActive, onActiveReset, onBeginLogin, onCancelLogin }) {
|
|
3537
3638
|
const active = state.activeAccount;
|
|
3538
3639
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3539
3640
|
className: "cc-card",
|
|
@@ -3611,14 +3712,31 @@ window.__ModuleLoader__.load({
|
|
|
3611
3712
|
})
|
|
3612
3713
|
]
|
|
3613
3714
|
}),
|
|
3614
|
-
state.accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3715
|
+
state.accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3716
|
+
className: "cc-accountEditor",
|
|
3717
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountRow, {
|
|
3718
|
+
account,
|
|
3719
|
+
disabled: disabled || login.targetRef === account.ref && (login.phase === "starting" || login.phase === "waiting"),
|
|
3720
|
+
t,
|
|
3721
|
+
onLabel: (text) => onLabel(account.id, text),
|
|
3722
|
+
onKey: (text) => onKey(account.id, text),
|
|
3723
|
+
onToggleClear: () => onToggleClear(account.id),
|
|
3724
|
+
onRemove: () => onRemove(account.id)
|
|
3725
|
+
}), account.added ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3726
|
+
className: "cc-accountLoginHint",
|
|
3727
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3728
|
+
className: "cc-hint",
|
|
3729
|
+
children: t("accountLoginAfterSave")
|
|
3730
|
+
})
|
|
3731
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoginRow, {
|
|
3732
|
+
state: login,
|
|
3733
|
+
targetRef: account.ref,
|
|
3734
|
+
disabled: disabled || !account.writable || state.dirty,
|
|
3735
|
+
disabledHint: state.dirty ? t("loginSaveBefore") : void 0,
|
|
3736
|
+
t,
|
|
3737
|
+
onBegin: () => onBeginLogin(account.ref),
|
|
3738
|
+
onCancel: onCancelLogin
|
|
3739
|
+
})]
|
|
3622
3740
|
}, account.id))
|
|
3623
3741
|
]
|
|
3624
3742
|
});
|
|
@@ -3930,6 +4048,8 @@ window.__ModuleLoader__.load({
|
|
|
3930
4048
|
/** The settings page body: connection facts for the Command Code provider. */
|
|
3931
4049
|
function CommandCodeSettingsPage(props) {
|
|
3932
4050
|
const { t } = props;
|
|
4051
|
+
const footerMarker = (0, react.useRef)(null);
|
|
4052
|
+
const [footerFloating, setFooterFloating] = (0, react.useState)(false);
|
|
3933
4053
|
const state = props.useCommandCodeSettings((snapshot) => snapshot);
|
|
3934
4054
|
const usage = props.useCommandCodeUsage((snapshot) => snapshot);
|
|
3935
4055
|
const login = props.useCommandCodeLogin((snapshot) => snapshot);
|
|
@@ -3937,6 +4057,15 @@ window.__ModuleLoader__.load({
|
|
|
3937
4057
|
const keyLocked = !state.apiKeyWritable;
|
|
3938
4058
|
const savedVisible = useSavedFlash(state.savedCount);
|
|
3939
4059
|
const updateVersion = usePluginUpdate();
|
|
4060
|
+
(0, react.useEffect)(() => {
|
|
4061
|
+
const marker = footerMarker.current;
|
|
4062
|
+
if (!marker || typeof IntersectionObserver === "undefined") return;
|
|
4063
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
4064
|
+
if (entry) setFooterFloating(!entry.isIntersecting);
|
|
4065
|
+
});
|
|
4066
|
+
observer.observe(marker);
|
|
4067
|
+
return () => observer.disconnect();
|
|
4068
|
+
}, []);
|
|
3940
4069
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
3941
4070
|
className: "cc-section",
|
|
3942
4071
|
"aria-label": t("title"),
|
|
@@ -3966,6 +4095,7 @@ window.__ModuleLoader__.load({
|
|
|
3966
4095
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountsCard, {
|
|
3967
4096
|
t,
|
|
3968
4097
|
state,
|
|
4098
|
+
login,
|
|
3969
4099
|
disabled,
|
|
3970
4100
|
onAdd: props.addAccount,
|
|
3971
4101
|
onRemove: props.removeAccount,
|
|
@@ -3973,7 +4103,9 @@ window.__ModuleLoader__.load({
|
|
|
3973
4103
|
onKey: props.editAccountKey,
|
|
3974
4104
|
onToggleClear: (id) => props.toggleKeyClear(id),
|
|
3975
4105
|
onActive: (text) => props.edit("activeAccount", text),
|
|
3976
|
-
onActiveReset: () => props.resetField("activeAccount")
|
|
4106
|
+
onActiveReset: () => props.resetField("activeAccount"),
|
|
4107
|
+
onBeginLogin: props.beginLogin,
|
|
4108
|
+
onCancelLogin: props.cancelLogin
|
|
3977
4109
|
}),
|
|
3978
4110
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RulesCard, {
|
|
3979
4111
|
t,
|
|
@@ -3997,7 +4129,7 @@ window.__ModuleLoader__.load({
|
|
|
3997
4129
|
label: t("apiKey"),
|
|
3998
4130
|
hint: keyLocked ? t("apiKeyLocked") : t("apiKeyHint"),
|
|
3999
4131
|
state: state.apiKey,
|
|
4000
|
-
disabled: disabled || keyLocked,
|
|
4132
|
+
disabled: disabled || keyLocked || login.targetRef === void 0 && (login.phase === "starting" || login.phase === "waiting"),
|
|
4001
4133
|
configured: state.apiKeyConfigured,
|
|
4002
4134
|
configuredLabel: t("apiKeySet"),
|
|
4003
4135
|
unconfiguredLabel: t("apiKeyUnset"),
|
|
@@ -4011,7 +4143,8 @@ window.__ModuleLoader__.load({
|
|
|
4011
4143
|
onToggleClear: () => props.toggleKeyClear("default")
|
|
4012
4144
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoginRow, {
|
|
4013
4145
|
state: login,
|
|
4014
|
-
disabled: disabled || keyLocked,
|
|
4146
|
+
disabled: disabled || keyLocked || state.dirty,
|
|
4147
|
+
disabledHint: state.dirty ? t("loginSaveBefore") : void 0,
|
|
4015
4148
|
t,
|
|
4016
4149
|
onBegin: props.beginLogin,
|
|
4017
4150
|
onCancel: props.cancelLogin
|
|
@@ -4024,34 +4157,42 @@ window.__ModuleLoader__.load({
|
|
|
4024
4157
|
onEdit: props.edit,
|
|
4025
4158
|
onReset: props.resetField
|
|
4026
4159
|
}),
|
|
4027
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
|
|
4160
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4161
|
+
ref: footerMarker,
|
|
4162
|
+
className: "cc-footerMarker",
|
|
4163
|
+
"aria-hidden": "true"
|
|
4164
|
+
}),
|
|
4165
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4166
|
+
className: `cc-footer cc-footerSticky${footerFloating ? " cc-footerFloating" : ""}`,
|
|
4167
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4168
|
+
className: "cc-footerActions",
|
|
4169
|
+
children: [
|
|
4170
|
+
state.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4171
|
+
className: "cc-failed",
|
|
4172
|
+
role: "status",
|
|
4173
|
+
children: t("saveFailed")
|
|
4174
|
+
}) : null,
|
|
4175
|
+
savedVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4176
|
+
className: "cc-saved",
|
|
4177
|
+
role: "status",
|
|
4178
|
+
children: t("saved")
|
|
4179
|
+
}) : null,
|
|
4180
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4181
|
+
variant: "ghost",
|
|
4182
|
+
size: "sm",
|
|
4183
|
+
disabled: !state.dirty || state.saving,
|
|
4184
|
+
onClick: props.discard,
|
|
4185
|
+
children: t("discard")
|
|
4186
|
+
}),
|
|
4187
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4188
|
+
variant: "primary",
|
|
4189
|
+
size: "sm",
|
|
4190
|
+
disabled: !state.dirty || state.invalid || state.saving,
|
|
4191
|
+
onClick: props.save,
|
|
4192
|
+
children: t(state.saving ? "saving" : "save")
|
|
4193
|
+
})
|
|
4194
|
+
]
|
|
4195
|
+
})
|
|
4055
4196
|
}),
|
|
4056
4197
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
4057
4198
|
className: "cc-version",
|
|
@@ -4338,6 +4479,8 @@ window.__ModuleLoader__.load({
|
|
|
4338
4479
|
errorServiceUnavailableHint: "服务端返回错误(5xx),请稍后点击刷新重试。",
|
|
4339
4480
|
errorNetwork: "无法连接 Command Code 服务",
|
|
4340
4481
|
errorNetworkHint: "所有请求都没有到达服务端。请检查网络连接或 API 地址设置。",
|
|
4482
|
+
errorInvalidResponse: "Command Code 响应无法读取",
|
|
4483
|
+
errorInvalidResponseHint: "请求已收到响应,但内容无法解析。请检查宿主的 HTTP 代理或响应解压配置。",
|
|
4341
4484
|
errorGeneric: "用量获取失败"
|
|
4342
4485
|
};
|
|
4343
4486
|
/** The panel's English string table (must mirror {@link PANEL_COPY_ZH}). */
|
|
@@ -4390,6 +4533,8 @@ window.__ModuleLoader__.load({
|
|
|
4390
4533
|
errorServiceUnavailableHint: "The server returned errors (5xx). Try Refresh again in a moment.",
|
|
4391
4534
|
errorNetwork: "Could not reach the Command Code service",
|
|
4392
4535
|
errorNetworkHint: "No request reached the server. Check your network connection or the API base setting.",
|
|
4536
|
+
errorInvalidResponse: "Could not read the Command Code response",
|
|
4537
|
+
errorInvalidResponseHint: "The requests received responses, but their bodies could not be parsed. Check the host HTTP proxy or response decoding.",
|
|
4393
4538
|
errorGeneric: "Could not fetch account usage"
|
|
4394
4539
|
};
|
|
4395
4540
|
/** Every panel key, in the English table's declaration order. */
|
|
@@ -4570,6 +4715,11 @@ window.__ModuleLoader__.load({
|
|
|
4570
4715
|
hint: "errorNetworkHint",
|
|
4571
4716
|
detail
|
|
4572
4717
|
};
|
|
4718
|
+
if (blocked === "invalid-response") return {
|
|
4719
|
+
title: "errorInvalidResponse",
|
|
4720
|
+
hint: "errorInvalidResponseHint",
|
|
4721
|
+
detail
|
|
4722
|
+
};
|
|
4573
4723
|
if (state.status === "error" && state.report === void 0) return {
|
|
4574
4724
|
title: "errorGeneric",
|
|
4575
4725
|
hint: "errorGeneric",
|
|
@@ -6174,6 +6324,13 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6174
6324
|
.cc-advancedBody>.cc-field:first-of-type{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
6175
6325
|
.cc-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}
|
|
6176
6326
|
.cc-footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}
|
|
6327
|
+
/* Keep the original footer in flow and inside the settings scrollport. */
|
|
6328
|
+
.cc-footerMarker{height:1px;margin:-6px 0 -7px;pointer-events:none}
|
|
6329
|
+
.cc-footerSticky{position:sticky;bottom:0;z-index:2;flex-shrink:0;min-height:48px;pointer-events:none}
|
|
6330
|
+
.cc-footerActions{align-items:center;gap:8px;display:flex;pointer-events:auto}
|
|
6331
|
+
.cc-footerFloating .cc-footerActions{padding:6px;border:1px solid var(--dsw-alias-border-l2);border-radius:12px;background:var(--dsw-alias-bg-layer-3,var(--dsw-alias-bg-layer-2));box-shadow:0 8px 24px rgba(0,0,0,.12)}
|
|
6332
|
+
.cc-accountEditor{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
6333
|
+
.cc-accountLoginHint{padding:0 0 12px}
|
|
6177
6334
|
.cc-toggleRow{align-items:center;gap:8px;cursor:pointer;display:flex}
|
|
6178
6335
|
.cc-toggleRow:has(.cc-toggle:disabled){cursor:default}
|
|
6179
6336
|
.cc-toggle{appearance:none;flex-shrink:0;background:var(--dsw-alias-border-l2);border-radius:999px;width:30px;height:18px;margin:0;cursor:pointer;position:relative;transition:background .15s ease}
|
|
@@ -6450,6 +6607,14 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6450
6607
|
webSearchHint: "开启后,dsh 的 web_search 工具由 Command Code 承担(复用同一个 API key 与地址),并优先于其他搜索后端;关闭则把选择权交还给之前的后端(如 modsearch),而不是强制回退到 DeepSeek 搜索。",
|
|
6451
6608
|
showSidebarQuota: "在侧边栏显示额度卡片",
|
|
6452
6609
|
showSidebarQuotaHint: "开启后,侧边栏底部(Settings 上方)显示 Command Code 套餐与配额卡片,点击可在中间栏打开完整仪表盘。默认关闭:左侧不显示任何额度信息,也不会为其后台刷新用量。保存后立即生效。",
|
|
6610
|
+
commandGuard: "AI 命令安全预判",
|
|
6611
|
+
commandGuardHint: "命令确认弹窗前,先由 typesafe/jev 判断它是否安全:安全就自动放行,其余照常弹窗。默认关闭。",
|
|
6612
|
+
commandGuardThreshold: "自动放行阈值(0.5–1)",
|
|
6613
|
+
commandGuardThresholdHint: "typesafe/jev 判定\"安全\"的概率达到该值即放行,默认 0.9。",
|
|
6614
|
+
commandGuardTimeoutMs: "判定超时(毫秒,200–10000)",
|
|
6615
|
+
commandGuardTimeoutMsHint: "typesafe/jev 超过该时间未返回就照常弹窗,默认 1500。",
|
|
6616
|
+
zdr: "零数据保留(ZDR)",
|
|
6617
|
+
zdrHint: "开启后,请求只经由不留存提示词与回复、也不用于训练的上游(等价于 CLI 的 CMD_ZDR=1)。没有可用 ZDR 上游的模型会返回错误,请换用其他模型或关闭此开关。ZDR 容量按上游实价透传,通常更贵;费用读数仍按常规目录价估算。默认关闭。",
|
|
6453
6618
|
accountsTitle: "多账户轮换",
|
|
6454
6619
|
accountsHint: "当前账户达到用量限额(429)或密钥失效(401)时,请求自动切换到下一个账户;全部耗尽时会提示最早的重置时间。",
|
|
6455
6620
|
accountAdd: "添加账户",
|
|
@@ -6457,6 +6622,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6457
6622
|
accountLabel: "账户备注名",
|
|
6458
6623
|
accountKey: "API 密钥",
|
|
6459
6624
|
accountKeyHint: "该账户的 API 密钥。留空保存不会覆盖已存储的密钥。",
|
|
6625
|
+
accountLoginAfterSave: "先点击页面底部的「保存」,再点击该账户的「登录 Command Code」通过网页获取密钥。",
|
|
6460
6626
|
accountDefault: "默认账户",
|
|
6461
6627
|
activeAccount: "当前使用账户",
|
|
6462
6628
|
activeAccountAuto: "自动(第一个可用账户)",
|
|
@@ -6527,6 +6693,8 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6527
6693
|
usageServiceUnavailableHint: "服务端返回了错误(5xx),稍后点击刷新重试。",
|
|
6528
6694
|
usageNetworkError: "无法连接 Command Code 服务",
|
|
6529
6695
|
usageNetworkHint: "所有请求都没有到达服务端。请检查网络连接或 API 地址设置。",
|
|
6696
|
+
usageInvalidResponse: "Command Code 响应无法读取",
|
|
6697
|
+
usageInvalidResponseHint: "请求已收到响应,但内容无法解析。请检查宿主的 HTTP 代理或响应解压配置。",
|
|
6530
6698
|
usageUpdated: "更新于",
|
|
6531
6699
|
usagePeriodEnd: "账期截止",
|
|
6532
6700
|
usageActive: "当前使用",
|
|
@@ -6537,6 +6705,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6537
6705
|
updateHint: "已发布新版本,点击查看发布说明;更新插件后刷新本页,提示会自动消失。",
|
|
6538
6706
|
loginTitle: "通过官方登录获取密钥",
|
|
6539
6707
|
loginHintIdle: "不想手动创建密钥?点击登录后浏览器会打开 commandcode.ai 授权页,完成后密钥自动写入本机凭据服务,下次请求即生效。",
|
|
6708
|
+
loginSaveBefore: "请先保存本页更改,再通过网页登录此账户。",
|
|
6540
6709
|
loginButton: "登录 Command Code",
|
|
6541
6710
|
loginStarting: "正在启动本地回调服务…",
|
|
6542
6711
|
loginWaiting: "等待在浏览器中完成授权…",
|
|
@@ -6586,6 +6755,14 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6586
6755
|
webSearchHint: "When on, the model-facing web_search tool is backed by Command Code (same API key and base URL as chat), winning over other search backends. Off hands the selection back to the previous backend (e.g. modsearch) instead of forcing the shipped DeepSeek search.",
|
|
6587
6756
|
showSidebarQuota: "Show the quota card in the sidebar",
|
|
6588
6757
|
showSidebarQuotaHint: "When on, a Command Code plan & quota card sits at the bottom of the sidebar (above Settings) and opens the full dashboard in the centre column. Off by default: nothing is shown on the left, and no background usage poll runs for it. Applies on save.",
|
|
6758
|
+
commandGuard: "AI command guard",
|
|
6759
|
+
commandGuardHint: "Before a shell command asks for approval, typesafe/jev judges whether it is safe: safe commands run without a prompt, everything else asks as usual. Off by default.",
|
|
6760
|
+
commandGuardThreshold: "Auto-approve threshold (0.5–1)",
|
|
6761
|
+
commandGuardThresholdHint: "Approve when typesafe/jev rates the command \"safe\" at least this likely; default 0.9.",
|
|
6762
|
+
commandGuardTimeoutMs: "Judgement timeout (ms, 200–10000)",
|
|
6763
|
+
commandGuardTimeoutMsHint: "If typesafe/jev does not answer in time, the normal prompt appears; default 1500.",
|
|
6764
|
+
zdr: "Zero data retention (ZDR)",
|
|
6765
|
+
zdrHint: "Serve requests only through upstreams that keep no prompts or completions and never train on them (the same opt-in as the CLI's CMD_ZDR=1). A few models have no ZDR upstream; requests for those models fail rather than losing ZDR protection. ZDR capacity is billed at the upstream's pass-through rates and usually costs more; the cost readout keeps quoting the ordinary catalog rates. Off by default.",
|
|
6589
6766
|
accountsTitle: "Account rotation",
|
|
6590
6767
|
accountsHint: "When the active account hits its usage limit (429) or its key fails (401), requests switch to the next account; when every account is exhausted the error names the earliest window reset.",
|
|
6591
6768
|
accountAdd: "Add account",
|
|
@@ -6593,6 +6770,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6593
6770
|
accountLabel: "Account label",
|
|
6594
6771
|
accountKey: "API key",
|
|
6595
6772
|
accountKeyHint: "This account’s API key. Saving with the field blank keeps the stored key.",
|
|
6773
|
+
accountLoginAfterSave: "Use Save at the bottom of the page, then sign in to this account in your browser to obtain a key.",
|
|
6596
6774
|
accountDefault: "Default account",
|
|
6597
6775
|
activeAccount: "Active account",
|
|
6598
6776
|
activeAccountAuto: "Auto (first usable account)",
|
|
@@ -6663,6 +6841,8 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6663
6841
|
usageServiceUnavailableHint: "The server returned errors (5xx); try Refresh again later.",
|
|
6664
6842
|
usageNetworkError: "Could not reach the Command Code service",
|
|
6665
6843
|
usageNetworkHint: "No request reached the server. Check your network connection or the API base setting.",
|
|
6844
|
+
usageInvalidResponse: "Could not read the Command Code response",
|
|
6845
|
+
usageInvalidResponseHint: "The requests received responses, but their bodies could not be parsed. Check the host HTTP proxy or response decoding.",
|
|
6666
6846
|
usageUpdated: "Updated",
|
|
6667
6847
|
usagePeriodEnd: "Period ends",
|
|
6668
6848
|
usageActive: "Active",
|
|
@@ -6673,6 +6853,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6673
6853
|
updateHint: "A newer version has been published; click for release notes. The notice disappears once the plugin is updated.",
|
|
6674
6854
|
loginTitle: "Sign in to fetch a key",
|
|
6675
6855
|
loginHintIdle: "Rather not create a key by hand? Sign in and your browser opens the commandcode.ai authorization page; the approved key is stored in the local credential service and applies to the next request.",
|
|
6856
|
+
loginSaveBefore: "Save page changes before signing in to this account.",
|
|
6676
6857
|
loginButton: "Sign in to Command Code",
|
|
6677
6858
|
loginStarting: "Starting the local callback server…",
|
|
6678
6859
|
loginWaiting: "Waiting for authorization in your browser…",
|
|
@@ -6887,12 +7068,12 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6887
7068
|
const pricesStore = createSnapshotStore(pricesController.state());
|
|
6888
7069
|
pricesController.subscribe(() => pricesStore.set(pricesController.state()));
|
|
6889
7070
|
const loginRemote = {
|
|
6890
|
-
loginBegin: async () => {
|
|
7071
|
+
loginBegin: async (targetRef) => {
|
|
6891
7072
|
if (usageNamespace === void 0) return {
|
|
6892
7073
|
ok: false,
|
|
6893
7074
|
error: { message: usageMountError ?? "commandcode remote is not mounted" }
|
|
6894
7075
|
};
|
|
6895
|
-
return usageNamespace.loginBegin();
|
|
7076
|
+
return usageNamespace.loginBegin(targetRef);
|
|
6896
7077
|
},
|
|
6897
7078
|
loginStatus: async () => {
|
|
6898
7079
|
if (usageNamespace === void 0) return {
|
|
@@ -6936,7 +7117,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6936
7117
|
}),
|
|
6937
7118
|
discard: () => controller.discard(),
|
|
6938
7119
|
refreshUsage: () => void usageController.refresh(),
|
|
6939
|
-
beginLogin: () => void loginController.begin(),
|
|
7120
|
+
beginLogin: (targetRef) => void loginController.begin(targetRef),
|
|
6940
7121
|
cancelLogin: () => void loginController.cancel(),
|
|
6941
7122
|
addAccount: () => controller.addAccount(),
|
|
6942
7123
|
removeAccount: (id) => controller.removeAccount(id),
|