@opsee/mcp-server 0.5.6 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,60 @@
1
+ // @generated by protoc-gen-es v2.2.3
2
+ // @generated from file api/v1/task_dependency.proto (package api.v1, syntax proto3)
3
+ /* eslint-disable */
4
+
5
+ import { fileDesc, messageDesc, serviceDesc } from "@bufbuild/protobuf/codegenv1";
6
+ import { file_google_protobuf_empty } from "@bufbuild/protobuf/wkt";
7
+ import { file_google_api_annotations } from "../../google/api/annotations_pb";
8
+ import { file_validate_validate } from "../../validate/validate_pb";
9
+ import { file_api_v1_pagination } from "./pagination_pb";
10
+ import { file_api_v1_models } from "./models_pb";
11
+
12
+ /**
13
+ * Describes the file api/v1/task_dependency.proto.
14
+ */
15
+ export const file_api_v1_task_dependency = /*@__PURE__*/
16
+ fileDesc("ChxhcGkvdjEvdGFza19kZXBlbmRlbmN5LnByb3RvEgZhcGkudjEijAEKGEFkZFRhc2tEZXBlbmRlbmN5UmVxdWVzdBIdCgxmcm9tX3Rhc2tfaWQYASABKA1CB/pCBCoCKAESGwoKdG9fdGFza19pZBgCIAEoDUIH+kIEKgIoARI0CgR0eXBlGAMgASgOMhouYXBpLnYxLlRhc2tEZXBlbmRlbmN5VHlwZUIK+kIHggEEEAEgACJeChpHZXRUYXNrRGVwZW5kZW5jaWVzUmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBEiYKCnBhZ2luYXRpb24YAiABKAsyEi5hcGkudjEuUGFnaW5hdGlvbiIyChtEZWxldGVUYXNrRGVwZW5kZW5jeVJlcXVlc3QSEwoCaWQYASABKA1CB/pCBCoCKAEiTAoZQWRkVGFza0RlcGVuZGVuY3lSZXNwb25zZRIvCg90YXNrX2RlcGVuZGVuY3kYASABKAsyFi5hcGkudjEuVGFza0RlcGVuZGVuY3kieAobR2V0VGFza0RlcGVuZGVuY2llc1Jlc3BvbnNlEjEKEXRhc2tfZGVwZW5kZW5jaWVzGAEgAygLMhYuYXBpLnYxLlRhc2tEZXBlbmRlbmN5EiYKCnBhZ2luYXRpb24YAiABKAsyEi5hcGkudjEuUGFnaW5hdGlvbjKYAwoVVGFza0RlcGVuZGVuY3lTZXJ2aWNlEn4KEUFkZFRhc2tEZXBlbmRlbmN5EiAuYXBpLnYxLkFkZFRhc2tEZXBlbmRlbmN5UmVxdWVzdBohLmFwaS52MS5BZGRUYXNrRGVwZW5kZW5jeVJlc3BvbnNlIiSC0+STAh46ASoiGS9hcGkvdjEvdGFzay1kZXBlbmRlbmNpZXMSgQEKE0dldFRhc2tEZXBlbmRlbmNpZXMSIi5hcGkudjEuR2V0VGFza0RlcGVuZGVuY2llc1JlcXVlc3QaIy5hcGkudjEuR2V0VGFza0RlcGVuZGVuY2llc1Jlc3BvbnNlIiGC0+STAhsSGS9hcGkvdjEvdGFzay1kZXBlbmRlbmNpZXMSewoURGVsZXRlVGFza0RlcGVuZGVuY3kSIy5hcGkudjEuRGVsZXRlVGFza0RlcGVuZGVuY3lSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IiaC0+STAiAqHi9hcGkvdjEvdGFzay1kZXBlbmRlbmNpZXMve2lkfUJ4Cgpjb20uYXBpLnYxQhNUYXNrRGVwZW5kZW5jeVByb3RvUAFaHG9wc2VlL2JhY2tlbmQvZ2VuL2FwaS92MTtnZW6iAgNBWFiqAgZBcGkuVjHKAgZBcGlcVjHiAhJBcGlcVjFcR1BCTWV0YWRhdGHqAgdBcGk6OlYxYgZwcm90bzM", [file_google_protobuf_empty, file_google_api_annotations, file_validate_validate, file_api_v1_pagination, file_api_v1_models]);
17
+
18
+ /**
19
+ * Describes the message api.v1.AddTaskDependencyRequest.
20
+ * Use `create(AddTaskDependencyRequestSchema)` to create a new message.
21
+ */
22
+ export const AddTaskDependencyRequestSchema = /*@__PURE__*/
23
+ messageDesc(file_api_v1_task_dependency, 0);
24
+
25
+ /**
26
+ * Describes the message api.v1.GetTaskDependenciesRequest.
27
+ * Use `create(GetTaskDependenciesRequestSchema)` to create a new message.
28
+ */
29
+ export const GetTaskDependenciesRequestSchema = /*@__PURE__*/
30
+ messageDesc(file_api_v1_task_dependency, 1);
31
+
32
+ /**
33
+ * Describes the message api.v1.DeleteTaskDependencyRequest.
34
+ * Use `create(DeleteTaskDependencyRequestSchema)` to create a new message.
35
+ */
36
+ export const DeleteTaskDependencyRequestSchema = /*@__PURE__*/
37
+ messageDesc(file_api_v1_task_dependency, 2);
38
+
39
+ /**
40
+ * Describes the message api.v1.AddTaskDependencyResponse.
41
+ * Use `create(AddTaskDependencyResponseSchema)` to create a new message.
42
+ */
43
+ export const AddTaskDependencyResponseSchema = /*@__PURE__*/
44
+ messageDesc(file_api_v1_task_dependency, 3);
45
+
46
+ /**
47
+ * Describes the message api.v1.GetTaskDependenciesResponse.
48
+ * Use `create(GetTaskDependenciesResponseSchema)` to create a new message.
49
+ */
50
+ export const GetTaskDependenciesResponseSchema = /*@__PURE__*/
51
+ messageDesc(file_api_v1_task_dependency, 4);
52
+
53
+ /**
54
+ * Service
55
+ *
56
+ * @generated from service api.v1.TaskDependencyService
57
+ */
58
+ export const TaskDependencyService = /*@__PURE__*/
59
+ serviceDesc(file_api_v1_task_dependency, 0);
60
+
@@ -303,6 +303,11 @@ export declare type GetTasksRequest = Message<"api.v1.GetTasksRequest"> & {
303
303
  * @generated from field: api.v1.FilterOptions filter_options = 3;
304
304
  */
305
305
  filterOptions?: FilterOptions;
306
+
307
+ /**
308
+ * @generated from field: repeated uint32 label_ids = 4;
309
+ */
310
+ labelIds: number[];
306
311
  };
307
312
 
308
313
  /**
@@ -497,9 +502,18 @@ export declare type ImportTasksRequest = Message<"api.v1.ImportTasksRequest"> &
497
502
  projectId: number;
498
503
 
499
504
  /**
505
+ * csv_content is capped at 10 MiB to prevent OOM from a malicious or
506
+ * accidental gigabyte upload. The service layer additionally caps the
507
+ * row count.
508
+ *
500
509
  * @generated from field: bytes csv_content = 2;
501
510
  */
502
511
  csvContent: Uint8Array;
512
+
513
+ /**
514
+ * @generated from field: bool skip_notifications = 3;
515
+ */
516
+ skipNotifications: boolean;
503
517
  };
504
518
 
505
519
  /**
@@ -508,6 +522,32 @@ export declare type ImportTasksRequest = Message<"api.v1.ImportTasksRequest"> &
508
522
  */
509
523
  export declare const ImportTasksRequestSchema: GenMessage<ImportTasksRequest>;
510
524
 
525
+ /**
526
+ * @generated from message api.v1.ImportedTask
527
+ */
528
+ export declare type ImportedTask = Message<"api.v1.ImportedTask"> & {
529
+ /**
530
+ * @generated from field: string external_id = 1;
531
+ */
532
+ externalId: string;
533
+
534
+ /**
535
+ * @generated from field: uint32 task_id = 2;
536
+ */
537
+ taskId: number;
538
+
539
+ /**
540
+ * @generated from field: bool created = 3;
541
+ */
542
+ created: boolean;
543
+ };
544
+
545
+ /**
546
+ * Describes the message api.v1.ImportedTask.
547
+ * Use `create(ImportedTaskSchema)` to create a new message.
548
+ */
549
+ export declare const ImportedTaskSchema: GenMessage<ImportedTask>;
550
+
511
551
  /**
512
552
  * @generated from message api.v1.ImportTasksResponse
513
553
  */
@@ -531,6 +571,16 @@ export declare type ImportTasksResponse = Message<"api.v1.ImportTasksResponse">
531
571
  * @generated from field: repeated string errors = 4;
532
572
  */
533
573
  errors: string[];
574
+
575
+ /**
576
+ * @generated from field: int32 skipped_count = 5;
577
+ */
578
+ skippedCount: number;
579
+
580
+ /**
581
+ * @generated from field: repeated api.v1.ImportedTask created_tasks = 6;
582
+ */
583
+ createdTasks: ImportedTask[];
534
584
  };
535
585
 
536
586
  /**
@@ -539,6 +589,84 @@ export declare type ImportTasksResponse = Message<"api.v1.ImportTasksResponse">
539
589
  */
540
590
  export declare const ImportTasksResponseSchema: GenMessage<ImportTasksResponse>;
541
591
 
592
+ /**
593
+ * @generated from message api.v1.TaskLink
594
+ */
595
+ export declare type TaskLink = Message<"api.v1.TaskLink"> & {
596
+ /**
597
+ * external_id matches the column we add on Task; 128-char varchar in DB.
598
+ *
599
+ * @generated from field: string external_id = 1;
600
+ */
601
+ externalId: string;
602
+
603
+ /**
604
+ * @generated from field: optional string parent_external_id = 2;
605
+ */
606
+ parentExternalId?: string;
607
+
608
+ /**
609
+ * @generated from field: optional string milestone_name = 3;
610
+ */
611
+ milestoneName?: string;
612
+ };
613
+
614
+ /**
615
+ * Describes the message api.v1.TaskLink.
616
+ * Use `create(TaskLinkSchema)` to create a new message.
617
+ */
618
+ export declare const TaskLinkSchema: GenMessage<TaskLink>;
619
+
620
+ /**
621
+ * @generated from message api.v1.LinkTasksByExternalIdRequest
622
+ */
623
+ export declare type LinkTasksByExternalIdRequest = Message<"api.v1.LinkTasksByExternalIdRequest"> & {
624
+ /**
625
+ * @generated from field: uint32 project_id = 1;
626
+ */
627
+ projectId: number;
628
+
629
+ /**
630
+ * Cap on per-call links keeps the in-transaction work bounded; matches the
631
+ * per-import row cap on the service side.
632
+ *
633
+ * @generated from field: repeated api.v1.TaskLink links = 2;
634
+ */
635
+ links: TaskLink[];
636
+ };
637
+
638
+ /**
639
+ * Describes the message api.v1.LinkTasksByExternalIdRequest.
640
+ * Use `create(LinkTasksByExternalIdRequestSchema)` to create a new message.
641
+ */
642
+ export declare const LinkTasksByExternalIdRequestSchema: GenMessage<LinkTasksByExternalIdRequest>;
643
+
644
+ /**
645
+ * @generated from message api.v1.LinkTasksByExternalIdResponse
646
+ */
647
+ export declare type LinkTasksByExternalIdResponse = Message<"api.v1.LinkTasksByExternalIdResponse"> & {
648
+ /**
649
+ * @generated from field: int32 linked_parents = 1;
650
+ */
651
+ linkedParents: number;
652
+
653
+ /**
654
+ * @generated from field: int32 linked_milestones = 2;
655
+ */
656
+ linkedMilestones: number;
657
+
658
+ /**
659
+ * @generated from field: repeated string errors = 3;
660
+ */
661
+ errors: string[];
662
+ };
663
+
664
+ /**
665
+ * Describes the message api.v1.LinkTasksByExternalIdResponse.
666
+ * Use `create(LinkTasksByExternalIdResponseSchema)` to create a new message.
667
+ */
668
+ export declare const LinkTasksByExternalIdResponseSchema: GenMessage<LinkTasksByExternalIdResponse>;
669
+
542
670
  /**
543
671
  * @generated from message api.v1.BulkEditTasksRequest
544
672
  */
@@ -733,6 +861,14 @@ export declare const TaskService: GenService<{
733
861
  input: typeof ImportTasksRequestSchema;
734
862
  output: typeof ImportTasksResponseSchema;
735
863
  },
864
+ /**
865
+ * @generated from rpc api.v1.TaskService.LinkTasksByExternalId
866
+ */
867
+ linkTasksByExternalId: {
868
+ methodKind: "unary";
869
+ input: typeof LinkTasksByExternalIdRequestSchema;
870
+ output: typeof LinkTasksByExternalIdResponseSchema;
871
+ },
736
872
  /**
737
873
  * @generated from rpc api.v1.TaskService.AddTask
738
874
  */
@@ -14,7 +14,7 @@ import { file_api_v1_models } from "./models_pb";
14
14
  * Describes the file api/v1/task.proto.
15
15
  */
16
16
  export const file_api_v1_task = /*@__PURE__*/
17
- fileDesc("ChFhcGkvdjEvdGFzay5wcm90bxIGYXBpLnYxIvkFCg5BZGRUYXNrUmVxdWVzdBIiCgppZGVudGlmaWVyGAEgASgJQgn6QgZyBBABGDJIAIgBARIZCgV0aXRsZRgCIAEoCUIK+kIHcgUQARjIARIYCgtkZXNjcmlwdGlvbhgDIAEoCUgBiAEBEh4KDWRpc3BsYXlfb3JkZXIYBCABKAVCB/pCBBoCKAASIgoMc3RvcnlfcG9pbnRzGAUgASgFQgf6QgQaAigBSAKIAQESLAoPZXN0aW1hdGVkX2hvdXJzGAYgASgBQg76QgsSCSkAAAAAAAAAAEgDiAEBEikKDGFjdHVhbF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIBIgBARIsCghkdWVfZGF0ZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFwoPYWlfbW9kZV9lbmFibGVkGAkgASgIEhoKDW1ldGFkYXRhX2pzb24YCiABKAlIBYgBARIQCghib2FyZF9pZBgLIAEoDRIXCg9ib2FyZF9jb2x1bW5faWQYDCABKA0SEgoKcHJvamVjdF9pZBgNIAEoDRIUCgx0YXNrX3R5cGVfaWQYDiABKA0SGAoQdGFza19wcmlvcml0eV9pZBgPIAEoDRIYChByZXBvcnRlcl91c2VyX2lkGBAgASgNEh0KEGFzc2lnbmVkX3VzZXJfaWQYESABKA1IBogBARIbCg5wYXJlbnRfdGFza19pZBgSIAEoDUgHiAEBEhYKDnJlcG9zaXRvcnlfaWRzGBMgAygNEhUKCGN5Y2xlX2lkGBQgASgNSAiIAQFCDQoLX2lkZW50aWZpZXJCDgoMX2Rlc2NyaXB0aW9uQg8KDV9zdG9yeV9wb2ludHNCEgoQX2VzdGltYXRlZF9ob3Vyc0IPCg1fYWN0dWFsX2hvdXJzQhAKDl9tZXRhZGF0YV9qc29uQhMKEV9hc3NpZ25lZF91c2VyX2lkQhEKD19wYXJlbnRfdGFza19pZEILCglfY3ljbGVfaWQi4gYKD0VkaXRUYXNrUmVxdWVzdBITCgJpZBgBIAEoDUIH+kIEKgIoARIdCgppZGVudGlmaWVyGAIgASgJQgn6QgZyBBABGDISGQoFdGl0bGUYAyABKAlCCvpCB3IFEAEYyAESGAoLZGVzY3JpcHRpb24YBCABKAlIAIgBARIeCg1kaXNwbGF5X29yZGVyGAUgASgFQgf6QgQaAigAEiIKDHN0b3J5X3BvaW50cxgGIAEoBUIH+kIEGgIoAUgBiAEBEiwKD2VzdGltYXRlZF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIAogBARIpCgxhY3R1YWxfaG91cnMYCCABKAFCDvpCCxIJKQAAAAAAAAAASAOIAQESLAoIZHVlX2RhdGUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhcKD2FpX21vZGVfZW5hYmxlZBgKIAEoCBIaCg1tZXRhZGF0YV9qc29uGAsgASgJSASIAQESEAoIYm9hcmRfaWQYDCABKA0SFwoPYm9hcmRfY29sdW1uX2lkGA0gASgNEhIKCnByb2plY3RfaWQYDiABKA0SFAoMdGFza190eXBlX2lkGA8gASgNEhgKEHRhc2tfcHJpb3JpdHlfaWQYECABKA0SGAoQcmVwb3J0ZXJfdXNlcl9pZBgRIAEoDRIdChBhc3NpZ25lZF91c2VyX2lkGBIgASgNSAWIAQESGwoOcGFyZW50X3Rhc2tfaWQYEyABKA1IBogBARIWCg5yZXBvc2l0b3J5X2lkcxgUIAMoDRIVCghjeWNsZV9pZBgVIAEoDUgHiAEBEi8KC3Jlc29sdmVkX2F0GBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIeChFvcmlnaW5hbF9lc3RpbWF0ZRgXIAEoAUgIiAEBQg4KDF9kZXNjcmlwdGlvbkIPCg1fc3RvcnlfcG9pbnRzQhIKEF9lc3RpbWF0ZWRfaG91cnNCDwoNX2FjdHVhbF9ob3Vyc0IQCg5fbWV0YWRhdGFfanNvbkITChFfYXNzaWduZWRfdXNlcl9pZEIRCg9fcGFyZW50X3Rhc2tfaWRCCwoJX2N5Y2xlX2lkQhQKEl9vcmlnaW5hbF9lc3RpbWF0ZSIcCg5HZXRUYXNrUmVxdWVzdBIKCgJpZBgBIAEoDSIuChRHZXRUYXNrQnlVVUlEUmVxdWVzdBIWCgR1dWlkGAEgASgJQgj6QgVyA7ABASKPAQoPR2V0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESMAoKcGFnaW5hdGlvbhgCIAEoCzISLmFwaS52MS5QYWdpbmF0aW9uQgj6QgWKAQIQARItCg5maWx0ZXJfb3B0aW9ucxgDIAEoCzIVLmFwaS52MS5GaWx0ZXJPcHRpb25zIh8KEURlbGV0ZVRhc2tSZXF1ZXN0EgoKAmlkGAEgASgNIlcKEEdldFRhc2tzUmVzcG9uc2USGwoFdGFza3MYASADKAsyDC5hcGkudjEuVGFzaxImCgpwYWdpbmF0aW9uGAIgASgLMhIuYXBpLnYxLlBhZ2luYXRpb24iLQoPQWRkVGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayIuChBFZGl0VGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayItCg9HZXRUYXNrUmVzcG9uc2USGgoEdGFzaxgBIAEoCzIMLmFwaS52MS5UYXNrIjQKGFRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBIk4KGVRyaWdnZXJBSVdvcmtmbG93UmVzcG9uc2USEAoIam9iX25hbWUYASABKAkSDgoGc3RhdHVzGAIgASgJEg8KB21lc3NhZ2UYAyABKAkicgoSRXhwb3J0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESLQoOZmlsdGVyX29wdGlvbnMYAiABKAsyFS5hcGkudjEuRmlsdGVyT3B0aW9ucxIQCgh0YXNrX2lkcxgDIAMoDSI8ChNFeHBvcnRUYXNrc1Jlc3BvbnNlEhMKC2Nzdl9jb250ZW50GAEgASgMEhAKCGZpbGVuYW1lGAIgASgJIk8KEkltcG9ydFRhc2tzUmVxdWVzdBIbCgpwcm9qZWN0X2lkGAEgASgNQgf6QgQqAigBEhwKC2Nzdl9jb250ZW50GAIgASgMQgf6QgR6AhABImkKE0ltcG9ydFRhc2tzUmVzcG9uc2USFQoNY3JlYXRlZF9jb3VudBgBIAEoBRIVCg11cGRhdGVkX2NvdW50GAIgASgFEhQKDGZhaWxlZF9jb3VudBgDIAEoBRIOCgZlcnJvcnMYBCADKAki0QIKFEJ1bGtFZGl0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESGgoIdGFza19pZHMYAiADKA1CCPpCBZIBAggBEhwKD2JvYXJkX2NvbHVtbl9pZBgDIAEoDUgAiAEBEh0KEHRhc2tfcHJpb3JpdHlfaWQYBCABKA1IAYgBARIZCgx0YXNrX3R5cGVfaWQYBSABKA1IAogBARIdChBhc3NpZ25lZF91c2VyX2lkGAYgASgNSAOIAQESFQoIY3ljbGVfaWQYByABKA1IBIgBARIWCg5yZXBvc2l0b3J5X2lkcxgIIAMoDUISChBfYm9hcmRfY29sdW1uX2lkQhMKEV90YXNrX3ByaW9yaXR5X2lkQg8KDV90YXNrX3R5cGVfaWRCEwoRX2Fzc2lnbmVkX3VzZXJfaWRCCwoJX2N5Y2xlX2lkIi4KFUJ1bGtFZGl0VGFza3NSZXNwb25zZRIVCg11cGRhdGVkX2NvdW50GAEgASgFIlEKFkJ1bGtEZWxldGVUYXNrc1JlcXVlc3QSGwoKcHJvamVjdF9pZBgBIAEoDUIH+kIEKgIoARIaCgh0YXNrX2lkcxgCIAMoDUII+kIFkgECCAEiMAoXQnVsa0RlbGV0ZVRhc2tzUmVzcG9uc2USFQoNZGVsZXRlZF9jb3VudBgBIAEoBSJ2ChFBZGRXb3JrTG9nUmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBEh0KBWhvdXJzGAIgASgBQg76QgsSCSmamZmZmZm5PxIYCgtkZXNjcmlwdGlvbhgDIAEoCUgAiAEBQg4KDF9kZXNjcmlwdGlvbiI3ChJBZGRXb3JrTG9nUmVzcG9uc2USIQoId29ya19sb2cYASABKAsyDy5hcGkudjEuV29ya0xvZyIzChREZWxldGVXb3JrTG9nUmVxdWVzdBIPCgd0YXNrX2lkGAEgASgNEgoKAmlkGAIgASgNMr4LCgtUYXNrU2VydmljZRJ9CgtFeHBvcnRUYXNrcxIaLmFwaS52MS5FeHBvcnRUYXNrc1JlcXVlc3QaGy5hcGkudjEuRXhwb3J0VGFza3NSZXNwb25zZSI1gtPkkwIvOgEqIiovYXBpL3YxL3Byb2plY3RzL3twcm9qZWN0X2lkfS90YXNrcy9leHBvcnQSfQoLSW1wb3J0VGFza3MSGi5hcGkudjEuSW1wb3J0VGFza3NSZXF1ZXN0GhsuYXBpLnYxLkltcG9ydFRhc2tzUmVzcG9uc2UiNYLT5JMCLzoBKiIqL2FwaS92MS9wcm9qZWN0cy97cHJvamVjdF9pZH0vdGFza3MvaW1wb3J0ElQKB0FkZFRhc2sSFi5hcGkudjEuQWRkVGFza1JlcXVlc3QaFy5hcGkudjEuQWRkVGFza1Jlc3BvbnNlIhiC0+STAhI6ASoiDS9hcGkvdjEvdGFza3MSXAoIRWRpdFRhc2sSFy5hcGkudjEuRWRpdFRhc2tSZXF1ZXN0GhguYXBpLnYxLkVkaXRUYXNrUmVzcG9uc2UiHYLT5JMCFzoBKhoSL2FwaS92MS90YXNrcy97aWR9ElYKB0dldFRhc2sSFi5hcGkudjEuR2V0VGFza1JlcXVlc3QaFy5hcGkudjEuR2V0VGFza1Jlc3BvbnNlIhqC0+STAhQSEi9hcGkvdjEvdGFza3Mve2lkfRJpCg1HZXRUYXNrQnlVVUlEEhwuYXBpLnYxLkdldFRhc2tCeVVVSURSZXF1ZXN0GhcuYXBpLnYxLkdldFRhc2tSZXNwb25zZSIhgtPkkwIbEhkvYXBpL3YxL3Rhc2tzL3V1aWQve3V1aWR9ElQKCEdldFRhc2tzEhcuYXBpLnYxLkdldFRhc2tzUmVxdWVzdBoYLmFwaS52MS5HZXRUYXNrc1Jlc3BvbnNlIhWC0+STAg8SDS9hcGkvdjEvdGFza3MSWwoKRGVsZXRlVGFzaxIZLmFwaS52MS5EZWxldGVUYXNrUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIagtPkkwIUKhIvYXBpL3YxL3Rhc2tzL3tpZH0ShwEKEVRyaWdnZXJBSVdvcmtmbG93EiAuYXBpLnYxLlRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBohLmFwaS52MS5UcmlnZ2VyQUlXb3JrZmxvd1Jlc3BvbnNlIi2C0+STAic6ASoiIi9hcGkvdjEvdGFza3Mve3Rhc2tfaWR9L3RyaWdnZXItYWkScQoKQWRkV29ya0xvZxIZLmFwaS52MS5BZGRXb3JrTG9nUmVxdWVzdBoaLmFwaS52MS5BZGRXb3JrTG9nUmVzcG9uc2UiLILT5JMCJjoBKiIhL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzEnUKDURlbGV0ZVdvcmtMb2cSHC5hcGkudjEuRGVsZXRlV29ya0xvZ1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiLoLT5JMCKComL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzL3tpZH0SgQEKDUJ1bGtFZGl0VGFza3MSHC5hcGkudjEuQnVsa0VkaXRUYXNrc1JlcXVlc3QaHS5hcGkudjEuQnVsa0VkaXRUYXNrc1Jlc3BvbnNlIjOC0+STAi06ASoaKC9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGsSjgEKD0J1bGtEZWxldGVUYXNrcxIeLmFwaS52MS5CdWxrRGVsZXRlVGFza3NSZXF1ZXN0Gh8uYXBpLnYxLkJ1bGtEZWxldGVUYXNrc1Jlc3BvbnNlIjqC0+STAjQ6ASoiLy9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGstZGVsZXRlQm4KCmNvbS5hcGkudjFCCVRhc2tQcm90b1ABWhxvcHNlZS9iYWNrZW5kL2dlbi9hcGkvdjE7Z2VuogIDQVhYqgIGQXBpLlYxygIGQXBpXFYx4gISQXBpXFYxXEdQQk1ldGFkYXRh6gIHQXBpOjpWMWIGcHJvdG8z", [file_google_protobuf_empty, file_google_protobuf_timestamp, file_google_api_annotations, file_validate_validate, file_api_v1_pagination, file_api_v1_filter, file_api_v1_models]);
17
+ fileDesc("ChFhcGkvdjEvdGFzay5wcm90bxIGYXBpLnYxIvkFCg5BZGRUYXNrUmVxdWVzdBIiCgppZGVudGlmaWVyGAEgASgJQgn6QgZyBBABGDJIAIgBARIZCgV0aXRsZRgCIAEoCUIK+kIHcgUQARjIARIYCgtkZXNjcmlwdGlvbhgDIAEoCUgBiAEBEh4KDWRpc3BsYXlfb3JkZXIYBCABKAVCB/pCBBoCKAASIgoMc3RvcnlfcG9pbnRzGAUgASgFQgf6QgQaAigBSAKIAQESLAoPZXN0aW1hdGVkX2hvdXJzGAYgASgBQg76QgsSCSkAAAAAAAAAAEgDiAEBEikKDGFjdHVhbF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIBIgBARIsCghkdWVfZGF0ZRgIIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFwoPYWlfbW9kZV9lbmFibGVkGAkgASgIEhoKDW1ldGFkYXRhX2pzb24YCiABKAlIBYgBARIQCghib2FyZF9pZBgLIAEoDRIXCg9ib2FyZF9jb2x1bW5faWQYDCABKA0SEgoKcHJvamVjdF9pZBgNIAEoDRIUCgx0YXNrX3R5cGVfaWQYDiABKA0SGAoQdGFza19wcmlvcml0eV9pZBgPIAEoDRIYChByZXBvcnRlcl91c2VyX2lkGBAgASgNEh0KEGFzc2lnbmVkX3VzZXJfaWQYESABKA1IBogBARIbCg5wYXJlbnRfdGFza19pZBgSIAEoDUgHiAEBEhYKDnJlcG9zaXRvcnlfaWRzGBMgAygNEhUKCGN5Y2xlX2lkGBQgASgNSAiIAQFCDQoLX2lkZW50aWZpZXJCDgoMX2Rlc2NyaXB0aW9uQg8KDV9zdG9yeV9wb2ludHNCEgoQX2VzdGltYXRlZF9ob3Vyc0IPCg1fYWN0dWFsX2hvdXJzQhAKDl9tZXRhZGF0YV9qc29uQhMKEV9hc3NpZ25lZF91c2VyX2lkQhEKD19wYXJlbnRfdGFza19pZEILCglfY3ljbGVfaWQi4gYKD0VkaXRUYXNrUmVxdWVzdBITCgJpZBgBIAEoDUIH+kIEKgIoARIdCgppZGVudGlmaWVyGAIgASgJQgn6QgZyBBABGDISGQoFdGl0bGUYAyABKAlCCvpCB3IFEAEYyAESGAoLZGVzY3JpcHRpb24YBCABKAlIAIgBARIeCg1kaXNwbGF5X29yZGVyGAUgASgFQgf6QgQaAigAEiIKDHN0b3J5X3BvaW50cxgGIAEoBUIH+kIEGgIoAUgBiAEBEiwKD2VzdGltYXRlZF9ob3VycxgHIAEoAUIO+kILEgkpAAAAAAAAAABIAogBARIpCgxhY3R1YWxfaG91cnMYCCABKAFCDvpCCxIJKQAAAAAAAAAASAOIAQESLAoIZHVlX2RhdGUYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEhcKD2FpX21vZGVfZW5hYmxlZBgKIAEoCBIaCg1tZXRhZGF0YV9qc29uGAsgASgJSASIAQESEAoIYm9hcmRfaWQYDCABKA0SFwoPYm9hcmRfY29sdW1uX2lkGA0gASgNEhIKCnByb2plY3RfaWQYDiABKA0SFAoMdGFza190eXBlX2lkGA8gASgNEhgKEHRhc2tfcHJpb3JpdHlfaWQYECABKA0SGAoQcmVwb3J0ZXJfdXNlcl9pZBgRIAEoDRIdChBhc3NpZ25lZF91c2VyX2lkGBIgASgNSAWIAQESGwoOcGFyZW50X3Rhc2tfaWQYEyABKA1IBogBARIWCg5yZXBvc2l0b3J5X2lkcxgUIAMoDRIVCghjeWNsZV9pZBgVIAEoDUgHiAEBEi8KC3Jlc29sdmVkX2F0GBYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcBIeChFvcmlnaW5hbF9lc3RpbWF0ZRgXIAEoAUgIiAEBQg4KDF9kZXNjcmlwdGlvbkIPCg1fc3RvcnlfcG9pbnRzQhIKEF9lc3RpbWF0ZWRfaG91cnNCDwoNX2FjdHVhbF9ob3Vyc0IQCg5fbWV0YWRhdGFfanNvbkITChFfYXNzaWduZWRfdXNlcl9pZEIRCg9fcGFyZW50X3Rhc2tfaWRCCwoJX2N5Y2xlX2lkQhQKEl9vcmlnaW5hbF9lc3RpbWF0ZSIcCg5HZXRUYXNrUmVxdWVzdBIKCgJpZBgBIAEoDSIuChRHZXRUYXNrQnlVVUlEUmVxdWVzdBIWCgR1dWlkGAEgASgJQgj6QgVyA7ABASKiAQoPR2V0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESMAoKcGFnaW5hdGlvbhgCIAEoCzISLmFwaS52MS5QYWdpbmF0aW9uQgj6QgWKAQIQARItCg5maWx0ZXJfb3B0aW9ucxgDIAEoCzIVLmFwaS52MS5GaWx0ZXJPcHRpb25zEhEKCWxhYmVsX2lkcxgEIAMoDSIfChFEZWxldGVUYXNrUmVxdWVzdBIKCgJpZBgBIAEoDSJXChBHZXRUYXNrc1Jlc3BvbnNlEhsKBXRhc2tzGAEgAygLMgwuYXBpLnYxLlRhc2sSJgoKcGFnaW5hdGlvbhgCIAEoCzISLmFwaS52MS5QYWdpbmF0aW9uIi0KD0FkZFRhc2tSZXNwb25zZRIaCgR0YXNrGAEgASgLMgwuYXBpLnYxLlRhc2siLgoQRWRpdFRhc2tSZXNwb25zZRIaCgR0YXNrGAEgASgLMgwuYXBpLnYxLlRhc2siLQoPR2V0VGFza1Jlc3BvbnNlEhoKBHRhc2sYASABKAsyDC5hcGkudjEuVGFzayI0ChhUcmlnZ2VyQUlXb3JrZmxvd1JlcXVlc3QSGAoHdGFza19pZBgBIAEoDUIH+kIEKgIoASJOChlUcmlnZ2VyQUlXb3JrZmxvd1Jlc3BvbnNlEhAKCGpvYl9uYW1lGAEgASgJEg4KBnN0YXR1cxgCIAEoCRIPCgdtZXNzYWdlGAMgASgJInIKEkV4cG9ydFRhc2tzUmVxdWVzdBIbCgpwcm9qZWN0X2lkGAEgASgNQgf6QgQqAigBEi0KDmZpbHRlcl9vcHRpb25zGAIgASgLMhUuYXBpLnYxLkZpbHRlck9wdGlvbnMSEAoIdGFza19pZHMYAyADKA0iPAoTRXhwb3J0VGFza3NSZXNwb25zZRITCgtjc3ZfY29udGVudBgBIAEoDBIQCghmaWxlbmFtZRgCIAEoCSJwChJJbXBvcnRUYXNrc1JlcXVlc3QSGwoKcHJvamVjdF9pZBgBIAEoDUIH+kIEKgIoARIhCgtjc3ZfY29udGVudBgCIAEoDEIM+kIJegcQARiAgIAFEhoKEnNraXBfbm90aWZpY2F0aW9ucxgDIAEoCCJFCgxJbXBvcnRlZFRhc2sSEwoLZXh0ZXJuYWxfaWQYASABKAkSDwoHdGFza19pZBgCIAEoDRIPCgdjcmVhdGVkGAMgASgIIq0BChNJbXBvcnRUYXNrc1Jlc3BvbnNlEhUKDWNyZWF0ZWRfY291bnQYASABKAUSFQoNdXBkYXRlZF9jb3VudBgCIAEoBRIUCgxmYWlsZWRfY291bnQYAyABKAUSDgoGZXJyb3JzGAQgAygJEhUKDXNraXBwZWRfY291bnQYBSABKAUSKwoNY3JlYXRlZF90YXNrcxgGIAMoCzIULmFwaS52MS5JbXBvcnRlZFRhc2sipwEKCFRhc2tMaW5rEh8KC2V4dGVybmFsX2lkGAEgASgJQgr6QgdyBRABGIABEikKEnBhcmVudF9leHRlcm5hbF9pZBgCIAEoCUII+kIFcgMYgAFIAIgBARIlCg5taWxlc3RvbmVfbmFtZRgDIAEoCUII+kIFcgMYgAJIAYgBAUIVChNfcGFyZW50X2V4dGVybmFsX2lkQhEKD19taWxlc3RvbmVfbmFtZSJnChxMaW5rVGFza3NCeUV4dGVybmFsSWRSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESKgoFbGlua3MYAiADKAsyEC5hcGkudjEuVGFza0xpbmtCCfpCBpIBAxCIJyJiCh1MaW5rVGFza3NCeUV4dGVybmFsSWRSZXNwb25zZRIWCg5saW5rZWRfcGFyZW50cxgBIAEoBRIZChFsaW5rZWRfbWlsZXN0b25lcxgCIAEoBRIOCgZlcnJvcnMYAyADKAki0QIKFEJ1bGtFZGl0VGFza3NSZXF1ZXN0EhsKCnByb2plY3RfaWQYASABKA1CB/pCBCoCKAESGgoIdGFza19pZHMYAiADKA1CCPpCBZIBAggBEhwKD2JvYXJkX2NvbHVtbl9pZBgDIAEoDUgAiAEBEh0KEHRhc2tfcHJpb3JpdHlfaWQYBCABKA1IAYgBARIZCgx0YXNrX3R5cGVfaWQYBSABKA1IAogBARIdChBhc3NpZ25lZF91c2VyX2lkGAYgASgNSAOIAQESFQoIY3ljbGVfaWQYByABKA1IBIgBARIWCg5yZXBvc2l0b3J5X2lkcxgIIAMoDUISChBfYm9hcmRfY29sdW1uX2lkQhMKEV90YXNrX3ByaW9yaXR5X2lkQg8KDV90YXNrX3R5cGVfaWRCEwoRX2Fzc2lnbmVkX3VzZXJfaWRCCwoJX2N5Y2xlX2lkIi4KFUJ1bGtFZGl0VGFza3NSZXNwb25zZRIVCg11cGRhdGVkX2NvdW50GAEgASgFIlEKFkJ1bGtEZWxldGVUYXNrc1JlcXVlc3QSGwoKcHJvamVjdF9pZBgBIAEoDUIH+kIEKgIoARIaCgh0YXNrX2lkcxgCIAMoDUII+kIFkgECCAEiMAoXQnVsa0RlbGV0ZVRhc2tzUmVzcG9uc2USFQoNZGVsZXRlZF9jb3VudBgBIAEoBSJ2ChFBZGRXb3JrTG9nUmVxdWVzdBIYCgd0YXNrX2lkGAEgASgNQgf6QgQqAigBEh0KBWhvdXJzGAIgASgBQg76QgsSCSmamZmZmZm5PxIYCgtkZXNjcmlwdGlvbhgDIAEoCUgAiAEBQg4KDF9kZXNjcmlwdGlvbiI3ChJBZGRXb3JrTG9nUmVzcG9uc2USIQoId29ya19sb2cYASABKAsyDy5hcGkudjEuV29ya0xvZyIzChREZWxldGVXb3JrTG9nUmVxdWVzdBIPCgd0YXNrX2lkGAEgASgNEgoKAmlkGAIgASgNMukMCgtUYXNrU2VydmljZRJ9CgtFeHBvcnRUYXNrcxIaLmFwaS52MS5FeHBvcnRUYXNrc1JlcXVlc3QaGy5hcGkudjEuRXhwb3J0VGFza3NSZXNwb25zZSI1gtPkkwIvOgEqIiovYXBpL3YxL3Byb2plY3RzL3twcm9qZWN0X2lkfS90YXNrcy9leHBvcnQSfQoLSW1wb3J0VGFza3MSGi5hcGkudjEuSW1wb3J0VGFza3NSZXF1ZXN0GhsuYXBpLnYxLkltcG9ydFRhc2tzUmVzcG9uc2UiNYLT5JMCLzoBKiIqL2FwaS92MS9wcm9qZWN0cy97cHJvamVjdF9pZH0vdGFza3MvaW1wb3J0EqgBChVMaW5rVGFza3NCeUV4dGVybmFsSWQSJC5hcGkudjEuTGlua1Rhc2tzQnlFeHRlcm5hbElkUmVxdWVzdBolLmFwaS52MS5MaW5rVGFza3NCeUV4dGVybmFsSWRSZXNwb25zZSJCgtPkkwI8OgEqIjcvYXBpL3YxL3Byb2plY3RzL3twcm9qZWN0X2lkfS90YXNrcy9saW5rLWJ5LWV4dGVybmFsLWlkElQKB0FkZFRhc2sSFi5hcGkudjEuQWRkVGFza1JlcXVlc3QaFy5hcGkudjEuQWRkVGFza1Jlc3BvbnNlIhiC0+STAhI6ASoiDS9hcGkvdjEvdGFza3MSXAoIRWRpdFRhc2sSFy5hcGkudjEuRWRpdFRhc2tSZXF1ZXN0GhguYXBpLnYxLkVkaXRUYXNrUmVzcG9uc2UiHYLT5JMCFzoBKhoSL2FwaS92MS90YXNrcy97aWR9ElYKB0dldFRhc2sSFi5hcGkudjEuR2V0VGFza1JlcXVlc3QaFy5hcGkudjEuR2V0VGFza1Jlc3BvbnNlIhqC0+STAhQSEi9hcGkvdjEvdGFza3Mve2lkfRJpCg1HZXRUYXNrQnlVVUlEEhwuYXBpLnYxLkdldFRhc2tCeVVVSURSZXF1ZXN0GhcuYXBpLnYxLkdldFRhc2tSZXNwb25zZSIhgtPkkwIbEhkvYXBpL3YxL3Rhc2tzL3V1aWQve3V1aWR9ElQKCEdldFRhc2tzEhcuYXBpLnYxLkdldFRhc2tzUmVxdWVzdBoYLmFwaS52MS5HZXRUYXNrc1Jlc3BvbnNlIhWC0+STAg8SDS9hcGkvdjEvdGFza3MSWwoKRGVsZXRlVGFzaxIZLmFwaS52MS5EZWxldGVUYXNrUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIagtPkkwIUKhIvYXBpL3YxL3Rhc2tzL3tpZH0ShwEKEVRyaWdnZXJBSVdvcmtmbG93EiAuYXBpLnYxLlRyaWdnZXJBSVdvcmtmbG93UmVxdWVzdBohLmFwaS52MS5UcmlnZ2VyQUlXb3JrZmxvd1Jlc3BvbnNlIi2C0+STAic6ASoiIi9hcGkvdjEvdGFza3Mve3Rhc2tfaWR9L3RyaWdnZXItYWkScQoKQWRkV29ya0xvZxIZLmFwaS52MS5BZGRXb3JrTG9nUmVxdWVzdBoaLmFwaS52MS5BZGRXb3JrTG9nUmVzcG9uc2UiLILT5JMCJjoBKiIhL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzEnUKDURlbGV0ZVdvcmtMb2cSHC5hcGkudjEuRGVsZXRlV29ya0xvZ1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiLoLT5JMCKComL2FwaS92MS90YXNrcy97dGFza19pZH0vd29yay1sb2dzL3tpZH0SgQEKDUJ1bGtFZGl0VGFza3MSHC5hcGkudjEuQnVsa0VkaXRUYXNrc1JlcXVlc3QaHS5hcGkudjEuQnVsa0VkaXRUYXNrc1Jlc3BvbnNlIjOC0+STAi06ASoaKC9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGsSjgEKD0J1bGtEZWxldGVUYXNrcxIeLmFwaS52MS5CdWxrRGVsZXRlVGFza3NSZXF1ZXN0Gh8uYXBpLnYxLkJ1bGtEZWxldGVUYXNrc1Jlc3BvbnNlIjqC0+STAjQ6ASoiLy9hcGkvdjEvcHJvamVjdHMve3Byb2plY3RfaWR9L3Rhc2tzL2J1bGstZGVsZXRlQm4KCmNvbS5hcGkudjFCCVRhc2tQcm90b1ABWhxvcHNlZS9iYWNrZW5kL2dlbi9hcGkvdjE7Z2VuogIDQVhYqgIGQXBpLlYxygIGQXBpXFYx4gISQXBpXFYxXEdQQk1ldGFkYXRh6gIHQXBpOjpWMWIGcHJvdG8z", [file_google_protobuf_empty, file_google_protobuf_timestamp, file_google_api_annotations, file_validate_validate, file_api_v1_pagination, file_api_v1_filter, file_api_v1_models]);
18
18
 
19
19
  /**
20
20
  * Describes the message api.v1.AddTaskRequest.
@@ -121,61 +121,89 @@ export const ExportTasksResponseSchema = /*@__PURE__*/
121
121
  export const ImportTasksRequestSchema = /*@__PURE__*/
122
122
  messageDesc(file_api_v1_task, 14);
123
123
 
124
+ /**
125
+ * Describes the message api.v1.ImportedTask.
126
+ * Use `create(ImportedTaskSchema)` to create a new message.
127
+ */
128
+ export const ImportedTaskSchema = /*@__PURE__*/
129
+ messageDesc(file_api_v1_task, 15);
130
+
124
131
  /**
125
132
  * Describes the message api.v1.ImportTasksResponse.
126
133
  * Use `create(ImportTasksResponseSchema)` to create a new message.
127
134
  */
128
135
  export const ImportTasksResponseSchema = /*@__PURE__*/
129
- messageDesc(file_api_v1_task, 15);
136
+ messageDesc(file_api_v1_task, 16);
137
+
138
+ /**
139
+ * Describes the message api.v1.TaskLink.
140
+ * Use `create(TaskLinkSchema)` to create a new message.
141
+ */
142
+ export const TaskLinkSchema = /*@__PURE__*/
143
+ messageDesc(file_api_v1_task, 17);
144
+
145
+ /**
146
+ * Describes the message api.v1.LinkTasksByExternalIdRequest.
147
+ * Use `create(LinkTasksByExternalIdRequestSchema)` to create a new message.
148
+ */
149
+ export const LinkTasksByExternalIdRequestSchema = /*@__PURE__*/
150
+ messageDesc(file_api_v1_task, 18);
151
+
152
+ /**
153
+ * Describes the message api.v1.LinkTasksByExternalIdResponse.
154
+ * Use `create(LinkTasksByExternalIdResponseSchema)` to create a new message.
155
+ */
156
+ export const LinkTasksByExternalIdResponseSchema = /*@__PURE__*/
157
+ messageDesc(file_api_v1_task, 19);
130
158
 
131
159
  /**
132
160
  * Describes the message api.v1.BulkEditTasksRequest.
133
161
  * Use `create(BulkEditTasksRequestSchema)` to create a new message.
134
162
  */
135
163
  export const BulkEditTasksRequestSchema = /*@__PURE__*/
136
- messageDesc(file_api_v1_task, 16);
164
+ messageDesc(file_api_v1_task, 20);
137
165
 
138
166
  /**
139
167
  * Describes the message api.v1.BulkEditTasksResponse.
140
168
  * Use `create(BulkEditTasksResponseSchema)` to create a new message.
141
169
  */
142
170
  export const BulkEditTasksResponseSchema = /*@__PURE__*/
143
- messageDesc(file_api_v1_task, 17);
171
+ messageDesc(file_api_v1_task, 21);
144
172
 
145
173
  /**
146
174
  * Describes the message api.v1.BulkDeleteTasksRequest.
147
175
  * Use `create(BulkDeleteTasksRequestSchema)` to create a new message.
148
176
  */
149
177
  export const BulkDeleteTasksRequestSchema = /*@__PURE__*/
150
- messageDesc(file_api_v1_task, 18);
178
+ messageDesc(file_api_v1_task, 22);
151
179
 
152
180
  /**
153
181
  * Describes the message api.v1.BulkDeleteTasksResponse.
154
182
  * Use `create(BulkDeleteTasksResponseSchema)` to create a new message.
155
183
  */
156
184
  export const BulkDeleteTasksResponseSchema = /*@__PURE__*/
157
- messageDesc(file_api_v1_task, 19);
185
+ messageDesc(file_api_v1_task, 23);
158
186
 
159
187
  /**
160
188
  * Describes the message api.v1.AddWorkLogRequest.
161
189
  * Use `create(AddWorkLogRequestSchema)` to create a new message.
162
190
  */
163
191
  export const AddWorkLogRequestSchema = /*@__PURE__*/
164
- messageDesc(file_api_v1_task, 20);
192
+ messageDesc(file_api_v1_task, 24);
165
193
 
166
194
  /**
167
195
  * Describes the message api.v1.AddWorkLogResponse.
168
196
  * Use `create(AddWorkLogResponseSchema)` to create a new message.
169
197
  */
170
198
  export const AddWorkLogResponseSchema = /*@__PURE__*/
171
- messageDesc(file_api_v1_task, 21);
199
+ messageDesc(file_api_v1_task, 25);
172
200
 
173
201
  /**
174
202
  * Describes the message api.v1.DeleteWorkLogRequest.
175
203
  * Use `create(DeleteWorkLogRequestSchema)` to create a new message.
176
204
  */
177
205
  export const DeleteWorkLogRequestSchema = /*@__PURE__*/
178
- messageDesc(file_api_v1_task, 22);
206
+ messageDesc(file_api_v1_task, 26);
179
207
 
180
208
  /**
181
209
  * Service definition
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opsee/mcp-server",
3
- "version": "0.5.6",
3
+ "version": "0.6.1",
4
4
  "description": "Opsee MCP server — manage projects, tasks, docs, and cycles from AI coding environments",
5
5
  "type": "module",
6
6
  "bin": {
package/src/client/api.ts CHANGED
@@ -22,6 +22,10 @@ import { UserService } from "../../gen/api/v1/user_pb.js";
22
22
  import { VCSIntegrationService } from "../../gen/api/v1/vcs_integration_pb.js";
23
23
  import { MilestoneService } from "../../gen/api/v1/milestone_pb.js";
24
24
  import { MilestoneTaskService } from "../../gen/api/v1/milestone_task_pb.js";
25
+ import { LabelService } from "../../gen/api/v1/label_pb.js";
26
+ import { TaskLabelService } from "../../gen/api/v1/task_label_pb.js";
27
+ import { CommentService } from "../../gen/api/v1/comment_pb.js";
28
+ import { TaskDependencyService } from "../../gen/api/v1/task_dependency_pb.js";
25
29
 
26
30
  const authInterceptor: Interceptor = (next) => async (req) => {
27
31
  // Remote mode: token from AsyncLocalStorage (per-request)
@@ -97,6 +101,10 @@ export type ApiClients = {
97
101
  vcsIntegrations: Client<typeof VCSIntegrationService>;
98
102
  milestones: Client<typeof MilestoneService>;
99
103
  milestoneTasks: Client<typeof MilestoneTaskService>;
104
+ labels: Client<typeof LabelService>;
105
+ taskLabels: Client<typeof TaskLabelService>;
106
+ comments: Client<typeof CommentService>;
107
+ taskDependencies: Client<typeof TaskDependencyService>;
100
108
  };
101
109
 
102
110
  export function getClients(): ApiClients {
@@ -115,6 +123,10 @@ export function getClients(): ApiClients {
115
123
  vcsIntegrations: makeClient(VCSIntegrationService),
116
124
  milestones: makeClient(MilestoneService),
117
125
  milestoneTasks: makeClient(MilestoneTaskService),
126
+ labels: makeClient(LabelService),
127
+ taskLabels: makeClient(TaskLabelService),
128
+ comments: makeClient(CommentService),
129
+ taskDependencies: makeClient(TaskDependencyService),
118
130
  };
119
131
  }
120
132
  return cachedClients;
package/src/server.ts CHANGED
@@ -8,6 +8,9 @@ import { registerCycleTools } from "./tools/cycles.js";
8
8
  import { registerDocTools } from "./tools/docs.js";
9
9
  import { registerRepositoryTools } from "./tools/repositories.js";
10
10
  import { registerMilestoneTools } from "./tools/milestones.js";
11
+ import { registerLabelTools } from "./tools/labels.js";
12
+ import { registerCommentTools } from "./tools/comments.js";
13
+ import { registerTaskDependencyTools } from "./tools/task-dependencies.js";
11
14
 
12
15
  export function createServer(clientFactory?: () => ApiClients): McpServer {
13
16
  const factory = clientFactory ?? getClients;
@@ -25,6 +28,9 @@ export function createServer(clientFactory?: () => ApiClients): McpServer {
25
28
  registerDocTools(server, factory);
26
29
  registerRepositoryTools(server, factory);
27
30
  registerMilestoneTools(server, factory);
31
+ registerLabelTools(server, factory);
32
+ registerCommentTools(server, factory);
33
+ registerTaskDependencyTools(server, factory);
28
34
 
29
35
  return server;
30
36
  }
@@ -0,0 +1,96 @@
1
+ import { z } from "zod";
2
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import type { ApiClients } from "../client/api.js";
4
+ import { defaultPagination } from "../client/api.js";
5
+ import { authManager } from "../auth/manager.js";
6
+ import {
7
+ formatComment,
8
+ formatCommentList,
9
+ formatError,
10
+ } from "../utils/format.js";
11
+
12
+ export function registerCommentTools(
13
+ server: McpServer,
14
+ getClients: () => ApiClients,
15
+ ): void {
16
+ server.tool(
17
+ "opsee_list_comments",
18
+ "List comments on a task, oldest first. Includes both regular and internal comments visible to the caller.",
19
+ {
20
+ taskId: z.number().describe("The task ID"),
21
+ page: z.number().optional().describe("Page number (default: 1)"),
22
+ pageSize: z.number().optional().describe("Items per page (default: 50)"),
23
+ },
24
+ { readOnlyHint: true, destructiveHint: false },
25
+ async ({ taskId, page, pageSize }) => {
26
+ try {
27
+ const clients = getClients();
28
+ const res = await clients.comments.getComments({
29
+ taskId,
30
+ pagination: defaultPagination(page || 1, pageSize || 50),
31
+ });
32
+ return { content: [{ type: "text", text: formatCommentList(res.comments) }] };
33
+ } catch (error) {
34
+ return { content: [{ type: "text", text: formatError(error) }], isError: true };
35
+ }
36
+ },
37
+ );
38
+
39
+ server.tool(
40
+ "opsee_add_comment",
41
+ "Add a comment to a task. Posts as the authenticated user. Set isInternal=true to mark the comment as internal (visibility depends on backend RBAC).",
42
+ {
43
+ taskId: z.number().describe("The task ID to comment on"),
44
+ content: z.string().min(1).describe("Comment body"),
45
+ isInternal: z.boolean().optional().describe("Mark as internal comment (default: false)"),
46
+ },
47
+ { readOnlyHint: false, destructiveHint: false },
48
+ async ({ taskId, content, isInternal }) => {
49
+ try {
50
+ const clients = getClients();
51
+
52
+ let userId = 0;
53
+ const cachedId = authManager.getUserId();
54
+ if (cachedId) userId = Number(cachedId);
55
+ if (!userId) {
56
+ const meRes = await clients.users.getMe({});
57
+ if (meRes.user) userId = meRes.user.id;
58
+ }
59
+ if (!userId) {
60
+ return { content: [{ type: "text", text: "Could not resolve current user. Authentication may be incomplete." }], isError: true };
61
+ }
62
+
63
+ const res = await clients.comments.addComment({
64
+ content,
65
+ isInternal: isInternal ?? false,
66
+ taskId,
67
+ userId,
68
+ });
69
+
70
+ if (!res.comment) {
71
+ return { content: [{ type: "text", text: "Failed to add comment." }] };
72
+ }
73
+
74
+ return { content: [{ type: "text", text: `Comment added:\n${formatComment(res.comment)}` }] };
75
+ } catch (error) {
76
+ return { content: [{ type: "text", text: formatError(error) }], isError: true };
77
+ }
78
+ },
79
+ );
80
+
81
+ server.tool(
82
+ "opsee_delete_comment",
83
+ "Delete a comment by ID. This is permanent.",
84
+ { commentId: z.number().describe("The comment ID") },
85
+ { readOnlyHint: false, destructiveHint: true },
86
+ async ({ commentId }) => {
87
+ try {
88
+ const clients = getClients();
89
+ await clients.comments.deleteComment({ id: commentId });
90
+ return { content: [{ type: "text", text: "Comment deleted." }] };
91
+ } catch (error) {
92
+ return { content: [{ type: "text", text: formatError(error) }], isError: true };
93
+ }
94
+ },
95
+ );
96
+ }