774 lines · 28.4 KB · TypeScript
RawDownload
import { describe, expect, it } from "vite-plus/test";import * as Schema from "effect/Schema"; import { ProviderDriverKind, ProviderInstanceId } from "./providerInstance.ts";import {  ClientSettingsSchema,  ClientSettingsPatch,  ClaudeSettings,  DEFAULT_SERVER_SETTINGS,  resolveProviderInstanceEnabled,  ServerSettings,  ServerSettingsPatch,} from "./settings.ts"; const decodeClientSettings = Schema.decodeUnknownSync(ClientSettingsSchema);const decodeClientSettingsPatch = Schema.decodeUnknownSync(ClientSettingsPatch);const encodeClientSettings = Schema.encodeSync(ClientSettingsSchema);const decodeServerSettings = Schema.decodeUnknownSync(ServerSettings);const decodeServerSettingsPatch = Schema.decodeUnknownSync(ServerSettingsPatch);const encodeServerSettings = Schema.encodeSync(ServerSettings);const decodeClaudeSettings = Schema.decodeUnknownSync(ClaudeSettings); describe("ServerSettings usage price overrides", () => {  const prices = { inputCostPerMillionTokens: 2, outputCostPerMillionTokens: 8 };   it("defaults to automatic pricing and round-trips arbitrary model IDs", () => {    expect(decodeServerSettings({}).usagePriceOverrides).toEqual({});    const settings = decodeServerSettings({      usagePriceOverrides: { "  vendor/example-model  ": prices },    });    expect(encodeServerSettings(settings).usagePriceOverrides).toEqual({      "vendor/example-model": prices,    });  });   it("accepts zero rates, optional cache rates, and per-model deletion", () => {    const overrides = {      "example-model": {        inputCostPerMillionTokens: 0,        outputCostPerMillionTokens: 0,        cacheReadCostPerMillionTokens: 0.5,        cacheWriteCostPerMillionTokens: 3,      },      "removed-model": null,    };    expect(      decodeServerSettingsPatch({ usagePriceOverrides: overrides }).usagePriceOverrides,    ).toEqual(overrides);  });   it.each([    "inputCostPerMillionTokens",    "outputCostPerMillionTokens",    "cacheReadCostPerMillionTokens",    "cacheWriteCostPerMillionTokens",  ])("rejects invalid %s rates at the settings boundary", (field) => {    for (const value of [-1, Number.NaN, Number.POSITIVE_INFINITY, "2"]) {      const usagePriceOverrides = { "example-model": { ...prices, [field]: value } };      expect(() => decodeServerSettings({ usagePriceOverrides })).toThrow();      expect(() => decodeServerSettingsPatch({ usagePriceOverrides })).toThrow();    }  });   it("rejects empty model IDs and incomplete input/output pricing", () => {    for (const usagePriceOverrides of [      { " ": prices },      { "example-model": { inputCostPerMillionTokens: 2 } },      { "example-model": { outputCostPerMillionTokens: 8 } },    ]) {      expect(() => decodeServerSettingsPatch({ usagePriceOverrides })).toThrow();    }  });}); describe("custom model settings", () => {  const capabilities = {    optionDescriptors: [      {        id: "effort",        label: "Reasoning",        type: "select",        options: [{ id: "high", label: "High", isDefault: true }],      },    ],  };   it("accepts legacy bare slugs alongside full entries", () => {    const decoded = decodeClaudeSettings({      customModels: ["bare-slug", { slug: "named", name: "Named", capabilities }],    });    expect(decoded.customModels).toEqual([      "bare-slug",      { slug: "named", name: "Named", capabilities },    ]);  });   it("accepts entries at the settings patch boundary", () => {    expect(      decodeServerSettingsPatch({        providers: { codex: { customModels: [{ slug: "x", capabilities }] } },      }).providers?.codex?.customModels,    ).toEqual([{ slug: "x", capabilities }]);    expect(() =>      decodeServerSettingsPatch({ providers: { codex: { customModels: [{ name: "no slug" }] } } }),    ).toThrow();  });}); describe("ClaudeSettings auto-compaction", () => {  it("uses Claude's default threshold when no override is configured", () => {    expect(decodeClaudeSettings({}).autoCompactWindow).toBe("");  });   it.each(["100000", "300000", "1000000"])(    "accepts a supported auto-compaction threshold: %s",    (value) => {      expect(decodeClaudeSettings({ autoCompactWindow: value }).autoCompactWindow).toBe(value);    },  );   it.each(["99999", "1000001", "300k", "invalid"])(    "rejects an unsupported auto-compaction threshold: %s",    (value) => {      expect(() => decodeClaudeSettings({ autoCompactWindow: value })).toThrow();    },  );   it("rejects an unsupported threshold at the settings patch boundary", () => {    expect(() =>      decodeServerSettingsPatch({ providers: { claudeAgent: { autoCompactWindow: "300k" } } }),    ).toThrow();    expect(      decodeServerSettingsPatch({ providers: { claudeAgent: { autoCompactWindow: "300000" } } }),    ).toBeDefined();  });}); describe("ClientSettings diff colors", () => {  it("keeps red and green for existing settings without a saved palette", () => {    expect(decodeClientSettings({}).diffColorScheme).toBe("red-green");  });   it.each(["red-green", "blue-orange"])("round-trips the %s palette", (diffColorScheme) => {    const settings = decodeClientSettings({ diffColorScheme });    expect(encodeClientSettings(settings).diffColorScheme).toBe(diffColorScheme);    expect(decodeClientSettingsPatch({ diffColorScheme }).diffColorScheme).toBe(diffColorScheme);  });   it("rejects unsupported palettes", () => {    expect(() => decodeClientSettings({ diffColorScheme: "purple-yellow" })).toThrow();    expect(() => decodeClientSettingsPatch({ diffColorScheme: "purple-yellow" })).toThrow();  });}); describe("ClientSettings load balancing", () => {  it("requires opt-in when settings are new or omit load balancing", () => {    expect(decodeClientSettings({}).loadBalancingEnabled).toBe(false);    expect(decodeClientSettings({ loadBalancingWeights: {} }).loadBalancingEnabled).toBe(false);  });   it.each([true, false])("preserves a saved choice of %s", (loadBalancingEnabled) => {    const settings = decodeClientSettings({ loadBalancingEnabled });    expect(encodeClientSettings(settings).loadBalancingEnabled).toBe(loadBalancingEnabled);    expect(decodeClientSettingsPatch({ loadBalancingEnabled }).loadBalancingEnabled).toBe(      loadBalancingEnabled,    );  });}); describe("ClientSettings word wrap", () => {  it("defaults word wrap on", () => {    expect(decodeClientSettings({}).wordWrap).toBe(true);  });   it("ignores obsolete wrapping preferences", () => {    const decoded = decodeClientSettings({      chatWordWrap: false,      diffWordWrap: false,    });     expect(decoded.wordWrap).toBe(true);    expect(decoded).not.toHaveProperty("chatWordWrap");    expect(decoded).not.toHaveProperty("diffWordWrap");  });}); describe("ClientSettings window capture", () => {  it("defaults capture off while keeping its feedback enabled", () => {    const settings = decodeClientSettings({});     expect(settings.snapShotEnabled).toBe(false);    expect(settings.snapShotIncludeAccessibility).toBe(true);    expect(settings.snapShotShortcut).toEqual({ kind: "both-shift-keys" });    expect(settings.snapShotPlaySound).toBe(true);    expect(settings.snapShotSound).toBe("soft-pop");    expect(settings.snapShotFlash).toBe(true);    expect(settings.snapShotAnimations).toBe(true);  });   it("accepts capture preference updates", () => {    expect(      decodeClientSettingsPatch({        snapShotEnabled: true,        snapShotIncludeAccessibility: false,        snapShotShortcut: {          key: "w",          metaKey: false,          ctrlKey: false,          shiftKey: true,          altKey: true,          modKey: false,        },        snapShotPlaySound: false,        snapShotSound: "camera-shutter",        snapShotFlash: false,        snapShotAnimations: false,      }),    ).toEqual({      snapShotEnabled: true,      snapShotIncludeAccessibility: false,      snapShotShortcut: {        key: "w",        metaKey: false,        ctrlKey: false,        shiftKey: true,        altKey: true,        modKey: false,      },      snapShotPlaySound: false,      snapShotSound: "camera-shutter",      snapShotFlash: false,      snapShotAnimations: false,    });  });   it("rejects unknown capture sounds", () => {    expect(() => decodeClientSettingsPatch({ snapShotSound: "doorbell" })).toThrow();  });   it("accepts modifier pair shortcuts", () => {    expect(      decodeClientSettingsPatch({        snapShotShortcut: { kind: "modifier-pair", modifier: "meta" },      }),    ).toEqual({      snapShotShortcut: { kind: "modifier-pair", modifier: "meta" },    });    expect(() =>      decodeClientSettingsPatch({        snapShotShortcut: { kind: "modifier-pair", modifier: "hyper" },      }),    ).toThrow();  });   it("rejects a capture shortcut with no modifier", () => {    expect(() =>      decodeClientSettingsPatch({        snapShotShortcut: {          key: "w",          metaKey: false,          ctrlKey: false,          shiftKey: false,          altKey: false,          modKey: false,        },      }),    ).toThrow();  });}); describe("ClientSettings proactive panels", () => {  it("is opt-in and accepts client-local updates", () => {    expect(decodeClientSettings({}).proactivePanelsEnabled).toBe(false);    expect(decodeClientSettingsPatch({ proactivePanelsEnabled: true }).proactivePanelsEnabled).toBe(      true,    );  });}); describe("ClientSettings quit confirmation", () => {  it("defaults to hold", () => {    expect(decodeClientSettings({}).confirmQuit).toBe("hold");  });   it.each(["direct", "hold", "double-click"] as const)("accepts the %s mode", (mode) => {    expect(decodeClientSettings({ confirmQuit: mode }).confirmQuit).toBe(mode);    expect(decodeClientSettingsPatch({ confirmQuit: mode }).confirmQuit).toBe(mode);  });   it.each([    [true, "hold"],    [false, "direct"],  ] as const)("migrates the legacy %s value to %s", (legacyValue, mode) => {    const settings = decodeClientSettings({ confirmQuit: legacyValue });     expect(settings.confirmQuit).toBe(mode);    expect(encodeClientSettings(settings).confirmQuit).toBe(mode);  });   it("rejects legacy booleans at the patch boundary", () => {    expect(() => decodeClientSettingsPatch({ confirmQuit: true })).toThrow();  });}); describe("ClientSettings browser recording frame rate", () => {  it("defaults to 30 fps", () => {    expect(decodeClientSettings({}).browserRecordingFrameRate).toBe(30);  });   it.each([30, 60])("accepts a supported frame rate: %s", (frameRate) => {    expect(      decodeClientSettings({ browserRecordingFrameRate: frameRate }).browserRecordingFrameRate,    ).toBe(frameRate);    expect(      decodeClientSettingsPatch({ browserRecordingFrameRate: frameRate }).browserRecordingFrameRate,    ).toBe(frameRate);  });   it.each([24, 59, 120])("rejects an unsupported frame rate: %s", (frameRate) => {    expect(() => decodeClientSettings({ browserRecordingFrameRate: frameRate })).toThrow();    expect(() => decodeClientSettingsPatch({ browserRecordingFrameRate: frameRate })).toThrow();  });}); describe("ClientSettings glass opacity", () => {  it("defaults to a readable translucent surface", () => {    expect(decodeClientSettings({}).glassOpacity).toBe(80);  });   it.each([39, 101, 72.5])("rejects an invalid glass opacity: %s", (value) => {    expect(() => decodeClientSettings({ glassOpacity: value })).toThrow();    expect(() => decodeClientSettingsPatch({ glassOpacity: value })).toThrow();  });   it.each([40, 75, 100])("accepts a glass opacity within the supported range: %s", (value) => {    expect(decodeClientSettings({ glassOpacity: value }).glassOpacity).toBe(value);    expect(decodeClientSettingsPatch({ glassOpacity: value }).glassOpacity).toBe(value);  });}); describe("ClientSettings appearance contrast", () => {  it("defaults to the theme's original contrast", () => {    expect(decodeClientSettings({}).appearanceContrast).toBe(100);  });   it.each([49, 201, 92.5])("rejects an invalid appearance contrast: %s", (value) => {    expect(() => decodeClientSettings({ appearanceContrast: value })).toThrow();    expect(() => decodeClientSettingsPatch({ appearanceContrast: value })).toThrow();  });   it.each([50, 100, 150, 200])("accepts an appearance contrast in range: %s", (value) => {    expect(decodeClientSettings({ appearanceContrast: value }).appearanceContrast).toBe(value);    expect(decodeClientSettingsPatch({ appearanceContrast: value }).appearanceContrast).toBe(value);  });}); describe("ClientSettings panel animations", () => {  it("defaults to instant changes", () => {    expect(decodeClientSettings({}).panelAnimationDurationMs).toBe(0);  });   it.each([0, 400])("accepts a panel animation duration: %s", (value) => {    expect(decodeClientSettingsPatch({ panelAnimationDurationMs: value })).toEqual({      panelAnimationDurationMs: value,    });  });   it.each([-1, 401, 150.5])("rejects an invalid panel animation duration: %s", (value) => {    expect(() => decodeClientSettingsPatch({ panelAnimationDurationMs: value })).toThrow();  });}); describe("ClientSettings environment identification", () => {  it("defaults to artwork and accepts each presentation mode", () => {    expect(decodeClientSettings({}).environmentIdentificationMode).toBe("artwork");     for (const mode of ["artwork", "pill", "none"] as const) {      expect(        decodeClientSettingsPatch({ environmentIdentificationMode: mode })          .environmentIdentificationMode,      ).toBe(mode);    }  });   it("rejects unsupported presentation modes", () => {    expect(() => decodeClientSettings({ environmentIdentificationMode: "badge" })).toThrow();    expect(() => decodeClientSettingsPatch({ environmentIdentificationMode: "badge" })).toThrow();  });}); describe("ClientSettings sidebar", () => {  it("defaults to the current sidebar", () => {    expect(decodeClientSettings({}).legacySidebarEnabled).toBe(false);  });   it("drops the retired sidebar v2 beta keys, resetting everyone to the default", () => {    const decoded = decodeClientSettings({      sidebarV2Enabled: false,      sidebarV2ConfiguredByUser: true,    });    expect(decoded.legacySidebarEnabled).toBe(false);    expect(decoded).not.toHaveProperty("sidebarV2Enabled");    expect(decoded).not.toHaveProperty("sidebarV2ConfiguredByUser");  });   it("preserves an explicit legacy sidebar opt-in", () => {    expect(decodeClientSettings({ legacySidebarEnabled: true }).legacySidebarEnabled).toBe(true);    expect(decodeClientSettingsPatch({ legacySidebarEnabled: true }).legacySidebarEnabled).toBe(      true,    );  });   it("keeps unpin confirmation opt-in and patchable", () => {    expect(decodeClientSettings({}).confirmThreadUnpin).toBe(false);    expect(decodeClientSettingsPatch({ confirmThreadUnpin: true }).confirmThreadUnpin).toBe(true);    expect(() => decodeClientSettingsPatch({ confirmThreadUnpin: "yes" })).toThrow();  });}); describe("ClientSettings context window meter", () => {  it("defaults off and preserves an explicit legacy opt-in", () => {    expect(decodeClientSettings({}).contextWindowMeterEnabled).toBe(false);    expect(      decodeClientSettings({ contextWindowMeterEnabled: true }).contextWindowMeterEnabled,    ).toBe(true);    expect(      decodeClientSettingsPatch({ contextWindowMeterEnabled: true }).contextWindowMeterEnabled,    ).toBe(true);  });}); describe("ClientSettings composer collapse", () => {  it("collapses on scroll by default and accepts opting out", () => {    expect(decodeClientSettings({}).composerCollapseOnScroll).toBe(true);    expect(      decodeClientSettingsPatch({ composerCollapseOnScroll: false }).composerCollapseOnScroll,    ).toBe(false);  });   it("drops the retired blur trigger key", () => {    const decoded = decodeClientSettings({ composerCollapseOnBlur: false });    expect(decoded.composerCollapseOnScroll).toBe(true);    expect(decoded).not.toHaveProperty("composerCollapseOnBlur");  });}); describe("ServerSettings thread settlement", () => {  it("defaults merge settlement on and inactivity settlement to three days", () => {    const settings = decodeServerSettings({});    expect(settings.sidebarAutoSettleAfterDays).toBe(3);    expect(settings.sidebarAutoSettleOnMerge).toBe(true);  });   it("allows both automatic rules to be disabled", () => {    expect(      decodeServerSettings({        sidebarAutoSettleAfterDays: null,        sidebarAutoSettleOnMerge: false,      }),    ).toMatchObject({ sidebarAutoSettleAfterDays: null, sidebarAutoSettleOnMerge: false });    expect(      decodeServerSettingsPatch({        sidebarAutoSettleAfterDays: null,        sidebarAutoSettleOnMerge: false,      }),    ).toMatchObject({ sidebarAutoSettleAfterDays: null, sidebarAutoSettleOnMerge: false });  });   it.each([-1, 0, 91])("rejects an auto-settle threshold outside 1..90: %s", (value) => {    expect(() => decodeServerSettings({ sidebarAutoSettleAfterDays: value })).toThrow();    expect(() => decodeServerSettingsPatch({ sidebarAutoSettleAfterDays: value })).toThrow();  });}); describe("ClientSettings pull request merge methods", () => {  it("defaults to no project overrides and accepts supported methods", () => {    expect(decodeClientSettings({}).pullRequestMergeMethodOverrides).toEqual({});    expect(      decodeClientSettingsPatch({        pullRequestMergeMethodOverrides: { project: "squash" },      }).pullRequestMergeMethodOverrides,    ).toEqual({ project: "squash" });  });   it("rejects unsupported project merge methods", () => {    expect(() =>      decodeClientSettingsPatch({        pullRequestMergeMethodOverrides: { project: "fast-forward" },      }),    ).toThrow();  });}); describe("ServerSettings.providerInstances (slice-2 invariant)", () => {  it("defaults text generation to Luna at low reasoning effort", () => {    expect(DEFAULT_SERVER_SETTINGS.textGenerationModelSelection).toEqual({      instanceId: ProviderInstanceId.make("codex"),      model: "gpt-5.6-luna",      options: [{ id: "reasoningEffort", value: "low" }],    });

Lines 1–500 of 774.