diff --git a/src/shared/file-reference-resolver.test.ts b/src/shared/file-reference-resolver.test.ts index 3684b340a..5e24ecf4d 100644 --- a/src/shared/file-reference-resolver.test.ts +++ b/src/shared/file-reference-resolver.test.ts @@ -1,8 +1,62 @@ import { afterAll, beforeAll, describe, expect, test } from "bun:test" import { mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs" import { tmpdir } from "node:os" -import { join } from "node:path" -import { resolveFileReferencesInText } from "./file-reference-resolver" +import { join, resolve } from "node:path" +import { resolveFilePath, resolveFileReferencesInText } from "./file-reference-resolver" + +describe("resolveFilePath", () => { + const cwd = "/skills/gsd" + + test("expands bare environment variables before resolving absolute paths", () => { + //#given + const homeDir = process.env.HOME + if (!homeDir) { + throw new Error("HOME must be set for file reference resolver tests") + } + + //#when + const resolved = resolveFilePath("$HOME/foo.md", cwd) + + //#then + expect(resolved).toBe(resolve(homeDir, "foo.md")) + }) + + test("expands braced environment variables before resolving absolute paths", () => { + //#given + const homeDir = process.env.HOME + if (!homeDir) { + throw new Error("HOME must be set for file reference resolver tests") + } + + //#when + const resolved = resolveFilePath("${HOME}/foo.md", cwd) + + //#then + expect(resolved).toBe(resolve(homeDir, "foo.md")) + }) + + test("keeps absolute paths absolute", () => { + //#given + const absolutePath = "/abs/path.md" + + //#when + const resolved = resolveFilePath(absolutePath, cwd) + + //#then + expect(resolved).toBe(resolve(absolutePath)) + }) + + test("resolves relative paths from cwd", () => { + //#given + const relativePath = "relative/path.md" + + //#when + const resolved = resolveFilePath(relativePath, cwd) + + //#then + expect(resolved).toBe(resolve(cwd, relativePath)) + }) +}) describe("resolveFileReferencesInText", () => { const fixtureRoot = join(tmpdir(), `file-reference-resolver-${Date.now()}`) diff --git a/src/shared/file-reference-resolver.ts b/src/shared/file-reference-resolver.ts index d5f0eafb6..9bfede41e 100644 --- a/src/shared/file-reference-resolver.ts +++ b/src/shared/file-reference-resolver.ts @@ -30,12 +30,20 @@ function findFileReferences(text: string): FileMatch[] { return matches } -function resolveFilePath(filePath: string, cwd: string): string { - if (isAbsolute(filePath)) { - return resolve(filePath) +export function resolveFilePath(filePath: string, cwd: string): string { + const expanded = filePath.replace(/\$\{(\w+)\}|\$(\w+)/g, (match, braced: string | undefined, bare: string | undefined) => { + const variableName = braced ?? bare + if (!variableName) { + return match + } + return process.env[variableName] ?? match + }) + + if (isAbsolute(expanded)) { + return resolve(expanded) } - return resolve(cwd, filePath) + return resolve(cwd, expanded) } function readFileContent(resolvedPath: string): string {