@telosmaylx/dsh-session-notify 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +590 -0
- package/README.ja.md +590 -0
- package/README.ko.md +590 -0
- package/README.md +11 -4
- package/README.zh-TW.md +590 -0
- package/lib/client.js +17 -24
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
# dsh-session-notify
|
|
4
4
|
|
|
5
|
+
**简体中文** · [English](README.en.md) · [繁體中文](README.zh-TW.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
|
|
6
|
+
|
|
5
7
|
**DSH(DeepSeek Harness)会话完成提醒插件 —— 每一轮结束,让完成状态主动找你,而不是你盯着屏幕等。**
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
@@ -302,7 +304,7 @@ Session "重构登录模块" completed (took 3m25s, used 1,240 in / 3,560 out).
|
|
|
302
304
|
| 预设 | 下拉选择内置或自定义预设;「新增」把当前配置另存为自定义预设;当前预设可「删除」 |
|
|
303
305
|
| 语言 | 5 种语言单选,切换即时重渲染整个面板 |
|
|
304
306
|
| 推送方式 | 三选一:双通道(系统通知 + 页内提示,默认)/ 仅系统通知 / 仅页内提示 |
|
|
305
|
-
| 推送标题 |
|
|
307
|
+
| 推送标题 | 所有原因共用的标题模板(普通输入框,原生占位提示:输入才消失、清空恢复);留空时各原因用默认标题(完成=任务已完成、出错=任务出错、中止=任务已中止、阻塞=任务被阻塞、上限=任务达到输出上限);`{title}` 引用会话标题(点「+ 会话标题」在光标处插入) |
|
|
306
308
|
| 模板 × 5 | 每条结束原因(完成、出错、中止、阻塞、输出上限)独立一个 Chip 编辑器:文字 + 内联信息胶囊,光标处插入、点击移除、实时预览 |
|
|
307
309
|
| 跳过子代理会话 | 复选框(保存时一并写入设置文档) |
|
|
308
310
|
| 通知权限 | 状态实时显示:已授权(绿)/ 尚未授权(附「请求授权」按钮)/ 已被浏览器屏蔽(附地址栏操作指引)/ 环境不支持 |
|
|
@@ -311,7 +313,7 @@ Session "重构登录模块" completed (took 3m25s, used 1,240 in / 3,560 out).
|
|
|
311
313
|
| 重置 | 一键还原默认值(**语言保留当前选择**,标题/模板/推送方式恢复默认)并立即保存 |
|
|
312
314
|
|
|
313
315
|
> [!NOTE]
|
|
314
|
-
> 「推送方式」的取舍:`dual`(默认)同时弹 Windows 系统通知与页内 toast,toast 是保底通道,防止系统通知被平台静默(专注助手、通知横幅关闭)。但 QQ
|
|
316
|
+
> 「推送方式」的取舍:`dual`(默认)同时弹 Windows 系统通知与页内 toast,toast 是保底通道,防止系统通知被平台静默(专注助手、通知横幅关闭)。但 **QQ 浏览器等国产 Chromium 壳浏览器会把 `Notification` 渲染成「浏览器内置的页内推送弹窗」**(页面顶部/角落的横幅,不经 Windows 通知中心)——此时 `dual` 会造成页内两个提示(浏览器内置弹窗 + 插件 toast)。这类浏览器请选「仅页内提示」(不再调用 `Notification`,浏览器内置弹窗不会出现,页内只有插件自己的小 toast);「仅系统通知」模式在 QQ 浏览器无效(它永远渲染为页内弹窗)。设置面板每个原因的「发送」测试按钮同样受此影响。
|
|
315
317
|
|
|
316
318
|
> [!NOTE]
|
|
317
319
|
> 系统通知(`Notification` API)能否弹出由**浏览器与站点访问方式**共同决定:Edge/Chrome 对"不熟悉"的站点会**自动屏蔽通知**(地址栏出现「通知已屏蔽」)——点击地址栏左侧权限图标 → 网站设置 → 通知 → 允许即可恢复;`http://IP` 这类非安全上下文访问时 `Notification` 根本不存在,请改用「仅页内提示」。设置面板「通知权限」区域会实时显示当前状态并给出对应操作指引(可一键请求授权)。Firefox 窗口聚焦时通知显示为页内横幅、失焦才进系统通知中心。
|
|
@@ -521,12 +523,16 @@ node scripts/verify-notice.mjs <session.jsonl.zstd>
|
|
|
521
523
|
</details>
|
|
522
524
|
|
|
523
525
|
<details>
|
|
524
|
-
<summary><b>为什么 Edge 推不了系统通知?QQ
|
|
526
|
+
<summary><b>为什么 Edge 推不了系统通知?QQ 浏览器为什么只有页内横幅(内置推送弹窗)?</b></summary>
|
|
525
527
|
|
|
526
528
|
两者都是浏览器行为,插件无法强制:
|
|
527
529
|
|
|
528
530
|
- **Edge / Chrome**:对"不熟悉"的站点会**自动屏蔽通知**(地址栏出现「通知已屏蔽」)。点击地址栏左侧权限图标 → 网站设置 → 通知 → 允许即可恢复,之后正常弹 Windows 通知中心。也可在浏览器通知设置中关闭「自动屏蔽」。
|
|
529
|
-
- **QQ 浏览器等国产 Chromium 壳**:把 `Notification`
|
|
531
|
+
- **QQ 浏览器等国产 Chromium 壳**:把 `Notification` 固定渲染为**浏览器内置的页内推送弹窗**(页面顶部/角落横幅,不经 Windows 通知中心),且无系统通知选项。三种推送方式的实际表现:
|
|
532
|
+
- `双通道` → 浏览器内置弹窗 + 插件 toast,页内两个提示;
|
|
533
|
+
- `仅系统通知` → 无效(QQ 浏览器永远渲染为页内弹窗);
|
|
534
|
+
- `仅页内提示` → 浏览器内置弹窗不出现,页内只有插件自带的小 toast(推荐)。
|
|
535
|
+
设置面板每个原因的「发送」测试按钮同样按此规则渲染。
|
|
530
536
|
- **Firefox**:窗口聚焦时通知显示为页内横幅,失焦/最小化才进系统通知中心;权限需在地址栏手动允许。
|
|
531
537
|
- 另注意:`http://IP` 访问(非安全上下文)时 `Notification` 不存在,任何浏览器都弹不了系统通知。
|
|
532
538
|
|
|
@@ -540,6 +546,7 @@ node scripts/verify-notice.mjs <session.jsonl.zstd>
|
|
|
540
546
|
|
|
541
547
|
| 版本 | 日期 | 变更 |
|
|
542
548
|
| --- | --- | --- |
|
|
549
|
+
| **0.1.10** | 2026-08-29 | 「推送标题」改为原生输入框(原生占位提示:不可复制、输入才消失、清空恢复;「+ 会话标题」在光标处插入 `{title}`);文档补充 QQ 浏览器内置推送弹窗说明(三种推送方式的实际表现 + 发送按钮测试同规则);**多语言 README**:中文设为主页,新增 English / 繁體中文 / 日本語 / 한국어 版本(顶部语言切换互链) |
|
|
543
550
|
| **0.1.9** | 2026-08-29 | 推送标题支持**按原因定制**(折叠区 UI,默认收起不臃肿;留空时各原因用差异化默认标题:任务已完成/任务出错/任务已中止/任务被阻塞/任务达到输出上限,5 语言);投影升级为对象(kind/text/title)承载 host 渲染好的标题;重置按钮**保留当前语言**;默认文案内嵌「会话标题」标签(会话「{title}」已完成,无标题自动回退);设置面板模板预览同步;「+插入信息」插入标签后不再自动折叠;删除当前使用的自定义预设自动切回默认;模板预览修复(点击不消失、输入才隐藏、清空恢复);每个原因新增「发送」按钮(一键发当前模板渲染的测试通知) |
|
|
544
551
|
| **0.1.8** | 2026-08-29 | 默认推送标题改为「任务已完成」(`{title}` 仍可引用会话标题);默认文案按结束原因差异化表达(完成紧凑括号式 / 中止·阻塞拆句 / 出错错误前置 / 上限附建议,5 语言);设置面板新增「重置」按钮一键还原默认 |
|
|
545
552
|
| **0.1.7** | 2026-08-29 | 修复 0.1.6 的设置卡片崩溃:`notificationPermissionRow`/`requestPermissionNow` 曾引用 Card 组件内 state(作用域外)导致渲染 ReferenceError、整个设置卡片消失;改为自包含 + 回调传参 |
|
package/README.zh-TW.md
ADDED
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# dsh-session-notify
|
|
4
|
+
|
|
5
|
+
[简体中文](README.md) · [English](README.en.md) · **繁體中文** · [日本語](README.ja.md) · [한국어](README.ko.md)
|
|
6
|
+
|
|
7
|
+
**DSH(DeepSeek Harness)會話完成提醒外掛 —— 每一輪結束,讓完成狀態主動找你,而不是你盯著畫面等。**
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
10
|
+
[](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
11
|
+
[](./LICENSE)
|
|
12
|
+
[](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
13
|
+
[](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
14
|
+
[](https://github.com/TelosmaYLX/dsh-session-notify/pulls)
|
|
15
|
+
|
|
16
|
+
每輪對話結束時,把「已完成 / 出錯 / 被阻塞 / 達到上限」連同用時、token 消耗寫入會話日誌,並推送瀏覽器系統通知與頁內 toast。內建 5 種語言、視覺化文案模板編輯器、自訂預設庫,快取命中率與生成速度取自官方投影,與狀態列同口徑。
|
|
17
|
+
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 目錄
|
|
23
|
+
|
|
24
|
+
- [功能特色](#功能特色)
|
|
25
|
+
- [環境需求](#環境需求)
|
|
26
|
+
- [安裝](#安裝)
|
|
27
|
+
- [解除安裝](#解除安裝)
|
|
28
|
+
- [快速開始](#快速開始)
|
|
29
|
+
- [通知行為](#通知行為)
|
|
30
|
+
- [觸發條件](#觸發條件)
|
|
31
|
+
- [推送內文從哪來](#推送內文從哪來)
|
|
32
|
+
- [通知範例](#通知範例)
|
|
33
|
+
- [通知權限](#通知權限)
|
|
34
|
+
- [設定](#設定)
|
|
35
|
+
- [設定面板](#設定面板)
|
|
36
|
+
- [文案模板與佔位符](#文案模板與佔位符)
|
|
37
|
+
- [預設系統](#預設系統)
|
|
38
|
+
- [宿主設定項](#宿主設定項)
|
|
39
|
+
- [運作原理](#運作原理)
|
|
40
|
+
- [專案結構](#專案結構)
|
|
41
|
+
- [開發與除錯](#開發與除錯)
|
|
42
|
+
- [常見問題](#常見問題)
|
|
43
|
+
- [更新紀錄](#更新紀錄)
|
|
44
|
+
- [貢獻](#貢獻)
|
|
45
|
+
- [相關連結](#相關連結)
|
|
46
|
+
- [授權條款](#授權條款)
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 功能特色
|
|
51
|
+
|
|
52
|
+
### 三通道提醒,一條不漏
|
|
53
|
+
|
|
54
|
+
| 通道 | 形式 | 說明 |
|
|
55
|
+
| --- | --- | --- |
|
|
56
|
+
| 會話內系統訊息 | 可收合的提示列 | 每輪結束把結束原因與用時、消耗作為外掛來源的系統訊息附加進會話日誌,隨 JSONL 寫入磁碟,還原或重播會話後依然可見。 |
|
|
57
|
+
| 瀏覽器系統通知 | Web Notification | 原生彈出視窗。每次完成事件使用獨立 `tag`(`dsh-session-notify:<timestamp>`),不會與前一次互相取代,也不會被收合成一個分組項目;點擊通知聚焦回視窗。 |
|
|
58
|
+
| 頁內 toast | 右下角浮動彈出視窗 | 永遠顯示的保底通道:系統通知被平台靜默、權限拒絕或環境不支援時仍有可見回饋。同畫面最多 3 條(超出移除最舊),10 秒自動消失,點擊關閉。 |
|
|
59
|
+
|
|
60
|
+
### 背景會話全覆蓋
|
|
61
|
+
|
|
62
|
+
- 宿主為所有會話(含背景、未開啟視窗的)維護「最近一則通知內文」的會話投影單元(key = `session-complete-notify`),推送內文跨會話一致,不依賴你剛好開著那個視窗。
|
|
63
|
+
- 用戶端從會話清單快照觀測所有會話的 `running` 位元,`true → false` 邊緣即觸發推送,與官方 sidebar 提醒同策略(首次觀測只記錄基線,已在 idle 的會話不補發)。
|
|
64
|
+
|
|
65
|
+
### 可自訂到每一句話
|
|
66
|
+
|
|
67
|
+
- **5 種語言**:簡體中文、繁體中文、English、日本語、한국어 —— 通知文案、時長與用量措辭、設定面板介面全部隨語言切換(切換即時重渲染)。
|
|
68
|
+
- **視覺化模板編輯器**(Chip 膠囊編輯器):動態資訊渲染為內聯膠囊(佔位符程式碼不露出),「+ 插入資訊」在游標處插入(可插到文字中間),點擊膠囊移除,每欄帶即時預覽(資訊以範例值流入內文)。
|
|
69
|
+
- **預設系統**:內建「預設」預設作為基線;目前設定可另存為自訂預設(`localStorage` 持久化),支援自動編號的未命名預設(`未命名`、`未命名 2`…)、「來自:xxx · 已修改」來源指示、刪除預設。
|
|
70
|
+
- **推送標題模板**:留空時各原因用預設標題(完成=任務已完成 / 出錯=任務出錯 / …);`{title}` 引用會話標題。
|
|
71
|
+
|
|
72
|
+
### 與官方口徑同源
|
|
73
|
+
|
|
74
|
+
- **快取命中率**取自官方 `tokenUsage` 投影:快取讀 /(未快取輸入 + 快取讀 + 快取寫)。
|
|
75
|
+
- **生成速度**取自官方 `sessionStats` 投影:輸出 token ÷ 解碼耗時。
|
|
76
|
+
- 兩者與 dsh-web-ui 狀態列完全同口徑,不含排隊、準備、工具時間;投影不可用或資料未就緒時自動回退為本地用量彙總估算。
|
|
77
|
+
|
|
78
|
+
> [!NOTE]
|
|
79
|
+
> 快取命中率與速度只在自訂模板中透過 `{cache}`、`{tps}` 佔位符插入時才顯示。使用內建預設文案時,內文只含用時與消耗。
|
|
80
|
+
|
|
81
|
+
### 工程品質
|
|
82
|
+
|
|
83
|
+
- **只回應即時事件**:resume、replay 不重播舊通知,載入會話不洗版。
|
|
84
|
+
- **自免疫迴圈**:外掛附加的訊息類型(`user/message`)與自身監聽目標(`turn/*`)不相交。
|
|
85
|
+
- **零外部依賴**:宿主平面零裸 import,UserMessage 按 `dsh-llm` 的 `createUserMessage` 契約手工構造;純邏輯層(`lib/core.js`)零依賴,可獨立測試。
|
|
86
|
+
- **Cordis effect 紀律**:重試計時器包裝在 `ctx.effect()` 中並回傳 `clearTimeout` disposer,註冊隨 fiber 卸載自動撤銷,HMR 熱重載安全。
|
|
87
|
+
- **安裝即掛載**:宣告官方 `dsh.bundle` manifest,`dsh plugin add` 一條指令裝完即用,無需手寫 patch。
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 環境需求
|
|
92
|
+
|
|
93
|
+
| 依賴 | 需求 |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| DSH(DeepSeek Harness) | Web profile 部署。官方 base bundle 預設包含 `@deepseek-ai/dsh-settings`(設定命名空間)與會話投影,無需額外設定 |
|
|
96
|
+
| cordis | `>=4.0.0-rc <5`(peer dependency,由宿主提供) |
|
|
97
|
+
| Node.js | `>=22`(宿主側) |
|
|
98
|
+
| 瀏覽器 | 支援 Web Notification 則有系統通知;不支援、權限拒絕或被靜默時由 toast 保底 |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 安裝
|
|
103
|
+
|
|
104
|
+
> [!WARNING]
|
|
105
|
+
> 裸 `npm install` 只會把套件裝進依賴樹,**不會註冊外掛** —— 這是 DSH 官方設計(`npm install only adds the dependency; it does not register the plugin`)。自動掛載的唯一官方途徑是 `dsh plugin add`:它讀取套件內 `dsh.bundle` manifest(此外掛自 0.1.3 起宣告,指向儲存庫根 `cordis.patch.yml`)並自動套用。
|
|
106
|
+
|
|
107
|
+
### 方式一:dsh plugin add(推薦)
|
|
108
|
+
|
|
109
|
+
安裝套件的同時自動套用 `cordis.patch.yml`,把外掛掛載進 profile 組合(host 事件訂閱 + client 啟動圖注入)。
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
dsh plugin --profile web add @telosmaylx/dsh-session-notify
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 方式二:從 GitHub 儲存庫安裝
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
dsh plugin add github:TelosmaYLX/dsh-session-notify
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
也可以在 DSH Web GUI 會話內執行:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
dev_install_package github=TelosmaYLX/dsh-session-notify
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### 方式三:本地目錄熱掛載(開發用)
|
|
128
|
+
|
|
129
|
+
把路徑換成你的克隆目錄,在 DSH Web GUI 會話內執行:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
dev_install_package dir=/你的/克隆目录/dsh-session-notify
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### 方式四:npm 套件手動安裝
|
|
136
|
+
|
|
137
|
+
先打包:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
npm pack @telosmaylx/dsh-session-notify
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
解壓縮後指定目錄安裝(在 DSH Web GUI 會話內執行):
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
dev_install_package dir=/解压/目录/package
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 方式五:手動 cordis patch(不依賴安裝器)
|
|
150
|
+
|
|
151
|
+
在 `~/.dsh/profiles/web/cordis.patch.yml` 附加:
|
|
152
|
+
|
|
153
|
+
```yaml
|
|
154
|
+
- insert:
|
|
155
|
+
- id: dsh-session-notify
|
|
156
|
+
name: '@telosmaylx/dsh-session-notify'
|
|
157
|
+
config: {}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> [!IMPORTANT]
|
|
161
|
+
> 無論用哪種方式,裝完都需要**重新整理一次瀏覽器頁面** —— 用戶端 bundle 透過 `__DSH_BOOT__` 啟動圖注入。
|
|
162
|
+
|
|
163
|
+
## 解除安裝
|
|
164
|
+
|
|
165
|
+
一條指令移除外掛及其掛載(自動從 `cordis.patch.yml` 移除 insert 項目):
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
dsh plugin --profile web remove @telosmaylx/dsh-session-notify
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
> [!NOTE]
|
|
172
|
+
> 手動安裝(方式四/五)的使用者,需同步從 `~/.dsh/profiles/web/cordis.patch.yml` 刪除對應 insert 項目,再重新整理頁面。
|
|
173
|
+
|
|
174
|
+
### 解除安裝時自動清理的內容
|
|
175
|
+
|
|
176
|
+
外掛實作了完整的生命週期收尾(Cordis effect 紀律),解除安裝/停用/HMR 熱重載時:
|
|
177
|
+
|
|
178
|
+
| 平面 | 自動釋放的資源 |
|
|
179
|
+
| --- | --- |
|
|
180
|
+
| host | `session/event` 事件訂閱、settings 命名空間、會話投影單元、設定註冊重試計時器(`ctx.effect` 包裝);置解除安裝旗標抑制已排程的微任務附加 |
|
|
181
|
+
| client | 會話清單訂閱、完成推送內文的輪詢計時器、`window.__dsch_notify_debug` 除錯鉤子(按參考刪除,防閉包洩漏)、頁內 toast 容器 DOM |
|
|
182
|
+
|
|
183
|
+
### 解除安裝後保留的資料
|
|
184
|
+
|
|
185
|
+
- **設定組態**(語言、文案模板)留在 settings 文件,重裝後自動恢復;
|
|
186
|
+
- **自訂預設**存於瀏覽器 `localStorage`(`dsh-scn-custom-presets`),重裝後仍在;
|
|
187
|
+
- 歷史會話中已附加的系統訊息與 JSONL 日誌**不會**被回滾(它們是會話資料的一部分,與官方側邊欄提示同語意)。
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 快速開始
|
|
192
|
+
|
|
193
|
+
1. 按上面任一方式安裝並重新整理頁面。
|
|
194
|
+
2. 發起任意一輪對話,等它結束 —— 右下角彈出 toast、瀏覽器彈系統通知、會話日誌裡出現可收合的系統提示列。
|
|
195
|
+
3. 首次收到完成事件時,瀏覽器會請求通知權限(每頁只問一次),允許後後續完成都有系統通知。
|
|
196
|
+
4. 開啟 **設定 → 外掛 → 會話完成提醒**,切換語言、編輯文案模板、另存預設。儲存後點「點擊重新整理」讓宿主與用戶端兩側重新讀取,新設定即生效。
|
|
197
|
+
|
|
198
|
+
剛裝好時,會話日誌裡會出現這樣一行可收合提示:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
会话「重构登录模块」已完成(用时 1 分 12 秒,消耗 1,240 输入 / 3,560 输出)。
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
> 預設文案在「會話」後內嵌會話標題標籤(`{title}`);會話無標題時自動退回「會話已完成」。
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## 通知行為
|
|
209
|
+
|
|
210
|
+
### 觸發條件
|
|
211
|
+
|
|
212
|
+
每輪對話結束(`turn/end`)時按結束原因判斷,命中白名單即提醒:
|
|
213
|
+
|
|
214
|
+
| 結束原因 | 含義 | 預設 |
|
|
215
|
+
| --- | --- | --- |
|
|
216
|
+
| `completed` | 會話正常完成 | 提醒 |
|
|
217
|
+
| `aborted` | 會話中止 | 提醒 |
|
|
218
|
+
| `blocked` | 會話被阻塞 | 提醒 |
|
|
219
|
+
| `error` | 會話出錯(附錯誤詳情,超長截斷) | 提醒 |
|
|
220
|
+
| `max-tokens` | 達到輸出 token 上限 | 提醒 |
|
|
221
|
+
| `interrupted` | 中斷(崩潰復原後由持久化後端補寫的孤兒輪次關閉標記) | 不提醒(可設定加入) |
|
|
222
|
+
|
|
223
|
+
**子代理會話預設跳過**(`header.origin === 'subagent'` 或 `delegationDepth > 0`)—— 子代理由父會話編排,逐輪提醒是噪音;可在宿主設定關閉跳過。
|
|
224
|
+
|
|
225
|
+
### 推送內文從哪來
|
|
226
|
+
|
|
227
|
+
用戶端在會話清單觀測到 `running: true → false` 邊緣時推送,內文按以下優先級取得(最長輪詢 6 秒,400ms 間隔):
|
|
228
|
+
|
|
229
|
+
1. **宿主投影**(key = `session-complete-notify`)—— 每個會話都有,背景會話同樣拿到全文;
|
|
230
|
+
2. **會話事件視窗裡的 notice 節點**(`kind=context` + `form=notice`)—— 正在查看的會話,寫入磁碟後立即可用;
|
|
231
|
+
3. **降級** —— 「詳情見會話內系統訊息」+ 工作區資訊(`cwd` 最後一段)。
|
|
232
|
+
|
|
233
|
+
### 通知範例
|
|
234
|
+
|
|
235
|
+
以下均由 `lib/core.js` 的 `buildNotice` 實際生成。預設文案按結束原因**差異化表達**(非清一色句式):
|
|
236
|
+
|
|
237
|
+
簡體中文預設文案:
|
|
238
|
+
|
|
239
|
+
```text
|
|
240
|
+
会话「重构登录模块」已完成(用时 3 分 25 秒,消耗 12,400 输入 / 35,600 输出)。 ← 完成:括号紧凑式 + 内嵌会话标题
|
|
241
|
+
会话「重构登录模块」已中止。用时 3 分 25 秒,消耗 12,400 输入 / 35,600 输出。 ← 中止:句号拆句
|
|
242
|
+
会话「重构登录模块」被阻塞。用时 3 分 25 秒,消耗 12,400 输入 / 35,600 输出。 ← 阻塞:句号拆句
|
|
243
|
+
会话「重构登录模块」达到输出上限。用时 3 分 25 秒,消耗 12,400 输入 / 35,600 输出,建议拆分任务后重试。 ← 上限:附建议
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
> 會話無標題(`titleValue` 為空)時自動退回不帶標題的句式,如「會話已完成(用時 …)」。
|
|
247
|
+
|
|
248
|
+
出錯時錯誤詳情前置(單行化,超過 40 字元截斷):
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
会话「重构登录模块」出错:connection timeout(用时 12 秒)。
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
English 預設文案(會話標題用雙引號):
|
|
255
|
+
|
|
256
|
+
```text
|
|
257
|
+
Session "重构登录模块" completed (took 3m25s, used 12,400 in / 35,600 out).
|
|
258
|
+
Session "重构登录模块" hit the output-token cap. Took 3m25s, used 12,400 in / 35,600 out — consider splitting the task.
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
自訂模板(在設定面板編輯,本例用到全部資訊位):
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
{title} 干完了!用时 {duration},消耗 {usage},缓存命中 {cache},速度 {tps}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
渲染結果:
|
|
268
|
+
|
|
269
|
+
```text
|
|
270
|
+
重构登录模块 干完了!用时 3 分 25 秒,消耗 103,600 输入 / 35,600 输出,缓存命中 96.5%,速度 92 tok/s
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
五種語言的同一事件:
|
|
274
|
+
|
|
275
|
+
```text
|
|
276
|
+
会话「重构登录模块」已完成(用时 3 分 25 秒,消耗 1,240 输入 / 3,560 输出)。
|
|
277
|
+
會話「重構登入模組」已完成(用時 3 分 25 秒,消耗 1,240 輸入 / 3,560 輸出)。
|
|
278
|
+
Session "重构登录模块" completed (took 3m25s, used 1,240 in / 3,560 out).
|
|
279
|
+
セッション「重构登录模块」完了(所要 3 分 25 秒、消費 1,240 入力 / 3,560 出力)。
|
|
280
|
+
세션「重构登录模块」 완료(소요 3분 25초, 소모 1,240 입력 / 3,560 출력)。
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### 通知權限
|
|
284
|
+
|
|
285
|
+
| 權限狀態 | 行為 |
|
|
286
|
+
| --- | --- |
|
|
287
|
+
| `default`(未決定) | 完成事件只發 toast;設定面板「通知權限」區提供「請求授權」按鈕(**使用者手勢內請求**——Chromium 會忽略非手勢的自動請求,因此外掛不再自動請求) |
|
|
288
|
+
| `granted` | 按「推送方式」發系統通知(獨立 tag,互不覆蓋) |
|
|
289
|
+
| `denied`(被瀏覽器封鎖) | 僅 toast;設定面板顯示網址列操作指引(權限圖示 → 網站設定 → 通知 → 允許) |
|
|
290
|
+
| `undefined`(非安全上下文 / 不支援) | 僅 toast;建議改用「僅頁內提示」 |
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## 設定
|
|
295
|
+
|
|
296
|
+
絕大多數設定在 **DSH Web UI → 設定 → 外掛 → 會話完成提醒** 面板完成(儲存後點「點擊重新整理」生效)。僅「觸發原因白名單」與「跳過子代理」兩項在宿主 `cordis.patch.yml` 的 `config` 中設定。
|
|
297
|
+
|
|
298
|
+
### 設定面板
|
|
299
|
+
|
|
300
|
+
面板在官方「設定 → 外掛」面板中註冊(`settings.plugin.item` keyed slot,key = `session-complete-notify`),樣式逐值復刻原生外掛卡片(12px 圓角、展開收合、旋轉 chevron、footer 狀態位 + 棄置 ghost + 主色儲存按鈕):
|
|
301
|
+
|
|
302
|
+
| 區域 | 內容 |
|
|
303
|
+
| --- | --- |
|
|
304
|
+
| 預設 | 下拉選擇內建或自訂預設;「新增」把目前設定另存為自訂預設;目前預設可「刪除」 |
|
|
305
|
+
| 語言 | 5 種語言單選,切換即時重渲染整個面板 |
|
|
306
|
+
| 推送方式 | 三選一:雙通道(系統通知 + 頁內提示,預設)/ 僅系統通知 / 僅頁內提示 |
|
|
307
|
+
| 推送標題 | 所有原因共用的標題模板(普通輸入框,原生佔位提示:輸入才消失、清空恢復);留空時各原因用預設標題(完成=任務已完成、出錯=任務出錯、中止=任務已中止、阻塞=任務被阻塞、上限=任務達到輸出上限);`{title}` 引用會話標題(點「+ 會話標題」在游標處插入) |
|
|
308
|
+
| 模板 × 5 | 每條結束原因(完成、出錯、中止、阻塞、輸出上限)獨立一個 Chip 編輯器:文字 + 內聯資訊膠囊,游標處插入、點擊移除、即時預覽 |
|
|
309
|
+
| 跳過子代理會話 | 核取方塊(儲存時一併寫入設定文件) |
|
|
310
|
+
| 通知權限 | 狀態即時顯示:已授權(綠)/ 尚未授權(附「請求授權」按鈕)/ 已被瀏覽器封鎖(附網址列操作指引)/ 環境不支援 |
|
|
311
|
+
| 按原因自訂標題 | 收合區(預設收合):每個結束原因一個獨立標題輸入框,留空 = 用全域模板或語言預設標題 |
|
|
312
|
+
| 儲存 | 寫入宿主設定文件(`language` / `templates` / `titleTemplate` / `titleTemplates` / `pushMode`);儲存後顯示「點擊重新整理」連結 |
|
|
313
|
+
| 重置 | 一鍵還原預設值(**語言保留目前選擇**,標題/模板/推送方式恢復預設)並立即儲存 |
|
|
314
|
+
|
|
315
|
+
> [!NOTE]
|
|
316
|
+
> 「推送方式」的取捨:`dual`(預設)同時彈 Windows 系統通知與頁內 toast,toast 是保底通道,防止系統通知被平台靜默(專注小幫手、通知橫幅關閉)。但 **QQ 瀏覽器等國產 Chromium 殼瀏覽器會把 `Notification` 渲染成「瀏覽器內建的頁內推送彈出視窗」**(頁面頂部/角落的橫幅,不經 Windows 通知中心)——此時 `dual` 會造成頁內兩個提示(瀏覽器內建彈出視窗 + 外掛 toast)。這類瀏覽器請選「僅頁內提示」(不再呼叫 `Notification`,瀏覽器內建彈出視窗不會出現,頁內只有外掛自己的小 toast);「僅系統通知」模式在 QQ 瀏覽器無效(它永遠渲染為頁內彈出視窗)。設定面板每個原因的「傳送」測試按鈕同樣受此影響。
|
|
317
|
+
|
|
318
|
+
> [!NOTE]
|
|
319
|
+
> 系統通知(`Notification` API)能否彈出由**瀏覽器與網站存取方式**共同決定:Edge/Chrome 對"不熟悉"的網站會**自動封鎖通知**(網址列出現「通知已封鎖」)——點擊網址列左側權限圖示 → 網站設定 → 通知 → 允許即可恢復;`http://IP` 這類非安全上下文存取時 `Notification` 根本不存在,請改用「僅頁內提示」。設定面板「通知權限」區域會即時顯示目前狀態並給出對應操作指引(可一鍵請求授權)。Firefox 視窗聚焦時通知顯示為頁內橫幅、失焦才進系統通知中心。
|
|
320
|
+
|
|
321
|
+
> [!NOTE]
|
|
322
|
+
> 面板中「跳過子代理會話」儲存的是設定文件裡的布林值;宿主 `cordis.patch.yml` 的 `config.skipSubagents` 是其啟動預設值,兩者任一為真即跳過。
|
|
323
|
+
|
|
324
|
+
### 文案模板與佔位符
|
|
325
|
+
|
|
326
|
+
每條結束原因獨立一個模板輸入框,**標籤即開關** —— 在模板裡插入對應資訊標籤,該項資料才會顯示:
|
|
327
|
+
|
|
328
|
+
| 佔位符 | 含義 | 範例值 |
|
|
329
|
+
| --- | --- | --- |
|
|
330
|
+
| `{title}` | 會話標題(推送標題模板也可用) | `重構登入模組` |
|
|
331
|
+
| `{duration}` | 本輪用時(`turn/start` 起表 → `turn/end` 結束) | `3 分 25 秒` / `3m25s` |
|
|
332
|
+
| `{usage}` | token 消耗(輸入 = 未快取 + 快取讀 + 快取寫) | `1,240 輸入 / 3,560 輸出` |
|
|
333
|
+
| `{error}` | 錯誤資訊(無錯誤時顯示 `none`;單行化,80 字元截斷) | `connection timeout` |
|
|
334
|
+
| `{cache}` | 快取命中率(官方投影口徑,無資料為空) | `96.5%` |
|
|
335
|
+
| `{tps}` | 生成速度(官方投影口徑,無資料為空) | `92 tok/s` |
|
|
336
|
+
| `{label}` | 已廢棄 —— 渲染時自動剝除,舊模板仍相容(插入選單已移除該選項) | — |
|
|
337
|
+
|
|
338
|
+
模板留空即使用內建預設文案(自動帶用時與消耗)。收合行 `summary` 與內文同源(渲染結果截斷至 120 字元)—— 只看收合行的使用者也能看到真實標題與用時、消耗。
|
|
339
|
+
|
|
340
|
+
### 預設系統
|
|
341
|
+
|
|
342
|
+
- **內建預設**:僅「預設」,作為基線。
|
|
343
|
+
- **自訂預設**:儲存在 `localStorage`(key = `dsh-scn-custom-presets`):
|
|
344
|
+
- 「新增」命名後儲存為自訂預設;儲存後可「修改」自動同步、「刪除」移除;
|
|
345
|
+
- **自動編號的未命名預設**:從「預設 / 空白」直接儲存時,自動生成 `未命名`、`未命名 2`、`未命名 3`…(編號取目前最大值 + 1);
|
|
346
|
+
- 表單顯示「來自:xxx · 已修改」來源指示(來自預設但內容已改動時)。
|
|
347
|
+
- **儲存即同步**:儲存時若表單來源是自訂預設則更新該預設,否則新建或繼續編號未命名預設。
|
|
348
|
+
|
|
349
|
+
### 宿主設定項
|
|
350
|
+
|
|
351
|
+
```yaml
|
|
352
|
+
- insert:
|
|
353
|
+
- id: dsh-session-notify
|
|
354
|
+
name: '@telosmaylx/dsh-session-notify'
|
|
355
|
+
config:
|
|
356
|
+
reasons: [completed, aborted, blocked, error, max-tokens]
|
|
357
|
+
skipSubagents: true
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
| 欄位 | 型別 | 預設值 | 說明 |
|
|
361
|
+
| --- | --- | --- | --- |
|
|
362
|
+
| `reasons` | `string[]` | `[completed, aborted, blocked, error, max-tokens]` | 觸發提醒的 `turn/end` 原因白名單 |
|
|
363
|
+
| `skipSubagents` | `boolean` | `true` | 跳過子代理會話(`origin=subagent` 或 `delegationDepth>0`) |
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 運作原理
|
|
368
|
+
|
|
369
|
+
外掛分**宿主平面**(Node)與**用戶端平面**(瀏覽器),中間靠會話日誌(JSONL)與官方會話投影銜接:
|
|
370
|
+
|
|
371
|
+
```text
|
|
372
|
+
┌─────────────────── 宿主平面(lib/index.js,Node)──────────────────┐
|
|
373
|
+
│ │
|
|
374
|
+
│ session/event 火线 │
|
|
375
|
+
│ ├─ turn/start → tracker 起表(key: sessionId:turn) │
|
|
376
|
+
│ ├─ assistant/message → 累加该轮 token 用量 │
|
|
377
|
+
│ └─ turn/end → reason.kind ∈ reasons ? │
|
|
378
|
+
│ ├─ 子代理会话?跳过 │
|
|
379
|
+
│ ├─ 读官方投影:cache / tps / title │
|
|
380
|
+
│ ├─ 按语言+模板构建通知(summary ≤120 字) │
|
|
381
|
+
│ └─ queueMicrotask 追加系统消息 │
|
|
382
|
+
│ (避开 append 重入窗口) │
|
|
383
|
+
│ │
|
|
384
|
+
│ settings.register → 官方「设置 → 插件」命名空间(失败退避重试) │
|
|
385
|
+
│ sessionProjections → 注册投影单元(key=session-complete-notify) │
|
|
386
|
+
└──────────────────────────────┬──────────────────────────────────────┘
|
|
387
|
+
│ user/message (source: plugin, form: notice)
|
|
388
|
+
▼ JSONL 持久化 + 投影推送
|
|
389
|
+
┌─────────────────── 客户端平面(lib/client.js,浏览器)──────────────┐
|
|
390
|
+
│ │
|
|
391
|
+
│ 会话列表订阅:running true → false 边沿 → pushCompletion │
|
|
392
|
+
│ ├─ 取正文:投影 → 事件窗口 notice → 降级(轮询 ≤6s) │
|
|
393
|
+
│ ├─ Web Notification(独立 tag,点击聚焦) │
|
|
394
|
+
│ └─ 页内 toast(永远展示,≤3 条,10s 自动消失) │
|
|
395
|
+
│ │
|
|
396
|
+
│ slots.inject('settings.plugin.item') → 设置卡片(预设/语言/模板) │
|
|
397
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### 關鍵設計決策
|
|
401
|
+
|
|
402
|
+
- **不重播**:只處理即時事件,resume、replay 不會補發歷史通知。
|
|
403
|
+
- **無自我迴圈**:外掛附加 `user/message`,自身只監聽 `turn/*`,事件類型不相交。
|
|
404
|
+
- **零外部 import**:外掛從儲存庫目錄以 realpath 載入,`@deepseek-ai/*` 無法裸解析 —— 宿主平面用 `createRequire` 錨定 profile 共享依賴樞紐(`.dsh/profiles/node_modules`)取 `schemastery`(設定 schema)與 `zod`(投影 schema);UserMessage 按 `dsh-llm` 契約手工構造(`id = crypto.randomUUID()`,deep-freeze 由 `session.append` 的 adopt 快照階段完成)。
|
|
405
|
+
- **append 重入規避**:`session/event` 觀察者回呼執行在 `turn/end` 那次 append 的發布邊界之內(dsh-session 在 dispatch 前置 `entry.appending`、`finally` 復位),同步 append 會被拒絕 —— 因此延後到 `queueMicrotask`(微任務在本次同步棧含 `finally` 復位之後才執行)。
|
|
406
|
+
- **effect 紀律**:設定註冊的退避重試計時器包裝在 `ctx.effect()` 中並回傳 `clearTimeout` disposer —— 外掛在重試視窗內被卸載或熱重載時計時器隨 fiber 拆除,不會對已釋放的 ctx 觸發註冊(極老環境無 `ctx.effect` API 時退化為裸計時器 + ctx 已拆除兜底捕獲)。
|
|
407
|
+
- **HMR 安全**:`core.js` 匯入帶 `?v=1` 快取破壞(HMR 重載按 URL 作為鍵值);設定註冊遇到熱重載競爭條件(duplicate)時自動退避重試(最多 8 次,間隔 `400ms × attempts`)。
|
|
408
|
+
- **投影註冊雙軌**:優先 `ctx.root.get('sessionProjections')`(最靠近宿主根的一份),拿不到時回退注入實例;只註冊進注入實例時用戶端可能讀不到投影單元,推送內文走降級路徑 —— 屬盡力而為,不影響會話內系統訊息。
|
|
409
|
+
|
|
410
|
+
---
|
|
411
|
+
|
|
412
|
+
## 專案結構
|
|
413
|
+
|
|
414
|
+
```text
|
|
415
|
+
dsh-session-notify/
|
|
416
|
+
├── lib/
|
|
417
|
+
│ ├── index.js # 宿主平面(Node):session/event 订阅 → 系统消息落盘;
|
|
418
|
+
│ │ # settings 命名空间注册(schemastery schema,退避重试);
|
|
419
|
+
│ │ # sessionProjections 投影单元(后台会话推送正文)
|
|
420
|
+
│ ├── core.js # 纯逻辑层(零依赖,可独立测试):轮次计时与用量聚合、
|
|
421
|
+
│ │ # 5 语言文案表、时长/用量/缓存/速度格式化、
|
|
422
|
+
│ │ # 模板渲染({title}{duration}{usage}{error}{cache}{tps})
|
|
423
|
+
│ └── client.js # 浏览器平面:完成推送(系统通知 + toast)、
|
|
424
|
+
│ # 设置卡片(Chip 模板编辑器 + 预设系统 + 实时预览)
|
|
425
|
+
├── scripts/
|
|
426
|
+
│ ├── build.sh # 零构建:仅 node --check 语法校验
|
|
427
|
+
│ ├── verify-notice.mjs # 校验会话日志落盘证据(zstd 多帧逐帧解压)
|
|
428
|
+
│ ├── probe-client.mjs # 探针:客户端装配
|
|
429
|
+
│ ├── probe-client-e2e.mjs # 探针:客户端端到端
|
|
430
|
+
│ ├── probe-card-render.mjs # 探针:设置卡片渲染
|
|
431
|
+
│ ├── probe-settings-card.mjs # 探针:设置面板卡片
|
|
432
|
+
│ ├── probe-settings-check.mjs# 探针:设置面板检查
|
|
433
|
+
│ └── probe-diag-settings.mjs # 探针:settings 诊断
|
|
434
|
+
├── cordis.patch.yml # dsh.bundle manifest —— dsh plugin add 自动挂载的凭证
|
|
435
|
+
├── package.json # dsh.bundle(patch)+ dsh.client(web 注入)双 manifest;
|
|
436
|
+
│ # exports: "." / "./client" / "./core"
|
|
437
|
+
├── LICENSE # MIT
|
|
438
|
+
└── README.md # 本文档
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## 開發與除錯
|
|
444
|
+
|
|
445
|
+
語法驗證(零建構,`prepublishOnly` 同款檢查):
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
npm run build
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
發布(發布前自動執行 `prepublishOnly` 語法驗證):
|
|
452
|
+
|
|
453
|
+
```bash
|
|
454
|
+
npm publish --registry=https://registry.npmjs.org --access public
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
離線驗證:解出會話日誌中所有 plugin-source 事件與 `turn/end` 尾部序列(不傳路徑則自動選 `~/.dsh/sessions` 下最新會話):
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
node scripts/verify-notice.mjs <session.jsonl.zstd>
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### 除錯入口
|
|
464
|
+
|
|
465
|
+
| 入口 | 內容 |
|
|
466
|
+
| --- | --- |
|
|
467
|
+
| `~/.dsh/session-complete-notify.log` | 宿主診斷日誌:設定註冊、重試與失敗、投影註冊、附加失敗堆疊 |
|
|
468
|
+
| 瀏覽器 console `[dsh-session-notify-client]` | 用戶端日誌:權限狀態、通知展示、設定儲存 |
|
|
469
|
+
| `window.__dsch_notify_debug.readNotice(id)` | 手動讀取指定會話的最新通知內文 |
|
|
470
|
+
| `window.__dsch_notify_debug.snapshotDebug(id)` | 會話尾部節點類型 + notice 數量 + 最近內文(前 200 字) |
|
|
471
|
+
|
|
472
|
+
---
|
|
473
|
+
|
|
474
|
+
## 常見問題
|
|
475
|
+
|
|
476
|
+
<details>
|
|
477
|
+
<summary><b>npm install 之後為什麼不自動掛載?</b></summary>
|
|
478
|
+
|
|
479
|
+
這是 DSH 官方設計:`npm install` 只把套件裝進依賴樹,不註冊外掛。自動掛載的唯一途徑是 `dsh plugin add` —— 它讀取套件內 `dsh.bundle` manifest(此外掛自 0.1.3 起宣告)並自動套用 `cordis.patch.yml`。參見[安裝](#安裝)。
|
|
480
|
+
|
|
481
|
+
</details>
|
|
482
|
+
|
|
483
|
+
<details>
|
|
484
|
+
<summary><b>為什麼「中斷」(interrupted)不提醒?</b></summary>
|
|
485
|
+
|
|
486
|
+
`interrupted` 是崩潰復原後由持久化後端補寫的孤兒輪次關閉標記,使用者視角的「完成」不包含它(否則復原會話會洗版誤報)。確有需要可在宿主設定的 `reasons` 中加入。
|
|
487
|
+
|
|
488
|
+
</details>
|
|
489
|
+
|
|
490
|
+
<details>
|
|
491
|
+
<summary><b>背景會話(沒開啟視窗的)也會推送嗎?</b></summary>
|
|
492
|
+
|
|
493
|
+
會。用戶端從會話清單快照觀測所有會話的 `running` 邊緣;內文優先取宿主投影 —— 宿主為所有會話(含背景)維護投影單元,因此推送內文跨會話一致。投影不可用時降級為事件視窗或工作區資訊。
|
|
494
|
+
|
|
495
|
+
</details>
|
|
496
|
+
|
|
497
|
+
<details>
|
|
498
|
+
<summary><b>儲存設定後為什麼提示重新整理頁面?</b></summary>
|
|
499
|
+
|
|
500
|
+
宿主在註冊命名空間時讀取一次設定,用戶端 bundle 在頁面載入時組裝。儲存後點「點擊重新整理」讓兩側重新讀取,新語言、模板即生效。
|
|
501
|
+
|
|
502
|
+
</details>
|
|
503
|
+
|
|
504
|
+
<details>
|
|
505
|
+
<summary><b>快取命中率、速度資料從哪來?為什麼有時是空的?</b></summary>
|
|
506
|
+
|
|
507
|
+
來自官方 `sessionProjections`(`tokenUsage`、`sessionStats`),與 dsh-web-ui 狀態列同口徑。宿主讀取投影快照失敗或資料尚未就緒時,回退為本地用量彙總估算,仍無資料則該項留空(標籤插了也不顯示)。另外,這兩項只在自訂模板中透過 `{cache}`、`{tps}` 插入時才出現,預設文案不含。
|
|
508
|
+
|
|
509
|
+
</details>
|
|
510
|
+
|
|
511
|
+
<details>
|
|
512
|
+
<summary><b>通知內文裡的錯誤資訊太長、有換行怎麼辦?</b></summary>
|
|
513
|
+
|
|
514
|
+
摘要行(收合行)與錯誤詳情都會單行化並截斷:摘要 120 字元、模板 `{error}` 80 字元、預設文案的錯誤詳情 40 字元,超長以省略號結尾。
|
|
515
|
+
|
|
516
|
+
</details>
|
|
517
|
+
|
|
518
|
+
<details>
|
|
519
|
+
<summary><b>可以自訂系統通知的圖示或音效嗎?</b></summary>
|
|
520
|
+
|
|
521
|
+
目前版本使用瀏覽器預設通知樣式,不注入自訂圖示或音效,toast 為固定深色卡片。如需這些能力歡迎提 Issue 或 PR。
|
|
522
|
+
|
|
523
|
+
</details>
|
|
524
|
+
|
|
525
|
+
<details>
|
|
526
|
+
<summary><b>為什麼 Edge 推不了系統通知?QQ 瀏覽器為什麼只有頁內橫幅(內建推送彈出視窗)?</b></summary>
|
|
527
|
+
|
|
528
|
+
兩者都是瀏覽器行為,外掛無法強制:
|
|
529
|
+
|
|
530
|
+
- **Edge / Chrome**:對"不熟悉"的網站會**自動封鎖通知**(網址列出現「通知已封鎖」)。點擊網址列左側權限圖示 → 網站設定 → 通知 → 允許即可恢復,之後正常彈 Windows 通知中心。也可在瀏覽器通知設定中關閉「自動封鎖」。
|
|
531
|
+
- **QQ 瀏覽器等國產 Chromium 殼**:把 `Notification` 固定渲染為**瀏覽器內建的頁內推送彈出視窗**(頁面頂部/角落橫幅,不經 Windows 通知中心),且無系統通知選項。三種推送方式的實際表現:
|
|
532
|
+
- `雙通道` → 瀏覽器內建彈出視窗 + 外掛 toast,頁內兩個提示;
|
|
533
|
+
- `僅系統通知` → 無效(QQ 瀏覽器永遠渲染為頁內彈出視窗);
|
|
534
|
+
- `僅頁內提示` → 瀏覽器內建彈出視窗不出現,頁內只有外掛自帶的小 toast(推薦)。
|
|
535
|
+
設定面板每個原因的「傳送」測試按鈕同樣按此規則渲染。
|
|
536
|
+
- **Firefox**:視窗聚焦時通知顯示為頁內橫幅,失焦/最小化才進系統通知中心;權限需在網址列手動允許。
|
|
537
|
+
- 另注意:`http://IP` 存取(非安全上下文)時 `Notification` 不存在,任何瀏覽器都彈不了系統通知。
|
|
538
|
+
|
|
539
|
+
設定面板「通知權限」區域會即時顯示目前狀態與對應操作指引。
|
|
540
|
+
|
|
541
|
+
</details>
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## 更新紀錄
|
|
546
|
+
|
|
547
|
+
| 版本 | 日期 | 變更 |
|
|
548
|
+
| --- | --- | --- |
|
|
549
|
+
| **0.1.10** | 2026-08-29 | 「推送標題」改為原生輸入框(原生佔位提示:不可複製、輸入才消失、清空恢復;「+ 會話標題」在游標處插入 `{title}`);文件補充 QQ 瀏覽器內建推送彈出視窗說明(三種推送方式的實際表現 + 傳送按鈕測試同規則) |
|
|
550
|
+
| **0.1.9** | 2026-08-29 | 推送標題支援**按原因自訂**(收合區 UI,預設收合不臃腫;留空時各原因用差異化預設標題:任務已完成/任務出錯/任務已中止/任務被阻塞/任務達到輸出上限,5 語言);投影升級為物件(kind/text/title)承載 host 渲染好的標題;重置按鈕**保留目前語言**;預設文案內嵌「會話標題」標籤(會話「{title}」已完成,無標題自動回退);設定面板模板預覽同步;「+插入資訊」插入標籤後不再自動收合;刪除目前使用的自訂預設自動切回預設;模板預覽修復(點擊不消失、輸入才隱藏、清空恢復);每個原因新增「傳送」按鈕(一鍵發目前模板渲染的測試通知) |
|
|
551
|
+
| **0.1.8** | 2026-08-29 | 預設推送標題改為「任務已完成」(`{title}` 仍可引用會話標題);預設文案按結束原因差異化表達(完成緊湊括號式 / 中止·阻塞拆句 / 出錯錯誤前置 / 上限附建議,5 語言);設定面板新增「重置」按鈕一鍵還原預設 |
|
|
552
|
+
| **0.1.7** | 2026-08-29 | 修復 0.1.6 的設定卡片崩潰:`notificationPermissionRow`/`requestPermissionNow` 曾引用 Card 元件內 state(作用域外)導致渲染 ReferenceError、整個設定卡片消失;改為自包含 + 回呼傳參 |
|
|
553
|
+
| **0.1.6** | 2026-08-29 | 設定面板新增「通知權限」狀態區(授權狀態即時顯示 + 一鍵請求授權按鈕 + 被封鎖時的網址列操作指引);授權改為**使用者手勢內請求**(Chromium 忽略非手勢自動請求,Edge 對不熟悉網站自動封鎖通知的典型場景得以解決);FAQ 新增瀏覽器差異說明 |
|
|
554
|
+
| **0.1.5** | 2026-08-29 | 新增「推送方式」設定(雙通道 / 僅系統通知 / 僅頁內提示):解決 QQ 瀏覽器等 Chromium 殼把 `Notification` 渲染成頁內橫幅導致的雙提示;`pushMode` 加入設定 schema 與設定面板 |
|
|
555
|
+
| **0.1.4** | 2026-08-28 | 補充完整解除安裝支援:`dispose` 生命週期收尾(host 置解除安裝旗標抑制待附加微任務;client 清理內文輪詢計時器、`__dsch_notify_debug` 鉤子、toast 容器);解除安裝文件與 FAQ 同步 |
|
|
556
|
+
| **0.1.3** | 2026-08-28 | 宣告官方 `dsh.bundle` manifest(`dsh plugin add` 一條指令自動掛載);settings 重試計時器改為 `ctx.effect()` 包裝(Cordis effect 紀律);安裝文件重排 |
|
|
557
|
+
| 0.1.2 | 2026-08-27 | 套件更名至 `@telosmaylx` scope(npm 使用者名稱作用域) |
|
|
558
|
+
| 0.1.1 | 2026-08-27 | GitHub、npm 安裝方式文件化 |
|
|
559
|
+
| 0.1.0 | 2026-08-26 | 初始版本:會話內系統訊息 + 瀏覽器推送 + 官方設定面板 |
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## 貢獻
|
|
564
|
+
|
|
565
|
+
歡迎 Issue 與 PR:
|
|
566
|
+
|
|
567
|
+
1. Fork 儲存庫並新建分支(`feat/xxx`)
|
|
568
|
+
2. 改動後執行 `npm run build` 做語法驗證
|
|
569
|
+
3. 送出 PR,說明動機與驗證方式
|
|
570
|
+
|
|
571
|
+
送出前請遵守 [Cordis 開發教學](https://deepseek-harness.github.io/deepseek-harness/develop/cordis-tutorial) 紀律:
|
|
572
|
+
|
|
573
|
+
- Cordis 之外的資源(計時器、訂閱、watcher)必須包裝在 `ctx.effect()` 中並回傳 disposer;
|
|
574
|
+
- 設定項明確 `id` 防止編輯漂移;
|
|
575
|
+
- 外掛須宣告 `dsh.bundle` manifest 才能被 `dsh plugin add` 辨識安裝。
|
|
576
|
+
|
|
577
|
+
---
|
|
578
|
+
|
|
579
|
+
## 相關連結
|
|
580
|
+
|
|
581
|
+
- [awesome-dsh-plugin](https://github.com/awesome-dsh-plugin/awesome-dsh-plugin) —— DSH 外掛精選清單(投稿規範:`dsh.bundle` 是安裝唯一憑證)
|
|
582
|
+
- [Cordis 開發教學](https://deepseek-harness.github.io/deepseek-harness/develop/cordis-tutorial) —— 外掛開發全流程(01-07 章)
|
|
583
|
+
- [npm 套件首頁](https://www.npmjs.com/package/@telosmaylx/dsh-session-notify)
|
|
584
|
+
- [GitHub 儲存庫](https://github.com/TelosmaYLX/dsh-session-notify)
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
## 授權條款
|
|
589
|
+
|
|
590
|
+
[MIT](./LICENSE) © dsh-session-notify contributors
|