DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-turn-chime

M

dsh-turn-chime

Manifest valid

Conversation-completion chime for DeepSeek Harness: plays a sound when a user-initiated task actually finishes, not when it is interrupted.

UI (client)hasBundlePatch

dsh-turn-chime

English | 简体中文

Plays a chime when a conversation task actually finishes. The decision is made on the host side, the sound is emitted in the client, and the tone is synthesized on the fly with Web Audio — no audio files involved.

What it solves

DeepSeek Harness's api-session/status only tells you whether the agent is busy right now. Using it directly as a completion signal runs into two problems:

  • It can't tell "finished" from "interrupted". When the user hits stop, a run exits with an error, or a hook blocks it, the status flips back to idle all the same.
  • A single task can consist of multiple drivers. Subagents feeding results back, goal rounds continuing the run — every driver that stops flips idle once, so one stretch of work chimes several times.

This plugin moves the decision to the host side, so it chimes exactly once, and only when a user-initiated task finishes normally.

Install

Put the repository in any directory, then:

node install.mjs                  # install into %DSH_HOME%\profiles\desktop
node install.mjs web              # install into the named profile (multiple allowed)
node install.mjs D:\path\to\profile

The script does three things: writes a file: dependency into the profile's package.json, adds the plugin name to dsh.profile.bundles, and creates a junction under node_modules/<plugin> pointing at this repository (so source edits take effect immediately, with no copy to re-sync).

DSH must be restarted after installing — the client module manifest is generated at startup, so the plugin won't load without a restart.

To uninstall: remove that line from dsh.profile.bundles, then delete node_modules/dsh-turn-chime.

Usage

Settings → Chime:

ItemDescription
Enable chimeMaster switch
VoiceCrisp ding / Bell / Short pluck / Short beep / Water drop / Xylophone / Retro two-tone / Soft bass / Muted
Volume0–100%, previews automatically when you release the slider
Ignore subagent sessionsOn by default. A subagent finishing doesn't count as "the thing the user is waiting for"
Event channelShows whether SSE is connected and how many times it has chimed so far

The configuration is stored in the browser's localStorage (dsh-turn-chime:config:v1).

When it fires

All three conditions must hold:

  1. session/event's user/message, with source.kind === "user" — the user really sent a message (time-context injection, subagent feedback, and hook injection don't count);
  2. session/event's turn/end, with reason.kind === "completed" — finished normally. Interrupted (aborted), errored (error), blocked by a hook (blocked), and hitting max-tokens all stay silent;
  3. agent/status flipping to idle — one driver has come to a full stop.

One user message chimes once: the pending flag is consumed on the first ring, so automatic continuation of the same task doesn't ring again.

The verdict is pushed to the client over SSE at /dsh-turn-chime/events.

Troubleshooting

Host-side diagnostic log:

%DSH_HOME%\logs\dsh-turn-chime.log

A normal wrap-up looks like this:

client-ready {"hasSessions":false,"audio":true,"sse":true,...}
sse-open
chime        {"sessionId":"...","clients":1}
play         {"sessionId":"...","voice":"chime","ok":true,"count":1}
What you see in the logMeaning
No client-readyThe client plugin didn't load; restart DSH
sse:falseThe browser has no EventSource, so completion events don't arrive
client-ready but no sse-openSSE never connected; check the event channel in the settings panel
Only skip-turn-endThat turn's reason wasn't completed
No chime line at allThe host didn't pass its check: that message wasn't sent by the user
play ok:falseThe voice is "Muted", or the audio context is suspended by policy

Three routes from the same source:

  • GET /dsh-turn-chime/events — SSE completion event stream
  • GET /dsh-turn-chime/log — reads back the last 120 lines
  • POST /dsh-turn-chime/clear — clears the log

Debug entry points in the browser console:

__dshTurnChime.play('chime', 0.6)  // preview manually
__dshTurnChime.status()            // { connected, chimes, config }
__dshTurnChime.onChime('x')        // simulate a completion event → should chime once

Why it's split this way

Sound can only come from the renderer process. Playing audio in the host means either spawning a PowerShell/player process (hundreds of milliseconds of cold start, plus process reaping to manage), or using Electron's shell.beep() (no choice of tone). Web Audio is zero-dependency, zero-latency, cross-platform, and can synthesize tones on the fly.

The decision can only live in the host. The api-session/status the client receives is a boolean, so it can't show whether this turn ended normally or someone pressed stop; the turn/end reason and the user/message source exist only on the host event bus.

Files

FilePurpose
lib/index.jsHost: completion decision + the four routes /dsh-turn-chime/{events,diag,log,clear}
lib/client.jsClient: SSE subscription, Web Audio synthesis, settings panel, diagnostics reporting
cordis.patch.ymlBundle patch; a single insert line activates the plugin
install.mjsIdempotent install script
test/test-logic.mjsDecision-logic tests (replays event sequences against a fake ctx)

Tests

node test/test-logic.mjs   # or npm test

Covers six scenarios: normal finish → chime; user interrupt → silent; time-context injection only → silent; one message with two drivers → chime once; error → silent; interrupt followed by a new message that finishes → chime.

Known limitations

  • The chime only plays in the browser renderer process, so there is no sound while DSH is fully closed.
  • The decision depends on DSH internal events (session/event, agent/status). If their shape changes in a major DSH upgrade, lib/index.js needs a matching update.
  • It only chimes on reason.kind === "completed"; a turn that errors out is silent. To make errors ring as well (with a different sound), change CHIME_REASON in lib/index.js.

License

MIT

Comments

Loading…

Similar plugins

dsh-complete-chime

by Whale-Zhang

DSH plugin: play a chime when a conversation turn finishes. Built-in tones plus custom upload in Settings → Plugins.

Notifications & IntegrationsDevelopment & InfrastructureManifest valid

★ 2

MIT

JavaScript

Aug 23, 2026

dsh plugin --profile web add @dsh-external/dsh-complete-chime

Task-complete and question notification sounds for the DeepSeek Harness Web UI: a soft chime when the agent finishes a turn, a ding-dong when it asks you something (questions, plan reviews, approvals)

Notifications & IntegrationsTerminal & ClientsManifest valid

★ 0

dsh plugin --profile web add dsh-task-sounds

by AGImentu

DSH (DeepSeek Harness) Web 插件:任务完成后播放提示音(可开关、可调音量、可上传自己的音频;内置提示音由脚本合成)

Development & InfrastructureManifest valid

★ 0

MIT

TypeScript

Sep 12, 2026

dsh plugin --profile web add dsh-turn-chime

by xxxxxxxyu

DSH (DeepSeek Harness) web plugin: plays a sound when the agent finishes replying (turn/end). Sound, volume and on/off configurable in Settings.

Manifest valid

★ 3

↓ 54/wk

MIT

TypeScript

Aug 14, 2026

dsh plugin --profile web add dsh-notify-sound

by aokamoaki

Conversation-completion notifications for DeepSeek Harness: Windows toast + sound on turn done / error / goal, plus ask & approval alerts - background-only, with a volume-adjustable bell in the conver

Notifications & IntegrationsTerminal & ClientsDevelopment & InfrastructureManifest valid

★ 1

↓ 197/wk

MIT

JavaScript

Aug 16, 2026

dsh plugin --profile web add dsh-notify

by HtO404

Task-completion notification chime for the DSH web GUI: beeps when an agent turn finishes, even in background tabs. 10 preset sounds + custom import + volume.

Manifest valid

★ 0

Apache-2.0

JavaScript

Oct 10, 2026

dsh plugin --profile web add @hto404/dsh-chime