Repository navigation
Releases: hawkongz/dsh-task-reminder
Release list
v1.6.5
文档
纯文档版本:把修正后的 README 推到 npm(registry 不能事后改已发布版本的 README,
只有发新版才会更新包页与包内文件)。代码无改动,只有版本号跟着走。
- 修正桌面端安装说明:旧文档让读者把
--profile web换成--profile desktop再跑
dsh plugin,但桌面端 profile 由应用独占管理,命令行一律被拒
(profile "desktop" is managed exclusively by the Electron application)。现在改成
应用内安装:侧栏 插件 → 添加插件,把包名填进「包名或地址」,点 安装,
装完彻底退出并重开应用;附两张界面截图(docs/images/desktop-add-plugin.png、
docs/images/desktop-plugin-market.png)。webprofile 的命令行安装保持不变。 - 常见问题补一条该报错的解释;「设置页不见了」「卸载」补桌面端分支。
- 页首徽章行加 Awesome DSH Plugin 徽章(本插件已收录于
awesome-dsh-plugin.com)
与 powered by dsh 徽章;「开发与相关文档」补一行收录说明。 - 删掉解释性噪音:不再在安装段解释 profile 归属机制,只留做法。
v1.6.4
修复
- 不再把"日志还没落盘"误报成完成:停止分类改成三态——拿到本次回合
turn/end
(closed)、只看到比它更新的turn/start说明本次结束还没落盘(unclosed)、完全读不到
(unreadable)。unclosed 会等会话事件流把turn/end送上来;到截止仍等不到就不弹窗、
不响提示音(只记stats.suppressedUnclosed),不再猜成完成。只有 unreadable 才走
完成兜底。 - 兜底之后迟到的分类会纠正:unreadable 先按完成报之后,迟到的
error仍会替换成
错误通知(原有);迟到的aborted/blocked/interrupted现在会撤掉那条兜底
完成通知、不补错误(1.6.4 起),不再留一条"其实已经被取消"的完成弹窗。 - 修「上一轮刚停、新回合马上开始」时的新回合双弹:分类三态、在途守卫与回合号判据的
交接重新对齐,同一个停止不会在慢路径与事件重放之间各报一次。 - 修当前 DSH 上一键升级必然失败:当前宿主(0.2.1+)在 HMR 存在时对已安装的包拒绝普通
installBundle(already-installed),官方升级路径是 remove+install。插件现在先 install,
遇 already-installed 自动走removeBundle → installBundle;两步都失败时会尝试装回当前
版本,尽量不让 profile 停在"删了没装回"的状态。 - 修自定义音效「清除」失败时假装成功:IndexedDB 删除失败会如实提示,不再出现"设置页
显示已清除、下次启动文件又回来"。 - 修同一毫秒内两条通知互相替换:通知 tag 加了单调序号。同一毫秒里连发的两条不再共用
tag,避免 Windows 上后一条替换前一条、而被替换的那条点不动(electron#29461)。 - 同类型多条通知都保住点击:页面级保活表以前按类型只留最近一条,同类型第二条到达后
第一条失去强引用、点击送不到页面。现在按对象身份逐条保活(上限 20 条),点击 / 关闭 /
等待消散时按身份释放;卸载时还会按 tag 收掉带按钮的审批通知。 - 修通知权限提示与真实状态脱节:文案不再假设"已经发过申请",只说明尚未授权、点按钮申请。
- 清理等待类 / 审批通知的残留:插件热重载、等待消散、会话消失时,页面级保活表与通知
中心里的陈旧条目收得更干净。
变更
- 停止边沿快路径(0-RPC):会话正被 DSH retain(用户正在看)时,直接同步读事件窗口,
弹窗与提示音在停止边沿的同一个同步段里发出,不再先等一次 RPC。 - 未 retain 时改为事件驱动:一次
sessions.using拿到绑定后订阅会话事件流等turn/end
落盘,去掉原来 3×120 ms、最多 4 次 RPC 的轮询重试。 - 卸载回收加固:热重载 / 停用后,在途分类、等待落盘的订阅、兜底定时器都不会再往已经
卸载的实例上弹窗、放音。 - 宿主定时器与 helper 清理:唤醒补发的定时器与 PowerShell helper 子进程在卸载时统一
收掉,不再留孤儿进程 / 定时器。 - 检查更新增加总超时与响应体大小上限:某个源挂住、或回了异常大的页面时,整次检查有
界,失败如实写原因;升级结果无论记成restart-required还是applied,设置页文案都
不变(仍是「重启 DSH 后生效」)。 - 新排障计数:
stats.suppressedUnclosed(判断为 unclosed、等到上限仍静音的停止数)、
stats.lateCorrections(兜底之后被迟到分类纠正的次数)。 - 提示音生命周期加固:卸载后
chime置 closed,迟到的解码 / 播放路径不再新建
AudioContext、不再排音;用户手势预热只 resume 一次(旧实现两次);touchend也算手势。 - 设置页与更新状态机的小修:更新请求有总超时(15 s)与「200 但非 JSON」的可读兜底、
在途重复点击不再发第二个请求;自定义音效写盘与解码试听并行(解码成功即可先试听,写盘
失败保留旧文件继续用);清除失败保留原文件继续播放、只如实提示;音量按 5 的步进对齐;
点「通知语言」里已选中的档不再把 auto 静默钉住。 - 代码收敛:按钮样式抽公共基座、设置页订阅抽
useStore、权限申请抽
requestNotifyPermission、更新动作抽runUpdateAction、switchRow支持可选说明;
删除无读者的NOTIFY_KIND_ERROR诊断出口、客户端UPDATE_IDLE.registry、音效表里的
id与customMeta的死分支。三套自检共 673 条断言(契约 20 + 浏览器半侧 551 +
宿主半侧 102)。
文档
docs/how-it-works.md:第 3 节重写分类三态 / 快路径 / 迟到纠正,第 8 节补提示音与
分类的关系,第 11 节补两步升级与 already-installed,第 12 节更新「有意保守」的说法。- 修正一处文档错误:「本地开发安装」「没有插件管理服务」两态的按钮实际会退化为「检查
更新」(只再查一次),不是「无按钮」。 - README(中英)只同步「检查更新与一键升级」与「一次停止只提醒一次」的新语义,不改编排。
v1.6.3 — README 用户向重写(中英双页、真实弹窗配图、CHANGELOG)
这次发版只改文档,功能代码零改动(index.js 未动,client.js 只改版本号)——已经装着 1.6.2 的可以不用升级,除非想要包内的最新文档。
文档
- README 重写为面向用户的中文版,原英文 README 移为
README.en.md,删除重复的zh-CN/README.md:首屏直接回答「这是什么 / 怎么装 / 装上会看到什么」,功能覆盖补全,术语不再出现在用户文档里 - 配图换成真实弹窗截图(
docs/images/,中英各三张:完成通知、审批通知带「同意 / 拒绝」、一直挂着的通知) - 新增
docs/how-it-works.md:把实现细节从 README 搬出来——停止分类、三通道检测、回合号去重、点击落点、通知标签、审批按钮桥、自定义音效存储、检查更新的双源双传输、桌面端唤醒策略、设置持久化键;信息只搬家,不删除 - 新增
CHANGELOG.md:19 个版本,从这次倒序到 1.2.1 CONTRIBUTING.md新增「自检」一节:三套断言各自覆盖什么,以及在没有 Windows 的机器上模拟本插件 Windows 链路的办法
安装
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.6.3pnpm 11 默认有一天冷静期,发版当天请钉住
@1.6.3;桌面端把web换成desktop并重开应用。
自检:npm test → 591 条断言全过(契约 19 + 浏览器半侧 501 + 宿主半侧 66)。npm 包带 --provenance 签名,来源与构建信息可在 Sigstore 透明日志里查。
v1.6.2 — 通知 tag 回到每条独立、去掉完成未读补漏、唤醒补发改成「成功就停」
修复
- 通知 tag 回到「每条独立」(1.5.5 的行为)并去掉
renotify:「按类型固定 tag」会让
新横幅替换掉上一条,而被替换的那条在 Windows 通知中心里点不动(Electron 在 Windows 上
不投递通知中心条目的 click,electron#29461),现场表现就是「点了通知窗口抬不起来」。 - 去掉「完成未读」电平补漏:它是唯一真正依赖宿主字段
uiSession.sessionStatus.completionUnread的检测逻辑。完成检测回到纯 running 边沿
(三通道共用一张表)+ 1.5.4 的回合号判据。 - 桌面壳(
dsh-app://)里审批通知强制退回普通通知,不走 Service Worker 转信那条点击
链路(桌面端「点通知抬窗」是命脉,普通onclick才是验证过的)。 - 修「反复抢前台」:桌面端唤醒的补发梯子从
0/700/1400/2400/4000ms五次收成
0/700/2200ms三次,并改成成功就停 —— 前台助手退出码 0 表示收尾时目标窗口已经是
前台,宿主拿到这个信号就把剩下的补发全部作废;助手动手抢之前也先看一眼是否已经在前台
(最小化的不算,照样 restore),并把alreadyForeground写进 raise 日志。
变更
- 清掉恒假的
window/document守卫,补上卸载守卫。 - CI:宿主自检在 Linux 上也能跑,发布门不再只对 Windows 成立。
文档
- 对齐 1.6.2:设置表补齐、清掉已删功能的描述、版本号示例刷新。
安装(发版当天请钉版本,pnpm 11 有一天冷静期)
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.6.2自检 npm test:契约 19 + 浏览器半侧 501 + 宿主半侧 66 = 591 条断言全过;npm 包带 --provenance 签名。
v1.6.1 — 审批通知正文改为「工具名 + 理由」(修复)
v1.6.1 — 审批通知正文改为「工具 + 理由」(修复)
Bug 修复: 审批请求的系统弹窗,正文以前恒等于会话名(取不到内容时的兜底),
通知上带着「同意 / 拒绝」却看不出要批准什么。现在正文按审批交互自己的字段拼:
工具名 + 本地化理由,displayReason 按通知语言取,退回 reason,两者都空才退回会话名。
正文统一按 160 字截断加省略号(不再被系统通知拦腰截出难看的截痕)。
npm test(test/verify-client.mjs446 条 +test/verify-host.mjs31 条)全过。
中文
0. 审批通知正文:工具名 + 理由(修复)
- 根因:宿主侧审批交互(
PendingApproval)不带questions列表(那只有提问 /
方案待确认的PendingQuestion才有),详情在toolName/reason/
displayReason上。旧代码只认questions[0].question,审批一律取不到 → 掉进
titleOf()兜底 → 正文恒等于会话名(界面按首句消息生成的会话标题,还常被系统
通知截断,出现过「给出审批请求 / 提问 / 方案待待」这样的截痕)。 - 现在(
approvalBodyText):displayReason(宿主的本地化展示文案,形如{ en, zh })按通知语言取对应键,
取不到退回en,再退回未本地化的reason;- 拼成
工具名:理由(中文用全角冒号,English 用半角冒号 + 空格); - 工具与理由都拿不到才退回会话名 —— 它只是兜底,不是审批内容本身。
- 真实样本(沙箱升级审批):
bash:允许本次操作使用 danger-full-access 权限:<你的理由>。 - 顺带:所有等待类正文按固定字数(160,与既有惯例一致)截断并加省略号,截痕可控。
- 自检新增 4 条:displayReason 中文 / 钉英文取 en、无 displayReason 退 reason、
两者都缺退会话名(兜底仍在)。
English
0. Approval toast body: tool + reason (fix).
- Root cause: a pending approval (
PendingApproval) carries noquestionslist
(that belongs toPendingQuestion, used by questions and plan reviews); its
content lives ontoolName,reasonanddisplayReason. The old body only
looked atquestions[0].question, so approvals always fell through to the
session-title fallback — the toast carried Approve / Reject while saying
nothing about what was being approved. - New body (
approvalBodyText): resolvedisplayReason(the host's localized
presentation copy, e.g.{ en, zh }) in the notification language, falling back
toenand then to the rawreason; render astool: reason(full-width colon
in Chinese,": "in English); the session title is only the last resort. - Waiting-kind bodies are also clipped at a fixed length (160 chars) with an
ellipsis, so the system cuts a clean end instead of a ragged one. - Self-check grew by 4 cases covering the localized body, the English pin, the raw
reasonfallback and the session-title last resort.
关于这个版本号: 1.6.0 与 1.6.1 是同一次提交(
c25bc74)里的两个版本号,都没有发布到 npm——npm 上从1.5.5直接跳到1.6.2。本页只作历史记录;要安装请用@1.6.2或更新。
v1.5.5 — 文档更新(代码零改动)
v1.5.5 — 文档更新(代码零改动)
为什么有 1.5.5: 1.5.4 之后只改了 README,而 npm 包页渲染的是「已发布版本」里的
README——不发布就刷新不了。所以换一个新版本号把这批文档带上去。插件行为与 1.5.4
完全一致,除版本号外代码逐字节相同;已经装了 1.5.4 的无需升级(除非想要包内最新文档)。
中文
这一版只动 README.md 与 zh-CN/README.md:
- 新增「全屏时看不到横幅」排障条目。 前台有全屏应用(全屏视频 / 游戏)时,Windows
会隐藏通知横幅——连优先级通知一起隐藏——提醒只进通知中心,而且退出全屏不会补弹。
开关在「设置 → 系统 → 通知 → 请勿打扰 → 在全屏模式下使用应用时(优先级通知横幅也会
隐藏)」,关掉即恢复。附实测条件:Windows 11 build 26200 上开着时该规则把全屏绑到
「仅限闹钟」档(优先名单里的应用也不放行),关掉后绑定消失、横幅正常。插件侧绕不过
(Web Notification 没有绕过「请勿打扰」的接口),提示音照常响。 - 标题下新增两枚徽章: npm 版本与总下载量(中文版用中文标签「下载量」)。
- 补上桌面端安装命令。 此前 README 只有
--profile web:现在 Quick Start、安装小节
与桌面端小节都写明dsh plugin --profile desktop add @hawkongz/dsh-task-reminder,
并说明桌面端装完重启 App 即可(不存在浏览器硬刷新那一步)。 - 代码、自检用例、设置项、行为一律不变。
node test/verify-client.mjs319 条全过。
English
A documentation-only release; only README.md and zh-CN/README.md changed:
- New troubleshooting entry for "no banner while fullscreen". While a fullscreen app
(fullscreen video or a game) is in the foreground, Windows hides toast banners —
priority notifications included — so the reminder only reaches the notification
center, and a suppressed banner is never replayed when you leave fullscreen. The
switch is Settings → System → Notifications → Do not disturb → "When using an app
in fullscreen mode (priority banners are hidden too)". Verified on Windows 11 (build
26200): with it on, the fullscreen rule binds to the Alarms only profile and silences
even priority apps; with it off the binding is gone and banners show. A Web Notification
cannot bypass Do not disturb — the chime keeps working. - Two new badges under the title: npm version and total downloads (the Chinese README
labels the latter 下载量). - Desktop install command documented. The READMEs previously only showed
--profile web; Quick Start, the Installation section and the DSH Desktop section now
all spell outdsh plugin --profile desktop add @hawkongz/dsh-task-reminder, noting that
the desktop app needs a restart instead of a browser hard-refresh. - Code, tests, settings and behavior are unchanged:
node test/verify-client.mjspasses
all 319 assertions.
安装 / Install
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.5.5
dsh plugin --profile desktop add @hawkongz/dsh-task-reminder@1.5.5装完重启宿主(dsh web / 桌面端)+ 浏览器 Ctrl+F5。新版发布未满 24 小时,命令必须带
@1.5.5(pnpm 11 的 minimumReleaseAge 冷静期);满一天后裸命令也能拿到。
npm shasum: be7f9c56a0ecd470cddae96e0b61a38abd0268df(含 provenance 证明;与发布前本地
npm pack --dry-run 逐字节一致,公开索引已核对。CI 发布 17:55:47Z,索引可见 17:58:59Z,
latest 已指向 1.5.5)
v1.5.4 — 修「上一轮刚停、新任务开始后 5 秒内完成不提醒」
v1.5.4 — 修「上一轮刚停、新任务开始后 5 秒内完成不提醒」
1.5.3 的发布卡在 npm staging(公开索引里一直没出现,
latest仍是 1.5.2),
所以这次的候选直接换号为 1.5.4。装 1.5.4 即可。
中文
修复:一轮对话刚停下来,你立刻开始新任务,那一轮在 5 秒内跑完时,弹窗和提示音都没有。
- 复现:上一轮完成(已经弹过一次)→ 马上发下一条 → 这一轮在 5 秒内结束 → 预期再弹一条
「对话任务已完成」+ 提示音,实际完全静默(弹窗与提示音都没有)。 - 原因(如实说明):插件用一张「最近一次报告」的账本做完成去重,旧判据是 5 秒时间窗
—— 窗口内已有完成票据就当成同一次停止的重复边沿丢掉;这个窗口同时还兼任「同一次停止
只报一次」。但桌面端渲染进程几乎收不到宿主转发事件(探针实测一轮 0~1 条),而只有
那一条通道会在running=true时清掉账本。于是上一轮的完成票据一直留在窗口里,新任务
在 5 秒内完成时被当成重复边沿整条吞掉。与 1.5.1 的「回答之后整轮静音」是同一个形状,
只是这次有界(5 秒)。 - 修法:把「同一次停止」的判据从时间换成回合号。停止边沿分类时本来就要读会话持久
日志的最后一条turn/end,现在把它的data.turn一并带出:与每个会话记下的「最近一次
结清的回合号」相等 → 确定性丢掉(计入stats.stopDuplicates);不同 → 照常提醒并记下。
5 秒窗口只保留给「错误优先」两个方向(error → 完成不报、完成 → error 撤回完成弹窗)
与读不到回合号时的兜底。- 没有顺手把「
running=true就清账本」推广到另外两条通道:那会让会话列表的陈旧
回放(假的running=true→ 再翻回false)重新造出一次停止边沿、弹出第二条。回合号
判据本身就把这种回放挡住了(新增用例连「边沿风暴」一起盯)。 - 有意不报的停止(取消 / 询问已报 / 崩溃孤儿 / 询问豁免)也记回合号:它们的重复边沿
同样不该再弹第二条。
- 没有顺手把「
- 其余行为一律不变:三种停止原因、错误优先、两种弹窗时机、子智能体闸门、询问豁免窗口、
提示音与自定义音效。无配置迁移,值不用改。 - 兜底一侧(如实说明,有意保守):分类读不到原因时(于是也读不到回合号)按完成报;这种
「无号」停止的重复边沿仍只能靠 5 秒窗口兜着 —— 宁可漏掉兜底报告之后 5 秒内的新回合,
也不为它冒重复弹窗的风险。
自检 node test/verify-client.mjs 319 条全过(新增 27 条,其中 13 条在 1.5.3 的代码上
必红:同回合的重复停止边沿只报一条(含列表陈旧回放、5 秒窗口过期)、新回合在上一轮停止
5 秒内完成照报、同一个回合的 error 与 completion 不会各报一次、边沿风暴下每个回合恰好一条
弹窗)。
English
Fix: when one turn stopped and you immediately started the next one, a turn that
finished within 5 s of the previous stop produced no toast and no chime at all.
- Repro: a turn completes (toast shown) → you send the next message right away → that
turn finishes within 5 seconds. Expected: another "task complete" toast plus the
chime. Actual: complete silence (no toast, no sound). - Cause (plainly): completion dedupe used a "last report" ledger keyed on a 5-second
clock — a completion ticket inside that window was treated as a repeated edge of the
same stop (the window was also the only guard for "one stop reported once"). On DSH
Desktop the renderer receives almost no host-forwarded events (measured: 0–1 per
turn), and only that one channel ever cleared the ledger onrunning=true. So the
previous stop's ticket stayed inside the window and swallowed the new turn that
finished within 5 seconds. Same shape as 1.5.1's "silent after an answered question",
only bounded this time (5 s). - Fix: the criterion for "the same stop" is now the turn number, not a clock. The
stop classification already reads the durable log's lastturn/end; it now also
returns itsdata.turn. Equal to the last turn that session settled → dropped
deterministically (counted instats.stopDuplicates); different → reported normally
and recorded. The 5 s window is kept only for error precedence (error → completion
suppressed,completion → errorretracts the completion toast) and as the fallback
when no turn number can be read.- The "clear the ledger on
running=true" rule was deliberately not extended to
the other two channels: that would let a stale session-list replay (a fake
running=trueflipping back tofalse) create a second stop edge and a duplicate
toast. The turn-number check already blocks exactly that (an edge-storm case is
covered by the new tests). - Stops that are intentionally not reported (cancelled / question already reported /
crash orphan / question grace) also record their turn, so replays of those cannot
pop a toast either.
- The "clear the ledger on
- Everything else is unchanged: the three stop reasons, error precedence, both toast
timing modes, the subagent gate, the question grace window, the chime and custom
audio. No settings migration. - Known fallback side (stated plainly, deliberately conservative): when classification
cannot read the reason (and therefore no turn number), the completion is reported at
once; a replay of such a no-number stop is still guarded only by the 5 s window —
missing a new turn inside those 5 s is the cheaper mistake than a duplicate toast.
node test/verify-client.mjs passes all 319 assertions (27 new; 13 of them fail on
1.5.3's code: a repeated edge for one turn reports once even after the 5 s window
expired or a stale list replay cleared the ticket, a new turn completing within 5 s is
reported, a same-turn error and completion never each report, and an edge storm yields
exactly one toast per turn).
安装 / Install
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.5.4
dsh plugin --profile desktop add @hawkongz/dsh-task-reminder@1.5.4装完重启宿主(dsh web / 桌面端)+ 浏览器 Ctrl+F5。新版发布未满 24 小时,命令必须带
@1.5.4(pnpm 11 的 minimumReleaseAge 冷静期);满一天后裸命令也能拿到。
npm shasum: 224cd6d400f72cdc5dcc26ec077cbdaa02b31ac1(含 provenance 证明;与发布前本地
npm pack --dry-run 一致,公开索引已核对。发布 16:34:49Z、索引可见 16:46:56Z,staging
传播约 12 分钟 —— 这期间重发同一版本会撞 409,等就好)
v1.5.3 — 修「问过问题之后那一轮完成不提醒」
v1.5.3 — 修「问过问题之后那一轮完成不提醒」
为什么有 1.5.3: 内容与 1.5.2 完全相同,只换了版本号。1.5.2 的 npm 发布在
registry 侧卡在 staging(重发时返回409 Cannot publish over previously staged version "1.5.2",公开索引里始终没有它),所以换一个新版本号重发。装 1.5.3 即可;
不要装 1.5.2(装不到,当时latest仍是 1.5.1)。
中文
修复:Agent 向你提过问(ask_user_question / 计划确认)之后,那一轮真正跑完时
既不弹窗也不响提示音。
- 复现:一轮里出现过提问 → 你回答 → Agent 继续干了几分钟 → 这一轮结束。
预期是弹「对话任务已完成」+ 提示音,实际完全静默(弹窗与提示音都没有)。 - 原因(如实说明):插件为了「一次交互一次提醒」,在你回答后给这个会话挂了一个
完成豁免(紧接着的那次完成不报)。但这个豁免原来只由「宿主转发事件」
(api-session/status)这一条通道清理。桌面端渲染进程收不到足够的转发事件时
(实测该通道在一次轮次里只有 0~1 条),豁免会一直挂到会话结束,把真正的回合完成
连弹窗带提示音一起吞掉。 - 修法(两条一起):
- 豁免变成有界窗口(45 秒)—— 只豁免「回答完紧随」的那次完成;回答之后
Agent 又干了几分钟活,那是一次新的停止,照常提醒; - 任一通道观测到
running=true(会话又跑起来)就立刻作废该豁免 ——
不再依赖某一条通道必然送达。
- 豁免变成有界窗口(45 秒)—— 只豁免「回答完紧随」的那次完成;回答之后
- 三种停止、去重、错误优先、弹窗时机、子智能体闸门等其余行为一律不变。
- 无配置迁移,值也不用改。
自检 node test/verify-client.mjs 292 条全过(新增 3 条:豁免窗口有界、超过窗口的
完成照报、会话再跑起来即作废 —— 后两条在 1.5.1 的代码上必红)。
English
Fix: after the agent asked you a question (ask_user_question / plan review), the
completion of that turn produced no toast and no chime at all.
- Repro: a turn contained a question → you answered → the agent kept working for
minutes → the turn finished. Expected: a "task complete" toast plus the chime.
Actual: complete silence (neither toast nor sound). - Cause (plainly): to avoid double reminders, the plugin puts a completion exemption
on the session when you answer a question (the immediately following completion is
muted). That exemption used to be cleared only by one channel — the forwarded host
eventapi-session/status. In DSH Desktop the renderer receives almost none of those
events (measured: 0–1 per turn), so the exemption stayed armed until the session
ended and swallowed the real turn completion, toast and chime alike. - Fix (both parts): the exemption is now a bounded 45 s window (it only mutes the
completion that immediately follows your answer; work that continues for minutes ends
as a new stop and is reported normally), and any of the three observation channels
seeingrunning=true(the session running again) invalidates it immediately. - Everything else — the three stop kinds, dedupe, error precedence, timing modes, the
subagent gate — is unchanged. No settings migration.
node test/verify-client.mjs passes all 292 assertions (3 new: the exemption window
is bounded, a completion past the window is reported, and a resumed session invalidates
the exemption — the last two fail on 1.5.1's code).
安装 / Install
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.5.3
dsh plugin --profile desktop add @hawkongz/dsh-task-reminder@1.5.3装完重启宿主(dsh web / 桌面端)+ 浏览器 Ctrl+F5。新版发布未满 24 小时,命令必须带
@1.5.3(pnpm 11 的 minimumReleaseAge 冷静期);满一天后裸命令也能拿到。
npm shasum: bbcb904655827a4a44dc1fe7d16124cb39220350(含 provenance,与发布前本地
npm pack --dry-run 一致)
v1.5.2 — 修「问过相关问题后那一轮完成不提醒」
ℹ️ 发布过程说明: 1.5.2 在 npm registry 侧卡了约 20 分钟 staging(发布 15:32:31Z,
公开索引 15:52:20Z 才可见),现已上架并一度是latest:
shasum4478b80052a9fd4facb031b042894c9152967c25(与发布前本地npm pack --dry-run一致)。
当时误判为「装不到」,于是换了版本号又发了一个 1.5.3(内容完全相同);装 1.5.2 或
1.5.3 都可以。
v1.5.2 — 修「问过问题之后那一轮完成不提醒」
中文
修复:Agent 向你提过问(ask_user_question / 计划确认)之后,那一轮真正跑完时
既不弹窗也不响提示音。
- 复现:一轮里出现过提问 → 你回答 → Agent 继续干了几分钟 → 这一轮结束。
预期是弹「对话任务已完成」+ 提示音,实际完全静默(弹窗与提示音都没有)。 - 原因(如实说明):插件为了「一次交互一次提醒」,在你回答后给这个会话挂了一个
完成豁免(紧接着的那次完成不报)。但这个豁免原来只由「宿主转发事件」
(api-session/status)这一条通道清理。桌面端渲染进程收不到足够的转发事件时
(实测该通道在一次轮次里只有 0~1 条),豁免会一直挂到会话结束,把真正的回合完成
连弹窗带提示音一起吞掉。 - 修法(两条一起):
- 豁免变成有界窗口(45 秒)—— 只豁免「回答完紧随」的那次完成;回答之后
Agent 又干了几分钟活,那是一次新的停止,照常提醒; - 任一通道观测到
running=true(会话又跑起来)就立刻作废该豁免 ——
不再依赖某一条通道必然送达。
- 豁免变成有界窗口(45 秒)—— 只豁免「回答完紧随」的那次完成;回答之后
- 三种停止、去重、错误优先、弹窗时机、子智能体闸门等其余行为一律不变。
- 无配置迁移,值也不用改。
自检 node test/verify-client.mjs 292 条全过(新增 3 条:豁免窗口有界、超过窗口的
完成照报、会话再跑起来即作废 —— 后两条在 1.5.1 的代码上必红)。
English
Fix: after the agent asked you a question (ask_user_question / plan review), the
completion of that turn produced no toast and no chime at all.
- Repro: a turn contained a question → you answered → the agent kept working for
minutes → the turn finished. Expected: a "task complete" toast plus the chime.
Actual: complete silence (neither toast nor sound). - Cause (plainly): to avoid double reminders, the plugin puts a completion exemption
on the session when you answer a question (the immediately following completion is
muted). That exemption used to be cleared only by one channel — the forwarded host
eventapi-session/status. In DSH Desktop the renderer receives almost none of those
events (measured: 0–1 per turn), so the exemption stayed armed until the session
ended and swallowed the real turn completion, toast and chime alike. - Fix (both parts): the exemption is now a bounded 45 s window (it only mutes the
completion that immediately follows your answer; work that continues for minutes ends
as a new stop and is reported normally), and any of the three observation channels
seeingrunning=true(the session running again) invalidates it immediately. - Everything else — the three stop kinds, dedupe, error precedence, timing modes, the
subagent gate — is unchanged. No settings migration.
node test/verify-client.mjs passes all 292 assertions (3 new: the exemption window
is bounded, a completion past the window is reported, and a resumed session invalidates
the exemption — the last two fail on 1.5.1's code).
安装 / Install
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.5.2
dsh plugin --profile desktop add @hawkongz/dsh-task-reminder@1.5.2装完重启宿主(dsh web / 桌面端)+ 浏览器 Ctrl+F5。新版发布未满 24 小时,命令必须带
@1.5.2(pnpm 11 的 minimumReleaseAge 冷静期);满一天后裸命令也能拿到。
npm shasum: 4478b80052a9fd4facb031b042894c9152967c25(含 provenance,与发布前本地 npm pack --dry-run 一致)
v1.5.1
v1.5.1 — 点通知直接落到对话底部
中文
新功能:点系统通知后,会话打开即停在对话底部。
- 以前点通知只会「打开对应会话」,而你上次的阅读位置会被恢复 —— 于是常常停在历史中间,
还得自己往下滚。现在打开后会自动落到最新的对话内容(相当于替你点了界面自带的
「回到底部」按钮)。 - 实现方式(如实说明):DSH 没有对外暴露滚动接口(
openSession(target)不收参数,
ctx.uiConversation也没有导航能力),所以插件打开会话后在约 1.4 秒内轮询应用自带的
「回到底部」按钮(只在未跟随底部时渲染),出现就替用户点一下,走应用自己的
returnToBottom(),滚动状态机保持一致。 - 按钮一直不出现 = 本来就在底部,什么也不做;将来 DSH 改了 DOM,最多丢掉这一步,
绝不影响「打开会话」与桌面端的窗口唤醒。轮询定时器随插件卸载一并取消。 - 三种通知(完成 / 等你回答 / 出错)点击行为一致。
自检 node test/verify-client.mjs 289 条全过(新增 11 条:按钮按 aria-label / 类名后缀
定位、点中一次后停止轮询、找不到按钮时到上限静默收工)。
English
New: clicking a toast now opens the session at the bottom of the conversation.
- Before, a toast click only opened the session and DSH restored your previous reading
position, so you often landed in the middle of the history and had to scroll down.
The plugin now lands you on the latest content — the same thing the built-in
back-to-bottom button does. - How (plainly): DSH exposes no scroll API (
openSession(target)takes no options and
ctx.uiConversationhas no navigation surface), so after opening the session the
plugin polls for the built-in back-to-bottom button (rendered only while the reader
is off the tail) for about 1.4 s and clicks it, which runs the app's own
returnToBottom()and keeps the scroll state machine consistent. - If the button never appears the reader was already at the bottom and nothing happens.
A future DOM change can only lose this extra step — never session opening or the
DSH Desktop window activation. Polling timers are cancelled with the plugin. - All three toasts (completion / waiting for your answer / error) behave the same.
node test/verify-client.mjs passes all 289 assertions (11 new ones: label and
class-suffix lookup, clicking exactly once, bounded polling that gives up silently).
安装 / Install
dsh plugin --profile web add @hawkongz/dsh-task-reminder@1.5.1
dsh plugin --profile desktop add @hawkongz/dsh-task-reminder@1.5.1装完重启宿主(dsh web / 桌面端)+ 浏览器 Ctrl+F5。新版发布未满 24 小时,命令必须带
@1.5.1(pnpm 11 的 minimumReleaseAge 冷静期);满一天后裸命令也能拿到。
npm shasum: 9fbfec0a77fd9279d543d08d35a7c0e70b12f9a7(含 provenance)