dsh-task-reminder
Conversation task-completion reminders for the DeepSeek Harness Web UI
Language: English | 简体中文
📋 Table of Contents
Agent turns in DeepSeek Harness keep running while you read the news in another
window — and the only signal that a task finished was the session list turning
idle. This plugin turns that moment into a real reminder, without leaving the
browser surface you already use.
When a conversation task finishes while you are not looking at the
conversation window, the plugin can remind you three ways: a bottom-right reminder card as
the fallback when the system notification cannot be delivered, a synthesized
chime, and a system notification that survives even when the browser is in the
background. Everything is configured on its own settings page and persists
across restarts.
The whole plugin lives on the browser side. The host half (index.js) is an
empty apply() {}, and there are no runtime dependencies — the host ships it
to the page as a client plugin.
✨ Features
- Reminder card as the fallback: when the system notification cannot be
delivered (permission not granted, or the browser lacks the Notification
API), a bottom-right card (8 px from the corner) shows the session name and
jumps straight back to it. Width (240–640 px) and height (0–400 px,
0 = automatic) are adjustable, with a live sample card on the settings
page.
- Four synthesized chimes: two-tone (classic), rising three-tone, rising
arpeggio, and soft triangle — generated live with Web Audio, so no audio
files are shipped. Picking an effect plays it immediately at the current
volume; there is no separate preview button.
- System notifications, on by default: Web Notification API, so the
reminder is an OS toast you can see while the app is in the background.
Clicking it brings the window forward and opens the session. The browser
asks for notification permission once on the first load — the Notification
API has no permission-free path, which is why in-page-only plugins never
show such a prompt. If the permission was reset afterwards, a Request
notification permission button under the System notification row re-asks.
A denied or unsupported Notification API degrades to a clear hint on the
settings page instead of failing silently.
- Dedicated settings page:
Settings → Task reminder (no more rows in
Settings → General), with one-click restore defaults.
- Presence-aware silence for the card and the notification: the reminder
stays quiet only while the main area shows the conversation window, the tab
is visible, and the window has focus. Switching panels, switching tabs, or
focusing another application all count as away — the card and the system
notification fire. The chime ignores presence and sounds on every task
completion.
- Dual-channel completion detection with deduplication: the host-forwarded
api-session/status event and the official session list's own running bit
share one edge table, so one completion never fires twice.
- All values persist in browser local storage and survive restarts, so the
host half needs no settings namespace.
🚀 Quick Start
What you need: DeepSeek Harness running with the web profile
(dsh web), pnpm on your PATH (the dsh plugin command forwards to it),
and a browser you can hard-refresh.
Step 1 — Open a terminal
- macOS / Linux: open Terminal.
- Windows:
Win + R, type powershell, press Enter.
Step 2 — Install and register with one command
dsh plugin installs the package into the profile directory and appends the
bundle to the profile's dsh.profile.bundles in a single step — no manual
registration:
# Windows (PowerShell) — run it from any directory
dsh plugin --profile web add github:hawkongz/dsh-task-reminder
# macOS / Linux
dsh plugin --profile web add github:hawkongz/dsh-task-reminder
To pin a release instead of the default branch, append the tag:
dsh plugin --profile web add github:hawkongz/dsh-task-reminder#v1.2.1.
Once the package is published to the npm registry, the bare name works the
same way: dsh plugin --profile web add dsh-task-reminder.
Step 3 — Restart and verify
Restart the host (dsh web), then hard-refresh the browser (Ctrl + F5).
The browser does not hot-read a changed client.js, so both steps are
required after every update. Verify the registration:
dsh --profile web --dump-config | Select-String task-reminder
Done. Open Settings → Task reminder: if the page is there, the plugin
is live. On the first load the browser shows a one-time
notification-permission prompt — choose Allow and the system
notification is set. Run a task in any session, switch to another
application, and wait for the reminder.
📦 Installation
Prerequisites
- DeepSeek Harness (
dsh web) with a web profile.
- pnpm on your
PATH — dsh plugin forwards its arguments to pnpm inside the
profile directory.
- Node.js 20 or newer (for the self-check).
- A browser that supports Web Audio and (optionally) the Notification API.
Install with dsh plugin
dsh plugin --profile web add github:hawkongz/dsh-task-reminder
This installs the package into the profile and appends dsh-task-reminder to
the profile's dsh.profile.bundles; the loader then applies the bundle's
cordis.patch.yml and inserts the task-reminder row. The package ships no
build scripts, so pnpm never blocks the install (unlike git-hosted packages
that need an allowBuilds entry in the profile's pnpm-workspace.yaml).
The package contains everything the plugin needs: index.js (host half),
client.js (browser half), cordis.patch.yml (the bundle row), and the
self-check under test/.
Uninstall
dsh plugin --profile web remove dsh-task-reminder
The remove drops the package and reconciles the bundle list in one step.
Then restart dsh web so the row leaves the composed config.
Local development install
To iterate on a checkout instead of the published package, link it into the
profile (this is what the plugin_manager tool's install_bundle action
creates internally):
# Windows (PowerShell) — from the directory that contains the checkout
dsh plugin --profile web add link:.\dsh-task-reminder
# or with an absolute path, from anywhere
dsh plugin --profile web add link:C:\Users\20105\OneDrive\Desktop\ds\dsh-task-reminder
Remember the restart rule: edit client.js, run node test/verify-client.mjs,
restart dsh web, hard-refresh the browser — the host does not hot-read a
changed client.js.
📖 Usage
Settings page
Settings → Task reminder (settings navigation order 44):
| Setting | Default | Persist key |
|---|
| System notification | On | dsh.task-reminder.notify |
| Completion sound | On | dsh.task-reminder.sound |
| Chime effect (four options) | Two-tone (classic) | dsh.task-reminder.sound-choice |
| Chime volume (0–100) | 80 | dsh.task-reminder.volume |
| Card width (240–640 px) | 420 | dsh.task-reminder.width |
| Card height (0–400 px, 0 = automatic) | 0 | dsh.task-reminder.height |
Below the rows sits a live card preview that follows the width and height
settings, and a restore-defaults button that writes back: notification on,
sound on, first effect, volume 80, width 420 px, automatic height.
Browser console helpers
In the browser DevTools console:
// Panel state, the six settings, notification permission, current cards,
// per-session running records, channel counters and the last completion source
__dshTaskReminder.state()
// Pop a card right away and play the chime (does not wait for a task)
__dshTaskReminder.test()
// Play the selected effect at the current volume only
__dshTaskReminder.sound()
Self-check
node test/verify-client.mjs
Runs the browser half under stubbed services (no browser needed) and asserts
the module identity, the wiring, the edge detection, both deduplication
channels, presence-aware silence for the card and the notification, the chime
sounding on every completion regardless of presence, the six settings'
defaults / read / write / restore, the oscillator parameters for every effect
and volume, the card and preview styles, all three notification permission
paths plus the in-page permission-request button, and disposal.
🔧 Troubleshooting
- The settings page is missing. The plugin declares
@deepseek-ai/dsh-client-ui-settings in dsh.client.inject; make sure the
installation completed, then restart dsh web and hard-refresh. If the page
still does not appear, re-run
dsh plugin --profile web add github:hawkongz/dsh-task-reminder.
- Code changes have no effect. The host reads client plugins only at
process start and the browser caches the old bundle. Restart
dsh web,
then hard-refresh (Ctrl + F5).
- No system notification appears. Check
__dshTaskReminder.state():
notificationSupported must be true and notificationPermission must be
granted. If the permission is still default (never answered), the
settings page shows a Request notification permission button under the
System notification row — click it once and choose Allow. If the permission
is denied (you once chose Block), allow notifications for the site in the
browser's address-bar site settings, then click the button again.
- The chime is silent. The volume may be
0, or the browser's autoplay
policy blocked the AudioContext before your first interaction. Interact with
the page once (any click), then it plays.
- A reminder fires while you are watching the conversation. All three
conditions must hold for silence: the main area is the conversation window,
the tab is visible, and the window has focus. If the panel hook is missing
the plugin warns once in the console and treats you as away by design.
📌 Topics
dsh deepseek-harness cordis cordis-plugin web-ui notification reminder web-audio
🤝 Contributing
See CONTRIBUTING.md.
📄 License
Licensed under the MIT License.