dsh-notification
其他 活跃维护

dsh-notification

nishit130/dsh-notification

支持智能体回合完成、运行报错、待审批三类状态实时推送,无需盯守浏览器标签页,可快速对接各类智能体工作流,消息直达本地通知中心,交互轻量化无冗余配置。

1
Stars 标星
0
Forks 分支
1
Watchers 关注
0
Open Issues
JavaScript
主要语言
MIT
开源协议
24 KB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:nishit130/dsh-notification
git clone https://github.com/nishit130/dsh-notification.git
git clone git@github.com:nishit130/dsh-notification.git
README.md main

dsh-notification

Desktop, browser + webhook notifications for DeepSeek Harness
on macOS · Linux · Windows: know when your agent finishes a turn, hits an error,
or is waiting for your approval — without watching the tab.

Long agent turns are the norm: you kick off a task, switch away, and come back to find the agent
finished five minutes ago — or worse, stuck on an approval prompt the whole time. dsh-notification
listens to the harness's own lifecycle events and pings you the moment your attention is needed.

What it does

Event Trigger Default
Agent finished agent/status flips running → idle, and the turn ran ≥ minTurnDurationMs on
Agent error agent/error (a step or turn errored) on
Approval needed approval/request waterfall (observe-only; always delegates with next()) on

Each event can go to:

  • Desktop notification — zero dependencies: osascript (macOS), notify-send (Linux),
    PowerShell toast (Windows).
  • Webhook — a JSON POST with a Slack-compatible text field, so a Slack/Discord/generic
    incoming-webhook URL works out of the box.

Install

dsh plugin --profile web add dsh-notification
# or straight from git:
dsh plugin --profile web add github:nishit130/dsh-notification

The package ships plain ESM JavaScript — no build step, so a git install needs no
allowBuilds entry.

Where notifications appear

Three channels, three places:

Channel Fires on Best for
Desktop (desktop) the machine running the dsh server dsh web on your own machine
Browser (browser) the machine viewing the Web UI a remote server, or any Web UI use
Webhook (webhookUrl) wherever the URL points phones, Slack, unattended runs

Browser notifications use the standard Notification API: the Web UI asks for permission on
your first click or keypress, and by default popups appear only while the tab is hidden —
a visible tab already has your attention (set browserOnlyWhenHidden: false to change that).

Running everything on one machine with the tab hidden? You'd get both a desktop and a browser
popup for the same event — turn one channel off (desktop: false or browser: false) if the
pair bothers you.

Configuration

Override the row in your profile's cordis.patch.yml (or via the Settings UI):

- insert:
    - id: notify
      name: dsh-notification
      config:
        minTurnDurationMs: 10000        # only notify for turns ≥ 10s
        webhookUrl: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
        notifyOnApproval: true
        desktop: true
        title: 'DSH'
Field Type Default Meaning
notifyOnIdle boolean true Notify when a turn finishes
notifyOnError boolean true Notify on agent/error
notifyOnApproval boolean true Notify when a tool call awaits approval
minTurnDurationMs number 5000 Skip notifications for quick turns
desktop boolean true Native desktop notification on the server host
browser boolean true Browser Notification popups in the Web UI
browserOnlyWhenHidden boolean true Suppress browser popups while the tab is visible
webhookUrl string '' Optional POST target (Slack-compatible payload)
title string 'DeepSeek Harness' Desktop notification title

Webhook payload

{
  "text": "Agent finished — done in 2m 14s",
  "summary": "Agent finished",
  "body": "done in 2m 14s",
  "level": "info",
  "ts": "2026-08-21T12:34:56.000Z"
}

Design notes

  • Everything registered through ctx is an effect — the listeners are removed automatically
    on unload/hot-reload; there is no manual cleanup path (Cordis revertible effects).
  • approval/request is a waterfall. This plugin only observes it, so its listener always
    calls next() — returning without it would claim the decision and swallow the real answerers.
  • Never break the loop. Desktop spawns are detached and fire-and-forget; webhook failures are
    swallowed. A notifier must never surface an error into the agent's turn.

Local development

Copy dev.patch.example.yml to dev.patch.yml (gitignored), point it at your checkout's
absolute path, then from a harness source checkout:

pnpm dsh web --patch ./path/to/dsh-notification/dev.patch.yml

Edits to index.js hot-reload without a restart. Run the tests with npm test.

License

MIT