fix(projects): isolate legacy host identity

This commit is contained in:
Mohamed Boudra
2026-07-28 23:11:50 +00:00
parent 6544ca7419
commit 95ceb238ee
4 changed files with 109 additions and 25 deletions
@@ -1,3 +1,5 @@
import { mkdirSync, mkdtempSync, rmSync, symlinkSync } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { describe, expect, test } from "vitest";
import { deriveProjectGroupKey } from "./project-group-key.js";
@@ -82,4 +84,29 @@ describe("deriveProjectGroupKey", () => {
}),
).toBe(path.join(mainRepoRoot, "packages", "app"));
});
test.skipIf(process.platform === "win32")(
"preserves a selected subproject reached through a symlink",
() => {
const tempDir = mkdtempSync(path.join(tmpdir(), "project-group-key-"));
try {
const worktreeRoot = path.join(tempDir, "repo");
const selectedRoot = path.join(worktreeRoot, "packages", "app");
const linkedRoot = path.join(tempDir, "app-link");
mkdirSync(selectedRoot, { recursive: true });
symlinkSync(selectedRoot, linkedRoot, "dir");
expect(
deriveProjectGroupKey({
rootPath: linkedRoot,
remoteUrl: "git@github.com:getpaseo/paseo.git",
worktreeRoot,
mainRepoRoot: worktreeRoot,
}),
).toBe("remote:github.com/getpaseo/paseo#subdir:packages/app");
} finally {
rmSync(tempDir, { recursive: true, force: true });
}
},
);
});
@@ -1,4 +1,5 @@
import { isAbsolute, relative, resolve, sep } from "node:path";
import { resolve, sep } from "node:path";
import { getRealpathAwareRelativePath } from "../utils/path.js";
/**
* Derives the persisted, opaque equivalence key used to group projects across hosts.
@@ -23,17 +24,7 @@ export function deriveProjectGroupKey(input: {
function deriveSelectedPath(rootPath: string, worktreeRoot: string | null): string | null {
if (!worktreeRoot) return null;
const selectedPath = relative(resolve(worktreeRoot), resolve(rootPath));
if (
!selectedPath ||
selectedPath === "." ||
selectedPath === ".." ||
selectedPath.startsWith(`..${sep}`) ||
isAbsolute(selectedPath)
) {
return null;
}
return selectedPath;
return getRealpathAwareRelativePath(worktreeRoot, rootPath) || null;
}
function encodeSelectedPath(selectedPath: string): string {