feat(core): add runtime and sharing config schema

This commit is contained in:
Dax Raad 2026-05-28 00:40:37 -04:00
commit b9c9fcbfec
11 changed files with 150 additions and 14 deletions

View file

@ -8,10 +8,14 @@ import { Global } from "./global"
import { Location } from "./location"
import { Policy } from "./policy"
import { AbsolutePath } from "./schema"
import { ConfigAttachments } from "./config/attachments"
import { ConfigExperimental } from "./config/experimental"
import { ConfigFormatter } from "./config/formatter"
import { ConfigLSP } from "./config/lsp"
import { ConfigPlugin } from "./config/plugin"
import { ConfigProvider } from "./config/provider"
import { ConfigReference } from "./config/reference"
import { ConfigToolOutput } from "./config/tool-output"
import { ConfigWatcher } from "./config/watcher"
export class Info extends Schema.Class<Info>("Config.Info")({
@ -27,12 +31,35 @@ export class Info extends Schema.Class<Info>("Config.Info")({
autoupdate: Schema.Union([Schema.Boolean, Schema.Literal("notify")]).pipe(Schema.optional).annotate({
description: "Automatically update or notify when a new version is available",
}),
share: Schema.Literals(["manual", "auto", "disabled"]).pipe(Schema.optional).annotate({
description: "Control whether sessions may be shared manually, automatically, or not at all",
}),
enterprise: Schema.Struct({
url: Schema.String.pipe(Schema.optional),
}).pipe(Schema.optional).annotate({
description: "Enterprise sharing service configuration",
}),
username: Schema.String.pipe(Schema.optional).annotate({
description: "Username displayed in conversations and used for telemetry identity",
}),
snapshots: Schema.Boolean.pipe(Schema.optional).annotate({
description: "Enable snapshots used for undo and revert behavior",
}),
watcher: ConfigWatcher.Info.pipe(Schema.optional).annotate({
description: "Filesystem watcher configuration",
}),
formatter: ConfigFormatter.Info.pipe(Schema.optional).annotate({
description: "Enable built-in formatters or configure formatter overrides",
}),
lsp: ConfigLSP.Info.pipe(Schema.optional).annotate({
description: "Enable built-in language servers or configure server overrides",
}),
attachments: ConfigAttachments.Info.pipe(Schema.optional).annotate({
description: "Attachment processing configuration",
}),
tool_output: ConfigToolOutput.Info.pipe(Schema.optional).annotate({
description: "Tool output truncation thresholds",
}),
skills: Schema.String.pipe(Schema.Array, Schema.optional).annotate({
description: "Additional paths or URLs to discover skills from",
}),

View file

@ -0,0 +1,15 @@
export * as ConfigAttachments from "./attachments"
import { Schema } from "effect"
import { PositiveInt } from "../schema"
export class Image extends Schema.Class<Image>("ConfigV2.Attachments.Image")({
auto_resize: Schema.Boolean.pipe(Schema.optional),
max_width: PositiveInt.pipe(Schema.optional),
max_height: PositiveInt.pipe(Schema.optional),
max_base64_bytes: PositiveInt.pipe(Schema.optional),
}) {}
export class Info extends Schema.Class<Info>("ConfigV2.Attachments")({
image: Image.pipe(Schema.optional),
}) {}

View file

@ -8,11 +8,11 @@ import { Policy as PolicyV2 } from "../policy"
// this union makes it valid in authored config while keeping Policy generic.
export const PolicyAction = Schema.Union([Catalog.PolicyActions])
export class Policy extends Schema.Class<Policy>("Config.Experimental.Policy")({
export class Policy extends Schema.Class<Policy>("ConfigV2.Experimental.Policy")({
...PolicyV2.Info.fields,
action: PolicyAction,
}) {}
export class Experimental extends Schema.Class<Experimental>("Config.Experimental")({
export class Experimental extends Schema.Class<Experimental>("ConfigV2.Experimental")({
policies: Policy.pipe(Schema.Array, Schema.optional),
}) {}

View file

@ -0,0 +1,12 @@
export * as ConfigFormatter from "./formatter"
import { Schema } from "effect"
export class Entry extends Schema.Class<Entry>("ConfigV2.Formatter.Entry")({
disabled: Schema.Boolean.pipe(Schema.optional),
command: Schema.String.pipe(Schema.Array, Schema.optional),
environment: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional),
extensions: Schema.String.pipe(Schema.Array, Schema.optional),
}) {}
export const Info = Schema.Union([Schema.Boolean, Schema.Record(Schema.String, Entry)])

View file

@ -0,0 +1,18 @@
export * as ConfigLSP from "./lsp"
import { Schema } from "effect"
export const Disabled = Schema.Struct({
disabled: Schema.Literal(true),
})
export class Server extends Schema.Class<Server>("ConfigV2.LSP.Server")({
command: Schema.String.pipe(Schema.Array),
extensions: Schema.String.pipe(Schema.Array, Schema.optional),
disabled: Schema.Boolean.pipe(Schema.optional),
env: Schema.Record(Schema.String, Schema.String).pipe(Schema.optional),
initialization: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
}) {}
export const Entry = Schema.Union([Disabled, Server])
export const Info = Schema.Union([Schema.Boolean, Schema.Record(Schema.String, Entry)])

View file

@ -2,7 +2,7 @@ export * as ConfigPlugin from "./plugin"
import { Schema } from "effect"
export class Entry extends Schema.Class<Entry>("Config.Plugin.Entry")({
export class Entry extends Schema.Class<Entry>("ConfigV2.Plugin.Entry")({
package: Schema.String,
options: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
}) {}

View file

@ -2,12 +2,12 @@ export * as ConfigReference from "./reference"
import { Schema } from "effect"
export class Git extends Schema.Class<Git>("Config.Reference.Git")({
export class Git extends Schema.Class<Git>("ConfigV2.Reference.Git")({
repository: Schema.String,
branch: Schema.String.pipe(Schema.optional),
}) {}
export class Local extends Schema.Class<Local>("Config.Reference.Local")({
export class Local extends Schema.Class<Local>("ConfigV2.Reference.Local")({
path: Schema.String,
}) {}

View file

@ -0,0 +1,9 @@
export * as ConfigToolOutput from "./tool-output"
import { Schema } from "effect"
import { PositiveInt } from "../schema"
export class Info extends Schema.Class<Info>("ConfigV2.ToolOutput")({
max_lines: PositiveInt.pipe(Schema.optional),
max_bytes: PositiveInt.pipe(Schema.optional),
}) {}

View file

@ -2,6 +2,6 @@ export * as ConfigWatcher from "./watcher"
import { Schema } from "effect"
export class Info extends Schema.Class<Info>("Config.Watcher")({
export class Info extends Schema.Class<Info>("ConfigV2.Watcher")({
ignore: Schema.String.pipe(Schema.Array, Schema.optional),
}) {}