- Establish the stable public CLI and library compatibility baseline. Future breaking changes require a major release.
- Make visual finishing the default agent-skill workflow for rendered delivery: compare desktop and mobile, correct authored source, regenerate through the existing gate, and verify native edit/save/reopen.
- Keep source-only work, unavailable render targets and explicit skips deliverable with clear verification gaps. A clean first comparison requires no correction loop.
- Include reproducible visual-review fixtures and retained native editing evidence.
- Refresh the Gutenberg, React, validation, browser and build toolchains, plus generated-plugin dependencies.
- Require security-patched Node releases (^22.23.4 || ^24.22.1 || >=26.12.1) and target WordPress 7.1.3 for release proof.
- Add block-theme folder validation, in-place markup repair, WordPress 7.1 theme.json schema checks and local part/pattern/preset references.
- Align native attribute order with WordPress server definitions; send unknown-block warnings to stderr and preserve native Accordion icon placement.
- Compile caller-authored whole-site intent into a local block theme and page bundle, with explicit media, font and synced-pattern bindings.
- Add source/target-bound site planning, confirmed owned apply with durable journals, read-only drift and staged pull of saved template/part edits. Theme deployment and activation remain separate.
- Add mounted-editor theme save proof and controlled whole-site proof. Save persistence does not establish visual fidelity.
- Update Wesper to 0.5.0 and require Node.js ^22.13.0 || >=24.0.0, dropping Node 20 support.
- Preserve unmanaged page fields and native publication dates on apply, allow pending first-install pattern media, canonicalise site identity and reduce repeated compilation, snapshots and source scans.
- Document current theme/site routes and guarded manual interrupted-apply recovery; remove the public proof failure-seeding option and fixed five-page fixture requirement.
- Remove redundant tests and run benchmark/evidence tooling separately, with required CI and release coverage.
- Clarify native intent styling versus HTML/CSS conversion, with runnable native-attribute, headerless-table and sequential library examples. Verified theme layout contracts can override generic block-mapping defaults.
- Warn when the native block constructor discards explicitly supplied intent attributes, including the attribute key and input path without raw values. Warnings remain informational in strict mode.
- Preserve nested lists inside intent list items.
- Reject malformed intent nodes, children, list items and table cells with input-located errors instead of returning partial content.
- Reject unregistered intent block names in normal and strict mode. This changes the previous warning-only behavior:
realizereturns a failed report with empty output, and low-levelassemblerejects. Registering custom block types remains outside the public API.
- Reject inline content inside synced-pattern references before serialization can discard it. Failed repairs preserve the original markup, and both conversion and assembly reject malformed references before emitting output.
- Explain shared pattern definitions, named instance overrides and explicit detachment in the agent guide.
- Add native Tabs assembly and WordPress editor/frontend regression coverage, including persistence, independent instances and keyboard behaviour.
- Add a development compatibility suite for generated blocks across WordPress 7.1, 7.1.2 and WordPress 7.1.2 with Gutenberg 24.0.0.
- Clarify native-block support and proof boundaries, and correct Accordion's first WordPress release to 6.9.
- Allow compatible versions of optional proof tooling so existing project dependencies do not block installation. WordPress proof still requires the exact tested toolchain.
- Update the pinned Gutenberg packages together, fixing the reported
author()crash in projects using@wordpress/blocks16.0.0. - Clarify the README, architecture and command reference, and add a worked custom conversion rule example.
- Update Wesper to 0.4.1, retaining compatibility with optional ownership and taxonomy evidence and partial collection warnings.
- Reuse WordPress between sequential proof cases while retaining each artifact installation and browser check.
- Run focused CI checks for allowlisted documentation and demo updates pushed to main.
- Point the package homepage to the Block Runner website on Accelerate.
- Update the README demo to show Block Runner driven from Claude Code.
- Patch colour and ZIP dependencies, including the lockfile shipped with generated plugins.
- Update Vitest and WordPress environment tooling, with matching proof pins and setup instructions.
- Clarify button-width and colour attributes in the assembly guide.
- Require generated page markup in the reply when no delivery destination is agreed.
- Route the agent skill by requested artifact before loading detailed instructions, and split page assembly, registered-block authoring and advanced plan references.
- Consolidate the complete registered-block delivery walkthrough in the shipped authoring guide.
- Limit the page-intent benchmark engine to its page references and bind its cache identity to the exact instructions used; no new model benchmark result is claimed.
- Add acceptance coverage for project-owned custom-block development without expanding the static generator's supported output.
- Separate clean consumer archive tests from the default repository suite while retaining them in CI and release checks, and reuse the proof-enabled package consumer for dependency checks.
- Select conservative documentation, skill and full CI routes; run the classifier regression tests on every route, retain complete diff history, and serialize shared Query Loop wp-env calls.
CLI and library contracts, runtime dependencies, and generated-block templates are unchanged.
- Distinguish generated-markup diagnostic locations from authored input and show diagnostic codes, stages and repair actions in text reports.
- Preserve authored heading anchors and detect lost or ambiguous local fragment targets during source-bound authoring.
- Extend the shipped notice example through standalone packaging and ZIP validation.
- Add focused native Query Loop assembly and WordPress save/reopen, pagination and empty-result proof, with retained CI command and browser receipts.
- Check clean editor reopening and exercise declared fields through visible native controls.
- Shorten skill routing and support continuing custom renderer/editor work in ordinary project-owned source when the static generator does not fit. This does not add dynamic-block generation to the compiler.
- Offer source delivery for developer integration when automatic host integration is unsupported; retain standalone plugin packaging as an alternative.
- Guide implementation choices through composition, extension and custom-block contracts, including field frameworks and combined save/render behavior, without expanding generator support.
- Shorten the README and clarify installation, supported behavior and proof boundaries.
-
Add a concise construction reference to the agent skill, with examples for persistence, existing block mechanisms, dependency ownership, and integration wiring.
-
Link project discovery to the reference and remove duplicated guidance.
-
Correct the guide to describe registered-block authoring as released in 0.9.0.
-
Allow the release receipt validator to accept 0.9 patch versions.
CLI and library behavior are unchanged.
0.9.0 is the public release on npm's latest tag. The release workflow runs the required
receipt-backed matrix before publication. The optional registered-block authoring benchmark remains
separate from deterministic release acceptance, and no new model benchmark result is claimed here.
-
Project-aware skill routing. The shipped skill now begins registered-block work by inspecting the relevant project source, local instructions, working-tree changes, and available site context before recommending a supported route.
-
Adaptive discovery questions. The skill reuses facts already established by the request and repository, then asks only for unresolved editorial, ownership, or delivery choices.
-
Source-only developer handoff. For an unsupported existing host, the skill can deliver retained generated source with source-backed editor, PHP registration, build, asset, and remaining verification handoff details. It does not claim integration, build, or WordPress proof.
-
Source-bound semantic proposals. For authored HTML, call
collectSourceEvidence()and submitAuthorOptions.proposalwith native structure, source references and editing decisions. Block Runner derives the canonical plan, content and CSS coverage, asset hashes, and required warnings. CompleteAuthorOptions.planinput remains an advanced compatibility route. -
Source-content preservation. Missing, duplicated or stale source bindings are rejected. Intentional additions, replacements and omissions require explicit source decisions. Diagnostics identify the source location and incompatible native relationship to correct.
-
Native style adapters. Authored button styles target the native link rather than its wrapper; image sizing retains source dimensions as aspect-ratio evidence. Supported authored grids use native Groups, with grid-item placement retained as scoped CSS. Source canvases and vertical spacing are preserved without changing existing saved block markup.
-
Registered-block authoring. A versioned
GeneratedAuthoringPlancan be reviewed in a deterministic terminal preview and compiled into one static registered block whose content remains native WordPressInnerBlocks. The preview is read-only;author write --confirmbinds the canonical plan, compiler contract, and destination fingerprint before publishing source. -
Authored HTML analysis.
author <html> --name <namespace/slug> --jsonanalyses one authored design and returns a canonical plan plus style and asset ledgers. It does not write source or turn an unresolvedcore/htmlregion into a registered-block substitute. -
Plugin output workflow.
plugin inspect,plugin preview, andplugin writeinspect a recognised@wordpress/scriptshost or plan/write a standalone plugin wrapper. Existing files require explicit replacement approval. -
Target metadata. Standalone generated plugins declare the observed compatibility floor: WordPress 7.1 and PHP 7.4.
-
Destination-aware source transport. The compiler carries confirmed native styles, scoped declarative CSS, and hash-verified local PNG/JPEG/GIF/WebP/static-SVG assets. Native SVGs use an owned URL helper so the built asset remains a real file rather than a data URL stripped on a WordPress save.
-
Bound source identity and editing policy. Authored source hashes and style/asset coverage flow into the canonical plan, generated files, and manifest. Fixed fields use Gutenberg's native block-level
lock.edit: true; mixed fixed/editable fields on one native node are refused. This is an editor policy, not an immutable-content or security guarantee. -
Licensed local font transport. Only local WOFF/WOFF2 files with an explicit source, SHA-256, ownership/license decision, and optional redistribution notice are bundled. Faces are namespaced in shared editor/frontend CSS; unlicensed or unsupported faces fall back safely with a source-located warning. Full font notices are retained as a separate text file in production archives, including when adding the block to a supported existing plugin.
-
Pattern-override path. Native Heading/Paragraph/List Item/Image/Button fields can be marked for the WordPress 7.1 pattern-override flow through the generated plan. Generic Block Bindings, dynamic PHP, and frontend interaction code remain outside this release's contract.
-
Release proof and benchmark contracts. Separate receipts cover package, skill, generated plugin activation, WordPress editor/frontend lifecycle, pattern behavior, visual evidence, and accessibility. The registered-block authoring suite is independent of the historical HTML-to-page-block benchmark; model/tool failures are invalid measurements, never zero scores.
-
Recoverable build cleanup.
npm run buildmoves this checkout's existingdist/to macOS Trash (or~/.Trashwhen thetrashCLI is unavailable) before runningtsupwith cleanup disabled. The guard refuses target arguments and cannot silently delete another path.
- Node.js compatibility decision. Block Runner now explicitly supports Node.js
^20.19.0 || ^22.13.0 || >=24.0.0, rather than broadly advertising>=20. This retains the Node 20 release line by pinning Commander to 14.0.3, but raises its minimum patch release to 20.19.0 because the resolved jsdom and WordPress production dependencies require it. Node 21 and 23 are not supported by that graph. CI installs the lockfile and packed tarball with engine-strict at each exact floor. - The public authoring example now runs directly with Node and emits a source-bound canonical plan for the CLI's destination-confirmed preview/write workflow. The short skill now describes capability-specific proof requirements consistently with the detailed guide.
- The context token resolver consumes Wesper 0.0.3's normalized native preset registry instead of reparsing potentially different raw settings. An explicit empty registry is authoritative; older settings-only manifests remain supported. The bundled collector now pins published Wesper 0.0.3.
- Owner-acceptance preparation now uses explicit semantic proposals, a bounded sibling-asset root for its SVG, and a recorded component-containment decision for its reduced-motion CSS. The packed-consumer smoke checks both inputs through analysis, preview, and source generation.
- Grid-item
grid-column,grid-rowandgrid-areadeclarations are no longer mistaken for unsupported grid-container settings. Unsupported container behavior still fails closed. - The package private-reference checker finds the npm pack record after lifecycle/build output instead of treating an earlier JSON build message as the package manifest.
Release evidence is artifact-bound: historical CI, WordPress fixture, ZIP, and mutation evidence remains attached to its own revision and artifact. Automated proof establishes only its named artifact and claim; it is not a human accessibility certification or owner-acceptance record. Prepared-but-unrun owner-acceptance inputs retain the required visual, editing-feel, and manual-accessibility decisions. The separate registered-block benchmark remains pending and unscored; no new model benchmark result is claimed here.
- Updated the bundled Gutenberg runtime to the WordPress 7.1 package releases.
- The bundled agent skill is now canonical and cross-harness. Its source lives at
skills/block-runner/, where the directory matches the frontmatter name, with the detailed guide underreferences/.skill --installcopies the complete bundle to both.agents/skills/block-runner/and.claude/skills/block-runner/by default;--scope,--target, and--dircover user-wide, single-harness, and arbitrary roots. - Skill installation is inspectable and guarded.
--dry-runresolves destinations without writes, repeat installs are idempotent, managed files carry hashes, local changes are refused unless--forceis explicit, and installed runtime commands are pinned to the installing package version while the explicit update command stays on@latest.
- Custom HTML fallbacks retain their source markup after the WordPress 7.1
core/htmlserialization change; unsupported input no longer collapses to an empty block. - Validation no longer rejects a working Custom HTML fallback because
core/htmlhas no canonical saved output. The fallback warning and count remain unchanged. - The skill metadata now states its Node/shell/registry requirements, and the guide no longer
describes an uncached
npxrun as fully offline or treats frontend-scraped HTML as supported authored input. - Pre-manifest 0.7.x installations now fail closed on their first upgrade. After review, rerun
with
--force; the obsolete root-levelGUIDE.mdis preserved rather than deleted. - Skill installs reject symlinked discovery roots, and default dual-target installs preflight ordinary write permissions across both destinations before changing either one.
- The guide now says where the blocks go. It stopped at "here is valid markup", leaving an
agent holding correct output with no instruction on what to do with it — so a request like
"add a pricing section to my site" ended in improvisation.
GUIDE.md§5 covers the three endings: write it where the user asked, offer to write it through an available WordPress connection, or show it with the paste instruction. Including the one users get wrong — block markup must go into the Code editor (Ctrl+Shift+Alt+M), not the visual editor, which turns it into a mess and reads as the tool being broken.
No code changes; the CLI and library are identical to 0.7.0.
Block Runner now ships a skill. Agents get markedly better conversions when told how to use the tool, so the instructions travel with the package instead of being rediscovered by every consumer.
npx block-runner skill # print the guide — nothing installed or written
npx block-runner skill --install # install it as a skillMeasured on the project's own 53-fixture benchmark, the guide takes the corpus from 28 to 97, with 0 invalid and 0 fallbacks. Those figures come from a controlled harness rather than a live session, so treat them as a ceiling.
- The skill, shipped in the package and readable by any harness.
skill/GUIDE.mdis the content;skill/SKILL.mdis a thin wrapper over it.skill --installwrites both into.claude/skills/block-runner/, with--dirfor harnesses that keep skills elsewhere. The guide covers which command to reach for, the block mappings per section type, the validate/fix loop, and how to fail safely without stranding the user. assemble— build blocks from a described structure, not from markup. The command the skill drives. Give it an intent tree (JSON naming which blocks go where) and it builds the result withcreateBlock, so the output cannot be invalid. Describing a structure suits a model far better than authoring block markup, which is where invalid output comes from. Also available asassemble/extractIntent/realizelibrary exports.- A hint when a conversion falls back. A
convertrun that drops to Custom HTML now says so on stderr and inreport.hint, pointing at the path that usually handles that input cleanly. It is advisory: it never affects the exit code, the summary counts, or--strict.
- Media resolution and brand-token repair are shared by every path.
convertandassemblenow run the same finalization, so a tree built from intent resolves images and maps colours onto theme presets exactly as a converted one does.
--stylingand--css-outdo not apply toassembleand are rejected with an explanation: an intent tree carries structure and content, never the source CSS. Useconvertwhen the styling matters.- Malformed or empty intent input is a hard failure (exit
1) naming what went wrong, rather than a successful run that produced nothing. convert,validate, andfixare unchanged. Verified by running the benchmark at the previous release and at this one: identical scores across all 53 fixtures.
- CSS is now carried onto blocks as native, editable styling. Previously only
background-imagewas read and every other declaration was discarded in silence — a<div style="padding:64px;background:#f5f5f5">produced a correct block tree with none of its design. Declarations from inlinestyleattributes and from single-class<style>rules (.hero { … }) now map onto the block's own attributes, so padding lands in the spacing control and colours in the colour picker. Inline styles outrank class rules, and!importantand shorthand resets are honoured as CSS defines them. - A
stylingceiling:strict·relaxed·open.strictkeeps only values that snap onto theme presets;relaxed(the default) keeps exact values on the block;openadditionally preserves CSS no block attribute can express, by putting a class on the block and emitting a stylesheet. Set it in config or per run with--styling. --css-outandreport.sidecarCssfor the stylesheetopenproduces.--styling openwithout one of them is an error: a level that quietly discarded the CSS it promised to keep would be worse than not offering it.- Every declaration is accounted for. Each one is reported as mapped, consumed by the
structural rules, or dropped — with the input line, the selector, and the rule that authored
it. Warnings name the class (
max-width: 600px in .hero) so the fix lands upstream. text-alignsupport, mapped throughstyle.typography.textAlign.- WordPress 7.1
minWidth, gated on the block opting in, and recognised-but-refusedtext-shadow(Global-Styles-only in 7.1, so a per-block value would render CSS the editor gives no control over — the warning points attheme.json). - Capability gating against the real target site. With a wesper
--contextmanifest, styling is admitted only where the pinned block library and the target site's own block registry agree, so degradation across WordPress versions is measured rather than hardcoded.
- Background images are chosen by the CSS cascade, not by first match. A background that a later declaration replaced or removed no longer becomes cover media — the structural rules and the styling ledger now read a style attribute through the same parser.
@wordpress/block-editoris now a direct pinned dependency. It was already present transitively and governs the emitted markup, so it belongs in the pin rather than resolved by chance.
- Stop shipping sourcemaps.
dist/*.js.mapwere ~340KB of the published tarball and served no purpose for consumers. Dropping them roughly halves the package (unpacked 542KB → 202KB) and avoids leaking local build paths.
- Inline SVG (and any foreign element) no longer crashes conversion. An
<svg>or MathML node anywhere in the input threwclassName.split is not a functionand aborted the whole run with no output. Foreign elements now route straight to Custom HTML, and a per-rule error boundary guarantees no single node can abort a run.
- Native-block coverage for traditional content. New rules map
<table>→core/table(colspan/rowspan/scope +<caption>),<blockquote>→core/quote,<pre><code>/<pre>→core/code/core/preformatted,<hr>→core/separator,<video>/<audio>→core/video/core/audio(with<track>),<details>→core/details, YouTube/Vimeo<iframe>→core/embed, and multi-image<figure>→core/gallery. A<figure>dispatcher carries<figcaption>onto the right block. - Atomic enclosing-unit fallback. When a block's rich text contains content the
editor can't hold (inline SVG/iframe, block-level markup), the whole enclosing block
falls back to Custom HTML with a warning at the offending node — output, render, and
editor-load state always agree. Empty decorative inline hooks (e.g. a CSS chevron
<span>) are stripped so the block stays native; empty semantic elements (id/href/datetime/aria-*) fall back instead of being lost.
- Hardened URL sanitization.
javascript:/vbscript:schemes obfuscated with control characters or whitespace (java\nscript:) are now stripped, and executable<iframe srcdoc>is removed before it can reach a Custom HTML block. - Exact-hostname embed matching. Provider detection parses the URL and matches exact
hostnames over HTTPS with anchored path shapes, so lookalike domains
(
notyoutube.com) can no longer be rewritten into a trustedcore/embed.
- Strip unused Gutenberg media WASM from installs: override
@wordpress/vips+wasm-vipsto empty stubs, and prune them inpostinstallwhen this package is a nested dependency (~155MB). Headless convert/validate never calls that pipeline.
@wordpress/blocks14.15 → 15.23,@wordpress/block-library9.26 → 10.1 (current Gutenberg headless stack).jsdom24 → 29,commander12 → 15.- Dev:
vitest2 → 4,tsup8.5,tsx4.23,typescript5.9, types updated. - Overrides:
uuid@11.1.1,esbuild@0.28.1(clear remaining audit findings).
npm auditreports 0 vulnerabilities (was 18: 1 critical, 1 high, 16 moderate).
- README hero + benchmark images use jsDelivr (
cdn.jsdelivr.net/gh/...) so they render on npmjs.com (raw.githubusercontent.com was returning 429).
check:privatesupports both npm ≤11 and npm ≥12pack --jsonshapes.- CI/release pin
npm@11(not floatinglatest/ npm 12 engine cliff).
- Fix package-lock sync so
npm ciworks in CI (missing optional peer entries). - Harden
check:privateJSON extraction for npm 11 (bracket-balanced parse; release workflow was failing after green tests).
- Token repair — map raw colors/fonts/spacing to theme presets via
noop/file/wpcli/rest/contextresolvers (--token-resolver,--theme-json,--context,--token-match). block-runner context— collect a wespersite.context.jsonmanifest over WP-CLI (library:collectSiteContext).- Depend on published
wesper@0.0.2for site context collection.
- README hero + benchmark images use absolute GitHub URLs so they render on npm.
- Harden
check:privateagainstnpm packstdout pollution (CI was red on main). - CLI
--versionreads frompackage.json(no more hardcoded version). - Package hygiene:
author,publishConfig, top-leveltypes. engines.noderaised to>=20(Node 18 EOL); CI matrix is 20 / 22 / 24.- Build target is
node20;pack:checkskips lifecycle scripts.
- Gate: render Gutenberg validation issues as readable messages.
- Prepare/prepublish build so git installs and npm publish produce
dist/. - Pre-commit hook config and “run it anywhere” docs.
- Benchmark section + fidelity chart in the README.
- Initial public v1 implementation: headless Gutenberg boot, validation, canonicalization, deterministic conversion rules, media resolvers, CLI, and library API.