@restregular/dsh-visual-browser 0.1.0 → 0.2.0
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/README.md +57 -21
- package/client.js +1077 -437
- package/lib/browser.js +1255 -963
- package/lib/cdp.js +208 -192
- package/lib/routes.js +101 -47
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +6 -6
- package/test/format.test.mjs +62 -0
- package/test/package.test.mjs +68 -0
- package/test/routes.test.mjs +248 -0
- package/test/scripts.test.mjs +214 -0
package/README.md
CHANGED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
# dsh-visual-browser
|
|
2
2
|
|
|
3
|
-
A DeepSeek Harness plugin that gives the Agent a **real Chrome** and gives you a **window into it
|
|
3
|
+
A DeepSeek Harness plugin that gives the Agent a **real Chrome** and gives you a **live window into it** — as a tab in the **right Sidebar**, right under the built-in *Browser* entry.
|
|
4
4
|
|
|
5
5
|
- The Agent never reads the DOM. It reads a numbered list of *visible interactive
|
|
6
6
|
elements* plus a short text excerpt — a few hundred tokens per page instead of a
|
|
7
|
-
full snapshot.
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
full DOM snapshot.
|
|
8
|
+
- The tab streams Chrome's own screencast (CDP `Page.startScreencast`) as a
|
|
9
|
+
length-prefixed JPEG stream, decoded off the main thread onto a canvas. No
|
|
10
|
+
screenshot polling, no per-frame request, no re-render of the panel per frame.
|
|
11
|
+
- Your pointer, wheel and keyboard go straight to the DevTools input domain in
|
|
12
|
+
animation-frame batches: click, drag, scroll and type with normal latency
|
|
13
|
+
instead of "screenshot after the fact" latency.
|
|
14
|
+
- Every action — the Agent's and yours — lands in a collapsible, scrollable
|
|
15
|
+
**operation log**. Records only: there is nothing to replay.
|
|
11
16
|
- Cookies persist across restarts (one dedicated Chrome profile), so a login the
|
|
12
17
|
Agent performs once keeps working.
|
|
13
18
|
|
|
14
19
|
## Install
|
|
15
20
|
|
|
16
21
|
```bash
|
|
17
|
-
# The plugin is a normal DSH bundle; install it from the registry
|
|
18
22
|
dsh plugin add @restregular/dsh-visual-browser
|
|
19
23
|
```
|
|
20
24
|
|
|
@@ -26,11 +30,23 @@ dependencies; it talks CDP over the built-in WebSocket).
|
|
|
26
30
|
|
|
27
31
|
## Use
|
|
28
32
|
|
|
29
|
-
1.
|
|
33
|
+
1. Open the right Sidebar. Under the built-in **浏览器 / Browser** card sits the
|
|
34
|
+
Visual Browser row — click it, or click the **浏览器** card itself and then the
|
|
35
|
+
extra row beneath it. The tab opens and replaces the guide in that pane.
|
|
30
36
|
2. Ask the Agent something that needs a website, for example
|
|
31
37
|
*"打开 example.com 看看首页写了什么"*. The Agent calls `browser_open`.
|
|
32
|
-
3. Watch the
|
|
33
|
-
|
|
38
|
+
3. Watch the picture. Click, drag, wheel and type straight into it; the toolbar
|
|
39
|
+
has back / forward / reload / stop, and the address bar opens any URL.
|
|
40
|
+
|
|
41
|
+
The operation log at the bottom remembers the Agent's actions and yours. Click
|
|
42
|
+
its header to fold it away, or scroll it when the list is longer than the pane.
|
|
43
|
+
|
|
44
|
+
### Dark mode
|
|
45
|
+
|
|
46
|
+
The panel only uses `--dsw-alias-*` theme tokens for surfaces, text, borders,
|
|
47
|
+
hover and focus, so light and dark (and theme switches) need no extra rules. The
|
|
48
|
+
only literal colour in the bundle is the `#fff` fallback after
|
|
49
|
+
`--dsw-alias-label-primary-foreground`.
|
|
34
50
|
|
|
35
51
|
## Tools the Agent gets
|
|
36
52
|
|
|
@@ -77,9 +93,9 @@ Row config (in the profile's `cordis.patch.yml`, override by row id
|
|
|
77
93
|
height: 800
|
|
78
94
|
maxElements: 100 # cap on the numbered list
|
|
79
95
|
maxTextChars: 320 # cap on the text excerpt
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
96
|
+
streamQuality: 60 # JPEG quality of the live screencast
|
|
97
|
+
allowUserControl: true # allow clicks/typing from the panel
|
|
98
|
+
reuseExisting: true # adopt a Chrome that already owns the profile
|
|
83
99
|
actionTimeoutMs: 12000
|
|
84
100
|
navigationTimeoutMs: 30000
|
|
85
101
|
```
|
|
@@ -90,18 +106,30 @@ Row config (in the profile's `cordis.patch.yml`, override by row id
|
|
|
90
106
|
`--remote-debugging-port=0 --user-data-dir=<profile>`, parses the DevTools
|
|
91
107
|
endpoint from stderr, attaches one flattened CDP session, and exposes:
|
|
92
108
|
- five tools through the `tools` service (registration is effect-scoped),
|
|
93
|
-
- a same-origin prefix route `/visual-browser/api
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
- a same-origin prefix route `/visual-browser/api`:
|
|
110
|
+
| Route | Purpose |
|
|
111
|
+
| --- | --- |
|
|
112
|
+
| `GET /state` | Status, viewport and the operation log (tiny JSON poll). |
|
|
113
|
+
| `GET /stream` | One long response of `[len][seq][jpeg]` frames. |
|
|
114
|
+
| `POST /input` | A batch of pointer / wheel / key / text events. |
|
|
115
|
+
| `POST /start`, `POST /stop`, `POST /nav` | Open a URL, close Chrome, back/forward/reload. |
|
|
116
|
+
- **Live picture** (`lib/browser.js`): `Page.startScreencast` pushes a JPEG per
|
|
117
|
+
painted frame; the manager acks each frame and fans the same buffer out to every
|
|
118
|
+
panel. The first subscriber restarts the screencast so a still page appears at
|
|
119
|
+
once; the last one stops it, so a closed panel costs nothing. No screenshot is
|
|
120
|
+
taken per click, and nothing about the picture touches the model context.
|
|
121
|
+
- **Input** (`lib/browser.js`): panel events become `Input.dispatchMouseEvent` /
|
|
122
|
+
`Input.dispatchKeyEvent` / `Input.insertText` commands. Nothing waits for a
|
|
123
|
+
snapshot or a capture, so input latency is one round trip; the client batches
|
|
124
|
+
per animation frame so a drag or flick is one request, not thirty.
|
|
96
125
|
- **Snapshot** (`lib/page-scripts.js`): one serialized function runs in the page,
|
|
97
126
|
filters interactive elements to the viewport, assigns `data-dsh-vb-ref`
|
|
98
127
|
numbers, and returns structured JSON. Nothing else about the DOM leaves the
|
|
99
128
|
page.
|
|
100
|
-
- **
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
`BrowserManager` methods the tools use.
|
|
129
|
+
- **Survives a host restart**: Chrome writes `DevToolsActivePort` into its
|
|
130
|
+
profile, so a restarted host (or one whose previous host crashed with Chrome
|
|
131
|
+
still alive) attaches to that browser instead of failing on the profile lock.
|
|
132
|
+
An adopted browser is only detached — its process is not killed.
|
|
105
133
|
|
|
106
134
|
Chrome is killed with its process tree when the plugin unloads.
|
|
107
135
|
|
|
@@ -109,9 +137,11 @@ Chrome is killed with its process tree when the plugin unloads.
|
|
|
109
137
|
|
|
110
138
|
- Cross-origin iframes are counted but not inspected; open the direct URL when a
|
|
111
139
|
flow lives inside a frame.
|
|
112
|
-
- Blocking JS dialogs are auto-accepted and logged in the
|
|
140
|
+
- Blocking JS dialogs are auto-accepted and logged in the operation log.
|
|
113
141
|
- The panel route is served by the Harness web server on its existing origin;
|
|
114
142
|
it performs no extra authentication, matching the other local panel routes.
|
|
143
|
+
- The stream is a raw binary response on purpose: `multipart/x-mixed-replace`
|
|
144
|
+
parsing differs between browser builds, so the panel parses frames itself.
|
|
115
145
|
- Headless mode is the default. Some sites behave differently headless; set
|
|
116
146
|
`headless: false` when a site insists on a window.
|
|
117
147
|
|
|
@@ -121,4 +151,10 @@ Chrome is killed with its process tree when the plugin unloads.
|
|
|
121
151
|
npm test # syntax checks + snapshot/format/route/package smoke tests
|
|
122
152
|
```
|
|
123
153
|
|
|
154
|
+
`.dsh-probe/` (git-ignored) holds the manual probes used while developing:
|
|
155
|
+
`live-probe.mjs` drives the real browser end to end, `ui-probe.mjs` renders the
|
|
156
|
+
real client bundle in Chrome against the real host API and drives the panel with
|
|
157
|
+
real DOM events, and `build-css.mjs` copies the panel CSS and theme tokens for
|
|
158
|
+
that harness.
|
|
159
|
+
|
|
124
160
|
MIT © RestRegular
|