WP Manifestindependent plugin directory

Local Site Worktree Router

Local Site Worktree Router — run multiple WordPress plugin branches simultaneously via git worktrees

by OpenAI · github.com/zacharyg-ms/mslwr

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/zacharyg-ms/mslwr/archive/refs/heads/main.zip

MSLWR — Local Site Worktree Router

Routes each WordPress multisite subsite to a different plugin worktree. Run multiple branches of your plugin simultaneously without switching branches or rebuilding.


How It Works

Every subsite on the multisite network normally loads plugins/membersplash/membersplash.php. MSLWR intercepts this and swaps in a different plugin directory for each site based on a per-blog option.

WordPress Multisite
  ├── site1.msdev.com  →  plugins/membersplash-wt-feature-x/   (feature branch)
  ├── site2.msdev.com  →  plugins/membersplash-wt-bugfix-y/   (bugfix branch)
  └── site3.msdev.com  →  plugins/membersplash/               (main branch)

Each worktree is a git worktree. It shares the same .git history as the main plugin repo but has its own checkout and working directory. Changes in one worktree do not affect others.

Vue dev servers run in parallel. The node container monitors a state file and starts or stops servers automatically when worktrees are activated or removed.


Admin UI

Open WordPress Tools > Local Worktree Router.

From this page you can:

Action What it does
Create Worktree + Activate Creates a new git branch from main, adds a worktree, and routes the current subsite to it.
Activate Existing Worktree Routes the current subsite to an existing worktree. No git operations.
Switch To Main Routes the current subsite back to the main plugin. Worktree stays on disk.
Delete Worktree + Use Main Removes the worktree from disk and routes back to main.
Refresh Worktree Hard-resets the worktree to match its branch tip.
Clean Stale Worktrees Removes state entries whose plugin directories no longer exist on disk. Frees up ports.
Reset All Sites to Main Resets every subsite back to the main plugin. Worktrees are preserved on disk.
Refresh Port Status Updates the Dev Server health indicators.

Dev Server Health

The Known Worktrees table shows a Dev Server column:

Indicator Meaning
Green dot :8091 Dev server is running and responding
Red dot :8091 (down) Port is assigned but server not responding
Gray dash No port assigned

Port Exhaustion

If all ports are in use, a warning banner appears at the top of the page. Free a port by deleting an unneeded worktree or running Clean Stale Worktrees.


CLI Commands

All commands use the mslwr namespace.

# Show all site assignments
wp mslwr status

# List worktrees on disk
wp mslwr list

# Create a new branch from main, add worktree, activate for current site
wp mslwr create feature/my-thing --url=deepdive.msdev.com

# Switch current site to a branch (creates worktree if needed)
wp mslwr switch feature/my-thing --url=deepdive.msdev.com

# Switch back to main
wp mslwr main --url=deepdive.msdev.com

# Activate an existing worktree (no git operations)
wp mslwr activate feature/my-thing --url=deepdive.msdev.com

# Refresh a worktree (fetch + hard reset)
wp mslwr refresh feature/my-thing

# Delete a worktree and route site back to main
wp mslwr delete feature/my-thing --url=deepdive.msdev.com --yes

# Clean stale worktree state entries
wp mslwr clean-stale

# Reset all subsites to main
wp mslwr reset-all

# Trigger a production Vue build for a worktree
wp mslwr build feature/my-thing

Capacity

Slot Vue port Route
Main 8080 vue-dev.msdev.com
Worktree 1 8091 vue-dev-1.msdev.com
Worktree 2 8092 vue-dev-2.msdev.com
Worktree 3 8093 vue-dev-3.msdev.com
Worktree 4 8094 vue-dev-4.msdev.com
Worktree 5 8095 vue-dev-5.msdev.com
Worktree 6 8096 vue-dev-6.msdev.com
Worktree 7 8097 vue-dev-7.msdev.com

Up to 8 branches simultaneously (1 main + 7 worktrees).


Architecture

┌──────────────────────────────────────────────────────────────┐
│                    MSLWR (MU Plugin)                          │
│  wp-content/mu-plugins/local-site-worktree-router.php         │
│                                                              │
│  • Monitors lwt_membersplash_branch per-blog option          │
│  • Swaps active_plugins filter to load worktree plugin       │
│  • Manages Vue state file (worktree, port, host assignments) │
│  • Serves admin UI at Tools > Local Worktree Router          │
│  • Provides wp mslwr CLI commands                            │
└──────────────────────┬───────────────────────────────────────┘
                       │ writes
                       ▼
┌───────────────────────────────────────────────┐
│           .mslwr-vue-state.json                 │
│  wp-content/.mslwr-vue-state.json              │
│                                               │
│  Maps worktree slug → {plugin_dir, vue_dir,    │
│                         port, dev_host}        │
└──────────────────────┬────────────────────────┘
                       │ polled every 2 seconds
                       ▼
┌─────────────────────────────────────────────────┐
│           node-worktree-vue-dev.sh                │
│  Runs inside node:16 Docker container            │
│                                                  │
│  • Reads state file → starts/stops dev servers   │
│  • Prunes stale entries (missing plugin dirs)    │
│  • Links node_modules to main (no duplicate npm) │
│  • Watches build trigger → runs production build │
└──────────────────────────────────────────────────┘

Vue Dev Servers

The node container manages Vue dev servers automatically. When you activate a worktree, a dev server starts on its assigned port within seconds. When you delete a worktree, the server stops.

Servers are monitored every 2 seconds. If a server crashes, it restarts automatically. If a worktree directory is removed from disk, its state entry is pruned and the server stops.

Production Builds

To run a production build instead of a dev server:

wp mslwr build feature/my-thing

This runs vue-cli-service build inside the node container, copies the output to js/vue/*.min.js and css/vue/*.min.css, then cleans up the build trigger.


Common Questions

What happens to my worktree when I switch a site to main? Nothing. The worktree stays on disk. You can activate it again later.

Can two subsites use the same worktree? No. Each worktree is assigned to one subsite at a time. A subsite can only load one plugin directory.

What if the worktree directory is deleted manually? MSLWR checks if the worktree file exists before loading it. If missing, it clears the assignment and routes back to main. The node script prunes the stale state entry automatically.

How do I free up a port? Delete the worktree or run Clean Stale Worktrees from the admin UI. The port becomes available for the next worktree.

Can I run more than 8 branches? Not with Vue dev servers. Each dev server needs a dedicated port. The container exposes 8 ports (8080, 8091 to 8097). If you do not need Vue dev servers, you can create worktrees without assigning a port by manually editing the state file. This is not supported through the UI or CLI.