Add preview environments: CoW provisioner and preview tools - #79
Open
christianc1 wants to merge 1 commit into
Open
christianc1 wants to merge 1 commit into
christianc1 wants to merge 1 commit into
Conversation
Coverage Report
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
christianc1
force-pushed
the
feature/preview-environments
branch
from
August 21, 2026 13:53
a5d1d9b to
59848da
Compare
Adds preview_start / preview_list / preview_destroy MCP tools that clone a site into a disposable, isolated preview: copy-on-write file and DB copies on APFS (filtered copy fallback elsewhere), our own provision sequence built from Local's cradle services, domain rewrite that survives mu-plugin WP_CLI guards, per-preview object-cache prefixing, and parent-pointing symlink retargeting. Previews are tagged from birth so preview_destroy can always clean up, and refuse to delete regular sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
christianc1
force-pushed
the
feature/preview-environments
branch
from
August 21, 2026 14:00
59848da to
a9fe448
Compare
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
Three new MCP tools that give agents disposable, isolated clones of a Local site:
preview_start— clones a site (optionalsiteId, defaults to the endpoint's site) into a preview with its own database, PHP/MySQL processes, domain, and logs, and returns the preview's own MCP endpoint URL. Callers pass a purposelabel("Polylang Fix", "player-v3") and the site is named<Parent Name> - <label>so humans can identify previews in Local's sidebar.preview_list— lists previews with parent site id and MCP URL, so orphans stay visible.preview_destroy— deletes a preview (files to trash); hard-refuses any site not created bypreview_start.Why
Two agent sessions sharing one Local site trample each other: concurrent WP-CLI writes, mixed error logs, one checked-out branch. Previews give each session (e.g. each git worktree) its own environment.
Why not Local's own CloneSite service
Live testing on a real 1.5G multisite showed
cloneSite: copies the entire site dir includingnode_modules/.git, resolvesundefinedon failure while work continues in background, pops a blocking native error dialog headless callers can't dismiss, and its hardcoded--skip-pluginssearch-replace dies on sites whose mu-plugins guard on plugin presence. The new provisioner mirrors CloneSite's sequence using the same cradle services, but owns each step.Key implementation points
cp -Rcclonefile) on APFS for both the file tree and the MySQL data dir — a 1.5G multisite clones in ~76s wall clock with megabytes of physical disk cost. Non-APFS/Windows falls back to a filtered copy that skipsnode_modules/.git. (src/helpers/fast-copy.ts)search-replacepass (subsumes protocol variants; single pass because the tool scans every table per pass) executed with mu-plugins neutralized via--exec=define("WPMU_PLUGIN_DIR", …)— required because some mu-plugins callWP_CLI::error()at registration when a dependency plugin isn't loaded. Plus a literal domain rewrite inwp-config.php(covers multisiteDOMAIN_CURRENT_SITE), withchangeSiteDomainToHostas a non-fatal finisher.WP_REDIS_PREFIX/WP_CACHE_KEY_SALT(shared persistent object caches otherwise serve the parent's cached data to the preview) and retargeting of absolute symlinks that still point into the parent tree (e.g. Query Monitor'sdb.php, which otherwise double-loads its autoloader and fatals).agentToolsPreview/agentToolsPreviewOfbefore any copying, so even a failed provision is listable and destroyable; inheritedagentToolsEnabled*options are stripped. Previews re-register with the MCP server after a Local restart.selectSite, so a background preview doesn't steal the user's selection),haltedstatus on step failure, and per-step timing logged throughlocalLoggerso every run benchmarks itself inlocal-lightning.log.siteIdto operate on any other registered site. This is the working agent flow: a session connected to the primary site's endpoint spins up a preview, then runswp_cli/read_error_logagainst it by id — no client reconnect. Environment tools keep their ownsiteIdrouting (they may target unregistered sites).execWpCliextracted from thewp_clitool as a reusable runner (skip flags, mu-plugin neutralization, timeout);wp_clitool behavior unchanged from Don't auto-skip plugins/themes in wp_cli #63 (no default skips).Testing
wp_blogs), parent untouched.Known limitations / follow-ups
preview_starton large sites can exceed MCP client tool timeouts (the clone still completes server-side; a retry then reports the name collision). Follow-up: fast-return + status polling.localLogger.🤖 Generated with Claude Code