import { z } from "zod"; import { CLIENT_CAPS } from "./client-capabilities.js"; import { AGENT_LIFECYCLE_STATUSES } from "./agent-lifecycle.js"; import { MAX_EXPLICIT_AGENT_TITLE_CHARS } from "../server/agent/agent-title-limits.js"; import { AgentProviderSchema } from "../server/agent/provider-manifest.js"; import { TOOL_CALL_ICON_NAMES } from "../server/agent/agent-sdk-types.js"; import { ChatCreateRequestSchema, ChatListRequestSchema, ChatInspectRequestSchema, ChatDeleteRequestSchema, ChatPostRequestSchema, ChatReadRequestSchema, ChatWaitRequestSchema, ChatCreateResponseSchema, ChatListResponseSchema, ChatInspectResponseSchema, ChatDeleteResponseSchema, ChatPostResponseSchema, ChatReadResponseSchema, ChatWaitResponseSchema, } from "../server/chat/chat-rpc-schemas.js"; import { ScheduleCreateRequestSchema, ScheduleListRequestSchema, ScheduleInspectRequestSchema, ScheduleLogsRequestSchema, SchedulePauseRequestSchema, ScheduleResumeRequestSchema, ScheduleDeleteRequestSchema, ScheduleRunOnceRequestSchema, ScheduleUpdateRequestSchema, ScheduleCreateResponseSchema, ScheduleListResponseSchema, ScheduleInspectResponseSchema, ScheduleLogsResponseSchema, SchedulePauseResponseSchema, ScheduleResumeResponseSchema, ScheduleDeleteResponseSchema, ScheduleRunOnceResponseSchema, ScheduleUpdateResponseSchema, } from "../server/schedule/rpc-schemas.js"; import { LoopRunRequestSchema, LoopListRequestSchema, LoopInspectRequestSchema, LoopLogsRequestSchema, LoopStopRequestSchema, LoopRunResponseSchema, LoopListResponseSchema, LoopInspectResponseSchema, LoopLogsResponseSchema, LoopStopResponseSchema, } from "../server/loop/rpc-schemas.js"; import { PaseoConfigRawSchema, PaseoLifecycleCommandRawSchema, PaseoMetadataGenerationEntrySchema, PaseoMetadataGenerationSchema, PaseoScriptEntryRawSchema, PaseoWorktreeConfigRawSchema, PaseoConfigRevisionSchema, ProjectConfigRpcErrorSchema, type PaseoConfigRaw, type PaseoConfigRevision, type PaseoMetadataGeneration, type PaseoMetadataGenerationEntry, type PaseoScriptEntryRaw, type ProjectConfigRpcError, } from "../utils/paseo-config-schema.js"; export { PaseoConfigRawSchema, PaseoLifecycleCommandRawSchema, PaseoMetadataGenerationEntrySchema, PaseoMetadataGenerationSchema, PaseoScriptEntryRawSchema, PaseoWorktreeConfigRawSchema, type PaseoConfigRaw, type PaseoConfigRevision, type PaseoMetadataGeneration, type PaseoMetadataGenerationEntry, type PaseoScriptEntryRaw, type ProjectConfigRpcError, }; // --------------------------------------------------------------------------- // Mutable daemon config schemas (shared between server store and client) // --------------------------------------------------------------------------- const MutableDaemonProviderModelSchema = z .object({ id: z.string().min(1), label: z.string().min(1), description: z.string().optional(), isDefault: z.boolean().optional(), }) .passthrough(); const MutableDaemonProviderConfigSchema = z .object({ enabled: z.boolean().optional(), additionalModels: z.array(MutableDaemonProviderModelSchema).optional(), }) .passthrough(); export const MutableDaemonConfigSchema = z .object({ mcp: z .object({ injectIntoAgents: z.boolean(), }) .passthrough(), providers: z.record(z.string(), MutableDaemonProviderConfigSchema).default({}), }) .passthrough(); export const MutableDaemonConfigPatchSchema = z .object({ mcp: MutableDaemonConfigSchema.shape.mcp.partial().optional(), providers: z .record(z.string(), MutableDaemonProviderConfigSchema.partial().passthrough()) .optional(), }) .partial() .passthrough(); export type MutableDaemonConfig = z.infer; export type MutableDaemonConfigPatch = z.infer; import type { LiteralUnion } from "./literal-union.js"; import type { AgentCapabilityFlags, AgentModelDefinition, AgentMode, AgentPermissionRequest, AgentPermissionResponse, AgentPersistenceHandle, ProviderStatus, AgentRuntimeInfo, AgentTimelineItem, ToolCallDetail, ToolCallTimelineItem, AgentUsage, } from "../server/agent/agent-sdk-types.js"; export const AgentStatusSchema = z.enum(AGENT_LIFECYCLE_STATUSES); const AgentModeSchema: z.ZodType = z.object({ id: z.string(), label: z.string(), description: z.string().optional(), icon: z.string().optional(), colorTier: z.string().optional(), }); const ProviderStatusSchema: z.ZodType = z.enum([ "ready", "loading", "error", "unavailable", ]); const AgentSelectOptionSchema = z.object({ id: z.string(), label: z.string(), description: z.string().optional(), isDefault: z.boolean().optional(), metadata: z.record(z.unknown()).optional(), }); export const AgentFeatureToggleSchema = z.object({ type: z.literal("toggle"), id: z.string(), label: z.string(), description: z.string().optional(), tooltip: z.string().optional(), icon: z.string().optional(), value: z.boolean(), }); export const AgentFeatureSelectSchema = z.object({ type: z.literal("select"), id: z.string(), label: z.string(), description: z.string().optional(), tooltip: z.string().optional(), icon: z.string().optional(), value: z.string().nullable(), options: z.array(AgentSelectOptionSchema), }); export const AgentFeatureSchema = z.discriminatedUnion("type", [ AgentFeatureToggleSchema, AgentFeatureSelectSchema, ]); const AgentModelDefinitionSchema: z.ZodType = z.object({ provider: AgentProviderSchema, id: z.string(), label: z.string(), description: z.string().optional(), isDefault: z.boolean().optional(), metadata: z.record(z.unknown()).optional(), thinkingOptions: z.array(AgentSelectOptionSchema).optional(), defaultThinkingOptionId: z.string().optional(), }); export const ProviderSnapshotEntrySchema = z.object({ provider: AgentProviderSchema, status: ProviderStatusSchema, enabled: z.boolean().optional().default(true), error: z.string().optional(), models: z.array(AgentModelDefinitionSchema).optional(), modes: z.array(AgentModeSchema).optional(), fetchedAt: z.string().optional(), label: z.string().optional(), description: z.string().optional(), defaultModeId: z.string().nullable().optional(), }); const AgentCapabilityFlagsSchema: z.ZodType = z.object({ supportsStreaming: z.boolean(), supportsSessionPersistence: z.boolean(), supportsDynamicModes: z.boolean(), supportsMcpServers: z.boolean(), supportsReasoningStream: z.boolean(), supportsToolInvocations: z.boolean(), }); const AgentUsageSchema: z.ZodType = z.object({ inputTokens: z.number().optional(), cachedInputTokens: z.number().optional(), outputTokens: z.number().optional(), totalCostUsd: z.number().optional(), contextWindowMaxTokens: z.number().optional(), contextWindowUsedTokens: z.number().optional(), }); const McpStdioServerConfigSchema = z.object({ type: z.literal("stdio"), command: z.string(), args: z.array(z.string()).optional(), env: z.record(z.string()).optional(), }); const McpHttpServerConfigSchema = z.object({ type: z.literal("http"), url: z.string(), headers: z.record(z.string()).optional(), }); const McpSseServerConfigSchema = z.object({ type: z.literal("sse"), url: z.string(), headers: z.record(z.string()).optional(), }); const McpServerConfigSchema = z.discriminatedUnion("type", [ McpStdioServerConfigSchema, McpHttpServerConfigSchema, McpSseServerConfigSchema, ]); const AgentSessionConfigSchema = z.object({ provider: AgentProviderSchema, cwd: z.string(), modeId: z.string().optional(), model: z.string().optional(), thinkingOptionId: z.string().optional(), featureValues: z.record(z.unknown()).optional(), title: z.string().trim().min(1).max(MAX_EXPLICIT_AGENT_TITLE_CHARS).optional().nullable(), approvalPolicy: z.string().optional(), sandboxMode: z.string().optional(), networkAccess: z.boolean().optional(), webSearch: z.boolean().optional(), extra: z .object({ codex: z.record(z.unknown()).optional(), claude: z.record(z.unknown()).optional(), }) .partial() .optional(), systemPrompt: z.string().optional(), mcpServers: z.record(McpServerConfigSchema).optional(), }); const AgentPermissionUpdateSchema = z.record(z.unknown()); const AgentPermissionActionSchema = z.object({ id: z.string(), label: z.string(), behavior: z.enum(["allow", "deny"]), variant: z.enum(["primary", "secondary", "danger"]).optional(), intent: z.enum(["implement", "implement_resume", "dismiss"]).optional(), }); export const AgentPermissionResponseSchema: z.ZodType = z.union([ z.object({ behavior: z.literal("allow"), selectedActionId: z.string().optional(), updatedInput: z.record(z.unknown()).optional(), updatedPermissions: z.array(AgentPermissionUpdateSchema).optional(), }), z.object({ behavior: z.literal("deny"), selectedActionId: z.string().optional(), message: z.string().optional(), interrupt: z.boolean().optional(), }), ]); export const AgentPermissionRequestPayloadSchema: z.ZodType< AgentPermissionRequest, z.ZodTypeDef, unknown > = z.object({ id: z.string(), provider: AgentProviderSchema, name: z.string(), kind: z.enum(["tool", "plan", "question", "mode", "other"]), title: z.string().optional(), description: z.string().optional(), input: z.record(z.unknown()).optional(), detail: z.lazy(() => ToolCallDetailPayloadSchema).optional(), suggestions: z.array(AgentPermissionUpdateSchema).optional(), actions: z.array(AgentPermissionActionSchema).optional(), metadata: z.record(z.unknown()).optional(), }); const UnknownValueSchema = z.union([ z.null(), z.boolean(), z.number(), z.string(), z.array(z.unknown()), z.object({}).passthrough(), ]); const NonNullUnknownSchema = z.union([ z.boolean(), z.number(), z.string(), z.array(z.unknown()), z.object({}).passthrough(), ]); const WorktreeSetupCommandSnapshotSchema = z.object({ index: z.number().int().positive(), command: z.string(), cwd: z.string(), log: z.string().optional().default(""), status: z.enum(["running", "completed", "failed"]), exitCode: z.number().nullable(), durationMs: z.number().nonnegative().optional(), }); const WorktreeSetupDetailPayloadSchema = z.object({ type: z.literal("worktree_setup"), worktreePath: z.string(), branchName: z.string(), log: z.string(), commands: z.array(WorktreeSetupCommandSnapshotSchema), truncated: z.boolean().optional(), }); const ToolCallDetailPayloadSchema: z.ZodType = z.discriminatedUnion("type", [ WorktreeSetupDetailPayloadSchema, z.object({ type: z.literal("shell"), command: z.string(), cwd: z.string().optional(), output: z.string().optional(), exitCode: z.number().nullable().optional(), }), z.object({ type: z.literal("read"), filePath: z.string(), content: z.string().optional(), offset: z.number().optional(), limit: z.number().optional(), }), z.object({ type: z.literal("edit"), filePath: z.string(), oldString: z.string().optional(), newString: z.string().optional(), unifiedDiff: z.string().optional(), }), z.object({ type: z.literal("write"), filePath: z.string(), content: z.string().optional(), }), z.object({ type: z.literal("search"), query: z.string(), toolName: z.enum(["search", "grep", "glob", "web_search"]).optional(), content: z.string().optional(), filePaths: z.array(z.string()).optional(), webResults: z .array( z.object({ title: z.string(), url: z.string(), }), ) .optional(), annotations: z.array(z.string()).optional(), numFiles: z.number().optional(), numMatches: z.number().optional(), durationMs: z.number().optional(), durationSeconds: z.number().optional(), truncated: z.boolean().optional(), mode: z.enum(["content", "files_with_matches", "count"]).optional(), }), z.object({ type: z.literal("fetch"), url: z.string(), prompt: z.string().optional(), result: z.string().optional(), code: z.number().optional(), codeText: z.string().optional(), bytes: z.number().optional(), durationMs: z.number().optional(), }), z.object({ type: z.literal("sub_agent"), subAgentType: z.string().optional(), description: z.string().optional(), childSessionId: z.string().optional(), log: z.string(), // Compat cruft for clients <= 0.1.65-beta.3 that required this field. Producers still // emit `[]`; nothing reads it. Drop the field (and the `[]` emissions) once those // clients are no longer in the field. actions: z .array( z.object({ index: z.number().int().positive(), toolName: z.string(), summary: z.string().optional(), }), ) .optional(), }), z.object({ type: z.literal("plain_text"), label: z.string().optional(), text: z.string().optional(), icon: z.enum(TOOL_CALL_ICON_NAMES).optional(), }), z.object({ type: z.literal("plan"), text: z.string(), }), z.object({ type: z.literal("unknown"), input: UnknownValueSchema, output: UnknownValueSchema, }), ]); const ToolCallBasePayloadSchema = z .object({ type: z.literal("tool_call"), callId: z.string(), name: z.string(), detail: ToolCallDetailPayloadSchema, metadata: z.record(z.string(), z.unknown()).optional(), }) .strict(); const ToolCallRunningPayloadSchema = ToolCallBasePayloadSchema.extend({ status: z.literal("running"), error: z.null(), }); const ToolCallCompletedPayloadSchema = ToolCallBasePayloadSchema.extend({ status: z.literal("completed"), error: z.null(), }); const ToolCallFailedPayloadSchema = ToolCallBasePayloadSchema.extend({ status: z.literal("failed"), error: NonNullUnknownSchema, }); const ToolCallCanceledPayloadSchema = ToolCallBasePayloadSchema.extend({ status: z.literal("canceled"), error: z.null(), }); const ToolCallTimelineItemPayloadSchema: z.ZodType = z.union([ ToolCallRunningPayloadSchema, ToolCallCompletedPayloadSchema, ToolCallFailedPayloadSchema, ToolCallCanceledPayloadSchema, ]); export const AgentTimelineItemPayloadSchema: z.ZodType = z.union([ z.object({ type: z.literal("user_message"), text: z.string(), messageId: z.string().optional(), }), z.object({ type: z.literal("assistant_message"), text: z.string(), messageId: z.string().optional(), }), z.object({ type: z.literal("reasoning"), text: z.string(), }), ToolCallTimelineItemPayloadSchema, z.object({ type: z.literal("todo"), items: z.array( z.object({ text: z.string(), completed: z.boolean(), }), ), }), z.object({ type: z.literal("error"), message: z.string(), }), z.object({ type: z.literal("compaction"), status: z.enum(["loading", "completed"]), trigger: z.enum(["auto", "manual"]).optional(), preTokens: z.number().optional(), }), ]); export const AgentStreamEventPayloadSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal("thread_started"), sessionId: z.string(), provider: AgentProviderSchema, }), z.object({ type: z.literal("turn_started"), provider: AgentProviderSchema, }), z.object({ type: z.literal("turn_completed"), provider: AgentProviderSchema, usage: AgentUsageSchema.optional(), }), z.object({ type: z.literal("turn_failed"), provider: AgentProviderSchema, error: z.string(), code: z.string().optional(), diagnostic: z.string().optional(), }), z.object({ type: z.literal("turn_canceled"), provider: AgentProviderSchema, reason: z.string(), }), z.object({ type: z.literal("timeline"), provider: AgentProviderSchema, item: AgentTimelineItemPayloadSchema, }), z.object({ type: z.literal("permission_requested"), provider: AgentProviderSchema, request: AgentPermissionRequestPayloadSchema, }), z.object({ type: z.literal("permission_resolved"), provider: AgentProviderSchema, requestId: z.string(), resolution: AgentPermissionResponseSchema, }), z.object({ type: z.literal("attention_required"), provider: AgentProviderSchema, reason: z.enum(["finished", "error", "permission"]), timestamp: z.string(), shouldNotify: z.boolean(), notification: z .object({ title: z.string(), body: z.string(), data: z.object({ serverId: z.string(), agentId: z.string(), reason: z.enum(["finished", "error", "permission"]), }), }) .optional(), }), ]); const AgentPersistenceHandleSchema: z.ZodType = z .object({ provider: AgentProviderSchema, sessionId: z.string(), nativeHandle: z.string().optional(), metadata: z.record(z.string(), z.unknown()).optional(), }) .nullable(); const AgentRuntimeInfoSchema: z.ZodType = z.object({ provider: AgentProviderSchema, sessionId: z.string().nullable(), model: z.string().nullable().optional(), thinkingOptionId: z.string().nullable().optional(), modeId: z.string().nullable().optional(), extra: z.record(z.string(), z.unknown()).optional(), }); export const AgentSnapshotPayloadSchema = z.object({ id: z.string(), provider: AgentProviderSchema, cwd: z.string(), model: z.string().nullable(), features: z.array(AgentFeatureSchema).optional(), thinkingOptionId: z.string().nullable().optional(), effectiveThinkingOptionId: z.string().nullable().optional(), createdAt: z.string(), updatedAt: z.string(), lastUserMessageAt: z.string().nullable(), status: AgentStatusSchema, capabilities: AgentCapabilityFlagsSchema, currentModeId: z.string().nullable(), availableModes: z.array(AgentModeSchema), pendingPermissions: z.array(AgentPermissionRequestPayloadSchema), persistence: AgentPersistenceHandleSchema.nullable(), runtimeInfo: AgentRuntimeInfoSchema.optional(), lastUsage: AgentUsageSchema.optional(), lastError: z.string().optional(), title: z.string().nullable(), labels: z.record(z.string(), z.string()).default({}), requiresAttention: z.boolean().optional(), attentionReason: z.enum(["finished", "error", "permission"]).nullable().optional(), attentionTimestamp: z.string().nullable().optional(), archivedAt: z.string().nullable().optional(), providerUnavailable: z.boolean().optional(), }); export type AgentSnapshotPayload = z.infer; export const AgentListItemPayloadSchema = z.object({ id: z.string(), shortId: z.string(), title: z.string().nullable(), provider: AgentProviderSchema, model: z.string().nullable(), thinkingOptionId: z.string().nullable().optional(), effectiveThinkingOptionId: z.string().nullable().optional(), status: AgentStatusSchema, cwd: z.string(), createdAt: z.string(), updatedAt: z.string(), lastUserMessageAt: z.string().nullable(), archivedAt: z.string().nullable().optional(), requiresAttention: z.boolean().optional(), attentionReason: z.enum(["finished", "error", "permission"]).nullable().optional(), attentionTimestamp: z.string().nullable().optional(), labels: z.record(z.string(), z.string()).default({}), providerUnavailable: z.boolean().optional(), }); export type AgentListItemPayload = z.infer; export type AgentStreamEventPayload = z.infer; export const RecentProviderSessionDescriptorPayloadSchema = z.object({ providerId: z.string(), providerLabel: z.string(), providerHandleId: z.string(), cwd: z.string(), title: z.string().nullable(), firstPromptPreview: z.string().nullable(), lastPromptPreview: z.string().nullable(), lastActivityAt: z.string(), }); export type RecentProviderSessionDescriptorPayload = z.infer< typeof RecentProviderSessionDescriptorPayloadSchema >; // ============================================================================ // Session Inbound Messages (Session receives these) // ============================================================================ export const VoiceAudioChunkMessageSchema = z.object({ type: z.literal("voice_audio_chunk"), audio: z.string(), // base64 encoded format: z.string(), isLast: z.boolean(), }); export const AbortRequestMessageSchema = z.object({ type: z.literal("abort_request"), }); export const AudioPlayedMessageSchema = z.object({ type: z.literal("audio_played"), id: z.string(), }); const AgentDirectoryFilterSchema = z.object({ labels: z.record(z.string()).optional(), projectKeys: z.array(z.string()).optional(), statuses: z.array(AgentStatusSchema).optional(), includeArchived: z.boolean().optional(), requiresAttention: z.boolean().optional(), thinkingOptionId: z.string().nullable().optional(), }); export const DeleteAgentRequestMessageSchema = z.object({ type: z.literal("delete_agent_request"), agentId: z.string(), requestId: z.string(), }); export const ArchiveAgentRequestMessageSchema = z.object({ type: z.literal("archive_agent_request"), agentId: z.string(), requestId: z.string(), }); export const CloseItemsRequestMessageSchema = z.object({ type: z.literal("close_items_request"), agentIds: z.array(z.string()).default([]), terminalIds: z.array(z.string()).default([]), requestId: z.string(), }); export const UpdateAgentRequestMessageSchema = z.object({ type: z.literal("update_agent_request"), agentId: z.string(), name: z.string().optional(), labels: z.record(z.string()).optional(), requestId: z.string(), }); export const SetVoiceModeMessageSchema = z.object({ type: z.literal("set_voice_mode"), enabled: z.boolean(), agentId: z.string().optional(), requestId: z.string().optional(), }); export const GitHubPrAttachmentSchema = z.object({ type: z.literal("github_pr"), mimeType: z.literal("application/github-pr"), number: z.number().int().positive(), title: z.string(), url: z.string(), body: z.string().nullable().optional(), baseRefName: z.string().nullable().optional(), headRefName: z.string().nullable().optional(), }); export const GitHubIssueAttachmentSchema = z.object({ type: z.literal("github_issue"), mimeType: z.literal("application/github-issue"), number: z.number().int().positive(), title: z.string(), url: z.string(), body: z.string().nullable().optional(), }); export const TextAttachmentSchema = z.object({ type: z.literal("text"), mimeType: z.literal("text/plain"), title: z.string().nullable().optional(), text: z.string(), }); export const ReviewAttachmentContextLineSchema = z.object({ oldLineNumber: z.number().int().positive().nullable(), newLineNumber: z.number().int().positive().nullable(), type: z.enum(["add", "remove", "context"]), content: z.string(), }); export const ReviewAttachmentCommentSchema = z.object({ filePath: z.string(), side: z.enum(["old", "new"]), lineNumber: z.number().int().positive(), body: z.string(), context: z.object({ hunkHeader: z.string(), targetLine: ReviewAttachmentContextLineSchema, lines: z.array(ReviewAttachmentContextLineSchema), }), }); export const ReviewAttachmentSchema = z.object({ type: z.literal("review"), mimeType: z.literal("application/paseo-review"), cwd: z.string(), mode: z.enum(["uncommitted", "base"]), baseRef: z.string().nullable().optional(), comments: z.array(ReviewAttachmentCommentSchema), }); export const AgentAttachmentSchema = z.discriminatedUnion("type", [ GitHubPrAttachmentSchema, GitHubIssueAttachmentSchema, TextAttachmentSchema, ReviewAttachmentSchema, ]); function normalizeAgentAttachments(input: unknown): AgentAttachment[] { if (!Array.isArray(input)) { return []; } const normalized: AgentAttachment[] = []; for (const item of input) { const parsed = AgentAttachmentSchema.safeParse(item); if (parsed.success) { normalized.push(parsed.data); } } return normalized; } const AgentAttachmentsSchema = z.unknown().transform(normalizeAgentAttachments).optional(); const ImageAttachmentSchema = z.object({ data: z.string(), // base64 encoded image mimeType: z.string(), // e.g., "image/jpeg", "image/png" }); export const SendAgentMessageSchema = z.object({ type: z.literal("send_agent_message"), agentId: z.string(), text: z.string(), messageId: z.string().optional(), // Client-provided ID for deduplication images: z.array(ImageAttachmentSchema).optional(), attachments: AgentAttachmentsSchema, }); // ============================================================================ // Agent RPCs (requestId-correlated) // ============================================================================ export const FetchAgentsRequestMessageSchema = z.object({ type: z.literal("fetch_agents_request"), requestId: z.string(), scope: z.enum(["active"]).optional(), filter: AgentDirectoryFilterSchema.optional(), sort: z .array( z.object({ key: z.enum(["status_priority", "created_at", "updated_at", "title"]), direction: z.enum(["asc", "desc"]), }), ) .optional(), page: z .object({ limit: z.number().int().positive().max(200), cursor: z.string().min(1).optional(), }) .optional(), subscribe: z .object({ subscriptionId: z.string().optional(), }) .optional(), }); const WorkspaceStateBucketSchema = z.enum([ "needs_input", "failed", "running", "attention", "done", ]); export const FetchWorkspacesRequestMessageSchema = z.object({ type: z.literal("fetch_workspaces_request"), requestId: z.string(), filter: z .object({ query: z.string().optional(), projectId: z.string().optional(), idPrefix: z.string().optional(), }) .optional(), sort: z .array( z.object({ key: z.enum(["status_priority", "activity_at", "name", "project_id"]), direction: z.enum(["asc", "desc"]), }), ) .optional(), page: z .object({ limit: z.number().int().positive().max(200), cursor: z.string().min(1).optional(), }) .optional(), subscribe: z .object({ subscriptionId: z.string().optional(), }) .optional(), }); export const FetchAgentHistoryRequestMessageSchema = z.object({ type: z.literal("fetch_agent_history_request"), requestId: z.string(), filter: AgentDirectoryFilterSchema.optional(), sort: z .array( z.object({ key: z.enum(["status_priority", "created_at", "updated_at", "title"]), direction: z.enum(["asc", "desc"]), }), ) .optional(), page: z .object({ limit: z.number().int().positive().max(200), cursor: z.string().min(1).optional(), }) .optional(), }); export const FetchRecentProviderSessionsRequestMessageSchema = z.object({ type: z.literal("fetch_recent_provider_sessions_request"), requestId: z.string(), cwd: z.string().optional(), providers: z.array(z.string()).optional(), since: z.string().optional(), limit: z.number().int().positive().max(200).optional(), }); export const FetchAgentRequestMessageSchema = z.object({ type: z.literal("fetch_agent_request"), requestId: z.string(), /** Accepts full ID, unique prefix, or exact full title (server resolves). */ agentId: z.string(), }); export const SendAgentMessageRequestSchema = z.object({ type: z.literal("send_agent_message_request"), requestId: z.string(), /** Accepts full ID, unique prefix, or exact full title (server resolves). */ agentId: z.string(), text: z.string(), messageId: z.string().optional(), // Client-provided ID for deduplication images: z.array(ImageAttachmentSchema).optional(), attachments: AgentAttachmentsSchema, }); export const WaitForFinishRequestSchema = z.object({ type: z.literal("wait_for_finish_request"), requestId: z.string(), /** Accepts full ID, unique prefix, or exact full title (server resolves). */ agentId: z.string(), timeoutMs: z.number().int().positive().optional(), }); export const GetDaemonConfigRequestMessageSchema = z.object({ type: z.literal("get_daemon_config_request"), requestId: z.string(), }); export const SetDaemonConfigRequestMessageSchema = z.object({ type: z.literal("set_daemon_config_request"), requestId: z.string(), config: MutableDaemonConfigPatchSchema, }); export const ReadProjectConfigRequestMessageSchema = z.object({ type: z.literal("read_project_config_request"), requestId: z.string(), repoRoot: z.string(), }); export const WriteProjectConfigRequestMessageSchema = z.object({ type: z.literal("write_project_config_request"), requestId: z.string(), repoRoot: z.string(), config: PaseoConfigRawSchema, expectedRevision: PaseoConfigRevisionSchema.nullable(), }); // ============================================================================ // Dictation Streaming (lossless, resumable) // ============================================================================ export const DictationStreamStartMessageSchema = z.object({ type: z.literal("dictation_stream_start"), dictationId: z.string(), format: z.string(), // e.g. "audio/pcm;rate=16000;bits=16" }); export const DictationStreamChunkMessageSchema = z.object({ type: z.literal("dictation_stream_chunk"), dictationId: z.string(), seq: z.number().int().nonnegative(), audio: z.string(), // base64 encoded chunk format: z.string(), // e.g. "audio/pcm;rate=16000;bits=16" }); export const DictationStreamFinishMessageSchema = z.object({ type: z.literal("dictation_stream_finish"), dictationId: z.string(), finalSeq: z.number().int().nonnegative(), }); export const DictationStreamCancelMessageSchema = z.object({ type: z.literal("dictation_stream_cancel"), dictationId: z.string(), }); const GitSetupOptionsSchema = z.object({ baseBranch: z.string().optional(), createNewBranch: z.boolean().optional(), newBranchName: z.string().optional(), createWorktree: z.boolean().optional(), worktreeSlug: z.string().optional(), refName: z.string().min(1).optional(), action: z.enum(["branch-off", "checkout"]).optional(), githubPrNumber: z.number().int().positive().optional(), }); export type GitSetupOptions = z.infer; export const CreateAgentRequestMessageSchema = z.object({ type: z.literal("create_agent_request"), config: AgentSessionConfigSchema, workspaceId: z.string().optional(), worktreeName: z.string().optional(), initialPrompt: z.string().optional(), clientMessageId: z.string().optional(), outputSchema: z.record(z.unknown()).optional(), images: z.array(ImageAttachmentSchema).optional(), attachments: AgentAttachmentsSchema, git: GitSetupOptionsSchema.optional(), labels: z.record(z.string()).default({}), requestId: z.string(), }); export const ListProviderModelsRequestMessageSchema = z.object({ type: z.literal("list_provider_models_request"), provider: AgentProviderSchema, cwd: z.string().optional(), requestId: z.string(), }); export const ListProviderModesRequestMessageSchema = z.object({ type: z.literal("list_provider_modes_request"), provider: AgentProviderSchema, cwd: z.string().optional(), requestId: z.string(), }); export const ListAvailableProvidersRequestMessageSchema = z.object({ type: z.literal("list_available_providers_request"), requestId: z.string(), }); export const GetProvidersSnapshotRequestMessageSchema = z.object({ type: z.literal("get_providers_snapshot_request"), cwd: z.string().optional(), requestId: z.string(), }); export const RefreshProvidersSnapshotRequestMessageSchema = z.object({ type: z.literal("refresh_providers_snapshot_request"), cwd: z.string().optional(), providers: z.array(AgentProviderSchema).optional(), requestId: z.string(), }); export const ProviderDiagnosticRequestMessageSchema = z.object({ type: z.literal("provider_diagnostic_request"), provider: AgentProviderSchema, requestId: z.string(), }); export const ResumeAgentRequestMessageSchema = z.object({ type: z.literal("resume_agent_request"), handle: AgentPersistenceHandleSchema, overrides: AgentSessionConfigSchema.partial().optional(), requestId: z.string(), }); export const ImportAgentRequestMessageSchema = z.object({ type: z.literal("import_agent_request"), provider: AgentProviderSchema.optional(), providerId: z.string().optional(), sessionId: z.string().optional(), providerHandleId: z.string().optional(), cwd: z.string().optional(), labels: z.record(z.string()).optional(), requestId: z.string(), }); export const RefreshAgentRequestMessageSchema = z.object({ type: z.literal("refresh_agent_request"), agentId: z.string(), requestId: z.string(), }); export const CancelAgentRequestMessageSchema = z.object({ type: z.literal("cancel_agent_request"), agentId: z.string(), requestId: z.string().optional(), }); export const RestartServerRequestMessageSchema = z.object({ type: z.literal("restart_server_request"), reason: z.string().optional(), requestId: z.string(), }); export const ShutdownServerRequestMessageSchema = z.object({ type: z.literal("shutdown_server_request"), requestId: z.string(), }); export const AgentTimelineCursorSchema = z.object({ epoch: z.string(), seq: z.number().int().nonnegative(), }); export const FetchAgentTimelineRequestMessageSchema = z.object({ type: z.literal("fetch_agent_timeline_request"), agentId: z.string(), requestId: z.string(), direction: z.enum(["tail", "before", "after"]).optional(), cursor: AgentTimelineCursorSchema.optional(), // 0 means "all matching rows for this query window". limit: z.number().int().nonnegative().optional(), // Default should be projected for app timeline loading. projection: z.enum(["projected", "canonical"]).optional(), }); export const SetAgentModeRequestMessageSchema = z.object({ type: z.literal("set_agent_mode_request"), agentId: z.string(), modeId: z.string(), requestId: z.string(), }); const AgentActionResponsePayloadSchema = z.object({ requestId: z.string(), agentId: z.string(), accepted: z.boolean(), error: z.string().nullable(), }); export const SetAgentModeResponseMessageSchema = z.object({ type: z.literal("set_agent_mode_response"), payload: AgentActionResponsePayloadSchema, }); export const SetAgentModelRequestMessageSchema = z.object({ type: z.literal("set_agent_model_request"), agentId: z.string(), modelId: z.string().nullable(), requestId: z.string(), }); export const SetAgentModelResponseMessageSchema = z.object({ type: z.literal("set_agent_model_response"), payload: AgentActionResponsePayloadSchema, }); export const SetAgentThinkingRequestMessageSchema = z.object({ type: z.literal("set_agent_thinking_request"), agentId: z.string(), thinkingOptionId: z.string().nullable(), requestId: z.string(), }); export const SetAgentThinkingResponseMessageSchema = z.object({ type: z.literal("set_agent_thinking_response"), payload: AgentActionResponsePayloadSchema, }); export const SetAgentFeatureRequestMessageSchema = z.object({ type: z.literal("set_agent_feature_request"), agentId: z.string(), featureId: z.string(), value: z.unknown(), requestId: z.string(), }); export const SetAgentFeatureResponseMessageSchema = z.object({ type: z.literal("set_agent_feature_response"), payload: AgentActionResponsePayloadSchema, }); export const UpdateAgentResponseMessageSchema = z.object({ type: z.literal("update_agent_response"), payload: AgentActionResponsePayloadSchema, }); export const SetVoiceModeResponseMessageSchema = z.object({ type: z.literal("set_voice_mode_response"), payload: z.object({ requestId: z.string(), enabled: z.boolean(), agentId: z.string().nullable(), accepted: z.boolean(), error: z.string().nullable(), reasonCode: z.string().optional(), retryable: z.boolean().optional(), missingModelIds: z.array(z.string()).optional(), }), }); export const AgentPermissionResponseMessageSchema = z.object({ type: z.literal("agent_permission_response"), agentId: z.string(), requestId: z.string(), response: AgentPermissionResponseSchema, }); const CheckoutErrorCodeSchema = z.enum([ "NOT_GIT_REPO", "NOT_ALLOWED", "MERGE_CONFLICT", "UNKNOWN", ]); const CheckoutErrorSchema = z.object({ code: CheckoutErrorCodeSchema, message: z.string(), }); const CheckoutDiffCompareSchema = z.object({ mode: z.enum(["uncommitted", "base"]), baseRef: z.string().optional(), ignoreWhitespace: z.boolean().optional(), }); export const CheckoutStatusRequestSchema = z.object({ type: z.literal("checkout_status_request"), cwd: z.string(), requestId: z.string(), }); export const SubscribeCheckoutDiffRequestSchema = z.object({ type: z.literal("subscribe_checkout_diff_request"), subscriptionId: z.string(), cwd: z.string(), compare: CheckoutDiffCompareSchema, requestId: z.string(), }); export const UnsubscribeCheckoutDiffRequestSchema = z.object({ type: z.literal("unsubscribe_checkout_diff_request"), subscriptionId: z.string(), }); export const CheckoutCommitRequestSchema = z.object({ type: z.literal("checkout_commit_request"), cwd: z.string(), message: z.string().optional(), addAll: z.boolean().optional(), requestId: z.string(), }); export const CheckoutMergeRequestSchema = z.object({ type: z.literal("checkout_merge_request"), cwd: z.string(), baseRef: z.string().optional(), strategy: z.enum(["merge", "squash"]).optional(), requireCleanTarget: z.boolean().optional(), requestId: z.string(), }); export const CheckoutMergeFromBaseRequestSchema = z.object({ type: z.literal("checkout_merge_from_base_request"), cwd: z.string(), baseRef: z.string().optional(), requireCleanTarget: z.boolean().optional(), requestId: z.string(), }); export const CheckoutPullRequestSchema = z.object({ type: z.literal("checkout_pull_request"), cwd: z.string(), requestId: z.string(), }); export const CheckoutPushRequestSchema = z.object({ type: z.literal("checkout_push_request"), cwd: z.string(), requestId: z.string(), }); export const CheckoutPrCreateRequestSchema = z.object({ type: z.literal("checkout_pr_create_request"), cwd: z.string(), title: z.string().optional(), body: z.string().optional(), baseRef: z.string().optional(), requestId: z.string(), }); export const CheckoutPrMergeRequestSchema = z.object({ type: z.literal("checkout_pr_merge_request"), cwd: z.string(), mergeMethod: z.enum(["merge", "squash", "rebase"]), requestId: z.string(), }); export const CheckoutPrStatusRequestSchema = z.object({ type: z.literal("checkout_pr_status_request"), cwd: z.string(), requestId: z.string(), }); export const PullRequestTimelineRequestSchema = z.object({ type: z.literal("pull_request_timeline_request"), cwd: z.string(), prNumber: z.number(), repoOwner: z.string(), repoName: z.string(), requestId: z.string(), }); export const ValidateBranchRequestSchema = z.object({ type: z.literal("validate_branch_request"), cwd: z.string(), branchName: z.string(), requestId: z.string(), }); export const CheckoutSwitchBranchRequestSchema = z.object({ type: z.literal("checkout_switch_branch_request"), cwd: z.string(), branch: z.string(), requestId: z.string(), }); export const StashSaveRequestSchema = z.object({ type: z.literal("stash_save_request"), cwd: z.string(), /** Branch name to tag the stash with for later identification. */ branch: z.string().optional(), requestId: z.string(), }); export const StashPopRequestSchema = z.object({ type: z.literal("stash_pop_request"), cwd: z.string(), /** Zero-based index from stash_list_response. */ stashIndex: z.number().int().min(0), requestId: z.string(), }); export const StashListRequestSchema = z.object({ type: z.literal("stash_list_request"), cwd: z.string(), /** If true, only return paseo-created stashes. Default true. */ paseoOnly: z.boolean().optional(), requestId: z.string(), }); export const BranchSuggestionsRequestSchema = z.object({ type: z.literal("branch_suggestions_request"), cwd: z.string(), query: z.string().optional(), limit: z.number().int().min(1).max(200).optional(), requestId: z.string(), }); export const GitHubSearchItemSchema = z.object({ kind: z.enum(["issue", "pr"]), number: z.number(), title: z.string(), url: z.string(), state: z.string(), body: z.string().nullable(), labels: z.array(z.string()), baseRefName: z.string().nullable().optional(), headRefName: z.string().nullable().optional(), updatedAt: z.string().optional(), }); export const GitHubSearchKindSchema = z.enum(["github-issue", "github-pr"]); export const GitHubSearchRequestSchema = z.object({ type: z.literal("github_search_request"), cwd: z.string(), query: z.string(), limit: z.number().int().min(1).max(50).optional(), kinds: z.array(GitHubSearchKindSchema).optional(), requestId: z.string(), }); export const DirectorySuggestionsRequestSchema = z.object({ type: z.literal("directory_suggestions_request"), query: z.string(), cwd: z.string().optional(), includeFiles: z.boolean().optional(), includeDirectories: z.boolean().optional(), limit: z.number().int().min(1).max(100).optional(), requestId: z.string(), }); export const PaseoWorktreeListRequestSchema = z.object({ type: z.literal("paseo_worktree_list_request"), cwd: z.string().optional(), repoRoot: z.string().optional(), requestId: z.string(), }); export const PaseoWorktreeArchiveRequestSchema = z.object({ type: z.literal("paseo_worktree_archive_request"), worktreePath: z.string().optional(), repoRoot: z.string().optional(), branchName: z.string().optional(), requestId: z.string(), }); export const FirstAgentContextSchema = z.object({ prompt: z.string().optional(), attachments: AgentAttachmentsSchema, }); export const CreatePaseoWorktreeRequestSchema = z.object({ type: z.literal("create_paseo_worktree_request"), cwd: z.string(), worktreeSlug: z.string().optional(), nameContext: z.string().optional(), attachments: AgentAttachmentsSchema.optional(), firstAgentContext: FirstAgentContextSchema.optional(), refName: z.string().min(1).optional(), action: z.enum(["branch-off", "checkout"]).optional(), githubPrNumber: z.number().int().positive().optional(), requestId: z.string(), }); export const WorkspaceSetupStatusRequestSchema = z.object({ type: z.literal("workspace_setup_status_request"), workspaceId: z.string(), requestId: z.string(), }); // TODO(2026-07): Remove once most clients are on >=0.1.50 and support arbitrary editor ids. export const LEGACY_EDITOR_TARGET_IDS = [ "cursor", "vscode", "zed", "finder", "explorer", "file-manager", ] as const; export const KNOWN_EDITOR_TARGET_IDS = [...LEGACY_EDITOR_TARGET_IDS, "webstorm"] as const; export const KnownEditorTargetIdSchema = z.enum(KNOWN_EDITOR_TARGET_IDS); export const LegacyEditorTargetIdSchema = z.enum(LEGACY_EDITOR_TARGET_IDS); export const EditorTargetIdSchema = z.string().trim().min(1); const KNOWN_EDITOR_TARGET_ID_SET = new Set(KNOWN_EDITOR_TARGET_IDS); const LEGACY_EDITOR_TARGET_ID_SET = new Set(LEGACY_EDITOR_TARGET_IDS); export function isKnownEditorTargetId(value: string): value is KnownEditorTargetId { return KNOWN_EDITOR_TARGET_ID_SET.has(value); } export function isLegacyEditorTargetId(value: string): value is LegacyEditorTargetId { return LEGACY_EDITOR_TARGET_ID_SET.has(value); } export const EditorTargetDescriptorPayloadSchema = z.object({ id: EditorTargetIdSchema, label: z.string(), }); export const ListAvailableEditorsRequestSchema = z.object({ type: z.literal("list_available_editors_request"), requestId: z.string(), }); export const OpenInEditorRequestSchema = z.object({ type: z.literal("open_in_editor_request"), path: z.string(), editorId: EditorTargetIdSchema, requestId: z.string(), }); export const OpenProjectRequestSchema = z.object({ type: z.literal("open_project_request"), cwd: z.string(), requestId: z.string(), }); export const ArchiveWorkspaceRequestSchema = z.object({ type: z.literal("archive_workspace_request"), workspaceId: z.string(), requestId: z.string(), }); // Highlighted diff token schema // Note: style can be a compound class name (e.g., "heading meta") from the syntax highlighter const HighlightTokenSchema = z.object({ text: z.string(), style: z.string().nullable(), }); const DiffLineSchema = z.object({ type: z.enum(["add", "remove", "context", "header"]), content: z.string(), tokens: z.array(HighlightTokenSchema).optional(), }); const DiffHunkSchema = z.object({ oldStart: z.number(), oldCount: z.number(), newStart: z.number(), newCount: z.number(), lines: z.array(DiffLineSchema), }); const ParsedDiffFileSchema = z.object({ path: z.string(), isNew: z.boolean(), isDeleted: z.boolean(), additions: z.number(), deletions: z.number(), hunks: z.array(DiffHunkSchema), status: z.enum(["ok", "too_large", "binary"]).optional(), }); const FileExplorerEntrySchema = z.object({ name: z.string(), path: z.string(), kind: z.enum(["file", "directory"]), size: z.number(), modifiedAt: z.string(), }); const FileExplorerFileSchema = z.object({ path: z.string(), kind: z.enum(["text", "image", "binary"]), encoding: z.enum(["utf-8", "base64", "none"]), content: z.string().optional(), mimeType: z.string().optional(), size: z.number(), modifiedAt: z.string(), }); const FileExplorerDirectorySchema = z.object({ path: z.string(), entries: z.array(FileExplorerEntrySchema), }); export const FileExplorerRequestSchema = z.object({ type: z.literal("file_explorer_request"), cwd: z.string(), path: z.string().optional(), mode: z.enum(["list", "file"]), requestId: z.string(), acceptBinary: z.boolean().optional(), }); export const ProjectIconRequestSchema = z.object({ type: z.literal("project_icon_request"), cwd: z.string(), requestId: z.string(), }); export const FileDownloadTokenRequestSchema = z.object({ type: z.literal("file_download_token_request"), cwd: z.string(), path: z.string(), requestId: z.string(), }); export const ClearAgentAttentionMessageSchema = z.object({ type: z.literal("clear_agent_attention"), agentId: z.union([z.string(), z.array(z.string())]), requestId: z.string().optional(), }); export const ClientHeartbeatMessageSchema = z.object({ type: z.literal("client_heartbeat"), deviceType: z.enum(["web", "mobile"]), focusedAgentId: z.string().nullable(), lastActivityAt: z.string(), appVisible: z.boolean(), appVisibilityChangedAt: z.string().optional(), }); export const PingMessageSchema = z.object({ type: z.literal("ping"), requestId: z.string(), clientSentAt: z.number().int().optional(), }); const ListCommandsDraftConfigSchema = z.object({ provider: AgentProviderSchema, cwd: z.string(), modeId: z.string().optional(), model: z.string().optional(), thinkingOptionId: z.string().optional(), featureValues: z.record(z.unknown()).optional(), }); export const ListProviderFeaturesRequestMessageSchema = z.object({ type: z.literal("list_provider_features_request"), draftConfig: ListCommandsDraftConfigSchema, requestId: z.string(), }); export const ListCommandsRequestSchema = z.object({ type: z.literal("list_commands_request"), agentId: z.string(), draftConfig: ListCommandsDraftConfigSchema.optional(), requestId: z.string(), }); export const RegisterPushTokenMessageSchema = z.object({ type: z.literal("register_push_token"), token: z.string(), }); // ============================================================================ // Terminal Messages // ============================================================================ export const ListTerminalsRequestSchema = z.object({ type: z.literal("list_terminals_request"), cwd: z.string().optional(), requestId: z.string(), }); export const SubscribeTerminalsRequestSchema = z.object({ type: z.literal("subscribe_terminals_request"), cwd: z.string(), }); export const UnsubscribeTerminalsRequestSchema = z.object({ type: z.literal("unsubscribe_terminals_request"), cwd: z.string(), }); export const CreateTerminalRequestSchema = z.object({ type: z.literal("create_terminal_request"), cwd: z.string(), name: z.string().optional(), agentId: z.string().optional(), command: z.string().optional(), args: z.array(z.string()).optional(), requestId: z.string(), }); export const StartWorkspaceScriptRequestSchema = z.object({ type: z.literal("start_workspace_script_request"), workspaceId: z.string(), scriptName: z.string(), requestId: z.string(), }); export const SubscribeTerminalRequestSchema = z.object({ type: z.literal("subscribe_terminal_request"), terminalId: z.string(), requestId: z.string(), }); export const UnsubscribeTerminalRequestSchema = z.object({ type: z.literal("unsubscribe_terminal_request"), terminalId: z.string(), }); const TerminalClientMessageSchema = z.discriminatedUnion("type", [ z.object({ type: z.literal("input"), data: z.string() }), z.object({ type: z.literal("resize"), rows: z.number(), cols: z.number() }), z.object({ type: z.literal("mouse"), row: z.number(), col: z.number(), button: z.number(), action: z.enum(["down", "up", "move"]), }), ]); export const TerminalInputSchema = z.object({ type: z.literal("terminal_input"), terminalId: z.string(), message: TerminalClientMessageSchema, }); export const KillTerminalRequestSchema = z.object({ type: z.literal("kill_terminal_request"), terminalId: z.string(), requestId: z.string(), }); export const CaptureTerminalRequestSchema = z.object({ type: z.literal("capture_terminal_request"), terminalId: z.string(), start: z.number().int().optional(), end: z.number().int().optional(), stripAnsi: z.boolean().default(true), requestId: z.string(), }); export const SessionInboundMessageSchema = z.discriminatedUnion("type", [ VoiceAudioChunkMessageSchema, AbortRequestMessageSchema, AudioPlayedMessageSchema, FetchAgentsRequestMessageSchema, FetchAgentHistoryRequestMessageSchema, FetchRecentProviderSessionsRequestMessageSchema, FetchWorkspacesRequestMessageSchema, FetchAgentRequestMessageSchema, DeleteAgentRequestMessageSchema, ArchiveAgentRequestMessageSchema, CloseItemsRequestMessageSchema, UpdateAgentRequestMessageSchema, SetVoiceModeMessageSchema, SendAgentMessageRequestSchema, WaitForFinishRequestSchema, GetDaemonConfigRequestMessageSchema, SetDaemonConfigRequestMessageSchema, ReadProjectConfigRequestMessageSchema, WriteProjectConfigRequestMessageSchema, DictationStreamStartMessageSchema, DictationStreamChunkMessageSchema, DictationStreamFinishMessageSchema, DictationStreamCancelMessageSchema, CreateAgentRequestMessageSchema, ListProviderModelsRequestMessageSchema, ListProviderModesRequestMessageSchema, ListProviderFeaturesRequestMessageSchema, ListAvailableProvidersRequestMessageSchema, GetProvidersSnapshotRequestMessageSchema, RefreshProvidersSnapshotRequestMessageSchema, ProviderDiagnosticRequestMessageSchema, ResumeAgentRequestMessageSchema, ImportAgentRequestMessageSchema, RefreshAgentRequestMessageSchema, CancelAgentRequestMessageSchema, ShutdownServerRequestMessageSchema, RestartServerRequestMessageSchema, FetchAgentTimelineRequestMessageSchema, SetAgentModeRequestMessageSchema, SetAgentModelRequestMessageSchema, SetAgentThinkingRequestMessageSchema, SetAgentFeatureRequestMessageSchema, AgentPermissionResponseMessageSchema, CheckoutStatusRequestSchema, SubscribeCheckoutDiffRequestSchema, UnsubscribeCheckoutDiffRequestSchema, CheckoutCommitRequestSchema, CheckoutMergeRequestSchema, CheckoutMergeFromBaseRequestSchema, CheckoutPullRequestSchema, CheckoutPushRequestSchema, CheckoutPrCreateRequestSchema, CheckoutPrMergeRequestSchema, CheckoutPrStatusRequestSchema, PullRequestTimelineRequestSchema, CheckoutSwitchBranchRequestSchema, StashSaveRequestSchema, StashPopRequestSchema, StashListRequestSchema, ValidateBranchRequestSchema, BranchSuggestionsRequestSchema, GitHubSearchRequestSchema, DirectorySuggestionsRequestSchema, PaseoWorktreeListRequestSchema, PaseoWorktreeArchiveRequestSchema, CreatePaseoWorktreeRequestSchema, WorkspaceSetupStatusRequestSchema, ListAvailableEditorsRequestSchema, OpenInEditorRequestSchema, OpenProjectRequestSchema, ArchiveWorkspaceRequestSchema, FileExplorerRequestSchema, ProjectIconRequestSchema, FileDownloadTokenRequestSchema, ClearAgentAttentionMessageSchema, ClientHeartbeatMessageSchema, PingMessageSchema, ListCommandsRequestSchema, RegisterPushTokenMessageSchema, ListTerminalsRequestSchema, SubscribeTerminalsRequestSchema, UnsubscribeTerminalsRequestSchema, CreateTerminalRequestSchema, StartWorkspaceScriptRequestSchema, SubscribeTerminalRequestSchema, UnsubscribeTerminalRequestSchema, TerminalInputSchema, KillTerminalRequestSchema, CaptureTerminalRequestSchema, ChatCreateRequestSchema, ChatListRequestSchema, ChatInspectRequestSchema, ChatDeleteRequestSchema, ChatPostRequestSchema, ChatReadRequestSchema, ChatWaitRequestSchema, ScheduleCreateRequestSchema, ScheduleListRequestSchema, ScheduleInspectRequestSchema, ScheduleLogsRequestSchema, SchedulePauseRequestSchema, ScheduleResumeRequestSchema, ScheduleDeleteRequestSchema, ScheduleRunOnceRequestSchema, ScheduleUpdateRequestSchema, LoopRunRequestSchema, LoopListRequestSchema, LoopInspectRequestSchema, LoopLogsRequestSchema, LoopStopRequestSchema, ]); export type SessionInboundMessage = z.infer; // ============================================================================ // Session Outbound Messages (Session emits these) // ============================================================================ export const ActivityLogPayloadSchema = z.object({ id: z.string(), timestamp: z.coerce.date(), type: z.enum(["transcript", "assistant", "tool_call", "tool_result", "error", "system"]), content: z.string(), metadata: z.record(z.unknown()).optional(), }); export const ActivityLogMessageSchema = z.object({ type: z.literal("activity_log"), payload: ActivityLogPayloadSchema, }); export const AssistantChunkMessageSchema = z.object({ type: z.literal("assistant_chunk"), payload: z.object({ chunk: z.string(), }), }); export const AudioOutputMessageSchema = z.object({ type: z.literal("audio_output"), payload: z.object({ audio: z.string(), // base64 encoded format: z.string(), id: z.string(), isVoiceMode: z.boolean(), // Mode when audio was generated (for drift protection) groupId: z.string().optional(), // Logical utterance id chunkIndex: z.number().int().nonnegative().optional(), isLastChunk: z.boolean().optional(), }), }); export const TranscriptionResultMessageSchema = z.object({ type: z.literal("transcription_result"), payload: z.object({ text: z.string(), language: z.string().optional(), duration: z.number().optional(), requestId: z.string(), // Echoed back from request for tracking avgLogprob: z.number().optional(), isLowConfidence: z.boolean().optional(), byteLength: z.number().optional(), format: z.string().optional(), debugRecordingPath: z.string().optional(), }), }); export const VoiceInputStateMessageSchema = z.object({ type: z.literal("voice_input_state"), payload: z.object({ isSpeaking: z.boolean(), }), }); export const DictationStreamAckMessageSchema = z.object({ type: z.literal("dictation_stream_ack"), payload: z.object({ dictationId: z.string(), ackSeq: z.number().int(), }), }); export const DictationStreamFinishAcceptedMessageSchema = z.object({ type: z.literal("dictation_stream_finish_accepted"), payload: z.object({ dictationId: z.string(), timeoutMs: z.number().int().positive(), }), }); export const DictationStreamPartialMessageSchema = z.object({ type: z.literal("dictation_stream_partial"), payload: z.object({ dictationId: z.string(), text: z.string(), }), }); export const DictationStreamFinalMessageSchema = z.object({ type: z.literal("dictation_stream_final"), payload: z.object({ dictationId: z.string(), text: z.string(), debugRecordingPath: z.string().optional(), }), }); export const DictationStreamErrorMessageSchema = z.object({ type: z.literal("dictation_stream_error"), payload: z.object({ dictationId: z.string(), error: z.string(), retryable: z.boolean(), reasonCode: z.string().optional(), missingModelIds: z.array(z.string()).optional(), debugRecordingPath: z.string().optional(), }), }); export const ServerCapabilityStateSchema = z.object({ enabled: z.boolean(), reason: z.string(), }); export const ServerVoiceCapabilitiesSchema = z.object({ dictation: ServerCapabilityStateSchema, voice: ServerCapabilityStateSchema, }); export const ServerCapabilitiesSchema = z .object({ voice: ServerVoiceCapabilitiesSchema.optional(), }) .passthrough(); const ServerInfoHostnameSchema = z.unknown().transform((value): string | null => { if (typeof value !== "string") { return null; } const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : null; }); const ServerInfoVersionSchema = z.unknown().transform((value): string | null => { if (typeof value !== "string") { return null; } const trimmed = value.trim(); return trimmed.length > 0 ? trimmed : null; }); const ServerCapabilitiesFromUnknownSchema = z .unknown() .optional() .transform((value): z.infer | undefined => { if (value === undefined) { return undefined; } const parsed = ServerCapabilitiesSchema.safeParse(value); if (!parsed.success) { return undefined; } return parsed.data; }); export const ServerInfoStatusPayloadSchema = z .object({ status: z.literal("server_info"), serverId: z.string().trim().min(1), hostname: ServerInfoHostnameSchema.optional(), version: ServerInfoVersionSchema.optional(), capabilities: ServerCapabilitiesFromUnknownSchema, // COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot features: z .object({ providersSnapshot: z.boolean().optional(), }) .optional(), }) .passthrough() .transform((payload) => ({ ...payload, hostname: payload.hostname ?? null, version: payload.version ?? null, })); export const StatusMessageSchema = z.object({ type: z.literal("status"), payload: z .object({ status: z.string(), }) .passthrough(), // Allow additional fields }); export const PongMessageSchema = z.object({ type: z.literal("pong"), payload: z.object({ requestId: z.string(), clientSentAt: z.number().int().optional(), serverReceivedAt: z.number().int(), serverSentAt: z.number().int(), }), }); export const RpcErrorMessageSchema = z.object({ type: z.literal("rpc_error"), payload: z.object({ requestId: z.string(), requestType: z.string().optional(), error: z.string(), code: z.string().optional(), }), }); const AgentStatusWithRequestSchema = z.object({ agentId: z.string(), requestId: z.string(), }); const AgentStatusWithTimelineSchema = AgentStatusWithRequestSchema.extend({ timelineSize: z.number().optional(), }); export const AgentCreatedStatusPayloadSchema = z .object({ status: z.literal("agent_created"), agent: AgentSnapshotPayloadSchema, }) .extend(AgentStatusWithRequestSchema.shape); export const AgentCreateFailedStatusPayloadSchema = z.object({ status: z.literal("agent_create_failed"), requestId: z.string(), error: z.string(), errorCode: z.string().optional(), }); export const AgentResumedStatusPayloadSchema = z .object({ status: z.literal("agent_resumed"), agent: AgentSnapshotPayloadSchema, }) .extend(AgentStatusWithTimelineSchema.shape); export const AgentRefreshedStatusPayloadSchema = z .object({ status: z.literal("agent_refreshed"), }) .extend(AgentStatusWithTimelineSchema.shape); export const RestartRequestedStatusPayloadSchema = z.object({ status: z.literal("restart_requested"), clientId: z.string(), reason: z.string().optional(), requestId: z.string(), }); export const ShutdownRequestedStatusPayloadSchema = z.object({ status: z.literal("shutdown_requested"), clientId: z.string(), requestId: z.string(), }); export const DaemonConfigChangedStatusPayloadSchema = z .object({ status: z.literal("daemon_config_changed"), config: MutableDaemonConfigSchema, }) .passthrough(); export const KnownStatusPayloadSchema = z.discriminatedUnion("status", [ AgentCreatedStatusPayloadSchema, AgentCreateFailedStatusPayloadSchema, AgentResumedStatusPayloadSchema, AgentRefreshedStatusPayloadSchema, ShutdownRequestedStatusPayloadSchema, RestartRequestedStatusPayloadSchema, DaemonConfigChangedStatusPayloadSchema, ]); export type KnownStatusPayload = z.infer; export const ArtifactMessageSchema = z.object({ type: z.literal("artifact"), payload: z.object({ type: z.enum(["markdown", "diff", "image", "code"]), id: z.string(), title: z.string(), content: z.string(), isBase64: z.boolean(), }), }); export const ProjectCheckoutLiteNotGitPayloadSchema = z .object({ cwd: z.string(), isGit: z.literal(false), currentBranch: z.null(), remoteUrl: z.null(), worktreeRoot: z.null().optional(), isPaseoOwnedWorktree: z.literal(false), mainRepoRoot: z.null(), }) .transform((value) => ({ ...value, worktreeRoot: null, })); export const ProjectCheckoutLiteGitNonPaseoPayloadSchema = z .object({ cwd: z.string(), isGit: z.literal(true), currentBranch: z.string().nullable(), remoteUrl: z.string().nullable(), worktreeRoot: z.string().optional(), isPaseoOwnedWorktree: z.literal(false), mainRepoRoot: z.string().nullable().optional().default(null), }) .transform((value) => ({ ...value, worktreeRoot: value.worktreeRoot ?? value.cwd, })); export const ProjectCheckoutLiteGitPaseoPayloadSchema = z .object({ cwd: z.string(), isGit: z.literal(true), currentBranch: z.string().nullable(), remoteUrl: z.string().nullable(), worktreeRoot: z.string().optional(), isPaseoOwnedWorktree: z.literal(true), mainRepoRoot: z.string(), }) .transform((value) => ({ ...value, worktreeRoot: value.worktreeRoot ?? value.cwd, })); export const ProjectCheckoutLitePayloadSchema = z.union([ ProjectCheckoutLiteNotGitPayloadSchema, ProjectCheckoutLiteGitNonPaseoPayloadSchema, ProjectCheckoutLiteGitPaseoPayloadSchema, ]); export const ProjectPlacementPayloadSchema = z.object({ projectKey: z.string(), projectName: z.string(), checkout: ProjectCheckoutLitePayloadSchema, }); export const WorkspaceScriptLifecycleSchema = z.enum(["running", "stopped"]); export const WorkspaceScriptHealthSchema = z.enum(["healthy", "unhealthy"]); export const WorkspaceScriptPayloadSchema = z.object({ scriptName: z.string(), type: z.enum(["script", "service"]).optional().default("service"), hostname: z.string(), port: z.number().int().positive().nullable(), proxyUrl: z.string().nullable().optional().default(null), lifecycle: WorkspaceScriptLifecycleSchema, health: WorkspaceScriptHealthSchema.nullable(), exitCode: z.number().nullable().optional().default(null), terminalId: z.string().nullable().optional().default(null), }); const WorkspaceGitRuntimePayloadSchema = z .object({ currentBranch: z.string().nullable().optional(), remoteUrl: z.string().nullable().optional(), isPaseoOwnedWorktree: z.boolean().optional(), isDirty: z.boolean().nullable().optional(), aheadBehind: z .object({ ahead: z.number(), behind: z.number(), }) .nullable() .optional(), aheadOfOrigin: z.number().nullable().optional(), behindOfOrigin: z.number().nullable().optional(), }) .optional() .nullable(); const WorkspaceGitHubRuntimePayloadSchema = z .object({ featuresEnabled: z.boolean().optional(), pullRequest: z .object({ url: z.string(), title: z.string(), state: z.string(), baseRefName: z.string(), headRefName: z.string(), isMerged: z.boolean(), }) .nullable() .optional(), error: z .object({ message: z.string(), }) .nullable() .optional(), refreshedAt: z.string().nullable().optional(), }) .optional() .nullable(); export const WorkspaceDescriptorPayloadSchema = z .object({ id: z.string(), projectId: z.string(), projectDisplayName: z.string(), projectRootPath: z.string(), workspaceDirectory: z.string().optional(), projectKind: z.enum(["git", "non_git", "directory"]), // COMPAT(workspaces): keep legacy directory workspace kind parseable. workspaceKind: z.enum(["directory", "local_checkout", "checkout", "worktree"]), name: z.string(), archivingAt: z.string().nullable().optional().default(null), status: WorkspaceStateBucketSchema, activityAt: z.string().nullable(), diffStat: z .object({ additions: z.number(), deletions: z.number(), }) .nullable() .optional(), scripts: z.array(WorkspaceScriptPayloadSchema).default([]), gitRuntime: WorkspaceGitRuntimePayloadSchema, githubRuntime: WorkspaceGitHubRuntimePayloadSchema, project: ProjectPlacementPayloadSchema.optional(), }) .transform((workspace) => ({ ...workspace, workspaceDirectory: workspace.workspaceDirectory ?? workspace.projectRootPath, })); export const AgentUpdateMessageSchema = z.object({ type: z.literal("agent_update"), payload: z.discriminatedUnion("kind", [ z.object({ kind: z.literal("upsert"), agent: AgentSnapshotPayloadSchema, project: ProjectPlacementPayloadSchema.nullable().optional(), }), z.object({ kind: z.literal("remove"), agentId: z.string(), }), ]), }); export const AgentStreamMessageSchema = z.object({ type: z.literal("agent_stream"), payload: z.object({ agentId: z.string(), event: AgentStreamEventPayloadSchema, timestamp: z.string(), // Present for timeline events. Maps 1:1 to canonical in-memory timeline rows. seq: z.number().int().nonnegative().optional(), epoch: z.string().optional(), }), }); export const AgentStatusMessageSchema = z.object({ type: z.literal("agent_status"), payload: z.object({ agentId: z.string(), status: z.string(), info: AgentSnapshotPayloadSchema, }), }); export const AgentListMessageSchema = z.object({ type: z.literal("agent_list"), payload: z.object({ agents: z.array(AgentSnapshotPayloadSchema), }), }); const AgentDirectoryResponseEntrySchema = z.object({ agent: AgentSnapshotPayloadSchema, project: ProjectPlacementPayloadSchema, }); const AgentDirectoryPageInfoSchema = z.object({ nextCursor: z.string().nullable(), prevCursor: z.string().nullable(), hasMore: z.boolean(), }); export const FetchAgentsResponseMessageSchema = z.object({ type: z.literal("fetch_agents_response"), payload: z.object({ requestId: z.string(), subscriptionId: z.string().nullable().optional(), entries: z.array(AgentDirectoryResponseEntrySchema), pageInfo: AgentDirectoryPageInfoSchema, }), }); export const FetchAgentHistoryResponseMessageSchema = z.object({ type: z.literal("fetch_agent_history_response"), payload: z.object({ requestId: z.string(), entries: z.array(AgentDirectoryResponseEntrySchema), pageInfo: AgentDirectoryPageInfoSchema, }), }); export const FetchRecentProviderSessionsResponseMessageSchema = z.object({ type: z.literal("fetch_recent_provider_sessions_response"), payload: z.object({ requestId: z.string(), entries: z.array(RecentProviderSessionDescriptorPayloadSchema), filteredAlreadyImportedCount: z.number().int().nonnegative().optional(), }), }); export const FetchWorkspacesResponseMessageSchema = z.object({ type: z.literal("fetch_workspaces_response"), payload: z.object({ requestId: z.string(), subscriptionId: z.string().nullable().optional(), entries: z.array(WorkspaceDescriptorPayloadSchema), pageInfo: z.object({ nextCursor: z.string().nullable(), prevCursor: z.string().nullable(), hasMore: z.boolean(), }), }), }); export const WorkspaceUpdateMessageSchema = z.object({ type: z.literal("workspace_update"), payload: z.discriminatedUnion("kind", [ z.object({ kind: z.literal("upsert"), workspace: WorkspaceDescriptorPayloadSchema, }), z.object({ kind: z.literal("remove"), id: z.string(), }), ]), }); export const ScriptStatusUpdateMessageSchema = z.object({ type: z.literal("script_status_update"), payload: z.object({ workspaceId: z.string(), scripts: z.array(WorkspaceScriptPayloadSchema), }), }); export const WorkspaceSetupProgressMessageSchema = z.object({ type: z.literal("workspace_setup_progress"), payload: z.object({ workspaceId: z.string(), status: z.enum(["running", "completed", "failed"]), detail: WorktreeSetupDetailPayloadSchema, error: z.string().nullable(), }), }); export const WorkspaceSetupSnapshotSchema = z.object({ status: z.enum(["running", "completed", "failed"]), detail: WorktreeSetupDetailPayloadSchema, error: z.string().nullable(), }); export const WorkspaceSetupStatusResponseMessageSchema = z.object({ type: z.literal("workspace_setup_status_response"), payload: z.object({ requestId: z.string(), workspaceId: z.string(), snapshot: WorkspaceSetupSnapshotSchema.nullable(), }), }); export const OpenProjectResponseMessageSchema = z.object({ type: z.literal("open_project_response"), payload: z.object({ requestId: z.string(), workspace: WorkspaceDescriptorPayloadSchema.nullable(), error: z.string().nullable(), }), }); export const StartWorkspaceScriptResponseMessageSchema = z.object({ type: z.literal("start_workspace_script_response"), payload: z.object({ requestId: z.string(), workspaceId: z.string(), scriptName: z.string(), terminalId: z.string().nullable(), error: z.string().nullable(), }), }); export const ListAvailableEditorsResponseMessageSchema = z.object({ type: z.literal("list_available_editors_response"), payload: z.object({ requestId: z.string(), editors: z.array(EditorTargetDescriptorPayloadSchema), error: z.string().nullable(), }), }); export const OpenInEditorResponseMessageSchema = z.object({ type: z.literal("open_in_editor_response"), payload: z.object({ requestId: z.string(), error: z.string().nullable(), }), }); export const ArchiveWorkspaceResponseMessageSchema = z.object({ type: z.literal("archive_workspace_response"), payload: z.object({ requestId: z.string(), workspaceId: z.string(), archivedAt: z.string().nullable(), error: z.string().nullable(), }), }); export const FetchAgentResponseMessageSchema = z.object({ type: z.literal("fetch_agent_response"), payload: z.object({ requestId: z.string(), agent: AgentSnapshotPayloadSchema.nullable(), project: ProjectPlacementPayloadSchema.nullable().optional(), error: z.string().nullable(), }), }); const AgentTimelineSeqRangeSchema = z.object({ startSeq: z.number().int().nonnegative(), endSeq: z.number().int().nonnegative(), }); export const AgentTimelineEntryPayloadSchema = z.object({ provider: AgentProviderSchema, item: AgentTimelineItemPayloadSchema, timestamp: z.string(), seqStart: z.number().int().nonnegative(), seqEnd: z.number().int().nonnegative(), sourceSeqRanges: z.array(AgentTimelineSeqRangeSchema), collapsed: z.array(z.enum(["assistant_merge", "reasoning_merge", "tool_lifecycle"])), }); export const FetchAgentTimelineResponseMessageSchema = z.object({ type: z.literal("fetch_agent_timeline_response"), payload: z.object({ requestId: z.string(), agentId: z.string(), agent: AgentSnapshotPayloadSchema.nullable(), direction: z.enum(["tail", "before", "after"]), projection: z.enum(["projected", "canonical"]), epoch: z.string(), reset: z.boolean(), staleCursor: z.boolean(), gap: z.boolean(), window: z.object({ minSeq: z.number().int().nonnegative(), maxSeq: z.number().int().nonnegative(), nextSeq: z.number().int().nonnegative(), }), startCursor: AgentTimelineCursorSchema.nullable(), endCursor: AgentTimelineCursorSchema.nullable(), hasOlder: z.boolean(), hasNewer: z.boolean(), entries: z.array(AgentTimelineEntryPayloadSchema), error: z.string().nullable(), }), }); export const CancelAgentResponseMessageSchema = z.object({ type: z.literal("cancel_agent_response"), payload: z.object({ requestId: z.string(), agentId: z.string(), agent: AgentSnapshotPayloadSchema.nullable(), }), }); export const ClearAgentAttentionResponseMessageSchema = z.object({ type: z.literal("clear_agent_attention_response"), payload: z.object({ requestId: z.string(), agentId: z.string().or(z.array(z.string())), agents: z.array(AgentSnapshotPayloadSchema), }), }); export const SendAgentMessageResponseMessageSchema = z.object({ type: z.literal("send_agent_message_response"), payload: z.object({ requestId: z.string(), agentId: z.string(), accepted: z.boolean(), error: z.string().nullable(), }), }); export const WaitForFinishResponseMessageSchema = z.object({ type: z.literal("wait_for_finish_response"), payload: z.object({ requestId: z.string(), status: z.enum(["idle", "error", "permission", "timeout"]), final: AgentSnapshotPayloadSchema.nullable(), error: z.string().nullable(), lastMessage: z.string().nullable(), }), }); export const GetDaemonConfigResponseMessageSchema = z.object({ type: z.literal("get_daemon_config_response"), payload: z .object({ requestId: z.string(), config: MutableDaemonConfigSchema, }) .passthrough(), }); export const SetDaemonConfigResponseMessageSchema = z.object({ type: z.literal("set_daemon_config_response"), payload: z .object({ requestId: z.string(), config: MutableDaemonConfigSchema, }) .passthrough(), }); export const ReadProjectConfigResponseMessageSchema = z.object({ type: z.literal("read_project_config_response"), payload: z.discriminatedUnion("ok", [ z.object({ requestId: z.string(), repoRoot: z.string(), ok: z.literal(true), config: PaseoConfigRawSchema.nullable(), revision: PaseoConfigRevisionSchema.nullable(), }), z.object({ requestId: z.string(), repoRoot: z.string(), ok: z.literal(false), error: ProjectConfigRpcErrorSchema, }), ]), }); export const WriteProjectConfigResponseMessageSchema = z.object({ type: z.literal("write_project_config_response"), payload: z.discriminatedUnion("ok", [ z.object({ requestId: z.string(), repoRoot: z.string(), ok: z.literal(true), config: PaseoConfigRawSchema, revision: PaseoConfigRevisionSchema, }), z.object({ requestId: z.string(), repoRoot: z.string(), ok: z.literal(false), error: ProjectConfigRpcErrorSchema, }), ]), }); export const AgentPermissionRequestMessageSchema = z.object({ type: z.literal("agent_permission_request"), payload: z.object({ agentId: z.string(), request: AgentPermissionRequestPayloadSchema, }), }); export const AgentPermissionResolvedMessageSchema = z.object({ type: z.literal("agent_permission_resolved"), payload: z.object({ agentId: z.string(), requestId: z.string(), resolution: AgentPermissionResponseSchema, }), }); export const AgentDeletedMessageSchema = z.object({ type: z.literal("agent_deleted"), payload: z.object({ agentId: z.string(), requestId: z.string(), }), }); export const AgentArchivedMessageSchema = z.object({ type: z.literal("agent_archived"), payload: z.object({ agentId: z.string(), archivedAt: z.string(), requestId: z.string(), }), }); const CloseItemsAgentResultSchema = z.object({ agentId: z.string(), archivedAt: z.string(), }); const CloseItemsTerminalResultSchema = z.object({ terminalId: z.string(), success: z.boolean(), }); export const CloseItemsResponseSchema = z.object({ type: z.literal("close_items_response"), payload: z.object({ agents: z.array(CloseItemsAgentResultSchema), terminals: z.array(CloseItemsTerminalResultSchema), requestId: z.string(), }), }); const AheadBehindSchema = z.object({ ahead: z.number(), behind: z.number(), }); const CheckoutStatusCommonSchema = z.object({ cwd: z.string(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }); const CheckoutStatusNotGitSchema = CheckoutStatusCommonSchema.extend({ isGit: z.literal(false), isPaseoOwnedWorktree: z.literal(false), repoRoot: z.null(), currentBranch: z.null(), isDirty: z.null(), baseRef: z.null(), aheadBehind: z.null(), aheadOfOrigin: z.null(), behindOfOrigin: z.null(), hasRemote: z.boolean(), remoteUrl: z.null(), }); const CheckoutStatusGitNonPaseoSchema = CheckoutStatusCommonSchema.extend({ isGit: z.literal(true), isPaseoOwnedWorktree: z.literal(false), repoRoot: z.string(), mainRepoRoot: z.string().nullable().optional().default(null), currentBranch: z.string().nullable(), isDirty: z.boolean(), baseRef: z.string().nullable(), aheadBehind: AheadBehindSchema.nullable(), aheadOfOrigin: z.number().nullable(), behindOfOrigin: z.number().nullable(), hasRemote: z.boolean(), remoteUrl: z.string().nullable(), }); const CheckoutStatusGitPaseoSchema = CheckoutStatusCommonSchema.extend({ isGit: z.literal(true), isPaseoOwnedWorktree: z.literal(true), repoRoot: z.string(), mainRepoRoot: z.string(), currentBranch: z.string().nullable(), isDirty: z.boolean(), baseRef: z.string(), aheadBehind: AheadBehindSchema.nullable(), aheadOfOrigin: z.number().nullable(), behindOfOrigin: z.number().nullable(), hasRemote: z.boolean(), remoteUrl: z.string().nullable(), }); export const CheckoutStatusResponseSchema = z.object({ type: z.literal("checkout_status_response"), payload: z.union([ CheckoutStatusNotGitSchema, CheckoutStatusGitNonPaseoSchema, CheckoutStatusGitPaseoSchema, ]), }); export const CheckoutPrStatusSchema = z.object({ number: z.number().optional(), url: z.string(), title: z.string(), state: z.string(), baseRefName: z.string(), headRefName: z.string(), isMerged: z.boolean(), isDraft: z.boolean().optional().default(false), mergeable: z .enum(["MERGEABLE", "CONFLICTING", "UNKNOWN"]) .catch("UNKNOWN") .optional() .default("UNKNOWN"), checks: z .array( z.object({ name: z.string(), status: z.string(), url: z.string().nullable(), workflow: z.string().optional(), duration: z.string().optional(), }), ) .optional() .default([]), checksStatus: z.string().optional(), reviewDecision: z.string().nullable().optional(), repoOwner: z.string().optional(), repoName: z.string().optional(), }); const CheckoutPrStatusPayloadSchema = z.object({ cwd: z.string(), status: CheckoutPrStatusSchema.nullable(), githubFeaturesEnabled: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }); const CheckoutStatusUpdateMetadataSchema = z.object({ prStatus: CheckoutPrStatusPayloadSchema.optional(), }); export const CheckoutStatusUpdateSchema = z.object({ type: z.literal("checkout_status_update"), payload: z .union([ CheckoutStatusNotGitSchema, CheckoutStatusGitNonPaseoSchema, CheckoutStatusGitPaseoSchema, ]) .and(CheckoutStatusUpdateMetadataSchema), }); const CheckoutDiffSubscriptionPayloadSchema = z.object({ subscriptionId: z.string(), cwd: z.string(), files: z.array(ParsedDiffFileSchema), error: CheckoutErrorSchema.nullable(), }); export const SubscribeCheckoutDiffResponseSchema = z.object({ type: z.literal("subscribe_checkout_diff_response"), payload: CheckoutDiffSubscriptionPayloadSchema.extend({ requestId: z.string(), }), }); export const CheckoutDiffUpdateSchema = z.object({ type: z.literal("checkout_diff_update"), payload: CheckoutDiffSubscriptionPayloadSchema, }); export const CheckoutCommitResponseSchema = z.object({ type: z.literal("checkout_commit_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutMergeResponseSchema = z.object({ type: z.literal("checkout_merge_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutMergeFromBaseResponseSchema = z.object({ type: z.literal("checkout_merge_from_base_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutPullResponseSchema = z.object({ type: z.literal("checkout_pull_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutPushResponseSchema = z.object({ type: z.literal("checkout_push_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutPrCreateResponseSchema = z.object({ type: z.literal("checkout_pr_create_response"), payload: z.object({ cwd: z.string(), url: z.string().nullable(), number: z.number().nullable(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutPrMergeResponseSchema = z.object({ type: z.literal("checkout_pr_merge_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CheckoutPrStatusResponseSchema = z.object({ type: z.literal("checkout_pr_status_response"), payload: CheckoutPrStatusPayloadSchema, }); const PullRequestTimelineKnownErrorSchema = z.discriminatedUnion("kind", [ z.object({ kind: z.literal("not_found"), message: z.string().optional().default(""), }), z.object({ kind: z.literal("forbidden"), message: z.string().optional().default(""), }), z.object({ kind: z.literal("unknown"), message: z.string().optional().default(""), }), ]); const PullRequestTimelineErrorSchema = z.preprocess((value) => { if (!value || typeof value !== "object" || Array.isArray(value)) { return { kind: "unknown", message: "" }; } const error = value as Record; if (error.kind === "not_found" || error.kind === "forbidden" || error.kind === "unknown") { return error; } return { ...error, kind: "unknown" }; }, PullRequestTimelineKnownErrorSchema); const PullRequestTimelineReviewItemSchema = z.object({ id: z.string().optional().default(""), kind: z.literal("review"), author: z.string().optional().default("unknown"), body: z.string().optional().default(""), createdAt: z.number().optional().default(0), url: z.string().optional().default(""), reviewState: z .enum(["approved", "changes_requested", "commented"]) .optional() .default("commented"), }); const PullRequestTimelineCommentItemSchema = z.object({ id: z.string().optional().default(""), kind: z.literal("comment"), author: z.string().optional().default("unknown"), body: z.string().optional().default(""), createdAt: z.number().optional().default(0), url: z.string().optional().default(""), }); export const PullRequestTimelineItemSchema = z.preprocess( (value) => { if (!value || typeof value !== "object" || Array.isArray(value)) { return value; } const item = value as Record; if (item.kind === "review" || item.kind === "comment") { return item; } return { ...item, kind: "comment" }; }, z.discriminatedUnion("kind", [ PullRequestTimelineReviewItemSchema, PullRequestTimelineCommentItemSchema, ]), ); export const PullRequestTimelineResponseSchema = z.object({ type: z.literal("pull_request_timeline_response"), payload: z .object({ cwd: z.string().optional().default(""), prNumber: z.number().nullable().optional().default(null), items: z.array(PullRequestTimelineItemSchema).optional().default([]), truncated: z.boolean().optional().default(false), error: PullRequestTimelineErrorSchema.nullable().optional().default(null), requestId: z.string().optional().default(""), githubFeaturesEnabled: z.boolean().optional().default(true), }) .optional() .default({}), }); export const CheckoutSwitchBranchResponseSchema = z.object({ type: z.literal("checkout_switch_branch_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), branch: z.string(), source: z.enum(["local", "remote"]).optional(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); const StashEntrySchema = z.object({ index: z.number().int().min(0), message: z.string(), branch: z.string().nullable(), isPaseo: z.boolean(), }); export const StashSaveResponseSchema = z.object({ type: z.literal("stash_save_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const StashPopResponseSchema = z.object({ type: z.literal("stash_pop_response"), payload: z.object({ cwd: z.string(), success: z.boolean(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const StashListResponseSchema = z.object({ type: z.literal("stash_list_response"), payload: z.object({ cwd: z.string(), entries: z.array(StashEntrySchema), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const ValidateBranchResponseSchema = z.object({ type: z.literal("validate_branch_response"), payload: z.object({ exists: z.boolean(), resolvedRef: z.string().nullable(), isRemote: z.boolean(), error: z.string().nullable(), requestId: z.string(), }), }); export const BranchSuggestionsResponseSchema = z.object({ type: z.literal("branch_suggestions_response"), payload: z.object({ branches: z.array(z.string()), branchDetails: z .array( z.object({ name: z.string(), committerDate: z.number(), hasLocal: z.boolean().optional(), hasRemote: z.boolean().optional(), }), ) .optional(), error: z.string().nullable(), requestId: z.string(), }), }); export const GitHubSearchResponseSchema = z.object({ type: z.literal("github_search_response"), payload: z.object({ items: z.array(GitHubSearchItemSchema), githubFeaturesEnabled: z.boolean(), error: z.string().nullable(), requestId: z.string(), }), }); export const DirectorySuggestionsResponseSchema = z.object({ type: z.literal("directory_suggestions_response"), payload: z.object({ directories: z.array(z.string()), entries: z .array( z.object({ path: z.string(), kind: z.enum(["file", "directory"]), }), ) .optional() .default([]), error: z.string().nullable(), requestId: z.string(), }), }); const PaseoWorktreeSchema = z.object({ worktreePath: z.string(), createdAt: z.string(), branchName: z.string().nullable().optional(), head: z.string().nullable().optional(), }); export const PaseoWorktreeListResponseSchema = z.object({ type: z.literal("paseo_worktree_list_response"), payload: z.object({ worktrees: z.array(PaseoWorktreeSchema), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const PaseoWorktreeArchiveResponseSchema = z.object({ type: z.literal("paseo_worktree_archive_response"), payload: z.object({ success: z.boolean(), removedAgents: z.array(z.string()).optional(), error: CheckoutErrorSchema.nullable(), requestId: z.string(), }), }); export const CreatePaseoWorktreeResponseSchema = z.object({ type: z.literal("create_paseo_worktree_response"), payload: z.object({ workspace: WorkspaceDescriptorPayloadSchema.nullable(), error: z.string().nullable(), errorCode: z.string().optional(), setupTerminalId: z.string().nullable(), requestId: z.string(), }), }); export const FileExplorerResponseSchema = z.object({ type: z.literal("file_explorer_response"), payload: z.object({ cwd: z.string(), path: z.string(), mode: z.enum(["list", "file"]), directory: FileExplorerDirectorySchema.nullable(), file: FileExplorerFileSchema.nullable(), error: z.string().nullable(), requestId: z.string(), }), }); const ProjectIconSchema = z.object({ data: z.string(), mimeType: z.string(), }); export const ProjectIconResponseSchema = z.object({ type: z.literal("project_icon_response"), payload: z.object({ cwd: z.string(), icon: ProjectIconSchema.nullable(), error: z.string().nullable(), requestId: z.string(), }), }); export const FileDownloadTokenResponseSchema = z.object({ type: z.literal("file_download_token_response"), payload: z.object({ cwd: z.string(), path: z.string(), token: z.string().nullable(), fileName: z.string().nullable(), mimeType: z.string().nullable(), size: z.number().nullable(), error: z.string().nullable(), requestId: z.string(), }), }); export const ListProviderModelsResponseMessageSchema = z.object({ type: z.literal("list_provider_models_response"), payload: z.object({ provider: AgentProviderSchema, models: z.array(AgentModelDefinitionSchema).optional(), error: z.string().nullable().optional(), fetchedAt: z.string(), requestId: z.string(), }), }); export const ListProviderModesResponseMessageSchema = z.object({ type: z.literal("list_provider_modes_response"), payload: z.object({ provider: AgentProviderSchema, modes: z.array(AgentModeSchema).optional(), error: z.string().nullable().optional(), fetchedAt: z.string(), requestId: z.string(), }), }); export const ListProviderFeaturesResponseMessageSchema = z.object({ type: z.literal("list_provider_features_response"), payload: z.object({ provider: AgentProviderSchema, features: z.array(AgentFeatureSchema).optional(), error: z.string().nullable().optional(), fetchedAt: z.string(), requestId: z.string(), }), }); const ProviderAvailabilitySchema = z.object({ provider: AgentProviderSchema, available: z.boolean(), error: z.string().nullable().optional(), }); export const ListAvailableProvidersResponseSchema = z.object({ type: z.literal("list_available_providers_response"), payload: z.object({ providers: z.array(ProviderAvailabilitySchema), error: z.string().nullable().optional(), fetchedAt: z.string(), requestId: z.string(), }), }); // COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot export const GetProvidersSnapshotResponseMessageSchema = z.object({ type: z.literal("get_providers_snapshot_response"), payload: z.object({ entries: z.array(ProviderSnapshotEntrySchema), generatedAt: z.string(), requestId: z.string(), }), }); // COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot export const ProvidersSnapshotUpdateMessageSchema = z.object({ type: z.literal("providers_snapshot_update"), payload: z.object({ cwd: z.string().optional(), entries: z.array(ProviderSnapshotEntrySchema), generatedAt: z.string(), }), }); // COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot export const RefreshProvidersSnapshotResponseMessageSchema = z.object({ type: z.literal("refresh_providers_snapshot_response"), payload: z.object({ requestId: z.string(), acknowledged: z.boolean(), }), }); // COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot export const ProviderDiagnosticResponseMessageSchema = z.object({ type: z.literal("provider_diagnostic_response"), payload: z.object({ provider: AgentProviderSchema, diagnostic: z.string(), requestId: z.string(), }), }); const AgentSlashCommandSchema = z.object({ name: z.string(), description: z.string(), argumentHint: z.string(), }); export const ListCommandsResponseSchema = z.object({ type: z.literal("list_commands_response"), payload: z.object({ agentId: z.string(), commands: z.array(AgentSlashCommandSchema), error: z.string().nullable(), requestId: z.string(), }), }); // ============================================================================ // Terminal Outbound Messages // ============================================================================ const TerminalInfoSchema = z.object({ id: z.string(), name: z.string(), cwd: z.string(), title: z.string().optional(), }); export const TerminalCellSchema = z .object({ char: z.string(), fg: z.number().optional(), bg: z.number().optional(), fgMode: z.number().optional(), bgMode: z.number().optional(), bold: z.boolean().optional(), italic: z.boolean().optional(), underline: z.boolean().optional(), dim: z.boolean().optional(), inverse: z.boolean().optional(), strikethrough: z.boolean().optional(), }) .strict(); export const TerminalCursorStyleSchema = z.enum(["block", "underline", "bar"]); export const TerminalCursorSchema = z .object({ row: z.number(), col: z.number(), hidden: z.boolean().optional(), style: TerminalCursorStyleSchema.optional(), blink: z.boolean().optional(), }) .strict(); export const TerminalStateSchema = z .object({ rows: z.number(), cols: z.number(), grid: z.array(z.array(TerminalCellSchema)), scrollback: z.array(z.array(TerminalCellSchema)), cursor: TerminalCursorSchema, title: z.string().optional(), }) .strict(); export const ListTerminalsResponseSchema = z.object({ type: z.literal("list_terminals_response"), payload: z.object({ cwd: z.string().optional(), terminals: z.array(TerminalInfoSchema.omit({ cwd: true })), requestId: z.string(), }), }); export const TerminalsChangedSchema = z.object({ type: z.literal("terminals_changed"), payload: z.object({ cwd: z.string(), terminals: z.array(TerminalInfoSchema.omit({ cwd: true })), }), }); export const CreateTerminalResponseSchema = z.object({ type: z.literal("create_terminal_response"), payload: z.object({ terminal: TerminalInfoSchema.nullable(), error: z.string().nullable(), requestId: z.string(), }), }); export const SubscribeTerminalResponseSchema = z.object({ type: z.literal("subscribe_terminal_response"), payload: z.union([ z.object({ terminalId: z.string(), slot: z.number().int().min(0).max(255), error: z.null(), requestId: z.string(), }), z.object({ terminalId: z.string(), error: z.string(), requestId: z.string(), }), ]), }); export const KillTerminalResponseSchema = z.object({ type: z.literal("kill_terminal_response"), payload: z.object({ terminalId: z.string(), success: z.boolean(), requestId: z.string(), }), }); export const CaptureTerminalResponseSchema = z.object({ type: z.literal("capture_terminal_response"), payload: z.object({ terminalId: z.string(), lines: z.array(z.string()), totalLines: z.number().int().nonnegative(), requestId: z.string(), }), }); export const TerminalStreamExitSchema = z.object({ type: z.literal("terminal_stream_exit"), payload: z.object({ terminalId: z.string(), }), }); export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [ ActivityLogMessageSchema, AssistantChunkMessageSchema, AudioOutputMessageSchema, TranscriptionResultMessageSchema, VoiceInputStateMessageSchema, DictationStreamAckMessageSchema, DictationStreamFinishAcceptedMessageSchema, DictationStreamPartialMessageSchema, DictationStreamFinalMessageSchema, DictationStreamErrorMessageSchema, StatusMessageSchema, PongMessageSchema, RpcErrorMessageSchema, ArtifactMessageSchema, AgentUpdateMessageSchema, WorkspaceUpdateMessageSchema, ScriptStatusUpdateMessageSchema, WorkspaceSetupProgressMessageSchema, WorkspaceSetupStatusResponseMessageSchema, AgentStreamMessageSchema, AgentStatusMessageSchema, FetchAgentsResponseMessageSchema, FetchAgentHistoryResponseMessageSchema, FetchRecentProviderSessionsResponseMessageSchema, FetchWorkspacesResponseMessageSchema, OpenProjectResponseMessageSchema, StartWorkspaceScriptResponseMessageSchema, ListAvailableEditorsResponseMessageSchema, OpenInEditorResponseMessageSchema, ArchiveWorkspaceResponseMessageSchema, FetchAgentResponseMessageSchema, FetchAgentTimelineResponseMessageSchema, CancelAgentResponseMessageSchema, ClearAgentAttentionResponseMessageSchema, SendAgentMessageResponseMessageSchema, SetVoiceModeResponseMessageSchema, GetDaemonConfigResponseMessageSchema, SetDaemonConfigResponseMessageSchema, ReadProjectConfigResponseMessageSchema, WriteProjectConfigResponseMessageSchema, SetAgentModeResponseMessageSchema, SetAgentModelResponseMessageSchema, SetAgentThinkingResponseMessageSchema, SetAgentFeatureResponseMessageSchema, UpdateAgentResponseMessageSchema, WaitForFinishResponseMessageSchema, AgentPermissionRequestMessageSchema, AgentPermissionResolvedMessageSchema, AgentDeletedMessageSchema, AgentArchivedMessageSchema, CloseItemsResponseSchema, CheckoutStatusResponseSchema, CheckoutStatusUpdateSchema, SubscribeCheckoutDiffResponseSchema, CheckoutDiffUpdateSchema, CheckoutCommitResponseSchema, CheckoutMergeResponseSchema, CheckoutMergeFromBaseResponseSchema, CheckoutPullResponseSchema, CheckoutPushResponseSchema, CheckoutPrCreateResponseSchema, CheckoutPrMergeResponseSchema, CheckoutPrStatusResponseSchema, PullRequestTimelineResponseSchema, CheckoutSwitchBranchResponseSchema, StashSaveResponseSchema, StashPopResponseSchema, StashListResponseSchema, ValidateBranchResponseSchema, BranchSuggestionsResponseSchema, GitHubSearchResponseSchema, DirectorySuggestionsResponseSchema, PaseoWorktreeListResponseSchema, PaseoWorktreeArchiveResponseSchema, CreatePaseoWorktreeResponseSchema, FileExplorerResponseSchema, ProjectIconResponseSchema, FileDownloadTokenResponseSchema, ListProviderModelsResponseMessageSchema, ListProviderModesResponseMessageSchema, ListProviderFeaturesResponseMessageSchema, ListAvailableProvidersResponseSchema, GetProvidersSnapshotResponseMessageSchema, ProvidersSnapshotUpdateMessageSchema, RefreshProvidersSnapshotResponseMessageSchema, ProviderDiagnosticResponseMessageSchema, ListCommandsResponseSchema, ListTerminalsResponseSchema, TerminalsChangedSchema, CreateTerminalResponseSchema, SubscribeTerminalResponseSchema, KillTerminalResponseSchema, CaptureTerminalResponseSchema, TerminalStreamExitSchema, ChatCreateResponseSchema, ChatListResponseSchema, ChatInspectResponseSchema, ChatDeleteResponseSchema, ChatPostResponseSchema, ChatReadResponseSchema, ChatWaitResponseSchema, ScheduleCreateResponseSchema, ScheduleListResponseSchema, ScheduleInspectResponseSchema, ScheduleLogsResponseSchema, SchedulePauseResponseSchema, ScheduleResumeResponseSchema, ScheduleDeleteResponseSchema, ScheduleRunOnceResponseSchema, ScheduleUpdateResponseSchema, LoopRunResponseSchema, LoopListResponseSchema, LoopInspectResponseSchema, LoopLogsResponseSchema, LoopStopResponseSchema, ]); export type SessionOutboundMessage = z.infer; // Type exports for individual message types export type ActivityLogMessage = z.infer; export type AssistantChunkMessage = z.infer; export type AudioOutputMessage = z.infer; export type TranscriptionResultMessage = z.infer; export type StatusMessage = z.infer; export type ServerCapabilityState = z.infer; export type ServerVoiceCapabilities = z.infer; export type ServerCapabilities = z.infer; export type ServerInfoStatusPayload = z.infer; export type RpcErrorMessage = z.infer; export type ArtifactMessage = z.infer; export type AgentUpdateMessage = z.infer; export type WorkspaceSetupProgressMessage = z.infer; export type WorkspaceSetupSnapshot = z.infer; export type WorkspaceSetupStatusResponseMessage = z.infer< typeof WorkspaceSetupStatusResponseMessageSchema >; export type AgentStreamMessage = z.infer; export type AgentStatusMessage = z.infer; export type ProjectCheckoutLitePayload = z.infer; export type ProjectPlacementPayload = z.infer; export type WorkspaceStateBucket = z.infer; export type WorkspaceDescriptorPayload = z.infer; export type WorkspaceScriptLifecycle = z.infer; export type WorkspaceScriptHealth = z.infer; export type WorkspaceScriptPayload = z.infer; export type KnownEditorTargetId = z.infer; export type LegacyEditorTargetId = z.infer; export type EditorTargetId = LiteralUnion; export type EditorTargetDescriptorPayload = z.infer; export type FetchAgentsResponseMessage = z.infer; export type FetchAgentHistoryResponseMessage = z.infer< typeof FetchAgentHistoryResponseMessageSchema >; export type FetchRecentProviderSessionsResponseMessage = z.infer< typeof FetchRecentProviderSessionsResponseMessageSchema >; export type FetchWorkspacesResponseMessage = z.infer; export type ScriptStatusUpdateMessage = z.infer; export type OpenProjectResponseMessage = z.infer; export type StartWorkspaceScriptResponseMessage = z.infer< typeof StartWorkspaceScriptResponseMessageSchema >; export type ListAvailableEditorsResponseMessage = z.infer< typeof ListAvailableEditorsResponseMessageSchema >; export type OpenInEditorResponseMessage = z.infer; export type ArchiveWorkspaceResponseMessage = z.infer; export type FetchAgentResponseMessage = z.infer; export type FetchAgentTimelineResponseMessage = z.infer< typeof FetchAgentTimelineResponseMessageSchema >; export type CancelAgentResponseMessage = z.infer; export type SendAgentMessageResponseMessage = z.infer; export type SetVoiceModeResponseMessage = z.infer; export type SetAgentModeResponseMessage = z.infer; export type SetAgentModelResponseMessage = z.infer; export type SetAgentThinkingResponseMessage = z.infer; export type SetAgentFeatureResponseMessage = z.infer; export type UpdateAgentResponseMessage = z.infer; export type WaitForFinishResponseMessage = z.infer; export type AgentPermissionRequestMessage = z.infer; export type AgentPermissionResolvedMessage = z.infer; export type AgentDeletedMessage = z.infer; export type ListProviderModelsResponseMessage = z.infer< typeof ListProviderModelsResponseMessageSchema >; export type ListProviderModesResponseMessage = z.infer< typeof ListProviderModesResponseMessageSchema >; export type ListProviderFeaturesResponseMessage = z.infer< typeof ListProviderFeaturesResponseMessageSchema >; export type ListAvailableProvidersResponse = z.infer; export type GetProvidersSnapshotResponseMessage = z.infer< typeof GetProvidersSnapshotResponseMessageSchema >; export type ProvidersSnapshotUpdateMessage = z.infer; export type RefreshProvidersSnapshotResponseMessage = z.infer< typeof RefreshProvidersSnapshotResponseMessageSchema >; export type ProviderDiagnosticResponseMessage = z.infer< typeof ProviderDiagnosticResponseMessageSchema >; export type ChatCreateResponse = z.infer; export type ChatListResponse = z.infer; export type ChatInspectResponse = z.infer; export type ChatDeleteResponse = z.infer; export type ChatPostResponse = z.infer; export type ChatReadResponse = z.infer; export type ChatWaitResponse = z.infer; export type ScheduleCreateResponse = z.infer; export type ScheduleListResponse = z.infer; export type ScheduleInspectResponse = z.infer; export type ScheduleLogsResponse = z.infer; export type SchedulePauseResponse = z.infer; export type ScheduleResumeResponse = z.infer; export type ScheduleDeleteResponse = z.infer; export type ScheduleRunOnceResponse = z.infer; export type ScheduleUpdateResponse = z.infer; export type LoopRunResponse = z.infer; export type LoopListResponse = z.infer; export type LoopInspectResponse = z.infer; export type LoopLogsResponse = z.infer; export type LoopStopResponse = z.infer; // Type exports for payload types export type ActivityLogPayload = z.infer; // Type exports for inbound message types export type VoiceAudioChunkMessage = z.infer; export type FetchAgentsRequestMessage = z.infer; export type FetchAgentHistoryRequestMessage = z.infer; export type FetchRecentProviderSessionsRequestMessage = z.infer< typeof FetchRecentProviderSessionsRequestMessageSchema >; export type FetchWorkspacesRequestMessage = z.infer; export type FetchAgentRequestMessage = z.infer; export type SendAgentMessageRequest = z.infer; export type WaitForFinishRequest = z.infer; export type DictationStreamStartMessage = z.infer; export type DictationStreamChunkMessage = z.infer; export type DictationStreamFinishMessage = z.infer; export type DictationStreamCancelMessage = z.infer; export type CreateAgentRequestMessage = z.infer; export type AgentAttachment = z.infer; export type FirstAgentContext = z.infer; export type ReviewAttachment = z.infer; export type ListProviderModelsRequestMessage = z.infer< typeof ListProviderModelsRequestMessageSchema >; export type ListProviderModesRequestMessage = z.infer; export type ListProviderFeaturesRequestMessage = z.infer< typeof ListProviderFeaturesRequestMessageSchema >; export type ListAvailableProvidersRequestMessage = z.infer< typeof ListAvailableProvidersRequestMessageSchema >; export type GetProvidersSnapshotRequestMessage = z.infer< typeof GetProvidersSnapshotRequestMessageSchema >; export type RefreshProvidersSnapshotRequestMessage = z.infer< typeof RefreshProvidersSnapshotRequestMessageSchema >; export type ProviderDiagnosticRequestMessage = z.infer< typeof ProviderDiagnosticRequestMessageSchema >; export type ChatCreateRequest = z.infer; export type ChatListRequest = z.infer; export type ChatInspectRequest = z.infer; export type ChatDeleteRequest = z.infer; export type ChatPostRequest = z.infer; export type ChatReadRequest = z.infer; export type ChatWaitRequest = z.infer; export type ScheduleCreateRequest = z.infer; export type ScheduleListRequest = z.infer; export type ScheduleInspectRequest = z.infer; export type ScheduleLogsRequest = z.infer; export type SchedulePauseRequest = z.infer; export type ScheduleResumeRequest = z.infer; export type ScheduleDeleteRequest = z.infer; export type ScheduleRunOnceRequest = z.infer; export type ScheduleUpdateRequest = z.infer; export type LoopRunRequest = z.infer; export type LoopListRequest = z.infer; export type LoopInspectRequest = z.infer; export type LoopLogsRequest = z.infer; export type LoopStopRequest = z.infer; export type ResumeAgentRequestMessage = z.infer; export type DeleteAgentRequestMessage = z.infer; export type UpdateAgentRequestMessage = z.infer; export type SetAgentModeRequestMessage = z.infer; export type SetAgentModelRequestMessage = z.infer; export type SetAgentThinkingRequestMessage = z.infer; export type SetAgentFeatureRequestMessage = z.infer; export type AgentPermissionResponseMessage = z.infer; export type CheckoutStatusRequest = z.infer; export type CheckoutStatusResponse = z.infer; export type CheckoutStatusUpdate = z.infer; export type SubscribeCheckoutDiffRequest = z.infer; export type UnsubscribeCheckoutDiffRequest = z.infer; export type SubscribeCheckoutDiffResponse = z.infer; export type CheckoutDiffUpdate = z.infer; export type CheckoutCommitRequest = z.infer; export type CheckoutCommitResponse = z.infer; export type CheckoutMergeRequest = z.infer; export type CheckoutMergeResponse = z.infer; export type CheckoutMergeFromBaseRequest = z.infer; export type CheckoutMergeFromBaseResponse = z.infer; export type CheckoutPullRequest = z.infer; export type CheckoutPullResponse = z.infer; export type CheckoutPushRequest = z.infer; export type CheckoutPushResponse = z.infer; export type CheckoutPrCreateRequest = z.infer; export type CheckoutPrCreateResponse = z.infer; export type CheckoutPrMergeRequest = z.infer; export type CheckoutPrMergeResponse = z.infer; export type CheckoutPrMergeMethod = z.infer["mergeMethod"]; export type PullRequestMergeable = z.infer["mergeable"]; export type CheckoutPrStatusRequest = z.infer; export type CheckoutPrStatusResponse = z.infer; export type PullRequestTimelineRequest = z.infer; export type PullRequestTimelineItem = z.infer; export type PullRequestTimelineResponse = z.infer; export type CheckoutSwitchBranchRequest = z.infer; export type CheckoutSwitchBranchResponse = z.infer; export type StashSaveRequest = z.infer; export type StashSaveResponse = z.infer; export type StashPopRequest = z.infer; export type StashPopResponse = z.infer; export type StashListRequest = z.infer; export type StashListResponse = z.infer; export type StashEntry = z.infer; export type ValidateBranchRequest = z.infer; export type ValidateBranchResponse = z.infer; export type BranchSuggestionsRequest = z.infer; export type BranchSuggestionsResponse = z.infer; export type GitHubSearchItem = z.infer; export type GitHubSearchKind = z.infer; export type GitHubSearchRequest = z.infer; export type GitHubSearchResponse = z.infer; export type CreatePaseoWorktreeRequest = z.infer; export type DirectorySuggestionsRequest = z.infer; export type DirectorySuggestionsResponse = z.infer; export type PaseoWorktreeListRequest = z.infer; export type PaseoWorktreeListResponse = z.infer; export type PaseoWorktreeArchiveRequest = z.infer; export type PaseoWorktreeArchiveResponse = z.infer; export type WorkspaceSetupStatusRequest = z.infer; export type ListAvailableEditorsRequest = z.infer; export type OpenInEditorRequest = z.infer; export type OpenProjectRequest = z.infer; export type ArchiveWorkspaceRequest = z.infer; export type FileExplorerRequest = z.infer; export type FileExplorerResponse = z.infer; export type ProjectIconRequest = z.infer; export type ProjectIconResponse = z.infer; export type ProjectIcon = z.infer; export type FileDownloadTokenRequest = z.infer; export type FileDownloadTokenResponse = z.infer; export type RestartServerRequestMessage = z.infer; export type ShutdownServerRequestMessage = z.infer; export type ClearAgentAttentionMessage = z.infer; export type ClearAgentAttentionResponseMessage = z.infer< typeof ClearAgentAttentionResponseMessageSchema >; export type ClientHeartbeatMessage = z.infer; export type ListCommandsRequest = z.infer; export type ListCommandsResponse = z.infer; export type RegisterPushTokenMessage = z.infer; // Terminal message types export type ListTerminalsRequest = z.infer; export type ListTerminalsResponse = z.infer; export type SubscribeTerminalsRequest = z.infer; export type UnsubscribeTerminalsRequest = z.infer; export type TerminalsChanged = z.infer; export type CreateTerminalRequest = z.infer; export type CreateTerminalResponse = z.infer; export type StartWorkspaceScriptRequest = z.infer; export type StartWorkspaceScriptResponse = z.infer< typeof StartWorkspaceScriptResponseMessageSchema >; export type SubscribeTerminalRequest = z.infer; export type SubscribeTerminalResponse = z.infer; export type UnsubscribeTerminalRequest = z.infer; export type TerminalInput = z.infer; export type TerminalCell = z.infer; export type TerminalCursorStyle = z.infer; export type TerminalCursor = z.infer; export type TerminalState = z.infer; export type CloseItemsRequest = z.infer; export type CloseItemsResponse = z.infer; export type KillTerminalRequest = z.infer; export type KillTerminalResponse = z.infer; export type CaptureTerminalRequest = z.infer; export type CaptureTerminalResponse = z.infer; export type TerminalStreamExit = z.infer; // ============================================================================ // WebSocket Level Messages (wraps session messages) // ============================================================================ // WebSocket-only messages (not session messages) export const WSPingMessageSchema = z.object({ type: z.literal("ping"), }); export const WSPongMessageSchema = z.object({ type: z.literal("pong"), }); export const WSHelloMessageSchema = z.object({ type: z.literal("hello"), clientId: z.string().min(1), clientType: z.enum(["mobile", "browser", "cli", "mcp"]), protocolVersion: z.number().int(), appVersion: z.string().optional(), capabilities: z .object({ voice: z.boolean().optional(), pushNotifications: z.boolean().optional(), [CLIENT_CAPS.reasoningMergeEnum]: z.boolean().optional(), }) .passthrough() .optional(), }); export const WSRecordingStateMessageSchema = z.object({ type: z.literal("recording_state"), isRecording: z.boolean(), }); // Wrapped session message export const WSSessionInboundSchema = z.object({ type: z.literal("session"), message: SessionInboundMessageSchema, }); export const WSSessionOutboundSchema = z.object({ type: z.literal("session"), message: SessionOutboundMessageSchema, }); // Complete WebSocket message schemas export const WSInboundMessageSchema = z.discriminatedUnion("type", [ WSPingMessageSchema, WSHelloMessageSchema, WSRecordingStateMessageSchema, WSSessionInboundSchema, ]); export const WSOutboundMessageSchema = z.discriminatedUnion("type", [ WSPongMessageSchema, WSSessionOutboundSchema, ]); export type WSInboundMessage = z.infer; export type WSOutboundMessage = z.infer; export type WSHelloMessage = z.infer; // ============================================================================ // Helper functions for message conversion // ============================================================================ /** * Extract session message from WebSocket message * Returns null if message should be handled at WS level only */ export function extractSessionMessage(wsMsg: WSInboundMessage): SessionInboundMessage | null { if (wsMsg.type === "session") { return wsMsg.message; } // Ping and recording_state are WS-level only return null; } /** * Wrap session message in WebSocket envelope */ export function wrapSessionMessage(sessionMsg: SessionOutboundMessage): WSOutboundMessage { return { type: "session", message: sessionMsg, }; } export function parseServerInfoStatusPayload(payload: unknown): ServerInfoStatusPayload | null { const parsed = ServerInfoStatusPayloadSchema.safeParse(payload); if (!parsed.success) { return null; } return parsed.data; }