import * as Effect from "effect/Effect";import * as Schema from "effect/Schema";import { type EnvironmentMachineKind, ExecutionEnvironmentDescriptor, ServerSelfUpdateMethod,} from "./environment.ts";import { ServerAuthDescriptor } from "./auth.ts";import { ForwardCompatibleArray, IsoDateTime, NonNegativeInt, PositiveInt, ProjectId, ThreadId, TrimmedNonEmptyString,} from "./baseSchemas.ts";import { KeybindingCommand, KeybindingValue, KeybindingWhen, ResolvedKeybindingsConfig,} from "./keybindings.ts";import { EditorId, FileManagerRevealKind, RemoteOpenTarget } from "./editor.ts";import { ModelCapabilities } from "./model.ts";import { ProviderDriverKind, ProviderInstanceId } from "./providerInstance.ts";import { ServerProviderUsageLimits, UsageLimitSourceSnapshots } from "./providerUsageLimits.ts";import { ServerSettings } from "./settings.ts"; const KeybindingsMalformedConfigIssue = Schema.Struct({ kind: Schema.Literal("keybindings.malformed-config"), message: TrimmedNonEmptyString,}); const KeybindingsInvalidEntryIssue = Schema.Struct({ kind: Schema.Literal("keybindings.invalid-entry"), message: TrimmedNonEmptyString, index: Schema.Number,}); export const ServerConfigIssue = Schema.Union([ KeybindingsMalformedConfigIssue, KeybindingsInvalidEntryIssue,]);export type ServerConfigIssue = typeof ServerConfigIssue.Type; // Issue kinds grow over time; older clients must not fail the whole config// decode over a kind they cannot render.const ServerConfigIssues = ForwardCompatibleArray(ServerConfigIssue); export const ServerProviderState = Schema.Literals(["ready", "warning", "error", "disabled"]);export type ServerProviderState = typeof ServerProviderState.Type; export const ServerProviderAuthStatus = Schema.Literals([ "authenticated", "unauthenticated", "unknown",]);export type ServerProviderAuthStatus = typeof ServerProviderAuthStatus.Type; export const ServerProviderAuth = Schema.Struct({ status: ServerProviderAuthStatus, type: Schema.optional(TrimmedNonEmptyString), label: Schema.optional(TrimmedNonEmptyString), email: Schema.optional(TrimmedNonEmptyString),});export type ServerProviderAuth = typeof ServerProviderAuth.Type; export const ServerProviderModel = Schema.Struct({ slug: TrimmedNonEmptyString, name: TrimmedNonEmptyString, shortName: Schema.optional(TrimmedNonEmptyString), subProvider: Schema.optional(TrimmedNonEmptyString), aliases: Schema.optional(Schema.Array(TrimmedNonEmptyString)), badge: Schema.optional(Schema.Literal("new")), isCustom: Schema.Boolean, isDefault: Schema.optional(Schema.Boolean), isLegacy: Schema.optional(Schema.Boolean), capabilities: Schema.NullOr(ModelCapabilities),});export type ServerProviderModel = typeof ServerProviderModel.Type; export const ServerProviderSlashCommandInput = Schema.Struct({ hint: TrimmedNonEmptyString,});export type ServerProviderSlashCommandInput = typeof ServerProviderSlashCommandInput.Type; export const ServerProviderSlashCommand = Schema.Struct({ name: TrimmedNonEmptyString, description: Schema.optional(TrimmedNonEmptyString), input: Schema.optional(ServerProviderSlashCommandInput),});export type ServerProviderSlashCommand = typeof ServerProviderSlashCommand.Type; export const ServerProviderSkill = Schema.Struct({ name: TrimmedNonEmptyString, description: Schema.optional(TrimmedNonEmptyString), path: TrimmedNonEmptyString, scope: Schema.optional(TrimmedNonEmptyString), enabled: Schema.Boolean, displayName: Schema.optional(TrimmedNonEmptyString), shortDescription: Schema.optional(TrimmedNonEmptyString), /** * The skill is hidden from the agent's own skill tool, so only the user can * start it — Claude Code's `disable-model-invocation`. Composers must offer * it as a slash command; naming it in prose does nothing. */ userInvocationOnly: Schema.optional(Schema.Boolean), /** * The mirror of {@link ServerProviderSkill.userInvocationOnly}: Claude Code's * `user-invocable: false` keeps the skill out of its own slash commands, so * only the agent can start it. Composers must not offer it under `/`. */ userInvocable: Schema.optional(Schema.Boolean),});export type ServerProviderSkill = typeof ServerProviderSkill.Type; export const ServerProviderWorkspaceSnapshot = Schema.Struct({ cwd: TrimmedNonEmptyString, checkedAt: IsoDateTime, slashCommands: Schema.Array(ServerProviderSlashCommand), skills: Schema.Array(ServerProviderSkill),});export type ServerProviderWorkspaceSnapshot = typeof ServerProviderWorkspaceSnapshot.Type; /** * Availability of a configured provider instance from the runtime's POV. * * - `available` — the build ships this driver and an instance is wired * up. Default for legacy snapshots produced from the closed * `ServerSettings.providers` map. * - `unavailable` — the user's `ServerSettings.providerInstances` (or a * persisted thread / session binding) references a driver this build * doesn't ship. Common after rolling back from a fork or PR branch * that introduced a new driver. The snapshot is preserved so the UI * can render "missing driver" affordances and so the data round-trips * when the user moves back to the fork. * * Snapshots with `availability: "unavailable"` MUST set * `installed: false` and `enabled: false`; the runtime refuses turn * starts against them with a structured error. */export const ServerProviderAvailability = Schema.Literals(["available", "unavailable"]);export type ServerProviderAvailability = typeof ServerProviderAvailability.Type; export const ServerProviderContinuation = Schema.Struct({ groupKey: TrimmedNonEmptyString,});export type ServerProviderContinuation = typeof ServerProviderContinuation.Type; export const ServerProviderVersionAdvisoryStatus = Schema.Literals([ "unknown", "current", "behind_latest",]);export type ServerProviderVersionAdvisoryStatus = typeof ServerProviderVersionAdvisoryStatus.Type; export const ServerProviderVersionAdvisory = Schema.Struct({ status: ServerProviderVersionAdvisoryStatus, currentVersion: Schema.NullOr(TrimmedNonEmptyString), latestVersion: Schema.NullOr(TrimmedNonEmptyString), updateCommand: Schema.NullOr(TrimmedNonEmptyString), canUpdate: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), checkedAt: Schema.NullOr(IsoDateTime), message: Schema.NullOr(TrimmedNonEmptyString),});export type ServerProviderVersionAdvisory = typeof ServerProviderVersionAdvisory.Type; export const ServerProviderUpdateStatus = Schema.Literals([ "idle", "queued", "running", "succeeded", "failed", "unchanged",]);export type ServerProviderUpdateStatus = typeof ServerProviderUpdateStatus.Type; export const ServerProviderUpdateState = Schema.Struct({ status: ServerProviderUpdateStatus, startedAt: Schema.NullOr(IsoDateTime), finishedAt: Schema.NullOr(IsoDateTime), message: Schema.NullOr(TrimmedNonEmptyString), output: Schema.NullOr(Schema.String.check(Schema.isMaxLength(10_000))),});export type ServerProviderUpdateState = typeof ServerProviderUpdateState.Type; export const ServerProvider = Schema.Struct({ // Routing key for the configured instance this snapshot represents. This // is the only stable identity consumers may use for provider routing. instanceId: ProviderInstanceId, // Open driver kind slug that selects the implementation handling this // instance. It is metadata/capability context, not a routing key. driver: ProviderDriverKind, displayName: Schema.optional(TrimmedNonEmptyString), accentColor: Schema.optional(TrimmedNonEmptyString), badgeLabel: Schema.optional(TrimmedNonEmptyString), continuation: Schema.optional(ServerProviderContinuation), showInteractionModeToggle: Schema.optional(Schema.Boolean), // The driver streams context window usage, so a started thread will have a // meter once its activities load. Clients reserve the meter's space on it. reportsContextWindow: Schema.optional(Schema.Boolean), requiresNewThreadForModelChange: Schema.optional(Schema.Boolean), supportsConversationRollback: Schema.optional(Schema.Boolean), supportsTextGeneration: Schema.optional(Schema.Boolean), setup: Schema.optional( Schema.Struct({ canAuthenticate: Schema.Boolean, canInstall: Schema.Boolean, }), ), enabled: Schema.Boolean, installed: Schema.Boolean, version: Schema.NullOr(TrimmedNonEmptyString), status: ServerProviderState, auth: ServerProviderAuth, checkedAt: IsoDateTime, message: Schema.optional(TrimmedNonEmptyString), // Optional for back-compat: every legacy producer omits this field and // an absent value is interpreted as `"available"` by consumers (see // `isProviderAvailable`). New `ProviderInstanceRegistry` outputs set it // explicitly so the UI can render unavailable shadows from // `ServerSettings.providerInstances`. availability: Schema.optional(ServerProviderAvailability), // Human-readable reason populated when `availability === "unavailable"`. // Surfaces in the UI alongside the missing-driver affordance. unavailableReason: Schema.optional(TrimmedNonEmptyString), models: Schema.Array(ServerProviderModel), slashCommands: Schema.Array(ServerProviderSlashCommand).pipe( Schema.withDecodingDefault(Effect.succeed([])), ), skills: Schema.Array(ServerProviderSkill).pipe(Schema.withDecodingDefault(Effect.succeed([]))), workspaceSnapshots: Schema.optionalKey(Schema.Array(ServerProviderWorkspaceSnapshot)), // Absent when the driver has no notion of subscription usage. usageLimits: Schema.optional(ServerProviderUsageLimits), versionAdvisory: Schema.optionalKey(ServerProviderVersionAdvisory), updateState: Schema.optionalKey(ServerProviderUpdateState),});export type ServerProvider = typeof ServerProvider.Type; // Provider status kinds grow over time (ServerProviderState,// ServerProviderAuthStatus, ServerProviderVersionAdvisoryStatus,// ServerProviderUpdateStatus); an older client must not fail the whole config// decode over one provider it cannot render.export const ServerProviders = ForwardCompatibleArray(ServerProvider);export type ServerProviders = typeof ServerProviders.Type; /** * Treat the optional `availability` as "available" when absent. This is * the rule legacy producers (which omit the field) and new producers * (which set it explicitly) agree on so consumers never have to thread * `?? "available"` defaults through their code paths. */export const isProviderAvailable = (snapshot: ServerProvider): boolean => snapshot.availability !== "unavailable"; export const ServerObservability = Schema.Struct({ logsDirectoryPath: TrimmedNonEmptyString, localTracingEnabled: Schema.Boolean, otlpTracesUrl: Schema.optional(TrimmedNonEmptyString), otlpTracesEnabled: Schema.Boolean, otlpMetricsUrl: Schema.optional(TrimmedNonEmptyString), otlpMetricsEnabled: Schema.Boolean,});export type ServerObservability = typeof ServerObservability.Type; export const ServerTraceDiagnosticsErrorKind = Schema.Literals([ "trace-file-not-found", "trace-file-read-failed",]);export type ServerTraceDiagnosticsErrorKind = typeof ServerTraceDiagnosticsErrorKind.Type; export const ServerTraceDiagnosticsSpanSummary = Schema.Struct({ name: TrimmedNonEmptyString, count: NonNegativeInt, failureCount: NonNegativeInt, totalDurationMs: Schema.Number, averageDurationMs: Schema.Number, maxDurationMs: Schema.Number,});export type ServerTraceDiagnosticsSpanSummary = typeof ServerTraceDiagnosticsSpanSummary.Type; export const ServerTraceDiagnosticsFailureSummary = Schema.Struct({ name: TrimmedNonEmptyString, cause: TrimmedNonEmptyString, count: NonNegativeInt, lastSeenAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString,});export type ServerTraceDiagnosticsFailureSummary = typeof ServerTraceDiagnosticsFailureSummary.Type; export const ServerTraceDiagnosticsRecentFailure = Schema.Struct({ name: TrimmedNonEmptyString, cause: TrimmedNonEmptyString, durationMs: Schema.Number, endedAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString,});export type ServerTraceDiagnosticsRecentFailure = typeof ServerTraceDiagnosticsRecentFailure.Type; export const ServerTraceDiagnosticsSpanOccurrence = Schema.Struct({ name: TrimmedNonEmptyString, durationMs: Schema.Number, endedAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString,});export type ServerTraceDiagnosticsSpanOccurrence = typeof ServerTraceDiagnosticsSpanOccurrence.Type; export const ServerTraceDiagnosticsLogEvent = Schema.Struct({ spanName: TrimmedNonEmptyString, level: TrimmedNonEmptyString, message: TrimmedNonEmptyString, seenAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString,});export type ServerTraceDiagnosticsLogEvent = typeof ServerTraceDiagnosticsLogEvent.Type; export const ServerTraceDiagnosticsResult = Schema.Struct({ traceFilePath: TrimmedNonEmptyString, scannedFilePaths: Schema.Array(TrimmedNonEmptyString), readAt: Schema.DateTimeUtc, recordCount: NonNegativeInt, parseErrorCount: NonNegativeInt, firstSpanAt: Schema.Option(Schema.DateTimeUtc), lastSpanAt: Schema.Option(Schema.DateTimeUtc), failureCount: NonNegativeInt, interruptionCount: NonNegativeInt, slowSpanThresholdMs: NonNegativeInt, slowSpanCount: NonNegativeInt, logLevelCounts: Schema.Record(TrimmedNonEmptyString, NonNegativeInt), topSpansByCount: Schema.Array(ServerTraceDiagnosticsSpanSummary), slowestSpans: Schema.Array(ServerTraceDiagnosticsSpanOccurrence), commonFailures: Schema.Array(ServerTraceDiagnosticsFailureSummary), latestFailures: Schema.Array(ServerTraceDiagnosticsRecentFailure), latestWarningAndErrorLogs: Schema.Array(ServerTraceDiagnosticsLogEvent), partialFailure: Schema.Option(Schema.Boolean), error: Schema.Option( Schema.Struct({ kind: ServerTraceDiagnosticsErrorKind, message: TrimmedNonEmptyString, }), ),});export type ServerTraceDiagnosticsResult = typeof ServerTraceDiagnosticsResult.Type; export const ServerProcessSignal = Schema.Literals(["SIGINT", "SIGKILL"]);export type ServerProcessSignal = typeof ServerProcessSignal.Type; export const ServerProcessDiagnosticsEntry = Schema.Struct({ pid: PositiveInt, startTimeMs: NonNegativeInt, ppid: NonNegativeInt, pgid: Schema.Option(Schema.Int), status: TrimmedNonEmptyString, cpuPercent: Schema.Number, rssBytes: NonNegativeInt, elapsed: TrimmedNonEmptyString, command: TrimmedNonEmptyString, depth: NonNegativeInt, childPids: Schema.Array(PositiveInt),});export type ServerProcessDiagnosticsEntry = typeof ServerProcessDiagnosticsEntry.Type; export const ServerProcessDiagnosticsResult = Schema.Struct({ serverPid: PositiveInt, readAt: Schema.DateTimeUtc, processCount: NonNegativeInt, totalRssBytes: NonNegativeInt, totalCpuPercent: Schema.Number, processes: Schema.Array(ServerProcessDiagnosticsEntry), error: Schema.Option( Schema.Struct({ message: TrimmedNonEmptyString, }), ),});export type ServerProcessDiagnosticsResult = typeof ServerProcessDiagnosticsResult.Type; export const ServerProcessResourceHistoryInput = Schema.Struct({ windowMs: NonNegativeInt, bucketMs: NonNegativeInt,});export type ServerProcessResourceHistoryInput = typeof ServerProcessResourceHistoryInput.Type; export const ServerProcessResourceHistoryBucket = Schema.Struct({ startedAt: Schema.DateTimeUtc, endedAt: Schema.DateTimeUtc, avgCpuPercent: Schema.Number, maxCpuPercent: Schema.Number, maxRssBytes: NonNegativeInt, maxProcessCount: NonNegativeInt,});export type ServerProcessResourceHistoryBucket = typeof ServerProcessResourceHistoryBucket.Type; export const ServerProcessResourceHistorySummary = Schema.Struct({ processKey: TrimmedNonEmptyString, pid: PositiveInt, ppid: NonNegativeInt, command: TrimmedNonEmptyString, depth: NonNegativeInt, isServerRoot: Schema.Boolean, firstSeenAt: Schema.DateTimeUtc, lastSeenAt: Schema.DateTimeUtc, currentCpuPercent: Schema.Number, avgCpuPercent: Schema.Number, maxCpuPercent: Schema.Number, cpuSecondsApprox: Schema.Number, currentRssBytes: NonNegativeInt, maxRssBytes: NonNegativeInt, sampleCount: NonNegativeInt,});export type ServerProcessResourceHistorySummary = typeof ServerProcessResourceHistorySummary.Type; export const ServerProcessResourceHistoryFailureTag = Schema.Literals([ "ProcessDiagnosticsQueryTimeoutError", "ProcessDiagnosticsQueryFailedError", "ProcessDiagnosticsServerProcessSignalError", "ProcessDiagnosticsNotDescendantError", "ProcessDiagnosticsSignalFailedError",]);export type ServerProcessResourceHistoryFailureTag = typeof ServerProcessResourceHistoryFailureTag.Type; export const ServerProcessResourceHistoryResult = Schema.Struct({ readAt: Schema.DateTimeUtc, windowMs: NonNegativeInt, bucketMs: NonNegativeInt, sampleIntervalMs: NonNegativeInt, retainedSampleCount: NonNegativeInt, totalCpuSecondsApprox: Schema.Number, buckets: Schema.Array(ServerProcessResourceHistoryBucket), topProcesses: Schema.Array(ServerProcessResourceHistorySummary), error: Schema.Option( Schema.Struct({ failureTag: ServerProcessResourceHistoryFailureTag, message: TrimmedNonEmptyString, }), ),});export type ServerProcessResourceHistoryResult = typeof ServerProcessResourceHistoryResult.Type; export const ServerSignalProcessInput = Schema.Struct({ pid: PositiveInt, startTimeMs: NonNegativeInt, signal: ServerProcessSignal,});export type ServerSignalProcessInput = typeof ServerSignalProcessInput.Type; export const ServerSignalProcessResult = Schema.Struct({ pid: PositiveInt, signal: ServerProcessSignal, signaled: Schema.Boolean, message: Schema.Option(TrimmedNonEmptyString),});export type ServerSignalProcessResult = typeof ServerSignalProcessResult.Type; /** * A palette the environment's machine publishes for T3 Code to follow, read * from a theme file next to the rest of the environment's state. Two seed * colors rather than a full palette: clients derive the remaining roles with * the same generator the guided theme editor uses, so a desktop theme carries * over as a coherent T3 Code palette instead of a foreign one. */export const EnvironmentThemeColor = Schema.String.check( Schema.isPattern(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/),);export type EnvironmentThemeColor = typeof EnvironmentThemeColor.Type; /** * Matches the client-side theme id rule, so a published id is selectable. * The appearance keywords are excluded outright: a published `dark.json` * would otherwise capture every client whose stored preference is the stock * `"dark"`, retinting people who never chose it. */export const EnvironmentThemeId = Schema.String.check( Schema.isPattern(/^(?!(?:system|light|dark)$)[a-z0-9](?:[a-z0-9-]{0,47})$/),);export type EnvironmentThemeId = typeof EnvironmentThemeId.Type; /** * Role colors as published. Values are any CSS color the client's theme * parser accepts (exported theme files use oklch), canonicalized client-side; * roles a build does not know are dropped there, so a machine may publish * roles a newer client added without breaking an older one. Keys must still * be role-shaped and values color-sized, so the record stays open to future * vocabulary without being an arbitrary-payload channel. */const EnvironmentThemeColors = Schema.Record( Schema.String.check(Schema.isPattern(/^[a-zA-Z][a-zA-Z0-9]{0,63}$/)), TrimmedNonEmptyString.check(Schema.isMaxLength(64)),); const environmentThemeFields = { /** * Standard exported theme files (the Download button's output) carry * `version: 1`; the seeded short form a desktop generates has no version.Lines 1–500 of 861. Load more
import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; import { type EnvironmentMachineKind, ExecutionEnvironmentDescriptor, ServerSelfUpdateMethod, } from "./environment.ts"; import { ServerAuthDescriptor } from "./auth.ts"; import { ForwardCompatibleArray, IsoDateTime, NonNegativeInt, PositiveInt, ProjectId, ThreadId, TrimmedNonEmptyString, } from "./baseSchemas.ts"; import { KeybindingCommand, KeybindingValue, KeybindingWhen, ResolvedKeybindingsConfig, } from "./keybindings.ts"; import { EditorId, FileManagerRevealKind, RemoteOpenTarget } from "./editor.ts"; import { ModelCapabilities } from "./model.ts"; import { ProviderDriverKind, ProviderInstanceId } from "./providerInstance.ts"; import { ServerProviderUsageLimits, UsageLimitSourceSnapshots } from "./providerUsageLimits.ts"; import { ServerSettings } from "./settings.ts"; const KeybindingsMalformedConfigIssue = Schema.Struct({ kind: Schema.Literal("keybindings.malformed-config"), message: TrimmedNonEmptyString, }); const KeybindingsInvalidEntryIssue = Schema.Struct({ kind: Schema.Literal("keybindings.invalid-entry"), message: TrimmedNonEmptyString, index: Schema.Number, }); export const ServerConfigIssue = Schema.Union([ KeybindingsMalformedConfigIssue, KeybindingsInvalidEntryIssue, ]); export type ServerConfigIssue = typeof ServerConfigIssue.Type; // Issue kinds grow over time; older clients must not fail the whole config // decode over a kind they cannot render. const ServerConfigIssues = ForwardCompatibleArray(ServerConfigIssue); export const ServerProviderState = Schema.Literals(["ready", "warning", "error", "disabled"]); export type ServerProviderState = typeof ServerProviderState.Type; export const ServerProviderAuthStatus = Schema.Literals([ "authenticated", "unauthenticated", "unknown", ]); export type ServerProviderAuthStatus = typeof ServerProviderAuthStatus.Type; export const ServerProviderAuth = Schema.Struct({ status: ServerProviderAuthStatus, type: Schema.optional(TrimmedNonEmptyString), label: Schema.optional(TrimmedNonEmptyString), email: Schema.optional(TrimmedNonEmptyString), }); export type ServerProviderAuth = typeof ServerProviderAuth.Type; export const ServerProviderModel = Schema.Struct({ slug: TrimmedNonEmptyString, name: TrimmedNonEmptyString, shortName: Schema.optional(TrimmedNonEmptyString), subProvider: Schema.optional(TrimmedNonEmptyString), aliases: Schema.optional(Schema.Array(TrimmedNonEmptyString)), badge: Schema.optional(Schema.Literal("new")), isCustom: Schema.Boolean, isDefault: Schema.optional(Schema.Boolean), isLegacy: Schema.optional(Schema.Boolean), capabilities: Schema.NullOr(ModelCapabilities), }); export type ServerProviderModel = typeof ServerProviderModel.Type; export const ServerProviderSlashCommandInput = Schema.Struct({ hint: TrimmedNonEmptyString, }); export type ServerProviderSlashCommandInput = typeof ServerProviderSlashCommandInput.Type; export const ServerProviderSlashCommand = Schema.Struct({ name: TrimmedNonEmptyString, description: Schema.optional(TrimmedNonEmptyString), input: Schema.optional(ServerProviderSlashCommandInput), }); export type ServerProviderSlashCommand = typeof ServerProviderSlashCommand.Type; export const ServerProviderSkill = Schema.Struct({ name: TrimmedNonEmptyString, description: Schema.optional(TrimmedNonEmptyString), path: TrimmedNonEmptyString, scope: Schema.optional(TrimmedNonEmptyString), enabled: Schema.Boolean, displayName: Schema.optional(TrimmedNonEmptyString), shortDescription: Schema.optional(TrimmedNonEmptyString), /** * The skill is hidden from the agent's own skill tool, so only the user can * start it — Claude Code's `disable-model-invocation`. Composers must offer * it as a slash command; naming it in prose does nothing. */ userInvocationOnly: Schema.optional(Schema.Boolean), /** * The mirror of {@link ServerProviderSkill.userInvocationOnly}: Claude Code's * `user-invocable: false` keeps the skill out of its own slash commands, so * only the agent can start it. Composers must not offer it under `/`. */ userInvocable: Schema.optional(Schema.Boolean), }); export type ServerProviderSkill = typeof ServerProviderSkill.Type; export const ServerProviderWorkspaceSnapshot = Schema.Struct({ cwd: TrimmedNonEmptyString, checkedAt: IsoDateTime, slashCommands: Schema.Array(ServerProviderSlashCommand), skills: Schema.Array(ServerProviderSkill), }); export type ServerProviderWorkspaceSnapshot = typeof ServerProviderWorkspaceSnapshot.Type; /** * Availability of a configured provider instance from the runtime's POV. * * - `available` — the build ships this driver and an instance is wired * up. Default for legacy snapshots produced from the closed * `ServerSettings.providers` map. * - `unavailable` — the user's `ServerSettings.providerInstances` (or a * persisted thread / session binding) references a driver this build * doesn't ship. Common after rolling back from a fork or PR branch * that introduced a new driver. The snapshot is preserved so the UI * can render "missing driver" affordances and so the data round-trips * when the user moves back to the fork. * * Snapshots with `availability: "unavailable"` MUST set * `installed: false` and `enabled: false`; the runtime refuses turn * starts against them with a structured error. */ export const ServerProviderAvailability = Schema.Literals(["available", "unavailable"]); export type ServerProviderAvailability = typeof ServerProviderAvailability.Type; export const ServerProviderContinuation = Schema.Struct({ groupKey: TrimmedNonEmptyString, }); export type ServerProviderContinuation = typeof ServerProviderContinuation.Type; export const ServerProviderVersionAdvisoryStatus = Schema.Literals([ "unknown", "current", "behind_latest", ]); export type ServerProviderVersionAdvisoryStatus = typeof ServerProviderVersionAdvisoryStatus.Type; export const ServerProviderVersionAdvisory = Schema.Struct({ status: ServerProviderVersionAdvisoryStatus, currentVersion: Schema.NullOr(TrimmedNonEmptyString), latestVersion: Schema.NullOr(TrimmedNonEmptyString), updateCommand: Schema.NullOr(TrimmedNonEmptyString), canUpdate: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), checkedAt: Schema.NullOr(IsoDateTime), message: Schema.NullOr(TrimmedNonEmptyString), }); export type ServerProviderVersionAdvisory = typeof ServerProviderVersionAdvisory.Type; export const ServerProviderUpdateStatus = Schema.Literals([ "idle", "queued", "running", "succeeded", "failed", "unchanged", ]); export type ServerProviderUpdateStatus = typeof ServerProviderUpdateStatus.Type; export const ServerProviderUpdateState = Schema.Struct({ status: ServerProviderUpdateStatus, startedAt: Schema.NullOr(IsoDateTime), finishedAt: Schema.NullOr(IsoDateTime), message: Schema.NullOr(TrimmedNonEmptyString), output: Schema.NullOr(Schema.String.check(Schema.isMaxLength(10_000))), }); export type ServerProviderUpdateState = typeof ServerProviderUpdateState.Type; export const ServerProvider = Schema.Struct({ // Routing key for the configured instance this snapshot represents. This // is the only stable identity consumers may use for provider routing. instanceId: ProviderInstanceId, // Open driver kind slug that selects the implementation handling this // instance. It is metadata/capability context, not a routing key. driver: ProviderDriverKind, displayName: Schema.optional(TrimmedNonEmptyString), accentColor: Schema.optional(TrimmedNonEmptyString), badgeLabel: Schema.optional(TrimmedNonEmptyString), continuation: Schema.optional(ServerProviderContinuation), showInteractionModeToggle: Schema.optional(Schema.Boolean), // The driver streams context window usage, so a started thread will have a // meter once its activities load. Clients reserve the meter's space on it. reportsContextWindow: Schema.optional(Schema.Boolean), requiresNewThreadForModelChange: Schema.optional(Schema.Boolean), supportsConversationRollback: Schema.optional(Schema.Boolean), supportsTextGeneration: Schema.optional(Schema.Boolean), setup: Schema.optional( Schema.Struct({ canAuthenticate: Schema.Boolean, canInstall: Schema.Boolean, }), ), enabled: Schema.Boolean, installed: Schema.Boolean, version: Schema.NullOr(TrimmedNonEmptyString), status: ServerProviderState, auth: ServerProviderAuth, checkedAt: IsoDateTime, message: Schema.optional(TrimmedNonEmptyString), // Optional for back-compat: every legacy producer omits this field and // an absent value is interpreted as `"available"` by consumers (see // `isProviderAvailable`). New `ProviderInstanceRegistry` outputs set it // explicitly so the UI can render unavailable shadows from // `ServerSettings.providerInstances`. availability: Schema.optional(ServerProviderAvailability), // Human-readable reason populated when `availability === "unavailable"`. // Surfaces in the UI alongside the missing-driver affordance. unavailableReason: Schema.optional(TrimmedNonEmptyString), models: Schema.Array(ServerProviderModel), slashCommands: Schema.Array(ServerProviderSlashCommand).pipe( Schema.withDecodingDefault(Effect.succeed([])), ), skills: Schema.Array(ServerProviderSkill).pipe(Schema.withDecodingDefault(Effect.succeed([]))), workspaceSnapshots: Schema.optionalKey(Schema.Array(ServerProviderWorkspaceSnapshot)), // Absent when the driver has no notion of subscription usage. usageLimits: Schema.optional(ServerProviderUsageLimits), versionAdvisory: Schema.optionalKey(ServerProviderVersionAdvisory), updateState: Schema.optionalKey(ServerProviderUpdateState), }); export type ServerProvider = typeof ServerProvider.Type; // Provider status kinds grow over time (ServerProviderState, // ServerProviderAuthStatus, ServerProviderVersionAdvisoryStatus, // ServerProviderUpdateStatus); an older client must not fail the whole config // decode over one provider it cannot render. export const ServerProviders = ForwardCompatibleArray(ServerProvider); export type ServerProviders = typeof ServerProviders.Type; /** * Treat the optional `availability` as "available" when absent. This is * the rule legacy producers (which omit the field) and new producers * (which set it explicitly) agree on so consumers never have to thread * `?? "available"` defaults through their code paths. */ export const isProviderAvailable = (snapshot: ServerProvider): boolean => snapshot.availability !== "unavailable"; export const ServerObservability = Schema.Struct({ logsDirectoryPath: TrimmedNonEmptyString, localTracingEnabled: Schema.Boolean, otlpTracesUrl: Schema.optional(TrimmedNonEmptyString), otlpTracesEnabled: Schema.Boolean, otlpMetricsUrl: Schema.optional(TrimmedNonEmptyString), otlpMetricsEnabled: Schema.Boolean, }); export type ServerObservability = typeof ServerObservability.Type; export const ServerTraceDiagnosticsErrorKind = Schema.Literals([ "trace-file-not-found", "trace-file-read-failed", ]); export type ServerTraceDiagnosticsErrorKind = typeof ServerTraceDiagnosticsErrorKind.Type; export const ServerTraceDiagnosticsSpanSummary = Schema.Struct({ name: TrimmedNonEmptyString, count: NonNegativeInt, failureCount: NonNegativeInt, totalDurationMs: Schema.Number, averageDurationMs: Schema.Number, maxDurationMs: Schema.Number, }); export type ServerTraceDiagnosticsSpanSummary = typeof ServerTraceDiagnosticsSpanSummary.Type; export const ServerTraceDiagnosticsFailureSummary = Schema.Struct({ name: TrimmedNonEmptyString, cause: TrimmedNonEmptyString, count: NonNegativeInt, lastSeenAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString, }); export type ServerTraceDiagnosticsFailureSummary = typeof ServerTraceDiagnosticsFailureSummary.Type; export const ServerTraceDiagnosticsRecentFailure = Schema.Struct({ name: TrimmedNonEmptyString, cause: TrimmedNonEmptyString, durationMs: Schema.Number, endedAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString, }); export type ServerTraceDiagnosticsRecentFailure = typeof ServerTraceDiagnosticsRecentFailure.Type; export const ServerTraceDiagnosticsSpanOccurrence = Schema.Struct({ name: TrimmedNonEmptyString, durationMs: Schema.Number, endedAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString, }); export type ServerTraceDiagnosticsSpanOccurrence = typeof ServerTraceDiagnosticsSpanOccurrence.Type; export const ServerTraceDiagnosticsLogEvent = Schema.Struct({ spanName: TrimmedNonEmptyString, level: TrimmedNonEmptyString, message: TrimmedNonEmptyString, seenAt: Schema.DateTimeUtc, traceId: TrimmedNonEmptyString, spanId: TrimmedNonEmptyString, }); export type ServerTraceDiagnosticsLogEvent = typeof ServerTraceDiagnosticsLogEvent.Type; export const ServerTraceDiagnosticsResult = Schema.Struct({ traceFilePath: TrimmedNonEmptyString, scannedFilePaths: Schema.Array(TrimmedNonEmptyString), readAt: Schema.DateTimeUtc, recordCount: NonNegativeInt, parseErrorCount: NonNegativeInt, firstSpanAt: Schema.Option(Schema.DateTimeUtc), lastSpanAt: Schema.Option(Schema.DateTimeUtc), failureCount: NonNegativeInt, interruptionCount: NonNegativeInt, slowSpanThresholdMs: NonNegativeInt, slowSpanCount: NonNegativeInt, logLevelCounts: Schema.Record(TrimmedNonEmptyString, NonNegativeInt), topSpansByCount: Schema.Array(ServerTraceDiagnosticsSpanSummary), slowestSpans: Schema.Array(ServerTraceDiagnosticsSpanOccurrence), commonFailures: Schema.Array(ServerTraceDiagnosticsFailureSummary), latestFailures: Schema.Array(ServerTraceDiagnosticsRecentFailure), latestWarningAndErrorLogs: Schema.Array(ServerTraceDiagnosticsLogEvent), partialFailure: Schema.Option(Schema.Boolean), error: Schema.Option( Schema.Struct({ kind: ServerTraceDiagnosticsErrorKind, message: TrimmedNonEmptyString, }), ), }); export type ServerTraceDiagnosticsResult = typeof ServerTraceDiagnosticsResult.Type; export const ServerProcessSignal = Schema.Literals(["SIGINT", "SIGKILL"]); export type ServerProcessSignal = typeof ServerProcessSignal.Type; export const ServerProcessDiagnosticsEntry = Schema.Struct({ pid: PositiveInt, startTimeMs: NonNegativeInt, ppid: NonNegativeInt, pgid: Schema.Option(Schema.Int), status: TrimmedNonEmptyString, cpuPercent: Schema.Number, rssBytes: NonNegativeInt, elapsed: TrimmedNonEmptyString, command: TrimmedNonEmptyString, depth: NonNegativeInt, childPids: Schema.Array(PositiveInt), }); export type ServerProcessDiagnosticsEntry = typeof ServerProcessDiagnosticsEntry.Type; export const ServerProcessDiagnosticsResult = Schema.Struct({ serverPid: PositiveInt, readAt: Schema.DateTimeUtc, processCount: NonNegativeInt, totalRssBytes: NonNegativeInt, totalCpuPercent: Schema.Number, processes: Schema.Array(ServerProcessDiagnosticsEntry), error: Schema.Option( Schema.Struct({ message: TrimmedNonEmptyString, }), ), }); export type ServerProcessDiagnosticsResult = typeof ServerProcessDiagnosticsResult.Type; export const ServerProcessResourceHistoryInput = Schema.Struct({ windowMs: NonNegativeInt, bucketMs: NonNegativeInt, }); export type ServerProcessResourceHistoryInput = typeof ServerProcessResourceHistoryInput.Type; export const ServerProcessResourceHistoryBucket = Schema.Struct({ startedAt: Schema.DateTimeUtc, endedAt: Schema.DateTimeUtc, avgCpuPercent: Schema.Number, maxCpuPercent: Schema.Number, maxRssBytes: NonNegativeInt, maxProcessCount: NonNegativeInt, }); export type ServerProcessResourceHistoryBucket = typeof ServerProcessResourceHistoryBucket.Type; export const ServerProcessResourceHistorySummary = Schema.Struct({ processKey: TrimmedNonEmptyString, pid: PositiveInt, ppid: NonNegativeInt, command: TrimmedNonEmptyString, depth: NonNegativeInt, isServerRoot: Schema.Boolean, firstSeenAt: Schema.DateTimeUtc, lastSeenAt: Schema.DateTimeUtc, currentCpuPercent: Schema.Number, avgCpuPercent: Schema.Number, maxCpuPercent: Schema.Number, cpuSecondsApprox: Schema.Number, currentRssBytes: NonNegativeInt, maxRssBytes: NonNegativeInt, sampleCount: NonNegativeInt, }); export type ServerProcessResourceHistorySummary = typeof ServerProcessResourceHistorySummary.Type; export const ServerProcessResourceHistoryFailureTag = Schema.Literals([ "ProcessDiagnosticsQueryTimeoutError", "ProcessDiagnosticsQueryFailedError", "ProcessDiagnosticsServerProcessSignalError", "ProcessDiagnosticsNotDescendantError", "ProcessDiagnosticsSignalFailedError", ]); export type ServerProcessResourceHistoryFailureTag = typeof ServerProcessResourceHistoryFailureTag.Type; export const ServerProcessResourceHistoryResult = Schema.Struct({ readAt: Schema.DateTimeUtc, windowMs: NonNegativeInt, bucketMs: NonNegativeInt, sampleIntervalMs: NonNegativeInt, retainedSampleCount: NonNegativeInt, totalCpuSecondsApprox: Schema.Number, buckets: Schema.Array(ServerProcessResourceHistoryBucket), topProcesses: Schema.Array(ServerProcessResourceHistorySummary), error: Schema.Option( Schema.Struct({ failureTag: ServerProcessResourceHistoryFailureTag, message: TrimmedNonEmptyString, }), ), }); export type ServerProcessResourceHistoryResult = typeof ServerProcessResourceHistoryResult.Type; export const ServerSignalProcessInput = Schema.Struct({ pid: PositiveInt, startTimeMs: NonNegativeInt, signal: ServerProcessSignal, }); export type ServerSignalProcessInput = typeof ServerSignalProcessInput.Type; export const ServerSignalProcessResult = Schema.Struct({ pid: PositiveInt, signal: ServerProcessSignal, signaled: Schema.Boolean, message: Schema.Option(TrimmedNonEmptyString), }); export type ServerSignalProcessResult = typeof ServerSignalProcessResult.Type; /** * A palette the environment's machine publishes for T3 Code to follow, read * from a theme file next to the rest of the environment's state. Two seed * colors rather than a full palette: clients derive the remaining roles with * the same generator the guided theme editor uses, so a desktop theme carries * over as a coherent T3 Code palette instead of a foreign one. */ export const EnvironmentThemeColor = Schema.String.check( Schema.isPattern(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/), ); export type EnvironmentThemeColor = typeof EnvironmentThemeColor.Type; /** * Matches the client-side theme id rule, so a published id is selectable. * The appearance keywords are excluded outright: a published `dark.json` * would otherwise capture every client whose stored preference is the stock * `"dark"`, retinting people who never chose it. */ export const EnvironmentThemeId = Schema.String.check( Schema.isPattern(/^(?!(?:system|light|dark)$)[a-z0-9](?:[a-z0-9-]{0,47})$/), ); export type EnvironmentThemeId = typeof EnvironmentThemeId.Type; /** * Role colors as published. Values are any CSS color the client's theme * parser accepts (exported theme files use oklch), canonicalized client-side; * roles a build does not know are dropped there, so a machine may publish * roles a newer client added without breaking an older one. Keys must still * be role-shaped and values color-sized, so the record stays open to future * vocabulary without being an arbitrary-payload channel. */ const EnvironmentThemeColors = Schema.Record( Schema.String.check(Schema.isPattern(/^[a-zA-Z][a-zA-Z0-9]{0,63}$/)), TrimmedNonEmptyString.check(Schema.isMaxLength(64)), ); const environmentThemeFields = { /** * Standard exported theme files (the Download button's output) carry * `version: 1`; the seeded short form a desktop generates has no version.