DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
R

dsh-remind

Remind

Reminds you with a Windows native notification (with sound) when a task is complete or DSH needs your approval or response—only interrupting you when DSH is not in the foreground.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add github:JHyugou/dsh-remind#a609cba71228919a9b27e4b8fe446810a8225577
READMECompatibilityVersions

Compatibility and provenance

Remind is published as dsh-remind and currently resolves to version 0.2.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
any
Release source
github
Registry updated
10/19/2026

Versions

0.2.0stable
10/19/2026

Related plugins

Loading related plugins…

Latest
0.2.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
any
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
10/19/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in integrations-communication.

Dafeiyudsh-dafeiyuA desktop-native BigFish companion driven by DeepSeek Harness session events.Im Connect@michengai/dsh-im-connectDSH IM Connect — 将主流即时通讯平台接入本机 DeepSeek Harness · Connect major messaging platforms to local DeepSeek Harness agentsAcp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseDouyin Browser Localdsh-douyin-browser-localDSH native Douyin tools and standalone DeepSeek local assistant

README

dsh-remind

任务做完了 / DSH 需要你批准或回答,但你在看别的窗口 —— 用 Windows 原生通知(带提示音)提醒你。

DSH 的会话跑完不会主动告诉你,切出去以后只能靠回来瞄一眼;DSH 等你批准或回答时更是干等着。这个插件把「这一轮真的做完了」和「DSH 需要你处理」都变成一条 Windows 通知,而且只在你不在看 DSH 的时候才打扰。


它做什么

能力说明
完成任务提醒顶层会话的 agent 从 running 落回 idle(这一轮真的结束);后台任务(jobs)落地时也会补一条
审批提醒DSH 请求批准时提醒。只有真的在等你决定才提醒:先等 800ms 确认窗口,期间被自动批准/拒绝/自动审批器决定掉就不打扰
提问提醒DSH 调用 ask_user_question 向你提问时提醒,通知里带问题原文(多个问题显示第一条 + 数量)
提示音三类通知都可配提示音(default / reminder / alarm / im / mail / sms / call … 或 none 静音);默认任务完成用 default,审批/提问用更醒目的 reminder
只在该提醒时提醒用 Win32 GetForegroundWindow 读当前前台窗口的标题与进程名,命中 focusMarkers(默认 DeepSeek Harness)就认为你正在看 DSH,不弹通知(审批/提问可单独配置)
通知形态Windows 原生 Toast(进操作中心、可关闭、可点击)
通知内容任务完成:DSH · 任务完成 + 会话标题 · 工作区 · 用时;审批:DSH · 需要批准 + 工具名 · 会话;提问:DSH · 需要你的回答 + 问题文本 · 会话

防误报设计

一轮「结束」到真正「没事干了」之间可能还有后续动作,所以判定做了四层:

  1. 只认顶层会话:ctx.agents.roots() 排除子代理——子代理结束时父轮还在跑,不该打扰。
  2. 静默期复查(默认 700ms):复查时仍须满足「agent 仍是 idle、inbox 没有排队的 nextTurn/nextStep、该会话没有 running|stopping 的 job、workspace/session-activity 里没有 turn/job/subagent」。任何一条不满足就放弃这次提醒。
  3. 同会话冷却(默认 5s):避免 turn 结束与 job 落地撞在一起弹两条。
  4. 宽限期(默认 1500ms):弹通知前先等 1.5 秒,你刚切回 DSH 就不打扰。

审批 / 提问提醒怎么判断「真的在等你」

  • 审批:订阅 approval/asked / approval/decided 审计对。注意 approval/asked 对每一次审批都会追加,包括策略为 never(直接拒绝)或自动审批器立即决定的情况——所以不是「一见到 asked 就弹」,而是先静默 attentionSettleMs(默认 800ms):期间收到同 id 的 approval/decided 就当作没发生。
  • 提问:订阅 tool/call,且工具名是 ask_user_question。解析其参数 JSON 取问题文本;同样先静默 800ms,期间收到同 callId 的 tool/result(你已经答完或工具已返回)就取消。
  • 子代理里发出的审批/提问会沿 session.header.parentSession 上溯,展示到顶层会话的标题上;turn/end 或会话销毁时清掉该会话所有待发提醒。

架构与关键取舍

src/index.js            宿主端 cordis 插件:订阅事件、注册 /api/dsh-remind.* 路由、拼通知
src/detect.js           「任务完成」判定(纯逻辑,可脱离 DSH 单测)
src/attention.js        「审批 / 提问」判定(确认窗口、去重、子代理上溯)
src/notify.js           Windows 通知层:调助手脚本、提示音归一化、解析结果
scripts/dsh-remind.ps1  单次 PowerShell 助手:宽限 → 前台判定 → WinRT Toast + 提示音(一次进程完成)
src/config.js           配置读写(原子写、BOM 容错、非法值夹紧)
src/contract.js         对 DSH 宿主接口的全部假设清单(升级体检用)
test/                   单测 + 真实通知实测
tools/                  侦察与验证工具(读 app.asar、带鉴权调路由、真实宿主端到端、doctor)

为什么是 PowerShell,而不是 Electron 的 Notification? DSH 桌面端把宿主跑在独立的 Node 进程里(@deepseek-ai/dsh-desktop-host),插件拿不到 Electron API;DSH 自身也没有对插件开放的 OS 级通知接口(整个壳里只有更新提示那一处 Notification)。所以走系统自带能力:Windows PowerShell 5.1 的 WinRT Toast API。整轮(含前台判定)实测约 300ms,任务完成这种低频事件完全够用。

为什么不用 koffi FFI 直接调 user32? koffi 的原生 .node 在 DSH 安装目录里有两套(3.1.1 / 3.3.2,互不兼容),且只能按绝对路径加载;插件里引它会把「DSH 升级 / 换机器」变成故障源。PowerShell 是每台 Windows 都有的稳定面。

前台判定为什么看窗口标题而不是页面可见性? GUI 可能在 Electron 窗口里,也可能在浏览器标签页里(比如 Edge 打开 http://127.0.0.1:19387)。两种情况的活动窗口标题都来自页面 <title>DeepSeek Harness</title>,所以标题匹配同时覆盖两种形态;浏览器里切到别的标签页时,窗口标题变成那个标签页的标题,于是正确判定为「不在看 DSH」。


安装

本机已安装并已生效(desktop profile):

dsh plugin --profile desktop add <克隆下来的仓库目录>

这一步会:把包以 link: 形式加进 %USERPROFILE%\.dsh\profiles\desktop\package.json 的 dependencies,并把 dsh-remind 追加到 dsh.profile.bundles。插件的 cordis.patch.yml 负责把自己挂进 profile 组合树:

- insert:
    - id: dsh-remind
      name: dsh-remind

卸载:dsh plugin --profile desktop remove dsh-remind,或在 GUI 的 Plugins 页里移除。

改完插件源码要重启 DSH 才生效:插件以 link: 方式安装,profile 热重载会重新执行 apply(),但 Node 的 ESM 模块缓存不会失效——已加载过的模块仍是旧代码。实测:改动 src/ 后触发 profile 重载,日志里出现的仍是旧版 ready 行;重启桌面端后才是新代码。纯配置改动(config.json 或 setConfig 路由)不受影响。


配置

配置文件:%USERPROFILE%\.dsh\plugins\dsh-remind\config.json(改完重启 DSH 生效;也可以用下面的 setConfig 路由热改)。

字段默认含义
enabledtrue总开关
onlyWhenUnfocusedtrue只在「前台不是 DSH」时提醒;false = 每次都提醒
focusMarkers["DeepSeek Harness"]命中即视为「正在看 DSH」的窗口标题/进程名片段(子串匹配)
graceMs1500弹通知前的宽限期:你马上切回来就不打扰
settleMs700判定「真的做完了」前的静默期
minRunMs0短于此时长的任务不提醒(0 = 不限制)
cooldownMs5000同一会话两次提醒的最小间隔
notifyOnJobtrue后台任务全部落地时也提醒
titleDSH · 任务完成通知标题
bodyTemplate{{session}} · {{workspace}} · 用时 {{duration}}正文模板,支持 {{session}} {{workspace}} {{duration}} {{cause}};空片段连同分隔符自动省略
sounddefault任务完成通知的提示音:default / im / mail / reminder / sms / alarm / alarm2…alarm10 / call / call2…call10 / loop / none
notifyOnApprovaltrueDSH 请求批准时提醒
notifyOnQuestiontrueDSH 向你提问时提醒
attentionOnlyWhenUnfocusedtrue审批/提问是否也遵守前台判定(false = 正在看 DSH 也弹)
attentionGraceMs300审批/提问通知的宽限期(比任务完成更短)
attentionSettleMs

自检与排查

1) 立刻弹一条测试通知 —— 在 DSH 页面(浏览器/桌面窗口均可)按 F12 打开控制台执行:

// 任务完成样式
fetch('/api/dsh-remind.test', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })
  .then(r => r.json()).then(console.log)
// 审批 / 提问样式(带 reminder 提示音)
fetch('/api/dsh-remind.test', { method: 'POST', headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ kind: 'approval' }) }).then(r => r.json()).then(console.log)
fetch('/api/dsh-remind.test', { method: 'POST', headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ kind: 'question', sound: 'alarm' }) }).then(r => r.json()).then(console.log)

2) 看当前状态、前台判定与最近判定:

fetch('/api/dsh-remind.status', { method: 'POST', headers: { 'content-type': 'application/json' }, body: '{}' })
  .then(r => r.json()).then(x => console.log(x.result))

返回里的 foreground 就是「现在算不算在看 DSH」的判定依据(窗口标题、进程名、是否命中);recent 是最近若干次任务完成判定(notified / focused / queued-work / jobs-running / session-active / cooldown …);attention.recent 是审批/提问判定,attention.pending 是还在确认窗口里的条数。

3) 热改配置(不重启):

fetch('/api/dsh-remind.setConfig', { method: 'POST', headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ onlyWhenUnfocused: false, debug: true }) }).then(r => r.json()).then(console.log)

4) 判定轨迹:debug: true 时,%USERPROFILE%\.dsh\plugins\dsh-remind\events.jsonl 会记录加载与每次判定。

5) 命令行测试:

node --test                                        # 单测(判定逻辑、配置、路由装配)
$env:DSH_REMIND_E2E='1'; node --test test/notify.test.mjs   # 真实弹一条 Windows 通知

验证记录(本机实测)

项目结果
前台窗口探测✅ 正确读出前台窗口标题与进程名,耗时 ~250ms
原生 Toast(中文 + emoji)✅ 弹出并进入操作中心历史(History.GetHistory 可查)
提示音✅ Toast XML 带 <audio src="ms-winsoundevent:Notification.Reminder" loop="false"/>,实测可闻
通知层实测✅ node --test 全部通过(含前台命中时正确跳过、提示音参数)
真实宿主加载✅ desktop(DSH 0.2.1-rc.2)宿主启动即加载,events.jsonl 记录 ready: … approval=true question=true sound=default/reminder
真实任务端到端✅ 临时 profile 跑一轮真实任务:status running → status idle → notified,并真实弹出通知
真实提问端到端✅ 临时 web profile 里让 agent 真的调用 ask_user_question → 插件 attention.recent 记录 kind=question, action=notify,通知里带问题原文与 reminder 提示音
审批/提问通知样式✅ /api/dsh-remind.test 的 `kind=approval
插件路由✅ /api/dsh-remind.{status,config,setConfig,probe,test} 在真实宿主里可用(信封与裸 JSON 两种请求体都支持)
升级稳定性✅ 零依赖 + 零 peerDependencies,不会被 DSH 的版本兼容校验拦下(evaluatePluginCompatibility 无 peer 直接放行);bundle 解析失败只会「跳过 + stderr 一行」,不会导致 profile 启动失败
契约体检✅ node tools/doctor.mjs 五层全 PASS:20 条公开契约对着新版本 DSH 自带 API 目录逐条核对通过,另有 2 条实现核对(审批/提问事件名、提问工具名)通过

DSH 升级后的稳定性

结论:升级不会把插件卸载或禁用,真正的风险是宿主接口漂移;后者已用「契约清单 + 体检脚本」兜住。

升级不会动它(已核对 DSH 自身源码)

事实依据
插件代码在本地克隆目录里,不在 DSH 程序目录里;升级只替换程序目录桌面端更新走 app-update.yml 的 generic 源,替换安装目录;DSH home 与 profile 属用户数据
升级后 DSH 会重启宿主,插件从源码重新加载(等于一次干净的重载)壳里的更新流程装完即重启
零 npm 依赖、零 peerDependencies → 永远不会被「版本不兼容」拦下dsh-app-boot 的 evaluatePluginCompatibility() 第一句就是 if (!Object.hasOwn(fields, "peerDependencies")) return undefined,没有 peer 直接放行(对比:dsh-plugin-subscriptions 就因为有 peer 范围而被判不兼容、启动时拒绝激活)
bundle 解析只看「profile 的 node_modules 里能不能找到」resolveBundleDir() 依次从安装锚点与 profile 目录解析,与版本无关
最坏情况是「被跳过」而不是「启动失败」loadProfileDirectory() 对每个 bundle 逐个 try/catch:解析失败/缺 dsh.bundle/peer 不兼容 → 该 bundle 进 skippedBundles,profile 照常启动,stderr 打一行 dsh: skipping profile bundle "dsh-remind": …

真正的风险:宿主接口漂移

插件的每条假设都写在 src/contract.js 里,分三类:

  • 20 条公开契约(DSH 自己的 API 目录 dsh-tool-cordis/lib/types/api-catalog.js 里有声明):agent/status 事件、AgentStatus 取值、agents.roots()/get()、jobs.list()/events.subscribe()、sessions.get()、SessionHeader.cwd / parentSession、sessionTitle.get()、sessionProjections.stateOf()、workspace/session-activity 瀑布、approval/request 瀑布、session/event 与 tool/call 事件、connection.fetch.register() 等。
  • 3 条运行时形状(目录里没声明,属于 Agent 对象的内部字段):agent.status、agent.inbox.nextTurn/nextStep、agent.session。这三条是最大变数。
  • 2 条实现核对(API 目录里没声明、但插件依赖的实现细节):审批审计事件名(approval/asked / approval/decided)、提问工具名(ask_user_question)。doctor 直接读新版本 DSH 的实现文件确认关键字串还在。

关键假设失效时的降级路径:

假设失效后果(降级,而不是崩溃)
agent.status 没了静默期复查放宽 → 可能多提醒一次
agent.inbox 没了当作「没有排队工作」 → 宁可多提醒,不漏
agent.session 没了通知正文退化成「会话已完成」
sessionTitle / cwd 没了正文里对应片段自动省略
connection.fetch.register 没了只是没有自检路由,核心通知照常
审批事件名 / 提问工具名变了只是审批或提问提醒失效,任务完成提醒照常
agent/status 事件本身改名/改语义任务完成提醒会「静默失效」 → 由下面的体检负责第一时间发现

另外,workspace/session-activity 的判断刻意用否定表:只有已知不算干活的 schedule(已排期提醒)被忽略,其余任何种类都当作「还有活在跑」。所以新版本引入新活动种类时,插件会保守地少打扰,而不会把新种类的活误判成「已完成」。

升级后跑一次体检

node tools/doctor.mjs          # 五层体检,10 秒出结论
node tools/doctor.mjs --toast  # 顺带真弹一条通知
  • L1 包完整性:入口能 import、dsh.bundle.patch 与助手脚本齐全、powershell 就位
  • L2 profile 注册:依赖与 dsh.profile.bundles 条目、node_modules/dsh-remind 链接都在
  • L3 宿主契约:直接读新版本 DSH 自带的 API 目录,逐条核对上面 20 条公开契约;再读 DSH 的审批/提问实现文件核对 2 条实现细节 —— 哪条没了就点名哪条,并说明后果
  • L4 通知通道:真调一次 Windows 助手(前台探测;--toast 才弹)
  • L5 运行痕迹:读 events.jsonl 最近一次加载与判定;给了 --url <带令牌地址> 还能问运行中的宿主要 health

退出码 0 = 可用。运行期同一份清单也在生效:插件加载时逐项探测,缺失项会写进宿主日志,并出现在 /api/dsh-remind.status 的 health 字段里。

万一 L3 报某条契约失效

插件是本地 link: 的,改完源码重启 DSH 即生效:按 contract.js 里那条的 why 定位受影响代码 → 适配新接口 → node --test → node tools/doctor.mjs 复验。若 L1/L2 报缺失(例如 profile 被重建),一条命令装回来:

dsh plugin --profile desktop add <克隆下来的仓库目录>

已知边界

  • 通知卡片的“应用名”显示为 Windows PowerShell:Windows 要求 Toast 必须带一个已注册的 AUMID,而 DSH 桌面端从未调用 setAppUserModelId(壳里零命中),com.deepseek.dsh 只写在 package.json 里、运行时没用到。所以默认借用系统 PowerShell 的注册 AUMID。想显示成 “DeepSeek Harness”,需要给开始菜单快捷方式注册一个 AUMID(后续可做)。
  • 审批提醒只在「真的在等你决定」时出现:审批策略为 never(当前会话常见)或自动审批器瞬间决定时,approval/asked 之后同一刻就会 approval/decided,确认窗口会把它过滤掉——这是刻意的,避免为不需要你操作的审批弹窗。只有当审批真的挂起等待 UI 应答时才会提醒。
  • 提问提醒只认 ask_user_question 工具:这是 DSH 的标准提问工具;如果某个 profile 不加载它(例如 headless 模板的极简工具集),自然也不会有提问提醒。
  • 专注助手/勿扰模式会照常拦截 Toast(系统行为,插件无法绕过)。
  • 前台判定基于窗口标题/进程名子串。若你把 GUI 套在标题不含 DeepSeek Harness 的外壳里,请把该标题加进 focusMarkers。
  • openOnClick 默认关闭:开启后点击通知会用默认浏览器打开带令牌的地址(等于新开一个已登录的 DSH 页面,而不是聚焦已有窗口)。
  • 一轮结束后若宿主进程在静默期内直接退出(如 dsh headless "..." 一次跑完即退),判定来不及执行——短命进程的固有限制;桌面端宿主长期驻留,不受影响。

开发工具(tools/)

工具用途
doctor.mjs升级后体检:五层核对(包完整性 / profile 注册 / 新版本 API 目录契约核对 / 通知通道 / 运行痕迹)
asar.mjs不装 Electron 也能列/读/解 app.asar(list / read / extract;也可当模块 import)
api.mjs带启动令牌换 cookie 后调插件路由(Windows 命令行会吃掉裸 JSON 的引号,复杂请求体用 @文件)
e2e-turn.mjs在真实宿主里建会话、发提示、轮询「任务完成」判定
e2e-attention.mjs在真实宿主里让 agent 调用 ask_user_question,轮询「提问提醒」判定(兼容新旧两种 RPC 信封)
live-reload-check.mjs临时摘除/加回 bundle 以触发 profile 热重载(用于确认插件是否已在运行中的宿主里生效)
verify-toast.ps1查某个 AUMID 的操作中心历史,确认 Toast 真的被系统接受
800
审批/提问的确认窗口:期间被决定/回答就不打扰
approvalTitleDSH · 需要批准审批提醒标题
approvalBodyTemplate{{tool}} · {{session}}审批正文模板,支持 {{tool}} {{reason}} {{session}} {{workspace}}
questionTitleDSH · 需要你的回答提问提醒标题
questionBodyTemplate{{question}} · {{session}}提问正文模板,支持 {{question}} {{session}} {{workspace}}
attentionSoundreminder审批/提问提醒的提示音
openOnClickfalse开启后通知可点击,用默认浏览器打开带令牌的 DSH 地址
actionLabel打开 DSH可点击时的按钮文案
aumid""Toast 的 AUMID;留空用系统 PowerShell 已注册的那个
debugfalse把每次判定写进 events.jsonl,排查「为什么没提醒」时打开