dsh-memoir 0.5.6 → 0.6.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/README.en.md +158 -255
- package/README.md +158 -257
- package/cordis.patch.yml +9 -8
- package/lib/autodistill.d.ts +17 -1
- package/lib/autodistill.js +14 -6
- package/lib/client.js +2115 -1769
- package/lib/client.js.map +4 -4
- package/lib/dsh-home.d.ts +7 -0
- package/lib/dsh-home.js +14 -0
- package/lib/governance.d.ts +2 -0
- package/lib/governance.js +15 -9
- package/lib/i18n.d.ts +123 -0
- package/lib/i18n.js +262 -0
- package/lib/index.d.ts +8 -2
- package/lib/index.js +62 -25
- package/lib/routes.d.ts +1 -0
- package/lib/routes.js +21 -11
- package/lib/selector.d.ts +5 -4
- package/lib/selector.js +20 -15
- package/lib/settings.d.ts +7 -3
- package/lib/settings.js +27 -18
- package/lib/snapshot.d.ts +2 -0
- package/lib/snapshot.js +4 -0
- package/lib/store.d.ts +14 -6
- package/lib/store.js +55 -39
- package/lib/tools.d.ts +5 -4
- package/lib/tools.js +75 -63
- package/package.json +43 -15
package/README.en.md
CHANGED
|
@@ -1,335 +1,238 @@
|
|
|
1
1
|
# dsh-memoir
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/dsh-memoir)
|
|
4
|
+
[](https://www.npmjs.com/package/dsh-memoir)
|
|
5
|
+
[](https://github.com/Qinling-Melon-Farmers/dsh-memoir/actions/workflows/ci.yml)
|
|
6
|
+
[](./LICENSE)
|
|
4
7
|
|
|
5
|
-
[中文](./README.md) · English · [Changelog](./CHANGELOG.md) · [
|
|
8
|
+
[中文](./README.md) · English · [Changelog](./CHANGELOG.md) · [Releases](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases)
|
|
6
9
|
|
|
7
|
-
**
|
|
10
|
+
**A local-first, cross-session project-memory plugin for DeepSeek Harness (DSH).** It persists an agent's confirmed work, lessons, and next actions, injects bounded cache-friendly Hot Memory into new sessions, and retrieves long-tail history through local BM25 ranking.
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
No embeddings, vector database, or cloud memory service. The npm package has zero bundled runtime dependencies; DSH peers are supplied by the host.
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- **Zero external memory service** — no vector database, no embedding API, no cloud memory service
|
|
14
|
-
- **Bounded hot-memory injection** — token-budgeted Hot Memory is injected into the system prompt (default 900/1200)
|
|
15
|
-
- **Ranked local recall** — inverted index + BM25 local ranked retrieval; `memoir_read` fetches long-tail history on demand
|
|
16
|
-
- **Traceable and duplicate-aware** — trusted session/turn provenance plus explainable pre-write duplicate/conflict candidates; the caller explicitly updates, supersedes, or keeps both
|
|
17
|
-
- **Web GUI** — a bilingual sidebar panel with complete lifecycle editing, project/global browsing, BM25 search, Hot Memory, diagnostics, and live settings
|
|
18
|
-
|
|
19
|
-
## Quick Start
|
|
14
|
+
> [!IMPORTANT]
|
|
15
|
+
> npm `latest` is `dsh-memoir@0.6.1` for `@deepseek-ai/dsh >=0.1.2-alpha.2 <0.1.3`, validated against DSH alpha.4 and the current alpha.5. Users remaining on `0.1.1-rc.2` should pin `dsh-memoir@0.5.6`.
|
|
20
16
|
|
|
21
17
|
```bash
|
|
22
|
-
|
|
23
|
-
dsh plugin --profile web add dsh-memoir
|
|
18
|
+
npm install --global @deepseek-ai/dsh@alpha
|
|
19
|
+
dsh plugin --profile web add dsh-memoir@latest
|
|
20
|
+
```
|
|
24
21
|
|
|
25
|
-
|
|
26
|
-
dsh plugin --profile web add github:Qinling-Melon-Farmers/dsh-memoir
|
|
22
|
+
Restart `dsh web`. Memory remains local and is not automatically deleted when the plugin is updated or removed.
|
|
27
23
|
|
|
28
|
-
|
|
29
|
-
dsh plugin --profile web add link:/absolute/path/dsh-memoir
|
|
30
|
-
```
|
|
24
|
+
## Why dsh-memoir
|
|
31
25
|
|
|
32
|
-
|
|
26
|
+
| Capability | What you get |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| Local-first storage | A JSON single source of truth plus per-project `PROJECT_MEMORY.md`; no memory upload or external service |
|
|
29
|
+
| Automatic distill reminder | Reminds the top-level agent after a worked turn, then persists transparently through `memoir_record`; skips idle, aborted, subagent, and already-recorded turns |
|
|
30
|
+
| Bounded Hot Memory | Only high-value memory enters the system prompt under a hard token limit; a frozen session prefix improves prompt-prefix cache hits |
|
|
31
|
+
| BM25 ranked recall | Searches Chinese phrases, English keywords, code identifiers, and paths; cross-project Top-K and query LRU caching use one engine |
|
|
32
|
+
| Governable memory | Importance, pinning, tags, archive/restore, and supersede lifecycle; similar writes require an explicit update, replacement, or keep-both decision |
|
|
33
|
+
| Provenance | Agent writes retain trusted session/turn sources; the Web panel can copy and make a best-effort jump to the original session |
|
|
34
|
+
| Complete Web GUI | Bilingual project/global browsing, ranked search, editing, Hot Memory inspection, diagnostics, and live settings, with an independent agent-facing language choice |
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
use the Agent as usual
|
|
36
|
-
↓
|
|
37
|
-
end of each worked turn: an automatic distill reminder
|
|
38
|
-
↓
|
|
39
|
-
memoir_record persists work / lessons / next steps
|
|
40
|
-
↓
|
|
41
|
-
future sessions auto-inherit Hot Memory (bounded, ranked, frozen per session)
|
|
42
|
-
↓
|
|
43
|
-
need long-tail history? memoir_read (local relevance-ranked recall)
|
|
44
|
-
```
|
|
36
|
+
It fits personal and local development workflows where a new agent should continue understanding a project. It is not a raw chat backup, multi-user cloud sync service, or vector-semantic knowledge base.
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+

|
|
39
|
+
|
|
40
|
+
## How it works
|
|
47
41
|
|
|
48
42
|
```text
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
PROJECT_MEMORY.md Retrieval Index
|
|
58
|
-
human-readable ranked recall
|
|
59
|
-
(git-committable) │
|
|
60
|
-
│ ▼
|
|
61
|
-
│ memoir_read
|
|
62
|
-
│ GUI /search
|
|
63
|
-
│
|
|
64
|
-
▼
|
|
65
|
-
Hot Memory Selector
|
|
66
|
-
(token budget)
|
|
67
|
-
│
|
|
68
|
-
▼
|
|
69
|
-
Session Snapshot
|
|
70
|
-
(frozen per session)
|
|
43
|
+
worked turn
|
|
44
|
+
│ automatic distill reminder
|
|
45
|
+
▼
|
|
46
|
+
memoir_record / memoir_update
|
|
47
|
+
│
|
|
48
|
+
├── ~/.dsh/dsh-memoir.json complete structured history (SSOT)
|
|
49
|
+
├── <project>/PROJECT_MEMORY.md readable, committable projection
|
|
50
|
+
└── Retrieval Index inverted index + BM25 + query cache
|
|
71
51
|
│
|
|
72
|
-
|
|
73
|
-
|
|
52
|
+
├── Hot Memory Selector ──> bounded system-prompt injection
|
|
53
|
+
└── memoir_read / Web ────> on-demand long-tail recall
|
|
74
54
|
```
|
|
75
55
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
**Full Memory (complete history)** — the structured JSON SSOT plus the regenerated `PROJECT_MEMORY.md` projection. Used for: complete history, GUI browsing, git commits, manual inspection, and as the source data for ranked recall.
|
|
79
|
-
|
|
80
|
-
**Hot Memory (bounded injection)** — high-value memories selected by the selector within a token budget, injected into the system prompt. Properties: **bounded / ranked / compact / session-frozen**.
|
|
56
|
+
Complete history and Hot Memory are separate layers:
|
|
81
57
|
|
|
82
|
-
|
|
58
|
+
- **Full Memory** retains every record for the GUI, human review, Markdown projection, and ranked retrieval.
|
|
59
|
+
- **Hot Memory** selects only budgeted actions, lessons, and recent state; the full `PROJECT_MEMORY.md` is never injected.
|
|
60
|
+
- **Session Snapshot** freezes injected text within a session. New writes are immediately readable by tools and the GUI, while automatic injection refreshes in the next new session.
|
|
83
61
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
## v0.5.6 Provenance, similar-memory governance, and Web UX
|
|
87
|
-
|
|
88
|
-
- Store format v4 records trusted `source.sessionId` / `source.turnId` for Agent writes. Legacy top-level `sessionId` values remain lazily readable and are persisted in the new shape only on a real subsequent write.
|
|
89
|
-
- Entry cards can copy provenance and make a best-effort jump to the source session/turn; manual browser writes cannot spoof trusted provenance.
|
|
90
|
-
- Before `memoir_record` or a manual Web add mutates data, the existing BM25 engine supplies candidates and title similarity plus Token Jaccard rerank them. Only suspected duplicates/conflicts are shown; nothing is changed automatically.
|
|
91
|
-
- A surfaced candidate requires an explicit `update`, `supersede`, or `force-record` decision. The UI explains BM25/title/Jaccard components and reasons, and a resolution target must belong to the current candidate set.
|
|
92
|
-
- The Memoir item under Settings → Web UI Plugins now matches the dsh-web-ui family card and starts collapsed. The Memory panel has one vertical scroll region, so expanded settings, Hot Memory, and diagnostics remain continuously scrollable.
|
|
93
|
-
- The release workflow always tries npm OIDC first and uses `NPM_TOKEN` only as an ephemeral fallback; an expired legacy token can no longer take precedence over healthy trusted publishing.
|
|
94
|
-
|
|
95
|
-
## v0.5.5 Sidebar visual-parity fix
|
|
96
|
-
|
|
97
|
-
- Fixed the stylesheet-marker collision: another style carrying the same generic `data-plugin` value no longer makes Memoir skip its own CSS. The owned stylesheet has a unique `data-dsh-memoir-style` marker and is removed on plugin unload.
|
|
98
|
-
- Matched dsh-web-ui-all 0.3.x task-board and skill-center sidebar geometry: 36px row height, 10px horizontal padding, a 24px icon box, an 18px SVG, and an 8px icon-label gap.
|
|
99
|
-
- The collapsed rail now uses the same 36px circular control and 12px row spacing, hiding copy while preserving localized `aria-label` and tooltip text; the open-book glyph remains distinct from Skill Center.
|
|
100
|
-
- Playwright runtime assertions compare expanded and collapsed row/icon/svg/label coordinates, box sizes, typography, and color instead of relying on screenshots alone.
|
|
101
|
-
|
|
102
|
-
## v0.5.4 Complete GUI, bilingual settings, and Web UI integration
|
|
103
|
-
|
|
104
|
-
- The development and peer-dependency baseline is `@deepseek-ai/dsh-* 0.1.1-rc.2`.
|
|
105
|
-
- Add/edit forms now cover `importance`, `pinned`, `tags`, and `supersedes`; cards expose importance, tags, and replacement relationships, with a new section filter.
|
|
106
|
-
- Memory Settings now appears both inside the Memory panel and under Settings → Web UI Plugins. It covers agent injection, auto-distill, Hot Memory, recall, session snapshots, and the BM25 query cache.
|
|
107
|
-
- Every saved setting applies live and persists in `~/.dsh/dsh-memoir.settings.json`; version-1 settings remain readable and upgrade to version 2 only on the next save.
|
|
108
|
-
- The GUI follows DSH's `<html lang>` and switches between Chinese and English without a reload, including the sidebar entry, panel, and Settings card.
|
|
109
|
-
- The panel and sidebar emit `data-dsh-plugin="memoir"` / `data-dsh-part` semantic attributes for the dsh-web-ui v0.3 skin contract. Sidebar mounting is idempotent and self-heals after a complete shell rebuild.
|
|
110
|
-
- Center-panel coordination now responds to any sibling through the generic `dsh-panel-activate` protocol instead of recognizing only SSH and Task Board.
|
|
111
|
-
- Auto-distill retains per-agent worked-turn intervals, time cooldowns, and tool-call thresholds; defaults `1 / 0 / 1` preserve prior behavior.
|
|
112
|
-
- Store format v3 migrates v2 entries without changing their `id`, content, or timestamp. The first mutation materializes `importance`, `pinned`, `status`, `supersedes`, and `tags`; startup reads do not rewrite old files.
|
|
113
|
-
- Retrieval defaults to `active`. Archived and superseded history is retained and can be inspected from the Web panel. Explicit `supersedes` marks its targets as superseded; history is never deleted automatically.
|
|
114
|
-
- Agents can use `memoir_update` to edit an entry's section, title, content, and lifecycle in place; the Web panel also supports editing, pinning, marking superseded, archiving, and restoring.
|
|
115
|
-
- `PROJECT_MEMORY.md` is a human-readable projection. Only bounded Hot Memory enters the system prompt; the full file is not injected.
|
|
116
|
-
- GET routes no longer register browser-supplied paths as active workspaces. Only the trusted system-prompt cwd grants panel write authorization. Lock metadata now includes pid, creation time, and nonce, with conservative reclaim only after 60 seconds and a dead owner.
|
|
117
|
-
- `memoir_read(scope: 'all')` uses a deduplicated global ranking so project and global results are not repeated.
|
|
118
|
-
|
|
119
|
-
## Tools
|
|
62
|
+
## Agent tools and memory lifecycle
|
|
120
63
|
|
|
121
64
|
| Tool | Purpose |
|
|
122
65
|
| --- | --- |
|
|
123
|
-
| `memoir_record` |
|
|
124
|
-
| `memoir_update` |
|
|
125
|
-
| `memoir_read` |
|
|
126
|
-
|
|
127
|
-
`memoir_read`'s query description matches its real behavior: **local relevance retrieval over titles and content — supports Chinese phrases, English keywords, code identifiers, and paths, ordered by relevance**.
|
|
128
|
-
|
|
129
|
-
## Retrieval
|
|
130
|
-
|
|
131
|
-
- No embeddings, no vector database, no external memory service
|
|
132
|
-
- Tokenization: Chinese 2/3-grams + English words + code/path identifiers
|
|
133
|
-
- BM25 (documents keep true term frequency; queries are deduplicated)
|
|
134
|
-
- 2.5× title boost, exact-phrase boost, section weight, recency decay
|
|
135
|
-
- Separate length normalization for titles and bodies (v0.4.2)
|
|
136
|
-
- Epoch-aware LRU query cache with 1-hour time buckets: limit/detail stay out of the cache key, so every output shape shares one ranked result (v0.4.2)
|
|
137
|
-
- Query-cache metrics (hits/misses/evictions/hit rate) and Last Query (latency/candidates/returned) observability (v0.4.2)
|
|
138
|
-
- Global recall limit is a true global Top-K; output truncation preserves the top-ranked head (v0.4.2)
|
|
139
|
-
- Pre-write governance takes the current project's active BM25 Top-24 candidate set, then combines query-relative BM25, title similarity, and Token Jaccard; at most five explainable candidates are returned (v0.5.6)
|
|
66
|
+
| `memoir_record` | Write work / lessons / actions / note entries; returns explainable similar/conflicting candidates before mutation |
|
|
67
|
+
| `memoir_update` | Preserve id and creation time while updating content, section, importance, tags, and lifecycle |
|
|
68
|
+
| `memoir_read` | Local ranked recall across project (default) / global / all with compact or full output |
|
|
140
69
|
|
|
141
|
-
|
|
70
|
+
Each entry has importance 1–5. The default, **3**, is neutral; pinning adds separate Hot Memory weight. Recall defaults to `active`. Archived or superseded history remains inspectable and restorable and is never deleted automatically.
|
|
142
71
|
|
|
143
|
-
|
|
72
|
+
Similar-memory governance starts with BM25 candidates, then combines title similarity and Token Jaccard. The plugin surfaces suspected duplicates or conflicts but does not decide truth on its own. The caller must choose:
|
|
144
73
|
|
|
145
|
-
|
|
74
|
+
- `update`: update an existing record in place;
|
|
75
|
+
- `supersede`: retain old history and mark it as replaced by the new record;
|
|
76
|
+
- `force-record`: explicitly keep both.
|
|
146
77
|
|
|
147
|
-
|
|
148
|
-
- **Hot Memory Inspector**: expand to see the Hot Memory that will actually be injected for the current workspace (Actions / Lessons / Recent state) — i.e. "what exactly the next session inherits"
|
|
149
|
-
- **Retrieval Diagnostics**: Retrieval Index (docs/terms/epoch), Query Cache (hits/misses/evictions/hit rate/size/capacity), Last Query (latency/returned), Session Snapshot (hash/createdAt/storeRevision)
|
|
150
|
-
- **Complete lifecycle forms (v0.5.4)**: add and edit section, title, content, importance, pinning, tags, and explicit replacement relationships; filter by status and section
|
|
151
|
-
- **Complete live settings (v0.5.4)**: adjust agent injection, auto-distill, Hot Memory target/hard limits, recall defaults/maxima, session snapshots, and query cache immediately
|
|
152
|
-
- **Settings integration (v0.5.4)**: the same bilingual card mounts in the Memory panel and Settings → Web UI Plugins, and redraws immediately when the page language changes
|
|
153
|
-
- **Visual parity with the dsh-web-ui family (v0.5.5)**: the panel, sidebar entry, forms, cards and tabs ride the `--dsw-alias-*` / `--dsw-specific-*` / `--dsw-font-family` design tokens (with standalone fallbacks), matching the task-board / ssh / skill-explorer panels shipped by dsh-web-ui-all; the center-column panel mutual-exclusion protocol is aligned too.
|
|
154
|
-
- **Provenance and similar-memory governance (v0.5.6)**: display/copy/jump session and turn provenance; new records expose duplicate/conflict candidates, three score components, reasons, and three explicit resolution actions
|
|
155
|
-
- **Settings and scrolling fix (v0.5.6)**: the Settings card starts collapsed and follows the family card structure; the panel keeps one scroll owner across the list, settings, Hot Memory, and diagnostics
|
|
78
|
+
## Automatic distillation
|
|
156
79
|
|
|
157
|
-
|
|
80
|
+
Automatic distillation is an observable agent turn-end reminder, not silent background scraping of every chat. The default `1 / 0 / 1` means every eligible worked turn, no extra cooldown, and at least one tool call.
|
|
158
81
|
|
|
159
|
-
|
|
82
|
+
`autoDistillEvery`, `autoDistillCooldownMin`, and `autoDistillMinTools` are AND conditions isolated per agent. Idle, aborted, subagent, and already-recorded turns do not trigger. Cooldown advances only after a successful reminder. All cadence parameters are live-editable in the GUI.
|
|
160
83
|
|
|
161
|
-
|
|
84
|
+
`language` independently controls agent-visible tool descriptions and parameters, the distillation prompt, tool results, Hot Memory / `PROJECT_MEMORY.md` headings, and validation or governance errors. It defaults to `zh` for backward compatibility and can be switched to `en` in the GUI. Tool schemas and subsequent prompts update live without restarting DSH.
|
|
162
85
|
|
|
163
|
-
|
|
86
|
+
## Local recall and caching
|
|
164
87
|
|
|
165
|
-
|
|
88
|
+
- Chinese 2/3-grams, English words, and code/path identifier tokenization;
|
|
89
|
+
- document-side BM25 keeps true term frequency, with a 2.5× title boost plus exact-phrase, section, and recency weighting;
|
|
90
|
+
- separate title/body length normalization;
|
|
91
|
+
- deduplicated global Top-K shared by project / global / all;
|
|
92
|
+
- epoch-aware LRU query cache with one-hour time buckets; `limit` and output detail stay outside the key so output shapes share rankings;
|
|
93
|
+
- the GUI and `memoir_read` use the same RetrievalEngine and expose hits, misses, evictions, hit rate, and last-query latency.
|
|
166
94
|
|
|
167
|
-
|
|
95
|
+
Top-5 recall on the fixed quality set is 100%; the repository gate requires at least 90%.
|
|
168
96
|
|
|
169
|
-
|
|
97
|
+
## Web GUI
|
|
170
98
|
|
|
171
|
-
|
|
99
|
+
Installing into a DSH-alpha `web` profile registers a native Memory Conversation view and Memory Settings section through official slots. The DSH shell owns layout, navigation, and unload lifecycle; Memoir no longer takes over the legacy sidebar through DOM selectors.
|
|
172
100
|
|
|
173
|
-
|
|
101
|
+
- Project memory and all-project global memory, with project groups collapsed by default and complete lifecycle totals;
|
|
102
|
+
- status, section, and keyword filters with BM25 scores;
|
|
103
|
+
- add, edit, pin, archive, restore, and supersede;
|
|
104
|
+
- copy and best-effort navigation for session/turn provenance;
|
|
105
|
+
- Hot Memory Inspector: what the next session will inherit;
|
|
106
|
+
- Retrieval Diagnostics: index, query cache, last query, and session snapshot;
|
|
107
|
+
- permanent `Browse / Settings / Hot Memory / Diagnostics` navigation with an independent bounded scroll position per surface;
|
|
108
|
+
- progressive batches of 20 entries or projects, plus a controlled six-line preview for long memory bodies;
|
|
109
|
+
- the native DSH composer-overlay contract, keeping the final memory visible above the conversation composer while the list scrolls fully;
|
|
110
|
+
- arrow-key, Home, and End navigation for surface tabs, plus `aria-expanded` project disclosures and visible focus states;
|
|
111
|
+
- live GUI Chinese/English switching from `<html lang>`, with a separate `language` setting for agent-facing copy.
|
|
174
112
|
|
|
175
|
-
|
|
113
|
+
<details>
|
|
114
|
+
<summary>More GUI screenshots</summary>
|
|
176
115
|
|
|
177
|
-

|
|
178
117
|
|
|
179
|
-
|
|
118
|
+

|
|
180
119
|
|
|
181
|
-
|
|
120
|
+

|
|
182
121
|
|
|
183
|
-

|
|
184
123
|
|
|
185
|
-
|
|
124
|
+

|
|
186
125
|
|
|
187
|
-

|
|
188
127
|
|
|
189
|
-
|
|
128
|
+
</details>
|
|
190
129
|
|
|
191
|
-
|
|
130
|
+
## Installation and compatibility
|
|
192
131
|
|
|
193
|
-
|
|
132
|
+
| Channel | DSH baseline | Installation | Status |
|
|
133
|
+
| --- | --- | --- | --- |
|
|
134
|
+
| npm `latest` (`0.6.1`) | `>=0.1.2-alpha.2 <0.1.3` | `dsh plugin --profile web add dsh-memoir@latest` | Current release; alpha.4 compile and alpha.5 + dsh-web-all browser validated |
|
|
135
|
+
| pinned npm `0.5.6` | `0.1.1-rc.2` | `dsh plugin --profile web add dsh-memoir@0.5.6` | rc2 compatibility line |
|
|
136
|
+
| GitHub `main` (`0.6.1`) | `>=0.1.2-alpha.2 <0.1.3` | source clone + `link:` | Synchronized with npm `0.6.1`; intended for development and debugging |
|
|
194
137
|
|
|
195
|
-
|
|
138
|
+
Node.js `^22.19.0 || >=24.0.0` is required. v0.6.x uses the native DSH-alpha `conversation.view` / `settings.section` slots and the Remote-era client module architecture. v0.6.1 supports both the public `session.events` surface in alpha.2/alpha.3 and `session.snapshotEvents()` in alpha.4+. `dsh.engines.dsh` rejects incompatible hosts.
|
|
196
139
|
|
|
197
|
-
|
|
140
|
+
<details>
|
|
141
|
+
<summary>Install from source</summary>
|
|
198
142
|
|
|
199
|
-
|
|
143
|
+
0.6.x source:
|
|
200
144
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
No cloud memory DB · No embedding API · No vector DB
|
|
145
|
+
```bash
|
|
146
|
+
git clone https://github.com/Qinling-Melon-Farmers/dsh-memoir.git
|
|
147
|
+
cd dsh-memoir
|
|
148
|
+
pnpm install --frozen-lockfile
|
|
149
|
+
pnpm run build
|
|
150
|
+
npm install --global @deepseek-ai/dsh@alpha
|
|
151
|
+
dsh plugin --profile web add "link:/absolute/path/dsh-memoir"
|
|
209
152
|
```
|
|
210
153
|
|
|
211
|
-
|
|
154
|
+
</details>
|
|
212
155
|
|
|
213
|
-
##
|
|
156
|
+
## Storage, privacy, and security boundaries
|
|
214
157
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
-
|
|
219
|
-
- id: memoir
|
|
220
|
-
name: dsh-memoir
|
|
221
|
-
config:
|
|
222
|
-
enabled: true # master switch (tools, routes, prompt section)
|
|
223
|
-
announceToAgent: true # system-prompt announcement section
|
|
224
|
-
autoDistill: true # auto distill reminder after each worked turn
|
|
225
|
-
autoDistillEvery: 1 # remind at most once per N worked turns
|
|
226
|
-
autoDistillCooldownMin: 0 # require M minutes between successful reminders
|
|
227
|
-
autoDistillMinTools: 1 # triggering turn must contain at least K tool calls
|
|
228
|
-
hotMemoryTokens: 900 # Hot Memory target tokens
|
|
229
|
-
hotMemoryMaxTokens: 1200 # Hot Memory hard ceiling (never exceeded)
|
|
230
|
-
readDefaultLimit: 8 # memoir_read default result count
|
|
231
|
-
readMaxLimit: 30 # memoir_read maximum result count
|
|
232
|
-
sessionSnapshotMax: 128 # per-session snapshot LRU cap
|
|
233
|
-
queryCacheSize: 128 # ranked-query LRU cache size
|
|
158
|
+
```text
|
|
159
|
+
~/.dsh/dsh-memoir.json structured JSON v4 (single source of truth)
|
|
160
|
+
~/.dsh/dsh-memoir.settings.json live GUI setting overrides
|
|
161
|
+
<project>/PROJECT_MEMORY.md human-readable projection generated from JSON
|
|
234
162
|
```
|
|
235
163
|
|
|
236
|
-
|
|
164
|
+
- No cloud memory database, embedding API, or vector database;
|
|
165
|
+
- an arbitrary absolute path submitted by the browser does not grant write access; panel writes accept only a trusted active workspace or an existing project bucket;
|
|
166
|
+
- manual browser records cannot spoof trusted session/turn provenance;
|
|
167
|
+
- cross-process writes use an exclusive lock and reread disk inside the critical section, with conservative dead-owner recovery;
|
|
168
|
+
- Windows path keys are case-normalized while display paths retain their original form;
|
|
169
|
+
- `PROJECT_MEMORY.md` may be committed by you, so the user decides whether sensitive content enters Git.
|
|
237
170
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
## Design Trade-offs
|
|
241
|
-
|
|
242
|
-
- **Bounded vs full injection**: v0.3 injected the full history into the prompt and it kept growing; v0.4+ injects only budgeted Hot Memory, with long-tail history recalled on demand. Token benchmarks below.
|
|
243
|
-
- **Frozen vs fresh**: within a session the injected text is frozen to gain prompt-prefix cache hits; without a unique session identity it is not frozen (v0.4.2), so new sessions always see new memory.
|
|
244
|
-
- **Hot Memory quota**: Recent state (newest work, 1–3 entries) is guaranteed a floor, actions/lessons fill by ranking, and work only appears in Recent state — never injected twice (v0.4.2).
|
|
245
|
-
- **Multi-process safety**: store record/remove runs inside a cross-process critical section on `~/.dsh/dsh-memoir.lock` (exclusive O_EXCL creation with timeout); the section force-reloads from disk before mutating, so two interleaved DSH processes lose no updates (v0.4.2).
|
|
246
|
-
- **Windows paths**: canonical keys are fully lowercased (`C:\A` / `c:\a\` / `C:/A` share one bucket) while display paths keep the original casing (v0.4.2).
|
|
247
|
-
- **GUI and Agent share one engine**: panel search and `memoir_read` use the same RetrievalEngine instead of separate filter logic (v0.4.2).
|
|
248
|
-
- **Auto-distill cadence**: the default still reminds after every worked turn; research-heavy sessions can combine interval, cooldown, and activity thresholds and tune them immediately from either GUI settings surface (v0.5.4).
|
|
249
|
-
- **Similarity governance, not automatic merging**: lexical similarity can identify candidates but cannot reliably decide semantic truth, so v0.5.6 always requires an explicit update, supersede, or keep-both choice.
|
|
250
|
-
|
|
251
|
-
## Use Cases
|
|
252
|
-
|
|
253
|
-
| Scenario | How to use it |
|
|
254
|
-
| --- | --- |
|
|
255
|
-
| Recurring environment pitfalls (encoding / escaping / paths / permissions) | record a `lessons` entry with copy-pasteable fix commands |
|
|
256
|
-
| Project rules and conventions (no emoji, run tests before release, branch policy) | record as `actions`, auto-injected for whoever takes over |
|
|
257
|
-
| Root cause of a hard-to-find bug | record as `lessons` / `work` to avoid re-investigation |
|
|
258
|
-
| Fixed deployment/release checklist | record as `actions`; new sessions follow it |
|
|
259
|
-
| Reuse experience across projects | global tab or `memoir_read(scope: 'global', query: ...)` |
|
|
171
|
+
Back up the JSON and project Markdown according to your own policy before upgrades. Removing the plugin does not actively delete them.
|
|
260
172
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
## Comparison
|
|
264
|
-
|
|
265
|
-
| Project | Primary focus |
|
|
266
|
-
| --- | --- |
|
|
267
|
-
| dsh-memory | citation / source-traceable reference memory |
|
|
268
|
-
| dsh-mnemon | a heavier long-term memory system |
|
|
269
|
-
| distill | distilling sessions into skills |
|
|
270
|
-
| **dsh-memoir** | **lightweight project workflow memory: local, bounded injection, ranked recall** |
|
|
271
|
-
|
|
272
|
-
Each plugin has its own focus — pick per need; no "which is stronger" narrative.
|
|
273
|
-
|
|
274
|
-
## Development / Benchmark / Tests
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
pnpm install # install devDeps (typescript, esbuild, @deepseek-ai/* type packages)
|
|
278
|
-
pnpm run build # tsc builds the host + esbuild builds the client bundle
|
|
279
|
-
pnpm run typecheck # full type check (src + test)
|
|
280
|
-
pnpm test # 171 tests: store/migrations/lock, settings, snapshot, selector, BM25/similarity governance, tools/routes, auto-distill, GUI/scrolling/bilingual behavior, integration, bundle, and release notes
|
|
281
|
-
npm run bench # benchmark (100/1k/10k/100k entries); results written to bench/report.md
|
|
282
|
-
```
|
|
173
|
+
## Configuration
|
|
283
174
|
|
|
284
|
-
|
|
175
|
+
Every field below can be set in the memoir `config` row in `cordis.patch.yml`. Except for `enabled`, each is also live-editable and persisted from the Memory panel or Settings card.
|
|
285
176
|
|
|
286
|
-
|
|
177
|
+
| Field | Default | Purpose |
|
|
178
|
+
| --- | ---: | --- |
|
|
179
|
+
| `enabled` | `true` | master switch for tools, routes, and prompt injection |
|
|
180
|
+
| `language` | `zh` | agent-facing prompt, tool schema/result, projection-heading, and error language; `zh` or `en` |
|
|
181
|
+
| `announceToAgent` | `true` | announce memory tools and rules to the agent |
|
|
182
|
+
| `autoDistill` | `true` | enable top-level worked-turn reminders |
|
|
183
|
+
| `autoDistillEvery` | `1` | remind at most once per N worked turns |
|
|
184
|
+
| `autoDistillCooldownMin` | `0` | minimum minutes between successful reminders |
|
|
185
|
+
| `autoDistillMinTools` | `1` | minimum tool calls required in a triggering turn |
|
|
186
|
+
| `hotMemoryTokens` | `900` | normal Hot Memory target budget |
|
|
187
|
+
| `hotMemoryMaxTokens` | `1200` | hard ceiling that no session exceeds |
|
|
188
|
+
| `readDefaultLimit` | `8` | default `memoir_read` result count |
|
|
189
|
+
| `readMaxLimit` | `30` | live upper bound per recall |
|
|
190
|
+
| `sessionSnapshotMax` | `128` | frozen session-snapshot LRU capacity |
|
|
191
|
+
| `queryCacheSize` | `128` | BM25 query LRU capacity |
|
|
287
192
|
|
|
288
|
-
|
|
289
|
-
|---|---|---|---|---|---|---|---|---|---|---|
|
|
290
|
-
| 100 | 0.9 ms | 0.95 µs | 0.46 ms | 2.1 ms | 0.169 ms | 2.21 µs | 50.0% | 3908 | 902 | 76.9% |
|
|
291
|
-
| 1,000 | 3.0 ms | 0.35 µs | 0.58 ms | 10.5 ms | 1.190 ms | 4.07 µs | 50.0% | 38220 | 916 | 97.6% |
|
|
292
|
-
| 10,000 | 26.4 ms | 0.35 µs | 2.05 ms | 126.9 ms | 11.011 ms | 1.45 µs | 50.0% | 385845 | 902 | 99.8% |
|
|
293
|
-
| 100,000 | 210.7 ms | 0.51 µs | 20.11 ms | 1679.9 ms | 126.933 ms | 1.42 µs | 50.0% | 3907095 | 917 | 100.0% |
|
|
193
|
+
Shrinking a cache evicts the oldest entries immediately. Existing frozen sessions are not rewritten after budget changes, preserving prompt-prefix stability. “Restore startup configuration” removes Web overrides and returns to profile startup values.
|
|
294
194
|
|
|
295
|
-
##
|
|
195
|
+
## Performance and verification
|
|
296
196
|
|
|
297
|
-
|
|
298
|
-
- **Two-sided plugin**: the host half registers the agent tools, `/api/dsh-memoir` routes, the `agent/turn-stopping` auto-distill listener, and the per-project system-prompt injection section; the client half renders the panel. Runtime deps are official NPM SDK packages only.
|
|
299
|
-
- Mounted via the `dsh.bundle.patch` manifest (`insert` row in `cordis.patch.yml`); no DSH source changes.
|
|
300
|
-
- Auto-distill safety boundaries: top-level sessions only (subagents / nested delegations skipped), turns with tool activity that haven't recorded yet, aborted turns skipped, at most one steer per turn.
|
|
197
|
+
v0.5.6 benchmark (Node 24.19, 900/1200-token budget; full data in [`bench/report.md`](./bench/report.md)):
|
|
301
198
|
|
|
302
|
-
|
|
199
|
+
| Entries | Index build | Uncached query | Cached query | Injection reduction vs full Markdown |
|
|
200
|
+
| ---: | ---: | ---: | ---: | ---: |
|
|
201
|
+
| 1,000 | 10.5 ms | 1.190 ms | 4.07 µs | 97.6% |
|
|
202
|
+
| 10,000 | 126.9 ms | 11.011 ms | 1.45 µs | 99.8% |
|
|
203
|
+
| 100,000 | 1.68 s | 126.933 ms | 1.42 µs | about 100% |
|
|
303
204
|
|
|
304
|
-
|
|
205
|
+
Numbers vary by machine and corpus. The important properties are that injection remains bounded and the cache-hit path is independent of total memory size.
|
|
305
206
|
|
|
306
|
-
-
|
|
307
|
-
- [ISSUE_TRIAGE.md](ISSUE_TRIAGE.md) — issue labels, classification and closing criteria;
|
|
308
|
-
- `.github/ISSUE_TEMPLATE` — bug / request templates; `.github/pull_request_template.md` — PR template.
|
|
207
|
+
v0.6.1 has 189 automated tests covering store/settings migration and locks, Hot Memory, BM25 quality/cache, lifecycle, provenance anti-spoofing, similar-memory governance, automatic distillation, bilingual agent and GUI surfaces, project disclosure/progressive loading, scrolling, and DSH-alpha compatibility. An isolated DSH alpha.5 + `@linxin666/dsh-web-all@0.3.12` profile also passed Settings and real-session browser regression; alpha.4 type compilation passed separately.
|
|
309
208
|
|
|
310
|
-
|
|
209
|
+
## FAQ
|
|
311
210
|
|
|
312
|
-
|
|
211
|
+
**Does it automatically summarize every chat?**<br>
|
|
212
|
+
It does not silently scrape every conversation. At the end of an eligible turn it reminds the current agent to distill, and the agent writes through a public tool, keeping the process observable and reviewable.
|
|
313
213
|
|
|
314
|
-
|
|
214
|
+
**Why does every new memory start at importance 3?**<br>
|
|
215
|
+
Three is the neutral default on a 1–5 scale, so unscored content is neither demoted nor treated as highest priority. Change it through tool arguments or the GUI; pinning has separate weight.
|
|
315
216
|
|
|
316
|
-
|
|
217
|
+
**Why is a new write not reinjected immediately in the current session?**<br>
|
|
218
|
+
The session Hot Memory snapshot is deliberately frozen for prompt-prefix caching. The write is immediately visible to `memoir_read` and the GUI, and the next session rebuilds automatic injection.
|
|
317
219
|
|
|
318
|
-
|
|
220
|
+
**Does it inject all stored memory into context?**<br>
|
|
221
|
+
No. Only Hot Memory bounded by `hotMemoryMaxTokens` is injected automatically. Complete history is recalled on demand.
|
|
319
222
|
|
|
320
|
-
|
|
321
|
-
|
|
223
|
+
**Why is the UI missing after installation?**<br>
|
|
224
|
+
Confirm the command used `--profile web`, then fully restart `dsh web`. Refreshing the browser alone is not enough.
|
|
322
225
|
|
|
323
|
-
|
|
226
|
+
## Development and contributing
|
|
324
227
|
|
|
325
228
|
```bash
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
229
|
+
pnpm install --frozen-lockfile
|
|
230
|
+
pnpm run build
|
|
231
|
+
pnpm run typecheck
|
|
232
|
+
pnpm test
|
|
233
|
+
npm run bench
|
|
329
234
|
```
|
|
330
235
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
## License
|
|
236
|
+
Read [CONTRIBUTING.md](./CONTRIBUTING.md) before submitting changes. See [CHANGELOG.md](./CHANGELOG.md) for version history. Formal packages are published by the tag workflow through npm OIDC. The current npm release is [v0.6.1](https://github.com/Qinling-Melon-Farmers/dsh-memoir/releases/tag/v0.6.1), and `main` is synchronized with it.
|
|
334
237
|
|
|
335
238
|
Apache-2.0
|