# https://github.com/jo-inc/camofox-browser 项目说明书

生成时间：2026-05-30 22:29:34 UTC

## 目录

- [项目概览](#page-overview)
- [系统架构](#page-architecture)
- [安装与快速开始](#page-installation)
- [反检测机制](#page-anti-detection)
- [会话管理](#page-session-management)
- [API 参考](#page-api-reference)
- [插件系统](#page-plugin-system)
- [搜索宏](#page-macros)
- [部署指南](#page-deployment)
- [配置参考](#page-configuration)

<a id='page-overview'></a>

## 项目概览

### 相关页面

相关主题：[反检测机制](#page-anti-detection), [系统架构](#page-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/jo-inc/camofox-browser/blob/main/README.md)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/openapi.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/openapi.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [lib/reporter.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/reporter.js)
- [lib/extract.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/extract.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)

</details>

# 项目概览

## 简介

Camofox Browser 是一个专为 AI 代理设计的反检测浏览器自动化服务器，基于 Firefox 内核（Camoufox 引擎）构建。该项目提供了一套完整的浏览器控制 API，支持无头浏览器操作、页面交互、内容提取等自动化任务，同时集成了多项反检测技术，能够有效绕过 Google Captcha 等常见的反爬虫机制。

Camofox Browser 的核心价值在于为 AI 代理提供稳定、可靠的浏览器控制能力，使用户能够在不触发网站反爬虫机制的情况下完成网页浏览、数据抓取、表单填写等操作。资料来源：[AGENTS.md]()

## 系统架构

Camofox Browser 采用模块化架构设计，主要包含以下几个核心模块：

```mermaid
graph TD
    A[客户端请求] --> B[server.js 路由层]
    B --> C{请求类型}
    C -->|Tab 操作| D[Tab 管理模块]
    C -->|Session 操作| E[Session 管理模块]
    C -->|Browser 操作| F[Browser 管理模块]
    C -->|内容提取| G[Extract 模块]
    D --> H[Camoufox 引擎]
    E --> H
    F --> H
    G --> H
    H --> I[浏览器实例]
    I --> J[网页内容]
    
    K[插件系统] --> H
    L[事件系统] --> B
    M[OpenAPI 文档] --> B
```

### 核心模块职责

| 模块 | 文件位置 | 职责说明 |
|------|----------|----------|
| 服务器入口 | `server.js` | 处理所有 HTTP API 请求，路由分发 |
| 浏览器启动器 | `lib/launcher.js` | 管理浏览器实例的启动和生命周期 |
| 内容提取 | `lib/extract.js` | 提供结构化数据提取功能 |
| 插件系统 | `lib/plugins.js` | 插件加载、事件钩子管理 |
| 报告器 | `lib/reporter.js` | 崩溃和挂起报告的收集与上报 |
| OpenAPI | `lib/openapi.js` | API 文档自动生成 |

资料来源：[server.js](), [lib/openapi.js](), [lib/extract.js]()

## 技术栈与依赖

Camofox Browser 使用以下核心技术栈：

```mermaid
graph LR
    A[运行时] --> B[Node.js]
    A --> C[Camoufox 内核]
    B --> D[Express.js]
    B --> E[Playwright API]
    C --> F[Firefox]
    
    G[API 文档] --> H[swagger-jsdoc]
    G --> I[swagger-stripey]
```

### 主要技术依赖

| 类别 | 技术 | 用途 |
|------|------|------|
| 运行时 | Node.js | 服务器运行环境 |
| 浏览器引擎 | Camoufox | 基于 Firefox 的反检测浏览器 |
| Web 框架 | Express.js | HTTP API 服务 |
| API 文档 | swagger-jsdoc + swagger-stripey | 自动生成 API 文档 |
| 监控 | Prometheus 指标 | 健康检查和性能监控 |

## API 系统

### OpenAPI 规范

Camofox Browser 采用 OpenAPI 3.0.3 规范管理 API。所有路由通过 `@openapi` JSDoc 注释自动生成规范文件，文档可通过 `GET /docs` 访问 API 的 Swagger UI 界面。资料来源：[lib/openapi.js:1-30]()

### API 标签分类

API 按功能划分为以下标签组：

| 标签 | 功能范围 |
|------|----------|
| System | 系统状态、健康检查 |
| Tabs | 标签页生命周期管理 |
| Navigation | 页面导航操作 |
| Interaction | 用户交互操作 |
| Content | 内容提取和快照 |
| Sessions | 会话管理 |
| Browser | 浏览器控制 |
| Legacy | 兼容性遗留接口 |

资料来源：[AGENTS.md]()

### 主要 API 端点

| 方法 | 路径 | 功能 |
|------|------|------|
| GET | `/health` | 健康状态检查 |
| POST | `/tabs` | 创建新标签页 |
| GET | `/tabs/:tabId` | 获取标签页信息 |
| POST | `/tabs/:tabId/click` | 点击页面元素 |
| POST | `/tabs/:tabId/type` | 向输入框输入文本 |
| POST | `/tabs/:tabId/navigate` | 导航到指定 URL |
| POST | `/tabs/:tabId/screenshot` | 页面截图 |
| POST | `/tabs/:tabId/snapshot` | 获取无障碍快照 |
| DELETE | `/tabs/:tabId` | 关闭标签页 |

资料来源：[server.js]()

## 会话管理

### 用户隔离机制

Camofox Browser 通过 `userId` 参数实现用户间的 cookies 和存储隔离，确保不同用户的数据完全独立。资料来源：[AGENTS.md]()

```mermaid
graph TD
    A[用户请求] --> B{userId 验证}
    B -->|有效| C[获取/创建 Session]
    B -->|无效| D[返回 400 错误]
    C --> E{Session 存在?}
    E -->|是| F[复用现有 Session]
    E -->|否| G[创建新 Session]
    F --> H[执行操作]
    G --> H
    H --> I[Session 超时检查]
    I -->|30分钟无活动| J[销毁 Session]
```

### 会话配置

| 参数 | 说明 | 默认值 |
|------|------|--------|
| `userId` | 用户唯一标识 | 必需 |
| `sessionKey` | 会话分组键 | 可选 |
| `listItemId` | 列表项 ID（兼容性） | 可选 |
| 超时时间 | 无活动会话自动销毁 | 30 分钟 |

## 事件系统

Camofox Browser 内置完整的事件系统，支持同步和异步两种事件模式。资料来源：[lib/plugins.js]()

### 事件类型分类

#### Tab 生命周期事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:created` | `{ userId, tabId, page, url }` | 新标签页创建 |
| `tab:navigated` | `{ userId, tabId, url, prevUrl }` | 页面导航完成 |
| `tab:destroyed` | `{ userId, tabId, reason }` | 标签页销毁 |
| `tab:recycled` | `{ userId, tabId }` | 标签页回收复用 |
| `tab:error` | `{ userId, tabId, error }` | 标签页错误 |

#### 内容事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:snapshot` | `{ userId, tabId, snapshot }` | 无障碍快照生成 |
| `tab:screenshot` | `{ userId, tabId, buffer }` | 页面截图完成 |
| `tab:evaluate` | `{ userId, tabId, expression }` | JavaScript 执行 |
| `tab:evaluated` | `{ userId, tabId, result }` | 执行结果返回 |

#### 输入事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:click` | `{ userId, tabId, ref, selector }` | 元素点击 |
| `tab:type` | `{ userId, tabId, text, ref, mode }` | 文本输入 |
| `tab:scroll` | `{ userId, tabId, direction, amount }` | 页面滚动 |
| `tab:press` | `{ userId, tabId, key }` | 键盘按键 |

### 事件钩子模式

事件系统支持两种模式：

1. **异步钩子**（`events.emitAsync()`）：用于 `browser:launching`、`session:creating`、`session:created`、`session:destroyed`，服务器会等待所有监听器完成后再继续执行
2. **同步事件**（`events.emit()`）：用于其他所有事件，采用即发即忘模式

资料来源：[AGENTS.md]()

## 插件系统

Camofox Browser 支持插件扩展，通过事件钩子机制允许插件在关键生命周期节点执行自定义逻辑。资料来源：[scripts/plugin.js]()

### 插件管理命令

| 命令 | 功能 |
|------|------|
| `node scripts/plugin.js install <source>` | 从 Git URL 或本地路径安装插件 |
| `node scripts/plugin.js remove <name>` | 卸载指定插件 |
| `node scripts/plugin.js list` | 列出已安装插件 |

### 插件安装来源

- Git URL：`git:github.com/user/repo` 或 `https://github.com/user/repo`
- 本地路径：`./path/to/local/plugin`

资料来源：[scripts/plugin.js]()

## 崩溃报告系统

Camofox Browser 内置 `lib/reporter.js` 模块，负责收集和上报崩溃及事件循环停滞信息。资料来源：[lib/reporter.js]()

### 报告的环境信息

| 字段 | 说明 |
|------|------|
| `version` | Camofox 版本号 |
| `node` | Node.js 版本 |
| `platform` | 操作系统平台 |
| `uptime` | 服务器运行时间（分钟） |
| `node RSS` | 节点内存占用 |
| `browser contexts` | 浏览器上下文数量 |
| `active tabs` | 活跃标签页数量 |

### 已知问题：事件循环停滞

社区反馈显示，部分用户在运行过程中会遇到事件循环停滞（Event loop stalled）问题：

| 问题类型 | 阈值 | 社区报告案例数 |
|----------|------|----------------|
| stuck:event-loop | 5 秒 | 12+ 个案例 |
| 最大停滞时间 | 74 秒 | 最严重案例 |

受影响版本包括 v1.6.0、v1.7.2、v1.7.3，主要发生在 macOS 和 Linux 平台。该问题会导致浏览器操作无响应，但不会造成数据丢失。资料来源：[社区反馈 Issue #4860](https://github.com/jo-inc/camofox-browser/issues/4860)

## 配置与运行

### 环境变量

| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| `PORT` | 服务端口 | 9377 |
| `ENABLE_VNC` | 启用 VNC 远程查看 | 0 |
| `VNC_BIND` | VNC 绑定地址 | 0.0.0.0 |

### 运行方式

Camofox Browser 支持多种运行方式：

```bash
# 从源码运行
npm start
# 或使用运行脚本
./run.sh

# 从 npm 安装运行
npx @askjo/camofox-browser

# 全局安装
npm install -g @askjo/camofox-browser
camofox-browser
```

资料来源：[AGENTS.md](), [社区公告]()

### Docker 部署

Docker 容器支持通过环境变量配置，v1.10 版本可通过环境变量正确启用 VNC，但 v1.11 版本存在回归问题。资料来源：[Issue #4314](https://github.com/jo-inc/camofox-browser/issues/4314)

## 测试框架

| 测试类型 | 命令 | 说明 |
|----------|------|------|
| 全部测试 | `npm test` | 运行单元测试、端到端测试和插件测试 |
| 插件测试 | `npm run test:plugins` | 仅运行插件相关测试 |
| 端到端测试 | `npm run test:e2e` | 端到端功能测试 |
| 实时测试 | `npm run test:live` | 真实 Google 网站测试 |

资料来源：[AGENTS.md]()

## Schema 验证

内容提取模块提供了 Schema 验证功能，确保提取的数据符合预定义结构。资料来源：[lib/extract.js]()

### 支持的数据类型

| 类型 | 说明 |
|------|------|
| `string` | 字符串类型 |
| `number` | 浮点数类型 |
| `integer` | 整数类型 |
| `boolean` | 布尔类型 |
| `object` | 对象类型 |
| `null` | 空值类型 |

### 验证规则

- 顶层 schema 必须为 `type: object`
- 每个属性必须定义为对象格式
- 属性可指定 `type`，未指定时默认为字符串

## 快速开始

1. **安装依赖**
   ```bash
   npm install
   ```

2. **启动服务**
   ```bash
   npm start
   ```

3. **验证健康状态**
   ```bash
   curl http://localhost:9377/health
   ```

4. **创建标签页并导航**
   ```bash
   curl -X POST http://localhost:9377/tabs \
     -H "Content-Type: application/json" \
     -d '{"userId": "agent1"}'
   ```

5. **访问 API 文档**
   ```
   http://localhost:9377/docs

---

<a id='page-architecture'></a>

## 系统架构

### 相关页面

相关主题：[项目概览](#page-overview), [会话管理](#page-session-management), [API 参考](#page-api-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/launcher.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/launcher.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [lib/reporter.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/reporter.js)
- [lib/openapi.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/openapi.js)
- [lib/extract.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/extract.js)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
</details>

# 系统架构

camofox-browser 是一个基于 Node.js 的反检测浏览器自动化服务器，专为 AI 代理设计。它通过 RESTful API 提供无头浏览器控制能力，支持会话隔离、代理轮换、Cookie 导入和结构化日志等企业级功能。

## 核心组件概览

```mermaid
graph TD
    Client["AI 代理客户端"]
    Server["Express HTTP Server<br/>(port 9377)"]
    Browser["Camoufox Browser<br/>(Firefox 核心)"]
    Sessions["Session Manager"]
    Plugins["Plugin System"]
    Events["Event Emitter"]
    Reporter["Crash/Hang Reporter"]
    
    Client -->|"REST API"| Server
    Server --> Browser
    Server --> Sessions
    Server --> Events
    Sessions --> Browser
    Plugins --> Server
    Events --> Plugins
    Reporter --> Events
    
    subgraph "server.js"
        Server
        Sessions
        Events
    end
    
    subgraph "lib/"
        Plugins
        Reporter
    end
```

### 组件职责

| 组件 | 文件位置 | 职责 |
|------|----------|------|
| HTTP Server | `server.js` | 处理所有 REST API 请求，路由分发 |
| Browser Engine | `lib/launcher.js` | 启动和管理 Camoufox (Firefox) 无头浏览器 |
| Session Manager | `server.js` (内嵌) | 用户会话隔离、标签页分组、超时管理 |
| Plugin System | `lib/plugins.js` | 生命周期钩子、插件安装/卸载 |
| Event System | `lib/plugins.js` (内嵌) | 组件间事件通信 |
| Crash Reporter | `lib/reporter.js` | 崩溃/挂起自动上报 |
| OpenAPI Docs | `lib/openapi.js` | API 文档自动生成 |

## 服务器架构

### 技术栈

- **运行环境**: Node.js (v22+)
- **Web 框架**: Express.js
- **浏览器引擎**: Camoufox (基于 Firefox 的反检测浏览器)
- **API 规范**: OpenAPI 3.0.3 (通过 swagger-jsdoc 自动生成)
- **文档 UI**: swagger-stripey (三栏式界面)

### 架构层次

```mermaid
graph LR
    subgraph "表现层"
        OpenAPI["OpenAPI Docs UI<br/>/docs"]
        JSON["/openapi.json"]
    end
    
    subgraph "路由层"
        Tabs["Tabs Routes<br/>/tabs/:tabId/*"]
        Sessions["Sessions Routes<br/>/sessions/:userId/*"]
        Browser["Browser Routes<br/>/browser/*"]
        System["System Routes<br/>/health, /metrics"]
    end
    
    subgraph "业务逻辑层"
        Auth["authMiddleware()"]
        Limits["withUserLimit()"]
        TabLock["withTabLock()"]
        Timeout["withTimeout()"]
    end
    
    subgraph "浏览器控制层"
        Launcher["Browser Launcher"]
        Context["Browser Contexts"]
        Page["Pages/Tabs"]
    end
    
    OpenAPI -->|"spec"| JSON
    JSON --> Tabs
    JSON --> Sessions
    JSON --> Browser
    JSON --> System
    
    Tabs --> Auth
    Sessions --> Auth
    Tabs --> Limits
    Tabs --> TabLock
    Tabs --> Timeout
    TabLock --> Page
    Limits --> Context
    Context --> Launcher
```

### API 路由分类

| 分类 (Tag) | 路由前缀 | 功能描述 |
|------------|----------|----------|
| System | `/health`, `/metrics` | 健康检查、指标采集 |
| Tabs | `/tabs/:tabId/*` | 标签页生命周期管理 |
| Navigation | `/tabs/:tabId/navigate` | 页面导航 |
| Interaction | `/tabs/:tabId/click`, `/type`, `/scroll` | 用户交互 |
| Content | `/tabs/:tabId/snapshot`, `/screenshot` | 内容获取 |
| Sessions | `/sessions/:userId/*` | 会话管理 |
| Browser | `/browser/*` | 浏览器控制 |
| Legacy | 早期兼容路由 | 向后兼容 |

## 浏览器引擎架构

### Camoufox 启动流程

```mermaid
sequenceDiagram
    participant Server as server.js
    participant Launcher as lib/launcher.js
    participant Browser as Camoufox Browser
    participant Context as Browser Context
    
    Server->>Launcher: ensureBrowser()
    Launcher->>Launcher: 检查浏览器实例
    alt 浏览器未启动或断开
        Launcher->>Launcher: 检测环境 (Docker/WSL2/Fly.io)
        Launcher->>Browser: launchBrowser(options)
        Browser-->>Launcher: browser instance
        Launcher-->>Server: 返回浏览器引用
    end
    
    Server->>Context: createBrowserContext(userId)
    Context-->>Server: context with独立存储
```

### 浏览器上下文隔离

每个用户会话 (`userId`) 拥有独立的浏览器上下文，实现以下隔离：

| 隔离维度 | 实现方式 |
|----------|----------|
| Cookies | 独立 cookie 存储 |
| LocalStorage | 独立存储区域 |
| 代理设置 | 按会话配置 |
| User-Agent | 可定制 |

资料来源：[AGENTS.md:60-75]()

## 会话管理架构

### 会话生命周期

```mermaid
stateDiagram-v2
    [*] --> Created: 创建新用户会话
    Created --> Active: 首次访问
    Active --> Active: 持续操作
    Active --> Idle: 30分钟无活动
    Idle --> Active: 恢复使用
    Idle --> Expired: 超时
    Expired --> [*]
    Active --> [*]: 主动销毁
```

### 会话数据结构

```javascript
sessions = Map<userId, {
  id: string,
  lastAccess: number,      // 时间戳
  tabGroups: Map<sessionKey, Set<tabId>>,
  context: BrowserContext,
  ...
}>
```

| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | string | 会话唯一标识 |
| `lastAccess` | number | 最后访问时间戳 |
| `tabGroups` | Map | 按 sessionKey 分组的标签页 |
| `context` | BrowserContext | 浏览器上下文 |

### 标签页管理

```mermaid
graph TD
    TabGroup["TabGroup<br/>(sessionKey)"]
    Tab1["Tab e1"]
    Tab2["Tab e2"]
    Tab3["Tab e3"]
    
    TabGroup --> Tab1
    TabGroup --> Tab2
    TabGroup --> Tab3
    
    TabState["TabState"]
    TabState --> Page["page (Playwright)"]
    TabState --> NavigateAbort["navigateAbort"]
    TabState --> ToolCalls["toolCalls"]
    TabState --> ConsecutiveTimeouts["consecutiveTimeouts"]
    TabState --> ConsecutiveFailures["consecutiveFailures"]
    
    Tab1 --> TabState
    Tab2 --> TabState
    Tab3 --> TabState
```

## 事件系统架构

### 事件分类

| 事件类型 | 触发时机 | 同步方式 |
|----------|----------|----------|
| `browser:launching` | 浏览器启动前 | `emitAsync()` |
| `session:creating` | 会话创建前 | `emitAsync()` |
| `session:created` | 会话创建后 | `emitAsync()` |
| `session:destroyed` | 会话销毁时 | `emitAsync()` |
| `tab:created` | 标签页创建 | `emit()` |
| `tab:navigated` | 页面导航完成 | `emit()` |
| `tab:click` | 点击操作 | `emit()` |
| `tab:type` | 输入操作 | `emit()` |
| `server:starting` | 服务器启动 | `emit()` |

### Mutating Hooks

Mutating hooks 允许插件在操作前修改配置对象：

```javascript
// 修改 Xvfb 分辨率 (用于 VNC 插件)
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});
```

资料来源：[lib/plugins.js:32-50]()

## 插件系统架构

### 插件管理器

```mermaid
graph LR
    subgraph "scripts/plugin.js"
        Install["install 命令"]
        Remove["remove 命令"]
        List["list 命令"]
    end
    
    subgraph "lib/plugins.js"
        Load["插件加载"]
        Hooks["事件钩子注册"]
        Deps["依赖安装"]
    end
    
    Install --> Load
    Remove --> Load
    Load --> Hooks
    Load --> Deps
```

### 插件安装流程

```bash
node scripts/plugin.js install <source>
# source 支持:
#   - git:github.com/user/repo
#   - https://github.com/user/repo
#   - ./path/to/local/plugin
```

### 插件生命周期钩子

| 钩子名称 | 传入参数 | 说明 |
|----------|----------|------|
| `browser:launching` | `{ options }` | 修改浏览器启动参数 |
| `session:creating` | `{ userId, contextOptions }` | 修改上下文配置 |
| `session:created` | `{ userId, context }` | 会话创建完成 |
| `session:destroyed` | `{ userId, reason }` | 会话销毁 |

## 错误处理与监控

### 健康检查端点

`GET /health` 返回系统状态：

```json
{
  "ok": true,
  "engine": "camoufox",
  "browserConnected": true,
  "browserRunning": true,
  "activeTabs": 5,
  "activeSessions": 3,
  "consecutiveFailures": 0,
  "memory": {
    "rssMb": 42,
    "heapUsedMb": 66,
    "nativeMemMb": 36
  }
}
```

资料来源：[server.js:150-175]()

### 崩溃/挂起报告

`lib/reporter.js` 实现自动上报机制：

| 检测类型 | 阈值 | 报告内容 |
|----------|------|----------|
| Event Loop 阻塞 | 5秒 | 阻塞时长、平台、版本、内存使用 |

**社区问题关联**: 社区中存在多个 `stuck:event-loop` 问题报告（#4863, #4862, #4860 等），显示 Event Loop 阻塞是已知问题，用户应注意长时运行任务对事件循环的影响。

### 速率限制

| 限制类型 | 实现 | 说明 |
|----------|------|------|
| 用户级限制 | `withUserLimit()` | 防止单用户过度使用 |
| 标签页锁 | `withTabLock()` | 防止并发操作同一标签页 |
| 超时控制 | `withTimeout()` | 防止操作无限等待 |

## 数据提取验证

`lib/extract.js` 提供 schema 验证功能：

```javascript
validateSchema(schema) → { ok: boolean, error?: string }
```

| 支持类型 | 说明 |
|----------|------|
| `string` | 字符串 |
| `number` | 浮点数 |
| `integer` | 整数 |
| `boolean` | 布尔值 |
| `object` | 对象 |
| `null` | 空值 |

## API 文档自动生成

### OpenAPI 规范生成流程

```mermaid
graph TD
    JSDoc["@openapi JSDoc 注释"]
    swagger["swagger-jsdoc"]
    spec["openapi.json"]
    UI["swagger-stripey UI"]
    Docs["/docs"]
    JSON["/openapi.json"]
    
    JSDoc --> swagger
    swagger --> spec
    spec --> UI
    spec --> JSON
    UI --> Docs
    JSON --> JSON
```

### JSDoc 注释规范

```javascript
/**
 * @openapi
 * /tabs/{tabId}/click:
 *   post:
 *     tags: [Interaction]
 *     summary: Click an element
 *     parameters:
 *       - name: tabId
 *         in: path
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [userId]
 *     responses:
 *       200:
 *         description: Click result.
 */
app.post('/tabs/:tabId/click', async (req, res) => { ... });
```

| 规范要求 | 说明 |
|----------|------|
| 路径参数 | 使用 `{tabId}` 而非 `:tabId` |
| tags | 必须是预定义的分类之一 |
| summary | 必须提供 |
| responses | 必须包含响应定义 |

资料来源：[AGENTS.md:15-45]()

## 环境适配

### 平台检测

服务器自动检测运行环境并调整配置：

| 环境 | 检测特征 | 适配措施 |
|------|----------|----------|
| Docker | 容器环境变量 | VNC 配置、headless 模式 |
| Fly.io | `FLY_MACHINE_ID` | 特殊内存管理 |
| WSL2 | Windows/Linux 混合 | 虚拟显示配置 |
| 普通 Linux | 标准环境 | 默认配置 |

### 环境变量配置

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `PORT` | 9377 | HTTP 服务端口 |
| `ENABLE_VNC` | 0 | 启用 VNC |
| `VNC_BIND` | 0.0.0.0 | VNC 绑定地址 |

**社区问题关联**: Docker VNC 回归问题（#4314）表明环境变量检测在 1.11 版本中存在变化，用户遇到 VNC 无法从环境变量激活的情况。

## 安全性

### 中间件链

```mermaid
graph LR
    Request["HTTP Request"]
    Auth["authMiddleware()"]
    RateLimit["速率限制"]
    ErrorHandler["错误处理"]
    Route["Route Handler"]
    
    Request --> Auth
    Auth --> RateLimit
    RateLimit --> ErrorHandler
    ErrorHandler --> Route
```

### 认证机制

| 端点类型 | 认证要求 |
|----------|----------|
| 状态查询 | 可选 |
| 数据获取 | `userId` 参数 |
| 敏感操作 | 中间件认证 |
| 追踪文件 | `authMiddleware()` |

## 性能优化

### 内存管理

健康检查返回内存指标：

```javascript
memory: {
  rssMb: 42,        // 进程总内存
  heapUsedMb: 66,   // V8 堆使用
  nativeMemMb: 36   // 原生内存 (RSS - Heap)
}
```

### 并发控制

| 策略 | 实现 | 目的 |
|------|------|------|
| 用户限制 | 令牌桶算法 | 防止资源耗尽 |
| 标签页锁 | Mutex | 操作原子性 |
| 浏览器池 | 连接复用 | 降低启动开销 |

## 扩展阅读

- [API 参考文档](./API-Reference.md) - 完整 API 端点说明
- [插件开发指南](./Plugins.md) - 如何开发自定义插件
- [部署指南](./Deployment.md) - Docker、Fly.io 部署配置
- [故障排除](./Troubleshooting.md) - 常见问题与解决方案

---

<a id='page-installation'></a>

## 安装与快速开始

### 相关页面

相关主题：[部署指南](#page-deployment), [配置参考](#page-configuration)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [package.json](https://github.com/jo-inc/camofox-browser/blob/main/package.json)
- [Dockerfile](https://github.com/jo-inc/camofox-browser/blob/main/Dockerfile)
- [Makefile](https://github.com/jo-inc/camofox-browser/blob/main/Makefile)
- [build.ps1](https://github.com/jo-inc/camofox-browser/blob/main/build.ps1)
- [scripts/postinstall.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/postinstall.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)
- [README.md](https://github.com/jo-inc/camofox-browser/blob/main/README.md)
</details>

# 安装与快速开始

## 项目概述

camofox-browser 是一个面向 AI Agent 的反检测浏览器自动化服务器，提供无头浏览器控制、辅助功能快照、元素引用、会话隔离、Cookie 导入、代理轮换和结构化日志等功能。服务默认监听端口 `9377`。

## 系统要求

| 组件 | 要求 | 说明 |
|------|------|------|
| Node.js | v20+ | 推荐 v22 或更高版本 |
| 平台 | Linux / macOS / Windows | 支持 Docker 跨平台部署 |
| 浏览器引擎 | Firefox (camoufox) | 默认引擎，支持反检测 |
| 内存 | 最低 512MB RAM | 视并发量而定 |

> 注意：社区反馈在 WSL2 环境下运行可能出现屏幕闪烁问题（每 3 分钟一次），这是已知问题，暂无解决方案。

## 安装方式

### 方式一：NPM 全局安装（推荐）

从 v1.11.2 起，npm 包直接安装可执行文件：

```bash
# 临时运行
npx @askjo/camofox-browser

# 全局安装
npm install -g @askjo/camofox-browser
camofox-browser
```

全局安装后，默认端口为 `9377`，可通过相同环境变量配置。

### 方式二：Docker 安装

Docker 镜像提供开箱即用的环境，预装默认插件依赖：

```bash
# 运行最新版本
docker run --rm -it -p 9377:9377 \
  ghcr.io/jo-inc/camofox-browser:latest

# 带 VNC 支持（需 v1.10.x，v1.11 存在回归问题）
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  -e ENABLE_VNC=1 -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:1.10.0

# 验证 VNC 激活
curl -4I localhost:6080
# HTTP/1.1 200 OK
```

> **已知问题**：v1.11 版本中 VNC 无法通过环境变量激活，请关注 [Issue #4314](https://github.com/jo-inc/camofox-browser/issues/4314)。

### 方式三：源码安装

```bash
# 克隆仓库
git clone https://github.com/jo-inc/camofox-browser.git
cd camofox-browser

# 安装依赖
npm install

# 构建 camoufox 引擎
npm run build:camoufox
```

构建完成后，使用以下命令启动：

```bash
npm start
# 或
./run.sh
```

## 快速开始

### 基本工作流程

```mermaid
graph TD
    A[启动服务] --> B{安装方式}
    B -->|NPM| C[camofox-browser]
    B -->|Docker| D[docker run]
    B -->|源码| E[npm start]
    C --> F[服务就绪<br/>localhost:9377]
    D --> F
    E --> F
    F --> G[创建会话]
    G --> H[开启 Tab]
    H --> I[导航到网页]
    I --> J[获取快照]
    J --> K[交互操作]
```

### 首次使用示例

**1. 启动服务**

```bash
npm start
# 输出: Server started on port 9377
```

**2. 创建新 Tab 并导航**

```bash
# 创建 Tab
curl -X POST http://localhost:9377/tabs \
  -H "Content-Type: application/json" \
  -d '{"userId": "agent1", "sessionKey": "task1"}'

# 导航到 Google
curl -X POST http://localhost:9377/tabs/{tabId}/navigate \
  -H "Content-Type: application/json" \
  -d '{"userId": "agent1", "macro": "@google_search", "query": "test"}'
```

**3. 获取页面快照**

```bash
curl "http://localhost:9377/tabs/{tabId}/snapshot?userId=agent1"
```

返回元素引用（如 `e1`, `e2`），用于后续交互。

**4. 执行交互操作**

```bash
# 点击元素
curl -X POST http://localhost:9377/tabs/{tabId}/click \
  -H "Content-Type: application/json" \
  -d '{"userId": "agent1", "ref": "e1"}'

# 输入文本
curl -X POST http://localhost:9377/tabs/{tabId}/type \
  -H "Content-Type: application/json" \
  -d '{"userId": "agent1", "ref": "e2", "text": "hello world"}'
```

## 环境变量配置

| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| `PORT` | `9377` | 服务监听端口 |
| `ENABLE_VNC` | `0` | 启用 VNC 远程查看 |
| `VNC_BIND` | `127.0.0.1` | VNC 绑定地址 |
| `PROXY` | - | HTTP 代理地址 |
| `CAMOUFOX_HEADLESS` | `1` | 无头模式 |

配置方式：
- Docker: `-e VAR=value`
- 源码: 在 `.env` 文件中设置

## 插件管理

camofox-browser 支持插件扩展：

```bash
# 安装插件（从 Git 或本地路径）
node scripts/plugin.js install git:github.com/user/repo
node scripts/plugin.js install ./path/to/local/plugin

# 列出已安装插件
node scripts/plugin.js list

# 移除插件
node scripts/plugin.js remove <plugin-name>
```

安装插件后需重启服务。

## 验证安装

### 运行测试套件

```bash
# 所有测试（单元 + E2E + 插件）
npm test

# 仅插件测试
npm run test:plugins

# E2E 测试
npm run test:e2e

# 实时 Google 测试
npm run test:live
```

### 健康检查

```bash
curl http://localhost:9377/health
# 或访问 API 文档
curl http://localhost:9377/docs
```

## 常见问题

| 问题 | 解决方案 |
|------|----------|
| VNC 在 v1.11 不工作 | 使用 v1.10.0 或等待修复 |
| WSL2 屏幕闪烁 | 暂无解决方案，是已知问题 |
| 插件更新失败 | 检查模块路径，参考 [Issue #54](https://github.com/jo-inc/camofox-browser/issues/54) |
| Event loop 阻塞 | 检查超时配置，常见于高负载场景 |

## 下一步

- [API 参考](./api-reference) - 完整的 REST API 文档
- [插件开发](./plugins) - 开发自定义插件
- [事件系统](./events) - 订阅和处理浏览器事件

---

<a id='page-anti-detection'></a>

## 反检测机制

### 相关页面

相关主题：[项目概览](#page-overview)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/reporter.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/reporter.js)
- [lib/extract.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/extract.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [lib/openapi.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/openapi.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
</details>

# 反检测机制

camofox-browser 是一个基于 Firefox 的反检测浏览器自动化服务器，专门设计用于帮助 AI 代理绕过网站的安全检测机制。本页面详细介绍 camofox-browser 的反检测技术架构、核心组件和扩展机制。

## 核心引擎：Camoufox

camofox-browser 默认使用 **Camoufox** 作为底层浏览器引擎。Camoufox 是基于 Firefox 的反检测浏览器，专门针对网站反爬虫和机器人检测机制进行了优化。

### 技术特点

| 特性 | 描述 |
|------|------|
| 渲染引擎 | Firefox (Gecko) |
| 反检测能力 | 内置浏览器指纹随机化 |
| Captcha 绕过 | 支持 Google Captcha 绕过 |
| 默认端口 | 9377 |
| 启动命令 | `npm start` 或 `./run.sh` |

资料来源：[AGENTS.md:运行引擎]()

## 事件循环健康监测

反检测机制不仅包括浏览器层面的防护，还包含服务器端的性能监控。当事件循环阻塞超过阈值时，系统会自动报告问题。

### 阻塞检测机制

```mermaid
graph TD
    A[事件循环监控] --> B{阻塞时间 > 阈值?}
    B -->|是| C[触发 stuck:event-loop 报告]
    B -->|否| D[继续正常监控]
    C --> E[匿名化错误数据]
    E --> F[上报至 crash-reporter]
    F --> G[创建 GitHub Issue]
```

### 阈值配置

| 参数 | 默认值 | 说明 |
|------|--------|------|
| 阈值 | 5秒 | 事件循环阻塞超过此时间触发警告 |
| 上报方式 | camofox-crash-reporter | 自动匿名报告 |

社区反馈表明，在高负载场景下（如长时间运行、大量并发标签页），事件循环可能出现 17s 至 74s 的阻塞情况。资料来源：[社区 Issue #4863](https://github.com/jo-inc/camofox-browser/issues/4863)

## 会话隔离机制

camofox-browser 通过 `userId` 实现用户间的 cookies 和存储隔离，这是防止检测的重要手段。

### 隔离策略

| 隔离维度 | 实现方式 |
|----------|----------|
| Cookies | 独立浏览器上下文 |
| LocalStorage | 按 userId 隔离 |
| SessionStorage | 按 userId 隔离 |
| 缓存 | 按 userId 隔离 |

### 会话生命周期

| 事件 | 触发时机 |
|------|----------|
| `session:created` | 创建新会话上下文 |
| `session:destroyed` | 显式销毁会话 |
| `session:expired` | 空闲 30 分钟后自动过期 |
| `session:cookies:import` | 导入 cookies |
| `session:storage:export` | 导出存储状态 |

资料来源：[lib/plugins.js:事件定义]()

## 浏览器上下文管理

### 上下文选项动态修改

通过 `session:creating` 钩子，插件可以在浏览器上下文创建前修改配置：

```javascript
events.on('session:creating', ({ userId, contextOptions }) => {
  // 修改 contextOptions
});
```

### 上下文创建流程

```mermaid
graph TD
    A[browser:launching 钩子] --> B[session:creating 钩子]
    B --> C[async 插件处理完成]
    C --> D[创建浏览器上下文]
    D --> E[session:created 事件]
    E --> F[上下文就绪]
```

## 标签页级隔离

每个标签页在独立的页面实例中运行，通过 `tabId` 进行标识和管理。

### 标签页事件流

| 事件 | 载荷数据 |
|------|----------|
| `tab:created` | userId, tabId, page, url |
| `tab:navigated` | userId, tabId, url, prevUrl |
| `tab:destroyed` | userId, tabId, reason |
| `tab:recycled` | userId, tabId |
| `tab:error` | userId, tabId, error |

资料来源：[lib/plugins.js:标签页事件]()

## 用户代理伪装

camofox-browser 通过以下方式伪装用户行为：

### 交互操作伪装

| 操作 | 事件触发 |
|------|----------|
| 点击 | `tab:click` |
| 输入文本 | `tab:type` |
| 滚动 | `tab:scroll` |
| 按键 | `tab:press` |

所有交互操作都会记录到 `tabState.toolCalls`，用于统计和监控。

### 点击操作的延迟预算机制

camofox-browser 实现了点击延迟预算机制，防止操作过快被检测：

```javascript
const remainingBudget = () => Math.max(0, budget - elapsed);
```

资料来源：[server.js:点击处理]()

## 插件扩展机制

camofox-browser 提供插件系统，允许用户扩展反检测能力。

### 插件命令

```bash
# 安装插件
node scripts/plugin.js install <git-url|local-path>

# 移除插件
node scripts/plugin.js remove <name>

# 列出插件
node scripts/plugin.js list
```

### 插件安装来源格式

| 格式 | 示例 |
|------|------|
| Git URL | `https://github.com/user/repo` |
| Git 简写 | `git:github.com/user/repo` |
| 本地路径 | `./path/to/local/plugin` |

资料来源：[scripts/plugin.js:插件命令]()

### 插件钩子类型

| 钩子类型 | 行为 | 示例 |
|----------|------|------|
| 同步钩子 | fire-and-forget | `tab:click`, `tab:type` |
| 异步钩子 | 等待所有监听器完成 | `browser:launching`, `session:creating` |

### 变异钩子示例

```javascript
// 修改 Xvfb 分辨率（用于 VNC 插件）
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});
```

## VNC 插件与反检测

VNC 插件允许用户实时查看浏览器画面，这在调试反检测行为时非常有用。

### 环境变量配置

| 变量 | 说明 |
|------|------|
| `ENABLE_VNC` | 启用 VNC |
| `VNC_BIND` | 绑定地址，默认 0.0.0.0 |

### Docker 部署

```bash
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  -e ENABLE_VNC=1 -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:1.10.0
```

**注意**：社区反馈 v1.11 版本存在 VNC 环境变量激活回归问题。资料来源：[社区 Issue #4314](https://github.com/jo-inc/camofox-browser/issues/4314)

## 健康状态监控

camofox-browser 提供健康检查端点，用于监控反检测机制的运行状态。

### 健康检查端点

```
GET /health
```

### 响应示例

```json
{
  "ok": true,
  "engine": "camoufox",
  "browserConnected": true,
  "browserRunning": true,
  "activeTabs": 5,
  "activeSessions": 2,
  "consecutiveFailures": 0,
  "memory": {
    "rssMb": 183,
    "heapUsedMb": 66,
    "nativeMemMb": 117
  }
}
```

### 状态说明

| 状态码 | 含义 |
|--------|------|
| 200 | 服务正常 |
| 503 | 正在恢复中 (`recovering: true`) |

## 反检测限制与已知问题

### Cloudflare Turnstile 挑战

当前版本的反检测机制在处理 Cloudflare Turnstile 挑战时存在限制：

> Cloudflare Turnstile challenges (used by sites like GunBroker, bet365, and others) cannot be bypassed with the current camofox-browser toolset even when using a residential proxy IP.

资料来源：[社区 Issue #40](https://github.com/jo-inc/camofox-browser/issues/40)

### 事件循环阻塞

在高负载长时间运行的场景中，事件循环可能出现显著阻塞：

| 报告版本 | 平台 | 阻塞时间 |
|----------|------|----------|
| v1.7.2 | darwin | 17s - 74s |
| v1.6.0 | darwin | 22s |
| v1.7.3 | linux | 6s |

资料来源：[社区 Issue #4860](https://github.com/jo-inc/camofox-browser/issues/4860)、[社区 Issue #4483](https://github.com/jo-inc/camofox-browser/issues/4483)

## 最佳实践

### 1. 合理的操作延迟

在模拟人类行为时，应使用合理的操作间隔：

- 页面加载后等待 1-3 秒再进行交互
- 点击之间添加随机延迟
- 避免连续快速操作

### 2. 会话管理

- 为不同任务使用不同的 `userId`
- 定期清理过期会话
- 监控活跃会话数量

### 3. 插件扩展

- 使用 VNC 插件调试反检测行为
- 通过 `session:creating` 钩子自定义上下文选项
- 避免安装来源不明的插件

### 4. 监控告警

- 定期检查 `/health` 端点
- 关注 `consecutiveFailures` 指标
- 配置事件循环阻塞阈值告警

## 相关资源

- [OpenAPI 文档](http://localhost:9377/docs) - 完整的 API 参考
- [Camoufox 官方文档](https://github.com/nicholas病患者/camoufox) - 底层浏览器引擎
- [插件开发指南](./plugins.md) - 如何开发自定义插件

---

<a id='page-session-management'></a>

## 会话管理

### 相关页面

相关主题：[API 参考](#page-api-reference), [系统架构](#page-architecture)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
- [lib/extract.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/extract.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)

> 注：以下文件未在当前检索上下文中直接获取，但其功能通过其他文件间接体现：
> - `lib/persistence.js` - 会话持久化存储
> - `lib/cookies.js` - Cookie 管理
> - `lib/proxy.js` - 代理配置
> - `lib/tracing.js` - 追踪管理
> - `lib/fly.js` - Fly.io 平台集成

</details>

# 会话管理

## 概述

camofox-browser 的会话管理是整个自动化浏览器的核心子系统，负责管理浏览器上下文（Browser Context）、标签页生命周期、用户资源限制以及会话级别的持久化状态。每一个会话（Session）对应一个独立的浏览器上下文，提供了完整的隔离环境，支持并发多用户访问和独立的代理配置。

会话管理器通过内存中的 `Map` 结构维护活跃会话，并结合事件驱动架构实现插件扩展和状态同步。

## 核心架构

### 会话存储结构

camofox 使用 JavaScript `Map` 数据结构存储会话实例：

```javascript
const sessions = new Map();
```

每个会话对象包含以下关键属性：

| 属性 | 类型 | 说明 |
|------|------|------|
| `userId` | `string` | 会话唯一标识符 |
| `lastAccess` | `number` | 最后访问时间戳（毫秒） |
| `tabGroups` | `Map` | 标签页分组管理 |
| `contextOptions` | `object` | 浏览器上下文配置 |
| `consecutiveFailures` | `number` | 连续失败计数 |

资料来源：[server.js]()

会话通过 `normalizeUserId()` 函数规范化用户 ID，确保大小写不敏感的查询一致性：

```javascript
const session = sessions.get(normalizeUserId(userId));
```

### 会话与标签页关系

```
┌─────────────────────────────────────────┐
│           Session (userId)               │
│  ┌─────────────────────────────────┐   │
│  │     TabGroup (listItemId)        │   │
│  │  ┌───────┐ ┌───────┐ ┌───────┐ │   │
│  │  │ Tab 1 │ │ Tab 2 │ │ Tab N │ │   │
│  │  └───────┘ └───────┘ └───────┘ │   │
│  └─────────────────────────────────┘   │
│  lastAccess: timestamp                 │
│  contextOptions: {...}                 │
└─────────────────────────────────────────┘
```

会话与标签页的层级关系：
- **会话层**：管理用户级别的配置、代理、Cookie 和资源限制
- **分组层**：通过 `listItemId` 组织相关标签页
- **标签页层**：独立的页面实例，包含 `page`、`tabState` 等

资料来源：[server.js]()（标签页删除逻辑）

## 会话生命周期

### 创建流程

会话创建通过 `POST /sessions` 路由触发，流程如下：

```mermaid
graph TD
    A[接收创建会话请求] --> B[验证 userId]
    B --> C{会话已存在?}
    C -->|是| D[返回现有会话]
    C -->|否| E[分配新会话 ID]
    E --> F[初始化 contextOptions]
    F --> G[触发 session:creating 事件]
    G --> H[调用 browser.newContext]
    H --> I[触发 session:created 事件]
    I --> J[注册到 sessions Map]
    J --> K[设置活跃会话指标]
```

关键事件钩子：

| 事件 | 触发时机 | 说明 |
|------|----------|------|
| `session:creating` | 创建上下文前 | 可修改 contextOptions |
| `session:created` | 上下文创建完成 | 可执行初始化操作 |

资料来源：[lib/plugins.js]()
资料来源：[AGENTS.md]()

### 销毁流程

会话销毁支持显式和隐式两种方式：

**显式销毁**：通过 `DELETE /sessions/:userId` 显式关闭会话
**隐式销毁**：会话空闲超时后自动清理

```javascript
// 关闭标签页时清理分组
if (found.group.size === 0) {
  session.tabGroups.delete(found.listItemId);
}
```

资料来源：[server.js]()

### 过期与清理机制

系统通过 `session:expired` 事件通知会话过期：

```javascript
// 事件载荷
{ userId, idleMs }
```

过期条件：
- 会话在配置的空闲时间（`IDLE_TIMEOUT_MS`）内无访问
- `lastAccess` 时间戳距离当前时间超过阈值

## 标签页管理

### 标签页数据结构

每个标签页在会话中以 `tabId` 为键存储，包含：

```javascript
{
  tabId: string,
  tabState: {
    page: Page,           // Playwright Page 对象
    toolCalls: number,    // 工具调用计数
    consecutiveTimeouts: number,    // 连续超时次数
    consecutiveFailures: number,    // 连续失败次数
    navigateAbort: AbortController, // 导航取消控制器
  },
  group: Set,      // 同组标签页集合
  listItemId: string, // 分组标识
}
```

资料来源：[server.js]()

### 标签页锁定机制

为防止并发操作冲突，系统实现了标签页级别的锁机制：

```javascript
await withTabLock(tabId, async () => {
  await tabState.page.keyboard.press(key);
});
```

锁队列深度通过 `refreshTabLockQueueDepth()` 更新，用于监控。

### 标签页删除

删除标签页时执行完整清理：

```javascript
if (found.tabState.navigateAbort) found.tabState.navigateAbort.abort();
await clearTabDownloads(found.tabState);
await safePageClose(found.tabState.page);
found.group.delete(req.params.tabId);
tabLocks.get(req.params.tabId)?.drain();
tabLocks.delete(req.params.tabId);
```

## 事件系统

### 会话事件

| 事件名 | 载荷 | 说明 |
|--------|------|------|
| `session:creating` | `{ userId, contextOptions }` | 创建前（可修改配置） |
| `session:created` | `{ userId, context }` | 创建完成 |
| `session:modifying` | `{ userId, contextOptions }` | 修改上下文选项 |
| `session:modified` | `{ userId, contextOptions }` | 修改完成 |
| `session:destroying` | `{ userId, reason }` | 销毁前 |
| `session:destroyed` | `{ userId, reason }` | 销毁完成 |
| `session:expired` | `{ userId, idleMs }` | 空闲超时 |

资料来源：[AGENTS.md]()

### 标签页事件

| 事件名 | 载荷 | 说明 |
|--------|------|------|
| `tab:created` | `{ userId, tabId, page, url }` | 标签页创建 |
| `tab:navigated` | `{ userId, tabId, url, prevUrl }` | 导航完成 |
| `tab:destroyed` | `{ userId, tabId, reason }` | 标签页关闭 |
| `tab:recycled` | `{ userId, tabId }` | 标签页复用 |
| `tab:error` | `{ userId, tabId, error }` | 错误发生 |

资料来源：[lib/plugins.js]()

### 异步钩子

以下事件通过 `events.emitAsync()` 触发，系统会等待所有监听器完成：

- `browser:launching`
- `session:creating`
- `session:created`
- `session:destroyed`

```javascript
// 示例：修改浏览器启动参数
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});
```

资料来源：[AGENTS.md]()

## 用户限制与配额

### 用户级限流

系统通过 `withUserLimit()` 函数实现用户级别的并发限制：

```javascript
const result = await withUserLimit(userId, () => withTimeout(...));
```

### 标签页操作计数器

每个标签页维护操作计数器，用于检测异常行为：

```javascript
tabState.toolCalls++;
tabState.consecutiveTimeouts = 0;
tabState.consecutiveFailures = 0;
```

连续失败/超时计数达到阈值后会触发告警。

## Cookie 与存储管理

### Cookie 导入

通过 `session:cookies:import` 事件导入 Cookie：

```javascript
events.on('session:cookies:import', ({ userId, count }) => {
  console.log(`Imported ${count} cookies for user ${userId}`);
});
```

### 存储状态导出

会话级别的存储状态可通过 `session:storage:export` 事件导出：

```javascript
events.on('session:storage:export', ({ userId }) => {
  // 导出 localStorage, sessionStorage 等
});
```

## 健康检查与会话状态

### 健康检查端点

`GET /health` 返回会话相关的健康指标：

```json
{
  "ok": true,
  "engine": "camoufox",
  "browserConnected": true,
  "browserRunning": true,
  "activeTabs": 5,
  "activeSessions": 2,
  "consecutiveFailures": 0,
  "memory": {
    "rssMb": 120,
    "heapUsedMb": 66,
    "nativeMemMb": 54
  }
}
```

资料来源：[server.js]()

### 恢复状态

系统支持恢复模式，当检测到问题时返回 503 状态：

```javascript
if (healthState.isRecovering) {
  return res.status(503).json({ ok: false, recovering: true });
}
```

## 插件集成

### 插件与会话交互

插件可以通过事件系统与会话管理深度集成：

```javascript
// 监听所有会话标签页事件
events.on('tab:navigated', ({ userId, tabId, url, prevUrl }) => {
  // 记录导航历史
});
```

### 插件命令

通过 `scripts/plugin.js` 管理会话相关的插件：

```bash
# 安装插件
node scripts/plugin.js install git:github.com/user/repo

# 列出已安装插件
node scripts/plugin.js list

# 移除插件
node scripts/plugin.js remove <name>
```

## 常见问题与排查

### Event Loop 阻塞

社区反馈中频繁出现的 `stuck:event-loop` 问题：

| 症状 | 可能原因 | 解决方案 |
|------|----------|----------|
| Event loop stalled for Xs | 页面 JavaScript 执行阻塞 | 检查目标网站的响应性 |
| 阈值：5s | Node.js 主线程繁忙 | 优化操作序列 |
| 高 RSS/Heap 使用 | 内存泄漏 | 重启会话清理资源 |

### 会话泄露

如果 `activeSessions` 持续增长但不下降：
1. 检查 `session:expired` 事件是否正常触发
2. 验证空闲超时配置
3. 检查客户端是否正确调用会话销毁接口

### 标签页无法关闭

关闭标签页时需要完整清理：
- 中止导航控制器
- 清除下载记录
- 安全关闭页面对象
- 清理标签页锁

## 配置参考

| 环境变量 | 说明 | 默认值 |
|----------|------|--------|
| `PORT` | 服务端口 | `9377` |
| `IDLE_TIMEOUT_MS` | 会话空闲超时 | 300000 (5分钟) |
| `MAX_TABS_PER_SESSION` | 每会话最大标签页数 | - |

## 源码索引

| 文件路径 | 主要职责 |
|----------|----------|
| `server.js` | 会话路由、生命周期管理 |
| `lib/plugins.js` | 事件系统与插件钩子 |
| `lib/cookies.js` | Cookie 导入导出 |
| `lib/persistence.js` | 会话状态持久化 |
| `lib/proxy.js` | 代理配置管理 |
| `lib/tracing.js` | 调试追踪管理 |

---

<a id='page-api-reference'></a>

## API 参考

### 相关页面

相关主题：[会话管理](#page-session-management), [搜索宏](#page-macros)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/openapi.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/openapi.js)
- [lib/extract.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/extract.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
- [lib/reporter.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/reporter.js)
</details>

# API 参考

## 概述

camofox-browser 提供了一套完整的 RESTful API，用于控制反检测浏览器自动化引擎。API 基于 OpenAPI 3.0.3 规范构建，支持通过标准 HTTP 请求与浏览器实例进行交互，实现页面导航、元素操作、内容提取、数据抓取等功能。

API 的核心设计理念是为 AI 代理提供可靠、可观测的浏览器控制接口。每个 API 端点都集成了以下特性：

- **会话隔离**：通过 `userId` 参数实现多用户资源隔离
- **并发控制**：使用 Tab 锁机制防止竞态条件
- **错误处理**：统一的错误响应格式和超时保护
- **事件驱动**：完整的插件事件系统用于扩展和监控

资料来源：[lib/openapi.js:1-30]()

## API 端点分类

API 端点按功能分为以下标签组：

| 标签 | 描述 | 端点数量 |
|------|------|----------|
| `System` | 系统状态和健康检查 | 2 |
| `Tabs` | 标签页管理和统计 | 2 |
| `Navigation` | 页面导航操作 | 3 |
| `Interaction` | 用户交互操作 | 4 |
| `Content` | 内容提取和快照 | 3 |
| `Sessions` | 会话管理 | 3 |
| `Browser` | 浏览器控制 | 2 |
| `Legacy` | 兼容遗留端点 | 若干 |

资料来源：[AGENTS.md:80-90]()

## 系统端点

### 健康检查

```
GET /health
```

返回服务器健康状态和浏览器运行信息。

**响应示例：**

```json
{
  "ok": true,
  "engine": "camoufox",
  "browserConnected": true,
  "browserRunning": true,
  "activeTabs": 5,
  "activeSessions": 3,
  "consecutiveFailures": 0,
  "memory": {
    "rssMb": 42,
    "heapUsedMb": 66,
    "nativeMemMb": 12
  }
}
```

当服务器处于恢复状态时，返回 503 状态码：

```json
{
  "ok": false,
  "recovering": true
}
```

资料来源：[server.js:health-endpoint]()

## 标签页操作

### 创建标签页

```
POST /tabs
```

创建新的浏览器标签页。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `contextOptions` | object | 否 | 浏览器上下文配置 |

### 获取标签页快照

```
GET /tabs/:tabId/snapshot
```

获取页面的可访问性快照，包含元素引用（ref）系统。

**查询参数：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |

**响应结构：**

```json
{
  "tabId": "tab_abc123",
  "url": "https://example.com",
  "title": "Example Page",
  "refs": {
    "e1": {
      "tag": "BUTTON",
      "text": "Submit",
      "rect": { "x": 100, "y": 200, "width": 80, "height": 40 }
    }
  }
}
```

### 标签页统计

```
GET /tabs/:tabId/stats
```

返回标签页元数据，包括 URL、工具调用计数、访问过的 URL、下载/失败计数。

资料来源：[server.js:tabs-stats-endpoint]()

### 关闭标签页

```
DELETE /tabs/:tabId
```

关闭指定标签页并释放相关资源。

**查询/请求体参数：**

| 参数 | 类型 | 位置 | 描述 |
|------|------|------|------|
| `userId` | string | query/body | 用户标识符 |

关闭操作会执行以下清理步骤：

1. 中止导航请求（如果存在）
2. 清除下载记录
3. 安全关闭页面
4. 移除 Tab 锁
5. 更新标签页组

资料来源：[server.js:tabs-delete-endpoint]()

## 导航操作

### 页面导航

```
POST /tabs/:tabId/navigate
```

导航到指定 URL 或执行搜索宏。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `url` | string | 否 | 目标 URL |
| `macro` | string | 否 | 搜索宏（如 `@google_search`） |
| `query` | string | 否 | 搜索查询 |
| `sessionKey` | string | 否 | 会话键 |
| `listItemId` | string | 否 | 列表项 ID |

### 前进/后退

```
POST /tabs/:tabId/forward
POST /tabs/:tabId/back
```

在浏览历史中前进或后退。

资料来源：[server.js:navigate-forward-endpoint]()

## 交互操作

### 点击元素

```
POST /tabs/:tabId/click
```

点击页面上的元素。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `ref` | string | 否* | 快照元素引用 |
| `selector` | string | 否* | CSS 选择器 |

*`ref` 和 `selector` 至少需要提供一个。

**执行流程：**

```mermaid
graph TD
    A[接收 click 请求] --> B[验证 userId 和 tabId]
    B --> C[检查 ref 或 selector]
    C --> D[定位元素]
    D --> E[执行点击]
    E --> F[获取点击后快照]
    F --> G[返回结果]
```

点击操作会重置 `consecutiveTimeouts` 和 `consecutiveFailures` 计数器。

资料来源：[server.js:tabs-click-endpoint]()

### 输入文本

```
POST /tabs/:tabId/type
```

向元素输入文本。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `ref` | string | 否 | 快照元素引用 |
| `selector` | string | 否 | CSS 选择器 |
| `text` | string | 是 | 要输入的文本 |
| `clear` | boolean | 否 | 输入前清空字段 |
| `submit` | boolean | 否 | 输入后按 Enter |

### 按键

```
POST /tabs/:tabId/press
```

模拟键盘按键。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `key` | string | 是 | 按键名称（如 `Enter`、`Escape`、`Tab`） |

### 滚动

滚动页面内容，支持方向和滚动量控制。

## 内容提取

### 结构化数据提取

```
POST /tabs/:tabId/extract
```

使用 JSON Schema 从页面提取结构化数据。

**请求体：**

| 参数 | 类型 | 必填 | 描述 |
|------|------|------|------|
| `userId` | string | 是 | 用户标识符 |
| `schema` | object | 是 | JSON Schema 定义 |

**Schema 格式示例：**

```json
{
  "type": "object",
  "properties": {
    "title": {
      "type": "string",
      "x-ref": "e5"
    },
    "price": {
      "type": "number",
      "x-ref": "e12"
    },
    "inStock": {
      "type": "boolean",
      "x-ref": "e8"
    }
  }
}
```

`x-ref` 字段指向快照中的元素引用。

**类型支持：**

| 类型 | 描述 | 转换规则 |
|------|------|----------|
| `string` | 字符串 | 去除首尾空白 |
| `number` | 浮点数 | 提取数字字符 |
| `integer` | 整数 | 提取整数部分 |
| `boolean` | 布尔值 | 解析文本逻辑 |
| `object` | 对象 | 递归处理 |
| `null` | 空值 | 返回 null |

**Schema 验证规则：**

1. 顶层 schema 必须 `type: object`
2. 必须包含 `properties` 对象
3. 每个属性必须是对象
4. 属性类型必须在支持列表中

资料来源：[lib/extract.js:1-60]()

### 页面评估

```
POST /tabs/:tabId/evaluate
```

在页面上下文中执行 JavaScript 表达式。

### 截图

```
GET /tabs/:tabId/screenshot
```

获取页面截图。

## 会话管理

### 获取会话追踪

```
GET /sessions/:userId/traces/:filename
```

下载会话追踪文件（ZIP 格式）。

**响应头：**

```
Content-Type: application/zip
Content-Length: <file_size>
```

**错误响应：**

| 状态码 | 描述 |
|--------|------|
| 400 | 无效的文件名 |
| 403 | 禁止访问 |
| 404 | 追踪文件不存在 |
| 500 | 服务器错误 |

### 会话追踪文件结构

追踪文件包含会话期间的详细操作日志，用于调试和性能分析。

资料来源：[server.js:sessions-traces-endpoint]()

## 认证机制

API 使用中间件进行认证控制：

```javascript
authMiddleware()
```

认证方式优先级：
1. API Key 在请求头中
2. 环回地址免认证（`127.0.0.1` / `localhost`）

资料来源：[AGENTS.md:100-110]()

## OpenAPI 文档

### 文档访问

| 端点 | 格式 | 用途 |
|------|------|------|
| `GET /openapi.json` | JSON | 机器可读的 OpenAPI 规范 |
| `GET /docs` | HTML | Swagger UI 交互式文档 |

### 规范生成

OpenAPI 规范通过 [swagger-jsdoc](https://github.com/Surnet/swagger-jsdoc) 从 `server.js` 中的 JSDoc `@openapi` 注释自动生成。

**JSDoc 注释规范：**

```javascript
/**
 * @openapi
 * /tabs/{tabId}/click:
 *   post:
 *     tags: [Interaction]
 *     summary: Click an element
 *     parameters:
 *       - name: tabId
 *         in: path
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [userId]
 *             properties:
 *               userId:
 *                 type: string
 *     responses:
 *       200:
 *         description: Click result.
 */
app.post('/tabs/:tabId/click', async (req, res) => {
  // ...
});
```

**生成命令：**

```bash
npm run generate-openapi
```

资料来源：[lib/openapi.js:1-45]()

## 插件事件系统

API 与插件系统深度集成，通过事件发射器提供钩子机制。

### 事件分类

#### 浏览器事件

| 事件名 | Payload | 描述 |
|--------|---------|------|
| `browser:launching` | `{ options }` | 浏览器启动前（可修改配置） |

#### 标签页事件

| 事件名 | Payload | 描述 |
|--------|---------|------|
| `tab:created` | `{ userId, tabId, page, url }` | 标签页创建 |
| `tab:navigated` | `{ userId, tabId, url, prevUrl }` | 标签页导航 |
| `tab:destroyed` | `{ userId, tabId, reason }` | 标签页销毁 |
| `tab:click` | `{ userId, tabId, ref, selector }` | 点击操作 |
| `tab:type` | `{ userId, tabId, text, ref, mode }` | 输入操作 |
| `tab:scroll` | `{ userId, tabId, direction, amount }` | 滚动操作 |
| `tab:press` | `{ userId, tabId, key }` | 按键操作 |

#### 内容事件

| 事件名 | Payload | 描述 |
|--------|---------|------|
| `tab:snapshot` | `{ userId, tabId, snapshot }` | 快照生成 |
| `tab:screenshot` | `{ userId, tabId, buffer }` | 截图生成 |

#### 下载事件

| 事件名 | Payload | 描述 |
|--------|---------|------|
| `tab:download:start` | `{ userId, tabId, filename, url }` | 下载开始 |
| `tab:download:complete` | `{ userId, tabId, filename, path, size }` | 下载完成 |

#### 服务器事件

| 事件名 | Payload | 描述 |
|--------|---------|------|
| `server:starting` | `{ port }` | 服务器启动中 |
| `server:started` | `{ port, pid }` | 服务器已启动 |
| `server:shutdown` | `{ signal }` | 服务器关闭 |

### 异步钩子

以下事件通过 `events.emitAsync()` 发射，服务器会等待所有监听器完成：

- `browser:launching`
- `session:creating`
- `session:created`
- `session:destroyed`

其他事件使用 `events.emit()`（即发即忘模式）。

### 事件使用示例

```javascript
// 监听标签页点击
events.on('tab:click', ({ userId, tabId, ref }) => {
  console.log(`User ${userId} clicked element ${ref} in tab ${tabId}`);
});

// 修改浏览器启动配置
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});
```

资料来源：[lib/plugins.js:event-system]()

## 错误处理

### 统一错误响应

所有端点使用统一的错误响应格式：

```json
{
  "error": "错误描述信息"
}
```

### 常见错误

| 状态码 | 错误类型 | 描述 |
|--------|----------|------|
| 400 | Bad Request | 缺少必需参数或参数格式错误 |
| 403 | Forbidden | 认证失败或权限不足 |
| 404 | Not Found | 标签页或资源不存在 |
| 500 | Internal Error | 服务器内部错误 |

### 安全错误处理

错误信息通过 `safeError()` 函数处理，防止敏感信息泄露：

```javascript
safeError(err) // 清理堆栈跟踪和内部路径
```

资料来源：[lib/reporter.js:error-sanitization]()

## 速率限制

### 用户并发限制

每个 `userId` 有独立的并发限制，防止资源滥用：

```javascript
withUserLimit(userId, async () => {
  // 执行操作
});
```

### Tab 锁

每个标签页使用独立的锁机制，确保操作顺序执行：

```javascript
withTabLock(tabId, async () => {
  // 执行操作
});
```

## 监控与可观测性

### Prometheus 指标

API 集成 Prometheus 指标收集：

| 指标名 | 类型 | 标签 | 描述 |
|--------|------|------|------|
| `failuresTotal` | Counter | `type`, `action` | 失败总数 |

### 健康状态追踪

服务器追踪以下健康指标：

- `consecutiveNavFailures`：连续导航失败次数
- `isRecovering`：是否处于恢复状态
- `activeTabs`：活跃标签页数量
- `activeSessions`：活跃会话数量

### 事件循环监控

社区反馈显示存在事件循环阻塞问题（阈值 5 秒），这可能导致 API 请求超时。

相关问题：[#4863](https://github.com/jo-inc/camofox-browser/issues/4863)、[#4483](https://github.com/jo-inc/camofox-browser/issues/4483)

## 客户端库

### CLI 二进制文件

从 v1.11.2 起，npm 包提供 `camofox-browser` 可执行文件：

```bash
# 直接运行
npx @askjo/camofox-browser

# 全局安装
npm install -g @askjo/camofox-browser
camofox-browser
```

默认端口：`9377`

### 环境变量配置

| 变量名 | 默认值 | 描述 |
|--------|--------|------|
| `PORT` | 9377 | 服务器监听端口 |
| `API_KEY` | - | API 认证密钥 |

## 最佳实践

### 请求组织

1. **先创建标签页**：使用 `POST /tabs` 创建新会话
2. **获取快照**：使用 `GET /tabs/:tabId/snapshot` 获取元素引用
3. **使用引用操作**：优先使用 `ref` 而非 CSS 选择器
4. **提取结构化数据**：使用 `POST /tabs/:tabId/extract` 进行数据抓取

### 错误恢复

1. 检查 `GET /health` 端点的 `recovering` 状态
2. 监控 `consecutiveFailures` 指标
3. 实现指数退避重试机制

### 性能优化

1. 复用标签页而非频繁创建销毁
2. 使用批量操作减少网络往返
3. 避免在单次请求中执行过多操作

## 相关文档

- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md) - 完整的事件系统文档
- [docs/api.html](https://github.com/jo-inc/camofox-browser/blob/main/docs/api.html) - Swagger UI 源码
- [openapi.json](https://github.com/jo-inc/camofox-browser/blob/main/openapi.json) - 完整的 OpenAPI 规范

---

<a id='page-plugin-system'></a>

## 插件系统

### 相关页面

相关主题：[项目概览](#page-overview), [API 参考](#page-api-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)
- [plugins/vnc/index.js](https://github.com/jo-inc/camofox-browser/blob/main/plugins/vnc/index.js)
- [plugins/vnc/vnc-launcher.js](https://github.com/jo-inc/camofox-browser/blob/main/plugins/vnc/vnc-launcher.js)
- [plugins/persistence/index.js](https://github.com/jo-inc/camofox-browser/blob/main/plugins/persistence/index.js)
- [plugins/youtube/index.js](https://github.com/jo-inc/camofox-browser/blob/main/plugins/youtube/index.js)
- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
</details>

# 插件系统

## 概述

camofox-browser 的插件系统是一个可扩展的模块化架构，允许开发者通过事件钩子（hooks）和生命周期回调来增强浏览器自动化服务器的功能。插件可以监听浏览器启动、会话创建、标签页操作等事件，并能够修改浏览器配置和会话选项。

插件系统基于 Node.js 的 EventEmitter 实现，支持同步和异步两种事件处理模式。核心插件包括 VNC（虚拟网络计算）远程可视化、持久化存储、以及 YouTube 特定功能扩展。

资料来源：[lib/plugins.js:1-50]()

## 架构设计

### 系统组件

```mermaid
graph TD
    A[camofox-browser 服务器] --> B[插件系统核心<br/>lib/plugins.js]
    B --> C[事件总线<br/>EventEmitter]
    B --> D[插件加载器]
    B --> E[钩子处理器]
    
    D --> F[VNC 插件]
    D --> G[Persistence 插件]
    D --> H[YouTube 插件]
    D --> I[自定义插件]
    
    C -->|tab:created| J1[Tab 生命周期]
    C -->|browser:launching| J2[Browser 生命周期]
    C -->|session:creating| J3[Session 生命周期]
    
    E -->|修改 options| K[传递给核心引擎]
```

### 事件分类

插件系统中的事件分为两类：**变异钩子（Mutating Hooks）** 和 **观察者钩子（Observer Hooks）**。

| 类别 | 事件名称 | 说明 |
|------|----------|------|
| 变异钩子 | `browser:launching` | 可修改浏览器启动选项 |
| 变异钩子 | `session:creating` | 可修改会话创建选项 |
| 变异钩子 | `session:created` | 异步等待，可执行初始化 |
| 变异钩子 | `session:destroyed` | 异步等待，可执行清理 |
| 观察者钩子 | `tab:*` | Tab 生命周期事件 |
| 观察者钩子 | `tab:snapshot` | 快照生成事件 |
| 观察者钩子 | `tab:screenshot` | 截图事件 |

资料来源：[lib/plugins.js:25-45]()

## 事件系统详解

### Tab 生命周期事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:created` | `{ userId, tabId, page, url }` | 新标签页创建 |
| `tab:navigated` | `{ userId, tabId, url, prevUrl }` | 标签页导航完成 |
| `tab:destroyed` | `{ userId, tabId, reason }` | 标签页关闭 |
| `tab:recycled` | `{ userId, tabId }` | 标签页被复用 |
| `tab:error` | `{ userId, tabId, error }` | 标签页发生错误 |

### 内容相关事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:snapshot` | `{ userId, tabId, snapshot }` | 可访问性快照生成 |
| `tab:screenshot` | `{ userId, tabId, buffer }` | 页面截图完成 |
| `tab:evaluate` | `{ userId, tabId, expression }` | JavaScript 表达式求值 |
| `tab:evaluated` | `{ userId, tabId, result }` | 求值结果返回 |

### 输入交互事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:click` | `{ userId, tabId, ref, selector }` | 元素点击 |
| `tab:type` | `{ userId, tabId, text, ref, mode }` | 文本输入 |
| `tab:scroll` | `{ userId, tabId, direction, amount }` | 页面滚动 |
| `tab:press` | `{ userId, tabId, key }` | 键盘按键 |

资料来源：[lib/plugins.js:35-55]()

### 下载与认证事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `tab:download:start` | `{ userId, tabId, filename, url }` | 下载开始 |
| `tab:download:complete` | `{ userId, tabId, filename, path, size }` | 下载完成 |
| `session:cookies:import` | `{ userId, count }` | Cookie 导入 |
| `session:storage:export` | `{ userId }` | 存储导出 |

### 服务器事件

| 事件名称 | 载荷 | 说明 |
|----------|------|------|
| `server:starting` | `{ port }` | 服务器启动中 |
| `server:started` | `{ port, pid }` | 服务器已启动 |
| `server:shutdown` | `{ signal }` | 服务器关闭 |

## 插件管理 CLI

插件管理通过 `node scripts/plugin.js` 命令行工具执行。

### 命令列表

| 命令 | 说明 | 用法 |
|------|------|------|
| `install` | 从 Git 或本地路径安装插件 | `plugin install <git-url\|local-path>` |
| `remove` | 移除已安装的插件 | `plugin remove <name>` |
| `list` | 列出所有已安装的插件 | `plugin list` |

### 安装插件

```bash
# 从 GitHub 安装
node scripts/plugin.js install git:github.com/user/repo
node scripts/plugin.js install https://github.com/user/repo

# 从本地路径安装
node scripts/plugin.js install ./path/to/local/plugin
```

安装过程会自动执行以下步骤：

1. 解析插件来源（Git URL 或本地路径）
2. 克隆/复制插件文件到 `plugins/` 目录
3. 安装插件依赖（`npm install`）
4. 更新配置文件记录新插件
5. 输出安装结果和重启提示

资料来源：[scripts/plugin.js:1-60]()

## 内置插件

### VNC 插件

VNC（Virtual Network Computing）插件提供基于 noVNC 的浏览器可视化访问能力。

#### 启动配置

| 环境变量 | 默认值 | 说明 |
|----------|--------|------|
| `ENABLE_VNC` | `0` | 启用 VNC 功能（设为 `1` 启用） |
| `VNC_BIND` | `127.0.0.1` | VNC 服务绑定地址 |
| `VNC_PORT` | `6080` | VNC WebSocket 端口 |
| `VNC_PASSWORD` | 无 | VNC 访问密码（可选） |

#### 已知问题

社区反馈 `#4314` 指出在 v1.11 版本中，VNC 无法通过环境变量正确激活：

```bash
# v1.10 工作正常
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  -e ENABLE_VNC=1 -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:1.10.0

# v1.11 环境变量不生效
```

此问题影响在 Docker 容器环境中使用 VNC 功能的需求。

资料来源：[plugins/vnc/index.js](), [plugins/vnc/vnc-launcher.js]()

### Persistence 插件

持久化插件用于在会话之间保存和恢复浏览器状态，包括 Cookie、LocalStorage 和会话存储。

| 功能 | 说明 |
|------|------|
| Cookie 持久化 | 跨会话保留登录状态 |
| Storage 导出 | 导出页面存储数据 |
| Storage 导入 | 恢复之前导出的存储 |

资料来源：[plugins/persistence/index.js]()

### YouTube 插件

YouTube 插件提供针对 YouTube 网站的特定功能扩展，包括播放控制、评论操作和播放列表管理。

资料来源：[plugins/youtube/index.js](), [plugins/youtube/youtube.js]()

## 插件开发指南

### 基本结构

一个典型的插件目录结构：

```
plugins/my-plugin/
├── index.js          # 插件入口，导出事件处理器
├── package.json      # 插件依赖定义
└── *.js              # 其他模块文件
```

### 插件入口格式

```javascript
// plugins/my-plugin/index.js
export default {
  name: 'my-plugin',
  version: '1.0.0',
  
  // 事件处理器
  onBrowserLaunching: async ({ options }) => {
    // 修改浏览器启动选项
    options.virtual_display_resolution = '1920x1080';
  },
  
  onTabCreated: async ({ userId, tabId, page, url }) => {
    // 监听新标签页创建
    console.log(`Tab ${tabId} created for ${userId}`);
  },
  
  onTabNavigated: async ({ userId, tabId, url, prevUrl }) => {
    // 监听页面导航
    if (url.includes('特定域名')) {
      // 执行特定逻辑
    }
  }
};
```

### 变异钩子示例

变异钩子允许插件修改传递给核心引擎的选项对象：

```javascript
// 修改 Xvfb 分辨率（用于 VNC 插件）
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});

// 修改会话创建参数
events.on('session:creating', ({ options }) => {
  options.extraHTTPHeaders = {
    'X-Custom-Header': 'value'
  };
});
```

资料来源：[AGENTS.md:1-50]()

### 异步钩子处理

部分钩子使用 `emitAsync()` 触发，服务器会等待所有监听器完成后再继续：

```javascript
// 这是一个异步钩子，服务器会等待完成
events.on('session:created', async ({ userId, context }) => {
  // 从磁盘加载存储状态
  const storageState = await loadStorageState(userId);
  await context.addInitScript({
    storage: storageState
  });
});
```

### 插件依赖安装

插件安装后会自动执行依赖安装：

```javascript
// 安装插件依赖
function installPluginDeps(name) {
  const pluginDir = join(pluginsDir, name);
  const pkgFile = join(pluginDir, 'package.json');
  
  if (existsSync(pkgFile)) {
    // 执行 npm install
    spawnSync('npm', ['install', '--silent'], {
      cwd: pluginDir,
      stdio: 'inherit'
    });
  }
}
```

## 配置管理

### 插件配置存储

已安装的插件信息存储在配置文件中：

```javascript
// 添加插件到配置
function addToConfig(name) {
  if (!CONFIG.plugins.includes(name)) {
    CONFIG.plugins.push(name);
    saveConfig();
  }
}
```

### 插件目录结构

| 目录 | 说明 |
|------|------|
| `plugins/` | 插件根目录 |
| `plugins/vnc/` | VNC 插件 |
| `plugins/persistence/` | 持久化插件 |
| `plugins/youtube/` | YouTube 插件 |

## 常见问题

### 模块未找到错误

社区 Issue `#54` 报告了插件更新失败的问题：

```
Failed to update camofox-browser: Error [ERR_MODULE_NOT_FOUND]: Cannot find module...
```

**解决方案**：

1. 确认插件的 `package.json` 配置正确
2. 检查模块路径是否使用相对路径
3. 运行 `npm install` 重新安装依赖

### VNC 在 Docker 中不工作

**问题**：v1.11 版本中环境变量 `ENABLE_VNC=1` 不生效

**临时解决方案**：

```bash
# 使用 v1.10 版本
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  ghcr.io/jo-inc/camofox-browser:1.10.0
```

### 插件加载失败

插件加载时会执行依赖安装，如果 `npm install` 失败，插件可能无法正常工作。建议检查：

1. Node.js 版本兼容性
2. 网络连接（需要访问 npm registry）
3. 文件系统权限

## 最佳实践

### 事件处理优化

| 实践 | 说明 |
|------|------|
| 避免阻塞操作 | 异步操作不要阻塞事件循环 |
| 错误处理 | 始终使用 try-catch 包装异步代码 |
| 资源清理 | 在 `session:destroyed` 中释放资源 |

### 内存管理

长时间运行的服务器需要注意插件的内存使用：

```javascript
// 定期清理不再使用的数据
events.on('session:destroyed', async ({ userId }) => {
  await clearUserCache(userId);
});
```

### 安全考虑

| 建议 | 说明 |
|------|------|
| 输入验证 | 验证事件载荷中的所有用户输入 |
| 沙箱隔离 | 避免在插件中执行不受信任的代码 |
| 最小权限 | 只请求必要的浏览器权限 |

## API 参考

### 事件载荷类型

| 类型名称 | 属性 |
|----------|------|
| `BrowserLaunchingPayload` | `options` |
| `SessionCreatingPayload` | `userId, contextOptions` |
| `SessionCreatedPayload` | `userId, context` |
| `TabCreatedPayload` | `userId, tabId, page, url` |
| `TabNavigatedPayload` | `userId, tabId, url, prevUrl` |
| `TabDestroyedPayload` | `userId, tabId, reason` |

### 钩子执行顺序

```mermaid
sequenceDiagram
    participant Server as 服务器
    participant Plugin as 插件系统
    participant Browser as 浏览器引擎
    
    Server->>Plugin: browser:launching (mutating)
    Plugin->>Browser: 修改后的 options
    Browser->>Server: 浏览器启动
    
    Server->>Plugin: session:creating (mutating)
    Plugin->>Server: 修改后的配置
    
    Server->>Plugin: session:created (async, await)
    Note over Plugin: 执行初始化逻辑
    Server->>Server: 会话就绪
    
    Loop 会话生命周期
        Server->>Plugin: tab:created
        Server->>Plugin: tab:navigated
        Server->>Plugin: tab:snapshot
        Server->>Plugin: tab:click / tab:type / tab:scroll
    end
    
    Server->>Plugin: session:destroyed (async, await)
    Note over Plugin: 执行清理逻辑
```

## 总结

camofox-browser 的插件系统提供了强大的扩展能力，通过事件驱动的架构，开发者可以在浏览器生命周期、会话管理和标签页操作的各个环节注入自定义逻辑。系统支持两种事件处理模式（同步和异步），并提供了变异钩子来修改核心引擎的配置选项。

内置插件涵盖了 VNC 可视化、持久化存储和 YouTube 功能等常见场景。插件管理 CLI 提供了便捷的安装、移除和列表查看功能。开发自定义插件时，需要注意遵循入口格式规范，正确处理异步操作，并做好错误处理和资源清理。

---

<a id='page-macros'></a>

## 搜索宏

### 相关页面

相关主题：[API 参考](#page-api-reference)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [AGENTS.md](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)
- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
</details>

# 搜索宏

搜索宏是 camofox-browser 提供的一种便捷语法，允许用户通过宏名称和查询词自动生成目标网站的搜索 URL，而无需手动构造复杂的搜索链接。

## 概述

搜索宏作为 `navigate` 接口的参数之一，配合 `query` 参数使用，可以自动解析并导航到对应搜索引擎的搜索结果页面。这种设计简化了 AI 代理与搜索引擎交互的流程，避免了直接处理 URL 编码和搜索参数拼接的复杂性。

资料来源：[server.js:navigate endpoint](https://github.com/jo-inc/camofox-browser/blob/main/server.js)

## 支持的搜索宏

camofox-browser 当前支持以下搜索宏：

| 宏名称 | 目标网站 | 说明 |
|--------|----------|------|
| `@google_search` | Google | 全球最大的搜索引擎 |
| `@youtube_search` | YouTube | 视频搜索 |
| `@amazon_search` | Amazon | 电商平台搜索 |
| `@reddit_search` | Reddit | 社区讨论搜索 |
| `@wikipedia_search` | Wikipedia | 维基百科知识库 |
| `@twitter_search` | Twitter/X | 社交媒体搜索 |
| `@yelp_search` | Yelp | 本地商家点评搜索 |
| `@linkedin_search` | LinkedIn | 职业社交搜索 |

资料来源：[AGENTS.md:Search Macros section](https://github.com/jo-inc/camofox-browser/blob/main/AGENTS.md)

## 使用方式

### API 调用

搜索宏通过 `POST /tabs/:tabId/navigate` 接口使用：

```bash
POST /tabs/:tabId/navigate
Content-Type: application/json

{
  "userId": "agent1",
  "macro": "@google_search",
  "query": "camofox browser automation"
}
```

请求参数说明：

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| userId | string | 是 | 用户标识符 |
| tabId | string | 是 | 目标标签页 ID |
| macro | string | 是 | 搜索宏名称（如 `@google_search`） |
| query | string | 是 | 搜索查询词 |
| sessionKey | string | 否 | 会话分组键 |
| listItemId | string | 否 | 列表项 ID（兼容性保留） |

资料来源：[server.js:navigate endpoint schema](https://github.com/jo-inc/camofox-browser/blob/main/server.js)

### 工作流程

```mermaid
graph TD
    A[客户端请求 navigate] --> B[解析 macro 参数]
    B --> C{检查 macro 格式}
    C -->|有效宏| D[根据宏名选择搜索引擎]
    C -->|无效或空| E[使用 url 参数直接导航]
    D --> F[拼接 query 参数]
    F --> G[编码生成搜索 URL]
    G --> H[浏览器导航到搜索结果]
```

## 最佳实践

### 元素引用稳定性

搜索宏导航后会生成新的页面快照，此时元素引用（如 `e1`, `e2`）会被重置。每次导航操作后需要重新调用 `/snapshot` 获取当前页面的元素引用。

### 搜索流程示例

```bash
# 1. 创建标签页
POST /tabs
# 返回: { tabId: "tab_abc123" }

# 2. 使用搜索宏导航
POST /tabs/tab_abc123/navigate
{
  "userId": "agent1",
  "macro": "@google_search",
  "query": "browser automation"
}

# 3. 获取快照（引用已更新）
GET /tabs/tab_abc123/snapshot?userId=agent1

# 4. 点击搜索结果
POST /tabs/tab_abc123/click
{
  "userId": "agent1",
  "ref": "e3"
}
```

### 会话隔离

搜索宏导航时会继承当前 `userId` 的会话上下文，包括 cookies、存储状态和代理设置。这确保了搜索行为的连续性和隐私隔离。

## 与直接 URL 的对比

| 特性 | 搜索宏 | 直接 URL |
|------|--------|----------|
| URL 编码 | 自动处理 | 需手动处理 |
| 搜索引擎切换 | 修改宏名即可 | 需重写整个 URL |
| 维护性 | 高 | 低 |
| 可读性 | 好 | 较差 |
| 灵活性 | 限于预设宏 | 支持任意 URL |

## 相关事件

搜索宏导航过程中会触发以下事件：

| 事件 | 载荷 | 说明 |
|------|------|------|
| `tab:navigated` | `{ userId, tabId, url, prevUrl }` | 导航完成时触发 |
| `tab:error` | `{ userId, tabId, error }` | 导航失败时触发 |

资料来源：[lib/plugins.js:Tab Lifecycle events](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)

## 限制与注意事项

1. **宏名称格式**：必须包含 `@` 前缀（如 `@google_search`），使用时会进行格式校验
2. **查询词编码**：特殊字符会自动进行 URL 编码，无需手动处理
3. **导航超时**：宏解析和导航操作受全局超时机制约束
4. **反爬虫检测**：即使使用搜索宏，目标网站仍可能触发反爬虫机制

## 扩展搜索宏

搜索宏的实现位于 `lib/macros.js`（如存在），可通过插件系统进行扩展。开发自定义宏需遵循以下约定：

- 宏名称必须以 `@` 开头
- 必须实现 URL 转换逻辑
- 需要处理查询词的编码转义

具体扩展方式可参考 AGENTS.md 中的搜索宏使用文档。

---

<a id='page-deployment'></a>

## 部署指南

### 相关页面

相关主题：[安装与快速开始](#page-installation), [配置参考](#page-configuration)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [Dockerfile](https://github.com/jo-inc/camofox-browser/blob/main/Dockerfile)
- [Dockerfile.ci](https://github.com/jo-inc/camofox-browser/blob/main/Dockerfile.ci)
- [Makefile](https://github.com/jo-inc/camofox-browser/blob/main/Makefile)
- [railway.toml](https://github.com/jo-inc/camofox-browser/blob/main/railway.toml)
- [fly.toml](https://github.com/jo-inc/camofox-browser/blob/main/fly.toml)
</details>

# 部署指南

本页面详细说明 camofox-browser 的各种部署方式、环境配置选项以及常见问题的解决方案。

## 部署方式概览

camofox-browser 支持多种部署方式，开发者可根据实际需求选择最适合的方案：

| 部署方式 | 适用场景 | 特点 |
|---------|---------|------|
| Docker | 生产环境、规模化部署 | 隔离性好、环境一致、内置 VNC 支持 |
| npm/npx | 快速测试、临时使用 | 安装便捷、无需 Docker |
| 源码运行 | 开发调试 | 可自定义修改 |
| Railway | 云原生部署 | 自动构建、PaaS 托管 |
| Fly.io | 边缘部署 | 全球分布式、低延迟 |

## Docker 部署

Docker 是生产环境推荐使用的部署方式，提供完整的功能支持和隔离环境。

### 使用预构建镜像

从 GitHub Container Registry 获取最新稳定版本：

```bash
docker run --rm -it -p 9377:9377 \
  ghcr.io/jo-inc/camofox-browser:latest
```

### 启用 VNC 支持

在 Docker 环境中启用 VNC 需要设置以下环境变量：

```bash
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  -e ENABLE_VNC=1 \
  -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:latest
```

验证 VNC 服务是否正常运行：

```bash
curl -4I localhost:6080
HTTP/1.1 200 OK
```

**已知问题：** 在 v1.11 版本中，VNC 无法通过环境变量正确激活，社区已报告此回归问题。资料来源：[#4314](https://github.com/jo-inc/camofox-browser/issues/4314)

### 持久化配置

将配置目录和数据卷挂载到宿主机：

```bash
docker run --rm -it -p 9377:9377 \
  -v $(pwd)/config:/app/config \
  -v $(pwd)/plugins:/app/plugins \
  -v $(pwd)/data:/app/data \
  ghcr.io/jo-inc/camofox-browser:latest
```

### 自定义构建

如需包含特定插件或自定义配置，可基于官方 Dockerfile 构建：

```dockerfile
FROM ghcr.io/jo-inc/camofox-browser:latest

# 安装额外插件
COPY plugins/* /app/plugins/

# 配置环境变量
ENV BROWSER_HEADLESS=false
ENV LOG_LEVEL=debug
```

## npm 部署

### 快速启动

使用 npx 直接运行，无需全局安装：

```bash
npx @askjo/camofox-browser
```

### 全局安装

将 CLI 工具全局安装到系统：

```bash
npm install -g @askjo/camofox-browser
camofox-browser
```

默认端口为 `9377`，可通过环境变量配置。

## 平台部署

### Railway 部署

camofox-browser 原生支持 Railway 平台部署，配置通过 `railway.toml` 管理：

```toml
[build]
builder = "NIXPACKS"
buildCommand = "npm install && npm run build"

[deploy]
healthcheckPath = "/health"
restartPolicyType = "ON_FAILURE"
restartPolicyLimit = 10
```

Railway 会自动检测项目类型并配置构建环境。资料来源：[railway.toml:1-10]()

### Fly.io 部署

对于 Fly.io 平台，配置由 `fly.toml` 定义：

```toml
app = "camofox-browser"
primary_region = "iad"

[build]
  builder = "heroku/buildpacks:20"

[env]
  PORT = "8080"
  METAL = "true"

[http_service]
  internal_port = 8080
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]
```

资料来源：[fly.toml:1-15]()

部署到 Fly.io：

```bash
fly launch
fly deploy
```

## 环境变量配置

camofox-browser 通过环境变量控制运行时行为，以下是主要配置项：

| 变量名 | 默认值 | 说明 |
|-------|-------|------|
| `PORT` | `9377` | HTTP 服务监听端口 |
| `HOST` | `0.0.0.0` | 监听地址 |
| `LOG_LEVEL` | `info` | 日志级别：debug/info/warn/error |
| `ENABLE_VNC` | `0` | 启用 VNC 支持 |
| `VNC_BIND` | `127.0.0.1` | VNC 绑定地址 |
| `BROWSER_HEADLESS` | `true` | 无头模式运行 |
| `MAX_CONCURRENT_SESSIONS` | `10` | 最大并发会话数 |
| `SESSION_TIMEOUT_MS` | `1800000` | 会话超时（30分钟） |

### VNC 相关配置

| 变量名 | 说明 |
|-------|------|
| `VNC_PASSWORD` | VNC 连接密码（可选） |
| `VNC_RESOLUTION` | 虚拟显示分辨率，如 `1920x1080` |

## 源码部署

### 依赖要求

- Node.js v22+
- npm v10+
- Linux/macOS（部分功能在 Windows WSL2 中有限制）

### 构建步骤

```bash
# 克隆仓库
git clone https://github.com/jo-inc/camofox-browser.git
cd camofox-browser

# 安装依赖
npm install

# 构建
npm run build

# 启动
npm start
# 或使用运行脚本
./run.sh
```

### Makefile 自动化

项目提供 Makefile 简化常见操作：资料来源：[Makefile]()

```bash
make install    # 安装依赖
make build     # 构建项目
make start     # 启动服务
make test      # 运行测试
make clean     # 清理构建产物
```

## 故障排除

### 事件循环停滞

频繁报告的问题是事件循环停滞（Event loop stalled），表现为操作超时：

```
stuck:event-loop: Event loop stalled for 17s (threshold: 5s)
```

**原因分析：**
- 长时间运行的浏览器实例内存占用过高
- 并发会话过多导致资源耗尽
- 网络请求阻塞事件循环

**解决方案：**
1. 监控内存使用：关注 `node heap` 和 `node RSS` 指标
2. 限制并发会话数量，设置合理的 `MAX_CONCURRENT_SESSIONS`
3. 定期重启服务以释放资源
4. 社区报告显示此问题在 v1.7.2-v1.7.3 版本中较为常见

资料来源：[#4863](https://github.com/jo-inc/camofox-browser/issues/4863)、[#4483](https://github.com/jo-inc/camofox-browser/issues/4483)

### WSL2 屏幕闪烁

在 Windows 11 的 WSL2 环境中运行可能遇到屏幕每3分钟闪烁一次的问题，伴随 Tux 图标任务短暂出现。资料来源：[#64](https://github.com/jo-inc/camofox-browser/issues/64)

### Docker 构建失败

如需自动化 Docker 构建作为发布流程的一部分，社区已有相关功能请求。资料来源：[#525](https://github.com/jo-inc/camofox-browser/issues/525)

## 生产环境建议

### 资源规划

| 指标 | 建议值 |
|-----|-------|
| 内存 | 至少 2GB RAM |
| CPU | 2 核以上 |
| 磁盘 | 10GB 以上可用空间 |
| Node.js 版本 | v22+ |

### 监控指标

建议监控以下指标：
- HTTP 请求延迟
- 事件循环阻塞时间
- 浏览器堆内存使用率
- 活跃会话数
- 错误率

### 安全建议

- 通过环境变量设置强密码保护 VNC 访问
- 配置防火墙限制端口访问
- 使用反向代理（如 nginx）处理 HTTPS
- 定期更新到最新稳定版本

## 相关链接

- GitHub 仓库：https://github.com/jo-inc/camofox-browser
- 问题反馈：https://github.com/jo-inc/camofox-browser/issues
- 最新版本：v1.11.2

---

<a id='page-configuration'></a>

## 配置参考

### 相关页面

相关主题：[部署指南](#page-deployment), [会话管理](#page-session-management)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [lib/config.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/config.js)
- [camofox.config.json](https://github.com/jo-inc/camofox-browser/blob/main/camofox.config.json)
- [lib/proxy.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/proxy.js)
- [lib/reporter.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/reporter.js)
- [scripts/plugin.js](https://github.com/jo-inc/camofox-browser/blob/main/scripts/plugin.js)
- [server.js](https://github.com/jo-inc/camofox-browser/blob/main/server.js)
- [lib/plugins.js](https://github.com/jo-inc/camofox-browser/blob/main/lib/plugins.js)
</details>

# 配置参考

Camofox-browser 是一个基于 Firefox (Camoufox 引擎) 的反检测浏览器自动化服务器。配置系统支持通过环境变量、JSON 配置文件和 API 参数三种方式进行配置。本页面详细说明所有可用的配置选项。

## 配置方式概览

Camofox-browser 支持三种配置方式，按优先级从高到低排列：

```mermaid
graph TD
    A[配置优先级] --> B[API请求参数]
    A --> C[环境变量]
    A --> D[camofox.config.json]
    
    B -->|最高优先级| E[运行时覆盖]
    C -->|次优先级| E
    D -->|最低优先级| E
```

| 配置方式 | 适用场景 | 示例 |
|---------|---------|------|
| API 请求参数 | 运行时动态配置 | `/tabs/:tabId/click` 中的 `userId` |
| 环境变量 | 容器部署、Docker | `ENABLE_VNC=1` |
| 配置文件 | 本地开发、持久化 | `camofox.config.json` |

## 环境变量配置

环境变量是部署和 Docker 场景中最常用的配置方式。

### 核心配置变量

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `PORT` | number | `9377` | 服务器监听端口 |
| `HOST` | string | `0.0.0.0` | 服务器绑定地址 |
| `FLY_APP_NAME` | string | - | Fly.io 应用名称 |
| `FLY_MACHINE_ID` | string | - | Fly.io 机器 ID |
| `LOG_LEVEL` | string | `info` | 日志级别 (debug/info/warn/error) |
| `LOG_FORMAT` | string | `json` | 日志格式 (json/text) |

### VNC 配置

社区反馈表明 VNC 配置在 1.11 版本中存在回归问题，详见 [Issue #4314](https://github.com/jo-inc/camofox-browser/issues/4314)。

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `ENABLE_VNC` | boolean | `false` | 启用 VNC 服务 |
| `VNC_BIND` | string | `127.0.0.1` | VNC 绑定地址 |
| `VNC_PORT` | number | `6080` | VNC 端口 |

```bash
# Docker 部署示例
docker run --rm -it -p 9377:9377 -p 6080:6080 \
  -e ENABLE_VNC=1 \
  -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:1.11.2
```

### 代理配置

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `HTTP_PROXY` | string | - | HTTP 代理地址 |
| `HTTPS_PROXY` | string | - | HTTPS 代理地址 |
| `NO_PROXY` | string | - | 跳过代理的地址 |

代理格式：`protocol://username:password@host:port`

### 会话配置

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `SESSION_TIMEOUT_MS` | number | `1800000` | 会话超时时间（毫秒，默认30分钟） |
| `MAX_TABS_PER_SESSION` | number | - | 每个会话最大标签页数 |

### 浏览器配置

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `BROWSER_HEADLESS` | boolean | `true` | 无头模式 |
| `BROWSER_ARGS` | string | - | 浏览器启动参数 |
| `VIEWPORT_WIDTH` | number | `1280` | 默认视口宽度 |
| `VIEWPORT_HEIGHT` | number | `800` | 默认视口高度 |

### 插件配置

| 变量名 | 类型 | 默认值 | 说明 |
|-------|------|-------|------|
| `PLUGIN_DIR` | string | `./plugins` | 插件目录路径 |
| `PLUGIN_NPM_REGISTRY` | string | `https://registry.npmjs.org/` | npm 注册表地址 |

## 配置文件

项目根目录下的 `camofox.config.json` 用于持久化配置。

### 配置文件结构

```json
{
  "server": {
    "port": 9377,
    "host": "0.0.0.0",
    "logLevel": "info",
    "logFormat": "json"
  },
  "browser": {
    "headless": true,
    "viewport": {
      "width": 1280,
      "height": 800
    },
    "args": []
  },
  "session": {
    "timeoutMs": 1800000,
    "maxTabs": 10
  },
  "proxy": {
    "http": null,
    "https": null,
    "noProxy": null
  },
  "vnc": {
    "enabled": false,
    "bind": "127.0.0.1",
    "port": 6080
  },
  "plugins": {
    "dir": "./plugins",
    "npmRegistry": "https://registry.npmjs.org/"
  },
  "traces": {
    "dir": "./traces",
    "retentionDays": 7
  }
}
```

### 配置验证

配置系统在 `lib/extract.js` 中提供了 schema 验证功能：

```javascript
const SUPPORTED_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'object', 'null']);
```

| 验证规则 | 说明 |
|---------|------|
| 顶级 schema 必须是 `type: object` | 配置文件必须是对象结构 |
| 必须包含 `properties` | 每个配置对象需要定义属性 |
| 属性值必须是对象 | 属性定义需符合规范 |
| 类型必须在支持列表中 | 仅支持 string/number/integer/boolean/object/null |

## 代理配置详解

### 代理格式

```mermaid
graph LR
    A[代理格式] --> B[protocol]
    A --> C[username]
    A --> D[password]
    A --> E[host]
    A --> F[port]
    
    B -->|"socks5|http|https"| G[协议]
```

代理 URL 格式：`protocol://username:password@host:port`

### 代理配置示例

```javascript
// 通过 API 创建带代理的会话
POST /sessions
{
  "userId": "agent1",
  "contextOptions": {
    "proxy": {
      "server": "http://username:password@proxy.example.com:8080"
    }
  }
}
```

### 代理生命周期管理

| 功能 | 说明 |
|-----|------|
| 代理轮换 | 支持在插件中使用 `session:creating` 钩子动态修改 |
| 代理验证 | 启动时验证代理格式 |
| 代理错误处理 | 连接失败自动重试 |

## 插件配置

### 插件管理命令

```bash
# 安装插件
node scripts/plugin.js install <source>

# 卸载插件
node scripts/plugin.js remove <name>

# 列出已安装插件
node scripts/plugin.js list
node scripts/plugin.js ls
```

### 插件安装来源

| 来源类型 | 示例 |
|---------|------|
| Git URL | `git:github.com/user/repo` |
| HTTPS URL | `https://github.com/user/repo` |
| 本地路径 | `./path/to/local/plugin` |

### 插件依赖管理

安装插件后，系统会自动执行以下操作：

1. 解析插件源码类型
2. 克隆/复制到 `PLUGIN_DIR`
3. 安装插件 npm 依赖
4. 更新 `camofox.config.json` 中的插件列表

```javascript
// scripts/plugin.js 中的核心逻辑
const installed = parsed.type === 'git'
  ? installFromGit(parsed.url, parsed.name)
  : installFromLocal(parsed.path, parsed.name);

for (const name of installed) {
  addToConfig(name);
  installPluginDeps(name);
}
```

### 插件事件钩子

| 钩子事件 | 类型 | 说明 |
|---------|------|------|
| `browser:launching` | Mutating | 浏览器启动前，可修改启动选项 |
| `session:creating` | Mutating | 会话创建前，可修改上下文选项 |
| `session:created` | Async | 会话创建后 |
| `session:destroyed` | Async | 会话销毁后 |

```javascript
// 修改 Xvfb 分辨率示例
events.on('browser:launching', ({ options }) => {
  options.virtual_display_resolution = '1920x1080';
});
```

## API 配置参数

### 会话相关参数

| 参数名 | 类型 | 位置 | 说明 |
|-------|------|-----|------|
| `userId` | string | body/query | 用户标识符，必填 |
| `sessionKey` | string | body | 会话分组键 |
| `listItemId` | string | body | 遗留会话分组标识 |

### 标签页操作参数

| 参数名 | 类型 | 适用端点 | 说明 |
|-------|------|---------|------|
| `tabId` | string | path | 标签页 ID |
| `ref` | string | /click, /type | 元素引用 ID |
| `selector` | string | /click, /type | CSS 选择器 |
| `x` | number | /click | 点击 X 坐标 |
| `y` | number | /click | 点击 Y 坐标 |
| `width` | integer | /viewport | 视口宽度 (100-4000) |
| `height` | integer | /viewport | 视口高度 (100-4000) |

### 内容获取参数

| 参数名 | 类型 | 适用端点 | 说明 |
|-------|------|---------|------|
| `includeData` | boolean | /images | 是否包含图片 base64 数据 |
| `maxBytes` | number | /images | 单张图片最大字节数 |
| `limit` | number | /images | 返回图片数量限制 (最大20) |

## 健康检查配置

`/health` 端点返回服务器和浏览器的健康状态：

```json
{
  "ok": true,
  "engine": "camoufox",
  "browserConnected": true,
  "browserRunning": true,
  "activeTabs": 5,
  "activeSessions": 2,
  "consecutiveFailures": 0,
  "memory": {
    "rssMb": 150,
    "heapUsedMb": 66,
    "nativeMemMb": 84
  }
}
```

当系统处于恢复状态时，返回 503 状态码：

```json
{
  "ok": false,
  "recovering": true
}
```

## 日志配置

### 日志格式

支持 `json` 和 `text` 两种格式：

```javascript
// JSON 格式示例
{
  "level": "info",
  "msg": "tab closed",
  "reqId": "abc123",
  "tabId": "tab1",
  "userId": "agent1",
  "timestamp": "2024-01-01T00:00:00.000Z"
}
```

### 日志级别

| 级别 | 用途 |
|-----|------|
| `debug` | 详细调试信息 |
| `info` | 一般信息 |
| `warn` | 警告信息 |
| `error` | 错误信息 |

### 请求日志字段

| 字段 | 说明 |
|-----|------|
| `reqId` | 请求唯一标识 |
| `error` | 错误信息 |
| `duration` | 请求耗时（毫秒） |

## 路径配置

| 配置项 | 默认值 | 说明 |
|-------|-------|------|
| `tracesDir` | `./traces` | 追踪文件存储目录 |
| `pluginsDir` | `./plugins` | 插件目录 |
| `downloadsDir` | `./downloads` | 下载文件目录 |

### 追踪文件路径规则

```javascript
// 路径格式
${tracesDir}/${userId}/${filename}

// 示例
./traces/agent1/trace-20240101.zip
```

### 路径安全验证

系统对文件路径进行安全验证，防止路径遍历攻击：

```javascript
const full = resolveTracePath(CONFIG.tracesDir, userId, req.params.filename);
if (!full) return res.status(400).json({ error: 'invalid filename' });
```

## Docker 环境配置

### 镜像拉取

```bash
# 拉取指定版本
docker pull ghcr.io/jo-inc/camofox-browser:1.11.2

# 拉取最新版本
docker pull ghcr.io/jo-inc/camofox-browser:latest
```

### Docker 常用配置

```bash
docker run --rm -it \
  -p 9377:9377 \
  -p 6080:6080 \
  -e PORT=9377 \
  -e ENABLE_VNC=1 \
  -e VNC_BIND=0.0.0.0 \
  -e LOG_LEVEL=info \
  ghcr.io/jo-inc/camofox-browser:1.11.2
```

### Docker Compose 示例

```yaml
version: '3.8'
services:
  camofox:
    image: ghcr.io/jo-inc/camofox-browser:1.11.2
    ports:
      - "9377:9377"
      - "6080:6080"
    environment:
      - ENABLE_VNC=1
      - VNC_BIND=0.0.0.0
      - LOG_LEVEL=info
    restart: unless-stopped
```

## 配置优先级与合并

```mermaid
graph TD
    A[配置合并顺序] --> B[1. 加载 camofox.config.json]
    B --> C[2. 应用环境变量覆盖]
    C --> D[3. 应用运行时 API 参数]
    D --> E[最终配置]
    
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style E fill:#9f9,stroke:#333,stroke-width:2px
```

### 合并规则

1. **深层合并**：嵌套对象执行深层合并，非替换
2. **数组替换**：数组类型直接替换，非合并
3. **null 处理**：`null` 值覆盖为空，而非删除键

## 常见配置问题

### VNC 在 Docker 中不生效

**问题描述**：Issue #4314 反馈 VNC 在 1.11 版本中无法通过环境变量激活。

**解决方案**：确保在 Docker 运行时正确设置 `ENABLE_VNC=1` 和 `VNC_BIND=0.0.0.0`：

```bash
docker run --rm -it \
  -p 6080:6080 \
  -e ENABLE_VNC=1 \
  -e VNC_BIND=0.0.0.0 \
  ghcr.io/jo-inc/camofox-browser:1.11.2

# 验证 VNC 服务
curl -4I localhost:6080
# 应返回 HTTP/1.1 200 OK
```

### 插件安装失败

**问题描述**：Issue #54 报告从 OC 4.5 更新到 4.9 时插件更新失败。

**错误信息**：
```
Failed to update camofox-browser: Error [ERR_MODULE_NOT_FOUND]: Cannot find module...
```

**解决方案**：检查插件目录权限，确保 `node_modules` 已正确安装：

```bash
# 重新安装插件依赖
cd plugins/camofox-browser
npm install
```

### WSL2 环境屏幕闪烁

**问题描述**：Issue #64 报告在 WSL2 环境下每 3 分钟出现屏幕闪烁。

**说明**：这是由 Xvfb 虚拟显示驱动的已知行为，不影响功能但可能影响使用体验。

## 配置参考表

### 完整环境变量列表

| 变量名 | 类型 | 默认值 | 来源 |
|-------|------|-------|------|
| `PORT` | number | `9377` | server.js |
| `HOST` | string | `0.0.0.0` | server.js |
| `ENABLE_VNC` | boolean | `false` | lib/reporter.js |
| `VNC_BIND` | string | `127.0.0.1` | lib/reporter.js |
| `VNC_PORT` | number | `6080` | lib/reporter.js |
| `HTTP_PROXY` | string | - | lib/proxy.js |
| `HTTPS_PROXY` | string | - | lib/proxy.js |
| `NO_PROXY` | string | - | lib/proxy.js |
| `SESSION_TIMEOUT_MS` | number | `1800000` | server.js |
| `LOG_LEVEL` | string | `info` | lib/reporter.js |
| `LOG_FORMAT` | string | `json` | lib/reporter.js |
| `PLUGIN_DIR` | string | `./plugins` | scripts/plugin.js |
| `PLUGIN_NPM_REGISTRY` | string | npm registry | scripts/plugin.js |

---

<!-- evidence_pipeline_checked: true -->
<!-- evidence_injected: true -->

---

## Doramagic 踩坑日志

项目：jo-inc/camofox-browser

摘要：发现 37 个潜在踩坑项，其中 3 个为 high/blocking；最高优先级：配置坑 - 来源证据：[0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)。

## 1. 配置坑 · 来源证据：[0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_509e4f60bc5b4f59b2f30d8e940b435f | https://github.com/jo-inc/camofox-browser/issues/4493 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 2. 配置坑 · 来源证据：[50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_9b0d643d129c40bba9029a91908b6df8 | https://github.com/jo-inc/camofox-browser/issues/4495 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 3. 维护坑 · 来源证据：[5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)

- 严重度：high
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：[5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源问题仍为 open，Pack Agent 需要复核是否仍影响当前版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_b64265a647de4b7b87d3c451230683a7 | https://github.com/jo-inc/camofox-browser/issues/4483 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 4. 配置坑 · 来源证据：[1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_bc5774adce304ebcb8ccd6511fcf24df | https://github.com/jo-inc/camofox-browser/issues/4859 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 5. 配置坑 · 来源证据：[1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_66b048f511104e1f9c71f1ab5bb753ad | https://github.com/jo-inc/camofox-browser/issues/4854 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 6. 配置坑 · 来源证据：[43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_34506ec241e243b79da0f0ffc55849da | https://github.com/jo-inc/camofox-browser/issues/4858 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 7. 配置坑 · 来源证据：[51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_ec01f035f6474fde8b54a78998fcf0e8 | https://github.com/jo-inc/camofox-browser/issues/4851 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 8. 配置坑 · 来源证据：[674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_ea7990b603954ff98742c9307eaa3873 | https://github.com/jo-inc/camofox-browser/issues/4856 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 9. 配置坑 · 来源证据：[7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_79456dd0004342acba398cdc03c58748 | https://github.com/jo-inc/camofox-browser/issues/4852 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 10. 配置坑 · 来源证据：[8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_d5beb836c1824c75b5eedfce488baaeb | https://github.com/jo-inc/camofox-browser/issues/4853 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 11. 配置坑 · 来源证据：[8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_59fb2f68349c474fb6875fd66c694591 | https://github.com/jo-inc/camofox-browser/issues/4855 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 12. 配置坑 · 来源证据：[90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_c4c3a2b1654f4286b1c91f91aad1713e | https://github.com/jo-inc/camofox-browser/issues/4863 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 13. 配置坑 · 来源证据：[988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_734e663855e842ce92efed98a8cbd0b3 | https://github.com/jo-inc/camofox-browser/issues/4862 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 14. 配置坑 · 来源证据：[c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：GitHub 社区证据显示该项目存在一个配置相关的待验证问题：[c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)
- 对用户的影响：可能阻塞安装或首次运行。
- 建议检查：来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- 防护动作：不得脱离来源链接放大为确定性结论；需要标注适用版本和复核状态。
- 证据：community_evidence:github | cevd_defd39095ef14988a51da35554363f33 | https://github.com/jo-inc/camofox-browser/issues/4860 | 来源讨论提到 node 相关条件，需在安装/试用前复核。

## 15. 能力坑 · 能力判断依赖假设

- 严重度：medium
- 证据强度：source_linked
- 发现：README/documentation is current enough for a first validation pass.
- 对用户的影响：假设不成立时，用户拿不到承诺的能力。
- 建议检查：将假设转成下游验证清单。
- 防护动作：假设必须转成验证项；没有验证结果前不能写成事实。
- 证据：capability.assumptions | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | README/documentation is current enough for a first validation pass.

## 16. 运行坑 · 失败模式：runtime: [5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this runtime risk before relying on the project: [5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s). Context: Observed when using macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_adfbf6e2a8851ffb888977db14835ee7 | https://github.com/jo-inc/camofox-browser/issues/4483 | [5cf7d100] stuck:event-loop: Event loop stalled for 22s (threshold: 5s)

## 17. 运行坑 · 失败模式：runtime: [ef2f639f] stuck:event-loop: Event loop stalled for 103s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this runtime risk before relying on the project: [ef2f639f] stuck:event-loop: Event loop stalled for 103s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [ef2f639f] stuck:event-loop: Event loop stalled for 103s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [ef2f639f] stuck:event-loop: Event loop stalled for 103s (threshold: 5s). Context: Observed when using macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_e1e537c82dc9bc903c25afaff458ef37 | https://github.com/jo-inc/camofox-browser/issues/4484 | [ef2f639f] stuck:event-loop: Event loop stalled for 103s (threshold: 5s)

## 18. 运行坑 · 运行可能依赖外部服务

- 严重度：medium
- 证据强度：source_linked
- 发现：项目说明出现 external service/cloud/webhook/database 等运行依赖关键词。
- 对用户的影响：本地安装成功不等于能力可用，外部服务不可用会阻断体验。
- 建议检查：确认是否有离线 demo、mock 数据或可替代服务。
- 防护动作：外部服务依赖未明确时，不把本地安装成功等同于能力可用。
- 证据：packet_text.keyword_scan | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | matched external service / cloud / webhook / database keyword

## 19. 维护坑 · 失败模式：migration: [1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_4f4c6975103e49767f988cddded1c5a3 | https://github.com/jo-inc/camofox-browser/issues/4857 | [1f7f8070] stuck:event-loop: Event loop stalled for 6s (threshold: 5s)

## 20. 维护坑 · 失败模式：migration: [1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_7f437cba05011955428eb8555b0dd70c | https://github.com/jo-inc/camofox-browser/issues/4854 | [1f8af390] stuck:event-loop: Event loop stalled for 80s (threshold: 5s)

## 21. 维护坑 · 失败模式：migration: [43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_f75614730f93a7ca81e759ec5b88bf03 | https://github.com/jo-inc/camofox-browser/issues/4858 | [43752418] stuck:event-loop: Event loop stalled for 46s (threshold: 5s)

## 22. 维护坑 · 失败模式：migration: [51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_a3790117e4c346db5a241874d5355c6d | https://github.com/jo-inc/camofox-browser/issues/4851 | [51f1f89c] stuck:event-loop: Event loop stalled for 38s (threshold: 5s)

## 23. 维护坑 · 失败模式：migration: [674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_5f800f182f246903f0b004ebdf189ce5 | https://github.com/jo-inc/camofox-browser/issues/4856 | [674b19b0] stuck:event-loop: Event loop stalled for 23s (threshold: 5s)

## 24. 维护坑 · 失败模式：migration: [7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_5cbd66fe3eb622d1f5e34730b742dbac | https://github.com/jo-inc/camofox-browser/issues/4852 | [7506c020] stuck:event-loop: Event loop stalled for 70s (threshold: 5s)

## 25. 维护坑 · 失败模式：migration: [8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_1c9813603e614996e1e705a49f5d9459 | https://github.com/jo-inc/camofox-browser/issues/4853 | [8c732f44] stuck:event-loop: Event loop stalled for 93s (threshold: 5s)

## 26. 维护坑 · 失败模式：migration: [8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_dcf762017f14fd0f1ff0f2fd7938023e | https://github.com/jo-inc/camofox-browser/issues/4855 | [8ffefba3] stuck:event-loop: Event loop stalled for 55s (threshold: 5s)

## 27. 维护坑 · 失败模式：migration: [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_0ae6d0d255bee7d4c76ecadae2a2b89b | https://github.com/jo-inc/camofox-browser/issues/4863 | [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s), failure_mode_cluster:github_issue | fmev_9b0f7685b8e7a6dc76d4052c3ed229f3 | https://github.com/jo-inc/camofox-browser/issues/4861 | [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s), failure_mode_cluster:github_issue | fmev_4a9cb6fcef9fa031d0e8ee287b4c4997 | https://github.com/jo-inc/camofox-browser/issues/4849 | [90cfc6c8] stuck:event-loop: Event loop stalled for 17s (threshold: 5s)

## 28. 维护坑 · 失败模式：migration: [988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_58b8387d3aaf6df3674469afed9e6e2b | https://github.com/jo-inc/camofox-browser/issues/4862 | [988be9c4] stuck:event-loop: Event loop stalled for 18s (threshold: 5s)

## 29. 维护坑 · 失败模式：migration: [c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_aebc2e6751b5e29fe6a44e3dc055a8cd | https://github.com/jo-inc/camofox-browser/issues/4860 | [c665094c] stuck:event-loop: Event loop stalled for 74s (threshold: 5s)

## 30. 维护坑 · 失败模式：migration: [fed74e38] stuck:event-loop: Event loop stalled for 96s (threshold: 5s)

- 严重度：medium
- 证据强度：source_linked
- 发现：Developers should check this migration risk before relying on the project: [fed74e38] stuck:event-loop: Event loop stalled for 96s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [fed74e38] stuck:event-loop: Event loop stalled for 96s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [fed74e38] stuck:event-loop: Event loop stalled for 96s (threshold: 5s). Context: Observed when using node, macos
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_f1881e686e51f7989cbba960e849e678 | https://github.com/jo-inc/camofox-browser/issues/4850 | [fed74e38] stuck:event-loop: Event loop stalled for 96s (threshold: 5s)

## 31. 维护坑 · 维护活跃度未知

- 严重度：medium
- 证据强度：source_linked
- 发现：未记录 last_activity_observed。
- 对用户的影响：新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- 建议检查：补 GitHub 最近 commit、release、issue/PR 响应信号。
- 防护动作：维护活跃度未知时，推荐强度不能标为高信任。
- 证据：evidence.maintainer_signals | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | last_activity_observed missing

## 32. 安全/权限坑 · 下游验证发现风险项

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：下游已经要求复核，不能在页面中弱化。
- 建议检查：进入安全/权限治理复核队列。
- 防护动作：下游风险存在时必须保持 review/recommendation 降级。
- 证据：downstream_validation.risk_items | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | no_demo; severity=medium

## 33. 安全/权限坑 · 存在评分风险

- 严重度：medium
- 证据强度：source_linked
- 发现：no_demo
- 对用户的影响：风险会影响是否适合普通用户安装。
- 建议检查：把风险写入边界卡，并确认是否需要人工复核。
- 防护动作：评分风险必须进入边界卡，不能只作为内部分数。
- 证据：risks.scoring_risks | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | no_demo; severity=medium

## 34. 运行坑 · 失败模式：performance: [0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)

- 严重度：low
- 证据强度：source_linked
- 发现：Developers should check this performance risk before relying on the project: [0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s). Context: Observed when using node, linux
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_96d2eca451f642a641a8a7b2525b1746 | https://github.com/jo-inc/camofox-browser/issues/4493 | [0d148b4c] stuck:event-loop: Event loop stalled for 7s (threshold: 5s)

## 35. 运行坑 · 失败模式：performance: [50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)

- 严重度：low
- 证据强度：source_linked
- 发现：Developers should check this performance risk before relying on the project: [50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)
- 对用户的影响：Developers may hit a documented source-backed failure mode: [50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)
- 建议检查：Before packaging this project, run the relevant install/config/quickstart check for: [50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s). Context: Observed when using node, linux
- 防护动作：State this as source-backed community evidence, not as Doramagic reproduction.
- 证据：failure_mode_cluster:github_issue | fmev_4c3438066164124d4582118383fcfdca | https://github.com/jo-inc/camofox-browser/issues/4495 | [50ffc888] stuck:event-loop: Event loop stalled for 12s (threshold: 5s)

## 36. 维护坑 · issue/PR 响应质量未知

- 严重度：low
- 证据强度：source_linked
- 发现：issue_or_pr_quality=unknown。
- 对用户的影响：用户无法判断遇到问题后是否有人维护。
- 建议检查：抽样最近 issue/PR，判断是否长期无人处理。
- 防护动作：issue/PR 响应未知时，必须提示维护风险。
- 证据：evidence.maintainer_signals | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | issue_or_pr_quality=unknown

## 37. 维护坑 · 发布节奏不明确

- 严重度：low
- 证据强度：source_linked
- 发现：release_recency=unknown。
- 对用户的影响：安装命令和文档可能落后于代码，用户踩坑概率升高。
- 建议检查：确认最近 release/tag 和 README 安装命令是否一致。
- 防护动作：发布节奏未知或过期时，安装说明必须标注可能漂移。
- 证据：evidence.maintainer_signals | github_repo:1142274728 | https://github.com/jo-inc/camofox-browser | release_recency=unknown

<!-- canonical_name: jo-inc/camofox-browser; human_manual_source: deepwiki_human_wiki -->
