agentsclimarketplace

Block refactoring

Skill hekivo/superpowers-sage/skills/block-refactoring

Refactor ACF Composer blocks — evolve blocks along 4 axes: rendering model, field composition, block variants $styles, InnerBlocks adoption; legacy block migration, ACF Composer v2 to v3, block phase classification, atomic vs container, block evolution report, get_block_wrapper_attributes, $styles, $innerBlocks, refactor without breaking existing content, block refactoring reportFrom its SKILL.md

Install
npx -y skills add hekivo/superpowers-sage --skill block-refactoring

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 13 stars13 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.1 KB, as published. Nobody here has run it

Block Refactoring — Evolution of Existing Blocks

Analyze and improve an existing block after its first implementation. Four axes of evolution: design drift detection, CSS coverage analysis, variation expansion, and gap/migration detection.

Announce at start: "I'm using the block-refactoring skill to evolve the block."

When to use

  • Block shipped in a previous PR and design has evolved since
  • CSS bundle includes rules/tokens that are no longer used
  • New design tokens exist in app.css/design-tokens.md that the block could leverage
  • Legacy block still uses v1 pattern (.b-{slug} class, dual selector, no custom element)
  • You suspect implementation diverged from design reference during initial build

When NOT to use

  • Creating a new block from scratch → use /block-scaffolding instead
  • Project-wide convention audit → use /reviewing
  • Non-block UI component → Blade components are not ACF blocks

Input

$ARGUMENTS

Resolve to {ClassName} and {slug}. If not provided, ask.


See references/evolution-axes.md for the 4 evolution axes.

Refactoring NEVER rebuilds from scratch. For a full re-scaffold, delegate to /block-scaffolding as a fallback.


Procedure

Phase 0 — Resolve block identity and locate files

From the argument, identify:

  • {ClassName} — e.g. HeroSection
  • {slug} — e.g. hero-section
  • 5 target files (one may be absent on legacy blocks):
    • app/Blocks/{ClassName}.php
    • resources/views/blocks/{slug}.blade.php
    • resources/css/blocks/{slug}.css
    • resources/js/blocks/{slug}.js (may not exist — legacy)
    • resources/css/editor.css (check for @import './blocks/{slug}.css')

Read all present files.

Phase 0b — Shared component inventory

Glob resources/views/components/*.blade.php in the target project (if a path is known, otherwise skip this step).

Build a component inventory table:

Component slugFileLikely use
section-headersection-header.blade.php<x-eyebrow> + <h2> pairing
buttonbutton.blade.php<a> or <button> with utility classes
cardcard.blade.phpRepeated card structure

Keep this table in context — G9 in Axis 4 will reference it to report concrete component names instead of generic suggestions.

If resources/views/components/ does not exist or is empty, note "No shared components found" and proceed.

Phase 1 — Classify current pattern version

Inspect the view file and the CSS file:

SignalVersion
View has <block-{slug}> custom elementv2
View uses $attributes->merge() on a <section class="b-{slug}">v1
CSS scoped to block-{slug} tag selectorv2
CSS scoped to .b-{slug} class selectorv1
CSS has dual selector &.is-style-*, .is-style-* &v1
CSS has single selector .is-style-* block-{slug}v2
JS file at resources/js/blocks/{slug}.jsv2

Mark the block's current version (v1 / v2 / mixed) before proceeding.


AXIS 1 — Design drift detection

Prerequisites: a design reference must be available. Check in order:

  1. MCP design tool with the project's file open (Pencil / Paper / Figma / Stitch)
  2. docs/plans/*/assets/section-{slug}-ref.png on disk
  3. docs/plans/*/assets/section-{slug}-spec.md on disk

If none available, report drift: NOT_VERIFIED and skip to Axis 2.

Execution:

  1. Dispatch visual-verifier agent with:
    • url: current environment's URL for a page rendering the block
    • selector: block-{slug} (v2) or .b-{slug} (v1)
    • ref: the reference path found above
    • spec: spec file path if available
  2. Collect: MATCH | DRIFT | MISSING | FAIL_ARBITRARY_VALUES
  3. If DRIFT: capture the exact divergences (typography size, color hex, spacing px) for Phase 6 report

For detailed axis procedures (CSS coverage, variation expansion, gap checks G1–G8), see references/evolution-axes.md.

G9. Component reuse gap

Grep the view for co-occurring <x-eyebrow and <h2 inline — these should use <x-section-header> instead. Also grep for <a elements carrying button utility classes (e.g. btn-, rounded-, px-, py-, font-) — these should be <x-button>.

Each instance where a component from the Phase 0b inventory exists but is not used: flag as IMPROVEMENT, naming the component (e.g., "use <x-section-header> instead of inline <x-eyebrow> + <h2>").

G10. CSS custom property cascade not used

Detection — check the view for any of:

  • match($tone) expressions returning Tailwind class strings (e.g. match($tone) { 'fg' => 'text-fg', 'dark' => 'text-depth-fg' })
  • Props declared as tone="fg" / tone="dark" / variant="*-dark" encoding color context in PHP and passing it to child components
  • Hardcoded color utility classes (text-depth-fg, text-identity, text-white) applied directly on semantic elements (h2, p, span) instead of via inherited CSS variables

Colors must cascade from custom properties in the block's CSS; the view must not encode color context via conditional logic or hardcoded utilities. Each instance is CRITICAL.

When detected, generate corrected CSS for the Phase 6 report:

  1. Run inline component inventory: glob resources/views/components/*.blade.php, grep each for var(--) patterns → build local variable name registry (same logic as block-scaffolding Phase 0b; runs inline here, not delegated)
  2. Read design-guide.md ## Tokens → Colors to determine background context:
    • If design-guide.md exists at docs/plans/*/components/*/design-guide.md → apply decision table
    • If design-guide.md is absent → treat as Ambiguous; generate with /* VERIFY: design-guide.md not found — confirm background context */
  3. Apply decision table:
    Token foundBackgroundCSS action
    bg-depth, bg-primary, bg-dark, bg-inverseDarkOverride cascade vars with *-on-dark equivalents
    bg-identity, bg-sage, bg-accentIdentity (brand color bg)Override cascade vars with *-on-identity equivalents (e.g. var(--color-identity-fg))
    bg-bg, bg-surface, bg-muted, absentLight (default)No override — inherit :root defaults
    Unrecognized tokenAmbiguousGenerate with /* VERIFY: background context unknown */
  4. Include generated CSS in Phase 6 report (see report-format.md G10 section template)

G11. nl2br on non-textarea fields

For each nl2br(esc_html($var)) call in the view, trace the variable back to its ACF field definition in app/Blocks/{ClassName}.php. If the field uses addText() (single-line text), nl2br() is a no-op at best and misleading at worst. Flag as IMPROVEMENT — remove nl2br() or change the field to addTextarea() / addWysiwyg().


Phase 6 — Report and propose

See references/report-format.md for the refactoring report format.


Phase 7 — Apply approved changes

After user approves proposals, apply in order: CSS removals → variation expansions → gap fixes. Run lando theme-build && lando flush to verify.


Phase 8 — Verification

Use Playwright MCP to screenshot at canonical width and verify all variations. Then:

git commit -m "refactor(blocks): {slug} — {summary of applied changes}"

Anti-drift — don't reintroduce

See /block-scaffolding anti-drift table — same rules apply during refactor. Every proposal in Phase 6 should, after applied, produce code that would pass /block-scaffolding as if the block were being created today.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.