agentleFS
thesawdawgthesawdawg/agent-skills/dogfood/SKILL.md

dogfood

Skill2 starsChanged 59 days agoMITView on GitHub

Run systematic, evidence-backed exploratory QA on a live web app — navigate its pages, exercise interactive elements, capture console errors and screenshots, then produce a categorized bug report. Use when the user wants to find bugs in a web application before shipping, wants a QA pass on a deployed app or PR preview, asks to "dogfood" a URL, or requests a persona-based UX friction assessment.

78 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use dep-refs, feature-boundary-planner and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • betacatslingSkill

    dep-refs

    Use when needs to inspect TypeScript export references in the z-code workspace, list exports from a file, verify whether an export is unused before deletion, investigate who imports a symbol during refactors, or combine pnpm knip unused-export results with pnpm dep:refs symbol-level reference tracing.

    Also in 5 projects that use this

  • betacatslingSkill

    feature-boundary-planner

    Map a ZCode behavior change to current UI surfaces, state owners, protocol commands, persistence, and validation. Use for impact analysis, product-boundary planning, or an implementation handoff grounded in the checked-out source.

    Also in 5 projects that use this

  • lir-navcooSkill

    yuanbao

    Yuanbao (元宝) groups: @mention users, query info/members.

    Also in 18 projects that use this

  • Cartograf666Skill

    architecture-governance

    Bootstrap, document, enforce, and review a project's architecture through layer responsibilities, dependency direction, architecture manifests, legacy baselines, Change Envelopes, cross-layer approval policy, and deterministic architecture checks. Use when starting a project, auditing an existing codebase, planning cross-layer work, preventing architecture erosion, reviewing structural changes, or deciding whether implementation may expand into another layer.

    Also in 5 projects that use this

  • john-data-chenSkill

    touchdesigner-mcp

    Control a running TouchDesigner instance via twozero MCP — create operators, set parameters, wire connections, execute Python, build real-time visuals. 36 native tools.

    Also in 7 projects that use this

  • math-incSkill

    minecraft-modpack-server

    Set up a modded Minecraft server from a CurseForge/Modrinth server pack zip. Covers NeoForge/Forge install, Java version, JVM tuning, firewall, LAN config, backups, and launch scripts.

    Also in 5 projects that use this

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 3 are distinctive, and 6 are very specific to this project.

  • 0

    Common

    Most of the 78 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run that, read the D=/absolute/path line it prints, and use that literal path as D in every block below.

    line 26
  2. Very specific:

    If a Chromium binary is already installed (some environments pre-provision one and set PLAYWRIGHT_BROWSERS_PATH), the driver auto-detects …

    line 40
  3. Very specific:

    Check package.json for a dev/start script and try its declared port first, or probe common local dev ports and use the first that responds:

    line 46
  4. Distinctive:

    If none respond, ask the user to pick (a) a local dev server on another port, (b) a staging/preview URL, or (c) a public URL — and paste it.

    line 52
  5. Distinctive:

    Create the output layout:

    line 62
  6. Very specific:

    If you never see READY, read launch.log — it holds the error (usually a missing Chromium or Node < 18).

    line 85
  7. Distinctive:

    Keep the whole object on one physical line.

    line 144
  8. Very specific:

    Read ./dogfood-output/issues.jsonl back (each line is one finding).

    line 152
  9. Very specific:

    Use annotate: when you need to click precisely or reason about positions — snapshot gives structure but not layout.

    line 175

“Common” is measured: kept by at least 6 in 10 of the 78 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Dogfood Skill

Systematic exploratory QA of a web application: navigate it, interact with it, capture evidence of anything broken, and produce a structured bug report with screenshots and console errors attached.

This skill drives a real headless Chromium instance through a small bundled Node script (scripts/browser-driver.mjs). One browser session stays alive across the whole pass, so pages, cookies, and console history persist. It requires filesystem access, a shell, Node/npm, and Chromium. Use a native browser tool instead when it supports the required navigation, evidence, console, and axe operations.

Setup: paths & shell state (READ THIS FIRST)

Two facts about how commands run, and how this skill deals with them:

  1. Each Bash command may run in a fresh shell. Shell variables and exports do not carry over from one Bash call to the next. So this skill does not rely on a variable set in an earlier step. Instead:
    • The output directory is a fixed relative path, ./dogfood-output — the working directory (your project root) is stable between calls, so this same relative path always resolves to the same place. Every command below uses it literally.
    • The one value that must be absolute is this skill's own directory (where browser-driver.mjs lives). Each Bash block that needs it sets D= on its first line. You must fill in D with the real absolute path (see step 2). Do not leave the placeholder.
  2. Find this skill's directory once, and reuse that exact string as D. You loaded this SKILL.md from a path — its containing directory is the value. If you need to find it programmatically, check available installed skill locations (this is unambiguous and fast):
    for d in "$HOME/.pi/agent/skills/dogfood" "$HOME/.agents/skills/dogfood" ".pi/skills/dogfood" ".agents/skills/dogfood" ./dogfood; do
      [ -f "$d/scripts/browser-driver.mjs" ] && printf 'D=%s\n' "$(cd "$d" && pwd)" && break
    done
    Run that, read the D=/absolute/path line it prints, and use that literal path as D in every block below.

Prerequisites

One-time setup (installs the Node Playwright package and a Chromium binary). Replace D=... with your real path:

D="/absolute/path/to/dogfood"
bash "$D/scripts/preflight.sh"
bash "$D/scripts/setup.sh" --install-browser
# Record the printed absolute browser-driver.mjs path as DRIVER in each command.

Notes:

  • If a Chromium binary is already installed (some environments pre-provision one and set PLAYWRIGHT_BROWSERS_PATH), the driver auto-detects it and npx playwright install is a harmless no-op.
  • The driver needs Node 18+. Check node --version if launch fails.

Inputs

  1. Target URL — the entry point. If the user didn't give one, don't just ask open-endedly — offer concrete options:
    • Check package.json for a dev/start script and try its declared port first, or probe common local dev ports and use the first that responds:
      for u in http://localhost:3000 http://localhost:5173 http://localhost:8080 http://localhost:4200 http://localhost:5000 http://127.0.0.1:8000; do
        curl -sf -o /dev/null "$u" && echo "responds: $u" && break
      done
    • If none respond, ask the user to pick (a) a local dev server on another port, (b) a staging/preview URL, or (c) a public URL — and paste it.
  2. Scope — what to focus on. If not given, default to full site from /, and say so explicitly.
  3. Output directory — fixed at ./dogfood-output for this skill (see Setup). No variable to set.

Workflow

Five phases. If your harness has a task/todo list, track each phase on it.

Phase 1: Plan

  1. Create the output layout:
    mkdir -p ./dogfood-output/screenshots ./dogfood-output/.browser
    ( set -o noclobber; : > ./dogfood-output/issues.jsonl ) || exit 1
    # If it exists, explicitly resume or choose a new output directory.
    Layout: ./dogfood-output/screenshots/ (evidence), issues.jsonl (findings, append as you go), report.md (written in Phase 5).
  2. Confirm the testing scope (from Inputs).
  3. Sketch a rough sitemap: landing/home, nav links (header/footer/sidebar), key flows (sign up, login, search, checkout), forms, edge cases (empty states, error pages, 404s).
  4. Start the browser in the background and leave it running until Phase 5. Launch is a long-lived process (it blocks until close), so start it detached and then poll its log for READY:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    nohup node "$DRIVER" launch --state-dir ./dogfood-output/.browser \
      > ./dogfood-output/.browser/launch.log 2>&1 &
    Then confirm it came up (separate command; safe to repeat):
    for i in $(seq 1 20); do
      grep -q READY ./dogfood-output/.browser/launch.log 2>/dev/null && { echo "browser up"; break; }
      sleep 0.5
    done
    cat ./dogfood-output/.browser/launch.log
    If you never see READY, read launch.log — it holds the error (usually a missing Chromium or Node < 18).

Phase 2: Explore

For each page/feature, in order. Every block below re-sets D because variables don't carry between calls — fill in your real path each time.

  1. Navigate:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" navigate --state-dir ./dogfood-output/.browser --url "https://example.com/page"
  2. Snapshot the accessibility tree (text structure — labels, roles, headings):
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" snapshot --state-dir ./dogfood-output/.browser
  3. Check the console and clear it for the next step — do this after every navigation and interaction; silent JS errors are high-value findings:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" console --state-dir ./dogfood-output/.browser --clear true
  4. Annotate interactive elements and inspect:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" annotate --state-dir ./dogfood-output/.browser --path ./dogfood-output/screenshots/page-1.png
    This overlays numbered [N] badges, saves the screenshot, and writes refs.json mapping each number to a CSS selector.
    • If your harness can view images: open the PNG and assess layout, visual bugs, accessibility.
    • If it cannot: rely on the snapshot from step 2 (text). Note in the report that visual-only issues weren't assessed.
    • ⚠️ --ref N numbers are only valid until the next annotate or navigate. After you re-annotate or change pages, the numbering is regenerated — don't reuse an old --ref. When acting across several steps, prefer --selector "<css>" (stable) over --ref.
  5. Test interactive elements (refs are from the most recent annotate):
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" click  --state-dir ./dogfood-output/.browser --ref 3
    # Re-annotate after each action before using another reference.
    node "$DRIVER" type   --state-dir ./dogfood-output/.browser --selector "input[name=email]" --text "test input"
    node "$DRIVER" press  --state-dir ./dogfood-output/.browser --key Tab
    node "$DRIVER" press  --state-dir ./dogfood-output/.browser --key Enter
    node "$DRIVER" scroll --state-dir ./dogfood-output/.browser --direction down
    node "$DRIVER" back   --state-dir ./dogfood-output/.browser
    You can pass --selector "<css>" instead of --ref. Cover keyboard navigation, form validation with invalid inputs, and empty submissions.
  6. After each interaction, re-check: run console again; re-run annotate/snapshot and compare; ask "did the expected thing happen?" If not, it's a finding.

Phase 3: Collect Evidence

For every issue found:

  1. Capture a screenshot:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" screenshot --state-dir ./dogfood-output/.browser --path ./dogfood-output/screenshots/issue-1.png
  2. Append one line to issues.jsonl — one complete JSON object per line (JSONL). Appending a line can't corrupt earlier findings, unlike editing one big JSON array:
    cat >> ./dogfood-output/issues.jsonl <<'EOF'
    {"url":"https://example.com/page","steps":["click Login","submit empty"],"expected":"validation error","actual":"500 page","console":"TypeError: ...","screenshot":"screenshots/issue-1.png","severity":"High","category":"Functional"}
    EOF
    Keep the whole object on one physical line. After writing, sanity-check every line is valid JSON:
    while IFS= read -r line; do printf '%s' "$line" | python3 -c "import sys,json; json.loads(sys.stdin.read())" || echo "BAD LINE: $line"; done < ./dogfood-output/issues.jsonl
  3. Classify severity (Critical / High / Medium / Low) and category (Functional / Visual / Accessibility / Console / UX / Content) using the taxonomy — read <D>/references/issue-taxonomy.md with the Read tool.

Phase 4: Categorize

  1. Read ./dogfood-output/issues.jsonl back (each line is one finding).
  2. De-duplicate — merge lines that are the same bug in different places.
  3. Assign each a final severity and category.
  4. Sort by severity: Critical, then High, Medium, Low.
  5. Count issues by severity and by category (for the summary table).

Phase 5: Report

  1. Write ./dogfood-output/report.md using the template — read <D>/templates/dogfood-report-template.md first. Fill in: executive summary, per-issue sections (link screenshots as relative markdown images, e.g. ![](screenshots/issue-1.png)), the summary table, and testing notes (what was tested, what wasn't, blockers — including "visual issues not assessed" if the harness couldn't view images).
  2. Shut down the browser:
    DRIVER="/absolute/cache/path/browser-driver.mjs"
    node "$DRIVER" close --state-dir ./dogfood-output/.browser
  3. Tell the user the exact paths (./dogfood-output/report.md and the Critical/High screenshots). If your harness has a file-delivery capability, use it to surface them; otherwise the paths are enough.

The full driver command table lives in references/browser-commands.md; every command takes --state-dir ./dogfood-output/.browser.

Tips

  • Check the console after navigating and after significant interactions. Silent JS errors are high value.
  • Use annotate when you need to click precisely or reason about positions — snapshot gives structure but not layout.
  • Test valid and invalid inputs — form-validation bugs are common.
  • Scroll long pages — below-the-fold content may render wrong.
  • Test navigation flows end-to-end.
  • Edge cases: empty states, very long text, special characters, rapid clicking.
  • Always run close when done — it's the only thing that stops the background browser process.

For requested persona/UX exploration, use persona UX within the same run and evidence stream.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.