From 1d01b9f2cfe44cb7899410e742a9d553c7807e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Sun, 2 Aug 2026 17:37:51 +0000 Subject: [PATCH] fix(studio): exclude generated caches from project metadata --- packages/cli/src/server/fileWatcher.ts | 2 +- .../src/helpers/projectSignature.ts | 3 ++ .../studio-server/src/helpers/safePath.ts | 8 +++- .../studio-server/src/routes/projects.test.ts | 47 +++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/server/fileWatcher.ts b/packages/cli/src/server/fileWatcher.ts index 5d7a00bee..3f7dec580 100644 --- a/packages/cli/src/server/fileWatcher.ts +++ b/packages/cli/src/server/fileWatcher.ts @@ -15,8 +15,8 @@ const WATCHER_EXCLUDED_DIRS = new Set([ ".next", ".thumbnails", ".transcode-cache", - ".waveform-cache", ".vite", + ".waveform-cache", "build", "coverage", "dist", diff --git a/packages/studio-server/src/helpers/projectSignature.ts b/packages/studio-server/src/helpers/projectSignature.ts index 576c78860..763082f00 100644 --- a/packages/studio-server/src/helpers/projectSignature.ts +++ b/packages/studio-server/src/helpers/projectSignature.ts @@ -20,7 +20,10 @@ const SIGNATURE_EXCLUDED_DIRS = new Set([ ".git", ".hyperframes", ".next", + ".thumbnails", + ".transcode-cache", ".vite", + ".waveform-cache", "build", "coverage", "dist", diff --git a/packages/studio-server/src/helpers/safePath.ts b/packages/studio-server/src/helpers/safePath.ts index 688eb2386..cc7ff8855 100644 --- a/packages/studio-server/src/helpers/safePath.ts +++ b/packages/studio-server/src/helpers/safePath.ts @@ -6,7 +6,13 @@ import { readdirSync } from "node:fs"; // Re-exported here for back-compat with existing `../helpers/safePath.js` imports. export { isSafePath, resolveWithinProject } from "@hyperframes/core"; -const IGNORE_DIRS = new Set([".thumbnails", "node_modules", ".git"]); +const IGNORE_DIRS = new Set([ + ".thumbnails", + ".transcode-cache", + ".waveform-cache", + "node_modules", + ".git", +]); function shouldIgnoreDir(rel: string): boolean { return rel === ".hyperframes/backup"; diff --git a/packages/studio-server/src/routes/projects.test.ts b/packages/studio-server/src/routes/projects.test.ts index e6a6fcfe3..63804eb23 100644 --- a/packages/studio-server/src/routes/projects.test.ts +++ b/packages/studio-server/src/routes/projects.test.ts @@ -91,6 +91,37 @@ describe("GET /projects/:id/signature", () => { expect(second.signature).not.toBe(first.signature); }); + it("ignores generated cache writes while detecting source edits", async () => { + const projectDir = createProjectDir(); + const app = new Hono(); + registerProjectRoutes(app, createAdapter(projectDir)); + const getSignature = async () => + ( + (await (await app.request("http://localhost/projects/demo/signature")).json()) as { + signature: string; + } + ).signature; + + const initial = await getSignature(); + const generatedFiles = [ + [".transcode-cache", "proxy.mp4"], + [".thumbnails", "frame.jpg"], + [".waveform-cache", "peaks.json"], + ] as const; + const generatedSignatures: string[] = []; + for (const [dir, file] of generatedFiles) { + mkdirSync(join(projectDir, dir)); + writeFileSync(join(projectDir, dir, file), `generated ${dir}`); + generatedSignatures.push(await getSignature()); + } + + expect(generatedSignatures).toEqual([initial, initial, initial]); + + mkdirSync(join(projectDir, "src")); + writeFileSync(join(projectDir, "src", "scene.ts"), "export const scene = true;"); + expect(await getSignature()).not.toBe(initial); + }); + it("404s for an unknown project", async () => { const app = new Hono(); registerProjectRoutes(app, { @@ -132,4 +163,20 @@ describe("registerProjectRoutes — composition discovery (#1384)", () => { // Only Studio's own backup snapshots are hidden from the tree (#1366). expect(payload.files).not.toContain(".hyperframes/backup/snapshot.html"); }); + + it("omits generated cache files from the project file tree", async () => { + const projectDir = createProjectDir(); + mkdirSync(join(projectDir, ".transcode-cache")); + writeFileSync(join(projectDir, ".transcode-cache", "proxy.mp4"), "proxy"); + mkdirSync(join(projectDir, ".waveform-cache")); + writeFileSync(join(projectDir, ".waveform-cache", "peaks.json"), "[]"); + const app = new Hono(); + registerProjectRoutes(app, createAdapter(projectDir)); + + const response = await app.request("http://localhost/projects/demo"); + const payload = (await response.json()) as { files?: string[] }; + + expect(payload.files).not.toContain(".transcode-cache/proxy.mp4"); + expect(payload.files).not.toContain(".waveform-cache/peaks.json"); + }); });