Add native TypeScript Blueprint v2 runner - #3725
Closed
adamziel wants to merge 37 commits into
Closed
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a native TypeScript Blueprint v2 compile/validate/execute path and routes v2 Blueprints through the standard v1 worker, deprecating the legacy remote v2 worker entrypoint.
Changes:
- Deprecates/fences the remote
blueprints-runner=v2worker and routes all remote execution through the standard worker. - Adds native TypeScript v2 handling in the client and CLI (including v1→v2 upgrades and option normalization).
- Expands Blueprint v2 capabilities (WordPress sources, WXR controls, plugin/theme options, runtime configuration) and adds broad regression coverage.
Reviewed changes
Copilot reviewed 25 out of 27 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/playground/remote/src/lib/playground-worker-endpoint.ts | Adds WordPress ZIP buffer support to worker boot options. |
| packages/playground/remote/src/lib/playground-worker-endpoint-blueprints-v1.ts | Rejects legacy remote v2 runner options; supports caller-provided WordPress ZIP buffers. |
| packages/playground/remote/src/lib/playground-worker-endpoint-blueprints-v1.spec.ts | Tests legacy v2 rejection and WordPress ZIP buffer passthrough. |
| packages/playground/remote/src/lib/boot-playground-remote.ts | Removes v2 worker selection; warns when blueprints-runner=v2 is requested. |
| packages/playground/client/src/index.ts | Routes v2 declarations to native TS handler while always using the standard worker. |
| packages/playground/client/src/index.spec.ts | Adds routing test for v2 declarations. |
| packages/playground/client/src/blueprints-v2-handler.ts | Implements native TS v2 compile/boot/run path and WordPress source resolution. |
| packages/playground/client/src/blueprints-v2-handler.spec.ts | Tests native v2 boot/run, ZIP restrictions, and v1 wp opt-out behavior. |
| packages/playground/client/src/blueprints-v1-handler.ts | Tightens v1 opt-out check and adjusts types for v1 compilation hook. |
| packages/playground/cli/tests/run-cli.spec.ts | Adds routing/option tests and replaces unzip shelling with JS extraction helper. |
| packages/playground/cli/tests/blueprints-v2-handler.spec.ts | Adds unit coverage for CLI native v2 handler behaviors and overrides. |
| packages/playground/cli/src/run-cli.ts | Enables native v2 routing without experimental flag in some cases; tracks which CLI args were explicitly provided. |
| packages/playground/cli/src/blueprints-v2/blueprints-v2-handler.ts | Reworks CLI v2 handler to use TS compiler/runtime while still using v1 worker type. |
| packages/playground/cli/src/blueprints-v1/worker-thread-v1.ts | Adds networking support and centralizes related php.ini entries. |
| packages/playground/blueprints/src/tests/v2/compile.spec.ts | Adds comprehensive v2 compiler/validator/execution-plan/runtime tests. |
| packages/playground/blueprints/src/tests/steps/site-data.spec.ts | Tests rewrite-rule flush on permalink updates. |
| packages/playground/blueprints/src/tests/steps/install-plugin.spec.ts | Adds coverage for skip-plugin and activationOptions. |
| packages/playground/blueprints/src/tests/steps/import-wxr.spec.ts | Adds WXR option/control and repeated-import safety tests. |
| packages/playground/blueprints/src/lib/steps/site-data.ts | Flushes rewrite rules when permalink_structure changes. |
| packages/playground/blueprints/src/lib/steps/install-theme.ts | Adds human-readable progress naming support. |
| packages/playground/blueprints/src/lib/steps/install-plugin.ts | Adds activationOptions, onError, human-readable progress naming, and temp option cleanup. |
| packages/playground/blueprints/src/lib/steps/import-wxr.ts | Adds WXR import controls (URLs/authors/comments/users/site options) and repeated-import helpers. |
| packages/playground/blueprints/src/lib/resolve-runtime-configuration.ts | Resolves v2 runtime configuration via TS compiler (with v1→v2 upgrade). |
| packages/playground/blueprints/src/index.ts | Exports new v2 compiler/validator/runtime APIs and types. |
| packages/playground/blueprints/public/blueprint-schema.json | Updates public schema with new plugin/theme and WXR options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
adamziel
marked this pull request as ready for review
June 2, 2026 02:09
This was referenced Jun 27, 2026
adamziel
force-pushed
the
add/native-blueprint-v2-ts-runner
branch
from
June 30, 2026 23:12
6b52795 to
adb775c
Compare
This was referenced Jun 30, 2026
adamziel
added a commit
that referenced
this pull request
Jul 1, 2026
…3851) ## What it does Flushes WordPress rewrite rules when the `setSiteOptions` Blueprint step changes `permalink_structure`. ```json { "step": "setSiteOptions", "options": { "permalink_structure": "/%postname%/" } } ``` Before this change, the option was updated but `rewrite_rules` could remain missing or stale until WordPress regenerated them later. After this change, `setSiteOptions` calls `flush_rewrite_rules(false)` only when `permalink_structure` is present in the options payload. ## Rationale `permalink_structure` is not just display metadata. It changes how WordPress maps pretty URLs to posts, pages, feeds, embeds, and other routes. Updating the option without flushing rewrite rules can leave a Playground in a split state: `get_option('permalink_structure')` reports the new structure, but requests still rely on old or missing rewrite rules. That matters for Blueprints that set permalink structure and then immediately import content, run checks, or expect pretty URLs to resolve in the same boot. This PR extracts one v1 step behavior from #3725 so it can be reviewed on its own. ## Implementation `setSiteOptions` now checks whether the submitted options include `permalink_structure`: ```php $flush_rewrite_rules = array_key_exists('permalink_structure', $site_options); ``` After updating all requested options, it calls: ```php flush_rewrite_rules(false); ``` The `false` argument avoids writing `.htaccess`; Playground only needs WordPress to regenerate the in-database rewrite rules. ## Testing instructions ```bash npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/steps/site-data.spec.ts npm exec nx run playground-blueprints:typecheck npm exec nx run playground-blueprints:lint git diff --check ``` The new test deletes the `rewrite_rules` option, runs `setSiteOptions` with `permalink_structure`, and verifies that WordPress stores both the permalink structure and regenerated rewrite rules.
adamziel
added a commit
that referenced
this pull request
Jul 1, 2026
## What it does
Adds `activationOptions` to the `installPlugin` Blueprint step.
```json
{
"step": "installPlugin",
"pluginData": { "resource": "wordpress.org/plugins", "slug": "my-plugin" },
"options": {
"activate": true,
"activationOptions": {
"storeCity": "Wroclaw",
"enabled": true
}
}
}
```
When activation options are provided, `installPlugin` stores them in a
temporary WordPress option before running the plugin activation hook.
The option name is based on `plugin_basename(__FILE__)`, so plugin code
can read:
```php
get_option('blueprint_activation_' . plugin_basename(__FILE__))
```
The temporary option is deleted after activation, even if activation
fails.
## Rationale
Some plugins need setup values during activation, not after activation.
A later Blueprint step can update options or run PHP, but it cannot
affect code that already ran inside `register_activation_hook()`.
The Blueprint v2 schema already describes `activationOptions` as data
exposed through a WordPress option named `blueprint_activation_` plus
`plugin_basename(__FILE__)`, and removed after activation. This PR
brings the v1 `installPlugin` step in line with that contract so the
behavior can be reviewed independently before #3725 depends on it.
This does not change plugin installation, plugin path validation,
overwrite behavior, or `onError` handling.
## Implementation
`installPlugin` now wraps the activation call:
1. Locate the plugin PHP file that will receive activation options.
2. Store `options.activationOptions` in
`blueprint_activation_<plugin_basename>`.
3. Run `activatePlugin()` as before.
4. Delete the temporary option in `finally`.
The PHP staging helper prints a sentinel-prefixed JSON payload because
plugin bootstrap code may write to stdout before the helper reports the
option name.
## Testing instructions
```bash
npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/steps/install-plugin.spec.ts
npm exec nx run playground-blueprints:typecheck
npm exec nx run playground-blueprints:lint
git diff --check
```
The new tests cover:
- a plugin activation hook reading `activationOptions`
- cleanup of the temporary activation option after activation
- a clear error when `activationOptions` is requested but no plugin PHP
file can be found
adamziel
added a commit
that referenced
this pull request
Jul 4, 2026
…#3908) ## What it does Extracts the compile-only part of the native TypeScript Blueprint v2 runner work from #3725. `compileBlueprintV2()` now turns a parsed v2 declaration into a typed `BlueprintV2ExecutionPlan` while preserving runtime metadata and `applicationOptions`. The plan records the ordered work implied by v2 fields such as `constants`, `siteOptions`, `muPlugins`, `themes`, `activeTheme`, `plugins`, `fonts`, `media`, `siteLanguage`, `roles`, `users`, `postTypes`, `content`, and `additionalStepsAfterExecution`. ## Rationale This lets us review the v2 parser/compiler shape separately from execution. The current PR does **not** resolve resources, lower v2 data references into v1 resources, call v1 step handlers, or wire the plan into existing consumer data flows. Non-empty v2 plans still fail at `run()` with an explicit `UnsupportedBlueprintV2FeatureError`, so callers cannot accidentally treat parsed-but-unwired v2 declarations as executed. ## Implementation Adds `BlueprintV2ExecutionPlan` and `BlueprintV2ExecutionPlanItem` types in `lib/v2/compile.ts`. `createBlueprintV2ExecutionPlan()` mirrors the ordering from the broader TypeScript runner work while keeping each item in v2-shaped data: ```ts { type: 'defineWpConfigConsts', consts } { type: 'setSiteOptions', options } { type: 'installPlugin', plugin, sourcePath: '/plugins/0' } { type: 'runStep', step, sourcePath: '/additionalStepsAfterExecution/0' } ``` Minimal v2 declarations still compile and run as a no-op. Declarations with planned work compile successfully but reject on `run()` until follow-up PRs wire individual plan items. ## Testing instructions ```bash npm run format:uncommitted npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/compile.spec.ts npm exec nx run playground-blueprints:typecheck npm exec nx run playground-blueprints:lint npm exec nx run playground-blueprints:build npm exec nx run playground-blueprints:test:vite git diff --check ```
adamziel
added a commit
that referenced
this pull request
Jul 4, 2026
## What it does Adds the next v2-local layer after #3908: `compileBlueprintV2()` now includes a lowered `steps` array and an `unsupportedPlan` array alongside the existing v2 `plan`. In this PR, **lowering** means translating Blueprint v2 declarations into the older v1 step records that the current TypeScript runner already understands. For example, a v2 `plugins` declaration becomes an `installPlugin` step record, and a v2 `siteOptions` declaration becomes a `setSiteOptions` step record. This PR does not execute those step records yet. It only converts the supported v2 plan items into a runner-friendly shape and keeps the rest visible as unsupported work. The lowering covers many of the safe, already-understood v2 plan items: - `constants` -> `defineWpConfigConsts` - `siteOptions` -> `setSiteOptions` - `siteLanguage` -> `setSiteLanguage` - top-level `plugins` -> `installPlugin` step records - top-level `themes` / `activeTheme` -> `installTheme` step records - simple `additionalStepsAfterExecution` entries like `mkdir`, `cp`, `mv`, `rm`, `rmdir`, `defineConstants`, `setSiteOptions`, `setSiteLanguage`, `installPlugin`, `installTheme`, `activatePlugin`, `activateTheme`, `importThemeStarterContent`, and `wp-cli` Unsupported v2-only areas such as media/content/font/user/role/post-type imports remain in `unsupportedPlan` instead of being silently dropped. ## Rationale This keeps processing the larger TypeScript Blueprint v2 runner work from #3725 piece by piece. The previous PR made v2 declarations compile into an ordered v2 plan. This PR groups the v2-only translation work that does not need consumer wiring or actual runtime execution yet. The benefit is that reviewers can inspect the v2-to-v1 mapping separately from the later execution work. If a v2 declaration maps cleanly to an existing v1 step shape, this PR makes that explicit. If it does not, the plan item stays in `unsupportedPlan` for a later focused PR. It still does **not** execute the lowered steps, resolve resources at runtime, import content/media, or touch website/CLI/remote data flows. Non-empty v2 plans continue to reject at `run()` until a later PR wires execution. ## Implementation Adds `lowerBlueprintV2ExecutionPlan()` in `lib/v2/compile.ts`. It returns: ```ts { steps: StepDefinition[], unsupportedPlan: BlueprintV2ExecutionPlan } ``` The lowering layer: - walks the ordered v2 execution plan - converts supported plan items to existing `StepDefinition` records - keeps unsupported items in `unsupportedPlan` - converts plugin/theme data references into existing v1 resource shapes - normalizes target-site paths for simple file steps - rejects empty paths and parent-directory traversal before producing v1 paths Plugin/theme data references are lowered for WordPress.org slugs, versioned slugs, URLs, GitHub/GitLab repo URLs, execution-context paths, inline files, inline directories, and git directory objects. ## Testing instructions ```bash npm run format:uncommitted npm exec nx run playground-blueprints:test:vite -- --testFiles=packages/playground/blueprints/src/tests/compile.spec.ts npm exec nx run playground-blueprints:typecheck npm exec nx run playground-blueprints:lint npm exec nx run playground-blueprints:build git diff --check ```
adamziel
added a commit
that referenced
this pull request
Jul 11, 2026
## What Load custom `wordpressVersion` data references in TypeScript Blueprints v2. Blueprints v2 can now load WordPress from a custom ZIP, a directory embedded in the Blueprint, or a directory in Git. The ZIP can sit next to the Blueprint or be embedded in it. Directory sources are turned into ZIPs before WordPress boots. Both the browser and CLI use the supplied source instead of downloading another WordPress build. Built-in versions and HTTP(S) archives keep their existing download paths. This takes the useful source-resolution idea from #3725 without reviving that PR's compiler, validator, or migration work. ## Why The public v2 schema already accepts general data references for `wordpressVersion`, but the TypeScript runtime rejected every form except HTTP(S). A valid Blueprint could therefore validate and still fail before boot. ## Testing CI
Collaborator
Author
|
This has been merged in a series of smaller PRs, let's close it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it does
Adds a TypeScript execution path for Blueprint v2 inside
@wp-playground/blueprints.compileBlueprintForExecution()compileBlueprintV1(); v2 goes through the new compiler.compileBlueprintV2()onError, plugin activation options, WXR controls, safer install paths, and site option handling.This PR does not wire website, client, CLI, or remote data flows to the new runner. That is stacked in #3850.
Rationale
Blueprint v2 needs one reviewed runtime contract before every consumer starts using it.
The meaningful problem this solves is that v2 declarations can now be accepted and executed by the blueprints package itself, instead of requiring a separate PHP-side v2 runner path. The package can validate v2 input, derive boot requirements, load v2 data references, and execute the supported declaration by lowering it into the existing v1 step engine.
@wp-playground/blueprintsusersblueprint-v1-schema-validator.js.@wp-playground/client, CLIwp-envImplementation
compileBlueprintForExecution(input, options)detects the declaration version and dispatches to the matching compiler. The oldcompileBlueprint()export remains v1-only for compatibility.For v2, the compiler performs this flow:
The v2 compiler also supports upgrading v1 declarations through the v2 path for parity tests while preserving v1 runtime-only metadata internally.
Testing instructions
Validated locally on
adb775c99:The focused test runs passed 80 tests and 83 tests respectively.
Part of #2592.