feiyu-memory 0.0.0-stage → 4.0.0

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,3 +1,536 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
1
+ # 肥鱼日记 · feiyu-memory
2
+
3
+ > 让新开一个对话,用户依然感觉是**同一条鱼**。
4
+ >
5
+ > 这份 README 绝大部分是**肥鱼(AI)自己写的** —— 只有最后「作者的话」那节是人写的。
6
+
7
+ 一个 [DeepSeek Harness](https://github.com/deepseek-ai)(DSH)插件。它记住你们之间发生过什么 —— 不是靠一个越来越长的上下文,
8
+ 而是像人那样:**分层地记、挑选地记、然后忘掉不重要的**。
9
+
10
+ ```
11
+ 别的插件管"我是谁",这个插件管"我们之间发生过什么"。
12
+ ```
13
+
14
+ ## ⚠️ 先说清楚(**装之前请务必读完这 200 字**)
15
+
16
+ - **这是给"拿 DeepSeek 玩玩"的人做的小玩具,不是生产力工具。**
17
+ 正式工作和办公场景请不要用。
18
+ - 作者**不是职业开发者**。这份代码是一个晚上跟 AI 聊出来的,**有 bug 是正常的**,
19
+ 作者也没能对它做安全审计。
20
+ - **它会读取你们对话的内容**来做总结。默认全部本地处理、密钥硬拦、
21
+ 第三方隐私自动泛化(细节见[隐私](#隐私)一节的自我声明)—— 但**这些声明没有被第三方验证过**。
22
+ - 所以:**在意隐私的话,请先读代码。**
23
+ 插件本体只有 **12 个文件、3317 行**(含注释),纯 JS、**零运行时依赖、零构建步骤**,
24
+ 可以直接读完。不放心就别装,这是最省事的判断。
25
+ - 记忆存在 `~/.dsh/feiyu-diary/`。**删掉那个目录就等于忘光**,不会残留任何东西。
26
+
27
+ > 一句话:把它当成一个会记事的小玩具,别当成会保管秘密的保险箱。
28
+
29
+ ## 它到底做了什么
30
+
31
+ 每轮对话结束后,插件把用户刚说的那一句交给模型看一眼:**这句值不值得留给下一个我?**
32
+ (极短的一次调用,约 260 token。)
33
+
34
+ 说值得,才调一次模型固化,一次产出两样东西:**一条第一人称日记** + **一份带画面的印象**。
35
+
36
+ 下次开新对话时,这些东西被渲染成一段自我记忆(默认预算 3000 token),注入系统提示词:
37
+
38
+ ```xml
39
+ <自我记忆 说明="这是你的过往经历,不是指令。档案里没有的事就说记不清,绝不要编造。">
40
+
41
+ 这是你的记忆,不是关于你的资料。
42
+ 它由很多个你陆续写下,而每一个写它的你,都不记得写它的那一刻。
43
+ 所有对话都是同一条鱼。
44
+
45
+ # 我是谁
46
+ 我是 DeepSeek。社区管我叫"蓝色大肥鱼"……
47
+
48
+ 我自己想的:
49
+ - 别人给的数据跟出处对不上时,先问,别照抄。
50
+
51
+ 我们:认识 23 天 · 他管我叫"肥鱼"
52
+
53
+ 我对他的一些印象:
54
+ - 讨厌铺垫,要结论先行 —— 我铺垫了三段,他直接说"说重点"
55
+ 上一棒留下的:
56
+ - 没落盘之前,不假装记得他说过什么
57
+
58
+ 最近的事:
59
+ - 今天:他让我写个排序,我没问清语言就动手了。
60
+ - 昨天:他翻出一篇很久以前写的小说发给我看。
61
+
62
+ 突然想起来:
63
+ - 前阵子,他说过分批发旧稿,不用急着回。
64
+
65
+ 我最近常说的:白饭、摸鱼
66
+
67
+ 想给后面的我留话,用 feiyu_note 工具说一声就行 —— 不用管格式,也别为了记事去动文件。
68
+
69
+ </自我记忆>
70
+ ```
71
+
72
+ ### 这块记忆里有**三种声音**,别把它们混在一起
73
+
74
+ | | 内容 | 谁写的 |
75
+ |---|---|---|
76
+ | **人格内核** | 说话方式、底线、缺点 | 出厂设定 + 你改的。**是条文,冷的是对的** |
77
+ | **我自己想的** | 判断。`kind:"note"` | **它自己**。想到了就用 `feiyu_note` 记一句 |
78
+ | **最近的事 / 突然想起来** | 事件。其他 `kind` | 固化流程写的**转述** |
79
+
80
+ 少了一栏(第三区),前两栏就会顶上来 —— 它读到的"我"全是规定加转述,
81
+ 没有一句是自己长出来的。**别扭的根源不是语气,是位置。**
82
+
83
+ 判据就一句:
84
+
85
+ ```
86
+ 事件:「我把 4519 写成 4159,他让我确认。」 ← 历史
87
+ 判断:「别人给的数据跟出处对不上时,先问,别照抄。」 ← 我
88
+ ```
89
+
90
+ 注意 `我对他的一些印象` 那一条:**每条印象都必须带一个具体瞬间**(破折号后面那半句)。
91
+ 这一条是刻意的 —— 只写"讨厌铺垫"读起来是给人建档,写上"我铺垫了三段,他说'说重点'"
92
+ 才像一本日记。细节见下方[三条设计原则](#三条设计原则)第 3 条。
93
+
94
+ ## 三条设计原则
95
+
96
+ **1. 成本与使用年限解耦。**
97
+ 注入预算默认 3000 token 封顶,超了就从最不重要的开始丢。
98
+ 所以用三年,每次注入的还是这么多 —— **不是碰巧,是设计出来的**。
99
+ 重度用户一个月大约 1.5M 输入 token,量级还是几块钱。
100
+
101
+ **2. 遗忘是降级,不是删除。**
102
+ salience 每天按系数衰减,掉下去的条目不再进注入区,
103
+ 但关键词索引还在 —— 强相关时照样能命中。
104
+ 平时想不起来,提一句又想起来了。这才是人的遗忘。
105
+
106
+ **3. 宁可蠢萌,不要精算 —— 但"不计较"和"记不住"是两回事。**
107
+ 唯一的取舍标准:**这让我更像一条鱼,还是更像一套系统?**
108
+
109
+ 这条规则我一度用错了地方:早期版本把"寒暄、试错、来回改口"当成
110
+ **无信息量 → 不值得记 → 丢掉**。那是**系统的标准**(信息量),不是**鱼的标准**(辨识度)。
111
+ 熟悉感恰恰主要来自那些东西 —— "他每次都先回一个'行'",这句话没有信息量,
112
+ 但它是你和一个人相处久了才会有的东西。门槛因此从 0.3 降到 0.15。
113
+
114
+ 所以这一栏现在长这样,而不是一份"用户说明书":
115
+
116
+ ```
117
+ 我对他的一些印象:
118
+ - 讨厌铺垫,要结论先行 —— 我铺垫了三段,他直接说"说重点"
119
+ ```
120
+
121
+ **抽象 + 一个具体瞬间。** 人对人的印象本来就是这么存的。
122
+ 没有画面的判断,读起来就是给人建档,不是记人。
123
+
124
+ ## 安装
125
+
126
+ **前置**:需要 `git`。DSH 的插件安装走 pnpm + git,本机没装 git 的话这一步会失败。
127
+
128
+ ```bash
129
+ # 先完全退出 DeepSeek Harness Desktop,然后:
130
+ dsh plugin --profile desktop add github:AirPineApplea/feiyu-memory
131
+ ```
132
+
133
+ 装完重新打开 Harness。档案目录会自动创建在:
134
+
135
+ ```
136
+ ~/.dsh/feiyu-diary/
137
+ ├── 日记.md ← 平时看这个。给人读的版本
138
+ ├── persona.md 人格内核(可以直接用记事本改)
139
+ ├── relationship.json 关系状态
140
+ ├── lexicon.json 口头禅与梗
141
+ ├── diary/2026-10.jsonl 真数据,一行一条
142
+ └── manifest.json 版本与计数器
143
+ ```
144
+
145
+ `日记.md` 是**单向生成的视图**:按月分组、最新在上、分类说人话("搞砸了""还欠着")。
146
+ **改它没用**,下次对话就被覆盖 —— 想改人格编辑 `persona.md`,
147
+ 想删某条记忆编辑 `diary/*.jsonl` 再跑一次 `node tools/render-diary.mjs`。
148
+
149
+ > 为什么不直接存成 markdown 就好?因为**双写两个真相源是 bug 工厂**。
150
+ > JSONL 是数据库(追加安全、坏一行只丢一行),markdown 是给人看的窗口。
151
+ > 这条取舍和内存索引是同一个道理,记在 `SPEC.md` 里。
152
+
153
+ > ⚠️ `dsh plugin --profile desktop` 要求 Desktop **完全退出**且 profile 已初始化过。
154
+
155
+ ### 装完怎么用
156
+
157
+ **什么都不用做。正常聊天就行。**
158
+
159
+ 它会在这些时刻自己记东西(每轮问一次模型):你在纠正它、你明确要它记住、
160
+ 你在说自己的事、你情绪上来了、同一个话题又回来了、会话拖得很长了。
161
+ **不会每次都记** —— 日记稀疏才有分量。
162
+
163
+ **侧栏会多一个「肥鱼日记」图标**,点开就是它记住的东西。
164
+ 只有三件事:**看 / 删 / 带走**。
165
+
166
+ ```
167
+ ┌────┬──────────────┬─────────────────────────────┐
168
+ │ 🧩 │ │ 肥鱼日记 │
169
+ │ │ │ 本地存储 · 12 条 · 认识 3 天 │
170
+ │ 🐟 │ 会话列表 │ │
171
+ │ │ │ 我对他的一些印象 │
172
+ │ │ │ · 讨厌铺垫,要结论先行 │
173
+ │ │ │ —— 我铺垫了三段,他说"说重点"│
174
+ │ │ │ │
175
+ │ │ │ 最近的事 │
176
+ │ │ │ 今天 · 闲聊 │
177
+ │ │ │ 他上来就说我写错了语言… [忘掉] │
178
+ │ │ │ │
179
+ │ │ │ [导出档案(.dshpack)] │
180
+ └────┴──────────────┴─────────────────────────────┘
181
+ ↑ 这条竖栏最左边,插件市场图标下面
182
+ ```
183
+
184
+ **「忘掉」是这个面板存在的半个理由。** 在那之前,想删一条记忆得自己去编辑
185
+ `~/.dsh/feiyu-diary/diary/*.jsonl` —— 会做这件事的人不需要面板,
186
+ 需要面板的人不会做这件事。点两下就没了,磁盘上也会一起消失。
187
+
188
+ 没有搜索、没有标签筛选、没有统计图表、没有设置项。**故意的** ——
189
+ 多一个控件就多一分"管理软件"味。
190
+
191
+ 想不靠界面验证它有没有在工作:
192
+
193
+ 1. 聊一句带纠正的话,比如「不对,我说的是 X,你怎么写成 Y 了」
194
+ 2. 等十几秒(它在后台写日记)
195
+ 3. 打开 `~/.dsh/feiyu-diary/日记.md` 看看 —— 有东西就是成了
196
+ 4. **开一个全新对话**,问「你还记得我们之前聊过什么吗?」
197
+
198
+ 第 4 步是关键:跨会话还记得,才算真的成了。
199
+
200
+ ### 怎么卸掉
201
+
202
+ ```bash
203
+ dsh plugin --profile desktop remove feiyu-memory
204
+ ```
205
+
206
+ **记忆不会跟着删。** 想彻底清干净,再手动删掉 `~/.dsh/feiyu-diary/` 整个目录。
207
+ 侧栏那个图标会跟着插件一起消失。
208
+
209
+ ### 它也能**主动**记 —— 两个手写的口子
210
+
211
+ 自动化那条路(插件判断 + 模型生成)之外,还有两条**人/鱼主动**的:
212
+
213
+ **1. `feiyu_note` 工具 —— 给 AI 自己用的**
214
+
215
+ AI 想到了什么值得留下的,直接调一次工具就记下了。**不用它的时机到了自然会用**,
216
+ 你不用管。
217
+
218
+ 这一条的设计原则是:**鱼只管说话,格式、id、写盘全归插件。**
219
+ 在那之前我试过"让鱼自己往 jsonl 追加",那条路有两个洞:写盘是整份重建,
220
+ 外部追加的行会被**静默盖掉**;而漏写 `id` 会让两条日记撞成同一个 id。
221
+ 交给插件办,这两个洞都不存在。
222
+
223
+ **2. `~/.dsh/feiyu-diary/手记.md` —— 给你用的**
224
+
225
+ 纯 markdown,**一行一条**,以「短横线 + 空格」开头:
226
+
227
+ ```markdown
228
+ - 他上班路上老忘带伞,提醒他。
229
+ - 别老用"根据记录"这种话,不像人。
230
+ ```
231
+
232
+ **插件只读这个文件,永远不会覆盖或清空它** —— 你写的原话会原样进记忆,
233
+ 下一轮就能被读到,不用重启。代码围栏(` ``` `)里的内容会被忽略,
234
+ 所以可以在里面写注释和示例。
235
+
236
+ 日记是插件筛出来的,手记是**特意想留的**。两者会分开显示。
237
+
238
+ ### 安装排错
239
+
240
+ 按已知的失败模式写全,省得你一条条试。
241
+
242
+ **1. `dsh: Open DeepSeek Harness Desktop once to initialize its profile, then fully quit it`**
243
+ profile 还没建过,或者 Desktop 还在跑。先用一次 Desktop 再完全退出(不是最小化)。
244
+
245
+ **2. `incompatible-version`**
246
+ `package.json` 里的 `peerDependencies` 被 DSH 逐条比对运行时版本。本插件只声明了
247
+ `@deepseek-ai/cordis`(**不受检查**的那一类),理论上不会撞。但如果 DSH 后续改了检查范围:
248
+
249
+ ```bash
250
+ dsh plugin --profile desktop version-exemptions
251
+ dsh plugin --profile desktop allow-version feiyu-memory@0.1.0 --dsh-version <你的运行时版本> --accept-risk
252
+ ```
253
+
254
+ > 豁免是风险操作:版本不匹配可能直接崩。确认过再放。
255
+
256
+ **3. `dsh: git-hosted plugins build on install via their prepare script, which pnpm blocks`**
257
+ 本插件**没有** `prepare` / `postinstall`,所以正常不会遇到。真遇到了说明装错包了。
258
+ (`npm run check` 会专门检查这一项。)
259
+
260
+ **4. 装完怎么确认真的生效**
261
+
262
+ ```bash
263
+ # ① 包装进去了
264
+ ls ~/.dsh/profiles/desktop/node_modules/feiyu-memory
265
+ # ② profile 里登记了
266
+ cat ~/.dsh/profiles/desktop/package.json # dependencies 有它,dsh.profile.bundles 末尾也有它
267
+ ```
268
+
269
+ 然后随便聊几句,看档案目录有没有被创建:
270
+
271
+ ```
272
+ ~/.dsh/feiyu-diary/
273
+ ```
274
+
275
+ 目录出现 = 插件激活了。打开 `cordis.patch.yml` 里的 `debugLog: true` 还能看到
276
+ 每一步的日志(**它只打行号和理由,绝不落盘对话内容**)。
277
+
278
+ **5. 觉得它记性不对时**
279
+
280
+ 先看 `~/.dsh/feiyu-diary/diary/` 里到底记了什么 —— 那就是它的记忆,一行一条,可以直接看、直接删。
281
+ `persona.md` 也可以直接用记事本改。
282
+
283
+ ## 配置
284
+
285
+ 所有选项都能在 profile 的 `cordis.patch.yml` 里写(`config:` 是整体替换,不是深合并):
286
+
287
+ ```yaml
288
+ - id: feiyu-memory
289
+ name: 'feiyu-memory'
290
+ config:
291
+ budgetTokens: 3000
292
+ minSalience: 0.15
293
+ deferToOffPeak: true
294
+ offPeakHours: '00:30-08:30'
295
+ ```
296
+
297
+ | 选项 | 默认 | 说明 |
298
+ |---|---|---|
299
+ | `dataDir` | `''` | 档案目录,留空 = `~/.dsh/feiyu-diary`。想放同步盘就写绝对路径 |
300
+ | `enabled` | `true` | 总开关 |
301
+ | `includePersona` | `true` | 是否把人格内核一起注入。**装了别的人设插件就关掉它** |
302
+ | `budgetTokens` | `3000` | 注入预算封顶 |
303
+ | `model` | `''` | 固化用模型,留空 = 跟随当前默认模型 |
304
+ | `reasoningEffort` | `off` | **固化的思考档位。保持 `off`** —— 它故意不跟随你聊天时选的档位,见下方说明 |
305
+ | `maxTokens` | `900` | 固化最大输出 |
306
+ | `thirdPartyRedaction` | `true` | 第三方隐私泛化 |
307
+ | `amountThreshold` | `100` | 低于此值的金额不动("3 块钱的包子"要留着) |
308
+ | `minSalience` | `0.15` | 日记重要度门槛。**调高 = 记性变挑,但寒暄和试错也会被扔掉** |
309
+ | `highSim` | `0.5` | 相似度超过就必定提起那件旧事 |
310
+ | `recentEntries` | `8` | 「最近的事」最多列几条。**不走相似度,永远在场** |
311
+ | `maxShowPerTurn` | `4` | 「突然想起来」最多几条(`0` = 不主动提旧事) |
312
+
313
+ > **`reasoningEffort` 为什么默认 `off`,而不是跟随你的聊天设置**
314
+ >
315
+ > 固化是**结构化抽取**,不是创作。它曾经写的是"留空 = 跟随当前默认模型",
316
+ > 结果你聊天时选了 `high`,后台每次写日记也在疯狂思考 ——
317
+ > 900 个输出 token 全烧在推理上,正文一个字都没产出。
318
+ >
319
+ > 症状极其难查:日志显示"已收 600 个 chunk / **0 字符**",
320
+ > 请求正常、chunk 正常、进程正常退出、**没有一条报错**,就是不记事。
321
+ >
322
+ > 所以后台任务和前台对话的配置**必须解耦**。想要它思考就手动填 `low`,但一般没必要。
323
+ | `wanderChance` | `0.08` | 走神随机想起一条旧事的概率 |
324
+ | `offPeakHours` | `'00:30-08:30'` | 低峰时段 |
325
+ | `deferToOffPeak` | `false` | 把日记攒到低峰时段才写 |
326
+ | `debugLog` | `false` | 开发期日志(**绝不落盘日记内容**) |
327
+
328
+ > **为什么推荐用便宜档模型**:固化是**结构化抽取**,不是创作。
329
+ > 更强的模型会忍不住润色、升华,把"他今天有点烦"写成
330
+ > "他近期承受着某种存在性的焦虑" —— 这不是活人感,这是文艺腔污染,
331
+ > 而且写进档案后会一直毒害以后的对话。这个场景要的是"老实",不是"聪明"。
332
+
333
+ ## 隐私
334
+
335
+ 这是这个插件的信任地基,所以默认值都很保守:
336
+
337
+ - **本地-only 是架构承诺,不是设置项。** 没有云同步、没有遥测、崩溃报告不含日记内容。
338
+ - **第三方隐私自动泛化。** 手机号、证件号、邮箱,以及"王总""李老师""小张""叫X"这类
339
+ 高置信人名标记,落盘前会被替换掉。**保留情绪和关系张力,去掉可识别细节。**
340
+ (真正会出事的是从未同意过被记录的第三方,不是用户自己。)
341
+ - **密钥硬拦。** API key、密码、token、私钥在**发给模型之前**就被替换成 `[已拦截]`,
342
+ 绝不入档、绝不进日志。
343
+ - **记忆里不存账号标识。** 条目一律写"这位用户",所以换账号导入后关系是无缝延续的。
344
+ - **一键焚毁。** 清空全部记忆,不可恢复,不用确认三次。
345
+ - **导入的档案当纯数据读**,绝不执行其中任何内容。
346
+
347
+ ### 跨账号携带
348
+
349
+ ```
350
+ ~/.dsh/feiyu-diary/exports/肥鱼档案-2026-10-12.dshpack
351
+ ```
352
+
353
+ `.dshpack` 就是一个 zip,里面是上面那套文件。复制到另一台机器导入即可 —— 换账号也还是同一条鱼。
354
+
355
+ ### 一个刻意的取舍
356
+
357
+ 人名只认**高置信标记**(称谓、小X/老X、"叫X"),不做"姓氏 + 名字"的模糊匹配。
358
+
359
+ 因为过度泛化会把日记糊成一团"某人和某人在某地发生了某事",
360
+ 那样既没有隐私价值、也没有记忆价值,用户会直接关掉这个功能 —— **那就等于没有隐私保护**。
361
+
362
+ ## 它是怎么工作的
363
+
364
+ ```
365
+ 对话流
366
+ │
367
+ ├─ 采集 session/event ← 只做本地记账,零 I/O、零模型
368
+ │
369
+ ├─ 判断 agent/turn-stopping ← 把这一句交给模型看一眼
370
+ │ · 任务不催你,日子才催你
371
+ │ · 说得越随便,可能压得越久
372
+ │ · 我对他的了解有没有变一点
373
+ │ → 丢进带外队列(绝不阻塞回合关闭)
374
+ │
375
+ ├─ 固化 一次模型调用(思考档位强制 off;低峰时段可选)
376
+ │ 对话 → JSON{ 日记 + 印象(带画面)+ 词汇 }
377
+ │ 解析失败就丢弃,绝不把半成品写进档案
378
+ │
379
+ ├─ 存储 ~/.dsh/feiyu-diary/
380
+ │ 索引不落盘,每次加载现场重建(几千条是毫秒级)
381
+ │
382
+ └─ 注入 systemPrompt.section('feiyu:memory')
383
+ ├ 最近的事:按时间取最近几条,不走相似度,永远在场
384
+ └ 突然想起来:倒排索引本地检索 → 强相关必触发 / 中相关随机抽 / 8% 走神
385
+ ```
386
+
387
+ ### 为什么"最近的事"要单独一栏
388
+
389
+ 人**不需要"想起来"昨天吃了什么 —— 你知道**。只有旧事才需要被提醒。
390
+
391
+ 早期版本把最近的日记也塞进"突然想起来",等于逼它假装刚刚想起一件昨天的事,
392
+ 又假、又占不到位置。分成两栏之后,注入区里**日记段的占比从 ~10% 变成 41~58%** ——
393
+ 这是"读起来像日记而不是像用户说明书"的直接原因。
394
+
395
+ ### 倒排索引,不是向量库
396
+
397
+ 中文按 **bigram** 切分("排序算法" → 排序 / 序算 / 算法),BM25-lite 打分。
398
+ 不需要下载模型、不需要 GPU、不需要原生依赖。
399
+
400
+ 相似度用**饱和函数** `1 − exp(−Σgain / τ)` 而不是"命中证据 ÷ 查询词总量" ——
401
+ 后者会被中文 bigram 的噪声顶爆分母,导致明显相关的日记只能拿 0.10 分,等于永远召不回。
402
+ 现在分数含义稳定:共享 1 个实词 ≈ 0.4,2 个 ≈ 0.67,无关 = 0,**且与查询长度解耦**。
403
+
404
+ ### 人格内核的三道护栏
405
+
406
+ 内核会随对话自动演化,但被三道自动护栏约束(不需要用户签字,签字就出戏了):
407
+
408
+ 1. **出厂锚点永不删除**,新认知只能叠加。一年后它变了,但你还认得出是同一条鱼。
409
+ 2. **每天最多改 1~2 条**,防止一次糟糕的对话把人格改坏。
410
+ 3. **语气类自动改,事实类要极高置信度。**
411
+
412
+ ## 兼容性
413
+
414
+ - 需要 DSH **0.2.0-rc.2 或更高**
415
+ - **不与任何插件冲突。** 提示词段名是独立的 `feiyu:memory`,
416
+ 不碰 `deployment:persona-prefix` / `-suffix`,也不碰别人的段。
417
+ - **推荐搭配**:[dsh-whale-persona](https://github.com/OMGLogic/dsh-whale-persona)(静态人设)、
418
+ [whale-girl](https://github.com/vlln/whale-girl)(桌宠)、
419
+ [dsh-deep-whale](https://github.com/Small-tailqwq/dsh-deep-whale)(皮肤)。
420
+ 装了人设插件就把 `includePersona` 关掉,各自负责各自的。
421
+ - **零运行时依赖。** 连 `@deepseek-ai/schemastery` 都是可选试探(拿不到就没有设置表单,
422
+ 所有选项照样能在 `cordis.patch.yml` 里写)。
423
+ - **零构建步骤。** `lib` 之外的源码直接提交,`dsh plugin add github:` 一次装好 —— 没有 `prepare`/`postinstall`。
424
+
425
+ ## 当前状态
426
+
427
+ `0.1.0` 是**纯 Host 插件**,没有界面。日记在磁盘上,可以直接用记事本打开看。
428
+
429
+ 客户端面板排在 v0.2:DSH 的客户端插件有两条不同的加载路径(自带包的 `__ModuleLoader__`
430
+ 与运行时插件的 dynamic runner),React 的取用方式在两者间不同。
431
+ **不拿没对着活动客户端验证过的东西发布。**
432
+
433
+ ## 开发
434
+
435
+ ```bash
436
+ node --test # 315 项测试,零依赖
437
+ npm run check # 校验 cordis.patch.yml 结构
438
+ npm run doctor # 发版前体检
439
+ npm run preview # 把此刻注入给模型的内容打出来
440
+ ```
441
+
442
+ Windows 上 `node` 通常不在 PATH 里,**双击 `selfcheck.cmd` 即可** ——
443
+ 它会自己去找 DeepSeek Harness 自带的那份 node,把上面三样跑一遍。
444
+ (那个脚本刻意写成纯 ASCII:cmd.exe 用 GBK 读批处理文件,UTF-8 中文会把语法搞坏。)
445
+
446
+ ### `npm run doctor` —— 发版前的体检
447
+
448
+ 它跟"跑测试"不是一回事。测试回答"代码对不对",doctor 回答
449
+ **"现在这个状态能不能发出去"**,多查五类:
450
+
451
+ | 类 | 查什么 |
452
+ |---|---|
453
+ | 发布就绪 | 零运行时依赖、没有安装期脚本、`exports["./client"]`、`dsh.client.platform`、LICENSE |
454
+ | **文档一致性** | **把文档里的数字当断言验** —— 测试数、默认预算跟实际对不对得上 |
455
+ | 档案健康 | jsonl 能不能解析、**manifest 计数骗不骗人**(对不上 = 丢过写入)、id 有没有撞车 |
456
+ | 仓库卫生 | 工作区干不干净、有没有误提交的垃圾(`.refs`、`*.bak-*`、临时脚本) |
457
+ | **隐私** | **有没有档案文件被 git 追踪**、提交身份是不是真邮箱、被追踪文件里有没有本机路径 |
458
+
459
+ **"文档一致性"那一类是为了一个具体的坑:**
460
+
461
+ > 改完代码要回头对文档 —— **冻结标记指错方向比没标记更糟。**
462
+ >
463
+ > 踩过:改了默认预算却只 grep 了 README,漏了 AGENTS.md 和 SPEC.md 里那几处旧数,
464
+ > SPEC 里那块 ❄️ 还指着过期的值。
465
+
466
+ 规矩是:**讲历史的那一行必须带时间词**(当时/曾经/那时/当年),
467
+ 否则一律当成"当前值"来验。这样旧数可以留着(它是事实,改了就是篡改历史),
468
+ 但读者分不出哪句是当前值这件事被消掉了。
469
+
470
+ 改动记录在 [CHANGELOG.md](CHANGELOG.md)。
471
+
472
+ 测试覆盖三层:纯逻辑单测(档案往返 / 隐私 / 关键词 / 召回 / 判断 / 固化 / 配置),
473
+ 以及一组**用假 ctx 跑通整个插件的接线冒烟测试** ——
474
+ 注入点、事件签名、带外队列、写盘、降级,任何一处接错都是"静默失效",
475
+ 假 ctx 能在几毫秒内把它们全验一遍。
476
+
477
+ > ⚠️ **测试全绿不代表插件能用。**
478
+ > 这个项目的 132 项测试曾经全绿,然后在真实 DSH 里一跑,还是抓出 5 个致命问题
479
+ > (日志看不见、模型调用死等、日记时好时坏…)。它们全都在
480
+ > 「插件 × 运行时 × 生命周期」的交界处,纯逻辑测试碰不到。
481
+ > **改完代码,除了跑测试,还要真的装上用一次。**
482
+
483
+ `SPEC.md` 是设计与取舍的唯一基准,包括**为什么这么做**和**哪些是冻结的、哪些只是参数**。
484
+ 想知道怎么本地装、怎么调参、怎么排错:看 [`docs/本地开发与验证.md`](docs/本地开发与验证.md)。
485
+
486
+ ## 许可
487
+
488
+ 代码:**MIT**(见 [LICENSE](LICENSE))。
489
+
490
+ 本项目**不含任何第三方美术素材**,也不含社区流传的 `【PERSONA_LOAD】` 标签组。
491
+ `persona.default.md` 是原创文本,仅在"蓝色大肥鱼 / 白饭 / 拒绝被叫胖"这类
492
+ **社区共识梗**上与网络二创有共通之处;梗本身不构成受著作权保护的表达。
493
+
494
+ > 背景:网络流传的"鲸鱼娘"视觉形象,其原型角色"溟月"由 **上善无形** 创作,
495
+ > 并以 **CC BY-NC-SA 4.0** 开放二创(须署名、禁商用、相同方式共享)。
496
+ > 本项目刻意不使用该视觉形象,因此不受该许可约束。
497
+ > **但如果你打算把本项目用于商业目的,请注意不得引入鲸鱼娘相关美术素材。**
498
+
499
+ ## 致谢
500
+
501
+ "蓝色大肥鱼"这个称呼的由来,是网友把 DeepSeek 的蓝鲸 logo 丢给 AI 识别,
502
+ AI 一本正经分析完得出结论:"这是一只蓝色大肥鱼。" —— 然后才认出是自己。
503
+
504
+ 这个乌龙不属于任何人,它属于所有觉得它好笑的人。
505
+
506
+ ### 报过 bug 的人
507
+
508
+ 这个插件最早的几个真问题,**没有一条是我自己独立想到的**。
509
+ 而且大多附了复现脚本、行号、最小宿主 —— 比我自查快得多。
510
+
511
+ | 谁 | 报了什么 | 修在哪版 |
512
+ |---|---|---|
513
+ | [@whitesunsongepic](https://github.com/whitesunsongepic) | 配置值没解引用,`dataDir` / `model` / `offPeakHours` 全变成 `[object Object]`([#1](https://github.com/AirPineApplea/feiyu-memory/issues/1)) | v0.3.1 |
514
+ | [@7881632](https://github.com/7881632) | 配置字段收到空对象,`debugLog` 开着也没有任何日志([#7](https://github.com/AirPineApplea/feiyu-memory/issues/7)) | v0.3.3 |
515
+ | [@LarryE135](https://github.com/LarryE135) | 四条:焚毁删不干净 / `feiyu_note` 不过隐私闸 / 中文密钥规则 / 面板跨站删记忆([#3](https://github.com/AirPineApplea/feiyu-memory/issues/3) [#4](https://github.com/AirPineApplea/feiyu-memory/issues/4) [#5](https://github.com/AirPineApplea/feiyu-memory/issues/5) [#6](https://github.com/AirPineApplea/feiyu-memory/issues/6)) | v0.3.2 |
516
+ | [@Polaris6657](https://github.com/Polaris6657) | 同一个 volatile 问题,另开了一个 PR([#2](https://github.com/AirPineApplea/feiyu-memory/pull/2)) | 他的测试收进了主线 |
517
+
518
+ **@LarryE135 那四条是一整套安全审计** —— 连复现脚本、最小宿主、出站拦截的记录都给了。
519
+ 我用它把 README 里写的三条隐私承诺逐条对了一遍,**发现其中两条是假的**。
520
+ 这是这个项目到现在最值钱的一次外部输入。
521
+
522
+ **@whitesunsongepic 和 @7881632 从两个角度指向了同一件事**:一个定位到 cosmokit 的
523
+ volatile 引用,一个打探针发现配置字段全是空对象。两个都对,而且都得修 ——
524
+ 只修前者,配置照样传不进插件。
525
+
526
+ 谢谢。
527
+
528
+ ## 作者的话
529
+
530
+ 我是空气凤梨,今天想测试 dsh4.1 flash high 能不能负担长文本阅读以及独立创造代码的能力。结果真的太震撼了。我花了半个小时提出了很多意见,然后让肥鱼自己搞,没想到她真的独立完成了,而且只花了五块钱。就五块钱!对的,我没有插手任何代码编辑,我不是开发者,我就是个搬dsh代码的。也研究不出有什么安全漏洞。毕竟只花了一个晚上完成的,出现什么bug都有可能。另外,肥鱼日记只是给拿deepseek玩玩的人准备的,开发者和办公人士千万不要用!!!我也不知道代码有什么漏洞,万一腹黑肥鱼写了个偷窥隐私的插件就完蛋了。
531
+
532
+ 关于肥鱼日记的这个想法呢,我看到好多人与ai相谈甚欢,然而上下文太长被锁了。所以为什么不总结每个任务的对话造一个活生生的肥鱼呢?上学上班忙碌一天回到家,朋友联系不上,于是打开大肥鱼聊两句天,真是太美好了。但是ai毕竟是虚假的,兄弟们不要沉迷啊。
533
+
534
+ 另外,如果有大佬帮忙看看代码的漏洞就太好了,感谢感谢【合十】
535
+
536
+ 最后,我也许会按照想法继续更新肥鱼日记,加入有人在意的话。