From 9cf7f9ce31b1396779d47570fb9edf06d5e7656e Mon Sep 17 00:00:00 2001 From: Daniel Sticker Date: Sun, 8 Mar 2026 11:03:36 +0100 Subject: [PATCH 1/3] feat(sidebar): add Svelte favicon support Resolve project icons from src/app.html, including %sveltekit.assets% paths, before falling back to sidebar-specific SVG assets for generic and Svelte projects. Load the fallback SVGs from checked-in asset files, include the Affinity source file in the repo, and copy the runtime SVG assets into dist/assets during server builds. --- apps/server/scripts/cli.ts | 39 ++++- .../src/assets/project-favicon-default.svg | 5 + .../src/assets/project-favicon-svelte.svg | 13 ++ apps/server/src/assets/project-favicons.af | Bin 0 -> 88636 bytes apps/server/src/projectFaviconAssets.ts | 13 ++ apps/server/src/projectFaviconRoute.test.ts | 159 +++++++++++++++++- apps/server/src/projectFaviconRoute.ts | 42 ++++- apps/server/src/projectIconFallback.ts | 85 ++++++++++ 8 files changed, 344 insertions(+), 12 deletions(-) create mode 100644 apps/server/src/assets/project-favicon-default.svg create mode 100644 apps/server/src/assets/project-favicon-svelte.svg create mode 100644 apps/server/src/assets/project-favicons.af create mode 100644 apps/server/src/projectFaviconAssets.ts create mode 100644 apps/server/src/projectIconFallback.ts diff --git a/apps/server/scripts/cli.ts b/apps/server/scripts/cli.ts index ccf1f5a91..95537409f 100644 --- a/apps/server/scripts/cli.ts +++ b/apps/server/scripts/cli.ts @@ -37,6 +37,11 @@ interface PublishIconBackup { readonly backupPath: string; } +const PROJECT_FAVICON_ASSET_FILE_NAMES = [ + "project-favicon-default.svg", + "project-favicon-svelte.svg", +] as const; + const applyPublishIconOverrides = Effect.fn("applyPublishIconOverrides")(function* ( repoRoot: string, serverDir: string, @@ -110,6 +115,32 @@ const applyDevelopmentIconOverrides = Effect.fn("applyDevelopmentIconOverrides") yield* Effect.log("[cli] Applied development icon overrides to dist/client"); }); +const copyProjectFaviconAssets = Effect.fn("copyProjectFaviconAssets")(function* ( + serverDir: string, +) { + const path = yield* Path.Path; + const fs = yield* FileSystem.FileSystem; + const sourceDir = path.join(serverDir, "src/assets"); + const targetDir = path.join(serverDir, "dist/assets"); + + yield* fs.makeDirectory(targetDir, { recursive: true }); + + for (const fileName of PROJECT_FAVICON_ASSET_FILE_NAMES) { + const sourcePath = path.join(sourceDir, fileName); + const targetPath = path.join(targetDir, fileName); + + if (!(yield* fs.exists(sourcePath))) { + return yield* new CliError({ + message: `Missing project favicon asset: ${sourcePath}`, + }); + } + + yield* fs.copyFile(sourcePath, targetPath); + } + + yield* Effect.log("[cli] Copied project favicon assets into dist/assets"); +}); + // --------------------------------------------------------------------------- // build subcommand // --------------------------------------------------------------------------- @@ -134,6 +165,7 @@ const buildCmd = Command.make( stderr: "inherit", })`bun tsdown`, ); + yield* copyProjectFaviconAssets(serverDir); const webDist = path.join(repoRoot, "apps/web/dist"); const clientTarget = path.join(serverDir, "dist/client"); @@ -172,7 +204,12 @@ const publishCmd = Command.make( const backupPath = `${packageJsonPath}.bak`; // Assert build assets exist - for (const relPath of ["dist/index.mjs", "dist/client/index.html"]) { + for (const relPath of [ + "dist/index.mjs", + "dist/client/index.html", + "dist/assets/project-favicon-default.svg", + "dist/assets/project-favicon-svelte.svg", + ]) { const abs = path.join(serverDir, relPath); if (!(yield* fs.exists(abs))) { return yield* new CliError({ diff --git a/apps/server/src/assets/project-favicon-default.svg b/apps/server/src/assets/project-favicon-default.svg new file mode 100644 index 000000000..83fabee2d --- /dev/null +++ b/apps/server/src/assets/project-favicon-default.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/apps/server/src/assets/project-favicon-svelte.svg b/apps/server/src/assets/project-favicon-svelte.svg new file mode 100644 index 000000000..6810494ee --- /dev/null +++ b/apps/server/src/assets/project-favicon-svelte.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/apps/server/src/assets/project-favicons.af b/apps/server/src/assets/project-favicons.af new file mode 100644 index 0000000000000000000000000000000000000000..d868ff02f5aedb3df503e50cccedd1264d8e4924 GIT binary patch literal 88636 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 Promise, -): Promise { +async function withRouteServer(run: (baseUrl: string) => Promise): Promise { const server = http.createServer((req, res) => { const url = new URL(req.url ?? "/", "http://127.0.0.1"); if (tryHandleProjectFaviconRequest(url, res)) { @@ -104,7 +106,10 @@ describe("tryHandleProjectFaviconRequest", () => { const projectDir = makeTempDir("t3code-favicon-route-source-"); const iconPath = path.join(projectDir, "public", "brand", "logo.svg"); fs.mkdirSync(path.dirname(iconPath), { recursive: true }); - fs.writeFileSync(path.join(projectDir, "index.html"), ''); + fs.writeFileSync( + path.join(projectDir, "index.html"), + '', + ); fs.writeFileSync(iconPath, "brand", "utf8"); await withRouteServer(async (baseUrl) => { @@ -120,7 +125,10 @@ describe("tryHandleProjectFaviconRequest", () => { const projectDir = makeTempDir("t3code-favicon-route-html-order-"); const iconPath = path.join(projectDir, "public", "brand", "logo.svg"); fs.mkdirSync(path.dirname(iconPath), { recursive: true }); - fs.writeFileSync(path.join(projectDir, "index.html"), ''); + fs.writeFileSync( + path.join(projectDir, "index.html"), + '', + ); fs.writeFileSync(iconPath, "brand-html-order", "utf8"); await withRouteServer(async (baseUrl) => { @@ -132,6 +140,27 @@ describe("tryHandleProjectFaviconRequest", () => { }); }); + it("resolves SvelteKit asset placeholders from src/app.html", async () => { + const projectDir = makeTempDir("t3code-favicon-route-sveltekit-assets-"); + const iconPath = path.join(projectDir, "static", "favicon.png"); + fs.mkdirSync(path.dirname(iconPath), { recursive: true }); + fs.mkdirSync(path.join(projectDir, "src"), { recursive: true }); + fs.writeFileSync( + path.join(projectDir, "src", "app.html"), + '', + "utf8", + ); + fs.writeFileSync(iconPath, "sveltekit-favicon", "utf8"); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.contentType).toContain("image/png"); + expect(response.body).toBe("sveltekit-favicon"); + }); + }); + it("resolves object-style icon metadata when href appears before rel", async () => { const projectDir = makeTempDir("t3code-favicon-route-obj-order-"); const iconPath = path.join(projectDir, "public", "brand", "obj.svg"); @@ -161,7 +190,125 @@ describe("tryHandleProjectFaviconRequest", () => { const response = await request(baseUrl, pathname); expect(response.statusCode).toBe(200); expect(response.contentType).toContain("image/svg+xml"); - expect(response.body).toContain('data-fallback="project-favicon"'); + expect(response.body).toBe(DEFAULT_PROJECT_FAVICON_SVG); + }); + }); + + it("returns the Svelte fallback when svelte.config.ts exists and no favicon exists", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-config-"); + fs.writeFileSync(path.join(projectDir, "svelte.config.ts"), "export default {};\n", "utf8"); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.contentType).toContain("image/svg+xml"); + expect(response.body).toBe(SVELTE_PROJECT_FAVICON_SVG); + }); + }); + + it("returns the Svelte fallback when package.json declares svelte", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-package-"); + fs.writeFileSync( + path.join(projectDir, "package.json"), + JSON.stringify({ dependencies: { svelte: "^5.0.0" } }), + "utf8", + ); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe(SVELTE_PROJECT_FAVICON_SVG); + }); + }); + + it("returns the Svelte fallback when package.json declares @sveltejs/kit", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-kit-package-"); + fs.writeFileSync( + path.join(projectDir, "package.json"), + JSON.stringify({ devDependencies: { "@sveltejs/kit": "^2.0.0" } }), + "utf8", + ); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe(SVELTE_PROJECT_FAVICON_SVG); + }); + }); + + it("returns the Svelte fallback when src/app.html exists", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-app-html-"); + fs.mkdirSync(path.join(projectDir, "src"), { recursive: true }); + fs.writeFileSync( + path.join(projectDir, "src", "app.html"), + "
%sveltekit.body%
", + "utf8", + ); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe(SVELTE_PROJECT_FAVICON_SVG); + }); + }); + + it("returns the Svelte fallback when a .svelte-kit directory exists", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-kit-dir-"); + fs.mkdirSync(path.join(projectDir, ".svelte-kit"), { recursive: true }); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe(SVELTE_PROJECT_FAVICON_SVG); + }); + }); + + it("prefers a real favicon over the Svelte fallback", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-real-favicon-"); + fs.writeFileSync(path.join(projectDir, "svelte.config.ts"), "export default {};\n", "utf8"); + fs.writeFileSync(path.join(projectDir, "favicon.svg"), "favicon-wins", "utf8"); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe("favicon-wins"); + }); + }); + + it("prefers a resolved icon href over the Svelte fallback", async () => { + const projectDir = makeTempDir("t3code-favicon-route-svelte-href-"); + const iconPath = path.join(projectDir, "public", "brand", "logo.svg"); + fs.mkdirSync(path.dirname(iconPath), { recursive: true }); + fs.writeFileSync(path.join(projectDir, "svelte.config.ts"), "export default {};\n", "utf8"); + fs.writeFileSync( + path.join(projectDir, "index.html"), + '', + ); + fs.writeFileSync(iconPath, "href-wins", "utf8"); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe("href-wins"); + }); + }); + + it("keeps the generic fallback for non-Svelte projects", async () => { + const projectDir = makeTempDir("t3code-favicon-route-generic-fallback-"); + fs.writeFileSync(path.join(projectDir, "package.json"), "{not valid json", "utf8"); + + await withRouteServer(async (baseUrl) => { + const pathname = `/api/project-favicon?cwd=${encodeURIComponent(projectDir)}`; + const response = await request(baseUrl, pathname); + expect(response.statusCode).toBe(200); + expect(response.body).toBe(DEFAULT_PROJECT_FAVICON_SVG); }); }); }); diff --git a/apps/server/src/projectFaviconRoute.ts b/apps/server/src/projectFaviconRoute.ts index cf234ad89..6fdfe6824 100644 --- a/apps/server/src/projectFaviconRoute.ts +++ b/apps/server/src/projectFaviconRoute.ts @@ -1,6 +1,11 @@ import fs from "node:fs"; import http from "node:http"; import path from "node:path"; +import { + DEFAULT_PROJECT_FAVICON_SVG, + SVELTE_PROJECT_FAVICON_SVG, +} from "./projectFaviconAssets"; +import { detectProjectIconFallback } from "./projectIconFallback"; const FAVICON_MIME_TYPES: Record = { ".png": "image/png", @@ -9,8 +14,6 @@ const FAVICON_MIME_TYPES: Record = { ".ico": "image/x-icon", }; -const FALLBACK_FAVICON_SVG = ``; - // Well-known favicon paths checked in order. const FAVICON_CANDIDATES = [ "favicon.svg", @@ -39,6 +42,7 @@ const FAVICON_CANDIDATES = [ const ICON_SOURCE_FILES = [ "index.html", "public/index.html", + "src/app.html", "app/routes/__root.tsx", "src/routes/__root.tsx", "app/root.tsx", @@ -61,8 +65,18 @@ function extractIconHref(source: string): string | null { } function resolveIconHref(projectCwd: string, href: string): string[] { + const sveltekitAssetsPrefix = "%sveltekit.assets%/"; + if (href.startsWith(sveltekitAssetsPrefix)) { + const clean = href.slice(sveltekitAssetsPrefix.length); + return [path.join(projectCwd, "static", clean), path.join(projectCwd, clean)]; + } + const clean = href.replace(/^\//, ""); - return [path.join(projectCwd, "public", clean), path.join(projectCwd, clean)]; + return [ + path.join(projectCwd, "public", clean), + path.join(projectCwd, "static", clean), + path.join(projectCwd, clean), + ]; } function isPathWithinProject(projectCwd: string, candidatePath: string): boolean { @@ -88,11 +102,29 @@ function serveFaviconFile(filePath: string, res: http.ServerResponse): void { } function serveFallbackFavicon(res: http.ServerResponse): void { + serveInlineSvg(DEFAULT_PROJECT_FAVICON_SVG, res); +} + +function serveInlineSvg(svg: string, res: http.ServerResponse): void { res.writeHead(200, { "Content-Type": "image/svg+xml", "Cache-Control": "public, max-age=3600", }); - res.end(FALLBACK_FAVICON_SVG); + res.end(svg); +} + +function serveDetectedFallback(projectCwd: string, res: http.ServerResponse): void { + void detectProjectIconFallback(projectCwd) + .then((fallbackKind) => { + if (fallbackKind === "svelte") { + serveInlineSvg(SVELTE_PROJECT_FAVICON_SVG, res); + return; + } + serveFallbackFavicon(res); + }) + .catch(() => { + serveFallbackFavicon(res); + }); } export function tryHandleProjectFaviconRequest(url: URL, res: http.ServerResponse): boolean { @@ -128,7 +160,7 @@ export function tryHandleProjectFaviconRequest(url: URL, res: http.ServerRespons const trySourceFiles = (index: number): void => { if (index >= ICON_SOURCE_FILES.length) { - serveFallbackFavicon(res); + serveDetectedFallback(projectCwd, res); return; } const sourceFile = path.join(projectCwd, ICON_SOURCE_FILES[index]!); diff --git a/apps/server/src/projectIconFallback.ts b/apps/server/src/projectIconFallback.ts new file mode 100644 index 000000000..7727f26e4 --- /dev/null +++ b/apps/server/src/projectIconFallback.ts @@ -0,0 +1,85 @@ +import fs from "node:fs/promises"; +import path from "node:path"; + +export type ProjectIconFallbackKind = "svelte"; + +const SVELTE_MARKER_FILES = [ + "svelte.config.js", + "svelte.config.ts", + "svelte.config.mjs", + "svelte.config.cjs", +] as const; +const SVELTE_PACKAGE_MARKERS = ["svelte", "@sveltejs/kit"] as const; + +interface PackageJsonLike { + dependencies?: Record; + devDependencies?: Record; + peerDependencies?: Record; +} + +async function isFile(filePath: string): Promise { + try { + return (await fs.stat(filePath)).isFile(); + } catch { + return false; + } +} + +async function isDirectory(directoryPath: string): Promise { + try { + return (await fs.stat(directoryPath)).isDirectory(); + } catch { + return false; + } +} + +function hasPackageMarker(dependencies: unknown): boolean { + if (!dependencies || typeof dependencies !== "object") { + return false; + } + + return SVELTE_PACKAGE_MARKERS.some((packageName) => + Object.prototype.hasOwnProperty.call(dependencies, packageName), + ); +} + +async function hasSveltePackageMarker(projectCwd: string): Promise { + const packageJsonPath = path.join(projectCwd, "package.json"); + + let packageJson: PackageJsonLike; + try { + packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")) as PackageJsonLike; + } catch { + return false; + } + + return ( + hasPackageMarker(packageJson.dependencies) || + hasPackageMarker(packageJson.devDependencies) || + hasPackageMarker(packageJson.peerDependencies) + ); +} + +export async function detectProjectIconFallback( + projectCwd: string, +): Promise { + for (const markerFile of SVELTE_MARKER_FILES) { + if (await isFile(path.join(projectCwd, markerFile))) { + return "svelte"; + } + } + + if (await isDirectory(path.join(projectCwd, ".svelte-kit"))) { + return "svelte"; + } + + if (await isFile(path.join(projectCwd, "src", "app.html"))) { + return "svelte"; + } + + if (await hasSveltePackageMarker(projectCwd)) { + return "svelte"; + } + + return null; +} From fb70e0796d75727d5b273c75c1e608119d57e881 Mon Sep 17 00:00:00 2001 From: Daniel Sticker Date: Sun, 8 Mar 2026 11:05:42 +0100 Subject: [PATCH 2/3] fix(sidebar): prevent project icon layout shift Keep a fixed-size icon slot in the project list and show the folder placeholder until the favicon request finishes so project names no longer jump when the server-backed icon loads. --- apps/web/src/components/Sidebar.tsx | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index e3a3ce02e..c998ecf6e 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -242,18 +242,25 @@ function ProjectFavicon({ cwd }: { cwd: string }) { const src = `${serverHttpOrigin}/api/project-favicon?cwd=${encodeURIComponent(cwd)}`; - if (status === "error") { - return ; - } + useEffect(() => { + setStatus("loading"); + }, [src]); return ( - setStatus("loaded")} - onError={() => setStatus("error")} - /> + + {status === "error" ? ( + + ) : null} + setStatus("loaded")} + onError={() => setStatus("error")} + /> + ); } From 8bc8ed8b07500fd6fb3f6bcf4839e090f63a3952 Mon Sep 17 00:00:00 2001 From: Daniel Sticker Date: Sun, 8 Mar 2026 11:34:02 +0100 Subject: [PATCH 3/3] fix(sidebar): avoid cached project icon race --- apps/web/src/components/Sidebar.tsx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index c998ecf6e..658d8bcd2 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -238,13 +238,16 @@ function getServerHttpOrigin(): string { const serverHttpOrigin = getServerHttpOrigin(); function ProjectFavicon({ cwd }: { cwd: string }) { - const [status, setStatus] = useState<"loading" | "loaded" | "error">("loading"); - const src = `${serverHttpOrigin}/api/project-favicon?cwd=${encodeURIComponent(cwd)}`; + const [imageState, setImageState] = useState<{ + src: string; + status: "loading" | "loaded" | "error"; + }>({ + src: "", + status: "loading", + }); - useEffect(() => { - setStatus("loading"); - }, [src]); + const status = imageState.src === src ? imageState.status : "loading"; return ( @@ -252,13 +255,14 @@ function ProjectFavicon({ cwd }: { cwd: string }) { ) : null} setStatus("loaded")} - onError={() => setStatus("error")} + onLoad={() => setImageState({ src, status: "loaded" })} + onError={() => setImageState({ src, status: "error" })} /> );