@qilin-agent/client-ui-sidebar-browser 0.0.0-stage → 3.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 kkutysllb
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
2
+ # section, a hash of its English and Chinese blocks outside code blocks and generated regions.
3
+ # After editing either side, bring the other along and re-record with:
4
+ # pnpm run verify-translation-pairing --write packages/client/ui-sidebar-browser/README.md
5
+ /:
6
+ en: aceaa4f1e64f54b1
7
+ zh: 0f43a543e01f0778
8
+ /qilin-client-ui-sidebar-browser:
9
+ en: 9f9263df01d584e4
10
+ zh: 9caebcee40fef885
11
+ /qilin-client-ui-sidebar-browser/summary:
12
+ en: 445ca89282df57ac
13
+ zh: dfe6239547e3c4a2
14
+ /qilin-client-ui-sidebar-browser/table-of-contents:
15
+ en: d152484eb41ac6b4
16
+ zh: de4a2a92773d135e
17
+ /qilin-client-ui-sidebar-browser/use-this-package:
18
+ en: eb290f26cfe96a18
19
+ zh: eb80fd35440fd3cb
20
+ /qilin-client-ui-sidebar-browser/use-this-package/when-to-choose-it:
21
+ en: 638bc5f88739898b
22
+ zh: 9cce8ed4a99187ca
23
+ /qilin-client-ui-sidebar-browser/use-this-package/minimal-configuration:
24
+ en: aaab23ff2bca2fd0
25
+ zh: 7760a3a406dd2733
26
+ /qilin-client-ui-sidebar-browser/understand-the-implementation:
27
+ en: 42b15ac6321706aa
28
+ zh: e15901d8462ec7c7
29
+ /qilin-client-ui-sidebar-browser/understand-the-implementation/protocol-policy:
30
+ en: ae4bf6dcb1d9aca9
31
+ zh: a52fd529b175df78
32
+ /qilin-client-ui-sidebar-browser/understand-the-implementation/iframe-carrier:
33
+ en: 89a93904a4cb37f8
34
+ zh: fbbd9bd7ff27184a
35
+ /qilin-client-ui-sidebar-browser/understand-the-implementation/controller:
36
+ en: eaef9fc9999348c6
37
+ zh: 325d26183996cf3e
38
+ /qilin-client-ui-sidebar-browser/further-exploration:
39
+ en: ba6b428973d50727
40
+ zh: 354ac9f0ef374c6c
41
+ /qilin-client-ui-sidebar-browser/model-experience:
42
+ en: 69e711858e7d9ebc
43
+ zh: d84610491e69a35b
44
+ /qilin-client-ui-sidebar-browser/model-experience/kv-cache-effect:
45
+ en: e17a5fd3d5405745
46
+ zh: db957a16dddce770
47
+ /qilin-client-ui-sidebar-browser/known-limitations-and-deferred-work:
48
+ en: c0dc4f92cbaa62af
49
+ zh: 204949db5f0c9304
50
+ /qilin-client-ui-sidebar-browser/known-limitations-and-deferred-work/dev-note:
51
+ en: e67f633dc6fe7773
52
+ zh: e88aeb617ffb74ea
package/README.md CHANGED
@@ -1,3 +1,115 @@
1
- # Temporary Holding Version
1
+ ---
2
+ description: "Right-Sidebar browser tabs for sandboxed HTTP(S) pages, including loopback services."
3
+ kind: "package-reference"
4
+ ---
2
5
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
6
+ # @qilin-agent/client-ui-sidebar-browser
7
+
8
+ English | [中文](README.zh.md)
9
+
10
+ ## Summary
11
+
12
+ Browse HTTP(S) pages, including loopback services, inside independent right-Sidebar tabs. The current carrier is an iframe with application-managed history in both Web and Desktop. The package never injects Electron or Node access into visited content.
13
+
14
+ ## Table of Contents
15
+
16
+ - [Use this package](#use-this-package)
17
+ - [Understand the implementation](#understand-the-implementation)
18
+ - [Further Exploration](#further-exploration)
19
+ - [Model Experience](#model-experience)
20
+ - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
21
+ - [Dev Note](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## Use this package
27
+
28
+ The shipped Web and Desktop compositions already mount this package. Open **Browser** from the right-Sidebar guide, enter an HTTP(S) URL, or select an HTTP(S) link in Assistant Markdown. A host name without a scheme becomes HTTPS. Public and loopback targets use the same default sandbox. Each guide action or message-link activation creates another Browser tab.
29
+
30
+ ### When to choose it
31
+
32
+ Choose Browser for a Web page that should remain beside the current Session. Choose [Document Preview](../ui-sidebar-documentpreview/README.md) for local files, and use the explicit external-browser action when a site refuses iframe embedding or needs browser capabilities this package withholds.
33
+
34
+ ### Minimal configuration
35
+
36
+ The package has no configuration. A custom Web composition mounts its Host companion; the Client loader then discovers the browser entry declared by the package manifest:
37
+
38
+ ```yaml
39
+ - id: ui-sidebar-browser
40
+ name: '@qilin-agent/client-ui-sidebar-browser'
41
+ ```
42
+
43
+ Client plugins can open a tab through `ctx.sidebarRight.openTab('browser', { params: { url } })`. The optional URL passes the same validation as address-bar input before navigation.
44
+
45
+ The toolbar provides Back, Forward, Reload, Go, Open in system browser, and a rightmost per-tab sandbox toggle. Disabling the sandbox is temporary and displays a warning. The external action accepts a known HTTP(S) target. The tab title is the Web host.
46
+
47
+ -----
48
+
49
+ <a id="understand-the-implementation"></a>
50
+ ## Understand the implementation
51
+
52
+ <details>
53
+ <summary>Implementation internals — click to expand</summary>
54
+
55
+ ### Protocol policy
56
+
57
+ The address parser accepts HTTP and HTTPS, including loopback targets. It rejects `file:` URLs, script/data/blob input, embedded credentials, the QILIN application origin, and malformed addresses. Document Preview owns local-file rendering.
58
+
59
+ ### Iframe carrier
60
+
61
+ Web and Desktop use `sandbox="allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox"` by default. The frame has no direct download or top-navigation flag. Popups leave the sandbox; in Web, an escaped popup retains its opener and can navigate the top-level application. The visited origin can use its own cookies and Web storage but a cross-origin target cannot read QILIN DOM, storage, or API responses. The iframe sends no referrer and adds no package-owned Permissions Policy, so browser defaults and user grants apply. The toolbar can remove the sandbox for the current tab occurrence; the choice is not persisted. An unsandboxed page can navigate the top-level application under browser activation rules and use downloads, modal dialogs, and input locks. The package does not proxy or probe remote pages.
62
+
63
+ Web records toolbar submissions and typed tab opens. A navigation state machine treats the first iframe load for each controlled revision as known and a later load as proof that the page changed to an unreadable URL. In that unknown state the address is marked, Back, Forward, and external-open are disabled, and Reload returns to the last controlled URL. A remounted body reloads the latest application-known URL and uses its optional initial URL only before the first controlled target. History API and fragment changes that emit no iframe load remain invisible. An iframe `error` event displays a transient load-failure notice until the next controlled load without changing URL history.
64
+
65
+ ### Controller
66
+
67
+ Each tab receives one `BrowserController` class. Its public commands are `loadUrl`, `goBack`, `goForward`, and `reload`; address validation and history mutation stay behind that object. Its `BrowserNavigation` class owns the serializable URL state machine. The `BrowserFrame` interface owns transient sandbox and document state plus carrier operations, and `IframeImpl` implements that interface for the current iframe carrier. Slot injection exposes keyed frame state through `useBrowserFrame` and supplies plain callbacks, so the React body receives neither the controller nor an observable source; it keeps only the editable draft and iframe DOM.
68
+
69
+ The controller interface does not depend on iframe APIs. A future `ElectronWebViewImpl` can implement `BrowserFrame` while owning `<webview>` attachment and target identity. That deferred carrier is documented in the same Sidebar Browser decision, but is not registered or tested today.
70
+
71
+ </details>
72
+
73
+ -----
74
+
75
+ <a id="further-exploration"></a>
76
+ ## Further Exploration
77
+
78
+ - [Right Sidebar](../../../docs/subsystems/sidebar-right.md) — tab composition, navigation, and lifecycle.
79
+ - [Document Preview](../ui-sidebar-documentpreview/README.md) — local source, Markdown, images, HTML, and PDF rendering.
80
+ - [Sidebar Browser decision](../../../.agents/notes/implemented/feature/2026-09-16-sidebar-browser.md) — current iframe behavior, controller ownership, and deferred Electron carrier.
81
+
82
+ -----
83
+
84
+ <a id="model-experience"></a>
85
+ ## Model Experience
86
+
87
+ None, as Browser tabs are user-facing presentation state and register no tool, prompt section, or Session event.
88
+
89
+ #### KV Cache effect
90
+
91
+ None; browsing does not enter a model request.
92
+
93
+ ## Known Limitations and Deferred Work
94
+
95
+ <a id="known-limitations-and-deferred-work"></a>
96
+
97
+ The isolation policy deliberately gives up some browser compatibility:
98
+
99
+ - Many sites refuse iframe embedding or need downloads or top-level navigation withheld from the frame by the default sandbox. An HTTPS application can also block public HTTP pages as mixed content. Disabling the sandbox trades its restrictions for compatibility but does not bypass mixed-content or private-network policy. The unsandboxed frame can navigate the top-level application under browser activation rules and use downloads, modal dialogs, and input locks. It does not isolate the visited origin's cookies per Browser tab or prevent an in-frame page from choosing its own next URL.
100
+ - In Web, a popup that escapes the sandbox retains its opener and can use that chain to navigate the top-level application. Desktop handles popup creation separately.
101
+ - A later iframe load reveals that navigation occurred but not the new cross-origin URL. History API and fragment changes may remain invisible; Web Back and Forward are unavailable after the state becomes unknown.
102
+ - Browsers conceal many iframe failures for security: DNS, TLS, mixed-content, CSP, and `X-Frame-Options` failures may emit `load` or no actionable event instead of `error`. The load-failure notice is best-effort.
103
+ - Browser history survives body remounts and ordinary page reloads, but closing the tab or unloading `ui-sidebar-right` aborts its occurrence and removes the stored history bucket.
104
+ - Local files are rejected and remain owned by Document Preview.
105
+ - The proposed Electron `<webview>` carrier, per-tab cookie partitions, native history, and target-specific CDP connection are not implemented.
106
+
107
+ <a id="dev-note"></a>
108
+ ### Dev Note
109
+
110
+ <details>
111
+ <summary>Working context for maintainers — click to expand</summary>
112
+
113
+ None.
114
+
115
+ </details>
package/README.zh.md ADDED
@@ -0,0 +1,115 @@
1
+ ---
2
+ description: "右侧 Sidebar 浏览器 tab:在 sandbox 中访问 HTTP(S) 页面,包括 loopback 服务。"
3
+ kind: "package-reference"
4
+ ---
5
+
6
+ # @qilin-agent/client-ui-sidebar-browser
7
+
8
+ [English](README.md) | 中文
9
+
10
+ ## 概述
11
+
12
+ 在独立的右侧 Sidebar tab 中浏览 HTTP(S) 页面,包括 loopback 服务。当前 Web 与 Desktop 都使用 iframe 和应用维护的 history。本包不会向被访问内容注入 Electron 或 Node 能力。
13
+
14
+ ## 目录
15
+
16
+ - [使用本包](#use-this-package)
17
+ - [了解实现](#understand-the-implementation)
18
+ - [延伸阅读](#further-exploration)
19
+ - [模型体验](#model-experience)
20
+ - [已知限制与延期工作](#known-limitations-and-deferred-work)
21
+ - [开发备注](#dev-note)
22
+
23
+ -----
24
+
25
+ <a id="use-this-package"></a>
26
+ ## 使用本包
27
+
28
+ 随附的 Web 与 Desktop composition 已挂载本包。可以从右侧 Sidebar guide 打开 **浏览器**、输入 HTTP(S) URL,或点击 Assistant Markdown 中的 HTTP(S) 链接。不带 scheme 的主机名会补全为 HTTPS。公共目标与 loopback 目标使用相同的默认 sandbox。每次 guide 操作或消息链接操作都会创建一个新的 Browser tab。
29
+
30
+ ### 何时选择
31
+
32
+ 当 Web 页面需要保留在当前 Session 旁时,选择 Browser。本地文件使用 [Document Preview](../ui-sidebar-documentpreview/README.zh.md);站点拒绝 iframe 嵌入或需要本包不授予的浏览器 capability 时,使用明确的外部浏览器操作。
33
+
34
+ ### 最小配置
35
+
36
+ 本包没有配置字段。自定义 Web composition 挂载 Host companion;随后 Client loader 会发现 package manifest 声明的浏览器入口:
37
+
38
+ ```yaml
39
+ - id: ui-sidebar-browser
40
+ name: '@qilin-agent/client-ui-sidebar-browser'
41
+ ```
42
+
43
+ Client 插件可以调用 `ctx.sidebarRight.openTab('browser', { params: { url } })` 打开 tab。可选 URL 会在导航前接受与地址栏输入相同的校验。
44
+
45
+ 工具栏提供后退、前进、刷新、前往、在系统浏览器中打开,以及最右侧的逐 tab sandbox 开关。关闭 sandbox 是临时选择,并会显示警告。外部打开接受已知的 HTTP(S) 目标。tab 标题显示 Web 主机名。
46
+
47
+ -----
48
+
49
+ <a id="understand-the-implementation"></a>
50
+ ## 了解实现
51
+
52
+ <details>
53
+ <summary>实现细节——点击展开</summary>
54
+
55
+ ### 协议策略
56
+
57
+ 地址解析器接受 HTTP 与 HTTPS,包括 loopback 目标。`file:` URL、脚本/data/blob 输入、内嵌凭据、QILIN 应用自身 origin 和畸形地址会被拒绝。本地文件由 Document Preview 负责渲染。
58
+
59
+ ### Iframe 载体
60
+
61
+ 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,但跨域目标无法读取 QILIN DOM、storage 或 API 响应。iframe 不发送 referrer,也不添加包自有的 Permissions Policy,因此浏览器默认策略与用户授权生效。toolbar 可以为当前 tab occurrence 移除 sandbox;该选择不持久化。未受 sandbox 约束的页面可以按浏览器 activation 规则导航顶层应用,并使用下载、模态对话框和输入锁定。本包不代理或探测远程页面。
62
+
63
+ 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。
64
+
65
+ ### Controller
66
+
67
+ 每个 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。
68
+
69
+ Controller 接口不依赖 iframe API。未来的 `ElectronWebViewImpl` 可以实现 `BrowserFrame`,并持有 `<webview>` attachment 与 target identity。该延期载体记录在同一份 Sidebar Browser 决策中,当前不注册也不测试。
70
+
71
+ </details>
72
+
73
+ -----
74
+
75
+ <a id="further-exploration"></a>
76
+ ## 延伸阅读
77
+
78
+ - [右侧 Sidebar](../../../docs/subsystems/sidebar-right.zh.md)——tab composition、导航与生命周期。
79
+ - [Document Preview](../ui-sidebar-documentpreview/README.zh.md)——本地源码、Markdown、图片、HTML 与 PDF 渲染。
80
+ - [Sidebar Browser 决策](../../../.agents/notes/implemented/feature/2026-09-16-sidebar-browser.zh.md)——当前 iframe 行为、controller 所有权与延期 Electron 载体。
81
+
82
+ -----
83
+
84
+ <a id="model-experience"></a>
85
+ ## 模型体验
86
+
87
+ 无。Browser tab 是用户侧呈现状态,不注册工具、prompt section 或 Session event。
88
+
89
+ #### KV Cache 影响
90
+
91
+ 无;浏览内容不进入模型请求。
92
+
93
+ ## 已知限制与延期工作
94
+
95
+ <a id="known-limitations-and-deferred-work"></a>
96
+
97
+ 隔离策略有意放弃部分浏览器兼容性:
98
+
99
+ - 很多站点拒绝 iframe 嵌入,或需要默认 sandbox 不向 frame 授予的下载与顶层导航。HTTPS 应用还可能按 mixed-content 策略阻止公共 HTTP 页面。关闭 sandbox 会用自身限制换取兼容性,但不会绕过 mixed-content 或 private-network 策略。未受 sandbox 约束的 frame 可以按浏览器 activation 规则导航顶层应用,并使用下载、模态对话框和输入锁定。该模式不会按 Browser tab 隔离被访问 origin 的 Cookie,也无法阻止 iframe 内页面自行选择后续 URL。
100
+ - 在 Web 中,逃逸出 sandbox 的 popup 会保留 opener,并可以通过该链导航顶层应用。Desktop 会单独处理 popup 创建。
101
+ - 后续 iframe load 能表明发生了导航,但无法给出新的跨域 URL。History API 与 fragment 变化可能仍不可见;状态变成 unknown 后,Web 的后退与前进不可用。
102
+ - 出于安全原因,浏览器会隐藏很多 iframe 失败:DNS、TLS、mixed-content、CSP 与 `X-Frame-Options` 失败可能触发 `load`,也可能不提供可操作 event,而不是触发 `error`。加载失败 notice 只能作为 best-effort 提示。
103
+ - Browser history 会跨 body 重挂载与普通页面刷新保留,但关闭 tab 或卸载 `ui-sidebar-right` 会中止其 occurrence 并删除已存储的 history bucket。
104
+ - 本地文件会被拒绝,并继续由 Document Preview 负责。
105
+ - 拟议的 Electron `<webview>` 载体、per-tab Cookie partition、原生 history 和 target-specific CDP 连接尚未实现。
106
+
107
+ <a id="dev-note"></a>
108
+ ### 开发备注
109
+
110
+ <details>
111
+ <summary>维护者工作上下文——点击展开</summary>
112
+
113
+ 无。
114
+
115
+ </details>