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 CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  **纯浏览器自动化 CLI,专为 AI Agent 设计**
4
4
 
5
+ [![npm version](https://img.shields.io/npm/v/hyper-agent-browser.svg)](https://www.npmjs.com/package/hyper-agent-browser)
5
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)](https://www.typescriptlang.org/)
6
7
  [![Bun](https://img.shields.io/badge/Bun-%3E%3D1.1.0-orange.svg)](https://bun.sh)
7
8
  [![License](https://img.shields.io/badge/license-MIT-green.svg)](./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
- git clone https://github.com/yourusername/hyper-agent-browser.git
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
- bun dev -- --headed open https://google.com
55
+ # 1. 打开网页(有头模式,可以看到浏览器)
56
+ hab --headed open https://google.com
35
57
 
36
58
  # 2. 获取可交互元素快照
37
- bun dev -- snapshot -i
38
-
39
- # 输出:
40
- # @e1 [textbox] "Search"
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 [link] "Gmail"
68
+ # @e3 [button] "I'm Feeling Lucky"
69
+ # @e4 [link] "Gmail"
70
+ # @e5 [link] "Images"
43
71
 
44
72
  # 3. 使用 @eN 引用操作元素
45
- bun dev -- fill @e1 "Bun JavaScript runtime"
46
- bun dev -- press Enter
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
- # 4. 截图
49
- bun dev -- screenshot -o result.png
82
+ # 6. 获取页面内容
83
+ hab content
50
84
  ```
51
85
 
52
- ### 使用已登录的 Google Profile
86
+ ### Session 管理(多账号隔离)
53
87
 
54
88
  ```bash
55
- # 导入 Chrome Profile(保留登录状态)
56
- ./scripts/import-chrome-profile.sh -s gmail
89
+ # 个人 Gmail 账号
90
+ hab -s personal-gmail open https://mail.google.com
91
+ hab -s personal-gmail snapshot -i
57
92
 
58
- # 使用已登录状态访问 Gmail
59
- bun dev -- -s gmail --headed open https://mail.google.com
60
- bun dev -- -s gmail snapshot -i
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
- - [GETTING_STARTED.md](./GETTING_STARTED.md) - 快速入门指南
66
- - [ELEMENT_REFERENCE_GUIDE.md](./ELEMENT_REFERENCE_GUIDE.md) - @eN 引用完整文档
67
- - [GOOGLE_PROFILE_GUIDE.md](./GOOGLE_PROFILE_GUIDE.md) - Google Profile 集成
68
- - [CLAUDE.md](./CLAUDE.md) - 开发者文档
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 click 'css=button.MuiButton-root.MuiButton-contained'
124
+ # 启动网络监听
125
+ LISTENER_ID=$(hab network-start --filter xhr,fetch --url-pattern "*/api/*" | jq -r '.listenerId')
80
126
 
81
- # hyper-agent-browser 方式(简单)
82
- hab snapshot -i # 生成引用
83
- hab click @e5 # 使用引用
84
- ```
127
+ # 执行操作(翻页/点击等)
128
+ hab click @e5
129
+ hab wait-idle
85
130
 
86
- ### Session 管理
131
+ # 停止监听并获取所有 API 数据
132
+ hab network-stop $LISTENER_ID > api_data.json
133
+ ```
87
134
 
88
- 每个 session 独立的浏览器环境:
135
+ ### 智能等待(新增)
89
136
 
90
137
  ```bash
91
- # 个人账号
92
- bun dev -- -s personal open https://mail.google.com
138
+ # 等待页面完全空闲(网络 + DOM)
139
+ hab wait-idle --timeout 30000
93
140
 
94
- # 工作账号
95
- bun dev -- -s work open https://mail.google.com
141
+ # 等待元素可见
142
+ hab wait-element "css=.data-row" --state visible
96
143
 
97
- # 列出所有 session
98
- bun dev -- sessions
144
+ # 等待加载动画消失
145
+ hab wait-element "css=.loading" --state detached
99
146
  ```
100
147
 
101
- ### 支持的命令
148
+ ## 📖 完整命令列表
102
149
 
103
- **导航**: `open`, `reload`, `back`, `forward`
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
- ```bash
111
- # 运行测试
112
- bun test
159
+ ### 操作命令
113
160
 
114
- # 类型检查
115
- bun run typecheck
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
- bun run build # 当前平台
122
- bun run build:all # 所有平台
123
- ```
185
+ | 命令 | 说明 | 示例 |
186
+ |------|------|------|
187
+ | `sessions` | 列出所有 Session | `hab sessions` |
188
+ | `close [-s <name>]` | 关闭 Session | `hab close -s gmail` |
189
+
190
+ ### 全局选项
124
191
 
125
- ## 🤖 AI Agent 集成
192
+ | 选项 | 说明 | 默认值 |
193
+ |------|------|--------|
194
+ | `-s, --session <name>` | 指定 Session 名称 | `default` |
195
+ | `--headed` | 有头模式(显示浏览器) | `false` |
196
+ | `--channel <chrome\|msedge>` | 浏览器类型 | `chrome` |
197
+ | `--timeout <ms>` | 超时时间 | `30000` |
126
198
 
127
- hyper-agent-browser 专为 AI Agent 设计。安装 Skill 文件:
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
- 1. Agent 打开网页:`hab open <url>`
136
- 2. Agent 获取快照:`hab snapshot -i`
137
- 3. Agent 分析快照,找到目标元素 `@eN`
138
- 4. Agent 执行操作:`hab click @eN`
139
- 5. 重复直到任务完成
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
- | `@eN` | `@e1`, `@e5` | 元素引用(推荐) |
146
- | `css=` | `css=#login` | CSS 选择器 |
147
- | `text=` | `text=Sign in` | 文本匹配 |
148
- | `xpath=` | `xpath=//button` | XPath |
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
- ├── session/ # Session 持久化
157
- ├── commands/ # 命令实现
158
- ├── snapshot/ # 元素引用系统
159
- │ ├── accessibility.ts # Accessibility API
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.1.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"
@@ -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
- if (!this.page) {
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
- return this.browser !== null && this.page !== null;
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