1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { describe, expect, it } from "@effect/vitest";
3import * as Effect from "effect/Effect";
4import * as Path from "effect/Path";
5import * as HostProcess from "@t3tools/shared/HostProcess";
6
7import { mergeProviderInstanceEnvironment } from "./instanceEnvironment.ts";
8
9describe("mergeProviderInstanceEnvironment", () => {
10 it.effect.each([
11 { value: "~/.account", tail: ".account" },
12 { value: "~\\.account\\work", tail: ".account\\work" },
13 ])("expands configured provider homes set to $value", ({ value, tail }) =>
14 Effect.gen(function* () {
15 const path = yield* Path.Path;
16 const baseEnv = {
17 CODEX_HOME: "~/.inherited-codex",
18 CLAUDE_CONFIG_DIR: "~/.inherited-claude",
19 };
20 const environment = yield* mergeProviderInstanceEnvironment(
21 [
22 { name: "CODEX_HOME", value, sensitive: false },
23 { name: "CLAUDE_CONFIG_DIR", value, sensitive: false },
24 { name: "CUSTOM_VALUE", value, sensitive: false },
25 ],
26 baseEnv,
27 );
28
29 expect(environment).toEqual({
30 CODEX_HOME: path.join("/home/ada", tail),
31 CLAUDE_CONFIG_DIR: path.join("/home/ada", tail),
32 CUSTOM_VALUE: value,
33 });
34 expect(baseEnv).toEqual({
35 CODEX_HOME: "~/.inherited-codex",
36 CLAUDE_CONFIG_DIR: "~/.inherited-claude",
37 });
38 }).pipe(
39 Effect.provideService(HostProcess.HomeDirectory, "/home/ada"),
40 Effect.provide(NodeServices.layer),
41 ),
42 );
43
44 it.effect("leaves inherited provider homes unchanged", () =>
45 Effect.gen(function* () {
46 const baseEnv = { CODEX_HOME: "~/.codex", CLAUDE_CONFIG_DIR: "~\\.claude" };
47
48 expect(
49 yield* mergeProviderInstanceEnvironment(
50 [{ name: "CUSTOM_VALUE", value: "~/.custom", sensitive: false }],
51 baseEnv,
52 ),
53 ).toEqual({ ...baseEnv, CUSTOM_VALUE: "~/.custom" });
54 }),
55 );
56
57 it.effect("overrides inherited environment values and preserves empty strings", () =>
58 Effect.gen(function* () {
59 expect(
60 yield* mergeProviderInstanceEnvironment(
61 [
62 { name: "OPENROUTER_API_KEY", value: "sk-or-test", sensitive: true },
63 { name: "ANTHROPIC_API_KEY", value: "", sensitive: false },
64 ],
65 { ANTHROPIC_API_KEY: "inherited", PATH: "/bin" },
66 ),
67 ).toMatchObject({
68 OPENROUTER_API_KEY: "sk-or-test",
69 ANTHROPIC_API_KEY: "",
70 PATH: "/bin",
71 });
72 }),
73 );
74});