Skip to content
Agentmart
Submit a tool

flow-verify

Run pre-commit verification checks, fix failures, and re-run until clean.

Skill by gavingolden

IndexedMIT★ 1
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/gavingolden-flow-verify

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Run pre-commit verification checks, fix failures, and re-run until clean. Use when user says "verify", "run checks", "check my changes", "pre-commit", or before committing changes.

Use cases: data

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/flow-verify

What's inside

Skill name
flow-verify
Description
Run pre-commit verification checks, fix failures, and re-run until clean. Use when user says "verify", "run checks", "check my changes", "pre-commit", or before committing changes.
License
MIT
Instructions
309 lines in SKILL.md · view on GitHub

Agent Skills spec issues

  • files: referenced but missing: references/exemption-contracts.md

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Goal

Run all relevant pre-commit checks, fix any failures, and re-run until every check passes.

# When to Use

- Before committing changes
- User asks to "verify", "run checks", "check my changes"
- After completing a refactor, feature, or bug fix
- As a sub-step of other skills (e.g., pr-review Step 6)

# When NOT to Use

- When the user wants to run a single specific check (e.g., just `npm run test`)
- When the user is only running `npm run format` without checks

# Context

- `flow-pre-commit` (installed globally by `flow install` and on PATH) auto-detects scope,
  runs the checks (it never formats), and reports pass/fail. The `--json` flag emits a single bounded
  JSON object — head/tail-capped failure excerpts plus a `firstErrorText` extraction —
  so this skill returns a compact summary to its caller instead of replaying 50–200 KB
  of raw test stack traces.
- If the binary isn't on PATH, fall back to invoking the relevant `npm run` scripts
  directly (e.g., `npm run check`, `npm run lint`, `npm run test`).

# Instructions

## 1. Run the Pre-Commit Checks

```bash
flow-pre-commit --json --reuse-verified-tree $ARGUMENTS
```

When the invocation asks for a fresh run (a `fresh` or `--fresh` token in `$ARGUMENTS`),
drop that token and omit `--reuse-verified-tree` so every check executes; a direct
terminal run of `flow-pre-commit --json` is the equivalent.

If `$ARGUMENTS` is empty, the helper auto-detects scope from `git diff HEAD` (a clean
tree falls back to the diff against the merge-base). The `--json`
flag is required: it bounds each failed check's output to ~200 lines (head 100 + tail 100)
and extracts a `firstErrorText` field so the model summarising results doesn't have to scrape
a wall of raw stderr. If `flow-pre-commit` isn't on PATH, fall back to running the equivalent
npm scripts in sequence and stopping on the first failure — in that fallback path you don't
have the JSON structure, so summarise manually.

For direct human use at a terminal, the human-readable mode without `--json` is still
available (`flow-pre-commit` with no flag) and that path is unchanged.

### Optional UI-smoke pass

When the diff touches a meaningful UI surface AND the `chrome-devtools` MCP is available in this session, run the browser-driven UI-smoke pass alongside `flow-pre-commit` — a hand-authored `.flow/ui-validation.json` manifest is no longer a precondition; when none exists the helper returns a mechanical `action: "bootstrap"` verdict you branch on (infer `launch`/`baseUrl`/`routes`/`loginUrl` + credential NAMES → empirically verify → write the verified NAMES/config back into the manifest, names and non-secret config only — never a secret value, and commit it). Probe the MCP (`ToolSearch query="select:mcp__chrome-devtools__navigate_page"`) → on missing schema fall back to `flow-ui-validate --mcp-absent` (a quiet `ran:false` skip that never blocks the run) → otherwise `flow-ui-validate --changed-files <diff>` and save the resulting envelope to `.flow-tmp/ui-driver-envelope.json`. On an `mcp-not-available` / `browser-profile-busy` skip, relay the loud skip and stop — never spawn.

<!-- flow-credential-denial-rule -->

**Credential denial means stop.** When a permission check, the auto-mode
classifier, or a deny rule refuses any credential-related action —
reading a `.env`-family file, printing a credential variable, running
`flow-ui-login test-account`, or the `fill_form` that types the
test-account values — STOP the browser check. Never retry through another
tool (Read, grep, cat, a script, `evaluate_script`, or a different
fill/type tool): record `skipped_reason: "credentials-unavailable"` and let
the caller surface `smoketest-needs-creds`, naming only the variable NAMES.
Values filled and submitted but the page still on `loginUrl` is not a
refusal: record `login-failed`.

On a `bootstrap` or `ran:true` (ready) envelope, this is the eighth Task-tool exemption's spawn site (`/flow-verify` Independent UI-Driver Subagent — `skills/pipeline/flow-pipeline/SKILL.md` "Hard rules", full contract in `references/exemption-contracts.md`).

**Load the Task tool before spawning.** In Claude Code sessions where neither `Task` nor its alias `Agent` is surfaced top-level by the harness (both are aliases of the same one-shot subagent-spawn primitive: identical `subagent_type` / `prompt` / `description` schema), the spawn will silently fall through to in-line execution unless the schema is loaded first. Before the Task call below, run `ToolSearch query="select:Task"` and confirm the response contains either a `<function>{"name": "Task", ...}</function>` or a `<function>{"name": "Agent", ...}</function>` line. If it does not, **do not fall back to in-line execution** — escalate `NEEDS HUMAN: task-tool-unavailable: ui-driver`, write the existing skip note, and exit.

**The `UI_SMOKE_DRIVER: inline` marker.** When the invocation carries the literal marker `UI_SMOKE_DRIVER: inline` (the `/flow-fix-applier-instructions` re-run path, which has no Task tool of its own), drive the procedure yourself in this session's own context per `../flow-ui-driver-instructions/SKILL.md` — `meta.env`-injected launch on dedicated ports through `flow-spawn`, same as the spawned agent below — and skip the Task call entirely. Absent the marker, spawn as follows.

**Model.** Resolve `config.models.uiDriver` via `jq -r '.models.uiDriver // empty' ~/.flow/config.json 2>/dev/null` and fall back to the literal `sonnet` when empty — config-only, no CLI flag, no `state.json` read at all (unlike every other spawn site's precedence chain).

**Effort.** Resolve `UI_DRIVER_EFFORT` as below (built-in `medium` capped at the session's effort; `config.efforts.uiDriver` overrides — `../flow-pipeline/references/model-routing.md`) and pass the non-empty result as the Task call's per-spawn `effort:` (empty ⇒ omit).

```bash
UI_DRIVER_EFFORT=$(command -v flow-spawn-effort >/dev/null 2>&1 && flow-spawn-effort ui-driver)
# Non-empty ⇒ pass effort: "$UI_DRIVER_EFFORT" as the Task call's per-spawn effort; empty ⇒ omit.
```

**Agent resolution (two-tier guard).** `[ -f ~/.flow/claude-home/.claude/skills/flow-module-core/agents/flow-ui-driver.md ]`: when present, `subagent_type: flow-module-core:flow-ui-driver` (a bare `flow-ui-driver` name fails Task-tool resolution outright on a plugin-root install); else `general-purpose` with the loud `NOTICE — agent-fallback:` line.

**Exactly one Task call per outer attempt.** Before the first spawn (never under `UI_SMOKE_DRIVER: inline`), run steps 0–1 of [../flow-pipeline/references/ui-critique-loop.md](../flow-pipeline/references/ui-critique-loop.md) — the re-entry check and the pre-drive `flow-ui-critique gate` — and on `run:true` add the line `SECTIONS: on` to every spawn prompt below; without it the drive takes no section shots and the critique loop cannot run. Spawn `flow-ui-driver` (preloading `../flow-ui-driver-instructions/SKILL.md`) passing `ENVELOPE_PATH=$WORKTREE/.flow-tmp/ui-driver-envelope.json`, `MANIFEST_PATH=$WORKTREE/.flow/ui-validation.json`, `WORKTREE` (absolute), `SLUG` (resolved below), `ARTIFACT_PATH=$WORKTREE/.flow-tmp/ui-driver-result.json`, `CAPTURES_PATH=$WORKTREE/.flow-tmp/ui-captures.json`, and `SKILL_DIR` (absolute). Every path is absolute — the driver's own instructions declare `ARTIFACT_PATH`/`CAPTURES_PATH`/`ui_screenshots[]` absolute, and the `Write` tool rejects a relative path outright, so a worktree-relative value here degrades to `driver-no-artifact` on every attempt. Resolve `SLUG` from `$FLOW_SLUG` when set, else fall back to the worktree's basename (`$(basename "$WORKTREE")`) so an interactive run outside a launcher session still keys the isolated page deterministically. Never re-spawn within the same outer `/flow-verify` attempt — the next outer attempt (of the 3-attempt cap) re-spawns naturally. **Post-pass repair allowance:** after the outer loop ends clean, the smell-repair round or the UI critique round — never both — may spawn ONE extra `flow-ui-driver` re-drive and ONE `/flow-coder` round; nothing else re-spawns.

**Post-return check and degrade (never escalate) — except a credential denial.** After the Task call returns, `test -s "$WORKTREE/.flow-tmp/ui-driver-result.json"` and `flow-ui-driver-schema --validate` it. On success, read it once and reuse the parsed object — never re-derive — and record the attempt's page-check defects with `flow-ui-critique persistent --record "$WORKTREE/.flow-tmp/ui-driver-result.json" --worktree "$WORKTREE"` (it feeds the supervisor's step 6 exhaustion branch in [step-06-verify.md](../flow-pipeline/references/phases/step-06-verify.md)). On a missing/unwritable/invalid artifact, treat it as `{ran: false, ok: false, skipped_reason: "driver-no-artifact"}` and emit the existing skip note below; do **not** escalate `NEEDS HUMAN`, do **not** re-spawn, and do **not** fail verify. **Named carve-out:** a `credentials-unavailable` `skipped_reason` is the one exception to "never escalate" — when this Task call ran under the `/flow-pipeline` supervisor (no `UI_SMOKE_DRIVER: inline` marker), run `flow-browser-teardown --reap --record` as its own standalone call (never `&&`-joined, never `|| true`) and then escalate `NEEDS HUMAN: smoketest-needs-creds`, naming the `credentialEnvVars` NAMES from the manifest and the `flow feature resume <slug>` command; when it ran on the `UI_SMOKE_DRIVER: inline` fix-applier path, this subagent has no escalation path of its own — record `credentials-unavailable` in the fix-applier artifact summary instead (per `../flow-fix-applier-instructions/SKILL.md` Step 8) — the fix-applier makes no further browser, MCP or teardown calls after the denial, and the supervisor's next escalation/terminal `flow-browser-teardown --reap --record` owns teardown — and leave the affected items unchecked so the pr-review wrapper surfaces the pause.

A `ran:true` result with `ok:false` (a console error, a failed request, or a missing `expectSelectors` element) is a verify failure routed through the same fix loop as any `flow-pre-commit` check (see Step 3), consuming the artifact's `fix_context[]` for what to fix — never re-driving the browser yourself; headless / MCP-absent runs stay green. **Adaptive noise filter:** when an `ok:false` flags a benign console error or failed request unrelated to the diff (a favicon 404, a third-party beacon/analytics request, browser-extension noise), do **not** fix-loop on it — add the substring to the manifest's `ignoreRequestPatterns` / `ignoreConsolePatterns` in `.flow/ui-validation.json` and commit that manifest change (it lands in the reviewable PR diff), then re-run. **Self-completing + self-maintaining manifest (CRITICAL):** the agent completes and maintains EVERYTHING the smoketest needs, not just the launch — when it adapts the launch on the fly, fixes a 404'd route or failed launch field, or records a verified `loginUrl` + credential NAMES, it persists the launch adaptation back into `.flow/ui-validation.json` (env/launch/baseUrl/routes/loginUrl/credentialEnvVars) and commits it into the reviewable PR diff so the next run starts deterministic; runtime credential VALUES are resolved by `flow-ui-login` and are never persisted — the agent never reads them itself. The committed manifest and every artifact reference credential env-var NAMES only — logging in through `flow-ui-login` (see the “## Login step (auth-gated apps)” section in [ui-validation-evidence.md](../flow-pr-review/references/ui-validation-evidence.md)) is sanctioned only for zero-risk seed/test accounts, not a license to hand-type arbitrary or production passwords. When run directly (interactive `/flow-verify`), a genuinely-unresolvable creds gap may prompt via `AskUserQuestion`; the autonomous pipeline path instead escalates `NEEDS HUMAN: smoketest-needs-creds`. See [../flow-pipeline/references/ui-smoke-pass.md](../flow-pipeline/references/ui-smoke-pass.md) for the full probe → bootstrap → launch → drive → assemble → fix-loop body, and `skills/pipeline/flow-pipeline/SKILL.md` Step 6 for the supervisor-side contract.

**Shared-profile lock (parallel pipelines).** chrome-devtools-mcp backs every browser with a single default on-disk Chrome profile (`~/.cache/chrome-devtools-mcp/chrome-profile`), so two flow pipelines that both reach this pass under one un-isolated MCP registration contend for it — the second to launch errors with `The browser is already running for ~/.cache/chrome-devtools-mcp/chrome-profile. Use --isolated to run multiple browser instances`. Recovery: register the chrome-devtools MCP with `--isolated` in `~/.claude.json` (each server process gets its own auto-cleaned throwaway profile), or wait for/close the other pipeline browser. The per-call `isolatedContext` above is same-server defense-in-depth — it isolates pages within one MCP server but does NOT resolve this cross-process on-disk-profile lock; `--isolated` is the remedy for the cross-process on-disk PROFILE LOCK specifically, but it does not prevent a leaked browser process — its temp profile is cleaned only after the browser closes, and the browser itself is reaped separately by `flow-browser-teardown` at the pipeline's terminal state. On detecting the lock, drive `flow-ui-validate --browser-busy`, which emits a loud-but-clean `ran:false` / `skipped_reason: browser-profile-busy` skip — a busy browser degrades exactly like an absent one (never a hard failure) and verify proceeds green on the rest of the diff.

### Layer-3 proactive config-authoring branch

When `flow-pre-commit --json` returns `reason: "unmatched-files"`, the
orphaned files may belong to a recognizable-but-uncovered layout. Before
treating it as a verify failure, call the pure
`draftConfigEntryForOrphans` helper (exported from
`bin/lib/monorepo-scopes.ts`) over the report's `unmatchedFiles`:

- **If it returns an entry** (a recognizable layout whose owning
  `package.json` declares verify-class scripts), write/merge it into the
  repo-relative `.flow/pre-commit.json` (top-level array of
  `{ name, prefixes, checks }` entries — append, do not clobber existing
  entries), commit it to the feature branch so it lands in the reviewable
  PR diff, and **re-run verify** — this does NOT count as a new failed
  check.
- **If it returns `null`** (a genuine orphan: no `package.json` owner, no
  stack marker, no config), fall through to the loud `unmatched-files`
  failure at Step 3.

The helper is LLM-free and pure (no `claude -p` / Task sub-call). This is
the **third** of `flow-pre-commit`'s command-resolution layers;
zero-config auto-detect (layers 1–2) writes nothing — the Layer-3 commit
above is the only config write this skill makes.

## 2. Interpret Results

The helper exits 0 if all checks pass, 1 if any fail. Stdout is a single JSON object with
this shape (failed checks only — passing checks omit the `failure` field):

From gavingolden/flow, MIT.

More from gavingolden/flow

Signals

Stars
1
Forks
0
Open issues
87
Last commit (this folder)
Oct 19, 2026 (9 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from gavingolden

Cite this page

flow-verify skill. Agent Mart. https://agentmart.dev/skills/gavingolden-flow-verify (last updated 2026-10-24)