Audio and voice alerts for the dsh web GUI: distinct tones and optional speech for approvals, questions, completions and errors.
Install
# from npm (prebuilt)
dsh plugin --profile web add @machine-126/dsh-alert-sound
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:Machine-126/dsh-alert-sound
Any plugin you install runs third-party code with your own permissions — it can read your files, use your credentials, and reach the network, and tool approvals don’t sandbox it. GitHub-sourced plugins also run build scripts at install time — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).
README
English | 中文
Notification sound alerts for the DeepSeek Harness (dsh) web GUI. When a session needs an approval, needs your answer, finishes a turn, or hits an error, the plugin plays a distinct synthesized tone and shows a toast — optionally with a spoken voice utterance. Each kind has its own selectable sound/voice, enable toggle and a master volume, configured in a dedicated Settings page. The UI and the spoken voice support both Chinese and English (switch in settings).
Note: the plugin shipped Chinese-first; its on-screen labels (sound names, notification kinds, settings page) are localized. Use the 界面语言 / Language picker in settings to switch between 自动 (auto) / 中文 / English — English is used throughout this README for reference.
About this project: requirements and acceptance testing by the repo owner @Machine-126; the code was developed end-to-end by DeepSeek Harness (an AI coding agent). Issues are welcome at the issue tracker.
- Five notification kinds, distinct tones — needs approval / needs answer / output complete / error, plus an experimental Stalled kind (off by default).
- Optional voice — switch any kind to Voice (语音) to hear it spoken (browser speech synthesis), in the selected interface language. If speech synthesis fails to start, the plugin falls back to that kind's tone, so an alert is never silent.
- Settings page (sidebar → 提醒音 / Alerts) — master volume (0–200%), per-kind enable, sound picker (Ding-dong 叮咚 / Low 低沉 / Tap 轻点 / Alert 警醒 / Voice 语音 / Custom 自定义 / Mute 静音), a preview button, and Restore defaults (with a confirmation).
- Works in the background — audio is unlocked on the first user gesture.
- Alerts across all sessions by default — a multi-session user hears approval/answer/error/completion from any session; switch to 仅当前会话 (current session only) in settings if you only care about the one you're viewing.
- Voice reads the detail — with a kind set to Voice, it speaks the specific blocker (e.g.
Needs approval: write; write file D:\xxx,Needs answer: <question>,Error: <reason>). The fixed phrase and the spoken language follow the interface-language setting; the detail text is the session's own content. - Blocking events repeat — approval/question keep re-alerting every N seconds until handled (configurable 关/10/20/30s); error repeats a few times.
- Localized (zh/en) — the settings page, toast, per-kind/sound names and the spoken voice language all follow the 界面语言 / Language setting.
- Browser system notification — when enabled, an alert also raises a system notification (visible even when dsh is in the background).
- Stall detection (experimental, off by default) — alerts when an agent shows no progress for a while; currently
updatedAt-based and not yet reliable, so it is disabled by default. Note: the 5th Stalled alert only fires when this is on. - Settings persist to
localStorage, surviving refresh/restart; a one-click restore-to-defaults is available.
Requirements
- DeepSeek Harness
0.2.0-rc.2or newer (dsh web) — approval/question detection relies on rc2'suiSession.sessionStatus(theuiSession.pendingInteractionsobservable introduced in 0.1.2 was withdrawn from the public face); on older versions only the complete/error alerts work. - A browser with Web Audio (for tones); Web Speech for voice is optional and degrades to a tone
Install
Recommended: install the npm package (prebuilt, no build-approval, and storefronts show it by download count):
dsh plugin --profile web add @machine-126/dsh-alert-sound
Or install from GitHub (pure JS, no build step, works directly):
dsh plugin --profile web add github:Machine-126/dsh-alert-sound
Or from a local checkout (the path must be absolute; rc2 installs it as a link:, so edits need only a page refresh):
dsh plugin --profile web add D:\path\to\dsh-alert-sound
Restart dsh web, then open Settings → 提醒音 / Alerts to configure.
Usage
After install, open DSH Settings → 提醒音 / Alerts and set the sound/voice, enable switch and volume per kind; the 界面语言 / Language picker at the top switches between 自动 (auto) / 中文 / English, and Restore defaults at the bottom resets everything (with a confirmation). Notifications fire automatically; nothing else to do.
Notification kinds & default sounds
| Kind | Trigger | Default sound | Toast |
|---|---|---|---|
| Needs approval (需要审批) | uiSession.sessionStatus has pendingInteraction.kind === 'approval' for the session |
Alert (警醒, square triple) | amber |
| Needs answer (需要回答) | same source, kind === 'question' (incl. plan-review) |
Tap (轻点, quick taps) | purple |
| Output complete (输出完成) | the session's running goes true→false (authoritative source: sessionStatus.running) |
Ding-dong (叮咚, ascending two-note) | green |
| Error (发生错误) | a turn errors during a run (lastAgentError changes) |
Low (低沉, descending sawtooth) | red |
There is also a 5th Stalled/卡住 kind (experimental, off by default — enable “Stall detection” first); its default sound is Low (fault).
About the Voice sound: approval / question speak the pending detail (tool name, reason, question text); the “Output complete” reply body (the last assistant message) requires Read-aloud to be on — with it off, only the kind name is spoken. The body is capped at 400 characters.
Settings persistence
Preferences are stored in localStorage under dsh-alert-sound.v1 (master volume + per-kind {enabled, sound} + scope/repeat/system-notification/read-aloud/stall-detection/toast/voice-rate/do-not-disturb/interface-language); uploaded custom sounds live under dsh-alert-sound.custom.v1. They survive page reloads and restarts.
Privacy
All processing stays in the browser. The plugin reads, in memory only: uiSession.sessionStatus (running, the pending kind plus tool name, reason and question text); the session list row's updatedAt and retainedBy (to decide the “current session”; running only as a fallback); the session snapshot's lastAgentError (failed detection); and — only when “Read-aloud” is on — the last assistant reply text from the conversation view (for speaking it). None of it is stored or sent anywhere. The only persisted data is your own settings (localStorage dsh-alert-sound.v1; custom sounds in dsh-alert-sound.custom.v1). The plugin makes no network requests, sends nothing to any server, uses no analytics/telemetry, and plays sounds / voices through browser-local Web Audio and Speech Synthesis.
Project layout
├─ package.json # dsh.bundle + dsh.client (web client plugin)
├─ cordis.patch.yml # composition patch: inserts one row (id = in-package name)
└─ lib/
├─ index.mjs # host half (pure-client plugin; host row is a minimal placeholder)
└─ client.js # client half (bundle module-loader format)
Credits
The detection approach (watching uiSession.sessionStatus's running and pendingInteraction) follows the idea used by dsh-session-notification (BSD-3-Clause); the “task-completion chime” concept follows dsh-chime (Apache-2.0). The bundle/client-plugin structure follows the official dsh docs (docs/user/develop/basic/publish.md) and the layouts of dsh-plugin-tts, dsh-status-rotator and dsh-web-ui-notify.
The tones are original (waveforms/frequencies designed for this plugin); no audio constants were copied from the above projects. Source is an independent implementation.
License
MIT
Links
More in this category
xmanrui/dsh-im★ 1710
Connect IM bots to DeepSeek Harness via QR codes or bot credentials (9 channels: Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp).
shaobeichen/dsh-pocket★ 1576
Remote phone access to the DSH Web UI: scan a QR code for LAN or public (cloudflared tunnel) access with real-time sync, a mobile-adaptive layout, and a settings tab.
inclusionAI/Avernet#deepseek-harness-channel-bcn★ 677
Connects DeepSeek Harness to Avernet's Bot Collaboration Network over WebSocket V2, with automatic onboarding, isolated agent sessions, tool-call events, and multi-bot routing tools.
omdsh-dev/dsh-notification★ 87
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
THEWOLFWALKER/dsh-notifier★ 56
DSH notification & remote-control plane: one `notify()` API across 28 outbound channels, six inbound control channels, phone approvals/questions/task control, a Native DSH Notify & Control UI, live outbound hot-apply, multi-agent routing, and zero runtime dependencies.
whyihaveyou/dsh-suite#plugin-notify★ 56
IM webhook and local notifications on turn completion, errors, or approval (Feishu/WeCom/DingTalk/Slack/Discord/custom).
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.