dsh-browser-verify 0.1.0 → 0.1.2

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 CHANGED
@@ -1,113 +1,163 @@
1
1
  # dsh-browser-verify
2
2
 
3
- Read-only browser verification tools for the DeepSeek Harness web GUI — verify a page (H5/desktop) in **≤4 tool calls** with mock interception, DOM assertions, and screenshots that auto-project into the model context. If your verification fits the four tools below, this plugin beats ad-hoc toolchain setup (browser install, cache probing, script authoring, image inspection) roughly 4 calls to ~20 steps.
3
+ English | [中文](README.zh.md)
4
4
 
5
- - **Registry**: `browser_open` / `browser_mock` / `browser_assert` / `browser_screenshot`
6
- - **Scope**: read-only verification only (no click/input/scroll). Runs headless Chromium via `playwright-core` (no browser download on the plugin side).
7
- - **License**: Apache-2.0
5
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
+ [![Node](https://img.shields.io/badge/node-%3E%3D22-blue.svg)](package.json)
8
7
 
9
- ## Install
8
+ **Give your DeepSeek Harness a pair of eyes on any web page** — read-only
9
+ browser verification in ≤4 tool calls: open, mock, assert, screenshot.
10
10
 
11
- > The plugin runs inside the harness process; install it into the harness profile. `dsh plugin` is invoked from the harness checkout.
11
+ Pages that change every day (H5 carousels, payment flows, admin consoles) are
12
+ hard to verify by eye. This plugin lets the model drive a real headless
13
+ browser through four tools — open a page, intercept its APIs, assert on the
14
+ DOM, screenshot it — and the screenshot lands straight back into the model's
15
+ context as an image. No terminal scripts, no browser bookkeeping: a
16
+ verification is just tool calls.
12
17
 
13
- ### From a packed tarball (recommended for local/private use)
18
+ ## Quick start
14
19
 
15
- ```bash
16
- pnpm install && pnpm build && pnpm pack # → dsh-browser-verify-<version>.tgz
17
- dsh plugin --profile web add ./dsh-browser-verify-<version>.tgz
20
+ ```sh
21
+ dsh plugin --profile web add dsh-browser-verify@0.1.2
18
22
  ```
19
23
 
20
- ### From a directory link (development)
24
+ 1. **Install** with the command above (or see [Install](#install)).
25
+ 2. **Restart the GUI once** — plugins load at boot; the four tools become
26
+ visible only after the restart.
27
+ 3. **Open a new session** and tell the model — or call directly:
21
28
 
22
- ```bash
23
- pnpm build # lib/ is gitignored — build first
24
- dsh plugin --profile web add /path/to/dsh-browser-verify
25
29
  ```
30
+ browser_open url="http://localhost:5173/hweb/#/pages/lyp/livingPayment" waitSelector=".header"
31
+ Opens the page in a fresh headless session and returns
32
+ title / status / visible-text / console-errors.
26
33
 
27
- ### From a git URL (git+https)
34
+ browser_assert selector=".empty-wrap" text="暂无可用缴费服务"
35
+ Waits for the selector (5s default) and returns {pass, count,
36
+ actualText, elapsedMs}. A miss is a normal pass:false, never an error.
37
+ ```
28
38
 
29
- pnpm installs a git dependency by cloning the repo and running its `prepare` script, so the remote repo must define `prepare` (build `lib/`), and the target profile must allow that build script via `allowBuilds` in its `pnpm-workspace.yaml`. The verified install paths for this repo are the packed tarball and the directory link above.
39
+ That is the whole loop two calls to answer "does the page show the empty
40
+ state?"; add `browser_screenshot` when you need to see the layout, or
41
+ `browser_mock` first when the page needs mocked APIs (see below).
30
42
 
31
- After install, restart the harness GUI, open a new session, and the four tools appear in the tool catalog.
43
+ ## What it does
32
44
 
33
- ## Quick start
45
+ | Tool | Purpose |
46
+ |---|---|
47
+ | `browser_open` | Open a URL in a fresh scenario (headless Chromium, default viewport 390×844 @2x) and report title / HTTP status / visible-text summary / console errors. Optional `waitSelector` waits for a key element before returning, and optional inline `mocks` intercept APIs **before** the first navigation — for pages that boot against mocked data. |
48
+ | `browser_mock` | Register a playwright-glob route (`**/api/*.do*`) returning your JSON, then auto-reload the page to show the mocked state — the quickest way to verify empty / error / abnormal states without touching the backend. Duplicate patterns are rejected with a hint. |
49
+ | `browser_assert` | The cheapest and most precise check: wait for a CSS selector, verify its count and contained text, return `{pass, count, actualText, elapsedMs}`. A mismatch is `pass:false` (with the diff), never a throw — so failure is a first-class result, not an error you debug. |
50
+ | `browser_screenshot` | Capture the current page (viewport or full page) and **auto-project the image block into the model context** — the model sees the layout without any file handling. Reports dimensions, sha256, and `identicalToPrevious:true` when the shot is byte-identical to the previous one (page probably not refreshed). |
34
51
 
35
- ```text
36
- browser_open url="http://localhost:5173/hweb/#/pages/lyp/livingPayment" waitSelector=".header"
37
- Opens the page in a fresh scenario (headless Chromium, default viewport 390×844 @2x) and
38
- returns title/status/visible-text/console-errors. Pass `mocks` here to intercept APIs before
39
- the first navigation, for pages that boot against mocked data.
40
- ```
52
+ Use `browser_assert` before `browser_screenshot`: an assertion is cheaper, and
53
+ a screenshot is for when the rendering itself must be judged.
54
+
55
+ ### Worked example two states, six calls
56
+
57
+ The typical verification (empty state + normal state) is 6 calls:
41
58
 
42
- ```text
43
- browser_mock urlPattern="**/api/*.do*" json={status:0,result:{list:[],data:{}}} status=200
44
- Registers a playwright-glob route interception and auto-reloads the page to show the mocked
45
- state. Duplicate patterns error: browser_open a fresh scenario or use a different pattern.
46
59
  ```
60
+ browser_open url="…/livingPayment" mocks=[{urlPattern:"**/api/*.do*", json:{status:0,result:{list:[],data:{}}}}] waitSelector=".header"
61
+ browser_assert selector=".empty-wrap" text="暂无可用缴费服务"
62
+ browser_screenshot
47
63
 
48
- ```text
49
- browser_assert selector=".empty-wrap" count=1 text="暂无可用缴费服务"
50
- Waits for the selector (default 5s) and returns {pass, count, actualText, elapsedMs} —
51
- a miss is a normal `pass:false`, never a thrown error. This is the cheapest verification
52
- step; use it before ever taking a screenshot.
64
+ browser_open … (same url, mocks with one list item {wegType:"WATER",name:"水费",info:"128.00"})
65
+ browser_assert selector=".grid-item" text="水费"
66
+ browser_screenshot
53
67
  ```
54
68
 
55
- ```text
56
- browser_screenshot name="livingPayment-empty" fullPage=false
57
- Captures the current page and auto-projects the image block into the model context;
58
- returns size/hash plus `identicalToPrevious:true` when the shot is byte-identical to the
59
- previous one (page probably not refreshed — re-open with browser_open).
69
+ ## Install
70
+
71
+ ```sh
72
+ dsh plugin --profile web add dsh-browser-verify@0.1.2
60
73
  ```
61
74
 
62
- ## Environment variables
75
+ The version is pinned on purpose: pnpm 11 holds back packages published in the
76
+ last 24 hours, so a bare `add dsh-browser-verify` (latest) would silently
77
+ install the previous release on launch day. `--profile web` is the GUI profile
78
+ of this deployment — use your own profile name if it differs.
63
79
 
64
- | Variable | Default | Meaning |
65
- |---|---|---|
66
- | `DSH_BROWSER_VERIFY_CHROMIUM` | *(unset)* | Full path to a Chromium binary; wins over cache probing. Checked for existence — startup fails with a hint if the path is wrong. |
67
- | `DSH_BROWSER_VERIFY_TIMEOUT` | `10000` | Timeout (ms) for page load / wait-selector / mock reload; wraps `browser_open`'s page-load path only (the other tools are FIFO-serialized without a wall-clock timeout). |
68
- | `DSH_BROWSER_VERIFY_IDLE_MS` | `600000` | Idle window (ms) before the browser instance auto-closes; plugin dispose force-cleans in any case. |
80
+ Requires **dsh 0.1.2-alpha.1**.
69
81
 
70
- ## Garbage cleanup
82
+ ### Browser prerequisite (read this)
71
83
 
72
- This plugin writes only to the system temp dir (its own `dsh-browser-verify-*` prefix), the harness attachment store, and `--persist` paths you choose explicitly. A startup sweep removes leftover dirs (>1 h old, own prefix) and kills stray Chromium; still, after a host crash the manual commands are:
84
+ The plugin does **not** download Chromium it finds a browser on your machine
85
+ instead. Install it once with:
73
86
 
74
- ```bash
75
- # Temp dirs + profile dirs left by crashes (macOS tmpdir, not /tmp)
76
- rm -rf "$(node -p 'require("os").tmpdir()')/dsh-browser-verify-*"
87
+ ```sh
88
+ npx playwright install chromium # needs playwright-core@1.62.0
77
89
  ```
78
90
 
79
- - **Attachment store**: screenshots persist to the harness-wide store at `~/.dsh/attachments` (content-addressed, identical bytes deduplicated). Their lifecycle is the harness attachment store's, not this plugin's — they are not deleted by tool exit.
80
- - **Playwright cache**: first-run install (`npx playwright install chromium`, needs `playwright-core@1.62.0`) writes the machine cache (`~/Library/Caches/ms-playwright`). The whole directory can be deleted and reinstalled; the plugin also probes it for a usable binary instead of downloading anything itself.
81
- - **Packed artifacts**: `*.tgz` from `pnpm pack` is gitignored; delete freely.
91
+ or point the plugin at an existing binary via `DSH_BROWSER_VERIFY_CHROMIUM`
92
+ (see [Environment variables](#environment-variables)). Without either, the
93
+ first `browser_open` fails with an actionable install hint.
94
+
95
+ ## Environment variables
96
+
97
+ | Variable | Default | Meaning |
98
+ |---|---|---|
99
+ | `DSH_BROWSER_VERIFY_CHROMIUM` | *(unset)* | Full path to a Chromium binary; wins over cache probing. If the path is wrong, startup fails with a hint. |
100
+ | `DSH_BROWSER_VERIFY_TIMEOUT` | `10000` | Wall-clock budget (ms) for the page-load path of `browser_open` (including wait-selector and mock reload). |
101
+ | `DSH_BROWSER_VERIFY_IDLE_MS` | `600000` | Idle window (ms) before the browser instance auto-closes; plugin disposal force-cleans in any case. |
102
+
103
+ ## Reliability & housekeeping
104
+
105
+ - **One browser, one scenario** — a lazy singleton per process, FIFO-serialized
106
+ tool access, an idle reclaim after 10 min, and a full teardown on dispose.
107
+ - **Screenshot dedup** — identical bytes report `identicalToPrevious:true`
108
+ instead of re-sending the model the same image.
109
+ - **Garbage discipline** — the plugin writes only to the system temp dir
110
+ (`dsh-browser-verify-*`), the harness attachment store, and explicit
111
+ `--persist` paths. On host crashes, clean leftovers with:
112
+
113
+ ```sh
114
+ rm -rf "$(node -p 'require("os").tmpdir()')/dsh-browser-verify-*"
115
+ ```
116
+
117
+ - **Error policy** — every error carries a `browser-verify: ` prefix and ends
118
+ with actionable advice; verification "failures" are results (`pass:false`),
119
+ never exceptions.
120
+
121
+ ## Testing status
122
+
123
+ 39 unit tests (fully offline — no browser needed), strict typecheck, and a
124
+ per-file ≥90% statement coverage gate. Verified **end-to-end in the real DSH
125
+ web GUI** on dsh 0.1.2-alpha.4: a two-state loop (empty + normal) against a
126
+ live uni-app H5 (hhhweb) in 6 tool calls, with screenshots auto-projected and
127
+ zero leftover temp dirs or zombie processes.
128
+
129
+ ## Known limitations
130
+
131
+ - **Read-only**: no clicks, inputs, or scrolling — verification only. One
132
+ scenario at a time; each `browser_open` resets mocks and page state.
133
+ - **Platform**: verified on macOS arm64. On other platforms set
134
+ `DSH_BROWSER_VERIFY_CHROMIUM` to a browser binary.
135
+ - **Single-machine assumption**: the startup sweep only touches
136
+ `dsh-browser-verify-*` pid dirs older than 1 h, so concurrent harnesses on
137
+ one machine are safe.
138
+ - **No GUI config card** — configuration is env-var only (see above).
82
139
 
83
140
  ## Development
84
141
 
85
142
  ```bash
86
143
  pnpm install
87
- pnpm build # tsc -b && tsdown → lib/
88
- pnpm test # vitest run
89
- pnpm vitest run --coverage # per-file ≥90% statements gate on discover/cleanup/attachments
144
+ pnpm build # tsc -b && tsdown → lib/ (clean build; lib/ is gitignored)
145
+ pnpm test # vitest run (offline)
90
146
  pnpm typecheck
91
- node lib/cli.js --url 'http://localhost:5173/hweb/#/pages/lyp/livingPayment' \
92
- --mock tests/fixtures/mock-empty.json --wait-selector '.header' \
93
- --assert '.empty-wrap' --screenshot
94
- scripts/smoke.sh # two-state end-to-end; REQUIRES the hhhweb dev server on :5173
147
+ pnpm vitest run --coverage # per-file ≥90% gate on discover / cleanup / attachments
148
+ scripts/smoke.sh # two-state end-to-end; requires the reference app dev server on :5173
95
149
  ```
96
150
 
97
- CLI options: `--url <u>` (required), `--mock <file.json>`, `--wait-selector <sel>`, `--assert <sel>`, `--screenshot`, `--persist <dir>` (keep the PNG), `--viewport <WxH>`.
98
-
99
- ## Moving to another machine
100
-
101
- 1. Copy/clone this repo and run `pnpm install && pnpm build && pnpm pack`.
102
- 2. `dsh plugin --profile web add ./dsh-browser-verify-<version>.tgz` on the target machine.
103
- 3. The browser cache is **not** shipped with the repo: install once with `npx playwright install chromium` (or set `DSH_BROWSER_VERIFY_CHROMIUM` to an existing binary).
104
-
105
- ## Notes
151
+ CLI (harness-free debug path): `node lib/cli.js --url <u> [--mock <file.json>]
152
+ [--wait-selector <sel>] [--assert <sel>] [--screenshot] [--persist <dir>]
153
+ [--viewport <WxH>]`.
106
154
 
107
- - **Single-machine assumption**: the startup sweep assumes one harness instance per machine — it only removes `dsh-browser-verify-*` pid dirs older than 1 h (plus stray Chromium for those pids), so concurrent harnesses on one host keep their fresh dirs.
108
- - **Platform**: verified on macOS arm64. On other platforms point `DSH_BROWSER_VERIFY_CHROMIUM` at a browser binary.
155
+ Contributors can install the local build with
156
+ `dsh plugin --profile web add ./dsh-browser-verify-<version>.tgz` after
157
+ `pnpm build`; the tarball ships a prebuilt `lib/`, so no build step runs on
158
+ the installing machine.
109
159
 
110
- ## Notes for real apps
160
+ ## License & attribution
111
161
 
112
- - uni-app H5 pages use hash routes (`/hweb/#/pages/...`) and an API envelope of `{status, result}` — both confirmed against the reference app (hhhweb).
113
- - Pages that re-route or bounce when real APIs answer “session invalid” need mocks registered **before** navigation: pass `mocks` to `browser_open` (or `--mock` to the CLI).
162
+ Apache-2.0. Architecture and implementation notes for agents and
163
+ contributors live in [AGENTS.md](AGENTS.md).
package/README.zh.md CHANGED
@@ -1,110 +1,132 @@
1
1
  # dsh-browser-verify
2
2
 
3
- 面向 DeepSeek Harness Web GUI 的只读浏览器验证工具——**≤4 次工具调用**即可验证一个页面(H5/桌面),覆盖 mock 拦截、DOM 断言、截图自动投影进模型上下文。如果你的验证场景能被以下四件套覆盖,本插件相比临时搭建验证工具链(装浏览器、探测缓存、写场景脚本、人工读图)大约 4 次调用对 ~20 个步骤。
3
+ [English](README.md) | 中文
4
4
 
5
- - **工具面**:`browser_open` / `browser_mock` / `browser_assert` / `browser_screenshot`
6
- - **范围**:仅只读验证(无点击/输入/滚动)。通过 `playwright-core` 驱动无头 Chromium(插件侧不下载浏览器)。
7
- - **许可证**:Apache-2.0
5
+ [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
6
+ [![Node](<https://img.shields.io/badge/node-%3E%3D22-blue.svg>)](package.json)
8
7
 
9
- ## 安装
8
+ **给你的 DeepSeek Harness 一双看网页的眼睛** —— 只读浏览器验证,≤4 次工具调用完成:打开、mock、断言、截图。
10
9
 
11
- > 插件在 harness 进程内运行,安装目标是 harness profile;`dsh plugin` 命令在 harness checkout 下执行。
10
+ 每天都在变的页面(H5 轮播、缴费流程、后台控制台)很难靠肉眼验证。本插件让模型通过四个工具驱动一个真实的无头浏览器——打开页面、拦截接口、断言 DOM、截图——截图自动以图片块形式回到模型上下文。不需要终端脚本,不需要打理浏览器:一次验证就是几次工具调用。
12
11
 
13
- ### 从打包 tgz 安装(本地/私有使用推荐)
12
+ ## 快速上手
14
13
 
15
- ```bash
16
- pnpm install && pnpm build && pnpm pack # → dsh-browser-verify-<版本号>.tgz
17
- dsh plugin --profile web add ./dsh-browser-verify-<版本号>.tgz
14
+ ```sh
15
+ dsh plugin --profile web add dsh-browser-verify@0.1.2
18
16
  ```
19
17
 
20
- ### 从目录 link 安装(开发调试)
18
+ 1. **安装**(更多方式见 [安装](#安装))。
19
+ 2. **重启 GUI 一次**——插件在启动时加载,四个工具要在重启后才可见。
20
+ 3. **新开会话**,告诉模型——或直接调用:
21
21
 
22
- ```bash
23
- pnpm build # lib/ 被 gitignore——先构建
24
- dsh plugin --profile web add /路径/dsh-browser-verify
25
22
  ```
23
+ browser_open url="http://localhost:5173/hweb/#/pages/lyp/livingPayment" waitSelector=".header"
24
+ 打开页面(全新无头会话),返回 title / HTTP status / 可见文本摘要 / console 错误。
26
25
 
27
- ### 从 git URL 安装(git+https)
26
+ browser_assert selector=".empty-wrap" text="暂无可用缴费服务"
27
+ 等待选择器(默认 5s),返回 {pass, count, actualText, elapsedMs}。
28
+ 未命中是正常的 pass:false,而不是抛错。
29
+ ```
28
30
 
29
- pnpm 安装 git 依赖时先克隆仓库再执行其 `prepare` 脚本:因此远端仓库必须定义 `prepare`(构建 `lib/`),且目标 profile 必须在 `pnpm-workspace.yaml` 的 `allowBuilds` 中放行该构建脚本。本仓库已验证的安装路径为上述 tgz 与目录 link 两种。
31
+ 这就是整个闭环——两次调用回答"页面是否显示了空态?";需要看版式再加
32
+ `browser_screenshot`,页面启动依赖 mock 接口就先 `browser_mock`(或直接在
33
+ `browser_open` 传内联 `mocks`,见下文)。
30
34
 
31
- 安装后重启 harness GUI、新开会话,四个工具即出现在工具目录中。
35
+ ## 它做什么
32
36
 
33
- ## 快速上手
37
+ | 工具 | 用途 |
38
+ | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
39
+ | `browser_open` | 在全新场景中打开 URL(无头 Chromium,默认视口 390×844 @2x),返回 title / HTTP 状态 / 可见文本摘要 / console 错误。可选`waitSelector` 等待关键元素出现后再返回;可选内联 `mocks` 在**首次导航前**拦截接口——用于一启动就依赖 mock 数据的页面。 |
40
+ | `browser_mock` | 注册 playwright glob 路由(如`**/api/*.do*`)返回指定 JSON,并自动 reload 页面展示 mock 状态——不碰后端最快验证空态/异常态。重复 pattern 会提示报错。 |
41
+ | `browser_assert` | 最省 token 也最精确的验证:等待 CSS 选择器出现,校验数量与包含文本,返回`{pass, count, actualText, elapsedMs}`。不满足时返回 `pass:false`(附差异),**绝不抛错**——失败是一等公民的结果,而不是要调试的异常。 |
42
+ | `browser_screenshot` | 截取当前页面(视口或整页),**自动以 image block 投影到模型上下文**——模型直接"看见"版式,无需任何文件处理。返回尺寸、sha256;与上一张完全一致时 `identicalToPrevious:true`(疑似页面未刷新)。 |
43
+
44
+ 先 `browser_assert` 再 `browser_screenshot`:断言更便宜,截图留给必须判断
45
+ 渲染效果的时刻。
46
+
47
+ ### 完整示例——两态六次调用
48
+
49
+ 典型验证(空态 + 正常态)只需 6 次调用:
34
50
 
35
- ```text
36
- browser_open url="http://localhost:5173/hweb/#/pages/lyp/livingPayment" waitSelector=".header"
37
- 在新场景中打开页面(无头 Chromium,默认视口 390×844 @2x),返回标题/状态码/可见文本/
38
- console 错误。对于启动即依赖接口数据的页面,可在此传 mocks 在首次导航前完成拦截。
39
51
  ```
52
+ browser_open url="…/livingPayment" mocks=[{urlPattern:"**/api/*.do*", json:{status:0,result:{list:[],data:{}}}}] waitSelector=".header"
53
+ browser_assert selector=".empty-wrap" text="暂无可用缴费服务"
54
+ browser_screenshot
40
55
 
41
- ```text
42
- browser_mock urlPattern="**/api/*.do*" json={status:0,result:{list:[],data:{}}} status=200
43
- 注册 playwright glob 路由拦截并自动 reload 当前页,展示 mock 后的状态。pattern 重复会
44
- 报错:请 browser_open 重开场景,或换一个 urlPattern。
56
+ browser_open …(同 url,mocks 换成一条 {wegType:"WATER",name:"水费",info:"128.00"})
57
+ browser_assert selector=".grid-item" text="水费"
58
+ browser_screenshot
45
59
  ```
46
60
 
47
- ```text
48
- browser_assert selector=".empty-wrap" count=1 text="暂无可用缴费服务"
49
- 等待选择器出现(默认 5s),返回 {pass, count, actualText, elapsedMs}——不满足时是正常的
50
- pass:false,绝不抛错。这是最省 token 的验证手段;先断言,确有必要再截图。
61
+ ## 安装
62
+
63
+ ```sh
64
+ dsh plugin --profile web add dsh-browser-verify@0.1.2
51
65
  ```
52
66
 
53
- ```text
54
- browser_screenshot name="livingPayment-empty" fullPage=false
55
- 截取当前页并将图片块自动投影进模型上下文;返回尺寸/哈希,若与上一张字节完全一致则
56
- identicalToPrevious:true(疑似页面未刷新——请 browser_open 重开)。
67
+ 版本故意钉死:pnpm 11 会暂缓 24 小时内新发布的包,裸写 `add dsh-browser-verify`(latest)会在发布当天装到上一个版本。`--profile web`
68
+ 是本部署的 GUI profile——如果不同请换成你自己的 profile 名。
69
+
70
+ 要求 **dsh 0.1.2-alpha.1**。
71
+
72
+ ### 浏览器前置(务必读)
73
+
74
+ 本插件**不自带 Chromium**——它在你机器上找浏览器。先装一次:
75
+
76
+ ```sh
77
+ npx playwright install chromium # 需要 playwright-core@1.62.0
57
78
  ```
58
79
 
80
+ 或通过 `DSH_BROWSER_VERIFY_CHROMIUM` 指向已有二进制(见
81
+ [环境变量](#环境变量))。两者都没有时,第一次 `browser_open` 会给出可操作的安装提示。
82
+
59
83
  ## 环境变量
60
84
 
61
- | 变量 | 默认值 | 含义 |
62
- |---|---|---|
63
- | `DSH_BROWSER_VERIFY_CHROMIUM` | (未设置) | Chromium 二进制完整路径,优先级高于缓存探测;启动时校验存在性,路径有误会给出提示。 |
64
- | `DSH_BROWSER_VERIFY_TIMEOUT` | `10000` | 超时(ms):页面加载 / 等待选择器 / mock reload;仅包裹 `browser_open` 的页面加载路径(其余三个工具仅 FIFO 串行,无墙钟超时)。 |
65
- | `DSH_BROWSER_VERIFY_IDLE_MS` | `600000` | 空闲回收窗口(ms),到时自动关闭浏览器实例;插件 dispose 时无论如何会强制清理。 |
85
+ | 变量 | 默认 | 含义 |
86
+ | ------------------------------- | ------------ | -------------------------------------------------------------------------------- |
87
+ | `DSH_BROWSER_VERIFY_CHROMIUM` | *(未设置)* | Chromium 完整路径;优先于缓存探测。路径错误时启动即报可操作提示。 |
88
+ | `DSH_BROWSER_VERIFY_TIMEOUT` | `10000` | `browser_open` 页面加载路径的墙钟预算(ms),含 wait-selector mock reload |
89
+ | `DSH_BROWSER_VERIFY_IDLE_MS` | `600000` | 空闲回收窗口(ms),超时后浏览器实例自动关闭;插件 dispose 时强制清理。 |
66
90
 
67
- ## 垃圾清理
91
+ ## 可靠性与清理
68
92
 
69
- 本插件只会在系统临时目录(自己的 `dsh-browser-verify-*` 前缀)、harness 附件库、以及你显式指定的 `--persist` 路径落东西。启动时会清扫过期残留目录(>1h、仅限自己的前缀)并兜底杀死孤儿 Chromium;但宿主崩溃后仍建议手动执行:
93
+ - **单浏览器单场景**——每进程一个惰性单例,FIFO 串行工具访问,10 分钟空闲回收,dispose 全量清理。
94
+ - **截图幂等**——字节一致时返回 `identicalToPrevious:true`,不再把同一张图重复发给模型。
95
+ - **零垃圾纪律**——插件只写系统临时目录(`dsh-browser-verify-*` 前缀)、DSH 附件库和显式 `--persist` 路径。宿主崩溃后手动清理:
70
96
 
71
- ```bash
72
- # 崩溃残留的临时目录/profile 目录(注意 macOS tmpdir 不是 /tmp)
73
- rm -rf "$(node -p 'require("os").tmpdir()')/dsh-browser-verify-*"
74
- ```
97
+ ```sh
98
+ rm -rf "$(node -p 'require("os").tmpdir()')/dsh-browser-verify-*"
99
+ ```
100
+ - **错误即接口**——所有错误以 `browser-verify: ` 前缀开头、以可操作建议结尾;验证"失败"是结果(`pass:false`),不是异常。
75
101
 
76
- - **附件库**:截图持久化到 harness 全局附件库 `~/.dsh/attachments`(内容寻址,相同字节自动去重)。其生命周期由 harness 附件库管理,不随工具退出删除。
77
- - **Playwright 缓存**:首次安装(`npx playwright install chromium`,需 `playwright-core@1.62.0`)写入机器级缓存(`~/Library/Caches/ms-playwright`)。整个目录可整删后重装;插件本身只会探测该缓存中的可用二进制,不会自行下载。
78
- - **打包产物**:`pnpm pack` 产生的 `*.tgz` 已被 gitignore,可随意删除。
102
+ ## 测试状态
103
+
104
+ 39 个单测(完全离线,无需浏览器)、严格 typecheck、每文件 ≥90% 语句覆盖率闸门。已在 **dsh 0.1.2-alpha.4 真实 GUI 端到端验证**:对一个真实 uni-app H5(hhhweb),空态+正常态两态闭环共 6 次调用,截图自动投影,无临时目录残留、无僵尸进程。
105
+
106
+ ## 已知限制
107
+
108
+ - **只读**:不点击、不输入、不滚动——仅验证。同时只有一个场景;每次 `browser_open` 重置 mocks 与页面状态。
109
+ - **平台**:已实测 macOS arm64。其他平台请用 `DSH_BROWSER_VERIFY_CHROMIUM` 指定浏览器二进制。
110
+ - **单机假设**:启动清理只处理超过 1 小时的 `dsh-browser-verify-*` pid 目录,同机多实例互不影响。
111
+ - **无 GUI 配置卡**——配置仅环境变量(见上)。
79
112
 
80
113
  ## 开发
81
114
 
82
115
  ```bash
83
116
  pnpm install
84
- pnpm build # tsc -b && tsdown → lib/
85
- pnpm test # vitest run
86
- pnpm vitest run --coverage # discover/cleanup/attachments 逐文件语句覆盖 ≥90% 门槛
117
+ pnpm build # tsc -b && tsdown → lib/(clean 构建;lib/ 不入库)
118
+ pnpm test # vitest run(离线)
87
119
  pnpm typecheck
88
- node lib/cli.js --url 'http://localhost:5173/hweb/#/pages/lyp/livingPayment' \
89
- --mock tests/fixtures/mock-empty.json --wait-selector '.header' \
90
- --assert '.empty-wrap' --screenshot
91
- scripts/smoke.sh # 两态端到端冒烟;需要 hhhweb dev server 在 :5173 运行
120
+ pnpm vitest run --coverage # discover / cleanup / attachments 每文件 ≥90%
121
+ scripts/smoke.sh # 两态端到端;需要参考应用 dev server 在 :5173
92
122
  ```
93
123
 
94
- CLI 选项:`--url <u>`(必填)、`--mock <file.json>`、`--wait-selector <sel>`、`--assert <sel>`、`--screenshot`、`--persist <dir>`(保留 PNG)、`--viewport <WxH>`。
95
-
96
- ## 多机迁移
97
-
98
- 1. 复制/克隆本仓库并执行 `pnpm install && pnpm build && pnpm pack`。
99
- 2. 在目标机器 `dsh plugin --profile web add ./dsh-browser-verify-<版本号>.tgz`。
100
- 3. 浏览器缓存**不随仓库**:先 `npx playwright install chromium` 安装一次(或将 `DSH_BROWSER_VERIFY_CHROMIUM` 指向已有二进制)。
101
-
102
- ## 注意事项
124
+ CLI(免 harness 的调试路径):`node lib/cli.js --url <u> [--mock <file.json>] [--wait-selector <sel>] [--assert <sel>] [--screenshot] [--persist <dir>] [--viewport <WxH>]`。
103
125
 
104
- - **单机假设**:启动清扫按“每台机器一个 harness 实例”设计——只清理超过 1h 的 `dsh-browser-verify-*` pid 目录(及对应孤儿进程),同机多实例的新鲜目录不受影响。
105
- - **平台**:已在 macOS arm64 实测验证;其他平台请用 `DSH_BROWSER_VERIFY_CHROMIUM` 指向浏览器二进制。
126
+ 贡献者可本地构建后安装:`pnpm build`
127
+ `dsh plugin --profile web add ./dsh-browser-verify-<version>.tgz`——tgz 内已含
128
+ 预构建 `lib/`,安装机无需再构建。
106
129
 
107
- ## 真实应用注意事项
130
+ ## 许可与署名
108
131
 
109
- - uni-app H5 页面使用 hash 路由(`/hweb/#/pages/...`),API 响应信封为 `{status, result}`——均已在参考应用(hhhweb)实测确认。
110
- - 真实 API 返回“session invalid”时会跳转/回退的路由:mock 必须在导航前注册——请通过 `browser_open` 的 `mocks` 传入(CLI 则用 `--mock`)。
132
+ Apache-2.0。面向 agent 与贡献者的架构说明与实现约定见 [AGENTS.md](AGENTS.md)。
package/cordis.patch.yml CHANGED
@@ -1,17 +1,11 @@
1
- # dsh-browser-verify bundle patch: inserts the four browser verification
2
- # tools into the web profile roster. Applied as a profile bundle layer (the
3
- # dsh.bundle.patch manifest field).
1
+ # dsh-browser-verify bundle patch: registers the four read-only browser
2
+ # verification tools (browser_open / browser_mock / browser_assert /
3
+ # browser_screenshot) in the profile's tool roster. Applied automatically as a
4
+ # profile bundle layer (dsh.bundle.patch in package.json).
4
5
  #
5
- # Install (from a source checkout; tarball name follows the current version):
6
- # pnpm install && pnpm build && pnpm pack
7
- # dsh plugin --profile web add ./dsh-browser-verify-<version>.tgz
8
- # # or, during development, add the checkout directory directly (pnpm link):
9
- # dsh plugin --profile web add <path-to-this-directory>
10
- #
11
- # Host half only: the node half (exports ".") registers browser_open /
12
- # browser_mock / browser_assert / browser_screenshot. No client half, no
13
- # settings card. Configuration is env-var only (DSH_BROWSER_VERIFY_*); do NOT
14
- # add a `config:` block here.
6
+ # Install: dsh plugin --profile web add dsh-browser-verify@<version>
7
+ # Host half only no client half, no settings card. Configuration is env-var
8
+ # only (DSH_BROWSER_VERIFY_*); do NOT add a `config:` block here.
15
9
  - insert:
16
10
  - id: browser-verify
17
11
  name: 'dsh-browser-verify'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-browser-verify",
3
3
  "description": "Read-only browser verification tools for the DeepSeek Harness web GUI: browser_open / browser_mock / browser_assert / browser_screenshot — verify a page (H5/desktop) in ≤4 tool calls with mock interception, DOM assertions, and screenshots that auto-project into the model context.",
4
- "version": "0.1.0",
4
+ "version": "0.1.2",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@11.7.0",
7
7
  "engines": {
@@ -31,6 +31,10 @@
31
31
  "dependencies": {
32
32
  "playwright-core": "1.62.0"
33
33
  },
34
+ "peerDependencies": {
35
+ "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",
36
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.4"
37
+ },
34
38
  "devDependencies": {
35
39
  "@deepseek-ai/cordis": "^4.0.1",
36
40
  "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",