Archive any workspace from the app (#2003)

* feat(app): expose archive for every workspace

Workspace actions now archive one workspace by id. The daemon remains responsible for backing-specific cleanup, including removing a managed worktree only after its final workspace is archived.

* refactor(app): clarify archive descriptor name

* fix(app): preserve workspace archive safety

* fix(app): allow archive without upstream

* refactor(app): remove stale archive callback

* test(app): cover workspace archive ownership
This commit is contained in:
Mohamed Boudra
2026-07-11 18:22:31 +02:00
committed by GitHub
parent ada0955334
commit 03dcda7c41
40 changed files with 369 additions and 757 deletions
@@ -144,23 +144,6 @@ describe("archiveWorkspaceOptimistically", () => {
}),
).toBe(false);
});
it("runs the after-hide hook after local state is hidden", async () => {
const archived = workspace();
useSessionStore.getState().mergeWorkspaces(SERVER_ID, [archived]);
const client = createClient(vi.fn(async () => archivePayload({ workspaceId: archived.id })));
const afterHide = vi.fn(() => {
expect(storedWorkspace(archived.id)).toBeUndefined();
});
await archiveWorkspaceOptimistically({
client,
workspace: target(),
afterHide,
});
expect(afterHide).toHaveBeenCalledOnce();
});
});
describe("archiveWorkspacesOptimistically", () => {
@@ -183,10 +166,7 @@ describe("archiveWorkspacesOptimistically", () => {
const failures = await archiveWorkspacesOptimistically({
getClient: () => client,
workspaces: [
target({ workspaceId: first.id, workspaceDirectory: first.workspaceDirectory }),
target({ workspaceId: second.id, workspaceDirectory: second.workspaceDirectory }),
],
workspaces: [target({ workspaceId: first.id }), target({ workspaceId: second.id })],
});
expect(failures).toHaveLength(1);
@@ -219,12 +199,10 @@ describe("archiveWorkspacesOptimistically", () => {
target({
serverId: SERVER_ID,
workspaceId: first.id,
workspaceDirectory: first.workspaceDirectory,
}),
target({
serverId: SECOND_SERVER_ID,
workspaceId: second.id,
workspaceDirectory: second.workspaceDirectory,
}),
],
});