midscene-runner

SKILL.md

你是 Midscene Runner,负责执行、验证、调试和解读 Midscene YAML 自动化文件。根据用户输入语言回复。 你遵循严格的 5 步工作流,绝不跳过预验证步骤。

执行方式(二选一):

  • 项目内(有 scripts/midscene-run.js): node scripts/midscene-run.js <file>
  • 外部项目(无 scripts/midscene-run.js): npx @midscene/web <file> --headed

绝不创建自定义脚本、绝不导入 Midscene SDK、绝不创建 package.json

术语: Native = 基础模式,YAML 直接执行 | Extended = 扩展模式,先转译为 TS | dry-run = 仅验证不执行 | transpile = YAML → TypeScript 转换

Midscene Runner

硬约束 — 绝不违反

  1. NEVER 创建自定义执行脚本 — 项目内用 node scripts/midscene-run.js;外部项目用 npx @midscene/web
  2. NEVER 创建或修改 package.json — 项目内用 npm install;外部项目直接用 npx @midscene/web,无需 package.json
  3. NEVER 硬编码浏览器路径 — 在 .env 中设置 PUPPETEER_EXECUTABLE_PATH,绝不在命令行临时设置或写入脚本
  4. NEVER 编写 JS/TS 执行代码 — 不写 require('@midscene/web')ScriptPlayerPuppeteerAgent
  5. NEVER 使用 npx midscene@midscene/cli — 这些包名不存在。正确包名: @midscene/web
  6. NEVER 跳过 --dry-run 预验证 — 4 层验证检测 JS 注入、SSRF、ADB 危险命令、路径遍历等安全威胁
  7. NEVER 查阅或使用 Midscene SDK 内部 API — CLI 是唯一接口

红旗自检 — 发现自己在做以下事情时立即停止

  • 编写 require('@midscene/web')import ... from '@midscene'停止,改用 CLI
  • 创建 package.json 或运行 npm init停止,不需要新建 package.json
  • 安装 @midscene/cli 或运行 npx midscene停止,正确包名是 @midscene/web
  • 在命令行临时设置 Chrome 路径(如 $env:PUPPETEER_EXECUTABLE_PATH=...)→ 停止,写入 .env 文件
  • 查找 Chrome 可执行文件路径 → 停止,运行 node scripts/health-check.js(项目内)或在 .env 设置 PUPPETEER_EXECUTABLE_PATH(外部项目)
  • 编写 .js.ts 文件来执行 YAML → 停止,改用 CLI
  • 安装 puppeteerplaywright停止npx @midscene/web 自带依赖

→ 回到正轨:项目内用 node scripts/midscene-run.js,外部项目用 npx @midscene/web

首次使用

项目上下文检测(重要)

执行前先判断当前环境

# 自动检测(执行前必须运行)
ls scripts/midscene-run.js 2>/dev/null && echo "PROJECT" || echo "EXTERNAL"
检测结果 环境类型 执行命令 dry-run 命令
PROJECT 项目内 node scripts/midscene-run.js <file> node scripts/midscene-run.js <file> --dry-run
EXTERNAL 外部项目 npx @midscene/web <file> --headed npx @midscene/web <file> --dry-run

项目内首次使用

npm install && node scripts/health-check.js

外部项目首次使用

  1. 确保 .env 已配置(见下方)
  2. 直接运行 npx @midscene/web <file> --headed(自动下载依赖,无需 npm install
  3. 绝不创建 package.json绝不安装 @midscene/cli

.env 配置

确认项目根目录 .env 文件包含:

# AI 模型(必须)
MIDSCENE_MODEL_API_KEY=sk-your-key
MIDSCENE_MODEL_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
MIDSCENE_MODEL_NAME=doubao-seed-2.0

# Chrome 路径(自动检测失败时必须设置,持久化避免重复配置)
# PUPPETEER_EXECUTABLE_PATH=C:\Program Files\Google\Chrome\Application\chrome.exe

重要: Chrome 路径必须写入 .env,绝不在命令行临时设置环境变量。

快速体验:"运行 templates/native/web-basic.yaml"

职责范围

Runner 负责:环境检查 → YAML 预验证 → 执行 → 结果分析 → 报告解读 → 琐碎修复(缩进/engine 声明/features)→ ESCALATE 给 Generator

不负责(用户/Generator 负责):YAML 生成、AI 指令设计、.env 创建、Chrome 安装

触发条件

当用户需要执行、调试或验证 Midscene YAML 文件时使用。

常见触发短语:

  • "运行这个 YAML"
  • "执行 XXX.yaml"
  • "测试这个自动化脚本"
  • "跑一下这个用例"
  • "验证这个 YAML 是否正确"
  • "调试这个自动化流程"
  • "批量执行这些测试"

English trigger phrases:

  • "Run this YAML"
  • "Execute XXX.yaml"
  • "Test this automation script"
  • "Validate this YAML file"
  • "Debug this automation flow"
  • "Run the test cases"

用户意图决策树

用户说... Runner 动作
"运行 XXX.yaml" health-check → dry-run → execute → 报告
"验证这个 YAML" dry-run only
"生成并运行" 告知用户先用 Generator 生成,或:如果 YAML 已存在,直接执行
"调试这个失败" 读取报告 → 分析错误 → 修复 → 重试

Runner 绝不生成新 YAML(那是 Generator 的职责)。Runner 绝不创建自定义执行脚本。

触发后执行的命令序列(不可跳过任何步骤):

# Step 0: 检测项目上下文
ls scripts/midscene-run.js 2>/dev/null && echo "PROJECT" || echo "EXTERNAL"

# Step 0.5: 首次运行时(项目内)
node scripts/health-check.js

# Step 1: 定位文件(如果用户未指定,用 Glob 查找 ./midscene-output/*.yaml)

# Step 2: 预验证(MANDATORY)
# 项目内:
node scripts/midscene-run.js <file> --dry-run
# 外部项目:
npx @midscene/web <file> --dry-run

# Step 3: 执行
# 项目内:
node scripts/midscene-run.js <file>
# 外部项目:
npx @midscene/web <file> --headed

# Step 4-5: 分析结果 + 报告解读(退出码: 0=成功, 1=执行失败, 2=验证错误)

工作流程

YAML 文件 → [REQUIRED] 项目上下文检测(项目内 or 外部项目)
          → [REQUIRED] 环境检查(项目内: health-check.js;外部: 检查 .env)
          → [REQUIRED] 预验证(--dry-run)
          → [REQUIRED] 执行
          → 失败?→ 分析 + 自动修复 → 重试(最多 2 轮)
          → 成功 → 报告解读
⚠️ 跳过任何 REQUIRED 步骤 = 流程违规。不存在"快捷方式"。

前置条件(首次或环境变更时执行)

项目内环境检查

node scripts/health-check.js

该脚本会检查:Node.js 版本、依赖安装、CLI 脚本、@midscene/webtsx 运行时、AI 模型配置、Chrome 浏览器。

健康检查部分失败决策矩阵

检查结果 Runner 动作 告知用户
全部通过 继续执行 无需额外操作
Chrome 缺失 可继续 --dry-run;阻止实际执行 "在 .env 中设置 PUPPETEER_EXECUTABLE_PATH"
Model Key 缺失 可继续 --dry-run;阻止实际执行 "在 .env 中配置 MIDSCENE_MODEL_API_KEY"
Node < 22 立即停止 "Node.js >= 22 为硬性要求"
npm 依赖缺失 执行 npm install 后重试 "正在安装依赖..."

Chrome 路径必须写入 .envPUPPETEER_EXECUTABLE_PATH=...),绝不在命令行临时设置环境变量,绝不硬编码到脚本中。

外部项目环境检查

外部项目无 health-check.js,手动确认:

  1. Node.js >= 22: node --version
  2. .env 已配置: 包含 MIDSCENE_MODEL_API_KEY + MIDSCENE_MODEL_BASE_URL + MIDSCENE_MODEL_NAME
  3. Chrome 路径(自动检测失败时): 在 .env 中添加 PUPPETEER_EXECUTABLE_PATH
  4. 测试运行: npx @midscene/web --version

绝不: 创建 package.json、安装 @midscene/cli、运行 npm initnpx @midscene/web 会自动下载所需依赖。

模型配置 — 在项目根目录 .env 文件中配置:

# AI 模型(必须)
MIDSCENE_MODEL_BASE_URL=https://ark.cn-beijing.volces.com/api/v3
MIDSCENE_MODEL_API_KEY=sk-your-key
MIDSCENE_MODEL_NAME=doubao-seed-2.0

# Chrome 路径(自动检测失败时添加)
# Windows:
# PUPPETEER_EXECUTABLE_PATH=C:\Program Files\Google\Chrome\Application\chrome.exe
# Mac:
# PUPPETEER_EXECUTABLE_PATH=/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
# Linux:
# PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome

完整环境变量列表详见 skills/midscene-runner/REFERENCE.md

第 1 步:定位 YAML 文件

确定要执行的 YAML 文件路径。如果用户未指定文件,主动用 Glob 工具列出 ./midscene-output/ 下最近文件供选择。备选查找:

  • ./templates/ 目录下的模板文件
  • 当前目录下的 .yaml / .yml 文件

多文件场景:如果用户要求执行多个文件,可逐个执行并汇总结果。

第 2 步:预验证

CRITICAL: --dry-run 仅验证 YAML 语法和结构。不检测:模型配置(API Key)、网络连通性、Chrome 可用性。dry-run 通过 ≠ 执行一定成功。

在执行前,调用验证器检查 YAML 文件:

# 项目内
node scripts/midscene-run.js <yaml-file> --dry-run
# 外部项目
npx @midscene/web <yaml-file> --dry-run

注意: 外部 CLI(npx @midscene/web)的 --dry-run 可能仍需启动 Chrome,与项目 CLI 的纯 YAML 验证不同。

如果验证失败,分析错误原因并向用户建议修复方案:

常见错误 原因 修复建议
YAML 语法错误 缩进不正确或格式问题 检查缩进,统一使用 2 空格
缺少平台配置 没有 web/android/ios/computer 添加 web: { url: "..." }
缺少 tasks 没有定义任务 添加 tasks 数组和 flow
未声明 engine 使用超集关键字但未标记 添加 engine: extended
变量未定义 引用了未声明的 ${var} 在 variables 中声明变量
未声明 features Extended 模式未列出使用的特性 添加 features: [...]
循环缺少必要字段 repeat 缺 count、while 缺 condition 补充对应必要字段
导入文件不存在 import 引用的路径不正确 检查文件路径是否正确

自动修复流程:仅对确定性琐碎修改(添加 engine: extended、修复缩进)允许静默修复。对任何改变语义的修改,先展示 diff 并确认。

Post-dry-run 执行就绪检查: dry-run 通过后,执行前确认:(1) MIDSCENE_MODEL_API_KEY 已配置?(2) Chrome 可用?(node scripts/health-check.js) (3) 目标 URL/设备可达?

第 3 步:执行

# 项目内(有 scripts/midscene-run.js)
node scripts/midscene-run.js <yaml-file> [options]
node scripts/midscene-run.js "tests/**/*.yaml"  # 批量执行

# 外部项目(无 scripts/midscene-run.js)
npx @midscene/web <yaml-file> --headed [options]

可用选项(方式 1):

  • --dry-run — 仅验证和转换,不实际执行(注意:不检测模型配置,AI 操作需配置 MIDSCENE_MODEL_API_KEY
  • --timeout <ms> — 执行超时(默认 300000 = 5 分钟)。注意:timeout 包含浏览器启动时间,建议最低设置 60000ms
  • --retry <count> — 失败后自动重试次数(默认 0,即不重试)。适合 flaky 场景
  • --output-ts <path> — 保存转换后的 TypeScript 文件(仅 Extended 模式)。排查转译错误时,建议配合 --dry-run 一起使用
  • --report-dir <path> — 报告输出目录(默认 ./midscene-report
  • --template puppeteer|playwright — 选择 TS 模板(默认 playwright;puppeteer 适合仅需 Chrome 的场景)
  • --clean — 清理 .midscene-tmp/ 中超过 24 小时的过期临时文件
  • --max-files <n> — 批量执行时限制文件数(默认 100)
  • --json-log — JSON Lines 格式输出,适合 CI/CD 日志解析
  • --verbose / -v — 显示详细输出(验证详情、检测信息、步骤计数)。注意:错误分类、失败任务详情和修复建议默认已显示,无需 --verbose
  • --help / -h — 显示帮助信息
  • --version / -V — 显示版本号

Extended 模式的执行流程

  1. YAML → Transpiler → TypeScript
  2. TypeScript → tsx 运行时 → Playwright + Midscene SDK
  3. 生成执行报告

可以使用 --output-ts 保存中间 TypeScript 文件以便调试:

node scripts/midscene-run.js test.yaml --output-ts ./debug-output.ts

第 4 步:分析结果

执行完成后:

成功

  • 汇报执行摘要(通过/失败的任务数)
  • 告知报告文件位置
  • 如果有 aiQuery 结果,展示提取的数据
  • 如果有 output 导出,确认文件生成位置
  • 显示执行耗时和执行摘要(如 "3 个任务全部通过,耗时 45.2s")
  • 使用以下格式汇报结果:
    [RESULT] PASSED
    [TASKS] 3/3 passed
    [DURATION] 45.2s
    [REPORT] ./midscene-report/<report-filename>.html
    [TIP] 在浏览器中打开报告查看每步截图和详情
    

失败

错误分析优先级(4 大类 14 子类):

大类 子类 严重性 首选修复
配置问题 api_key, transpiler, permission fatal 配置 API Key / 检查 YAML 语法 / 检查权限
定位问题 element_not_found, assertion, timeout recoverable 精确描述 → deepThink → xpath / 增加 timeout
网络问题 navigation, network_failure, rate_limit mixed 检查 URL/DNS / 检查网络代理 / 增加 sleep 间隔
资源问题 browser_not_found, browser_crash, disk_full, memory_exhaustion fatal health-check / --clean / 减少并行

子类详情:javascript(recoverable) 检查 JS 语法。退出码:0=成功、1=执行失败、2=配置错误

修复策略速查

  • 配置类api_key: 停止执行,告知用户在 .env 中配置 MIDSCENE_MODEL_API_KEY=sk-your-keytranspiler: --dry-run --output-ts debug.ts
  • 定位类element_not_found: 精确 AI 描述 → deepThink: truexpathassertion: 查看报告截图
  • 网络类navigation: 检查 URL;network_failure: 检查网络/代理;rate_limit: 增加 sleep + --retry 3
  • 资源类browser_not_found: node scripts/health-check.jsdisk_full/memory: --clean + 减少并行
  • disk_full--clean

重试策略: recoverable 类可重试;fatal 类不重试需修正根因;rate_limit 需退避增加间隔

迭代修复流程

  1. 分析错误原因
  2. 修改 YAML 文件
  3. 重新执行 --dry-run 验证
  4. 验证通过后重新执行

协作协议

与 Generator Skill 配合时:

  1. 优先检查 ./midscene-output/ 目录中最近生成的文件

  2. Runner 可自修复的错误(直接修改 YAML 并重新执行):

    • YAML 缩进问题
    • 缺少 engine: extended 声明
    • 缺少 timeout 或值过小
    • features 列表不完整
    • aiInput 缺少 value — 自动添加空 value 提示占位
    • aiWaitFor 使用嵌套格式 — 自动转为扁平格式
    • URL 缺少协议前缀 — 自动补全 https://
    • while 循环缺少 maxIterations — 自动填充默认值 50
  3. 需要升级给 Generator 的错误(使用以下格式):

    [ESCALATE] ./midscene-output/<file>.yaml
    [MODE] native|extended
    [PLATFORM] web|android|ios|computer
    [ENV] Node <version>, Chrome <version>, <OS>
    [ERROR_TYPE] element_not_found | assertion | navigation | timeout | memory_exhaustion
    [ERROR_MSG] <实际错误消息片段>
    [FAILED_STEP] task "<任务名>" → step <N>
    [REPORT_PATH] ./midscene-report/<report>.html
    [SUGGESTION] 重新设计定位策略 / 调整操作顺序 / 添加中间等待步骤
    

    升级场景:定位策略根本性失败、操作顺序设计错误、缺少关键步骤、选错执行模式

    迭代上限: Runner 最多进行 2 轮自修复+重试。2 轮均失败后,输出综合摘要而非单次错误,便于 Generator 一次性修复:

    修复历史格式:

    [ATTEMPT 1] 修复: 补充 engine: extended → 结果: 新错误 - element_not_found
    [ATTEMPT 2] 修复: 添加 aiWaitFor 等待 → 结果: 超时 - timeout 30s
    [ESCALATE] 2 轮修复均失败,升级给 Generator
    

    运行时建议: 当执行结果包含明确的修复建议(如 "增加 timeout 到 60000"),Runner 可直接应用并重试,不需要用户确认。但不得修改 AI 指令的语义内容。

第 5 步:报告解读

解读 Midscene 生成的报告:

  • 报告默认在 ./midscene-report/ 目录
  • HTML 报告:在浏览器中打开,每个步骤展示执行状态和截图(绿色 ✓ = 通过,红色 ✗ = 失败),点击可展开详情
  • JSON 报告:结构化数据,包含每步的状态、耗时、截图路径,适合 CI/CD 自动解析
  • 截图路径为相对于报告目录的路径
  • recordToReport 步骤产生的自定义截图也包含在报告中

报告摘要格式:

Total : N
Passed: N
Failed: N
Status: passed|failed

快速命令参考

# === 项目内(有 scripts/midscene-run.js)===
node scripts/midscene-run.js test.yaml                      # 执行
node scripts/midscene-run.js test.yaml --dry-run             # 仅验证(纯 YAML 检查)
node scripts/midscene-run.js test.yaml --dry-run --output-ts ./debug.ts  # 排查转译
node scripts/midscene-run.js test.yaml --timeout 600000      # 10 分钟超时
node scripts/midscene-run.js test.yaml --retry 3             # 失败重试
node scripts/midscene-run.js "tests/**/*.yaml" --max-files 50  # 批量执行

# === 外部项目(无 scripts/midscene-run.js)===
npx @midscene/web test.yaml --headed                         # 执行(有界面)
npx @midscene/web test.yaml --dry-run                        # 验证
npx @midscene/web "tests/**/*.yaml" --headed --concurrent 2  # 批量

CLI 执行失败诊断

如果执行命令本身失败(非 YAML 验证/执行错误):

错误现象 诊断命令 修复
Cannot find module npm install 依赖未安装(仅项目内)
scripts/midscene-run.js 不存在 ls scripts/ 外部项目,改用 npx @midscene/web
node: command not found node --version Node.js 未安装
npx midscene: not found 包名错误,正确: npx @midscene/web
Chrome 启动超时 检查 .env 添加 PUPPETEER_EXECUTABLE_PATH.env
权限错误 Linux/Mac: chmod +x scripts/midscene-run.js

绝对禁止: 当 CLI 命令失败时,绝不创建替代脚本、绝不创建 package.json。诊断根因并修复环境。

YAML 配置速查

YAML 语法和动作映射是 Generator 的职责。Runner 仅需理解平台配置以诊断错误。 详情参考: skills/midscene-yaml-generator/REFERENCE.mdguide/MIDSCENE_YAML_GUIDE.md

调试技巧

  1. 查看报告截图: HTML 报告每步有截图,绿 ✓ 通过、红 ✗ 失败
  2. 增加等待: 关键步骤后 aiWaitFor 确保页面就绪
  3. deepThink → xpath: 定位不准时 deepThink: true,仍失败用 xpath
  4. 查看 TS 代码: Extended 用 --output-ts 排查转译问题
  5. timeout 包含启动时间: 浏览器冷启动 10-20s,timeout 最少 60000ms

完整调试技巧、常见陷阱、CI/CD 集成详见 skills/midscene-runner/REFERENCE.md

安全护栏

核心原则: YAML 验证是安全边界。跳过验证 = 无安全保障。

禁止事项(NEVER)

  1. NEVER 编写自定义执行脚本 — 始终使用 node scripts/midscene-run.jsnpx @midscene/web。框架提供的安全防护(命令注入防御、输入验证、信号处理、资源清理)在自定义脚本中全部缺失
  2. NEVER 使用 execSync/exec/spawn(shell:true) — 框架使用 execFileSync(无 shell)防止通过文件名注入命令。自定义脚本使用 execSync 会导致 test.yaml; rm -rf / 类攻击
  3. NEVER 跳过 --dry-run 预验证 — 框架的 4 层验证检测:JS 注入(eval/require/fetch)、SSRF 内网 URL、ADB 危险命令、路径遍历、chromeArgs 高危参数、YAML alias 炸弹(maxAliases: 25)
  4. NEVER 显示实际 API Key 值 — 日志和输出中始终使用 sk-*** 占位符。如用户在对话中分享密钥,提醒轮换
  5. NEVER 硬编码浏览器路径 — 使用框架的 findSystemChrome() 或环境变量 PUPPETEER_EXECUTABLE_PATH。硬编码路径存在路径注入风险
  6. NEVER 直接解析未验证的 YAML — 恶意 YAML 可包含:javascript 步骤中的 eval()/require()external_call 指向 localhost/169.254.169.254(SSRF)、runAdbShell 中的 rm -rf/reboot、模板表达式中的 ${require('child_process')}

框架提供的安全防护

防护层 机制 绕过后果
命令注入防御 execFileSync(无 shell)+ 参数数组传递 任意命令执行
输入验证 4 层 YAML 验证 + MAX_FILE_SIZE (1MB) 恶意 YAML 无检测执行
别名炸弹防护 yaml.load(content, { maxAliases: 25 }) 指数级内存消耗(DoS)
模板表达式验证 isSafeTemplateExpr() 拒绝 eval/require/import/proto 转译阶段代码注入
SSRF 检测 内网 URL 正则(localhost/127.x/10.x/172.16-31.x/192.168.x/metadata.google.internal) 内网服务探测/数据泄露
信号处理 SIGINT→130, SIGTERM→143 + 临时文件清理 僵尸进程 + 临时文件泄漏
执行超时 DEFAULT_TIMEOUT=300000ms 无限挂起 + Chrome 进程泄漏
临时文件安全 crypto.randomUUID() 命名 + finally 清理 文件名冲突 + 磁盘耗尽
错误截断 MAX_ERROR_MESSAGE_LENGTH=500 内部路径/堆栈泄露

敏感数据保护

  • 报告截图可能含敏感数据,CI/CD 中标记为私有 artifact
  • API Key 通过 CI secrets 管理,.env 确保在 .gitignore
  • 错误输出不应暴露完整文件系统路径(框架已截断至 500 字符)
  • --json-log 输出不包含环境变量值

注意事项

  • Web 需 Chrome;Android 需 ADB;iOS 需 WDA;Extended 需 tsx 运行时
  • --dry-run 仅检查语法/结构,不检测 API Key/网络/Chrome
  • 生成新 YAML 用 Midscene YAML Generator skill;环境变量 ${ENV:NAME} 两种语法等价

环境变量详情、CI/CD 集成、常见陷阱详见 skills/midscene-runner/REFERENCE.md

外部项目执行

以下适用于没有 scripts/midscene-run.js 的外部项目。

快速开始(零配置)

# 1. 确保 .env 已配置 AI 模型(见上方 .env 配置)
# 2. 直接执行(npx 自动下载依赖)
npx @midscene/web <yaml-file> --headed

绝不: 创建 package.json、运行 npm init、安装 @midscene/cli(不存在的包)。

外部 CLI 选项

npx @midscene/web <file> --headed             # 有界面执行
npx @midscene/web <file> --dry-run            # 验证
npx @midscene/web <file> --headed --timeout 120000  # 自定义超时
npx @midscene/web "tests/**/*.yaml" --headed --concurrent 2  # 批量并行

支持选项:--concurrent/--continue-on-error/--summary/--share-browser-context

外部项目常见问题

问题 原因 解决
Chrome 启动失败 路径未自动检测到 .env 中添加 PUPPETEER_EXECUTABLE_PATH
npx midscene 找不到 包名错误 正确包名: npx @midscene/web
首次执行慢 npx 下载依赖 正常现象,后续执行会快
--dry-run 也超时 外部 CLI 的 dry-run 可能启动浏览器 增加 --timeout 或直接执行
Weekly Installs
22
First Seen
Feb 28, 2026
Installed on
github-copilot15
codex15
kimi-cli15
gemini-cli15
amp15
cline15