# FoxPaw 中继 3.0 迁移说明（收敛版）

中继 3.0.0 把「登录、Agent 接口、页面」各收成一套。旧东西**在 3.0 全部还能用一个版本**，但每次调用都会明确提示弃用；**中继 3.1 删除**。

> 2026-10-29 更新（中继 3.1.0 IA v1）：3.1.0 **没有删**任何旧接口（旧扩展 1.14.5 / 1.17.x 仍在线上），删除推迟到 **3.2**；回包里的 `removal` 改为 `3.2.0`。

> 2026-10-29 再更新（中继 3.2.0 飞书通知）：3.2.0 也**没有删**旧接口，删除推迟到 **3.3**；回包里的 `removal` 改为 `3.3.0`。

> 2026-10-29 三更（中继 3.3.0 账号 / 设备回收）：3.3.0 仍**没有删**旧接口，删除推迟到 **3.4**；回包里的 `removal` 改为 `3.4.0`。

> 2026-10-30 四更（中继 3.4.0 运行不黑盒）：3.4.0 仍**没有删**旧接口（旧扩展 1.17 / 1.20 要能连），删除推迟到 **3.5**；回包里的 `removal` 改为 `3.5.0`。

## 一、登录只剩三种

| 谁 | 唯一方式 | 接口 |
|---|---|---|
| 主人 | 邮箱验证码 → 网页会话（Cookie，30 天） | `POST /auth/request-code` → `POST /auth/verify` |
| 浏览器（扩展） | 设备码流程 → 设备令牌 | `POST /auth/device/start` → 主人在 `/app/connect?code=XXXX` 批准（`/auth/device/pending`、`/auth/device/approve`）→ 扩展 `POST /auth/device/poll` 拿到连接串 |
| Agent | 邀请链接 → Agent 令牌 | 主人在控制台「接入 Agent」生成 `/app/claim?invite=<码>` → `POST /auth/agent/claim {invite, label}` |

## 二、弃用对照（3.0 仍可用，3.1 删除）

弃用的 HTTP 接口：回包 JSON 多一个 `deprecated` 字段（`api / since / removal / use / message / doc`），响应头带 `Deprecation: true`、`Link: <…/docs/migration-3.0>; rel="deprecation"`、`X-FoxPaw-Deprecated`。运维总览 `/admin/api/overview` 的 `deprecated_hits` 记着每个旧接口启动以来被调用的次数——全是 0 了再删。

| 旧的 | 改用 | 说明 |
|---|---|---|
| `POST /auth/exchange`（账户连接码换连接串） | 设备码流程 | 扩展 1.17 已去掉「用连接码连接」「更换连接码」 |
| `POST /auth/my/reset-code`、`POST /app/api/reset-code` | 无需替代 | 连接码只为 exchange 存在 |
| `GET /app?ticket=…` 与扩展 WS `consoleTicket`（控制台免登票据） | 直接打开 `/app/…` | 浏览器连接时主人已在这台浏览器登录过（批准设备需要登录），会话 30 天；过期就在控制台用邮箱验证码登录 |
| 设备邀请（`kind=device`）+ `POST /claim/api` 领配对串 | 设备码流程 | |
| `POST /claim/api`（Agent 邀请） | `POST /auth/agent/claim` | 入参出参相同 |
| `GET /auth/my/devices`、`POST /auth/my/revoke` | `/app/api/state`、`/app/api/device/revoke`、`/app/api/agent/remove` | 旧 /connect 页用的接口 |
| `POST /admin/api/devices`、`POST /admin/api/agents`（运营直发配对串/凭证） | 设备码流程 / `POST /admin/api/invites {kind:"agent"}` | 运营后台也不再直发凭证 |
| WS `/agent` 自定义 Agent 协议 | MCP `POST /mcp` | `auth.ok` 帧带 `deprecated`；命令对照见第三节 |
| 页面 `/connect`、`/claim`、`/account`、`/admin` | `/app/connect`、`/app/claim`、`/app/account`、`/app/admin` | 302 跳转并保留查询串 |
| 官网 `/` 由中继托管 | 独立静态目录 `site/`，单独部署 | 3.0：设了 `FOXPAW_SITE_URL` 就 302 过去；否则中继旁边放了 `site/index.html` 就照旧返回；都没有就跳 `/app` |

## 三、Agent：WS 命令 → MCP 工具

| WS kind | MCP 工具 |
|---|---|
| whoami | foxpaw_whoami |
| tabs / snapshot / navigate / click / fill / waitFor | foxpaw_tabs / foxpaw_snapshot / foxpaw_navigate / foxpaw_click / foxpaw_fill / foxpaw_wait_for |
| createTab / closeTab / activateTab / findTabs | foxpaw_open_tab / foxpaw_close_tab / foxpaw_activate_tab / foxpaw_find_tabs |
| cdp / cdpEndpoint | foxpaw_cdp / foxpaw_cdp_endpoint（都需要主人给的「原始 CDP」授权） |
| ask | foxpaw_need_human |
| requestElevation | foxpaw_request_elevation |
| listTasks / taskAccept / taskProgress / taskResult | foxpaw_list_tasks / foxpaw_task_accept / foxpaw_task_progress / foxpaw_task_result |
| flowRun（录制版新增，扩展 ≥1.17） | foxpaw_flow_run（回放 foxpaw.flow/1 流程；付款/授权/密码验证码卡号停下交主人；命令行 `foxpaw.js flow_run`） |

注意：WS 的 `fill` 旧数组默认只描边不填（`dryRun` 默认 true）；MCP `foxpaw_fill` 默认真填。命令行 `agent/foxpaw.js fill` 改走 MCP 后保留旧口径：不带 `--real` 就是 `dryRun:true`。

命令行 `agent/foxpaw.js` 与技能脚本 `skill/scripts/foxpaw.js` 已改成 MCP 薄客户端：环境变量 `FOXPAW_URL`（中继 https 地址）+ `FOXPAW_AGENT_TOKEN`（或 `FOXPAW_TOKEN_FILE` / 旧的令牌文件位置）。

## 四、扩展 1.17 与中继 3.0 是否要同批

- 中继 3.0 + 旧扩展 1.16：可用。1.16 的「打开控制台」走票据（弃用但可用）、「用连接码连接」走 exchange（弃用但可用）；设备码流程的批准页改成 `/app/connect`，1.16 打开的是中继给的 `verify_url`，自动跟上。
- 扩展 1.17 + 旧中继 2.9：可用。1.17 的出口都是 `/app#视图`（hash，不是 `/app/视图` 路径），2.9 的 app.html 认得，`#account` 会被 2.9 转去它的 /account 页；1.17 没有了连接码入口，设备码流程照常。
- 录制版（同在 3.0 / 1.17 里）：MCP `foxpaw_flow_run` 要扩展 ≥1.17，配 1.16 会回 UNKNOWN_KIND；面板里的回放、导出 Playwright 不经过中继，不受中继版本影响。扩展 1.17 上云前自己先脱敏流程（redactFlow）；中继 3.0 再兜一层（不是脱敏流程就丢掉），2.9 没有这层兜底，所以扩展 1.17 最好不早于中继 3.0 上。
- 结论：**建议同一窗口内先上中继 3.0、再上扩展 1.17**；两者之间没有 WS 协议或 MCP 信封变化。
