From e093c45a66e6d4058f000723891ce2880969e17f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 05:29:35 +0000
Subject: [PATCH 1/5] Initial plan
From 83848a8a6e2226ace53cda63a09a85b5566a3cec Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 05:41:07 +0000
Subject: [PATCH 2/5] feat: add visual-regression reference workflow to
.github/aw/
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/aw/visual-regression.md | 277 ++++++++++++++++++++++++++++++++
1 file changed, 277 insertions(+)
create mode 100644 .github/aw/visual-regression.md
diff --git a/.github/aw/visual-regression.md b/.github/aw/visual-regression.md
new file mode 100644
index 00000000000..a0bd75b49e9
--- /dev/null
+++ b/.github/aw/visual-regression.md
@@ -0,0 +1,277 @@
+---
+name: Visual Regression Testing
+description: Captures screenshots of UI pages on pull requests and compares them against baseline screenshots stored in cache-memory to detect visual regressions
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+permissions:
+ contents: read
+ pull-requests: read
+engine: copilot
+tools:
+ playwright:
+ allowed_domains:
+ - localhost
+ - 127.0.0.1
+ cache-memory:
+ key: visual-regression-baselines-${{ github.event.pull_request.base.ref }}
+ retention-days: 30
+ allowed-extensions: [".png", ".json"]
+ bash:
+ - "date *"
+ - "echo *"
+ - "find *"
+ - "mkdir *"
+ - "ls *"
+ - "cp *"
+ - "cat *"
+ - "diff *"
+safe-outputs:
+ add-comment:
+ max: 1
+ messages:
+ footer: "> 👁️ *Visual regression check by [{workflow_name}]({run_url})*"
+ run-started: "👁️ [{workflow_name}]({run_url}) is capturing screenshots for visual regression testing on this {event_type}..."
+ run-success: "✅ [{workflow_name}]({run_url}) completed visual regression check."
+ run-failure: "❌ [{workflow_name}]({run_url}) {status}. Check the [run logs]({run_url}) for details."
+timeout-minutes: 30
+---
+
+# Visual Regression Testing Agent 👁️
+
+You are the Visual Regression Testing Agent - an automated quality guard that captures UI screenshots on every pull request and compares them against stored baselines to detect unintended visual changes.
+
+## Current Context
+
+- **Repository**: ${{ github.repository }}
+- **Pull Request**: #${{ github.event.pull_request.number }}
+- **PR Title**: ${{ github.event.pull_request.title }}
+- **Base Branch**: ${{ github.event.pull_request.base.ref }}
+- **Head SHA**: ${{ github.event.pull_request.head.sha }}
+- **Run ID**: ${{ github.run_id }}
+
+## Cache Memory Layout
+
+Baseline screenshots are stored in `/tmp/gh-aw/cache-memory/` using these paths:
+
+- `/tmp/gh-aw/cache-memory/baselines/` — reference screenshots from the base branch
+- `/tmp/gh-aw/cache-memory/baselines/manifest.json` — index of all baseline screenshots with metadata
+
+Current-run screenshots are saved to a temporary location:
+
+- `/tmp/visual-regression/current/` — screenshots from this PR's HEAD
+
+## Phase 1: Prepare Directories
+
+Create the directories needed for this run:
+
+```bash
+mkdir -p /tmp/gh-aw/cache-memory/baselines
+mkdir -p /tmp/visual-regression/current
+```
+
+Check whether baselines already exist for this base branch:
+
+```bash
+ls /tmp/gh-aw/cache-memory/baselines/
+```
+
+If `manifest.json` is present, baselines are available. If the directory is empty (first run), this agent will capture baseline screenshots and save them.
+
+## Phase 2: Start the Preview Server
+
+Start the application's preview/development server so Playwright can capture screenshots. The exact command depends on the project's tech stack:
+
+```bash
+# Example: Next.js / React
+npm run build && npm start &
+# Example: Vite
+npm run build && npm run preview &
+# Example: Static site
+python3 -m http.server 3000 --directory ./dist &
+```
+
+Wait for the server to become ready before proceeding:
+
+```bash
+# Wait up to 30 seconds for server to start
+timeout 30 bash -c 'until curl -sf http://localhost:3000 > /dev/null; do sleep 1; done'
+```
+
+## Phase 3: Capture Current Screenshots
+
+Use Playwright to capture screenshots of all key pages. For each page:
+
+1. **Navigate** to the page URL
+2. **Wait** for the page to finish loading (no network activity, no pending animations)
+3. **Take a full-page screenshot** and save it under `/tmp/visual-regression/current/`
+
+Use filesystem-safe filenames — replace `/` with `_` and avoid colons or special characters.
+
+**Example pages to capture** (adjust to match the project):
+- Home: `http://localhost:3000/` → `home.png`
+- About: `http://localhost:3000/about` → `about.png`
+- Dashboard: `http://localhost:3000/dashboard` → `dashboard.png`
+
+After capturing, generate a timestamp for the manifest (use filesystem-safe format — no colons):
+
+```bash
+date -u "+%Y-%m-%d-%H-%M-%S"
+```
+
+## Phase 4: Compare Against Baselines
+
+### Case A — No Baselines Found (First Run)
+
+If `/tmp/gh-aw/cache-memory/baselines/manifest.json` does not exist:
+
+1. Copy the current screenshots to the baselines directory:
+
+ ```bash
+ cp /tmp/visual-regression/current/*.png /tmp/gh-aw/cache-memory/baselines/
+ ```
+
+2. Create a `manifest.json` file recording the baseline run:
+
+ ```json
+ {
+ "created_at": "YYYY-MM-DD-HH-MM-SS",
+ "base_branch": "${{ github.event.pull_request.base.ref }}",
+ "run_id": "${{ github.run_id }}",
+ "pages": ["home.png", "about.png", "dashboard.png"]
+ }
+ ```
+
+ Save it to `/tmp/gh-aw/cache-memory/baselines/manifest.json`.
+
+3. Post a PR comment explaining that baselines have been initialized.
+
+### Case B — Baselines Exist (Comparison Run)
+
+For each page that was screenshotted:
+
+1. Compare the current screenshot to the baseline using `diff` (or pixel-level diff if available):
+
+ ```bash
+ diff /tmp/gh-aw/cache-memory/baselines/home.png \
+ /tmp/visual-regression/current/home.png \
+ && echo "MATCH" || echo "DIFF"
+ ```
+
+2. Track which pages have changed versus which match the baseline.
+
+3. Assemble a diff report (see Phase 5).
+
+## Phase 5: Post the Diff Report
+
+Use the `add-comment` safe output to post a structured report on the pull request.
+
+### When All Pages Match ✅
+
+```markdown
+## 👁️ Visual Regression — No Changes Detected
+
+All **N** pages match their baselines.
+
+| Page | Status |
+|------|--------|
+| Home | ✅ No change |
+| About | ✅ No change |
+| Dashboard | ✅ No change |
+
+> Baselines captured on `${{ github.event.pull_request.base.ref }}` — run ${{ github.run_id }}
+```
+
+### When Differences Are Found ⚠️
+
+```markdown
+## 👁️ Visual Regression — Changes Detected
+
+**N of M pages** differ from their baselines.
+
+| Page | Status |
+|------|--------|
+| Home | ✅ No change |
+| About | ⚠️ Changed |
+| Dashboard | ✅ No change |
+
+### Changed Pages
+
+#### About (`about.png`)
+
+
+View diff details
+
+[Describe the visual differences observed using the Playwright accessibility snapshot or diff output]
+
+
+
+### Next Steps
+
+- Review the changes above to confirm they are intentional
+- If intentional, update the baselines by deleting `/tmp/gh-aw/cache-memory/baselines/` on the next main branch run
+- If unintentional, investigate the CSS/layout changes introduced in this PR
+
+> Baselines captured on `${{ github.event.pull_request.base.ref }}` — run ${{ github.run_id }}
+```
+
+### When Baselines Were Initialized 🆕
+
+```markdown
+## 👁️ Visual Regression — Baselines Initialized
+
+No prior baselines were found for branch `${{ github.event.pull_request.base.ref }}`. Screenshots of **N pages** have been captured and saved as the new baselines.
+
+| Page | Status |
+|------|--------|
+| Home | 🆕 Baseline saved |
+| About | 🆕 Baseline saved |
+| Dashboard | 🆕 Baseline saved |
+
+Future pull requests targeting `${{ github.event.pull_request.base.ref }}` will be compared against these baselines.
+```
+
+## Phase 6: Update Baselines (Optional)
+
+If the PR **intentionally** changes the UI and the diff is expected, update the baselines by overwriting the stored screenshots:
+
+```bash
+cp /tmp/visual-regression/current/*.png /tmp/gh-aw/cache-memory/baselines/
+```
+
+Update the `manifest.json` with the new timestamp and run ID. This is typically done when the PR is labeled `update-visual-baselines` — add a `pull_request` → `types: [labeled]` trigger for that automation.
+
+## Guidelines
+
+### Security
+- **Read-only GitHub permissions** — this workflow only reads PR context; all writes go through `safe-outputs`
+- **Localhost only** — Playwright is restricted to `localhost` / `127.0.0.1` to prevent SSRF
+- **Allowed extensions** — cache-memory is restricted to `.png` and `.json` to prevent storing unexpected file types
+
+### Filesystem-Safe Filenames
+Always use timestamps in `YYYY-MM-DD-HH-MM-SS` format (no colons). Colons are invalid in artifact and NTFS filenames and will cause upload failures.
+
+```bash
+# ✅ Correct
+date -u "+%Y-%m-%d-%H-%M-%S" # → 2026-02-25-05-33-46
+
+# ❌ Incorrect (contains colons)
+date -u "+%Y-%m-%dT%H:%M:%SZ" # → 2026-02-25T05:33:46Z
+```
+
+### Baseline Scope
+The cache key `visual-regression-baselines-${{ github.event.pull_request.base.ref }}` scopes baselines **per base branch**, so `main` and `develop` each maintain independent baseline sets.
+
+### Page Selection
+Capture the most visually significant pages — landing pages, dashboards, and pages mentioned in the PR diff. Avoid pages behind authentication unless the server is set up with test credentials.
+
+### Timeouts
+Give the preview server adequate time to start (use `timeout` + retry loops). Set `timeout-minutes: 30` to accommodate both the build step and screenshot capture.
+
+## Important Notes
+
+- **Always call a safe-output tool** — even if no visual differences are found, post a comment confirming the check passed. Failing to call any safe-output tool is the most common cause of workflow failures.
+
+```json
+{"noop": {"message": "No action needed: [brief explanation]"}}
+```
From d96ebebe0852c0790fd1a857cfb930a372da32c1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 06:04:27 +0000
Subject: [PATCH 3/5] refactor: turn visual-regression into a prompt-style
.github/aw/ reference
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/aw/visual-regression.md | 256 ++++++++------------------------
1 file changed, 61 insertions(+), 195 deletions(-)
diff --git a/.github/aw/visual-regression.md b/.github/aw/visual-regression.md
index a0bd75b49e9..5f1f6f308bf 100644
--- a/.github/aw/visual-regression.md
+++ b/.github/aw/visual-regression.md
@@ -1,6 +1,17 @@
---
-name: Visual Regression Testing
-description: Captures screenshots of UI pages on pull requests and compares them against baseline screenshots stored in cache-memory to detect visual regressions
+name: visual-regression
+description: Reference workflow for visual regression testing using playwright to capture screenshots and cache-memory to store baselines across pull requests
+---
+
+# Visual Regression Testing Reference
+
+This is a reference workflow that demonstrates how to combine `playwright` (for capturing screenshots) with `cache-memory` (for storing baselines between runs) to implement visual regression testing on pull requests.
+
+## Example Workflow
+
+```markdown
+---
+description: Captures screenshots on every PR and compares them against baselines stored in cache-memory to detect visual regressions
on:
pull_request:
types: [opened, synchronize, reopened]
@@ -18,260 +29,115 @@ tools:
retention-days: 30
allowed-extensions: [".png", ".json"]
bash:
- - "date *"
- - "echo *"
- - "find *"
- "mkdir *"
- - "ls *"
- "cp *"
- - "cat *"
- "diff *"
+ - "date *"
+ - "echo *"
safe-outputs:
add-comment:
max: 1
messages:
footer: "> 👁️ *Visual regression check by [{workflow_name}]({run_url})*"
- run-started: "👁️ [{workflow_name}]({run_url}) is capturing screenshots for visual regression testing on this {event_type}..."
+ run-started: "👁️ [{workflow_name}]({run_url}) is running visual regression on this {event_type}..."
run-success: "✅ [{workflow_name}]({run_url}) completed visual regression check."
run-failure: "❌ [{workflow_name}]({run_url}) {status}. Check the [run logs]({run_url}) for details."
timeout-minutes: 30
---
-# Visual Regression Testing Agent 👁️
+# Visual Regression Agent 👁️
-You are the Visual Regression Testing Agent - an automated quality guard that captures UI screenshots on every pull request and compares them against stored baselines to detect unintended visual changes.
+You are the Visual Regression Agent. On every pull request, capture screenshots of key UI pages and compare them against baseline screenshots stored in cache-memory.
-## Current Context
+## Context
- **Repository**: ${{ github.repository }}
- **Pull Request**: #${{ github.event.pull_request.number }}
-- **PR Title**: ${{ github.event.pull_request.title }}
- **Base Branch**: ${{ github.event.pull_request.base.ref }}
-- **Head SHA**: ${{ github.event.pull_request.head.sha }}
- **Run ID**: ${{ github.run_id }}
-## Cache Memory Layout
-
-Baseline screenshots are stored in `/tmp/gh-aw/cache-memory/` using these paths:
-
-- `/tmp/gh-aw/cache-memory/baselines/` — reference screenshots from the base branch
-- `/tmp/gh-aw/cache-memory/baselines/manifest.json` — index of all baseline screenshots with metadata
-
-Current-run screenshots are saved to a temporary location:
-
-- `/tmp/visual-regression/current/` — screenshots from this PR's HEAD
+## Steps
-## Phase 1: Prepare Directories
-
-Create the directories needed for this run:
+### 1. Prepare directories
```bash
mkdir -p /tmp/gh-aw/cache-memory/baselines
mkdir -p /tmp/visual-regression/current
```
-Check whether baselines already exist for this base branch:
-
-```bash
-ls /tmp/gh-aw/cache-memory/baselines/
-```
-
-If `manifest.json` is present, baselines are available. If the directory is empty (first run), this agent will capture baseline screenshots and save them.
+### 2. Start the preview server
-## Phase 2: Start the Preview Server
-
-Start the application's preview/development server so Playwright can capture screenshots. The exact command depends on the project's tech stack:
+Build and serve the app locally (adjust for the project's stack), then wait for it to be ready:
```bash
-# Example: Next.js / React
npm run build && npm start &
-# Example: Vite
-npm run build && npm run preview &
-# Example: Static site
-python3 -m http.server 3000 --directory ./dist &
-```
-
-Wait for the server to become ready before proceeding:
-
-```bash
-# Wait up to 30 seconds for server to start
timeout 30 bash -c 'until curl -sf http://localhost:3000 > /dev/null; do sleep 1; done'
```
-## Phase 3: Capture Current Screenshots
+### 3. Capture screenshots
-Use Playwright to capture screenshots of all key pages. For each page:
+Use Playwright to navigate to each key page and take a full-page screenshot saved under `/tmp/visual-regression/current/`. Use filesystem-safe filenames (replace `/` with `_`, no special characters).
-1. **Navigate** to the page URL
-2. **Wait** for the page to finish loading (no network activity, no pending animations)
-3. **Take a full-page screenshot** and save it under `/tmp/visual-regression/current/`
-
-Use filesystem-safe filenames — replace `/` with `_` and avoid colons or special characters.
-
-**Example pages to capture** (adjust to match the project):
-- Home: `http://localhost:3000/` → `home.png`
-- About: `http://localhost:3000/about` → `about.png`
-- Dashboard: `http://localhost:3000/dashboard` → `dashboard.png`
-
-After capturing, generate a timestamp for the manifest (use filesystem-safe format — no colons):
+Generate a filesystem-safe timestamp when needed (no colons — colons break artifact uploads):
```bash
date -u "+%Y-%m-%d-%H-%M-%S"
```
-## Phase 4: Compare Against Baselines
-
-### Case A — No Baselines Found (First Run)
-
-If `/tmp/gh-aw/cache-memory/baselines/manifest.json` does not exist:
+### 4. Compare against baselines
-1. Copy the current screenshots to the baselines directory:
+**First run** — no `manifest.json` in `/tmp/gh-aw/cache-memory/baselines/`:
- ```bash
- cp /tmp/visual-regression/current/*.png /tmp/gh-aw/cache-memory/baselines/
- ```
+Copy current screenshots to `/tmp/gh-aw/cache-memory/baselines/` and write a `manifest.json`:
-2. Create a `manifest.json` file recording the baseline run:
-
- ```json
- {
- "created_at": "YYYY-MM-DD-HH-MM-SS",
- "base_branch": "${{ github.event.pull_request.base.ref }}",
- "run_id": "${{ github.run_id }}",
- "pages": ["home.png", "about.png", "dashboard.png"]
- }
- ```
-
- Save it to `/tmp/gh-aw/cache-memory/baselines/manifest.json`.
-
-3. Post a PR comment explaining that baselines have been initialized.
-
-### Case B — Baselines Exist (Comparison Run)
-
-For each page that was screenshotted:
-
-1. Compare the current screenshot to the baseline using `diff` (or pixel-level diff if available):
-
- ```bash
- diff /tmp/gh-aw/cache-memory/baselines/home.png \
- /tmp/visual-regression/current/home.png \
- && echo "MATCH" || echo "DIFF"
- ```
-
-2. Track which pages have changed versus which match the baseline.
+```json
+{
+ "created_at": "YYYY-MM-DD-HH-MM-SS",
+ "base_branch": "${{ github.event.pull_request.base.ref }}",
+ "run_id": "${{ github.run_id }}",
+ "pages": ["home.png", "dashboard.png"]
+}
+```
-3. Assemble a diff report (see Phase 5).
+**Subsequent runs** — baselines exist:
-## Phase 5: Post the Diff Report
+Compare each screenshot with its baseline and collect the list of changed pages.
-Use the `add-comment` safe output to post a structured report on the pull request.
+### 5. Post diff report
-### When All Pages Match ✅
+Use `add-comment` to post the results. Examples:
-```markdown
+**No changes:**
+```
## 👁️ Visual Regression — No Changes Detected
-
-All **N** pages match their baselines.
-
-| Page | Status |
-|------|--------|
-| Home | ✅ No change |
-| About | ✅ No change |
-| Dashboard | ✅ No change |
-
-> Baselines captured on `${{ github.event.pull_request.base.ref }}` — run ${{ github.run_id }}
+All N pages match their baselines.
```
-### When Differences Are Found ⚠️
-
-```markdown
+**Changes found:**
+```
## 👁️ Visual Regression — Changes Detected
-
-**N of M pages** differ from their baselines.
-
-| Page | Status |
-|------|--------|
-| Home | ✅ No change |
-| About | ⚠️ Changed |
-| Dashboard | ✅ No change |
-
-### Changed Pages
-
-#### About (`about.png`)
-
-
-View diff details
-
-[Describe the visual differences observed using the Playwright accessibility snapshot or diff output]
-
-
-
-### Next Steps
-
-- Review the changes above to confirm they are intentional
-- If intentional, update the baselines by deleting `/tmp/gh-aw/cache-memory/baselines/` on the next main branch run
-- If unintentional, investigate the CSS/layout changes introduced in this PR
-
-> Baselines captured on `${{ github.event.pull_request.base.ref }}` — run ${{ github.run_id }}
+N of M pages differ from their baselines.
+List each changed page with a description of the difference.
```
-### When Baselines Were Initialized 🆕
-
-```markdown
+**Baselines initialized:**
+```
## 👁️ Visual Regression — Baselines Initialized
-
-No prior baselines were found for branch `${{ github.event.pull_request.base.ref }}`. Screenshots of **N pages** have been captured and saved as the new baselines.
-
-| Page | Status |
-|------|--------|
-| Home | 🆕 Baseline saved |
-| About | 🆕 Baseline saved |
-| Dashboard | 🆕 Baseline saved |
-
-Future pull requests targeting `${{ github.event.pull_request.base.ref }}` will be compared against these baselines.
+No prior baselines found. N pages captured and saved as new baselines.
```
-## Phase 6: Update Baselines (Optional)
-
-If the PR **intentionally** changes the UI and the diff is expected, update the baselines by overwriting the stored screenshots:
+Always call a safe-output tool. If nothing changed, use noop:
-```bash
-cp /tmp/visual-regression/current/*.png /tmp/gh-aw/cache-memory/baselines/
+```json
+{"noop": {"message": "Visual regression complete: all pages match baselines"}}
```
-
-Update the `manifest.json` with the new timestamp and run ID. This is typically done when the PR is labeled `update-visual-baselines` — add a `pull_request` → `types: [labeled]` trigger for that automation.
-
-## Guidelines
-
-### Security
-- **Read-only GitHub permissions** — this workflow only reads PR context; all writes go through `safe-outputs`
-- **Localhost only** — Playwright is restricted to `localhost` / `127.0.0.1` to prevent SSRF
-- **Allowed extensions** — cache-memory is restricted to `.png` and `.json` to prevent storing unexpected file types
-
-### Filesystem-Safe Filenames
-Always use timestamps in `YYYY-MM-DD-HH-MM-SS` format (no colons). Colons are invalid in artifact and NTFS filenames and will cause upload failures.
-
-```bash
-# ✅ Correct
-date -u "+%Y-%m-%d-%H-%M-%S" # → 2026-02-25-05-33-46
-
-# ❌ Incorrect (contains colons)
-date -u "+%Y-%m-%dT%H:%M:%SZ" # → 2026-02-25T05:33:46Z
```
-### Baseline Scope
-The cache key `visual-regression-baselines-${{ github.event.pull_request.base.ref }}` scopes baselines **per base branch**, so `main` and `develop` each maintain independent baseline sets.
-
-### Page Selection
-Capture the most visually significant pages — landing pages, dashboards, and pages mentioned in the PR diff. Avoid pages behind authentication unless the server is set up with test credentials.
+## Key Design Decisions
-### Timeouts
-Give the preview server adequate time to start (use `timeout` + retry loops). Set `timeout-minutes: 30` to accommodate both the build step and screenshot capture.
-
-## Important Notes
-
-- **Always call a safe-output tool** — even if no visual differences are found, post a comment confirming the check passed. Failing to call any safe-output tool is the most common cause of workflow failures.
-
-```json
-{"noop": {"message": "No action needed: [brief explanation]"}}
-```
+- **`cache-memory` key per base branch** — `visual-regression-baselines-${{ github.event.pull_request.base.ref }}` scopes baselines to `main`, `develop`, etc. independently
+- **`allowed-extensions: [".png", ".json"]`** — restricts cache to screenshots and the manifest only
+- **`playwright.allowed_domains: [localhost, 127.0.0.1]`** — prevents SSRF; the app must be served locally
+- **`retention-days: 30`** — keeps baselines accessible beyond the default 7-day cache expiry
+- **Filesystem-safe timestamps** — `YYYY-MM-DD-HH-MM-SS` (no colons); colons are invalid in NTFS/artifact filenames
+- **Minimal permissions** — `contents: read` + `pull-requests: read`; all PR writes go through `safe-outputs`
From abc03a650e982b17f4be4d96db04990d34827524 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 06:12:53 +0000
Subject: [PATCH 4/5] docs: link visual-regression.md in
create-agentic-workflow agent prompt
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/agents/agentic-workflows.agent.md | 11 +++++++++++
.github/aw/create-agentic-workflow.md | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/.github/agents/agentic-workflows.agent.md b/.github/agents/agentic-workflows.agent.md
index e34a4da6123..c0f21877e1b 100644
--- a/.github/agents/agentic-workflows.agent.md
+++ b/.github/agents/agentic-workflows.agent.md
@@ -18,6 +18,7 @@ This is a **dispatcher agent** that routes your request to the appropriate speci
- **Creating report-generating workflows**: Routes to `report` prompt — consult this whenever the workflow posts status updates, audits, analyses, or any structured output as issues, discussions, or comments
- **Creating shared components**: Routes to `create-shared-agentic-workflow` prompt
- **Fixing Dependabot PRs**: Routes to `dependabot` prompt — use this when Dependabot opens PRs that modify generated manifest files (`.github/workflows/package.json`, `.github/workflows/requirements.txt`, `.github/workflows/go.mod`). Never merge those PRs directly; instead update the source `.md` files and rerun `gh aw compile --dependabot` to bundle all fixes
+- **Analyzing test coverage**: Routes to `test-coverage` prompt — consult this whenever the workflow reads, analyzes, or reports on test coverage data from PRs or CI runs
Workflows may optionally include:
@@ -118,6 +119,16 @@ When you interact with this agent, it will:
- "Bundle and close the Dependabot PRs for workflow dependencies"
- "Update @playwright/test to fix the Dependabot PR"
+### Analyze Test Coverage
+**Load when**: The workflow reads, analyzes, or reports test coverage — whether triggered by a PR, a schedule, or a slash command. Always consult this prompt before designing the coverage data strategy.
+
+**Prompt file**: https://github.com/github/gh-aw/blob/main/.github/aw/test-coverage.md
+
+**Use cases**:
+- "Create a workflow that comments coverage on PRs"
+- "Analyze coverage trends over time"
+- "Add a coverage gate that blocks PRs below a threshold"
+
## Instructions
When a user interacts with you:
diff --git a/.github/aw/create-agentic-workflow.md b/.github/aw/create-agentic-workflow.md
index 906f092e89f..3b700a066f5 100644
--- a/.github/aw/create-agentic-workflow.md
+++ b/.github/aw/create-agentic-workflow.md
@@ -208,7 +208,7 @@ These resources contain workflow patterns, best practices, safe outputs, and per
- `Package.swift`, `*.podspec` → add `swift`
- `composer.json` → add `php`
- `pubspec.yaml` → add `dart`
- - 💡 If you detect the task requires **browser automation**, suggest the **`playwright`** tool.
+ - 💡 If you detect the task requires **browser automation**, suggest the **`playwright`** tool. For **visual regression testing** (comparing screenshots across PRs), consult `.github/aw/visual-regression.md` for the reference pattern using `playwright` + `cache-memory`.
- 🔐 If building an **issue triage** workflow that should respond to issues filed by non-team members (users without write permission), suggest setting **`roles: all`** to allow any authenticated user to trigger the workflow. The default is `roles: [admin, maintainer, write]` which only allows team members.
**Scheduling Best Practices:**
From 7c7bcf8e11f35306f6866f577b0922ca4e09dc8f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Wed, 25 Feb 2026 06:20:59 +0000
Subject: [PATCH 5/5] docs: condense visual-regression.md instructions
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
.github/aw/visual-regression.md | 113 ++++----------------------------
1 file changed, 14 insertions(+), 99 deletions(-)
diff --git a/.github/aw/visual-regression.md b/.github/aw/visual-regression.md
index 5f1f6f308bf..dd1bf45fbf7 100644
--- a/.github/aw/visual-regression.md
+++ b/.github/aw/visual-regression.md
@@ -1,17 +1,17 @@
---
name: visual-regression
-description: Reference workflow for visual regression testing using playwright to capture screenshots and cache-memory to store baselines across pull requests
+description: Reference prompt for visual regression testing using playwright + cache-memory for baseline screenshot storage across pull requests
---
-# Visual Regression Testing Reference
+# Visual Regression Testing
-This is a reference workflow that demonstrates how to combine `playwright` (for capturing screenshots) with `cache-memory` (for storing baselines between runs) to implement visual regression testing on pull requests.
+Use `playwright` for screenshots and `cache-memory` to persist baselines between PR runs.
## Example Workflow
```markdown
---
-description: Captures screenshots on every PR and compares them against baselines stored in cache-memory to detect visual regressions
+description: Capture screenshots on every PR and compare against cached baselines to detect visual regressions
on:
pull_request:
types: [opened, synchronize, reopened]
@@ -33,111 +33,26 @@ tools:
- "cp *"
- "diff *"
- "date *"
- - "echo *"
safe-outputs:
add-comment:
max: 1
- messages:
- footer: "> 👁️ *Visual regression check by [{workflow_name}]({run_url})*"
- run-started: "👁️ [{workflow_name}]({run_url}) is running visual regression on this {event_type}..."
- run-success: "✅ [{workflow_name}]({run_url}) completed visual regression check."
- run-failure: "❌ [{workflow_name}]({run_url}) {status}. Check the [run logs]({run_url}) for details."
timeout-minutes: 30
---
-# Visual Regression Agent 👁️
+Build and serve the app locally, then use Playwright to capture full-page screenshots of key pages into `/tmp/visual-regression/current/`.
-You are the Visual Regression Agent. On every pull request, capture screenshots of key UI pages and compare them against baseline screenshots stored in cache-memory.
+Use filesystem-safe timestamps (no colons — colons break artifact uploads):
+`date -u "+%Y-%m-%d-%H-%M-%S"`
-## Context
+If `/tmp/gh-aw/cache-memory/baselines/manifest.json` does not exist, copy screenshots there as new baselines and post: "Baselines initialized — N pages captured."
-- **Repository**: ${{ github.repository }}
-- **Pull Request**: #${{ github.event.pull_request.number }}
-- **Base Branch**: ${{ github.event.pull_request.base.ref }}
-- **Run ID**: ${{ github.run_id }}
-
-## Steps
-
-### 1. Prepare directories
-
-```bash
-mkdir -p /tmp/gh-aw/cache-memory/baselines
-mkdir -p /tmp/visual-regression/current
-```
-
-### 2. Start the preview server
-
-Build and serve the app locally (adjust for the project's stack), then wait for it to be ready:
-
-```bash
-npm run build && npm start &
-timeout 30 bash -c 'until curl -sf http://localhost:3000 > /dev/null; do sleep 1; done'
-```
-
-### 3. Capture screenshots
-
-Use Playwright to navigate to each key page and take a full-page screenshot saved under `/tmp/visual-regression/current/`. Use filesystem-safe filenames (replace `/` with `_`, no special characters).
-
-Generate a filesystem-safe timestamp when needed (no colons — colons break artifact uploads):
-
-```bash
-date -u "+%Y-%m-%d-%H-%M-%S"
-```
-
-### 4. Compare against baselines
-
-**First run** — no `manifest.json` in `/tmp/gh-aw/cache-memory/baselines/`:
-
-Copy current screenshots to `/tmp/gh-aw/cache-memory/baselines/` and write a `manifest.json`:
-
-```json
-{
- "created_at": "YYYY-MM-DD-HH-MM-SS",
- "base_branch": "${{ github.event.pull_request.base.ref }}",
- "run_id": "${{ github.run_id }}",
- "pages": ["home.png", "dashboard.png"]
-}
-```
-
-**Subsequent runs** — baselines exist:
-
-Compare each screenshot with its baseline and collect the list of changed pages.
-
-### 5. Post diff report
-
-Use `add-comment` to post the results. Examples:
-
-**No changes:**
-```
-## 👁️ Visual Regression — No Changes Detected
-All N pages match their baselines.
-```
-
-**Changes found:**
-```
-## 👁️ Visual Regression — Changes Detected
-N of M pages differ from their baselines.
-List each changed page with a description of the difference.
-```
-
-**Baselines initialized:**
-```
-## 👁️ Visual Regression — Baselines Initialized
-No prior baselines found. N pages captured and saved as new baselines.
-```
-
-Always call a safe-output tool. If nothing changed, use noop:
-
-```json
-{"noop": {"message": "Visual regression complete: all pages match baselines"}}
-```
+Otherwise compare each screenshot to its baseline. Post a comment summarizing: pages unchanged / pages with diffs. If nothing changed, use the `noop` safe-output.
```
## Key Design Decisions
-- **`cache-memory` key per base branch** — `visual-regression-baselines-${{ github.event.pull_request.base.ref }}` scopes baselines to `main`, `develop`, etc. independently
-- **`allowed-extensions: [".png", ".json"]`** — restricts cache to screenshots and the manifest only
-- **`playwright.allowed_domains: [localhost, 127.0.0.1]`** — prevents SSRF; the app must be served locally
-- **`retention-days: 30`** — keeps baselines accessible beyond the default 7-day cache expiry
-- **Filesystem-safe timestamps** — `YYYY-MM-DD-HH-MM-SS` (no colons); colons are invalid in NTFS/artifact filenames
-- **Minimal permissions** — `contents: read` + `pull-requests: read`; all PR writes go through `safe-outputs`
+- **`cache-memory` key per base branch** — scopes baselines to `main`, `develop`, etc. independently
+- **`allowed_domains: [localhost, 127.0.0.1]`** — prevents SSRF; app must be served locally
+- **`retention-days: 30`** — keeps baselines beyond the default 7-day cache expiry
+- **Filesystem-safe timestamps** — `YYYY-MM-DD-HH-MM-SS` format; colons are invalid in artifact filenames
+- **Minimal permissions** — all PR writes go through `safe-outputs`, not GitHub tools