Skip to content

Add wp-env project support: run partial sites (plugins/themes) from .wp-env.json#4079

Open
youknowriad wants to merge 2 commits into
trunkfrom
claude/tender-johnson-356450
Open

Add wp-env project support: run partial sites (plugins/themes) from .wp-env.json#4079
youknowriad wants to merge 2 commits into
trunkfrom
claude/tender-johnson-356450

Conversation

@youknowriad

Copy link
Copy Markdown
Contributor

Related issues

  • Related to: wp-env project support exploration

How AI was used in this PR

Built end-to-end with Claude Code, iteratively directed and reviewed by @youknowriad: spike first (both runtimes verified live before any product code), then the translator library with unit tests, then command/UI wiring, followed by a dedicated self-review pass (simplification, removal of implementation-detail tests, audit for destructive paths). Every stage was verified against a real checkout of WordPress/gutenberg.

Proposed Changes

Studio currently requires every site folder to be (or become) a full WordPress install. This PR lets Studio run partial sites — a plugin repo, a theme, or a mix — driven by the standard .wp-env.json spec, so projects like Gutenberg work out of the box:

studio create --path ~/Workspace/gutenberg
  • Project-backed sites: when the chosen folder holds a .wp-env.json, WordPress core is installed into a Studio-managed directory (~/.studio/wp-env/<siteId>) and the project's plugins / themes / mappings are linked in — symlinks on the native runtime (reusing the existing open_basedir symlink allowlisting), VFS mounts on the Playground sandbox. The user's folder is never written to, and edits are live in the running site.
  • The project file is the source of truth: core maps to Studio WP versions (WordPress/WordPress → nightly, release tags/zips → that version), phpVersion and port are honored, config becomes wp-config constants, and start recomputes everything so .wp-env.json edits apply on restart. A conflicting --wp is refused (pointing at .wp-env.override.json, the wp-env-native escape hatch); PHP stays user-choosable with the divergence surfaced.
  • All entry points adapt: CLI prompts skip the WP version for wp-env projects; both create forms (desktop and studio ui) detect the folder, lock the WordPress version field, default PHP from the file, and show what the project contributes. status shows the WordPress path and file-owned values.
  • Safety: delete never trashes the project folder (only the technical directory); sync/push/pull/export/import/copy are refused for wp-env sites until designed properly (they'd operate on the project folder or archive through symlinks).

Trade-offs made (flagged for review):

  • core: "WordPress/WordPress" (trunk) maps to nightly — closest available equivalent.
  • mappings onto directories that already exist in the install (e.g. wp-content/mu-plugins, which holds Studio's SQLite integration) merge children instead of shadowing the directory as Docker wp-env does.
  • Unsupported wp-env fields (multisite, lifecycleScripts, env.tests, remote sources, local core checkouts) warn or fail with explicit errors rather than being silently approximated.

Scope note for reviewers: this crosses several boundaries — a new shared library (packages/common/lib/wp-env/), CLI commands (create/start/status/config set + guards), the Electron main process (folder-validation IPC), and both create forms (desktop renderer + apps/ui, including a new POST /paths/inspect endpoint on the local web server for typed paths).

Known follow-ups (not in this PR): remote plugin/theme sources, local core checkouts, sync/export support design, desktop wp-env badge/UX polish, verification of junctions on real Windows.

Testing Instructions

CLI (needs npm run cli:build):

  1. node apps/cli/dist/cli/main.mjs create --path <gutenberg checkout> — expect "Using .wp-env.json: WordPress nightly…", plugin active in wp-admin, served from your checkout (edits are live).
  2. studio status --path <checkout> — expect a WordPress Path row and "(from .wp-env.json)" annotations.
  3. studio config set --path <checkout> --wp 6.8 — expect refusal pointing at .wp-env.override.json.
  4. studio delete --path <checkout> --files — expect the checkout to survive; only ~/.studio/wp-env/<id> is trashed.
  5. Also works with a minimal project: a folder holding .wp-env.json with { "plugins": [ "." ] } and a plugin file.

UIs:
6. Desktop: Add site → pick a wp-env folder — expect the wp-env notice, a locked WordPress version field, PHP defaulted from the file; Sync and Import/Export tabs hidden for the created site.
7. studio ui: create form → type the project path into Local path and blur — same adaptation (screenshot below).

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

🤖 Generated with Claude Code

Comment thread packages/common/lib/wp-env/config.ts Dismissed
Comment thread packages/common/lib/wp-env/config.ts Dismissed
Comment thread packages/common/lib/wp-env/config.ts Dismissed
Comment thread packages/common/lib/wp-env/config.ts Dismissed
…wp-env.json

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@youknowriad youknowriad force-pushed the claude/tender-johnson-356450 branch from 8c5f668 to c4a581e Compare July 3, 2026 16:26
…t endpoint

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@youknowriad

Copy link
Copy Markdown
Contributor Author

On the CodeQL js/path-injection alerts (4× in packages/common/lib/wp-env/config.ts):

Assessment: these flag user-chosen folder paths flowing into filesystem reads. The reads are confined to fixed filenames (.wp-env.json / .wp-env.override.json) appended to a directory the user selected — there is no filename injection, and "any directory the user chooses" is the feature's contract (same model as the existing folder-validation IPC and /paths/compare), so no prefix containment is possible by design. The only network-reachable source is the studio ui local server, which is loopback-bound and Origin-checked.

Hardening applied in 2621740: POST /paths/inspect now rejects non-absolute paths and normalizes with path.resolve() before any probe.

Given the 9 previously dismissed alerts of this same rule in the repo, I'd suggest dismissing these four as won't fix (by design) — leaving that call to a maintainer.

@youknowriad

Copy link
Copy Markdown
Contributor Author

@jorgefilipecosta @talldan this might be of interest for you. I'm trying to make Studio CLI and Studio app support projects using .wp-env by default. I'd love some testing.

@f This PR in theory allows plugin only and theme only projects (if a wp-env.json is provided in the folder). I guess it can be some kind of first step towards pressship kind of features.

@youknowriad youknowriad marked this pull request as ready for review July 3, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants