🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

语音朗读 RinChanNOWWW/dsh-speak

DeepSeek Harnessv1.8.2
RinChanNOWWW24 天前有提交已提供中文文档扫描:含敏感能力

让助手把回复读出来,选中文字也能即点即听

30.8/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/12 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add RinChanNOWWW/dsh-speak
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/10/31·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 24 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-speak @ 1.8.2
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 09:38:47

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 10 处,展示前 10 条)
  • 执行外部命令固定命令
    index.js:100
    child = spawn('say', ['-v', '?'], { stdio: ['ignore', 'pipe', 'ignore'] });
  • 读取本地文件
    index.js:162
    return normalizeSettings(JSON.parse(readFileSync(SETTINGS_FILE, 'utf8')), empty);
  • 写入本地文件
    index.js:205
    mkdirSync(dirname(SETTINGS_FILE), { recursive: true });
  • 写入本地文件
    index.js:206
    writeFileSync(SETTINGS_FILE, `${JSON.stringify(next, null, 2)}\n`);
  • 执行外部命令固定命令
    index.js:497
    const child = spawn('say', utterance.argv, { stdio: 'ignore' });
  • 发起网络请求
    client.js:64
    void fetch(CLIENT_ROUTE, {
  • 发起网络请求
    client.js:101
    const response = await fetch(STATUS_ROUTE, { headers: { accept: 'application/json' } });
  • 发起网络请求
    client.js:137
    const response = await fetch(SPEAK_ROUTE, {
  • 发起网络请求
    client.js:232
    const response = await fetch(SETTINGS_ROUTE, { headers: { accept: 'application/json' } });
  • 发起网络请求
    client.js:262
    const response = await fetch(SETTINGS_ROUTE, {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 朗读助手回复
  • 划词即点即听
  • 按语言区分语音

在 DeepSeek Harness(DSH)里朗读文本:给智能体的 speak 工具、Web UI 里的逐条朗读与划词朗读按钮,以及按语言区分的语音——全部走 macOS 的 say 命令。

README

由 DeepSeek 最新模型翻译生成
dsh-speak 在 DeepSeek Harness(DSH)里把文字读出来:用 macOS 自带的 say,声音从运行 DSH 的那台机器出来。 | 入口 | 位置 | 行为 | | speak 工具 | 模型可调用 | 朗读文本;stop: true 则为中止 | | 🔊 消息操作 | 每条助手回复下方的操作条 | 点击朗读该条;朗读中再点即停止 | | 🔊 选中朗读气泡 | 页面上任意文本选区上方 | 「选中即朗读」,类似选中翻译 | | ⚙ 朗读设置 | 输入框旁的「喇叭+齿轮」按钮 | 每语种音色、语速、汉字优先 | 中文、英文、日文、韩文按字符自动识别,每个语种片段各起一个 say 进程、各用自己的系统音色。同一时刻只播一句,新请求替换旧的。 无云端、无 API Key、无模型下载;文本不离开本机。
展开完整文档(README 剩余 1 节)
dsh-speak

在 DeepSeek Harness(DSH)里把文字读出来:用 macOS 自带的 say,声音从运行 DSH 的那台机器出来。

| 入口 | 位置 | 行为 |
| speak 工具 | 模型可调用 | 朗读文本;stop: true 则为中止 |
| 🔊 消息操作 | 每条助手回复下方的操作条 | 点击朗读该条;朗读中再点即停止 |
| 🔊 选中朗读气泡 | 页面上任意文本选区上方 | 「选中即朗读」,类似选中翻译 |
| ⚙ 朗读设置 | 输入框旁的「喇叭+齿轮」按钮 | 每语种音色、语速、汉字优先 |

中文、英文、日文、韩文按字符自动识别,每个语种片段各起一个 say 进程、各用自己的系统音色。同一时刻只播一句,新请求替换旧的。

无云端、无 API Key、无模型下载;文本不离开本机。

环境要求

- macOS —— 播放调用 say(Linux 的 spd-say 或浏览器端 speechSynthesis 属于另一条实现路线,暂未提供)
- DSH 0.2.x —— 桌面客户端,或任何把页面服务到浏览器的 profile
- Node 20+ —— 仅运行离线测试时需要

安装

A. 通过插件管理器(推荐)

1. 打开 DSH → Plugins(设置里的 Plugins,或侧边栏的插件面板);
2. 点 Install bundle,粘贴仓库地址:

https://github.com/RinChanNOWWW/dsh-speak

支持 git 地址、本地绝对路径、npm 包名三种写法;
3. 插件的 bundle patch 会插入一行 speak,浏览器半由宿主自动服务 —— 无需构建、无需安装依赖;
4. 直接用。若按钮没出现,刷新一次页面。

桌面客户端由 App 独占管理 profile,所以 dsh plugin 命令会拒绝它 —— 用 App 内的插件面板即可。其他 profile 也可以用命令行,见下。

B. 手动装进某个 profile

1. 把包放在 profile 的 patch 文件旁边:

$DSH_HOME/profiles/<profile>/plugins/dsh-speak/{package.json,index.js,client.js}

2. 在 $DSH_HOME/profiles/<profile>/cordis.patch.yml 末尾加一行:

- insert:
- id: speak
name: ./plugins/dsh-speak/index.js

name 必须指到入口文件:Loader 对 . 开头的 name 直接 import(new URL(name, baseUrl)),目录无法 import;而浏览器半是从该文件位置逐级向上找最近的 package.json 才被识别。

3. 重启 App,或等 profile 热重载(新增的行会实时生效)。
4. 以后改宿主代码:写一个新文件名(index.v2.js…),并把这一行先删再插。原因:已挂载的行只改 name 不会重新 import,而带 ?v= 查询串的 name 会被 Loader 拒绝。deploy.sh 就是自动做这件事的。

C. dsh web 之类的其他 profile

dsh plugin --profile web add https://github.com/RinChanNOWWW/dsh-speak

这条命令只安装依赖;bundle 还要被列进该 profile package.json 的 dsh.profile.bundles 里,它的 patch 才会被应用 —— App 内的插件管理器会一次做完这两步。

用法

让助手读

「把这段读给我听」/ "read this aloud" / 「别读了」/ "stop reading"

| speak 参数 | 含义 |
| text | 要读的文本(markdown 自动剥掉);除非 stop 为 true,否则必填 |
| stop | true 时中止当前朗读,不开始新的 |
| language | zh / en / ja / ko:用于消歧(纯汉字按哪种语言读)与音色兜底,不会把整段塞进一个音色 |
| voice | 精确的 macOS 音色名(Tingting、Kyoko、Yuna、Samantha…),整段用这一个音色 |
| rate | 语速(词/分,80–500) |
| wait | 等整段读完再返回,而不是一开始就返回 |

返回值包含字符数、识别到的语种、用到的音色,以及逐段序列,例如 zh:Tingting -> ko:Yuna -> ja:Kyoko -> en:Samantha。

在界面上用

- 消息操作:回复下方的 🔊。朗读中图标高亮、声波脉动,再点即停;若正在读别的回复则显示为暗态(点击改为读这条);失败变红并提示可重试。
- 选中朗读:选中任意非输入框文本,选区上方出现小气泡(空间不足时移到下方,且始终夹在视口内)。点击朗读后气泡不会消失,而是变成「停止朗读」。输入框、文本域、contenteditable 内的选区不触发;超过 20000 字符不触发。
- 朗读设置:输入框旁的「喇叭+齿轮」,或选中气泡里的齿轮。

中止朗读

| 方式 | 说明 |
| 气泡上同一个按钮(已变成「停止朗读」) | 点击朗读后气泡不再自动收起 |
| 右下角常驻停止悬浮条 | 任何来源的朗读(包括助手用工具发起的)都会出现:页面有一条慢心跳在问宿主"现在在播什么" |
| ⌘⇧S(Windows/Linux 为 Ctrl/Cmd+Shift+S) | 页面任何位置都生效,输入框里也能按;可在 DSH 快捷键设置里搜 speak.stop 改键位 |
| 让助手停 | speak 带 stop: true |

设置

面板按语种(中文 / English / 日本語 / 한국어)列出本机实际安装的音色(推荐音色排最前),另有语速滑杆、汉字优先(没有假名的汉字算中文还是日文)、试听按钮与保存状态。

设置存在 $DSH_HOME/dsh-speak.settings.json,并且同样作用于 speak 工具 —— 助手会用你选的音色朗读;工具里显式传参只覆盖当次。

curl -s $DSH_WEB_URL/api/dsh-speak/settings # 已装音色 + 当前设置

实现

一个包里两半,共用一行 Loader 条目:

- index.js —— 宿主半。注册 speak 工具,并在 Web server 上挂四条路由:

| 路由 | 用途 |
| POST /api/dsh-speak | {action:"speak", text?/sessionId+messageId} 或 {action:"stop"} |
| GET /api/dsh-speak/status | 当前在播什么:来源、消息身份、语种、音色、逐段序列、进度 |
| GET/POST /api/dsh-speak/settings | 读写偏好;列出已装音色 |
| GET/POST /api/dsh-speak/client | 浏览器半的上报通道(见「诊断」) |

- client.js —— 浏览器半,客户端模块加载器要求的预构建格式(window.__ModuleLoader__.load({id, factory})),注册四个槽位:conversation.chat.assistant-actions、shell.overlay 两条、conversation.composer.dock。

语言判定:

- 出现假名 → 该汉字/假名段为日语;韩文 → 韩语;拉丁 → 英语;无假名的汉字段按汉字优先设置;
- 句末标点与脚本切换都会切段,所以「中文句子。日本語の文。」各用各的音色;
- 拉丁片段若不足 MIN_LATIN_RUN(默认 12 个"该语言自己的字符")会并入相邻语言,避免中文里夹一个缩写就来回换音色;中日韩片段永不被吞;
- 播放是"一段一个 say 进程,上一段退出再起下一段":say 没有内联换音色的命令(它的 [[...]] 只覆盖 rate/pitch/volume/input 模式),不支持的 [[voice:…]] 会被当文本念出来。

诊断

浏览器半会把"加载了什么、做了什么"上报到宿主:GET /api/dsh-speak/client(宿主里 200 条环形缓冲)—— 包含 hello(build 与注册的条目)、style、mounted、visibility、rendered(实测落点、是否在视口内、哪个祖先会破坏 position: fixed)、error(带组件栈),以及设置与播放状态变化。"点了没反应"这类问题因此不需要开 devtools 就能定位。

curl -s $DSH_WEB_URL/api/dsh-speak/client

常见问题

| 现象 | 排查 |
| 完全没声音 | curl -s $DSH_WEB_URL/api/dsh-speak/status,speaking 应非 null;再看 .../client 有没有浏览器侧报错 |
| 按钮不出现 | 刷新页面;client.js 的改动只有在行被重新合成后才会送到页面 |
| 一直在跑旧代码 | 已挂载的行改 name 不会重新 import —— 换新文件名并「删行+重插」(deploy.sh 已自动化) |
| 音色不对 | 设置面板:每语种钉的音色优先,其次该语种推荐音色,最后系统默认 |
| 汉字读成错的语种 | 该段没有假名,本身就歧义;把「汉字优先」设成中文或日文 |
| unknown session(422) | 该消息属于这个 Harness 进程尚未加载的会话 |

开发

pnpm install # 只为 @deepseek-ai/dsh-tools(index.js 与测试都用它)
pnpm test # 宿主半离线测试;会真的调用 say 发声
./deploy.sh # 部署到运行中的 profile 并等重载回来(开发辅助脚本)

deploy.sh 会写入新的版本化入口文件、删掉并重插 profile 行、等状态路由恢复、只保留一个入口文件;它读 $DSH_PROFILE_DIR,缺省回退到 $DSH_HOME/profiles/desktop。

测试用桩替换了工具注册表、会话存储与 Web server,并把设置文件指向临时 DSH_HOME,所以既不需要装 DSH,也不会动你的偏好设置。

安全说明

- 路由只接受 POST/GET 且要求 application/json:跨站页面会先撞 CORS 预检而无法通过,简单请求则被 415 拒掉。文本不离开本机,直接交给 say。
- 插件故意没有给这些路由加 DSH 的 connection 信任围栏,以便用 curl 直接验证 —— 它能做的仅仅是让宿主发声。

许可

MIT
预览分享卡片长什么样 ↓RinChanNOWWW/dsh-speak
分享 · DeepSeek Harness Hub
RinChanNOWWW/dsh-speak

让助手把回复读出来,选中文字也能即点即听

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部