ahp_types/commands.rs
1// Generated from types/*.ts — do not edit.
2//
3// Regenerate with: npm run generate:rust
4
5#![allow(missing_docs)]
6
7#[allow(unused_imports)]
8use crate::common::{AnyValue, JsonObject, StringOrMarkdown, Uri};
9#[allow(unused_imports)]
10use serde::{Deserialize, Serialize};
11#[allow(unused_imports)]
12use serde_repr::{Deserialize_repr, Serialize_repr};
13
14#[allow(unused_imports)]
15use crate::actions::{ActionEnvelope, StateAction};
16#[allow(unused_imports)]
17use crate::state::{
18 AgentSelection, ContentRef, Message, MessageAttachment, ModelSelection, SessionActiveClient,
19 SessionConfigSchema, SessionSummary, SideChatSelection, Snapshot, SnapshotState,
20 TelemetryCapabilities, TerminalClaim, TextRange, Turn,
21};
22
23// ─── Enums ────────────────────────────────────────────────────────────
24
25/// Discriminant for reconnect result types.
26#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
27pub enum ReconnectResultType {
28 #[serde(rename = "replay")]
29 Replay,
30 #[serde(rename = "snapshot")]
31 Snapshot,
32}
33
34/// How a new chat uses its source chat and turn.
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
36pub enum ChatSourceKind {
37 /// Copy source history through the referenced turn into the new chat.
38 #[serde(rename = "fork")]
39 Fork,
40 /// Supply source context without copying it into the new chat's visible history.
41 #[serde(rename = "sideChat")]
42 SideChat,
43}
44
45/// Encoding of fetched content data.
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
47pub enum ContentEncoding {
48 #[serde(rename = "base64")]
49 Base64,
50 #[serde(rename = "utf-8")]
51 Utf8,
52}
53
54/// The kind of completion items being requested.
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
56pub enum CompletionItemKind {
57 /// Completions for the text of a {@link Message} the user is composing.
58 /// Each returned item carries an attachment that gets associated with the
59 /// message when accepted.
60 #[serde(rename = "userMessage")]
61 UserMessage,
62}
63
64/// Discriminant for {@link ResourceResolveResult.type}.
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
66pub enum ResourceType {
67 #[serde(rename = "file")]
68 File,
69 #[serde(rename = "directory")]
70 Directory,
71 #[serde(rename = "symlink")]
72 Symlink,
73}
74
75/// How {@link ResourceWriteParams.data} is placed within the target file.
76///
77/// Each mode interprets {@link ResourceWriteParams.position} differently:
78///
79/// - `truncate` (default): rooted at the **start** of the file. The file is
80/// truncated at `position` (0 by default) and `data` is written from that
81/// offset, so the resulting file is `existing[0..position] + data`. With
82/// `position` omitted this is a full overwrite.
83/// - `append`: rooted at the **end** of the file. `position` counts bytes
84/// backwards from EOF, so `position: 0` (the default) writes at EOF —
85/// POSIX append — and `position: 5` inserts `data` 5 bytes before the
86/// current EOF, shifting those trailing 5 bytes after the inserted region.
87/// The server MUST evaluate the effective EOF and write atomically with
88/// respect to other appenders so concurrent `append` writes do not
89/// clobber each other.
90/// - `insert`: rooted at the **start** of the file. `position` (0 by default)
91/// is the byte offset at which `data` is spliced in; bytes at or after
92/// `position` are shifted right by `data.length`. `insert` always grows
93/// the file — use `truncate` to overwrite bytes in place.
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
95pub enum ResourceWriteMode {
96 #[serde(rename = "truncate")]
97 Truncate,
98 #[serde(rename = "append")]
99 Append,
100 #[serde(rename = "insert")]
101 Insert,
102}
103
104// ─── Command Payloads ─────────────────────────────────────────────────
105
106/// Establishes a new connection and negotiates the protocol version.
107/// This MUST be the first message sent by the client.
108#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
109#[serde(rename_all = "camelCase")]
110pub struct InitializeParams {
111 /// Channel URI this command targets.
112 pub channel: Uri,
113 /// Protocol versions the client is willing to speak, ordered from most
114 /// preferred to least preferred. Each entry is a [SemVer](https://semver.org)
115 /// `MAJOR.MINOR.PATCH` string (e.g. `"0.1.0"`).
116 ///
117 /// The server selects one entry and returns it as `InitializeResult.protocolVersion`.
118 /// If the server cannot speak any of the offered versions, it MUST return
119 /// error code `-32005` (`UnsupportedProtocolVersion`).
120 pub protocol_versions: Vec<String>,
121 /// Unique client identifier
122 pub client_id: String,
123 /// Optional identity of the client implementation (name and version).
124 /// Informational only — see {@link Implementation} for how it may and may not
125 /// be used. Distinct from {@link InitializeParams.clientId | `clientId`},
126 /// which is an opaque per-connection identifier used for reconnection, not a
127 /// human-readable implementation name.
128 #[serde(default, skip_serializing_if = "Option::is_none")]
129 pub client_info: Option<Implementation>,
130 /// URIs to subscribe to during handshake
131 #[serde(default, skip_serializing_if = "Option::is_none")]
132 pub initial_subscriptions: Option<Vec<Uri>>,
133 /// IETF BCP 47 language tag indicating the client's preferred locale
134 /// (e.g. `"en-US"`, `"ja"`). The server SHOULD use this to localise
135 /// user-facing strings such as confirmation option labels.
136 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub locale: Option<String>,
138 /// Optional client capability declarations.
139 ///
140 /// Servers SHOULD only advertise features whose corresponding client
141 /// capability is set here. Absent means "not declared" — the server
142 /// MUST assume the client does not support the feature.
143 #[serde(default, skip_serializing_if = "Option::is_none")]
144 pub capabilities: Option<ClientCapabilities>,
145}
146
147/// Result of the `initialize` command.
148///
149/// `protocolVersion` is the version the server has selected from the client's
150/// `protocolVersions` list. The client and server MUST use this version for
151/// the rest of the connection. If the server cannot speak any of the offered
152/// versions it MUST return error code `-32005` (`UnsupportedProtocolVersion`)
153/// instead of a result.
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155#[serde(rename_all = "camelCase")]
156pub struct InitializeResult {
157 /// Protocol version selected by the server. MUST be one of the entries in
158 /// `InitializeParams.protocolVersions`. Formatted as a [SemVer](https://semver.org)
159 /// `MAJOR.MINOR.PATCH` string (e.g. `"0.1.0"`).
160 pub protocol_version: String,
161 /// Current server sequence number
162 pub server_seq: i64,
163 /// Optional identity of the server implementation (name and version).
164 /// Informational only — see {@link Implementation} for how it may and may not
165 /// be used. Whereas {@link InitializeResult.protocolVersion | `protocolVersion`}
166 /// identifies the negotiated protocol, `serverInfo` identifies the host
167 /// software behind it.
168 #[serde(default, skip_serializing_if = "Option::is_none")]
169 pub server_info: Option<Implementation>,
170 /// Snapshots for each `initialSubscriptions` URI
171 pub snapshots: Vec<Snapshot>,
172 /// Suggested default directory for remote filesystem browsing
173 #[serde(default, skip_serializing_if = "Option::is_none")]
174 pub default_directory: Option<Uri>,
175 /// Characters that, when typed in a {@link Message} input, SHOULD cause
176 /// the client to issue a `completions` request with
177 /// {@link CompletionItemKind.UserMessage}. Typically includes characters like
178 /// `'@'` or `'/'`.
179 #[serde(default, skip_serializing_if = "Option::is_none")]
180 pub completion_trigger_characters: Option<Vec<String>>,
181 /// Prefix that the host recognizes at the start of a user {@link Message.text}
182 /// as a shorthand for executing the remainder as a terminal command. Currently
183 /// the standardized convention is `"!"`; absence means the host does not
184 /// support command prefixes.
185 #[serde(default, skip_serializing_if = "Option::is_none")]
186 pub terminal_command_prefix: Option<String>,
187 /// OTLP telemetry channels the host emits, if any. Each populated field is
188 /// either a literal `ahp-otlp:` channel URI or an RFC 6570 URI template a
189 /// client expands before subscribing (currently only the `logs` channel
190 /// defines a template variable, `{level}`, for subscriber-side severity
191 /// filtering). Clients MAY ignore signals they cannot process.
192 #[serde(default, skip_serializing_if = "Option::is_none")]
193 pub telemetry: Option<TelemetryCapabilities>,
194}
195
196/// Optional capabilities a client declares during `initialize`.
197///
198/// Each field is a presence flag: an empty object `{}` means "supported",
199/// absence means "not supported". Sub-fields on individual capabilities
200/// are reserved for future per-capability options.
201#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
202#[serde(rename_all = "camelCase")]
203pub struct ClientCapabilities {
204 /// Client can render
205 /// [MCP Apps](https://github.com/modelcontextprotocol/ext-apps) — i.e.
206 /// it can host the View sandbox, run the `ui/*` protocol against it,
207 /// and forward `mcp://`-channel traffic on the App's behalf.
208 ///
209 /// Hosts SHOULD only populate
210 /// {@link McpServerCustomization.mcpApp | `McpServerCustomization.mcpApp`}
211 /// (and expose the corresponding
212 /// {@link McpServerCustomization.channel | `mcp://` channel}) when this
213 /// capability is declared. Clients that omit it MUST treat
214 /// App-bearing tool calls as ordinary MCP tool calls.
215 #[serde(default, skip_serializing_if = "Option::is_none")]
216 pub mcp_apps: Option<JsonObject>,
217}
218
219/// Identifies a protocol implementation — the software (and build) on one end
220/// of the connection, as distinct from the {@link AgentInfo | agent persona} it
221/// hosts. Carried as {@link InitializeParams.clientInfo | `clientInfo`} on the
222/// client side and {@link InitializeResult.serverInfo | `serverInfo`} on the
223/// server side, mirroring LSP's `clientInfo`/`serverInfo` and MCP's
224/// `Implementation`.
225///
226/// This is **informational only**: it exists for logging, telemetry, an
227/// about/status affordance, and — as a last resort — a known-issue workaround
228/// for a specific buggy build. It is **not** a feature-detection mechanism.
229/// Feature availability stays with the capability model
230/// ({@link ClientCapabilities} and the various `*.capabilities` declarations);
231/// implementations SHOULD NOT gate protocol behaviour on parsing
232/// {@link Implementation.version | `version`}.
233#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
234#[serde(rename_all = "camelCase")]
235pub struct Implementation {
236 /// Implementation name, e.g. a product or package identifier.
237 pub name: String,
238 /// Implementation version. A [SemVer](https://semver.org) string is
239 /// recommended but not required.
240 #[serde(default, skip_serializing_if = "Option::is_none")]
241 pub version: Option<String>,
242 /// Optional human-readable display name.
243 #[serde(default, skip_serializing_if = "Option::is_none")]
244 pub title: Option<String>,
245}
246
247/// Re-establishes a dropped connection. The server replays missed actions or
248/// provides fresh snapshots.
249#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
250#[serde(rename_all = "camelCase")]
251pub struct ReconnectParams {
252 /// Channel URI this command targets.
253 pub channel: Uri,
254 /// Client identifier from the original connection
255 pub client_id: String,
256 /// Last `serverSeq` the client received
257 pub last_seen_server_seq: i64,
258 /// URIs the client was subscribed to
259 pub subscriptions: Vec<Uri>,
260}
261
262/// Reconnect result when the server can replay from the requested sequence.
263///
264/// The server MUST include all replayed data in the response.
265#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
266#[serde(rename_all = "camelCase")]
267pub struct ReconnectReplayResult {
268 /// Missed action envelopes since `lastSeenServerSeq`
269 pub actions: Vec<ActionEnvelope>,
270 /// URIs from `ReconnectParams.subscriptions` that the server cannot resume.
271 /// This includes resources that no longer exist (e.g. disposed sessions or
272 /// terminals) as well as resources the client is no longer permitted to
273 /// observe. Clients SHOULD drop these from their local subscription set.
274 pub missing: Vec<Uri>,
275}
276
277/// Reconnect result when the gap exceeds the replay buffer.
278#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
279#[serde(rename_all = "camelCase")]
280pub struct ReconnectSnapshotResult {
281 /// Fresh snapshots for each subscription
282 pub snapshots: Vec<Snapshot>,
283}
284
285/// Subscribe to a URI-identified channel.
286///
287/// A channel MAY have state associated with it (e.g. root, sessions,
288/// terminals) or be stateless (pure pub/sub for streaming data). For
289/// state-bearing channels the result includes a snapshot; for stateless
290/// channels `snapshot` is omitted.
291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
292#[serde(rename_all = "camelCase")]
293pub struct SubscribeParams {
294 /// Channel URI this command targets.
295 pub channel: Uri,
296 /// Optional delivery preferences for this subscription.
297 ///
298 /// Servers MAY use these preferences to buffer and coalesce high-frequency
299 /// updates while preserving the same reduced state. Omit this field for the
300 /// server's default delivery behavior.
301 #[serde(default, skip_serializing_if = "Option::is_none")]
302 pub delivery: Option<SubscriptionDeliveryOptions>,
303 /// Optional client-requested shape for the returned snapshot.
304 ///
305 /// Servers that do not understand a requested view ignore it and return their
306 /// default snapshot. Clients MUST tolerate receiving more state than requested.
307 #[serde(default, skip_serializing_if = "Option::is_none")]
308 pub view: Option<SubscribeView>,
309}
310
311impl SubscribeParams {
312 /// Create subscribe params with default delivery behavior.
313 pub fn new(channel: impl Into<Uri>) -> Self {
314 Self {
315 channel: channel.into(),
316 delivery: None,
317 view: None,
318 }
319 }
320
321 /// Create subscribe params with advisory delivery preferences.
322 pub fn with_delivery(channel: impl Into<Uri>, delivery: SubscriptionDeliveryOptions) -> Self {
323 Self {
324 channel: channel.into(),
325 delivery: Some(delivery),
326 view: None,
327 }
328 }
329
330 /// Create subscribe params with snapshot-shaping preferences.
331 pub fn with_view(channel: impl Into<Uri>, view: SubscribeView) -> Self {
332 Self {
333 channel: channel.into(),
334 delivery: None,
335 view: Some(view),
336 }
337 }
338}
339
340/// Optional client-requested shape for a subscription snapshot.
341#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
342#[serde(rename_all = "camelCase")]
343pub struct SubscribeView {
344 /// Advisory number of most-recent completed turns to expose in a chat
345 /// snapshot.
346 ///
347 /// Servers MAY return more or fewer turns than requested. When omitted, the
348 /// host MUST return all retained turns. When older turns remain available, the
349 /// returned {@link ChatState} carries `turnsNextCursor`; clients pass that
350 /// cursor to `fetchTurns` to ask the host to page more turns into the chat
351 /// state.
352 #[serde(default, skip_serializing_if = "Option::is_none")]
353 pub turns: Option<i64>,
354}
355
356/// Advisory delivery preferences for a single subscription.
357#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
358#[serde(rename_all = "camelCase")]
359pub struct SubscriptionDeliveryOptions {
360 /// Maximum time, in milliseconds, that the server may intentionally delay
361 /// delivery while buffering/coalescing updates for this subscription.
362 ///
363 /// A value of `0` requests immediate delivery with no intentional coalescing.
364 #[serde(default, skip_serializing_if = "Option::is_none")]
365 pub max_latency_ms: Option<i64>,
366}
367
368/// Result of the `subscribe` command.
369///
370/// `snapshot` is present when the subscribed channel has associated state, and
371/// absent for stateless channels.
372#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
373#[serde(rename_all = "camelCase")]
374pub struct SubscribeResult {
375 /// Snapshot of the subscribed channel's state (omitted for stateless channels)
376 #[serde(default, skip_serializing_if = "Option::is_none")]
377 pub snapshot: Option<Snapshot>,
378}
379
380/// Creates a new session with the specified agent provider.
381///
382/// If the session URI already exists, the server MUST return an error with code
383/// `-32003` (`SessionAlreadyExists`).
384///
385/// After creation, the client should subscribe to the session URI to receive state
386/// updates. The server also broadcasts a `root/sessionAdded` notification to all
387/// clients.
388#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
389#[serde(rename_all = "camelCase")]
390pub struct SessionForkSource {
391 /// URI of the existing session to fork from
392 pub session: Uri,
393 /// Turn ID in the source session; content up to and including this turn's response is copied
394 pub turn_id: String,
395}
396
397#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
398#[serde(rename_all = "camelCase")]
399pub struct CreateSessionParams {
400 /// Channel URI this command targets.
401 pub channel: Uri,
402 /// Agent provider ID
403 #[serde(default, skip_serializing_if = "Option::is_none")]
404 pub provider: Option<String>,
405 /// The working directories the session's agent is granted tool access to.
406 /// A session may span multiple directories; they are equal peers except when
407 /// the agent advertises
408 /// {@link MultipleWorkingDirectoriesCapability.immutablePrimary} (in which case
409 /// the first entry is a fixed process root).
410 ///
411 /// A client MUST NOT supply more than one entry unless the agent advertises
412 /// {@link AgentCapabilities.multipleWorkingDirectories}; a server without that
413 /// capability treats only the first entry as the session's working directory
414 /// and ignores the rest. Dispatch `session/workingDirectorySet` /
415 /// `session/workingDirectoryRemoved` to change the set after the session has
416 /// started.
417 ///
418 /// Ignored for forked sessions — a fork inherits its working directories
419 /// from the source session identified by `fork`.
420 #[serde(default, skip_serializing_if = "Option::is_none")]
421 pub working_directories: Option<Vec<Uri>>,
422 /// Fork from an existing session. The new session is populated with content
423 /// from the source session up to and including the specified turn's response.
424 #[serde(default, skip_serializing_if = "Option::is_none")]
425 pub fork: Option<SessionForkSource>,
426 /// Agent-specific configuration values collected via `resolveSessionConfig`.
427 /// Keys and values correspond to the schema returned by the server.
428 #[serde(default, skip_serializing_if = "Option::is_none")]
429 pub config: Option<JsonObject>,
430 /// Eagerly claim an active client role for the new session.
431 ///
432 /// When provided, the server initializes the session with this client as an
433 /// active client, equivalent to dispatching a `session/activeClientSet`
434 /// action immediately after creation. The `clientId` MUST match the
435 /// `clientId` the creating client supplied in `initialize`.
436 #[serde(default, skip_serializing_if = "Option::is_none")]
437 pub active_client: Option<SessionActiveClient>,
438 /// Opt-in progress token. When set, the client is offering to receive
439 /// `progress` notifications (see `ProgressParams`) for any long-running work
440 /// the server does to bring this session up — most notably the lazy,
441 /// first-use download of the provider's native SDK. The server echoes this
442 /// exact token on every `progress` frame so the client can correlate it to
443 /// this `createSession` call (and the UI awaiting it).
444 ///
445 /// The token MUST be unique across the client's active requests. The server
446 /// MAY ignore it (e.g. when nothing long-running is needed), in which case no
447 /// `progress` notifications are emitted.
448 #[serde(default, skip_serializing_if = "Option::is_none")]
449 pub progress_token: Option<String>,
450}
451
452/// Disposes a session and cleans up server-side resources.
453///
454/// The server broadcasts a `root/sessionRemoved` notification to all clients.
455#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
456#[serde(rename_all = "camelCase")]
457pub struct DisposeSessionParams {
458 /// Channel URI this command targets.
459 pub channel: Uri,
460}
461
462/// Copies source history through a completed turn into the new chat.
463#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
464#[serde(rename_all = "camelCase")]
465pub struct ForkChatSource {
466 /// URI of the existing source chat.
467 pub chat: Uri,
468 /// Completed turn identifier in the source chat.
469 ///
470 /// Content through this turn is copied into the new chat's visible `turns`.
471 pub turn_id: String,
472}
473
474/// Supplies source context to a new side chat without copying it into the side
475/// chat's visible history.
476#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
477#[serde(rename_all = "camelCase")]
478pub struct SideChatSource {
479 /// URI of the existing source chat.
480 pub chat: Uri,
481 /// Stable source-turn identifier in the source chat.
482 ///
483 /// Hosts resolve this id against the source chat's current `activeTurn` or its
484 /// retained `turns` when accepting `createChat`. If it names the current
485 /// active turn, the host snapshots the source chat's retained history plus
486 /// that turn's current user message and any partial assistant response already
487 /// available. Once that turn later becomes historical, it is still referenced
488 /// by this same identifier.
489 pub turn_id: String,
490 /// Optional immutable selected-text snapshot to carry into the created side
491 /// chat's origin.
492 ///
493 /// When present, the host MUST snapshot and preserve this exact selection when
494 /// it accepts `createChat`; later source-turn deltas do not alter it.
495 #[serde(default, skip_serializing_if = "Option::is_none")]
496 pub selection: Option<SideChatSelection>,
497}
498
499/// Creates a new chat within a session.
500#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
501#[serde(rename_all = "camelCase")]
502pub struct CreateChatParams {
503 /// Channel URI this command targets.
504 pub channel: Uri,
505 /// Chat URI (client-chosen, e.g. `ahp-chat:/<uuid>`).
506 pub chat: Uri,
507 /// Optional initial message for the new chat.
508 #[serde(default, skip_serializing_if = "Option::is_none")]
509 pub initial_message: Option<Message>,
510 /// Optional source chat and source turn.
511 ///
512 /// The source chat MUST belong to this session. Clients MUST only request
513 /// `kind: "fork"` when the selected agent advertises
514 /// `capabilities.multipleChats.fork`, and `kind: "sideChat"` when the
515 /// selected agent advertises `capabilities.multipleChats.sideChat`. Both
516 /// source forms carry a stable top-level `turnId`. Forks target completed
517 /// turns. Side chats also carry a stable `turnId`, which the host resolves
518 /// against the source chat's current active turn or retained history. If it
519 /// resolves to the active turn, the host snapshots the currently available
520 /// partial response when accepting `createChat`. When
521 /// `source.kind === "sideChat"` and `source.selection` is present, the host
522 /// also snapshots and preserves that exact selected text in the created chat's
523 /// origin; any `responsePartId` there is provenance only, not a live range.
524 #[serde(default, skip_serializing_if = "Option::is_none")]
525 pub source: Option<ChatSource>,
526 /// Initial working-directory subset for this chat. Every entry MUST be
527 /// present in the owning session's `workingDirectories`; the server MUST
528 /// reject any entry that is not. When absent, the chat inherits the full
529 /// session set. Forked chats (those whose `source.kind` is `"fork"`) inherit
530 /// the source chat's `workingDirectories`; this field is ignored for forks.
531 ///
532 /// A client MUST NOT supply this field unless the agent advertises
533 /// {@link AgentCapabilities.multipleWorkingDirectories}.
534 #[serde(default, skip_serializing_if = "Option::is_none")]
535 pub working_directories: Option<Vec<Uri>>,
536}
537
538/// Disposes a chat and cleans up server-side resources.
539#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
540#[serde(rename_all = "camelCase")]
541pub struct DisposeChatParams {
542 /// Channel URI this command targets.
543 pub channel: Uri,
544}
545
546/// Returns a list of session summaries. Used to populate session lists and sidebars.
547///
548/// The session list is **not** part of the state tree because it can be arbitrarily
549/// large. Clients fetch it imperatively and maintain a local cache updated by
550/// `root/sessionAdded` and `root/sessionRemoved` notifications.
551///
552/// A large catalogue can be fetched incrementally via the {@link PaginatedParams}
553/// `limit`/`cursor` inputs (see that type for the full pagination contract). The
554/// server SHOULD return most-recently-modified entries first, so the first page
555/// is the immediately useful one. The `root/session*` notifications keep an
556/// already-fetched page live; pagination governs only the initial and backfill
557/// fetches.
558#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
559#[serde(rename_all = "camelCase")]
560pub struct ListSessionsParams {
561 /// Channel URI this command targets.
562 pub channel: Uri,
563 /// Maximum number of entries to return in this page. The server SHOULD respect
564 /// this bound but MAY return fewer entries and MAY impose its own upper cap.
565 /// Omit to let the server choose the page size.
566 #[serde(default, skip_serializing_if = "Option::is_none")]
567 pub limit: Option<i64>,
568 /// Opaque pagination cursor from a previous {@link PaginatedResult.nextCursor}.
569 /// Omit to fetch the first page. Cursors are server-defined and MUST be treated
570 /// as opaque — do not parse, modify, or persist them across connections. An
571 /// unrecognised cursor SHOULD be rejected with an `InvalidParams` error.
572 #[serde(default, skip_serializing_if = "Option::is_none")]
573 pub cursor: Option<String>,
574}
575
576/// Result of the `listSessions` command.
577#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
578#[serde(rename_all = "camelCase")]
579pub struct ListSessionsResult {
580 /// Opaque cursor for the next page. Present when more entries exist beyond the
581 /// returned page; absent signals the end of the collection. Pass it back as
582 /// {@link PaginatedParams.cursor} to fetch the following page.
583 #[serde(default, skip_serializing_if = "Option::is_none")]
584 pub next_cursor: Option<String>,
585 /// The list of session summaries. The server SHOULD order them
586 /// most-recently-modified first.
587 pub items: Vec<SessionSummary>,
588}
589
590/// Reads the content of a resource by URI.
591///
592/// Content references keep the state tree small by storing large data (images,
593/// long tool outputs) by reference rather than inline.
594///
595/// Binary content (images, etc.) MUST use `base64` encoding. Text content MAY
596/// use `utf-8` encoding.
597///
598/// Like all `resource*` methods, `resourceRead` is symmetrical and MAY be
599/// sent in either direction. Hosts use it to fetch content from a
600/// client-published URI (e.g. `virtual://my-client/...` plugins); clients
601/// use it to read host-side files. The receiver enforces access via the
602/// same permission/`resourceRequest` flow regardless of which peer initiated.
603#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
604#[serde(rename_all = "camelCase")]
605pub struct ResourceReadParams {
606 /// Channel URI this command targets.
607 pub channel: Uri,
608 /// Content URI from a `ContentRef`
609 pub uri: String,
610 /// Preferred encoding for the returned data (default: server-chosen)
611 #[serde(default, skip_serializing_if = "Option::is_none")]
612 pub encoding: Option<ContentEncoding>,
613}
614
615/// Result of the `resourceRead` command.
616///
617/// The server SHOULD honor the `encoding` requested in the params. If the
618/// server cannot provide the requested encoding, it MUST fall back to either
619/// `base64` or `utf-8`.
620#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
621#[serde(rename_all = "camelCase")]
622pub struct ResourceReadResult {
623 /// Content encoded as a string
624 pub data: String,
625 /// How `data` is encoded
626 pub encoding: ContentEncoding,
627 /// Content type (e.g. `"image/png"`, `"text/plain"`)
628 #[serde(default, skip_serializing_if = "Option::is_none")]
629 pub content_type: Option<String>,
630}
631
632/// Writes content to a file on the server's filesystem.
633///
634/// Binary content (images, etc.) MUST use `base64` encoding. Text content MAY
635/// use `utf-8` encoding.
636///
637/// If the file does not exist, it is created. If the file already exists, the
638/// effect on existing bytes depends on {@link ResourceWriteParams.mode}:
639/// `truncate` (default) overwrites from the chosen offset onward, `append`
640/// preserves all existing bytes and adds `data` at a position rooted at EOF,
641/// and `insert` preserves all existing bytes and splices `data` in at an
642/// offset rooted at the start of the file.
643///
644/// Like all `resource*` methods, `resourceWrite` is symmetrical and MAY be
645/// sent in either direction.
646#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
647#[serde(rename_all = "camelCase")]
648pub struct ResourceWriteParams {
649 /// Channel URI this command targets.
650 pub channel: Uri,
651 /// Target file URI on the server filesystem
652 pub uri: Uri,
653 /// Content encoded as a string
654 pub data: String,
655 /// How `data` is encoded
656 pub encoding: ContentEncoding,
657 /// Content type (e.g. `"text/plain"`, `"image/png"`)
658 #[serde(default, skip_serializing_if = "Option::is_none")]
659 pub content_type: Option<String>,
660 /// If `true`, the server MUST fail if the file already exists instead of
661 /// overwriting it. Useful for safe creation of new files.
662 #[serde(default, skip_serializing_if = "Option::is_none")]
663 pub create_only: Option<bool>,
664 /// How `data` is placed within the target file. Defaults to `'truncate'`
665 /// (full overwrite) when omitted. See {@link ResourceWriteMode} for the
666 /// meaning of each mode and how it interprets {@link position}.
667 #[serde(default, skip_serializing_if = "Option::is_none")]
668 pub mode: Option<ResourceWriteMode>,
669 /// Byte offset interpreted according to {@link mode}. Defaults to `0`.
670 /// - `truncate`: offset from the start of the file at which to truncate
671 /// before writing.
672 /// - `append`: bytes back from EOF at which to insert `data`.
673 /// - `insert`: offset from the start of the file at which to splice in
674 /// `data`.
675 #[serde(default, skip_serializing_if = "Option::is_none")]
676 pub position: Option<i64>,
677 /// Optimistic-concurrency token previously returned by
678 /// {@link ResourceResolveResult.etag}. When set, the server MUST fail with
679 /// `Conflict` if the current `etag` does not match — preventing lost
680 /// updates between a `resourceResolve` and a subsequent `resourceWrite`.
681 #[serde(default, skip_serializing_if = "Option::is_none")]
682 pub if_match: Option<String>,
683}
684
685/// Result of the `resourceWrite` command.
686///
687/// An empty object on success.
688#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
689#[serde(rename_all = "camelCase")]
690pub struct ResourceWriteResult {}
691
692/// Lists directory entries at a file URI on the server's filesystem.
693///
694/// This is intended for remote folder pickers and similar UI that needs to let
695/// users navigate the server's local filesystem.
696///
697/// The server MUST return success only if the target exists and is a directory.
698/// If the target does not exist, is not a directory, or cannot be accessed, the
699/// server MUST return a JSON-RPC error.
700///
701/// Like all `resource*` methods, `resourceList` is symmetrical and MAY be
702/// sent in either direction.
703#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
704#[serde(rename_all = "camelCase")]
705pub struct ResourceListParams {
706 /// Channel URI this command targets.
707 pub channel: Uri,
708 /// Directory URI on the server filesystem
709 pub uri: Uri,
710}
711
712/// Result of the `resourceList` command.
713#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
714#[serde(rename_all = "camelCase")]
715pub struct ResourceListResult {
716 /// Entries directly contained in the requested directory
717 pub entries: Vec<DirectoryEntry>,
718}
719
720/// Directory entry returned by `resourceList`.
721#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
722#[serde(rename_all = "camelCase")]
723pub struct DirectoryEntry {
724 /// Base name of the entry
725 pub name: String,
726 /// Whether the entry is a file or directory
727 pub r#type: String,
728}
729
730/// Copies a resource from one URI to another on the server's filesystem.
731///
732/// If the destination already exists, it is overwritten unless `failIfExists`
733/// is set.
734///
735/// Like all `resource*` methods, `resourceCopy` is symmetrical and MAY be
736/// sent in either direction.
737#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
738#[serde(rename_all = "camelCase")]
739pub struct ResourceCopyParams {
740 /// Channel URI this command targets.
741 pub channel: Uri,
742 /// Source URI to copy from
743 pub source: Uri,
744 /// Destination URI to copy to
745 pub destination: Uri,
746 /// If `true`, the server MUST fail if the destination already exists instead
747 /// of overwriting it.
748 #[serde(default, skip_serializing_if = "Option::is_none")]
749 pub fail_if_exists: Option<bool>,
750}
751
752/// Result of the `resourceCopy` command.
753///
754/// An empty object on success.
755#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
756#[serde(rename_all = "camelCase")]
757pub struct ResourceCopyResult {}
758
759/// Deletes a resource at a URI on the server's filesystem.
760///
761/// Like all `resource*` methods, `resourceDelete` is symmetrical and MAY be
762/// sent in either direction.
763#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
764#[serde(rename_all = "camelCase")]
765pub struct ResourceDeleteParams {
766 /// Channel URI this command targets.
767 pub channel: Uri,
768 /// URI of the resource to delete
769 pub uri: Uri,
770 /// If `true` and the target is a directory, delete it and all its contents
771 /// recursively. If `false` (default), deleting a non-empty directory MUST fail.
772 #[serde(default, skip_serializing_if = "Option::is_none")]
773 pub recursive: Option<bool>,
774}
775
776/// Result of the `resourceDelete` command.
777///
778/// An empty object on success.
779#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
780#[serde(rename_all = "camelCase")]
781pub struct ResourceDeleteResult {}
782
783/// Moves (renames) a resource from one URI to another on the server's filesystem.
784///
785/// If the destination already exists, it is overwritten unless `failIfExists`
786/// is set.
787///
788/// Like all `resource*` methods, `resourceMove` is symmetrical and MAY be
789/// sent in either direction.
790#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
791#[serde(rename_all = "camelCase")]
792pub struct ResourceMoveParams {
793 /// Channel URI this command targets.
794 pub channel: Uri,
795 /// Source URI to move from
796 pub source: Uri,
797 /// Destination URI to move to
798 pub destination: Uri,
799 /// If `true`, the server MUST fail if the destination already exists instead
800 /// of overwriting it.
801 #[serde(default, skip_serializing_if = "Option::is_none")]
802 pub fail_if_exists: Option<bool>,
803}
804
805/// Result of the `resourceMove` command.
806///
807/// An empty object on success.
808#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
809#[serde(rename_all = "camelCase")]
810pub struct ResourceMoveResult {}
811
812/// Resolves a resource — the combination of POSIX `stat` and `realpath`.
813///
814/// `resourceResolve` returns metadata about the resource together with its
815/// canonical URI after symlink resolution. Use this in place of any
816/// `resourceExists` shim: a missing resource MUST surface as a `NotFound`
817/// JSON-RPC error rather than a success with a sentinel value. Callers that
818/// truly need a boolean check should attempt `resourceResolve` and treat
819/// `NotFound` as "does not exist".
820///
821/// Like all `resource*` methods, `resourceResolve` is symmetrical and MAY be
822/// sent in either direction.
823#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
824#[serde(rename_all = "camelCase")]
825pub struct ResourceResolveParams {
826 /// Channel URI this command targets.
827 pub channel: Uri,
828 /// URI to resolve
829 pub uri: Uri,
830 /// When `true` (default), follow symlinks and report the metadata of the
831 /// link target — and set `uri` in the result to the canonical (realpath)
832 /// URI. When `false`, stat the link itself (lstat semantics) and report
833 /// `type: 'symlink'`.
834 #[serde(default, skip_serializing_if = "Option::is_none")]
835 pub follow_symlinks: Option<bool>,
836}
837
838/// Result of the `resourceResolve` command.
839#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
840#[serde(rename_all = "camelCase")]
841pub struct ResourceResolveResult {
842 /// Canonical URI after symlink resolution. Equal to the requested URI when
843 /// `followSymlinks` is `false` or the URI does not traverse a symlink.
844 pub uri: Uri,
845 /// Resource kind.
846 pub r#type: ResourceType,
847 /// Size in bytes. Omitted for directories when the provider cannot
848 /// cheaply compute it.
849 #[serde(default, skip_serializing_if = "Option::is_none")]
850 pub size: Option<i64>,
851 /// Last-modified time in ISO 8601 format, when known.
852 #[serde(default, skip_serializing_if = "Option::is_none")]
853 pub mtime: Option<String>,
854 /// Creation time in ISO 8601 format, when known.
855 #[serde(default, skip_serializing_if = "Option::is_none")]
856 pub ctime: Option<String>,
857 /// Sniffed MIME type, when known (e.g. `"text/plain"`, `"image/png"`).
858 #[serde(default, skip_serializing_if = "Option::is_none")]
859 pub content_type: Option<String>,
860 /// Opaque per-provider version token. When present, pass it as
861 /// {@link ResourceWriteParams.ifMatch} on a subsequent `resourceWrite` to
862 /// detect concurrent modifications.
863 #[serde(default, skip_serializing_if = "Option::is_none")]
864 pub etag: Option<String>,
865}
866
867/// Creates a directory on the server's filesystem with `mkdir -p` semantics.
868///
869/// The server MUST create any missing parent directories. Creating a
870/// directory that already exists is a no-op success. If `uri` already
871/// exists but is **not** a directory, the server MUST fail with
872/// `AlreadyExists`.
873///
874/// Like all `resource*` methods, `resourceMkdir` is symmetrical and MAY be
875/// sent in either direction.
876#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
877#[serde(rename_all = "camelCase")]
878pub struct ResourceMkdirParams {
879 /// Channel URI this command targets.
880 pub channel: Uri,
881 /// Directory URI to create (parents created as needed).
882 pub uri: Uri,
883}
884
885/// Result of the `resourceMkdir` command.
886///
887/// An empty object on success.
888#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
889#[serde(rename_all = "camelCase")]
890pub struct ResourceMkdirResult {}
891
892/// Requests permission to access a resource on the receiver's filesystem.
893///
894/// `resourceRequest` is symmetrical and MAY be sent in either direction: a
895/// client asks the server to grant access to a server-side resource, or a
896/// server asks the client to grant access to a client-side resource. The
897/// receiver decides whether to allow, deny, or prompt the user for the
898/// requested access.
899///
900/// If the receiver denies access, it MUST respond with `PermissionDenied`
901/// (-32009). The error data MAY include a `ResourceRequestParams` value
902/// describing the access the caller would need to be granted for the
903/// operation to succeed; see `PermissionDeniedErrorData` in
904/// `types/errors.ts`.
905///
906/// After a successful `resourceRequest`, the caller MAY use the corresponding
907/// `resource*` commands (e.g. `resourceRead`, `resourceWrite`) to perform the
908/// operation. Receivers MAY rescind access at any time by returning
909/// `PermissionDenied` on subsequent operations.
910///
911/// Either `read`, `write`, or both SHOULD be set to `true`. A request with
912/// neither flag set is treated as `read: true` by receivers.
913#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
914#[serde(rename_all = "camelCase")]
915pub struct ResourceRequestParams {
916 /// Channel URI this command targets.
917 pub channel: Uri,
918 /// Resource URI being requested. Typically a `file:` URI on the receiver's
919 /// filesystem, but any URI scheme that the receiver mediates access to is
920 /// allowed.
921 pub uri: Uri,
922 /// Whether the caller needs read access to the resource.
923 #[serde(default, skip_serializing_if = "Option::is_none")]
924 pub read: Option<bool>,
925 /// Whether the caller needs write access to the resource.
926 #[serde(default, skip_serializing_if = "Option::is_none")]
927 pub write: Option<bool>,
928}
929
930/// Result of the `resourceRequest` command.
931///
932/// An empty object on success.
933#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
934#[serde(rename_all = "camelCase")]
935pub struct ResourceRequestResult {}
936
937/// Creates a resource watcher on the receiver's filesystem.
938///
939/// The receiver allocates an `ahp-resource-watch:/<id>` channel URI and
940/// returns it on {@link CreateResourceWatchResult.channel}. The caller then
941/// [`subscribe`](./subscriptions)s to that channel to receive
942/// `resourceWatch/changed` actions over the standard action envelope.
943///
944/// The watch lifecycle is tied to subscription: when every subscriber has
945/// unsubscribed (or the underlying connection drops), the receiver MUST
946/// release the watcher. There is no explicit dispose command — `unsubscribe`
947/// is the only handle the caller needs.
948///
949/// Like the rest of the `resource*` family, `createResourceWatch` is
950/// symmetrical and MAY be sent in either direction. Access is gated through
951/// the same permission flow as `resourceRead`/`resourceWrite`.
952#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
953#[serde(rename_all = "camelCase")]
954pub struct CreateResourceWatchParams {
955 /// Channel URI this command targets.
956 pub channel: Uri,
957 /// URI to watch.
958 pub uri: Uri,
959 /// If `true`, the receiver MUST report changes for descendants of `uri`.
960 /// If `false` (default), only changes to `uri` itself — and, when `uri`
961 /// is a directory, its direct children — are reported.
962 #[serde(default, skip_serializing_if = "Option::is_none")]
963 pub recursive: Option<bool>,
964 /// Glob patterns or paths relative to `uri` to exclude from reporting.
965 /// Wrapped in `{ items }` for forward compatibility.
966 #[serde(default, skip_serializing_if = "Option::is_none")]
967 pub excludes: Option<AnyValue>,
968 /// Glob patterns or paths relative to `uri` to restrict reporting to.
969 /// Omit to report every change under `uri` subject to `excludes`.
970 /// Wrapped in `{ items }` for forward compatibility.
971 #[serde(default, skip_serializing_if = "Option::is_none")]
972 pub includes: Option<AnyValue>,
973}
974
975/// Result of the `createResourceWatch` command.
976#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
977#[serde(rename_all = "camelCase")]
978pub struct CreateResourceWatchResult {
979 /// Receiver-assigned watch channel URI (`ahp-resource-watch:/<id>`). The
980 /// caller subscribes to this URI to start receiving change events and
981 /// unsubscribes to release the watcher.
982 pub channel: Uri,
983}
984
985/// Requests that the host load older historical turns into a chat state.
986///
987/// The command result does not carry turns. Instead, before responding, the host
988/// MUST dispatch `chat/turnsLoaded` to insert any loaded turns into the chat
989/// channel's `turns` state, ahead of the already-loaded window, and update or
990/// clear `turnsNextCursor`.
991///
992/// Before applying any operation that references a turn outside the currently
993/// loaded window, the host MUST eagerly load enough older turns into state for
994/// that operation to reduce against valid state.
995#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
996#[serde(rename_all = "camelCase")]
997pub struct FetchTurnsParams {
998 /// Channel URI this command targets.
999 pub channel: Uri,
1000 /// Opaque cursor from `ChatState.turnsNextCursor`.
1001 ///
1002 /// The host MUST reject unrecognised cursors with `InvalidParams`. Omit only
1003 /// when asking the host to opportunistically load its next older page for the
1004 /// chat, if any.
1005 #[serde(default, skip_serializing_if = "Option::is_none")]
1006 pub cursor: Option<String>,
1007}
1008
1009/// Result of the `fetchTurns` command.
1010#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1011#[serde(rename_all = "camelCase")]
1012pub struct FetchTurnsResult {}
1013
1014/// Stop receiving updates for a channel.
1015#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1016#[serde(rename_all = "camelCase")]
1017pub struct UnsubscribeParams {
1018 /// Channel URI to unsubscribe from
1019 pub channel: Uri,
1020}
1021
1022/// Fire-and-forget action dispatch (write-ahead). The client applies actions
1023/// optimistically to local state and the server echoes them back as an
1024/// {@link ActionEnvelope} once accepted.
1025///
1026/// The client → server method is named `dispatchAction`; the server's reply
1027/// arrives on the server → client `action` notification (params:
1028/// {@link ActionEnvelope}).
1029#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1030#[serde(rename_all = "camelCase")]
1031pub struct DispatchActionParams {
1032 /// Channel URI this action targets
1033 pub channel: Uri,
1034 /// Client sequence number
1035 pub client_seq: i64,
1036 /// The action to dispatch
1037 pub action: StateAction,
1038}
1039
1040/// Pushes a Bearer token for a protected resource. The `resource` field MUST
1041/// match a protected-resource identifier the client has discovered from the
1042/// server — whether declared statically in `AgentInfo.protectedResources`,
1043/// or discovered dynamically from a live `McpServerAuthRequiredState.resource`
1044/// or `ToolCallAuthRequiredState.auth.resource` (both surfaced only once the
1045/// corresponding MCP server or tool call actually challenges for auth).
1046/// Servers MUST accept any `resource` value they have themselves advertised
1047/// through one of these three mechanisms.
1048///
1049/// Tokens are delivered using [RFC 6750](https://datatracker.ietf.org/doc/html/rfc6750)
1050/// (Bearer Token Usage) semantics. The client obtains the token from the
1051/// authorization server(s) listed in the resource's metadata and pushes it
1052/// to the server via this command.
1053#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1054#[serde(rename_all = "camelCase")]
1055pub struct AuthenticateParams {
1056 /// Channel URI this command targets.
1057 pub channel: Uri,
1058 /// The protected resource identifier. MUST match a `resource` value the
1059 /// server has advertised — via `ProtectedResourceMetadata` in
1060 /// `AgentInfo.protectedResources`, or via a live
1061 /// `McpServerAuthRequiredState.resource` / `ToolCallAuthRequiredState.auth.resource`.
1062 pub resource: String,
1063 /// Bearer token obtained from the resource's authorization server
1064 pub token: String,
1065 /// OAuth scopes the token grants, when known. Lets the server determine
1066 /// whether a specific challenge — e.g. the `requiredScopes` on a live
1067 /// `McpServerAuthRequiredState` or `ToolCallAuthRequiredState.auth` — is
1068 /// satisfied without decoding the (opaque, server-specific) token itself.
1069 /// Omit when the client doesn't track granted scopes separately from the
1070 /// token.
1071 #[serde(default, skip_serializing_if = "Option::is_none")]
1072 pub scopes: Option<Vec<String>>,
1073}
1074
1075/// Result of the `authenticate` command.
1076///
1077/// An empty object on success. If the token is invalid or the resource is
1078/// unrecognized, the server MUST return a JSON-RPC error (e.g. `AuthRequired`
1079/// `-32007` or `InvalidParams` `-32602`).
1080#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1081#[serde(rename_all = "camelCase")]
1082pub struct AuthenticateResult {}
1083
1084/// Creates a new terminal on the server.
1085///
1086/// After creation, the client should subscribe to the terminal URI to receive
1087/// state updates. The server dispatches `root/terminalsChanged` to update the
1088/// root terminal list.
1089#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1090#[serde(rename_all = "camelCase")]
1091pub struct CreateTerminalParams {
1092 /// Channel URI this command targets.
1093 pub channel: Uri,
1094 /// Initial owner of the terminal
1095 pub claim: TerminalClaim,
1096 /// Human-readable terminal name
1097 #[serde(default, skip_serializing_if = "Option::is_none")]
1098 pub name: Option<String>,
1099 /// Initial working directory URI
1100 #[serde(default, skip_serializing_if = "Option::is_none")]
1101 pub cwd: Option<Uri>,
1102 /// Initial terminal width in columns
1103 #[serde(default, skip_serializing_if = "Option::is_none")]
1104 pub cols: Option<i64>,
1105 /// Initial terminal height in rows
1106 #[serde(default, skip_serializing_if = "Option::is_none")]
1107 pub rows: Option<i64>,
1108}
1109
1110/// Disposes a terminal and kills its process if still running.
1111///
1112/// The server dispatches `root/terminalsChanged` to remove the terminal from
1113/// the root terminal list.
1114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1115#[serde(rename_all = "camelCase")]
1116pub struct DisposeTerminalParams {
1117 /// Channel URI this command targets.
1118 pub channel: Uri,
1119}
1120
1121/// Iteratively resolves the session configuration schema. The client sends the
1122/// current partial session config and any user-filled metadata values. The server
1123/// returns a property schema describing what additional metadata is needed,
1124/// contextual to the current selections.
1125///
1126/// The client calls this command whenever the user changes a significant input
1127/// (e.g. picks a working directory, toggles a property). Each response returns
1128/// the full current property set (not a delta). The returned `values` contain
1129/// server-resolved defaults to pass to `createSession`.
1130#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1131#[serde(rename_all = "camelCase")]
1132pub struct ResolveSessionConfigParams {
1133 /// Channel URI this command targets.
1134 pub channel: Uri,
1135 /// Agent provider ID
1136 #[serde(default, skip_serializing_if = "Option::is_none")]
1137 pub provider: Option<String>,
1138 /// Working directory for the session
1139 #[serde(default, skip_serializing_if = "Option::is_none")]
1140 pub working_directory: Option<Uri>,
1141 /// Current user-filled configuration values
1142 #[serde(default, skip_serializing_if = "Option::is_none")]
1143 pub config: Option<JsonObject>,
1144}
1145
1146/// Result of the `resolveSessionConfig` command.
1147#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1148#[serde(rename_all = "camelCase")]
1149pub struct ResolveSessionConfigResult {
1150 /// JSON Schema describing available configuration properties given the current context
1151 pub schema: SessionConfigSchema,
1152 /// Current configuration values (echoed back with server-resolved defaults applied)
1153 pub values: JsonObject,
1154}
1155
1156/// Queries the server for allowed values of a dynamic session config property.
1157///
1158/// Used when a property in the schema returned by `resolveSessionConfig` has
1159/// `enumDynamic: true`. The client sends a search query and receives matching
1160/// values with display metadata.
1161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1162#[serde(rename_all = "camelCase")]
1163pub struct SessionConfigCompletionsParams {
1164 /// Channel URI this command targets.
1165 pub channel: Uri,
1166 /// Agent provider ID
1167 #[serde(default, skip_serializing_if = "Option::is_none")]
1168 pub provider: Option<String>,
1169 /// Working directory for the session
1170 #[serde(default, skip_serializing_if = "Option::is_none")]
1171 pub working_directory: Option<Uri>,
1172 /// Current user-filled configuration values (provides context for the query)
1173 #[serde(default, skip_serializing_if = "Option::is_none")]
1174 pub config: Option<JsonObject>,
1175 /// Property id from the schema to query values for
1176 pub property: String,
1177 /// Search filter text (empty or omitted returns default/recent values)
1178 #[serde(default, skip_serializing_if = "Option::is_none")]
1179 pub query: Option<String>,
1180}
1181
1182/// Result of the `sessionConfigCompletions` command.
1183#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1184#[serde(rename_all = "camelCase")]
1185pub struct SessionConfigCompletionsResult {
1186 /// Matching value items
1187 pub items: Vec<SessionConfigValueItem>,
1188}
1189
1190/// A single value item returned by `sessionConfigCompletions`.
1191#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1192#[serde(rename_all = "camelCase")]
1193pub struct SessionConfigValueItem {
1194 /// The value to store in config
1195 pub value: String,
1196 /// Human-readable display label
1197 pub label: String,
1198 /// Optional secondary description
1199 #[serde(default, skip_serializing_if = "Option::is_none")]
1200 pub description: Option<String>,
1201}
1202
1203/// Requests completion items for a partially-typed input (e.g. a user message
1204/// the user is currently composing). Used to power `@`-mention pickers,
1205/// file/symbol references, and similar inline-completion experiences.
1206///
1207/// Servers SHOULD treat this command as best-effort and return promptly. The
1208/// client SHOULD debounce calls to avoid flooding the server with requests on
1209/// every keystroke.
1210#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1211#[serde(rename_all = "camelCase")]
1212pub struct CompletionsParams {
1213 /// Channel URI this command targets.
1214 pub channel: Uri,
1215 /// What kind of completion is being requested.
1216 pub kind: CompletionItemKind,
1217 /// The complete text of the input being completed (e.g. the full user
1218 /// message text typed so far).
1219 pub text: String,
1220 /// The character offset within `text` at which the completion is requested,
1221 /// measured in UTF-16 code units. MUST satisfy `0 <= offset <= text.length`.
1222 pub offset: i64,
1223}
1224
1225/// A single completion item returned by the `completions` command.
1226///
1227/// When the user accepts an item, the client SHOULD:
1228/// 1. Replace the range `[rangeStart, rangeEnd)` in the input with `insertText`
1229/// (or insert `insertText` at the cursor when the range is omitted).
1230/// 2. Associate the item's `attachment` with the resulting {@link Message}.
1231#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1232#[serde(rename_all = "camelCase")]
1233pub struct CompletionItem {
1234 /// The text inserted into the input when this item is accepted.
1235 pub insert_text: String,
1236 /// If defined, the start of the range in the input's `text` that is replaced
1237 /// by `insertText`. The range is the half-open interval
1238 /// `[rangeStart, rangeEnd)` of character offsets, measured in UTF-16 code
1239 /// units.
1240 ///
1241 /// When omitted, the client SHOULD insert `insertText` at the cursor.
1242 ///
1243 /// Note: this range refers to positions in the *current* input. The
1244 /// attachment's own `rangeStart`/`rangeEnd` (when present) refer to
1245 /// positions in the final {@link Message.text} after the item is
1246 /// accepted.
1247 #[serde(default, skip_serializing_if = "Option::is_none")]
1248 pub range_start: Option<i64>,
1249 /// The end of the range in the input's `text` that is replaced by
1250 /// `insertText`. See {@link rangeStart}.
1251 #[serde(default, skip_serializing_if = "Option::is_none")]
1252 pub range_end: Option<i64>,
1253 /// The attachment associated with this completion item.
1254 pub attachment: MessageAttachment,
1255}
1256
1257/// Result of the `completions` command.
1258#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1259#[serde(rename_all = "camelCase")]
1260pub struct CompletionsResult {
1261 /// The completion items, in the order the server suggests displaying them.
1262 pub items: Vec<CompletionItem>,
1263}
1264
1265/// Invokes a server-defined {@link ChangesetOperation} against a changeset,
1266/// a single file, or a line range.
1267///
1268/// The server validates that `operationId` exists in the changeset's
1269/// current `operations` list and that the requested `target.kind` is
1270/// contained in the operation's `scopes`. Invalid combinations result in a
1271/// JSON-RPC error.
1272///
1273/// State changes resulting from invocation flow back through the normal
1274/// `changeset/*` action stream on the relevant changeset URIs. Clients
1275/// SHOULD NOT synthesise local optimistic changes for invocations unless
1276/// the server explicitly opts in via a future capability.
1277#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1278#[serde(rename_all = "camelCase")]
1279pub struct InvokeChangesetOperationParams {
1280 /// Channel URI this command targets.
1281 pub channel: Uri,
1282 /// Matches {@link ChangesetOperation.id} from the changeset's `operations` list.
1283 pub operation_id: String,
1284 /// Target of the operation. Required iff the chosen scope is
1285 /// `'resource'` or `'range'`. Omit for changeset-scoped operations.
1286 #[serde(default, skip_serializing_if = "Option::is_none")]
1287 pub target: Option<ChangesetOperationTarget>,
1288}
1289
1290/// Result of the {@link InvokeChangesetOperationParams | `invokeChangesetOperation`}
1291/// command.
1292///
1293/// Success is implicit: the server returns this result when it accepted
1294/// the operation. Failure is signalled by rejecting the JSON-RPC request
1295/// with an appropriate error code, not by any field on this result. The
1296/// operation MAY still produce subsequent failure feedback through the
1297/// {@link ChangesetStatusChangedAction | `changeset/statusChanged`} stream.
1298#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1299#[serde(rename_all = "camelCase")]
1300pub struct InvokeChangesetOperationResult {
1301 /// Optional human-readable message describing the result.
1302 #[serde(default, skip_serializing_if = "Option::is_none")]
1303 pub message: Option<StringOrMarkdown>,
1304 /// Optional follow-up: a URI to open (e.g. a PR), a content ref, etc.
1305 #[serde(default, skip_serializing_if = "Option::is_none")]
1306 pub follow_up: Option<ChangesetOperationFollowUp>,
1307}
1308
1309/// Optional follow-up surfaced by the server after an operation completes —
1310/// a {@link ContentRef} the client can fetch and display.
1311///
1312/// Set `external` to `true` to open the content in the user's preferred
1313/// external handler (e.g. browser); otherwise the client is expected to
1314/// surface it inline.
1315#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1316#[serde(rename_all = "camelCase")]
1317pub struct ChangesetOperationFollowUp {
1318 pub content: ContentRef,
1319 /// When `true`, open in an external handler rather than inline.
1320 #[serde(default, skip_serializing_if = "Option::is_none")]
1321 pub external: Option<bool>,
1322}
1323
1324// ─── ChatSource Union ─────────────────────────────────────────────────
1325
1326/// How a new chat uses a source chat.
1327#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1328#[serde(tag = "kind")]
1329pub enum ChatSource {
1330 #[serde(rename = "fork")]
1331 Fork(ForkChatSource),
1332 #[serde(rename = "sideChat")]
1333 SideChat(SideChatSource),
1334}
1335
1336// ─── ReconnectResult Union ────────────────────────────────────────────
1337
1338/// Result of the `reconnect` command.
1339#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1340#[serde(tag = "type")]
1341pub enum ReconnectResult {
1342 #[serde(rename = "replay")]
1343 Replay(ReconnectReplayResult),
1344 #[serde(rename = "snapshot")]
1345 Snapshot(ReconnectSnapshotResult),
1346}
1347
1348// ─── Changeset Operation Unions ───────────────────────────────────────
1349
1350/// Identifies the file or range a `ChangesetOperation` should act on.
1351#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1352#[serde(tag = "kind")]
1353pub enum ChangesetOperationTarget {
1354 #[serde(rename = "resource")]
1355 Resource {
1356 resource: Uri,
1357 #[serde(default, skip_serializing_if = "Option::is_none")]
1358 side: Option<String>,
1359 },
1360 #[serde(rename = "range")]
1361 Range {
1362 resource: Uri,
1363 #[serde(default, skip_serializing_if = "Option::is_none")]
1364 side: Option<String>,
1365 range: TextRange,
1366 },
1367}