From 892a8560067f9e9af10b6ee5c35f93f6110cbf01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=86=A0=E8=BE=B0?= Date: Thu, 2 Jul 2026 17:13:33 +0800 Subject: [PATCH] fix(scene): normalize indexed filenames on read --- src/core/scene/scene-index.test.ts | 45 ++++++++++++++++++++++++++++++ src/core/scene/scene-index.ts | 3 +- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/core/scene/scene-index.test.ts diff --git a/src/core/scene/scene-index.test.ts b/src/core/scene/scene-index.test.ts new file mode 100644 index 00000000..f6a7395f --- /dev/null +++ b/src/core/scene/scene-index.test.ts @@ -0,0 +1,45 @@ +import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises"; +import { tmpdir } from "node:os"; +import path from "node:path"; + +import { afterEach, describe, expect, it } from "vitest"; + +import { readSceneIndex } from "./scene-index.js"; + +const tempDirs: string[] = []; + +async function makeDataDir(): Promise { + const dir = await mkdtemp(path.join(tmpdir(), "tdai-scene-index-")); + tempDirs.push(dir); + return dir; +} + +describe("readSceneIndex", () => { + afterEach(async () => { + await Promise.all(tempDirs.splice(0).map((dir) => rm(dir, { recursive: true, force: true }))); + }); + + it("normalizes filenames loaded from metadata", async () => { + const dataDir = await makeDataDir(); + const metadataDir = path.join(dataDir, ".metadata"); + await mkdir(metadataDir, { recursive: true }); + await writeFile( + path.join(metadataDir, "scene_index.json"), + JSON.stringify([ + { + filename: "../../secret.md", + summary: "unsafe", + heat: 1, + created: "2026-07-02T00:00:00.000Z", + updated: "2026-07-02T00:00:00.000Z", + }, + ]), + "utf-8", + ); + + const entries = await readSceneIndex(dataDir); + + expect(entries).toHaveLength(1); + expect(entries[0].filename).toBe("secret.md"); + }); +}); diff --git a/src/core/scene/scene-index.ts b/src/core/scene/scene-index.ts index 84f7d471..405928c6 100644 --- a/src/core/scene/scene-index.ts +++ b/src/core/scene/scene-index.ts @@ -5,6 +5,7 @@ import fs from "node:fs/promises"; import path from "node:path"; import { parseSceneBlock } from "./scene-format.js"; +import { normalizeSceneFilename } from "./filename-normalizer.js"; export interface SceneIndexEntry { filename: string; @@ -31,7 +32,7 @@ export async function readSceneIndex(dataDir: string): Promise