1import * as Schema from "effect/Schema";
2import { describe, expect, it } from "vite-plus/test";
3
4import {
5 DEFAULT_TERMINAL_ID,
6 TerminalError,
7 TerminalOpenInput,
8 TerminalProviderEnvironmentError,
9} from "./terminal.ts";
10import { ProviderInstanceId } from "./providerInstance.ts";
11
12const encodeTerminalError = Schema.encodeUnknownSync(TerminalError);
13const decodeTerminalError = Schema.decodeUnknownSync(TerminalError);
14
15function decodeSync<S extends Schema.Top>(schema: S, input: unknown): Schema.Schema.Type<S> {
16 return Schema.decodeUnknownSync(schema as never)(input) as Schema.Schema.Type<S>;
17}
18
19describe("TerminalProviderEnvironmentError", () => {
20 it("round-trips its required cause without exposing it in the message", () => {
21 const cause = { operation: "read-secret", detail: "secret backend unavailable" };
22 const error = new TerminalProviderEnvironmentError({
23 providerInstanceId: ProviderInstanceId.make("codex_work"),
24 cause,
25 });
26 const encoded = encodeTerminalError(error);
27 const decoded = decodeTerminalError(encoded);
28
29 expect(decoded).toMatchObject({
30 _tag: "TerminalProviderEnvironmentError",
31 providerInstanceId: "codex_work",
32 cause,
33 });
34 expect(decoded.message).toBe(
35 "Could not prepare the terminal environment for provider instance: codex_work",
36 );
37 expect(decoded.message).not.toContain("secret backend unavailable");
38 });
39});
40
41describe("TerminalOpenInput", () => {
42 it("drops invalid env keys while retaining valid overrides", () => {
43 const parsed = decodeSync(TerminalOpenInput, {
44 threadId: "thread-1",
45 terminalId: DEFAULT_TERMINAL_ID,
46 cwd: "/tmp/project",
47 env: { "bad-key": "1", GOOD_KEY: "2" },
48 });
49 expect(parsed.env).toEqual({ GOOD_KEY: "2" });
50 });
51});