@telosmaylx/dsh-session-notify 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-session-notify contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ # dsh-session-notify
2
+
3
+ **DeepSeek Harness plugin that notifies you when a session finishes** — a durable system message is appended into the session log (plugin-source notice, persisted to JSONL), and the browser gets a real push (Web Notification + toast). Which session, how long it took, tokens, cache-hit rate and generation speed — all customizable from the official settings panel.
4
+
5
+ - **Dual channel**: host system message + browser push (each notification has its own tag; toast always shows as a safety net)
6
+ - **Official settings panel** (`设置 → 插件配置 → 会话完成提醒`): preset library, title template, per-reason message templates with insertable tags, live preview
7
+ - **5 languages** (zh / zh-tw / en / ja / ko) for both the panel and the generated messages
8
+ - **Real metrics** from official projections: cache hit rate (`tokenUsage`), tok/s decode speed (`sessionStats`), session title (`title`) — same source as dsh-web-ui
9
+ - **Zero build deps**: hand-written ESM host + official `window.__ModuleLoader__` client bundle; verified end-to-end with headless Chrome probes included in `scripts/`
10
+
11
+ > 中文完整文档见下文。An English section follows the Chinese README below — see 功能特性/安装/使用/标签 tables for details.
12
+
13
+ > DeepSeek Harness 会话完成提醒插件:**会话完成时,在会话内写一条系统消息,并向浏览器推送通知**(哪个会话、耗时、token、缓存命中率、生成速度,全部可自定义)。
14
+
15
+ - ✅ 双通道提醒:**宿主系统消息**(写入会话日志,随 JSONL 持久化)+ **浏览器推送**(Web Notification + 页内 toast)
16
+ - ✅ 官方设置面板:**设置 → 插件配置 → 会话完成提醒**(预设 / 语言 / 标题模板 / 消息模板 / 标签插入)
17
+ - ✅ 5 语言界面与文案:简体中文 / 繁體中文 / English / 日本語 / 한국어
18
+ - ✅ 零外部依赖打包:宿主插件为手写 ESM(无构建步骤),客户端 bundle 为官方 `window.__ModuleLoader__` 契约
19
+ - ✅ 全链路实测:无头 Chrome 端到端验证(落盘 / 渲染 / 推送),仓库附带探针脚本
20
+
21
+ ---
22
+
23
+ ## 功能特性
24
+
25
+ | 能力 | 说明 |
26
+ | --- | --- |
27
+ | 完成提醒 | 监听 `session/event` 火线,`turn/end`(`completed/aborted/blocked/error/max-tokens`)时触发 |
28
+ | 系统消息 | 以 plugin-source 的 `user/message`(`form: 'notice'`)写入会话日志:UI 渲染为可折叠系统行(折叠态即显示正文渲染结果,含 `{title}`/用时/消耗,截断至 120 字符),随 JSONL 持久化,resume/replay 可见 |
29
+ | 浏览器推送 | `running → idle` 边沿检测:Web Notification(每次独立 tag,不折叠)+ **toast 永远展示**(保底,同屏最多 3 条) |
30
+ | 详情指标 | 用时 / token 用量 / **缓存命中率** / **速度 tok/s** —— 数据来自官方投影(`tokenUsage`、`sessionStats`),与 dsh-web-ui 状态栏同源 |
31
+ | 会话标题 | `{title}` 标签:推送标题与消息正文都可插入会话标题(官方 `title` 投影) |
32
+ | 设置面板 | 预设库(默认 + 自定义预设自动管理 / 命名预设)、标题模板、5 字段消息模板、5 语言、标签插入(光标处)、实时预览 |
33
+ | 多语言 | 消息文案(标签/时长/用量/默认文案)+ 面板 UI 全量 i18n:`zh` `zh-tw` `en` `ja` `ko` |
34
+ | 子代理过滤 | 默认跳过子代理会话(子代理由父会话编排) |
35
+ | 投影同步 | 注册 `session-complete-notify` 投影单元:每个会话的最新通知全文推送到客户端,**后台会话同样有完整正文** |
36
+
37
+ ---
38
+
39
+ ## 安装
40
+
41
+ ### 方式一:GitHub 仓库(发布后)
42
+
43
+ ```bash
44
+ # 在 Web GUI 会话中执行
45
+ dev_install_package github=TelosmaYLX/dsh-session-notify # 或 dsh plugin add github:TelosmaYLX/dsh-session-notify
46
+ ```
47
+
48
+ ### 方式二:npm 包(发布后)
49
+
50
+ ```bash
51
+ npm install @telosmaylx/dsh-session-notify # 或从 npm 下载 tgz 解压
52
+ ```
53
+
54
+ ### 方式三:bundle 热装配(本地开发,dsh-super-injector)
55
+
56
+ ```bash
57
+ # 在 Web GUI 会话中执行(dir 换成你的克隆目录)
58
+ dev_install_package dir=</你的插件目录>
59
+ ```
60
+
61
+ ### 方式四:cordis patch(重启后由 bundles 装配,与热装配双路径一致)
62
+
63
+ 在 `~/.dsh/profiles/web/cordis.patch.yml` 追加:
64
+
65
+ ```yaml
66
+ - insert:
67
+ - id: dsh-session-notify
68
+ name: '@telosmaylx/dsh-session-notify'
69
+ config: {}
70
+ ```
71
+
72
+ > 装配要求:`@deepseek-ai/dsh-settings`(设置命名空间)、`@deepseek-ai/dsh-session-projection`(投影)在部署中启用(官方 base bundle 默认包含)。
73
+
74
+ 安装后**刷新浏览器页面**一次(客户端 bundle 通过 `__DSH_BOOT__` 启动图注入)。
75
+
76
+ ---
77
+
78
+ ## 使用
79
+
80
+ 1. 打开 **设置 → 插件配置 → 会话完成提醒**
81
+ 2. 配置(见下)→ **保存** → 状态位提示 `已保存 ✓ · 刷新页面后生效` → 点击 **刷新**
82
+ 3. 任一会话(顶部会话)完成时:
83
+ - 会话尾部出现系统消息(文案 = 你的模板)
84
+ - 右下角 toast 弹出(标题 = 你的标题模板 + 会话标题)
85
+ - 授权后系统通知同步弹出
86
+
87
+ ### 设置面板字段
88
+
89
+ | 字段 | 说明 |
90
+ | --- | --- |
91
+ | **预设(载入)** | 下拉显示当前应用的预设;选预设 = 载入其全部配置(语言 + 标题 + 5 模板)。内置仅「**默认**」 |
92
+ | **新增** | 将当前配置另存为**命名**自定义预设 |
93
+ | **修改 / 删除** | 选中自定义预设时出现:修改 = 当前表单写回该预设;删除 = 移除 |
94
+ | **语言** | 简体中文 / 繁體中文 / English / 日本語 / 한국어 —— 面板与消息文案即时切换 |
95
+ | **推送标题** | 占位符提示「留空则使用会话标题」;`{title}` 标签经「+ 会话标题」插入,如 `【完成】{title}` |
96
+ | **模板 × 5** | 完成 / 出错 / 中止 / 阻塞 / 输出上限:文字 + 内联标签胶囊(点击 × 删除、+ 光标处插入、全选可删);空态直接展示默认文案(始终可编辑) |
97
+ | 预览 | 纯文本最终效果(示例值直出,无标签样式) |
98
+
99
+ ### 标签(可插入信息)
100
+
101
+ | 标签 | 胶囊文字 | 内容 | 示例 |
102
+ | --- | --- | --- | --- |
103
+ | `{title}` | 会话标题 | 会话标题(官方 title 投影) | DeepSeek Harness 插件开发 |
104
+ | `{duration}` | 用时 | 本轮耗时(语言化格式) | 1 分 23 秒 / 1m23s |
105
+ | `{usage}` | 消耗 | 输入 / 输出 token | 1,600 输入 / 3,560 输出 |
106
+ | `{error}` | 错误 | 错误详情;无错误显示 `none` | 连接超时 |
107
+ | `{cache}` | 缓存命中 | 缓存命中率(官方 tokenUsage 四桶口径) | 96.5% |
108
+ | `{tps}` | 速度 TPS | 输出 token ÷ 解码耗时(官方 sessionStats 口径) | 115 tok/s |
109
+
110
+ ### 预设模型(自动生命周期)
111
+
112
+ - **默认预设**:空模板 + 空标题(= 内置默认文案)
113
+ - **保存 = 自动落入一个预设**:
114
+ - 来自自定义预设 → 更新它(修改即自动,无需手动按钮)
115
+ - 来自默认/空白 → 新建 **未命名预设**;已存在则递增编号(未命名预设 2 / 3 …),从不覆盖旧的
116
+ - 从未命名预设本身载入再改 → 更新该未命名预设
117
+ - 预设库持久化在浏览器 localStorage(`dsh-scn-custom-presets`)
118
+
119
+ ---
120
+
121
+ ## 工作原理
122
+
123
+ ### 生命周期
124
+
125
+ ```
126
+ 用户会话 turn/end
127
+ └─ host lib/index.js(session/event 监听)
128
+ ├─ tracker:turn/start 起表,assistant/message 累计用量
129
+ ├─ 官方投影快照:tokenUsage → 缓存命中率;sessionStats → tok/s;title → 会话标题
130
+ ├─ buildNotice(kind, reason, 数据, {language, templates}) → 多语言/模板渲染
131
+ ├─ queueMicrotask → session.append('user/message', plugin-notice, {surfaceOp:'append'})
132
+ └─(投影单元自动更新:每个会话的最新通知全文)
133
+ └─ client lib/client.js(sessions.list running→idle 边沿)
134
+ ├─ 正文:投影(每个会话都有全文)→ 事件窗口 notice 节点 → 降级
135
+ ├─ 标题:用户标题模板({title} = 会话标题;留空 = 会话标题)
136
+ └─ 通知:独立 tag(不折叠)+ toast 永远展示(保底)
137
+ ```
138
+
139
+ ### 关键设计取舍
140
+
141
+ | 取舍 | 说明 |
142
+ | --- | --- |
143
+ | 追加必须微任务延迟 | `session/event` 观察者回调运行在 `turn/end` 那次 append 的发布边界内,同步重入会被拒绝(`"session append cannot reenter…"`)——`queueMicrotask` 在边界复位后执行 |
144
+ | 指标不存插件内存 | 缓存命中/速度/标题取自官方投影(宿主维护、无内存状态,热重载不丢)——与 dsh-web-ui 状态栏同源 |
145
+ | 客户端零构建 | 手写 ESM;宿主经 `createRequire` 锚定 profile 共享依赖枢纽取 schemastery/zod(从仓库目录以 realpath 加载时裸导入不可用) |
146
+ | 双通道解耦 | 系统消息(宿主,持久)与 push(客户端,即时)各自独立;正文以投影通知全文为准保证跨会话一致 |
147
+ | 标签即开关 | 模板里插了标签就显示、不插就不显示(无独立开关) |
148
+ | 注册竞态兜底 | 设置命名空间注册遇 duplicate(热重载下的旧 fiber 注销竞态)自动退避重试 8 次并落盘日志 |
149
+
150
+ ### 多语言
151
+
152
+ - **宿主消息**:标签、时长(`1 分 23 秒` / `1m23s` / `1分 23초`…)、用量措辞、默认文案骨架、错误分隔符随语言
153
+ - **面板 UI**:标题/字段/预设/按钮/提示/标签名/预览示例全量 i18n(约 45 串 × 5)
154
+
155
+ ---
156
+
157
+ ## 脚本(验证工具)
158
+
159
+ | 脚本 | 用途 |
160
+ | --- | --- |
161
+ | `scripts/verify-notice.mjs` | 解压多帧 zstd 会话日志,核验系统消息落盘(plugin-source notice)+ turn/end 触发点 |
162
+ | `scripts/probe-client.mjs` | 客户端激活冒烟(boot graph / 模块加载 / 报错) |
163
+ | `scripts/probe-client-e2e.mjs` | 端到端推送实测:无头 Chrome 等待真实完成事件,抓取 toast 内容(可钉会话窗口:`node scripts/probe-client-e2e.mjs 900000 <sessionId>`) |
164
+ | `scripts/probe-card-render.mjs` | 无头完整流程:设置 → 插件 → 卡片渲染 + 控制台错误 |
165
+ | `scripts/probe-settings-card.mjs` | 设置面板卡片检测(DOM 文本) |
166
+
167
+ ---
168
+
169
+ ## 项目结构
170
+
171
+ ```
172
+ lib/index.js # 宿主:事件订阅 / 计时 / 设置命名空间(5 语言 schema)/ 投影注册 / 通知构建 + 追加
173
+ lib/core.js # 纯逻辑:计时/用量聚合/命中率/tps/多语言标签/模板渲染(可独立单测)
174
+ lib/client.js # 浏览器:推送(通知 + toast)/ 设置卡片(ChipEditor + 预设库 + 标题模板)
175
+ scripts/build.sh # 构建(node --check 校验手写 ESM)
176
+ scripts/*.mjs # 验证/探针脚本(见上表)
177
+ ```
178
+
179
+ ## 开发提示
180
+
181
+ - 宿主热重载后会出现一次「用时 0 秒」:内存计时器随重载重置(下轮恢复;缓存命中/速度/标题来自投影不受影响)
182
+ - 设置保存后需刷新页面:宿主实时生效,但客户端 bundle 需整页加载
183
+ - 通知权限:首次完成时浏览器会请求(权限 `default` 只发起一次);拒绝不影响 toast
184
+ - 发布包:`npm run build`(node --check)→ `npm pack` → `telosmaylx-dsh-session-notify-*.tgz`
185
+
186
+ ## License
187
+
188
+ MIT