Restore an archived workspace when its agent is reopened

Reopening an archived agent previously dead-ended at "workspace not
found": the agent record was un-archived but its workspace stayed
archived and was never sent to the client.

The daemon now un-archives the owning workspace alongside the agent when
its backing directory still exists, and the app auto-fires the restore
ahead of the missing-workspace gate so the user lands back in the
workspace rather than a dead end.

Worktrees whose directory was deleted on archive are not yet restorable
(recreating them from their branch is a follow-up); the workspace record
now persists its base branch as groundwork for that.
This commit is contained in:
Mohamed Boudra
2026-06-18 20:44:56 +07:00
parent fe15b68e06
commit 31fcde2ea6
22 changed files with 778 additions and 17 deletions
@@ -71,7 +71,11 @@ import { useToast } from "@/contexts/toast-context";
import { useExplorerOpenGesture } from "@/hooks/use-explorer-open-gesture";
import { selectIsFileExplorerOpen, usePanelStore } from "@/stores/panel-store";
import { type ExplorerCheckoutContext } from "@/stores/explorer-checkout-context";
import { useSessionStore, type WorkspaceDescriptor } from "@/stores/session-store";
import {
useSessionStore,
useWorkspaceRestoreStatus,
type WorkspaceDescriptor,
} from "@/stores/session-store";
import {
buildWorkspaceTabPersistenceKey,
collectAllTabs,
@@ -1487,6 +1491,7 @@ function useWorkspaceRouteActions(normalizedServerId: string): {
function useResolvedWorkspaceRouteState(input: {
serverId: string;
workspaceId: string;
workspace: WorkspaceDescriptor | null;
hasHydratedWorkspaces: boolean;
}): WorkspaceRouteState {
@@ -1497,6 +1502,7 @@ function useResolvedWorkspaceRouteState(input: {
);
const hostSnapshot = useHostRuntimeSnapshot(input.serverId);
const hostName = useMemo(() => getHostDisplayName(host, input.serverId), [host, input.serverId]);
const restoreStatus = useWorkspaceRestoreStatus(input.serverId, input.workspaceId);
return useMemo(
() =>
@@ -1506,6 +1512,7 @@ function useResolvedWorkspaceRouteState(input: {
lastError: hostSnapshot?.lastError ?? null,
workspace: input.workspace,
hasHydratedWorkspaces: input.hasHydratedWorkspaces,
restoreStatus,
}),
[
hostName,
@@ -1513,6 +1520,7 @@ function useResolvedWorkspaceRouteState(input: {
hostSnapshot?.lastError,
input.workspace,
input.hasHydratedWorkspaces,
restoreStatus,
],
);
}
@@ -1858,6 +1866,7 @@ function WorkspaceScreenContent({
);
const workspaceRouteState = useResolvedWorkspaceRouteState({
serverId: normalizedServerId,
workspaceId: normalizedWorkspaceId,
workspace: workspaceDescriptor,
hasHydratedWorkspaces,
});