Files
galaxy/crates/remote_server/proto/diff_state.proto
T

514 lines
16 KiB
Protocol Buffer
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Diff state protocol messages for communication between
// the Warp client and the remote server binary.
//
// These messages are used by the diff state subsystem to synchronize
// code review diff data between a remote daemon and the Warp client.
syntax = "proto3";
package remote_server;
// ── Diff state sub-messages ───────────────────────────────────────
// Mirror the Rust domain types in code_review/diff_state.rs.
// Mirrors DiffMode in Rust.
message DiffMode {
oneof mode {
DiffModeHead head = 1;
DiffModeMainBranch main_branch = 2;
DiffModeOtherBranch other_branch = 3;
}
}
message DiffModeHead {}
message DiffModeMainBranch {}
message DiffModeOtherBranch {
string branch_name = 1;
}
// Mirrors DiffState in Rust. After the wrapper split (§1), Loaded is a
// unit variant — the diff payload is carried separately in
// DiffStateSnapshot.diffs.
message DiffState {
oneof state {
DiffStateNotInRepository not_in_repository = 1;
DiffStateLoading loading = 2;
DiffStateErrorValue error = 3;
DiffStateLoaded loaded = 4;
}
}
message DiffStateNotInRepository {}
message DiffStateLoading {}
message DiffStateErrorValue {
string message = 1;
}
message DiffStateLoaded {}
// Mirrors DiffLineType in Rust.
enum DiffLineType {
DIFF_LINE_TYPE_UNSPECIFIED = 0;
DIFF_LINE_TYPE_CONTEXT = 1;
DIFF_LINE_TYPE_ADD = 2;
DIFF_LINE_TYPE_DELETE = 3;
DIFF_LINE_TYPE_HUNK_HEADER = 4;
}
// Represents a single line in a diff hunk, as rendered by `git diff`. Mirrors DiffLine in Rust.
message DiffLine {
DiffLineType line_type = 1;
optional uint64 old_line_number = 2;
optional uint64 new_line_number = 3;
string text = 4;
bool no_trailing_newline = 5;
}
// Represents a hunk of changes in a file diff, as rendered by `git diff`. Mirrors DiffHunk in Rust.
message DiffHunk {
uint64 old_start_line = 1;
uint64 old_line_count = 2;
uint64 new_start_line = 3;
uint64 new_line_count = 4;
repeated DiffLine lines = 5;
uint64 unified_diff_start = 6;
uint64 unified_diff_end = 7;
}
// Represents the status of a file in the git working directory. Mirrors GitFileStatus in Rust.
message GitFileStatus {
oneof status {
GitFileStatusNew new_file = 1;
GitFileStatusModified modified = 2;
GitFileStatusDeleted deleted = 3;
GitFileStatusRenamed renamed = 4;
GitFileStatusCopied copied = 5;
GitFileStatusUntracked untracked = 6;
GitFileStatusConflicted conflicted = 7;
}
}
message GitFileStatusNew {}
message GitFileStatusModified {}
message GitFileStatusDeleted {}
message GitFileStatusRenamed {
string old_path = 1;
}
message GitFileStatusCopied {
string old_path = 1;
}
message GitFileStatusUntracked {}
message GitFileStatusConflicted {}
// Mirrors DiffSize in Rust (diff_size_limits.rs).
enum DiffSize {
DIFF_SIZE_UNSPECIFIED = 0;
DIFF_SIZE_NORMAL = 1;
DIFF_SIZE_LARGE = 2;
// The diff/patch itself is too large to render. (Was DIFF_SIZE_UNRENDERABLE;
// value 3 is preserved for wire compatibility.)
DIFF_SIZE_UNRENDERABLE_DIFF_TOO_LARGE = 3;
// The base file content was withheld because it exceeded the per-file wire
// budget; the client renders a "file too large" placeholder.
DIFF_SIZE_UNRENDERABLE_FILE_TOO_LARGE = 4;
}
// Mirrors FileDiff + FileDiffAndContent in Rust.
// The two types are collapsed into a single message with an optional content_at_base field,
// since every wire context that sends a FileDiff also needs base content for editor rendering.
message FileDiff {
string file_path = 1;
GitFileStatus status = 2;
repeated DiffHunk hunks = 3;
bool is_binary = 4;
bool is_autogenerated = 5;
uint64 max_line_number = 6;
bool has_hidden_bidi_chars = 7;
DiffSize size = 8;
// File content at HEAD or merge-base, used by the code review editor to
// render inline diff decorations (set_base). Absent for binary files, for
// files whose content exceeds the per-file wire budget (size =
// DIFF_SIZE_UNRENDERABLE_FILE_TOO_LARGE), or when git show fails.
optional string content_at_base = 9;
// Number of complete conflict-marker blocks in the working-tree file.
uint64 conflict_count = 10;
}
// Represents the complete git diff information for a repository. Mirrors GitDiffData in Rust.
message GitDiffData {
repeated FileDiff files = 1;
uint64 total_additions = 2;
uint64 total_deletions = 3;
uint64 files_changed = 4;
}
// Mirrors DiffStats in Rust.
message DiffStats {
uint64 files_changed = 1;
uint64 total_additions = 2;
uint64 total_deletions = 3;
}
// Mirrors DiffMetadataAgainstBase in Rust.
message DiffMetadataAgainstBase {
DiffStats aggregate_stats = 1;
// Per-file change entries for this base, captured from the same numstat that
// produces aggregate_stats so the git dialog's Changes box can render
// without a working-tree read (lets the box populate for remote repos).
repeated FileChangeEntry files = 2;
}
// Mirrors Commit in Rust (util/git.rs).
message Commit {
string hash = 1;
string subject = 2;
uint64 files_changed = 3;
uint64 additions = 4;
uint64 deletions = 5;
// Per-file changes in this commit, captured up front so the push dialog can
// render a commit's file list on expansion without a follow-up RPC.
repeated FileChangeEntry files = 6;
}
// Mirrors FileChangeEntry in Rust (util/git.rs).
message FileChangeEntry {
string path = 1;
uint64 additions = 2;
uint64 deletions = 3;
}
// Mirrors PrInfo in Rust (util/git.rs).
message PrInfo {
uint64 number = 1;
string url = 2;
string state = 3;
bool draft = 4;
string base_branch = 5;
}
// Mirrors DiffMetadata in Rust.
message DiffMetadata {
string main_branch_name = 1;
string current_branch_name = 2;
DiffMetadataAgainstBase against_head = 3;
optional DiffMetadataAgainstBase against_base_branch = 4;
bool has_head_commit = 5;
repeated Commit unpushed_commits = 6;
optional string upstream_ref = 7;
}
// Mirrors FileStatusInfo in Rust. Identifies a file and its git status
// for discard operations (git restore / git stash / git rm).
message FileStatusInfo {
string path = 1;
GitFileStatus status = 2;
}
// ── Diff state client → server ────────────────────────────────────
// Client → server: subscribe to diff state for a (repo, mode) pair.
// The server responds with GetDiffStateResponse, then pushes subsequent changes.
message GetDiffState {
string repo_path = 1;
DiffMode mode = 2;
}
// Client → server: unsubscribe from diff state updates for a (repo, mode) pair.
// Fire-and-forget — the server does not send a response.
message UnsubscribeDiffState {
string repo_path = 1;
DiffMode mode = 2;
}
// Client → server: discard changes for one or more files.
// Runs git restore/stash/rm on the remote filesystem.
message DiscardFilesRequest {
string repo_path = 1;
repeated FileStatusInfo files = 2;
bool should_stash = 3;
// Branch to restore against. Absent means HEAD.
optional string branch_name = 4;
// The diff mode identifying which DiffStateModel to use.
DiffMode mode = 5;
}
// ── Diff state server → client ────────────────────────────────────
// Error payload for GetDiffStateResponse.
message DiffStateError {
string message = 1;
}
// Full diff state snapshot for a (repo, mode) pair.
// Pushed on structural changes (NewDiffsComputed events).
message DiffStateSnapshot {
string repo_path = 1;
DiffMode mode = 2;
DiffMetadata metadata = 3;
DiffState state = 4;
// Present when state is Loaded.
optional GitDiffData diffs = 5;
}
// Response to GetDiffState.
message GetDiffStateResponse {
oneof result {
DiffStateSnapshot snapshot = 1;
DiffStateError error = 2;
}
}
// Metadata-only update pushed for MetadataRefreshed and
// CurrentBranchChanged events. Avoids re-serializing the entire diff
// payload on every throttled refresh.
message DiffStateMetadataUpdate {
string repo_path = 1;
DiffMode mode = 2;
DiffMetadata metadata = 3;
}
// Single-file diff delta pushed for SingleFileUpdated events.
// Carries one FileDiff + file path + updated metadata.
// Debounced at 2s on the server.
message DiffStateFileDelta {
string repo_path = 1;
DiffMode mode = 2;
string file_path = 3;
optional FileDiff diff = 4;
optional DiffMetadata metadata = 5;
}
// Server → client: result of a DiscardFilesRequest.
message DiscardFilesResponse {
oneof result {
DiscardFilesSuccess success = 1;
DiscardFilesError error = 2;
}
}
message DiscardFilesSuccess {}
message DiscardFilesError {
string message = 1;
}
// ── Branch listing ────────────────────────────────────────────────
// Client → server: list branches for a repository.
message GetBranches {
string repo_path = 1;
// Maximum number of branches to return. Absent = server default (100).
optional uint32 max_branch_count = 2;
// Whether to include remote-tracking branches (refs/remotes).
bool include_remotes = 3;
}
// A single branch entry.
message BranchInfo {
string name = 1;
bool is_main = 2;
}
// Server → client: result of a GetBranches request.
message GetBranchesResponse {
oneof result {
GetBranchesSuccess success = 1;
GetBranchesError error = 2;
}
}
message GetBranchesSuccess {
repeated BranchInfo branches = 1;
}
message GetBranchesError {
string message = 1;
}
// ── Git operations (commit / push / create-PR) ────────────────────
// Run git / gh on the remote filesystem. These mirror the local code
// review git dialog operations in app/src/code_review/git_dialog/*.
// Shared error payload for git operation responses. The message is the
// raw git/gh error, mapped to user-facing copy on the client.
message GitOpError {
string message = 1;
}
// Post-operation delta applied to DiffMetadata so the client refreshes the
// header immediately, without waiting for the next watcher-driven snapshot.
message GitOpDelta {
repeated Commit unpushed_commits = 1;
optional string upstream_ref = 2;
}
// Client → server: run the commit chain (commit, then optionally push, then
// optionally create-PR) host-local in a single round trip. The daemon
// sequences the underlying git / gh subprocesses (see handle_git_commit_chain), so
// the SSH link carries one request/response instead of the 23 a client-side
// chain would send.
message GitCommitChainRequest {
string repo_path = 1;
string message = 2;
bool include_unstaged = 3;
// Branch to push / open the PR against. Ignored for COMMIT_ONLY.
string branch = 4;
GitCommitChainMode mode = 5;
// When mode is COMMIT_AND_CREATE_PR, generate the PR title/body via AI on the
// daemon (get_diff_for_pr + generate_code_review_content), falling back to
// `gh pr create --fill`. Ignored for the other modes.
bool autogenerate_pr_content = 6;
}
// What to run after the commit succeeds.
enum GitCommitChainMode {
GIT_COMMIT_CHAIN_MODE_COMMIT_ONLY = 0;
GIT_COMMIT_CHAIN_MODE_COMMIT_AND_PUSH = 1;
GIT_COMMIT_CHAIN_MODE_COMMIT_AND_CREATE_PR = 2;
}
message GitCommitChainResponse {
oneof result {
GitCommitChainSuccess success = 1;
GitOpError error = 2;
}
}
// Final post-chain delta plus the PR when one was created (absent for
// COMMIT_ONLY / COMMIT_AND_PUSH).
message GitCommitChainSuccess {
GitOpDelta delta = 1;
optional PrInfo pr_info = 2;
}
// Client → server: push `branch` to origin, setting upstream tracking.
message GitPushRequest {
string repo_path = 1;
string branch = 2;
}
message GitPushResponse {
oneof result {
GitOpDelta success = 1;
GitOpError error = 2;
}
}
// Client → server: create a PR for the current branch (must be pushed).
// Absent title/body => `gh pr create --fill`, unless autogenerate_content is
// set (then the daemon generates the title/body via AI first).
message GitCreatePrRequest {
string repo_path = 1;
// Current branch name, passed as context to daemon-side AI generation.
string branch = 2;
// When true and title/body are both absent, the daemon generates the PR
// title + body via AI (get_diff_for_pr + generate_code_review_content)
// before running `gh pr create`, falling back to `--fill` on failure.
bool autogenerate_content = 3;
}
message GitCreatePrResponse {
oneof result {
PrInfo success = 1;
GitOpError error = 2;
}
}
// Client → server: list the committed file changes for the current branch's
// PR-ready diff (merge_base(HEAD, main)..HEAD). Backs the Create PR dialog's
// Changes box; deliberately committed-only (no working-tree edits, no
// untracked files) so it matches what `gh pr create` would include.
message GitGetCommittedBranchFilesRequest {
string repo_path = 1;
}
message GitGetCommittedBranchFilesResponse {
oneof result {
GitGetCommittedBranchFilesSuccess success = 1;
GitOpError error = 2;
}
}
message GitGetCommittedBranchFilesSuccess {
repeated FileChangeEntry files = 1;
}
// Client → server: generate a commit message via AI on the remote host.
// The daemon computes the working-tree diff locally and calls the Warp
// server's code-review content endpoint, returning the message string. Sent
// at commit-dialog open time, mirroring the local open-time autogen.
message GitGenerateCommitMessageRequest {
string repo_path = 1;
// Whether to include unstaged changes in the diff sent to AI (mirrors the
// commit dialog's include-unstaged toggle).
bool include_unstaged = 2;
// Current branch name, passed as context to the AI request.
string branch_name = 3;
}
message GitGenerateCommitMessageResponse {
oneof result {
// The generated commit message (already trimmed, non-empty).
string message = 1;
GitOpError error = 2;
}
}
// ── Git and GitHub info ──────────────────────────────────────────────────
// Mirrors RepositoryInfo in Rust (util/git.rs). Returned by `gh repo view`.
message RepositoryInfo {
string name = 1;
optional string owner = 2;
}
// Mirrors GitStatusMetadata in Rust (code_review/git_repo_model/mod.rs).
message GitStatusMetadata {
string current_branch_name = 1;
string main_branch_name = 2;
DiffStats stats_against_head = 3;
optional string tracking_upstream = 4;
uint32 tracking_ahead = 5;
uint32 tracking_behind = 6;
bool tracking_counts_available = 7;
}
// Server -> client push: aggregate git status for a repo. Sent on every
// watcher tick, opportunistically after navigation resolves a git root, and
// when a client requests a current snapshot.
message GitStatusPush {
string repo_path = 1;
GitStatusMetadata metadata = 2;
}
// Client -> server notification: ask the daemon to create the per-repo git
// status model if needed and push the current GitStatusPush snapshot when
// available. Fire-and-forget; no response is sent.
message UpdateGitStatus {
string repo_path = 1;
}
// Server -> client push: PR info for a repo's current branch. Sent when the
// daemon's `GitHubRepoModel` recomputes PR info.
message GitHubPrInfoPush {
string repo_path = 1;
optional PrInfo pr_info = 2;
}
// Server -> client push: repository name/owner info for a repo. Sent when the
// daemon's `GitHubRepoModel` recomputes repository info.
message GitHubRepositoryInfoPush {
string repo_path = 1;
optional RepositoryInfo repository_info = 2;
}
// Client -> server notification: ask the daemon to create the per-repo
// GitHubRepoModel if needed and refresh PR info for the current branch. The
// result is delivered as a `GitHubPrInfoPush` broadcast (single source of
// truth: the daemon's `GitHubRepoModel`). Fire-and-forget; no response.
message UpdateGitHubPrInfo {
string repo_path = 1;
}
// Client -> server notification: ask the daemon to create the per-repo
// GitHubRepoModel if needed and refresh repository name/owner. The result is
// delivered as a `GitHubRepositoryInfoPush` broadcast. Fire-and-forget; no
// response.
message UpdateGitHubRepoInfo {
string repo_path = 1;
}