// @effect-diagnostics nodeBuiltinImport:off import * as NodeServices from "@effect/platform-node/NodeServices"; import * as NodeOS from "node:os"; import * as NodePath from "node:path"; import { expect, it } from "@effect/vitest"; import { ProviderInstanceId } from "@t3tools/contracts"; import { HostProcessPlatform } from "@t3tools/shared/hostProcess"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Layer from "effect/Layer"; import { HttpClient } from "effect/unstable/http"; import * as ChildProcessSpawner from "effect/unstable/process/ChildProcessSpawner"; import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts"; import { ServerConfig } from "../../config.ts"; import { ServerSettingsService } from "../../serverSettings.ts"; import { layerTest as codexResetCreditLayerTest } from "../Layers/codexResetCredit.ts"; import { NoOpProviderEventLoggers, ProviderEventLoggers } from "../Layers/ProviderEventLoggers.ts"; import * as ModelManifest from "../ModelManifest.ts"; import { CodexDriver } from "./CodexDriver.ts"; const testLayer = ServerConfig.layerTest(process.cwd(), { prefix: "t3-codex-driver-maintenance-", }).pipe( Layer.provideMerge(NodeServices.layer), Layer.provideMerge(ServerSettingsService.layerTest()), Layer.provideMerge(ModelManifest.layerTest), Layer.provideMerge(codexResetCreditLayerTest), Layer.provideMerge( Layer.mock(BackgroundPolicy.BackgroundPolicy)({ shouldRunScopeWork: () => Effect.succeed(false), }), ), Layer.provideMerge(Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers)), Layer.provideMerge( Layer.succeed( HttpClient.HttpClient, HttpClient.make(() => Effect.die("Disabled Codex must not make an HTTP request")), ), ), ); // The `#!/bin/sh` stub below cannot be resolved as an executable on Windows. const windowsHost = HostProcessPlatform.defaultValue() === "win32"; const noSpawn = ChildProcessSpawner.make(() => Effect.die("Disabled Codex must not spawn a process"), ); it.layer(testLayer)("CodexDriver", (it) => { it.effect.skipIf(windowsHost)( "runs the standalone updater against the shared home, not the shadow home", () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-codex-driver-" }); const sharedHome = NodePath.join(tempDir, "codex-home"); const shadowHome = NodePath.join(tempDir, "codex-shadow"); const binaryPath = NodePath.join(sharedHome, "packages", "standalone", "bin", "codex"); yield* fs.makeDirectory(NodePath.dirname(binaryPath), { recursive: true }); yield* fs.writeFileString(binaryPath, "#!/bin/sh\n"); yield* fs.chmod(binaryPath, 0o755); const instance = yield* CodexDriver.create({ instanceId: ProviderInstanceId.make("codex-shadow"), displayName: "Codex test", enabled: false, environment: [], config: { ...CodexDriver.defaultConfig(), binaryPath, homePath: sharedHome, shadowHomePath: shadowHome, }, }); const capabilities = yield* instance.snapshot.resolveMaintenance(); expect(capabilities.update).toMatchObject({ executable: binaryPath, args: ["update"], lockKey: "codex-native", env: { CODEX_HOME: sharedHome }, }); }).pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn), Effect.scoped, ), ); it.effect("stays manual-only when the configured executable does not exist", () => Effect.gen(function* () { const instance = yield* CodexDriver.create({ instanceId: ProviderInstanceId.make("codex-missing"), displayName: "Codex test", enabled: false, environment: [], config: { ...CodexDriver.defaultConfig(), binaryPath: NodePath.join(NodeOS.tmpdir(), "t3-codex-missing", "codex"), }, }); expect((yield* instance.snapshot.resolveMaintenance()).update).toBeNull(); }).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn), Effect.scoped), ); for (const fixture of [ { name: "leaves mise npm-backend installations manual-only", installSegments: ["mise", "installs", "npm-openai-codex", "0.110.0"], npmOwned: false, }, { name: "leaves mise tool aliases backed by npm manual-only", installSegments: ["mise", "installs", "codex", "0.110.0"], npmOwned: false, }, { name: "keeps npm updates for globals in a mise Node installation", installSegments: ["mise", "installs", "node", "24.0.0"], npmOwned: true, }, { name: "keeps npm updates for ordinary global installations", installSegments: ["npm-global"], npmOwned: true, }, ] as const) { it.effect.skipIf(windowsHost)(fixture.name, () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: "t3-codex-installer-" }); const installPath = NodePath.join(tempDir, ...fixture.installSegments); const realBinaryPath = NodePath.join( installPath, "lib", "node_modules", "@openai", "codex", "bin", "codex.js", ); const binaryPath = NodePath.join(tempDir, "bin", "codex"); yield* fs.makeDirectory(NodePath.dirname(realBinaryPath), { recursive: true }); yield* fs.makeDirectory(NodePath.dirname(binaryPath), { recursive: true }); yield* fs.writeFileString(realBinaryPath, "#!/bin/sh\n"); yield* fs.chmod(realBinaryPath, 0o755); yield* fs.symlink(realBinaryPath, binaryPath); const instance = yield* CodexDriver.create({ instanceId: ProviderInstanceId.make("codex-installer"), displayName: "Codex installer test", enabled: false, environment: [], config: { ...CodexDriver.defaultConfig(), binaryPath, homePath: NodePath.join(tempDir, "codex-home"), }, }); const update = (yield* instance.snapshot.resolveMaintenance()).update; if (fixture.npmOwned) { expect(update).toMatchObject({ executable: "npm", args: [ "install", "-g", "--prefix", installPath, "--allow-scripts=@openai/codex", "@openai/codex@latest", ], }); } else { expect(update).toBeNull(); } }).pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn), Effect.scoped, ), ); } for (const layout of ["direct", "wrapper"] as const) { it.effect.skipIf(windowsHost)(`leaves a mise ${layout} installation manual-only`, () => Effect.gen(function* () { const fs = yield* FileSystem.FileSystem; const tempDir = yield* fs.makeTempDirectoryScoped({ prefix: `t3-codex-mise-${layout}-` }); const binaryPath = layout === "direct" ? NodePath.join(tempDir, "mise", "installs", "codex", "0.110.0", "codex") : NodePath.join(tempDir, "omarchy", "bin", "codex"); yield* fs.makeDirectory(NodePath.dirname(binaryPath), { recursive: true }); yield* fs.writeFileString( binaryPath, layout === "direct" ? "#!/bin/sh\n" : '#!/bin/sh\nmise use -g --quiet "codex" || exit 1\nexec mise x "codex" -- "codex" "$@"\n', ); yield* fs.chmod(binaryPath, 0o755); const instance = yield* CodexDriver.create({ instanceId: ProviderInstanceId.make(`codex-mise-${layout}`), displayName: "Codex mise test", enabled: false, environment: [], config: { ...CodexDriver.defaultConfig(), binaryPath, homePath: NodePath.join(tempDir, "codex-home"), }, }); expect((yield* instance.snapshot.resolveMaintenance()).update).toBeNull(); }).pipe( Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, noSpawn), Effect.scoped, ), ); } });