Skip to content
dsh.fish
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

[![npm version](https://img.shields.io/npm/v/dsh-helper)](https://www.npmjs.com/package/dsh-helper) [![npm downloads](https://img.shields.io/npm/dm/dsh-helper)](https://www.npmjs.com/package/dsh-helper) [![GitHub stars](https://img.shields.io/github/stars/sunligh91/dsh-helper)](https://github.com/sunligh91/dsh-helper/stargazers) [![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

[![Supported DSH: 0.1.2-rc.1+](https://img.shields.io/badge/DSH-0.1.2--rc.1%2B-blue)](https://www.npmjs.com/package/@deepseek-ai/dsh) [![platform](https://img.shields.io/badge/platform-Windows-0078D6)](https://github.com/sunligh91/dsh-helper)

[![task notifications](https://img.shields.io/badge/-task%20notifications-4dc6fe)](https://github.com/sunligh91/dsh-helper) [![settings panel](https://img.shields.io/badge/-settings%20panel-4dc6fe)](https://github.com/sunligh91/dsh-helper) [![zero build](https://img.shields.io/badge/-zero%20build-4dc6fe)](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

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