1/**
2 * OpenCode instance settings. Shared by the server driver and the client
3 * settings form, so it holds only browser-safe schema code.
4 *
5 * @module provider-opencode/settings
6 */
7import {
8 CustomModelSetting,
9 makeBinaryPathSetting,
10 makeProviderSettingsSchema,
11 TrimmedString,
12} from "@t3tools/contracts";
13import * as Effect from "effect/Effect";
14import * as Schema from "effect/Schema";
15
16export const OpenCodeSettings = makeProviderSettingsSchema(
17 {
18 // Off by default (like Cursor and Grok): the binding is not yet stable
19 // enough to probe on every install. Users opt in from Settings.
20 enabled: Schema.Boolean.pipe(
21 Schema.withDecodingDefault(Effect.succeed(false)),
22 Schema.annotateKey({ providerSettingsForm: { hidden: true } }),
23 ),
24 binaryPath: makeBinaryPathSetting("opencode").pipe(
25 Schema.annotateKey({
26 title: "Binary path",
27 description: "Path to the OpenCode binary.",
28 providerSettingsForm: {
29 placeholder: "opencode",
30 clearWhenEmpty: "omit",
31 },
32 }),
33 ),
34 serverUrl: TrimmedString.pipe(
35 Schema.withDecodingDefault(Effect.succeed("")),
36 Schema.annotateKey({
37 title: "Server URL",
38 description: "Leave blank to let T3 Code spawn the server when needed.",
39 providerSettingsForm: {
40 placeholder: "http://127.0.0.1:4096",
41 clearWhenEmpty: "omit",
42 },
43 }),
44 ),
45 serverPassword: TrimmedString.pipe(
46 Schema.withDecodingDefault(Effect.succeed("")),
47 Schema.annotateKey({
48 title: "Server password",
49 description: "Stored in plain text on disk.",
50 providerSettingsForm: {
51 control: "password",
52 placeholder: "Optional",
53 clearWhenEmpty: "omit",
54 },
55 }),
56 ),
57 customModels: Schema.Array(CustomModelSetting).pipe(
58 Schema.withDecodingDefault(Effect.succeed([])),
59 Schema.annotateKey({ providerSettingsForm: { hidden: true } }),
60 ),
61 },
62 {
63 order: ["binaryPath", "serverUrl", "serverPassword"],
64 },
65);
66export type OpenCodeSettings = typeof OpenCodeSettings.Type;