浏览器打开 haoqiya138-source/dsh-plugin-open-in-browser
DeepSeek Harness把侧边栏文件交给系统默认浏览器打开,绕开预览限制
30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/22 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add haoqiya138-source/dsh-plugin-open-in-browser该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · vision
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 13 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件
查看扫描证据(共 4 处,展示前 4 条)
- 读取本地文件dist/index.js:159
realpath: (candidate) => realpath(candidate), - 执行外部命令来自配置/变量dist/browser.js:184
const child = spawn(plan.command, [...plan.args], { - 执行外部命令来自配置/变量dist/browser.js:243
execFile(command, [...args], { timeout: timeoutMs, windowsHide: true, maxBuffer: 1024 * 1024 }, (error, stdout) => { - 读取本地文件dist/browser.js:251
return (await stat(path)).isFile();
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
在系统默认浏览器中打开任意 DSH 侧边栏文件,包括内置预览打不开的 HTML、PDF 和图片,从标签页右键菜单一键即可。
README
由 DeepSeek 最新模型翻译生成dsh-plugin-open-in-browser
一个社区 DSH 插件,把侧边栏里的文件交给系统默认浏览器打开,而不是在应用内预览。
一个插件里带两个入口:
| 位置 | 显示在哪里 | 需要 Host 提供什么 |
| sidebar.right.tab.document.unpreviewable | 「无法预览此文件」空状态 | 文件的 Host 路径(absolutePath) |
| sidebar.right.tab.menu.item | 侧边栏标签页 chip 的右键菜单 | 只要标签页的 contentId(dsh-resource://file/session/…) |
这里刻意没有 sidebar.right.tab.document.actions 这个位置。预览渲染文件时,标题栏已经带着预览自己的控件,再塞一个「在浏览器中打开」按钮毫无收益;标签页 chip 的菜单右键一下就到,而且对每个标签页都有效。也正是这个菜单位置,让插件对预览失败的标签页同样有用:内置预览只有在 Host 元数据读取成功后才会渲染文档位置,所以一个显示错误的标签页(比如第三方预览器返回 HTTP 405)没有 absolutePath。标签页菜单仍然持有该标签页的资源地址,足够用来解析、校验并打开文件。
展开完整文档(README 剩余 1 节)
dsh-plugin-open-in-browser
一个社区 DSH 插件,把侧边栏里的文件交给系统默认浏览器打开,而不是在应用内预览。
一个插件里带两个入口:
| 位置 | 显示在哪里 | 需要 Host 提供什么 |
| sidebar.right.tab.document.unpreviewable | 「无法预览此文件」空状态 | 文件的 Host 路径(absolutePath) |
| sidebar.right.tab.menu.item | 侧边栏标签页 chip 的右键菜单 | 只要标签页的 contentId(dsh-resource://file/session/…) |
这里刻意没有 sidebar.right.tab.document.actions 这个位置。预览渲染文件时,标题栏已经带着预览自己的控件,再塞一个「在浏览器中打开」按钮毫无收益;标签页 chip 的菜单右键一下就到,而且对每个标签页都有效。也正是这个菜单位置,让插件对预览失败的标签页同样有用:内置预览只有在 Host 元数据读取成功后才会渲染文档位置,所以一个显示错误的标签页(比如第三方预览器返回 HTTP 405)没有 absolutePath。标签页菜单仍然持有该标签页的资源地址,足够用来解析、校验并打开文件。
安装
包内已带预构建产物(dist/),安装不需要构建步骤,也没有运行时依赖。
从 npm 安装 —— 已发布为 dsh-plugin-open-in-browser:
1. 打开 DSH → 插件 → 添加插件。
2. 输入包名 dsh-plugin-open-in-browser。
3. 完全退出并重新打开 DSH,让新的 Host 部分和客户端产物加载进来。
用插件工具走同一个目标也可以:
plugin_manager action=install_bundle target=dsh-plugin-open-in-browser
从本地检出或 GitHub 克隆安装(克隆里已经包含 dist/):
plugin_manager action=install_bundle target=<absolute path to the checkout>
要求:DSH 桌面应用(Host 必须能启动原生应用);只有从源码构建时才需要 Node ≥ 20。远程/SSH 部署没有桌面浏览器可启动,此时控件会如实报告,而不是静默失败。
任何安装、更新或重新构建之后,都要完全退出并重新打开 DSH:客户端 bundle 会被模块加载器缓存。
为什么
内置预览在沙箱化的 iframe(srcDoc/blob)里渲染 HTML。页面一旦依赖 fetch、模块、绝对路径、Service Worker 或真实源,就会显示空白;预览完全无法渲染的文件则显示空状态。最快的绕行办法是交给操作系统:把文件交给默认浏览器,相对资源和依赖源的 API 都能正常解析。
打开流程
浏览器端向本插件 Host 端注册的一个确切 Host 路由发请求:
POST /dsh-plugin-open-in-browser/open
content-type: application/json
{ "path": "C:\\Users\\me\\project\\preview.html" }
{ "address": "dsh-resource://file/session/<sessionId>/pages/preview.html" }
address 是标签页菜单能产出的形式:Host 解析会话的工作区根目录(sessions.get(sessionId).header.cwd),拼接相对路径,再校验结果(见下文)。回复为 { ok: true, mode: "browser" | "association", path };失败为 { ok: false, code },状态码 4xx/5xx。
随后 Host 端解析用户实际的默认浏览器,不依赖操作系统文件关联:
1. HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https|http\UserChoice
→ ProgId → HKCR\<ProgId>\shell\open\command → 可执行文件;
2. 常见安装路径(Chrome、Edge、Brave、Firefox、Vivaldi、Opera);
3. 兜底:操作系统关联(Windows 上 explorer.exe <file-uri>,macOS 上 open,Linux 上 xdg-open)。
这对图片、PDF 和其他可预览文件很关键:随附的 session.openWorkspacePath Remote 走操作系统关联(Windows 上 .png 会打开「照片」应用),而本插件承诺的是浏览器。如果 Host 路由不可用(Host 端版本较旧、部署时未包含),浏览器端降级到该 Remote,控件仍能发挥作用。
Remote 请求 schema 为 { path, action?: 'reveal', application?: string }。
没有 intent 字段——省略 action/application 就是「用默认应用打开」。
与 DSH 随附 open-in-app 的关系
DSH 已随附 @deepseek-ai/dsh-host-open-in-app + @deepseek-ai/dsh-client-ui-open-in-app,它们注册文档预览席位(…document.actions 和 …document.unpreviewable),并提供「Open in app」菜单(编辑器、Git GUI、终端)。本插件不是替代品:它是一条单一用途的快捷方式,只做「用浏览器打开」,也覆盖那个插件的预览无法渲染的文件,另外还加了标签页芯片菜单。
目录结构
src/security.ts path-safety layer: absolute-path check, traversal/UNC/device
rejection, extension whitelist, workspace containment, symlink
escape detection via an injected realpath, and the
dsh-resource://file/… address parser src/browser.ts Host-side default-browser resolver: registry UserChoice → ProgId → 命令行、常见安装路径、带监视窗口的分离式启动 src/index.ts Host 部分:注册唯一路由,解析地址 → 工作区路径,校验,启动 src/client.ts 浏览器部分:两个插槽注册 + 路由/Remote 适配器 locale/en.json meta.title / meta.description locale/zh.json 同上,中文版 cordis.patch.yml Loader 插入行 scripts/.mjs 由 tsc 驱动的构建(不用打包器);客户端构建把编译后的模块包进 DSH 模块加载器工厂 tests/.test.mjs node:test 测试套件:安全层、浏览器解析器、Host 路由契约、构建后的客户端包
为什么没有 src/main/、src/preload/、src/renderer/?
这些是 Electron 应用的层次。DSH 插件是 Cordis 包,不是 Electron 应用:它永远碰不到 Electron 主进程,DSH 也不向插件暴露 preload/contextBridge 桥。对应的拆分是:
| Electron 应用层 | 本插件 |
| 主进程(Node) | src/index.ts + src/browser.ts —— Host 部分,运行在 DSH 的 Host 进程内 |
| preload / contextBridge | Host 路由 POST /dsh-plugin-open-in-browser/open(以 DSH 的 session.openWorkspacePath Remote 作为兜底) |
| 渲染进程注入 | src/client.ts —— 浏览器产物,通过 window.__ModuleLoader__ 加载 |
security.ts 故意由两部分共用:浏览器部分在调用前校验,Host 在启动前再校验一次。把它拆成「主进程」副本,两道关卡就会逐渐走偏。
构建
需要 Node ≥ 20(已在 Node 24 上验证),无运行时依赖。
npm install # typescript + @types/node only
npm run build # dist/index.js + dist/browser.js (host) + dist/client.js (browser)
npm run typecheck # host and client configs
npm test # builds, then runs all four node:test suites
DSH 只需要 npm run build 这一步:包的 files 和 exports 都指向 dist/。
本地测试步骤
1. 构建并跑单元测试
npm run build
npm test
预期:dist/index.js、dist/browser.js、dist/client.js 都存在;所有 node:test 用例通过(目前 78 个)。测试套件覆盖纯安全层与地址语法、Windows 注册表/路径解析与启动计划排序(注入进程事实)、Host 路由的 HTTP 契约(405/415/403/400 各路径与 Origin 围栏),以及在裸 VM 中执行构建后的客户端包(加载器 id、两个注册、路由优先且 Remote 兜底、拒绝路径)。
2. 安装到当前配置档(从包的绝对目录执行):
plugin_manager action=install_bundle target=E:\Ai\DSHprojects\plug-in\open-in-browser
已经装过此包的配置档,必须重启后新的产物已加载。当配置档链接工作区目录时(本地开发环境就是这样),重新构建就够了;只需重启。
3. 在 GUI 中做冒烟测试
- 打开会话,打开 Files 标签页,点击预览能渲染的文件(.html 页面、.png)→ 预览头部没有额外的浏览器按钮;文件就该在原地阅读。
- 右键点击标签页芯片,选择 Open in browser → 标签页的文件会交给系统默认浏览器(不是操作系统文件关联),适用于白名单上的任何文件类型——图片会在浏览器中打开,而不是在「照片」中打开。
- 点击预览失败的标签页(例如第三方预览器显示 HTTP 405)→ 同一个右键菜单项会解析标签页的资源地址并打开文件。
- 在远程/SSH 部署中(canOpenWorkspacePath() 为 false 且没有 Host 路由),文档控件保持隐藏,菜单项会提示 Host 路由不可用。
- 拒绝会以简短的行内文本呈现,绝不会导致崩溃:含 .. 的路径、不在白名单的扩展名、外部 Origin、Host 无法映射的路径,都会报告出来。
4. 卸载
plugin_manager action=set_plugin target=dsh-plugin-open-in-browser enabled=false
安全说明
- 路由有三层防护:Host Web 服务器自身的认证、同源 Origin 检查(dsh-app://app 或提供服务的 Host;缺少 Origin 视为本地客户端,如 curl)、以及有界的 JSON 请求体(16 KiB,要求 content-type: application/json)。它只能打开通过校验的文件路径,绝不接受命令。
- 浏览器端在调用前先校验:路径必须是绝对路径,不得包含 ./..、UNC 或设备命名空间路径、控制字符或保留设备名,扩展名必须在浏览器安全白名单上。
- 基于地址的请求会针对会话实时的 header.cwd 解析,然后通过同一道关卡和注入的 realpath;离开工作区的符号链接会被拒绝(symlink-escape),未知会话也会被拒绝(session-unavailable),而不是猜测一个根目录。
- 只有知道工作区根目录时,才能做针对根目录的围栏;在文档席位,槽位只提供绝对路径,因此 Remote(以及预览本身)的 Host 映射检查在那里仍是权威防线。
限制
- 没有文件树右键菜单。槽位目录不暴露文件节点上下文菜单槽位(只有 sidebar.right.tab.files.actions,一个接收所显示工作区目录的工具栏),而随附的 Files 树本身没有上下文菜单。要加一个,就得随附一棵替换的文件树(dsh-better-sidebar 就是这么做的)。
- 空状态按钮只在预览已有该文件元数据后才出现(absolutePath);预览失败的标签页由标签菜单的座位兜底。
- 预览头部按设计不带任何按钮(见上文);想加回来,就在 src/client.ts 里重新注册 sidebar.right.tab.document.actions。
- 重新构建后需要重启配置档,因为模块加载器会缓存客户端产物。
- 白名单刻意做得很小;想在外置程序里打开更多类型,就扩展 DEFAULT_ALLOWED_EXTENSIONS。
安全
插件新增了启动进程的能力,所以附带一份成文的威胁模型:唯一的 Host 路由、它周围的围栏、路径闸门,以及明确不在范围内的部分。见 docs/SECURITY.md。
报告漏洞请用 GitHub 的私密安全公告表单(Security 标签页),不要开公开 issue。
发布
仓库:<https://github.com/haoqiya138-source/dsh-plugin-open-in-browser>。
包以 dsh-plugin-open-in-browser 的名字发布到 npm。
0.2.0(2026-10-21)是首个公开发布版本。
发布清单(Trusted Publishing 已配置,见下文):
1. npm test(重新构建 dist/ 并跑全部 78 个用例)和 npm run typecheck。
2. npm version <patch|minor|major> —— 升 package.json 和 package-lock.json 的版本号,提交,并创建 v<version> 标签。
3. git push origin main --follow-tags —— 标签会触发 .github/workflows/release.yml,它跑类型检查和测试,通过 Trusted Publishing(OIDC)带 provenance 发布到 npm,并创建 GitHub release。本地不需要登录 npm。
首个公开发布(0.2.0)是手动走的 npm 交互式 2FA 流程:npm publish --access public 会打印一个 https://www.npmjs.com/auth/cli/... URL,得在浏览器里批准。这条路仍可作为兜底,但对处于 auth-and-writes 2FA 模式的账号,光有访问 token 会返回 EOTP,所以 CI 不用 token。
Trusted publishing(已配置)
在 npmjs.com 上,包配了 Trusted publisher:GitHub Actions,仓库 haoqiya138-source/dsh-plugin-open-in-browser,工作流 release.yml,环境留空,权限 npm publish / npm stage publish / npm dist-tag。
release.yml 用 runner 的 OIDC token(id-token: write)认证,并保留 --provenance;仓库里不存 NPM_TOKEN secret。v0.2.1 这次发布就是 npm 在配置发布者之后要求的验证发布。
CI(.github/workflows/ci.yml)在 Linux 和 Windows 上、Node 20 和 22 下跑类型检查和全部 78 个测试用例。发布工作流在发布前会重新构建 dist/,所以 tarball 始终与打标签的源码一致。
许可
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
haoqiya138-source/dsh-plugin-open-in-browser
把侧边栏文件交给系统默认浏览器打开,绕开预览限制
相关插件 · 视觉能力
智能体工作台Devin-AXIS/iPolloWork
企业级、本地优先的智能体工作台,面向个人和智能体团队——一个工作区,容纳多个智能体引擎;一套统一体系,管理插件和技能;支…
★ 7,364已汉化DSH
72
开源设计工作台nexu-io/open-design
OpenDesign:首个协作式 AI 设计智能体工作区
★ 105,709已汉化DSH
71.8
GPT 图像提示词库freestylefly/awesome-gpt-image-2
Prompt as Code | GPT Image 2 / 2.5 提示词与案例库,530+ 个案例、20+…
★ 34,534已汉化DSH
71.5
多智能体编码工作区spacering-net/codeg
多智能体协作的 AI 编程工作区:汇总 Claude Code、Codex、OpenCode、Pi、Grok Build 等来源的会话。支持桌面应用、自托管服务器或 Docker。
★ 4,319已汉化DSH
71.5
AI 用量桌面小部件Javis603/token-monitor
EN | 简 | 繁 | KO | JA | PT
★ 3,533已汉化DSH
71.1
架构图生成器tt-a1i/archify
把你想理解、规划或分享的事,变成可以互动的可视化作品。
★ 93,105已汉化DSH
71.1
这是你的仓库?认领条目