zed.proto

  1syntax = "proto3";
  2package zed.messages;
  3
  4message Envelope {
  5    uint32 id = 1;
  6    optional uint32 responding_to = 2;
  7    optional uint32 original_sender_id = 3;
  8    oneof payload {
  9        Ack ack = 4;
 10        Error error = 5;
 11        Ping ping = 6;
 12        Test test = 7;
 13
 14        RegisterProject register_project = 8;
 15        RegisterProjectResponse register_project_response = 9;
 16        UnregisterProject unregister_project = 10;
 17        RequestJoinProject request_join_project = 11;
 18        RespondToJoinProjectRequest respond_to_join_project_request = 12;
 19        JoinProjectRequestCancelled join_project_request_cancelled = 13;
 20        JoinProject join_project = 14;
 21        JoinProjectResponse join_project_response = 15;
 22        LeaveProject leave_project = 16;
 23        AddProjectCollaborator add_project_collaborator = 17;
 24        RemoveProjectCollaborator remove_project_collaborator = 18;
 25        ProjectUnshared project_unshared = 19;
 26
 27        GetDefinition get_definition = 20;
 28        GetDefinitionResponse get_definition_response = 21;
 29        GetTypeDefinition get_type_definition = 22;
 30        GetTypeDefinitionResponse get_type_definition_response = 23;
 31        GetReferences get_references = 24;
 32        GetReferencesResponse get_references_response = 25;
 33        GetDocumentHighlights get_document_highlights = 26;
 34        GetDocumentHighlightsResponse get_document_highlights_response = 27;
 35        GetProjectSymbols get_project_symbols = 28;
 36        GetProjectSymbolsResponse get_project_symbols_response = 29;
 37        OpenBufferForSymbol open_buffer_for_symbol = 30;
 38        OpenBufferForSymbolResponse open_buffer_for_symbol_response = 31;
 39
 40        UpdateProject update_project = 32;
 41        RegisterProjectActivity register_project_activity = 33;
 42        UpdateWorktree update_worktree = 34;
 43        UpdateWorktreeExtensions update_worktree_extensions = 35;
 44
 45        CreateProjectEntry create_project_entry = 36;
 46        RenameProjectEntry rename_project_entry = 37;
 47        CopyProjectEntry copy_project_entry = 38;
 48        DeleteProjectEntry delete_project_entry = 39;
 49        ProjectEntryResponse project_entry_response = 40;
 50
 51        UpdateDiagnosticSummary update_diagnostic_summary = 41;
 52        StartLanguageServer start_language_server = 42;
 53        UpdateLanguageServer update_language_server = 43;
 54
 55        OpenBufferById open_buffer_by_id = 44;
 56        OpenBufferByPath open_buffer_by_path = 45;
 57        OpenBufferResponse open_buffer_response = 46;
 58        CreateBufferForPeer create_buffer_for_peer = 47;
 59        UpdateBuffer update_buffer = 48;
 60        UpdateBufferFile update_buffer_file = 49;
 61        SaveBuffer save_buffer = 50;
 62        BufferSaved buffer_saved = 51;
 63        BufferReloaded buffer_reloaded = 52;
 64        ReloadBuffers reload_buffers = 53;
 65        ReloadBuffersResponse reload_buffers_response = 54;
 66        FormatBuffers format_buffers = 55;
 67        FormatBuffersResponse format_buffers_response = 56;
 68        GetCompletions get_completions = 57;
 69        GetCompletionsResponse get_completions_response = 58;
 70        ApplyCompletionAdditionalEdits apply_completion_additional_edits = 59;
 71        ApplyCompletionAdditionalEditsResponse apply_completion_additional_edits_response = 60;
 72        GetCodeActions get_code_actions = 61;
 73        GetCodeActionsResponse get_code_actions_response = 62;
 74        GetHover get_hover = 63;
 75        GetHoverResponse get_hover_response = 64;
 76        ApplyCodeAction apply_code_action = 65;
 77        ApplyCodeActionResponse apply_code_action_response = 66;
 78        PrepareRename prepare_rename = 67;
 79        PrepareRenameResponse prepare_rename_response = 68;
 80        PerformRename perform_rename = 69;
 81        PerformRenameResponse perform_rename_response = 70;
 82        SearchProject search_project = 71;
 83        SearchProjectResponse search_project_response = 72;
 84
 85        GetChannels get_channels = 73;
 86        GetChannelsResponse get_channels_response = 74;
 87        JoinChannel join_channel = 75;
 88        JoinChannelResponse join_channel_response = 76;
 89        LeaveChannel leave_channel = 77;
 90        SendChannelMessage send_channel_message = 78;
 91        SendChannelMessageResponse send_channel_message_response = 79;
 92        ChannelMessageSent channel_message_sent = 80;
 93        GetChannelMessages get_channel_messages = 81;
 94        GetChannelMessagesResponse get_channel_messages_response = 82;
 95
 96        UpdateContacts update_contacts = 83;
 97        UpdateInviteInfo update_invite_info = 84;
 98        ShowContacts show_contacts = 85;
 99
100        GetUsers get_users = 86;
101        FuzzySearchUsers fuzzy_search_users = 87;
102        UsersResponse users_response = 88;
103        RequestContact request_contact = 89;
104        RespondToContactRequest respond_to_contact_request = 90;
105        RemoveContact remove_contact = 91;
106
107        Follow follow = 92;
108        FollowResponse follow_response = 93;
109        UpdateFollowers update_followers = 94;
110        Unfollow unfollow = 95;
111    }
112}
113
114// Messages
115
116message Ping {}
117
118message Ack {}
119
120message Error {
121    string message = 1;
122}
123
124message Test {
125    uint64 id = 1;
126}
127
128message RegisterProject {
129    bool online = 1;
130}
131
132message RegisterProjectResponse {
133    uint64 project_id = 1;
134}
135
136message UnregisterProject {
137    uint64 project_id = 1;
138}
139
140message UpdateProject {
141    uint64 project_id = 1;
142    repeated WorktreeMetadata worktrees = 2;
143    bool online = 3;
144}
145
146message RegisterProjectActivity {
147    uint64 project_id = 1;
148}
149
150message RequestJoinProject {
151    uint64 requester_id = 1;
152    uint64 project_id = 2;
153}
154
155message RespondToJoinProjectRequest {
156    uint64 requester_id = 1;
157    uint64 project_id = 2;
158    bool allow = 3;
159}
160
161message JoinProjectRequestCancelled {
162    uint64 requester_id = 1;
163    uint64 project_id = 2;
164}
165
166message JoinProject {
167    uint64 project_id = 1;
168}
169
170message JoinProjectResponse {
171    oneof variant {
172        Accept accept = 1;
173        Decline decline = 2;
174    }
175
176    message Accept {
177        uint32 replica_id = 1;
178        repeated WorktreeMetadata worktrees = 2;
179        repeated Collaborator collaborators = 3;
180        repeated LanguageServer language_servers = 4;        
181    }
182    
183    message Decline {
184        Reason reason = 1;
185
186        enum Reason {
187            Declined = 0;
188            Closed = 1;
189            WentOffline = 2;
190        }
191    }
192}
193
194message LeaveProject {
195    uint64 project_id = 1;
196}
197
198message UpdateWorktree {
199    uint64 project_id = 1;
200    uint64 worktree_id = 2;
201    string root_name = 3;
202    repeated Entry updated_entries = 4;
203    repeated uint64 removed_entries = 5;
204    uint64 scan_id = 6;
205    bool is_last_update = 7;
206}
207
208message UpdateWorktreeExtensions {
209    uint64 project_id = 1;
210    uint64 worktree_id = 2;
211    repeated string extensions = 3;
212    repeated uint32 counts = 4;
213}
214
215message CreateProjectEntry {
216    uint64 project_id = 1;
217    uint64 worktree_id = 2;
218    bytes path = 3;
219    bool is_directory = 4;
220}
221
222message RenameProjectEntry {
223    uint64 project_id = 1;
224    uint64 entry_id = 2;
225    bytes new_path = 3;
226}
227
228message CopyProjectEntry {
229    uint64 project_id = 1;
230    uint64 entry_id = 2;
231    bytes new_path = 3;
232}
233
234message DeleteProjectEntry {
235    uint64 project_id = 1;
236    uint64 entry_id = 2;
237}
238
239message ProjectEntryResponse {
240    Entry entry = 1;
241    uint64 worktree_scan_id = 2;
242}
243
244message AddProjectCollaborator {
245    uint64 project_id = 1;
246    Collaborator collaborator = 2;
247}
248
249message RemoveProjectCollaborator {
250    uint64 project_id = 1;
251    uint32 peer_id = 2;
252}
253
254message ProjectUnshared {
255    uint64 project_id = 1;
256}
257
258message GetDefinition {
259     uint64 project_id = 1;
260     uint64 buffer_id = 2;
261     Anchor position = 3;
262     repeated VectorClockEntry version = 4;
263 }
264
265message GetDefinitionResponse {
266    repeated LocationLink links = 1;
267}
268
269message GetTypeDefinition {
270     uint64 project_id = 1;
271     uint64 buffer_id = 2;
272     Anchor position = 3;
273     repeated VectorClockEntry version = 4;
274 }
275
276message GetTypeDefinitionResponse {
277    repeated LocationLink links = 1;
278}
279
280message GetReferences {
281     uint64 project_id = 1;
282     uint64 buffer_id = 2;
283     Anchor position = 3;
284     repeated VectorClockEntry version = 4;
285 }
286
287message GetReferencesResponse {
288    repeated Location locations = 1;
289}
290
291message GetDocumentHighlights {
292     uint64 project_id = 1;
293     uint64 buffer_id = 2;
294     Anchor position = 3;
295     repeated VectorClockEntry version = 4;
296 }
297
298message GetDocumentHighlightsResponse {
299    repeated DocumentHighlight highlights = 1;
300}
301
302message Location {
303    uint64 buffer_id = 1;
304    Anchor start = 2;
305    Anchor end = 3;
306}
307
308message LocationLink {
309    optional Location origin = 1;
310    Location target = 2;
311}
312
313message DocumentHighlight {
314    Kind kind = 1;
315    Anchor start = 2;
316    Anchor end = 3;
317
318    enum Kind {
319        Text = 0;
320        Read = 1;
321        Write = 2;
322    }
323}
324
325message GetProjectSymbols {
326    uint64 project_id = 1;
327    string query = 2;
328}
329
330message GetProjectSymbolsResponse {
331    repeated Symbol symbols = 4;
332}
333
334message Symbol {
335    uint64 source_worktree_id = 1;
336    uint64 worktree_id = 2;
337    string language_server_name = 3;
338    string name = 4;
339    int32 kind = 5;
340    string path = 6;
341    Point start = 7;
342    Point end = 8;
343    bytes signature = 9;
344}
345
346message OpenBufferForSymbol {
347    uint64 project_id = 1;
348    Symbol symbol = 2;
349}
350
351message OpenBufferForSymbolResponse {
352    uint64 buffer_id = 1;
353}
354
355message OpenBufferByPath {
356    uint64 project_id = 1;
357    uint64 worktree_id = 2;
358    string path = 3;
359}
360
361message OpenBufferById {
362    uint64 project_id = 1;
363    uint64 id = 2;
364}
365
366message OpenBufferResponse {
367    uint64 buffer_id = 1;
368}
369
370message CreateBufferForPeer {
371    uint64 project_id = 1;
372    uint32 peer_id = 2;
373    oneof variant {
374        BufferState state = 3;
375        BufferChunk chunk = 4;
376    }
377}
378
379message UpdateBuffer {
380    uint64 project_id = 1;
381    uint64 buffer_id = 2;
382    repeated Operation operations = 3;
383}
384
385message UpdateBufferFile {
386    uint64 project_id = 1;
387    uint64 buffer_id = 2;
388    File file = 3;
389}
390
391message SaveBuffer {
392    uint64 project_id = 1;
393    uint64 buffer_id = 2;
394    repeated VectorClockEntry version = 3;
395}
396
397message BufferSaved {
398    uint64 project_id = 1;
399    uint64 buffer_id = 2;
400    repeated VectorClockEntry version = 3;
401    Timestamp mtime = 4;
402    string fingerprint = 5;
403}
404
405message BufferReloaded {
406    uint64 project_id = 1;
407    uint64 buffer_id = 2;
408    repeated VectorClockEntry version = 3;
409    Timestamp mtime = 4;
410    string fingerprint = 5;
411    LineEnding line_ending = 6;
412}
413
414message ReloadBuffers {
415    uint64 project_id = 1;
416    repeated uint64 buffer_ids = 2;
417}
418
419message ReloadBuffersResponse {
420    ProjectTransaction transaction = 1;
421}
422
423message FormatBuffers {
424    uint64 project_id = 1;
425    repeated uint64 buffer_ids = 2;
426}
427
428message FormatBuffersResponse {
429    ProjectTransaction transaction = 1;
430}
431
432message GetCompletions {
433    uint64 project_id = 1;
434    uint64 buffer_id = 2;
435    Anchor position = 3;
436    repeated VectorClockEntry version = 4;
437}
438
439message GetCompletionsResponse {
440    repeated Completion completions = 1;
441    repeated VectorClockEntry version = 2;
442}
443
444message ApplyCompletionAdditionalEdits {
445    uint64 project_id = 1;
446    uint64 buffer_id = 2;
447    Completion completion = 3;
448}
449
450message ApplyCompletionAdditionalEditsResponse {
451    Transaction transaction = 1;
452}
453
454message Completion {
455    Anchor old_start = 1;
456    Anchor old_end = 2;
457    string new_text = 3;
458    bytes lsp_completion = 4;
459}
460
461message GetCodeActions {
462    uint64 project_id = 1;
463    uint64 buffer_id = 2;
464    Anchor start = 3;
465    Anchor end = 4;
466    repeated VectorClockEntry version = 5;
467}
468
469message GetCodeActionsResponse {
470    repeated CodeAction actions = 1;
471    repeated VectorClockEntry version = 2;
472}
473
474message GetHover {
475    uint64 project_id = 1;
476    uint64 buffer_id = 2;
477    Anchor position = 3;
478    repeated VectorClockEntry version = 5;
479}
480
481message GetHoverResponse {
482    optional Anchor start = 1;
483    optional Anchor end = 2;
484    repeated HoverBlock contents = 3;
485}
486
487message HoverBlock {
488    string text = 1;
489    optional string language = 2;
490}
491
492message ApplyCodeAction {
493    uint64 project_id = 1;
494    uint64 buffer_id = 2;
495    CodeAction action = 3;
496}
497
498message ApplyCodeActionResponse {
499    ProjectTransaction transaction = 1;
500}
501
502message PrepareRename {
503    uint64 project_id = 1;
504    uint64 buffer_id = 2;
505    Anchor position = 3;
506    repeated VectorClockEntry version = 4;
507}
508
509message PrepareRenameResponse {
510    bool can_rename = 1;
511    Anchor start = 2;
512    Anchor end = 3;
513    repeated VectorClockEntry version = 4;
514}
515
516message PerformRename {
517    uint64 project_id = 1;
518    uint64 buffer_id = 2;
519    Anchor position = 3;
520    string new_name = 4;
521    repeated VectorClockEntry version = 5;
522}
523
524message PerformRenameResponse {
525    ProjectTransaction transaction = 2;
526}
527
528message SearchProject {
529    uint64 project_id = 1;
530    string query = 2;
531    bool regex = 3;
532    bool whole_word = 4;
533    bool case_sensitive = 5;
534}
535
536message SearchProjectResponse {
537    repeated Location locations = 1;
538}
539
540message CodeAction {
541    Anchor start = 1;
542    Anchor end = 2;
543    bytes lsp_action = 3;
544}
545
546message ProjectTransaction {
547    repeated uint64 buffer_ids = 1;
548    repeated Transaction transactions = 2;
549}
550
551message Transaction {
552    LocalTimestamp id = 1;
553    repeated LocalTimestamp edit_ids = 2;
554    repeated VectorClockEntry start = 3;
555}
556
557message LocalTimestamp {
558    uint32 replica_id = 1;
559    uint32 value = 2;
560}
561
562message LanguageServer {
563    uint64 id = 1;
564    string name = 2;
565}
566
567message StartLanguageServer {
568    uint64 project_id = 1;
569    LanguageServer server = 2;
570}
571
572message UpdateDiagnosticSummary {
573    uint64 project_id = 1;
574    uint64 worktree_id = 2;
575    DiagnosticSummary summary = 3;
576}
577
578message DiagnosticSummary {
579    string path = 1;
580    uint64 language_server_id = 2;
581    uint32 error_count = 3;
582    uint32 warning_count = 4;
583}
584
585message UpdateLanguageServer {
586    uint64 project_id = 1;
587    uint64 language_server_id = 2;
588    oneof variant {
589        LspWorkStart work_start = 3;
590        LspWorkProgress work_progress = 4;
591        LspWorkEnd work_end = 5;
592        LspDiskBasedDiagnosticsUpdating disk_based_diagnostics_updating = 6;
593        LspDiskBasedDiagnosticsUpdated disk_based_diagnostics_updated = 7;
594    }
595}
596
597message LspWorkStart {
598    string token = 1;
599    optional string message = 2;
600    optional uint32 percentage = 3;
601}
602
603message LspWorkProgress {
604    string token = 1;
605    optional string message = 2;
606    optional uint32 percentage = 3;
607}
608
609message LspWorkEnd {
610    string token = 1;
611}
612
613message LspDiskBasedDiagnosticsUpdating {}
614
615message LspDiskBasedDiagnosticsUpdated {}
616
617message GetChannels {}
618
619message GetChannelsResponse {
620    repeated Channel channels = 1;
621}
622
623message JoinChannel {
624    uint64 channel_id = 1;
625}
626
627message JoinChannelResponse {
628    repeated ChannelMessage messages = 1;
629    bool done = 2;
630}
631
632message LeaveChannel {
633    uint64 channel_id = 1;
634}
635
636message GetUsers {
637    repeated uint64 user_ids = 1;
638}
639
640message FuzzySearchUsers {
641    string query = 1;
642}
643
644message UsersResponse {
645    repeated User users = 1;
646}
647
648message RequestContact {
649    uint64 responder_id = 1;
650}
651
652message RemoveContact {
653    uint64 user_id = 1;
654}
655
656message RespondToContactRequest {
657    uint64 requester_id = 1;
658    ContactRequestResponse response = 2;
659}
660
661enum ContactRequestResponse {
662    Accept = 0;
663    Decline = 1;
664    Block = 2;
665    Dismiss = 3;
666}
667
668message SendChannelMessage {
669    uint64 channel_id = 1;
670    string body = 2;
671    Nonce nonce = 3;
672}
673
674message SendChannelMessageResponse {
675    ChannelMessage message = 1;
676}
677
678message ChannelMessageSent {
679    uint64 channel_id = 1;
680    ChannelMessage message = 2;
681}
682
683message GetChannelMessages {
684    uint64 channel_id = 1;
685    uint64 before_message_id = 2;
686}
687
688message GetChannelMessagesResponse {
689    repeated ChannelMessage messages = 1;
690    bool done = 2;
691}
692
693message UpdateContacts {
694    repeated Contact contacts = 1;
695    repeated uint64 remove_contacts = 2;
696    repeated IncomingContactRequest incoming_requests = 3;
697    repeated uint64 remove_incoming_requests = 4;
698    repeated uint64 outgoing_requests = 5;
699    repeated uint64 remove_outgoing_requests = 6;
700}
701
702message UpdateInviteInfo {
703    string url = 1;
704    uint32 count = 2;
705}
706
707message ShowContacts {}
708
709message IncomingContactRequest {
710    uint64 requester_id = 1;
711    bool should_notify = 2;
712}
713
714message UpdateDiagnostics {
715    uint32 replica_id = 1;
716    uint32 lamport_timestamp = 2;
717    repeated Diagnostic diagnostics = 3;
718}
719
720message Follow {
721    uint64 project_id = 1;
722    uint32 leader_id = 2;
723}
724
725message FollowResponse {
726    optional uint64 active_view_id = 1;
727    repeated View views = 2;
728}
729
730message UpdateFollowers {
731    uint64 project_id = 1;
732    repeated uint32 follower_ids = 2;
733    oneof variant {
734        UpdateActiveView update_active_view = 3;
735        View create_view = 4;
736        UpdateView update_view = 5;
737    }
738}
739
740message Unfollow {
741    uint64 project_id = 1;
742    uint32 leader_id = 2;
743}
744
745// Entities
746
747message UpdateActiveView {
748    optional uint64 id = 1;
749    optional uint32 leader_id = 2;
750}
751
752message UpdateView {
753    uint64 id = 1;
754    optional uint32 leader_id = 2;
755
756    oneof variant {
757        Editor editor = 3;
758    }
759
760    message Editor {
761        repeated Selection selections = 1;
762        Anchor scroll_top_anchor = 2;
763        float scroll_x = 3;
764        float scroll_y = 4;
765    }
766}
767
768message View {
769    uint64 id = 1;
770    optional uint32 leader_id = 2;
771
772    oneof variant {
773        Editor editor = 3;
774    }
775
776    message Editor {
777        uint64 buffer_id = 1;
778        repeated Selection selections = 2;
779        Anchor scroll_top_anchor = 3;
780        float scroll_x = 4;
781        float scroll_y = 5;
782    }
783}
784
785message Collaborator {
786    uint32 peer_id = 1;
787    uint32 replica_id = 2;
788    uint64 user_id = 3;
789}
790
791message User {
792    uint64 id = 1;
793    string github_login = 2;
794    string avatar_url = 3;
795}
796
797message File {
798    uint64 worktree_id = 1;
799    optional uint64 entry_id = 2;
800    string path = 3;
801    Timestamp mtime = 4;
802}
803
804message Entry {
805    uint64 id = 1;
806    bool is_dir = 2;
807    bytes path = 3;
808    uint64 inode = 4;
809    Timestamp mtime = 5;
810    bool is_symlink = 6;
811    bool is_ignored = 7;
812}
813
814message BufferState {
815    uint64 id = 1;
816    optional File file = 2;
817    string base_text = 3;
818    LineEnding line_ending = 4;
819}
820
821message BufferChunk {
822    uint64 buffer_id = 1;
823    repeated Operation operations = 2;
824    bool is_last = 3;
825}
826
827enum LineEnding {
828    Unix = 0;
829    Windows = 1;
830}
831
832message SelectionSet {
833    uint32 replica_id = 1;
834    repeated Selection selections = 2;
835    uint32 lamport_timestamp = 3;
836    bool line_mode = 4;
837}
838
839message Selection {
840    uint64 id = 1;
841    Anchor start = 2;
842    Anchor end = 3;
843    bool reversed = 4;
844}
845
846message Anchor {
847    uint32 replica_id = 1;
848    uint32 local_timestamp = 2;
849    uint64 offset = 3;
850    Bias bias = 4;
851    optional uint64 buffer_id = 5;
852}
853
854enum Bias {
855    Left = 0;
856    Right = 1;
857}
858
859message Diagnostic {
860    Anchor start = 1;
861    Anchor end = 2;
862    Severity severity = 3;
863    string message = 4;
864    optional string code = 5;
865    uint64 group_id = 6;
866    bool is_primary = 7;
867    bool is_valid = 8;
868    bool is_disk_based = 9;
869    bool is_unnecessary = 10;
870
871    enum Severity {
872        None = 0;
873        Error = 1;
874        Warning = 2;
875        Information = 3;
876        Hint = 4;
877    }
878}
879
880message Operation {
881    oneof variant {
882        Edit edit = 1;
883        Undo undo = 2;
884        UpdateSelections update_selections = 3;
885        UpdateDiagnostics update_diagnostics = 4;
886        UpdateCompletionTriggers update_completion_triggers = 5;
887    }
888
889    message Edit {
890        uint32 replica_id = 1;
891        uint32 local_timestamp = 2;
892        uint32 lamport_timestamp = 3;
893        repeated VectorClockEntry version = 4;
894        repeated Range ranges = 5;
895        repeated string new_text = 6;
896    }
897
898    message Undo {
899        uint32 replica_id = 1;
900        uint32 local_timestamp = 2;
901        uint32 lamport_timestamp = 3;
902        repeated VectorClockEntry version = 4;
903        repeated UndoCount counts = 5;
904    }
905
906    message UpdateSelections {
907        uint32 replica_id = 1;
908        uint32 lamport_timestamp = 2;
909        repeated Selection selections = 3;
910        bool line_mode = 4;
911    }
912
913    message UpdateCompletionTriggers {
914        uint32 replica_id = 1;
915        uint32 lamport_timestamp = 2;
916        repeated string triggers = 3;
917    }
918}
919
920message UndoMapEntry {
921    uint32 replica_id = 1;
922    uint32 local_timestamp = 2;
923    repeated UndoCount counts = 3;
924}
925
926message UndoCount {
927    uint32 replica_id = 1;
928    uint32 local_timestamp = 2;
929    uint32 count = 3;
930}
931
932message VectorClockEntry {
933    uint32 replica_id = 1;
934    uint32 timestamp = 2;
935}
936
937message Timestamp {
938    uint64 seconds = 1;
939    uint32 nanos = 2;
940}
941
942message Range {
943    uint64 start = 1;
944    uint64 end = 2;
945}
946
947message Point {
948    uint32 row = 1;
949    uint32 column = 2;
950}
951
952message Nonce {
953    uint64 upper_half = 1;
954    uint64 lower_half = 2;
955}
956
957message Channel {
958    uint64 id = 1;
959    string name = 2;
960}
961
962message ChannelMessage {
963    uint64 id = 1;
964    string body = 2;
965    uint64 timestamp = 3;
966    uint64 sender_id = 4;
967    Nonce nonce = 5;
968}
969
970message Contact {
971    uint64 user_id = 1;
972    repeated ProjectMetadata projects = 2;
973    bool online = 3;
974    bool should_notify = 4;
975}
976
977message ProjectMetadata {
978    uint64 id = 1;
979    repeated string visible_worktree_root_names = 3;
980    repeated uint64 guests = 4;
981}
982
983message WorktreeMetadata {
984    uint64 id = 1;
985    string root_name = 2;
986    bool visible = 3;
987}