Bundle
dsh-helper
DSH task notifier plugin: pops Windows toast notifications when an agent session finishes, errors, needs confirmation, or asks for approval. Self-registers the required AppUserModelID shortcut so notifications are delivered even when the app is not focused.
- Source
- sunligh91
- License
- MIT
- Updated
- Updated 17 hours ago
Readme
# dsh-helper
[](https://www.npmjs.com/package/dsh-helper) [](https://www.npmjs.com/package/dsh-helper) [](https://github.com/sunligh91/dsh-helper/stargazers) [](https://opensource.org/licenses/MIT)
[](https://www.npmjs.com/package/@deepseek-ai/dsh) [](https://github.com/sunligh91/dsh-helper)
[](https://github.com/sunligh91/dsh-helper) [](https://github.com/sunligh91/dsh-helper) [](https://github.com/sunligh91/dsh-helper)
π [**English**](./README.md) Β· [δΈζ](./README.zh.md)
> A [DSH](https://www.npmjs.com/package/@deepseek-ai/dsh) plugin that pops native Windows notifications when an agent session **finishes**, **fails**, or **needs your confirmation** β with an optional completion chime β so you can walk away from long runs and still know the moment something needs you.
## β¨ Features
- **π Task notifications** β a native Windows toast when the agent goes idle (task complete), hits an error, is about to ask you a question, or a tool needs permission approval.
- **π Completion chime** β plays a sound when a session finishes. Ships with a built-in synthesized two-note chime; volume is adjustable (0β100) and you can point it at any local audio file (wav / mp3 / wma).
- **βοΈ Settings panel** β a **Task Notifications (dsh-helper)** section in DSH Settings with four notification toggles plus the sound controls.
- **π§ͺ Three test buttons** β preview each real notification type (complete / multi-choice confirm / permission approval) with one click.
- **πͺΆ Zero native dependencies** β notifications go through PowerShell WinRT Toast, so there is nothing to compile.
- **π Hot reload** β configuration is written back to the profile's `cordis.patch.yml` and picked up by DSH's patch watcher, no restart needed.
## π Installation
**Prerequisites**: DSH `0.1.2-rc.1+` with the `web` profile already initialized (run `dsh web` at least once), Node.js β₯ 20, pnpm β₯ 10.
### Option 1 β npm registry (recommended)
```bash
dsh plugin --profile web add dsh-helper@latest
```
The package ships **prebuilt artifacts** (`lib/` is published) and contains **no install scripts**, so pnpm never asks you to authorize a build.
### Option 2 β from the git repo
```bash
dsh plugin --profile web add github:sunligh91/dsh-helper
```
> A git install pulls source and has pnpm run `prepare`; pnpm β₯10 refuses until you explicitly allow it. Copy the exact package key pnpm prints into that profile's `pnpm-workspace.yaml`:
> ```yaml
> allowBuilds:
> dsh-helper: true
> ```
> That authorization means "allow this package's code to run on your machine at install time". If you only want prebuilt code, use **Option 1**.
### Option 3 β from source
```bash
git clone https://github.com/sunligh91/dsh-helper.git
cd dsh-helper
# link it into your web profile
cd ~/.dsh/profiles/web
pnpm add file:/absolute/path/to/dsh-helper
```
Then add `"dsh-helper"` to the `dsh.profile.bundles` array in `~/.dsh/profiles/web/package.json`, and **hard-refresh** your browser (Ctrl/Cmd + Shift + R).
## βοΈ Configuration
Go to **Settings β Task Notifications (dsh-helper)**.
| Key | Default | Description |
| --- | --- | --- |
| `notifyOnComplete` | `true` | Notify when a session finishes (deduped to once per 60 s per session). |
| `notifyOnError` | `true` | Notify when a session hits an error. |
| `notifyOnConfirm` | `true` | Notify when the agent is about to ask you a question (multi-choice). |
| `notifyOnPermission` | `true` | Notify when a tool triggers a permission approval dialog. |
| `soundOnComplete` | `true` | Play the completion chime after the completion toast. |
| `soundVolume` | `70` | Chime volume, `0`β`100`. |
| `soundFile` | `""` | Path to a local audio file (wav / mp3 / wma). Empty = the bundled chime; if the custom file is missing it falls back to the bundled chime, then to Windows built-in notify sounds. |
Defaults ship in `cordis.patch.yml`; your overrides are written to `~/.dsh/profiles/web/cordis.patch.yml`.
## π How it works
| DSH event | Behaviour |
| --- | --- |
| `agent/status` (`idle`) | Completion toast + chime |
| `agent/request-error` | Error toast (passthrough β this plugin never blocks or retries) |
| `tools/pre-execute` (`ask_user_question`) | Confirmation toast (multi-choice question) |
| `session/event` β `approval/asked` | Permission toast (tool approval) |
> Approval notifications listen on the session audit event `approval/asked` rather than the `approval/request` waterfall. Cordis waterfall semantics are "not calling `next()` vetoes the rest of the chain", so any earlier listener that returns a result directly (e.g. an auto-approval gate) would permanently starve later listeners. `approval/asked` is a log-only audit event written before the decision, so it cannot be pre-empted.
The settings HTTP route (`/_dsh/dsh-helper/settings`) is bound to localhost only β anything other than `127.0.0.1` / `::1` gets a `403`.
> π **Need auto-retry too?** This plugin intentionally does notifications only. Pair it with a retry plugin such as [`dsh-task-reliability`](https://www.npmjs.com/package/dsh-task-reliability), which returns `{ kind: 'retry' }` on the same event.
## π οΈ Development
```bash
git clone https://github.com/sunligh91/dsh-helper.git
cd dsh-helper
```
| File | Role |
| --- | --- |
| `lib/index.js` | Host half β cordis plugin: event hooks + settings route |
| `lib/client.js` | Client half β registered via `window.__ModuleLoader__`, no build step |
| `cordis.patch.yml` | Default configuration inserted into the profile |
Both halves are plain ES modules / UMD β there is no bundler, so edit and reload.
## β οΈ Known limitations
- Notifications target Windows (PowerShell WinRT Toast). On macOS/Linux the plugin still loads, but toasts and sounds are silent no-ops.
- Sound playback uses WPF MediaPlayer via PowerShell. If that's unavailable it falls back to `System.Media.SoundPlayer`, which only plays wav and ignores the volume setting.
- If Windows Focus Assist / Do Not Disturb is on, toasts may be suppressed.
- **Delivery identity (handled automatically since 0.5.0)**: Windows requires a desktop app to have a Start-Menu shortcut carrying `System.AppUserModel.ID`, otherwise toasts are **intermittently and silently dropped** (especially while a foreground window exists) β the symptom users report as "I only get notifications while the app is focused". The plugin idempotently creates that shortcut on startup (`%APPDATA%\Microsoft\Windows\Start Menu\Programs\dsh-helper.lnk`) β no manual step, no admin rights.
- If a cleanup tool removes the shortcut, it is recreated on the next DSH start.
## π License
[MIT](./LICENSE) Β© sunligh91
## π Changelog
- **0.5.0** β Fixed "no notifications unless the app is focused": Windows requires a desktop app's Start-Menu shortcut to carry `System.AppUserModel.ID`, otherwise toasts are intermittently dropped silently. The plugin now idempotently creates that shortcut at startup (runtime-created, so the package ships **no install scripts** and npm installation needs no build authorization). Also: approval notifications now listen on `session/event` β `approval/asked` instead of the `approval/request` waterfall, so an auto-approval gate can no longer starve them.
- **0.4.4** β Removed the global throttle introduced in 0.4.3 (it swallowed completion notifications from concurrent main sessions). Only the **sub-agent filter** remains.
- **0.4.3** β Fixed notification flooding: completion notifications no longer fire for **sub-agents** (dsh runs several sub-agents in parallel and each one finishing posted a "task complete" toast, flooding the notification center β main session ids carry a `session-` prefix while sub-agent ids are bare UUIDs, used for filtering); added a global 60s throttle so multiple main sessions finishing together still post at most one toast.
- **0.4.2** β The toast header now shows a real app name: the AUMID switched from the borrowed File Explorer GUID to `dsh-helper`, with its `DisplayName` idempotently written to `HKCU\Software\Classes\AppUserModelId\dsh-helper` before every send β the header changes from a hex GUID to **dsh-helper**.
- **0.4.1** β Fixed notifications falling back to a popup dialog: `GetTemplateContent` was mistakenly called on the `ToastNotifier` instance (the method belongs to the static `ToastNotificationManager` class), so the WinRT toast never actually succeeded and every notification took the WScript dialog fallback. Now calls the correct target β real toasts verified.
- **0.4.0** β Added a "needs permission" notification (hooks the `approval/request` event for tool approval dialogs); the settings panel now has three test buttons: complete / multi-choice confirm / permission.
- **0.3.2** β Fixed confirmation toasts not appearing. Windows silently drops WinRT toasts sent under an unregistered custom app id, so notifications are now sent under File Explorer's always-registered AUMID. Added a `WScript.Shell` popup fallback for environments where WinRT is unavailable.
- **0.3.1** β Added temporary diagnostic logging (to be removed once the confirm-notification issue is verified resolved).
- **0.3.0** β Added an optional completion chime (built-in synthesized two-note sound, adjustable volume, custom local file).
- **0.2.0** β Removed auto-retry; notifications only.
- **0.1.0** β Initial release: completion / error / confirm notifications.
Install
dsh plugin --profile web add github:sunligh91/dsh-helper
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-helper from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.