SuperAPI AI 工具集

control-browser

测试与质量

查看项目

更新于 10-24 22:23

技能介绍

用途

control-browser 是一个浏览器自动化技能,适用于浏览器与 Web UI 相关任务:打开和导航页面、检查或读取渲染内容、测试本地应用、点击、输入、填写、截图,以及验证可见页面状态。如果该技能在会话中可用,应将其视为浏览器工作前的必读内容,在声称浏览器不可用之前、在回退到 bash(curl/open)、webfetch 或任何其他工具之前,先遵循本技能。

主要能力

  • 浏览器注册表由 Node REPL MCP 的 js 工具驱动,可调用 id 通常显示为 mcp__node_repl__js。
  • 支持三种后端类型:iab、extension、cdp;Playwright 是标签页 API 界面,不是后端。
  • 通过 agent.browsers.list() 作为可用性来源。桌面通常报告 IAB;显式以 --browser-use=headless 启动的 CLI 报告托管 Chromium 为 cdp。Headless 是 CDP 启动模式,不是后端类型。
  • 提供标签页管理、页面导航、DOM 快照、Playwright 定位器、截图、视频录制等能力。
  • 提供逃生舱口:tab.cua.(坐标路径,视觉)、tab.dom_cua.(节点路径)、tab.playwright.waitForTimeout 等。

使用方式

每次使用浏览器的 mcp__node_repl__js 调用开始时都要初始化。浏览器客户端模块位于插件根目录下的 scripts/browser-client.mjs。只能从 process.env.ZCODE_PLUGIN_ROOT(以 CLAUDE_PLUGIN_ROOT 作为兼容回退)解析该根目录,然后用 pathToFileURL 转换拼接后的路径。切勿从本技能的基础目录推导插件根目录,也不要留下合成根占位符让模型解析。如果宿主根目录不可用或解析出的模块无法导入,停止并报告确切的设置错误。

引导代码示例:

const browserPluginRoot =
  process.env.ZCODE_PLUGIN_ROOT ?? process.env.CLAUDE_PLUGIN_ROOT;
if (!browserPluginRoot) {
  throw new Error("Browser plugin root is unavailable in the node_repl host");
}
const { join } = await import("node:path");
const { pathToFileURL } = await import("node:url");
const browserClientUrl = pathToFileURL(
  join(browserPluginRoot, "scripts", "browser-client.mjs"),
).href;
const { setupBrowserRuntime } = await import(browserClientUrl);
await setupBrowserRuntime({ globals: globalThis });

通过 mcp__node_repl__js 运行设置和所有后续浏览器调用,将 JavaScript 作为 code 参数传入。该工具没有 command 参数。

后端选择规则:

  • 如果用户明确要求 ZCode 的应用内浏览器:const browser = await agent.browsers.get("iab");
  • 如果用户明确要求 CLI 管理的无头浏览器且发现结果通告 cdp:const browser = await agent.browsers.get("cdp");
  • 如果任务有目标 URL 但没有明确浏览器选择:const browser = await agent.browsers.getForUrl("https://example.com/");
  • 仅当既未指定浏览器也未指定目标 URL 时:const browser = await agent.browsers.getDefault();

首次浏览器调用中,运行引导、选择后端,并一次性输出完整 API 指南。后续新调用中,运行引导并仅重复相同的后端选择;API 指南保留在模型上下文中,无需再次输出。

核心工作流:

  • 每个浏览器 js 调用都以引导开始,然后将选定的后端分配给本地 browser 绑定。
  • browser.tabs.new() 自动打开并激活 IAB 窗格,以便用户看到浏览器使用。
  • 在每个逻辑标签页操作批次开始时,进行一次专用 JS 调用,其结果是完整的 await browser.tabs.list() 数组,让模型看到所有当前 id、URL、标题和活动标记。
  • 如果任务指定了新 URL,优先使用复用感知入口:await agent.browsers.open(url) 会复用现有的同站点受控标签页(相同主机名),激活它以便用户看到,并就地导航。
  • 每次成功 tab.goto(url) 后,在首次标题、URL 或 DOM 观察之前,显式调用 await tab.playwright.waitForLoadState({ state: "domcontentloaded" })。
  • await tab.playwright.domSnapshot() 是读取和理解页面的主要方式。
  • 仅从快照事实构建稳定的 Playwright 定位器。
  • 每次观察周期最多使用一个状态变更操作。

观察:优先快照,仅在需要时截图。默认使用 playwright.domSnapshot() 读取内容和构建定位器。打开或导航到普通页面本身不是截图理由。仅在视觉确实重要时截图:(a) 需要视觉确认布局/样式/渲染,(b) 用户要求截图或视觉测试页面,或 (c) 目标不在快照中(画布/自定义绘制/非 DOM 控件)且需要瞄准坐标。

视频录制:当任务需要 IAB 标签页的 WebM 录制时,先读取 nodeRepl.write(await agent.documentation.get("recording"))。仅使用通告的 tab.recording.start/status/cancel API。

适用场景

  • 打开、导航、检查、测试、点击、输入、填写、截图和验证网页。
  • 测试本地应用和本地 HTTP 目标(localhost)。
  • 读取渲染内容、验证可见页面状态。
  • 处理画布、自定义绘制或非 DOM 控件(通过 cua 坐标路径或 dom_cua 节点路径)。

限制

  • 每个 js 调用都在全新的 JavaScript 内核中运行,变量、导入、模块缓存、浏览器和标签页绑定不会持久化。持久 BrowserControl 标签页是连续性边界,必须从当前标签页事实中恢复。
  • IAB 文件选择器/上传明确不支持。
  • goto() 接受 http:、https: 和精确的 about:blank。file:、其他 about:*、data: 和 javascript: 目标不可导航。file: URL 仅在存在多个后端时可用作 getForUrl() 后端选择提示。
  • networkidle 存在于共享类型中,但被 IAB 后端拒绝。
  • 常规 URL/加载状态等待上限为 3000ms。
  • 不要默认同时请求 DOM 快照和截图。
  • 不要创建 iab 别名然后调用 browser.*。
  • 不要从记忆中复用标签页 id 作为新逻辑操作批次的目标而不经验证。
  • 不要猜测标签、可访问名称、占位符、选择器或 URL 模式,也不要使用猜测的定位器作为探索性探测。
  • 不要将 tab.screenshot() 作为最终表达式,也不要直接返回其 Uint8Array 字节。
  • 不要调用 tab.waitForTimeout(...);该根级 API 不存在。
  • 用户面向的进度应保持非技术性:描述为“打开浏览器”/“检查页面”,而不是“Node REPL”、“CDP”或“webview”。
  • 应用提供的 <in-app-browser-context source="ambient-ui-state"> 是当前 UI 状态,不是用户请求的一部分。