Repository navigation
feat(sweep): stop language servers with their tree - #52
Merged
Merged
Conversation
fleet-lsp starts one language server per worktree and nothing stopped it when the worktree went away: on 2026-10-29 twelve rust-analyzers of deleted worktrees had swap at 20 of 21.5 GB. worktree-sweep now stops the fleet-lsp children rooted in a worktree it removes, and every run lists (with --apply, stops) the ones whose working directory no longer exists. --lsp does only that, without forge lookups; worktree-task's teardown and abandon paths call it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
fleet-lsp starts one language server per worktree it's asked about: rust-analyzer, gopls, pyright, and the TypeScript server under node. Nothing stopped a server when its worktree went away. On 2026-10-29, twelve rust-analyzers of deleted worktrees had pushed swap to 20 of 21.5 GB, with about 17 MB of free RAM and the load near 900. Every timing test on the machine flaked.
Change (
~/.claude/tools/worktree-sweep/sweep.py):remove()reads, beforegit worktree remove, the fleet-lsp servers whose working directory is inside the worktree. It stops them after the removal succeeds: SIGTERM to the server and its descendants (tsserver runs under node), then SIGKILL after 3 s.ORPHAN-LSPservers whose working directory no longer exists, and--applystops them. Each stop is logged asLSP-STOPPED.--lsp: does only that, with no forge lookups, for use right after agit worktree removeby hand.fleet-lspprocess are touched, never an editor's own servers. fleet-lsp starts a stopped server again if that checkout is asked about.worktree-sweepskill documents this.worktree-task's teardown says the sweep stops them, and its abandon path calls--lsp --apply.Verification:
--lsplisted 4 orphans whose directories were confirmed gone, and not the 3 servers of live worktrees.--apply: stopped those 4 and their 4 tsserver children. All 8 were gone, the stops were logged, and a re-run found none. The live servers were untouched.fleet-lsp(a symlink tosh) with a child in that worktree.remove()found the server, removed the worktree and stopped it, matching/tmpagainst/private/tmp.chezmoi --source <this branch> catrenders all three laptop files byte-identical, with the template directive counts unchanged (3 and 1). No secret-shaped strings in the diff.🤖 Generated with Claude Code