Clean VM
Use this skill when repeated loop, Claude, or Codex runs leave the machine in a bad state.
Start with the bundled script. It does a dry run by default and only mutates the machine with --apply.
Default Workflow
- Run a dry run first:
python3 .agents/skills/clean-vm/scripts/clean_vm.py
- Review the report. The script only targets:
- loop manifests under
~/.loop/runs/<repoId>
- direct
loop __bridge-mcp <runDir> <claude|codex> processes for stale runs
- loop helper processes tied to stale run dirs
- Next.js and Storybook servers running inside stale loop worktrees
- loop-created worktrees from
git worktree list --porcelain
- Apply the cleanup once the plan looks safe:
python3 .agents/skills/clean-vm/scripts/clean_vm.py --apply
- Only close browser windows when the user explicitly wants browser cleanup:
python3 .agents/skills/clean-vm/scripts/clean_vm.py --apply --browsers
Safety Rules
- Always inspect the dry run before using
--apply.
- Treat loop manifests in
~/.loop/runs as the source of truth for paired runs.
- Keep any run whose manifest state is
submitted, working, reviewing, or input-required and whose pid or tmuxSession is still live.
- Never mass-kill
claude, codex, or node. Kill only per PID after the script proves the process belongs to stale loop state.
- Never remove the main worktree, the worktree containing the current
pwd, or a dirty worktree.
- The script does not auto-force worktree removal. If a plain
git worktree remove fails, it reports the failure and leaves escalation to a manual follow-up.
- Treat any live tmux session as in use even if the manifest looks stale.
- Browser cleanup is opt-in and macOS-only.
What the Script Checks
- repo identity via
git rev-parse --git-common-dir, using the same repo id scheme as loop
- run manifests under
~/.loop/runs
- tmux liveness with exact session targets like
tmux has-session -t =<name> plus a live-pane check from tmux list-panes
- helper processes whose command line references a stale run dir
- direct loop bridge MCP server processes whose run dir is stale or orphaned
- dev servers matching
next dev, next-server, storybook, or start-storybook
- worktrees from
git worktree list --porcelain
Manual Fallback
If the script cannot classify something safely, leave it alone and inspect it manually:
tmux ls 2>/dev/null
tmux list-panes -a -F '#{session_name} #{pane_dead} #{pane_current_command} #{pane_current_path}' 2>/dev/null
git worktree list --porcelain
lsof -nP -iTCP -sTCP:LISTEN | grep -E 'next|storybook|node'
ps -axo pid=,tty=,command= | grep -E 'claude|codex|next dev|storybook'
Useful loop states:
- active:
submitted, working, reviewing, input-required
- inactive:
completed, failed, stopped
If a manifest claims to be active but its pid is gone and its exact tmux session is missing or every pane in that exact session is dead, treat it as stale.
Report
End with a short cleanup report that includes:
- processes killed, with PID and reason
- dev servers stopped, with cwd and reason
- browser actions taken or skipped
- worktrees pruned or removed
- anything suspicious you left alone because it was active, dirty, or ambiguous
If any item is ambiguous, prefer skipped over cleaned.
1---2name: clean-vm3description: Safely clean the local loop VM by reporting and removing stale loop runs, inactive Next.js or Storybook servers, optional browser windows, and unused loop-created worktrees without disturbing active tmux-backed sessions.4---56# Clean VM78Use this skill when repeated loop, Claude, or Codex runs leave the machine in a bad state.9Start with the bundled script. It does a dry run by default and only mutates the machine with `--apply`.1011## Default Workflow12131. Run a dry run first:1415```bash16python3 .agents/skills/clean-vm/scripts/clean_vm.py17```18192. Review the report. The script only targets:2021- loop manifests under `~/.loop/runs/<repoId>`22- direct `loop __bridge-mcp <runDir> <claude|codex>` processes for stale runs23- loop helper processes tied to stale run dirs24- Next.js and Storybook servers running inside stale loop worktrees25- loop-created worktrees from `git worktree list --porcelain`26273. Apply the cleanup once the plan looks safe:2829```bash30python3 .agents/skills/clean-vm/scripts/clean_vm.py --apply31```32334. Only close browser windows when the user explicitly wants browser cleanup:3435```bash36python3 .agents/skills/clean-vm/scripts/clean_vm.py --apply --browsers37```3839## Safety Rules4041- Always inspect the dry run before using `--apply`.42- Treat loop manifests in `~/.loop/runs` as the source of truth for paired runs.43- Keep any run whose manifest state is `submitted`, `working`, `reviewing`, or `input-required` and whose `pid` or `tmuxSession` is still live.44- Never mass-kill `claude`, `codex`, or `node`. Kill only per PID after the script proves the process belongs to stale loop state.45- Never remove the main worktree, the worktree containing the current `pwd`, or a dirty worktree.46- The script does not auto-force worktree removal. If a plain `git worktree remove` fails, it reports the failure and leaves escalation to a manual follow-up.47- Treat any live tmux session as in use even if the manifest looks stale.48- Browser cleanup is opt-in and macOS-only.4950## What the Script Checks5152- repo identity via `git rev-parse --git-common-dir`, using the same repo id scheme as loop53- run manifests under `~/.loop/runs`54- tmux liveness with exact session targets like `tmux has-session -t =<name>` plus a live-pane check from `tmux list-panes`55- helper processes whose command line references a stale run dir56- direct loop bridge MCP server processes whose run dir is stale or orphaned57- dev servers matching `next dev`, `next-server`, `storybook`, or `start-storybook`58- worktrees from `git worktree list --porcelain`5960## Manual Fallback6162If the script cannot classify something safely, leave it alone and inspect it manually:6364```bash65tmux ls 2>/dev/null66tmux list-panes -a -F '#{session_name} #{pane_dead} #{pane_current_command} #{pane_current_path}' 2>/dev/null67git worktree list --porcelain68lsof -nP -iTCP -sTCP:LISTEN | grep -E 'next|storybook|node'69ps -axo pid=,tty=,command= | grep -E 'claude|codex|next dev|storybook'70```7172Useful loop states:7374- active: `submitted`, `working`, `reviewing`, `input-required`75- inactive: `completed`, `failed`, `stopped`7677If a manifest claims to be active but its `pid` is gone and its exact tmux session is missing or every pane in that exact session is dead, treat it as stale.7879## Report8081End with a short cleanup report that includes:8283- processes killed, with PID and reason84- dev servers stopped, with cwd and reason85- browser actions taken or skipped86- worktrees pruned or removed87- anything suspicious you left alone because it was active, dirty, or ambiguous8889If any item is ambiguous, prefer `skipped` over `cleaned`.