DeepSeek Harness Plugin

TaoYe599/dsh-notify

Stars ★ 0 Category Notifications & Integrations Added 2026-09-21

Desktop notifications for DeepSeek Harness — a web notification while a browser page holds the plugin (turn completion and pending questions), and a native Windows toast from the host for finished turns once the browser is closed.

Install

# from a prebuilt release tarball

dsh plugin --profile web add "https://github.com/TaoYe599/dsh-notify/releases/download/v0.1.0/dsh-notify-0.1.0.tgz"

# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)

dsh plugin --profile web add github:TaoYe599/dsh-notify

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 — pnpm blocks those until you allow them, so an install can stop with ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED or ERR_PNPM_IGNORED_BUILDS; dsh prints the exact key to add under allowBuilds in your profile’s pnpm-workspace.yaml, and the install works on the next run. Allowing a build is a trust decision: only install sources you trust, and pin a commit (github:owner/repo#sha).

README

System notifications for DeepSeek Harness: know when a task finishes, or when DSH is waiting on you.

A web notification while a browser page is open; a native Windows toast raised by the DSH host when the browser is closed.

What it solves

DSH needs you in exactly two states:

State How it shows up Notification
It is waiting for you ask_user_question, an approval request, a plan confirmation "Needs your reply / confirmation"
It is done with you A conversation goes from running to idle (the turn finished) "Task finished"

Coverage follows one rule: whichever process is still alive when the turn ends raises the notification.

Where you are Who notifies Channel
Looking at DSH nobody the state change is already on screen
Another tab / another app / browser minimised the page web notification (click focuses the tab) + (N) unread badge in the tab title
Browser closed the DSH host native Windows toast via PowerShell 5.1 + WinRT ToastNotificationManager

Design notes

  • Layered by surviving process. A web notification is physically impossible once the page is gone, so the host half takes over — the only process still able to speak.
  • No double notifications. A presence handshake keeps the two apart: each page pings /dsh-notify/presence every 20s while it holds the plugin and sends a sendBeacon farewell on pagehide. While any page is alive the host stays silent and lets the client own delivery — only the page knows whether you are actually looking.
  • Invisible by default. No permanent settings row. One small card asks once for notification permission; if the browser refuses to grant it (Edge's "quiet notification requests" can swallow the prompt entirely) the card comes back with the reason instead of failing silently.
  • No lost events. Detection reads the authoritative client stores through the shell.overlay standard props, so delivery is push-driven by DSH's own connection — no polling, and therefore no background-tab timer throttling.
  • Subagents do not notify. The host only reports top-level sessions (agents.roots()); a subagent finishing inside a running turn is not news.

Install

This package is a standard DSH bundle (it declares dsh.bundle.patch and ships one configuration layer). Install it with the official CLI — dsh plugin forwards its arguments to pnpm inside the profile directory and appends the bundle to dsh.profile.bundles automatically.

# from a local checkout
dsh plugin --profile web add <path-to-this-package>

# from a tarball (handy for sharing)
pnpm pack
dsh plugin --profile web add ./dsh-notify-0.1.0.tgz

# from npm or GitHub
dsh plugin --profile web add dsh-notify
dsh plugin --profile web add github:TaoYe599/dsh-notify

Verify without booting:

dsh --profile web --dump-config      # should print a "# == dsh-notify" layer

Restart dsh web after installing or updating. The bundle list and the host half are read at profile boot; client-bundle-only changes just need a page refresh.

Uninstall

dsh plugin --profile web remove dsh-notify

then restart. To disable without removing, set disabled: true on this plugin's row in the profile's cordis.patch.yml.

Why this is a community plugin rather than a PR

The official repository has has_pull_requests: false — pull requests are disabled at the repository level (issues too; only Discussions are open). Its CONTRIBUTING.md states that external pull requests cannot be accepted at the moment and asks contributors to grow the ecosystem instead, associating their project with the dsh-plugin topic, adding that "we do not believe that packages in the official repository are inherently more important than packages created by the community."

Troubleshooting

The host half appends one diagnostic line per event to ~/.dsh/dsh-notify.log.jsonl (or under $DSH_HOME):

event meaning
presence-route the presence route registered (the handshake is live)
toast a native notification was raised (sessionId / title / presenceReady)
skip + reason: page-alive a page is alive, so the client owns this one
skip + reason: subagent a subagent session — not reported
skip + reason: repeat-window same session went idle twice within 10s
toast-failed the PowerShell call failed (with the error)
no-web-server the webServer service was unavailable, so presence cannot gate delivery

Client-side logging goes to the browser console with a [dsh-notify] prefix.

Known boundaries

  • Native notifications are Windows-only for now. Detection still runs elsewhere; only the display step is skipped.
  • Presence TTL is 150 seconds. A clean browser exit sends the farewell beacon immediately; if the browser crashes, the host takes over within 150 seconds.
  • Remote access may double-notify. When DSH is reached through a non-localhost origin, the presence ping is a same-origin request; if that path is not proxied the host concludes "no page" and both channels fire. Local 127.0.0.1 is unaffected.
  • Subagent sessions are intentionally silent.

Layout

dsh-notify/
├── package.json          # dsh.bundle.patch + dsh.client(platform: web)
├── cordis.patch.yml      # inserts this plugin's row into the profile composition
├── lib/
│   ├── index.js          # host half: presence route + turn-end detection + Windows toast
│   └── client.js         # client bundle (hand-written; no build toolchain)
├── LICENSE
└── README.md             # 中文说明

Content from the project README on GitHub ↗

Links

More in this category

View the whole category →

Community comments

Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.