dsh-mnemon-source-runtime 0.5.0-rc.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-external contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # dsh-mnemon-source-runtime
2
+
3
+ An ordinary, self-contained Source plugin. It owns its configuration, storage,
4
+ projection, read/write semantics and tests; Core supplies no private controller.
5
+
6
+ Install declared dependencies, then run `pnpm verify`. For unreleased SDK work,
7
+ install the packed `dsh-mnemon` artifact as the development peer. This directory
8
+ has no dependency on the parent repository's tsconfig, test helpers or source.
9
+
10
+ Configure `dataDir` explicitly to reuse existing data. Otherwise storage is scoped
11
+ to the stable Source instance id under `~/.mnemon/sources/`. The default Mnemon
12
+ bundle supplies the existing storage paths without changing existing user data.
13
+
14
+ This package does not auto-mount a default instance. The Starter or a user's
15
+ Profile explicitly mounts its Entry. The same module can be mounted again with
16
+ another Entry id and configuration; no default Strategy is installed here.
17
+
18
+ ## Source-owned Client
19
+
20
+ The optional ./client entry is a normal DSH Client module. This package owns
21
+ its pages, browser API adapter, Host management operations, and tests. It only
22
+ imports the public dsh-mnemon/client helpers; it never receives a Host Context,
23
+ raw RPC transport, credentials, or an LLM View grant.
24
+
25
+ The default distribution loads these same Client plugins through DSH. Each page
26
+ uses Source-scoped read/mutate operations. Optional Agent-assisted cross-Source
27
+ maintenance is advertised by the Host through the same scoped page client; it
28
+ is not silently installed by a Source. There is one Slot owner per Source page,
29
+ not a second fallback registration or copied default implementation.
30
+
31
+ pnpm verify checks Host behavior and real Source-backed page interactions, then
32
+ builds both Host and browser artifacts plus their public declarations. Client
33
+ tests load the installed Core's browser artifact using dsh-mnemon/testing; they
34
+ have no dependency on Core's repository sources or configuration files.
package/lib/client.js ADDED
@@ -0,0 +1,590 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-mnemon-source-runtime",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ let dsh_mnemon_client = require("dsh-mnemon/client");
9
+ let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region src/client/pages.tsx
11
+ function RuntimePage(props) {
12
+ const t = (0, dsh_mnemon_client.useT)();
13
+ const locale = (0, dsh_mnemon_client.useLocale)();
14
+ const runtimeAddFormId = (0, react.useId)();
15
+ const runtimeEditFormId = (0, react.useId)();
16
+ const pageSize = 10;
17
+ const [snapshot, setSnapshot] = (0, react.useState)(null);
18
+ const [loading, setLoading] = (0, react.useState)(true);
19
+ const [error, setError] = (0, react.useState)(null);
20
+ const [notice, setNotice] = (0, react.useState)(null);
21
+ const [target, setTarget] = (0, react.useState)("memory");
22
+ const [importance, setImportance] = (0, react.useState)("normal");
23
+ const [content, setContent] = (0, react.useState)("");
24
+ const [saving, setSaving] = (0, react.useState)(false);
25
+ const [editing, setEditing] = (0, react.useState)(null);
26
+ const [editContent, setEditContent] = (0, react.useState)("");
27
+ const [editImportance, setEditImportance] = (0, react.useState)("normal");
28
+ const [branches, setBranches] = (0, react.useState)("");
29
+ const [editBranches, setEditBranches] = (0, react.useState)("");
30
+ const [editBranchesOriginal, setEditBranchesOriginal] = (0, react.useState)("");
31
+ const [removing, setRemoving] = (0, react.useState)(null);
32
+ const [adding, setAdding] = (0, react.useState)(false);
33
+ const [filterTarget, setFilterTarget] = (0, react.useState)("all");
34
+ const [filterQuery, setFilterQuery] = (0, react.useState)("");
35
+ const [visibleLimit, setVisibleLimit] = (0, react.useState)(pageSize);
36
+ const load = (0, react.useCallback)(async () => {
37
+ setLoading(true);
38
+ setError(null);
39
+ try {
40
+ setSnapshot(await props.client.runtimeMemory());
41
+ } catch (reason) {
42
+ setError((0, dsh_mnemon_client.message)(reason));
43
+ } finally {
44
+ setLoading(false);
45
+ }
46
+ }, [props.client]);
47
+ (0, react.useEffect)(() => {
48
+ load();
49
+ }, [load, props.revision]);
50
+ (0, react.useEffect)(() => {
51
+ setVisibleLimit(pageSize);
52
+ }, [filterQuery, filterTarget]);
53
+ const entryKey = (entry) => `${entry.target}:${entry.created_at}:${entry.content}`;
54
+ const mutate = async (request) => {
55
+ setNotice(null);
56
+ setError(null);
57
+ const result = await props.client.mutateRuntimeMemory(request);
58
+ setNotice(result.maintenance === void 0 ? t(`runtime.result.${request.action}`, {
59
+ target: t(`runtime.target.${request.target}`),
60
+ count: result.entryCount
61
+ }) : result.maintenance.kind === "local-compaction" ? t("runtime.result.localCompaction", {
62
+ target: t(`runtime.target.${request.target}`),
63
+ count: result.entryCount
64
+ }) : t("runtime.result.maintenance", {
65
+ target: t(`runtime.target.${request.target}`),
66
+ count: result.entryCount,
67
+ spaces: result.maintenance.memoryBodyIds.join(", ") || "—"
68
+ }));
69
+ await load();
70
+ props.onMutate();
71
+ };
72
+ const add = async (event) => {
73
+ event.preventDefault();
74
+ if (content.trim() === "") return;
75
+ setSaving(true);
76
+ try {
77
+ const branchInput = target === "memory" ? (0, dsh_mnemon_client.parseBranchesInput)(branches) : void 0;
78
+ await mutate({
79
+ action: "add",
80
+ target,
81
+ content,
82
+ importance,
83
+ ...branchInput === void 0 ? {} : { branches: branchInput }
84
+ });
85
+ setContent("");
86
+ setBranches("");
87
+ setAdding(false);
88
+ } catch (reason) {
89
+ setError((0, dsh_mnemon_client.message)(reason));
90
+ } finally {
91
+ setSaving(false);
92
+ }
93
+ };
94
+ const beginEdit = (entry) => {
95
+ const branchText = entry.branches?.join(", ") ?? "";
96
+ setEditing(entryKey(entry));
97
+ setEditContent(entry.content);
98
+ setEditImportance(entry.importance);
99
+ setEditBranches(branchText);
100
+ setEditBranchesOriginal(branchText);
101
+ setRemoving(null);
102
+ };
103
+ const replace = async (entry) => {
104
+ if (editContent.trim() === "") return;
105
+ setSaving(true);
106
+ try {
107
+ const rawBranches = editBranches.trim();
108
+ const branchDelta = entry.target !== "memory" || rawBranches === editBranchesOriginal.trim() ? void 0 : rawBranches === "" ? [] : (0, dsh_mnemon_client.parseBranchesInput)(editBranches);
109
+ await mutate({
110
+ action: "replace",
111
+ target: entry.target,
112
+ old_text: entry.content,
113
+ content: editContent,
114
+ importance: editImportance,
115
+ ...branchDelta === void 0 ? {} : { branches: branchDelta }
116
+ });
117
+ setEditing(null);
118
+ } catch (reason) {
119
+ setError((0, dsh_mnemon_client.message)(reason));
120
+ } finally {
121
+ setSaving(false);
122
+ }
123
+ };
124
+ const remove = async (entry) => {
125
+ setSaving(true);
126
+ try {
127
+ await mutate({
128
+ action: "remove",
129
+ target: entry.target,
130
+ old_text: entry.content
131
+ });
132
+ setRemoving(null);
133
+ } catch (reason) {
134
+ setError((0, dsh_mnemon_client.message)(reason));
135
+ } finally {
136
+ setSaving(false);
137
+ }
138
+ };
139
+ const runtimeEditActionClass = (0, dsh_mnemon_client.appearanceClass)(dsh_mnemon_client.memoryPageStyles.ghostButton, (0, dsh_mnemon_client.appearanceClass)(dsh_mnemon_client.memorySidebarStyles.itemActionButton, dsh_mnemon_client.memorySidebarStyles.itemEditAction));
140
+ const runtimeRemoveActionClass = (0, dsh_mnemon_client.appearanceClass)(dsh_mnemon_client.memoryPageStyles.dangerButton, (0, dsh_mnemon_client.appearanceClass)(dsh_mnemon_client.memorySidebarStyles.itemActionButton, dsh_mnemon_client.memorySidebarStyles.itemDangerAction));
141
+ const runtimeEntry = (entry, showTarget = false) => {
142
+ const key = entryKey(entry);
143
+ const isRemoving = removing === key;
144
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
145
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntry,
146
+ "data-importance": entry.importance,
147
+ "data-target": entry.target,
148
+ children: [
149
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
150
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntryMeta,
151
+ children: [showTarget ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
152
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntryBadges,
153
+ children: [
154
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
155
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntryTarget,
156
+ children: entry.target === "user" ? "USER.md" : "MEMORY.md"
157
+ }),
158
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`runtime.importance.${entry.importance}`) }),
159
+ entry.branches !== void 0 && entry.branches.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
160
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntryBranch,
161
+ title: t("runtime.branchBadge"),
162
+ children: entry.branches.join(", ")
163
+ })
164
+ ]
165
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`runtime.importance.${entry.importance}`) }), entry.branches !== void 0 && entry.branches.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
166
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEntryBranch,
167
+ title: t("runtime.branchBadge"),
168
+ children: entry.branches.join(", ")
169
+ })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
170
+ dateTime: entry.updated_at,
171
+ children: new Date(entry.updated_at).toLocaleString(locale)
172
+ })]
173
+ }),
174
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: entry.content }),
175
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("footer", { children: props.writeEnabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
176
+ type: "button",
177
+ className: runtimeEditActionClass,
178
+ disabled: saving && isRemoving,
179
+ onClick: () => beginEdit(entry),
180
+ children: t("runtime.editAction")
181
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
182
+ type: "button",
183
+ className: runtimeRemoveActionClass,
184
+ disabled: saving && isRemoving,
185
+ onClick: () => {
186
+ setRemoving(key);
187
+ setEditing(null);
188
+ },
189
+ children: t("runtime.removeAction")
190
+ })] }) : null })
191
+ ]
192
+ }, key);
193
+ };
194
+ const targetSummary = (value) => {
195
+ const view = snapshot?.targets[value];
196
+ const percentage = view === void 0 || view.limit === 0 ? 0 : Math.min(100, Math.round(view.used / view.limit * 100));
197
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
198
+ className: dsh_mnemon_client.memoryPageStyles.runtimeSummaryCard,
199
+ "aria-label": t(`runtime.target.${value}`),
200
+ children: [
201
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
202
+ className: dsh_mnemon_client.memoryPageStyles.runtimeTargetHeader,
203
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: value === "user" ? "USER.md" : "MEMORY.md" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t(`runtime.target.${value}`) })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: view?.entryCount ?? 0 })]
204
+ }),
205
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
206
+ className: dsh_mnemon_client.memoryPageStyles.capacityLine,
207
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", { style: { width: `${percentage}%` } }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: view === void 0 ? "—" : `${(0, dsh_mnemon_client.humanBytes)(view.used)} / ${(0, dsh_mnemon_client.humanBytes)(view.limit)}` })]
208
+ }),
209
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
210
+ className: dsh_mnemon_client.memoryPageStyles.runtimeTargetDescription,
211
+ children: t(`runtime.target.${value}.description`)
212
+ })
213
+ ]
214
+ });
215
+ };
216
+ const normalizedQuery = filterQuery.trim().toLocaleLowerCase();
217
+ const filteredEntries = (snapshot?.entries ?? []).filter((entry) => (filterTarget === "all" || entry.target === filterTarget) && (normalizedQuery === "" || entry.content.toLocaleLowerCase().includes(normalizedQuery)));
218
+ const visibleEntries = filteredEntries.slice(0, visibleLimit);
219
+ const closeComposer = () => {
220
+ setContent("");
221
+ setAdding(false);
222
+ };
223
+ const composer = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
224
+ id: runtimeAddFormId,
225
+ className: dsh_mnemon_client.memoryPageStyles.runtimeComposer,
226
+ onSubmit: (event) => void add(event),
227
+ children: [
228
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
229
+ className: dsh_mnemon_client.memoryPageStyles.runtimeComposerHeading,
230
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", { children: t("runtime.addTitle") }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtime.addDescription") })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("runtime.hotContext") })]
231
+ }),
232
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
233
+ "aria-label": t("runtime.content"),
234
+ value: content,
235
+ onChange: (event) => setContent(event.target.value),
236
+ rows: 3,
237
+ placeholder: t("runtime.placeholder")
238
+ }),
239
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
240
+ className: dsh_mnemon_client.memoryPageStyles.runtimeComposerActions,
241
+ children: [
242
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("runtime.target"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
243
+ value: target,
244
+ onChange: (event) => setTarget(event.target.value),
245
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
246
+ value: "memory",
247
+ children: t("runtime.target.memory")
248
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
249
+ value: "user",
250
+ children: t("runtime.target.user")
251
+ })]
252
+ })] }),
253
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("runtime.importance"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
254
+ value: importance,
255
+ onChange: (event) => setImportance(event.target.value),
256
+ children: [
257
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
258
+ value: "critical",
259
+ children: t("runtime.importance.critical")
260
+ }),
261
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
262
+ value: "normal",
263
+ children: t("runtime.importance.normal")
264
+ }),
265
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
266
+ value: "low",
267
+ children: t("runtime.importance.low")
268
+ })
269
+ ]
270
+ })] }),
271
+ target === "memory" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
272
+ className: dsh_mnemon_client.memoryPageStyles.runtimeComposerBranch,
273
+ children: [t("runtime.branches"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
274
+ value: branches,
275
+ onChange: (event) => setBranches(event.target.value),
276
+ placeholder: t("runtime.branchesPlaceholder"),
277
+ "aria-label": t("runtime.branches")
278
+ })]
279
+ })
280
+ ]
281
+ })
282
+ ]
283
+ });
284
+ const editingEntry = editing === null ? void 0 : snapshot?.entries.find((entry) => entryKey(entry) === editing);
285
+ const removingEntry = removing === null ? void 0 : snapshot?.entries.find((entry) => entryKey(entry) === removing);
286
+ const editForm = editingEntry === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
287
+ id: runtimeEditFormId,
288
+ className: dsh_mnemon_client.memoryPageStyles.bodyEdit,
289
+ onSubmit: (event) => {
290
+ event.preventDefault();
291
+ replace(editingEntry);
292
+ },
293
+ children: [
294
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("runtime.editContent"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
295
+ "aria-label": t("runtime.editContent"),
296
+ value: editContent,
297
+ onChange: (event) => setEditContent(event.target.value),
298
+ rows: 7
299
+ })] }),
300
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("runtime.importance"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
301
+ "aria-label": t("runtime.importance"),
302
+ value: editImportance,
303
+ onChange: (event) => setEditImportance(event.target.value),
304
+ children: [
305
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
306
+ value: "critical",
307
+ children: t("runtime.importance.critical")
308
+ }),
309
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
310
+ value: "normal",
311
+ children: t("runtime.importance.normal")
312
+ }),
313
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
314
+ value: "low",
315
+ children: t("runtime.importance.low")
316
+ })
317
+ ]
318
+ })] }),
319
+ editingEntry.target === "memory" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
320
+ className: dsh_mnemon_client.memoryPageStyles.bodyEditBranch,
321
+ children: [
322
+ t("runtime.branches"),
323
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
324
+ value: editBranches,
325
+ onChange: (event) => setEditBranches(event.target.value),
326
+ placeholder: t("runtime.branchesPlaceholder"),
327
+ "aria-label": t("runtime.branches")
328
+ }),
329
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("small", { children: t("runtime.branchesHint") })
330
+ ]
331
+ })
332
+ ]
333
+ });
334
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
335
+ className: dsh_mnemon_client.memoryPageStyles.page,
336
+ children: [
337
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.PageHeader, {
338
+ title: t("runtime.title"),
339
+ description: t("runtime.description"),
340
+ meta: snapshot === null ? t("common.loading") : t("runtime.total", { count: snapshot.entries.length }),
341
+ action: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
342
+ type: "button",
343
+ className: dsh_mnemon_client.memoryPageStyles.secondaryButton,
344
+ disabled: loading,
345
+ onClick: () => void load(),
346
+ children: t("runtime.refresh")
347
+ }), props.writeEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
348
+ type: "button",
349
+ className: dsh_mnemon_client.memoryPageStyles.primaryButton,
350
+ onClick: () => setAdding(true),
351
+ children: t("runtime.addButton")
352
+ })] })
353
+ }),
354
+ error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
355
+ className: dsh_mnemon_client.memoryPageStyles.inlineError,
356
+ role: "alert",
357
+ children: error
358
+ }),
359
+ notice !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
360
+ className: dsh_mnemon_client.memoryPageStyles.runtimeNotice,
361
+ role: "status",
362
+ children: notice
363
+ }),
364
+ !props.writeEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
365
+ className: dsh_mnemon_client.memoryPageStyles.runtimeReadOnly,
366
+ children: t("runtime.readOnly")
367
+ }),
368
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
369
+ className: dsh_mnemon_client.memoryPageStyles.runtimeSummaryGrid,
370
+ children: [targetSummary("user"), targetSummary("memory")]
371
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
372
+ className: dsh_mnemon_client.memoryPageStyles.runtimeBrowser,
373
+ "aria-label": t("runtime.entriesAria"),
374
+ children: [
375
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
376
+ className: dsh_mnemon_client.memoryPageStyles.runtimeBrowserToolbar,
377
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
378
+ className: dsh_mnemon_client.memoryPageStyles.runtimeScopeFilter,
379
+ role: "group",
380
+ "aria-label": t("runtime.scopeAria"),
381
+ children: [
382
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
383
+ type: "button",
384
+ "data-active": filterTarget === "all" || void 0,
385
+ onClick: () => setFilterTarget("all"),
386
+ children: [
387
+ t("runtime.scopeAll"),
388
+ " ",
389
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: snapshot?.entries.length ?? 0 })
390
+ ]
391
+ }),
392
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
393
+ type: "button",
394
+ "data-active": filterTarget === "user" || void 0,
395
+ onClick: () => setFilterTarget("user"),
396
+ children: [
397
+ t("runtime.target.user"),
398
+ " ",
399
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: snapshot?.targets.user.entryCount ?? 0 })
400
+ ]
401
+ }),
402
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
403
+ type: "button",
404
+ "data-active": filterTarget === "memory" || void 0,
405
+ onClick: () => setFilterTarget("memory"),
406
+ children: [
407
+ t("runtime.target.memory"),
408
+ " ",
409
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: snapshot?.targets.memory.entryCount ?? 0 })
410
+ ]
411
+ })
412
+ ]
413
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
414
+ className: dsh_mnemon_client.memoryPageStyles.runtimeFilterQuery,
415
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
416
+ "aria-hidden": "true",
417
+ children: "⌕"
418
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
419
+ "aria-label": t("runtime.filterAria"),
420
+ value: filterQuery,
421
+ onChange: (event) => setFilterQuery(event.target.value),
422
+ placeholder: t("runtime.filterPlaceholder")
423
+ })]
424
+ })]
425
+ }),
426
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
427
+ className: dsh_mnemon_client.memoryPageStyles.runtimeUnifiedList,
428
+ children: [visibleEntries.map((entry) => runtimeEntry(entry, true)), !loading && filteredEntries.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
429
+ className: dsh_mnemon_client.memoryPageStyles.runtimeEmpty,
430
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "○" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtime.noMatch") })]
431
+ })]
432
+ }),
433
+ !loading && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.ProgressiveFooter, {
434
+ visible: visibleEntries.length,
435
+ total: filteredEntries.length,
436
+ pageSize,
437
+ onMore: () => setVisibleLimit((value) => value + pageSize)
438
+ })
439
+ ]
440
+ })] }),
441
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
442
+ className: dsh_mnemon_client.memoryPageStyles.runtimeFootnote,
443
+ children: t("runtime.footnote")
444
+ }),
445
+ adding && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SidebarModal, {
446
+ title: t("runtime.addTitle"),
447
+ description: t("runtime.addDescription"),
448
+ busy: saving,
449
+ onClose: closeComposer,
450
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
451
+ className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
452
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
453
+ type: "button",
454
+ "data-dialog-close": true,
455
+ className: dsh_mnemon_client.memoryPageStyles.ghostButton,
456
+ disabled: saving,
457
+ onClick: closeComposer,
458
+ children: t("common.cancel")
459
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
460
+ type: "submit",
461
+ form: runtimeAddFormId,
462
+ className: dsh_mnemon_client.memoryPageStyles.primaryButton,
463
+ disabled: saving || content.trim() === "",
464
+ children: saving ? t("runtime.saving") : t("runtime.addAction")
465
+ })]
466
+ }),
467
+ children: composer
468
+ }),
469
+ editingEntry !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SidebarModal, {
470
+ title: t("runtime.editContent"),
471
+ description: t(`runtime.target.${editingEntry.target}`),
472
+ busy: saving,
473
+ onClose: () => setEditing(null),
474
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
475
+ className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
476
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
477
+ type: "button",
478
+ "data-dialog-close": true,
479
+ className: dsh_mnemon_client.memoryPageStyles.ghostButton,
480
+ disabled: saving,
481
+ onClick: () => setEditing(null),
482
+ children: t("common.cancel")
483
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
484
+ type: "submit",
485
+ form: runtimeEditFormId,
486
+ className: dsh_mnemon_client.memoryPageStyles.primaryButton,
487
+ disabled: saving || editContent.trim() === "",
488
+ children: t("runtime.saveEdit")
489
+ })]
490
+ }),
491
+ children: editForm
492
+ }),
493
+ removingEntry !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SidebarModal, {
494
+ title: t("runtime.removeTitle"),
495
+ description: t(`runtime.target.${removingEntry.target}`),
496
+ busy: saving,
497
+ onClose: () => setRemoving(null),
498
+ footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
499
+ className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
500
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
501
+ type: "button",
502
+ "data-dialog-close": true,
503
+ "data-autofocus": true,
504
+ className: dsh_mnemon_client.memoryPageStyles.ghostButton,
505
+ disabled: saving,
506
+ onClick: () => setRemoving(null),
507
+ children: t("common.cancel")
508
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
509
+ type: "button",
510
+ className: dsh_mnemon_client.memoryPageStyles.dangerSolidButton,
511
+ disabled: saving,
512
+ onClick: () => void remove(removingEntry),
513
+ children: t("runtime.removeAction")
514
+ })]
515
+ }),
516
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
517
+ className: dsh_mnemon_client.memoryPageStyles.bodyDeleteConfirm,
518
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtime.removeWarning") }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
519
+ className: dsh_mnemon_client.memoryPageStyles.bodyDeleteSummary,
520
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
521
+ className: dsh_mnemon_client.memoryPageStyles.bodyDeleteContent,
522
+ children: removingEntry.content
523
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`runtime.importance.${removingEntry.importance}`) })]
524
+ })]
525
+ })
526
+ })
527
+ ]
528
+ });
529
+ }
530
+ //#endregion
531
+ //#region src/client/ui.tsx
532
+ function runtimePageClient(management) {
533
+ const client = (0, dsh_mnemon_client.createMemorySourcePageClient)(management);
534
+ return {
535
+ runtimeMemory: () => client.read("snapshot"),
536
+ mutateRuntimeMemory: (input) => client.canAssist("mutate") ? client.assist("mutate", {
537
+ ...input,
538
+ ...input.old_text === void 0 ? {} : { oldText: input.old_text }
539
+ }, true) : client.mutate("mutate", { ...input }, true)
540
+ };
541
+ }
542
+ function RuntimeSourceView(props) {
543
+ const client = (0, react.useMemo)(() => props.management === void 0 ? void 0 : runtimePageClient(props.management), [props.management]);
544
+ const [revision, setRevision] = (0, react.useState)(0);
545
+ if (client === void 0) return null;
546
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimePage, {
547
+ client,
548
+ revision,
549
+ writeEnabled: props.writable === true,
550
+ onMutate: () => {
551
+ setRevision((value) => value + 1);
552
+ props.onRefresh?.();
553
+ }
554
+ });
555
+ }
556
+ function RuntimeSourcePage(props) {
557
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.MemorySourcePageFrame, {
558
+ locale: props.locale,
559
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RuntimeSourceView, { ...props }, props.sourceInstanceKey)
560
+ });
561
+ }
562
+ function installRuntimeMemoryUI(ctx, t = dsh_mnemon_client.translateEn) {
563
+ return (0, dsh_mnemon_client.installMemorySourceUI)(ctx, {
564
+ sourceTypeId: "runtime",
565
+ pages: [{
566
+ id: "entries",
567
+ order: 100,
568
+ navigation: {
569
+ group: "storage",
570
+ glyph: "◫"
571
+ },
572
+ label: () => t("nav.runtime"),
573
+ component: RuntimeSourcePage
574
+ }]
575
+ });
576
+ }
577
+ const inject = ["slots", "locale"];
578
+ function apply(ctx) {
579
+ installRuntimeMemoryUI(ctx, ctx.locale?.bind("mnemon") ?? dsh_mnemon_client.translateEn);
580
+ }
581
+ //#endregion
582
+ exports.RuntimePage = RuntimePage;
583
+ exports.RuntimeSourcePage = RuntimeSourcePage;
584
+ exports.apply = apply;
585
+ exports.inject = inject;
586
+ exports.installRuntimeMemoryUI = installRuntimeMemoryUI;
587
+ exports.runtimePageClient = runtimePageClient;
588
+ return module.exports;
589
+ }
590
+ });
@@ -0,0 +1,14 @@
1
+ //#region src/defaults.ts
2
+ const DEFAULT_RUNTIME_MEMORY_LIMIT_BYTES = 10240;
3
+ const DEFAULT_RUNTIME_USER_LIMIT_BYTES = 4096;
4
+ const MAX_RUNTIME_MEMORY_LIMIT_BYTES = 1048576;
5
+ //#endregion
6
+ //#region src/contracts.ts
7
+ const RUNTIME_MEMORY_VERSION = 1;
8
+ const RUNTIME_ENTRY_DELIMITER = "\n§\n";
9
+ const RUNTIME_MEMORY_LIMITS = {
10
+ memory: DEFAULT_RUNTIME_MEMORY_LIMIT_BYTES,
11
+ user: DEFAULT_RUNTIME_USER_LIMIT_BYTES
12
+ };
13
+ //#endregion
14
+ export { DEFAULT_RUNTIME_USER_LIMIT_BYTES as a, DEFAULT_RUNTIME_MEMORY_LIMIT_BYTES as i, RUNTIME_MEMORY_LIMITS as n, MAX_RUNTIME_MEMORY_LIMIT_BYTES as o, RUNTIME_MEMORY_VERSION as r, RUNTIME_ENTRY_DELIMITER as t };