Skip to content

Add studio uninstall command for the standalone CLI - #3974

Merged
bcotrim merged 3 commits into
trunkfrom
stu-1938-add-cli-uninstall-command
Jun 29, 2026
Merged

Add studio uninstall command for the standalone CLI#3974
bcotrim merged 3 commits into
trunkfrom
stu-1938-add-cli-uninstall-command

Conversation

@bcotrim

@bcotrim bcotrim commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Related issues

How AI was used in this PR

Used Claude Code to confirm the standalone install layout against the live wpcom-hosted install.sh/install.ps1 (paths aren't in this repo), scaffold the uninstall subcommand and tests, and diagnose the stale cross-channel update banner (live-probed the updates endpoint to confirm the server was correct and the cache was at fault). All code was reviewed by the author.

Proposed Changes

The standalone curl/irm one-liner installs the Studio CLI but there was no matching way to remove it (raised during nightly testing). This adds a discoverable, offline, cross-platform studio uninstall:

  • Removes the installed bundle and takes studio off PATH. On macOS/Linux it deletes its own runtime in place and removes the ~/.local/bin/studio symlink (leaving the shell-profile PATH line, which the desktop app also relies on). On Windows — where the running node.exe can't delete itself — a detached helper finishes the removal after exit and strips the PATH registry entry the installer added.
  • Stops running sites and the daemon first so nothing holds open handles on the runtime being removed.
  • Preserves user data (~/.studio — sites, config) by default; --purge/--all removes it too, with a confirmation prompt.
  • Only acts on standalone installs; npm and desktop-embedded installs get pointed at the right uninstall path instead.

It also fixes a related bug surfaced while testing: a production CLI could show an update banner offering a -dev nightly. The standalone update-check cache lives in the shared ~/.studio config, so reinstalling a different channel onto the same directory reused the previous channel's cached result for up to 24h. The cache is now ignored when its channel differs from the running CLI's, so the server stays the source of truth.

Testing Instructions

Build a standalone bundle and install it locally:

npm run cli:bundle -- darwin arm64   # or your platform/arch
curl -fsSL https://public-api.wordpress.com/wpcom/v2/studio-app/install.sh \
  | STUDIO_CLI_URL="$(pwd)/standalone-bundles" bash

Then, in a new shell:

  • studio uninstall — confirm bin/, cli/, and the ~/.local/bin/studio symlink are removed, studio is gone from PATH, and ~/.studio config/sites are kept.
  • Reinstall, then studio uninstall --purge — confirm it prompts before deleting ~/.studio, and removes it on confirmation.
  • Start a site, then studio uninstall — confirm sites/daemon stop before removal.
  • Run studio uninstall from an npm install (npm i -g wp-studio) and a desktop-embedded build — confirm it does nothing destructive and prints the correct guidance.
  • Windows (needs manual cross-platform verification): confirm the detached helper removes the bundle after the process exits and strips the <install>\bin entry from the user PATH registry.

Unit tests: npm test -- apps/cli/commands/tests/uninstall.test.ts apps/cli/lib/tests/update-notifier.test.ts

Note: this PR also carries a small drive-by fix to the standalone update notifier (the cross-channel cache guard), which is STU-1772 scope — bundled here because it's a one-line correctness fix surfaced during this work.

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?
@bcotrim bcotrim self-assigned this Jun 26, 2026
@bcotrim
bcotrim requested review from a team and fredrikekelund June 26, 2026 12:07
@wpmobilebot

wpmobilebot commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing 131072d vs trunk

app-size

Metric trunk 131072d Diff Change
App Size (Mac) 1315.56 MB 1315.56 MB +0.00 MB ⚪ 0.0%

site-editor

Metric trunk 131072d Diff Change
load 1057 ms 1074 ms +17 ms ⚪ 0.0%

site-startup

Metric trunk 131072d Diff Change
siteCreation 6490 ms 6504 ms +14 ms ⚪ 0.0%
siteStartup 6505 ms 7000 ms +495 ms 🔴 7.6%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

@fredrikekelund fredrikekelund left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested on Windows yet, but this looks good to me and works as expected on macOS 👍

I left a few comments that'd be nice to address, but I'll let you address the ones you think are relevant without waiting for another review from me, @bcotrim

Comment thread apps/cli/commands/uninstall.ts
Comment on lines +127 to +130
if ( removeConfig ) {
fs.rmSync( configDir, { recursive: true, force: true } );
removed.push( configDir );
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's trash it instead.

Comment thread apps/cli/commands/uninstall.ts
Comment thread apps/cli/commands/uninstall.ts Outdated
Comment thread apps/cli/lib/update-notifier.ts Outdated
Comment thread apps/studio/package.json
bcotrim added 2 commits June 29, 2026 10:22
Adds a `studio uninstall` subcommand that removes a curl-installed standalone CLI bundle and its PATH entry, keeping user config unless --purge is passed. Also fixes a stale cross-channel update banner by making the standalone update cache channel-aware.
@bcotrim
bcotrim force-pushed the stu-1938-add-cli-uninstall-command branch from d3c856c to d074394 Compare June 29, 2026 09:23
@bcotrim
bcotrim enabled auto-merge (squash) June 29, 2026 09:58
@bcotrim
bcotrim merged commit 47e5f21 into trunk Jun 29, 2026
11 checks passed
@bcotrim
bcotrim deleted the stu-1938-add-cli-uninstall-command branch June 29, 2026 10:03
gcsecsey pushed a commit that referenced this pull request Jun 29, 2026
## Related issues

- Fixes STU-1938

## How AI was used in this PR

Used Claude Code to confirm the standalone install layout against the
live wpcom-hosted `install.sh`/`install.ps1` (paths aren't in this
repo), scaffold the `uninstall` subcommand and tests, and diagnose the
stale cross-channel update banner (live-probed the updates endpoint to
confirm the server was correct and the cache was at fault). All code was
reviewed by the author.

## Proposed Changes

The standalone curl/irm one-liner installs the Studio CLI but there was
no matching way to remove it (raised during nightly testing). This adds
a discoverable, offline, cross-platform `studio uninstall`:

- Removes the installed bundle and takes `studio` off PATH. On
macOS/Linux it deletes its own runtime in place and removes the
`~/.local/bin/studio` symlink (leaving the shell-profile PATH line,
which the desktop app also relies on). On Windows — where the running
`node.exe` can't delete itself — a detached helper finishes the removal
after exit and strips the PATH registry entry the installer added.
- Stops running sites and the daemon first so nothing holds open handles
on the runtime being removed.
- Preserves user data (`~/.studio` — sites, config) by default;
`--purge`/`--all` removes it too, with a confirmation prompt.
- Only acts on standalone installs; npm and desktop-embedded installs
get pointed at the right uninstall path instead.

It also fixes a related bug surfaced while testing: a production CLI
could show an update banner offering a `-dev` nightly. The standalone
update-check cache lives in the shared `~/.studio` config, so
reinstalling a different channel onto the same directory reused the
previous channel's cached result for up to 24h. The cache is now ignored
when its channel differs from the running CLI's, so the server stays the
source of truth.

## Testing Instructions

Build a standalone bundle and install it locally:

```bash
npm run cli:bundle -- darwin arm64   # or your platform/arch
curl -fsSL https://public-api.wordpress.com/wpcom/v2/studio-app/install.sh \
  | STUDIO_CLI_URL="$(pwd)/standalone-bundles" bash
```

Then, in a new shell:

- `studio uninstall` — confirm `bin/`, `cli/`, and the
`~/.local/bin/studio` symlink are removed, `studio` is gone from PATH,
and `~/.studio` config/sites are kept.
- Reinstall, then `studio uninstall --purge` — confirm it prompts before
deleting `~/.studio`, and removes it on confirmation.
- Start a site, then `studio uninstall` — confirm sites/daemon stop
before removal.
- Run `studio uninstall` from an npm install (`npm i -g wp-studio`) and
a desktop-embedded build — confirm it does nothing destructive and
prints the correct guidance.
- **Windows** (needs manual cross-platform verification): confirm the
detached helper removes the bundle after the process exits and strips
the `<install>\bin` entry from the user PATH registry.

Unit tests: `npm test -- apps/cli/commands/tests/uninstall.test.ts
apps/cli/lib/tests/update-notifier.test.ts`

> Note: this PR also carries a small drive-by fix to the standalone
update notifier (the cross-channel cache guard), which is STU-1772 scope
— bundled here because it's a one-line correctness fix surfaced during
this work.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?
@gcsecsey gcsecsey mentioned this pull request Jun 29, 2026
1 task
gcsecsey added a commit that referenced this pull request Jun 30, 2026
## Related issues

<!--
Link a related issue to this PR. If the PR does not immediately resolve
the issue,
for example, it requires a separate deployment to production, avoid
using the "Fixes" keyword and use "Related to" instead.
-->

- N/A

## How AI was used in this PR

Claude compared previous release-note sections and release-note PR
descriptions, and drafted the curated 1.12.0 wording. The wording was
reviewed in-thread before updating the PR.

## Proposed Changes

- Replace the generated `1.12.0` release-note block with a shorter,
user-facing summary.
- Added the two PRs cherry-picked onto the release branch after code
freeze: #3974 and #3988
- Folded all dependency/dependabot bumps into a single "Updated multiple
dependencies" line.
- Omitted internal-only PRs (test/CI infra, `AGENTS.md`/`STUDIO.md`
docs, pure refactors, and the experimental Studio Web / "hosted"
groundwork).


## Testing Instructions

- Read the `1.12.0` section of `RELEASE-NOTES.txt`
- Confirm the groupings and wording read well and are accurate
- Cross-check against the merged-PR list for anything important that
should be surfaced or reworded

## Pre-merge Checklist

- [ ] Have you checked for TypeScript, React or other console errors?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants