Merge branch 'investigate/portless' into dev

# Conflicts:
#	packages/app/e2e/helpers/workspace-setup.ts
#	packages/app/src/components/sidebar-workspace-list.tsx
#	packages/app/src/contexts/session-context.tsx
#	packages/app/src/hooks/use-sidebar-workspaces-list.test.ts
#	packages/app/src/screens/workspace/workspace-tab-menu.ts
#	packages/app/src/stores/workspace-setup-store.ts
#	packages/app/src/stores/workspace-tabs-store.ts
#	packages/app/src/utils/sidebar-project-row-model.test.ts
#	packages/app/src/utils/sidebar-shortcuts.test.ts
#	packages/app/src/utils/workspace-tab-identity.ts
#	packages/server/src/server/bootstrap.ts
#	packages/server/src/server/worktree-session.ts
This commit is contained in:
Mohamed Boudra
2026-04-01 22:06:39 +07:00
52 changed files with 5855 additions and 354 deletions
@@ -83,6 +83,10 @@ describe("workspace route parsing", () => {
kind: "file",
path: "src/index.ts",
});
expect(parseWorkspaceOpenIntent("setup:L3RtcC9yZXBv")).toEqual({
kind: "setup",
workspaceId: "/tmp/repo",
});
});
it("uses the plain workspace route when workspace context is provided", () => {
+9 -1
View File
@@ -99,7 +99,8 @@ export type WorkspaceOpenIntent =
| { kind: "agent"; agentId: string }
| { kind: "terminal"; terminalId: string }
| { kind: "file"; path: string }
| { kind: "draft"; draftId: string };
| { kind: "draft"; draftId: string }
| { kind: "setup"; workspaceId: string };
export function parseWorkspaceOpenIntent(
value: string | null | undefined,
@@ -136,6 +137,13 @@ export function parseWorkspaceOpenIntent(
}
return { kind: "file", path: decodedPath };
}
if (kind === "setup") {
const workspaceId = decodeWorkspaceIdFromPathSegment(payload);
if (!workspaceId) {
return null;
}
return { kind: "setup", workspaceId };
}
return null;
}
@@ -19,6 +19,8 @@ function workspace(overrides: Partial<SidebarWorkspaceEntry> = {}): SidebarWorks
activityAt: null,
statusBucket: "done",
diffStat: null,
services: [],
hasRunningServices: false,
...overrides,
};
}
@@ -17,6 +17,8 @@ function workspace(serverId: string, cwd: string): SidebarWorkspaceEntry {
activityAt: null,
statusBucket: "done",
diffStat: null,
services: [],
hasRunningServices: false,
};
}
@@ -96,6 +96,7 @@ describe("tool-call-display", () => {
index: 1,
command: "npm install",
cwd: "/tmp/repo/.paseo/worktrees/repo/branch",
log: "",
status: "running",
exitCode: null,
},
@@ -20,6 +20,7 @@ function workspace(
status: input.status ?? "running",
activityAt: input.activityAt ?? null,
diffStat: input.diffStat ?? null,
services: input.services ?? [],
};
}
@@ -26,6 +26,10 @@ export function normalizeWorkspaceTabTarget(
const launcherId = trimNonEmpty(value.launcherId);
return launcherId ? { kind: "launcher", launcherId } : null;
}
if (value.kind === "setup") {
const workspaceId = trimNonEmpty(value.workspaceId);
return workspaceId ? { kind: "setup", workspaceId: workspaceId.replace(/\\/g, "/") } : null;
}
return null;
}
@@ -52,6 +56,9 @@ export function workspaceTabTargetsEqual(
// Launcher tabs are intentionally always unique, even when reopened repeatedly.
return false;
}
if (left.kind === "setup" && right.kind === "setup") {
return left.workspaceId === right.workspaceId;
}
return false;
}
@@ -68,6 +75,9 @@ export function buildDeterministicWorkspaceTabId(target: WorkspaceTabTarget): st
if (target.kind === "launcher") {
return `launcher_${target.launcherId}`;
}
if (target.kind === "setup") {
return `setup_${target.workspaceId}`;
}
return `file_${target.path}`;
}