前言¶
在 DSH(DeepSeek Harness)里跑生图、MCP 出图或各类插件任务时,产物往往落在 $DSH_HOME/plugin-data 下的固定目录,记录分散在 tasks.json、mcp-records.json 里。若只靠文件管理器翻目录,很难和任务元数据(prompt、modelId、时间)对应;若把画廊做成占据中央聊天区的常驻面板,又会挤占对话区域。下面介绍社区插件 deepseek-media-gallery(维护者 yuanyiHY):以侧边栏底部按钮打开半透明弹窗,在本机完成列表、预览、Range 播放、下载与删除,不占用主聊天区。
这是什么¶
DeepSeek Media Gallery 是 DSH(cordis)生态下的客户端 + 宿主组合插件:宿主半边在 Node 侧注册本地 HTTP 路由与文件读写;浏览器半边通过 window.__ModuleLoader__.load 注入,在侧边栏注册入口并在帧级浮层渲染 React 弹窗(非 iframe)。分类上属于客户端能力,所有媒体读写均在本地文件系统完成,不联网、不上传。
- 目录页:https://www.skillhub.cn/plugins/yuanyiHY/deepseek-media-gallery
- 源码与说明:https://github.com/yuanyiHY/deepseek-media-gallery
- 许可证:MIT(见仓库
package.json) - 版本(资料记载):1.0.0
架构:两半各管一段¶
插件 deliberately 拆成两条线,避免和 client/ 下的独立调试页混淆:
| 半边 | 文件 | 作用 |
|---|---|---|
| 宿主(Node) | lib/index.js |
cordis 插件:注册 <prefix>/* 路由,提供 API 与静态独立页 |
| 浏览器 | lib/client.js |
DSH 客户端插件:apply(ctx) 里经 ctx.slots 注册按钮与弹窗 |
client/index.html + client/client.js 由宿主路由 <prefix>/ 与 <prefix>/client.js 提供,用于在浏览器直接打开画廊调试;与 lib/client.js 不是同一套脚本。
入口与交互:不占中央区¶
插槽注册如下(资料原文):
| 插槽 | kind | 注册项 | 说明 |
|---|---|---|---|
sidebar.footer.action |
list | { id: 'media-gallery-panel', order: 60 } |
侧边栏底部(设置旁)入口,wide 等 props |
shell.overlay |
list | { id: 'media-gallery-panel', order: 60 } |
帧级浮层,弹窗本体 |
不注册 main / sidebar.panellist,避免画廊变成常驻中央面板。弹窗关闭时组件返回 null,不常驻 DOM。
关闭方式:右上角关闭、点击背景遮罩、按 Esc(先关预览大图,再关窗口)。
视觉上半透明背景与 dsh-rail-equalizer(律动) 同款 token:弹窗底色用 var(--dsw-specific-input-major, …),卡片用 var(--dsw-specific-bubble, …),模糊用 blur(var(--we-blur,16px)) saturate(var(--we-saturate,1.8));无 wallpaper-engine 主题时回落到官方 --dsw-alias-*。
核心功能¶
媒体列表与兜底扫描¶
GET /api/tasks 合并三路来源并按文件名去重(同名保留 tasks.json 条目):
dataRoot下的tasks.json:仅status === "done"且文件仍存在才展示。mcp-records.json:例如 MCP 生图(ofapp-image-mcp)登记的文件。- 目录扫描兜底:图片目录里存在但未登记的媒体也会列出(上限 500,按修改时间倒序,
adapterId: "scan")。因此把generatedDir指到一个普通图片文件夹也能直接用。
预览与 Range 播放¶
GET /api/media/:filename 支持 Range(如 bytes=0-9、bytes=-10、bytes=50-);越界或畸形请求返回 416,便于视频分段加载。
下载(复制,不删原文件)¶
| 方式 | 行为 |
|---|---|
| 卡片 ⤓ / 预览内「下载」 | POST /api/download,服务端复制到下载目录,原文件不动 |
| 复制失败(如无写权限) | 退回浏览器下载 GET <prefix>/api/file/<name>(Content-Disposition: attachment) |
同名不覆盖:第二份存为 名字 (2).ext。删除才会移除存档文件,勿与「清空下载目录」混淆。
删除(不可撤销)¶
DELETE /api/tasks/:id,请求体含 { "filename": "..." }:同时删记录与磁盘文件,并清理对应 mcp 记录。filename 仅接受媒体目录内裸文件名,拒绝路径分隔符、..、: 与 NUL。
设置:三项路径,保存即生效¶
弹窗右上角齿轮进入设置。三项均可改,保存后立即生效,无需重启 host(每次 API 实时读配置):
| 键 | 含义 | 默认 |
|---|---|---|
generatedDir |
画廊扫描的图片/视频目录 | $DSH_HOME/plugin-data/image-gen/generated |
dataRoot |
tasks.json / mcp-records.json 所在目录 |
$DSH_HOME/plugin-data/media-gallery |
downloadDir |
下载目标 | 自动探测的桌面 |
「选择…」优先调用宿主原生目录对话框(ctx.uiWorkspace.pickDirectory());失败则退到内置目录浏览器(盘符行、面包屑、新建文件夹、「转到」粘路径,含 E:\ 与 UNC)。Linux 上原生对话框依赖 zenity/kdialog 与 DISPLAY;Windows/macOS 上 native pick 不可用时会走 browse 能力。
配置优先级:用户在面板保存的值 > profile cordis.patch.yml 中的 config > 环境变量 > 默认。generatedDir / dataRoot 仍可用 DEEPSEEK_MEDIA_GENERATED_DIR / DEEPSEEK_MEDIA_DATA_DIR 作为种子(经 dsh-settings 组合层)。
宿主 Config(schemastery schema)种子项还包括:
| 键 | 默认 | 说明 |
|---|---|---|
routePrefix |
/deepseek-media-gallery |
路由前缀 |
dshHome |
"" |
留空则用 DSH_HOME |
generatedDir / dataRoot / downloadDir |
"" |
面板保存值优先 |
浏览器半边在 lib/client.js 顶部用 PREFIX 常量拼请求 URL;若修改 routePrefix,需同步修改该常量。
宿主 API 一览¶
前缀默认为 /deepseek-media-gallery:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | / |
独立调试页 |
| GET | /client.js |
独立页脚本 |
| GET | /api/tasks |
媒体列表 |
| GET | /api/media/:filename |
媒体流(Range) |
| GET | /api/file/:filename |
附件下载兜底 |
| GET | /api/drives |
内置浏览器根(Windows 盘符 / POSIX /) |
| GET | /api/settings |
当前值、默认值、目录状态 |
| POST | /api/settings |
更新路径(空字符串回退默认) |
| POST | /api/download |
复制到下载目录 |
| DELETE | /api/tasks/:id |
删除记录与文件 |
路由挂在 DSH 本地 webserver(默认 127.0.0.1),无额外鉴权;勿将 routePrefix 暴露到公网。
安装与启用¶
资料中的安装说明以 npm 包 + cordis bundle patch 为准,未给出单独的 dsh plugin add … 一行命令,此处不臆造 CLI 字符串。包结构要点如下:
package.json的dsh.bundle.patch指向cordis.patch.yml,将插件插入 profile 层栈。dsh.client声明浏览器半边,exports["./client"]→lib/client.js。- peer 依赖(如
@deepseek-ai/cordis、@deepseek-ai/dsh-host-webserver、各dsh-client-ui-*、react等)从 profile 的node_modules解析。 - Node 引擎:
>=18。
安装或更新 bundle 后,需要重启 DSH host 才会重新加载插件;这与设置页改路径「即时生效」是两层不同机制。
具体从 SkillHub 目录页或 npm 安装到当前 profile 的步骤,以目录页与仓库 README 当时文档为准:https://www.skillhub.cn/plugins/yuanyiHY/deepseek-media-gallery。
典型用法¶
- 启用插件并重启 host 后,在 DSH 侧边栏底部找到媒体画廊入口,打开半透明弹窗。
- 若尚未有生图插件写入
tasks.json,可先在设置里确认或修改generatedDir,指向已有图片/视频目录;保存后刷新列表即可看到扫描结果。 - 点击条目预览;视频可依赖 Range 播放。需要备份时用下载(复制到
downloadDir);确认无用后再删除(不可恢复)。 - 开发调试可起本地预览(仓库 README):
npm test
node test/preview.mjs --port 43199 \
--generated "<图片目录>" --data "<记录目录>"
npm test 跑宿主 60 条 + 浏览器 73 条测试;测试脚本会把 lib/、client/ 复制到 ~/.dsh/profiles/ 下临时目录再执行。
适用场景与注意¶
适合谁:在本机用 DSH 或 MCP 生图、需要集中查看 prompt/模型元数据,又不想占用聊天主区域的开发者。
局限与风险(来自 README「说明与局限」):
- 纯本地;索引依赖
dataRoot下 JSON,无登记时靠目录扫描。 - 插件以当前 DSH 进程权限读写文件;安装前请自行审阅源码与 MIT 许可证。
- 平台:Windows / macOS / Linux 均可用;目录选择器在 Linux 外多走内置浏览器。
- 删除不可撤销;下载为复制,不替代版本管理或云备份。
DSH 社区插件目录(SkillHub)为独立站点,与 DeepSeek / 幻方无官方从属关系;生态理念是「一切皆插件」,本插件是其中面向客户端 UI + 本地媒体管理的一项补充。
结尾¶
DeepSeek Media Gallery 把生图产物管理收进侧边栏弹窗:列表、预览、Range、下载与删除都在本机完成,并和律动主题共享半透明观感。需要细节、Issue 或贡献代码时,见 GitHub 仓库:https://github.com/yuanyiHY/deepseek-media-gallery;插件索引见 SkillHub:https://www.skillhub.cn/plugins/yuanyiHY/deepseek-media-gallery。