mcpField
F
flowchad-runner

flowchad-runner

github.com/fellowship-dev测试与质量3202 次安装2 周前更新
代码仓库

关于 flowchad-runner

flowchad-runner 是用于验证 FlowChad 浏览器流程的技能,适用于合并前、部署后及定期运行。它逐个执行流程、采集视觉证据,并将结果写入 GitHub 和本地报告。

主要功能

  1. 01按顺序执行浏览器流程
  2. 02逐步采集截图和视频证据
  3. 03遇到 CAPTCHA 时交由 Navvi
  4. 04上传证据并向 GitHub 报告
  5. 05生成本地报告和结果状态

适用场景

  1. 01验证 PR 修改影响的流程
  2. 02部署后运行生产环境检查
  3. 03定期执行关键流程冒烟测试
  4. 04在配置 CAPTCHA 行为后本地排查流程

MCP 相关

该技能在浏览器流程执行期间,将 Navvi 用作处理 CAPTCHA 的 MCP 工具。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/fellowship-dev/dogfooded-skills --skill flowchad-runner

安装后在 Claude Code 中输入/flowchad-runner确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CONTEXT.md
references/
interactive-contract.md
scripts/
test_validate_contract.py
validate_contract.py
stages/01-preflight/
CONTEXT.md
stages/02-load-flows/
CONTEXT.md
stages/03-walk-flows/
CONTEXT.md
stages/04-upload-evidence/
CONTEXT.md
stages/05-report/
CONTEXT.md

详细介绍

flowchad-runner

使用 Playwright/Navvi 验证指定的 FlowChad 工作流,捕获每个步骤的屏幕截图和视频证据,遇到 CAPTCHA 时自动切换到 Navvi,尽力上传证据,然后将结果发布到 GitHub 并写入本地报告。每个阶段都由具有独立上下文的专用子 Agent 执行。这里的 ICM 重点是清晰的阶段契约 + 可恢复性,而不是并行处理:工作流不能并发运行,因为它们共享浏览器、会话和角色状态,并会相互冲突。阶段 03 会在顺序循环中逐个运行工作流。

适用场景

  • 对影响已声明工作流的 PR 进行明确的合并前验证
  • 部署后进行生产环境验证
  • 每周或按计划执行关键生产环境冒烟测试
  • 已明确配置本地 CAPTCHA 行为时,手动进行本地诊断

不适用场景

  • 仅涉及文档、Dependabot 或不受影响的 PR:返回 N/A,且不创建预览
  • 将仅静态分析描述为交互式认证
  • 全局启用 Provider 自动预览;预览必须按需明确启动

参数

Param必填默认值备注
flow-name是—工作流名称,或以下选择器之一:affected / all
repo是—目标 org/repo
pr-number否(无)如果已设置,则向此 PR 发布结果评论
trigger否manualpr | merge | cron | manual — 用于驱动 URL 解析和部署等待

从 $ARGUMENTS 按位置解析:$1=flow-name $2=repo $3=pr-number $4=trigger。 当 cron/manual 调用没有 PR 编号时,使用字面值 none。

选择器不是工作流名称。 仅当 $1 既不是 affected 也不是 all 时,它才是工作流名称:

flow-name解析为
affectedaffects glob 与 PR 已更改文件匹配的工作流——生产环境用法,每个 flowchad-on-double-checked 分发任务都会使用
allsmoke.flows,若无则使用 smoke.critical,再无则使用 .flowchad/flows/ 中的文件
(某个名称)与受影响集合取交集后的该工作流
(任意值,trigger=cron)smoke.critical

绝不能将 affected 或 all 解析为 .flowchad/flows/<selector>.yml。将字面字符串 affected 与实际工作流名称取交集会得到空集合,并导致真正影响某个工作流的 PR 被错误地返回 N/A。

结果约定

状态含义
PASSED必需步骤已通过,并提供了真实的浏览器证据
FAILED浏览器证据表明产品或工作流存在缺陷
BLOCKED必需的目标、部署、浏览器、角色或凭据不可用
N/APR 仅涉及文档、Dependabot,或不影响任何已声明的工作流

交互式工作流绝不能仅凭 curl、静态 HTML 或 bundle 检查判定通过。创建或升级 .flowchad/config.yml 和工作流定义时,请阅读 references/interactive-contract.md。

功能

5 阶段 ICM 流程(全部按顺序执行——没有并行阶段):

阶段模式描述
01-preflight子 Agent验证契约,解析流程选择器,解析目标/选择性预览,等待部署完成,检查捕获主机/角色
02-load-flows子 Agent读取 .flowchad/config.yml,验证每个流程文件是否存在,加载流程 YAML,解析证据后端
03-walk-flows子 Agent生成一个工作 devbox(操作端没有浏览器),然后进行顺序循环:逐个处理每个流程——连接浏览器、运行步骤、逐步截图、判断预期结果、CAPTCHA→Navvi、记录对话
04-upload-evidence子 Agent上传带有 evidence_class: visual 的截图/GIF(永久 URL),记录每个文件的成功/失败情况,在有请求对话时附上一份未分类的副本,并停止工作进程
05-report内联汇总结果,嵌入每一步的截图 URL,发布判定 PR 评论(以机器可读的 `` 标记开头)+ 应用仍具决定作用的 chad-approves/chad-rejects 标签;在有请求 Slack 线程时向其中发布判定结果;失败时创建问题;写入本地报告;发出结果标记
浏览器实际运行的位置

Dockerfile.operator 不会安装浏览器系统库;.devcontainer/Dockerfile(仓库 devbox/工作进程镜像)会准确安装 Chromium 所需的库。因此,Playwright 捕获会在阶段 03 启动的工作 devbox 上运行,而 Navvi——绑定到操作端会话的 MCP 工具——则在操作端轮次中运行。在操作端轮次中尝试 chromium.launch() 会失败,并报错 "missing system shared libraries … no sudo/apt-get available",从而产生不含截图的 BLOCKED 判定。负责分发的自动化上下文已经说明 "Use qa worker."

携带 flowchad-runner 的操作端 pylot.qa 和 booster-pack.qa 都携带 pylot-cli(注入的基线工具,因此每个操作端都具备)和 evidence-upload,这些已涵盖操作端所需的一切。它们不需要安装 playwright 或 visual-evidence:浏览器要求属于工作进程镜像,而非操作端。

交接位置

所有交接内容都位于解析后的仓库工作区($WORKDIR,见工作区解析)中:

$WORKDIR/.procedure-output/flowchad-runner/{stage}/handoff.md

阶段 01 会写入已解析的运行上下文(URL、角色、流程列表)。每个子 Agent 阶段只会收到其 CONTEXT.md 列为输入的交接路径——绝不会收到编排器历史记录。

执行

严格按顺序逐个运行各阶段。此流程中不会并行启动 Task。每个子 Agent 阶段恰好启动一个 Task,并等待其完成后再启动下一阶段。

工作区解析(务必首先执行)

契约、流程、交接文件和报告都位于目标仓库的检出目录中。任务运行所在的工作区不包含该检出目录——切勿假设当前目录就是仓库。执行任何其他操作之前,请先以确定性方式解析该目录:

SKILL_DIR="$HOME/.claude/skills/flowchad-runner"
[ -d "$SKILL_DIR" ] || SKILL_DIR="$(pwd)/.claude/skills/flowchad-runner"

if [ -f .flowchad/config.yml ]; then
  # Already inside a checkout (local/manual runs)
  WORKDIR="$(pwd)"
else
  REPO_NAME="${REPO##*/}"
  REPO_DIR="/tmp/flowchad-${REPO_NAME}"
  if [ ! -d "$REPO_DIR/.git" ]; then
    # Plain https URL — inline credentials would bypass git-credential-pylot
    git clone "https://github.com/${REPO}.git" "$REPO_DIR" 2>/dev/null \
      || gh repo clone "$REPO" "$REPO_DIR"
  fi
  cd "$REPO_DIR"
  git fetch origin --prune
  if [ "$TRIGGER" = pr ] && [ -n "$PR_NUMBER" ] && [ "$PR_NUMBER" != none ]; then
    # Validate the PR's OWN contract — flows/config may change in the PR itself
    git fetch origin "pull/${PR_NUMBER}/head:flowchad-pr-${PR_NUMBER}" --force
    git checkout -f "flowchad-pr-${PR_NUMBER}"
  else
    DEFAULT_BRANCH=$(gh repo view "$REPO" --json defaultBranchRef -q .defaultBranchRef.name)
    git checkout -f "$DEFAULT_BRANCH"
    git reset --hard "origin/${DEFAULT_BRANCH}"
  fi
  WORKDIR="$REPO_DIR"
fi
[ -f "$WORKDIR/.flowchad/config.yml" ] || {
  echo "[flowchad] blocked: $REPO has no .flowchad/config.yml at the resolved ref"
  exit 0
}

如果因缺少配置而退出,请将以下解析后的标记作为助手的最后一行完整内容输出(不要从 Bash 输出,也不要放在代码围栏中),然后停止:

[pylot:$PYLOT_OUTCOME_NONCE] outcome="flowchad blocked: $REPO has no .flowchad/config.yml at the resolved ref" status=blocked

之后的每条命令(验证器、阶段交接、报告)都必须通过 cd "$WORKDIR" 运行。 由于子 Agent Task 不会继承编排器的 cd,阶段提示词必须包含绝对路径:将下方模板中的 $WORKDIR 和 $SKILL_DIR 替换为其字面值——绝不能传递 .claude/... 或 .procedure-output/... 这样的相对路径。

阶段 01 → 04(顺序执行的子 Agent)

每个阶段都启动一个 Task。Task 提示词必须独立完整:

  • 仅包含该阶段的输入交接路径
  • 包含该阶段的 CONTEXT.md 路径
  • 不要传入编排器历史记录或先前的推理

Task 提示词模板:

You are running stage {NN}-{name} of the flowchad-runner procedure.

Workspace: cd {WORKDIR} before any step (absolute path — all relative paths resolve there).

Read your stage instructions:
  {SKILL_DIR}/stages/{NN}-{name}/CONTEXT.md

Your inputs:
  {list each input handoff path this stage needs — absolute, under {WORKDIR}}

Write your output to:
  {WORKDIR}/.procedure-output/flowchad-runner/{NN}-{name}/handoff.md

Execute all steps in CONTEXT.md. Write handoff.md before exiting.

{WORKDIR} 和 {SKILL_DIR} 是在 Workspace resolution 中解析出的绝对路径。

当前阶段完成前,不要启动下一阶段。如果阶段 01 无法解析出 TARGET_URL,或阶段 01 的 deploy-wait 失败,或阶段 02 发现流程文件缺失,则输出对应的结果标记并停止(这些阶段也会自行创建 GitHub issues)。

阶段 01 开始前,从 $WORKDIR 确定性地验证已检入的契约:

cd "$WORKDIR"
mkdir -p .procedure-output/flowchad-runner
MODE="$TRIGGER"
[ "$MODE" = merge ] && MODE=production
[ "$MODE" = pr ] && MODE=preview
[ "$MODE" = manual ] && MODE=local
python3 "$SKILL_DIR/scripts/validate_contract.py" \
  --mode "$MODE" --repo "$REPO" --format json \
  > .procedure-output/flowchad-runner/contract.json

任何验证器错误都会阻止 production、preview 和 cron certification。对于这些模式,不要静默回退到旧版 .url、模板标识或 localhost。

阶段 05(内联执行)

在编排器中自行运行阶段 05。阅读 CONTEXT.md:

.claude/skills/flowchad-runner/stages/05-report/CONTEXT.md

汇总先前的交接信息、发布 PR 评论/创建失败 issues、写入本地报告文件,并由编排器输出 [pylot] outcome=... 标记(绝不能由子 Agent 输出)。

阶段交接链

01-preflight ─► 02-load-flows ─► 03-walk-flows ─► 04-upload-evidence ─► 05-report (inline)
   (URL,            (validated        (SPAWN WORKER,     (permanent URLs        (PR comment
   persona,          flow YAML,        sequential         per step, upload        WITH the
   capture_host,     evidence          per-flow walk,     accounting,             screenshots,
   FLOWS_TO_RUN)     backend)          results+transcript) STOP WORKER)           issues, marker)

工作器 devbox 跨越阶段 03→04:阶段 03 启动它并让它保持运行,以便阶段 04 上传其文件系统上的证据;阶段 04 将其停止。如果阶段 04 没有停止它,阶段 05 会将其作为后备措施停止。

退出路径

  • 成功:阶段 05 输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="flowchad {flow} on {repo}: all flows passed" status=success
  • 失败:阶段 05 输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="flowchad {flow} on {repo}: {N} flow(s) failed" status=failed (阶段 05 已创建失败 issues)
  • 阻止:阶段 01(契约无效/没有 URL/部署失败/没有浏览器)或阶段 02 (流程缺失)输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="flowchad blocked: {reason}" status=blocked,然后停止整个链。
  • 不适用:阶段 01 检测到 PR 不受影响、仅涉及文档或由 Dependabot 创建,并在不部署的情况下输出 [pylot:$PYLOT_OUTCOME_NONCE] outcome="flowchad N/A: no affected interactive flow" status=success。

硬性规则

  1. 所有阶段都必须按顺序运行——每次只能运行一个 Task,等待其完成后再运行下一个。 整个流程中任何地方都不得并行分发任务。
  2. 在阶段 03 中逐个遍历流程——绝不能为每个流程各运行一个子 Agent。流程共享浏览器/会话/角色状态,并行运行会导致冲突。
  3. 阶段 05 必须内联运行——[pylot] outcome=... 标记必须由编排器生成,不能由子 Agent 生成。
  4. 绝不能将完整的编排器上下文传入子 Agent 的 Task 提示词——仅传入输入。
  5. 每个阶段都必须先写入 handoff.md,下一阶段才能读取。
  6. 不得跳过任何阶段——即使阶段的操作是“无需处理”,也必须执行(例如,后端为 none 的证据上传仍须写入 handoff)。
  7. 步骤出错属于发现项,不是崩溃——阶段 03 在步骤出错后仍须继续收集证据;只判定流程级别的通过/失败。
  8. **不使用 Quest,不使用外部仪表板。**报告 = 本地报告文件 + GitHub;另外,仅当任务的 dispatched_by_conv 已设置时,才向发起流程请求的线程发送一条 slack-post。由自动化分发的运行只发布到 GitHub,不发布到其他地方。
  9. **交互式 PASS 必须有浏览器证据。**静态/curl 诊断可以支持 FAILED 或 BLOCKED 结果,但绝不能支持 PASSED。
  10. **生产环境关键控制绝不可设为可选或跳过。**缺少 CAPTCHA/Navvi 能力时,结果必须为 BLOCKED,不能判定为通过,也不能在生产环境中跳过。
  11. **选择性创建 Preview。**绝不启用提供商自动创建 Preview;仅当不存在 staging 目标,且存在明确分发、与任务相关的 PR 时,最多按需创建一个 Preview。
  12. **Cron 使用 smoke.critical。**失败时创建或更新去重后的 issue,并附上浏览器证据;公开 skill 不负责调度器。
  13. **绝不能在操作员回合中启动浏览器。**操作员镜像没有浏览器库。Playwright 捕获任务交由 worker devbox 执行;Navvi 保持在操作员侧运行。缺少捕获主机时,结果必须为 BLOCKED,不能以静态探测判定通过。
  14. **每个上传的资源都必须包含 evidence_class: visual。**未分类的能力 URL 会在 30 天后返回 410,因此未分类的回执就是带有到期日的回执。发布已分类资源还必须设置 override_policy: true。
  15. **判定结果必须附带回执。**截图 URL 必须按步骤嵌入 PR 评论。没有图片的流程遍历判定只是陈述,不是证据。
  16. **上传失败时必须尽力交付,并且必须如实披露。**上传失败绝不会阻止运行,也绝不能被隐去——阶段 04 统计失败次数,阶段 05 输出失败信息。不作说明就无法区分“没有截图需求”和“截图上传失败”。

参考文件

  • CONTEXT.md — 架构概览
  • stages/NN-name/CONTEXT.md — 各阶段的输入、任务和输出约定
  • references/interactive-contract.md — 目标配置以及 CAPTCHA/i18n 示例
  • scripts/validate_contract.py — 确定性环境/流程约定验证器

评论

支持 Markdown