dsh-mail-digest
给 DSH 装一个邮件通道:每轮回答结束后,把一条详略得当的中文摘要发到你的邮箱; 而且你可以直接回邮件——用邮件回答我的提问、收到摘要后续接对话。 地址、授权码、收件人全在设置页里填,不用改配置文件、不用命令行。
它能解决什么问题
- 不用守着屏幕:回答完了自动发邮箱,手机上就能看到进展。
- 离开电脑也能继续干活:回一封邮件就是一条新指令,对话继续往下走。
- 离开电脑也能批准:需要放行的操作发到邮箱,回信
1即可——不必坐在电脑前点按钮。 - 摘要不是全文搬运,也不是固定字数截断:长度由结论多少决定,结论少就一句话,结论多就多写几句。
- 纯本地收发:自己实现的零依赖 SMTP + IMAP,不经过任何云服务,不装额外依赖。
- QQ / 163 / 126 预置:选一个邮箱类型,服务器和端口自动填好,只要填地址和授权码。
安装
在普通 PowerShell 窗口里跑(不要走 DSH 沙箱:沙箱写不了 ~\.dsh):
# 一键脚本(装 / 卸载都行)
powershell -ExecutionPolicy Bypass -File .\安装邮件摘要.ps1
powershell -ExecutionPolicy Bypass -File .\安装邮件摘要.ps1 -Uninstall
或者手动两步:
# 1. 让插件能从自己的 node_modules 解析 DSH 官方包(junction,不占空间)
$dest = ".\node_modules\@deepseek-ai"
New-Item -ItemType Directory -Force $dest | Out-Null
$src = Get-ChildItem "$env:LOCALAPPDATA\npm-cache\_npx\*\node_modules\@deepseek-ai" -Directory |
Select-Object -First 1
Get-ChildItem $src.FullName -Directory |
ForEach-Object { cmd /c mklink /J "$dest\$($_.Name)" $_.FullName }
# 2. 装进 web profile(用 link: 软链,改代码即生效)
dsh plugin --profile web add "link:$($PWD.Path)"
装完重启 DSH(退出桌面应用时会连后端一起重启),然后打开设置页:
http://127.0.0.1:3080/dsh-mail-digest
配置
设置页五块,填完点「保存」,再点「发送测试邮件」;要用回信功能就再点「测试收信」:
| 填什么 | 说明 |
|---|---|
| 邮箱类型 | QQ / 163 / 126 / 自定义 SMTP |
| 发件邮箱地址 | 你的完整邮箱地址 |
| 授权码 / 密码 | 不是登录密码。网页版邮箱 → 设置 → 账户 → 开启 IMAP/SMTP 服务后生成的授权码 |
| 收件地址 | 留空 = 发给自己 |
| 回信通道 | 打开「启用回信通道」才能回信(需要邮箱已开启 IMAP 服务) |
点「发送测试邮件」验证发信,点「测试收信」验证 IMAP 登录(只验证登录,不读你任何邮件内容)。
授权码只存在本机 %USERPROFILE%\.dsh\dsh-mail-digest\config.json,界面回显时永远是空的。
常见问题
| 现象 | 原因与处理 |
|---|---|
提示授权码不对(535) |
用的是登录密码。要去网页版邮箱单独生成授权码,并先开启 IMAP/SMTP 服务 |
| QQ 邮箱回复后标记里有空格 | 正常。手机客户端会按显示宽度插空格([DSH-Q:x] → [D SH-Q:x]),插件能认出来。不要去手改主题 |
| 收不到我发的摘要 | 看设置页的「发送测试邮件」结果;再确认收件地址没填错(留空是发给自己) |
| 回信没反应 | 主题里的 [DSH-?:...] 标记不能删或改;发件邮箱必须是配置里的收件地址;另外收信默认 15 秒一轮,最多等十几秒 |
| 邮件里的问题看不懂(没头没尾) | 说明 agent 把问题写得太省,丢了上下文。插件已内置规则要求摘要自包含(提问必须带上"针对什么、为什么问"),并且这条规则也写进了用户全局指令。若仍遇到,回信告诉它"把上下文写全"即可 |
怎么用
收摘要
主题形如 [DSH] ✅ 会话名 [DSH-T:k3f9a2x8m1qp],出错是 ⚠️,被中止是 ⏹️。
末尾那个标记每封都不一样,是你回信时的凭据。
我已经给 DSH 装好邮件摘要插件了:它订阅每轮结束事件,把这一轮回答压成一条摘要发到你的邮箱。
────────────
会话:给 dsh 加邮件插件
工作区:dsh
回合:第 1 轮 · 用时 3 分 12 秒
时间:2026-09-23 09:12:04
────────────
直接回复本邮件即可继续对话(保持主题不变)。
回信
内容写在正文,主题保持原样别动。
| 情况 | 正文这样写 |
|---|---|
| 多个问题选选项 | 1. A 换行 2. B;写一行 1. A 2. B 也行 |
| 只有一个问题 | 直接写字母,例如 A |
| 对某个选项不满意 | 直接写你要的内容,例如 1. 用私有仓库 |
| 收到摘要后想继续聊 | 直接写你要说的话 |
一次可选的字母是 A/B/C…(按邮件里列出的顺序)。
批准操作(不在电脑前也能放行)
工具请求提权时(典型是 pwsh 要写工作区之外的路径),插件会把审批请求发到邮箱:
⚠ 有一项操作需要你放行,我现在停在这里等你决定。
工具:pwsh
原因:需要写 ~/.dsh/skills(工作区外)
会话:给 dsh 加邮件插件
时间:2026-09-23 14:05:00
────────────
回复本邮件决定(保持主题不变,正文只写一个选项):
1. 允许这一次
2. 拒绝
只放行这一次操作,不会记住为长期允许。超过 10 分钟未回复则默认拒绝。
回信 1 / 允许 / 批准 都算放行,2 / 拒绝 / 不允许 都算拒绝。
界面弹框和邮件同时有效:界面点批准立刻生效;界面点拒绝会给邮件留一小段宽限期, 期间你回信批准仍以邮件为准(人在电脑前点拒绝时,最多多等几十秒)。
待批准清单
需要你放行的操作会攒成一份清单,放进每封摘要邮件的固定区块,你回来一次看完再批, 不用守着屏幕。主题上也会标出来,手机上不用点开就能看到:
[DSH] ✅ 会话名 ⚠2项待批准 [DSH-T:...]
⚠ 待你批准的权限(2 项,我有工作区外的操作需要你放行)
1. 把三条实测坑整理进技能
需要:写 ~/.dsh/skills
原因:下次发布插件还会踩同样的坑
2. DSH 升级后重新校验插件层
需要:重启 DSH 后跑一次自检
你回来时批准任意一项即可(回复本邮件说明也可以)。
- 清单持久化存盘(
pending-permissions.json,与配置文件同目录),DSH 重启不丢 - 清单为空时,邮件里不会出现这个区块
装完之后 agent 怎么知道规则
这个插件除了收发邮件,还带一套给 agent 的规则(摘要怎么写、回信怎么读、 什么情况下申请权限)。规则通过三层让 agent 知道:
| 层 | 位置 | 生效范围 |
|---|---|---|
| ① 工具描述 | 插件内置 | 任何会话,agent 看到 mail_digest 工具时 |
| ② 用户全局指令 | ~/.dsh/AGENTS.md |
任何会话,自动加载(由 DSH 的 dsh-agent-instructions 提供) |
| ③ 仓库内指令 | 本仓库的 AGENTS.md |
agent 在本仓库里工作时 |
安装脚本会自动把规则写进 ②:写成一个带标记的托管区块,可反复安装(替换而非追加),
卸载时只删自己那一块、不动你写的其它内容。写出的 AGENTS.md 不带 BOM。
- 规则内容见
AGENTS.dsh-mail-digest.md - 不想让 agent 收到这些规则:跑
-Uninstall,或手动删~/.dsh/AGENTS.md里<!-- BEGIN dsh-mail-digest -->到<!-- END dsh-mail-digest -->之间的内容
给其它插件作者:这套"把规则写进用户全局指令"的机制是通用逻辑,已抽成可复用模块
tools/AgentRules.ps1——dot-source 后调用Install-AgentRules/Uninstall-AgentRules即可,自带幂等替换、保留用户已有内容、 干净卸载、不带 BOM。用法与踩过的坑都写在那个文件的头部注释里。
安全说明
为什么不会被随机邮件骗到
收信时过三道闸,任何一道不过就丢弃:
| 闸 | 判据 |
|---|---|
| ① 主题 | 必须有写全的 [DSH-T:<token>] / [DSH-Q:<token>] / [DSH-A:<token>],且 token 必须是我们真的发出去过的那一串 |
| ② 发件人 | 必须是你配置的收件地址 |
| ③ 出处 | 回信的 References/In-Reply-To 要能对上我们那封的 Message-ID(客户端剥掉这两个头时靠 ①② 放行) |
token 是 12 位密码学随机串、每封都换,所以外人既猜不到也撞不上。
邮件审批的边界(重要,不藏)
| 事项 | 说明 |
|---|---|
绕过不了 never 策略 |
DSH 的 never 在应答者瀑布分发之前就强制 rejected,插件无法介入。所以只在 ask 策略下有效 |
| 邮箱成为批准通道 | 邮箱被盗 = 批准能力被盗。这是真实的降级(原先必须坐在电脑前点) |
| 认不出表态就拒绝 | fail closed:回信内容无法明确解析为「允许」时一律按拒绝,绝不因"看起来像同意"放行 |
| 超时默认拒绝 | 10 分钟未回复按拒绝处理,而不是无限挂着等 |
| 只放行一次 | 返回的是 allowed-once,不会记住为长期允许 |
摘要怎么来的
三级来源,前一级不可用才退到下一级:
- agent 自己写 —— 回答结尾调用
mail_digest工具提交一条摘要(最准,长度自己掂量); - 模型压缩 —— 没写就用当前模型把这一轮回答压成一条;
- 确定性兜底 —— 模型不可用时,从回答里挑出结论句和收尾句拼一条。
三级的字数纪律都是「详略控制」:不做字数校验、不做截断。
行为开关
| 开关 | 默认 | 说明 |
|---|---|---|
| 启用邮件摘要 | 开 | 关掉之后一轮都不发 |
| 子代理回合也发 | 关 | 一次任务可能因此收到几十封,默认不发子代理 |
| 摘要来源 | 自动 | 自动 / 总是用模型压缩 / 不发信只记日志 |
| 一分钟最多发几封 | 6 | 防死循环刷屏 |
| 同一会话最小间隔 | 0 | 秒 |
| 处理完的回信标为已读 | 开 | 避免未读堆积;见下 |
已知限制
- 发信失败不会重试:日志里会记原因(比如
535授权码不对),但不会补发。 - 不加密的服务器默认拒绝发信:没有 STARTTLS 就拒绝把授权码发出去。 本机中继要发,得在设置页勾「允许未加密发送」。
- 摘要由模型生成时会有 Token 开销:每轮多一次很小的模型调用;
想省掉就让 agent 调用
mail_digest(走第一级,不再额外调模型)。 - 只在每轮结束时触发:一轮里调了工具、分了多步,最后只发一封。
- 收信默认 15 秒一轮:回信不会秒到,最多等十几秒;提问邮件挂了 30 分钟没回就交回界面。
- 回信要保住主题里的标记:那个
[DSH-?:...]被删掉或改写就找不到了。 - 收件人不在白名单里的回信一律丢弃:所以别用另一个邮箱回信。
- 处理完的回信会被标为已读:让"未读"始终只包含真正还没处理的东西。 没处理成功的(认不出、发件人不对、解析不出内容)不会被标已读,你仍能看到、能重试。
卸载
dsh plugin --profile web remove dsh-mail-digest
配置文件不会自动删,要清掉就删 %USERPROFILE%\.dsh\dsh-mail-digest\。
自检
不联网、不发信,直接跑:
node smoke.mjs # 入口契约 / 工具注册 / 摘要函数 / 配置 / 设置页 / 审批仲裁
node test-reply.mjs # 回复解析 / 1. A 格式 / 防误判 token / 发件人白名单
node test-bridge.mjs # 收信判定整合:三道闸 / 两种通道 / 文件夹挑选 / 标已读
node test-mime.mjs # MIME 解析 / 中文编码 / 引用剥离 / 候选排序与截断
node test-smtp.mjs # 假 SMTP 服务器对发:认证 / 中文主题 / 正文还原 / 安全底线
合计 328 项。另外安装脚本的用户全局指令区块有单独测试(用临时目录,不碰真实文件):
powershell -ExecutionPolicy Bypass -File test-installer.ps1
开发
实现细节、踩坑记录、设计取舍见 DEVELOPMENT.md。
License
MIT
No comments yet. Be the first to write one.