Setup a dogfood workflow
This guide describes how to set up a GitHub Action that uses Claude Code and the agent browser and the dogfood skill to perform a monthly exploration session of a web application to find issues, and produce a report with full reproduction evidence for every finding.
For a complete example of this workflow, refer to the Squide repository on GitHub.
Install the agent skills and the CLI
First, install directly in your project the agent-browser and dogfood skills. To do so, open a terminal at the root of the workspace and execute the following command:
pnpx skills add https://github.com/vercel-labs/agent-browser --skill agent-browser
pnpx skills add https://github.com/vercel-labs/agent-browser --skill dogfood
Then, install the agent-browser CLI. To do so, open a terminal at the root of the workspace and execute the following command:
pnpm add -D agent-browser
Create the prompt file
Then, create a .github/prompts/dogfood.md with the following content, and adjust the steps to match your project's capabilities:
# Dogfood
## Constraints
- Do NOT read AGENTS.md or agent-docs/
- Do NOT read the target app's source code
- Do NOT use the Skill tool — read skill files directly with the Read tool
## Task
Run an exploratory QA session on the endpoints sample app using the agent-browser dogfood skill, then report findings as a GitHub issue.
### Step 1 — Start servers
Start the endpoint servers in the background and wait for them to be ready:
```bash
pnpm serve-endpoints > /tmp/endpoints-serve.log 2>&1 &
```
Wait for both servers to be ready (single command to save a turn):
```bash
curl --retry 30 --retry-delay 5 --retry-connrefused --silent --output /dev/null http://localhost:8080 && curl --retry 30 --retry-delay 5 --retry-connrefused --silent --output /dev/null http://localhost:8081
```
If either curl command fails, run `cat /tmp/endpoints-serve.log` for diagnostics and stop.
### Step 2 — Run the dogfood session
Read and follow the skill instructions at `.agents/skills/dogfood/SKILL.md` with these parameters:
- **Target URL**: `http://localhost:8080`
- **Session name**: `endpoints`
- **Output directory**: `/tmp/dogfood-output`
- **Auth credentials**: username `temp`, password `temp`
### Step 3 — Known noise (IGNORE these)
Apply these ignore rules during the dogfood session:
- `/federated-tabs/failing` — intentionally throws to exercise error boundaries. The error boundary UI is expected.
- MSW (Mock Service Worker) console warnings — expected in this mock-data app.
- React warnings and deprecation notices — only flag actual JS errors/exceptions.
### Step 4 — Upload evidence and file a GitHub issue (or stop)
After the skill completes, read the generated report at `/tmp/dogfood-output/report.md`.
- **If the report contains zero issues**: end with "DOGFOOD PASSED — no issues found" and stop.
- **If the report contains issues**:
1. **Identify referenced evidence** — Using the Grep tool (parameter is `path`, not `file_path`), find all `screenshots/*.png` and `videos/*.webm` paths referenced in the report. Only these files should be uploaded (ignore exploration screenshots not cited in the report).
2. **Push evidence to the `dogfood-evidence` branch** — Evidence is stored in date-stamped directories (`YYYY-MM-DD/screenshots/`, `YYYY-MM-DD/videos/`) so each run's evidence persists and old issue links keep working.
- Configure git auth (use `--global` so it applies to any repo or clone):
```bash
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/workleap/wl-squide.git"
```
- Fetch or create the `dogfood-evidence` branch:
- If it exists: `git fetch origin dogfood-evidence && git checkout -B dogfood-evidence origin/dogfood-evidence`
- If not: `git checkout --orphan dogfood-evidence && git rm -rf . 2>/dev/null || true`
- **Prune old evidence** — Delete date directories older than 60 days, then commit the deletions if any were removed. **Do NOT use `git add -A`** — the working directory contains the full main-branch checkout (node_modules, packages, etc.) which must never be staged on this branch. Only add/remove the specific date directories:
```bash
CUTOFF=$(date -d '60 days ago' +%Y-%m-%d)
PRUNED=false
for d in ./[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]/; do
[ -d "$d" ] || continue
name=$(basename "$d")
if [[ "$name" < "$CUTOFF" ]]; then
git rm -rf "$d"
PRUNED=true
fi
done
if [ "$PRUNED" = true ]; then
git commit -m "Prune evidence older than 60 days"
fi
```
- **Add new evidence** — Create `YYYY-MM-DD/screenshots/` and `YYYY-MM-DD/videos/`, copy only the referenced files. Stage only the new date directory (`git add ./YYYY-MM-DD/`), commit, push. **Never use `git add -A` or `git add .`** on this branch.
- **Return to main branch** — `git checkout main`
3. **Rewrite evidence paths** in the report — Replace relative asset paths with absolute GitHub URLs so images render in the issue. First, capture today's date into a variable, then use it in the sed replacements:
```bash
TODAY=$(date +%Y-%m-%d)
sed -i "s|screenshots/|https://raw.githubusercontent.com/workleap/wl-squide/dogfood-evidence/${TODAY}/screenshots/|g" /tmp/dogfood-output/report.md
sed -i "s|videos/|https://raw.githubusercontent.com/workleap/wl-squide/dogfood-evidence/${TODAY}/videos/|g" /tmp/dogfood-output/report.md
```
4. **Create the issue**:
```bash
gh issue create \
--title "Dogfood: endpoints — $(date +%Y-%m-%d)" \
--body "$(cat /tmp/dogfood-output/report.md)"
```
Create the workflow file
Then, create a .github/workflows/dogfood.yml file for the GitHub action:
name: Dogfood
on:
schedule:
- cron: "0 9 15 * *"
workflow_dispatch:
permissions:
contents: write
issues: write
id-token: write
concurrency:
group: dogfood
cancel-in-progress: true
jobs:
dogfood:
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
run_install: false
- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: ">=24.0.0"
check-latest: true
cache: pnpm
cache-dependency-path: pnpm-lock.yaml
- name: Install dependencies
run: pnpm install --frozen-lockfile
# Expose workspace binaries (e.g. agent-browser) as bare commands.
- name: Add node_modules/.bin to PATH
run: echo "$PWD/node_modules/.bin" >> $GITHUB_PATH
- name: Install browser dependencies
run: agent-browser install --with-deps
- name: Warm up browser
run: |
agent-browser open about:blank
agent-browser close
- name: Run dogfood
uses: anthropics/claude-code-action@v1
with:
prompt: |
Read and follow the instructions in .github/prompts/dogfood.md
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
show_full_output: true
claude_args: >-
--max-turns 200
--allowedTools Read,Write,Edit,Glob,Grep,Bash(agent-browser:*),Bash(mkdir:*),Bash(cp:*),Bash(sleep:*),Bash(cat:*),Bash(gh:*),Bash(date:*),Bash(pnpm:*),Bash(curl:*),Bash(git:*),Bash(sed:*),Bash(rm:*),Bash(find:*),Bash(ls:*)
env:
# Required by gh CLI to create issues for dogfood findings.
GH_TOKEN: ${{ github.token }}
Try it 🚀
Push the GitHub Action and manually trigger the workflow. Once it completes, the workflow will open an issue with findings if it runs successfully.