From 1cd4e7f6680146c5602e12c3c23e9c0d6849d54a Mon Sep 17 00:00:00 2001 From: Chris Wanstrath Date: Fri, 20 Feb 2026 07:40:02 -0800 Subject: [PATCH] add cleanup command to remove stale sessions with missing worktrees --- src/cli.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/cli.ts b/src/cli.ts index ec30cd3..361a246 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -4,6 +4,7 @@ import { Command } from "commander" import { $} from "bun" import { basename, join } from "path" import { homedir } from "os" +import { existsSync } from "fs" import { mkdir, symlink, unlink } from "fs/promises" import * as git from "./git.ts" import * as vm from "./vm.ts" @@ -598,6 +599,35 @@ program process.stdout.write(session.worktree + "\n") }) +// ── sandlot cleanup ───────────────────────────────────────────────── + +program + .command("cleanup") + .description("Remove stale sessions whose worktrees no longer exist") + .action(async () => { + const root = await git.repoRoot() + const st = await state.load(root) + const sessions = Object.values(st.sessions) + + if (sessions.length === 0) { + console.log("No sessions to clean up.") + return + } + + const stale = sessions.filter(s => !existsSync(s.worktree)) + + if (stale.length === 0) { + console.log("No stale sessions found.") + return + } + + for (const s of stale) { + await state.removeSession(root, s.branch) + await unlink(join(root, '.sandlot', s.branch)).catch(() => {}) + console.log(`✔ Removed stale session: ${s.branch}`) + } + }) + // ── sandlot vm ─────────────────────────────────────────────────────── const vmCmd = program.command("vm").description("Manage the sandlot VM")