hyper-agent-browser 0.1.0 → 0.3.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 +333 -92
- package/package.json +2 -2
- package/src/browser/manager.ts +61 -3
- package/src/cli.ts +150 -0
- package/src/commands/extract.ts +76 -0
- package/src/commands/network.ts +111 -0
- package/src/commands/wait.ts +226 -0
- package/src/daemon/browser-pool.ts +38 -5
- package/src/daemon/server.ts +66 -0
- package/src/extractors/form-extractor.ts +153 -0
- package/src/extractors/list-extractor.ts +213 -0
- package/src/extractors/meta-extractor.ts +139 -0
- package/src/extractors/table-extractor.ts +215 -0
- package/src/utils/network-listener.ts +247 -0
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**纯浏览器自动化 CLI,专为 AI Agent 设计**
|
|
4
4
|
|
|
5
|
+
[](https://www.npmjs.com/package/hyper-agent-browser)
|
|
5
6
|
[](https://www.typescriptlang.org/)
|
|
6
7
|
[](https://bun.sh)
|
|
7
8
|
[](./LICENSE)
|
|
@@ -13,161 +14,354 @@
|
|
|
13
14
|
- 🎭 **反检测** - 基于 Patchright,绕过自动化检测
|
|
14
15
|
- ⚡ **快速启动** - Bun 运行时,冷启动 ~25ms
|
|
15
16
|
- 🤖 **AI Agent 友好** - 设计用于 Claude Code 等 AI Agent 调用
|
|
17
|
+
- 🔒 **安全加固** - 沙箱隔离、权限控制、Session 保护
|
|
18
|
+
- 📊 **数据提取** - 表格/列表/表单/元数据自动提取
|
|
19
|
+
- 🌐 **网络监听** - 拦截 XHR/Fetch 请求,直接获取 API 数据
|
|
20
|
+
- ⏳ **智能等待** - 网络空闲 + DOM 稳定双重策略
|
|
16
21
|
|
|
17
22
|
## 🚀 快速开始
|
|
18
23
|
|
|
19
24
|
### 安装
|
|
20
25
|
|
|
26
|
+
**使用 npm(推荐)**
|
|
27
|
+
|
|
21
28
|
```bash
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
cd hyper-agent-browser
|
|
29
|
+
# 全局安装
|
|
30
|
+
npm install -g hyper-agent-browser
|
|
25
31
|
|
|
26
|
-
#
|
|
32
|
+
# 或使用 Bun
|
|
33
|
+
bun install -g hyper-agent-browser
|
|
34
|
+
|
|
35
|
+
# 或使用 npx(无需安装)
|
|
36
|
+
npx hyper-agent-browser --version
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**从源码安装**
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git clone https://github.com/hubo1989/hyper-agent-browser.git
|
|
43
|
+
cd hyper-agent-browser
|
|
27
44
|
bun install
|
|
45
|
+
bun run build # 构建二进制文件到 dist/hab
|
|
28
46
|
```
|
|
29
47
|
|
|
48
|
+
**下载预编译二进制文件**
|
|
49
|
+
|
|
50
|
+
访问 [GitHub Releases](https://github.com/hubo1989/hyper-agent-browser/releases) 下载对应平台的二进制文件。
|
|
51
|
+
|
|
30
52
|
### 基础使用
|
|
31
53
|
|
|
32
54
|
```bash
|
|
33
|
-
# 1.
|
|
34
|
-
|
|
55
|
+
# 1. 打开网页(有头模式,可以看到浏览器)
|
|
56
|
+
hab --headed open https://google.com
|
|
35
57
|
|
|
36
58
|
# 2. 获取可交互元素快照
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
#
|
|
40
|
-
#
|
|
59
|
+
hab snapshot -i
|
|
60
|
+
|
|
61
|
+
# 输出示例:
|
|
62
|
+
# URL: https://google.com
|
|
63
|
+
# Title: Google
|
|
64
|
+
#
|
|
65
|
+
# Interactive Elements:
|
|
66
|
+
# @e1 [textbox] "Search" (focused)
|
|
41
67
|
# @e2 [button] "Google Search"
|
|
42
|
-
# @e3 [
|
|
68
|
+
# @e3 [button] "I'm Feeling Lucky"
|
|
69
|
+
# @e4 [link] "Gmail"
|
|
70
|
+
# @e5 [link] "Images"
|
|
43
71
|
|
|
44
72
|
# 3. 使用 @eN 引用操作元素
|
|
45
|
-
|
|
46
|
-
|
|
73
|
+
hab fill @e1 "Bun JavaScript runtime"
|
|
74
|
+
hab press Enter
|
|
75
|
+
|
|
76
|
+
# 4. 等待页面加载
|
|
77
|
+
hab wait 2000
|
|
78
|
+
|
|
79
|
+
# 5. 截图
|
|
80
|
+
hab screenshot -o result.png
|
|
47
81
|
|
|
48
|
-
#
|
|
49
|
-
|
|
82
|
+
# 6. 获取页面内容
|
|
83
|
+
hab content
|
|
50
84
|
```
|
|
51
85
|
|
|
52
|
-
###
|
|
86
|
+
### Session 管理(多账号隔离)
|
|
53
87
|
|
|
54
88
|
```bash
|
|
55
|
-
#
|
|
56
|
-
|
|
89
|
+
# 个人 Gmail 账号
|
|
90
|
+
hab -s personal-gmail open https://mail.google.com
|
|
91
|
+
hab -s personal-gmail snapshot -i
|
|
57
92
|
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
|
|
93
|
+
# 工作 Gmail 账号
|
|
94
|
+
hab -s work-gmail open https://mail.google.com
|
|
95
|
+
hab -s work-gmail snapshot -i
|
|
96
|
+
|
|
97
|
+
# 列出所有 Session
|
|
98
|
+
hab sessions
|
|
99
|
+
|
|
100
|
+
# 关闭特定 Session
|
|
101
|
+
hab close -s personal-gmail
|
|
61
102
|
```
|
|
62
103
|
|
|
63
|
-
|
|
104
|
+
### 数据提取(新增)
|
|
64
105
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
-
|
|
69
|
-
- [hyper-agent-browser-spec.md](./hyper-agent-browser-spec.md) - 技术规格
|
|
106
|
+
```bash
|
|
107
|
+
# 提取表格数据
|
|
108
|
+
hab open https://example.com/users
|
|
109
|
+
hab extract-table > users.json
|
|
70
110
|
|
|
71
|
-
|
|
111
|
+
# 提取列表数据(自动检测商品/文章列表)
|
|
112
|
+
hab extract-list --selector ".product-list" > products.json
|
|
72
113
|
|
|
73
|
-
|
|
114
|
+
# 提取表单状态
|
|
115
|
+
hab extract-form > form_data.json
|
|
74
116
|
|
|
75
|
-
|
|
117
|
+
# 提取页面元数据(SEO/OG/Schema.org)
|
|
118
|
+
hab extract-meta --include seo,og > metadata.json
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 网络监听(新增)
|
|
76
122
|
|
|
77
123
|
```bash
|
|
78
|
-
#
|
|
79
|
-
hab
|
|
124
|
+
# 启动网络监听
|
|
125
|
+
LISTENER_ID=$(hab network-start --filter xhr,fetch --url-pattern "*/api/*" | jq -r '.listenerId')
|
|
80
126
|
|
|
81
|
-
#
|
|
82
|
-
hab
|
|
83
|
-
hab
|
|
84
|
-
```
|
|
127
|
+
# 执行操作(翻页/点击等)
|
|
128
|
+
hab click @e5
|
|
129
|
+
hab wait-idle
|
|
85
130
|
|
|
86
|
-
|
|
131
|
+
# 停止监听并获取所有 API 数据
|
|
132
|
+
hab network-stop $LISTENER_ID > api_data.json
|
|
133
|
+
```
|
|
87
134
|
|
|
88
|
-
|
|
135
|
+
### 智能等待(新增)
|
|
89
136
|
|
|
90
137
|
```bash
|
|
91
|
-
#
|
|
92
|
-
|
|
138
|
+
# 等待页面完全空闲(网络 + DOM)
|
|
139
|
+
hab wait-idle --timeout 30000
|
|
93
140
|
|
|
94
|
-
#
|
|
95
|
-
|
|
141
|
+
# 等待元素可见
|
|
142
|
+
hab wait-element "css=.data-row" --state visible
|
|
96
143
|
|
|
97
|
-
#
|
|
98
|
-
|
|
144
|
+
# 等待加载动画消失
|
|
145
|
+
hab wait-element "css=.loading" --state detached
|
|
99
146
|
```
|
|
100
147
|
|
|
101
|
-
|
|
148
|
+
## 📖 完整命令列表
|
|
102
149
|
|
|
103
|
-
|
|
104
|
-
**操作**: `click`, `fill`, `type`, `press`, `scroll`, `hover`, `select`, `wait`
|
|
105
|
-
**信息**: `snapshot`, `screenshot`, `evaluate`, `url`, `title`, `content`
|
|
106
|
-
**会话**: `sessions`, `close`
|
|
150
|
+
### 导航命令
|
|
107
151
|
|
|
108
|
-
|
|
152
|
+
| 命令 | 说明 | 示例 |
|
|
153
|
+
|------|------|------|
|
|
154
|
+
| `open <url>` | 打开网页 | `hab open https://example.com` |
|
|
155
|
+
| `reload` | 刷新当前页面 | `hab reload` |
|
|
156
|
+
| `back` | 后退 | `hab back` |
|
|
157
|
+
| `forward` | 前进 | `hab forward` |
|
|
109
158
|
|
|
110
|
-
|
|
111
|
-
# 运行测试
|
|
112
|
-
bun test
|
|
159
|
+
### 操作命令
|
|
113
160
|
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
| 命令 | 说明 | 示例 |
|
|
162
|
+
|------|------|------|
|
|
163
|
+
| `click <selector>` | 点击元素 | `hab click @e1` |
|
|
164
|
+
| `fill <selector> <value>` | 填充输入框 | `hab fill @e1 "hello"` |
|
|
165
|
+
| `type <text>` | 逐字输入文本 | `hab type "password"` |
|
|
166
|
+
| `press <key>` | 按键 | `hab press Enter` |
|
|
167
|
+
| `scroll <direction> [amount]` | 滚动页面 | `hab scroll down 500` |
|
|
168
|
+
| `hover <selector>` | 悬停在元素上 | `hab hover @e3` |
|
|
169
|
+
| `select <selector> <value>` | 选择下拉选项 | `hab select @e2 "Option 1"` |
|
|
170
|
+
| `wait <ms\|condition>` | 等待时间或条件 | `hab wait 3000` |
|
|
171
|
+
|
|
172
|
+
### 信息命令
|
|
173
|
+
|
|
174
|
+
| 命令 | 说明 | 示例 |
|
|
175
|
+
|------|------|------|
|
|
176
|
+
| `snapshot [-i\|--interactive]` | 获取页面快照 | `hab snapshot -i` |
|
|
177
|
+
| `screenshot [-o <file>] [--full-page]` | 截图 | `hab screenshot -o page.png` |
|
|
178
|
+
| `url` | 获取当前 URL | `hab url` |
|
|
179
|
+
| `title` | 获取页面标题 | `hab title` |
|
|
180
|
+
| `content [selector]` | 获取文本内容 | `hab content` |
|
|
181
|
+
| `evaluate <script>` | 执行 JavaScript | `hab evaluate "document.title"` |
|
|
116
182
|
|
|
117
|
-
|
|
118
|
-
bun run lint
|
|
183
|
+
### Session 命令
|
|
119
184
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
185
|
+
| 命令 | 说明 | 示例 |
|
|
186
|
+
|------|------|------|
|
|
187
|
+
| `sessions` | 列出所有 Session | `hab sessions` |
|
|
188
|
+
| `close [-s <name>]` | 关闭 Session | `hab close -s gmail` |
|
|
189
|
+
|
|
190
|
+
### 全局选项
|
|
124
191
|
|
|
125
|
-
|
|
192
|
+
| 选项 | 说明 | 默认值 |
|
|
193
|
+
|------|------|--------|
|
|
194
|
+
| `-s, --session <name>` | 指定 Session 名称 | `default` |
|
|
195
|
+
| `--headed` | 有头模式(显示浏览器) | `false` |
|
|
196
|
+
| `--channel <chrome\|msedge>` | 浏览器类型 | `chrome` |
|
|
197
|
+
| `--timeout <ms>` | 超时时间 | `30000` |
|
|
126
198
|
|
|
127
|
-
|
|
199
|
+
## 🤖 AI Agent 集成(Claude Code)
|
|
200
|
+
|
|
201
|
+
hyper-agent-browser 专为 AI Agent 设计,可与 Claude Code 无缝集成。
|
|
202
|
+
|
|
203
|
+
### 安装 Skill 文件
|
|
128
204
|
|
|
129
205
|
```bash
|
|
206
|
+
# 方法 1:从本地仓库复制
|
|
130
207
|
mkdir -p ~/.claude/skills
|
|
131
208
|
cp skills/hyper-browser.md ~/.claude/skills/
|
|
209
|
+
|
|
210
|
+
# 方法 2:直接下载
|
|
211
|
+
curl -o ~/.claude/skills/hyper-browser.md \
|
|
212
|
+
https://raw.githubusercontent.com/hubo1989/hyper-agent-browser/main/skills/hyper-browser.md
|
|
132
213
|
```
|
|
133
214
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
215
|
+
### 使用示例
|
|
216
|
+
|
|
217
|
+
安装 Skill 后,Claude Code 会自动识别并使用 `hab` 命令。你可以这样指示 Claude:
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
"帮我打开 Google 搜索 'Bun runtime' 并截图"
|
|
221
|
+
"登录我的 Gmail 账号,找到未读邮件数量"
|
|
222
|
+
"访问 Twitter 并获取首页的所有推文标题"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Claude 会自动:
|
|
226
|
+
1. 使用 `hab open` 打开网页
|
|
227
|
+
2. 使用 `hab snapshot -i` 获取元素引用
|
|
228
|
+
3. 分析快照,找到目标元素(如 `@e5`)
|
|
229
|
+
4. 使用 `hab click @e5` 等命令完成操作
|
|
230
|
+
|
|
231
|
+
### Skill 功能
|
|
232
|
+
|
|
233
|
+
- ✅ 自动解析 `@eN` 引用
|
|
234
|
+
- ✅ Session 管理(多账号隔离)
|
|
235
|
+
- ✅ 错误处理和重试
|
|
236
|
+
- ✅ 浏览器状态保持
|
|
237
|
+
- ✅ 登录状态持久化
|
|
140
238
|
|
|
141
239
|
## 📋 选择器格式
|
|
142
240
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
|
146
|
-
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
241
|
+
hyper-agent-browser 支持多种选择器格式:
|
|
242
|
+
|
|
243
|
+
| 格式 | 示例 | 说明 | 推荐度 |
|
|
244
|
+
|------|------|------|--------|
|
|
245
|
+
| `@eN` | `@e1`, `@e5` | 元素引用(来自 snapshot) | ⭐⭐⭐⭐⭐ |
|
|
246
|
+
| `css=` | `css=#login` | CSS 选择器 | ⭐⭐⭐ |
|
|
247
|
+
| `text=` | `text=Sign in` | 文本匹配 | ⭐⭐⭐⭐ |
|
|
248
|
+
| `xpath=` | `xpath=//button` | XPath 选择器 | ⭐⭐ |
|
|
249
|
+
|
|
250
|
+
**推荐使用 `@eN` 引用**:
|
|
251
|
+
- 无需手写选择器
|
|
252
|
+
- 自动处理动态 ID/Class
|
|
253
|
+
- AI Agent 友好
|
|
254
|
+
|
|
255
|
+
## 🎯 核心功能详解
|
|
256
|
+
|
|
257
|
+
### 1. 元素引用系统
|
|
258
|
+
|
|
259
|
+
不需要手写复杂的选择器:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# 传统方式(繁琐、易出错)
|
|
263
|
+
hab click 'css=button.MuiButton-root.MuiButton-contained.MuiButton-sizeMedium'
|
|
264
|
+
|
|
265
|
+
# hyper-agent-browser 方式(简单、可靠)
|
|
266
|
+
hab snapshot -i # 自动生成 @e1, @e2... 引用
|
|
267
|
+
hab click @e5 # 直接使用引用
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 2. Session 持久化
|
|
271
|
+
|
|
272
|
+
每个 Session 有独立的:
|
|
273
|
+
- 浏览器实例
|
|
274
|
+
- UserData 目录(Cookies/LocalStorage)
|
|
275
|
+
- 登录状态
|
|
276
|
+
- 浏览历史
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
~/.hab/sessions/
|
|
280
|
+
├── default/
|
|
281
|
+
│ ├── userdata/ # Chrome UserData
|
|
282
|
+
│ ├── session.json # 元数据(wsEndpoint/pid/url)
|
|
283
|
+
│ └── element-refs.json # @eN 映射
|
|
284
|
+
├── gmail-personal/
|
|
285
|
+
└── gmail-work/
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 3. 浏览器复用
|
|
289
|
+
|
|
290
|
+
CLI 每次调用是独立进程,但浏览器实例会持久化复用:
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# 第一次:启动新浏览器 (~1-2s)
|
|
294
|
+
hab --headed open https://google.com
|
|
295
|
+
|
|
296
|
+
# 后续调用:复用浏览器 (~50ms)
|
|
297
|
+
hab snapshot -i
|
|
298
|
+
hab click @e1
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## 🔒 安全特性
|
|
302
|
+
|
|
303
|
+
hyper-agent-browser v0.1.0 包含全面的安全加固:
|
|
304
|
+
|
|
305
|
+
### 1. evaluate 命令沙箱
|
|
306
|
+
|
|
307
|
+
- ✅ 白名单模式(仅允许安全的 document/window 操作)
|
|
308
|
+
- ✅ 增强黑名单(阻止 eval/Function/constructor/globalThis)
|
|
309
|
+
- ✅ 结果大小限制(最大 100KB,防止数据窃取)
|
|
310
|
+
|
|
311
|
+
### 2. Session 文件权限保护
|
|
312
|
+
|
|
313
|
+
- ✅ session.json 权限设置为 `0o600`(仅所有者可读写)
|
|
314
|
+
- ✅ 保护 wsEndpoint 不被其他进程劫持
|
|
315
|
+
|
|
316
|
+
### 3. 配置文件权限保护
|
|
317
|
+
|
|
318
|
+
- ✅ config.json 权限设置为 `0o600`
|
|
319
|
+
- ✅ 保护敏感配置
|
|
320
|
+
|
|
321
|
+
### 4. Chrome 扩展安全验证
|
|
322
|
+
|
|
323
|
+
- ✅ 扩展白名单机制
|
|
324
|
+
- ✅ 自动检查扩展 manifest 危险权限
|
|
325
|
+
- ✅ 过滤含 debugger/webRequest/proxy 权限的扩展
|
|
326
|
+
|
|
327
|
+
### 5. 系统 Keychain 隔离
|
|
328
|
+
|
|
329
|
+
- ✅ 默认使用隔离的密码存储
|
|
330
|
+
- ✅ 通过 `HAB_USE_SYSTEM_KEYCHAIN=true` 显式启用
|
|
331
|
+
|
|
332
|
+
### 6. 配置键白名单验证
|
|
333
|
+
|
|
334
|
+
- ✅ 仅允许修改安全的配置键
|
|
335
|
+
- ✅ 阻止危险浏览器参数注入
|
|
149
336
|
|
|
150
337
|
## 🏗️ 架构
|
|
151
338
|
|
|
152
339
|
```
|
|
153
340
|
src/
|
|
154
|
-
├── cli.ts # CLI
|
|
155
|
-
├── browser/
|
|
156
|
-
├──
|
|
157
|
-
|
|
158
|
-
├──
|
|
159
|
-
│ ├──
|
|
341
|
+
├── cli.ts # CLI 入口(Commander.js)
|
|
342
|
+
├── browser/
|
|
343
|
+
│ ├── manager.ts # 浏览器生命周期管理
|
|
344
|
+
│ └── context.ts # BrowserContext 封装
|
|
345
|
+
├── session/
|
|
346
|
+
│ ├── manager.ts # Session 管理(多浏览器实例)
|
|
347
|
+
│ └── store.ts # UserData 持久化
|
|
348
|
+
├── commands/
|
|
349
|
+
│ ├── navigation.ts # open/reload/back/forward
|
|
350
|
+
│ ├── actions.ts # click/fill/type/press/scroll
|
|
351
|
+
│ ├── info.ts # snapshot/screenshot/evaluate
|
|
352
|
+
│ └── session.ts # sessions/close
|
|
353
|
+
├── snapshot/
|
|
354
|
+
│ ├── accessibility.ts # 从 Accessibility Tree 提取元素
|
|
160
355
|
│ ├── dom-extractor.ts # DOM 提取器(fallback)
|
|
356
|
+
│ ├── formatter.ts # 格式化输出
|
|
161
357
|
│ └── reference-store.ts # @eN 映射存储
|
|
162
|
-
└── utils/
|
|
358
|
+
└── utils/
|
|
359
|
+
├── selector.ts # 选择器解析
|
|
360
|
+
├── config.ts # 配置管理
|
|
361
|
+
├── errors.ts # 错误处理
|
|
362
|
+
└── logger.ts # 日志
|
|
163
363
|
```
|
|
164
364
|
|
|
165
|
-
## 🔒 安全
|
|
166
|
-
|
|
167
|
-
- Session 目录权限 700(仅用户可访问)
|
|
168
|
-
- `evaluate` 命令禁止危险操作(require, process, fs 等)
|
|
169
|
-
- UserData 独立隔离,不影响系统 Chrome
|
|
170
|
-
|
|
171
365
|
## 📊 技术栈
|
|
172
366
|
|
|
173
367
|
- **Bun** 1.2.21 - JavaScript 运行时
|
|
@@ -176,21 +370,68 @@ src/
|
|
|
176
370
|
- **Zod** 3.25.76 - 数据验证
|
|
177
371
|
- **Biome** 1.9.4 - 代码规范
|
|
178
372
|
|
|
373
|
+
## 🛠️ 开发
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# 克隆仓库
|
|
377
|
+
git clone https://github.com/hubo1989/hyper-agent-browser.git
|
|
378
|
+
cd hyper-agent-browser
|
|
379
|
+
|
|
380
|
+
# 安装依赖
|
|
381
|
+
bun install
|
|
382
|
+
|
|
383
|
+
# 开发模式运行
|
|
384
|
+
bun dev -- --headed open https://google.com
|
|
385
|
+
|
|
386
|
+
# 运行测试
|
|
387
|
+
bun test
|
|
388
|
+
|
|
389
|
+
# 类型检查
|
|
390
|
+
bun run typecheck
|
|
391
|
+
|
|
392
|
+
# 代码规范检查
|
|
393
|
+
bun run lint
|
|
394
|
+
|
|
395
|
+
# 构建
|
|
396
|
+
bun run build # 当前平台
|
|
397
|
+
bun run build:all # 所有平台
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
## 📚 文档
|
|
401
|
+
|
|
402
|
+
- [GETTING_STARTED.md](./GETTING_STARTED.md) - 快速入门指南
|
|
403
|
+
- [ELEMENT_REFERENCE_GUIDE.md](./ELEMENT_REFERENCE_GUIDE.md) - @eN 引用完整文档
|
|
404
|
+
- [GOOGLE_PROFILE_GUIDE.md](./GOOGLE_PROFILE_GUIDE.md) - Google Profile 集成
|
|
405
|
+
- [CLAUDE.md](./CLAUDE.md) - 开发者文档
|
|
406
|
+
- [hyper-agent-browser-spec.md](./hyper-agent-browser-spec.md) - 技术规格
|
|
407
|
+
- [Skill 文档](./skills/hyper-browser.md) - Claude Code Skill 说明
|
|
408
|
+
|
|
179
409
|
## 🤝 贡献
|
|
180
410
|
|
|
181
411
|
欢迎 Pull Requests!请确保:
|
|
182
412
|
|
|
183
|
-
- TypeScript 类型检查通过:`bun run typecheck`
|
|
184
|
-
- 测试通过:`bun test`
|
|
185
|
-
- 代码规范检查通过:`bun run lint`
|
|
413
|
+
- ✅ TypeScript 类型检查通过:`bun run typecheck`
|
|
414
|
+
- ✅ 测试通过:`bun test`
|
|
415
|
+
- ✅ 代码规范检查通过:`bun run lint`
|
|
186
416
|
|
|
187
417
|
## 📄 许可证
|
|
188
418
|
|
|
189
|
-
MIT
|
|
419
|
+
[MIT](./LICENSE)
|
|
420
|
+
|
|
421
|
+
## 🔗 相关链接
|
|
422
|
+
|
|
423
|
+
- **npm 包**: https://www.npmjs.com/package/hyper-agent-browser
|
|
424
|
+
- **GitHub**: https://github.com/hubo1989/hyper-agent-browser
|
|
425
|
+
- **Issues**: https://github.com/hubo1989/hyper-agent-browser/issues
|
|
426
|
+
- **Releases**: https://github.com/hubo1989/hyper-agent-browser/releases
|
|
190
427
|
|
|
191
428
|
## 🙏 致谢
|
|
192
429
|
|
|
193
430
|
- [Patchright](https://github.com/Patchright/patchright) - 反检测 Playwright fork
|
|
194
431
|
- [agent-browser](https://github.com/anthropics/agent-browser) - CLI 设计灵感
|
|
195
432
|
- [Bun](https://bun.sh) - 快速的 JavaScript 运行时
|
|
433
|
+
- [Claude Code](https://claude.ai/code) - AI 编程助手
|
|
434
|
+
|
|
435
|
+
---
|
|
196
436
|
|
|
437
|
+
**Made with ❤️ for AI Agents**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hyper-agent-browser",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pure browser automation CLI for AI Agents - 纯浏览器自动化 CLI,专为 AI Agent 设计",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/cli.ts",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"repository": {
|
|
43
43
|
"type": "git",
|
|
44
|
-
"url": "https://github.com/hubo1989/hyper-agent-browser.git"
|
|
44
|
+
"url": "git+https://github.com/hubo1989/hyper-agent-browser.git"
|
|
45
45
|
},
|
|
46
46
|
"bugs": {
|
|
47
47
|
"url": "https://github.com/hubo1989/hyper-agent-browser/issues"
|
package/src/browser/manager.ts
CHANGED
|
@@ -29,10 +29,26 @@ export class BrowserManager {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async connect(): Promise<void> {
|
|
32
|
+
// 清理可能存在的无效状态
|
|
33
|
+
if (this.page?.isClosed()) {
|
|
34
|
+
this.page = null;
|
|
35
|
+
}
|
|
36
|
+
if (this.context) {
|
|
37
|
+
try {
|
|
38
|
+
// 检查 context 是否有效
|
|
39
|
+
this.context.pages();
|
|
40
|
+
} catch {
|
|
41
|
+
this.context = null;
|
|
42
|
+
this.browser = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
32
46
|
// Try to reconnect to existing browser via CDP
|
|
33
47
|
if (this.session.wsEndpoint && (await this.isBrowserRunning())) {
|
|
34
48
|
try {
|
|
35
|
-
this.browser = await chromium.connectOverCDP(this.session.wsEndpoint
|
|
49
|
+
this.browser = await chromium.connectOverCDP(this.session.wsEndpoint, {
|
|
50
|
+
timeout: 5000, // 5 秒超时,避免长时间等待
|
|
51
|
+
});
|
|
36
52
|
const contexts = this.browser.contexts();
|
|
37
53
|
|
|
38
54
|
if (contexts.length > 0) {
|
|
@@ -51,10 +67,19 @@ export class BrowserManager {
|
|
|
51
67
|
this.page.setDefaultTimeout(this.options.timeout);
|
|
52
68
|
}
|
|
53
69
|
|
|
70
|
+
// 监听页面关闭事件
|
|
71
|
+
this.page.on("close", () => {
|
|
72
|
+
this.page = null;
|
|
73
|
+
});
|
|
74
|
+
|
|
54
75
|
console.log(`Reconnected to existing browser (PID: ${this.session.pid})`);
|
|
55
76
|
return;
|
|
56
77
|
} catch (error) {
|
|
57
78
|
console.error("Failed to reconnect, launching new browser:", error);
|
|
79
|
+
// 清理失败的连接状态
|
|
80
|
+
this.browser = null;
|
|
81
|
+
this.context = null;
|
|
82
|
+
this.page = null;
|
|
58
83
|
}
|
|
59
84
|
}
|
|
60
85
|
|
|
@@ -145,6 +170,20 @@ export class BrowserManager {
|
|
|
145
170
|
this.page.setDefaultTimeout(this.options.timeout);
|
|
146
171
|
}
|
|
147
172
|
|
|
173
|
+
// 监听页面关闭事件,自动清理状态
|
|
174
|
+
this.page.on("close", () => {
|
|
175
|
+
console.log("Page closed, clearing state");
|
|
176
|
+
this.page = null;
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// 监听 context 关闭事件
|
|
180
|
+
this.context.on("close", () => {
|
|
181
|
+
console.log("Context closed, clearing all state");
|
|
182
|
+
this.browser = null;
|
|
183
|
+
this.context = null;
|
|
184
|
+
this.page = null;
|
|
185
|
+
});
|
|
186
|
+
|
|
148
187
|
// @ts-ignore - Browser has process and wsEndpoint methods
|
|
149
188
|
const pid = this.browser?.process?.()?.pid;
|
|
150
189
|
// @ts-ignore
|
|
@@ -286,7 +325,13 @@ export class BrowserManager {
|
|
|
286
325
|
}
|
|
287
326
|
|
|
288
327
|
async getPage(): Promise<Page> {
|
|
289
|
-
|
|
328
|
+
// 检查 page 是否有效
|
|
329
|
+
if (!this.page || this.page.isClosed()) {
|
|
330
|
+
// 清理旧状态
|
|
331
|
+
this.browser = null;
|
|
332
|
+
this.context = null;
|
|
333
|
+
this.page = null;
|
|
334
|
+
// 重新连接
|
|
290
335
|
await this.connect();
|
|
291
336
|
}
|
|
292
337
|
return this.page!;
|
|
@@ -316,7 +361,20 @@ export class BrowserManager {
|
|
|
316
361
|
}
|
|
317
362
|
|
|
318
363
|
isConnected(): boolean {
|
|
319
|
-
|
|
364
|
+
if (!this.context || !this.page) {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// 真正检查连接是否有效
|
|
369
|
+
try {
|
|
370
|
+
// 检查 page 是否已关闭
|
|
371
|
+
if (this.page.isClosed()) {
|
|
372
|
+
return false;
|
|
373
|
+
}
|
|
374
|
+
return true;
|
|
375
|
+
} catch {
|
|
376
|
+
return false;
|
|
377
|
+
}
|
|
320
378
|
}
|
|
321
379
|
|
|
322
380
|
// Inject visual indicator for agent operations
|