Community plugin for DeepSeek Harness Β· MIT

Customizable bell notifications for your Agent

A distinct bell for every lifecycle event, plus a breathing status dot that tells you what your Agent is up to. No audio files β€” every bell is synthesized in real time with the Web Audio API, and each event can be swapped for your own sound.

dsh-bell-notify β€” bells and status dot in the corner of a dsh session

In the corner: the breathing status dot. Every step: its own bell.

What it does

One small plugin, three small things: distinct bells, your own sounds, and a breathing status dot.

🎡 A distinct bell for every step

Startup, thinking, tool calls, command done, waiting on you… each event sounds different, so you can follow progress with your ears.

πŸŽ›οΈ Swap in your own sounds

Click the little dot: preview, upload your own audio file, or reset to default. Your replacement sticks and survives reload.

🎼 Sounds that are "alive"

All bells are synthesized on the fly β€” zero audio assets, a negligible footprint, fully offline, and pitch/rhythm tunable via config.

πŸ”΄ A status dot that "breathes"

It doesn't interrupt, doesn't pop up, doesn't add text β€” it just quietly keeps you company.

πŸ”΅ Blue pulse Β· thinking
🟠 Orange rhythm · working (tools/commands)
🟑 Yellow blink · waiting on you
🟒 Green ripple · this turn ended nicely

🎧 Hear every bell live

Same recipes and rendering logic as the plugin runtime (real-time Web Audio synthesis, no audio files). Volume 0.7, the default masterVolume.

πŸ”Š Click any bell once to unlock audio (browser autoplay policy).

Install

From a DeepSeek Harness source checkout:

pnpm dsh plugin --profile bell add github:Laplace-bit/dsh-bell-notify

If dsh is already on your PATH:

dsh plugin --profile bell add github:Laplace-bit/dsh-bell-notify

The first add is expected to fail: git install has to run the prepare script, and pnpm β‰₯10 blocks it until you allow it. Open ~/.dsh/profiles/bell/pnpm-workspace.yaml, add the onlyBuiltDependencies snippet pnpm printed, then run the same add again.

Start it:

pnpm dsh --profile bell

Open the page, click anywhere once (browser autoplay policy unlocks audio), then run any task β€” the sounds and the dot come alive together.

Remove it:

pnpm dsh plugin --profile bell remove dsh-bell-notify

🎡 Default bell for every event

Every move the Agent makes rings once, and each one sounds different. Try them all live above.

EventDefault bellFeels like
Session startstartupA soft upward sweep, like powering on
Agent startclickA short "ding", we're off
ThinkingnotifyA gentle single note, settling in
Tool calltickA crisp metallic "ta-ta"
Tool donedropA low settle, wrapping up
Command runbeepA short beep, terminal-flavored
Command doneriseA rising two-note "done"
Waiting for youalertA high triple-chirp, look here
Turn completesuccessA rising major chord, satisfying
Back to idleconfirmA single note drifting down, quiet again

error and failure are built in too, off by default β€” wire them up in config if you like.

Configuration

Edit the profile's cordis.patch.yml (Cordis validates and fills defaults at load):

OptionDefaultDescription
enabledtrueMaster switch
masterVolume0.7Master volume 0-1
muteAllfalseMute, but the dot keeps working
maxQueue8Wait-queue capacity
maxConcurrent3Simultaneous sounds (1 = serial)
defaultCooldown1000Global cooldown fallback (ms)
statusRevertMs1000Transient status auto-revert (ms)
showStatusIndicatortrueShow the corner status dot

Sound toggles and custom-sound replacements live in browser local storage (localStorage + IndexedDB) β€” click the dot to change them, applied instantly and kept across reloads.

FAQ

Is this an official DeepSeek plugin?

No. It's a community plugin for DeepSeek Harness (dsh), MIT-licensed, not part of the official distribution.

Why is there no sound?

Most likely the browser autoplay policy β€” after the plugin loads you need to click the page once to unlock audio.

Can I keep the sounds and drop the dot?

Yes. Set showStatusIndicator: false; sounds keep working.

Where are custom sounds stored?

Bytes in browser IndexedDB, event-to-file mapping in localStorage. All local β€” nothing is uploaded anywhere.