Bundle
dsh-mail-digest
每轮回答结束后,把一条详略得当的中文摘要发到你的邮箱(QQ / 163 / 自建 SMTP),地址在 DSH 设置页里配置。
- Source
- Xixixiao2007
- License
- MIT
- Updated
- Updated 24 days ago
Readme
# dsh-mail-digest
给 DSH 装一个邮件通道:**每轮回答结束后,把一条详略得当的中文摘要发到你的邮箱**;
而且**你可以直接回邮件**——用邮件回答我的提问、收到摘要后续接对话。
地址、授权码、收件人全在设置页里填,不用改配置文件、不用命令行。
## 它能解决什么问题
- **不用守着屏幕**:回答完了自动发邮箱,手机上就能看到进展。
- **离开电脑也能继续干活**:回一封邮件就是一条新指令,对话继续往下走。
- **离开电脑也能批准**:需要放行的操作发到邮箱,回信 `1` 即可——不必坐在电脑前点按钮。
- **摘要不是全文搬运**,也不是固定字数截断:长度由结论多少决定,结论少就一句话,结论多就多写几句。
- **纯本地收发**:自己实现的零依赖 SMTP + IMAP,不经过任何云服务,不装额外依赖。
- **QQ / 163 / 126 预置**:选一个邮箱类型,服务器和端口自动填好,只要填地址和授权码。
## 安装
在**普通 PowerShell 窗口**里跑(不要走 DSH 沙箱:沙箱写不了 `~\.dsh`):
```powershell
# 一键脚本(装 / 卸载都行)
powershell -ExecutionPolicy Bypass -File .\安装邮件摘要.ps1
powershell -ExecutionPolicy Bypass -File .\安装邮件摘要.ps1 -Uninstall
```
或者手动两步:
```powershell
# 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`](./AGENTS.dsh-mail-digest.md)
- 不想让 agent 收到这些规则:跑 `-Uninstall`,或手动删 `~/.dsh/AGENTS.md` 里
`<!-- BEGIN dsh-mail-digest -->` 到 `<!-- END dsh-mail-digest -->` 之间的内容
> **给其它插件作者**:这套"把规则写进用户全局指令"的机制是通用逻辑,已抽成可复用模块
> [`tools/AgentRules.ps1`](./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`,不会记住为长期允许 |
## 摘要怎么来的
三级来源,前一级不可用才退到下一级:
1. **agent 自己写** —— 回答结尾调用 `mail_digest` 工具提交一条摘要(最准,长度自己掂量);
2. **模型压缩** —— 没写就用当前模型把这一轮回答压成一条;
3. **确定性兜底** —— 模型不可用时,从回答里挑出结论句和收尾句拼一条。
三级的字数纪律都是「详略控制」:不做字数校验、不做截断。
## 行为开关
| 开关 | 默认 | 说明 |
| --- | --- | --- |
| 启用邮件摘要 | 开 | 关掉之后一轮都不发 |
| 子代理回合也发 | 关 | 一次任务可能因此收到几十封,默认不发子代理 |
| 摘要来源 | 自动 | `自动` / `总是用模型压缩` / `不发信只记日志` |
| 一分钟最多发几封 | 6 | 防死循环刷屏 |
| 同一会话最小间隔 | 0 | 秒 |
| 处理完的回信标为已读 | 开 | 避免未读堆积;见下 |
## 已知限制
- **发信失败不会重试**:日志里会记原因(比如 `535` 授权码不对),但不会补发。
- **不加密的服务器默认拒绝发信**:没有 STARTTLS 就拒绝把授权码发出去。
本机中继要发,得在设置页勾「允许未加密发送」。
- **摘要由模型生成时会有 Token 开销**:每轮多一次很小的模型调用;
想省掉就让 agent 调用 `mail_digest`(走第一级,不再额外调模型)。
- **只在每轮结束时触发**:一轮里调了工具、分了多步,最后只发一封。
- **收信默认 15 秒一轮**:回信不会秒到,最多等十几秒;提问邮件挂了 30 分钟没回就交回界面。
- **回信要保住主题里的标记**:那个 `[DSH-?:...]` 被删掉或改写就找不到了。
- **收件人不在白名单里的回信一律丢弃**:所以别用另一个邮箱回信。
- **处理完的回信会被标为已读**:让"未读"始终只包含真正还没处理的东西。
没处理成功的(认不出、发件人不对、解析不出内容)**不会**被标已读,你仍能看到、能重试。
## 卸载
```bash
dsh plugin --profile web remove dsh-mail-digest
```
配置文件不会自动删,要清掉就删 `%USERPROFILE%\.dsh\dsh-mail-digest\`。
## 自检
不联网、不发信,直接跑:
```bash
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
powershell -ExecutionPolicy Bypass -File test-installer.ps1
```
## 开发
实现细节、踩坑记录、设计取舍见 [`DEVELOPMENT.md`](./DEVELOPMENT.md)。
## License
MIT
Install
dsh plugin --profile web add github:Xixixiao2007/dsh-mail-digest
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-mail-digest from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.