dsh-modellix 0.1.0 → 0.1.1
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 +13 -0
- package/README.md +14 -17
- package/README.zh-CN.md +14 -17
- package/docs/assets/design-desktop-en.webp +0 -0
- package/docs/assets/design-desktop-zh.webp +0 -0
- package/docs/assets/design-proposal-en.webp +0 -0
- package/docs/assets/design-proposal-zh.webp +0 -0
- package/docs/assets/design-results-media-en.webp +0 -0
- package/docs/assets/design-results-media-zh.webp +0 -0
- package/docs/assets/llm-model-selector-en.webp +0 -0
- package/docs/assets/llm-model-selector-zh.webp +0 -0
- package/docs/assets/settings-ready-en.webp +0 -0
- package/docs/assets/settings-ready-zh.webp +0 -0
- package/docs/assets/web-tools-en.webp +0 -0
- package/docs/assets/web-tools-zh.webp +0 -0
- package/docs/en-US/LOCAL_USAGE.md +3 -3
- package/docs/en-US/USER_GUIDE.md +18 -24
- package/docs/zh-CN/LOCAL_USAGE.md +3 -3
- package/docs/zh-CN/USER_GUIDE.md +18 -24
- package/lib/client.js +37 -15
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
- package/docs/assets/credential-recovery.webp +0 -0
- package/docs/assets/design-desktop.webp +0 -0
- package/docs/assets/design-mobile-en.webp +0 -0
- package/docs/assets/design-proposal.webp +0 -0
- package/docs/assets/design-results-media.webp +0 -0
- package/docs/assets/llm-model-selector.webp +0 -0
- package/docs/assets/onboarding-defaults.webp +0 -0
- package/docs/assets/settings-ready.webp +0 -0
- package/docs/assets/web-tools.webp +0 -0
package/lib/client.js
CHANGED
|
@@ -911,7 +911,7 @@ const MODAL_DIALOG_SELECTOR = "[role=\"dialog\"][aria-modal=\"true\"]";
|
|
|
911
911
|
* therefore uses only the ARIA modal contract and a marker owned by this
|
|
912
912
|
* plugin; it does not depend on host classes or DOM structure.
|
|
913
913
|
*/
|
|
914
|
-
function useExternalDialogGate(requestedOpen) {
|
|
914
|
+
function useExternalDialogGate(requestedOpen, externalDialogOwner) {
|
|
915
915
|
const [decision, setDecision] = (0, react.useState)({
|
|
916
916
|
requestedOpen: false,
|
|
917
917
|
allowed: false
|
|
@@ -931,7 +931,7 @@ function useExternalDialogGate(requestedOpen) {
|
|
|
931
931
|
const reconcile = () => {
|
|
932
932
|
reconciliationQueued = false;
|
|
933
933
|
if (disposed) return;
|
|
934
|
-
const allowed = !hasVisibleExternalDialog(ownerDocument);
|
|
934
|
+
const allowed = !hasVisibleExternalDialog(ownerDocument, resolveExternalDialogOwner(externalDialogOwner));
|
|
935
935
|
setDecision((current) => current.requestedOpen && current.allowed === allowed ? current : {
|
|
936
936
|
requestedOpen: true,
|
|
937
937
|
allowed
|
|
@@ -962,12 +962,12 @@ function useExternalDialogGate(requestedOpen) {
|
|
|
962
962
|
disposed = true;
|
|
963
963
|
observer?.disconnect();
|
|
964
964
|
};
|
|
965
|
-
}, [requestedOpen]);
|
|
965
|
+
}, [externalDialogOwner, requestedOpen]);
|
|
966
966
|
return requestedOpen && decision.requestedOpen && decision.allowed;
|
|
967
967
|
}
|
|
968
968
|
/** Adds the focus behavior intentionally absent from the public Modal primitive. */
|
|
969
969
|
function useDialogA11y(options) {
|
|
970
|
-
const { open, container, initialFocusSelector, mandatory, onEscape } = options;
|
|
970
|
+
const { open, container, externalDialogOwner, initialFocusSelector, mandatory, onEscape } = options;
|
|
971
971
|
const onEscapeRef = (0, react.useRef)(onEscape);
|
|
972
972
|
const restoreTargetRef = (0, react.useRef)(null);
|
|
973
973
|
onEscapeRef.current = onEscape;
|
|
@@ -1019,13 +1019,14 @@ function useDialogA11y(options) {
|
|
|
1019
1019
|
document.removeEventListener("keydown", onKeyDown, true);
|
|
1020
1020
|
unlockInert();
|
|
1021
1021
|
unlockScroll();
|
|
1022
|
-
if (!hasVisibleExternalDialog(document)) {
|
|
1022
|
+
if (!hasVisibleExternalDialog(document, resolveExternalDialogOwner(externalDialogOwner))) {
|
|
1023
1023
|
restoreFocus(restoreTargetRef.current, dialogRoot, appRoot);
|
|
1024
1024
|
restoreTargetRef.current = null;
|
|
1025
1025
|
}
|
|
1026
1026
|
};
|
|
1027
1027
|
}, [
|
|
1028
1028
|
container,
|
|
1029
|
+
externalDialogOwner,
|
|
1029
1030
|
initialFocusSelector,
|
|
1030
1031
|
mandatory,
|
|
1031
1032
|
open
|
|
@@ -1111,8 +1112,11 @@ function restoreFocus(previous, dialog, appRoot) {
|
|
|
1111
1112
|
if (fallback !== void 0 && focus(fallback)) return;
|
|
1112
1113
|
}
|
|
1113
1114
|
}
|
|
1114
|
-
function hasVisibleExternalDialog(ownerDocument) {
|
|
1115
|
-
return [...ownerDocument.querySelectorAll(MODAL_DIALOG_SELECTOR)].some((candidate) => candidate.querySelector(MODELLIX_DIALOG_SENTINEL) === null && isVisibleDialog(candidate));
|
|
1115
|
+
function hasVisibleExternalDialog(ownerDocument, allowedOwner = null) {
|
|
1116
|
+
return [...ownerDocument.querySelectorAll(MODAL_DIALOG_SELECTOR)].some((candidate) => candidate !== allowedOwner && candidate.querySelector(MODELLIX_DIALOG_SENTINEL) === null && isVisibleDialog(candidate));
|
|
1117
|
+
}
|
|
1118
|
+
function resolveExternalDialogOwner(owner) {
|
|
1119
|
+
return owner?.current?.closest(MODAL_DIALOG_SELECTOR) ?? null;
|
|
1116
1120
|
}
|
|
1117
1121
|
function isVisibleDialog(candidate) {
|
|
1118
1122
|
if (candidate.tagName === "DIALOG" && !candidate.hasAttribute("open")) return false;
|
|
@@ -1276,7 +1280,7 @@ function CredentialStatus({ configured, source, verification, t }) {
|
|
|
1276
1280
|
});
|
|
1277
1281
|
}
|
|
1278
1282
|
function CredentialModal(props) {
|
|
1279
|
-
const { open, mandatory, title, description, services, onServicesChange, busy, errorCode, onSave, onSaved, onCancel, laterLabel = "cancel", t } = props;
|
|
1283
|
+
const { open, mandatory, title, description, services, onServicesChange, busy, errorCode, onSave, onSaved, onCancel, laterLabel = "cancel", t, externalDialogOwner } = props;
|
|
1280
1284
|
const [draft, setDraft] = (0, react.useState)("");
|
|
1281
1285
|
const [visible, setVisible] = (0, react.useState)(false);
|
|
1282
1286
|
const [displayedErrorCode, setDisplayedErrorCode] = (0, react.useState)(errorCode);
|
|
@@ -1286,7 +1290,7 @@ function CredentialModal(props) {
|
|
|
1286
1290
|
const helpId = `${keyId}-help`;
|
|
1287
1291
|
const errorId = `${keyId}-error`;
|
|
1288
1292
|
const errorPresentation = displayedErrorCode === null ? null : presentClientError(displayedErrorCode);
|
|
1289
|
-
const surfaceOpen = useExternalDialogGate(open);
|
|
1293
|
+
const surfaceOpen = useExternalDialogGate(open, externalDialogOwner);
|
|
1290
1294
|
const clear = (0, react.useCallback)(() => {
|
|
1291
1295
|
draftRef.current = "";
|
|
1292
1296
|
setDraft("");
|
|
@@ -1301,6 +1305,7 @@ function CredentialModal(props) {
|
|
|
1301
1305
|
useDialogA11y({
|
|
1302
1306
|
open: surfaceOpen,
|
|
1303
1307
|
container: contentRef,
|
|
1308
|
+
externalDialogOwner,
|
|
1304
1309
|
initialFocusSelector: "[data-mdlx-initial-focus]",
|
|
1305
1310
|
mandatory,
|
|
1306
1311
|
onEscape: close
|
|
@@ -1686,6 +1691,11 @@ var CredentialDialogCoordinator = class {
|
|
|
1686
1691
|
if (this.#snapshot.activeOwner !== null) return;
|
|
1687
1692
|
this.#publish({ activeOwner: owner });
|
|
1688
1693
|
}
|
|
1694
|
+
/** Lets an explicit Credential editor adopt a queued shell recovery prompt. */
|
|
1695
|
+
openCredential(owner) {
|
|
1696
|
+
if (this.#snapshot.activeOwner !== null && this.#snapshot.activeOwner !== "shell:credential-recovery") return;
|
|
1697
|
+
this.#publish({ activeOwner: owner });
|
|
1698
|
+
}
|
|
1689
1699
|
presentRecovery(token) {
|
|
1690
1700
|
if (token === this.#snapshot.dismissedRecoveryToken) return;
|
|
1691
1701
|
if (token === this.#snapshot.recoveryToken) {
|
|
@@ -1989,6 +1999,9 @@ function ModellixDesignView({ controller, settingsController, t }) {
|
|
|
1989
1999
|
(0, react.useEffect)(() => {
|
|
1990
2000
|
if (state.pending !== null) setOutcomeAnnouncement("");
|
|
1991
2001
|
}, [state.pending]);
|
|
2002
|
+
(0, react.useEffect)(() => {
|
|
2003
|
+
setOutcomeAnnouncement("");
|
|
2004
|
+
}, [t]);
|
|
1992
2005
|
(0, react.useEffect)(() => {
|
|
1993
2006
|
if (snapshot === null) return;
|
|
1994
2007
|
const transition = designOutcomeTransition(previousOutcome.current, snapshot);
|
|
@@ -2081,7 +2094,7 @@ function ModellixDesignView({ controller, settingsController, t }) {
|
|
|
2081
2094
|
settings?.credential.writable === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
2082
2095
|
type: "button",
|
|
2083
2096
|
variant: "primary",
|
|
2084
|
-
onClick: () => credentialDialogs.
|
|
2097
|
+
onClick: () => credentialDialogs.openCredential(credentialDialogOwner),
|
|
2085
2098
|
children: t("configureToContinue")
|
|
2086
2099
|
}),
|
|
2087
2100
|
settings?.credential.source === "env" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -3177,6 +3190,7 @@ const en = {
|
|
|
3177
3190
|
//#region src/client/SettingsSection.tsx
|
|
3178
3191
|
function ModellixSettingsSection({ controller, t }) {
|
|
3179
3192
|
const state = useResourceState(controller.store);
|
|
3193
|
+
const settingsSectionRef = (0, react.useRef)(null);
|
|
3180
3194
|
const snapshot = state.data;
|
|
3181
3195
|
const [services, setServices] = (0, react.useState)(null);
|
|
3182
3196
|
const [announcement, setAnnouncement] = (0, react.useState)("");
|
|
@@ -3204,6 +3218,9 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3204
3218
|
(0, react.useEffect)(() => {
|
|
3205
3219
|
if (snapshot !== null) setServices(snapshot.services);
|
|
3206
3220
|
}, [snapshot?.settingsRevision]);
|
|
3221
|
+
(0, react.useEffect)(() => {
|
|
3222
|
+
setAnnouncement("");
|
|
3223
|
+
}, [t]);
|
|
3207
3224
|
const busy = state.pending !== null;
|
|
3208
3225
|
const saveServices = (0, react.useCallback)(() => {
|
|
3209
3226
|
if (snapshot === null || services === null || busy) return;
|
|
@@ -3219,6 +3236,7 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3219
3236
|
t
|
|
3220
3237
|
]);
|
|
3221
3238
|
if (snapshot === null || services === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3239
|
+
ref: settingsSectionRef,
|
|
3222
3240
|
className: "mdlx-settings",
|
|
3223
3241
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3224
3242
|
className: "mdlx-live",
|
|
@@ -3239,6 +3257,7 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3239
3257
|
const canWriteCredential = credential.writable && credential.source !== "env";
|
|
3240
3258
|
const llmRefreshDisabled = busy || !snapshot.services.llm || !credential.configured;
|
|
3241
3259
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3260
|
+
ref: settingsSectionRef,
|
|
3242
3261
|
className: "mdlx-settings",
|
|
3243
3262
|
children: [
|
|
3244
3263
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
@@ -3277,7 +3296,7 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3277
3296
|
type: "button",
|
|
3278
3297
|
variant: !credential.configured || credential.verification === "invalid" ? "primary" : "outline",
|
|
3279
3298
|
disabled: busy,
|
|
3280
|
-
onClick: () => credentialDialogs.
|
|
3299
|
+
onClick: () => credentialDialogs.openCredential(credentialDialogOwner),
|
|
3281
3300
|
children: credential.configured ? t("replaceKey") : t("configureKey")
|
|
3282
3301
|
}), credential.configured && canWriteCredential && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3283
3302
|
type: "button",
|
|
@@ -3356,7 +3375,8 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3356
3375
|
},
|
|
3357
3376
|
onCancel: () => credentialDialogs.dismissCredential(credentialDialogOwner),
|
|
3358
3377
|
laterLabel: credentialRecovery ? "later" : "cancel",
|
|
3359
|
-
t
|
|
3378
|
+
t,
|
|
3379
|
+
externalDialogOwner: settingsSectionRef
|
|
3360
3380
|
}),
|
|
3361
3381
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RemoveCredentialDialog, {
|
|
3362
3382
|
open: removeOpen,
|
|
@@ -3371,7 +3391,8 @@ function ModellixSettingsSection({ controller, t }) {
|
|
|
3371
3391
|
setAnnouncement(t("saved"));
|
|
3372
3392
|
});
|
|
3373
3393
|
},
|
|
3374
|
-
t
|
|
3394
|
+
t,
|
|
3395
|
+
externalDialogOwner: settingsSectionRef
|
|
3375
3396
|
})
|
|
3376
3397
|
]
|
|
3377
3398
|
});
|
|
@@ -3426,12 +3447,13 @@ function LlmCatalogCard({ snapshot, dateLocale, busy, disabled, onRefresh, t })
|
|
|
3426
3447
|
]
|
|
3427
3448
|
});
|
|
3428
3449
|
}
|
|
3429
|
-
function RemoveCredentialDialog({ open, busy, errorCode, onClose, onConfirm, t }) {
|
|
3450
|
+
function RemoveCredentialDialog({ open, busy, errorCode, onClose, onConfirm, t, externalDialogOwner }) {
|
|
3430
3451
|
const contentRef = (0, react.useRef)(null);
|
|
3431
|
-
const surfaceOpen = useExternalDialogGate(open);
|
|
3452
|
+
const surfaceOpen = useExternalDialogGate(open, externalDialogOwner);
|
|
3432
3453
|
useDialogA11y({
|
|
3433
3454
|
open: surfaceOpen,
|
|
3434
3455
|
container: contentRef,
|
|
3456
|
+
externalDialogOwner,
|
|
3435
3457
|
initialFocusSelector: "[data-mdlx-initial-focus]",
|
|
3436
3458
|
mandatory: false,
|
|
3437
3459
|
onEscape: onClose
|