Skip to content

dsh-turn-notify

Verified

@lwgm/dsh-turn-notify · v0.3.3 · MIT · Web UI

DSH Web GUI turn-end reminder: chime + browser Notification on every agent turn end; taskbar badge counter (Chrome PWA Badging API, title fallback) accumulating per completed turn, cleared on window focus; approval/question attention alert with distinct t

Install

dsh plugin add @lwgm/dsh-turn-notify

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

Source

Published to npm without a public repository. Inspect the package contents before installing.

Tags

Creators

Readme

dsh-turn-notify

DSH Web GUI 静态插件(0.3.3,双版本兼容 + 挂载诊断):

  1. 回合结束提醒:每当 agent 的一个 turn 结束(正常完成 / 报错 / 中止), 播放 880→1318.5Hz 上升双音"叮"(Web Audio,约 0.7s,峰值 0.25)
    • 浏览器 Notification(标题 "DSH:回合完成",tag dsh-turn-end)。 正文带本次用户 prompt 摘要(locations.getTurn(N) 精确取该 turn 的用户 消息文本,截断 60 字;含图片标注;无用户消息的 turn 显示纯状态行)。
  2. 任务栏角标:你离开页面期间(窗口失焦/文档隐藏)每完成一个回合, 任务栏 DSH 图标数字角标 +1(Chrome 已安装 PWA 的 Badging API: navigator.setAppBadge(n));点击/聚焦浏览器窗口清零。在场时回合结束 不计数(你在看着,无需提醒)。setAppBadge 不可用/被拒时自动降级为标签页 标题计数 (N) DSH…(只管理自己的 (N) 前缀,不碰应用自身标题正文)。
  3. 审批提醒:工具审批(approval/requested)或提问(question/requested) 等待用户操作时,下降双音(1046.5→659.25Hz)+ 通知 "DSH:需要审批 / 工具 X 等待审批"(tag dsh-approval)或 "DSH:需要回答 / 首问摘要"(tag dsh-question),均附 "执行中:〈最新用户 prompt 摘要〉"上下文行。
  4. 双版本兼容:旧代 dsh(0.1.0-rc.7 代)会话快照顶层带 turnEnds/pending/chat;新代 dsh(0.1.5-rc.1 起)Session 快照瘦身, turnEnds 迁至 useChat(s => s.legacy.turnEnds)、pending 迁至独立 store useSessionPendingInteraction(每会话单条最高优先级 interaction: approval:<n> / question:<n>)、chat 视图经 useChat。插件同时消费两代 信号源、按能力自动择一——同一份 0.3.x 在旧代/新代 dsh 上均可直接工作 (此前 0.2.x 在新代 dsh 上因快照字段移除而静默失效)。挂载时向 Console 打 [turn-notify] v0.3.2 mounted 标记(含信号源新旧),武装时打 [turn-notify] armed (baseline)。
  • 每个 turn / 每次审批只提醒一次;turn 进行中绝不响;
  • 页签在后台(document.hidden)照常弹通知、照常出声;
  • 无可见 UI(组件渲染 null),不注入任何 CSS,不产生 DOM——对其它插件零样式影响;
  • 仅监听当前打开的会话。

安装(本 profile 内)

源码在 local-plugins/dsh-turn-notify(本文件所在目录),package.json 以 file: 依赖挂进 profile;profile 的 cordis.patch.yml 已插入行 {id: turn-notify, name: dsh-turn-notify}。 重启 dsh web 即生效——静态 composition 插件走信任面,无需审批、重启自动挂载。

使用

激活后全自动,无需配置:

场景 表现
离席期间任一 turn 结束 上升双音叮 + 通知 "DSH:回合完成";PWA 任务栏角标 +1(否则标题 (N))
在场时 turn 结束 叮 + 通知(照常),角标不计数
点击/聚焦浏览器窗口 角标/标题计数清零
工具审批等待 下降双音 + 通知 "DSH:需要审批 / 工具 X 等待审批"
ask_user_question 等待 下降双音 + 通知 "DSH:需要回答 / 首问摘要"
页面刚打开还没交互过 首次任意点击或按键即解锁音频(并顺带弹通知授权)
页签在后台 照常弹通知,声音也照常播

维护

  • 升级版本后必须重启 dsh web:新代 dsh(0.1.5-rc.1 起)的 client bundle 字节在 dsh web 启动时读入内存缓存并按 revision 服务,pnpm add 新版本后 不重启则浏览器加载的仍是启动时的旧字节(非 dev:web 环境无 HMR 热更)。
  • 修改代码后直接改 local-plugins/dsh-turn-notify/lib/client.js 并重启 dsh web; node_modules/dsh-turn-notify 是运行期副本,pnpm install 会按 file: 依赖自动重建。
  • 分发给别人:把 local-plugins/dsh-turn-notify 整目录给对方,按对方 profile 的同样三处接线(package.json file: 依赖 + cordis.patch.yml 行 + node_modules 副本), 或将来发布 npm 后改成 registry 依赖。

实现要点

  • 客户端无 turn/end 事件 → 会话快照状态迁移判定(双代信号源,自动择一): 旧代 useSession(s => s.turnEnds)(Map<turn, turn/end seq>,timeline 变化重建 新 Map 引用 → 选择器可靠重渲染);新代 useChat(s => s.legacy.turnEnds) (同一 timeline turn.end 构建,语义不变)。running 两代均在 useSession 快照。
  • 开火条件:armed(会话窗口首次 open 时以现有 turnEnds/pending 为历史基线, 重载/翻页不响)∧ running===false ∧ 存在未通知条目;notified Set 按 turn 号去重; sessionId 变化复位。
  • 审批信号(双代):旧代 useSession(s => s.pending) 数组(wire 契约 approval/requested payload={approvalId,toolName,callId?,reason?}; question/requested payload={questions[]}),按 pending.key (a: / q:)去重;新代 useSessionPendingInteraction store 的 snapshot.get(sessionId) 单条 interaction(PendingApproval {kind:"approval", key:"approval:", toolName, reason} / PendingQuestion {kind:"question"|"plan-review", key:"question:", questions[]}),按 key 去重。
  • 角标:navigator.setAppBadge(n)(W3C Badging API;Chrome 要求已安装 PWA); Promise 被拒/同步抛错 → 一次性降级标题前缀模式(/^\(\d+\)\s+/ 前缀管理, 与应用自身标题变更正交);窗口 focus / visibilitychange→visible 时清零。
  • prompt 摘要:chat.locations.getTurn(turn)(官方 turn→节点键索引)取该 turn 首个 kind==="user" 节点的内容块({type:"text",text} 拼接、{type:"image"} 计数标注),60 字截断;审批/提问上下文取 chat.order 末尾最近用户节点; 全防御式访问,取不到即降级纯状态行。
  • UI 落点:conversation.composer.dock(list / session 级 / additive,渲染 null)。
  • 卸载时 close 懒创建的 AudioContext(ctx.effect),副作用全部可逆。