dsh-index-tap-bridge:让 tapIndex 插件在官方 DSH 桌面版生效

前言

DeepSeek Harness(DSH)里不少第三方插件通过 webServer.tapIndex(html => html) 向页面注入 <script>、<style> 等标记。在 dsh web 或 Host 自行渲染 index.html 的路径上,这套机制工作正常;官方桌面版却加载内置 SPA(dsh-app://app/),只消费 Host 经 IPC 上报的结构化注入行(webserver/index-inject),不会执行 renderIndex() 里的 tapIndex 变换。结果是插件在列表里显示已启用、加载也无报错,但注入的资源从未出现在页面里。下面介绍社区插件 dsh-index-tap-bridge 如何在不改目标插件源码的前提下,把 tapIndex 桥接到桌面外壳能识别的注入通道。

这是什么

dsh-index-tap-bridge(GitHub:VCPr0j3k7/dsh-index-tap-bridge)由维护者 VCPr0j3k7 发布,分类为客户端插件,当前版本 0.1.0,许可证 MIT。它以独立 bundle 形式装入 DSH profile,在 webserver/index-inject 事件触发时读取已注册的 indexTaps,把变换产生的新增 HTML 标记翻译成结构化注入行,再 push 进注入表,使依赖 tapIndex 的第三方插件在官方 Harness 桌面版中同样生效。

问题背景与两条注入通道

@deepseek-ai/dsh-host-webserver 向 index.html 提供两条通道:

通道 主要使用者 官方桌面版
结构化注入行(webserver/index-inject 事件) 官方插件(如 dsh-client-modules) 生效
索引变换(tapIndex(html => html)) 大量第三方插件 不生效

桌面版不渲染 Host 的 index.html:窗口加载外壳内置 SPA;Host 启动后仅上报一次 collectIndexInjections() 的结果。tapIndex 只在 renderIndex() 内执行,而桌面版不会走该路径。官方源码将 applyIndexTaps() 描述为 “the escape hatch for markup no IndexInjection row expresses”——桥接插件正是把 escape hatch 里的产出转写为 IndexInjection 行能表达的形式。

核心功能

  1. 透明兼容:目标插件仍调用 tapIndex(),变换保留在 indexTaps 中;浏览器与 dsh web 经 renderIndex() 的行为不变。
  2. 翻译注入:在桌面外壳场景下,对每个 tap 作用于最小骨架 HTML,提取新增标记,按规则映射为 script-src、script、style、html 等 kind,并按 kind 与载荷去重。
  3. 条件启用:默认根据 process.argv 是否包含 dsh-desktop-host 判断是否启用桥接,避免在自包含外壳(仍走 renderIndex())上重复注入。
  4. Bundle 集成:通过 dsh.bundle.patch(cordis.patch.yml)挂入 profile;dsh plugin 安装后会运行 reconcilePlugins() 自动维护 dsh.profile.bundles。

翻译规则摘要(完整表见仓库 README):

原始标记 翻译结果
<script src="U"> { kind: 'script-src', src: 'U' }
<script>内联</script> { kind: 'script', text, placement }
<style>…</style> { kind: 'style', text }
<link>、div 等 { kind: 'html', placement, html }

桌面前端对 html 行使用 insertAdjacentHTML(),经此插入的 <script> 不会执行,因此 <script> 必须单独映射,不能由 html 行承载。

环境要求

项 要求
Node.js ^22.19.0 \|\| >=24
DeepSeek Harness 已在官方桌面版 0.1.7-rc.2 上验证

安装与启用

插件以 DSH profile 为单位安装。Web 侧常用 web profile(DSH 首次运行自动创建);官方 Harness 桌面版使用 desktop profile。

装入 web profile:

dsh plugin --profile web add github:VCPr0j3k7/dsh-index-tap-bridge

桌面版:

dsh plugin --profile desktop add github:VCPr0j3k7/dsh-index-tap-bridge

无需手改 dsh.profile.bundles。确认已登记:

dsh --profile web --dump-config

输出中应包含 index-tap-bridge。安装完成后需重启目标 harness;桌面版在启动时加载插件,运行中的实例不会热更新。

排障时可覆盖启用逻辑:

环境变量 取值 作用
DSH_INDEX_TAP_BRIDGE on 强制启用
DSH_INDEX_TAP_BRIDGE off 强制关闭

卸载

dsh plugin --profile desktop rm dsh-index-tap-bridge

reconcilePlugins() 会同步清理 bundle 条目;若有残留可手动删除对应项。卸载后同样需要重启 harness。

典型验证方式

仓库提供不依赖 DSH 运行时的逻辑自检:

npm test

test/check.mjs 覆盖翻译分支、空载荷丢弃、顺序保持、不可翻译标记上报及桌面外壳判定;README 记载当前 23/23 通过。

端到端:安装并重启桌面版后,原先不显示挂件的 tapIndex 插件应开始工作;若插件有日志,可看到其注入资源被请求。

适用场景与注意

适合谁:已在 DSH 中启用依赖 tapIndex 的第三方插件,且主要使用官方桌面外壳的开发者。

权限与安全:插件随当前 DSH 进程以相同权限运行。安装前请阅读 GitHub 仓库 源码与 MIT 许可证,自行评估是否纳入 profile。

已知限制(摘自 README):

  • 仅翻译新增标记;若 tap 修改已有 DOM 片段,无法翻译,会通过 console.warn 列出。
  • 官方若变更 indexTaps 字段名,桥接可能静默失效(有 Array.isArray 守卫)。
  • <canvas> 等需「替换节点」语义的标记不会强行译为 html 行。
  • 桌面版插件库开关可能重写 dsh.profile.bundles(sanitizeProfile);桥接突然失效时,先检查 bundle 中是否仍有该条目。

DSH 生态强调「一切皆插件」;社区目录 SkillHub 插件页 为独立站点,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-index-tap-bridge 解决的是官方桌面版与 tapIndex 注入路径脱节的问题:在 Host 仍注册 tap 的前提下,于 index-inject 时刻把新增标记翻译成外壳能应用的注入行。若你的插件列表正常但页面脚本从未加载,可先为 desktop profile 安装本桥接并重启,再对照 README 中的限制排查未翻译的标记。

  • 目录页:https://www.skillhub.cn/plugins/VCPr0j3k7/dsh-index-tap-bridge
  • GitHub:https://github.com/VCPr0j3k7/dsh-index-tap-bridge
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜