agentleFS
respira-pressrespira-press/agent-skills-wordpress/skills/content-portability/SKILL.md

content-portability

Skill49 starsChanged 8 months agoMITView on GitHub

Use when the user says 'export my site', 'backup my pages before editing', 'download my content locally', or 'migrate content to my other site'. Exports pages, posts, and custom posts to portable local packages with builder data, media, and markdown, then imports elsewhere with ID remapping.

The file

Show its rules and text

We split this skill into the rules it gives an agent

23 rules. About 0 are common, 12 are distinctive, and 11 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈12

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 11

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Ask the user what to export:

    line 61
  2. Distinctive:

    Ask whether to include media downloads:

    line 65
  3. Very specific:

    Call wordpress_list_pages, wordpress_list_posts, and/or wordpress_list_custom_posts to enumerate content in scope

    line 70
  4. Distinctive:

    Create the export directory structure:

    line 75
  5. Distinctive:

    If media download is enabled:

    line 163
  6. Very specific:

    Call wordpress_list_media to get all media items

    line 164
  7. Very specific:

    Write media/media-index.json mapping old URLs and IDs to local paths

    line 167
  8. Very specific:

    Read manifest.json from the local package

    line 234
  9. Very specific:

    If media/ directory exists with files:

    line 239
  10. Distinctive:

    If media was not included in the package:

    line 243
  11. Distinctive:

    Ask the user for a bulk resolution strategy:

    line 260
  12. Distinctive:

    Skip conflicts: Only import non-conflicting content

    line 262
  13. Very specific:

    Rename imports: Add suffix to conflicting slugs (e.g., about-imported)

    line 263
  14. Distinctive:

    MANDATORY: Before overwriting any existing content, take a server-side snapshot of each target page/post using the existing snapshot system

    line 266
  15. Very specific:

    If no conflict or overwrite strategy: call wordpress_update_page or wordpress_update_post

    line 272
  16. Very specific:

    Call wordpress_inject_builder_content to apply the rewritten builder data

    line 283
  17. Very specific:

    Call wordpress_read_page with full includes

    line 309
  18. Very specific:

    Write a single timestamped file: ./respira-backups/home-2026-03-16-1430.json

    line 310
  19. Very specific:

    Read the local manifest.json to identify exported content

    line 320
  20. Distinctive:

    Key rule: Always continue on non-fatal errors (skip the item, log it).

    line 352
  21. Distinctive:

    Read-only export: No changes to the source site during export

    line 356
  22. Distinctive:

    No credential exposure: Only allowlisted meta is exported — no API keys, passwords, or sensitive plugin settings

    line 360
  23. Distinctive:

    Create complete local backups of pages, posts, and custom post types

    line 373

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Content Portability

Export WordPress content to portable local packages. Import to another site with smart ID remapping. Auto-backup before AI edits. Full builder data preservation, human-readable markdown previews, and optional media download.

What This Skill Does

Exports:

  • Pages, posts, and custom post types — individually or in bulk
  • Full builder data (Elementor, Bricks, Divi, etc.) alongside standard content
  • Allowlisted post meta (SEO fields, featured images, builder config)
  • Human-readable markdown preview of every page/post
  • Optional media binary download for fully offline packages
  • Manifest with hashes, stats, and export metadata

Imports:

  • Reads a local Respira Content Package and pushes to a target WordPress site
  • Smart ID remapping — media IDs, post IDs, and internal links rewritten for the target site
  • Bulk conflict resolution — detects slug collisions upfront, one decision for all
  • Mandatory server-side snapshots before any overwrites (safety net)
  • Builder JSON rewriting with full ID mapping tables
  • Fidelity verification — re-reads imported content and compares hashes

Auto-Backup:

  • Quick-backup mode before any AI edit — saves a local snapshot to ./respira-backups/
  • Timestamped, human-readable, zero-friction insurance

Requirements

  • Respira for WordPress plugin installed and activated
  • MCP connection configured (site URL + API key)
  • For import: write access on the target site
  • For media download: sufficient local disk space

How to Use

Trigger Phrases

  • "export my site"
  • "export the homepage"
  • "backup my pages before editing"
  • "download my content locally"
  • "migrate content to my other site"
  • "content portability"
  • "create a local backup"
  • "export with media"

Export Workflow

Phase 1: Scope Selection

  1. Ask the user what to export:
    • Single page/post: "export the homepage", "backup the about page"
    • Full site: "export everything", "download all my content"
    • By type: "export all blog posts", "export portfolio items"
  2. Ask whether to include media downloads:
    • Without media (default): Fast, small packages with URL references
    • With media: Downloads all referenced images/files locally for full offline portability

Phase 2: Content Enumeration 3. Call wordpress_list_pages, wordpress_list_posts, and/or wordpress_list_custom_posts to enumerate content in scope 4. For each item, call wordpress_read_page or wordpress_read_post with include=builder.extracted,meta.allowlisted to get full content with builder data 5. Report progress every 10 items: "Exported 30/120 pages..."

Phase 3: Write Local Package 6. Create the export directory structure:

respira-export/
├── manifest.json              # Package metadata, source site, export date, hashes
├── README.md                  # One-line import prompt for zero-friction migration
├── pages/
│   ├── home/
│   │   ├── content.json       # Full machine-readable export
│   │   └── content.md         # Human-readable markdown preview
│   ├── about/
│   │   ├── content.json
│   │   └── content.md
│   └── ...
├── posts/
│   ├── 2024-hello-world/
│   │   ├── content.json
│   │   └── content.md
│   └── ...
├── cpt/                       # Custom post types
│   └── {post_type}/
│       └── {slug}/
│           ├── content.json
│           └── content.md
└── media/                     # Only if --with-media
    ├── media-index.json       # URL→local-path mapping with old media IDs
    └── uploads/
        ├── hero-image.webp
        └── ...
  1. For each page/post, write two files:

content.json — machine-readable, contains:

{
  "export_version": "1.0",
  "source_site": "https://example.com",
  "exported_at": "2026-03-16T14:30:00Z",
  "post": {
    "id": 42,
    "post_type": "page",
    "title": "About Us",
    "slug": "about",
    "status": "publish",
    "content": "<full HTML content>",
    "excerpt": "...",
    "modified": "2026-03-10T09:00:00Z"
  },
  "builder": {
    "name": "bricks",
    "payload": {},
    "extracted": {}
  },
  "meta": {
    "_thumbnail_id": 108,
    "_yoast_wpseo_title": "About Us | Example"
  },
  "hashes": {
    "content_hash": "sha256:abc123...",
    "builder_hash": "sha256:def456...",
    "meta_hash": "sha256:ghi789..."
  }
}

content.md — human-readable markdown preview:

# About Us

**Source:** https://example.com/about/
**Type:** page | **Status:** publish | **Builder:** Bricks
**Exported:** 2026-03-16

---

[Rendered text content extracted from HTML, preserving headings and structure]

## Section: Hero
- Heading: "Welcome to Our Company"
- Text: "We've been helping businesses..."
- Image: hero-team-photo.webp (Media ID: 108)

## Section: Team
- Heading: "Meet the Team"
...
  1. If media download is enabled:
    • Call wordpress_list_media to get all media items
    • Filter to only media referenced by exported content
    • Download each file and save to media/uploads/
    • Write media/media-index.json mapping old URLs and IDs to local paths

Phase 4: Manifest & Stats 9. Write manifest.json:

{
  "export_version": "1.0",
  "source_site": "https://example.com",
  "source_wordpress_version": "6.7.1",
  "source_respira_version": "4.3.1",
  "exported_at": "2026-03-16T14:30:00Z",
  "scope": "full_site",
  "content": {
    "pages": 23,
    "posts": 8,
    "custom_post_types": { "portfolio": 12, "testimonial": 5 }
  },
  "media": {
    "included": true,
    "files": 156,
    "total_bytes": 52428800
  },
  "warnings": [],
  "skipped": [],
  "hashes": {
    "manifest_hash": "sha256:..."
  }
}
  1. Write README.md:
# Respira Content Package

Exported from: https://example.com
Date: 2026-03-16
Contents: 23 pages, 8 posts, 17 custom posts, 156 media files

## To import this content to another site

Tell your AI agent:
> Import the content package from ./respira-export/

## Package format
- content.json files contain full machine-readable content with builder data
- content.md files are human-readable previews
- media/ contains downloaded media files (if included)
  1. Show export stats summary:
Export Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━
Pages exported:     23
Posts exported:      8
Custom posts:       17
Media files:       156
Package size:     52.4 MB
Warnings:           0
Skipped:            0
━━━━━━━━━━━━━━━━━━━━━━━━━━
Saved to: ./respira-export/

Import Workflow

Phase 1: Read & Validate Package

  1. Read manifest.json from the local package
  2. Validate export version compatibility
  3. Report what will be imported: "Found 23 pages, 8 posts, 156 media files from example.com"

Phase 2: Upload Media (if included) 4. If media/ directory exists with files:

  • For each media file, call wordpress_upload_media on the target site
  • Build the media ID mapping table: { old_id: 108, new_id: 342 }
  • Log each upload; skip failures with warning
  1. If media was not included in the package:
    • Media references will point to original URLs (cross-site references)
    • Warn the user about this

Phase 3: Detect Conflicts 6. For each content item in the package, check if a page/post with the same slug already exists on the target site 7. Present all conflicts upfront in a single table:

Slug Conflicts Detected (5 of 23 pages)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Slug          Source Title       Target Title
about         About Us           About Our Company
contact       Contact            Contact Us
team          Our Team           The Team
services      Services           Our Services
faq           FAQ                FAQ
  1. Ask the user for a bulk resolution strategy:
    • Overwrite all: Replace target content with package content
    • Skip conflicts: Only import non-conflicting content
    • Rename imports: Add suffix to conflicting slugs (e.g., about-imported)

Phase 4: Snapshot Existing Content 9. MANDATORY: Before overwriting any existing content, take a server-side snapshot of each target page/post using the existing snapshot system

  • This uses the before_edit snapshot kind automatically via MCP write operations
  • Ensures rollback is always possible

Phase 5: Create/Update Content 10. For each content item: - If no conflict or overwrite strategy: call wordpress_update_page or wordpress_update_post - Set title, content, excerpt, status, and allowlisted meta - Build the post ID mapping table: { old_id: 42, new_id: 187 } 11. Report progress every 10 items

Phase 6: Rewrite & Inject Builder Data 12. For each imported page/post that has builder data: - Take the builder JSON from content.json - Rewrite all media IDs using the media ID mapping table - Rewrite all internal post/page IDs using the post ID mapping table - Rewrite all internal URLs from source domain to target domain - Call wordpress_inject_builder_content to apply the rewritten builder data

Phase 7: Verify & Report 13. For each imported page/post: - Re-read via wordpress_read_page/wordpress_read_post - Compare content hashes to source hashes - Flag any mismatches 14. Show import report:

Import Complete
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Pages imported:     23  (5 overwrites, 18 new)
Posts imported:      8  (0 overwrites, 8 new)
Media uploaded:    156  (2 skipped — too large)
Builder data:       19  pages with builder content rewritten
ID remappings:     187  references updated
Hash verification: 46/48 match (2 minor diffs flagged)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Server-side snapshots taken for all overwrites.

Auto-Backup Workflow

A lightweight mode for quick local backups before AI editing:

  1. User says "backup the homepage before editing" or "save a local copy first"
  2. Call wordpress_read_page with full includes
  3. Write a single timestamped file: ./respira-backups/home-2026-03-16-1430.json
  4. Also write the markdown preview: ./respira-backups/home-2026-03-16-1430.md
  5. Confirm: "Backed up homepage to ./respira-backups/home-2026-03-16-1430.json"
  6. Proceed with the requested edit

Diff Workflow

Compare local export against current site state:

  1. User says "what changed since my last export?" or "diff my backup"
  2. Read the local manifest.json to identify exported content
  3. For each exported page/post, call wordpress_read_page/wordpress_read_post
  4. Compare content hashes from local content.json against current site hashes
  5. Report differences:
Content Changes Since Export (2026-03-16)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Changed:
  about         Content updated (builder + text)
  homepage      Builder layout changed
  pricing       Text content changed

Unchanged:    21 pages, 8 posts
New on site:   2 pages (not in export)
Deleted:       0 pages

Error Handling

The skill must handle these scenarios gracefully:

ErrorActionUser Sees
Site disconnectedStop, report what was saved"Site unreachable — 45/120 pages saved"
Page not found mid-exportSkip, log in manifest warnings"Skipped: About (deleted)"
Malformed builder dataExport raw content without builderWarning in manifest
Disk fullStop, report progress"Disk full after 45 pages"
Media download 404/403Skip file, log in media-index"Skipped 3 media files"
Slug conflict on importBulk resolution (see Phase 3)Conflict table
Media upload too largeSkip, log"Skipped: hero.webp (too large)"
Builder version mismatchWarn, import anywayWarning in report

Key rule: Always continue on non-fatal errors (skip the item, log it). Never silently drop content. Always produce a summary of warnings/skips at the end.

Safety Model

  • Read-only export: No changes to the source site during export
  • Mandatory snapshots: Server-side snapshot taken before every import overwrite
  • Non-destructive import: Creates new content or overwrites with snapshot safety net
  • Rollback ready: Server-side snapshots enable one-click restoration via wordpress_restore_snapshot
  • No credential exposure: Only allowlisted meta is exported — no API keys, passwords, or sensitive plugin settings

Honest Disclaimer

What this skill CANNOT do:

  • Export/import WordPress settings, options, or configuration
  • Export/import user accounts or roles
  • Export/import plugin or theme files
  • Handle taxonomy/term migration (categories, tags) — future enhancement
  • Guarantee pixel-perfect builder rendering across different builder versions
  • Process sites with more than ~500 pages in a single session (token/context limits)

What this skill CAN do:

  • Create complete local backups of pages, posts, and custom post types
  • Preserve full builder data (Elementor, Bricks, Divi) across migrations
  • Download media for fully offline packages
  • Generate human-readable markdown previews of all content
  • Migrate content between sites with smart ID remapping
  • Auto-backup before AI edits for peace of mind
  • Compare local backups against current site state

Respira MCP Tools Used

  • wordpress_list_pages / wordpress_list_posts / wordpress_list_custom_posts — enumerate content
  • wordpress_read_page / wordpress_read_post / wordpress_get_custom_post — read full content with builder data
  • wordpress_list_media / wordpress_get_media — media enumeration and metadata
  • wordpress_upload_media — upload media during import
  • wordpress_update_page / wordpress_update_post / wordpress_update_custom_post — create/update content during import
  • wordpress_inject_builder_content — apply rewritten builder data during import
  • wordpress_get_active_site / wordpress_get_site_context — verify connection and site details
  • wordpress_list_snapshots / wordpress_restore_snapshot — safety net for imports

Related Skills

  • Site Onboarding — first-run primer, discovers site capabilities
  • WordPress Site DNA — deep site archaeology and health scoring
  • Technical Debt Audit — find orphaned content and unused plugins before migration
  • WordPress AI Image Optimizer — optimize images before or after migration

Built by Respira for WordPress https://respira.press

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.