Event sounds for DSH: plays a chosen sound on session end, options popup, permission request and stop, with AI-generated character voice lines and a manageable sound library.
Install
# from npm (prebuilt)
dsh plugin --profile web add dsh-sound-lab
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:miiaowuwu/dsh-sound-lab
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. Only install sources you trust, and pin a commit (github:owner/repo#sha).
README
English | 中文
A DSH Web GUI Sound Lab: pick a sound for each of the four triggers (session end / options popup / permission request / stop), generate AI character voice lines, and upload & manage your own sound library — all set with a few clicks, no code needed; draggable floating ball, 3 appearances, dual-persisted config.
🐋 Character reference: a fan-made project for Angelina from Arknights. The bundled sample sounds are Angelina's "hirari do~", "Huh?" and "AWAWA!" voice clips, for personal learning and entertainment only — not for commercial use.
Install
Both methods work for either user type — Desktop users and npx dsh web users can use whichever they prefer.
Option A — Setup installer (recommended, zero dependencies, works for both):
- If dsh isn't running, start it once (the Desktop app or
npx dsh web) so its profiles get initialized — then quit it (the Desktop app or thedsh webserver) - Download dsh-sound-lab-Setup-1.2.0-x64.exe and double-click it
- The installer restarts dsh automatically — the 🔊 floating ball means it's installed
- Update: re-download the latest Setup exe and run it (restarts dsh automatically; older versions are overwritten automatically — no need to uninstall first, no conflicts)
- Uninstall: double-click dsh-sound-lab-UnSetup-1.2.0-x64.exe — it restarts dsh automatically when done
Note (just how it works — no action needed): the installer deploys the plugin to
$DSH_HOME/plugins/dsh-sound-laband registers it into every initialized profile (web, desktop, …) via the officialdsh plugincommand, so all profiles share the same copy. If no dsh CLI is found, it auto-detects one (desktop bundled runtime → system npx → downloads Node.js); if dsh hasn't been initialized yet (no profiles), it runsdsh webonce to initialize. On finish it restarts dsh automatically: for Desktop it closes the running instance first, then launches it (exactly like double-clicking the app — no terminal window, unaffected by closing the installer); when no Desktop app is detected (web environment) it prompts you to restart the dsh web service manually. Fully automated, no manual config edits.
Option B — dsh CLI (needs Node.js, works for both):
If dsh isn't running yet, start it once first (
npx @deepseek-ai/dsh web) so its profiles get initialized (npm run setupand the Option A installer do this automatically when uninitialized). Don't have dsh yet? Download the DeepSeek Harness Desktop app, or install Node.js (https://nodejs.org) and runnpx @deepseek-ai/dsh web.
Pick the one command that matches how you run dsh — Desktop or web — and run only that one (choose 1 of 2):
# Desktop users —— run this one
npx @deepseek-ai/dsh plugin --profile desktop add dsh-sound-lab --config.minimumReleaseAge=0
# web users (dsh runs via `npx dsh web`) —— run this one
npx @deepseek-ai/dsh plugin --profile web add dsh-sound-lab --config.minimumReleaseAge=0
Then restart dsh (or just start it if it isn't running):
npx @deepseek-ai/dsh web
Development convenience:
npm run setupauto-detects all local profiles and registers this plugin into each of them;npm run setup:deploydeploys a copy to$DSH_HOME/pluginsand points every profile at it (release/fixed-use mode). Add--profile <name>(e.g.node tools/install.mjs --profile web --unify) to operate on a single profile only;node tools/install.mjs --npm --startinstalls from the npm package and auto-starts the matching side when done (Desktop window for desktop / web service + browser for web).
Features
- Draggable floating ball (🔊): drag it anywhere on screen; dragging it to a screen edge collapses it into a small half-ball (a ">" icon only); click to open the settings dialog; position is persisted, defaults to the left side
- Settings dialog: draggable (grab the title bar), z-index on top
- 4 trigger conditions: session end / options popup / permission request / stop, each with an independent 【enable checkbox + sound dropdown】offering built-in chime / no sound / a specific sound ("built-in chime" is a Web Audio arpeggio — no audio file required)
- Attention events (options popup / permission request) always ring — they play as soon as they appear, regardless of the conversation's running/viewing state, and take priority over the completion sounds
- Appearance: Whale Girl (default) / Pure White / Pure Black, plus a customizable voice name
- Volume slider (0–100%), test sound dropdown (incl. a "built-in chime" option) + ▶ preview + status bar, reset button position
- Sound library (local audio in the plugin
sounds/folder, managed via asounds.jsoncontrol file) + refresh + Upload dialog: pick/drag-drop upload, delete sounds, restore hidden bundled sounds; non-bundled sounds can be renamed via ✎ - "AI Voice" dialog: above the sound library — bring your own Alibaba Cloud Bailian API Key and cloned voice ID, type a line and generate speech in your custom voice (custom file name / preview / delete, one-click add to the library with automatic registration); a step-by-step tutorial with screenshots is included; token costs are on you
- 3 bundled sounds ("hirari do~" / "Huh?" / "AWAWA!") — cannot be deleted or renamed (delete = soft-hide, restorable anytime); hidden sounds are directly previewable with instant playback
- The sound library scrolls vertically beyond 4 entries and never exceeds the settings panel height; file extensions are hidden from sound names
- Sound source: local audio files in the plugin
sounds/directory (mp3/wav/ogg/m4a/flac/opus/aac/wma/webm), served by the host side via the/dsh-sounds-controlstatic server (Range/206 chunking, ETag, streaming) - Persistent config: dual-write to localStorage + host-side
config.json, survives restarts; every field is sanitized (type/range/enum) on load, bad values fall back to defaults - Preload on startup: fetches config and sound list and buffers the configured sound when the app opens, so the first play is instant
- Defaults: volume 75%; session end →「hirari do~」, options popup / permission request →「呢?」, stop → built-in chime
- Falls back to a Web Audio built-in beep when no sound is selected or loading fails
- Dev tooling:
npm test(Node smoke tests for host-side list/config/upload/delete and browser-side logic),npm run setup/setup:fix/setup:deploy(multi-profile auto-config),releases/build-single-exe.ps1(builds the Setup/UnSetup installers)
Directory structure
dsh-sound-lab/
├── package.json # Package manifest (dsh.client / dsh.bundle.patch / types / scripts)
├── cordis.patch.yml # Composition patch: mounts line ui-event-sounds
├── CHANGELOG.md # Version history
├── README.md / README.zh.md
├── LICENSE
├── sounds/ # Sound library: bundled sounds (hirari do~/Huh?/AWAWA!) + uploaded/AI-generated audio
├── lib/
│ ├── index.js # Host side: /dsh-sounds-control static server (list/config/audio/TTS)
│ ├── client.js # Browser side: floating ball + settings dialog + trigger detection + playback
│ ├── tutorial/ # Illustrated tutorial images for AI voice generation (image1.png / image2.png)
│ └── types/index.d.ts # Type declarations
└── tools/
├── install.mjs # Multi-profile auto-config (setup / --fix / --unify / --deploy)
├── test-host.mjs # Host-side API smoke tests (list/config/upload/delete/TTS)
├── test-client.mjs # Browser-side logic smoke tests
└── api/ # Standalone TTS script (tts_api.py + guide + reference audio)
Dual-side structure
The plugin is two halves, loaded automatically from a single install:
- Host side (Node half) lib/index.js: runs in the DSH main process (Node), exposes the plugin
sounds/directory to the browser side through the/dsh-sounds-controlstatic server (sound list / audio files / config.json persistence) - Browser side (Web GUI half) lib/client.js: runs in the DSH Web GUI page — floating ball, settings dialog, trigger detection, and sound playback
Mounting of both halves is driven by package.json — no separate install needed:
dsh.clientdeclaration (exports "./client") → loads the browser side in the Web GUIdsh.bundle.patch(cordis.patch.yml) → registers the host side in the DSH main process
Because dsh plugins are isolated per profile ($DSH_HOME/profiles/<name> each has its own package.json / node_modules), a plugin must be registered in every profile you want it in — that's what the installer and tools/install.mjs automate (see Install).
Usage
- Add sounds: during development, put audio files in the repo
sounds/folder (see the directory tree above) — they are reconciled into the library automatically on startup. When installed, there is no need to hunt for the folder — open the settings dialog → Sound library → Upload, then pick a local file or drag & drop to import (it is copied into thesounds/folder of the install location automatically). You can also delete sounds from the list (bundled sounds are hidden, restorable anytime) or rename them via ✎. - Open the settings dialog: click the 🔊 floating ball
- Refresh the sound list: click "Refresh"; the plugin enumerates all audio files under
sounds/ - Configure triggers: for the four events (session end / options popup / permission request / stop), set 【enable + sound】independently — each dropdown offers "built-in chime / no sound / a specific sound" ("built-in chime" is a Web Audio arpeggio — no audio file required)
- Test sound: pick one in the "Test sound" dropdown (which includes a "built-in chime" option) and click ▶ to preview; selecting "built-in chime" or nothing previews the Web Audio arpeggio. Adjust volume with the slider (0–100%)
- In effect: the chosen sound plays automatically on matching events; a built-in beep plays as a fallback when nothing is selected or loading fails
Tip: drag the floating ball anywhere; it collapses into a half-ball at screen edges; switch between Whale Girl / Pure White / Pure Black under "Appearance"; position and config are saved automatically and survive restarts.
Disclaimer
- This is a fan-made (unofficial) personal project with no affiliation, sponsorship, or authorization from the official Arknights team or Shanghai Hypergryph Network Technology Co., Ltd.
- Character images, names, quotes, and voice assets referenced in this project (including Angelina's "hirari do~", "Huh?" and "AWAWA!" voice clips) belong to the official Arknights team and their respective right holders; the copyright of the voices belongs to the respective voice actors.
- This project is for personal learning, research, and entertainment only — not for commercial use and not for profit.
- The sound assets shipped with the project are local audio files added by users; users are responsible for ensuring their usage complies with applicable laws and the original right holders' requirements.
- If any right holder believes any content of this project infringes their rights, please contact the author to remove the material and we will handle it promptly.
- This project is provided as-is; the author is not responsible for any consequences arising from its use.
Links
More in this category
alvinunreal/openpets#dsh★ 1075
Bridges DeepSeek Harness lifecycle status, errors, and approval requests to a locally running OpenPets desktop companion.
shaobeichen/dsh-pocket★ 120
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.
omdsh-dev/dsh-notification★ 59
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
omdsh-dev/dsh-open-in-vscode★ 49
Open DSH workspace directories in VS Code directly from the web GUI.
xmanrui/dsh-im★ 48
Connect IM bots to DeepSeek Harness via QR codes or bot credentials (9 channels: Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp).
THEWOLFWALKER/dsh-notifier★ 40
Unified notification & remote control for DSH: one `notify()` API, 25+ channels (Telegram / DingTalk / Feishu / WeCom / QQ bot / WxPusher / PushPlus / ServerChan / Bark / Discord / Slack / ntfy / webhook...), level routing (timeSensitive / active / passive) with tiered retry, multi-channel inbound approval (Telegram buttons, Feishu cards, QQ, WxPusher, WeChat iLink), official QR login for QQ/DingTalk/Feishu, a local web admin console, multi-agent routing, desktop notifications — and a mobile command center: `!status` / `!stop` / `!retry` agent control from your phone plus actionable notifications (view result / retry / logs buttons that call back into the agent). Secrets redacted, tool rate-limited, zero runtime deps — plus an open event source: other plugins can inject the notifier service (ctx.notifier) and subscribe to dsh-notifier/sent events, reusing notification without coupling — and an identity system (v0.7): pairing codes (/pair in any DM, first redeemer becomes owner), composite-key bindings, member roles, and a guided bootstrap state when the whitelist is empty.