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