page-harness 0.1.1 → 0.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/README.md +63 -10
- package/README.zh-CN.md +64 -11
- package/THIRD_PARTY_LICENSES.md +31 -0
- package/dist/cli.js +2212 -614
- package/dist/cli.js.map +1 -1
- package/dist/client/app/assets/history-BpjPiEWL.js +1 -0
- package/dist/client/app/assets/history-SejuExAu.css +1 -0
- package/dist/client/app/assets/{index.es-pLGXQA_f.js → index.es-5I8QYCO4.js} +1 -1
- package/dist/client/app/assets/{jspdf.es.min-OsUFBIXu.js → jspdf.es.min-BF5gKf3S.js} +4 -4
- package/dist/client/app/assets/panel-CSA_nlud.css +1 -0
- package/dist/client/app/assets/panel-DWp67jXP.js +2 -0
- package/dist/client/app/assets/{ws-BhXqMf5F.css → ws-DtkfUYSX.css} +1 -1
- package/dist/client/app/assets/{ws-B8OO397O.js → ws-Kt3Cg5KH.js} +21 -21
- package/dist/client/app/history.html +4 -4
- package/dist/client/app/panel.html +4 -4
- package/dist/client/page/live-overlay.js +6 -3
- package/dist/client/page/overlay.js +30 -16
- package/package.json +1 -1
- package/dist/client/app/assets/history-DTQ4t3U_.js +0 -1
- package/dist/client/app/assets/history-DfMi5ceT.css +0 -1
- package/dist/client/app/assets/panel-5OkTcFqg.css +0 -1
- package/dist/client/app/assets/panel-dt4wG7is.js +0 -2
package/README.md
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
[中文](./README.zh-CN.md)
|
|
4
4
|
|
|
5
|
-
Point it at any running frontend and the page gets a **Pick / Artifacts / Chat** dock, driven by the coding agent CLI already on your machine (Claude Code, Codex
|
|
5
|
+
Point it at any running frontend and the page gets a **Pick / Artifacts / Chat** dock, driven by the coding agent CLI already on your machine (Claude Code, Codex, Cursor Agent, CodeBuddy Code or OpenCode). No sandbox, no accounts, no changes to your app.
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx page-harness http://localhost:5173 --project ./my-app --agent claude
|
|
9
9
|
# open http://127.0.0.1:17990 — it is your app, plus the dock in the bottom-right corner
|
|
10
|
+
|
|
11
|
+
npx page-harness --no-agent http://localhost:5173 # Pick and Notes only; no agent CLI
|
|
12
|
+
npx page-harness # no URL: review-only home page and a bookmarklet
|
|
10
13
|
```
|
|
11
14
|
|
|
12
15
|
## What you get
|
|
@@ -26,30 +29,79 @@ npx page-harness http://localhost:5173 --project ./my-app --agent claude
|
|
|
26
29
|
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) (`claude`)
|
|
27
30
|
- [Codex](https://github.com/openai/codex) (`codex`)
|
|
28
31
|
- [Cursor Agent](https://docs.cursor.com/en/cli/overview) (`cursor-agent`)
|
|
32
|
+
- [CodeBuddy Code](https://www.codebuddy.ai/cli) (`codebuddy`, `npm i -g @tencent-ai/codebuddy-code`)
|
|
33
|
+
- [OpenCode](https://opencode.ai) (`opencode`, `npm i -g opencode-ai`)
|
|
34
|
+
|
|
35
|
+
page-harness detects which ones are installed and shows them in the banner. Use `--claude-path`, `--codex-path`, `--cursor-path`, `--codebuddy-path` or `--opencode-path` for non-standard locations. Agents that are not installed stay in the chat's agent picker, greyed out, with the install command.
|
|
36
|
+
|
|
37
|
+
What each agent supports:
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
| | Claude Code | Codex | Cursor Agent | CodeBuddy Code | OpenCode |
|
|
40
|
+
|---|---|---|---|---|---|
|
|
41
|
+
| Streaming text / thinking | ✓ | ✓ | ✓ | ✓ | per block¹ |
|
|
42
|
+
| Tool cards, changed files | ✓ | ✓ | ✓ | ✓ | ✓¹ |
|
|
43
|
+
| Resume a chat | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
44
|
+
| Model list | ✓ | ✓ | ✓ | ✓ (from `--help`) | ✓ (`opencode models`) |
|
|
45
|
+
| Reasoning effort | – | ✓ | – | ✓ (`--effort`) | ✓ (`--variant`) |
|
|
46
|
+
| Image attachments | ✓ | ✓ | file path in prompt | ✓ | ✓ (`--file`) |
|
|
47
|
+
|
|
48
|
+
¹ `opencode run --format json` reports text, reasoning and tool calls once each part has finished, so replies arrive a block at a time and a tool card opens and closes together.
|
|
31
49
|
|
|
32
50
|
## Usage
|
|
33
51
|
|
|
34
52
|
```text
|
|
35
|
-
page-harness
|
|
53
|
+
page-harness [frontend-url] [options]
|
|
36
54
|
|
|
37
55
|
--project <dir> Project the agent works in (default: current directory)
|
|
38
|
-
--agent <id> claude | codex | cursor (default: first one installed)
|
|
56
|
+
--agent <id> claude | codex | cursor | codebuddy | opencode (default: first one installed)
|
|
39
57
|
--model <name> Default model for new chats
|
|
40
58
|
--port <n> App port: the proxied frontend (default 17990)
|
|
41
|
-
--control-port <n> Panel / API port (default: app port + 1)
|
|
59
|
+
--control-port <n> Panel / API port (default: app port + 1, or 17991 with no URL)
|
|
42
60
|
--host <addr> Listen address (default 127.0.0.1)
|
|
43
61
|
--allow-host <name> Extra Host header to accept (repeatable), e.g. a LAN name
|
|
44
62
|
--keep-host Forward the browser's Host header to the target
|
|
63
|
+
--public-scheme <s> http | https: scheme browsers use to reach both ports (default http);
|
|
64
|
+
https behind a load balancer that terminates TLS on the same ports
|
|
45
65
|
--open Open the browser
|
|
46
66
|
--live-guard-hook Install a git pre-commit hook that rejects Live candidate markers
|
|
47
67
|
--review / --source Force review mode (no source) or source mode; default is by host
|
|
68
|
+
--no-agent Review only. Do not detect or start an agent CLI.
|
|
69
|
+
The dock is Pick and Notes. Implied when no URL is given.
|
|
48
70
|
--share Let teammates on your network join as reviewers (listens on 0.0.0.0)
|
|
49
71
|
--verbose / --quiet
|
|
50
72
|
```
|
|
51
73
|
|
|
52
|
-
`<frontend-url>` can be a bare port (`3000`), `host:port` or a full URL. Dev-server HMR (Vite, webpack, Next.js…) keeps working through the proxy, including WebSockets.
|
|
74
|
+
`<frontend-url>` can be a bare port (`3000`), `host:port` or a full URL. Omit it to start the bookmarklet home page. Dev-server HMR (Vite, webpack, Next.js…) keeps working through the proxy, including WebSockets.
|
|
75
|
+
|
|
76
|
+
### Review only (`--no-agent`)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx page-harness --no-agent http://localhost:5173
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
No agent CLI is detected or started, and MCP is refused. The dock is **Pick** and **Notes** only: comment, edit, reply, resolve and approve. Chat, Artifacts, Live, page control and questions are not shown. Notes are still saved in the project's `review.json`, under the **target** site's host (not the proxy's `127.0.0.1:17990`).
|
|
83
|
+
|
|
84
|
+
### Bookmarklet (no URL)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx page-harness
|
|
88
|
+
# Home http://127.0.0.1:17991
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This starts only the control server, always in review-only mode. The home page has a **PH Review** button: drag it to the bookmarks bar, open any site and click it. The overlay is injected into that page (no reverse proxy) inside a Shadow DOM, so the host page's CSS does not restyle the dock. The source select chooses where the script loads from:
|
|
92
|
+
|
|
93
|
+
- **This server** — `http://127.0.0.1:<control-port>/__ph/overlay.js`. Works on http pages.
|
|
94
|
+
- **jsDelivr** — `https://cdn.jsdelivr.net/npm/page-harness@<version>/dist/client/page/overlay.js`. Use this on https pages, and only after that version is published to npm.
|
|
95
|
+
|
|
96
|
+
Notes are written to this local server and grouped by site (`location.host`, including a non-default port). The home page lists sites on the left and that site's notes on the right, with Export Markdown, Export JSON and Copy prompt. The copied prompt calls this control server and includes `host=` so an agent only pulls that site:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
GET http://127.0.0.1:17991/__ph/api/review?scope=all&path=%2F&page=1&pageSize=20&host=shop.example.com
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The same `host` query works on the paging API when you want one site. Omit it and the API still returns every site, as before.
|
|
103
|
+
|
|
104
|
+
**Limits.** An https page usually blocks a script loaded from `http://127.0.0.1` (mixed content); switch the bookmarklet to jsDelivr so the script itself is https. Saving a note still calls the http control port. Chrome generally allows `127.0.0.1` and may ask for local-network access; the server answers `Access-Control-Allow-Private-Network` on the bookmarklet routes. Firefox and Safari often block that request as mixed content. A host page CSP that forbids connections to `127.0.0.1` blocks saving too. When the bookmarklet cannot reach the control port, use `page-harness <url> --no-agent` and review through the proxy instead. The bookmarklet carries a per-run token (`X-PH-Token`). It is visible in the bookmark and on pages where you click it; other sites cannot read or write notes without it. The unauthenticated paging API (`GET /__ph/api/review`) does not send CORS headers, so a random page cannot read notes through it.
|
|
53
105
|
|
|
54
106
|
## How it works
|
|
55
107
|
|
|
@@ -57,7 +109,8 @@ page-harness <frontend-url> [options]
|
|
|
57
109
|
browser ──► :17990 app port reverse proxy to your dev server; injects /__ph/overlay.js into HTML
|
|
58
110
|
└─► :17991 control port panel UI, history page, JSON API, WebSocket, MCP endpoint
|
|
59
111
|
│
|
|
60
|
-
└─ spawns the agent CLI per turn (claude -p / codex app-server / cursor-agent -p
|
|
112
|
+
└─ spawns the agent CLI per turn (claude -p / codex app-server / cursor-agent -p /
|
|
113
|
+
codebuddy -p / opencode run --format json)
|
|
61
114
|
with a local MCP server for page_*, artifacts, questions and Live
|
|
62
115
|
```
|
|
63
116
|
|
|
@@ -106,7 +159,7 @@ When the target is a public site (anything that is not localhost, a private IP o
|
|
|
106
159
|
|
|
107
160
|
Notes work in both modes; hand edits and `page_patch` only without source.
|
|
108
161
|
|
|
109
|
-
- Notes belong to the page they were made on (path without hash, trailing slash or tracking parameters). **This page** shows the current page; **All** groups every page, and clicking a note on another page goes there and opens it. The dock badge counts open notes on the current page and shows a dot when other pages have some.
|
|
162
|
+
- Notes belong to the page they were made on (path without hash, trailing slash or tracking parameters) and to the **site** (`host`, hostname plus a non-default port). Proxy mode stores the target host; the bookmarklet stores `location.host`. The overlay only pins notes for the site you are on. **This page** shows the current page; **All** groups every page of that site, and clicking a note on another page goes there and opens it. The dock badge counts open notes on the current page and shows a dot when other pages have some.
|
|
110
163
|
- Each pin opens a thread: author, replies, Resolve / Reopen, compare a change with the original, quote the element into the chat (owner) and delete (author or owner).
|
|
111
164
|
- **Approve** / **Request changes** records a verdict per page and person.
|
|
112
165
|
- Pins are re-attached with a fingerprint (tag, id, stable classes, key attributes, text and its context) when the selector breaks after a re-render or a redesign. If nothing fits well enough the note is shown as *not found on the page* instead of being pinned to the wrong element. Changes are re-applied after reloads and re-renders; nothing is sent to the site.
|
|
@@ -129,14 +182,14 @@ There is no login: it is a local developer tool and binds to `127.0.0.1` by defa
|
|
|
129
182
|
- **Two origins.** Your app (and any script on it) runs on the app port; the panel, API and agent endpoints are on the control port, so page scripts cannot read them.
|
|
130
183
|
- **Owner and reviewers.** Without `--share` only this machine can connect and everything behaves as one user. With `--share`, the owner session is only issued to loopback requests; other machines need the invite link, which sets signed (HMAC) reviewer cookies for the panel and the app port; without them both ports answer `403`. Reviewers are limited to the review actions on the WebSocket and to reading artifacts; everything else returns `403`. Name the owner in Settings → Team.
|
|
131
184
|
- **Session cookie.** The panel gets an `HttpOnly`, `SameSite=Strict` cookie scoped to `/__ph`; the cookie is stripped before requests are forwarded to your dev server.
|
|
132
|
-
- **API.** Reads require a same-origin `Sec-Fetch-Site`; writes require a matching `Origin` plus a custom `X-PH` header. The WebSocket checks the cookie and `Origin`.
|
|
185
|
+
- **API.** Reads require a same-origin `Sec-Fetch-Site`; writes require a matching `Origin` plus a custom `X-PH` header. The WebSocket checks the cookie and `Origin`. The bookmarklet is the exception: cross-origin review reads and writes need the per-run `X-PH-Token`, and the response reflects that page's `Origin` (never `*`). `GET /__ph/api/review` stays callable from curl without CORS headers.
|
|
133
186
|
- **MCP.** Every agent turn gets its own bearer token (passed through an environment variable or a private temp file, never on the command line) that is revoked when the turn ends. Browser requests to the MCP endpoint are rejected.
|
|
134
187
|
- **Host allow-list.** Requests with unexpected `Host` headers get `421` (DNS rebinding). Add names with `--allow-host` if you expose it on a LAN.
|
|
135
188
|
- **Framing.** The panel may only be framed by the app origin; the history page cannot be framed at all.
|
|
136
189
|
- **Artifacts.** HTML and SVG artifacts are served with a `sandbox` CSP and shown in iframes without `allow-same-origin`.
|
|
137
190
|
- **Page control** is opt-in per browser, shown with a banner, and password values are never sent to the agent.
|
|
138
191
|
|
|
139
|
-
Agents run with their CLI's non-interactive permissions (e.g. Claude Code `--permission-mode bypassPermissions`, Codex with approvals off, Cursor Agent `--force`) inside `--project`. Only point page-harness at projects you would let the agent edit.
|
|
192
|
+
Agents run with their CLI's non-interactive permissions (e.g. Claude Code `--permission-mode bypassPermissions`, Codex with approvals off, Cursor Agent `--force`, CodeBuddy Code `--permission-mode bypassPermissions`, OpenCode `run --auto`) inside `--project`. Only point page-harness at projects you would let the agent edit.
|
|
140
193
|
|
|
141
194
|
## Data
|
|
142
195
|
|
package/README.zh-CN.md
CHANGED
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
[English](./README.md)
|
|
4
4
|
|
|
5
|
-
给任意正在运行的前端地址,页面上就多出 **取点 / 产物 / 对话** 底栏,由你本机已有的编码 Agent CLI(Claude Code、Codex、Cursor Agent)驱动。不需要沙箱、不需要账号、不用改你的项目代码。
|
|
5
|
+
给任意正在运行的前端地址,页面上就多出 **取点 / 产物 / 对话** 底栏,由你本机已有的编码 Agent CLI(Claude Code、Codex、Cursor Agent、CodeBuddy Code、OpenCode)驱动。不需要沙箱、不需要账号、不用改你的项目代码。
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npx page-harness http://localhost:5173 --project ./my-app --agent claude
|
|
9
9
|
# 打开 http://127.0.0.1:17990 —— 页面就是你的应用,右下角多出底栏
|
|
10
|
+
|
|
11
|
+
npx page-harness --no-agent http://localhost:5173 # 只有取点和意见,不启动 Agent CLI
|
|
12
|
+
npx page-harness # 不给地址:仅评审的主页,外加一个书签按钮
|
|
10
13
|
```
|
|
11
14
|
|
|
12
15
|
## 功能
|
|
13
16
|
|
|
14
|
-
- **取点(Pick)**:点选页面元素后选择要做什么:**引用到对话**(选择器、文本、outerHTML 附到下一条消息;Shift+点击直接引用)、**评论**、**编辑**(没有源码的站点)或
|
|
17
|
+
- **取点(Pick)**:点选页面元素后选择要做什么:**引用到对话**(选择器、文本、outerHTML 附到下一条消息;Shift+点击直接引用)、**评论**、**编辑**(没有源码的站点)或 **在线生成**。在线生成:选中元素、描述改动,Agent 直接在源码里写出 2–4 个候选;你在页面上轮换、并排对比、调参数、细化某一个,最后采用或放弃。
|
|
15
18
|
- **对话(Chat)**:可拖动、可缩放的对话窗。流式回复,Markdown 与代码高亮,可折叠的思考过程,工具卡片,改动文件列表,图片/文件附件(粘贴、拖入、选择),每个会话独立的排队(可拖动排序、编辑、撤回),停止 / 重试,多会话,每个会话可选 Agent 与模型。
|
|
16
19
|
- **页面控制**(默认关闭):允许 Agent 读取页面并点击、输入、选择、滚动。开启时页面顶部有横幅,随时可以停止。
|
|
17
20
|
- **产物(Artifacts)**:Agent 通过 MCP 写报告、原型、JSON、图片等文件。标签页预览并保留版本历史:Markdown、沙箱 HTML(桌面 / 手机宽度)、结构化 JSON、代码、图片;可复制、下载、导出 PNG / PDF。
|
|
@@ -26,30 +29,79 @@ npx page-harness http://localhost:5173 --project ./my-app --agent claude
|
|
|
26
29
|
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)(`claude`)
|
|
27
30
|
- [Codex](https://github.com/openai/codex)(`codex`)
|
|
28
31
|
- [Cursor Agent](https://docs.cursor.com/en/cli/overview)(`cursor-agent`)
|
|
32
|
+
- [CodeBuddy Code](https://www.codebuddy.ai/cli)(`codebuddy`,`npm i -g @tencent-ai/codebuddy-code`)
|
|
33
|
+
- [OpenCode](https://opencode.ai)(`opencode`,`npm i -g opencode-ai`)
|
|
34
|
+
|
|
35
|
+
启动时会自动检测已安装的 CLI 并在终端里列出。不在默认位置时用 `--claude-path` / `--codex-path` / `--cursor-path` / `--codebuddy-path` / `--opencode-path` 指定。没装的 Agent 也会出现在对话的 Agent 选择器里,置灰,点一下能看到安装命令。
|
|
36
|
+
|
|
37
|
+
各 Agent 支持情况:
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
| | Claude Code | Codex | Cursor Agent | CodeBuddy Code | OpenCode |
|
|
40
|
+
|---|---|---|---|---|---|
|
|
41
|
+
| 流式文字 / 思考过程 | ✓ | ✓ | ✓ | ✓ | 按段¹ |
|
|
42
|
+
| 工具卡片、改动文件 | ✓ | ✓ | ✓ | ✓ | ✓¹ |
|
|
43
|
+
| 续接对话 | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
44
|
+
| 模型列表 | ✓ | ✓ | ✓ | ✓(取自 `--help`) | ✓(`opencode models`) |
|
|
45
|
+
| 推理强度 | – | ✓ | – | ✓(`--effort`) | ✓(`--variant`) |
|
|
46
|
+
| 图片附件 | ✓ | ✓ | 只传文件路径 | ✓ | ✓(`--file`) |
|
|
47
|
+
|
|
48
|
+
¹ `opencode run --format json` 只在每段文字、思考和工具调用结束后才输出,所以回复是一段一段出来的,工具卡片也是一次性出现并完成。
|
|
31
49
|
|
|
32
50
|
## 用法
|
|
33
51
|
|
|
34
52
|
```text
|
|
35
|
-
page-harness
|
|
53
|
+
page-harness [前端地址] [选项]
|
|
36
54
|
|
|
37
55
|
--project <dir> Agent 工作的项目目录(默认当前目录)
|
|
38
|
-
--agent <id> claude | codex | cursor(默认第一个已安装的)
|
|
56
|
+
--agent <id> claude | codex | cursor | codebuddy | opencode(默认第一个已安装的)
|
|
39
57
|
--model <name> 新会话的默认模型
|
|
40
58
|
--port <n> 应用端口:代理后的前端(默认 17990)
|
|
41
|
-
--control-port <n> 面板 / API 端口(默认应用端口 + 1)
|
|
59
|
+
--control-port <n> 面板 / API 端口(默认应用端口 + 1;不给地址时默认 17991)
|
|
42
60
|
--host <addr> 监听地址(默认 127.0.0.1)
|
|
43
61
|
--allow-host <name> 额外允许的 Host 头(可重复),比如局域网域名
|
|
44
62
|
--keep-host 把浏览器的 Host 头原样转发给目标
|
|
63
|
+
--public-scheme <s> http | https:浏览器访问两个端口用的协议(默认 http);
|
|
64
|
+
放在同端口卸载 TLS 的负载均衡后面时用 https
|
|
45
65
|
--open 自动打开浏览器
|
|
46
66
|
--live-guard-hook 安装 git pre-commit 钩子,拒绝提交 Live 候选标记
|
|
47
67
|
--review / --source 强制评审模式(无源码)或源码模式;默认按域名判断
|
|
68
|
+
--no-agent 仅评审。不检测、不启动 Agent CLI。底栏只有取点和意见。
|
|
69
|
+
不给前端地址时默认就是这个模式。
|
|
48
70
|
--share 允许同一网络的同事以评审者身份加入(监听 0.0.0.0)
|
|
49
71
|
--verbose / --quiet
|
|
50
72
|
```
|
|
51
73
|
|
|
52
|
-
`<前端地址>` 可以是端口(`3000`)、`host:port` 或完整 URL
|
|
74
|
+
`<前端地址>` 可以是端口(`3000`)、`host:port` 或完整 URL。不写地址就只打开书签主页。开发服务器的热更新(Vite、webpack、Next.js 等)通过代理照常工作,包括 WebSocket。
|
|
75
|
+
|
|
76
|
+
### 仅评审(`--no-agent`)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx page-harness --no-agent http://localhost:5173
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
不会检测或启动任何 Agent CLI,MCP 也会被拒绝。底栏只有**取点**和**意见**:评论、编辑、回复、解决、审批。没有对话、产物、Live、页面控制和提问。意见仍写在项目的 `review.json` 里,按**目标网站**的 host 存放(不是代理自己的 `127.0.0.1:17990`)。
|
|
83
|
+
|
|
84
|
+
### 书签(不给地址)
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
npx page-harness
|
|
88
|
+
# 主页 http://127.0.0.1:17991
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
这时只启动控制端口,并且一定是仅评审。主页上有一个 **PH 评审** 按钮:拖到收藏夹栏,打开任意网站再点它。覆盖层直接注入到那个页面(不经过反向代理),放在 Shadow DOM 里,宿主页面的 CSS 改不到底栏。来源可以选择脚本从哪里加载:
|
|
92
|
+
|
|
93
|
+
- **本机** — `http://127.0.0.1:<控制端口>/__ph/overlay.js`。适合 http 页面。
|
|
94
|
+
- **jsDelivr** — `https://cdn.jsdelivr.net/npm/page-harness@<版本>/dist/client/page/overlay.js`。https 页面用这个,而且该版本已经发布到 npm 之后才能加载到。
|
|
95
|
+
|
|
96
|
+
意见写回这台本机服务,按网站分组(`location.host`,非默认端口也算进去)。主页左边是网站列表,右边是该网站的意见,可以导出 Markdown、导出 JSON,以及复制 Prompt。复制出来的说明指向这个控制端口,并带上 `host=`,Agent 只会拉取这个网站:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
GET http://127.0.0.1:17991/__ph/api/review?scope=all&path=%2F&page=1&pageSize=20&host=shop.example.com
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
分页接口同样接受 `host`。不传时仍返回所有网站,和以前一样。
|
|
103
|
+
|
|
104
|
+
**限制。** https 页面通常会拦截从 `http://127.0.0.1` 加载的脚本(混合内容);把书签来源改成 jsDelivr,脚本本身就走 https。保存意见时仍然要请求这个 http 控制端口。Chrome 一般允许访问 `127.0.0.1`,并可能弹出本地网络权限;书签相关的响应会带 `Access-Control-Allow-Private-Network`。Firefox 和 Safari 多半会把这次请求当成混合内容拦掉。宿主页面的 CSP 如果禁止连接 `127.0.0.1`,保存也会失败。书签连不上控制端口时,改用 `page-harness <网址> --no-agent`,通过代理做评审。书签里带有本次运行的令牌(请求头 `X-PH-Token`),收藏夹和你点过书签的页面能看到它;没有令牌的其他网站不能读写意见。不带鉴权的分页接口(`GET /__ph/api/review`)不返回 CORS 头,随便一个网页不能靠它把意见读走。
|
|
53
105
|
|
|
54
106
|
## 原理
|
|
55
107
|
|
|
@@ -57,7 +109,8 @@ page-harness <前端地址> [选项]
|
|
|
57
109
|
浏览器 ──► :17990 应用端口 反向代理到你的开发服务器,在 HTML 里注入 /__ph/overlay.js
|
|
58
110
|
└─► :17991 控制端口 面板 UI、聊天记录页、JSON API、WebSocket、MCP
|
|
59
111
|
│
|
|
60
|
-
└─ 每一轮对话启动一次 Agent CLI(claude -p / codex app-server / cursor-agent -p
|
|
112
|
+
└─ 每一轮对话启动一次 Agent CLI(claude -p / codex app-server / cursor-agent -p /
|
|
113
|
+
codebuddy -p / opencode run --format json),
|
|
61
114
|
并接入本地 MCP:page_*、产物、提问、Live
|
|
62
115
|
```
|
|
63
116
|
|
|
@@ -106,7 +159,7 @@ page-harness <前端地址> [选项]
|
|
|
106
159
|
|
|
107
160
|
意见在两种模式下都能用;手动编辑和 `page_patch` 只在没有源码时可用。
|
|
108
161
|
|
|
109
|
-
- 意见属于创建它的页面(路径,忽略 hash
|
|
162
|
+
- 意见属于创建它的页面(路径,忽略 hash、末尾斜杠和统计参数),也属于**网站**(`host`:主机名,非默认端口一并算上)。代理模式存的是目标网站的 host;书签模式存的是 `location.host`。覆盖层只钉当前网站的意见。「本页」只看当前页面;「全部」按该网站的页面分组,点其他页面的条目会跳过去并打开它。底栏角标只计当前页面未解决的意见,其他页面有意见时显示小圆点。
|
|
110
163
|
- 每个图钉打开一个讨论串:作者、回复、解决 / 重新打开、修改与原版对比、引用到对话(所有者)、删除(作者或所有者)。
|
|
111
164
|
- 「通过」/「需修改」按页面、按人记录审批结论。
|
|
112
165
|
- 页面重新渲染或改版导致选择器失效时,用指纹(标签、id、稳定的 class、关键属性、文字及上下文)重新定位。没有足够匹配的元素时显示「页面上找不到了」,而不是钉到错误的元素上。刷新和重新渲染后修改会自动重新套上,不会向站点发送任何东西。
|
|
@@ -129,14 +182,14 @@ npx page-harness https://example.com --share
|
|
|
129
182
|
- **两个源。** 你的应用(以及其中任何脚本)在应用端口;面板、API、Agent 接口在控制端口,页面脚本读不到。
|
|
130
183
|
- **所有者与评审者。** 不加 `--share` 时只有本机能连,一切按单用户处理。加了 `--share` 后,所有者会话只发给本机回环请求;其他机器必须通过邀请链接拿到带 HMAC 签名的评审者 Cookie(面板和应用端口各一个),没有就两个端口都返回 `403`。评审者在 WebSocket 上只能做评审操作,API 只能读产物,其余一律 `403`。所有者名字在设置 → 团队里修改。
|
|
131
184
|
- **会话 Cookie。** 面板拿到 `HttpOnly`、`SameSite=Strict`、作用于 `/__ph` 的 Cookie;转发到你的开发服务器前会去掉它。
|
|
132
|
-
- **API。** 读请求要求同源的 `Sec-Fetch-Site`;写请求要求匹配的 `Origin` 加自定义 `X-PH` 头。WebSocket 校验 Cookie 和 `Origin
|
|
185
|
+
- **API。** 读请求要求同源的 `Sec-Fetch-Site`;写请求要求匹配的 `Origin` 加自定义 `X-PH` 头。WebSocket 校验 Cookie 和 `Origin`。书签是例外:跨源读写意见必须带本次运行的 `X-PH-Token`,响应会反射该页面的 `Origin`(不会是 `*`)。`GET /__ph/api/review` 仍给 curl 用,不带 CORS 头。
|
|
133
186
|
- **MCP。** 每一轮 Agent 调用都发一个独立的 Bearer token(通过环境变量或私有临时文件传递,不出现在命令行),回合结束即作废。来自浏览器的 MCP 请求一律拒绝。
|
|
134
187
|
- **Host 白名单。** `Host` 头不符的请求返回 `421`(防 DNS rebinding)。在局域网使用时用 `--allow-host` 添加。
|
|
135
188
|
- **嵌入限制。** 面板只允许被应用源嵌入;聊天记录页不允许被任何页面嵌入。
|
|
136
189
|
- **产物。** HTML / SVG 产物带 `sandbox` CSP 返回,并放在不含 `allow-same-origin` 的 iframe 里展示。
|
|
137
190
|
- **页面控制**需要在浏览器里手动开启,开启时有横幅提示,密码框的值不会发给 Agent。
|
|
138
191
|
|
|
139
|
-
Agent 以各自 CLI 的非交互权限在 `--project` 里运行(例如 Claude Code `--permission-mode bypassPermissions`、Codex 关闭审批、Cursor Agent `--force`)。只对你愿意让 Agent 修改的项目使用。
|
|
192
|
+
Agent 以各自 CLI 的非交互权限在 `--project` 里运行(例如 Claude Code `--permission-mode bypassPermissions`、Codex 关闭审批、Cursor Agent `--force`、CodeBuddy Code `--permission-mode bypassPermissions`、OpenCode `run --auto`)。只对你愿意让 Agent 修改的项目使用。
|
|
140
193
|
|
|
141
194
|
## 数据
|
|
142
195
|
|
package/THIRD_PARTY_LICENSES.md
CHANGED
|
@@ -2923,3 +2923,34 @@ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
2923
2923
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
2924
2924
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
2925
2925
|
```
|
|
2926
|
+
|
|
2927
|
+
## Agent logos (LobeHub Icons, @lobehub/icons-static-svg@1.95.1)
|
|
2928
|
+
|
|
2929
|
+
License: MIT
|
|
2930
|
+
Repository: https://github.com/lobehub/lobe-icons
|
|
2931
|
+
|
|
2932
|
+
The Claude, Codex, Cursor, CodeBuddy and OpenCode marks are trademarks of their owners (Anthropic, OpenAI, Anysphere, Tencent, SST) and are shown only to name the agent CLI in use.
|
|
2933
|
+
|
|
2934
|
+
```text
|
|
2935
|
+
MIT License
|
|
2936
|
+
|
|
2937
|
+
Copyright (c) 2023 LobeHub
|
|
2938
|
+
|
|
2939
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
2940
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
2941
|
+
in the Software without restriction, including without limitation the rights
|
|
2942
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
2943
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
2944
|
+
furnished to do so, subject to the following conditions:
|
|
2945
|
+
|
|
2946
|
+
The above copyright notice and this permission notice shall be included in all
|
|
2947
|
+
copies or substantial portions of the Software.
|
|
2948
|
+
|
|
2949
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
2950
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
2951
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
2952
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
2953
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
2954
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
2955
|
+
SOFTWARE.
|
|
2956
|
+
```
|