fix(coding-agent): move temporary extension cache (#5345)
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { createHash } from "node:crypto";
|
||||
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
@@ -51,6 +50,20 @@ function getFileContent(repoDir: string, filename: string): string {
|
||||
return readFileSync(join(repoDir, filename), "utf-8");
|
||||
}
|
||||
|
||||
type GitSourceForTest = {
|
||||
type: "git";
|
||||
repo: string;
|
||||
host: string;
|
||||
path: string;
|
||||
pinned: boolean;
|
||||
ref?: string;
|
||||
};
|
||||
|
||||
interface PackageManagerPathInternals {
|
||||
parseSource(source: string): GitSourceForTest;
|
||||
getGitInstallPath(source: GitSourceForTest, scope: "temporary"): string;
|
||||
}
|
||||
|
||||
describe("DefaultPackageManager git update", () => {
|
||||
let tempDir: string;
|
||||
let remoteDir: string; // Simulates the "remote" repository
|
||||
@@ -376,10 +389,8 @@ describe("DefaultPackageManager git update", () => {
|
||||
|
||||
describe("temporary git sources", () => {
|
||||
it("should refresh cached temporary git sources when resolving", async () => {
|
||||
const gitHost = "github.com";
|
||||
const gitPath = "test/extension";
|
||||
const hash = createHash("sha256").update(`git-${gitHost}-${gitPath}`).digest("hex").slice(0, 8);
|
||||
const cachedDir = join(tmpdir(), "pi-extensions", `git-${gitHost}`, hash, gitPath);
|
||||
const managerWithPaths = packageManager as unknown as PackageManagerPathInternals;
|
||||
const cachedDir = managerWithPaths.getGitInstallPath(managerWithPaths.parseSource(gitSource), "temporary");
|
||||
const extensionFile = join(cachedDir, "pi-extensions", "session-breakdown.ts");
|
||||
|
||||
rmSync(cachedDir, { recursive: true, force: true });
|
||||
@@ -423,10 +434,8 @@ describe("DefaultPackageManager git update", () => {
|
||||
});
|
||||
|
||||
it("should not refresh pinned temporary git sources", async () => {
|
||||
const gitHost = "github.com";
|
||||
const gitPath = "test/extension";
|
||||
const hash = createHash("sha256").update(`git-${gitHost}-${gitPath}`).digest("hex").slice(0, 8);
|
||||
const cachedDir = join(tmpdir(), "pi-extensions", `git-${gitHost}`, hash, gitPath);
|
||||
const managerWithPaths = packageManager as unknown as PackageManagerPathInternals;
|
||||
const cachedDir = managerWithPaths.getGitInstallPath(managerWithPaths.parseSource(gitSource), "temporary");
|
||||
const extensionFile = join(cachedDir, "pi-extensions", "session-breakdown.ts");
|
||||
|
||||
rmSync(cachedDir, { recursive: true, force: true });
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { EventEmitter } from "node:events";
|
||||
import { mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
||||
import { mkdirSync, rmSync, statSync, symlinkSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join, relative } from "node:path";
|
||||
import { PassThrough } from "node:stream";
|
||||
@@ -33,6 +33,16 @@ interface PackageManagerInternals {
|
||||
options?: { cwd?: string; timeoutMs?: number; env?: Record<string, string> },
|
||||
): Promise<string>;
|
||||
getLocalGitUpdateTarget(installedPath: string): Promise<{ ref: string; head: string; fetchArgs: string[] }>;
|
||||
parseSource(
|
||||
source: string,
|
||||
):
|
||||
| { type: "npm"; spec: string; name: string; pinned: boolean }
|
||||
| { type: "git"; repo: string; host: string; path: string; pinned: boolean; ref?: string }
|
||||
| { type: "local"; path: string };
|
||||
getNpmInstallPath(
|
||||
source: { type: "npm"; spec: string; name: string; pinned: boolean },
|
||||
scope: "user" | "project" | "temporary",
|
||||
): string;
|
||||
getGitInstallPath(
|
||||
source: { type: "git"; repo: string; host: string; path: string; pinned: boolean; ref?: string },
|
||||
scope: "user" | "project" | "temporary",
|
||||
@@ -1161,6 +1171,26 @@ Content`,
|
||||
});
|
||||
});
|
||||
|
||||
describe("temporary install paths", () => {
|
||||
it("should place temporary npm packages under the agent temp extension folder", () => {
|
||||
const managerWithInternals = packageManager as unknown as PackageManagerInternals;
|
||||
const source = managerWithInternals.parseSource("npm:left-pad");
|
||||
if (source.type !== "npm") {
|
||||
throw new Error("Expected npm source");
|
||||
}
|
||||
|
||||
const installPath = managerWithInternals.getNpmInstallPath(source, "temporary");
|
||||
const tempRoot = join(agentDir, "tmp", "extensions");
|
||||
|
||||
expect(pathEndsWith(installPath, "node_modules/left-pad")).toBe(true);
|
||||
expect(relative(tempRoot, installPath).startsWith("..")).toBe(false);
|
||||
expect(installPath.startsWith(join(tmpdir(), "pi-extensions"))).toBe(false);
|
||||
if (process.platform !== "win32") {
|
||||
expect(statSync(tempRoot).mode & 0o777).toBe(0o700);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("settings source normalization", () => {
|
||||
it("should store global local packages relative to agent settings base", () => {
|
||||
const pkgDir = join(tempDir, "packages", "local-global-pkg");
|
||||
|
||||
Reference in New Issue
Block a user