# 浏览器录制生成个性化 Bundle

用 Baijimu CLI 创建 Agent 会话，让用户在托管浏览器中完成操作，再把捕获的请求固化为工作区专属 Bundle 并验证自动调用。

这条流程把一次真实网页操作变成可重复调用的工作区能力：CLI 创建 Agent 会话，Agent 创建带网络录制的浏览器会话，用户在 viewer 中操作，Agent 从录制请求中识别稳定接口并返回脱敏候选；运行 Agent 的外层自动化再通过同一台设备上的 Baijimu CLI 生成模块、创建 Bundle 版本、安装并验证。后续自动化调用的是 Bundle 中冻结的方法，不依赖再次人工操作页面。

Agent 会话和浏览器会话不是同一个对象。Agent 会话承载任务和项目上下文；`browser-session` 提供浏览器 Profile、viewer、标签页、网络录制及请求上下文。必须分别记录二者的 ID，并在结束时分别清理。

Browser Profile 的申请、稳定身份和 Resource Binding 边界见
[基础能力与 Resource Binding](/features/resource-bindings/)。

## 前置条件

1. 安装并登录 Baijimu CLI。该流程要求 `0.1.37` 或更高版本，因为创建 Agent 会话必须显式传入 `workspaceId`。
2. 目标工作区已有默认 Runtime、项目、可执行的 Agent 配置和 Browser Profile。
3. Runtime 已安装并能调用 `browser-session` 模块，Agent 配置允许使用它的浏览器工具。
4. 测试账号有权访问目标网站和目标工作区；涉及扫码、MFA、验证码或授权确认时，由用户在 viewer 中完成。
5. 为测试准备独立的工作区或明确的名称前缀。录制内容可能包含 Cookie、Authorization、表单数据和响应体，不得使用生产账号做无审计测试。

先从当前 CLI 确认命令面，不要复制其他版本的参数：

```bash
baijimu --version
baijimu auth status
baijimu agent session create --help
baijimu agent chat --help
baijimu bundle --help
baijimu runtime service --help
```

通过工作区、项目、Agent 配置和 Browser Profile 的列表或详情命令取得真实 ID。不要从页面 URL、历史日志或其他工作区猜测 ID。

## 1. 创建 Agent 会话

```bash
baijimu agent session create <PROJECT_ID> \
  --workspace-id <WORKSPACE_ID> \
  --agent-config-id <AGENT_CONFIG_ID> \
  --browser-profile-id <BROWSER_PROFILE_ID> \
  --title 'browser-record-to-bundle-<TIMESTAMP>' \
  --json
```

保存返回的 `sessionId`。如果接口返回 `workspaceId is required`，说明正在使用旧版 CLI；升级后重新创建，不要绕过 CLI 直接调用内部 API。

## 2. 让 Agent 打开浏览器并开始录制

向同一个会话发送完整目标。提示词至少要声明目标 URL、可识别的用户操作、录制范围、输出 Bundle 的命名规则和成功验收项：

```bash
baijimu agent chat <WORKSPACE_ID> <PROJECT_ID> <SESSION_ID> \
  --agent-config-id <AGENT_CONFIG_ID> \
  --message '请创建或复用当前 Browser Profile 的浏览器会话，把网络录制模式设置为 full，然后打开 <TARGET_URL>。返回 viewerUrl 和 browserSessionId，等待我完成页面操作。操作完成后只分析 XHR/Fetch 请求，选择能够稳定重放的业务请求，移除 Cookie、Authorization、一次性 token 和个人数据，把动态输入建模为方法参数。最后只返回脱敏后的候选方法定义和录制证据，不要通过 Runtime 内部服务创建项目、模块、Bundle 或版本。' \
  --json
```

Agent 应通过 `browser-session` 的这些能力完成准备：

- `ensure_browser_session`：创建或复用浏览器会话并返回 `sessionId`、`viewerUrl`、`profileId`；
- `set_network_capture_mode`：在用户操作前设置为 `full`；
- `get_browser_session`、`list_browser_session_tabs`、`activate_browser_session_tab`：确认会话就绪并选中正确标签页。

只有在返回的工作区、Profile 和目标 URL 都正确后，才把 viewer 交给用户操作。

## 3. 用户在 viewer 中完成一次真实操作

用户在 viewer 中完成登录、点击、输入和提交。至少产生一个可识别的业务请求；只打开静态页面不算完成录制。

操作结束后，通知 Agent 继续。Agent 先调用 `list_recorded_network_requests`，优先筛选 `XHR`、`Fetch`、JSON、非静态资源，再用 `get_recorded_network_request` 查看候选请求详情。需要复用当前登录态时，可以用 `get_browser_request_context` 导出指定 URL 对应的 Cookie 名称和 User-Agent，但敏感值只能进入模块的敏感属性或运行态凭据，不能写进项目文件、方法定义、Bundle Manifest、日志或聊天结果。

读取列表前先确认最新记录的时间晚于本次用户操作。若记录仍停留在浏览器初始导航时间，说明当前采集 watcher 没有覆盖这次操作；重新把模式设置为 `full`，先执行一次无副作用导航或刷新并确认列表时间前进，再让用户重做目标操作。不要用旧请求冒充本次录制证据。

录制结果必须经过人工或 Agent 审查：

1. 确认请求确实对应刚才的用户动作，而不是埋点、轮询或静态资源。
2. 把路径、查询参数、请求体中的业务输入变成明确的方法参数。
3. 移除 Cookie、Authorization、CSRF、追踪 ID、时间戳和一次性签名等会话值。
4. 明确认证刷新、超时、幂等、重试、错误和响应裁剪规则。
5. 首次验证选择查询或其他无副作用操作；写操作必须使用专用测试数据。

## 4. 固化为工作区专属 Bundle

生成结果必须走 Bundle-first 发布链，不能创建游离模块，也不能把历史“自定义服务”记录当成最终发布单元：

```text
录制请求
  -> module.json + methods/*.json
  -> 项目 Git 提交
  -> Bundle 内创建模块版本
  -> 创建不可变 Bundle 版本
  -> 安装或升级到目标 Runtime
  -> 回读服务并调用验证
```

浏览器 Agent 到返回脱敏候选为止。项目和 Bundle 的写操作属于外层发布控制器：由启动 Agent 会话的同一台受信任设备使用 Baijimu CLI 执行。不要让 Agent 经 Runtime 内部服务创建 Bundle；内部服务接收的是运行态上下文，不等同于 CLI 的工作区发布凭据和参数契约。

外层自动化至少执行并检查这些标准命令：

```bash
baijimu module project create \
  --workspace-id <WORKSPACE_ID> \
  --name <MODULE_PROJECT_NAME>

baijimu project create --workspace-id <WORKSPACE_ID> \
  --project-type-key BUNDLE \
  --name <BUNDLE_PROJECT_NAME>

baijimu bundle create --workspace-id <WORKSPACE_ID> \
  --bundle-id <BUNDLE_ID> \
  --name <BUNDLE_NAME> \
  --project-id <BUNDLE_PROJECT_ID>

baijimu bundle module create <WORKSPACE_ID> <BUNDLE_ID> \
  --project-id <MODULE_PROJECT_ID> \
  --name <MODULE_NAME> \
  --description '<DESCRIPTION>'

baijimu project checkout <MODULE_PROJECT_ID> --workspace-id <WORKSPACE_ID> --directory <DIRECTORY>
cd <DIRECTORY>
git status --short
git diff -- module.json methods/<METHOD_NAME>.json
git add -- module.json methods/<METHOD_NAME>.json
git commit -m 'feat: generate module from browser recording'
git push
COMMIT_ID="$(git rev-parse HEAD)"

baijimu bundle module version create <WORKSPACE_ID> <BUNDLE_ID> <MODULE_PROJECT_ID> \
  --module-id <MODULE_ID> \
  --version 0.1.0 \
  --commit-id <COMMIT_ID>

baijimu project checkout <BUNDLE_PROJECT_ID> --workspace-id <WORKSPACE_ID> --directory <BUNDLE_DIRECTORY>
cd <BUNDLE_DIRECTORY>
baijimu bundle manifest validate @baijimu.bundle.json
git add baijimu.bundle.json
git commit -m 'feat: include generated module version'
git push
BUNDLE_COMMIT_ID="$(git rev-parse HEAD)"

baijimu bundle version create <BUNDLE_ID> --workspace-id <WORKSPACE_ID> \
  --version 0.1.0 --git-commit-id <BUNDLE_COMMIT_ID>
baijimu bundle install <WORKSPACE_ID> <BUNDLE_ID>
```

若 Bundle 已安装，发布后使用 `bundle upgrade` 指向新 `bundleVersionId`，不要重复安装。个性化接入默认仅在当前工作区发布和安装；除非完成通用化、安全审查与市场审核，不得执行 `bundle market publish`。

`bundle install` 必须能解析工作区自有 Bundle，并由 Partner 路由把安装请求交给默认 Runtime。若命令只查询公共市场，或自有 Bundle 安装 Partner 路由返回 404，应停止闭环并修复 CLI/网关能力；不要为了通过测试把个性化 Bundle 发布到公共市场。

## 5. 验证闭环

安装成功不等于闭环成功。用当前 CLI 的 Runtime 服务命令回读安装结果并调用方法：

```bash
baijimu runtime services list <WORKSPACE_ID> --keyword <MODULE_NAME> --json
baijimu runtime service get <WORKSPACE_ID> <BUSINESS_ID> --method <METHOD_NAME> --json
baijimu runtime service call <WORKSPACE_ID> <BUSINESS_ID> <METHOD_NAME> \
  --params @verification-input.json \
  --json
baijimu bundle resources <WORKSPACE_ID> <BUNDLE_ID>
```

验收证据至少包含：

- Agent `sessionId`、浏览器 `browserSessionId`、Browser Profile ID 和目标 URL；
- 被选中的请求 method、URL 模板及脱敏后的参数映射；
- 模块项目 ID、模块 ID、Git commit ID 和创建的不可变模块版本；
- Bundle ID、不可变 Bundle 语义版本、版本内容和 Runtime 安装记录；
- Runtime 中可见的 `businessId`、方法名及一次成功调用的脱敏结果；
- 再次调用时不需要用户重新操作网页。若认证本身需要用户确认，应明确把它定义为凭据更新步骤，而不是伪装成全自动。

最后让 Agent 关闭临时浏览器会话。保留 Profile 前先确认其中没有测试账号之外的敏感登录态；删除 Bundle、卸载应用或删除项目均属于破坏性操作，测试清理前需要单独确认。

## 常见失败

| 现象                                         | 根因与处理                                                                            |
| ------------------------------------------ | -------------------------------------------------------------------------------- |
| 创建 Agent 会话返回缺少 `workspaceId`              | CLI 版本低于 `0.1.37`，升级并显式使用 `--workspace-id`。                                      |
| viewer 可操作但没有业务请求                          | 录制开始太晚、模式仍为 `off`/`metadata`，或用户只访问了静态页面；在操作前切到 `full` 并重新执行。                    |
| 请求列表只有初始导航记录                               | watcher 没有覆盖本次用户操作；重新设置 `full`，用无副作用刷新确认记录时间前进，再重做目标操作。                          |
| 找到大量无关请求                                   | 先筛选 XHR/Fetch、JSON、非静态资源，再逐条核对触发时间和业务响应。                                         |
| 生成的方法只能调用一次                                | 把 Cookie、CSRF、签名、追踪 ID 或时间戳硬编码进了方法；改为敏感属性、认证刷新逻辑或动态参数后重新创建不可变版本。                 |
| Runtime 看不到方法                              | 只提交了项目文件或创建了模块版本，没有更新清单、创建并安装/升级 Bundle 版本；按版本内容逐层回查。                            |
| Agent 创建 Bundle 时出现 `workspaceId` 类型或上下文错误 | 责任边界错误；Agent 只返回脱敏候选，外层自动化必须使用 Baijimu CLI 完成项目和 Bundle 写操作。                     |
| `bundle install` 找不到刚发布的自有 Bundle          | CLI 退化为只查公共市场，或工作区自有安装 Partner 路由未注册；修复发布链路后再验证，不要执行 `bundle market publish` 绕过。 |
| 网关调用缺少用户上下文                                | 模块错误地要求浏览器传普通 `userId`；应从 Runtime 调用上下文获取当前用户和工作区。                               |
| 测试意外进入公共市场                                 | 个性化测试不应执行 `bundle market publish`；停止审核流程并确认没有公开版本后再继续。                           |
