422 lines · 12.6 KB · TypeScript
RawDownload
import * as NodeOS from "node:os"; import { ProviderDriverKind, type CodexSettings } from "@t3tools/contracts";import * as Effect from "effect/Effect";import * as FileSystem from "effect/FileSystem";import * as Path from "effect/Path";import * as Schema from "effect/Schema";import * as PlatformError from "effect/PlatformError"; import { expandHomePath } from "../../pathExpansion.ts"; export interface CodexHomeLayout {  readonly mode: "direct" | "authOverlay";  readonly sharedHomePath: string;  readonly effectiveHomePath: string | undefined;  readonly continuationKey: string;} const KNOWN_SHARED_DIRECTORIES = [  "sessions",  "archived_sessions",  "sqlite",  "shell_snapshots",  "worktrees",  "skills",  "plugins",  "cache",  "logs",  "mcp-oauth-locks",] as const; const PRIVATE_ENTRY_NAMES = new Set(["auth.json", "models_cache.json"]);const SHADOW_LOCAL_ENTRY_NAMES = new Set(["log", "memories", "tmp"]);const REPLACEABLE_SHARED_RUNTIME_DIRECTORIES = new Set(["mcp-oauth-locks"]); function resolveHomePath(path: Path.Path, value: string | undefined): string {  const expanded =    value && value.trim().length > 0      ? expandHomePath(value)      : path.join(NodeOS.homedir(), ".codex");  return path.resolve(expanded);} export const resolveCodexHomeLayout = Effect.fn("resolveCodexHomeLayout")(function* (  config: CodexSettings,): Effect.fn.Return<CodexHomeLayout, never, Path.Path> {  const path = yield* Path.Path;  const sharedHomePath = resolveHomePath(path, config.homePath);  const shadowHomePath = config.shadowHomePath.trim();  if (shadowHomePath.length === 0) {    return {      mode: "direct",      sharedHomePath,      effectiveHomePath: config.homePath.trim().length > 0 ? sharedHomePath : undefined,      continuationKey: `codex:home:${sharedHomePath}`,    };  }   const effectiveHomePath = path.resolve(expandHomePath(shadowHomePath));  return {    mode: "authOverlay",    sharedHomePath,    effectiveHomePath,    continuationKey: `codex:home:${sharedHomePath}`,  };}); const CodexShadowHomeContext = {  sharedHomePath: Schema.String,  effectiveHomePath: Schema.String,}; export class CodexShadowHomeFileSystemError extends Schema.TaggedError<CodexShadowHomeFileSystemError>()(  "CodexShadowHomeFileSystemError",  {    ...CodexShadowHomeContext,    operation: Schema.Literals(["readLink", "makeDirectory", "readDirectory", "remove", "symlink"]),    path: Schema.String,    targetPath: Schema.optional(Schema.String),    entryName: Schema.optional(Schema.String),    cause: Schema.Defect(),  },) {  override get message(): string {    const target = this.targetPath === undefined ? "" : ` to '${this.targetPath}'`;    return `Codex shadow home filesystem operation '${this.operation}' failed for '${this.path}'${target}.`;  }} export class CodexShadowHomePathConflictError extends Schema.TaggedError<CodexShadowHomePathConflictError>()(  "CodexShadowHomePathConflictError",  CodexShadowHomeContext,) {  override get message(): string {    return `Codex shadow home path '${this.effectiveHomePath}' must be different from the shared home path '${this.sharedHomePath}'.`;  }} export class CodexShadowHomeEntryConflictError extends Schema.TaggedError<CodexShadowHomeEntryConflictError>()(  "CodexShadowHomeEntryConflictError",  {    ...CodexShadowHomeContext,    entryName: Schema.String,    linkPath: Schema.String,    targetPath: Schema.String,  },) {  override get message(): string {    return `Cannot create Codex shadow home entry '${this.entryName}' because '${this.linkPath}' already exists and is not a symlink.`;  }} export class CodexShadowHomePrivateEntrySymlinkError extends Schema.TaggedError<CodexShadowHomePrivateEntrySymlinkError>()(  "CodexShadowHomePrivateEntrySymlinkError",  {    ...CodexShadowHomeContext,    entryName: Schema.String,    path: Schema.String,  },) {  override get message(): string {    return `Codex shadow home private entry '${this.entryName}' at '${this.path}' must be a real file, not a symlink.`;  }} export const CodexShadowHomeError = Schema.Union([  CodexShadowHomeFileSystemError,  CodexShadowHomePathConflictError,  CodexShadowHomeEntryConflictError,  CodexShadowHomePrivateEntrySymlinkError,]);export type CodexShadowHomeError = typeof CodexShadowHomeError.Type; type LinkState =  | {      readonly _tag: "Missing";    }  | {      readonly _tag: "NotSymlink";    }  | {      readonly _tag: "Symlink";      readonly target: string;    }; function isNotSymlinkError(error: PlatformError.PlatformError): boolean {  const cause = error.reason.cause;  return (    error.reason._tag === "Unknown" &&    typeof cause === "object" &&    cause !== null &&    "code" in cause &&    cause.code === "EINVAL"  );} const readLinkState = Effect.fn("CodexHomeLayout.readLinkState")(function* (input: {  readonly fileSystem: FileSystem.FileSystem;  readonly sharedHomePath: string;  readonly effectiveHomePath: string;  readonly entryName: string;  readonly linkPath: string;}): Effect.fn.Return<LinkState, CodexShadowHomeError> {  return yield* input.fileSystem.readLink(input.linkPath).pipe(    Effect.map((target): LinkState => ({ _tag: "Symlink", target })),    Effect.catchTags({      PlatformError: (cause) => {        if (cause.reason._tag === "NotFound") {          return Effect.succeed<LinkState>({ _tag: "Missing" });        }        if (isNotSymlinkError(cause)) {          return Effect.succeed<LinkState>({ _tag: "NotSymlink" });        }        return new CodexShadowHomeFileSystemError({          sharedHomePath: input.sharedHomePath,          effectiveHomePath: input.effectiveHomePath,          operation: "readLink",          path: input.linkPath,          entryName: input.entryName,          cause,        });      },    }),  );}); const removePrivateSymlink = Effect.fn("CodexHomeLayout.removePrivateSymlink")(function* (input: {  readonly fileSystem: FileSystem.FileSystem;  readonly sharedHomePath: string;  readonly effectiveHomePath: string;  readonly entryName: string;}): Effect.fn.Return<void, CodexShadowHomeError, Path.Path> {  const path = yield* Path.Path;  const privatePath = path.join(input.effectiveHomePath, input.entryName);  const state = yield* readLinkState({    ...input,    linkPath: privatePath,  });  if (state._tag === "Symlink") {    yield* input.fileSystem.remove(privatePath).pipe(      Effect.catchTags({        PlatformError: (cause) =>          new CodexShadowHomeFileSystemError({            sharedHomePath: input.sharedHomePath,            effectiveHomePath: input.effectiveHomePath,            operation: "remove",            path: privatePath,            entryName: input.entryName,            cause,          }),      }),    );  }}); const ensureSymlink = Effect.fn("CodexHomeLayout.ensureSymlink")(function* (input: {  readonly fileSystem: FileSystem.FileSystem;  readonly sharedHomePath: string;  readonly effectiveHomePath: string;  readonly entryName: string;}): Effect.fn.Return<void, CodexShadowHomeError, Path.Path> {  const path = yield* Path.Path;  const target = path.join(input.sharedHomePath, input.entryName);  const link = path.join(input.effectiveHomePath, input.entryName);  const state = yield* readLinkState({    ...input,    linkPath: link,  });   const createLink = input.fileSystem.symlink(target, link).pipe(    Effect.catchTags({      PlatformError: (cause) =>        new CodexShadowHomeFileSystemError({          sharedHomePath: input.sharedHomePath,          effectiveHomePath: input.effectiveHomePath,          operation: "symlink",          path: link,          targetPath: target,          entryName: input.entryName,          cause,        }),    }),  );   if (state._tag === "NotSymlink") {    if (!REPLACEABLE_SHARED_RUNTIME_DIRECTORIES.has(input.entryName)) {      return yield* new CodexShadowHomeEntryConflictError({        sharedHomePath: input.sharedHomePath,        effectiveHomePath: input.effectiveHomePath,        entryName: input.entryName,        linkPath: link,        targetPath: target,      });    }     yield* input.fileSystem.remove(link, { recursive: true }).pipe(      Effect.catchTags({        PlatformError: (cause) =>          new CodexShadowHomeFileSystemError({            sharedHomePath: input.sharedHomePath,            effectiveHomePath: input.effectiveHomePath,            operation: "remove",            path: link,            entryName: input.entryName,            cause,          }),      }),    );    return yield* createLink;  }   if (state._tag === "Missing") {    return yield* createLink;  }   const resolvedExisting = path.resolve(path.dirname(link), state.target);  if (resolvedExisting !== target) {    yield* input.fileSystem.remove(link).pipe(      Effect.catchTags({        PlatformError: (cause) =>          new CodexShadowHomeFileSystemError({            sharedHomePath: input.sharedHomePath,            effectiveHomePath: input.effectiveHomePath,            operation: "remove",            path: link,            entryName: input.entryName,            cause,          }),      }),    );    yield* createLink;  }}); const ensureShadowAuthIsPrivate = Effect.fn("CodexHomeLayout.ensureShadowAuthIsPrivate")(  function* (input: {    readonly fileSystem: FileSystem.FileSystem;    readonly sharedHomePath: string;    readonly effectiveHomePath: string;  }): Effect.fn.Return<void, CodexShadowHomeError, Path.Path> {    const path = yield* Path.Path;    const entryName = "auth.json";    const authPath = path.join(input.effectiveHomePath, entryName);    const state = yield* readLinkState({      ...input,      entryName,      linkPath: authPath,    });    if (state._tag === "Symlink") {      return yield* new CodexShadowHomePrivateEntrySymlinkError({        sharedHomePath: input.sharedHomePath,        effectiveHomePath: input.effectiveHomePath,        entryName,        path: authPath,      });    }  },); export const materializeCodexShadowHome = Effect.fn("materializeCodexShadowHome")(function* (  layout: CodexHomeLayout,) {  if (layout.mode !== "authOverlay") return;  const effectiveHomePath = layout.effectiveHomePath;  if (!effectiveHomePath) return;  if (layout.sharedHomePath === effectiveHomePath) {    return yield* new CodexShadowHomePathConflictError({      sharedHomePath: layout.sharedHomePath,      effectiveHomePath,    });  }   const fileSystem = yield* FileSystem.FileSystem;  const path = yield* Path.Path;   const makeDirectory = (directoryPath: string) =>    fileSystem.makeDirectory(directoryPath, { recursive: true }).pipe(      Effect.catchTags({        PlatformError: (cause) =>          new CodexShadowHomeFileSystemError({            sharedHomePath: layout.sharedHomePath,            effectiveHomePath,            operation: "makeDirectory",            path: directoryPath,            cause,          }),      }),    );   yield* Effect.all(    [      makeDirectory(layout.sharedHomePath),      makeDirectory(effectiveHomePath),      ...KNOWN_SHARED_DIRECTORIES.map((directory) =>        makeDirectory(path.join(layout.sharedHomePath, directory)),      ),    ],    { concurrency: "unbounded" },  );   const sharedEntryNames = yield* fileSystem.readDirectory(layout.sharedHomePath).pipe(    Effect.catchTags({      PlatformError: (cause) =>        new CodexShadowHomeFileSystemError({          sharedHomePath: layout.sharedHomePath,          effectiveHomePath,          operation: "readDirectory",          path: layout.sharedHomePath,          cause,        }),    }),  );  const entries = new Set<string>(KNOWN_SHARED_DIRECTORIES);  for (const entryName of sharedEntryNames) {    if (!PRIVATE_ENTRY_NAMES.has(entryName) && !SHADOW_LOCAL_ENTRY_NAMES.has(entryName)) {      entries.add(entryName);    }  }   yield* Effect.forEach(    PRIVATE_ENTRY_NAMES,    (entryName) =>      entryName === "auth.json"        ? Effect.void        : removePrivateSymlink({            fileSystem,            sharedHomePath: layout.sharedHomePath,            effectiveHomePath,            entryName,          }),    { discard: true },  );   yield* Effect.forEach(    entries,    (entryName) => {      if (PRIVATE_ENTRY_NAMES.has(entryName)) {        return Effect.void;      }      return ensureSymlink({        fileSystem,        sharedHomePath: layout.sharedHomePath,        effectiveHomePath,        entryName,      });    },    { discard: true },  );   yield* ensureShadowAuthIsPrivate({    fileSystem,    sharedHomePath: layout.sharedHomePath,    effectiveHomePath,  });}); export function codexContinuationIdentity(layout: CodexHomeLayout) {  return {    driverKind: ProviderDriverKind.make("codex"),    continuationKey: layout.continuationKey,  };}