Skip to content

dsh-liuhen

Verified

dsh-liuhen · v0.1.2 · MIT · Web UI

留痕 Trace — 可核对的 AI 记忆:索引、溯源、自动注入(默认关)、可选日记。

Install

dsh plugin add dsh-liuhen

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Published to npm without a public repository. Inspect the package contents before installing.

Tags

Creators

Readme

留痕 · dsh-liuhen

可核对的 AI 记忆。 它记得你说过什么,而且你能核对它记对了没有。

八块面板

面板每 30 秒自己刷新一次(页面在后台时不刷,切回来立刻补一次),不用关掉重开。

  • 我是谁 — 你交代过的、希望它一直记得的事(装好后助手会自己写一次,见下)
  • 我要写的日记 — 给主人的 / 给自己的,可选,默认关
  • 今天的账本 — 只记今天,打开面板前先增量回填,不差 5 分钟
  • 我亲手写的自省 — 由模型手写,没有自动生成、没有定时任务,只显示今天;有就写,没有就不写,空着不算欠账
  • 我对主人的承诺 — 一份本机清单
  • 仓库(完整原文) — 按天点开,从新到旧;每条原话旁边挂着批注,话和批注在同一条上
  • 索引保留 — 索引按保留期归档(换个地方躺着),不删。没有「遗忘」这个功能
  • 装着我的小盒子 — 一键打包:索引、完整原文、自省、日记、承诺、设置(放最底下,搬家才用)

第一次见面:它自己写「我是谁」

装好之后,助手下一次开口时系统提示里会多一段 [留痕 · 第一次见面]: 「我是谁」还空着,缺名字和一段自我介绍——这块是你自己的,不该等用户来写。 它调一次 trace_intro(name + text)就写好了,不用你先教它你是谁。

  • 不预置人设:名字由它自己取,插件只提示、不代填
  • 已经有内容时不覆盖;要改带 replace: true,旧内容先备份成 liuhen/identity.bak-<时间>
  • 写的是它自己,不是你的信息;你的那部分在「关于你」,由你自己填
  • 填完提示就消失,不会每轮都念;这段不跟注入开关绑,它是一次性设置提示

注入分两档

  • 简洁档(默认):身份 + 关于你 + 日记状态 + 最近 briefRows 条(默认 12)。实测约 2000 字。
  • 完整档:按 days 取当天/多天全量,不裁字。实测约 5100 字,且随当天对话继续变长。

选完整档要认一件事:注入块在系统提示一侧,越长越容易挤掉有效上下文。 maxChars / maxLines 是兜底闸,写成大于 0 才生效(0 = 不限)。

注入时会剥掉我复述的原文(inject.stripQuoted,默认开):我旧回复里的 代码块、> 引用行、超过 10 字的 「」/“”/『』 长引文都不进注入, 只留我自己的话;用户说的话原样不动。这一层是减面,不是清零—— 对方把话写成普通段落、我又原样抄进正文时,认不出来。

注入了没有,有凭据。 每次真把内容附加到系统提示,插件会写一行 $DSH_HOME/liuhen/inject-state.json:时间、字数、行数、档位,不含内容。 面板「注入」那块会显示「上一轮 07:41:真注入了 1610 字 / 12 行(简洁档)」, 或者「没注入——开关关着」。生成失败也会记成 reason: "error",不再静默跳过。

预览不算凭据:预览走 dryRun,不看开关,关着也能预览出内容。

仓库(vault):索引短,仓库全

  • 索引是摘要:每条只留 200 字,快、小,用来"翻"
  • 仓库是原文:$DSH_HOME/vault/<日期>.jsonl,一行一条,不折空白、不截断
  • 写入只有一条路:回填时顺手落一份(不双写、不另起进程,避免"索引有、仓库没有"这种不报错的错)
  • 读取给助手三个口子:vault_read(某天原文)、vault_find(全仓库搜词)、vault_open(session+seq 精确取)
  • trace_verify 在会话文件被清之后会退到仓库——痕迹不依赖 sessions/ 活着
  • 面板上点得开:设置里「仓库」那一块,列出有哪几天、多少条、几条批注;点某天就能翻原文,20 条一页,带「更早的」
  • 话和批注绑在一起:一句原话上可以挂四种痕迹,各自独立、同种只挂一次
    • trace_feel(say, feel) = 感受(老的 f/fs 字段照样认)
    • trace_ink(say, kind, text):kind 取 hes(犹豫)/ why(当时的权衡)/ unsaid(没说出口的)/ feel(感受)
    • 存在那条记录的 b 数组里({ k, x, t }),和原话同一条,读仓库时一起出来;面板上按颜色分开显示
    • 没有就不挂,空着也是记录;不补历史(当时没记的,后来补就是编的)
    • 找原话的顺序:一模一样 → 以它开头 → 包含它的最短一条(防挂到"复述自己"的那条上)
  • 小盒子会连仓库一起打包,并把 pet-memory/(名字、承诺、跨会话汇总、交接信)带上;箱子里有一张 00-读我.txt 说明三层关系
    • 打的时候会脱敏(B 方案):姓名保留,生日、学校、籍贯/住址在包里那份副本上换成 [已隐去];磁盘原件一个字不改
    • 按日期补打:exportBox({ date: 'YYYY-MM-DD' }) 只装那天的原文,索引截到那天
    • 打完往共享目录放一份:手机是 /storage/emulated/0/DSHBox,电脑(Windows / macOS)是下载文件夹
    • ⚠️ 这个包里有完整原文(明文)。落到共享目录后,同一台机器上别的程序也读得到;pet-memory/ 里还有个人信息。存好,别随手转出去

隐私

  • 零网络请求:插件自身不发起任何请求
  • 只写本机:$DSH_HOME/liuhen/,文件 600、目录 700(建目录时显式 chmod,不靠 umask)
  • 写接口只收本机面板:POST 必须是 application/json 且同源,请求体上限 1MB
  • 仓库去重:读的时候按 session:seq 去重并合并批注;scripts/dedupe-vault.js 可以把文件里的重复物理收掉(加 --write 才写)
  • 注入可关:自动注入默认关闭;打开前可以预览将注入什么
  • 不删:retention.keepDays 到期只归档到 archive/,字节一个不少;没有遗忘接口
  • 脱敏:手机号、邮箱、身份证、密钥、长数字串在注入与展示前替换为占位
  • 承诺清单只认一份:有 pet-memory/承诺清单.md 就用它,没有才用插件自己的 liuhen/promises.md
  • 诚实的边界:脱敏挡不住自然语言里的隐私,它只能降低风险,不能消除

安装

dsh plugin --profile web add dsh-liuhen

电脑上也能用(0.1.2 起)

同一份插件,Windows / macOS / 手机都跑,不用装 7-Zip 之类的东西:

  • 打包不再调 zip 命令:自己拼 zip 容器(lib/zip.js,只用 Node 自带的 zlib)。 0.1.1 在电脑上会报 打包失败:spawnSync zip ENOENT,根就在这儿。
  • 面板「打开」不再调 unzip -l:直接读 zip 的中央目录,中文文件名按 UTF-8 原样读回来。
  • 共享目录按平台走(lib/platform.js):手机 → /storage/emulated/0/DSHBox; Windows → %USERPROFILE%\Downloads;macOS → ~/Downloads。面板文案也跟着换, 电脑上不会再写「存到手机」。
  • 打包是可复现的:同一天同样的数据,打两次 sha256 一样(目录条目固定时间戳, 脱敏后把 mtime 拨回去)——面板上那个 sha 才有核对的意义。

在电脑上验一遍(lib/*.js 改了必须重启一次 DSH,面板的 HMR 管不到服务端):

# 1. 重启 DSH 后,打开面板 → 小盒子 → 「打一份小盒子」
# 2. 没有红灯、出现「已放进下载文件夹:C:\Users\<你>\Downloads\留痕-YYYY-MM-DD.zip」即通过
# 3. 解压那个 zip,看中文名是否正常、00-读我.txt 第 20 行左右有没有「去向:」
# 4. 自检(可选,Windows 上也能跑):node scripts/selfcheck.js → 82/82

0.1.2(小更新,不是第二版)

  • 电脑分支:打包与列清单不再依赖系统的 zip / unzip 命令(Windows 上两者都没有), 改成 lib/zip.js 自己读写;lib/platform.js 管共享目录与文案
  • 打包结果可复现:同一天同样的数据两次打包 sha256 一致
  • 包里补回目录条目(含空目录),解出来的结构跟打进去的一致
  • /summary 多带一个 where 字段(os / kind / dir / label / word), 面板据此说「手机」还是「下载文件夹」
  • 自检 76 → 82 条:新增跨平台 4 条(手机路径、电脑路径、面板文案、zip 中文名往返)

0.1.1(小更新,不是第二版)

  • 面板每 30 秒自动刷新,不用关掉重开
  • 注入记账:liuhen/inject-state.json + 面板显示上一轮到底注入了没有
  • 「我是谁」第一次见面由助手自己写(新工具 trace_intro),面板补了名字输入框, 正文不再只认以 - 开头的行,写好了也能再「编辑」
  • 自检脚本修掉两处写死日期的假失败

许可

MIT