vtcode_webmcp/runtime.rs
1use crate::error::Result;
2use crate::protocol::FileChange;
3use async_trait::async_trait;
4use serde::Serialize;
5use std::borrow::Cow;
6
7/// Runtime status exposed to a paired browser.
8#[derive(Debug, Clone, Serialize)]
9pub struct RuntimeStatus {
10 /// Displayed workspace root, never a secret.
11 pub workspace_root: String,
12 /// Whether the bridge has a connected runtime adapter.
13 pub connected: bool,
14 /// Whether the adapter can submit prompts to an agent runtime.
15 pub turns_available: bool,
16 /// Whether mutation requests can be authorized by the runtime.
17 pub mutations_allowed: bool,
18 /// Whether check requests can be authorized by the runtime.
19 pub checks_allowed: bool,
20 /// Human-readable approval authority.
21 pub approval_authority: Cow<'static, str>,
22}
23
24/// A file entry returned by a runtime adapter.
25#[derive(Debug, Clone, Serialize)]
26pub struct WorkspaceFile {
27 /// Workspace-relative path.
28 pub path: String,
29 /// File size in bytes.
30 pub size_bytes: u64,
31 /// SHA-256 digest prefixed with `sha256:`.
32 pub digest: String,
33}
34
35/// File content plus its authoritative digest.
36#[derive(Debug, Clone, Serialize)]
37pub struct FileSnapshot {
38 /// Workspace-relative path.
39 pub path: String,
40 /// UTF-8 file content.
41 pub content: String,
42 /// SHA-256 digest of `content`.
43 pub digest: String,
44}
45
46/// A validated, not-yet-applied proposal.
47#[derive(Debug, Clone, Serialize)]
48pub struct PatchProposal {
49 /// Opaque proposal identity.
50 pub proposal_id: String,
51 /// Structured changes included in the proposal.
52 pub changes: Vec<FileChange>,
53 /// Authoritative unified diff generated by the adapter.
54 pub unified_diff: String,
55}
56
57/// Result of an applied proposal.
58#[derive(Debug, Clone, Serialize)]
59pub struct AppliedChange {
60 /// Opaque identity required for revert.
61 pub change_id: String,
62 /// Paths changed by the proposal.
63 pub paths: Vec<String>,
64}
65
66/// Result of a check command.
67#[derive(Debug, Clone, Serialize)]
68pub struct CheckResult {
69 /// Parsed command text.
70 pub command: String,
71 /// Process exit code, if the process started.
72 pub exit_code: Option<i32>,
73 /// Captured standard output.
74 pub stdout: String,
75 /// Captured standard error.
76 pub stderr: String,
77}
78
79/// Result of a submitted agent turn.
80#[derive(Debug, Clone, Serialize)]
81pub struct TurnResult {
82 /// Runtime-assigned turn identifier.
83 pub turn_id: String,
84 /// Whether the turn was accepted for execution.
85 pub accepted: bool,
86}
87
88/// The runtime boundary used by the WebMCP transport.
89#[async_trait]
90pub trait RuntimeAdapter: Send + Sync {
91 /// Return current workspace and permission state.
92 async fn status(&self) -> Result<RuntimeStatus>;
93
94 /// List files visible to the session.
95 async fn list_files(&self) -> Result<Vec<WorkspaceFile>>;
96
97 /// Read one visible file.
98 async fn read_file(&self, path: &str) -> Result<FileSnapshot>;
99
100 /// Validate and stage a proposal without mutating the workspace.
101 async fn propose_changes(&self, changes: Vec<FileChange>) -> Result<PatchProposal>;
102
103 /// Apply a proposal through the runtime's approval authority.
104 async fn apply_proposal(&self, proposal_id: &str) -> Result<AppliedChange>;
105
106 /// Run a runtime-approved check command.
107 async fn run_checks(&self, command: &str) -> Result<CheckResult>;
108
109 /// Revert a still-current last change.
110 async fn revert_last_change(&self, change_id: &str) -> Result<AppliedChange>;
111
112 /// Submit a prompt and optional validated proposal to the active runtime.
113 async fn request_turn(&self, prompt: &str, proposal_id: Option<&str>) -> Result<TurnResult>;
114
115 /// Cancel a runtime request.
116 ///
117 /// The boolean reports whether an active operation was found and accepted
118 /// for cancellation. Unknown or already-complete identifiers are not
119 /// errors, which keeps reconnecting clients idempotent.
120 async fn cancel(&self, _target_id: &str) -> Result<bool> {
121 Ok(false)
122 }
123}