Guides

Clean Up Workspaces

Remove workspaces by name or by filter, and reconcile state when something was deleted behind uxd's back.

Workspaces accumulate. clean removes them by name or by filter, always showing its plan first.

Remove specific workspaces

uxd my-project clean pr-42
uxd my-project clean pr-42 feat-login

Or one workspace by ref, using the workspace verb:

uxd my-project 42 rm

Remove by filter

FilterRemoves
--allEvery workspace for the project
--mergedBranches merged into the default branch (git-only check)
--closedWorkspaces whose PR is closed or merged (prefers gh)
--older-than <dur>Workspaces idle for at least <dur> (s/m/h/d/w)
uxd my-project clean --merged
uxd my-project clean --closed
uxd my-project clean --older-than 7d

Filters intersect — this removes only workspaces that are both merged and idle for a week:

uxd my-project clean --merged --older-than 7d
Explicit slugs and filters cannot be combined. Pick one or the other.

The plan and the prompt

clean prints what it is about to do and waits for confirmation:

uxd my-project clean --all
→ plan:
  feat-login (clean, 16 KB)

Approve it and the removed slugs are listed with the space reclaimed:

feat-login
→ freed 16 KB

For scripts and CI, skip the prompt:

uxd my-project clean --merged --yes

To see the plan and stop there, use --dry-run.

Safety rules

A workspace with uncommitted changes is left alone. Pass --force to remove it anyway — that discards the changes.
Working trees you adopted with a path ref are not removed by filters, because uxd did not create them. Pass --include-adopted to include them.

Reconciling drift

If a worktree was deleted outside uxd — an rm -rf, a disk cleanup — git metadata and uxd's state entry are left pointing at nothing. list shows the workspace as missing:

SLUG        KIND    BRANCH      STATUS   PORT  AGE  LAST USED
feat-login  branch  feat/login  missing  3053  2m   1m

Reconcile it with:

uxd my-project clean --prune-state --yes
→ plan:
  feat-login (missing, state-only, clean, ?)
feat-login
→ freed 1 KB

This drops state entries whose worktree is gone. clean also runs git worktree prune as part of its normal work, so the git side is handled.

--prune-state obeys the same confirmation prompt as any other clean run. Without --yes on a non-interactive terminal it exits 2 with error(E_USAGE): refusing to remove 1 workspace(s) without confirmation.

A cleanup habit

# Friday: everything that shipped, plus anything you have not touched in a fortnight
uxd my-project clean --closed --yes
uxd my-project clean --older-than 14d --yes

Check what you would reclaim first:

uxd my-project list --du