前言¶
用 DeepSeek Harness(DSH)跑长任务时,终端里往往已有「任务完成」一类提示:Kitty 走 OSC 99,Ghostty / WezTerm 走 OSC 777,iTerm2 走 OSC 9,其它环境则多为 BEL。这些信号针对的是回合结束,而不是「智能体停在你面前等你」的那两个节点——工具审批和用户提问。你离开终端去忙别的事时,恰恰最需要被叫回来。dsh-attention-notify 是社区维护的 DSH 客户端插件,把上述两种阻塞场景接到 Linux 桌面的 notify-send,并可选择点击通知后把终端窗口拉回前台。
这是什么¶
插件全名 dsh-attention-notify,由 PandaAQI 维护,在 DSH 插件目录中归类为客户端。版本 0.1.0,许可证 MIT,要求 Node.js >= 20,DSH 引擎 >= 0.1.1-rc.1。它监听权限层与用户提问流上的事件,在需要审批或回答时弹出桌面通知;不重复终端已有的任务完成通知(由 TUI 的 taskNotifications 负责)。
工作原理简述¶
审批走 session/event 上的纯事件 approval/asked;用户提问走 Cordis 瀑布 user-questions/request,监听器在通知之外仍必须调用 next(),避免挡掉终端自带的提问 UI。通知通过可配置的 command(默认 notify-send)异步拉起,失败只记日志,不拖垮当前回合。
┌──────────────────────┐ approval/asked ┌───────────────────┐
│ permission layer │────────────────────▶│ this plugin │
│ user-questions seam │ user-questions/... │ ↓ notify-send │
└──────────────────────┘ └────────┬──────────┘
▼
desktop notification
会触发哪些通知¶
| Session 事件 | 标题(默认) | 正文 |
|---|---|---|
approval/asked |
需要你审批 | toolName: reason,单行截断 |
user-questions/request |
需要你回答 | 第一道题的 header/text,其余以 (+N) 表示 |
环境与依赖¶
| 项目 | 说明 |
|---|---|
| 主机 | 带 D-Bus 会话的 Linux(Wayland 或 X11) |
notify-send |
来自 libnotify(Debian/Ubuntu 上常为 libnotify-bin) |
paplay |
可选,来自 pulseaudio-utils;仅当 sound: true 时使用 |
默认实现面向 Linux。macOS 可将 command 改为 terminal-notifier、soundCommand 改为 afplay;Windows 无 notify-send,上游明确以 Linux 为设计目标。
安装与启用¶
在目标 profile 下执行官方安装命令。bundle 补丁只增加一行 loader,不改动宿主配置。
dsh plugin --profile <profile> add dsh-attention-notify
安装前建议浏览 GitHub 仓库 源码与 MIT 许可证。插件与当前 dsh 进程同权限运行,只应装你信任的包。
配置项¶
下列键可在插件配置中调整(缺省见第二列):
| 键 | 默认 | 含义 |
|---|---|---|
enabled |
true |
总开关 |
approval |
true |
是否在 approval/asked 时通知 |
question |
true |
是否在 user-questions/request 时通知 |
approvalTitle |
需要你审批 |
审批通知标题 |
questionTitle |
需要你回答 |
提问通知标题 |
command |
notify-send |
接受 -a -u <title> <body> 的可执行文件 |
appName |
dsh |
传给 notify-send -a |
urgency |
normal |
low / normal / critical |
sound |
true |
通知后是否播放 soundFile |
soundCommand |
paplay |
播放器 |
soundFile |
/usr/share/sounds/freedesktop/stereo/message.oga |
留空则不发声 |
cooldownMs |
1500 |
同一标题在此时长内去重 |
maxBodyChars |
160 |
正文上限,超出以 … 截断 |
clickAction |
true |
是否注册可点击动作 |
actionLabel |
打开窗口 |
动作按钮文案 |
focus |
true |
点击后是否尝试聚焦阻塞中的终端 |
windowsCommand |
niri msg windows |
列窗命令(合成器相关) |
focusCommand |
niri msg action focus-window --id {windowId} |
聚焦命令模板 |
focusAppId |
kitty |
未知 pid 时的后备匹配 |
focusPid |
"" |
窗口属主 pid,默认 $KITTY_PID |
focusTimeoutMs |
2000 |
单次命令超时 |
不想处理点击聚焦时,可将 focus 设为 false。
点击通知回到终端¶
通知带 default 动作。点击正文时守护进程会回调,notify-send -A default=… 的输出即插件所等待的信号。Wayland 下应用无法直接抬高他人窗口,因此默认通过 niri 查询并聚焦:
niri msg windows
niri msg action focus-window --id <id>
其它合成器可通过 windowsCommand / focusCommand 模板接入,占位符支持 {windowId}、{pid}、{appId}。聚焦的是窗口而非 Kitty 单个标签页;跨标签需 Kitty 远程控制(默认未开)。
本地验证¶
单元测试不依赖桌面环境:
npm test
在真实机器上可用手工片段模拟审批事件(README 中的 node -e 示例),确认弹窗与文案是否符合配置。
适用场景与限制¶
适合在 Linux 上长时间挂 DSH、又不想盯着终端等审批或问答的开发者。需要注意:
- 仅 Linux 为开箱路径;
command可改,但默认假定 D-Bus 与notify-send。 - 无法感知终端是否在前台;与部分终端内置「聚焦时不响」不同,本插件仍会通知,主要靠
cooldownMs降噪。 - 通知在提问出现时触发,没有「仍在等待」的周期性提醒。
- 点击聚焦与合成器绑定;上游仅提供并测试 niri 路径。
- 未点击的通知可能让
notify-send进程挂到弹窗关闭为止。
任务完成类提示请继续用 TUI 自带能力,本插件刻意不重复。
结尾¶
dsh-attention-notify 补上 DSH 在「等你审批、等你回答」时的桌面侧提醒,并可选点击回到 Kitty 等终端窗口。目录页:SkillHub - dsh-attention-notify;源码与文档:GitHub - PandaAQI/dsh-attention-notify。DSH 生态强调「一切皆插件」,SkillHub 为社区目录,与 DeepSeek / 幻方无官方从属关系;装插件前自行核对源码与许可证即可。