@lemoncat7/dsh-knowledge 1.1.2 → 1.1.5
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/lib/client.js +100 -103
- package/lib/client.js.map +4 -4
- package/lib/workspace-ownership.d.ts +5 -0
- package/lib/workspace-ownership.d.ts.map +1 -0
- package/lib/workspace-ownership.js +18 -0
- package/lib/workspace-ownership.js.map +1 -0
- package/package.json +1 -2
- package/web/app.js +8 -0
- package/web/styles.css +58 -13
package/lib/client.js
CHANGED
|
@@ -25,25 +25,22 @@ __export(client_exports, {
|
|
|
25
25
|
inject: () => inject
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(client_exports);
|
|
28
|
-
var import_react2 = require("react");
|
|
29
|
-
|
|
30
|
-
// node_modules/@lemoncat7/dsh-plugin-ui/lib/index.js
|
|
31
|
-
var import_jsx_runtime = require("react/jsx-runtime");
|
|
32
28
|
var import_react = require("react");
|
|
33
|
-
|
|
29
|
+
|
|
30
|
+
// src/workspace-ownership.ts
|
|
31
|
+
var WORKSPACE_ACTIVATE_EVENT = "@lemoncat7/dsh-plugin-ui/workspace-activate";
|
|
34
32
|
function activatePluginWorkspace(pluginId) {
|
|
35
|
-
window.dispatchEvent(new CustomEvent(
|
|
33
|
+
window.dispatchEvent(new CustomEvent(WORKSPACE_ACTIVATE_EVENT, {
|
|
36
34
|
detail: { pluginId }
|
|
37
35
|
}));
|
|
38
36
|
}
|
|
39
37
|
function observePluginWorkspace(pluginId, close) {
|
|
40
38
|
const onActivate = (event) => {
|
|
41
39
|
const detail = event.detail;
|
|
42
|
-
if (detail?.pluginId !== pluginId)
|
|
43
|
-
close();
|
|
40
|
+
if (detail?.pluginId !== pluginId) close();
|
|
44
41
|
};
|
|
45
|
-
window.addEventListener(
|
|
46
|
-
return () => window.removeEventListener(
|
|
42
|
+
window.addEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
43
|
+
return () => window.removeEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
47
44
|
}
|
|
48
45
|
|
|
49
46
|
// src/client.tsx
|
|
@@ -154,7 +151,7 @@ function firstDefinedToken(computed, snapshotTokens, sources) {
|
|
|
154
151
|
}
|
|
155
152
|
|
|
156
153
|
// src/client.tsx
|
|
157
|
-
var
|
|
154
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
158
155
|
var PLUGIN_ID = "@lemoncat7/dsh-knowledge";
|
|
159
156
|
var STYLE_ID = `${PLUGIN_ID}/client`;
|
|
160
157
|
var CONNECTION_CONTROL_PATH = "/knowledge-control/v1/connection";
|
|
@@ -170,7 +167,7 @@ function apply(ctx) {
|
|
|
170
167
|
name: "sidebar.footer.action",
|
|
171
168
|
id: "knowledge",
|
|
172
169
|
order: -10
|
|
173
|
-
}, (props) => /* @__PURE__ */ (0,
|
|
170
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KnowledgeLauncher, { ...props, workspace })));
|
|
174
171
|
ctx.slots.inject("settings.plugin.item", () => ctx.slots.register({
|
|
175
172
|
name: "settings.plugin.item",
|
|
176
173
|
key: KNOWLEDGE_SETTINGS_NAMESPACE
|
|
@@ -178,12 +175,12 @@ function apply(ctx) {
|
|
|
178
175
|
ctx.slots.inject("conversation.chat.turnTail", () => ctx.slots.register({
|
|
179
176
|
name: "conversation.chat.turnTail",
|
|
180
177
|
select: (owner) => ({ turn: owner.turn.turn })
|
|
181
|
-
}, (props) => /* @__PURE__ */ (0,
|
|
178
|
+
}, (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KnowledgeWritebackStatus, { sessionId: String(props.sessionId), turn: props.matched.turn })));
|
|
182
179
|
}
|
|
183
180
|
function KnowledgeWritebackStatus({ sessionId, turn }) {
|
|
184
|
-
const [state, setState] = (0,
|
|
185
|
-
const [retrying, setRetrying] = (0,
|
|
186
|
-
(0,
|
|
181
|
+
const [state, setState] = (0, import_react.useState)();
|
|
182
|
+
const [retrying, setRetrying] = (0, import_react.useState)(false);
|
|
183
|
+
(0, import_react.useEffect)(() => {
|
|
187
184
|
const controller = new AbortController();
|
|
188
185
|
void fetch(`/knowledge-control/v1/writeback-status?sessionId=${encodeURIComponent(sessionId)}&turn=${turn}`, {
|
|
189
186
|
headers: { accept: "application/json" },
|
|
@@ -216,11 +213,11 @@ function KnowledgeWritebackStatus({ sessionId, turn }) {
|
|
|
216
213
|
setRetrying(false);
|
|
217
214
|
}
|
|
218
215
|
};
|
|
219
|
-
return /* @__PURE__ */ (0,
|
|
220
|
-
/* @__PURE__ */ (0,
|
|
221
|
-
/* @__PURE__ */ (0,
|
|
222
|
-
/* @__PURE__ */ (0,
|
|
223
|
-
state.status === "failed" && state.retryable && /* @__PURE__ */ (0,
|
|
216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-knowledge-writeback-status", children: [
|
|
217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\u4E0A\u4E0B\u6587\u6CE8\u5165" }),
|
|
218
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "dsh-knowledge" }),
|
|
219
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { title: state.error, children: state.summary }),
|
|
220
|
+
state.status === "failed" && state.retryable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", disabled: retrying, onClick: () => {
|
|
224
221
|
void retry();
|
|
225
222
|
}, children: retrying ? "\u91CD\u8BD5\u4E2D\u2026" : "\u91CD\u8BD5" })
|
|
226
223
|
] });
|
|
@@ -243,7 +240,7 @@ function createKnowledgeWorkspaceController(client) {
|
|
|
243
240
|
toggle: () => {
|
|
244
241
|
if (disposeWorkspace !== void 0) return close();
|
|
245
242
|
activatePluginWorkspace(PLUGIN_ID);
|
|
246
|
-
const dispose = client.slots.register({ name: "conversation", priority: -1 }, (props) => /* @__PURE__ */ (0,
|
|
243
|
+
const dispose = client.slots.register({ name: "conversation", priority: -1 }, (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(KnowledgeWorkspace, { ...props, client, workspace: controller }));
|
|
247
244
|
disposeWorkspace = dispose;
|
|
248
245
|
notify();
|
|
249
246
|
},
|
|
@@ -258,18 +255,18 @@ function createKnowledgeWorkspaceController(client) {
|
|
|
258
255
|
return controller;
|
|
259
256
|
}
|
|
260
257
|
function KnowledgeConnectionCard() {
|
|
261
|
-
const [current, setCurrent] = (0,
|
|
262
|
-
const [loadState, setLoadState] = (0,
|
|
263
|
-
const [loadError, setLoadError] = (0,
|
|
264
|
-
const [open, setOpen] = (0,
|
|
265
|
-
const [backend, setBackend] = (0,
|
|
266
|
-
const [remoteUrl, setRemoteUrl] = (0,
|
|
267
|
-
const [remoteToken, setRemoteToken] = (0,
|
|
268
|
-
const [timeout, setTimeoutValue] = (0,
|
|
269
|
-
const [dirty, setDirty] = (0,
|
|
270
|
-
const [saving, setSaving] = (0,
|
|
271
|
-
const [message, setMessage] = (0,
|
|
272
|
-
const load = (0,
|
|
258
|
+
const [current, setCurrent] = (0, import_react.useState)();
|
|
259
|
+
const [loadState, setLoadState] = (0, import_react.useState)("loading");
|
|
260
|
+
const [loadError, setLoadError] = (0, import_react.useState)("");
|
|
261
|
+
const [open, setOpen] = (0, import_react.useState)(false);
|
|
262
|
+
const [backend, setBackend] = (0, import_react.useState)("local");
|
|
263
|
+
const [remoteUrl, setRemoteUrl] = (0, import_react.useState)("");
|
|
264
|
+
const [remoteToken, setRemoteToken] = (0, import_react.useState)("");
|
|
265
|
+
const [timeout, setTimeoutValue] = (0, import_react.useState)("10000");
|
|
266
|
+
const [dirty, setDirty] = (0, import_react.useState)(false);
|
|
267
|
+
const [saving, setSaving] = (0, import_react.useState)(false);
|
|
268
|
+
const [message, setMessage] = (0, import_react.useState)();
|
|
269
|
+
const load = (0, import_react.useCallback)(async (signal) => {
|
|
273
270
|
setLoadState("loading");
|
|
274
271
|
setLoadError("");
|
|
275
272
|
try {
|
|
@@ -282,14 +279,14 @@ function KnowledgeConnectionCard() {
|
|
|
282
279
|
setLoadState("error");
|
|
283
280
|
}
|
|
284
281
|
}, []);
|
|
285
|
-
(0,
|
|
282
|
+
(0, import_react.useEffect)(() => {
|
|
286
283
|
const controller = new AbortController();
|
|
287
284
|
void load(controller.signal);
|
|
288
285
|
return () => {
|
|
289
286
|
controller.abort();
|
|
290
287
|
};
|
|
291
288
|
}, [load]);
|
|
292
|
-
(0,
|
|
289
|
+
(0, import_react.useEffect)(() => {
|
|
293
290
|
if (dirty || current === void 0) return;
|
|
294
291
|
setBackend(current.backend);
|
|
295
292
|
setRemoteUrl(current.remoteUrl ?? "");
|
|
@@ -337,75 +334,75 @@ function KnowledgeConnectionCard() {
|
|
|
337
334
|
setSaving(false);
|
|
338
335
|
}
|
|
339
336
|
};
|
|
340
|
-
return /* @__PURE__ */ (0,
|
|
341
|
-
/* @__PURE__ */ (0,
|
|
337
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("li", { className: `dsh-knowledge-settings-card${open ? " dsh-knowledge-settings-card--open" : ""}`, children: [
|
|
338
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: "dsh-knowledge-settings-header", "aria-expanded": open, onClick: () => {
|
|
342
339
|
setOpen((value) => !value);
|
|
343
340
|
}, children: [
|
|
344
|
-
/* @__PURE__ */ (0,
|
|
345
|
-
/* @__PURE__ */ (0,
|
|
346
|
-
/* @__PURE__ */ (0,
|
|
341
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
342
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u77E5\u8BC6\u5E93\u8FDE\u63A5" }),
|
|
343
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u9009\u62E9\u672C\u673A\u77E5\u8BC6\u5E93\uFF0C\u6216\u8FDE\u63A5\u4E00\u53F0\u4E2D\u592E DSH \u77E5\u8BC6\u5E93" })
|
|
347
344
|
] }),
|
|
348
|
-
/* @__PURE__ */ (0,
|
|
345
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dsh-knowledge-settings-summary", children: [
|
|
349
346
|
loadState === "loading" ? "\u8BFB\u53D6\u4E2D" : loadState === "error" ? "\u8FDE\u63A5\u5165\u53E3" : current?.backend === "remote" ? "\u8FDC\u7A0B" : "\u672C\u5730",
|
|
350
|
-
/* @__PURE__ */ (0,
|
|
347
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("i", { "aria-hidden": "true" })
|
|
351
348
|
] })
|
|
352
349
|
] }),
|
|
353
|
-
open && /* @__PURE__ */ (0,
|
|
354
|
-
/* @__PURE__ */ (0,
|
|
355
|
-
/* @__PURE__ */ (0,
|
|
350
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-knowledge-settings-body", children: loadState === "loading" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-knowledge-settings-note", role: "status", children: "\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u914D\u7F6E\u2026" }) : loadState === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-knowledge-settings-load-error", role: "alert", children: [
|
|
351
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: loadError }),
|
|
352
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: () => {
|
|
356
353
|
void load();
|
|
357
354
|
}, children: "\u91CD\u65B0\u8BFB\u53D6" })
|
|
358
|
-
] }) : /* @__PURE__ */ (0,
|
|
359
|
-
/* @__PURE__ */ (0,
|
|
360
|
-
/* @__PURE__ */ (0,
|
|
361
|
-
/* @__PURE__ */ (0,
|
|
362
|
-
/* @__PURE__ */ (0,
|
|
355
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
356
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("fieldset", { className: "dsh-knowledge-source-picker", children: [
|
|
357
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("legend", { children: "\u77E5\u8BC6\u5E93\u6765\u6E90" }),
|
|
358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: backend === "local" ? "is-selected" : "", children: [
|
|
359
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "radio", name: "dsh-knowledge-backend", checked: backend === "local", onChange: () => edit(() => {
|
|
363
360
|
setBackend("local");
|
|
364
361
|
}) }),
|
|
365
|
-
/* @__PURE__ */ (0,
|
|
366
|
-
/* @__PURE__ */ (0,
|
|
367
|
-
/* @__PURE__ */ (0,
|
|
362
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
363
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u672C\u5730" }),
|
|
364
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u6570\u636E\u4FDD\u5B58\u5728\u5F53\u524D DSH \u7684 SQLite \u4E2D" })
|
|
368
365
|
] })
|
|
369
366
|
] }),
|
|
370
|
-
/* @__PURE__ */ (0,
|
|
371
|
-
/* @__PURE__ */ (0,
|
|
367
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: `${backend === "remote" ? "is-selected" : ""}${!current?.canSwitchRemote ? " is-disabled" : ""}`, children: [
|
|
368
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { type: "radio", name: "dsh-knowledge-backend", checked: backend === "remote", disabled: !current?.canSwitchRemote, onChange: () => edit(() => {
|
|
372
369
|
setBackend("remote");
|
|
373
370
|
}) }),
|
|
374
|
-
/* @__PURE__ */ (0,
|
|
375
|
-
/* @__PURE__ */ (0,
|
|
376
|
-
/* @__PURE__ */ (0,
|
|
371
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
372
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u8FDC\u7A0B" }),
|
|
373
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u53EC\u56DE\u548C\u56DE\u5199\u7EDF\u4E00\u4F7F\u7528\u4E2D\u592E\u77E5\u8BC6\u5E93" })
|
|
377
374
|
] })
|
|
378
375
|
] })
|
|
379
376
|
] }),
|
|
380
|
-
!current?.canSwitchRemote && /* @__PURE__ */ (0,
|
|
381
|
-
backend === "remote" && /* @__PURE__ */ (0,
|
|
382
|
-
/* @__PURE__ */ (0,
|
|
377
|
+
!current?.canSwitchRemote && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-knowledge-settings-note", children: "\u5F53\u524D\u5B9E\u4F8B\u662F\u4E2D\u592E\u77E5\u8BC6\u5E93\u670D\u52A1\uFF0C\u4E0D\u80FD\u518D\u5207\u6362\u5230\u53E6\u4E00\u53F0\u8FDC\u7A0B\u670D\u52A1\u3002" }),
|
|
378
|
+
backend === "remote" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-knowledge-remote-fields", children: [
|
|
379
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dsh-knowledge-remote-url", children: [
|
|
383
380
|
"\u670D\u52A1\u5668\u5730\u5740",
|
|
384
|
-
/* @__PURE__ */ (0,
|
|
381
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { id: "dsh-knowledge-remote-url", type: "url", value: remoteUrl, placeholder: "https://example.com/knowledge-api/v1", autoComplete: "url", onChange: (event) => edit(() => {
|
|
385
382
|
setRemoteUrl(event.target.value);
|
|
386
383
|
}), "aria-invalid": urlError !== void 0, "aria-describedby": urlError ? "dsh-knowledge-url-error" : void 0 }),
|
|
387
|
-
urlError && /* @__PURE__ */ (0,
|
|
384
|
+
urlError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { id: "dsh-knowledge-url-error", className: "dsh-knowledge-field-error", children: urlError })
|
|
388
385
|
] }),
|
|
389
|
-
/* @__PURE__ */ (0,
|
|
386
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { htmlFor: "dsh-knowledge-remote-token", children: [
|
|
390
387
|
"\u5BA2\u6237\u7AEF\u4EE4\u724C",
|
|
391
|
-
/* @__PURE__ */ (0,
|
|
388
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { id: "dsh-knowledge-remote-token", type: "password", value: remoteToken, placeholder: current?.tokenConfigured ? "\u5DF2\u4FDD\u5B58\uFF1B\u7559\u7A7A\u5219\u4FDD\u6301\u4E0D\u53D8" : "\u7C98\u8D34\u5BA2\u6237\u7AEF\u4EE4\u724C", autoComplete: "new-password", onChange: (event) => edit(() => {
|
|
392
389
|
setRemoteToken(event.target.value);
|
|
393
390
|
}), "aria-invalid": tokenError !== void 0, "aria-describedby": "dsh-knowledge-token-help" }),
|
|
394
|
-
/* @__PURE__ */ (0,
|
|
391
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { id: "dsh-knowledge-token-help", className: tokenError ? "dsh-knowledge-field-error" : void 0, children: tokenError ?? (current?.tokenConfigured ? "\u4EE4\u724C\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF0C\u9875\u9762\u65E0\u6CD5\u8BFB\u53D6\uFF1B\u8F93\u5165\u65B0\u4EE4\u724C\u53EF\u8986\u76D6\u3002" : "\u4EE4\u724C\u4FDD\u5B58\u540E\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u53EA\u80FD\u8986\u76D6\u3002") })
|
|
395
392
|
] })
|
|
396
393
|
] }),
|
|
397
|
-
/* @__PURE__ */ (0,
|
|
394
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: "dsh-knowledge-timeout-field", htmlFor: "dsh-knowledge-timeout", children: [
|
|
398
395
|
"\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09",
|
|
399
|
-
/* @__PURE__ */ (0,
|
|
396
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("input", { id: "dsh-knowledge-timeout", type: "number", min: "100", max: "120000", step: "100", value: timeout, onChange: (event) => edit(() => {
|
|
400
397
|
setTimeoutValue(event.target.value);
|
|
401
398
|
}), "aria-invalid": timeoutError !== void 0 }),
|
|
402
|
-
timeoutError && /* @__PURE__ */ (0,
|
|
399
|
+
timeoutError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { className: "dsh-knowledge-field-error", children: timeoutError })
|
|
403
400
|
] }),
|
|
404
|
-
!current?.writable && /* @__PURE__ */ (0,
|
|
405
|
-
message && /* @__PURE__ */ (0,
|
|
406
|
-
/* @__PURE__ */ (0,
|
|
407
|
-
/* @__PURE__ */ (0,
|
|
408
|
-
/* @__PURE__ */ (0,
|
|
401
|
+
!current?.writable && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dsh-knowledge-settings-note", children: "\u5F53\u524D\u63D2\u4EF6\u6CA1\u6709\u914D\u7F6E\u6301\u4E45\u5316\u8DEF\u5F84\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u8FDE\u63A5\u3002" }),
|
|
402
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: `dsh-knowledge-settings-message is-${message.kind}`, role: message.kind === "error" ? "alert" : "status", "aria-live": "polite", children: message.text }),
|
|
403
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-knowledge-settings-actions", children: [
|
|
404
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: reset, disabled: !dirty || saving, children: "\u653E\u5F03\u66F4\u6539" }),
|
|
405
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "is-primary", onClick: () => {
|
|
409
406
|
void save();
|
|
410
407
|
}, disabled: !dirty || invalid || saving || !current?.writable, children: saving ? "\u6B63\u5728\u9A8C\u8BC1\u2026" : "\u9A8C\u8BC1\u5E76\u8FDE\u63A5" })
|
|
411
408
|
] })
|
|
@@ -451,11 +448,11 @@ function isManagementPath(value) {
|
|
|
451
448
|
return typeof value === "string" && value.startsWith("/") && !value.startsWith("//");
|
|
452
449
|
}
|
|
453
450
|
function KnowledgeLauncher({ wide, workspace }) {
|
|
454
|
-
const [open, setOpen] = (0,
|
|
455
|
-
(0,
|
|
451
|
+
const [open, setOpen] = (0, import_react.useState)(workspace.isOpen());
|
|
452
|
+
(0, import_react.useEffect)(() => workspace.subscribe(() => {
|
|
456
453
|
setOpen(workspace.isOpen());
|
|
457
454
|
}), [workspace]);
|
|
458
|
-
return /* @__PURE__ */ (0,
|
|
455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
459
456
|
"button",
|
|
460
457
|
{
|
|
461
458
|
type: "button",
|
|
@@ -467,8 +464,8 @@ function KnowledgeLauncher({ wide, workspace }) {
|
|
|
467
464
|
workspace.toggle();
|
|
468
465
|
},
|
|
469
466
|
children: [
|
|
470
|
-
/* @__PURE__ */ (0,
|
|
471
|
-
wide && /* @__PURE__ */ (0,
|
|
467
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconDataOutline16, { size: wide ? 16 : 18 }),
|
|
468
|
+
wide && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: open ? "\u8FD4\u56DE\u5BF9\u8BDD" : "\u77E5\u8BC6\u5E93" })
|
|
472
469
|
]
|
|
473
470
|
}
|
|
474
471
|
);
|
|
@@ -479,14 +476,14 @@ function KnowledgeWorkspace({
|
|
|
479
476
|
client,
|
|
480
477
|
workspace
|
|
481
478
|
}) {
|
|
482
|
-
const [panelState, setPanelState] = (0,
|
|
483
|
-
const [managementPath, setManagementPath] = (0,
|
|
484
|
-
const [panelError, setPanelError] = (0,
|
|
479
|
+
const [panelState, setPanelState] = (0, import_react.useState)("loading");
|
|
480
|
+
const [managementPath, setManagementPath] = (0, import_react.useState)();
|
|
481
|
+
const [panelError, setPanelError] = (0, import_react.useState)("");
|
|
485
482
|
const projectId = useSessions((state) => sessionId === void 0 ? void 0 : state.byId[sessionId]?.cwd);
|
|
486
483
|
const knowledgeUrl = managementPath === void 0 ? void 0 : knowledgePanelUrl(managementPath, sessionId, projectId);
|
|
487
|
-
const frame = (0,
|
|
488
|
-
const themeFrame = (0,
|
|
489
|
-
const loadManagement = (0,
|
|
484
|
+
const frame = (0, import_react.useRef)(null);
|
|
485
|
+
const themeFrame = (0, import_react.useRef)(0);
|
|
486
|
+
const loadManagement = (0, import_react.useCallback)(async () => {
|
|
490
487
|
setPanelState("loading");
|
|
491
488
|
setPanelError("");
|
|
492
489
|
try {
|
|
@@ -504,10 +501,10 @@ function KnowledgeWorkspace({
|
|
|
504
501
|
setPanelState("error");
|
|
505
502
|
}
|
|
506
503
|
}, []);
|
|
507
|
-
(0,
|
|
504
|
+
(0, import_react.useEffect)(() => {
|
|
508
505
|
void loadManagement();
|
|
509
506
|
}, [loadManagement]);
|
|
510
|
-
const sendTheme = (0,
|
|
507
|
+
const sendTheme = (0, import_react.useCallback)(() => {
|
|
511
508
|
const currentFrame = frame.current;
|
|
512
509
|
if (currentFrame === null) return;
|
|
513
510
|
const target = currentFrame.contentWindow;
|
|
@@ -518,14 +515,14 @@ function KnowledgeWorkspace({
|
|
|
518
515
|
frameOrigin(currentFrame) ?? "*"
|
|
519
516
|
);
|
|
520
517
|
}, [client]);
|
|
521
|
-
const scheduleTheme = (0,
|
|
518
|
+
const scheduleTheme = (0, import_react.useCallback)(() => {
|
|
522
519
|
if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current);
|
|
523
520
|
themeFrame.current = window.requestAnimationFrame(() => {
|
|
524
521
|
themeFrame.current = 0;
|
|
525
522
|
sendTheme();
|
|
526
523
|
});
|
|
527
524
|
}, [sendTheme]);
|
|
528
|
-
(0,
|
|
525
|
+
(0, import_react.useEffect)(() => {
|
|
529
526
|
const off = client.on("theme/change", scheduleTheme);
|
|
530
527
|
const onMessage = (event) => {
|
|
531
528
|
const currentFrame = frame.current;
|
|
@@ -543,21 +540,21 @@ function KnowledgeWorkspace({
|
|
|
543
540
|
if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current);
|
|
544
541
|
};
|
|
545
542
|
}, [client, scheduleTheme, sendTheme]);
|
|
546
|
-
return /* @__PURE__ */ (0,
|
|
547
|
-
/* @__PURE__ */ (0,
|
|
548
|
-
/* @__PURE__ */ (0,
|
|
549
|
-
/* @__PURE__ */ (0,
|
|
550
|
-
/* @__PURE__ */ (0,
|
|
551
|
-
/* @__PURE__ */ (0,
|
|
552
|
-
/* @__PURE__ */ (0,
|
|
543
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "dsh-knowledge-workspace", "data-xiaohei-surface": "plugin-workspace", "aria-labelledby": "dsh-knowledge-workspace-title", children: [
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { className: "dsh-knowledge-workspace-header", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", "data-xiaohei-workspace-close": true, onClick: workspace.close, "aria-label": "\u8FD4\u56DE\u4F1A\u8BDD", title: "\u8FD4\u56DE\u4F1A\u8BDD", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconChevronLeftOutline14, { size: 15 }) }),
|
|
546
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconDataOutline16, { size: 18 }),
|
|
547
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
548
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: "dsh-knowledge-workspace-title", children: "\u77E5\u8BC6\u5E93" }),
|
|
549
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u6587\u6863\u3001\u5BA1\u6838\u3001\u6302\u8F7D\u4E0E\u8BBF\u95EE\u7BA1\u7406" })
|
|
553
550
|
] })
|
|
554
551
|
] }) }),
|
|
555
|
-
panelState === "ready" && knowledgeUrl !== void 0 ? /* @__PURE__ */ (0,
|
|
556
|
-
/* @__PURE__ */ (0,
|
|
557
|
-
/* @__PURE__ */ (0,
|
|
558
|
-
/* @__PURE__ */ (0,
|
|
559
|
-
/* @__PURE__ */ (0,
|
|
560
|
-
panelState === "error" && /* @__PURE__ */ (0,
|
|
552
|
+
panelState === "ready" && knowledgeUrl !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("iframe", { ref: frame, className: "dsh-knowledge-frame", src: knowledgeUrl, title: "\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0", onLoad: sendTheme }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-knowledge-panel-state", role: panelState === "error" ? "alert" : "status", "aria-live": "polite", children: [
|
|
553
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-knowledge-panel-state-icon", "aria-hidden": "true", children: panelState === "loading" ? "\xB7\xB7\xB7" : panelState === "error" ? "!" : "\u2014" }),
|
|
554
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
555
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: panelState === "loading" ? "\u6B63\u5728\u6253\u5F00\u77E5\u8BC6\u5E93\u2026" : panelState === "error" ? "\u6682\u65F6\u65E0\u6CD5\u6253\u5F00\u77E5\u8BC6\u5E93" : "\u8FD9\u53F0 DSH \u672A\u542F\u7528\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0" }),
|
|
556
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: panelState === "loading" ? "\u6B63\u5728\u786E\u8BA4\u5F53\u524D\u5B9E\u4F8B\u662F\u5426\u63D0\u4F9B\u7BA1\u7406\u9875\u9762\u3002" : panelState === "error" ? panelError : "\u672C\u5730\u53EC\u56DE\u548C\u56DE\u5199\u4ECD\u53EF\u4F7F\u7528\u3002\u5F53\u524D profile \u5DF2\u663E\u5F0F\u5173\u95ED exposeWeb\uFF1B\u91CD\u65B0\u542F\u7528\u540E\u5373\u53EF\u5728\u8FD9\u91CC\u7BA1\u7406\u3002\u4F7F\u7528\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u65F6\uFF0C\u8BF7\u524D\u5F80\u4E2D\u592E DSH \u7684\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0\u3002" }),
|
|
557
|
+
panelState === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: () => {
|
|
561
558
|
void loadManagement();
|
|
562
559
|
}, children: "\u91CD\u8BD5" })
|
|
563
560
|
] })
|
package/lib/client.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/client.tsx", "../
|
|
4
|
-
"sourcesContent": ["import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-layout/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-theme/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { activatePluginWorkspace, observePluginWorkspace } from '@lemoncat7/dsh-plugin-ui'\nimport {\n IconChevronLeftOutline14, IconDataOutline16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport cssText from './client.css'\nimport { KNOWLEDGE_SETTINGS_NAMESPACE } from './constants.js'\nimport {\n createKnowledgeHostTheme,\n KNOWLEDGE_THEME_PROTOCOL_VERSION,\n KNOWLEDGE_THEME_READY_MESSAGE,\n type ThemeSnapshotLike,\n} from './theme-bridge.js'\n\nconst PLUGIN_ID = '@lemoncat7/dsh-knowledge'\nconst STYLE_ID = `${PLUGIN_ID}/client`\n\ntype SidebarActionProps = PropsRuntime<'sidebar.footer.action'>\ntype ConversationSlotProps = PropsRuntime<'conversation'>\n\ninterface KnowledgeConnectionView {\n backend: 'local' | 'remote'\n remoteUrl?: string\n remoteTimeoutMs: number\n tokenConfigured: boolean\n canSwitchRemote: boolean\n writable: boolean\n managementAvailable: boolean\n managementPath?: string\n}\n\ninterface KnowledgeWorkspaceController {\n isOpen(): boolean\n toggle(): void\n close(): void\n subscribe(listener: () => void): () => void\n}\n\nconst CONNECTION_CONTROL_PATH = '/knowledge-control/v1/connection'\n\n/** Cordis services needed by the browser half. */\nexport const inject = ['slots', 'theme']\n\n/** Register the knowledge launcher in the sidebar's official extension slot. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(installStyles, 'dsh-knowledge: client styles')\n const workspace = createKnowledgeWorkspaceController(ctx)\n ctx.effect(() => observePluginWorkspace(PLUGIN_ID, workspace.close), 'dsh-knowledge: exclusive workspace')\n ctx.effect(() => () => { workspace.close() }, 'dsh-knowledge: workspace lifecycle')\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action',\n id: 'knowledge',\n order: -10,\n }, props => <KnowledgeLauncher {...props} workspace={workspace} />))\n\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: KNOWLEDGE_SETTINGS_NAMESPACE,\n }, KnowledgeConnectionCard))\n\n ctx.slots.inject('conversation.chat.turnTail', () => ctx.slots.register({\n name: 'conversation.chat.turnTail',\n select: owner => ({ turn: owner.turn.turn }),\n }, props => <KnowledgeWritebackStatus sessionId={String(props.sessionId)} turn={props.matched.turn} />))\n}\n\nfunction KnowledgeWritebackStatus({ sessionId, turn }: { sessionId: string; turn: number }) {\n type Status = { status: 'running' | 'completed' | 'failed'; summary: string; error?: string; retryable: boolean }\n const [state, setState] = useState<Status>()\n const [retrying, setRetrying] = useState(false)\n useEffect(() => {\n const controller = new AbortController()\n void fetch(`/knowledge-control/v1/writeback-status?sessionId=${encodeURIComponent(sessionId)}&turn=${turn}`, {\n headers: { accept: 'application/json' }, signal: controller.signal,\n }).then(async response => response.ok ? response.json() as Promise<Status> : undefined)\n .then(value => { if (value?.summary) setState(value) })\n .catch(() => {})\n return () => { controller.abort() }\n }, [sessionId, turn])\n if (state === undefined) return null\n const retry = async (): Promise<void> => {\n setRetrying(true)\n try {\n const response = await fetch(`/knowledge-control/v1/writeback-status?sessionId=${encodeURIComponent(sessionId)}&turn=${turn}`, {\n method: 'POST', headers: { accept: 'application/json', 'x-dsh-knowledge-client': 'conversation-web' },\n })\n if (!response.ok) throw new Error(`retry failed with HTTP ${response.status}`)\n setState(await response.json() as Status)\n } catch (error) {\n setState(previous => previous === undefined ? previous : {\n ...previous, error: error instanceof Error ? error.message : String(error), retryable: true,\n })\n } finally { setRetrying(false) }\n }\n return <div className=\"dsh-knowledge-writeback-status\">\n <span>\u4E0A\u4E0B\u6587\u6CE8\u5165</span><strong>dsh-knowledge</strong><span title={state.error}>{state.summary}</span>\n {state.status === 'failed' && state.retryable && <button type=\"button\" disabled={retrying} onClick={() => { void retry() }}>{retrying ? '\u91CD\u8BD5\u4E2D\u2026' : '\u91CD\u8BD5'}</button>}\n </div>\n}\n\nfunction createKnowledgeWorkspaceController(client: ClientContext): KnowledgeWorkspaceController {\n const listeners = new Set<() => void>()\n let disposeWorkspace: (() => void) | undefined\n const notify = (): void => { for (const listener of listeners) listener() }\n const close = (): void => {\n if (disposeWorkspace === undefined) return\n const dispose = disposeWorkspace\n disposeWorkspace = undefined\n dispose()\n notify()\n }\n const controller: KnowledgeWorkspaceController = {\n isOpen: () => disposeWorkspace !== undefined,\n toggle: () => {\n if (disposeWorkspace !== undefined) return close()\n activatePluginWorkspace(PLUGIN_ID)\n const dispose = client.slots.register({ name: 'conversation', priority: -1 }, props => (\n <KnowledgeWorkspace {...props} client={client} workspace={controller} />\n ))\n disposeWorkspace = dispose\n notify()\n },\n close,\n subscribe: listener => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n }\n return controller\n}\n\nfunction KnowledgeConnectionCard() {\n const [current, setCurrent] = useState<KnowledgeConnectionView>()\n const [loadState, setLoadState] = useState<'loading' | 'ready' | 'error'>('loading')\n const [loadError, setLoadError] = useState('')\n const [open, setOpen] = useState(false)\n const [backend, setBackend] = useState<'local' | 'remote'>('local')\n const [remoteUrl, setRemoteUrl] = useState('')\n const [remoteToken, setRemoteToken] = useState('')\n const [timeout, setTimeoutValue] = useState('10000')\n const [dirty, setDirty] = useState(false)\n const [saving, setSaving] = useState(false)\n const [message, setMessage] = useState<{ kind: 'success' | 'error'; text: string }>()\n\n const load = useCallback(async (signal?: AbortSignal): Promise<void> => {\n setLoadState('loading')\n setLoadError('')\n try {\n const value = await requestConnection('GET', undefined, signal)\n setCurrent(value)\n setLoadState('ready')\n } catch (error) {\n if (signal?.aborted) return\n setLoadError(connectionErrorMessage(error))\n setLoadState('error')\n }\n }, [])\n\n useEffect(() => {\n const controller = new AbortController()\n void load(controller.signal)\n return () => { controller.abort() }\n }, [load])\n\n useEffect(() => {\n if (dirty || current === undefined) return\n setBackend(current.backend)\n setRemoteUrl(current.remoteUrl ?? '')\n setTimeoutValue(String(current.remoteTimeoutMs ?? 10000))\n }, [current, dirty])\n\n const timeoutNumber = Number(timeout)\n const urlError = backend === 'remote' ? validateRemoteUrl(remoteUrl) : undefined\n const tokenError = backend === 'remote' && !current?.tokenConfigured && remoteToken.trim().length === 0\n ? '\u9996\u6B21\u8FDE\u63A5\u5FC5\u987B\u586B\u5199\u5BA2\u6237\u7AEF\u4EE4\u724C\u3002'\n : remoteToken.length > 0 && remoteToken.trim().length < 24 ? '\u4EE4\u724C\u81F3\u5C11\u9700\u8981 24 \u4E2A\u5B57\u7B26\u3002' : undefined\n const timeoutError = !Number.isInteger(timeoutNumber) || timeoutNumber < 100 || timeoutNumber > 120000\n ? '\u8D85\u65F6\u5FC5\u987B\u662F 100 \u5230 120000 \u6BEB\u79D2\u4E4B\u95F4\u7684\u6574\u6570\u3002'\n : undefined\n const invalid = urlError !== undefined || tokenError !== undefined || timeoutError !== undefined\n\n const edit = (action: () => void): void => {\n action()\n setDirty(true)\n setMessage(undefined)\n }\n const reset = (): void => {\n setBackend(current?.backend ?? 'local')\n setRemoteUrl(current?.remoteUrl ?? '')\n setRemoteToken('')\n setTimeoutValue(String(current?.remoteTimeoutMs ?? 10000))\n setDirty(false)\n setMessage(undefined)\n }\n const save = async (): Promise<void> => {\n if (!dirty || invalid || !current?.writable || saving) return\n setSaving(true)\n setMessage(undefined)\n try {\n const next = await requestConnection('PUT', {\n backend,\n remoteTimeoutMs: timeoutNumber,\n ...backend === 'remote' ? { remoteUrl: remoteUrl.trim() } : {},\n ...backend === 'remote' && remoteToken.trim().length > 0 ? { remoteToken: remoteToken.trim() } : {},\n })\n setCurrent(next)\n setRemoteToken('')\n setDirty(false)\n setMessage({\n kind: 'success',\n text: backend === 'remote' ? '\u5DF2\u9A8C\u8BC1\u5E76\u5207\u6362\u81F3\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u3002' : '\u5DF2\u5207\u6362\u81F3\u672C\u5730\u77E5\u8BC6\u5E93\u3002',\n })\n } catch (error) {\n setMessage({ kind: 'error', text: connectionErrorMessage(error) })\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <li className={`dsh-knowledge-settings-card${open ? ' dsh-knowledge-settings-card--open' : ''}`}>\n <button type=\"button\" className=\"dsh-knowledge-settings-header\" aria-expanded={open} onClick={() => { setOpen(value => !value) }}>\n <span><strong>\u77E5\u8BC6\u5E93\u8FDE\u63A5</strong><small>\u9009\u62E9\u672C\u673A\u77E5\u8BC6\u5E93\uFF0C\u6216\u8FDE\u63A5\u4E00\u53F0\u4E2D\u592E DSH \u77E5\u8BC6\u5E93</small></span>\n <span className=\"dsh-knowledge-settings-summary\">{loadState === 'loading' ? '\u8BFB\u53D6\u4E2D' : loadState === 'error' ? '\u8FDE\u63A5\u5165\u53E3' : current?.backend === 'remote' ? '\u8FDC\u7A0B' : '\u672C\u5730'}<i aria-hidden=\"true\" /></span>\n </button>\n {open && <div className=\"dsh-knowledge-settings-body\">\n {loadState === 'loading' ? <p className=\"dsh-knowledge-settings-note\" role=\"status\">\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u914D\u7F6E\u2026</p>\n : loadState === 'error' ? <div className=\"dsh-knowledge-settings-load-error\" role=\"alert\">\n <p>{loadError}</p>\n <button type=\"button\" onClick={() => { void load() }}>\u91CD\u65B0\u8BFB\u53D6</button>\n </div> : <>\n <fieldset className=\"dsh-knowledge-source-picker\">\n <legend>\u77E5\u8BC6\u5E93\u6765\u6E90</legend>\n <label className={backend === 'local' ? 'is-selected' : ''}>\n <input type=\"radio\" name=\"dsh-knowledge-backend\" checked={backend === 'local'} onChange={() => edit(() => { setBackend('local') })} />\n <span><strong>\u672C\u5730</strong><small>\u6570\u636E\u4FDD\u5B58\u5728\u5F53\u524D DSH \u7684 SQLite \u4E2D</small></span>\n </label>\n <label className={`${backend === 'remote' ? 'is-selected' : ''}${!current?.canSwitchRemote ? ' is-disabled' : ''}`}>\n <input type=\"radio\" name=\"dsh-knowledge-backend\" checked={backend === 'remote'} disabled={!current?.canSwitchRemote} onChange={() => edit(() => { setBackend('remote') })} />\n <span><strong>\u8FDC\u7A0B</strong><small>\u53EC\u56DE\u548C\u56DE\u5199\u7EDF\u4E00\u4F7F\u7528\u4E2D\u592E\u77E5\u8BC6\u5E93</small></span>\n </label>\n </fieldset>\n {!current?.canSwitchRemote && <p className=\"dsh-knowledge-settings-note\">\u5F53\u524D\u5B9E\u4F8B\u662F\u4E2D\u592E\u77E5\u8BC6\u5E93\u670D\u52A1\uFF0C\u4E0D\u80FD\u518D\u5207\u6362\u5230\u53E6\u4E00\u53F0\u8FDC\u7A0B\u670D\u52A1\u3002</p>}\n {backend === 'remote' && <div className=\"dsh-knowledge-remote-fields\">\n <label htmlFor=\"dsh-knowledge-remote-url\">\u670D\u52A1\u5668\u5730\u5740\n <input id=\"dsh-knowledge-remote-url\" type=\"url\" value={remoteUrl} placeholder=\"https://example.com/knowledge-api/v1\" autoComplete=\"url\" onChange={event => edit(() => { setRemoteUrl(event.target.value) })} aria-invalid={urlError !== undefined} aria-describedby={urlError ? 'dsh-knowledge-url-error' : undefined} />\n {urlError && <small id=\"dsh-knowledge-url-error\" className=\"dsh-knowledge-field-error\">{urlError}</small>}\n </label>\n <label htmlFor=\"dsh-knowledge-remote-token\">\u5BA2\u6237\u7AEF\u4EE4\u724C\n <input id=\"dsh-knowledge-remote-token\" type=\"password\" value={remoteToken} placeholder={current?.tokenConfigured ? '\u5DF2\u4FDD\u5B58\uFF1B\u7559\u7A7A\u5219\u4FDD\u6301\u4E0D\u53D8' : '\u7C98\u8D34\u5BA2\u6237\u7AEF\u4EE4\u724C'} autoComplete=\"new-password\" onChange={event => edit(() => { setRemoteToken(event.target.value) })} aria-invalid={tokenError !== undefined} aria-describedby=\"dsh-knowledge-token-help\" />\n <small id=\"dsh-knowledge-token-help\" className={tokenError ? 'dsh-knowledge-field-error' : undefined}>{tokenError ?? (current?.tokenConfigured ? '\u4EE4\u724C\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF0C\u9875\u9762\u65E0\u6CD5\u8BFB\u53D6\uFF1B\u8F93\u5165\u65B0\u4EE4\u724C\u53EF\u8986\u76D6\u3002' : '\u4EE4\u724C\u4FDD\u5B58\u540E\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u53EA\u80FD\u8986\u76D6\u3002')}</small>\n </label>\n </div>}\n <label className=\"dsh-knowledge-timeout-field\" htmlFor=\"dsh-knowledge-timeout\">\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09\n <input id=\"dsh-knowledge-timeout\" type=\"number\" min=\"100\" max=\"120000\" step=\"100\" value={timeout} onChange={event => edit(() => { setTimeoutValue(event.target.value) })} aria-invalid={timeoutError !== undefined} />\n {timeoutError && <small className=\"dsh-knowledge-field-error\">{timeoutError}</small>}\n </label>\n {!current?.writable && <p className=\"dsh-knowledge-settings-note\">\u5F53\u524D\u63D2\u4EF6\u6CA1\u6709\u914D\u7F6E\u6301\u4E45\u5316\u8DEF\u5F84\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u8FDE\u63A5\u3002</p>}\n {message && <p className={`dsh-knowledge-settings-message is-${message.kind}`} role={message.kind === 'error' ? 'alert' : 'status'} aria-live=\"polite\">{message.text}</p>}\n <div className=\"dsh-knowledge-settings-actions\">\n <button type=\"button\" onClick={reset} disabled={!dirty || saving}>\u653E\u5F03\u66F4\u6539</button>\n <button type=\"button\" className=\"is-primary\" onClick={() => { void save() }} disabled={!dirty || invalid || saving || !current?.writable}>{saving ? '\u6B63\u5728\u9A8C\u8BC1\u2026' : '\u9A8C\u8BC1\u5E76\u8FDE\u63A5'}</button>\n </div>\n </>}\n </div>}\n </li>\n )\n}\n\nfunction validateRemoteUrl(value: string): string | undefined {\n try {\n const url = new URL(value.trim())\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1'\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) return '\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u5FC5\u987B\u4F7F\u7528 HTTPS\u3002'\n return undefined\n } catch { return '\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u77E5\u8BC6\u5E93 API \u5730\u5740\u3002' }\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error)\n if (message.includes('Failed to fetch')) return '\u65E0\u6CD5\u8BBF\u95EE\u63D2\u4EF6\u8FDE\u63A5\u63A5\u53E3\uFF0C\u8BF7\u786E\u8BA4\u63D2\u4EF6\u670D\u52A1\u5DF2\u52A0\u8F7D\u3002'\n return message || '\u8FDE\u63A5\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u3001\u4EE4\u724C\u548C DSH \u65E5\u5FD7\u3002'\n}\n\nasync function requestConnection(\n method: 'GET' | 'PUT',\n body?: Record<string, unknown>,\n signal?: AbortSignal,\n): Promise<KnowledgeConnectionView> {\n const response = await fetch(CONNECTION_CONTROL_PATH, {\n method,\n headers: { accept: 'application/json', ...body === undefined ? {} : { 'content-type': 'application/json' } },\n ...body === undefined ? {} : { body: JSON.stringify(body) },\n ...signal === undefined ? {} : { signal },\n })\n const payload = await response.json().catch(() => undefined) as unknown\n if (!response.ok) {\n const message = payload !== null && typeof payload === 'object' && typeof (payload as { error?: unknown }).error === 'string'\n ? (payload as { error: string }).error\n : `\u8FDE\u63A5\u63A5\u53E3\u8FD4\u56DE HTTP ${response.status}`\n throw new Error(message)\n }\n if (!isConnectionView(payload)) throw new Error('\u63D2\u4EF6\u8FDE\u63A5\u63A5\u53E3\u8FD4\u56DE\u4E86\u65E0\u6548\u6570\u636E\u3002')\n return payload\n}\n\nfunction isConnectionView(value: unknown): value is KnowledgeConnectionView {\n if (value === null || typeof value !== 'object') return false\n const item = value as Partial<KnowledgeConnectionView>\n return (item.backend === 'local' || item.backend === 'remote')\n && Number.isInteger(item.remoteTimeoutMs)\n && typeof item.tokenConfigured === 'boolean'\n && typeof item.canSwitchRemote === 'boolean'\n && typeof item.writable === 'boolean'\n && typeof item.managementAvailable === 'boolean'\n && (!item.managementAvailable || isManagementPath(item.managementPath))\n}\n\nfunction isManagementPath(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith('/') && !value.startsWith('//')\n}\n\nfunction KnowledgeLauncher({ wide, workspace }: SidebarActionProps & { workspace: KnowledgeWorkspaceController }) {\n const [open, setOpen] = useState(workspace.isOpen())\n\n useEffect(() => workspace.subscribe(() => { setOpen(workspace.isOpen()) }), [workspace])\n\n return (\n <button\n type=\"button\"\n className={`dsh-knowledge-trigger${wide ? '' : ' dsh-knowledge-trigger--rail'}${open ? ' is-active' : ''}`}\n aria-label={open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}\n aria-pressed={open}\n title={wide ? undefined : open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}\n onClick={() => { workspace.toggle() }}\n >\n <IconDataOutline16 size={wide ? 16 : 18} />\n {wide && <span>{open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}</span>}\n </button>\n )\n}\n\nfunction KnowledgeWorkspace({\n sessionId,\n useSessions,\n client,\n workspace,\n}: ConversationSlotProps & { client: ClientContext; workspace: KnowledgeWorkspaceController }) {\n const [panelState, setPanelState] = useState<'loading' | 'ready' | 'unavailable' | 'error'>('loading')\n const [managementPath, setManagementPath] = useState<string>()\n const [panelError, setPanelError] = useState('')\n const projectId = useSessions(state => sessionId === undefined ? undefined : state.byId[sessionId]?.cwd)\n const knowledgeUrl = managementPath === undefined ? undefined : knowledgePanelUrl(managementPath, sessionId, projectId)\n const frame = useRef<HTMLIFrameElement | null>(null)\n const themeFrame = useRef(0)\n\n const loadManagement = useCallback(async (): Promise<void> => {\n setPanelState('loading')\n setPanelError('')\n try {\n const connection = await requestConnection('GET')\n if (!connection.managementAvailable || connection.managementPath === undefined) {\n setManagementPath(undefined)\n setPanelState('unavailable')\n return\n }\n setManagementPath(connection.managementPath)\n setPanelState('ready')\n } catch (error) {\n setManagementPath(undefined)\n setPanelError(connectionErrorMessage(error))\n setPanelState('error')\n }\n }, [])\n\n useEffect(() => {\n void loadManagement()\n }, [loadManagement])\n\n const sendTheme = useCallback((): void => {\n const currentFrame = frame.current\n if (currentFrame === null) return\n const target = currentFrame.contentWindow\n if (target === null) return\n const computed = getComputedStyle(document.body)\n target.postMessage(\n createKnowledgeHostTheme(computed, client.theme.getTheme()),\n frameOrigin(currentFrame) ?? '*',\n )\n }, [client])\n\n const scheduleTheme = useCallback((): void => {\n if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current)\n themeFrame.current = window.requestAnimationFrame(() => {\n themeFrame.current = 0\n sendTheme()\n })\n }, [sendTheme])\n\n useEffect(() => {\n const off = client.on('theme/change', scheduleTheme)\n const onMessage = (event: MessageEvent): void => {\n const currentFrame = frame.current\n if (event.source !== currentFrame?.contentWindow) return\n const expectedOrigin = frameOrigin(currentFrame)\n if (expectedOrigin !== undefined && event.origin !== expectedOrigin) return\n const data = event.data as { type?: unknown; version?: unknown } | null\n if (data?.type === KNOWLEDGE_THEME_READY_MESSAGE && data.version === KNOWLEDGE_THEME_PROTOCOL_VERSION) sendTheme()\n }\n window.addEventListener('message', onMessage)\n scheduleTheme()\n return () => {\n off()\n window.removeEventListener('message', onMessage)\n if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current)\n }\n }, [client, scheduleTheme, sendTheme])\n\n return (\n <section className=\"dsh-knowledge-workspace\" data-xiaohei-surface=\"plugin-workspace\" aria-labelledby=\"dsh-knowledge-workspace-title\">\n <header className=\"dsh-knowledge-workspace-header\">\n <div>\n <button type=\"button\" data-xiaohei-workspace-close onClick={workspace.close} aria-label=\"\u8FD4\u56DE\u4F1A\u8BDD\" title=\"\u8FD4\u56DE\u4F1A\u8BDD\"><IconChevronLeftOutline14 size={15} /></button>\n <IconDataOutline16 size={18} />\n <span><h2 id=\"dsh-knowledge-workspace-title\">\u77E5\u8BC6\u5E93</h2><p>\u6587\u6863\u3001\u5BA1\u6838\u3001\u6302\u8F7D\u4E0E\u8BBF\u95EE\u7BA1\u7406</p></span>\n </div>\n </header>\n {panelState === 'ready' && knowledgeUrl !== undefined\n ? <iframe ref={frame} className=\"dsh-knowledge-frame\" src={knowledgeUrl} title=\"\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0\" onLoad={sendTheme} />\n : <div className=\"dsh-knowledge-panel-state\" role={panelState === 'error' ? 'alert' : 'status'} aria-live=\"polite\">\n <span className=\"dsh-knowledge-panel-state-icon\" aria-hidden=\"true\">{panelState === 'loading' ? '\u00B7\u00B7\u00B7' : panelState === 'error' ? '!' : '\u2014'}</span>\n <div>\n <h3>{panelState === 'loading' ? '\u6B63\u5728\u6253\u5F00\u77E5\u8BC6\u5E93\u2026' : panelState === 'error' ? '\u6682\u65F6\u65E0\u6CD5\u6253\u5F00\u77E5\u8BC6\u5E93' : '\u8FD9\u53F0 DSH \u672A\u542F\u7528\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0'}</h3>\n <p>{panelState === 'loading'\n ? '\u6B63\u5728\u786E\u8BA4\u5F53\u524D\u5B9E\u4F8B\u662F\u5426\u63D0\u4F9B\u7BA1\u7406\u9875\u9762\u3002'\n : panelState === 'error'\n ? panelError\n : '\u672C\u5730\u53EC\u56DE\u548C\u56DE\u5199\u4ECD\u53EF\u4F7F\u7528\u3002\u5F53\u524D profile \u5DF2\u663E\u5F0F\u5173\u95ED exposeWeb\uFF1B\u91CD\u65B0\u542F\u7528\u540E\u5373\u53EF\u5728\u8FD9\u91CC\u7BA1\u7406\u3002\u4F7F\u7528\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u65F6\uFF0C\u8BF7\u524D\u5F80\u4E2D\u592E DSH \u7684\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0\u3002'}</p>\n {panelState === 'error' && <button type=\"button\" onClick={() => { void loadManagement() }}>\u91CD\u8BD5</button>}\n </div>\n </div>}\n </section>\n )\n}\n\nfunction knowledgePanelUrl(managementPath: string, sessionId?: string, projectId?: string): string {\n const params = new URLSearchParams()\n if (sessionId !== undefined) params.set('sessionId', sessionId)\n if (projectId !== undefined) params.set('projectId', projectId)\n const query = params.toString()\n return query.length === 0 ? managementPath : `${managementPath}${managementPath.includes('?') ? '&' : '?'}${query}`\n}\n\nfunction frameOrigin(frame: HTMLIFrameElement): string | undefined {\n try {\n const origin = new URL(frame.src).origin\n return origin === 'null' ? undefined : origin\n } catch {\n return undefined\n }\n}\n\nfunction installStyles(): () => void {\n const previous = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${STYLE_ID}\"]`)\n previous?.remove()\n const style = document.createElement('style')\n style.dataset.plugin = PLUGIN_ID\n style.dataset.pluginCss = STYLE_ID\n style.textContent = cssText\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n", null, ".dsh-knowledge-trigger,\n.dsh-knowledge-workspace,\n.dsh-knowledge-settings-card,\n.dsh-knowledge-writeback-status {\n --knowledge-accent: var(--dsw-alias-interactive-primary, var(--dsw-alias-brand-primary, #547d78));\n --knowledge-on-accent: var(--dsw-alias-label-primary-foreground, #fff);\n --knowledge-danger: var(--dsw-alias-state-error-primary, #c9362b);\n --knowledge-success: var(--dsw-alias-state-success-primary, #15803d);\n}\n\n.dsh-knowledge-trigger,\n.dsh-knowledge-panel-state button,\n.dsh-knowledge-settings-card button,\n.dsh-knowledge-writeback-status button {\n -webkit-appearance: none;\n appearance: none;\n margin: 0;\n}\n\n.dsh-knowledge-trigger {\n flex: none;\n display: flex;\n align-items: center;\n gap: 8px;\n width: calc(100% + 8px);\n height: 34px;\n margin: 4px -4px;\n padding: 6px 2px 6px 10px;\n box-sizing: border-box;\n border: 0;\n border-radius: 12px;\n overflow: hidden;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.dsh-knowledge-trigger:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.dsh-knowledge-trigger:focus-visible,\n.dsh-knowledge-writeback-status button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n\n.dsh-knowledge-trigger.is-active {\n background: var(--dsw-alias-interactive-bg-selected, var(--dsw-alias-interactive-bg-hover));\n color: var(--knowledge-accent);\n}\n\n.dsh-knowledge-trigger--rail {\n width: 36px;\n height: 36px;\n margin: 8px 0 4px;\n padding: 0;\n justify-content: center;\n gap: 0;\n border-radius: 50%;\n}\n\n.dsh-knowledge-workspace {\n --knowledge-pane: var(--xiaohei-plugin-pane-fill, var(--dsw-alias-bg-base, #f7f8f7));\n --knowledge-raised: var(--xiaohei-plugin-raised-fill, var(--dsw-alias-bg-layer-2, #fff));\n --knowledge-control: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--knowledge-pane);\n}\n\n.dsh-knowledge-workspace-header {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n min-height: 56px;\n padding: 8px 16px 8px 20px;\n box-sizing: border-box;\n border-bottom: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .18));\n background: var(--knowledge-pane);\n}\n\n.dsh-knowledge-workspace-header > div {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close] {\n -webkit-appearance: none;\n appearance: none;\n display: grid;\n place-items: center;\n box-sizing: border-box;\n flex: none;\n width: 30px;\n height: 30px;\n margin: 0;\n padding: 0;\n border: 1px solid transparent;\n border-radius: 9px;\n color: var(--dsw-alias-label-secondary, #68686f);\n background: transparent;\n font: inherit;\n line-height: 1;\n -webkit-tap-highlight-color: transparent;\n cursor: pointer;\n transition: color 140ms ease, background 140ms ease, border-color 140ms ease, transform 140ms ease;\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:hover {\n border-color: var(--dsw-alias-divider-primary, rgba(128, 128, 128, .18));\n color: var(--dsw-alias-label-primary, #171719);\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .08));\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:active { transform: scale(.96); }\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close] > svg {\n display: block;\n pointer-events: none;\n}\n\n.dsh-knowledge-workspace-header > div > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.dsh-knowledge-workspace-header h2,\n.dsh-knowledge-workspace-header p {\n margin: 0;\n}\n\n.dsh-knowledge-workspace-header h2 {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n line-height: 22px;\n font-weight: 600;\n}\n\n.dsh-knowledge-workspace-header p {\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n line-height: 16px;\n}\n\n.dsh-knowledge-frame {\n flex: 1;\n width: 100%;\n min-height: 0;\n border: 0;\n background: transparent;\n}\n\n.dsh-knowledge-panel-state {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 16px;\n min-height: 0;\n padding: 32px;\n box-sizing: border-box;\n background: transparent;\n color: var(--dsw-alias-label-primary, #171719);\n}\n\n.dsh-knowledge-panel-state-icon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 12px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .1));\n color: var(--dsw-alias-label-secondary, #68686f);\n font-size: 18px;\n font-weight: 600;\n}\n\n.dsh-knowledge-panel-state > div { max-width: 560px; }\n.dsh-knowledge-panel-state h3 { margin: 0 0 6px; font-size: 17px; line-height: 24px; font-weight: 600; }\n.dsh-knowledge-panel-state p { margin: 0; color: var(--dsw-alias-label-secondary, #68686f); font-size: 13px; line-height: 20px; }\n.dsh-knowledge-panel-state button {\n min-width: 72px;\n min-height: 32px;\n margin-top: 16px;\n padding: 6px 14px;\n border: 0;\n border-radius: 10px;\n background: var(--knowledge-accent);\n color: var(--knowledge-on-accent);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-panel-state button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n\n.dsh-knowledge-settings-card {\n list-style: none;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary, #171719);\n transition: border-color .16s, background .16s;\n}\n.dsh-knowledge-settings-card:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dsh-knowledge-settings-card--open { border-color: var(--dsw-alias-label-dimmed); background: var(--dsw-alias-bg-layer-2); }\n.dsh-knowledge-settings-header { display: flex; width: 100%; align-items: center; gap: 12px; padding: 14px 16px; border: 0; border-radius: 12px; background: transparent; color: inherit; text-align: left; cursor: pointer; font: inherit; }\n.dsh-knowledge-settings-header:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: -2px;\n}\n.dsh-knowledge-settings-actions button:focus-visible,\n.dsh-knowledge-settings-load-error button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-settings-header > span:first-child { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 4px; }\n.dsh-knowledge-settings-header strong { font-size: 15px; font-weight: 600; line-height: 1.4; }\n.dsh-knowledge-settings-header small { color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }\n.dsh-knowledge-source-picker small,\n.dsh-knowledge-remote-fields small { color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-settings-summary { display: flex; flex: none; align-items: center; gap: 10px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-knowledge-settings-summary i { width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 160ms ease; }\n.dsh-knowledge-settings-card--open .dsh-knowledge-settings-summary i { transform: rotate(225deg); }\n\n.dsh-knowledge-settings-body {\n display: grid;\n gap: 18px;\n margin: 0 16px;\n padding-bottom: 8px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n\n.dsh-knowledge-source-picker {\n min-width: 0;\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n margin: 18px 0 0;\n padding: 0;\n border: 0;\n}\n\n.dsh-knowledge-source-picker legend { margin-bottom: 8px; padding: 0; color: inherit; font-size: 13px; font-weight: 600; }\n.dsh-knowledge-source-picker label {\n display: flex;\n gap: 10px;\n padding: 13px;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .2));\n border-radius: 14px;\n cursor: pointer;\n}\n.dsh-knowledge-source-picker label.is-selected {\n border-color: var(--knowledge-accent);\n background: color-mix(in srgb, var(--knowledge-accent) 7%, transparent);\n}\n.dsh-knowledge-source-picker label.is-disabled {\n cursor: default;\n opacity: .55;\n}\n.dsh-knowledge-source-picker label:focus-within {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-source-picker input {\n -webkit-appearance: none;\n appearance: none;\n width: 16px;\n height: 16px;\n display: inline-grid;\n place-content: center;\n flex: none;\n margin: 2px 0 0;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .34));\n border-radius: 50%;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n color: var(--knowledge-on-accent);\n cursor: pointer;\n transition: border-color .15s ease, background-color .15s ease;\n}\n.dsh-knowledge-source-picker input::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transform: scale(.55);\n transition: opacity .12s ease, transform .15s cubic-bezier(.2, .8, .2, 1);\n}\n.dsh-knowledge-source-picker input:checked { border-color: var(--knowledge-accent); background: var(--knowledge-accent); }\n.dsh-knowledge-source-picker input:checked::before { opacity: 1; transform: scale(1); }\n.dsh-knowledge-source-picker input:disabled { cursor: default; }\n.dsh-knowledge-source-picker span { display: grid; gap: 3px; }\n\n.dsh-knowledge-remote-fields { display: grid; grid-template-columns: 1.25fr 1fr; gap: 12px; }\n.dsh-knowledge-remote-fields label,\n.dsh-knowledge-timeout-field { display: grid; gap: 6px; color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-remote-fields input,\n.dsh-knowledge-timeout-field input {\n -webkit-appearance: none;\n appearance: none;\n min-height: 38px;\n box-sizing: border-box;\n padding: 8px 11px;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .25));\n border-radius: 10px;\n outline: none;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n color: var(--dsw-alias-label-primary, #171719);\n font: inherit;\n}\n.dsh-knowledge-remote-fields input:focus,\n.dsh-knowledge-timeout-field input:focus { border-color: var(--knowledge-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--knowledge-accent) 16%, transparent); }\n.dsh-knowledge-remote-fields input:-webkit-autofill,\n.dsh-knowledge-remote-fields input:-webkit-autofill:hover,\n.dsh-knowledge-remote-fields input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--dsw-alias-label-primary, #171719);\n box-shadow: 0 0 0 1000px var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff)) inset;\n caret-color: var(--dsw-alias-label-primary, #171719);\n}\n.dsh-knowledge-timeout-field input::-webkit-inner-spin-button,\n.dsh-knowledge-timeout-field input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }\n.dsh-knowledge-timeout-field { max-width: 240px; }\n.dsh-knowledge-field-error { color: var(--knowledge-danger) !important; }\n\n.dsh-knowledge-settings-message,\n.dsh-knowledge-settings-note { margin: 0; color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-settings-message.is-success { color: var(--knowledge-success); }\n.dsh-knowledge-settings-message.is-error { color: var(--knowledge-danger); }\n.dsh-knowledge-settings-load-error {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 18px;\n padding: 12px 14px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--knowledge-danger) 8%, transparent);\n color: var(--knowledge-danger);\n font-size: 13px;\n}\n.dsh-knowledge-settings-load-error p { margin: 0; }\n.dsh-knowledge-settings-load-error button {\n flex: none;\n min-height: 30px;\n padding: 5px 10px;\n border: 0;\n border-radius: 9px;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-2, #fff));\n color: var(--dsw-alias-label-primary, #171719);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-settings-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.dsh-knowledge-settings-actions button {\n min-height: 34px;\n padding: 7px 13px;\n border: 0;\n border-radius: 10px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .1));\n color: var(--dsw-alias-label-primary, #171719);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n}\n.dsh-knowledge-settings-actions button.is-primary { background: var(--knowledge-accent); color: var(--knowledge-on-accent); }\n.dsh-knowledge-settings-actions button:disabled { cursor: default; opacity: .45; }\n\n@media (max-width: 720px) {\n .dsh-knowledge-source-picker,\n .dsh-knowledge-remote-fields { grid-template-columns: 1fr; }\n .dsh-knowledge-settings-summary { font-size: 0; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dsh-knowledge-settings-card,\n .dsh-knowledge-settings-header,\n .dsh-knowledge-settings-summary i { transition: none; }\n}\n\n.dsh-knowledge-writeback-status {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n color: var(--dsw-alias-label-tertiary, #6b7280);\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-knowledge-writeback-status strong {\n color: var(--dsw-alias-label-secondary, #374151);\n font-weight: 600;\n}\n.dsh-knowledge-writeback-status button {\n min-height: 24px;\n padding: 0 9px;\n border: 1px solid var(--dsw-alias-separator, #d1d5db);\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary, #374151);\n background: var(--dsw-alias-button-elevated-fill, #fff);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-writeback-status button:disabled { cursor: default; opacity: .5; }\n", "/** Host settings namespace that makes the knowledge connection card discoverable. */\nexport const KNOWLEDGE_SETTINGS_NAMESPACE = 'dsh-knowledge-connection'\n", "export const KNOWLEDGE_THEME_MESSAGE = '@lemoncat7/dsh-knowledge/host-theme'\nexport const KNOWLEDGE_THEME_READY_MESSAGE = '@lemoncat7/dsh-knowledge/host-theme-ready'\nexport const KNOWLEDGE_THEME_PROTOCOL_VERSION = 1\n\nexport type KnowledgeColorScheme = 'light' | 'dark'\n\nexport interface KnowledgeHostThemeMessage {\n type: typeof KNOWLEDGE_THEME_MESSAGE\n version: typeof KNOWLEDGE_THEME_PROTOCOL_VERSION\n colorScheme: KnowledgeColorScheme\n tokens: Record<string, string>\n}\n\nexport interface ThemeSnapshotLike {\n active: {\n colorScheme: KnowledgeColorScheme\n tokens: Readonly<Record<string, string>>\n }\n}\n\ninterface ComputedStyleLike {\n getPropertyValue(name: string): string\n}\n\nconst TOKEN_SOURCES = {\n '--bg': ['--xiaohei-plugin-workspace-fill', '--dsw-alias-bg-layer-1', '--dsw-alias-bg-base'],\n '--surface': ['--xiaohei-plugin-pane-fill', '--dsw-alias-bg-layer-2', '--dsw-alias-bg-layer-1'],\n '--surface-raised': ['--xiaohei-plugin-raised-fill', '--dsw-alias-bg-layer-3', '--dsw-alias-bg-overlay', '--dsw-alias-bg-layer-2'],\n '--surface-soft': ['--xiaohei-plugin-control-fill', '--dsw-alias-bg-module-platform', '--dsw-alias-bg-layer-3', '--dsw-alias-bg-layer-2'],\n '--surface-hover': ['--dsw-alias-interactive-bg-hover', '--dsw-alias-bg-layer-3'],\n '--text': ['--dsw-alias-label-primary'],\n '--text-secondary': ['--dsw-alias-label-secondary', '--dsw-alias-label-primary-dimmed'],\n '--text-tertiary': ['--dsw-alias-label-tertiary', '--dsw-alias-label-caption'],\n '--border': ['--dsw-alias-border-l2', '--dsw-alias-divider-primary', '--dsw-alias-border-l1'],\n '--border-strong': ['--dsw-alias-border-l3', '--dsw-alias-border-l2'],\n '--accent': ['--dsw-alias-button-primary-fill', '--dsw-alias-brand-primary'],\n '--accent-hover': ['--dsw-alias-button-primary-hover', '--dsw-alias-brand-primary'],\n '--accent-soft': ['--dsw-alias-interactive-bg-active', '--dsw-alias-interactive-bg-hover-accent'],\n '--on-accent': ['--dsw-alias-label-primary-foreground', '--dsw-alias-brand-primary-invert'],\n '--success': ['--dsw-alias-state-success-primary'],\n '--success-soft': ['--dsw-alias-state-success-tertiary'],\n '--warning': ['--dsw-alias-state-warn-primary', '--dsw-alias-state-warn-label'],\n '--warning-soft': ['--dsw-alias-state-warn-tertiary'],\n '--danger': ['--dsw-alias-state-error-primary'],\n '--danger-soft': ['--dsw-alias-state-error-tertiary'],\n '--shadow': ['--dsw-shadow-lv3', '--dsw-shadow-lv2'],\n} as const\n\nconst FALLBACK_TOKENS: Record<KnowledgeColorScheme, Readonly<Record<string, string>>> = {\n light: {\n '--bg': '#f5f5f7', '--surface': '#ffffff', '--surface-raised': '#ffffff',\n '--surface-soft': '#f0f0f3', '--surface-hover': '#f5f5f8',\n '--text': '#1d1d1f', '--text-secondary': '#4c4c50', '--text-tertiary': '#6e6e73',\n '--border': '#dedee3', '--border-strong': '#c7c7cc',\n '--accent': '#086bd8', '--accent-hover': '#005ab8', '--accent-soft': '#e8f2ff', '--on-accent': '#ffffff',\n '--success': '#18794e', '--success-soft': '#e8f5ee', '--warning': '#986800', '--warning-soft': '#fff4cf',\n '--danger': '#c9343a', '--danger-soft': '#fdebec', '--shadow': '0 18px 48px rgb(30 45 70 / 10%)',\n },\n dark: {\n '--bg': '#101012', '--surface': '#1c1c1e', '--surface-raised': '#242426',\n '--surface-soft': '#2c2c2e', '--surface-hover': '#303033',\n '--text': '#f5f5f7', '--text-secondary': '#c7c7cc', '--text-tertiary': '#98989d',\n '--border': '#353538', '--border-strong': '#4a4a4f',\n '--accent': '#64a8ff', '--accent-hover': '#82b8ff', '--accent-soft': '#17365d', '--on-accent': '#0c1b2c',\n '--success': '#62c596', '--success-soft': '#163a2a', '--warning': '#e7bc62', '--warning-soft': '#423414',\n '--danger': '#ff858a', '--danger-soft': '#4b2227', '--shadow': '0 16px 40px rgb(0 0 0 / 28%)',\n },\n}\n\n/** Translate DSH's public semantic palette into the knowledge console's tokens. */\nexport function createKnowledgeHostTheme(\n computed: ComputedStyleLike,\n snapshot: ThemeSnapshotLike,\n): KnowledgeHostThemeMessage {\n const tokens: Record<string, string> = {}\n for (const [target, sources] of Object.entries(TOKEN_SOURCES)) {\n const value = firstDefinedToken(computed, snapshot.active.tokens, sources)\n tokens[target] = value ?? FALLBACK_TOKENS[snapshot.active.colorScheme][target]!\n }\n return {\n type: KNOWLEDGE_THEME_MESSAGE,\n version: KNOWLEDGE_THEME_PROTOCOL_VERSION,\n colorScheme: snapshot.active.colorScheme,\n tokens,\n }\n}\n\nfunction firstDefinedToken(\n computed: ComputedStyleLike,\n snapshotTokens: Readonly<Record<string, string>>,\n sources: readonly string[],\n): string | undefined {\n for (const source of sources) {\n const computedValue = computed.getPropertyValue(source).trim()\n if (computedValue.length > 0) return computedValue\n const snapshotValue = snapshotTokens[source]?.trim()\n if (snapshotValue !== undefined && snapshotValue.length > 0) return snapshotValue\n }\n return undefined\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": [
|
|
3
|
+
"sources": ["../src/client.tsx", "../src/workspace-ownership.ts", "../src/client.css", "../src/constants.ts", "../src/theme-bridge.ts"],
|
|
4
|
+
"sourcesContent": ["import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-layout/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-sidebar/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-theme/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport { activatePluginWorkspace, observePluginWorkspace } from './workspace-ownership.js'\nimport {\n IconChevronLeftOutline14, IconDataOutline16,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport cssText from './client.css'\nimport { KNOWLEDGE_SETTINGS_NAMESPACE } from './constants.js'\nimport {\n createKnowledgeHostTheme,\n KNOWLEDGE_THEME_PROTOCOL_VERSION,\n KNOWLEDGE_THEME_READY_MESSAGE,\n type ThemeSnapshotLike,\n} from './theme-bridge.js'\n\nconst PLUGIN_ID = '@lemoncat7/dsh-knowledge'\nconst STYLE_ID = `${PLUGIN_ID}/client`\n\ntype SidebarActionProps = PropsRuntime<'sidebar.footer.action'>\ntype ConversationSlotProps = PropsRuntime<'conversation'>\n\ninterface KnowledgeConnectionView {\n backend: 'local' | 'remote'\n remoteUrl?: string\n remoteTimeoutMs: number\n tokenConfigured: boolean\n canSwitchRemote: boolean\n writable: boolean\n managementAvailable: boolean\n managementPath?: string\n}\n\ninterface KnowledgeWorkspaceController {\n isOpen(): boolean\n toggle(): void\n close(): void\n subscribe(listener: () => void): () => void\n}\n\nconst CONNECTION_CONTROL_PATH = '/knowledge-control/v1/connection'\n\n/** Cordis services needed by the browser half. */\nexport const inject = ['slots', 'theme']\n\n/** Register the knowledge launcher in the sidebar's official extension slot. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(installStyles, 'dsh-knowledge: client styles')\n const workspace = createKnowledgeWorkspaceController(ctx)\n ctx.effect(() => observePluginWorkspace(PLUGIN_ID, workspace.close), 'dsh-knowledge: exclusive workspace')\n ctx.effect(() => () => { workspace.close() }, 'dsh-knowledge: workspace lifecycle')\n ctx.slots.inject('sidebar.footer.action', () => ctx.slots.register({\n name: 'sidebar.footer.action',\n id: 'knowledge',\n order: -10,\n }, props => <KnowledgeLauncher {...props} workspace={workspace} />))\n\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n key: KNOWLEDGE_SETTINGS_NAMESPACE,\n }, KnowledgeConnectionCard))\n\n ctx.slots.inject('conversation.chat.turnTail', () => ctx.slots.register({\n name: 'conversation.chat.turnTail',\n select: owner => ({ turn: owner.turn.turn }),\n }, props => <KnowledgeWritebackStatus sessionId={String(props.sessionId)} turn={props.matched.turn} />))\n}\n\nfunction KnowledgeWritebackStatus({ sessionId, turn }: { sessionId: string; turn: number }) {\n type Status = { status: 'running' | 'completed' | 'failed'; summary: string; error?: string; retryable: boolean }\n const [state, setState] = useState<Status>()\n const [retrying, setRetrying] = useState(false)\n useEffect(() => {\n const controller = new AbortController()\n void fetch(`/knowledge-control/v1/writeback-status?sessionId=${encodeURIComponent(sessionId)}&turn=${turn}`, {\n headers: { accept: 'application/json' }, signal: controller.signal,\n }).then(async response => response.ok ? response.json() as Promise<Status> : undefined)\n .then(value => { if (value?.summary) setState(value) })\n .catch(() => {})\n return () => { controller.abort() }\n }, [sessionId, turn])\n if (state === undefined) return null\n const retry = async (): Promise<void> => {\n setRetrying(true)\n try {\n const response = await fetch(`/knowledge-control/v1/writeback-status?sessionId=${encodeURIComponent(sessionId)}&turn=${turn}`, {\n method: 'POST', headers: { accept: 'application/json', 'x-dsh-knowledge-client': 'conversation-web' },\n })\n if (!response.ok) throw new Error(`retry failed with HTTP ${response.status}`)\n setState(await response.json() as Status)\n } catch (error) {\n setState(previous => previous === undefined ? previous : {\n ...previous, error: error instanceof Error ? error.message : String(error), retryable: true,\n })\n } finally { setRetrying(false) }\n }\n return <div className=\"dsh-knowledge-writeback-status\">\n <span>\u4E0A\u4E0B\u6587\u6CE8\u5165</span><strong>dsh-knowledge</strong><span title={state.error}>{state.summary}</span>\n {state.status === 'failed' && state.retryable && <button type=\"button\" disabled={retrying} onClick={() => { void retry() }}>{retrying ? '\u91CD\u8BD5\u4E2D\u2026' : '\u91CD\u8BD5'}</button>}\n </div>\n}\n\nfunction createKnowledgeWorkspaceController(client: ClientContext): KnowledgeWorkspaceController {\n const listeners = new Set<() => void>()\n let disposeWorkspace: (() => void) | undefined\n const notify = (): void => { for (const listener of listeners) listener() }\n const close = (): void => {\n if (disposeWorkspace === undefined) return\n const dispose = disposeWorkspace\n disposeWorkspace = undefined\n dispose()\n notify()\n }\n const controller: KnowledgeWorkspaceController = {\n isOpen: () => disposeWorkspace !== undefined,\n toggle: () => {\n if (disposeWorkspace !== undefined) return close()\n activatePluginWorkspace(PLUGIN_ID)\n const dispose = client.slots.register({ name: 'conversation', priority: -1 }, props => (\n <KnowledgeWorkspace {...props} client={client} workspace={controller} />\n ))\n disposeWorkspace = dispose\n notify()\n },\n close,\n subscribe: listener => {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n }\n return controller\n}\n\nfunction KnowledgeConnectionCard() {\n const [current, setCurrent] = useState<KnowledgeConnectionView>()\n const [loadState, setLoadState] = useState<'loading' | 'ready' | 'error'>('loading')\n const [loadError, setLoadError] = useState('')\n const [open, setOpen] = useState(false)\n const [backend, setBackend] = useState<'local' | 'remote'>('local')\n const [remoteUrl, setRemoteUrl] = useState('')\n const [remoteToken, setRemoteToken] = useState('')\n const [timeout, setTimeoutValue] = useState('10000')\n const [dirty, setDirty] = useState(false)\n const [saving, setSaving] = useState(false)\n const [message, setMessage] = useState<{ kind: 'success' | 'error'; text: string }>()\n\n const load = useCallback(async (signal?: AbortSignal): Promise<void> => {\n setLoadState('loading')\n setLoadError('')\n try {\n const value = await requestConnection('GET', undefined, signal)\n setCurrent(value)\n setLoadState('ready')\n } catch (error) {\n if (signal?.aborted) return\n setLoadError(connectionErrorMessage(error))\n setLoadState('error')\n }\n }, [])\n\n useEffect(() => {\n const controller = new AbortController()\n void load(controller.signal)\n return () => { controller.abort() }\n }, [load])\n\n useEffect(() => {\n if (dirty || current === undefined) return\n setBackend(current.backend)\n setRemoteUrl(current.remoteUrl ?? '')\n setTimeoutValue(String(current.remoteTimeoutMs ?? 10000))\n }, [current, dirty])\n\n const timeoutNumber = Number(timeout)\n const urlError = backend === 'remote' ? validateRemoteUrl(remoteUrl) : undefined\n const tokenError = backend === 'remote' && !current?.tokenConfigured && remoteToken.trim().length === 0\n ? '\u9996\u6B21\u8FDE\u63A5\u5FC5\u987B\u586B\u5199\u5BA2\u6237\u7AEF\u4EE4\u724C\u3002'\n : remoteToken.length > 0 && remoteToken.trim().length < 24 ? '\u4EE4\u724C\u81F3\u5C11\u9700\u8981 24 \u4E2A\u5B57\u7B26\u3002' : undefined\n const timeoutError = !Number.isInteger(timeoutNumber) || timeoutNumber < 100 || timeoutNumber > 120000\n ? '\u8D85\u65F6\u5FC5\u987B\u662F 100 \u5230 120000 \u6BEB\u79D2\u4E4B\u95F4\u7684\u6574\u6570\u3002'\n : undefined\n const invalid = urlError !== undefined || tokenError !== undefined || timeoutError !== undefined\n\n const edit = (action: () => void): void => {\n action()\n setDirty(true)\n setMessage(undefined)\n }\n const reset = (): void => {\n setBackend(current?.backend ?? 'local')\n setRemoteUrl(current?.remoteUrl ?? '')\n setRemoteToken('')\n setTimeoutValue(String(current?.remoteTimeoutMs ?? 10000))\n setDirty(false)\n setMessage(undefined)\n }\n const save = async (): Promise<void> => {\n if (!dirty || invalid || !current?.writable || saving) return\n setSaving(true)\n setMessage(undefined)\n try {\n const next = await requestConnection('PUT', {\n backend,\n remoteTimeoutMs: timeoutNumber,\n ...backend === 'remote' ? { remoteUrl: remoteUrl.trim() } : {},\n ...backend === 'remote' && remoteToken.trim().length > 0 ? { remoteToken: remoteToken.trim() } : {},\n })\n setCurrent(next)\n setRemoteToken('')\n setDirty(false)\n setMessage({\n kind: 'success',\n text: backend === 'remote' ? '\u5DF2\u9A8C\u8BC1\u5E76\u5207\u6362\u81F3\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u3002' : '\u5DF2\u5207\u6362\u81F3\u672C\u5730\u77E5\u8BC6\u5E93\u3002',\n })\n } catch (error) {\n setMessage({ kind: 'error', text: connectionErrorMessage(error) })\n } finally {\n setSaving(false)\n }\n }\n\n return (\n <li className={`dsh-knowledge-settings-card${open ? ' dsh-knowledge-settings-card--open' : ''}`}>\n <button type=\"button\" className=\"dsh-knowledge-settings-header\" aria-expanded={open} onClick={() => { setOpen(value => !value) }}>\n <span><strong>\u77E5\u8BC6\u5E93\u8FDE\u63A5</strong><small>\u9009\u62E9\u672C\u673A\u77E5\u8BC6\u5E93\uFF0C\u6216\u8FDE\u63A5\u4E00\u53F0\u4E2D\u592E DSH \u77E5\u8BC6\u5E93</small></span>\n <span className=\"dsh-knowledge-settings-summary\">{loadState === 'loading' ? '\u8BFB\u53D6\u4E2D' : loadState === 'error' ? '\u8FDE\u63A5\u5165\u53E3' : current?.backend === 'remote' ? '\u8FDC\u7A0B' : '\u672C\u5730'}<i aria-hidden=\"true\" /></span>\n </button>\n {open && <div className=\"dsh-knowledge-settings-body\">\n {loadState === 'loading' ? <p className=\"dsh-knowledge-settings-note\" role=\"status\">\u6B63\u5728\u8BFB\u53D6\u8FDE\u63A5\u914D\u7F6E\u2026</p>\n : loadState === 'error' ? <div className=\"dsh-knowledge-settings-load-error\" role=\"alert\">\n <p>{loadError}</p>\n <button type=\"button\" onClick={() => { void load() }}>\u91CD\u65B0\u8BFB\u53D6</button>\n </div> : <>\n <fieldset className=\"dsh-knowledge-source-picker\">\n <legend>\u77E5\u8BC6\u5E93\u6765\u6E90</legend>\n <label className={backend === 'local' ? 'is-selected' : ''}>\n <input type=\"radio\" name=\"dsh-knowledge-backend\" checked={backend === 'local'} onChange={() => edit(() => { setBackend('local') })} />\n <span><strong>\u672C\u5730</strong><small>\u6570\u636E\u4FDD\u5B58\u5728\u5F53\u524D DSH \u7684 SQLite \u4E2D</small></span>\n </label>\n <label className={`${backend === 'remote' ? 'is-selected' : ''}${!current?.canSwitchRemote ? ' is-disabled' : ''}`}>\n <input type=\"radio\" name=\"dsh-knowledge-backend\" checked={backend === 'remote'} disabled={!current?.canSwitchRemote} onChange={() => edit(() => { setBackend('remote') })} />\n <span><strong>\u8FDC\u7A0B</strong><small>\u53EC\u56DE\u548C\u56DE\u5199\u7EDF\u4E00\u4F7F\u7528\u4E2D\u592E\u77E5\u8BC6\u5E93</small></span>\n </label>\n </fieldset>\n {!current?.canSwitchRemote && <p className=\"dsh-knowledge-settings-note\">\u5F53\u524D\u5B9E\u4F8B\u662F\u4E2D\u592E\u77E5\u8BC6\u5E93\u670D\u52A1\uFF0C\u4E0D\u80FD\u518D\u5207\u6362\u5230\u53E6\u4E00\u53F0\u8FDC\u7A0B\u670D\u52A1\u3002</p>}\n {backend === 'remote' && <div className=\"dsh-knowledge-remote-fields\">\n <label htmlFor=\"dsh-knowledge-remote-url\">\u670D\u52A1\u5668\u5730\u5740\n <input id=\"dsh-knowledge-remote-url\" type=\"url\" value={remoteUrl} placeholder=\"https://example.com/knowledge-api/v1\" autoComplete=\"url\" onChange={event => edit(() => { setRemoteUrl(event.target.value) })} aria-invalid={urlError !== undefined} aria-describedby={urlError ? 'dsh-knowledge-url-error' : undefined} />\n {urlError && <small id=\"dsh-knowledge-url-error\" className=\"dsh-knowledge-field-error\">{urlError}</small>}\n </label>\n <label htmlFor=\"dsh-knowledge-remote-token\">\u5BA2\u6237\u7AEF\u4EE4\u724C\n <input id=\"dsh-knowledge-remote-token\" type=\"password\" value={remoteToken} placeholder={current?.tokenConfigured ? '\u5DF2\u4FDD\u5B58\uFF1B\u7559\u7A7A\u5219\u4FDD\u6301\u4E0D\u53D8' : '\u7C98\u8D34\u5BA2\u6237\u7AEF\u4EE4\u724C'} autoComplete=\"new-password\" onChange={event => edit(() => { setRemoteToken(event.target.value) })} aria-invalid={tokenError !== undefined} aria-describedby=\"dsh-knowledge-token-help\" />\n <small id=\"dsh-knowledge-token-help\" className={tokenError ? 'dsh-knowledge-field-error' : undefined}>{tokenError ?? (current?.tokenConfigured ? '\u4EE4\u724C\u5DF2\u5B89\u5168\u4FDD\u5B58\uFF0C\u9875\u9762\u65E0\u6CD5\u8BFB\u53D6\uFF1B\u8F93\u5165\u65B0\u4EE4\u724C\u53EF\u8986\u76D6\u3002' : '\u4EE4\u724C\u4FDD\u5B58\u540E\u4E0D\u53EF\u8BFB\u53D6\uFF0C\u53EA\u80FD\u8986\u76D6\u3002')}</small>\n </label>\n </div>}\n <label className=\"dsh-knowledge-timeout-field\" htmlFor=\"dsh-knowledge-timeout\">\u8BF7\u6C42\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09\n <input id=\"dsh-knowledge-timeout\" type=\"number\" min=\"100\" max=\"120000\" step=\"100\" value={timeout} onChange={event => edit(() => { setTimeoutValue(event.target.value) })} aria-invalid={timeoutError !== undefined} />\n {timeoutError && <small className=\"dsh-knowledge-field-error\">{timeoutError}</small>}\n </label>\n {!current?.writable && <p className=\"dsh-knowledge-settings-note\">\u5F53\u524D\u63D2\u4EF6\u6CA1\u6709\u914D\u7F6E\u6301\u4E45\u5316\u8DEF\u5F84\uFF0C\u65E0\u6CD5\u4FDD\u5B58\u8FDE\u63A5\u3002</p>}\n {message && <p className={`dsh-knowledge-settings-message is-${message.kind}`} role={message.kind === 'error' ? 'alert' : 'status'} aria-live=\"polite\">{message.text}</p>}\n <div className=\"dsh-knowledge-settings-actions\">\n <button type=\"button\" onClick={reset} disabled={!dirty || saving}>\u653E\u5F03\u66F4\u6539</button>\n <button type=\"button\" className=\"is-primary\" onClick={() => { void save() }} disabled={!dirty || invalid || saving || !current?.writable}>{saving ? '\u6B63\u5728\u9A8C\u8BC1\u2026' : '\u9A8C\u8BC1\u5E76\u8FDE\u63A5'}</button>\n </div>\n </>}\n </div>}\n </li>\n )\n}\n\nfunction validateRemoteUrl(value: string): string | undefined {\n try {\n const url = new URL(value.trim())\n const loopback = url.hostname === 'localhost' || url.hostname === '127.0.0.1' || url.hostname === '::1'\n if (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) return '\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u5FC5\u987B\u4F7F\u7528 HTTPS\u3002'\n return undefined\n } catch { return '\u8BF7\u8F93\u5165\u5B8C\u6574\u7684\u77E5\u8BC6\u5E93 API \u5730\u5740\u3002' }\n}\n\nfunction connectionErrorMessage(error: unknown): string {\n const message = error instanceof Error ? error.message : String(error)\n if (message.includes('Failed to fetch')) return '\u65E0\u6CD5\u8BBF\u95EE\u63D2\u4EF6\u8FDE\u63A5\u63A5\u53E3\uFF0C\u8BF7\u786E\u8BA4\u63D2\u4EF6\u670D\u52A1\u5DF2\u52A0\u8F7D\u3002'\n return message || '\u8FDE\u63A5\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u5730\u5740\u3001\u4EE4\u724C\u548C DSH \u65E5\u5FD7\u3002'\n}\n\nasync function requestConnection(\n method: 'GET' | 'PUT',\n body?: Record<string, unknown>,\n signal?: AbortSignal,\n): Promise<KnowledgeConnectionView> {\n const response = await fetch(CONNECTION_CONTROL_PATH, {\n method,\n headers: { accept: 'application/json', ...body === undefined ? {} : { 'content-type': 'application/json' } },\n ...body === undefined ? {} : { body: JSON.stringify(body) },\n ...signal === undefined ? {} : { signal },\n })\n const payload = await response.json().catch(() => undefined) as unknown\n if (!response.ok) {\n const message = payload !== null && typeof payload === 'object' && typeof (payload as { error?: unknown }).error === 'string'\n ? (payload as { error: string }).error\n : `\u8FDE\u63A5\u63A5\u53E3\u8FD4\u56DE HTTP ${response.status}`\n throw new Error(message)\n }\n if (!isConnectionView(payload)) throw new Error('\u63D2\u4EF6\u8FDE\u63A5\u63A5\u53E3\u8FD4\u56DE\u4E86\u65E0\u6548\u6570\u636E\u3002')\n return payload\n}\n\nfunction isConnectionView(value: unknown): value is KnowledgeConnectionView {\n if (value === null || typeof value !== 'object') return false\n const item = value as Partial<KnowledgeConnectionView>\n return (item.backend === 'local' || item.backend === 'remote')\n && Number.isInteger(item.remoteTimeoutMs)\n && typeof item.tokenConfigured === 'boolean'\n && typeof item.canSwitchRemote === 'boolean'\n && typeof item.writable === 'boolean'\n && typeof item.managementAvailable === 'boolean'\n && (!item.managementAvailable || isManagementPath(item.managementPath))\n}\n\nfunction isManagementPath(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith('/') && !value.startsWith('//')\n}\n\nfunction KnowledgeLauncher({ wide, workspace }: SidebarActionProps & { workspace: KnowledgeWorkspaceController }) {\n const [open, setOpen] = useState(workspace.isOpen())\n\n useEffect(() => workspace.subscribe(() => { setOpen(workspace.isOpen()) }), [workspace])\n\n return (\n <button\n type=\"button\"\n className={`dsh-knowledge-trigger${wide ? '' : ' dsh-knowledge-trigger--rail'}${open ? ' is-active' : ''}`}\n aria-label={open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}\n aria-pressed={open}\n title={wide ? undefined : open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}\n onClick={() => { workspace.toggle() }}\n >\n <IconDataOutline16 size={wide ? 16 : 18} />\n {wide && <span>{open ? '\u8FD4\u56DE\u5BF9\u8BDD' : '\u77E5\u8BC6\u5E93'}</span>}\n </button>\n )\n}\n\nfunction KnowledgeWorkspace({\n sessionId,\n useSessions,\n client,\n workspace,\n}: ConversationSlotProps & { client: ClientContext; workspace: KnowledgeWorkspaceController }) {\n const [panelState, setPanelState] = useState<'loading' | 'ready' | 'unavailable' | 'error'>('loading')\n const [managementPath, setManagementPath] = useState<string>()\n const [panelError, setPanelError] = useState('')\n const projectId = useSessions(state => sessionId === undefined ? undefined : state.byId[sessionId]?.cwd)\n const knowledgeUrl = managementPath === undefined ? undefined : knowledgePanelUrl(managementPath, sessionId, projectId)\n const frame = useRef<HTMLIFrameElement | null>(null)\n const themeFrame = useRef(0)\n\n const loadManagement = useCallback(async (): Promise<void> => {\n setPanelState('loading')\n setPanelError('')\n try {\n const connection = await requestConnection('GET')\n if (!connection.managementAvailable || connection.managementPath === undefined) {\n setManagementPath(undefined)\n setPanelState('unavailable')\n return\n }\n setManagementPath(connection.managementPath)\n setPanelState('ready')\n } catch (error) {\n setManagementPath(undefined)\n setPanelError(connectionErrorMessage(error))\n setPanelState('error')\n }\n }, [])\n\n useEffect(() => {\n void loadManagement()\n }, [loadManagement])\n\n const sendTheme = useCallback((): void => {\n const currentFrame = frame.current\n if (currentFrame === null) return\n const target = currentFrame.contentWindow\n if (target === null) return\n const computed = getComputedStyle(document.body)\n target.postMessage(\n createKnowledgeHostTheme(computed, client.theme.getTheme()),\n frameOrigin(currentFrame) ?? '*',\n )\n }, [client])\n\n const scheduleTheme = useCallback((): void => {\n if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current)\n themeFrame.current = window.requestAnimationFrame(() => {\n themeFrame.current = 0\n sendTheme()\n })\n }, [sendTheme])\n\n useEffect(() => {\n const off = client.on('theme/change', scheduleTheme)\n const onMessage = (event: MessageEvent): void => {\n const currentFrame = frame.current\n if (event.source !== currentFrame?.contentWindow) return\n const expectedOrigin = frameOrigin(currentFrame)\n if (expectedOrigin !== undefined && event.origin !== expectedOrigin) return\n const data = event.data as { type?: unknown; version?: unknown } | null\n if (data?.type === KNOWLEDGE_THEME_READY_MESSAGE && data.version === KNOWLEDGE_THEME_PROTOCOL_VERSION) sendTheme()\n }\n window.addEventListener('message', onMessage)\n scheduleTheme()\n return () => {\n off()\n window.removeEventListener('message', onMessage)\n if (themeFrame.current !== 0) window.cancelAnimationFrame(themeFrame.current)\n }\n }, [client, scheduleTheme, sendTheme])\n\n return (\n <section className=\"dsh-knowledge-workspace\" data-xiaohei-surface=\"plugin-workspace\" aria-labelledby=\"dsh-knowledge-workspace-title\">\n <header className=\"dsh-knowledge-workspace-header\">\n <div>\n <button type=\"button\" data-xiaohei-workspace-close onClick={workspace.close} aria-label=\"\u8FD4\u56DE\u4F1A\u8BDD\" title=\"\u8FD4\u56DE\u4F1A\u8BDD\"><IconChevronLeftOutline14 size={15} /></button>\n <IconDataOutline16 size={18} />\n <span><h2 id=\"dsh-knowledge-workspace-title\">\u77E5\u8BC6\u5E93</h2><p>\u6587\u6863\u3001\u5BA1\u6838\u3001\u6302\u8F7D\u4E0E\u8BBF\u95EE\u7BA1\u7406</p></span>\n </div>\n </header>\n {panelState === 'ready' && knowledgeUrl !== undefined\n ? <iframe ref={frame} className=\"dsh-knowledge-frame\" src={knowledgeUrl} title=\"\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0\" onLoad={sendTheme} />\n : <div className=\"dsh-knowledge-panel-state\" role={panelState === 'error' ? 'alert' : 'status'} aria-live=\"polite\">\n <span className=\"dsh-knowledge-panel-state-icon\" aria-hidden=\"true\">{panelState === 'loading' ? '\u00B7\u00B7\u00B7' : panelState === 'error' ? '!' : '\u2014'}</span>\n <div>\n <h3>{panelState === 'loading' ? '\u6B63\u5728\u6253\u5F00\u77E5\u8BC6\u5E93\u2026' : panelState === 'error' ? '\u6682\u65F6\u65E0\u6CD5\u6253\u5F00\u77E5\u8BC6\u5E93' : '\u8FD9\u53F0 DSH \u672A\u542F\u7528\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0'}</h3>\n <p>{panelState === 'loading'\n ? '\u6B63\u5728\u786E\u8BA4\u5F53\u524D\u5B9E\u4F8B\u662F\u5426\u63D0\u4F9B\u7BA1\u7406\u9875\u9762\u3002'\n : panelState === 'error'\n ? panelError\n : '\u672C\u5730\u53EC\u56DE\u548C\u56DE\u5199\u4ECD\u53EF\u4F7F\u7528\u3002\u5F53\u524D profile \u5DF2\u663E\u5F0F\u5173\u95ED exposeWeb\uFF1B\u91CD\u65B0\u542F\u7528\u540E\u5373\u53EF\u5728\u8FD9\u91CC\u7BA1\u7406\u3002\u4F7F\u7528\u8FDC\u7A0B\u77E5\u8BC6\u5E93\u65F6\uFF0C\u8BF7\u524D\u5F80\u4E2D\u592E DSH \u7684\u77E5\u8BC6\u5E93\u7BA1\u7406\u53F0\u3002'}</p>\n {panelState === 'error' && <button type=\"button\" onClick={() => { void loadManagement() }}>\u91CD\u8BD5</button>}\n </div>\n </div>}\n </section>\n )\n}\n\nfunction knowledgePanelUrl(managementPath: string, sessionId?: string, projectId?: string): string {\n const params = new URLSearchParams()\n if (sessionId !== undefined) params.set('sessionId', sessionId)\n if (projectId !== undefined) params.set('projectId', projectId)\n const query = params.toString()\n return query.length === 0 ? managementPath : `${managementPath}${managementPath.includes('?') ? '&' : '?'}${query}`\n}\n\nfunction frameOrigin(frame: HTMLIFrameElement): string | undefined {\n try {\n const origin = new URL(frame.src).origin\n return origin === 'null' ? undefined : origin\n } catch {\n return undefined\n }\n}\n\nfunction installStyles(): () => void {\n const previous = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${STYLE_ID}\"]`)\n previous?.remove()\n const style = document.createElement('style')\n style.dataset.plugin = PLUGIN_ID\n style.dataset.pluginCss = STYLE_ID\n style.textContent = cssText\n document.head.appendChild(style)\n return () => { style.remove() }\n}\n", "const WORKSPACE_ACTIVATE_EVENT = '@lemoncat7/dsh-plugin-ui/workspace-activate'\n\ninterface WorkspaceActivateDetail {\n pluginId: string\n}\n\n/** Claim the conversation workspace while remaining compatible with installed plugin versions. */\nexport function activatePluginWorkspace(pluginId: string): void {\n window.dispatchEvent(new CustomEvent<WorkspaceActivateDetail>(WORKSPACE_ACTIVATE_EVENT, {\n detail: { pluginId },\n }))\n}\n\n/** Close this workspace when another plugin claims the conversation area. */\nexport function observePluginWorkspace(pluginId: string, close: () => void): () => void {\n const onActivate = (event: Event): void => {\n const detail = (event as CustomEvent<WorkspaceActivateDetail>).detail\n if (detail?.pluginId !== pluginId) close()\n }\n window.addEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate)\n return () => window.removeEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate)\n}\n", ".dsh-knowledge-trigger,\n.dsh-knowledge-workspace,\n.dsh-knowledge-settings-card,\n.dsh-knowledge-writeback-status {\n --knowledge-accent: var(--dsw-alias-interactive-primary, var(--dsw-alias-brand-primary, #547d78));\n --knowledge-on-accent: var(--dsw-alias-label-primary-foreground, #fff);\n --knowledge-danger: var(--dsw-alias-state-error-primary, #c9362b);\n --knowledge-success: var(--dsw-alias-state-success-primary, #15803d);\n}\n\n.dsh-knowledge-trigger,\n.dsh-knowledge-panel-state button,\n.dsh-knowledge-settings-card button,\n.dsh-knowledge-writeback-status button {\n -webkit-appearance: none;\n appearance: none;\n margin: 0;\n}\n\n.dsh-knowledge-trigger {\n flex: none;\n display: flex;\n align-items: center;\n gap: 8px;\n width: calc(100% + 8px);\n height: 34px;\n margin: 4px -4px;\n padding: 6px 2px 6px 10px;\n box-sizing: border-box;\n border: 0;\n border-radius: 12px;\n overflow: hidden;\n background: transparent;\n color: var(--dsw-alias-label-primary);\n cursor: pointer;\n font: inherit;\n font-size: 14px;\n line-height: 22px;\n white-space: nowrap;\n}\n\n.dsh-knowledge-trigger:hover {\n background: var(--dsw-alias-interactive-bg-hover);\n}\n\n.dsh-knowledge-trigger:focus-visible,\n.dsh-knowledge-writeback-status button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n\n.dsh-knowledge-trigger.is-active {\n background: var(--dsw-alias-interactive-bg-selected, var(--dsw-alias-interactive-bg-hover));\n color: var(--knowledge-accent);\n}\n\n.dsh-knowledge-trigger--rail {\n width: 36px;\n height: 36px;\n margin: 8px 0 4px;\n padding: 0;\n justify-content: center;\n gap: 0;\n border-radius: 50%;\n}\n\n.dsh-knowledge-workspace {\n --knowledge-pane: var(--xiaohei-plugin-pane-fill, var(--dsw-alias-bg-base, #f7f8f7));\n --knowledge-raised: var(--xiaohei-plugin-raised-fill, var(--dsw-alias-bg-layer-2, #fff));\n --knowledge-control: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--knowledge-pane);\n}\n\n.dsh-knowledge-workspace-header {\n flex: none;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 16px;\n min-height: 56px;\n padding: 8px 16px 8px 20px;\n box-sizing: border-box;\n border-bottom: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .18));\n background: var(--knowledge-pane);\n}\n\n.dsh-knowledge-workspace-header > div {\n display: flex;\n align-items: center;\n gap: 10px;\n min-width: 0;\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close] {\n -webkit-appearance: none;\n appearance: none;\n display: grid;\n place-items: center;\n box-sizing: border-box;\n flex: none;\n width: 30px;\n height: 30px;\n margin: 0;\n padding: 0;\n border: 1px solid transparent;\n border-radius: 9px;\n color: var(--dsw-alias-label-secondary, #68686f);\n background: transparent;\n font: inherit;\n line-height: 1;\n -webkit-tap-highlight-color: transparent;\n cursor: pointer;\n transition: color 140ms ease, background 140ms ease, border-color 140ms ease, transform 140ms ease;\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:hover {\n border-color: var(--dsw-alias-divider-primary, rgba(128, 128, 128, .18));\n color: var(--dsw-alias-label-primary, #171719);\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .08));\n}\n\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:active { transform: scale(.96); }\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close]:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-workspace-header [data-xiaohei-workspace-close] > svg {\n display: block;\n pointer-events: none;\n}\n\n.dsh-knowledge-workspace-header > div > span {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.dsh-knowledge-workspace-header h2,\n.dsh-knowledge-workspace-header p {\n margin: 0;\n}\n\n.dsh-knowledge-workspace-header h2 {\n color: var(--dsw-alias-label-primary);\n font-size: 15px;\n line-height: 22px;\n font-weight: 600;\n}\n\n.dsh-knowledge-workspace-header p {\n color: var(--dsw-alias-label-secondary);\n font-size: 11px;\n line-height: 16px;\n}\n\n.dsh-knowledge-frame {\n flex: 1;\n width: 100%;\n min-height: 0;\n border: 0;\n background: transparent;\n}\n\n.dsh-knowledge-panel-state {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 16px;\n min-height: 0;\n padding: 32px;\n box-sizing: border-box;\n background: transparent;\n color: var(--dsw-alias-label-primary, #171719);\n}\n\n.dsh-knowledge-panel-state-icon {\n flex: none;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 12px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .1));\n color: var(--dsw-alias-label-secondary, #68686f);\n font-size: 18px;\n font-weight: 600;\n}\n\n.dsh-knowledge-panel-state > div { max-width: 560px; }\n.dsh-knowledge-panel-state h3 { margin: 0 0 6px; font-size: 17px; line-height: 24px; font-weight: 600; }\n.dsh-knowledge-panel-state p { margin: 0; color: var(--dsw-alias-label-secondary, #68686f); font-size: 13px; line-height: 20px; }\n.dsh-knowledge-panel-state button {\n min-width: 72px;\n min-height: 32px;\n margin-top: 16px;\n padding: 6px 14px;\n border: 0;\n border-radius: 10px;\n background: var(--knowledge-accent);\n color: var(--knowledge-on-accent);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-panel-state button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n\n.dsh-knowledge-settings-card {\n list-style: none;\n overflow: hidden;\n border: 1px solid var(--dsw-alias-border-l2);\n border-radius: 12px;\n background: var(--dsw-alias-bg-layer-3);\n color: var(--dsw-alias-label-primary, #171719);\n transition: border-color .16s, background .16s;\n}\n.dsh-knowledge-settings-card:hover { border-color: var(--dsw-alias-label-dimmed); }\n.dsh-knowledge-settings-card--open { border-color: var(--dsw-alias-label-dimmed); background: var(--dsw-alias-bg-layer-2); }\n.dsh-knowledge-settings-header { display: flex; width: 100%; align-items: center; gap: 12px; padding: 14px 16px; border: 0; border-radius: 12px; background: transparent; color: inherit; text-align: left; cursor: pointer; font: inherit; }\n.dsh-knowledge-settings-header:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: -2px;\n}\n.dsh-knowledge-settings-actions button:focus-visible,\n.dsh-knowledge-settings-load-error button:focus-visible {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-settings-header > span:first-child { display: flex; min-width: 0; flex: 1; flex-direction: column; gap: 4px; }\n.dsh-knowledge-settings-header strong { font-size: 15px; font-weight: 600; line-height: 1.4; }\n.dsh-knowledge-settings-header small { color: var(--dsw-alias-label-tertiary); font-size: 13px; line-height: 1.5; }\n.dsh-knowledge-source-picker small,\n.dsh-knowledge-remote-fields small { color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-settings-summary { display: flex; flex: none; align-items: center; gap: 10px; color: var(--dsw-alias-label-tertiary); font-size: 12px; }\n.dsh-knowledge-settings-summary i { width: 8px; height: 8px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform 160ms ease; }\n.dsh-knowledge-settings-card--open .dsh-knowledge-settings-summary i { transform: rotate(225deg); }\n\n.dsh-knowledge-settings-body {\n display: grid;\n gap: 18px;\n margin: 0 16px;\n padding-bottom: 8px;\n border-top: 1px solid var(--dsw-alias-border-l2);\n}\n\n.dsh-knowledge-source-picker {\n min-width: 0;\n display: grid;\n grid-template-columns: repeat(2, minmax(0, 1fr));\n gap: 10px;\n margin: 18px 0 0;\n padding: 0;\n border: 0;\n}\n\n.dsh-knowledge-source-picker legend { margin-bottom: 8px; padding: 0; color: inherit; font-size: 13px; font-weight: 600; }\n.dsh-knowledge-source-picker label {\n display: flex;\n gap: 10px;\n padding: 13px;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .2));\n border-radius: 14px;\n cursor: pointer;\n}\n.dsh-knowledge-source-picker label.is-selected {\n border-color: var(--knowledge-accent);\n background: color-mix(in srgb, var(--knowledge-accent) 7%, transparent);\n}\n.dsh-knowledge-source-picker label.is-disabled {\n cursor: default;\n opacity: .55;\n}\n.dsh-knowledge-source-picker label:focus-within {\n outline: 2px solid var(--knowledge-accent);\n outline-offset: 2px;\n}\n.dsh-knowledge-source-picker input {\n -webkit-appearance: none;\n appearance: none;\n width: 16px;\n height: 16px;\n display: inline-grid;\n place-content: center;\n flex: none;\n margin: 2px 0 0;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .34));\n border-radius: 50%;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n color: var(--knowledge-on-accent);\n cursor: pointer;\n transition: border-color .15s ease, background-color .15s ease;\n}\n.dsh-knowledge-source-picker input::before {\n content: \"\";\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: currentColor;\n opacity: 0;\n transform: scale(.55);\n transition: opacity .12s ease, transform .15s cubic-bezier(.2, .8, .2, 1);\n}\n.dsh-knowledge-source-picker input:checked { border-color: var(--knowledge-accent); background: var(--knowledge-accent); }\n.dsh-knowledge-source-picker input:checked::before { opacity: 1; transform: scale(1); }\n.dsh-knowledge-source-picker input:disabled { cursor: default; }\n.dsh-knowledge-source-picker span { display: grid; gap: 3px; }\n\n.dsh-knowledge-remote-fields { display: grid; grid-template-columns: 1.25fr 1fr; gap: 12px; }\n.dsh-knowledge-remote-fields label,\n.dsh-knowledge-timeout-field { display: grid; gap: 6px; color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-remote-fields input,\n.dsh-knowledge-timeout-field input {\n -webkit-appearance: none;\n appearance: none;\n min-height: 38px;\n box-sizing: border-box;\n padding: 8px 11px;\n border: 1px solid var(--dsw-alias-divider-primary, rgba(128, 128, 128, .25));\n border-radius: 10px;\n outline: none;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff));\n color: var(--dsw-alias-label-primary, #171719);\n font: inherit;\n}\n.dsh-knowledge-remote-fields input:focus,\n.dsh-knowledge-timeout-field input:focus { border-color: var(--knowledge-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--knowledge-accent) 16%, transparent); }\n.dsh-knowledge-remote-fields input:-webkit-autofill,\n.dsh-knowledge-remote-fields input:-webkit-autofill:hover,\n.dsh-knowledge-remote-fields input:-webkit-autofill:focus {\n -webkit-text-fill-color: var(--dsw-alias-label-primary, #171719);\n box-shadow: 0 0 0 1000px var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-1, #fff)) inset;\n caret-color: var(--dsw-alias-label-primary, #171719);\n}\n.dsh-knowledge-timeout-field input::-webkit-inner-spin-button,\n.dsh-knowledge-timeout-field input::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }\n.dsh-knowledge-timeout-field { max-width: 240px; }\n.dsh-knowledge-field-error { color: var(--knowledge-danger) !important; }\n\n.dsh-knowledge-settings-message,\n.dsh-knowledge-settings-note { margin: 0; color: var(--dsw-alias-label-secondary, #68686f); font-size: 12px; }\n.dsh-knowledge-settings-message.is-success { color: var(--knowledge-success); }\n.dsh-knowledge-settings-message.is-error { color: var(--knowledge-danger); }\n.dsh-knowledge-settings-load-error {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 18px;\n padding: 12px 14px;\n border-radius: 12px;\n background: color-mix(in srgb, var(--knowledge-danger) 8%, transparent);\n color: var(--knowledge-danger);\n font-size: 13px;\n}\n.dsh-knowledge-settings-load-error p { margin: 0; }\n.dsh-knowledge-settings-load-error button {\n flex: none;\n min-height: 30px;\n padding: 5px 10px;\n border: 0;\n border-radius: 9px;\n background: var(--xiaohei-plugin-control-fill, var(--dsw-alias-bg-layer-2, #fff));\n color: var(--dsw-alias-label-primary, #171719);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-settings-actions { display: flex; justify-content: flex-end; gap: 8px; }\n.dsh-knowledge-settings-actions button {\n min-height: 34px;\n padding: 7px 13px;\n border: 0;\n border-radius: 10px;\n background: var(--dsw-alias-interactive-bg-hover, rgba(128, 128, 128, .1));\n color: var(--dsw-alias-label-primary, #171719);\n cursor: pointer;\n font: inherit;\n font-size: 13px;\n}\n.dsh-knowledge-settings-actions button.is-primary { background: var(--knowledge-accent); color: var(--knowledge-on-accent); }\n.dsh-knowledge-settings-actions button:disabled { cursor: default; opacity: .45; }\n\n@media (max-width: 720px) {\n .dsh-knowledge-source-picker,\n .dsh-knowledge-remote-fields { grid-template-columns: 1fr; }\n .dsh-knowledge-settings-summary { font-size: 0; }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .dsh-knowledge-settings-card,\n .dsh-knowledge-settings-header,\n .dsh-knowledge-settings-summary i { transition: none; }\n}\n\n.dsh-knowledge-writeback-status {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n color: var(--dsw-alias-label-tertiary, #6b7280);\n font-size: 12px;\n line-height: 1.5;\n}\n.dsh-knowledge-writeback-status strong {\n color: var(--dsw-alias-label-secondary, #374151);\n font-weight: 600;\n}\n.dsh-knowledge-writeback-status button {\n min-height: 24px;\n padding: 0 9px;\n border: 1px solid var(--dsw-alias-separator, #d1d5db);\n border-radius: 7px;\n color: var(--dsw-alias-label-secondary, #374151);\n background: var(--dsw-alias-button-elevated-fill, #fff);\n cursor: pointer;\n font: inherit;\n}\n.dsh-knowledge-writeback-status button:disabled { cursor: default; opacity: .5; }\n", "/** Host settings namespace that makes the knowledge connection card discoverable. */\nexport const KNOWLEDGE_SETTINGS_NAMESPACE = 'dsh-knowledge-connection'\n", "export const KNOWLEDGE_THEME_MESSAGE = '@lemoncat7/dsh-knowledge/host-theme'\nexport const KNOWLEDGE_THEME_READY_MESSAGE = '@lemoncat7/dsh-knowledge/host-theme-ready'\nexport const KNOWLEDGE_THEME_PROTOCOL_VERSION = 1\n\nexport type KnowledgeColorScheme = 'light' | 'dark'\n\nexport interface KnowledgeHostThemeMessage {\n type: typeof KNOWLEDGE_THEME_MESSAGE\n version: typeof KNOWLEDGE_THEME_PROTOCOL_VERSION\n colorScheme: KnowledgeColorScheme\n tokens: Record<string, string>\n}\n\nexport interface ThemeSnapshotLike {\n active: {\n colorScheme: KnowledgeColorScheme\n tokens: Readonly<Record<string, string>>\n }\n}\n\ninterface ComputedStyleLike {\n getPropertyValue(name: string): string\n}\n\nconst TOKEN_SOURCES = {\n '--bg': ['--xiaohei-plugin-workspace-fill', '--dsw-alias-bg-layer-1', '--dsw-alias-bg-base'],\n '--surface': ['--xiaohei-plugin-pane-fill', '--dsw-alias-bg-layer-2', '--dsw-alias-bg-layer-1'],\n '--surface-raised': ['--xiaohei-plugin-raised-fill', '--dsw-alias-bg-layer-3', '--dsw-alias-bg-overlay', '--dsw-alias-bg-layer-2'],\n '--surface-soft': ['--xiaohei-plugin-control-fill', '--dsw-alias-bg-module-platform', '--dsw-alias-bg-layer-3', '--dsw-alias-bg-layer-2'],\n '--surface-hover': ['--dsw-alias-interactive-bg-hover', '--dsw-alias-bg-layer-3'],\n '--text': ['--dsw-alias-label-primary'],\n '--text-secondary': ['--dsw-alias-label-secondary', '--dsw-alias-label-primary-dimmed'],\n '--text-tertiary': ['--dsw-alias-label-tertiary', '--dsw-alias-label-caption'],\n '--border': ['--dsw-alias-border-l2', '--dsw-alias-divider-primary', '--dsw-alias-border-l1'],\n '--border-strong': ['--dsw-alias-border-l3', '--dsw-alias-border-l2'],\n '--accent': ['--dsw-alias-button-primary-fill', '--dsw-alias-brand-primary'],\n '--accent-hover': ['--dsw-alias-button-primary-hover', '--dsw-alias-brand-primary'],\n '--accent-soft': ['--dsw-alias-interactive-bg-active', '--dsw-alias-interactive-bg-hover-accent'],\n '--on-accent': ['--dsw-alias-label-primary-foreground', '--dsw-alias-brand-primary-invert'],\n '--success': ['--dsw-alias-state-success-primary'],\n '--success-soft': ['--dsw-alias-state-success-tertiary'],\n '--warning': ['--dsw-alias-state-warn-primary', '--dsw-alias-state-warn-label'],\n '--warning-soft': ['--dsw-alias-state-warn-tertiary'],\n '--danger': ['--dsw-alias-state-error-primary'],\n '--danger-soft': ['--dsw-alias-state-error-tertiary'],\n '--shadow': ['--dsw-shadow-lv3', '--dsw-shadow-lv2'],\n} as const\n\nconst FALLBACK_TOKENS: Record<KnowledgeColorScheme, Readonly<Record<string, string>>> = {\n light: {\n '--bg': '#f5f5f7', '--surface': '#ffffff', '--surface-raised': '#ffffff',\n '--surface-soft': '#f0f0f3', '--surface-hover': '#f5f5f8',\n '--text': '#1d1d1f', '--text-secondary': '#4c4c50', '--text-tertiary': '#6e6e73',\n '--border': '#dedee3', '--border-strong': '#c7c7cc',\n '--accent': '#086bd8', '--accent-hover': '#005ab8', '--accent-soft': '#e8f2ff', '--on-accent': '#ffffff',\n '--success': '#18794e', '--success-soft': '#e8f5ee', '--warning': '#986800', '--warning-soft': '#fff4cf',\n '--danger': '#c9343a', '--danger-soft': '#fdebec', '--shadow': '0 18px 48px rgb(30 45 70 / 10%)',\n },\n dark: {\n '--bg': '#101012', '--surface': '#1c1c1e', '--surface-raised': '#242426',\n '--surface-soft': '#2c2c2e', '--surface-hover': '#303033',\n '--text': '#f5f5f7', '--text-secondary': '#c7c7cc', '--text-tertiary': '#98989d',\n '--border': '#353538', '--border-strong': '#4a4a4f',\n '--accent': '#64a8ff', '--accent-hover': '#82b8ff', '--accent-soft': '#17365d', '--on-accent': '#0c1b2c',\n '--success': '#62c596', '--success-soft': '#163a2a', '--warning': '#e7bc62', '--warning-soft': '#423414',\n '--danger': '#ff858a', '--danger-soft': '#4b2227', '--shadow': '0 16px 40px rgb(0 0 0 / 28%)',\n },\n}\n\n/** Translate DSH's public semantic palette into the knowledge console's tokens. */\nexport function createKnowledgeHostTheme(\n computed: ComputedStyleLike,\n snapshot: ThemeSnapshotLike,\n): KnowledgeHostThemeMessage {\n const tokens: Record<string, string> = {}\n for (const [target, sources] of Object.entries(TOKEN_SOURCES)) {\n const value = firstDefinedToken(computed, snapshot.active.tokens, sources)\n tokens[target] = value ?? FALLBACK_TOKENS[snapshot.active.colorScheme][target]!\n }\n return {\n type: KNOWLEDGE_THEME_MESSAGE,\n version: KNOWLEDGE_THEME_PROTOCOL_VERSION,\n colorScheme: snapshot.active.colorScheme,\n tokens,\n }\n}\n\nfunction firstDefinedToken(\n computed: ComputedStyleLike,\n snapshotTokens: Readonly<Record<string, string>>,\n sources: readonly string[],\n): string | undefined {\n for (const source of sources) {\n const computedValue = computed.getPropertyValue(source).trim()\n if (computedValue.length > 0) return computedValue\n const snapshotValue = snapshotTokens[source]?.trim()\n if (snapshotValue !== undefined && snapshotValue.length > 0) return snapshotValue\n }\n return undefined\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Claim the conversation workspace while remaining compatible with installed plugin versions. */
|
|
2
|
+
export declare function activatePluginWorkspace(pluginId: string): void;
|
|
3
|
+
/** Close this workspace when another plugin claims the conversation area. */
|
|
4
|
+
export declare function observePluginWorkspace(pluginId: string, close: () => void): () => void;
|
|
5
|
+
//# sourceMappingURL=workspace-ownership.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-ownership.d.ts","sourceRoot":"","sources":["../src/workspace-ownership.ts"],"names":[],"mappings":"AAMA,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI9D;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAOtF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const WORKSPACE_ACTIVATE_EVENT = '@lemoncat7/dsh-plugin-ui/workspace-activate';
|
|
2
|
+
/** Claim the conversation workspace while remaining compatible with installed plugin versions. */
|
|
3
|
+
export function activatePluginWorkspace(pluginId) {
|
|
4
|
+
window.dispatchEvent(new CustomEvent(WORKSPACE_ACTIVATE_EVENT, {
|
|
5
|
+
detail: { pluginId },
|
|
6
|
+
}));
|
|
7
|
+
}
|
|
8
|
+
/** Close this workspace when another plugin claims the conversation area. */
|
|
9
|
+
export function observePluginWorkspace(pluginId, close) {
|
|
10
|
+
const onActivate = (event) => {
|
|
11
|
+
const detail = event.detail;
|
|
12
|
+
if (detail?.pluginId !== pluginId)
|
|
13
|
+
close();
|
|
14
|
+
};
|
|
15
|
+
window.addEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
16
|
+
return () => window.removeEventListener(WORKSPACE_ACTIVATE_EVENT, onActivate);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=workspace-ownership.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-ownership.js","sourceRoot":"","sources":["../src/workspace-ownership.ts"],"names":[],"mappings":"AAAA,MAAM,wBAAwB,GAAG,6CAA6C,CAAA;AAM9E,kGAAkG;AAClG,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,MAAM,CAAC,aAAa,CAAC,IAAI,WAAW,CAA0B,wBAAwB,EAAE;QACtF,MAAM,EAAE,EAAE,QAAQ,EAAE;KACrB,CAAC,CAAC,CAAA;AACL,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAE,KAAiB;IACxE,MAAM,UAAU,GAAG,CAAC,KAAY,EAAQ,EAAE;QACxC,MAAM,MAAM,GAAI,KAA8C,CAAC,MAAM,CAAA;QACrE,IAAI,MAAM,EAAE,QAAQ,KAAK,QAAQ;YAAE,KAAK,EAAE,CAAA;IAC5C,CAAC,CAAA;IACD,MAAM,CAAC,gBAAgB,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAA;IAC7D,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,wBAAwB,EAAE,UAAU,CAAC,CAAA;AAC/E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lemoncat7/dsh-knowledge",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "Local and remote knowledge bases for DeepSeek Harness, with scoped recall, controlled write-back, and a Web management console",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -82,7 +82,6 @@
|
|
|
82
82
|
"@deepseek-ai/dsh-client-ui-sidebar": "0.1.1-rc.2",
|
|
83
83
|
"@deepseek-ai/dsh-client-ui-slots": "0.1.1-rc.2",
|
|
84
84
|
"@deepseek-ai/dsh-client-ui-theme": "0.1.1-rc.2",
|
|
85
|
-
"@lemoncat7/dsh-plugin-ui": "file:../dsh-plugin-ui",
|
|
86
85
|
"@types/node": "^24.0.0",
|
|
87
86
|
"@types/react": "18.3.28",
|
|
88
87
|
"dompurify": "^3.4.14",
|
package/web/app.js
CHANGED
|
@@ -1344,6 +1344,14 @@ function renderMarkdownPreview(markdown) {
|
|
|
1344
1344
|
if (!markdown.trim()) return element('div', { class: 'markdown-preview is-empty', role: 'document' }, '暂无正文')
|
|
1345
1345
|
const preview = element('div', { class: 'markdown-preview', role: 'document' })
|
|
1346
1346
|
preview.innerHTML = window.DshKnowledgeMarkdown.renderMarkdown(markdown)
|
|
1347
|
+
preview.querySelectorAll('table').forEach(table => {
|
|
1348
|
+
const scroller = element('div', {
|
|
1349
|
+
class: 'markdown-table-scroll', role: 'region', tabindex: '0',
|
|
1350
|
+
'aria-label': '表格内容,可横向滚动',
|
|
1351
|
+
})
|
|
1352
|
+
table.replaceWith(scroller)
|
|
1353
|
+
scroller.append(table)
|
|
1354
|
+
})
|
|
1347
1355
|
return preview
|
|
1348
1356
|
}
|
|
1349
1357
|
|
package/web/styles.css
CHANGED
|
@@ -171,6 +171,7 @@ html,
|
|
|
171
171
|
.note-tree,
|
|
172
172
|
.note-editor-scroll,
|
|
173
173
|
.markdown-preview pre,
|
|
174
|
+
.markdown-table-scroll,
|
|
174
175
|
.candidate-comparison pre,
|
|
175
176
|
.dialog-body,
|
|
176
177
|
.textarea {
|
|
@@ -178,16 +179,16 @@ html,
|
|
|
178
179
|
scrollbar-color: var(--scrollbar-thumb) transparent;
|
|
179
180
|
}
|
|
180
181
|
|
|
181
|
-
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar {
|
|
182
|
+
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar {
|
|
182
183
|
width: 8px;
|
|
183
184
|
height: 8px;
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-track {
|
|
187
|
+
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-track {
|
|
187
188
|
background: transparent;
|
|
188
189
|
}
|
|
189
190
|
|
|
190
|
-
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb {
|
|
191
|
+
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb {
|
|
191
192
|
min-width: 28px;
|
|
192
193
|
min-height: 28px;
|
|
193
194
|
border: 2px solid transparent;
|
|
@@ -196,7 +197,7 @@ html,
|
|
|
196
197
|
background-clip: padding-box;
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb:hover {
|
|
200
|
+
:where(html, .mount-table, .note-tree, .note-editor-scroll, .markdown-preview pre, .markdown-table-scroll, .candidate-comparison pre, .dialog-body, .textarea)::-webkit-scrollbar-thumb:hover {
|
|
200
201
|
background: var(--scrollbar-thumb-hover);
|
|
201
202
|
background-clip: padding-box;
|
|
202
203
|
}
|
|
@@ -713,7 +714,15 @@ html,
|
|
|
713
714
|
.note-tree-new { min-height: 30px; gap: 7px; border-radius: 7px; padding: 4px 8px; color: var(--text-tertiary); font-size: 11px; }
|
|
714
715
|
.note-tree-footer { border-top: 1px solid var(--border); padding: 8px 11px; }
|
|
715
716
|
.note-tree-empty { padding: 28px 12px; color: var(--text-tertiary); font-size: 12px; text-align: center; }
|
|
716
|
-
.note-editor {
|
|
717
|
+
.note-editor {
|
|
718
|
+
min-width: 0;
|
|
719
|
+
min-height: 0;
|
|
720
|
+
display: grid;
|
|
721
|
+
grid-template-rows: auto minmax(0, 1fr) auto;
|
|
722
|
+
background: var(--surface);
|
|
723
|
+
container-name: note-editor;
|
|
724
|
+
container-type: inline-size;
|
|
725
|
+
}
|
|
717
726
|
.note-editor-empty { place-items: center; display: grid; padding: 32px; }
|
|
718
727
|
.note-empty-content { max-width: 360px; text-align: center; }
|
|
719
728
|
.note-empty-content h3 { margin: 16px 0 5px; font-size: 17px; }
|
|
@@ -722,7 +731,7 @@ html,
|
|
|
722
731
|
.note-editor-toolbar { min-height: 58px; display: flex; align-items: center; justify-content: space-between; gap: 14px; border-bottom: 1px solid var(--border); padding: 9px 14px 9px 20px; }
|
|
723
732
|
.note-breadcrumb { min-width: 0; display: flex; align-items: center; gap: 7px; overflow: hidden; color: var(--text-tertiary); font-size: 11px; white-space: nowrap; }
|
|
724
733
|
.note-breadcrumb strong { overflow: hidden; color: var(--text-secondary); font-weight: 560; text-overflow: ellipsis; }
|
|
725
|
-
.note-editor-actions { display: flex; align-items: center; gap: 6px; }
|
|
734
|
+
.note-editor-actions { min-width: 0; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 6px; }
|
|
726
735
|
.editor-save-status { margin-right: 4px; color: var(--text-tertiary); font-size: 10px; white-space: nowrap; }
|
|
727
736
|
.note-mode-switch { display: inline-flex; gap: 2px; border: 1px solid var(--border); border-radius: 8px; padding: 2px; background: var(--surface-soft); }
|
|
728
737
|
.note-mode-switch button { min-width: 48px; min-height: 28px; border: 0; border-radius: 6px; padding: 4px 9px; background: transparent; color: var(--text-tertiary); font-size: 11px; font-weight: 600; }
|
|
@@ -747,6 +756,7 @@ html,
|
|
|
747
756
|
.document-finalized-banner small { color: var(--text-tertiary); white-space: nowrap; }
|
|
748
757
|
.note-paper {
|
|
749
758
|
width: 100%;
|
|
759
|
+
min-width: 0;
|
|
750
760
|
min-height: 100%;
|
|
751
761
|
margin: 0;
|
|
752
762
|
padding: clamp(34px, 5cqi, 72px) max(clamp(24px, 6cqi, 84px), calc((100% - 1120px) / 2)) 90px;
|
|
@@ -757,7 +767,7 @@ html,
|
|
|
757
767
|
.note-document-meta { display: flex; flex-wrap: wrap; gap: 7px 16px; margin: 14px 0 30px; color: var(--text-tertiary); font-size: 10px; }
|
|
758
768
|
.note-body-editor { width: 100%; min-height: 420px; border: 0; padding: 0 0 80px; resize: none; overflow: hidden; background: transparent; color: var(--text-secondary); font-family: inherit; font-size: 15px; line-height: 1.82; outline: none; }
|
|
759
769
|
.note-body-editor::placeholder { color: color-mix(in srgb, var(--text-tertiary) 70%, transparent); }
|
|
760
|
-
.markdown-preview { min-height: 420px; padding-bottom: 80px; color: var(--text-secondary); font-size: 15px; line-height: 1.78; overflow-wrap: anywhere; }
|
|
770
|
+
.markdown-preview { min-width: 0; max-width: 100%; min-height: 420px; padding-bottom: 80px; color: var(--text-secondary); font-size: 15px; line-height: 1.78; overflow-wrap: anywhere; }
|
|
761
771
|
.markdown-preview.is-empty { color: var(--text-tertiary); }
|
|
762
772
|
.markdown-preview > :first-child { margin-top: 0; }
|
|
763
773
|
.markdown-preview > :last-child { margin-bottom: 0; }
|
|
@@ -774,10 +784,23 @@ html,
|
|
|
774
784
|
.markdown-preview blockquote { border-left: 3px solid color-mix(in srgb, var(--accent) 35%, var(--border)); padding: .1em 0 .1em 1em; color: var(--text-tertiary); }
|
|
775
785
|
.markdown-preview code, .markdown-preview pre { font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace; }
|
|
776
786
|
.markdown-preview :not(pre) > code { border: 1px solid var(--border); border-radius: 5px; padding: .12em .35em; background: var(--surface-soft); color: var(--text); font-size: .9em; }
|
|
777
|
-
.markdown-preview pre { overflow: auto; margin: 1.15em 0; border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; background: var(--surface-soft); color: var(--text); font-size: 13px; line-height: 1.65; tab-size: 2; }
|
|
787
|
+
.markdown-preview pre { max-width: 100%; overflow: auto; margin: 1.15em 0; border: 1px solid var(--border); border-radius: 10px; padding: 14px 16px; background: var(--surface-soft); color: var(--text); font-size: 13px; line-height: 1.65; tab-size: 2; }
|
|
778
788
|
.markdown-preview pre code { font: inherit; }
|
|
779
|
-
.markdown-
|
|
789
|
+
.markdown-table-scroll {
|
|
790
|
+
width: 100%;
|
|
791
|
+
max-width: 100%;
|
|
792
|
+
overflow-x: auto;
|
|
793
|
+
margin: 1.15em 0;
|
|
794
|
+
border: 1px solid var(--border);
|
|
795
|
+
border-radius: 10px;
|
|
796
|
+
overscroll-behavior-inline: contain;
|
|
797
|
+
touch-action: pan-x pan-y;
|
|
798
|
+
-webkit-overflow-scrolling: touch;
|
|
799
|
+
}
|
|
800
|
+
.markdown-table-scroll:focus-visible { outline-offset: 2px; }
|
|
801
|
+
.markdown-preview table { width: max-content; min-width: 100%; margin: 0; border-collapse: collapse; font-size: 13px; }
|
|
780
802
|
.markdown-preview th, .markdown-preview td { border-bottom: 1px solid var(--border); padding: 9px 11px; text-align: left; vertical-align: top; }
|
|
803
|
+
.markdown-preview tbody tr:last-child td { border-bottom: 0; }
|
|
781
804
|
.markdown-preview th { color: var(--text); font-weight: 650; }
|
|
782
805
|
.markdown-preview hr { height: 1px; margin: 2em 0; border: 0; background: var(--border); }
|
|
783
806
|
.markdown-preview img { max-width: 100%; height: auto; border-radius: 10px; }
|
|
@@ -802,6 +825,32 @@ html,
|
|
|
802
825
|
.note-tags-field input { width: min(100%, 360px); }
|
|
803
826
|
.note-format-hint { margin-left: auto; color: var(--text-tertiary); font-size: 9px; white-space: nowrap; }
|
|
804
827
|
|
|
828
|
+
@container note-editor (max-width: 700px) {
|
|
829
|
+
.note-editor-toolbar {
|
|
830
|
+
min-height: 0;
|
|
831
|
+
display: grid;
|
|
832
|
+
grid-template-columns: minmax(0, 1fr);
|
|
833
|
+
align-items: stretch;
|
|
834
|
+
gap: 7px;
|
|
835
|
+
padding: 9px 12px;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.note-editor-actions {
|
|
839
|
+
width: 100%;
|
|
840
|
+
justify-content: flex-start;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
.note-mode-switch { margin-right: auto; }
|
|
844
|
+
.editor-save-status { margin-left: auto; }
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
@container note-editor (max-width: 480px) {
|
|
848
|
+
.note-breadcrumb { display: none; }
|
|
849
|
+
.note-mode-switch { flex: 1 1 112px; }
|
|
850
|
+
.note-mode-switch button { min-width: 0; flex: 1; }
|
|
851
|
+
.note-editor-actions > .button { flex: 1 1 auto; }
|
|
852
|
+
}
|
|
853
|
+
|
|
805
854
|
.list { display: grid; gap: 8px; }
|
|
806
855
|
.list-row {
|
|
807
856
|
min-width: 0;
|
|
@@ -1039,10 +1088,6 @@ html,
|
|
|
1039
1088
|
.note-editor { grid-column: 1; }
|
|
1040
1089
|
.note-tree-header { padding-left: 11px; }
|
|
1041
1090
|
.note-tree-header span, .tree-document-copy small, .tree-count { display: none; }
|
|
1042
|
-
.note-editor-toolbar { align-items: flex-start; padding: 8px 10px 8px 14px; }
|
|
1043
|
-
.note-breadcrumb { display: none; }
|
|
1044
|
-
.note-editor-actions { width: 100%; justify-content: flex-end; }
|
|
1045
|
-
.note-mode-switch { margin-right: auto; }
|
|
1046
1091
|
.note-paper { padding: 32px 24px 60px; }
|
|
1047
1092
|
.document-finalized-banner { grid-template-columns: 1fr; margin: 12px; }
|
|
1048
1093
|
.document-finalized-banner p { grid-column: 1; }
|