mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
* feat(agents): show agent messages and completion notifications with sender identity * fix(agents): preserve human envelope examples and attachment context * fix(agents): separate message provenance from timeline presentation
7614 lines
265 KiB
TypeScript
7614 lines
265 KiB
TypeScript
import { AgentMessageSchema } from "./agent-message.js";
|
|
import { PluginRegistryIdentitySchema } from "./plugin-registry.js";
|
|
import { AgentProfileSchema, AgentSkillSelectionSchema } from "./agent-profile.js";
|
|
export {
|
|
AgentProfileSchema,
|
|
AgentSkillSelectionSchema,
|
|
type AgentProfile,
|
|
type AgentSkillSelection,
|
|
} from "./agent-profile.js";
|
|
import { PluginIdSchema, PluginRequirementsSchema, PluginSourceSchema } from "./plugin-config.js";
|
|
export {
|
|
PluginIdSchema,
|
|
PluginRequirementsSchema,
|
|
DirectoryPluginSourceSchema,
|
|
PluginSourceSchema,
|
|
type PluginRequirements,
|
|
type PluginSource,
|
|
} from "./plugin-config.js";
|
|
import { TerminalProfileSchema } from "./terminal-profile.js";
|
|
export { TerminalProfileSchema, type TerminalProfile } from "./terminal-profile.js";
|
|
import { z } from "zod";
|
|
import { TerminalActivitySchema } from "./terminal-activity.js";
|
|
import { CLIENT_CAPS } from "./client-capabilities.js";
|
|
import { AGENT_LIFECYCLE_STATUSES } from "./agent-lifecycle.js";
|
|
import { MAX_EXPLICIT_AGENT_TITLE_CHARS } from "./agent-title-limits.js";
|
|
import { AgentProviderSchema } from "./provider-manifest.js";
|
|
import { ProviderPaseoToolsPolicySchema } from "./provider-config.js";
|
|
import { TOOL_CALL_ICON_NAMES } from "./agent-types.js";
|
|
import { WORKSPACE_LABEL_COLORS } from "./workspace-labels.js";
|
|
import {
|
|
ChatCreateRequestSchema,
|
|
ChatListRequestSchema,
|
|
ChatInspectRequestSchema,
|
|
ChatDeleteRequestSchema,
|
|
ChatPostRequestSchema,
|
|
ChatReadRequestSchema,
|
|
ChatWaitRequestSchema,
|
|
ChatCreateResponseSchema,
|
|
ChatListResponseSchema,
|
|
ChatInspectResponseSchema,
|
|
ChatDeleteResponseSchema,
|
|
ChatPostResponseSchema,
|
|
ChatReadResponseSchema,
|
|
ChatWaitResponseSchema,
|
|
} from "./chat/rpc-schemas.js";
|
|
import {
|
|
ScheduleCreateRequestSchema,
|
|
ScheduleListRequestSchema,
|
|
ScheduleInspectRequestSchema,
|
|
ScheduleLogsRequestSchema,
|
|
SchedulePauseRequestSchema,
|
|
ScheduleResumeRequestSchema,
|
|
ScheduleDeleteRequestSchema,
|
|
ScheduleRunOnceRequestSchema,
|
|
ScheduleUpdateRequestSchema,
|
|
ScheduleCreateResponseSchema,
|
|
ScheduleListResponseSchema,
|
|
ScheduleInspectResponseSchema,
|
|
ScheduleLogsResponseSchema,
|
|
SchedulePauseResponseSchema,
|
|
ScheduleResumeResponseSchema,
|
|
ScheduleDeleteResponseSchema,
|
|
ScheduleRunOnceResponseSchema,
|
|
ScheduleUpdateResponseSchema,
|
|
} from "./schedule/rpc-schemas.js";
|
|
import {
|
|
LoopRunRequestSchema,
|
|
LoopListRequestSchema,
|
|
LoopInspectRequestSchema,
|
|
LoopLogsRequestSchema,
|
|
LoopStopRequestSchema,
|
|
LoopRunResponseSchema,
|
|
LoopListResponseSchema,
|
|
LoopInspectResponseSchema,
|
|
LoopLogsResponseSchema,
|
|
LoopStopResponseSchema,
|
|
} from "./loop/rpc-schemas.js";
|
|
import {
|
|
BROWSER_AUTOMATION_COMMAND_NAMES,
|
|
BrowserAutomationExecuteRequestSchema,
|
|
BrowserAutomationExecuteResponseSchema,
|
|
} from "./browser-automation/rpc-schemas.js";
|
|
import { BrowserAutomationHostCapabilitySchema } from "./browser-automation/capabilities.js";
|
|
import {
|
|
PaseoConfigRawSchema,
|
|
PaseoLifecycleCommandRawSchema,
|
|
PaseoMetadataGenerationEntrySchema,
|
|
PaseoMetadataGenerationSchema,
|
|
PaseoScriptEntryRawSchema,
|
|
PaseoWorktreeConfigRawSchema,
|
|
PaseoConfigRevisionSchema,
|
|
ProjectConfigRpcErrorSchema,
|
|
type PaseoConfigRaw,
|
|
type PaseoConfigRevision,
|
|
type PaseoMetadataGeneration,
|
|
type PaseoMetadataGenerationEntry,
|
|
type PaseoScriptEntryRaw,
|
|
type ProjectConfigRpcError,
|
|
} from "./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)
|
|
// ---------------------------------------------------------------------------
|
|
|
|
export const DAEMON_PERMISSIONS = [
|
|
"daemon.read",
|
|
"daemon.manage",
|
|
"tunnel.manage",
|
|
"access.manage",
|
|
"workspace.read",
|
|
"workspace.write",
|
|
"workspace.manage",
|
|
"automation.manage",
|
|
"hub.execute",
|
|
] as const;
|
|
export const DaemonPermissionSchema = z.enum(DAEMON_PERMISSIONS);
|
|
export type DaemonPermission = z.infer<typeof DaemonPermissionSchema>;
|
|
|
|
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({
|
|
paseoTools: ProviderPaseoToolsPolicySchema.optional(),
|
|
enabled: z.boolean().optional(),
|
|
additionalModels: z.array(MutableDaemonProviderModelSchema).optional(),
|
|
})
|
|
.passthrough();
|
|
|
|
const MutableStructuredGenerationProviderSchema = z
|
|
.object({
|
|
provider: z.string().min(1),
|
|
model: z.string().min(1).optional(),
|
|
thinkingOptionId: z.string().min(1).optional(),
|
|
})
|
|
.passthrough();
|
|
|
|
const MutableMetadataGenerationConfigSchema = z
|
|
.object({
|
|
providers: z.array(MutableStructuredGenerationProviderSchema).default([]),
|
|
})
|
|
.passthrough();
|
|
|
|
const MutableBrowserToolsConfigSchema = z
|
|
.object({
|
|
enabled: z.boolean().default(false),
|
|
})
|
|
.passthrough();
|
|
const MutableRelayConfigSchema = z
|
|
.object({
|
|
enabled: z.boolean(),
|
|
})
|
|
.passthrough();
|
|
|
|
export const MutableDaemonConfigSchema = z
|
|
.object({
|
|
// COMPAT(relayConfig): added in v0.2.6, remove after 2027-01-31 when old daemons are unsupported.
|
|
relay: MutableRelayConfigSchema.optional(),
|
|
mcp: z
|
|
.object({
|
|
enabled: z.boolean().optional(),
|
|
injectIntoAgents: z.boolean(),
|
|
})
|
|
.passthrough(),
|
|
hostnames: z.union([z.literal(true), z.array(z.string())]).optional(),
|
|
cors: z
|
|
.object({
|
|
allowedOrigins: z.array(z.string()),
|
|
})
|
|
.passthrough()
|
|
.optional(),
|
|
trustedProxies: z.union([z.literal(true), z.array(z.string())]).optional(),
|
|
git: z
|
|
.object({
|
|
maxProcessesPerSecond: z.number().int().positive(),
|
|
maxProcessConcurrency: z.number().int().positive(),
|
|
})
|
|
.optional(),
|
|
app: z.object({ baseUrl: z.string() }).optional(),
|
|
catalogRefreshTimeoutMs: z.number().int().positive().optional(),
|
|
browserTools: MutableBrowserToolsConfigSchema.default({ enabled: false }),
|
|
providers: z.record(z.string(), MutableDaemonProviderConfigSchema).default({}),
|
|
metadataGeneration: MutableMetadataGenerationConfigSchema.default({ providers: [] }),
|
|
autoArchiveAfterMerge: z.boolean().default(false),
|
|
enableTerminalAgentHooks: z.boolean().default(false),
|
|
appendSystemPrompt: z.string().default(""),
|
|
terminalProfiles: z.array(TerminalProfileSchema).optional(),
|
|
agentProfiles: z.array(AgentProfileSchema).optional(),
|
|
skills: z.object({ selection: AgentSkillSelectionSchema.optional() }).strict().optional(),
|
|
pluginsEnabled: z.boolean().optional(),
|
|
plugins: z.record(PluginIdSchema, PluginSourceSchema).optional(),
|
|
})
|
|
.passthrough();
|
|
|
|
export const MutableDaemonConfigPatchSchema = z
|
|
.object({
|
|
relay: MutableRelayConfigSchema.partial().optional(),
|
|
mcp: z.object({ injectIntoAgents: z.boolean().optional() }).passthrough().optional(),
|
|
browserTools: MutableBrowserToolsConfigSchema.partial().optional(),
|
|
providers: z
|
|
.record(z.string(), MutableDaemonProviderConfigSchema.partial().passthrough())
|
|
.optional(),
|
|
removeProviders: z.array(z.string().min(1)).optional(),
|
|
metadataGeneration: MutableMetadataGenerationConfigSchema.partial().optional(),
|
|
autoArchiveAfterMerge: z.boolean().optional(),
|
|
enableTerminalAgentHooks: z.boolean().optional(),
|
|
appendSystemPrompt: z.string().optional(),
|
|
terminalProfiles: z.array(TerminalProfileSchema).optional(),
|
|
agentProfiles: z.array(AgentProfileSchema).optional(),
|
|
pluginsEnabled: z.boolean().optional(),
|
|
plugins: z.record(PluginIdSchema, PluginSourceSchema).optional(),
|
|
})
|
|
.partial()
|
|
.passthrough();
|
|
|
|
export type MutableDaemonConfig = z.infer<typeof MutableDaemonConfigSchema>;
|
|
export type MutableDaemonConfigPatch = z.infer<typeof MutableDaemonConfigPatchSchema>;
|
|
import type {
|
|
AgentCapabilityFlags,
|
|
AgentModelDefinition,
|
|
AgentMode,
|
|
AgentPermissionRequest,
|
|
AgentPermissionResponse,
|
|
AgentPersistenceHandle,
|
|
ProviderStatus,
|
|
AgentRuntimeInfo,
|
|
AgentTimelineItem,
|
|
AgentProviderNotice,
|
|
ToolCallDetail,
|
|
ToolCallTimelineItem,
|
|
AgentUsage,
|
|
JsonValue,
|
|
} from "./agent-types.js";
|
|
|
|
// WebSocket payloads have already crossed JSON serialization. Keeping this as
|
|
// unknown avoids zod-aot's recursive z.json() object-codegen regression.
|
|
const JsonWireValueSchema = z.unknown() as z.ZodType<JsonValue>;
|
|
|
|
export const AgentStatusSchema = z.enum(AGENT_LIFECYCLE_STATUSES);
|
|
|
|
const AgentModeSchema: z.ZodType<AgentMode> = z.object({
|
|
id: z.string(),
|
|
label: z.string(),
|
|
description: z.string().optional(),
|
|
icon: z.string().optional(),
|
|
colorTier: z.string().optional(),
|
|
});
|
|
|
|
const ProviderStatusSchema: z.ZodType<ProviderStatus> = 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.string(), z.unknown()).optional(),
|
|
});
|
|
|
|
const AgentProviderNoticeSchema: z.ZodType<AgentProviderNotice> = z.discriminatedUnion("type", [
|
|
z.object({ type: z.literal("info"), message: z.string() }),
|
|
z.object({ type: z.literal("warning"), message: z.string() }),
|
|
z.object({ type: z.literal("error"), message: z.string() }),
|
|
]);
|
|
|
|
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(),
|
|
desktopTrigger: z.enum(["icon", "label"]).optional(),
|
|
value: z.string().nullable(),
|
|
options: z.array(AgentSelectOptionSchema),
|
|
});
|
|
|
|
export const AgentFeatureSchema = z.discriminatedUnion("type", [
|
|
AgentFeatureToggleSchema,
|
|
AgentFeatureSelectSchema,
|
|
]);
|
|
|
|
const AgentModelDefinitionSchema = z.object({
|
|
provider: AgentProviderSchema,
|
|
id: z.string(),
|
|
aliases: z.array(z.string()).optional(),
|
|
isSelectable: z.boolean().optional(),
|
|
label: z.string(),
|
|
description: z.string().optional(),
|
|
isDefault: z.boolean().optional(),
|
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
contextWindowMaxTokens: z.number().optional(),
|
|
thinkingOptions: z.array(AgentSelectOptionSchema).optional(),
|
|
defaultThinkingOptionId: z.string().optional(),
|
|
}) satisfies z.ZodType<AgentModelDefinition>;
|
|
|
|
export const ProviderSnapshotEntrySchema = z.object({
|
|
provider: AgentProviderSchema,
|
|
status: ProviderStatusSchema,
|
|
enabled: z.boolean().optional().default(true),
|
|
source: z.enum(["builtin", "custom"]).optional(),
|
|
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(),
|
|
iconSvg: z.string().optional(),
|
|
defaultModeId: z.string().nullable().optional(),
|
|
});
|
|
|
|
export const CompactProviderSnapshotModelSchema = AgentModelDefinitionSchema.omit({
|
|
provider: true,
|
|
thinkingOptions: true,
|
|
}).extend({
|
|
thinkingSet: z.number().int().nonnegative().optional(),
|
|
});
|
|
|
|
export const ProviderSnapshotThinkingSetSchema = z.object({
|
|
options: z.array(AgentSelectOptionSchema),
|
|
defaultOptionId: z.string().optional(),
|
|
});
|
|
|
|
export const CompactProviderSnapshotEntrySchema = ProviderSnapshotEntrySchema.omit({
|
|
models: true,
|
|
}).extend({
|
|
models: z.array(CompactProviderSnapshotModelSchema).optional(),
|
|
});
|
|
|
|
export const CompactProviderSnapshotSchema = z.object({
|
|
entries: z.array(CompactProviderSnapshotEntrySchema),
|
|
thinkingSets: z.array(ProviderSnapshotThinkingSetSchema),
|
|
});
|
|
|
|
const AgentCapabilityFlagsSchema: z.ZodType<AgentCapabilityFlags> = z
|
|
.object({
|
|
supportsStreaming: z.boolean(),
|
|
supportsSessionPersistence: z.boolean(),
|
|
supportsSessionListing: z.boolean().optional(),
|
|
supportsDynamicModes: z.boolean(),
|
|
supportsMcpServers: z.boolean(),
|
|
supportsReasoningStream: z.boolean(),
|
|
supportsToolInvocations: z.boolean(),
|
|
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
supportsRewindConversation: z.boolean().optional().default(false),
|
|
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
supportsRewindFiles: z.boolean().optional().default(false),
|
|
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
supportsRewindBoth: z.boolean().optional().default(false),
|
|
})
|
|
.catchall(z.boolean());
|
|
|
|
const AgentUsageSchema: z.ZodType<AgentUsage> = 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(), z.string()).optional(),
|
|
alwaysLoad: z.boolean().optional(),
|
|
});
|
|
|
|
const McpHttpServerConfigSchema = z.object({
|
|
type: z.literal("http"),
|
|
url: z.string(),
|
|
headers: z.record(z.string(), z.string()).optional(),
|
|
alwaysLoad: z.boolean().optional(),
|
|
});
|
|
|
|
const McpSseServerConfigSchema = z.object({
|
|
type: z.literal("sse"),
|
|
url: z.string(),
|
|
headers: z.record(z.string(), z.string()).optional(),
|
|
alwaysLoad: z.boolean().optional(),
|
|
});
|
|
|
|
const McpServerConfigSchema = z.discriminatedUnion("type", [
|
|
McpStdioServerConfigSchema,
|
|
McpHttpServerConfigSchema,
|
|
McpSseServerConfigSchema,
|
|
]);
|
|
|
|
const ProviderOptionsSchema = z.record(z.string(), z.unknown());
|
|
|
|
const McpToolRefSchema = z
|
|
.object({
|
|
kind: z.literal("mcp"),
|
|
server: z.string().trim().min(1),
|
|
tool: z.string().trim().min(1),
|
|
})
|
|
.strict();
|
|
|
|
const ToolPolicySchema = z
|
|
.object({
|
|
preapproved: z.array(McpToolRefSchema),
|
|
})
|
|
.strict();
|
|
|
|
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.string(), z.unknown()).optional(),
|
|
title: z.string().trim().min(1).max(MAX_EXPLICIT_AGENT_TITLE_CHARS).optional().nullable(),
|
|
providerOptions: ProviderOptionsSchema.optional(),
|
|
toolPolicy: ToolPolicySchema.optional(),
|
|
systemPrompt: z.string().optional(),
|
|
mcpServers: z.record(z.string(), McpServerConfigSchema).optional(),
|
|
});
|
|
|
|
const AgentPermissionUpdateSchema = z.record(z.string(), 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<AgentPermissionResponse> =
|
|
z.discriminatedUnion("behavior", [
|
|
z.object({
|
|
behavior: z.literal("allow"),
|
|
selectedActionId: z.string().optional(),
|
|
updatedInput: z.record(z.string(), 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, 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.string(), z.unknown()).optional(),
|
|
detail: z.lazy(() => ToolCallDetailPayloadSchema).optional(),
|
|
suggestions: z.array(AgentPermissionUpdateSchema).optional(),
|
|
actions: z.array(AgentPermissionActionSchema).optional(),
|
|
metadata: z.record(z.string(), 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<ToolCallDetail, unknown> = 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({
|
|
agentMessage: AgentMessageSchema.optional(),
|
|
type: z.literal("tool_call"),
|
|
callId: z.string(),
|
|
name: z.string(),
|
|
detail: ToolCallDetailPayloadSchema,
|
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
|
|
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<ToolCallTimelineItem, unknown> =
|
|
z.discriminatedUnion("status", [
|
|
ToolCallRunningPayloadSchema,
|
|
ToolCallCompletedPayloadSchema,
|
|
ToolCallFailedPayloadSchema,
|
|
ToolCallCanceledPayloadSchema,
|
|
]);
|
|
|
|
// zod-aot 0.20.4 miscompiles this as a nested discriminated union by omitting
|
|
// the inner tool_call branch from the generated outer dispatch.
|
|
export const AgentTimelineItemPayloadSchema: z.ZodType<AgentTimelineItem, unknown> = z.union([
|
|
z.object({
|
|
type: z.literal("user_message"),
|
|
text: z.string(),
|
|
messageId: z.string().optional(),
|
|
clientMessageId: 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(),
|
|
id: z.string().optional(),
|
|
status: z.enum(["pending", "in_progress", "completed"]).optional(),
|
|
activeForm: z.string().optional(),
|
|
}),
|
|
),
|
|
}),
|
|
z.object({
|
|
type: z.literal("error"),
|
|
message: z.string(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("notification"),
|
|
level: z.enum(["info", "warning", "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(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("plugin"),
|
|
id: z.string(),
|
|
pluginId: PluginIdSchema,
|
|
kind: z.string(),
|
|
version: z.number(),
|
|
data: JsonWireValueSchema,
|
|
}),
|
|
]);
|
|
|
|
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,
|
|
turnId: z.string().optional(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("turn_completed"),
|
|
provider: AgentProviderSchema,
|
|
turnId: z.string().optional(),
|
|
usage: AgentUsageSchema.optional(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("turn_failed"),
|
|
provider: AgentProviderSchema,
|
|
turnId: z.string().optional(),
|
|
error: z.string(),
|
|
code: z.string().optional(),
|
|
diagnostic: z.string().optional(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("turn_canceled"),
|
|
provider: AgentProviderSchema,
|
|
turnId: z.string().optional(),
|
|
reason: z.string(),
|
|
}),
|
|
z.object({
|
|
type: z.literal("timeline"),
|
|
provider: AgentProviderSchema,
|
|
item: AgentTimelineItemPayloadSchema,
|
|
turnId: z.string().optional(),
|
|
}),
|
|
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(),
|
|
workspaceId: z.string().optional(),
|
|
agentId: z.string(),
|
|
reason: z.enum(["finished", "error", "permission"]),
|
|
}),
|
|
})
|
|
.optional(),
|
|
}),
|
|
]);
|
|
|
|
const AgentPersistenceHandleSchema: z.ZodType<AgentPersistenceHandle | null> = z
|
|
.object({
|
|
provider: AgentProviderSchema,
|
|
sessionId: z.string(),
|
|
nativeHandle: z.string().optional(),
|
|
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
})
|
|
.nullable();
|
|
|
|
const AgentRuntimeInfoSchema: z.ZodType<AgentRuntimeInfo> = 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(),
|
|
});
|
|
|
|
const AgentActiveTurnPayloadSchema = z.object({
|
|
turnId: z.string(),
|
|
startedAt: z.string().nullable(),
|
|
});
|
|
|
|
export const AgentSnapshotPayloadSchema = z.object({
|
|
id: z.string(),
|
|
provider: AgentProviderSchema,
|
|
cwd: z.string(),
|
|
workspaceId: z.string().optional(),
|
|
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,
|
|
activeTurn: AgentActiveTurnPayloadSchema.nullable().optional(),
|
|
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<typeof AgentSnapshotPayloadSchema>;
|
|
|
|
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<typeof AgentListItemPayloadSchema>;
|
|
|
|
export type AgentStreamEventPayload = z.infer<typeof AgentStreamEventPayloadSchema>;
|
|
|
|
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(), 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(), z.string()).optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// The daemon accepts only image bytes chosen or acquired by the client. It must
|
|
// never fetch a user-provided URL on the host's network.
|
|
export const ProjectIconSourceSchema = z.discriminatedUnion("type", [
|
|
z.object({ type: z.literal("automatic") }),
|
|
z.object({ type: z.literal("upload"), data: z.string() }),
|
|
]);
|
|
|
|
export const ProjectRenameRequestSchema = z.object({
|
|
type: z.literal("project.rename.request"),
|
|
projectId: z.string(),
|
|
// Null or empty string clears the override and reverts to the derived name.
|
|
customName: z.string().nullable(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectIconSetRequestSchema = z.object({
|
|
type: z.literal("project.icon.set.request"),
|
|
projectId: z.string(),
|
|
source: ProjectIconSourceSchema,
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectRemoveRequestSchema = z.object({
|
|
type: z.literal("project.remove.request"),
|
|
projectId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceTitleSetRequestSchema = z.object({
|
|
type: z.literal("workspace.title.set.request"),
|
|
workspaceId: z.string(),
|
|
// Null or empty string clears the title and reverts to the derived name.
|
|
title: z.string().nullable(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspacePinSetRequestSchema = z.object({
|
|
type: z.literal("workspace.pin.set.request"),
|
|
workspaceId: z.string(),
|
|
pinned: z.boolean(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceLabelColorSchema = z.enum(WORKSPACE_LABEL_COLORS);
|
|
export const WorkspaceLabelDefinitionSchema = z.object({
|
|
name: z.string(),
|
|
color: WorkspaceLabelColorSchema,
|
|
});
|
|
const WorkspaceLabelSyncCursorSchema = z.object({
|
|
generation: z.string(),
|
|
afterSeq: z.number().int().nonnegative(),
|
|
});
|
|
|
|
export const WorkspaceLabelListRequestSchema = z.object({
|
|
type: z.literal("workspace.label.list.request"),
|
|
requestId: z.string(),
|
|
subscribe: z.object({ subscriptionId: z.string().optional() }).optional(),
|
|
sync: WorkspaceLabelSyncCursorSchema.optional(),
|
|
});
|
|
export const WorkspaceLabelAssignmentSetRequestSchema = z.object({
|
|
type: z.literal("workspace.label.assignment.set.request"),
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
label: WorkspaceLabelDefinitionSchema,
|
|
assigned: z.boolean(),
|
|
});
|
|
/**
|
|
* Editing a label is one operation. A name and a colour are two fields of one thing, and two
|
|
* RPCs can land half-applied — leaving the catalog in a state the user never asked for and the
|
|
* UI with nothing true to say. Both fields are optional; omitting one leaves it alone.
|
|
*/
|
|
export const WorkspaceLabelUpdateRequestSchema = z.object({
|
|
type: z.literal("workspace.label.update.request"),
|
|
requestId: z.string(),
|
|
name: z.string(),
|
|
newName: z.string().optional(),
|
|
color: WorkspaceLabelColorSchema.optional(),
|
|
});
|
|
export const WorkspaceLabelDeleteRequestSchema = z.object({
|
|
type: z.literal("workspace.label.delete.request"),
|
|
requestId: z.string(),
|
|
name: z.string(),
|
|
});
|
|
export const WorkspaceLabelDeleteInspectRequestSchema = z.object({
|
|
type: z.literal("workspace.label.delete.inspect.request"),
|
|
requestId: z.string(),
|
|
name: z.string(),
|
|
});
|
|
|
|
export const WorkspaceRecoveryInspectRequestSchema = z.object({
|
|
type: z.literal("workspace.recovery.inspect.request"),
|
|
workspaceId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceRecoveryRestoreRequestSchema = z.object({
|
|
type: z.literal("workspace.recovery.restore.request"),
|
|
workspaceId: z.string(),
|
|
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(),
|
|
});
|
|
|
|
// COMPAT(githubAttachmentKinds): legacy wire attachment retained when
|
|
// forge-neutral attachments shipped in v0.2.0-beta.1. Stop emitting it after
|
|
// 2027-01-17 once supported client and daemon floors are >= v0.2.0.
|
|
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 ForgeChangeRequestAttachmentSchema = z.object({
|
|
type: z.literal("forge_change_request"),
|
|
mimeType: z.literal("application/paseo-forge-change-request"),
|
|
forge: z.string().optional().default("github"),
|
|
number: z.number().int().positive(),
|
|
title: z.string(),
|
|
url: z.string(),
|
|
body: z.string().nullable().optional(),
|
|
projectPath: z.string().optional(),
|
|
baseRefName: z.string().nullable().optional(),
|
|
headRefName: z.string().nullable().optional(),
|
|
});
|
|
|
|
// COMPAT(githubAttachmentKinds): legacy wire attachment retained when
|
|
// forge-neutral attachments shipped in v0.2.0-beta.1. Stop emitting it after
|
|
// 2027-01-17 once supported client and daemon floors are >= v0.2.0.
|
|
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 ForgeIssueAttachmentSchema = z.object({
|
|
type: z.literal("forge_issue"),
|
|
mimeType: z.literal("application/paseo-forge-issue"),
|
|
forge: z.string().optional().default("github"),
|
|
number: z.number().int().positive(),
|
|
title: z.string(),
|
|
url: z.string(),
|
|
body: z.string().nullable().optional(),
|
|
projectPath: z.string().optional(),
|
|
});
|
|
|
|
export const ExternalResourceAttachmentMetadataSchema = z.object({
|
|
provider: z.string(),
|
|
providerLabel: z.string(),
|
|
resourceType: z.string(),
|
|
id: z.string(),
|
|
identifier: z.string(),
|
|
title: z.string(),
|
|
url: z.string(),
|
|
});
|
|
|
|
export const TextAttachmentSchema = z
|
|
.object({
|
|
type: z.literal("text"),
|
|
mimeType: z.literal("text/plain"),
|
|
contextKind: z.string().optional(),
|
|
title: z.string().nullable().optional(),
|
|
text: z.string(),
|
|
externalResource: ExternalResourceAttachmentMetadataSchema.optional(),
|
|
})
|
|
.transform(({ contextKind, ...attachment }) => ({
|
|
...attachment,
|
|
...(contextKind === "chat_history" ? { contextKind } : {}),
|
|
}));
|
|
|
|
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 UploadedFileAttachmentSchema = z.object({
|
|
type: z.literal("uploaded_file"),
|
|
id: z.string(),
|
|
fileName: z.string(),
|
|
mimeType: z.string(),
|
|
size: z.number().int().nonnegative(),
|
|
path: z.string(),
|
|
});
|
|
|
|
export const AgentAttachmentSchema = z.discriminatedUnion("type", [
|
|
ForgeChangeRequestAttachmentSchema,
|
|
ForgeIssueAttachmentSchema,
|
|
GitHubPrAttachmentSchema,
|
|
GitHubIssueAttachmentSchema,
|
|
TextAttachmentSchema,
|
|
ReviewAttachmentSchema,
|
|
UploadedFileAttachmentSchema,
|
|
]);
|
|
|
|
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();
|
|
|
|
export const ChangeRequestCheckoutSourceSchema = z.object({
|
|
kind: z.literal("change_request"),
|
|
forge: z.string().optional(),
|
|
number: z.number().int().positive(),
|
|
projectPath: z.string().optional(),
|
|
});
|
|
|
|
const ImageAttachmentSchema = z.object({
|
|
data: z.string(), // base64 encoded image
|
|
mimeType: z.string(), // e.g., "image/jpeg", "image/png"
|
|
});
|
|
|
|
export const ActiveTurnBehaviorSchema = z.enum(["interrupt", "steer"]);
|
|
export type ActiveTurnBehavior = z.infer<typeof ActiveTurnBehaviorSchema>;
|
|
|
|
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
|
|
activeTurnBehavior: ActiveTurnBehaviorSchema.optional(),
|
|
images: z.array(ImageAttachmentSchema).optional(),
|
|
attachments: AgentAttachmentsSchema,
|
|
});
|
|
|
|
// ============================================================================
|
|
// Agent RPCs (requestId-correlated)
|
|
// ============================================================================
|
|
|
|
const DirectorySyncRequestSchema = z.object({
|
|
generation: z.string().optional(),
|
|
afterSeq: z.number().int().nonnegative().optional(),
|
|
});
|
|
|
|
const DirectorySyncRemovalSchema = z.object({
|
|
id: z.string(),
|
|
seq: z.number().int().positive(),
|
|
});
|
|
|
|
const DirectorySyncMetadataSchema = z.object({
|
|
generation: z.string(),
|
|
headSeq: z.number().int().nonnegative(),
|
|
mode: z.enum(["snapshot", "changes"]),
|
|
reason: z
|
|
.enum(["no_cursor", "generation_changed", "cursor_expired", "changes_too_large"])
|
|
.optional(),
|
|
removals: z.array(DirectorySyncRemovalSchema),
|
|
});
|
|
|
|
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(),
|
|
// COMPAT(directorySync): added in v0.3.x, remove optional after 2027-02-12.
|
|
sync: DirectorySyncRequestSchema.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(),
|
|
// Unused: accepted so older clients still parse, but the server does not filter on it.
|
|
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(),
|
|
// COMPAT(directorySync): added in v0.3.x, remove optional after 2027-02-12.
|
|
sync: DirectorySyncRequestSchema.optional(),
|
|
});
|
|
|
|
export const ProjectListRequestMessageSchema = z.object({
|
|
type: z.literal("project.list.request"),
|
|
requestId: z.string(),
|
|
// COMPAT(directorySync): added in v0.3.x, remove optional after 2027-02-12.
|
|
sync: DirectorySyncRequestSchema.optional(),
|
|
});
|
|
|
|
export const FetchAgentHistoryRequestMessageSchema = z.object({
|
|
type: z.literal("fetch_agent_history_request"),
|
|
requestId: z.string(),
|
|
filter: AgentDirectoryFilterSchema.optional(),
|
|
// A free-text filter over agent title, workspace name, branch, and project name.
|
|
// Matching rows follow the requested sort and cursor pagination.
|
|
search: z.string().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(),
|
|
query: z.string().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(),
|
|
/** Opaque sender identity for agent-originated prompts. */
|
|
sourceAgentId: z.string().min(1).optional(),
|
|
messageId: z.string().optional(), // Client-provided ID for deduplication
|
|
activeTurnBehavior: ActiveTurnBehaviorSchema.optional(),
|
|
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 DaemonGetStatusRequestSchema = z.object({
|
|
type: z.literal("daemon.get_status.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const DaemonGetPairingOfferRequestSchema = z.object({
|
|
type: z.literal("daemon.get_pairing_offer.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const DaemonConfigReloadRequestSchema = z.object({
|
|
type: z.literal("daemon.config.reload.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const HubManagementDaemonConnectRequestSchema = z.object({
|
|
type: z.literal("hub.management.daemon.connect.request"),
|
|
requestId: z.string(),
|
|
hubUrl: z.string(),
|
|
token: z.string(),
|
|
permissions: z.array(DaemonPermissionSchema).default([]),
|
|
});
|
|
export const HubManagementDaemonGetStatusRequestSchema = z.object({
|
|
type: z.literal("hub.management.daemon.get_status.request"),
|
|
requestId: z.string(),
|
|
});
|
|
export const HubManagementDaemonDisconnectRequestSchema = z.object({
|
|
type: z.literal("hub.management.daemon.disconnect.request"),
|
|
requestId: z.string(),
|
|
force: z.boolean().optional(),
|
|
});
|
|
export const HubManagementDaemonPermissionsUpdateRequestSchema = z.object({
|
|
type: z.literal("hub.management.daemon.permissions.update.request"),
|
|
requestId: z.string(),
|
|
grant: z.array(DaemonPermissionSchema).default([]),
|
|
revoke: z.array(DaemonPermissionSchema).default([]),
|
|
});
|
|
|
|
export const DiagnosticsRequestSchema = z.object({
|
|
type: z.literal("diagnostics.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const PluginCatalogGetRequestSchema = z.object({
|
|
type: z.literal("plugin.catalog.get.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const PluginListRequestSchema = z.object({
|
|
type: z.literal("plugin.list.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const PluginLogsGetRequestSchema = z.object({
|
|
type: z.literal("plugin.logs.get.request"),
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema,
|
|
});
|
|
|
|
export const PluginDirectoryInstallRequestSchema = z.object({
|
|
type: z.literal("plugin.directory.install.request"),
|
|
requestId: z.string(),
|
|
path: z.string().min(1),
|
|
id: PluginIdSchema.optional(),
|
|
});
|
|
|
|
export const PluginDirectoryInspectRequestSchema = z.object({
|
|
type: z.literal("plugin.directory.inspect.request"),
|
|
requestId: z.string(),
|
|
path: z.string().min(1),
|
|
});
|
|
|
|
export const PluginSourceInstallRequestSchema = z.object({
|
|
type: z.literal("plugin.source.install.request"),
|
|
requestId: z.string(),
|
|
source: z.string().min(1),
|
|
id: PluginIdSchema.optional(),
|
|
ref: z.string().min(1).optional(),
|
|
// COMPAT(plugin-source-path): accepted for v0.7 clients; remove after 2027-09-01.
|
|
pluginPath: z.string().min(1).optional(),
|
|
});
|
|
|
|
export const PluginSourceIdentitySchema = z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("directory"), path: z.string() }),
|
|
z.object({
|
|
kind: z.literal("git"),
|
|
remote: z.string(),
|
|
pluginPath: z.string(),
|
|
registry: PluginRegistryIdentitySchema.optional(),
|
|
}),
|
|
z.object({
|
|
kind: z.literal("npm"),
|
|
packageName: z.string(),
|
|
pluginPath: z.string(),
|
|
registry: PluginRegistryIdentitySchema.optional(),
|
|
}),
|
|
]);
|
|
export const PluginInstallationSchema = z.object({
|
|
identity: PluginSourceIdentitySchema,
|
|
currentRevision: z.string().optional(),
|
|
});
|
|
export type PluginInstallation = z.infer<typeof PluginInstallationSchema>;
|
|
export const PluginUpdateTargetSchema = z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("git"), commit: z.string().regex(/^[0-9a-f]{40,64}$/) }),
|
|
z.object({
|
|
kind: z.literal("npm"),
|
|
version: z.string().min(1),
|
|
resolved: z.string().url(),
|
|
integrity: z.string().min(1),
|
|
}),
|
|
]);
|
|
export type PluginUpdateTarget = z.infer<typeof PluginUpdateTargetSchema>;
|
|
export const PluginUpdateProposalSchema = z.object({
|
|
id: PluginIdSchema,
|
|
expected: z.object({
|
|
identity: PluginSourceIdentitySchema,
|
|
installationRoot: z.string(),
|
|
revision: z.string(),
|
|
}),
|
|
target: PluginUpdateTargetSchema,
|
|
});
|
|
export type PluginUpdateProposal = z.infer<typeof PluginUpdateProposalSchema>;
|
|
export const PluginUpdateSelectionSchema = z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("git"), ref: z.string().min(1) }),
|
|
z.object({ kind: z.literal("npm"), version: z.string().min(1) }),
|
|
]);
|
|
export type PluginUpdateSelection = z.infer<typeof PluginUpdateSelectionSchema>;
|
|
export const PluginUpdatePreviewRequestSchema = z.object({
|
|
type: z.literal("plugin.source.update.preview.request"),
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema.optional(),
|
|
target: PluginUpdateSelectionSchema.optional(),
|
|
});
|
|
export const PluginUpdateApplyRequestSchema = z.object({
|
|
type: z.literal("plugin.source.update.apply.request"),
|
|
requestId: z.string(),
|
|
proposals: z.array(PluginUpdateProposalSchema).min(1),
|
|
});
|
|
|
|
export const PluginSourceStatusRequestSchema = z.object({
|
|
type: z.literal("plugin.source.status.request"),
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema.optional(),
|
|
});
|
|
|
|
export const PluginSourceUpdateRequestSchema = z.object({
|
|
type: z.literal("plugin.source.update.request"),
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema.optional(),
|
|
});
|
|
|
|
function pluginIdRequest<const Type extends string>(type: Type) {
|
|
return z.object({ type: z.literal(type), requestId: z.string(), pluginId: PluginIdSchema });
|
|
}
|
|
|
|
export const PluginReloadRequestSchema = pluginIdRequest("plugin.reload.request");
|
|
export const PluginEnableRequestSchema = pluginIdRequest("plugin.enable.request");
|
|
export const PluginDisableRequestSchema = pluginIdRequest("plugin.disable.request");
|
|
export const PluginRemoveRequestSchema = pluginIdRequest("plugin.remove.request");
|
|
|
|
export const PluginRpcInvokeRequestSchema = z.object({
|
|
type: z.literal("plugin.rpc.invoke.request"),
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema,
|
|
method: z.string().min(1),
|
|
input: z.unknown(),
|
|
});
|
|
|
|
export const AgentTimelineAppendRequestSchema = z.object({
|
|
type: z.literal("agent.timeline.append.request"),
|
|
requestId: z.string(),
|
|
agentId: z.string(),
|
|
item: z.object({
|
|
type: z.literal("plugin"),
|
|
id: z.string(),
|
|
kind: z.string(),
|
|
version: z.number().int().positive(),
|
|
data: JsonWireValueSchema,
|
|
}),
|
|
});
|
|
|
|
export const AgentSkillOperationSchema = z.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("add"), name: z.string() }).strict(),
|
|
z.object({ kind: z.literal("update"), name: z.string() }).strict(),
|
|
z.object({ kind: z.literal("delete"), name: z.string() }).strict(),
|
|
]);
|
|
export type AgentSkillOperation = z.infer<typeof AgentSkillOperationSchema>;
|
|
|
|
export const AgentSkillsStatusSchema = z.object({
|
|
state: z.enum(["not-installed", "up-to-date", "drift"]),
|
|
ops: z.array(AgentSkillOperationSchema),
|
|
available: z.array(z.string()),
|
|
installed: z.array(z.string()),
|
|
selection: AgentSkillSelectionSchema,
|
|
});
|
|
export type AgentSkillsStatus = z.infer<typeof AgentSkillsStatusSchema>;
|
|
|
|
export const AgentSkillsConfirmationSchema = z.object({ removals: z.array(z.string()) }).strict();
|
|
export type AgentSkillsConfirmation = z.infer<typeof AgentSkillsConfirmationSchema>;
|
|
|
|
export const AgentSkillsSaveResultSchema = AgentSkillsStatusSchema.extend({
|
|
confirmationRequired: AgentSkillsConfirmationSchema.nullable(),
|
|
});
|
|
export type AgentSkillsSaveResult = z.infer<typeof AgentSkillsSaveResultSchema>;
|
|
|
|
function agentSkillsRequest<const Type extends string>(type: Type) {
|
|
return z.object({ type: z.literal(type), requestId: z.string() }).strict();
|
|
}
|
|
|
|
export const AgentSkillsGetStatusRequestSchema = agentSkillsRequest(
|
|
"agent.skills.get_status.request",
|
|
);
|
|
export const AgentSkillsReconcileRequestSchema = agentSkillsRequest(
|
|
"agent.skills.reconcile.request",
|
|
);
|
|
export const AgentSkillsUninstallRequestSchema = agentSkillsRequest(
|
|
"agent.skills.uninstall.request",
|
|
);
|
|
export const AgentSkillsSaveSelectionRequestSchema = z
|
|
.object({
|
|
type: z.literal("agent.skills.save_selection.request"),
|
|
requestId: z.string(),
|
|
selection: AgentSkillSelectionSchema,
|
|
confirmedRemovals: z.array(z.string()).optional(),
|
|
})
|
|
.strict();
|
|
export const AgentSkillsImportLegacySelectionRequestSchema = z
|
|
.object({
|
|
type: z.literal("agent.skills.import_legacy_selection.request"),
|
|
requestId: z.string(),
|
|
selection: AgentSkillSelectionSchema,
|
|
})
|
|
.strict();
|
|
|
|
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(),
|
|
checkoutSource: ChangeRequestCheckoutSourceSchema.optional(),
|
|
// COMPAT(githubPrNumber): legacy GitHub checkout input retained when
|
|
// checkoutSource shipped in v0.2.0-beta.1. Remove after 2027-01-17 once the
|
|
// supported client floor is >= v0.2.0.
|
|
githubPrNumber: z.number().int().positive().optional(),
|
|
});
|
|
|
|
export type GitSetupOptions = z.infer<typeof GitSetupOptionsSchema>;
|
|
|
|
export const CreateAgentWorktreeTargetSchema = z.discriminatedUnion("mode", [
|
|
z.object({
|
|
mode: z.literal("branch-off"),
|
|
newBranch: z.string().min(1),
|
|
base: z.string().min(1).optional(),
|
|
}),
|
|
z.object({
|
|
mode: z.literal("checkout-branch"),
|
|
branch: z.string().min(1),
|
|
}),
|
|
z.object({
|
|
mode: z.literal("checkout-pr"),
|
|
prNumber: z.number().int().positive(),
|
|
}),
|
|
]);
|
|
|
|
export type CreateAgentWorktreeTarget = z.infer<typeof CreateAgentWorktreeTargetSchema>;
|
|
|
|
export const CreateAgentRequestMessageSchema = z.object({
|
|
type: z.literal("create_agent_request"),
|
|
// Legacy create_agent_request uses a separate initial-message receipt when keyed.
|
|
idempotencyKey: z.string().min(1).max(512).optional(),
|
|
config: AgentSessionConfigSchema,
|
|
env: z.record(z.string(), z.string()).optional(),
|
|
workspaceId: z.string().optional(),
|
|
// Optional caller context lets managed CLI invocations use the same daemon-owned
|
|
// workspace and parentage policy as agent-scoped MCP creation.
|
|
callerAgentId: z.string().optional(),
|
|
worktreeName: z.string().optional(),
|
|
initialPrompt: z.string().optional(),
|
|
clientMessageId: z.string().optional(),
|
|
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
images: z.array(ImageAttachmentSchema).optional(),
|
|
attachments: AgentAttachmentsSchema,
|
|
git: GitSetupOptionsSchema.optional(),
|
|
worktree: CreateAgentWorktreeTargetSchema.optional(),
|
|
autoArchive: z.boolean().optional(),
|
|
labels: z.record(z.string(), z.string()).default({}),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
/** Resource IDs are optional on creation; supplied IDs retain their identity on replay. */
|
|
export const AgentCreateRequestSchema = CreateAgentRequestMessageSchema.extend({
|
|
type: z.literal("agent.create.request"),
|
|
agentId: z.uuid().optional(),
|
|
attachments: z.array(AgentAttachmentSchema).optional(),
|
|
subscribe: z.boolean().optional(),
|
|
});
|
|
|
|
export const WorkspaceInitialAgentSchema = AgentCreateRequestSchema.omit({
|
|
type: true,
|
|
requestId: true,
|
|
idempotencyKey: true,
|
|
subscribe: true,
|
|
workspaceId: true,
|
|
worktree: true,
|
|
worktreeName: true,
|
|
git: true,
|
|
});
|
|
|
|
export const CreationSubscribeRequestSchema = z.object({
|
|
type: z.literal("creation.subscribe.request"),
|
|
requestId: z.string(),
|
|
kind: z.enum(["workspace", "agent"]),
|
|
idempotencyKey: z.string().min(1).max(512),
|
|
subscribe: z.boolean().optional(),
|
|
});
|
|
|
|
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(),
|
|
// COMPAT(compactProviderSnapshots): old daemons ignore this field and return a full snapshot.
|
|
ifNoneMatch: 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 ProviderUsageListRequestMessageSchema = z.object({
|
|
type: z.literal("provider.usage.list.request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const UsageListReportsRequestMessageSchema = z.object({
|
|
type: z.literal("usage.list_reports.request"),
|
|
agentId: z.string().optional(),
|
|
requestId: z.string(),
|
|
reportIds: z.array(z.string()).optional(),
|
|
forceRefresh: z.boolean().optional(),
|
|
});
|
|
|
|
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(),
|
|
workspaceId: z.string().optional(),
|
|
labels: z.record(z.string(), 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 DaemonUpdateRequestMessageSchema = z.object({
|
|
type: z.literal("daemon.update.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(),
|
|
// Allow the client to merge this bounded page outside its contiguous loaded range.
|
|
mergeWindow: z.boolean().optional(),
|
|
});
|
|
|
|
export const AgentTimelineSearchRequestMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.search.request"),
|
|
agentId: z.string(),
|
|
requestId: z.string(),
|
|
query: z.string(),
|
|
cursor: z.number().int().nonnegative().optional(),
|
|
});
|
|
|
|
export const AgentTimelineListPromptsRequestMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.list_prompts.request"),
|
|
agentId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProviderSubagentListRequestMessageSchema = z.object({
|
|
type: z.literal("agent.provider_subagents.list.request"),
|
|
parentAgentId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProviderSubagentTimelineRequestMessageSchema = z.object({
|
|
type: z.literal("agent.provider_subagents.timeline.get.request"),
|
|
parentAgentId: z.string(),
|
|
subagentId: z.string(),
|
|
requestId: z.string(),
|
|
direction: z.enum(["tail", "before", "after"]).optional(),
|
|
cursor: AgentTimelineCursorSchema.optional(),
|
|
limit: z.number().int().nonnegative().optional(),
|
|
});
|
|
|
|
export const SetAgentTimelineSubscriptionRequestMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.set_subscription.request"),
|
|
agentIds: z.array(z.string()),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const AgentForkContextRequestMessageSchema = z.object({
|
|
type: z.literal("agent.fork_context.request"),
|
|
agentId: z.string(),
|
|
boundaryCursor: AgentTimelineCursorSchema.optional(),
|
|
boundaryMessageId: z.string().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
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(),
|
|
notice: AgentProviderNoticeSchema.nullable().optional(),
|
|
});
|
|
|
|
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,
|
|
});
|
|
|
|
/**
|
|
* Every agent-config value a client can change in one shot. Each field is
|
|
* optional and an omitted field is left alone; `null` on model and thinking
|
|
* clears them, matching the single-field RPCs above.
|
|
*/
|
|
export const AgentConfigApplySchema = z.object({
|
|
modelId: z.string().nullable().optional(),
|
|
modeId: z.string().optional(),
|
|
thinkingOptionId: z.string().nullable().optional(),
|
|
featureValues: z.record(z.string(), z.unknown()).optional(),
|
|
});
|
|
|
|
export type AgentConfigApply = z.infer<typeof AgentConfigApplySchema>;
|
|
|
|
/**
|
|
* Applies a whole config bundle to one agent. The four single-field RPCs above
|
|
* stay for individual control edits. One request prevents client interruption
|
|
* and other mutations from interleaving between bundle steps; provider-level
|
|
* rejection can still leave earlier steps applied.
|
|
*/
|
|
export const AgentConfigApplyRequestMessageSchema = z.object({
|
|
type: z.literal("agent.config.apply.request"),
|
|
agentId: z.string(),
|
|
config: AgentConfigApplySchema,
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const AgentConfigApplyResponseMessageSchema = z.object({
|
|
type: z.literal("agent.config.apply.response"),
|
|
payload: AgentActionResponsePayloadSchema,
|
|
});
|
|
|
|
export const AgentDetachRequestMessageSchema = z.object({
|
|
type: z.literal("agent.detach.request"),
|
|
agentId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const AgentDetachResponseMessageSchema = z.object({
|
|
type: z.literal("agent.detach.response"),
|
|
payload: AgentActionResponsePayloadSchema,
|
|
});
|
|
|
|
export const AgentRewindModeSchema = z.enum(["conversation", "files", "both"]);
|
|
|
|
export const AgentRewindRequestMessageSchema = z.object({
|
|
type: z.literal("agent.rewind.request"),
|
|
agentId: z.string(),
|
|
messageId: z.string(),
|
|
mode: AgentRewindModeSchema,
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const AgentRewindResponseMessageSchema = z.object({
|
|
type: z.literal("agent.rewind.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
agentId: z.string(),
|
|
ok: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const UpdateAgentResponseMessageSchema = z.object({
|
|
type: z.literal("update_agent_response"),
|
|
payload: AgentActionResponsePayloadSchema,
|
|
});
|
|
|
|
export const ProjectRenameResponsePayloadSchema = z.object({
|
|
requestId: z.string(),
|
|
projectId: z.string(),
|
|
accepted: z.boolean(),
|
|
customName: z.string().nullable(),
|
|
error: z.string().nullable(),
|
|
});
|
|
|
|
export const ProjectRenameResponseSchema = z.object({
|
|
type: z.literal("project.rename.response"),
|
|
payload: ProjectRenameResponsePayloadSchema,
|
|
});
|
|
|
|
export const ProjectIconSetResponseSchema = z.object({
|
|
type: z.literal("project.icon.set.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
projectId: z.string(),
|
|
accepted: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const ProjectRemoveResponsePayloadSchema = z.object({
|
|
requestId: z.string(),
|
|
projectId: z.string(),
|
|
accepted: z.boolean(),
|
|
removedWorkspaceIds: z.array(z.string()).default([]),
|
|
error: z.string().nullable(),
|
|
});
|
|
|
|
export const ProjectRemoveResponseSchema = z.object({
|
|
type: z.literal("project.remove.response"),
|
|
payload: ProjectRemoveResponsePayloadSchema,
|
|
});
|
|
|
|
export const WorkspaceTitleSetResponsePayloadSchema = z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
accepted: z.boolean(),
|
|
title: z.string().nullable(),
|
|
error: z.string().nullable(),
|
|
});
|
|
|
|
export const WorkspaceTitleSetResponseSchema = z.object({
|
|
type: z.literal("workspace.title.set.response"),
|
|
payload: WorkspaceTitleSetResponsePayloadSchema,
|
|
});
|
|
|
|
export const WorkspacePinSetResponsePayloadSchema = z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
accepted: z.boolean(),
|
|
pinnedAt: z.string().nullable(),
|
|
error: z.string().nullable(),
|
|
});
|
|
|
|
export const WorkspacePinSetResponseSchema = z.object({
|
|
type: z.literal("workspace.pin.set.response"),
|
|
payload: WorkspacePinSetResponsePayloadSchema,
|
|
});
|
|
|
|
export const WorkspaceRecoveryStateSchema = z.discriminatedUnion("kind", [
|
|
z.object({
|
|
kind: z.literal("recoverable"),
|
|
workspaceId: z.string(),
|
|
workspaceName: z.string(),
|
|
action: z.string(),
|
|
branch: z.string().nullable(),
|
|
}),
|
|
z.object({
|
|
kind: z.literal("unavailable"),
|
|
workspaceId: z.string(),
|
|
reason: z.string(),
|
|
message: z.string(),
|
|
}),
|
|
]);
|
|
|
|
export const WorkspaceRecoveryInspectResponseSchema = z.object({
|
|
type: z.literal("workspace.recovery.inspect.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
state: WorkspaceRecoveryStateSchema,
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceRecoveryRestoreResponseSchema = z.object({
|
|
type: z.literal("workspace.recovery.restore.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
accepted: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
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().optional(),
|
|
cwd: z.string(),
|
|
compare: CheckoutDiffCompareSchema,
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const CheckoutDiffGetRequestSchema = z.object({
|
|
type: z.literal("checkout.diff.get.request"),
|
|
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 CheckoutRefreshRequestSchema = z.object({
|
|
type: z.literal("checkout.refresh.request"),
|
|
cwd: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const CheckoutDiscardChangesRequestSchema = z.object({
|
|
type: z.literal("checkout.discard_changes.request"),
|
|
cwd: z.string(),
|
|
paths: z.array(z.string()).min(1),
|
|
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 CheckoutForgeSetAutoMergeRequestSchema = z.object({
|
|
type: z.literal("checkout.forge.set_auto_merge.request"),
|
|
cwd: z.string(),
|
|
enabled: z.boolean(),
|
|
mergeMethod: z.enum(["merge", "squash", "rebase"]).optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// COMPAT(githubAutoMergeRpc): legacy RPC retained when
|
|
// checkout.forge.set_auto_merge.* shipped in v0.2.0-beta.1. Stop serving and
|
|
// consuming it after 2027-01-17 once client and daemon floors are >= v0.2.0.
|
|
export const CheckoutGithubSetAutoMergeRequestSchema = z.object({
|
|
type: z.literal("checkout.github.set_auto_merge.request"),
|
|
cwd: z.string(),
|
|
enabled: z.boolean(),
|
|
mergeMethod: z.enum(["merge", "squash", "rebase"]).optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
const CheckoutCommitFileSchema = z.object({
|
|
path: z.string(),
|
|
additions: z.number(),
|
|
deletions: z.number(),
|
|
status: z.enum(["added", "modified", "deleted", "renamed"]).optional(),
|
|
});
|
|
|
|
const CheckoutCommitSchema = z.object({
|
|
sha: z.string(),
|
|
shortSha: z.string(),
|
|
subject: z.string(),
|
|
authorName: z.string(),
|
|
authorDate: z.string(), // ISO 8601
|
|
isOnRemote: z.boolean(), // false = local-only (unpushed)
|
|
// COMPAT(commitBaseClassification): added in v0.2.0, remove optional after 2027-01-23.
|
|
isOnBase: z.boolean().optional(),
|
|
files: z.array(CheckoutCommitFileSchema),
|
|
});
|
|
|
|
export const CheckoutCommitsListRequestSchema = z.object({
|
|
type: z.literal("checkout.commits.list.request"),
|
|
cwd: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const CheckoutCommitFileDiffRequestSchema = z.object({
|
|
type: z.literal("checkout.commits.file_diff.request"),
|
|
cwd: z.string(),
|
|
sha: z.string(),
|
|
path: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
const GitHubRepoSegmentSchema = z.string().regex(/^[A-Za-z0-9._-]+$/);
|
|
|
|
const CheckoutCheckDetailsRequestPayloadSchema = z.object({
|
|
cwd: z.string(),
|
|
// GitHub addresses check runs by owner/name. GitLab resolves the project from
|
|
// cwd and omits these GitHub-only single-segment fields.
|
|
repoOwner: GitHubRepoSegmentSchema.optional(),
|
|
repoName: GitHubRepoSegmentSchema.optional(),
|
|
// Permanently optional: a check addressed only by workflowRunId (Gitea
|
|
// Actions runs carry no check-run id) is fetchable. Callers send at least one
|
|
// of checkRunId/workflowRunId; the gated forge RPC only reaches daemons that
|
|
// understand this.
|
|
checkRunId: z.number().int().positive().optional(),
|
|
workflowRunId: z.number().int().positive().optional(),
|
|
// Permanent forge-routing field, optional because only some forges need it:
|
|
// GitLab routes check details to the MR's head pipeline; Gitea-family adapters
|
|
// resolve the PR head SHA by number, including after merge/close. GitHub
|
|
// ignores it.
|
|
changeRequestNumber: z.number().int().positive().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const CheckoutForgeGetCheckDetailsRequestSchema =
|
|
CheckoutCheckDetailsRequestPayloadSchema.extend({
|
|
type: z.literal("checkout.forge.get_check_details.request"),
|
|
});
|
|
|
|
// COMPAT(githubCheckDetailsRpc): legacy RPC retained when
|
|
// checkout.forge.get_check_details.* shipped in v0.2.0-beta.1. Stop serving
|
|
// and consuming it after 2027-01-17 once client and daemon floors are >= v0.2.0.
|
|
export const CheckoutGithubGetCheckDetailsRequestSchema =
|
|
CheckoutCheckDetailsRequestPayloadSchema.extend({
|
|
type: z.literal("checkout.github.get_check_details.request"),
|
|
});
|
|
|
|
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 CheckoutRenameBranchRequestSchema = z.object({
|
|
type: z.literal("checkout.rename_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"]),
|
|
forge: z.string().optional(),
|
|
number: z.number(),
|
|
title: z.string(),
|
|
url: z.string(),
|
|
state: z.string(),
|
|
body: z.string().nullable(),
|
|
labels: z.array(z.string()),
|
|
projectPath: z.string().optional(),
|
|
baseRefName: z.string().nullable().optional(),
|
|
headRefName: z.string().nullable().optional(),
|
|
updatedAt: z.string().optional(),
|
|
});
|
|
|
|
export const ForgeSearchItemSchema = GitHubSearchItemSchema.extend({
|
|
kind: z.enum(["issue", "change_request"]),
|
|
});
|
|
|
|
// COMPAT(githubSearchKind): legacy GitHub kind aliases retained when neutral
|
|
// forge search shipped in v0.2.0-beta.1. Remove after 2027-01-17 together with
|
|
// the legacy github_search_request RPC.
|
|
export const ForgeSearchKindSchema = z.enum([
|
|
"issue",
|
|
"change_request",
|
|
"github-issue",
|
|
"github-pr",
|
|
"pr",
|
|
]);
|
|
|
|
export const GitHubSearchKindSchema = ForgeSearchKindSchema;
|
|
|
|
export const ForgeSearchRequestSchema = z.object({
|
|
type: z.literal("forge.search.request"),
|
|
cwd: z.string(),
|
|
query: z.string(),
|
|
limit: z.number().int().min(1).max(50).optional(),
|
|
kinds: z.array(ForgeSearchKindSchema).optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// COMPAT(githubSearchRpc): legacy RPC retained when forge.search.* shipped in
|
|
// v0.2.0-beta.1. Stop serving and consuming it after 2027-01-17 once client
|
|
// and daemon floors are >= v0.2.0.
|
|
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(),
|
|
matchMode: z.enum(["fuzzy", "suffix"]).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(),
|
|
// COMPAT(worktreeArchiveWorkspaceId): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
// Explicit workspace record to archive. A directory can back multiple workspaces
|
|
// (Model B), so resolving the target by cwd alone picks the wrong record. When
|
|
// present the daemon archives this exact workspace; when absent it falls back to
|
|
// resolving by worktreePath, preferring the worktree-kind record on a cwd tie.
|
|
workspaceId: z.string().optional(),
|
|
// COMPAT(worktreeArchiveScope): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
// Scope of the archive operation. "workspace" archives a single workspace record
|
|
// (today's default UI behavior). "worktree" archives every active workspace whose
|
|
// cwd resolves to the target directory, then removes the directory if it is
|
|
// Paseo-owned. Omitted/unknown values default to "workspace" for old-client safety.
|
|
scope: z.enum(["workspace", "worktree"]).optional().default("workspace"),
|
|
// COMPAT(worktreeDiskDeletion): added in v0.1.97, ignored as of v0.1.97
|
|
// (disk removal derived from scope + last-reference + ownership); field
|
|
// retained for wire parse-compat, drop when floor >= v0.1.97.
|
|
deleteWorktreeFromDisk: z.boolean().optional().default(false),
|
|
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(),
|
|
projectId: z.string().optional(),
|
|
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(),
|
|
checkoutSource: ChangeRequestCheckoutSourceSchema.optional(),
|
|
// COMPAT(githubPrNumber): legacy GitHub checkout input retained when
|
|
// checkoutSource shipped in v0.2.0-beta.1. Remove after 2027-01-17 once the
|
|
// supported client floor is >= v0.2.0.
|
|
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(),
|
|
});
|
|
|
|
export const WorkspaceSetupRunRequestSchema = z.object({
|
|
type: z.literal("workspace.setup.run.request"),
|
|
workspaceId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// COMPAT(desktopEditorBridge): added in v0.1.88, remove after 2026-12-03 once old clients no longer call daemon editor RPCs.
|
|
export const LegacyListAvailableEditorsRequestSchema = z.object({
|
|
type: z.literal("list_available_editors_request"),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const LegacyOpenInEditorRequestSchema = z.object({
|
|
type: z.literal("open_in_editor_request"),
|
|
path: z.string(),
|
|
editorId: z.string().trim().min(1),
|
|
mode: z.enum(["open", "reveal"]).optional(),
|
|
cwd: z.string().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const OpenProjectRequestSchema = z.object({
|
|
type: z.literal("open_project_request"),
|
|
// Path used only for workspace lookup/creation. Use the returned workspace.id for all subsequent references.
|
|
cwd: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// Smallest shorthand repo path is "a/b": owner, slash, repository.
|
|
const MIN_REPOSITORY_PATH_LENGTH = 3;
|
|
|
|
export const ProjectAddRequestSchema = z.object({
|
|
type: z.literal("project.add.request"),
|
|
cwd: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectCreateDirectoryRequestSchema = z.object({
|
|
type: z.literal("project.create_directory.request"),
|
|
parentPath: z.string(),
|
|
name: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const GithubRepositorySchema = z.object({
|
|
id: z.string().min(1),
|
|
name: z.string().min(1),
|
|
nameWithOwner: z.string().min(MIN_REPOSITORY_PATH_LENGTH),
|
|
description: z.string().nullable(),
|
|
visibility: z.enum(["public", "private", "internal"]),
|
|
updatedAt: z.string(),
|
|
cloneUrl: z.string().min(MIN_REPOSITORY_PATH_LENGTH),
|
|
});
|
|
|
|
export const WorkspaceGithubSearchRepositoriesRequestSchema = z.object({
|
|
type: z.literal("workspace.github.search_repositories.request"),
|
|
query: z.string(),
|
|
limit: z.number().int().min(1).max(50).optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectGithubCloneProtocolSchema = z.enum(["https", "ssh"]);
|
|
|
|
export const ProjectGithubCloneRequestSchema = z.object({
|
|
type: z.literal("project.github.clone.request"),
|
|
repo: z.string().trim().min(MIN_REPOSITORY_PATH_LENGTH),
|
|
cloneProtocol: ProjectGithubCloneProtocolSchema.optional(),
|
|
targetDirectory: z.string().trim().min(1),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ArchiveWorkspaceRequestSchema = z.object({
|
|
type: z.literal("archive_workspace_request"),
|
|
workspaceId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
// Create a new workspace record. Unlike open_project, this never deduplicates by
|
|
// directory: it always produces a fresh workspace. The source discriminates
|
|
// between an existing local directory and a newly created paseo worktree.
|
|
export const WorkspaceCreateRequestSchema = z.object({
|
|
type: z.literal("workspace.create.request"),
|
|
workspaceId: z
|
|
.string()
|
|
.regex(/^wks_[a-f0-9]{16}$/)
|
|
.optional(),
|
|
agent: WorkspaceInitialAgentSchema.optional(),
|
|
subscribe: z.boolean().optional(),
|
|
requestId: z.string(),
|
|
idempotencyKey: z.string().min(1).max(512).optional(),
|
|
// Optional user-set title applied to the created workspace.
|
|
title: z.string().optional(),
|
|
// Optional prompt context for workspace-level name/branch generation.
|
|
firstAgentContext: FirstAgentContextSchema.optional(),
|
|
source: z.discriminatedUnion("kind", [
|
|
z.object({
|
|
kind: z.literal("directory"),
|
|
// Path of the existing checkout/directory to back the workspace.
|
|
path: z.string(),
|
|
projectId: z.string().optional(),
|
|
}),
|
|
z.object({
|
|
kind: z.literal("worktree"),
|
|
// The project whose repo the worktree is cut from.
|
|
cwd: z.string().optional(),
|
|
projectId: z.string().optional(),
|
|
action: z.enum(["branch-off", "checkout"]).optional(),
|
|
// Target branch for checkout, or base ref for branch-off.
|
|
refName: z.string().min(1).optional(),
|
|
baseBranch: z.string().optional(),
|
|
// New branch name for branch-off. The worktree path may use a different slug.
|
|
branchName: z.string().min(1).optional(),
|
|
checkoutSource: ChangeRequestCheckoutSourceSchema.optional(),
|
|
// COMPAT(githubPrNumber): legacy GitHub checkout input retained when
|
|
// checkoutSource shipped in v0.2.0-beta.1. Remove after 2027-01-17 once
|
|
// the supported client floor is >= v0.2.0.
|
|
githubPrNumber: z.number().int().positive().optional(),
|
|
worktreeSlug: z.string().optional(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
export const WorkspaceClearAttentionRequestSchema = z.object({
|
|
type: z.literal("workspace.clear_attention.request"),
|
|
workspaceId: z.union([z.string(), z.array(z.string())]),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceMarkUnreadRequestSchema = z.object({
|
|
type: z.literal("workspace.mark_unread.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(),
|
|
// COMPAT(diffOldPath): added in v0.3.0, remove gate after 2027-02-09.
|
|
oldPath: z.string().optional(),
|
|
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(),
|
|
revision: z.string().optional(),
|
|
});
|
|
|
|
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(),
|
|
maxBytes: z.number().int().positive().optional(),
|
|
});
|
|
|
|
export const FileVersionSchema = z.discriminatedUnion("status", [
|
|
z.object({
|
|
status: z.literal("ready"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
size: z.number().int().nonnegative(),
|
|
modifiedAt: z.string(),
|
|
revision: z.string().optional(),
|
|
}),
|
|
z.object({
|
|
status: z.literal("missing"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
}),
|
|
z.object({
|
|
status: z.literal("error"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
error: z.string(),
|
|
}),
|
|
]);
|
|
|
|
export const FileSubscribeRequestSchema = z.object({
|
|
type: z.literal("fs.file.subscribe.request"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
subscriptionId: z.string().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileUnsubscribeRequestSchema = z.object({
|
|
type: z.literal("fs.file.unsubscribe.request"),
|
|
subscriptionId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileWriteRequestSchema = z.object({
|
|
type: z.literal("fs.file.write.request"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
content: z.string(),
|
|
expectedModifiedAt: z.string(),
|
|
expectedRevision: z.string().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileEntryCreateRequestSchema = z.object({
|
|
type: z.literal("fs.entry.create.request"),
|
|
cwd: z.string(),
|
|
parentPath: z.string(),
|
|
name: z.string(),
|
|
kind: z.enum(["file", "directory"]),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileEntryRenameRequestSchema = z.object({
|
|
type: z.literal("fs.entry.rename.request"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
name: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileEntryDuplicateRequestSchema = z.object({
|
|
type: z.literal("fs.entry.duplicate.request"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const FileEntryDeleteRequestSchema = z.object({
|
|
type: z.literal("fs.entry.delete.request"),
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectIconRequestSchema = z.object({
|
|
type: z.literal("project_icon_request"),
|
|
cwd: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ProjectIconGetRequestSchema = z.object({
|
|
type: z.literal("project.icon.get.request"),
|
|
projectId: 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 FileUploadRequestSchema = z.object({
|
|
type: z.literal("file.upload.request"),
|
|
fileName: z.string().min(1),
|
|
mimeType: z.string().min(1),
|
|
size: z.number().int().nonnegative(),
|
|
modifiedAt: 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(),
|
|
// COMPAT(terminalFocusHeartbeat): added in v0.1.97, remove optional default after 2026-12-13 once old clients no longer send heartbeats without terminal focus.
|
|
focusedTerminalId: z.string().nullable().optional().default(null),
|
|
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.string(), 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(),
|
|
});
|
|
|
|
export const PushUnregisterRequestSchema = z.object({
|
|
type: z.literal("push.unregister.request"),
|
|
token: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const PushUnregisterResponseSchema = z.object({
|
|
type: z.literal("push.unregister.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
// ============================================================================
|
|
// Terminal Messages
|
|
// ============================================================================
|
|
|
|
export const ListTerminalsRequestSchema = z.object({
|
|
type: z.literal("list_terminals_request"),
|
|
cwd: z.string().optional(),
|
|
workspaceId: z.string().optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const SubscribeTerminalsRequestSchema = z.object({
|
|
type: z.literal("subscribe_terminals_request"),
|
|
requestId: z.string().optional(),
|
|
cwd: z.string(),
|
|
workspaceId: z.string().optional(),
|
|
});
|
|
|
|
export const UnsubscribeTerminalsRequestSchema = z.object({
|
|
type: z.literal("unsubscribe_terminals_request"),
|
|
cwd: z.string(),
|
|
workspaceId: z.string().optional(),
|
|
});
|
|
|
|
export const CreateTerminalRequestSchema = z.object({
|
|
type: z.literal("create_terminal_request"),
|
|
cwd: z.string(),
|
|
workspaceId: z.string().optional(),
|
|
name: z.string().optional(),
|
|
agentId: z.string().optional(),
|
|
command: z.string().optional(),
|
|
args: z.array(z.string()).optional(),
|
|
// Initial PTY size. Added in v0.1.107; the app no longer sends it (the estimate cache that fed
|
|
// it was removed — the pane-focus resize claim sizes the PTY instead). Kept and honored
|
|
// permanently: released v0.1.107 clients still send it, and programmatic callers may pass an
|
|
// exact size. Daemons without it start at 80x24 and the first resize corrects that.
|
|
size: z
|
|
.object({
|
|
rows: z.number().int().positive(),
|
|
cols: z.number().int().positive(),
|
|
})
|
|
.optional(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const RenameTerminalRequestSchema = z.object({
|
|
type: z.literal("terminal.rename.request"),
|
|
terminalId: z.string(),
|
|
title: z.string(),
|
|
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 WorkspaceScriptListRequestSchema = z.object({
|
|
type: z.literal("workspace.script.list.request"),
|
|
workspaceId: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceScriptStartRequestSchema = z.object({
|
|
type: z.literal("workspace.script.start.request"),
|
|
workspaceId: z.string(),
|
|
scriptName: z.string(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const WorkspaceScriptStopRequestSchema = z.object({
|
|
type: z.literal("workspace.script.stop.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(),
|
|
restore: z
|
|
.object({
|
|
mode: z.enum(["live", "visible-snapshot", "full-snapshot"]),
|
|
scrollbackLines: z.number().int().nonnegative().optional(),
|
|
size: z
|
|
.object({
|
|
rows: z.number().int().positive(),
|
|
cols: z.number().int().positive(),
|
|
})
|
|
.optional(),
|
|
})
|
|
.optional(),
|
|
});
|
|
|
|
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(),
|
|
intent: z.enum(["claim", "update"]).optional(),
|
|
}),
|
|
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 HubExecutionAgentCreateRequestSchema = z.object({
|
|
type: z.literal("hub.execution.agent.create.request"),
|
|
requestId: z.string(),
|
|
executionId: z.string(),
|
|
provider: z.string(),
|
|
cwd: z.string(),
|
|
prompt: z.string(),
|
|
// COMPAT(hubExecutionWorkspaceSelection): semantics retired in v0.3.1; remove after 2027-08-08 once the Hub floor no longer sends it.
|
|
workspaceId: z.string().optional(),
|
|
model: z.string().optional(),
|
|
modeId: z.string().optional(),
|
|
thinkingOptionId: z.string().optional(),
|
|
featureValues: z.record(z.string(), z.unknown()).optional(),
|
|
providerOptions: ProviderOptionsSchema.optional(),
|
|
toolPolicy: ToolPolicySchema.optional(),
|
|
env: z.record(z.string(), z.string()).optional(),
|
|
mcpServers: z.record(z.string(), McpServerConfigSchema).optional(),
|
|
worktree: CreateAgentWorktreeTargetSchema.optional(),
|
|
});
|
|
|
|
export type HubExecutionAgentCreateRequest = z.infer<typeof HubExecutionAgentCreateRequestSchema>;
|
|
|
|
export const HubExecutionAgentValidateRequestSchema = z.object({
|
|
type: z.literal("hub.execution.agent.validate.request"),
|
|
requestId: z.string(),
|
|
provider: z.string(),
|
|
model: z.string().optional(),
|
|
modeId: z.string().optional(),
|
|
thinkingOptionId: z.string().optional(),
|
|
providerOptions: ProviderOptionsSchema.optional(),
|
|
});
|
|
|
|
export type HubExecutionAgentValidateRequest = z.infer<
|
|
typeof HubExecutionAgentValidateRequestSchema
|
|
>;
|
|
|
|
const HubExecutionAgentCreateErrorSchema = z.discriminatedUnion("code", [
|
|
z.object({
|
|
code: z.literal("provider_options_invalid"),
|
|
provider: z.string(),
|
|
issues: z.array(
|
|
z.object({
|
|
path: z.array(z.union([z.string(), z.number()])),
|
|
message: z.string(),
|
|
}),
|
|
),
|
|
message: z.string(),
|
|
}),
|
|
z.object({
|
|
code: z.literal("tool_policy_unsupported"),
|
|
provider: z.string(),
|
|
message: z.string(),
|
|
}),
|
|
z.object({
|
|
code: z.literal("create_failed"),
|
|
message: z.string(),
|
|
}),
|
|
]);
|
|
|
|
export type HubExecutionAgentCreateError = z.infer<typeof HubExecutionAgentCreateErrorSchema>;
|
|
|
|
export const HubExecutionControlActionSchema = z.enum(["interrupt", "archive"]);
|
|
export type HubExecutionControlAction = z.infer<typeof HubExecutionControlActionSchema>;
|
|
|
|
export const HubExecutionControlRequestSchema = z.object({
|
|
type: z.literal("hub.execution.control.request"),
|
|
requestId: z.string(),
|
|
executionId: z.string(),
|
|
action: HubExecutionControlActionSchema,
|
|
});
|
|
|
|
export type HubExecutionControlRequest = z.infer<typeof HubExecutionControlRequestSchema>;
|
|
|
|
// These connection event streams have no directory bootstrap or timeline membership.
|
|
export const SessionEventSubscriptionSchema = z.enum([
|
|
"project.update",
|
|
"providers_snapshot_update",
|
|
"agent_attention_required",
|
|
"agent_permission_request",
|
|
"agent_permission_resolved",
|
|
"checkout_status_update",
|
|
"script_status_update",
|
|
"workspace_setup_progress",
|
|
"agent.provider_subagents.update",
|
|
"terminal_attention_required",
|
|
"status.server_info",
|
|
"status.daemon_config_changed",
|
|
"status.plugin_catalog_changed",
|
|
"status.plugin_settings_changed",
|
|
"activity_log",
|
|
"hub.execution.agent.update",
|
|
"hub.execution.agent.stream",
|
|
]);
|
|
export type SessionEventSubscription = z.infer<typeof SessionEventSubscriptionSchema>;
|
|
export const SessionEventsSetSubscriptionRequestSchema = z.object({
|
|
type: z.literal("session.events.set_subscription.request"),
|
|
requestId: z.string(),
|
|
events: z.array(SessionEventSubscriptionSchema),
|
|
notifications: z.boolean().optional(),
|
|
});
|
|
export const SessionEventsSetSubscriptionResponseSchema = z.object({
|
|
type: z.literal("session.events.set_subscription.response"),
|
|
payload: z.object({ requestId: z.string(), subscriptionId: z.string().optional() }),
|
|
});
|
|
|
|
export const BrowserHostRegisterRequestSchema = z.object({
|
|
type: z.literal("browser.host.register.request"),
|
|
requestId: z.string(),
|
|
hostKind: z.string().min(1),
|
|
supportedCommands: z.array(z.enum(BROWSER_AUTOMATION_COMMAND_NAMES)).min(1),
|
|
});
|
|
export const BrowserHostRegisterResponseSchema = z.object({
|
|
type: z.literal("browser.host.register.response"),
|
|
payload: z.object({ requestId: z.string(), subscriptionId: z.string() }),
|
|
});
|
|
|
|
export const SubscriptionReleaseRequestSchema = z.object({
|
|
type: z.literal("subscription.release.request"),
|
|
requestId: z.string(),
|
|
subscriptionId: z.string(),
|
|
});
|
|
export const SubscriptionReleaseResponseSchema = z.object({
|
|
type: z.literal("subscription.release.response"),
|
|
payload: z.object({ requestId: z.string(), subscriptionId: z.string() }),
|
|
});
|
|
|
|
export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
|
|
BrowserHostRegisterRequestSchema,
|
|
SubscriptionReleaseRequestSchema,
|
|
SessionEventsSetSubscriptionRequestSchema,
|
|
HubExecutionAgentCreateRequestSchema,
|
|
HubExecutionAgentValidateRequestSchema,
|
|
HubExecutionControlRequestSchema,
|
|
BrowserAutomationExecuteResponseSchema,
|
|
VoiceAudioChunkMessageSchema,
|
|
AbortRequestMessageSchema,
|
|
AudioPlayedMessageSchema,
|
|
FetchAgentsRequestMessageSchema,
|
|
FetchAgentHistoryRequestMessageSchema,
|
|
FetchRecentProviderSessionsRequestMessageSchema,
|
|
FetchWorkspacesRequestMessageSchema,
|
|
ProjectListRequestMessageSchema,
|
|
FetchAgentRequestMessageSchema,
|
|
DeleteAgentRequestMessageSchema,
|
|
ArchiveAgentRequestMessageSchema,
|
|
CloseItemsRequestMessageSchema,
|
|
UpdateAgentRequestMessageSchema,
|
|
ProjectRenameRequestSchema,
|
|
ProjectIconSetRequestSchema,
|
|
ProjectRemoveRequestSchema,
|
|
WorkspaceTitleSetRequestSchema,
|
|
WorkspacePinSetRequestSchema,
|
|
WorkspaceLabelListRequestSchema,
|
|
WorkspaceLabelAssignmentSetRequestSchema,
|
|
WorkspaceLabelUpdateRequestSchema,
|
|
WorkspaceLabelDeleteRequestSchema,
|
|
WorkspaceLabelDeleteInspectRequestSchema,
|
|
WorkspaceRecoveryInspectRequestSchema,
|
|
WorkspaceRecoveryRestoreRequestSchema,
|
|
SetVoiceModeMessageSchema,
|
|
SendAgentMessageRequestSchema,
|
|
WaitForFinishRequestSchema,
|
|
DaemonGetStatusRequestSchema,
|
|
DaemonGetPairingOfferRequestSchema,
|
|
DaemonConfigReloadRequestSchema,
|
|
HubManagementDaemonConnectRequestSchema,
|
|
HubManagementDaemonGetStatusRequestSchema,
|
|
HubManagementDaemonDisconnectRequestSchema,
|
|
HubManagementDaemonPermissionsUpdateRequestSchema,
|
|
DiagnosticsRequestSchema,
|
|
PluginCatalogGetRequestSchema,
|
|
PluginListRequestSchema,
|
|
PluginLogsGetRequestSchema,
|
|
PluginDirectoryInstallRequestSchema,
|
|
PluginDirectoryInspectRequestSchema,
|
|
PluginSourceInstallRequestSchema,
|
|
PluginSourceStatusRequestSchema,
|
|
PluginSourceUpdateRequestSchema,
|
|
PluginUpdatePreviewRequestSchema,
|
|
PluginUpdateApplyRequestSchema,
|
|
PluginReloadRequestSchema,
|
|
PluginEnableRequestSchema,
|
|
PluginDisableRequestSchema,
|
|
PluginRemoveRequestSchema,
|
|
PluginRpcInvokeRequestSchema,
|
|
AgentTimelineAppendRequestSchema,
|
|
AgentSkillsGetStatusRequestSchema,
|
|
AgentSkillsReconcileRequestSchema,
|
|
AgentSkillsUninstallRequestSchema,
|
|
AgentSkillsSaveSelectionRequestSchema,
|
|
AgentSkillsImportLegacySelectionRequestSchema,
|
|
GetDaemonConfigRequestMessageSchema,
|
|
SetDaemonConfigRequestMessageSchema,
|
|
ReadProjectConfigRequestMessageSchema,
|
|
WriteProjectConfigRequestMessageSchema,
|
|
DictationStreamStartMessageSchema,
|
|
DictationStreamChunkMessageSchema,
|
|
DictationStreamFinishMessageSchema,
|
|
DictationStreamCancelMessageSchema,
|
|
CreateAgentRequestMessageSchema,
|
|
ListProviderModelsRequestMessageSchema,
|
|
ListProviderModesRequestMessageSchema,
|
|
ListProviderFeaturesRequestMessageSchema,
|
|
ListAvailableProvidersRequestMessageSchema,
|
|
GetProvidersSnapshotRequestMessageSchema,
|
|
RefreshProvidersSnapshotRequestMessageSchema,
|
|
ProviderDiagnosticRequestMessageSchema,
|
|
ProviderUsageListRequestMessageSchema,
|
|
UsageListReportsRequestMessageSchema,
|
|
ResumeAgentRequestMessageSchema,
|
|
ImportAgentRequestMessageSchema,
|
|
RefreshAgentRequestMessageSchema,
|
|
CancelAgentRequestMessageSchema,
|
|
ShutdownServerRequestMessageSchema,
|
|
RestartServerRequestMessageSchema,
|
|
DaemonUpdateRequestMessageSchema,
|
|
FetchAgentTimelineRequestMessageSchema,
|
|
AgentTimelineSearchRequestMessageSchema,
|
|
AgentTimelineListPromptsRequestMessageSchema,
|
|
ProviderSubagentListRequestMessageSchema,
|
|
ProviderSubagentTimelineRequestMessageSchema,
|
|
SetAgentTimelineSubscriptionRequestMessageSchema,
|
|
AgentForkContextRequestMessageSchema,
|
|
SetAgentModeRequestMessageSchema,
|
|
SetAgentModelRequestMessageSchema,
|
|
SetAgentThinkingRequestMessageSchema,
|
|
SetAgentFeatureRequestMessageSchema,
|
|
AgentConfigApplyRequestMessageSchema,
|
|
AgentDetachRequestMessageSchema,
|
|
AgentRewindRequestMessageSchema,
|
|
AgentPermissionResponseMessageSchema,
|
|
CheckoutStatusRequestSchema,
|
|
CheckoutDiffGetRequestSchema,
|
|
SubscribeCheckoutDiffRequestSchema,
|
|
UnsubscribeCheckoutDiffRequestSchema,
|
|
CheckoutCommitRequestSchema,
|
|
CheckoutMergeRequestSchema,
|
|
CheckoutMergeFromBaseRequestSchema,
|
|
CheckoutPullRequestSchema,
|
|
CheckoutPushRequestSchema,
|
|
CheckoutRefreshRequestSchema,
|
|
CheckoutDiscardChangesRequestSchema,
|
|
CheckoutPrCreateRequestSchema,
|
|
CheckoutPrMergeRequestSchema,
|
|
CheckoutForgeSetAutoMergeRequestSchema,
|
|
CheckoutGithubSetAutoMergeRequestSchema,
|
|
CheckoutCommitsListRequestSchema,
|
|
CheckoutCommitFileDiffRequestSchema,
|
|
CheckoutForgeGetCheckDetailsRequestSchema,
|
|
CheckoutGithubGetCheckDetailsRequestSchema,
|
|
CheckoutPrStatusRequestSchema,
|
|
PullRequestTimelineRequestSchema,
|
|
CheckoutSwitchBranchRequestSchema,
|
|
CheckoutRenameBranchRequestSchema,
|
|
StashSaveRequestSchema,
|
|
StashPopRequestSchema,
|
|
StashListRequestSchema,
|
|
ValidateBranchRequestSchema,
|
|
BranchSuggestionsRequestSchema,
|
|
ForgeSearchRequestSchema,
|
|
GitHubSearchRequestSchema,
|
|
DirectorySuggestionsRequestSchema,
|
|
PaseoWorktreeListRequestSchema,
|
|
PaseoWorktreeArchiveRequestSchema,
|
|
CreatePaseoWorktreeRequestSchema,
|
|
WorkspaceSetupStatusRequestSchema,
|
|
WorkspaceSetupRunRequestSchema,
|
|
LegacyListAvailableEditorsRequestSchema,
|
|
LegacyOpenInEditorRequestSchema,
|
|
OpenProjectRequestSchema,
|
|
ProjectAddRequestSchema,
|
|
ProjectCreateDirectoryRequestSchema,
|
|
WorkspaceGithubSearchRepositoriesRequestSchema,
|
|
ProjectGithubCloneRequestSchema,
|
|
ArchiveWorkspaceRequestSchema,
|
|
WorkspaceCreateRequestSchema,
|
|
AgentCreateRequestSchema,
|
|
CreationSubscribeRequestSchema,
|
|
WorkspaceClearAttentionRequestSchema,
|
|
WorkspaceMarkUnreadRequestSchema,
|
|
FileExplorerRequestSchema,
|
|
FileSubscribeRequestSchema,
|
|
FileUnsubscribeRequestSchema,
|
|
FileWriteRequestSchema,
|
|
FileEntryCreateRequestSchema,
|
|
FileEntryRenameRequestSchema,
|
|
FileEntryDuplicateRequestSchema,
|
|
FileEntryDeleteRequestSchema,
|
|
ProjectIconRequestSchema,
|
|
ProjectIconGetRequestSchema,
|
|
FileDownloadTokenRequestSchema,
|
|
FileUploadRequestSchema,
|
|
ClearAgentAttentionMessageSchema,
|
|
ClientHeartbeatMessageSchema,
|
|
PingMessageSchema,
|
|
ListCommandsRequestSchema,
|
|
RegisterPushTokenMessageSchema,
|
|
PushUnregisterRequestSchema,
|
|
ListTerminalsRequestSchema,
|
|
SubscribeTerminalsRequestSchema,
|
|
UnsubscribeTerminalsRequestSchema,
|
|
CreateTerminalRequestSchema,
|
|
RenameTerminalRequestSchema,
|
|
StartWorkspaceScriptRequestSchema,
|
|
WorkspaceScriptListRequestSchema,
|
|
WorkspaceScriptStartRequestSchema,
|
|
WorkspaceScriptStopRequestSchema,
|
|
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<typeof SessionInboundMessageSchema>;
|
|
|
|
// ============================================================================
|
|
// Session Outbound Messages (Session emits these)
|
|
// ============================================================================
|
|
|
|
export const ActivityLogPayloadSchema = z.object({
|
|
subscriptionId: z.string().optional(),
|
|
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.string(), 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<typeof ServerCapabilitiesSchema> | 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"),
|
|
protocolVersion: z.number().int().optional(),
|
|
serverId: z.string().trim().min(1),
|
|
hostname: ServerInfoHostnameSchema.optional(),
|
|
version: ServerInfoVersionSchema.optional(),
|
|
// COMPAT(sessionPermissions): optional while clients support older daemons.
|
|
permissions: z.array(DaemonPermissionSchema).optional(),
|
|
// COMPAT(desktopManaged): added in v0.1.X, remove optional parsing after 2027-01-16.
|
|
desktopManaged: z.boolean().optional(),
|
|
capabilities: ServerCapabilitiesFromUnknownSchema.optional(),
|
|
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
features: z
|
|
.object({
|
|
// COMPAT(agentRequestReceipts): added in v0.8.0; remove gate after 2027-03-05.
|
|
agentRequestReceipts: z.boolean().optional(),
|
|
// COMPAT(workspaceRequestReceipts): added in v0.8.0; remove gate after 2027-03-07.
|
|
workspaceRequestReceipts: z.boolean().optional(),
|
|
creationLifecycle: z.boolean().optional(),
|
|
// COMPAT(hubAgentRpc): added in v0.8.0; remove gate after 2027-03-05.
|
|
hubAgentRpc: z.boolean().optional(),
|
|
providersSnapshot: z.boolean().optional(),
|
|
usageSources: z.boolean().optional(),
|
|
// COMPAT(providersSnapshotCwd): added in v0.3.2, remove gate after 2027-02-10.
|
|
providersSnapshotCwd: z.boolean().optional(),
|
|
// COMPAT(directorySync): added in v0.3.x, remove gate after 2027-02-12.
|
|
directorySync: z.boolean().optional(),
|
|
// COMPAT(workspaceLabels): added in v0.5.0, remove after 2027-08-14.
|
|
workspaceLabels: z.boolean().optional(),
|
|
// COMPAT(workspaceSetupRun): added in v0.8.0, remove gate after 2027-09-02.
|
|
workspaceSetupRun: z.boolean().optional(),
|
|
// COMPAT(workspaceTerminals): added in v0.8.0, remove gate after 2027-09-05.
|
|
workspaceTerminals: z.boolean().optional(),
|
|
// COMPAT(checkoutForgeSetAutoMerge): added in v0.2.0-beta.1. Remove the
|
|
// feature gate and checkoutGithubSetAutoMerge fallback after 2027-01-17
|
|
// once the supported daemon floor is >= v0.2.0.
|
|
checkoutForgeSetAutoMerge: z.boolean().optional(),
|
|
// COMPAT(checkoutGithubSetAutoMerge): added in v0.1.75 and retained as
|
|
// the fallback for checkoutForgeSetAutoMerge. Stop advertising and
|
|
// consuming it after 2027-01-17 once supported floors are >= v0.2.0.
|
|
checkoutGithubSetAutoMerge: z.boolean().optional(),
|
|
// COMPAT(githubCheckDetails): added in v0.1.92 and retained as the
|
|
// fallback for forgeCheckDetails. Stop advertising and consuming it
|
|
// after 2027-01-17 once supported floors are >= v0.2.0.
|
|
githubCheckDetails: z.boolean().optional(),
|
|
// COMPAT(forgeCheckDetails): added in v0.2.0-beta.1. Remove the feature
|
|
// gate and githubCheckDetails fallback after 2027-01-17 once the
|
|
// supported daemon floor is >= v0.2.0.
|
|
forgeCheckDetails: z.boolean().optional(),
|
|
// COMPAT(forgeSearch): added in v0.2.0-beta.1. Remove the feature gate
|
|
// and github_search fallback after 2027-01-17 once the supported daemon
|
|
// floor is >= v0.2.0.
|
|
forgeSearch: z.boolean().optional(),
|
|
// COMPAT(daemonStatusRpc): added in v0.1.76, remove gate after 2026-11-18.
|
|
daemonStatusRpc: z.boolean().optional(),
|
|
// COMPAT(daemonConfigReload): added in v0.4.0, remove gate after 2027-02-14.
|
|
daemonConfigReload: z.boolean().optional(),
|
|
// COMPAT(relayConfig): added in v0.2.6, remove gate after 2027-01-31.
|
|
relayConfig: z.boolean().optional(),
|
|
// COMPAT(pushTokenRevocation): added in v0.3.2, remove gate after 2027-02-10.
|
|
pushTokenRevocation: z.boolean().optional(),
|
|
// COMPAT(plugins): added in v0.3.0, remove gate after 2027-08-07.
|
|
plugins: z.boolean().optional(),
|
|
// COMPAT(pluginManagement): added in v0.4.0, remove gate after 2027-08-14.
|
|
pluginManagement: z.boolean().optional(),
|
|
// COMPAT(pluginLogs): added in v0.4.0, remove gate after 2027-08-16.
|
|
pluginLogs: z.boolean().optional(),
|
|
// COMPAT(pluginGitManagement): added in v0.7.0, remove gate after 2027-08-26.
|
|
pluginGitManagement: z.boolean().optional(),
|
|
// COMPAT(pluginSourceInstallation): added in v0.8.0; remove gate after 2027-03-16 once daemon floor supports source identifiers.
|
|
pluginSourceInstallation: z.boolean().optional(),
|
|
// COMPAT(pluginSourceUpdates): added in v0.8.0; remove gate after 2027-03-16 once daemon floor supports reviewed updates.
|
|
pluginSourceUpdates: z.boolean().optional(),
|
|
// COMPAT(pluginThemes): added in v0.5.0, remove gate after 2027-08-20.
|
|
// A daemon that predates this flag keeps `addTheme` in the server bundle it compiles,
|
|
// so a theme plugin cannot start there at all.
|
|
pluginThemes: z.boolean().optional(),
|
|
pluginSettings: z.boolean().optional(),
|
|
pluginTimelineItems: z.boolean().optional(),
|
|
// COMPAT(skillManagement): added in v0.4.0, remove gate after 2027-08-16.
|
|
skillManagement: z.boolean().optional(),
|
|
// COMPAT(terminalRestoreModes): added in v0.1.81, remove gate after 2026-11-23.
|
|
"terminal-restore-modes": z.boolean().optional(),
|
|
// COMPAT(terminalInputModeReplay): added in v0.2.6, remove gate after 2027-02-02.
|
|
"terminal-input-mode-replay": z.boolean().optional(),
|
|
// COMPAT(terminalSizeOwnership): added in v0.2.6, remove gate after 2027-02-02.
|
|
"terminal-size-ownership": z.boolean().optional(),
|
|
// COMPAT(rewind): added in v0.1.X, drop the gate when floor >= v0.1.X.
|
|
rewind: z.boolean().optional(),
|
|
// COMPAT(agentTimelinePromptIndex): added in v0.2.X, drop the gate when floor >= v0.2.X.
|
|
agentTimelinePromptIndex: z.boolean().optional(),
|
|
// COMPAT(agentHistorySearch): added in v0.3.0, remove gate after 2027-02-07.
|
|
agentHistorySearch: z.boolean().optional(),
|
|
// COMPAT(checkoutRefresh): added in v0.1.86, remove gate after 2026-11-29.
|
|
checkoutRefresh: z.boolean().optional(),
|
|
// COMPAT(workspaceMultiplicity): added in v0.1.97, drop the gate when floor >= v0.1.97
|
|
workspaceMultiplicity: z.boolean().optional(),
|
|
// COMPAT(projectRemove): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
projectRemove: z.boolean().optional(),
|
|
// COMPAT(projectAdd): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
projectAdd: z.boolean().optional(),
|
|
// COMPAT(worktreeRestore): added in v0.1.97, drop the gate when floor >= v0.1.97
|
|
worktreeRestore: z.boolean().optional(),
|
|
// COMPAT(workspaceRecovery): added in v0.1.105, remove after 2027-01-11 once daemon floor >= v0.1.105.
|
|
workspaceRecovery: z.boolean().optional(),
|
|
// COMPAT(workspaceFileEditing): added in v0.2.0, remove after 2027-01-18 once daemon floor >= v0.2.0.
|
|
workspaceFileEditing: z.boolean().optional(),
|
|
// COMPAT(providerUsageList): added in v0.1.98, drop the gate when daemon floor >= v0.1.98.
|
|
providerUsageList: z.boolean().optional(),
|
|
// COMPAT(agentDetach): added in v0.1.98, remove gate after 2026-12-19 once daemon floor >= v0.1.98.
|
|
agentDetach: z.boolean().optional(),
|
|
// COMPAT(agentThinkingUpdate): added in v0.2.4, remove gate after 2027-01-28.
|
|
agentThinkingUpdate: z.boolean().optional(),
|
|
// COMPAT(daemonDiagnostics): added in v0.1.100, remove gate after 2026-12-25 once daemon floor >= v0.1.100.
|
|
daemonDiagnostics: z.boolean().optional(),
|
|
// COMPAT(daemonSelfUpdate): added in v0.1.93, remove gate after 2026-12-13.
|
|
daemonSelfUpdate: z.boolean().optional(),
|
|
// COMPAT(agentForkContext): added in v0.1.102, remove gate after 2026-12-28.
|
|
agentForkContext: z.boolean().optional(),
|
|
// COMPAT(agentForkContextCursor): added in v0.1.108, remove gate after 2027-01-14.
|
|
agentForkContextCursor: z.boolean().optional(),
|
|
// COMPAT(providerSubagents): added in v0.1.107, remove gate after 2027-01-12.
|
|
providerSubagents: z.boolean().optional(),
|
|
// COMPAT(projectedSubagentTimeline): added after v0.8.0, remove gates after 2027-03-14; retain wire field.
|
|
projectedSubagentTimeline: z.boolean().optional(),
|
|
// COMPAT(providerSubagentNesting): added in v0.7, remove gate after 2027-03-04.
|
|
providerSubagentNesting: z.boolean().optional(),
|
|
// COMPAT(workspacePinning): added in v0.1.107, remove gate after 2027-01-12.
|
|
workspacePinning: z.boolean().optional(),
|
|
// COMPAT(workspaceMarkUnread): added in v0.5.0, remove after 2027-08-20.
|
|
workspaceMarkUnread: z.boolean().optional(),
|
|
// COMPAT(hubRelationship): added in v0.1.X, drop the gate when floor >= v0.1.X.
|
|
hubRelationship: z.boolean().optional(),
|
|
// COMPAT(projectGithubClone): added in v0.1.108, remove gate after 2027-01-15.
|
|
projectGithubClone: z.boolean().optional(),
|
|
// COMPAT(workspaceGithubRepositorySearch): added in v0.1.108, remove gate after 2027-01-15.
|
|
workspaceGithubRepositorySearch: z.boolean().optional(),
|
|
// COMPAT(projectCreateDirectory): added in v0.1.108, remove gate after 2027-01-15.
|
|
projectCreateDirectory: z.boolean().optional(),
|
|
// COMPAT(projectList): added in v0.2.4, drop the gate when floor >= v0.2.4.
|
|
projectList: z.boolean().optional(),
|
|
// COMPAT(commitsList): added in v0.1.110, remove gate after 2027-01-16.
|
|
commitsList: z.boolean().optional(),
|
|
// COMPAT(commitBaseClassification): added in v0.2.0, remove gate after 2027-01-23.
|
|
commitBaseClassification: z.boolean().optional(),
|
|
// COMPAT(providerRemoval): added in v0.1.105, drop the gate when floor >= v0.1.105.
|
|
providerRemoval: z.boolean().optional(),
|
|
// COMPAT(importSessionWorkspaceTarget): added in v0.1.110, remove gate after 2027-01-16.
|
|
importSessionWorkspaceTarget: z.boolean().optional(),
|
|
// COMPAT(importSessionSearch): added in v0.8.0, remove gate after 2027-03-02.
|
|
importSessionSearch: z.boolean().optional(),
|
|
// COMPAT(forgeProviders): added in v0.2.0-beta.1. Drop the gate after
|
|
// 2027-01-17 once the supported daemon floor is >= v0.2.0.
|
|
// Daemon advertises pluggable non-GitHub forge support (the forge registry);
|
|
// the client gates non-GitHub setup UI on it.
|
|
forgeProviders: z.boolean().optional(),
|
|
// COMPAT(selectiveAgentTimeline): added in v0.1.106, remove after 2027-01-12.
|
|
selectiveAgentTimeline: z.boolean().optional(),
|
|
explicitEventSubscriptions: z.boolean().optional(),
|
|
ownedSubscriptions: z.boolean().optional(),
|
|
// COMPAT(canonicalSubmittedPrompts): added in v0.2.6, remove gate after 2027-01-30.
|
|
canonicalSubmittedPrompts: z.boolean().optional(),
|
|
agentMessageProvenance: z.boolean().optional(),
|
|
// COMPAT(agentTurnIdentity): accept peers that observed pre-release v0.2.6 through 2027-01-31.
|
|
agentTurnIdentity: z.boolean().optional(),
|
|
// COMPAT(stableProjectIdentity): added in v0.1.109, remove gate after 2027-01-15.
|
|
stableProjectIdentity: z.boolean().optional(),
|
|
// COMPAT(workspaceScriptManagement): added in v0.1.105, remove gate after 2027-01-10.
|
|
workspaceScriptManagement: z.boolean().optional(),
|
|
// COMPAT(projectCustomIcon): added in v0.2.0, remove after 2027-01-20.
|
|
projectCustomIcon: z.boolean().optional(),
|
|
// COMPAT(fsEntryOps): added in v0.3.0, remove gate after 2027-02-08.
|
|
fsEntryOps: z.boolean().optional(),
|
|
// COMPAT(fsEntryDuplicate): added in v0.3.0, remove gate after 2027-02-09.
|
|
fsEntryDuplicate: z.boolean().optional(),
|
|
// COMPAT(checkoutDiscardChanges): added in v0.3.0, remove gate after 2027-02-08.
|
|
checkoutDiscardChanges: z.boolean().optional(),
|
|
// COMPAT(agentProfiles): added in v0.3.2, remove gate after 2027-02-11.
|
|
// An older daemon parses its persisted config strictly, so writing
|
|
// agentProfiles to one is silently dropped. The client hides the feature
|
|
// rather than letting a save appear to succeed.
|
|
agentProfiles: z.boolean().optional(),
|
|
// COMPAT(agentConfigApply): added in v0.3.2, remove gate after 2027-02-11.
|
|
agentConfigApply: 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 PluginCatalogChangedStatusPayloadSchema = z.object({
|
|
status: z.literal("plugin_catalog_changed"),
|
|
pluginId: PluginIdSchema,
|
|
});
|
|
|
|
export const PluginSettingsChangedStatusPayloadSchema = z.object({
|
|
status: z.literal("plugin_settings_changed"),
|
|
pluginId: PluginIdSchema,
|
|
settingsId: z.string(),
|
|
});
|
|
|
|
export const KnownStatusPayloadSchema = z.discriminatedUnion("status", [
|
|
AgentCreatedStatusPayloadSchema,
|
|
AgentCreateFailedStatusPayloadSchema,
|
|
AgentResumedStatusPayloadSchema,
|
|
AgentRefreshedStatusPayloadSchema,
|
|
ShutdownRequestedStatusPayloadSchema,
|
|
RestartRequestedStatusPayloadSchema,
|
|
DaemonConfigChangedStatusPayloadSchema,
|
|
PluginCatalogChangedStatusPayloadSchema,
|
|
PluginSettingsChangedStatusPayloadSchema,
|
|
]);
|
|
|
|
export type KnownStatusPayload = z.infer<typeof KnownStatusPayloadSchema>;
|
|
|
|
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(),
|
|
workspaceName: z.string().nullable().optional(),
|
|
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(),
|
|
localProxyUrl: z.string().nullable().optional(),
|
|
publicProxyUrl: z.string().nullable().optional(),
|
|
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();
|
|
|
|
export const WorkspaceGitHubRuntimePayloadSchema = z
|
|
.object({
|
|
featuresEnabled: z.boolean().optional(),
|
|
pullRequest: 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(),
|
|
mergeable: z.enum(["MERGEABLE", "CONFLICTING", "UNKNOWN"]).catch("UNKNOWN").optional(),
|
|
checks: z
|
|
.array(
|
|
z.object({
|
|
name: z.string(),
|
|
status: z.enum(["success", "failure", "pending", "skipped", "cancelled"]),
|
|
url: z.string().nullable(),
|
|
workflow: z.string().optional(),
|
|
duration: z.string().optional(),
|
|
// Open so future forge-neutral refinements remain parse-compatible.
|
|
traits: z.array(z.string()).optional(),
|
|
}),
|
|
)
|
|
.optional(),
|
|
checksStatus: z.enum(["none", "pending", "success", "failure"]).optional(),
|
|
reviewDecision: z.enum(["approved", "changes_requested", "pending"]).nullable().optional(),
|
|
repoOwner: z.string().optional(),
|
|
repoName: z.string().optional(),
|
|
github: z.unknown().optional(),
|
|
})
|
|
.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(),
|
|
// COMPAT(projectCustomName): added in v0.1.76, drop the optional gate when floor >= v0.1.76.
|
|
// When the user has renamed a project, projectDisplayName carries the resolved
|
|
// value (customName) and projectCustomName mirrors the raw override so the
|
|
// settings UI can prefill its input and offer a "reset" action.
|
|
projectCustomName: z.string().nullable().optional(),
|
|
// Identifies the project's stored custom icon; null means automatic.
|
|
// COMPAT(projectCustomIcon): added in v0.2.0, remove after 2027-01-20.
|
|
projectCustomIconRevision: z.string().nullable().optional(),
|
|
projectRootPath: z.string(),
|
|
workspaceDirectory: z.string().optional(),
|
|
// COMPAT(worktreeSlug): added in v0.2.6, remove optional after 2027-01-31.
|
|
// Present only for Paseo-owned worktrees; this is the basename of their root directory.
|
|
worktreeSlug: 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(),
|
|
// COMPAT(workspaceTitles): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
// When the user has titled a workspace, `name` carries the resolved value
|
|
// (title) and `title` mirrors the raw override so the rename UI can prefill
|
|
// its input and offer a "reset to branch name" action. Null means the name
|
|
// is derived from the branch/directory.
|
|
title: z.string().nullable().optional(),
|
|
// COMPAT(workspacePinning): added in v0.1.107, remove optional after 2027-01-12.
|
|
pinnedAt: z.string().nullable().optional(),
|
|
// COMPAT(workspaceLabels): added in v0.5.0, remove optional after 2027-08-14.
|
|
labels: z.array(z.string()).optional(),
|
|
archivingAt: z.string().nullable().optional().default(null),
|
|
status: WorkspaceStateBucketSchema,
|
|
// Best-effort workspace status entry timestamp. Old daemons omit the
|
|
// field; old clients treat missing and null equivalently. The transform
|
|
// coerces a missing field to `null` so downstream code never has to
|
|
// handle `undefined`.
|
|
statusEnteredAt: z
|
|
.string()
|
|
.nullish()
|
|
.transform((value) => value ?? null),
|
|
activityAt: z.string().nullable(),
|
|
diffStat: z
|
|
.object({
|
|
additions: z.number(),
|
|
deletions: z.number(),
|
|
})
|
|
.nullable()
|
|
.optional(),
|
|
scripts: z.array(WorkspaceScriptPayloadSchema).default([]),
|
|
gitRuntime: WorkspaceGitRuntimePayloadSchema,
|
|
// COMPAT(githubRuntimeName): legacy wire-field name now carries
|
|
// forge-neutral runtime data. Introduce and migrate to a neutral
|
|
// forgeRuntime field before consumers stop using this name. Target cleanup
|
|
// after 2027-01-17 once the supported client floor is >= v0.2.0.
|
|
githubRuntime: WorkspaceGitHubRuntimePayloadSchema,
|
|
// COMPAT(forge): added in v0.2.0-beta.1. Treat an absent forge as GitHub
|
|
// until 2027-01-17; remove the consumer fallback once the supported daemon
|
|
// floor is >= v0.2.0.
|
|
forge: z.string().optional(),
|
|
project: ProjectPlacementPayloadSchema.optional(),
|
|
// COMPAT(directorySync): sequence of this latest directory projection.
|
|
syncSeq: z.number().int().positive().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({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("upsert"),
|
|
agent: AgentSnapshotPayloadSchema,
|
|
project: ProjectPlacementPayloadSchema.nullable().optional(),
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("remove"),
|
|
agentId: z.string(),
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
export const AgentStreamMessageSchema = z.object({
|
|
type: z.literal("agent_stream"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
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),
|
|
}),
|
|
});
|
|
|
|
export const AgentSearchMatchFieldSchema = z.enum(["workspace", "title", "branch", "project"]);
|
|
|
|
export const AgentSearchMatchSchema = z.object({
|
|
field: AgentSearchMatchFieldSchema,
|
|
ranges: z.array(
|
|
z.object({
|
|
start: z.number().int().nonnegative(),
|
|
length: z.number().int().positive(),
|
|
}),
|
|
),
|
|
});
|
|
|
|
export type AgentSearchMatch = z.infer<typeof AgentSearchMatchSchema>;
|
|
|
|
const AgentDirectoryResponseEntrySchema = z.object({
|
|
agent: AgentSnapshotPayloadSchema,
|
|
project: ProjectPlacementPayloadSchema,
|
|
// Legacy relevance metadata remains accepted from older daemons.
|
|
// Current history responses use the requested chronological sort.
|
|
searchScore: z.number().optional(),
|
|
// Legacy server-generated highlights. Current clients highlight displayed text locally.
|
|
searchMatches: z.array(AgentSearchMatchSchema).optional(),
|
|
// COMPAT(directorySync): sequence of this latest directory projection.
|
|
syncSeq: z.number().int().positive().optional(),
|
|
});
|
|
|
|
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,
|
|
sync: DirectorySyncMetadataSchema.optional(),
|
|
}),
|
|
});
|
|
|
|
export const FetchAgentHistoryResponseMessageSchema = z.object({
|
|
type: z.literal("fetch_agent_history_response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
entries: z.array(AgentDirectoryResponseEntrySchema),
|
|
pageInfo: AgentDirectoryPageInfoSchema,
|
|
// Older daemons truncate relevance-ranked searches instead of returning a cursor.
|
|
searchTruncated: z.boolean().optional(),
|
|
}),
|
|
});
|
|
|
|
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(),
|
|
providerErrors: z
|
|
.array(
|
|
z.object({
|
|
provider: z.string(),
|
|
message: z.string(),
|
|
}),
|
|
)
|
|
.optional(),
|
|
}),
|
|
});
|
|
|
|
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
// A project parent that has zero active workspaces. The sidebar renders the
|
|
// project row with a new-workspace child so projects persist after their last
|
|
// workspace is archived.
|
|
export const WorkspaceProjectDescriptorPayloadSchema = z.object({
|
|
projectId: z.string(),
|
|
// COMPAT(projectKey): added in v0.2.4 on 2026-07-28; remove optional after 2027-01-28.
|
|
projectKey: z.string().optional(),
|
|
projectDisplayName: z.string(),
|
|
projectCustomName: z.string().nullable().optional(),
|
|
// COMPAT(projectCustomIcon): added in v0.2.0, remove after 2027-01-20.
|
|
projectCustomIconRevision: z.string().nullable().optional(),
|
|
// Fingerprints the effective icon, including automatic discovery and the
|
|
// absence of an icon. Clients may persist icon results against this value.
|
|
// COMPAT(projectIconCache): added in v0.2.7, remove optional after 2027-02-12.
|
|
projectIconRevision: z.string().optional(),
|
|
projectRootPath: z.string(),
|
|
projectKind: z.enum(["git", "non_git", "directory"]),
|
|
// COMPAT(directorySync): sequence of this latest directory projection.
|
|
syncSeq: z.number().int().positive().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),
|
|
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
// Project parents with no active workspaces. Old daemons omit it; old clients
|
|
// ignore it. Only populated on the first page (no cursor).
|
|
emptyProjects: z.array(WorkspaceProjectDescriptorPayloadSchema).optional().default([]),
|
|
pageInfo: z.object({
|
|
nextCursor: z.string().nullable(),
|
|
prevCursor: z.string().nullable(),
|
|
hasMore: z.boolean(),
|
|
}),
|
|
sync: DirectorySyncMetadataSchema.optional(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceUpdateMessageSchema = z.object({
|
|
type: z.literal("workspace_update"),
|
|
payload: z.discriminatedUnion("kind", [
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("upsert"),
|
|
workspace: WorkspaceDescriptorPayloadSchema,
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("remove"),
|
|
id: z.string(),
|
|
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
// When archiving this workspace leaves its project with no active
|
|
// workspaces, the daemon includes the project parent so the sidebar keeps
|
|
// rendering it without waiting for a full re-hydration. Old daemons omit
|
|
// it; old clients ignore it and surface the project on their next
|
|
// workspace fetch instead.
|
|
emptyProject: WorkspaceProjectDescriptorPayloadSchema.optional(),
|
|
// Project removal is represented on the existing workspace update channel
|
|
// so old clients can still parse the message and ignore the extra field.
|
|
removedProjectId: z.string().optional(),
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
const WorkspaceLabelSyncMetadataSchema = z.object({
|
|
mode: z.enum(["snapshot", "changes"]),
|
|
generation: z.string(),
|
|
headSeq: z.number().int().nonnegative(),
|
|
removals: z.array(z.object({ name: z.string(), seq: z.number().int().positive() })),
|
|
});
|
|
export const WorkspaceLabelListResponseSchema = z.object({
|
|
type: z.literal("workspace.label.list.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
subscriptionId: z.string().optional(),
|
|
labels: z.array(WorkspaceLabelDefinitionSchema),
|
|
sync: WorkspaceLabelSyncMetadataSchema,
|
|
}),
|
|
});
|
|
export const WorkspaceLabelUpdateSchema = z.object({
|
|
type: z.literal("workspace.label.update"),
|
|
payload: z.discriminatedUnion("kind", [
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("upsert"),
|
|
label: WorkspaceLabelDefinitionSchema,
|
|
previousName: z.string().optional(),
|
|
generation: z.string(),
|
|
seq: z.number().int().positive(),
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("remove"),
|
|
name: z.string(),
|
|
generation: z.string(),
|
|
seq: z.number().int().positive(),
|
|
}),
|
|
]),
|
|
});
|
|
export const WorkspaceLabelAssignmentSetResponseSchema = z.object({
|
|
type: z.literal("workspace.label.assignment.set.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
label: WorkspaceLabelDefinitionSchema,
|
|
workspaceLabels: z.array(z.string()),
|
|
}),
|
|
});
|
|
export const WorkspaceLabelUpdateResponseSchema = z.object({
|
|
type: z.literal("workspace.label.update.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
label: WorkspaceLabelDefinitionSchema,
|
|
affectedWorkspaceCount: z.number().int().nonnegative(),
|
|
}),
|
|
});
|
|
export const WorkspaceLabelDeleteResponseSchema = z.object({
|
|
type: z.literal("workspace.label.delete.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
affectedWorkspaceCount: z.number().int().nonnegative(),
|
|
}),
|
|
});
|
|
export const WorkspaceLabelDeleteInspectResponseSchema = z.object({
|
|
type: z.literal("workspace.label.delete.inspect.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
affectedWorkspaceCount: z.number().int().nonnegative(),
|
|
}),
|
|
});
|
|
|
|
export const ProjectUpdateMessageSchema = z.object({
|
|
type: z.literal("project.update"),
|
|
payload: z.discriminatedUnion("kind", [
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("upsert"),
|
|
project: WorkspaceProjectDescriptorPayloadSchema,
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("remove"),
|
|
projectId: z.string(),
|
|
generation: z.string().optional(),
|
|
seq: z.number().int().positive().optional(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
export const ProjectListResponseMessageSchema = z.object({
|
|
type: z.literal("project.list.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
projects: z.array(WorkspaceProjectDescriptorPayloadSchema),
|
|
sync: DirectorySyncMetadataSchema.optional(),
|
|
}),
|
|
});
|
|
|
|
export const ScriptStatusUpdateMessageSchema = z.object({
|
|
type: z.literal("script_status_update"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
workspaceId: z.string(),
|
|
scripts: z.array(WorkspaceScriptPayloadSchema),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceSetupProgressMessageSchema = z.object({
|
|
type: z.literal("workspace_setup_progress"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
workspaceId: z.string(),
|
|
status: z.enum(["running", "completed", "failed", "blocked"]),
|
|
detail: WorktreeSetupDetailPayloadSchema,
|
|
error: z.string().nullable(),
|
|
blockedSource: z
|
|
.object({
|
|
kind: z.literal("change_request"),
|
|
forge: z.string(),
|
|
number: z.number().int().positive(),
|
|
headRepository: z.string(),
|
|
})
|
|
.optional(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceSetupSnapshotSchema = z.object({
|
|
status: z.enum(["running", "completed", "failed", "blocked"]),
|
|
detail: WorktreeSetupDetailPayloadSchema,
|
|
error: z.string().nullable(),
|
|
blockedSource: z
|
|
.object({
|
|
kind: z.literal("change_request"),
|
|
forge: z.string(),
|
|
number: z.number().int().positive(),
|
|
headRepository: z.string(),
|
|
})
|
|
.optional(),
|
|
});
|
|
|
|
export const WorkspaceSetupRunResponseMessageSchema = z.object({
|
|
type: z.literal("workspace.setup.run.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
started: z.boolean(),
|
|
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(),
|
|
// Unknown codes from newer daemons degrade to null; clients fall back to `error`.
|
|
errorCode: z.enum(["directory_not_found"]).nullish().catch(null),
|
|
}),
|
|
});
|
|
|
|
export const ProjectAddResponseSchema = z.object({
|
|
type: z.literal("project.add.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
project: WorkspaceProjectDescriptorPayloadSchema.nullable(),
|
|
error: z.string().nullable(),
|
|
errorCode: z.enum(["directory_not_found"]).nullish().catch(null),
|
|
}),
|
|
});
|
|
|
|
export const ProjectCreateDirectoryErrorCodeSchema = z.enum([
|
|
"invalid_name",
|
|
"parent_directory_not_found",
|
|
"directory_exists",
|
|
"permission_denied",
|
|
"registration_failed",
|
|
"filesystem_error",
|
|
]);
|
|
|
|
export const ProjectCreateDirectoryResponseSchema = z.object({
|
|
type: z.literal("project.create_directory.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
directoryPath: z.string().nullable(),
|
|
project: WorkspaceProjectDescriptorPayloadSchema.nullable(),
|
|
error: z.string().nullable(),
|
|
// Error codes are open-ended on the wire so older clients can still parse
|
|
// responses after a newer daemon learns another failure reason.
|
|
errorCode: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceGithubSearchRepositoriesResponseSchema = z.object({
|
|
type: z.literal("workspace.github.search_repositories.response"),
|
|
payload: z.discriminatedUnion("status", [
|
|
z.object({
|
|
status: z.literal("success"),
|
|
requestId: z.string(),
|
|
repositories: z.array(GithubRepositorySchema),
|
|
available: z.literal(true),
|
|
error: z.null(),
|
|
}),
|
|
z.object({
|
|
status: z.literal("unavailable"),
|
|
requestId: z.string(),
|
|
repositories: z.array(GithubRepositorySchema),
|
|
reason: z.literal("gh_missing"),
|
|
available: z.literal(false),
|
|
error: z.string(),
|
|
}),
|
|
z.object({
|
|
status: z.literal("unauthenticated"),
|
|
requestId: z.string(),
|
|
repositories: z.array(GithubRepositorySchema),
|
|
available: z.literal(false),
|
|
error: z.string(),
|
|
}),
|
|
z.object({
|
|
status: z.literal("error"),
|
|
requestId: z.string(),
|
|
repositories: z.array(GithubRepositorySchema),
|
|
available: z.literal(true),
|
|
error: z.string(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
export const ProjectGithubCloneResponseSchema = z.object({
|
|
type: z.literal("project.github.clone.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
repo: z.string().trim().min(MIN_REPOSITORY_PATH_LENGTH),
|
|
checkoutPath: z.string().nullable(),
|
|
project: WorkspaceProjectDescriptorPayloadSchema.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(),
|
|
}),
|
|
});
|
|
|
|
const WorkspaceScriptOperationPayloadSchema = z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
scriptName: z.string().optional(),
|
|
script: WorkspaceScriptPayloadSchema.nullable().optional(),
|
|
scripts: z.array(WorkspaceScriptPayloadSchema).optional(),
|
|
error: z.string().nullable(),
|
|
});
|
|
|
|
export const WorkspaceScriptListResponseMessageSchema = z.object({
|
|
type: z.literal("workspace.script.list.response"),
|
|
payload: WorkspaceScriptOperationPayloadSchema,
|
|
});
|
|
|
|
export const WorkspaceScriptStartResponseMessageSchema = z.object({
|
|
type: z.literal("workspace.script.start.response"),
|
|
payload: WorkspaceScriptOperationPayloadSchema,
|
|
});
|
|
|
|
export const WorkspaceScriptStopResponseMessageSchema = z.object({
|
|
type: z.literal("workspace.script.stop.response"),
|
|
payload: WorkspaceScriptOperationPayloadSchema,
|
|
});
|
|
|
|
// COMPAT(desktopEditorBridge): added in v0.1.88, remove after 2026-12-03 once old clients no longer parse daemon editor RPC responses.
|
|
export const LegacyListAvailableEditorsResponseMessageSchema = z.object({
|
|
type: z.literal("list_available_editors_response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
editors: z.array(
|
|
z.object({
|
|
id: z.string().trim().min(1),
|
|
label: z.string(),
|
|
}),
|
|
),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const LegacyOpenInEditorResponseMessageSchema = 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,
|
|
turnId: z.string().optional(),
|
|
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", "identity"])),
|
|
});
|
|
|
|
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(),
|
|
mergeWindow: z.boolean().optional(),
|
|
entries: z.array(AgentTimelineEntryPayloadSchema),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const AgentTimelineReplacementMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.replacement"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
agentId: z.string(),
|
|
epoch: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const AgentTimelineSearchResponseMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.search.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
agentId: z.string(),
|
|
epoch: z.string(),
|
|
locations: z.array(
|
|
z.object({
|
|
seq: z.number().int().nonnegative(),
|
|
role: z.enum(["user", "assistant"]),
|
|
// Estimated occurrences in the message; the client verifies against rendered text.
|
|
// COMPAT(timelineSearchCount): added in v0.9.0, remove optional after 2027-09-22.
|
|
count: z.number().int().positive().optional(),
|
|
}),
|
|
),
|
|
nextCursor: z.number().int().nonnegative().nullable(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const AgentTimelineListPromptsResponseMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.list_prompts.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
agentId: z.string(),
|
|
epoch: z.string(),
|
|
prompts: z.array(
|
|
z.object({
|
|
seq: z.number().int().nonnegative(),
|
|
timestamp: z.string(),
|
|
preview: z.string(),
|
|
}),
|
|
),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const ProviderSubagentDescriptorPayloadSchema = z.object({
|
|
id: z.string(),
|
|
parentAgentId: z.string(),
|
|
// COMPAT(providerSubagentNesting): added in v0.7, remove optional after 2027-03-04.
|
|
parentSubagentId: z.string().nullable().optional(),
|
|
provider: AgentProviderSchema,
|
|
title: z.string().nullable(),
|
|
description: z.string().nullable(),
|
|
status: z.enum(["running", "completed", "failed", "canceled"]),
|
|
createdAt: z.string(),
|
|
updatedAt: z.string(),
|
|
toolCallId: z.string().nullable(),
|
|
cwd: z.string().nullable().optional(),
|
|
// Compact provider-owned context for the shared track. Providers choose what belongs here and
|
|
// format it for display; clients must not parse provider-specific facts out of this string.
|
|
subtitle: z.string().nullable().optional(),
|
|
});
|
|
|
|
export type ProviderSubagentDescriptorPayload = z.infer<
|
|
typeof ProviderSubagentDescriptorPayloadSchema
|
|
>;
|
|
|
|
export const ProviderSubagentListResponseMessageSchema = z.object({
|
|
type: z.literal("agent.provider_subagents.list.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
parentAgentId: z.string(),
|
|
subagents: z.array(ProviderSubagentDescriptorPayloadSchema),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const ProviderSubagentTimelineResponseMessageSchema = z.object({
|
|
type: z.literal("agent.provider_subagents.timeline.get.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
parentAgentId: z.string(),
|
|
subagentId: z.string(),
|
|
provider: AgentProviderSchema.nullable(),
|
|
direction: z.enum(["tail", "before", "after"]),
|
|
epoch: z.string(),
|
|
projection: z.literal("projected").optional(),
|
|
startCursor: AgentTimelineCursorSchema.nullable().optional(),
|
|
endCursor: AgentTimelineCursorSchema.nullable().optional(),
|
|
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(),
|
|
}),
|
|
hasOlder: z.boolean(),
|
|
hasNewer: z.boolean(),
|
|
rows: z.array(
|
|
z.object({
|
|
item: AgentTimelineItemPayloadSchema,
|
|
timestamp: z.string(),
|
|
seq: z.number().int().nonnegative(),
|
|
seqStart: z.number().int().nonnegative().optional(),
|
|
seqEnd: z.number().int().nonnegative().optional(),
|
|
sourceSeqRanges: z
|
|
.array(
|
|
z.object({
|
|
startSeq: z.number().int().nonnegative(),
|
|
endSeq: z.number().int().nonnegative(),
|
|
}),
|
|
)
|
|
.optional(),
|
|
}),
|
|
),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const ProviderSubagentUpdateMessageSchema = z.object({
|
|
type: z.literal("agent.provider_subagents.update"),
|
|
payload: z.discriminatedUnion("kind", [
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("upsert"),
|
|
subagent: ProviderSubagentDescriptorPayloadSchema,
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("timeline"),
|
|
parentAgentId: z.string(),
|
|
subagentId: z.string(),
|
|
provider: AgentProviderSchema,
|
|
item: AgentTimelineItemPayloadSchema,
|
|
timestamp: z.string(),
|
|
seq: z.number().int().nonnegative(),
|
|
epoch: z.string(),
|
|
}),
|
|
z.object({
|
|
subscriptionId: z.string().optional(),
|
|
kind: z.literal("remove"),
|
|
parentAgentId: z.string(),
|
|
subagentId: z.string(),
|
|
}),
|
|
]),
|
|
});
|
|
|
|
export const SetAgentTimelineSubscriptionResponseMessageSchema = z.object({
|
|
type: z.literal("agent.timeline.set_subscription.response"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
agentIds: z.array(z.string()),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const AgentAttentionRequiredMessageSchema = z.object({
|
|
type: z.literal("agent_attention_required"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
agentId: z.string(),
|
|
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(),
|
|
workspaceId: z.string().optional(),
|
|
agentId: z.string(),
|
|
reason: z.enum(["finished", "error", "permission"]),
|
|
}),
|
|
})
|
|
.optional(),
|
|
}),
|
|
});
|
|
|
|
export const AgentForkContextResponseMessageSchema = z.object({
|
|
type: z.literal("agent.fork_context.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
agentId: z.string(),
|
|
attachment: TextAttachmentSchema.nullable(),
|
|
itemCount: z.number().int().nonnegative(),
|
|
boundaryMessageId: z.string().nullable(),
|
|
boundaryCursor: AgentTimelineCursorSchema.nullable().optional(),
|
|
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(),
|
|
error: z.string().nullable().optional(),
|
|
}),
|
|
});
|
|
|
|
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 CreationSnapshotSchema = z.object({
|
|
kind: z.enum(["workspace", "agent"]),
|
|
idempotencyKey: z.string(),
|
|
revision: z.number().int().nonnegative(),
|
|
phase: z.enum([
|
|
"accepted",
|
|
"workspace_ready",
|
|
"agent_ready",
|
|
"prompt_started",
|
|
"completed",
|
|
"failed",
|
|
]),
|
|
workspaceId: z.string().nullable(),
|
|
agentId: z.string().nullable(),
|
|
workspace: WorkspaceDescriptorPayloadSchema.optional(),
|
|
agent: AgentSnapshotPayloadSchema.optional(),
|
|
error: z.string().nullable(),
|
|
setupSkippedReason: z.string().optional(),
|
|
errorCode: z.string().optional(),
|
|
failedStage: z.enum(["workspace", "agent", "prompt"]).optional(),
|
|
outcomeUnknown: z.boolean().optional(),
|
|
});
|
|
export type CreationSnapshot = z.infer<typeof CreationSnapshotSchema>;
|
|
export type AgentCreateRequest = z.infer<typeof AgentCreateRequestSchema>;
|
|
export type WorkspaceInitialAgent = z.infer<typeof WorkspaceInitialAgentSchema>;
|
|
|
|
export const WorkspaceCreationUpdateSchema = z.object({
|
|
type: z.literal("workspace.create.update"),
|
|
payload: CreationSnapshotSchema.extend({ subscriptionId: z.string().optional() }),
|
|
});
|
|
export const AgentCreationUpdateSchema = WorkspaceCreationUpdateSchema.extend({
|
|
type: z.literal("agent.create.update"),
|
|
});
|
|
export const CreationSubscribeResponseSchema = z.object({
|
|
type: z.literal("creation.subscribe.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
subscriptionId: z.string().optional(),
|
|
snapshot: CreationSnapshotSchema.nullable(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
export const AgentCreateResponseSchema = z.object({
|
|
type: z.literal("agent.create.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
agent: AgentSnapshotPayloadSchema.nullable(),
|
|
error: z.string().nullable(),
|
|
creation: CreationSnapshotSchema.optional(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceCreateResponseSchema = z.object({
|
|
type: z.literal("workspace.create.response"),
|
|
payload: z.object({
|
|
agent: AgentSnapshotPayloadSchema.optional(),
|
|
creation: CreationSnapshotSchema.optional(),
|
|
workspace: WorkspaceDescriptorPayloadSchema.nullable(),
|
|
setupTerminalId: z.string().nullable(),
|
|
setupSkippedReason: z.string().optional(),
|
|
error: z.string().nullable(),
|
|
errorCode: z.string().optional(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceClearAttentionResponseSchema = z.object({
|
|
type: z.literal("workspace.clear_attention.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.union([z.string(), z.array(z.string())]),
|
|
clearedAgentIds: z.array(z.string()),
|
|
results: z.array(
|
|
z.object({
|
|
workspaceId: z.string(),
|
|
clearedAgentIds: z.array(z.string()),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const WorkspaceMarkUnreadResponseSchema = z.object({
|
|
type: z.literal("workspace.mark_unread.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
workspaceId: z.string(),
|
|
markedAgentId: z.string().nullable(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
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 DaemonGetStatusResponseSchema = z.object({
|
|
type: z.literal("daemon.get_status.response"),
|
|
payload: z
|
|
.object({
|
|
requestId: z.string(),
|
|
serverId: z.string(),
|
|
version: z.string().nullable().optional(),
|
|
pid: z.number(),
|
|
nodePath: z.string(),
|
|
startedAt: z.string().nullable().optional(),
|
|
listen: z.string().nullable(),
|
|
relay: z
|
|
.object({
|
|
enabled: z.boolean(),
|
|
endpoint: z.string(),
|
|
publicEndpoint: z.string(),
|
|
useTls: z.boolean(),
|
|
publicUseTls: z.boolean(),
|
|
})
|
|
.nullable()
|
|
.optional(),
|
|
providers: z.array(
|
|
z.object({
|
|
provider: z.string(),
|
|
available: z.boolean(),
|
|
error: z.string().nullable().optional(),
|
|
}),
|
|
),
|
|
})
|
|
.passthrough(),
|
|
});
|
|
|
|
export const HubRelationshipStatusSchema = z.object({
|
|
state: z.enum([
|
|
"not_connected",
|
|
"connecting",
|
|
"connected",
|
|
"reconnecting",
|
|
"disconnecting",
|
|
"revoked",
|
|
]),
|
|
daemonId: z.string().nullable(),
|
|
hubOrigin: z.string().nullable(),
|
|
permissions: z.array(DaemonPermissionSchema),
|
|
connectedAt: z.string().nullable(),
|
|
lastError: z.string().nullable(),
|
|
});
|
|
export const HubManagementDaemonConnectResponseSchema = z.object({
|
|
type: z.literal("hub.management.daemon.connect.response"),
|
|
payload: z.object({ requestId: z.string(), status: HubRelationshipStatusSchema }),
|
|
});
|
|
export const HubManagementDaemonGetStatusResponseSchema = z.object({
|
|
type: z.literal("hub.management.daemon.get_status.response"),
|
|
payload: z.object({ requestId: z.string(), status: HubRelationshipStatusSchema }),
|
|
});
|
|
export const HubManagementDaemonDisconnectResponseSchema = z.object({
|
|
type: z.literal("hub.management.daemon.disconnect.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
status: HubRelationshipStatusSchema,
|
|
warning: z.string().optional(),
|
|
}),
|
|
});
|
|
export const HubManagementDaemonPermissionsUpdateResponseSchema = z.object({
|
|
type: z.literal("hub.management.daemon.permissions.update.response"),
|
|
payload: z.object({ requestId: z.string(), status: HubRelationshipStatusSchema }),
|
|
});
|
|
|
|
export const DaemonGetPairingOfferResponseSchema = z.object({
|
|
type: z.literal("daemon.get_pairing_offer.response"),
|
|
payload: z
|
|
.object({
|
|
requestId: z.string(),
|
|
url: z.string(),
|
|
qr: z.string().nullable().optional(),
|
|
relayEnabled: z.boolean(),
|
|
})
|
|
.passthrough(),
|
|
});
|
|
|
|
export const DaemonConfigReloadResponseSchema = z.object({
|
|
type: z.literal("daemon.config.reload.response"),
|
|
payload: z
|
|
.object({
|
|
requestId: z.string(),
|
|
appliedPaths: z.array(z.string()),
|
|
restartRequiredPaths: z.array(z.string()),
|
|
overrideControlledPaths: z.array(z.string()),
|
|
})
|
|
.passthrough(),
|
|
});
|
|
|
|
export const DiagnosticsResponseSchema = z.object({
|
|
type: z.literal("diagnostics.response"),
|
|
payload: z
|
|
.object({
|
|
requestId: z.string(),
|
|
diagnostic: z.string(),
|
|
})
|
|
.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"),
|
|
// zod-aot 0.2.0 miscompiles boolean discriminators as string options
|
|
// (`"true"`/`"false"`), so keep this sequential until upstream fixes it.
|
|
payload: z.union([
|
|
z.object({
|
|
requestId: z.string(),
|
|
repoRoot: z.string(),
|
|
ok: z.literal(true),
|
|
config: PaseoConfigRawSchema.nullable(),
|
|
revision: PaseoConfigRevisionSchema.nullable(),
|
|
hasUncommittedWorktreeSetupChanges: z.boolean().optional(),
|
|
}),
|
|
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"),
|
|
// zod-aot 0.2.0 miscompiles boolean discriminators as string options
|
|
// (`"true"`/`"false"`), so keep this sequential until upstream fixes it.
|
|
payload: z.union([
|
|
z.object({
|
|
requestId: z.string(),
|
|
repoRoot: z.string(),
|
|
ok: z.literal(true),
|
|
config: PaseoConfigRawSchema,
|
|
revision: PaseoConfigRevisionSchema,
|
|
hasUncommittedWorktreeSetupChanges: z.boolean().optional(),
|
|
}),
|
|
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({
|
|
subscriptionId: z.string().optional(),
|
|
agentId: z.string(),
|
|
request: AgentPermissionRequestPayloadSchema,
|
|
}),
|
|
});
|
|
|
|
export const AgentPermissionResolvedMessageSchema = z.object({
|
|
type: z.literal("agent_permission_resolved"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
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(),
|
|
// The full ref currentBranch tracks, as git resolves `<branch>@{upstream}`:
|
|
// "refs/remotes/origin/main", "refs/remotes/upstream/main" on a fork, or a
|
|
// "refs/heads/..." ref for a branch tracking a local branch. Null when there is no
|
|
// upstream. Clients use it verbatim — the remote is not necessarily origin and the
|
|
// upstream branch name is not necessarily currentBranch, so composing one is wrong.
|
|
// aheadOfOrigin/behindOfOrigin are measured against exactly this ref.
|
|
upstreamRef: z.string().nullable().optional(),
|
|
});
|
|
|
|
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,
|
|
]),
|
|
});
|
|
|
|
const CheckoutPrGithubAutoMergeRequestSchema = z
|
|
.object({
|
|
enabledAt: z.string().nullable().optional().default(null),
|
|
mergeMethod: z.string().nullable().optional().default(null),
|
|
enabledBy: z.string().nullable().optional().default(null),
|
|
})
|
|
.nullable()
|
|
.optional()
|
|
.default(null);
|
|
|
|
const CheckoutPrGithubRepositoryPolicySchema = z
|
|
.object({
|
|
autoMergeAllowed: z.boolean().optional().default(false),
|
|
mergeCommitAllowed: z.boolean().optional().default(false),
|
|
squashMergeAllowed: z.boolean().optional().default(false),
|
|
rebaseMergeAllowed: z.boolean().optional().default(false),
|
|
viewerDefaultMergeMethod: z.string().nullable().optional().default(null),
|
|
})
|
|
.optional()
|
|
.default({
|
|
autoMergeAllowed: false,
|
|
mergeCommitAllowed: false,
|
|
squashMergeAllowed: false,
|
|
rebaseMergeAllowed: false,
|
|
viewerDefaultMergeMethod: null,
|
|
});
|
|
|
|
const CheckoutPrGithubStatusObjectSchema = z.object({
|
|
mergeStateStatus: z.string().nullable().optional().default(null),
|
|
autoMergeRequest: CheckoutPrGithubAutoMergeRequestSchema,
|
|
viewerCanEnableAutoMerge: z.boolean().optional().default(false),
|
|
viewerCanDisableAutoMerge: z.boolean().optional().default(false),
|
|
viewerCanMergeAsAdmin: z.boolean().optional().default(false),
|
|
viewerCanUpdateBranch: z.boolean().optional().default(false),
|
|
repository: CheckoutPrGithubRepositoryPolicySchema,
|
|
isMergeQueueEnabled: z.boolean().optional().default(false),
|
|
isInMergeQueue: z.boolean().optional().default(false),
|
|
});
|
|
|
|
const CheckoutPrGithubStatusSchema = CheckoutPrGithubStatusObjectSchema.optional();
|
|
|
|
// The open facts envelope for forge-specific PR facts. Permanent — non-GitHub
|
|
// forges deliver their native facts through it. The transitional piece is the
|
|
// `github` mirror above, which stays populated for clients predating this
|
|
// envelope; see COMPAT(forgeSpecific) in status-projection.ts for the shim.
|
|
//
|
|
// NOTE: `forgeSpecific.forge` is a FACTS-FAMILY tag, not the workspace brand id.
|
|
// The whole Gitea family (gitea, forgejo, codeberg) emits `forge: "gitea"` here
|
|
// because they share one facts shape, while the top-level `forge` above carries
|
|
// the specific brand. Validation of family-specific payloads happens at runtime
|
|
// in the consumer that knows that forge family.
|
|
const CheckoutPrForgeSpecificSchema = z.unknown().optional();
|
|
|
|
export const CheckoutPrStatusSchema = z.object({
|
|
// COMPAT(forge): added in v0.2.0-beta.1. Remove the GitHub default after
|
|
// 2027-01-17 once the supported daemon floor is >= v0.2.0.
|
|
forge: z.string().optional().default("github"),
|
|
projectPath: z.string().optional(),
|
|
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(),
|
|
/**
|
|
* Formatted by the forge adapter: how long a finished check took, or how long a
|
|
* running one has been going. Raw timestamps stay off the wire.
|
|
*/
|
|
duration: z.string().optional(),
|
|
checkRunId: z.number().optional(),
|
|
workflowRunId: z.number().optional(),
|
|
// Open so future forge-neutral refinements remain parse-compatible.
|
|
traits: z.array(z.string()).optional(),
|
|
}),
|
|
)
|
|
.optional()
|
|
.default([]),
|
|
checksStatus: z.string().optional(),
|
|
reviewDecision: z.string().nullable().optional(),
|
|
repoOwner: z.string().optional(),
|
|
repoName: z.string().optional(),
|
|
github: CheckoutPrGithubStatusSchema,
|
|
forgeSpecific: CheckoutPrForgeSpecificSchema,
|
|
});
|
|
|
|
// Why a forge's PR/MR features are (un)available, so the client can offer the
|
|
// precise next step instead of a generic dead-end. Kept open on the wire so
|
|
// feature consumers can ignore values introduced by newer daemons.
|
|
export type ForgeAuthState =
|
|
| "authenticated"
|
|
| "unauthenticated"
|
|
| "cli_missing"
|
|
| "no_remote"
|
|
| "error";
|
|
|
|
export const ForgeAuthStateSchema = z.unknown().optional();
|
|
|
|
const CheckoutPrStatusPayloadSchema = z.object({
|
|
cwd: z.string(),
|
|
status: CheckoutPrStatusSchema.nullable(),
|
|
githubFeaturesEnabled: z.boolean(),
|
|
// COMPAT(forgeAuthState): added in v0.2.0-beta.1. Remove the legacy
|
|
// githubFeaturesEnabled normalization after 2027-01-17 once the supported
|
|
// daemon floor is >= v0.2.0.
|
|
authState: ForgeAuthStateSchema,
|
|
// COMPAT(forge): added in v0.2.0-beta.1. Remove the GitHub default after
|
|
// 2027-01-17 once the supported daemon floor is >= v0.2.0.
|
|
forge: z.string().optional().default("github"),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
const CheckoutStatusUpdateMetadataSchema = z.object({
|
|
subscriptionId: z.string().optional(),
|
|
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(),
|
|
// COMPAT(diffTooLarge): added in v0.2.4, keep optional until the daemon floor is v0.2.4.
|
|
diffTooLarge: z.boolean().optional(),
|
|
});
|
|
|
|
export const SubscribeCheckoutDiffResponseSchema = z.object({
|
|
type: z.literal("subscribe_checkout_diff_response"),
|
|
payload: CheckoutDiffSubscriptionPayloadSchema.extend({
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const CheckoutDiffGetResponseSchema = z.object({
|
|
type: z.literal("checkout.diff.get.response"),
|
|
payload: CheckoutDiffSubscriptionPayloadSchema.omit({ subscriptionId: true }).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 CheckoutRefreshResponseSchema = z.object({
|
|
type: z.literal("checkout.refresh.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 CheckoutForgeSetAutoMergeResponseSchema = z.object({
|
|
type: z.literal("checkout.forge.set_auto_merge.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
enabled: z.boolean(),
|
|
success: z.boolean(),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
// COMPAT(githubAutoMergeRpc): legacy RPC retained when
|
|
// checkout.forge.set_auto_merge.* shipped in v0.2.0-beta.1. Stop serving and
|
|
// consuming it after 2027-01-17 once client and daemon floors are >= v0.2.0.
|
|
export const CheckoutGithubSetAutoMergeResponseSchema = z.object({
|
|
type: z.literal("checkout.github.set_auto_merge.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
enabled: z.boolean(),
|
|
success: z.boolean(),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const CheckoutDiscardChangesResponseSchema = z.object({
|
|
type: z.literal("checkout.discard_changes.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
success: z.boolean(),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const CheckoutCommitsListResponseSchema = z.object({
|
|
type: z.literal("checkout.commits.list.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
baseRef: z.string().nullable(),
|
|
commits: z.array(CheckoutCommitSchema),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const CheckoutCommitFileDiffResponseSchema = z.object({
|
|
type: z.literal("checkout.commits.file_diff.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
sha: z.string(),
|
|
path: z.string(),
|
|
// null when the file is absent from the commit or carries no textual diff
|
|
// (e.g. binary-only changes).
|
|
file: ParsedDiffFileSchema.nullable(),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
const CheckoutGithubCheckAnnotationSchema = z.object({
|
|
path: z.string().optional(),
|
|
startLine: z.number().optional(),
|
|
endLine: z.number().optional(),
|
|
annotationLevel: z.string().optional(),
|
|
message: z.string().optional(),
|
|
title: z.string().optional(),
|
|
rawDetails: z.string().optional(),
|
|
});
|
|
|
|
const CheckoutGithubCheckJobSchema = z.object({
|
|
jobId: z.number(),
|
|
name: z.string(),
|
|
status: z.string().nullable().optional(),
|
|
conclusion: z.string().nullable().optional(),
|
|
url: z.string().nullable().optional(),
|
|
logTail: z.string().optional(),
|
|
logTruncated: z.boolean().optional(),
|
|
});
|
|
|
|
// Statuses stay open strings so future forge values cannot break parsing.
|
|
const CheckoutPipelineJobSchema = z.object({
|
|
id: z.number(),
|
|
name: z.string(),
|
|
stage: z.string(),
|
|
status: z.string(),
|
|
// COMPAT(pipelineRawStatus): no client reads this, but peers <= v0.2.0-rc.1
|
|
// validate it as required, so daemons must keep emitting it. Optional since
|
|
// this schema so future daemons may omit it; delete the field and its
|
|
// emission after 2027-01-17 once the supported client floor is >= v0.2.0.
|
|
rawStatus: z.string().optional(),
|
|
url: z.string().nullable().optional().default(null),
|
|
allowFailure: z.boolean().optional().default(false),
|
|
durationSeconds: z.number().nullable().optional().default(null),
|
|
});
|
|
|
|
const CheckoutPipelineStageSchema = z.object({
|
|
name: z.string(),
|
|
status: z.string(),
|
|
jobs: z.array(CheckoutPipelineJobSchema).optional().default([]),
|
|
});
|
|
|
|
const CheckoutPipelineSchema = z.object({
|
|
id: z.number(),
|
|
status: z.string(),
|
|
// COMPAT(pipelineRawStatus): see CheckoutPipelineJobSchema.rawStatus.
|
|
rawStatus: z.string().optional(),
|
|
url: z.string().nullable().optional().default(null),
|
|
ref: z.string().nullable().optional().default(null),
|
|
sha: z.string().nullable().optional().default(null),
|
|
stages: z.array(CheckoutPipelineStageSchema).optional().default([]),
|
|
});
|
|
|
|
export const CheckoutGithubCheckDetailsSchema = z.object({
|
|
checkRunId: z.number(),
|
|
workflowRunId: z.number().nullable().optional(),
|
|
name: z.string(),
|
|
status: z.string().nullable().optional(),
|
|
conclusion: z.string().nullable().optional(),
|
|
url: z.string().nullable().optional(),
|
|
detailsUrl: z.string().nullable().optional(),
|
|
output: z
|
|
.object({
|
|
title: z.string().nullable().optional(),
|
|
summary: z.string().nullable().optional(),
|
|
text: z.string().nullable().optional(),
|
|
})
|
|
.nullable()
|
|
.optional(),
|
|
annotations: z.array(CheckoutGithubCheckAnnotationSchema).optional().default([]),
|
|
failedJobs: z.array(CheckoutGithubCheckJobSchema).optional().default([]),
|
|
truncated: z.boolean().optional().default(false),
|
|
// No default: server CheckDetails keeps this optional and GitHub leaves it absent.
|
|
pipeline: CheckoutPipelineSchema.nullable().optional(),
|
|
});
|
|
|
|
export const CheckoutCheckDetailsSchema = CheckoutGithubCheckDetailsSchema;
|
|
|
|
export const CheckoutForgeGetCheckDetailsResponseSchema = z.object({
|
|
type: z.literal("checkout.forge.get_check_details.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
success: z.boolean(),
|
|
details: CheckoutCheckDetailsSchema.nullable().optional().default(null),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
// COMPAT(githubCheckDetailsRpc): legacy RPC retained when
|
|
// checkout.forge.get_check_details.* shipped in v0.2.0-beta.1. Stop serving
|
|
// and consuming it after 2027-01-17 once client and daemon floors are >= v0.2.0.
|
|
export const CheckoutGithubGetCheckDetailsResponseSchema = z.object({
|
|
type: z.literal("checkout.github.get_check_details.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
success: z.boolean(),
|
|
details: CheckoutCheckDetailsSchema.nullable().optional().default(null),
|
|
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<string, unknown>;
|
|
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"),
|
|
authorUrl: z.string().nullable().optional(),
|
|
avatarUrl: z.string().nullable().optional(),
|
|
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"),
|
|
authorUrl: z.string().nullable().optional(),
|
|
avatarUrl: z.string().nullable().optional(),
|
|
body: z.string().optional().default(""),
|
|
createdAt: z.number().optional().default(0),
|
|
url: z.string().optional().default(""),
|
|
// GitHub review id this inline comment belongs to; lets clients nest review
|
|
// threads under their parent review. Absent on issue comments and on
|
|
// timelines from daemons that predate the field.
|
|
reviewId: z.string().optional(),
|
|
// Forge-neutral discussion/thread id this comment belongs to, independent of a
|
|
// file position. GitLab maps its discussion id here so general (non-file)
|
|
// reply chains group into one thread; file-position threads also carry it.
|
|
// Absent on standalone comments and on timelines from daemons that predate it.
|
|
threadId: z.string().optional(),
|
|
// Forge-neutral resolution state for a thread that has no file position, e.g. a
|
|
// GitLab general (non-file) discussion that is resolvable. File-position threads
|
|
// carry their resolution under `location.isResolved` instead. Absent on ordinary
|
|
// comments, on forges that expose no thread resolution, and on older timelines.
|
|
threadIsResolved: z.boolean().optional(),
|
|
location: z
|
|
.object({
|
|
path: z.string(),
|
|
line: z.number().optional(),
|
|
startLine: z.number().optional(),
|
|
threadId: z.string().optional(),
|
|
isResolved: z.boolean().optional(),
|
|
isOutdated: z.boolean().optional(),
|
|
})
|
|
.optional(),
|
|
});
|
|
|
|
export const PullRequestTimelineItemSchema = z.preprocess(
|
|
(value) => {
|
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
return value;
|
|
}
|
|
const item = value as Record<string, unknown>;
|
|
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),
|
|
// COMPAT(forgeAuthState): added in v0.2.0-beta.1. Remove the legacy
|
|
// githubFeaturesEnabled normalization after 2027-01-17 once the supported
|
|
// daemon floor is >= v0.2.0.
|
|
authState: ForgeAuthStateSchema,
|
|
})
|
|
.optional()
|
|
.prefault({}),
|
|
});
|
|
|
|
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(),
|
|
}),
|
|
});
|
|
|
|
export const CheckoutRenameBranchResponseSchema = z.object({
|
|
type: z.literal("checkout.rename_branch.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
success: z.boolean(),
|
|
cwd: z.string(),
|
|
currentBranch: z.string().nullable(),
|
|
error: CheckoutErrorSchema.nullable(),
|
|
}),
|
|
});
|
|
|
|
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(),
|
|
localAhead: z.number().int().nonnegative().optional(),
|
|
localBehind: z.number().int().nonnegative().optional(),
|
|
}),
|
|
)
|
|
.optional(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
const ForgeSearchResponsePayloadSchema = z.object({
|
|
items: z.array(z.unknown()),
|
|
authState: z.unknown().optional(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
const GitHubSearchResponsePayloadSchema = z.object({
|
|
items: z.array(z.unknown()),
|
|
featuresEnabled: z.boolean().optional(),
|
|
authState: z.unknown().optional(),
|
|
githubFeaturesEnabled: z.boolean().optional(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
});
|
|
|
|
export const ForgeSearchResponseSchema = z.object({
|
|
type: z.literal("forge.search.response"),
|
|
payload: ForgeSearchResponsePayloadSchema,
|
|
});
|
|
|
|
// COMPAT(githubSearchRpc): legacy RPC retained when forge.search.* shipped in
|
|
// v0.2.0-beta.1. Stop serving and consuming it after 2027-01-17 once client
|
|
// and daemon floors are >= v0.2.0.
|
|
export const GitHubSearchResponseSchema = z.object({
|
|
type: z.literal("github_search_response"),
|
|
payload: GitHubSearchResponsePayloadSchema,
|
|
});
|
|
|
|
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(),
|
|
setupSkippedReason: z.string().optional(),
|
|
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(),
|
|
}),
|
|
});
|
|
|
|
export const FileSubscribeResponseSchema = z.object({
|
|
type: z.literal("fs.file.subscribe.response"),
|
|
payload: z.object({
|
|
subscriptionId: z.string(),
|
|
initial: FileVersionSchema,
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileUnsubscribeResponseSchema = z.object({
|
|
type: z.literal("fs.file.unsubscribe.response"),
|
|
payload: z.object({
|
|
subscriptionId: z.string(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileWriteResultSchema = z.discriminatedUnion("status", [
|
|
z.object({
|
|
status: z.literal("written"),
|
|
modifiedAt: z.string(),
|
|
size: z.number(),
|
|
revision: z.string().optional(),
|
|
}),
|
|
z.object({ status: z.literal("conflict"), version: FileVersionSchema }),
|
|
z.object({ status: z.literal("error"), error: z.string() }),
|
|
]);
|
|
|
|
export const FileWriteResponseSchema = z.object({
|
|
type: z.literal("fs.file.write.response"),
|
|
payload: z.object({
|
|
result: FileWriteResultSchema,
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileEntryCreateResponseSchema = z.object({
|
|
type: z.literal("fs.entry.create.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
parentPath: z.string(),
|
|
path: z.string().nullable(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileEntryRenameResponseSchema = z.object({
|
|
type: z.literal("fs.entry.rename.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
renamedPath: z.string().nullable(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileEntryDuplicateResponseSchema = z.object({
|
|
type: z.literal("fs.entry.duplicate.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
duplicatedPath: z.string().nullable(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileEntryDeleteResponseSchema = z.object({
|
|
type: z.literal("fs.entry.delete.response"),
|
|
payload: z.object({
|
|
cwd: z.string(),
|
|
path: z.string(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const FileUpdateSchema = z.object({
|
|
type: z.literal("fs.file.update"),
|
|
payload: z.object({
|
|
subscriptionId: z.string(),
|
|
version: FileVersionSchema,
|
|
}),
|
|
});
|
|
|
|
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 ProjectIconGetResponseSchema = z.object({
|
|
type: z.literal("project.icon.get.response"),
|
|
payload: z.object({
|
|
projectId: 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 FileUploadResponseSchema = z.object({
|
|
type: z.literal("file.upload.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
file: UploadedFileAttachmentSchema.nullable(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
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({
|
|
cwd: z.string().optional(),
|
|
entries: z.array(ProviderSnapshotEntrySchema),
|
|
compactSnapshot: CompactProviderSnapshotSchema.optional(),
|
|
snapshotHash: z.string().optional(),
|
|
fetchedAt: z.record(z.string(), z.string()).optional(),
|
|
notModified: z.boolean().optional(),
|
|
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({
|
|
subscriptionId: z.string().optional(),
|
|
cwd: z.string().optional(),
|
|
entries: z.array(ProviderSnapshotEntrySchema),
|
|
compactSnapshot: CompactProviderSnapshotSchema.optional(),
|
|
snapshotHash: z.string().optional(),
|
|
fetchedAt: z.record(z.string(), z.string()).optional(),
|
|
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(),
|
|
}),
|
|
});
|
|
|
|
export const ProviderUsageToneSchema = z.enum(["default", "ok", "warning", "danger"]);
|
|
export const ProviderUsageStatusSchema = z.enum(["available", "unavailable", "error"]);
|
|
|
|
export const ProviderUsageWindowSchema = z.object({
|
|
id: z.string(),
|
|
label: z.string(),
|
|
/**
|
|
* A few characters naming the window where space is tight, e.g. "5h" or "wk". An empty string
|
|
* shows the percent alone; leaving it out shows `label`.
|
|
*/
|
|
shortLabel: z.string().optional(),
|
|
/** Shown in the usage summary until the user pins windows of their own. */
|
|
summary: z.boolean().optional(),
|
|
usedPct: z.number().nullable().optional(),
|
|
remainingPct: z.number().nullable().optional(),
|
|
resetsAt: z.string().nullable().optional(),
|
|
runsOutAt: z.string().nullable().optional(),
|
|
shortfallPct: z.number().nullable().optional(),
|
|
tone: ProviderUsageToneSchema.optional(),
|
|
});
|
|
|
|
export const ProviderUsageBalanceSchema = z.object({
|
|
id: z.string(),
|
|
label: z.string(),
|
|
used: z.number().nullable().optional(),
|
|
remaining: z.number().nullable().optional(),
|
|
limit: z.number().nullable().optional(),
|
|
unit: z.enum(["usd", "credits", "requests", "tokens"]),
|
|
resetsAt: z.string().nullable().optional(),
|
|
tone: ProviderUsageToneSchema.optional(),
|
|
});
|
|
|
|
export const ProviderUsageDetailSchema = z.object({
|
|
id: z.string(),
|
|
label: z.string(),
|
|
value: z.string(),
|
|
tone: ProviderUsageToneSchema.optional(),
|
|
});
|
|
|
|
export const ProviderUsageSchema = z.object({
|
|
providerId: z.string(),
|
|
displayName: z.string(),
|
|
status: ProviderUsageStatusSchema,
|
|
planLabel: z.string().nullable(),
|
|
sourceLabel: z.string().nullable().optional(),
|
|
fetchedAt: z.string().nullable().optional(),
|
|
nextRefreshAt: z.string().nullable().optional(),
|
|
windows: z.array(ProviderUsageWindowSchema),
|
|
balances: z.array(ProviderUsageBalanceSchema).optional(),
|
|
details: z.array(ProviderUsageDetailSchema).optional(),
|
|
error: z.string().nullable().optional(),
|
|
});
|
|
|
|
export const ProviderUsageListResponseMessageSchema = z.object({
|
|
type: z.literal("provider.usage.list.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
fetchedAt: z.string(),
|
|
providers: z.array(ProviderUsageSchema),
|
|
}),
|
|
});
|
|
|
|
export const UsageProblemSchema = z.discriminatedUnion("kind", [
|
|
z.object({
|
|
kind: z.literal("expired"),
|
|
expiresAt: z.iso.datetime(),
|
|
refreshedBy: z.string().optional(),
|
|
}),
|
|
z.object({
|
|
kind: z.literal("rejected"),
|
|
status: z.number().int(),
|
|
refreshedBy: z.string().optional(),
|
|
}),
|
|
z.object({ kind: z.literal("no_quota"), detail: z.string() }),
|
|
]);
|
|
export const UsageReportSchema = z.discriminatedUnion("status", [
|
|
z.object({
|
|
status: z.literal("available"),
|
|
planLabel: z.string().optional(),
|
|
windows: z.array(ProviderUsageWindowSchema),
|
|
balances: z.array(ProviderUsageBalanceSchema).optional(),
|
|
details: z.array(ProviderUsageDetailSchema).optional(),
|
|
}),
|
|
z.object({ status: z.literal("unavailable"), problem: UsageProblemSchema }),
|
|
z.object({ status: z.literal("error"), error: z.string() }),
|
|
]);
|
|
export const UsageReportEntrySchema = z.object({
|
|
id: z.string(),
|
|
account: z.object({ label: z.string().optional() }),
|
|
fetchedAt: z.string(),
|
|
sourceId: z.string(),
|
|
sourceLabel: z.string(),
|
|
icon: z.string().optional(),
|
|
report: UsageReportSchema,
|
|
loginErrors: z
|
|
.array(
|
|
z.object({
|
|
harness: z.string(),
|
|
report: z.discriminatedUnion("status", [
|
|
z.object({ status: z.literal("unavailable"), problem: UsageProblemSchema }),
|
|
z.object({ status: z.literal("error"), error: z.string() }),
|
|
]),
|
|
}),
|
|
)
|
|
.optional(),
|
|
});
|
|
export const UsageListReportsUpdateMessageSchema = z.object({
|
|
type: z.literal("usage.list_reports.update"),
|
|
payload: z.object({ requestId: z.string(), report: UsageReportEntrySchema }),
|
|
});
|
|
export const UsageListReportsResponseMessageSchema = z.object({
|
|
type: z.literal("usage.list_reports.response"),
|
|
payload: z.object({ requestId: z.string(), error: z.string().nullable() }),
|
|
});
|
|
|
|
const AgentSlashCommandSchema = z.object({
|
|
name: z.string(),
|
|
description: z.string(),
|
|
argumentHint: z.string(),
|
|
kind: z.enum(["command", "skill"]).optional().catch("command"),
|
|
});
|
|
|
|
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(),
|
|
workspaceId: z.string().optional(),
|
|
title: z.string().optional(),
|
|
activity: TerminalActivitySchema.nullable().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(),
|
|
});
|
|
|
|
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(),
|
|
});
|
|
|
|
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(),
|
|
// Per-row soft-wrap flags aligned 1:1 with `grid` / `scrollback`. `true` means
|
|
// the row continued onto the next row (xterm's GRID_LINE_WRAPPED equivalent),
|
|
// so the client can re-wrap the logical line on resize instead of freezing it
|
|
// at the snapshot width. Optional: only sent to clients that advertise the
|
|
// `terminalReflowableSnapshot` capability, so old daemons/clients are unaffected.
|
|
gridWrapped: z.array(z.boolean()).optional(),
|
|
scrollbackWrapped: z.array(z.boolean()).optional(),
|
|
});
|
|
|
|
export const ListTerminalsResponseSchema = z.object({
|
|
type: z.literal("list_terminals_response"),
|
|
payload: z.object({
|
|
cwd: z.string().optional(),
|
|
terminals: z.array(TerminalInfoSchema.partial({ cwd: true })),
|
|
requestId: z.string(),
|
|
}),
|
|
});
|
|
|
|
export const TerminalsChangedSchema = z.object({
|
|
type: z.literal("terminals_changed"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
requestId: z.string().optional(),
|
|
workspaceId: z.string().optional(),
|
|
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 RenameTerminalResponseSchema = z.object({
|
|
type: z.literal("terminal.rename.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
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),
|
|
subscriptionId: z.string().optional(),
|
|
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({
|
|
subscriptionId: z.string().optional(),
|
|
terminalId: z.string(),
|
|
// Observation failure; the underlying terminal process may still be running.
|
|
error: z.string().optional(),
|
|
}),
|
|
});
|
|
|
|
export const TerminalAttentionRequiredSchema = z.object({
|
|
type: z.literal("terminal_attention_required"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
serverId: z.string().optional(),
|
|
terminalId: z.string(),
|
|
cwd: z.string(),
|
|
workspaceId: z.string().optional(),
|
|
reason: z.enum(["finished", "needs_input"]),
|
|
title: z.string(),
|
|
body: z.string(),
|
|
shouldNotify: z.boolean(),
|
|
}),
|
|
});
|
|
|
|
export const DaemonUpdateResponseSchema = z.object({
|
|
type: z.literal("daemon.update.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
previousVersion: z.string().nullable(),
|
|
newVersion: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export type DaemonUpdateResponse = z.infer<typeof DaemonUpdateResponseSchema>;
|
|
|
|
export const DaemonUpdateProgressMessageSchema = z.object({
|
|
type: z.literal("daemon.update.progress"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
phase: z.enum(["starting", "downloading", "installing", "complete"]),
|
|
}),
|
|
});
|
|
|
|
export const HubExecutionAgentCreateResponseSchema = z.object({
|
|
type: z.literal("hub.execution.agent.create.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
executionId: z.string(),
|
|
agentId: z.string().nullable(),
|
|
agent: AgentSnapshotPayloadSchema.nullable(),
|
|
success: z.boolean(),
|
|
toolPolicyApplied: z.literal(true).optional(),
|
|
error: HubExecutionAgentCreateErrorSchema.nullable(),
|
|
}),
|
|
});
|
|
|
|
export const HubExecutionAgentValidationIssueSchema = z.object({
|
|
path: z.array(z.union([z.string(), z.number()])),
|
|
message: z.string(),
|
|
});
|
|
|
|
export type HubExecutionAgentValidationIssue = z.infer<
|
|
typeof HubExecutionAgentValidationIssueSchema
|
|
>;
|
|
|
|
export const HubExecutionAgentValidateResponseSchema = z.object({
|
|
type: z.literal("hub.execution.agent.validate.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
valid: z.boolean(),
|
|
issues: z.array(HubExecutionAgentValidationIssueSchema),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const HubExecutionControlResponseSchema = z.object({
|
|
type: z.literal("hub.execution.control.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
executionId: z.string(),
|
|
action: HubExecutionControlActionSchema,
|
|
success: z.boolean(),
|
|
error: z.string().nullable(),
|
|
}),
|
|
});
|
|
|
|
export const HubExecutionAgentUpdateSchema = z.object({
|
|
type: z.literal("hub.execution.agent.update"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
executionId: z.string(),
|
|
agentId: z.string(),
|
|
agent: AgentSnapshotPayloadSchema,
|
|
}),
|
|
});
|
|
|
|
export const HubExecutionAgentStreamSchema = z.object({
|
|
type: z.literal("hub.execution.agent.stream"),
|
|
payload: z.object({
|
|
subscriptionId: z.string().optional(),
|
|
executionId: z.string(),
|
|
agentId: z.string(),
|
|
event: AgentStreamEventPayloadSchema,
|
|
}),
|
|
});
|
|
|
|
export type HubExecutionAgentCreateResponse = z.infer<typeof HubExecutionAgentCreateResponseSchema>;
|
|
export type HubExecutionAgentValidateResponse = z.infer<
|
|
typeof HubExecutionAgentValidateResponseSchema
|
|
>;
|
|
export type HubExecutionControlResponse = z.infer<typeof HubExecutionControlResponseSchema>;
|
|
export type HubExecutionAgentUpdate = z.infer<typeof HubExecutionAgentUpdateSchema>;
|
|
export type HubExecutionAgentStream = z.infer<typeof HubExecutionAgentStreamSchema>;
|
|
|
|
export const HubExecutionOutboundMessageSchema = z.discriminatedUnion("type", [
|
|
HubExecutionAgentCreateResponseSchema,
|
|
HubExecutionAgentValidateResponseSchema,
|
|
HubExecutionControlResponseSchema,
|
|
HubExecutionAgentUpdateSchema,
|
|
HubExecutionAgentStreamSchema,
|
|
]);
|
|
|
|
export type HubExecutionOutboundMessage = z.infer<typeof HubExecutionOutboundMessageSchema>;
|
|
|
|
export class HubMessageCorrelationError extends Error {
|
|
constructor(messageType: HubExecutionOutboundMessage["type"]) {
|
|
super(`Hub message ${messageType} has mismatched agent correlation`);
|
|
this.name = "HubMessageCorrelationError";
|
|
}
|
|
}
|
|
|
|
export function parseHubExecutionOutboundMessage(value: unknown): HubExecutionOutboundMessage {
|
|
const message = HubExecutionOutboundMessageSchema.parse(value);
|
|
const payload = message.payload;
|
|
if (
|
|
"agent" in payload &&
|
|
payload.agent !== null &&
|
|
"agentId" in payload &&
|
|
payload.agentId !== null &&
|
|
payload.agent.id !== payload.agentId
|
|
) {
|
|
throw new HubMessageCorrelationError(message.type);
|
|
}
|
|
return message;
|
|
}
|
|
|
|
export type DaemonUpdateProgressMessage = z.infer<typeof DaemonUpdateProgressMessageSchema>;
|
|
|
|
export const PluginCatalogGetResponseSchema = z.object({
|
|
type: z.literal("plugin.catalog.get.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
plugins: z.array(
|
|
z.object({
|
|
id: PluginIdSchema,
|
|
clientBundle: z.string(),
|
|
requirements: PluginRequirementsSchema.optional(),
|
|
}),
|
|
),
|
|
}),
|
|
});
|
|
|
|
export const PluginStatusSchema = z.enum(["running", "disabled", "failed"]);
|
|
export type PluginStatus = z.infer<typeof PluginStatusSchema>;
|
|
|
|
export const PluginNpmInstallationSchema = z.object({
|
|
packageName: z.string(),
|
|
requestedSpec: z.string(),
|
|
version: z.string(),
|
|
integrity: z.string(),
|
|
});
|
|
|
|
export const PluginListItemSchema = z.object({
|
|
id: PluginIdSchema,
|
|
name: z.string().optional(),
|
|
icon: z.string().optional(),
|
|
media: z.array(z.string()).optional(),
|
|
description: z.string().optional(),
|
|
path: z.string(),
|
|
enabled: z.boolean(),
|
|
status: PluginStatusSchema,
|
|
source: z.enum(["directory", "git"]).optional(),
|
|
npm: PluginNpmInstallationSchema.optional(),
|
|
installation: PluginInstallationSchema.optional(),
|
|
remote: z.string().optional(),
|
|
ref: z.string().optional(),
|
|
commit: z.string().optional(),
|
|
error: z.string().optional(),
|
|
});
|
|
export type PluginListItem = z.infer<typeof PluginListItemSchema>;
|
|
|
|
export const PluginLogEntrySchema = z.object({
|
|
sequence: z.number().int().nonnegative(),
|
|
timestamp: z.string().datetime(),
|
|
stream: z.enum(["stdout", "stderr"]),
|
|
message: z.string(),
|
|
});
|
|
export type PluginLogEntry = z.infer<typeof PluginLogEntrySchema>;
|
|
|
|
export const PluginListResponseSchema = z.object({
|
|
type: z.literal("plugin.list.response"),
|
|
payload: z.object({ requestId: z.string(), plugins: z.array(PluginListItemSchema) }),
|
|
});
|
|
|
|
export const PluginLogsGetResponseSchema = z.object({
|
|
type: z.literal("plugin.logs.get.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
pluginId: PluginIdSchema,
|
|
entries: z.array(PluginLogEntrySchema),
|
|
}),
|
|
});
|
|
|
|
export const PluginDirectoryInstallResponseSchema = z.object({
|
|
type: z.literal("plugin.directory.install.response"),
|
|
payload: z.object({ requestId: z.string(), plugin: PluginListItemSchema }),
|
|
});
|
|
|
|
export const PluginDirectoryInspectResponseSchema = z.object({
|
|
type: z.literal("plugin.directory.inspect.response"),
|
|
payload: z.object({ requestId: z.string(), id: PluginIdSchema }),
|
|
});
|
|
|
|
export const PluginSourceInstallResponseSchema = z.object({
|
|
type: z.literal("plugin.source.install.response"),
|
|
payload: z.object({ requestId: z.string(), plugin: PluginListItemSchema }),
|
|
});
|
|
|
|
export const PluginSourceStatusItemSchema = z.object({
|
|
id: PluginIdSchema,
|
|
source: z.enum(["directory", "git"]),
|
|
npm: PluginNpmInstallationSchema.optional(),
|
|
installation: PluginInstallationSchema.optional(),
|
|
path: z.string(),
|
|
remote: z.string().optional(),
|
|
ref: z.string().optional(),
|
|
currentCommit: z.string().optional(),
|
|
latestCommit: z.string().optional(),
|
|
commitsBehind: z.number().int().nonnegative().optional(),
|
|
updateAvailable: z.boolean().optional(),
|
|
});
|
|
export type PluginSourceStatusItem = z.infer<typeof PluginSourceStatusItemSchema>;
|
|
|
|
export const PluginSourceStatusResponseSchema = z.object({
|
|
type: z.literal("plugin.source.status.response"),
|
|
payload: z.object({ requestId: z.string(), plugins: z.array(PluginSourceStatusItemSchema) }),
|
|
});
|
|
|
|
export const PluginSourceUpdateItemSchema = z.object({
|
|
id: PluginIdSchema,
|
|
previousCommit: z.string(),
|
|
currentCommit: z.string(),
|
|
commits: z.number().int().nonnegative(),
|
|
updated: z.boolean(),
|
|
});
|
|
export type PluginSourceUpdateItem = z.infer<typeof PluginSourceUpdateItemSchema>;
|
|
|
|
export const PluginSourceUpdateResponseSchema = z.object({
|
|
type: z.literal("plugin.source.update.response"),
|
|
payload: z.object({ requestId: z.string(), plugins: z.array(PluginSourceUpdateItemSchema) }),
|
|
});
|
|
|
|
export const PluginUpdatePreviewSchema = z.object({
|
|
id: PluginIdSchema,
|
|
outcome: z.enum(["update", "current", "installed-newer", "local", "error"]),
|
|
current: PluginInstallationSchema.optional(),
|
|
target: PluginUpdateTargetSchema.optional(),
|
|
links: z.array(z.string()),
|
|
proposal: PluginUpdateProposalSchema.optional(),
|
|
error: z.string().optional(),
|
|
});
|
|
export type PluginUpdatePreview = z.infer<typeof PluginUpdatePreviewSchema>;
|
|
export const PluginUpdateResultSchema = z.object({
|
|
id: PluginIdSchema,
|
|
outcome: z.enum(["updated", "error"]),
|
|
plugin: PluginListItemSchema.optional(),
|
|
error: z.string().optional(),
|
|
warning: z.string().optional(),
|
|
});
|
|
export type PluginUpdateResult = z.infer<typeof PluginUpdateResultSchema>;
|
|
export const PluginUpdatePreviewResponseSchema = z.object({
|
|
type: z.literal("plugin.source.update.preview.response"),
|
|
payload: z.object({ requestId: z.string(), plugins: z.array(PluginUpdatePreviewSchema) }),
|
|
});
|
|
export const PluginUpdateApplyResponseSchema = z.object({
|
|
type: z.literal("plugin.source.update.apply.response"),
|
|
payload: z.object({ requestId: z.string(), plugins: z.array(PluginUpdateResultSchema) }),
|
|
});
|
|
|
|
function pluginActionResponse<const Type extends string>(type: Type) {
|
|
return z.object({
|
|
type: z.literal(type),
|
|
payload: z.object({ requestId: z.string(), plugin: PluginListItemSchema }),
|
|
});
|
|
}
|
|
|
|
export const PluginReloadResponseSchema = pluginActionResponse("plugin.reload.response");
|
|
export const PluginEnableResponseSchema = pluginActionResponse("plugin.enable.response");
|
|
export const PluginDisableResponseSchema = pluginActionResponse("plugin.disable.response");
|
|
export const PluginRemoveResponseSchema = z.object({
|
|
type: z.literal("plugin.remove.response"),
|
|
payload: z.object({ requestId: z.string() }).strict(),
|
|
});
|
|
|
|
export const PluginRpcInvokeResponseSchema = z.object({
|
|
type: z.literal("plugin.rpc.invoke.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
output: z.unknown(),
|
|
}),
|
|
});
|
|
|
|
export const AgentTimelineAppendResponseSchema = z.object({
|
|
type: z.literal("agent.timeline.append.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
seq: z.number().int().nonnegative(),
|
|
epoch: z.string(),
|
|
}),
|
|
});
|
|
|
|
function agentSkillsStatusResponse<const Type extends string>(type: Type) {
|
|
return z.object({
|
|
type: z.literal(type),
|
|
payload: AgentSkillsStatusSchema.extend({ requestId: z.string() }),
|
|
});
|
|
}
|
|
|
|
export const AgentSkillsGetStatusResponseSchema = agentSkillsStatusResponse(
|
|
"agent.skills.get_status.response",
|
|
);
|
|
export const AgentSkillsReconcileResponseSchema = agentSkillsStatusResponse(
|
|
"agent.skills.reconcile.response",
|
|
);
|
|
export const AgentSkillsUninstallResponseSchema = agentSkillsStatusResponse(
|
|
"agent.skills.uninstall.response",
|
|
);
|
|
export const AgentSkillsSaveSelectionResponseSchema = z.object({
|
|
type: z.literal("agent.skills.save_selection.response"),
|
|
payload: AgentSkillsSaveResultSchema.extend({ requestId: z.string() }),
|
|
});
|
|
export const AgentSkillsImportLegacySelectionResponseSchema = z.object({
|
|
type: z.literal("agent.skills.import_legacy_selection.response"),
|
|
payload: z.object({
|
|
requestId: z.string(),
|
|
imported: z.boolean(),
|
|
selection: AgentSkillSelectionSchema,
|
|
}),
|
|
});
|
|
|
|
export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
|
BrowserHostRegisterResponseSchema,
|
|
SubscriptionReleaseResponseSchema,
|
|
SessionEventsSetSubscriptionResponseSchema,
|
|
HubExecutionAgentCreateResponseSchema,
|
|
HubExecutionAgentValidateResponseSchema,
|
|
HubExecutionControlResponseSchema,
|
|
HubExecutionAgentUpdateSchema,
|
|
HubExecutionAgentStreamSchema,
|
|
BrowserAutomationExecuteRequestSchema,
|
|
PluginCatalogGetResponseSchema,
|
|
PluginListResponseSchema,
|
|
PluginLogsGetResponseSchema,
|
|
PluginDirectoryInstallResponseSchema,
|
|
PluginDirectoryInspectResponseSchema,
|
|
PluginSourceInstallResponseSchema,
|
|
PluginSourceStatusResponseSchema,
|
|
PluginSourceUpdateResponseSchema,
|
|
PluginUpdatePreviewResponseSchema,
|
|
PluginUpdateApplyResponseSchema,
|
|
PluginReloadResponseSchema,
|
|
PluginEnableResponseSchema,
|
|
PluginDisableResponseSchema,
|
|
PluginRemoveResponseSchema,
|
|
PluginRpcInvokeResponseSchema,
|
|
AgentTimelineAppendResponseSchema,
|
|
AgentSkillsGetStatusResponseSchema,
|
|
AgentSkillsReconcileResponseSchema,
|
|
AgentSkillsUninstallResponseSchema,
|
|
AgentSkillsSaveSelectionResponseSchema,
|
|
AgentSkillsImportLegacySelectionResponseSchema,
|
|
ActivityLogMessageSchema,
|
|
AssistantChunkMessageSchema,
|
|
AudioOutputMessageSchema,
|
|
TranscriptionResultMessageSchema,
|
|
VoiceInputStateMessageSchema,
|
|
DictationStreamAckMessageSchema,
|
|
DictationStreamFinishAcceptedMessageSchema,
|
|
DictationStreamPartialMessageSchema,
|
|
DictationStreamFinalMessageSchema,
|
|
DictationStreamErrorMessageSchema,
|
|
StatusMessageSchema,
|
|
PongMessageSchema,
|
|
PushUnregisterResponseSchema,
|
|
RpcErrorMessageSchema,
|
|
ArtifactMessageSchema,
|
|
AgentUpdateMessageSchema,
|
|
WorkspaceUpdateMessageSchema,
|
|
WorkspaceLabelListResponseSchema,
|
|
WorkspaceLabelUpdateSchema,
|
|
WorkspaceLabelAssignmentSetResponseSchema,
|
|
WorkspaceLabelUpdateResponseSchema,
|
|
WorkspaceLabelDeleteResponseSchema,
|
|
WorkspaceLabelDeleteInspectResponseSchema,
|
|
ProjectUpdateMessageSchema,
|
|
ProjectListResponseMessageSchema,
|
|
ScriptStatusUpdateMessageSchema,
|
|
WorkspaceSetupProgressMessageSchema,
|
|
WorkspaceSetupStatusResponseMessageSchema,
|
|
WorkspaceSetupRunResponseMessageSchema,
|
|
AgentStreamMessageSchema,
|
|
AgentStatusMessageSchema,
|
|
FetchAgentsResponseMessageSchema,
|
|
FetchAgentHistoryResponseMessageSchema,
|
|
FetchRecentProviderSessionsResponseMessageSchema,
|
|
FetchWorkspacesResponseMessageSchema,
|
|
ProjectAddResponseSchema,
|
|
ProjectCreateDirectoryResponseSchema,
|
|
OpenProjectResponseMessageSchema,
|
|
WorkspaceGithubSearchRepositoriesResponseSchema,
|
|
ProjectGithubCloneResponseSchema,
|
|
StartWorkspaceScriptResponseMessageSchema,
|
|
WorkspaceScriptListResponseMessageSchema,
|
|
WorkspaceScriptStartResponseMessageSchema,
|
|
WorkspaceScriptStopResponseMessageSchema,
|
|
LegacyListAvailableEditorsResponseMessageSchema,
|
|
LegacyOpenInEditorResponseMessageSchema,
|
|
ArchiveWorkspaceResponseMessageSchema,
|
|
FetchAgentResponseMessageSchema,
|
|
FetchAgentTimelineResponseMessageSchema,
|
|
AgentTimelineReplacementMessageSchema,
|
|
AgentTimelineSearchResponseMessageSchema,
|
|
AgentTimelineListPromptsResponseMessageSchema,
|
|
ProviderSubagentListResponseMessageSchema,
|
|
ProviderSubagentTimelineResponseMessageSchema,
|
|
ProviderSubagentUpdateMessageSchema,
|
|
SetAgentTimelineSubscriptionResponseMessageSchema,
|
|
AgentAttentionRequiredMessageSchema,
|
|
AgentForkContextResponseMessageSchema,
|
|
CancelAgentResponseMessageSchema,
|
|
ClearAgentAttentionResponseMessageSchema,
|
|
WorkspaceCreateResponseSchema,
|
|
AgentCreateResponseSchema,
|
|
WorkspaceCreationUpdateSchema,
|
|
AgentCreationUpdateSchema,
|
|
CreationSubscribeResponseSchema,
|
|
WorkspaceClearAttentionResponseSchema,
|
|
WorkspaceMarkUnreadResponseSchema,
|
|
SendAgentMessageResponseMessageSchema,
|
|
SetVoiceModeResponseMessageSchema,
|
|
DaemonGetStatusResponseSchema,
|
|
DaemonGetPairingOfferResponseSchema,
|
|
DaemonConfigReloadResponseSchema,
|
|
HubManagementDaemonConnectResponseSchema,
|
|
HubManagementDaemonGetStatusResponseSchema,
|
|
HubManagementDaemonDisconnectResponseSchema,
|
|
HubManagementDaemonPermissionsUpdateResponseSchema,
|
|
DiagnosticsResponseSchema,
|
|
GetDaemonConfigResponseMessageSchema,
|
|
SetDaemonConfigResponseMessageSchema,
|
|
ReadProjectConfigResponseMessageSchema,
|
|
WriteProjectConfigResponseMessageSchema,
|
|
SetAgentModeResponseMessageSchema,
|
|
SetAgentModelResponseMessageSchema,
|
|
SetAgentThinkingResponseMessageSchema,
|
|
SetAgentFeatureResponseMessageSchema,
|
|
AgentConfigApplyResponseMessageSchema,
|
|
AgentDetachResponseMessageSchema,
|
|
AgentRewindResponseMessageSchema,
|
|
UpdateAgentResponseMessageSchema,
|
|
ProjectRenameResponseSchema,
|
|
ProjectIconSetResponseSchema,
|
|
ProjectRemoveResponseSchema,
|
|
WorkspaceTitleSetResponseSchema,
|
|
WorkspacePinSetResponseSchema,
|
|
WorkspaceRecoveryInspectResponseSchema,
|
|
WorkspaceRecoveryRestoreResponseSchema,
|
|
WaitForFinishResponseMessageSchema,
|
|
AgentPermissionRequestMessageSchema,
|
|
AgentPermissionResolvedMessageSchema,
|
|
AgentDeletedMessageSchema,
|
|
AgentArchivedMessageSchema,
|
|
CloseItemsResponseSchema,
|
|
CheckoutStatusResponseSchema,
|
|
CheckoutStatusUpdateSchema,
|
|
CheckoutDiffGetResponseSchema,
|
|
SubscribeCheckoutDiffResponseSchema,
|
|
CheckoutDiffUpdateSchema,
|
|
CheckoutCommitResponseSchema,
|
|
CheckoutMergeResponseSchema,
|
|
CheckoutMergeFromBaseResponseSchema,
|
|
CheckoutPullResponseSchema,
|
|
CheckoutPushResponseSchema,
|
|
CheckoutRefreshResponseSchema,
|
|
CheckoutDiscardChangesResponseSchema,
|
|
CheckoutPrCreateResponseSchema,
|
|
CheckoutPrMergeResponseSchema,
|
|
CheckoutForgeSetAutoMergeResponseSchema,
|
|
CheckoutGithubSetAutoMergeResponseSchema,
|
|
CheckoutCommitsListResponseSchema,
|
|
CheckoutCommitFileDiffResponseSchema,
|
|
CheckoutForgeGetCheckDetailsResponseSchema,
|
|
CheckoutGithubGetCheckDetailsResponseSchema,
|
|
CheckoutPrStatusResponseSchema,
|
|
PullRequestTimelineResponseSchema,
|
|
CheckoutSwitchBranchResponseSchema,
|
|
CheckoutRenameBranchResponseSchema,
|
|
StashSaveResponseSchema,
|
|
StashPopResponseSchema,
|
|
StashListResponseSchema,
|
|
ValidateBranchResponseSchema,
|
|
BranchSuggestionsResponseSchema,
|
|
ForgeSearchResponseSchema,
|
|
GitHubSearchResponseSchema,
|
|
DirectorySuggestionsResponseSchema,
|
|
PaseoWorktreeListResponseSchema,
|
|
PaseoWorktreeArchiveResponseSchema,
|
|
CreatePaseoWorktreeResponseSchema,
|
|
FileExplorerResponseSchema,
|
|
FileSubscribeResponseSchema,
|
|
FileUnsubscribeResponseSchema,
|
|
FileWriteResponseSchema,
|
|
FileEntryCreateResponseSchema,
|
|
FileEntryRenameResponseSchema,
|
|
FileEntryDuplicateResponseSchema,
|
|
FileEntryDeleteResponseSchema,
|
|
FileUpdateSchema,
|
|
ProjectIconResponseSchema,
|
|
ProjectIconGetResponseSchema,
|
|
FileDownloadTokenResponseSchema,
|
|
FileUploadResponseSchema,
|
|
ListProviderModelsResponseMessageSchema,
|
|
ListProviderModesResponseMessageSchema,
|
|
ListProviderFeaturesResponseMessageSchema,
|
|
ListAvailableProvidersResponseSchema,
|
|
GetProvidersSnapshotResponseMessageSchema,
|
|
ProvidersSnapshotUpdateMessageSchema,
|
|
RefreshProvidersSnapshotResponseMessageSchema,
|
|
ProviderDiagnosticResponseMessageSchema,
|
|
ProviderUsageListResponseMessageSchema,
|
|
UsageListReportsUpdateMessageSchema,
|
|
UsageListReportsResponseMessageSchema,
|
|
ListCommandsResponseSchema,
|
|
ListTerminalsResponseSchema,
|
|
TerminalsChangedSchema,
|
|
CreateTerminalResponseSchema,
|
|
RenameTerminalResponseSchema,
|
|
SubscribeTerminalResponseSchema,
|
|
KillTerminalResponseSchema,
|
|
CaptureTerminalResponseSchema,
|
|
TerminalStreamExitSchema,
|
|
TerminalAttentionRequiredSchema,
|
|
ChatCreateResponseSchema,
|
|
ChatListResponseSchema,
|
|
ChatInspectResponseSchema,
|
|
ChatDeleteResponseSchema,
|
|
ChatPostResponseSchema,
|
|
ChatReadResponseSchema,
|
|
ChatWaitResponseSchema,
|
|
ScheduleCreateResponseSchema,
|
|
ScheduleListResponseSchema,
|
|
ScheduleInspectResponseSchema,
|
|
ScheduleLogsResponseSchema,
|
|
SchedulePauseResponseSchema,
|
|
ScheduleResumeResponseSchema,
|
|
ScheduleDeleteResponseSchema,
|
|
ScheduleRunOnceResponseSchema,
|
|
ScheduleUpdateResponseSchema,
|
|
LoopRunResponseSchema,
|
|
LoopListResponseSchema,
|
|
LoopInspectResponseSchema,
|
|
LoopLogsResponseSchema,
|
|
LoopStopResponseSchema,
|
|
DaemonUpdateProgressMessageSchema,
|
|
DaemonUpdateResponseSchema,
|
|
]);
|
|
|
|
export type SessionOutboundMessage = z.infer<typeof SessionOutboundMessageSchema>;
|
|
|
|
// Type exports for individual message types
|
|
export type ActivityLogMessage = z.infer<typeof ActivityLogMessageSchema>;
|
|
export type AssistantChunkMessage = z.infer<typeof AssistantChunkMessageSchema>;
|
|
export type AudioOutputMessage = z.infer<typeof AudioOutputMessageSchema>;
|
|
export type TranscriptionResultMessage = z.infer<typeof TranscriptionResultMessageSchema>;
|
|
export type StatusMessage = z.infer<typeof StatusMessageSchema>;
|
|
export type ServerCapabilityState = z.infer<typeof ServerCapabilityStateSchema>;
|
|
export type ServerVoiceCapabilities = z.infer<typeof ServerVoiceCapabilitiesSchema>;
|
|
export type ServerCapabilities = z.infer<typeof ServerCapabilitiesSchema>;
|
|
export type ServerInfoStatusPayload = z.infer<typeof ServerInfoStatusPayloadSchema>;
|
|
export type RpcErrorMessage = z.infer<typeof RpcErrorMessageSchema>;
|
|
export type ArtifactMessage = z.infer<typeof ArtifactMessageSchema>;
|
|
export type AgentUpdateMessage = z.infer<typeof AgentUpdateMessageSchema>;
|
|
export type WorkspaceSetupProgressMessage = z.infer<typeof WorkspaceSetupProgressMessageSchema>;
|
|
export type WorkspaceSetupSnapshot = z.infer<typeof WorkspaceSetupSnapshotSchema>;
|
|
export type WorkspaceSetupStatusResponseMessage = z.infer<
|
|
typeof WorkspaceSetupStatusResponseMessageSchema
|
|
>;
|
|
export type WorkspaceSetupRunResponseMessage = z.infer<
|
|
typeof WorkspaceSetupRunResponseMessageSchema
|
|
>;
|
|
export type AgentStreamMessage = z.infer<typeof AgentStreamMessageSchema>;
|
|
export type AgentStatusMessage = z.infer<typeof AgentStatusMessageSchema>;
|
|
export type ProjectCheckoutLitePayload = z.infer<typeof ProjectCheckoutLitePayloadSchema>;
|
|
export type ProjectPlacementPayload = z.infer<typeof ProjectPlacementPayloadSchema>;
|
|
export type WorkspaceStateBucket = z.infer<typeof WorkspaceStateBucketSchema>;
|
|
export type WorkspaceDescriptorPayload = z.infer<typeof WorkspaceDescriptorPayloadSchema>;
|
|
export type WorkspaceProjectDescriptorPayload = z.infer<
|
|
typeof WorkspaceProjectDescriptorPayloadSchema
|
|
>;
|
|
export type ProjectListResponseMessage = z.infer<typeof ProjectListResponseMessageSchema>;
|
|
export type WorkspaceScriptLifecycle = z.infer<typeof WorkspaceScriptLifecycleSchema>;
|
|
export type WorkspaceScriptHealth = z.infer<typeof WorkspaceScriptHealthSchema>;
|
|
export type WorkspaceScriptPayload = z.infer<typeof WorkspaceScriptPayloadSchema>;
|
|
export type FetchAgentsResponseMessage = z.infer<typeof FetchAgentsResponseMessageSchema>;
|
|
export type FetchAgentHistoryResponseMessage = z.infer<
|
|
typeof FetchAgentHistoryResponseMessageSchema
|
|
>;
|
|
export type FetchRecentProviderSessionsResponseMessage = z.infer<
|
|
typeof FetchRecentProviderSessionsResponseMessageSchema
|
|
>;
|
|
export type FetchWorkspacesResponseMessage = z.infer<typeof FetchWorkspacesResponseMessageSchema>;
|
|
export type ProjectAddResponse = z.infer<typeof ProjectAddResponseSchema>;
|
|
export type ProjectCreateDirectoryResponse = z.infer<typeof ProjectCreateDirectoryResponseSchema>;
|
|
export type ScriptStatusUpdateMessage = z.infer<typeof ScriptStatusUpdateMessageSchema>;
|
|
export type OpenProjectResponseMessage = z.infer<typeof OpenProjectResponseMessageSchema>;
|
|
export type WorkspaceGithubSearchRepositoriesResponse = z.infer<
|
|
typeof WorkspaceGithubSearchRepositoriesResponseSchema
|
|
>;
|
|
export type GithubRepository = z.infer<typeof GithubRepositorySchema>;
|
|
export type ProjectGithubCloneResponse = z.infer<typeof ProjectGithubCloneResponseSchema>;
|
|
export type StartWorkspaceScriptResponseMessage = z.infer<
|
|
typeof StartWorkspaceScriptResponseMessageSchema
|
|
>;
|
|
export type WorkspaceScriptListRequest = z.infer<typeof WorkspaceScriptListRequestSchema>;
|
|
export type WorkspaceScriptStartRequest = z.infer<typeof WorkspaceScriptStartRequestSchema>;
|
|
export type WorkspaceScriptStopRequest = z.infer<typeof WorkspaceScriptStopRequestSchema>;
|
|
export type WorkspaceScriptListResponseMessage = z.infer<
|
|
typeof WorkspaceScriptListResponseMessageSchema
|
|
>;
|
|
export type WorkspaceScriptStartResponseMessage = z.infer<
|
|
typeof WorkspaceScriptStartResponseMessageSchema
|
|
>;
|
|
export type WorkspaceScriptStopResponseMessage = z.infer<
|
|
typeof WorkspaceScriptStopResponseMessageSchema
|
|
>;
|
|
export type LegacyListAvailableEditorsResponseMessage = z.infer<
|
|
typeof LegacyListAvailableEditorsResponseMessageSchema
|
|
>;
|
|
export type LegacyOpenInEditorResponseMessage = z.infer<
|
|
typeof LegacyOpenInEditorResponseMessageSchema
|
|
>;
|
|
export type ArchiveWorkspaceResponseMessage = z.infer<typeof ArchiveWorkspaceResponseMessageSchema>;
|
|
export type FetchAgentResponseMessage = z.infer<typeof FetchAgentResponseMessageSchema>;
|
|
export type FetchAgentTimelineResponseMessage = z.infer<
|
|
typeof FetchAgentTimelineResponseMessageSchema
|
|
>;
|
|
export type AgentTimelineListPromptsResponseMessage = z.infer<
|
|
typeof AgentTimelineListPromptsResponseMessageSchema
|
|
>;
|
|
export type AgentForkContextResponseMessage = z.infer<typeof AgentForkContextResponseMessageSchema>;
|
|
export type CancelAgentResponseMessage = z.infer<typeof CancelAgentResponseMessageSchema>;
|
|
export type SendAgentMessageResponseMessage = z.infer<typeof SendAgentMessageResponseMessageSchema>;
|
|
export type SetVoiceModeResponseMessage = z.infer<typeof SetVoiceModeResponseMessageSchema>;
|
|
export type SetAgentModeResponseMessage = z.infer<typeof SetAgentModeResponseMessageSchema>;
|
|
export type SetAgentModelResponseMessage = z.infer<typeof SetAgentModelResponseMessageSchema>;
|
|
export type SetAgentThinkingResponseMessage = z.infer<typeof SetAgentThinkingResponseMessageSchema>;
|
|
export type SetAgentFeatureResponseMessage = z.infer<typeof SetAgentFeatureResponseMessageSchema>;
|
|
export type AgentConfigApplyResponseMessage = z.infer<typeof AgentConfigApplyResponseMessageSchema>;
|
|
export type AgentDetachResponseMessage = z.infer<typeof AgentDetachResponseMessageSchema>;
|
|
export type AgentRewindResponseMessage = z.infer<typeof AgentRewindResponseMessageSchema>;
|
|
export type UpdateAgentResponseMessage = z.infer<typeof UpdateAgentResponseMessageSchema>;
|
|
export type ProjectRenameResponse = z.infer<typeof ProjectRenameResponseSchema>;
|
|
export type ProjectIconSetResponse = z.infer<typeof ProjectIconSetResponseSchema>;
|
|
export type ProjectRemoveResponse = z.infer<typeof ProjectRemoveResponseSchema>;
|
|
export type WorkspaceTitleSetResponse = z.infer<typeof WorkspaceTitleSetResponseSchema>;
|
|
export type WorkspaceTitleSetResponsePayload = z.infer<
|
|
typeof WorkspaceTitleSetResponsePayloadSchema
|
|
>;
|
|
export type WorkspacePinSetResponse = z.infer<typeof WorkspacePinSetResponseSchema>;
|
|
export type WorkspacePinSetResponsePayload = z.infer<typeof WorkspacePinSetResponsePayloadSchema>;
|
|
export type WorkspaceRecoveryState = z.infer<typeof WorkspaceRecoveryStateSchema>;
|
|
export type WorkspaceRecoveryInspectResponse = z.infer<
|
|
typeof WorkspaceRecoveryInspectResponseSchema
|
|
>;
|
|
export type WorkspaceRecoveryRestoreResponse = z.infer<
|
|
typeof WorkspaceRecoveryRestoreResponseSchema
|
|
>;
|
|
export type WorkspaceCreateRequest = z.infer<typeof WorkspaceCreateRequestSchema>;
|
|
export type WorkspaceCreateResponse = z.infer<typeof WorkspaceCreateResponseSchema>;
|
|
export type ProjectRenameResponsePayload = z.infer<typeof ProjectRenameResponsePayloadSchema>;
|
|
export type ProjectRemoveResponsePayload = z.infer<typeof ProjectRemoveResponsePayloadSchema>;
|
|
export type WaitForFinishResponseMessage = z.infer<typeof WaitForFinishResponseMessageSchema>;
|
|
export type AgentPermissionRequestMessage = z.infer<typeof AgentPermissionRequestMessageSchema>;
|
|
export type AgentPermissionResolvedMessage = z.infer<typeof AgentPermissionResolvedMessageSchema>;
|
|
export type AgentDeletedMessage = z.infer<typeof AgentDeletedMessageSchema>;
|
|
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<typeof ListAvailableProvidersResponseSchema>;
|
|
export type DaemonGetStatusResponse = z.infer<typeof DaemonGetStatusResponseSchema>;
|
|
export type DaemonGetPairingOfferResponse = z.infer<typeof DaemonGetPairingOfferResponseSchema>;
|
|
export type DaemonConfigReloadResponse = z.infer<typeof DaemonConfigReloadResponseSchema>;
|
|
export type DiagnosticsResponse = z.infer<typeof DiagnosticsResponseSchema>;
|
|
export type GetProvidersSnapshotResponseMessage = z.infer<
|
|
typeof GetProvidersSnapshotResponseMessageSchema
|
|
>;
|
|
export type ProvidersSnapshotUpdateMessage = z.infer<typeof ProvidersSnapshotUpdateMessageSchema>;
|
|
export type RefreshProvidersSnapshotResponseMessage = z.infer<
|
|
typeof RefreshProvidersSnapshotResponseMessageSchema
|
|
>;
|
|
export type ProviderDiagnosticResponseMessage = z.infer<
|
|
typeof ProviderDiagnosticResponseMessageSchema
|
|
>;
|
|
export type ProviderUsageTone = z.infer<typeof ProviderUsageToneSchema>;
|
|
export type UsageProblem = z.infer<typeof UsageProblemSchema>;
|
|
export type UsageReport = z.infer<typeof UsageReportSchema>;
|
|
export type UsageReportEntry = z.infer<typeof UsageReportEntrySchema>;
|
|
export type UsageListReportsResponseMessage = z.infer<typeof UsageListReportsResponseMessageSchema>;
|
|
export type ProviderUsageStatus = z.infer<typeof ProviderUsageStatusSchema>;
|
|
export type ProviderUsage = z.infer<typeof ProviderUsageSchema>;
|
|
export type ProviderUsageWindow = z.infer<typeof ProviderUsageWindowSchema>;
|
|
export type ProviderUsageBalance = z.infer<typeof ProviderUsageBalanceSchema>;
|
|
export type ProviderUsageDetail = z.infer<typeof ProviderUsageDetailSchema>;
|
|
export type ProviderUsageListResponseMessage = z.infer<
|
|
typeof ProviderUsageListResponseMessageSchema
|
|
>;
|
|
export type ChatCreateResponse = z.infer<typeof ChatCreateResponseSchema>;
|
|
export type ChatListResponse = z.infer<typeof ChatListResponseSchema>;
|
|
export type ChatInspectResponse = z.infer<typeof ChatInspectResponseSchema>;
|
|
export type ChatDeleteResponse = z.infer<typeof ChatDeleteResponseSchema>;
|
|
export type ChatPostResponse = z.infer<typeof ChatPostResponseSchema>;
|
|
export type ChatReadResponse = z.infer<typeof ChatReadResponseSchema>;
|
|
export type ChatWaitResponse = z.infer<typeof ChatWaitResponseSchema>;
|
|
export type ScheduleCreateResponse = z.infer<typeof ScheduleCreateResponseSchema>;
|
|
export type ScheduleListResponse = z.infer<typeof ScheduleListResponseSchema>;
|
|
export type ScheduleInspectResponse = z.infer<typeof ScheduleInspectResponseSchema>;
|
|
export type ScheduleLogsResponse = z.infer<typeof ScheduleLogsResponseSchema>;
|
|
export type SchedulePauseResponse = z.infer<typeof SchedulePauseResponseSchema>;
|
|
export type ScheduleResumeResponse = z.infer<typeof ScheduleResumeResponseSchema>;
|
|
export type ScheduleDeleteResponse = z.infer<typeof ScheduleDeleteResponseSchema>;
|
|
export type ScheduleRunOnceResponse = z.infer<typeof ScheduleRunOnceResponseSchema>;
|
|
export type ScheduleUpdateResponse = z.infer<typeof ScheduleUpdateResponseSchema>;
|
|
export type LoopRunResponse = z.infer<typeof LoopRunResponseSchema>;
|
|
export type LoopListResponse = z.infer<typeof LoopListResponseSchema>;
|
|
export type LoopInspectResponse = z.infer<typeof LoopInspectResponseSchema>;
|
|
export type LoopLogsResponse = z.infer<typeof LoopLogsResponseSchema>;
|
|
export type LoopStopResponse = z.infer<typeof LoopStopResponseSchema>;
|
|
|
|
// Type exports for payload types
|
|
export type ActivityLogPayload = z.infer<typeof ActivityLogPayloadSchema>;
|
|
|
|
// Type exports for inbound message types
|
|
export type VoiceAudioChunkMessage = z.infer<typeof VoiceAudioChunkMessageSchema>;
|
|
export type FetchAgentsRequestMessage = z.infer<typeof FetchAgentsRequestMessageSchema>;
|
|
export type FetchAgentHistoryRequestMessage = z.infer<typeof FetchAgentHistoryRequestMessageSchema>;
|
|
export type FetchRecentProviderSessionsRequestMessage = z.infer<
|
|
typeof FetchRecentProviderSessionsRequestMessageSchema
|
|
>;
|
|
export type FetchWorkspacesRequestMessage = z.infer<typeof FetchWorkspacesRequestMessageSchema>;
|
|
export type ProjectListRequestMessage = z.infer<typeof ProjectListRequestMessageSchema>;
|
|
export type FetchAgentRequestMessage = z.infer<typeof FetchAgentRequestMessageSchema>;
|
|
export type AgentForkContextRequestMessage = z.infer<typeof AgentForkContextRequestMessageSchema>;
|
|
export type SendAgentMessageRequest = z.infer<typeof SendAgentMessageRequestSchema>;
|
|
export type WaitForFinishRequest = z.infer<typeof WaitForFinishRequestSchema>;
|
|
export type DictationStreamStartMessage = z.infer<typeof DictationStreamStartMessageSchema>;
|
|
export type DictationStreamChunkMessage = z.infer<typeof DictationStreamChunkMessageSchema>;
|
|
export type DictationStreamFinishMessage = z.infer<typeof DictationStreamFinishMessageSchema>;
|
|
export type DictationStreamCancelMessage = z.infer<typeof DictationStreamCancelMessageSchema>;
|
|
export type CreateAgentRequestMessage = z.infer<typeof CreateAgentRequestMessageSchema>;
|
|
export type AgentAttachment = z.infer<typeof AgentAttachmentSchema>;
|
|
export type ForgeChangeRequestAttachment = z.infer<typeof ForgeChangeRequestAttachmentSchema>;
|
|
export type ForgeIssueAttachment = z.infer<typeof ForgeIssueAttachmentSchema>;
|
|
export type UploadedFileAttachment = z.infer<typeof UploadedFileAttachmentSchema>;
|
|
export type FirstAgentContext = z.infer<typeof FirstAgentContextSchema>;
|
|
export type ReviewAttachment = z.infer<typeof ReviewAttachmentSchema>;
|
|
export type ListProviderModelsRequestMessage = z.infer<
|
|
typeof ListProviderModelsRequestMessageSchema
|
|
>;
|
|
export type ListProviderModesRequestMessage = z.infer<typeof ListProviderModesRequestMessageSchema>;
|
|
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<typeof ChatCreateRequestSchema>;
|
|
export type ChatListRequest = z.infer<typeof ChatListRequestSchema>;
|
|
export type ChatInspectRequest = z.infer<typeof ChatInspectRequestSchema>;
|
|
export type ChatDeleteRequest = z.infer<typeof ChatDeleteRequestSchema>;
|
|
export type ChatPostRequest = z.infer<typeof ChatPostRequestSchema>;
|
|
export type ChatReadRequest = z.infer<typeof ChatReadRequestSchema>;
|
|
export type ChatWaitRequest = z.infer<typeof ChatWaitRequestSchema>;
|
|
export type ScheduleCreateRequest = z.infer<typeof ScheduleCreateRequestSchema>;
|
|
export type ScheduleListRequest = z.infer<typeof ScheduleListRequestSchema>;
|
|
export type ScheduleInspectRequest = z.infer<typeof ScheduleInspectRequestSchema>;
|
|
export type ScheduleLogsRequest = z.infer<typeof ScheduleLogsRequestSchema>;
|
|
export type SchedulePauseRequest = z.infer<typeof SchedulePauseRequestSchema>;
|
|
export type ScheduleResumeRequest = z.infer<typeof ScheduleResumeRequestSchema>;
|
|
export type ScheduleDeleteRequest = z.infer<typeof ScheduleDeleteRequestSchema>;
|
|
export type ScheduleRunOnceRequest = z.infer<typeof ScheduleRunOnceRequestSchema>;
|
|
export type ScheduleUpdateRequest = z.infer<typeof ScheduleUpdateRequestSchema>;
|
|
export type LoopRunRequest = z.infer<typeof LoopRunRequestSchema>;
|
|
export type LoopListRequest = z.infer<typeof LoopListRequestSchema>;
|
|
export type LoopInspectRequest = z.infer<typeof LoopInspectRequestSchema>;
|
|
export type LoopLogsRequest = z.infer<typeof LoopLogsRequestSchema>;
|
|
export type LoopStopRequest = z.infer<typeof LoopStopRequestSchema>;
|
|
export type ResumeAgentRequestMessage = z.infer<typeof ResumeAgentRequestMessageSchema>;
|
|
export type DeleteAgentRequestMessage = z.infer<typeof DeleteAgentRequestMessageSchema>;
|
|
export type UpdateAgentRequestMessage = z.infer<typeof UpdateAgentRequestMessageSchema>;
|
|
export type ProjectIconSource = z.infer<typeof ProjectIconSourceSchema>;
|
|
export type ProjectRenameRequest = z.infer<typeof ProjectRenameRequestSchema>;
|
|
export type ProjectIconSetRequest = z.infer<typeof ProjectIconSetRequestSchema>;
|
|
export type ProjectRemoveRequest = z.infer<typeof ProjectRemoveRequestSchema>;
|
|
export type WorkspaceTitleSetRequest = z.infer<typeof WorkspaceTitleSetRequestSchema>;
|
|
export type WorkspacePinSetRequest = z.infer<typeof WorkspacePinSetRequestSchema>;
|
|
export type WorkspaceRecoveryInspectRequest = z.infer<typeof WorkspaceRecoveryInspectRequestSchema>;
|
|
export type WorkspaceRecoveryRestoreRequest = z.infer<typeof WorkspaceRecoveryRestoreRequestSchema>;
|
|
export type SetAgentModeRequestMessage = z.infer<typeof SetAgentModeRequestMessageSchema>;
|
|
export type SetAgentModelRequestMessage = z.infer<typeof SetAgentModelRequestMessageSchema>;
|
|
export type SetAgentThinkingRequestMessage = z.infer<typeof SetAgentThinkingRequestMessageSchema>;
|
|
export type SetAgentFeatureRequestMessage = z.infer<typeof SetAgentFeatureRequestMessageSchema>;
|
|
export type AgentConfigApplyRequestMessage = z.infer<typeof AgentConfigApplyRequestMessageSchema>;
|
|
export type AgentDetachRequestMessage = z.infer<typeof AgentDetachRequestMessageSchema>;
|
|
export type AgentPermissionResponseMessage = z.infer<typeof AgentPermissionResponseMessageSchema>;
|
|
export type CheckoutStatusRequest = z.infer<typeof CheckoutStatusRequestSchema>;
|
|
export type CheckoutStatusResponse = z.infer<typeof CheckoutStatusResponseSchema>;
|
|
export type CheckoutStatusUpdate = z.infer<typeof CheckoutStatusUpdateSchema>;
|
|
export type SubscribeCheckoutDiffRequest = z.infer<typeof SubscribeCheckoutDiffRequestSchema>;
|
|
export type UnsubscribeCheckoutDiffRequest = z.infer<typeof UnsubscribeCheckoutDiffRequestSchema>;
|
|
export type SubscribeCheckoutDiffResponse = z.infer<typeof SubscribeCheckoutDiffResponseSchema>;
|
|
export type CheckoutDiffUpdate = z.infer<typeof CheckoutDiffUpdateSchema>;
|
|
export type CheckoutCommitRequest = z.infer<typeof CheckoutCommitRequestSchema>;
|
|
export type CheckoutCommitResponse = z.infer<typeof CheckoutCommitResponseSchema>;
|
|
export type CheckoutMergeRequest = z.infer<typeof CheckoutMergeRequestSchema>;
|
|
export type CheckoutMergeResponse = z.infer<typeof CheckoutMergeResponseSchema>;
|
|
export type CheckoutMergeFromBaseRequest = z.infer<typeof CheckoutMergeFromBaseRequestSchema>;
|
|
export type CheckoutMergeFromBaseResponse = z.infer<typeof CheckoutMergeFromBaseResponseSchema>;
|
|
export type CheckoutPullRequest = z.infer<typeof CheckoutPullRequestSchema>;
|
|
export type CheckoutPullResponse = z.infer<typeof CheckoutPullResponseSchema>;
|
|
export type CheckoutPushRequest = z.infer<typeof CheckoutPushRequestSchema>;
|
|
export type CheckoutPushResponse = z.infer<typeof CheckoutPushResponseSchema>;
|
|
export type CheckoutRefreshRequest = z.infer<typeof CheckoutRefreshRequestSchema>;
|
|
export type CheckoutRefreshResponse = z.infer<typeof CheckoutRefreshResponseSchema>;
|
|
export type CheckoutDiscardChangesRequest = z.infer<typeof CheckoutDiscardChangesRequestSchema>;
|
|
export type CheckoutDiscardChangesResponse = z.infer<typeof CheckoutDiscardChangesResponseSchema>;
|
|
export type CheckoutCommitFile = z.infer<typeof CheckoutCommitFileSchema>;
|
|
export type CheckoutCommit = z.infer<typeof CheckoutCommitSchema>;
|
|
export type CheckoutCommitsListRequest = z.infer<typeof CheckoutCommitsListRequestSchema>;
|
|
export type CheckoutCommitsListResponse = z.infer<typeof CheckoutCommitsListResponseSchema>;
|
|
export type CheckoutCommitFileDiffRequest = z.infer<typeof CheckoutCommitFileDiffRequestSchema>;
|
|
export type CheckoutCommitFileDiffResponse = z.infer<typeof CheckoutCommitFileDiffResponseSchema>;
|
|
export type ParsedDiffFile = z.infer<typeof ParsedDiffFileSchema>;
|
|
export type CheckoutPrCreateRequest = z.infer<typeof CheckoutPrCreateRequestSchema>;
|
|
export type CheckoutPrCreateResponse = z.infer<typeof CheckoutPrCreateResponseSchema>;
|
|
export type CheckoutPrMergeRequest = z.infer<typeof CheckoutPrMergeRequestSchema>;
|
|
export type CheckoutPrMergeResponse = z.infer<typeof CheckoutPrMergeResponseSchema>;
|
|
export type CheckoutPrMergeMethod = z.infer<typeof CheckoutPrMergeRequestSchema>["mergeMethod"];
|
|
export type CheckoutForgeSetAutoMergeRequest = z.infer<
|
|
typeof CheckoutForgeSetAutoMergeRequestSchema
|
|
>;
|
|
export type CheckoutForgeSetAutoMergeResponse = z.infer<
|
|
typeof CheckoutForgeSetAutoMergeResponseSchema
|
|
>;
|
|
export type CheckoutGithubSetAutoMergeRequest = z.infer<
|
|
typeof CheckoutGithubSetAutoMergeRequestSchema
|
|
>;
|
|
export type CheckoutGithubSetAutoMergeResponse = z.infer<
|
|
typeof CheckoutGithubSetAutoMergeResponseSchema
|
|
>;
|
|
export type CheckoutForgeGetCheckDetailsRequest = z.infer<
|
|
typeof CheckoutForgeGetCheckDetailsRequestSchema
|
|
>;
|
|
export type CheckoutGithubGetCheckDetailsRequest = z.infer<
|
|
typeof CheckoutGithubGetCheckDetailsRequestSchema
|
|
>;
|
|
export type CheckoutCheckDetails = z.infer<typeof CheckoutCheckDetailsSchema>;
|
|
export type CheckoutGithubCheckDetails = z.infer<typeof CheckoutGithubCheckDetailsSchema>;
|
|
export type CheckoutPipeline = z.infer<typeof CheckoutPipelineSchema>;
|
|
export type CheckoutPipelineStage = z.infer<typeof CheckoutPipelineStageSchema>;
|
|
export type CheckoutPipelineJob = z.infer<typeof CheckoutPipelineJobSchema>;
|
|
export type CheckoutForgeGetCheckDetailsResponse = z.infer<
|
|
typeof CheckoutForgeGetCheckDetailsResponseSchema
|
|
>;
|
|
export type CheckoutGithubGetCheckDetailsResponse = z.infer<
|
|
typeof CheckoutGithubGetCheckDetailsResponseSchema
|
|
>;
|
|
export type PullRequestMergeable = z.infer<typeof CheckoutPrStatusSchema>["mergeable"];
|
|
export type CheckoutPrStatusRequest = z.infer<typeof CheckoutPrStatusRequestSchema>;
|
|
export type CheckoutPrStatusResponse = z.infer<typeof CheckoutPrStatusResponseSchema>;
|
|
export type PullRequestTimelineRequest = z.infer<typeof PullRequestTimelineRequestSchema>;
|
|
export type PullRequestTimelineItem = z.infer<typeof PullRequestTimelineItemSchema>;
|
|
export type PullRequestTimelineResponse = z.infer<typeof PullRequestTimelineResponseSchema>;
|
|
export type CheckoutSwitchBranchRequest = z.infer<typeof CheckoutSwitchBranchRequestSchema>;
|
|
export type CheckoutSwitchBranchResponse = z.infer<typeof CheckoutSwitchBranchResponseSchema>;
|
|
export type CheckoutRenameBranchRequest = z.infer<typeof CheckoutRenameBranchRequestSchema>;
|
|
export type CheckoutRenameBranchResponse = z.infer<typeof CheckoutRenameBranchResponseSchema>;
|
|
export type StashSaveRequest = z.infer<typeof StashSaveRequestSchema>;
|
|
export type StashSaveResponse = z.infer<typeof StashSaveResponseSchema>;
|
|
export type StashPopRequest = z.infer<typeof StashPopRequestSchema>;
|
|
export type StashPopResponse = z.infer<typeof StashPopResponseSchema>;
|
|
export type StashListRequest = z.infer<typeof StashListRequestSchema>;
|
|
export type StashListResponse = z.infer<typeof StashListResponseSchema>;
|
|
export type StashEntry = z.infer<typeof StashEntrySchema>;
|
|
export type ValidateBranchRequest = z.infer<typeof ValidateBranchRequestSchema>;
|
|
export type ValidateBranchResponse = z.infer<typeof ValidateBranchResponseSchema>;
|
|
export type BranchSuggestionsRequest = z.infer<typeof BranchSuggestionsRequestSchema>;
|
|
export type BranchSuggestionsResponse = z.infer<typeof BranchSuggestionsResponseSchema>;
|
|
export type ForgeSearchItem = z.infer<typeof ForgeSearchItemSchema>;
|
|
export type ForgeSearchKind = "issue" | "change_request";
|
|
export type ForgeSearchRequest = z.infer<typeof ForgeSearchRequestSchema>;
|
|
export type ForgeSearchResponse = z.infer<typeof ForgeSearchResponseSchema>;
|
|
export type GitHubSearchItem = z.infer<typeof GitHubSearchItemSchema>;
|
|
export type GitHubSearchKind = z.infer<typeof GitHubSearchKindSchema>;
|
|
export type GitHubSearchRequest = z.infer<typeof GitHubSearchRequestSchema>;
|
|
export type GitHubSearchResponse = z.infer<typeof GitHubSearchResponseSchema>;
|
|
export type ChangeRequestCheckoutSource = z.infer<typeof ChangeRequestCheckoutSourceSchema>;
|
|
export type CreatePaseoWorktreeRequest = z.infer<typeof CreatePaseoWorktreeRequestSchema>;
|
|
export type DirectorySuggestionsRequest = z.infer<typeof DirectorySuggestionsRequestSchema>;
|
|
export type DirectorySuggestionsResponse = z.infer<typeof DirectorySuggestionsResponseSchema>;
|
|
export type PaseoWorktreeListRequest = z.infer<typeof PaseoWorktreeListRequestSchema>;
|
|
export type PaseoWorktreeListResponse = z.infer<typeof PaseoWorktreeListResponseSchema>;
|
|
export type PaseoWorktreeArchiveRequest = z.infer<typeof PaseoWorktreeArchiveRequestSchema>;
|
|
export type PaseoWorktreeArchiveResponse = z.infer<typeof PaseoWorktreeArchiveResponseSchema>;
|
|
export type WorkspaceSetupStatusRequest = z.infer<typeof WorkspaceSetupStatusRequestSchema>;
|
|
export type WorkspaceSetupRunRequest = z.infer<typeof WorkspaceSetupRunRequestSchema>;
|
|
export type LegacyListAvailableEditorsRequest = z.infer<
|
|
typeof LegacyListAvailableEditorsRequestSchema
|
|
>;
|
|
export type LegacyOpenInEditorRequest = z.infer<typeof LegacyOpenInEditorRequestSchema>;
|
|
export type OpenProjectRequest = z.infer<typeof OpenProjectRequestSchema>;
|
|
export type ProjectAddRequest = z.infer<typeof ProjectAddRequestSchema>;
|
|
export type ProjectCreateDirectoryRequest = z.infer<typeof ProjectCreateDirectoryRequestSchema>;
|
|
export type ProjectCreateDirectoryErrorCode = z.infer<typeof ProjectCreateDirectoryErrorCodeSchema>;
|
|
export type WorkspaceGithubSearchRepositoriesRequest = z.infer<
|
|
typeof WorkspaceGithubSearchRepositoriesRequestSchema
|
|
>;
|
|
export type ProjectGithubCloneRequest = z.infer<typeof ProjectGithubCloneRequestSchema>;
|
|
export type ProjectGithubCloneProtocol = z.infer<typeof ProjectGithubCloneProtocolSchema>;
|
|
export type ArchiveWorkspaceRequest = z.infer<typeof ArchiveWorkspaceRequestSchema>;
|
|
export type WorkspaceClearAttentionRequest = z.infer<typeof WorkspaceClearAttentionRequestSchema>;
|
|
export type WorkspaceMarkUnreadRequest = z.infer<typeof WorkspaceMarkUnreadRequestSchema>;
|
|
export type FileExplorerRequest = z.infer<typeof FileExplorerRequestSchema>;
|
|
export type FileExplorerResponse = z.infer<typeof FileExplorerResponseSchema>;
|
|
export type FileVersion = z.infer<typeof FileVersionSchema>;
|
|
export type FileSubscribeRequest = z.infer<typeof FileSubscribeRequestSchema>;
|
|
export type FileSubscribeResponse = z.infer<typeof FileSubscribeResponseSchema>;
|
|
export type FileUnsubscribeRequest = z.infer<typeof FileUnsubscribeRequestSchema>;
|
|
export type FileUnsubscribeResponse = z.infer<typeof FileUnsubscribeResponseSchema>;
|
|
export type FileWriteRequest = z.infer<typeof FileWriteRequestSchema>;
|
|
export type FileWriteResponse = z.infer<typeof FileWriteResponseSchema>;
|
|
export type FileEntryCreateRequest = z.infer<typeof FileEntryCreateRequestSchema>;
|
|
export type FileEntryCreateResponse = z.infer<typeof FileEntryCreateResponseSchema>;
|
|
export type FileEntryRenameRequest = z.infer<typeof FileEntryRenameRequestSchema>;
|
|
export type FileEntryRenameResponse = z.infer<typeof FileEntryRenameResponseSchema>;
|
|
export type FileEntryDuplicateRequest = z.infer<typeof FileEntryDuplicateRequestSchema>;
|
|
export type FileEntryDuplicateResponse = z.infer<typeof FileEntryDuplicateResponseSchema>;
|
|
export type FileEntryDeleteRequest = z.infer<typeof FileEntryDeleteRequestSchema>;
|
|
export type FileEntryDeleteResponse = z.infer<typeof FileEntryDeleteResponseSchema>;
|
|
export type FileWriteResult = z.infer<typeof FileWriteResultSchema>;
|
|
export type FileUpdate = z.infer<typeof FileUpdateSchema>;
|
|
export type ProjectIconRequest = z.infer<typeof ProjectIconRequestSchema>;
|
|
export type ProjectIconResponse = z.infer<typeof ProjectIconResponseSchema>;
|
|
export type ProjectIconGetRequest = z.infer<typeof ProjectIconGetRequestSchema>;
|
|
export type ProjectIconGetResponse = z.infer<typeof ProjectIconGetResponseSchema>;
|
|
export type ProjectIcon = z.infer<typeof ProjectIconSchema>;
|
|
export type FileDownloadTokenRequest = z.infer<typeof FileDownloadTokenRequestSchema>;
|
|
export type FileDownloadTokenResponse = z.infer<typeof FileDownloadTokenResponseSchema>;
|
|
export type FileUploadRequest = z.infer<typeof FileUploadRequestSchema>;
|
|
export type FileUploadResponse = z.infer<typeof FileUploadResponseSchema>;
|
|
export type RestartServerRequestMessage = z.infer<typeof RestartServerRequestMessageSchema>;
|
|
export type ShutdownServerRequestMessage = z.infer<typeof ShutdownServerRequestMessageSchema>;
|
|
export type ClearAgentAttentionMessage = z.infer<typeof ClearAgentAttentionMessageSchema>;
|
|
export type ClearAgentAttentionResponseMessage = z.infer<
|
|
typeof ClearAgentAttentionResponseMessageSchema
|
|
>;
|
|
export type ClientHeartbeatMessage = z.infer<typeof ClientHeartbeatMessageSchema>;
|
|
export type ListCommandsRequest = z.infer<typeof ListCommandsRequestSchema>;
|
|
export type ListCommandsResponse = z.infer<typeof ListCommandsResponseSchema>;
|
|
export type RegisterPushTokenMessage = z.infer<typeof RegisterPushTokenMessageSchema>;
|
|
export type PushUnregisterRequest = z.infer<typeof PushUnregisterRequestSchema>;
|
|
export type PushUnregisterResponse = z.infer<typeof PushUnregisterResponseSchema>;
|
|
|
|
// Terminal message types
|
|
export type ListTerminalsRequest = z.infer<typeof ListTerminalsRequestSchema>;
|
|
export type ListTerminalsResponse = z.infer<typeof ListTerminalsResponseSchema>;
|
|
export type SubscribeTerminalsRequest = z.infer<typeof SubscribeTerminalsRequestSchema>;
|
|
export type UnsubscribeTerminalsRequest = z.infer<typeof UnsubscribeTerminalsRequestSchema>;
|
|
export type TerminalsChanged = z.infer<typeof TerminalsChangedSchema>;
|
|
export type CreateTerminalRequest = z.infer<typeof CreateTerminalRequestSchema>;
|
|
export type CreateTerminalResponse = z.infer<typeof CreateTerminalResponseSchema>;
|
|
export type RenameTerminalRequest = z.infer<typeof RenameTerminalRequestSchema>;
|
|
export type RenameTerminalResponse = z.infer<typeof RenameTerminalResponseSchema>;
|
|
export type StartWorkspaceScriptRequest = z.infer<typeof StartWorkspaceScriptRequestSchema>;
|
|
export type StartWorkspaceScriptResponse = z.infer<
|
|
typeof StartWorkspaceScriptResponseMessageSchema
|
|
>;
|
|
export type SubscribeTerminalRequest = z.infer<typeof SubscribeTerminalRequestSchema>;
|
|
export type SubscribeTerminalResponse = z.infer<typeof SubscribeTerminalResponseSchema>;
|
|
export type UnsubscribeTerminalRequest = z.infer<typeof UnsubscribeTerminalRequestSchema>;
|
|
export type TerminalInput = z.infer<typeof TerminalInputSchema>;
|
|
export type TerminalCell = z.infer<typeof TerminalCellSchema>;
|
|
export type TerminalCursorStyle = z.infer<typeof TerminalCursorStyleSchema>;
|
|
export type TerminalCursor = z.infer<typeof TerminalCursorSchema>;
|
|
export type TerminalState = z.infer<typeof TerminalStateSchema>;
|
|
export type CloseItemsRequest = z.infer<typeof CloseItemsRequestMessageSchema>;
|
|
export type CloseItemsResponse = z.infer<typeof CloseItemsResponseSchema>;
|
|
export type KillTerminalRequest = z.infer<typeof KillTerminalRequestSchema>;
|
|
export type KillTerminalResponse = z.infer<typeof KillTerminalResponseSchema>;
|
|
export type CaptureTerminalRequest = z.infer<typeof CaptureTerminalRequestSchema>;
|
|
export type CaptureTerminalResponse = z.infer<typeof CaptureTerminalResponseSchema>;
|
|
export type TerminalStreamExit = z.infer<typeof TerminalStreamExitSchema>;
|
|
|
|
// ============================================================================
|
|
// 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", "hub"]),
|
|
protocolVersion: z.number().int(),
|
|
auth: z
|
|
.discriminatedUnion("kind", [
|
|
z.object({ kind: z.literal("password"), password: z.string() }),
|
|
z.object({ kind: z.literal("localCredential"), token: z.string() }),
|
|
])
|
|
.optional(),
|
|
appVersion: z.string().optional(),
|
|
capabilities: z
|
|
.object({
|
|
voice: z.boolean().optional(),
|
|
[CLIENT_CAPS.helloRejection]: z.boolean().optional(),
|
|
pushNotifications: z.boolean().optional(),
|
|
[CLIENT_CAPS.explicitEventSubscriptions]: z.boolean().optional(),
|
|
[CLIENT_CAPS.allProviders]: z.boolean().optional(),
|
|
[CLIENT_CAPS.reasoningMergeEnum]: z.boolean().optional(),
|
|
[CLIENT_CAPS.selectiveAgentTimeline]: z.boolean().optional(),
|
|
[CLIENT_CAPS.customModeIcons]: z.boolean().optional(),
|
|
[CLIENT_CAPS.terminalReflowableSnapshot]: z.boolean().optional(),
|
|
[CLIENT_CAPS.providerSubagents]: z.boolean().optional(),
|
|
[CLIENT_CAPS.projectUpdates]: z.boolean().optional(),
|
|
[CLIENT_CAPS.compactProviderSnapshots]: z.boolean().optional(),
|
|
[CLIENT_CAPS.providerSnapshotReferences]: z.boolean().optional(),
|
|
[CLIENT_CAPS.timelineReplacementInvalidation]: z.boolean().optional(),
|
|
[CLIENT_CAPS.timelineNotifications]: z.boolean().optional(),
|
|
[CLIENT_CAPS.browserHost]: BrowserAutomationHostCapabilitySchema.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,
|
|
});
|
|
|
|
export const WSHelloRejectedMessageSchema = z.object({
|
|
type: z.literal("hello.rejected"),
|
|
reason: z.enum(["password_required", "incorrect_password", "incompatible_protocol"]),
|
|
accepts: z.array(z.literal("password")),
|
|
});
|
|
|
|
// Complete WebSocket message schemas
|
|
export const WSInboundMessageSchema = z.discriminatedUnion("type", [
|
|
WSPingMessageSchema,
|
|
WSHelloMessageSchema,
|
|
WSRecordingStateMessageSchema,
|
|
WSSessionInboundSchema,
|
|
]);
|
|
|
|
export const WSOutboundMessageSchema = z.discriminatedUnion("type", [
|
|
WSPongMessageSchema,
|
|
WSSessionOutboundSchema,
|
|
WSHelloRejectedMessageSchema,
|
|
]);
|
|
|
|
export type WSInboundMessage = z.infer<typeof WSInboundMessageSchema>;
|
|
export type WSOutboundMessage = z.infer<typeof WSOutboundMessageSchema>;
|
|
export type WSHelloMessage = z.infer<typeof WSHelloMessageSchema>;
|
|
|
|
// ============================================================================
|
|
// 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;
|
|
}
|