回合结束时向 Server酱3 推送微信通知——标题、模型、项目目录、Git 分支、状态与回复摘要,支持子代理过滤,fire-and-forget 不阻塞主流程。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-serverchan-notify
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:nickhelion/dsh-plugins#path:/packages/serverchan-notify
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
🔔 dsh-serverchan-notify
DeepSeek Harness (DSH) 插件:每当一个回答回合结束,就向 Server酱3 (ServerChan³) 推送一条通知到你的微信;agent 向你提问时同样推送——对齐 codex Stop hook 的行为,并补上 codex 没覆盖的那种情形:agent 正卡在等你回答。
功能
- 订阅 DSH 会话事件流(
ctx.on("session/event", …))。 - 每个回答回合结束(
turn/end,无论completed/error/blocked/max-tokens/aborted)推送一条 Markdown 通知到 Server酱3 → 你的微信。通知内容:对话标题、模型、项目目录、Git 分支、回合状态、完成时间、会话 ID,以及最新一段回复正文(超过 16000 字符自动截断)。 - agent 向你提问时也推送。 出现
ask_user_question工具调用,就意味着 agent 已经阻塞、在等人回答——这是最不该漏掉的情形,因此单独推一条:带上每个问题的 header、正文、选项及其说明。用notifyQuestions: false关闭。 - fire-and-forget:推送失败只记一条警告日志,绝不阻塞或中断 agent 主循环。
- 默认跳过子代理会话,避免被内部子任务刷屏。
| codex Stop hook | 本插件 | |
|---|---|---|
| 触发时机 | 每个回合结束一次 | 每个回合结束一次(turn/end),外加每次 ask_user_question 调用一次 |
| key 来源 | 环境变量 / ~/.codex/secrets/… |
环境变量 / 配置 / $DSH_HOME/secrets/…(见 SendKey 解析顺序) |
| 失败处理 | 绝不影响回合 | 绝不影响回合 |
| 作用域 | 全局 hooks.json |
全局 $DSH_HOME/cordis.patch.yml(或单 profile) |
🔐 本仓库不含任何 SendKey。 key 一律来自环境变量、文件或插件配置,绝不写入源码。
环境要求
- DeepSeek Harness (DSH) —— 已在
0.1.1-rc.2与0.1.2-rc.1上验证(@deepseek-ai/cordis^4.0.1)。插件按运行时 harness 实际暴露的访问器读取会话日志,因此两条 API 线都支持。 - Node.js ≥ 18
- 一个 Server酱3 SendKey(https://sct.ftqq.com/ 免费注册)
快速开始
1. 获取 SendKey
登录 https://sct.ftqq.com/,打开「SendKey」页签复制你的 key,形如 sctp<数字>txxxx…。插件会自动推导专属推送域名(https://<数字>.push.ft07.com/send/<key>.send);不带通道号的旧式 key 则使用通用域名 https://sctapi.ftqq.com/<key>.send。
2. 保存 key(推荐)
mkdir -p ~/.dsh/secrets
echo '你的SendKey' > ~/.dsh/secrets/serverchan_sendkey
chmod 600 ~/.dsh/secrets/serverchan_sendkey
3. 挂载插件
编辑 DSH 的补丁层并重启 harness:
# 全局(所有 profile 生效,等价于 codex 的全局 hooks.json):
# $DSH_HOME/cordis.patch.yml (默认 ~/.dsh/cordis.patch.yml)
# 单 profile:
# $DSH_HOME/profiles/<name>/cordis.patch.yml
- insert:
- id: serverchan-notify
name: 'dsh-serverchan-notify'
config:
sendkeyFile: '~/.dsh/secrets/serverchan_sendkey'
插件行只在启动时解析——改完配置后必须重启 harness 进程。
安装插件包
本包声明了 dsh.bundle manifest,通过 npm 一条命令安装:
# 推荐
dsh plugin --profile web add dsh-serverchan-notify
# 固定版本
dsh plugin --profile web add dsh-serverchan-notify@1.0.2
# GitHub monorepo 回退
dsh plugin --profile web add 'github:nickhelion/dsh-plugins#main&path:/packages/serverchan-notify'
# 本地开发
git clone https://github.com/nickhelion/dsh-plugins.git
dsh plugin --profile web add "$PWD/dsh-plugins/packages/serverchan-notify"
包内自带的 cordis.patch.yml 以全默认配置插入插件行;如需覆盖某个选项,在自己的补丁层里按行 id serverchan-notify 重写即可。
SendKey 解析顺序
取第一个非空值,优先级从高到低:
| # | 来源 | 示例 |
|---|---|---|
| 1 | 环境变量 SERVERCHAN_SENDKEY |
export SERVERCHAN_SENDKEY=sctp… |
| 2 | 配置内联 sendkey |
config.sendkey: 'sctp…' |
| 3 | 环境变量 SERVERCHAN_SENDKEY_FILE(指向 key 文件) |
export SERVERCHAN_SENDKEY_FILE=… |
| 4 | 配置 sendkeyFile(支持 ~) |
config.sendkeyFile: '~/.dsh/secrets/…' |
| 5 | 默认文件 $DSH_HOME/secrets/serverchan_sendkey |
~/.dsh/secrets/serverchan_sendkey |
配置项
| 键 | 默认 | 说明 |
|---|---|---|
sendkey |
— | 内联明文 key(优先级低于 SERVERCHAN_SENDKEY 环境变量) |
sendkeyFile |
$DSH_HOME/secrets/serverchan_sendkey |
key 文件路径,支持 ~ 开头 |
reasons |
[completed, blocked, error, max-tokens, aborted] |
哪些 turn/end 原因触发推送(interrupted 恒不推) |
notifyQuestions |
true |
agent 调用 ask_user_question 等你回答时是否推送 |
notifySubagents |
false |
是否也给子代理会话推送(默认关,防刷屏) |
timeoutMs |
8000 |
HTTP 超时(毫秒) |
maxResponseChars |
16000 |
回复正文 / 提问内容截断长度 |
disabled |
false |
临时禁用(不读 key、不订阅事件) |
通知示例
回合结束:
DSH 完成:<对话标题>
- 对话标题:…
- 模型:deepseek-official / deepseek-v4-pro
- 项目目录:
/home/you/project- Git 分支:
main- 回合状态:完成
- 完成时间:2026-08-18T21:00:00.000Z
- 会话 ID:
session-12DSH 最新回复
……最新一段模型回复……
agent 正在等你回答:
DSH 提问:<对话标题>
- 对话标题:…
- 模型:deepseek-official / deepseek-v4-pro
- 项目目录:
/home/you/project- Git 分支:
main- 提问时间:2026-08-18T21:05:00.000Z
- 会话 ID:
session-12DSH 正在等待你的回答
1. 选择模式
要按哪条路径继续?
- 直接改(推荐) — 小步快跑
- 先出方案 — 多一轮评审
2. 改动范围
- README
- 测试 > 该问题可多选
常见问题
| 现象 | 处理 |
|---|---|
| 启动日志出现「未找到 Server酱 SendKey」 | 按上面 5 种来源之一提供 key |
日志出现 HTTP 403 / 超时 |
网络或代理问题;推送域名由 key 推导(<n>.push.ft07.com) |
| 重启后仍收不到 | 确认行 id 唯一且包可解析——dsh --profile web --dump-config | grep -A8 serverchan-notify |
| 推送太频繁 | 保持 notifySubagents: false(默认)、裁剪 reasons,或设 notifyQuestions: false |
| 提问提醒显示「无法解析本次提问内容」 | 模型输出的工具参数 JSON 损坏;harness 本身仍拿到了问题,回 DSH 界面作答即可 |
| 想临时停用 | disabled: true,重启生效 |
开发
npm install # 安装 devDependencies(cordis),供冒烟测试使用
npm test # 冒烟测试——fetch 打桩,不真实推送
REPORT=1 npm test # 冒烟测试 + 打印组装好的报文
npm run test:live # 按配置的 key 真实推送一条测试通知
仓库结构
lib/index.js 插件入口——事件订阅、报文组装、HTTP 推送(回合结束 + agent 提问)
test-send.mjs 独立真实推送脚本(key 解析顺序与插件一致)
smoke-test.mjs cordis 进程内冒烟测试(fetch 打桩)
package.json 包元数据 + npm scripts
README.md 英文文档
README.zh-CN.md 中文文档
参与贡献
请向统一的 nickhelion/dsh-plugins monorepo 提交 PR。两条底线规则:
- 绝不提交 SendKey(或任何机器绝对路径)——key 只能经环境变量 / 文件 / 配置进入。
- 事件监听器必须保持不抛异常、fire-and-forget——通知绝不能影响 harness 主流程。
License
链接
同类插件
xmanrui/dsh-im★ 1995
通过二维码或机器人凭据将 IM 机器人接入 DeepSeek Harness(支持飞书、微信、钉钉、企业微信、QQ、Slack、Telegram、Discord 和 WhatsApp 共 9 种渠道)。
shaobeichen/dsh-pocket★ 1750
手机远程访问 DSH Web 界面:扫码即用局域网或公网(cloudflared 隧道)访问,实时同屏、移动端适配布局,带设置页管理。
inclusionAI/Avernet#deepseek-harness-channel-bcn★ 620
通过 WebSocket V2 将 DeepSeek Harness 接入 Avernet Bot 协作网络,支持自动注册、Agent 会话隔离、工具调用事件和多 Bot 路由工具。
Oscar-Williams/dsh-deepcanary★ 90
面向 DeepSeek Harness 的证据优先注意力监督,提供 C0–C3 策略、去重 Inbox 提醒、静默时段和脱敏结果记录。
omdsh-dev/dsh-notification★ 89
回合完成桌面通知,按结果分控 + 关键词过滤。
whyihaveyou/dsh-suite#plugin-notify★ 60
回合完成、错误或待审批时推送 IM webhook(飞书/企微/钉钉/Slack/Discord/自定义)与本地通知。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。