Skip to content

Releases: humanmade/block-runner

v0.8.0 — cross-harness agent skill

Choose a tag to compare

@noeltock noeltock released this 02 Sep 14:43

Full Changelog: v0.7.1...v0.8.0

v0.7.1 — the guide now says where the blocks go

Choose a tag to compare

@noeltock noeltock released this 07 Aug 09:10

Fixed

  • 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.

v0.7.0 — Block Runner ships a skill

Choose a tag to compare

@noeltock noeltock released this 06 Aug 05:53

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 skill

Measured 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.

Added

  • The skill, shipped in the package and readable by any harness. skill/GUIDE.md is the
    content; skill/SKILL.md is a thin wrapper over it. skill --install writes both into
    .claude/skills/block-runner/, with --dir for 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 with createBlock, 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 as assemble / extractIntent / realize library exports.
  • A hint when a conversion falls back. A convert run that drops to Custom HTML now says
    so on stderr and in report.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.

Changed

  • Media resolution and brand-token repair are shared by every path. convert and
    assemble now run the same finalization, so a tree built from intent resolves images and
    maps colours onto theme presets exactly as a converted one does.

Notes

  • --styling and --css-out do not apply to assemble and are rejected with an explanation:
    an intent tree carries structure and content, never the source CSS. Use convert when 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, and fix are unchanged. Verified by running the benchmark at the
    previous release and at this one: identical scores across all 53 fixtures.

0.6.0 — CSS to native block styles

Choose a tag to compare

@noeltock noeltock released this 27 Jul 12:41

Until now the converter read only background-image and discarded every other CSS declaration in silence. A <div style="padding:64px;background:#f5f5f5"> produced a correct block tree with none of its design, and nothing said so.

Added

  • CSS maps onto blocks as native, editable styling — from inline style attributes and single-class <style> rules. Padding lands in the spacing control, colours in the colour picker. Inline outranks class rules; !important and shorthand resets are honoured as CSS defines them.
  • A styling ceiling: strict · relaxed · open. strict keeps only values that snap onto theme presets, relaxed (default) keeps exact values on the block, open also preserves CSS no block attribute can express by classing the block and emitting a stylesheet. Config or --styling.
  • --css-out / report.sidecarCss for what open produces. --styling open without a sink 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: mapped, consumed by the structural rules, or dropped — with the input line and the authoring selector, so warnings point upstream (max-width: 600px in .hero).
  • text-align, via style.typography.textAlign.
  • WordPress 7.1 minWidth, gated on the block opting in. text-shadow is recognised and refused: it is Global-Styles-only in 7.1, so a per-block value would render CSS the editor gives no control over — the warning points at theme.json.
  • Capability gating against the real target site. With a wesper --context manifest, styling is admitted only where the pinned block library and the site's own block registry agree, so degradation across WordPress versions is measured rather than hardcoded.

Fixed

  • Background images follow the CSS cascade, not first match. An image 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.

Changed

  • @wordpress/block-editor is 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.

179 tests. Full notes in CHANGELOG.md.

v0.5.1

Choose a tag to compare

@noeltock noeltock released this 17 Jul 05:09

Changed

  • Stop shipping sourcemaps. dist/*.js.map were ~340KB of the published tarball and served no purpose for consumers. Dropping them roughly halves the package (packed 128.6 kB → 52 kB, unpacked 542KB → 202KB) and avoids leaking local build paths.

v0.5.0 — traditional-content coverage & inline-SVG crash fix

Choose a tag to compare

@noeltock noeltock released this 10 Jul 07:28

The layer between generated content and WordPress just got much broader coverage — and stopped crashing on inline SVG.

Fixed

  • Inline SVG (and any foreign element) no longer crashes conversion. An <svg>/MathML node anywhere threw className.split is not a function and aborted the whole run with no output. Foreign elements now route to Custom HTML, and a per-rule error boundary guarantees no single node can abort a run.

Added

  • Native-block coverage for traditional content: <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 (+<track>), <details>core/details, YouTube/Vimeo <iframe>core/embed, multi-image <figure>core/gallery, with a <figure> dispatcher for captions.
  • Atomic enclosing-unit fallback. When a block's rich text holds content the editor can't keep (inline SVG/iframe, block-level markup), the whole enclosing block falls back to Custom HTML with a warning at the offending node. Decorative empty inline hooks are stripped so blocks stay native; empty semantic elements (id/href/datetime/aria-*) fall back instead of being lost.

Security

  • Hardened URL sanitization: control-char/whitespace-obfuscated javascript:/vbscript: and executable <iframe srcdoc> are stripped.
  • Exact-hostname embed matching over HTTPS, so lookalike domains (notyoutube.com) can't be rewritten into a trusted core/embed.

Codex Review

2 review passes. Final: all actionable findings resolved.

  • ✅ Addressed: embed lookalike-domain trust-boundary bypass — exact-hostname URL parsing.
  • ✅ Addressed: data:/control-char URL schemes in rich text — normalized + rejected.
  • ✅ Addressed: silent loss of gallery images / table captions / video tracks / mixed-figure content — all carried or preserved via group.
  • ✅ Addressed: semantic empty inline elements stripped — now fall back to Custom HTML.
  • ✋ By design: presentational attributes (class/style/preload) are shed for clean native blocks, consistent with every existing rule; content-bearing attributes are carried.

Full transcript: .git/codex-review-main.log (local).

0.4.1

Choose a tag to compare

@noeltock noeltock released this 09 Jul 08:42

0.4.1 — cut unused media WASM (~155MB)

Headless convert/validate never uses Gutenberg’s editor media pipeline, but
@wordpress/block-library still pulled in @wordpress/vips + wasm-vips.

Changes

  • Override those packages to empty stubs when block-runner is the install root
  • postinstall prune removes them when block-runner is a nested dependency
    (npm ignores nested overrides)

Measured consumer install

Size
0.4.0 ~501 MB
0.4.1 ~346 MB
npm install block-runner@0.4.1

0.4.0

Choose a tag to compare

@noeltock noeltock released this 09 Jul 08:27

0.4.0 — dependency refresh & zero audit findings

Dependencies

  • @wordpress/blocks 14.15 → 15.23, @wordpress/block-library 9.26 → 10.1
  • jsdom 24 → 29, commander 12 → 15
  • Dev: vitest 2 → 4, tsup 8.5, tsx 4.23, typescript 5.9
  • Overrides: uuid@11.1.1, esbuild@0.28.1

Security

  • npm audit0 vulnerabilities (was 18: 1 critical, 1 high, 16 moderate)

Notes

  • Requires Node ≥20 (unchanged from 0.3.x)
  • Full test suite green against the new Gutenberg headless stack
npm install block-runner@0.4.0

0.3.3

Choose a tag to compare

@noeltock noeltock released this 09 Jul 03:05

0.3.3

npm install block-runner@0.3.3

0.3.2

Choose a tag to compare

@noeltock noeltock released this 09 Jul 02:59

0.3.2

Release-blocking fixes (0.3.0 / 0.3.1 never published to npm):

  • check:private supports npm ≤11 and npm ≥12 pack --json shapes.
  • CI and release pin npm@11 (not floating latest — npm 12 requires newer Node and broke the gate).

Included from 0.3.0 / 0.3.1

  • Token repair resolvers + block-runner context (wesper@0.0.2)
  • README absolute image URLs (npm-renderable)
  • Lockfile fixed for npm ci
  • Node ≥20, CI matrix 20 / 22 / 24
npm install block-runner@0.3.2