Automattic / Automattic/studio

Feature Request: plugin and theme link management via CLI

Open
#3,121 5 comments 0 reactions 1 assignee Claimed by @cbravobernal View on GitHub
Enhancement OSS Citizen Proof of Concept
Dominant language
TypeScript
Stars
517
Forks
95
Avg merge
1d 22h
Merged PRs (30d)
162

Description

## TL;DR (caveman)

CLI commands. Symlink external plugin/theme source → Studio site `wp-content/plugins` or `wp-content/themes`.

* `studio plugin link [source]` / `unlink [plugin]` / `list-linked`
* `studio theme link [source]` / `unlink [theme]` / `list-linked`

No args inside plugin/theme folder → source = cwd. Opens picker listing all Studio sites. No need `--path`. Non-interactive shell (CI, piped stdin) → original error. Automation fail loud.

**Why:** devs keep one plugin/theme outside any site, test across many Studio sites (different WP/PHP/theme/data). Copy breaks feedback loop. Symlink = one source of truth. CLI right surface — plugin/theme dev already in terminal. Complements [STU-750](https://linear.app/a8c/issue/STU-750/feature-request-add-symbolic-link-functionality-in-the-ui).

**How:**

* Validation: plugin source needs PHP file with `Plugin Name:` header. Theme needs `style.css` with `Theme Name:` header.
* Symlinks relative (portable). Windows `EPERM` → fallback directory junction. No admin needed.
* `unlink` removes symlink node only. Never source files. Refuse regular dirs.
* Idempotent: same source twice → "already linked", exit 0. Different source on occupied name → clear error.

---

# Long version

### Warning

Vibewritten-coded - needs review

### What

Add a set of Studio CLI commands to manage symbolic links between an external plugin or theme source directory and a local Studio site's `wp-content/plugins` or `wp-content/themes` folder:

* `studio plugin link [source]` / `studio plugin unlink [plugin]` / `studio plugin list-linked`
* `studio theme link [source]` / `studio theme unlink [theme]` / `studio theme list-linked`

When run inside a plugin or theme folder without arguments, the CLI defaults the source to the current directory and opens an interactive picker listing every local Studio site so the target can be chosen without passing `--path`. Non-interactive shells (CI, piped stdin) preserve the original error so automation fails loud.

### Why

Developers commonly maintain a single plugin or theme source outside any specific site (e.g. `~/Developer/wp-plugins/secure-custom-fields`) and need to exercise that code against multiple Studio sites: different WordPress versions, PHP versions, themes, or datasets. Copying the source into each site breaks the feedback loop because edits land in a copy and must be kept in sync by hand. Symlinks give one source of truth; a CLI is the right surface because plugin / theme development already happens from the terminal.

This complements [STU-750](https://linear.app/a8c/issue/STU-750/feature-request-add-symbolic-link-functionality-in-the-ui) (UI-side symlink support) by giving CLI-centric workflows a first-class path while the UI version is still being designed.

### How

* Source validation: plugin source must contain a PHP file with a `Plugin Name:` header; theme source must contain `style.css` with a `Theme Name:` header.
* Symlinks are relative by default (portable). On Windows, falls back to a directory junction when `EPERM` is raised so admin privileges are not required.
* `unlink` only removes the symlink node, never the resolved source files. Refuses to operate on regular (non-symlink) directories.
* Idempotency: linking the same source twice reports "already linked" and exits success. Linking a different source to an occupied name raises a clear error.

A Proof-of-Concept implementation is in preparation as a draft PR; design doc will live at `docs/design-docs/plugin-theme-link.md`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.