mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-06 16:34:36 +00:00
fix: preserve recovered workspace session state
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { execFileSync } from "node:child_process";
|
||||
import { existsSync } from "node:fs";
|
||||
import { rename } from "node:fs/promises";
|
||||
import type { Page } from "@playwright/test";
|
||||
import { buildHostWorkspaceRoute } from "@/utils/host-routes";
|
||||
import { expect, test } from "./fixtures";
|
||||
import { gotoAppShell } from "./helpers/app";
|
||||
import {
|
||||
expectWorkspaceBranch,
|
||||
openChangesPanel,
|
||||
switchBranchFromChangesPanel,
|
||||
} from "./helpers/branch-switcher";
|
||||
import {
|
||||
createIdleAgent,
|
||||
expectSessionRowNotArchived,
|
||||
@@ -81,6 +88,19 @@ test.describe("Worktree restore", () => {
|
||||
return seeded;
|
||||
}
|
||||
|
||||
async function openArchivedAgentBeforeWorkspaceHydration(page: Page, prefix: string) {
|
||||
const seeded = await createArchivedMissingWorktree(prefix);
|
||||
const workspaceRoute = buildHostWorkspaceRoute(getServerId(), seeded.worktree.workspaceId);
|
||||
const openAgent = encodeURIComponent(`agent:${seeded.agent.id}`);
|
||||
|
||||
await page.goto(`${workspaceRoute}?open=${openAgent}`);
|
||||
await expect(page.getByText("Workspace archived", { exact: true })).toBeVisible({
|
||||
timeout: 30_000,
|
||||
});
|
||||
await expect(page.getByTestId("workspace-recovery-action")).toHaveText("Restore");
|
||||
return seeded;
|
||||
}
|
||||
|
||||
test.afterEach(async () => {
|
||||
for (const directory of createdWorktreeDirectories) {
|
||||
await archiveWorkspaceFromDaemon(worktreeClient, directory).catch(() => undefined);
|
||||
@@ -156,7 +176,10 @@ test.describe("Worktree restore", () => {
|
||||
});
|
||||
|
||||
test("explicit Restore shows loading and opens the recreated workspace", async ({ page }) => {
|
||||
const { agent, worktree } = await openArchivedWorkspaceFromHistory(page, "restore-success");
|
||||
const { agent, worktree } = await openArchivedAgentBeforeWorkspaceHydration(
|
||||
page,
|
||||
"restore-success",
|
||||
);
|
||||
|
||||
await page.getByTestId("workspace-recovery-action").click();
|
||||
|
||||
@@ -173,6 +196,22 @@ test.describe("Worktree restore", () => {
|
||||
).toBeVisible({ timeout: 30_000 });
|
||||
await expect(page.getByTestId("workspace-recovery-action")).toHaveCount(0);
|
||||
expect(await fetchAgentArchivedAt(client, agent.id)).toBeNull();
|
||||
|
||||
const switchedBranch = `restored-live-${randomUUID().slice(0, 8)}`;
|
||||
execFileSync("git", ["branch", switchedBranch], {
|
||||
cwd: tempRepo.path,
|
||||
stdio: "pipe",
|
||||
});
|
||||
await openChangesPanel(page);
|
||||
await expectWorkspaceBranch(page, worktree.workspaceName);
|
||||
await switchBranchFromChangesPanel(page, {
|
||||
from: worktree.workspaceName,
|
||||
to: switchedBranch,
|
||||
});
|
||||
await expectWorkspaceBranch(page, switchedBranch);
|
||||
await expect(
|
||||
page.getByTestId("workspace-header-title").filter({ visible: true }).first(),
|
||||
).toHaveText(switchedBranch, { timeout: 30_000 });
|
||||
});
|
||||
|
||||
test("restore failure stays visible and permits a successful retry", async ({ page }) => {
|
||||
|
||||
@@ -111,7 +111,7 @@ function HostWorkspaceRouteContent() {
|
||||
const hasHydratedWorkspaces = useHasHydratedWorkspaces(serverId);
|
||||
const workspaceExists = useWorkspaceExists(serverId, workspaceId);
|
||||
const isOpenIntentWaitingForWorkspace = Boolean(
|
||||
openValue && hasHydratedWorkspaces && !workspaceExists,
|
||||
openValue && (!hasHydratedWorkspaces || !workspaceExists),
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!serverId || !workspaceId) {
|
||||
|
||||
@@ -4012,9 +4012,11 @@ export class Session {
|
||||
|
||||
private async restoreWorkspaceAndEmit(workspaceId: string): Promise<void> {
|
||||
await this.workspaceRecovery.restore(workspaceId);
|
||||
await this.emitWorkspaceUpdatesForWorkspaceIds([workspaceId], {
|
||||
skipReconcile: true,
|
||||
});
|
||||
const workspace = await this.workspaceRegistry.get(workspaceId);
|
||||
if (!workspace) {
|
||||
throw new Error(`Recovered workspace record not found: ${workspaceId}`);
|
||||
}
|
||||
await this.workspaceGitObserver.warmGitData(workspace);
|
||||
}
|
||||
|
||||
private async restoreOwningWorkspaceForLegacyAgentRefresh(agentId: string): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user