@mars-sea/dsh-commandcode-provider 0.11.10 → 0.11.12
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 +16 -0
- package/README.md +20 -17
- package/README.zh-CN.md +14 -17
- package/lib/client.js +225 -182
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +53 -84
- package/lib/index.js +307 -364
- package/lib/index.js.map +1 -1
- package/package.json +40 -48
package/lib/client.js
CHANGED
|
@@ -625,7 +625,6 @@ window.__ModuleLoader__.load({
|
|
|
625
625
|
listeners = /* @__PURE__ */ new Set();
|
|
626
626
|
disposers = [];
|
|
627
627
|
disposed = false;
|
|
628
|
-
defaultWorkingDir;
|
|
629
628
|
/** The credential reference the default account resolves. */
|
|
630
629
|
credentialRef = DEFAULT_API_KEY_REF;
|
|
631
630
|
/** Host-reported configured/writable state per credential reference. */
|
|
@@ -669,10 +668,8 @@ window.__ModuleLoader__.load({
|
|
|
669
668
|
/**
|
|
670
669
|
* @param scope - bound scope for the `llm-commandcode` namespace.
|
|
671
670
|
* @param api - credentials wire face.
|
|
672
|
-
* @param hostDescription - the Host-description observable whose `cwd` is
|
|
673
|
-
* shown as the placeholder a blank `workingDir` field resolves to.
|
|
674
671
|
*/
|
|
675
|
-
constructor(scope, api
|
|
672
|
+
constructor(scope, api) {
|
|
676
673
|
this.scope = scope;
|
|
677
674
|
this.api = api;
|
|
678
675
|
this.disposers.push(scope.subscribe(() => {
|
|
@@ -680,17 +677,6 @@ window.__ModuleLoader__.load({
|
|
|
680
677
|
this.describeAll();
|
|
681
678
|
this.publish();
|
|
682
679
|
}));
|
|
683
|
-
if (hostDescription !== void 0) {
|
|
684
|
-
this.defaultWorkingDir = hostDescription.getSnapshot()?.cwd;
|
|
685
|
-
this.disposers.push(hostDescription.subscribe(() => {
|
|
686
|
-
if (this.disposed) return;
|
|
687
|
-
const cwd = hostDescription.getSnapshot()?.cwd;
|
|
688
|
-
if (cwd !== this.defaultWorkingDir) {
|
|
689
|
-
this.defaultWorkingDir = cwd;
|
|
690
|
-
this.publish();
|
|
691
|
-
}
|
|
692
|
-
}));
|
|
693
|
-
}
|
|
694
680
|
this.recomputeCredentialRef();
|
|
695
681
|
this.describeAll();
|
|
696
682
|
this.refreshCatalog();
|
|
@@ -743,7 +729,6 @@ window.__ModuleLoader__.load({
|
|
|
743
729
|
apiKeyClearStaged: this.keyClears.has(this.credentialRef),
|
|
744
730
|
apiBase: this.field("apiBase"),
|
|
745
731
|
workingDir: this.field("workingDir"),
|
|
746
|
-
defaultWorkingDir: this.defaultWorkingDir,
|
|
747
732
|
requestTimeoutMs: this.field("requestTimeoutMs"),
|
|
748
733
|
streamIdleTimeoutMs: this.field("streamIdleTimeoutMs"),
|
|
749
734
|
transportMaxRetries: this.field("transportMaxRetries"),
|
|
@@ -1483,47 +1468,6 @@ window.__ModuleLoader__.load({
|
|
|
1483
1468
|
}
|
|
1484
1469
|
};
|
|
1485
1470
|
//#endregion
|
|
1486
|
-
//#region src/client/legacy-credentials.ts
|
|
1487
|
-
/** Convert a legacy credentials ApiProxy into the current settings-page face. */
|
|
1488
|
-
function adaptLegacyCredentials(legacy) {
|
|
1489
|
-
if (legacy === void 0) return void 0;
|
|
1490
|
-
return { credentials: {
|
|
1491
|
-
describe: async (refs) => {
|
|
1492
|
-
const response = await legacy.describe({ refs });
|
|
1493
|
-
return response.result.ok ? {
|
|
1494
|
-
ok: true,
|
|
1495
|
-
value: response.result.value.credentials
|
|
1496
|
-
} : {
|
|
1497
|
-
ok: false,
|
|
1498
|
-
error: response.result.error
|
|
1499
|
-
};
|
|
1500
|
-
},
|
|
1501
|
-
set: async (ref, value) => {
|
|
1502
|
-
const response = await legacy.set({
|
|
1503
|
-
ref,
|
|
1504
|
-
value
|
|
1505
|
-
});
|
|
1506
|
-
return response.result.ok ? {
|
|
1507
|
-
ok: true,
|
|
1508
|
-
value: void 0
|
|
1509
|
-
} : {
|
|
1510
|
-
ok: false,
|
|
1511
|
-
error: response.result.error
|
|
1512
|
-
};
|
|
1513
|
-
},
|
|
1514
|
-
unset: async (ref) => {
|
|
1515
|
-
const response = await legacy.unset({ ref });
|
|
1516
|
-
return response.result.ok ? {
|
|
1517
|
-
ok: true,
|
|
1518
|
-
value: void 0
|
|
1519
|
-
} : {
|
|
1520
|
-
ok: false,
|
|
1521
|
-
error: response.result.error
|
|
1522
|
-
};
|
|
1523
|
-
}
|
|
1524
|
-
} };
|
|
1525
|
-
}
|
|
1526
|
-
//#endregion
|
|
1527
1471
|
//#region src/client/usage.ts
|
|
1528
1472
|
const IDLE$1 = {
|
|
1529
1473
|
status: "idle",
|
|
@@ -1803,6 +1747,21 @@ window.__ModuleLoader__.load({
|
|
|
1803
1747
|
};
|
|
1804
1748
|
//#endregion
|
|
1805
1749
|
//#region src/client/login.ts
|
|
1750
|
+
/** Keep one account's login status out of every other account's row. */
|
|
1751
|
+
function loginStateForTarget(state, targetRef) {
|
|
1752
|
+
if (state.targetRef === targetRef) return {
|
|
1753
|
+
visible: state,
|
|
1754
|
+
busyElsewhere: false
|
|
1755
|
+
};
|
|
1756
|
+
return {
|
|
1757
|
+
visible: {
|
|
1758
|
+
...state,
|
|
1759
|
+
phase: "idle",
|
|
1760
|
+
authUrl: void 0
|
|
1761
|
+
},
|
|
1762
|
+
busyElsewhere: state.phase === "starting" || state.phase === "waiting"
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1806
1765
|
/** How often a live attempt is polled. */
|
|
1807
1766
|
const POLL_INTERVAL_MS = 1e3;
|
|
1808
1767
|
/**
|
|
@@ -1817,6 +1776,7 @@ window.__ModuleLoader__.load({
|
|
|
1817
1776
|
generation = 0;
|
|
1818
1777
|
disposed = false;
|
|
1819
1778
|
phase = "idle";
|
|
1779
|
+
targetRef;
|
|
1820
1780
|
authUrl;
|
|
1821
1781
|
userName;
|
|
1822
1782
|
keyName;
|
|
@@ -1835,6 +1795,7 @@ window.__ModuleLoader__.load({
|
|
|
1835
1795
|
state() {
|
|
1836
1796
|
return {
|
|
1837
1797
|
phase: this.phase,
|
|
1798
|
+
...this.targetRef === void 0 ? {} : { targetRef: this.targetRef },
|
|
1838
1799
|
authUrl: this.authUrl,
|
|
1839
1800
|
userName: this.userName,
|
|
1840
1801
|
keyName: this.keyName,
|
|
@@ -1843,9 +1804,10 @@ window.__ModuleLoader__.load({
|
|
|
1843
1804
|
};
|
|
1844
1805
|
}
|
|
1845
1806
|
/** Start (or rejoin) a login attempt and begin polling its status. */
|
|
1846
|
-
async begin() {
|
|
1807
|
+
async begin(targetRef) {
|
|
1847
1808
|
if (this.disposed || this.phase === "starting" || this.phase === "waiting") return;
|
|
1848
1809
|
const generation = ++this.generation;
|
|
1810
|
+
this.targetRef = targetRef;
|
|
1849
1811
|
this.set({
|
|
1850
1812
|
phase: "starting",
|
|
1851
1813
|
authUrl: void 0,
|
|
@@ -1868,7 +1830,7 @@ window.__ModuleLoader__.load({
|
|
|
1868
1830
|
}
|
|
1869
1831
|
let result;
|
|
1870
1832
|
try {
|
|
1871
|
-
result = await remote.loginBegin();
|
|
1833
|
+
result = await remote.loginBegin(targetRef);
|
|
1872
1834
|
} catch (error) {
|
|
1873
1835
|
result = {
|
|
1874
1836
|
ok: false,
|
|
@@ -2106,6 +2068,14 @@ window.__ModuleLoader__.load({
|
|
|
2106
2068
|
booleanField
|
|
2107
2069
|
};
|
|
2108
2070
|
}
|
|
2071
|
+
/** Use the same strict-codec shape for invocation parameters and results. */
|
|
2072
|
+
function makeStrictCodec(typeSymbol, schema) {
|
|
2073
|
+
return {
|
|
2074
|
+
mode: "strict",
|
|
2075
|
+
typeSymbol,
|
|
2076
|
+
create: () => schema
|
|
2077
|
+
};
|
|
2078
|
+
}
|
|
2109
2079
|
/**
|
|
2110
2080
|
* Build one strict invocation descriptor. Every Command Code Remote shares the
|
|
2111
2081
|
* `commandcode` namespace, the `commandcodeUsage` service, and a strict
|
|
@@ -2114,12 +2084,6 @@ window.__ModuleLoader__.load({
|
|
|
2114
2084
|
* only its own facts.
|
|
2115
2085
|
*/
|
|
2116
2086
|
function makeRemoteDescriptor(endpoint, method, typeSymbol, schema) {
|
|
2117
|
-
const result = {
|
|
2118
|
-
mode: "strict",
|
|
2119
|
-
typeSymbol,
|
|
2120
|
-
schema,
|
|
2121
|
-
create: () => schema
|
|
2122
|
-
};
|
|
2123
2087
|
return {
|
|
2124
2088
|
id: `${REMOTE_PACKAGE}#${endpoint}`,
|
|
2125
2089
|
service: REMOTE_SERVICE,
|
|
@@ -2127,7 +2091,7 @@ window.__ModuleLoader__.load({
|
|
|
2127
2091
|
method,
|
|
2128
2092
|
invocation: { kind: "direct" },
|
|
2129
2093
|
parameters: [],
|
|
2130
|
-
result
|
|
2094
|
+
result: makeStrictCodec(typeSymbol, schema)
|
|
2131
2095
|
};
|
|
2132
2096
|
}
|
|
2133
2097
|
//#endregion
|
|
@@ -2172,7 +2136,7 @@ window.__ModuleLoader__.load({
|
|
|
2172
2136
|
const report = { failures };
|
|
2173
2137
|
if (source.blocked !== void 0) {
|
|
2174
2138
|
const blocked = source.blocked;
|
|
2175
|
-
if (blocked === "invalid-key" || blocked === "service-unavailable" || blocked === "network") report.blocked = blocked;
|
|
2139
|
+
if (blocked === "invalid-key" || blocked === "service-unavailable" || blocked === "invalid-response" || blocked === "network") report.blocked = blocked;
|
|
2176
2140
|
else reject$1("blocked");
|
|
2177
2141
|
}
|
|
2178
2142
|
if (source.account !== void 0) {
|
|
@@ -2388,9 +2352,24 @@ window.__ModuleLoader__.load({
|
|
|
2388
2352
|
}
|
|
2389
2353
|
/** The strict result codec shared by all three login endpoints. */
|
|
2390
2354
|
const loginStatusSchema = { parse: parseLoginStatus };
|
|
2391
|
-
/**
|
|
2355
|
+
/** Optional account target; the Host still checks it against saved slots. */
|
|
2356
|
+
const loginTargetSchema = { parse(value) {
|
|
2357
|
+
if (value === void 0 || typeof value === "string") return value;
|
|
2358
|
+
return reject("targetRef");
|
|
2359
|
+
} };
|
|
2360
|
+
/** Build one login invocation descriptor. Only begin accepts an account ref. */
|
|
2392
2361
|
function loginDescriptor(endpoint, method) {
|
|
2393
|
-
|
|
2362
|
+
const descriptor = makeRemoteDescriptor(endpoint, method, `${REMOTE_PACKAGE}#CommandCodeLoginStatus`, loginStatusSchema);
|
|
2363
|
+
return method === "loginBegin" ? {
|
|
2364
|
+
...descriptor,
|
|
2365
|
+
parameters: [{
|
|
2366
|
+
name: "targetRef",
|
|
2367
|
+
wire: "targetRef",
|
|
2368
|
+
source: "json",
|
|
2369
|
+
codec: makeStrictCodec(`${REMOTE_PACKAGE}#CommandCodeLoginTargetRef`, loginTargetSchema),
|
|
2370
|
+
acceptsUndefined: true
|
|
2371
|
+
}]
|
|
2372
|
+
} : descriptor;
|
|
2394
2373
|
}
|
|
2395
2374
|
/** The Client-face contribution fragment mounted on `ctx.remote`. */
|
|
2396
2375
|
const LOGIN_REMOTE_CONTRIBUTION = {
|
|
@@ -2404,9 +2383,10 @@ window.__ModuleLoader__.load({
|
|
|
2404
2383
|
//#endregion
|
|
2405
2384
|
//#region src/client/login-row.tsx
|
|
2406
2385
|
/** The sign-in alternative to pasting a key (settings page + Models card). */
|
|
2407
|
-
function LoginRow({ state, disabled, t, onBegin, onCancel }) {
|
|
2408
|
-
const
|
|
2409
|
-
const
|
|
2386
|
+
function LoginRow({ state, targetRef, disabled, disabledHint, t, onBegin, onCancel }) {
|
|
2387
|
+
const { visible: visibleState, busyElsewhere } = loginStateForTarget(state, targetRef);
|
|
2388
|
+
const busy = visibleState.phase === "starting" || visibleState.phase === "waiting";
|
|
2389
|
+
const hint = loginHint(visibleState, t);
|
|
2410
2390
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2411
2391
|
className: "cc-field",
|
|
2412
2392
|
children: [
|
|
@@ -2425,17 +2405,17 @@ window.__ModuleLoader__.load({
|
|
|
2425
2405
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2426
2406
|
type: "button",
|
|
2427
2407
|
className: "cc-reset",
|
|
2428
|
-
disabled,
|
|
2408
|
+
disabled: disabled || busyElsewhere,
|
|
2429
2409
|
onClick: onBegin,
|
|
2430
2410
|
children: t("loginButton")
|
|
2431
2411
|
})
|
|
2432
2412
|
})]
|
|
2433
2413
|
}),
|
|
2434
|
-
|
|
2414
|
+
visibleState.authUrl !== void 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2435
2415
|
className: "cc-hint",
|
|
2436
2416
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2437
2417
|
className: "cc-loginLink",
|
|
2438
|
-
href:
|
|
2418
|
+
href: visibleState.authUrl,
|
|
2439
2419
|
target: "_blank",
|
|
2440
2420
|
rel: "noreferrer",
|
|
2441
2421
|
children: t("loginOpenLink")
|
|
@@ -2444,7 +2424,7 @@ window.__ModuleLoader__.load({
|
|
|
2444
2424
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2445
2425
|
className: hint.className,
|
|
2446
2426
|
title: hint.title,
|
|
2447
|
-
children: hint.text
|
|
2427
|
+
children: disabled && !busy && disabledHint !== void 0 ? disabledHint : hint.text
|
|
2448
2428
|
})
|
|
2449
2429
|
]
|
|
2450
2430
|
});
|
|
@@ -2593,7 +2573,7 @@ window.__ModuleLoader__.load({
|
|
|
2593
2573
|
}
|
|
2594
2574
|
//#endregion
|
|
2595
2575
|
//#region package.json
|
|
2596
|
-
var version = "0.11.
|
|
2576
|
+
var version = "0.11.12";
|
|
2597
2577
|
var repository = {
|
|
2598
2578
|
"type": "git",
|
|
2599
2579
|
"url": "git+https://github.com/Mars-Sea/dsh-commandcode-provider.git"
|
|
@@ -2915,7 +2895,6 @@ window.__ModuleLoader__.load({
|
|
|
2915
2895
|
hint: t("workingDirHint"),
|
|
2916
2896
|
state: state.workingDir,
|
|
2917
2897
|
disabled,
|
|
2918
|
-
placeholder: state.defaultWorkingDir,
|
|
2919
2898
|
onEdit: (text) => onEdit("workingDir", text),
|
|
2920
2899
|
onReset: () => onReset("workingDir"),
|
|
2921
2900
|
t
|
|
@@ -3398,12 +3377,14 @@ window.__ModuleLoader__.load({
|
|
|
3398
3377
|
function blockedTitle(reason, t) {
|
|
3399
3378
|
if (reason === "invalid-key") return t("usageKeyInvalid");
|
|
3400
3379
|
if (reason === "service-unavailable") return t("usageServiceUnavailable");
|
|
3380
|
+
if (reason === "invalid-response") return t("usageInvalidResponse");
|
|
3401
3381
|
return t("usageNetworkError");
|
|
3402
3382
|
}
|
|
3403
3383
|
/** The actionable hint under a blocked report's headline. */
|
|
3404
3384
|
function blockedHint(reason, t) {
|
|
3405
3385
|
if (reason === "invalid-key") return t("usageKeyInvalidHint");
|
|
3406
3386
|
if (reason === "service-unavailable") return t("usageServiceUnavailableHint");
|
|
3387
|
+
if (reason === "invalid-response") return t("usageInvalidResponseHint");
|
|
3407
3388
|
return t("usageNetworkHint");
|
|
3408
3389
|
}
|
|
3409
3390
|
/** The status dot on an account tab: cooling/invalid warn, everything else ok. */
|
|
@@ -3594,7 +3575,7 @@ window.__ModuleLoader__.load({
|
|
|
3594
3575
|
});
|
|
3595
3576
|
}
|
|
3596
3577
|
/** The multi-account card: the active-account selector + extra accounts in rotation order + add button. */
|
|
3597
|
-
function AccountsCard({ t, state, disabled, onAdd, onRemove, onLabel, onKey, onToggleClear, onActive, onActiveReset }) {
|
|
3578
|
+
function AccountsCard({ t, state, login, disabled, onAdd, onRemove, onLabel, onKey, onToggleClear, onActive, onActiveReset, onBeginLogin, onCancelLogin }) {
|
|
3598
3579
|
const active = state.activeAccount;
|
|
3599
3580
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3600
3581
|
className: "cc-card",
|
|
@@ -3672,14 +3653,31 @@ window.__ModuleLoader__.load({
|
|
|
3672
3653
|
})
|
|
3673
3654
|
]
|
|
3674
3655
|
}),
|
|
3675
|
-
state.accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3656
|
+
state.accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3657
|
+
className: "cc-accountEditor",
|
|
3658
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountRow, {
|
|
3659
|
+
account,
|
|
3660
|
+
disabled: disabled || login.targetRef === account.ref && (login.phase === "starting" || login.phase === "waiting"),
|
|
3661
|
+
t,
|
|
3662
|
+
onLabel: (text) => onLabel(account.id, text),
|
|
3663
|
+
onKey: (text) => onKey(account.id, text),
|
|
3664
|
+
onToggleClear: () => onToggleClear(account.id),
|
|
3665
|
+
onRemove: () => onRemove(account.id)
|
|
3666
|
+
}), account.added ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3667
|
+
className: "cc-accountLoginHint",
|
|
3668
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3669
|
+
className: "cc-hint",
|
|
3670
|
+
children: t("accountLoginAfterSave")
|
|
3671
|
+
})
|
|
3672
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoginRow, {
|
|
3673
|
+
state: login,
|
|
3674
|
+
targetRef: account.ref,
|
|
3675
|
+
disabled: disabled || !account.writable || state.dirty,
|
|
3676
|
+
disabledHint: state.dirty ? t("loginSaveBefore") : void 0,
|
|
3677
|
+
t,
|
|
3678
|
+
onBegin: () => onBeginLogin(account.ref),
|
|
3679
|
+
onCancel: onCancelLogin
|
|
3680
|
+
})]
|
|
3683
3681
|
}, account.id))
|
|
3684
3682
|
]
|
|
3685
3683
|
});
|
|
@@ -3991,6 +3989,8 @@ window.__ModuleLoader__.load({
|
|
|
3991
3989
|
/** The settings page body: connection facts for the Command Code provider. */
|
|
3992
3990
|
function CommandCodeSettingsPage(props) {
|
|
3993
3991
|
const { t } = props;
|
|
3992
|
+
const footerMarker = (0, react.useRef)(null);
|
|
3993
|
+
const [footerFloating, setFooterFloating] = (0, react.useState)(false);
|
|
3994
3994
|
const state = props.useCommandCodeSettings((snapshot) => snapshot);
|
|
3995
3995
|
const usage = props.useCommandCodeUsage((snapshot) => snapshot);
|
|
3996
3996
|
const login = props.useCommandCodeLogin((snapshot) => snapshot);
|
|
@@ -3998,6 +3998,15 @@ window.__ModuleLoader__.load({
|
|
|
3998
3998
|
const keyLocked = !state.apiKeyWritable;
|
|
3999
3999
|
const savedVisible = useSavedFlash(state.savedCount);
|
|
4000
4000
|
const updateVersion = usePluginUpdate();
|
|
4001
|
+
(0, react.useEffect)(() => {
|
|
4002
|
+
const marker = footerMarker.current;
|
|
4003
|
+
if (!marker || typeof IntersectionObserver === "undefined") return;
|
|
4004
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
4005
|
+
if (entry) setFooterFloating(!entry.isIntersecting);
|
|
4006
|
+
});
|
|
4007
|
+
observer.observe(marker);
|
|
4008
|
+
return () => observer.disconnect();
|
|
4009
|
+
}, []);
|
|
4001
4010
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
4002
4011
|
className: "cc-section",
|
|
4003
4012
|
"aria-label": t("title"),
|
|
@@ -4027,6 +4036,7 @@ window.__ModuleLoader__.load({
|
|
|
4027
4036
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountsCard, {
|
|
4028
4037
|
t,
|
|
4029
4038
|
state,
|
|
4039
|
+
login,
|
|
4030
4040
|
disabled,
|
|
4031
4041
|
onAdd: props.addAccount,
|
|
4032
4042
|
onRemove: props.removeAccount,
|
|
@@ -4034,7 +4044,9 @@ window.__ModuleLoader__.load({
|
|
|
4034
4044
|
onKey: props.editAccountKey,
|
|
4035
4045
|
onToggleClear: (id) => props.toggleKeyClear(id),
|
|
4036
4046
|
onActive: (text) => props.edit("activeAccount", text),
|
|
4037
|
-
onActiveReset: () => props.resetField("activeAccount")
|
|
4047
|
+
onActiveReset: () => props.resetField("activeAccount"),
|
|
4048
|
+
onBeginLogin: props.beginLogin,
|
|
4049
|
+
onCancelLogin: props.cancelLogin
|
|
4038
4050
|
}),
|
|
4039
4051
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RulesCard, {
|
|
4040
4052
|
t,
|
|
@@ -4058,7 +4070,7 @@ window.__ModuleLoader__.load({
|
|
|
4058
4070
|
label: t("apiKey"),
|
|
4059
4071
|
hint: keyLocked ? t("apiKeyLocked") : t("apiKeyHint"),
|
|
4060
4072
|
state: state.apiKey,
|
|
4061
|
-
disabled: disabled || keyLocked,
|
|
4073
|
+
disabled: disabled || keyLocked || login.targetRef === void 0 && (login.phase === "starting" || login.phase === "waiting"),
|
|
4062
4074
|
configured: state.apiKeyConfigured,
|
|
4063
4075
|
configuredLabel: t("apiKeySet"),
|
|
4064
4076
|
unconfiguredLabel: t("apiKeyUnset"),
|
|
@@ -4072,7 +4084,8 @@ window.__ModuleLoader__.load({
|
|
|
4072
4084
|
onToggleClear: () => props.toggleKeyClear("default")
|
|
4073
4085
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(LoginRow, {
|
|
4074
4086
|
state: login,
|
|
4075
|
-
disabled: disabled || keyLocked,
|
|
4087
|
+
disabled: disabled || keyLocked || state.dirty,
|
|
4088
|
+
disabledHint: state.dirty ? t("loginSaveBefore") : void 0,
|
|
4076
4089
|
t,
|
|
4077
4090
|
onBegin: props.beginLogin,
|
|
4078
4091
|
onCancel: props.cancelLogin
|
|
@@ -4085,34 +4098,42 @@ window.__ModuleLoader__.load({
|
|
|
4085
4098
|
onEdit: props.edit,
|
|
4086
4099
|
onReset: props.resetField
|
|
4087
4100
|
}),
|
|
4088
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4101
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4102
|
+
ref: footerMarker,
|
|
4103
|
+
className: "cc-footerMarker",
|
|
4104
|
+
"aria-hidden": "true"
|
|
4105
|
+
}),
|
|
4106
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4107
|
+
className: `cc-footer cc-footerSticky${footerFloating ? " cc-footerFloating" : ""}`,
|
|
4108
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4109
|
+
className: "cc-footerActions",
|
|
4110
|
+
children: [
|
|
4111
|
+
state.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4112
|
+
className: "cc-failed",
|
|
4113
|
+
role: "status",
|
|
4114
|
+
children: t("saveFailed")
|
|
4115
|
+
}) : null,
|
|
4116
|
+
savedVisible ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4117
|
+
className: "cc-saved",
|
|
4118
|
+
role: "status",
|
|
4119
|
+
children: t("saved")
|
|
4120
|
+
}) : null,
|
|
4121
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4122
|
+
variant: "ghost",
|
|
4123
|
+
size: "sm",
|
|
4124
|
+
disabled: !state.dirty || state.saving,
|
|
4125
|
+
onClick: props.discard,
|
|
4126
|
+
children: t("discard")
|
|
4127
|
+
}),
|
|
4128
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4129
|
+
variant: "primary",
|
|
4130
|
+
size: "sm",
|
|
4131
|
+
disabled: !state.dirty || state.invalid || state.saving,
|
|
4132
|
+
onClick: props.save,
|
|
4133
|
+
children: t(state.saving ? "saving" : "save")
|
|
4134
|
+
})
|
|
4135
|
+
]
|
|
4136
|
+
})
|
|
4116
4137
|
}),
|
|
4117
4138
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
4118
4139
|
className: "cc-version",
|
|
@@ -4399,6 +4420,8 @@ window.__ModuleLoader__.load({
|
|
|
4399
4420
|
errorServiceUnavailableHint: "服务端返回错误(5xx),请稍后点击刷新重试。",
|
|
4400
4421
|
errorNetwork: "无法连接 Command Code 服务",
|
|
4401
4422
|
errorNetworkHint: "所有请求都没有到达服务端。请检查网络连接或 API 地址设置。",
|
|
4423
|
+
errorInvalidResponse: "Command Code 响应无法读取",
|
|
4424
|
+
errorInvalidResponseHint: "请求已收到响应,但内容无法解析。请检查宿主的 HTTP 代理或响应解压配置。",
|
|
4402
4425
|
errorGeneric: "用量获取失败"
|
|
4403
4426
|
};
|
|
4404
4427
|
/** The panel's English string table (must mirror {@link PANEL_COPY_ZH}). */
|
|
@@ -4451,6 +4474,8 @@ window.__ModuleLoader__.load({
|
|
|
4451
4474
|
errorServiceUnavailableHint: "The server returned errors (5xx). Try Refresh again in a moment.",
|
|
4452
4475
|
errorNetwork: "Could not reach the Command Code service",
|
|
4453
4476
|
errorNetworkHint: "No request reached the server. Check your network connection or the API base setting.",
|
|
4477
|
+
errorInvalidResponse: "Could not read the Command Code response",
|
|
4478
|
+
errorInvalidResponseHint: "The requests received responses, but their bodies could not be parsed. Check the host HTTP proxy or response decoding.",
|
|
4454
4479
|
errorGeneric: "Could not fetch account usage"
|
|
4455
4480
|
};
|
|
4456
4481
|
/** Every panel key, in the English table's declaration order. */
|
|
@@ -4631,6 +4656,11 @@ window.__ModuleLoader__.load({
|
|
|
4631
4656
|
hint: "errorNetworkHint",
|
|
4632
4657
|
detail
|
|
4633
4658
|
};
|
|
4659
|
+
if (blocked === "invalid-response") return {
|
|
4660
|
+
title: "errorInvalidResponse",
|
|
4661
|
+
hint: "errorInvalidResponseHint",
|
|
4662
|
+
detail
|
|
4663
|
+
};
|
|
4634
4664
|
if (state.status === "error" && state.report === void 0) return {
|
|
4635
4665
|
title: "errorGeneric",
|
|
4636
4666
|
hint: "errorGeneric",
|
|
@@ -5701,15 +5731,15 @@ window.__ModuleLoader__.load({
|
|
|
5701
5731
|
/**
|
|
5702
5732
|
* The shipped composer stats row (dsh-client-ui-chat `StatsPills`).
|
|
5703
5733
|
*
|
|
5704
|
-
* A PREFERENCE, not a requirement:
|
|
5705
|
-
*
|
|
5706
|
-
* insisted on it would silently stop finding the row
|
|
5707
|
-
* absent the search falls back to the dock OUTLET — deliberately the outlet
|
|
5708
|
-
* never the outlet's parent, because
|
|
5709
|
-
*
|
|
5710
|
-
*
|
|
5711
|
-
*
|
|
5712
|
-
*
|
|
5734
|
+
* A PREFERENCE, not a requirement: the attribute has already been dropped once
|
|
5735
|
+
* upstream (0.1.6-alpha.2) while the rest of the row's markup stayed identical,
|
|
5736
|
+
* so a lookup that insisted on it would silently stop finding the row. When it
|
|
5737
|
+
* is absent the search falls back to the dock OUTLET — deliberately the outlet
|
|
5738
|
+
* and never the outlet's parent, because the parent is the composer footer,
|
|
5739
|
+
* which holds the `ContextMeter` as well, and that meter's trigger is itself a
|
|
5740
|
+
* `button[aria-haspopup="dialog"]` rendered AFTER the dock. A parent-scoped
|
|
5741
|
+
* "last trigger wins" would therefore append the cost to the context ring
|
|
5742
|
+
* instead of the token pill.
|
|
5713
5743
|
*/
|
|
5714
5744
|
const STATS_ROOT = "[data-composer-stats]";
|
|
5715
5745
|
/**
|
|
@@ -5846,14 +5876,14 @@ window.__ModuleLoader__.load({
|
|
|
5846
5876
|
*
|
|
5847
5877
|
* The scope is the dock OUTLET (`display: contents`, one per slot), which holds
|
|
5848
5878
|
* exactly that slot's entries — the shipped `stats` cell and ours, in their
|
|
5849
|
-
* registration order. {@link STATS_ROOT} narrows that to the stats row
|
|
5850
|
-
*
|
|
5851
|
-
*
|
|
5852
|
-
*
|
|
5879
|
+
* registration order. {@link STATS_ROOT} narrows that to the stats row where
|
|
5880
|
+
* the markup marks it; where it does not, the outlet is already the narrowest
|
|
5881
|
+
* correct container, because the composer footer's `ContextMeter` sits BESIDE
|
|
5882
|
+
* the outlet rather than inside it.
|
|
5853
5883
|
*
|
|
5854
5884
|
* A missing scope is "no pill", never a document-wide search: the outlet is
|
|
5855
5885
|
* what makes this lookup per-composer, and a second composer can be live at
|
|
5856
|
-
* once (
|
|
5886
|
+
* once (the sidebar can mount an embedded Conversation).
|
|
5857
5887
|
*/
|
|
5858
5888
|
resolvePillButton() {
|
|
5859
5889
|
const scope = this.scope();
|
|
@@ -6203,9 +6233,18 @@ window.__ModuleLoader__.load({
|
|
|
6203
6233
|
.cc-ruleCaret{flex-shrink:0;border-right:1.5px solid var(--dsw-alias-label-tertiary);border-bottom:1.5px solid var(--dsw-alias-label-tertiary);width:6px;height:6px;margin-right:4px;margin-bottom:2px;transform:rotate(45deg)}
|
|
6204
6234
|
.cc-checkRow{align-items:center;gap:8px;display:inline-flex;min-width:0}
|
|
6205
6235
|
.cc-checkRow:hover{cursor:pointer}
|
|
6206
|
-
|
|
6236
|
+
/* A hand-drawn box rather than the platform's accent-color checkbox: the
|
|
6237
|
+
* native control's colours come from color-scheme, which the theme sets once
|
|
6238
|
+
* at BOOT (it is not re-applied when the theme is switched in-session), so a
|
|
6239
|
+
* native box can paint light-chrome white on a dark page. Drawn from tokens it
|
|
6240
|
+
* cannot. The mark rides a brand-primary fill, so it takes the theme's brand
|
|
6241
|
+
* foreground — the platform's pairing for anything painted on that fill, and
|
|
6242
|
+
* the only one that survives the dark mode's near-white brand. The box
|
|
6243
|
+
* outline is a border-l3 hairline: border-l2 (#ffffff1f in dark) leaves an
|
|
6244
|
+
* unchecked box all but invisible against the menu surface. */
|
|
6245
|
+
.cc-check{box-sizing:border-box;appearance:none;flex-shrink:0;width:16px;height:16px;margin:0;border:1px solid var(--dsw-alias-border-l3);border-radius:4px;background:0 0;position:relative}
|
|
6207
6246
|
.cc-check:checked{background:var(--dsw-alias-brand-primary);border-color:var(--dsw-alias-brand-primary)}
|
|
6208
|
-
.cc-check:checked::after{content:'';position:absolute;top:
|
|
6247
|
+
.cc-check:checked::after{content:'';position:absolute;top:3px;left:5px;width:3px;height:7px;border:solid var(--dsw-alias-label-primary-foreground,#fff);border-width:0 1.5px 1.5px 0;transform:rotate(45deg)}
|
|
6209
6248
|
.cc-checkName{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
6210
6249
|
/* The model multi-select search box: stacked under the trigger while the
|
|
6211
6250
|
* dropdown is open, same input sizing so the pair reads as one control. The
|
|
@@ -6235,12 +6274,38 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6235
6274
|
.cc-advancedBody>.cc-field:first-of-type{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
6236
6275
|
.cc-hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}
|
|
6237
6276
|
.cc-footer{justify-content:flex-end;align-items:center;gap:8px;display:flex}
|
|
6277
|
+
/* Keep the original footer in flow and inside the settings scrollport. */
|
|
6278
|
+
.cc-footerMarker{height:1px;margin:-6px 0 -7px;pointer-events:none}
|
|
6279
|
+
.cc-footerSticky{position:sticky;bottom:0;z-index:2;flex-shrink:0;min-height:48px;pointer-events:none}
|
|
6280
|
+
.cc-footerActions{align-items:center;gap:8px;display:flex;pointer-events:auto}
|
|
6281
|
+
.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)}
|
|
6282
|
+
.cc-accountEditor{border-top:1px solid var(--dsw-alias-border-l2)}
|
|
6283
|
+
.cc-accountLoginHint{padding:0 0 12px}
|
|
6238
6284
|
.cc-toggleRow{align-items:center;gap:8px;cursor:pointer;display:flex}
|
|
6239
6285
|
.cc-toggleRow:has(.cc-toggle:disabled){cursor:default}
|
|
6240
|
-
|
|
6286
|
+
/* Modelled on the platform's own Switch primitive (ui-primitives
|
|
6287
|
+
* Switch.module.css, dsh 0.1.6+): a 36x20 capsule that pads its track by 2px
|
|
6288
|
+
* and slides a 16px thumb across the 32px content box, so the control is the
|
|
6289
|
+
* same shape, size and motion as every other switch in the app.
|
|
6290
|
+
*
|
|
6291
|
+
* Three things are load-bearing. (1) corner-shape:round on BOTH the track and
|
|
6292
|
+
* the thumb: the theme sets a global superellipse corner shape on every
|
|
6293
|
+
* element, and a superellipse capsule squares its ends off around a round
|
|
6294
|
+
* thumb (the primitive's own comment is about exactly this).
|
|
6295
|
+
* (2) No literal colours. --dsw-alias-brand-primary INVERTS between the two
|
|
6296
|
+
* modes (near-black in light, near-white in dark, on every engine generation
|
|
6297
|
+
* this plugin supports), so the old hardcoded white thumb vanished on the
|
|
6298
|
+
* checked track in dark mode; the brand foreground is the token the platform
|
|
6299
|
+
* paints on that fill, so it contrasts in both modes and in any brand pack.
|
|
6300
|
+
* (3) --dsw-alias-border-l3 as the off track: --dsw-alias-border-l2
|
|
6301
|
+
* (#ffffff1f in dark) left the unchecked track indistinguishable from the card
|
|
6302
|
+
* — the dark-mode half of the same report. */
|
|
6303
|
+
.cc-toggle{box-sizing:border-box;appearance:none;flex-shrink:0;width:36px;height:20px;margin:0;padding:2px;border:0;border-radius:10px;corner-shape:round;background:var(--dsw-alias-border-l3);cursor:pointer;position:relative}
|
|
6241
6304
|
.cc-toggle:checked{background:var(--dsw-alias-brand-primary)}
|
|
6242
|
-
.cc-toggle::after{content:'';
|
|
6243
|
-
.
|
|
6305
|
+
.cc-toggle::after{content:'';display:block;width:16px;height:16px;border-radius:50%;corner-shape:round;background:var(--dsw-alias-label-primary-foreground);box-shadow:0 0 0 .5px var(--dsw-alias-border-l2);transition:transform .12s ease}
|
|
6306
|
+
/* 32px content box minus the 16px thumb. */
|
|
6307
|
+
.cc-toggle:checked::after{transform:translateX(16px)}
|
|
6308
|
+
.cc-toggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
6244
6309
|
.cc-toggle:disabled{cursor:default;opacity:.5}
|
|
6245
6310
|
.cc-failed{min-width:0;color:var(--dsw-alias-label-error);flex:1;margin:0;font-size:12px;line-height:1.5}
|
|
6246
6311
|
.cc-usageCard{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;flex-direction:column;gap:12px;display:flex}
|
|
@@ -6268,7 +6333,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6268
6333
|
.cc-usageBar{overflow:hidden;background:var(--dsw-alias-bg-layer-1);border-radius:999px;height:6px}
|
|
6269
6334
|
.cc-usageBarFill{background:var(--dsw-alias-brand-primary);border-radius:999px;height:100%;transition:width .3s ease}
|
|
6270
6335
|
.cc-usageBarFillWarn{background:var(--dsw-alias-label-error)}
|
|
6271
|
-
@media (prefers-reduced-motion:reduce){.cc-chevron,.cc-toggle
|
|
6336
|
+
@media (prefers-reduced-motion:reduce){.cc-chevron,.cc-toggle::after,.cc-usageBarFill{transition:none}}.cc-usageWindowReset{color:var(--dsw-alias-label-tertiary);margin:0;font-size:11px;line-height:1.5}
|
|
6272
6337
|
.cc-usageMeta{align-items:center;gap:8px;display:flex}
|
|
6273
6338
|
.cc-accountReport{flex-direction:column;gap:12px;display:flex}
|
|
6274
6339
|
.cc-tabs{flex-wrap:wrap;gap:6px;display:flex}
|
|
@@ -6526,6 +6591,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6526
6591
|
accountLabel: "账户备注名",
|
|
6527
6592
|
accountKey: "API 密钥",
|
|
6528
6593
|
accountKeyHint: "该账户的 API 密钥。留空保存不会覆盖已存储的密钥。",
|
|
6594
|
+
accountLoginAfterSave: "先点击页面底部的「保存」,再点击该账户的「登录 Command Code」通过网页获取密钥。",
|
|
6529
6595
|
accountDefault: "默认账户",
|
|
6530
6596
|
activeAccount: "当前使用账户",
|
|
6531
6597
|
activeAccountAuto: "自动(第一个可用账户)",
|
|
@@ -6596,6 +6662,8 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6596
6662
|
usageServiceUnavailableHint: "服务端返回了错误(5xx),稍后点击刷新重试。",
|
|
6597
6663
|
usageNetworkError: "无法连接 Command Code 服务",
|
|
6598
6664
|
usageNetworkHint: "所有请求都没有到达服务端。请检查网络连接或 API 地址设置。",
|
|
6665
|
+
usageInvalidResponse: "Command Code 响应无法读取",
|
|
6666
|
+
usageInvalidResponseHint: "请求已收到响应,但内容无法解析。请检查宿主的 HTTP 代理或响应解压配置。",
|
|
6599
6667
|
usageUpdated: "更新于",
|
|
6600
6668
|
usagePeriodEnd: "账期截止",
|
|
6601
6669
|
usageActive: "当前使用",
|
|
@@ -6606,6 +6674,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6606
6674
|
updateHint: "已发布新版本,点击查看发布说明;更新插件后刷新本页,提示会自动消失。",
|
|
6607
6675
|
loginTitle: "通过官方登录获取密钥",
|
|
6608
6676
|
loginHintIdle: "不想手动创建密钥?点击登录后浏览器会打开 commandcode.ai 授权页,完成后密钥自动写入本机凭据服务,下次请求即生效。",
|
|
6677
|
+
loginSaveBefore: "请先保存本页更改,再通过网页登录此账户。",
|
|
6609
6678
|
loginButton: "登录 Command Code",
|
|
6610
6679
|
loginStarting: "正在启动本地回调服务…",
|
|
6611
6680
|
loginWaiting: "等待在浏览器中完成授权…",
|
|
@@ -6623,7 +6692,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6623
6692
|
cardTitle: "Command Code",
|
|
6624
6693
|
cardRouteActive: "已启用",
|
|
6625
6694
|
cardLoadingHint: "正在读取 Command Code 配置…",
|
|
6626
|
-
cardRegistrationHint: "
|
|
6695
|
+
cardRegistrationHint: "此卡片由 Command Code 插件提供,正在等待设置页装配,稍后即可显示完整内容。"
|
|
6627
6696
|
};
|
|
6628
6697
|
const en = {
|
|
6629
6698
|
nav: "Command Code",
|
|
@@ -6670,6 +6739,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6670
6739
|
accountLabel: "Account label",
|
|
6671
6740
|
accountKey: "API key",
|
|
6672
6741
|
accountKeyHint: "This account’s API key. Saving with the field blank keeps the stored key.",
|
|
6742
|
+
accountLoginAfterSave: "Use Save at the bottom of the page, then sign in to this account in your browser to obtain a key.",
|
|
6673
6743
|
accountDefault: "Default account",
|
|
6674
6744
|
activeAccount: "Active account",
|
|
6675
6745
|
activeAccountAuto: "Auto (first usable account)",
|
|
@@ -6740,6 +6810,8 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6740
6810
|
usageServiceUnavailableHint: "The server returned errors (5xx); try Refresh again later.",
|
|
6741
6811
|
usageNetworkError: "Could not reach the Command Code service",
|
|
6742
6812
|
usageNetworkHint: "No request reached the server. Check your network connection or the API base setting.",
|
|
6813
|
+
usageInvalidResponse: "Could not read the Command Code response",
|
|
6814
|
+
usageInvalidResponseHint: "The requests received responses, but their bodies could not be parsed. Check the host HTTP proxy or response decoding.",
|
|
6743
6815
|
usageUpdated: "Updated",
|
|
6744
6816
|
usagePeriodEnd: "Period ends",
|
|
6745
6817
|
usageActive: "Active",
|
|
@@ -6750,6 +6822,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6750
6822
|
updateHint: "A newer version has been published; click for release notes. The notice disappears once the plugin is updated.",
|
|
6751
6823
|
loginTitle: "Sign in to fetch a key",
|
|
6752
6824
|
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.",
|
|
6825
|
+
loginSaveBefore: "Save page changes before signing in to this account.",
|
|
6753
6826
|
loginButton: "Sign in to Command Code",
|
|
6754
6827
|
loginStarting: "Starting the local callback server…",
|
|
6755
6828
|
loginWaiting: "Waiting for authorization in your browser…",
|
|
@@ -6767,7 +6840,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6767
6840
|
cardTitle: "Command Code",
|
|
6768
6841
|
cardRouteActive: "Active",
|
|
6769
6842
|
cardLoadingHint: "Loading the Command Code configuration…",
|
|
6770
|
-
cardRegistrationHint: "This card is contributed by the Command Code plugin
|
|
6843
|
+
cardRegistrationHint: "This card is contributed by the Command Code plugin and is waiting for the settings page to finish assembling."
|
|
6771
6844
|
};
|
|
6772
6845
|
//#endregion
|
|
6773
6846
|
//#region src/client/index.ts
|
|
@@ -6807,15 +6880,6 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6807
6880
|
*/
|
|
6808
6881
|
const PANEL_ID = "commandcode-panel";
|
|
6809
6882
|
/**
|
|
6810
|
-
* ui-conversation's reserved `main` key, used only as the exit fallback for a
|
|
6811
|
-
* layout whose `selectPanel` predates the `null` "show the Conversation"
|
|
6812
|
-
* selection (see `close` in {@link applyClientSurfaces}). Declared locally for
|
|
6813
|
-
* the same reason as {@link PANEL_ID}: ui-conversation is not a dependency of
|
|
6814
|
-
* this bundle, and the key is a published contract of the layout (its README
|
|
6815
|
-
* names `conversation` as reserved for the Conversation).
|
|
6816
|
-
*/
|
|
6817
|
-
const CONVERSATION_PANEL_ID = "conversation";
|
|
6818
|
-
/**
|
|
6819
6883
|
* The composer figure's entry id in `conversation.composer.dock`. Its own id,
|
|
6820
6884
|
* not the shipped `stats` cell's: reusing `stats` would REPLACE the tokens /
|
|
6821
6885
|
* cache-hit / throughput readout rather than inject into it, and that readout
|
|
@@ -6823,12 +6887,10 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6823
6887
|
*/
|
|
6824
6888
|
const SESSION_COST_ID = "commandcode-session-cost";
|
|
6825
6889
|
/**
|
|
6826
|
-
* Client plugin body. Gates on
|
|
6827
|
-
*
|
|
6828
|
-
*
|
|
6829
|
-
*
|
|
6830
|
-
* appears; legacy clients mount it from the connection ApiProxy credential
|
|
6831
|
-
* face.
|
|
6890
|
+
* Client plugin body. Gates on `slots`, `locale` and `remote` — never on
|
|
6891
|
+
* `settingsScope`, whose wrapper service the 0.1.7 settings rewrite removed
|
|
6892
|
+
* (the settings scope here speaks the `remote.settings` wire directly). The
|
|
6893
|
+
* page mounts once `remote.credentials` appears.
|
|
6832
6894
|
*/
|
|
6833
6895
|
function apply(ctx) {
|
|
6834
6896
|
injectPageCss();
|
|
@@ -6840,19 +6902,13 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6840
6902
|
zh: PANEL_COPY_ZH,
|
|
6841
6903
|
en: PANEL_COPY_EN
|
|
6842
6904
|
}), "dsh-commandcode-provider: panel copy");
|
|
6843
|
-
const connection = ctx.get("connection");
|
|
6844
|
-
const legacyApi = adaptLegacyCredentials(connection?.api?.credentials);
|
|
6845
|
-
if (legacyApi !== void 0) {
|
|
6846
|
-
applyClientSurfaces(ctx, legacyApi, connection?.hostDescription);
|
|
6847
|
-
return;
|
|
6848
|
-
}
|
|
6849
6905
|
ctx.inject(["remote.credentials"], (remoteCtx) => {
|
|
6850
6906
|
const credentials = remoteCtx.remote.credentials;
|
|
6851
6907
|
applyClientSurfaces(remoteCtx, { credentials });
|
|
6852
6908
|
});
|
|
6853
6909
|
}
|
|
6854
|
-
/** Mount the one shared UI implementation
|
|
6855
|
-
function applyClientSurfaces(ctx, api
|
|
6910
|
+
/** Mount the one shared UI implementation. */
|
|
6911
|
+
function applyClientSurfaces(ctx, api) {
|
|
6856
6912
|
let settingsNamespace;
|
|
6857
6913
|
const scope = createSettingsScope(ctx, COMMANDCODE_NS, () => settingsNamespace);
|
|
6858
6914
|
ctx.effect(() => () => {
|
|
@@ -6872,7 +6928,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6872
6928
|
ok: false,
|
|
6873
6929
|
error: { message: "commandcode/models remote is not mounted" }
|
|
6874
6930
|
})
|
|
6875
|
-
}
|
|
6931
|
+
});
|
|
6876
6932
|
ctx.effect(() => () => controller.dispose(), "dsh-commandcode-provider: settings controller");
|
|
6877
6933
|
const store = createSnapshotStore(controller.state());
|
|
6878
6934
|
controller.subscribe(() => store.set(controller.state()));
|
|
@@ -6964,12 +7020,12 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
6964
7020
|
const pricesStore = createSnapshotStore(pricesController.state());
|
|
6965
7021
|
pricesController.subscribe(() => pricesStore.set(pricesController.state()));
|
|
6966
7022
|
const loginRemote = {
|
|
6967
|
-
loginBegin: async () => {
|
|
7023
|
+
loginBegin: async (targetRef) => {
|
|
6968
7024
|
if (usageNamespace === void 0) return {
|
|
6969
7025
|
ok: false,
|
|
6970
7026
|
error: { message: usageMountError ?? "commandcode remote is not mounted" }
|
|
6971
7027
|
};
|
|
6972
|
-
return usageNamespace.loginBegin();
|
|
7028
|
+
return usageNamespace.loginBegin(targetRef);
|
|
6973
7029
|
},
|
|
6974
7030
|
loginStatus: async () => {
|
|
6975
7031
|
if (usageNamespace === void 0) return {
|
|
@@ -7013,7 +7069,7 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
7013
7069
|
}),
|
|
7014
7070
|
discard: () => controller.discard(),
|
|
7015
7071
|
refreshUsage: () => void usageController.refresh(),
|
|
7016
|
-
beginLogin: () => void loginController.begin(),
|
|
7072
|
+
beginLogin: (targetRef) => void loginController.begin(targetRef),
|
|
7017
7073
|
cancelLogin: () => void loginController.cancel(),
|
|
7018
7074
|
addAccount: () => controller.addAccount(),
|
|
7019
7075
|
removeAccount: (id) => controller.removeAccount(id),
|
|
@@ -7065,21 +7121,10 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
7065
7121
|
},
|
|
7066
7122
|
startAutoRefresh: () => startPanelAutoRefresh(usageController, () => true),
|
|
7067
7123
|
open: () => {
|
|
7068
|
-
|
|
7069
|
-
if (typeof layout?.selectPanel === "function") layout.selectPanel(PANEL_ID);
|
|
7124
|
+
ctx.get("layout")?.selectPanel(PANEL_ID);
|
|
7070
7125
|
},
|
|
7071
7126
|
close: () => {
|
|
7072
|
-
|
|
7073
|
-
if (typeof layout?.selectPanel !== "function") return;
|
|
7074
|
-
try {
|
|
7075
|
-
layout.selectPanel(null);
|
|
7076
|
-
} catch {
|
|
7077
|
-
try {
|
|
7078
|
-
layout.selectPanel(CONVERSATION_PANEL_ID);
|
|
7079
|
-
} catch (error) {
|
|
7080
|
-
console.error("[dsh-commandcode-provider] could not close the plans & quota panel:", error);
|
|
7081
|
-
}
|
|
7082
|
-
}
|
|
7127
|
+
ctx.get("layout")?.selectPanel(null);
|
|
7083
7128
|
}
|
|
7084
7129
|
});
|
|
7085
7130
|
ctx.effect(() => injectPanelCss(), "dsh-commandcode-provider: panel styles");
|
|
@@ -7094,7 +7139,6 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
7094
7139
|
console.error("[dsh-commandcode-provider] could not register the plans & quota panel:", error);
|
|
7095
7140
|
}
|
|
7096
7141
|
ctx.inject(["layout"], (layoutCtx) => {
|
|
7097
|
-
if (typeof layoutCtx.get("layout")?.selectPanel !== "function") return;
|
|
7098
7142
|
try {
|
|
7099
7143
|
layoutCtx.slots.inject("sidebar.footer.action", () => layoutCtx.slots.register({
|
|
7100
7144
|
name: "sidebar.footer.action",
|
|
@@ -7121,7 +7165,6 @@ select.cc-input{appearance:none;-webkit-appearance:none;-moz-appearance:none;box
|
|
|
7121
7165
|
const inject = [
|
|
7122
7166
|
"slots",
|
|
7123
7167
|
"locale",
|
|
7124
|
-
"connection",
|
|
7125
7168
|
"remote"
|
|
7126
7169
|
];
|
|
7127
7170
|
//#endregion
|