When a DeepSeek Harness (DSH) agent transitions into an idle, error, or blocked state, it lacks external feedback. This plugin subscribes to DSH’s built-in agent/status event and pushes notifications to your device when a task is completed, errors, or becomes blocked.

Installation

Install the plugin using a local file path. Installation commands for other profiles follow the same pattern.

dsh plugin --profile web add file:/path/to/dsh-task-notify

If pnpm v11 blocks installation due to the supply-chain policy, append --config.minimum-release-age=0 to the end of the command.

Configuration

Edit ~/.dsh/settings.yaml and add a task-notify: section at the end of the file.

task-notify:
  enabled: true
  notifyOn: [idle, error, blocked]   # 可选事件:idle error blocked goal-completed
  agents: root                        # root=只通知顶层代理 | all
  coalesceWindowMs: 2000              # 同会话窗口内合并重复通知
  desktop:
    enabled: auto                     # auto | on | off
    sound: true                       # macOS 播放 Glass 提示音;Windows 静音开关
  format:
    time: short                       # hidden | short | full
    showDuration: true                # 负载携带 durationMs 时追加「用时 X」
  icons:
    enabled: true                     # 图形图标总开关
    urlTemplate: ""                   # 远程图标模板,如 https://host/icons/{event}.svg
  bark:
    enabled: false
    server: https://api.day.app
    deviceKey: "你的deviceKey"
  ntfy:
    enabled: false
    server: https://ntfy.sh
    topic: "只有你知道的随机topic"
    token: ""
  serverchan:
    enabled: false
    sendKey: ""
  webhook:
    enabled: false
    url: ""
    headers: {}

The configuration priority, from highest to lowest, is: explicit patch configuration > settings.yaml > environment variables > default values.

Features and Channels

This plugin supports multi-platform, multi-channel delivery and provides notification coalescing and deduplication on desktop.

Desktop

  • macOS: Calls osascript to invoke the system Notification Center. Due to system limitations, only plain text + sound is supported, and custom notification icons are not available.
  • Windows: Sends Toast notifications through PowerShell + WinRT and supports embedded PNG icons.

Mobile and Web

  • iOS: Pushes via Bark.
  • Android / iOS: Pushes via ntfy.
  • WeChat: Pushes via ServerChan.
  • Generic: Sends a JSON payload via any Webhook.

Notification Content

The body is uniformly formatted by composeBody as: content summary · time · duration X.
* format.time controls time display: short=HH:mm, full=YYYY-MM-DD HH:mm:ss, hidden=hidden.
* format.showDuration controls whether task duration is displayed.
* The time and duration suffixes are not subject to truncation and are always shown in full.

Icons

  • Titles are always plain text, with no emoji.
  • Icon assets are in assets/icons/ within the package, including SVG vector sources and 64×64 PNGs.
  • Windows: PNGs are embedded using appLogoOverride.
  • Bark / ntfy: After configuring icons.urlTemplate, the icon parameter is appended automatically.
  • Webhook: The JSON payload includes icon and inline iconSvg.
  • macOS: No custom icon; plain text only.

Interactive Configuration

If you do not want to edit YAML manually, run the interactive menu. The menu automatically backs up the original configuration to settings.yaml.bak-<timestamp>.

npm run menu

Self-Test

Send a sample notification to all enabled channels.

node self-test.mjs

# 仅测试桌面通道
node self-test.mjs --channel desktop

Smoke Test

Verify the installation path and event handling in a real environment.

npm run smoke

Notes

  • Node.js version: Node.js ^22.19.0 || >=24 is required.
  • Dependencies: Pure ESM module, with no build step.
  • Runtime permissions: The plugin runs with the permissions of the current dsh process. Review the source code and license before installing.