dsh-notify-say 0.4.24 → 0.4.26

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.
Files changed (53) hide show
  1. package/README.md +216 -176
  2. package/docs/audio-audit/README.md +164 -0
  3. package/docs/audio-audit/fetch-snapshots.ps1 +76 -0
  4. package/docs/audio-audit/snapshots/ameharu-hau.txt +89 -0
  5. package/docs/audio-audit/snapshots/goki-nuigurumi.txt +73 -0
  6. package/docs/audio-audit/snapshots/kasukabe-tsumugi.txt +197 -0
  7. package/docs/audio-audit/snapshots/manbetsu-hanamaru.txt +27 -0
  8. package/docs/audio-audit/snapshots/meimei-meria.txt +84 -0
  9. package/docs/audio-audit/snapshots/mochiko.txt +27 -0
  10. package/docs/audio-audit/snapshots/namiine-ritsu.txt +76 -0
  11. package/docs/audio-audit/snapshots/shirakami-kotaro.txt +158 -0
  12. package/docs/audio-audit/snapshots/sss-anonymous-common.txt +142 -0
  13. package/docs/audio-audit/snapshots/sss-zundamon.txt +142 -0
  14. package/docs/audio-audit/snapshots/voicevox-software.txt +41 -0
  15. package/docs/audio-audit/snapshots/voicevox-vvm-terms.txt +385 -0
  16. package/docs/audio-audit/snapshots/yurei-chan.txt +112 -0
  17. package/docs//345/276/205/345/201/232/346/270/205/345/215/225.md +218 -0
  18. package/docs//350/257/255/351/237/263/345/214/205/345/210/206/345/217/221/346/226/271/346/241/210-/345/276/205/345/256/241/351/230/205.md +378 -0
  19. package/lib/client.js +10 -1
  20. package/lib/config-route.js +4 -1
  21. package/lib/dev-reload.js +647 -617
  22. package/lib/http-guard.js +222 -212
  23. package/lib/session-bridge.js +138 -117
  24. package/package.json +11 -2
  25. package/test/audio-source.test.mjs +184 -0
  26. package/test/audio-wiring.test.mjs +287 -0
  27. package/test/client-bundle.test.mjs +671 -0
  28. package/test/client-contract.test.mjs +118 -0
  29. package/test/config-coverage.test.mjs +109 -0
  30. package/test/config-route.test.mjs +212 -0
  31. package/test/config-schema.test.mjs +147 -0
  32. package/test/config-store.test.mjs +256 -0
  33. package/test/dev-reload.test.mjs +132 -0
  34. package/test/effective-for-client.test.mjs +142 -0
  35. package/test/fail-route.test.mjs +128 -0
  36. package/test/fail-voice.test.mjs +193 -0
  37. package/test/http-guard.test.mjs +143 -0
  38. package/test/http-integration.test.mjs +284 -0
  39. package/test/idle-gate.test.mjs +167 -0
  40. package/test/preview.test.mjs +92 -0
  41. package/test/real-cordis.test.mjs +204 -0
  42. package/test/release-voice-guard.test.mjs +185 -0
  43. package/test/reload-live.test.mjs +261 -0
  44. package/test/reload-verification.test.mjs +218 -0
  45. package/test/route-loader-register.mjs +22 -0
  46. package/test/scalar-guard.test.mjs +125 -0
  47. package/test/session-jump.test.mjs +266 -0
  48. package/test/stub-child-process.mjs +43 -0
  49. package/test/tts-lines.test.mjs +112 -0
  50. package/test/version-consistency.test.mjs +98 -0
  51. package/test/voice-availability.test.mjs +90 -0
  52. package/test/wav-gain.test.mjs +138 -0
  53. package/test/wiring.test.mjs +287 -0
package/README.md CHANGED
@@ -1,179 +1,219 @@
1
- # dsh-notify-desktop
2
-
3
- 给 [DeepSeek Harness](https://github.com/deepseek-ai) Desktop 用的通知插件:**任务跑完会说话**。
4
-
5
- > 别的通知插件"叮"一声;这个会喊你"主人、任务完成了"。
6
- > 而且**子代理还在跑的时候,它不会骗你说完成了**。
7
-
8
- ---
9
-
10
- ## 它解决什么问题
11
-
12
- 你让 AI 跑一个较长任务,然后切去干别的。常见两种通知插件的毛病:
13
-
14
- 1. **该响的时候不响** —— 主会话一轮结束就报"完成",但其实它派出的子代理还在跑,你回来发现没干完。
15
- 2. **不该响的时候一直响** —— 每个子代理结束都弹一次,连环轰炸。
16
-
17
- 本插件的做法:
18
-
19
- - **空闲门(idle gate)**:主会话这轮结束、但仍有子代理或后台任务在跑时,**先不播**;等全部结束再播**一次**。超时(默认 10 分钟)兜底,防子任务卡死导致永不播报。
20
- - **按会话去抖**:同一会话 60 秒内只响一次。
21
- - **失败单独提醒**:回合出错时播**日语道歉语音**(可选),比"任务完成"更该让你立刻知道。
22
-
23
- ---
24
-
25
- ## 特性
26
-
27
- | 特性 | 说明 |
28
- |---|---|
29
- | **语音播报** | 本地 wav,不联网、不调用云端 TTS。发布版附 1 个音色,其余可按需下载 |
30
- | **空闲门** | 有在飞工作时不误报"完成",全部结束才播一次 |
31
- | **五类事件** | 完成 / 出错 / 被拦截 / 待批准 / 要提问,各自独立开关 |
32
- | **设置页 GUI** | 走官方 `Config` schema,DSH 设置页自动生成表单 |
33
- | **命令行** | `tools/notify-config.ps1`,改完**立即生效、不用重启** |
34
- | **点通知跳会话** | 点击 Toast 可直接回到对应会话(拿不到导航服务时自动降级为"唤出窗口") |
35
- | **不装语音也能用** | 没有语音包 = Toast + 系统提示音,这是正常配置 |
36
- | **全离线** | 不联网、不发送任何会话内容 |
37
-
38
- ---
39
-
40
- ## 安装
41
-
42
- ### 前置
43
-
44
- - DSH Desktop **0.1.7-rc.2 或更高**
45
- - Windows(Toast 用 WinRT,播放用 MCI;暂不支持 macOS/Linux)
46
-
47
- ### 方式一:插件页(推荐)
48
-
49
- 在 DSH 的 **设置 → 插件** 里搜索 `dsh-notify-desktop` 安装。
50
-
51
- ### 方式二:手工 link(本地开发)
52
-
53
- 把本仓库目录链接进 profile:
54
-
55
- ```
56
- D:\Program Files (x86)\DSH\profiles\desktop\package.json
57
- dependencies 里加: "dsh-notify-desktop": "link:<本仓库路径>"
58
- dsh.profile.bundles 里加: "dsh-notify-desktop"
59
- ```
60
-
61
- 然后在该 profile 目录执行 `pnpm install`,重启 DSH。
62
-
63
- ---
64
-
65
- ## 配置
66
-
67
- 三种方式,优先级由低到高(后者覆盖前者):
68
-
69
- ```
70
- 1. schema 默认值
71
- 2. cordis.patch.yml 的 config
72
- 3. DSH 设置页里改的值
73
- 4. tools/notify-config.ps1 写的 storages/config.json
74
- ```
75
-
76
- > ⚠️ **注意语义**:一旦你在设置页改过某项,再改 `cordis.patch.yml` 里同一项**不再生效**。
77
- > 这是 DSH 官方设计(用户层优先级更高),不是本插件的 bug。
78
-
79
- ### 设置页
80
-
81
- DSH **设置 → 通知**(由官方 Loader 从本插件的 `Config` schema 自动生成),共 12 项:
82
-
83
- 语音开关、音色模式(固定/随机)、音色名、音量,
84
- 以及完成/出错/被拦截/已中止/待批准/要提问/子代理/空闲门 八个开关。
85
-
86
- ### 命令行
87
-
88
- ```powershell
89
- cd <插件目录>\tools
90
-
91
- .\notify-config.ps1 -Show # 看当前生效值
92
- .\notify-config.ps1 -Voice off # 静音(Toast 仍弹)
93
- .\notify-config.ps1 -Volume 40
94
- .\notify-config.ps1 -VoiceMode random
95
- .\notify-config.ps1 -VoiceName ankomon
96
- .\notify-config.ps1 -Disable aborted -Enable subagents
97
- .\notify-config.ps1 -Clear # 交还控制权给设置页
98
- ```
99
-
100
- 改完**立即生效**,不需要重启 DSH。
101
-
102
- ### 语音包管理
103
-
1
+ # dsh-notify-say
2
+
3
+ 给 [DeepSeek Harness](https://github.com/deepseek-ai) Desktop 用的通知插件:**任务跑完会说话**。
4
+
5
+ > 别的通知插件"叮"一声;这个会喊你"主人、任务完成了"。
6
+ > 而且**子代理还在跑的时候,它不会骗你说完成了**。
7
+
8
+ ---
9
+
10
+ ## 它解决什么问题
11
+
12
+ 你让 AI 跑一个较长任务,然后切去干别的。常见两种通知插件的毛病:
13
+
14
+ 1. **该响的时候不响** —— 主会话一轮结束就报"完成",但其实它派出的子代理还在跑,你回来发现没干完。
15
+ 2. **不该响的时候一直响** —— 每个子代理结束都弹一次,连环轰炸。
16
+
17
+ 本插件的做法:
18
+
19
+ - **空闲门(idle gate)**:主会话这轮结束、但仍有子代理或后台任务在跑时,**先不播**;等全部结束再播**一次**。超时(默认 10 分钟)兜底,防子任务卡死导致永不播报。
20
+ - **按会话去抖**:同一会话 60 秒内只响一次。
21
+ - **失败单独提醒**:回合出错时播**日语道歉语音**(可选),比"任务完成"更该让你立刻知道。
22
+
23
+ ---
24
+
25
+ ## 特性
26
+
27
+ | 特性 | 说明 |
28
+ |---|---|
29
+ | **语音播报** | 本地 wav,不联网、不调用云端 TTS。发布版附 1 个音色,其余可按需下载 |
30
+ | **空闲门** | 有在飞工作时不误报"完成",全部结束才播一次 |
31
+ | **五类事件** | 完成 / 出错 / 被拦截 / 待批准 / 要提问,各自独立开关 |
32
+ | **设置页 GUI** | 走官方 `Config` schema,DSH 设置页自动生成表单 |
33
+ | **命令行** | `tools/notify-config.ps1`,改完**立即生效、不用重启** |
34
+ | **点通知跳会话** | 点击 Toast 可直接回到对应会话(拿不到导航服务时自动降级为"唤出窗口") |
35
+ | **不装语音也能用** | 没有语音包 = Toast + 系统提示音,这是正常配置 |
36
+ | **全离线** | 不联网、不发送任何会话内容 |
37
+
38
+ ---
39
+
40
+ ## 安装
41
+
42
+ ### 前置
43
+
44
+ - DSH Desktop **0.1.7-rc.2 或更高**
45
+ - Windows(Toast 用 WinRT,播放用 MCI;暂不支持 macOS/Linux)
46
+
47
+ ### 方式一:插件页(推荐)
48
+
49
+ 在 DSH 的 **设置 → 插件** 里搜索 `dsh-notify-say` 安装。
50
+
51
+ ### 方式二:手工 link(本地开发)
52
+
53
+ 把本仓库目录链接进 profile:
54
+
55
+ ```
56
+ D:\Program Files (x86)\DSH\profiles\desktop\package.json
57
+ dependencies 里加: "dsh-notify-say": "link:<本仓库路径>"
58
+ dsh.profile.bundles 里加: "dsh-notify-say"
59
+ ```
60
+
61
+ 然后在该 profile 目录执行 `pnpm install`,重启 DSH。
62
+
63
+ ---
64
+
65
+ ## 配置
66
+
67
+ 三种方式,优先级由低到高(后者覆盖前者):
68
+
69
+ ```
70
+ 1. schema 默认值
71
+ 2. cordis.patch.yml 的 config
72
+ 3. DSH 设置页里改的值
73
+ 4. tools/notify-config.ps1 写的 storages/config.json
74
+ ```
75
+
76
+ > ⚠️ **注意语义**:一旦你在设置页改过某项,再改 `cordis.patch.yml` 里同一项**不再生效**。
77
+ > 这是 DSH 官方设计(用户层优先级更高),不是本插件的 bug。
78
+
79
+ ### 设置页
80
+
81
+ DSH **设置 → 通知**(由官方 Loader 从本插件的 `Config` schema 自动生成),共 12 项:
82
+
83
+ 语音开关、音色模式(固定/随机)、音色名、音量,
84
+ 以及完成/出错/被拦截/已中止/待批准/要提问/子代理/空闲门 八个开关。
85
+
86
+ ### 命令行
87
+
88
+ ```powershell
89
+ cd <插件目录>\tools
90
+
91
+ .\notify-config.ps1 -Show # 看当前生效值
92
+ .\notify-config.ps1 -Voice off # 静音(Toast 仍弹)
93
+ .\notify-config.ps1 -Volume 40
94
+ .\notify-config.ps1 -VoiceMode random
95
+ .\notify-config.ps1 -VoiceName ankomon
96
+ .\notify-config.ps1 -Disable aborted -Enable subagents
97
+ .\notify-config.ps1 -Clear # 交还控制权给设置页
98
+ ```
99
+
100
+ 改完**立即生效**,不需要重启 DSH。
101
+
102
+ ### 语音包管理
103
+
104
104
  核心包只带**一个日语音色**(ずんだもん),体积约 2.8 MB。
105
- 完整多音色包体积较大(十余个音色约 40 MB),故不随包发布 —— 计划通过单独下载提供(尚未实现)。
106
-
107
- ```powershell
108
- .\notify-config.ps1 -ListPacks # 看已装哪些音色、各占多少
109
- .\notify-config.ps1 -PurgeVoice <key> # 删掉不用的音色
110
- .\notify-config.ps1 -InstallHint # 看怎么获取更多音色
111
- ```
112
-
113
- **不装任何语音包也完全可用**:通知会退回 Windows Toast + 系统提示音。
114
-
115
- 想要更多音色,两条路:
116
-
117
- 1. **自己合成**:装 [VOICEVOX](https://voicevox.hiroshiba.jp/)(本地免费 TTS),启动引擎(默认 `http://127.0.0.1:50021`),
118
- 然后按下面的命名规则把合成好的 wav 放进对应目录即可。
119
- (合成脚本不随本包发布——它依赖本地 VOICEVOX 引擎与特定音色表,放在发布包里只会误导。)
120
- 2. **手工放入**:把 wav 按下面的命名放进对应目录
121
-
122
- ```
123
- sounds/voice-lines/<key>~1.wav 完成
124
- sounds/voice-lines/question/<key>~1.wav 提问
125
- sounds/voice-lines/approval/<key>~1.wav 审批
126
- sounds/voice-lines/fail/<key>~1.wav 出错
127
- ```
128
-
129
- ---
130
-
131
- ## 兼容性与降级
132
-
133
- 本插件的首要目标是**稳定**,所以每个依赖外部能力的地方都有降级路径:
134
-
135
- | 能力 | 拿不到时怎么办 |
136
- |---|---|
137
- | `@deepseek-ai/schemastery`(生成设置页) | 不导出 `Config` → **设置页不出现,插件照常工作** |
138
- | `uiWorkspace.openSession`(点通知跳会话) | 不跳转,Toast 仍能唤出窗口(**退回旧行为**) |
139
- | 语音包 | 回退系统提示音 |
140
- | `$DSH_HOME` 未设置 | 配置走 patch 默认值;不写任何状态文件 |
141
-
142
- **不会出现"静默失效"**:每个降级都有明确行为,并有测试锁定。
143
-
144
- > 对比:某些插件写 `if (typeof sessions?.open === 'function') sessions.open(id)`,
145
- > 而 `sessions.open` 在 0.1.7+ 已被移除 —— 该功能**静默失效,用户点通知没反应却无从察觉**。
146
- > 详见 `CARD.md` 的 §零之二。
147
-
148
- ---
149
-
150
- ## 已知限制
151
-
152
- - **仅 Windows**(Toast = WinRT,播放 = MCI,调用 Windows PowerShell 5.1)
153
- - **设置页真实渲染尚未验证**(代码已就绪、schema 结构已测,但未在宿主里看过界面)
154
- - **点通知跳会话依赖未文档化 API**(`uiWorkspace`),官方随时可能改;坏了会自动降级
155
- - `blocked`(回合被拦截)只用系统蜂鸣,不播失败语音 —— 因为语义是"被拦下"而非"失败"
156
- - **`fail` 语音包只覆盖 16 个基础音色**(103 个音色里的其余 87 个只有完成语音)。选到未覆盖的音色时,失败会在同池内换一个音色,不会哑掉、也不会播错语义
157
-
158
- ---
159
-
160
- ## 开发
161
-
162
- ```powershell
163
- npm run test:all # 101 条测试
164
- npm test # 主套件(route 测试会 skip)
165
- npm run test:route # 需要 --import loader 的 6 条接线测试
166
- ```
167
-
168
- 测试分九组:空闲门判定(20)、事件接线(12)、会话跳转降级(11)、配置持久化(11)、
169
- 语音包(10)、失败语音(10)、Config schema(8)、失败路由(6)、真实 Cordis(5)。
170
-
171
- 全部通过才算提交就绪;关键断言做过**变异测试**(故意改坏代码确认测试变红)。
172
-
173
- ---
174
-
175
- ## 许可
176
-
105
+ 完整多音色包体积较大(十余个音色约 40 MB),故不随包发布 —— 计划通过单独下载提供(尚未实现)。
106
+
107
+ ```powershell
108
+ .\notify-config.ps1 -ListPacks # 看已装哪些音色、各占多少
109
+ .\notify-config.ps1 -PurgeVoice <key> # 删掉不用的音色
110
+ .\notify-config.ps1 -InstallHint # 看怎么获取更多音色
111
+ ```
112
+
113
+ **不装任何语音包也完全可用**:通知会退回 Windows Toast + 系统提示音。
114
+
115
+ 想要更多音色,两条路:
116
+
117
+ 1. **自己合成**:装 [VOICEVOX](https://voicevox.hiroshiba.jp/)(本地免费 TTS),启动引擎(默认 `http://127.0.0.1:50021`),
118
+ 然后按下面的命名规则把合成好的 wav 放进对应目录即可。
119
+ (合成脚本不随本包发布——它依赖本地 VOICEVOX 引擎与特定音色表,放在发布包里只会误导。)
120
+ 2. **手工放入**:把 wav 按下面的命名放进对应目录
121
+
122
+ ```
123
+ sounds/voice-lines/<key>~1.wav 完成
124
+ sounds/voice-lines/question/<key>~1.wav 提问
125
+ sounds/voice-lines/approval/<key>~1.wav 审批
126
+ sounds/voice-lines/fail/<key>~1.wav 出错
127
+ ```
128
+
129
+ ---
130
+
131
+ ## 兼容性与降级
132
+
133
+ 本插件的首要目标是**稳定**,所以每个依赖外部能力的地方都有降级路径:
134
+
135
+ | 能力 | 拿不到时怎么办 |
136
+ |---|---|
137
+ | `@deepseek-ai/schemastery`(生成设置页) | 不导出 `Config` → **设置页不出现,插件照常工作** |
138
+ | `uiWorkspace.openSession`(点通知跳会话) | 不跳转,Toast 仍能唤出窗口(**退回旧行为**) |
139
+ | 语音包 | 回退系统提示音 |
140
+ | `$DSH_HOME` 未设置 | 配置走 patch 默认值;不写任何状态文件 |
141
+
142
+ **不会出现"静默失效"**:每个降级都有明确行为,并有测试锁定。
143
+
144
+ > 对比:某些插件写 `if (typeof sessions?.open === 'function') sessions.open(id)`,
145
+ > 而 `sessions.open` 在 0.1.7+ 已被移除 —— 该功能**静默失效,用户点通知没反应却无从察觉**。
146
+ > 详见 `CARD.md` 的 §零之二。
147
+
148
+ ---
149
+
150
+ ## 已知限制
151
+
152
+ - **仅 Windows**(Toast = WinRT,播放 = MCI,调用 Windows PowerShell 5.1)
153
+ - **设置页真实渲染尚未验证**(代码已就绪、schema 结构已测,但未在宿主里看过界面)
154
+ - **点通知跳会话依赖未文档化 API**(`uiWorkspace`),官方随时可能改;坏了会自动降级
155
+ - `blocked`(回合被拦截)只用系统蜂鸣,不播失败语音 —— 因为语义是"被拦下"而非"失败"
156
+ - **`fail` 语音包只覆盖 16 个基础音色**(103 个音色里的其余 87 个只有完成语音)。选到未覆盖的音色时,失败会在同池内换一个音色,不会哑掉、也不会播错语义
157
+
158
+ ---
159
+
160
+ ## 开发
161
+
162
+ ### 跑测试
163
+
164
+ ```powershell
165
+ npm test # 主套件(纯 Node,不需要 DSH 宿主)
166
+ npm run test:all # 全部(含 route 注入的两组)
167
+ npm run test:route # 需要 --import loader 的接线测试
168
+ npm run test:audio-wire
169
+ ```
170
+
171
+ **274 条测试。** 绝大多数是纯逻辑测试,克隆仓库后 `npm test` 即可跑。
172
+
173
+ 少数用例需要真实的 DSH 宿主(用于验证 Cordis 上下文行为)。
174
+ 找不到宿主时它们会**自动 skip** —— 注意 skip 不等于通过。
175
+ 指定宿主路径:
176
+
177
+ ```powershell
178
+ $env:DSH_CORDIS_ENTRY = "<DSH 安装目录>\.runtime\node_modules\@deepseek-ai\cordis\lib\index.js"
179
+ npm test
180
+ ```
181
+
182
+ ### 测试分层
183
+
184
+ | 层次 | 内容 |
185
+ |---|---|
186
+ | 单元 | 音源选择、空闲门、配置校验、TTS 文案、http-guard 判定 |
187
+ | 集成 | 真实 HTTP 服务器 + 真实 handler,覆盖请求/响应全链路 |
188
+ | 实机 | 真实 Cordis 上下文(需宿主,无则 skip) |
189
+ | 发布 | 构建发布包并断言被禁音色/第三方素材未进包 |
190
+
191
+ 集成测试(`test/http-integration.test.mjs`)是 2026-10-18 加的,起因是
192
+ 一次真实回归:给 `/consume` 加了"写操作必须 JSON"的防护,但客户端还在用
193
+ GET —— 单元测试全绿,功能却断了。集成测试会读取客户端源码里的真实调用形状,
194
+ 所以两边一旦不同步就会变红。
195
+
196
+ ### CI
197
+
198
+ `.github/workflows/ci.yml` 在每次 push / PR 时跑:
199
+
200
+ - 单元测试(Node 20 / 22 / 24)
201
+ - PowerShell 语法与 UTF-8 BOM 检查
202
+ - 关键文件齐全 + npm 打包内容检查(含"被禁音色不得进包")
203
+ - 版本一致性
204
+
205
+ ### 变异测试
206
+
207
+ 关键断言都做过变异验证(故意改坏代码确认测试变红)。例如:
208
+
209
+ - 把 `consume` 的客户端调用改回 GET → E0/E1 变红
210
+ - 把 `head` 的前缀剥离去掉 → E3 变红
211
+ - 把 `verifyReload` 改成永远放行 → S2/S6/R8/R8b 变红
212
+
213
+ ---
214
+
215
+ ## 许可
216
+
177
217
  代码以 MIT 发布。
178
218
  **语音文件不适用 MIT**,由 VOICEVOX 生成,各音色有其自身使用条款,
179
- 详见 [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md)。
219
+ 详见 [`THIRD-PARTY-NOTICES.md`](THIRD-PARTY-NOTICES.md)。
@@ -0,0 +1,164 @@
1
+ # 音色许可审核记录(2026-10-18)
2
+
3
+ > 本文档是**开发者内部的审核记录**,基于各权利人官方页面的**本地快照**(见 `snapshots/`)。
4
+ > 它不是权利人出具的授权书,也不构成法律意见。
5
+ >
6
+ > 对外提供时只用 `licenses/AUDIO.md` 的摘要与官方链接。
7
+
8
+ ## 一、审核口径(限定条件)
9
+
10
+ 本审核仅针对以下使用形态:
11
+
12
+ ```
13
+ ✅ 个人开发
14
+ ✅ 免费、开源、无广告、无赞助
15
+ ✅ 本地用 VOICEVOX 生成 WAV
16
+ ✅ 打包 ZIP 上传 GitHub Release 供下载
17
+ ✅ 在插件 GUI 中播放这些 WAV
18
+ ❌ 不分发 VOICEVOX 软件 / 模型权重 / 角色立绘
19
+ ```
20
+
21
+ **换任何一条(如收费、公司运营、接受赞助、商业化),结论都要重新评估。**
22
+
23
+ ## 二、判定标准
24
+
25
+ | 状态 | 含义 | 插件行为 |
26
+ |---|---|---|
27
+ | `APPROVED` | 官方条款明确允许商用非商用 + 仅需署名与用途限制,**未发现禁止素材再分发** | 可提供下载 |
28
+ | `CONDITIONAL` | 允许使用,但**未明确涉及「独立音频素材包分发」** | 可提供下载,但须传递义务 + 显著标示 |
29
+ | `PENDING` | 条款未能完整读取,或有身份/来源疑问 | **不提供下载** |
30
+ | `FORBIDDEN` | 官方明确禁止再分发 / 禁止无偿配发音声素材 | **不提供下载** |
31
+
32
+ ## 三、逐音色结论(16 个 VOICEVOX 音色)
33
+
34
+ ### FORBIDDEN(明确禁止,必须移除)
35
+
36
+ | 音色 | 依据原文 | 出处 |
37
+ |---|---|---|
38
+ | **kasukabe-tsumugi** 春日部つむぎ | 「以下の行為について禁止します…**・二次配布**、自作発言」 | [官方](https://tsumugi-official.studio.site/rule) |
39
+ | **mochiko** もち子さん | 「出力した合成音声を使用した**音声素材を無償配布**、有償販売。」(禁止事項第 1 项) | [官方](https://vtubermochio.wixsite.com/mochizora/利用規約) |
40
+
41
+ > ⚠️ **kasukabe-tsumugi 是本次新发现**。此前只知它「条件保留」,
42
+ > 实际读原文后发现第 6 条禁令直接写了「二次配布」——
43
+ > 与我方 ZIP 分发模式正面冲突。**必须移除。**
44
+
45
+ ### CONDITIONAL(可发,须履行义务)
46
+
47
+ | 音色 | 署名要求 | 关键限制 | 出处 |
48
+ |---|---|---|---|
49
+ | **zundamon-normal** | `VOICEVOX:ずんだもん` | 无政治/宗教/信息商材/虚假信息;不可转卖音频 | [ずんずん](https://zunko.jp/con_ongen_kiyaku.html) |
50
+ | **zundamon-amama** | `VOICEVOX:ずんだもん` | 同上 | 同上 |
51
+ | **shikoku-metang** | `VOICEVOX:四国めたん` | 同上 | 同上 |
52
+ | **kyushu-sora** | `VOICEVOX:九州そら` | 同上 | 同上 |
53
+ | **tohoku-zunko** | `VOICEVOX:東北ずん子` | 同上 | 同上 |
54
+ | **tohoku-kiritan** | `VOICEVOX:東北きりたん` | 同上 | 同上 |
55
+ | **ankomon** | `VOICEVOX:あんこもん` | 同上 | 同上 |
56
+ | **ameharu-hau** 雨晴はう | `VOICEVOX:雨晴はう`(角色名可选) | **禁止 R18 音声用途**;禁止未授权变声模型 | [あめはれくりにっく](https://amehau.com/rules/amehare-hau-rule.html) |
57
+ | **goki-nuigurumi** 後鬼 | `VOICEVOX:後鬼` | 企业商用需事前确认(本项目为个人免费,不触发) | [ついなちゃん](https://xn--n8jychz0k1d.com/voice_terms/) |
58
+ | **manbetsu-hanamaru-genki** 満別花丸 | `VOICEVOX:満別花丸` | 禁止恶意使用、冒充官方、特定政治极端宣传 | [官方](https://100hanamaru.wixsite.com/manbetsu-hanamaru/rule) |
59
+ | **meimei-meria** 冥鳴ひまり | `VOICEVOX:冥鳴ひまり` | 禁止损害第三方、特定思想团体 | [官方](https://www.meimeihimari.com/terms-of-use) |
60
+ | **namiine-ritsu** 波音リツ | `VOICEVOX:波音リツ`(见下) | 权利人有要求停止公开的条款 | [カノンの落ちる城](https://www.canon-voice.com/terms/) |
61
+ | **shirakami-kotaro** 白上虎太郎 | `VOICEVOX:白上虎太郎` | 禁止用输出训练新声音模型 | [VirVox](https://www.virvoxproject.com/voicevoxの利用規約) |
62
+
63
+ #### 两个特别说明
64
+
65
+ **namiine-ritsu(最宽松但也有坑)**
66
+
67
+ 官方页面顶部写 `音源の転載、再配布可` 和 `クレジット表記不要`。
68
+ 但**同一页面另有**:`VOICEVOXを使用する場合、「VOICEVOX」のクレジットが必要`。
69
+
70
+ → 结论:**可以再分发,但必须标 `VOICEVOX` 署名**(不是完全不署名)。
71
+
72
+ > 这是 2026-10-18 的教训:只看三行摘要会漏掉这条,差点做出错误判断。
73
+
74
+ **shirakami-kotaro(分发依据最明确)**
75
+
76
+ VirVox 条款直接规范了素材分发场景:
77
+
78
+ > 出力音声を音声素材として配布する際は、2.と同様の規約を素材の利用者へ義務づける必要があるものとします。
79
+
80
+ → 这是所有音色里**唯一明确写了"分发音声素材"该怎么做**的条款。
81
+ 对我们最有利——它证明了「分发是被考虑的、被规范的情形」。
82
+
83
+ ### PENDING(不提供下载)
84
+
85
+ | 音色 | 原因 |
86
+ |---|---|
87
+ | **yurei-chan** | 身份未确认。VOICEVOX 官方同时存在「ユーレイちゃん」(U-Stella, style_id 102) 与「夜語トバリ」(style_id 118),是**不同权利人**。文件名 `yurei-chan` 倾向指前者,但**无生成记录可证**。 |
88
+
89
+ ## 四、自有声音(2 个)
90
+
91
+ | 音色 | 状态 | 说明 |
92
+ |---|---|---|
93
+ | `my-voice-ja` | **永不分发** | 作者本人声音。已加入发布黑名单。 |
94
+ | `my-voice-ja-2` | **永不分发** | 同上。 |
95
+
96
+ ## 五、可选但尚未纳入的音色
97
+
98
+ VOICEVOX 官方共 40+ 个音色。以下**可能有价值但我们没用过**,如需扩充可先审核:
99
+
100
+ | 音色 | 声音特点 | 备注 |
101
+ |---|---|---|
102
+ | 中国うさぎ | 幽玄で初々しい | SSS 阵营,条款与ずんだもん同源 |
103
+ | 中部つるぎ | 凛然とした存在感 | SSS 阵营 |
104
+ | WhiteCUL | 聞き心地のよい率直 | 需单独查条款 |
105
+ | 猫使アル / 猫使ビィ | 厚みのある気さく / ピュアであどけない | 需单独查条款 |
106
+ | 春歌ナナ | はつらつとした力強い | 需单独查条款 |
107
+ | 琴詠ニア | 滑らかで無機質 | 需单独查条款 |
108
+ | 離途 / 黒沢冴白 / 暁記ミタマ | 各异 | 需单独查条款 |
109
+ | **VOICEVOX Nemo** | 无人格设定的纯音声库 | **条款最简单**:署名即可商用非商用,无角色条款负担 |
110
+
111
+ **Nemo 值得特别考虑**:它没有角色人格,条款是一次性的
112
+ (`VOICEVOX Nemo` 署名即可),不像角色音色那样每家都要单独查。
113
+ 如果未来要扩大音色库,Nemo 是最省事的方向。
114
+
115
+ ## 六、快照清单
116
+
117
+ `snapshots/` 下的文件是本审核的**原始证据**:
118
+
119
+ | 文件 | 内容 | 抓取方式 |
120
+ |---|---|---|
121
+ | `voicevox-software.txt` | VOICEVOX 软件规约 | browser-auto |
122
+ | `voicevox-vvm-terms.txt` | 官方模型/音源总条款(含各角色摘要) | raw.githubusercontent |
123
+ | `sss-zundamon.txt` / `sss-anonymous-common.txt` | ずんずんプロジェクト共通规约 | browser-auto |
124
+ | `ameharu-hau.txt` | 雨晴はう规约 | browser-auto |
125
+ | `goki-nuigurumi.txt` | 後鬼音源规约 | browser-auto |
126
+ | `kasukabe-tsumugi.txt` | 春日部つむぎ规约(**含二次配布禁令**) | browser-auto |
127
+ | `meimei-meria.txt` | 冥鳴ひまり规约 | browser-auto |
128
+ | `namiine-ritsu.txt` | 波音リツ规约 | browser-auto |
129
+ | `shirakami-kotaro.txt` | VirVox 规约(**含素材分发条款**) | browser-auto |
130
+ | `yurei-chan.txt` | U-Stella ユーレイちゃん规约 | browser-auto |
131
+
132
+ ### 未能抓取(网络受限)
133
+
134
+ | 目标 | 原因 | 补救 |
135
+ |---|---|---|
136
+ | `mochiko` 完整正文 | `wixsite.com` 域名在本机网络不可达(ERR_CONNECTION_CLOSED) | 已有搜索摘要含禁止条款原文,且我们**已决定排除**,不影响结论 |
137
+ | `manbetsu-hanamaru` 完整正文 | 同上(同为 wixsite) | 已有摘要含署名要求;建议后续用代理重抓 |
138
+ | `夜語トバリ` 规约正文 | 官网用 JS 动态加载,`#rules` 锚点未触发 | 身份未确认,暂不发布,暂不需要 |
139
+
140
+ ## 七、当前可发布清单
141
+
142
+ ```
143
+ 可发布(CONDITIONAL,13 个):
144
+ zundamon-normal, zundamon-amama, shikoku-metang, kyushu-sora,
145
+ tohoku-zunko, tohoku-kiritan, ankokon, ameharu-hau,
146
+ goki-nuigurumi, manbetsu-hanamaru-genki, meimei-meria,
147
+ namiine-ritsu, shirakami-kotaro
148
+
149
+ 禁止发布(FORBIDDEN,2 个):
150
+ kasukabe-tsumugi, mochiko
151
+
152
+ 待确认(PENDING,1 个):
153
+ yurei-chan
154
+
155
+ 永不分发(隐私,2 个):
156
+ my-voice-ja, my-voice-ja-2
157
+ ```
158
+
159
+ ## 八、维护规则
160
+
161
+ 1. **新增音色** → 必须先抓快照、填本记录、判定状态,才能进下载列表
162
+ 2. **官方改条款** → 重抓快照,比对差异,重新判定
163
+ 3. **用途变更**(收费、公司运营、赞助)→ 全部重新审核
164
+ 4. **本记录与 `licenses/AUDIO.md` 必须同步** —— 前者是内部证据,后者是对外摘要
@@ -0,0 +1,76 @@
1
+ # 批量抓取音色条款快照
2
+ #
3
+ # 用途:把各音色官方规约的**正文**存成本地快照,作为审核证据。
4
+ #
5
+ # 为什么必须这样做:
6
+ # 2026-10-18 我曾只依赖搜索摘要,漏掉了「波音リツ」页面顶部的
7
+ # "VOICEVOXを使用する場合、「VOICEVOX」のクレジットが必要",
8
+ # 差点做出错误判断。二手摘要不可靠,必须留原文。
9
+ #
10
+ # 用法:在 browser-auto 技能目录下运行
11
+ # & $env:DSHX_NODE scripts/browser.mjs --url <url> --action text
12
+
13
+ $ErrorActionPreference = 'Continue'
14
+ $browser = "C:\Users\audio\.codex\skills\browser-auto"
15
+ $outDir = "E:\0Deepseek\tools\plugins\dsh-notify-desktop\docs\audio-audit\snapshots"
16
+ New-Item -ItemType Directory -Force -Path $outDir | Out-Null
17
+
18
+ # 音色 → 官方条款 URL(我方已使用的 16 个 VOICEVOX 音色)
19
+ $targets = [ordered]@{
20
+ # SSS / ずんずんプロジェクト(7 个配置共用一份)
21
+ 'sss-zundamon' = 'https://zunko.jp/con_ongen_kiyaku.html'
22
+ 'sss-anonymous-common' = 'https://zunko.jp/con_ongen_kiyaku.html'
23
+
24
+ # 独立角色
25
+ 'ameharu-hau' = 'https://amehau.com/rules/amehare-hau-rule.html'
26
+ 'goki-nuigurumi' = 'https://xn--n8jychz0k1d.com/voice_terms/'
27
+ 'kasukabe-tsumugi' = 'https://tsumugi-official.studio.site/rule'
28
+ 'manbetsu-hanamaru' = 'https://100hanamaru.wixsite.com/manbetsu-hanamaru/rule'
29
+ 'meimei-meria' = 'https://www.meimeihimari.com/terms-of-use'
30
+ 'mochiko' = 'https://vtubermochio.wixsite.com/mochizora/'
31
+ 'namiine-ritsu' = 'https://www.canon-voice.com/terms/'
32
+ 'shirakami-kotaro' = 'https://www.virvoxproject.com/voicevoxの利用規約'
33
+ 'yurei-chan' = 'https://u-stella.co.jp/voicevox-ure-chan-tucumo-terms-of-use/'
34
+
35
+ # VOICEVOX 自身
36
+ 'voicevox-software' = 'https://voicevox.hiroshiba.jp/term/'
37
+ 'voicevox-vvm-terms' = 'https://raw.githubusercontent.com/VOICEVOX/voicevox_vvm/main/TERMS.txt'
38
+ }
39
+
40
+ Push-Location $browser
41
+ try {
42
+ foreach ($name in $targets.Keys) {
43
+ $url = $targets[$name]
44
+ $outFile = Join-Path $outDir "$name.txt"
45
+ Write-Host ("--- {0} ---" -f $name) -ForegroundColor Cyan
46
+ Write-Host (" {0}" -f $url) -ForegroundColor DarkGray
47
+
48
+ try {
49
+ $text = & $env:DSHX_NODE scripts/browser.mjs --url $url --action text --max-chars 20000 2>&1 | Out-String
50
+ # ⚠️ 必须校验"真的是页面正文"。
51
+ # 踩过:抓取失败时 PowerShell 把 stderr 的异常文本也当输出,
52
+ # 于是"错误堆栈"被当成内容写进了快照文件(还以为成功了)。
53
+ # 判定标准:有 TITLE/TEXT 标记,且不含 Node 异常特征。
54
+ $looksLikeError = $text -match 'ERR_CONNECTION|UncaughtException|node:internal|at .*browser\.mjs:'
55
+ $hasPageMarker = $text -match 'TITLE:'
56
+ if ($text -and $text.Length -gt 200 -and $hasPageMarker -and -not $looksLikeError) {
57
+ $header = "# 快照:$name`r`n# URL: $url`r`n# 抓取时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')`r`n# 工具: browser-auto (Edge + Playwright)`r`n`r`n"
58
+ [System.IO.File]::WriteAllText($outFile, $header + $text, (New-Object System.Text.UTF8Encoding($false)))
59
+ Write-Host (" OK {0:N0} 字符" -f $text.Length) -ForegroundColor Green
60
+ } else {
61
+ Write-Host " FAIL 内容过短" -ForegroundColor Red
62
+ }
63
+ } catch {
64
+ Write-Host (" FAIL {0}" -f $_.Exception.Message) -ForegroundColor Red
65
+ }
66
+ Start-Sleep -Milliseconds 800
67
+ }
68
+ } finally {
69
+ Pop-Location
70
+ }
71
+
72
+ Write-Host ""
73
+ Write-Host "=== 快照结果 ===" -ForegroundColor Cyan
74
+ Get-ChildItem $outDir -File | Sort-Object Name | ForEach-Object {
75
+ Write-Host (" {0,-32} {1,8:N0} B" -f $_.Name, $_.Length)
76
+ }