dsh-speak 1.7.4 → 1.8.1
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 +21 -21
- package/README.md +462 -417
- package/README.zh-CN.md +433 -394
- package/adapters/dsh/install.ps1 +81 -81
- package/adapters/dsh/speech-hook.js +614 -561
- package/client/client.js +357 -340
- package/docs/DESIGN.md +60 -14
- package/docs/DESIGN.zh-CN.md +48 -12
- package/engine/speak.ps1 +214 -155
- package/engine/speak.sh +36 -6
- package/engine/speech-prompt.ps1 +24 -22
- package/engine/speech-summary.ps1 +27 -27
- package/package.json +82 -85
package/README.zh-CN.md
CHANGED
|
@@ -1,394 +1,433 @@
|
|
|
1
|
-
# dsh-speak 🔊 — 为 AI 编程 harness 提供语音播报
|
|
2
|
-
|
|
3
|
-
**中文** · [English](README.md)
|
|
4
|
-
|
|
5
|
-

|
|
6
|
-
|
|
7
|
-
[](https://awesome-dsh-plugin.com)
|
|
8
|
-
|
|
9
|
-
[](https://www.npmjs.com/package/dsh-speak)
|
|
10
|
-
|
|
11
|
-
让 Agent 在长任务完成时**开口告诉你**——不用再盯着屏幕等。
|
|
12
|
-
|
|
13
|
-
dsh-speak 通过系统语音合成把 Agent 的最终回复朗读出来——Windows 上优先使用自然
|
|
14
|
-
语音(Windows 11 内置,或 Windows 10 上经
|
|
15
|
-
[NaturalVoiceSAPIAdapter] 注册,如晓晓),macOS 上使用系统自带的 `say`
|
|
16
|
-
(可跟随 Siri 自然音色);没有时优雅回退到系统自带中文语音。本项目为
|
|
17
|
-
[DeepSeek Harness](https://github.com/deepseek-ai/dsh) 而生,但结构上
|
|
18
|
-
任何 harness 都能接入。
|
|
19
|
-
|
|
20
|
-
## 特性
|
|
21
|
-
|
|
22
|
-
- **全自动**:DSH web 插件监听会话事件流,自动播报最终回复
|
|
23
|
-
(跳过 reasoning/工具调用旁白,合并同一回复的多步消息)。
|
|
24
|
-
- **提醒你**:审批请求(Agent 等你操作时会播"需要你的审批")和 Agent 通过
|
|
25
|
-
`ask_user_question` 提出的问题都会播报。
|
|
26
|
-
- **最终回复重播**(1.7.0):每条最终回复(回合尾部)操作栏有 🔊 按钮——点击
|
|
27
|
-
重播该条回复、再点停止、点另一条切换。语音执行完全由 DSH host 拥有(浏览器
|
|
28
|
-
关掉也继续读)。
|
|
29
|
-
- **host 语音队列**(1.7.0):同一时间只运行一个语音进程,队列自动串行;
|
|
30
|
-
WebSocket 实时同步"正在读哪条、队列长度"到 UI。
|
|
31
|
-
- **多事件可选播报**(1.6.0):回合结束、命令完成、目标变更、工具出错、
|
|
32
|
-
待办更新等事件都可选播报,各自独立开/关(默认关)。
|
|
33
|
-
- **可视化配置**(1.7.0):设置 → dsh-speak 设置独立设置页,所有配置项(总开关、
|
|
34
|
-
自动朗读、Markdown 清洗、代码块、事件开关、固定提示语…)直接改,无需手写
|
|
35
|
-
YAML。
|
|
36
|
-
- **总开关**(1.6.0):一键静音所有播报。
|
|
37
|
-
- **Bundle 自动注册**(1.3.0):把包声明进 `dsh.profile.bundles`,插件通过包内
|
|
38
|
-
自带的 `cordis.patch.yml` 自动注册,无需手动写 patch 条目。
|
|
39
|
-
- **尽力而为**:绝不抛错、绝不阻塞 harness、绝不破坏会话。
|
|
40
|
-
- **自然语音**:Windows 优先使用自然语音——Windows 11 内置语音包,或 Windows 10
|
|
41
|
-
上经 NaturalVoiceSAPIAdapter 注册的语音(如晓晓);macOS 使用系统朗读声音
|
|
42
|
-
(新版可跟随 Siri 自然音色)。均回退到任意已安装语音。
|
|
43
|
-
- **健壮的文本清洗**:去掉会让语音合成静默失败的 markdown/URL/emoji,
|
|
44
|
-
并守卫适配器单次朗读的字数上限。
|
|
45
|
-
- **引擎可移植**:任意进程一行即可朗读:
|
|
46
|
-
Windows `powershell -File speak.ps1 -Text "你好"` / macOS `./speak.sh -t "你好"`。
|
|
47
|
-
|
|
48
|
-
## 工作原理
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
harness 事件(DSH 会话事件 / Claude Code Stop hook / 任意方式)
|
|
52
|
-
│
|
|
53
|
-
▼ adapters/… (harness 专属触发器:过滤、节流、取消)
|
|
54
|
-
▼ engine/speak.ps1 / speak.sh (与 harness 无关:清洗文本 → SAPI5 / say)
|
|
55
|
-
▼ 🔊 你听到最终回复
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
适配器负责把 harness 专属事件转成引擎调用;引擎负责清洗文本并朗读,
|
|
59
|
-
与 harness 完全解耦。完整设计见 [docs/DESIGN.zh-CN.md](docs/DESIGN.zh-CN.md)。
|
|
60
|
-
|
|
61
|
-
## 前置条件
|
|
62
|
-
|
|
63
|
-
### Windows
|
|
64
|
-
|
|
65
|
-
- Windows 10 或 11,任意较新的 PowerShell。
|
|
66
|
-
- 自然语音:
|
|
67
|
-
- **Windows 11(21H2–23H2)**:系统已内置自然语音包,无需额外安装——在
|
|
68
|
-
*设置 → 辅助功能 → 讲述人* 或 *设置 → 时间和语言 → 语音* 中启用/切换即可。
|
|
69
|
-
- **Windows 11 24H2/25H2**:自然语音已改为 MSIX 应用包,`System.Speech` 可能
|
|
70
|
-
枚举不到(`SpeechSynthesizer` 找不到自然语音、回退到机械音)——与 Windows 10
|
|
71
|
-
相同,需安装 [NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter)
|
|
72
|
-
桥接。
|
|
73
|
-
- **Windows 10**:需要安装
|
|
74
|
-
[NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter),
|
|
75
|
-
并用它的 VoiceDownloader 手动下载你需要的中文或其他语言的自然语音包。
|
|
76
|
-
- 没有自然语音时,引擎回退到系统自带语音(如 Huihui)。
|
|
77
|
-
|
|
78
|
-
### macOS 要求
|
|
79
|
-
|
|
80
|
-
- macOS(Apple Silicon / Intel 均可),系统自带 `say` 命令,**无需安装任何软件**。
|
|
81
|
-
- 中文音色与 Siri 音色的选择入口/坑见 [macOS](#macos) 一节。
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
>
|
|
115
|
-
>
|
|
116
|
-
>
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
####
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
powershell -NoProfile -ExecutionPolicy Bypass -File
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
|
297
|
-
|
|
|
298
|
-
| `
|
|
299
|
-
| `
|
|
300
|
-
| `
|
|
301
|
-
| `
|
|
302
|
-
| `
|
|
303
|
-
| `
|
|
304
|
-
| `
|
|
305
|
-
| `
|
|
306
|
-
| `
|
|
307
|
-
| `
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
1
|
+
# dsh-speak 🔊 — 为 AI 编程 harness 提供语音播报
|
|
2
|
+
|
|
3
|
+
**中文** · [English](README.md)
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
[](https://awesome-dsh-plugin.com)
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/dsh-speak)
|
|
10
|
+
|
|
11
|
+
让 Agent 在长任务完成时**开口告诉你**——不用再盯着屏幕等。
|
|
12
|
+
|
|
13
|
+
dsh-speak 通过系统语音合成把 Agent 的最终回复朗读出来——Windows 上优先使用自然
|
|
14
|
+
语音(Windows 11 内置,或 Windows 10 上经
|
|
15
|
+
[NaturalVoiceSAPIAdapter] 注册,如晓晓),macOS 上使用系统自带的 `say`
|
|
16
|
+
(可跟随 Siri 自然音色);没有时优雅回退到系统自带中文语音。本项目为
|
|
17
|
+
[DeepSeek Harness](https://github.com/deepseek-ai/dsh) 而生,但结构上
|
|
18
|
+
任何 harness 都能接入。
|
|
19
|
+
|
|
20
|
+
## 特性
|
|
21
|
+
|
|
22
|
+
- **全自动**:DSH web 插件监听会话事件流,自动播报最终回复
|
|
23
|
+
(跳过 reasoning/工具调用旁白,合并同一回复的多步消息)。
|
|
24
|
+
- **提醒你**:审批请求(Agent 等你操作时会播"需要你的审批")和 Agent 通过
|
|
25
|
+
`ask_user_question` 提出的问题都会播报。
|
|
26
|
+
- **最终回复重播**(1.7.0):每条最终回复(回合尾部)操作栏有 🔊 按钮——点击
|
|
27
|
+
重播该条回复、再点停止、点另一条切换。语音执行完全由 DSH host 拥有(浏览器
|
|
28
|
+
关掉也继续读)。
|
|
29
|
+
- **host 语音队列**(1.7.0):同一时间只运行一个语音进程,队列自动串行;
|
|
30
|
+
WebSocket 实时同步"正在读哪条、队列长度"到 UI。
|
|
31
|
+
- **多事件可选播报**(1.6.0):回合结束、命令完成、目标变更、工具出错、
|
|
32
|
+
待办更新等事件都可选播报,各自独立开/关(默认关)。
|
|
33
|
+
- **可视化配置**(1.7.0):设置 → dsh-speak 设置独立设置页,所有配置项(总开关、
|
|
34
|
+
自动朗读、Markdown 清洗、代码块、事件开关、固定提示语…)直接改,无需手写
|
|
35
|
+
YAML。
|
|
36
|
+
- **总开关**(1.6.0):一键静音所有播报。
|
|
37
|
+
- **Bundle 自动注册**(1.3.0):把包声明进 `dsh.profile.bundles`,插件通过包内
|
|
38
|
+
自带的 `cordis.patch.yml` 自动注册,无需手动写 patch 条目。
|
|
39
|
+
- **尽力而为**:绝不抛错、绝不阻塞 harness、绝不破坏会话。
|
|
40
|
+
- **自然语音**:Windows 优先使用自然语音——Windows 11 内置语音包,或 Windows 10
|
|
41
|
+
上经 NaturalVoiceSAPIAdapter 注册的语音(如晓晓);macOS 使用系统朗读声音
|
|
42
|
+
(新版可跟随 Siri 自然音色)。均回退到任意已安装语音。
|
|
43
|
+
- **健壮的文本清洗**:去掉会让语音合成静默失败的 markdown/URL/emoji,
|
|
44
|
+
并守卫适配器单次朗读的字数上限。
|
|
45
|
+
- **引擎可移植**:任意进程一行即可朗读:
|
|
46
|
+
Windows `powershell -File speak.ps1 -Text "你好"` / macOS `./speak.sh -t "你好"`。
|
|
47
|
+
|
|
48
|
+
## 工作原理
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
harness 事件(DSH 会话事件 / Claude Code Stop hook / 任意方式)
|
|
52
|
+
│
|
|
53
|
+
▼ adapters/… (harness 专属触发器:过滤、节流、取消)
|
|
54
|
+
▼ engine/speak.ps1 / speak.sh (与 harness 无关:清洗文本 → SAPI5 / say)
|
|
55
|
+
▼ 🔊 你听到最终回复
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
适配器负责把 harness 专属事件转成引擎调用;引擎负责清洗文本并朗读,
|
|
59
|
+
与 harness 完全解耦。完整设计见 [docs/DESIGN.zh-CN.md](docs/DESIGN.zh-CN.md)。
|
|
60
|
+
|
|
61
|
+
## 前置条件
|
|
62
|
+
|
|
63
|
+
### Windows
|
|
64
|
+
|
|
65
|
+
- Windows 10 或 11,任意较新的 PowerShell。
|
|
66
|
+
- 自然语音:
|
|
67
|
+
- **Windows 11(21H2–23H2)**:系统已内置自然语音包,无需额外安装——在
|
|
68
|
+
*设置 → 辅助功能 → 讲述人* 或 *设置 → 时间和语言 → 语音* 中启用/切换即可。
|
|
69
|
+
- **Windows 11 24H2/25H2**:自然语音已改为 MSIX 应用包,`System.Speech` 可能
|
|
70
|
+
枚举不到(`SpeechSynthesizer` 找不到自然语音、回退到机械音)——与 Windows 10
|
|
71
|
+
相同,需安装 [NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter)
|
|
72
|
+
桥接。
|
|
73
|
+
- **Windows 10**:需要安装
|
|
74
|
+
[NaturalVoiceSAPIAdapter](https://github.com/gexgd0419/NaturalVoiceSAPIAdapter),
|
|
75
|
+
并用它的 VoiceDownloader 手动下载你需要的中文或其他语言的自然语音包。
|
|
76
|
+
- 没有自然语音时,引擎回退到系统自带语音(如 Huihui)。
|
|
77
|
+
|
|
78
|
+
### macOS 要求
|
|
79
|
+
|
|
80
|
+
- macOS(Apple Silicon / Intel 均可),系统自带 `say` 命令,**无需安装任何软件**。
|
|
81
|
+
- 中文音色与 Siri 音色的选择入口/坑见 [macOS](#macos) 一节。
|
|
82
|
+
|
|
83
|
+
### DSH 版本
|
|
84
|
+
|
|
85
|
+
- 已在 **DSH 0.1.5-rc.1** 上验证。0.1.1 之后有两处 host/客户端 API 变更,本插件
|
|
86
|
+
1.8.0 均已适配:
|
|
87
|
+
- `@deepseek-ai/dsh-settings` 删除了 `installSettingsSection` /
|
|
88
|
+
`settingsNamespace` 两个辅助导出——插件改为通过 `settings` **服务**注册
|
|
89
|
+
namespace(旧版本上原实现会让宿主启动直接崩掉:
|
|
90
|
+
`settingsNamespace is not a function`)。没有 settings provider 时,插件照旧
|
|
91
|
+
按 patch `config` 工作。
|
|
92
|
+
- Session snapshot 不再携带会话视图(Conversation target)数据——🔊 按钮改为
|
|
93
|
+
通过 Chat 目标的 hook `useChat` 取被点击消息的文本。
|
|
94
|
+
- 宿主要求声明在 dsh-market 实际读取的位置:`package.json` 的 `engines.dsh`
|
|
95
|
+
(`>=0.1.5-rc.1`)。市场卡片与「适配当前 DSH」筛选读的正是这个字段,因此只有在
|
|
96
|
+
某个宿主版本上实测通过后,这个下限才会移动。
|
|
97
|
+
|
|
98
|
+
## 安装与快速开始
|
|
99
|
+
|
|
100
|
+
### DSH — 方式 A:npm 插件(推荐)
|
|
101
|
+
|
|
102
|
+
```powershell
|
|
103
|
+
# 1. 把插件装进你的 web profile(会写入 ~/.dsh/profiles/web/package.json 的 dependencies)
|
|
104
|
+
dsh plugin --profile web add dsh-speak
|
|
105
|
+
|
|
106
|
+
# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 里注册(npm 包直接用包名,无需 file:/// URL):
|
|
107
|
+
# - insert:
|
|
108
|
+
# - id: speech-hook
|
|
109
|
+
# name: 'dsh-speak'
|
|
110
|
+
|
|
111
|
+
# 3. 重启 DSH web 应用 — 之后回复会被自动播报
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
> **没有 pnpm?** `dsh plugin` 内部转发给 pnpm,并非所有机器都装了。可以用 npm
|
|
115
|
+
> 直接完成同样的安装:
|
|
116
|
+
>
|
|
117
|
+
> ```powershell
|
|
118
|
+
> npm install --prefix "$env:USERPROFILE\.dsh\profiles\web" dsh-speak
|
|
119
|
+
> ```
|
|
120
|
+
>
|
|
121
|
+
> macOS(bash):
|
|
122
|
+
>
|
|
123
|
+
> ```bash
|
|
124
|
+
> npm install --prefix "$HOME/.dsh/profiles/web" dsh-speak
|
|
125
|
+
> ```
|
|
126
|
+
|
|
127
|
+
引擎随包分发(`node_modules/dsh-speak/engine/`),无需额外拷贝。
|
|
128
|
+
|
|
129
|
+
> **想让 Agent 帮你装?** 把本仓库地址(`https://github.com/Alan2Z/dsh-speak`)
|
|
130
|
+
> 丢给你的 DSH 会话,让它照着这份 README 安装即可——它读的就是你正在看的这份文档。
|
|
131
|
+
> 只需要同意它对 `~/.dsh`(工作区外)的写入审批。
|
|
132
|
+
|
|
133
|
+
### DSH — 方式 B:文件安装(不需要 npm)
|
|
134
|
+
|
|
135
|
+
```powershell
|
|
136
|
+
# 1. 克隆
|
|
137
|
+
git clone https://github.com/Alan2Z/dsh-speak.git
|
|
138
|
+
cd dsh-speak
|
|
139
|
+
|
|
140
|
+
# 2. 一键安装:拷贝引擎 + 插件,并注册到 cordis.patch.yml
|
|
141
|
+
powershell.exe -NoProfile -ExecutionPolicy Bypass -File adapters\dsh\install.ps1
|
|
142
|
+
|
|
143
|
+
# 3. 验证引擎能出声
|
|
144
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File "$env:USERPROFILE\.dsh\hooks\speak.ps1" -Text "你好,语音播报已就绪。"
|
|
145
|
+
|
|
146
|
+
# 4. 重启 DSH web 应用 — 之后回复会被自动播报
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
文件安装脚本做了这些事:
|
|
150
|
+
|
|
151
|
+
| 文件 | 目标位置 |
|
|
152
|
+
| ---- | -------- |
|
|
153
|
+
| `engine/*.ps1` | `%USERPROFILE%\.dsh\hooks\` |
|
|
154
|
+
| `adapters/dsh/speech-hook.js` | `%USERPROFILE%\.dsh\profiles\web\plugins\` |
|
|
155
|
+
| 注册条目 | 追加到 `%USERPROFILE%\.dsh\profiles\web\cordis.patch.yml`(先备份) |
|
|
156
|
+
|
|
157
|
+
### macOS
|
|
158
|
+
|
|
159
|
+
同一套适配层原生支持 macOS——插件自动检测平台,改调 `engine/speak.sh`
|
|
160
|
+
(系统自带的 `say` 命令)而不是 `speak.ps1`。**自 1.2.0 起 macOS 引擎随 npm 包
|
|
161
|
+
正式分发**,无需安装任何额外软件。
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
# 1. 装进你的 web profile(没有 pnpm 也能装——dsh plugin 才依赖 pnpm)
|
|
165
|
+
npm install --prefix "$HOME/.dsh/profiles/web" dsh-speak
|
|
166
|
+
|
|
167
|
+
# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 末尾注册(裸包名即可,无需 file:/// URL):
|
|
168
|
+
# - insert:
|
|
169
|
+
# - id: speech-hook
|
|
170
|
+
# name: 'dsh-speak'
|
|
171
|
+
|
|
172
|
+
# 3. 无需重启——patch 监视器会热更新;回复在节流后(约 1.5 秒)自动播报;
|
|
173
|
+
# 带工具调用的回复会在回合结束时补播最终回复
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
> 装过 pnpm 也可以 `dsh plugin --profile web add dsh-speak`,效果相同。
|
|
177
|
+
|
|
178
|
+
#### 音色(重要,有两个坑)
|
|
179
|
+
|
|
180
|
+
- 默认跟随**系统朗读声音**(系统设置 → 辅助功能 → 朗读内容 → 系统朗读声音)。
|
|
181
|
+
**macOS 26** 上该选择框旁有个 **ⓘ 圆圈图标**,点开才是完整音色列表——普通
|
|
182
|
+
下拉框里**没有 Siri 自然音色**;可在 ⓘ 列表里选"普通话 Siri 声音1(男声)"等。
|
|
183
|
+
- **Siri 声音**(设置 → Siri → 声音)与系统朗读声音是**两个独立设置**;Siri
|
|
184
|
+
音色不暴露给 `say -v '?'`,无法按名选择,只能作为系统默认生效。
|
|
185
|
+
- ⚠️ **坑 1(实测复现)**:打开"朗读内容 / Siri 声音"设置面板(**哪怕不改任何
|
|
186
|
+
选项**)会把系统朗读声音漂移/重置成经典音色"婷婷(Tingting)"——音色突然变了
|
|
187
|
+
就回到 ⓘ 入口重新选择。
|
|
188
|
+
- ⚠️ **坑 2**:日志在 `$TMPDIR/dsh-speech-hook.log`(`os.tmpdir()`,**不是**
|
|
189
|
+
`/tmp`)。
|
|
190
|
+
- 想强制指定音色用 `-v Eddy|Flo|Tingting`(`say -v '?'` 列出可用音色)。
|
|
191
|
+
- `say` 没有音量参数——音量跟随系统输出音量。
|
|
192
|
+
|
|
193
|
+
#### 单独测试引擎(不装 DSH 也行)
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
curl -sfL -o ~/speak.sh "https://cdn.jsdelivr.net/gh/Alan2Z/dsh-speak@main/engine/speak.sh"
|
|
197
|
+
chmod +x ~/speak.sh
|
|
198
|
+
~/speak.sh -t "你好,Mac 版语音播报测试"
|
|
199
|
+
~/speak.sh -t "测试" -v Eddy -r 200 # 指定音色 + 语速
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Claude Code
|
|
203
|
+
|
|
204
|
+
在 `~/.claude/settings.json` 注册 Stop hook:
|
|
205
|
+
|
|
206
|
+
```json
|
|
207
|
+
{
|
|
208
|
+
"hooks": {
|
|
209
|
+
"Stop": [
|
|
210
|
+
{
|
|
211
|
+
"hooks": [
|
|
212
|
+
{
|
|
213
|
+
"type": "command",
|
|
214
|
+
"command": "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\\path\\to\\dsh-speak\\adapters\\claude-code\\stop-hook.ps1"
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 其他任何 harness
|
|
224
|
+
|
|
225
|
+
直接从你的 Agent / 包装脚本 / 工具里调用引擎:
|
|
226
|
+
|
|
227
|
+
```powershell
|
|
228
|
+
# 播报一句话
|
|
229
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File engine\speak.ps1 -Text "构建完成"
|
|
230
|
+
|
|
231
|
+
# 播报较长总结(阻塞,读完才返回)
|
|
232
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File engine\speech-summary.ps1 -Text "…"
|
|
233
|
+
|
|
234
|
+
# 需要用户注意时(阻塞,适合提问/授权场景)
|
|
235
|
+
powershell -NoProfile -ExecutionPolicy Bypass -File engine\speech-prompt.ps1 -Text "请做出选择"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 配置
|
|
239
|
+
|
|
240
|
+
### 引擎参数
|
|
241
|
+
|
|
242
|
+
详见 [docs/DESIGN.zh-CN.md §5 配置参考](docs/DESIGN.zh-CN.md#5-配置参考):
|
|
243
|
+
|
|
244
|
+
```powershell
|
|
245
|
+
speak.ps1 -Text "…" -Volume 50 -Rate 1 -MaxChars 300 -LongTextMessage "本次播报内容较长,请自行阅读。"
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### DSH 插件配置
|
|
249
|
+
|
|
250
|
+
**两种改法,任选其一**(改 UI 或改 YAML 都写进同一个 settings 文档,彼此同步):
|
|
251
|
+
|
|
252
|
+
1. **Web UI(1.7.0,推荐)**:设置 → dsh-speak 设置独立设置页。所有配置项都能直接改并
|
|
253
|
+
保存(`dsh --dump-config` 可见、按 profile 隔离、升级不丢)。
|
|
254
|
+
2. **profile patch 的 `config` 块**(等效):
|
|
255
|
+
|
|
256
|
+
```yaml
|
|
257
|
+
# ~/.dsh/profiles/web/cordis.patch.yml
|
|
258
|
+
- insert:
|
|
259
|
+
- id: speech-hook
|
|
260
|
+
name: 'dsh-speak'
|
|
261
|
+
config:
|
|
262
|
+
enabled: true # 总开关:false 时完全不播报
|
|
263
|
+
automaticSpeech: true # 自动朗读最终回复
|
|
264
|
+
queueAllMessages: false # true = 所有 assistant 消息立即入队朗读(中间消息也读)
|
|
265
|
+
replayFullRead: false # true = 手动重播跳过超长文本截断,完整朗读
|
|
266
|
+
cleanMarkdownFormatting: true # Markdown 转自然语音
|
|
267
|
+
readInlineCode: true # 朗读行内代码(去掉反引号)
|
|
268
|
+
codeBlocks: smart # all | smart | replace(围栏代码块)
|
|
269
|
+
codeBlockMaxChars: 300 # smart 模式下的代码块字数上限
|
|
270
|
+
codeBlockReplacementText: 'You can see the code in our history.' # replace 时的替代文本
|
|
271
|
+
throttleMs: 1500 # 播报前的合并延迟(毫秒)
|
|
272
|
+
engine: '' # 引擎路径覆盖;'' = 自动解析
|
|
273
|
+
announceApprovals: true # 播报审批请求
|
|
274
|
+
announceQuestions: true # 播报 ask_user_question 提问内容
|
|
275
|
+
stripApprovalPrefix: true # 剥离审批原因里的 "escalate sandbox to ...: " 前缀
|
|
276
|
+
questionGapMs: 2000 # 多个提问播报之间的停顿(毫秒)
|
|
277
|
+
longTextMode: message # message | heading(念最大字号 markdown 标题)
|
|
278
|
+
longTextMessage: '本次播报内容较长,请自行阅读。' # message 模式下的固定提示语
|
|
279
|
+
maxChars: 300 # 引擎单次朗读字数上限(macOS 默认 0 = 不限)
|
|
280
|
+
volume: 50 # 仅 Windows
|
|
281
|
+
rate: 0 # 0 = 引擎默认(Windows SAPI 刻度 / macOS wpm)
|
|
282
|
+
# —— 可选事件播报(1.6.0,默认全关)——
|
|
283
|
+
announceTurnEnd: false # 回合结束("第 N 轮对话完成")
|
|
284
|
+
announceCommandDone: false # 命令完成/失败(command/done)
|
|
285
|
+
announceGoalChange: false # 目标创建/更新/完成(goal/change)
|
|
286
|
+
announceToolErrors: false # 工具调用出错时播报(英文详情截掉,tool/result)
|
|
287
|
+
announceTodoWrite: false # 待办列表更新(todo/write)
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
> 解析顺序:schema 默认值 → patch `config` → UI 用户设置。写进 YAML 的字段
|
|
291
|
+
> 同样出现在 UI 中。平台差异:`maxChars` 在 macOS 默认 0(`say` 无上限),
|
|
292
|
+
> Windows 默认 300(SAPI 安全上限)。
|
|
293
|
+
|
|
294
|
+
#### 选项说明
|
|
295
|
+
|
|
296
|
+
| 选项 | 默认值 | 效果 |
|
|
297
|
+
| ---- | ------ | ---- |
|
|
298
|
+
| `enabled` | `true` | **总开关**:关闭后所有播报都不触发(最终回复/审批/提问/可选事件/重播) |
|
|
299
|
+
| `automaticSpeech` | `true` | 自动朗读最终回复;手动重播始终可用 |
|
|
300
|
+
| `queueAllMessages` | `false` | `true` 时每条 assistant 消息立即入队朗读(中间消息也读,FIFO);默认只读节流后的最终回复 |
|
|
301
|
+
| `replayFullRead` | `false` | `true` 时手动重播跳过超长文本的标题截断(`longTextMode: heading`),完整分段朗读 |
|
|
302
|
+
| `cleanMarkdownFormatting` | `true` | 把 Markdown 转成自然语音文本(链接保留文字去 URL、标题/强调符号清理) |
|
|
303
|
+
| `readInlineCode` | `true` | 朗读行内代码(去掉反引号标记) |
|
|
304
|
+
| `codeBlocks` | `smart` | 围栏代码块处理:`all` 全读 / `smart`(≤`codeBlockMaxChars` 才读)/ `replace` 用替代文本 |
|
|
305
|
+
| `codeBlockMaxChars` | `300` | `smart` 模式下的代码块字数上限 |
|
|
306
|
+
| `codeBlockReplacementText` | `You can see the code in our history.` | `replace` 模式(或超限的 `smart`)下朗读的替代文本 |
|
|
307
|
+
| `throttleMs` | `1500` | 回复文本等待多久才播报(合并同一回复的多步消息) |
|
|
308
|
+
| `engine` | `''` | 显式引擎脚本路径;`''` 自动解析:包内 `engine/<平台>` → `~/.dsh/hooks/<平台>` |
|
|
309
|
+
| `announceApprovals` | `true` | 播报 `approval/asked` 事件(审批原因,或固定提示语) |
|
|
310
|
+
| `announceQuestions` | `true` | 播报 `ask_user_question`:每个问题单独朗读,带"问题N"序号(多问题时)与"选项N"序号(与 UI 编号一致);多个问题之间停顿 `questionGapMs` |
|
|
311
|
+
| `questionGapMs` | `2000` | 多个提问播报之间的停顿(毫秒),0 = 不停顿 |
|
|
312
|
+
| `stripApprovalPrefix` | `true` | 剥离审批原因里的固定英文模板前缀(`escalate sandbox to danger-full-access: `),保留中文说明 |
|
|
313
|
+
| `longTextMode` | `message` | `message` = 超长念固定提示语;`heading` = 改念最大字号 markdown 标题(规则见下) |
|
|
314
|
+
| `longTextMessage` | `本次播报内容较长,请自行阅读。` | `message` 模式下超长文本改念的固定提示语(UI 可编辑) |
|
|
315
|
+
| `maxChars` | 平台相关 | 引擎单次朗读上限。**macOS 默认 0(`say` 无上限);Windows 默认 300**(SAPI 超过约 375-470 字会静默失败) |
|
|
316
|
+
| `volume` | `50` | 仅 Windows(0-100);macOS 音量跟随系统 |
|
|
317
|
+
| `rate` | `0` | 语速:Windows SAPI 刻度(-10 到 10,0 = 正常,推荐 0 / 稍快 1-3);macOS words-per-minute(默认 175,稍快 200) |
|
|
318
|
+
| `announceTurnEnd` | `false` | 回合结束时播报"第 N 轮对话完成/中断/异常结束"(`turn/end`) |
|
|
319
|
+
| `announceCommandDone` | `false` | 命令执行完成/失败时播报(`command/done`) |
|
|
320
|
+
| `announceGoalChange` | `false` | 目标创建/更新/完成/暂停/恢复时播报(`goal/change`,含目标标题前 40 字) |
|
|
321
|
+
| `announceToolErrors` | `false` | 工具调用返回错误时播报"工具调用出错"(英文错误详情/技术 code 截掉,只保留中文详情)。触发条件:`tool/result` 带 `error`(结构化失败身份)或结果块 `isError === true`。注意 **shell 命令非零退出不算**——pwsh/bash 把 `exit code: N` 当结果数据上报(dsh 明文如此设计),只有基础设施失败(spawn 错误、abort)和 fs 这类结构化失败才置 `isError` |
|
|
322
|
+
| `announceTodoWrite` | `false` | agent 更新待办列表时播报"待办已更新:n/m 完成"(`todo/write`) |
|
|
323
|
+
|
|
324
|
+
#### 超长文本模式
|
|
325
|
+
|
|
326
|
+
清洗后文本超过 `maxChars` 时:
|
|
327
|
+
|
|
328
|
+
- **`message`**(默认):念 `longTextMessage`(`本次播报内容较长,请自行阅读。`,
|
|
329
|
+
可在 UI 或 YAML 里编辑)。
|
|
330
|
+
- **`heading`**:在原始文本里挑**最大字号**的 markdown 标题——`#` 数量最少者优先,
|
|
331
|
+
并列取第一个。**整段没有任何标题时**改念"有头有尾的开头":取开头 `maxChars`
|
|
332
|
+
长度的窗口并回退到窗口内最后一个句末标点;若这样会砍掉半个窗口以上则保留整窗。
|
|
333
|
+
句末标点中英双语识别:全角 `。!?;` 与 `…` 无条件算;半角 `.!?;` 只在后面跟
|
|
334
|
+
空白、右引号/右括号时才算,落在窗口最后一位时会**多读一位**判断——所以英文
|
|
335
|
+
「句号+空格」在边缘照样算,而 `Version 0.1.` 这种小数点不算。(1.8.0 之前这里只念
|
|
336
|
+
第一个非空行,听感上就是"从第二行开始不念了"。)选中的候选仍会清洗并受 `maxChars`
|
|
337
|
+
上限约束,若其本身仍超长则回退提示语。
|
|
338
|
+
|
|
339
|
+
完整架构与设计取舍见 [docs/DESIGN.zh-CN.md](docs/DESIGN.zh-CN.md)。
|
|
340
|
+
|
|
341
|
+
## 自定义(升级不丢)
|
|
342
|
+
|
|
343
|
+
想调行为又不想 fork,而且改完**不会被 `npm update` 覆盖**:
|
|
344
|
+
|
|
345
|
+
1. **把引擎复制出来改**(推荐——默认参数都在这:音量、语速、字数上限、超长提示语、音色逻辑):
|
|
346
|
+
|
|
347
|
+
```powershell
|
|
348
|
+
# Windows
|
|
349
|
+
Copy-Item "$env:USERPROFILE\.dsh\profiles\web\node_modules\dsh-speak\engine\speak.ps1" "$env:USERPROFILE\.dsh\hooks\my-speak.ps1"
|
|
350
|
+
# macOS
|
|
351
|
+
cp ~/.dsh/profiles/web/node_modules/dsh-speak/engine/speak.sh ~/.dsh/hooks/my-speak.sh
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
然后在 config 块里指向你的副本:
|
|
355
|
+
|
|
356
|
+
> **Windows:务必保住文件的 UTF-8 BOM。** `speak.ps1` 是 UTF-8 脚本,而 Windows
|
|
357
|
+
> PowerShell 5.1 只能靠开头那三个字节 `EF BB BF` 知道这一点;编辑器保存时若把它
|
|
358
|
+
> 丢掉,系统会改用 ANSI 代码页解码,脚本里的中文会变乱码——症状是**静默无声或
|
|
359
|
+
> 修剪错乱,且不报错**。为此仓库里的脚本已把**逻辑部分全部写成纯 ASCII**,所以
|
|
360
|
+
> 丢 BOM 只会让中文注释和默认提示语变乱码。改完可以用
|
|
361
|
+
> `Get-Content -Encoding Byte -TotalCount 3 你的-speak.ps1` 检查(应为 `239 187 191`),
|
|
362
|
+
> 或跑 `node scripts/test-engine-static.js`。
|
|
363
|
+
|
|
364
|
+
```yaml
|
|
365
|
+
- insert:
|
|
366
|
+
- id: speech-hook
|
|
367
|
+
name: 'dsh-speak'
|
|
368
|
+
config:
|
|
369
|
+
engine: 'C:/Users/<你>/.dsh/hooks/my-speak.ps1' # macOS 用 ~/.dsh/hooks/my-speak.sh
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
插件按 `config.engine` → 包内引擎 → `~/.dsh/hooks/` 的顺序解析引擎,所以你的副本
|
|
373
|
+
优先生效;`npm update` 只动包本身,你的引擎安然无恙。
|
|
374
|
+
|
|
375
|
+
2. **直接改 `node_modules` 里的文件**——能改,但下次 `npm update` 会被覆盖。
|
|
376
|
+
|
|
377
|
+
3. **fork 仓库**——完全掌控,想发自己的包也行。
|
|
378
|
+
|
|
379
|
+
## 排障
|
|
380
|
+
|
|
381
|
+
| 现象 | 原因 | 解决 |
|
|
382
|
+
| ---- | ---- | ---- |
|
|
383
|
+
| 完全没有声音、无报错 | 未启用/安装自然语音 | Win11:在 设置 → 讲述人/语音 中启用自然语音;Win10:安装 NaturalVoiceSAPIAdapter 并下载语音包。直接测 `speak.ps1` |
|
|
384
|
+
| 长回复从不播报 | 适配器单次 `Speak` 有字数上限 | 已默认在 300 字处守卫——必要时调低 `-MaxChars` |
|
|
385
|
+
| 念到第二行就停/像是被切断 | `longTextMode: heading` 下,文本超过 `maxChars` 且整段没有 markdown 标题时,旧版引擎只念第一个非空行(1.8.0 之前) | 1.8.0 已修(改念"有头有尾的开头");想换策略可用 `message` 模式或调高 `maxChars` |
|
|
386
|
+
| 听到 `工具调用出错:Error: cannot read …` | "是否中文"的详情判据只检查"含有汉字",英文报错里夹着中文目录名就能骗过它(1.8.0 引入的回归) | 1.8.0 已修——详情需满足"汉字数量多于拉丁字母数量" |
|
|
387
|
+
| 含大量 emoji 的文本静默 | SAPI 遇到 emoji 会静默失败 | 引擎已自动剥离 |
|
|
388
|
+
| 插件加载失败 | 插件名用了 Windows 原始路径 | 改用 `file:///C:/…` URL 形式(安装脚本会自动处理) |
|
|
389
|
+
| macOS:音色突然变成"婷婷" | 打开过"朗读内容 / Siri 声音"设置面板导致系统朗读声音漂移 | 系统设置 → 辅助功能 → 阅读与朗读 → 系统声音 → ⓘ 入口重新选择 |
|
|
390
|
+
| macOS:在 `/tmp` 找不到日志 | `os.tmpdir()` 是 `/var/folders/.../T`,不是 `/tmp` | 日志在 `$TMPDIR/dsh-speech-hook.log` |
|
|
391
|
+
|
|
392
|
+
插件诊断日志:Windows `%TEMP%\dsh-speech-hook.log`;macOS `$TMPDIR/dsh-speech-hook.log`
|
|
393
|
+
|
|
394
|
+
## 仓库结构
|
|
395
|
+
|
|
396
|
+
```
|
|
397
|
+
engine/ 与 harness 无关的语音引擎(PowerShell + SAPI5 / bash + say)
|
|
398
|
+
speak.ps1 / speak.sh 清洗 + 朗读(适配层唯一需要打交道的接口)
|
|
399
|
+
speech-prompt.ps1 阻塞式短提示播报
|
|
400
|
+
speech-summary.ps1 阻塞式回复总结播报
|
|
401
|
+
adapters/
|
|
402
|
+
dsh/ DSH web 插件 + 一键安装脚本
|
|
403
|
+
speech-hook.js 会话事件触发器(节流/取消 + 可选事件 + FIFO 语音队列 + WebSocket + settings 注册)
|
|
404
|
+
install.ps1 拷贝 + 注册 + 备份
|
|
405
|
+
claude-code/
|
|
406
|
+
stop-hook.ps1 Claude Code Stop hook 触发器
|
|
407
|
+
client/
|
|
408
|
+
client.js DSH 浏览器端 bundle:回合尾部 Speak/Stop 按钮 + 设置 → dsh-speak 设置页
|
|
409
|
+
docs/
|
|
410
|
+
DESIGN.zh-CN.md 完整设计文档:设计取舍、踩坑记录、扩展指南
|
|
411
|
+
scripts/ 测试 + 手动开发辅助脚本(不随 npm 包发布)
|
|
412
|
+
test-engine-static.js 引擎静态不变量:.ps1 的 BOM + PowerShell 语法解析、.sh 的 LF(prepublishOnly 也会跑)
|
|
413
|
+
test-engine-longtext.js 两个引擎的长文守卫契约(speak.ps1 -DryRun / speak.sh 的 perl)
|
|
414
|
+
test-speech-hook.js 宿主插件:事件触发、队列、工具出错详情过滤
|
|
415
|
+
test-client-bundle.js 浏览器 bundle:slot 注册 + 组件渲染
|
|
416
|
+
test-settings-integration.js settings 服务接线 + 已删除 API 的回归守卫
|
|
417
|
+
session-log-dump.js 读取 DSH 会话日志(手动:看引擎究竟收到了什么文本)
|
|
418
|
+
settings-ui-check.py Playwright UI 检查(手动:需要运行中且已鉴权的 dsh)
|
|
419
|
+
dsh-events-check.py Playwright 折叠行检查(手动)
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
## 编写新适配器
|
|
423
|
+
|
|
424
|
+
三种参考模式:**事件流**(DSH)、**Stop hook**(Claude Code)、**Agent 自调用**
|
|
425
|
+
(在 shell 里调 `speech-summary.ps1`)。无论哪种,适配器只需做一件事:
|
|
426
|
+
拿到*最终回复文本* → 调用引擎。详见
|
|
427
|
+
[docs/DESIGN.zh-CN.md §7 扩展](docs/DESIGN.zh-CN.md#7-扩展)。
|
|
428
|
+
|
|
429
|
+
## License
|
|
430
|
+
|
|
431
|
+
MIT — 见 [LICENSE](LICENSE)。
|
|
432
|
+
|
|
433
|
+
[NaturalVoiceSAPIAdapter]: https://github.com/gexgd0419/NaturalVoiceSAPIAdapter
|