Files
dsh_shenxian/dsh-server-docs/04-调整方案/89-对话内文件预览-采纳官方推荐库现成插件.md
T
admin 5ad755116e chore(docs): 文档库并入代码仓(R4 选 a)+ 索引/台账跟进
1) dsh-server-docs/ 从工作区(原 E:\...\aliyun-dsh-server\dsh-server-docs)**整体并入本仓**,
   保留目录名 ⇒ 仓库内 dsh-server-docs/... 的相对引用天然继续有效;旧目录(含其 .git)已归档到
   工作区 _中间产物_待清理/,未随本提交带入。
2) .gitattributes:新增 `dsh-server-docs/** -text` —— 原文档库是 `* -text` + autocrlf=false,
   必须保持纯 LF,否则会被本仓的 CRLF 规则翻掉。
3) 活引用里的绝对路径已全部改到新位置(docs 的 INDEX / README / scripts / skills + 用户级 skills
   + ~/.workbuddy/settings.json 的 hooks);历史档案(04-调整方案/、archive/)按「只增不改」未动。
   ⚠️ hooks 路径改动需「完全重启会话」才生效(配置是会话启动快照)。
4) 交接单/T08:新增 §16「生产整体切换执行记录」(形态 / 落地动作 / **4 个只有真上线才暴露的真 bug** /
   验收证据 / 回滚命令 / 残留项);台账 T08 行 → 已完成并归档;03-路线图 §二 登记 T08 收尾项。
5) 统一称谓:**「本机」只指跑 WorkBuddy 的开发机**,47 / 106 一律写「远程服务器」。
2026-09-15 18:47:13 +08:00

10 KiB
Raw Blame History

89-对话内文件预览——采纳官方推荐库现成插件(2026-09-14 落地)

  • 日期:2026-09-14 | 状态:🔄 进行中(L2 机制级已验证;L5 用户实测待做)
  • 触发:用户原话 ——「这个 univer 太重了,有没有别的方式可以做个插件让用户点击对话中的文件,可以在会话栏旁边的窗口中打开展示」→ 追加「需要查官方推荐库是否有类似插件,是重新开发还是改造」

TL;DR 不重新开发、也不改造 univer —— 官方推荐库里有现成的,且有一个与我们的 dsh 版本精确匹配: @softspark/[email protected](tgz 65 KB = univer 的 1/650)。 它包住官方的 remote.session.openWorkspacePath,接管"对话里点文件"的手势,弹只读预览弹窗;卸载即恢复原生行为。 已导入候选池(兼容预检 level: ok,无需声明信任)→ 在 guest 启用 → 实例重启探活 success; 页面客户端插件 46 → 47,其 inject 4 个全部可满足(避开"静默挂死"老坑)。


背景与动机

  • univer 插件(dsh-univer-office)重:tgz 42 MB、网关进程常驻 ~350 MB、还带原生绑定(glibc 门禁)。
  • 用户要的是轻量替代:点对话里的文件 → 在会话栏旁边的窗口展示。
  • 用户明确要求先查官方推荐库再决定"重新开发还是改造"(对应 dsh-decision-method 的 U2 能扩展就不新建)。

「官方推荐库」是什么(本次查清)

来源 说明
Awesome-DeepSeek-Harness-Plugins(github.com/web-casa/Awesome-DeepSeek-Harness-Plugins) 社区整理的官方索引,数据源 = cordis.run 插件索引,自称 331 个插件(分 5 类:Dev Assistants 78 / Workflow 37 / Themes&UI 90 / Data Integration 8 / Productivity 118)
npm keywords:dsh-plugin 搜索 + 具体包元数据 取真名、版本、dsh 声明、依赖范围、体积
⚠️ cordis.run/data/plugins.json 直连 403(需要浏览器的 UA/上下文)⇒ 走 README 与 npm 两条路

dsh 客户端能力现状(本次实测):

  • 没有官方 viewer/preview 注册点(全客户端包 grep 无 registerViewer 类 API);
  • 但布局里有 details 列(会话栏旁边、可拖宽)与 shell.overlay 浮层;
  • 官方 dsh-client-ui-deliverables 已把「本轮产出文件」渲染成可点击 chips(点击走 chat 视图的 openFile,该 opener 由宿主能力提供、在无桌面宿主的实例里基本是空转);
  • 平台侧已有 GET /api/fs/download?path=(requireAuth + 限定调用者根内 + 大小限制)且跨域放行 (实测 access-control-allow-origin: https://guest.alotbuy.com + allow-credentials: true ⇒ 200、536 KB 真读到)。

方案对比(含"不做")

方案 内容 判定 理由
A 复用现成插件 从官方推荐库挑一个,走既有投放通道 ✅ 采纳 零开发、可回滚(卸载即恢复原生)、体积最小
B 自己写轻量插件 纯客户端 + shell.overlay 右侧抽屉 + 拦截官方 chips 点击 ❌ 否决 需复刻「产出文件」解析逻辑或做 DOM 拦截(耦合官方类名);有现成的就不该造(U2)
C 改造 univer 让它变轻 ❌ 否决 42 MB 与网关常驻是它的架构(协作网关 + 原生绑定),改造=重写
D 改造官方 deliverables / sidebar 直接改官方包 ⛔ 不可 R2 不改官方 dsh 主程序与缓存
不做(保持现状) 用户只能下载后本地打开 ❌ 否决 用户明确的痛点在"会话里看"

候选体检(判据三关,可复用)

闸 1 依赖的官方包存在吗(不存在的包 ⇒ 客户端 fiber 静默挂死)| 闸 2 有没有依赖被平台角色补丁禁用的官方包(dsh-client-ui-settings-models / -settings-plugins / -settings-plugin-inventory / -cordis / dsh-client-hmr / dsh-host-directory-picker-auto)(同上,静默挂死)| 闸 3 peerDependencies 的 @deepseek-ai/* 版本范围是否覆盖我们的 dsh 版本(0.1.2-rc.1)

候选 体积 判定 依据
✅ @softspark/dsh-file-preview v2.0.0 65 KB 采纳 peer 精确锁 0.1.2-rc.1(=本站版本);inject = client-locale / api-remotes / api-session-controller / client-ui-renderer 全在且未被禁;exports["./client"].default 形态(被 dsh 接受);读文件走官方 host Remote seam;patch 自述"包住 remote.session.openWorkspacePath 接管对话文件打开手势,移除即恢复原生"
❌ dsh-file-viewer v0.3.5 5.7 MB 否决 inject 含 @deepseek-ai/dsh-client-runtime(本站不存在) ⇒ 静默挂死
❌ @deepseek-ai/dsh-client-ui-sidebar-documentpreview 6.8 MB 否决 面向 0.1.5 系(依赖 dsh-client-ui-sidebar-right,本站只有 -ui-sidebar)⇒ 版本不匹配;且 R1 不升 dsh
❌ dsh-file-review v0.8.1 1.5 MB 否决 inject 含 ui-settings-plugins(被平台角色补丁禁) ⇒ 静默挂死
❌ dsh-at-file / @linxin666/dsh-client-ui-aionui-panel — 否决 同样注入不存在的 dsh-client-runtime
❌ dsh-local-filetree / dsh-split-panes — 不可得 npm 无此名(README 未给包名)⇒ 需再溯源
⏸ dsh-better-sidebar + @huanlin/…-office 14 MB + 22 MB 备选 功能最强(VSCode 式右栏 + Office 预览),但合计 ~36 MB、30 依赖,且依赖 dsh-client-ui-sidebar-right(本站无)⇒ 与"轻量"诉求相悖

实现

  1. curl 取 tgz(https://registry.npmjs.org/@softspark/dsh-file-preview/-/dsh-file-preview-2.0.0.tgz,65 247 B)→ scp 到服务器;
  2. admin POST /api/plugins/business(base64 上传 + 安全/兼容预检)⇒ {"ok":true, "version":"2.0.0", "compat":{"level":"ok","findings":[],"platformPkgs":223}, "trustedOverride":false} —— 预检全过,未使用 trust override ✓(warning 有 vm-eval(打包产物里的动态求值)与 network-egress(README 链接),非阻塞);
  3. POST /api/plugins/mine/apply(guest 启用)⇒ 任务 success / 完成(平台自动重启实例 + 探活);
  4. 实装路径:…/profiles/web/node_modules/@softspark/dsh-file-preview ✓。

验证记录

级别 手段 结果
L2 机制 实装存在性 ✅ node_modules/@softspark/dsh-file-preview
L2 机制 实例页面 __DSH_BOOT__ 清单 ✅ 客户端插件 46 → 47;@softspark/dsh-file-preview 行 inject 4 个 差集为空(无可满足性问题)
L2 机制 平台侧预检 ✅ compat.level = ok(判据 A/B 均过)
L5 用户实测 硬刷新后点击对话里的文件 ⏳ 待用户确认(本机无 Chromium,渲染类只能到此)

事故 / 踩坑记录

  • cordis.run/data/plugins.json 直连 403 ⇒ 官方索引要走 README / npm 两条替代路径。
  • npm 包名不等于清单里的短名:dsh-local-filetree / dsh-split-panes 在 npm 无此名(dsh-local-filetree 疑似本地/未发布)。
  • 本机 shell 丢 PATH:rm/cat 变 shim 报错、curl "$(cat f)" 空参数 ⇒ 每次先 export PortableGit 的 usr/bin+mingw64/bin。
  • Windows python 与 git-bash 的 /tmp 不是同一目录 ⇒ 两边传文件要统一用 D:/... 或在同一侧读写。

回滚 / 注意

  • 回滚 = 在功能管理里停用该插件(mine/apply 传 enabled:false)⇒ 平台 pnpm remove + 重启;卸载即恢复原生文件打开行为(patch 自述)。
  • 与 univer 并存无冲突(两者入口不同:univer 管 .univer 的协作预览,本插件管"对话里的文件"只读预览)。
  • ⚠️ 第三方插件升级前仍要过三关(见上)——尤其别让它新版本引入 dsh-client-runtime 之类不存在的包。
  • 候选池里新增了 @softspark/[email protected](id 即包名)。

追加(2026-09-14 14:xx · 能力边界实测 + 三条后续建议的逐条处置)

触发:用户「按照你的建议处理」。

一、该插件的能力边界(读包内 lib/client.js 的分派表实测)

类型 支持 渲染方式
文本类(md markdown txt log json yaml yml csv js ts tsx jsx py sh sql html css xml) ✅ kind: text / html(sanitize 后渲染)
图片(png jpg jpeg gif webp svg) ✅ kind: image / svg(base64 内联)
PDF ✅ kind: pdf
xlsx / docx / pptx / .univer ❌ 命中 unsupported(有兜底提示);另有 「too large」大小上限(阈值写在代码里,未命名常量)
  • host 半边(host.js 15 KB)职责 = 会话授权 + 只读工作区文件(workspace / path.resolve / base64)⇒ 与平台 fs-guard 同思路,权限收窄 ✓。

二、三条建议的处置

建议 处置 理由
① L5(用户硬刷新后点对话里的文件) ⏳ 归用户 本机无 Chromium,渲染类只能到此(dsh-decision-method §4.3 L5 口径)
② Office 预览:装 36 MB 组合 或 让 AI 出 HTML 两条都不做 —— 改走已有能力 用户早上问的"xlsx 能不能在会话里看",答案已从「不能」变成「可以」:univer_import 自 0.2.28(本日 §八 接通 glibc 2.35)起可用 ⇒ 导进 .univer 即在线看;要轻量则让 AI 出 csv/html。无需再装任何东西
③ 停用 univer 省内存(我上一条的💡建议) ❌ 我自己否决(记录在案) 它承载用户明说的核心用法 ——「AI 生成 md/doc/excel + Univer 在线看」;而"太重"的痛点已由本插件覆盖,且 univer 网关是按需启动 + 空闲自停(常驻成本主要就是 42 MB 磁盘)。⇒ 要停的前置动作 = 先把 office-file-generation 技能迁出 univer(改由独立载体承载),之后才可安全停用;该迁移等用户明确说"停"再做

📌 两者定位互补,并存:本插件管「对话里任意文件 → 只读预览」(文本/图片/PDF);univer 管「Office 双向 + .univer 协作预览/编辑」。