🎬AI 导演:MiniMax-H3 视频生成插件,由 DeepSeek-Harness 执导。🤖不止是提示词。🪄画布 UI。
54.6/100
综合分
69
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/29 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add chiphoton/DeepSeek-Harness-Video-Director该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · market
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 36 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-video-director(未发布到 npm,仅可源码安装)
✓Node 引擎要求 ^22.19.0 || >=24.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/11/3 09:17:54
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件
查看扫描证据(共 97 处,展示前 90 条)
- 读取本地文件src/index.js:94
const skillContent = skillMarkdownBody(await readFile(skillUrl, 'utf8')) - 写入本地文件src/director-host.js:28
await mkdir(dirname(location.settingsPath), { recursive: true }) - 读取本地文件src/director-host.js:29
const defaultDataDir = await realpath(dirname(location.settingsPath)) - 读取本地文件src/director-host.js:67
return { dataDir: runtime.store.root, defaultDataDir, isDefault: await realpath(runtime.store.root) === defaultDataDir, openLabel: folderOpenLabel(), - 读取本地文件src/director-host.js:80
if (reset && await realpath(previousDataDir) === defaultDataDir) return { ...await storageInfo(), canChange: true, blockedReason: null, previousDataDi - 读取本地文件src/codex-model-catalog.js:118
const cache = JSON.parse(await readFile(this.cachePath, 'utf8')) - 写入本地文件src/codex-model-catalog.js:151
await mkdir(dirname(this.cachePath), { recursive: true, mode: 0o700 }) - 写入本地文件src/codex-model-catalog.js:152
await writeFile(`${this.cachePath}.tmp`, JSON.stringify({ version: 1, fetchedAt, models }) + '\n', { mode: 0o600 }) - 写入本地文件src/codex-model-catalog.js:153
await rename(`${this.cachePath}.tmp`, this.cachePath) - 读取本地文件src/example-projects.js:15
try { entries = await readdir(this.root, { withFileTypes: true }) } - 读取本地文件src/example-projects.js:25
return readFile(join(this.root, id), 'utf8') - 读取本地文件src/project-store.js:129
return JSON.parse(await readFile(path, 'utf8')) - 写入本地文件src/project-store.js:151
mkdir(this.projectsDir, { recursive: true }), - 写入本地文件src/project-store.js:152
mkdir(this.assetsDir, { recursive: true }), - 读取本地文件src/project-store.js:167
const entries = await readdir(this.projectsDir, { withFileTypes: true }) - 删除本地文件递归src/project-store.js:261
catch (error) { await rm(join(this.projectsDir, project.id), { recursive: true, force: true }); throw error } - 写入本地文件src/project-store.js:380
await mkdir(directory, { recursive: true }) - 读取本地文件src/project-store.js:406
try { files = await readdir(directory) } catch (error) { - 写入本地文件src/project-store.js:427
await mkdir(directory, { recursive: true }) - 读取本地文件src/project-store.js:438
const files = await readdir(directory).catch(error => { if (error.code === 'ENOENT') return []; throw error }) - 写入本地文件src/project-store.js:461
await mkdir(directory, { recursive: true }) - 写入本地文件src/project-store.js:572
await rename(directory, tombstone) - 删除本地文件src/project-store.js:585
try { await Promise.all([...filenames].map(filename => rm(join(this.assetsDir, filename), { force: true }))) } - 删除本地文件递归src/project-store.js:596
await Promise.all(staged.map(({ tombstone }) => rm(tombstone, { recursive: true, force: true }))) - 删除本地文件src/project-store.js:664
if (slot.created) await rm(join(this.assetsDir, slot.filename), { force: true }) - 读取本地文件src/project-store.js:766
data: await readFile(join(this.assetsDir, asset.filename)), - 读取本地文件src/project-store.js:773
const info = await stat(filePath) - 删除本地文件src/project-store.js:852
} finally { await rm(temp, { force: true }) } - 读取本地文件src/workflow-store.js:516
const document = JSON.parse(await readFile(spec.file, 'utf8')) - 读取本地文件src/workflow-store.js:556
rows = JSON.parse(await readFile(this.path, 'utf8')) - 写入本地文件src/workflow-store.js:676
await mkdir(dirname(this.path), { recursive: true }) - 写入本地文件src/workflow-store.js:679
await writeFile(temp, `${JSON.stringify(rows, null, 2)}\n`, { flag: 'wx' }) - 写入本地文件src/workflow-store.js:680
await rename(temp, this.path) - 读取本地文件src/storage.js:30
try { saved = JSON.parse(await readFile(settingsPath, 'utf8')) } - 读取本地文件src/storage.js:38
if (!(await stat(dataDir)).isDirectory()) throw new Error('Not a folder') - 写入本地文件src/storage.js:48
await writeFile(temporary, JSON.stringify({ version: 1, dataDir }, null, 2) + '\n', { mode: 0o600, flag: 'wx' }) - 写入本地文件src/storage.js:49
await rename(temporary, settingsPath) - 删除本地文件src/storage.js:50
} finally { await rm(temporary, { force: true }) } - 读取本地文件src/storage.js:59
try { return await realpath(path) } - 读取本地文件src/storage.js:69
const current = await realpath(source) - 读取本地文件src/storage.js:75
const entry = await lstat(destination) - 读取本地文件src/storage.js:76
if (!entry.isDirectory() || (!replaceDefault && (await readdir(destination)).length > 0)) { - 写入本地文件src/storage.js:81
await mkdir(dirname(destination), { recursive: true }) - 写入本地文件src/storage.js:94
try { await rename(destination, backupDataDir) } - 删除本地文件src/storage.js:98
try { await rmdir(destination) } catch (error) { if (error.code !== 'ENOENT') throw error } - 写入本地文件src/storage.js:100
try { await rename(stagedData, destination) } - 写入本地文件src/storage.js:102
if (backupDataDir) await rename(backupDataDir, destination) - 删除本地文件递归src/storage.js:106
} finally { await rm(staging, { recursive: true, force: true }) } - 读取本地文件src/codex-environment.js:17
accessSync(directory, constants.R_OK | constants.W_OK) - 读取本地文件src/codex-environment.js:18
for (const name of readdirSync(directory)) { - 读取本地文件src/codex-environment.js:20
accessSync(join(directory, name), constants.R_OK | constants.W_OK) - 读取本地文件src/codex-executable.js:15
accessSync(candidate, constants.X_OK) - 读取本地文件src/codex-executable.js:16
if (statSync(candidate).isFile()) return candidate - 读取本地文件src/project-folders.js:87
try { this.value = validate(JSON.parse(await readFile(this.path, 'utf8'))) } - 读取本地文件src/project-folders.js:91
try { value.projectOrder = JSON.parse(await readFile(join(this.root, 'project-order.json'), 'utf8')) } catch (error) { if (error.code !== 'ENOENT') th - 写入本地文件src/project-folders.js:102
try { await writeFile(temporary, JSON.stringify(value, null, 2) + '\n', { flag: 'wx' }); await rename(temporary, this.path) } - 写入本地文件src/project-folders.js:102
try { await writeFile(temporary, JSON.stringify(value, null, 2) + '\n', { flag: 'wx' }); await rename(temporary, this.path) } - 删除本地文件src/project-folders.js:103
finally { await rm(temporary, { force: true }) } - 写入本地文件src/asset-layout.js:39
await mkdir(path, { recursive: true }) - 读取本地文件src/asset-layout.js:40
if (!(await lstat(path)).isDirectory()) throw new Error('Asset folders must be real directories, not symbolic links.') - 读取本地文件src/asset-layout.js:46
const info = await lstat(path) - 读取本地文件src/asset-layout.js:49
const stream = createReadStream(path, { flags: constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0) }) - 读取本地文件src/asset-layout.js:122
for (const entry of await readdir(directory, { withFileTypes: true })) { - 读取本地文件src/asset-layout.js:126
else if (entry.isFile() && entry.name.endsWith('.json')) inspect(JSON.parse(await readFile(path, 'utf8'))) - 写入本地文件src/asset-layout.js:136
await writeFile(temporary, JSON.stringify(value, null, 2) + '\n', { flag: 'wx', mode: 0o600 }) - 写入本地文件src/asset-layout.js:137
await rename(temporary, path) - 删除本地文件src/asset-layout.js:138
} finally { await rm(temporary, { force: true }) } - 读取本地文件src/asset-layout.js:146
try { journal = JSON.parse(await readFile(path, 'utf8')) } catch (error) { if (error.code === 'ENOENT') return; throw error } - 删除本地文件src/asset-layout.js:160
await rm(join(assetsDir, move.from), { force: true }) - 写入本地文件src/asset-layout.js:210
await mkdir(directory, { recursive: true }) - 写入本地文件src/asset-layout.js:220
await copyFile(join(assetsDir, move.from), target, constants.COPYFILE_EXCL) - 读取本地文件src/ffmpeg-media.js:55
const info = await stat(output) - 读取本地文件src/ffmpeg-media.js:59
mimeType: frame ? 'image/png' : 'video/mp4', dataBase64: (await readFile(output)).toString('base64') }) - 删除本地文件递归src/ffmpeg-media.js:65
} finally { await rm(directory, { recursive: true, force: true }) } - 读取本地文件src/codex-plan-provider.js:119
try { entries = await readdir(directory, { withFileTypes: true }) } - 读取本地文件src/codex-plan-provider.js:123
.map(async entry => ({ name: entry.name, ...await stat(join(directory, entry.name)) }))) - 读取本地文件src/codex-plan-provider.js:128
bytes: await readFile(join(directory, selected.name)), - 写入本地文件src/codex-plan-provider.js:163
await writeFile(path, data, { flag: 'wx' }) - 删除本地文件递归src/codex-plan-provider.js:228
await rm(directory, { recursive: true, force: true }) - 写入本地文件src/codex-plan-provider.js:245
await writeFile(path, data, { flag: 'wx' }) - 删除本地文件递归src/codex-plan-provider.js:280
await rm(directory, { recursive: true, force: true }) - 写入本地文件src/chat-references.js:39
await mkdir(directory, { recursive: true }) - 读取本地文件src/chat-references.js:41
try { state = JSON.parse(await readFile(join(directory, 'references.json'), 'utf8')) } - 写入本地文件src/chat-references.js:47
await writeFile(temporary, JSON.stringify(state)); await rename(temporary, join(directory, 'references.json')) - 写入本地文件src/chat-references.js:47
await writeFile(temporary, JSON.stringify(state)); await rename(temporary, join(directory, 'references.json')) - 写入本地文件src/chat-references.js:108
await writeFile(join(directory, `${entry.id}-${input.fileIndex}.bin`), data) - 读取本地文件src/chat-references.js:129
const text = await readFile(join(directory, `${entry.id}-${index}.bin`), 'utf8') - 读取本地文件src/media-editor.js:64
const info = await stat(output) - 读取本地文件src/media-editor.js:66
const dataBase64 = (await readFile(output)).toString('base64') - 删除本地文件递归src/media-editor.js:76
await rm(directory, { recursive: true, force: true })
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-mcp-client@deepseek-ai/schemastery@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
2 张 · 点击查看大图功能亮点
- 画布UI操作
- AI执导视频生成
README
由 DeepSeek 最新模型翻译生成简体中文 ·智能体安装指南 ·开发者指南 ·术语表 · vd-node 定义 ·示例库
🎬 DeepSeek-Harness Video-Director
为 DeepSeek Harness 打造的可视化节点式视频导演。
脚本 · 提示词 · 图像 · 音频 · 视频 · 全本地工作流
DSH Plugin · ComfyUI · Ollama · MiniMax-H3
DeepSeek-Harness Video-Director 是专为 DeepSeek Harness 打造的视频制作插件。它把脚本、图像、音频、视频生成变成一张可连线的画布,并内置了 ComfyUI、Ollama、OpenAI 兼容 API 和 Codex Plan 的开箱即用路径。
新手可以直接用内置工作流起步,不必手动拼装每一次服务商调用。原生 Qwen3.8-27B 和 MiniMax-H3 路径让全本地、部署可控的多媒体流水线成为可能——前提是所选模型和运行时支持。
我们把画布元素称为 vd-node,把整张画布图称为 vd-workflow。由 ComfyUI 支撑的 vd-node 执行的是 comfyui-workflow,其中包含 comfyui-nodes。定义、包、绑定和执行 ID 见术语指南。
展开完整文档(README 剩余 1 节)
简体中文 ·智能体安装指南 ·开发者指南 ·术语表 · vd-node 定义 ·示例库 🎬 DeepSeek-Harness Video-Director 为 DeepSeek Harness 打造的可视化节点式视频导演。 脚本 · 提示词 · 图像 · 音频 · 视频 · 全本地工作流 DSH Plugin · ComfyUI · Ollama · MiniMax-H3 DeepSeek-Harness Video-Director 是专为 DeepSeek Harness 打造的视频制作插件。它把脚本、图像、音频、视频生成变成一张可连线的画布,并内置了 ComfyUI、Ollama、OpenAI 兼容 API 和 Codex Plan 的开箱即用路径。 新手可以直接用内置工作流起步,不必手动拼装每一次服务商调用。原生 Qwen3.8-27B 和 MiniMax-H3 路径让全本地、部署可控的多媒体流水线成为可能——前提是所选模型和运行时支持。 我们把画布元素称为 vd-node,把整张画布图称为 vd-workflow。由 ComfyUI 支撑的 vd-node 执行的是 comfyui-workflow,其中包含 comfyui-nodes。定义、包、绑定和执行 ID 见术语指南。 ✨ 为什么选 Video-Director | 亮点 | 你能得到什么 | | 🧩 可视化制作图 | 在一张无限画布上连接文本、图像、音频、视频、工作流、预览和已保存输出。 | | 🚀 新手友好工作流 | 从内置的图像、H3 视频、H3 音频和提示词增强工作流开始。 | | 🏠 本地优先生成 | 在自己机器上跑 Ollama 和 ComfyUI,包括 Qwen3.8-27B 和 MiniMax-H3 流水线。 | | 🔌 多服务商 | 在同一个项目里混用 Ollama、OpenAI 兼容端点、Codex Plan 和一个逻辑 ComfyUI 后端。 | | 🎞️ 项目感知导演 | 每个 Video Project 都有自己的画布、聊天会话、任务、不可变资产和服务商选择。 | | 🌐 语言与存储 | 在英文和中文之间切换,并从 Settings 迁移画布数据。 | | 🛠️ 天生可扩展 | 导入经过审核的 API 格式 comfyui-workflow,或把它们打包成声明式 vd-node 包。 | 🚀 快速开始 1. 安装到 DSH 并运行 环境要求:Git、Node.js ^22.19.0 或 >=24、pnpm 11.7.0,以及已安装的 dsh 命令行。单机全本地部署时,推荐使用 NVIDIA DGX Spark,但并非必须;具体硬件要求取决于你选择的安装预设和模型精度。在你希望存放插件的目录下运行: git clone --branch main --single-branch https://github.com/chiphoton/DeepSeek-Harness-Video-Director.git cd DeepSeek-Harness-Video-Director pnpm install --frozen-lockfile pnpm run build dsh plugin --profile web add "file:$PWD" dsh web dsh web 会打开 DSH Web UI。插件会持久安装到 web 配置档,之后启动只需: dsh web 如果你从同级的源码检出目录运行 DSH,而不是用已安装的命令行: Run once in DeepSeek-Harness-Video-Director pnpm install --frozen-lockfile pnpm run build Then run in the sibling deepseek-harness checkout pnpm dsh plugin --profile web add ../DeepSeek-Harness-Video-Director pnpm dsh web 2. 连接生成器 如果 Ollama 或 ComfyUI 还没准备好,把智能体安装指南交给智能体。它会盘点本仓库用到的具体模型、comfyui-workflows 和 ComfyUI 自定义节点包,只安装你选定的安装预设,并验证结果。默认路径会在本地安装这两个服务;另一条路径让云服务绑定各自的远程 loopback 接口,再通过 SSH 本地端口转发访问它们。 在 Video-Director 中打开 Settings → Connections: - Ollama: 默认 127.0.0.1:11434;在 Ollama 主机上安装模型,例如 Qwen3.8-27B,然后在 Video-Director 中选中它。 - ComfyUI: 默认 127.0.0.1:8188;在 ComfyUI 服务器上安装每个 comfyui-workflow 所需的模型和 ComfyUI 自定义节点包。 - OpenAI Compatible: 设置 Base URL 和 API key,然后刷新以发现服务商的模型列表。 - Codex Coding Plan: 使用本机已有的 Codex 登录,用于提示词和图像工作流。模型和默认推理强度来自已安装的命令行。Refresh 重新加载目录;Fast (priority) 可选,默认关闭。如果 Codex 不在 PATH 中,设置 DSH_VIDEO_DIRECTOR_CODEX_PATH。 连接字段会在你离开该字段或按 Enter 时保存。Refresh 会检查已保存的连接,并显示其模型清单;在单个节点上选择生成模型。ComfyUI 会在 checkpoints、diffusion_models、loras 和 vae 标签页下列出已安装的文件,每个分类内都支持搜索。采样器、调度器和其他工作流选项仍保留在节点控件中。Unload Models 会释放已加载的 Ollama 模型,或在该卡片的端点上请求 ComfyUI 清理模型/缓存。已安装的模型文件仍然可用。在窄屏幕上,Refresh 和 Unload Models 使用图标。API key 字段留空会保留已保存的 key;Clear saved key 会明确移除它的设置覆盖项。 你只需要一个能用的服务商就能开始。Video-Director 不会静默安装模型、ComfyUI 自定义节点包或外部服务。 3. 构建你的第一个 vd-workflow 双击画布空白处,添加 vd-nodes,然后连接兼容的句柄: Text → Prompt Enhancer → H3 Video → Preview → Save Output 在每个可执行的 vd-node 上设置服务商,按需选择其模型或已注册的 comfyui-workflow,输入生成提示词,然后点击 Run。用顶栏的 Save 持久化画布编辑;生成可以基于当前未保存的画布快照运行。 未保存的工作流在项目选择器及其选中标题中以斜体显示,并带一个 *。编辑会自动缓存,与 Save 无关,因此你可以切换项目,并在重启 DSH 后恢复草稿。选择器会显示未保存的数量;拖动项目行可重新排序(或使用 Alt+Up / Alt+Down),每行的 ⋯ 菜单用于项目操作。该顺序在重启后仍然保留。 新建项目、导入、副本以及可编辑的示例副本在你点击 Save 之前都保持未保存状态。Discard changes 会恢复最后一次明确保存的工作流,并清除撤销/重做,同时保留其任务和资产。对于从未保存过的副本,Discard 会移除草稿及其拥有的资产;它的 DSH 会话仍然保留。丢弃前请等待排队中/运行中的任务完成,或先取消它们。 再次点击 Run 即可排队另一个快照。同一 DSH 主机上的所有浏览器标签页共用一个工作流队列,依赖阶段和批次会保持在一起。执行期间,你可以切换、重命名、复制、导入和导出工作流。Jobs 初始拉取最新 10 条记录,滚动到底部时再加载 10 条(或选择 Load 10 more)。已加载的页面会留在当前标签页的控制器内存中,关闭抽屉和切换工作流过滤器都不会丢失;新开标签页或重新加载则从 10 条重新开始。已完成的卡片会在日期时间行后追加 (elapsed time)。Jobs 以紧凑形式展示所有工作流的运行记录,支持过滤、实时耗时、可点击的产物,以及三点菜单,用于下载产物/工作流、打开已提交的快照、删除历史和查看属性。在三点菜单顶部选择 Cancel Job 可取消排队中或运行中的任务;检查器也保留了自己的取消操作。Inspect Property 会在 Submitted 正下方显示 Elapsed Time:它不含排队等待时间,执行期间持续更新,到终止时间戳停止。打开已提交的快照可以撤销;导出会生成可导入的项目归档,并带上其引用的资源。DSH 后端会持久化并调度完整图,包括依赖阶段、触发器和 Batch Input 用例。提交后标签页可以最小化、挂起或关闭。Run N 会添加 N 个独立运行。请保持 DSH 和电脑运行;主机重启后,排队的快照会按顺序恢复,而中断的活动任务会标记为失败,不会重复提交。 复制工作流会创建独立的资源引用,指向同一份已存储的媒体字节。替换输入只影响该副本,删除一个工作流也不会删掉其他工作流引用的文件。可移植导出仍会包含其媒体。 启动 vd-workflow 或单个节点会把其他非冻结、非活动的节点重置为 IDLE,并保留其缓存输出。节点等待时保持 IDLE,执行期间显示 RUNNING 及当前阶段或百分比,完成后显示 COMPLETED,并带上本地完成时间(MMDD-HH:mm:ss)和以秒为单位的耗时。冻结节点保持 FROZEN。新任务的耗时不含 Host 排队等待;较早的历史记录使用其可用的时间戳。 如果 SSH 隧道断开,活动的 ComfyUI 和 Ollama 任务会等待,并以退避策略自动重试。ComfyUI 使用原始 prompt ID 取回已完成的输出;Ollama 重试被中断的文本请求。永久性的配置或执行错误仍会明确失败。 Cancel 也会停止已提交的 ComfyUI 提示词,包括正在 ComfyUI 队列中等待的提示词。任务会一直保持 cancelling,直到该提示词停止;cancelling-reconnecting 表示取消操作正在等待隧道恢复。其他用户的任务不受影响。取消正在运行的提示词需要 ComfyUI 的按任务取消 API;旧版服务器会明确报错,而不是去中断一个无关的任务。Ollama 取消会关闭当前推理请求并停止重试;模型仍保持加载,供后续使用。 🧰 vd-nodes 及其用法 | 分组 | vd-nodes | 用途 | | Inputs | Text、Image、Audio、Video、Sketch | 输入、上传、粘贴、拖放或绘制源素材。 | | Generation | Prompt Enhancer、Image Processing、H3 Video、H3 Audio | 用选定的服务商和模型或 comfyui-workflow 生成或转换媒体。 | | Utilities | VRAM Trigger | 插入执行屏障,可选地卸载 Ollama 模型或清除 ComfyUI 显存/缓存。 | | Outputs | Preview、Save Output | 在项目中查看结果,或用指定文件名下载。 | | vd-node definitions | 内置与导入的定义 | 运行带类型、可复用的 ComfyUI 后端 vd-nodes,配有精简的主控件与 Advanced 控件。 | 画布上的实用操作: - 添加 Image、Audio 或 Video 输入会创建一个空节点。准备好后再选择或拖入文件。 - 音频查看会打开一个紧凑的波形播放器,带滚动时间轴、整轨概览、点击/拖动跳转、缩放、精确播放时间、15 秒快进快退控件、音量与播放速度。时长、格式、采样率、声道数、文件大小和内嵌元数据依然可查。 - 音频/视频预览中 Metadata 左侧的 Edit 会打开 Media Editor。你也可以右键选择 Edit Audio 或 Edit Video。用波形手柄或精确时间裁剪;视频还提供可拖动的裁剪矩形、宽高比预设和 Export current frame。Export 下载结果,不改动源文件;Save 将其应用到当前源文件;Save as new copy 让副本生效,并在 Gallery 中保留原文件。Discard changes 关闭且不应用编辑。未做改动时,关闭按钮直接退出;有未保存的编辑时,会先请求确认。源文件的改动支持 Undo,关闭右键菜单只需点击别处。编辑需要 DSH 主机上有 ffmpeg 和 ffprobe;输出为 MP4 视频、FLAC/WAV 音频或 PNG 帧。 - Image、Audio 和 Video 输入的右键菜单提供 Replace 和 Inspect。点击图片可在 Preview 查看器中查看,点击文件名可替换其文件;悬停或聚焦文件名会显示 Replace。替换会保留节点与连接,重置其蒙版与裁剪,并支持 Undo。 - 把匹配的文件拖到 Text、Image、Audio 或 Video 输入上,即可替换其内容。Batch Input 接受多个受支持的文本/媒体文件,并应用其文件名正则;不受支持的文件会被跳过并给出提示。拖放到输入节点上永远不会额外创建画布节点。 - Input、Preview 和 Save Output 中的视频检查会显示尺寸、FPS、格式、时长和文件大小。Metadata 会打开容器/流标签和编解码器详情。详细的视频检查使用 DSH 主机上 FFmpeg 的 ffprobe;如果它不可用,浏览器可读的尺寸和时长仍会显示。 - Gallery 位于 Tasks 旁边,在 All workflows 上打开,把源产物归到 Input 下,把缓存结果和保留的任务历史归到 Output 下。可按工作流筛选,并搜索文件名、工作流/节点名称、媒体类型或文本内容;卡片会标明所属工作流,未保存的草稿也会包含在内。浏览不会切换或保存当前活动的工作流。Refresh 会重新加载目录。重复文件按工作流/标签各出现一次。点击任意图像、视频、音频或文本卡片即可检查;图像支持拖拽平移、滚轮/按钮缩放、Reset view 和 Metadata。关闭 Inspect 会保留 Gallery 标签、筛选和搜索。 - Text 输入会在文本框上方显示实时字符数,下方有 Import(UTF-8 文本文件)和 Clear。Import 会替换文本,同时保留空白;两个操作都支持 Undo。 - 双击空白处可搜索节点菜单。 - 把输出拖到空白处,即可创建并连接兼容节点。 - Select (V): 拖拽空画布可平移,点击节点可选中,拖拽节点可移动。Hand (H): 在任意位置拖拽都可平移,包括节点及其控件上方。按住 Space 可临时进入 Hand 导航。 - 侧边栏接受 Image、Audio、Video、Folder 和 Node 引用。紧凑磁贴会在悬停或键盘聚焦时显示预览/移除控件;点击主体会插入原子别名,例如 <Image 1>。移除未发送的引用会重新编号草稿别名;已发送的别名保持稳定。双击节点标题栏任意位置、把可编辑标题拖进聊天、选择 + → Node,或右键点击节点并选择 Add to Chat References。媒体和文件夹可拖放到侧边栏任意位置。文件夹预览提供可搜索的树。别名属于对话;导入的画布资源保留其原始文件名。 - 侧边栏上下文包含紧凑的工作流摘要。Host 拥有的 vd_canvas 工具按需查询详情,并可在标签关闭后编辑/验证/运行工作流。会检测人工/智能体编辑冲突。命令、上下文处理和当前限制见 sidebar architecture and validation。 - Ctrl 拖拽可在任一模式下选中一组节点;Ctrl 单击添加或移除单个节点。在 macOS 上,Command 同样适用于这些手势和快捷键;Ctrl 单击只选中节点,不会打开上下文菜单。选中的节点边框会加粗,Select 模式下可拖拽的节点区域使用十字光标。Ctrl+B 冻结或解冻所选内容。 - 在画布或节点上滚动可缩放。可滚动字段和面板会占用滚轮事件,用来滚动自身内容。 - 右键点击空白画布,可打开 Node catalog、Reset VRAM 或 Paste。右键点击节点,可执行 Run/Cancel、Freeze、Copy、Duplicate、Rename、Details 和 Delete。输入字段保留原生上下文菜单。 - Ctrl+C / Ctrl+V 在当前项目内复制粘贴节点,包括被复制节点之间的连接。复制会生成快照;粘贴出的节点获得新身份,并创建在光标位置。Reset VRAM 会卸载已配置的 Ollama 模型,并释放 ComfyUI 的模型与缓存内存。 - 选中节点后,用 Run 运行单个节点、一组选中节点、下游节点或整张图。 - 把生成的媒体连接到 Preview 和 Save Output;未连接的结果会自动获得一个 Preview。 内置的 vd-node 定义包括:用 Qwen-Rapid-AIO-SFW-v19.safetensors 做 Qwen 图像编辑、Z-Image Turbo、MiniMax-H3 文本/图像转视频、参考图转视频,以及 Turbo/Standard H3 音频。依赖项与安全注意事项见 custom_nodes/。 🪄 ComfyUI workflow-to-node 技能 内置的 comfyui-workflow-to-node 技能可把可信的 comfyui-workflow 转换成以下两种形式之一: - 仓库内置的已注册 comfyui-workflow;或 - 可移植的声明式 vd-node 包(即现有的 Custom Node v1 协议)。 在 DSH 对话中调用它: $comfyui-workflow-to-node Convert /absolute/path/my-workflow-api.json into a reusable vd-node pack. Keep model and sampler controls in Advanced. API 格式的工作流可以离线分析。编辑器/UI 工作流需要从匹配的 ComfyUI /object_info 获取精确元数据;一旦映射存在歧义,技能会直接停止,而不是猜测。转换过程不会提交图、不会安装 ComfyUI 自定义节点包、不会下载模型,也不会生成媒体。 该技能已为插件分发做好准备:项目源码位于 skills/comfyui-workflow-to-node/,package.json 在发布包中包含 skills/,Host 在把技能正文注册到 DSH Skills 服务之前会剥离其 YAML front matter,同时保留本地引用和脚本。 项目选择器包含 examples/ 文件夹。选择 canvas-demo 或 all-in-one 可打开一份独立、可编辑的副本;当前编辑会先保存,导入绝不会启动生成。Settings → Language 可立即切换英文/中文,并在当前浏览器中记住选择。 选择器支持嵌套的虚拟文件夹。文件夹的三点菜单提供 New Workflow、New Folder、移动、重命名和删除。Move to… 会打开可折叠的目录树,根目标为 /;全局菜单保留 Import project。把项目拖到文件夹上即可移入其中,拖到同级项目之间即可重新排序;拖到任一边缘附近会滚动,拖到 / 上则移到顶层。Multi-Select 用复选框替换行菜单,并新增批量菜单,支持全选、取消全选、反选、移动和删除,包括折叠文件夹内的项目。选中文件夹及其后代时,移动会保留它们的嵌套关系。删除确认会分别列出受影响的工作流和文件夹:显式选中的工作流会被删除,而文件夹子项可以移到 / 或删除。混合选择时,选中的工作流需要单独确认。文件夹组织只更新快捷方式元数据;它绝不会创建磁盘目录,也不会移动工作流或素材文件。 💾 文件保存在哪里 默认 Host 数据目录是 ./.dsh-video-director,从 dsh web 启动时所在的目录解析: .dsh-video-director/ ├── project-folders.json # virtual folders, shortcut membership, and ordering ├── projects/<project-id>/project.json # saved workflow, optional draft, and recent jobs ├── projects/<project-id>/runs/ # run summaries and immutable submitted snapshots ├── assets/index.json # IDs, ownership, original names, hashes, and relative paths ├── assets/inputs/<original-name>.<ext> # uploaded input files, shared across workflows ├── assets/inputs/mask/mask-YYYYMMDD-<short-uuid>.<ext> ├── assets/inputs/sketch/sketch-YYYYMMDD-<short-uuid>.<ext> ├── assets/outputs/YYYYMMDD-<uuid>.<ext> # generated and edited media ├── migrations/asset-layout-v2.json # legacy index and completed migration mapping, when needed └── workflows.json # imported workflow registry 上传的输入文件保留原始文件名。同名文件若 SHA-256 相同,就复用已存储的文件;字节不同则依次尝试 name-0001.ext、name-0002.ext,以此类推,每个候选名都会校验哈希。工作流引用共享不可变字节,只有当某个文件的最后一个引用消失时,删除工作流才会删除该文件。日期使用 UTC。生成的输出在索引中保留服务商文件名,下载和导出也使用该文件名。 Image、Video、Audio 和 Sketch 输入提供 Choose from assets,会显示所有工作流中兼容的输入和输出,支持文件名搜索和来源筛选。选择器每次加载 15 项;滚动到底部会加载接下来 15 项,搜索/筛选结果也一样。点击缩略图可以预览而不选中,然后选中一行并选择 Use asset 来附加它。选中素材只会添加引用,不会复制其媒体。空的 Sketch 输入还提供 Draw sketch。 首次启动时,如果检测到旧版扁平资源文件夹,会自动迁移。迁移会检查本地哈希以及工作流/任务元数据,不解码媒体,也不联系服务商。迁移保留 ID 和 URL,先暂存文件,再原子替换索引,并把原始索引与映射保留在迁移记录中。中断的迁移会在下次启动时继续。无法识别输出来源的文件仍作为输入保留;哈希不匹配会停止迁移,且不改动原始文件。 Settings → Storage 可以打开当前文件夹、切换到新文件夹或空文件夹,或重置为最初的 dataDir。切换时会缓存当前草稿、复制画布数据,并立即生效;之前的文件夹保留为备份。原始数据目录会保留 .video-director-storage.json,这样重启后选择依然有效。生成任务和工作流必须先完成或取消。原生文件夹控件作用于 Harness 宿主机。Harness 继续管理对话历史和服商凭据。你也可以在插件的 DSH 配置里设置初始 dataDir。Save Output 通过浏览器把副本下载到浏览器配置的下载目录;项目拥有的资源仍保留在 dataDir/assets 下。 📝 Notes - 本插件负责编排服务商,本身不是托管式生成服务。Ollama、ComfyUI、模型和远程 API 账号都需另行运维。 - 「完全本地」指所选的 Ollama/ComfyUI 路径始终位于你掌控的基础设施上。 - MiniMax-H3 权重有单独的许可证。启用生产或商业用途前请先审阅。 - ComfyUI 工作流 JSON 是可执行配置,因为它能调用已安装的 ComfyUI 自定义节点包。只导入可信的图。 - 上传资源默认每个上限 200 MiB。项目保留最近 100 条任务记录。 - 画布编辑是显式保存。运行时会捕获不可变快照,因此之后的编辑不会改变已排队的工作。 - 插件把 DSH Web 绑定到常规的 loopback 安全默认值。任何远程 Ollama、ComfyUI 或 OpenAI 兼容端点都要做好防护和认证。 配置、架构、传输行为、恢复、安全、限制和开发命令,请阅读开发者指南。 License MIT。模型权重、ComfyUI、ComfyUI 自定义节点包和外部服务各自保留其许可证与条款。 Batch Input 和 Batch Output 支持顺序的文本/文件/文件夹用例、正则过滤、闭区间索引范围、逐节点种子策略,以及带索引的预览/下载。参见批处理。批处理用例在 DSH 后端运行,浏览器关闭后仍会继续。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
chiphoton/DeepSeek-Harness-Video-Director
🎬AI 导演:MiniMax-H3 视频生成插件,由 DeepSeek-Harness 执导。🤖不止是提示词。🪄画布 UI。
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,225未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,370已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13941 个插件含 PR 收录与…
★ 355已汉化DSH
71.8
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这是你的仓库?认领条目