---
name: theme-review
description: Review a WordPress block theme against the team checklist and draft a PR comment with findings.
---

# Theme Review Skill

This skill reviews a WordPress block theme against the team's quality checklist and generates a draft PR comment with the findings. The reviewer can edit the draft before posting.

## Usage

```
/theme-review themeslug
```

## Step 1: Parse Arguments

Extract the theme slug from `$ARGUMENTS`.

**Arguments received:** $ARGUMENTS

If no argument provided, ask the user for the theme slug using `AskUserQuestion`.

## Step 2: Locate the Theme

The theme should be located at `./<theme-slug>/` relative to the current working directory.

```bash
ls -la ./<theme-slug>/
```

If the theme directory doesn't exist, inform the user and stop.

## Step 3: Run Automated Checks

Run through each section of the checklist in @checklist.md and collect findings.

### 3.1 Required Templates Check

Verify the theme has these required templates:
- `archive.html`
- `index.html`
- `404.html`
- `page.html`
- `search.html`
- `single.html`

### 3.2 Template Content Checks

For each template (or pattern it references):

**archive.html:**
- Has `wp:query-title` with `type: archive`
- Has `wp:query` block with `"inherit": true`
- Has `wp:query-no-results` with descriptive text
- Has `wp:query-pagination`

**index.html:**
- Has `wp:query` block with `"inherit": true`
- Has `wp:query-pagination`

**404.html:**
- Has error message (heading/text)
- Has `wp:search` block

**page*.html (all page templates):**
- Has `wp:post-content`
- (Bonus) Content block is locked

**search.html:**
- Has `wp:query-title` with `type: search`
- Has `wp:query` block with `"inherit": true`
- Has `wp:query-no-results` with descriptive text
- Has `wp:query-pagination`

**single*.html (all single templates):**
- Has `wp:post-content`
- (Bonus) Content block is locked

**Semantic `<main>` tag (all templates):**
- Each template (including patterns it references) has exactly one `"tagName":"main"` block
- No duplicate `<main>` tags

**Hardcoded text (all templates):**
- No `.html` template files contain hardcoded text requiring i18n
- All user-facing text should be in patterns (PHP) where translation functions can be used

### 3.3 theme.json Checks

- "Big" font sizes use the `fluid` option
- If custom `spacingSizes`: `defaultSpacingSizes` is `false` (version 3)
- `spacingSizes` over 20px use `clamp()` or `min()`
- No unitless values in `styles.spacing.padding`
- `customTemplates` match actual template files
- `templateParts` are registered with proper titles

### 3.4 functions.php Checks

- All block stylesheets in `/assets/css/blocks/` are enqueued

### 3.5 Assets Checks

**/assets/fonts/:**
- All fonts registered in `theme.json` or `/styles/typography/*.json`
- File paths match actual files (case-sensitive)

**/assets/images/:**
- All images are used in the theme
- All references use `get_template_directory_uri()`

### 3.6 Template Parts Checks

- All parts are used in templates
- No hardcoded text (or patterns use proper i18n)
- Registered in `theme.json`'s `templateParts`

### 3.7 Patterns Checks

- Template patterns have `Inserter: no`
- User patterns have `Categories` defined
- User patterns consistently include `Viewport width` in their headers
- All text strings are internationalized

**i18n false-positive exclusions:** Block comment attributes (e.g., `"label":"Email"` inside `<!-- wp:jetpack/label ... /-->` or `"ariaLabel":"Post navigation"` inside `<!-- wp:group ... -->`) cannot use PHP translation functions. These are rendered server-side by their respective blocks and should NOT be flagged as i18n issues. Only flag text that appears directly in PHP output or HTML markup outside of block comments.

### 3.8 Navigation Blocks Check

- No navigation blocks have `"ref"` attribute (site-specific IDs)

### 3.9 Style Variations Check

- Identify color/style variations in `/styles/*.json`
- Flag for manual contrast testing if found

### 3.10 File Metadata Checks

**screenshot.png or screenshot.jpg:**
- Dimensions: 1200 x 900
- Size: warn if over 1MB

**readme.txt:**
- Contributors is Automattic
- Tested up to is latest WP version
- Requires PHP is 7.2+
- Description present
- Changelog present
- Copyright section with GPL
- All fonts credited
- All images credited

**style.css:**
- Version uses semantic versioning (X.X.X)
- Author is Automattic
- Description matches readme.txt
- Tags validated against allowed list: Fetch the allowed tags from `https://api.wordpress.org/themes/info/1.1/?action=feature_list` using `WebFetch`. Flatten all tag arrays from the response (Layout, Features, Subject) into a single allowed set. Compare each tag in style.css against this set and report any invalid tags as issues. This check MUST be automated — do NOT defer to manual review.

### 3.11 Block Markup Validation

For each pattern file and template part, validate that block comments match the HTML markup. Mismatches cause "Block contains unexpected or invalid content" errors in the editor.

**Nesting validation:**
- Every opening block comment (`<!-- wp:blockname -->`) has a matching `<!-- /wp:blockname -->`
- Self-closing blocks use `<!-- wp:blockname /-->` syntax
- No orphaned opening or closing comments

**JSON attribute validation:**
- JSON in block comments (e.g., `<!-- wp:group {"align":"full"} -->`) is valid and parseable

**Attribute-to-markup consistency:**
Check that key block attributes are reflected in the HTML element that immediately follows:
- `"align"` → element has `align{value}` class (e.g., `alignfull`, `alignwide`)
- `"textAlign"` → element has `has-text-align-{value}` class
- `"fontSize"` → element has `has-{value}-font-size` class
- `"backgroundColor"` → element has `has-{value}-background-color` class
- `"textColor"` → element has `has-{value}-color` class
- `"className"` → each class listed appears in the element's `class` attribute
- `"dropCap": true` → element has `has-drop-cap` class
- `"tagName"` → the HTML element tag matches (e.g., `"tagName":"main"` → `<main`)

**Tag name validation for known blocks:**
- `wp:paragraph` → `<p>`
- `wp:heading` → `<h1>` through `<h6>`
- `wp:image` → `<figure>` with `wp-block-image` class
- `wp:list` → `<ul>` or `<ol>`
- `wp:quote` → `<blockquote>`
- `wp:group` → `<div>` (or element matching `tagName` attribute)

**Note:** This won't catch every issue Gutenberg catches (it has full block schema validation), but it catches the most common hand-editing mistakes.

### 3.12 Housekeeping Checks

- No OS metadata files (`.DS_Store`, `Thumbs.db`, `desktop.ini`) in the theme directory
- No editor/AI tool config directories (`.idea/`, `.vscode/`, `.claude/`, `.cursor/`, `.windsurf/`) in the theme directory

### 3.13 Referenced CSS Files Check

- `editor-style.css` referenced in `functions.php` exists at the expected path
- `editor-ui.css` referenced in `functions.php` exists at the expected path (if used)
- Any other CSS files referenced in `functions.php` exist

### 3.14 Image Alt Text Check

- Flag images with empty `alt=""` attributes in patterns for manual review to confirm they are intentionally decorative

### 3.15 Global Checks

- All `fontSize` values use theme presets (no hardcoded px/rem/em)
- No localhost/staging/dev URLs
- No Unicode line terminator characters (U+2028 Line Separator or U+2029 Paragraph Separator) in any `.php` or `.html` file — these sneak in via copy-paste and can silently break PHP comment parsing
- No dev tool artifact directories (`.claude`, `.cursor`, `.vscode`, `.idea`, etc.) present in the theme folder

## Step 4: Identify Additional Templates

Flag any templates beyond the standard set for manual review:
- `home.html`
- `front-page.html`
- Custom templates (e.g., `category-*.html`)

## Step 5: Generate Draft PR Comment

Create a formatted PR comment with all findings:

```markdown
## Theme Review: <theme-slug>

### Summary
- **Passed:** X checks
- **Issues:** X issues found
- **Manual Review Needed:** X items

---

### Automated Checks

#### Required Templates
| Template | Status |
|----------|--------|
| archive.html | ✅ |
| index.html | ✅ |
| ... | ... |

#### Template Content
[Details of each template check...]

#### theme.json
[Details...]

#### Assets
[Details...]

#### Patterns
[Details...]

---

### Issues Found

1. **[File:Line]** - Description of issue
2. **[File:Line]** - Description of issue

---

### Manual Review Needed

- [ ] Color variations contrast testing
- [ ] Custom template: `category-blog.html`

---

*Generated by `/theme-review` skill. Please verify findings before posting.*
```

## Step 6: Present Draft to Reviewer

Display the draft comment and ask the reviewer:

Use `AskUserQuestion` with options:
- **Post comment** - Post the comment to the PR (requires PR number)
- **Copy to clipboard** - Copy the comment for manual posting
- **Edit and retry** - Let reviewer suggest edits
- **Cancel** - Discard the draft

### If "Post comment" selected:

Ask for the PR number if not already known, then post:

```bash
gh pr comment <PR-NUMBER> --body "<COMMENT>"
```

### If "Copy to clipboard" selected:

```bash
echo "<COMMENT>" | pbcopy
```

Inform the user the comment is copied.

## Additional Notes

- This skill does NOT make any changes to the theme
- All checks are read-only
- The reviewer should always verify findings before posting
- Some checks require manual verification (noted in output)
- Use Unicode emoji (✅ ❌ ⚠️) instead of GitHub shortcodes (`:white_check_mark:`) so the draft renders correctly both in the terminal preview and on GitHub

## Reference

See @checklist.md for the complete checklist with detailed explanations.
