System-level desktop notifications: turn-completion and workflow-end banners, plus a modal alert when an approval is needed (macOS osascript / Linux notify-send).
Install
# from GitHub (first run asks for allowBuilds approval — follow the hint, retry)
dsh plugin --profile web add github:zhengjy01/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
English | 中文
DSH server-side plugin: pops operating-system-level notifications to alert you to important events happening in DSH, so you don't need to keep staring at the browser page.
Notification triggers
| Event | Popup type | Default |
|---|---|---|
Main session task reply finished (turn/end completed, non-subagent session) |
System banner "Session name · Task finished" | On |
Main session task failed (turn/end reason=error) |
Modal popup "Session name · Task failed" + sound | On |
Main session task interrupted (turn/end reason=aborted / max-tokens / blocked) |
System banner "Session name · Task interrupted" | On |
Single tool call failed (tools/result isError) |
System banner "Session name · Tool failed" | On |
Goal completed (goal/changed phase=complete) |
System banner "Session name · Goal completed" | On |
Goal blocked (goal/changed phase=blocked) |
Modal popup "Session name · Goal blocked" | On |
Workflow run finished (tool-workflow/run-end) |
System banner "Session name · Workflow finished" | On |
Manual approval needed: tool permission request (approval/asked) |
Modal popup "Session name · Approval needed" + sound | On |
Permission request auto-rejected (policy is never) |
System banner "Session name · Permission request (auto-rejected)" | On (follows the item above) |
Subagent (background subtask) turn ended (turn/end, subagent session) |
System banner "Session name · Subtask finished" | Off |
Notes:
- Titles carry the session name: every popup title uses the corresponding session's name (taken from the session's
session/titleevent), truncated automatically when too long (18 characters + …); when there is no title, it falls back to the first 8 characters of the session ID. - Tool-failure throttling: within the same session, two tool-failure notifications are separated by at least 60 seconds by default (
toolErrorCooldownMs); you can also usetoolErrorAllowlistto only notify for critical tools (e.g.["bash", "ssh_exec"]). - Severity levels: real failures (errors), blocked goals, and manual approval requests → modal popup (must be clicked to dismiss) with a sound; completions, interruptions, auto-rejections, etc. → notification-center banner (non-intrusive).
- macOS: modals use
osascript display alert ... as critical, banners usedisplay notification; Linux: unifiednotify-send, with-u critical(urgent level, stays until clicked) for modal scenarios; other platforms: logs only. - When the approval policy is
ask, an approval request pops a modal dialog reminding you to approve it in the DSH UI; when the policy isnever, requests are auto-rejected and only a banner tells you it was auto-rejected, without popping a modal to disturb you. - Popups run detached from the process and do not block the DSH server.
Installation
Standard DSH plugin package installation (any one of the following); after installing, restart dsh web for it to take effect:
# Local development (link mode, pointing at this repository path)
dsh plugin --profile web add link:/Users/zhengjunyao/Documents/DSH-test/dsh-notify
# After publishing to GitHub (the repository must have the dsh-plugin topic)
dsh plugin --profile web add github:<your-account>/dsh-notify
Alternative: the repository ships with scripts/install.mjs (copies the package to ~/.dsh/profiles/node_modules/dsh-notify), but the standard method above is recommended.
Configuration
The plugin's cordis.patch.yml provides default configuration; after installing, you can override it at the profile's patch layer (e.g. ~/.dsh/profiles/web/cordis.patch.yml):
- patch:
- id: notify
config:
notifyTurnEnd: true # main session task finished banner
notifyTurnError: true # main session task failed: error→modal popup, aborted/over-limit/blocked→banner
notifySubagentEnd: false # subtask finished banner (off by default to avoid noise)
notifyWorkflowEnd: true # workflow finished banner
notifyApproval: true # approval-needed popup / auto-rejected banner
notifyToolError: true # single tool call failed banner (per-session cooldown + optional allowlist against noise)
toolErrorAllowlist: [] # only notify for these tool names, empty = all (e.g. ["bash", "ssh_exec"])
toolErrorCooldownMs: 60000 # minimum interval between two tool-failure notifications in the same session (ms)
notifyGoalComplete: true # goal completed banner
notifyGoalBlocked: true # goal blocked modal popup
sound: true # play a sound on popup
After changing the configuration, restart dsh web as well.
Manual verification
You can verify that popups work without restarting:
osascript -e 'display notification "测试" with title "DSH" sound name "Glass"'
osascript -e 'display alert "DSH" message "测试" as critical'
Publishing to the community
- Push this repository to your GitHub (remember to change the
repository.urlinpackage.jsonto the actual address). - Add the
dsh-plugintopic in the repository settings → Topics, so DSH users around the world can find it and install it with one command. - (Optional) Register it in community marketplaces/lists, e.g. dsh-market, awesome-dsh-plugin.
- (Optional) The official plugin scaffolding is still under discussion; you can leave feedback at deepseek-ai/deepseek-harness Discussion #1629 to help push forward an official publishing channel.
Links
More in this category
xmanrui/dsh-im★ 1525
Connect IM bots to DeepSeek Harness via QR codes or bot credentials (9 channels: Feishu, WeChat, DingTalk, WeCom, QQ, Slack, Telegram, Discord, and WhatsApp).
shaobeichen/dsh-pocket★ 1396
Remote phone access to the DSH Web UI: scan a QR code for LAN or public (cloudflared tunnel) access with real-time sync, a mobile-adaptive layout, and a settings tab.
inclusionAI/Avernet#deepseek-harness-channel-bcn★ 572
Connects DeepSeek Harness to Avernet's Bot Collaboration Network over WebSocket V2, with automatic onboarding, isolated agent sessions, tool-call events, and multi-bot routing tools.
omdsh-dev/dsh-notification★ 85
Desktop notifications for turn completions, with per-outcome controls and keyword rules.
whyihaveyou/dsh-suite#plugin-notify★ 57
IM webhook and local notifications on turn completion, errors, or approval (Feishu/WeCom/DingTalk/Slack/Discord/custom).
omdsh-dev/dsh-lark★ 55
Lark/Feishu bot channel for DeepSeek Harness: each chat drives its own agent, and tool approvals, model questions, and plan reviews return as cards answered by a button or a reply. Switch workspace and model from the chat (`/cd`, `/model`, `/new`), and run several bots that keep separate sessions and can hand turns to each other in one group.
Community comments
Comments are public GitHub Discussions. Loading them connects to GitHub and Giscus; a GitHub account is required to post.