Skip to content
dsh.fish
Bundle

@dsh-external/dsh-agent-sound-alert

Agent 停止音效提醒:监听会话事件 firehose,在完成、审批询问和异常中断时播放 macOS 系统音效

Source
moonlin1213
stars
1 stars
License
MIT
Updated
Updated yesterday

Readme

# dsh-agent-sound-alert

A macOS sound notification plugin for [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness). It listens to the Host session event firehose and plays a local system sound when an Agent completes a turn, asks for approval, or stops abnormally.

Package name: `@dsh-external/dsh-agent-sound-alert`

## Requirements

- macOS (`afplay` and `/System/Library/Sounds`)
- DeepSeek Harness with an installed runtime
- Node.js and npm

The repository is open source but intentionally has `private: true` in `package.json`: it is distributed as a GitHub source plugin, not published to npm.

## Events and defaults

| Event | Meaning | Default sound | Setting |
|---|---|---|---|
| `turn/end` completed | Turn completed; waiting for user input | Glass | `onCompleted` |
| `approval/asked` | Tool approval requested; debounced per session | Tink | `onApproval` |
| `turn/end` error / blocked | Turn failed or became blocked | Basso | `onError` |
| `turn/end` aborted (`hook` / `legacy`) | Abnormal interruption such as a policy hook | Sosumi | `onAborted` |
| `turn/end` max-tokens | Output reached its token limit | Glass | `onMaxTokens` (off by default) |

Subagent sessions are ignored by default. User-initiated cancellation (`user`, `parent`, or `disposed`) and crash-recovery replay (`interrupted`) do not play a sound.

## Settings

Open **Settings → Plugins → Plugin configuration → agent-sound-alert**. Changes apply live.

- `enabled`: master switch
- `volume`: `0` to `1`, default `0.7`
- `approvalDebounceMs`: minimum interval between approval sounds in one session, default `2500`
- `includeSubagents`: also notify for subagent sessions, default `false`
- Sound fields accept a macOS system sound name, an absolute audio file path, or `none`

The plugin exposes `agent_sound_alert_test`; pass `completed`, `approval`, `error`, `aborted`, or a macOS system sound name.

## Build

```bash
git clone https://github.com/moonlin1213/dsh-agent-sound-alert.git
cd dsh-agent-sound-alert
npm install --legacy-peer-deps
npm run check
```

The repository includes a verified `lib/` build so a fresh clone can be installed directly. Contributors who modify `src/` must run `npm run check` and commit the regenerated `lib/`. The build script locates the newest valid installed DSH runtime; set `DSH_RUNTIME=/absolute/path/to/runtime` when automatic discovery is not appropriate.

## Development injection

Use `dev_inject_plugin` only while developing:

```text
dev_inject_plugin /absolute/path/to/dsh-agent-sound-alert
```

This writes a persistent entry to `~/.dsh/super-injector/registry.json`; DSH restores it after restart. Development injection is therefore not the same as a temporary one-process load.

## Formal bundle installation

`dev_install_package` requires `lib/`, which is included in this repository. If you changed the source, complete the [Build](#build) steps first. Before converting a development injection into a formal bundle installation, remove the development registration first:

```text
dev_uninject_plugin dsh-agent-sound-alert
dev_install_package /absolute/path/to/dsh-agent-sound-alert
```

Never keep both `dev_inject_plugin` registration and `dsh.profile.bundles` registration for the same plugin. Otherwise DSH can restore both copies during cold start and fail with an error such as:

```text
settings namespace "agent-sound-alert" is already registered
```

The correct formal state is:

- one profile dependency
- one `dsh.profile.bundles` entry
- no matching entry in `~/.dsh/super-injector/registry.json`
- one active runtime instance
- no duplicate `insert` or accidental `disabled` override in `cordis.patch.yml`

## Cold-start verification

`--dump-config` validates static configuration only. It does not prove that runtime injection restoration and bundle loading will not collide.

After formal installation:

1. Fully quit DeepSeek Harness.
2. Start it again.
3. Confirm the service remains running and the desktop app reaches WebUI.
4. Confirm the plugin starts exactly once.
5. Confirm logs contain neither `already registered` nor `plugin tree failed to load`.

## Privacy

The plugin makes no network requests and collects no telemetry. It only reads DSH session lifecycle events and launches the local macOS `afplay` process. Custom audio paths are not written to plugin logs or tool responses. Playback is capped at three concurrent processes, and active players are stopped when the plugin is unloaded.

## License

MIT

Install

dsh plugin --profile web add github:moonlin1213/dsh-agent-sound-alert

Profile: web

  • 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.
Source