{"_id":"@automattic/blocks-engine","_rev":"6-78c200e0e81ed8a5632fdf21b94176b0","name":"@automattic/blocks-engine","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.0":{"name":"@automattic/blocks-engine","version":"0.1.0","keywords":["wordpress","blocks","gutenberg","block-theme","html","static-site"],"license":"GPL-3.0-or-later","_id":"@automattic/blocks-engine@0.1.0","maintainers":[{"name":"macbre","email":"maciej.brencz@gmail.com"},{"name":"yuliyan","email":"yuliyan.slavchev@gmail.com"},{"name":"mjangda","email":"batmoo@gmail.com"},{"name":"matticbot","email":"jetpack+engineering@automattic.com"},{"name":"a8c","email":"invoices@automattic.com"},{"name":"blowery","email":"ben@blowery.org"},{"name":"ehg_","email":"chris@ehg.sh"},{"name":"sgomes","email":"mail@sgomes.io"},{"name":"tyxla","email":"tyxla@abv.bg"},{"name":"saroshaga","email":"sarosh.aga@automattic.com"},{"name":"nejclovrencic","email":"nejc.lovrencic@gmail.com"},{"name":"sirbrillig","email":"payton@foolord.com"},{"name":"chriszarate","email":"chris@zarate.org"},{"name":"robersongomes","email":"robersonccgomes@gmail.com"},{"name":"johngodley","email":"johng75@gmail.com"},{"name":"jeherve","email":"jeremy@tagada.hu"},{"name":"daledupreez-a8c","email":"dale@automattic.com"},{"name":"t2dw4t","email":"todd.wright@automattic.com"},{"name":"luismulinari","email":"luis.mulinari@gmail.com"},{"name":"andrea-sdl","email":"andrea.grassi@automattic.com"},{"name":"elazzabi","email":"elazzabi.ahmed@gmail.com"},{"name":"fmfernandes","email":"fernando.fernandes@automattic.com"},{"name":"sirreal","email":"jon.surrell@gmail.com"},{"name":"wwa","email":"volodymyr@wildwolf.name"},{"name":"chihsuan","email":"chihsuan.tw@gmail.com"},{"name":"manzoorwanijk","email":"manzoorwani.jk@gmail.com"},{"name":"msurdi-a8c","email":"matias.emanuel.surdi@automattic.com"},{"name":"newspack-npm","email":"newspack@a8c.com"},{"name":"dsmartg","email":"derek.smart@automattic.com"},{"name":"kthai15","email":"kavin.keratikasama@automattic.com"},{"name":"bgrgicak","email":"berislav.grgicak@gmail.com"},{"name":"robertsreberski_a8c","email":"robert.sreberski@automattic.com"},{"name":"artpi","email":"artur.piszek@gmail.com"},{"name":"gmjuhasz","email":"jugergo@gmail.com"},{"name":"borkweb","email":"borkweb@gmail.com"},{"name":"kat3samsin","email":"kat3samsin@gmail.com"},{"name":"brunobasto","email":"b.basto@gmail.com"},{"name":"dhenridev","email":"douglas.henri@automattic.com"},{"name":"mrmurphy","email":"m@mrmurphy.dev"},{"name":"wpvip-bot","email":"platform+npm@wpvip.com"},{"name":"etobiesen","email":"e.tobiesen@gmail.com"},{"name":"alshakero","email":"omar@omaralshaker.com"},{"name":"arthur791004","email":"arthur791004@gmail.com"},{"name":"dilirity","email":"peter.petrov89@gmail.com"},{"name":"mehmoodak","email":"npmjs.corporate906@passinbox.com"},{"name":"natalia.vidal","email":"natalia.vidal@automattic.com"},{"name":"ivan.ottinger","email":"ivan.ottinger@automattic.com"},{"name":"anandnalya","email":"anand.nalya@gmail.com"},{"name":"arcangelinis","email":"anthony.arcangelini@gmail.com"},{"name":"retrofox","email":"rdsuarez@gmail.com"},{"name":"fredrikekelund","email":"fredrik@fredrik.computer"},{"name":"chriskmnds","email":"chriskmnds@gmail.com"},{"name":"oandregal","email":"ola@oandre.gal"},{"name":"galatanovidiu","email":"galatanovidiu@gmail.com"},{"name":"kangzj","email":"kangzjnet@gmail.com"},{"name":"_mirka_","email":"lena@jaguchi.com"},{"name":"aduth","email":"andrew@andrewduthie.com"},{"name":"ebuccelli","email":"emanuele.buccelli@automattic.com"}],"homepage":"https://github.com/Automattic/blocks-engine/tree/trunk/packages/blocks-engine#readme","bugs":{"url":"https://github.com/Automattic/blocks-engine/issues"},"bin":{"blocks-engine":"dist/cli.js"},"dist":{"shasum":"6dbc97dd14f97ab3028cd2e9dfd958a591ccf81e","tarball":"https://registry.npmjs.org/@automattic/blocks-engine/-/blocks-engine-0.1.0.tgz","fileCount":55,"integrity":"sha512-3eAknzPA1DUEKPfBd1U9NMZ7OsHerrSjIXY9rE/6khDMeUKk7AYhgdDkD8Oemr0ZOX+qe6aFe+GLE8lNBNbcew==","signatures":[{"sig":"MEQCIDrtwurtI7du7Ry5yYNeYbdtt6TP41DhJltqrSH+BCZzAiB4XynbXfW22Y0IjzZW6FLu44r0+ToKt9eVYULQ9Oj9xw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3578863},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","source":"./src/index.ts","require":"./dist/index.cjs"},"./wp":{"types":"./dist/wp/index.d.ts","import":"./dist/wp/index.js","source":"./src/wp/index.ts","require":"./dist/wp/index.cjs"},"./theme":{"types":"./dist/theme/index.d.ts","import":"./dist/theme/index.js","source":"./src/theme/index.ts","require":"./dist/theme/index.cjs"},"./internals":{"types":"./dist/internals/index.d.ts","import":"./dist/internals/index.js","source":"./src/internals/index.ts","require":"./dist/internals/index.cjs"}},"gitHead":"56474e38fbe4dd03097ed85eaea9a638c733b277","scripts":{"test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"borkweb","email":"borkweb@gmail.com"},"repository":{"url":"git+https://github.com/Automattic/blocks-engine.git","type":"git","directory":"packages/blocks-engine"},"_npmVersion":"11.12.1","description":"Convert HTML and static sites into WordPress block markup and block themes.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"jsdom":"29.0.1","cheerio":"1.2.0","domhandler":"5.0.3","@wordpress/data":"10.42.0","@wordpress/hooks":"4.42.0","@wordpress/blocks":"15.15.0","@wordpress/block-editor":"15.15.0","@wordpress/block-library":"9.42.0","@wordpress/block-serialization-default-parser":"5.47.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.4","tsup":"8.0.0","vitest":"2.0.0","typescript":"5.7.3","@types/node":"^26.0.0"},"_npmOperationalInternal":{"tmp":"tmp/blocks-engine_0.1.0_1782740212056_0.12812793853853788","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@automattic/blocks-engine","version":"0.2.1","keywords":["wordpress","blocks","gutenberg","block-theme","html","static-site"],"license":"GPL-3.0-or-later","_id":"@automattic/blocks-engine@0.2.1","maintainers":[{"name":"macbre","email":"maciej.brencz@gmail.com"},{"name":"yuliyan","email":"yuliyan.slavchev@gmail.com"},{"name":"mjangda","email":"batmoo@gmail.com"},{"name":"matticbot","email":"jetpack+engineering@automattic.com"},{"name":"a8c","email":"invoices@automattic.com"},{"name":"blowery","email":"ben@blowery.org"},{"name":"ehg_","email":"chris@ehg.sh"},{"name":"sgomes","email":"mail@sgomes.io"},{"name":"tyxla","email":"tyxla@abv.bg"},{"name":"saroshaga","email":"sarosh.aga@automattic.com"},{"name":"nejclovrencic","email":"nejc.lovrencic@gmail.com"},{"name":"sirbrillig","email":"payton@foolord.com"},{"name":"chriszarate","email":"chris@zarate.org"},{"name":"robersongomes","email":"robersonccgomes@gmail.com"},{"name":"johngodley","email":"johng75@gmail.com"},{"name":"jeherve","email":"jeremy@tagada.hu"},{"name":"daledupreez-a8c","email":"dale@automattic.com"},{"name":"t2dw4t","email":"todd.wright@automattic.com"},{"name":"luismulinari","email":"luis.mulinari@gmail.com"},{"name":"andrea-sdl","email":"andrea.grassi@automattic.com"},{"name":"elazzabi","email":"elazzabi.ahmed@gmail.com"},{"name":"fmfernandes","email":"fernando.fernandes@automattic.com"},{"name":"sirreal","email":"jon.surrell@gmail.com"},{"name":"wwa","email":"volodymyr@wildwolf.name"},{"name":"chihsuan","email":"chihsuan.tw@gmail.com"},{"name":"manzoorwanijk","email":"manzoorwani.jk@gmail.com"},{"name":"msurdi-a8c","email":"matias.emanuel.surdi@automattic.com"},{"name":"newspack-npm","email":"newspack@a8c.com"},{"name":"dsmartg","email":"derek.smart@automattic.com"},{"name":"kthai15","email":"kavin.keratikasama@automattic.com"},{"name":"bgrgicak","email":"berislav.grgicak@gmail.com"},{"name":"robertsreberski_a8c","email":"robert.sreberski@automattic.com"},{"name":"artpi","email":"artur.piszek@gmail.com"},{"name":"gmjuhasz","email":"jugergo@gmail.com"},{"name":"borkweb","email":"borkweb@gmail.com"},{"name":"kat3samsin","email":"kat3samsin@gmail.com"},{"name":"brunobasto","email":"b.basto@gmail.com"},{"name":"dhenridev","email":"douglas.henri@automattic.com"},{"name":"mrmurphy","email":"m@mrmurphy.dev"},{"name":"wpvip-bot","email":"platform+npm@wpvip.com"},{"name":"etobiesen","email":"e.tobiesen@gmail.com"},{"name":"alshakero","email":"omar@omaralshaker.com"},{"name":"arthur791004","email":"arthur791004@gmail.com"},{"name":"dilirity","email":"peter.petrov89@gmail.com"},{"name":"mehmoodak","email":"npmjs.corporate906@passinbox.com"},{"name":"natalia.vidal","email":"natalia.vidal@automattic.com"},{"name":"ivan.ottinger","email":"ivan.ottinger@automattic.com"},{"name":"anandnalya","email":"anand.nalya@gmail.com"},{"name":"arcangelinis","email":"anthony.arcangelini@gmail.com"},{"name":"retrofox","email":"rdsuarez@gmail.com"},{"name":"fredrikekelund","email":"fredrik@fredrik.computer"},{"name":"chriskmnds","email":"chriskmnds@gmail.com"},{"name":"oandregal","email":"ola@oandre.gal"},{"name":"galatanovidiu","email":"galatanovidiu@gmail.com"},{"name":"kangzj","email":"kangzjnet@gmail.com"},{"name":"_mirka_","email":"lena@jaguchi.com"},{"name":"aduth","email":"andrew@andrewduthie.com"},{"name":"ebuccelli","email":"emanuele.buccelli@automattic.com"}],"homepage":"https://github.com/Automattic/blocks-engine/tree/trunk/packages/blocks-engine#readme","bugs":{"url":"https://github.com/Automattic/blocks-engine/issues"},"bin":{"blocks-engine":"dist/cli.js"},"dist":{"shasum":"56f76e011dda1b5d7813cac44162cecaa3c59799","tarball":"https://registry.npmjs.org/@automattic/blocks-engine/-/blocks-engine-0.2.1.tgz","fileCount":56,"integrity":"sha512-MiGHBChn+USfdXP1FpVlv8Ts8TF0SDh13JlmPDB5gDIO7bKUzaVAveadkjdELQuEGqF1pbVA/KYYQA3hQc8MUg==","signatures":[{"sig":"MEYCIQDD9SVyHu9MS/rvquBBJEyr5XqOjVreruVZAnW8tjr95gIhANQ8Yt3wkAc+oUR3w/HmD9X3DsGc+dSlP4OB2lt7PEVs","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25578989},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","source":"./src/index.ts","require":"./dist/index.cjs"},"./wp":{"types":"./dist/wp/index.d.ts","import":"./dist/wp/index.js","source":"./src/wp/index.ts","require":"./dist/wp/index.cjs"},"./theme":{"types":"./dist/theme/index.d.ts","import":"./dist/theme/index.js","source":"./src/theme/index.ts","require":"./dist/theme/index.cjs"},"./internals":{"types":"./dist/internals/index.d.ts","import":"./dist/internals/index.js","source":"./src/internals/index.ts","require":"./dist/internals/index.cjs"}},"gitHead":"bb2bafe403bb7fd004c8464c17a31308f28d2cf9","scripts":{"test":"vitest run","bench":"node --import tsx scripts/tuner/bench.ts","build":"tsup && node scripts/build-wp-runtime.mjs","typecheck":"tsc --noEmit","test:bundle":"pnpm build && BLOCKS_ENGINE_WP_RUNTIME=bundle BLOCKS_ENGINE_WP_RUNTIME_PATH=\"$PWD/dist/wp-runtime.cjs\" vitest run","bench:derive":"node --import tsx scripts/tuner/derive.ts","bench:record":"node --import tsx scripts/tuner/bench.ts --record","prepublishOnly":"npm run build"},"_npmUser":{"name":"borkweb","email":"borkweb@gmail.com"},"repository":{"url":"git+https://github.com/Automattic/blocks-engine.git","type":"git","directory":"packages/blocks-engine"},"_npmVersion":"11.12.1","description":"Convert HTML and static sites into WordPress block markup and block themes.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"jsdom":"29.0.1","cheerio":"1.2.0","domhandler":"5.0.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.4","tsup":"8.0.0","vitest":"2.0.0","esbuild":"^0.24.0","typescript":"5.7.3","@types/node":"^26.0.0","@wordpress/blocks":"15.22.0","@wordpress/block-library":"10.0.0","@wordpress/block-serialization-default-parser":"5.49.0"},"_npmOperationalInternal":{"tmp":"tmp/blocks-engine_0.2.1_1782791234940_0.5970442635426689","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@automattic/blocks-engine","version":"0.2.2","keywords":["wordpress","blocks","gutenberg","block-theme","html","static-site"],"license":"GPL-3.0-or-later","_id":"@automattic/blocks-engine@0.2.2","maintainers":[{"name":"macbre","email":"maciej.brencz@gmail.com"},{"name":"yuliyan","email":"yuliyan.slavchev@gmail.com"},{"name":"mjangda","email":"batmoo@gmail.com"},{"name":"matticbot","email":"jetpack+engineering@automattic.com"},{"name":"a8c","email":"invoices@automattic.com"},{"name":"blowery","email":"ben@blowery.org"},{"name":"ehg_","email":"chris@ehg.sh"},{"name":"sgomes","email":"mail@sgomes.io"},{"name":"tyxla","email":"tyxla@abv.bg"},{"name":"saroshaga","email":"sarosh.aga@automattic.com"},{"name":"nejclovrencic","email":"nejc.lovrencic@gmail.com"},{"name":"sirbrillig","email":"payton@foolord.com"},{"name":"chriszarate","email":"chris@zarate.org"},{"name":"robersongomes","email":"robersonccgomes@gmail.com"},{"name":"johngodley","email":"johng75@gmail.com"},{"name":"jeherve","email":"jeremy@tagada.hu"},{"name":"daledupreez-a8c","email":"dale@automattic.com"},{"name":"t2dw4t","email":"todd.wright@automattic.com"},{"name":"luismulinari","email":"luis.mulinari@gmail.com"},{"name":"andrea-sdl","email":"andrea.grassi@automattic.com"},{"name":"elazzabi","email":"elazzabi.ahmed@gmail.com"},{"name":"fmfernandes","email":"fernando.fernandes@automattic.com"},{"name":"sirreal","email":"jon.surrell@gmail.com"},{"name":"wwa","email":"volodymyr@wildwolf.name"},{"name":"chihsuan","email":"chihsuan.tw@gmail.com"},{"name":"manzoorwanijk","email":"manzoorwani.jk@gmail.com"},{"name":"msurdi-a8c","email":"matias.emanuel.surdi@automattic.com"},{"name":"newspack-npm","email":"newspack@a8c.com"},{"name":"dsmartg","email":"derek.smart@automattic.com"},{"name":"kthai15","email":"kavin.keratikasama@automattic.com"},{"name":"bgrgicak","email":"berislav.grgicak@gmail.com"},{"name":"robertsreberski_a8c","email":"robert.sreberski@automattic.com"},{"name":"artpi","email":"artur.piszek@gmail.com"},{"name":"gmjuhasz","email":"jugergo@gmail.com"},{"name":"borkweb","email":"borkweb@gmail.com"},{"name":"kat3samsin","email":"kat3samsin@gmail.com"},{"name":"brunobasto","email":"b.basto@gmail.com"},{"name":"dhenridev","email":"douglas.henri@automattic.com"},{"name":"mrmurphy","email":"m@mrmurphy.dev"},{"name":"wpvip-bot","email":"platform+npm@wpvip.com"},{"name":"etobiesen","email":"e.tobiesen@gmail.com"},{"name":"alshakero","email":"omar@omaralshaker.com"},{"name":"arthur791004","email":"arthur791004@gmail.com"},{"name":"dilirity","email":"peter.petrov89@gmail.com"},{"name":"mehmoodak","email":"npmjs.corporate906@passinbox.com"},{"name":"natalia.vidal","email":"natalia.vidal@automattic.com"},{"name":"ivan.ottinger","email":"ivan.ottinger@automattic.com"},{"name":"anandnalya","email":"anand.nalya@gmail.com"},{"name":"arcangelinis","email":"anthony.arcangelini@gmail.com"},{"name":"retrofox","email":"rdsuarez@gmail.com"},{"name":"fredrikekelund","email":"fredrik@fredrik.computer"},{"name":"chriskmnds","email":"chriskmnds@gmail.com"},{"name":"oandregal","email":"ola@oandre.gal"},{"name":"galatanovidiu","email":"galatanovidiu@gmail.com"},{"name":"kangzj","email":"kangzjnet@gmail.com"},{"name":"_mirka_","email":"lena@jaguchi.com"},{"name":"aduth","email":"andrew@andrewduthie.com"},{"name":"ebuccelli","email":"emanuele.buccelli@automattic.com"}],"homepage":"https://github.com/Automattic/blocks-engine/tree/trunk/packages/blocks-engine#readme","bugs":{"url":"https://github.com/Automattic/blocks-engine/issues"},"bin":{"blocks-engine":"dist/cli.js"},"dist":{"shasum":"aa057772ac400eff7ef114145771be74adaa4ee3","tarball":"https://registry.npmjs.org/@automattic/blocks-engine/-/blocks-engine-0.2.2.tgz","fileCount":56,"integrity":"sha512-1d2C7QAhDJfaDlrDdkECE7bUkPttYUHmXizwgCPxZwVQhm8P5MTM99pvWYjh2+NsDRkQK7ZA1xHDNY5iEMW0gQ==","signatures":[{"sig":"MEUCIQD+FrzarCWSHeIeJdLlboCYkJ2bqQ5WhD9PHCCaNgO8zgIgIktZd+zIH3wqOckQLpDW3nmBSDTvXVKotEwI0CtZLJ8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":25585210},"type":"module","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","source":"./src/index.ts","require":"./dist/index.cjs"},"./wp":{"types":"./dist/wp/index.d.ts","import":"./dist/wp/index.js","source":"./src/wp/index.ts","require":"./dist/wp/index.cjs"},"./theme":{"types":"./dist/theme/index.d.ts","import":"./dist/theme/index.js","source":"./src/theme/index.ts","require":"./dist/theme/index.cjs"},"./internals":{"types":"./dist/internals/index.d.ts","import":"./dist/internals/index.js","source":"./src/internals/index.ts","require":"./dist/internals/index.cjs"}},"gitHead":"770865e386740c3bc785275dd58129355e6c9576","scripts":{"test":"vitest run","bench":"node --import tsx scripts/tuner/bench.ts","build":"tsup && node scripts/build-wp-runtime.mjs","typecheck":"tsc --noEmit","test:bundle":"pnpm build && BLOCKS_ENGINE_WP_RUNTIME=bundle BLOCKS_ENGINE_WP_RUNTIME_PATH=\"$PWD/dist/wp-runtime.cjs\" vitest run","bench:derive":"node --import tsx scripts/tuner/derive.ts","bench:record":"node --import tsx scripts/tuner/bench.ts --record","prepublishOnly":"npm run build"},"_npmUser":{"name":"borkweb","email":"borkweb@gmail.com"},"repository":{"url":"git+https://github.com/Automattic/blocks-engine.git","type":"git","directory":"packages/blocks-engine"},"_npmVersion":"11.12.1","description":"Convert HTML and static sites into WordPress block markup and block themes.","directories":{},"_nodeVersion":"24.15.0","dependencies":{"jsdom":"29.0.1","cheerio":"1.2.0","domhandler":"5.0.3"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.4","tsup":"8.0.0","vitest":"2.0.0","esbuild":"^0.24.0","typescript":"5.7.3","@types/node":"^26.0.0","@wordpress/blocks":"15.22.0","@wordpress/block-library":"10.0.0","@wordpress/block-serialization-default-parser":"5.49.0"},"_npmOperationalInternal":{"tmp":"tmp/blocks-engine_0.2.2_1782797492881_0.2738332043569036","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-06-29T13:36:51.768Z","modified":"2026-09-25T20:23:48.287Z","0.1.0":"2026-06-29T13:36:52.315Z","0.2.1":"2026-06-30T03:47:15.216Z","0.2.2":"2026-06-30T05:31:33.140Z"},"bugs":{"url":"https://github.com/Automattic/blocks-engine/issues"},"license":"GPL-3.0-or-later","homepage":"https://github.com/Automattic/blocks-engine/tree/trunk/packages/blocks-engine#readme","keywords":["wordpress","blocks","gutenberg","block-theme","html","static-site"],"repository":{"url":"git+https://github.com/Automattic/blocks-engine.git","type":"git","directory":"packages/blocks-engine"},"description":"Convert HTML and static sites into WordPress block markup and block themes.","maintainers":[{"email":"maciej.brencz@gmail.com","name":"macbre"},{"email":"yuliyan.slavchev@gmail.com","name":"yuliyan"},{"email":"batmoo@gmail.com","name":"mjangda"},{"email":"jetpack+engineering@automattic.com","name":"matticbot"},{"email":"invoices@automattic.com","name":"a8c"},{"email":"ben@blowery.org","name":"blowery"},{"email":"chris@ehg.sh","name":"ehg_"},{"email":"mail@sgomes.io","name":"sgomes"},{"email":"tyxla@abv.bg","name":"tyxla"},{"email":"sarosh.aga@automattic.com","name":"saroshaga"},{"email":"nejc.lovrencic@gmail.com","name":"nejclovrencic"},{"email":"payton@foolord.com","name":"sirbrillig"},{"email":"chris@zarate.org","name":"chriszarate"},{"email":"robersonccgomes@gmail.com","name":"robersongomes"},{"email":"johng75@gmail.com","name":"johngodley"},{"email":"jeremy@tagada.hu","name":"jeherve"},{"email":"dale@automattic.com","name":"daledupreez-a8c"},{"email":"todd.wright@automattic.com","name":"t2dw4t"},{"email":"luis.mulinari@gmail.com","name":"luismulinari"},{"email":"andrea.grassi@automattic.com","name":"andrea-sdl"},{"email":"elazzabi.ahmed@gmail.com","name":"elazzabi"},{"email":"fernando.fernandes@automattic.com","name":"fmfernandes"},{"email":"jon.surrell@gmail.com","name":"sirreal"},{"email":"volodymyr@wildwolf.name","name":"wwa"},{"email":"chihsuan.tw@gmail.com","name":"chihsuan"},{"email":"manzoorwani.jk@gmail.com","name":"manzoorwanijk"},{"email":"matias.emanuel.surdi@automattic.com","name":"msurdi-a8c"},{"email":"newspack@a8c.com","name":"newspack-npm"},{"email":"derek.smart@automattic.com","name":"dsmartg"},{"email":"kavin.keratikasama@automattic.com","name":"kthai15"},{"email":"berislav.grgicak@gmail.com","name":"bgrgicak"},{"email":"robert.sreberski@automattic.com","name":"robertsreberski_a8c"},{"email":"artur.piszek@gmail.com","name":"artpi"},{"email":"jugergo@gmail.com","name":"gmjuhasz"},{"email":"borkweb@gmail.com","name":"borkweb"},{"email":"kat3samsin@gmail.com","name":"kat3samsin"},{"email":"b.basto@gmail.com","name":"brunobasto"},{"email":"douglas.henri@automattic.com","name":"dhenridev"},{"email":"m@mrmurphy.dev","name":"mrmurphy"},{"email":"platform+npm@wpvip.com","name":"wpvip-bot"},{"email":"e.tobiesen@gmail.com","name":"etobiesen"},{"email":"omar@omaralshaker.com","name":"alshakero"},{"email":"arthur791004@gmail.com","name":"arthur791004"},{"email":"peter.petrov89@gmail.com","name":"dilirity"},{"email":"npmjs.corporate906@passinbox.com","name":"mehmoodak"},{"email":"natalia.vidal@automattic.com","name":"natalia.vidal"},{"email":"ivan.ottinger@automattic.com","name":"ivan.ottinger"},{"email":"anand.nalya@gmail.com","name":"anandnalya"},{"email":"anthony.arcangelini@gmail.com","name":"arcangelinis"},{"email":"rdsuarez@gmail.com","name":"retrofox"},{"email":"mayank.chugh@automattic.com","name":"iamchughmayank"},{"email":"mikael@ihminen.org","name":"simison"},{"email":"fredrik@fredrik.computer","name":"fredrikekelund"},{"email":"griffith.chen@automattic.com","name":"griffithchen"},{"email":"josh.boland@automattic.com","name":"jboland8"},{"email":"chriskmnds@gmail.com","name":"chriskmnds"},{"email":"ola@oandre.gal","name":"oandregal"},{"email":"galatanovidiu@gmail.com","name":"galatanovidiu"},{"email":"kangzjnet@gmail.com","name":"kangzj"},{"email":"lena@jaguchi.com","name":"_mirka_"},{"email":"andrew@andrewduthie.com","name":"aduth"},{"email":"emanuele.buccelli@automattic.com","name":"ebuccelli"}],"readme":"# @automattic/blocks-engine\n\nConvert HTML and static sites into WordPress block markup and block themes — from JavaScript or the command line.\n\n- **Convert HTML → blocks.** Turn an HTML fragment or page into clean WordPress block markup.\n- **Build a whole block theme.** Point it at a directory of static HTML and get back a ready-to-install block theme (templates, parts, patterns, `theme.json`, assets).\n- **Use it however you like.** A one-shot async API, a pure in-process composer, a reusable worker pool, and an `npx` CLI all ship in the box.\n\n## Install\n\n```sh\nnpm install @automattic/blocks-engine\n```\n\nOr run the CLI without installing anything:\n\n```sh\nnpx @automattic/blocks-engine --help\n```\n\nRequires Node.js with support for forking child processes and IPC (the worker pool runs conversions in child processes).\n\n## Quick Start\n\n### Build a block theme from the CLI\n\n```sh\nnpx @automattic/blocks-engine theme ./my-site\n```\n\nThis reads the static HTML in `./my-site` and writes a complete block theme to `./_block-theme`. The command exits without touching anything if that default directory already exists, so a stray `_block-theme/` is never silently overwritten.\n\nSet the output directory and theme metadata with flags:\n\n```sh\nnpx @automattic/blocks-engine theme ./my-site --out ./theme --slug my-site --name \"My Site\"\n```\n\nThe bare source-directory form is shorthand for `theme`:\n\n```sh\nnpx @automattic/blocks-engine ./my-site\n```\n\n### Convert HTML in JavaScript\n\n```js\nimport { convert } from '@automattic/blocks-engine';\n\nconst html = '<h2>Hi</h2><p>Body</p>';\nconst blockMarkup = await convert(html, { url: 'https://example.com/page.html' });\n\nconsole.log(blockMarkup);\n```\n\nEmits:\n\n```html\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Hi</h2>\n<!-- /wp:heading -->\n\n<!-- wp:paragraph -->\n<p>Body</p>\n<!-- /wp:paragraph -->\n```\n\n`convert` is the normal end-to-end path: it tries worker-backed conversion, falls back through composition when needed, canonicalizes the result, and returns WordPress block markup. If you don't pass a pool, it spins one up for the call and stops it before returning.\n\n## CLI\n\n```\nblocks-engine theme <srcDir> [--out <dir>] [--slug <slug>] [--name <name>]\nblocks-engine <srcDir> [--out <dir>] [--slug <slug>] [--name <name>]\nblocks-engine convert [file]\nblocks-engine --help | -h\n```\n\n| Command   | Description |\n|-----------|-------------|\n| `theme`   | Build a whole-site block theme from a source directory. |\n| `convert` | Convert a single HTML file — or stdin — to block markup. |\n\n| Option          | Description |\n|-----------------|-------------|\n| `--out <dir>`   | Write the generated theme to a directory (default: `./_block-theme`; the command exits if it already exists). |\n| `--slug <slug>` | Set the generated theme slug. |\n| `--name <name>` | Set the generated theme name. |\n\n`convert` writes block markup to stdout. With a file argument it reads that file; with no argument it reads HTML from stdin:\n\n```sh\nnpx @automattic/blocks-engine convert page.html\nprintf '<h2>Hi</h2>' | npx @automattic/blocks-engine convert\n```\n\n## JavaScript API\n\nThe root export (`@automattic/blocks-engine`) mirrors `src/index.ts`:\n\n**Functions & classes**\n\n| Export | Use it to… |\n|--------|-----------|\n| `convert` | Run the normal end-to-end HTML → blocks conversion (async). |\n| `compose` | Run the pure, synchronous in-process composition layer directly. |\n| `createWorker` | Create a reusable `WorkerPool` for batches or long-lived processes. |\n| `siteToTheme` | Build and write a block theme from a source directory (the CLI's `theme` engine). |\n| `writeTheme` | Write an already-built `ThemeModel` to disk. |\n| `lintThemeJson` | Lint a `theme.json` object and get back structured findings. |\n| `BlocksEngineError` | Catch package-level failures carrying a stable `code` and user-facing `hint`. |\n\n**Types**\n\n`ConvertOptions`, `BlocksEngineErrorOptions`, `SiteToThemeOptions`, `ThemeBuildResult`, `ThemeJsonLintResult`, `ConversionContext`, `Converter`, `HtmlFallback`, `CreateWorker`, `FixResult`, `RawConvertResult`, `WorkerPool`, `WorkerPoolOptions`, `PoolEvent`.\n\nImport runtime functions and classes normally, and import TypeScript shapes with `type`:\n\n```ts\nimport {\n  BlocksEngineError,\n  compose,\n  convert,\n  createWorker,\n  siteToTheme,\n  type Converter,\n  type PoolEvent,\n  type WorkerPool,\n} from '@automattic/blocks-engine';\n```\n\nAdvanced utilities that aren't part of the headline path live under `@automattic/blocks-engine/internals`. Theme- and WordPress-specific helpers are exposed under `@automattic/blocks-engine/theme` and `@automattic/blocks-engine/wp`.\n\n### Build a theme programmatically\n\n```ts\nimport { siteToTheme } from '@automattic/blocks-engine';\n\nconst result = await siteToTheme('./my-site', {\n  outDir: './theme',\n  themeMeta: { slug: 'my-site', name: 'My Site' },\n});\n\nconsole.log(`Wrote ${result.written.length} files to ${result.outDir}`);\nresult.warnings.forEach((warning) => console.warn(warning));\n```\n\n`siteToTheme` ingests the source directory, builds the theme model, and writes it to `outDir` (defaulting to `<srcDir>/theme`), returning a `ThemeBuildResult` with the written file list, tallies, warnings, and diagnostics. Pass your own `pool` to reuse a worker pool across builds; otherwise it manages one internally.\n\n## Which entry point do I use?\n\n- **`convert`** — the default. Async, worker-backed with composition fallback, and self-contained: it owns and stops its pool unless you supply one.\n- **`compose`** — the pure, synchronous composition layer. Reach for it when you want custom `Converter` chains, custom `HtmlFallback` behavior, or tests and tools that only need best-effort local HTML-to-block composition. It never creates, owns, or stops a worker pool.\n- **`createWorker`** — for batches or long-lived processes. Reuse one `WorkerPool` across calls to avoid per-item worker startup costs, and pass it into `convert` via `ConvertOptions.pool`.\n- **`siteToTheme`** — for turning a directory of static HTML into a full block theme (this is what the CLI's `theme` command runs).\n- **`BlocksEngineError`** — catch this for package-level failures with a stable `code` and user-facing `hint`.\n\n## Worker Pool Lifecycle\n\n`createWorker(options?)` returns a `WorkerPool` with `rawConvert(items)`, `canonicalize(items)`, and `stop()`. Treat the pool as an owned process resource.\n\n```ts\nimport { convert, createWorker, type PoolEvent } from '@automattic/blocks-engine';\n\nconst events: PoolEvent[] = [];\nconst pool = createWorker({\n  size: 2,\n  recycleAfter: 100,\n  itemTimeoutMs: 15_000,\n  onEvent: (event) => events.push(event),\n});\n\ntry {\n  const blockMarkup = await convert('<p>Hello</p>', { url: 'https://example.com/' }, { pool });\n  console.log(blockMarkup);\n} finally {\n  await pool.stop();\n}\n```\n\n**Sizing.** The default pool size is `min(cores, 4)`, with a minimum of one worker. `WorkerPoolOptions.size` floors the value and still keeps at least one worker. Start with the default for request/response code; prefer `size: 1` (or another small number) for CI, deterministic tests, or memory-constrained jobs.\n\n**Cleanup.** Workers are child processes connected to the parent over Node IPC. Create the pool in the process that will send work, and don't pass a live pool across process boundaries. Workers die with the parent, but that is not a deterministic cleanup path — always `await pool.stop()` in a `finally` block, test teardown, or shutdown hook. The one-shot `convert` helper handles this for pools it creates itself; shared pools are your responsibility.\n\n**Recycling.** `recycleAfter` replaces a child after it has processed that many items. The default is `0` (disabled). Recycling helps with long-running batches, CI isolation, and workloads where periodically refreshing child-process state is safer than keeping one alive indefinitely.\n\n**Timeouts & resilience.** `itemTimeoutMs` (default `10000`) bounds how long one item can occupy a worker. On timeout or worker failure the pool reroutes work until its reroute limit is reached; unresolved raw conversions return a `RawConvertResult` sentinel and unresolved canonicalization returns the original HTML in a `FixResult`.\n\n**Observability.** `onEvent` receives `PoolEvent` values for `child-spawn`, `child-crash`, `re-route`, `recycle`, `sentinel`, and `pool-degraded`, with `childId` and `count` when available. Log these when diagnosing flakes, timeouts, fork limits, or degraded worker startup.\n\n**Packaging.** Run from an environment that can fork Node child processes and use IPC. For packaged or CI usage, run the package from its built distribution so the worker child file is present; source-mode execution depends on the local TypeScript runner setup.\n\n## Error handling\n\nPackage-level failures throw a `BlocksEngineError` carrying a stable `code` and a user-facing `hint`. The `code` is part of the package's contract — switch on it rather than matching message text. From the CLI, the `message` and `hint` are printed to stderr and the process exits non-zero.\n\n```ts\nimport { siteToTheme, BlocksEngineError } from '@automattic/blocks-engine';\n\ntry {\n  await siteToTheme('./my-site');\n} catch (error) {\n  if (error instanceof BlocksEngineError) {\n    console.error(`[${error.code}] ${error.message}\\n${error.hint}`);\n  } else {\n    throw error;\n  }\n}\n```\n\n| Code | Thrown when | Fix |\n|------|-------------|-----|\n| `INJECTION_VECTORS_REMAIN` | The default HTML fallback sanitized input but unsafe vectors remained. | Pass a custom `htmlFallback` that emits safe markup, or pre-sanitize the input. |\n| `THEME_INGEST_DUPLICATE_SLUG` | Two source pages resolve to the same theme slug. | Rename or restructure the source pages so each maps to a unique slug. |\n| `THEME_INGEST_NO_HTML` | A theme build finds no `.html`/`.htm` pages under the source directory. | Point the build at a directory that contains at least one HTML page. |\n| `WORKER_CHILD_UNRESOLVED` | The worker pool can't locate its child file (typically running from source, or an incomplete build). | Run `npm run build` and run from the built `dist`; confirm the worker child file is present. |\n\n## License\n\nGPL-3.0-or-later\n","readmeFilename":"README.md"}