LBurny/dsh-plugin--packages-dsh-notify ↗★ 0
dsh-notify
Task reminders for DeepSeek Harness: approval, question, turn done and answer ready, each with an in-page popup, a bundled sound and a browser notification. Subscribes host-side and streams over SSE. Ships a panel and the /notify command. dsh-notify:dsh 任务提醒——四类事件(等待批准/等待回答/任务完成/回答就绪)弹窗、音效与系统通知,自带面板与 /notify 命令。 适合在后台运行长任务,需要弹窗、音效和系统通知提醒进度的用户。
Other repositories with this package name
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:LBurny/dsh-plugin#7922dc00723785a651a741a9d255357f56b87f56&path:packages/dsh-notifyREADME
Read the full README ↗dsh-notify
Task reminders inside dsh: a popup, a sound and a browser notification, for four kinds of events.
Ported from DSHDesktop, which raised Windows toasts from WinRT and played WAV files on a
self-managed waveOut thread. Neither exists inside dsh, so the split is: the host half subscribes
to dsh's own events and republishes them on a small SSE stream, and the browser half plays the sound
and shows the notification.
Why subscribe host-side instead of having the page connect to /api/remote.mux: the page would have
to replay the frame protocol (stream ids, $events waterflow acks, per-session session/follow)
that the desktop shell implements in Rust. ctx.on(...) host-side is far less code and far less
likely to break on a dsh upgrade — and SSE reconnects on its own.
Placement
With dsh-features (功能管理) installed, this panel appears on that hub's single
page and no longer docks its own corner button; without the hub — a bare dsh, or a profile where it is
not installed — the floating panel is built exactly as before. The coupling is two DOM-level
conventions (window.__dshFeatures, #dsh-launchers), described in the repository's AGENTS.md.
Install
dsh plugin --profile web add github:LBurny/dsh-plugin#path:/packages/dsh-notify
# pin a commit:
dsh plugin --profile web add github:LBurny/dsh-plugin#&path:/packages/dsh-notify
--profile web = DSHDesktop's shell, --profile desktop = the official desktop app; the panel needs no flag.
Restart dsh afterwards — plugins have no HMR.
The four kinds
| Kind | Raised when |
|---|---|
approval | an operation is waiting for your approval |
question | a question is waiting for your answer |
turn_done | a turn finished and it had used at least one tool |
answer_done | a turn finished and it was a plain answer |
Subagent turns are suppressed, and a turn that did not end with reason.kind == "completed" is not
reported — the same rules the desktop shell applies.
Each kind has an on/off switch and a timing: always, or only when this page is not focused (the default — no point popping a toast you are already looking at).
Channels: an in-page popup, a sound (a bundled 17-sound pack, the system default, or silent), and a browser notification (needs permission once). Volume 0–1.
Routes
| Method | Path | Purpose |
|---|---|---|
| GET | /dsh-notify/panel.js /dsh-notify/panel.css | browser half |
| GET | /dsh-notify/api/settings | settings + the bundled sound list |
| POST | /dsh-notify/api/settings | deep-merged settings patch |
| GET | /dsh-notify/api/events | SSE reminder stream |
| GET | /dsh-notify/api/notifications | the last 50 reminders |
| GET | /dsh-notify/sounds/.wav | the bundled sound pack |
Data
| What | Where |
|---|---|
| The four rules, sound, volume, popup and browser toggles | $DSH_HOME/dsh-notify.json |
Caveats
- The sound is played by the browser (
HTMLAudioElement), not by a native audio thread, so the browser's autoplay policy can block it until you have interacted with the page. The popup and the system notification are unaffected. - Browser notifications need permission (and a secure context —
127.0.0.1counts as one). - The panel must be open in some tab for reminders to be raised at all: the SSE stream lives in the page. Reminders are per-browser, not per-machine.
Test
cd "$DSH_HOME/profiles/plugins/dsh-notify"
node test/notify.test.mjs
License
MIT. The WAV files under sounds/ come from opencode via DSHDesktop and are copied as-is.