fix: keep archived worktrees optimistically hidden (#640)

This commit is contained in:
Mohamed Boudra
2026-04-30 21:36:41 +08:00
committed by GitHub
parent 92afb826d9
commit 93c6c3e5f8
32 changed files with 712 additions and 112 deletions
@@ -18,6 +18,7 @@ function workspace(input: {
workspaceKind: "checkout",
name: "main",
status: "running",
archivingAt: null,
diffStat: null,
scripts: input.scripts ?? [],
};
@@ -41,6 +41,7 @@ import {
normalizeWorkspaceDescriptor,
} from "@/stores/session-store";
import { useDraftStore } from "@/stores/draft-store";
import { isLocalWorktreeArchivePending } from "@/stores/checkout-git-actions-store";
import { useWorkspaceSetupStore } from "@/stores/workspace-setup-store";
import { sendOsNotification } from "@/utils/os-notifications";
import { getIsAppActivelyVisible } from "@/utils/app-visibility";
@@ -58,6 +59,7 @@ import type { AttachmentMetadata } from "@/attachments/types";
import { splitComposerAttachmentsForSubmit } from "@/components/composer-attachments";
import { reconcilePreviousAgentStatuses } from "@/contexts/session-status-tracking";
import { patchWorkspaceScripts } from "@/contexts/session-workspace-scripts";
import { shouldSuppressWorkspaceUpsertForLocalArchive } from "@/contexts/session-workspace-upserts";
import { isNative } from "@/constants/platform";
import { useToast } from "@/contexts/toast-context";
import { toErrorMessage } from "@/utils/error-messages";
@@ -1232,6 +1234,15 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider
return;
}
const workspace = normalizeWorkspaceDescriptor(message.payload.workspace);
if (
shouldSuppressWorkspaceUpsertForLocalArchive({
serverId,
workspace,
isArchivePending: isLocalWorktreeArchivePending,
})
) {
return;
}
mergeWorkspaces(serverId, [workspace]);
});
@@ -0,0 +1,60 @@
import { describe, expect, it, vi } from "vitest";
import type { WorkspaceDescriptor } from "@/stores/session-store";
import { shouldSuppressWorkspaceUpsertForLocalArchive } from "@/contexts/session-workspace-upserts";
const baseWorkspace: WorkspaceDescriptor = {
id: "/repo/worktree",
projectId: "/repo",
projectDisplayName: "Repo",
projectRootPath: "/repo",
workspaceDirectory: "/repo/worktree",
projectKind: "git",
workspaceKind: "worktree",
name: "feature",
status: "done",
archivingAt: "2026-04-30T00:00:00.000Z",
diffStat: null,
scripts: [],
};
function workspace(input?: Partial<WorkspaceDescriptor>): WorkspaceDescriptor {
return { ...baseWorkspace, ...input };
}
describe("shouldSuppressWorkspaceUpsertForLocalArchive", () => {
it("suppresses archiving upserts for a locally pending archive", () => {
const isArchivePending = vi.fn(() => true);
expect(
shouldSuppressWorkspaceUpsertForLocalArchive({
serverId: "server-1",
workspace: workspace({ workspaceDirectory: "/repo/worktree" }),
isArchivePending,
}),
).toBe(true);
expect(isArchivePending).toHaveBeenCalledWith({
serverId: "server-1",
cwd: "/repo/worktree",
});
});
it("allows archiving upserts when this client did not start the archive", () => {
expect(
shouldSuppressWorkspaceUpsertForLocalArchive({
serverId: "server-1",
workspace: workspace(),
isArchivePending: () => false,
}),
).toBe(false);
});
it("allows normal upserts while a local archive is pending", () => {
expect(
shouldSuppressWorkspaceUpsertForLocalArchive({
serverId: "server-1",
workspace: workspace({ archivingAt: null }),
isArchivePending: () => true,
}),
).toBe(false);
});
});
@@ -0,0 +1,15 @@
import type { WorkspaceDescriptor } from "@/stores/session-store";
export function shouldSuppressWorkspaceUpsertForLocalArchive(input: {
serverId: string;
workspace: WorkspaceDescriptor;
isArchivePending: (params: { serverId: string; cwd: string }) => boolean;
}): boolean {
return (
input.workspace.archivingAt !== null &&
input.isArchivePending({
serverId: input.serverId,
cwd: input.workspace.workspaceDirectory,
})
);
}