npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wndrfl/wonderpress-cli

v2.14.2

Published

CLI for Wonderpress: bootstrap WordPress environments and author themes from manifests.

Readme

Wonderpress CLI

Command-line tooling for Wonderpress: a WordPress theme development environment with a manifest-first authoring model.

The CLI bootstraps a local environment, scaffolds partials / blocks / page templates, keeps generated code in sync with manifests, and exposes the same operations to agents over MCP.

npm install -g @wndrfl/wonderpress-cli

Requires Node.js 24+.


Contents


What it does

Wonderpress treats a partial as the unit of markup: a PHP class, a view, and a JSON manifest. A Gutenberg block is an optional thin wrapper whose render.php delegates back to that partial. Page templates compose partials and record editor locks in their own manifests.

The CLI is the only supported way to create and maintain that graph. Interactive wizards exist for humans; every command also runs headless for scripts and agents.

The CLI documents itself:

wonderpress                  # command map
wonderpress partial help     # authoring model
wonderpress init help        # environment backends and flags

Requirements

| Tool | Notes | | --- | --- | | Node.js >= 24 | Native install for the machine architecture (avoid Rosetta Node on Apple Silicon). | | WP-CLI (wp) | On PATH. | | PHP and Composer | On PATH. Used at init and by wonderpress lint. | | MySQL or Docker | host backend needs a running MySQL. wp-env needs Docker Desktop. |

wp-env replaces local MySQL, not the PHP toolchain. Both backends still need wp, php, and composer.


Installation

npm install -g @wndrfl/wonderpress-cli
wonderpress version

Package: @wndrfl/wonderpress-cli


Quick start

Installing the CLI is not the same as knowing the order of work. docs/getting-started.md is the narrative: build the environment, set the block namespace, wire design tokens, then author partials.

wonderpress init --dir ~/projects/acme --env wp-env --namespace acme --theme acme --yes

--namespace is written into page content as <namespace>/<slug>. Change it later and existing blocks become unrecognized. Pin it to the client name at init; it is recorded in .wonderpressrc and does not drift.

On wp-env, the site is serving when init finishes. On host, start it with wonderpress server.


Command reference

Global options used across many commands:

| Flag | Description | | --- | --- | | --dir <path> | Environment root (default: current directory, or the detected project root). | | --theme <name> | Target a theme by slug instead of the active lookup. | | --env <backend> | host (default) or wp-env. Needed at init; later commands read .wonderpressrc. Override per invocation with WONDERPRESS_ENV. | | --format json | Structured { ok, data, error } envelope. Unknown values are refused. | | -h, --help | Help for the current command (same as wonderpress <command> help). |

Exit codes: 0 success, 1 failure, 2 usage (ambiguous theme, bad flags, and similar).

Environment

wonderpress init

Clones the development environment, downloads WordPress, creates the database, installs theme Composer dependencies (including wonderpress-core) and Static Kit, and activates the theme.

| Flag | Description | | --- | --- | | --yes, -y | Headless: take defaults, never prompt. | | --env <host\|wp-env> | Backend. Recorded in .wonderpressrc. | | --dir <path> | Where to build (default: cwd). | | --theme <name> | Theme to activate (default: wonderpress). | | --namespace <slug> | Block namespace. Defaults to the theme slug. Set once. | | --db-host, --db-user, --db-name, --db-password | Database. Host backend only. Password may come from WP_DB_PASSWORD. | | --wp-url <url> | Site URL. Host backend only. | | --wp-title <title> | Site title. | | --admin-user, --admin-email, --admin-password | First administrator. Password may come from WP_ADMIN_PASSWORD. --admin-user is refused on wp-env (the first user is always admin). | | --skip-readme | Do not generate a project README. |

wonderpress init --yes --db-user root --db-name my_site \
  --wp-url localhost:8080 --wp-title "My Site" \
  --admin-user admin --admin-email [email protected]

wonderpress init --env wp-env --yes --wp-title "My Site"

The wp-env backend cannot honor --db-* or --wp-url. Drop those flags, or use host.

wonderpress server / wonderpress server stop

Start or stop the local site for the backend this project was built with. Bare wonderpress server means start. On host, start blocks in the foreground until Ctrl-C.

wonderpress destroy

Tear the environment down (database / containers) while keeping the theme and project files.

wonderpress lint [-f, --fix]

Runs PHPCS against the Wonderpress coding standards, partial check-drift, and template validate. --fix runs phpcbf on lightweight PHPCS issues; it does not repair drift — use wonderpress partial sync for that — and it does not edit page-template manifests or PHP.

--axe and --budget are reserved and currently skipped.

wonderpress acf install [--free]

Downloads and activates ACF directly from its official distribution. ACF PRO is the default because WonderPress repeater fields require it:

ACF_PRO_LICENSE=... wonderpress acf install

The key is read only from the environment; it is not accepted as an argument, written to the project, or passed to WP-CLI. Use --free to install the latest free edition from https://www.advancedcustomfields.com/latest/. Add --force to download and reinstall an edition that is already present.

This installs and activates the plugin but does not persist the PRO license for updates. Configure ACF_PRO_LICENSE in wp-config.php or activate it in the ACF admin.

wonderpress version

Print the installed CLI version.


Authoring

A partial is a rendering primitive (button, section, quote). It is not a Gutenberg block. A block is definitionally a wrapper over a partial: it cannot exist without one. A partial does not need a block.

wonderpress partial create

Scaffolds a PHP class, view template, agent-readable manifest, and a delegated Static Kit style stub.

| Flag | Description | | --- | --- | | --name <Class_Name> | PHP class name. Positional name works too (partial create Hero). Omit both for the wizard. | | --json <@file\|string> | Create from a JSON spec instead of flags. | | --prop <name:type[:required]> | Property (repeatable). Types: string, boolean, image, link, repeater, array, object. | | --sub <parent:name:type[:required]> | Repeater sub-field (repeatable). | | --acf | Mark ACF-compatible. Core registers a field group from the manifest when ACF is present. Cannot combine with --no-manifest. | | --block | Also emit a Gutenberg wrapper (block.json + a render.php that delegates to the partial). | | --js | Also scaffold a JS behavior class (delegated to Static Kit). Most partials have no behavior. | | --template-name <name.php> | View template filename. | | --no-template | Skip the view. | | --no-style | Skip the SCSS stub. | | --no-manifest | Skip the manifest. Cannot combine with --block or --acf. |

--block --no-manifest and --acf --no-manifest are refused. --js --no-template emits no behavior class. --block and --acf may be combined: the block uses Gutenberg attributes; the PHP caller uses ACF. Do not locate the ACF group on a page that also inserts the block.

wonderpress partial create --name Testimonial --prop quote:string:required
wonderpress partial create --name Hero --block --js
wonderpress partial create --name Testimonials --acf \
  --prop items:repeater --sub items:quote:string:required

wonderpress partial list

List every partial (name, slug, wrapping block if any). Indexed from .wonderpress/manifest/partials/*.json.

wonderpress partial sync [<Name>]

Regenerate class $properties and block.json from the manifest after editing properties in JSON.

| Flag | Description | | --- | --- | | --all | Sync every partial in the theme. | | --slug <slug> | Address by slug instead of class name. | | --dry-run | Print what would be written. | | --properties-only | Update class + block.json only (skip render.php). |

wonderpress partial check-drift [<Name>]

Fail if class or block.json has drifted from the manifest. Use in CI; repair with partial sync. Supports --all and --format json.

wonderpress partial add-js [<Name>]

Scaffold a JS behavior class onto an existing partial that already has a view and no script. With no name, pick from eligible partials. The file is not auto-imported; wire it from the page JS entry that renders the partial.

wonderpress partial remove [<Name>]

Remove a partial and every artifact its manifest records (class, view, style, behavior), then the manifest. Accepts a class name (Call_To_Action) or slug (call-to-action).

If a block wraps the partial, removal is refused — run wonderpress block remove first, or pass --with-block.

wonderpress partial install-manifest <slug>

Copy a core primitive manifest (for example link) into .wonderpress/manifest/partials/.

wonderpress block create [<Name>]

Add a Gutenberg wrapper to an existing partial. Output matches partial create --block. If no partial exists, create it with --block rather than scaffolding an empty one. With no name, pick from partials that do not yet have a block.

wonderpress block list / wonderpress block remove [<Name>]

List blocks and the partials behind them. Remove deletes the block directory and strips it from the manifest; the partial is left intact.

Blocks register under the Wonderpress editor category via wonderpress-core. If a new block is missing, run composer install in the theme directory.

wonderpress template create

Create a custom page template, a matching .wonderpress/manifest/page-templates/*.json (schemaVersion 1), and Static Kit page assets. --section rows become real PHP render() calls. After create, keep going in that PHP file and the manifest together (see AGENTS.md).

| Flag | Description | | --- | --- | | --name <Name> | Template name (e.g. Landing → template-landing.php). | | --lock <all\|insert\|false> | Editor lock. | | --section <id:partial> | Composition row, repeatable (e.g. hero-main:landing-hero). |

wonderpress template list / wonderpress template remove [<Name>]

List templates under .wonderpress/manifest/page-templates/. Remove deletes the PHP file, manifest, and delegated Static Kit JS/SCSS (pass --no-static to keep static files).

wonderpress template validate [<Name>]

Check every page-template manifest (or one by name). Reports invalid composition — unknown partials, duplicate ids, bad property types — and rows the template PHP does not render. A partial row needs wonder_partial_props( 'slug', 'id' ). A fields row needs wonder_template_composition_field( 'id' ). wonderpress lint runs the same check. Commented-out examples in the scaffold are ignored.

wonderpress static compile

Compile the active theme’s Static Kit tree (wp-content/themes/<theme>/static) from the environment root. Static Kit still owns that directory; this is a proxy so you do not cd into it.

| Flag | Description | | --- | --- | | --watch | Recompile on change (foreground). Cannot be combined with --format json. | | --theme <name> | Theme slug when WordPress is not reachable. |

Not an MCP tool.


Agents and MCP

wonderpress agents write

Writes AGENTS.md at the environment root (conventions plus live manifests), a one-line CLAUDE.md that points at it, and MCP host configs:

  • .mcp.json
  • .cursor/mcp.json
  • .vscode/mcp.json
  • .codex/config.toml

Regenerated after init, partial create / sync, and template create. Do not hand-edit the generated AGENTS.md index.

MCP configs pin this machine’s Node binary and CLI path, so they are gitignored (agents write adds the ignore rules). AGENTS.md and CLAUDE.md are committed.

An existing wonderpress MCP entry is left alone so hosts do not re-prompt for approval. Pass --force after switching Node versions or moving the checkout. The first write of a host config prints how to enable it.

wonderpress mcp

Starts an MCP stdio server in this package. Tools call the same operations as the CLI (partial_list, partial_create, partial_sync, lint_theme, and so on). init, destroy, server, acf install, and static compile are not tools. See wonderpress mcp help.

wonderpress readme create

Wizard (or flags) to generate a project README.

| Flag | Description | | --- | --- | | --project-name, --project-description | Identity. | | --github-url, --production-url, --stage-url, --dev-url | Links. |


Machine-readable output

--format json prints an envelope suitable for scripts and MCP:

{ "ok": true, "data": {}, "error": null }

Supported on version, lint, acf install, static compile (not --watch), partial list, partial check-drift, partial sync --dry-run, and agents write. Human output remains the default.


Architecture

Wonderpress consumes Static Kit as a dependency and delegates everything under the theme’s static/ directory to it. Static Kit’s node_modules is installed by the CLI and is never committed. The theme’s Composer vendor/ is committed: it is runtime PHP the site cannot serve without.

The ownership contract — CLI, Static Kit, and wonderpress-core — is in ARCHITECTURE.md.


Further reading

| Document | Purpose | | --- | --- | | docs/getting-started.md | Order of work and irreversible decisions | | docs/manifest-first-partials.md | Why manifests own generated PHP and block.json | | docs/property-value-shapes.md | Property types and values | | docs/static-kit-conventions.md | Tokens, SCSS, and theme.json |

Issues: github.com/wndrfl/wonderpress-cli


License

MIT © Wonderful — see LICENSE. PHP templates in src/templates/ that emit WordPress PHP are GPL-2.0-or-later.