dsh-notebook
Manifest validPersistent cross-day notebook plugin for DeepSeek Harness (DSH): append, list, search and delete notes kept in notes.md.
dsh-notebook
给 DeepSeek Harness(DSH)的跨天长期笔记本:四条工具,一个纯文本文件,笔记跨会话、跨重启保留。
仓库:https://github.com/mllun/dsh-notebook · 问题反馈:https://github.com/mllun/dsh-notebook/issues
- 零第三方依赖:只用 Node 内置模块(
fs/os/path) - 数据落在
$DSH_HOME/dsh-notebook/notes.md,不写死任何本机路径 - 写入是原子的(临时文件 + rename),同进程内所有操作串行排队
- 面向 agent 设计:工具描述写清参数、默认值、边界和失败方式
适合记「以后还要用」的零碎信息:约定、待办、配置片段、某个决定的理由。它不是知识库,也不做全文索引——几千条以内最舒服。
目录
功能
| 工具 | 一句话 |
|---|---|
note_add(content, tag?) | 追加一条笔记,返回行号;与已有笔记完全重复时跳过 |
note_list(limit?) | 取最近 N 条(默认 20,上限 200),带行号 |
note_search(query, limit?) | 大小写不敏感的子串检索,返回命中行与行号 |
note_delete(index) | 按行号删除;越界给可读错误,文件不被修改 |
四条工具读写同一个 UTF-8 文件,行格式固定为:
ISO时间 | tag | 内容
例如:
2026-10-21T00:23:40.123Z | 生活 | 记住买牛奶
2026-10-21T00:25:01.456Z | - | 没有标签的笔记
工具参考
note_add(content, tag?)
追加一条笔记。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
content | string | 是 | 笔记正文。单行,最多 200 字(按 Unicode 字符计,不是字节)。换行会被压成空格;首尾空白会被去掉。 |
tag | string | 否 | 可选标签。省略、空字符串或全空白时写 -;标签内的 | 会被替换成全角 |,避免破坏行格式。 |
返回:
| 字段 | 说明 |
|---|---|
added | true 新写入;false 表示重复而跳过 |
line | 本条的行号(重复时是已有那条的行号) |
total | 写入后的笔记总数 |
message | 人类可读的结果说明 |
行为细节:
- 重复判定:
content(去首尾空白、单行化后)与tag都相同才算重复。同样的内容配不同 tag 会各存一条。 - 超长/为空:内容为空或超过 200 字时直接报错,不会写入,也不会截断。
- 时间:写入时的 ISO 时间(UTC,带
Z),例如2026-10-21T00:23:40.123Z。
note_list(limit?)
列出最近的笔记,按文件顺序(旧 → 新)返回。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
limit | integer | 20 | 返回条数;可填 1–200,超过 200 按 200 返回 |
返回 total(笔记总数)、returned(本次条数)和 notes 数组,每条含 line / time / tag / content。
文件不存在或为空时返回空列表,不报错。
note_search(query, limit?)
在笔记中做大小写不敏感的子串检索,内容和 tag 都会匹配。
| 参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
query | string | — | 纯文本子串,不是正则;不能为空 |
limit | integer | 20 | 最多返回多少条命中,可填 1–200 |
返回 matched(命中总数)、returned(本次条数)和命中的 notes,每条带行号与整行内容。结果按文件顺序(旧 → 新)返回;命中超过 limit 时只显示最近 limit 条。
note_delete(index)
按行号删除一条笔记。
| 参数 | 类型 | 说明 |
|---|---|---|
index | integer | 从 1 开始的物理行号,对应 notes.md 里的行 |
删除后原子写回文件,其余行内容不变。以下情况返回可读错误且不修改文件:
- 行号超出范围(大于总行数)
- 行号小于 1 或不是整数
- 目标行是空行
删除不可撤销,没有回收站。操作前建议先用
note_list/note_search确认行号。
数据文件
位置
$DSH_HOME/dsh-notebook/notes.md
未设置 DSH_HOME 时:
~/.dsh/dsh-notebook/notes.md
解析顺序与 DSH 其他组件一致:$DSH_HOME 环境变量优先,否则用户主目录下的 .dsh。插件从不硬编码盘符或用户目录。
同一台机器上的所有 DSH profile 共享这一个文件(因为 DSH_HOME 是全局的)。如果你希望不同 profile 分开记,可以给某个 profile 单独设置 DSH_HOME。
格式
- UTF-8 明文,LF 换行(Windows 上手工编辑成 CRLF 也能读)
- 每行一条:
时间 | tag | 内容 - 时间不含
|;tag 不含|;内容里可以有|(只按前两个分隔符切分) - 没有 tag 时写
- - 行号从 1 开始,就是文件的物理行号
备份与迁移
直接复制 notes.md 即可。想多设备同步,可以把这个文件放进同步盘或用私有 Git 管理它——但注意多进程并发的限制。
安装
方式一:从源码安装(推荐)
git clone https://github.com/mllun/dsh-notebook.git
然后在 DSH 里让 agent 执行(或通过插件管理器):
plugin_manager action: install_bundle target: <克隆下来的目录绝对路径>
这是本地 bundle 安装:DSH 会把该目录链接进 profile,之后修改源码即可热更新。
方式二:手动放进插件目录
不推荐。请让 DSH 的 plugin_manager 完成安装,它会负责依赖链接、bundle 选择和注册,手改 profile 的 package.json / cordis.patch.yml 容易漏步骤。
安装后验证
对 agent 说:
- 「记一下:周五之前把报价单发出去」
- 「列一下最近的笔记」
- 「搜一下『报价单』」
或者直接检查数据文件:
cat "$DSH_HOME/dsh-notebook/notes.md"
升级与卸载
- 升级:
git pull后重装/重启 DSH;本地链接安装会直接使用新代码,但已加载的模块可能要到下次启动才换成新的一代。 - 卸载:在插件管理器里移除
@local/dsh-notebookbundle。卸载不会删除notes.md,数据仍然在原来的位置。
使用示例
用户:记一下,DSH 的插件数据目录在 $DSH_HOME 下,别写死路径。
助手:(调用 note_add)
已追加到第 1 行,当前共 1 条。
用户:把刚才那条加上标签「DSH」
助手:(note_add 会当成新的一条,因为 tag 不同)
已追加到第 2 行,当前共 2 条。
查看与清理:
用户:列一下最近的 5 条
助手:(note_list limit=5)
用户:搜一下「数据目录」
助手:(note_search query="数据目录")→ #1 ...
用户:删掉第 1 条
助手:(note_delete index=1)
已删除第 1 行,当前共 1 条。
可靠性与设计
- 串行:同一进程内所有读改写经过一个 Promise 队列,两个工具同时调用不会交错覆盖。
- 原子写:先写同目录临时文件,再
rename覆盖;崩溃不会留下半截notes.md。 - 无依赖:没有 npm 依赖、没有原生模块、没有网络请求;数据只在本机。
- 宽容读取:文件不存在视为空笔记本;手工编辑出的、不符合格式的行也会作为笔记列出(时间留空、tag 记为
-),不会凭空消失。 - 编码:严格按 UTF-8 读写,不写 BOM。
注意事项与已知限制
- 所有 agent 共享:工具注册在 Host 全局,同一 DSH 进程里的每个会话、每个子 agent 都能读写同一本笔记。别把它当私有日记;敏感信息不要写。
- 删除不可撤销:没有回收站、没有 undo。
- 重复判定看「内容 + tag」:同内容不同 tag 会各存一条;想合并请先删再加。
- 200 字硬上限:超长直接报错而不是悄悄截断;长文请拆成多条或存在别处。
- 行号是物理行号:手工插行/删行/留空行都会让行号变化。删除前先
note_list确认。 - 多进程没有跨进程锁:同一 DSH 进程内安全;两个 DSH 实例(或一个 DSH + 手工编辑)同时写同一文件时,后写者会覆盖前者。用同步盘/Git 同步时尤其要避免同时写。
- 全量读写:每次操作都会读一遍整个文件。几千条以内没问题;几十万行会很慢。
- 没有
note_edit:要改一条,先删掉再重写。 - tag 长度不限但不建议过长:列表和检索里都会完整显示。
- 明文存储:
notes.md是普通文本,权限跟随系统默认;不要写密码、令牌等秘密。 - 时间统一 UTC:显示的是写入时刻的 ISO UTC 时间,和本地时区可能差几小时,这是有意为之(跨时区不歧义)。
- 版本兼容:需要带
tools服务的 DSH(当前 0.2.x 桌面版验证通过)。若tools不可用,插件会明确报错而不是静默失败。
常见问题
笔记到底存在哪?
$DSH_HOME/dsh-notebook/notes.md。没有设置 DSH_HOME 就是 ~/.dsh/dsh-notebook/notes.md。插件在运行时才解析路径,所以改环境变量后新写入会跟随新位置。
为什么我写的内容没出现?
最常见的是重复:内容和 tag 都和已有条目一样时会被跳过,返回的 line 指向已有那条。其次检查是否超过 200 字或内容为空——这两种情况会报错且不写入。
为什么搜索没命中? 检索是子串匹配,不是分词;试试更短的关键词。内容和 tag 都会匹配,大小写不敏感。
删除后行号怎么变了? 删掉一行后,后面的行号会前移。这是物理行号的正常行为,不是 bug。
能同步到别的机器吗?
可以:复制文件,或用同步盘/私有 Git 管理 notes.md。但不要让两个 DSH 同时写同一份文件。
卸载会丢笔记吗?
不会。卸载只移除插件,notes.md 保留在原处;重新安装后继续用。
开发
dsh-notebook/
├── index.js # Host 插件:注册四个工具、输出渲染
├── lib/notes.mjs # 存储层:解析、去重、串行队列、原子写
├── cordis.patch.yml # bundle 补丁:插入 dsh-notebook 行
├── locale/ # 插件管理器显示用的标题/描述(中/英)
├── icon.svg # 插件图标
├── test/smoke.mjs # 冒烟测试(临时 DSH_HOME + 跨进程读回)
└── README.md
运行测试:
node test/smoke.mjs
测试会:
- 在系统临时目录建一个隔离的
DSH_HOME - 覆盖追加、去重、列表、检索(大小写不敏感、按 tag 命中)、删除
- 验证 200 字边界、越界删除、空行删除的可读错误
- 另起一个 Node 进程读回文件,证明数据确实落盘
- 结束后清理临时目录
代码里没有测试框架依赖,node:assert 足够。
版本
1.0.0 — 首个公开版本。
License
English
dsh-notebook is a persistent, cross-session notebook plugin for DeepSeek Harness. It registers four agent tools backed by a single UTF-8 file at $DSH_HOME/dsh-notebook/notes.md (default ~/.dsh/dsh-notebook/notes.md):
note_add(content, tag?)— append a note and return its line number; identical content+tag is skipped.note_list(limit?)— most recent notes (default 20, max 200) with line numbers.note_search(query, limit?)— case-insensitive substring search over content and tag.note_delete(index)— delete by 1-based physical line number; out-of-range returns a readable error and leaves the file untouched.
Each line is ISO time | tag | content; no tag is written as -; a note is capped at 200 Unicode characters. Writes are atomic (temp file + rename) and all operations in one process are serialized. The plugin has zero third-party dependencies, makes no network requests, and stores data in plain text.
Install by cloning this repository and installing the directory as a DSH bundle (plugin_manager install_bundle). Uninstalling does not delete notes.md.
Comments
Loading…