@zhou05/dsh-memory 1.0.0-dsh020.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js ADDED
@@ -0,0 +1,502 @@
1
+ window.__ModuleLoader__.load({id:"@zhou05/dsh-memory",factory:(require)=>{var module={exports:{}};var exports=module.exports;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // plugin/src/client/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ PANEL_ID: () => PANEL_ID,
24
+ activeSession: () => activeSession,
25
+ apply: () => apply,
26
+ inject: () => inject
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // plugin/src/client/MemoryWorkspace.tsx
31
+ var import_react = require("react");
32
+ var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
33
+ var import_jsx_runtime = require("react/jsx-runtime");
34
+ var kinds = { preference: "\u504F\u597D", project: "\u9879\u76EE\u4E8B\u5B9E", episode: "\u8FD1\u671F\u7ECF\u5386", reference: "\u53C2\u8003\u8D44\u6599" };
35
+ var states = { active: "\u6B63\u5728\u4F7F\u7528", archived: "\u5DF2\u5F52\u6863", retracted: "\u5DF2\u64A4\u56DE", expired: "\u5DF2\u8FC7\u671F" };
36
+ var actions = { created: "\u521B\u5EFA", updated: "\u81EA\u52A8\u66F4\u65B0", edited: "\u4EBA\u5DE5\u4FEE\u8BA2", retracted: "\u64A4\u56DE", restored: "\u6062\u590D", archived: "\u5F52\u6863", imported: "\u5BFC\u5165" };
37
+ var jobNames = { queued: "\u7B49\u5F85\u6574\u7406", running: "\u6B63\u5728\u6574\u7406", succeeded: "\u5DF2\u6574\u7406", failed: "\u6574\u7406\u5931\u8D25", deferred: "\u7B49\u5F85\u9884\u7B97\u6062\u590D", cancelled: "\u5DF2\u6682\u505C" };
38
+ var Icon = ({ kind, size = 18 }) => {
39
+ const Component = { preference: import_dsh_client_ui_primitives.IconUserOutlineRegular, project: import_dsh_client_ui_primitives.IconFolderOpenOutlineRegular, episode: import_dsh_client_ui_primitives.IconClockOutlineRegular, reference: import_dsh_client_ui_primitives.IconLinkOutlineRegular }[kind] || import_dsh_client_ui_primitives.IconDatabaseOutlineRegular;
40
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Component, { size });
41
+ };
42
+ function date(value, short = false) {
43
+ return value ? new Intl.DateTimeFormat("zh-CN", short ? { month: "short", day: "numeric" } : { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }).format(value) : "\u5C1A\u672A\u6574\u7406";
44
+ }
45
+ function bytes(n) {
46
+ return n >= 1024 ? `${(n / 1024).toFixed(1)} KB` : `${n} B`;
47
+ }
48
+ function MemoryWorkspace({ request, currentSession, subscribeSession }) {
49
+ const [snapshot, setSnapshot] = (0, import_react.useState)(null), [memories, setMemories] = (0, import_react.useState)([]);
50
+ const [tab, setTab] = (0, import_react.useState)("all"), [project, setProject] = (0, import_react.useState)("all"), [query, setQuery] = (0, import_react.useState)(""), [search, setSearch] = (0, import_react.useState)("");
51
+ const [loading, setLoading] = (0, import_react.useState)(true), [error, setError] = (0, import_react.useState)(""), [busy, setBusy] = (0, import_react.useState)(false), [notice, setNotice] = (0, import_react.useState)("");
52
+ const [selected, setSelected] = (0, import_react.useState)(null), [editor, setEditor] = (0, import_react.useState)(null), [settings, setSettings] = (0, import_react.useState)(null);
53
+ const [sessionId, setSessionId] = (0, import_react.useState)(currentSession()), [detailTab, setDetailTab] = (0, import_react.useState)("content");
54
+ const serial = (0, import_react.useRef)(0), selectionSerial = (0, import_react.useRef)(0);
55
+ (0, import_react.useEffect)(() => subscribeSession(() => setSessionId(currentSession())), [subscribeSession, currentSession]);
56
+ (0, import_react.useEffect)(() => {
57
+ const timer = setTimeout(() => setSearch(query.trim()), 180);
58
+ return () => clearTimeout(timer);
59
+ }, [query]);
60
+ const load = (0, import_react.useCallback)(async (quiet = false) => {
61
+ const seq = ++serial.current;
62
+ if (!quiet) setLoading(true);
63
+ try {
64
+ const params = { query: search, status: tab === "inactive" ? "all" : "active" };
65
+ if (project === "user") params.scope = "user";
66
+ else if (project !== "all") params.projectId = project;
67
+ if (tab === "recent") params.kind = "episode";
68
+ const [overview, list] = await Promise.all([request("snapshot", sessionId ? { sessionId } : {}), request("list", params)]);
69
+ if (seq !== serial.current) return;
70
+ setSnapshot(overview);
71
+ setMemories(list.memories.filter((m) => tab === "durable" ? m.kind !== "episode" : tab === "inactive" ? m.status !== "active" : true));
72
+ setError("");
73
+ } catch (e) {
74
+ if (seq === serial.current) setError(e instanceof Error ? e.message : "\u52A0\u8F7D\u5931\u8D25");
75
+ } finally {
76
+ if (seq === serial.current) setLoading(false);
77
+ }
78
+ }, [request, search, project, tab, sessionId]);
79
+ (0, import_react.useEffect)(() => {
80
+ void load();
81
+ const timer = setInterval(() => {
82
+ if (document.visibilityState === "visible") void load(true);
83
+ }, 1e4);
84
+ return () => {
85
+ clearInterval(timer);
86
+ serial.current++;
87
+ };
88
+ }, [load]);
89
+ (0, import_react.useEffect)(() => {
90
+ if (!notice) return;
91
+ const timer = setTimeout(() => setNotice(""), 5e3);
92
+ return () => clearTimeout(timer);
93
+ }, [notice]);
94
+ const act = async (fn, success) => {
95
+ if (busy) return null;
96
+ setBusy(true);
97
+ setError("");
98
+ try {
99
+ const value = await fn();
100
+ await load(true);
101
+ if (success) setNotice(success);
102
+ return value;
103
+ } catch (e) {
104
+ setError(e instanceof Error ? e.message : "\u64CD\u4F5C\u5931\u8D25\uFF0C\u539F\u5185\u5BB9\u5DF2\u4FDD\u7559");
105
+ return null;
106
+ } finally {
107
+ setBusy(false);
108
+ }
109
+ };
110
+ const open = async (id) => {
111
+ const seq = ++selectionSerial.current;
112
+ setDetailTab("content");
113
+ try {
114
+ const value = await request("detail", { id });
115
+ if (seq === selectionSerial.current) setSelected(value);
116
+ } catch (e) {
117
+ setError(e instanceof Error ? e.message : "\u52A0\u8F7D\u5931\u8D25");
118
+ }
119
+ };
120
+ const closeDetail = () => {
121
+ selectionSerial.current++;
122
+ setSelected(null);
123
+ };
124
+ const state = async (status) => {
125
+ const m = selected.memory, result = await act(() => request("state", {}, { id: m.id, expectedVersion: m.version, status }), status === "retracted" ? "\u5DF2\u64A4\u56DE\uFF0C\u4E0D\u518D\u81EA\u52A8\u5F15\u7528\u3002\u53EF\u5728\u300C\u5DF2\u9000\u51FA\u300D\u4E2D\u6062\u590D\u3002" : status === "archived" ? "\u5DF2\u5F52\u6863\uFF0C\u5386\u53F2\u4ECD\u4FDD\u7559\u3002" : "\u5DF2\u6062\u590D\u5230\u5F53\u524D\u8BB0\u5FC6\u3002");
126
+ if (result) await open(m.id);
127
+ };
128
+ const add = () => {
129
+ const projectId = project !== "all" && project !== "user" ? project : snapshot?.currentSession?.projectId;
130
+ setEditor({ key: "manual-" + Date.now().toString(36), title: "", body: "", kind: projectId ? "project" : "preference", scope: projectId ? "project" : "user", projectId: projectId || null, pinned: false });
131
+ };
132
+ const save = async () => {
133
+ const value = await act(() => request("save", {}, { ...editor, expectedVersion: editor.version }), editor.id ? "\u4FEE\u6539\u5DF2\u4FDD\u5B58\uFF0C\u4E0B\u6B21\u5BF9\u8BDD\u4F7F\u7528\u65B0\u7248\u672C\u3002" : "\u8BB0\u5FC6\u5DF2\u4FDD\u5B58\u3002");
134
+ if (value) {
135
+ setEditor(null);
136
+ if (selected) await open(value.memory.id);
137
+ }
138
+ };
139
+ const exportMemories = async () => {
140
+ await act(async () => {
141
+ const data = await request("export");
142
+ const url = URL.createObjectURL(new Blob([JSON.stringify(data, null, 2)], { type: "application/json" }));
143
+ const a = document.createElement("a");
144
+ a.href = url;
145
+ a.download = `DSH-memory-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`;
146
+ a.click();
147
+ setTimeout(() => URL.revokeObjectURL(url), 1e3);
148
+ return data;
149
+ }, "\u8BB0\u5FC6\u5DF2\u5BFC\u51FA\uFF0C\u4E0D\u5305\u542B\u539F\u59CB\u804A\u5929\u3002");
150
+ };
151
+ const latest = snapshot?.jobs?.[0], current = snapshot?.currentSession;
152
+ const trace = snapshot?.traces?.find((t) => t.session_id === sessionId) || snapshot?.traces?.[0];
153
+ const disabled = busy || !snapshot;
154
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", { className: "dsh-memory", "aria-label": "\u8BB0\u5FC6\u7BA1\u7406", children: [
155
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-memory-scroll", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-memory-content", children: [
156
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("header", { className: "dm-heading", children: [
157
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { children: "\u8BB0\u5FC6" }),
159
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u628A\u6709\u7528\u7684\u4FE1\u606F\u7559\u5230\u4E0B\u4E00\u6B21\u3002" })
160
+ ] }),
161
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-heading-actions", children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-auto", children: [
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-dot", "data-on": snapshot?.settings?.automatic !== false }),
164
+ snapshot?.settings?.automatic === false ? "\u81EA\u52A8\u6574\u7406\u5DF2\u6682\u505C" : "\u81EA\u52A8\u6574\u7406"
165
+ ] }),
166
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { "aria-label": "\u8BB0\u5FC6\u8BBE\u7F6E", title: "\u8BB0\u5FC6\u8BBE\u7F6E", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconSettingsOutlineRegular, { size: 18 }), onClick: () => snapshot && setSettings({ ...snapshot.settings }), disabled }),
167
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 16 }), onClick: add, disabled, children: "\u6DFB\u52A0\u8BB0\u5FC6" })
168
+ ] })
169
+ ] }),
170
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-alert", role: "alert", children: [
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: error }),
172
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", onClick: () => void load(), children: "\u91CD\u8BD5" })
173
+ ] }),
174
+ notice && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-notice", role: "status", children: notice }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-overview", "aria-label": "\u8BB0\u5FC6\u6982\u51B5", children: [
176
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
177
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: snapshot?.counts?.durable ?? "\u2014" }),
178
+ " \u957F\u671F\u8BB0\u5FC6"
179
+ ] }),
180
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-separator" }),
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: snapshot?.counts?.recent ?? "\u2014" }),
183
+ " \u8FD1\u671F\u7ECF\u5386"
184
+ ] }),
185
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-overview-status", children: latest?.status === "failed" ? "\u6700\u8FD1\u6574\u7406\u5931\u8D25 \xB7 \u4E0B\u65B9\u53EF\u67E5\u770B\u4E0E\u91CD\u8BD5" : latest?.status === "running" ? "\u6B63\u5728\u6574\u7406\u65B0\u589E\u5BF9\u8BDD\u2026" : snapshot?.pending ? `${snapshot.pending} \u9879\u7B49\u5F85\u6574\u7406` : snapshot?.settings?.automatic === false ? "\u81EA\u52A8\u6574\u7406\u5DF2\u6682\u505C" : "\u81EA\u52A8\u4FDD\u5B58\uFF0C\u968F\u65F6\u53EF\u6539" })
186
+ ] }),
187
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-toolbar", children: [
188
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { className: "dm-search", "aria-label": "\u641C\u7D22\u8BB0\u5FC6", placeholder: "\u641C\u7D22\u8BB0\u5FC6\u5185\u5BB9", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconSearchOutlineRegular, { size: 16 }), value: query, onChange: (e) => setQuery(e.target.value) }),
189
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { className: "dm-select dm-project", "aria-label": "\u8BB0\u5FC6\u8303\u56F4", value: project, onChange: (e) => setProject(e.target.value), children: [
190
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "all", children: "\u5168\u90E8\u9879\u76EE" }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "user", children: "\u901A\u7528\u8BB0\u5FC6" }),
192
+ (snapshot?.projects || []).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("option", { value: p.id, children: [
193
+ p.name,
194
+ p.id === current?.projectId ? " \xB7 \u5F53\u524D" : ""
195
+ ] }, p.id))
196
+ ] }),
197
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconRefreshOutlineRegular, { size: 16 }), "aria-label": "\u5237\u65B0\u8BB0\u5FC6", title: "\u5237\u65B0", disabled: loading, onClick: () => void load() })
198
+ ] }),
199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-tabs-row", children: [
200
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.SegmentedTabs, { label: "\u8BB0\u5FC6\u5206\u7C7B", value: tab, onChange: setTab, items: [{ value: "all", label: "\u5168\u90E8" }, { value: "durable", label: "\u957F\u671F\u8BB0\u5FC6" }, { value: "recent", label: "\u8FD1\u671F\u7ECF\u5386" }, { value: "inactive", label: "\u5DF2\u9000\u51FA" }] }),
201
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-count", children: [
202
+ memories.length,
203
+ " \u6761"
204
+ ] })
205
+ ] }),
206
+ loading && !snapshot ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-empty", role: "status", children: [
207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconDatabaseOutlineRegular, { size: 30 }),
208
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: "\u6B63\u5728\u8BFB\u53D6\u8BB0\u5FC6" })
209
+ ] }) : memories.length ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-list", "aria-label": "\u8BB0\u5FC6\u5217\u8868", children: memories.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { className: "dm-row", onClick: () => void open(m.id), children: [
210
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-row-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { kind: m.kind }) }),
211
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-row-main", children: [
212
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-row-title", children: [
213
+ m.title,
214
+ m.pinned && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconPinFillRegular, { size: 13 })
215
+ ] }),
216
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-row-body", children: m.body }),
217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-row-meta", children: [
218
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: kinds[m.kind] }),
219
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\xB7" }),
220
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: m.scope === "user" ? "\u901A\u7528" : m.projectName || "\u9879\u76EE" }),
221
+ m.status !== "active" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
222
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\xB7" }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: states[m.status] })
224
+ ] })
225
+ ] })
226
+ ] }),
227
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-row-end", children: [
228
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: date(m.updatedMs, true) }),
229
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconChevronRightOutlineRegular, { size: 16 })
230
+ ] })
231
+ ] }, m.id)) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-empty", children: [
232
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-empty-icon", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconDatabaseOutlineRegular, { size: 28 }) }),
233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { children: search ? "\u6CA1\u6709\u627E\u5230\u76F8\u5173\u8BB0\u5FC6" : tab === "inactive" ? "\u8FD9\u91CC\u8FD8\u6CA1\u6709\u9000\u51FA\u7684\u8BB0\u5FC6" : "\u8BB0\u5FC6\u4F1A\u5728\u5BF9\u8BDD\u4E2D\u6162\u6162\u79EF\u7D2F" }),
234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: search ? "\u6362\u4E00\u4E2A\u5173\u952E\u8BCD\uFF0C\u6216\u5207\u6362\u5230\u5176\u4ED6\u9879\u76EE\u770B\u770B\u3002" : tab === "inactive" ? "\u5F52\u6863\u3001\u64A4\u56DE\u548C\u8FC7\u671F\u7684\u5185\u5BB9\u4F1A\u4FDD\u7559\u5728\u8FD9\u91CC\uFF0C\u4E0D\u518D\u8FDB\u5165\u65E5\u5E38\u53EC\u56DE\u3002" : "\u504F\u597D\u3001\u9879\u76EE\u51B3\u5B9A\u548C\u8FD1\u671F\u8FDB\u5C55\uFF0C\u4F1A\u5728\u5BF9\u8BDD\u540E\u81EA\u52A8\u6574\u7406\u3002\u4F60\u968F\u65F6\u53EF\u4EE5\u67E5\u770B\u4F9D\u636E\u3001\u4FEE\u6539\u6216\u64A4\u56DE\u3002" }),
235
+ !search && tab !== "inactive" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 16 }), onClick: add, disabled, children: "\u5148\u8BB0\u4E0B\u4E00\u4EF6\u4E8B" }),
236
+ !search && tab !== "inactive" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: "\u4ECE\u542F\u7528\u540E\u7684\u65B0\u5BF9\u8BDD\u5F00\u59CB\uFF0C\u4E0D\u4F1A\u56DE\u8BFB\u5168\u90E8\u5386\u53F2\u3002" })
237
+ ] }),
238
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", { className: "dm-footer", children: [
239
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "\u5185\u5BB9\u4FDD\u5B58\u5728\u672C\u673A \xB7 \u9879\u76EE\u8BB0\u5FC6\u4E92\u76F8\u9694\u79BB" }),
240
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconDownloadOutlineRegular, { size: 14 }), onClick: () => void exportMemories(), disabled, children: "\u5BFC\u51FA" })
241
+ ] }),
242
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "dm-activity", children: [
243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", { children: [
244
+ "\u6574\u7406\u4E0E\u53EC\u56DE",
245
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: latest ? `${jobNames[latest.status]} \xB7 ${date(latest.updated_ms)}` : "\u5C1A\u65E0\u6574\u7406\u8BB0\u5F55" })
246
+ ] }),
247
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-activity-body", children: [
248
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u53EA\u5C55\u793A\u5904\u7406\u72B6\u6001\u3002\u8BB0\u5FC6\u8FDB\u5165\u4E0A\u4E0B\u6587\uFF0C\u4E0D\u4EE3\u8868\u6A21\u578B\u4E00\u5B9A\u91C7\u7528\u4E86\u5B83\u3002" }),
249
+ trace && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-trace", children: [
250
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("h3", { children: [
251
+ "\u6700\u8FD1\u63D0\u4F9B\u7ED9\u6A21\u578B ",
252
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: bytes(trace.bytes) })
253
+ ] }),
254
+ trace.items.length ? trace.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { onClick: () => void open(item.id), children: [
255
+ item.title,
256
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: item.reason })
257
+ ] }, item.id)) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u672C\u6B21\u6CA1\u6709\u63D0\u4F9B\u76F8\u5173\u8BB0\u5FC6\u3002" })
258
+ ] }),
259
+ (snapshot?.jobs || []).slice(0, 5).map((job) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-job", children: [
260
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: jobNames[job.status] }),
261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: job.error || (job.result ? (() => {
262
+ try {
263
+ const r = JSON.parse(job.result);
264
+ return `\u4FDD\u5B58 ${r.written} \u6761 \xB7 \u8DF3\u8FC7 ${r.skipped} \u6761`;
265
+ } catch {
266
+ return "";
267
+ }
268
+ })() : "\u7B49\u5F85\u65B0\u5BF9\u8BDD\u5B8C\u6210") }),
269
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: date(job.updated_ms) })
270
+ ] }, job.id)),
271
+ snapshot?.jobs?.some((j) => j.status === "failed") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", variant: "outline", disabled: busy, onClick: () => void act(() => request("retry", {}, {}), "\u5DF2\u91CD\u65B0\u6392\u961F\uFF0C\u4ECD\u9075\u5B88\u4ECA\u65E5\u9884\u7B97\u3002"), children: "\u91CD\u8BD5\u5931\u8D25\u7684\u6574\u7406" })
272
+ ] })
273
+ ] })
274
+ ] }) }),
275
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Modal, { open: !!selected && !editor, onClose: closeDetail, title: selected?.memory.title || "\u8BB0\u5FC6", closeLabel: "\u5173\u95ED", className: "dm-modal", footer: selected && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-detail-actions", children: [
276
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "dm-help", children: [
277
+ "\u7248\u672C ",
278
+ selected.memory.version,
279
+ " \xB7 ",
280
+ states[selected.memory.status]
281
+ ] }),
282
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: selected.memory.status === "active" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconEditOutlineRegular, { size: 14 }), disabled: busy, onClick: () => setEditor({ ...selected.memory }), children: "\u7F16\u8F91" }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconArchiveOutlineRegular, { size: 14 }), disabled: busy, onClick: () => void state("archived"), children: "\u5F52\u6863" }),
285
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", disabled: busy, onClick: () => void state("retracted"), children: "\u64A4\u56DE" })
286
+ ] }) : selected.memory.status !== "expired" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.IconUnarchiveOutlineRegular, { size: 14 }), disabled: busy, onClick: () => void state("active"), children: "\u6062\u590D\u8BB0\u5FC6" }) : null })
287
+ ] }), children: selected && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-detail", children: [
288
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-alert", role: "alert", children: error }),
289
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.SegmentedTabs, { label: "\u8BB0\u5FC6\u8BE6\u60C5", value: detailTab, onChange: setDetailTab, items: [{ value: "content", label: "\u5185\u5BB9" }, { value: "evidence", label: "\u6765\u6E90\u4E0E\u7248\u672C" }] }),
290
+ detailTab === "content" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
291
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-detail-labels", children: [
292
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: kinds[selected.memory.kind] }),
293
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: selected.memory.scope === "user" ? "\u901A\u7528\u8BB0\u5FC6" : selected.memory.projectName || "\u9879\u76EE\u8BB0\u5FC6" }),
294
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: { user_statement: "\u7528\u6237\u9648\u8FF0", assistant_report: "\u52A9\u624B\u62A5\u544A", manual: "\u4EBA\u5DE5\u4FEE\u8BA2", legacy: "\u65E7\u7248\u5BFC\u5165" }[selected.memory.basis] })
295
+ ] }),
296
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-body", children: selected.memory.body }),
297
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("dl", { className: "dm-properties", children: [
298
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", { children: "\u6700\u8FD1\u66F4\u65B0" }),
299
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: date(selected.memory.updatedMs) }),
300
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", { children: "\u6709\u6548\u671F" }),
301
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: selected.memory.expiresMs ? `\u81F3 ${date(selected.memory.expiresMs)}` : "\u957F\u671F\u4FDD\u7559\uFF0C\u53EF\u968F\u65F6\u64A4\u56DE" }),
302
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dt", { children: "\u7F6E\u9876" }),
303
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("dd", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Switch, { label: "\u7F6E\u9876\u8FD9\u6761\u8BB0\u5FC6", checked: selected.memory.pinned, disabled: busy || selected.memory.status !== "active", onChange: async (pinned) => {
304
+ const result = await act(() => request("save", {}, { ...selected.memory, pinned, expectedVersion: selected.memory.version }));
305
+ if (result) await open(selected.memory.id);
306
+ } }) })
307
+ ] }),
308
+ selected.memory.status === "retracted" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u5DF2\u505C\u6B62\u5F15\u7528\uFF0C\u4E5F\u4E0D\u4F1A\u4ECE\u540C\u4E00\u6765\u6E90\u81EA\u52A8\u751F\u6210\u3002\u5386\u53F2\u4E0E\u539F\u59CB\u5BF9\u8BDD\u4ECD\u7136\u4FDD\u7559\u3002" }),
309
+ selected.memory.basis === "assistant_report" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u8FD9\u662F\u52A9\u624B\u5F53\u65F6\u7684\u62A5\u544A\uFF0C\u4E0D\u7B49\u4E8E\u5DF2\u7ECF\u6838\u9A8C\u7684\u6267\u884C\u7ED3\u679C\u3002" })
310
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
311
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6765\u6E90\u4F9D\u636E" }),
312
+ selected.evidence.length ? selected.evidence.map((source) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-source", children: [
313
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
314
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: source.role === "user" ? "\u4F60\u7684\u6D88\u606F" : "\u52A9\u624B\u62A5\u544A" }),
315
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: date(source.createdMs) })
316
+ ] }),
317
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: source.text }),
318
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("small", { children: [
319
+ "\u4F1A\u8BDD ",
320
+ source.sessionId,
321
+ " \xB7 \u6D88\u606F ",
322
+ source.seq
323
+ ] })
324
+ ] }, source.id)) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u8FD9\u6761\u5185\u5BB9\u7531\u4F60\u624B\u52A8\u6DFB\u52A0\uFF0C\u6CA1\u6709\u5173\u8054\u7684\u5BF9\u8BDD\u539F\u6587\u3002" }),
325
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u4FEE\u8BA2\u5386\u53F2" }),
326
+ selected.versions.map((version) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "dm-version", children: [
327
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("summary", { children: [
328
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
329
+ "v",
330
+ version.version,
331
+ " \xB7 ",
332
+ actions[version.action] || version.action
333
+ ] }),
334
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("small", { children: date(version.created_ms) })
335
+ ] }),
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: version.snapshot.body }),
337
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
338
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dm-help", children: version.actor === "user" ? "\u4F60\u7684\u64CD\u4F5C" : version.actor === "automatic" ? "\u540E\u53F0\u6574\u7406" : "\u4F1A\u8BDD\u8BB0\u5FC6\u5DE5\u5177" }),
339
+ version.version !== selected.memory.version && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { size: "sm", variant: "outline", disabled: busy, onClick: async () => {
340
+ const result = await act(() => request("restore", {}, { id: selected.memory.id, expectedVersion: selected.memory.version, targetVersion: version.version }), "\u5DF2\u6062\u590D\u4E3A\u65B0\u7248\u672C\uFF0C\u65E7\u5386\u53F2\u4FDD\u6301\u4E0D\u53D8\u3002");
341
+ if (result) await open(selected.memory.id);
342
+ }, children: "\u6062\u590D\u6B64\u7248\u672C" })
343
+ ] })
344
+ ] }, version.id))
345
+ ] })
346
+ ] }) }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Modal, { open: !!editor, onClose: () => !busy && setEditor(null), title: editor?.id ? "\u7F16\u8F91\u8BB0\u5FC6" : "\u6DFB\u52A0\u8BB0\u5FC6", closeLabel: "\u5173\u95ED", className: "dm-modal", footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form-footer", children: [
348
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { onClick: () => setEditor(null), disabled: busy, children: "\u53D6\u6D88" }),
349
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busy || !editor?.title?.trim() || !editor?.body?.trim(), onClick: () => void save(), children: busy ? "\u4FDD\u5B58\u4E2D\u2026" : "\u4FDD\u5B58" })
350
+ ] }), children: editor && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form", children: [
351
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-alert", role: "alert", children: error }),
352
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
353
+ "\u6807\u9898",
354
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { "aria-label": "\u8BB0\u5FC6\u6807\u9898", value: editor.title, maxLength: 100, placeholder: "\u4F8B\u5982\uFF1A\u754C\u9762\u4FDD\u6301\u7B80\u6D01\u3001\u7CBE\u81F4", onChange: (e) => setEditor({ ...editor, title: e.target.value }) })
355
+ ] }),
356
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form-pair", children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
358
+ "\u7C7B\u522B",
359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("select", { className: "dm-select", "aria-label": "\u8BB0\u5FC6\u7C7B\u522B", value: editor.kind, onChange: (e) => setEditor({ ...editor, kind: e.target.value }), children: Object.entries(kinds).filter(([key]) => editor.scope !== "user" || ["preference", "reference"].includes(key)).map(([key, label]) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: key, children: label }, key)) })
360
+ ] }),
361
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
362
+ "\u8303\u56F4",
363
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("select", { className: "dm-select", "aria-label": "\u4FDD\u5B58\u8303\u56F4", disabled: !!editor.id, value: editor.scope === "user" ? "user" : editor.projectId || "", onChange: (e) => setEditor({ ...editor, scope: e.target.value === "user" ? "user" : "project", projectId: e.target.value === "user" ? null : e.target.value, kind: e.target.value === "user" ? "preference" : editor.kind }), children: [
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: "user", children: "\u901A\u7528\u8BB0\u5FC6" }),
365
+ (snapshot?.projects || []).map((p) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("option", { value: p.id, children: p.name }, p.id))
366
+ ] })
367
+ ] })
368
+ ] }),
369
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
370
+ "\u5185\u5BB9",
371
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("textarea", { className: "dm-textarea", "aria-label": "\u8BB0\u5FC6\u5185\u5BB9", rows: 6, maxLength: 2400, value: editor.body, placeholder: "\u5199\u4E0B\u4EE5\u540E\u4ECD\u6709\u7528\u7684\u4E00\u4EF6\u4E8B\u3002", onChange: (e) => setEditor({ ...editor, body: e.target.value }) })
372
+ ] }),
373
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u4FDD\u5B58\u540E\u7ACB\u5373\u751F\u6548\u3002\u4EBA\u5DE5\u4FEE\u8BA2\u7684\u5185\u5BB9\u4E0D\u4F1A\u88AB\u540E\u53F0\u6574\u7406\u8986\u76D6\uFF1B\u539F\u6709\u7248\u672C\u4F1A\u4FDD\u7559\u3002" })
374
+ ] }) }),
375
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Modal, { open: !!settings, onClose: () => !busy && setSettings(null), title: "\u8BB0\u5FC6\u8BBE\u7F6E", closeLabel: "\u5173\u95ED", className: "dm-modal", footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form-footer", children: [
376
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { disabled: busy, onClick: () => setSettings(null), children: "\u53D6\u6D88" }),
377
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", disabled: busy, onClick: async () => {
378
+ const result = await act(() => request("settings", {}, settings), "\u8BB0\u5FC6\u8BBE\u7F6E\u5DF2\u4FDD\u5B58\u3002");
379
+ if (result) setSettings(null);
380
+ }, children: "\u4FDD\u5B58\u8BBE\u7F6E" })
381
+ ] }), children: settings && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-settings", children: [
382
+ error && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dm-alert", role: "alert", children: error }),
383
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-setting-row", children: [
384
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
385
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u81EA\u52A8\u6574\u7406" }),
386
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u4ECE\u65B0\u589E\u5BF9\u8BDD\u4E2D\u63D0\u70BC\uFF0C\u81EA\u52A8\u751F\u6548\uFF0C\u4E0D\u9010\u6761\u6253\u6270\u3002" })
387
+ ] }),
388
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Switch, { label: "\u81EA\u52A8\u6574\u7406", checked: settings.automatic, onChange: (automatic) => setSettings({ ...settings, automatic }) })
389
+ ] }),
390
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u8BB0\u5FC6\u4FDD\u5B58\u5728\u672C\u673A\u3002\u6574\u7406\u4F1A\u5C06\u8131\u654F\u540E\u7684\u65B0\u589E\u5BF9\u8BDD\u7247\u6BB5\u53D1\u7ED9\u8BE5\u4F1A\u8BDD\u6240\u7528\u7684\u6A21\u578B\uFF0C\u5E76\u4EA7\u751F\u6A21\u578B\u7528\u91CF\uFF1B\u51ED\u636E\u8BC6\u522B\u4E0D\u662F\u5B8C\u6574\u7684\u654F\u611F\u4FE1\u606F\u68C0\u6D4B\u3002" }),
391
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-setting-row", children: [
392
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
393
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u5728\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u8BB0\u5FC6" }),
394
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u5173\u95ED\u540E\u4FDD\u7559\u5185\u5BB9\uFF0C\u4F46\u4E0D\u81EA\u52A8\u63D0\u4F9B\u5230\u6A21\u578B\u4E0A\u4E0B\u6587\u3002" })
395
+ ] }),
396
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Switch, { label: "\u5728\u5BF9\u8BDD\u4E2D\u4F7F\u7528\u8BB0\u5FC6", checked: settings.recall, onChange: (recall) => setSettings({ ...settings, recall }) })
397
+ ] }),
398
+ current && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-setting-row", children: [
399
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
400
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: "\u672C\u6B21\u4F1A\u8BDD\u53C2\u4E0E\u8BB0\u5FC6" }),
401
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { children: "\u5173\u95ED\u540E\uFF0C\u672C\u6B21\u4F1A\u8BDD\u4E0D\u518D\u8BB0\u5F55\uFF0C\u4E5F\u4E0D\u8C03\u7528\u5DF2\u6709\u8BB0\u5FC6\u3002" })
402
+ ] }),
403
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Switch, { label: "\u672C\u6B21\u4F1A\u8BDD\u53C2\u4E0E\u8BB0\u5FC6", checked: current.enabled, disabled: busy, onChange: (enabled) => void act(() => request("session", {}, { id: current.id, enabled }), "\u672C\u6B21\u4F1A\u8BDD\u7684\u8BB0\u5FC6\u72B6\u6001\u5DF2\u66F4\u65B0\u3002") })
404
+ ] }),
405
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { children: "\u6574\u7406\u9884\u7B97" }),
406
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u4F7F\u7528\u5F53\u524D\u4F1A\u8BDD\u7684\u6A21\u578B\u3002\u8FBE\u5230\u4E0A\u9650\u540E\u6392\u961F\u7B49\u5F85\uFF0C\u4E0D\u5F71\u54CD\u6B63\u5E38\u804A\u5929\u3002" }),
407
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form-pair", children: [
408
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
409
+ "\u6BCF\u65E5\u6700\u591A\u8C03\u7528",
410
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { type: "number", "aria-label": "\u6BCF\u65E5\u6700\u591A\u8C03\u7528", min: 1, max: 200, value: settings.dailyCalls, onChange: (e) => setSettings({ ...settings, dailyCalls: Number(e.target.value) }) })
411
+ ] }),
412
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
413
+ "\u6BCF\u65E5 Token \u9884\u7B97",
414
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { type: "number", "aria-label": "\u6BCF\u65E5Token\u9884\u7B97", min: 5e3, max: 1e6, step: 5e3, value: settings.dailyTokens, onChange: (e) => setSettings({ ...settings, dailyTokens: Number(e.target.value) }) })
415
+ ] })
416
+ ] }),
417
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "dm-help", children: [
418
+ "\u4ECA\u65E5 ",
419
+ snapshot?.usage.calls || 0,
420
+ " \u6B21 \xB7 \u5DF2\u8BA1 ",
421
+ (snapshot?.usage.tokens || 0).toLocaleString(),
422
+ " Token\uFF08\u542B\u5728\u9014\u9884\u7559\uFF1B\u7F3A\u5C11\u7528\u91CF\u65F6\u4FDD\u5B88\u4F30\u7B97\uFF09"
423
+ ] }),
424
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dm-form-pair", children: [
425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
426
+ "\u8FD1\u671F\u7ECF\u5386\u6709\u6548\u5929\u6570",
427
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { type: "number", "aria-label": "\u8FD1\u671F\u7ECF\u5386\u6709\u6548\u5929\u6570", min: 1, max: 180, value: settings.recentDays, onChange: (e) => setSettings({ ...settings, recentDays: Number(e.target.value) }) })
428
+ ] }),
429
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { children: [
430
+ "\u5355\u6B21\u4E0A\u4E0B\u6587\u9884\u7B97\uFF08\u5B57\u8282\uFF09",
431
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Input, { type: "number", "aria-label": "\u5355\u6B21\u4E0A\u4E0B\u6587\u9884\u7B97", min: 2e3, max: 16e3, step: 1e3, value: settings.contextBytes, onChange: (e) => setSettings({ ...settings, contextBytes: Number(e.target.value) }) })
432
+ ] })
433
+ ] }),
434
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "dm-help", children: "\u6709\u6548\u671F\u8BBE\u7F6E\u7528\u4E8E\u65B0\u751F\u6210\u7684\u8FD1\u671F\u7ECF\u5386\u3002\u957F\u671F\u504F\u597D\u4E0D\u4F1A\u6309\u5929\u6570\u81EA\u52A8\u5220\u9664\u3002" })
435
+ ] }) })
436
+ ] });
437
+ }
438
+
439
+ // plugin/src/client/MemoryPanelIcon.tsx
440
+ var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primitives");
441
+ var import_jsx_runtime2 = require("react/jsx-runtime");
442
+ function MemoryPanelIcon(_props) {
443
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dsh_client_ui_primitives2.IconDatabaseOutlineRegular, { size: 18 });
444
+ }
445
+
446
+ // plugin/src/client/memory.css
447
+ var memory_default = ".dsh-memory{height:100%;width:100%;min-height:0;min-width:0;overflow:hidden;display:flex;flex-direction:column;color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-base);font-family:inherit;font-size:14px;line-height:1.55;container-type:inline-size;container-name:memory}\n.dsh-memory *,.dm-modal *{box-sizing:border-box}\n.dsh-memory-scroll{overflow:auto;width:100%;min-height:0;flex:1;scrollbar-gutter:stable}\n.dsh-memory-content{width:100%;max-width:1040px;margin:0 auto;padding:36px 36px 28px}\n.dm-heading{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:25px}\n.dm-heading h1{font-size:24px;line-height:32px;font-weight:600;letter-spacing:-.4px;margin:0 0 5px}\n.dm-heading p,.dm-help{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:1.65;margin:0}\n.dm-heading-actions{display:flex;align-items:center;gap:8px;flex-shrink:0}\n.dm-auto{display:inline-flex;align-items:center;gap:7px;font-size:12px;color:var(--dsw-alias-label-secondary);margin-right:8px;white-space:nowrap}\n.dm-dot{width:6px;height:6px;background:var(--dsw-alias-label-dimmed);border-radius:50%}.dm-dot[data-on=true]{background:var(--dsw-alias-state-business-primary)}\n.dm-overview{display:flex;align-items:center;gap:16px;color:var(--dsw-alias-label-secondary);font-size:12px;padding-bottom:23px}\n.dm-overview strong{font-size:15px;font-weight:550;color:var(--dsw-alias-label-primary);margin-right:5px;font-variant-numeric:tabular-nums}.dm-separator{width:1px;height:12px;background:var(--dsw-alias-border-l3)}\n.dm-overview-status{margin-left:auto;color:var(--dsw-alias-label-tertiary)}\n.dm-toolbar{display:flex;align-items:center;gap:10px;margin-bottom:16px}.dm-search{flex:1;min-width:0;height:36px!important;border-radius:var(--dsw-radius-md)}\n.dm-select{appearance:auto;height:36px;min-width:0;padding:0 28px 0 11px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);font:inherit;font-size:13px;outline:none;cursor:pointer}\n.dm-select:focus-visible,.dm-textarea:focus{border-color:var(--dsw-alias-state-business-primary)}.dm-select:disabled{opacity:.6;cursor:default}.dm-project{max-width:220px}\n.dm-tabs-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:14px}.dm-count{font-size:12px;color:var(--dsw-alias-label-tertiary);white-space:nowrap}\n.dm-list{border:.5px solid var(--dsw-alias-border-l3);border-radius:14px;overflow:hidden}\n.dm-row{display:flex;width:100%;gap:14px;align-items:flex-start;text-align:left;border:0;border-bottom:.5px solid var(--dsw-alias-border-l3);border-radius:0;padding:18px 18px 16px;background:transparent;color:inherit;font:inherit;cursor:pointer;transition:background .12s ease}\n.dm-row:last-child{border-bottom:0}.dm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.dm-row:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:-2px}\n.dm-row-icon{width:32px;height:32px;flex:none;display:flex;align-items:center;justify-content:center;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-radius:9px}\n.dm-row-main{display:block;flex:1;min-width:0}.dm-row-title{font-size:14px;font-weight:550;display:flex;align-items:center;gap:7px;line-height:23px}.dm-row-title svg{color:var(--dsw-alias-label-tertiary);flex:none}\n.dm-row-body{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--dsw-alias-label-secondary);font-size:13px;line-height:21px;margin-top:3px;overflow-wrap:anywhere;white-space:pre-line}\n.dm-row-meta{display:flex;gap:7px;color:var(--dsw-alias-label-tertiary);font-size:11px;margin-top:8px}.dm-row-end{display:flex;align-items:center;gap:10px;color:var(--dsw-alias-label-tertiary);font-size:11px;white-space:nowrap;padding-top:3px}\n.dm-empty{display:flex;flex-direction:column;align-items:center;text-align:center;padding:62px 20px 58px;border:.5px solid var(--dsw-alias-border-l3);border-radius:14px}\n.dm-empty-icon{width:58px;height:58px;border-radius:17px;display:flex;align-items:center;justify-content:center;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);margin-bottom:20px}\n.dm-empty h2{font-size:16px;font-weight:550;margin:0 0 10px}.dm-empty p{max-width:340px;color:var(--dsw-alias-label-tertiary);line-height:1.8;font-size:13px;margin:0 0 22px}.dm-empty small{font-size:11px;color:var(--dsw-alias-label-tertiary);margin-top:15px}\n.dm-footer{display:flex;justify-content:space-between;align-items:center;margin:12px 1px 22px;color:var(--dsw-alias-label-tertiary);font-size:11px;gap:12px}\n.dm-alert,.dm-notice{padding:10px 13px;border:.5px solid var(--dsw-alias-border-l3);border-radius:10px;background:var(--dsw-alias-bg-layer-1);font-size:12px;display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:15px}\n.dm-alert{border-left:3px solid var(--dsw-alias-state-business-primary)}.dm-notice{color:var(--dsw-alias-label-secondary)}\n.dm-activity{border-top:.5px solid var(--dsw-alias-border-l3);font-size:12px;color:var(--dsw-alias-label-secondary)}.dm-activity>summary{cursor:pointer;padding:16px 0;list-style:disclosure-closed inside}.dm-activity[open]>summary{list-style:disclosure-open inside}.dm-activity>summary>span{float:right;font-size:11px;color:var(--dsw-alias-label-tertiary)}.dm-activity-body{padding:0 0 16px}\n.dm-activity h3,.dm-detail h3,.dm-settings h3{font-size:13px;font-weight:550;margin:22px 0 12px}.dm-trace h3 small{font-size:11px;font-weight:400;color:var(--dsw-alias-label-tertiary);margin-left:6px}\n.dm-trace>button{display:flex;justify-content:space-between;gap:16px;width:100%;font:inherit;color:inherit;background:transparent;border:0;padding:8px;border-radius:6px;text-align:left;cursor:pointer}.dm-trace>button:hover{background:var(--dsw-alias-interactive-bg-hover)}.dm-trace>button>span{color:var(--dsw-alias-label-tertiary)}\n.dm-job{display:flex;gap:12px;padding:10px 0;border-bottom:.5px solid var(--dsw-alias-border-l3);align-items:baseline}.dm-job>span:nth-child(2){flex:1;color:var(--dsw-alias-label-tertiary)}.dm-job small{white-space:nowrap;color:var(--dsw-alias-label-tertiary)}\n.dm-modal{width:min(660px,calc(100vw - 40px));max-width:660px;color:var(--dsw-alias-label-primary);font-family:inherit}\n.dm-detail,.dm-form,.dm-settings{font-size:13px;line-height:1.65}.dm-detail-labels{display:flex;gap:8px;flex-wrap:wrap;margin:20px 0 15px}.dm-detail-labels>span{font-size:11px;border:.5px solid var(--dsw-alias-border-l3);padding:2px 8px;border-radius:6px;color:var(--dsw-alias-label-secondary)}\n.dm-body{font-size:14px;line-height:1.85;white-space:pre-wrap;overflow-wrap:anywhere;margin:0 0 24px}\n.dm-properties{display:grid;grid-template-columns:84px 1fr;gap:13px 12px;border-top:.5px solid var(--dsw-alias-border-l3);padding-top:18px;margin:0 0 10px;font-size:12px;align-items:center}.dm-properties dt{color:var(--dsw-alias-label-tertiary)}.dm-properties dd{margin:0}\n.dm-detail-actions{width:100%;display:flex;align-items:center;justify-content:space-between;gap:10px}.dm-detail-actions>div{display:flex;gap:4px}.dm-form-footer{display:flex;justify-content:flex-end;width:100%;gap:8px}\n.dm-form>label,.dm-form-pair>label{display:flex;flex-direction:column;gap:7px;font-size:12px;font-weight:500}.dm-form>label{margin-bottom:17px}.dm-form-pair{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:16px 0}.dm-form-pair>label>*{font-weight:400}\n.dm-form label>div,.dm-form-pair label>div{width:100%}.dm-textarea{width:100%;resize:vertical;min-height:140px;max-height:350px;font:inherit;font-size:14px;line-height:1.7;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);padding:10px 12px;outline:none}.dm-textarea::placeholder{color:var(--dsw-alias-label-dimmed)}\n.dm-source{padding:13px 15px;background:var(--dsw-alias-bg-layer-1);border:.5px solid var(--dsw-alias-border-l3);border-radius:10px;margin-bottom:10px}.dm-source>div{display:flex;justify-content:space-between;gap:12px}.dm-source strong{font-size:12px;font-weight:550}.dm-source p,.dm-version p{white-space:pre-wrap;overflow-wrap:anywhere;margin:9px 0;color:var(--dsw-alias-label-secondary);font-size:12px}.dm-source small{font-size:10px;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere}\n.dm-version{padding:12px 0;border-bottom:.5px solid var(--dsw-alias-border-l3)}.dm-version>summary{cursor:pointer;font-size:12px}.dm-version>summary small{float:right;color:var(--dsw-alias-label-tertiary);font-size:11px}.dm-version>div{display:flex;align-items:center;justify-content:space-between;gap:10px}\n.dm-setting-row{display:flex;justify-content:space-between;align-items:center;gap:20px;padding:16px 0;border-bottom:.5px solid var(--dsw-alias-border-l3)}.dm-setting-row:first-child{padding-top:0}.dm-setting-row strong{font-size:13px;font-weight:550}.dm-setting-row p{font-size:12px;color:var(--dsw-alias-label-tertiary);margin:4px 0 0}.dm-setting-row>button{flex:none}\n@media(max-width:900px){.dsh-memory-content{padding:26px 22px}.dm-auto{display:none}}\n@media(max-width:640px){.dsh-memory-content{padding:22px 16px}.dm-heading{gap:10px}.dm-heading h1{font-size:22px}.dm-heading-actions{gap:2px}.dm-overview-status{display:none}.dm-project{max-width:140px}.dm-row{padding:15px 13px;gap:10px}.dm-row-end>span{display:none}.dm-empty{padding:45px 16px}.dm-activity>summary>span{float:none;display:block;margin:6px 0 0 15px}.dm-form-pair{grid-template-columns:1fr}.dm-job{flex-wrap:wrap}.dm-detail-actions{align-items:flex-start;flex-direction:column}.dm-modal{width:calc(100vw - 24px)}}\n@media(prefers-reduced-motion:reduce){.dm-row{transition:none}}\n@container memory (max-width:700px){.dm-auto,.dm-overview-status{display:none}.dsh-memory-content{padding:24px 20px}.dm-row-end>span{display:none}.dm-heading-actions{gap:2px}.dm-project{max-width:150px}}\n@container memory (max-width:480px){.dm-heading{align-items:flex-start;flex-direction:column;gap:14px}.dm-heading-actions{align-self:flex-end}.dm-toolbar{gap:5px}.dm-project{max-width:115px}.dm-footer{align-items:flex-start}.dm-empty{padding:40px 14px}.dm-activity>summary>span{float:none;display:block;margin-top:6px}}\n";
448
+
449
+ // plugin/src/client/index.ts
450
+ var inject = ["slots", "locale", "sessions"];
451
+ var PANEL_ID = "auto-memory";
452
+ var BASE = "/api/auto-memory/v2.";
453
+ function activeSession(byId, previous) {
454
+ const selected = Object.values(byId).find((s) => (s.retainedBy?.mainView ?? 0) > 0);
455
+ return selected?.id || (previous && byId[previous] ? previous : void 0);
456
+ }
457
+ function face(ctx) {
458
+ let previous;
459
+ const store = ctx.get("sessions")?.list;
460
+ const currentSession = () => {
461
+ previous = activeSession(store?.getSnapshot?.()?.byId || {}, previous);
462
+ return previous;
463
+ };
464
+ currentSession();
465
+ ctx.effect(() => store?.subscribe?.(() => currentSession()), "memory active session");
466
+ return {
467
+ currentSession,
468
+ subscribeSession: (listener) => store?.subscribe?.(listener) || (() => {
469
+ }),
470
+ request: async (route, params = {}, body) => {
471
+ const query = new URLSearchParams(params).toString();
472
+ const response = await fetch(BASE + route + (query ? "?" + query : ""), {
473
+ method: body === void 0 ? "GET" : "POST",
474
+ credentials: "same-origin",
475
+ headers: body === void 0 ? { "cache-control": "no-store" } : { "content-type": "application/json" },
476
+ ...body === void 0 ? {} : { body: JSON.stringify(body) }
477
+ });
478
+ let value;
479
+ try {
480
+ value = await response.json();
481
+ } catch {
482
+ throw new Error("\u8BB0\u5FC6\u670D\u52A1\u6682\u4E0D\u53EF\u7528\uFF08HTTP " + response.status + "\uFF09");
483
+ }
484
+ if (!response.ok) throw new Error(value?.error || "\u8BB0\u5FC6\u64CD\u4F5C\u5931\u8D25\uFF08HTTP " + response.status + "\uFF09");
485
+ return value;
486
+ }
487
+ };
488
+ }
489
+ function apply(ctx) {
490
+ ctx.effect(() => ctx.locale.register("autoMemory", { zh: { panel: "\u8BB0\u5FC6" }, en: { panel: "Memory" } }), "memory locale");
491
+ ctx.effect(() => {
492
+ const style = document.createElement("style");
493
+ style.dataset.pluginCss = "@zhou05/dsh-memory/v2";
494
+ style.textContent = memory_default;
495
+ document.head.appendChild(style);
496
+ return () => style.remove();
497
+ }, "memory styles");
498
+ const api = face(ctx), t = ctx.locale.bind("autoMemory");
499
+ ctx.slots.inject("main", () => ctx.slots.register({ name: "main", key: PANEL_ID, locale: "autoMemory", inject: () => api }, MemoryWorkspace));
500
+ ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({ name: "sidebar.panellist", id: PANEL_ID, order: 50, label: () => t("panel"), locale: "autoMemory" }, MemoryPanelIcon));
501
+ }
502
+ return module.exports;}});