From 2d0c4e635d8786df7c53da4486bf19e00bfc9817 Mon Sep 17 00:00:00 2001 From: Noel Tock Date: Tue, 15 Sep 2026 21:35:10 +0700 Subject: [PATCH 1/3] docs: simplify the first-use README --- README.md | 636 ++++++-------------------------------------- docs/development.md | 94 +++++++ docs/reference.md | 459 ++++++++++++++++++++++++++++++++ 3 files changed, 640 insertions(+), 549 deletions(-) create mode 100644 docs/development.md create mode 100644 docs/reference.md diff --git a/README.md b/README.md index 9a4504d..a37f01b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Block Runner -Convert authored HTML into native WordPress blocks, or generate a reusable registered block. +Turn HTML into editable WordPress blocks, or generate the source for a reusable registered block. [![npm version](https://img.shields.io/npm/v/block-runner.svg)](https://www.npmjs.com/package/block-runner) [![npm downloads](https://img.shields.io/npm/dm/block-runner.svg)](https://www.npmjs.com/package/block-runner) @@ -9,598 +9,136 @@ Convert authored HTML into native WordPress blocks, or generate a reusable regis ![Block Runner driven from Claude Code: preview the registered block, confirm, write it into the plugin](https://cdn.jsdelivr.net/gh/humanmade/block-runner@main/demo/demo.gif) -Block Runner converts authored design HTML into nested Gutenberg blocks and checks the result -against headless WordPress. It also generates static registered-block source from a reviewed -plan. Use it from a coding agent, a content pipeline, the CLI or the library. +Block Runner is an open-source CLI and JavaScript library from Human Made. It converts supported HTML into native Gutenberg blocks and checks the generated markup with the Gutenberg packages used by the WordPress editor. It can also generate a static registered block: source files you build into a plugin, with native editable blocks inside. -The package makes no model calls. An agent can interpret the design; deterministic code -assembles, generates and validates the result. Validation is not proof of visual fidelity or -compatibility with every WordPress installation. +**The package makes no AI model calls.** Built-in rules can convert HTML on their own. An external agent can interpret a design and give Block Runner a structured plan to assemble or compile. The optional skill provides instructions for that agent. ## Quickstart -```sh -npm install block-runner # requires Node.js ^20.19.0 || ^22.13.0 || >=24.0.0 -``` - -Convert a file to page-content blocks: +Requires Node.js **20.19.0+ on 20.x, 22.13.0+ on 22.x, or 24.0.0+**. Node 21 and 23 are unsupported. Basic conversion needs no AI agent, Docker or running WordPress site. ```sh -npx --no-install block-runner convert hero.html --out hero.blocks.html -# Use JSON to inspect warnings, source locations and fallback blocks. -npx --no-install block-runner convert hero.html --json +npm install block-runner +printf '

Hello WordPress

\n' > hello.html +npx --no-install block-runner convert hello.html ``` -For a reusable named block in code, use [registered-block authoring](#registered-block-authoring). -The standard install includes both workflows; Docker and browser tooling are needed only for -real-WordPress proof. - -## Using Block Runner from an AI agent +Output: -Install the bundled skill in your project: - -```sh -npx --no-install block-runner skill --install +```html + +

Hello WordPress

+ ``` -This writes `.agents/skills/block-runner` and `.claude/skills/block-runner`. The skill guides -project inspection, implementation choice, preview, confirmation and delivery. Then ask: - -> Use Block Runner to create a reusable block from this design in the existing plugin. - -For page content with no authored HTML, the agent should submit an intent tree to `assemble`. -For an existing HTML design, use `convert`. Neither page-content command creates registered -block source. - -Use `--scope user`, `--target agents|claude` or `--dir ` to choose installation -scope. Without `--install`, `npx --no-install block-runner skill` prints the guide without writing. - -## Benchmark - -![Historical HTML-to-block benchmark: five low-effort model lanes plus the deterministic rules engine, 63 HTML sections per lane; the adjacent caption gives invalid counts and timing method.](https://cdn.jsdelivr.net/gh/humanmade/block-runner@main/assets/benchmark.jpg) - -The image is **historical conversion evidence**, not an authoring result. Its workload is 63 -fixed HTML sections per lane (11 serial lanes, 693 conversions); the suite, models/low effort, -per-lane invalid counts, and monotonic serial timing method are labelled in the -[benchmark report](https://github.com/humanmade/block-runner/blob/main/dev/benchmarks/presentation/figures.html). Each model gets the same fixture in two -lanes: **Direct** writes Gutenberg markup itself; **Block Runner** returns an intent tree that the -package assembles and validates. The dashed line is the deterministic rules converter running -without an LLM. Every result is scored from 0 to 100 against the fixture's accepted block tree. - -The separate [registered-block authoring corpus](https://github.com/humanmade/block-runner/blob/main/dev/benchmarks/authoring/README.md) -remains unscored. This image does not measure generated plugins, editor persistence or authoring -quality. Required package and WordPress release proof are separate from either benchmark. - -## Capabilities and limits - -- Convert supported HTML structures into native blocks; unsupported structures become Custom - HTML with source-located warnings. -- Assemble an intent tree, validate existing block markup, or canonicalize near-miss markup. -- Resolve media through a supplied map, WP-CLI or REST; unresolved IDs remain warnings. -- Map styles to theme tokens or preserve supported off-theme CSS. -- Generate a static custom wrapper around native editable children, with reviewed locks and assets. - -Use authored markup, not scraped frontend HTML. Registered-block generation does not create -new PHP renderers, field-framework editors or arbitrary interaction code. For an existing project, -the [construction reference](skills/block-runner/references/CONSTRUCTION-PATTERNS.md) helps choose -between composition, extension and custom-block work without implying generator support. - -## CLI - -For a local installation, run these commands with `npx --no-install block-runner`. - -| Command | What it does | -| --- | --- | -| `convert` | Authored HTML to native post-content blocks, including the legacy styling path. | -| `author --json` | Analyze one authored design into a canonical registered-block plan, checked source, and style/asset ledgers. Does not write source. | -| `assemble` | An intent tree to native page-content blocks, assembled and validated by Gutenberg. | -| `author preview ` | Validate and render a versioned registered-block GeneratedAuthoringPlan without writing files. | -| `author write --confirm --output-dir ` | Write the reviewed compiler-owned source package bound to its SHA-256 confirmation and destination. Build and runtime proof remain separate. | -| `validate` | Check block markup against headless Gutenberg. | -| `fix` | Canonicalize near-miss block markup. | -| `context` | Read a WordPress site into a `site.context.json` manifest (read-only). | -| `proof` | Run a real-WordPress proof profile for a built plugin ZIP and write an immutable receipt. | -| `skill` | Print or install the agent guide. | -| `plugin inspect` | Read-only detection of the supported `@wordpress/scripts` plugin profile. | -| `plugin preview` / `plugin write` | Preview, confirm, and integrate a generated registered-block directory; or create a standalone plugin wrapper. | +This is Gutenberg page content, ready to paste into the editor's code view. To save the markup or inspect its warnings: ```sh -block-runner convert hero.html # blocks to stdout -block-runner author hero.html --name acme/hero --json -block-runner assemble intent.json # structure in, blocks out -block-runner validate "content/**/*.html" --json -block-runner fix post-content.html --out post-content.fixed.html - -# Inspect a host before integrating generated block files. This writes nothing. -block-runner plugin inspect ./my-plugin --json - -# Preview every exact target, then use the displayed fingerprint with `plugin write`. -block-runner plugin preview ./generated-block --host ./my-plugin - -# If a standalone plugin suits the project, preview that destination. -block-runner plugin preview ./generated-block --standalone ./my-notice-plugin +npx --no-install block-runner convert hello.html --out hello.blocks.html +npx --no-install block-runner convert hello.html --json ``` -`plugin preview` never writes. Its fingerprint binds the exact target files; pass it to -`plugin write --confirm `. Existing PHP or `package.json` files are marked as -separate replacement approvals, so their absolute preview paths must also be supplied with -`--approve-replace ` before they can change. An unrecognised host is refused without -writing. Retain the generated source for developer integration into the existing project, or -choose a standalone plugin if that suits the project. - -Standalone previews include the complete, versioned npm lock for their pinned local -`@wordpress/scripts` toolchain. Confirmed writes only materialize the reviewed source and lock -bytes: they do not resolve dependencies, contact a registry, or run npm. Run `npm ci` separately -when preparing the generated plugin to build or package it. - -### Registered-block authoring - -HTML analysis returns `package.canonicalPlan`, a versioned `GeneratedAuthoringPlan` containing -the target, native structure, fields, locks, style/asset decisions and warnings. Unresolved Custom -HTML, unsafe assets and unsupported CSS are failures, not a ready-to-install package. +The JSON report includes `ok`, block counts, warnings and source locations. Review it when converting a more complex design. The [shipped hero example](https://github.com/humanmade/block-runner/blob/main/examples/hero.html) is a larger input to explore. -Preview the plan before writing: +## Choose your workflow -```sh -block-runner author preview authoring-plan.json --output-dir generated/feature-grid -``` - -The preview shows the tree, files, warnings and a confirmation hash bound to the plan and -destination. It writes nothing and does not prompt. After explicit approval, pass that hash and -the same destination to `author write`. - -Missing or stale confirmation, changed destinations, unsafe paths and symlinks are refused. -Existing-file replacements require a separate decision. The compiler owns file content; -`files` can declare only its output paths and create/replace operations. - -### Complete source-to-build routes - -For the complete source-to-ZIP walkthrough, the route-specific confirmation boundaries, and the -source-only and existing-plugin alternatives, read [registered-block delivery](skills/block-runner/references/AUTHORING.md#shipped-notice-source-to-standalone-zip). -It is bundled with the installed skill, so it remains available without this checkout. - -The shipped [`authoring-plan.mjs`](examples/authoring-plan.mjs) is the executable notice plan used -by that walkthrough. After installation it is available at -`node_modules/block-runner/examples/authoring-plan.mjs`; it writes only JSON on success, so its -redirected output is the reviewed plan. The marked proposal example in the authoring reference -teaches the proposal API; it is a separate contract, not a replacement for the complete notice -route. - -All delivery routes begin with a reviewed `authoring-plan.json`; use `author --name - --json` when deterministic HTML analysis must produce its canonical plan. The -author confirmation binds that plan and source destination, while the separate `plugin preview` -fingerprint binds the wrapper or host destination. Missing or stale confirmation, changed -destinations, unsafe paths and symlinks are refused; existing-file replacements require separate -approval. Neither route requires hand-written React, PHP, block metadata, or a repair step. - -The detailed reference covers [standalone delivery](skills/block-runner/references/AUTHORING.md#standalone-plugin-output), -[recognised existing-plugin integration](skills/block-runner/references/AUTHORING.md#existing-plugin-output), -and [source-only developer integration](skills/block-runner/references/AUTHORING.md#source-for-an-existing-project-developer-integration). -Source delivery or a successful build is not WordPress runtime proof; use the applicable proof -profile with the reviewed ZIP, source, markup, and fixture before claiming activation, editing, -saved-content reopening, or frontend behavior. - -### WordPress proof requirements - -Headless validation is a fast first rung. A generated plugin needs a separate -real-WordPress proof before any claim that it activates, registers, edits, or -renders is credible. Before running, the proof report derives the required gates -from the selected claim and the hash-matched artifact contract rather than treating -every artifact as pattern-override-ready: - -| Claim / profile | What it establishes | Extra proof requirements | +| What you need | Use | Output | | --- | --- | --- | -| `generated` | Deterministic Gutenberg validation. | None; it does not start Docker. | -| `built` | ZIP installation, activation, and runtime registration. | Exact `wp-env`, Playwright, WordPress Playwright helpers, and Axe; Docker; an explicitly installed Chromium browser. | -| `editor-verified` | Built behavior plus insertion, declared editable fields, save, and reopen. | The runtime/editor toolchain. | -| `fidelity-checked` | Editor behavior plus frontend, visual, and automated accessibility checks. | The runtime/editor toolchain plus exact `pixelmatch` and `pngjs`. | -| `pattern-verified` | The two-instance pattern-override lifecycle. | A hash-matched artifact contract that declares `capabilities.patternOverrides: true` and its complete pattern fixture. | -| `full` | The exhaustive release-profile gate set. | All full-profile inputs, including pattern, visual, and manual-review evidence. | - -Library plus `convert`, `assemble`, `validate`, `fix`, `author`, `plugin`, `context`, -and `skill` need only Block Runner's production dependencies. WP-CLI remains an -external requirement only when selected for context, token, or media resolution. - -The browser-proof packages are exact optional peers, absent from a basic installation. -Install them only where real-WordPress proof will run. - -Set up the runtime/editor proof boundary before requesting `runtime` or `editor`: - -```sh -npm install --save-dev --save-exact \ - @wordpress/env@11.15.0 \ - @playwright/test@1.61.1 \ - @wordpress/e2e-test-utils-playwright@1.51.0 \ - axe-core@4.11.0 -npx --no-install playwright install chromium -``` - -The `full` profile adds the visual-proof pair: - -```sh -npm install --save-dev --save-exact pixelmatch@7.1.0 pngjs@7.0.0 -``` - -Proof never downloads tooling or browsers or calls a model. Missing or mismatched tooling blocks -the run before Docker starts and reports the required installation command. Runtime profiles -also require a working Docker daemon. - -```sh -block-runner proof dist/acme-hero.zip --profile full \ - --markup fixtures/hero.blocks.html --input fixtures/hero.source.html \ - --fixture fixtures/hero.proof.json --receipt-dir artifacts/proof -``` - -The fixture supplies editable fields, frontend expectations and reviewed visual/accessibility -inputs; pattern claims require a pattern fixture. Required failed, skipped, blocked or missing -gates fail the selected claim. Golden images are read-only inputs, never refreshed during proof. -Axe results are automated evidence, not complete accessibility certification or owner acceptance. - -The pinned environment and package hashes, runtime observations, logs and evidence objects are -retained in the receipt. See the [proof guide](skills/block-runner/references/AUTHORING.md#proof-is-part-of-completion) -and [release gate](https://github.com/humanmade/block-runner/blob/main/dev/release/0.9-testing/README.md) -for profile inputs, accepted upstream findings and release requirements. - -### Flags - -Page-content options (see each command's `--help`): - -| Flag | Description | -| --- | --- | -| `--config ` | Use a specific config file (otherwise auto-loaded from the working directory). | -| `--json` | Emit a machine-readable JSON report instead of text or markup. | -| `--strict` | Exit `1` on strict warnings (unresolved media, fallback blocks). | -| `--explain` | Include rule attribution and near-misses in the report. | - -`convert` and `fix` also take `--out ` to write the result to a file instead of stdout. - -`convert` adds styling flags: - -| Flag | Description | -| --- | --- | -| `--styling ` | Styling ceiling: `strict`, `relaxed` (default), `open`. See [Styling fidelity](#styling-fidelity). | -| `--css-out ` | Write the sidecar CSS emitted by `--styling open` to a file. | - -`convert` adds media-resolution flags: - -| Flag | Description | -| --- | --- | -| `--resolver ` | Media resolver: `noop`, `map`, `wpcli`, `rest`. | -| `--wp-url ` | WordPress URL for `wpcli` or `rest` resolution. | -| `--wp-user ` | WordPress username for `rest` resolution. | -| `--wp-app-password-env ` | Env var holding a WordPress application password. | - -`author --name --json` analyses exactly one design and returns a canonical -plan; it does not write source. Use `author preview` then the confirmed `author write` command to -materialize the compiler-owned package. Shared generated CSS is registered through `block.json`'s -`style` field, while `editorStyle` is reserved for explicitly supplied editor affordances. - -`skill --install` adds installation flags: - -| Flag | Description | -| --- | --- | -| `--scope project\|user` | Install for the current project (default) or the current user. | -| `--target all\|agents\|claude` | Install both discovery copies (default), only `.agents/skills`, or only `.claude/skills`. | -| `--dir ` | Install under one explicit skills directory; cannot be combined with `--scope` or `--target`. | -| `--dry-run` | Show resolved destinations without writing files. | -| `--force` | Replace locally changed or unmanaged files at canonical bundle paths. | - -Installed instructions pin runtime commands to the package version that installed them. To -update an installed skill after upgrading Block Runner, re-run -`npx --no-install block-runner skill --install`. Existing local edits are refused unless -`--force` is explicit. - -An installation made by 0.7.x predates the managed manifest, so the first upgrade is -deliberately refused as unmanaged. Review that copy, rerun once with `--force`, and remove the -preserved root-level `GUIDE.md` after confirming the new `references/GUIDE.md` copy. - -### Exit codes - -- `0`: clean -- `1`: problems found -- `2`: usage or I/O error -- `3`: headless Gutenberg boot failure +| Convert HTML using built-in rules | `convert` | Gutenberg markup for page content | +| Build page content from an agent's block tree | CLI `assemble` | Gutenberg markup, assembled and validated | +| Create a reusable named block from a design | `author` | A plan and generated block source; preview and confirm before writing | +| Check or repair existing block markup | `validate` / `fix` | A report or canonicalised markup | -## Run it anywhere +For straightforward HTML, start with `convert`. For a design that needs interpretation, an agent can choose the block structure and send it to CLI `assemble`. Both page-content routes finish with media resolution, theme-token handling and validation. Neither creates a registered block's source files. -Use the CLI in shell scripts, pre-commit hooks or CI. - -**pre-commit** (add to `.pre-commit-config.yaml`): +### Registered-block authoring -```yaml -- repo: https://github.com/humanmade/block-runner - rev: v0.9.1 - hooks: - - id: block-runner - args: ['content/**/*.html'] # glob of files that contain block markup -``` +Use `author` when the result should be a named block such as `acme/notice`, available for repeated insertion. Here, “authoring” means generating block source code. Block Runner can analyse HTML directly or accept an agent's source-linked proposal for the structure and editable fields. -**GitHub Actions** (or any CI) validate blocks on every push: - -```yaml -- uses: actions/setup-node@v4 - with: { node-version: 22.13.0 } -- run: npx block-runner validate "content/**/*.html" --strict -``` +The output is a static wrapper around native blocks, with block metadata, editor code, styles and assets. Source generation, plugin build and verification in WordPress are separate steps. Follow the [complete registered-block delivery guide](https://github.com/humanmade/block-runner/blob/main/skills/block-runner/references/AUTHORING.md#shipped-notice-source-to-standalone-zip), including the shipped notice example and destination-specific write confirmations. That guide is also bundled with the installed skill. ## Library -The library is ESM-only and requires Node.js ^20.19.0 || ^22.13.0 || >=24.0.0. This means -Node 20.19.0+ on the 20.x line, Node 22.13.0+ on the 22.x line, or Node 24.0.0+. Node 21 and -23 are intentionally unsupported. CommonJS callers should use -`await import('block-runner')` rather than `require('block-runner')`. - -```ts -import { canonicalize, convert, validate } from 'block-runner'; - -const validation = await validate(markup); -const fixed = await canonicalize(markup); -const converted = await convert(html, { resolver: 'noop' }); -``` - -### Registered-block authoring contract - -`GeneratedAuthoringPlan` is the public authoring contract at the preview/confirmation/write -boundary. `AuthoringPlan` remains the semantic input contract for existing consumers, with -`SemanticAuthoringPlan` available as its additive alias. HTML analysis (`author()`) and the -deprecated semantic `compileAuthoringPlan()` adapt that contract; their returned `canonicalPlan` -is a `GeneratedAuthoringPlan` that consumers review and write. - -For HTML authoring, the primary path first calls `collectSourceEvidence()` and then sends -`AuthorOptions.proposal`: an ordered native structure with the returned `sourceRef`s, editor -fields/locks, and reviewed source decisions. Block Runner owns exact source hashes/content coverage, -assets, native style adapters, CSS coverage, and mandatory warnings before returning the canonical -plan. Inspection/validation need no consent; only the final canonical write identity does. Existing -complete `AuthorOptions.plan` callers remain supported as an advanced compatibility route. -The runnable [authoring example](examples/authoring-plan.mjs) derives a canonical plan from -HTML and a semantic proposal using only public imports. From a project with Block Runner installed: - -```sh -node node_modules/block-runner/examples/authoring-plan.mjs > notice.plan.json -npx --no-install block-runner author preview notice.plan.json --output-dir generated/notice -# Review the complete preview and approve its destination-bound confirmation hash. -npx --no-install block-runner author write notice.plan.json \ - --confirm '' --output-dir generated/notice -``` - -The example emits JSON only. The CLI supplies the same destination-bound preview and write checks -used by other plans; the plan hash alone is not a write confirmation. Continue with either plugin -packaging route above. - -#### Regeneration and saved content - -Compiler-owned output is only replaced after the destination-bound preview marks each replacement -and its confirmation is supplied. An unchanged package is a no-op. Preview classifies a replacement -as content-defaults, style-only, or saved-markup/structure. Style and asset changes can alter -rendered appearance, but do not migrate saved block markup. Updated editor defaults apply to new -insertions; existing saved content remains its own content record, though changed editor code can alter its editing experience. - -A same-identity change to saved markup, registration identity, or attribute schema is refused. -Use a new block identity, or add a tested WordPress deprecation/migration before replacing it. -Block Runner does not edit a site's database, templates, or posts. Synced-pattern canonical updates -are separate site operations and source changes make no sitewide propagation claim. Direct insertion, -synced-pattern use, and plugin deactivation each need their own WordPress acceptance proof. Generated -packages are static WordPress source and contain no Block Runner runtime dependency. - -| Supported entry point | Compatibility boundary | -| --- | --- | -| `GeneratedAuthoringPlan`, `validateAuthoringPlan`, `hashAuthoringPlan`, `renderAuthoringPreview`, `planRegisteredBlockOutput`, `compileRegisteredBlock`, destination inspection/write helpers | Supported v1 confirmation contract. The canonical hash is its sole plan identity. | -| `AuthoringPlan` / `SemanticAuthoringPlan`, `author()` and `compileAuthoringPlan()` / `compileAuthoringBlock()` | Supported semantic adapters. They return a `GeneratedAuthoringPlan`; semantic input is not a second preview/write contract. The compile names are deprecated through 1.x. | -| `generateRegisteredBlock`, `materializeAuthoringPlan` | Deprecated compatibility aliases through 1.x. Migrate to `compileRegisteredBlock`; no runtime behaviour changes. | -| `emit*`, `validateBlockMetadata`, generated-source and destination primitives | Advanced/internal-facing helpers. | -| `convert`, `assemble`, `validate`, `fix`/`canonicalize`, `extractIntent`, `realize` | Existing page-content APIs, unchanged and outside registered-block authoring. | - -`target.metadata` carries hash-bound native `block.json` metadata without forcing a reduced -vendor schema at plan parsing time. The static compiler validates capabilities: executable keys -and string `metadata.variations` PHP-file references fail with a precise compilation error. -Inline declarative variation records and safe native metadata pass through unchanged. - -Pass a `GeneratedAuthoringPlan` to `compileRegisteredBlock`. Adapt legacy semantic plans first; -they are not a second confirmation contract. No page-content API is renamed or removed. - -## Synced-pattern overrides (WordPress 7.1) - -Generated wrappers can expose supported native child fields as synced-pattern overrides through -reviewed `fields` and `pattern.overrides`. Layout remains the canonical InnerBlocks template; -the compiler does not bind or synthesize `innerBlocks`. Generic Block Bindings are not supported. - -The full proof checks two instances, save/reopen, canonical updates, reset, structural policy, -a missing-binding negative and frontend output. Use a built plugin ZIP and the reviewed fixture, -visual and accessibility inputs described under [proof requirements](#wordpress-proof-requirements). - -These are checks of the supplied artifact, not a human judgement of visual fidelity, editing -feel or accessibility. - -### Testing workflow - -For ordinary changes, run the focused affected tests first: +The library is ESM-only. Save this as `hello.mjs` in the project where you installed Block Runner, then run `node hello.mjs`: -```sh -npx vitest run -``` - -For changes to proof startup or publication recovery, run: +```js +import { convert } from 'block-runner'; -```sh -npx vitest run dev/test/proof-control-setup.test.ts dev/test/proof.test.ts dev/test/publication.test.ts dev/test/publication.public-api.test.ts -npm run typecheck +const result = await convert('

Hello WordPress

'); +console.log(result.output); +console.log(result.items); // Warnings and validation findings; empty for this input. ``` -`npm run verify` remains the required repository gate. It runs the deterministic repository -suite. Pull requests that change only the root documentation allowlist or the shipped skill use -their focused CI contracts; runtime, package, proof, workflow, release, unknown, and main-branch -changes retain the full route. Run `npm run test:consumer` separately to build the clean standalone release archive and -the native style-adapter fixture; it needs npm, `unzip`, and enough time for an isolated -`npm ci` and two ZIP builds. Run `npm run build && npm run test:package` -when changing exports, packed files, dependency pins, or consumer behavior. The full CI and -release matrix run both repository and consumer suites. Run -`npm run test:proof:wordpress` for proof-runner, browser, emitted-editor layout, persistence, -or pattern changes; it requires Docker. Run the opt-in `npm run test:proof:mutations` only when -detector wiring changes, and run the existing release check only for release candidates or release -automation. Do not relax the visible mutation skips, runtime-proof gates, thresholds, or the -intentional `fileParallelism: false` Gutenberg serialization. - -The consumer suite owns these archive assertions: `standalone consumer release archive > resolves, -clean-installs, builds, and inspects the actual release archive` in -`plugin.consumer.test.ts`, and `native style adapter proof fixture > retains and pins the public -utility hero package with authored image sizing` in -`proof-native-style-adapter-builder.test.ts`. - -## Media Resolution - -Media resolution connects source image URLs to WordPress attachment IDs: - -- `noop`: leave URLs as-is and warn when an ID is missing (good for a dry run). -- `map`: look up IDs and URLs from a JSON map you provide. -- `wpcli`: find or import media with `wp media list` and `wp media import`. -- `rest`: find or import via the WordPress REST API, with credentials supplied explicitly. +`convert` returns the same report used by the CLI. For an intent JSON string, use `realize` to get the complete assembly and validation report. The lower-level library `assemble` only builds Gutenberg objects; it does not run that full workflow. See the [API reference](https://github.com/humanmade/block-runner/blob/main/docs/reference.md#library) for validation, registered-block generation and compatibility contracts. -Remote sideloading is off by default. Under `--strict`, unresolved media (and fallback blocks) -cause exit code `1`. +CommonJS callers can use `await import('block-runner')`. -## Configuration - -Block Runner auto-loads `block-runner.config.{mjs,js,json}` from the working -directory, so most runs need no flags; the config sets the media resolver, tokens, -and rules. Pass `--config ` only to point at a config elsewhere. - -`block-runner.config.mjs`: - -```js -export default { - strict: false, - media: { - resolver: 'map', - mapFile: './media-map.json', - }, - tokens: { - colors: { - dark: 'contrast', - light: 'base', - accent: 'accent', - }, - fonts: { - heading: 'display', - body: 'body', - }, - spacing: ['20', '30', '40', '50', '60'], - }, -}; -``` - -## Site context from Wesper +## Using Block Runner from an AI agent -Supply a full Wesper manifest as a token source for conversion or canonicalisation: +Install the bundled skill in your project: ```sh -block-runner convert '

Hello

' --context site.context.json +npx --no-install block-runner skill --install ``` -The resolver prefers Wesper 0.0.3's `theme.tokens.presets`: collected colour, font-family, -font-size and spacing values map to the matching WordPress preset category and slug. -An explicitly empty registry stays empty; it does not fall back to old settings. Manifests -without this registry retain the legacy `theme.settings` route. Malformed context yields no -resolved tokens, following the existing resolver contract. This mapping does not attest the -manifest's source hash or turn partial collection into complete site compatibility evidence. - -Wesper's `focusContext()` output is a derived view, not a manifest for `--context`. Callers can -map its selected tokens into `config.tokens.colors`, `fonts`, `fontSizes` and `spacing` for -the library API. Registered-block authoring separately accepts an explicit theme settings -snapshot at `author.styles.context.theme.settings`; `--context` does not populate that snapshot -or import binding permissions. Use Wesper's validation and compatibility helpers in the calling -harness when those checks are needed. - -The bundled `context` command uses the pinned Wesper 0.0.3 WP-CLI collector. Its manifests -provide the native preset registry consumed by the resolver above. - -## Styling fidelity +This writes `.agents/skills/block-runner` and `.claude/skills/block-runner`. Then ask your agent: -The styling ceiling controls how conversion handles CSS that does not match the target theme: - -| Level | What it does | -|---|---| -| `strict` | Map to theme presets; report dropped off-theme styles. | -| `relaxed` | Keep supported off-theme values as native block attributes. | -| `open` | Also emit supported residual CSS as a sidecar stylesheet to ship alongside the blocks. | -| `source` | Reserved; not implemented. Requests are rejected. | - -You set one ceiling. Per block, Block Runner uses the **strictest level that still -captures the design**, and never goes past your ceiling. Configure it in -`block-runner.config.mjs`, or per run with `--styling`: +> Use Block Runner to create a reusable block from this design in the existing plugin. -```js -export default { styling: 'relaxed' }; // the default -``` +Your agent interprets the design and runs the tools. The package handles conversion, generation and validation. Installing the skill does not add a model or require an API key for Block Runner. -Styling is read from inline `style` attributes and from single-class `