fix(host-service): remove a git-unregistered-but-left-on-disk worktree on delete
Fixes #6730
What & why
Two fixes for the workspace-delete saga in #6730:
1. Orphaned-worktree cleanup (workspace-cleanup.ts).
git worktree remove --force is not atomic: it can fully unregister a
worktree (so it no longer appears in git worktree list → stillRegistered = false) while still failing to delete the working directory when a nested file
is undeletable (Operation not permitted, e.g. chflags uchg). The destroy
saga trusted stillRegistered alone and set worktreeRemoved = true, then
archived the row — leaving a silently orphaned folder on disk with no git
record of it. The repo-missing and session branches in the same saga already do
an existsSync → rm fallback under the managed-worktrees root guard; this
wires that same fallback into the common "project + repo present" path.
2. Logging the underlying git error (workers/tasks/git.ts).
The real git failure was swallowed by .catch(() => {}), so the toast text was
the only diagnostic and nothing reached host-service.log. It's now captured and
logged via console.warn (the existing host-service pattern) with the target
path, so the cause is discoverable when a folder is left orphaned.
How I tested it
- New unit test in
packages/host-service/test/workspace-cleanup.test.ts:
removeWorktreereturns{ stillRegistered: false }while the worktree's
directory exists on disk → asserts the directory is gone after destroy. bun test packages/host-service/test/→ 308 pass, 0 fail (workspace-cleanup
suite 26/26).bun x tsc --noEmitclean on the changed files.- Also threaded a
hostWorktreeBaseDiroption throughmakeCtxso
getHostWorktreeBaseDirreturns a value in the test harness (the live
host-settings lookup was previously untestable there).
Note: #6730's point 1 (git's non-atomic unregister/delete) is a git behavior we
cannot change in-repo; this PR covers points 2 and 3.
Checklist
- PR title follows conventional commits (
type(scope): subject) -
bun run lintandbun run typecheckpass - "Allow edits from maintainers" is checked on fork PRs
Summary by CodeRabbit
- Bug Fixes
- Improved workspace cleanup for directories that remain after Git unregisters a worktree.
- Safely removes leftover directories within the managed workspace area.
- Preserves directories outside the managed area and warns when cleanup is skipped.
- Cleanup status now accurately reflects whether removal succeeded.
- Reports cleanup failures appropriately instead of indicating successful removal.
- Added clearer warnings when forced worktree removal fails, including the affected location and error details.