* 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
43 lines
1.2 KiB
TypeScript
43 lines
1.2 KiB
TypeScript
import { confirmRiskyWorktreeArchive, toWorktreeArchiveRisk } from "@/git/worktree-archive-warning";
|
|
import type { SidebarWorkspaceEntry } from "@/hooks/use-sidebar-workspaces-list";
|
|
import type { WorkspaceArchiveTarget } from "@/workspace/workspace-archive";
|
|
|
|
export interface ProjectWorkspaceArchiveEntry extends Pick<
|
|
SidebarWorkspaceEntry,
|
|
| "serverId"
|
|
| "workspaceId"
|
|
| "workspaceKind"
|
|
| "name"
|
|
| "archiveHasUncommittedChanges"
|
|
| "archiveUnpushedCommitCount"
|
|
| "diffStat"
|
|
> {}
|
|
|
|
type ConfirmWorktreeArchive = typeof confirmRiskyWorktreeArchive;
|
|
|
|
export async function selectProjectWorkspacesToArchive(
|
|
workspaces: ProjectWorkspaceArchiveEntry[],
|
|
confirmWorktreeArchive: ConfirmWorktreeArchive = confirmRiskyWorktreeArchive,
|
|
): Promise<WorkspaceArchiveTarget[]> {
|
|
const confirmed: WorkspaceArchiveTarget[] = [];
|
|
|
|
for (const workspace of workspaces) {
|
|
if (workspace.workspaceKind === "worktree") {
|
|
const shouldArchive = await confirmWorktreeArchive({
|
|
workspaceName: workspace.name,
|
|
...toWorktreeArchiveRisk(workspace),
|
|
});
|
|
if (!shouldArchive) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
confirmed.push({
|
|
serverId: workspace.serverId,
|
|
workspaceId: workspace.workspaceId,
|
|
});
|
|
}
|
|
|
|
return confirmed;
|
|
}
|