📝 docs: README 只保留功能与用法,移除开发相关说明
This commit is contained in:
@@ -1,51 +1,62 @@
|
||||
# 会话通知
|
||||
|
||||
DeepSeek Harness(DSH)插件:会话**需要你注意**时提醒你——窗口不在前台时用**系统通知**,窗口在前台时用**应用内轻弹窗**。
|
||||
|
||||
Windows / macOS / Linux 三个平台走的是同一条通知通道(渲染进程的 Web Notification API),插件里没有平台分支。
|
||||
DeepSeek Harness(DSH)插件:会话**需要你注意**时提醒你——窗口不在前台用**系统通知**,窗口在前台用**应用内轻弹窗**。
|
||||
|
||||
## 提醒什么
|
||||
|
||||
| 触发 | 通知标题 |
|
||||
| 什么时候提醒 | 通知标题 | 内容里带什么 |
|
||||
| --- | --- | --- |
|
||||
| 会话从「运行中」变为「空闲」(一轮回答结束) | 会话已完成 | 会话题目 |
|
||||
| 出现等待你处理的工具授权请求 | 需要授权 | 等待授权的工具名 |
|
||||
| 出现等待你回答的提问,或等待你确认的计划 | 需要回答 | 提问提醒带问题原文,计划确认带会话题目 |
|
||||
|
||||
三类提醒可以分别开关。
|
||||
|
||||
每条只提醒一次:同一会话的同一轮只报一次完成,同一个待处理请求只报一次;请求消失之后再次出现,会重新提醒。
|
||||
|
||||
## 提醒送到哪里
|
||||
|
||||
按 DSH 窗口**当时**的状态选通道,你不需要预先设置:
|
||||
|
||||
| 窗口状态 | 怎么提醒 |
|
||||
| --- | --- |
|
||||
| 会话从「运行中」变为「空闲」(一轮回答结束) | 会话已完成 |
|
||||
| 待处理的工具授权请求(`approval`) | 需要授权 |
|
||||
| 待处理的提问 / 计划确认(`question` / `plan-review`) | 需要回答 |
|
||||
| 窗口**不在前台** | **系统通知**(Windows 通知中心 / macOS 通知中心 / Linux 通知守护)。点一下通知:窗口回到前台,并跳到那个会话 |
|
||||
| 窗口在**前台**,但不是你正在看的那个会话 | **应用内轻弹窗**:右上角浮出一张卡片,标题是提醒类型,下面一行是会话题目与细节 |
|
||||
| 窗口在**前台**,且正是你**在看的**那个会话 | 不打扰(你就在看着,不需要弹) |
|
||||
|
||||
每条只提醒一次:同一会话的同一轮只报一次完成,同一个待处理请求只报一次;请求消失后再来才会再报。
|
||||
轻弹窗的用法:
|
||||
|
||||
## 走哪个通道
|
||||
|
||||
| 状态 | 行为 |
|
||||
| --- | --- |
|
||||
| DSH 窗口**不在前台** | **系统通知**(这是插件唯一能拿到的系统通知通道,三个平台一致)。点通知:窗口回到前台并跳到该会话 |
|
||||
| DSH 窗口在前台,且**不是**你正在看的那个会话 | **应用内轻弹窗**:右上角悬浮,标题是提醒类型、下面一行是会话题目与细节;点「查看」跳过去,6 秒自动消失,鼠标悬停时不消失,Esc 或者 ✕ 关掉 |
|
||||
| DSH 窗口在前台,且就是你**正在看的**那个会话 | 不打扰(你在看,不需要弹) |
|
||||
- 点「查看」跳到该会话;
|
||||
- 6 秒后自动消失;鼠标停在上面期间不消失,移开后重新计时;
|
||||
- 按 `Esc` 关掉最新的一条,或点 ✕ 关掉这一条;
|
||||
- 同屏最多叠 3 条,更早的会被挤掉。
|
||||
|
||||
## 设置
|
||||
|
||||
**插件 → 会话通知**(插件自己的介绍页里):
|
||||
**插件 → 会话通知**:
|
||||
|
||||
- 三个开关分别控制**完成 / 授权 / 提问**三类提醒(默认全开),状态存在浏览器本地,重装插件不丢;
|
||||
- 系统通知权限状态;未授权时点「允许通知」请求权限(浏览器要求必须由你手动点击才能弹权限框),授权后自动发一条测试通知;权限被系统层关闭时按平台给出开启路径;
|
||||
- 「测试系统通知」直接走系统通知通道(窗口在前台也照发),专门用来验证系统通知本身是否可用;
|
||||
- 「运行状态」一段显示:窗口现在是前台还是后台(决定会走哪条通道)、观察器是否真的收到了会话状态、以及**最近一次投递走的通道与时间**。
|
||||
| 分组 | 内容 |
|
||||
| --- | --- |
|
||||
| 提醒内容 | **完成 / 授权 / 提问** 三个开关,分别控制三类提醒,默认全开;开关保存在浏览器本地,重开页面、重装插件都保留 |
|
||||
| 系统通知权限 | 当前权限状态;尚未授权时点「允许通知」请求授权(浏览器要求必须由你手动点击),授权成功后会自动发一条测试提醒。权限被系统层关闭时,会按当前平台告诉你去哪里打开 |
|
||||
| 运行状态 | 窗口现在是前台还是后台(即会走哪条通道)、插件是否真的在读会话状态、以及**最近一次提醒走的通道与时间**;旁边「测试提醒」按钮发一条测试提醒 |
|
||||
|
||||
设置放在插件自己的页面里,而不是「设置 → 通用」:它是这个插件的配置,不是 DSH 的通用偏好。页面顶部是 DSH 自己渲染的插件标题与描述,所以这块配置不再重复标题,直接用一句「提醒是怎么送出去的」开头。
|
||||
- 已经授权时,权限行的按钮变成「测试系统通知」:它直接走系统通知通道(窗口在前台也照发),专门用来验证系统通知本身是否可用。
|
||||
- 开关只影响提醒,不改 DSH 本身的任何设置。
|
||||
|
||||
## 安装
|
||||
|
||||
### 1. 从 Git 仓库安装(推荐)
|
||||
### 从 Git 仓库安装(推荐)
|
||||
|
||||
在 DSH 的 **插件 → 添加插件** 的上方输入框里填:
|
||||
|
||||
```text
|
||||
https://gitea.iwake.top/dsh-plugin/session-notify.git#v1.0.3
|
||||
https://gitea.iwake.top/dsh-plugin/session-notify.git#v1.0.5
|
||||
```
|
||||
|
||||
`#` 后面跟标签或提交,用来锁定版本;不写则取默认分支。跟随 1.x 最新版可以写 `#semver:^1.0.3`。仓库是公开的,不需要凭据,也不用改「安装源」。
|
||||
`#` 后面跟标签或提交,用来锁定版本;不写则取默认分支。跟随 1.x 最新版可以写 `#semver:^1.0.5`。仓库是公开的,不需要凭据,也不用改「安装源」。
|
||||
|
||||
### 2. 本地路径安装
|
||||
### 本地路径安装
|
||||
|
||||
把仓库克隆或下载到本机,在同一个输入框里填包目录的绝对路径,例如:
|
||||
|
||||
@@ -53,62 +64,32 @@ https://gitea.iwake.top/dsh-plugin/session-notify.git#v1.0.3
|
||||
D:\DeepSeek Harness Plugins\dsh-session-notify
|
||||
```
|
||||
|
||||
### 装完之后
|
||||
### 安装之后
|
||||
|
||||
- **浏览器半**随页面加载,**刷新页面**即生效;
|
||||
- **宿主半**是空壳(不改任何 DSH 状态、不注册服务与路由),只有它变化时才需要完全退出 DSH 再打开;
|
||||
- 本插件没有第三方依赖,不需要 pnpm 下载,也没有构建步骤。
|
||||
- 装好**刷新页面**即生效;本插件没有第三方依赖,也不需要 pnpm 下载或构建步骤。
|
||||
- 卸载:在插件页里移除 `@dsh-plugin/session-notify`。
|
||||
|
||||
卸载:插件页里移除 `@dsh-plugin/session-notify`(它同时是 profile 的一个 bundle)。
|
||||
## 提醒规则
|
||||
|
||||
## 平台说明与验证范围
|
||||
- **只在「运行中 → 空闲」的转变上提醒**:打开应用时已经在跑的会话只建立基线,不补发;历史里早已结束的会话不会被翻出来提醒。
|
||||
- **正在看的那个会话完成后不打扰**。
|
||||
- **子智能体的会话不单独提醒**,等它归属的主会话结束时才提醒。
|
||||
- **空白会话完成不提醒**。
|
||||
- **授权 / 提问如果出现的当下会话仍在运行,会先记下、等这一轮真正停下来再提醒**,不在模型还在跑的时候打扰你。
|
||||
- **节流**:1.5 秒内只投递一条,多个会话同时完成不会刷屏。
|
||||
- **完成提醒有 400ms 的确认窗口**:如果那一轮马上又跑起来,就不报了。
|
||||
- **同一会话的完成提醒会覆盖上一条**(通知带 `tag`),不叠加堆积。
|
||||
- 提醒只在 DSH 运行、页面打开时产生:**DSH 完全退出期间结束的会话不会再补发通知**。
|
||||
|
||||
- **通道是跨平台统一的**:插件的提醒都通过页面(Electron 渲染进程)的 `Notification` 构造器发出,Windows 通知中心 / macOS 通知中心 / Linux 通知守护(libnotify、GNOME、KDE)都由系统把它转成原生通知;应用内轻弹窗是纯 DOM,与平台无关。
|
||||
- **前台/后台的判定不依赖单一信号**:每次都现读页面的可见性与文档焦点(任一为"不可见"就算后台),不靠"记住上次的 blur 事件"——桌面外壳里漏掉一次 blur 曾让插件误判为前台而吃掉提醒(v1.0.5 修)。
|
||||
- **宿主半拿不到系统通知**:DSH Desktop 的宿主进程是纯 Node 进程(不是 Electron 主进程),没有 Electron 的 `Notification` 可用,所以插件的所有提醒都在浏览器半产生——这也正是"三个平台一套代码"的原因。
|
||||
- **已验证**:Windows 上的安装、三个 slot 条目注册、以及 28 项离线断言(接线 / 国际化 / 两种后台信号 / 系统通道被拒时的降级 / 配置页诊断 / 全部投递规则)。
|
||||
- **未验证**:macOS 与 Linux 上的实际弹窗效果本机无法测试。结构上它们与 Windows 共用同一条通道、同一份代码,只有"权限被系统关闭时显示的开启路径"是分平台的。
|
||||
- 提醒只在 DSH 进程运行、页面打开时产生:**DSH 完全退出期间结束的会话不会再补发通知**。
|
||||
## 平台
|
||||
|
||||
## 行为细节(都已验证)
|
||||
|
||||
- **只有观测到「运行中 → 空闲」的转变才提醒**:打开应用时已经在跑的会话只建立基线,不补发;历史里早已结束的会话不会被翻出来提醒。
|
||||
- **子智能体会话不单独提醒**(`origin === 'subagent'`),归属它的主会话结束时才提醒。
|
||||
- **新会话(空白会话)完成不提醒**。
|
||||
- **授权/提问在会话仍在运行时被延后提醒**:先记下,等这一轮真正停下来再报,避免在模型还在跑的时候就打扰你。
|
||||
- **节流**:1.5 秒内只投递一条,多个会话同时完成不会刷屏;完成提醒前有 400ms 的确认窗口,如果那一轮马上又跑起来就不报。
|
||||
- **同一会话的完成提醒会覆盖上一条**(通知带 `tag`),不堆叠。
|
||||
- Windows / macOS / Linux 都支持,三个平台走同一条通知通道,行为一致;应用内轻弹窗与平台无关。
|
||||
- 当前环境不支持系统通知时(权限一行会显示「不可用」),提醒仍然以应用内轻弹窗的形式送达。
|
||||
- 系统通知被拒绝或发送失败时,插件会改用轻弹窗,并把原因写在插件页的权限 / 状态那一段,不会静默失败。
|
||||
|
||||
## 兼容性
|
||||
|
||||
基于 **DeepSeek Harness 0.2.0-rc.2** 编写,遵循 DSH 插件规范:`dsh.manifestVersion: 1`、`dsh.bundle.patch` 声明宿主行、`dsh.client` 声明 `platform: "web"` 的浏览器半。
|
||||
|
||||
依赖的都是稳定契约:
|
||||
|
||||
- 浏览器半只依赖 **slot 的标准 props**(`useSessions`、`useSessionStatus`)读取会话状态,这是 DSH 官方给插件读会话数据的方式;不轮询、不自己订阅会话事件、不读别的插件的 DOM;
|
||||
- 只往两个官方 slot 注册:`plugins.bundle.config`(本插件在插件页里的配置,key 就是包名)与 `shell.overlay`(两个条目:轻弹窗层 + 无渲染的观察器,内容永远是 `null`);
|
||||
- **配置放在插件页**:`plugins.bundle.config` 的 key 取包名(`@dsh-plugin/session-notify`),插件页就会渲染这块配置;官方 `dsh-experimental-voice-input-bundle` 用的就是这个口子。行级口子是 `plugins.row.config`,key 形如 `<包名>#<行 id>`,会在该行上多出一个「配置」入口;
|
||||
- **不要**把"无渲染"条目放进 `sidebar.panellist`:该 slot 的宿主会把**每个条目的 id 当成一个左侧面板按钮**(`entriesOfSlot('sidebar.panellist')` → 面板列表,按钮文字取 `options.label ?? options.id`,条目本身作为图标内联渲染),放进去会在左侧多出一行空面板并挤坏侧边栏。本插件第一版踩过这个坑,现已改挂到通用浮层;
|
||||
- **文案必须注册字典**:`ctx.locale.register('session-notify', { zh, en })`,否则 `locale.bind(ns)` 在查不到该命名空间时会把 key 原样返回——界面上就会显示成 `settings.title` 这样的原始键(本插件第二版踩过这个坑)。注册会在 locale 修订号上打点,已经渲染出来的部件会自动换上文案,不需要刷新;
|
||||
- **前台/后台要现读、不能只靠事件**:桌面外壳里 `blur` 可能不到,只记事件会让插件一直以为在前台而吃掉系统通知(本插件第三版踩过这个坑)。现在每次投递都读 `document.visibilityState` 与 `document.hasFocus()`;
|
||||
- 另外自带一份本地字典兜底:即使拿不到框架的 `t`、或 locale 服务没有保存注册,也会渲染中文/英文文案而不是原始键;
|
||||
- 样式只用主题 token,不 import 任何 `@deepseek-ai/dsh-client-*` 包(规范要求,也是渲染不被上游改动打断的前提);
|
||||
- 宿主半不声明 `inject`、不注册服务、不注册路由;三个开关存浏览器本地,不改 DSH 的配置文件。
|
||||
|
||||
上游若改动 slot 名或 hook 名:注册会静默跳过而不是把页面弄坏,插件会退化成"不提醒";这类情况请按上面的契约名核对。
|
||||
|
||||
## 验证方式(开发记录)
|
||||
|
||||
`client.js` 是纯 JavaScript、浏览器端运行,可以在 Node 里用桩模块加载器评估并驱动:
|
||||
|
||||
- 模块接线:插件返回值、注册集合(含"配置挂在插件页""观察器绝不在 `sidebar.*` 里"这两条);
|
||||
- 国际化:字典中英键集合一致且没有死键、插件页与弹窗渲染出的每个字符串都不是原始键、拿不到框架 `t` 时本地字典兜底;
|
||||
- 前台/后台判定:**只给"页面不可见"信号**、或**只给"文档失焦"信号**(都不发 blur 事件)时,都必须走系统通知;
|
||||
- 系统通道被拒时降级:构造器抛错时改用轻弹窗,并在配置页写明被拒;
|
||||
- 配置页诊断:窗口状态、观察器健康、最近一次投递的通道与时间都能渲染;
|
||||
- 投递规则:完成提醒一次、当前会话不打扰、授权/提问各提醒一次、运行中延后、子会话跳过、空白会话跳过、历史不补发等。
|
||||
|
||||
合计 28 项断言。
|
||||
需要 **DeepSeek Harness 0.2.0-rc.2 或更高**。
|
||||
|
||||
## License
|
||||
|
||||
|
||||
Reference in New Issue
Block a user