web-automation-builder
Web Automation Builder
被动录制用户在浏览器中的操作,生成可重放的自动化工作流。
核心模式:用户自由操作 + 系统被动录制(非 LLM 驱动)。
安装 / 更新
# 安装(安装依赖 + 构建)
node skills/web-automation-builder/tool.js install
# 全局安装(复制到 ~/.cursor/skills/ + 安装依赖)
node skills/web-automation-builder/tool.js install '{"target":"~/.cursor/skills/web-automation-builder"}'
# 更新(从源码覆盖 + 清理重装)
node skills/web-automation-builder/tool.js update '{"target":"~/.cursor/skills/web-automation-builder"}'
前置依赖
| 依赖 | 说明 | 安装方式 |
|---|---|---|
| Playwright Skill | 浏览器启动和操作命令 | ~/.cursor/skills/playwright/ |
| playwright-core | CDP 连接库 | npm install(package.json 已声明) |
CLI 命令
node skills/web-automation-builder/tool.js <command> '<JSON参数>'
录制控制
# 开始被动录制(启动浏览器 + 注入 DOM 监听 + 启动网络监听)
node tool.js record '{"name":"部署后端代码"}'
# 查看录制状态(已收集的事件数量)
node tool.js status '{}'
# 停止录制(返回原始录制数据:DOM 事件 + API 请求)
node tool.js stop '{}'
# 保存 LLM 分析后的结构化工作流
node tool.js save '{"id":"wf-xxx","workflow":{...}}'
工作流管理
node tool.js list '{}'
node tool.js show '{"id":"wf-xxx"}'
node tool.js delete '{"id":"wf-xxx"}'
重放
# 批量重放(快速路径)
node tool.js replay '{"id":"wf-xxx"}'
node tool.js replay '{"id":"wf-xxx","params":{"username":"admin","password":"123"}}'
# 从指定步骤恢复
node tool.js replay '{"id":"wf-xxx","startFrom":3,"params":{...}}'
LLM-First 逐步重放(推荐)
# 获取步骤列表(含 intent、locators),LLM 阅读后决定每步执行策略
node tool.js replaySteps '{"id":"wf-xxx"}'
# 执行单个步骤(1-based)
node tool.js replayStep '{"id":"wf-xxx","step":1,"params":{"key":"value"}}'
LLM 根据每步的 intent 和置信度,选择用 replayStep 工具执行或直接用 playwright 手动操作。
录制期间辅助操作(Phase 4)
Agent 在录制期间可以通过 exec 命令直接调用 Playwright 辅助用户操作:
# 导航到特定 URL
node tool.js exec '{"command":"navigate","args":{"url":"https://example.com"}}'
# 点击元素
node tool.js exec '{"command":"click","args":{"selector":"#some-button"}}'
# 填写表单
node tool.js exec '{"command":"type","args":{"selector":"#input","text":"value"}}'
生成独立 Skill
# 默认:生成 Skill(SKILL.md + tool.js + workflow.json + package.json)
node tool.js generate '{"id":"wf-xxx","skillName":"deploy-staging","target":"~/.cursor/skills/deploy-staging"}'
# 同时生成 Playwright 脚本(Skill 产物 + deploy-staging.js)
node tool.js generate '{"id":"wf-xxx","skillName":"deploy-staging","target":"~/.cursor/skills/deploy-staging","includePlaywright":true}'
# 仅生成 Playwright 脚本(不生成 Skill 产物)
node tool.js generate '{"id":"wf-xxx","skillName":"deploy-staging","target":"./scripts","format":"playwright"}'
导出 Playwright 脚本(单文件)
node tool.js export '{"id":"wf-xxx","output":"./my-automation.js"}'
自主决策指南
LLM 在录制流程中的行为协议:
录制流程(LLM 必须严格按此顺序执行)
1. 用户请求录制 → 调用 record 命令
2. record 返回成功(包含 id、pid)→ 立即执行步骤 3
3. 弹出 agent-interact wait 对话框(见下方代码)
- 浏览器窗口会自动打开,用户可直接操作
- 用户点击对话框"确认"按钮表示操作完成
4. 用户确认后 → 调用 stop 命令 → 获取 rawEvents
5. LLM 分析 rawEvents → 生成分析报告
6. 弹出 agent-interact custom 对话框展示分析报告(见下方代码)
- 展示操作流程摘要、事件统计、可参数化的值
- 提供文本输入区域让用户补充说明
- 用户选择"生成并保存"或"不需要"
7. 用户确认后 → 生成结构化工作流 JSON → 调用 save 保存
8. 弹出 agent-interact custom 对话框询问产物生成(见下方代码)
- 提供生成模式选择(Skill / Skill+Playwright / 仅Playwright)
- 提供 Skill 名称和目标路径输入
- 用户选择"生成"或"跳过"
9. 用户确认后 → 调用 generate 命令生成产物
重要:步骤 8 必须通过 agent-interact 弹框交互,禁止在对话文本中提问。所有需要用户选择或输入的环节都应使用 agent-interact。
agent-interact 强制交互规则
核心原则:在整个录制流程中,所有需要用户选择、确认或输入的环节,必须通过 agent-interact 弹框完成。禁止在对话文本中提问或列出选项让用户回复。
违反此规则的典型错误:
- ❌ 在对话中写"需要我生成 Skill 吗?请选择:1. Skill 2. Playwright"
- ❌ 在对话中写"请告诉我 Skill 名称和目标路径"
- ✅ 调用 agent-interact dialog 弹出选择/输入对话框
必须使用 agent-interact 的环节:
- 步骤 3:录制等待(wait 类型)
- 步骤 6:分析报告展示 + 确认(custom 类型)
- 步骤 8:产物选择 + 参数输入(custom 类型)
调用方式(选择一种可用的路径):
# 方式 1:项目内 skill
node skills/agent-interact/tool.js dialog '<JSON>'
# 方式 2:全局安装的 skill
node ~/.cursor/skills/agent-interact/tool.js dialog '<JSON>'
降级策略:仅当 agent-interact skill 完全不存在时,才降级为对话模式。
注意:
- LLM 不应在 record 和 agent-interact 之间插入任何其他操作或对话。
- agent-interact dialog 命令是阻塞的(等用户点击才返回),应设置足够长的超时等待(如
block_until_ms: 3600000),不要用sleep + 轮询方式。
录制等待对话框(步骤 3)
record 命令返回成功后,必须立即弹出等待对话框:
node skills/agent-interact/tool.js dialog '{"type":"wait","title":"🔴 正在录制浏览器操作","message":"浏览器已打开,请在浏览器中完成所有操作。\n操作完成后点击下方按钮停止录制。","confirmText":"✅ 操作完成,停止录制","timeout":3600}'
分析报告对话框(步骤 6)
stop 命令返回后,LLM 分析 rawEvents 并通过 agent-interact custom 对话框展示报告:
node skills/agent-interact/tool.js dialog '{"type":"custom","schemaVersion":"1.0","title":"📊 录制分析报告","timeout":1200,"content":[{"kind":"kv","items":[{"key":"录制名称","value":"<name>"},{"key":"时长","value":"<duration>"},{"key":"DOM 事件","value":"<domCount>"},{"key":"网络请求","value":"<networkCount>"}]},{"kind":"divider"},{"kind":"heading","value":"操作流程","level":3},{"kind":"text","value":"<步骤列表>"},{"kind":"divider"},{"kind":"heading","value":"可参数化的值","level":3},{"kind":"text","value":"<参数列表>"},{"kind":"divider"},{"kind":"textarea","id":"notes","label":"补充说明(可选)","placeholder":"如有需要补充的信息请在此输入..."}],"actions":[{"id":"save","label":"✅ 生成并保存","submit":true},{"id":"cancel","label":"❌ 不需要"}]}'
用户点击"生成并保存"后,LLM 根据 rawEvents + 用户补充信息生成工作流 JSON 并保存。
产物选择对话框(步骤 8)
save 命令成功后,必须立即弹出 agent-interact custom 对话框让用户选择产物形态:
node skills/agent-interact/tool.js dialog '{"type":"custom","schemaVersion":"1.0","title":"🎯 生成产物选择","timeout":300,"content":[{"kind":"kv","items":[{"key":"工作流名称","value":"<name>"},{"key":"工作流 ID","value":"<id>"},{"key":"步骤数","value":"<stepCount>"}]},{"kind":"divider"},{"kind":"heading","value":"选择生成方式","level":3},{"kind":"select","id":"generateMode","label":"生成模式","options":["Skill 产物(SKILL.md + tool.js + workflow.json + package.json)","Skill + Playwright 脚本(两者兼有)","仅 Playwright 脚本(不生成 Skill)"],"default":"Skill + Playwright 脚本(两者兼有)"},{"kind":"divider"},{"kind":"input","id":"skillName","label":"Skill 名称","placeholder":"例如:deploy-staging"},{"kind":"input","id":"targetPath","label":"目标路径","placeholder":"例如:~/.cursor/skills/deploy-staging"}],"actions":[{"id":"generate","label":"✅ 生成","submit":true},{"id":"skip","label":"⏭️ 跳过","variant":"outline","submit":false}]}'
用户选择后,LLM 根据 generateMode 字段调用 generate 命令:
- "Skill 产物..." →
generate '{"id":"<id>","skillName":"<name>","target":"<path>"}' - "Skill + Playwright..." →
generate '{"id":"<id>","skillName":"<name>","target":"<path>","includePlaywright":true}' - "仅 Playwright..." →
generate '{"id":"<id>","skillName":"<name>","target":"<path>","format":"playwright"}'
如果用户未填写 skillName 或 targetPath,LLM 应根据工作流名称自动生成合理的默认值。
custom dialog schema 强制约束
调用 agent-interact custom 对话框时,必须严格遵守以下规则:
- 必须包含
"schemaVersion":"1.0" - content 数组中每个节点使用
kind字段(不是type),值的字段用value(不是text) - 按钮使用
actions数组(不是buttons),每个 action 包含id、label,可选submit、variant - 可用的 kind 值:
text、heading、divider、alert、badge、kv、progress、chart、code、image、table、input、select、checkbox、textarea、row、column、grid、section、group
错误处理:调用 agent-interact dialog 后,必须检查返回结果。如果返回 "error": "Invalid custom schema" 或 exit code 非 0,LLM 应:
- 读取
details中的错误信息 - 根据错误修正 JSON schema(常见错误:
type→kind,text→value,buttons→actions,缺少schemaVersion) - 重新调用 dialog 命令
何时建议录制
| 场景 | 操作 |
|---|---|
| 用户要求执行重复性浏览器操作 | 主动建议录制 |
| 用户说"录制"、"记录操作"、"学习操作" | 执行录制流程 |
| 录制完成后 | 弹出产物选择对话框 |
| 用户说"重放"、"再执行一次" | 执行 replay |
LLM 分析 rawEvents 的要求
stop 返回的 rawEvents 包含 DOM 事件和网络请求的原始数据。LLM 需要:
- 过滤噪音:去除无关点击(空白区域)、无意义滚动
- 合并输入:连续的 input 事件合并为单次填写操作;同一输入框的多次 change/input 事件只保留最终值
- 捕获操作意图(关键,影响 LLM 自愈能力):
- 每步必须包含
intent字段,格式:「[在什么上下文中] + 操作目标 + [期望产生的页面变化]」 - 示例(正确):「在部署任务列表第一行,点击 Deploy 按钮,以打开部署配置对话框」
- 示例(不足):「点击 Deploy」(缺少上下文和期望结果,LLM 无法用于自愈)
description字段保留简短描述,intent字段承载完整语义
- 每步必须包含
- 识别参数:将可变输入值替换为
{{paramName}} - 关联 API:将 DOM 操作与触发的 API 请求关联
- 生成等待条件(
waitAfter字段,优先于固定时间等待):- 导航后:等待目标页面关键元素出现
{ "type": "selector", "value": ".some-key-element" } - 点击触发 modal:等待 modal 容器出现
{ "type": "selector", "value": ".modal-container" } - 提交后等待完成:等待加载状态消失
{ "type": "selectorGone", "value": ".loading-spinner" } - 页面跳转:等待 URL 变化
{ "type": "url", "value": "/target-path" }
- 导航后:等待目标页面关键元素出现
- 识别 UI 容器模式:
- 点击按钮 → 弹出 modal:后续步骤的 intent 和 locator 应说明「在弹出对话框中」
- 下拉菜单展开:选项的 intent 应说明「在展开的下拉菜单中」
- 表格行操作:intent 应包含行锚定信息,如「在显示 job-name-xxx 的那一行中」
- 事件去重:同一元素连续多次 click 合并为一次;导航后 500ms 内的误触点击丢弃
- 保留 locator 元数据:
roleName:录制脚本自动提取的 accessible name(aria-label / label[for] / aria-labelledby),生成 workflow 时必须保留context:录制脚本自动检测的容器上下文(modal / dropdown / table-row / form),生成 workflow 时必须保留在 locators 中- 这两个字段是
buildLocatorChain作用域限定和精确匹配的关键输入
分析后生成的工作流 JSON 通过 save 命令保存。
录制数据说明
DOM 事件类型
| type | 说明 | 关键字段 |
|---|---|---|
| click | 用户点击 | locators |
| input | 文本输入 | locators, value |
| select | 下拉选择 | locators, value, selectedText |
| check | 勾选复选框 | locators, checked |
| submit | 表单提交 | locators |
| keydown | 特殊按键(Enter/Tab/Escape) | key, modifiers |
| navigation | 页面导航 | url / fromUrl, toUrl |
网络请求
| 字段 | 说明 |
|---|---|
| request.url | 请求 URL |
| request.method | HTTP 方法 |
| request.body | 请求体(已解析 JSON) |
| response.status | 响应状态码 |
| response.body | 响应体(文本类 MIME,≤512KB) |
自动过滤静态资源(.js/.css/.png 等)和 tracking 请求。
参数化语法
工作流中的可变值使用 {{paramName}} 标记:
{
"command": "fill",
"args": { "text": "{{username}}" },
"locators": { "css": "#username", "placeholder": "Username" }
}
重放时通过 params 注入:
node tool.js replay '{"id":"wf-xxx","params":{"username":"admin"}}'
导出为 Playwright 脚本时,参数通过环境变量注入:
USERNAME=admin PASSWORD=secret node deploy-staging.js
产物形态
| 形态 | 命令 | 适合场景 |
|---|---|---|
| JSON 工作流 | save |
临时或低频操作 |
| 独立 Skill | generate |
高频复用、跨项目 |
| Skill + Playwright 脚本 | generate + includePlaywright |
两种方式都需要 |
| 仅 Playwright 脚本 | generate + format:"playwright" |
只需脚本,不需要 Skill |
| 单文件 Playwright 脚本 | export |
快速导出到指定路径 |
Playwright 脚本特性:
- 可直接
node script.js运行,不依赖 Cursor 或 Playwright Skill - 与 replayer.js 一致的 locator 链(testId > ariaLabel > placeholder > text > role > id > css)
- 支持 context 作用域(modal/dropdown)
- 支持 waitAfter 条件
- 每步 try-catch + 失败截图
- 参数通过环境变量注入
数据存储
~/.cursor/skills/
├── web-automation-builder/ # Skill 代码
└── web-automation-builder-data/ # 数据目录
├── workflows/ # 已保存的结构化工作流 JSON
├── recordings/ # 录制数据(按日期归档)
│ ├── 2026-02-23-wf-xxx.json # 精简 summary(DOM事件+导航+API请求)
│ └── ...
├── chrome-profile/ # Chrome 用户数据(认证缓存持久化)
└── .recording.json # 录制中的临时状态(stop 后删除)
触发词
- 录制浏览器操作、开始录制、帮我录制
- 重放工作流、再执行一次、用新参数执行
- 生成 Skill、做成 Skill、以后直接用
- 导出脚本、导出为 JS
- 查看录制、工作流列表
More from shetengteng/skillix-hub
swagger-api-reader
读取并缓存 Swagger/OpenAPI 文档供模型使用。当用户需要添加、读取、刷新 API 文档,或使用 Swagger URL 时触发。
15web-content-reader
读取网页内容,支持 SPA 页面自动检测与浏览器渲染降级。当普通 HTTP fetch 无法获取 Vue/React 等 SPA 页面的渲染数据时,自动通过 Playwright 浏览器获取完整内容。当用户需要读取网页数据、提取页面内容、或 WebFetch 工具返回空内容时使用。
6socratic
苏格拉底式批判性思维分析。自动识别需求分析、系统设计、技术选型、数据分析四类场景,智能决定快速结论(≤1问)或深度探索(≤5问),防止过度追问与草率结论。Socratic critical thinking for requirements, design review, tech research, and data analysis.
1memory
|
1skill-store
|
1skill-builder
|
1