@deepseek-ai/dsh-client-ui-sidebar-browser
v0.1.6-alpha.2
Published
Sandboxed Web browser tabs for the right Sidebar
Readme
description: "右侧 Sidebar 浏览器 tab:在 sandbox 中访问 HTTP(S) 页面,包括 loopback 服务。" kind: "package-reference"
@deepseek-ai/dsh-client-ui-sidebar-browser
English | 中文
概述
在独立的右侧 Sidebar tab 中浏览 HTTP(S) 页面,包括 loopback 服务。当前 Web 与 Desktop 都使用 iframe 和应用维护的 history。本包不会向被访问内容注入 Electron 或 Node 能力。
目录
使用本包
随附的 Web 与 Desktop composition 已挂载本包。可以从右侧 Sidebar guide 打开 浏览器、输入 HTTP(S) URL,或点击 Assistant Markdown 中的 HTTP(S) 链接。不带 scheme 的主机名会补全为 HTTPS。公共目标与 loopback 目标使用相同的默认 sandbox。每次 guide 操作或消息链接操作都会创建一个新的 Browser tab。
何时选择
当 Web 页面需要保留在当前 Session 旁时,选择 Browser。本地文件使用 Document Preview;站点拒绝 iframe 嵌入或需要本包不授予的浏览器 capability 时,使用明确的外部浏览器操作。
最小配置
本包没有配置字段。自定义 Web composition 挂载 Host companion;随后 Client loader 会发现 package manifest 声明的浏览器入口:
- id: ui-sidebar-browser
name: '@deepseek-ai/dsh-client-ui-sidebar-browser'Client 插件可以调用 ctx.sidebarRight.openTab('browser', { params: { url } }) 打开 tab。可选 URL 会在导航前接受与地址栏输入相同的校验。
工具栏提供后退、前进、刷新、前往、在系统浏览器中打开,以及最右侧的逐 tab sandbox 开关。关闭 sandbox 是临时选择,并会显示警告。外部打开接受已知的 HTTP(S) 目标。tab 标题显示 Web 主机名。
了解实现
协议策略
地址解析器接受 HTTP 与 HTTPS,包括 loopback 目标。file: URL、脚本/data/blob 输入、内嵌凭据、DSH 应用自身 origin 和畸形地址会被拒绝。本地文件由 Document Preview 负责渲染。
Iframe 载体
Web 与 Desktop 默认使用 sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"。frame 没有直接的下载或顶层导航 flag。popup 会脱离 sandbox;在 Web 中,逃逸的 popup 会保留 opener,并可以导航顶层应用。被访问的 origin 可以使用自身 Cookie 与 Web storage,但跨域目标无法读取 DSH DOM、storage 或 API 响应。iframe 不发送 referrer,也不添加包自有的 Permissions Policy,因此浏览器默认策略与用户授权生效。toolbar 可以为当前 tab occurrence 移除 sandbox;该选择不持久化。未受 sandbox 约束的页面可以按浏览器 activation 规则导航顶层应用,并使用下载、模态对话框和输入锁定。本包不代理或探测远程页面。
Web 记录 toolbar 提交和 typed tab 打开。导航状态机把每个受控 revision 的第一次 iframe load 视为已知,把后续 load 视为页面已经变化到不可读取 URL 的证据。进入 unknown 状态后,地址会显示标记,后退、前进和外部打开会禁用,刷新则返回最后一个受控 URL。body 重挂载时会重新加载应用最后已知的 URL,并且仅在尚无受控目标时使用可选初始 URL。不产生 iframe load 的 History API 与 fragment 变化仍不可见。iframe error event 会显示临时加载失败 notice,直到下一个受控加载,但不会改变 URL history。
Controller
每个 tab 获得一个 BrowserController class。它的公开命令只有 loadUrl、goBack、goForward 与 reload;地址校验与 history 变更均由该对象封装。它的 BrowserNavigation class 拥有可序列化的 URL 状态机。BrowserFrame 接口负责临时 sandbox 与 document 状态以及载体操作,IframeImpl 为当前 iframe 载体实现该接口。Slot injection 通过 useBrowserFrame 提供按 key 索引的 frame 状态,并提供普通 callback,因此 React body 不接收 controller 或 observable source;它只保留可编辑草稿与 iframe DOM。
Controller 接口不依赖 iframe API。未来的 ElectronWebViewImpl 可以实现 BrowserFrame,并持有 <webview> attachment 与 target identity。该延期载体记录在同一份 Sidebar Browser 决策中,当前不注册也不测试。
延伸阅读
- 右侧 Sidebar——tab composition、导航与生命周期。
- Document Preview——本地源码、Markdown、图片、HTML 与 PDF 渲染。
- Sidebar Browser 决策——当前 iframe 行为、controller 所有权与延期 Electron 载体。
模型体验
无。Browser tab 是用户侧呈现状态,不注册工具、prompt section 或 Session event。
KV Cache 影响
无;浏览内容不进入模型请求。
已知限制与延期工作
隔离策略有意放弃部分浏览器兼容性:
- 很多站点拒绝 iframe 嵌入,或需要默认 sandbox 不向 frame 授予的下载与顶层导航。HTTPS 应用还可能按 mixed-content 策略阻止公共 HTTP 页面。关闭 sandbox 会用自身限制换取兼容性,但不会绕过 mixed-content 或 private-network 策略。未受 sandbox 约束的 frame 可以按浏览器 activation 规则导航顶层应用,并使用下载、模态对话框和输入锁定。该模式不会按 Browser tab 隔离被访问 origin 的 Cookie,也无法阻止 iframe 内页面自行选择后续 URL。
- 在 Web 中,逃逸出 sandbox 的 popup 会保留 opener,并可以通过该链导航顶层应用。Desktop 会单独处理 popup 创建。
- 后续 iframe load 能表明发生了导航,但无法给出新的跨域 URL。History API 与 fragment 变化可能仍不可见;状态变成 unknown 后,Web 的后退与前进不可用。
- 出于安全原因,浏览器会隐藏很多 iframe 失败:DNS、TLS、mixed-content、CSP 与
X-Frame-Options失败可能触发load,也可能不提供可操作 event,而不是触发error。加载失败 notice 只能作为 best-effort 提示。 - Browser history 会跨 body 重挂载与普通页面刷新保留,但关闭 tab 或卸载
ui-sidebar-right会中止其 occurrence 并删除已存储的 history bucket。 - 本地文件会被拒绝,并继续由 Document Preview 负责。
- 拟议的 Electron
<webview>载体、per-tab Cookie partition、原生 history 和 target-specific CDP 连接尚未实现。
开发备注
无。
运行时不变量: 不发布 companion。BrowserNavigation 是唯一的 URL 状态写入方;store 接收它的 immutable snapshot,controller 与组件的聚焦测试直接覆盖发布与清理。
