dsh-completion-reminder 1.0.0 → 1.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/README.md +55 -77
- package/dist/dsh-completion-reminder.js +1 -0
- package/install.md +27 -37
- package/lib/client.d.ts +13 -15
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +644 -203
- package/lib/client.js.map +1 -1
- package/lib/types.d.ts +31 -0
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +16 -1
- package/lib/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,8 +3,15 @@
|
|
|
3
3
|
为 DeepSeek Harness (DSH) Web GUI 增加 **Agent 完成提醒** 功能的插件。
|
|
4
4
|
当 agent 停止生成(成功 / 主动停止 / 出错)时,弹一个通知给用户。
|
|
5
5
|
|
|
6
|
-
默认走 **浏览器原生通知**(`window.Notification
|
|
7
|
-
|
|
6
|
+
- 🌐 默认走 **浏览器原生通知**(`window.Notification`,首次使用需要用户授权)
|
|
7
|
+
- ⚙️ 右下角悬浮一个 **🔔 按钮**,点开是带 9 种通知渠道的图形化配置面板
|
|
8
|
+
- 💾 配置保存在本浏览器 `localStorage`,不会上传任何服务器
|
|
9
|
+
- 🧪 配置面板自带 **「发送测试通知」** 按钮,方便验证渠道是否通
|
|
10
|
+
- 🪟 标签页可见时默认静默(不打断工作),可通过开关关闭
|
|
11
|
+
- ⏱ 内置 5 秒冷却,避免连续 agent 完成时刷屏
|
|
12
|
+
- 🎨 标题/正文可定制,匹配 `success` / `stopped` / `error` 三种状态
|
|
13
|
+
|
|
14
|
+
## 9 种通知渠道
|
|
8
15
|
|
|
9
16
|
| 渠道 | 适用人群 | 配置字段 |
|
|
10
17
|
|------|----------|----------|
|
|
@@ -18,17 +25,20 @@
|
|
|
18
25
|
| 🔗 **Webhook** | 自建服务 | `webhookUrl` |
|
|
19
26
|
| 🛠 **Custom** | 完全自定义 | `customSend(payload)` |
|
|
20
27
|
|
|
21
|
-
##
|
|
28
|
+
## 工作原理(v1.1)
|
|
29
|
+
|
|
30
|
+
DSH 的 composer 卡片 `<div data-composer-card="true">` 内的主按钮 `aria-label` 会在
|
|
31
|
+
`"Stop generating"` / `"Send message"`(中文 UI 下是 `"停止生成"` / `"发送消息"`)之间切换。
|
|
32
|
+
插件用一个轻量 `MutationObserver` 监听这个属性变化:
|
|
22
33
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
- 📦 **npm 分发**:CI 自动构建、发布、创建 GitHub Release
|
|
34
|
+
- 检测到 `Stop generating` → 记录开始时间
|
|
35
|
+
- 检测到 `Send message` → 触发完成事件
|
|
36
|
+
- 根据 `data-phase` (`active` / `settling` / `hero`) 和最后一条 `data-role="assistant"`
|
|
37
|
+
消息的文本/类名,判断 `success` / `stopped` / `error`
|
|
38
|
+
- 派发到当前渠道,调用 `Notification` / `fetch` 发送
|
|
39
|
+
|
|
40
|
+
所有匹配都用 **稳定属性**(`data-*`、`aria-label`、`type`),不依赖会被 CSS-modules
|
|
41
|
+
哈希改变的 class 名(`uV2eYG_primary` 这类),跨 DSH 版本更稳。
|
|
32
42
|
|
|
33
43
|
## 快速开始
|
|
34
44
|
|
|
@@ -53,86 +63,45 @@ dsh plugin --profile web add -w dsh-completion-reminder
|
|
|
53
63
|
dsh web
|
|
54
64
|
```
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
打开任一会话,右下角应该出现一个 **🔔** 浮动按钮。点击它打开设置面板:
|
|
67
|
+
|
|
68
|
+
1. 选择通知渠道(如 `Telegram`)
|
|
69
|
+
2. 填入对应的 token / id(一次即可,存到 `localStorage`)
|
|
70
|
+
3. 点击 **「发送测试通知」** 验证渠道通不通
|
|
71
|
+
4. 等一次 agent 完成,会自动收到通知 🎉
|
|
58
72
|
|
|
59
|
-
##
|
|
73
|
+
## 程序化 API
|
|
60
74
|
|
|
61
75
|
```javascript
|
|
62
76
|
DSHCompletionReminder.configure({
|
|
63
|
-
provider: 'telegram',
|
|
64
|
-
// | 'serverchan' | 'discord' | 'slack'
|
|
65
|
-
// | 'webhook' | 'custom'
|
|
66
|
-
autoRequestPermission: true, // 浏览器模式下自动请求 Notification 权限
|
|
67
|
-
notifyOnSuccess: true, // 成功完成时通知
|
|
68
|
-
notifyOnStopped: true, // 用户主动停止时通知
|
|
69
|
-
notifyOnError: true, // agent 出错时通知
|
|
70
|
-
suppressWhenFocused: true, // 标签页可见且有焦点时不响
|
|
71
|
-
cooldownMs: 5000, // 连续通知之间的最小间隔
|
|
72
|
-
titleTemplate: ({ status }) => 'DSH 已结束', // 自定义标题
|
|
73
|
-
bodyTemplate: ({ model, durationMs }) => `${model} · 用时 ${durationMs}ms`,
|
|
74
|
-
iconUrl: '/favicon.ico',
|
|
75
|
-
clickUrl: location.href,
|
|
76
|
-
|
|
77
|
+
provider: 'telegram',
|
|
77
78
|
providers: {
|
|
78
79
|
telegramBotToken: '123456:ABC...',
|
|
79
80
|
telegramChatId: '987654321',
|
|
80
|
-
|
|
81
|
-
// barkKey / pushover* / serverchanSendKey / discordWebhookUrl /
|
|
82
|
-
// slackWebhookUrl / webhookUrl 只需按当前 provider 填写。
|
|
83
81
|
},
|
|
84
|
-
|
|
82
|
+
suppressWhenFocused: false,
|
|
83
|
+
cooldownMs: 3000,
|
|
85
84
|
onNotify: (payload, provider) => console.log('delivered via', provider, payload),
|
|
86
85
|
onError: (err, provider) => console.warn('failed via', provider, err),
|
|
87
86
|
});
|
|
88
87
|
|
|
89
88
|
DSHCompletionReminder.activate();
|
|
90
89
|
DSHCompletionReminder.deactivate();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
### 只走「页面内 toast」?
|
|
94
|
-
|
|
95
|
-
把 `provider` 设为 `'browser'` 即可。如果用户拒绝浏览器通知权限,插件会自动
|
|
96
|
-
回退为页面内的浮动提示,不需要任何额外配置。
|
|
97
|
-
|
|
98
|
-
### 切换到 Telegram?
|
|
99
|
-
|
|
100
|
-
1. 在 Telegram 中 `@BotFather` 创建 bot,拿到 `telegramBotToken`
|
|
101
|
-
2. 给自己发一条消息,访问 `https://api.telegram.org/bot<TOKEN>/getUpdates` 拿到 `chat.id`
|
|
102
|
-
3. 配置:
|
|
103
|
-
|
|
104
|
-
```javascript
|
|
105
|
-
DSHCompletionReminder.configure({
|
|
106
|
-
provider: 'telegram',
|
|
107
|
-
providers: {
|
|
108
|
-
telegramBotToken: '<TOKEN>',
|
|
109
|
-
telegramChatId: '<CHAT_ID>',
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## 公开 API
|
|
115
|
-
|
|
116
|
-
```javascript
|
|
117
|
-
DSHCompletionReminder.DEFAULTS // 默认配置
|
|
118
|
-
DSHCompletionReminder.configure(opts) // 合并配置(多次调用累加)
|
|
119
|
-
DSHCompletionReminder.activate() // 启动 DOM 观察与通知
|
|
120
|
-
DSHCompletionReminder.deactivate() // 停止一切
|
|
121
|
-
DSHCompletionReminder.requestBrowserPermission() // 手动触发 Notification 权限请求
|
|
90
|
+
DSHCompletionReminder.requestBrowserPermission();
|
|
122
91
|
```
|
|
123
92
|
|
|
124
93
|
`apply(ctx, opts)` 是 DSH Cordis Loader 调用的入口,等价于 `configure(opts); activate()`。
|
|
125
94
|
|
|
126
|
-
##
|
|
95
|
+
## 公开 API
|
|
127
96
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
97
|
+
| 方法 / 属性 | 说明 |
|
|
98
|
+
|------|------|
|
|
99
|
+
| `DSHCompletionReminder.configure(opts)` | 合并配置(与 localStorage 持久值叠加) |
|
|
100
|
+
| `DSHCompletionReminder.activate()` | 启动 DOM 观察 + 注入浮动按钮 |
|
|
101
|
+
| `DSHCompletionReminder.deactivate()` | 停止一切,移除 UI |
|
|
102
|
+
| `DSHCompletionReminder.requestBrowserPermission()` | 手动触发浏览器通知权限请求 |
|
|
103
|
+
| `DSHCompletionReminder.apply(ctx, opts)` | DSH Cordis Loader 入口 |
|
|
104
|
+
| `DSHCompletionReminder.DEFAULTS` | 默认配置(只读) |
|
|
136
105
|
|
|
137
106
|
## 项目结构
|
|
138
107
|
|
|
@@ -143,7 +112,7 @@ dsh-completion-reminder/
|
|
|
143
112
|
├── tsconfig.json # TypeScript 配置
|
|
144
113
|
├── src/
|
|
145
114
|
│ ├── index.ts # 服务端入口(桩)
|
|
146
|
-
│ ├── client.ts # 客户端插件 TypeScript
|
|
115
|
+
│ ├── client.ts # 客户端插件 TypeScript 源码(DOM 检测 + 9 渠道 + 设置面板)
|
|
147
116
|
│ └── types.ts # 类型定义 & 默认值
|
|
148
117
|
├── lib/
|
|
149
118
|
│ ├── index.js # 编译后的服务端入口(纯载体)
|
|
@@ -153,9 +122,9 @@ dsh-completion-reminder/
|
|
|
153
122
|
├── scripts/
|
|
154
123
|
│ ├── build-plugin.js # 构建脚本(tsc 产物 → ModuleLoader 包装)
|
|
155
124
|
│ └── clean.js # 清理 lib/ 和 dist/
|
|
156
|
-
├──
|
|
157
|
-
|
|
158
|
-
└──
|
|
125
|
+
├── probes/ # 离线 smoke test(jsdom,模拟 DSH DOM)
|
|
126
|
+
└── .github/workflows/
|
|
127
|
+
└── publish.yml # tag 推送 → 构建 → npm 发布 → GitHub Release
|
|
159
128
|
```
|
|
160
129
|
|
|
161
130
|
## 发布流程
|
|
@@ -168,6 +137,15 @@ git push origin main --tags
|
|
|
168
137
|
推送 `v*` tag 后 CI 自动完成构建、npm 发布和 GitHub Release。
|
|
169
138
|
`NPM_TOKEN` 与 `GITHUB_TOKEN` 在仓库 Settings → Secrets 中配置。
|
|
170
139
|
|
|
140
|
+
## 版本历史
|
|
141
|
+
|
|
142
|
+
- **v1.1.0** — 真正的 v1:
|
|
143
|
+
- 改用真实 DSH DOM 锚点(`data-composer-card` + `aria-label`),不再依赖会被哈希的 class 名
|
|
144
|
+
- 新增右下角浮动 **🔔** 按钮 + 完整设置面板(9 渠道、11 凭证字段、4 个行为开关、测试按钮)
|
|
145
|
+
- 配置持久化到 `localStorage`
|
|
146
|
+
- jsdom 离线 smoke test 验证 3 种状态(success / stopped / error)+ 9 渠道派发
|
|
147
|
+
- **v1.0.0** — 初始版本(class 名匹配,实际 DSH 上不可用)
|
|
148
|
+
|
|
171
149
|
## 许可
|
|
172
150
|
|
|
173
151
|
MIT
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
providers: {},
|
|
30
30
|
clickUrl: '',
|
|
31
31
|
iconUrl: '',
|
|
32
|
+
showSettingsPanel: true,
|
|
32
33
|
onNotify: function () { return undefined; },
|
|
33
34
|
onError: function (err) { try { console.warn('[dsh-completion-reminder]', err); } catch (_e) {} },
|
|
34
35
|
titleTemplate: function (ctx) {
|
package/install.md
CHANGED
|
@@ -26,63 +26,53 @@ dsh plugin --profile web add dsh-completion-reminder
|
|
|
26
26
|
dsh web
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
点击「允许」即可启用浏览器原生通知。
|
|
29
|
+
启动后,DSH 右下角会出现一个 **🔔** 浮动按钮。点击它打开设置面板。
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
## 配置通知渠道
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
dsh plugin --profile web update dsh-completion-reminder
|
|
36
|
-
dsh web # 重启生效
|
|
37
|
-
```
|
|
33
|
+
打开设置面板:
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
1. **选择通知渠道**(默认 `🌐 浏览器通知`)
|
|
36
|
+
2. **填入对应凭证**(如 Telegram Bot Token / Chat ID)
|
|
37
|
+
3. 调整 **行为选项**(成功 / 停止 / 出错 是否通知、是否在标签页可见时静默、冷却时长)
|
|
38
|
+
4. 点击 **「发送测试通知」** 验证渠道
|
|
39
|
+
5. 关闭面板 → 自动保存到 localStorage
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
2. 给 agent 发任意一条消息
|
|
43
|
-
3. 等任务结束 → 系统右下角(或顶部)出现通知:「✅ DSH Agent 已完成 · 用时 Xs」
|
|
41
|
+
如果使用浏览器原生通知,第一次会弹权限询问;如果拒绝,插件会自动改用页面内浮动 toast,**不会**完全失效。
|
|
44
42
|
|
|
45
|
-
|
|
43
|
+
## 切换渠道示例
|
|
46
44
|
|
|
47
|
-
|
|
45
|
+
### Telegram
|
|
48
46
|
|
|
49
|
-
在
|
|
47
|
+
1. 在 Telegram 中 `@BotFather` 创建 bot,拿到 `telegramBotToken`
|
|
48
|
+
2. 给自己发一条消息,访问 `https://api.telegram.org/bot<TOKEN>/getUpdates` 拿到 `chat.id`
|
|
49
|
+
3. 在设置面板选 `Telegram` 并填入两项凭证
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
DSHCompletionReminder.configure({
|
|
53
|
-
provider: 'telegram',
|
|
54
|
-
providers: {
|
|
55
|
-
telegramBotToken: '123456:ABC...',
|
|
56
|
-
telegramChatId: '987654321',
|
|
57
|
-
},
|
|
58
|
-
});
|
|
59
|
-
```
|
|
51
|
+
### Bark (iPhone)
|
|
60
52
|
|
|
61
|
-
|
|
53
|
+
1. App Store 装 Bark([apps.apple.com/cn/app/bark](https://apps.apple.com/cn/app/bark-customed-notifications/id1403753865))
|
|
54
|
+
2. 打开 Bark,记下你的设备 Key
|
|
55
|
+
3. 面板里选 `Bark`,填入 `barkKey`
|
|
62
56
|
|
|
63
|
-
|
|
57
|
+
### Server酱 (微信)
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- `pushover` — Pushover
|
|
69
|
-
- `serverchan` — Server酱 (sct.ftqq.com)
|
|
70
|
-
- `discord` — Discord Webhook
|
|
71
|
-
- `slack` — Slack Webhook
|
|
72
|
-
- `webhook` — 通用 JSON POST Webhook
|
|
73
|
-
- `custom` — 自定义 `customSend(payload)` 函数
|
|
59
|
+
1. 微信扫码登录 [sct.ftqq.com](https://sct.ftqq.com)
|
|
60
|
+
2. 拿到 SendKey(以 `SCT` 开头)
|
|
61
|
+
3. 面板里选 `Server酱`,填入
|
|
74
62
|
|
|
75
63
|
## 故障排除
|
|
76
64
|
|
|
77
65
|
| 问题 | 原因 | 解决方法 |
|
|
78
66
|
|------|------|----------|
|
|
79
67
|
| 安装报 `ERR_PNPM_ADDING_TO_ROOT` | profile 是 pnpm workspace root | 加 `-w` 标志重新执行 |
|
|
80
|
-
|
|
|
68
|
+
| 装了但右下角没有 🔔 按钮 | 未重启 `dsh web` | 重启后强刷页面 |
|
|
81
69
|
| 浏览器没弹权限询问 | 之前已「阻止」该网站 | 浏览器地址栏左侧锁形图标 → 通知 → 允许 |
|
|
82
70
|
| Telegram 报 401/400 | `telegramBotToken` / `telegramChatId` 配错 | 用 `@BotFather` 重新获取 token;用 `getUpdates` 找 chat id |
|
|
83
|
-
|
|
|
84
|
-
|
|
|
71
|
+
| 测试按钮提示「Telegram provider requires…」 | 凭证未填 | 滚动到「渠道凭证」区填入对应字段 |
|
|
72
|
+
| 通知频率太高 | 多个 agent 接连完成 | 调大「冷却(ms)」,默认 5000 |
|
|
73
|
+
| 切回浏览器通知 | 想撤销 Telegram 配置 | 面板顶部下拉切回 `浏览器通知` |
|
|
85
74
|
| 完全停用 | — | `DSHCompletionReminder.deactivate()` |
|
|
75
|
+
| 重置所有配置 | — | 设置面板里点「重置」按钮 |
|
|
86
76
|
|
|
87
77
|
## 卸载
|
|
88
78
|
|
package/lib/client.d.ts
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DSH Completion Reminder — client half.
|
|
2
|
+
* DSH Completion Reminder — client half (v1.1).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Detects the agent-completion lifecycle by watching the DSH composer
|
|
5
|
+
* primary button's `aria-label` (which flips between "Stop generating" /
|
|
6
|
+
* "Stop 生成" / "Stop" while running and "Send message" / "发送消息" /
|
|
7
|
+
* "Send" when idle) and the conversation root's `data-phase` (which
|
|
8
|
+
* transitions through `active` / `settling` / `hero`).
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
16
|
-
* - slack : Slack incoming webhook
|
|
17
|
-
* - webhook : generic JSON POST webhook
|
|
18
|
-
* - custom : user-supplied function
|
|
10
|
+
* The plugin:
|
|
11
|
+
* - exposes `window.DSHCompletionReminder.configure({...})` for API users
|
|
12
|
+
* - injects a floating 🔔 button in the bottom-right corner that opens
|
|
13
|
+
* a settings panel (provider picker + per-provider credentials + test
|
|
14
|
+
* button). Configuration is persisted to localStorage.
|
|
15
|
+
* - delivers notifications via 9 channels: browser, Telegram, Bark,
|
|
16
|
+
* Pushover, Server酱, Discord, Slack, generic Webhook, custom.
|
|
19
17
|
*
|
|
20
18
|
* The plugin is packaged as a DSH client plugin (`dsh.client` in
|
|
21
19
|
* package.json) and loaded through `window.__ModuleLoader__`.
|
package/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAEV,yBAAyB,EAM1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EAIhB,MAAM,YAAY,CAAC;AAiFpB,iBAAS,SAAS,CAAC,IAAI,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAgBzD;AAED,iBAAS,QAAQ,IAAI,IAAI,CAiBxB;AAED,iBAAS,UAAU,IAAI,IAAI,CAS1B;AA6CD,iBAAe,wBAAwB,IAAI,OAAO,CAAC,sBAAsB,GAAG,aAAa,CAAC,CAczF;AA+8BD;;GAEG;AACH,iBAAS,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAGnE;AAED,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,wBAAwB,EAAE,eAAe,EAAE,CAAA"}
|