DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-push-notify

z

dsh-push-notify

Manifest valid

DeepSeek Harness (dsh) plugin: push a notification to your phone (ntfy, Bark, Feishu, DingTalk, WeCom, Slack, Discord, Telegram, webhook) when an agent finishes, gets stuck, needs you, or hits a model

UI (client)hasBundlePatch

dsh-push-notify

English · 中文

DeepSeek Harness(dsh)推送通知插件。Agent 跑完任务、卡住、需要你介入、模型出错停下时,推一条通知给你。

支持并保证的只有两种接口:

  • ntfy——推到手机(ntfy.sh 或你自建的 ntfy 服务器)。
  • 你自己的 webhook——插件把通知以 JSON POST 到你的服务。

飞书、钉钉、企业微信、Slack、Telegram 等其他服务不内置,可以用 webhook 的模板自己对接,见下文「接入其他服务」。

不用盯着屏幕。装好、填一个地址、结束。

/notify add https://ntfy.sh/你自己起的一个长随机主题

这一条命令会保存接口并立刻发一条测试通知,手机响了就配好了。

它会在什么时候通知你

类别场景
✅ done一个任务真正做完(连续几轮算一次,不会每轮都响);done:goal 目标(goal)完成
🙋 humanapproval 等你批准某个操作 · question Agent 在问你 · plan 计划等你审阅 · wait Agent 自己声明“卡住了,需要人” · goal-blocked 目标被阻塞
❌ error模型请求失败导致这一轮中断(认证失效 / 额度用完 / 限流 / 超时…,附一句可操作的提示)· max-tokens 输出被长度上限截断
⏳ stuckretry 模型请求已连续重试 4 次(还没失败,但很可能要失败)· tools 工具连续失败 · loop 原地打转(同一调用重复)· silent 很久没任何动静 · tool 某个工具调用迟迟不返回

所有通知都以高优先级发送:ntfy 收到 priority: 4(等同 X-Priority: high);webhook 的 JSON 里 priority 字段也是 4。最终是否弹出还取决于手机系统和 App 的通知设置。

它不会通知你的:子代理自己的结束或出错(只在整棵树都停了才算完成)· 你自己按了停止 · 你刚发的提示被钩子拦下(你正看着屏幕)· 少于 1 分钟的闲聊式问答。

安装

在 dsh 侧栏 插件 → 添加插件,填:

github:ztllll/dsh-push-notify

装好后刷新页面。没配置任何接口时,插件完全空转,什么都不会发。

更新:请在插件页(插件管理器)里操作。命令行 dsh plugin add 只改磁盘,不会通知正在运行的 dsh 重新加载这个插件。

配置接口(三种方式,任选)

方式一:插件页面板(最简单)

侧栏 插件 → 已安装 → 推送通知,在「通知地址」里填一个 http:// 或 https:// 地址,点保存。下一条通知起生效,不用重启。 填 https://ntfy.sh/主题 就按 ntfy 发到手机;填其他地址就按 webhook 把 JSON POST 过去(格式见「Webhook 收到什么」)。留空则不发。 面板只管这一个地址;多个接口、事件开关、阈值请用方式二或方式三。

方式二:在对话里用 /notify(推荐,立刻生效)

/notify                                   查看状态
/notify add <url> [name=手机] [preset=ntfy|webhook] [token=…] [events=done,human]
/notify test [名字|#序号]                  发一条测试通知
/notify rm <名字|#序号>                    删除
/notify on | off                          总开关
  • 接口保存在 ~/.dsh/dsh-push-notify/endpoints.json,权限 0600(里面有 webhook 密钥)。
  • /notify 命令本身不会被记入会话日志(命令行里可能带密钥),回显、状态和日志里只显示地址的域名(如 ntfy.sh/…),路径和参数一律不显示;多个接口请用 name= 区分。
  • ntfy.sh 的地址自动按 ntfy 发送;自建 ntfy 服务器请加 preset=ntfy。其他地址都按 webhook 发送。
  • token=:ntfy 开了访问控制时填,插件会带上 Authorization: Bearer <token>。

方式三:写在插件配置里(可以多个、可以每个接口选不同事件)

dsh 的 profile 里(cordis.patch.yml):

- id: push-notify
  config:
    detail: normal            # normal(默认,带 agent 回复)| minimal(不带任何对话内容)| full,见「隐私」
    lang: auto                # auto | zh | en
    endpoints:
      - name: 手机
        url: https://ntfy.sh/一个只有你知道的长随机主题
      - name: 我的服务
        url: https://example.com/dsh-hook
        headers: { Authorization: "Bearer 你的密钥" }
        events: [human, error]   # 这个接口只收 需要人 和 出错

ntfy

情况怎么填
用 ntfy.shhttps://ntfy.sh/一个只有你知道的长随机主题。手机装 ntfy App,订阅同一个主题
自建 ntfy/notify add https://你的域名/主题 preset=ntfy
开了访问控制再加 token=tk_…

主题名就是口令,请用长随机串。插件把通知以 JSON 发布到服务器根地址(官方文档),中文标题不会乱码。

Webhook 收到什么

不写 body 时,每条通知是一个 POST,Content-Type: application/json,正文如下(真实输出):

{
  "title": "✅ 任务完成 · demo",
  "text": "已完成:修复了登录页的 bug。\n用时 3分12秒",
  "kind": "done",
  "priority": 4,
  "tags": ["white_check_mark"],
  "project": "demo",
  "cwd": "/w/demo",
  "session": "s1",
  "sub": "",
  "duration": "3分12秒",
  "durationSec": 192,
  "time": "2026-10-19T07:00:00.000Z",
  "label": "任务完成"
}
字段含义
kinddone / human / error / stuck,见上文表格
sub细分类型,如 approval、goal、retry;没有就是空串
title / text现成的标题和正文,直接展示即可
priority固定为 4(高)
其余项目名、工作目录、会话 ID 前 12 位、用时、ISO 时间、类别名

怎样算发送成功:你的服务返回任意 2xx 就算成功,响应体不看。408、425、429 和 5xx 会重试,连接失败或超时也会重试:默认间隔 1 秒、3 秒,最多重试 2 次;对方给了 Retry-After 响应头或 JSON 正文里的 retry_after 秒数就按它等,但单次最多等 30 秒。其他状态码不重试,记一行日志。不跟随重定向,请直接填最终地址。

接入其他服务(自己对接)

飞书、钉钉、企业微信、Slack、Telegram 等都能收 HTTP 请求,但各家要的 JSON 格式不同、鉴权方式也不同。插件不内置它们,你可以用 webhook 的 url / headers / body 模板把请求改成对方要的样子:

- id: push-notify
  config:
    endpoints:
      - name: 某个机器人
        method: POST                              # 默认 POST;也可以 GET
        url: https://example.com/hook?t={{title}}  # url 里的变量会被 URL 编码
        headers: { X-Token: 你的密钥 }
        body:
          msg_type: text
          content: { text: "{{title}}\n{{text}}" }
          level: "{{priority}}"                   # 整个值恰好是一个变量时保留原类型:这里是数字 4

上面这个配置实际发出的正文是:

{"msg_type":"text","content":{"text":"✅ 任务完成 · demo\n已完成:修复了登录页的 bug。\n用时 3分12秒"},"level":4}

规则:

  • 可用变量就是上一节 JSON 里的全部字段名,写成 {{字段名}}。
  • 先解析、再替换:变量是逐个替换到每个字符串里的,标题里有引号、换行也不会弄坏 JSON。
  • 写错的变量名会原样留在通知里,方便发现。
  • 对方要表单就加 headers: { Content-Type: application/x-www-form-urlencoded },body 的每个字段会变成一个表单项。
  • body 也可以写成一段 JSON 字符串,效果相同。

对接前请自己确认:

  1. 对方的 JSON 格式(以它的官方文档为准);
  2. 是否需要签名——签名一般要用当前时间算哈希,模板做不到,需要你自己写个小转发服务,或者 fork 本插件(见下);
  3. 对方「HTTP 200 但正文里报错」时,插件仍会当成功。

验证方法:配好后发 /notify test 名字,看对方有没有收到。

Fork 后内置一个新服务

想把某个服务做成内置(自动识别地址、算签名、按正文判断成败),改的地方都在 lib/presets.mjs:

  1. PRESETS 里加上名字;
  2. BUILD 里加一个构造函数 (ep, message, now) => ({ url, headers?, contentType, body }),参考 ntfy;
  3. 需要按地址自动识别就改 detectPreset();
  4. 对方会「200 但失败」,就在 judge() 里按它的正文判定;
  5. 在 test/presets.test.mjs 里加一条测试,期望值来自对方官方文档;npm test 全部通过后,再对真实服务发一条确认。

隐私:什么会离开你的电脑

推送服务是第三方。默认 detail: normal:任务完成的通知正文就是 agent 最后一条回复(最多约 1500 字节,超出以 … 截断),外加用时。你的 ntfy 主题就是口令,请用长随机串。

不想让任何对话内容离开本机,把 detail 设成 minimal——只发固定短语 + 项目名 + 数字 + 错误码。

detail通知里有什么
minimal固定短语、项目名、用时、错误码。没有任何你或模型写的内容
normal(默认)以上 + agent 的最后回复(完成时)、Agent 向你提的问题、目标描述、工具名
full以上 + 审批的命令原文、服务端返回的错误信息

“最后回复”指本次任务里 agent(不含子代理)最后写下的一段文字;目标(goal)完成时,用它写的总结。错误、卡住、需要你的通知不带回复,只带各自的事实。

可靠性(它是怎么避免漏报、误报、刷屏的)

  • 发送失败不拖累 Agent:超时 10 秒、最多重试 2 次(尊重 Retry-After)、永不抛错;失败只写一行日志,且日志里抹掉密钥。
  • 不跟随重定向:POST 被 301/302 变成 GET 会悄悄丢消息,所以直接报错并提示你用最终的 https 地址。
  • 回复不会张冠李戴:只取根会话最近一次有文字的回复;新任务从空开始,不会带出上一个任务的回答;子代理写的文字不算。
  • 去重 + 限流:同一类错误 60 秒内不重复;“模型请求重试”每会话每小时最多 1 次(在 64 个真实会话上从 54 条降到 22 条);每接口每分钟最多 20 条,超出的会在下一条里写明“被抑制了 N 条”。
  • 子代理不单独响;根会话要等整棵树都停了才算完成。
  • 配置写错不会让 dsh 起不来:坏值回落默认并在 /notify 状态里点名。
  • 损坏的 endpoints.json 绝不覆盖。

调参:先在你自己的历史上试跑

node scripts/replay.mjs --limit 80 --detail          # 用你的真实会话日志回放,看会推多少条(不联网、不打印对话内容)
node scripts/replay.mjs --set stallSec=600           # 改一个阈值再看
node scripts/live-ntfy.mjs                           # 往一个随机 ntfy 主题发每一类样例,并回读确认

主要阈值(均有范围保护):settleSec(8) 停多久算收工 · minDurationSec(60) 短于此的不算任务 · humanDelaySec(5) 给你多久在屏幕前答复 · remindAfterSec(0=不催) · stallSec(900) · toolStallSec(7200) · retryAt(4) · toolFailStreak(5) · loopRepeat(8) · cooldownSec(60) · quietSec。默认值来自对真实会话日志的实测(例如:重试到第 3 次后恢复的占 21/23,到第 4 次后仍失败的占 32/47)。

已知限制

  • dsh 进程崩溃或机器断电无法通知——插件和 dsh 同进程。需要这个请另配外部看门狗。
  • 通知不排队落盘:重启 dsh 时还没发出去的会丢。
  • 成功 = 服务端接受了请求,不保证手机上一定弹出(那取决于推送服务和你的设备)。
  • 只对 ntfy 做过真实推送验证;webhook 在本地 HTTP 服务上验证过。其他服务需要你按「接入其他服务」自己对接和验证。
  • ntfy.sh 上的主题名等同口令:请用长随机串,不要用 Project 这类好猜的名字。

开发

npm test                                   # 含真实本地 HTTP 服务和真实 Cordis 运行时(需本机装有 dsh)

MIT 许可。


English

Push notifications for DeepSeek Harness. When an agent finishes, gets stuck, needs you, or hits a model error and stops, it sends a notification to one of the two supported targets:

  • ntfy — your phone (ntfy.sh or a self-hosted ntfy server; add preset=ntfy for self-hosted).
  • your own webhook — a JSON POST to your service.

Other services (Feishu, DingTalk, WeCom, Slack, Telegram…) are not built in; reach them with the webhook's url / headers / body templates, or fork and add a preset (see "Connecting other services" in the Chinese section — the YAML and JSON there need no translation).

/notify add https://ntfy.sh/a-long-random-topic-only-you-know

That saves the endpoint and sends a test message immediately.

What it reports: done (a task really finished; a goal completed) · human (approval needed, a question for you, a plan to review, the agent says it is stuck, a goal is blocked) · error (the turn stopped on a model error or was cut off at the output limit) · stuck (model request retried 4× in a row, tool calls keep failing, a loop, long silence, a tool call that never returns).

What it deliberately ignores: subagent chatter, your own Stop, a prompt you just typed being rejected by a hook, and quick chat replies under a minute.

Install: Plugins → Add plugin → github:ztllll/dsh-push-notify, or dsh plugin --profile web add "github:ztllll/dsh-push-notify". With no endpoint configured the plugin does nothing.

Privacy: by default (detail: normal) a finished task's notification body is the agent's last reply (up to ~1500 bytes) plus the duration. Set detail: minimal to keep every word of the conversation off the wire (fixed phrases, project name, numbers, error codes only). full also adds approval command text and provider error messages. Treat your ntfy topic as a password.

Webhook contract: without a body, each notification is a JSON POST with title, text, kind, sub, priority (always 4), tags, project, cwd, session, duration, durationSec, time, label. Any 2xx counts as delivered; 408, 425, 429, 5xx and network errors/timeouts are retried up to 2 times (1 s, then 3 s, or Retry-After / a JSON retry_after, capped at 30 s per wait); other statuses are not retried; redirects are not followed. Every field can be used as {{name}} in url, headers and body.

Reliability: never blocks or throws into the agent; 10 s timeout, 2 retries; secrets are scrubbed from logs and replies; repeated signals are de-duplicated and rate-limited.

Limits: only ntfy has been verified against the real service; the webhook was verified against a local HTTP server. A crash of dsh itself cannot be reported (same process); undelivered notifications are not persisted across a restart; "success" means the server accepted the request, not that a phone lit up.

See the Chinese section above for the full webhook example, tuning with scripts/replay.mjs, and the full list of known limitations.

Comments

Loading…

Similar plugins

dsh-mobile-notify

by zjhaaa042-cloud

DSH (DeepSeek Harness) 插件:任务完成后把通知推送到手机 —— ntfy / Bark / 钉钉 / 企业微信 / 飞书 / Server酱 / PushPlus / Telegram / Qmsg酱 / 通用 webhook

Notifications & IntegrationsManifest valid

★ 0

MIT

JavaScript

Oct 2, 2026

dsh plugin --profile web add dsh-mobile-notify

by 534119219

Multi-channel push for DeepSeek Harness: Server酱, PushPlus, Bark, DingTalk, WeCom, Telegram, Feishu, ntfy, custom webhooks and more, configurable from the settings panel and callable by other plugins

Notifications & IntegrationsManifest valid

★ 7

MIT

JavaScript

Aug 16, 2026

dsh plugin --profile web add chicheng-push

by rizkirmdhnnn

DSH plugin: model-facing notify tool for DeepSeek Harness — send notifications to ntfy or generic webhooks when an agent task finishes.

Manifest valid

★ 0

MIT

TypeScript

Aug 14, 2026

dsh plugin --profile web add dsh-tool-notify

by c-ling

DeepSeek Harness 消息提醒插件:回合结束或等待确认时向浏览器、系统、飞书/钉钉/企业微信/通用 Webhook 发送通知

Notifications & IntegrationsManifest valid

★ 7

↓ 355/wk

MIT

JavaScript

Aug 21, 2026

dsh plugin --profile web add dsh-plugin-notify

by GuZhengSVT

DeepSeek Harness (dsh) 插件:事件驱动的企业微信(WeCom)群机器人通知 — goal 完成/阻塞与每轮对话自动推送,另含 wechat_notify 工具;走官方 webhook,零封号风险。

Terminal & ClientsManifest valid

★ 3

MIT

TypeScript

Aug 15, 2026

dsh plugin --profile web add dsh-wecom-notify

by THEWOLFWALKER

Unified notification and remote-control plugin for DeepSeek Harness (DSH): one zero-dependency notify() API across 27 channels, with phone-friendly approvals/questions, six inbound control channels, a

Notifications & IntegrationsManifest valid

★ 55

MIT

JavaScript

Oct 17, 2026

dsh plugin --profile web add dsh-notifier