@mcd0luo/celes-dsh-notify
v0.1.1
Published
Windows system notifications for dsh (Celestea series): session approval requests and task completions raised through the HTML5 Notification API in the WebView2 shell
Maintainers
Readme
@mcd0luo/celes-dsh-notify
dsh 系统通知(Celestea 系列成员):会话出现审批请求、智能体一轮任务结束、
目标完成时,通过 HTML5 Notification API 在 Windows 任务栏弹出系统通知
(WebView2/Chromium),窗口在后台时也能看到。
功能
| 场景 | 触发条件 | 通知标题 |
|---|---|---|
| 审批请求 | 会话出现 approval/requested(或 plan-review 计划评审) | [dsh] 需要你的审批 |
| 任务完成 | 智能体从忙碌回到空闲(一轮结束),或后台会话完成 | [dsh] 任务完成 |
| 目标完成 | goal 投影阶段进入 complete(默认关闭) | [dsh] 目标完成 |
同类通知按 minIntervalMs(默认 5s)去抖,避免审批/工具调用刷屏。
实现方式
事件来源(不 patch 官方 bundle,不挂槽位)
本插件是纯事件监听的 client 半插件,不挂任何槽位、不 patch 官方 bundle。
事件来自 dsh-client-runtime 暴露的公开会话列表快照 ctx.sessions.list
(SnapshotStore<SessionListState>,client 插件声明 inject: ["sessions"] 即可
订阅),每一行 SessionSummary 携带由 host wire 帧驱动的实时事实:
pendingInteraction('approval' | 'plan-review' | 'question')——由approval/requested/question/requested帧在 manager 层登记;running——由host/session-status帧镜像,忙碌→空闲翻转即"一轮结束";completed——后台会话完成提醒(未选中时完成的补充信号);displayTitle/projectionValues——会话标题与 host 下发的投影值。
通知正文 best-effort 增强:审批发生时尝试从 ctx.sessions.binding(id) 的会话
快照 pending 面读取 approval/requested 载荷(toolName / reason),取不到
就退回会话标题、再退回通用文案。
为什么不用 session/event? session/event 是 host 侧 Cordis 事件;client
侧对应物是 mux 流帧(dsh-client-connection 建立的连接流 → dsh-client-runtime
SessionRuntime.handleMuxEnvelope 分发),原始事件窗口在 Session 实例内部,
不属于公开契约。列表快照是官方 UI(侧栏琥珀点、完成提醒)同源的数据面,最稳。
(替代方案:挂 session 作用域槽位拿 useSession/useProjection,或
ctx.sessions.scope(id) 后的 agent 作用域 ctx 上监听事件——本插件不需要。)
通知通道(双通道,自动切换)
- 原生 HTML5
Notification:真实浏览器授权后使用(首次启用时requestPermission()); - host 系统气泡(默认兜底):WebView2(desk)的宿主不处理
PermissionRequested,原生通知永远拿不到granted——client 检测到 原生通道不可用时,自动POST /api/notify/fire,host 半用零依赖的 PowerShellNotifyIcon弹 Windows 托盘气泡(不需要 AUMID 注册,区别于 WinRT toast)。
每条通知带 tag(按类型)并 8s 自动关闭,避免任务栏堆积。
通道自检
重启后可直接在浏览器/命令行验证通道:
GET http://127.0.0.1:3180/api/notify/test应弹出一条「[dsh] 通知通道测试」气泡并返回 {"ok":true}。
安装
Celestea 系列由基座 @mcd0luo/dsh-celestea 的 bundle 统一挂载(基座补丁给每个
成员预留带条件的挂载行,本包装进 profile 后下次启动自动启用)。
⚠️ 基座必须显式安装一次。
# 1. 一次性:安装基座(设置中心 + 系列挂载点)
dsh plugin --profile web add @mcd0luo/dsh-celestea
# 2. 安装本包,重启后自动挂载
dsh plugin --profile web add @mcd0luo/celes-dsh-notify
# 3. 重启 desk(或 dsh web + 硬刷新)不装基座、单独使用本包时(不推荐),需要手动在
~/.dsh/profiles/web/cordis.patch.yml 添加:
- insert:
- id: notify
name: "@mcd0luo/celes-dsh-notify"走了基座 bundle 路线就不要再加这行,否则 loader 会报
duplicate loader entry id。
配置(设置 → Celestea → notify)
| 字段 | 默认 | 说明 |
|---|---|---|
| enabled | true | 是否启用系统通知 |
| notifyApproval | true | 审批请求(approval / plan-review)时通知 |
| notifyTaskDone | true | 一轮任务结束、智能体空闲时通知 |
| notifyGoalDone | false | 目标(goal)完成时通知(见下方局限) |
| titlePrefix | dsh | 通知标题前缀,如 [dsh] 需要你的审批 |
| minIntervalMs | 5000 | 同类通知最小间隔(ms),防刷屏 |
| hostFallback | true | 原生通知不可用时由 host 弹 Windows 气泡 |
| balloonMs | 6000 | host 气泡显示时长(ms) |
配置保存后需要刷新页面 / 重启 desk 才会被 client 半重新读取(与 thread-rail 相同:client 启动时读取
/api/notify/status)。
兼容性(WebView2 / 浏览器)与局限
- 通知依赖 WebView2 / Chromium 的
NotificationAPI;宿主若关闭了通知 权限(WebView2 的PermissionRequested策略),原生通知会被拒绝—— desk 场景会自动切换到 host 系统气泡(见上),真实浏览器场景走原生。 notifyGoalDone依赖 host 在列表行下发 goal 投影值 (projectionValues.goal);若 host 未在列表行携带投影,该触发不会生效 (此时目标完成只能靠运行中会话的投影面,暂未接通——best-effort,默认关闭)。- 审批正文的
toolName/reason读取依赖会话快照的pending面,后台未打开 窗口的会话可能取不到,自动退回会话标题。 - 通知事件来自官方 client runtime 的会话列表契约(
SessionSummary),属官方 内部契约,后续 dsh 升级可能需要同步。
开发
npm run build # src/ → lib/(host + client 都生成)
npm publish # 发版后 dsh plugin --profile web update @mcd0luo/celes-dsh-notifyLicense
MIT
