Back to home

Zouu-X

DSH_WebNotification

It is a plug-in that helps sending notifications when agent finishes in DSH. 这是一个DSH的网页提示插件,让Agent跑完任务时会有明确提示

Stars
1
Language
TypeScript
Created
Aug 16, 2026
Updated
Aug 16, 2026

Introduction

dsh-notify

Browser notification for the DeepSeek Harness Web UI — get a system notification the moment a session finishes running.

dsh-notify is a small, behavior-only Web client plugin for DeepSeek Harness (dsh). When you hand the model a long task and switch to another tab or application, it raises a browser notification the instant the task completes, so you never have to keep checking back.

Features

  • 🛎️ System notification on completion — fires exactly when a session's running state flips to idle, titled with the session name and a Chinese completion body.
  • 👀 No noise while you watch — it stays silent only when you are actively looking at the session that just finished. It notifies when:
    • the page is hidden (you switched tab), or
    • the browser window lost focus (you switched to another app), or
    • the completing session is not the currently selected one.
  • 🔁 Per-session dedup — each notification is tagged by session, so a repeat replaces the previous instead of stacking.
  • 🔐 Permission asked at the right moment — the permission prompt appears on your first click or keystroke, not while you are away (this is what makes it work in Safari).
  • ⚙️ Zero UI — no buttons, no settings screen, no host-side changes. It is one browser row in your profile.

Requirements

  • DeepSeek Harness with the Web UI (dsh web, or dsh --profile web).
  • A modern browser. The Web UI runs on http://127.0.0.1:<port>, which is a secure context, so the Notification API is available.
  • On macOS, also allow the browser in System Settings → Notifications, otherwise the OS suppresses the banner even when the page has permission.

Install

dsh-notify is an installable bundle. Install it into a profile from npm, a tarball, or straight from this repository.

# from GitHub (this repo)
dsh plugin --profile web add github:you/dsh-notify

# from npm
dsh plugin --profile web add dsh-notify

# from a local checkout or packed tarball
dsh plugin --profile web add ./dsh-notify

dsh plugin forwards to pnpm, so any pnpm spec works. Installing a bundle appends it to the profile's dsh.profile.bundles and applies its patch layer; no manual cordis.yml editing is needed.

GitHub installs need no build step. This repository commits its built lib/, so dsh plugin add github:you/dsh-notify works directly, with no install-time build allowance to grant.

Usage

Install, then boot the Web UI and grant the notification permission the first time the browser asks (on your first click or keystroke):

dsh --profile web

Start a task in any session, switch away, and a system notification appears when the model finishes. There is nothing else to configure.

How it works

The plugin injects the runtime's sessions service and subscribes to the session list snapshot — the same fact source the sidebar reads. A small fold keeps each session's previous running bit, records the first observation without notifying, and dispatches one notification per running → idle edge, gated by the "are you looking at this session" rule above.

The browser half is a CJS bundle registered through window.__ModuleLoader__.load, which the harness's client module system scans and serves under /plugins/dsh-notify/client.js. The node half is a no-op host plugin body.

Development

pnpm install     # install dev tooling
pnpm build       # bundle lib/index.js (node) and lib/client.js (browser)
pnpm typecheck   # tsc --noEmit
pnpm test        # vitest

Build artifacts are committed under lib/ so GitHub installs work without a build step.

dsh-notify/
├── package.json        # dsh.client + dsh.bundle.patch manifests
├── cordis.patch.yml    # bundle layer: inserts the dsh-notify row
├── tsdown.config.ts    # builds the node half and browser half
├── src/
│   ├── index.ts        # node half (no-op host plugin)
│   └── client/
│       ├── index.ts    # apply / inject
│       ├── watcher.ts  # running→idle edge detection
│       ├── notifier.ts # Notification dispatch + permission bootstrap
│       └── types.ts    # minimal local runtime views
└── tests/notify.spec.ts

Known limitations

  • Always on — there is no user-facing toggle yet. A settings row (enable/disable, sound, only-when-hidden) is the natural follow-up.
  • System notification only — completion does not also produce an in-app toast or a title flash; the sidebar's built-in green "done" dot remains the in-app signal.
  • Browser-owned permission — if the user denies the permission prompt, the plugin is disabled for that origin with no in-app recovery.
  • No sound — a short chime is deferred.

License

MIT