dsh-web-search-enhanced 0.2.0 → 0.2.2
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/README.md +27 -3
- package/lib/client.cjs +764 -555
- package/lib/client.cjs.map +1 -1
- package/lib/index.js +1592 -295
- package/package.json +3 -1
package/lib/client.cjs
CHANGED
|
@@ -33,7 +33,12 @@ window.__ModuleLoader__.load({
|
|
|
33
33
|
const SEARCH = {
|
|
34
34
|
packageName: "dsh-web-search-enhanced",
|
|
35
35
|
rowId: "web-search-enhanced",
|
|
36
|
-
providerId: "search-enhanced"
|
|
36
|
+
providerId: "search-enhanced",
|
|
37
|
+
tools: {
|
|
38
|
+
action: "web_search_enhanced",
|
|
39
|
+
list: "list_web_search_providers"
|
|
40
|
+
},
|
|
41
|
+
command: "setup-search"
|
|
37
42
|
};
|
|
38
43
|
/**
|
|
39
44
|
* Key of a row's configuration page on the Plugins page (`plugins.row.config`).
|
|
@@ -151,6 +156,7 @@ window.__ModuleLoader__.load({
|
|
|
151
156
|
"version",
|
|
152
157
|
"defaultConnection",
|
|
153
158
|
"showSelector",
|
|
159
|
+
"enhancedTools",
|
|
154
160
|
"defaults",
|
|
155
161
|
"connections"
|
|
156
162
|
];
|
|
@@ -193,8 +199,16 @@ window.__ModuleLoader__.load({
|
|
|
193
199
|
}
|
|
194
200
|
return result;
|
|
195
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Operator text shown as one line (a label in menus, error messages and the
|
|
204
|
+
* Agent's provider list): control characters and line or paragraph separators
|
|
205
|
+
* become spaces, runs of whitespace one space, the ends trimmed.
|
|
206
|
+
*/
|
|
207
|
+
function singleLine(value) {
|
|
208
|
+
return value.replaceAll(/[\p{Cc}\p{Zl}\p{Zp}]/gu, " ").replaceAll(/\s+/gu, " ").trim();
|
|
209
|
+
}
|
|
196
210
|
const text = zod.z.string().trim().min(1).max(TEXT_MAX_LENGTH);
|
|
197
|
-
const label = zod.z.string().
|
|
211
|
+
const label = zod.z.string().transform(singleLine).pipe(zod.z.string().min(1).max(200));
|
|
198
212
|
const credentialRef = text.regex(CREDENTIAL_REF, "must be a credential reference such as EXA_API_KEY");
|
|
199
213
|
const endpoint = text.refine(isEndpoint, "must be an absolute http(s) URL without credentials, query or fragment");
|
|
200
214
|
const options = zod.z.record(zod.z.string(), zod.z.unknown());
|
|
@@ -203,6 +217,7 @@ window.__ModuleLoader__.load({
|
|
|
203
217
|
version: zod.z.literal(currentVersion).optional(),
|
|
204
218
|
defaultConnection: zod.z.string().min(1).max(200).optional(),
|
|
205
219
|
showSelector: zod.z.boolean().optional(),
|
|
220
|
+
enhancedTools: zod.z.boolean().optional(),
|
|
206
221
|
defaults: defaults.optional(),
|
|
207
222
|
connections: zod.z.record(zod.z.string().max(200), zod.z.unknown()).refine((value) => Object.keys(value).length <= 200, "must contain at most 200 connections").optional()
|
|
208
223
|
});
|
|
@@ -264,7 +279,7 @@ window.__ModuleLoader__.load({
|
|
|
264
279
|
const customSchema = customConnectionSchema(adapterKeys, protocolKeys);
|
|
265
280
|
const connections = /* @__PURE__ */ new Map();
|
|
266
281
|
const rejectId = (id, path) => fail(path, "unknown connection id \"" + id + "\"; this release does not read 0.1.x settings; remove the field or use Reset on the settings page");
|
|
267
|
-
const resolve = (id, key, override,
|
|
282
|
+
const resolve = (id, key, override, origin) => {
|
|
268
283
|
const info = catalog[key];
|
|
269
284
|
const path = "connections." + id;
|
|
270
285
|
const access = info.kind === "model" ? "api-key" : override.access ?? defaultAccess(info.access);
|
|
@@ -276,11 +291,12 @@ window.__ModuleLoader__.load({
|
|
|
276
291
|
if (problems.length > 0) fail(path + ".options", problems.join("; ") + "; this release does not read 0.1.x settings; remove the field or use Reset on the settings page");
|
|
277
292
|
const trustedEndpoint = override.trustedEndpoint ?? false;
|
|
278
293
|
for (const [name, rule] of Object.entries(info.options)) if (rule.kind === "url" && values[name] !== void 0 && values[name] !== info.endpoint && !trustedEndpoint) fail(path + ".trustedEndpoint", "a non-official " + name + " needs trustedEndpoint: true");
|
|
294
|
+
const disabled = override.disabled ?? (origin.kind === "builtin" ? info.optIn : false);
|
|
279
295
|
const base = {
|
|
280
296
|
id,
|
|
281
297
|
catalogKey: key,
|
|
282
298
|
label: override.label ?? info.label,
|
|
283
|
-
disabled
|
|
299
|
+
disabled,
|
|
284
300
|
remote: info.remote,
|
|
285
301
|
trustedEndpoint,
|
|
286
302
|
options: values
|
|
@@ -297,7 +313,7 @@ window.__ModuleLoader__.load({
|
|
|
297
313
|
};
|
|
298
314
|
if (info.kind !== "native" && info.kind !== "adapter") return fail(path + ".kind", "unsupported catalog kind");
|
|
299
315
|
if (!info.access.apiKey || info.endpoint === void 0) return fail(path, "remote catalog entry needs credentials and an endpoint");
|
|
300
|
-
const url =
|
|
316
|
+
const url = origin.kind === "custom" && origin.endpoint !== void 0 ? origin.endpoint : info.endpoint;
|
|
301
317
|
if (url !== info.endpoint && !trustedEndpoint) fail(path + ".trustedEndpoint", "a custom endpoint needs trustedEndpoint: true");
|
|
302
318
|
return {
|
|
303
319
|
...base,
|
|
@@ -318,7 +334,7 @@ window.__ModuleLoader__.load({
|
|
|
318
334
|
]) if (Object.hasOwn(raw, field)) fail("connections." + id + "." + field, "this connection takes its route from the Session model");
|
|
319
335
|
}
|
|
320
336
|
const override = raw === void 0 ? {} : parse(builtinOverrideSchema, raw, "connections." + id);
|
|
321
|
-
connections.set(id, resolve(id, key, override));
|
|
337
|
+
connections.set(id, resolve(id, key, override, { kind: "builtin" }));
|
|
322
338
|
}
|
|
323
339
|
for (const [id, raw] of Object.entries(overrides)) {
|
|
324
340
|
if (connections.has(id)) continue;
|
|
@@ -328,7 +344,10 @@ window.__ModuleLoader__.load({
|
|
|
328
344
|
if (custom.kind === "adapter") connections.set(id, resolve(id, custom.adapter, {
|
|
329
345
|
...custom,
|
|
330
346
|
access: "api-key"
|
|
331
|
-
},
|
|
347
|
+
}, {
|
|
348
|
+
kind: "custom",
|
|
349
|
+
endpoint: custom.endpoint
|
|
350
|
+
}));
|
|
332
351
|
else {
|
|
333
352
|
const info = protocols[custom.protocol];
|
|
334
353
|
const values = custom.options ?? {};
|
|
@@ -359,6 +378,7 @@ window.__ModuleLoader__.load({
|
|
|
359
378
|
version: migrations.currentVersion,
|
|
360
379
|
defaultConnection,
|
|
361
380
|
showSelector: settings.showSelector ?? true,
|
|
381
|
+
enhancedTools: settings.enhancedTools ?? false,
|
|
362
382
|
defaults: settings.defaults ?? parse(defaults.schema, {}, "defaults"),
|
|
363
383
|
connections
|
|
364
384
|
};
|
|
@@ -800,6 +820,7 @@ window.__ModuleLoader__.load({
|
|
|
800
820
|
const MODEL_PROTOCOLS = {
|
|
801
821
|
"anthropic-messages": {
|
|
802
822
|
label: "Anthropic Messages",
|
|
823
|
+
use: "the model searches and answers",
|
|
803
824
|
options: {
|
|
804
825
|
maxTokens,
|
|
805
826
|
anthropicTool,
|
|
@@ -815,6 +836,7 @@ window.__ModuleLoader__.load({
|
|
|
815
836
|
},
|
|
816
837
|
"openai-responses": {
|
|
817
838
|
label: "OpenAI Responses",
|
|
839
|
+
use: "the model searches and answers",
|
|
818
840
|
options: {
|
|
819
841
|
maxTokens,
|
|
820
842
|
responsesTool,
|
|
@@ -828,6 +850,7 @@ window.__ModuleLoader__.load({
|
|
|
828
850
|
},
|
|
829
851
|
"openai-chat-completions": {
|
|
830
852
|
label: "OpenAI Chat Completions",
|
|
853
|
+
use: "the model searches and answers",
|
|
831
854
|
options: {
|
|
832
855
|
maxTokens,
|
|
833
856
|
searchContextSize,
|
|
@@ -847,6 +870,8 @@ window.__ModuleLoader__.load({
|
|
|
847
870
|
label: "DeepSeek Messages",
|
|
848
871
|
kind: "native",
|
|
849
872
|
remote: true,
|
|
873
|
+
optIn: false,
|
|
874
|
+
use: "answers with a summary and sources",
|
|
850
875
|
endpoint: "https://api.deepseek.com/anthropic/v1",
|
|
851
876
|
homepage: "https://platform.deepseek.com",
|
|
852
877
|
access: nativeAccess,
|
|
@@ -877,6 +902,7 @@ window.__ModuleLoader__.load({
|
|
|
877
902
|
label: "DeepSeek Search API",
|
|
878
903
|
kind: "native",
|
|
879
904
|
remote: true,
|
|
905
|
+
optIn: true,
|
|
880
906
|
endpoint: "https://api.deepseek.com/v1/tools",
|
|
881
907
|
homepage: "https://platform.deepseek.com",
|
|
882
908
|
access: nativeAccess,
|
|
@@ -895,6 +921,8 @@ window.__ModuleLoader__.load({
|
|
|
895
921
|
label: "Session model",
|
|
896
922
|
kind: "model",
|
|
897
923
|
remote: true,
|
|
924
|
+
optIn: false,
|
|
925
|
+
use: "the session model searches and answers",
|
|
898
926
|
access: {
|
|
899
927
|
keyless: false,
|
|
900
928
|
apiKey: false,
|
|
@@ -914,6 +942,7 @@ window.__ModuleLoader__.load({
|
|
|
914
942
|
},
|
|
915
943
|
kind: "adapter",
|
|
916
944
|
remote: true,
|
|
945
|
+
optIn: true,
|
|
917
946
|
freshness: ["api-key"],
|
|
918
947
|
homepage: "https://exa.ai",
|
|
919
948
|
options: { type: {
|
|
@@ -936,6 +965,7 @@ window.__ModuleLoader__.load({
|
|
|
936
965
|
},
|
|
937
966
|
kind: "adapter",
|
|
938
967
|
remote: true,
|
|
968
|
+
optIn: true,
|
|
939
969
|
freshness: ["keyless", "api-key"],
|
|
940
970
|
homepage: "https://www.firecrawl.dev",
|
|
941
971
|
options: {
|
|
@@ -961,6 +991,7 @@ window.__ModuleLoader__.load({
|
|
|
961
991
|
},
|
|
962
992
|
kind: "adapter",
|
|
963
993
|
remote: true,
|
|
994
|
+
optIn: true,
|
|
964
995
|
freshness: [],
|
|
965
996
|
homepage: "https://www.tavily.com",
|
|
966
997
|
options: {
|
|
@@ -993,6 +1024,7 @@ window.__ModuleLoader__.load({
|
|
|
993
1024
|
},
|
|
994
1025
|
kind: "adapter",
|
|
995
1026
|
remote: true,
|
|
1027
|
+
optIn: true,
|
|
996
1028
|
freshness: [],
|
|
997
1029
|
homepage: "https://www.tinyfish.ai",
|
|
998
1030
|
options: {
|
|
@@ -1029,8 +1061,10 @@ window.__ModuleLoader__.load({
|
|
|
1029
1061
|
},
|
|
1030
1062
|
kind: "adapter",
|
|
1031
1063
|
remote: true,
|
|
1064
|
+
optIn: true,
|
|
1032
1065
|
freshness: [],
|
|
1033
1066
|
homepage: "https://openalex.org",
|
|
1067
|
+
use: "scholarly works (papers, citations); keyword queries",
|
|
1034
1068
|
options: {
|
|
1035
1069
|
sort: {
|
|
1036
1070
|
kind: "text",
|
|
@@ -1059,8 +1093,10 @@ window.__ModuleLoader__.load({
|
|
|
1059
1093
|
},
|
|
1060
1094
|
kind: "adapter",
|
|
1061
1095
|
remote: true,
|
|
1096
|
+
optIn: true,
|
|
1062
1097
|
freshness: [],
|
|
1063
1098
|
homepage: "https://www.semanticscholar.org/product/api",
|
|
1099
|
+
use: "academic papers (citations, TL;DR); keyword queries",
|
|
1064
1100
|
options: {
|
|
1065
1101
|
year: {
|
|
1066
1102
|
kind: "text",
|
|
@@ -1106,6 +1142,378 @@ window.__ModuleLoader__.load({
|
|
|
1106
1142
|
return (0, react.useSyncExternalStore)(subscribe, getSnapshot);
|
|
1107
1143
|
}
|
|
1108
1144
|
//#endregion
|
|
1145
|
+
//#region ../core/src/client/settings/parts.tsx
|
|
1146
|
+
/** Building blocks shared by the settings sections. */
|
|
1147
|
+
function classNames(...args) {
|
|
1148
|
+
return args.flat(Number.POSITIVE_INFINITY).filter(Boolean).map((arg) => {
|
|
1149
|
+
if (typeof arg === "string") return arg;
|
|
1150
|
+
if (typeof arg === "object" && arg !== null) return Object.entries(arg).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
|
|
1151
|
+
return "";
|
|
1152
|
+
}).filter(Boolean).join(" ");
|
|
1153
|
+
}
|
|
1154
|
+
/** A local schema failure whose diagnostic stays out of the translated message. */
|
|
1155
|
+
var SettingsValidationError = class extends Error {};
|
|
1156
|
+
function createSettingsParts({ classes: css, keys }) {
|
|
1157
|
+
/** `titleId` lets a control inside name itself by the section title. */
|
|
1158
|
+
function Section({ title, titleId, actions, children }) {
|
|
1159
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1160
|
+
className: css.section,
|
|
1161
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1162
|
+
className: css.sectionHead,
|
|
1163
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
1164
|
+
id: titleId,
|
|
1165
|
+
className: css.sectionTitle,
|
|
1166
|
+
children: title
|
|
1167
|
+
}), actions]
|
|
1168
|
+
}), children]
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
/** Title and hint on the left, one control on the right; wraps under the text on narrow pages. */
|
|
1172
|
+
function SettingRow({ title, hint, children }) {
|
|
1173
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1174
|
+
className: css.settingRow,
|
|
1175
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1176
|
+
className: css.settingText,
|
|
1177
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1178
|
+
className: css.settingTitle,
|
|
1179
|
+
children: title
|
|
1180
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1181
|
+
className: css.hint,
|
|
1182
|
+
children: hint
|
|
1183
|
+
})]
|
|
1184
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1185
|
+
className: css.settingControl,
|
|
1186
|
+
children
|
|
1187
|
+
})]
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
/** A dropdown in the settings pill style, built on the shared Menu. */
|
|
1191
|
+
function SelectMenu({ label, title, value, options, disabled, onChange, compact = false }) {
|
|
1192
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
1193
|
+
const current = options.find((option) => option.id === value);
|
|
1194
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
1195
|
+
open,
|
|
1196
|
+
onClose: () => {
|
|
1197
|
+
setOpen(false);
|
|
1198
|
+
},
|
|
1199
|
+
items: options.map((option) => ({
|
|
1200
|
+
id: option.id,
|
|
1201
|
+
label: option.label
|
|
1202
|
+
})),
|
|
1203
|
+
selectedId: value,
|
|
1204
|
+
onSelect: (id) => {
|
|
1205
|
+
setOpen(false);
|
|
1206
|
+
if (id !== value) onChange(id);
|
|
1207
|
+
},
|
|
1208
|
+
align: "end",
|
|
1209
|
+
portal: true,
|
|
1210
|
+
anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1211
|
+
type: "button",
|
|
1212
|
+
className: compact ? css.selectCompact : css.select,
|
|
1213
|
+
"aria-label": label,
|
|
1214
|
+
title,
|
|
1215
|
+
"aria-haspopup": "menu",
|
|
1216
|
+
"aria-expanded": open,
|
|
1217
|
+
disabled,
|
|
1218
|
+
onClick: () => {
|
|
1219
|
+
setOpen(!open);
|
|
1220
|
+
},
|
|
1221
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1222
|
+
className: css.selectValue,
|
|
1223
|
+
children: current?.label ?? value
|
|
1224
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: css.selectChevron })]
|
|
1225
|
+
})
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
/** Pending state and the last failure of one section's writes. */
|
|
1229
|
+
function useWrite(t) {
|
|
1230
|
+
const [state, setState] = (0, react.useState)({
|
|
1231
|
+
busy: false,
|
|
1232
|
+
error: void 0,
|
|
1233
|
+
errorTitle: void 0
|
|
1234
|
+
});
|
|
1235
|
+
const run = async (work) => {
|
|
1236
|
+
setState({
|
|
1237
|
+
busy: true,
|
|
1238
|
+
error: void 0,
|
|
1239
|
+
errorTitle: void 0
|
|
1240
|
+
});
|
|
1241
|
+
try {
|
|
1242
|
+
const accepted = await work();
|
|
1243
|
+
setState({
|
|
1244
|
+
busy: false,
|
|
1245
|
+
error: accepted ? void 0 : t(keys.refused),
|
|
1246
|
+
errorTitle: void 0
|
|
1247
|
+
});
|
|
1248
|
+
return accepted;
|
|
1249
|
+
} catch (error) {
|
|
1250
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1251
|
+
const invalid = error instanceof SettingsValidationError;
|
|
1252
|
+
setState({
|
|
1253
|
+
busy: false,
|
|
1254
|
+
error: invalid ? t(keys.invalid) : message || t(keys.failed),
|
|
1255
|
+
errorTitle: invalid ? message : void 0
|
|
1256
|
+
});
|
|
1257
|
+
return false;
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
return {
|
|
1261
|
+
...state,
|
|
1262
|
+
run
|
|
1263
|
+
};
|
|
1264
|
+
}
|
|
1265
|
+
function ErrorText({ children, title }) {
|
|
1266
|
+
return children === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1267
|
+
className: css.error,
|
|
1268
|
+
role: "alert",
|
|
1269
|
+
title,
|
|
1270
|
+
children
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
/** Inline confirmation of a destructive action: the question beside cancel and confirm. */
|
|
1274
|
+
function ConfirmRow({ message, confirmLabel, cancelLabel, disabled, onConfirm, onCancel }) {
|
|
1275
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1276
|
+
className: css.confirmRow,
|
|
1277
|
+
role: "group",
|
|
1278
|
+
"aria-label": message,
|
|
1279
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1280
|
+
className: css.confirmText,
|
|
1281
|
+
children: message
|
|
1282
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1283
|
+
className: css.actions,
|
|
1284
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1285
|
+
variant: "ghost",
|
|
1286
|
+
size: "sm",
|
|
1287
|
+
onClick: onCancel,
|
|
1288
|
+
children: cancelLabel
|
|
1289
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1290
|
+
variant: "outline",
|
|
1291
|
+
size: "sm",
|
|
1292
|
+
className: css.danger,
|
|
1293
|
+
disabled,
|
|
1294
|
+
onClick: onConfirm,
|
|
1295
|
+
children: confirmLabel
|
|
1296
|
+
})]
|
|
1297
|
+
})]
|
|
1298
|
+
});
|
|
1299
|
+
}
|
|
1300
|
+
return {
|
|
1301
|
+
Section,
|
|
1302
|
+
SettingRow,
|
|
1303
|
+
SelectMenu,
|
|
1304
|
+
ErrorText,
|
|
1305
|
+
ConfirmRow,
|
|
1306
|
+
useWrite
|
|
1307
|
+
};
|
|
1308
|
+
}
|
|
1309
|
+
function applyOps(user, ops) {
|
|
1310
|
+
const root = structuredClone(user !== null && typeof user === "object" && !Array.isArray(user) ? user : {});
|
|
1311
|
+
for (const op of ops) {
|
|
1312
|
+
if (op.path.length === 0) continue;
|
|
1313
|
+
if (op.op === "set") {
|
|
1314
|
+
let current = root;
|
|
1315
|
+
for (let i = 0; i < op.path.length - 1; i++) {
|
|
1316
|
+
const seg = op.path[i];
|
|
1317
|
+
if (current[seg] === null || typeof current[seg] !== "object" || Array.isArray(current[seg])) current[seg] = {};
|
|
1318
|
+
current = current[seg];
|
|
1319
|
+
}
|
|
1320
|
+
current[op.path.at(-1)] = structuredClone(op.value);
|
|
1321
|
+
} else if (op.op === "unset") {
|
|
1322
|
+
let current = root;
|
|
1323
|
+
for (let i = 0; i < op.path.length - 1; i++) {
|
|
1324
|
+
const seg = op.path[i];
|
|
1325
|
+
if (current[seg] === null || typeof current[seg] !== "object" || Array.isArray(current[seg])) break;
|
|
1326
|
+
current = current[seg];
|
|
1327
|
+
}
|
|
1328
|
+
delete current[op.path.at(-1)];
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1331
|
+
return root;
|
|
1332
|
+
}
|
|
1333
|
+
//#endregion
|
|
1334
|
+
//#region ../core/src/client/settings/document.ts
|
|
1335
|
+
/** ConfigForm.value is schema-projected; the raw layers retain unknown fields for validation. */
|
|
1336
|
+
function effectiveDocument(snapshot) {
|
|
1337
|
+
return merge(snapshot.base, snapshot.user);
|
|
1338
|
+
}
|
|
1339
|
+
/** Validate before exposing normal editors; only successful older migrations need writeback. */
|
|
1340
|
+
function editableSettings(raw, layers, writable, resolve, migrations = SETTINGS_MIGRATIONS) {
|
|
1341
|
+
try {
|
|
1342
|
+
const version = documentVersion$2(raw, migrations.currentVersion);
|
|
1343
|
+
const config = migrateDocument(raw, migrations);
|
|
1344
|
+
resolve(config);
|
|
1345
|
+
return {
|
|
1346
|
+
kind: "ready",
|
|
1347
|
+
config,
|
|
1348
|
+
layers,
|
|
1349
|
+
needsWriteback: writable && version.kind === "older"
|
|
1350
|
+
};
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
return {
|
|
1353
|
+
kind: "invalid",
|
|
1354
|
+
diagnostic: diagnostic(error),
|
|
1355
|
+
layers,
|
|
1356
|
+
needsWriteback: false
|
|
1357
|
+
};
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
/** Check the exact recursively overlaid candidate that the settings store will persist. */
|
|
1361
|
+
function settingsOperations(layers, operations, resolve) {
|
|
1362
|
+
try {
|
|
1363
|
+
const candidate = effectiveDocument({
|
|
1364
|
+
base: layers.base,
|
|
1365
|
+
user: applyOps(layers.user, operations)
|
|
1366
|
+
});
|
|
1367
|
+
const result = [...operations];
|
|
1368
|
+
if (result.some((op) => op.op === "set") && candidate.version === void 0) {
|
|
1369
|
+
result.push({
|
|
1370
|
+
op: "set",
|
|
1371
|
+
path: ["version"],
|
|
1372
|
+
value: 2
|
|
1373
|
+
});
|
|
1374
|
+
candidate.version = 2;
|
|
1375
|
+
}
|
|
1376
|
+
resolve(candidate);
|
|
1377
|
+
return result;
|
|
1378
|
+
} catch (error) {
|
|
1379
|
+
throw new SettingsValidationError(diagnostic(error));
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
/**
|
|
1383
|
+
* Share validation, revision fencing and automatic future migrations between both pages.
|
|
1384
|
+
* @param snapshot - the settings snapshot the page renders.
|
|
1385
|
+
* @param read - the settings snapshot now, which a write the form accepted has already updated.
|
|
1386
|
+
*/
|
|
1387
|
+
function useSettingsDocument(snapshot, read, resolve, mutate, migrations = SETTINGS_MIGRATIONS) {
|
|
1388
|
+
const view = (0, react.useMemo)(() => {
|
|
1389
|
+
if (snapshot.status === "unavailable" || snapshot.value === void 0 || snapshot.revision === void 0) return void 0;
|
|
1390
|
+
const result = editableSettings(effectiveDocument(snapshot), {
|
|
1391
|
+
base: snapshot.base,
|
|
1392
|
+
user: snapshot.user
|
|
1393
|
+
}, snapshot.writable, resolve, migrations);
|
|
1394
|
+
if (snapshot.diagnostic === void 0) return result;
|
|
1395
|
+
return {
|
|
1396
|
+
kind: "invalid",
|
|
1397
|
+
layers: result.layers,
|
|
1398
|
+
needsWriteback: false,
|
|
1399
|
+
diagnostic: result.kind === "invalid" ? result.diagnostic + "; " + snapshot.diagnostic : snapshot.diagnostic
|
|
1400
|
+
};
|
|
1401
|
+
}, [
|
|
1402
|
+
snapshot,
|
|
1403
|
+
resolve,
|
|
1404
|
+
migrations
|
|
1405
|
+
]);
|
|
1406
|
+
const attemptedRevision = (0, react.useRef)(void 0);
|
|
1407
|
+
const [failure, setFailure] = (0, react.useState)();
|
|
1408
|
+
const revision = snapshot.revision;
|
|
1409
|
+
(0, react.useEffect)(() => {
|
|
1410
|
+
if (view?.kind !== "ready" || !view.needsWriteback || revision === void 0 || attemptedRevision.current === revision) return;
|
|
1411
|
+
attemptedRevision.current = revision;
|
|
1412
|
+
const writeback = async () => {
|
|
1413
|
+
try {
|
|
1414
|
+
const operations = replaceDocumentOperations(view.layers.user, view.config);
|
|
1415
|
+
await mutate(settingsOperations(view.layers, operations, resolve), revision);
|
|
1416
|
+
} catch (error) {
|
|
1417
|
+
setFailure({
|
|
1418
|
+
revision,
|
|
1419
|
+
diagnostic: diagnostic(error)
|
|
1420
|
+
});
|
|
1421
|
+
}
|
|
1422
|
+
};
|
|
1423
|
+
writeback();
|
|
1424
|
+
}, [
|
|
1425
|
+
view,
|
|
1426
|
+
revision,
|
|
1427
|
+
resolve,
|
|
1428
|
+
mutate
|
|
1429
|
+
]);
|
|
1430
|
+
const queue = (0, react.useRef)(Promise.resolve());
|
|
1431
|
+
const submit = async (change, displayedRevision) => {
|
|
1432
|
+
if (typeof change !== "function") {
|
|
1433
|
+
if (change.length === 0) return true;
|
|
1434
|
+
if (view === void 0 || !snapshot.writable || displayedRevision === void 0) return false;
|
|
1435
|
+
return mutate(settingsOperations(view.layers, change, resolve), displayedRevision);
|
|
1436
|
+
}
|
|
1437
|
+
const current = read();
|
|
1438
|
+
if (current.status !== "ready" || !current.writable || current.revision === void 0) return false;
|
|
1439
|
+
const layers = {
|
|
1440
|
+
base: current.base,
|
|
1441
|
+
user: current.user
|
|
1442
|
+
};
|
|
1443
|
+
const operations = change(layers);
|
|
1444
|
+
if (operations.length === 0) return true;
|
|
1445
|
+
return mutate(settingsOperations(layers, operations, resolve), current.revision);
|
|
1446
|
+
};
|
|
1447
|
+
const write = (change, expectedRevision = revision) => {
|
|
1448
|
+
const task = queue.current.then(() => submit(change, expectedRevision));
|
|
1449
|
+
queue.current = task.then(() => {}, () => {});
|
|
1450
|
+
return task;
|
|
1451
|
+
};
|
|
1452
|
+
return {
|
|
1453
|
+
view,
|
|
1454
|
+
write,
|
|
1455
|
+
migrationError: failure?.revision === revision ? failure?.diagnostic : void 0
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
function replaceDocumentOperations(user, document) {
|
|
1459
|
+
const operations = Object.keys(objectOf$1(user)).filter((key) => !Object.hasOwn(document, key)).map((key) => ({
|
|
1460
|
+
op: "unset",
|
|
1461
|
+
path: [key]
|
|
1462
|
+
}));
|
|
1463
|
+
for (const [key, value] of Object.entries(document)) operations.push({
|
|
1464
|
+
op: "set",
|
|
1465
|
+
path: [key],
|
|
1466
|
+
value
|
|
1467
|
+
});
|
|
1468
|
+
return operations;
|
|
1469
|
+
}
|
|
1470
|
+
function diagnostic(error) {
|
|
1471
|
+
return error instanceof Error ? error.message : String(error);
|
|
1472
|
+
}
|
|
1473
|
+
function isObject$1(value) {
|
|
1474
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1475
|
+
}
|
|
1476
|
+
function objectOf$1(value) {
|
|
1477
|
+
return isObject$1(value) ? value : {};
|
|
1478
|
+
}
|
|
1479
|
+
function merge(base, user) {
|
|
1480
|
+
const result = { ...objectOf$1(base) };
|
|
1481
|
+
for (const [key, value] of Object.entries(objectOf$1(user))) Object.defineProperty(result, key, {
|
|
1482
|
+
value: isObject$1(value) && isObject$1(result[key]) ? merge(result[key], value) : value,
|
|
1483
|
+
enumerable: true,
|
|
1484
|
+
writable: true,
|
|
1485
|
+
configurable: true
|
|
1486
|
+
});
|
|
1487
|
+
return result;
|
|
1488
|
+
}
|
|
1489
|
+
//#endregion
|
|
1490
|
+
//#region ../core/src/client/remote-services.ts
|
|
1491
|
+
/** Whether the catalog has remote services and every one of them is off. */
|
|
1492
|
+
function remoteServicesOff(catalog, resolved) {
|
|
1493
|
+
const remote = Object.keys(catalog).filter((key) => catalog[key].optIn);
|
|
1494
|
+
return remote.length > 0 && remote.every((key) => resolved.connections.get(builtinId(key)).disabled);
|
|
1495
|
+
}
|
|
1496
|
+
/** The fact for the current row settings, recomputed only when the settings snapshot changes. */
|
|
1497
|
+
function remoteServicesOffSource(settings, catalog, resolve) {
|
|
1498
|
+
let cached;
|
|
1499
|
+
const compute = (source) => {
|
|
1500
|
+
if (source.value === void 0) return false;
|
|
1501
|
+
const view = editableSettings(effectiveDocument(source), source, false, resolve);
|
|
1502
|
+
return view.kind === "ready" && remoteServicesOff(catalog, resolve(view.config));
|
|
1503
|
+
};
|
|
1504
|
+
return {
|
|
1505
|
+
getSnapshot() {
|
|
1506
|
+
const source = settings.getSnapshot();
|
|
1507
|
+
if (cached === void 0 || cached.source !== source) cached = {
|
|
1508
|
+
source,
|
|
1509
|
+
off: compute(source)
|
|
1510
|
+
};
|
|
1511
|
+
return cached.off;
|
|
1512
|
+
},
|
|
1513
|
+
subscribe: (listener) => settings.subscribe(listener)
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
//#endregion
|
|
1109
1517
|
//#region ../core/src/client/command.ts
|
|
1110
1518
|
/** Shared ids cannot be shadowed by capability-specific option groups. */
|
|
1111
1519
|
function parseSelectionCommandOption(id, parseOptions) {
|
|
@@ -1113,7 +1521,11 @@ window.__ModuleLoader__.load({
|
|
|
1113
1521
|
if (id.startsWith("connection:") && id.length > 11) return { connectionId: id.slice(11) };
|
|
1114
1522
|
return parseOptions?.(id);
|
|
1115
1523
|
}
|
|
1116
|
-
/**
|
|
1524
|
+
/**
|
|
1525
|
+
* The browser's bare invocation of the capability's Host command: a popup over
|
|
1526
|
+
* the same per-session store the composer menu uses. The Host command keeps its
|
|
1527
|
+
* menu row and runs every line with arguments.
|
|
1528
|
+
*/
|
|
1117
1529
|
function selectionCommand(selections, spec) {
|
|
1118
1530
|
const t = (key) => spec.t(spec.keys[key]);
|
|
1119
1531
|
const read = async (sessionId) => {
|
|
@@ -1123,9 +1535,6 @@ window.__ModuleLoader__.load({
|
|
|
1123
1535
|
};
|
|
1124
1536
|
return {
|
|
1125
1537
|
name: spec.name,
|
|
1126
|
-
label: () => t("label"),
|
|
1127
|
-
description: () => t("description"),
|
|
1128
|
-
icon: spec.icon,
|
|
1129
1538
|
available: () => true,
|
|
1130
1539
|
ui: {
|
|
1131
1540
|
kind: "popupSelect",
|
|
@@ -1173,6 +1582,19 @@ window.__ModuleLoader__.load({
|
|
|
1173
1582
|
}
|
|
1174
1583
|
};
|
|
1175
1584
|
}
|
|
1585
|
+
/**
|
|
1586
|
+
* Call `ran` after this browser ran the Host command `name` in a Session. A line
|
|
1587
|
+
* with arguments (`/setup-search off`) writes on the Host without the selection
|
|
1588
|
+
* store, so that Session's views must read again. DSH reports each Host command
|
|
1589
|
+
* this browser executed with `command/executed`, without its arguments, so every
|
|
1590
|
+
* run counts; runs from another browser or the TUI are not reported here.
|
|
1591
|
+
* @returns the listener's disposer; it also ends with `ctx`'s fiber.
|
|
1592
|
+
*/
|
|
1593
|
+
function followHostCommand(ctx, name, ran) {
|
|
1594
|
+
return ctx.on("command/executed", (sessionId, executed) => {
|
|
1595
|
+
if (executed === name) ran(sessionId);
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1176
1598
|
//#endregion
|
|
1177
1599
|
//#region ../core/src/client/selection.ts
|
|
1178
1600
|
var ConnectionSelectionStore = class {
|
|
@@ -1253,10 +1675,16 @@ window.__ModuleLoader__.load({
|
|
|
1253
1675
|
* read again, the others read on their next load.
|
|
1254
1676
|
*/
|
|
1255
1677
|
invalidate() {
|
|
1256
|
-
for (const entry of this.entries.values())
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1678
|
+
for (const entry of this.entries.values()) this.reread(entry);
|
|
1679
|
+
}
|
|
1680
|
+
/**
|
|
1681
|
+
* The Session's selection changed without this store (its Host command ran):
|
|
1682
|
+
* its views read again, at once when observed, otherwise on their next load.
|
|
1683
|
+
* A read already in flight reads once more.
|
|
1684
|
+
*/
|
|
1685
|
+
invalidateSession(sessionId) {
|
|
1686
|
+
const entry = this.entries.get(sessionId);
|
|
1687
|
+
if (entry !== void 0) this.reread(entry);
|
|
1260
1688
|
}
|
|
1261
1689
|
entry(sessionId) {
|
|
1262
1690
|
const existing = this.entries.get(sessionId);
|
|
@@ -1289,6 +1717,10 @@ window.__ModuleLoader__.load({
|
|
|
1289
1717
|
this.entries.set(sessionId, entry);
|
|
1290
1718
|
return entry;
|
|
1291
1719
|
}
|
|
1720
|
+
reread(entry) {
|
|
1721
|
+
this.outdate(entry);
|
|
1722
|
+
if (entry.observers > 0) this.read(entry);
|
|
1723
|
+
}
|
|
1292
1724
|
outdate(entry) {
|
|
1293
1725
|
entry.stale = true;
|
|
1294
1726
|
entry.epoch += 1;
|
|
@@ -1505,26 +1937,26 @@ window.__ModuleLoader__.load({
|
|
|
1505
1937
|
};
|
|
1506
1938
|
//#endregion
|
|
1507
1939
|
//#region ../core/src/client/settings/sparse.ts
|
|
1508
|
-
const objectOf
|
|
1509
|
-
const isObject
|
|
1940
|
+
const objectOf = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
1941
|
+
const isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1510
1942
|
function equal(a, b) {
|
|
1511
1943
|
if (Object.is(a, b)) return true;
|
|
1512
1944
|
if (Array.isArray(a) || Array.isArray(b)) return Array.isArray(a) && Array.isArray(b) && a.length === b.length && a.every((value, index) => equal(value, b[index]));
|
|
1513
|
-
if (!isObject
|
|
1945
|
+
if (!isObject(a) || !isObject(b)) return false;
|
|
1514
1946
|
const keys = Object.keys(a);
|
|
1515
1947
|
return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && equal(a[key], b[key]));
|
|
1516
1948
|
}
|
|
1517
1949
|
/** Remove what an object value shares with its inherited counterpart, key by key. */
|
|
1518
1950
|
function delta(value, inherited) {
|
|
1519
1951
|
if (equal(value, inherited)) return void 0;
|
|
1520
|
-
if (!isObject
|
|
1521
|
-
const base = objectOf
|
|
1952
|
+
if (!isObject(value)) return value;
|
|
1953
|
+
const base = objectOf(inherited);
|
|
1522
1954
|
return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, delta(child, base[key])]).filter(([, child]) => child !== void 0));
|
|
1523
1955
|
}
|
|
1524
1956
|
function documentVersion$1(layers) {
|
|
1525
1957
|
return documentVersion$2({
|
|
1526
|
-
...objectOf
|
|
1527
|
-
...objectOf
|
|
1958
|
+
...objectOf(layers.base),
|
|
1959
|
+
...objectOf(layers.user)
|
|
1528
1960
|
});
|
|
1529
1961
|
}
|
|
1530
1962
|
function assertCurrentVersion(layers) {
|
|
@@ -1540,241 +1972,54 @@ window.__ModuleLoader__.load({
|
|
|
1540
1972
|
assertCurrentVersion(layers);
|
|
1541
1973
|
const inherited = valueAt(layers.base, path) ?? fallback;
|
|
1542
1974
|
const user = valueAt(layers.user, path);
|
|
1543
|
-
const ops = [];
|
|
1544
|
-
if (target === void 0 || equal(target, inherited)) {
|
|
1545
|
-
if (user !== void 0) ops.push({
|
|
1546
|
-
op: "unset",
|
|
1547
|
-
path: prunedPath(layers.user, path)
|
|
1548
|
-
});
|
|
1549
|
-
} else {
|
|
1550
|
-
const sparse = delta(target, inherited);
|
|
1551
|
-
if (!equal(sparse, user)) ops.push({
|
|
1552
|
-
op: "set",
|
|
1553
|
-
path: [...path],
|
|
1554
|
-
value: sparse
|
|
1555
|
-
});
|
|
1556
|
-
}
|
|
1557
|
-
if (ops.some((op) => op.op === "set") && objectOf$1(layers.user).version !== spec.version) ops.push({
|
|
1558
|
-
op: "set",
|
|
1559
|
-
path: ["version"],
|
|
1560
|
-
value: spec.version
|
|
1561
|
-
});
|
|
1562
|
-
return ops;
|
|
1563
|
-
}
|
|
1564
|
-
function valueAt(root, path) {
|
|
1565
|
-
return path.reduce((value, key) => objectOf$1(value)[key], root);
|
|
1566
|
-
}
|
|
1567
|
-
/**
|
|
1568
|
-
* The path to unset so no empty object stays behind: removing the only key of
|
|
1569
|
-
* a user-layer object removes that object instead, up to a top-level field.
|
|
1570
|
-
*/
|
|
1571
|
-
function prunedPath(user, path) {
|
|
1572
|
-
let end = path.length;
|
|
1573
|
-
while (end > 1 && Object.keys(objectOf$1(valueAt(user, path.slice(0, end - 1)))).length === 1) end -= 1;
|
|
1574
|
-
return path.slice(0, end);
|
|
1575
|
-
}
|
|
1576
|
-
/** Unset every field this plugin stores in the user layer; inherited values and credentials stay. */
|
|
1577
|
-
function resetSettingsOperations$1(layers) {
|
|
1578
|
-
return Object.keys(objectOf$1(layers.user)).map((key) => ({
|
|
1579
|
-
op: "unset",
|
|
1580
|
-
path: [key]
|
|
1581
|
-
}));
|
|
1582
|
-
}
|
|
1583
|
-
/** Bind the current document version and fields; no predecessor schema is inferred. */
|
|
1584
|
-
function createSparseSettings(spec) {
|
|
1585
|
-
return {
|
|
1586
|
-
documentVersion: (layers) => documentVersion$1(layers),
|
|
1587
|
-
sparseSettingOperations: (layers, path, target, fallback) => sparseSettingOperations$1(spec, layers, path, target, fallback),
|
|
1588
|
-
resetSettingsOperations: (layers) => resetSettingsOperations$1(layers)
|
|
1589
|
-
};
|
|
1590
|
-
}
|
|
1591
|
-
//#endregion
|
|
1592
|
-
//#region ../core/src/client/settings/parts.tsx
|
|
1593
|
-
/** Building blocks shared by the settings sections. */
|
|
1594
|
-
function classNames(...args) {
|
|
1595
|
-
return args.flat(Number.POSITIVE_INFINITY).filter(Boolean).map((arg) => {
|
|
1596
|
-
if (typeof arg === "string") return arg;
|
|
1597
|
-
if (typeof arg === "object" && arg !== null) return Object.entries(arg).filter(([, v]) => Boolean(v)).map(([k]) => k).join(" ");
|
|
1598
|
-
return "";
|
|
1599
|
-
}).filter(Boolean).join(" ");
|
|
1600
|
-
}
|
|
1601
|
-
/** A local schema failure whose diagnostic stays out of the translated message. */
|
|
1602
|
-
var SettingsValidationError = class extends Error {};
|
|
1603
|
-
function createSettingsParts({ classes: css, keys }) {
|
|
1604
|
-
function Section({ title, actions, children }) {
|
|
1605
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
1606
|
-
className: css.section,
|
|
1607
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1608
|
-
className: css.sectionHead,
|
|
1609
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
1610
|
-
className: css.sectionTitle,
|
|
1611
|
-
children: title
|
|
1612
|
-
}), actions]
|
|
1613
|
-
}), children]
|
|
1614
|
-
});
|
|
1615
|
-
}
|
|
1616
|
-
/** Title and hint on the left, one control on the right; wraps under the text on narrow pages. */
|
|
1617
|
-
function SettingRow({ title, hint, children }) {
|
|
1618
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1619
|
-
className: css.settingRow,
|
|
1620
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1621
|
-
className: css.settingText,
|
|
1622
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1623
|
-
className: css.settingTitle,
|
|
1624
|
-
children: title
|
|
1625
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1626
|
-
className: css.hint,
|
|
1627
|
-
children: hint
|
|
1628
|
-
})]
|
|
1629
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1630
|
-
className: css.settingControl,
|
|
1631
|
-
children
|
|
1632
|
-
})]
|
|
1633
|
-
});
|
|
1634
|
-
}
|
|
1635
|
-
/** A dropdown in the settings pill style, built on the shared Menu. */
|
|
1636
|
-
function SelectMenu({ label, title, value, options, disabled, onChange, compact = false }) {
|
|
1637
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
1638
|
-
const current = options.find((option) => option.id === value);
|
|
1639
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
1640
|
-
open,
|
|
1641
|
-
onClose: () => {
|
|
1642
|
-
setOpen(false);
|
|
1643
|
-
},
|
|
1644
|
-
items: options.map((option) => ({
|
|
1645
|
-
id: option.id,
|
|
1646
|
-
label: option.label
|
|
1647
|
-
})),
|
|
1648
|
-
selectedId: value,
|
|
1649
|
-
onSelect: (id) => {
|
|
1650
|
-
setOpen(false);
|
|
1651
|
-
if (id !== value) onChange(id);
|
|
1652
|
-
},
|
|
1653
|
-
align: "end",
|
|
1654
|
-
portal: true,
|
|
1655
|
-
anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
1656
|
-
type: "button",
|
|
1657
|
-
className: compact ? css.selectCompact : css.select,
|
|
1658
|
-
"aria-label": label,
|
|
1659
|
-
title,
|
|
1660
|
-
"aria-haspopup": "menu",
|
|
1661
|
-
"aria-expanded": open,
|
|
1662
|
-
disabled,
|
|
1663
|
-
onClick: () => {
|
|
1664
|
-
setOpen(!open);
|
|
1665
|
-
},
|
|
1666
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1667
|
-
className: css.selectValue,
|
|
1668
|
-
children: current?.label ?? value
|
|
1669
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { className: css.selectChevron })]
|
|
1670
|
-
})
|
|
1671
|
-
});
|
|
1672
|
-
}
|
|
1673
|
-
/** Pending state and the last failure of one section's writes. */
|
|
1674
|
-
function useWrite(t) {
|
|
1675
|
-
const [state, setState] = (0, react.useState)({
|
|
1676
|
-
busy: false,
|
|
1677
|
-
error: void 0,
|
|
1678
|
-
errorTitle: void 0
|
|
1679
|
-
});
|
|
1680
|
-
const run = async (work) => {
|
|
1681
|
-
setState({
|
|
1682
|
-
busy: true,
|
|
1683
|
-
error: void 0,
|
|
1684
|
-
errorTitle: void 0
|
|
1685
|
-
});
|
|
1686
|
-
try {
|
|
1687
|
-
const accepted = await work();
|
|
1688
|
-
setState({
|
|
1689
|
-
busy: false,
|
|
1690
|
-
error: accepted ? void 0 : t(keys.refused),
|
|
1691
|
-
errorTitle: void 0
|
|
1692
|
-
});
|
|
1693
|
-
return accepted;
|
|
1694
|
-
} catch (error) {
|
|
1695
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1696
|
-
const invalid = error instanceof SettingsValidationError;
|
|
1697
|
-
setState({
|
|
1698
|
-
busy: false,
|
|
1699
|
-
error: invalid ? t(keys.invalid) : message || t(keys.failed),
|
|
1700
|
-
errorTitle: invalid ? message : void 0
|
|
1701
|
-
});
|
|
1702
|
-
return false;
|
|
1703
|
-
}
|
|
1704
|
-
};
|
|
1705
|
-
return {
|
|
1706
|
-
...state,
|
|
1707
|
-
run
|
|
1708
|
-
};
|
|
1709
|
-
}
|
|
1710
|
-
function ErrorText({ children, title }) {
|
|
1711
|
-
return children === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
1712
|
-
className: css.error,
|
|
1713
|
-
role: "alert",
|
|
1714
|
-
title,
|
|
1715
|
-
children
|
|
1975
|
+
const ops = [];
|
|
1976
|
+
if (target === void 0 || equal(target, inherited)) {
|
|
1977
|
+
if (user !== void 0) ops.push({
|
|
1978
|
+
op: "unset",
|
|
1979
|
+
path: prunedPath(layers.user, path)
|
|
1716
1980
|
});
|
|
1717
|
-
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
"aria-label": message,
|
|
1724
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1725
|
-
className: css.confirmText,
|
|
1726
|
-
children: message
|
|
1727
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1728
|
-
className: css.actions,
|
|
1729
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1730
|
-
variant: "ghost",
|
|
1731
|
-
size: "sm",
|
|
1732
|
-
onClick: onCancel,
|
|
1733
|
-
children: cancelLabel
|
|
1734
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1735
|
-
variant: "outline",
|
|
1736
|
-
size: "sm",
|
|
1737
|
-
className: css.danger,
|
|
1738
|
-
disabled,
|
|
1739
|
-
onClick: onConfirm,
|
|
1740
|
-
children: confirmLabel
|
|
1741
|
-
})]
|
|
1742
|
-
})]
|
|
1981
|
+
} else {
|
|
1982
|
+
const sparse = delta(target, inherited);
|
|
1983
|
+
if (!equal(sparse, user)) ops.push({
|
|
1984
|
+
op: "set",
|
|
1985
|
+
path: [...path],
|
|
1986
|
+
value: sparse
|
|
1743
1987
|
});
|
|
1744
1988
|
}
|
|
1989
|
+
if (ops.some((op) => op.op === "set") && objectOf(layers.user).version !== spec.version) ops.push({
|
|
1990
|
+
op: "set",
|
|
1991
|
+
path: ["version"],
|
|
1992
|
+
value: spec.version
|
|
1993
|
+
});
|
|
1994
|
+
return ops;
|
|
1995
|
+
}
|
|
1996
|
+
function valueAt(root, path) {
|
|
1997
|
+
return path.reduce((value, key) => objectOf(value)[key], root);
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* The path to unset so no empty object stays behind: removing the only key of
|
|
2001
|
+
* a user-layer object removes that object instead, up to a top-level field.
|
|
2002
|
+
*/
|
|
2003
|
+
function prunedPath(user, path) {
|
|
2004
|
+
let end = path.length;
|
|
2005
|
+
while (end > 1 && Object.keys(objectOf(valueAt(user, path.slice(0, end - 1)))).length === 1) end -= 1;
|
|
2006
|
+
return path.slice(0, end);
|
|
2007
|
+
}
|
|
2008
|
+
/** Unset every field this plugin stores in the user layer; inherited values and credentials stay. */
|
|
2009
|
+
function resetSettingsOperations$1(layers) {
|
|
2010
|
+
return Object.keys(objectOf(layers.user)).map((key) => ({
|
|
2011
|
+
op: "unset",
|
|
2012
|
+
path: [key]
|
|
2013
|
+
}));
|
|
2014
|
+
}
|
|
2015
|
+
/** Bind the current document version and fields; no predecessor schema is inferred. */
|
|
2016
|
+
function createSparseSettings(spec) {
|
|
1745
2017
|
return {
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
ErrorText,
|
|
1750
|
-
ConfirmRow,
|
|
1751
|
-
useWrite
|
|
2018
|
+
documentVersion: (layers) => documentVersion$1(layers),
|
|
2019
|
+
sparseSettingOperations: (layers, path, target, fallback) => sparseSettingOperations$1(spec, layers, path, target, fallback),
|
|
2020
|
+
resetSettingsOperations: (layers) => resetSettingsOperations$1(layers)
|
|
1752
2021
|
};
|
|
1753
2022
|
}
|
|
1754
|
-
function applyOps(user, ops) {
|
|
1755
|
-
const root = structuredClone(user !== null && typeof user === "object" && !Array.isArray(user) ? user : {});
|
|
1756
|
-
for (const op of ops) {
|
|
1757
|
-
if (op.path.length === 0) continue;
|
|
1758
|
-
if (op.op === "set") {
|
|
1759
|
-
let current = root;
|
|
1760
|
-
for (let i = 0; i < op.path.length - 1; i++) {
|
|
1761
|
-
const seg = op.path[i];
|
|
1762
|
-
if (current[seg] === null || typeof current[seg] !== "object" || Array.isArray(current[seg])) current[seg] = {};
|
|
1763
|
-
current = current[seg];
|
|
1764
|
-
}
|
|
1765
|
-
current[op.path.at(-1)] = structuredClone(op.value);
|
|
1766
|
-
} else if (op.op === "unset") {
|
|
1767
|
-
let current = root;
|
|
1768
|
-
for (let i = 0; i < op.path.length - 1; i++) {
|
|
1769
|
-
const seg = op.path[i];
|
|
1770
|
-
if (current[seg] === null || typeof current[seg] !== "object" || Array.isArray(current[seg])) break;
|
|
1771
|
-
current = current[seg];
|
|
1772
|
-
}
|
|
1773
|
-
delete current[op.path.at(-1)];
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
return root;
|
|
1777
|
-
}
|
|
1778
2023
|
//#endregion
|
|
1779
2024
|
//#region ../core/src/client/settings/CredentialEditor.tsx
|
|
1780
2025
|
/** Write-only key entry: the value goes to DSH Credentials and never into settings. */
|
|
@@ -2217,14 +2462,25 @@ window.__ModuleLoader__.load({
|
|
|
2217
2462
|
function adapterKeys(catalog) {
|
|
2218
2463
|
return Object.entries(catalog).filter(([, info]) => info.kind === "adapter").map(([key]) => key);
|
|
2219
2464
|
}
|
|
2465
|
+
/** A built-in entry's override as stored, its label on one line as the grammar reads it. */
|
|
2220
2466
|
function builtinOverride(config, key) {
|
|
2221
2467
|
const stored = config.connections === void 0 ? void 0 : config.connections[builtinId(key)];
|
|
2222
|
-
|
|
2468
|
+
if (stored === void 0) return {};
|
|
2469
|
+
return stored.label === void 0 ? stored : {
|
|
2470
|
+
...stored,
|
|
2471
|
+
label: singleLine(stored.label)
|
|
2472
|
+
};
|
|
2223
2473
|
}
|
|
2224
|
-
/** Custom connections in document order; the document has passed the capability's validation. */
|
|
2474
|
+
/** Custom connections in document order, labels on one line; the document has passed the capability's validation. */
|
|
2225
2475
|
function customConnections(config) {
|
|
2226
2476
|
if (config.connections === void 0) return [];
|
|
2227
|
-
return Object.entries(config.connections).filter(([id]) => CUSTOM_CONNECTION_ID.test(id)).map(([id,
|
|
2477
|
+
return Object.entries(config.connections).filter(([id]) => CUSTOM_CONNECTION_ID.test(id)).map(([id, stored]) => {
|
|
2478
|
+
const connection = stored;
|
|
2479
|
+
return [id, {
|
|
2480
|
+
...connection,
|
|
2481
|
+
label: singleLine(connection.label)
|
|
2482
|
+
}];
|
|
2483
|
+
});
|
|
2228
2484
|
}
|
|
2229
2485
|
/** Built-in connections default to the anonymous route where one exists. */
|
|
2230
2486
|
function builtinAccess(info, override) {
|
|
@@ -2560,15 +2816,19 @@ window.__ModuleLoader__.load({
|
|
|
2560
2816
|
});
|
|
2561
2817
|
function ServicesSection(props) {
|
|
2562
2818
|
const catalogKeys = Object.keys(catalog);
|
|
2563
|
-
|
|
2819
|
+
const optIn = catalogKeys.some((key) => catalog[key].optIn);
|
|
2820
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
2564
2821
|
title: props.t(keys["services.title"]),
|
|
2565
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
2822
|
+
children: [optIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2823
|
+
className: css.note,
|
|
2824
|
+
children: props.t(keys["services.optInNotice"])
|
|
2825
|
+
}) : null, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("ul", {
|
|
2566
2826
|
className: css.list,
|
|
2567
2827
|
children: catalogKeys.map((key) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ServiceRow, {
|
|
2568
2828
|
catalogKey: key,
|
|
2569
2829
|
...props
|
|
2570
2830
|
}, key))
|
|
2571
|
-
})
|
|
2831
|
+
})]
|
|
2572
2832
|
});
|
|
2573
2833
|
}
|
|
2574
2834
|
function ServiceRow({ catalogKey, doc, write, credentials, saveCredential, t }) {
|
|
@@ -2584,18 +2844,18 @@ window.__ModuleLoader__.load({
|
|
|
2584
2844
|
const credential = builtinCredential(info, override);
|
|
2585
2845
|
const credentialRef = credential === void 0 ? void 0 : credential.ref;
|
|
2586
2846
|
const credentialStatus = credentialRef === void 0 ? void 0 : credentials[credentialRef];
|
|
2587
|
-
const enabled = override.disabled
|
|
2847
|
+
const enabled = !(override.disabled ?? info.optIn);
|
|
2588
2848
|
const disabled = !doc.editable || action.busy;
|
|
2589
|
-
const operations = (path, target, fallback) => sparse.sparseSettingOperations(
|
|
2849
|
+
const operations = (layers, path, target, fallback) => sparse.sparseSettingOperations(layers, [
|
|
2590
2850
|
"connections",
|
|
2591
2851
|
connectionId,
|
|
2592
2852
|
...path
|
|
2593
2853
|
], target, fallback);
|
|
2594
|
-
const save = (path, target, fallback) => action.run(() => write(operations(path, target, fallback)));
|
|
2854
|
+
const save = (path, target, fallback) => action.run(() => write((layers) => operations(layers, path, target, fallback)));
|
|
2595
2855
|
const stored = override.options === void 0 ? {} : override.options;
|
|
2596
|
-
const saveOptions = (changes) => action.run(() => {
|
|
2597
|
-
let layers =
|
|
2598
|
-
return
|
|
2856
|
+
const saveOptions = (changes) => action.run(() => write((initial) => {
|
|
2857
|
+
let layers = initial;
|
|
2858
|
+
return Object.entries(changes).flatMap(([option, value]) => {
|
|
2599
2859
|
const next = sparse.sparseSettingOperations(layers, [
|
|
2600
2860
|
"connections",
|
|
2601
2861
|
connectionId,
|
|
@@ -2607,15 +2867,22 @@ window.__ModuleLoader__.load({
|
|
|
2607
2867
|
user: applyOps(layers.user, next)
|
|
2608
2868
|
};
|
|
2609
2869
|
return next;
|
|
2610
|
-
})
|
|
2611
|
-
});
|
|
2612
|
-
/**
|
|
2870
|
+
});
|
|
2871
|
+
}));
|
|
2872
|
+
/**
|
|
2873
|
+
* The keyless route takes only the options it accepts; the rest go in the
|
|
2874
|
+
* same write. Which ones those are is read from the layers the write runs
|
|
2875
|
+
* on: options changed while it waited stay as they are now.
|
|
2876
|
+
*/
|
|
2613
2877
|
const switchAccess = (next) => {
|
|
2614
2878
|
if (next === "api-key") return save(["access"], next, "keyless");
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2879
|
+
return action.run(() => write((layers) => {
|
|
2880
|
+
const current = builtinOverride(effectiveDocument(layers), catalogKey).options;
|
|
2881
|
+
const options = current === void 0 ? {} : current;
|
|
2882
|
+
const rejected = keylessRejected(info.options, options);
|
|
2883
|
+
const kept = Object.fromEntries(Object.entries(options).filter(([option]) => !rejected.includes(option)));
|
|
2884
|
+
return [...operations(layers, ["access"], next, "keyless"), ...rejected.length === 0 ? [] : operations(layers, ["options"], Object.keys(kept).length === 0 ? void 0 : kept)];
|
|
2885
|
+
}));
|
|
2619
2886
|
};
|
|
2620
2887
|
const note = notes[catalogKey];
|
|
2621
2888
|
const extra = extras[catalogKey];
|
|
@@ -2665,7 +2932,7 @@ window.__ModuleLoader__.load({
|
|
|
2665
2932
|
checked: enabled,
|
|
2666
2933
|
label: t(keys["services.enable"], { name }),
|
|
2667
2934
|
disabled,
|
|
2668
|
-
onChange: (next) => void save(["disabled"], !next,
|
|
2935
|
+
onChange: (next) => void save(["disabled"], !next, info.optIn)
|
|
2669
2936
|
})]
|
|
2670
2937
|
})
|
|
2671
2938
|
]
|
|
@@ -2890,7 +3157,7 @@ window.__ModuleLoader__.load({
|
|
|
2890
3157
|
const action = useWrite(t);
|
|
2891
3158
|
const disabled = !doc.editable || action.busy;
|
|
2892
3159
|
const save = (path, target, fallback) => {
|
|
2893
|
-
action.run(() => write(sparse.sparseSettingOperations(
|
|
3160
|
+
action.run(() => write((layers) => sparse.sparseSettingOperations(layers, path, target, fallback)));
|
|
2894
3161
|
};
|
|
2895
3162
|
const missing = defaultConnection !== void 0 && !choices.some((choice) => choice.id === defaultConnection);
|
|
2896
3163
|
const warning = missing ? t(keys.connectionMissing, { id: defaultConnection }) : defaultAvailability && (defaultAvailability.disabled || configurationState(true, defaultAvailability.access, defaultAvailability.credentialStatus) === "warning") ? defaultAvailability.warning : void 0;
|
|
@@ -2937,6 +3204,53 @@ window.__ModuleLoader__.load({
|
|
|
2937
3204
|
};
|
|
2938
3205
|
}
|
|
2939
3206
|
//#endregion
|
|
3207
|
+
//#region ../core/src/client/settings/EnhancedToolsSection.tsx
|
|
3208
|
+
/**
|
|
3209
|
+
* The row's Enhanced tools switch (docs/design.md, "开关与同意"): what turning
|
|
3210
|
+
* it on lets the Agent do, and what the operator agrees to by doing so.
|
|
3211
|
+
*/
|
|
3212
|
+
function createEnhancedToolsSection({ classes: css, parts: { Section, ErrorText, useWrite }, sparse, keys }) {
|
|
3213
|
+
return function EnhancedToolsSection({ doc, write, t }) {
|
|
3214
|
+
const id = (0, react.useId)();
|
|
3215
|
+
const action = useWrite(t);
|
|
3216
|
+
const enabled = doc.config.enhancedTools ?? false;
|
|
3217
|
+
const save = (next) => action.run(() => write((layers) => sparse.sparseSettingOperations(layers, ["enhancedTools"], next, false)));
|
|
3218
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Section, {
|
|
3219
|
+
title: t(keys.title),
|
|
3220
|
+
titleId: id + "-title",
|
|
3221
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3222
|
+
className: css.settingRow,
|
|
3223
|
+
role: "group",
|
|
3224
|
+
"aria-labelledby": id + "-title",
|
|
3225
|
+
"aria-describedby": id + "-description " + id + "-consent",
|
|
3226
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3227
|
+
className: css.settingText,
|
|
3228
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3229
|
+
id: id + "-description",
|
|
3230
|
+
className: css.settingLead,
|
|
3231
|
+
children: t(keys.description)
|
|
3232
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3233
|
+
id: id + "-consent",
|
|
3234
|
+
className: css.hint,
|
|
3235
|
+
children: t(keys.consent)
|
|
3236
|
+
})]
|
|
3237
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3238
|
+
className: css.settingControl,
|
|
3239
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
3240
|
+
checked: enabled,
|
|
3241
|
+
label: t(keys.title),
|
|
3242
|
+
disabled: !doc.editable || action.busy,
|
|
3243
|
+
onChange: (next) => void save(next)
|
|
3244
|
+
})
|
|
3245
|
+
})]
|
|
3246
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorText, {
|
|
3247
|
+
title: action.errorTitle,
|
|
3248
|
+
children: action.error
|
|
3249
|
+
})]
|
|
3250
|
+
});
|
|
3251
|
+
};
|
|
3252
|
+
}
|
|
3253
|
+
//#endregion
|
|
2940
3254
|
//#region ../core/src/client/settings/ResetSection.tsx
|
|
2941
3255
|
function createResetSection({ classes: css, keys, parts: { ConfirmRow, ErrorText, useWrite }, sparse }) {
|
|
2942
3256
|
return function ResetSection({ doc, write, t }) {
|
|
@@ -2971,174 +3285,39 @@ window.__ModuleLoader__.load({
|
|
|
2971
3285
|
onClick: () => {
|
|
2972
3286
|
setConfirming(true);
|
|
2973
3287
|
},
|
|
2974
|
-
children: t(keys["reset.button"])
|
|
2975
|
-
})]
|
|
2976
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorText, {
|
|
2977
|
-
title: action.errorTitle,
|
|
2978
|
-
children: action.error
|
|
2979
|
-
})]
|
|
2980
|
-
});
|
|
2981
|
-
};
|
|
2982
|
-
}
|
|
2983
|
-
//#endregion
|
|
2984
|
-
//#region ../core/src/client/settings/RouteNotice.tsx
|
|
2985
|
-
function createRouteNotice({ classes: css, keys, other }) {
|
|
2986
|
-
return function RouteNotice({ route, t }) {
|
|
2987
|
-
let text;
|
|
2988
|
-
switch (route.kind) {
|
|
2989
|
-
case "this": return null;
|
|
2990
|
-
case "unknown":
|
|
2991
|
-
text = t(keys.unknown);
|
|
2992
|
-
break;
|
|
2993
|
-
case "auto":
|
|
2994
|
-
text = t(keys.auto, { id: route.providerId });
|
|
2995
|
-
break;
|
|
2996
|
-
case "other": text = other?.(route, t) ?? t(keys.other, {
|
|
2997
|
-
provider: route.provider,
|
|
2998
|
-
id: route.providerId
|
|
2999
|
-
});
|
|
3000
|
-
}
|
|
3001
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3002
|
-
className: css.warning,
|
|
3003
|
-
role: "status",
|
|
3004
|
-
children: text
|
|
3005
|
-
});
|
|
3006
|
-
};
|
|
3007
|
-
}
|
|
3008
|
-
//#endregion
|
|
3009
|
-
//#region ../core/src/client/settings/document.ts
|
|
3010
|
-
/** ConfigForm.value is schema-projected; the raw layers retain unknown fields for validation. */
|
|
3011
|
-
function effectiveDocument(snapshot) {
|
|
3012
|
-
return merge(snapshot.base, snapshot.user);
|
|
3013
|
-
}
|
|
3014
|
-
/** Validate before exposing normal editors; only successful older migrations need writeback. */
|
|
3015
|
-
function editableSettings(raw, layers, writable, resolve, migrations = SETTINGS_MIGRATIONS) {
|
|
3016
|
-
try {
|
|
3017
|
-
const version = documentVersion$2(raw, migrations.currentVersion);
|
|
3018
|
-
const config = migrateDocument(raw, migrations);
|
|
3019
|
-
resolve(config);
|
|
3020
|
-
return {
|
|
3021
|
-
kind: "ready",
|
|
3022
|
-
config,
|
|
3023
|
-
layers,
|
|
3024
|
-
needsWriteback: writable && version.kind === "older"
|
|
3025
|
-
};
|
|
3026
|
-
} catch (error) {
|
|
3027
|
-
return {
|
|
3028
|
-
kind: "invalid",
|
|
3029
|
-
diagnostic: diagnostic(error),
|
|
3030
|
-
layers,
|
|
3031
|
-
needsWriteback: false
|
|
3032
|
-
};
|
|
3033
|
-
}
|
|
3034
|
-
}
|
|
3035
|
-
/** Check the exact recursively overlaid candidate that the settings store will persist. */
|
|
3036
|
-
function settingsOperations(layers, operations, resolve) {
|
|
3037
|
-
try {
|
|
3038
|
-
const candidate = effectiveDocument({
|
|
3039
|
-
base: layers.base,
|
|
3040
|
-
user: applyOps(layers.user, operations)
|
|
3041
|
-
});
|
|
3042
|
-
const result = [...operations];
|
|
3043
|
-
if (result.some((op) => op.op === "set") && candidate.version === void 0) {
|
|
3044
|
-
result.push({
|
|
3045
|
-
op: "set",
|
|
3046
|
-
path: ["version"],
|
|
3047
|
-
value: 2
|
|
3048
|
-
});
|
|
3049
|
-
candidate.version = 2;
|
|
3050
|
-
}
|
|
3051
|
-
resolve(candidate);
|
|
3052
|
-
return result;
|
|
3053
|
-
} catch (error) {
|
|
3054
|
-
throw new SettingsValidationError(diagnostic(error));
|
|
3055
|
-
}
|
|
3056
|
-
}
|
|
3057
|
-
/** Share validation, revision fencing and automatic future migrations between both pages. */
|
|
3058
|
-
function useSettingsDocument(snapshot, resolve, mutate, migrations = SETTINGS_MIGRATIONS) {
|
|
3059
|
-
const view = (0, react.useMemo)(() => {
|
|
3060
|
-
if (snapshot.status === "unavailable" || snapshot.value === void 0 || snapshot.revision === void 0) return void 0;
|
|
3061
|
-
const result = editableSettings(effectiveDocument(snapshot), {
|
|
3062
|
-
base: snapshot.base,
|
|
3063
|
-
user: snapshot.user
|
|
3064
|
-
}, snapshot.writable, resolve, migrations);
|
|
3065
|
-
if (snapshot.diagnostic === void 0) return result;
|
|
3066
|
-
return {
|
|
3067
|
-
kind: "invalid",
|
|
3068
|
-
layers: result.layers,
|
|
3069
|
-
needsWriteback: false,
|
|
3070
|
-
diagnostic: result.kind === "invalid" ? result.diagnostic + "; " + snapshot.diagnostic : snapshot.diagnostic
|
|
3071
|
-
};
|
|
3072
|
-
}, [
|
|
3073
|
-
snapshot,
|
|
3074
|
-
resolve,
|
|
3075
|
-
migrations
|
|
3076
|
-
]);
|
|
3077
|
-
const attemptedRevision = (0, react.useRef)(void 0);
|
|
3078
|
-
const [failure, setFailure] = (0, react.useState)();
|
|
3079
|
-
const revision = snapshot.revision;
|
|
3080
|
-
(0, react.useEffect)(() => {
|
|
3081
|
-
if (view?.kind !== "ready" || !view.needsWriteback || revision === void 0 || attemptedRevision.current === revision) return;
|
|
3082
|
-
attemptedRevision.current = revision;
|
|
3083
|
-
const writeback = async () => {
|
|
3084
|
-
try {
|
|
3085
|
-
const operations = replaceDocumentOperations(view.layers.user, view.config);
|
|
3086
|
-
await mutate(settingsOperations(view.layers, operations, resolve), revision);
|
|
3087
|
-
} catch (error) {
|
|
3088
|
-
setFailure({
|
|
3089
|
-
revision,
|
|
3090
|
-
diagnostic: diagnostic(error)
|
|
3091
|
-
});
|
|
3092
|
-
}
|
|
3093
|
-
};
|
|
3094
|
-
writeback();
|
|
3095
|
-
}, [
|
|
3096
|
-
view,
|
|
3097
|
-
revision,
|
|
3098
|
-
resolve,
|
|
3099
|
-
mutate
|
|
3100
|
-
]);
|
|
3101
|
-
const write = async (operations, expectedRevision = revision) => {
|
|
3102
|
-
if (operations.length === 0) return true;
|
|
3103
|
-
if (view === void 0 || !snapshot.writable || expectedRevision === void 0) return false;
|
|
3104
|
-
return mutate(settingsOperations(view.layers, operations, resolve), expectedRevision);
|
|
3105
|
-
};
|
|
3106
|
-
return {
|
|
3107
|
-
view,
|
|
3108
|
-
write,
|
|
3109
|
-
migrationError: failure?.revision === revision ? failure?.diagnostic : void 0
|
|
3288
|
+
children: t(keys["reset.button"])
|
|
3289
|
+
})]
|
|
3290
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ErrorText, {
|
|
3291
|
+
title: action.errorTitle,
|
|
3292
|
+
children: action.error
|
|
3293
|
+
})]
|
|
3294
|
+
});
|
|
3110
3295
|
};
|
|
3111
3296
|
}
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
value: isObject(value) && isObject(result[key]) ? merge(result[key], value) : value,
|
|
3137
|
-
enumerable: true,
|
|
3138
|
-
writable: true,
|
|
3139
|
-
configurable: true
|
|
3140
|
-
});
|
|
3141
|
-
return result;
|
|
3297
|
+
//#endregion
|
|
3298
|
+
//#region ../core/src/client/settings/RouteNotice.tsx
|
|
3299
|
+
function createRouteNotice({ classes: css, keys, other }) {
|
|
3300
|
+
return function RouteNotice({ route, t }) {
|
|
3301
|
+
let text;
|
|
3302
|
+
switch (route.kind) {
|
|
3303
|
+
case "this": return null;
|
|
3304
|
+
case "unknown":
|
|
3305
|
+
text = t(keys.unknown);
|
|
3306
|
+
break;
|
|
3307
|
+
case "auto":
|
|
3308
|
+
text = t(keys.auto, { id: route.providerId });
|
|
3309
|
+
break;
|
|
3310
|
+
case "other": text = other?.(route, t) ?? t(keys.other, {
|
|
3311
|
+
provider: route.provider,
|
|
3312
|
+
id: route.providerId
|
|
3313
|
+
});
|
|
3314
|
+
}
|
|
3315
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
3316
|
+
className: css.warning,
|
|
3317
|
+
role: "status",
|
|
3318
|
+
children: text
|
|
3319
|
+
});
|
|
3320
|
+
};
|
|
3142
3321
|
}
|
|
3143
3322
|
//#endregion
|
|
3144
3323
|
//#region ../core/src/client/settings/secret-diagnostics.ts
|
|
@@ -3248,7 +3427,7 @@ window.__ModuleLoader__.load({
|
|
|
3248
3427
|
const options = connection.options === void 0 ? {} : connection.options;
|
|
3249
3428
|
const fields = {
|
|
3250
3429
|
id,
|
|
3251
|
-
label: connection.label,
|
|
3430
|
+
label: singleLine(connection.label),
|
|
3252
3431
|
credentialRef: connection.credentialRef,
|
|
3253
3432
|
endpoint: connection.endpoint === void 0 ? "" : connection.endpoint,
|
|
3254
3433
|
options: Object.fromEntries(Object.entries(options).map(([name, value]) => [name, fieldText(value)]))
|
|
@@ -3322,7 +3501,7 @@ window.__ModuleLoader__.load({
|
|
|
3322
3501
|
const form = {
|
|
3323
3502
|
...input,
|
|
3324
3503
|
id: input.id.trim(),
|
|
3325
|
-
label: input.label
|
|
3504
|
+
label: singleLine(input.label),
|
|
3326
3505
|
credentialRef: input.credentialRef.trim(),
|
|
3327
3506
|
endpoint: input.endpoint.trim()
|
|
3328
3507
|
};
|
|
@@ -3841,7 +4020,7 @@ window.__ModuleLoader__.load({
|
|
|
3841
4020
|
const disabled = !doc.editable || action.busy;
|
|
3842
4021
|
const userConnections = doc.layers.user?.connections;
|
|
3843
4022
|
const removable = userConnections !== void 0 && Object.hasOwn(userConnections, id);
|
|
3844
|
-
const save = (path, target, fallback) => action.run(() => write(sparse.sparseSettingOperations(
|
|
4023
|
+
const save = (path, target, fallback) => action.run(() => write((layers) => sparse.sparseSettingOperations(layers, [
|
|
3845
4024
|
"connections",
|
|
3846
4025
|
id,
|
|
3847
4026
|
...path
|
|
@@ -3973,6 +4152,49 @@ window.__ModuleLoader__.load({
|
|
|
3973
4152
|
"searchContextSize"
|
|
3974
4153
|
];
|
|
3975
4154
|
//#endregion
|
|
4155
|
+
//#region src/settings/resolve.ts
|
|
4156
|
+
const defaultsSchema = zod.z.strictObject({ freshness: zod.z.enum(FRESHNESS).default("auto") });
|
|
4157
|
+
/** Pure sparse resolution shared by Host and browser. */
|
|
4158
|
+
function resolveSettings(document = {}) {
|
|
4159
|
+
const resolved = resolveDocument({
|
|
4160
|
+
catalog: CATALOG,
|
|
4161
|
+
protocols: MODEL_PROTOCOLS,
|
|
4162
|
+
document,
|
|
4163
|
+
retiredFields: RETIRED_FIELDS,
|
|
4164
|
+
defaults: {
|
|
4165
|
+
schema: defaultsSchema,
|
|
4166
|
+
defaultConnection: DEFAULT_CONNECTION
|
|
4167
|
+
},
|
|
4168
|
+
capabilityLabel: "search"
|
|
4169
|
+
});
|
|
4170
|
+
const connections = /* @__PURE__ */ new Map();
|
|
4171
|
+
for (const [id, connection] of resolved.connections) {
|
|
4172
|
+
const { catalogKey, ...base } = connection;
|
|
4173
|
+
switch (base.kind) {
|
|
4174
|
+
case "local": throw new Error("search catalog cannot contain a local connection");
|
|
4175
|
+
case "model":
|
|
4176
|
+
connections.set(id, base);
|
|
4177
|
+
break;
|
|
4178
|
+
case "native":
|
|
4179
|
+
connections.set(id, {
|
|
4180
|
+
...base,
|
|
4181
|
+
kind: "native",
|
|
4182
|
+
native: catalogKey
|
|
4183
|
+
});
|
|
4184
|
+
break;
|
|
4185
|
+
case "adapter": connections.set(id, {
|
|
4186
|
+
...base,
|
|
4187
|
+
kind: "adapter",
|
|
4188
|
+
adapter: catalogKey
|
|
4189
|
+
});
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
return {
|
|
4193
|
+
...resolved,
|
|
4194
|
+
connections
|
|
4195
|
+
};
|
|
4196
|
+
}
|
|
4197
|
+
//#endregion
|
|
3976
4198
|
//#region src/client/connections.ts
|
|
3977
4199
|
/** The Session-model connection keeps its catalog name only until the operator renames it; that name is localized. */
|
|
3978
4200
|
function connectionLabel(connection, t) {
|
|
@@ -4080,7 +4302,7 @@ window.__ModuleLoader__.load({
|
|
|
4080
4302
|
}
|
|
4081
4303
|
//#endregion
|
|
4082
4304
|
//#region src/client/command.ts
|
|
4083
|
-
const SEARCH_COMMAND =
|
|
4305
|
+
const SEARCH_COMMAND = SEARCH.command;
|
|
4084
4306
|
const FRESHNESS_PREFIX = "freshness:";
|
|
4085
4307
|
const parseFreshness = (id) => {
|
|
4086
4308
|
const freshness = FRESHNESS.find((mode) => id === FRESHNESS_PREFIX + mode);
|
|
@@ -4089,11 +4311,8 @@ window.__ModuleLoader__.load({
|
|
|
4089
4311
|
function searchCommand(selections, t) {
|
|
4090
4312
|
return selectionCommand(selections, {
|
|
4091
4313
|
name: SEARCH_COMMAND,
|
|
4092
|
-
icon: _deepseek_ai_dsh_client_ui_primitives.IconGlobeOutlineRegular,
|
|
4093
4314
|
t,
|
|
4094
4315
|
keys: {
|
|
4095
|
-
label: "command.label",
|
|
4096
|
-
description: "command.description",
|
|
4097
4316
|
placeholder: "command.placeholder",
|
|
4098
4317
|
empty: "command.empty",
|
|
4099
4318
|
noResults: "command.noResults",
|
|
@@ -4134,49 +4353,6 @@ window.__ModuleLoader__.load({
|
|
|
4134
4353
|
});
|
|
4135
4354
|
}
|
|
4136
4355
|
//#endregion
|
|
4137
|
-
//#region src/settings/resolve.ts
|
|
4138
|
-
const defaultsSchema = zod.z.strictObject({ freshness: zod.z.enum(FRESHNESS).default("auto") });
|
|
4139
|
-
/** Pure sparse resolution shared by Host and browser. */
|
|
4140
|
-
function resolveSettings(document = {}) {
|
|
4141
|
-
const resolved = resolveDocument({
|
|
4142
|
-
catalog: CATALOG,
|
|
4143
|
-
protocols: MODEL_PROTOCOLS,
|
|
4144
|
-
document,
|
|
4145
|
-
retiredFields: RETIRED_FIELDS,
|
|
4146
|
-
defaults: {
|
|
4147
|
-
schema: defaultsSchema,
|
|
4148
|
-
defaultConnection: DEFAULT_CONNECTION
|
|
4149
|
-
},
|
|
4150
|
-
capabilityLabel: "search"
|
|
4151
|
-
});
|
|
4152
|
-
const connections = /* @__PURE__ */ new Map();
|
|
4153
|
-
for (const [id, connection] of resolved.connections) {
|
|
4154
|
-
const { catalogKey, ...base } = connection;
|
|
4155
|
-
switch (base.kind) {
|
|
4156
|
-
case "local": throw new Error("search catalog cannot contain a local connection");
|
|
4157
|
-
case "model":
|
|
4158
|
-
connections.set(id, base);
|
|
4159
|
-
break;
|
|
4160
|
-
case "native":
|
|
4161
|
-
connections.set(id, {
|
|
4162
|
-
...base,
|
|
4163
|
-
kind: "native",
|
|
4164
|
-
native: catalogKey
|
|
4165
|
-
});
|
|
4166
|
-
break;
|
|
4167
|
-
case "adapter": connections.set(id, {
|
|
4168
|
-
...base,
|
|
4169
|
-
kind: "adapter",
|
|
4170
|
-
adapter: catalogKey
|
|
4171
|
-
});
|
|
4172
|
-
}
|
|
4173
|
-
}
|
|
4174
|
-
return {
|
|
4175
|
-
...resolved,
|
|
4176
|
-
connections
|
|
4177
|
-
};
|
|
4178
|
-
}
|
|
4179
|
-
//#endregion
|
|
4180
4356
|
//#region src/client/credentials.ts
|
|
4181
4357
|
/** The DSH credential a connection names; the Session-model connection uses the Session route's own. */
|
|
4182
4358
|
function credentialRefsOf(connection) {
|
|
@@ -4275,6 +4451,10 @@ window.__ModuleLoader__.load({
|
|
|
4275
4451
|
"defaults.showSelectorHint": "When hidden, switch the current conversation with /setup-search.",
|
|
4276
4452
|
"defaults.freshnessKeyOnly": "{name} (personal key)",
|
|
4277
4453
|
"services.title": "Search connections",
|
|
4454
|
+
"services.optInNotice": "Remote services are off by default.",
|
|
4455
|
+
"enhanced.title": "Enhanced tools",
|
|
4456
|
+
"enhanced.description": "Lets the Agent pick which enabled service runs a search with web_search_enhanced, and see the choices with list_web_search_providers. Applies to conversations started afterwards.",
|
|
4457
|
+
"enhanced.consent": "Turning this on means you agree that when the Agent picks a service, the query is sent to that service.",
|
|
4278
4458
|
"services.enable": "Enable {name}",
|
|
4279
4459
|
"services.configure": "Configure",
|
|
4280
4460
|
"services.configureLabel": "Configure {name}",
|
|
@@ -4400,7 +4580,7 @@ window.__ModuleLoader__.load({
|
|
|
4400
4580
|
"status.modelReady": "{access} · model search · sent to {name}",
|
|
4401
4581
|
"status.sessionModelNeedsKey": "The conversation model's API key isn't set",
|
|
4402
4582
|
"status.sessionModelNeedsSignIn": "Sign in to the DeepSeek account again",
|
|
4403
|
-
"status.reason.no-model": "
|
|
4583
|
+
"status.reason.no-model": "The model for this conversation's next request isn't known yet",
|
|
4404
4584
|
"status.reason.unknown-route": "Can't read the settings of this model's provider",
|
|
4405
4585
|
"status.reason.protocol": "Its route declares no supported api",
|
|
4406
4586
|
"status.reason.endpoint": "Its route has no fixed endpoint",
|
|
@@ -4488,7 +4668,7 @@ window.__ModuleLoader__.load({
|
|
|
4488
4668
|
"freshness.auto": "自动",
|
|
4489
4669
|
"freshness.fresh": "24 小时内",
|
|
4490
4670
|
"freshness.realtime": "实时",
|
|
4491
|
-
"status.disabled": "{name}
|
|
4671
|
+
"status.disabled": "{name} 未在设置中启用。",
|
|
4492
4672
|
"status.needsCredential": "需要 API Key",
|
|
4493
4673
|
"status.needsAccount": "需要 DeepSeek 账号或 API Key",
|
|
4494
4674
|
"status.unsupported": "本版本不支持 {name}。",
|
|
@@ -4501,7 +4681,7 @@ window.__ModuleLoader__.load({
|
|
|
4501
4681
|
"selector.freshnessIgnored": "{name} 不支持此偏好,选择不会生效。",
|
|
4502
4682
|
"selector.offRow": "关闭",
|
|
4503
4683
|
"write.conflict": "搜索设置已在别处更改,菜单已显示最新选择。",
|
|
4504
|
-
"write.unavailable": "
|
|
4684
|
+
"write.unavailable": "该连接未启用或已移除。",
|
|
4505
4685
|
"write.failed": "保存失败,请重试。",
|
|
4506
4686
|
"command.label": "搜索连接",
|
|
4507
4687
|
"command.description": "切换当前会话的搜索连接与内容实时性",
|
|
@@ -4532,10 +4712,14 @@ window.__ModuleLoader__.load({
|
|
|
4532
4712
|
"defaults.showSelectorHint": "隐藏后可用 /setup-search 切换当前会话。",
|
|
4533
4713
|
"defaults.freshnessKeyOnly": "{name}(个人密钥)",
|
|
4534
4714
|
"services.title": "搜索连接",
|
|
4715
|
+
"services.optInNotice": "远程服务默认关闭。",
|
|
4716
|
+
"enhanced.title": "增强工具",
|
|
4717
|
+
"enhanced.description": "让 Agent 用 web_search_enhanced 在已启用的服务中自行选择本次搜索用哪个,并用 list_web_search_providers 查看可选项。只影响之后新建的会话。",
|
|
4718
|
+
"enhanced.consent": "打开即表示同意:Agent 选用某个服务时,查询会发送给该服务。",
|
|
4535
4719
|
"services.enable": "启用 {name}",
|
|
4536
4720
|
"services.configure": "配置",
|
|
4537
4721
|
"services.configureLabel": "配置 {name}",
|
|
4538
|
-
"services.off": "
|
|
4722
|
+
"services.off": "未启用",
|
|
4539
4723
|
"services.keyless": "无需密钥",
|
|
4540
4724
|
"services.personalKey": "个人密钥 {ref}",
|
|
4541
4725
|
"services.account": "DeepSeek 账号或 {ref}",
|
|
@@ -4657,7 +4841,7 @@ window.__ModuleLoader__.load({
|
|
|
4657
4841
|
"status.modelReady": "{access} · 模型搜索 · 查询发送给 {name}",
|
|
4658
4842
|
"status.sessionModelNeedsKey": "会话模型的 API Key 未设置",
|
|
4659
4843
|
"status.sessionModelNeedsSignIn": "请重新登录 DeepSeek 账号",
|
|
4660
|
-
"status.reason.no-model": "
|
|
4844
|
+
"status.reason.no-model": "还不知道本会话下一次请求用哪个模型",
|
|
4661
4845
|
"status.reason.unknown-route": "无法读取会话模型服务商的设置",
|
|
4662
4846
|
"status.reason.protocol": "该路由在模型设置里没有声明支持的 api",
|
|
4663
4847
|
"status.reason.endpoint": "该路由在模型设置里没有固定的接口地址",
|
|
@@ -4742,14 +4926,14 @@ window.__ModuleLoader__.load({
|
|
|
4742
4926
|
}
|
|
4743
4927
|
var Section_module_css_default = {
|
|
4744
4928
|
"container": "La6KHG_container",
|
|
4929
|
+
"label": "La6KHG_label",
|
|
4745
4930
|
"caption": "La6KHG_caption",
|
|
4746
|
-
"segmented": "La6KHG_segmented",
|
|
4747
4931
|
"error": "La6KHG_error",
|
|
4748
|
-
"
|
|
4932
|
+
"segmented": "La6KHG_segmented"
|
|
4749
4933
|
};
|
|
4750
4934
|
//#endregion
|
|
4751
4935
|
//#region src/client/section.ts
|
|
4752
|
-
function searchSection(selection, settings, t) {
|
|
4936
|
+
function searchSection(selection, settings, remoteServicesOff, t) {
|
|
4753
4937
|
function Options({ sessionId }) {
|
|
4754
4938
|
const state = useObservable(selection.source(sessionId));
|
|
4755
4939
|
const [error, setError] = (0, react.useState)("");
|
|
@@ -4787,6 +4971,7 @@ window.__ModuleLoader__.load({
|
|
|
4787
4971
|
title: () => t("section.title"),
|
|
4788
4972
|
selection,
|
|
4789
4973
|
settings,
|
|
4974
|
+
remoteServicesOff,
|
|
4790
4975
|
Options,
|
|
4791
4976
|
describe: (connection) => describe(connection, t),
|
|
4792
4977
|
sourceText: (view) => sourceText(view, t),
|
|
@@ -4802,7 +4987,7 @@ window.__ModuleLoader__.load({
|
|
|
4802
4987
|
};
|
|
4803
4988
|
//#endregion
|
|
4804
4989
|
//#region \0dsh-css-module:/home/runner/work/dsh-tool-web-enhanced/dsh-tool-web-enhanced/packages/search-enhanced/src/client/settings/Settings.module.css.mjs
|
|
4805
|
-
const css = ".o9fCSq_page{min-width:0;color:var(--dsw-alias-label-primary);flex-direction:column;gap:28px;display:flex;container-type:inline-size}.o9fCSq_intro{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}.o9fCSq_status{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;margin:0;font-size:13px;line-height:20px;display:flex}.o9fCSq_warning{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label);margin:0;padding:8px 12px;font-size:12px;line-height:18px}.o9fCSq_section{flex-direction:column;gap:4px;min-width:0;display:flex}.o9fCSq_sectionHead{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;min-height:28px;display:flex}.o9fCSq_sectionTitle{margin:0;font-size:14px;font-weight:500;line-height:20px}.o9fCSq_sectionActions{flex-wrap:wrap;gap:4px;display:flex}.o9fCSq_hint,.o9fCSq_note{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.o9fCSq_panel .o9fCSq_hint,.o9fCSq_editor .o9fCSq_hint{color:var(--dsw-alias-label-secondary)}.o9fCSq_hint [role=status]{color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;margin-top:4px;display:flex}.o9fCSq_note{color:var(--dsw-alias-label-secondary)}.o9fCSq_error,.o9fCSq_success,.o9fCSq_fieldError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.o9fCSq_success{color:var(--dsw-alias-state-success-primary)}.o9fCSq_settingRow{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 24px;padding:14px 2px;display:flex}.o9fCSq_settingRow:last-of-type{border-bottom:0}.o9fCSq_settingText{flex-direction:column;flex:200px;gap:2px;min-width:0;display:flex}.o9fCSq_settingTitle{font-size:13.5px;font-weight:500;line-height:20px}.o9fCSq_settingControl{flex:0 auto;justify-content:flex-end;min-width:0;max-width:100%;display:flex}.o9fCSq_selectAnchor{min-width:0;max-width:100%}.o9fCSq_select,.o9fCSq_selectCompact{box-sizing:border-box;border-radius:var(--dsw-radius-md);min-width:0;max-width:100%;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;align-items:center;gap:8px;font-size:13px;line-height:20px;display:inline-flex}.o9fCSq_select{background:var(--dsw-alias-bg-module-platform);height:36px;padding:0 12px 0 14px}.o9fCSq_selectCompact{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1);justify-content:space-between;width:100%;height:36px;padding:0 10px 0 12px}.o9fCSq_select:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.o9fCSq_select:disabled,.o9fCSq_selectCompact:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.o9fCSq_select:focus-visible,.o9fCSq_selectCompact:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:1px}.o9fCSq_selectValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.o9fCSq_selectChevron{color:var(--dsw-alias-label-tertiary);flex:none}.o9fCSq_list{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.o9fCSq_row{border-bottom:.5px solid var(--dsw-alias-border-l2);padding:12px 2px}.o9fCSq_row:last-child{border-bottom:0}.o9fCSq_rowLine{align-items:center;gap:8px 12px;min-width:0;display:flex}.o9fCSq_rowMain{flex-direction:column;flex:1 1 0;gap:2px;min-width:0;display:flex}.o9fCSq_rowTitle{flex-wrap:wrap;align-items:center;gap:6px;font-size:13.5px;font-weight:500;line-height:20px;display:inline-flex}.o9fCSq_rowMeta{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:12px;line-height:18px}.o9fCSq_rowMeta code,.o9fCSq_optionKey{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);font-size:11.5px}.o9fCSq_rowActions{box-sizing:border-box;flex-wrap:wrap;flex:none;align-items:center;gap:4px;display:flex}@container (width<=560px){.o9fCSq_rowLine:has(.o9fCSq_rowActions){flex-wrap:wrap}.o9fCSq_rowActions{flex-basis:100%;order:3;padding-left:10px}}.o9fCSq_segmented{align-self:flex-start;max-width:100%}.o9fCSq_disclosure{color:var(--dsw-alias-label-secondary)}.o9fCSq_disclosureIcon{flex:none;width:12px;height:12px;transition:transform .12s}.o9fCSq_disclosureOpen{transform:rotate(180deg)}@media (prefers-reduced-motion:reduce){.o9fCSq_disclosureIcon{transition:none}}.o9fCSq_danger{color:var(--dsw-alias-state-error-primary)}.o9fCSq_panel,.o9fCSq_editor{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:16px;margin:12px 0 2px;padding:16px;display:flex}.o9fCSq_field,.o9fCSq_formField{flex-direction:column;gap:6px;min-width:0;display:flex}.o9fCSq_fieldHead{align-items:center;gap:8px;display:flex}.o9fCSq_fieldLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.o9fCSq_fieldState{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.o9fCSq_inline{flex-wrap:wrap;gap:8px;display:flex}.o9fCSq_inline>.o9fCSq_input{flex:160px}.o9fCSq_input{box-sizing:border-box;min-width:0;height:36px}.o9fCSq_input:has(input[aria-invalid=true]){border-color:var(--dsw-alias-state-error-primary)}.o9fCSq_link{color:var(--dsw-alias-link);align-self:flex-start;align-items:center;gap:2px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;display:inline-flex}.o9fCSq_link:hover,.o9fCSq_link:focus-visible{text-underline-offset:3px;text-decoration:underline dotted}.o9fCSq_optionGrid{grid-template-columns:repeat(auto-fill,minmax(min(100%,200px),1fr));gap:12px 16px;display:grid}.o9fCSq_option{flex-direction:column;gap:4px;min-width:0;display:flex}.o9fCSq_optionName{min-width:0;color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;font-size:12px;line-height:18px;display:flex}.o9fCSq_optionKey{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);overflow:hidden}.o9fCSq_actions{flex-wrap:wrap;justify-content:flex-end;gap:8px;display:flex}.o9fCSq_empty{color:var(--dsw-alias-label-tertiary);margin:0;padding:8px 2px;font-size:13px;line-height:20px}.o9fCSq_editorTitle{margin:0;font-size:13.5px;font-weight:500;line-height:20px}.o9fCSq_formGrid{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;gap:14px 16px;display:grid}.o9fCSq_formWide{grid-column:1/-1}@container (width<=760px){.o9fCSq_optionGrid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (width<=480px){.o9fCSq_optionGrid{grid-template-columns:minmax(0,1fr)}.o9fCSq_settingControl{flex-basis:100%;justify-content:flex-start}.o9fCSq_panel{padding:12px}}@container (width<=520px){.o9fCSq_formGrid{grid-template-columns:minmax(0,1fr)}}.o9fCSq_prefixed{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);align-items:center;height:36px;padding:0 8px 0 10px;display:flex}.o9fCSq_prefixed:focus-within{border-color:var(--dsw-alias-state-business-primary)}.o9fCSq_prefixedDisabled{color:var(--dsw-alias-label-tertiary)}.o9fCSq_prefix{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-tertiary);flex:none;font-size:13px;line-height:22px}.o9fCSq_prefixedInput{min-width:0;font:inherit;color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;flex:1;padding:0;font-size:14px;line-height:22px}.o9fCSq_prefixedInput::placeholder{color:var(--dsw-alias-label-dimmed)}.o9fCSq_reset{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:16px;display:flex}.o9fCSq_confirmRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 24px;display:flex}.o9fCSq_row .o9fCSq_confirmRow{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);margin-top:10px;padding:8px 12px}.o9fCSq_confirmText{min-width:0;color:var(--dsw-alias-label-secondary);flex:240px;font-size:12px;line-height:18px}.o9fCSq_optionWide{grid-column:1/-1}.o9fCSq_textarea{box-sizing:border-box;resize:vertical;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:100%;min-width:0;min-height:72px;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);padding:8px 10px;font-size:12px;line-height:20px}.o9fCSq_textarea:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.o9fCSq_textarea::placeholder{color:var(--dsw-alias-label-dimmed)}.o9fCSq_textarea[aria-invalid=true]{border-color:var(--dsw-alias-state-error-primary)}.o9fCSq_textarea:disabled{cursor:not-allowed;opacity:.5}.o9fCSq_optionGroup{border-top:.5px solid var(--dsw-alias-border-l4);flex-direction:column;gap:8px;padding-top:12px;display:flex}.o9fCSq_optionGroup:first-child,.o9fCSq_fieldHead+.o9fCSq_optionGroup{border-top:0;padding-top:0}.o9fCSq_optionGroupTitle{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500;line-height:18px}.o9fCSq_trust{border:.5px solid var(--dsw-alias-state-warn-primary);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);padding:10px 12px}.o9fCSq_trust .o9fCSq_trustCheck{align-items:flex-start}.o9fCSq_trust .o9fCSq_trustCheck input{margin-top:2px}.o9fCSq_actions>.o9fCSq_hint{flex:auto;align-self:center}";
|
|
4990
|
+
const css = ".o9fCSq_page{min-width:0;color:var(--dsw-alias-label-primary);flex-direction:column;gap:28px;display:flex;container-type:inline-size}.o9fCSq_intro{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:20px}.o9fCSq_status{color:var(--dsw-alias-label-tertiary);align-items:center;gap:6px;margin:0;font-size:13px;line-height:20px;display:flex}.o9fCSq_warning{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-state-warn-label);margin:0;padding:8px 12px;font-size:12px;line-height:18px}.o9fCSq_section{flex-direction:column;gap:4px;min-width:0;display:flex}.o9fCSq_sectionHead{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px;min-height:28px;display:flex}.o9fCSq_sectionTitle{margin:0;font-size:14px;font-weight:500;line-height:20px}.o9fCSq_sectionActions{flex-wrap:wrap;gap:4px;display:flex}.o9fCSq_hint,.o9fCSq_note{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.o9fCSq_panel .o9fCSq_hint,.o9fCSq_editor .o9fCSq_hint{color:var(--dsw-alias-label-secondary)}.o9fCSq_hint [role=status]{color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;margin-top:4px;display:flex}.o9fCSq_note{color:var(--dsw-alias-label-secondary)}.o9fCSq_error,.o9fCSq_success,.o9fCSq_fieldError{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.o9fCSq_success{color:var(--dsw-alias-state-success-primary)}.o9fCSq_settingRow{border-bottom:.5px solid var(--dsw-alias-border-l2);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 24px;padding:14px 2px;display:flex}.o9fCSq_settingRow:last-of-type{border-bottom:0}.o9fCSq_settingText{flex-direction:column;flex:200px;gap:2px;min-width:0;display:flex}.o9fCSq_settingTitle{font-size:13.5px;font-weight:500;line-height:20px}.o9fCSq_settingLead{color:var(--dsw-alias-label-primary);margin:0;font-size:13px;font-weight:400;line-height:20px}.o9fCSq_settingControl{flex:0 auto;justify-content:flex-end;min-width:0;max-width:100%;display:flex}.o9fCSq_selectAnchor{min-width:0;max-width:100%}.o9fCSq_select,.o9fCSq_selectCompact{box-sizing:border-box;border-radius:var(--dsw-radius-md);min-width:0;max-width:100%;font:inherit;color:var(--dsw-alias-label-primary);cursor:pointer;border:none;align-items:center;gap:8px;font-size:13px;line-height:20px;display:inline-flex}.o9fCSq_select{background:var(--dsw-alias-bg-module-platform);height:36px;padding:0 12px 0 14px}.o9fCSq_selectCompact{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-1);justify-content:space-between;width:100%;height:36px;padding:0 10px 0 12px}.o9fCSq_select:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.o9fCSq_select:disabled,.o9fCSq_selectCompact:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.o9fCSq_select:focus-visible,.o9fCSq_selectCompact:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:1px}.o9fCSq_selectValue{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.o9fCSq_selectChevron{color:var(--dsw-alias-label-tertiary);flex:none}.o9fCSq_list{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}.o9fCSq_row{border-bottom:.5px solid var(--dsw-alias-border-l2);padding:12px 2px}.o9fCSq_row:last-child{border-bottom:0}.o9fCSq_rowLine{align-items:center;gap:8px 12px;min-width:0;display:flex}.o9fCSq_rowMain{flex-direction:column;flex:1 1 0;gap:2px;min-width:0;display:flex}.o9fCSq_rowTitle{flex-wrap:wrap;align-items:center;gap:6px;font-size:13.5px;font-weight:500;line-height:20px;display:inline-flex}.o9fCSq_rowMeta{color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:12px;line-height:18px}.o9fCSq_rowMeta code,.o9fCSq_optionKey{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);font-size:11.5px}.o9fCSq_rowActions{box-sizing:border-box;flex-wrap:wrap;flex:none;align-items:center;gap:4px;display:flex}@container (width<=560px){.o9fCSq_rowLine:has(.o9fCSq_rowActions){flex-wrap:wrap}.o9fCSq_rowActions{flex-basis:100%;order:3;padding-left:10px}}.o9fCSq_segmented{align-self:flex-start;max-width:100%}.o9fCSq_disclosure{color:var(--dsw-alias-label-secondary)}.o9fCSq_disclosureIcon{flex:none;width:12px;height:12px;transition:transform .12s}.o9fCSq_disclosureOpen{transform:rotate(180deg)}@media (prefers-reduced-motion:reduce){.o9fCSq_disclosureIcon{transition:none}}.o9fCSq_danger{color:var(--dsw-alias-state-error-primary)}.o9fCSq_panel,.o9fCSq_editor{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:16px;margin:12px 0 2px;padding:16px;display:flex}.o9fCSq_field,.o9fCSq_formField{flex-direction:column;gap:6px;min-width:0;display:flex}.o9fCSq_fieldHead{align-items:center;gap:8px;display:flex}.o9fCSq_fieldLabel{color:var(--dsw-alias-label-primary);font-size:13px;font-weight:500;line-height:20px}.o9fCSq_fieldState{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.o9fCSq_inline{flex-wrap:wrap;gap:8px;display:flex}.o9fCSq_inline>.o9fCSq_input{flex:160px}.o9fCSq_input{box-sizing:border-box;min-width:0;height:36px}.o9fCSq_input:has(input[aria-invalid=true]){border-color:var(--dsw-alias-state-error-primary)}.o9fCSq_link{color:var(--dsw-alias-link);align-self:flex-start;align-items:center;gap:2px;font-size:12px;font-weight:500;line-height:18px;text-decoration:none;display:inline-flex}.o9fCSq_link:hover,.o9fCSq_link:focus-visible{text-underline-offset:3px;text-decoration:underline dotted}.o9fCSq_optionGrid{grid-template-columns:repeat(auto-fill,minmax(min(100%,200px),1fr));gap:12px 16px;display:grid}.o9fCSq_option{flex-direction:column;gap:4px;min-width:0;display:flex}.o9fCSq_optionName{min-width:0;color:var(--dsw-alias-label-secondary);align-items:baseline;gap:6px;font-size:12px;line-height:18px;display:flex}.o9fCSq_optionKey{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);overflow:hidden}.o9fCSq_actions{flex-wrap:wrap;justify-content:flex-end;gap:8px;display:flex}.o9fCSq_empty{color:var(--dsw-alias-label-tertiary);margin:0;padding:8px 2px;font-size:13px;line-height:20px}.o9fCSq_editorTitle{margin:0;font-size:13.5px;font-weight:500;line-height:20px}.o9fCSq_formGrid{grid-template-columns:repeat(2,minmax(0,1fr));align-items:start;gap:14px 16px;display:grid}.o9fCSq_formWide{grid-column:1/-1}@container (width<=760px){.o9fCSq_optionGrid{grid-template-columns:repeat(2,minmax(0,1fr))}}@container (width<=480px){.o9fCSq_optionGrid{grid-template-columns:minmax(0,1fr)}.o9fCSq_settingControl{flex-basis:100%;justify-content:flex-start}.o9fCSq_panel{padding:12px}}@container (width<=520px){.o9fCSq_formGrid{grid-template-columns:minmax(0,1fr)}}.o9fCSq_prefixed{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);align-items:center;height:36px;padding:0 8px 0 10px;display:flex}.o9fCSq_prefixed:focus-within{border-color:var(--dsw-alias-state-business-primary)}.o9fCSq_prefixedDisabled{color:var(--dsw-alias-label-tertiary)}.o9fCSq_prefix{font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);color:var(--dsw-alias-label-tertiary);flex:none;font-size:13px;line-height:22px}.o9fCSq_prefixedInput{min-width:0;font:inherit;color:var(--dsw-alias-label-primary);background:0 0;border:none;outline:none;flex:1;padding:0;font-size:14px;line-height:22px}.o9fCSq_prefixedInput::placeholder{color:var(--dsw-alias-label-dimmed)}.o9fCSq_reset{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:6px;padding-top:16px;display:flex}.o9fCSq_confirmRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 24px;display:flex}.o9fCSq_row .o9fCSq_confirmRow{border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-module-platform);margin-top:10px;padding:8px 12px}.o9fCSq_confirmText{min-width:0;color:var(--dsw-alias-label-secondary);flex:240px;font-size:12px;line-height:18px}.o9fCSq_optionWide{grid-column:1/-1}.o9fCSq_textarea{box-sizing:border-box;resize:vertical;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:100%;min-width:0;min-height:72px;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);padding:8px 10px;font-size:12px;line-height:20px}.o9fCSq_textarea:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.o9fCSq_textarea::placeholder{color:var(--dsw-alias-label-dimmed)}.o9fCSq_textarea[aria-invalid=true]{border-color:var(--dsw-alias-state-error-primary)}.o9fCSq_textarea:disabled{cursor:not-allowed;opacity:.5}.o9fCSq_optionGroup{border-top:.5px solid var(--dsw-alias-border-l4);flex-direction:column;gap:8px;padding-top:12px;display:flex}.o9fCSq_optionGroup:first-child,.o9fCSq_fieldHead+.o9fCSq_optionGroup{border-top:0;padding-top:0}.o9fCSq_optionGroupTitle{color:var(--dsw-alias-label-primary);font-size:12px;font-weight:500;line-height:18px}.o9fCSq_trust{border:.5px solid var(--dsw-alias-state-warn-primary);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);padding:10px 12px}.o9fCSq_trust .o9fCSq_trustCheck{align-items:flex-start}.o9fCSq_trust .o9fCSq_trustCheck input{margin-top:2px}.o9fCSq_actions>.o9fCSq_hint{flex:auto;align-self:center}";
|
|
4806
4991
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify("dsh-web-search-enhanced/src/client/settings/Settings.module.css") + "]") === null) {
|
|
4807
4992
|
const style = document.createElement("style");
|
|
4808
4993
|
style.dataset.plugin = "dsh-web-search-enhanced";
|
|
@@ -4811,72 +4996,73 @@ window.__ModuleLoader__.load({
|
|
|
4811
4996
|
document.head.appendChild(style);
|
|
4812
4997
|
}
|
|
4813
4998
|
var Settings_module_css_default = {
|
|
4814
|
-
"
|
|
4815
|
-
"
|
|
4816
|
-
"
|
|
4817
|
-
"rowMain": "o9fCSq_rowMain",
|
|
4818
|
-
"optionGroupTitle": "o9fCSq_optionGroupTitle",
|
|
4819
|
-
"warning": "o9fCSq_warning",
|
|
4820
|
-
"list": "o9fCSq_list",
|
|
4821
|
-
"actions": "o9fCSq_actions",
|
|
4999
|
+
"intro": "o9fCSq_intro",
|
|
5000
|
+
"disclosureOpen": "o9fCSq_disclosureOpen",
|
|
5001
|
+
"optionGroup": "o9fCSq_optionGroup",
|
|
4822
5002
|
"trustCheck": "o9fCSq_trustCheck",
|
|
4823
|
-
"fieldState": "o9fCSq_fieldState",
|
|
4824
|
-
"row": "o9fCSq_row",
|
|
4825
|
-
"selectChevron": "o9fCSq_selectChevron",
|
|
4826
|
-
"optionKey": "o9fCSq_optionKey",
|
|
4827
|
-
"textarea": "o9fCSq_textarea",
|
|
4828
|
-
"formGrid": "o9fCSq_formGrid",
|
|
4829
|
-
"status": "o9fCSq_status",
|
|
4830
|
-
"option": "o9fCSq_option",
|
|
4831
|
-
"selectAnchor": "o9fCSq_selectAnchor",
|
|
4832
|
-
"confirmText": "o9fCSq_confirmText",
|
|
4833
|
-
"editor": "o9fCSq_editor",
|
|
4834
5003
|
"trust": "o9fCSq_trust",
|
|
4835
|
-
"
|
|
5004
|
+
"field": "o9fCSq_field",
|
|
5005
|
+
"optionKey": "o9fCSq_optionKey",
|
|
4836
5006
|
"success": "o9fCSq_success",
|
|
4837
|
-
"
|
|
5007
|
+
"sectionHead": "o9fCSq_sectionHead",
|
|
5008
|
+
"confirmText": "o9fCSq_confirmText",
|
|
4838
5009
|
"confirmRow": "o9fCSq_confirmRow",
|
|
4839
|
-
"
|
|
4840
|
-
"rowMeta": "o9fCSq_rowMeta",
|
|
4841
|
-
"optionGrid": "o9fCSq_optionGrid",
|
|
4842
|
-
"sectionTitle": "o9fCSq_sectionTitle",
|
|
4843
|
-
"input": "o9fCSq_input",
|
|
5010
|
+
"inline": "o9fCSq_inline",
|
|
4844
5011
|
"prefixedInput": "o9fCSq_prefixedInput",
|
|
4845
|
-
"
|
|
4846
|
-
"
|
|
4847
|
-
"
|
|
5012
|
+
"rowTitle": "o9fCSq_rowTitle",
|
|
5013
|
+
"rowMain": "o9fCSq_rowMain",
|
|
5014
|
+
"rowActions": "o9fCSq_rowActions",
|
|
4848
5015
|
"page": "o9fCSq_page",
|
|
4849
|
-
"
|
|
4850
|
-
"
|
|
4851
|
-
"
|
|
4852
|
-
"
|
|
5016
|
+
"selectValue": "o9fCSq_selectValue",
|
|
5017
|
+
"prefixedDisabled": "o9fCSq_prefixedDisabled",
|
|
5018
|
+
"rowMeta": "o9fCSq_rowMeta",
|
|
5019
|
+
"reset": "o9fCSq_reset",
|
|
5020
|
+
"actions": "o9fCSq_actions",
|
|
5021
|
+
"settingControl": "o9fCSq_settingControl",
|
|
5022
|
+
"fieldLabel": "o9fCSq_fieldLabel",
|
|
5023
|
+
"section": "o9fCSq_section",
|
|
5024
|
+
"formGrid": "o9fCSq_formGrid",
|
|
5025
|
+
"formWide": "o9fCSq_formWide",
|
|
5026
|
+
"selectCompact": "o9fCSq_selectCompact",
|
|
5027
|
+
"textarea": "o9fCSq_textarea",
|
|
5028
|
+
"prefix": "o9fCSq_prefix",
|
|
5029
|
+
"fieldError": "o9fCSq_fieldError",
|
|
5030
|
+
"sectionActions": "o9fCSq_sectionActions",
|
|
4853
5031
|
"optionName": "o9fCSq_optionName",
|
|
5032
|
+
"row": "o9fCSq_row",
|
|
5033
|
+
"editorTitle": "o9fCSq_editorTitle",
|
|
5034
|
+
"optionWide": "o9fCSq_optionWide",
|
|
5035
|
+
"sectionTitle": "o9fCSq_sectionTitle",
|
|
5036
|
+
"fieldHead": "o9fCSq_fieldHead",
|
|
5037
|
+
"optionGrid": "o9fCSq_optionGrid",
|
|
5038
|
+
"input": "o9fCSq_input",
|
|
5039
|
+
"list": "o9fCSq_list",
|
|
5040
|
+
"optionGroupTitle": "o9fCSq_optionGroupTitle",
|
|
5041
|
+
"fieldState": "o9fCSq_fieldState",
|
|
4854
5042
|
"settingText": "o9fCSq_settingText",
|
|
4855
|
-
"
|
|
5043
|
+
"note": "o9fCSq_note",
|
|
5044
|
+
"settingRow": "o9fCSq_settingRow",
|
|
5045
|
+
"error": "o9fCSq_error",
|
|
5046
|
+
"rowLine": "o9fCSq_rowLine",
|
|
5047
|
+
"formField": "o9fCSq_formField",
|
|
5048
|
+
"link": "o9fCSq_link",
|
|
4856
5049
|
"danger": "o9fCSq_danger",
|
|
4857
|
-
"sectionActions": "o9fCSq_sectionActions",
|
|
4858
|
-
"settingControl": "o9fCSq_settingControl",
|
|
4859
5050
|
"select": "o9fCSq_select",
|
|
4860
|
-
"
|
|
4861
|
-
"
|
|
4862
|
-
"
|
|
4863
|
-
"
|
|
4864
|
-
"
|
|
5051
|
+
"status": "o9fCSq_status",
|
|
5052
|
+
"editor": "o9fCSq_editor",
|
|
5053
|
+
"panel": "o9fCSq_panel",
|
|
5054
|
+
"selectAnchor": "o9fCSq_selectAnchor",
|
|
5055
|
+
"segmented": "o9fCSq_segmented",
|
|
5056
|
+
"disclosure": "o9fCSq_disclosure",
|
|
5057
|
+
"hint": "o9fCSq_hint",
|
|
5058
|
+
"option": "o9fCSq_option",
|
|
5059
|
+
"selectChevron": "o9fCSq_selectChevron",
|
|
5060
|
+
"settingTitle": "o9fCSq_settingTitle",
|
|
4865
5061
|
"empty": "o9fCSq_empty",
|
|
4866
|
-
"
|
|
5062
|
+
"settingLead": "o9fCSq_settingLead",
|
|
5063
|
+
"prefixed": "o9fCSq_prefixed",
|
|
4867
5064
|
"disclosureIcon": "o9fCSq_disclosureIcon",
|
|
4868
|
-
"
|
|
4869
|
-
"fieldLabel": "o9fCSq_fieldLabel",
|
|
4870
|
-
"field": "o9fCSq_field",
|
|
4871
|
-
"section": "o9fCSq_section",
|
|
4872
|
-
"fieldHead": "o9fCSq_fieldHead",
|
|
4873
|
-
"optionGroup": "o9fCSq_optionGroup",
|
|
4874
|
-
"rowActions": "o9fCSq_rowActions",
|
|
4875
|
-
"note": "o9fCSq_note",
|
|
4876
|
-
"formWide": "o9fCSq_formWide",
|
|
4877
|
-
"prefixedDisabled": "o9fCSq_prefixedDisabled",
|
|
4878
|
-
"rowTitle": "o9fCSq_rowTitle",
|
|
4879
|
-
"selectCompact": "o9fCSq_selectCompact"
|
|
5065
|
+
"warning": "o9fCSq_warning"
|
|
4880
5066
|
};
|
|
4881
5067
|
//#endregion
|
|
4882
5068
|
//#region src/client/settings/CredentialEditor.tsx
|
|
@@ -5317,6 +5503,18 @@ window.__ModuleLoader__.load({
|
|
|
5317
5503
|
});
|
|
5318
5504
|
}
|
|
5319
5505
|
//#endregion
|
|
5506
|
+
//#region src/client/settings/EnhancedToolsSection.tsx
|
|
5507
|
+
const EnhancedToolsSection = createEnhancedToolsSection({
|
|
5508
|
+
classes: Settings_module_css_default,
|
|
5509
|
+
parts: settingsParts,
|
|
5510
|
+
sparse: sparse_exports,
|
|
5511
|
+
keys: {
|
|
5512
|
+
title: "enhanced.title",
|
|
5513
|
+
description: "enhanced.description",
|
|
5514
|
+
consent: "enhanced.consent"
|
|
5515
|
+
}
|
|
5516
|
+
});
|
|
5517
|
+
//#endregion
|
|
5320
5518
|
//#region src/client/settings/PairingsSection.tsx
|
|
5321
5519
|
const PairingsSection = createPairingsSection({
|
|
5322
5520
|
classes: Settings_module_css_default,
|
|
@@ -5350,6 +5548,7 @@ window.__ModuleLoader__.load({
|
|
|
5350
5548
|
optionGroups: { "session-model": SESSION_MODEL_GROUPS },
|
|
5351
5549
|
keys: {
|
|
5352
5550
|
"services.title": "services.title",
|
|
5551
|
+
"services.optInNotice": "services.optInNotice",
|
|
5353
5552
|
"options.hint": "options.hint",
|
|
5354
5553
|
"options.keylessMore": "options.keylessMore",
|
|
5355
5554
|
"options.invalid": "options.invalid",
|
|
@@ -5385,12 +5584,12 @@ window.__ModuleLoader__.load({
|
|
|
5385
5584
|
* Controls write immediately as sparse operations against the revision the
|
|
5386
5585
|
* page shows; credentials go to DSH Credentials only.
|
|
5387
5586
|
*/
|
|
5388
|
-
function SettingsPage({ useSettings, useCredentials, useRoute, usePairings, mutate, saveCredential, forgetPairing, t }) {
|
|
5587
|
+
function SettingsPage({ useSettings, useCredentials, useRoute, usePairings, readSettings, mutate, saveCredential, forgetPairing, t }) {
|
|
5389
5588
|
const snapshot = useSettings((value) => value);
|
|
5390
5589
|
const credentials = useCredentials((value) => value);
|
|
5391
5590
|
const route = useRoute((value) => value);
|
|
5392
5591
|
const pairings = usePairings((value) => value);
|
|
5393
|
-
const { view, write, migrationError } = useSettingsDocument(snapshot, resolveSettings, mutate);
|
|
5592
|
+
const { view, write, migrationError } = useSettingsDocument(snapshot, readSettings, resolveSettings, mutate);
|
|
5394
5593
|
if (snapshot.status === "unavailable") return null;
|
|
5395
5594
|
if (snapshot.value === void 0 || snapshot.revision === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
5396
5595
|
className: Settings_module_css_default.status,
|
|
@@ -5455,6 +5654,11 @@ window.__ModuleLoader__.load({
|
|
|
5455
5654
|
credentials,
|
|
5456
5655
|
t
|
|
5457
5656
|
}),
|
|
5657
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(EnhancedToolsSection, {
|
|
5658
|
+
doc,
|
|
5659
|
+
write,
|
|
5660
|
+
t
|
|
5661
|
+
}),
|
|
5458
5662
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ServicesSection, {
|
|
5459
5663
|
doc,
|
|
5460
5664
|
write,
|
|
@@ -5554,6 +5758,7 @@ window.__ModuleLoader__.load({
|
|
|
5554
5758
|
route: route.source,
|
|
5555
5759
|
pairings: pairings.source
|
|
5556
5760
|
},
|
|
5761
|
+
readSettings: () => settings.getSnapshot(),
|
|
5557
5762
|
async mutate(ops, revision) {
|
|
5558
5763
|
return settings.mutate(ops, revision);
|
|
5559
5764
|
},
|
|
@@ -5572,7 +5777,7 @@ window.__ModuleLoader__.load({
|
|
|
5572
5777
|
locale: NS,
|
|
5573
5778
|
inject: () => page
|
|
5574
5779
|
}, SettingsPage))), "search: settings page");
|
|
5575
|
-
const section = searchSection(selection, navigation, t);
|
|
5780
|
+
const section = searchSection(selection, navigation, remoteServicesOffSource(settings, CATALOG, resolveSettings), t);
|
|
5576
5781
|
scope.inject(["webConnections"], (ui) => {
|
|
5577
5782
|
ui.effect(() => ui.webConnections.registerRoute("search", route), "search: route facts");
|
|
5578
5783
|
ui.effect(() => {
|
|
@@ -5594,7 +5799,11 @@ window.__ModuleLoader__.load({
|
|
|
5594
5799
|
}, "search: composer section");
|
|
5595
5800
|
});
|
|
5596
5801
|
scope.inject(["commandUi"], (command) => {
|
|
5597
|
-
command.effect(() => command.commandUi.
|
|
5802
|
+
command.effect(() => command.commandUi.decorate(searchCommand(selection, t)), "search: /setup-search");
|
|
5803
|
+
followHostCommand(command, SEARCH.command, (sessionId) => {
|
|
5804
|
+
selection.invalidateSession(sessionId);
|
|
5805
|
+
pairings.invalidate();
|
|
5806
|
+
});
|
|
5598
5807
|
});
|
|
5599
5808
|
const invalidate = () => {
|
|
5600
5809
|
selection.invalidate();
|