Skip to main content

Overview

The contracts package provides foundational TypeScript types and Effect schemas used throughout T3 Code. These types ensure type safety and validation across the client-server boundary.

Base Schemas

String Types

TrimmedString

A string that has leading and trailing whitespace removed.
import { Schema } from "effect";

export const TrimmedString = Schema.Trim;

TrimmedNonEmptyString

A trimmed string that must contain at least one character.
export const TrimmedNonEmptyString = TrimmedString.check(Schema.isNonEmpty());

Numeric Types

NonNegativeInt

An integer greater than or equal to zero.
export const NonNegativeInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));

PositiveInt

An integer greater than or equal to one.
export const PositiveInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));

DateTime Types

IsoDateTime

An ISO 8601 formatted datetime string.
export const IsoDateTime = Schema.String;
export type IsoDateTime = typeof IsoDateTime.Type;

Branded Identifiers

Branded types provide type-safe identifiers that prevent mixing different ID types.

Entity IDs

ThreadId

Unique identifier for a conversation thread.
export const ThreadId = makeEntityId("ThreadId");
export type ThreadId = typeof ThreadId.Type;

ProjectId

Unique identifier for a workspace project.
export const ProjectId = makeEntityId("ProjectId");
export type ProjectId = typeof ProjectId.Type;

CommandId

Unique identifier for a command in the event-sourced system.
export const CommandId = makeEntityId("CommandId");
export type CommandId = typeof CommandId.Type;

EventId

Unique identifier for a domain event.
export const EventId = makeEntityId("EventId");
export type EventId = typeof EventId.Type;

MessageId

Unique identifier for a message in a thread.
export const MessageId = makeEntityId("MessageId");
export type MessageId = typeof MessageId.Type;

TurnId

Unique identifier for a turn (user input + assistant response cycle).
export const TurnId = makeEntityId("TurnId");
export type TurnId = typeof TurnId.Type;

Provider Runtime IDs

ProviderItemId

Identifier for a provider-specific item (e.g., a Codex conversation item).
export const ProviderItemId = makeEntityId("ProviderItemId");
export type ProviderItemId = typeof ProviderItemId.Type;

RuntimeSessionId

Identifier for a runtime session.
export const RuntimeSessionId = makeEntityId("RuntimeSessionId");
export type RuntimeSessionId = typeof RuntimeSessionId.Type;

RuntimeItemId

Identifier for a runtime item.
export const RuntimeItemId = makeEntityId("RuntimeItemId");
export type RuntimeItemId = typeof RuntimeItemId.Type;

RuntimeRequestId

Identifier for a runtime request.
export const RuntimeRequestId = makeEntityId("RuntimeRequestId");
export type RuntimeRequestId = typeof RuntimeRequestId.Type;

RuntimeTaskId

Identifier for a runtime task.
export const RuntimeTaskId = makeEntityId("RuntimeTaskId");
export type RuntimeTaskId = typeof RuntimeTaskId.Type;

ApprovalRequestId

Identifier for an approval request.
export const ApprovalRequestId = makeEntityId("ApprovalRequestId");
export type ApprovalRequestId = typeof ApprovalRequestId.Type;

CheckpointRef

Reference to a git checkpoint for rollback.
export const CheckpointRef = makeEntityId("CheckpointRef");
export type CheckpointRef = typeof CheckpointRef.Type;

Provider Types

ProviderKind

Supported AI provider types.
export const ProviderKind = Schema.Literal("codex");
export type ProviderKind = typeof ProviderKind.Type;
Currently, only Codex is supported. Additional providers may be added in the future.

Runtime Modes

RuntimeMode

Controls the level of access the provider has to the system.
export const RuntimeMode = Schema.Literals(["approval-required", "full-access"]);
export type RuntimeMode = typeof RuntimeMode.Type;

export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access";
  • approval-required - User must approve each tool call
  • full-access - Provider can execute tools without approval

ProviderApprovalPolicy

Detailed approval policy configuration.
export const ProviderApprovalPolicy = Schema.Literals([
  "untrusted",
  "on-failure",
  "on-request",
  "never",
]);
export type ProviderApprovalPolicy = typeof ProviderApprovalPolicy.Type;

ProviderSandboxMode

File system access level for the provider.
export const ProviderSandboxMode = Schema.Literals([
  "read-only",
  "workspace-write",
  "danger-full-access",
]);
export type ProviderSandboxMode = typeof ProviderSandboxMode.Type;

Interaction Modes

ProviderInteractionMode

Controls how the provider interacts with the user.
export const ProviderInteractionMode = Schema.Literals(["default", "plan"]);
export type ProviderInteractionMode = typeof ProviderInteractionMode.Type;

export const DEFAULT_PROVIDER_INTERACTION_MODE: ProviderInteractionMode = "default";
  • default - Standard conversational mode
  • plan - Provider proposes a plan before execution

Service Tiers

ProviderServiceTier

Service tier for API requests.
export const ProviderServiceTier = Schema.Literals(["fast", "flex"]);
export type ProviderServiceTier = typeof ProviderServiceTier.Type;

Approval Types

ProviderApprovalDecision

User’s decision on an approval request.
export const ProviderApprovalDecision = Schema.Literals([
  "accept",
  "acceptForSession",
  "decline",
  "cancel",
]);
export type ProviderApprovalDecision = typeof ProviderApprovalDecision.Type;
  • accept - Approve this specific request
  • acceptForSession - Approve this and future similar requests in the session
  • decline - Reject this request
  • cancel - Cancel the entire turn

ProviderRequestKind

Type of request requiring approval.
export const ProviderRequestKind = Schema.Literals(["command", "file-read", "file-change"]);
export type ProviderRequestKind = typeof ProviderRequestKind.Type;

Message Delivery

AssistantDeliveryMode

How assistant messages are delivered to the client.
export const AssistantDeliveryMode = Schema.Literals(["buffered", "streaming"]);
export type AssistantDeliveryMode = typeof AssistantDeliveryMode.Type;

Chat Attachments

ChatImageAttachment

An image attached to a chat message.
type
'image'
required
Attachment type discriminator
id
string
required
Unique attachment ID (max 128 chars, alphanumeric with dashes/underscores)
name
string
required
File name (max 255 chars)
mimeType
string
required
MIME type starting with “image/” (max 100 chars)
sizeBytes
number
required
File size in bytes (max 10MB)
export const ChatImageAttachment = Schema.Struct({
  type: Schema.Literal("image"),
  id: ChatAttachmentId,
  name: TrimmedNonEmptyString.check(Schema.isMaxLength(255)),
  mimeType: TrimmedNonEmptyString.check(Schema.isMaxLength(100), Schema.isPattern(/^image\//i)),
  sizeBytes: NonNegativeInt.check(Schema.isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)),
});
export type ChatImageAttachment = typeof ChatImageAttachment.Type;

ChatAttachment

Union of all attachment types.
export const ChatAttachment = Schema.Union([ChatImageAttachment]);
export type ChatAttachment = typeof ChatAttachment.Type;

Git Types

GitBranch

Represents a git branch with metadata.
name
string
required
Branch name
isRemote
boolean
Whether this is a remote branch
remoteName
string
Name of the remote (e.g., “origin”)
current
boolean
required
Whether this is the currently checked out branch
isDefault
boolean
required
Whether this is the default branch (main/master)
worktreePath
string | null
required
Path to the worktree if this branch has one
export const GitBranch = Schema.Struct({
  name: TrimmedNonEmptyString,
  isRemote: Schema.optional(Schema.Boolean),
  remoteName: Schema.optional(TrimmedNonEmptyString),
  current: Schema.Boolean,
  isDefault: Schema.Boolean,
  worktreePath: TrimmedNonEmptyString.pipe(Schema.NullOr),
});
export type GitBranch = typeof GitBranch.Type;

GitStackedAction

Git actions that can be performed in sequence.
export const GitStackedAction = Schema.Literals(["commit", "commit_push", "commit_push_pr"]);
export type GitStackedAction = typeof GitStackedAction.Type;
  • commit - Create a commit
  • commit_push - Create a commit and push
  • commit_push_pr - Create a commit, push, and open a PR

Project Types

ProjectEntry

Represents a file or directory in a project.
path
string
required
Relative path from project root
kind
'file' | 'directory'
required
Entry type
parentPath
string
Parent directory path
export const ProjectEntry = Schema.Struct({
  path: TrimmedNonEmptyString,
  kind: ProjectEntryKind,
  parentPath: Schema.optional(TrimmedNonEmptyString),
});
export type ProjectEntry = typeof ProjectEntry.Type;

Editor Types

EditorId

Supported code editors.
export const EditorId = Schema.Literals(["cursor", "vscode", "zed", "file-manager"]);
export type EditorId = typeof EditorId.Type;

Editor Configuration

export const EDITORS = [
  { id: "cursor", label: "Cursor", command: "cursor" },
  { id: "vscode", label: "VS Code", command: "code" },
  { id: "zed", label: "Zed", command: "zed" },
  { id: "file-manager", label: "File Manager", command: null },
] as const;

Usage Examples

Creating Branded IDs

import { ThreadId, MessageId } from "@t3tools/contracts";
import { nanoid } from "nanoid";

const threadId: ThreadId = nanoid() as ThreadId;
const messageId: MessageId = nanoid() as MessageId;

// TypeScript prevents mixing ID types
function getMessage(id: MessageId) {
  // ...
}

getMessage(threadId); // Type error!
getMessage(messageId); // OK

Validating with Effect Schema

import { Schema } from "effect";
import { TrimmedNonEmptyString, NonNegativeInt } from "@t3tools/contracts";

// Decode and validate
const result = Schema.decodeUnknownSync(TrimmedNonEmptyString)("  hello  ");
// result === "hello"

const count = Schema.decodeUnknownSync(NonNegativeInt)(5);
// count === 5

const invalid = Schema.decodeUnknownSync(NonNegativeInt)(-1);
// Throws ParseError

Working with Chat Attachments

import { ChatImageAttachment } from "@t3tools/contracts";

const attachment: typeof ChatImageAttachment.Type = {
  type: "image",
  id: "img_abc123",
  name: "screenshot.png",
  mimeType: "image/png",
  sizeBytes: 1024 * 500, // 500KB
};

Using Git Types

import { GitBranch, GitStackedAction } from "@t3tools/contracts";

const branch: typeof GitBranch.Type = {
  name: "feature/new-api",
  isRemote: false,
  current: true,
  isDefault: false,
  worktreePath: null,
};

const action: GitStackedAction = "commit_push_pr";

Type Guards

Effect Schema provides runtime type guards:
import { Schema } from "effect";
import { RuntimeMode } from "@t3tools/contracts";

const isRuntimeMode = Schema.is(RuntimeMode);

isRuntimeMode("full-access"); // true
isRuntimeMode("invalid"); // false
See also: