syntax = "proto3";
package zed.messages;

// Looking for a number? Search "// current max"

message PeerId {
    uint32 owner_id = 1;
    uint32 id = 2;
}

message Envelope {
    uint32 id = 1;
    optional uint32 responding_to = 2;
    optional PeerId original_sender_id = 3;

    oneof payload {
        Hello hello = 4;
        Ack ack = 5;
        Error error = 6;
        Ping ping = 7;
        Test test = 8;
        EndStream end_stream = 165;

        CreateRoom create_room = 9;
        CreateRoomResponse create_room_response = 10;
        JoinRoom join_room = 11;
        JoinRoomResponse join_room_response = 12;
        RejoinRoom rejoin_room = 13;
        RejoinRoomResponse rejoin_room_response = 14;
        LeaveRoom leave_room = 15;
        Call call = 16;
        IncomingCall incoming_call = 17;
        CallCanceled call_canceled = 18;
        CancelCall cancel_call = 19;
        DeclineCall decline_call = 20;
        UpdateParticipantLocation update_participant_location = 21;
        RoomUpdated room_updated = 22;

        ShareProject share_project = 23;
        ShareProjectResponse share_project_response = 24;
        UnshareProject unshare_project = 25;
        JoinProject join_project = 26;
        JoinProjectResponse join_project_response = 27;
        LeaveProject leave_project = 28;
        AddProjectCollaborator add_project_collaborator = 29;
        UpdateProjectCollaborator update_project_collaborator = 30;
        RemoveProjectCollaborator remove_project_collaborator = 31;

        GetDefinition get_definition = 32;
        GetDefinitionResponse get_definition_response = 33;
        GetDeclaration get_declaration = 237;
        GetDeclarationResponse get_declaration_response = 238;
        GetTypeDefinition get_type_definition = 34;
        GetTypeDefinitionResponse get_type_definition_response = 35;

        GetReferences get_references = 36;
        GetReferencesResponse get_references_response = 37;
        GetDocumentHighlights get_document_highlights = 38;
        GetDocumentHighlightsResponse get_document_highlights_response = 39;
        GetProjectSymbols get_project_symbols = 40;
        GetProjectSymbolsResponse get_project_symbols_response = 41;
        OpenBufferForSymbol open_buffer_for_symbol = 42;
        OpenBufferForSymbolResponse open_buffer_for_symbol_response = 43;

        UpdateProject update_project = 44;
        UpdateWorktree update_worktree = 45;

        CreateProjectEntry create_project_entry = 46;
        RenameProjectEntry rename_project_entry = 47;
        CopyProjectEntry copy_project_entry = 48;
        DeleteProjectEntry delete_project_entry = 49;
        ProjectEntryResponse project_entry_response = 50;
        ExpandProjectEntry expand_project_entry = 51;
        ExpandProjectEntryResponse expand_project_entry_response = 52;

        UpdateDiagnosticSummary update_diagnostic_summary = 53;
        StartLanguageServer start_language_server = 54;
        UpdateLanguageServer update_language_server = 55;

        OpenBufferById open_buffer_by_id = 56;
        OpenBufferByPath open_buffer_by_path = 57;
        OpenBufferResponse open_buffer_response = 58;
        CreateBufferForPeer create_buffer_for_peer = 59;
        UpdateBuffer update_buffer = 60;
        UpdateBufferFile update_buffer_file = 61;
        SaveBuffer save_buffer = 62;
        BufferSaved buffer_saved = 63;
        BufferReloaded buffer_reloaded = 64;
        ReloadBuffers reload_buffers = 65;
        ReloadBuffersResponse reload_buffers_response = 66;
        SynchronizeBuffers synchronize_buffers = 67;
        SynchronizeBuffersResponse synchronize_buffers_response = 68;
        FormatBuffers format_buffers = 69;
        FormatBuffersResponse format_buffers_response = 70;
        GetCompletions get_completions = 71;
        GetCompletionsResponse get_completions_response = 72;
        ResolveCompletionDocumentation resolve_completion_documentation = 73;
        ResolveCompletionDocumentationResponse resolve_completion_documentation_response = 74;
        ApplyCompletionAdditionalEdits apply_completion_additional_edits = 75;
        ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 76;
        GetCodeActions get_code_actions = 77;
        GetCodeActionsResponse get_code_actions_response = 78;
        GetHover get_hover = 79;
        GetHoverResponse get_hover_response = 80;
        ApplyCodeAction apply_code_action = 81;
        ApplyCodeActionResponse apply_code_action_response = 82;
        PrepareRename prepare_rename = 83;
        PrepareRenameResponse prepare_rename_response = 84;
        PerformRename perform_rename = 85;
        PerformRenameResponse perform_rename_response = 86;

        UpdateContacts update_contacts = 89;
        UpdateInviteInfo update_invite_info = 90;
        ShowContacts show_contacts = 91;

        GetUsers get_users = 92;
        FuzzySearchUsers fuzzy_search_users = 93;
        UsersResponse users_response = 94;
        RequestContact request_contact = 95;
        RespondToContactRequest respond_to_contact_request = 96;
        RemoveContact remove_contact = 97;

        Follow follow = 98;
        FollowResponse follow_response = 99;
        UpdateFollowers update_followers = 100;
        Unfollow unfollow = 101;
        GetPrivateUserInfo get_private_user_info = 102;
        GetPrivateUserInfoResponse get_private_user_info_response = 103;
        UpdateUserPlan update_user_plan = 234;
        UpdateDiffBase update_diff_base = 104;
        AcceptTermsOfService accept_terms_of_service = 239;
        AcceptTermsOfServiceResponse accept_terms_of_service_response = 240;

        OnTypeFormatting on_type_formatting = 105;
        OnTypeFormattingResponse on_type_formatting_response = 106;

        UpdateWorktreeSettings update_worktree_settings = 107;

        InlayHints inlay_hints = 108;
        InlayHintsResponse inlay_hints_response = 109;
        ResolveInlayHint resolve_inlay_hint = 110;
        ResolveInlayHintResponse resolve_inlay_hint_response = 111;
        RefreshInlayHints refresh_inlay_hints = 112;

        CreateChannel create_channel = 113;
        CreateChannelResponse create_channel_response = 114;
        InviteChannelMember invite_channel_member = 115;
        RemoveChannelMember remove_channel_member = 116;
        RespondToChannelInvite respond_to_channel_invite = 117;
        UpdateChannels update_channels = 118;
        JoinChannel join_channel = 119;
        DeleteChannel delete_channel = 120;
        GetChannelMembers get_channel_members = 121;
        GetChannelMembersResponse get_channel_members_response = 122;
        SetChannelMemberRole set_channel_member_role = 123;
        RenameChannel rename_channel = 124;
        RenameChannelResponse rename_channel_response = 125;
        SubscribeToChannels subscribe_to_channels = 207;

        JoinChannelBuffer join_channel_buffer = 126;
        JoinChannelBufferResponse join_channel_buffer_response = 127;
        UpdateChannelBuffer update_channel_buffer = 128;
        LeaveChannelBuffer leave_channel_buffer = 129;
        UpdateChannelBufferCollaborators update_channel_buffer_collaborators = 130;
        RejoinChannelBuffers rejoin_channel_buffers = 131;
        RejoinChannelBuffersResponse rejoin_channel_buffers_response = 132;
        AckBufferOperation ack_buffer_operation = 133;

        JoinChannelChat join_channel_chat = 134;
        JoinChannelChatResponse join_channel_chat_response = 135;
        LeaveChannelChat leave_channel_chat = 136;
        SendChannelMessage send_channel_message = 137;
        SendChannelMessageResponse send_channel_message_response = 138;
        ChannelMessageSent channel_message_sent = 139;
        GetChannelMessages get_channel_messages = 140;
        GetChannelMessagesResponse get_channel_messages_response = 141;
        RemoveChannelMessage remove_channel_message = 142;
        AckChannelMessage ack_channel_message = 143;
        GetChannelMessagesById get_channel_messages_by_id = 144;

        MoveChannel move_channel = 147;
        SetChannelVisibility set_channel_visibility = 148;

        AddNotification add_notification = 149;
        GetNotifications get_notifications = 150;
        GetNotificationsResponse get_notifications_response = 151;
        DeleteNotification delete_notification = 152;
        MarkNotificationRead mark_notification_read = 153;
        LspExtExpandMacro lsp_ext_expand_macro = 154;
        LspExtExpandMacroResponse lsp_ext_expand_macro_response = 155;
        SetRoomParticipantRole set_room_participant_role = 156;

        UpdateUserChannels update_user_channels = 157;

        GetImplementation get_implementation = 162;
        GetImplementationResponse get_implementation_response = 163;

        JoinHostedProject join_hosted_project = 164;

        CountLanguageModelTokens count_language_model_tokens = 230;
        CountLanguageModelTokensResponse count_language_model_tokens_response = 231;
        GetCachedEmbeddings get_cached_embeddings = 189;
        GetCachedEmbeddingsResponse get_cached_embeddings_response = 190;
        ComputeEmbeddings compute_embeddings = 191;
        ComputeEmbeddingsResponse compute_embeddings_response = 192;

        UpdateChannelMessage update_channel_message = 170;
        ChannelMessageUpdate channel_message_update = 171;

        BlameBuffer blame_buffer = 172;
        BlameBufferResponse blame_buffer_response = 173;

        UpdateNotification update_notification = 174;

        MultiLspQuery multi_lsp_query = 175;
        MultiLspQueryResponse multi_lsp_query_response = 176;
        RestartLanguageServers restart_language_servers = 208;

        CreateDevServerProject create_dev_server_project = 177;
        CreateDevServerProjectResponse create_dev_server_project_response = 188;
        CreateDevServer create_dev_server = 178;
        CreateDevServerResponse create_dev_server_response = 179;
        ShutdownDevServer shutdown_dev_server = 180;
        DevServerInstructions dev_server_instructions = 181;
        ReconnectDevServer reconnect_dev_server = 182;
        ReconnectDevServerResponse reconnect_dev_server_response = 183;

        ShareDevServerProject share_dev_server_project = 184;
        JoinDevServerProject join_dev_server_project = 185;
        RejoinRemoteProjects rejoin_remote_projects = 186;
        RejoinRemoteProjectsResponse rejoin_remote_projects_response = 187;

        DevServerProjectsUpdate dev_server_projects_update = 193;
        ValidateDevServerProjectRequest validate_dev_server_project_request = 194;
        DeleteDevServer delete_dev_server = 195;
        OpenNewBuffer open_new_buffer = 196;
        DeleteDevServerProject delete_dev_server_project = 197;

        GetSupermavenApiKey get_supermaven_api_key = 198;
        GetSupermavenApiKeyResponse get_supermaven_api_key_response = 199;

        RegenerateDevServerToken regenerate_dev_server_token = 200;
        RegenerateDevServerTokenResponse regenerate_dev_server_token_response = 201;
        RenameDevServer rename_dev_server = 202;

        TaskContextForLocation task_context_for_location = 203;
        TaskContext task_context = 204;

        LinkedEditingRange linked_editing_range = 209;
        LinkedEditingRangeResponse linked_editing_range_response = 210;

        AdvertiseContexts advertise_contexts = 211;
        OpenContext open_context = 212;
        OpenContextResponse open_context_response = 213;
        CreateContext create_context = 232;
        CreateContextResponse create_context_response = 233;
        UpdateContext update_context = 214;
        SynchronizeContexts synchronize_contexts = 215;
        SynchronizeContextsResponse synchronize_contexts_response = 216;

        GetSignatureHelp get_signature_help = 217;
        GetSignatureHelpResponse get_signature_help_response = 218;

        ListRemoteDirectory list_remote_directory = 219;
        ListRemoteDirectoryResponse list_remote_directory_response = 220;
        UpdateDevServerProject update_dev_server_project = 221;
        AddWorktree add_worktree = 222;
        AddWorktreeResponse add_worktree_response = 223;

        GetLlmToken get_llm_token = 235;
        GetLlmTokenResponse get_llm_token_response = 236;

        LspExtSwitchSourceHeader lsp_ext_switch_source_header = 241;
        LspExtSwitchSourceHeaderResponse lsp_ext_switch_source_header_response = 242;

        FindSearchCandidates find_search_candidates = 243;
        FindSearchCandidatesResponse find_search_candidates_response = 244;

        CloseBuffer close_buffer = 245;
        UpdateUserSettings update_user_settings = 246;

        CheckFileExists check_file_exists = 255;
        CheckFileExistsResponse check_file_exists_response = 256;

        ShutdownRemoteServer shutdown_remote_server = 257;

        RemoveWorktree remove_worktree = 258; // current max
    }

    reserved 87 to 88;
    reserved 158 to 161;
    reserved 166 to 169;
    reserved 205 to 206;
    reserved 224 to 229;
    reserved 247 to 254;
}

// Messages

message Hello {
    PeerId peer_id = 1;
}

message Ping {}

message Ack {}

message Error {
    string message = 1;
    ErrorCode code = 2;
    repeated string tags = 3;
}

enum ErrorCode {
    Internal = 0;
    NoSuchChannel = 1;
    Disconnected = 2;
    SignedOut = 3;
    UpgradeRequired = 4;
    Forbidden = 5;
    NeedsCla = 7;
    NotARootChannel = 8;
    BadPublicNesting = 9;
    CircularNesting = 10;
    WrongMoveTarget = 11;
    UnsharedItem = 12;
    NoSuchProject = 13;
    DevServerAlreadyOnline = 14;
    DevServerOffline = 15;
    DevServerProjectPathDoesNotExist = 16;
    RemoteUpgradeRequired = 17;
    RateLimitExceeded = 18;
    reserved 6;
}

message EndStream {}

message Test {
    uint64 id = 1;
}

message CreateRoom {}

message CreateRoomResponse {
    Room room = 1;
    optional LiveKitConnectionInfo live_kit_connection_info = 2;
}

message JoinRoom {
    uint64 id = 1;
}

message JoinRoomResponse {
    Room room = 1;
    optional uint64 channel_id = 2;
    optional LiveKitConnectionInfo live_kit_connection_info = 3;
}

message RejoinRoom {
    uint64 id = 1;
    repeated UpdateProject reshared_projects = 2;
    repeated RejoinProject rejoined_projects = 3;
}
message RejoinRemoteProjects {
    repeated RejoinProject rejoined_projects = 1;
}

message RejoinRemoteProjectsResponse {
    repeated RejoinedProject rejoined_projects = 1;
}

message RejoinProject {
    uint64 id = 1;
    repeated RejoinWorktree worktrees = 2;
}

message RejoinWorktree {
    uint64 id = 1;
    uint64 scan_id = 2;
}

message RejoinRoomResponse {
    Room room = 1;
    repeated ResharedProject reshared_projects = 2;
    repeated RejoinedProject rejoined_projects = 3;
}

message ResharedProject {
    uint64 id = 1;
    repeated Collaborator collaborators = 2;
}

message RejoinedProject {
    uint64 id = 1;
    repeated WorktreeMetadata worktrees = 2;
    repeated Collaborator collaborators = 3;
    repeated LanguageServer language_servers = 4;
}

message LeaveRoom {}

message Room {
    uint64 id = 1;
    repeated Participant participants = 2;
    repeated PendingParticipant pending_participants = 3;
    repeated Follower followers = 4;
    string live_kit_room = 5;
}

message Participant {
    uint64 user_id = 1;
    PeerId peer_id = 2;
    repeated ParticipantProject projects = 3;
    ParticipantLocation location = 4;
    uint32 participant_index = 5;
    ChannelRole role = 6;
    reserved 7;
}

message PendingParticipant {
    uint64 user_id = 1;
    uint64 calling_user_id = 2;
    optional uint64 initial_project_id = 3;
}

message ParticipantProject {
    uint64 id = 1;
    repeated string worktree_root_names = 2;
}

message Follower {
    PeerId leader_id = 1;
    PeerId follower_id = 2;
    uint64 project_id = 3;
}

message ParticipantLocation {
    oneof variant {
        SharedProject shared_project = 1;
        UnsharedProject unshared_project = 2;
        External external = 3;
    }

    message SharedProject {
        uint64 id = 1;
    }

    message UnsharedProject {}

    message External {}
}

message Call {
    uint64 room_id = 1;
    uint64 called_user_id = 2;
    optional uint64 initial_project_id = 3;
}

message IncomingCall {
    uint64 room_id = 1;
    uint64 calling_user_id = 2;
    repeated uint64 participant_user_ids = 3;
    optional ParticipantProject initial_project = 4;
}

message CallCanceled {
    uint64 room_id = 1;
}

message CancelCall {
    uint64 room_id = 1;
    uint64 called_user_id = 2;
}

message DeclineCall {
    uint64 room_id = 1;
}

message UpdateParticipantLocation {
    uint64 room_id = 1;
    ParticipantLocation location = 2;
}

message RoomUpdated {
    Room room = 1;
}

message LiveKitConnectionInfo {
    string server_url = 1;
    string token = 2;
    bool can_publish = 3;
}

message ShareProject {
    uint64 room_id = 1;
    repeated WorktreeMetadata worktrees = 2;
    optional uint64 dev_server_project_id = 3;
    bool is_ssh_project = 4;
}

message ShareProjectResponse {
    uint64 project_id = 1;
}

message UnshareProject {
    uint64 project_id = 1;
}

message UpdateProject {
    uint64 project_id = 1;
    repeated WorktreeMetadata worktrees = 2;
}

message JoinProject {
    uint64 project_id = 1;
}

message JoinHostedProject {
    uint64 project_id = 1;
}

message CreateDevServerProject {
    reserved 1;
    reserved 2;
    uint64 dev_server_id = 3;
    string path = 4;
}
message CreateDevServerProjectResponse {
    DevServerProject dev_server_project = 1;
}

message ValidateDevServerProjectRequest {
    string path = 1;
}

message ListRemoteDirectory {
    uint64 dev_server_id = 1;
    string path = 2;
}

message ListRemoteDirectoryResponse {
    repeated string entries = 1;
}

message UpdateDevServerProject {
    uint64 dev_server_project_id = 1;
    repeated string paths = 2;
}

message CreateDevServer {
    reserved 1;
    string name = 2;
    optional string ssh_connection_string = 3;
}

message RegenerateDevServerToken {
    uint64 dev_server_id = 1;
}

message RegenerateDevServerTokenResponse {
    uint64 dev_server_id = 1;
    string access_token = 2;
}

message CreateDevServerResponse {
    uint64 dev_server_id = 1;
    reserved 2;
    string access_token = 3;
    string name = 4;
}

message ShutdownDevServer {
    optional string reason = 1;
}

message RenameDevServer {
    uint64 dev_server_id = 1;
    string name = 2;
    optional string ssh_connection_string = 3;
}

message DeleteDevServer {
    uint64 dev_server_id = 1;
}

message DeleteDevServerProject {
    uint64 dev_server_project_id = 1;
}

message ReconnectDevServer {
    repeated UpdateProject reshared_projects = 1;
}

message ReconnectDevServerResponse {
    repeated ResharedProject reshared_projects = 1;
}

message DevServerInstructions {
    repeated DevServerProject projects = 1;
}

message DevServerProjectsUpdate {
    repeated DevServer dev_servers = 1;
    repeated DevServerProject dev_server_projects = 2;
}

message ShareDevServerProject {
    uint64 dev_server_project_id = 1;
    repeated WorktreeMetadata worktrees = 2;
}

message JoinDevServerProject {
    uint64 dev_server_project_id = 1;
}

message JoinProjectResponse {
    uint64 project_id = 5;
    uint32 replica_id = 1;
    repeated WorktreeMetadata worktrees = 2;
    repeated Collaborator collaborators = 3;
    repeated LanguageServer language_servers = 4;
    ChannelRole role = 6;
    optional uint64 dev_server_project_id = 7;
}

message LeaveProject {
    uint64 project_id = 1;
}

message UpdateWorktree {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string root_name = 3;
    repeated Entry updated_entries = 4;
    repeated uint64 removed_entries = 5;
    repeated RepositoryEntry updated_repositories = 6;
    repeated uint64 removed_repositories = 7;
    uint64 scan_id = 8;
    bool is_last_update = 9;
    string abs_path = 10;
}

message UpdateWorktreeSettings {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
    optional string content = 4;
    optional LocalSettingsKind kind = 5;
}

enum LocalSettingsKind {
    Settings = 0;
    Tasks = 1;
    Editorconfig = 2;
}

message CreateProjectEntry {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
    bool is_directory = 4;
}

message RenameProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
    string new_path = 3;
}

message CopyProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
    string new_path = 3;
    optional string relative_worktree_source_path = 4;
}

message DeleteProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
    bool use_trash = 3;
}

message ExpandProjectEntry {
    uint64 project_id = 1;
    uint64 entry_id = 2;
}

message ExpandProjectEntryResponse {
    uint64 worktree_scan_id = 1;
}

message ProjectEntryResponse {
    optional Entry entry = 1;
    uint64 worktree_scan_id = 2;
}

message AddProjectCollaborator {
    uint64 project_id = 1;
    Collaborator collaborator = 2;
}

message UpdateProjectCollaborator {
    uint64 project_id = 1;
    PeerId old_peer_id = 2;
    PeerId new_peer_id = 3;
}

message RemoveProjectCollaborator {
    uint64 project_id = 1;
    PeerId peer_id = 2;
}

message UpdateChannelBufferCollaborators {
    uint64 channel_id = 1;
    repeated Collaborator collaborators = 2;
}

message GetDefinition {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
}

message GetDefinitionResponse {
    repeated LocationLink links = 1;
}

message GetDeclaration {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
}

message GetDeclarationResponse {
    repeated LocationLink links = 1;
}

message GetTypeDefinition {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetTypeDefinitionResponse {
    repeated LocationLink links = 1;
}
message GetImplementation {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetImplementationResponse {
    repeated LocationLink links = 1;
}

message GetReferences {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetReferencesResponse {
    repeated Location locations = 1;
}

message GetDocumentHighlights {
     uint64 project_id = 1;
     uint64 buffer_id = 2;
     Anchor position = 3;
     repeated VectorClockEntry version = 4;
 }

message GetDocumentHighlightsResponse {
    repeated DocumentHighlight highlights = 1;
}

message Location {
    uint64 buffer_id = 1;
    Anchor start = 2;
    Anchor end = 3;
}

message LocationLink {
    optional Location origin = 1;
    Location target = 2;
}

message DocumentHighlight {
    Kind kind = 1;
    Anchor start = 2;
    Anchor end = 3;

    enum Kind {
        Text = 0;
        Read = 1;
        Write = 2;
    }
}

message GetProjectSymbols {
    uint64 project_id = 1;
    string query = 2;
}

message GetProjectSymbolsResponse {
    repeated Symbol symbols = 4;
}

message Symbol {
    uint64 source_worktree_id = 1;
    uint64 worktree_id = 2;
    string language_server_name = 3;
    string name = 4;
    int32 kind = 5;
    string path = 6;
    // Cannot use generate anchors for unopened files,
    // so we are forced to use point coords instead
    PointUtf16 start = 7;
    PointUtf16 end = 8;
    bytes signature = 9;
}

message OpenBufferForSymbol {
    uint64 project_id = 1;
    Symbol symbol = 2;
}

message OpenBufferForSymbolResponse {
    uint64 buffer_id = 1;
}

message OpenBufferByPath {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    string path = 3;
}

message OpenBufferById {
    uint64 project_id = 1;
    uint64 id = 2;
}

message OpenNewBuffer {
    uint64 project_id = 1;
}

message OpenBufferResponse {
    uint64 buffer_id = 1;
}

message CreateBufferForPeer {
    uint64 project_id = 1;
    PeerId peer_id = 2;
    oneof variant {
        BufferState state = 3;
        BufferChunk chunk = 4;
    }
}

message UpdateBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated Operation operations = 3;
}

message UpdateChannelBuffer {
    uint64 channel_id = 1;
    repeated Operation operations = 2;
}

message UpdateBufferFile {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    File file = 3;
}

message SaveBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    optional ProjectPath new_path = 4;
}

message CloseBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
}

message ProjectPath {
    uint64 worktree_id = 1;
    string path = 2;
}

message BufferSaved {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    Timestamp mtime = 4;
    reserved 5;
}

message BufferReloaded {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    Timestamp mtime = 4;
    reserved 5;
    LineEnding line_ending = 6;
}

message ReloadBuffers {
    uint64 project_id = 1;
    repeated uint64 buffer_ids = 2;
}

message ReloadBuffersResponse {
    ProjectTransaction transaction = 1;
}

message SynchronizeBuffers {
    uint64 project_id = 1;
    repeated BufferVersion buffers = 2;
}

message SynchronizeBuffersResponse {
    repeated BufferVersion buffers = 1;
}

message BufferVersion {
    uint64 id = 1;
    repeated VectorClockEntry version = 2;
}

message ChannelBufferVersion {
    uint64 channel_id = 1;
    repeated VectorClockEntry version = 2;
    uint64 epoch = 3;
}

enum FormatTrigger {
    Save = 0;
    Manual = 1;
}

message FormatBuffers {
    uint64 project_id = 1;
    FormatTrigger trigger = 2;
    repeated uint64 buffer_ids = 3;
}

message FormatBuffersResponse {
    ProjectTransaction transaction = 1;
}

message GetCompletions {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message GetCompletionsResponse {
    repeated Completion completions = 1;
    repeated VectorClockEntry version = 2;
}

message ApplyCompletionAdditionalEdits {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Completion completion = 3;
}

message ApplyCompletionAdditionalEditsResponse {
    Transaction transaction = 1;
}

message Completion {
    Anchor old_start = 1;
    Anchor old_end = 2;
    string new_text = 3;
    uint64 server_id = 4;
    bytes lsp_completion = 5;
}

message GetCodeActions {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor start = 3;
    Anchor end = 4;
    repeated VectorClockEntry version = 5;
}

message GetCodeActionsResponse {
    repeated CodeAction actions = 1;
    repeated VectorClockEntry version = 2;
}

message GetSignatureHelp {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message GetSignatureHelpResponse {
    optional SignatureHelp signature_help = 1;
}

message SignatureHelp {
    repeated SignatureInformation signatures = 1;
    optional uint32 active_signature = 2;
    optional uint32 active_parameter = 3;
}

message SignatureInformation {
    string label = 1;
    optional Documentation documentation = 2;
    repeated ParameterInformation parameters = 3;
    optional uint32 active_parameter = 4;
}

message Documentation {
    oneof content {
        string value = 1;
        MarkupContent markup_content = 2;
    }
}

enum MarkupKind {
    PlainText = 0;
    Markdown = 1;
}

message ParameterInformation {
    oneof label {
        string simple = 1;
        LabelOffsets label_offsets = 2;
    }
    optional Documentation documentation = 3;
}

message LabelOffsets {
    uint32 start = 1;
    uint32 end = 2;
}

message GetHover {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 5;
}

message GetHoverResponse {
    optional Anchor start = 1;
    optional Anchor end = 2;
    repeated HoverBlock contents = 3;
}

message HoverBlock {
    string text = 1;
    optional string language = 2;
    bool is_markdown = 3;
}

message ApplyCodeAction {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    CodeAction action = 3;
}

message ApplyCodeActionResponse {
    ProjectTransaction transaction = 1;
}

message PrepareRename {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message PrepareRenameResponse {
    bool can_rename = 1;
    Anchor start = 2;
    Anchor end = 3;
    repeated VectorClockEntry version = 4;
}

message PerformRename {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    string new_name = 4;
    repeated VectorClockEntry version = 5;
}

message OnTypeFormatting {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    string trigger = 4;
    repeated VectorClockEntry version = 5;
}

message OnTypeFormattingResponse {
    Transaction transaction = 1;
}


message LinkedEditingRange {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
    repeated VectorClockEntry version = 4;
}

message AnchorRange {
    Anchor start = 1;
    Anchor end = 2;
}

message LinkedEditingRangeResponse {
    repeated AnchorRange items = 1;
    repeated VectorClockEntry version = 4;
}

message InlayHints {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor start = 3;
    Anchor end = 4;
    repeated VectorClockEntry version = 5;
}

message InlayHintsResponse {
    repeated InlayHint hints = 1;
    repeated VectorClockEntry version = 2;
}

message InlayHint {
    Anchor position = 1;
    InlayHintLabel label = 2;
    optional string kind = 3;
    bool padding_left = 4;
    bool padding_right = 5;
    InlayHintTooltip tooltip = 6;
    ResolveState resolve_state = 7;
}

message InlayHintLabel {
    oneof label {
        string value = 1;
        InlayHintLabelParts label_parts = 2;
    }
}

message InlayHintLabelParts {
    repeated InlayHintLabelPart parts = 1;
}

message InlayHintLabelPart {
    string value = 1;
    InlayHintLabelPartTooltip tooltip = 2;
    optional string location_url = 3;
    PointUtf16 location_range_start = 4;
    PointUtf16 location_range_end = 5;
    optional uint64 language_server_id = 6;
}

message InlayHintTooltip {
    oneof content {
        string value = 1;
        MarkupContent markup_content = 2;
    }
}

message InlayHintLabelPartTooltip {
    oneof content {
        string value = 1;
        MarkupContent markup_content = 2;
    }
}

message ResolveState {
    State state = 1;
    LspResolveState lsp_resolve_state = 2;

    enum State {
        Resolved = 0;
        CanResolve = 1;
        Resolving = 2;
    }

    message LspResolveState {
        string value = 1;
        uint64 server_id = 2;
    }
}

// This type is used to resolve more than just
// the documentation, but for backwards-compatibility
// reasons we can't rename the type.
message ResolveCompletionDocumentation {
    uint64 project_id = 1;
    uint64 language_server_id = 2;
    bytes lsp_completion = 3;
    uint64 buffer_id = 4;
}

message ResolveCompletionDocumentationResponse {
    string documentation = 1;
    bool documentation_is_markdown = 2;
    Anchor old_start = 3;
    Anchor old_end = 4;
    string new_text = 5;
    bytes lsp_completion = 6;
}

message ResolveInlayHint {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    uint64 language_server_id = 3;
    InlayHint hint = 4;
}

message ResolveInlayHintResponse {
    InlayHint hint = 1;
}

message RefreshInlayHints {
    uint64 project_id = 1;
}

message MarkupContent {
    bool is_markdown = 1;
    string value = 2;
}

message PerformRenameResponse {
    ProjectTransaction transaction = 2;
}

message SearchQuery {
    string query = 2;
    bool regex = 3;
    bool whole_word = 4;
    bool case_sensitive = 5;
    string files_to_include = 6;
    string files_to_exclude = 7;
    bool include_ignored = 8;
}

message FindSearchCandidates {
    uint64 project_id = 1;
    SearchQuery query = 2;
    uint64 limit = 3;
}

message FindSearchCandidatesResponse {
    repeated uint64 buffer_ids = 1;
}

message CodeAction {
    uint64 server_id = 1;
    Anchor start = 2;
    Anchor end = 3;
    bytes lsp_action = 4;
}

message ProjectTransaction {
    repeated uint64 buffer_ids = 1;
    repeated Transaction transactions = 2;
}

message Transaction {
    LamportTimestamp id = 1;
    repeated LamportTimestamp edit_ids = 2;
    repeated VectorClockEntry start = 3;
}

message LamportTimestamp {
    uint32 replica_id = 1;
    uint32 value = 2;
}

message LanguageServer {
    uint64 id = 1;
    string name = 2;
}

message StartLanguageServer {
    uint64 project_id = 1;
    LanguageServer server = 2;
}

message UpdateDiagnosticSummary {
    uint64 project_id = 1;
    uint64 worktree_id = 2;
    DiagnosticSummary summary = 3;
}

message DiagnosticSummary {
    string path = 1;
    uint64 language_server_id = 2;
    uint32 error_count = 3;
    uint32 warning_count = 4;
}

message UpdateLanguageServer {
    uint64 project_id = 1;
    uint64 language_server_id = 2;
    oneof variant {
        LspWorkStart work_start = 3;
        LspWorkProgress work_progress = 4;
        LspWorkEnd work_end = 5;
        LspDiskBasedDiagnosticsUpdating disk_based_diagnostics_updating = 6;
        LspDiskBasedDiagnosticsUpdated disk_based_diagnostics_updated = 7;
    }
}

message LspWorkStart {
    string token = 1;
    optional string title = 4;
    optional string message = 2;
    optional uint32 percentage = 3;
}

message LspWorkProgress {
    string token = 1;
    optional string message = 2;
    optional uint32 percentage = 3;
}

message LspWorkEnd {
    string token = 1;
}

message LspDiskBasedDiagnosticsUpdating {}

message LspDiskBasedDiagnosticsUpdated {}

message UpdateChannels {
    repeated Channel channels = 1;
    repeated uint64 delete_channels = 4;
    repeated Channel channel_invitations = 5;
    repeated uint64 remove_channel_invitations = 6;
    repeated ChannelParticipants channel_participants = 7;
    repeated ChannelMessageId latest_channel_message_ids = 8;
    repeated ChannelBufferVersion latest_channel_buffer_versions = 9;

    repeated HostedProject hosted_projects = 10;
    repeated uint64 deleted_hosted_projects = 11;

    reserved 12;
    reserved 13;
    reserved 14;
    reserved 15;
}

message UpdateUserChannels {
    repeated ChannelMessageId observed_channel_message_id = 1;
    repeated ChannelBufferVersion observed_channel_buffer_version = 2;
    repeated ChannelMembership channel_memberships = 3;
}

message ChannelMembership {
    uint64 channel_id = 1;
    ChannelRole role = 2;
}

message ChannelMessageId {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message ChannelPermission {
    uint64 channel_id = 1;
    ChannelRole role = 3;
}

message ChannelParticipants {
    uint64 channel_id = 1;
    repeated uint64 participant_user_ids = 2;
}

message HostedProject {
    uint64 project_id = 1;
    uint64 channel_id = 2;
    string name = 3;
    ChannelVisibility visibility = 4;
}

message DevServerProject {
    uint64 id = 1;
    optional uint64 project_id = 2;
    reserved 3;
    reserved 4;
    uint64 dev_server_id = 5;
    string path = 6;
    repeated string paths = 7;
}

message DevServer {
    reserved 1;
    uint64 dev_server_id = 2;
    string name = 3;
    DevServerStatus status = 4;
    optional string ssh_connection_string = 5;
}

enum DevServerStatus {
    Offline = 0;
    Online = 1;
}

message JoinChannel {
    uint64 channel_id = 1;
}

message DeleteChannel {
    uint64 channel_id = 1;
}

message GetChannelMembers {
    uint64 channel_id = 1;
    string query = 2;
    uint64 limit = 3;
}

message GetChannelMembersResponse {
    repeated ChannelMember members = 1;
    repeated User users = 2;
}

message ChannelMember {
    uint64 user_id = 1;
    Kind kind = 3;
    ChannelRole role = 4;

    enum Kind {
        Member = 0;
        Invitee = 1;
    }
}

message SubscribeToChannels {}

message CreateChannel {
    string name = 1;
    optional uint64 parent_id = 2;
}

message CreateChannelResponse {
    Channel channel = 1;
    optional uint64 parent_id = 2;
}

message InviteChannelMember {
    uint64 channel_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 4;
}

message RemoveChannelMember {
    uint64 channel_id = 1;
    uint64 user_id = 2;
}

enum ChannelRole {
    Admin = 0;
    Member = 1;
    Guest = 2;
    Banned = 3;
    Talker = 4;
}

message SetChannelMemberRole {
    uint64 channel_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 3;
}

message SetChannelVisibility {
    uint64 channel_id = 1;
    ChannelVisibility visibility = 2;
}

message RenameChannel {
    uint64 channel_id = 1;
    string name = 2;
}

message RenameChannelResponse {
    Channel channel = 1;
}

message JoinChannelChat {
    uint64 channel_id = 1;
}

message JoinChannelChatResponse {
    repeated ChannelMessage messages = 1;
    bool done = 2;
}

message LeaveChannelChat {
    uint64 channel_id = 1;
}

message SendChannelMessage {
    uint64 channel_id = 1;
    string body = 2;
    Nonce nonce = 3;
    repeated ChatMention mentions = 4;
    optional uint64 reply_to_message_id = 5;
}

message RemoveChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message UpdateChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
    Nonce nonce = 4;
    string body = 5;
    repeated ChatMention mentions = 6;
}

message AckChannelMessage {
    uint64 channel_id = 1;
    uint64 message_id = 2;
}

message SendChannelMessageResponse {
    ChannelMessage message = 1;
}

message ChannelMessageSent {
    uint64 channel_id = 1;
    ChannelMessage message = 2;
}

message ChannelMessageUpdate {
    uint64 channel_id = 1;
    ChannelMessage message = 2;
}

message GetChannelMessages {
    uint64 channel_id = 1;
    uint64 before_message_id = 2;
}

message GetChannelMessagesResponse {
    repeated ChannelMessage messages = 1;
    bool done = 2;
}

message GetChannelMessagesById {
    repeated uint64 message_ids = 1;
}

message MoveChannel {
    uint64 channel_id = 1;
    uint64 to = 2;
}

message JoinChannelBuffer {
    uint64 channel_id = 1;
}

message ChannelMessage {
    uint64 id = 1;
    string body = 2;
    uint64 timestamp = 3;
    uint64 sender_id = 4;
    Nonce nonce = 5;
    repeated ChatMention mentions = 6;
    optional uint64 reply_to_message_id = 7;
    optional uint64 edited_at = 8;
}

message ChatMention {
    Range range = 1;
    uint64 user_id = 2;
}

message RejoinChannelBuffers {
    repeated ChannelBufferVersion buffers = 1;
}

message RejoinChannelBuffersResponse {
    repeated RejoinedChannelBuffer buffers = 1;
}

message AckBufferOperation {
    uint64 buffer_id = 1;
    uint64 epoch = 2;
    repeated VectorClockEntry version = 3;
}

message JoinChannelBufferResponse {
    uint64 buffer_id = 1;
    uint32 replica_id = 2;
    string base_text = 3;
    repeated Operation operations = 4;
    repeated Collaborator collaborators = 5;
    uint64 epoch = 6;
}

message RejoinedChannelBuffer {
    uint64 channel_id = 1;
    repeated VectorClockEntry version = 2;
    repeated Operation operations = 3;
    repeated Collaborator collaborators = 4;
}

message LeaveChannelBuffer {
    uint64 channel_id = 1;
}

message RespondToChannelInvite {
    uint64 channel_id = 1;
    bool accept = 2;
}

message GetUsers {
    repeated uint64 user_ids = 1;
}

message FuzzySearchUsers {
    string query = 1;
}

message UsersResponse {
    repeated User users = 1;
}

message RequestContact {
    uint64 responder_id = 1;
}

message RemoveContact {
    uint64 user_id = 1;
}

message RespondToContactRequest {
    uint64 requester_id = 1;
    ContactRequestResponse response = 2;
}

enum ContactRequestResponse {
    Accept = 0;
    Decline = 1;
    Block = 2;
    Dismiss = 3;
}

message UpdateContacts {
    repeated Contact contacts = 1;
    repeated uint64 remove_contacts = 2;
    repeated IncomingContactRequest incoming_requests = 3;
    repeated uint64 remove_incoming_requests = 4;
    repeated uint64 outgoing_requests = 5;
    repeated uint64 remove_outgoing_requests = 6;
}

message UpdateInviteInfo {
    string url = 1;
    uint32 count = 2;
}

message ShowContacts {}

message IncomingContactRequest {
    uint64 requester_id = 1;
}

message UpdateDiagnostics {
    uint32 replica_id = 1;
    uint32 lamport_timestamp = 2;
    uint64 server_id = 3;
    repeated Diagnostic diagnostics = 4;
}

message Follow {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    PeerId leader_id = 3;
}

message FollowResponse {
    View active_view = 3;
    // TODO: Remove after version 0.145.x stabilizes.
    optional ViewId active_view_id = 1;
    repeated View views = 2;
}

message UpdateFollowers {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    reserved 3;
    oneof variant {
        View create_view = 5;
        // TODO: Remove after version 0.145.x stabilizes.
        UpdateActiveView update_active_view = 4;
        UpdateView update_view = 6;
    }
}

message Unfollow {
    uint64 room_id = 1;
    optional uint64 project_id = 2;
    PeerId leader_id = 3;
}

message GetPrivateUserInfo {}

message GetPrivateUserInfoResponse {
    string metrics_id = 1;
    bool staff = 2;
    repeated string flags = 3;
    optional uint64 accepted_tos_at = 4;
}

enum Plan {
    Free = 0;
    ZedPro = 1;
}

message UpdateUserPlan {
    Plan plan = 1;
}

message AcceptTermsOfService {}

message AcceptTermsOfServiceResponse {
    uint64 accepted_tos_at = 1;
}

// Entities

message ViewId {
    PeerId creator = 1;
    uint64 id = 2;
}

message UpdateActiveView {
    optional ViewId id = 1;
    optional PeerId leader_id = 2;
    View view = 3;
}

enum PanelId {
    AssistantPanel = 0;
}

message UpdateView {
    ViewId id = 1;
    optional PeerId leader_id = 2;

    oneof variant {
        Editor editor = 3;
    }

    message Editor {
        repeated ExcerptInsertion inserted_excerpts = 1;
        repeated uint64 deleted_excerpts = 2;
        repeated Selection selections = 3;
        optional Selection pending_selection = 4;
        EditorAnchor scroll_top_anchor = 5;
        float scroll_x = 6;
        float scroll_y = 7;
    }
}

message View {
    ViewId id = 1;
    optional PeerId leader_id = 2;
    optional PanelId panel_id = 6;

    oneof variant {
        Editor editor = 3;
        ChannelView channel_view = 4;
        ContextEditor context_editor = 5;
    }

    message Editor {
        bool singleton = 1;
        optional string title = 2;
        repeated Excerpt excerpts = 3;
        repeated Selection selections = 4;
        optional Selection pending_selection = 5;
        EditorAnchor scroll_top_anchor = 6;
        float scroll_x = 7;
        float scroll_y = 8;
    }

    message ChannelView {
        uint64 channel_id = 1;
        Editor editor = 2;
    }

    message ContextEditor {
        string context_id = 1;
        Editor editor = 2;
    }
}

message Collaborator {
    PeerId peer_id = 1;
    uint32 replica_id = 2;
    uint64 user_id = 3;
}

message User {
    uint64 id = 1;
    string github_login = 2;
    string avatar_url = 3;
}

message File {
    uint64 worktree_id = 1;
    optional uint64 entry_id = 2;
    string path = 3;
    Timestamp mtime = 4;
    bool is_deleted = 5;
}

message Entry {
    uint64 id = 1;
    bool is_dir = 2;
    string path = 3;
    uint64 inode = 4;
    Timestamp mtime = 5;
    bool is_symlink = 6;
    bool is_ignored = 7;
    bool is_external = 8;
    optional GitStatus git_status = 9;
    bool is_fifo = 10;
    optional uint64 size = 11;
}

message RepositoryEntry {
    uint64 work_directory_id = 1;
    optional string branch = 2;
}

message StatusEntry {
    string repo_path = 1;
    GitStatus status = 2;
}

enum GitStatus {
    Added = 0;
    Modified = 1;
    Conflict = 2;
}

message BufferState {
    uint64 id = 1;
    optional File file = 2;
    string base_text = 3;
    optional string diff_base = 4;
    LineEnding line_ending = 5;
    repeated VectorClockEntry saved_version = 6;
    reserved 7;
    Timestamp saved_mtime = 8;
}

message BufferChunk {
    uint64 buffer_id = 1;
    repeated Operation operations = 2;
    bool is_last = 3;
}

enum LineEnding {
    Unix = 0;
    Windows = 1;
}

message Selection {
    uint64 id = 1;
    EditorAnchor start = 2;
    EditorAnchor end = 3;
    bool reversed = 4;
}

message EditorAnchor {
    uint64 excerpt_id = 1;
    Anchor anchor = 2;
}

enum CursorShape {
    CursorBar = 0;
    CursorBlock = 1;
    CursorUnderscore = 2;
    CursorHollow = 3;
}

message ExcerptInsertion {
    Excerpt excerpt = 1;
    optional uint64 previous_excerpt_id = 2;
}

message Excerpt {
    uint64 id = 1;
    uint64 buffer_id = 2;
    Anchor context_start = 3;
    Anchor context_end = 4;
    Anchor primary_start = 5;
    Anchor primary_end = 6;
}

message Anchor {
    uint32 replica_id = 1;
    uint32 timestamp = 2;
    uint64 offset = 3;
    Bias bias = 4;
    optional uint64 buffer_id = 5;
}

enum Bias {
    Left = 0;
    Right = 1;
}

message Diagnostic {
    Anchor start = 1;
    Anchor end = 2;
    optional string source = 3;
    Severity severity = 4;
    string message = 5;
    optional string code = 6;
    uint64 group_id = 7;
    bool is_primary = 8;

    // TODO: remove this field
    bool is_valid = 9;

    bool is_disk_based = 10;
    bool is_unnecessary = 11;

    enum Severity {
        None = 0;
        Error = 1;
        Warning = 2;
        Information = 3;
        Hint = 4;
    }
    optional string data = 12;
}

message Operation {
    oneof variant {
        Edit edit = 1;
        Undo undo = 2;
        UpdateSelections update_selections = 3;
        UpdateDiagnostics update_diagnostics = 4;
        UpdateCompletionTriggers update_completion_triggers = 5;
    }

    message Edit {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated VectorClockEntry version = 3;
        repeated Range ranges = 4;
        repeated string new_text = 5;
    }

    message Undo {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated VectorClockEntry version = 3;
        repeated UndoCount counts = 4;
    }

    message UpdateSelections {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated Selection selections = 3;
        bool line_mode = 4;
        CursorShape cursor_shape = 5;
    }

    message UpdateCompletionTriggers {
        uint32 replica_id = 1;
        uint32 lamport_timestamp = 2;
        repeated string triggers = 3;
    }
}

message UndoMapEntry {
    uint32 replica_id = 1;
    uint32 local_timestamp = 2;
    repeated UndoCount counts = 3;
}

message UndoCount {
    uint32 replica_id = 1;
    uint32 lamport_timestamp = 2;
    uint32 count = 3;
}

message VectorClockEntry {
    uint32 replica_id = 1;
    uint32 timestamp = 2;
}

message Timestamp {
    uint64 seconds = 1;
    uint32 nanos = 2;
}

message Range {
    uint64 start = 1;
    uint64 end = 2;
}

message PointUtf16 {
    uint32 row = 1;
    uint32 column = 2;
}

message Nonce {
    uint64 upper_half = 1;
    uint64 lower_half = 2;
}

enum ChannelVisibility {
    Public = 0;
    Members = 1;
}

message Channel {
    uint64 id = 1;
    string name = 2;
    ChannelVisibility visibility = 3;
    repeated uint64 parent_path = 5;
}

message Contact {
    uint64 user_id = 1;
    bool online = 2;
    bool busy = 3;
}

message WorktreeMetadata {
    uint64 id = 1;
    string root_name = 2;
    bool visible = 3;
    string abs_path = 4;
}

message UpdateDiffBase {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    optional string diff_base = 3;
}

message GetNotifications {
    optional uint64 before_id = 1;
}

message AddNotification {
    Notification notification = 1;
}

message GetNotificationsResponse {
    repeated Notification notifications = 1;
    bool done = 2;
}

message DeleteNotification {
    uint64 notification_id = 1;
}

message UpdateNotification {
    Notification notification = 1;
}

message MarkNotificationRead {
    uint64 notification_id = 1;
}

message Notification {
    uint64 id = 1;
    uint64 timestamp = 2;
    string kind = 3;
    optional uint64 entity_id = 4;
    string content = 5;
    bool is_read = 6;
    optional bool response = 7;
}

message LspExtExpandMacro {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    Anchor position = 3;
}

message LspExtExpandMacroResponse {
    string name = 1;
    string expansion = 2;
}

message LspExtSwitchSourceHeader {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
}

message LspExtSwitchSourceHeaderResponse {
    string target_file = 1;
}

message SetRoomParticipantRole {
    uint64 room_id = 1;
    uint64 user_id = 2;
    ChannelRole role = 3;
}

enum LanguageModelRole {
    LanguageModelUser = 0;
    LanguageModelAssistant = 1;
    LanguageModelSystem = 2;
    reserved 3;
}

message CountLanguageModelTokens {
    LanguageModelProvider provider = 1;
    string request = 2;
}

message CountLanguageModelTokensResponse {
    uint32 token_count = 1;
}

enum LanguageModelProvider {
    Anthropic = 0;
    OpenAI = 1;
    Google = 2;
    Zed = 3;
}

message GetCachedEmbeddings {
    string model = 1;
    repeated bytes digests = 2;
}

message GetCachedEmbeddingsResponse {
    repeated Embedding embeddings = 1;
}

message ComputeEmbeddings {
    string model = 1;
    repeated string texts = 2;
}

message ComputeEmbeddingsResponse {
    repeated Embedding embeddings = 1;
}

message Embedding {
    bytes digest = 1;
    repeated float dimensions = 2;
}

message BlameBuffer {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
}

message BlameEntry {
    bytes sha = 1;

    uint32 start_line = 2;
    uint32 end_line = 3;
    uint32 original_line_number = 4;

    optional string author = 5;
    optional string author_mail = 6;
    optional int64 author_time = 7;
    optional string author_tz = 8;

    optional string committer = 9;
    optional string committer_mail = 10;
    optional int64 committer_time = 11;
    optional string committer_tz = 12;

    optional string summary = 13;
    optional string previous = 14;

    string filename = 15;
}

message CommitMessage {
    bytes oid = 1;
    string message = 2;
}

message CommitPermalink {
    bytes oid = 1;
    string permalink = 2;
}

message BlameBufferResponse {
    repeated BlameEntry entries = 1;
    repeated CommitMessage messages = 2;
    repeated CommitPermalink permalinks = 3;
    optional string remote_url = 4;
}

message MultiLspQuery {
    uint64 project_id = 1;
    uint64 buffer_id = 2;
    repeated VectorClockEntry version = 3;
    oneof strategy {
        AllLanguageServers all = 4;
    }
    oneof request {
        GetHover get_hover = 5;
        GetCodeActions get_code_actions = 6;
        GetSignatureHelp get_signature_help = 7;
    }
}

message AllLanguageServers {}

message RestartLanguageServers {
    uint64 project_id = 1;
    repeated uint64 buffer_ids = 2;
}

message MultiLspQueryResponse {
    repeated LspResponse responses = 1;
}

message LspResponse {
    oneof response {
        GetHoverResponse get_hover_response = 1;
        GetCodeActionsResponse get_code_actions_response = 2;
        GetSignatureHelpResponse get_signature_help_response = 3;
    }
}

message GetSupermavenApiKey {}

message GetSupermavenApiKeyResponse {
    string api_key = 1;
}

message TaskContextForLocation {
    uint64 project_id = 1;
    Location location = 2;
    map<string, string> task_variables = 3;
}

message TaskContext {
    optional string cwd = 1;
    map<string, string> task_variables = 2;
    map<string, string> project_env = 3;
}

message Shell {
    message WithArguments {
        string program = 1;
        repeated string args = 2;
    }

    oneof shell_type {
        System system = 1;
        string program = 2;
        WithArguments with_arguments = 3;
    }
}

message System {}

enum RevealStrategy {
    RevealAlways = 0;
    RevealNever = 1;
}

enum HideStrategy {
    HideAlways = 0;
    HideNever = 1;
    HideOnSuccess = 2;
}

message ContextMessageStatus {
    oneof variant {
        Done done = 1;
        Pending pending = 2;
        Error error = 3;
        Canceled canceled = 4;
    }

    message Done {}

    message Pending {}

    message Error {
        string message = 1;
    }

    message Canceled {}
}

message ContextMessage {
    LamportTimestamp id = 1;
    Anchor start = 2;
    LanguageModelRole role = 3;
    ContextMessageStatus status = 4;
}

message SlashCommandOutputSection {
    AnchorRange range = 1;
    string icon_name = 2;
    string label = 3;
    optional string metadata = 4;
}

message ContextOperation {
    oneof variant {
        InsertMessage insert_message = 1;
        UpdateMessage update_message = 2;
        UpdateSummary update_summary = 3;
        SlashCommandFinished slash_command_finished = 4;
        BufferOperation buffer_operation = 5;
    }

    message InsertMessage {
        ContextMessage message = 1;
        repeated VectorClockEntry version = 2;
    }

    message UpdateMessage {
        LamportTimestamp message_id = 1;
        LanguageModelRole role = 2;
        ContextMessageStatus status = 3;
        LamportTimestamp timestamp = 4;
        repeated VectorClockEntry version = 5;
    }

    message UpdateSummary {
        string summary = 1;
        bool done = 2;
        LamportTimestamp timestamp = 3;
        repeated VectorClockEntry version = 4;
    }

    message SlashCommandFinished {
        LamportTimestamp id = 1;
        AnchorRange output_range = 2;
        repeated SlashCommandOutputSection sections = 3;
        repeated VectorClockEntry version = 4;
    }

    message BufferOperation {
        Operation operation = 1;
    }
}

message Context {
    repeated ContextOperation operations = 1;
}

message ContextMetadata {
    string context_id = 1;
    optional string summary = 2;
}

message AdvertiseContexts {
    uint64 project_id = 1;
    repeated ContextMetadata contexts = 2;
}

message OpenContext {
    uint64 project_id = 1;
    string context_id = 2;
}

message OpenContextResponse {
    Context context = 1;
}

message CreateContext {
    uint64 project_id = 1;
}

message CreateContextResponse {
    string context_id = 1;
    Context context = 2;
}

message UpdateContext {
    uint64 project_id = 1;
    string context_id = 2;
    ContextOperation operation = 3;
}

message ContextVersion {
    string context_id = 1;
    repeated VectorClockEntry context_version = 2;
    repeated VectorClockEntry buffer_version = 3;
}

message SynchronizeContexts {
    uint64 project_id = 1;
    repeated ContextVersion contexts = 2;
}

message SynchronizeContextsResponse {
    repeated ContextVersion contexts = 1;
}

message GetLlmToken {}

message GetLlmTokenResponse {
    string token = 1;
}

// Remote FS

message AddWorktree {
    uint64 project_id = 2;
    string path = 1;
    bool visible = 3;
}

message AddWorktreeResponse {
    uint64 worktree_id = 1;
}

message UpdateUserSettings {
    uint64 project_id = 1;
    string content = 2;
    optional Kind kind = 3;

    enum Kind {
        Settings = 0;
        Tasks = 1;
    }
}

message CheckFileExists {
    uint64 project_id = 1;
    string path = 2;
}

message CheckFileExistsResponse {
    bool exists = 1;
    string path = 2;
}

message ShutdownRemoteServer {}

message RemoveWorktree {
    uint64 worktree_id = 1;
}
