313 lines
9.9 KiB
Protocol Buffer
313 lines
9.9 KiB
Protocol Buffer
// A protobuf-based API for communication between
|
|
// the Warp client and the remote server binary.
|
|
//
|
|
// Messages are length-prefixed: [4-byte little-endian length][protobuf bytes].
|
|
|
|
syntax = "proto3";
|
|
|
|
package remote_server;
|
|
|
|
// ── Top-level envelopes ───────────────────────────────────────────
|
|
|
|
// Top-level envelope for all client → server messages.
|
|
message ClientMessage {
|
|
string request_id = 1;
|
|
oneof message {
|
|
Initialize initialize = 2;
|
|
Abort abort = 3;
|
|
NavigatedToDirectory navigated_to_directory = 4;
|
|
LoadRepoMetadataDirectory load_repo_metadata_directory = 5;
|
|
SessionBootstrapped session_bootstrapped = 6;
|
|
WriteFile write_file = 7;
|
|
DeleteFile delete_file = 8;
|
|
RunCommandRequest run_command = 9;
|
|
ReadFileContextRequest read_file_context = 10;
|
|
Authenticate authenticate = 11;
|
|
}
|
|
}
|
|
// Top-level envelope for all server → client messages.
|
|
// Push messages use an empty request_id to distinguish them from
|
|
// request/response pairs.
|
|
message ServerMessage {
|
|
string request_id = 1;
|
|
oneof message {
|
|
InitializeResponse initialize_response = 2;
|
|
ErrorResponse error = 3;
|
|
NavigatedToDirectoryResponse navigated_to_directory_response = 4;
|
|
RepoMetadataSnapshot repo_metadata_snapshot = 5;
|
|
RepoMetadataUpdatePush repo_metadata_update = 6;
|
|
LoadRepoMetadataDirectoryResponse load_repo_metadata_directory_response = 7;
|
|
WriteFileResponse write_file_response = 8;
|
|
DeleteFileResponse delete_file_response = 9;
|
|
RunCommandResponse run_command_response = 10;
|
|
ReadFileContextResponse read_file_context_response = 11;
|
|
}
|
|
}
|
|
|
|
// ── Initialize handshake
|
|
|
|
// Sent by the client immediately after connecting to negotiate the protocol.
|
|
message Initialize {
|
|
// Optional bearer token used by the daemon for Warp-server requests.
|
|
// Empty means no credential was available and does not clear an existing
|
|
// daemon credential.
|
|
string auth_token = 1;
|
|
}
|
|
|
|
// Sent by the client when its bearer credential rotates after initialization.
|
|
// This is a notification (fire-and-forget) — the server does not send a response.
|
|
message Authenticate {
|
|
// Optional bearer token used by the daemon for Warp-server requests.
|
|
// Empty means no credential was available and does not clear an existing
|
|
// daemon credential.
|
|
string auth_token = 1;
|
|
}
|
|
|
|
// Sent by the client to cancel an in-progress request.
|
|
// This is a notification (fire-and-forget) — the server does not send a response.
|
|
message Abort {
|
|
string request_id_to_abort = 1;
|
|
}
|
|
|
|
// Returned by the server in response to Initialize.
|
|
message InitializeResponse {
|
|
string server_version = 1;
|
|
string host_id = 2;
|
|
}
|
|
|
|
// Sent by the client after the SSH session has been bootstrapped.
|
|
// This is a notification (fire-and-forget) — the server does not send a
|
|
// response. The server uses this to create a per-session
|
|
// LocalCommandExecutor matching the bootstrapped shell.
|
|
message SessionBootstrapped {
|
|
uint64 session_id = 1;
|
|
string shell_type = 2;
|
|
// The full path to the shell binary (e.g. "/usr/bin/zsh").
|
|
// When present, the server uses this directly instead of doing a PATH lookup.
|
|
optional string shell_path = 3;
|
|
}
|
|
|
|
// Sent by the client to execute a shell command on the remote host.
|
|
message RunCommandRequest {
|
|
string command = 1;
|
|
// Working directory for the command. If empty, uses the server's default.
|
|
optional string working_directory = 2;
|
|
// Environment variables to set for the command.
|
|
map<string, string> environment_variables = 3;
|
|
// The session whose shell executor should run this command.
|
|
uint64 session_id = 4;
|
|
}
|
|
|
|
// Specific error codes for RunCommandRequest failures.
|
|
enum RunCommandErrorCode {
|
|
RUN_COMMAND_ERROR_CODE_UNSPECIFIED = 0;
|
|
// The session ID has no associated executor (session was never bootstrapped).
|
|
SESSION_NOT_FOUND = 1;
|
|
// The command could not be executed (e.g. the shell process failed to spawn).
|
|
EXECUTION_FAILED = 2;
|
|
}
|
|
|
|
message RunCommandError {
|
|
RunCommandErrorCode code = 1;
|
|
string message = 2;
|
|
}
|
|
|
|
message RunCommandSuccess {
|
|
bytes stdout = 1;
|
|
bytes stderr = 2;
|
|
// Absent when the process was killed by a signal (Unix).
|
|
optional int32 exit_code = 3;
|
|
}
|
|
|
|
// Returned by the server with the result of a RunCommandRequest.
|
|
message RunCommandResponse {
|
|
oneof result {
|
|
RunCommandSuccess success = 1;
|
|
RunCommandError error = 2;
|
|
}
|
|
}
|
|
|
|
// ── Shared error response ─────────────────────────────────────────
|
|
|
|
enum ErrorCode {
|
|
ERROR_CODE_UNSPECIFIED = 0;
|
|
// The request was malformed (e.g. missing oneof variant).
|
|
INVALID_REQUEST = 1;
|
|
// An unexpected server-side failure.
|
|
INTERNAL = 2;
|
|
}
|
|
|
|
message ErrorResponse {
|
|
ErrorCode code = 1;
|
|
string message = 2;
|
|
}
|
|
|
|
// ── Shared repo metadata sub-messages ─────────────────────────────
|
|
// Mirror the Rust types in repo_metadata/src/file_tree_update.rs.
|
|
|
|
// Mirrors RepoNodeMetadata in Rust.
|
|
message RepoNodeMetadata {
|
|
oneof node {
|
|
DirectoryNodeMetadata directory = 1;
|
|
FileNodeMetadata file = 2;
|
|
}
|
|
}
|
|
|
|
// Mirrors DirectoryNodeMetadata in Rust.
|
|
message DirectoryNodeMetadata {
|
|
string path = 1;
|
|
bool ignored = 2;
|
|
bool loaded = 3;
|
|
}
|
|
|
|
// Mirrors FileNodeMetadata in Rust.
|
|
message FileNodeMetadata {
|
|
string path = 1;
|
|
optional string extension = 2;
|
|
bool ignored = 3;
|
|
}
|
|
|
|
// Mirrors FileTreeEntryUpdate in Rust. Describes a subtree patch rooted
|
|
// at a parent directory.
|
|
message RepoMetadataEntryUpdate {
|
|
string parent_path_to_replace = 1;
|
|
repeated RepoNodeMetadata subtree_metadata = 2;
|
|
}
|
|
|
|
// ── NavigatedToDirectory ──────────────────────────────────────────
|
|
|
|
// Client → server: "I navigated to this directory, please index it."
|
|
message NavigatedToDirectory {
|
|
string path = 1;
|
|
}
|
|
|
|
// Response after the server has run git detection on the requested path.
|
|
// When is_git is true, indexed_path is the git repo root and full indexing
|
|
// runs in the background. A RepoMetadataSnapshot push will follow.
|
|
// When is_git is false, the directory was lazily indexed at first level.
|
|
// A RepoMetadataSnapshot push with the lazy tree data will follow.
|
|
message NavigatedToDirectoryResponse {
|
|
string indexed_path = 1;
|
|
bool is_git = 2;
|
|
}
|
|
|
|
// ── LoadRepoMetadataDirectory ─────────────────────────────────────
|
|
|
|
// Client → server: load the next level of a subdirectory within an
|
|
// already-tracked repo (lazy expand).
|
|
message LoadRepoMetadataDirectory {
|
|
string repo_path = 1;
|
|
string dir_path = 2;
|
|
}
|
|
|
|
// Response with the loaded subtree entries for the requested directory.
|
|
message LoadRepoMetadataDirectoryResponse {
|
|
string repo_path = 1;
|
|
string dir_path = 2;
|
|
repeated RepoMetadataEntryUpdate entries = 3;
|
|
}
|
|
|
|
// ── File write/delete operations ──────────────────────────────────
|
|
|
|
// Shared error type for file operations (read/write/delete).
|
|
message FileOperationError {
|
|
string message = 1;
|
|
}
|
|
|
|
// Client → server: write content to a file, creating parent dirs if needed.
|
|
message WriteFile {
|
|
string path = 1;
|
|
string content = 2;
|
|
}
|
|
|
|
// Server → client: result of a WriteFile request.
|
|
message WriteFileResponse {
|
|
oneof result {
|
|
WriteFileSuccess success = 1;
|
|
FileOperationError error = 2;
|
|
}
|
|
}
|
|
|
|
message WriteFileSuccess {}
|
|
|
|
// Client → server: delete a file.
|
|
message DeleteFile {
|
|
string path = 1;
|
|
}
|
|
|
|
// Server → client: result of a DeleteFile request.
|
|
message DeleteFileResponse {
|
|
oneof result {
|
|
DeleteFileSuccess success = 1;
|
|
FileOperationError error = 2;
|
|
}
|
|
}
|
|
|
|
message DeleteFileSuccess {}
|
|
|
|
// ── Read file context (batch) ─────────────────────────────────────
|
|
|
|
// A single file to read, with optional line ranges.
|
|
message ReadFileContextFile {
|
|
string path = 1;
|
|
// 1-indexed line ranges (start..end). Empty = read entire file.
|
|
repeated LineRange line_ranges = 2;
|
|
}
|
|
|
|
message LineRange {
|
|
uint32 start = 1;
|
|
uint32 end = 2;
|
|
}
|
|
|
|
// Client → server: batch read multiple files with full context.
|
|
message ReadFileContextRequest {
|
|
repeated ReadFileContextFile files = 1;
|
|
// Per-file byte limit. Absent = use server default.
|
|
optional uint32 max_file_bytes = 2;
|
|
// Cumulative byte budget across all files. Absent = no batch limit.
|
|
optional uint32 max_batch_bytes = 3;
|
|
}
|
|
|
|
// Server → client: result of a ReadFileContextRequest.
|
|
// Per-file failures are reported in `failed_files`, not as a top-level error.
|
|
// Catastrophic server errors (malformed request, etc.) use the generic ErrorResponse.
|
|
message ReadFileContextResponse {
|
|
repeated FileContextProto file_contexts = 1;
|
|
repeated FailedFileRead failed_files = 2;
|
|
}
|
|
|
|
message FailedFileRead {
|
|
string path = 1;
|
|
FileOperationError error = 2;
|
|
}
|
|
|
|
message FileContextProto {
|
|
string file_name = 1;
|
|
oneof content {
|
|
string text_content = 2;
|
|
bytes binary_content = 3;
|
|
}
|
|
// Optional 1-indexed line range this segment covers.
|
|
optional uint32 line_range_start = 4;
|
|
optional uint32 line_range_end = 5;
|
|
optional uint64 last_modified_epoch_millis = 6;
|
|
uint32 line_count = 7;
|
|
}
|
|
|
|
// ── Server → client push messages ─────────────────────────────────
|
|
|
|
// Full or lazy-loaded repo metadata snapshot. Pushed by the server after
|
|
// NavigatedToDirectory completes indexing (either lazy or full git).
|
|
message RepoMetadataSnapshot {
|
|
string repo_path = 1;
|
|
repeated RepoMetadataEntryUpdate entries = 2;
|
|
bool sync_complete = 3;
|
|
}
|
|
|
|
// Incremental repo metadata update. Mirrors RepoMetadataUpdate in Rust.
|
|
message RepoMetadataUpdatePush {
|
|
string repo_path = 1;
|
|
repeated string remove_entries = 2;
|
|
repeated RepoMetadataEntryUpdate update_entries = 3;
|
|
}
|