Bundle
dsh-soundscape
DeepSeek Harness Web UI soundscape: turn-complete celebration (synthesized chime + confetti burst), blocked/approval alerts, error buzz, send clack and optional typing ambience. Zero audio assets, zero core changes, and a ctx.soundscape service other plugins can call.
- Source
- Blaczz
- stars
- 2 stars
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dsh-soundscape 🔊
> A session soundscape for the DeepSeek Harness Web GUI: turn-complete celebration (synthesized fanfare + confetti), blocked-on-user alerts, error buzz, send clack, and optional typing ambience. Zero audio assets, zero core changes, plus a `ctx.soundscape` service for other plugins.
[English](./README.md) | [简体中文](./README.zh.md)
A **DeepSeek Harness (DSH)** web plugin that gives the agent's turns an audio identity: synthesized WebAudio feedback when a turn starts, succeeds, fails, or blocks on you — and a confetti burst when work completes. Every sound is generated live by oscillators and envelopes — **no audio files, no network requests, no core modifications**. Install, restart, and it works; tune it per-sound in the settings page.
## ✨ Features
| Event | Sound | Default |
|---|---|---|
| Turn started | send rebound clack `send` | ✅ |
| Turn completed successfully | **celebration fanfare + confetti** `celebrate` (or plain `ding`) | ✅ |
| Turn errored / interrupted | low buzz `buzz` | ✅ |
| Waiting on you (approval / question / plan review) | two-tone alert `alert` (1.5s throttle) | ✅ |
| Session opened | soft two-note greeting `greet` | ⛔ |
| Streaming output (optional) | typing ambience `click` (throttled + jittered) | ⛔ |
- **Zero audio assets**: pure WebAudio oscillator synthesis.
- **Zero core changes**: only official client-plugin seams (`conversation.input.dock` / `conversation.session.header.actions` / `settings.section`).
- **Durable settings**: the `soundscape` settings namespace, saved immediately.
- **Cross-plugin service**: `ctx.soundscape.play(name)` / `ctx.soundscape.celebrate()` for other client plugins.
- **HMR friendly**: every registration is a `ctx.effect`; hot reload cleans up automatically.
## 📦 Install
Prereqs: [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (`dsh web` works), Node ≥ 22.19, pnpm.
```bash
# From GitHub
dsh plugin --profile web add "github:Blaczz/dsh-soundscape#main"
# Local directory (development)
cd dsh-soundscape && npm install --legacy-peer-deps && npm run build
dsh plugin --profile web add ./dsh-soundscape
# Local link
dsh plugin --profile web add link:./dsh-soundscape
```
**Restart `dsh web` after install** (a new plugin row needs one restart; later source changes ride HMR).
> Git installs need `allowBuilds` authorization: if the first `add github:...` fails, put the package key
> under `allowBuilds` in `~/.dsh/profiles/web/pnpm-workspace.yaml` as dsh prints, then re-run; or publish a
> prebuilt npm package to skip build authorization entirely.
## 🎛️ Usage
1. Install, restart, open any session, send a message:
- turn start → rebound clack;
- successful completion → **fanfare + confetti** (switch to a plain ding in settings);
- error/interrupt → buzz; waiting on your approval/answer → two-tone alert.
2. The session header has a **🔊/🔇** quick mute toggle (durable across restarts).
3. **Settings → 🔊 音效**: master switch, master volume, per-sound toggles with previews, and stream-cadence knobs.
## 🔌 For developers: the `ctx.soundscape` service
Other client plugins add `soundscape` to their `inject` and call:
```ts
export const inject = ['slots', 'soundscape']
export function apply(ctx: Context): void {
ctx.soundscape.play('celebrate') // one sound
ctx.soundscape.celebrate() // full celebration (sound + confetti)
if (!ctx.soundscape.isEnabled()) ctx.soundscape.setEnabled(true)
}
```
Sound names: `click` `send` `ding` `celebrate` `buzz` `alert` `greet`. Each is gated by its user setting and the master volume.
## 🛠️ Development
```bash
npm install --legacy-peer-deps # build deps
$env:DSH_NODE_MODULES = "$env:USERPROFILE\.dsh\profiles\node_modules"
npm run setup:dsh-workspace # symlink the runtime @deepseek-ai/* packages
npm run verify # ★ one-shot local gate (clean + typecheck + test + build)
npm run typecheck # typecheck src + tests
npm test # vitest (37 tests: state machine / synth / engine / settings / manifest)
npm run build # tsc + tsdown → lib/
dsh web --patch ./cordis.patch.yml # zero-install quick verification
```
`npm run verify` is the pre-push gate: the extracted pure state machine (`turn-feedback.ts`) plus mock AudioContext / fetch tests catch event-mapping, gating, and throttle bugs locally, no browser needed.
### Layout
```
dsh-soundscape/
├── package.json # dual contract: dsh.bundle.patch + dsh.client
├── cordis.patch.yml # bundle patch layer (inserts this package)
├── tsdown.config.ts # client bundle (__ModuleLoader__.load + purity gate)
├── scripts/ # build / clean / setup-dsh-workspace
├── src/
│ ├── index.ts # host half: settings namespace + loopback HTTP API
│ ├── soundscape-settings.ts # shared settings model (schema + defaults)
│ ├── settings-api.ts # GET/PATCH settings API (loopback-only)
│ └── client/ # browser half
│ ├── index.ts # apply: ctx.soundscape service + slot injection
│ ├── SessionListener.tsx # conversation-snapshot diff → event sounds
│ ├── SoundEngine.ts # WebAudio engine (lazy AudioContext)
│ ├── synth.ts # pure synthesis primitives (oscillators + envelopes)
│ ├── confetti.ts # zero-dependency canvas confetti particles
│ ├── HeaderMute.tsx # session-header mute toggle
│ ├── SettingsSection.tsx # settings page (with previews)
│ └── settings-client.ts # settings API client
└── tests/ # manifest contract + settings patch validation
```
## 🧩 Ecosystem positioning
- **Fills a gap**: before this, the DSH ecosystem had **no** turn-complete sound/celebration effect and no blocked-on-user alert sound (desktop notifications are silent; `dsh-fun-typewriter` covers only typing ambience).
- **Technical route**: dual-sided client plugin (`dsh.client` + bundle patch), mirroring `dsh-fun-typewriter`'s zero-asset WebAudio + plugin-owned settings API, extended with the `ctx.soundscape` cross-plugin service (the `ctx.provide` pattern from `dsh-client-shortcuts`).
- **Zero core changes**: everything registers through `ctx.effect` / `ctx.slots.inject`; HMR unload cleans up.
## ⚖️ License
MIT © 2026 Blaczz. An independent community plugin, not affiliated with [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness).
Install
dsh plugin --profile web add github:Blaczz/dsh-soundscape
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-soundscape from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.