dsh-mnemon-source-runtime 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,34 +1,28 @@
1
1
  # dsh-mnemon-source-runtime
2
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.
3
+ Owns USER / MEMORY records, exact revisions, branch filtering, bounded projection and local capacity maintenance.
4
+
5
+ ## Use
6
+
7
+ The `dsh-mnemon` Starter installs and mounts this Source by default. The package alone does not activate an instance or select a Strategy.
8
+
9
+ For a custom Profile, mount an explicit Entry after the Host's `ctx.mnemonMemory` service is available:
10
+
11
+ ```yaml
12
+ - id: personal-runtime
13
+ name: dsh-mnemon-source-runtime
14
+ config:
15
+ dataDir: /absolute/path/to/personal-memory
16
+ ```
17
+
18
+ Choose an existing data authority deliberately. Without `dataDir`, each stable Source instance uses an isolated directory under `~/.mnemon/sources/`; the default Starter supplies the existing product paths. Replacing the default Source or adding a second instance requires an explicit selection Strategy, not a second implicit default role.
19
+
20
+ Disabling participation does not delete stored entries. Source data remains separate from the current turn's projection and access grants.
21
+
22
+ ## Source-owned UI and tests
23
+
24
+ The optional `./client` entry is an ordinary DSH Client plugin. This package owns its pages and `presentation/` resources and uses `dsh-mnemon/client` for the shared frame and scoped management client. It never receives a Host Context, credentials or another Source's controller.
25
+
26
+ From a source checkout, install the declared dependencies and run `pnpm verify` to check Host behavior, Source-backed page interactions and Host/browser artifacts. Unreleased SDK work consumes a packed `dsh-mnemon` peer, not repository aliases or copied root tests.
27
+
28
+ [Plugin development](https://github.com/omdsh-dev/dsh-mnemon/blob/8466e3560a3b9de4e9f4b7302cbf005c84e8e69f/docs/en/development/extensions.md) · [中文指南](https://github.com/omdsh-dev/dsh-mnemon/blob/8466e3560a3b9de4e9f4b7302cbf005c84e8e69f/docs/zh-CN/development/extensions.md)
package/lib/client.js CHANGED
@@ -7,9 +7,179 @@ window.__ModuleLoader__.load({
7
7
  let react = require("react");
8
8
  let dsh_mnemon_client = require("dsh-mnemon/client");
9
9
  let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region presentation/locales.json
11
+ var zh = {
12
+ "nav.runtime": "运行时",
13
+ "runtime.title": "运行时记忆",
14
+ "runtime.description": "管理每轮随上下文加载的紧凑热记忆。结构化数据由统一控制层维护,并自动投影为 USER.md 与 MEMORY.md。",
15
+ "runtime.total": "{count} 条热记忆",
16
+ "runtime.entriesAria": "运行时记忆列表",
17
+ "runtime.scopeAria": "运行时记忆范围",
18
+ "runtime.scopeAll": "全部",
19
+ "runtime.filterAria": "筛选运行时记忆",
20
+ "runtime.filterPlaceholder": "按内容筛选…",
21
+ "runtime.noMatch": "没有符合当前范围与查询条件的热记忆。",
22
+ "runtime.refresh": "刷新",
23
+ "runtime.hotContext": "每轮上下文",
24
+ "runtime.addTitle": "添加热记忆",
25
+ "runtime.addDescription": "稳定但仍需频繁使用的信息优先留在这里,长期归档由 Mnemon 记忆体承接。",
26
+ "runtime.content": "运行时记忆内容",
27
+ "runtime.placeholder": "输入一条简洁、独立、未来仍然有用的信息…",
28
+ "runtime.target": "分类",
29
+ "runtime.importance": "重要性",
30
+ "runtime.saving": "处理中…",
31
+ "runtime.addButton": "添加记忆",
32
+ "runtime.addAction": "添加",
33
+ "runtime.target.user": "用户画像",
34
+ "runtime.target.user.description": "身份、角色、习惯、表达偏好与明确的协作要求;容量整理始终留在本地,不进入记忆体。",
35
+ "runtime.target.memory": "工作记忆",
36
+ "runtime.target.memory.description": "项目、环境、决策、约定、工具特性与可复用经验;容量达到上限时按主题归档到一个或多个记忆体。",
37
+ "runtime.importance.critical": "关键",
38
+ "runtime.importance.normal": "普通",
39
+ "runtime.importance.low": "低",
40
+ "runtime.branches": "适用分支",
41
+ "runtime.branchesPlaceholder": "如 main、dev(逗号分隔;留空=全部分支可见)",
42
+ "runtime.branchesHint": "留空表示清除分支限制(全部分支可见)",
43
+ "runtime.branchBadge": "分支限定",
44
+ "runtime.editContent": "编辑运行时记忆",
45
+ "runtime.editAction": "编辑",
46
+ "runtime.saveEdit": "保存修改",
47
+ "runtime.removeAction": "移除",
48
+ "runtime.removeTitle": "移除运行时记忆?",
49
+ "runtime.removeWarning": "移除后,这条内容将不再随每轮上下文加载。该操作无法撤销。",
50
+ "runtime.result.add": "已添加到{target} · 当前 {count} 条",
51
+ "runtime.result.replace": "已更新{target} · 当前 {count} 条",
52
+ "runtime.result.remove": "已从{target}移除 · 当前 {count} 条",
53
+ "runtime.result.maintenance": "容量整理完成:已先归档到记忆体 {spaces},再更新{target} · 当前 {count} 条",
54
+ "runtime.result.localCompaction": "本地画像整理完成:未写入记忆体,已更新{target} · 当前 {count} 条",
55
+ "runtime.readOnly": "当前部署为只读模式;热记忆仍会进入上下文,但不能在此修改。",
56
+ "runtime.footnote": "memories.json 是唯一事实源;两个 Markdown 文件由控制层生成,不应直接编辑。"
57
+ };
58
+ var en = {
59
+ "nav.runtime": "Runtime",
60
+ "runtime.title": "Runtime Memory",
61
+ "runtime.description": "Manage compact hot memory loaded into every turn. A single control plane owns structured data and projects USER.md and MEMORY.md.",
62
+ "runtime.total": "{count} hot memories",
63
+ "runtime.entriesAria": "Runtime memory list",
64
+ "runtime.scopeAria": "Runtime memory scope",
65
+ "runtime.scopeAll": "All",
66
+ "runtime.filterAria": "Filter runtime memory",
67
+ "runtime.filterPlaceholder": "Filter by content…",
68
+ "runtime.noMatch": "No hot memory matches the current scope and query.",
69
+ "runtime.refresh": "Refresh",
70
+ "runtime.hotContext": "Every-turn context",
71
+ "runtime.addTitle": "Add hot memory",
72
+ "runtime.addDescription": "Keep stable, frequently useful information here; Mnemon Memory Spaces remain the durable archive.",
73
+ "runtime.content": "Runtime memory content",
74
+ "runtime.placeholder": "Enter one compact, self-contained fact that will remain useful…",
75
+ "runtime.target": "Target",
76
+ "runtime.importance": "Importance",
77
+ "runtime.saving": "Working…",
78
+ "runtime.addButton": "Add memory",
79
+ "runtime.addAction": "Add",
80
+ "runtime.target.user": "User Profile",
81
+ "runtime.target.user.description": "Identity, role, habits, communication preferences, and explicit collaboration requirements. Capacity maintenance stays local and never enters a Memory Space.",
82
+ "runtime.target.memory": "Working Memory",
83
+ "runtime.target.memory.description": "Projects, environment, decisions, conventions, tool behavior, and reusable lessons. At capacity, entries are routed into one or more topic-specific Memory Spaces.",
84
+ "runtime.importance.critical": "Critical",
85
+ "runtime.importance.normal": "Normal",
86
+ "runtime.importance.low": "Low",
87
+ "runtime.branches": "Branches",
88
+ "runtime.branchesPlaceholder": "e.g. main, dev (comma-separated; empty = visible on all branches)",
89
+ "runtime.branchesHint": "Empty input clears the branch restriction (visible on all branches)",
90
+ "runtime.branchBadge": "Branch-scoped",
91
+ "runtime.editContent": "Edit runtime memory",
92
+ "runtime.editAction": "Edit",
93
+ "runtime.saveEdit": "Save change",
94
+ "runtime.removeAction": "Remove",
95
+ "runtime.removeTitle": "Remove runtime memory?",
96
+ "runtime.removeWarning": "After removal, this content will no longer load with every turn. This action cannot be undone.",
97
+ "runtime.result.add": "Added to {target} · {count} entries",
98
+ "runtime.result.replace": "Updated {target} · {count} entries",
99
+ "runtime.result.remove": "Removed from {target} · {count} entries",
100
+ "runtime.result.maintenance": "Capacity maintenance complete: archived to {spaces}, then updated {target} · {count} entries",
101
+ "runtime.result.localCompaction": "Local profile compaction complete: no Memory Space write; updated {target} · {count} entries",
102
+ "runtime.readOnly": "This deployment is read only. Hot memory still enters context but cannot be changed here.",
103
+ "runtime.footnote": "memories.json is the only source of truth. The control plane generates both Markdown files; do not edit them directly."
104
+ };
105
+ //#endregion
106
+ //#region \0source-css:/home/runner/work/dsh-mnemon/dsh-mnemon/plugins/dsh-mnemon-source-runtime/presentation/page.module.css.mjs
107
+ const css$2 = ".IIa07q_runtimeComposer{border:1px solid var(--mn-line);background:var(--mn-layer-1);background:linear-gradient(135deg, color-mix(in srgb, var(--mn-accent) 5%, var(--mn-layer-1)), var(--mn-layer-1) 55%);border-radius:12px;margin-bottom:13px;padding:15px}.IIa07q_runtimeComposerHeading{justify-content:space-between;align-items:flex-start;gap:18px;margin-bottom:11px;display:flex}.IIa07q_runtimeComposerHeading h3{margin:0 0 2px;font-size:14px}.IIa07q_runtimeComposerHeading p{color:var(--mn-muted);margin:0;font-size:10px}.IIa07q_runtimeComposerHeading>span{color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 9%, transparent);font:650 9px var(--mn-code);border-radius:999px;flex:none;padding:4px 8px}.IIa07q_runtimeComposer>textarea,.IIa07q_runtimeEntry textarea{resize:vertical;border:1px solid var(--mn-line);width:100%;color:var(--mn-text);background:var(--mn-input);border-radius:9px;outline:0;padding:10px 11px;line-height:1.6}.IIa07q_runtimeComposer>textarea:focus,.IIa07q_runtimeEntry textarea:focus{border-color:var(--mn-accent)}.IIa07q_runtimeComposerActions{justify-content:flex-end;align-items:flex-end;gap:9px;margin-top:10px;display:flex}.IIa07q_runtimeComposerActions label{color:var(--mn-faint);gap:4px;font-size:9px;display:grid}.IIa07q_runtimeComposerActions select,.IIa07q_runtimeEntry select{border:1px solid var(--mn-line);background:var(--mn-input);border-radius:8px;outline:0;min-width:135px;height:34px;padding:0 8px}.IIa07q_runtimeReadOnly{border:1px solid color-mix(in srgb, var(--mn-success) 28%, var(--mn-line));color:var(--mn-muted);background:color-mix(in srgb, var(--mn-success) 6%, var(--mn-layer-1));border-color:var(--mn-line);background:var(--mn-layer-1);border-radius:9px;margin-bottom:13px;padding:9px 12px;font-size:11px}.IIa07q_runtimeSummaryGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin-bottom:10px;display:grid}.IIa07q_runtimeSummaryCard{border:1px solid var(--mn-line);background:var(--mn-layer-1);border-radius:11px;min-width:0}.IIa07q_runtimeBrowser{border:1px solid var(--mn-line);background:var(--mn-layer-1);border-radius:11px;overflow:hidden}.IIa07q_runtimeBrowserToolbar{border-bottom:1px solid var(--mn-line);justify-content:space-between;align-items:center;gap:12px;padding:10px;display:flex}.IIa07q_runtimeScopeFilter{flex-wrap:wrap;align-items:center;gap:3px;display:flex}.IIa07q_runtimeScopeFilter button{min-height:32px;color:var(--mn-muted);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:7px;padding:0 10px}.IIa07q_runtimeScopeFilter button:hover{background:var(--mn-hover)}.IIa07q_runtimeScopeFilter button[data-active]{border-color:var(--mn-line);color:var(--mn-text);background:var(--mn-layer-2)}.IIa07q_runtimeScopeFilter b{color:var(--mn-faint);font:600 10px var(--mn-code);margin-left:4px}.IIa07q_runtimeFilterQuery{border:1px solid var(--mn-line);background:var(--mn-input);border-radius:8px;align-items:center;gap:7px;width:min(320px,42%);min-width:210px;padding:0 9px;display:flex}.IIa07q_runtimeFilterQuery>span{color:var(--mn-faint)}.IIa07q_runtimeFilterQuery input{width:100%;min-width:0;height:32px;color:var(--mn-text);background:0 0;border:0;outline:0}.IIa07q_runtimeUnifiedList{background:color-mix(in srgb, var(--mn-layer-2) 30%, var(--mn-layer-1));grid-template-columns:1fr;gap:8px;padding:10px;display:grid}.IIa07q_runtimeEntryBadges{flex-wrap:wrap;align-items:center;gap:5px;display:flex}.IIa07q_runtimeEntryMeta .IIa07q_runtimeEntryTarget{color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 8%, var(--mn-layer-2));font-family:var(--mn-code)}.IIa07q_runtimeEntryMeta .IIa07q_runtimeEntryBranch{text-overflow:ellipsis;white-space:nowrap;max-width:140px;color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 8%, var(--mn-layer-2));font-family:var(--mn-code);overflow:hidden}.IIa07q_runtimeComposerBranch{color:var(--mn-faint);gap:4px;font-size:9px;display:grid}.IIa07q_runtimeComposerBranch input{border:1px solid var(--mn-line);width:100%;color:var(--mn-text);background:var(--mn-input);border-radius:8px;outline:0;padding:7px 9px;font-size:12px}.IIa07q_runtimeComposerBranch input:focus{border-color:var(--mn-accent)}.IIa07q_bodyEditBranch{color:var(--mn-faint);gap:4px;font-size:9px;display:grid}.IIa07q_bodyEditBranch input{border:1px solid var(--mn-line);width:100%;color:var(--mn-text);background:var(--mn-input);border-radius:8px;outline:0;padding:7px 9px;font-size:12px}.IIa07q_bodyEditBranch input:focus{border-color:var(--mn-accent)}.IIa07q_bodyEditBranch small{color:var(--mn-faint);font-size:9px}.IIa07q_runtimeTargetHeader{justify-content:space-between;align-items:center;gap:14px;padding:14px 15px 9px;display:flex}.IIa07q_runtimeTargetHeader>div{gap:1px;display:grid}.IIa07q_runtimeTargetHeader span{color:var(--mn-faint);font:650 9px var(--mn-code);letter-spacing:.08em}.IIa07q_runtimeTargetHeader h3{margin:0;font-size:15px}.IIa07q_runtimeTargetHeader>strong{min-width:28px;height:28px;color:var(--mn-accent);background:color-mix(in srgb, var(--mn-accent) 9%, transparent);font:650 11px var(--mn-code);border-radius:8px;place-items:center;display:grid}.IIa07q_capacityLine{align-items:center;gap:9px;padding:0 15px;display:flex}.IIa07q_capacityLine>div{background:var(--mn-layer-2);border-radius:999px;flex:1;height:4px;overflow:hidden}.IIa07q_capacityLine i{border-radius:inherit;background:var(--mn-success);height:100%;transition:width .25s;display:block}.IIa07q_capacityLine>span{min-width:88px;color:var(--mn-faint);font:9px var(--mn-code);text-align:right}.IIa07q_runtimeTargetDescription{min-height:31px;color:var(--mn-muted);margin:8px 15px 12px;font-size:10px}.IIa07q_runtimeEntry{--mn-provider-color:var(--mn-accent);border:1px solid var(--mn-line);background:linear-gradient(90deg, color-mix(in srgb, var(--mn-provider-color) 5%, var(--mn-layer-1)), var(--mn-layer-1) 34%);box-shadow:inset 3px 0 0 color-mix(in srgb, var(--mn-provider-color) 68%, transparent);border-radius:8px;padding:11px 12px 10px;position:relative}.IIa07q_runtimeEntry[data-importance=critical]{--mn-provider-color:var(--mn-priority)}.IIa07q_runtimeEntry[data-importance=low]{--mn-provider-color:var(--mn-faint)}.IIa07q_runtimeEntryMeta{justify-content:space-between;align-items:center;gap:12px;display:flex}.IIa07q_runtimeEntryMeta>span,.IIa07q_runtimeEntryBadges>span{color:var(--mn-muted);background:var(--mn-layer-2);border-radius:999px;padding:2px 6px;font-size:9px}.IIa07q_runtimeEntry[data-importance=critical] .IIa07q_runtimeEntryMeta>span,.IIa07q_runtimeEntry[data-importance=critical] .IIa07q_runtimeEntryBadges>span:not(.IIa07q_runtimeEntryTarget){color:var(--mn-priority);background:color-mix(in srgb, var(--mn-priority) 9%, transparent)}.IIa07q_runtimeEntryMeta time{color:var(--mn-faint);font:8px var(--mn-code);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.IIa07q_runtimeEntry>p{white-space:pre-wrap;overflow-wrap:anywhere;min-height:42px;margin:9px 0;font-size:12px;line-height:1.6}.IIa07q_runtimeEntry>select{margin-top:7px}.IIa07q_runtimeEntry footer{border-top:1px solid var(--mn-line);justify-content:flex-end;align-items:center;gap:4px;min-height:30px;margin-top:7px;padding-top:7px;display:flex}.IIa07q_runtimeEntry footer>span{color:var(--mn-danger);margin-right:auto;font-size:10px}.IIa07q_runtimeEmpty{min-height:126px;color:var(--mn-faint);text-align:center;align-content:center;place-items:center;gap:5px;display:grid}.IIa07q_runtimeEmpty>span{font:24px var(--mn-code);opacity:.65}.IIa07q_runtimeEmpty p{margin:0;font-size:10px}@media (width<=1000px){.IIa07q_runtimeSummaryGrid{grid-template-columns:1fr}}@media (width<=760px){.IIa07q_runtimeComposerHeading,.IIa07q_runtimeComposerActions{flex-direction:column;align-items:stretch}.IIa07q_runtimeComposerActions select,.IIa07q_runtimeComposerActions button{width:100%}.IIa07q_runtimeBrowserToolbar{flex-direction:column;align-items:stretch}.IIa07q_runtimeFilterQuery{width:100%;min-width:0}}";
108
+ const id$1 = "dsh-mnemon-source-runtime/presentation/page.module.css";
109
+ if (typeof document !== "undefined") {
110
+ let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(id$1) + "]");
111
+ if (!tag) {
112
+ tag = document.createElement("style");
113
+ tag.dataset.pluginCss = id$1;
114
+ document.head.appendChild(tag);
115
+ }
116
+ if (tag.textContent !== css$2) tag.textContent = css$2;
117
+ }
118
+ var page_module_css_default = {
119
+ "bodyEditBranch": "IIa07q_bodyEditBranch",
120
+ "capacityLine": "IIa07q_capacityLine",
121
+ "runtimeBrowser": "IIa07q_runtimeBrowser",
122
+ "runtimeBrowserToolbar": "IIa07q_runtimeBrowserToolbar",
123
+ "runtimeComposer": "IIa07q_runtimeComposer",
124
+ "runtimeComposerActions": "IIa07q_runtimeComposerActions",
125
+ "runtimeComposerBranch": "IIa07q_runtimeComposerBranch",
126
+ "runtimeComposerHeading": "IIa07q_runtimeComposerHeading",
127
+ "runtimeEmpty": "IIa07q_runtimeEmpty",
128
+ "runtimeEntry": "IIa07q_runtimeEntry",
129
+ "runtimeEntryBadges": "IIa07q_runtimeEntryBadges",
130
+ "runtimeEntryBranch": "IIa07q_runtimeEntryBranch",
131
+ "runtimeEntryMeta": "IIa07q_runtimeEntryMeta",
132
+ "runtimeEntryTarget": "IIa07q_runtimeEntryTarget",
133
+ "runtimeFilterQuery": "IIa07q_runtimeFilterQuery",
134
+ "runtimeReadOnly": "IIa07q_runtimeReadOnly",
135
+ "runtimeScopeFilter": "IIa07q_runtimeScopeFilter",
136
+ "runtimeSummaryCard": "IIa07q_runtimeSummaryCard",
137
+ "runtimeSummaryGrid": "IIa07q_runtimeSummaryGrid",
138
+ "runtimeTargetDescription": "IIa07q_runtimeTargetDescription",
139
+ "runtimeTargetHeader": "IIa07q_runtimeTargetHeader",
140
+ "runtimeUnifiedList": "IIa07q_runtimeUnifiedList"
141
+ };
142
+ //#endregion
143
+ //#region \0source-css:/home/runner/work/dsh-mnemon/dsh-mnemon/plugins/dsh-mnemon-source-runtime/presentation/sidebar.module.css.mjs
144
+ const css$1 = "._Bh55G_shell ._Bh55G_modal form[class*=runtimeComposer]{background:0 0;border:0;border-radius:0;margin:0;padding:0}._Bh55G_shell ._Bh55G_modal form[class*=runtimeComposer]>[class*=runtimeComposerHeading]{display:none}._Bh55G_shell [class*=runtimeComposerActions] label{color:var(--dsw-alias-label-secondary);gap:5px;font-size:12px;font-weight:500}._Bh55G_shell [class*=runtimeComposer]>textarea,._Bh55G_shell [class*=runtimeComposerActions] select,._Bh55G_shell [class*=runtimeEntry] select{border:1px solid var(--dsw-alias-border-l2);min-height:34px;color:var(--dsw-alias-label-primary);background:var(--dsw-specific-input-major);border-radius:8px;padding:7px 10px;font-size:13px;font-weight:400}._Bh55G_shell [class*=runtimeTargetDescription]{font-size:12px}._Bh55G_shell [class*=runtimeEntryMeta]>span,._Bh55G_shell [class*=runtimeEntryBadges]>span,._Bh55G_shell [class*=runtimeEntryMeta] time{font-size:11px}._Bh55G_shell [class*=runtimeEntry]>p{font-size:13px}._Bh55G_shell [class*=runtimeEntryBadges]>span{border:1px solid var(--dsw-alias-border-l1);min-height:22px;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-1);border-radius:999px;align-items:center;padding:0 8px;font-size:11px;font-weight:400;line-height:20px;display:inline-flex}._Bh55G_shell [class*=runtimeEntryBadges]>[class*=runtimeEntryTarget]{border-color:color-mix(in srgb, var(--dsw-alias-state-business-primary) 30%, var(--dsw-alias-border-l1));color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-layer-1));font-family:var(--dsw-font-family);font-weight:500}._Bh55G_shell [class*=runtimeEntry][data-importance=critical] [class*=runtimeEntryBadges]>span:last-child{border-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 24%, var(--dsw-alias-border-l1));color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb, var(--dsw-alias-state-error-primary) 6%, var(--dsw-alias-bg-layer-1))}._Bh55G_shell [class*=runtimeEntry] footer{gap:6px}";
145
+ const id = "dsh-mnemon-source-runtime/presentation/sidebar.module.css";
146
+ if (typeof document !== "undefined") {
147
+ let tag = document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]");
148
+ if (!tag) {
149
+ tag = document.createElement("style");
150
+ tag.dataset.pluginCss = id;
151
+ document.head.appendChild(tag);
152
+ }
153
+ if (tag.textContent !== css$1) tag.textContent = css$1;
154
+ }
155
+ var sidebar_module_css_default = {
156
+ "modal": "_Bh55G_modal",
157
+ "shell": "_Bh55G_shell"
158
+ };
159
+ //#endregion
160
+ //#region src/client/presentation.ts
161
+ const css = {
162
+ ...dsh_mnemon_client.memoryPageStyles,
163
+ ...page_module_css_default
164
+ };
165
+ const sidebarCss = {
166
+ ...dsh_mnemon_client.memorySidebarStyles,
167
+ ...sidebar_module_css_default
168
+ };
169
+ function useT() {
170
+ const fallback = (0, dsh_mnemon_client.useT)();
171
+ const locale = (0, dsh_mnemon_client.useLocale)();
172
+ return (0, react.useMemo)(() => (key, params) => {
173
+ const dictionary = locale.startsWith("en") ? en : zh;
174
+ if (!Object.hasOwn(dictionary, key)) return fallback(key, params);
175
+ const text = dictionary[key];
176
+ return params === void 0 ? text : text.replace(/\{(\w+)\}/g, (match, name) => name in params ? String(params[name]) : match);
177
+ }, [locale, fallback]);
178
+ }
179
+ //#endregion
10
180
  //#region src/client/pages.tsx
11
181
  function RuntimePage(props) {
12
- const t = (0, dsh_mnemon_client.useT)();
182
+ const t = useT();
13
183
  const locale = (0, dsh_mnemon_client.useLocale)();
14
184
  const runtimeAddFormId = (0, react.useId)();
15
185
  const runtimeEditFormId = (0, react.useId)();
@@ -136,34 +306,34 @@ window.__ModuleLoader__.load({
136
306
  setSaving(false);
137
307
  }
138
308
  };
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));
309
+ const runtimeEditActionClass = (0, dsh_mnemon_client.appearanceClass)(css.ghostButton, (0, dsh_mnemon_client.appearanceClass)(sidebarCss.itemActionButton, sidebarCss.itemEditAction));
310
+ const runtimeRemoveActionClass = (0, dsh_mnemon_client.appearanceClass)(css.dangerButton, (0, dsh_mnemon_client.appearanceClass)(sidebarCss.itemActionButton, sidebarCss.itemDangerAction));
141
311
  const runtimeEntry = (entry, showTarget = false) => {
142
312
  const key = entryKey(entry);
143
313
  const isRemoving = removing === key;
144
314
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
145
- className: dsh_mnemon_client.memoryPageStyles.runtimeEntry,
315
+ className: css.runtimeEntry,
146
316
  "data-importance": entry.importance,
147
317
  "data-target": entry.target,
148
318
  children: [
149
319
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
150
- className: dsh_mnemon_client.memoryPageStyles.runtimeEntryMeta,
320
+ className: css.runtimeEntryMeta,
151
321
  children: [showTarget ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
152
- className: dsh_mnemon_client.memoryPageStyles.runtimeEntryBadges,
322
+ className: css.runtimeEntryBadges,
153
323
  children: [
154
324
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
155
- className: dsh_mnemon_client.memoryPageStyles.runtimeEntryTarget,
325
+ className: css.runtimeEntryTarget,
156
326
  children: entry.target === "user" ? "USER.md" : "MEMORY.md"
157
327
  }),
158
328
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`runtime.importance.${entry.importance}`) }),
159
329
  entry.branches !== void 0 && entry.branches.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
160
- className: dsh_mnemon_client.memoryPageStyles.runtimeEntryBranch,
330
+ className: css.runtimeEntryBranch,
161
331
  title: t("runtime.branchBadge"),
162
332
  children: entry.branches.join(", ")
163
333
  })
164
334
  ]
165
335
  }) : /* @__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,
336
+ className: css.runtimeEntryBranch,
167
337
  title: t("runtime.branchBadge"),
168
338
  children: entry.branches.join(", ")
169
339
  })] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("time", {
@@ -195,19 +365,19 @@ window.__ModuleLoader__.load({
195
365
  const view = snapshot?.targets[value];
196
366
  const percentage = view === void 0 || view.limit === 0 ? 0 : Math.min(100, Math.round(view.used / view.limit * 100));
197
367
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
198
- className: dsh_mnemon_client.memoryPageStyles.runtimeSummaryCard,
368
+ className: css.runtimeSummaryCard,
199
369
  "aria-label": t(`runtime.target.${value}`),
200
370
  children: [
201
371
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
202
- className: dsh_mnemon_client.memoryPageStyles.runtimeTargetHeader,
372
+ className: css.runtimeTargetHeader,
203
373
  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
374
  }),
205
375
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
206
- className: dsh_mnemon_client.memoryPageStyles.capacityLine,
376
+ className: css.capacityLine,
207
377
  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
378
  }),
209
379
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
210
- className: dsh_mnemon_client.memoryPageStyles.runtimeTargetDescription,
380
+ className: css.runtimeTargetDescription,
211
381
  children: t(`runtime.target.${value}.description`)
212
382
  })
213
383
  ]
@@ -222,11 +392,11 @@ window.__ModuleLoader__.load({
222
392
  };
223
393
  const composer = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
224
394
  id: runtimeAddFormId,
225
- className: dsh_mnemon_client.memoryPageStyles.runtimeComposer,
395
+ className: css.runtimeComposer,
226
396
  onSubmit: (event) => void add(event),
227
397
  children: [
228
398
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
229
- className: dsh_mnemon_client.memoryPageStyles.runtimeComposerHeading,
399
+ className: css.runtimeComposerHeading,
230
400
  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
401
  }),
232
402
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
@@ -237,7 +407,7 @@ window.__ModuleLoader__.load({
237
407
  placeholder: t("runtime.placeholder")
238
408
  }),
239
409
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
240
- className: dsh_mnemon_client.memoryPageStyles.runtimeComposerActions,
410
+ className: css.runtimeComposerActions,
241
411
  children: [
242
412
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", { children: [t("runtime.target"), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
243
413
  value: target,
@@ -269,7 +439,7 @@ window.__ModuleLoader__.load({
269
439
  ]
270
440
  })] }),
271
441
  target === "memory" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
272
- className: dsh_mnemon_client.memoryPageStyles.runtimeComposerBranch,
442
+ className: css.runtimeComposerBranch,
273
443
  children: [t("runtime.branches"), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
274
444
  value: branches,
275
445
  onChange: (event) => setBranches(event.target.value),
@@ -285,7 +455,7 @@ window.__ModuleLoader__.load({
285
455
  const removingEntry = removing === null ? void 0 : snapshot?.entries.find((entry) => entryKey(entry) === removing);
286
456
  const editForm = editingEntry === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
287
457
  id: runtimeEditFormId,
288
- className: dsh_mnemon_client.memoryPageStyles.bodyEdit,
458
+ className: css.bodyEdit,
289
459
  onSubmit: (event) => {
290
460
  event.preventDefault();
291
461
  replace(editingEntry);
@@ -317,7 +487,7 @@ window.__ModuleLoader__.load({
317
487
  ]
318
488
  })] }),
319
489
  editingEntry.target === "memory" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
320
- className: dsh_mnemon_client.memoryPageStyles.bodyEditBranch,
490
+ className: css.bodyEditBranch,
321
491
  children: [
322
492
  t("runtime.branches"),
323
493
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
@@ -332,7 +502,7 @@ window.__ModuleLoader__.load({
332
502
  ]
333
503
  });
334
504
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
335
- className: dsh_mnemon_client.memoryPageStyles.page,
505
+ className: css.page,
336
506
  children: [
337
507
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.PageHeader, {
338
508
  title: t("runtime.title"),
@@ -340,42 +510,42 @@ window.__ModuleLoader__.load({
340
510
  meta: snapshot === null ? t("common.loading") : t("runtime.total", { count: snapshot.entries.length }),
341
511
  action: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
342
512
  type: "button",
343
- className: dsh_mnemon_client.memoryPageStyles.secondaryButton,
513
+ className: css.secondaryButton,
344
514
  disabled: loading,
345
515
  onClick: () => void load(),
346
516
  children: t("runtime.refresh")
347
517
  }), props.writeEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
348
518
  type: "button",
349
- className: dsh_mnemon_client.memoryPageStyles.primaryButton,
519
+ className: css.primaryButton,
350
520
  onClick: () => setAdding(true),
351
521
  children: t("runtime.addButton")
352
522
  })] })
353
523
  }),
354
524
  error !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
355
- className: dsh_mnemon_client.memoryPageStyles.inlineError,
525
+ className: css.inlineError,
356
526
  role: "alert",
357
527
  children: error
358
528
  }),
359
529
  notice !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
360
- className: dsh_mnemon_client.memoryPageStyles.runtimeNotice,
530
+ className: css.runtimeNotice,
361
531
  role: "status",
362
532
  children: notice
363
533
  }),
364
534
  !props.writeEnabled && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
365
- className: dsh_mnemon_client.memoryPageStyles.runtimeReadOnly,
535
+ className: css.runtimeReadOnly,
366
536
  children: t("runtime.readOnly")
367
537
  }),
368
538
  /* @__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,
539
+ className: css.runtimeSummaryGrid,
370
540
  children: [targetSummary("user"), targetSummary("memory")]
371
541
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
372
- className: dsh_mnemon_client.memoryPageStyles.runtimeBrowser,
542
+ className: css.runtimeBrowser,
373
543
  "aria-label": t("runtime.entriesAria"),
374
544
  children: [
375
545
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
376
- className: dsh_mnemon_client.memoryPageStyles.runtimeBrowserToolbar,
546
+ className: css.runtimeBrowserToolbar,
377
547
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
378
- className: dsh_mnemon_client.memoryPageStyles.runtimeScopeFilter,
548
+ className: css.runtimeScopeFilter,
379
549
  role: "group",
380
550
  "aria-label": t("runtime.scopeAria"),
381
551
  children: [
@@ -411,7 +581,7 @@ window.__ModuleLoader__.load({
411
581
  })
412
582
  ]
413
583
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
414
- className: dsh_mnemon_client.memoryPageStyles.runtimeFilterQuery,
584
+ className: css.runtimeFilterQuery,
415
585
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
416
586
  "aria-hidden": "true",
417
587
  children: "⌕"
@@ -424,9 +594,9 @@ window.__ModuleLoader__.load({
424
594
  })]
425
595
  }),
426
596
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
427
- className: dsh_mnemon_client.memoryPageStyles.runtimeUnifiedList,
597
+ className: css.runtimeUnifiedList,
428
598
  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,
599
+ className: css.runtimeEmpty,
430
600
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "○" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: t("runtime.noMatch") })]
431
601
  })]
432
602
  }),
@@ -439,7 +609,7 @@ window.__ModuleLoader__.load({
439
609
  ]
440
610
  })] }),
441
611
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
442
- className: dsh_mnemon_client.memoryPageStyles.runtimeFootnote,
612
+ className: css.runtimeFootnote,
443
613
  children: t("runtime.footnote")
444
614
  }),
445
615
  adding && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(dsh_mnemon_client.SidebarModal, {
@@ -448,18 +618,18 @@ window.__ModuleLoader__.load({
448
618
  busy: saving,
449
619
  onClose: closeComposer,
450
620
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
451
- className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
621
+ className: css.modalFooterActions,
452
622
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
453
623
  type: "button",
454
624
  "data-dialog-close": true,
455
- className: dsh_mnemon_client.memoryPageStyles.ghostButton,
625
+ className: css.ghostButton,
456
626
  disabled: saving,
457
627
  onClick: closeComposer,
458
628
  children: t("common.cancel")
459
629
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
460
630
  type: "submit",
461
631
  form: runtimeAddFormId,
462
- className: dsh_mnemon_client.memoryPageStyles.primaryButton,
632
+ className: css.primaryButton,
463
633
  disabled: saving || content.trim() === "",
464
634
  children: saving ? t("runtime.saving") : t("runtime.addAction")
465
635
  })]
@@ -472,18 +642,18 @@ window.__ModuleLoader__.load({
472
642
  busy: saving,
473
643
  onClose: () => setEditing(null),
474
644
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
475
- className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
645
+ className: css.modalFooterActions,
476
646
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
477
647
  type: "button",
478
648
  "data-dialog-close": true,
479
- className: dsh_mnemon_client.memoryPageStyles.ghostButton,
649
+ className: css.ghostButton,
480
650
  disabled: saving,
481
651
  onClick: () => setEditing(null),
482
652
  children: t("common.cancel")
483
653
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
484
654
  type: "submit",
485
655
  form: runtimeEditFormId,
486
- className: dsh_mnemon_client.memoryPageStyles.primaryButton,
656
+ className: css.primaryButton,
487
657
  disabled: saving || editContent.trim() === "",
488
658
  children: t("runtime.saveEdit")
489
659
  })]
@@ -496,29 +666,29 @@ window.__ModuleLoader__.load({
496
666
  busy: saving,
497
667
  onClose: () => setRemoving(null),
498
668
  footer: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
499
- className: dsh_mnemon_client.memoryPageStyles.modalFooterActions,
669
+ className: css.modalFooterActions,
500
670
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
501
671
  type: "button",
502
672
  "data-dialog-close": true,
503
673
  "data-autofocus": true,
504
- className: dsh_mnemon_client.memoryPageStyles.ghostButton,
674
+ className: css.ghostButton,
505
675
  disabled: saving,
506
676
  onClick: () => setRemoving(null),
507
677
  children: t("common.cancel")
508
678
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
509
679
  type: "button",
510
- className: dsh_mnemon_client.memoryPageStyles.dangerSolidButton,
680
+ className: css.dangerSolidButton,
511
681
  disabled: saving,
512
682
  onClick: () => void remove(removingEntry),
513
683
  children: t("runtime.removeAction")
514
684
  })]
515
685
  }),
516
686
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
517
- className: dsh_mnemon_client.memoryPageStyles.bodyDeleteConfirm,
687
+ className: css.bodyDeleteConfirm,
518
688
  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,
689
+ className: css.bodyDeleteSummary,
520
690
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
521
- className: dsh_mnemon_client.memoryPageStyles.bodyDeleteContent,
691
+ className: css.bodyDeleteContent,
522
692
  children: removingEntry.content
523
693
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(`runtime.importance.${removingEntry.importance}`) })]
524
694
  })]
@@ -0,0 +1,6 @@
1
+ import { type MnemonKey } from 'dsh-mnemon/client';
2
+ import type labels from 'dsh-mnemon-source-runtime/presentation/locales.json';
3
+ export type SourceKey = keyof typeof labels.zh;
4
+ export declare const css: Readonly<Record<string, string>>;
5
+ export declare const sidebarCss: Readonly<Record<string, string>>;
6
+ export declare function useT(): (key: SourceKey | MnemonKey, params?: Record<string, unknown>) => string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-mnemon-source-runtime",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Self-contained runtime Source for Composable View Memory.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,11 +20,15 @@
20
20
  "./contracts": {
21
21
  "types": "./lib/contracts.d.ts",
22
22
  "default": "./lib/contracts.js"
23
- }
23
+ },
24
+ "./presentation/locales.json": "./presentation/locales.json",
25
+ "./presentation/page.module.css": "./presentation/page.module.css",
26
+ "./presentation/sidebar.module.css": "./presentation/sidebar.module.css"
24
27
  },
25
28
  "files": [
26
29
  "lib",
27
- "README.md"
30
+ "README.md",
31
+ "presentation"
28
32
  ],
29
33
  "dsh": {
30
34
  "client": {
@@ -48,7 +52,7 @@
48
52
  },
49
53
  "peerDependencies": {
50
54
  "@deepseek-ai/cordis": "^4.0.1",
51
- "dsh-mnemon": "0.5.1",
55
+ "dsh-mnemon": "^0.5.1",
52
56
  "react": "^18.2.0"
53
57
  },
54
58
  "devDependencies": {
@@ -57,13 +61,14 @@
57
61
  "@types/node": "^22.0.0",
58
62
  "@types/react": "^18.3.0",
59
63
  "@types/react-dom": "^18.3.0",
60
- "dsh-mnemon": "0.5.1",
64
+ "dsh-mnemon": "^0.5.3",
61
65
  "jsdom": "^26.0.0",
62
66
  "react": "^18.2.0",
63
67
  "react-dom": "^18.2.0",
64
68
  "tsdown": "^0.22.0",
65
69
  "typescript": "^5.9.0",
66
- "vitest": "^3.2.0"
70
+ "vitest": "^3.2.0",
71
+ "lightningcss": "^1.33.0"
67
72
  },
68
73
  "peerDependenciesMeta": {
69
74
  "react": {
@@ -0,0 +1,96 @@
1
+ {
2
+ "zh": {
3
+ "nav.runtime": "运行时",
4
+ "runtime.title": "运行时记忆",
5
+ "runtime.description": "管理每轮随上下文加载的紧凑热记忆。结构化数据由统一控制层维护,并自动投影为 USER.md 与 MEMORY.md。",
6
+ "runtime.total": "{count} 条热记忆",
7
+ "runtime.entriesAria": "运行时记忆列表",
8
+ "runtime.scopeAria": "运行时记忆范围",
9
+ "runtime.scopeAll": "全部",
10
+ "runtime.filterAria": "筛选运行时记忆",
11
+ "runtime.filterPlaceholder": "按内容筛选…",
12
+ "runtime.noMatch": "没有符合当前范围与查询条件的热记忆。",
13
+ "runtime.refresh": "刷新",
14
+ "runtime.hotContext": "每轮上下文",
15
+ "runtime.addTitle": "添加热记忆",
16
+ "runtime.addDescription": "稳定但仍需频繁使用的信息优先留在这里,长期归档由 Mnemon 记忆体承接。",
17
+ "runtime.content": "运行时记忆内容",
18
+ "runtime.placeholder": "输入一条简洁、独立、未来仍然有用的信息…",
19
+ "runtime.target": "分类",
20
+ "runtime.importance": "重要性",
21
+ "runtime.saving": "处理中…",
22
+ "runtime.addButton": "添加记忆",
23
+ "runtime.addAction": "添加",
24
+ "runtime.target.user": "用户画像",
25
+ "runtime.target.user.description": "身份、角色、习惯、表达偏好与明确的协作要求;容量整理始终留在本地,不进入记忆体。",
26
+ "runtime.target.memory": "工作记忆",
27
+ "runtime.target.memory.description": "项目、环境、决策、约定、工具特性与可复用经验;容量达到上限时按主题归档到一个或多个记忆体。",
28
+ "runtime.importance.critical": "关键",
29
+ "runtime.importance.normal": "普通",
30
+ "runtime.importance.low": "低",
31
+ "runtime.branches": "适用分支",
32
+ "runtime.branchesPlaceholder": "如 main、dev(逗号分隔;留空=全部分支可见)",
33
+ "runtime.branchesHint": "留空表示清除分支限制(全部分支可见)",
34
+ "runtime.branchBadge": "分支限定",
35
+ "runtime.editContent": "编辑运行时记忆",
36
+ "runtime.editAction": "编辑",
37
+ "runtime.saveEdit": "保存修改",
38
+ "runtime.removeAction": "移除",
39
+ "runtime.removeTitle": "移除运行时记忆?",
40
+ "runtime.removeWarning": "移除后,这条内容将不再随每轮上下文加载。该操作无法撤销。",
41
+ "runtime.result.add": "已添加到{target} · 当前 {count} 条",
42
+ "runtime.result.replace": "已更新{target} · 当前 {count} 条",
43
+ "runtime.result.remove": "已从{target}移除 · 当前 {count} 条",
44
+ "runtime.result.maintenance": "容量整理完成:已先归档到记忆体 {spaces},再更新{target} · 当前 {count} 条",
45
+ "runtime.result.localCompaction": "本地画像整理完成:未写入记忆体,已更新{target} · 当前 {count} 条",
46
+ "runtime.readOnly": "当前部署为只读模式;热记忆仍会进入上下文,但不能在此修改。",
47
+ "runtime.footnote": "memories.json 是唯一事实源;两个 Markdown 文件由控制层生成,不应直接编辑。"
48
+ },
49
+ "en": {
50
+ "nav.runtime": "Runtime",
51
+ "runtime.title": "Runtime Memory",
52
+ "runtime.description": "Manage compact hot memory loaded into every turn. A single control plane owns structured data and projects USER.md and MEMORY.md.",
53
+ "runtime.total": "{count} hot memories",
54
+ "runtime.entriesAria": "Runtime memory list",
55
+ "runtime.scopeAria": "Runtime memory scope",
56
+ "runtime.scopeAll": "All",
57
+ "runtime.filterAria": "Filter runtime memory",
58
+ "runtime.filterPlaceholder": "Filter by content…",
59
+ "runtime.noMatch": "No hot memory matches the current scope and query.",
60
+ "runtime.refresh": "Refresh",
61
+ "runtime.hotContext": "Every-turn context",
62
+ "runtime.addTitle": "Add hot memory",
63
+ "runtime.addDescription": "Keep stable, frequently useful information here; Mnemon Memory Spaces remain the durable archive.",
64
+ "runtime.content": "Runtime memory content",
65
+ "runtime.placeholder": "Enter one compact, self-contained fact that will remain useful…",
66
+ "runtime.target": "Target",
67
+ "runtime.importance": "Importance",
68
+ "runtime.saving": "Working…",
69
+ "runtime.addButton": "Add memory",
70
+ "runtime.addAction": "Add",
71
+ "runtime.target.user": "User Profile",
72
+ "runtime.target.user.description": "Identity, role, habits, communication preferences, and explicit collaboration requirements. Capacity maintenance stays local and never enters a Memory Space.",
73
+ "runtime.target.memory": "Working Memory",
74
+ "runtime.target.memory.description": "Projects, environment, decisions, conventions, tool behavior, and reusable lessons. At capacity, entries are routed into one or more topic-specific Memory Spaces.",
75
+ "runtime.importance.critical": "Critical",
76
+ "runtime.importance.normal": "Normal",
77
+ "runtime.importance.low": "Low",
78
+ "runtime.branches": "Branches",
79
+ "runtime.branchesPlaceholder": "e.g. main, dev (comma-separated; empty = visible on all branches)",
80
+ "runtime.branchesHint": "Empty input clears the branch restriction (visible on all branches)",
81
+ "runtime.branchBadge": "Branch-scoped",
82
+ "runtime.editContent": "Edit runtime memory",
83
+ "runtime.editAction": "Edit",
84
+ "runtime.saveEdit": "Save change",
85
+ "runtime.removeAction": "Remove",
86
+ "runtime.removeTitle": "Remove runtime memory?",
87
+ "runtime.removeWarning": "After removal, this content will no longer load with every turn. This action cannot be undone.",
88
+ "runtime.result.add": "Added to {target} · {count} entries",
89
+ "runtime.result.replace": "Updated {target} · {count} entries",
90
+ "runtime.result.remove": "Removed from {target} · {count} entries",
91
+ "runtime.result.maintenance": "Capacity maintenance complete: archived to {spaces}, then updated {target} · {count} entries",
92
+ "runtime.result.localCompaction": "Local profile compaction complete: no Memory Space write; updated {target} · {count} entries",
93
+ "runtime.readOnly": "This deployment is read only. Hot memory still enters context but cannot be changed here.",
94
+ "runtime.footnote": "memories.json is the only source of truth. The control plane generates both Markdown files; do not edit them directly."
95
+ }
96
+ }
@@ -0,0 +1,78 @@
1
+ .runtimeComposer { border: 1px solid var(--mn-line); border-radius: 12px; background: var(--mn-layer-1); }
2
+ .runtimeComposer { margin-bottom: 13px; padding: 15px; background: linear-gradient(135deg, color-mix(in srgb, var(--mn-accent) 5%, var(--mn-layer-1)), var(--mn-layer-1) 55%); }
3
+ .runtimeComposerHeading { display: flex; align-items: flex-start; justify-content: space-between; gap: 18px; margin-bottom: 11px; }
4
+ .runtimeComposerHeading h3 { margin: 0 0 2px; font-size: 14px; }
5
+ .runtimeComposerHeading p { margin: 0; color: var(--mn-muted); font-size: 10px; }
6
+ .runtimeComposerHeading > span { flex: 0 0 auto; padding: 4px 8px; border-radius: 999px; color: var(--mn-accent); background: color-mix(in srgb, var(--mn-accent) 9%, transparent); font: 650 9px var(--mn-code); }
7
+ .runtimeComposer > textarea,
8
+ .runtimeEntry textarea { width: 100%; resize: vertical; border: 1px solid var(--mn-line); border-radius: 9px; outline: 0; padding: 10px 11px; color: var(--mn-text); background: var(--mn-input); line-height: 1.6; }
9
+ .runtimeComposer > textarea:focus,
10
+ .runtimeEntry textarea:focus { border-color: var(--mn-accent); }
11
+ .runtimeComposerActions { display: flex; align-items: flex-end; justify-content: flex-end; gap: 9px; margin-top: 10px; }
12
+ .runtimeComposerActions label { display: grid; gap: 4px; color: var(--mn-faint); font-size: 9px; }
13
+ .runtimeComposerActions select,
14
+ .runtimeEntry select { min-width: 135px; height: 34px; border: 1px solid var(--mn-line); border-radius: 8px; outline: 0; padding: 0 8px; background: var(--mn-input); }
15
+ .runtimeReadOnly { margin-bottom: 13px; padding: 9px 12px; border: 1px solid color-mix(in srgb, var(--mn-success) 28%, var(--mn-line)); border-radius: 9px; color: var(--mn-success); background: color-mix(in srgb, var(--mn-success) 6%, var(--mn-layer-1)); font-size: 11px; }
16
+ .runtimeReadOnly { color: var(--mn-muted); border-color: var(--mn-line); background: var(--mn-layer-1); }
17
+ .runtimeSummaryGrid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 10px; }
18
+ .runtimeSummaryCard { min-width: 0; border: 1px solid var(--mn-line); border-radius: 11px; background: var(--mn-layer-1); }
19
+ .runtimeBrowser { overflow: hidden; border: 1px solid var(--mn-line); border-radius: 11px; background: var(--mn-layer-1); }
20
+ .runtimeBrowserToolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px; border-bottom: 1px solid var(--mn-line); }
21
+ .runtimeScopeFilter { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; }
22
+ .runtimeScopeFilter button { min-height: 32px; border: 1px solid transparent; border-radius: 7px; padding: 0 10px; color: var(--mn-muted); background: transparent; cursor: pointer; }
23
+ .runtimeScopeFilter button:hover { background: var(--mn-hover); }
24
+ .runtimeScopeFilter button[data-active] { border-color: var(--mn-line); color: var(--mn-text); background: var(--mn-layer-2); }
25
+ .runtimeScopeFilter b { margin-left: 4px; color: var(--mn-faint); font: 600 10px var(--mn-code); }
26
+ .runtimeFilterQuery { display: flex; width: min(320px, 42%); min-width: 210px; align-items: center; gap: 7px; border: 1px solid var(--mn-line); border-radius: 8px; padding: 0 9px; background: var(--mn-input); }
27
+ .runtimeFilterQuery > span { color: var(--mn-faint); }
28
+ .runtimeFilterQuery input { width: 100%; min-width: 0; height: 32px; border: 0; outline: 0; color: var(--mn-text); background: transparent; }
29
+ .runtimeUnifiedList { display: grid; grid-template-columns: 1fr; gap: 8px; padding: 10px; background: color-mix(in srgb, var(--mn-layer-2) 30%, var(--mn-layer-1)); }
30
+ .runtimeEntryBadges { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
31
+ .runtimeEntryMeta .runtimeEntryTarget { color: var(--mn-accent); background: color-mix(in srgb, var(--mn-accent) 8%, var(--mn-layer-2)); font-family: var(--mn-code); }
32
+ .runtimeEntryMeta .runtimeEntryBranch { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--mn-accent); background: color-mix(in srgb, var(--mn-accent) 8%, var(--mn-layer-2)); font-family: var(--mn-code); }
33
+ .runtimeComposerBranch { display: grid; gap: 4px; color: var(--mn-faint); font-size: 9px; }
34
+ .runtimeComposerBranch input { width: 100%; border: 1px solid var(--mn-line); border-radius: 8px; outline: 0; padding: 7px 9px; color: var(--mn-text); background: var(--mn-input); font-size: 12px; }
35
+ .runtimeComposerBranch input:focus { border-color: var(--mn-accent); }
36
+ .bodyEditBranch { display: grid; gap: 4px; color: var(--mn-faint); font-size: 9px; }
37
+ .bodyEditBranch input { width: 100%; border: 1px solid var(--mn-line); border-radius: 8px; outline: 0; padding: 7px 9px; color: var(--mn-text); background: var(--mn-input); font-size: 12px; }
38
+ .bodyEditBranch input:focus { border-color: var(--mn-accent); }
39
+ .bodyEditBranch small { color: var(--mn-faint); font-size: 9px; }
40
+ .runtimeTargetHeader { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 15px 9px; }
41
+ .runtimeTargetHeader > div { display: grid; gap: 1px; }
42
+ .runtimeTargetHeader span { color: var(--mn-faint); font: 650 9px var(--mn-code); letter-spacing: .08em; }
43
+ .runtimeTargetHeader h3 { margin: 0; font-size: 15px; }
44
+ .runtimeTargetHeader > strong { display: grid; min-width: 28px; height: 28px; place-items: center; border-radius: 8px; color: var(--mn-accent); background: color-mix(in srgb, var(--mn-accent) 9%, transparent); font: 650 11px var(--mn-code); }
45
+ .capacityLine { display: flex; align-items: center; gap: 9px; padding: 0 15px; }
46
+ .capacityLine > div { height: 4px; flex: 1; overflow: hidden; border-radius: 999px; background: var(--mn-layer-2); }
47
+ .capacityLine i { display: block; height: 100%; border-radius: inherit; background: var(--mn-success); transition: width .25s ease; }
48
+ .capacityLine > span { min-width: 88px; color: var(--mn-faint); font: 9px var(--mn-code); text-align: right; }
49
+ .runtimeTargetDescription { min-height: 31px; margin: 8px 15px 12px; color: var(--mn-muted); font-size: 10px; }
50
+ .runtimeEntry { --mn-provider-color: var(--mn-accent); position: relative; padding: 11px 12px 10px; border: 1px solid var(--mn-line); border-radius: 8px; background: linear-gradient(90deg, color-mix(in srgb, var(--mn-provider-color) 5%, var(--mn-layer-1)), var(--mn-layer-1) 34%); box-shadow: inset 3px 0 0 color-mix(in srgb, var(--mn-provider-color) 68%, transparent); }
51
+ .runtimeEntry[data-importance="critical"] { --mn-provider-color: var(--mn-priority); }
52
+ .runtimeEntry[data-importance="low"] { --mn-provider-color: var(--mn-faint); }
53
+ .runtimeEntryMeta { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
54
+ .runtimeEntryMeta > span,
55
+ .runtimeEntryBadges > span { padding: 2px 6px; border-radius: 999px; color: var(--mn-muted); background: var(--mn-layer-2); font-size: 9px; }
56
+ .runtimeEntry[data-importance="critical"] .runtimeEntryMeta > span,
57
+ .runtimeEntry[data-importance="critical"] .runtimeEntryBadges > span:not(.runtimeEntryTarget) { color: var(--mn-priority); background: color-mix(in srgb, var(--mn-priority) 9%, transparent); }
58
+ .runtimeEntryMeta time { overflow: hidden; color: var(--mn-faint); font: 8px var(--mn-code); text-overflow: ellipsis; white-space: nowrap; }
59
+ .runtimeEntry > p { min-height: 42px; margin: 9px 0; white-space: pre-wrap; overflow-wrap: anywhere; font-size: 12px; line-height: 1.6; }
60
+ .runtimeEntry > select { margin-top: 7px; }
61
+ .runtimeEntry footer { display: flex; min-height: 30px; align-items: center; justify-content: flex-end; gap: 4px; margin-top: 7px; padding-top: 7px; border-top: 1px solid var(--mn-line); }
62
+ .runtimeEntry footer > span { margin-right: auto; color: var(--mn-danger); font-size: 10px; }
63
+ .runtimeEmpty { display: grid; min-height: 126px; place-items: center; align-content: center; gap: 5px; color: var(--mn-faint); text-align: center; }
64
+ .runtimeEmpty > span { font: 24px var(--mn-code); opacity: .65; }
65
+ .runtimeEmpty p { margin: 0; font-size: 10px; }
66
+
67
+ @media (max-width: 1000px) {
68
+ .runtimeSummaryGrid { grid-template-columns: 1fr; }
69
+ }
70
+
71
+ @media (max-width: 760px) {
72
+ .runtimeComposerHeading,
73
+ .runtimeComposerActions { align-items: stretch; flex-direction: column; }
74
+ .runtimeComposerActions select,
75
+ .runtimeComposerActions button { width: 100%; }
76
+ .runtimeBrowserToolbar { align-items: stretch; flex-direction: column; }
77
+ .runtimeFilterQuery { width: 100%; min-width: 0; }
78
+ }
@@ -0,0 +1,62 @@
1
+ .shell .modal form[class*='runtimeComposer'] {
2
+ margin: 0;
3
+ padding: 0;
4
+ border: 0;
5
+ border-radius: 0;
6
+ background: transparent;
7
+ }
8
+ .shell .modal form[class*='runtimeComposer'] > [class*='runtimeComposerHeading'] { display: none; }
9
+
10
+ .shell [class*='runtimeComposerActions'] label {
11
+ gap: 5px;
12
+ color: var(--dsw-alias-label-secondary);
13
+ font-size: 12px;
14
+ font-weight: 500;
15
+ }
16
+
17
+ .shell [class*='runtimeComposer'] > textarea,
18
+ .shell [class*='runtimeComposerActions'] select,
19
+ .shell [class*='runtimeEntry'] select {
20
+ min-height: 34px;
21
+ border: 1px solid var(--dsw-alias-border-l2);
22
+ border-radius: 8px;
23
+ padding: 7px 10px;
24
+ color: var(--dsw-alias-label-primary);
25
+ background: var(--dsw-specific-input-major);
26
+ font-size: 13px;
27
+ font-weight: 400;
28
+ }
29
+
30
+ .shell [class*='runtimeTargetDescription'] { font-size: 12px; }
31
+
32
+ .shell [class*='runtimeEntryMeta'] > span,
33
+ .shell [class*='runtimeEntryBadges'] > span,
34
+ .shell [class*='runtimeEntryMeta'] time { font-size: 11px; }
35
+
36
+ .shell [class*='runtimeEntry'] > p { font-size: 13px; }
37
+ .shell [class*='runtimeEntryBadges'] > span {
38
+ display: inline-flex;
39
+ min-height: 22px;
40
+ align-items: center;
41
+ border: 1px solid var(--dsw-alias-border-l1);
42
+ border-radius: 999px;
43
+ padding: 0 8px;
44
+ color: var(--dsw-alias-label-secondary);
45
+ background: var(--dsw-alias-bg-layer-1);
46
+ font-size: 11px;
47
+ font-weight: 400;
48
+ line-height: 20px;
49
+ }
50
+ .shell [class*='runtimeEntryBadges'] > [class*='runtimeEntryTarget'] {
51
+ border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary) 30%, var(--dsw-alias-border-l1));
52
+ color: var(--dsw-alias-state-business-primary);
53
+ background: color-mix(in srgb, var(--dsw-alias-state-business-primary) 7%, var(--dsw-alias-bg-layer-1));
54
+ font-family: var(--dsw-font-family);
55
+ font-weight: 500;
56
+ }
57
+ .shell [class*='runtimeEntry'][data-importance='critical'] [class*='runtimeEntryBadges'] > span:last-child {
58
+ border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary) 24%, var(--dsw-alias-border-l1));
59
+ color: var(--dsw-alias-state-error-primary);
60
+ background: color-mix(in srgb, var(--dsw-alias-state-error-primary) 6%, var(--dsw-alias-bg-layer-1));
61
+ }
62
+ .shell [class*='runtimeEntry'] footer { gap: 6px; }