diff --git a/packages/opencode/src/project/instance.ts b/packages/opencode/src/project/instance.ts index 98031f18d3f..f784cd99220 100644 --- a/packages/opencode/src/project/instance.ts +++ b/packages/opencode/src/project/instance.ts @@ -20,13 +20,14 @@ const disposal = { export const Instance = { async provide(input: { directory: string; init?: () => Promise; fn: () => R }): Promise { - let existing = cache.get(input.directory) + const directory = Filesystem.canonical(input.directory) + let existing = cache.get(directory) if (!existing) { - Log.Default.info("creating instance", { directory: input.directory }) + Log.Default.info("creating instance", { directory }) existing = iife(async () => { - const { project, sandbox } = await Project.fromDirectory(input.directory) + const { project, sandbox } = await Project.fromDirectory(directory) const ctx = { - directory: input.directory, + directory, worktree: sandbox, project, } @@ -35,7 +36,7 @@ export const Instance = { }) return ctx }) - cache.set(input.directory, existing) + cache.set(directory, existing) } const ctx = await existing return context.provide(ctx, async () => { diff --git a/packages/opencode/src/util/filesystem.ts b/packages/opencode/src/util/filesystem.ts index a87aaeb9866..160f473e7b6 100644 --- a/packages/opencode/src/util/filesystem.ts +++ b/packages/opencode/src/util/filesystem.ts @@ -2,7 +2,7 @@ import { chmod, mkdir, readFile, writeFile } from "fs/promises" import { createWriteStream, existsSync, statSync } from "fs" import { lookup } from "mime-types" import { realpathSync } from "fs" -import { dirname, join, relative } from "path" +import { dirname, join, normalize, relative, resolve } from "path" import { Readable } from "stream" import { pipeline } from "stream/promises" import { Glob } from "./glob" @@ -113,6 +113,19 @@ export namespace Filesystem { } } + export function canonical(p: string): string { + const abs = normalize(resolve(p)) + const real = (() => { + try { + return normalize(realpathSync.native(abs)) + } catch { + return abs + } + })() + if (process.platform === "win32") return real.toLowerCase() + return real + } + export function windowsPath(p: string): string { if (process.platform !== "win32") return p return (