Skip to content

dsh-popup-notify

Verified

dsh-popup-notify · v0.1.4 · MIT

通过 Windows 原生模态弹窗为 DeepSeek Harness 提醒审批请求、提问与计划审阅、回合结束;零依赖,无预编译二进制。

Install

dsh plugin add dsh-popup-notify

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

dsh-popup-notify

English | 中文

DeepSeek Harness 的桌面弹窗提醒。三种需要你回到窗口的时刻,各弹一个置顶对话框,不点掉就不会消失——不是几秒后自动淡出的 toast。

  • 需要权限 —— 工具请求审批。
  • 需要选择 —— 模型向你提问,或提交计划等你审阅。
  • 任务完成 —— 根 agent 从 running 落到 idle。

零 npm 依赖。没有预编译二进制、没有构建步骤、没有安装脚本:340 行纯 ESM 驱动 PowerShell。仅支持 Windows。

要求 DeepSeek Harness 0.2.1-rc.2 或更新版本。

安装

dsh plugin --profile web add dsh-popup-notify

然后重启,或等 profile 的 patch 层热重载。该 bundle 会插入一行:

- insert:
    - id: popup-notify
      name: 'dsh-popup-notify'

卸载:dsh plugin --profile web remove dsh-popup-notify。

插件页的卡片信息来自这个包导出的资源:./locale/en.json 与 ./locale/zh.json 提供 meta.title 与 meta.description,./icon 提供图标。DSH 通过 Node 的模块解析读取这些路径,不会加载插件代码;所以只导出 . 的 manifest 在插件页上只会显示包名,没有描述,图标也是默认图形。

为什么用模态框而不是 toast

Windows toast 会自己消失,并堆在通知中心里,很容易错过。当一次运行正卡在等你这一步时,一个不点掉就不走的对话框才是这个状态该有的表现。

对话框跑在独立进程,因此从不阻塞 agent 循环。同一时刻只显示一个——后续提醒排队,你关掉当前这个就弹下一个。

配置

在 profile 的 cordis.patch.yml 里覆盖该行的 config。patch 会替换整个 config 值,所以要把想保留的键一起写出来。

- id: popup-notify
  config:
    notifyOnComplete: false
    sound: false

行为开关

键 默认值 含义
notifyOnApproval true 工具请求审批时弹窗。
notifyOnQuestion true ask_user_question 或 exit_plan_mode 执行时弹窗。
notifyOnComplete true 根 agent 结束一次运行时弹窗。
ignoreSubagents true 静音子 agent、workflow worker、AgentTeams 成员。
sound true 弹窗时播放系统提示音。
completeCooldownMs 10000 同一会话两次完成弹窗的最小间隔。
plainDialog false 去掉置顶 owner 窗体。若对话框出现在奇怪位置可启用,代价是可能被其他窗口盖住。
testOnStart false 挂载时弹一次,确认 PowerShell 通路可用。
traceFile '' 每次事件与每次弹窗追加一行诊断。留空关闭。

文案模板

每条文案都是模板,{placeholder} 由事件填入;未知占位符原样保留。

键 默认值
title DeepSeek Harness
approvalMessage 工具 {tool} 需要你的权限确认
approvalReasonSuffix \n\n理由:{reason}
questionMessage 需要你的回答:{question}
questionCountSuffix \n\n(共 {count} 个问题,请在对话里逐个回答)
planReviewMessage 有一份计划等你审阅:批准,或继续规划。
completeMessage Agent 响应已结束,可以查看结果了。
completeReasonSuffix \n\n(结束原因:{reason})
projectSuffix \n\n项目:{project}

{reason} 是轮次结束原因——正常完成时不出现,否则为 aborted、error、max-tokens 等。{project} 是会话工作目录的目录名。把 projectSuffix 设为 '' 可去掉来源行,把 completeReasonSuffix 设为 '' 可不再说明异常结束。

挂载在哪

扩展点 模式 用途
approval/request waterfall 弹窗,然后 next() 交给已配置的 answerer 决策。
tools/pre-execute waterfall 匹配 ask_user_question 与 exit_plan_mode,弹窗,然后 next() 让工具执行。
agent/status emit 根 agent 的 running → idle 边沿弹窗。

DSH 没有提问事件:ctx.userQuestions.ask() 是服务调用,待答问题以 mux 帧发给浏览器,宿主插件看不到。在 tools/pre-execute 匹配两个提问工具,是你回答之前就会触发的可观测点,也正是提醒该响的时刻。

两个 waterfall 都调用 next()。不调用的监听器会短路整条链,审批会被解析成 unavailable,提问工具根本不会执行。

已知限制

  • 仅支持 Windows。 其他平台每条提醒记一条警告后跳过。
  • 不是所有审批都会弹。 审批策略为 never 时,服务在分发 approval/request 之前就返回 rejected,没有任何可观测点。会话审批只在 ask 策略下存在。
  • 对话框不能点进对话。 它只报告状态,回答仍在 DSH 窗口里进行。
  • 只识别两个提问工具。 将来若有同样阻塞等人回答的交互工具,需要把名字加进匹配表。
  • 同一时刻只有一个对话框。 长时间离开会让你面前这个后面排起若干条。
  • plainDialog: true 失去置顶。 无 owner 的 MessageBox 可能出现在其他窗口之后。

开发

npm test                      # 22 项单测,不弹任何窗口
node tests/smoke-dialog.mjs   # 打开并关闭一个真实对话框

单测注入假的 spawnDialog,因此从不接触屏幕。smoke-dialog.mjs 是唯一会打开真实窗口的文件。

许可证

MIT