🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

旧内核页面兼容 kelai141/dsh-host-web-compat

DeepSeek 客户端
kelai14118 天前有提交已提供中文文档扫描:含敏感能力兼容 / 相关生态

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 安装
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 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
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件读取剪贴板或密钥环境变量
查看扫描证据(共 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。
预览分享卡片长什么样 ↓kelai141/dsh-host-web-compat
分享 · DeepSeek Harness Hub
kelai141/dsh-host-web-compat

dsh 宿主插件——经 webserver 钩子向页面注入旧内核浏览器 polyfill。

回到顶部