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 一律写「远程服务器」。
10 KiB
10 KiB
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,其inject4 个全部可满足(避开"静默挂死"老坑)。
背景与动机
- 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)(同上,静默挂死)| 闸 3peerDependencies的@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(本站无)⇒ 与"轻量"诉求相悖 |
实现
curl取 tgz(https://registry.npmjs.org/@softspark/dsh-file-preview/-/dsh-file-preview-2.0.0.tgz,65 247 B)→ scp 到服务器;- 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 链接),非阻塞); POST /api/plugins/mine/apply(guest 启用)⇒ 任务success / 完成(平台自动重启实例 + 探活);- 实装路径:
…/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 内联) |
| ✅ | kind: pdf |
|
xlsx / docx / pptx / .univer |
❌ | 命中 unsupported(有兜底提示);另有 「too large」大小上限(阈值写在代码里,未命名常量) |
- host 半边(
host.js15 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协作预览/编辑」。