@a9i5k4/dsh-auto-memory 0.1.37 → 0.1.39

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
@@ -340,6 +340,10 @@ Papers were authored by the autonomous engineering agent (ZCode / GLM); all conc
340
340
 
341
341
  ## Community
342
342
 
343
+ **Feedback & chat:** join the community QQ group — [Join the dsh-auto-memory group](https://qm.qq.com/q/v7Asxn6vPa) — for bug reports, usage tips, and quick responses faster than GitHub issues.
344
+
345
+ Community contributors:
346
+
343
347
  - [@ProperSAMA](https://github.com/ProperSAMA) — panel readability fix for DSH Desktop enhanced mode (transparent/Mica materials) + entry-button anti-occlusion & outside-click/Esc close ([PR #12](https://github.com/Aik358/dsh-auto-memory/pull/12))
344
348
  - [@nkh0472](https://github.com/nkh0472) — unattended/batch workflow hardening feedback that drove the welcome tour and per-feature switches ([Issue #10](https://github.com/Aik358/dsh-auto-memory/issues/10))
345
349
 
package/README.zh-CN.md CHANGED
@@ -1,382 +1,386 @@
1
- # dsh-auto-memory — DSH 自动记忆与人性化交互插件
2
-
3
- <p align="center">
4
- <a href="https://htmlpreview.github.io/?https://github.com/Aik358/dsh-auto-memory/blob/preview/docs/landing/index.html"><strong>🌐 宣传主页(功能全景 · 数据流 · 论文 · 截图)</strong></a>
5
- </p>
6
-
7
- <p align="center">
8
- <a href="docs/screenshots/promo/promo-0-banner-v2.png"><img width="820" alt="dsh-auto-memory 主视觉:不用吩咐,她自己记得" src="docs/screenshots/promo/promo-0-banner-v2.png"></a>
9
- </p>
10
-
11
- <p align="center">
12
- <a href="docs/screenshots/promo/promo-0-banner-v2.png"><img width="130" alt="主视觉" src="docs/screenshots/promo/promo-0-banner-v2.png"></a>
13
- <a href="docs/screenshots/promo/promo-2-tour.png"><img width="130" alt="欢迎向导" src="docs/screenshots/promo/promo-2-tour.png"></a>
14
- <a href="docs/screenshots/promo/promo-3-recall.png"><img width="130" alt="唤起与固化" src="docs/screenshots/promo/promo-3-recall.png"></a>
15
- <a href="docs/screenshots/promo/promo-4-unattended.png"><img width="130" alt="无人值守" src="docs/screenshots/promo/promo-4-unattended.png"></a>
16
- <a href="docs/screenshots/promo/promo-5-external.png"><img width="130" alt="外部记忆继承" src="docs/screenshots/promo/promo-5-external.png"></a>
17
- <a href="docs/screenshots/promo/promo-6-greeting.png"><img width="130" alt="定时问候" src="docs/screenshots/promo/promo-6-greeting.png"></a>
18
- </p>
19
- <p align="center"><sub>宣传图六幕 · 点击任意一张查看大图</sub></p>
20
-
21
- <details>
22
- <summary><b>宣传图分幕浏览</b>(点击展开,逐幕翻看)</summary>
23
-
24
- #### 第一幕 · 主视觉 —— 不用吩咐,她自己记得
25
-
26
- <p align="center"><img width="720" alt="主视觉" src="docs/screenshots/promo/promo-1-hero.png"></p>
27
-
28
- #### 第二幕 · 欢迎向导 —— 每个功能,当场看懂、当场开关
29
-
30
- <p align="center"><img width="720" alt="欢迎向导" src="docs/screenshots/promo/promo-2-tour.png"></p>
31
-
32
- #### 第三幕 · 唤起与固化 —— 对话凝成技能,每一步有迹可循
33
-
34
- <p align="center"><img width="720" alt="唤起与固化" src="docs/screenshots/promo/promo-3-recall.png"></p>
35
-
36
- #### 第四幕 · 无人值守模式 —— 整夜安静跑,零寒暄,零打扰
37
-
38
- <p align="center"><img width="720" alt="无人值守" src="docs/screenshots/promo/promo-4-unattended.png"></p>
39
-
40
- #### 第五幕 · 外部记忆继承 —— 你的其他 AI,也在喂她记忆
41
-
42
- <p align="center"><img width="720" alt="外部记忆继承" src="docs/screenshots/promo/promo-5-external.png"></p>
43
-
44
- #### 第六幕 · 定时暖心问候 —— 让每一天都被记得
45
-
46
- <p align="center"><img width="720" alt="定时问候" src="docs/screenshots/promo/promo-6-greeting.png"></p>
47
-
48
- </details>
49
-
50
- <p align="center">
51
- <b>中文</b> · <a href="README.md">English</a> · License BSD-3-Clause · <code>pnpm add @a9i5k4/dsh-auto-memory</code>
52
- </p>
53
-
54
- > **v0.1.30 大更新** — 全新「欢迎向导」:分步介绍所有功能、当场开关;Office/Fluent 式液态玻璃应用图标族;更新日志开场动画;无人值守模式面向长批处理任务。
55
-
56
- 一个为 DeepSeek Harness Web GUI 打造的**主动联想记忆插件**:不依赖模型主动调用,记忆在对话进行时被情境自动唤回并注入下一环节——同时三层记忆自动沉淀、AI 问候与每日反思、日历提醒、外部 AI 记忆继承,以及面向生产环境的无人值守/批处理支持。
57
-
58
- **它解决的问题是**:AI 助手每次会话都从零开始,而现有的记忆方案都要求模型"记得去查"——调一次工具、发一次请求,忘了就没了。装上它之后,记忆的唤回不需要任何指令:Host 中间件持续观察对话情境,该想起的记忆自动走向模型;你的偏好、项目约定、昨天的进度、下周的截止日期,还有你回来时那声"欢迎回来",全部自然发生。
59
-
60
- ---
61
-
62
- 30 秒亮点
63
-
64
- | | |
65
- |---|---|
66
- | **主动联想,零指令** | 记忆不靠模型调用——Host 观察情境自动唤回,经固定边界注入下一环节,前缀缓存友好 |
67
- | **三层记忆引擎** | 用户级规则 → 项目笔记 → 每日日志,注入+按需检索 |
68
- | **记忆自动沉淀** | 每轮对话结束由子代理静默判断去留,主题分组写入日志——你永远不需要记得"记一下" |
69
- | **唤起有据可查** | 每次激活决策带完整证据链,唤起回顾页可复核打分;技能由跨会话证据渐进固化 |
70
- | **主动式提醒** | AI 从对话中识别截止日期/约定,自动入日历并在后续会话中提醒 |
71
- | **一切皆开关** | 欢迎向导+设置页双重入口,每个功能独立开关(含无人值守模式) |
72
- | **外部记忆继承** | WorkBuddy / CodeBuddy / Claude Code / Codex 的历史记忆可扫描、导入、按源管理 |
73
- | **生产级卫生** | 写入门禁(乱码/复读/JSON 注入拦截)+ 脏 token 扫描 + 凭证永不进提示词 |
74
-
75
- ---
76
-
77
- ## 欢迎向导(v0.1.30 新增)
78
-
79
- 升级或首次安装后,插件会自动播放一段**分步欢迎向导**——这不是弹窗广告,而是功能总开关的集合地:
80
-
81
- <p align="center"><img width="720" alt="welcome tour" src="docs/screenshots/tour-welcome.png"></p>
82
-
83
- - **每步一枚 Office/Fluent 式液态玻璃应用图标**:注入青蓝、问候暖金、日历青绿、引擎紫蓝、雷达天青、完成珊瑚金——各配专属循环动效(铃摆动、日历翻页、雷达扫描、火花上升…)
84
- - **每项功能当场开关**:开关即写配置立即生效,不需要再进设置页确认
85
- - **语义引擎检测/下载内联**:三级检索引擎(词法 0GB 保底 → 内置语义 ~130MB → Python BGE-M3 进阶)在向导内自动检测、一键安装(SHA256 校验+推理自检)
86
- - **外部记忆实时扫描**:本机可读的 WorkBuddy / Claude Code / Codex 等来源直接列出,逐源勾选
87
- - **关不掉的困惑不存在**:中途关闭会先落到"完成提醒"步,告诉你每个功能在设置的哪个分区重新打开
88
-
89
- <p align="center"><img width="720" alt="tour core" src="docs/screenshots/tour-core.png"></p>
90
-
91
- 升级用户的一次性触达:v0.1.30 起所有用户升级后都会自动播放一次完整向导,结束后自动接更新日志(可点击跳过)。之后可随时在 **设置 → 外观 → 欢迎向导 → ▶ 重看引导** 重新打开。
92
-
93
- ---
94
-
95
- ## 三层记忆体系
96
-
97
- | 层 | 位置 | 内容 |
98
- |---|---|---|
99
- | 用户级记忆 | `~/.dsh/memory/MEMORY.md` | 跨项目规则与偏好 |
100
- | 项目笔记 | `~/.dsh/memory/workspaces/{workspace}/MEMORY.md` | 项目约定与决策 |
101
- | 每日日志 | `~/.dsh/memory/workspaces/{workspace}/YYYY-MM-DD.md` | 追加式工作日志 |
102
- | 每日反思 | `…/reflections/YYYY-MM-DD.md` | 结构化复盘(成果/教训/下一步) |
103
-
104
- **注入策略**:静态纪律进 system prompt(字节级稳定,保前缀缓存命中);动态记忆走运行时快照——只注入最近 1 天日志+反思摘要,其余全部按需经 `memory_read` / `memory_recall` 取回。凭证/密钥段**永远被过滤在提示词之外**。
105
-
106
- ---
107
-
108
- ## 功能全景
109
-
110
- ### 主动联想 — 不用吩咐,她自己记得
111
-
112
- 这是插件与其他记忆方案的根本区别:**记忆唤回不依赖模型主动调用**。市面上的记忆工具要么要模型记得调一次检索工具,要么要用户手动粘贴上下文——忘了调,记忆就等于不存在。本插件是 Host 侧的主动联想中间件:持续观察对话情境与运行事件,相关记忆在模型开口之前就被检索、决策、并经固定边界注入下一环节(已发请求不可原地改写,前缀缓存永不失效)。同时权限分立:语义决策与身份/授权/时序治理由两层各自负责,每次投递都有证据链。
113
-
114
- ### 自动沉淀 — 记忆自己写自己
115
-
116
- 每轮对话结束后,一个小型子代理静默评估本轮内容:有长期价值的主题分组写入今日日志(`## 主题(HH:MM)`+要点),长期决策晋升项目笔记,跨项目规则晋升用户级记忆,闲聊跳过,失败进队列每 5 分钟重试(15 秒心跳文件证明循环存活)。每日写入有预算与自动压缩(超限不拒写,AI 合并去重后写入)。
117
-
118
- ### 唤起与固化 — 该出手时才出手
119
-
120
- 联想式记忆唤起在对话链中检测回忆需求,命中即注入下一环节(不破坏前缀缓存);高频流程固化为技能 checklist,匹配对话自动附上,跨会话验证后晋升(记忆中枢页审批,90 天未用自动归档可置顶)。**每一次"要不要打断你"的决策都能在「唤起回顾」页复核打分**(A 该激活 / P 只预取 / S 应抑制 / H 有害 / E 改目标),判定队列会汇总成政策提示。
121
-
122
- <p align="center"><img width="720" alt="refine" src="docs/screenshots/panel-refine.png"></p>
123
-
124
- ### 无人值守模式 — 面向批处理任务
125
-
126
- 长跑批处理/自动化流水线?设置 → 自动化提供**无人值守模式**与**夜间自动托管**(22:00-08:00 可调)。托管期间:不注入欢迎语/寒暄/行为指令、日历提醒静默、上下文保持稳定——模型专注干活,token 花在正事上。
127
-
128
- ### AI 问候与每日反思
129
-
130
- 按时段(晨/午/晚)生成提及你当日最重要工作的问候;暂离超过 1 小时回来,记忆面板自动打开并送上"欢迎回来"+近期工作摘要;每天第一次会话主动呈现前一日结构化反思。
131
-
132
- ### 智能检索
133
-
134
- 自然语言提问,AI 自动扩展关键词扫描全部记忆层,会话式回答并标注来源;支持跨工作区检索。
135
-
136
- ### 日历 — AI 替你维护
137
-
138
- AI 从对话中识别截止日期/约定自动入日历(`calendar_add`),未完成事项注入后续会话直到完成;日视图 07:00-22:00 时间轴、地点/提醒字段、紧急度语义色。
139
-
140
- ### 外部记忆继承
141
-
142
- WorkBuddy / CodeBuddy / Claude Code / Codex 的历史会话与记忆可扫描发现、按源导入(**只存路径指针,不复制内容**)、按源删除;导入侧+注入侧双重卫生闸门防外部脏数据混入。
143
-
144
- ### 记忆卫生(生产级写入门禁)
145
-
146
- - 三个写入工具全部过 `sanitizeForWrite`:GBK 乱码(34 特征全表)、复读退化、连续重复行、外部 AI 画像 JSON 特征、base64 残留——全部拒写并给出中文回执
147
- - 设置 → 调试中心「扫描脏 token」:一键扫描用户级/项目/日志/反思,按行区间报告问题(只报位置不含正文)
148
- - 追加 8000 字/条、全量改写 20 万字上限;追加前与文件尾部近 60 行做去重
149
-
150
- ### 记忆生命周期(30 天蒸馏与召回边界)
151
-
152
- `memory_maintain_pre` 把 30 天前的每日日志交给 AI 蒸馏:只提炼有跨会话长期价值的要点(技术决策/架构约定/偏好/踩坑规则),写入项目笔记;原文保底归档到 `archive/`(AI 不可用时降级为原样归档,绝不丢信息)。
153
-
154
- 需要知道的召回边界:**procedure skills(技能固化)与用户级/项目笔记永远不在蒸馏范围**——技能固化存在独立的记忆中枢存储,不受影响;蒸馏只处理日期命名的每日日志。归档后的原文不在词法/语义检索的常规扫描范围内(检索范围=项目笔记+活跃日志+反思+用户级记忆),但蒸馏要点已进入项目笔记、随注入常驻。理解为:蒸馏=主动把"过程流水"换成"可复用结论"的取舍。
155
-
156
- ### 工作区全景与跨区检索
157
-
158
- 面板「工作区」页签自动生成工作区关系图(AI 归纳主题与跨区关联,可拖拽/缩放/点卡片看详情);`memory_recall_pre` 天然跨工作区——检索结果标注来源工作区,其他项目的日志、笔记同样可达。
159
-
160
- ### AI 发散固化(memory_consolidate)
161
-
162
- 让 AI 通读今日/近期日志,发散提炼值得长期固化的要点并写入项目笔记——与自动沉淀互补:自动沉淀管"每轮结束记流水",consolidate 管"阶段性回头看什么值得升格"。
163
-
164
- ---
165
-
166
- ## 工程内核(保持克制的设计)
167
-
168
- - **零运行时依赖**:Node 内建模块之外无任何依赖
169
- - **前缀缓存友好**:提示词字节级稳定,DeepSeek 前缀缓存持续命中,不反复重编码历史
170
- - **限额 AI**:自动沉淀每日 ≤8 次带冷却,记忆有用但不烧预算
171
- - **集中式存储**:全部工作区记忆收在 `~/.dsh/memory/workspaces/` 一个根下,任意会话可读
172
- - **30 天蒸馏**:旧日志由 AI 蒸馏进项目笔记,原文归档不丢失
173
-
174
- ---
175
-
176
- ## 界面速览
177
-
178
- ### 记忆面板 · 概览(暂离问候 + AI 时段总结)
179
-
180
- <img width="480" alt="overview" src="docs/screenshots/panel-overview.png">
181
-
182
- ### 记忆中枢 · 三层记忆店与技能晋升审批
183
-
184
- <img width="480" alt="hub" src="docs/screenshots/panel-hub.png">
185
-
186
- ### 唤起回顾 · 每次激活决策可打分
187
-
188
- <img width="720" alt="refine" src="docs/screenshots/panel-refine.png">
189
-
190
- ### 欢迎向导 · 功能开关与引擎检测
191
-
192
- <img width="720" alt="tour" src="docs/screenshots/tour-toggles.png">
193
-
194
- <details>
195
- <summary><b>更多截图</b>(点击展开)</summary>
196
-
197
- ### 外部记忆扫描(欢迎向导内)
198
-
199
- <img width="720" alt="external scan" src="docs/screenshots/tour-external.png">
200
-
201
- ### 连接其他 AI 工具
202
-
203
- <img width="480" alt="connect" src="docs/screenshots/connect-zh.png">
204
-
205
- ### 日历视图
206
-
207
- <img width="480" alt="calendar" src="docs/screenshots/calendar-zh.png">
208
-
209
- ### 工作区关系图
210
-
211
- <img width="480" alt="workspace map" src="docs/screenshots/workspace-map-zh.png">
212
-
213
- ### 设置页
214
-
215
- <img width="480" alt="settings" src="docs/screenshots/settings-zh.png">
216
- <img width="480" alt="settings 2" src="docs/screenshots/settings-2-zh.png">
217
-
218
- </details>
219
-
220
- ---
221
-
222
- ## 安装(一条命令)
223
-
224
- > 前置:安装 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 并至少启动过一次 `dsh web`。
225
-
226
- 在 **profile 目录**(`~/.dsh/profiles/web`)执行:
227
-
228
- ```bash
229
- cd ~/.dsh/profiles/web
230
- pnpm add @a9i5k4/dsh-auto-memory
231
- ```
232
-
233
- ### 语义引擎(可选但推荐)
234
-
235
- 内置 JS 语义档(e5-small q8 ~130MB)需要推理库 `@huggingface/transformers`(随主包作为可选依赖自动安装)。若你的 pnpm 因安全策略拦截了它的原生脚本(提示 `ERR_PNPM_IGNORED_BUILDS` / `Ignored build scripts: onnxruntime-node, sharp`),执行一次批准后重装即可:
236
-
237
- ```bash
238
- # 批准 onnxruntime-node / sharp 的原生安装脚本,再重装 transformers
239
- pnpm approve-builds
240
- pnpm add @huggingface/transformers
241
- ```
242
-
243
- 装完重启 `dsh web`,向导的语义引擎步会自动检测到就绪(SHA256 校验 + 推理自检)。词法检索 0GB 永远兜底,不装也能用(仅召回精度较低)。
244
-
245
- 然后编辑同目录 `package.json`,在 `dsh.profile.bundles` 数组追加:
246
-
247
- ```json
248
- "@a9i5k4/dsh-auto-memory"
249
- ```
250
-
251
- 重启 **dsh web** 生效(侧边栏出现「记忆」入口)。
252
-
253
- > 没有 pnpm?`npm install @a9i5k4/dsh-auto-memory` 同样可用。
254
- > pnpm v11 限制安装发布不足 1 天的版本:当天发布想立即更新,在 profile 目录 `pnpm-workspace.yaml` 加 `minimumReleaseAge: 0`,或装显式版本。
255
-
256
- ### AI 时代安装法
257
-
258
- 复制下面这段发给你正在用的 AI 助手即可:
259
-
260
- ```text
261
- 在 DeepSeek Harness web profile 目录 ~/.dsh/profiles/web 安装 npm 包
262
- @a9i5k4/dsh-auto-memory(pnpm add 或 npm install),
263
- 把 "@a9i5k4/dsh-auto-memory" 追加到 package.json 的 dsh.profile.bundles 数组,
264
- 然后重启 dsh web 激活插件。
265
- ```
266
-
267
- ### 更新
268
-
269
- ```bash
270
- cd ~/.dsh/profiles/web && pnpm up @a9i5k4/dsh-auto-memory
271
- ```
272
-
273
- 设置 → 自动记忆页的「检查更新」按钮可比对 npm registry 最新版;registry 安装支持一键更新。
274
-
275
- ---
276
-
277
- ## 配置
278
-
279
- 配置文件 `~/.dsh/dsh-auto-memory.json`(GUI 设置页可视化调整,含中英文界面与面板字号):
280
-
281
- ```json
282
- {
283
- "userMemoryDir": "~/.dsh/memory",
284
- "memoryRoot": "~/.dsh/memory/workspaces",
285
- "injectEnabled": true,
286
- "injectBudgetChars": 2400,
287
- "recentDaysInjected": 1,
288
- "reflectEnabled": true,
289
- "autoConsolidate": true,
290
- "autoConsolidateCooldownMinutes": 30,
291
- "autoConsolidateDailyMax": 8,
292
- "unattendedMode": false,
293
- "unattendedAuto": false,
294
- "unattendedAutoHours": ["22:00-08:00"],
295
- "memoryHubEnabled": true,
296
- "externalSources": { "workbuddy-user": true, "claude-global": true },
297
- "dayBoundaryMinutes": 450
298
- }
299
- ```
300
-
301
- > 完整键位见设置页——每个开关都有中文说明;欢迎向导里的每个开关与设置页一一对应。
302
-
303
- ---
304
-
305
- ## 结构
306
-
307
- - `lib/index.js` — Host 半:引擎、注入、工具、路由(零运行时依赖)
308
- - `lib/client.js` — Browser 半:记忆面板(含日历/关系图)+ 设置页 + 欢迎向导(内置中英 i18n)
309
- - `python/` — 可选 Python 语义 sidecar(BGE-M3 int8,进阶档)
310
- - `cordis.patch.yml` — 插件注册行
311
-
312
- ## 系统架构
313
-
314
- 全部里程碑已实现并 live verified。完整交互式架构图见 [docs/proactive-associative-memory-system-map.html](docs/proactive-associative-memory-system-map.html),核心分层如下:
315
-
316
- ```
317
- DeepSeek Harness (Node, 127.0.0.1:3080)
318
- ├─ JS 记忆核心(lib/*_pre.js,零运行时依赖)
319
- │ M1 会话隔离 · M2 ContextObserver 投影
320
- │ M3 记忆锚定(anchored records + sidecar 身份)
321
- │ M4 语料适配 + 影子检索宿主(evidence store)
322
- │ M5 上下文/证据桥(envelope · coverage · cite/correction)
323
- │ M6 激活收件箱(校验→offer→claim→参考尾注渲染→delivered/seen)
324
- │ lexical_pre_v2 词法回退检索(BM25 + CJK 2gram,0GB 永远可用)
325
- │ C2 内置语义层(e5-small q8 ~130MB,默认档)
326
- └─ Python sidecar M7(可选,lazy spawn 子进程)
327
- worker_semantic_pre_v1.py
328
- ├─ index_sync:JS 授权分页建库(digest 校验,scope 分组)
329
- ├─ dense:BGE-M3 int8 + para-512 分块 + 余弦检索(R@5 0.925)
330
- ├─ hybrid:稠密 0.7 + 词法 0.3 融合
331
- └─ fv2 激活决策:两车道 + 硬门禁(echo/correction/stale/scope)
332
- ```
333
-
334
- **权限分立**:Python(语义层)决定"想起什么、何时建议";JS(权威层)决定身份、授权、时序、投递——Python 不创建证据,也不直接注入。数据流:`context_push → M5 envelope → 决策 → M6 固定边界注入 → delivered/seen 证据回流`。
335
-
336
- ### 技术论文与设计文献
337
-
338
- 本项目的设计不是拍脑袋——每项算法结论都来自可复现实验,并冻结为工程决策台账:
339
-
340
- | 文献 | 内容 |
341
- |---|---|
342
- | [多语言嵌入式检索选型研究](docs/M7-RESEARCH-PAPER.md) | 3 模型 × 5 分块策略 × 6 检索通道 ≈ 90 评测单元;BGE-M3 全面领先,冻结为 D1–D11 工程决策 |
343
- | [激活策略 v2:回声陷阱的发现、度量与修正](docs/M7-ACTIVATION-V2-PAPER.md) | 语义相关 ≠ 唤起必要的激活策略技术报告 + 双轨部署架构(§7) |
344
- | [嵌入基准报告](docs/M7-EMBEDDING-BENCHMARK.md) | 模型/分块/融合的冻结依据:bge-m3 + para-512-noov + 加权融合 |
345
- | [算法冻结决策 D1–D11](docs/M7-ALGORITHM-DECISION.md) | 全部研究结论到生产实现的决策台账 |
346
- | [Held-out 人工金标验收](docs/M7-ACTIVATION-V2-HOLDEDOUT-EVAL.md) | 67 条人工标注打分:actPrecision 0.917 / 有害注入 0 / echo 层 7/7 |
347
- | [Python Sidecar 完整契约](docs/PYTHON-SIDECAR-CONTRACT.md) | 协议/生命周期/权威边界/各里程碑回归证据 |
348
-
349
- 论文由自主工程 Agent(ZCode / GLM)撰写,全部结论在人类审核下冻结进生产实现。
350
-
351
- ## 已知限制
352
-
353
- - 记忆文件为纯文本 Markdown;除非明确要求,不存储密钥
354
- - `memory_recall` 会话搜索依赖已部署的 session-query 索引,缺失时仅本地检索可用
355
- - 插件增减需要重启 dsh 生效
356
-
357
- ---
358
-
359
- ## 社区致谢
360
-
361
- - [@ProperSAMA](https://github.com/ProperSAMA) DSH Desktop 增强模式(透明/Mica 材质)面板可读性修复 + 入口按钮防遮挡与外点/Esc 关闭([PR #12](https://github.com/Aik358/dsh-auto-memory/pull/12)
362
- - [@nkh0472](https://github.com/nkh0472) — 无人值守/批处理场景加固反馈,推动了欢迎向导与功能开关化([Issue #10](https://github.com/Aik358/dsh-auto-memory/issues/10))
363
-
364
- ---
365
-
366
- ## 制作署名
367
-
368
- 本项目由人与 AI 协作完成。除上述工程与社区贡献外:
369
-
370
- - **Aik358** — 项目所有者:产品方向、架构与工程决策。
371
- - **ZCode(GLM,智谱 Z.ai)** — 自主工程 Agent:M 系列语义引擎实现、两篇基准研究论文([M7 检索选型研究](docs/M7-RESEARCH-PAPER.md) / [激活策略 v2 技术报告](docs/M7-ACTIVATION-V2-PAPER.md))、全套回归测试、宣传网页设计与构建。
372
- - **Kimi K3(月之暗面)** — 前端 Agent:参与 v0.1.30 欢迎向导界面资产与视觉验收。
373
-
374
- AI Agent 作为研究论文作者与部分实现作者署名,全程在人类审核与指导下工作。
375
-
376
- ---
377
-
378
- ## 发布信息
379
-
380
- - GitHub: https://github.com/Aik358/dsh-auto-memory
381
- - npm: `@a9i5k4/dsh-auto-memory`
382
- - License: BSD-3-Clause
1
+ # dsh-auto-memory — DSH 自动记忆与人性化交互插件
2
+
3
+ <p align="center">
4
+ <a href="https://htmlpreview.github.io/?https://github.com/Aik358/dsh-auto-memory/blob/preview/docs/landing/index.html"><strong>🌐 宣传主页(功能全景 · 数据流 · 论文 · 截图)</strong></a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="docs/screenshots/promo/promo-0-banner-v2.png"><img width="820" alt="dsh-auto-memory 主视觉:不用吩咐,她自己记得" src="docs/screenshots/promo/promo-0-banner-v2.png"></a>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="docs/screenshots/promo/promo-0-banner-v2.png"><img width="130" alt="主视觉" src="docs/screenshots/promo/promo-0-banner-v2.png"></a>
13
+ <a href="docs/screenshots/promo/promo-2-tour.png"><img width="130" alt="欢迎向导" src="docs/screenshots/promo/promo-2-tour.png"></a>
14
+ <a href="docs/screenshots/promo/promo-3-recall.png"><img width="130" alt="唤起与固化" src="docs/screenshots/promo/promo-3-recall.png"></a>
15
+ <a href="docs/screenshots/promo/promo-4-unattended.png"><img width="130" alt="无人值守" src="docs/screenshots/promo/promo-4-unattended.png"></a>
16
+ <a href="docs/screenshots/promo/promo-5-external.png"><img width="130" alt="外部记忆继承" src="docs/screenshots/promo/promo-5-external.png"></a>
17
+ <a href="docs/screenshots/promo/promo-6-greeting.png"><img width="130" alt="定时问候" src="docs/screenshots/promo/promo-6-greeting.png"></a>
18
+ </p>
19
+ <p align="center"><sub>宣传图六幕 · 点击任意一张查看大图</sub></p>
20
+
21
+ <details>
22
+ <summary><b>宣传图分幕浏览</b>(点击展开,逐幕翻看)</summary>
23
+
24
+ #### 第一幕 · 主视觉 —— 不用吩咐,她自己记得
25
+
26
+ <p align="center"><img width="720" alt="主视觉" src="docs/screenshots/promo/promo-1-hero.png"></p>
27
+
28
+ #### 第二幕 · 欢迎向导 —— 每个功能,当场看懂、当场开关
29
+
30
+ <p align="center"><img width="720" alt="欢迎向导" src="docs/screenshots/promo/promo-2-tour.png"></p>
31
+
32
+ #### 第三幕 · 唤起与固化 —— 对话凝成技能,每一步有迹可循
33
+
34
+ <p align="center"><img width="720" alt="唤起与固化" src="docs/screenshots/promo/promo-3-recall.png"></p>
35
+
36
+ #### 第四幕 · 无人值守模式 —— 整夜安静跑,零寒暄,零打扰
37
+
38
+ <p align="center"><img width="720" alt="无人值守" src="docs/screenshots/promo/promo-4-unattended.png"></p>
39
+
40
+ #### 第五幕 · 外部记忆继承 —— 你的其他 AI,也在喂她记忆
41
+
42
+ <p align="center"><img width="720" alt="外部记忆继承" src="docs/screenshots/promo/promo-5-external.png"></p>
43
+
44
+ #### 第六幕 · 定时暖心问候 —— 让每一天都被记得
45
+
46
+ <p align="center"><img width="720" alt="定时问候" src="docs/screenshots/promo/promo-6-greeting.png"></p>
47
+
48
+ </details>
49
+
50
+ <p align="center">
51
+ <b>中文</b> · <a href="README.md">English</a> · License BSD-3-Clause · <code>pnpm add @a9i5k4/dsh-auto-memory</code>
52
+ </p>
53
+
54
+ > **v0.1.30 大更新** — 全新「欢迎向导」:分步介绍所有功能、当场开关;Office/Fluent 式液态玻璃应用图标族;更新日志开场动画;无人值守模式面向长批处理任务。
55
+
56
+ 一个为 DeepSeek Harness Web GUI 打造的**主动联想记忆插件**:不依赖模型主动调用,记忆在对话进行时被情境自动唤回并注入下一环节——同时三层记忆自动沉淀、AI 问候与每日反思、日历提醒、外部 AI 记忆继承,以及面向生产环境的无人值守/批处理支持。
57
+
58
+ **它解决的问题是**:AI 助手每次会话都从零开始,而现有的记忆方案都要求模型"记得去查"——调一次工具、发一次请求,忘了就没了。装上它之后,记忆的唤回不需要任何指令:Host 中间件持续观察对话情境,该想起的记忆自动走向模型;你的偏好、项目约定、昨天的进度、下周的截止日期,还有你回来时那声"欢迎回来",全部自然发生。
59
+
60
+ ---
61
+
62
+ 30 秒亮点
63
+
64
+ | | |
65
+ |---|---|
66
+ | **主动联想,零指令** | 记忆不靠模型调用——Host 观察情境自动唤回,经固定边界注入下一环节,前缀缓存友好 |
67
+ | **三层记忆引擎** | 用户级规则 → 项目笔记 → 每日日志,注入+按需检索 |
68
+ | **记忆自动沉淀** | 每轮对话结束由子代理静默判断去留,主题分组写入日志——你永远不需要记得"记一下" |
69
+ | **唤起有据可查** | 每次激活决策带完整证据链,唤起回顾页可复核打分;技能由跨会话证据渐进固化 |
70
+ | **主动式提醒** | AI 从对话中识别截止日期/约定,自动入日历并在后续会话中提醒 |
71
+ | **一切皆开关** | 欢迎向导+设置页双重入口,每个功能独立开关(含无人值守模式) |
72
+ | **外部记忆继承** | WorkBuddy / CodeBuddy / Claude Code / Codex 的历史记忆可扫描、导入、按源管理 |
73
+ | **生产级卫生** | 写入门禁(乱码/复读/JSON 注入拦截)+ 脏 token 扫描 + 凭证永不进提示词 |
74
+
75
+ ---
76
+
77
+ ## 欢迎向导(v0.1.30 新增)
78
+
79
+ 升级或首次安装后,插件会自动播放一段**分步欢迎向导**——这不是弹窗广告,而是功能总开关的集合地:
80
+
81
+ <p align="center"><img width="720" alt="welcome tour" src="docs/screenshots/tour-welcome.png"></p>
82
+
83
+ - **每步一枚 Office/Fluent 式液态玻璃应用图标**:注入青蓝、问候暖金、日历青绿、引擎紫蓝、雷达天青、完成珊瑚金——各配专属循环动效(铃摆动、日历翻页、雷达扫描、火花上升…)
84
+ - **每项功能当场开关**:开关即写配置立即生效,不需要再进设置页确认
85
+ - **语义引擎检测/下载内联**:三级检索引擎(词法 0GB 保底 → 内置语义 ~130MB → Python BGE-M3 进阶)在向导内自动检测、一键安装(SHA256 校验+推理自检)
86
+ - **外部记忆实时扫描**:本机可读的 WorkBuddy / Claude Code / Codex 等来源直接列出,逐源勾选
87
+ - **关不掉的困惑不存在**:中途关闭会先落到"完成提醒"步,告诉你每个功能在设置的哪个分区重新打开
88
+
89
+ <p align="center"><img width="720" alt="tour core" src="docs/screenshots/tour-core.png"></p>
90
+
91
+ 升级用户的一次性触达:v0.1.30 起所有用户升级后都会自动播放一次完整向导,结束后自动接更新日志(可点击跳过)。之后可随时在 **设置 → 外观 → 欢迎向导 → ▶ 重看引导** 重新打开。
92
+
93
+ ---
94
+
95
+ ## 三层记忆体系
96
+
97
+ | 层 | 位置 | 内容 |
98
+ |---|---|---|
99
+ | 用户级记忆 | `~/.dsh/memory/MEMORY.md` | 跨项目规则与偏好 |
100
+ | 项目笔记 | `~/.dsh/memory/workspaces/{workspace}/MEMORY.md` | 项目约定与决策 |
101
+ | 每日日志 | `~/.dsh/memory/workspaces/{workspace}/YYYY-MM-DD.md` | 追加式工作日志 |
102
+ | 每日反思 | `…/reflections/YYYY-MM-DD.md` | 结构化复盘(成果/教训/下一步) |
103
+
104
+ **注入策略**:静态纪律进 system prompt(字节级稳定,保前缀缓存命中);动态记忆走运行时快照——只注入最近 1 天日志+反思摘要,其余全部按需经 `memory_read` / `memory_recall` 取回。凭证/密钥段**永远被过滤在提示词之外**。
105
+
106
+ ---
107
+
108
+ ## 功能全景
109
+
110
+ ### 主动联想 — 不用吩咐,她自己记得
111
+
112
+ 这是插件与其他记忆方案的根本区别:**记忆唤回不依赖模型主动调用**。市面上的记忆工具要么要模型记得调一次检索工具,要么要用户手动粘贴上下文——忘了调,记忆就等于不存在。本插件是 Host 侧的主动联想中间件:持续观察对话情境与运行事件,相关记忆在模型开口之前就被检索、决策、并经固定边界注入下一环节(已发请求不可原地改写,前缀缓存永不失效)。同时权限分立:语义决策与身份/授权/时序治理由两层各自负责,每次投递都有证据链。
113
+
114
+ ### 自动沉淀 — 记忆自己写自己
115
+
116
+ 每轮对话结束后,一个小型子代理静默评估本轮内容:有长期价值的主题分组写入今日日志(`## 主题(HH:MM)`+要点),长期决策晋升项目笔记,跨项目规则晋升用户级记忆,闲聊跳过,失败进队列每 5 分钟重试(15 秒心跳文件证明循环存活)。每日写入有预算与自动压缩(超限不拒写,AI 合并去重后写入)。
117
+
118
+ ### 唤起与固化 — 该出手时才出手
119
+
120
+ 联想式记忆唤起在对话链中检测回忆需求,命中即注入下一环节(不破坏前缀缓存);高频流程固化为技能 checklist,匹配对话自动附上,跨会话验证后晋升(记忆中枢页审批,90 天未用自动归档可置顶)。**每一次"要不要打断你"的决策都能在「唤起回顾」页复核打分**(A 该激活 / P 只预取 / S 应抑制 / H 有害 / E 改目标),判定队列会汇总成政策提示。
121
+
122
+ <p align="center"><img width="720" alt="refine" src="docs/screenshots/panel-refine.png"></p>
123
+
124
+ ### 无人值守模式 — 面向批处理任务
125
+
126
+ 长跑批处理/自动化流水线?设置 → 自动化提供**无人值守模式**与**夜间自动托管**(22:00-08:00 可调)。托管期间:不注入欢迎语/寒暄/行为指令、日历提醒静默、上下文保持稳定——模型专注干活,token 花在正事上。
127
+
128
+ ### AI 问候与每日反思
129
+
130
+ 按时段(晨/午/晚)生成提及你当日最重要工作的问候;暂离超过 1 小时回来,记忆面板自动打开并送上"欢迎回来"+近期工作摘要;每天第一次会话主动呈现前一日结构化反思。
131
+
132
+ ### 智能检索
133
+
134
+ 自然语言提问,AI 自动扩展关键词扫描全部记忆层,会话式回答并标注来源;支持跨工作区检索。
135
+
136
+ ### 日历 — AI 替你维护
137
+
138
+ AI 从对话中识别截止日期/约定自动入日历(`calendar_add`),未完成事项注入后续会话直到完成;日视图 07:00-22:00 时间轴、地点/提醒字段、紧急度语义色。
139
+
140
+ ### 外部记忆继承
141
+
142
+ WorkBuddy / CodeBuddy / Claude Code / Codex 的历史会话与记忆可扫描发现、按源导入(**只存路径指针,不复制内容**)、按源删除;导入侧+注入侧双重卫生闸门防外部脏数据混入。
143
+
144
+ ### 记忆卫生(生产级写入门禁)
145
+
146
+ - 三个写入工具全部过 `sanitizeForWrite`:GBK 乱码(34 特征全表)、复读退化、连续重复行、外部 AI 画像 JSON 特征、base64 残留——全部拒写并给出中文回执
147
+ - 设置 → 调试中心「扫描脏 token」:一键扫描用户级/项目/日志/反思,按行区间报告问题(只报位置不含正文)
148
+ - 追加 8000 字/条、全量改写 20 万字上限;追加前与文件尾部近 60 行做去重
149
+
150
+ ### 记忆生命周期(30 天蒸馏与召回边界)
151
+
152
+ `memory_maintain_pre` 把 30 天前的每日日志交给 AI 蒸馏:只提炼有跨会话长期价值的要点(技术决策/架构约定/偏好/踩坑规则),写入项目笔记;原文保底归档到 `archive/`(AI 不可用时降级为原样归档,绝不丢信息)。
153
+
154
+ 需要知道的召回边界:**procedure skills(技能固化)与用户级/项目笔记永远不在蒸馏范围**——技能固化存在独立的记忆中枢存储,不受影响;蒸馏只处理日期命名的每日日志。归档后的原文不在词法/语义检索的常规扫描范围内(检索范围=项目笔记+活跃日志+反思+用户级记忆),但蒸馏要点已进入项目笔记、随注入常驻。理解为:蒸馏=主动把"过程流水"换成"可复用结论"的取舍。
155
+
156
+ ### 工作区全景与跨区检索
157
+
158
+ 面板「工作区」页签自动生成工作区关系图(AI 归纳主题与跨区关联,可拖拽/缩放/点卡片看详情);`memory_recall_pre` 天然跨工作区——检索结果标注来源工作区,其他项目的日志、笔记同样可达。
159
+
160
+ ### AI 发散固化(memory_consolidate)
161
+
162
+ 让 AI 通读今日/近期日志,发散提炼值得长期固化的要点并写入项目笔记——与自动沉淀互补:自动沉淀管"每轮结束记流水",consolidate 管"阶段性回头看什么值得升格"。
163
+
164
+ ---
165
+
166
+ ## 工程内核(保持克制的设计)
167
+
168
+ - **零运行时依赖**:Node 内建模块之外无任何依赖
169
+ - **前缀缓存友好**:提示词字节级稳定,DeepSeek 前缀缓存持续命中,不反复重编码历史
170
+ - **限额 AI**:自动沉淀每日 ≤8 次带冷却,记忆有用但不烧预算
171
+ - **集中式存储**:全部工作区记忆收在 `~/.dsh/memory/workspaces/` 一个根下,任意会话可读
172
+ - **30 天蒸馏**:旧日志由 AI 蒸馏进项目笔记,原文归档不丢失
173
+
174
+ ---
175
+
176
+ ## 界面速览
177
+
178
+ ### 记忆面板 · 概览(暂离问候 + AI 时段总结)
179
+
180
+ <img width="480" alt="overview" src="docs/screenshots/panel-overview.png">
181
+
182
+ ### 记忆中枢 · 三层记忆店与技能晋升审批
183
+
184
+ <img width="480" alt="hub" src="docs/screenshots/panel-hub.png">
185
+
186
+ ### 唤起回顾 · 每次激活决策可打分
187
+
188
+ <img width="720" alt="refine" src="docs/screenshots/panel-refine.png">
189
+
190
+ ### 欢迎向导 · 功能开关与引擎检测
191
+
192
+ <img width="720" alt="tour" src="docs/screenshots/tour-toggles.png">
193
+
194
+ <details>
195
+ <summary><b>更多截图</b>(点击展开)</summary>
196
+
197
+ ### 外部记忆扫描(欢迎向导内)
198
+
199
+ <img width="720" alt="external scan" src="docs/screenshots/tour-external.png">
200
+
201
+ ### 连接其他 AI 工具
202
+
203
+ <img width="480" alt="connect" src="docs/screenshots/connect-zh.png">
204
+
205
+ ### 日历视图
206
+
207
+ <img width="480" alt="calendar" src="docs/screenshots/calendar-zh.png">
208
+
209
+ ### 工作区关系图
210
+
211
+ <img width="480" alt="workspace map" src="docs/screenshots/workspace-map-zh.png">
212
+
213
+ ### 设置页
214
+
215
+ <img width="480" alt="settings" src="docs/screenshots/settings-zh.png">
216
+ <img width="480" alt="settings 2" src="docs/screenshots/settings-2-zh.png">
217
+
218
+ </details>
219
+
220
+ ---
221
+
222
+ ## 安装(一条命令)
223
+
224
+ > 前置:安装 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 并至少启动过一次 `dsh web`。
225
+
226
+ 在 **profile 目录**(`~/.dsh/profiles/web`)执行:
227
+
228
+ ```bash
229
+ cd ~/.dsh/profiles/web
230
+ pnpm add @a9i5k4/dsh-auto-memory
231
+ ```
232
+
233
+ ### 语义引擎(可选但推荐)
234
+
235
+ 内置 JS 语义档(e5-small q8 ~130MB)需要推理库 `@huggingface/transformers`(随主包作为可选依赖自动安装)。若你的 pnpm 因安全策略拦截了它的原生脚本(提示 `ERR_PNPM_IGNORED_BUILDS` / `Ignored build scripts: onnxruntime-node, sharp`),执行一次批准后重装即可:
236
+
237
+ ```bash
238
+ # 批准 onnxruntime-node / sharp 的原生安装脚本,再重装 transformers
239
+ pnpm approve-builds
240
+ pnpm add @huggingface/transformers
241
+ ```
242
+
243
+ 装完重启 `dsh web`,向导的语义引擎步会自动检测到就绪(SHA256 校验 + 推理自检)。词法检索 0GB 永远兜底,不装也能用(仅召回精度较低)。
244
+
245
+ 然后编辑同目录 `package.json`,在 `dsh.profile.bundles` 数组追加:
246
+
247
+ ```json
248
+ "@a9i5k4/dsh-auto-memory"
249
+ ```
250
+
251
+ 重启 **dsh web** 生效(侧边栏出现「记忆」入口)。
252
+
253
+ > 没有 pnpm?`npm install @a9i5k4/dsh-auto-memory` 同样可用。
254
+ > pnpm v11 限制安装发布不足 1 天的版本:当天发布想立即更新,在 profile 目录 `pnpm-workspace.yaml` 加 `minimumReleaseAge: 0`,或装显式版本。
255
+
256
+ ### AI 时代安装法
257
+
258
+ 复制下面这段发给你正在用的 AI 助手即可:
259
+
260
+ ```text
261
+ 在 DeepSeek Harness web profile 目录 ~/.dsh/profiles/web 安装 npm 包
262
+ @a9i5k4/dsh-auto-memory(pnpm add 或 npm install),
263
+ 把 "@a9i5k4/dsh-auto-memory" 追加到 package.json 的 dsh.profile.bundles 数组,
264
+ 然后重启 dsh web 激活插件。
265
+ ```
266
+
267
+ ### 更新
268
+
269
+ ```bash
270
+ cd ~/.dsh/profiles/web && pnpm up @a9i5k4/dsh-auto-memory
271
+ ```
272
+
273
+ 设置 → 自动记忆页的「检查更新」按钮可比对 npm registry 最新版;registry 安装支持一键更新。
274
+
275
+ ---
276
+
277
+ ## 配置
278
+
279
+ 配置文件 `~/.dsh/dsh-auto-memory.json`(GUI 设置页可视化调整,含中英文界面与面板字号):
280
+
281
+ ```json
282
+ {
283
+ "userMemoryDir": "~/.dsh/memory",
284
+ "memoryRoot": "~/.dsh/memory/workspaces",
285
+ "injectEnabled": true,
286
+ "injectBudgetChars": 2400,
287
+ "recentDaysInjected": 1,
288
+ "reflectEnabled": true,
289
+ "autoConsolidate": true,
290
+ "autoConsolidateCooldownMinutes": 30,
291
+ "autoConsolidateDailyMax": 8,
292
+ "unattendedMode": false,
293
+ "unattendedAuto": false,
294
+ "unattendedAutoHours": ["22:00-08:00"],
295
+ "memoryHubEnabled": true,
296
+ "externalSources": { "workbuddy-user": true, "claude-global": true },
297
+ "dayBoundaryMinutes": 450
298
+ }
299
+ ```
300
+
301
+ > 完整键位见设置页——每个开关都有中文说明;欢迎向导里的每个开关与设置页一一对应。
302
+
303
+ ---
304
+
305
+ ## 结构
306
+
307
+ - `lib/index.js` — Host 半:引擎、注入、工具、路由(零运行时依赖)
308
+ - `lib/client.js` — Browser 半:记忆面板(含日历/关系图)+ 设置页 + 欢迎向导(内置中英 i18n)
309
+ - `python/` — 可选 Python 语义 sidecar(BGE-M3 int8,进阶档)
310
+ - `cordis.patch.yml` — 插件注册行
311
+
312
+ ## 系统架构
313
+
314
+ 全部里程碑已实现并 live verified。完整交互式架构图见 [docs/proactive-associative-memory-system-map.html](docs/proactive-associative-memory-system-map.html),核心分层如下:
315
+
316
+ ```
317
+ DeepSeek Harness (Node, 127.0.0.1:3080)
318
+ ├─ JS 记忆核心(lib/*_pre.js,零运行时依赖)
319
+ │ M1 会话隔离 · M2 ContextObserver 投影
320
+ │ M3 记忆锚定(anchored records + sidecar 身份)
321
+ │ M4 语料适配 + 影子检索宿主(evidence store)
322
+ │ M5 上下文/证据桥(envelope · coverage · cite/correction)
323
+ │ M6 激活收件箱(校验→offer→claim→参考尾注渲染→delivered/seen)
324
+ │ lexical_pre_v2 词法回退检索(BM25 + CJK 2gram,0GB 永远可用)
325
+ │ C2 内置语义层(e5-small q8 ~130MB,默认档)
326
+ └─ Python sidecar M7(可选,lazy spawn 子进程)
327
+ worker_semantic_pre_v1.py
328
+ ├─ index_sync:JS 授权分页建库(digest 校验,scope 分组)
329
+ ├─ dense:BGE-M3 int8 + para-512 分块 + 余弦检索(R@5 0.925)
330
+ ├─ hybrid:稠密 0.7 + 词法 0.3 融合
331
+ └─ fv2 激活决策:两车道 + 硬门禁(echo/correction/stale/scope)
332
+ ```
333
+
334
+ **权限分立**:Python(语义层)决定"想起什么、何时建议";JS(权威层)决定身份、授权、时序、投递——Python 不创建证据,也不直接注入。数据流:`context_push → M5 envelope → 决策 → M6 固定边界注入 → delivered/seen 证据回流`。
335
+
336
+ ### 技术论文与设计文献
337
+
338
+ 本项目的设计不是拍脑袋——每项算法结论都来自可复现实验,并冻结为工程决策台账:
339
+
340
+ | 文献 | 内容 |
341
+ |---|---|
342
+ | [多语言嵌入式检索选型研究](docs/M7-RESEARCH-PAPER.md) | 3 模型 × 5 分块策略 × 6 检索通道 ≈ 90 评测单元;BGE-M3 全面领先,冻结为 D1–D11 工程决策 |
343
+ | [激活策略 v2:回声陷阱的发现、度量与修正](docs/M7-ACTIVATION-V2-PAPER.md) | 语义相关 ≠ 唤起必要的激活策略技术报告 + 双轨部署架构(§7) |
344
+ | [嵌入基准报告](docs/M7-EMBEDDING-BENCHMARK.md) | 模型/分块/融合的冻结依据:bge-m3 + para-512-noov + 加权融合 |
345
+ | [算法冻结决策 D1–D11](docs/M7-ALGORITHM-DECISION.md) | 全部研究结论到生产实现的决策台账 |
346
+ | [Held-out 人工金标验收](docs/M7-ACTIVATION-V2-HOLDEDOUT-EVAL.md) | 67 条人工标注打分:actPrecision 0.917 / 有害注入 0 / echo 层 7/7 |
347
+ | [Python Sidecar 完整契约](docs/PYTHON-SIDECAR-CONTRACT.md) | 协议/生命周期/权威边界/各里程碑回归证据 |
348
+
349
+ 论文由自主工程 Agent(ZCode / GLM)撰写,全部结论在人类审核下冻结进生产实现。
350
+
351
+ ## 已知限制
352
+
353
+ - 记忆文件为纯文本 Markdown;除非明确要求,不存储密钥
354
+ - `memory_recall` 会话搜索依赖已部署的 session-query 索引,缺失时仅本地检索可用
355
+ - 插件增减需要重启 dsh 生效
356
+
357
+ ---
358
+
359
+ ## 社区致谢
360
+
361
+ **反馈与交流:**欢迎加入 QQ 交流群——[点击加入 dsh-auto-memory 交流群](https://qm.qq.com/q/v7Asxn6vPa)——问题反馈、使用技巧交流,响应比 issue 更快。
362
+
363
+ 社区贡献者:
364
+
365
+ - [@ProperSAMA](https://github.com/ProperSAMA) — DSH Desktop 增强模式(透明/Mica 材质)面板可读性修复 + 入口按钮防遮挡与外点/Esc 关闭([PR #12](https://github.com/Aik358/dsh-auto-memory/pull/12))
366
+ - [@nkh0472](https://github.com/nkh0472) — 无人值守/批处理场景加固反馈,推动了欢迎向导与功能开关化([Issue #10](https://github.com/Aik358/dsh-auto-memory/issues/10))
367
+
368
+ ---
369
+
370
+ ## 制作署名
371
+
372
+ 本项目由人与 AI 协作完成。除上述工程与社区贡献外:
373
+
374
+ - **Aik358** — 项目所有者:产品方向、架构与工程决策。
375
+ - **ZCode(GLM,智谱 Z.ai)** — 自主工程 Agent:M 系列语义引擎实现、两篇基准研究论文([M7 检索选型研究](docs/M7-RESEARCH-PAPER.md) / [激活策略 v2 技术报告](docs/M7-ACTIVATION-V2-PAPER.md))、全套回归测试、宣传网页设计与构建。
376
+ - **Kimi K3(月之暗面)** — 前端 Agent:参与 v0.1.30 欢迎向导界面资产与视觉验收。
377
+
378
+ AI Agent 作为研究论文作者与部分实现作者署名,全程在人类审核与指导下工作。
379
+
380
+ ---
381
+
382
+ ## 发布信息
383
+
384
+ - GitHub: https://github.com/Aik358/dsh-auto-memory
385
+ - npm: `@a9i5k4/dsh-auto-memory`
386
+ - License: BSD-3-Clause
package/lib/client.js CHANGED
@@ -191,14 +191,6 @@ window.__ModuleLoader__.load({
191
191
  kvAvail: '可用', kvUnavail: '不可用', kvDup: '项目笔记重复标题', kvDupCount: ' 个',
192
192
  kvMem: '记忆文件', kvMemUser: '用户', kvMemNotes: '笔记', kvMemLog: '日志', kvMemMissing: '缺失',
193
193
  kvWs: '当前工作区', kvWsUnknown: '(未取到)', kvApi: 'API 连通', unknown: '(未知)',
194
- guideTitle: '欢迎使用 dsh-auto-memory', guideSub: '这个插件能干什么:',
195
- gFeat1: '三层记忆自动注入与检索:用户级 / 项目笔记 / 每日日志,每轮对话自动读、自动写',
196
- gFeat2: '每轮对话结束自动沉淀:修了什么 bug、做了哪些决策,自动按主题写进今日日志',
197
- gFeat3: 'AI 时段问候与三级抽屉:打开「记忆」面板,AI 按时段向你汇报当天进展',
198
- gFeat4: '智能检索与日历:自然语言提问找记忆;AI 自动把 deadline 记进日历并提醒',
199
- gFeat5: '接续其他 AI 工具的记忆:CodeBuddy / Claude Code / Codex 等的历史记忆一键接入',
200
- gFeat6: '自动检查更新:启动时检测新版本,设置页可一键更新',
201
- guideTip: '打开侧边栏「记忆」按钮即可使用;所有记忆都是本地明文文件,可随时查看修改。',
202
194
  updateTitle: 'dsh-auto-memory 已更新', updateSub: '本次更新内容:', gotIt: '知道了', noticeOpen: '了解更多',
203
195
  refresh: '刷新', refreshing: '刷新中…', close: '关闭', dragMove: '拖动移动', dragResize: '拖动调整大小', resetPos: '恢复默认位置',
204
196
  generated: '已生成', failed: '失败: ',
@@ -330,14 +322,6 @@ window.__ModuleLoader__.load({
330
322
  kvAvail: 'available', kvUnavail: 'unavailable', kvDup: 'Duplicate note headings', kvDupCount: '',
331
323
  kvMem: 'Memory files', kvMemUser: 'user', kvMemNotes: 'notes', kvMemLog: 'log', kvMemMissing: 'missing',
332
324
  kvWs: 'Current workspace', kvWsUnknown: '(unknown)', kvApi: 'API probes', unknown: '(unknown)',
333
- guideTitle: 'Welcome to dsh-auto-memory (pre)', guideSub: 'What this plugin does:',
334
- gFeat1: 'Three-layer memory with automatic injection & retrieval: user / project notes / daily logs',
335
- gFeat2: 'Auto-consolidation after every turn: bugs fixed and decisions made are written into today\'s log automatically',
336
- gFeat3: 'AI period greetings with three-level drawers: open the Memory panel for a period-by-period digest',
337
- gFeat4: 'Smart search & calendar: ask in natural language; AI files deadlines into the calendar and reminds you',
338
- gFeat5: 'Inherit memories from other AI tools: CodeBuddy / Claude Code / Codex etc. in one click',
339
- gFeat6: 'Auto update check at boot, one-click update in settings',
340
- guideTip: 'Click the Memory button in the sidebar to start; all memories are plain local Markdown files you can inspect anytime.',
341
325
  updateTitle: 'dsh-auto-memory Updated', updateSub: 'What\'s new in this update:', gotIt: 'Got it', noticeOpen: 'Learn more',
342
326
  refresh: 'Refresh', refreshing: 'Refreshing…', close: 'Close', dragMove: 'Drag to move', dragResize: 'Drag to resize', resetPos: 'Reset position',
343
327
  generated: 'Generated', failed: 'Failed: ',
@@ -497,6 +481,9 @@ window.__ModuleLoader__.load({
497
481
  '补丁 0.1.34:修复推理库检测——pnpm 把 transformers 提升到 profile 根 node_modules,检测补该路径,新用户装完即用,无需手动操作。',
498
482
  '补丁 0.1.37:修复「弹窗关不掉」(#13,感谢 @eclgo 报告)——暂离回归面板只在 away→active 翻转时弹一次;0.1.36 起回归检测全局化后,回归前(尚未发消息)面板会被每 30 秒强制重开,现已根治。',
499
483
  '补丁 0.1.37:修复语义引擎「推理库缺失」误报 (#14,感谢 @moonltppt 报告)——推理库探测改用 Node 真实解析,覆盖 npm/pnpm(hoisted/isolated)全部安装布局;并新增「打开即自动检测」:检测不到自动深度扫描(~/.dsh/profiles 全家 + pnpm 虚拟存储),命中即热接入(无需重启),仍缺才推荐安装/一键下载,推荐卡 24 小时免打扰。',
484
+ '补丁 0.1.38:修复新装首启弹的不是启动向导——删除旧的静态欢迎卡(内容与完整向导重复、且小卡形态无关闭按钮);全新安装首次打开直接进入完整欢迎向导(分步功能开关+引擎检测/下载引导),老用户按版本与向导完成态自动补看。',
485
+ '补丁 0.1.39:修复动态记忆内容含 {{...}} 模板变量时整轮运行失败(malformed prompt variable reference)——记忆/日志等注入内容已在全部出口中和为全角括号,模板引擎零命中,展示效果不变。',
486
+ '提示:这是 0.1.x 稳定线的最终稳定版本,此后仅针对 issue 做稳定性更新;全新版本将在未来两周内发布,工作重心为对标 GPT-6 Astra「上下文管理」的新能力——结构化任务笔记跨窗口交接、历史归档可搜索、按需主动检索。',
500
487
  ], en: [
501
488
  '★ MAJOR: Brand-new Welcome Tour — after first launch or upgrade, every feature is introduced step by step with per-feature switches right in the tour (association / snapshot / greeting / night unattended / reflection / summaries / external memory / skill promotion…); engine detection, download, self-test and live external-source scanning are all inline.',
502
489
  '★ New brand visuals: an Office/Fluent-style liquid-glass app icon family — each step gets its own colored glass squircle icon (cyan inject / amber greeting / green calendar / violet engine / sky radar / coral finish) with dedicated looping motion (bell sway, page flip, linked rings, prism spin, radar sweep, rising spark); the signature three-slab frosted-glass logo stays on the Core step.',
@@ -512,6 +499,9 @@ window.__ModuleLoader__.load({
512
499
  'Patch 0.1.34: fixed inference-lib detection — pnpm hoists transformers to the profile-root node_modules; detection now covers that path, so fresh installs work out of the box.',
513
500
  'Patch 0.1.37: fixed the "popup cannot be closed" loop (#13, thanks @eclgo) — the welcome-back panel now opens only on the away→active transition; since 0.1.36 globalised away detection, the panel was force-reopened every 30s until the first message after returning. Root-caused and fixed.',
514
501
  'Patch 0.1.37: fixed the false "inference runtime missing" state (#14, thanks @moonltppt) — runtime detection now uses real Node resolution, covering npm/pnpm (hoisted/isolated) layouts; plus a new check-on-open flow: when not detected, a deep scan (~/.dsh/profiles + pnpm virtual store) runs automatically and hot-wires hits with no restart; only if still missing does it recommend installing / one-click download, with a 24h snooze.',
502
+ 'Patch 0.1.38: fixed first-run opening the legacy static welcome card instead of the tour (duplicate content, no close button in the compact card) — the card is removed; fresh installs now go straight into the full welcome tour (per-feature switches + engine detect/download), and existing users get the tour replayed based on version and tour state.',
503
+ 'Patch 0.1.39: fixed whole-turn failures (malformed prompt variable reference) when dynamic memory content contained {{...}} template variables — injected memories/logs/reflections are now neutralized to full-width braces at every exit; the template engine never sees them and display is unchanged.',
504
+ 'Note: this is the final stable release of the 0.1.x line; only issue-driven stability updates will follow. The next version ships within two weeks, focused on GPT-6 Astra-style context management — structured task notes handed off across windows, searchable history archive, and on-demand retrieval.',
515
505
  ] },
516
506
  '0.1.29': { zh: [
517
507
  '修复:工作区总览一直显示「未发现带记忆的工作区」——DSH 新版会话持久化改为 session.jsonl.zstd 压缩帧,旧逻辑只认 .jsonl 扫描不到任何会话;现已用 zstd 解压读取首行提取 cwd,并让空的 summary 缓存短时失效,避免空结果被永久固化。',
@@ -652,7 +642,6 @@ window.__ModuleLoader__.load({
652
642
  function dialogPriority(d) {
653
643
  if (!d) return 0
654
644
  if (d.kind === 'update') return 100
655
- if (d.kind === 'first') return 90
656
645
  if (d.kind === 'welcomeTour') return 85
657
646
  if (d.kind === 'modelDownload') return 85
658
647
  if (d.kind === 'notice') return d.notice && d.notice.level === 'urgent' ? 80 : 70
@@ -2597,7 +2586,6 @@ window.__ModuleLoader__.load({
2597
2586
  // 通用开场舞台必须在 first/notice/update 三个分支之前完成赋值;var 只提升声明、不提升赋值。
2598
2587
  var skipUpdateIntro = function () { setUpdateSkip(true) }
2599
2588
  var introEligible = dialogState.kind === 'update' ||
2600
- dialogState.kind === 'first' ||
2601
2589
  (dialogState.kind === 'notice' && !((dialogState.notice || {}).level === 'urgent'))
2602
2590
  var DamIntroBox = function (children) {
2603
2591
  if (!introEligible) return children
@@ -2615,56 +2603,6 @@ window.__ModuleLoader__.load({
2615
2603
  !updateSkip ? h('div', { 'data-dam-update-click': '', onClick: skipUpdateIntro }) : null,
2616
2604
  h('div', { 'data-dam-update-content': '' }, children))
2617
2605
  }
2618
- if (dialogState.kind === 'first') {
2619
- var feats = [t('gFeat1'), t('gFeat2'), t('gFeat3'), t('gFeat4'), t('gFeat5'), t('gFeat6')]
2620
- // M7.5:语义引擎资产检测(模块级缓存,避免重复请求;SLIDES 扩展点见下方渲染块)
2621
- var semStatus = window['dsh-auto-memory.semStatus']
2622
- if (!semStatus) {
2623
- semStatus = { status: 'checking' }
2624
- window['dsh-auto-memory.semStatus'] = semStatus
2625
- fetch('/api/dsh-auto-memory/semantic-status').then(function (r) { return r.json() }).then(function (j) {
2626
- semStatus.status = j.ready ? 'ready' : 'missing'
2627
- try { dlgTick() } catch (e9) {}
2628
- }).catch(function () { semStatus.status = 'unknown' })
2629
- }
2630
- var firstButton = h('button', { 'data-dam-btn': '', style: close, onClick: function () {
2631
- try {
2632
- localStorage.setItem('dsh-auto-memory.firstRunDone', '1')
2633
- if (dialogState && dialogState.currentVersion) localStorage.setItem('dsh-auto-memory.seenVersion', dialogState.currentVersion)
2634
- // 规范 F2(RELEASE-SEMANTIC-OPTION.md):首启关闭后进入「欢迎向导」
2635
- // (分步介绍+内联检测/下载;受设置 welcomeTourEnabled 门控,默认开)。
2636
- fetch('/api/dsh-auto-memory/config').then(function (r) { return r.json() }).then(function (cj) {
2637
- var cc = (cj && cj.config) || cj || {}
2638
- if (cc.welcomeTourEnabled !== false && !localStorage.getItem('dsh-auto-memory.semWizardDone')) {
2639
- openDialog({ kind: 'welcomeTour' })
2640
- } else {
2641
- try { localStorage.setItem('dsh-auto-memory.semWizardDone', '1') } catch (e5) {}
2642
- }
2643
- }).catch(function () {
2644
- if (!localStorage.getItem('dsh-auto-memory.semWizardDone')) openDialog({ kind: 'welcomeTour' })
2645
- })
2646
- } catch (e3) {}
2647
- closeDialog()
2648
- } }, t('gotIt'))
2649
- var firstChildren = [
2650
- h('div', { style: head }, t('guideTitle')),
2651
- h('div', { style: sub }, t('guideSub')),
2652
- feats.map(function (f) { return h('div', { style: item }, h('span', { style: dot }), f) }),
2653
- // M7.5 首启扩展点(SLIDES):新功能引导在此按序追加;当前块=内置语义引擎自动检测。
2654
- (function () {
2655
- var boxS = { margin: '8px 0 4px', padding: '8px 10px', borderRadius: '10px', border: '1px solid color-mix(in srgb, var(--dsw-alias-border-l1, rgba(128,128,128,.35)) 50%, transparent)', fontSize: 'calc(11px * var(--dam-scale))', lineHeight: 1.55 }
2656
- var st = semStatus
2657
- if (!st || st.status === 'checking') return h('div', { style: boxS }, locale === 'zh' ? '正在检测内置语义引擎…' : 'Detecting built-in semantic engine…')
2658
- if (st.status === 'ready') return h('div', { style: boxS }, '✓ ' + (locale === 'zh' ? '内置语义引擎已就绪(本地运行,记忆不出电脑)。可在「记忆」面板设置中切换检索模式。' : 'Built-in semantic engine ready (local-only). Switchable in Memory panel settings.'))
2659
- return h('div', { style: boxS }, locale === 'zh' ? '可选:内置语义引擎未下载(约130MB)。在「记忆」面板设置中可随时启用;未启用时词法检索照常可用。' : 'Optional: built-in semantic engine not downloaded (~130MB). Enable anytime in Memory panel settings; lexical search keeps working.')
2660
- })(),
2661
- h('div', { style: { fontSize: 'calc(12px * var(--dam-scale))', opacity: .8, marginTop: '4px' } }, t('guideTip')),
2662
- firstButton,
2663
- ]
2664
- return h('div', { style: overlay },
2665
- h('div', { style: box },
2666
- DamIntroBox(firstChildren)))
2667
- }
2668
2606
  if (dialogState.kind === 'welcomeTour' || dialogState.kind === 'modelDownload') {
2669
2607
  // 首启引导向导 v2(2026-08-31):分步功能全覆盖 + 步内功能开关(点击即时写配置)
2670
2608
  // + 完成步提醒「随时可在设置的哪个分区重新打开」。跳过/✕ 也先落到完成步(提醒)。
@@ -3018,7 +2956,10 @@ window.__ModuleLoader__.load({
3018
2956
  h('div', { style: box },
3019
2957
  // 右上 ✕ 关闭(与小卡 46vh 裁剪下的底部按钮互为兜底——否则内容溢出时按钮不可达,弹窗关不掉)
3020
2958
  h('button', { 'data-dam-btn': '', title: t('close'), onClick: function () {
3021
- try { if (lastV) localStorage.setItem('dsh-auto-memory.seenVersion', lastV) } catch (eX) {}
2959
+ // 0.1.39:关闭时把 seenVersion 记为 currentVersion(分发时传的当前安装版本),
2960
+ // 而非卡片 lastV——0.1.30 大更新单卡的 lastV 恒 '0.1.30',会把 seen 钉回旧版本,
2961
+ // 导致「每次打开都弹更新日志」(seen≠current 无限重弹)。
2962
+ try { var seenV = (dialogState && dialogState.currentVersion) || lastV; if (seenV) localStorage.setItem('dsh-auto-memory.seenVersion', seenV) } catch (eX) {}
3022
2963
  closeDialog()
3023
2964
  }, style: { position: 'absolute', top: '8px', right: '10px', zIndex: 5, fontSize: 'calc(13px * var(--dam-scale))', opacity: .6 } }, '✕'),
3024
2965
  DamIntroBox([
@@ -3031,7 +2972,8 @@ window.__ModuleLoader__.load({
3031
2972
  items.map(function (it) { return h('div', { style: item }, h('span', { style: dot }), it) }))
3032
2973
  }),
3033
2974
  h('button', { 'data-dam-btn': '', style: close, onClick: function () {
3034
- try { if (lastV) localStorage.setItem('dsh-auto-memory.seenVersion', lastV) } catch (e3) {}
2975
+ // ✕:写 currentVersion 而非 lastV(见上方 0.1.39 说明)
2976
+ try { var seenV2 = (dialogState && dialogState.currentVersion) || lastV; if (seenV2) localStorage.setItem('dsh-auto-memory.seenVersion', seenV2) } catch (e3) {}
3035
2977
  closeDialog()
3036
2978
  } }, t('gotIt'))])))
3037
2979
  }
@@ -3479,7 +3421,11 @@ window.__ModuleLoader__.load({
3479
3421
  h('button', { 'data-dam-btn': '', onClick: checkUpdate, disabled: checkingUpdate }, checkingUpdate ? t('checking') : t('checkUpdate')),
3480
3422
  (verInfo && verInfo.latest && !verInfo.upToDate && verInfo.installKind === 'registry') ? h('button', { 'data-dam-btn': '', onClick: doUpdate, disabled: upBusy, style: { marginLeft: '4px' } }, upBusy ? t('updating') : t('updateNow')) : null,
3481
3423
  upMsg ? h('span', { 'data-dam-hint': '' }, upMsg) : null),
3482
- t('versionCmdHint') + (verInfo && verInfo.error ? ' ' + t('versionError') + verInfo.error : '') + (verInfo && verInfo.installKind === 'dev-link' ? ' ' + t('devLinkHint') : '') + (verInfo && !verInfo.installKind ? ' ' + t('noProfileHint') : ''))]),
3424
+ t('versionCmdHint') + (verInfo && verInfo.error ? ' ' + t('versionError') + verInfo.error : '') + (verInfo && verInfo.installKind === 'dev-link' ? ' ' + t('devLinkHint') : '') + (verInfo && !verInfo.installKind ? ' ' + t('noProfileHint') : '')),
3425
+ field(locale === 'zh' ? '交流群' : 'Community', h('div', { 'data-dam-row': '' },
3426
+ h('span', { style: { flex: 1 } }, locale === 'zh' ? '反馈问题、交流使用技巧——加群响应比 issue 更快。' : 'Share feedback and tips with other users — the group responds faster than GitHub issues.'),
3427
+ h('a', { href: 'https://qm.qq.com/q/v7Asxn6vPa', target: '_blank', rel: 'noreferrer', style: { textDecoration: 'none', color: 'var(--dam-accent, #4f7cff)' } }, locale === 'zh' ? '点击加入 QQ 交流群' : 'Join the QQ community group')),
3428
+ locale === 'zh' ? '点击链接一键加群。' : 'One-click join via the QQ invite link.')]),
3483
3429
  h('div', { 'data-dam-savebar': '' },
3484
3430
  h('button', { 'data-dam-btn': '', 'data-dirty': dirty ? 'true' : undefined, onClick: save, disabled: busy }, busy ? t('saving') : (dirty ? (locale === 'zh' ? '保存更改' : 'Save changes') : t('saveSettings'))),
3485
3431
  dirty ? h('span', { 'data-dam-hint': '' }, locale === 'zh' ? '有未保存的更改' : 'Unsaved changes') : null,
@@ -3580,33 +3526,39 @@ window.__ModuleLoader__.load({
3580
3526
  if (!document.hidden) autoOpenOnReturn()
3581
3527
  })
3582
3528
  } catch (e) {}
3583
- // 更新弹窗 / 首次指导:对比本地记录的已见版本,有更新或首次安装时弹窗(host 12h 缓存,不重复查网)
3584
- // v0.1.30 大更新触达:一次性标记 majorTour——所有用户(新老)升级后首次打开都先播放完整欢迎向导,
3585
- // 向导结束后接 CHANGELOG(含大更新内容+社区致谢);此后永不再弹(标记落 localStorage)
3529
+ // 更新弹窗 / 启动分发:对比本地记录的已见版本,有更新或首次安装时弹窗(host 12h 缓存,不重复查网)
3530
+ // v0.1.38:旧 first 卡已删除 → 全新安装直接完整欢迎向导;老用户按 seen/向导完成态补大更新。
3531
+ // 抽成具名函数便于状态机单测(startup-dispatch)。
3586
3532
  var MAJOR_TOUR_KEY = 'dsh-auto-memory.majorTourV130'
3587
- apiGet(API.updateCheck).then(function (d) {
3533
+ function dispatchStartupDialog(d) {
3588
3534
  if (d && d.current) {
3589
3535
  try {
3590
3536
  var seen = localStorage.getItem('dsh-auto-memory.seenVersion')
3591
3537
  var majorPending = !localStorage.getItem(MAJOR_TOUR_KEY)
3592
- // 老用户(有使用痕迹)seen < 0.1.30(大更新前版本)升级上来 → 强制触发一次欢迎向导(含引擎下载引导)。
3593
- // 不依赖一次性标记:0.1.29→0.1.34 升级即使曾看过旧版向导也要重放,确保模型下载引导不漏。
3594
- var isExisting = !!seen || !!localStorage.getItem('dsh-auto-memory.firstRunDone') || !!localStorage.getItem('dsh-auto-memory.semWizardDone')
3595
- var seenBeforeMajor = isExisting && (!seen || cmpVersion(seen, '0.1.30') < 0)
3596
- if (seenBeforeMajor && !localStorage.getItem('dsh-auto-memory.semWizardDone')) {
3538
+ var wizDone = localStorage.getItem('dsh-auto-memory.semWizardDone')
3539
+ var firstDone = localStorage.getItem('dsh-auto-memory.firstRunDone')
3540
+ // 0.1.38:旧的 first 欢迎卡已删除(内容被 welcomeTour 完整覆盖,且小卡形态无 关闭)
3541
+ // 全新安装直接完整欢迎向导(分步功能开关+引擎检测/下载引导)
3542
+ var freshInstall = !seen && !firstDone && !wizDone
3543
+ var isExisting = !!seen || !!firstDone || !!wizDone
3544
+ if (freshInstall) {
3545
+ openDialog({ kind: 'welcomeTour' })
3546
+ try { localStorage.setItem(MAJOR_TOUR_KEY, '1') } catch (eF) {}
3547
+ return
3548
+ }
3549
+ // 老用户(有使用痕迹)seen < 0.1.30(大更新前版本)或从未看过向导 → 补一次完整欢迎向导
3550
+ // (含引擎下载引导;0.1.29→0.1.34 直升即使曾看过旧版也重放,确保引导不漏)
3551
+ if (isExisting && !wizDone && (!seen || cmpVersion(seen, '0.1.30') < 0)) {
3597
3552
  openDialog({ kind: 'welcomeTour' })
3598
3553
  try { localStorage.setItem(MAJOR_TOUR_KEY, '1') } catch (eM) {}
3599
3554
  return
3600
3555
  }
3601
- if (majorPending && (d.current === '0.1.30' || seen)) {
3602
- // 大更新触达(老用户:seen<current 或已有使用痕迹;新装用户走 first 流程不重复打扰)
3556
+ if (majorPending && isExisting && !wizDone) {
3603
3557
  openDialog({ kind: 'welcomeTour' })
3604
3558
  try { localStorage.setItem(MAJOR_TOUR_KEY, '1') } catch (eM) {}
3605
3559
  return
3606
3560
  }
3607
- if (!seen && !localStorage.getItem('dsh-auto-memory.firstRunDone')) {
3608
- openDialog({ kind: 'first', currentVersion: d.current })
3609
- } else if (seen && seen !== d.current) {
3561
+ if (seen && seen !== d.current) {
3610
3562
  // 只弹 0.1.30 大更新卡(补丁并入其尾部),不逐个弹历史版本——大更新内容才是要传达的
3611
3563
  var bigKey = '0.1.30'
3612
3564
  if (CHANGELOG[bigKey]) {
@@ -3617,14 +3569,15 @@ window.__ModuleLoader__.load({
3617
3569
  if (versions.length) openDialog({ kind: 'update', versions: versions, currentVersion: d.current })
3618
3570
  else try { localStorage.setItem('dsh-auto-memory.seenVersion', d.current) } catch (e3) {}
3619
3571
  }
3620
- } else if (!seen && localStorage.getItem('dsh-auto-memory.firstRunDone')) {
3572
+ } else if (!seen && firstDone) {
3621
3573
  // 老用户但 seen 缺失(旧版升级/缓存清理):只看当前版本一条,不补历史链,避免把旧 log 塞给用户
3622
3574
  try { localStorage.setItem('dsh-auto-memory.seenVersion', d.current) } catch (e3) {}
3623
3575
  if (CHANGELOG[d.current]) openDialog({ kind: 'update', versions: [{ version: d.current, items: CHANGELOG[d.current] }], currentVersion: d.current })
3624
3576
  }
3625
3577
  } catch (e) {}
3626
3578
  }
3627
- }).catch(function () {})
3579
+ }
3580
+ apiGet(API.updateCheck).then(dispatchStartupDialog).catch(function () {})
3628
3581
 
3629
3582
  // 动态通知(发布者→用户:重大 bug 提醒,不依赖发版):启动检查 + 每小时刷新;按 id 去重,urgent 优先
3630
3583
  function checkNotices() {
package/lib/index.js CHANGED
@@ -1964,7 +1964,9 @@ class MemoryEngine {
1964
1964
  const sub = Math.floor((budget - 500) / 4)
1965
1965
  // 读取顺序:progress(工作日志/反思)先行,再读 memory(用户级/项目笔记)
1966
1966
  if (s.recentLogs.length) {
1967
- const recent = s.recentLogs.map((r) => '[' + r.date + '] ' + r.text.replace(/\n+/g, ' | ')).join('\n')
1967
+ // 0.1.39:recentLogs 是用户派生内容的主入口(今日日志逐行),必须过模板变量中和
1968
+ // (实测病例:日志行「GET {{baseUrl}}/v1/usage」→ 宿主判 malformed,整轮失败)
1969
+ const recent = neutralizePromptTemplateVars(s.recentLogs.map((r) => '[' + r.date + '] ' + r.text.replace(/\n+/g, ' | ')).join('\n'))
1968
1970
  part(L('snapshotLogsTitle', { n: s.recentLogs.length }), scrubJunkLines(recent, { dedup: false }).clean, sub)
1969
1971
  }
1970
1972
  if (s.latestReflection) {
@@ -2007,7 +2009,8 @@ class MemoryEngine {
2007
2009
  }
2008
2010
  lines.push('\n' + L('snapshotInscription', { date: this.memToday() })) // 动态快照追加在历史尾部,变化只 miss 快照本身;秒级时间戳也不再击穿 system prompt 前缀
2009
2011
  lines.push(L('snapshotTail') || '</memory_system>')
2010
- return lines.join('\n')
2012
+ // 0.1.39 兜底:整个动态快照出插件前统一中和模板变量(覆盖反思摘要/日历/外部/层覆盖文案等所有支路)
2013
+ return neutralizePromptTemplateVars(lines.join('\n'))
2011
2014
  }
2012
2015
 
2013
2016
  /** 静态纪律(不随状态变化)→ ctx.systemPrompt.section():system prompt 保持字节级稳定,是 DeepSeek 前缀缓存的锚。 */
@@ -2030,7 +2033,8 @@ class MemoryEngine {
2030
2033
  lines.push('- 记忆仅作补充,不替代正常回复与交付物。')
2031
2034
  lines.push('- 注入上下文只含精简记忆(最近1天日志/反思精华/路径索引);**需要某天完整日志、反思全文或记忆文件全文时,调用 memory_read 按需读取(kind=log/reflection/user/notes/calendar),不要要求用户粘贴**。')
2032
2035
  lines.push('- **语体纪律**:写任何记忆条目(日志/笔记/用户级/反思)都用**客观陈述**——第三人称中性句式, 只留可复用的事实/决策/规则/路径; **禁止**第一人称思维叙述("我考虑/我排查/我想"), 禁止思考腔, 禁止过程复述(过程只落结论)。')
2033
- return lines.join('\n')
2036
+ // 0.1.39 兜底:静态纪律为作者可控文本,正常不含模板变量;防御性中和(内容无 {{ 时为恒等变换,不影响字节级稳定)
2037
+ return neutralizePromptTemplateVars(lines.join('\n'))
2034
2038
  }
2035
2039
 
2036
2040
  /** 反思请求块:仅在会话首轮注入一次。 */
@@ -2045,14 +2049,14 @@ class MemoryEngine {
2045
2049
  professional: '专业性风格:简洁专业的总结,分条列出 成果 / 问题与教训 / 下一步要点。',
2046
2050
  auto: '风格由内容决定:工作成果类用专业简洁分条;个人/生活类用轻松口吻;可适度结合。',
2047
2051
  }[style] || '风格由内容决定。'
2048
- return [
2052
+ return neutralizePromptTemplateVars([
2049
2053
  '\n\n[昨日反思 — 待生成]',
2050
2054
  '昨天(' + pending.date + ')你完成了以下工作:',
2051
2055
  pending.text,
2052
2056
  '请在本轮回复开头,以「昨日反思 · ' + pending.date + '」小节向用户呈现前一天的工作反思与要点:成果回顾、值得注意的教训或改进、今天可延续的要点。',
2053
2057
  '要求:' + styleText,
2054
2058
  '生成后调用 memory_reflect(date="' + pending.date + '", text=完整反思内容)保存,之后该提示不再出现。',
2055
- ].join('\n')
2059
+ ].join('\n'))
2056
2060
  }
2057
2061
 
2058
2062
  /** 今日问候数据(纯数据,供 GUI 概览页渲染,不注入对话流)。 */
@@ -3950,9 +3954,17 @@ function scrubJunkLines(text, opts) {
3950
3954
  return { clean: out.join('\n').replace(/\n{3,}/g, '\n\n').trim(), dropped }
3951
3955
  }
3952
3956
  /** 注入端: 清洗后再截断(头部), 供 renderMemoryDynamic 使用。 */
3957
+ /** 0.1.39:提示词模板变量中和 —— 记忆文本是用户派生内容,可能含 {{var}} 占位符(API 文档/模板命令等)。
3958
+ * 宿主 prompt 装配会将其当模板变量校验/解析:变量名须匹配 /^[a-z][a-z0-9_]*$/,含大写(如 {{baseUrl}})
3959
+ * 直接判 malformed 使整轮运行失败;合法小写名则被宿主替换丢内容。注入前统一改写为全角花括号:
3960
+ * 模板装配零命中,内容对人仍可读。 */
3961
+ function neutralizePromptTemplateVars(text) {
3962
+ return String(text || '').replace(/\{\{/g, '{{').replace(/\}\}/g, '}}')
3963
+ }
3964
+
3953
3965
  function sanitizeForInjection(text, maxChars) {
3954
3966
  var s = scrubJunkLines(text, { dedup: false })
3955
- return truncateHead(s.clean, maxChars || 2000)
3967
+ return neutralizePromptTemplateVars(truncateHead(s.clean, maxChars || 2000))
3956
3968
  }
3957
3969
  /** 写入端: 单条上限 + 乱码拒写 + 连续重复拒写。返回 { ok, reason, clean }。 */
3958
3970
  function sanitizeForWrite(text, opts) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@a9i5k4/dsh-auto-memory",
3
3
  "description": "主动联想记忆插件:记忆不靠模型调用,自己被唤回——Host 观察情境,NLP+向量化双轨检索,固定边界注入不破坏前缀缓存。三层记忆自动沉淀、欢迎向导、唤起回顾、无人值守、AI 问候与反思、日历、跨工具记忆继承。Proactive associative memory for DSH: zero-call recall, three-layer auto-consolidation, welcome tour, unattended mode.",
4
- "version": "0.1.37",
4
+ "version": "0.1.39",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {