Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

drupal-content-cleanup

A Claude Code skill that cleans up years of content debt on a Drupal site — over core JSON:API, with zero contrib modules, and a human approval gate in front of every change.

What it does

you:    My blog has hundreds of old posts with messed up formatting —
        bold text instead of headings, broken images, missing alt text.
        Can you clean this up?

The skill then:

  1. Asks before it acts — scope (full site / demo pages / audit only), content types, dead-image handling, cosmetic depth, apply mode, model choice (with a cost estimate), and whether to back up the DB first.
  2. Audits every node over JSON:API: pseudo-headings, missing/junk alt text, dead images (HEAD-checked), spacer paragraphs, suspect <br>s.
  3. Fixes with judgment — the AI rewrites each body: bold section titles become <h2>/<h3> while bold inline labels stay bold; alt text is written by looking at the image (vision), never from filenames; dead images are flagged for a human, not guessed at.
  4. Applies safely — dry-run diff first, then JSON:API PATCH with a revision log message, so every change is one click from rollback in Drupal. A content hash guards against editing conflicts.
  5. Reports — a marketer-readable HTML report: what was found, what was fixed, what needs a human.

Architecture

Deterministic mechanics live in scripts; judgment lives in the AI.

Piece Role
SKILL.md The workflow + the judgment rules (see below)
scripts/audit.py Crawl via JSON:API, detect issues, HEAD-check images
scripts/apply.py Dry-run diffs; --live PATCHes with revisions + conflict detection
scripts/estimate.py Token/cost estimate shown before the user commits
scripts/report.py Before/after HTML report
approved-commands.md Every shell command a run uses, for permission pre-approval

The interesting part is the judgment rules in SKILL.md, each learned from a real page and a human review catch:

  • Judge the rendered page, not the database — this site's full_html format strips styles/classes on output, so stored markup lies.
  • Spacer <p>&nbsp;</p> removal is contextual: sometimes the fix is converting bare divs to real paragraphs, or stripping legacy margin:0 inline styles — not deleting the spacers.
  • <br> tags are read in context: leading/doubled ones are cruft; breaks in addresses, signatures, and botanical names are content.
  • Anything the AI judges too risky to restructure is flagged "needs a human" instead of touched.

Setup

Requires Claude Code, uv, and a Drupal 9+ site (local example uses DDEV).

  1. Copy (or symlink) this directory to ~/.claude/skills/drupal-content-cleanup/ (available everywhere) or <project>/.claude/skills/ (per-project).
  2. On the target site (dev/local only — never production directly):
    drush en jsonapi basic_auth -y
    drush cset jsonapi.settings read_only 0 -y
    drush role:create content_bot && drush user:create content-bot --password=…
    drush role:perm:add content_bot 'access content,edit any blog content,view media,use text format full_html'
  3. Create a .env next to SKILL.md (or at the project root):
    CLEANUP_BASE_URL=https://your-site.ddev.site
    CLEANUP_USER=content-bot
    CLEANUP_PASS=…
    CLEANUP_SITE_DIR=/path/to/local/ddev/project   # for backups & drush
    
  4. Ask Claude Code to clean up your content, or run /drupal-content-cleanup.

Site-specific bits to adjust for other sites: IMAGE_FIELDS in audit.py (this site's blog uses field_image_feature/field_image; the audit degrades gracefully if a type lacks them) and the full_html format check.

Safety model

  • Nothing is applied without a dry-run diff and an explicit --live step.
  • Every applied change is a Drupal revision with a descriptive log.
  • DB backup (local dump and/or remote via terminus) is offered — and gated — before the first apply.
  • The skill can't silently expand its own permissions: on first run it shows the exact command allowlist and asks what you're comfortable pre-approving. Content writes always prompt.

Cost

estimate.py prices the job from the audit before anything runs. For this site's ~700 flagged posts: ~6.8M input / ~4.0M output tokens — roughly $80 with bulk batches on Sonnet (recommended; the premium model writes the rules, a cheaper model executes them), vs ~175 hours of manual editing.

About

A Claude Code skill that cleans up years of content debt on a Drupal site — over core JSON:API, with zero contrib modules, and a human approval gate in front of every change.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages