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 命令。 适合在后台运行长任务,需要弹窗、音效和系统通知提醒进度的用户。

Package
dsh-notify
Compatibility
Unverified
Harness peer range
^0.2.0-rc.1
Version
0.1.0
License
MIT
Last updated
Oct 10, 2026

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-notify

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

KindRaised when
approvalan operation is waiting for your approval
questiona question is waiting for your answer
turn_donea turn finished and it had used at least one tool
answer_donea 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

MethodPathPurpose
GET/dsh-notify/panel.js /dsh-notify/panel.cssbrowser half
GET/dsh-notify/api/settingssettings + the bundled sound list
POST/dsh-notify/api/settingsdeep-merged settings patch
GET/dsh-notify/api/eventsSSE reminder stream
GET/dsh-notify/api/notificationsthe last 50 reminders
GET/dsh-notify/sounds/.wavthe bundled sound pack

Data

WhatWhere
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.1 counts 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.