回放会话时间线,录屏自动生成可安装技能
28.6/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add azure5100/huahua-dsh-record-replay该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 76 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 91 处,展示前 73 条)
- 发起网络请求lib/client.js:37
return (await readJson(await fetch("/api/dsh-record-replay/recordings", { - 发起网络请求lib/client.js:44
await readJson(await fetch("/api/dsh-record-replay/recording" + query({ - 发起网络请求lib/client.js:53
return (await readJson(await fetch("/api/dsh-record-replay/recording" + query({ - 发起网络请求lib/client.js:62
return (await readJson(await fetch("/api/dsh-record-replay/recordings"))).recordings; - 发起网络请求lib/client.js:65
return (await readJson(await fetch("/api/dsh-record-replay/recording" + query({ id })))).recording; - 发起网络请求lib/client.js:68
await readJson(await fetch("/api/dsh-record-replay/recording" + query({ id }), { method: "DELETE" })); - 写入剪贴板lib/client.js:8763
await navigator.clipboard.writeText(text); - 读取本地文件lib/routes.js:106
const stream = createReadStream(file, { start, end }); - 读取本地文件lib/routes.js:118
const stream = createReadStream(file); - 读取本地文件lib/routes.js:440
const stream = createReadStream(file); - 读取本地文件lib/recording-store.js:28
const text = await readFile(join(this.dir(id), 'metadata.json'), 'utf8'); - 写入本地文件lib/recording-store.js:37
await writeFile(join(this.dir(meta.id), 'metadata.json'), JSON.stringify(meta, null, 2), 'utf8'); - 写入本地文件lib/recording-store.js:41
await mkdir(this.root, { recursive: true }); - 写入本地文件lib/recording-store.js:43
await mkdir(this.dir(id), { recursive: true }); - 写入本地文件lib/recording-store.js:44
await mkdir(join(this.dir(id), 'frames'), { recursive: true }); - 写入本地文件lib/recording-store.js:54
await writeFile(join(this.dir(id), 'video.webm'), body); - 写入本地文件lib/recording-store.js:64
await mkdir(join(this.dir(id), 'frames'), { recursive: true }); - 读取本地文件lib/recording-store.js:80
entries = await readdir(this.root); - 读取本地文件lib/recording-store.js:104
const info = await stat(this.videoPath(id)); - 删除本地文件递归lib/recording-store.js:122
await rm(this.dir(id), { recursive: true, force: true }); - 写入本地文件lib/skill-installer.js:68
await mkdir(dir, { recursive: true }); - 写入本地文件lib/skill-installer.js:69
await writeFile(join(dir, 'SKILL.md'), parsed.text, 'utf8'); - 读取本地文件lib/skill-installer.js:76
entries = await readdir(this.root); - 读取本地文件lib/skill-installer.js:86
const text = await readFile(join(this.root, entry, 'SKILL.md'), 'utf8'); - 读取本地文件lib/session-store.js:46
raw = new Uint8Array(await readFile(file)); - 读取本地文件lib/session-store.js:61
raw = new Uint8Array(await readFile(file)); - 读取本地文件lib/session-store.js:107
projects = await readdir(this.root); - 读取本地文件lib/session-store.js:118
sessions = await readdir(projectDir); - 读取本地文件lib/session-store.js:130
const info = await stat(read.file).catch(() => undefined); - 读取本地文件lib/session-store.js:145
const raw = new Uint8Array(await readFile(summary.path)); - 写入本地文件lib/pack-store.js:17
await mkdir(this.root, { recursive: true }); - 写入本地文件lib/pack-store.js:24
await writeFile(file, JSON.stringify(pack, null, 2), 'utf8'); - 读取本地文件lib/pack-store.js:25
const info = await stat(file); - 读取本地文件lib/pack-store.js:39
files = await readdir(this.root); - 读取本地文件lib/pack-store.js:52
const info = await stat(join(this.root, file)); - 读取本地文件lib/pack-store.js:75
const text = await readFile(join(this.root, `${id}.json`), 'utf8'); - 删除本地文件lib/pack-store.js:87
await rm(join(this.root, `${id}.json`)); - 发起网络请求src/client/api.ts:49
const response = await fetch(API_BASE + '/recordings', { - 发起网络请求src/client/api.ts:59
const response = await fetch(API_BASE + '/recording' + query({ id, part: 'video' }), { - 发起网络请求src/client/api.ts:67
const response = await fetch(API_BASE + '/recording' + query({ id, name }), { - 发起网络请求src/client/api.ts:76
const response = await fetch(API_BASE + '/recordings') - 发起网络请求src/client/api.ts:82
const response = await fetch(API_BASE + '/recording' + query({ id })) - 发起网络请求src/client/api.ts:88
const response = await fetch(API_BASE + '/recording' + query({ id }), { method: 'DELETE' }) - 写入本地文件src/pack-store.ts:17
await mkdir(this.root, { recursive: true }) - 写入本地文件src/pack-store.ts:25
await writeFile(file, JSON.stringify(pack, null, 2), 'utf8') - 读取本地文件src/pack-store.ts:26
const info = await stat(file) - 读取本地文件src/pack-store.ts:40
try { files = await readdir(this.root) } catch { return [] } - 读取本地文件src/pack-store.ts:47
const info = await stat(join(this.root, file)) - 读取本地文件src/pack-store.ts:70
const text = await readFile(join(this.root, `${id}.json`), 'utf8') - 删除本地文件src/pack-store.ts:78
try { await rm(join(this.root, `${id}.json`)); return true } catch { return false } - 读取本地文件src/recording-store.ts:31
const text = await readFile(join(this.dir(id), 'metadata.json'), 'utf8') - 写入本地文件src/recording-store.ts:39
await writeFile(join(this.dir(meta.id), 'metadata.json'), JSON.stringify(meta, null, 2), 'utf8') - 写入本地文件src/recording-store.ts:44
await mkdir(this.root, { recursive: true }) - 写入本地文件src/recording-store.ts:46
await mkdir(this.dir(id), { recursive: true }) - 写入本地文件src/recording-store.ts:47
await mkdir(join(this.dir(id), 'frames'), { recursive: true }) - 写入本地文件src/recording-store.ts:57
await writeFile(join(this.dir(id), 'video.webm'), body) - 写入本地文件src/recording-store.ts:66
await mkdir(join(this.dir(id), 'frames'), { recursive: true }) - 读取本地文件src/recording-store.ts:82
try { entries = await readdir(this.root) } catch { return [] } - 读取本地文件src/recording-store.ts:102
const info = await stat(this.videoPath(id)) - 删除本地文件递归src/recording-store.ts:116
try { await rm(this.dir(id), { recursive: true, force: true }); return true } catch { return false } - 读取本地文件src/routes.ts:98
const stream = createReadStream(file, { start, end }) - 读取本地文件src/routes.ts:110
const stream = createReadStream(file) - 读取本地文件src/routes.ts:382
const stream = createReadStream(file) - 读取本地文件src/session-store.ts:53
try { raw = new Uint8Array(await readFile(file)) } catch { continue } - 读取本地文件src/session-store.ts:64
try { raw = new Uint8Array(await readFile(file)) } catch { continue } - 读取本地文件src/session-store.ts:105
try { projects = await readdir(this.root) } catch { return out } - 读取本地文件src/session-store.ts:110
try { sessions = await readdir(projectDir) } catch { continue } - 读取本地文件src/session-store.ts:116
const info = await stat(read.file).catch(() => undefined) - 读取本地文件src/session-store.ts:130
const raw = new Uint8Array(await readFile(summary.path)) - 写入本地文件src/skill-installer.ts:72
await mkdir(dir, { recursive: true }) - 写入本地文件src/skill-installer.ts:73
await writeFile(join(dir, 'SKILL.md'), parsed.text, 'utf8') - 读取本地文件src/skill-installer.ts:80
try { entries = await readdir(this.root) } catch { return [] } - 读取本地文件src/skill-installer.ts:85
const text = await readFile(join(this.root, entry, 'SKILL.md'), 'utf8')
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-locale@deepseek-ai/dsh-client-runtime@deepseek-ai/dsh-client-ui-settings@deepseek-ai/dsh-client-ui-slots@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-settings@deepseek-ai/dsh-system-prompt给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 会话时间线回放
- 回放包导出导入
- 录屏生成技能
DSH 录制回放插件:会话时间线回放、回放包导出导入、重跑录制的对话、录屏生成技能
README
由 DeepSeek 最新模型翻译生成🐻 huahua 出品 · DSH Record & Replay
DSH 录制回放插件 · 由 huahua 打造并持续维护
| 品牌 | 项目 |
| 🐻 huahua | 本插件(录制回放) |
| 🐻 huahua | huahua-dsh-plugin-orchestra · 插件管理系统 |
huahua 系列:为 DeepSeek Harness 打造实用、完整、可维护的插件。
DSH Web GUI 的「录制回放」插件,两套能力:
1. 会话回放:DSH 自动录制每一场会话(~/.dsh/sessions/session.jsonl.zstd),本插件把它变成可用资产——时间线回放、导出/导入可分享的回放包、一键复刻到全新会话重新执行。
2. 录屏 → 生成技能(Codex Record & Replay 同款):在浏览器里录下你的屏幕操作(computer use,getDisplayMedia → webm 视频 + 采样帧),回放查看,并让 agent 逐帧分析(describe_image)自动生成 SKILL.md,安装进 ~/.dsh/skills 立即可用。
类似 Codex 的 record & replay:录制是自动的,本插件补齐「回放 / 分享 / 复刻」这一半。
展开完整文档(README 剩余 1 节)
🐻 huahua 出品 · DSH Record & Replay
DSH 录制回放插件 · 由 huahua 打造并持续维护
| 品牌 | 项目 |
| 🐻 huahua | 本插件(录制回放) |
| 🐻 huahua | huahua-dsh-plugin-orchestra · 插件管理系统 |
huahua 系列:为 DeepSeek Harness 打造实用、完整、可维护的插件。
DSH Web GUI 的「录制回放」插件,两套能力:
1. 会话回放:DSH 自动录制每一场会话(~/.dsh/sessions/session.jsonl.zstd),本插件把它变成可用资产——时间线回放、导出/导入可分享的回放包、一键复刻到全新会话重新执行。
2. 录屏 → 生成技能(Codex Record & Replay 同款):在浏览器里录下你的屏幕操作(computer use,getDisplayMedia → webm 视频 + 采样帧),回放查看,并让 agent 逐帧分析(describe_image)自动生成 SKILL.md,安装进 ~/.dsh/skills 立即可用。
类似 Codex 的 record & replay:录制是自动的,本插件补齐「回放 / 分享 / 复刻」这一半。
衍生声明(Derivative notice):本仓库是 kangshifu1/dsh-record-replay(Apache-2.0)的适配衍生版。原项目作者:kangshifu1。本项目在此基础上做了 Windows / DSH rc.5 适配修复(见下方「Windows 适配」一节),其余功能与架构源自原项目。按 Apache-2.0 §4 注明来源与本项目改动。
Windows 适配(Windows adaptation)
本项目在 Windows + DeepSeek Harness 0.1.0-rc.5 上实测通过,并为此做了 4 处客户端源码适配(原版按更新一代 DSH 外壳的 DOM 约定编写,在 rc.5 上不可用):
| 文件 | 适配内容 |
| src/client/mount.tsx | 面板挂载选择器双匹配:[data-pane="conversation"], [class="centerCol"]——适配 rc.5 外壳(无 data-pane,中央列为 CSS Module 类名 centerCol) |
| src/client/styles.ts | 定位上下文同步双选择器——修复「进入面板后左侧主界面被整个盖住」的问题(rc.5 无 data-pane 定位上下文,绝对定位会锚定到外层 frame) |
| src/client/locales.ts | 新增「关闭面板」文案(中英双语) |
| src/client/panel/ReplayPanel.tsx | 面板头部加「关闭面板」按钮——原版无关闭入口,界面被盖住时无法返回对话 |
适配目标 DSH 版本:DeepSeek Harness 0.1.0-rc.5(Windows 桌面版)。在带 data-pane/taskboard/ssh 面板的新版外壳上,双选择器保持向后兼容(老规则对不存在的元素是空操作)。
完整适配过程与踩坑记录见:docs/适配修复报告.md(Windows 环境构建:NTFS 目录联接、pnpm 11、Node ≥ 20)。
能力
| 功能 | 说明 |
| 会话库 | 侧边栏「录制回放」入口,列出本机全部已录制会话(标题 / 项目 / 时间 / 消息数) |
| 时间线回放 | 以可读时间线查看任意会话:用户消息、助手回复(推理过程可折叠)、工具调用与参数、工具结果(长文可展开),支持搜索过滤 |
| 导出回放包 | 把任意会话导出为单个 dsh-replay-pack JSON(.replay.json),git 友好、体积小,可直接放到 GitHub 仓库分享 |
| 导入回放包 | 导入队友 / GitHub 上分享的 .replay.json,存到 ~/.dsh/replay-packs,可查看、删除、复刻 |
| 复刻执行 | 把录制会话的用户消息按原顺序逐条发送到全新会话,让 agent 真实重新执行一遍(可用于复现、回归、教学、模板化流程) |
| 录屏 | 浏览器 getDisplayMedia 录制屏幕/窗口(webm + 每 2s 采样帧,存 ~/.dsh/recordings),支持回放与删除 |
| 生成技能 | 一键让 agent 会话逐帧分析录屏(describe_image),输出 SKILL.md 并安装到 ~/.dsh/skills——新技能被 skill 目录热监听发现,直接进入每个会话的技能目录 |
安装
本地路径安装(开发 / 自用,推荐)
dsh plugin --profile web add link:/path/to/dsh-record-replay
或从 npm 安装(发布后)
dsh plugin --profile web add dsh-record-replay
安装后重启 dsh web GUI(插件集会变更需要重启生效)。侧边栏出现「录制回放」入口即成功。
原理:dsh plugin 是 pnpm 转发器——把包装进 profile 的 node_modules,检测到 dsh.bundle 声明后把 cordis.patch.yml 并入 bundle 层,插件行进入 roster;浏览器半区按 dsh.client 声明以 /plugins/dsh-record-replay/client.js 加载。
使用
1. 点侧边栏「录制回放」打开面板。
2. 会话 tab:任一会话可「回放」(时间线)、「导出」(下载回放包)、「复刻」(开新会话重新执行)。
3. 回放包 tab:导入 .replay.json,管理已导入的包。
4. 录屏 tab:点「开始录屏」选择屏幕/窗口录制操作;停止后自动上传视频与采样帧。对任意录屏可「回放」,或点「生成技能」——插件开一个 agent 会话,让它逐帧调用 describe_image 提炼工作流并产出 SKILL.md,写入 ~/.dsh/skills//SKILL.md 后即成为可用技能。
回放包格式
{
"format": "dsh-replay-pack",
"version": 1,
"meta": { "title": "...", "cwd": "...", "createdAt": 0, "agentPreset": "code", "exportedAt": 0, "sourceSessionId": "session-..." },
"items": [
{ "kind": "user", "turn": 1, "step": 1, "text": "...", "time": 0 },
{ "kind": "assistant", "turn": 1, "step": 1, "text": "...", "reasoning": "...", "time": 0 },
{ "kind": "tool", "turn": 1, "step": 1, "name": "run_code", "callId": "...", "argsText": "{...}", "time": 0 },
{ "kind": "result", "turn": 1, "step": 1, "callId": "...", "text": "...", "time": 0 }
]
}
数据与隐私
- 读取:~/.dsh/sessions/*/session.jsonl(.zstd)(DSH 自动录制,本插件只读)。
- 写入:~/.dsh/replay-packs/(导入的回放包)、~/.dsh/recordings/(录屏)、~/.dsh/skills/(生成的技能)。
- 录屏隐私:录屏会捕获屏幕上的一切(含密码输入等),生成技能前请留意;录制全程仅在浏览器本地,上传存于本机 ~/.dsh/recordings。
- 注意:回放包含完整对话与工具输出,可能含密钥 / 敏感信息——分享前请自行脱敏。API 路由仅限 loopback(本机浏览器同源),LAN 暴露的 dsh web 部署不会提供服务。
开发
pnpm install
pnpm build # tsc 编译宿主半区到 lib/,tsdown 打包浏览器半区到 lib/client.js
pnpm smoke # 对本机真实会话跑一遍 扫描→解析→建包→解析→存库 冒烟测试
架构
双面插件(dsh-web-ui 家族约定):
- 宿主半区(src/index.ts,node):SessionStore 扫描解码会话、timeline.ts 蒸馏时间线、replay-pack.ts / pack-store.ts 回放包、recording-store.ts 录屏存储(webm + 帧,视频带 Range 支持)、skill-installer.ts 技能安装(校验 frontmatter 与 skill 命名、写入 ~/.dsh/skills)、routes.ts 提供 /api/dsh-record-replay/,并向 agent 宣告插件存在(system-prompt section)。zstd 解码使用 vendored fzstd(MIT,支持多帧流),无运行时第三方依赖。
- 浏览器半区(src/client/):侧边栏入口(DOM 级注入、自愈)+ 中央列面板(React,单占用者接管,与 task-board / ssh 面板互斥)。会话/回放包/录屏三个 tab;复刻执行与技能生成都复用官方 sessions / workspaces / connection 服务——技能生成会话用 describe_image 逐帧看录屏帧(宿主以 HTTP URL 提供),最后把 agent 输出的 SKILL.md 交给宿主安装。
License
Apache-2.0。Vendored fzstd © 101arrowz, MIT(见 THIRD_PARTY_NOTICES.md)。
🐻 huahua 出品
huahua(花花的团队/个人)致力于为 DeepSeek Harness 打造高质量插件:
- huahua-dsh-plugin-orchestra — DSH 插件管理系统:清单 / 更新检测 / 一键升级 / 备份回滚
- 本插件(record-replay) — DSH 录制回放:会话时间线 / 回放包 / 复刻 / 录屏生成技能
功能完整、Windows 实测可用、持续维护。有问题欢迎提 Issue / PR。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
azure5100/huahua-dsh-record-replay
回放会话时间线,录屏自动生成可安装技能
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,489已汉化DSH
73.1
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,918已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,453已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
Download DS Bot for Windows 10/11 64-bit / 下载 Windows…
★ 5,293已汉化DSH
71.2
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,797已汉化DSH
71.1
这是你的仓库?认领条目