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, };}
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,
};
}