Merge remote-tracking branch 'origin/main' into brennanb2025/cleanup-filter-apply-groups

This commit is contained in:
Brennan Benson
2026-08-24 10:47:36 -07:00
2 changed files with 48 additions and 5 deletions
@@ -132,6 +132,16 @@ function makeStore(repos: Repo[] = [REPO], allMeta: Record<string, WorktreeMeta>
} as unknown as Store
}
/** `repo-1::/repo-old` is in the shared fixture map, so pinning it needs a getWorktreeMeta override. */
function makePinnedStore(): Store {
const pinned = makeWorktreeMeta({ isPinned: true, lastActivityAt: NOW - 40 * DAY_MS })
return {
...makeStore(),
getWorktreeMeta: (worktreeId: string) =>
worktreeId === 'repo-1::/repo-old' ? pinned : META_BY_WORKTREE_ID[worktreeId]
} as Store
}
describe('workspace cleanup broad scan opt-in', () => {
beforeEach(() => {
vi.useFakeTimers()
@@ -230,6 +240,34 @@ describe('workspace cleanup broad scan opt-in', () => {
)
})
it('skips git for a pinned workspace on a broad scan, which is the cost saving', async () => {
const store = makePinnedStore()
await scanWorkspaceCleanup(store, { includeAllWorkspaces: true })
expect(getStatusMock).not.toHaveBeenCalledWith(
expect.stringContaining('/repo-old'),
expect.anything()
)
})
it('reads git for a pinned workspace on a targeted preflight, which decides force-removal', async () => {
// Why this matters: `pinned` is not a queue blocker, so a pinned idle workspace is
// hand-selectable today, and removal forces whenever git is unknown. Skipping the
// forced read meant it could be force-deleted with no evidence ever obtained.
const worktreeId = 'repo-1::/repo-old'
const result = await scanWorkspaceCleanup(makePinnedStore(), { worktreeIds: [worktreeId] })
expect(getStatusMock).toHaveBeenCalledWith(
expect.stringContaining('/repo-old'),
expect.anything()
)
const pinned = result.candidates.find((candidate) => candidate.worktreeId === worktreeId)
expect(pinned?.blockers).toContain('pinned')
expect(pinned?.git.checkedAt).not.toBeNull()
})
it('keeps the legacy suggestion-only projection when the flag is absent', async () => {
const result = await scanWorkspaceCleanup(makeStore())
+10 -5
View File
@@ -192,11 +192,16 @@ function shouldReadWorkspaceCleanupGitEvidence(args: {
if ((skipGit && !forceGitCheck) || repoIsFolder || worktree.isMainWorktree) {
return false
}
if (
blockers.includes('pinned') ||
blockers.includes('main-worktree') ||
blockers.includes('folder-repo')
) {
// Why pinned sits with the cost skips and not the refusals: a pinned workspace is
// still queueable (`pinned` is not a queue blocker), so it can reach removal -- and
// removal forces whenever git is unknown. Skipping its git read on a broad scan is a
// fair saving; skipping it on the confirm-time forced read meant deleting with no
// evidence ever obtained. main-worktree and folder-repo stay unconditional: those are
// refused before removal, so reading git for them is pure cost.
if (blockers.includes('pinned') && !forceGitCheck) {
return false
}
if (blockers.includes('main-worktree') || blockers.includes('folder-repo')) {
return false
}