dsh-attention-notify
DiscoveredDesktop notifications for DeepSeek Harness when a tool approval or a user question is waiting - click to jump back to the terminal
dsh-attention-notify
Desktop notifications from DeepSeek Harness for the two moments that block a turn: tool approvals and user questions.
DeepSeek Harness already notifies task completion in the terminal (OSC 99 on Kitty,
OSC 777 on Ghostty/WezTerm, OSC 9 on iTerm2, BEL elsewhere). Nothing fires when the agent is
waiting on you — which is exactly when you have walked away from the terminal. This plugin
mirrors those two seams to the desktop through notify-send.
┌──────────────────────┐ approval/asked ┌───────────────────┐
│ permission layer │────────────────────▶│ this plugin │
│ user-questions seam │ user-questions/... │ ↓ notify-send │
└──────────────────────┘ └────────┬──────────┘
▼
desktop notification
Install
dsh plugin --profile <profile> add dsh-attention-notify
The bundle patch inserts one loader row; no host config is touched.
Requirements
| Host | Linux with a D-Bus session (Wayland or X11) |
notify-send | from libnotify (or libnotify-bin on Debian/Ubuntu) |
paplay | optional, from pulseaudio-utils; only used when sound: true |
macOS users can point command at terminal-notifier and soundCommand at afplay;
Windows has no notify-send, so this plugin is Linux-targeted on purpose.
What fires
| Session event | Title | Body |
|---|---|---|
approval/asked | 需要你审批 | toolName: reason, one line, truncated |
user-questions/request | 需要你回答 | first question's header/text, (+N) for the rest |
Task completion is deliberately not duplicated: the TUI's own
taskNotifications setting already covers it.
Config
| Key | Default | Meaning |
|---|---|---|
enabled | true | master switch |
approval | true | notify on approval/asked |
question | true | notify on user-questions/request |
approvalTitle | 需要你审批 | title for approvals |
questionTitle | 需要你回答 | title for questions |
command | notify-send | any binary taking -a -u <title> <body> |
appName | dsh | notify-send -a value |
urgency | normal | low / normal / critical |
sound | true | play soundFile after each notification |
soundCommand | paplay | sound player |
soundFile | /usr/share/sounds/freedesktop/stereo/message.oga | sound file; empty disables |
cooldownMs | 1500 | drop repeats of the same title inside this window |
maxBodyChars | 160 | body budget; longer text is cut with … |
clickAction | true | add an action so a click is observable |
actionLabel | 打开窗口 | action button text |
focus | true | raise the blocking terminal when the notification is clicked |
windowsCommand | niri msg windows | window list command for the compositor |
focusCommand | niri msg action focus-window --id {windowId} | focus command template |
focusAppId | kitty | fallback match when the terminal pid is unknown |
focusPid | "" | window owner pid; defaults to $KITTY_PID |
focusTimeoutMs | 2000 | per-command timeout |
Click to jump back
The notification carries a default action. Clicking the body asks the
notification daemon to invoke it, which dismisses the popup and makes
notify-send print the chosen action — that is the signal this plugin waits for
(notify-send -A default=…).
Wayland gives an application no way to raise someone else's window, so the plugin asks the compositor instead. With niri:
niri msg windows # find the window whose PID is $KITTY_PID
niri msg action focus-window --id <id>
Other compositors can be wired through windowsCommand / focusCommand without
touching the plugin — the templates accept {windowId}, {pid} and {appId}.
Set focus: false to keep the click action out entirely.
Design notes
- Approvals are observed on the
session/eventstream (approval/asked), a pure event: the plugin cannot influence the decision. - Questions are a Cordis waterfall (
user-questions/request). The listener therefore always callsnext()— a listener that returns without it vetoes every answerer, including the terminal's, and the question would never be shown. Notifying happens as a side effect inside atry, so a broken notifier still cannot block the prompt. - Delivery is best effort:
spawnis detached andstdio: "ignore", synchronous throws and asynchronousENOENTare both swallowed into the logger. A machine without libnotify degrades to no notifications instead of a failing turn. - The body is flattened to a single line and truncated before it reaches the notification daemon, because some daemons wrap long bodies into multi-screen popups.
Verify
npm test # 17 unit tests, no desktop required
Manual check on the real machine:
node -e '
import("./lib/index.js").then(async ({ install }) => {
const listeners = new Map();
const ctx = { logger: {}, on: (e, h) => (listeners.set(e, h), () => {}), effect: () => () => {} };
install(ctx, {});
listeners.get("session/event")({}, { type: "approval/asked", data: { toolName: "bash", reason: "测试通知" } });
});'
Limitations
- Linux only as shipped. The command is configurable, but the defaults assume
notify-sendand a D-Bus session bus. - No focus detection. The terminal protocol notifiers can stay quiet while the terminal
is focused; a host-side plugin cannot see that state, so this one always notifies.
cooldownMsis the only noise control. - Notifications are raised when the prompt appears, not when it is answered; there is no "still waiting" reminder.
- Click-to-focus is compositor-specific. Only niri is provided and tested. The focus path
raises the window, not the individual kitty tab — a tab switch needs kitty remote
control (
allow_remote_control yes), which is not enabled by default. - A notification that is never clicked leaves one waiting
notify-sendprocess behind until the daemon closes the popup; they exit on click, timeout or dismissal.
License
MIT.
Comments
Loading…
Similar plugins
by pedesdestiny
Browser desktop notifications for DeepSeek Harness (dsh) — get notified when a turn completes or an approval is needed
★ 3
↓ 481/wk
JavaScript
Aug 18, 2026
dsh plugin --profile web add dsh-notifyby CoachLeong
DeepSeek Harness plugin: desktop notifications when the model starts, finishes, or needs your input (approval / question / plan review).
★ 0
MIT
TypeScript
Aug 16, 2026
dsh plugin --profile web add dsh-notifyby FANLS05
Windows desktop toast notifications for DeepSeek Harness (DSH): approval requests, user questions, run completion, errors and sign-in prompts — every toast led by the conversation name.
★ 0
MIT
JavaScript
Oct 2, 2026
dsh plugin --profile web add dsh-desktop-notificationsby Jxxxxx729
DeepSeek Harness 插件:在 Windows 通知栏提示对话完成、等待选择、等待授权或需要登录,点击通知直接跳回对应对话。Toast 以 DeepSeek Harness 应用身份发出。
★ 3
↓ 215/wk
MIT
JavaScript
Oct 22, 2026
dsh plugin --profile web add dsh-win-notifyby weekitmo
Completion and status notifications for DeepSeek Harness: desktop alerts, browser-tab unread counts, and sidebar session indicators, with per-event controls.
★ 0
MIT
TypeScript
Sep 8, 2026
dsh plugin --profile web add dsh-notifyby drydeuterium
Desktop (Windows toast) notifications for DeepSeek Harness — questions, approvals, turn end and errors. Host-side plugin, zero dependencies.
★ 0
MIT
JavaScript
Oct 20, 2026
dsh plugin --profile web add dsh-desktop-notify