Blueprint
WordPressOfficialPublished by WordPress
- Skill
- Tool integration
- Software development
- GPL-2.0-or-later
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
A Blueprint is a JSON file that provides a declarative configuration for WordPress Playground instances. It allows users to automate the setup of WordPress environments, including installing plugins and themes, setting site options, executing PHP or SQL code, and manipulating files. Blueprints are designed to be portable, working across web, Node.js, and CLI environments, and they rely on a strict schema to ensure valid configurations.
What it does
- Defines WordPress environments using JSON configuration files.
- Automates plugin and theme installation from various sources like WordPress.org, URLs, or Git repositories.
- Executes custom PHP code and WP-CLI commands within the Playground instance.
- Manages file system operations such as writing, moving, or unzipping files.
- Supports the creation of self-contained Blueprint bundles for distribution.
- Validates configuration against the official WordPress Playground schema.
When to use it
- When you need to automate the setup of a consistent WordPress environment for testing or development.
- When creating reproducible WordPress demos or sandboxes.
- When you need to bundle custom plugins or themes with a specific WordPress configuration.
- When you want to share a specific WordPress state via a URL or a portable bundle.
Advantages
- Declarative configuration eliminates manual setup steps.
- Portable across browser, Node.js, and CLI environments.
- Supports complex setups including custom PHP code and database modifications.
- Enables version control for environment configurations.
- Self-contained bundles simplify distribution and sharing.
Usage examples
- “Create a blueprint that installs the WooCommerce plugin and sets the site title to 'My Shop'.”
- Generates a JSON file with a 'plugins' shorthand array containing 'woocommerce' and a 'setSiteOptions' step for the blogname.
- “How do I include a local plugin in my blueprint bundle?”
- Provides instructions to zip the plugin directory and use the 'bundled' resource type in the blueprint JSON.
- “Write a step to run a custom SQL query in my blueprint.”
- Provides a 'runSql' step example using a 'literal' resource to define the SQL content.
- “How can I test my blueprint locally?”
- Explains how to use the @wp-playground/cli server command with the --blueprint flag.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/wordpress/blueprint/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip blueprint.zip -d .agents/skills
Documentation by WordPress
WordPress Playground Blueprints
Overview
A Blueprint is a JSON file that declaratively configures a WordPress Playground instance — installing plugins/themes, setting options, running PHP/SQL, manipulating files, and more.
Core principle: Blueprints are trusted JSON-only declarations. No arbitrary JavaScript. They work on web, Node.js, and CLI.
Quick Start Template
{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/",
"preferredVersions": { "php": "8.3", "wp": "latest" },
"steps": [{ "step": "login" }]
}Top-Level Properties
All optional. Only documented keys are allowed — the schema rejects unknown properties.
| Property | Type | Notes |
|---|---|---|
$schema | string | Always "https://playground.wordpress.net/blueprint-schema.json" |
landingPage | string | Relative path, e.g. /wp-admin/ |
description | string | Deprecated optional top-level description. Prefer meta.description for new Blueprints |
meta | object | { title, author, description?, categories? } — title and author required |
preferredVersions | object | { php, wp } — both required when present |
features | object | { networking?: boolean, intl?: boolean } — only these two keys, nothing else. Networking defaults to true |
phpExtensionBundles | any | Deprecated/no longer used; the schema leaves the value unconstrained and says to remove it from Blueprints |
extraLibraries | array | ["wp-cli"] — auto-included when any wp-cli step is present |
constants | object | Shorthand for defineWpConfigConsts. Values: string/boolean/number |
plugins | array | Shorthand for installPlugin steps. Strings = wp.org slugs |
siteOptions | object | Shorthand for setSiteOptions |
login | boolean or object | true = login as admin. Object = { username?, password? } (both default to "admin"/"password") |
steps | array | Main execution pipeline. Runs after shorthands |
preferredVersions Values
php: Major.minor only:
"7.4","8.0","8.1","8.2","8.3","8.4","8.5", or"latest". Patch versions like"7.4.1"are invalid. Check the schema for currently supported versions.wp: Recent major versions,
"latest","beta","nightly"/"trunk", or a URL to a custom zip. The schema also acceptsfalsefor PHP-only Playground; do not combinewp: falsewith WordPress-only fields such asplugins,siteOptions,login, or WordPress-only steps.
Shorthands vs Steps
Shorthands (login, plugins, siteOptions, constants) are expanded and prepended to steps in an unspecified order. Use explicit steps when execution order matters.
Resource References
Resources tell Playground where to find files. Used by installPlugin, installTheme, writeFile, writeFiles, importWxr, etc.
| Resource Type | Required Fields | Example |
|---|---|---|
wordpress.org/plugins | slug | { "resource": "wordpress.org/plugins", "slug": "woocommerce" } |
wordpress.org/themes | slug | { "resource": "wordpress.org/themes", "slug": "astra" } |
url | url | { "resource": "url", "url": "https://example.com/plugin.zip" } |
git:directory | url, ref | See below |
literal | name, contents | { "resource": "literal", "name": "file.txt", "contents": "hello" } |
literal:directory | name, files | See below |
bundled | path | References a file within a blueprint bundle (e.g. { "resource": "bundled", "path": "/plugin.zip" }) |
zip | inner | Wraps another resource in a ZIP — use when a step expects a zip but your source isn't one (e.g. wrapping a url resource pointing to a raw directory) |
git:directory — Installing from GitHub
{
"resource": "git:directory",
"url": "https://github.com/WordPress/gutenberg",
"ref": "trunk",
"refType": "branch",
"path": "/"
}When using a branch or tag name for
ref, you must setrefType("branch"|"tag"|"commit"|"refname"). Without it, only"HEAD"resolves reliably.pathselects a subdirectory (defaults to repo root).
literal:directory — Inline File Trees
{
"resource": "literal:directory",
"name": "my-plugin",
"files": {
"plugin.php": "<?php /* Plugin Name: My Plugin */ ?>",
"includes": {
"helper.php": "<?php // helper code ?>"
}
}
}filesuses nested objects for subdirectories — keys are filenames or directory names, values are plain strings (file content) or objects (subdirectories). Never use resource references as values.Do NOT use path separators in keys (e.g.
"includes/helper.php"is wrong — use a nested"includes": { "helper.php": "..." }object).
Steps Reference
Every step requires "step": "<name>". Any step can optionally include "progress": { "weight": 1, "caption": "Installing..." } for UI feedback.
Plugin & Theme Installation
{
"step": "installPlugin",
"pluginData": { "resource": "wordpress.org/plugins", "slug": "gutenberg" },
"options": { "activate": true, "targetFolderName": "gutenberg" },
"ifAlreadyInstalled": "overwrite"
}{
"step": "installTheme",
"themeData": { "resource": "wordpress.org/themes", "slug": "twentytwentyfour" },
"options": { "activate": true, "importStarterContent": true },
"ifAlreadyInstalled": "overwrite"
}Use
pluginData/themeData— NOT the deprecatedpluginZipFile/themeZipFile.pluginData/themeDataaccept any FileReference or DirectoryReference — a zip URL, awordpress.org/pluginsslug, agit:directory, or aliteral:directory(nozipwrapper needed).options.activatecontrols activation. No need for a separateactivatePlugin/activateThemestep when usinginstallPlugin/installTheme.ifAlreadyInstalled:"overwrite"|"skip"|"error"
Activation (standalone)
Only needed for plugins/themes already on disk (e.g. after writeFile/writeFiles):
{ "step": "activatePlugin", "pluginPath": "my-plugin/my-plugin.php" }{ "step": "activateTheme", "themeFolderName": "twentytwentyfour" }File Operations
{ "step": "writeFile", "path": "/wordpress/wp-content/mu-plugins/custom.php", "data": "<?php // code" }data accepts a plain string (as shown above) or a resource reference (e.g. { "resource": "url", "url": "https://..." }).
{
"step": "writeFiles",
"writeToPath": "/wordpress/wp-content/plugins/",
"filesTree": {
"resource": "literal:directory",
"name": "my-plugin",
"files": {
"plugin.php": "<?php\n/*\nPlugin Name: My Plugin\n*/",
"includes": {
"helpers.php": "<?php // helpers"
}
}
}
}writeFiles requires a DirectoryReference (literal:directory or git:directory) as filesTree — not a plain object.
Other file operations: mkdir, cp, mv, rm, rmdir, unzip.
Running Code
runPHP:
{ "step": "runPHP", "code": "<?php require '/wordpress/wp-load.php'; update_option('key', 'value');" }GOTCHA: You must require '/wordpress/wp-load.php'; to use any WordPress functions.
wp-cli:
{ "step": "wp-cli", "command": "wp post create --post_type=page --post_title='Hello' --post_status=publish" }The step name is wp-cli (with hyphen), NOT cli or wpcli.
runSql:
{ "step": "runSql", "sql": { "resource": "literal", "name": "q.sql", "contents": "UPDATE wp_options SET option_value='val' WHERE option_name='key';" } }Site Configuration
{ "step": "setSiteOptions", "options": { "blogname": "My Site", "blogdescription": "A tagline" } }{ "step": "defineWpConfigConsts", "consts": { "WP_DEBUG": true } }{ "step": "setSiteLanguage", "language": "en_US" }{ "step": "defineSiteUrl", "siteUrl": "https://example.com" }Other Steps
| Step | Key Properties |
|---|---|
login | username?, password? (default "admin" / "password") |
enableMultisite | (no required props) |
importWxr | file (FileReference) |
importThemeStarterContent | themeSlug? |
importWordPressFiles | wordPressFilesZip, pathInZip? — imports a full WordPress directory from a zip |
request | request: { url, method?, headers?, body? } |
updateUserMeta | userId, meta |
runWpInstallationWizard | options? — runs the WP install wizard with given options |
resetData | (no props) |
Common Patterns
Inline mu-plugin (quick custom code)
{
"step": "writeFile",
"path": "/wordpress/wp-content/mu-plugins/custom.php",
"data": "<?php\n// mu-plugins load automatically — no activation needed, no require wp-load.php\nadd_filter('show_admin_bar', '__return_false');"
}Inline plugin with multiple files
{
"step": "writeFiles",
"writeToPath": "/wordpress/wp-content/plugins/",
"filesTree": {
"resource": "literal:directory",
"name": "my-plugin",
"files": {
"my-plugin.php": "<?php\n/*\nPlugin Name: My Plugin\n*/\nrequire __DIR__ . '/includes/main.php';",
"includes": {
"main.php": "<?php // main logic"
}
}
}
}Then activate it with a separate step:
{ "step": "activatePlugin", "pluginPath": "my-plugin/my-plugin.php" }Plugin from a GitHub branch
{
"step": "installPlugin",
"pluginData": {
"resource": "git:directory",
"url": "https://github.com/user/repo",
"ref": "feature-branch",
"refType": "branch",
"path": "/"
}
}Common Mistakes
| Mistake | Correct |
|---|---|
pluginZipFile / themeZipFile | pluginData / themeData |
"step": "cli" | "step": "wp-cli" |
Flat object as writeFiles.filesTree | Must be a literal:directory or git:directory resource |
Path separators in files keys | Use nested objects for subdirectories |
runPHP without wp-load.php | Always require '/wordpress/wp-load.php'; for WP functions |
| Invented top-level keys | Only documented keys work — schema rejects unknown properties |
| Inventing proxy URLs for GitHub | Use git:directory resource type |
Omitting refType with branch/tag ref | Required — only "HEAD" works without it |
Resource references in literal:directory files values | Values must be plain strings (content) or objects (subdirectories) — never resource refs |
features.debug or other invented feature keys | features only supports networking and intl — use constants: { "WP_DEBUG": true } for debug mode |
require wp-load.php in mu-plugin code | Only needed in runPHP steps — mu-plugins already run within WordPress |
Schema URL with .org domain | Must be playground.wordpress.net, not playground.wordpress.org |
Full Reference
This skill covers the most common steps and patterns. For the complete API, see:
Blueprint docs: https://wordpress.github.io/wordpress-playground/blueprints
JSON schema: https://playground.wordpress.net/blueprint-schema.json
Additional steps not covered above: runPHPWithOptions (run PHP with custom ini settings), runWpInstallationWizard, and resource types vfs and bundled (for advanced embedding scenarios).
Blueprint Bundles
Bundles are self-contained packages that include a blueprint.json along with all the resources it references (plugins, themes, WXR files, etc.). Instead of hosting assets externally, bundle them alongside the blueprint.
Bundle Structure
my-bundle/
├── blueprint.json ← must be at the root
├── my-plugin.zip ← zipped plugin directory
├── theme.zip
└── content/
└── sample-content.wxrPlugins and themes must be zipped before bundling — installPlugin expects a zip, not a raw directory. To create the zip from a plugin directory:
cd my-bundle
zip -r my-plugin.zip my-plugin/Referencing Bundled Resources
Use the bundled resource type to reference files within the bundle:
{
"step": "installPlugin",
"pluginData": {
"resource": "bundled",
"path": "/my-plugin.zip"
},
"options": { "activate": true }
}{
"step": "importWxr",
"file": {
"resource": "bundled",
"path": "/content/sample-content.wxr"
}
}Creating a Bundle Step by Step
Create the bundle directory and add
blueprint.jsonat its root.Write your plugin/theme source files in a subdirectory (e.g.
my-plugin/my-plugin.php).Zip the plugin directory:
zip -r my-plugin.zip my-plugin/Reference it in
blueprint.jsonusing{ "resource": "bundled", "path": "/my-plugin.zip" }.
Full example — a bundle that installs a custom plugin:
dashboard-widget-bundle/
├── blueprint.json
├── dashboard-widget.zip ← zip of dashboard-widget/
└── dashboard-widget/ ← plugin source (kept for editing)
└── dashboard-widget.php{
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
"landingPage": "/wp-admin/",
"preferredVersions": { "php": "8.3", "wp": "latest" },
"steps": [
{ "step": "login" },
{
"step": "installPlugin",
"pluginData": { "resource": "bundled", "path": "/dashboard-widget.zip" },
"options": { "activate": true }
}
]
}Distribution Formats
| Format | How to use |
|---|---|
| ZIP file (remote) | Website: https://playground.wordpress.net/?blueprint-url=https://example.com/bundle.zip |
| ZIP file (local) | CLI: npx @wp-playground/cli server --blueprint=./bundle.zip |
| Local directory | CLI: npx @wp-playground/cli server --blueprint=./my-bundle/ --blueprint-may-read-adjacent-files |
| Git repository directory | Point blueprint-url at a repo directory containing blueprint.json |
GOTCHA: Local directory bundles always need --blueprint-may-read-adjacent-files for the CLI to read bundled resources. Without it, any "resource": "bundled" reference will fail with a "File not found" error. ZIP bundles don't need this flag — all files are self-contained inside the archive.
Testing Blueprints
Inline Blueprints (quick test, no bundles)
Minify the blueprint JSON (no extra whitespace), encode it once with encodeURIComponent(), prepend https://playground.wordpress.net/#, and open the URL in a browser:
https://playground.wordpress.net/#%7B%22%24schema%22%3A%22https%3A%2F%2Fplayground.wordpress.net%2Fblueprint-schema.json%22%2C%22preferredVersions%22%3A%7B%22php%22%3A%228.3%22%2C%22wp%22%3A%22latest%22%7D%2C%22steps%22%3A%5B%7B%22step%22%3A%22login%22%7D%5D%7DVery large blueprints may exceed browser URL length limits; use the CLI or a hosted Blueprint URL instead. For share-link details, use wp-playground/references/website.md.
Local CLI Testing
Interactive server (keeps running, opens in browser):
# Directory bundle — requires --blueprint-may-read-adjacent-files
npx @wp-playground/cli server --blueprint=./my-bundle/ --blueprint-may-read-adjacent-files
# ZIP bundle — self-contained, no extra flags needed
npx @wp-playground/cli server --blueprint=./bundle.zipHeadless validation (runs blueprint and exits):
npx @wp-playground/cli run-blueprint --blueprint=./my-bundle/ --blueprint-may-read-adjacent-filesTesting with WordPress Playground
Use the wp-playground skill for local or browser testing. For CLI testing, follow wp-playground/references/cli.md with --blueprint=<path-or-url>; for directory bundles, pass --blueprint-may-read-adjacent-files.
Files
- ATTRIBUTION.mdAdded by AutoGineer882 B
- LICENSELicence file added by AutoGineer750 B
- SKILL.md15.8 KiB
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs Node.js
The author says: WordPress 7.0+, PHP 7.4.0+. Optionally Playground CLI or a browser
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- WordPress
- Publisher
- WordPress (Official)
- Source
- WordPress/agent-skills · skills/blueprint · commit 7374e6f
- Licence
- GNU General Public License v2.0 or later (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by WordPress or WordPress.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download blueprint.zip