import * as Effect from "effect/Effect";import * as Schema from "effect/Schema"; import { EnvironmentId, ForwardCompatibleOptional, ProjectId, ThreadId, TrimmedNonEmptyString,} from "./baseSchemas.ts"; export const ExecutionEnvironmentPlatformOs = Schema.Literals([ "darwin", "linux", "windows", "unknown",]);export type ExecutionEnvironmentPlatformOs = typeof ExecutionEnvironmentPlatformOs.Type; export const ExecutionEnvironmentPlatformArch = Schema.Literals(["arm64", "x64", "other"]);export type ExecutionEnvironmentPlatformArch = typeof ExecutionEnvironmentPlatformArch.Type; /** * The curated set of machine shapes and OS identities an environment can wear as its icon. * Servers detect one from the hardware they run on (`platform.machine`), and * the `environmentIcon` server setting lets a user pick one instead. */export const ENVIRONMENT_MACHINE_KINDS = [ "server", "cloud", "linux", "desktop", "laptop", "mac-mini", "mac-studio",] as const;export const EnvironmentMachineKind = Schema.Literals(ENVIRONMENT_MACHINE_KINDS);export type EnvironmentMachineKind = typeof EnvironmentMachineKind.Type;export const isEnvironmentMachineKind = Schema.is(EnvironmentMachineKind); export const ExecutionEnvironmentPlatform = Schema.Struct({ os: ExecutionEnvironmentPlatformOs, arch: ExecutionEnvironmentPlatformArch, /** Hardware shape detected at startup. Absent when the host gives no usable signal (containers, Windows, unknown DMI), on servers that predate it, or when a newer server names a kind this build cannot draw. */ machine: ForwardCompatibleOptional(EnvironmentMachineKind),}); /** * Where a new thread runs: the project's current checkout ("local") or a * fresh git worktree ("worktree"). Lives here (not settings.ts) so * orchestration contracts can reference it without an import cycle. */export const ThreadEnvMode = Schema.Literals(["local", "worktree"]);export type ThreadEnvMode = typeof ThreadEnvMode.Type;export type ExecutionEnvironmentPlatform = typeof ExecutionEnvironmentPlatform.Type; /** How a server can replace itself with another version when asked over RPC. New servers only advertise the stable launcher-backed "boot-service" path; "respawn" remains decodable for compatibility with older servers. "desktop-app" means the supervising desktop app updated and relaunched itself, bringing the server back with it. */export const ServerSelfUpdateMethod = Schema.Literals(["boot-service", "respawn", "desktop-app"]);export type ServerSelfUpdateMethod = typeof ServerSelfUpdateMethod.Type; /** What update path a client should offer for a server: one of the RPC self-update methods above, or "desktop-managed" when the backend's version belongs to the T3 Code desktop app supervising it — updating the app on that machine is the only way to update the server. */export const ServerSelfUpdateCapability = Schema.Literals([ "boot-service", "respawn", "desktop-managed",]);export type ServerSelfUpdateCapability = typeof ServerSelfUpdateCapability.Type; export const ExecutionEnvironmentCapabilities = Schema.Struct({ repositoryIdentity: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))), connectionProbe: Schema.optionalKey(Schema.Boolean), /** Missing on older servers, which still accept inline image attachments. */ attachmentUploads: Schema.optionalKey(Schema.Boolean), /** Uploaded files may accompany question answers. */ questionAttachments: Schema.optionalKey(Schema.Boolean), /** Missing on servers that only accept image attachments. */ fileAttachments: Schema.optionalKey( Schema.Struct({ maxUploadBytes: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)), }), ), /** Server exposes the pull-request list, detail, activity, diff, and mutation APIs. Absent on servers from before the pull-request workspace shipped, so clients must not probe them. */ pullRequests: Schema.optionalKey(Schema.Boolean), /** Server understands thread.settle / thread.unsettle commands. Absent on pre-settlement servers, so clients treat missing as unsupported and never send the commands under version skew. */ threadSettlement: Schema.optionalKey(Schema.Boolean), /** Server evaluates merge and inactivity settlement without a client. */ threadAutoSettlement: Schema.optionalKey(Schema.Boolean), /** Server persists the opt-in for continuing interrupted threads after restarts. */ threadRestartContinuation: Schema.optionalKey(Schema.Boolean), /** Server understands thread.snooze / thread.unsnooze commands. Same version-skew contract as threadSettlement. */ threadSnooze: Schema.optionalKey(Schema.Boolean), /** Server streams themes an environment publishes. Absent on servers from before environment themes shipped, which never emit the events -- so a client reconnecting to one must drop published themes rather than keep showing a set nothing will ever update. */ environmentThemes: Schema.optionalKey(Schema.Boolean), /** Server streams quota from configured usage-limit sources. Same version-skew contract as environmentThemes. */ usageLimitSources: Schema.optionalKey(Schema.Boolean), /** Server persists custom model rates and applies them to usage summaries. */ usagePriceOverrides: Schema.optionalKey(Schema.Boolean), /** Server understands thread.pin / thread.unpin commands. Same version-skew contract as threadSettlement. */ threadPinning: Schema.optionalKey(Schema.Boolean), /** Server understands thread.pin.reorder (and orderKey on thread.pin). Same version-skew contract as threadSettlement. */ threadPinReorder: Schema.optionalKey(Schema.Boolean), /** Server persists manual Active order through thread.active.reorder. */ threadActiveReorder: Schema.optionalKey(Schema.Boolean), /** Server understands regenerateTitle on thread.meta.update. Absent on older servers, so clients hide the action instead of sending it. */ threadTitleRegeneration: Schema.optionalKey(Schema.Boolean), /** Server supports legacy linkedPullRequest updates through thread.meta.update. Independent of threadPullRequests; servers supporting both advertise both. */ threadPullRequestLinking: Schema.optionalKey(Schema.Boolean), /** Server understands thread.pull-request.link / .unlink, exposes `pullRequests` on threads, and routes PullRequestRef.host across projects on the same host. Same version-skew contract as threadSettlement. */ threadPullRequests: Schema.optionalKey(Schema.Boolean), pullRequestStackActions: Schema.optionalKey(Schema.Boolean), /** The update path clients should offer for this server. Absent on servers that must be relaunched manually (dev checkouts, Windows foreground runs, pre-update servers). */ serverSelfUpdate: Schema.optionalKey(ServerSelfUpdateCapability), /** Server can stream self-update progress before acknowledging the restart. Clients fall back to server.updateServer when absent. */ serverSelfUpdateProgress: Schema.optionalKey(Schema.Boolean), /** Server can durably mark running provider turns before a self-update and continue them after the replacement process starts. */ serverUpdateThreadContinuation: Schema.optionalKey(Schema.Boolean), /** Agent-activity publishes (push notifications and Live Activities) currently leave this environment: the publish opt-in is enabled and the relay link credentials exist. Clients skip seeding a Live Activity when this is false — no update would ever repaint it. Absent on older servers, which may still publish, so only an explicit false skips. */ agentActivityPublishing: Schema.optionalKey(Schema.Boolean), /** Server detects `platform.machine` and persists the `environmentIcon` setting. Older servers drop the key on write, so clients show the picker inert rather than offering a choice that would never stick. */ environmentIcon: Schema.optionalKey(Schema.Boolean), /** The desktop app supervising this server can be driven over RPC: server.updateServer runs its check -> download -> relaunch. Absent on desktop servers whose app predates the remote trigger, where clients must keep telling the user to update the app on that machine. */ desktopAppUpdate: Schema.optionalKey(Schema.Boolean),});export type ExecutionEnvironmentCapabilities = typeof ExecutionEnvironmentCapabilities.Type; export const ExecutionEnvironmentDescriptor = Schema.Struct({ environmentId: EnvironmentId, label: TrimmedNonEmptyString, platform: ExecutionEnvironmentPlatform, serverVersion: TrimmedNonEmptyString, capabilities: ExecutionEnvironmentCapabilities,});export type ExecutionEnvironmentDescriptor = typeof ExecutionEnvironmentDescriptor.Type; export const EnvironmentConnectionState = Schema.Literals([ "connecting", "connected", "disconnected", "error",]);export type EnvironmentConnectionState = typeof EnvironmentConnectionState.Type; export const RepositoryIdentityLocator = Schema.Struct({ source: Schema.Literal("git-remote"), remoteName: TrimmedNonEmptyString, remoteUrl: TrimmedNonEmptyString,});export type RepositoryIdentityLocator = typeof RepositoryIdentityLocator.Type; export const RepositoryIdentity = Schema.Struct({ canonicalKey: TrimmedNonEmptyString, locator: RepositoryIdentityLocator, rootPath: Schema.optionalKey(TrimmedNonEmptyString), displayName: Schema.optionalKey(TrimmedNonEmptyString), provider: Schema.optionalKey(TrimmedNonEmptyString), owner: Schema.optionalKey(TrimmedNonEmptyString), name: Schema.optionalKey(TrimmedNonEmptyString),});export type RepositoryIdentity = typeof RepositoryIdentity.Type; export const ScopedProjectRef = Schema.Struct({ environmentId: EnvironmentId, projectId: ProjectId,});export type ScopedProjectRef = typeof ScopedProjectRef.Type; export const ScopedThreadRef = Schema.Struct({ environmentId: EnvironmentId, threadId: ThreadId,});export type ScopedThreadRef = typeof ScopedThreadRef.Type; export const ScopedThreadSessionRef = Schema.Struct({ environmentId: EnvironmentId, threadId: ThreadId,});export type ScopedThreadSessionRef = typeof ScopedThreadSessionRef.Type;
import * as Effect from "effect/Effect";
import * as Schema from "effect/Schema";
import {
EnvironmentId,
ForwardCompatibleOptional,
ProjectId,
ThreadId,
TrimmedNonEmptyString,
} from "./baseSchemas.ts";
export const ExecutionEnvironmentPlatformOs = Schema.Literals([
"darwin",
"linux",
"windows",
"unknown",
]);
export type ExecutionEnvironmentPlatformOs = typeof ExecutionEnvironmentPlatformOs.Type;
export const ExecutionEnvironmentPlatformArch = Schema.Literals(["arm64", "x64", "other"]);
export type ExecutionEnvironmentPlatformArch = typeof ExecutionEnvironmentPlatformArch.Type;
/**
* The curated set of machine shapes and OS identities an environment can wear as its icon.
* Servers detect one from the hardware they run on (`platform.machine`), and
* the `environmentIcon` server setting lets a user pick one instead.
*/
export const ENVIRONMENT_MACHINE_KINDS = [
"server",
"cloud",
"linux",
"desktop",
"laptop",
"mac-mini",
"mac-studio",
] as const;
export const EnvironmentMachineKind = Schema.Literals(ENVIRONMENT_MACHINE_KINDS);
export type EnvironmentMachineKind = typeof EnvironmentMachineKind.Type;
export const isEnvironmentMachineKind = Schema.is(EnvironmentMachineKind);
export const ExecutionEnvironmentPlatform = Schema.Struct({
os: ExecutionEnvironmentPlatformOs,
arch: ExecutionEnvironmentPlatformArch,
/** Hardware shape detected at startup. Absent when the host gives no usable
signal (containers, Windows, unknown DMI), on servers that predate it, or
when a newer server names a kind this build cannot draw. */
machine: ForwardCompatibleOptional(EnvironmentMachineKind),
});
/**
* Where a new thread runs: the project's current checkout ("local") or a
* fresh git worktree ("worktree"). Lives here (not settings.ts) so
* orchestration contracts can reference it without an import cycle.
*/
export const ThreadEnvMode = Schema.Literals(["local", "worktree"]);
export type ThreadEnvMode = typeof ThreadEnvMode.Type;
export type ExecutionEnvironmentPlatform = typeof ExecutionEnvironmentPlatform.Type;
/** How a server can replace itself with another version when asked over RPC.
New servers only advertise the stable launcher-backed "boot-service" path;
"respawn" remains decodable for compatibility with older servers.
"desktop-app" means the supervising desktop app updated and relaunched
itself, bringing the server back with it. */
export const ServerSelfUpdateMethod = Schema.Literals(["boot-service", "respawn", "desktop-app"]);
export type ServerSelfUpdateMethod = typeof ServerSelfUpdateMethod.Type;
/** What update path a client should offer for a server: one of the RPC
self-update methods above, or "desktop-managed" when the backend's
version belongs to the T3 Code desktop app supervising it — updating the
app on that machine is the only way to update the server. */
export const ServerSelfUpdateCapability = Schema.Literals([
"boot-service",
"respawn",
"desktop-managed",
]);
export type ServerSelfUpdateCapability = typeof ServerSelfUpdateCapability.Type;
export const ExecutionEnvironmentCapabilities = Schema.Struct({
repositoryIdentity: Schema.Boolean.pipe(Schema.withDecodingDefault(Effect.succeed(false))),
connectionProbe: Schema.optionalKey(Schema.Boolean),
/** Missing on older servers, which still accept inline image attachments. */
attachmentUploads: Schema.optionalKey(Schema.Boolean),
/** Uploaded files may accompany question answers. */
questionAttachments: Schema.optionalKey(Schema.Boolean),
/** Missing on servers that only accept image attachments. */
fileAttachments: Schema.optionalKey(
Schema.Struct({
maxUploadBytes: Schema.Int.check(Schema.isGreaterThanOrEqualTo(1)),
}),
),
/** Server exposes the pull-request list, detail, activity, diff, and mutation APIs. Absent on
servers from before the pull-request workspace shipped, so clients must not probe them. */
pullRequests: Schema.optionalKey(Schema.Boolean),
/** Server understands thread.settle / thread.unsettle commands. Absent on
pre-settlement servers, so clients treat missing as unsupported and
never send the commands under version skew. */
threadSettlement: Schema.optionalKey(Schema.Boolean),
/** Server evaluates merge and inactivity settlement without a client. */
threadAutoSettlement: Schema.optionalKey(Schema.Boolean),
/** Server persists the opt-in for continuing interrupted threads after restarts. */
threadRestartContinuation: Schema.optionalKey(Schema.Boolean),
/** Server understands thread.snooze / thread.unsnooze commands. Same
version-skew contract as threadSettlement. */
threadSnooze: Schema.optionalKey(Schema.Boolean),
/** Server streams themes an environment publishes. Absent on servers from
before environment themes shipped, which never emit the events -- so a
client reconnecting to one must drop published themes rather than keep
showing a set nothing will ever update. */
environmentThemes: Schema.optionalKey(Schema.Boolean),
/** Server streams quota from configured usage-limit sources. Same
version-skew contract as environmentThemes. */
usageLimitSources: Schema.optionalKey(Schema.Boolean),
/** Server persists custom model rates and applies them to usage summaries. */
usagePriceOverrides: Schema.optionalKey(Schema.Boolean),
/** Server understands thread.pin / thread.unpin commands. Same
version-skew contract as threadSettlement. */
threadPinning: Schema.optionalKey(Schema.Boolean),
/** Server understands thread.pin.reorder (and orderKey on thread.pin).
Same version-skew contract as threadSettlement. */
threadPinReorder: Schema.optionalKey(Schema.Boolean),
/** Server persists manual Active order through thread.active.reorder. */
threadActiveReorder: Schema.optionalKey(Schema.Boolean),
/** Server understands regenerateTitle on thread.meta.update. Absent on
older servers, so clients hide the action instead of sending it. */
threadTitleRegeneration: Schema.optionalKey(Schema.Boolean),
/** Server supports legacy linkedPullRequest updates through thread.meta.update.
Independent of threadPullRequests; servers supporting both advertise both. */
threadPullRequestLinking: Schema.optionalKey(Schema.Boolean),
/** Server understands thread.pull-request.link / .unlink, exposes `pullRequests` on
threads, and routes PullRequestRef.host across projects on the same host. Same
version-skew contract as threadSettlement. */
threadPullRequests: Schema.optionalKey(Schema.Boolean),
pullRequestStackActions: Schema.optionalKey(Schema.Boolean),
/** The update path clients should offer for this server. Absent on
servers that must be relaunched manually (dev checkouts, Windows
foreground runs, pre-update servers). */
serverSelfUpdate: Schema.optionalKey(ServerSelfUpdateCapability),
/** Server can stream self-update progress before acknowledging the
restart. Clients fall back to server.updateServer when absent. */
serverSelfUpdateProgress: Schema.optionalKey(Schema.Boolean),
/** Server can durably mark running provider turns before a self-update and
continue them after the replacement process starts. */
serverUpdateThreadContinuation: Schema.optionalKey(Schema.Boolean),
/** Agent-activity publishes (push notifications and Live Activities)
currently leave this environment: the publish opt-in is enabled and the
relay link credentials exist. Clients skip seeding a Live Activity when
this is false — no update would ever repaint it. Absent on older
servers, which may still publish, so only an explicit false skips. */
agentActivityPublishing: Schema.optionalKey(Schema.Boolean),
/** Server detects `platform.machine` and persists the `environmentIcon`
setting. Older servers drop the key on write, so clients show the
picker inert rather than offering a choice that would never stick. */
environmentIcon: Schema.optionalKey(Schema.Boolean),
/** The desktop app supervising this server can be driven over RPC:
server.updateServer runs its check -> download -> relaunch. Absent on
desktop servers whose app predates the remote trigger, where clients
must keep telling the user to update the app on that machine. */
desktopAppUpdate: Schema.optionalKey(Schema.Boolean),
});
export type ExecutionEnvironmentCapabilities = typeof ExecutionEnvironmentCapabilities.Type;
export const ExecutionEnvironmentDescriptor = Schema.Struct({
environmentId: EnvironmentId,
label: TrimmedNonEmptyString,
platform: ExecutionEnvironmentPlatform,
serverVersion: TrimmedNonEmptyString,
capabilities: ExecutionEnvironmentCapabilities,
});
export type ExecutionEnvironmentDescriptor = typeof ExecutionEnvironmentDescriptor.Type;
export const EnvironmentConnectionState = Schema.Literals([
"connecting",
"connected",
"disconnected",
"error",
]);
export type EnvironmentConnectionState = typeof EnvironmentConnectionState.Type;
export const RepositoryIdentityLocator = Schema.Struct({
source: Schema.Literal("git-remote"),
remoteName: TrimmedNonEmptyString,
remoteUrl: TrimmedNonEmptyString,
});
export type RepositoryIdentityLocator = typeof RepositoryIdentityLocator.Type;
export const RepositoryIdentity = Schema.Struct({
canonicalKey: TrimmedNonEmptyString,
locator: RepositoryIdentityLocator,
rootPath: Schema.optionalKey(TrimmedNonEmptyString),
displayName: Schema.optionalKey(TrimmedNonEmptyString),
provider: Schema.optionalKey(TrimmedNonEmptyString),
owner: Schema.optionalKey(TrimmedNonEmptyString),
name: Schema.optionalKey(TrimmedNonEmptyString),
});
export type RepositoryIdentity = typeof RepositoryIdentity.Type;
export const ScopedProjectRef = Schema.Struct({
environmentId: EnvironmentId,
projectId: ProjectId,
});
export type ScopedProjectRef = typeof ScopedProjectRef.Type;
export const ScopedThreadRef = Schema.Struct({
environmentId: EnvironmentId,
threadId: ThreadId,
});
export type ScopedThreadRef = typeof ScopedThreadRef.Type;
export const ScopedThreadSessionRef = Schema.Struct({
environmentId: EnvironmentId,
threadId: ThreadId,
});
export type ScopedThreadSessionRef = typeof ScopedThreadSessionRef.Type;