Notifications for four session states, with browser alerts and prompts.
- Language
- TypeScript
- Branch
- main
Install
$ dsh plugin --profile web add @dingyi222666/dsh-session-notificationRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin dingyi222666/dsh-session-notification for me: review the repository at https://github.com/dingyi222666/dsh-session-notification first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
一句话定位
给 DSH Web GUI 挂一套会话状态通知:会话跑完、出错、向你提问、需要你授权这四类事件会播放提示音,离开当前标签页时还会弹系统通知;所有偏好与自定义音效都存在浏览器本地。
核心能力
- 监听会话运行状态的边沿事件,会话正常完成时响一声「叮咚」,出错中断时响「低鸣」
- Agent 提问等待回答时响「轻响」,Agent 请求执行越权操作需要你批准时响「警示」
- 四种事件全部可以单独开关,并把提示音换成四种内置音效里的任意一种,或静音
- 内置音效用 Web Audio 实时合成,不携带任何音频文件;自定义音效支持 mp3/ogg/wav 上传(每类不超过 1 MB)
- 浏览器(系统级)通知默认关闭,开启时会向浏览器申请权限;离开当前标签页或事件属于后台会话时弹系统通知,点击自动聚焦窗口
- 通知正文里「完成」类带最后一次助手回复文本,「失败」类带错误信息,「提问」类带问题原文,「权限请求」类带工具名与原因
- 在设置面板新增「通知」栏目,含浏览器通知总开关、当前会话也提醒开关、声音总开关、音量滑块(0–200%)、每类事件单独行、测试通知按钮
- 偏好存在浏览器 localStorage,跨标签页自动同步,自定义音频按设备本地存储
技术实现
- 语言: TypeScript + React 18
- 关键依赖: @deepseek-ai/cordis(host 端 Cordis 上下文与 patch 注入)、@deepseek-ai/dsh-client-runtime / -connection / -locale / -ui-settings / -ui-slots / -ui-primitives(浏览器侧类型与 slot 注册)、@deepseek-ai/dsh-settings / -schemastery(host 侧 schemastery schema)、@deepseek-ai/dsh-invariants(package-owned invariant 伴生插件占位)、react / react-dom(设置栏目 UI)
- 架构模式: DSH 双端 bundle 架构。host 半边(
src/index.ts)只在 settings seam 注册dsh-session-notification命名空间,不挂任何 effect,invariant 伴生插件src/invariant.ts是空安装。client 半边(src/client/index.ts)由两条观察通路组成:① NotificationEngine 订阅 sessions.list 快照,捕捉每个会话的running与pendingInteraction边沿;② NotificationDispatcher 按当前偏好门控,播放内置 Web Audio 音效或调用浏览器NotificationAPI。设置栏目走标准settings.sectionslot 与slots.inject工厂,与官方栏目复用同一套 store / useStore / inject 模式。偏好以「浏览器本地 SettingsScope」方式实现(createLocalSettingsScope+ storage 事件跨标签页同步),不依赖 host 端 settings namespace 暴露。 - 入口文件: src/index.ts(host,仅注册 settings schema)、src/client/index.ts(client 主入口,绑定偏好、注册 slot、订阅 sessions.list)、src/invariant.ts(invariant 伴生占位)、cordis.patch.yml(向 host Loader 注入本插件条目)
适用场景
你日常在 DSH Web 里跑长任务(代码改动、长文写作、数据处理),过程中会切到其他标签页查资料、刷消息,DSH 自己的提示只会画在被切走的那个标签页里。这个插件把「任务跑完了」「出错了」「在等你回话」「要你授权」四类关键边沿搬到桌面通知和提示音上:你能在别的窗口听到响、收到系统弹窗,点回去就能立刻处理。它不向模型发任何请求,也不修改 DSH 宿主或聊天视图的代码。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | >= 0.1.1-rc.2 | README 安装说明所写;package.json#dsh.client.platform 显式声明 web,仅支持 dsh web,不适用于 Node CLI |
| Node | 未声明 | package.json 未声明 engines;运行产物是浏览器侧 bundle,宿主 Node 编译要求未明确 |
| 平台 | Web | 浏览器端 plugin;自定义音效限制 1 MB;浏览器通知走原生 Notification API |
| 原生模块 | 无 | 仅依赖浏览器原生的 AudioContext / Notification / localStorage,无 node-pty、sqlite 等 Node 原生模块 |
安装方式
dsh plugin --profile web add github:dingyi222666/dsh-session-notification
配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| 浏览器通知 | 开关 | 离开当前标签页或后台会话事件触发时弹系统通知;开启时会向浏览器申请权限 | 关闭 |
| 当前会话也提醒 | 开关 | 正在看的会话完成或失败时是否也响(默认避免打扰) | 关闭 |
| 声音 | 开关 | 是否播放提示音 | 开启 |
| 音量 | 0–200% | 主音量;超过 100% 会放大内置 Web Audio 合成音 | 60% |
| 会话完成 | 启用 + 音效 | 一轮会话正常结束时触发;可换 4 种内置音或静音或上传自定义 | 开启 / 叮咚 |
| 会话失败 | 启用 + 音效 | 一轮会话出错中断时触发 | 开启 / 低鸣 |
| 问问题 | 启用 + 音效 | Agent 正在等你回答时触发 | 开启 / 轻响 |
| 权限请求 | 启用 + 音效 | Agent 请求执行需授权操作时触发 | 开启 / 警示 |
常见问题
Q: 安装后需要做什么额外配置吗?
A: 不需要。安装并重启 dsh web 后,设置面板会多出一个「通知」栏目;浏览器通知默认关闭,首次开启时会向浏览器申请权限,点一次「授权」即可。所有偏好都存在浏览器本地(localStorage),跨标签页自动同步。
Q: 提示音是怎么来的?会随插件一起下载音频文件吗?
A: 不会下载。四种内置音效(叮咚/低鸣/轻响/警示)全部用 Web Audio API 在浏览器里实时合成,插件包不携带任何音频文件,体积因此保持很小;如果你想换音色,可以为任意一类事件上传 mp3/ogg/wav(不超过 1 MB)。
Q: 我正在看当前会话时它会响吗?
A: 默认不会。设计有意避免与对话界面自身的提示重复打扰:当你正在看的那个会话触发了完成/失败,并且标签页处于前台可见时,不会响铃也不会弹通知。如果希望它也提醒,把「当前会话也提醒」开关打开即可。
Q: 浏览器通知被拒绝后再点开关还能用吗?
A: 不能。开关只能反映用户的偏好,权限被拒绝后系统通知的开关会显示「通知已暂停:缺少浏览器权限」,需要去浏览器站点设置里重新放权再回来点一次;声音与权限无关,可以照常使用。
Q: 离开页面一段时间后再切回去,会不会有「补弹」一大堆通知?
A: 不会。插件只看会话列表快照的边沿事件(运行状态从 true 变 false、出现 question / approval),插件加载时已经空闲或已经在等待交互的会话不会触发任何通知,只有真正发生在加载之后的新边沿才会提醒。
Q: 自定义音效会上传到服务器吗?
A: 不会。自定义音频以 data URL 形式存进当前浏览器的 localStorage(key 是 dsh-session-notification.customSounds),属于设备本地媒体资源,不会跨浏览器或跨 profile 跟随。
Q: 会修改 DSH 宿主或聊天视图的代码吗?
A: 不会。设置栏目通过 settings.section slot 注册,与官方栏目做法一致;偏好放在浏览器本地,不需要宿主放行任何设置命名空间;通知来源是会话列表快照,不新增任何 wire 通道。Node 侧仅占位一个 dsh-session-notification 命名空间,不动 apiproxy 等宿主包。
Q: 怎么卸载?
A: 用 dsh plugin --profile web remove @dingyi222666/dsh-session-notification,然后重启 dsh web 并在浏览器硬刷新(Cmd/Ctrl+Shift+R);设置栏目会消失,浏览器本地存的偏好和自定义音频会留在 localStorage 里直到你手动清理。
上手难度
入门 — 一条 dsh plugin 命令安装并重启 dsh web 即可看到「通知」栏目,所有偏好都在 UI 里点选,无需配置文件、无需读源码、无需 host 端改动。
已知问题与限制
- 失败判定依赖会话的对话快照,而客户端只为「打开过」的会话维护快照;从未打开过的会话若运行失败,仍会被通知为「完成」
- 浏览器通知需要先在浏览器放权,声音播放需要页面获得用户激活(浏览器自动播放策略),首次访问点一下页面或开关即可解决
- 自定义音频仅存浏览器 localStorage,不跨浏览器、不跨 profile 同步;文件大小上限 1 MB
- 浏览器端基于会话列表快照的事件驱动,不直接读原始事件流;理论上两次快照之间开始又结束的运行可能漏报(host 对每个边沿都会下发状态帧,实际不会发生)
- 浏览器原生 Audio 元素的音量被浏览器封顶在 100%,即使主音量调到 200%,自定义音频也只会响到 100% 强度
- favicon 若无法被浏览器栅格化会触发一次无图标的备用通知(不是失败,但日志里会写一行警告)
English | 中文
A notification plugin for the dsh web GUI. When a session finishes, hits an error, asks you a question, or needs your permission, you get a heads-up: a sound plays, and when you step away from the tab a system notification keeps you in the loop.
Screenshots
| The settings panel with the Notifications entry in the sidebar and the section content | The sound picker for each kind (the official dropdown) |
|---|---|
![]() | ![]() |
Install
# Install from npm (requires dsh >= 0.1.0-rc.7)
dsh plugin --profile web add @dingyi222666/dsh-session-notification
# Restart dsh web for it to take effect
dsh web
Everything lives in this plugin — no harness (host) changes:
- The settings section is registered through the client slot system (
settings.section), exactly like official sections. - Preferences persist in the browser (localStorage) and sync across tabs; nothing requires the host's
WEB_SETTINGS_NAMESPACESor any other host-package change. (The node half still reserves thedsh-session-notificationnamespace host-side through the settings seam; that reservation is inert without exposure.) - The settings shell maps only its own section ids to nav icons, so the Notifications nav row shows the shell's default gear.
The four notification kinds
| Kind | When it fires | Default sound |
|---|---|---|
| Session completed | A turn ends normally (turn/end completed) | chime |
| Session failed | A turn breaks with an error, or the host reports an agent error | fault |
| Question asked | The agent is waiting for your answer (question/requested) | pop |
| Permission requested | The agent requests an authorized operation (approval/requested) | alert |
Each kind can be enabled or disabled and reassigned to any of the four built-in sound effects (or muted). The four sounds are synthesized with Web Audio — no audio files are shipped — and the master volume is adjustable with the official-style slider (0–200%; above 100% amplifies the built-in sounds).
Custom audio
Beyond the four built-in sounds, each kind accepts your own audio file (mp3/ogg/wav, up to 1 MB): pick Custom audio on a kind's row to upload one, and it replaces the built-in for that kind — with a Replace and remove affordance, plus the Custom audio in use tag. Custom files are stored browser-locally (they are device media, not shared preferences).
Browser notifications & the quiet default
Browser (system-level) notifications are off by default; turning the switch on asks for the browser's permission first (a user gesture). Once granted, a notification is shown when the event's session is not the one you are reading, or when the tab is in the background. Notifications carry the page's own icon (the favicon the harness serves). A completed session's notification carries its final reply text (the last assistant message). The Test notification button in the section sends one immediately to verify the channel once permission is granted. The session you are reading stays quiet by default — its own events don't interrupt you; flip the Alert for the current session toggle if you want it to alert too.
The Notifications settings section
The plugin registers a Notifications section in the settings panel (Settings ⚙ → Notifications):
- Browser notifications master switch (+ permission state and an enable button),
- Alert for the current session toggle (opt in to being alerted while reading that session),
- Sound master switch,
- Volume slider (0–200%),
- one row per notification kind: enable switch, custom-audio upload, sound picker (the official dropdown menu), and a Preview button,
- a Test notification button on the browser-notifications row (verifies the OS channel once permission is granted).
Preferences are stored browser-locally (localStorage) under the dsh-session-notification key — no host settings-namespace exposure required — so they persist across sessions and sync across tabs, and never depend on a harness change.
How it works
The browser half watches the sessions list snapshot and each session's conversation snapshot — no polling, no new wire channels:
- A session's
runningedge true→false ends a run; the run is classified failed when a newturn-errornode or a hostagent-errorappeared during it, otherwise completed (a failure that a retry recovered reads as completed). - A pending-interaction edge (
question/approval) raises the question / permission kinds, with the question text or the tool name+reason in the notification body. - Sessions already idle (or already pending) when the plugin loads raise nothing.
Development
yarn run build— builds the browser bundle (lib/client.js) and the Node half (lib/index.js/lib/invariant.js).src/client/notification-service.ts— the engine (classification) and dispatcher (gating);src/client/settings-store.ts— the settings section bridge;src/client/NotificationsSection.tsx— the section UI;src/client/sounds.ts+src/client/custom-audio.ts— the built-in and custom sounds.yarn test— behavior tests;yarn run typecheck— type gate.- Node-half changes need a
dsh webrestart; browser-bundle changes need a rebuild (yarn run build) — a--devserver hot-reloads them.
Known limitations
- Failure detection reads the conversation snapshot, which the client only maintains for sessions that have been opened; a session that runs without ever being opened notifies as completed even on failure.
- Browser notifications require permission, and sound playback requires the page to have user activation (the browser's autoplay policy) — both are normal for browser apps and resolve as soon as the user interacts with the GUI.
- Custom audio files live in the browser (localStorage), so they do not follow you across browsers or profiles.
- The browser half is event-driven from the sessions list; it does not observe the raw event stream, so a run that starts and finishes between two list snapshots could in principle be missed (the host sends a status flip per edge, so this does not happen in practice).
Model Experience
None. The plugin is a pure client-side observer over the already-logged session state; nothing here reaches a model request.
KV Cache effect
None; this package neither assembles nor sends provider requests.
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/dingyi222666/dsh-session-notification)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.

