DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Course Recorder — DeepSeek Harness 插件(DSH Plugin)
← Plugins
C

dsh-course-recorder

Course Recorder

dsh(DeepSeek Harness)课堂 AI 助手插件:麦克风录音 + 本地实时转录 + 授权后整理笔记 + 按课程归类 + 现场作业指导;音频、转录与笔记默认只在本机。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:Elion-Wang/class-help#57f4b721bdd36f8691a9c588573c7946cdf0e358
README兼容性版本

兼容性与来源证明

Course Recorder 以 dsh-course-recorder 发布,当前版本为 1.0.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/10/11

版本

1.0.0stable
2026/10/11

相关插件

正在加载相关插件…

最新版
1.0.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/10/11
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

README

课堂 AI 助手 · dsh-course-recorder

仓库简介(GitHub About 一行版) dsh(DeepSeek Harness)课堂 AI 助手插件:上课录音 + 本地实时转录,课后经你授权才整理成笔记并自动归入课程目录,作业现场按课程做助教式指导。音频、转录与笔记默认只在本机;可配合 dsh-plugin-wallpaper-engine 使用。

项目名:课堂 AI 助手 插件名:dsh-course-recorder 仓库名:class-help

一个 dsh Host + Client 双半边插件(同时内置一个 runtime skill)。它把「上课用麦克风(可选加系统声音)录音 → 本地 SenseVoice 逐段实时转录 → 我随时暂停/停止 → 只有我明确授权才由 dsh 的模型整理笔记 → 上课/做作业现场按需指导」做成一条闭环。

设计主线是「收集在课堂,推理在谷价时间,输出可验证」:课堂阶段不花模型 token(转录跑本地模型),推理推迟到你说「整理」的那一刻;每条结论都要能追回原话(session_id + 片段号 + 时间戳)。

目录:前置条件 · 一键导入 · 面板 · 21 个工具 · 磁盘布局 · 课程归类 · 配合 wallpaper-engine · 隐私 · 自测 · 常见问题

  • 音频、转录、笔记默认只在本机,输出根目录默认 D:\课程。
  • 绝不自动整理笔记:notes_generate / notes_integrate 需要 user_authorized=true 且 dsh 的授权弹窗返回 allowed-once,双闸门缺一不可。
  • 录音可随时 class_pause / class_stop(force),已录制内容一律保留。
  • 每节课的 session.json 都带 endedAt / endedAtLocal(用户要求的「每次录音结束时间」)。

详见 docs/PROTOCOL.md(Host↔Client 冻结契约)与 SKILL.md(模型侧工作流)。


1. 前置条件

依赖说明
dsh 桌面版 ≥ 0.2.0-rc.1麦克风权限已由 Electron 主进程放行(installMicrophonePermissions)
官方 Voice Input bundle在 设置 → 插件 里启用 @deepseek-ai/dsh-experimental-voice-input-bundle;它提供 ctx.speechToText 与本地 sensevoice-local provider(239 MB int8 模型已在 %USERPROFILE%\.dsh\speech-to-text\sensevoice\ 缓存)
Node ≥ 20仅自测用(node --test)

系统声音(可选):dsh 桌面版渲染会话的 setDisplayMediaRequestHandler 固定返回 {},因此页内 getDisplayMedia() 拿不到音轨,本插件也不假装成功。要录「电脑正在播放的声音」,在 Windows 打开 设置 → 系统 → 声音 → 更多声音设置 → 录制,启用 立体声混音;它随后会作为普通麦克风设备出现,在面板里选它即可。面板同时提供 display 试探源:一旦 dsh 未来支持 loopback,它会自动可用。

2. 安装

在 dsh 里(或用 plugin_manager 工具)把这个包挂进 profile。

2.1 一键导入(脚本,推荐)

仓库自带 scripts/install.ps1,把「挂载目录 + 依赖声明 + 开关」一次做完:

# 在本仓库根目录执行(默认 profile:%USERPROFILE%\.dsh\profiles\desktop)
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1

它做四件事,每一步都打印出来:

  1. 把仓库以 junction 挂到 <profile>\node_modules\dsh-course-recorder(加 -Copy 则改为复制文件);
  2. 在 profile 的 package.json 里写 dependencies["dsh-course-recorder"] = "link:<本仓库绝对路径>";
  3. 把 dsh-course-recorder 加进 dsh.profile.bundles(已存在则跳过);
  4. 改前备份 package.json.bak-before-course-recorder-<时间戳>,写完做一次 JSON 校验,然后提示你重启 dsh。
# 指定别的 profile
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -ProfileDir "$env:USERPROFILE\.dsh\profiles\other"

# 复制安装(把插件放进 profile 目录里,而不是链接到本仓库)
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -Copy

# 卸载:摘掉开关、依赖与挂载目录(同样先备份)
powershell -ExecutionPolicy Bypass -File .\scripts\install.ps1 -Uninstall

2.2 用 dsh 自带的插件管理

推荐路径(安装过一次之后都用这条):包已经以 link:<本仓库绝对路径> 的形式挂在 profile 的 dependencies 里, 启用/停用只需要改 dsh.profile.bundles:

plugin_manager set_bundle target="dsh-course-recorder" enabled=true

set_bundle 不会跑 pnpm,因此不会动 profile 的依赖树。

首次安装才需要 install_bundle target="<本仓库绝对路径>",它会在 profile 目录里跑一次 pnpm。注意两个真实存在的坑:

  • 它可能删掉第三方插件的 peer 依赖。实测日志 Packages: +1 -29:profile 的 pnpm-workspace.yaml 写着 autoInstallPeers: false,pnpm 会把 react、react-dom、@huanlin/dsh-plugin-better-locale 这类 peer 当成多余项清掉,而且 .modules.yaml 之后不再记录它们,普通 pnpm install 也装不回来。
  • 装完必须重启并确认应用能起来,不要连着装好几个插件再一起重启。

安装后 cordis.patch.yml 会在 profile 里插入一行 course-recorder。若要改配置(例如换输出目录),不要手写 profile 的 cordis.patch.yml;直接改本包 cordis.patch.yml 的 config:,或按官方约定在 profile 的 patch 层复制同一 id 并重述所有要保留的键(后层整块替换同 id 的 config)。

⚠️ Client 半边写错会让整个应用起不来

这不是夸张,是实测事故:lib/client.js 曾经写成裸 _ModuleLoader__.load({…}),渲染进程抛 ReferenceError: _ModuleLoader__ is not defined,web boot 随即抛 web boot: 1 entry did not activate,界面弹「应用无法启动或已意外停止」,用户只能点 「禁用第三方插件、备份 profile patch 并重启」——代价是插件列表被清空。

两条硬规则,build-inline.mjs 与 test/client.test.mjs 都在守护它们:

  1. facade 只在 window 上(window.__ModuleLoader__),没有裸全局。app.asar 里 74 个内置 client 产物全部用 window.__ModuleLoader__.load({...})。
  2. 包装层必须带守卫:facade 缺失时告警并 return,绝不抛错。宁可面板不出现,也不能让应用起不来。

改代码之后必须做什么

改了什么生效方式
Client 半边(src/client/*.js、build-inline.mjs)node build-inline.mjs 重新生成 lib/client.js,刷新页面(产物 URL 带内容 hash &rev=,会重新拉取)
Host 半边(src/host/*.js、lib/index.js)重启 dsh。Node 的 ESM 缓存按模块 URL 缓存成功的 import,plugin_manager 的重组合只重建条目树、不会重新导入模块,所以即使改了文件,运行中的 Host 仍执行旧的一代模块(官方原文:Replacing installed package versions still requires a restart through Plugin Manager)。
包清单(package.json)或 cordis.patch.yml同上,重启 dsh
只想启用/停用已有 bundleplugin_manager set_bundle,会立即重组合(不需要重启,但也不会重新导入已缓存的模块)

两个容易踩的坑:

  • plugin_manager 返回的 warnings 里可能带着上一次失败的诊断文本;判断"是不是还在跑旧代码"要看行号是否随文件改动而移动。
  • 应用起不来时那个对话框的第三个按钮会禁用第三方插件并备份 profile patch(备份名形如 cordis.patch.yml.bak-<时间戳>)。点过之后 dsh.profile.bundles 会被砍到只剩基础项,需要用 set_bundle 一个个加回来。

第三个坑(2026-10-10 实录):ctx.speechController.transcribe(request, signal) 的第二个参数必须是真的 AbortSignal。 两层语音服务都无条件调用 signal.throwIfAborted() (dsh-experimental-api-speech-to-text/lib/index.js:196、dsh-experimental-speech-to-text/lib/index.js:179), 漏传不会报"缺参数",而是让每一段都失败在 Cannot read properties of undefined (reading 'throwIfAborted') —— 面板上只看到状态 failed、文本为空, 很像"老师没说话"。第一次真实录音(3 段全部失败)就踩到过这个坑; src/host/session.js 现在通过 get transcribeSignal() 暴露录音器自己的 controller 信号,test/host.test.mjs 的 stubSpeech 也会像真服务一样检查它。同类教训:桩比真服务宽松,就等于没测。

3. 使用

3.1 面板(Client 半边)

聊天输入框下方出现 课堂录音 面板:

  • 选音频源(麦克风 / 立体声混音 / 屏幕共享试探)、开始 / 暂停 / 恢复 / 停止。
  • 2 秒轮询一次 /course-recorder/status:录音状态、时长、缓冲毫秒、音频源电平、最近转录片段、错误提示。
  • 页内 AudioContext 做 16 kHz 单声道下混与 PCM16 编码,按 2 秒一块 POST /course-recorder/stream;Host 端切段后逐段调用官方 Voice Input bundle 暴露的 ctx.speechController.transcribe(),结果增量落库 + 落 transcript.jsonl。切段规则:目标 20 秒、遇 400 ms 尾静音闭合、25 秒硬上限(真实教室底噪常高于 speechThreshold,静音判定不触发,硬上限才是实际延迟)。

3.2 工具(Host 半边,模型调用)

工具作用
class_start(title?, course?, consent: true)开始录音,必须 consent=true
class_pause() / class_resume()暂停 / 恢复(暂停期间的音频被丢弃但 seq 不回退)
class_stop(force?)停止;force=true 丢弃未切段缓冲,已落盘内容保留
class_status()实时监控快照
transcript_get_live(session_id?, limit?)最近转录片段
transcript_get(session_id?, start?, end?, ...)按时间/序号取转录
notes_generate(session_id, style?, user_authorized: true)授权后整理单节课笔记
notes_integrate(session_ids, title?, style?, time_window?, user_authorized: true)授权后跨多次录音整合
notes_get(session_id, format?) / notes_update(session_id, content, ...)读 / 手工编辑笔记
live_guide(question, session_id?)峰价时间现场指导(未整理时标注「基于实时转录,未整理」)
course_search(query, course?, session_id?, top_k?)本地检索(CJK 字符 bigram + TF-IDF,不联网);传 course 就跨该课程全部节次,非法课程名直接拒绝、不会静默回退
course_ask(question, course?, session_id?, mode?, top_k?)课程问答(mode: "live" / "review");传 course 就是「按课程请教」,跨该课程全部节次检索
course_export(session_id?, note_id?, format?, write?)导出 Markdown / 纯文本 / JSON
mic_list_devices()说明设备枚举在渲染页完成,并给出系统声音方案
session_delete(session_id, confirm: true, keep_notes?)一键删除(可只删音频、保留笔记)
course_audit()授权审计 + 整理任务 + 会话清单

所有工具统一返回 { ok, action, data, error }。

3.3 磁盘布局(默认 D:\课程)

D:\课程\
  index.json                                   # 课程索引镜像(归类后按 storage 现况重建)
  未命名课程\                                   # 课堂中不猜课程:新录音的默认落点
  <课程名>\                                     # 专业课 / 文化课 / 马课 / 其他课程(可带一级子目录)
    <YYYYMMDD-HHmmss>-<sessionId>\
      session.json                             # 含 course/courseId/outputRoot/sessionDir + endedAt / endedAtLocal
      transcript.jsonl                         # 每行一个转录片段(含片段号 / 毫秒 / 本地时间 / 文本)
      segments\seg-0001.wav                    # 16k mono PCM16 分段音频(可配置不保留)
      notes\draft-<jobId>.md|.json             # 未授权时的草稿痕迹
      notes\note-<iso>.md|.json                # 授权后生成的正式笔记

真正的索引是 dsh 的 storage 域(sessions / segments / postings / notes / authorizations 等表);index.json 只是给人看、给外部工具看的镜像,归类后按现况整份重建。

3.4 课程归类:四个顶层目录

顶层目录名是强约束,不允许自创第五类:

目录含义
专业课本专业核心课程
文化课语数英物化生史地政等基础学科(可再分,如 文化课/数学)
马课马原、毛概、思修、近代史、形势与政策、军事理论等
其他课程不属于以上三类的兜底

归类规则:

  • 判据只来自这节课自己的转录(老师讲的主题、章节名、术语、作业),不凭时间或录音时长猜;
  • 命中不足(默认少于 2 个词)就归 其他课程,并在笔记开头标「〔分类存疑:疑似 X〕」——宁可标疑问,也不把课塞错门;
  • 你在面板上主动指定了课程,就按你指定的走(用户 > 模型);
  • 报告固定格式:归类:未命名课程 → <目标课程> / 依据:<1–2 条,带 session_id + 片段号 + 时间戳>;
  • 目标已有同名目录时追加 -2 / -3,绝不覆盖;中途任何一步失败整体回滚;
  • 每次归类写一行审计(时间、原课程、新课程、依据、授权方式);
  • 用户一句话改类(「这个其实是马课」)→ 立即重归并覆盖上一次归类记录。

4. 与 dsh-plugin-wallpaper-engine 配合使用

本插件可以配合 dsh-plugin-wallpaper-engine 一起使用:两者都以 profile bundle 的形式挂进 dsh,互不依赖——不装它也能正常用。

  • wallpaper-engine 原作者 GitHub 主页:https://github.com/elysia395

5. 隐私

  • 录音前必须 consent: true,且面板会先弹确认。
  • 音频只在本机内存/磁盘与本地 SenseVoice 之间流动;插件不发起任何外部网络请求。
  • 整理笔记要用户主动发起 + dsh 授权弹窗,每一次尝试(含被拒)都写 authorizations 审计表。
  • session_delete 可删整节课(含音频与笔记),或只删音频保留笔记。
  • 本仓库不含任何个人数据:没有设备日志、没有 API Key、没有真实录音/转录样本,也没有作者的本地绝对路径(示例路径一律为可配置的默认值)。

6. 开发与自测

src/host/          宿主半边:纯 Node 模块(无 Cordis import,可直接单测)
  index.js         apply():注册工具、路由、system prompt 段与 skill
  session.js       录音器:切段、落盘、转写、暂停/恢复/停止、1 小时保险、归类移动
  routes.js        HTTP 路由 + token 围栏 + 回环限制 + manifest
  tools.js         21 个工具的实现与授权闸门
  notes.js         笔记内容构建、Markdown 渲染、审计日志
  context.js       检索与上下文组装(按节、按课程两种范围)
  courses.js       课程名归一化与归类判定
  search.js        本地检索:CJK 字符 bigram + TF-IDF
  segmenter.js     WAV 编码与切段规则
  store.js         dsh storage 域封装(表、复合键)
src/client/        浏览器半边:采集、传输、面板
  capture.js       getUserMedia / 混音 / 16 kHz 下混 / PCM16 / 2 秒分块
  transport.js     /course-recorder/* 调用封装(含 attach 续传)
  ui.js            面板组件(React.createElement),玻璃样式与录音列表
  core.js          工具函数(时钟、格式化、样式常量)
build-inline.mjs   把 src/client/* 内联成 lib/client.js
lib/               发布产物:index.js(host re-export)、client.js(构建生成)
test/              4 个测试文件,共 86 项
docs/PROTOCOL.md   Host↔Client 冻结契约
SKILL.md           模型侧工作流(注入给 dsh 的 skill)
node build-inline.mjs                                  # 改了 src/client/* 之后重建产物
node test/host.test.mjs                                # 41 项
node test/client.test.mjs                              # 32 项
node test/apply.test.mjs                               # 9 项
node test/tools-schema.test.mjs                        # 4 项
node --check lib/index.js; node --check lib/client.js

沙箱提示:node --test <file>(隔离子进程模式)在受限沙箱下会 spawn EPERM;用 --test-isolation=none 或直接 node test/host.test.mjs。

7. 常见问题(都是实测踩过的坑)

Q:面板显示了「○ 空闲」,宿主却还在 recording? 先看 class_status() 的 sources[].lastChunkAt 还在不在前进:不前进就是音频已断。面板显示「● 录音中(宿主)」时点「开始」即可接回同一节(POST /attach),不要另开新会话。

Q:转录全是失败、文本为空,像老师没说话? 大概率是 signal 的坑:两层语音服务都无条件调用 signal.throwIfAborted(),漏传不会报「缺参数」,而是每段都死在 Cannot read properties of undefined (reading 'throwIfAborted')。录音器现在通过 get transcribeSignal() 暴露自己的 controller 信号,测试桩也会像真服务一样检查它。同类教训:桩比真服务宽松,就等于没测。

Q:Client 半边写错会怎样? 会让整个应用起不来:lib/client.js 曾写成裸 _ModuleLoader__.load({…}),渲染进程抛 ReferenceError: _ModuleLoader__ is not defined,界面弹「应用无法启动或已意外停止」,只能点「禁用第三方插件、备份 profile patch 并重启」。两条硬规则由 build-inline.mjs 与 test/client.test.mjs 守护:facade 只在 window 上(没有裸全局),且包装层必须带守卫——facade 缺失时告警并 return,绝不抛错。

Q:为什么默认落在 未命名课程? 课堂中猜课程会把课塞错门,改类还得移动目录。默认落点保证「先录下来」永远成功,课程等你授意转译时按转录内容判定。

Q:音频文件好大,能不留 WAV 吗? 可以:配置项 keepSegmentAudio: false 只留转录;也可以事后 session_delete(..., keep_notes: true) 只删音频。

Q:电脑里的声音怎么录? Windows 到 设置 → 系统 → 声音 → 更多声音设置 → 录制 启用 立体声混音,在面板里选它即可(原因见第 1 节)。

8. 许可证

MIT,见 LICENSE。

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundle为 Web 组合添加 Schedule、其任务页面和时间上下文的可选捆绑包Ab Ocrdsh-ab-ocr--- description: "外部 ocr 工具:逐页识别扫描的 PDF 或图像,仅在处理完最后一页后按顺序合并页面,并使用模型确定的标题级别保存为一个 Markdown 文档。" kind: "package-reference" ---Deepseek Ipptdeepseek-ipptiPolloWork PPT Studio 及其精选幻灯片模板,作为原生 DeepSeek Harness 对话视图。