aokamoaki/dsh-notify

aokamoaki/dsh-notify

对话完成通知:回合完成/出错/目标完成/提问/审批时弹出 Windows toast 与提示音,仅后台提醒,会话头部铃铛即控制中心。

通知与集成deepseek-harnessdshnotification

🔔 dsh-notify

Conversation-completion notifications for DeepSeek Harness — Windows toast + sound when a turn finishes, errors, a goal completes, or the agent asks/needs approval. Alerts fire only while you are away from the app; they go quiet when you are looking at it. Zero-config, with a bell in the conversation header as the control center.


Overview

When you run long tasks in DeepSeek Harness (DSH), you usually switch to other windows. dsh-notify pings you with a native Windows toast + sound when a turn completes, errors, or a goal is reached — only while the app is in the background: completion-class notifications are suppressed while the page is visible or any desktop-shell window is focused, while "the agent needs you back" alerts (ask / approval) always fire — those are exactly the moments that should interrupt you.

Features

  • 🔔 Bell in the conversation header: master notifications toggle (click to mute/unmute) + volume slider (0–100%), persisted to disk in real time
  • 🛌 Background-only: silent in the foreground (page visible or any shell window focused), fires in the background
  • ⚠️ Ask/approval always alert: ask_user_question / approval/asked are never muted by foreground state
  • 🔇 Master switch: notifications: false silences everything (including ask/approval), survives restarts
  • 🌐 Bilingual: toast text follows the Windows display language (English / 中文)
  • ⚙️ Zero config to start, hot-reloaded config file
  • 🧵 Smart dedup: 5s per-session dedupe; turn-completion only after the agent stays idle (800ms debounce); subagent-internal sessions are skipped

Install

dsh plugin --profile web add github:aokamoaki/dsh-notify

Restart dsh web.

Local development (link mode): add to the profile's package.json:

"dependencies": { "dsh-notify": "link:C:/path/to/dsh-notify" }

and make sure "dsh-notify" is in dsh.profile.bundles.

Quick start

No configuration needed — it just works after install and restart:

TriggerTextBackground rule
Turn done (agent idle)"Conversation" done · tookbackground only
Turn error"Conversation" failed · tookbackground only
Goal completedGoal completedbackground only
ask_user_questionYour input neededalways
approval/askedApproval needed : toolalways

Want quiet? Click the 🔔 bell in the conversation header; hover for the volume slider.

Configuration

File: ~/.dsh/dsh-notify.json (defaults when absent; bell actions write back in real time).

FieldDefaultDescriptionControl
notificationstrueMaster switch (off = everything silent)bell click
volume1Sound volume 0–1bell slider
soundtrueSound on/offconfig file
toasttrueWindows toast on/offconfig file
serviceNotifytrueService notifications (read by the desktop shell)config file

HTTP API

EndpointMethodDescription
/dsh-notify/configGETRead current config
/dsh-notify/configPOSTPartial update ({"volume": 0.5}), atomic write
/dsh-notify/foregroundGETForeground snapshot ({page, shell, foreground})
/dsh-notify/foregroundPOSTReport foreground ({"page": bool} page / {"shell": bool} shell)

All endpoints accept same-origin requests only (sec-fetch-site check).

Architecture

web page (lib/client.js)   ──visibilitychange / focus──►  POST /dsh-notify/foreground {page}
desktop shell (Electron)   ──any window focus/blur─────►  POST /dsh-notify/foreground {shell}
                                                               │ merged: foreground = page || shell
host plugin (lib/index.js) ──notify()──┐                        ▼
   session/event, goal/changed events │   done/error/goal silent in foreground, ask always
                                      └─► notify.ps1 ──► Windows toast + sound
  • host (lib/index.js): event-driven; config / foreground-state API; notify() reads config → spawns notify.ps1
  • client (lib/client.js): bell UI in the conversation header; page visibility / focus reporting
  • notify.ps1: toast + sound executor (-SoundType done|error|ask, -Volume, -NoSound, -NoToast)
  • Foreground state is in-memory only (not persisted); initial state is background so a broken reporting link can never silently swallow notifications

Compatibility

  • Platform: Windows (toast via PowerShell + Windows notifications)
  • DSH: web (dsh web); desktop shell optional (reports shell foreground)
  • Node: >=22.13

Development

dsh-notify/
├── lib/
│   ├── index.js      # host entry (events + API; pure decision/arg logic unit-testable)
│   ├── client.js     # browser half (bell UI + foreground reporting)
│   ├── notify.ps1    # toast / sound executor
│   └── activate.ps1  # toast click handler (opens the local DSH URL only, safety-checked)
├── test/notify.test.mjs  # 22 tests (node:test, zero deps, injected spawn spy)
├── cordis.patch.yml  # bundle registration
└── package.json

Client build constraint: lib/client.js must stay in the DSH client-bundle artifact format — window.__ModuleLoader__.load({ id, factory }), no import/JSX. Keep that wrapper or the browser load will fail with "loaded without registering".

Checks:

npm run check        # node --check lib/index.js lib/client.js
npm test             # 22 tests (config / decision / event wiring / HTTP routes; no real powershell)
npm run pack:check   # npm pack --dry-run

Runtime API self-check: curl http://127.0.0.1:3080/dsh-notify/config.

Troubleshooting

SymptomFix
No notifications at allCheck notifications / sound / toast in ~/.dsh/dsh-notify.json; note foreground silence is by design
Notifications fire in the foregroundThe foreground-reporting link may be down (same-origin check on /dsh-notify/foreground); refresh the page
Bell missing / GUI fails to startdsh-startup-guard may have auto-disabled this plugin (disabled: true in cordis.patch.yml with a reason comment); fix the source, remove the entry, restart
Delayed notificationsTurn-completion has an 800ms idle debounce + 5s per-session dedupe

License

MIT


Independent community plugin for DeepSeek Harness. Not affiliated with DeepSeek.