@otto-code/protocol 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/agent-attention-notification.d.ts +41 -0
- package/dist/agent-attention-notification.js +140 -0
- package/dist/agent-labels.d.ts +7 -0
- package/dist/agent-labels.js +11 -0
- package/dist/agent-lifecycle.d.ts +3 -0
- package/dist/agent-lifecycle.js +8 -0
- package/dist/agent-personalities.d.ts +32 -0
- package/dist/agent-personalities.js +69 -0
- package/dist/agent-state-bucket.d.ts +14 -0
- package/dist/agent-state-bucket.js +41 -0
- package/dist/agent-title-limits.d.ts +2 -0
- package/dist/agent-title-limits.js +2 -0
- package/dist/agent-types.d.ts +479 -0
- package/dist/agent-types.js +22 -0
- package/dist/artifacts/rpc-schemas.d.ts +396 -0
- package/dist/artifacts/rpc-schemas.js +175 -0
- package/dist/artifacts/types.d.ts +166 -0
- package/dist/artifacts/types.js +73 -0
- package/dist/binary-frames/demux.d.ts +11 -0
- package/dist/binary-frames/demux.js +23 -0
- package/dist/binary-frames/file-transfer.d.ts +50 -0
- package/dist/binary-frames/file-transfer.js +107 -0
- package/dist/binary-frames/index.d.ts +4 -0
- package/dist/binary-frames/index.js +4 -0
- package/dist/binary-frames/terminal.d.ts +31 -0
- package/dist/binary-frames/terminal.js +99 -0
- package/dist/branch-slug.d.ts +14 -0
- package/dist/branch-slug.js +49 -0
- package/dist/browser-automation/capabilities.d.ts +7 -0
- package/dist/browser-automation/capabilities.js +31 -0
- package/dist/browser-automation/rpc-schemas.d.ts +1329 -0
- package/dist/browser-automation/rpc-schemas.js +555 -0
- package/dist/chat/rpc-schemas.d.ts +158 -0
- package/dist/chat/rpc-schemas.js +103 -0
- package/dist/chat/types.d.ts +30 -0
- package/dist/chat/types.js +22 -0
- package/dist/client-capabilities.d.ts +8 -0
- package/dist/client-capabilities.js +16 -0
- package/dist/connection-offer.d.ts +36 -0
- package/dist/connection-offer.js +53 -0
- package/dist/daemon-endpoints.d.ts +47 -0
- package/dist/daemon-endpoints.js +201 -0
- package/dist/default-personalities.d.ts +3 -0
- package/dist/default-personalities.js +127 -0
- package/dist/effort.d.ts +32 -0
- package/dist/effort.js +99 -0
- package/dist/error-utils.d.ts +11 -0
- package/dist/error-utils.js +27 -0
- package/dist/generated/validation/ws-outbound.aot.d.ts +2 -0
- package/dist/generated/validation/ws-outbound.aot.js +48755 -0
- package/dist/git-hosting.d.ts +21 -0
- package/dist/git-hosting.js +36 -0
- package/dist/git-remote.d.ts +18 -0
- package/dist/git-remote.js +84 -0
- package/dist/host-connection-schema.d.ts +11 -0
- package/dist/host-connection-schema.js +9 -0
- package/dist/literal-union.d.ts +2 -0
- package/dist/literal-union.js +2 -0
- package/dist/loop/rpc-schemas.d.ts +636 -0
- package/dist/loop/rpc-schemas.js +163 -0
- package/dist/messages.d.ts +38505 -0
- package/dist/messages.js +4719 -0
- package/dist/otto-config-schema.d.ts +136 -0
- package/dist/otto-config-schema.js +96 -0
- package/dist/path-utils.d.ts +2 -0
- package/dist/path-utils.js +16 -0
- package/dist/provider-config.d.ts +266 -0
- package/dist/provider-config.js +238 -0
- package/dist/provider-icon-names.d.ts +5 -0
- package/dist/provider-icon-names.js +52 -0
- package/dist/provider-manifest.d.ts +34 -0
- package/dist/provider-manifest.js +227 -0
- package/dist/schedule/cron-expression.d.ts +13 -0
- package/dist/schedule/cron-expression.js +97 -0
- package/dist/schedule/rpc-schemas.d.ts +667 -0
- package/dist/schedule/rpc-schemas.js +155 -0
- package/dist/schedule/types.d.ts +236 -0
- package/dist/schedule/types.js +84 -0
- package/dist/terminal-activity.d.ts +21 -0
- package/dist/terminal-activity.js +25 -0
- package/dist/terminal-input-mode.d.ts +26 -0
- package/dist/terminal-input-mode.js +151 -0
- package/dist/terminal-key-input.d.ts +13 -0
- package/dist/terminal-key-input.js +201 -0
- package/dist/terminal-profiles.d.ts +6 -0
- package/dist/terminal-profiles.js +28 -0
- package/dist/terminal-snapshot.d.ts +3 -0
- package/dist/terminal-snapshot.js +178 -0
- package/dist/terminal-stream-protocol.d.ts +2 -0
- package/dist/terminal-stream-protocol.js +2 -0
- package/dist/terminal-subscription-key.d.ts +2 -0
- package/dist/terminal-subscription-key.js +9 -0
- package/dist/tool-call-display.d.ts +11 -0
- package/dist/tool-call-display.js +135 -0
- package/dist/tool-name-normalization.d.ts +9 -0
- package/dist/tool-name-normalization.js +82 -0
- package/dist/validation/ws-outbound-schema-metadata.d.ts +7256 -0
- package/dist/validation/ws-outbound-schema-metadata.js +3 -0
- package/dist/validation/ws-outbound.d.ts +12 -0
- package/dist/validation/ws-outbound.js +8 -0
- package/package.json +42 -0
package/dist/messages.js
ADDED
|
@@ -0,0 +1,4719 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { TerminalActivitySchema } from "./terminal-activity.js";
|
|
3
|
+
import { ArtifactMetadataSchema } from "./artifacts/types.js";
|
|
4
|
+
import { ArtifactListRequestSchema, ArtifactCreateRequestSchema, ArtifactUpdateRequestSchema, ArtifactRegenerateRequestSchema, ArtifactCancelRequestSchema, ArtifactDeleteRequestSchema, ArtifactStarRequestSchema, ArtifactGetContentRequestSchema, ArtifactListResponseSchema, ArtifactCreateResponseSchema, ArtifactUpdateResponseSchema, ArtifactRegenerateResponseSchema, ArtifactCancelResponseSchema, ArtifactDeleteResponseSchema, ArtifactStarResponseSchema, ArtifactGetContentResponseSchema, ArtifactCreatedNotificationSchema, ArtifactUpdatedNotificationSchema, ArtifactDeletedNotificationSchema, } from "./artifacts/rpc-schemas.js";
|
|
5
|
+
import { CLIENT_CAPS } from "./client-capabilities.js";
|
|
6
|
+
import { AGENT_LIFECYCLE_STATUSES } from "./agent-lifecycle.js";
|
|
7
|
+
import { MAX_EXPLICIT_AGENT_TITLE_CHARS } from "./agent-title-limits.js";
|
|
8
|
+
import { AgentProviderSchema } from "./provider-manifest.js";
|
|
9
|
+
import { McpServerConfigSchema, OTTO_TOOL_GROUPS } from "./provider-config.js";
|
|
10
|
+
import { TOOL_CALL_ICON_NAMES } from "./agent-types.js";
|
|
11
|
+
import { ChatCreateRequestSchema, ChatListRequestSchema, ChatInspectRequestSchema, ChatDeleteRequestSchema, ChatPostRequestSchema, ChatReadRequestSchema, ChatWaitRequestSchema, ChatCreateResponseSchema, ChatListResponseSchema, ChatInspectResponseSchema, ChatDeleteResponseSchema, ChatPostResponseSchema, ChatReadResponseSchema, ChatWaitResponseSchema, } from "./chat/rpc-schemas.js";
|
|
12
|
+
import { ScheduleCreateRequestSchema, ScheduleListRequestSchema, ScheduleInspectRequestSchema, ScheduleLogsRequestSchema, SchedulePauseRequestSchema, ScheduleResumeRequestSchema, ScheduleDeleteRequestSchema, ScheduleRunOnceRequestSchema, ScheduleUpdateRequestSchema, ScheduleCreateResponseSchema, ScheduleListResponseSchema, ScheduleInspectResponseSchema, ScheduleLogsResponseSchema, SchedulePauseResponseSchema, ScheduleResumeResponseSchema, ScheduleDeleteResponseSchema, ScheduleRunOnceResponseSchema, ScheduleUpdateResponseSchema, } from "./schedule/rpc-schemas.js";
|
|
13
|
+
import { LoopRunRequestSchema, LoopListRequestSchema, LoopInspectRequestSchema, LoopLogsRequestSchema, LoopStopRequestSchema, LoopRunResponseSchema, LoopListResponseSchema, LoopInspectResponseSchema, LoopLogsResponseSchema, LoopStopResponseSchema, } from "./loop/rpc-schemas.js";
|
|
14
|
+
import { BrowserAutomationExecuteRequestSchema, BrowserAutomationExecuteResponseSchema, } from "./browser-automation/rpc-schemas.js";
|
|
15
|
+
import { BrowserAutomationHostCapabilitySchema } from "./browser-automation/capabilities.js";
|
|
16
|
+
import { OttoConfigRawSchema, OttoLifecycleCommandRawSchema, OttoMetadataGenerationEntrySchema, OttoMetadataGenerationSchema, OttoScriptEntryRawSchema, OttoWorktreeConfigRawSchema, OttoConfigRevisionSchema, ProjectConfigRpcErrorSchema, } from "./otto-config-schema.js";
|
|
17
|
+
import { GitHostingCapabilitiesSchema, GitHostingProviderIdWireSchema } from "./git-hosting.js";
|
|
18
|
+
export { GitHostingCapabilitiesSchema, GitHostingProviderIdSchema, GitHostingProviderIdWireSchema, isGitHostingProviderId, normalizeGitHostingProviderId, GIT_HOSTING_PROVIDER_IDS, } from "./git-hosting.js";
|
|
19
|
+
export { OttoConfigRawSchema, OttoLifecycleCommandRawSchema, OttoMetadataGenerationEntrySchema, OttoMetadataGenerationSchema, OttoScriptEntryRawSchema, OttoWorktreeConfigRawSchema, };
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Mutable daemon config schemas (shared between server store and client)
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
const MutableDaemonProviderModelSchema = z
|
|
24
|
+
.object({
|
|
25
|
+
id: z.string().min(1),
|
|
26
|
+
label: z.string().min(1),
|
|
27
|
+
description: z.string().optional(),
|
|
28
|
+
isDefault: z.boolean().optional(),
|
|
29
|
+
})
|
|
30
|
+
.passthrough();
|
|
31
|
+
const MutableDaemonProviderConfigSchema = z
|
|
32
|
+
.object({
|
|
33
|
+
enabled: z.boolean().optional(),
|
|
34
|
+
additionalModels: z.array(MutableDaemonProviderModelSchema).optional(),
|
|
35
|
+
ottoToolGroups: z.array(z.enum(OTTO_TOOL_GROUPS)).optional(),
|
|
36
|
+
})
|
|
37
|
+
.passthrough();
|
|
38
|
+
const MutableStructuredGenerationProviderSchema = z
|
|
39
|
+
.object({
|
|
40
|
+
provider: z.string().min(1),
|
|
41
|
+
model: z.string().min(1).optional(),
|
|
42
|
+
thinkingOptionId: z.string().min(1).optional(),
|
|
43
|
+
})
|
|
44
|
+
.passthrough();
|
|
45
|
+
const MutableMetadataGenerationConfigSchema = z
|
|
46
|
+
.object({
|
|
47
|
+
providers: z.array(MutableStructuredGenerationProviderSchema).default([]),
|
|
48
|
+
})
|
|
49
|
+
.passthrough();
|
|
50
|
+
export const TerminalProfileSchema = z
|
|
51
|
+
.object({
|
|
52
|
+
id: z.string(),
|
|
53
|
+
name: z.string(),
|
|
54
|
+
command: z.string(),
|
|
55
|
+
args: z.array(z.string()).optional(),
|
|
56
|
+
icon: z.string().optional(),
|
|
57
|
+
})
|
|
58
|
+
.passthrough();
|
|
59
|
+
const MutableBrowserToolsConfigSchema = z
|
|
60
|
+
.object({
|
|
61
|
+
enabled: z.boolean().default(false),
|
|
62
|
+
})
|
|
63
|
+
.passthrough();
|
|
64
|
+
// Speech engine ids and model ids stay plain strings on the wire so adding an
|
|
65
|
+
// engine or model never breaks an older peer; the daemon validates values
|
|
66
|
+
// against its own catalog when applying a patch.
|
|
67
|
+
const MutableSpeechSttConfigSchema = z
|
|
68
|
+
.object({
|
|
69
|
+
provider: z.string().optional(),
|
|
70
|
+
model: z.string().optional(),
|
|
71
|
+
language: z.string().optional(),
|
|
72
|
+
})
|
|
73
|
+
.passthrough();
|
|
74
|
+
const MutableSpeechTtsConfigSchema = z
|
|
75
|
+
.object({
|
|
76
|
+
provider: z.string().optional(),
|
|
77
|
+
model: z.string().optional(),
|
|
78
|
+
// Voice name (e.g. "af_heart" for local Kokoro, "alloy" for OpenAI). The
|
|
79
|
+
// daemon maps local voice names to sherpa speaker ids internally.
|
|
80
|
+
voice: z.string().optional(),
|
|
81
|
+
speed: z.number().optional(),
|
|
82
|
+
})
|
|
83
|
+
.passthrough();
|
|
84
|
+
const MutableSpeechDictationConfigSchema = z
|
|
85
|
+
.object({
|
|
86
|
+
enabled: z.boolean().optional(),
|
|
87
|
+
stt: MutableSpeechSttConfigSchema.optional(),
|
|
88
|
+
})
|
|
89
|
+
.passthrough();
|
|
90
|
+
const MutableSpeechVoiceModeConfigSchema = z
|
|
91
|
+
.object({
|
|
92
|
+
enabled: z.boolean().optional(),
|
|
93
|
+
stt: MutableSpeechSttConfigSchema.optional(),
|
|
94
|
+
tts: MutableSpeechTtsConfigSchema.optional(),
|
|
95
|
+
})
|
|
96
|
+
.passthrough();
|
|
97
|
+
// Credentials for the OpenAI speech engine. The key persists to config.json
|
|
98
|
+
// (providers.openai.apiKey) like provider env keys do, and is echoed back in
|
|
99
|
+
// get_daemon_config_response the same way provider connection keys are.
|
|
100
|
+
const MutableSpeechOpenAiConfigSchema = z
|
|
101
|
+
.object({
|
|
102
|
+
apiKey: z.string().optional(),
|
|
103
|
+
})
|
|
104
|
+
.passthrough();
|
|
105
|
+
export const MutableSpeechConfigSchema = z
|
|
106
|
+
.object({
|
|
107
|
+
dictation: MutableSpeechDictationConfigSchema.optional(),
|
|
108
|
+
voiceMode: MutableSpeechVoiceModeConfigSchema.optional(),
|
|
109
|
+
openai: MutableSpeechOpenAiConfigSchema.optional(),
|
|
110
|
+
})
|
|
111
|
+
.passthrough();
|
|
112
|
+
// Host-level git hosting credentials, one set per provider. A workspace's
|
|
113
|
+
// provider is derived from its git remote (bitbucket.org → Bitbucket,
|
|
114
|
+
// github.com → GitHub), so credentials are configured once per host, not per
|
|
115
|
+
// project. Keys persist to $OTTO_HOME/config.json and are echoed in
|
|
116
|
+
// get_daemon_config_response the same way provider connection keys are.
|
|
117
|
+
const MutableGitHostingBitbucketCloudConfigSchema = z
|
|
118
|
+
.object({
|
|
119
|
+
// Atlassian account email + API token, sent as HTTP Basic auth.
|
|
120
|
+
email: z.string().optional(),
|
|
121
|
+
apiToken: z.string().optional(),
|
|
122
|
+
})
|
|
123
|
+
.passthrough();
|
|
124
|
+
const MutableGitHostingProvidersConfigSchema = z
|
|
125
|
+
.object({
|
|
126
|
+
bitbucketCloud: MutableGitHostingBitbucketCloudConfigSchema.optional(),
|
|
127
|
+
})
|
|
128
|
+
.passthrough();
|
|
129
|
+
export const MutableGitHostingConfigSchema = z
|
|
130
|
+
.object({
|
|
131
|
+
providers: MutableGitHostingProvidersConfigSchema.optional(),
|
|
132
|
+
})
|
|
133
|
+
.passthrough();
|
|
134
|
+
// Canonical personality roles, in display order. Kept as an exported const so
|
|
135
|
+
// the daemon and app share one vocabulary, but the wire schema stores roles as
|
|
136
|
+
// plain strings (below) — adding an 8th role later must never break an older
|
|
137
|
+
// peer's parsing. Consumers filter incoming role arrays to this known set.
|
|
138
|
+
export const PERSONALITY_ROLES = [
|
|
139
|
+
"chatter",
|
|
140
|
+
"artificer",
|
|
141
|
+
"scheduler",
|
|
142
|
+
"worker",
|
|
143
|
+
"judger",
|
|
144
|
+
"advisor",
|
|
145
|
+
"orchestrator",
|
|
146
|
+
];
|
|
147
|
+
// Two glow colors for the personality's thinking spinner (BlobLoader glowA/glowB).
|
|
148
|
+
const AgentPersonalitySpinnerSchema = z
|
|
149
|
+
.object({
|
|
150
|
+
glowA: z.string().min(1),
|
|
151
|
+
glowB: z.string().min(1),
|
|
152
|
+
})
|
|
153
|
+
.passthrough();
|
|
154
|
+
// A TTS voice for the personality's spoken identity. Stored self-describing —
|
|
155
|
+
// provider + model + voice name — because voice names are namespaced per TTS
|
|
156
|
+
// engine/model (the same speaker index maps to different names across models),
|
|
157
|
+
// so a bare name is ambiguous across hosts. All plain strings (like the speech
|
|
158
|
+
// config) for forward-compat. This is a soft binding: an unavailable voice
|
|
159
|
+
// degrades to the host default at playback time, it never takes the personality
|
|
160
|
+
// out of commission.
|
|
161
|
+
const AgentPersonalityVoiceSchema = z
|
|
162
|
+
.object({
|
|
163
|
+
provider: z.string().min(1),
|
|
164
|
+
model: z.string().min(1),
|
|
165
|
+
name: z.string().min(1),
|
|
166
|
+
})
|
|
167
|
+
.passthrough();
|
|
168
|
+
// A named, reusable agent template stored per-host. `id` is the stable identity
|
|
169
|
+
// everything binds to; `name` is a freely-renamable label. Effort and roles are
|
|
170
|
+
// plain strings on the wire (like speech engine/model ids) so the daemon can
|
|
171
|
+
// grow the vocabulary without breaking old peers; the daemon validates them
|
|
172
|
+
// against its own catalog when applying a patch.
|
|
173
|
+
export const AgentPersonalitySchema = z
|
|
174
|
+
.object({
|
|
175
|
+
id: z.string().min(1),
|
|
176
|
+
name: z.string().min(1),
|
|
177
|
+
provider: z.string().min(1),
|
|
178
|
+
model: z.string().min(1),
|
|
179
|
+
// Canonical effort level ("off".."max"); resolved to the bound model's
|
|
180
|
+
// nearest advertised option at spawn.
|
|
181
|
+
effortLevel: z.string().min(1).optional(),
|
|
182
|
+
modeId: z.string().min(1).optional(),
|
|
183
|
+
personalityPrompt: z.string().optional(),
|
|
184
|
+
// Default true: the daemon-global appendSystemPrompt still stacks on top of
|
|
185
|
+
// the personality prompt. False = the personality prompt stands alone.
|
|
186
|
+
respectGlobalAppendPrompt: z.boolean().optional(),
|
|
187
|
+
roles: z.array(z.string().min(1)).optional(),
|
|
188
|
+
spinner: AgentPersonalitySpinnerSchema.optional(),
|
|
189
|
+
voice: AgentPersonalityVoiceSchema.optional(),
|
|
190
|
+
})
|
|
191
|
+
.passthrough();
|
|
192
|
+
const MutableAgentPersonalitiesConfigSchema = z
|
|
193
|
+
.object({
|
|
194
|
+
personalities: z.array(AgentPersonalitySchema).default([]),
|
|
195
|
+
})
|
|
196
|
+
.passthrough();
|
|
197
|
+
export const MutableDaemonConfigSchema = z
|
|
198
|
+
.object({
|
|
199
|
+
mcp: z
|
|
200
|
+
.object({
|
|
201
|
+
injectIntoAgents: z.boolean(),
|
|
202
|
+
})
|
|
203
|
+
.passthrough(),
|
|
204
|
+
browserTools: MutableBrowserToolsConfigSchema.default({ enabled: false }),
|
|
205
|
+
providers: z.record(z.string(), MutableDaemonProviderConfigSchema).default({}),
|
|
206
|
+
metadataGeneration: MutableMetadataGenerationConfigSchema.default({ providers: [] }),
|
|
207
|
+
autoArchiveAfterMerge: z.boolean().default(false),
|
|
208
|
+
enableTerminalAgentHooks: z.boolean().default(false),
|
|
209
|
+
appendSystemPrompt: z.string().default(""),
|
|
210
|
+
terminalProfiles: z.array(TerminalProfileSchema).optional(),
|
|
211
|
+
// Absent on daemons without the speechSettings feature.
|
|
212
|
+
speech: MutableSpeechConfigSchema.optional(),
|
|
213
|
+
// Absent on daemons without the gitHostingProviders feature.
|
|
214
|
+
gitHosting: MutableGitHostingConfigSchema.optional(),
|
|
215
|
+
// Per-host agent personality roster. Gated by the agentPersonalities
|
|
216
|
+
// feature; defaults to an empty roster so a new client parsing an old
|
|
217
|
+
// daemon's config still sees a well-formed section.
|
|
218
|
+
agentPersonalities: MutableAgentPersonalitiesConfigSchema.default({ personalities: [] }),
|
|
219
|
+
})
|
|
220
|
+
.passthrough();
|
|
221
|
+
export const MutableDaemonConfigPatchSchema = z
|
|
222
|
+
.object({
|
|
223
|
+
mcp: MutableDaemonConfigSchema.shape.mcp.partial().optional(),
|
|
224
|
+
browserTools: MutableBrowserToolsConfigSchema.partial().optional(),
|
|
225
|
+
// A null entry removes the provider's config entirely (custom provider
|
|
226
|
+
// uninstall). Gated by server_info features.providerRemove — old daemons
|
|
227
|
+
// reject null values.
|
|
228
|
+
providers: z
|
|
229
|
+
.record(z.string(), MutableDaemonProviderConfigSchema.partial().passthrough().nullable())
|
|
230
|
+
.optional(),
|
|
231
|
+
metadataGeneration: MutableMetadataGenerationConfigSchema.partial().optional(),
|
|
232
|
+
autoArchiveAfterMerge: z.boolean().optional(),
|
|
233
|
+
enableTerminalAgentHooks: z.boolean().optional(),
|
|
234
|
+
appendSystemPrompt: z.string().optional(),
|
|
235
|
+
terminalProfiles: z.array(TerminalProfileSchema).optional(),
|
|
236
|
+
// Gated by server_info features.speechSettings; every field is optional so
|
|
237
|
+
// patches deep-merge into the daemon's current speech config.
|
|
238
|
+
speech: MutableSpeechConfigSchema.optional(),
|
|
239
|
+
// Gated by server_info features.gitHostingProviders; patches deep-merge.
|
|
240
|
+
gitHosting: MutableGitHostingConfigSchema.optional(),
|
|
241
|
+
// Gated by server_info features.agentPersonalities. A patch replaces the
|
|
242
|
+
// full roster (read-modify-write the array), matching how terminalProfiles
|
|
243
|
+
// and metadataGeneration.providers patch.
|
|
244
|
+
agentPersonalities: MutableAgentPersonalitiesConfigSchema.partial().optional(),
|
|
245
|
+
})
|
|
246
|
+
.partial()
|
|
247
|
+
.passthrough();
|
|
248
|
+
export const AgentStatusSchema = z.enum(AGENT_LIFECYCLE_STATUSES);
|
|
249
|
+
const AgentModeSchema = z.object({
|
|
250
|
+
id: z.string(),
|
|
251
|
+
label: z.string(),
|
|
252
|
+
description: z.string().optional(),
|
|
253
|
+
icon: z.string().optional(),
|
|
254
|
+
colorTier: z.string().optional(),
|
|
255
|
+
});
|
|
256
|
+
const ProviderStatusSchema = z.enum([
|
|
257
|
+
"ready",
|
|
258
|
+
"loading",
|
|
259
|
+
"error",
|
|
260
|
+
"unavailable",
|
|
261
|
+
]);
|
|
262
|
+
const AgentSelectOptionSchema = z.object({
|
|
263
|
+
id: z.string(),
|
|
264
|
+
label: z.string(),
|
|
265
|
+
description: z.string().optional(),
|
|
266
|
+
isDefault: z.boolean().optional(),
|
|
267
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
268
|
+
});
|
|
269
|
+
const AgentProviderNoticeSchema = z.discriminatedUnion("type", [
|
|
270
|
+
z.object({ type: z.literal("info"), message: z.string() }),
|
|
271
|
+
z.object({ type: z.literal("warning"), message: z.string() }),
|
|
272
|
+
z.object({ type: z.literal("error"), message: z.string() }),
|
|
273
|
+
]);
|
|
274
|
+
export const AgentFeatureToggleSchema = z.object({
|
|
275
|
+
type: z.literal("toggle"),
|
|
276
|
+
id: z.string(),
|
|
277
|
+
label: z.string(),
|
|
278
|
+
description: z.string().optional(),
|
|
279
|
+
tooltip: z.string().optional(),
|
|
280
|
+
icon: z.string().optional(),
|
|
281
|
+
value: z.boolean(),
|
|
282
|
+
});
|
|
283
|
+
export const AgentFeatureSelectSchema = z.object({
|
|
284
|
+
type: z.literal("select"),
|
|
285
|
+
id: z.string(),
|
|
286
|
+
label: z.string(),
|
|
287
|
+
description: z.string().optional(),
|
|
288
|
+
tooltip: z.string().optional(),
|
|
289
|
+
icon: z.string().optional(),
|
|
290
|
+
value: z.string().nullable(),
|
|
291
|
+
options: z.array(AgentSelectOptionSchema),
|
|
292
|
+
});
|
|
293
|
+
export const AgentFeatureSchema = z.discriminatedUnion("type", [
|
|
294
|
+
AgentFeatureToggleSchema,
|
|
295
|
+
AgentFeatureSelectSchema,
|
|
296
|
+
]);
|
|
297
|
+
const AgentModelDefinitionSchema = z.object({
|
|
298
|
+
provider: AgentProviderSchema,
|
|
299
|
+
id: z.string(),
|
|
300
|
+
label: z.string(),
|
|
301
|
+
description: z.string().optional(),
|
|
302
|
+
isDefault: z.boolean().optional(),
|
|
303
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
304
|
+
contextWindowMaxTokens: z.number().optional(),
|
|
305
|
+
thinkingOptions: z.array(AgentSelectOptionSchema).optional(),
|
|
306
|
+
defaultThinkingOptionId: z.string().optional(),
|
|
307
|
+
});
|
|
308
|
+
export const ProviderSnapshotEntrySchema = z.object({
|
|
309
|
+
provider: AgentProviderSchema,
|
|
310
|
+
status: ProviderStatusSchema,
|
|
311
|
+
enabled: z.boolean().optional().default(true),
|
|
312
|
+
error: z.string().optional(),
|
|
313
|
+
models: z.array(AgentModelDefinitionSchema).optional(),
|
|
314
|
+
modes: z.array(AgentModeSchema).optional(),
|
|
315
|
+
fetchedAt: z.string().optional(),
|
|
316
|
+
label: z.string().optional(),
|
|
317
|
+
description: z.string().optional(),
|
|
318
|
+
defaultModeId: z.string().nullable().optional(),
|
|
319
|
+
});
|
|
320
|
+
const AgentCapabilityFlagsSchema = z
|
|
321
|
+
.object({
|
|
322
|
+
supportsStreaming: z.boolean(),
|
|
323
|
+
supportsSessionPersistence: z.boolean(),
|
|
324
|
+
supportsSessionListing: z.boolean().optional(),
|
|
325
|
+
supportsDynamicModes: z.boolean(),
|
|
326
|
+
supportsMcpServers: z.boolean(),
|
|
327
|
+
supportsReasoningStream: z.boolean(),
|
|
328
|
+
supportsToolInvocations: z.boolean(),
|
|
329
|
+
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
330
|
+
supportsRewindConversation: z.boolean().optional().default(false),
|
|
331
|
+
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
332
|
+
supportsRewindFiles: z.boolean().optional().default(false),
|
|
333
|
+
// COMPAT(rewind): added in v0.1.X, drop when floor >= v0.1.X.
|
|
334
|
+
supportsRewindBoth: z.boolean().optional().default(false),
|
|
335
|
+
})
|
|
336
|
+
.catchall(z.boolean());
|
|
337
|
+
const AgentUsageSchema = z.object({
|
|
338
|
+
inputTokens: z.number().optional(),
|
|
339
|
+
cachedInputTokens: z.number().optional(),
|
|
340
|
+
outputTokens: z.number().optional(),
|
|
341
|
+
totalCostUsd: z.number().optional(),
|
|
342
|
+
contextWindowMaxTokens: z.number().optional(),
|
|
343
|
+
contextWindowUsedTokens: z.number().optional(),
|
|
344
|
+
});
|
|
345
|
+
const AgentSessionConfigSchema = z.object({
|
|
346
|
+
provider: AgentProviderSchema,
|
|
347
|
+
cwd: z.string(),
|
|
348
|
+
modeId: z.string().optional(),
|
|
349
|
+
model: z.string().optional(),
|
|
350
|
+
thinkingOptionId: z.string().optional(),
|
|
351
|
+
featureValues: z.record(z.string(), z.unknown()).optional(),
|
|
352
|
+
title: z.string().trim().min(1).max(MAX_EXPLICIT_AGENT_TITLE_CHARS).optional().nullable(),
|
|
353
|
+
approvalPolicy: z.string().optional(),
|
|
354
|
+
sandboxMode: z.string().optional(),
|
|
355
|
+
networkAccess: z.boolean().optional(),
|
|
356
|
+
webSearch: z.boolean().optional(),
|
|
357
|
+
extra: z
|
|
358
|
+
.object({
|
|
359
|
+
codex: z.record(z.string(), z.unknown()).optional(),
|
|
360
|
+
claude: z.record(z.string(), z.unknown()).optional(),
|
|
361
|
+
})
|
|
362
|
+
.partial()
|
|
363
|
+
.optional(),
|
|
364
|
+
systemPrompt: z.string().optional(),
|
|
365
|
+
mcpServers: z.record(z.string(), McpServerConfigSchema).optional(),
|
|
366
|
+
});
|
|
367
|
+
const AgentPermissionUpdateSchema = z.record(z.string(), z.unknown());
|
|
368
|
+
const AgentPermissionActionSchema = z.object({
|
|
369
|
+
id: z.string(),
|
|
370
|
+
label: z.string(),
|
|
371
|
+
behavior: z.enum(["allow", "deny"]),
|
|
372
|
+
variant: z.enum(["primary", "secondary", "danger"]).optional(),
|
|
373
|
+
intent: z.enum(["implement", "implement_resume", "dismiss"]).optional(),
|
|
374
|
+
});
|
|
375
|
+
export const AgentPermissionResponseSchema = z.discriminatedUnion("behavior", [
|
|
376
|
+
z.object({
|
|
377
|
+
behavior: z.literal("allow"),
|
|
378
|
+
selectedActionId: z.string().optional(),
|
|
379
|
+
updatedInput: z.record(z.string(), z.unknown()).optional(),
|
|
380
|
+
updatedPermissions: z.array(AgentPermissionUpdateSchema).optional(),
|
|
381
|
+
}),
|
|
382
|
+
z.object({
|
|
383
|
+
behavior: z.literal("deny"),
|
|
384
|
+
selectedActionId: z.string().optional(),
|
|
385
|
+
message: z.string().optional(),
|
|
386
|
+
interrupt: z.boolean().optional(),
|
|
387
|
+
}),
|
|
388
|
+
]);
|
|
389
|
+
export const AgentPermissionRequestPayloadSchema = z.object({
|
|
390
|
+
id: z.string(),
|
|
391
|
+
provider: AgentProviderSchema,
|
|
392
|
+
name: z.string(),
|
|
393
|
+
kind: z.enum(["tool", "plan", "question", "mode", "other"]),
|
|
394
|
+
title: z.string().optional(),
|
|
395
|
+
description: z.string().optional(),
|
|
396
|
+
input: z.record(z.string(), z.unknown()).optional(),
|
|
397
|
+
detail: z.lazy(() => ToolCallDetailPayloadSchema).optional(),
|
|
398
|
+
suggestions: z.array(AgentPermissionUpdateSchema).optional(),
|
|
399
|
+
actions: z.array(AgentPermissionActionSchema).optional(),
|
|
400
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
401
|
+
});
|
|
402
|
+
const UnknownValueSchema = z.union([
|
|
403
|
+
z.null(),
|
|
404
|
+
z.boolean(),
|
|
405
|
+
z.number(),
|
|
406
|
+
z.string(),
|
|
407
|
+
z.array(z.unknown()),
|
|
408
|
+
z.object({}).passthrough(),
|
|
409
|
+
]);
|
|
410
|
+
const NonNullUnknownSchema = z.union([
|
|
411
|
+
z.boolean(),
|
|
412
|
+
z.number(),
|
|
413
|
+
z.string(),
|
|
414
|
+
z.array(z.unknown()),
|
|
415
|
+
z.object({}).passthrough(),
|
|
416
|
+
]);
|
|
417
|
+
const WorktreeSetupCommandSnapshotSchema = z.object({
|
|
418
|
+
index: z.number().int().positive(),
|
|
419
|
+
command: z.string(),
|
|
420
|
+
cwd: z.string(),
|
|
421
|
+
log: z.string().optional().default(""),
|
|
422
|
+
status: z.enum(["running", "completed", "failed"]),
|
|
423
|
+
exitCode: z.number().nullable(),
|
|
424
|
+
durationMs: z.number().nonnegative().optional(),
|
|
425
|
+
});
|
|
426
|
+
const WorktreeSetupDetailPayloadSchema = z.object({
|
|
427
|
+
type: z.literal("worktree_setup"),
|
|
428
|
+
worktreePath: z.string(),
|
|
429
|
+
branchName: z.string(),
|
|
430
|
+
log: z.string(),
|
|
431
|
+
commands: z.array(WorktreeSetupCommandSnapshotSchema),
|
|
432
|
+
truncated: z.boolean().optional(),
|
|
433
|
+
});
|
|
434
|
+
const ToolCallDetailPayloadSchema = z.discriminatedUnion("type", [
|
|
435
|
+
WorktreeSetupDetailPayloadSchema,
|
|
436
|
+
z.object({
|
|
437
|
+
type: z.literal("shell"),
|
|
438
|
+
command: z.string(),
|
|
439
|
+
cwd: z.string().optional(),
|
|
440
|
+
output: z.string().optional(),
|
|
441
|
+
exitCode: z.number().nullable().optional(),
|
|
442
|
+
}),
|
|
443
|
+
z.object({
|
|
444
|
+
type: z.literal("read"),
|
|
445
|
+
filePath: z.string(),
|
|
446
|
+
content: z.string().optional(),
|
|
447
|
+
offset: z.number().optional(),
|
|
448
|
+
limit: z.number().optional(),
|
|
449
|
+
}),
|
|
450
|
+
z.object({
|
|
451
|
+
type: z.literal("edit"),
|
|
452
|
+
filePath: z.string(),
|
|
453
|
+
oldString: z.string().optional(),
|
|
454
|
+
newString: z.string().optional(),
|
|
455
|
+
unifiedDiff: z.string().optional(),
|
|
456
|
+
}),
|
|
457
|
+
z.object({
|
|
458
|
+
type: z.literal("write"),
|
|
459
|
+
filePath: z.string(),
|
|
460
|
+
content: z.string().optional(),
|
|
461
|
+
}),
|
|
462
|
+
z.object({
|
|
463
|
+
type: z.literal("search"),
|
|
464
|
+
query: z.string(),
|
|
465
|
+
toolName: z.enum(["search", "grep", "glob", "web_search"]).optional(),
|
|
466
|
+
content: z.string().optional(),
|
|
467
|
+
filePaths: z.array(z.string()).optional(),
|
|
468
|
+
webResults: z
|
|
469
|
+
.array(z.object({
|
|
470
|
+
title: z.string(),
|
|
471
|
+
url: z.string(),
|
|
472
|
+
}))
|
|
473
|
+
.optional(),
|
|
474
|
+
annotations: z.array(z.string()).optional(),
|
|
475
|
+
numFiles: z.number().optional(),
|
|
476
|
+
numMatches: z.number().optional(),
|
|
477
|
+
durationMs: z.number().optional(),
|
|
478
|
+
durationSeconds: z.number().optional(),
|
|
479
|
+
truncated: z.boolean().optional(),
|
|
480
|
+
mode: z.enum(["content", "files_with_matches", "count"]).optional(),
|
|
481
|
+
}),
|
|
482
|
+
z.object({
|
|
483
|
+
type: z.literal("fetch"),
|
|
484
|
+
url: z.string(),
|
|
485
|
+
prompt: z.string().optional(),
|
|
486
|
+
result: z.string().optional(),
|
|
487
|
+
code: z.number().optional(),
|
|
488
|
+
codeText: z.string().optional(),
|
|
489
|
+
bytes: z.number().optional(),
|
|
490
|
+
durationMs: z.number().optional(),
|
|
491
|
+
}),
|
|
492
|
+
z.object({
|
|
493
|
+
type: z.literal("sub_agent"),
|
|
494
|
+
subAgentType: z.string().optional(),
|
|
495
|
+
description: z.string().optional(),
|
|
496
|
+
childSessionId: z.string().optional(),
|
|
497
|
+
log: z.string(),
|
|
498
|
+
// Compat cruft for clients <= 0.1.65-beta.3 that required this field. Producers still
|
|
499
|
+
// emit `[]`; nothing reads it. Drop the field (and the `[]` emissions) once those
|
|
500
|
+
// clients are no longer in the field.
|
|
501
|
+
actions: z
|
|
502
|
+
.array(z.object({
|
|
503
|
+
index: z.number().int().positive(),
|
|
504
|
+
toolName: z.string(),
|
|
505
|
+
summary: z.string().optional(),
|
|
506
|
+
}))
|
|
507
|
+
.optional(),
|
|
508
|
+
}),
|
|
509
|
+
z.object({
|
|
510
|
+
type: z.literal("plain_text"),
|
|
511
|
+
label: z.string().optional(),
|
|
512
|
+
text: z.string().optional(),
|
|
513
|
+
icon: z.enum(TOOL_CALL_ICON_NAMES).optional(),
|
|
514
|
+
}),
|
|
515
|
+
z.object({
|
|
516
|
+
type: z.literal("plan"),
|
|
517
|
+
text: z.string(),
|
|
518
|
+
}),
|
|
519
|
+
z.object({
|
|
520
|
+
type: z.literal("unknown"),
|
|
521
|
+
input: UnknownValueSchema,
|
|
522
|
+
output: UnknownValueSchema,
|
|
523
|
+
}),
|
|
524
|
+
]);
|
|
525
|
+
const ToolCallBasePayloadSchema = z.object({
|
|
526
|
+
type: z.literal("tool_call"),
|
|
527
|
+
callId: z.string(),
|
|
528
|
+
name: z.string(),
|
|
529
|
+
detail: ToolCallDetailPayloadSchema,
|
|
530
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
531
|
+
});
|
|
532
|
+
const ToolCallRunningPayloadSchema = ToolCallBasePayloadSchema.extend({
|
|
533
|
+
status: z.literal("running"),
|
|
534
|
+
error: z.null(),
|
|
535
|
+
});
|
|
536
|
+
const ToolCallCompletedPayloadSchema = ToolCallBasePayloadSchema.extend({
|
|
537
|
+
status: z.literal("completed"),
|
|
538
|
+
error: z.null(),
|
|
539
|
+
});
|
|
540
|
+
const ToolCallFailedPayloadSchema = ToolCallBasePayloadSchema.extend({
|
|
541
|
+
status: z.literal("failed"),
|
|
542
|
+
error: NonNullUnknownSchema,
|
|
543
|
+
});
|
|
544
|
+
const ToolCallCanceledPayloadSchema = ToolCallBasePayloadSchema.extend({
|
|
545
|
+
status: z.literal("canceled"),
|
|
546
|
+
error: z.null(),
|
|
547
|
+
});
|
|
548
|
+
const ToolCallTimelineItemPayloadSchema = z.discriminatedUnion("status", [
|
|
549
|
+
ToolCallRunningPayloadSchema,
|
|
550
|
+
ToolCallCompletedPayloadSchema,
|
|
551
|
+
ToolCallFailedPayloadSchema,
|
|
552
|
+
ToolCallCanceledPayloadSchema,
|
|
553
|
+
]);
|
|
554
|
+
// zod-aot 0.20.4 miscompiles this as a nested discriminated union by omitting
|
|
555
|
+
// the inner tool_call branch from the generated outer dispatch.
|
|
556
|
+
export const AgentTimelineItemPayloadSchema = z.union([
|
|
557
|
+
z.object({
|
|
558
|
+
type: z.literal("user_message"),
|
|
559
|
+
text: z.string(),
|
|
560
|
+
messageId: z.string().optional(),
|
|
561
|
+
}),
|
|
562
|
+
z.object({
|
|
563
|
+
type: z.literal("assistant_message"),
|
|
564
|
+
text: z.string(),
|
|
565
|
+
messageId: z.string().optional(),
|
|
566
|
+
}),
|
|
567
|
+
z.object({
|
|
568
|
+
type: z.literal("reasoning"),
|
|
569
|
+
text: z.string(),
|
|
570
|
+
}),
|
|
571
|
+
ToolCallTimelineItemPayloadSchema,
|
|
572
|
+
z.object({
|
|
573
|
+
type: z.literal("todo"),
|
|
574
|
+
items: z.array(z.object({
|
|
575
|
+
text: z.string(),
|
|
576
|
+
completed: z.boolean(),
|
|
577
|
+
})),
|
|
578
|
+
}),
|
|
579
|
+
z.object({
|
|
580
|
+
type: z.literal("error"),
|
|
581
|
+
message: z.string(),
|
|
582
|
+
}),
|
|
583
|
+
z.object({
|
|
584
|
+
type: z.literal("compaction"),
|
|
585
|
+
// COMPAT(compactionFailedStatus): "failed" added in v0.4.3. Clients older
|
|
586
|
+
// than that drop the whole timeline event on parse and keep showing the
|
|
587
|
+
// loading row — exactly their pre-"failed" behavior, so no gate is needed.
|
|
588
|
+
status: z.enum(["loading", "completed", "failed"]),
|
|
589
|
+
trigger: z.enum(["auto", "manual"]).optional(),
|
|
590
|
+
preTokens: z.number().optional(),
|
|
591
|
+
postTokens: z.number().optional(),
|
|
592
|
+
}),
|
|
593
|
+
]);
|
|
594
|
+
export const AgentStreamEventPayloadSchema = z.discriminatedUnion("type", [
|
|
595
|
+
z.object({
|
|
596
|
+
type: z.literal("thread_started"),
|
|
597
|
+
sessionId: z.string(),
|
|
598
|
+
provider: AgentProviderSchema,
|
|
599
|
+
}),
|
|
600
|
+
z.object({
|
|
601
|
+
type: z.literal("turn_started"),
|
|
602
|
+
provider: AgentProviderSchema,
|
|
603
|
+
}),
|
|
604
|
+
z.object({
|
|
605
|
+
type: z.literal("turn_completed"),
|
|
606
|
+
provider: AgentProviderSchema,
|
|
607
|
+
usage: AgentUsageSchema.optional(),
|
|
608
|
+
}),
|
|
609
|
+
z.object({
|
|
610
|
+
type: z.literal("turn_failed"),
|
|
611
|
+
provider: AgentProviderSchema,
|
|
612
|
+
error: z.string(),
|
|
613
|
+
code: z.string().optional(),
|
|
614
|
+
diagnostic: z.string().optional(),
|
|
615
|
+
}),
|
|
616
|
+
z.object({
|
|
617
|
+
type: z.literal("turn_canceled"),
|
|
618
|
+
provider: AgentProviderSchema,
|
|
619
|
+
reason: z.string(),
|
|
620
|
+
}),
|
|
621
|
+
z.object({
|
|
622
|
+
type: z.literal("timeline"),
|
|
623
|
+
provider: AgentProviderSchema,
|
|
624
|
+
item: AgentTimelineItemPayloadSchema,
|
|
625
|
+
}),
|
|
626
|
+
z.object({
|
|
627
|
+
type: z.literal("permission_requested"),
|
|
628
|
+
provider: AgentProviderSchema,
|
|
629
|
+
request: AgentPermissionRequestPayloadSchema,
|
|
630
|
+
}),
|
|
631
|
+
z.object({
|
|
632
|
+
type: z.literal("permission_resolved"),
|
|
633
|
+
provider: AgentProviderSchema,
|
|
634
|
+
requestId: z.string(),
|
|
635
|
+
resolution: AgentPermissionResponseSchema,
|
|
636
|
+
}),
|
|
637
|
+
z.object({
|
|
638
|
+
type: z.literal("attention_required"),
|
|
639
|
+
provider: AgentProviderSchema,
|
|
640
|
+
reason: z.enum(["finished", "error", "permission"]),
|
|
641
|
+
timestamp: z.string(),
|
|
642
|
+
shouldNotify: z.boolean(),
|
|
643
|
+
notification: z
|
|
644
|
+
.object({
|
|
645
|
+
title: z.string(),
|
|
646
|
+
body: z.string(),
|
|
647
|
+
data: z.object({
|
|
648
|
+
serverId: z.string(),
|
|
649
|
+
agentId: z.string(),
|
|
650
|
+
reason: z.enum(["finished", "error", "permission"]),
|
|
651
|
+
}),
|
|
652
|
+
})
|
|
653
|
+
.optional(),
|
|
654
|
+
}),
|
|
655
|
+
]);
|
|
656
|
+
const AgentPersistenceHandleSchema = z
|
|
657
|
+
.object({
|
|
658
|
+
provider: AgentProviderSchema,
|
|
659
|
+
sessionId: z.string(),
|
|
660
|
+
nativeHandle: z.string().optional(),
|
|
661
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
662
|
+
})
|
|
663
|
+
.nullable();
|
|
664
|
+
const AgentRuntimeInfoSchema = z.object({
|
|
665
|
+
provider: AgentProviderSchema,
|
|
666
|
+
sessionId: z.string().nullable(),
|
|
667
|
+
model: z.string().nullable().optional(),
|
|
668
|
+
thinkingOptionId: z.string().nullable().optional(),
|
|
669
|
+
modeId: z.string().nullable().optional(),
|
|
670
|
+
extra: z.record(z.string(), z.unknown()).optional(),
|
|
671
|
+
});
|
|
672
|
+
export const AgentSnapshotPayloadSchema = z.object({
|
|
673
|
+
id: z.string(),
|
|
674
|
+
provider: AgentProviderSchema,
|
|
675
|
+
cwd: z.string(),
|
|
676
|
+
workspaceId: z.string().optional(),
|
|
677
|
+
model: z.string().nullable(),
|
|
678
|
+
features: z.array(AgentFeatureSchema).optional(),
|
|
679
|
+
thinkingOptionId: z.string().nullable().optional(),
|
|
680
|
+
effectiveThinkingOptionId: z.string().nullable().optional(),
|
|
681
|
+
createdAt: z.string(),
|
|
682
|
+
updatedAt: z.string(),
|
|
683
|
+
lastUserMessageAt: z.string().nullable(),
|
|
684
|
+
status: AgentStatusSchema,
|
|
685
|
+
capabilities: AgentCapabilityFlagsSchema,
|
|
686
|
+
currentModeId: z.string().nullable(),
|
|
687
|
+
availableModes: z.array(AgentModeSchema),
|
|
688
|
+
pendingPermissions: z.array(AgentPermissionRequestPayloadSchema),
|
|
689
|
+
persistence: AgentPersistenceHandleSchema.nullable(),
|
|
690
|
+
runtimeInfo: AgentRuntimeInfoSchema.optional(),
|
|
691
|
+
lastUsage: AgentUsageSchema.optional(),
|
|
692
|
+
lastError: z.string().optional(),
|
|
693
|
+
title: z.string().nullable(),
|
|
694
|
+
labels: z.record(z.string(), z.string()).default({}),
|
|
695
|
+
requiresAttention: z.boolean().optional(),
|
|
696
|
+
attentionReason: z.enum(["finished", "error", "permission"]).nullable().optional(),
|
|
697
|
+
attentionTimestamp: z.string().nullable().optional(),
|
|
698
|
+
archivedAt: z.string().nullable().optional(),
|
|
699
|
+
providerUnavailable: z.boolean().optional(),
|
|
700
|
+
// Attendability. "observed" marks a provider-managed subagent (Claude Task /
|
|
701
|
+
// ultracode fan-out) that the user can watch but not prompt or reconfigure —
|
|
702
|
+
// the daemon refuses attended operations and the client renders it read-only.
|
|
703
|
+
// COMPAT(observedSubagents): added in v0.4.3; absent ⇒ "attended". Drop the
|
|
704
|
+
// gate when daemon floor >= v0.4.3. See projects/observed-subagents/observed-subagents.md.
|
|
705
|
+
attend: z.enum(["attended", "observed"]).optional(),
|
|
706
|
+
// Spinner colors from the Agent Personality this agent was spawned from, so
|
|
707
|
+
// its live thinking indicator renders in the personality's identity. Absent ⇒
|
|
708
|
+
// the client falls back to the theme's default spinner colors. Purely additive
|
|
709
|
+
// (no daemon floor needed). See projects/agent-personalities/.
|
|
710
|
+
personalitySpinner: AgentPersonalitySpinnerSchema.optional(),
|
|
711
|
+
// Name of the Agent Personality this agent was spawned from, so the running
|
|
712
|
+
// agent's controls keep showing the personality identity (trigger label +
|
|
713
|
+
// effort hidden) instead of reverting to the raw model. Absent ⇒ no bound
|
|
714
|
+
// personality. Purely additive. See projects/agent-personalities/.
|
|
715
|
+
personalityName: z.string().optional(),
|
|
716
|
+
// Stable id of the bound Agent Personality. The client keys roster selection
|
|
717
|
+
// on this (names can be renamed/duplicated); personalityName remains for
|
|
718
|
+
// display and as the selection fallback against daemons that predate this
|
|
719
|
+
// field. Purely additive. See projects/agent-personalities/.
|
|
720
|
+
personalityId: z.string().optional(),
|
|
721
|
+
});
|
|
722
|
+
export const AgentListItemPayloadSchema = z.object({
|
|
723
|
+
id: z.string(),
|
|
724
|
+
shortId: z.string(),
|
|
725
|
+
title: z.string().nullable(),
|
|
726
|
+
provider: AgentProviderSchema,
|
|
727
|
+
model: z.string().nullable(),
|
|
728
|
+
thinkingOptionId: z.string().nullable().optional(),
|
|
729
|
+
effectiveThinkingOptionId: z.string().nullable().optional(),
|
|
730
|
+
status: AgentStatusSchema,
|
|
731
|
+
cwd: z.string(),
|
|
732
|
+
createdAt: z.string(),
|
|
733
|
+
updatedAt: z.string(),
|
|
734
|
+
lastUserMessageAt: z.string().nullable(),
|
|
735
|
+
archivedAt: z.string().nullable().optional(),
|
|
736
|
+
requiresAttention: z.boolean().optional(),
|
|
737
|
+
attentionReason: z.enum(["finished", "error", "permission"]).nullable().optional(),
|
|
738
|
+
attentionTimestamp: z.string().nullable().optional(),
|
|
739
|
+
labels: z.record(z.string(), z.string()).default({}),
|
|
740
|
+
providerUnavailable: z.boolean().optional(),
|
|
741
|
+
});
|
|
742
|
+
export const RecentProviderSessionDescriptorPayloadSchema = z.object({
|
|
743
|
+
providerId: z.string(),
|
|
744
|
+
providerLabel: z.string(),
|
|
745
|
+
providerHandleId: z.string(),
|
|
746
|
+
cwd: z.string(),
|
|
747
|
+
title: z.string().nullable(),
|
|
748
|
+
firstPromptPreview: z.string().nullable(),
|
|
749
|
+
lastPromptPreview: z.string().nullable(),
|
|
750
|
+
lastActivityAt: z.string(),
|
|
751
|
+
});
|
|
752
|
+
// ============================================================================
|
|
753
|
+
// Session Inbound Messages (Session receives these)
|
|
754
|
+
// ============================================================================
|
|
755
|
+
export const VoiceAudioChunkMessageSchema = z.object({
|
|
756
|
+
type: z.literal("voice_audio_chunk"),
|
|
757
|
+
audio: z.string(), // base64 encoded
|
|
758
|
+
format: z.string(),
|
|
759
|
+
isLast: z.boolean(),
|
|
760
|
+
});
|
|
761
|
+
export const AbortRequestMessageSchema = z.object({
|
|
762
|
+
type: z.literal("abort_request"),
|
|
763
|
+
});
|
|
764
|
+
export const AudioPlayedMessageSchema = z.object({
|
|
765
|
+
type: z.literal("audio_played"),
|
|
766
|
+
id: z.string(),
|
|
767
|
+
});
|
|
768
|
+
const AgentDirectoryFilterSchema = z.object({
|
|
769
|
+
labels: z.record(z.string(), z.string()).optional(),
|
|
770
|
+
projectKeys: z.array(z.string()).optional(),
|
|
771
|
+
statuses: z.array(AgentStatusSchema).optional(),
|
|
772
|
+
includeArchived: z.boolean().optional(),
|
|
773
|
+
requiresAttention: z.boolean().optional(),
|
|
774
|
+
thinkingOptionId: z.string().nullable().optional(),
|
|
775
|
+
});
|
|
776
|
+
export const DeleteAgentRequestMessageSchema = z.object({
|
|
777
|
+
type: z.literal("delete_agent_request"),
|
|
778
|
+
agentId: z.string(),
|
|
779
|
+
requestId: z.string(),
|
|
780
|
+
});
|
|
781
|
+
export const ArchiveAgentRequestMessageSchema = z.object({
|
|
782
|
+
type: z.literal("archive_agent_request"),
|
|
783
|
+
agentId: z.string(),
|
|
784
|
+
requestId: z.string(),
|
|
785
|
+
});
|
|
786
|
+
export const CloseItemsRequestMessageSchema = z.object({
|
|
787
|
+
type: z.literal("close_items_request"),
|
|
788
|
+
agentIds: z.array(z.string()).default([]),
|
|
789
|
+
terminalIds: z.array(z.string()).default([]),
|
|
790
|
+
requestId: z.string(),
|
|
791
|
+
});
|
|
792
|
+
export const UpdateAgentRequestMessageSchema = z.object({
|
|
793
|
+
type: z.literal("update_agent_request"),
|
|
794
|
+
agentId: z.string(),
|
|
795
|
+
name: z.string().optional(),
|
|
796
|
+
labels: z.record(z.string(), z.string()).optional(),
|
|
797
|
+
requestId: z.string(),
|
|
798
|
+
});
|
|
799
|
+
export const ProjectRenameRequestSchema = z.object({
|
|
800
|
+
type: z.literal("project.rename.request"),
|
|
801
|
+
projectId: z.string(),
|
|
802
|
+
// Null or empty string clears the override and reverts to the derived name.
|
|
803
|
+
customName: z.string().nullable(),
|
|
804
|
+
requestId: z.string(),
|
|
805
|
+
});
|
|
806
|
+
export const ProjectRemoveRequestSchema = z.object({
|
|
807
|
+
type: z.literal("project.remove.request"),
|
|
808
|
+
projectId: z.string(),
|
|
809
|
+
requestId: z.string(),
|
|
810
|
+
});
|
|
811
|
+
export const WorkspaceTitleSetRequestSchema = z.object({
|
|
812
|
+
type: z.literal("workspace.title.set.request"),
|
|
813
|
+
workspaceId: z.string(),
|
|
814
|
+
// Null or empty string clears the title and reverts to the derived name.
|
|
815
|
+
title: z.string().nullable(),
|
|
816
|
+
requestId: z.string(),
|
|
817
|
+
});
|
|
818
|
+
export const SetVoiceModeMessageSchema = z.object({
|
|
819
|
+
type: z.literal("set_voice_mode"),
|
|
820
|
+
enabled: z.boolean(),
|
|
821
|
+
agentId: z.string().optional(),
|
|
822
|
+
requestId: z.string().optional(),
|
|
823
|
+
});
|
|
824
|
+
export const GitHubPrAttachmentSchema = z.object({
|
|
825
|
+
type: z.literal("github_pr"),
|
|
826
|
+
mimeType: z.literal("application/github-pr"),
|
|
827
|
+
number: z.number().int().positive(),
|
|
828
|
+
title: z.string(),
|
|
829
|
+
url: z.string(),
|
|
830
|
+
body: z.string().nullable().optional(),
|
|
831
|
+
baseRefName: z.string().nullable().optional(),
|
|
832
|
+
headRefName: z.string().nullable().optional(),
|
|
833
|
+
});
|
|
834
|
+
export const GitHubIssueAttachmentSchema = z.object({
|
|
835
|
+
type: z.literal("github_issue"),
|
|
836
|
+
mimeType: z.literal("application/github-issue"),
|
|
837
|
+
number: z.number().int().positive(),
|
|
838
|
+
title: z.string(),
|
|
839
|
+
url: z.string(),
|
|
840
|
+
body: z.string().nullable().optional(),
|
|
841
|
+
});
|
|
842
|
+
// Provider-neutral successors to github_pr/github_issue. New clients send
|
|
843
|
+
// these when server_info features.gitHostingProviders is set; the github_*
|
|
844
|
+
// kinds remain accepted forever (protocol contract) and are still what a new
|
|
845
|
+
// client sends to an old daemon for GitHub projects.
|
|
846
|
+
export const HostingPrAttachmentSchema = z.object({
|
|
847
|
+
type: z.literal("hosting_pr"),
|
|
848
|
+
mimeType: z.literal("application/otto-hosting-pr"),
|
|
849
|
+
provider: GitHostingProviderIdWireSchema,
|
|
850
|
+
number: z.number().int().positive(),
|
|
851
|
+
title: z.string(),
|
|
852
|
+
url: z.string(),
|
|
853
|
+
body: z.string().nullable().optional(),
|
|
854
|
+
baseRefName: z.string().nullable().optional(),
|
|
855
|
+
headRefName: z.string().nullable().optional(),
|
|
856
|
+
});
|
|
857
|
+
export const HostingIssueAttachmentSchema = z.object({
|
|
858
|
+
type: z.literal("hosting_issue"),
|
|
859
|
+
mimeType: z.literal("application/otto-hosting-issue"),
|
|
860
|
+
provider: GitHostingProviderIdWireSchema,
|
|
861
|
+
number: z.number().int().positive(),
|
|
862
|
+
title: z.string(),
|
|
863
|
+
url: z.string(),
|
|
864
|
+
body: z.string().nullable().optional(),
|
|
865
|
+
});
|
|
866
|
+
export const TextAttachmentSchema = z
|
|
867
|
+
.object({
|
|
868
|
+
type: z.literal("text"),
|
|
869
|
+
mimeType: z.literal("text/plain"),
|
|
870
|
+
contextKind: z.string().optional(),
|
|
871
|
+
title: z.string().nullable().optional(),
|
|
872
|
+
text: z.string(),
|
|
873
|
+
})
|
|
874
|
+
.transform(({ contextKind, ...attachment }) => ({
|
|
875
|
+
...attachment,
|
|
876
|
+
...(contextKind === "chat_history" ? { contextKind } : {}),
|
|
877
|
+
}));
|
|
878
|
+
export const ReviewAttachmentContextLineSchema = z.object({
|
|
879
|
+
oldLineNumber: z.number().int().positive().nullable(),
|
|
880
|
+
newLineNumber: z.number().int().positive().nullable(),
|
|
881
|
+
type: z.enum(["add", "remove", "context"]),
|
|
882
|
+
content: z.string(),
|
|
883
|
+
});
|
|
884
|
+
export const ReviewAttachmentCommentSchema = z.object({
|
|
885
|
+
filePath: z.string(),
|
|
886
|
+
side: z.enum(["old", "new"]),
|
|
887
|
+
lineNumber: z.number().int().positive(),
|
|
888
|
+
body: z.string(),
|
|
889
|
+
context: z.object({
|
|
890
|
+
hunkHeader: z.string(),
|
|
891
|
+
targetLine: ReviewAttachmentContextLineSchema,
|
|
892
|
+
lines: z.array(ReviewAttachmentContextLineSchema),
|
|
893
|
+
}),
|
|
894
|
+
});
|
|
895
|
+
export const ReviewAttachmentSchema = z.object({
|
|
896
|
+
type: z.literal("review"),
|
|
897
|
+
mimeType: z.literal("application/otto-review"),
|
|
898
|
+
cwd: z.string(),
|
|
899
|
+
mode: z.enum(["uncommitted", "base"]),
|
|
900
|
+
baseRef: z.string().nullable().optional(),
|
|
901
|
+
comments: z.array(ReviewAttachmentCommentSchema),
|
|
902
|
+
});
|
|
903
|
+
export const UploadedFileAttachmentSchema = z.object({
|
|
904
|
+
type: z.literal("uploaded_file"),
|
|
905
|
+
id: z.string(),
|
|
906
|
+
fileName: z.string(),
|
|
907
|
+
mimeType: z.string(),
|
|
908
|
+
size: z.number().int().nonnegative(),
|
|
909
|
+
path: z.string(),
|
|
910
|
+
});
|
|
911
|
+
export const AgentAttachmentSchema = z.discriminatedUnion("type", [
|
|
912
|
+
GitHubPrAttachmentSchema,
|
|
913
|
+
GitHubIssueAttachmentSchema,
|
|
914
|
+
HostingPrAttachmentSchema,
|
|
915
|
+
HostingIssueAttachmentSchema,
|
|
916
|
+
TextAttachmentSchema,
|
|
917
|
+
ReviewAttachmentSchema,
|
|
918
|
+
UploadedFileAttachmentSchema,
|
|
919
|
+
]);
|
|
920
|
+
function normalizeAgentAttachments(input) {
|
|
921
|
+
if (!Array.isArray(input)) {
|
|
922
|
+
return [];
|
|
923
|
+
}
|
|
924
|
+
const normalized = [];
|
|
925
|
+
for (const item of input) {
|
|
926
|
+
const parsed = AgentAttachmentSchema.safeParse(item);
|
|
927
|
+
if (parsed.success) {
|
|
928
|
+
normalized.push(parsed.data);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
return normalized;
|
|
932
|
+
}
|
|
933
|
+
const AgentAttachmentsSchema = z.unknown().transform(normalizeAgentAttachments).optional();
|
|
934
|
+
const ImageAttachmentSchema = z.object({
|
|
935
|
+
data: z.string(), // base64 encoded image
|
|
936
|
+
mimeType: z.string(), // e.g., "image/jpeg", "image/png"
|
|
937
|
+
});
|
|
938
|
+
export const SendAgentMessageSchema = z.object({
|
|
939
|
+
type: z.literal("send_agent_message"),
|
|
940
|
+
agentId: z.string(),
|
|
941
|
+
text: z.string(),
|
|
942
|
+
messageId: z.string().optional(), // Client-provided ID for deduplication
|
|
943
|
+
images: z.array(ImageAttachmentSchema).optional(),
|
|
944
|
+
attachments: AgentAttachmentsSchema,
|
|
945
|
+
});
|
|
946
|
+
// ============================================================================
|
|
947
|
+
// Agent RPCs (requestId-correlated)
|
|
948
|
+
// ============================================================================
|
|
949
|
+
export const FetchAgentsRequestMessageSchema = z.object({
|
|
950
|
+
type: z.literal("fetch_agents_request"),
|
|
951
|
+
requestId: z.string(),
|
|
952
|
+
scope: z.enum(["active"]).optional(),
|
|
953
|
+
filter: AgentDirectoryFilterSchema.optional(),
|
|
954
|
+
sort: z
|
|
955
|
+
.array(z.object({
|
|
956
|
+
key: z.enum(["status_priority", "created_at", "updated_at", "title"]),
|
|
957
|
+
direction: z.enum(["asc", "desc"]),
|
|
958
|
+
}))
|
|
959
|
+
.optional(),
|
|
960
|
+
page: z
|
|
961
|
+
.object({
|
|
962
|
+
limit: z.number().int().positive().max(200),
|
|
963
|
+
cursor: z.string().min(1).optional(),
|
|
964
|
+
})
|
|
965
|
+
.optional(),
|
|
966
|
+
subscribe: z
|
|
967
|
+
.object({
|
|
968
|
+
subscriptionId: z.string().optional(),
|
|
969
|
+
})
|
|
970
|
+
.optional(),
|
|
971
|
+
});
|
|
972
|
+
const WorkspaceStateBucketSchema = z.enum([
|
|
973
|
+
"needs_input",
|
|
974
|
+
"failed",
|
|
975
|
+
"running",
|
|
976
|
+
"attention",
|
|
977
|
+
"done",
|
|
978
|
+
]);
|
|
979
|
+
export const FetchWorkspacesRequestMessageSchema = z.object({
|
|
980
|
+
type: z.literal("fetch_workspaces_request"),
|
|
981
|
+
requestId: z.string(),
|
|
982
|
+
filter: z
|
|
983
|
+
.object({
|
|
984
|
+
query: z.string().optional(),
|
|
985
|
+
projectId: z.string().optional(),
|
|
986
|
+
// Unused: accepted so older clients still parse, but the server does not filter on it.
|
|
987
|
+
idPrefix: z.string().optional(),
|
|
988
|
+
})
|
|
989
|
+
.optional(),
|
|
990
|
+
sort: z
|
|
991
|
+
.array(z.object({
|
|
992
|
+
key: z.enum(["status_priority", "activity_at", "name", "project_id"]),
|
|
993
|
+
direction: z.enum(["asc", "desc"]),
|
|
994
|
+
}))
|
|
995
|
+
.optional(),
|
|
996
|
+
page: z
|
|
997
|
+
.object({
|
|
998
|
+
limit: z.number().int().positive().max(200),
|
|
999
|
+
cursor: z.string().min(1).optional(),
|
|
1000
|
+
})
|
|
1001
|
+
.optional(),
|
|
1002
|
+
subscribe: z
|
|
1003
|
+
.object({
|
|
1004
|
+
subscriptionId: z.string().optional(),
|
|
1005
|
+
})
|
|
1006
|
+
.optional(),
|
|
1007
|
+
});
|
|
1008
|
+
export const FetchAgentHistoryRequestMessageSchema = z.object({
|
|
1009
|
+
type: z.literal("fetch_agent_history_request"),
|
|
1010
|
+
requestId: z.string(),
|
|
1011
|
+
filter: AgentDirectoryFilterSchema.optional(),
|
|
1012
|
+
sort: z
|
|
1013
|
+
.array(z.object({
|
|
1014
|
+
key: z.enum(["status_priority", "created_at", "updated_at", "title"]),
|
|
1015
|
+
direction: z.enum(["asc", "desc"]),
|
|
1016
|
+
}))
|
|
1017
|
+
.optional(),
|
|
1018
|
+
page: z
|
|
1019
|
+
.object({
|
|
1020
|
+
limit: z.number().int().positive().max(200),
|
|
1021
|
+
cursor: z.string().min(1).optional(),
|
|
1022
|
+
})
|
|
1023
|
+
.optional(),
|
|
1024
|
+
});
|
|
1025
|
+
export const FetchRecentProviderSessionsRequestMessageSchema = z.object({
|
|
1026
|
+
type: z.literal("fetch_recent_provider_sessions_request"),
|
|
1027
|
+
requestId: z.string(),
|
|
1028
|
+
cwd: z.string().optional(),
|
|
1029
|
+
providers: z.array(z.string()).optional(),
|
|
1030
|
+
since: z.string().optional(),
|
|
1031
|
+
limit: z.number().int().positive().max(200).optional(),
|
|
1032
|
+
});
|
|
1033
|
+
export const FetchAgentRequestMessageSchema = z.object({
|
|
1034
|
+
type: z.literal("fetch_agent_request"),
|
|
1035
|
+
requestId: z.string(),
|
|
1036
|
+
/** Accepts full ID, unique prefix, or exact full title (server resolves). */
|
|
1037
|
+
agentId: z.string(),
|
|
1038
|
+
});
|
|
1039
|
+
export const SendAgentMessageRequestSchema = z.object({
|
|
1040
|
+
type: z.literal("send_agent_message_request"),
|
|
1041
|
+
requestId: z.string(),
|
|
1042
|
+
/** Accepts full ID, unique prefix, or exact full title (server resolves). */
|
|
1043
|
+
agentId: z.string(),
|
|
1044
|
+
text: z.string(),
|
|
1045
|
+
messageId: z.string().optional(), // Client-provided ID for deduplication
|
|
1046
|
+
images: z.array(ImageAttachmentSchema).optional(),
|
|
1047
|
+
attachments: AgentAttachmentsSchema,
|
|
1048
|
+
});
|
|
1049
|
+
export const WaitForFinishRequestSchema = z.object({
|
|
1050
|
+
type: z.literal("wait_for_finish_request"),
|
|
1051
|
+
requestId: z.string(),
|
|
1052
|
+
/** Accepts full ID, unique prefix, or exact full title (server resolves). */
|
|
1053
|
+
agentId: z.string(),
|
|
1054
|
+
timeoutMs: z.number().int().positive().optional(),
|
|
1055
|
+
});
|
|
1056
|
+
export const DaemonGetStatusRequestSchema = z.object({
|
|
1057
|
+
type: z.literal("daemon.get_status.request"),
|
|
1058
|
+
requestId: z.string(),
|
|
1059
|
+
});
|
|
1060
|
+
export const DaemonGetPairingOfferRequestSchema = z.object({
|
|
1061
|
+
type: z.literal("daemon.get_pairing_offer.request"),
|
|
1062
|
+
requestId: z.string(),
|
|
1063
|
+
});
|
|
1064
|
+
export const DiagnosticsRequestSchema = z.object({
|
|
1065
|
+
type: z.literal("diagnostics.request"),
|
|
1066
|
+
requestId: z.string(),
|
|
1067
|
+
});
|
|
1068
|
+
export const GetDaemonConfigRequestMessageSchema = z.object({
|
|
1069
|
+
type: z.literal("get_daemon_config_request"),
|
|
1070
|
+
requestId: z.string(),
|
|
1071
|
+
});
|
|
1072
|
+
export const SetDaemonConfigRequestMessageSchema = z.object({
|
|
1073
|
+
type: z.literal("set_daemon_config_request"),
|
|
1074
|
+
requestId: z.string(),
|
|
1075
|
+
config: MutableDaemonConfigPatchSchema,
|
|
1076
|
+
});
|
|
1077
|
+
export const SpeechSettingsGetOptionsRequestSchema = z.object({
|
|
1078
|
+
type: z.literal("speech.settings.get_options.request"),
|
|
1079
|
+
requestId: z.string(),
|
|
1080
|
+
});
|
|
1081
|
+
// One-shot "read this text aloud with this voice" for the voice-preview button.
|
|
1082
|
+
// The voice binding is soft, matching personality-voice semantics: an
|
|
1083
|
+
// unavailable voice degrades to the host default at synthesis time, and an
|
|
1084
|
+
// absent voice uses the host default. Synthesis runs on the host's active TTS
|
|
1085
|
+
// provider (there is no per-request provider switch); model/provider are hints.
|
|
1086
|
+
export const SpeechTtsPreviewRequestSchema = z.object({
|
|
1087
|
+
type: z.literal("speech.tts.preview.request"),
|
|
1088
|
+
requestId: z.string(),
|
|
1089
|
+
text: z.string(),
|
|
1090
|
+
voice: z
|
|
1091
|
+
.object({
|
|
1092
|
+
provider: z.string().optional(),
|
|
1093
|
+
model: z.string().optional(),
|
|
1094
|
+
name: z.string(),
|
|
1095
|
+
})
|
|
1096
|
+
.passthrough()
|
|
1097
|
+
.optional(),
|
|
1098
|
+
});
|
|
1099
|
+
export const AgentPersonalitiesGetStatsRequestSchema = z.object({
|
|
1100
|
+
type: z.literal("agentPersonalities.get_stats.request"),
|
|
1101
|
+
requestId: z.string(),
|
|
1102
|
+
});
|
|
1103
|
+
export const ReadProjectConfigRequestMessageSchema = z.object({
|
|
1104
|
+
type: z.literal("read_project_config_request"),
|
|
1105
|
+
requestId: z.string(),
|
|
1106
|
+
repoRoot: z.string(),
|
|
1107
|
+
});
|
|
1108
|
+
export const WriteProjectConfigRequestMessageSchema = z.object({
|
|
1109
|
+
type: z.literal("write_project_config_request"),
|
|
1110
|
+
requestId: z.string(),
|
|
1111
|
+
repoRoot: z.string(),
|
|
1112
|
+
config: OttoConfigRawSchema,
|
|
1113
|
+
expectedRevision: OttoConfigRevisionSchema.nullable(),
|
|
1114
|
+
});
|
|
1115
|
+
// ============================================================================
|
|
1116
|
+
// Dictation Streaming (lossless, resumable)
|
|
1117
|
+
// ============================================================================
|
|
1118
|
+
export const DictationStreamStartMessageSchema = z.object({
|
|
1119
|
+
type: z.literal("dictation_stream_start"),
|
|
1120
|
+
dictationId: z.string(),
|
|
1121
|
+
format: z.string(), // e.g. "audio/pcm;rate=16000;bits=16"
|
|
1122
|
+
});
|
|
1123
|
+
export const DictationStreamChunkMessageSchema = z.object({
|
|
1124
|
+
type: z.literal("dictation_stream_chunk"),
|
|
1125
|
+
dictationId: z.string(),
|
|
1126
|
+
seq: z.number().int().nonnegative(),
|
|
1127
|
+
audio: z.string(), // base64 encoded chunk
|
|
1128
|
+
format: z.string(), // e.g. "audio/pcm;rate=16000;bits=16"
|
|
1129
|
+
});
|
|
1130
|
+
export const DictationStreamFinishMessageSchema = z.object({
|
|
1131
|
+
type: z.literal("dictation_stream_finish"),
|
|
1132
|
+
dictationId: z.string(),
|
|
1133
|
+
finalSeq: z.number().int().nonnegative(),
|
|
1134
|
+
});
|
|
1135
|
+
export const DictationStreamCancelMessageSchema = z.object({
|
|
1136
|
+
type: z.literal("dictation_stream_cancel"),
|
|
1137
|
+
dictationId: z.string(),
|
|
1138
|
+
});
|
|
1139
|
+
const GitSetupOptionsSchema = z.object({
|
|
1140
|
+
baseBranch: z.string().optional(),
|
|
1141
|
+
createNewBranch: z.boolean().optional(),
|
|
1142
|
+
newBranchName: z.string().optional(),
|
|
1143
|
+
createWorktree: z.boolean().optional(),
|
|
1144
|
+
worktreeSlug: z.string().optional(),
|
|
1145
|
+
refName: z.string().min(1).optional(),
|
|
1146
|
+
action: z.enum(["branch-off", "checkout"]).optional(),
|
|
1147
|
+
githubPrNumber: z.number().int().positive().optional(),
|
|
1148
|
+
});
|
|
1149
|
+
export const CreateAgentWorktreeTargetSchema = z.discriminatedUnion("mode", [
|
|
1150
|
+
z.object({
|
|
1151
|
+
mode: z.literal("branch-off"),
|
|
1152
|
+
newBranch: z.string().min(1),
|
|
1153
|
+
base: z.string().min(1).optional(),
|
|
1154
|
+
}),
|
|
1155
|
+
z.object({
|
|
1156
|
+
mode: z.literal("checkout-branch"),
|
|
1157
|
+
branch: z.string().min(1),
|
|
1158
|
+
}),
|
|
1159
|
+
z.object({
|
|
1160
|
+
mode: z.literal("checkout-pr"),
|
|
1161
|
+
prNumber: z.number().int().positive(),
|
|
1162
|
+
}),
|
|
1163
|
+
]);
|
|
1164
|
+
export const CreateAgentRequestMessageSchema = z.object({
|
|
1165
|
+
type: z.literal("create_agent_request"),
|
|
1166
|
+
config: AgentSessionConfigSchema,
|
|
1167
|
+
// Optional personality id. When present the daemon resolves the personality
|
|
1168
|
+
// against this cwd's provider snapshot and snapshots its identity (spinner,
|
|
1169
|
+
// voice, prompt) onto the agent — the brain (provider/model/mode/effort) still
|
|
1170
|
+
// comes from `config`, so hand-deviations in the picker keep the identity.
|
|
1171
|
+
// COMPAT(agentPersonalities): added in v0.5.0; gate lives in features.agentPersonalities.
|
|
1172
|
+
personality: z.string().optional(),
|
|
1173
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
1174
|
+
workspaceId: z.string().optional(),
|
|
1175
|
+
worktreeName: z.string().optional(),
|
|
1176
|
+
initialPrompt: z.string().optional(),
|
|
1177
|
+
clientMessageId: z.string().optional(),
|
|
1178
|
+
outputSchema: z.record(z.string(), z.unknown()).optional(),
|
|
1179
|
+
images: z.array(ImageAttachmentSchema).optional(),
|
|
1180
|
+
attachments: AgentAttachmentsSchema,
|
|
1181
|
+
git: GitSetupOptionsSchema.optional(),
|
|
1182
|
+
worktree: CreateAgentWorktreeTargetSchema.optional(),
|
|
1183
|
+
autoArchive: z.boolean().optional(),
|
|
1184
|
+
labels: z.record(z.string(), z.string()).default({}),
|
|
1185
|
+
requestId: z.string(),
|
|
1186
|
+
});
|
|
1187
|
+
export const ListProviderModelsRequestMessageSchema = z.object({
|
|
1188
|
+
type: z.literal("list_provider_models_request"),
|
|
1189
|
+
provider: AgentProviderSchema,
|
|
1190
|
+
cwd: z.string().optional(),
|
|
1191
|
+
requestId: z.string(),
|
|
1192
|
+
});
|
|
1193
|
+
export const ListProviderModesRequestMessageSchema = z.object({
|
|
1194
|
+
type: z.literal("list_provider_modes_request"),
|
|
1195
|
+
provider: AgentProviderSchema,
|
|
1196
|
+
cwd: z.string().optional(),
|
|
1197
|
+
requestId: z.string(),
|
|
1198
|
+
});
|
|
1199
|
+
export const ListAvailableProvidersRequestMessageSchema = z.object({
|
|
1200
|
+
type: z.literal("list_available_providers_request"),
|
|
1201
|
+
requestId: z.string(),
|
|
1202
|
+
});
|
|
1203
|
+
export const GetProvidersSnapshotRequestMessageSchema = z.object({
|
|
1204
|
+
type: z.literal("get_providers_snapshot_request"),
|
|
1205
|
+
cwd: z.string().optional(),
|
|
1206
|
+
requestId: z.string(),
|
|
1207
|
+
});
|
|
1208
|
+
export const RefreshProvidersSnapshotRequestMessageSchema = z.object({
|
|
1209
|
+
type: z.literal("refresh_providers_snapshot_request"),
|
|
1210
|
+
cwd: z.string().optional(),
|
|
1211
|
+
providers: z.array(AgentProviderSchema).optional(),
|
|
1212
|
+
requestId: z.string(),
|
|
1213
|
+
});
|
|
1214
|
+
export const ProviderDiagnosticRequestMessageSchema = z.object({
|
|
1215
|
+
type: z.literal("provider_diagnostic_request"),
|
|
1216
|
+
provider: AgentProviderSchema,
|
|
1217
|
+
requestId: z.string(),
|
|
1218
|
+
});
|
|
1219
|
+
export const ProviderUsageListRequestMessageSchema = z.object({
|
|
1220
|
+
type: z.literal("provider.usage.list.request"),
|
|
1221
|
+
requestId: z.string(),
|
|
1222
|
+
});
|
|
1223
|
+
export const AgentContextGetUsageRequestMessageSchema = z.object({
|
|
1224
|
+
type: z.literal("agent.context.get_usage.request"),
|
|
1225
|
+
agentId: z.string(),
|
|
1226
|
+
requestId: z.string(),
|
|
1227
|
+
});
|
|
1228
|
+
export const ResumeAgentRequestMessageSchema = z.object({
|
|
1229
|
+
type: z.literal("resume_agent_request"),
|
|
1230
|
+
handle: AgentPersistenceHandleSchema,
|
|
1231
|
+
overrides: AgentSessionConfigSchema.partial().optional(),
|
|
1232
|
+
requestId: z.string(),
|
|
1233
|
+
});
|
|
1234
|
+
export const ImportAgentRequestMessageSchema = z.object({
|
|
1235
|
+
type: z.literal("import_agent_request"),
|
|
1236
|
+
provider: AgentProviderSchema.optional(),
|
|
1237
|
+
providerId: z.string().optional(),
|
|
1238
|
+
sessionId: z.string().optional(),
|
|
1239
|
+
providerHandleId: z.string().optional(),
|
|
1240
|
+
cwd: z.string().optional(),
|
|
1241
|
+
labels: z.record(z.string(), z.string()).optional(),
|
|
1242
|
+
requestId: z.string(),
|
|
1243
|
+
});
|
|
1244
|
+
export const RefreshAgentRequestMessageSchema = z.object({
|
|
1245
|
+
type: z.literal("refresh_agent_request"),
|
|
1246
|
+
agentId: z.string(),
|
|
1247
|
+
requestId: z.string(),
|
|
1248
|
+
});
|
|
1249
|
+
export const CancelAgentRequestMessageSchema = z.object({
|
|
1250
|
+
type: z.literal("cancel_agent_request"),
|
|
1251
|
+
agentId: z.string(),
|
|
1252
|
+
requestId: z.string().optional(),
|
|
1253
|
+
});
|
|
1254
|
+
export const RestartServerRequestMessageSchema = z.object({
|
|
1255
|
+
type: z.literal("restart_server_request"),
|
|
1256
|
+
reason: z.string().optional(),
|
|
1257
|
+
requestId: z.string(),
|
|
1258
|
+
});
|
|
1259
|
+
export const ShutdownServerRequestMessageSchema = z.object({
|
|
1260
|
+
type: z.literal("shutdown_server_request"),
|
|
1261
|
+
requestId: z.string(),
|
|
1262
|
+
});
|
|
1263
|
+
export const DaemonUpdateRequestMessageSchema = z.object({
|
|
1264
|
+
type: z.literal("daemon.update.request"),
|
|
1265
|
+
requestId: z.string(),
|
|
1266
|
+
});
|
|
1267
|
+
export const AgentTimelineCursorSchema = z.object({
|
|
1268
|
+
epoch: z.string(),
|
|
1269
|
+
seq: z.number().int().nonnegative(),
|
|
1270
|
+
});
|
|
1271
|
+
export const FetchAgentTimelineRequestMessageSchema = z.object({
|
|
1272
|
+
type: z.literal("fetch_agent_timeline_request"),
|
|
1273
|
+
agentId: z.string(),
|
|
1274
|
+
requestId: z.string(),
|
|
1275
|
+
direction: z.enum(["tail", "before", "after"]).optional(),
|
|
1276
|
+
cursor: AgentTimelineCursorSchema.optional(),
|
|
1277
|
+
// 0 means "all matching rows for this query window".
|
|
1278
|
+
limit: z.number().int().nonnegative().optional(),
|
|
1279
|
+
// Default should be projected for app timeline loading.
|
|
1280
|
+
projection: z.enum(["projected", "canonical"]).optional(),
|
|
1281
|
+
});
|
|
1282
|
+
export const AgentForkContextRequestMessageSchema = z.object({
|
|
1283
|
+
type: z.literal("agent.fork_context.request"),
|
|
1284
|
+
agentId: z.string(),
|
|
1285
|
+
boundaryMessageId: z.string().optional(),
|
|
1286
|
+
requestId: z.string(),
|
|
1287
|
+
});
|
|
1288
|
+
export const SetAgentModeRequestMessageSchema = z.object({
|
|
1289
|
+
type: z.literal("set_agent_mode_request"),
|
|
1290
|
+
agentId: z.string(),
|
|
1291
|
+
modeId: z.string(),
|
|
1292
|
+
requestId: z.string(),
|
|
1293
|
+
});
|
|
1294
|
+
const AgentActionResponsePayloadSchema = z.object({
|
|
1295
|
+
requestId: z.string(),
|
|
1296
|
+
agentId: z.string(),
|
|
1297
|
+
accepted: z.boolean(),
|
|
1298
|
+
error: z.string().nullable(),
|
|
1299
|
+
notice: AgentProviderNoticeSchema.nullable().optional(),
|
|
1300
|
+
});
|
|
1301
|
+
export const SetAgentModeResponseMessageSchema = z.object({
|
|
1302
|
+
type: z.literal("set_agent_mode_response"),
|
|
1303
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1304
|
+
});
|
|
1305
|
+
export const SetAgentModelRequestMessageSchema = z.object({
|
|
1306
|
+
type: z.literal("set_agent_model_request"),
|
|
1307
|
+
agentId: z.string(),
|
|
1308
|
+
modelId: z.string().nullable(),
|
|
1309
|
+
requestId: z.string(),
|
|
1310
|
+
});
|
|
1311
|
+
export const SetAgentModelResponseMessageSchema = z.object({
|
|
1312
|
+
type: z.literal("set_agent_model_response"),
|
|
1313
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1314
|
+
});
|
|
1315
|
+
export const SetAgentThinkingRequestMessageSchema = z.object({
|
|
1316
|
+
type: z.literal("set_agent_thinking_request"),
|
|
1317
|
+
agentId: z.string(),
|
|
1318
|
+
thinkingOptionId: z.string().nullable(),
|
|
1319
|
+
requestId: z.string(),
|
|
1320
|
+
});
|
|
1321
|
+
export const SetAgentThinkingResponseMessageSchema = z.object({
|
|
1322
|
+
type: z.literal("set_agent_thinking_response"),
|
|
1323
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1324
|
+
});
|
|
1325
|
+
export const SetAgentFeatureRequestMessageSchema = z.object({
|
|
1326
|
+
type: z.literal("set_agent_feature_request"),
|
|
1327
|
+
agentId: z.string(),
|
|
1328
|
+
featureId: z.string(),
|
|
1329
|
+
value: z.unknown(),
|
|
1330
|
+
requestId: z.string(),
|
|
1331
|
+
});
|
|
1332
|
+
export const SetAgentFeatureResponseMessageSchema = z.object({
|
|
1333
|
+
type: z.literal("set_agent_feature_response"),
|
|
1334
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1335
|
+
});
|
|
1336
|
+
export const AgentDetachRequestMessageSchema = z.object({
|
|
1337
|
+
type: z.literal("agent.detach.request"),
|
|
1338
|
+
agentId: z.string(),
|
|
1339
|
+
requestId: z.string(),
|
|
1340
|
+
});
|
|
1341
|
+
export const AgentDetachResponseMessageSchema = z.object({
|
|
1342
|
+
type: z.literal("agent.detach.response"),
|
|
1343
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1344
|
+
});
|
|
1345
|
+
// Stop a running observed subagent (Claude Task / ultracode fan-out). The
|
|
1346
|
+
// agentId is the observed subagent's id; the daemon resolves it to the owning
|
|
1347
|
+
// provider session's task and calls stopTask. Only observed subagents accept
|
|
1348
|
+
// this. COMPAT(observedSubagents): added in v0.4.3. See projects/observed-subagents/observed-subagents.md.
|
|
1349
|
+
export const AgentSubagentStopRequestMessageSchema = z.object({
|
|
1350
|
+
type: z.literal("agent.subagent.stop.request"),
|
|
1351
|
+
agentId: z.string(),
|
|
1352
|
+
requestId: z.string(),
|
|
1353
|
+
});
|
|
1354
|
+
export const AgentSubagentStopResponseMessageSchema = z.object({
|
|
1355
|
+
type: z.literal("agent.subagent.stop.response"),
|
|
1356
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1357
|
+
});
|
|
1358
|
+
// Switch a running agent to an Agent Personality (or clear with null). The
|
|
1359
|
+
// daemon re-resolves the id against the roster + the agent's cwd provider
|
|
1360
|
+
// snapshot and applies the full personality live — system prompt, identity
|
|
1361
|
+
// (name/spinner), and brain (model/mode/effort) — restarting the provider query
|
|
1362
|
+
// so the new prompt takes effect on the next turn. Providers that cannot apply
|
|
1363
|
+
// a prompt mid-session reject. COMPAT(setAgentPersonality): added in v0.5.0;
|
|
1364
|
+
// gate lives in features.setAgentPersonality.
|
|
1365
|
+
export const AgentPersonalitySetRequestMessageSchema = z.object({
|
|
1366
|
+
type: z.literal("agent.personality.set.request"),
|
|
1367
|
+
agentId: z.string(),
|
|
1368
|
+
personalityId: z.string().nullable(),
|
|
1369
|
+
requestId: z.string(),
|
|
1370
|
+
});
|
|
1371
|
+
export const AgentPersonalitySetResponseMessageSchema = z.object({
|
|
1372
|
+
type: z.literal("agent.personality.set.response"),
|
|
1373
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1374
|
+
});
|
|
1375
|
+
export const AgentRewindModeSchema = z.enum(["conversation", "files", "both"]);
|
|
1376
|
+
export const AgentRewindRequestMessageSchema = z.object({
|
|
1377
|
+
type: z.literal("agent.rewind.request"),
|
|
1378
|
+
agentId: z.string(),
|
|
1379
|
+
messageId: z.string(),
|
|
1380
|
+
mode: AgentRewindModeSchema,
|
|
1381
|
+
requestId: z.string(),
|
|
1382
|
+
});
|
|
1383
|
+
export const AgentRewindResponseMessageSchema = z.object({
|
|
1384
|
+
type: z.literal("agent.rewind.response"),
|
|
1385
|
+
payload: z.object({
|
|
1386
|
+
requestId: z.string(),
|
|
1387
|
+
agentId: z.string(),
|
|
1388
|
+
ok: z.boolean(),
|
|
1389
|
+
error: z.string().nullable(),
|
|
1390
|
+
}),
|
|
1391
|
+
});
|
|
1392
|
+
export const UpdateAgentResponseMessageSchema = z.object({
|
|
1393
|
+
type: z.literal("update_agent_response"),
|
|
1394
|
+
payload: AgentActionResponsePayloadSchema,
|
|
1395
|
+
});
|
|
1396
|
+
export const ProjectRenameResponsePayloadSchema = z.object({
|
|
1397
|
+
requestId: z.string(),
|
|
1398
|
+
projectId: z.string(),
|
|
1399
|
+
accepted: z.boolean(),
|
|
1400
|
+
customName: z.string().nullable(),
|
|
1401
|
+
error: z.string().nullable(),
|
|
1402
|
+
});
|
|
1403
|
+
export const ProjectRenameResponseSchema = z.object({
|
|
1404
|
+
type: z.literal("project.rename.response"),
|
|
1405
|
+
payload: ProjectRenameResponsePayloadSchema,
|
|
1406
|
+
});
|
|
1407
|
+
export const ProjectRemoveResponsePayloadSchema = z.object({
|
|
1408
|
+
requestId: z.string(),
|
|
1409
|
+
projectId: z.string(),
|
|
1410
|
+
accepted: z.boolean(),
|
|
1411
|
+
removedWorkspaceIds: z.array(z.string()).default([]),
|
|
1412
|
+
error: z.string().nullable(),
|
|
1413
|
+
});
|
|
1414
|
+
export const ProjectRemoveResponseSchema = z.object({
|
|
1415
|
+
type: z.literal("project.remove.response"),
|
|
1416
|
+
payload: ProjectRemoveResponsePayloadSchema,
|
|
1417
|
+
});
|
|
1418
|
+
export const WorkspaceTitleSetResponsePayloadSchema = z.object({
|
|
1419
|
+
requestId: z.string(),
|
|
1420
|
+
workspaceId: z.string(),
|
|
1421
|
+
accepted: z.boolean(),
|
|
1422
|
+
title: z.string().nullable(),
|
|
1423
|
+
error: z.string().nullable(),
|
|
1424
|
+
});
|
|
1425
|
+
export const WorkspaceTitleSetResponseSchema = z.object({
|
|
1426
|
+
type: z.literal("workspace.title.set.response"),
|
|
1427
|
+
payload: WorkspaceTitleSetResponsePayloadSchema,
|
|
1428
|
+
});
|
|
1429
|
+
export const SetVoiceModeResponseMessageSchema = z.object({
|
|
1430
|
+
type: z.literal("set_voice_mode_response"),
|
|
1431
|
+
payload: z.object({
|
|
1432
|
+
requestId: z.string(),
|
|
1433
|
+
enabled: z.boolean(),
|
|
1434
|
+
agentId: z.string().nullable(),
|
|
1435
|
+
accepted: z.boolean(),
|
|
1436
|
+
error: z.string().nullable(),
|
|
1437
|
+
reasonCode: z.string().optional(),
|
|
1438
|
+
retryable: z.boolean().optional(),
|
|
1439
|
+
missingModelIds: z.array(z.string()).optional(),
|
|
1440
|
+
}),
|
|
1441
|
+
});
|
|
1442
|
+
export const AgentPermissionResponseMessageSchema = z.object({
|
|
1443
|
+
type: z.literal("agent_permission_response"),
|
|
1444
|
+
agentId: z.string(),
|
|
1445
|
+
requestId: z.string(),
|
|
1446
|
+
response: AgentPermissionResponseSchema,
|
|
1447
|
+
});
|
|
1448
|
+
const CheckoutErrorCodeSchema = z.enum([
|
|
1449
|
+
"NOT_GIT_REPO",
|
|
1450
|
+
"NOT_ALLOWED",
|
|
1451
|
+
"MERGE_CONFLICT",
|
|
1452
|
+
"UNKNOWN",
|
|
1453
|
+
]);
|
|
1454
|
+
const CheckoutErrorSchema = z.object({
|
|
1455
|
+
code: CheckoutErrorCodeSchema,
|
|
1456
|
+
message: z.string(),
|
|
1457
|
+
});
|
|
1458
|
+
const CheckoutDiffCompareSchema = z.object({
|
|
1459
|
+
mode: z.enum(["uncommitted", "base"]),
|
|
1460
|
+
baseRef: z.string().optional(),
|
|
1461
|
+
ignoreWhitespace: z.boolean().optional(),
|
|
1462
|
+
});
|
|
1463
|
+
export const CheckoutStatusRequestSchema = z.object({
|
|
1464
|
+
type: z.literal("checkout_status_request"),
|
|
1465
|
+
cwd: z.string(),
|
|
1466
|
+
requestId: z.string(),
|
|
1467
|
+
});
|
|
1468
|
+
export const SubscribeCheckoutDiffRequestSchema = z.object({
|
|
1469
|
+
type: z.literal("subscribe_checkout_diff_request"),
|
|
1470
|
+
subscriptionId: z.string(),
|
|
1471
|
+
cwd: z.string(),
|
|
1472
|
+
compare: CheckoutDiffCompareSchema,
|
|
1473
|
+
requestId: z.string(),
|
|
1474
|
+
});
|
|
1475
|
+
export const UnsubscribeCheckoutDiffRequestSchema = z.object({
|
|
1476
|
+
type: z.literal("unsubscribe_checkout_diff_request"),
|
|
1477
|
+
subscriptionId: z.string(),
|
|
1478
|
+
});
|
|
1479
|
+
export const CheckoutCommitRequestSchema = z.object({
|
|
1480
|
+
type: z.literal("checkout_commit_request"),
|
|
1481
|
+
cwd: z.string(),
|
|
1482
|
+
message: z.string().optional(),
|
|
1483
|
+
addAll: z.boolean().optional(),
|
|
1484
|
+
requestId: z.string(),
|
|
1485
|
+
});
|
|
1486
|
+
export const CheckoutMergeRequestSchema = z.object({
|
|
1487
|
+
type: z.literal("checkout_merge_request"),
|
|
1488
|
+
cwd: z.string(),
|
|
1489
|
+
baseRef: z.string().optional(),
|
|
1490
|
+
strategy: z.enum(["merge", "squash"]).optional(),
|
|
1491
|
+
requireCleanTarget: z.boolean().optional(),
|
|
1492
|
+
requestId: z.string(),
|
|
1493
|
+
});
|
|
1494
|
+
export const CheckoutMergeFromBaseRequestSchema = z.object({
|
|
1495
|
+
type: z.literal("checkout_merge_from_base_request"),
|
|
1496
|
+
cwd: z.string(),
|
|
1497
|
+
baseRef: z.string().optional(),
|
|
1498
|
+
requireCleanTarget: z.boolean().optional(),
|
|
1499
|
+
requestId: z.string(),
|
|
1500
|
+
});
|
|
1501
|
+
export const CheckoutPullRequestSchema = z.object({
|
|
1502
|
+
type: z.literal("checkout_pull_request"),
|
|
1503
|
+
cwd: z.string(),
|
|
1504
|
+
requestId: z.string(),
|
|
1505
|
+
});
|
|
1506
|
+
export const CheckoutPushRequestSchema = z.object({
|
|
1507
|
+
type: z.literal("checkout_push_request"),
|
|
1508
|
+
cwd: z.string(),
|
|
1509
|
+
requestId: z.string(),
|
|
1510
|
+
});
|
|
1511
|
+
export const CheckoutRefreshRequestSchema = z.object({
|
|
1512
|
+
type: z.literal("checkout.refresh.request"),
|
|
1513
|
+
cwd: z.string(),
|
|
1514
|
+
requestId: z.string(),
|
|
1515
|
+
});
|
|
1516
|
+
export const CheckoutPrCreateRequestSchema = z.object({
|
|
1517
|
+
type: z.literal("checkout_pr_create_request"),
|
|
1518
|
+
cwd: z.string(),
|
|
1519
|
+
title: z.string().optional(),
|
|
1520
|
+
body: z.string().optional(),
|
|
1521
|
+
baseRef: z.string().optional(),
|
|
1522
|
+
requestId: z.string(),
|
|
1523
|
+
});
|
|
1524
|
+
export const CheckoutPrMergeRequestSchema = z.object({
|
|
1525
|
+
type: z.literal("checkout_pr_merge_request"),
|
|
1526
|
+
cwd: z.string(),
|
|
1527
|
+
mergeMethod: z.enum(["merge", "squash", "rebase"]),
|
|
1528
|
+
requestId: z.string(),
|
|
1529
|
+
});
|
|
1530
|
+
export const CheckoutGithubSetAutoMergeRequestSchema = z.object({
|
|
1531
|
+
type: z.literal("checkout.github.set_auto_merge.request"),
|
|
1532
|
+
cwd: z.string(),
|
|
1533
|
+
enabled: z.boolean(),
|
|
1534
|
+
mergeMethod: z.enum(["merge", "squash", "rebase"]).optional(),
|
|
1535
|
+
requestId: z.string(),
|
|
1536
|
+
});
|
|
1537
|
+
const GitHubRepoSegmentSchema = z.string().regex(/^[A-Za-z0-9._-]+$/);
|
|
1538
|
+
export const CheckoutGithubGetCheckDetailsRequestSchema = z.object({
|
|
1539
|
+
type: z.literal("checkout.github.get_check_details.request"),
|
|
1540
|
+
cwd: z.string(),
|
|
1541
|
+
repoOwner: GitHubRepoSegmentSchema,
|
|
1542
|
+
repoName: GitHubRepoSegmentSchema,
|
|
1543
|
+
checkRunId: z.number().int().positive(),
|
|
1544
|
+
workflowRunId: z.number().int().positive().optional(),
|
|
1545
|
+
requestId: z.string(),
|
|
1546
|
+
});
|
|
1547
|
+
export const CheckoutPrStatusRequestSchema = z.object({
|
|
1548
|
+
type: z.literal("checkout_pr_status_request"),
|
|
1549
|
+
cwd: z.string(),
|
|
1550
|
+
requestId: z.string(),
|
|
1551
|
+
});
|
|
1552
|
+
/**
|
|
1553
|
+
* UI-initiated preview RPCs (the Preview toolbar button), distinct from the
|
|
1554
|
+
* agent-facing preview_* tools in packages/server/src/server/preview/preview-tools.ts.
|
|
1555
|
+
* Both sides drive the same DevServerManager; only the caller differs.
|
|
1556
|
+
*/
|
|
1557
|
+
export const PreviewListConfigRequestSchema = z.object({
|
|
1558
|
+
type: z.literal("preview.list_config.request"),
|
|
1559
|
+
cwd: z.string(),
|
|
1560
|
+
requestId: z.string(),
|
|
1561
|
+
});
|
|
1562
|
+
export const PreviewStartRequestSchema = z.object({
|
|
1563
|
+
type: z.literal("preview.start.request"),
|
|
1564
|
+
cwd: z.string(),
|
|
1565
|
+
name: z.string(),
|
|
1566
|
+
requestId: z.string(),
|
|
1567
|
+
});
|
|
1568
|
+
export const PreviewBindTabRequestSchema = z.object({
|
|
1569
|
+
type: z.literal("preview.bind_tab.request"),
|
|
1570
|
+
serverId: z.string(),
|
|
1571
|
+
browserId: z.string(),
|
|
1572
|
+
requestId: z.string(),
|
|
1573
|
+
});
|
|
1574
|
+
export const PreviewStopRequestSchema = z.object({
|
|
1575
|
+
type: z.literal("preview.stop.request"),
|
|
1576
|
+
serverId: z.string(),
|
|
1577
|
+
requestId: z.string(),
|
|
1578
|
+
});
|
|
1579
|
+
export const PullRequestTimelineRequestSchema = z.object({
|
|
1580
|
+
type: z.literal("pull_request_timeline_request"),
|
|
1581
|
+
cwd: z.string(),
|
|
1582
|
+
prNumber: z.number(),
|
|
1583
|
+
repoOwner: z.string(),
|
|
1584
|
+
repoName: z.string(),
|
|
1585
|
+
requestId: z.string(),
|
|
1586
|
+
});
|
|
1587
|
+
export const ValidateBranchRequestSchema = z.object({
|
|
1588
|
+
type: z.literal("validate_branch_request"),
|
|
1589
|
+
cwd: z.string(),
|
|
1590
|
+
branchName: z.string(),
|
|
1591
|
+
requestId: z.string(),
|
|
1592
|
+
});
|
|
1593
|
+
export const CheckoutSwitchBranchRequestSchema = z.object({
|
|
1594
|
+
type: z.literal("checkout_switch_branch_request"),
|
|
1595
|
+
cwd: z.string(),
|
|
1596
|
+
branch: z.string(),
|
|
1597
|
+
requestId: z.string(),
|
|
1598
|
+
});
|
|
1599
|
+
export const CheckoutRenameBranchRequestSchema = z.object({
|
|
1600
|
+
type: z.literal("checkout.rename_branch.request"),
|
|
1601
|
+
cwd: z.string(),
|
|
1602
|
+
branch: z.string(),
|
|
1603
|
+
requestId: z.string(),
|
|
1604
|
+
});
|
|
1605
|
+
export const StashSaveRequestSchema = z.object({
|
|
1606
|
+
type: z.literal("stash_save_request"),
|
|
1607
|
+
cwd: z.string(),
|
|
1608
|
+
/** Branch name to tag the stash with for later identification. */
|
|
1609
|
+
branch: z.string().optional(),
|
|
1610
|
+
requestId: z.string(),
|
|
1611
|
+
});
|
|
1612
|
+
export const StashPopRequestSchema = z.object({
|
|
1613
|
+
type: z.literal("stash_pop_request"),
|
|
1614
|
+
cwd: z.string(),
|
|
1615
|
+
/** Zero-based index from stash_list_response. */
|
|
1616
|
+
stashIndex: z.number().int().min(0),
|
|
1617
|
+
requestId: z.string(),
|
|
1618
|
+
});
|
|
1619
|
+
export const StashListRequestSchema = z.object({
|
|
1620
|
+
type: z.literal("stash_list_request"),
|
|
1621
|
+
cwd: z.string(),
|
|
1622
|
+
/** If true, only return otto-created stashes. Default true. */
|
|
1623
|
+
ottoOnly: z.boolean().optional(),
|
|
1624
|
+
requestId: z.string(),
|
|
1625
|
+
});
|
|
1626
|
+
export const BranchSuggestionsRequestSchema = z.object({
|
|
1627
|
+
type: z.literal("branch_suggestions_request"),
|
|
1628
|
+
cwd: z.string(),
|
|
1629
|
+
query: z.string().optional(),
|
|
1630
|
+
limit: z.number().int().min(1).max(200).optional(),
|
|
1631
|
+
requestId: z.string(),
|
|
1632
|
+
});
|
|
1633
|
+
export const GitHubSearchItemSchema = z.object({
|
|
1634
|
+
kind: z.enum(["issue", "pr"]),
|
|
1635
|
+
number: z.number(),
|
|
1636
|
+
title: z.string(),
|
|
1637
|
+
url: z.string(),
|
|
1638
|
+
state: z.string(),
|
|
1639
|
+
body: z.string().nullable(),
|
|
1640
|
+
labels: z.array(z.string()),
|
|
1641
|
+
baseRefName: z.string().nullable().optional(),
|
|
1642
|
+
headRefName: z.string().nullable().optional(),
|
|
1643
|
+
updatedAt: z.string().optional(),
|
|
1644
|
+
});
|
|
1645
|
+
export const GitHubSearchKindSchema = z.enum(["github-issue", "github-pr"]);
|
|
1646
|
+
export const GitHubSearchRequestSchema = z.object({
|
|
1647
|
+
type: z.literal("github_search_request"),
|
|
1648
|
+
cwd: z.string(),
|
|
1649
|
+
query: z.string(),
|
|
1650
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
1651
|
+
kinds: z.array(GitHubSearchKindSchema).optional(),
|
|
1652
|
+
requestId: z.string(),
|
|
1653
|
+
});
|
|
1654
|
+
// Provider-neutral successor to github_search_request. Resolves the project's
|
|
1655
|
+
// configured hosting provider from cwd. Gated by server_info
|
|
1656
|
+
// features.gitHostingProviders.
|
|
1657
|
+
export const HostingSearchKindSchema = z.enum(["issue", "pr"]);
|
|
1658
|
+
export const HostingSearchRequestSchema = z.object({
|
|
1659
|
+
type: z.literal("hosting.search.request"),
|
|
1660
|
+
cwd: z.string(),
|
|
1661
|
+
query: z.string(),
|
|
1662
|
+
limit: z.number().int().min(1).max(50).optional(),
|
|
1663
|
+
kinds: z.array(HostingSearchKindSchema).optional(),
|
|
1664
|
+
requestId: z.string(),
|
|
1665
|
+
});
|
|
1666
|
+
// Reports whether a host-level provider's credentials are valid — drives the
|
|
1667
|
+
// connection-status row in the host Git providers settings section.
|
|
1668
|
+
export const HostingAuthStatusRequestSchema = z.object({
|
|
1669
|
+
type: z.literal("hosting.auth_status.request"),
|
|
1670
|
+
provider: GitHostingProviderIdWireSchema,
|
|
1671
|
+
requestId: z.string(),
|
|
1672
|
+
});
|
|
1673
|
+
export const DirectorySuggestionsRequestSchema = z.object({
|
|
1674
|
+
type: z.literal("directory_suggestions_request"),
|
|
1675
|
+
query: z.string(),
|
|
1676
|
+
cwd: z.string().optional(),
|
|
1677
|
+
includeFiles: z.boolean().optional(),
|
|
1678
|
+
includeDirectories: z.boolean().optional(),
|
|
1679
|
+
matchMode: z.enum(["fuzzy", "suffix"]).optional(),
|
|
1680
|
+
limit: z.number().int().min(1).max(100).optional(),
|
|
1681
|
+
requestId: z.string(),
|
|
1682
|
+
});
|
|
1683
|
+
export const OttoWorktreeListRequestSchema = z.object({
|
|
1684
|
+
type: z.literal("otto_worktree_list_request"),
|
|
1685
|
+
cwd: z.string().optional(),
|
|
1686
|
+
repoRoot: z.string().optional(),
|
|
1687
|
+
requestId: z.string(),
|
|
1688
|
+
});
|
|
1689
|
+
export const OttoWorktreeArchiveRequestSchema = z.object({
|
|
1690
|
+
type: z.literal("otto_worktree_archive_request"),
|
|
1691
|
+
worktreePath: z.string().optional(),
|
|
1692
|
+
repoRoot: z.string().optional(),
|
|
1693
|
+
branchName: z.string().optional(),
|
|
1694
|
+
// COMPAT(worktreeArchiveWorkspaceId): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
1695
|
+
// Explicit workspace record to archive. A directory can back multiple workspaces
|
|
1696
|
+
// (Model B), so resolving the target by cwd alone picks the wrong record. When
|
|
1697
|
+
// present the daemon archives this exact workspace; when absent it falls back to
|
|
1698
|
+
// resolving by worktreePath, preferring the worktree-kind record on a cwd tie.
|
|
1699
|
+
workspaceId: z.string().optional(),
|
|
1700
|
+
// COMPAT(worktreeArchiveScope): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
1701
|
+
// Scope of the archive operation. "workspace" archives a single workspace record
|
|
1702
|
+
// (today's default UI behavior). "worktree" archives every active workspace whose
|
|
1703
|
+
// cwd resolves to the target directory, then removes the directory if it is
|
|
1704
|
+
// Otto-owned. Omitted/unknown values default to "workspace" for old-client safety.
|
|
1705
|
+
scope: z.enum(["workspace", "worktree"]).optional().default("workspace"),
|
|
1706
|
+
// COMPAT(worktreeDiskDeletion): added in v0.1.97, ignored as of v0.1.97
|
|
1707
|
+
// (disk removal derived from scope + last-reference + ownership); field
|
|
1708
|
+
// retained for wire parse-compat, drop when floor >= v0.1.97.
|
|
1709
|
+
deleteWorktreeFromDisk: z.boolean().optional().default(false),
|
|
1710
|
+
requestId: z.string(),
|
|
1711
|
+
});
|
|
1712
|
+
export const FirstAgentContextSchema = z.object({
|
|
1713
|
+
prompt: z.string().optional(),
|
|
1714
|
+
attachments: AgentAttachmentsSchema,
|
|
1715
|
+
});
|
|
1716
|
+
export const CreateOttoWorktreeRequestSchema = z.object({
|
|
1717
|
+
type: z.literal("create_otto_worktree_request"),
|
|
1718
|
+
cwd: z.string(),
|
|
1719
|
+
projectId: z.string().optional(),
|
|
1720
|
+
worktreeSlug: z.string().optional(),
|
|
1721
|
+
nameContext: z.string().optional(),
|
|
1722
|
+
attachments: AgentAttachmentsSchema.optional(),
|
|
1723
|
+
firstAgentContext: FirstAgentContextSchema.optional(),
|
|
1724
|
+
refName: z.string().min(1).optional(),
|
|
1725
|
+
action: z.enum(["branch-off", "checkout"]).optional(),
|
|
1726
|
+
githubPrNumber: z.number().int().positive().optional(),
|
|
1727
|
+
requestId: z.string(),
|
|
1728
|
+
});
|
|
1729
|
+
export const WorkspaceSetupStatusRequestSchema = z.object({
|
|
1730
|
+
type: z.literal("workspace_setup_status_request"),
|
|
1731
|
+
workspaceId: z.string(),
|
|
1732
|
+
requestId: z.string(),
|
|
1733
|
+
});
|
|
1734
|
+
// COMPAT(desktopEditorBridge): added in v0.1.88, remove after 2026-12-03 once old clients no longer call daemon editor RPCs.
|
|
1735
|
+
export const LegacyListAvailableEditorsRequestSchema = z.object({
|
|
1736
|
+
type: z.literal("list_available_editors_request"),
|
|
1737
|
+
requestId: z.string(),
|
|
1738
|
+
});
|
|
1739
|
+
export const LegacyOpenInEditorRequestSchema = z.object({
|
|
1740
|
+
type: z.literal("open_in_editor_request"),
|
|
1741
|
+
path: z.string(),
|
|
1742
|
+
editorId: z.string().trim().min(1),
|
|
1743
|
+
mode: z.enum(["open", "reveal"]).optional(),
|
|
1744
|
+
cwd: z.string().optional(),
|
|
1745
|
+
requestId: z.string(),
|
|
1746
|
+
});
|
|
1747
|
+
export const OpenProjectRequestSchema = z.object({
|
|
1748
|
+
type: z.literal("open_project_request"),
|
|
1749
|
+
// Path used only for workspace lookup/creation. Use the returned workspace.id for all subsequent references.
|
|
1750
|
+
cwd: z.string(),
|
|
1751
|
+
requestId: z.string(),
|
|
1752
|
+
});
|
|
1753
|
+
export const ProjectAddRequestSchema = z.object({
|
|
1754
|
+
type: z.literal("project.add.request"),
|
|
1755
|
+
cwd: z.string(),
|
|
1756
|
+
requestId: z.string(),
|
|
1757
|
+
});
|
|
1758
|
+
export const ArchiveWorkspaceRequestSchema = z.object({
|
|
1759
|
+
type: z.literal("archive_workspace_request"),
|
|
1760
|
+
workspaceId: z.string(),
|
|
1761
|
+
requestId: z.string(),
|
|
1762
|
+
});
|
|
1763
|
+
// Create a new workspace record. Unlike open_project, this never deduplicates by
|
|
1764
|
+
// directory: it always produces a fresh workspace. The source discriminates
|
|
1765
|
+
// between an existing local directory and a newly created otto worktree.
|
|
1766
|
+
export const WorkspaceCreateRequestSchema = z.object({
|
|
1767
|
+
type: z.literal("workspace.create.request"),
|
|
1768
|
+
requestId: z.string(),
|
|
1769
|
+
// Optional user-set title applied to the created workspace.
|
|
1770
|
+
title: z.string().optional(),
|
|
1771
|
+
// Optional prompt context for workspace-level name/branch generation.
|
|
1772
|
+
firstAgentContext: FirstAgentContextSchema.optional(),
|
|
1773
|
+
source: z.discriminatedUnion("kind", [
|
|
1774
|
+
z.object({
|
|
1775
|
+
kind: z.literal("directory"),
|
|
1776
|
+
// Path of the existing checkout/directory to back the workspace.
|
|
1777
|
+
path: z.string(),
|
|
1778
|
+
projectId: z.string().optional(),
|
|
1779
|
+
}),
|
|
1780
|
+
z.object({
|
|
1781
|
+
kind: z.literal("worktree"),
|
|
1782
|
+
// The project whose repo the worktree is cut from.
|
|
1783
|
+
cwd: z.string().optional(),
|
|
1784
|
+
projectId: z.string().optional(),
|
|
1785
|
+
action: z.enum(["branch-off", "checkout"]).optional(),
|
|
1786
|
+
// Target branch name for checkout, or new branch name for branch-off.
|
|
1787
|
+
refName: z.string().min(1).optional(),
|
|
1788
|
+
baseBranch: z.string().optional(),
|
|
1789
|
+
githubPrNumber: z.number().int().positive().optional(),
|
|
1790
|
+
worktreeSlug: z.string().optional(),
|
|
1791
|
+
}),
|
|
1792
|
+
]),
|
|
1793
|
+
});
|
|
1794
|
+
export const WorkspaceClearAttentionRequestSchema = z.object({
|
|
1795
|
+
type: z.literal("workspace.clear_attention.request"),
|
|
1796
|
+
workspaceId: z.union([z.string(), z.array(z.string())]),
|
|
1797
|
+
requestId: z.string(),
|
|
1798
|
+
});
|
|
1799
|
+
// Highlighted diff token schema
|
|
1800
|
+
// Note: style can be a compound class name (e.g., "heading meta") from the syntax highlighter
|
|
1801
|
+
const HighlightTokenSchema = z.object({
|
|
1802
|
+
text: z.string(),
|
|
1803
|
+
style: z.string().nullable(),
|
|
1804
|
+
});
|
|
1805
|
+
const DiffLineSchema = z.object({
|
|
1806
|
+
type: z.enum(["add", "remove", "context", "header"]),
|
|
1807
|
+
content: z.string(),
|
|
1808
|
+
tokens: z.array(HighlightTokenSchema).optional(),
|
|
1809
|
+
});
|
|
1810
|
+
const DiffHunkSchema = z.object({
|
|
1811
|
+
oldStart: z.number(),
|
|
1812
|
+
oldCount: z.number(),
|
|
1813
|
+
newStart: z.number(),
|
|
1814
|
+
newCount: z.number(),
|
|
1815
|
+
lines: z.array(DiffLineSchema),
|
|
1816
|
+
});
|
|
1817
|
+
const ParsedDiffFileSchema = z.object({
|
|
1818
|
+
path: z.string(),
|
|
1819
|
+
isNew: z.boolean(),
|
|
1820
|
+
isDeleted: z.boolean(),
|
|
1821
|
+
additions: z.number(),
|
|
1822
|
+
deletions: z.number(),
|
|
1823
|
+
hunks: z.array(DiffHunkSchema),
|
|
1824
|
+
status: z.enum(["ok", "too_large", "binary"]).optional(),
|
|
1825
|
+
});
|
|
1826
|
+
const FileExplorerEntrySchema = z.object({
|
|
1827
|
+
name: z.string(),
|
|
1828
|
+
path: z.string(),
|
|
1829
|
+
kind: z.enum(["file", "directory"]),
|
|
1830
|
+
size: z.number(),
|
|
1831
|
+
modifiedAt: z.string(),
|
|
1832
|
+
});
|
|
1833
|
+
export const FileEolSchema = z.enum(["lf", "crlf"]);
|
|
1834
|
+
const FileExplorerFileSchema = z.object({
|
|
1835
|
+
path: z.string(),
|
|
1836
|
+
kind: z.enum(["text", "image", "binary"]),
|
|
1837
|
+
encoding: z.enum(["utf-8", "base64", "none"]),
|
|
1838
|
+
content: z.string().optional(),
|
|
1839
|
+
mimeType: z.string().optional(),
|
|
1840
|
+
size: z.number(),
|
|
1841
|
+
modifiedAt: z.string(),
|
|
1842
|
+
// COMPAT(textEditor): added in v0.4.4 for editor buffers (text files on the
|
|
1843
|
+
// inline JSON read path only); old daemons omit both fields.
|
|
1844
|
+
eol: FileEolSchema.optional(),
|
|
1845
|
+
hash: z.string().optional(),
|
|
1846
|
+
});
|
|
1847
|
+
const FileExplorerDirectorySchema = z.object({
|
|
1848
|
+
path: z.string(),
|
|
1849
|
+
entries: z.array(FileExplorerEntrySchema),
|
|
1850
|
+
});
|
|
1851
|
+
export const FileExplorerRequestSchema = z.object({
|
|
1852
|
+
type: z.literal("file_explorer_request"),
|
|
1853
|
+
cwd: z.string(),
|
|
1854
|
+
path: z.string().optional(),
|
|
1855
|
+
mode: z.enum(["list", "file"]),
|
|
1856
|
+
requestId: z.string(),
|
|
1857
|
+
acceptBinary: z.boolean().optional(),
|
|
1858
|
+
});
|
|
1859
|
+
export const ProjectIconRequestSchema = z.object({
|
|
1860
|
+
type: z.literal("project_icon_request"),
|
|
1861
|
+
cwd: z.string(),
|
|
1862
|
+
requestId: z.string(),
|
|
1863
|
+
});
|
|
1864
|
+
export const FileDownloadTokenRequestSchema = z.object({
|
|
1865
|
+
type: z.literal("file_download_token_request"),
|
|
1866
|
+
cwd: z.string(),
|
|
1867
|
+
path: z.string(),
|
|
1868
|
+
requestId: z.string(),
|
|
1869
|
+
});
|
|
1870
|
+
export const FileUploadRequestSchema = z.object({
|
|
1871
|
+
type: z.literal("file.upload.request"),
|
|
1872
|
+
fileName: z.string().min(1),
|
|
1873
|
+
mimeType: z.string().min(1),
|
|
1874
|
+
size: z.number().int().nonnegative(),
|
|
1875
|
+
modifiedAt: z.string(),
|
|
1876
|
+
requestId: z.string(),
|
|
1877
|
+
});
|
|
1878
|
+
/**
|
|
1879
|
+
* Text-editor save. A conditional write: the request carries the client's
|
|
1880
|
+
* last-known file identity and the daemon refuses to clobber content it did
|
|
1881
|
+
* not hand out — a mismatch comes back as a typed conflict, never a write.
|
|
1882
|
+
*/
|
|
1883
|
+
export const FileWriteRequestSchema = z.object({
|
|
1884
|
+
type: z.literal("file.write.request"),
|
|
1885
|
+
cwd: z.string(),
|
|
1886
|
+
path: z.string(),
|
|
1887
|
+
// LF-normalized UTF-8 text; the daemon re-applies the file's detected EOL.
|
|
1888
|
+
content: z.string(),
|
|
1889
|
+
expectedModifiedAt: z.string(),
|
|
1890
|
+
expectedHash: z.string().optional(),
|
|
1891
|
+
// Set only by the deleted-file "save re-creates" flow; a missing target is
|
|
1892
|
+
// otherwise never an invitation to create one. When the file reappeared in
|
|
1893
|
+
// the meantime, the normal precondition check still applies.
|
|
1894
|
+
allowCreate: z.boolean().optional(),
|
|
1895
|
+
// EOL to apply when creating (there is no on-disk EOL to detect).
|
|
1896
|
+
eol: FileEolSchema.optional(),
|
|
1897
|
+
requestId: z.string(),
|
|
1898
|
+
});
|
|
1899
|
+
// Subscriptions exist only for paths open in tabs; the daemon cleans them up
|
|
1900
|
+
// when the session ends.
|
|
1901
|
+
export const FileWatchSubscribeRequestSchema = z.object({
|
|
1902
|
+
type: z.literal("file.watch.subscribe.request"),
|
|
1903
|
+
cwd: z.string(),
|
|
1904
|
+
path: z.string(),
|
|
1905
|
+
requestId: z.string(),
|
|
1906
|
+
});
|
|
1907
|
+
export const FileWatchUnsubscribeRequestSchema = z.object({
|
|
1908
|
+
type: z.literal("file.watch.unsubscribe.request"),
|
|
1909
|
+
cwd: z.string(),
|
|
1910
|
+
path: z.string(),
|
|
1911
|
+
requestId: z.string(),
|
|
1912
|
+
});
|
|
1913
|
+
// ctags-style navigation (no LSP). All three are daemon RPCs so the client
|
|
1914
|
+
// never touches the filesystem; the symbol index is name-based and honest.
|
|
1915
|
+
export const CodeListFilesRequestSchema = z.object({
|
|
1916
|
+
type: z.literal("code.list_files.request"),
|
|
1917
|
+
cwd: z.string(),
|
|
1918
|
+
requestId: z.string(),
|
|
1919
|
+
});
|
|
1920
|
+
export const CodeSymbolsRequestSchema = z.object({
|
|
1921
|
+
type: z.literal("code.symbols.request"),
|
|
1922
|
+
cwd: z.string(),
|
|
1923
|
+
name: z.string(),
|
|
1924
|
+
requestId: z.string(),
|
|
1925
|
+
});
|
|
1926
|
+
export const CodeOutlineRequestSchema = z.object({
|
|
1927
|
+
type: z.literal("code.outline.request"),
|
|
1928
|
+
cwd: z.string(),
|
|
1929
|
+
path: z.string(),
|
|
1930
|
+
requestId: z.string(),
|
|
1931
|
+
});
|
|
1932
|
+
/**
|
|
1933
|
+
* Project-wide search ("Find in Files" semantics: explicit search, not
|
|
1934
|
+
* per-keystroke). Results stream as file.search.result events correlated by
|
|
1935
|
+
* searchId (= this requestId); a new search from the same session supersedes
|
|
1936
|
+
* any in-flight one.
|
|
1937
|
+
*/
|
|
1938
|
+
export const FileSearchRequestSchema = z.object({
|
|
1939
|
+
type: z.literal("file.search.request"),
|
|
1940
|
+
cwd: z.string(),
|
|
1941
|
+
query: z.string(),
|
|
1942
|
+
caseSensitive: z.boolean().optional(),
|
|
1943
|
+
wholeWord: z.boolean().optional(),
|
|
1944
|
+
regexp: z.boolean().optional(),
|
|
1945
|
+
include: z.string().optional(),
|
|
1946
|
+
exclude: z.string().optional(),
|
|
1947
|
+
requestId: z.string(),
|
|
1948
|
+
});
|
|
1949
|
+
const FileReplaceMatchSchema = z.object({
|
|
1950
|
+
/** 1-based line number. */
|
|
1951
|
+
line: z.number().int().positive(),
|
|
1952
|
+
/** 1-based character column of the match start. */
|
|
1953
|
+
column: z.number().int().positive(),
|
|
1954
|
+
/** Match length in characters. */
|
|
1955
|
+
length: z.number().int().nonnegative(),
|
|
1956
|
+
});
|
|
1957
|
+
/**
|
|
1958
|
+
* Preview-first project replace. Each file carries the hash the preview was
|
|
1959
|
+
* built against — files changed since are skipped and reported, never
|
|
1960
|
+
* corrupted. The replacement string is literal (no capture references in v1).
|
|
1961
|
+
*/
|
|
1962
|
+
export const FileReplaceRequestSchema = z.object({
|
|
1963
|
+
type: z.literal("file.replace.request"),
|
|
1964
|
+
cwd: z.string(),
|
|
1965
|
+
replacement: z.string(),
|
|
1966
|
+
files: z.array(z.object({
|
|
1967
|
+
path: z.string(),
|
|
1968
|
+
expectedHash: z.string(),
|
|
1969
|
+
matches: z.array(FileReplaceMatchSchema),
|
|
1970
|
+
})),
|
|
1971
|
+
requestId: z.string(),
|
|
1972
|
+
});
|
|
1973
|
+
export const ClearAgentAttentionMessageSchema = z.object({
|
|
1974
|
+
type: z.literal("clear_agent_attention"),
|
|
1975
|
+
agentId: z.union([z.string(), z.array(z.string())]),
|
|
1976
|
+
requestId: z.string().optional(),
|
|
1977
|
+
});
|
|
1978
|
+
export const ClientHeartbeatMessageSchema = z.object({
|
|
1979
|
+
type: z.literal("client_heartbeat"),
|
|
1980
|
+
deviceType: z.enum(["web", "mobile"]),
|
|
1981
|
+
focusedAgentId: z.string().nullable(),
|
|
1982
|
+
// COMPAT(terminalFocusHeartbeat): added in v0.1.97, remove optional default after 2026-12-13 once old clients no longer send heartbeats without terminal focus.
|
|
1983
|
+
focusedTerminalId: z.string().nullable().optional().default(null),
|
|
1984
|
+
lastActivityAt: z.string(),
|
|
1985
|
+
appVisible: z.boolean(),
|
|
1986
|
+
appVisibilityChangedAt: z.string().optional(),
|
|
1987
|
+
});
|
|
1988
|
+
export const PingMessageSchema = z.object({
|
|
1989
|
+
type: z.literal("ping"),
|
|
1990
|
+
requestId: z.string(),
|
|
1991
|
+
clientSentAt: z.number().int().optional(),
|
|
1992
|
+
});
|
|
1993
|
+
const ListCommandsDraftConfigSchema = z.object({
|
|
1994
|
+
provider: AgentProviderSchema,
|
|
1995
|
+
cwd: z.string(),
|
|
1996
|
+
modeId: z.string().optional(),
|
|
1997
|
+
model: z.string().optional(),
|
|
1998
|
+
thinkingOptionId: z.string().optional(),
|
|
1999
|
+
featureValues: z.record(z.string(), z.unknown()).optional(),
|
|
2000
|
+
});
|
|
2001
|
+
export const ListProviderFeaturesRequestMessageSchema = z.object({
|
|
2002
|
+
type: z.literal("list_provider_features_request"),
|
|
2003
|
+
draftConfig: ListCommandsDraftConfigSchema,
|
|
2004
|
+
requestId: z.string(),
|
|
2005
|
+
});
|
|
2006
|
+
export const ListCommandsRequestSchema = z.object({
|
|
2007
|
+
type: z.literal("list_commands_request"),
|
|
2008
|
+
agentId: z.string(),
|
|
2009
|
+
draftConfig: ListCommandsDraftConfigSchema.optional(),
|
|
2010
|
+
requestId: z.string(),
|
|
2011
|
+
});
|
|
2012
|
+
export const RegisterPushTokenMessageSchema = z.object({
|
|
2013
|
+
type: z.literal("register_push_token"),
|
|
2014
|
+
token: z.string(),
|
|
2015
|
+
});
|
|
2016
|
+
// ============================================================================
|
|
2017
|
+
// Terminal Messages
|
|
2018
|
+
// ============================================================================
|
|
2019
|
+
export const ListTerminalsRequestSchema = z.object({
|
|
2020
|
+
type: z.literal("list_terminals_request"),
|
|
2021
|
+
cwd: z.string().optional(),
|
|
2022
|
+
workspaceId: z.string().optional(),
|
|
2023
|
+
requestId: z.string(),
|
|
2024
|
+
});
|
|
2025
|
+
export const SubscribeTerminalsRequestSchema = z.object({
|
|
2026
|
+
type: z.literal("subscribe_terminals_request"),
|
|
2027
|
+
cwd: z.string(),
|
|
2028
|
+
workspaceId: z.string().optional(),
|
|
2029
|
+
});
|
|
2030
|
+
export const UnsubscribeTerminalsRequestSchema = z.object({
|
|
2031
|
+
type: z.literal("unsubscribe_terminals_request"),
|
|
2032
|
+
cwd: z.string(),
|
|
2033
|
+
workspaceId: z.string().optional(),
|
|
2034
|
+
});
|
|
2035
|
+
export const CreateTerminalRequestSchema = z.object({
|
|
2036
|
+
type: z.literal("create_terminal_request"),
|
|
2037
|
+
cwd: z.string(),
|
|
2038
|
+
workspaceId: z.string().optional(),
|
|
2039
|
+
name: z.string().optional(),
|
|
2040
|
+
agentId: z.string().optional(),
|
|
2041
|
+
command: z.string().optional(),
|
|
2042
|
+
args: z.array(z.string()).optional(),
|
|
2043
|
+
requestId: z.string(),
|
|
2044
|
+
});
|
|
2045
|
+
export const RenameTerminalRequestSchema = z.object({
|
|
2046
|
+
type: z.literal("terminal.rename.request"),
|
|
2047
|
+
terminalId: z.string(),
|
|
2048
|
+
title: z.string(),
|
|
2049
|
+
requestId: z.string(),
|
|
2050
|
+
});
|
|
2051
|
+
export const StartWorkspaceScriptRequestSchema = z.object({
|
|
2052
|
+
type: z.literal("start_workspace_script_request"),
|
|
2053
|
+
workspaceId: z.string(),
|
|
2054
|
+
scriptName: z.string(),
|
|
2055
|
+
requestId: z.string(),
|
|
2056
|
+
});
|
|
2057
|
+
export const SubscribeTerminalRequestSchema = z.object({
|
|
2058
|
+
type: z.literal("subscribe_terminal_request"),
|
|
2059
|
+
terminalId: z.string(),
|
|
2060
|
+
requestId: z.string(),
|
|
2061
|
+
restore: z
|
|
2062
|
+
.object({
|
|
2063
|
+
mode: z.enum(["live", "visible-snapshot", "full-snapshot"]),
|
|
2064
|
+
scrollbackLines: z.number().int().nonnegative().optional(),
|
|
2065
|
+
size: z
|
|
2066
|
+
.object({
|
|
2067
|
+
rows: z.number().int().positive(),
|
|
2068
|
+
cols: z.number().int().positive(),
|
|
2069
|
+
})
|
|
2070
|
+
.optional(),
|
|
2071
|
+
})
|
|
2072
|
+
.optional(),
|
|
2073
|
+
});
|
|
2074
|
+
export const UnsubscribeTerminalRequestSchema = z.object({
|
|
2075
|
+
type: z.literal("unsubscribe_terminal_request"),
|
|
2076
|
+
terminalId: z.string(),
|
|
2077
|
+
});
|
|
2078
|
+
const TerminalClientMessageSchema = z.discriminatedUnion("type", [
|
|
2079
|
+
z.object({ type: z.literal("input"), data: z.string() }),
|
|
2080
|
+
z.object({ type: z.literal("resize"), rows: z.number(), cols: z.number() }),
|
|
2081
|
+
z.object({
|
|
2082
|
+
type: z.literal("mouse"),
|
|
2083
|
+
row: z.number(),
|
|
2084
|
+
col: z.number(),
|
|
2085
|
+
button: z.number(),
|
|
2086
|
+
action: z.enum(["down", "up", "move"]),
|
|
2087
|
+
}),
|
|
2088
|
+
]);
|
|
2089
|
+
export const TerminalInputSchema = z.object({
|
|
2090
|
+
type: z.literal("terminal_input"),
|
|
2091
|
+
terminalId: z.string(),
|
|
2092
|
+
message: TerminalClientMessageSchema,
|
|
2093
|
+
});
|
|
2094
|
+
export const KillTerminalRequestSchema = z.object({
|
|
2095
|
+
type: z.literal("kill_terminal_request"),
|
|
2096
|
+
terminalId: z.string(),
|
|
2097
|
+
requestId: z.string(),
|
|
2098
|
+
});
|
|
2099
|
+
export const CaptureTerminalRequestSchema = z.object({
|
|
2100
|
+
type: z.literal("capture_terminal_request"),
|
|
2101
|
+
terminalId: z.string(),
|
|
2102
|
+
start: z.number().int().optional(),
|
|
2103
|
+
end: z.number().int().optional(),
|
|
2104
|
+
stripAnsi: z.boolean().default(true),
|
|
2105
|
+
requestId: z.string(),
|
|
2106
|
+
});
|
|
2107
|
+
export const SessionInboundMessageSchema = z.discriminatedUnion("type", [
|
|
2108
|
+
BrowserAutomationExecuteResponseSchema,
|
|
2109
|
+
VoiceAudioChunkMessageSchema,
|
|
2110
|
+
AbortRequestMessageSchema,
|
|
2111
|
+
AudioPlayedMessageSchema,
|
|
2112
|
+
FetchAgentsRequestMessageSchema,
|
|
2113
|
+
FetchAgentHistoryRequestMessageSchema,
|
|
2114
|
+
FetchRecentProviderSessionsRequestMessageSchema,
|
|
2115
|
+
FetchWorkspacesRequestMessageSchema,
|
|
2116
|
+
FetchAgentRequestMessageSchema,
|
|
2117
|
+
DeleteAgentRequestMessageSchema,
|
|
2118
|
+
ArchiveAgentRequestMessageSchema,
|
|
2119
|
+
CloseItemsRequestMessageSchema,
|
|
2120
|
+
UpdateAgentRequestMessageSchema,
|
|
2121
|
+
ProjectRenameRequestSchema,
|
|
2122
|
+
ProjectRemoveRequestSchema,
|
|
2123
|
+
WorkspaceTitleSetRequestSchema,
|
|
2124
|
+
SetVoiceModeMessageSchema,
|
|
2125
|
+
SendAgentMessageRequestSchema,
|
|
2126
|
+
WaitForFinishRequestSchema,
|
|
2127
|
+
DaemonGetStatusRequestSchema,
|
|
2128
|
+
DaemonGetPairingOfferRequestSchema,
|
|
2129
|
+
DiagnosticsRequestSchema,
|
|
2130
|
+
GetDaemonConfigRequestMessageSchema,
|
|
2131
|
+
SetDaemonConfigRequestMessageSchema,
|
|
2132
|
+
SpeechSettingsGetOptionsRequestSchema,
|
|
2133
|
+
SpeechTtsPreviewRequestSchema,
|
|
2134
|
+
AgentPersonalitiesGetStatsRequestSchema,
|
|
2135
|
+
ReadProjectConfigRequestMessageSchema,
|
|
2136
|
+
WriteProjectConfigRequestMessageSchema,
|
|
2137
|
+
DictationStreamStartMessageSchema,
|
|
2138
|
+
DictationStreamChunkMessageSchema,
|
|
2139
|
+
DictationStreamFinishMessageSchema,
|
|
2140
|
+
DictationStreamCancelMessageSchema,
|
|
2141
|
+
CreateAgentRequestMessageSchema,
|
|
2142
|
+
ListProviderModelsRequestMessageSchema,
|
|
2143
|
+
ListProviderModesRequestMessageSchema,
|
|
2144
|
+
ListProviderFeaturesRequestMessageSchema,
|
|
2145
|
+
ListAvailableProvidersRequestMessageSchema,
|
|
2146
|
+
GetProvidersSnapshotRequestMessageSchema,
|
|
2147
|
+
RefreshProvidersSnapshotRequestMessageSchema,
|
|
2148
|
+
ProviderDiagnosticRequestMessageSchema,
|
|
2149
|
+
ProviderUsageListRequestMessageSchema,
|
|
2150
|
+
AgentContextGetUsageRequestMessageSchema,
|
|
2151
|
+
ResumeAgentRequestMessageSchema,
|
|
2152
|
+
ImportAgentRequestMessageSchema,
|
|
2153
|
+
RefreshAgentRequestMessageSchema,
|
|
2154
|
+
CancelAgentRequestMessageSchema,
|
|
2155
|
+
ShutdownServerRequestMessageSchema,
|
|
2156
|
+
RestartServerRequestMessageSchema,
|
|
2157
|
+
DaemonUpdateRequestMessageSchema,
|
|
2158
|
+
FetchAgentTimelineRequestMessageSchema,
|
|
2159
|
+
AgentForkContextRequestMessageSchema,
|
|
2160
|
+
SetAgentModeRequestMessageSchema,
|
|
2161
|
+
SetAgentModelRequestMessageSchema,
|
|
2162
|
+
SetAgentThinkingRequestMessageSchema,
|
|
2163
|
+
SetAgentFeatureRequestMessageSchema,
|
|
2164
|
+
AgentDetachRequestMessageSchema,
|
|
2165
|
+
AgentSubagentStopRequestMessageSchema,
|
|
2166
|
+
AgentPersonalitySetRequestMessageSchema,
|
|
2167
|
+
AgentRewindRequestMessageSchema,
|
|
2168
|
+
AgentPermissionResponseMessageSchema,
|
|
2169
|
+
CheckoutStatusRequestSchema,
|
|
2170
|
+
SubscribeCheckoutDiffRequestSchema,
|
|
2171
|
+
UnsubscribeCheckoutDiffRequestSchema,
|
|
2172
|
+
CheckoutCommitRequestSchema,
|
|
2173
|
+
CheckoutMergeRequestSchema,
|
|
2174
|
+
CheckoutMergeFromBaseRequestSchema,
|
|
2175
|
+
CheckoutPullRequestSchema,
|
|
2176
|
+
CheckoutPushRequestSchema,
|
|
2177
|
+
CheckoutRefreshRequestSchema,
|
|
2178
|
+
CheckoutPrCreateRequestSchema,
|
|
2179
|
+
CheckoutPrMergeRequestSchema,
|
|
2180
|
+
CheckoutGithubSetAutoMergeRequestSchema,
|
|
2181
|
+
CheckoutGithubGetCheckDetailsRequestSchema,
|
|
2182
|
+
PreviewListConfigRequestSchema,
|
|
2183
|
+
PreviewStartRequestSchema,
|
|
2184
|
+
PreviewBindTabRequestSchema,
|
|
2185
|
+
PreviewStopRequestSchema,
|
|
2186
|
+
CheckoutPrStatusRequestSchema,
|
|
2187
|
+
PullRequestTimelineRequestSchema,
|
|
2188
|
+
CheckoutSwitchBranchRequestSchema,
|
|
2189
|
+
CheckoutRenameBranchRequestSchema,
|
|
2190
|
+
StashSaveRequestSchema,
|
|
2191
|
+
StashPopRequestSchema,
|
|
2192
|
+
StashListRequestSchema,
|
|
2193
|
+
ValidateBranchRequestSchema,
|
|
2194
|
+
BranchSuggestionsRequestSchema,
|
|
2195
|
+
GitHubSearchRequestSchema,
|
|
2196
|
+
HostingSearchRequestSchema,
|
|
2197
|
+
HostingAuthStatusRequestSchema,
|
|
2198
|
+
DirectorySuggestionsRequestSchema,
|
|
2199
|
+
OttoWorktreeListRequestSchema,
|
|
2200
|
+
OttoWorktreeArchiveRequestSchema,
|
|
2201
|
+
CreateOttoWorktreeRequestSchema,
|
|
2202
|
+
WorkspaceSetupStatusRequestSchema,
|
|
2203
|
+
LegacyListAvailableEditorsRequestSchema,
|
|
2204
|
+
LegacyOpenInEditorRequestSchema,
|
|
2205
|
+
OpenProjectRequestSchema,
|
|
2206
|
+
ProjectAddRequestSchema,
|
|
2207
|
+
ArchiveWorkspaceRequestSchema,
|
|
2208
|
+
WorkspaceCreateRequestSchema,
|
|
2209
|
+
WorkspaceClearAttentionRequestSchema,
|
|
2210
|
+
FileExplorerRequestSchema,
|
|
2211
|
+
ProjectIconRequestSchema,
|
|
2212
|
+
FileDownloadTokenRequestSchema,
|
|
2213
|
+
FileUploadRequestSchema,
|
|
2214
|
+
FileWriteRequestSchema,
|
|
2215
|
+
FileWatchSubscribeRequestSchema,
|
|
2216
|
+
FileWatchUnsubscribeRequestSchema,
|
|
2217
|
+
FileSearchRequestSchema,
|
|
2218
|
+
FileReplaceRequestSchema,
|
|
2219
|
+
CodeListFilesRequestSchema,
|
|
2220
|
+
CodeSymbolsRequestSchema,
|
|
2221
|
+
CodeOutlineRequestSchema,
|
|
2222
|
+
ClearAgentAttentionMessageSchema,
|
|
2223
|
+
ClientHeartbeatMessageSchema,
|
|
2224
|
+
PingMessageSchema,
|
|
2225
|
+
ListCommandsRequestSchema,
|
|
2226
|
+
RegisterPushTokenMessageSchema,
|
|
2227
|
+
ListTerminalsRequestSchema,
|
|
2228
|
+
SubscribeTerminalsRequestSchema,
|
|
2229
|
+
UnsubscribeTerminalsRequestSchema,
|
|
2230
|
+
CreateTerminalRequestSchema,
|
|
2231
|
+
RenameTerminalRequestSchema,
|
|
2232
|
+
StartWorkspaceScriptRequestSchema,
|
|
2233
|
+
SubscribeTerminalRequestSchema,
|
|
2234
|
+
UnsubscribeTerminalRequestSchema,
|
|
2235
|
+
TerminalInputSchema,
|
|
2236
|
+
KillTerminalRequestSchema,
|
|
2237
|
+
CaptureTerminalRequestSchema,
|
|
2238
|
+
ChatCreateRequestSchema,
|
|
2239
|
+
ChatListRequestSchema,
|
|
2240
|
+
ChatInspectRequestSchema,
|
|
2241
|
+
ChatDeleteRequestSchema,
|
|
2242
|
+
ChatPostRequestSchema,
|
|
2243
|
+
ChatReadRequestSchema,
|
|
2244
|
+
ChatWaitRequestSchema,
|
|
2245
|
+
ScheduleCreateRequestSchema,
|
|
2246
|
+
ScheduleListRequestSchema,
|
|
2247
|
+
ScheduleInspectRequestSchema,
|
|
2248
|
+
ScheduleLogsRequestSchema,
|
|
2249
|
+
SchedulePauseRequestSchema,
|
|
2250
|
+
ScheduleResumeRequestSchema,
|
|
2251
|
+
ScheduleDeleteRequestSchema,
|
|
2252
|
+
ScheduleRunOnceRequestSchema,
|
|
2253
|
+
ScheduleUpdateRequestSchema,
|
|
2254
|
+
LoopRunRequestSchema,
|
|
2255
|
+
LoopListRequestSchema,
|
|
2256
|
+
LoopInspectRequestSchema,
|
|
2257
|
+
LoopLogsRequestSchema,
|
|
2258
|
+
LoopStopRequestSchema,
|
|
2259
|
+
// COMPAT(artifacts): added in v0.4.1, drop the gate when daemon floor >= v0.4.1.
|
|
2260
|
+
ArtifactListRequestSchema,
|
|
2261
|
+
ArtifactCreateRequestSchema,
|
|
2262
|
+
ArtifactUpdateRequestSchema,
|
|
2263
|
+
ArtifactRegenerateRequestSchema,
|
|
2264
|
+
ArtifactCancelRequestSchema,
|
|
2265
|
+
ArtifactDeleteRequestSchema,
|
|
2266
|
+
ArtifactStarRequestSchema,
|
|
2267
|
+
ArtifactGetContentRequestSchema,
|
|
2268
|
+
]);
|
|
2269
|
+
// ============================================================================
|
|
2270
|
+
// Session Outbound Messages (Session emits these)
|
|
2271
|
+
// ============================================================================
|
|
2272
|
+
export const ActivityLogPayloadSchema = z.object({
|
|
2273
|
+
id: z.string(),
|
|
2274
|
+
timestamp: z.coerce.date(),
|
|
2275
|
+
type: z.enum(["transcript", "assistant", "tool_call", "tool_result", "error", "system"]),
|
|
2276
|
+
content: z.string(),
|
|
2277
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
2278
|
+
});
|
|
2279
|
+
export const ActivityLogMessageSchema = z.object({
|
|
2280
|
+
type: z.literal("activity_log"),
|
|
2281
|
+
payload: ActivityLogPayloadSchema,
|
|
2282
|
+
});
|
|
2283
|
+
export const AssistantChunkMessageSchema = z.object({
|
|
2284
|
+
type: z.literal("assistant_chunk"),
|
|
2285
|
+
payload: z.object({
|
|
2286
|
+
chunk: z.string(),
|
|
2287
|
+
}),
|
|
2288
|
+
});
|
|
2289
|
+
export const AudioOutputMessageSchema = z.object({
|
|
2290
|
+
type: z.literal("audio_output"),
|
|
2291
|
+
payload: z.object({
|
|
2292
|
+
audio: z.string(), // base64 encoded
|
|
2293
|
+
format: z.string(),
|
|
2294
|
+
id: z.string(),
|
|
2295
|
+
isVoiceMode: z.boolean(), // Mode when audio was generated (for drift protection)
|
|
2296
|
+
groupId: z.string().optional(), // Logical utterance id
|
|
2297
|
+
chunkIndex: z.number().int().nonnegative().optional(),
|
|
2298
|
+
isLastChunk: z.boolean().optional(),
|
|
2299
|
+
}),
|
|
2300
|
+
});
|
|
2301
|
+
export const TranscriptionResultMessageSchema = z.object({
|
|
2302
|
+
type: z.literal("transcription_result"),
|
|
2303
|
+
payload: z.object({
|
|
2304
|
+
text: z.string(),
|
|
2305
|
+
language: z.string().optional(),
|
|
2306
|
+
duration: z.number().optional(),
|
|
2307
|
+
requestId: z.string(), // Echoed back from request for tracking
|
|
2308
|
+
avgLogprob: z.number().optional(),
|
|
2309
|
+
isLowConfidence: z.boolean().optional(),
|
|
2310
|
+
byteLength: z.number().optional(),
|
|
2311
|
+
format: z.string().optional(),
|
|
2312
|
+
debugRecordingPath: z.string().optional(),
|
|
2313
|
+
}),
|
|
2314
|
+
});
|
|
2315
|
+
export const VoiceInputStateMessageSchema = z.object({
|
|
2316
|
+
type: z.literal("voice_input_state"),
|
|
2317
|
+
payload: z.object({
|
|
2318
|
+
isSpeaking: z.boolean(),
|
|
2319
|
+
}),
|
|
2320
|
+
});
|
|
2321
|
+
export const DictationStreamAckMessageSchema = z.object({
|
|
2322
|
+
type: z.literal("dictation_stream_ack"),
|
|
2323
|
+
payload: z.object({
|
|
2324
|
+
dictationId: z.string(),
|
|
2325
|
+
ackSeq: z.number().int(),
|
|
2326
|
+
}),
|
|
2327
|
+
});
|
|
2328
|
+
export const DictationStreamFinishAcceptedMessageSchema = z.object({
|
|
2329
|
+
type: z.literal("dictation_stream_finish_accepted"),
|
|
2330
|
+
payload: z.object({
|
|
2331
|
+
dictationId: z.string(),
|
|
2332
|
+
timeoutMs: z.number().int().positive(),
|
|
2333
|
+
}),
|
|
2334
|
+
});
|
|
2335
|
+
export const DictationStreamPartialMessageSchema = z.object({
|
|
2336
|
+
type: z.literal("dictation_stream_partial"),
|
|
2337
|
+
payload: z.object({
|
|
2338
|
+
dictationId: z.string(),
|
|
2339
|
+
text: z.string(),
|
|
2340
|
+
}),
|
|
2341
|
+
});
|
|
2342
|
+
export const DictationStreamFinalMessageSchema = z.object({
|
|
2343
|
+
type: z.literal("dictation_stream_final"),
|
|
2344
|
+
payload: z.object({
|
|
2345
|
+
dictationId: z.string(),
|
|
2346
|
+
text: z.string(),
|
|
2347
|
+
debugRecordingPath: z.string().optional(),
|
|
2348
|
+
}),
|
|
2349
|
+
});
|
|
2350
|
+
export const DictationStreamErrorMessageSchema = z.object({
|
|
2351
|
+
type: z.literal("dictation_stream_error"),
|
|
2352
|
+
payload: z.object({
|
|
2353
|
+
dictationId: z.string(),
|
|
2354
|
+
error: z.string(),
|
|
2355
|
+
retryable: z.boolean(),
|
|
2356
|
+
reasonCode: z.string().optional(),
|
|
2357
|
+
missingModelIds: z.array(z.string()).optional(),
|
|
2358
|
+
debugRecordingPath: z.string().optional(),
|
|
2359
|
+
}),
|
|
2360
|
+
});
|
|
2361
|
+
export const ServerCapabilityStateSchema = z.object({
|
|
2362
|
+
enabled: z.boolean(),
|
|
2363
|
+
reason: z.string(),
|
|
2364
|
+
});
|
|
2365
|
+
export const ServerVoiceCapabilitiesSchema = z.object({
|
|
2366
|
+
dictation: ServerCapabilityStateSchema,
|
|
2367
|
+
voice: ServerCapabilityStateSchema,
|
|
2368
|
+
});
|
|
2369
|
+
export const ServerCapabilitiesSchema = z
|
|
2370
|
+
.object({
|
|
2371
|
+
voice: ServerVoiceCapabilitiesSchema.optional(),
|
|
2372
|
+
})
|
|
2373
|
+
.passthrough();
|
|
2374
|
+
const ServerInfoHostnameSchema = z.unknown().transform((value) => {
|
|
2375
|
+
if (typeof value !== "string") {
|
|
2376
|
+
return null;
|
|
2377
|
+
}
|
|
2378
|
+
const trimmed = value.trim();
|
|
2379
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2380
|
+
});
|
|
2381
|
+
const ServerInfoVersionSchema = z.unknown().transform((value) => {
|
|
2382
|
+
if (typeof value !== "string") {
|
|
2383
|
+
return null;
|
|
2384
|
+
}
|
|
2385
|
+
const trimmed = value.trim();
|
|
2386
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
2387
|
+
});
|
|
2388
|
+
const ServerCapabilitiesFromUnknownSchema = z
|
|
2389
|
+
.unknown()
|
|
2390
|
+
.optional()
|
|
2391
|
+
.transform((value) => {
|
|
2392
|
+
if (value === undefined) {
|
|
2393
|
+
return undefined;
|
|
2394
|
+
}
|
|
2395
|
+
const parsed = ServerCapabilitiesSchema.safeParse(value);
|
|
2396
|
+
if (!parsed.success) {
|
|
2397
|
+
return undefined;
|
|
2398
|
+
}
|
|
2399
|
+
return parsed.data;
|
|
2400
|
+
});
|
|
2401
|
+
export const ServerInfoStatusPayloadSchema = z
|
|
2402
|
+
.object({
|
|
2403
|
+
status: z.literal("server_info"),
|
|
2404
|
+
serverId: z.string().trim().min(1),
|
|
2405
|
+
hostname: ServerInfoHostnameSchema.optional(),
|
|
2406
|
+
version: ServerInfoVersionSchema.optional(),
|
|
2407
|
+
capabilities: ServerCapabilitiesFromUnknownSchema.optional(),
|
|
2408
|
+
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
2409
|
+
features: z
|
|
2410
|
+
.object({
|
|
2411
|
+
providersSnapshot: z.boolean().optional(),
|
|
2412
|
+
checkoutGithubSetAutoMerge: z.boolean().optional(),
|
|
2413
|
+
// COMPAT(githubCheckDetails): added in v0.1.92, remove gate after 2026-12-08.
|
|
2414
|
+
githubCheckDetails: z.boolean().optional(),
|
|
2415
|
+
// COMPAT(daemonStatusRpc): added in v0.1.76, remove gate after 2026-11-18.
|
|
2416
|
+
daemonStatusRpc: z.boolean().optional(),
|
|
2417
|
+
// COMPAT(terminalRestoreModes): added in v0.1.81, remove gate after 2026-11-23.
|
|
2418
|
+
"terminal-restore-modes": z.boolean().optional(),
|
|
2419
|
+
// COMPAT(rewind): added in v0.1.X, drop the gate when floor >= v0.1.X.
|
|
2420
|
+
rewind: z.boolean().optional(),
|
|
2421
|
+
// COMPAT(checkoutRefresh): added in v0.1.86, remove gate after 2026-11-29.
|
|
2422
|
+
checkoutRefresh: z.boolean().optional(),
|
|
2423
|
+
// COMPAT(workspaceMultiplicity): added in v0.1.97, drop the gate when floor >= v0.1.97
|
|
2424
|
+
workspaceMultiplicity: z.boolean().optional(),
|
|
2425
|
+
// COMPAT(projectRemove): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
2426
|
+
projectRemove: z.boolean().optional(),
|
|
2427
|
+
// COMPAT(projectAdd): added in v0.1.97, drop the gate when floor >= v0.1.97.
|
|
2428
|
+
projectAdd: z.boolean().optional(),
|
|
2429
|
+
// COMPAT(worktreeRestore): added in v0.1.97, drop the gate when floor >= v0.1.97
|
|
2430
|
+
worktreeRestore: z.boolean().optional(),
|
|
2431
|
+
// COMPAT(providerUsageList): added in v0.1.98, drop the gate when daemon floor >= v0.1.98.
|
|
2432
|
+
providerUsageList: z.boolean().optional(),
|
|
2433
|
+
// COMPAT(agentDetach): added in v0.1.98, remove gate after 2026-12-19 once daemon floor >= v0.1.98.
|
|
2434
|
+
agentDetach: z.boolean().optional(),
|
|
2435
|
+
// COMPAT(daemonDiagnostics): added in v0.1.100, remove gate after 2026-12-25 once daemon floor >= v0.1.100.
|
|
2436
|
+
daemonDiagnostics: z.boolean().optional(),
|
|
2437
|
+
// COMPAT(daemonSelfUpdate): added in v0.1.93, remove gate after 2026-12-13.
|
|
2438
|
+
daemonSelfUpdate: z.boolean().optional(),
|
|
2439
|
+
// COMPAT(agentForkContext): added in v0.1.102, remove gate after 2026-12-28.
|
|
2440
|
+
agentForkContext: z.boolean().optional(),
|
|
2441
|
+
// COMPAT(providerRemove): added in v0.1.105, drop the gate when daemon floor >= v0.1.105.
|
|
2442
|
+
providerRemove: z.boolean().optional(),
|
|
2443
|
+
// COMPAT(agentContextUsage): added in v0.3.4, drop the gate when daemon floor >= v0.3.4.
|
|
2444
|
+
agentContextUsage: z.boolean().optional(),
|
|
2445
|
+
// COMPAT(artifacts): added in v0.4.1, drop the gate when daemon floor >= v0.4.1.
|
|
2446
|
+
artifacts: z.boolean().optional(),
|
|
2447
|
+
// COMPAT(observedSubagents): added in v0.4.3, drop the gate when daemon floor >= v0.4.3.
|
|
2448
|
+
observedSubagents: z.boolean().optional(),
|
|
2449
|
+
// COMPAT(textEditor): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
|
|
2450
|
+
textEditor: z.boolean().optional(),
|
|
2451
|
+
// COMPAT(projectSearch): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
|
|
2452
|
+
projectSearch: z.boolean().optional(),
|
|
2453
|
+
// COMPAT(codeIndex): added in v0.4.4, drop the gate when daemon floor >= v0.4.4.
|
|
2454
|
+
codeIndex: z.boolean().optional(),
|
|
2455
|
+
// COMPAT(artifactsToolGroup): added in v0.4.5, drop the gate when daemon floor >= v0.4.5.
|
|
2456
|
+
artifactsToolGroup: z.boolean().optional(),
|
|
2457
|
+
// COMPAT(speechSettings): added in v0.4.5, drop the gate when daemon floor >= v0.4.5.
|
|
2458
|
+
speechSettings: z.boolean().optional(),
|
|
2459
|
+
// COMPAT(gitHostingProviders): added in v0.4.5, drop the gate when daemon floor >= v0.4.5.
|
|
2460
|
+
gitHostingProviders: z.boolean().optional(),
|
|
2461
|
+
// COMPAT(agentPersonalities): added in v0.5.0, drop the gate when daemon floor >= v0.5.0.
|
|
2462
|
+
agentPersonalities: z.boolean().optional(),
|
|
2463
|
+
// COMPAT(ttsPreview): added in v0.4.7, drop the gate when daemon floor >= v0.4.7.
|
|
2464
|
+
ttsPreview: z.boolean().optional(),
|
|
2465
|
+
// COMPAT(setAgentPersonality): added in v0.5.0, drop the gate when daemon floor >= v0.5.0.
|
|
2466
|
+
setAgentPersonality: z.boolean().optional(),
|
|
2467
|
+
})
|
|
2468
|
+
.optional(),
|
|
2469
|
+
})
|
|
2470
|
+
.passthrough()
|
|
2471
|
+
.transform((payload) => ({
|
|
2472
|
+
...payload,
|
|
2473
|
+
hostname: payload.hostname ?? null,
|
|
2474
|
+
version: payload.version ?? null,
|
|
2475
|
+
}));
|
|
2476
|
+
export const StatusMessageSchema = z.object({
|
|
2477
|
+
type: z.literal("status"),
|
|
2478
|
+
payload: z
|
|
2479
|
+
.object({
|
|
2480
|
+
status: z.string(),
|
|
2481
|
+
})
|
|
2482
|
+
.passthrough(), // Allow additional fields
|
|
2483
|
+
});
|
|
2484
|
+
export const PongMessageSchema = z.object({
|
|
2485
|
+
type: z.literal("pong"),
|
|
2486
|
+
payload: z.object({
|
|
2487
|
+
requestId: z.string(),
|
|
2488
|
+
clientSentAt: z.number().int().optional(),
|
|
2489
|
+
serverReceivedAt: z.number().int(),
|
|
2490
|
+
serverSentAt: z.number().int(),
|
|
2491
|
+
}),
|
|
2492
|
+
});
|
|
2493
|
+
export const RpcErrorMessageSchema = z.object({
|
|
2494
|
+
type: z.literal("rpc_error"),
|
|
2495
|
+
payload: z.object({
|
|
2496
|
+
requestId: z.string(),
|
|
2497
|
+
requestType: z.string().optional(),
|
|
2498
|
+
error: z.string(),
|
|
2499
|
+
code: z.string().optional(),
|
|
2500
|
+
}),
|
|
2501
|
+
});
|
|
2502
|
+
const AgentStatusWithRequestSchema = z.object({
|
|
2503
|
+
agentId: z.string(),
|
|
2504
|
+
requestId: z.string(),
|
|
2505
|
+
});
|
|
2506
|
+
const AgentStatusWithTimelineSchema = AgentStatusWithRequestSchema.extend({
|
|
2507
|
+
timelineSize: z.number().optional(),
|
|
2508
|
+
});
|
|
2509
|
+
export const AgentCreatedStatusPayloadSchema = z
|
|
2510
|
+
.object({
|
|
2511
|
+
status: z.literal("agent_created"),
|
|
2512
|
+
agent: AgentSnapshotPayloadSchema,
|
|
2513
|
+
})
|
|
2514
|
+
.extend(AgentStatusWithRequestSchema.shape);
|
|
2515
|
+
export const AgentCreateFailedStatusPayloadSchema = z.object({
|
|
2516
|
+
status: z.literal("agent_create_failed"),
|
|
2517
|
+
requestId: z.string(),
|
|
2518
|
+
error: z.string(),
|
|
2519
|
+
errorCode: z.string().optional(),
|
|
2520
|
+
});
|
|
2521
|
+
export const AgentResumedStatusPayloadSchema = z
|
|
2522
|
+
.object({
|
|
2523
|
+
status: z.literal("agent_resumed"),
|
|
2524
|
+
agent: AgentSnapshotPayloadSchema,
|
|
2525
|
+
})
|
|
2526
|
+
.extend(AgentStatusWithTimelineSchema.shape);
|
|
2527
|
+
export const AgentRefreshedStatusPayloadSchema = z
|
|
2528
|
+
.object({
|
|
2529
|
+
status: z.literal("agent_refreshed"),
|
|
2530
|
+
})
|
|
2531
|
+
.extend(AgentStatusWithTimelineSchema.shape);
|
|
2532
|
+
export const RestartRequestedStatusPayloadSchema = z.object({
|
|
2533
|
+
status: z.literal("restart_requested"),
|
|
2534
|
+
clientId: z.string(),
|
|
2535
|
+
reason: z.string().optional(),
|
|
2536
|
+
requestId: z.string(),
|
|
2537
|
+
});
|
|
2538
|
+
export const ShutdownRequestedStatusPayloadSchema = z.object({
|
|
2539
|
+
status: z.literal("shutdown_requested"),
|
|
2540
|
+
clientId: z.string(),
|
|
2541
|
+
requestId: z.string(),
|
|
2542
|
+
});
|
|
2543
|
+
export const DaemonConfigChangedStatusPayloadSchema = z
|
|
2544
|
+
.object({
|
|
2545
|
+
status: z.literal("daemon_config_changed"),
|
|
2546
|
+
config: MutableDaemonConfigSchema,
|
|
2547
|
+
})
|
|
2548
|
+
.passthrough();
|
|
2549
|
+
export const KnownStatusPayloadSchema = z.discriminatedUnion("status", [
|
|
2550
|
+
AgentCreatedStatusPayloadSchema,
|
|
2551
|
+
AgentCreateFailedStatusPayloadSchema,
|
|
2552
|
+
AgentResumedStatusPayloadSchema,
|
|
2553
|
+
AgentRefreshedStatusPayloadSchema,
|
|
2554
|
+
ShutdownRequestedStatusPayloadSchema,
|
|
2555
|
+
RestartRequestedStatusPayloadSchema,
|
|
2556
|
+
DaemonConfigChangedStatusPayloadSchema,
|
|
2557
|
+
]);
|
|
2558
|
+
export const ArtifactMessageSchema = z.object({
|
|
2559
|
+
type: z.literal("artifact"),
|
|
2560
|
+
payload: z.object({
|
|
2561
|
+
type: z.enum(["markdown", "diff", "image", "code"]),
|
|
2562
|
+
id: z.string(),
|
|
2563
|
+
title: z.string(),
|
|
2564
|
+
content: z.string(),
|
|
2565
|
+
isBase64: z.boolean(),
|
|
2566
|
+
}),
|
|
2567
|
+
});
|
|
2568
|
+
export const ProjectCheckoutLiteNotGitPayloadSchema = z
|
|
2569
|
+
.object({
|
|
2570
|
+
cwd: z.string(),
|
|
2571
|
+
isGit: z.literal(false),
|
|
2572
|
+
currentBranch: z.null(),
|
|
2573
|
+
remoteUrl: z.null(),
|
|
2574
|
+
worktreeRoot: z.null().optional(),
|
|
2575
|
+
isOttoOwnedWorktree: z.literal(false),
|
|
2576
|
+
mainRepoRoot: z.null(),
|
|
2577
|
+
})
|
|
2578
|
+
.transform((value) => ({
|
|
2579
|
+
...value,
|
|
2580
|
+
worktreeRoot: null,
|
|
2581
|
+
}));
|
|
2582
|
+
export const ProjectCheckoutLiteGitNonOttoPayloadSchema = z
|
|
2583
|
+
.object({
|
|
2584
|
+
cwd: z.string(),
|
|
2585
|
+
isGit: z.literal(true),
|
|
2586
|
+
currentBranch: z.string().nullable(),
|
|
2587
|
+
remoteUrl: z.string().nullable(),
|
|
2588
|
+
worktreeRoot: z.string().optional(),
|
|
2589
|
+
isOttoOwnedWorktree: z.literal(false),
|
|
2590
|
+
mainRepoRoot: z.string().nullable().optional().default(null),
|
|
2591
|
+
})
|
|
2592
|
+
.transform((value) => ({
|
|
2593
|
+
...value,
|
|
2594
|
+
worktreeRoot: value.worktreeRoot ?? value.cwd,
|
|
2595
|
+
}));
|
|
2596
|
+
export const ProjectCheckoutLiteGitOttoPayloadSchema = z
|
|
2597
|
+
.object({
|
|
2598
|
+
cwd: z.string(),
|
|
2599
|
+
isGit: z.literal(true),
|
|
2600
|
+
currentBranch: z.string().nullable(),
|
|
2601
|
+
remoteUrl: z.string().nullable(),
|
|
2602
|
+
worktreeRoot: z.string().optional(),
|
|
2603
|
+
isOttoOwnedWorktree: z.literal(true),
|
|
2604
|
+
mainRepoRoot: z.string(),
|
|
2605
|
+
})
|
|
2606
|
+
.transform((value) => ({
|
|
2607
|
+
...value,
|
|
2608
|
+
worktreeRoot: value.worktreeRoot ?? value.cwd,
|
|
2609
|
+
}));
|
|
2610
|
+
export const ProjectCheckoutLitePayloadSchema = z.union([
|
|
2611
|
+
ProjectCheckoutLiteNotGitPayloadSchema,
|
|
2612
|
+
ProjectCheckoutLiteGitNonOttoPayloadSchema,
|
|
2613
|
+
ProjectCheckoutLiteGitOttoPayloadSchema,
|
|
2614
|
+
]);
|
|
2615
|
+
export const ProjectPlacementPayloadSchema = z.object({
|
|
2616
|
+
projectKey: z.string(),
|
|
2617
|
+
projectName: z.string(),
|
|
2618
|
+
workspaceName: z.string().nullable().optional(),
|
|
2619
|
+
checkout: ProjectCheckoutLitePayloadSchema,
|
|
2620
|
+
});
|
|
2621
|
+
export const WorkspaceScriptLifecycleSchema = z.enum(["running", "stopped"]);
|
|
2622
|
+
export const WorkspaceScriptHealthSchema = z.enum(["healthy", "unhealthy"]);
|
|
2623
|
+
export const WorkspaceScriptPayloadSchema = z.object({
|
|
2624
|
+
scriptName: z.string(),
|
|
2625
|
+
type: z.enum(["script", "service"]).optional().default("service"),
|
|
2626
|
+
hostname: z.string(),
|
|
2627
|
+
port: z.number().int().positive().nullable(),
|
|
2628
|
+
localProxyUrl: z.string().nullable().optional(),
|
|
2629
|
+
publicProxyUrl: z.string().nullable().optional(),
|
|
2630
|
+
proxyUrl: z.string().nullable().optional().default(null),
|
|
2631
|
+
lifecycle: WorkspaceScriptLifecycleSchema,
|
|
2632
|
+
health: WorkspaceScriptHealthSchema.nullable(),
|
|
2633
|
+
exitCode: z.number().nullable().optional().default(null),
|
|
2634
|
+
terminalId: z.string().nullable().optional().default(null),
|
|
2635
|
+
});
|
|
2636
|
+
const WorkspaceGitRuntimePayloadSchema = z
|
|
2637
|
+
.object({
|
|
2638
|
+
currentBranch: z.string().nullable().optional(),
|
|
2639
|
+
remoteUrl: z.string().nullable().optional(),
|
|
2640
|
+
isOttoOwnedWorktree: z.boolean().optional(),
|
|
2641
|
+
isDirty: z.boolean().nullable().optional(),
|
|
2642
|
+
aheadBehind: z
|
|
2643
|
+
.object({
|
|
2644
|
+
ahead: z.number(),
|
|
2645
|
+
behind: z.number(),
|
|
2646
|
+
})
|
|
2647
|
+
.nullable()
|
|
2648
|
+
.optional(),
|
|
2649
|
+
aheadOfOrigin: z.number().nullable().optional(),
|
|
2650
|
+
behindOfOrigin: z.number().nullable().optional(),
|
|
2651
|
+
})
|
|
2652
|
+
.optional()
|
|
2653
|
+
.nullable();
|
|
2654
|
+
const WorkspaceGitHubRuntimePayloadSchema = z
|
|
2655
|
+
.object({
|
|
2656
|
+
featuresEnabled: z.boolean().optional(),
|
|
2657
|
+
pullRequest: z
|
|
2658
|
+
.object({
|
|
2659
|
+
number: z.number().optional(),
|
|
2660
|
+
url: z.string(),
|
|
2661
|
+
title: z.string(),
|
|
2662
|
+
state: z.string(),
|
|
2663
|
+
baseRefName: z.string(),
|
|
2664
|
+
headRefName: z.string(),
|
|
2665
|
+
isMerged: z.boolean(),
|
|
2666
|
+
isDraft: z.boolean().optional(),
|
|
2667
|
+
mergeable: z.enum(["MERGEABLE", "CONFLICTING", "UNKNOWN"]).catch("UNKNOWN").optional(),
|
|
2668
|
+
checks: z
|
|
2669
|
+
.array(z.object({
|
|
2670
|
+
name: z.string(),
|
|
2671
|
+
status: z.enum(["success", "failure", "pending", "skipped", "cancelled"]),
|
|
2672
|
+
url: z.string().nullable(),
|
|
2673
|
+
workflow: z.string().optional(),
|
|
2674
|
+
duration: z.string().optional(),
|
|
2675
|
+
}))
|
|
2676
|
+
.optional(),
|
|
2677
|
+
checksStatus: z.enum(["none", "pending", "success", "failure"]).optional(),
|
|
2678
|
+
reviewDecision: z.enum(["approved", "changes_requested", "pending"]).nullable().optional(),
|
|
2679
|
+
repoOwner: z.string().optional(),
|
|
2680
|
+
repoName: z.string().optional(),
|
|
2681
|
+
github: z.unknown().optional(),
|
|
2682
|
+
})
|
|
2683
|
+
.nullable()
|
|
2684
|
+
.optional(),
|
|
2685
|
+
error: z
|
|
2686
|
+
.object({
|
|
2687
|
+
message: z.string(),
|
|
2688
|
+
})
|
|
2689
|
+
.nullable()
|
|
2690
|
+
.optional(),
|
|
2691
|
+
refreshedAt: z.string().nullable().optional(),
|
|
2692
|
+
})
|
|
2693
|
+
.optional()
|
|
2694
|
+
.nullable();
|
|
2695
|
+
export const WorkspaceDescriptorPayloadSchema = z
|
|
2696
|
+
.object({
|
|
2697
|
+
id: z.string(),
|
|
2698
|
+
projectId: z.string(),
|
|
2699
|
+
projectDisplayName: z.string(),
|
|
2700
|
+
// COMPAT(projectCustomName): added in v0.1.76, drop the optional gate when floor >= v0.1.76.
|
|
2701
|
+
// When the user has renamed a project, projectDisplayName carries the resolved
|
|
2702
|
+
// value (customName) and projectCustomName mirrors the raw override so the
|
|
2703
|
+
// settings UI can prefill its input and offer a "reset" action.
|
|
2704
|
+
projectCustomName: z.string().nullable().optional(),
|
|
2705
|
+
projectRootPath: z.string(),
|
|
2706
|
+
workspaceDirectory: z.string().optional(),
|
|
2707
|
+
projectKind: z.enum(["git", "non_git", "directory"]),
|
|
2708
|
+
// COMPAT(workspaces): keep legacy directory workspace kind parseable.
|
|
2709
|
+
workspaceKind: z.enum(["directory", "local_checkout", "checkout", "worktree"]),
|
|
2710
|
+
name: z.string(),
|
|
2711
|
+
// COMPAT(workspaceTitles): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
2712
|
+
// When the user has titled a workspace, `name` carries the resolved value
|
|
2713
|
+
// (title) and `title` mirrors the raw override so the rename UI can prefill
|
|
2714
|
+
// its input and offer a "reset to branch name" action. Null means the name
|
|
2715
|
+
// is derived from the branch/directory.
|
|
2716
|
+
title: z.string().nullable().optional(),
|
|
2717
|
+
archivingAt: z.string().nullable().optional().default(null),
|
|
2718
|
+
status: WorkspaceStateBucketSchema,
|
|
2719
|
+
// Best-effort workspace status entry timestamp. Old daemons omit the
|
|
2720
|
+
// field; old clients treat missing and null equivalently. The transform
|
|
2721
|
+
// coerces a missing field to `null` so downstream code never has to
|
|
2722
|
+
// handle `undefined`.
|
|
2723
|
+
statusEnteredAt: z
|
|
2724
|
+
.string()
|
|
2725
|
+
.nullish()
|
|
2726
|
+
.transform((value) => value ?? null),
|
|
2727
|
+
activityAt: z.string().nullable(),
|
|
2728
|
+
diffStat: z
|
|
2729
|
+
.object({
|
|
2730
|
+
additions: z.number(),
|
|
2731
|
+
deletions: z.number(),
|
|
2732
|
+
})
|
|
2733
|
+
.nullable()
|
|
2734
|
+
.optional(),
|
|
2735
|
+
scripts: z.array(WorkspaceScriptPayloadSchema).default([]),
|
|
2736
|
+
gitRuntime: WorkspaceGitRuntimePayloadSchema,
|
|
2737
|
+
githubRuntime: WorkspaceGitHubRuntimePayloadSchema,
|
|
2738
|
+
project: ProjectPlacementPayloadSchema.optional(),
|
|
2739
|
+
})
|
|
2740
|
+
.transform((workspace) => ({
|
|
2741
|
+
...workspace,
|
|
2742
|
+
workspaceDirectory: workspace.workspaceDirectory ?? workspace.projectRootPath,
|
|
2743
|
+
}));
|
|
2744
|
+
export const ArtifactUpdateMessageSchema = z.object({
|
|
2745
|
+
type: z.literal("artifact_update"),
|
|
2746
|
+
payload: z.object({
|
|
2747
|
+
artifact: ArtifactMetadataSchema,
|
|
2748
|
+
}),
|
|
2749
|
+
});
|
|
2750
|
+
export const AgentUpdateMessageSchema = z.object({
|
|
2751
|
+
type: z.literal("agent_update"),
|
|
2752
|
+
payload: z.discriminatedUnion("kind", [
|
|
2753
|
+
z.object({
|
|
2754
|
+
kind: z.literal("upsert"),
|
|
2755
|
+
agent: AgentSnapshotPayloadSchema,
|
|
2756
|
+
project: ProjectPlacementPayloadSchema.nullable().optional(),
|
|
2757
|
+
}),
|
|
2758
|
+
z.object({
|
|
2759
|
+
kind: z.literal("remove"),
|
|
2760
|
+
agentId: z.string(),
|
|
2761
|
+
}),
|
|
2762
|
+
]),
|
|
2763
|
+
});
|
|
2764
|
+
export const AgentStreamMessageSchema = z.object({
|
|
2765
|
+
type: z.literal("agent_stream"),
|
|
2766
|
+
payload: z.object({
|
|
2767
|
+
agentId: z.string(),
|
|
2768
|
+
event: AgentStreamEventPayloadSchema,
|
|
2769
|
+
timestamp: z.string(),
|
|
2770
|
+
// Present for timeline events. Maps 1:1 to canonical in-memory timeline rows.
|
|
2771
|
+
seq: z.number().int().nonnegative().optional(),
|
|
2772
|
+
epoch: z.string().optional(),
|
|
2773
|
+
}),
|
|
2774
|
+
});
|
|
2775
|
+
export const AgentStatusMessageSchema = z.object({
|
|
2776
|
+
type: z.literal("agent_status"),
|
|
2777
|
+
payload: z.object({
|
|
2778
|
+
agentId: z.string(),
|
|
2779
|
+
status: z.string(),
|
|
2780
|
+
info: AgentSnapshotPayloadSchema,
|
|
2781
|
+
}),
|
|
2782
|
+
});
|
|
2783
|
+
export const AgentListMessageSchema = z.object({
|
|
2784
|
+
type: z.literal("agent_list"),
|
|
2785
|
+
payload: z.object({
|
|
2786
|
+
agents: z.array(AgentSnapshotPayloadSchema),
|
|
2787
|
+
}),
|
|
2788
|
+
});
|
|
2789
|
+
const AgentDirectoryResponseEntrySchema = z.object({
|
|
2790
|
+
agent: AgentSnapshotPayloadSchema,
|
|
2791
|
+
project: ProjectPlacementPayloadSchema,
|
|
2792
|
+
});
|
|
2793
|
+
const AgentDirectoryPageInfoSchema = z.object({
|
|
2794
|
+
nextCursor: z.string().nullable(),
|
|
2795
|
+
prevCursor: z.string().nullable(),
|
|
2796
|
+
hasMore: z.boolean(),
|
|
2797
|
+
});
|
|
2798
|
+
export const FetchAgentsResponseMessageSchema = z.object({
|
|
2799
|
+
type: z.literal("fetch_agents_response"),
|
|
2800
|
+
payload: z.object({
|
|
2801
|
+
requestId: z.string(),
|
|
2802
|
+
subscriptionId: z.string().nullable().optional(),
|
|
2803
|
+
entries: z.array(AgentDirectoryResponseEntrySchema),
|
|
2804
|
+
pageInfo: AgentDirectoryPageInfoSchema,
|
|
2805
|
+
}),
|
|
2806
|
+
});
|
|
2807
|
+
export const FetchAgentHistoryResponseMessageSchema = z.object({
|
|
2808
|
+
type: z.literal("fetch_agent_history_response"),
|
|
2809
|
+
payload: z.object({
|
|
2810
|
+
requestId: z.string(),
|
|
2811
|
+
entries: z.array(AgentDirectoryResponseEntrySchema),
|
|
2812
|
+
pageInfo: AgentDirectoryPageInfoSchema,
|
|
2813
|
+
}),
|
|
2814
|
+
});
|
|
2815
|
+
export const FetchRecentProviderSessionsResponseMessageSchema = z.object({
|
|
2816
|
+
type: z.literal("fetch_recent_provider_sessions_response"),
|
|
2817
|
+
payload: z.object({
|
|
2818
|
+
requestId: z.string(),
|
|
2819
|
+
entries: z.array(RecentProviderSessionDescriptorPayloadSchema),
|
|
2820
|
+
filteredAlreadyImportedCount: z.number().int().nonnegative().optional(),
|
|
2821
|
+
}),
|
|
2822
|
+
});
|
|
2823
|
+
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
2824
|
+
// A project parent that has zero active workspaces. The sidebar renders the
|
|
2825
|
+
// project row with a new-workspace child so projects persist after their last
|
|
2826
|
+
// workspace is archived.
|
|
2827
|
+
export const WorkspaceProjectDescriptorPayloadSchema = z.object({
|
|
2828
|
+
projectId: z.string(),
|
|
2829
|
+
projectDisplayName: z.string(),
|
|
2830
|
+
projectCustomName: z.string().nullable().optional(),
|
|
2831
|
+
projectRootPath: z.string(),
|
|
2832
|
+
projectKind: z.enum(["git", "non_git", "directory"]),
|
|
2833
|
+
});
|
|
2834
|
+
export const FetchWorkspacesResponseMessageSchema = z.object({
|
|
2835
|
+
type: z.literal("fetch_workspaces_response"),
|
|
2836
|
+
payload: z.object({
|
|
2837
|
+
requestId: z.string(),
|
|
2838
|
+
subscriptionId: z.string().nullable().optional(),
|
|
2839
|
+
entries: z.array(WorkspaceDescriptorPayloadSchema),
|
|
2840
|
+
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
2841
|
+
// Project parents with no active workspaces. Old daemons omit it; old clients
|
|
2842
|
+
// ignore it. Only populated on the first page (no cursor).
|
|
2843
|
+
emptyProjects: z.array(WorkspaceProjectDescriptorPayloadSchema).optional().default([]),
|
|
2844
|
+
pageInfo: z.object({
|
|
2845
|
+
nextCursor: z.string().nullable(),
|
|
2846
|
+
prevCursor: z.string().nullable(),
|
|
2847
|
+
hasMore: z.boolean(),
|
|
2848
|
+
}),
|
|
2849
|
+
}),
|
|
2850
|
+
});
|
|
2851
|
+
export const WorkspaceUpdateMessageSchema = z.object({
|
|
2852
|
+
type: z.literal("workspace_update"),
|
|
2853
|
+
payload: z.discriminatedUnion("kind", [
|
|
2854
|
+
z.object({
|
|
2855
|
+
kind: z.literal("upsert"),
|
|
2856
|
+
workspace: WorkspaceDescriptorPayloadSchema,
|
|
2857
|
+
}),
|
|
2858
|
+
z.object({
|
|
2859
|
+
kind: z.literal("remove"),
|
|
2860
|
+
id: z.string(),
|
|
2861
|
+
// COMPAT(workspaceProjects): added in v0.1.97, drop the optional gate when floor >= v0.1.97.
|
|
2862
|
+
// When archiving this workspace leaves its project with no active
|
|
2863
|
+
// workspaces, the daemon includes the project parent so the sidebar keeps
|
|
2864
|
+
// rendering it without waiting for a full re-hydration. Old daemons omit
|
|
2865
|
+
// it; old clients ignore it and surface the project on their next
|
|
2866
|
+
// workspace fetch instead.
|
|
2867
|
+
emptyProject: WorkspaceProjectDescriptorPayloadSchema.optional(),
|
|
2868
|
+
// Project removal is represented on the existing workspace update channel
|
|
2869
|
+
// so old clients can still parse the message and ignore the extra field.
|
|
2870
|
+
removedProjectId: z.string().optional(),
|
|
2871
|
+
}),
|
|
2872
|
+
]),
|
|
2873
|
+
});
|
|
2874
|
+
export const ScriptStatusUpdateMessageSchema = z.object({
|
|
2875
|
+
type: z.literal("script_status_update"),
|
|
2876
|
+
payload: z.object({
|
|
2877
|
+
workspaceId: z.string(),
|
|
2878
|
+
scripts: z.array(WorkspaceScriptPayloadSchema),
|
|
2879
|
+
}),
|
|
2880
|
+
});
|
|
2881
|
+
export const WorkspaceSetupProgressMessageSchema = z.object({
|
|
2882
|
+
type: z.literal("workspace_setup_progress"),
|
|
2883
|
+
payload: z.object({
|
|
2884
|
+
workspaceId: z.string(),
|
|
2885
|
+
status: z.enum(["running", "completed", "failed"]),
|
|
2886
|
+
detail: WorktreeSetupDetailPayloadSchema,
|
|
2887
|
+
error: z.string().nullable(),
|
|
2888
|
+
}),
|
|
2889
|
+
});
|
|
2890
|
+
export const WorkspaceSetupSnapshotSchema = z.object({
|
|
2891
|
+
status: z.enum(["running", "completed", "failed"]),
|
|
2892
|
+
detail: WorktreeSetupDetailPayloadSchema,
|
|
2893
|
+
error: z.string().nullable(),
|
|
2894
|
+
});
|
|
2895
|
+
export const WorkspaceSetupStatusResponseMessageSchema = z.object({
|
|
2896
|
+
type: z.literal("workspace_setup_status_response"),
|
|
2897
|
+
payload: z.object({
|
|
2898
|
+
requestId: z.string(),
|
|
2899
|
+
workspaceId: z.string(),
|
|
2900
|
+
snapshot: WorkspaceSetupSnapshotSchema.nullable(),
|
|
2901
|
+
}),
|
|
2902
|
+
});
|
|
2903
|
+
export const OpenProjectResponseMessageSchema = z.object({
|
|
2904
|
+
type: z.literal("open_project_response"),
|
|
2905
|
+
payload: z.object({
|
|
2906
|
+
requestId: z.string(),
|
|
2907
|
+
workspace: WorkspaceDescriptorPayloadSchema.nullable(),
|
|
2908
|
+
error: z.string().nullable(),
|
|
2909
|
+
// Unknown codes from newer daemons degrade to null; clients fall back to `error`.
|
|
2910
|
+
errorCode: z.enum(["directory_not_found"]).nullish().catch(null),
|
|
2911
|
+
}),
|
|
2912
|
+
});
|
|
2913
|
+
export const ProjectAddResponseSchema = z.object({
|
|
2914
|
+
type: z.literal("project.add.response"),
|
|
2915
|
+
payload: z.object({
|
|
2916
|
+
requestId: z.string(),
|
|
2917
|
+
project: WorkspaceProjectDescriptorPayloadSchema.nullable(),
|
|
2918
|
+
error: z.string().nullable(),
|
|
2919
|
+
errorCode: z.enum(["directory_not_found"]).nullish().catch(null),
|
|
2920
|
+
}),
|
|
2921
|
+
});
|
|
2922
|
+
export const StartWorkspaceScriptResponseMessageSchema = z.object({
|
|
2923
|
+
type: z.literal("start_workspace_script_response"),
|
|
2924
|
+
payload: z.object({
|
|
2925
|
+
requestId: z.string(),
|
|
2926
|
+
workspaceId: z.string(),
|
|
2927
|
+
scriptName: z.string(),
|
|
2928
|
+
terminalId: z.string().nullable(),
|
|
2929
|
+
error: z.string().nullable(),
|
|
2930
|
+
}),
|
|
2931
|
+
});
|
|
2932
|
+
// COMPAT(desktopEditorBridge): added in v0.1.88, remove after 2026-12-03 once old clients no longer parse daemon editor RPC responses.
|
|
2933
|
+
export const LegacyListAvailableEditorsResponseMessageSchema = z.object({
|
|
2934
|
+
type: z.literal("list_available_editors_response"),
|
|
2935
|
+
payload: z.object({
|
|
2936
|
+
requestId: z.string(),
|
|
2937
|
+
editors: z.array(z.object({
|
|
2938
|
+
id: z.string().trim().min(1),
|
|
2939
|
+
label: z.string(),
|
|
2940
|
+
})),
|
|
2941
|
+
error: z.string().nullable(),
|
|
2942
|
+
}),
|
|
2943
|
+
});
|
|
2944
|
+
export const LegacyOpenInEditorResponseMessageSchema = z.object({
|
|
2945
|
+
type: z.literal("open_in_editor_response"),
|
|
2946
|
+
payload: z.object({
|
|
2947
|
+
requestId: z.string(),
|
|
2948
|
+
error: z.string().nullable(),
|
|
2949
|
+
}),
|
|
2950
|
+
});
|
|
2951
|
+
export const ArchiveWorkspaceResponseMessageSchema = z.object({
|
|
2952
|
+
type: z.literal("archive_workspace_response"),
|
|
2953
|
+
payload: z.object({
|
|
2954
|
+
requestId: z.string(),
|
|
2955
|
+
workspaceId: z.string(),
|
|
2956
|
+
archivedAt: z.string().nullable(),
|
|
2957
|
+
error: z.string().nullable(),
|
|
2958
|
+
}),
|
|
2959
|
+
});
|
|
2960
|
+
export const FetchAgentResponseMessageSchema = z.object({
|
|
2961
|
+
type: z.literal("fetch_agent_response"),
|
|
2962
|
+
payload: z.object({
|
|
2963
|
+
requestId: z.string(),
|
|
2964
|
+
agent: AgentSnapshotPayloadSchema.nullable(),
|
|
2965
|
+
project: ProjectPlacementPayloadSchema.nullable().optional(),
|
|
2966
|
+
error: z.string().nullable(),
|
|
2967
|
+
}),
|
|
2968
|
+
});
|
|
2969
|
+
const AgentTimelineSeqRangeSchema = z.object({
|
|
2970
|
+
startSeq: z.number().int().nonnegative(),
|
|
2971
|
+
endSeq: z.number().int().nonnegative(),
|
|
2972
|
+
});
|
|
2973
|
+
export const AgentTimelineEntryPayloadSchema = z.object({
|
|
2974
|
+
provider: AgentProviderSchema,
|
|
2975
|
+
item: AgentTimelineItemPayloadSchema,
|
|
2976
|
+
timestamp: z.string(),
|
|
2977
|
+
seqStart: z.number().int().nonnegative(),
|
|
2978
|
+
seqEnd: z.number().int().nonnegative(),
|
|
2979
|
+
sourceSeqRanges: z.array(AgentTimelineSeqRangeSchema),
|
|
2980
|
+
collapsed: z.array(z.enum(["assistant_merge", "reasoning_merge", "tool_lifecycle"])),
|
|
2981
|
+
});
|
|
2982
|
+
export const FetchAgentTimelineResponseMessageSchema = z.object({
|
|
2983
|
+
type: z.literal("fetch_agent_timeline_response"),
|
|
2984
|
+
payload: z.object({
|
|
2985
|
+
requestId: z.string(),
|
|
2986
|
+
agentId: z.string(),
|
|
2987
|
+
agent: AgentSnapshotPayloadSchema.nullable(),
|
|
2988
|
+
direction: z.enum(["tail", "before", "after"]),
|
|
2989
|
+
projection: z.enum(["projected", "canonical"]),
|
|
2990
|
+
epoch: z.string(),
|
|
2991
|
+
reset: z.boolean(),
|
|
2992
|
+
staleCursor: z.boolean(),
|
|
2993
|
+
gap: z.boolean(),
|
|
2994
|
+
window: z.object({
|
|
2995
|
+
minSeq: z.number().int().nonnegative(),
|
|
2996
|
+
maxSeq: z.number().int().nonnegative(),
|
|
2997
|
+
nextSeq: z.number().int().nonnegative(),
|
|
2998
|
+
}),
|
|
2999
|
+
startCursor: AgentTimelineCursorSchema.nullable(),
|
|
3000
|
+
endCursor: AgentTimelineCursorSchema.nullable(),
|
|
3001
|
+
hasOlder: z.boolean(),
|
|
3002
|
+
hasNewer: z.boolean(),
|
|
3003
|
+
entries: z.array(AgentTimelineEntryPayloadSchema),
|
|
3004
|
+
error: z.string().nullable(),
|
|
3005
|
+
}),
|
|
3006
|
+
});
|
|
3007
|
+
export const AgentForkContextResponseMessageSchema = z.object({
|
|
3008
|
+
type: z.literal("agent.fork_context.response"),
|
|
3009
|
+
payload: z.object({
|
|
3010
|
+
requestId: z.string(),
|
|
3011
|
+
agentId: z.string(),
|
|
3012
|
+
attachment: TextAttachmentSchema.nullable(),
|
|
3013
|
+
itemCount: z.number().int().nonnegative(),
|
|
3014
|
+
boundaryMessageId: z.string().nullable(),
|
|
3015
|
+
error: z.string().nullable(),
|
|
3016
|
+
}),
|
|
3017
|
+
});
|
|
3018
|
+
export const CancelAgentResponseMessageSchema = z.object({
|
|
3019
|
+
type: z.literal("cancel_agent_response"),
|
|
3020
|
+
payload: z.object({
|
|
3021
|
+
requestId: z.string(),
|
|
3022
|
+
agentId: z.string(),
|
|
3023
|
+
agent: AgentSnapshotPayloadSchema.nullable(),
|
|
3024
|
+
}),
|
|
3025
|
+
});
|
|
3026
|
+
export const ClearAgentAttentionResponseMessageSchema = z.object({
|
|
3027
|
+
type: z.literal("clear_agent_attention_response"),
|
|
3028
|
+
payload: z.object({
|
|
3029
|
+
requestId: z.string(),
|
|
3030
|
+
agentId: z.string().or(z.array(z.string())),
|
|
3031
|
+
agents: z.array(AgentSnapshotPayloadSchema),
|
|
3032
|
+
}),
|
|
3033
|
+
});
|
|
3034
|
+
export const WorkspaceCreateResponseSchema = z.object({
|
|
3035
|
+
type: z.literal("workspace.create.response"),
|
|
3036
|
+
payload: z.object({
|
|
3037
|
+
workspace: WorkspaceDescriptorPayloadSchema.nullable(),
|
|
3038
|
+
setupTerminalId: z.string().nullable(),
|
|
3039
|
+
error: z.string().nullable(),
|
|
3040
|
+
errorCode: z.string().optional(),
|
|
3041
|
+
requestId: z.string(),
|
|
3042
|
+
}),
|
|
3043
|
+
});
|
|
3044
|
+
export const WorkspaceClearAttentionResponseSchema = z.object({
|
|
3045
|
+
type: z.literal("workspace.clear_attention.response"),
|
|
3046
|
+
payload: z.object({
|
|
3047
|
+
requestId: z.string(),
|
|
3048
|
+
workspaceId: z.union([z.string(), z.array(z.string())]),
|
|
3049
|
+
clearedAgentIds: z.array(z.string()),
|
|
3050
|
+
results: z.array(z.object({
|
|
3051
|
+
workspaceId: z.string(),
|
|
3052
|
+
clearedAgentIds: z.array(z.string()),
|
|
3053
|
+
success: z.boolean(),
|
|
3054
|
+
error: z.string().nullable(),
|
|
3055
|
+
})),
|
|
3056
|
+
success: z.boolean(),
|
|
3057
|
+
error: z.string().nullable(),
|
|
3058
|
+
}),
|
|
3059
|
+
});
|
|
3060
|
+
export const SendAgentMessageResponseMessageSchema = z.object({
|
|
3061
|
+
type: z.literal("send_agent_message_response"),
|
|
3062
|
+
payload: z.object({
|
|
3063
|
+
requestId: z.string(),
|
|
3064
|
+
agentId: z.string(),
|
|
3065
|
+
accepted: z.boolean(),
|
|
3066
|
+
error: z.string().nullable(),
|
|
3067
|
+
}),
|
|
3068
|
+
});
|
|
3069
|
+
export const WaitForFinishResponseMessageSchema = z.object({
|
|
3070
|
+
type: z.literal("wait_for_finish_response"),
|
|
3071
|
+
payload: z.object({
|
|
3072
|
+
requestId: z.string(),
|
|
3073
|
+
status: z.enum(["idle", "error", "permission", "timeout"]),
|
|
3074
|
+
final: AgentSnapshotPayloadSchema.nullable(),
|
|
3075
|
+
error: z.string().nullable(),
|
|
3076
|
+
lastMessage: z.string().nullable(),
|
|
3077
|
+
}),
|
|
3078
|
+
});
|
|
3079
|
+
export const GetDaemonConfigResponseMessageSchema = z.object({
|
|
3080
|
+
type: z.literal("get_daemon_config_response"),
|
|
3081
|
+
payload: z
|
|
3082
|
+
.object({
|
|
3083
|
+
requestId: z.string(),
|
|
3084
|
+
config: MutableDaemonConfigSchema,
|
|
3085
|
+
})
|
|
3086
|
+
.passthrough(),
|
|
3087
|
+
});
|
|
3088
|
+
const SpeechEngineOptionSchema = z.object({
|
|
3089
|
+
id: z.string(),
|
|
3090
|
+
available: z.boolean(),
|
|
3091
|
+
reason: z.string().optional(),
|
|
3092
|
+
});
|
|
3093
|
+
const LocalSpeechSttModelOptionSchema = z.object({
|
|
3094
|
+
id: z.string(),
|
|
3095
|
+
// Short display name (e.g. "Parakeet v2 (English)"); older daemons omit it
|
|
3096
|
+
// and clients fall back to the id.
|
|
3097
|
+
label: z.string().optional(),
|
|
3098
|
+
description: z.string(),
|
|
3099
|
+
});
|
|
3100
|
+
const LocalSpeechTtsModelOptionSchema = z.object({
|
|
3101
|
+
id: z.string(),
|
|
3102
|
+
label: z.string().optional(),
|
|
3103
|
+
description: z.string(),
|
|
3104
|
+
voices: z.array(z.string()),
|
|
3105
|
+
defaultVoice: z.string(),
|
|
3106
|
+
});
|
|
3107
|
+
export const SpeechSettingsGetOptionsResponseSchema = z.object({
|
|
3108
|
+
type: z.literal("speech.settings.get_options.response"),
|
|
3109
|
+
payload: z
|
|
3110
|
+
.object({
|
|
3111
|
+
requestId: z.string(),
|
|
3112
|
+
options: z.object({
|
|
3113
|
+
sttEngines: z.array(SpeechEngineOptionSchema),
|
|
3114
|
+
ttsEngines: z.array(SpeechEngineOptionSchema),
|
|
3115
|
+
local: z.object({
|
|
3116
|
+
sttModels: z.array(LocalSpeechSttModelOptionSchema),
|
|
3117
|
+
ttsModels: z.array(LocalSpeechTtsModelOptionSchema),
|
|
3118
|
+
}),
|
|
3119
|
+
openai: z.object({
|
|
3120
|
+
configured: z.boolean(),
|
|
3121
|
+
sttModels: z.array(z.string()),
|
|
3122
|
+
ttsModels: z.array(z.string()),
|
|
3123
|
+
ttsVoices: z.array(z.string()),
|
|
3124
|
+
}),
|
|
3125
|
+
}),
|
|
3126
|
+
})
|
|
3127
|
+
.passthrough(),
|
|
3128
|
+
});
|
|
3129
|
+
export const SpeechTtsPreviewResponseSchema = z.object({
|
|
3130
|
+
type: z.literal("speech.tts.preview.response"),
|
|
3131
|
+
payload: z
|
|
3132
|
+
.object({
|
|
3133
|
+
requestId: z.string(),
|
|
3134
|
+
// base64-encoded audio bytes; absent when synthesis failed (see error).
|
|
3135
|
+
audio: z.string().optional(),
|
|
3136
|
+
// Media type carrying the sample rate, e.g. "audio/pcm;rate=24000",
|
|
3137
|
+
// so the client audio engine plays it back at the correct pitch.
|
|
3138
|
+
format: z.string().optional(),
|
|
3139
|
+
// Human-readable failure reason when audio could not be produced.
|
|
3140
|
+
error: z.string().optional(),
|
|
3141
|
+
})
|
|
3142
|
+
.passthrough(),
|
|
3143
|
+
});
|
|
3144
|
+
export const AgentPersonalitiesGetStatsResponseSchema = z.object({
|
|
3145
|
+
type: z.literal("agentPersonalities.get_stats.response"),
|
|
3146
|
+
payload: z
|
|
3147
|
+
.object({
|
|
3148
|
+
requestId: z.string(),
|
|
3149
|
+
// Per-personality spawn counts, keyed by personality id.
|
|
3150
|
+
stats: z.record(z.string(), z.number()),
|
|
3151
|
+
})
|
|
3152
|
+
.passthrough(),
|
|
3153
|
+
});
|
|
3154
|
+
export const DaemonGetStatusResponseSchema = z.object({
|
|
3155
|
+
type: z.literal("daemon.get_status.response"),
|
|
3156
|
+
payload: z
|
|
3157
|
+
.object({
|
|
3158
|
+
requestId: z.string(),
|
|
3159
|
+
serverId: z.string(),
|
|
3160
|
+
version: z.string().nullable().optional(),
|
|
3161
|
+
pid: z.number(),
|
|
3162
|
+
nodePath: z.string(),
|
|
3163
|
+
startedAt: z.string().nullable().optional(),
|
|
3164
|
+
listen: z.string().nullable(),
|
|
3165
|
+
relay: z
|
|
3166
|
+
.object({
|
|
3167
|
+
enabled: z.boolean(),
|
|
3168
|
+
endpoint: z.string(),
|
|
3169
|
+
publicEndpoint: z.string(),
|
|
3170
|
+
useTls: z.boolean(),
|
|
3171
|
+
publicUseTls: z.boolean(),
|
|
3172
|
+
})
|
|
3173
|
+
.nullable()
|
|
3174
|
+
.optional(),
|
|
3175
|
+
providers: z.array(z.object({
|
|
3176
|
+
provider: z.string(),
|
|
3177
|
+
available: z.boolean(),
|
|
3178
|
+
error: z.string().nullable().optional(),
|
|
3179
|
+
})),
|
|
3180
|
+
})
|
|
3181
|
+
.passthrough(),
|
|
3182
|
+
});
|
|
3183
|
+
export const DaemonGetPairingOfferResponseSchema = z.object({
|
|
3184
|
+
type: z.literal("daemon.get_pairing_offer.response"),
|
|
3185
|
+
payload: z
|
|
3186
|
+
.object({
|
|
3187
|
+
requestId: z.string(),
|
|
3188
|
+
url: z.string(),
|
|
3189
|
+
qr: z.string().nullable().optional(),
|
|
3190
|
+
relayEnabled: z.boolean(),
|
|
3191
|
+
})
|
|
3192
|
+
.passthrough(),
|
|
3193
|
+
});
|
|
3194
|
+
export const DiagnosticsResponseSchema = z.object({
|
|
3195
|
+
type: z.literal("diagnostics.response"),
|
|
3196
|
+
payload: z
|
|
3197
|
+
.object({
|
|
3198
|
+
requestId: z.string(),
|
|
3199
|
+
diagnostic: z.string(),
|
|
3200
|
+
})
|
|
3201
|
+
.passthrough(),
|
|
3202
|
+
});
|
|
3203
|
+
export const SetDaemonConfigResponseMessageSchema = z.object({
|
|
3204
|
+
type: z.literal("set_daemon_config_response"),
|
|
3205
|
+
payload: z
|
|
3206
|
+
.object({
|
|
3207
|
+
requestId: z.string(),
|
|
3208
|
+
config: MutableDaemonConfigSchema,
|
|
3209
|
+
})
|
|
3210
|
+
.passthrough(),
|
|
3211
|
+
});
|
|
3212
|
+
export const ReadProjectConfigResponseMessageSchema = z.object({
|
|
3213
|
+
type: z.literal("read_project_config_response"),
|
|
3214
|
+
// zod-aot 0.2.0 miscompiles boolean discriminators as string options
|
|
3215
|
+
// (`"true"`/`"false"`), so keep this sequential until upstream fixes it.
|
|
3216
|
+
payload: z.union([
|
|
3217
|
+
z.object({
|
|
3218
|
+
requestId: z.string(),
|
|
3219
|
+
repoRoot: z.string(),
|
|
3220
|
+
ok: z.literal(true),
|
|
3221
|
+
config: OttoConfigRawSchema.nullable(),
|
|
3222
|
+
revision: OttoConfigRevisionSchema.nullable(),
|
|
3223
|
+
}),
|
|
3224
|
+
z.object({
|
|
3225
|
+
requestId: z.string(),
|
|
3226
|
+
repoRoot: z.string(),
|
|
3227
|
+
ok: z.literal(false),
|
|
3228
|
+
error: ProjectConfigRpcErrorSchema,
|
|
3229
|
+
}),
|
|
3230
|
+
]),
|
|
3231
|
+
});
|
|
3232
|
+
export const WriteProjectConfigResponseMessageSchema = z.object({
|
|
3233
|
+
type: z.literal("write_project_config_response"),
|
|
3234
|
+
// zod-aot 0.2.0 miscompiles boolean discriminators as string options
|
|
3235
|
+
// (`"true"`/`"false"`), so keep this sequential until upstream fixes it.
|
|
3236
|
+
payload: z.union([
|
|
3237
|
+
z.object({
|
|
3238
|
+
requestId: z.string(),
|
|
3239
|
+
repoRoot: z.string(),
|
|
3240
|
+
ok: z.literal(true),
|
|
3241
|
+
config: OttoConfigRawSchema,
|
|
3242
|
+
revision: OttoConfigRevisionSchema,
|
|
3243
|
+
}),
|
|
3244
|
+
z.object({
|
|
3245
|
+
requestId: z.string(),
|
|
3246
|
+
repoRoot: z.string(),
|
|
3247
|
+
ok: z.literal(false),
|
|
3248
|
+
error: ProjectConfigRpcErrorSchema,
|
|
3249
|
+
}),
|
|
3250
|
+
]),
|
|
3251
|
+
});
|
|
3252
|
+
export const AgentPermissionRequestMessageSchema = z.object({
|
|
3253
|
+
type: z.literal("agent_permission_request"),
|
|
3254
|
+
payload: z.object({
|
|
3255
|
+
agentId: z.string(),
|
|
3256
|
+
request: AgentPermissionRequestPayloadSchema,
|
|
3257
|
+
}),
|
|
3258
|
+
});
|
|
3259
|
+
export const AgentPermissionResolvedMessageSchema = z.object({
|
|
3260
|
+
type: z.literal("agent_permission_resolved"),
|
|
3261
|
+
payload: z.object({
|
|
3262
|
+
agentId: z.string(),
|
|
3263
|
+
requestId: z.string(),
|
|
3264
|
+
resolution: AgentPermissionResponseSchema,
|
|
3265
|
+
}),
|
|
3266
|
+
});
|
|
3267
|
+
export const AgentDeletedMessageSchema = z.object({
|
|
3268
|
+
type: z.literal("agent_deleted"),
|
|
3269
|
+
payload: z.object({
|
|
3270
|
+
agentId: z.string(),
|
|
3271
|
+
requestId: z.string(),
|
|
3272
|
+
}),
|
|
3273
|
+
});
|
|
3274
|
+
export const AgentArchivedMessageSchema = z.object({
|
|
3275
|
+
type: z.literal("agent_archived"),
|
|
3276
|
+
payload: z.object({
|
|
3277
|
+
agentId: z.string(),
|
|
3278
|
+
archivedAt: z.string(),
|
|
3279
|
+
requestId: z.string(),
|
|
3280
|
+
}),
|
|
3281
|
+
});
|
|
3282
|
+
const CloseItemsAgentResultSchema = z.object({
|
|
3283
|
+
agentId: z.string(),
|
|
3284
|
+
archivedAt: z.string(),
|
|
3285
|
+
});
|
|
3286
|
+
const CloseItemsTerminalResultSchema = z.object({
|
|
3287
|
+
terminalId: z.string(),
|
|
3288
|
+
success: z.boolean(),
|
|
3289
|
+
});
|
|
3290
|
+
export const CloseItemsResponseSchema = z.object({
|
|
3291
|
+
type: z.literal("close_items_response"),
|
|
3292
|
+
payload: z.object({
|
|
3293
|
+
agents: z.array(CloseItemsAgentResultSchema),
|
|
3294
|
+
terminals: z.array(CloseItemsTerminalResultSchema),
|
|
3295
|
+
requestId: z.string(),
|
|
3296
|
+
}),
|
|
3297
|
+
});
|
|
3298
|
+
const AheadBehindSchema = z.object({
|
|
3299
|
+
ahead: z.number(),
|
|
3300
|
+
behind: z.number(),
|
|
3301
|
+
});
|
|
3302
|
+
const CheckoutStatusCommonSchema = z.object({
|
|
3303
|
+
cwd: z.string(),
|
|
3304
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3305
|
+
requestId: z.string(),
|
|
3306
|
+
});
|
|
3307
|
+
const CheckoutStatusNotGitSchema = CheckoutStatusCommonSchema.extend({
|
|
3308
|
+
isGit: z.literal(false),
|
|
3309
|
+
isOttoOwnedWorktree: z.literal(false),
|
|
3310
|
+
repoRoot: z.null(),
|
|
3311
|
+
currentBranch: z.null(),
|
|
3312
|
+
isDirty: z.null(),
|
|
3313
|
+
baseRef: z.null(),
|
|
3314
|
+
aheadBehind: z.null(),
|
|
3315
|
+
aheadOfOrigin: z.null(),
|
|
3316
|
+
behindOfOrigin: z.null(),
|
|
3317
|
+
hasRemote: z.boolean(),
|
|
3318
|
+
remoteUrl: z.null(),
|
|
3319
|
+
});
|
|
3320
|
+
const CheckoutStatusGitNonOttoSchema = CheckoutStatusCommonSchema.extend({
|
|
3321
|
+
isGit: z.literal(true),
|
|
3322
|
+
isOttoOwnedWorktree: z.literal(false),
|
|
3323
|
+
repoRoot: z.string(),
|
|
3324
|
+
mainRepoRoot: z.string().nullable().optional().default(null),
|
|
3325
|
+
currentBranch: z.string().nullable(),
|
|
3326
|
+
isDirty: z.boolean(),
|
|
3327
|
+
baseRef: z.string().nullable(),
|
|
3328
|
+
aheadBehind: AheadBehindSchema.nullable(),
|
|
3329
|
+
aheadOfOrigin: z.number().nullable(),
|
|
3330
|
+
behindOfOrigin: z.number().nullable(),
|
|
3331
|
+
hasRemote: z.boolean(),
|
|
3332
|
+
remoteUrl: z.string().nullable(),
|
|
3333
|
+
});
|
|
3334
|
+
const CheckoutStatusGitOttoSchema = CheckoutStatusCommonSchema.extend({
|
|
3335
|
+
isGit: z.literal(true),
|
|
3336
|
+
isOttoOwnedWorktree: z.literal(true),
|
|
3337
|
+
repoRoot: z.string(),
|
|
3338
|
+
mainRepoRoot: z.string(),
|
|
3339
|
+
currentBranch: z.string().nullable(),
|
|
3340
|
+
isDirty: z.boolean(),
|
|
3341
|
+
baseRef: z.string(),
|
|
3342
|
+
aheadBehind: AheadBehindSchema.nullable(),
|
|
3343
|
+
aheadOfOrigin: z.number().nullable(),
|
|
3344
|
+
behindOfOrigin: z.number().nullable(),
|
|
3345
|
+
hasRemote: z.boolean(),
|
|
3346
|
+
remoteUrl: z.string().nullable(),
|
|
3347
|
+
});
|
|
3348
|
+
export const CheckoutStatusResponseSchema = z.object({
|
|
3349
|
+
type: z.literal("checkout_status_response"),
|
|
3350
|
+
payload: z.union([
|
|
3351
|
+
CheckoutStatusNotGitSchema,
|
|
3352
|
+
CheckoutStatusGitNonOttoSchema,
|
|
3353
|
+
CheckoutStatusGitOttoSchema,
|
|
3354
|
+
]),
|
|
3355
|
+
});
|
|
3356
|
+
const CheckoutPrGithubAutoMergeRequestSchema = z
|
|
3357
|
+
.object({
|
|
3358
|
+
enabledAt: z.string().nullable().optional().default(null),
|
|
3359
|
+
mergeMethod: z.string().nullable().optional().default(null),
|
|
3360
|
+
enabledBy: z.string().nullable().optional().default(null),
|
|
3361
|
+
})
|
|
3362
|
+
.nullable()
|
|
3363
|
+
.optional()
|
|
3364
|
+
.default(null);
|
|
3365
|
+
const CheckoutPrGithubRepositoryPolicySchema = z
|
|
3366
|
+
.object({
|
|
3367
|
+
autoMergeAllowed: z.boolean().optional().default(false),
|
|
3368
|
+
mergeCommitAllowed: z.boolean().optional().default(false),
|
|
3369
|
+
squashMergeAllowed: z.boolean().optional().default(false),
|
|
3370
|
+
rebaseMergeAllowed: z.boolean().optional().default(false),
|
|
3371
|
+
viewerDefaultMergeMethod: z.string().nullable().optional().default(null),
|
|
3372
|
+
})
|
|
3373
|
+
.optional()
|
|
3374
|
+
.default({
|
|
3375
|
+
autoMergeAllowed: false,
|
|
3376
|
+
mergeCommitAllowed: false,
|
|
3377
|
+
squashMergeAllowed: false,
|
|
3378
|
+
rebaseMergeAllowed: false,
|
|
3379
|
+
viewerDefaultMergeMethod: null,
|
|
3380
|
+
});
|
|
3381
|
+
const CheckoutPrGithubStatusSchema = z
|
|
3382
|
+
.object({
|
|
3383
|
+
mergeStateStatus: z.string().nullable().optional().default(null),
|
|
3384
|
+
autoMergeRequest: CheckoutPrGithubAutoMergeRequestSchema,
|
|
3385
|
+
viewerCanEnableAutoMerge: z.boolean().optional().default(false),
|
|
3386
|
+
viewerCanDisableAutoMerge: z.boolean().optional().default(false),
|
|
3387
|
+
viewerCanMergeAsAdmin: z.boolean().optional().default(false),
|
|
3388
|
+
viewerCanUpdateBranch: z.boolean().optional().default(false),
|
|
3389
|
+
repository: CheckoutPrGithubRepositoryPolicySchema,
|
|
3390
|
+
isMergeQueueEnabled: z.boolean().optional().default(false),
|
|
3391
|
+
isInMergeQueue: z.boolean().optional().default(false),
|
|
3392
|
+
})
|
|
3393
|
+
.optional();
|
|
3394
|
+
export const CheckoutPrStatusSchema = z.object({
|
|
3395
|
+
number: z.number().optional(),
|
|
3396
|
+
url: z.string(),
|
|
3397
|
+
title: z.string(),
|
|
3398
|
+
state: z.string(),
|
|
3399
|
+
baseRefName: z.string(),
|
|
3400
|
+
headRefName: z.string(),
|
|
3401
|
+
isMerged: z.boolean(),
|
|
3402
|
+
isDraft: z.boolean().optional().default(false),
|
|
3403
|
+
mergeable: z
|
|
3404
|
+
.enum(["MERGEABLE", "CONFLICTING", "UNKNOWN"])
|
|
3405
|
+
.catch("UNKNOWN")
|
|
3406
|
+
.optional()
|
|
3407
|
+
.default("UNKNOWN"),
|
|
3408
|
+
checks: z
|
|
3409
|
+
.array(z.object({
|
|
3410
|
+
name: z.string(),
|
|
3411
|
+
status: z.string(),
|
|
3412
|
+
url: z.string().nullable(),
|
|
3413
|
+
workflow: z.string().optional(),
|
|
3414
|
+
duration: z.string().optional(),
|
|
3415
|
+
checkRunId: z.number().optional(),
|
|
3416
|
+
workflowRunId: z.number().optional(),
|
|
3417
|
+
}))
|
|
3418
|
+
.optional()
|
|
3419
|
+
.default([]),
|
|
3420
|
+
checksStatus: z.string().optional(),
|
|
3421
|
+
reviewDecision: z.string().nullable().optional(),
|
|
3422
|
+
repoOwner: z.string().optional(),
|
|
3423
|
+
repoName: z.string().optional(),
|
|
3424
|
+
github: CheckoutPrGithubStatusSchema,
|
|
3425
|
+
// Provider-neutral per-PR hosting facts. Absent from old daemons; for
|
|
3426
|
+
// GitHub projects both this and the legacy `github` field are populated.
|
|
3427
|
+
hosting: z
|
|
3428
|
+
.object({
|
|
3429
|
+
provider: GitHostingProviderIdWireSchema,
|
|
3430
|
+
bitbucket: z
|
|
3431
|
+
.object({
|
|
3432
|
+
mergeStrategiesAllowed: z.array(z.string()).optional().default([]),
|
|
3433
|
+
defaultMergeStrategy: z.string().nullable().optional().default(null),
|
|
3434
|
+
approvalCount: z.number().optional().default(0),
|
|
3435
|
+
changesRequestedCount: z.number().optional().default(0),
|
|
3436
|
+
})
|
|
3437
|
+
.optional(),
|
|
3438
|
+
})
|
|
3439
|
+
.optional(),
|
|
3440
|
+
});
|
|
3441
|
+
const CheckoutPrStatusPayloadSchema = z.object({
|
|
3442
|
+
cwd: z.string(),
|
|
3443
|
+
status: CheckoutPrStatusSchema.nullable(),
|
|
3444
|
+
// Legacy GitHub-only flag. For non-GitHub providers new daemons send false
|
|
3445
|
+
// here (old clients then correctly show no GitHub features) and describe
|
|
3446
|
+
// the real provider in `hosting` below.
|
|
3447
|
+
githubFeaturesEnabled: z.boolean(),
|
|
3448
|
+
// Provider-neutral enablement. Present even when status is null so clients
|
|
3449
|
+
// can drive search/create-PR affordances for the workspace's provider.
|
|
3450
|
+
hosting: z
|
|
3451
|
+
.object({
|
|
3452
|
+
provider: GitHostingProviderIdWireSchema,
|
|
3453
|
+
featuresEnabled: z.boolean(),
|
|
3454
|
+
capabilities: GitHostingCapabilitiesSchema.optional(),
|
|
3455
|
+
})
|
|
3456
|
+
.optional(),
|
|
3457
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3458
|
+
requestId: z.string(),
|
|
3459
|
+
});
|
|
3460
|
+
const CheckoutStatusUpdateMetadataSchema = z.object({
|
|
3461
|
+
prStatus: CheckoutPrStatusPayloadSchema.optional(),
|
|
3462
|
+
});
|
|
3463
|
+
export const CheckoutStatusUpdateSchema = z.object({
|
|
3464
|
+
type: z.literal("checkout_status_update"),
|
|
3465
|
+
payload: z
|
|
3466
|
+
.union([
|
|
3467
|
+
CheckoutStatusNotGitSchema,
|
|
3468
|
+
CheckoutStatusGitNonOttoSchema,
|
|
3469
|
+
CheckoutStatusGitOttoSchema,
|
|
3470
|
+
])
|
|
3471
|
+
.and(CheckoutStatusUpdateMetadataSchema),
|
|
3472
|
+
});
|
|
3473
|
+
const CheckoutDiffSubscriptionPayloadSchema = z.object({
|
|
3474
|
+
subscriptionId: z.string(),
|
|
3475
|
+
cwd: z.string(),
|
|
3476
|
+
files: z.array(ParsedDiffFileSchema),
|
|
3477
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3478
|
+
});
|
|
3479
|
+
export const SubscribeCheckoutDiffResponseSchema = z.object({
|
|
3480
|
+
type: z.literal("subscribe_checkout_diff_response"),
|
|
3481
|
+
payload: CheckoutDiffSubscriptionPayloadSchema.extend({
|
|
3482
|
+
requestId: z.string(),
|
|
3483
|
+
}),
|
|
3484
|
+
});
|
|
3485
|
+
export const CheckoutDiffUpdateSchema = z.object({
|
|
3486
|
+
type: z.literal("checkout_diff_update"),
|
|
3487
|
+
payload: CheckoutDiffSubscriptionPayloadSchema,
|
|
3488
|
+
});
|
|
3489
|
+
export const CheckoutCommitResponseSchema = z.object({
|
|
3490
|
+
type: z.literal("checkout_commit_response"),
|
|
3491
|
+
payload: z.object({
|
|
3492
|
+
cwd: z.string(),
|
|
3493
|
+
success: z.boolean(),
|
|
3494
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3495
|
+
requestId: z.string(),
|
|
3496
|
+
}),
|
|
3497
|
+
});
|
|
3498
|
+
export const CheckoutMergeResponseSchema = z.object({
|
|
3499
|
+
type: z.literal("checkout_merge_response"),
|
|
3500
|
+
payload: z.object({
|
|
3501
|
+
cwd: z.string(),
|
|
3502
|
+
success: z.boolean(),
|
|
3503
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3504
|
+
requestId: z.string(),
|
|
3505
|
+
}),
|
|
3506
|
+
});
|
|
3507
|
+
export const CheckoutMergeFromBaseResponseSchema = z.object({
|
|
3508
|
+
type: z.literal("checkout_merge_from_base_response"),
|
|
3509
|
+
payload: z.object({
|
|
3510
|
+
cwd: z.string(),
|
|
3511
|
+
success: z.boolean(),
|
|
3512
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3513
|
+
requestId: z.string(),
|
|
3514
|
+
}),
|
|
3515
|
+
});
|
|
3516
|
+
export const CheckoutPullResponseSchema = z.object({
|
|
3517
|
+
type: z.literal("checkout_pull_response"),
|
|
3518
|
+
payload: z.object({
|
|
3519
|
+
cwd: z.string(),
|
|
3520
|
+
success: z.boolean(),
|
|
3521
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3522
|
+
requestId: z.string(),
|
|
3523
|
+
}),
|
|
3524
|
+
});
|
|
3525
|
+
export const CheckoutPushResponseSchema = z.object({
|
|
3526
|
+
type: z.literal("checkout_push_response"),
|
|
3527
|
+
payload: z.object({
|
|
3528
|
+
cwd: z.string(),
|
|
3529
|
+
success: z.boolean(),
|
|
3530
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3531
|
+
requestId: z.string(),
|
|
3532
|
+
}),
|
|
3533
|
+
});
|
|
3534
|
+
export const CheckoutRefreshResponseSchema = z.object({
|
|
3535
|
+
type: z.literal("checkout.refresh.response"),
|
|
3536
|
+
payload: z.object({
|
|
3537
|
+
cwd: z.string(),
|
|
3538
|
+
success: z.boolean(),
|
|
3539
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3540
|
+
requestId: z.string(),
|
|
3541
|
+
}),
|
|
3542
|
+
});
|
|
3543
|
+
export const CheckoutPrCreateResponseSchema = z.object({
|
|
3544
|
+
type: z.literal("checkout_pr_create_response"),
|
|
3545
|
+
payload: z.object({
|
|
3546
|
+
cwd: z.string(),
|
|
3547
|
+
url: z.string().nullable(),
|
|
3548
|
+
number: z.number().nullable(),
|
|
3549
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3550
|
+
requestId: z.string(),
|
|
3551
|
+
}),
|
|
3552
|
+
});
|
|
3553
|
+
export const CheckoutPrMergeResponseSchema = z.object({
|
|
3554
|
+
type: z.literal("checkout_pr_merge_response"),
|
|
3555
|
+
payload: z.object({
|
|
3556
|
+
cwd: z.string(),
|
|
3557
|
+
success: z.boolean(),
|
|
3558
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3559
|
+
requestId: z.string(),
|
|
3560
|
+
}),
|
|
3561
|
+
});
|
|
3562
|
+
export const CheckoutGithubSetAutoMergeResponseSchema = z.object({
|
|
3563
|
+
type: z.literal("checkout.github.set_auto_merge.response"),
|
|
3564
|
+
payload: z.object({
|
|
3565
|
+
cwd: z.string(),
|
|
3566
|
+
enabled: z.boolean(),
|
|
3567
|
+
success: z.boolean(),
|
|
3568
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3569
|
+
requestId: z.string(),
|
|
3570
|
+
}),
|
|
3571
|
+
});
|
|
3572
|
+
export const PreviewConfiguredServerSchema = z.object({
|
|
3573
|
+
name: z.string(),
|
|
3574
|
+
port: z.number().int().positive(),
|
|
3575
|
+
});
|
|
3576
|
+
export const PreviewServerStatusSchema = z.enum(["starting", "running", "exited"]);
|
|
3577
|
+
export const PreviewRunningServerSchema = z.object({
|
|
3578
|
+
serverId: z.string(),
|
|
3579
|
+
name: z.string(),
|
|
3580
|
+
url: z.string(),
|
|
3581
|
+
port: z.number().int().positive(),
|
|
3582
|
+
status: PreviewServerStatusSchema,
|
|
3583
|
+
});
|
|
3584
|
+
export const PreviewListConfigResponseSchema = z.object({
|
|
3585
|
+
type: z.literal("preview.list_config.response"),
|
|
3586
|
+
payload: z.object({
|
|
3587
|
+
cwd: z.string(),
|
|
3588
|
+
configured: z.boolean(),
|
|
3589
|
+
servers: z.array(PreviewConfiguredServerSchema),
|
|
3590
|
+
runningServers: z.array(PreviewRunningServerSchema).optional(),
|
|
3591
|
+
error: z.string().nullable(),
|
|
3592
|
+
requestId: z.string(),
|
|
3593
|
+
}),
|
|
3594
|
+
});
|
|
3595
|
+
// Preview servers the daemon did not spawn (port-probed from launch.json, e.g.
|
|
3596
|
+
// a dev server the user started by hand) are addressed by an "ext:<port>" id.
|
|
3597
|
+
// Stopping one tree-kills whatever process owns the port, so bulk cleanup paths
|
|
3598
|
+
// must skip external servers and only explicit user action may stop them.
|
|
3599
|
+
export const EXTERNAL_PREVIEW_SERVER_ID_PREFIX = "ext:";
|
|
3600
|
+
export function isExternalPreviewServerId(serverId) {
|
|
3601
|
+
return serverId.startsWith(EXTERNAL_PREVIEW_SERVER_ID_PREFIX);
|
|
3602
|
+
}
|
|
3603
|
+
export const PreviewServerSummaryPayloadSchema = z.object({
|
|
3604
|
+
serverId: z.string(),
|
|
3605
|
+
name: z.string(),
|
|
3606
|
+
url: z.string(),
|
|
3607
|
+
port: z.number().int().positive(),
|
|
3608
|
+
status: z.enum(["starting", "running", "exited"]),
|
|
3609
|
+
boundBrowserId: z.string().nullable(),
|
|
3610
|
+
});
|
|
3611
|
+
export const PreviewStartResponseSchema = z.object({
|
|
3612
|
+
type: z.literal("preview.start.response"),
|
|
3613
|
+
payload: z.object({
|
|
3614
|
+
cwd: z.string(),
|
|
3615
|
+
success: z.boolean(),
|
|
3616
|
+
server: PreviewServerSummaryPayloadSchema.nullable(),
|
|
3617
|
+
reused: z.boolean(),
|
|
3618
|
+
error: z.string().nullable(),
|
|
3619
|
+
requestId: z.string(),
|
|
3620
|
+
}),
|
|
3621
|
+
});
|
|
3622
|
+
export const PreviewBindTabResponseSchema = z.object({
|
|
3623
|
+
type: z.literal("preview.bind_tab.response"),
|
|
3624
|
+
payload: z.object({
|
|
3625
|
+
success: z.boolean(),
|
|
3626
|
+
error: z.string().nullable(),
|
|
3627
|
+
requestId: z.string(),
|
|
3628
|
+
}),
|
|
3629
|
+
});
|
|
3630
|
+
export const PreviewStopResponseSchema = z.object({
|
|
3631
|
+
type: z.literal("preview.stop.response"),
|
|
3632
|
+
payload: z.object({
|
|
3633
|
+
success: z.boolean(),
|
|
3634
|
+
error: z.string().nullable(),
|
|
3635
|
+
requestId: z.string(),
|
|
3636
|
+
}),
|
|
3637
|
+
});
|
|
3638
|
+
const CheckoutGithubCheckAnnotationSchema = z.object({
|
|
3639
|
+
path: z.string().optional(),
|
|
3640
|
+
startLine: z.number().optional(),
|
|
3641
|
+
endLine: z.number().optional(),
|
|
3642
|
+
annotationLevel: z.string().optional(),
|
|
3643
|
+
message: z.string().optional(),
|
|
3644
|
+
title: z.string().optional(),
|
|
3645
|
+
rawDetails: z.string().optional(),
|
|
3646
|
+
});
|
|
3647
|
+
const CheckoutGithubCheckJobSchema = z.object({
|
|
3648
|
+
jobId: z.number(),
|
|
3649
|
+
name: z.string(),
|
|
3650
|
+
status: z.string().nullable().optional(),
|
|
3651
|
+
conclusion: z.string().nullable().optional(),
|
|
3652
|
+
url: z.string().nullable().optional(),
|
|
3653
|
+
logTail: z.string().optional(),
|
|
3654
|
+
logTruncated: z.boolean().optional(),
|
|
3655
|
+
});
|
|
3656
|
+
export const CheckoutGithubCheckDetailsSchema = z.object({
|
|
3657
|
+
checkRunId: z.number(),
|
|
3658
|
+
workflowRunId: z.number().nullable().optional(),
|
|
3659
|
+
name: z.string(),
|
|
3660
|
+
status: z.string().nullable().optional(),
|
|
3661
|
+
conclusion: z.string().nullable().optional(),
|
|
3662
|
+
url: z.string().nullable().optional(),
|
|
3663
|
+
detailsUrl: z.string().nullable().optional(),
|
|
3664
|
+
output: z
|
|
3665
|
+
.object({
|
|
3666
|
+
title: z.string().nullable().optional(),
|
|
3667
|
+
summary: z.string().nullable().optional(),
|
|
3668
|
+
text: z.string().nullable().optional(),
|
|
3669
|
+
})
|
|
3670
|
+
.nullable()
|
|
3671
|
+
.optional(),
|
|
3672
|
+
annotations: z.array(CheckoutGithubCheckAnnotationSchema).optional().default([]),
|
|
3673
|
+
failedJobs: z.array(CheckoutGithubCheckJobSchema).optional().default([]),
|
|
3674
|
+
truncated: z.boolean().optional().default(false),
|
|
3675
|
+
});
|
|
3676
|
+
export const CheckoutGithubGetCheckDetailsResponseSchema = z.object({
|
|
3677
|
+
type: z.literal("checkout.github.get_check_details.response"),
|
|
3678
|
+
payload: z.object({
|
|
3679
|
+
cwd: z.string(),
|
|
3680
|
+
success: z.boolean(),
|
|
3681
|
+
details: CheckoutGithubCheckDetailsSchema.nullable().optional().default(null),
|
|
3682
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3683
|
+
requestId: z.string(),
|
|
3684
|
+
}),
|
|
3685
|
+
});
|
|
3686
|
+
export const CheckoutPrStatusResponseSchema = z.object({
|
|
3687
|
+
type: z.literal("checkout_pr_status_response"),
|
|
3688
|
+
payload: CheckoutPrStatusPayloadSchema,
|
|
3689
|
+
});
|
|
3690
|
+
const PullRequestTimelineKnownErrorSchema = z.discriminatedUnion("kind", [
|
|
3691
|
+
z.object({
|
|
3692
|
+
kind: z.literal("not_found"),
|
|
3693
|
+
message: z.string().optional().default(""),
|
|
3694
|
+
}),
|
|
3695
|
+
z.object({
|
|
3696
|
+
kind: z.literal("forbidden"),
|
|
3697
|
+
message: z.string().optional().default(""),
|
|
3698
|
+
}),
|
|
3699
|
+
z.object({
|
|
3700
|
+
kind: z.literal("unknown"),
|
|
3701
|
+
message: z.string().optional().default(""),
|
|
3702
|
+
}),
|
|
3703
|
+
]);
|
|
3704
|
+
const PullRequestTimelineErrorSchema = z.preprocess((value) => {
|
|
3705
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3706
|
+
return { kind: "unknown", message: "" };
|
|
3707
|
+
}
|
|
3708
|
+
const error = value;
|
|
3709
|
+
if (error.kind === "not_found" || error.kind === "forbidden" || error.kind === "unknown") {
|
|
3710
|
+
return error;
|
|
3711
|
+
}
|
|
3712
|
+
return { ...error, kind: "unknown" };
|
|
3713
|
+
}, PullRequestTimelineKnownErrorSchema);
|
|
3714
|
+
const PullRequestTimelineReviewItemSchema = z.object({
|
|
3715
|
+
id: z.string().optional().default(""),
|
|
3716
|
+
kind: z.literal("review"),
|
|
3717
|
+
author: z.string().optional().default("unknown"),
|
|
3718
|
+
authorUrl: z.string().nullable().optional(),
|
|
3719
|
+
avatarUrl: z.string().nullable().optional(),
|
|
3720
|
+
body: z.string().optional().default(""),
|
|
3721
|
+
createdAt: z.number().optional().default(0),
|
|
3722
|
+
url: z.string().optional().default(""),
|
|
3723
|
+
reviewState: z
|
|
3724
|
+
.enum(["approved", "changes_requested", "commented"])
|
|
3725
|
+
.optional()
|
|
3726
|
+
.default("commented"),
|
|
3727
|
+
});
|
|
3728
|
+
const PullRequestTimelineCommentItemSchema = z.object({
|
|
3729
|
+
id: z.string().optional().default(""),
|
|
3730
|
+
kind: z.literal("comment"),
|
|
3731
|
+
author: z.string().optional().default("unknown"),
|
|
3732
|
+
authorUrl: z.string().nullable().optional(),
|
|
3733
|
+
avatarUrl: z.string().nullable().optional(),
|
|
3734
|
+
body: z.string().optional().default(""),
|
|
3735
|
+
createdAt: z.number().optional().default(0),
|
|
3736
|
+
url: z.string().optional().default(""),
|
|
3737
|
+
// GitHub review id this inline comment belongs to; lets clients nest review
|
|
3738
|
+
// threads under their parent review. Absent on issue comments and on
|
|
3739
|
+
// timelines from daemons that predate the field.
|
|
3740
|
+
reviewId: z.string().optional(),
|
|
3741
|
+
location: z
|
|
3742
|
+
.object({
|
|
3743
|
+
path: z.string(),
|
|
3744
|
+
line: z.number().optional(),
|
|
3745
|
+
startLine: z.number().optional(),
|
|
3746
|
+
threadId: z.string().optional(),
|
|
3747
|
+
isResolved: z.boolean().optional(),
|
|
3748
|
+
isOutdated: z.boolean().optional(),
|
|
3749
|
+
})
|
|
3750
|
+
.optional(),
|
|
3751
|
+
});
|
|
3752
|
+
export const PullRequestTimelineItemSchema = z.preprocess((value) => {
|
|
3753
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
3754
|
+
return value;
|
|
3755
|
+
}
|
|
3756
|
+
const item = value;
|
|
3757
|
+
if (item.kind === "review" || item.kind === "comment") {
|
|
3758
|
+
return item;
|
|
3759
|
+
}
|
|
3760
|
+
return { ...item, kind: "comment" };
|
|
3761
|
+
}, z.discriminatedUnion("kind", [
|
|
3762
|
+
PullRequestTimelineReviewItemSchema,
|
|
3763
|
+
PullRequestTimelineCommentItemSchema,
|
|
3764
|
+
]));
|
|
3765
|
+
export const PullRequestTimelineResponseSchema = z.object({
|
|
3766
|
+
type: z.literal("pull_request_timeline_response"),
|
|
3767
|
+
payload: z
|
|
3768
|
+
.object({
|
|
3769
|
+
cwd: z.string().optional().default(""),
|
|
3770
|
+
prNumber: z.number().nullable().optional().default(null),
|
|
3771
|
+
items: z.array(PullRequestTimelineItemSchema).optional().default([]),
|
|
3772
|
+
truncated: z.boolean().optional().default(false),
|
|
3773
|
+
error: PullRequestTimelineErrorSchema.nullable().optional().default(null),
|
|
3774
|
+
requestId: z.string().optional().default(""),
|
|
3775
|
+
githubFeaturesEnabled: z.boolean().optional().default(true),
|
|
3776
|
+
})
|
|
3777
|
+
.optional()
|
|
3778
|
+
.prefault({}),
|
|
3779
|
+
});
|
|
3780
|
+
export const CheckoutSwitchBranchResponseSchema = z.object({
|
|
3781
|
+
type: z.literal("checkout_switch_branch_response"),
|
|
3782
|
+
payload: z.object({
|
|
3783
|
+
cwd: z.string(),
|
|
3784
|
+
success: z.boolean(),
|
|
3785
|
+
branch: z.string(),
|
|
3786
|
+
source: z.enum(["local", "remote"]).optional(),
|
|
3787
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3788
|
+
requestId: z.string(),
|
|
3789
|
+
}),
|
|
3790
|
+
});
|
|
3791
|
+
export const CheckoutRenameBranchResponseSchema = z.object({
|
|
3792
|
+
type: z.literal("checkout.rename_branch.response"),
|
|
3793
|
+
payload: z.object({
|
|
3794
|
+
requestId: z.string(),
|
|
3795
|
+
success: z.boolean(),
|
|
3796
|
+
cwd: z.string(),
|
|
3797
|
+
currentBranch: z.string().nullable(),
|
|
3798
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3799
|
+
}),
|
|
3800
|
+
});
|
|
3801
|
+
const StashEntrySchema = z.object({
|
|
3802
|
+
index: z.number().int().min(0),
|
|
3803
|
+
message: z.string(),
|
|
3804
|
+
branch: z.string().nullable(),
|
|
3805
|
+
isOtto: z.boolean(),
|
|
3806
|
+
});
|
|
3807
|
+
export const StashSaveResponseSchema = z.object({
|
|
3808
|
+
type: z.literal("stash_save_response"),
|
|
3809
|
+
payload: z.object({
|
|
3810
|
+
cwd: z.string(),
|
|
3811
|
+
success: z.boolean(),
|
|
3812
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3813
|
+
requestId: z.string(),
|
|
3814
|
+
}),
|
|
3815
|
+
});
|
|
3816
|
+
export const StashPopResponseSchema = z.object({
|
|
3817
|
+
type: z.literal("stash_pop_response"),
|
|
3818
|
+
payload: z.object({
|
|
3819
|
+
cwd: z.string(),
|
|
3820
|
+
success: z.boolean(),
|
|
3821
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3822
|
+
requestId: z.string(),
|
|
3823
|
+
}),
|
|
3824
|
+
});
|
|
3825
|
+
export const StashListResponseSchema = z.object({
|
|
3826
|
+
type: z.literal("stash_list_response"),
|
|
3827
|
+
payload: z.object({
|
|
3828
|
+
cwd: z.string(),
|
|
3829
|
+
entries: z.array(StashEntrySchema),
|
|
3830
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3831
|
+
requestId: z.string(),
|
|
3832
|
+
}),
|
|
3833
|
+
});
|
|
3834
|
+
export const ValidateBranchResponseSchema = z.object({
|
|
3835
|
+
type: z.literal("validate_branch_response"),
|
|
3836
|
+
payload: z.object({
|
|
3837
|
+
exists: z.boolean(),
|
|
3838
|
+
resolvedRef: z.string().nullable(),
|
|
3839
|
+
isRemote: z.boolean(),
|
|
3840
|
+
error: z.string().nullable(),
|
|
3841
|
+
requestId: z.string(),
|
|
3842
|
+
}),
|
|
3843
|
+
});
|
|
3844
|
+
export const BranchSuggestionsResponseSchema = z.object({
|
|
3845
|
+
type: z.literal("branch_suggestions_response"),
|
|
3846
|
+
payload: z.object({
|
|
3847
|
+
branches: z.array(z.string()),
|
|
3848
|
+
branchDetails: z
|
|
3849
|
+
.array(z.object({
|
|
3850
|
+
name: z.string(),
|
|
3851
|
+
committerDate: z.number(),
|
|
3852
|
+
hasLocal: z.boolean().optional(),
|
|
3853
|
+
hasRemote: z.boolean().optional(),
|
|
3854
|
+
}))
|
|
3855
|
+
.optional(),
|
|
3856
|
+
error: z.string().nullable(),
|
|
3857
|
+
requestId: z.string(),
|
|
3858
|
+
}),
|
|
3859
|
+
});
|
|
3860
|
+
export const GitHubSearchResponseSchema = z.object({
|
|
3861
|
+
type: z.literal("github_search_response"),
|
|
3862
|
+
payload: z.object({
|
|
3863
|
+
items: z.array(GitHubSearchItemSchema),
|
|
3864
|
+
githubFeaturesEnabled: z.boolean(),
|
|
3865
|
+
error: z.string().nullable(),
|
|
3866
|
+
requestId: z.string(),
|
|
3867
|
+
}),
|
|
3868
|
+
});
|
|
3869
|
+
export const HostingSearchResponseSchema = z.object({
|
|
3870
|
+
type: z.literal("hosting.search.response"),
|
|
3871
|
+
payload: z.object({
|
|
3872
|
+
items: z.array(GitHubSearchItemSchema),
|
|
3873
|
+
provider: GitHostingProviderIdWireSchema,
|
|
3874
|
+
featuresEnabled: z.boolean(),
|
|
3875
|
+
error: z.string().nullable(),
|
|
3876
|
+
requestId: z.string(),
|
|
3877
|
+
}),
|
|
3878
|
+
});
|
|
3879
|
+
export const HostingAuthStatusResponseSchema = z.object({
|
|
3880
|
+
type: z.literal("hosting.auth_status.response"),
|
|
3881
|
+
payload: z.object({
|
|
3882
|
+
provider: GitHostingProviderIdWireSchema,
|
|
3883
|
+
authenticated: z.boolean(),
|
|
3884
|
+
error: z.string().nullable(),
|
|
3885
|
+
requestId: z.string(),
|
|
3886
|
+
}),
|
|
3887
|
+
});
|
|
3888
|
+
export const DirectorySuggestionsResponseSchema = z.object({
|
|
3889
|
+
type: z.literal("directory_suggestions_response"),
|
|
3890
|
+
payload: z.object({
|
|
3891
|
+
directories: z.array(z.string()),
|
|
3892
|
+
entries: z
|
|
3893
|
+
.array(z.object({
|
|
3894
|
+
path: z.string(),
|
|
3895
|
+
kind: z.enum(["file", "directory"]),
|
|
3896
|
+
}))
|
|
3897
|
+
.optional()
|
|
3898
|
+
.default([]),
|
|
3899
|
+
error: z.string().nullable(),
|
|
3900
|
+
requestId: z.string(),
|
|
3901
|
+
}),
|
|
3902
|
+
});
|
|
3903
|
+
const OttoWorktreeSchema = z.object({
|
|
3904
|
+
worktreePath: z.string(),
|
|
3905
|
+
createdAt: z.string(),
|
|
3906
|
+
branchName: z.string().nullable().optional(),
|
|
3907
|
+
head: z.string().nullable().optional(),
|
|
3908
|
+
});
|
|
3909
|
+
export const OttoWorktreeListResponseSchema = z.object({
|
|
3910
|
+
type: z.literal("otto_worktree_list_response"),
|
|
3911
|
+
payload: z.object({
|
|
3912
|
+
worktrees: z.array(OttoWorktreeSchema),
|
|
3913
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3914
|
+
requestId: z.string(),
|
|
3915
|
+
}),
|
|
3916
|
+
});
|
|
3917
|
+
export const OttoWorktreeArchiveResponseSchema = z.object({
|
|
3918
|
+
type: z.literal("otto_worktree_archive_response"),
|
|
3919
|
+
payload: z.object({
|
|
3920
|
+
success: z.boolean(),
|
|
3921
|
+
removedAgents: z.array(z.string()).optional(),
|
|
3922
|
+
error: CheckoutErrorSchema.nullable(),
|
|
3923
|
+
requestId: z.string(),
|
|
3924
|
+
}),
|
|
3925
|
+
});
|
|
3926
|
+
export const CreateOttoWorktreeResponseSchema = z.object({
|
|
3927
|
+
type: z.literal("create_otto_worktree_response"),
|
|
3928
|
+
payload: z.object({
|
|
3929
|
+
workspace: WorkspaceDescriptorPayloadSchema.nullable(),
|
|
3930
|
+
error: z.string().nullable(),
|
|
3931
|
+
errorCode: z.string().optional(),
|
|
3932
|
+
setupTerminalId: z.string().nullable(),
|
|
3933
|
+
requestId: z.string(),
|
|
3934
|
+
}),
|
|
3935
|
+
});
|
|
3936
|
+
export const FileExplorerResponseSchema = z.object({
|
|
3937
|
+
type: z.literal("file_explorer_response"),
|
|
3938
|
+
payload: z.object({
|
|
3939
|
+
cwd: z.string(),
|
|
3940
|
+
path: z.string(),
|
|
3941
|
+
mode: z.enum(["list", "file"]),
|
|
3942
|
+
directory: FileExplorerDirectorySchema.nullable(),
|
|
3943
|
+
file: FileExplorerFileSchema.nullable(),
|
|
3944
|
+
error: z.string().nullable(),
|
|
3945
|
+
requestId: z.string(),
|
|
3946
|
+
}),
|
|
3947
|
+
});
|
|
3948
|
+
const ProjectIconSchema = z.object({
|
|
3949
|
+
data: z.string(),
|
|
3950
|
+
mimeType: z.string(),
|
|
3951
|
+
});
|
|
3952
|
+
export const ProjectIconResponseSchema = z.object({
|
|
3953
|
+
type: z.literal("project_icon_response"),
|
|
3954
|
+
payload: z.object({
|
|
3955
|
+
cwd: z.string(),
|
|
3956
|
+
icon: ProjectIconSchema.nullable(),
|
|
3957
|
+
error: z.string().nullable(),
|
|
3958
|
+
requestId: z.string(),
|
|
3959
|
+
}),
|
|
3960
|
+
});
|
|
3961
|
+
export const FileDownloadTokenResponseSchema = z.object({
|
|
3962
|
+
type: z.literal("file_download_token_response"),
|
|
3963
|
+
payload: z.object({
|
|
3964
|
+
cwd: z.string(),
|
|
3965
|
+
path: z.string(),
|
|
3966
|
+
token: z.string().nullable(),
|
|
3967
|
+
fileName: z.string().nullable(),
|
|
3968
|
+
mimeType: z.string().nullable(),
|
|
3969
|
+
size: z.number().nullable(),
|
|
3970
|
+
error: z.string().nullable(),
|
|
3971
|
+
requestId: z.string(),
|
|
3972
|
+
}),
|
|
3973
|
+
});
|
|
3974
|
+
export const FileUploadResponseSchema = z.object({
|
|
3975
|
+
type: z.literal("file.upload.response"),
|
|
3976
|
+
payload: z.object({
|
|
3977
|
+
requestId: z.string(),
|
|
3978
|
+
file: UploadedFileAttachmentSchema.nullable(),
|
|
3979
|
+
error: z.string().nullable(),
|
|
3980
|
+
}),
|
|
3981
|
+
});
|
|
3982
|
+
export const FileWriteResultSchema = z.discriminatedUnion("status", [
|
|
3983
|
+
z.object({
|
|
3984
|
+
status: z.literal("ok"),
|
|
3985
|
+
modifiedAt: z.string(),
|
|
3986
|
+
hash: z.string(),
|
|
3987
|
+
size: z.number(),
|
|
3988
|
+
eol: FileEolSchema,
|
|
3989
|
+
}),
|
|
3990
|
+
// The file on disk is not what the client last saw; nothing was written.
|
|
3991
|
+
// `content` carries the current disk text so the client can offer reload or
|
|
3992
|
+
// an informed overwrite (a second conditional write against this identity)
|
|
3993
|
+
// without another round-trip.
|
|
3994
|
+
z.object({
|
|
3995
|
+
status: z.literal("conflict"),
|
|
3996
|
+
modifiedAt: z.string(),
|
|
3997
|
+
hash: z.string(),
|
|
3998
|
+
content: z.string().optional(),
|
|
3999
|
+
eol: FileEolSchema.optional(),
|
|
4000
|
+
}),
|
|
4001
|
+
z.object({
|
|
4002
|
+
status: z.literal("error"),
|
|
4003
|
+
message: z.string(),
|
|
4004
|
+
}),
|
|
4005
|
+
]);
|
|
4006
|
+
export const FileWriteResponseSchema = z.object({
|
|
4007
|
+
type: z.literal("file.write.response"),
|
|
4008
|
+
payload: z.object({
|
|
4009
|
+
cwd: z.string(),
|
|
4010
|
+
path: z.string(),
|
|
4011
|
+
result: FileWriteResultSchema,
|
|
4012
|
+
requestId: z.string(),
|
|
4013
|
+
}),
|
|
4014
|
+
});
|
|
4015
|
+
export const FileWatchSubscribeResponseSchema = z.object({
|
|
4016
|
+
type: z.literal("file.watch.subscribe.response"),
|
|
4017
|
+
payload: z.object({
|
|
4018
|
+
cwd: z.string(),
|
|
4019
|
+
path: z.string(),
|
|
4020
|
+
ok: z.boolean(),
|
|
4021
|
+
error: z.string().nullable(),
|
|
4022
|
+
requestId: z.string(),
|
|
4023
|
+
}),
|
|
4024
|
+
});
|
|
4025
|
+
export const FileWatchUnsubscribeResponseSchema = z.object({
|
|
4026
|
+
type: z.literal("file.watch.unsubscribe.response"),
|
|
4027
|
+
payload: z.object({
|
|
4028
|
+
cwd: z.string(),
|
|
4029
|
+
path: z.string(),
|
|
4030
|
+
ok: z.boolean(),
|
|
4031
|
+
error: z.string().nullable(),
|
|
4032
|
+
requestId: z.string(),
|
|
4033
|
+
}),
|
|
4034
|
+
});
|
|
4035
|
+
export const CodeListFilesResponseSchema = z.object({
|
|
4036
|
+
type: z.literal("code.list_files.response"),
|
|
4037
|
+
payload: z.object({
|
|
4038
|
+
cwd: z.string(),
|
|
4039
|
+
files: z.array(z.string()),
|
|
4040
|
+
truncated: z.boolean(),
|
|
4041
|
+
error: z.string().nullable(),
|
|
4042
|
+
requestId: z.string(),
|
|
4043
|
+
}),
|
|
4044
|
+
});
|
|
4045
|
+
export const CodeSymbolKindSchema = z.enum(["function", "class", "type", "variable", "property"]);
|
|
4046
|
+
export const CodeSymbolLocationSchema = z.object({
|
|
4047
|
+
path: z.string(),
|
|
4048
|
+
name: z.string(),
|
|
4049
|
+
kind: CodeSymbolKindSchema,
|
|
4050
|
+
line: z.number().int().positive(),
|
|
4051
|
+
column: z.number().int().positive(),
|
|
4052
|
+
});
|
|
4053
|
+
export const CodeSymbolsResponseSchema = z.object({
|
|
4054
|
+
type: z.literal("code.symbols.response"),
|
|
4055
|
+
payload: z.object({
|
|
4056
|
+
cwd: z.string(),
|
|
4057
|
+
name: z.string(),
|
|
4058
|
+
locations: z.array(CodeSymbolLocationSchema),
|
|
4059
|
+
error: z.string().nullable(),
|
|
4060
|
+
requestId: z.string(),
|
|
4061
|
+
}),
|
|
4062
|
+
});
|
|
4063
|
+
export const CodeOutlineResponseSchema = z.object({
|
|
4064
|
+
type: z.literal("code.outline.response"),
|
|
4065
|
+
payload: z.object({
|
|
4066
|
+
cwd: z.string(),
|
|
4067
|
+
path: z.string(),
|
|
4068
|
+
symbols: z.array(CodeSymbolLocationSchema),
|
|
4069
|
+
error: z.string().nullable(),
|
|
4070
|
+
requestId: z.string(),
|
|
4071
|
+
}),
|
|
4072
|
+
});
|
|
4073
|
+
export const FileSearchMatchSchema = z.object({
|
|
4074
|
+
/** 1-based line number. */
|
|
4075
|
+
line: z.number().int().positive(),
|
|
4076
|
+
/** 1-based character column of the match start within the full line. */
|
|
4077
|
+
column: z.number().int().positive(),
|
|
4078
|
+
/** Match length in characters. */
|
|
4079
|
+
length: z.number().int().nonnegative(),
|
|
4080
|
+
/** Display line (possibly truncated around the match). */
|
|
4081
|
+
lineText: z.string(),
|
|
4082
|
+
/** 0-based offset of the match within lineText. */
|
|
4083
|
+
previewStart: z.number().int().nonnegative(),
|
|
4084
|
+
});
|
|
4085
|
+
// One event per file with matches, streamed while the scan runs.
|
|
4086
|
+
export const FileSearchResultEventSchema = z.object({
|
|
4087
|
+
type: z.literal("file.search.result"),
|
|
4088
|
+
payload: z.object({
|
|
4089
|
+
cwd: z.string(),
|
|
4090
|
+
searchId: z.string(),
|
|
4091
|
+
path: z.string(),
|
|
4092
|
+
/** File content hash at match time — the replace precondition. */
|
|
4093
|
+
hash: z.string(),
|
|
4094
|
+
matches: z.array(FileSearchMatchSchema),
|
|
4095
|
+
}),
|
|
4096
|
+
});
|
|
4097
|
+
export const FileSearchResponseSchema = z.object({
|
|
4098
|
+
type: z.literal("file.search.response"),
|
|
4099
|
+
payload: z.object({
|
|
4100
|
+
cwd: z.string(),
|
|
4101
|
+
status: z.enum(["completed", "truncated", "superseded", "error"]),
|
|
4102
|
+
error: z.string().nullable(),
|
|
4103
|
+
fileCount: z.number(),
|
|
4104
|
+
matchCount: z.number(),
|
|
4105
|
+
requestId: z.string(),
|
|
4106
|
+
}),
|
|
4107
|
+
});
|
|
4108
|
+
export const FileReplaceFileResultSchema = z.discriminatedUnion("status", [
|
|
4109
|
+
z.object({
|
|
4110
|
+
status: z.literal("ok"),
|
|
4111
|
+
path: z.string(),
|
|
4112
|
+
replacedCount: z.number(),
|
|
4113
|
+
modifiedAt: z.string(),
|
|
4114
|
+
hash: z.string(),
|
|
4115
|
+
}),
|
|
4116
|
+
// The file changed since the preview; nothing was written to it.
|
|
4117
|
+
z.object({
|
|
4118
|
+
status: z.literal("skipped"),
|
|
4119
|
+
path: z.string(),
|
|
4120
|
+
reason: z.string(),
|
|
4121
|
+
}),
|
|
4122
|
+
z.object({
|
|
4123
|
+
status: z.literal("error"),
|
|
4124
|
+
path: z.string(),
|
|
4125
|
+
message: z.string(),
|
|
4126
|
+
}),
|
|
4127
|
+
]);
|
|
4128
|
+
export const FileReplaceResponseSchema = z.object({
|
|
4129
|
+
type: z.literal("file.replace.response"),
|
|
4130
|
+
payload: z.object({
|
|
4131
|
+
cwd: z.string(),
|
|
4132
|
+
results: z.array(FileReplaceFileResultSchema),
|
|
4133
|
+
error: z.string().nullable(),
|
|
4134
|
+
requestId: z.string(),
|
|
4135
|
+
}),
|
|
4136
|
+
});
|
|
4137
|
+
// Pushed to subscribers when a watched file changes under the editor. Carries
|
|
4138
|
+
// the fresh disk identity (null when the file is gone) so clients can ignore
|
|
4139
|
+
// echoes of their own saves; content is re-read on demand.
|
|
4140
|
+
export const FileWatchEventSchema = z.object({
|
|
4141
|
+
type: z.literal("file.watch.event"),
|
|
4142
|
+
payload: z.object({
|
|
4143
|
+
cwd: z.string(),
|
|
4144
|
+
path: z.string(),
|
|
4145
|
+
change: z.enum(["changed", "deleted", "recreated"]),
|
|
4146
|
+
modifiedAt: z.string().nullable(),
|
|
4147
|
+
hash: z.string().nullable(),
|
|
4148
|
+
size: z.number().nullable(),
|
|
4149
|
+
}),
|
|
4150
|
+
});
|
|
4151
|
+
export const ListProviderModelsResponseMessageSchema = z.object({
|
|
4152
|
+
type: z.literal("list_provider_models_response"),
|
|
4153
|
+
payload: z.object({
|
|
4154
|
+
provider: AgentProviderSchema,
|
|
4155
|
+
models: z.array(AgentModelDefinitionSchema).optional(),
|
|
4156
|
+
error: z.string().nullable().optional(),
|
|
4157
|
+
fetchedAt: z.string(),
|
|
4158
|
+
requestId: z.string(),
|
|
4159
|
+
}),
|
|
4160
|
+
});
|
|
4161
|
+
export const ListProviderModesResponseMessageSchema = z.object({
|
|
4162
|
+
type: z.literal("list_provider_modes_response"),
|
|
4163
|
+
payload: z.object({
|
|
4164
|
+
provider: AgentProviderSchema,
|
|
4165
|
+
modes: z.array(AgentModeSchema).optional(),
|
|
4166
|
+
error: z.string().nullable().optional(),
|
|
4167
|
+
fetchedAt: z.string(),
|
|
4168
|
+
requestId: z.string(),
|
|
4169
|
+
}),
|
|
4170
|
+
});
|
|
4171
|
+
export const ListProviderFeaturesResponseMessageSchema = z.object({
|
|
4172
|
+
type: z.literal("list_provider_features_response"),
|
|
4173
|
+
payload: z.object({
|
|
4174
|
+
provider: AgentProviderSchema,
|
|
4175
|
+
features: z.array(AgentFeatureSchema).optional(),
|
|
4176
|
+
error: z.string().nullable().optional(),
|
|
4177
|
+
fetchedAt: z.string(),
|
|
4178
|
+
requestId: z.string(),
|
|
4179
|
+
}),
|
|
4180
|
+
});
|
|
4181
|
+
const ProviderAvailabilitySchema = z.object({
|
|
4182
|
+
provider: AgentProviderSchema,
|
|
4183
|
+
available: z.boolean(),
|
|
4184
|
+
error: z.string().nullable().optional(),
|
|
4185
|
+
});
|
|
4186
|
+
export const ListAvailableProvidersResponseSchema = z.object({
|
|
4187
|
+
type: z.literal("list_available_providers_response"),
|
|
4188
|
+
payload: z.object({
|
|
4189
|
+
providers: z.array(ProviderAvailabilitySchema),
|
|
4190
|
+
error: z.string().nullable().optional(),
|
|
4191
|
+
fetchedAt: z.string(),
|
|
4192
|
+
requestId: z.string(),
|
|
4193
|
+
}),
|
|
4194
|
+
});
|
|
4195
|
+
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
4196
|
+
export const GetProvidersSnapshotResponseMessageSchema = z.object({
|
|
4197
|
+
type: z.literal("get_providers_snapshot_response"),
|
|
4198
|
+
payload: z.object({
|
|
4199
|
+
entries: z.array(ProviderSnapshotEntrySchema),
|
|
4200
|
+
generatedAt: z.string(),
|
|
4201
|
+
requestId: z.string(),
|
|
4202
|
+
}),
|
|
4203
|
+
});
|
|
4204
|
+
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
4205
|
+
export const ProvidersSnapshotUpdateMessageSchema = z.object({
|
|
4206
|
+
type: z.literal("providers_snapshot_update"),
|
|
4207
|
+
payload: z.object({
|
|
4208
|
+
cwd: z.string().optional(),
|
|
4209
|
+
entries: z.array(ProviderSnapshotEntrySchema),
|
|
4210
|
+
generatedAt: z.string(),
|
|
4211
|
+
}),
|
|
4212
|
+
});
|
|
4213
|
+
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
4214
|
+
export const RefreshProvidersSnapshotResponseMessageSchema = z.object({
|
|
4215
|
+
type: z.literal("refresh_providers_snapshot_response"),
|
|
4216
|
+
payload: z.object({
|
|
4217
|
+
requestId: z.string(),
|
|
4218
|
+
acknowledged: z.boolean(),
|
|
4219
|
+
}),
|
|
4220
|
+
});
|
|
4221
|
+
// COMPAT(providersSnapshot): added in v0.1.48, remove gating when all clients use snapshot
|
|
4222
|
+
export const ProviderDiagnosticResponseMessageSchema = z.object({
|
|
4223
|
+
type: z.literal("provider_diagnostic_response"),
|
|
4224
|
+
payload: z.object({
|
|
4225
|
+
provider: AgentProviderSchema,
|
|
4226
|
+
diagnostic: z.string(),
|
|
4227
|
+
requestId: z.string(),
|
|
4228
|
+
}),
|
|
4229
|
+
});
|
|
4230
|
+
export const ProviderUsageToneSchema = z.enum(["default", "ok", "warning", "danger"]);
|
|
4231
|
+
export const ProviderUsageStatusSchema = z.enum(["available", "unavailable", "error"]);
|
|
4232
|
+
export const ProviderUsageWindowSchema = z.object({
|
|
4233
|
+
id: z.string(),
|
|
4234
|
+
label: z.string(),
|
|
4235
|
+
usedPct: z.number().nullable().optional(),
|
|
4236
|
+
remainingPct: z.number().nullable().optional(),
|
|
4237
|
+
resetsAt: z.string().nullable().optional(),
|
|
4238
|
+
runsOutAt: z.string().nullable().optional(),
|
|
4239
|
+
shortfallPct: z.number().nullable().optional(),
|
|
4240
|
+
tone: ProviderUsageToneSchema.optional(),
|
|
4241
|
+
});
|
|
4242
|
+
export const ProviderUsageBalanceSchema = z.object({
|
|
4243
|
+
id: z.string(),
|
|
4244
|
+
label: z.string(),
|
|
4245
|
+
used: z.number().nullable().optional(),
|
|
4246
|
+
remaining: z.number().nullable().optional(),
|
|
4247
|
+
limit: z.number().nullable().optional(),
|
|
4248
|
+
unit: z.enum(["usd", "credits", "requests", "tokens"]),
|
|
4249
|
+
resetsAt: z.string().nullable().optional(),
|
|
4250
|
+
tone: ProviderUsageToneSchema.optional(),
|
|
4251
|
+
});
|
|
4252
|
+
export const ProviderUsageDetailSchema = z.object({
|
|
4253
|
+
id: z.string(),
|
|
4254
|
+
label: z.string(),
|
|
4255
|
+
value: z.string(),
|
|
4256
|
+
tone: ProviderUsageToneSchema.optional(),
|
|
4257
|
+
});
|
|
4258
|
+
export const ProviderUsageSchema = z.object({
|
|
4259
|
+
providerId: z.string(),
|
|
4260
|
+
displayName: z.string(),
|
|
4261
|
+
status: ProviderUsageStatusSchema,
|
|
4262
|
+
planLabel: z.string().nullable(),
|
|
4263
|
+
sourceLabel: z.string().nullable().optional(),
|
|
4264
|
+
fetchedAt: z.string().nullable().optional(),
|
|
4265
|
+
nextRefreshAt: z.string().nullable().optional(),
|
|
4266
|
+
windows: z.array(ProviderUsageWindowSchema),
|
|
4267
|
+
balances: z.array(ProviderUsageBalanceSchema).optional(),
|
|
4268
|
+
details: z.array(ProviderUsageDetailSchema).optional(),
|
|
4269
|
+
error: z.string().nullable().optional(),
|
|
4270
|
+
});
|
|
4271
|
+
export const ProviderUsageListResponseMessageSchema = z.object({
|
|
4272
|
+
type: z.literal("provider.usage.list.response"),
|
|
4273
|
+
payload: z.object({
|
|
4274
|
+
requestId: z.string(),
|
|
4275
|
+
fetchedAt: z.string(),
|
|
4276
|
+
providers: z.array(ProviderUsageSchema),
|
|
4277
|
+
}),
|
|
4278
|
+
});
|
|
4279
|
+
export const AgentContextUsageCategorySchema = z.object({
|
|
4280
|
+
/** Provider-supplied display label, e.g. "Messages", "System prompt". Not translated. */
|
|
4281
|
+
name: z.string(),
|
|
4282
|
+
tokens: z.number(),
|
|
4283
|
+
/** Deferred content (e.g. on-demand tool schemas) is not counted in totalTokens. */
|
|
4284
|
+
isDeferred: z.boolean().optional(),
|
|
4285
|
+
});
|
|
4286
|
+
export const AgentContextUsageSchema = z.object({
|
|
4287
|
+
categories: z.array(AgentContextUsageCategorySchema),
|
|
4288
|
+
totalTokens: z.number(),
|
|
4289
|
+
maxTokens: z.number(),
|
|
4290
|
+
});
|
|
4291
|
+
export const AgentContextGetUsageResponseMessageSchema = z.object({
|
|
4292
|
+
type: z.literal("agent.context.get_usage.response"),
|
|
4293
|
+
payload: z.object({
|
|
4294
|
+
requestId: z.string(),
|
|
4295
|
+
agentId: z.string(),
|
|
4296
|
+
/** Null when the agent's provider cannot report a context breakdown. */
|
|
4297
|
+
usage: AgentContextUsageSchema.nullable(),
|
|
4298
|
+
}),
|
|
4299
|
+
});
|
|
4300
|
+
const AgentSlashCommandSchema = z.object({
|
|
4301
|
+
name: z.string(),
|
|
4302
|
+
description: z.string(),
|
|
4303
|
+
argumentHint: z.string(),
|
|
4304
|
+
kind: z.enum(["command", "skill"]).optional().catch("command"),
|
|
4305
|
+
});
|
|
4306
|
+
export const ListCommandsResponseSchema = z.object({
|
|
4307
|
+
type: z.literal("list_commands_response"),
|
|
4308
|
+
payload: z.object({
|
|
4309
|
+
agentId: z.string(),
|
|
4310
|
+
commands: z.array(AgentSlashCommandSchema),
|
|
4311
|
+
error: z.string().nullable(),
|
|
4312
|
+
requestId: z.string(),
|
|
4313
|
+
}),
|
|
4314
|
+
});
|
|
4315
|
+
// ============================================================================
|
|
4316
|
+
// Terminal Outbound Messages
|
|
4317
|
+
// ============================================================================
|
|
4318
|
+
const TerminalInfoSchema = z.object({
|
|
4319
|
+
id: z.string(),
|
|
4320
|
+
name: z.string(),
|
|
4321
|
+
cwd: z.string(),
|
|
4322
|
+
workspaceId: z.string().optional(),
|
|
4323
|
+
title: z.string().optional(),
|
|
4324
|
+
activity: TerminalActivitySchema.nullable().optional(),
|
|
4325
|
+
});
|
|
4326
|
+
export const TerminalCellSchema = z.object({
|
|
4327
|
+
char: z.string(),
|
|
4328
|
+
fg: z.number().optional(),
|
|
4329
|
+
bg: z.number().optional(),
|
|
4330
|
+
fgMode: z.number().optional(),
|
|
4331
|
+
bgMode: z.number().optional(),
|
|
4332
|
+
bold: z.boolean().optional(),
|
|
4333
|
+
italic: z.boolean().optional(),
|
|
4334
|
+
underline: z.boolean().optional(),
|
|
4335
|
+
dim: z.boolean().optional(),
|
|
4336
|
+
inverse: z.boolean().optional(),
|
|
4337
|
+
strikethrough: z.boolean().optional(),
|
|
4338
|
+
});
|
|
4339
|
+
export const TerminalCursorStyleSchema = z.enum(["block", "underline", "bar"]);
|
|
4340
|
+
export const TerminalCursorSchema = z.object({
|
|
4341
|
+
row: z.number(),
|
|
4342
|
+
col: z.number(),
|
|
4343
|
+
hidden: z.boolean().optional(),
|
|
4344
|
+
style: TerminalCursorStyleSchema.optional(),
|
|
4345
|
+
blink: z.boolean().optional(),
|
|
4346
|
+
});
|
|
4347
|
+
export const TerminalStateSchema = z.object({
|
|
4348
|
+
rows: z.number(),
|
|
4349
|
+
cols: z.number(),
|
|
4350
|
+
grid: z.array(z.array(TerminalCellSchema)),
|
|
4351
|
+
scrollback: z.array(z.array(TerminalCellSchema)),
|
|
4352
|
+
cursor: TerminalCursorSchema,
|
|
4353
|
+
title: z.string().optional(),
|
|
4354
|
+
// Per-row soft-wrap flags aligned 1:1 with `grid` / `scrollback`. `true` means
|
|
4355
|
+
// the row continued onto the next row (xterm's GRID_LINE_WRAPPED equivalent),
|
|
4356
|
+
// so the client can re-wrap the logical line on resize instead of freezing it
|
|
4357
|
+
// at the snapshot width. Optional: only sent to clients that advertise the
|
|
4358
|
+
// `terminalReflowableSnapshot` capability, so old daemons/clients are unaffected.
|
|
4359
|
+
gridWrapped: z.array(z.boolean()).optional(),
|
|
4360
|
+
scrollbackWrapped: z.array(z.boolean()).optional(),
|
|
4361
|
+
});
|
|
4362
|
+
export const ListTerminalsResponseSchema = z.object({
|
|
4363
|
+
type: z.literal("list_terminals_response"),
|
|
4364
|
+
payload: z.object({
|
|
4365
|
+
cwd: z.string().optional(),
|
|
4366
|
+
terminals: z.array(TerminalInfoSchema.omit({ cwd: true })),
|
|
4367
|
+
requestId: z.string(),
|
|
4368
|
+
}),
|
|
4369
|
+
});
|
|
4370
|
+
export const TerminalsChangedSchema = z.object({
|
|
4371
|
+
type: z.literal("terminals_changed"),
|
|
4372
|
+
payload: z.object({
|
|
4373
|
+
cwd: z.string(),
|
|
4374
|
+
terminals: z.array(TerminalInfoSchema.omit({ cwd: true })),
|
|
4375
|
+
}),
|
|
4376
|
+
});
|
|
4377
|
+
export const CreateTerminalResponseSchema = z.object({
|
|
4378
|
+
type: z.literal("create_terminal_response"),
|
|
4379
|
+
payload: z.object({
|
|
4380
|
+
terminal: TerminalInfoSchema.nullable(),
|
|
4381
|
+
error: z.string().nullable(),
|
|
4382
|
+
requestId: z.string(),
|
|
4383
|
+
}),
|
|
4384
|
+
});
|
|
4385
|
+
export const RenameTerminalResponseSchema = z.object({
|
|
4386
|
+
type: z.literal("terminal.rename.response"),
|
|
4387
|
+
payload: z.object({
|
|
4388
|
+
requestId: z.string(),
|
|
4389
|
+
success: z.boolean(),
|
|
4390
|
+
error: z.string().nullable(),
|
|
4391
|
+
}),
|
|
4392
|
+
});
|
|
4393
|
+
export const SubscribeTerminalResponseSchema = z.object({
|
|
4394
|
+
type: z.literal("subscribe_terminal_response"),
|
|
4395
|
+
payload: z.union([
|
|
4396
|
+
z.object({
|
|
4397
|
+
terminalId: z.string(),
|
|
4398
|
+
slot: z.number().int().min(0).max(255),
|
|
4399
|
+
error: z.null(),
|
|
4400
|
+
requestId: z.string(),
|
|
4401
|
+
}),
|
|
4402
|
+
z.object({
|
|
4403
|
+
terminalId: z.string(),
|
|
4404
|
+
error: z.string(),
|
|
4405
|
+
requestId: z.string(),
|
|
4406
|
+
}),
|
|
4407
|
+
]),
|
|
4408
|
+
});
|
|
4409
|
+
export const KillTerminalResponseSchema = z.object({
|
|
4410
|
+
type: z.literal("kill_terminal_response"),
|
|
4411
|
+
payload: z.object({
|
|
4412
|
+
terminalId: z.string(),
|
|
4413
|
+
success: z.boolean(),
|
|
4414
|
+
requestId: z.string(),
|
|
4415
|
+
}),
|
|
4416
|
+
});
|
|
4417
|
+
export const CaptureTerminalResponseSchema = z.object({
|
|
4418
|
+
type: z.literal("capture_terminal_response"),
|
|
4419
|
+
payload: z.object({
|
|
4420
|
+
terminalId: z.string(),
|
|
4421
|
+
lines: z.array(z.string()),
|
|
4422
|
+
totalLines: z.number().int().nonnegative(),
|
|
4423
|
+
requestId: z.string(),
|
|
4424
|
+
}),
|
|
4425
|
+
});
|
|
4426
|
+
export const TerminalStreamExitSchema = z.object({
|
|
4427
|
+
type: z.literal("terminal_stream_exit"),
|
|
4428
|
+
payload: z.object({
|
|
4429
|
+
terminalId: z.string(),
|
|
4430
|
+
}),
|
|
4431
|
+
});
|
|
4432
|
+
export const TerminalAttentionRequiredSchema = z.object({
|
|
4433
|
+
type: z.literal("terminal_attention_required"),
|
|
4434
|
+
payload: z.object({
|
|
4435
|
+
serverId: z.string().optional(),
|
|
4436
|
+
terminalId: z.string(),
|
|
4437
|
+
cwd: z.string(),
|
|
4438
|
+
workspaceId: z.string().optional(),
|
|
4439
|
+
reason: z.enum(["finished", "needs_input"]),
|
|
4440
|
+
title: z.string(),
|
|
4441
|
+
body: z.string(),
|
|
4442
|
+
shouldNotify: z.boolean(),
|
|
4443
|
+
}),
|
|
4444
|
+
});
|
|
4445
|
+
export const DaemonUpdateResponseSchema = z.object({
|
|
4446
|
+
type: z.literal("daemon.update.response"),
|
|
4447
|
+
payload: z.object({
|
|
4448
|
+
requestId: z.string(),
|
|
4449
|
+
success: z.boolean(),
|
|
4450
|
+
error: z.string().nullable(),
|
|
4451
|
+
previousVersion: z.string().nullable(),
|
|
4452
|
+
newVersion: z.string().nullable(),
|
|
4453
|
+
}),
|
|
4454
|
+
});
|
|
4455
|
+
export const DaemonUpdateProgressMessageSchema = z.object({
|
|
4456
|
+
type: z.literal("daemon.update.progress"),
|
|
4457
|
+
payload: z.object({
|
|
4458
|
+
requestId: z.string(),
|
|
4459
|
+
phase: z.enum(["starting", "downloading", "installing", "complete"]),
|
|
4460
|
+
}),
|
|
4461
|
+
});
|
|
4462
|
+
export const SessionOutboundMessageSchema = z.discriminatedUnion("type", [
|
|
4463
|
+
BrowserAutomationExecuteRequestSchema,
|
|
4464
|
+
ActivityLogMessageSchema,
|
|
4465
|
+
AssistantChunkMessageSchema,
|
|
4466
|
+
AudioOutputMessageSchema,
|
|
4467
|
+
TranscriptionResultMessageSchema,
|
|
4468
|
+
VoiceInputStateMessageSchema,
|
|
4469
|
+
DictationStreamAckMessageSchema,
|
|
4470
|
+
DictationStreamFinishAcceptedMessageSchema,
|
|
4471
|
+
DictationStreamPartialMessageSchema,
|
|
4472
|
+
DictationStreamFinalMessageSchema,
|
|
4473
|
+
DictationStreamErrorMessageSchema,
|
|
4474
|
+
StatusMessageSchema,
|
|
4475
|
+
PongMessageSchema,
|
|
4476
|
+
RpcErrorMessageSchema,
|
|
4477
|
+
ArtifactMessageSchema,
|
|
4478
|
+
ArtifactUpdateMessageSchema,
|
|
4479
|
+
AgentUpdateMessageSchema,
|
|
4480
|
+
WorkspaceUpdateMessageSchema,
|
|
4481
|
+
ScriptStatusUpdateMessageSchema,
|
|
4482
|
+
WorkspaceSetupProgressMessageSchema,
|
|
4483
|
+
WorkspaceSetupStatusResponseMessageSchema,
|
|
4484
|
+
AgentStreamMessageSchema,
|
|
4485
|
+
AgentStatusMessageSchema,
|
|
4486
|
+
FetchAgentsResponseMessageSchema,
|
|
4487
|
+
FetchAgentHistoryResponseMessageSchema,
|
|
4488
|
+
FetchRecentProviderSessionsResponseMessageSchema,
|
|
4489
|
+
FetchWorkspacesResponseMessageSchema,
|
|
4490
|
+
ProjectAddResponseSchema,
|
|
4491
|
+
OpenProjectResponseMessageSchema,
|
|
4492
|
+
StartWorkspaceScriptResponseMessageSchema,
|
|
4493
|
+
LegacyListAvailableEditorsResponseMessageSchema,
|
|
4494
|
+
LegacyOpenInEditorResponseMessageSchema,
|
|
4495
|
+
ArchiveWorkspaceResponseMessageSchema,
|
|
4496
|
+
FetchAgentResponseMessageSchema,
|
|
4497
|
+
FetchAgentTimelineResponseMessageSchema,
|
|
4498
|
+
AgentForkContextResponseMessageSchema,
|
|
4499
|
+
CancelAgentResponseMessageSchema,
|
|
4500
|
+
ClearAgentAttentionResponseMessageSchema,
|
|
4501
|
+
WorkspaceCreateResponseSchema,
|
|
4502
|
+
WorkspaceClearAttentionResponseSchema,
|
|
4503
|
+
SendAgentMessageResponseMessageSchema,
|
|
4504
|
+
SetVoiceModeResponseMessageSchema,
|
|
4505
|
+
DaemonGetStatusResponseSchema,
|
|
4506
|
+
DaemonGetPairingOfferResponseSchema,
|
|
4507
|
+
DiagnosticsResponseSchema,
|
|
4508
|
+
GetDaemonConfigResponseMessageSchema,
|
|
4509
|
+
SetDaemonConfigResponseMessageSchema,
|
|
4510
|
+
SpeechSettingsGetOptionsResponseSchema,
|
|
4511
|
+
SpeechTtsPreviewResponseSchema,
|
|
4512
|
+
AgentPersonalitiesGetStatsResponseSchema,
|
|
4513
|
+
ReadProjectConfigResponseMessageSchema,
|
|
4514
|
+
WriteProjectConfigResponseMessageSchema,
|
|
4515
|
+
SetAgentModeResponseMessageSchema,
|
|
4516
|
+
SetAgentModelResponseMessageSchema,
|
|
4517
|
+
SetAgentThinkingResponseMessageSchema,
|
|
4518
|
+
SetAgentFeatureResponseMessageSchema,
|
|
4519
|
+
AgentDetachResponseMessageSchema,
|
|
4520
|
+
AgentSubagentStopResponseMessageSchema,
|
|
4521
|
+
AgentPersonalitySetResponseMessageSchema,
|
|
4522
|
+
AgentRewindResponseMessageSchema,
|
|
4523
|
+
UpdateAgentResponseMessageSchema,
|
|
4524
|
+
ProjectRenameResponseSchema,
|
|
4525
|
+
ProjectRemoveResponseSchema,
|
|
4526
|
+
WorkspaceTitleSetResponseSchema,
|
|
4527
|
+
WaitForFinishResponseMessageSchema,
|
|
4528
|
+
AgentPermissionRequestMessageSchema,
|
|
4529
|
+
AgentPermissionResolvedMessageSchema,
|
|
4530
|
+
AgentDeletedMessageSchema,
|
|
4531
|
+
AgentArchivedMessageSchema,
|
|
4532
|
+
CloseItemsResponseSchema,
|
|
4533
|
+
CheckoutStatusResponseSchema,
|
|
4534
|
+
CheckoutStatusUpdateSchema,
|
|
4535
|
+
SubscribeCheckoutDiffResponseSchema,
|
|
4536
|
+
CheckoutDiffUpdateSchema,
|
|
4537
|
+
CheckoutCommitResponseSchema,
|
|
4538
|
+
CheckoutMergeResponseSchema,
|
|
4539
|
+
CheckoutMergeFromBaseResponseSchema,
|
|
4540
|
+
CheckoutPullResponseSchema,
|
|
4541
|
+
CheckoutPushResponseSchema,
|
|
4542
|
+
CheckoutRefreshResponseSchema,
|
|
4543
|
+
CheckoutPrCreateResponseSchema,
|
|
4544
|
+
CheckoutPrMergeResponseSchema,
|
|
4545
|
+
CheckoutGithubSetAutoMergeResponseSchema,
|
|
4546
|
+
CheckoutGithubGetCheckDetailsResponseSchema,
|
|
4547
|
+
PreviewListConfigResponseSchema,
|
|
4548
|
+
PreviewStartResponseSchema,
|
|
4549
|
+
PreviewBindTabResponseSchema,
|
|
4550
|
+
PreviewStopResponseSchema,
|
|
4551
|
+
CheckoutPrStatusResponseSchema,
|
|
4552
|
+
PullRequestTimelineResponseSchema,
|
|
4553
|
+
CheckoutSwitchBranchResponseSchema,
|
|
4554
|
+
CheckoutRenameBranchResponseSchema,
|
|
4555
|
+
StashSaveResponseSchema,
|
|
4556
|
+
StashPopResponseSchema,
|
|
4557
|
+
StashListResponseSchema,
|
|
4558
|
+
ValidateBranchResponseSchema,
|
|
4559
|
+
BranchSuggestionsResponseSchema,
|
|
4560
|
+
GitHubSearchResponseSchema,
|
|
4561
|
+
HostingSearchResponseSchema,
|
|
4562
|
+
HostingAuthStatusResponseSchema,
|
|
4563
|
+
DirectorySuggestionsResponseSchema,
|
|
4564
|
+
OttoWorktreeListResponseSchema,
|
|
4565
|
+
OttoWorktreeArchiveResponseSchema,
|
|
4566
|
+
CreateOttoWorktreeResponseSchema,
|
|
4567
|
+
FileExplorerResponseSchema,
|
|
4568
|
+
ProjectIconResponseSchema,
|
|
4569
|
+
FileDownloadTokenResponseSchema,
|
|
4570
|
+
FileUploadResponseSchema,
|
|
4571
|
+
FileWriteResponseSchema,
|
|
4572
|
+
FileWatchSubscribeResponseSchema,
|
|
4573
|
+
FileWatchUnsubscribeResponseSchema,
|
|
4574
|
+
FileWatchEventSchema,
|
|
4575
|
+
FileSearchResultEventSchema,
|
|
4576
|
+
FileSearchResponseSchema,
|
|
4577
|
+
FileReplaceResponseSchema,
|
|
4578
|
+
CodeListFilesResponseSchema,
|
|
4579
|
+
CodeSymbolsResponseSchema,
|
|
4580
|
+
CodeOutlineResponseSchema,
|
|
4581
|
+
ListProviderModelsResponseMessageSchema,
|
|
4582
|
+
ListProviderModesResponseMessageSchema,
|
|
4583
|
+
ListProviderFeaturesResponseMessageSchema,
|
|
4584
|
+
ListAvailableProvidersResponseSchema,
|
|
4585
|
+
GetProvidersSnapshotResponseMessageSchema,
|
|
4586
|
+
ProvidersSnapshotUpdateMessageSchema,
|
|
4587
|
+
RefreshProvidersSnapshotResponseMessageSchema,
|
|
4588
|
+
ProviderDiagnosticResponseMessageSchema,
|
|
4589
|
+
ProviderUsageListResponseMessageSchema,
|
|
4590
|
+
AgentContextGetUsageResponseMessageSchema,
|
|
4591
|
+
ListCommandsResponseSchema,
|
|
4592
|
+
ListTerminalsResponseSchema,
|
|
4593
|
+
TerminalsChangedSchema,
|
|
4594
|
+
CreateTerminalResponseSchema,
|
|
4595
|
+
RenameTerminalResponseSchema,
|
|
4596
|
+
SubscribeTerminalResponseSchema,
|
|
4597
|
+
KillTerminalResponseSchema,
|
|
4598
|
+
CaptureTerminalResponseSchema,
|
|
4599
|
+
TerminalStreamExitSchema,
|
|
4600
|
+
TerminalAttentionRequiredSchema,
|
|
4601
|
+
ChatCreateResponseSchema,
|
|
4602
|
+
ChatListResponseSchema,
|
|
4603
|
+
ChatInspectResponseSchema,
|
|
4604
|
+
ChatDeleteResponseSchema,
|
|
4605
|
+
ChatPostResponseSchema,
|
|
4606
|
+
ChatReadResponseSchema,
|
|
4607
|
+
ChatWaitResponseSchema,
|
|
4608
|
+
ScheduleCreateResponseSchema,
|
|
4609
|
+
ScheduleListResponseSchema,
|
|
4610
|
+
ScheduleInspectResponseSchema,
|
|
4611
|
+
ScheduleLogsResponseSchema,
|
|
4612
|
+
SchedulePauseResponseSchema,
|
|
4613
|
+
ScheduleResumeResponseSchema,
|
|
4614
|
+
ScheduleDeleteResponseSchema,
|
|
4615
|
+
ScheduleRunOnceResponseSchema,
|
|
4616
|
+
ScheduleUpdateResponseSchema,
|
|
4617
|
+
LoopRunResponseSchema,
|
|
4618
|
+
LoopListResponseSchema,
|
|
4619
|
+
LoopInspectResponseSchema,
|
|
4620
|
+
LoopLogsResponseSchema,
|
|
4621
|
+
LoopStopResponseSchema,
|
|
4622
|
+
DaemonUpdateProgressMessageSchema,
|
|
4623
|
+
DaemonUpdateResponseSchema,
|
|
4624
|
+
// COMPAT(artifacts): added in v0.4.1, drop the gate when daemon floor >= v0.4.1.
|
|
4625
|
+
ArtifactListResponseSchema,
|
|
4626
|
+
ArtifactCreateResponseSchema,
|
|
4627
|
+
ArtifactUpdateResponseSchema,
|
|
4628
|
+
ArtifactRegenerateResponseSchema,
|
|
4629
|
+
ArtifactCancelResponseSchema,
|
|
4630
|
+
ArtifactDeleteResponseSchema,
|
|
4631
|
+
ArtifactStarResponseSchema,
|
|
4632
|
+
ArtifactGetContentResponseSchema,
|
|
4633
|
+
ArtifactCreatedNotificationSchema,
|
|
4634
|
+
ArtifactUpdatedNotificationSchema,
|
|
4635
|
+
ArtifactDeletedNotificationSchema,
|
|
4636
|
+
]);
|
|
4637
|
+
// ============================================================================
|
|
4638
|
+
// WebSocket Level Messages (wraps session messages)
|
|
4639
|
+
// ============================================================================
|
|
4640
|
+
// WebSocket-only messages (not session messages)
|
|
4641
|
+
export const WSPingMessageSchema = z.object({
|
|
4642
|
+
type: z.literal("ping"),
|
|
4643
|
+
});
|
|
4644
|
+
export const WSPongMessageSchema = z.object({
|
|
4645
|
+
type: z.literal("pong"),
|
|
4646
|
+
});
|
|
4647
|
+
export const WSHelloMessageSchema = z.object({
|
|
4648
|
+
type: z.literal("hello"),
|
|
4649
|
+
clientId: z.string().min(1),
|
|
4650
|
+
clientType: z.enum(["mobile", "browser", "cli", "mcp"]),
|
|
4651
|
+
protocolVersion: z.number().int(),
|
|
4652
|
+
appVersion: z.string().optional(),
|
|
4653
|
+
capabilities: z
|
|
4654
|
+
.object({
|
|
4655
|
+
voice: z.boolean().optional(),
|
|
4656
|
+
pushNotifications: z.boolean().optional(),
|
|
4657
|
+
[CLIENT_CAPS.reasoningMergeEnum]: z.boolean().optional(),
|
|
4658
|
+
[CLIENT_CAPS.customModeIcons]: z.boolean().optional(),
|
|
4659
|
+
[CLIENT_CAPS.terminalReflowableSnapshot]: z.boolean().optional(),
|
|
4660
|
+
[CLIENT_CAPS.browserHost]: BrowserAutomationHostCapabilitySchema.optional(),
|
|
4661
|
+
})
|
|
4662
|
+
.passthrough()
|
|
4663
|
+
.optional(),
|
|
4664
|
+
});
|
|
4665
|
+
export const WSRecordingStateMessageSchema = z.object({
|
|
4666
|
+
type: z.literal("recording_state"),
|
|
4667
|
+
isRecording: z.boolean(),
|
|
4668
|
+
});
|
|
4669
|
+
// Wrapped session message
|
|
4670
|
+
export const WSSessionInboundSchema = z.object({
|
|
4671
|
+
type: z.literal("session"),
|
|
4672
|
+
message: SessionInboundMessageSchema,
|
|
4673
|
+
});
|
|
4674
|
+
export const WSSessionOutboundSchema = z.object({
|
|
4675
|
+
type: z.literal("session"),
|
|
4676
|
+
message: SessionOutboundMessageSchema,
|
|
4677
|
+
});
|
|
4678
|
+
// Complete WebSocket message schemas
|
|
4679
|
+
export const WSInboundMessageSchema = z.discriminatedUnion("type", [
|
|
4680
|
+
WSPingMessageSchema,
|
|
4681
|
+
WSHelloMessageSchema,
|
|
4682
|
+
WSRecordingStateMessageSchema,
|
|
4683
|
+
WSSessionInboundSchema,
|
|
4684
|
+
]);
|
|
4685
|
+
export const WSOutboundMessageSchema = z.discriminatedUnion("type", [
|
|
4686
|
+
WSPongMessageSchema,
|
|
4687
|
+
WSSessionOutboundSchema,
|
|
4688
|
+
]);
|
|
4689
|
+
// ============================================================================
|
|
4690
|
+
// Helper functions for message conversion
|
|
4691
|
+
// ============================================================================
|
|
4692
|
+
/**
|
|
4693
|
+
* Extract session message from WebSocket message
|
|
4694
|
+
* Returns null if message should be handled at WS level only
|
|
4695
|
+
*/
|
|
4696
|
+
export function extractSessionMessage(wsMsg) {
|
|
4697
|
+
if (wsMsg.type === "session") {
|
|
4698
|
+
return wsMsg.message;
|
|
4699
|
+
}
|
|
4700
|
+
// Ping and recording_state are WS-level only
|
|
4701
|
+
return null;
|
|
4702
|
+
}
|
|
4703
|
+
/**
|
|
4704
|
+
* Wrap session message in WebSocket envelope
|
|
4705
|
+
*/
|
|
4706
|
+
export function wrapSessionMessage(sessionMsg) {
|
|
4707
|
+
return {
|
|
4708
|
+
type: "session",
|
|
4709
|
+
message: sessionMsg,
|
|
4710
|
+
};
|
|
4711
|
+
}
|
|
4712
|
+
export function parseServerInfoStatusPayload(payload) {
|
|
4713
|
+
const parsed = ServerInfoStatusPayloadSchema.safeParse(payload);
|
|
4714
|
+
if (!parsed.success) {
|
|
4715
|
+
return null;
|
|
4716
|
+
}
|
|
4717
|
+
return parsed.data;
|
|
4718
|
+
}
|
|
4719
|
+
//# sourceMappingURL=messages.js.map
|