🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

本地笔记待办 warmwine/dsh-memoryleak

DeepSeek Harness
warmwine23 天前有提交已提供中文文档扫描:含敏感能力

把随手记的日志与待办存进本地 Markdown 仓库

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add warmwine/dsh-memoryleak
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]—
静态安装检查有提示项,装前建议看一眼 README
L4 · 真实安装等级说明 →
数据截至 2026/10/19·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 23 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查⚠ 装前注意
要求 Node:>=20(dsh 本身要求 Node ≥ 22.19)

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-memoryleak(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/30 15:17:24

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 53 处,展示前 48 条)
  • 读取本地文件
    src/index.js:526
    text = await readFile(path, 'utf8')
  • 写入本地文件
    src/index.js:544
    await writeFile(path, YAML.stringify(doc), 'utf8')
  • 读取本地文件
    src/index.js:554
    const retry = YAML.parse(await readFile(path, 'utf8')) ?? {}
  • 写入本地文件
    src/index.js:556
    await writeFile(path, YAML.stringify(retry), 'utf8')
  • 发起网络请求
    src/client.js:29
    const res = await fetch(API + path);
  • 发起网络请求
    src/client.js:36
    const res = await fetch(API + path, {
  • 发起网络请求
    src/client.js:864
    const res = await fetch(`${API}/files?limit=50`, signal !== null && signal !== undefined ? { signal } : undefined)
  • 发起网络请求
    src/client.js:966
    fetch(`${API}/files?limit=50`)
  • 发起网络请求
    src/client.js:1814
    fetch(`${API}/path/complete?prefix=${encodeURIComponent(value)}`)
  • 发起网络请求
    src/client.js:2379
    const res = await fetch(root + path, options);
  • 读取本地文件
    src/journal.js:88
    content = await readFile(path, 'utf8')
  • 写入本地文件
    src/journal.js:108
    await writeFile(located.path, alignOnWrite(located.path, next), 'utf8')
  • 读取本地文件
    src/journal.js:153
    return await readFile(join(cwd, name), 'utf8')
  • 读取本地文件
    src/journal.js:175
    const content = await readFile(path, 'utf8')
  • 读取本地文件
    src/journal.js:214
    let content = await readFile(path, 'utf8')
  • 写入本地文件
    src/journal.js:223
    await writeFile(path, alignOnWrite(path, content), 'utf8')
  • 读取本地文件
    src/journal.js:275
    content = await readFile(path, 'utf8')
  • 写入本地文件
    src/journal.js:285
    await writeFile(path, alignOnWrite(path, result.content), 'utf8')
  • 读取本地文件
    src/journal.js:307
    content = await readFile(path, 'utf8')
  • 写入本地文件
    src/journal.js:316
    await writeFile(path, alignOnWrite(path, result.content), 'utf8')
  • 写入本地文件
    src/journal.js:347
    await writeFile(path, alignOnWrite(path, result.content), 'utf8')
  • 写入本地文件
    src/journal.js:379
    await writeFile(path, alignOnWrite(path, next), 'utf8')
  • 读取本地文件
    src/vault.js:65
    info = await stat(absolute)
  • 写入本地文件
    src/vault.js:68
    await mkdir(absolute, { recursive: true })
  • 读取本地文件
    src/vault.js:90
    text = await readFile(resolve(vaultDir, VAULT_SETTINGS_FILENAME), 'utf8')
  • 读取本地文件
    src/vault.js:156
    const parsed = YAML.parse(await readFile(target, 'utf8'))
  • 写入本地文件
    src/vault.js:174
    await writeFile(target, body, 'utf8')
  • 读取本地文件
    src/vault.js:186
    const parsed = YAML.parse(await readFile(resolve(vaultDir, VAULT_SETTINGS_FILENAME), 'utf8'))
  • 读取本地文件
    src/vault.js:205
    const parsed = YAML.parse(await readFile(resolve(vaultDir, VAULT_SETTINGS_FILENAME), 'utf8'))
  • 读取本地文件
    src/vault.js:237
    const existing = YAML.parse(await readFile(target, 'utf8'))
  • 写入本地文件
    src/vault.js:250
    await writeFile(target, head + YAML.stringify(parsed), 'utf8')
  • 读取本地文件
    src/note.js:264
    return await readFile(path, 'utf8')
  • 写入本地文件
    src/note.js:273
    await writeFile(path, alignOnWrite(path, content), 'utf8')
  • 写入本地文件
    src/note.js:301
    await mkdir(dirname(backupPath), { recursive: true })
  • 写入本地文件
    src/note.js:302
    await writeFile(backupPath, existing, 'utf8')
  • 写入本地文件
    src/note.js:365
    await mkdir(momentoDir, { recursive: true })
  • 写入本地文件
    src/note.js:398
    await mkdir(dirname(path), { recursive: true })
  • 读取本地文件
    src/ask.js:36
    return await readFile(path, 'utf8')
  • 读取本地文件
    src/ask.js:75
    for (const name of await readdir(momentoDir)) {
  • 读取本地文件
    src/ask.js:92
    const names = (await readdir(vaultDir))
  • 读取本地文件
    src/mail.js:123
    const entries = await readdir(tmpdir())
  • 读取本地文件
    src/mail.js:130
    const info = await stat(path)
  • 删除本地文件递归
    src/mail.js:131
    if (info.isDirectory() && now - info.ctimeMs > 24 * 3600 * 1000) await rm(path, { recursive: true, force: true })
  • 写入本地文件
    src/mail.js:282
    await mkdir(dir, { recursive: true })
  • 发起网络请求
    src/mail.js:300
    for await (const message of client.fetch(uids.join(','), { envelope: true, internalDate: true }, { uid: true })) {
  • 写入本地文件
    src/mail.js:320
    await writeFile(join(dir, file), full.source ?? Buffer.from(''))
  • 读取本地文件
    src/mail.js:396
    const buffer = await readFile(join(dir, mail.file))
  • 删除本地文件递归
    src/tools.js:368
    await rm(dir, { recursive: true, force: true }).catch(() => {})
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 日志与待办管理

基于dsh的知识库和待办管理工具

README

由 DeepSeek 最新模型翻译生成
dsh-memoryleak 好记性不如烂笔头,有了 memoryleak 你就不会 memoryleak。 一个把记事本带进 DSH 的插件:记的东西全是本地 Markdown 文件,git 和任何编辑器都能直接用,换个工具也带得走。 [!WARNING] ⚠️ 隐私警示:谨慎使用本插件 ⚠️ 任何 dsh 工作目录都可以把笔记写进同一个 Vault——这同样意味着你的领导很容易通过蒸馏(distill)你的 Vault 摸清你的动态。 - 当前请谨慎使用本插件,想清楚什么能记、什么不能记。 - 后续会推出「失联即焚」功能。在此之前,务必做好云备份,甚至不要把 Vault 放在公司电脑上。 - 在此之后,更要做好备份,防止系统自燃。 更新历史 你能用它干什么 你在写代码的时候,总有各种事想顺手记下来:这个 bug 怎么修的、明天要跟进什么、哪天要交什么材料。这些事放进专门的笔记软件就散落各处,放在脑子里又会漏。这个插件把它们集中存在你自己指定的一个目录(Vault)里: - 先选一个 Vault,只用选一次。刚装好时设置是空的,执行任意 /ml 命令会引导你选一个本地文件夹:输入路径时Tab 自动补全(↑↓ 选候选,输 e 补盘符、~ 开头是用户目录),或直接用当前工作区;目录不存在会自动创建。之后所有日志、待办都固定写进这个目录,不再跟着会话的工作区跑。
展开完整文档(README 剩余 1 节)
dsh-memoryleak

好记性不如烂笔头,有了 memoryleak 你就不会 memoryleak。
一个把记事本带进 DSH 的插件:记的东西全是本地 Markdown 文件,git 和任何编辑器都能直接用,换个工具也带得走。

[!WARNING]
⚠️ 隐私警示:谨慎使用本插件 ⚠️

任何 dsh 工作目录都可以把笔记写进同一个 Vault——这同样意味着你的领导很容易通过蒸馏(distill)你的 Vault 摸清你的动态。

- 当前请谨慎使用本插件,想清楚什么能记、什么不能记。
- 后续会推出「失联即焚」功能。在此之前,务必做好云备份,甚至不要把 Vault 放在公司电脑上。
- 在此之后,更要做好备份,防止系统自燃。

更新历史

你能用它干什么

你在写代码的时候,总有各种事想顺手记下来:这个 bug 怎么修的、明天要跟进什么、哪天要交什么材料。这些事放进专门的笔记软件就散落各处,放在脑子里又会漏。这个插件把它们集中存在你自己指定的一个目录(Vault)里:

- 先选一个 Vault,只用选一次。刚装好时设置是空的,执行任意 /ml 命令会引导你选一个本地文件夹:输入路径时Tab 自动补全(↑↓ 选候选,输 e 补盘符、~ 开头是用户目录),或直接用当前工作区;目录不存在会自动创建。之后所有日志、待办都固定写进这个目录,不再跟着会话的工作区跑。换项目、换会话,记的事都在同一个地方。
- 想到什么,一句话记下来。输入 /ml 明天找财务对一下发票 回车,这句话就写进了今天的日志文件(2026-08-16.md)。文件就在 Vault 根目录,打开就能看,提交 git 就能留痕。
- 待办带结构和优先级。输入 /ml todo add 交季度报告(简写 n 或 a),会弹一个固定表单问你类型和重要程度,各选一项、选完自动提交;表单全程可键盘——数字 1/2/3 或字母 d/s/a 选类型(deadline/sleep/anytime)、字母 u/m/l 选重要程度(urgent/medium/low),按页脚提示来即可。选到 deadline / sleep 时输入区变成日期选择器(日历 + 今天/明天/本周/本月快捷键,数字键 1-4 直选、←→ 切月)。有截止日的到期自然浮出来;不急的可以设成"睡到"某天再提醒你。
- 找文件像 VSCode 一样快。输入 /ml view 加几个字母,输入框上方弹出候选列表,↑↓ 选、Tab 补全、回车打开。
- 收尾时把对话沉淀成笔记。干完一段活,输入 /ml note:把这一段对话交给当前模型,由它在会话里直接整理成工作记录、知识文件和结构化登记(详见下文「/ml note」专章)。思考、工具调用与回复全程原生显示,与普通对话完全同款。花 token 的命令有 /ml note、/ml ask 和 /ml mail read 三个,其余命令全部本地完成。
- 把工作邮箱也接进来。设置里配好 IMAP 账号(没配置时 /ml mail 会弹设置引导),之后 /ml mail read 只读「上次读完 → 现在」的新邮件:原文只进系统临时目录、用完即删(绝不碰 Vault),下载清理全程零模型调用,再用当前模型提取重要事件 / 待办 / 待阅(详见下文「/ml mail」专章)。
- 右侧 Dock 记事面板。界面右端的常驻小工作台:不敲命令就能记一笔、勾待办、翻今日日志(详见下文「右侧 Dock」专章)。

安装

0.18.0 起适配 dsh 0.2 桌面版(desktop profile;设置从 ~/.dsh/settings.yaml 迁入 profile 的 cordis.patch.yml,旧配置在首次加载时自动迁移)。dsh 0.1.x 的 web 版请继续用 0.17.x。

桌面版(0.2+)——桌面应用自带 dsh 命令行(设置里可装到 PATH;没装的话在 <安装目录>\resources\runtime\cli\bin\dsh.cmd):

dsh plugin --profile desktop add github:warmwine/dsh-memoryleak
重启桌面应用生效;或在「插件」页里装(支持本地路径 link:E:/…/dsh-memoryleak)卸载:dsh plugin --profile desktop remove dsh-memoryleak

旧 web 版(0.1.x):

dsh plugin --profile web add github:warmwine/dsh-memoryleak@0.17.1
重启 dsh web 生效卸载:dsh plugin --profile web remove dsh-memoryleak

装好之后在输入框敲 /ml help 看全部命令。

记的东西长什么样

全部是普通 Markdown 文件,放在 Vault 根目录。每天的日志叫 2026-08-16.md,每周的叫 2026W33.md(用哪种在设置里选):

start: 2026-08-10 ← 周志模板自带的起止日期 end: 2026-08-16

MemoryLeak ← /ml 记的流水账都在这里
- 上午重构了扫描器
- 下午修了候选卡错位

Todo ← /ml todo add 存的待办在这里
- [ ] (ml:deadline 2026-09-01 urgent) 完成设计稿
- [ ] (ml:sleep 2026-12-01 low) 学一遍内部源码
- [ ] (ml:anytime medium) 整理收藏夹
- [x] (ml:active low done:2026-08-16) 复盘一次上线

待办有四种类型:

| 类型 | 日期 | 是什么 |
| deadline | 必填 | 有截止日的事,到点就出现在列表里,可用 /ml todo p 延期 |
| sleep | 必填 | 暂时不想看见的事,到唤醒日才自动出现(出现时会自动改写成 active) |
| anytime | 不填 | 随便什么时候搞一下的事 |
| active | 不填 | sleep 睡醒之后的样子,系统自动转换,不用手动写 |

优先级三档:urgent(紧急)、medium(中等)、low(低)。完成一件事时(/ml todo d)会自动在后面记上完成日期(done:2026-08-16),取消完成或撤销时自动去掉;放弃一件事时(/ml todo c)复选框变 [-] 并记上取消日期(cancelled:2026-08-18),再执行一次恢复原样。就算你手动把文件的格式改坏了,那一条也只是变回普通待办,不会丢。

/ml note:把对话沉淀成笔记

干完一段活,输入 /ml note 回车(不带任何参数),插件把整理任务交给当前会话的模型,由它在会话里直接完成整理。花 token 的命令有 /ml note、/ml ask 和 /ml mail read 三个,其余命令全部本地完成。

工具边界(0.17.1):memory_ 模型工具只在 /ml 指令发起的回合里可用——判定从会话日志推导(交接消息必须是最近的回合发起事件),普通对话里模型调用会被一律拒绝并引导回命令。你在其他会话里让 AI「顺手记一下 / 查下笔记 / 收下邮件」,它动不了你的 Vault。右侧 dock 面板不经模型工具(走插件自有 HTTP API),不受影响。

整理范围:只处理「上一次成功整理之后 → 现在」的对话;本会话第一次执行则整理全部上下文。所以一支会话可以多次执行,每次只消化新的一段——不重复、不越压越胖。只有模型成功调用写入工具的那次才算边界:模型没干活或写入被守卫拒绝的整理不消化它身前的对话,下次执行从更早的最后一次成功整理起算,重试不丢内容。

过程与普通对话完全同款:命令敲下后出现一条任务交接消息,之后就是一场普通回复——思考过程流式显示为可折叠思考块;模型先后调用 memory_note_context(拿存量登记与记录约定)和 memory_note_write(提交整理结果)两个真实工具,工具卡片在思考与输出过程中内联出现、转圈、翻到完成态(写入清单一目了然);最后的整理确认以原生 markdown 回复落定,进入对话上下文。模型忘了干活、或写入被守卫拒绝,你都看得见——它自己也会收到错误并重试。

产出四样东西(模型只负责压缩抽取,落盘格式全部由代码决定):

① 工作记录(当天/本周日志的 ## NOTE 段,每次整理一个 ### 小节,纯追加)

NOTE
14:30 · 把 /ml note 命令从零做到能跑
- core 纯逻辑:转写裁剪、协议解析、渲染
- 宿主胶水:区间定位、llm 调用、落盘

② 知识文件(MOMENTO/ 目录)

MOMENTO/
├── index.md ← 知识索引(按文件名去重更新) ├── dsh-llm-stream-用法.md ← 一条长期知识一个文件;同名再写追加「## 更新 <日期>」 ├── databases.md ← ③ 结构化登记:表格由代码渲染,按「名称」主键合并 ├── servers.md ← 服务器:名称 / 主机 / IP / 登录用户 / 系统 / 备注 ├── credentials.md ← 凭证:只登记「在哪、什么账号」,永不保存明文密码 └── glossary.md ← 术语表:术语 / 含义 / 备注

④ 汇总回执:整理范围(含消息数与是否裁剪)、写入文件清单、模型与 token 用量;条目不合规逐条告警而非整体失败。

零丢失写入:

- 压缩前先把 Vault 里的已有登记(databases/servers 等表格行、知识条目标题)喂给模型,要求增量增补——只输出新条目或有变化的字段(留空 = 保留原值),不会把本段对话当成全部上下文重建文件;
- 合并只认声明的格式;你手写的文件、格式对不上的内容永远不会被重写——内容对不上时只会在文件末尾追加一个带日期的小节;
- 表格列宽自动对齐(写时 lint):插件写回 markdown 文件时(/ml 记录、todo 增改与 d/c/p/u、/ml note 落盘),自动把该文件里所有规范表格按每列最大宽度补空格对齐(中文按 2 列宽计,分隔线随列宽伸展、对齐冒号保留)。只补空白不动内容——单元格文字逐字保留;代码围栏内、列数不齐(手改坏)、缩进 ≥4 的表一律不碰;
- 每次写入前有防丢失守卫(合并后条目必须包含合并前的全部主键,否则拒绝写入);备份默认关闭(git 兜底),可在 vault 配置 noteBackup: true 开启(见下);
- 字段白名单、条数与长度上限、| 与换行清洗——模型输出无法破坏文件结构。

两个使用注意:

- /ml note 后面不要跟文字——跟在后面的内容不会发给助手也不会被记录,命令会直接报错并提示正确用法;
- 模型用的是当前会话正在用的那个;整理在会话里现场完成,整理过程占一轮对话上下文(换来的是模型之后记得整理过什么,追问不失忆)。

/ml ask:把 Vault 当资料库向 AI 提问

/ml note 是把对话写进 Vault,/ml ask 反过来:把 Vault 读出来当资料,用当前模型回答你的问题。只读,绝不写 Vault。

/ml ask 生产主库的端口是多少?
/ml ask 我之前记过哪些 redis 的坑?

- 资料自动汇集:模型调用 memory_ask_gather 工具拿资料包——MOMENTO 索引 → 结构化登记(databases/servers 等,含 noteStructured 声明的自定义目标)→ MOMENTO 知识条目(按问题关键词挑最相关的在前)→ 近期日志(最近 3 份)。总量控制在约 8 万字符预算内,超出部分从队尾丢弃、长条目截断。
- 回答要求标注来源:模型被要求只依据资料回答、引用事实标注来源文件(如「MOMENTO/databases.md」)、笔记里没有的就直说没有、不编造。
- 过程与普通对话完全同款:命令后出现一条任务交接消息 → 模型原生思考、调工具拿资料、输出 markdown 回答(与普通回复同样的渲染)→ 回答自然进入对话上下文,可以接着追问。
- Vault 里还没有任何内容时会明确报错(先 /ml note 或直接写文件)。

note / ask 是纯 Vault 内的两个花 token 命令;mail read 花的 token 只用于分析邮件,不写 Vault。

/ml mail:工作邮件增量阅读

把 IMAP 邮箱接进 /ml,专门解决「攒了一收件箱没看」的问题——只读新邮件、提取要点,邮件原文绝不落 Vault。

先设置(三选一):

- 没配置时执行 /ml mail(或 /ml mail read),直接弹设置引导对话框:服务器 / 账号 / 密码三项(web 端是一张表单卡,密码遮蔽输入),填完真连一次 IMAP 试登陆,通过才保存;
- /ml mail setup 随时重配(留空提交 = 沿用当前值,换服务器不用重输密码);
- GUI 设置 → MemoryLeak 的「邮箱(/ml mail)」分区:登陆方式(密码/授权码 或 OAuth2 token)、服务器、端口(默认 993)、TLS、账号、密码、token、邮件目录(默认 INBOX)、单次上限(默认 50 封)。

QQ / 163 / 126 等邮箱要在网页版设置里开启 IMAP 并生成「授权码」,密码处填授权码而不是登陆密码。密码明文只存本机 DSH 的 profile 配置(cordis.patch.yml),双写同步会把它从 Vault 设置文件里剔除——凭证不进 Vault、不随目录迁移。配置好后裸 /ml mail 显示邮箱状态与上次读完时刻。

/ml mail read 增量阅读:

- 窗口:只处理「上次 read 结束 → 现在」的新邮件,首次默认当天 00:00 起。结束时刻记在 Vault 根 .memoryleak.yaml 的 mailState.lastReadEnd(vault 限定键,GUI 保存不会冲掉,随 Vault 迁移);进度由两段式工具保证——memory_mail_fetch 只下载解析不推进,模型输出报告后才调 memory_mail_commit 推进(漏调 = 下次重读同一批,绝不漏邮件)。超单次上限保留最新、丢最旧的会如实告知。
- 两条铁律:① 邮件原文只下载到系统临时目录(一次性目录,用完即删;崩溃残留由下次执行清扫 24 小时以上的旧目录),绝不写进 Vault 或当前工作区;② 下载与清理全程零模型调用——窗口内没有新邮件时工具直接说明,模型只转告一句「没有新邮件」。
- 分析(花 token,与普通对话同款原生渲染):模型通读邮件后直接输出 markdown 阅读报告——总评 + 重要事项(唯一的编号清单),所有重要的事务与信息都在同一份清单里:需要动手处理的、需要跟进的、值得知道的;需要处理的条目标注期限与来源,思考与输出全程在会话里可见。
- /ml mail todo <序号>:把最近一次 read 报告「重要事项」清单的第 <序号> 条转成 Vault 待办——走与 /ml todo add 完全相同的表单(类型 / 优先级),条目里明说期限的,选 deadline 时自动带入选中的期限(不用再填日期)。清单随 memory_mail_commit 存进 Vault(mailState.lastItems),跨会话、跨重启都可引用。
- 连接失败给排障提示:认证被拒 → 检查授权码;连不上 → 检查地址端口;TLS 失败 → 检查端口与开关匹配(993 开、143 关)。自建 Exchange 报 unable to verify the first certificate 不是端口问题:握手是通的,是内部 CA/自签证书 Node 不信任(Windows/Outlook 走 Windows 证书库,Node 不读它)。此时 setup 引导会弹出「信任并保存」一问——确认后插件自动抓取服务器证书存入设置(不落地其他文件),之后的连接以它为信任锚继续严格校验(证书链 + 主机名);拒绝或取证失败,可在 GUI 设置勾选「跳过证书校验」兜底(不再验证服务器身份,连接仍加密),「信任的证书」文本框也可手改。维护者排障工具:scripts/probe-mail-tls.mjs(分层定位网络/端口/证书)、scripts/export-imap-ca.ps1(导出证书链 + Node 自检)。

适配你自己的老库格式(vault 限定配置)

不想用内置的 MOMENTO/databases.md 标准表格?你的老库是自定义表头、YAML 列表、甚至「markdown 小节 + 内嵌 YAML 块」?在 Vault 根的 .memoryleak.yaml 里加一段 noteStructured,声明每类知识写到哪个文件、什么格式——这几个 note 配置键只住在这个文件里(GUI 保存不会冲掉,手改即生效),不配的类别继续用内置默认。三种格式:

noteStructured:
① markdown 小节 + 内嵌 yaml 块(复杂手工库):### 标题按模板定位,块按复合主键匹配,命中块内合并 / 节内追加块 / 末尾未分类章追加 databases: file: momento/databases.md format: sections heading: "{host}:{port}" # ### 标题模板(存储字段占位符)
key: [host, database] # 复合主键(同机多库各一条)
fields: [host, port, database, user, notes]
aliases:
notes: note # 模型字段 → 老库字段名(改名映射) extraFields: # 老库自有字段白名单(模型可填)
- key: environment
desc: production 或 test
- key: purposes
desc: 这台库上跑的功能(列表)未声明的字段(如 password)模型永不填写、合并时原样保留 ② 纯 YAML 对象列表 servers: file: infra/servers.yaml format: yaml
fields: [name, host, ip] # 内置字段的子集(省略 = 全集)
key: name # 单字段或数组主键 ③ 自定义表头的 markdown 表格 glossary: file: infra/terms.md format: table
header: [术语, 含义, 备注] # 你的表头(与 fields 一一对应)

规则与安全线(三种格式通用):按主键合并(新值非空才覆盖,列表字段追加去重);未声明的字段原样保留(老库的 password/rack/owner 等自有键模型不碰);格式对不上(表头不匹配 / YAML 不是列表 / 块解析不了)时只追加、绝不重写;写回 markdown 时全文件表格列宽自动对齐,但只补空格、单元格文字逐字保留,代码围栏内与列数不齐的表不动;防丢失守卫(条目只增不减,违反拒绝写入)始终生效。aliases 让模型说内置字段名(name/user/notes),落盘自动映射到你库里的字段名(hostname/admin/note);extraFields 里声明的自有字段(environment/purposes…)会连同说明一起告诉模型,转写中出现才填。

备份:默认不备份——vault 用 git 管理时版本历史就是兜底,不再产生裸露的 .bak 文件。需要时在 vault 配置里加 noteBackup: true 开启:修改已有文件前自动备份进 .backup/ 隐藏目录(保留原相对路径 + 时间戳,多次备份不互相覆盖;该目录已在默认扫描排除列表里)。

还可以放一个 note skill(记录约定):noteSkill: MOMENTO/.note-skill.md 指向一个 markdown 文件,内容会注入给模型当本 vault 的约定(命名习惯、必须标注的字段……),格式仍由代码强制:

本 Vault 的记录约定
- 服务器一律用「机房-编号」命名(如 bj-01),主机只写内网 IP
- databases.notes 必须标注环境(prod/staging/dev)
- credentials 只写 1Password 条目名,不写路径

右侧 Dock:不敲命令的 /ml 工作台

浏览器界面右端的常驻面板,上下两块。打开是推挤而非遮盖:面板展开时主窗口整体让位变窄(运行时定位应用骨架并设内联 padding-right,与官方左栏折叠同一使用感受,带 0.18s 过渡动画),关闭即还原;重载后面板默认收起(与官方 details 列一致,布局几何是瞬态的)。开关有两处:会话头右侧的橙色「✎ 记事」按钮(主开关),以及侧栏底部 Settings 旁的兜底开关(blank 会话也能用);Esc 或 ✕ 收起。

- 上半(记录区):一行「记一笔到今天」输入框(Enter 写入当前日志);下面是一张橙色调卡片(左缘橙条 + 橙染底),只列今天已记的条目(服务端从日志/周志按写入文法提取,周志只取今天的日期组;宿主为旧版时客户端回退提取),头部显示文件名与笔数,点标题折叠,记一笔或加待办后自动刷新——看文件全文用 /ml view;
- 下半(待办区):与记录区用更明显的分隔线划开,无底色直接铺列;状态过滤按钮(未完成 / 全部 / 已完成 / 已取消,选中项橙底墨字);「+ 新待办」展开小表单(内容 / 类型 / 优先级 / 日期,落盘与 /ml todo add 完全同构);待办列表——复选框就是方框本体(加粗描边、符号居中;未完成悬停浮出橙色 ✓ 提示、完成打绿 ✓、取消灰 ✕),悬停出「取消」/恢复、deadline 型「+1天」延期;「撤销(n)」依次撤销本面板最近 n 次操作。到日的 sleep 待办自动唤醒;过期 deadline 日期标红、urgent 标警示色。侧栏的「✎ 记事」开关是橙色胶囊,面板打开时加橙色外环。整个 dock 以品牌橙(#ff9000)做身份色:面板左缘橙条、标题橙点、记一笔条目橙点。

字体与字号:整个面板只在根部声明一次 var(--dsw-font-s-14) 主题令牌(家族 + 14px/22px),全部子元素继承——因此天然跟随 dsh-ui-font 插件的换字体与全局缩放(它在 body 上重定义 --dsw-font- 令牌);本插件注入的样式表也都打了 data-plugin 标记,纳入它的按插件字号调整。

面板与命令是同一枚硬币的两面:同一个 Vault、同一套核心函数,互相实时可见——dock 里勾掉的事,/ml todo list 立刻反映;命令加的待办,面板一刷新就在。Vault 未设置时面板显示引导(去设置页或 /ml init)。

挂载与兼容性设计(面向 DSH 升级)

DSH 的浏览器端约定会随升级演进(0.16.3 的 composer 契约变更就是一次实录)。dock 因此做成三层,把「会变的东西」关进最小的一层:

1. 插件自有 HTTP API(宿主侧 src/dock-routes.js,/api/memoryleak/dock/*):面板只与这份插件自己声明、自己演进的契约对话——业务全部复用与命令同一套核心函数,与 DSH 版本无关;
2. 纯 UI 组件(createMlDock({ React, api })):零 DSH 依赖的组件工厂,数据进出全是 JSON;
3. 薄挂载适配(mlMountDock 的候选挂载位表):唯一知道 DSH 槽位名的地方。候选挂载位逐个尝试、各自隔离故障——今天坐 shell.overlay(面板本体,root 作用域)、conversation.session.header.utilities(会话头开关)与 sidebar.footer.action(侧栏兜底开关),都是只加条目、不替换任何官方 UI 的无风险槽位(特意不碰右侧 details 列——它是 single 槽,注册即顶掉官方工具详情面板);全部失败时 dock 静默缺席(console.warn 留痕),其余功能不受影响。将来 DSH 提供官方停靠位、或现有槽位协议变化,只改这张候选表。推挤式布局由 mlApplyPushState 运行时完成:从官方稳定锚点([data-conversation-scroll] / [data-composer-input])攀爬定位应用骨架元素并设内联 margin-right 让位——不依赖对挂载结构的静态猜测;定位不到时自动退回覆盖式,功能不受影响。

命令一览

完整说明输入 /ml help 随时看,这里列个速查:

| 命令 | 干什么 |
| /ml init | 指定/更换 Vault 目录(唯一的设置入口) |
| /ml <文本> | 记一笔到今天(或本周)的日志 |
| /ml todo add <内容>(简写 n / a) | 加待办,弹表单选类型和优先级(表单支持键盘快捷键) |
| /ml todo list(简写 l) | 列出待办,默认只看没完成的 |
| /ml todo list all / open / done | 按状态过滤 |
| /ml todo list <关键词> | 按关键词过滤 |
| /ml todo d <序号>(简写 done) | 把列表里第几条标成完成(或取消完成) |
| /ml todo c <序号>(简写 cancel) | 取消该待办:变 [-] 并记 cancelled:日期;再执行恢复,从默认列表隐藏 |
| /ml todo p <序号> [天数](简写 postpone) | deadline 型延期:不填天数延 1 天;非 deadline 报错 |
| /ml todo u(简写 undo) | 反悔最近一次 d / c / p,连按可以一路撤回去 |
| /ml note | 用当前模型压缩区间对话进 MOMENTO/ 与日志 ## NOTE(花 token) |
| /ml ask <问题> | 反向:拿 Vault 当资料库向当前模型提问(只读,花 token) |
| /ml mail | 工作邮件:未配置弹设置引导(试登陆后保存),已配置显示状态 |
| /ml mail read | 增量阅读新邮件 → 提取重要事件/待办/待阅(原文只进临时目录,花 token) |
| /ml mail todo <序号> | 把上次 read 报告「重要事项」第 <序号> 条转成待办(同 todo add 表单) |
| /ml mail setup | 重新走邮箱配置引导(改密码/换服务器) |
| /ml view(简写 v) | 看今天(或本周)的日志 |
| /ml view <文件名几个字母> | 模糊找文件直接打开 |
| /ml help(简写 h) | 看这份说明 |

Vault 未设置时,除 help / init 外的所有命令都会直接报错并提示先执行 /ml init——init 是唯一严格的目录设置入口,不会自动弹引导。

输入 /ml view 后继续打字,输入框上方会弹实时候选:当前日志排第一个,下面是匹配的文件。↑↓ 换选中的,Tab 把文件名补全到命令里,回车直接打开,Esc 关掉。

设置分两层,都是手改友好的 YAML:

- 全局层存在 DSH profile 的 cordis.patch.yml 里 memoryleak 条目的 config: 段(dsh 0.2 统一位置;dsh 0.1 时代在 ~/.dsh/settings.yaml,升级后自动迁移)。GUI 设置面板 → MemoryLeak 分区改的就是它:Vault 目录(「浏览…」弹系统目录选择对话框,「清除」一键置空)、扫描哪些扩展名、排除哪些目录、数量上限、默认过滤、用日志还是周志、两个模板的内容,以及邮箱(/ml mail)的账号、密码/授权码、登陆方式等——mail 账号键只住这一层(vault 文件里写了无效,双写同步时剔除,凭证不进 Vault)。
- Vault 层是 Vault 根目录下的 .memoryleak.yaml。GUI 保存与 /ml init 都会双写——全局与这个文件同步为同一份,换台机器把整个 Vault 拷走、设置跟着走。读取时此文件里的键优先级更高(vault 路径与 mail 账号键除外——它们只认全局层);缺键回退全局层,全局层也没有就用默认值;文件写坏了也不崩,按缺失处理。手改这个文件仍可读,但下次 GUI 保存会被覆盖——例外是 noteStructured / noteSkill / noteBackup 这几个 vault 限定键与 mailState(/ml mail 的读信进度):它们只住这一层、GUI 不展示,双写同步时原样保留(见上文「适配老库格式」与「/ml mail」专章)。

两件可能让你困惑的事

新建会话里命令没反应? DSH 的设计是:一个会话在发出第一条消息之前不挂聊天记录区,所以这时跑任何斜杠命令(包括官方的 /plan)结果都看不见,但命令其实执行了,文件也写了。随便发一条消息,之前的命令卡片就会补出来。

改了代码没生效? 浏览器部分(设置窗口、候选卡、命令卡片)刷新页面就行;核心逻辑(命令处理、扫描、文件读写)在服务端,要重启 dsh web。

开发

pnpm install
pnpm test # 520 个测试
代码分四层:src/core/ 是纯逻辑(含 core/note.js:转写裁剪 / 协议解析 / 落盘渲染;core/mail.js:读信窗口 / 邮件预算 / 分析协议解析 / 流式摘要),不碰文件系统,测试直接跑;src/adapters/ 负责真实的文件读写(测试用内存版替换);src/journal.js、src/note.js、src/mail.js 是宿主胶水(日志写入、区间定位、ctx.llm.stream 压缩调用、IMAP 下载与读信编排——imapflow + mailparser 两个运行时依赖,测试全部注入伪客户端/伪模型,不碰真实网络);src/index.js 和 src/client.js 分别是服务端和浏览器两端。src/dock-routes.js 是 dock 面板的宿主侧桥(复用上述核心,浏览器侧对接代码在 src/client.js 的 Dock 段——三层封装见上文「挂载与兼容性设计」)。

给 AI 留了接口但还没启用:新的待办格式只需要注册一个新的解析策略;renderTodoJson 输出稳定的 JSON,将来 AI 可以直接按这个格式读和筛待办。

License

MIT
预览分享卡片长什么样 ↓warmwine/dsh-memoryleak
分享 · DeepSeek Harness Hub
warmwine/dsh-memoryleak

把随手记的日志与待办存进本地 Markdown 仓库

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部