dsh 宿主插件——经 webserver 钩子向页面注入旧内核浏览器 polyfill。
38.1/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/16 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/kelai141/dsh-host-web-compat.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 18 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包@dsh-android/dsh-host-web-compat(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 19:57:41
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件读取剪贴板或密钥环境变量
查看扫描证据(共 5 处,展示前 5 条)
- 读取密钥环境变量lib/index.js:1129
const token = process.env.DSH_PICK_TOKEN || ''; - 读取本地文件lib/index.js:1229
return existsSync(rel) ? { abs: rel } : { error: 'not-found', reason: '该绝对路径不存在' } - 读取本地文件lib/index.js:1233
return existsSync(abs) ? { abs } : { error: 'not-found', reason: '家目录下不存在该文件' } - 读取本地文件lib/index.js:1257
if (existsSync(abs)) return { abs, sessionId } - 读取本地文件lib/index.js:1268
try { if (existsSync(abs)) return { abs, guessed: true } } catch { }
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-host-web-compat
DeepSeek Harness × Android 生态 · dsh-mobile-apk(壳 APK)· dsh-shell-termux(shell)· dsh-client-ui-responsive(移动 UI)
DeepSeek Harness 宿主插件:通过 webserver tapIndex 钩子向每个页面注入旧内核浏览器缺失的 polyfill,并接入壳 APK 的目录选择/路径打开桥。
背景
旧内核(如模拟器自带浏览器、旧 WebView)缺少新 API,导致宿主页面功能直接抛错:
- 缺 AbortSignal.any() → 工作区目录选择器的并发 RPC 取消抛错(列表空白);
- 缺 Promise.withResolvers() → 宿主 boot 就绪尾脚本抛错,插件树加载失败;
- 缺全局 Iterator(Chrome 122+)→ 上游 0.1.5 客户端包(documentpreview 等)import 期 Iterator is not defined,整树报「Failed to load plugins」。
本插件在 HTML 层注入幂等 polyfill——无需浏览器侧改动。
快速开始
1. 安装(放入 profile 的 node_modules)。
展开完整文档(README 剩余 1 节)
dsh-host-web-compat
DeepSeek Harness × Android 生态 · dsh-mobile-apk(壳 APK)· dsh-shell-termux(shell)· dsh-client-ui-responsive(移动 UI)
DeepSeek Harness 宿主插件:通过 webserver tapIndex 钩子向每个页面注入旧内核浏览器缺失的 polyfill,并接入壳 APK 的目录选择/路径打开桥。
背景
旧内核(如模拟器自带浏览器、旧 WebView)缺少新 API,导致宿主页面功能直接抛错:
- 缺 AbortSignal.any() → 工作区目录选择器的并发 RPC 取消抛错(列表空白);
- 缺 Promise.withResolvers() → 宿主 boot 就绪尾脚本抛错,插件树加载失败;
- 缺全局 Iterator(Chrome 122+)→ 上游 0.1.5 客户端包(documentpreview 等)import 期 Iterator is not defined,整树报「Failed to load plugins」。
本插件在 HTML 层注入幂等 polyfill——无需浏览器侧改动。
快速开始
1. 安装(放入 profile 的 node_modules)。
2. 挂载(profile 的 cordis.patch.yml):
- insert:
- id: web-compat
name: '@dsh-android/dsh-host-web-compat'
disabled: !!js process.platform !== 'android'
3. 重启服务,旧内核上目录选择器恢复可用。
注入的 polyfill
| API | 条件 | 说明 |
| AbortSignal.any | 缺失时 | Chrome 116+ / Node 20.3+ |
| AbortSignal.timeout | 缺失时 | Chrome 103+ / Node 17.3+ |
| structuredClone | 缺失时 | Chrome 98+ / Node 17+ |
| Object.hasOwn | 缺失时 | Chrome 93+ / Safari 15.4+ |
| Array.prototype.at | 缺失时 | Chrome 92+ |
| String.prototype.replaceAll | 缺失时 | Chrome 85+ |
| crypto.randomUUID | 缺失时 | Chrome 92+,且要求安全上下文 |
| Promise.withResolvers | 缺失时 | Chrome 119+;宿主 boot 就绪尾脚本依赖 |
| 全局 Iterator + iterator helpers | 缺失时 | Chrome 122+(map/filter/take/drop/flatMap/toArray/forEach/some/every/find/reduce + Iterator.from) |
| Object.groupBy / Map.groupBy | 缺失时 | Chrome 117+ |
| Set.prototype 集合方法 | 缺失时 | Chrome 122+(union/intersection/difference/symmetricDifference/isSubsetOf/isSupersetOf/isDisjointFrom) |
| Array.fromAsync | 缺失时 | Chrome 121+ |
幂等:已存在则跳过。全部片段拼成一个 ,因此每个片段必须以完整语句结尾(见「开发约束」)。
其他注入
- 目录选择桥(__dshBridge + /api/android/dir-pick/ 轮询端点,SAF 真实路径回填);
- 打开路径(window.__dshOpenPath:聊天 mention 与工具行路径 → 壳侧系统选择器);0.14 起解析按会话作用域(相对路径对活跃会话 cwd 解析);
- 主题桥(__dshThemeBridge:系统深浅色 → 页面主题变量);
- Agent 工具行文件路径识别;0.14 起按 DOM 事实(不再靠 CSS-Module 类名)识别工具行,点击绝对路径 → 交给壳侧选择器打开;
- 剪贴板回落(2026-10-03):navigator.clipboard.writeText 的全局 wrapper。Android WebView 拒绝异步剪贴板 API (NotAllowedError: Write permission denied,WebView 没有权限弹窗通道),而上游 writeClipboard 的 catch 直接 return false——它只在 API 缺席时才回落 execCommand('copy') ⇒ 代码块/消息/终端各类复制按钮点了既不写入也无反馈。本 wrapper 依次回落 window.androidBridge.copyText(壳侧 ClipboardManager)→ execCommand('copy');三条全失败时给一次人话回执。为什么包在 API 上而不是逐个调用点:复制入口多路(CodeBlock / MessageIconActions / TerminalBlock / HoverCard / user-questions / trajectory / 第三方插件),全部在点击时现取该 API。
- boot 看门狗:40s 卡住诊断,以及壳 APK 按字段位置解析的三条契约行([dsh-boot-stall] 卡住、 [dsh-boot-ready] 真渲染完成、[dsh-boot-failed] 客户端插件树装配失败)——见「启动诊断契约」。
启动诊断契约
看门狗走 console.error 通道。壳 APK 先按行首前缀命中,再按位置读后续字段,因此下面的字段序属于接口本身:
| 行 | 含义 | 前缀之后的字段 |
| [dsh-boot-stall] dsh-boot-diag source=page-stall ... | 40s 未渲染 | pageSideRuntime=<折叠 JSON> detail=<折叠 k=v> |
| [dsh-boot-ready] dsh-boot-diag source=page-ready ... | #root 已渲染且启动页已卸载 | pageSideRuntime=<折叠 JSON> |
| [dsh-boot-failed] dsh-boot-diag source=page-plugin-fail ... | 客户端插件树装配失败 | detail=reason=<首行,200 字符> takenMs=<毫秒> failedCount=<N> rendered=<bool>、failedIds=<逗号分隔或 ->、pageSideRuntime=<折叠 JSON,收尾> |
failedIds 只保留「像 loader entry id」的项(/^[@A-Za-z0-9][@A-Za-z0-9._\/-]$/,长度不超过 120),最多 8 项,无引号无空格;一项都读不出时写 -。它排在 pageSideRuntime 之前:fold 有 2048 字符截断,JSON 在最尾被截断就完全无法解析。
就绪判据是 rendered() && !bootPagePresent()。客户端插件树失败时上游渲染的仍是启动页,#root
照样有子节点,于是旧「只看 rendered()」的判据会把它报成已就绪:壳侧据此停掉 stall 计时,失败被彻底静音。失败行由两个幂等触发点发布——MutationObserver 回调(2s 去抖)与 readyWatch 每一拍
(覆盖「失败页在观察器装上之前就已到终态」的竞态)。pendingBoot() 未改,因此失败页刻意不弹
40s 浮层:它有 [dsh-boot-failed] 这条自己的出口。
0.1.14(2026-10-03)重新入册剪贴板回落:0.13.3(d377abc)把该 wrapper 连同 assets/patched/web-frontend-index.html 一起退役(0.13.7fx-1 正式退役),androidBridge.copyText 桥自此零页面调用点,复制按钮静默失效直到用户报障(dsh-mobile-apk 坑 242)。
0.1.13(2026-09-10,0.13.7fx-1)退役:注入 composer 菜单的「引用本机文件」项(data-dsh-file-pick)与整条 pickFilePath/onFilePicked 桥管线。上游 0.1.5 自带 @ 引用菜单(ui-input-trigger + ui-reference,候选限定在会话工作区内),我们那一项挂在同一个 [role=listbox] 里属于重复入口;按官方语义,@ 只引用工作区文件(详见 issue #150/#144)。
开发约束
片段用 POLYFILLS 数组维护,装配规则写在 lib/index.js 的 POLYFILL_SCRIPT_BODY:
- 每个片段必须以 ; 或 } 结尾。全部片段共用一个 元素,一个片段语法错误会让整个元素被解析器拒绝——页面上的表现是「polyfill 全都没生效」,而抓 HTML 仍能看到片段文本(2026-09-10 实测:Set 方法 IIFE 结尾 })() 直接撞上下一段的 if (,WebView 110 上 Iterator is not defined,排查花了整整一轮)。
- apply() 在装载期对装配结果做 new Function 解析断言,不合格直接抛错(响亮失败优先于静默降级)。
- 垫片要按真实现的结构补:全局 Iterator 必须是构造器且 .prototype === %IteratorPrototype%(pdfjs 等打包代码会用 Iterator.prototype.x 直接打补丁),迭代器包装器必须继承同一原型,否则链式助手断链(见坑 61)。
测试
node scripts/smoke-injections.mjs # 装配 + 逐段解析 + 页面标记断言(无需安装依赖)
node scripts/boot-watchdog.test.mjs # 看门狗行为:pendingBoot / ready / 失败契约行
脚本用桩 cordis 真实装载插件、跑一次 tapIndex 变换,再对服务出去的 HTML 逐段解析——这是唯一能抓住「片段拼接语法错误」的检查(grep 文本会漏)。
License
MIT。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
kelai141/dsh-host-web-compat
dsh 宿主插件——经 webserver 钩子向页面注入旧内核浏览器 polyfill。
相关插件 · UI / 主题
破甲增强版JeffKeeping/dsh-purge-plus
dsh-purge 的非官方分支fork:适配 DeepSeek Harness 0.2.1-rc.2、破甲内核…
★ 387已汉化DeepSeek 客户端
71.9
无代码业务系统平台nocobase/nocobase
NocoBase 是什么
★ 24,804已汉化DSH
71.8
1Panel 服务器面板1Panel-dev/1Panel
全球 250 万+ 自托管用户共同喜爱。
★ 37,344已汉化DSH
71.5
终端编码代理esengine/DeepSeek-Reasonix
· 指南 · ACP · 扩展开发 · 规格 · 官方网站 · Discord · QQ
★ 36,045已汉化DSH
71.2
工作状态行动态ccch1mneyyy/working-activity
作者:chimney@ccch1mneyyy。社区项目,非 DeepSeek 官方项目。
★ 664已汉化DSH
71.2
多模型配置管家farion1231/cc-switch
跨平台桌面一体化助手,支持 Claude Code、Codex、OpenCode、DeepSeek Harness 等工具,唯一官网 ccswitch.io
★ 151,202已汉化DSH
71.1