Skip to content
dsh.fish
Bundle

dsh-sound-notifier

DSH bundle: plays distinct chimes in the Web UI on message received, thinking start, tool call, and turn end.

Source
Zhengshuji
License
MIT
Updated
Updated 7 days ago

Readme

# dsh-sound-notifier

Sound alerts for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH): the Web UI plays a distinct chime when the agent receives a message, starts thinking, calls a tool, or finishes a turn.

Installed as an official DSH **bundle** (`dsh.bundle` + `dsh.client`), so it loads automatically on every DSH start — no per-session activation required.

## Features

| Moment | Event | Sound |
|---|---|---|
| Message received | `agent/inbox/inserted` | two short pops (660 Hz → 990 Hz) |
| Thinking starts | first `reasoning-delta` in `llm/stream` | rising sweep (392 → 784 Hz, triangle) |
| Tool invoked | `tools/pre-execute` | crisp double tick (233 Hz → 311 Hz, triangle) |
| Turn ended | `agent/turn-stopping` | major-triad arpeggio (C5–E5–G5) |

- Sounds are synthesized with the Web Audio API — no audio assets.
- Only top-level sessions chime; subagent/workflow activity stays silent.
- Already-played events are not replayed after a page refresh (`sessionStorage`).

## How it works

The plugin has two halves:

- **Host half** (`index.js`) listens to DSH events, appends them to a bounded queue (256 entries), and serves them over a `GET /sound-alerts/events?after=N` endpoint registered through the official `webServer` service.
- **Browser half** (`client.js`) is a standard `dsh.client` plugin: the client-modules table injects it into `window.__DSH_BOOT__`, it polls the endpoint every 400 ms, and plays the matching chime.

## Requirements

- DeepSeek Harness with the Web UI (`dsh web` / `dsh --profile web`)
- pnpm (the `dsh plugin` command forwards to pnpm)

## Installation

From the root of your `deepseek-harness` checkout:

```sh
pnpm dsh plugin --profile web add /path/to/dsh-sound-notifier
```

This links the directory into `~/.dsh/profiles/web`, and because `package.json` declares `dsh.bundle`, it is appended to the profile's `dsh.profile.bundles` automatically.

**Restart DSH** (stop the running `pnpm dsh web` and start it again) for the plugin to load.

Verify the composed config without restarting:

```sh
pnpm dsh --profile web --dump-config   # shows a "# == dsh-sound-notifier" layer
```

Install directly from GitHub (add the printed package key to the profile's `pnpm-workspace.yaml` `allowBuilds` on first try, see the [official publishing guide](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/develop/basic/publish.md)):

```sh
pnpm dsh plugin --profile web add github:your-name/dsh-sound-notifier
```

## Uninstall

```sh
pnpm dsh plugin --profile web remove dsh-sound-notifier
```

## Customizing sounds

Edit the `SOUNDS` table in `client.js`:

| Option | Meaning |
|---|---|
| `freq` | start frequency (Hz) |
| `endFreq` | sweep target frequency (Hz); omit for no sweep |
| `dur` | duration (seconds) |
| `type` | waveform: `sine` / `triangle` / `square` / `sawtooth` |
| `gain` | volume (0–1) |
| `delay` | relative delay (seconds), for sequencing multiple notes |

The local `link:` install reads the file directly — save and restart DSH.

## Project structure

```
dsh-sound-notifier/
├── package.json        # dsh.bundle + dsh.client manifest; exports ./client
├── cordis.patch.yml    # plugin row: { id: sound-alerts, name: dsh-sound-notifier }
├── index.js            # host half: event listeners, queue, polling endpoint
└── client.js           # browser half: dsh.client bundle, polls and plays
```

## Known limitations

- **Polling latency**: up to ~400 ms between an event and its chime.
- **Fixed endpoint**: `/sound-alerts/events` is served by the host half's `webServer` route; without a webserver the events are still recorded but never polled.
- **Top-level sessions only**: `agent.owner === undefined` filtering means a subagent page opened on its own stays silent.
- **Internal LLM calls are skipped**: `compaction` and `session-title` purposes never trigger the "thinking" chime.
- **Browser autoplay policy**: the audio context is created lazily and `resume()`d on each play.

## Contributing

Bug reports and pull requests are welcome. Keep changes focused; update this README when behavior changes.

## License

[MIT](LICENSE)

Install

dsh plugin --profile web add github:Zhengshuji/dsh-sound-notifier

Profile: web

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source