runline 0.12.0 → 0.14.0

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,23 @@
1
+ import * as t from "typebox";
2
+ /** Common TypeBox primitives for Google plugin action inputs. */
3
+ export const NonEmptyString = t.String({ minLength: 1, pattern: "\\S" });
4
+ export const Id = t.String({ minLength: 1 });
5
+ export const PositiveInteger = t.Integer({ minimum: 1 });
6
+ export const NonNegativeInteger = t.Integer({ minimum: 0 });
7
+ export const StringArray = t.Array(t.String());
8
+ export const NonEmptyStringArray = t.Array(NonEmptyString, { minItems: 1 });
9
+ export const StringOrNumber = t.Union([t.String(), t.Number()]);
10
+ export const StringOrStringArray = t.Union([t.String(), t.Array(t.String())]);
11
+ /** JSON-compatible data whose provider-specific shape is intentionally open. */
12
+ export const RawGoogleObject = t.Object({}, { additionalProperties: true });
13
+ export const JsonValue = t.Unknown({
14
+ description: "Any JSON-compatible value",
15
+ });
16
+ export const JsonArray = t.Array(JsonValue);
17
+ export const StringMap = t.Record(t.String(), t.String());
18
+ export const GoogleTimestamp = t.Union([NonEmptyString, t.Number()], {
19
+ description: "ISO datetime, epoch milliseconds, or epoch seconds",
20
+ });
21
+ export function stringEnum(values) {
22
+ return t.Union(values.map((value) => t.Literal(value)));
23
+ }
@@ -20,7 +20,9 @@
20
20
  * raw Gmail API response (including base64url `raw` for format=raw,
21
21
  * or parsed `payload` tree for format=full).
22
22
  */
23
+ import * as t from "typebox";
23
24
  import { googleAccessToken } from "../../_shared/googleAuth.js";
25
+ import { GoogleTimestamp, Id, NonEmptyString, stringEnum, } from "../../_shared/googleSchemas.js";
24
26
  // ─── Auth ────────────────────────────────────────────────────────
25
27
  async function accessToken(ctx) {
26
28
  return googleAccessToken(ctx, "gmail", SCOPES);
@@ -503,6 +505,82 @@ const SCOPES = [
503
505
  "https://www.googleapis.com/auth/gmail.compose",
504
506
  "https://www.googleapis.com/auth/gmail.labels",
505
507
  ];
508
+ // ─── Action input schemas ────────────────────────────────────────
509
+ const strict = { additionalProperties: false };
510
+ const EmptyInput = t.Object({}, strict);
511
+ const IdInput = t.Object({ id: Id }, strict);
512
+ const MessageFormat = stringEnum(["minimal", "full", "raw", "metadata"]);
513
+ const ThreadFormat = stringEnum(["minimal", "full", "metadata"]);
514
+ const ReadStatus = stringEnum(["read", "unread", "both"]);
515
+ const LabelListVisibility = stringEnum([
516
+ "labelShow",
517
+ "labelShowIfUnread",
518
+ "labelHide",
519
+ ]);
520
+ const MessageListVisibility = stringEnum(["show", "hide"]);
521
+ const MetadataHeaders = t.Array(t.String());
522
+ const LabelIds = t.Array(NonEmptyString, { minItems: 1 });
523
+ const MaxResults = t.Integer({ minimum: 1, maximum: 500 });
524
+ const AttachmentContent = t.Union([
525
+ t.String(),
526
+ t.Object({ contentBase64: t.String() }, strict),
527
+ ]);
528
+ const Attachment = t.Object({
529
+ name: t.Optional(t.String()),
530
+ filename: t.Optional(t.String()),
531
+ mimeType: t.Optional(t.String()),
532
+ contentBase64: AttachmentContent,
533
+ }, strict);
534
+ const Attachments = t.Array(Attachment);
535
+ const HasMessageContent = {
536
+ anyOf: [
537
+ {
538
+ required: ["text"],
539
+ properties: { text: { type: "string", minLength: 1, pattern: "\\S" } },
540
+ },
541
+ {
542
+ required: ["html"],
543
+ properties: { html: { type: "string", minLength: 1, pattern: "\\S" } },
544
+ },
545
+ {
546
+ required: ["attachments"],
547
+ properties: { attachments: { type: "array", minItems: 1 } },
548
+ },
549
+ ],
550
+ };
551
+ const ReplyFields = {
552
+ text: t.Optional(t.String()),
553
+ html: t.Optional(t.String()),
554
+ cc: t.Optional(t.String()),
555
+ bcc: t.Optional(t.String()),
556
+ replyToSenderOnly: t.Optional(t.Boolean()),
557
+ replyToRecipientsOnly: t.Optional(t.Boolean()),
558
+ attachments: t.Optional(Attachments),
559
+ };
560
+ const ReplyOptions = {
561
+ ...strict,
562
+ ...HasMessageContent,
563
+ not: {
564
+ required: ["replyToSenderOnly", "replyToRecipientsOnly"],
565
+ properties: {
566
+ replyToSenderOnly: { const: true },
567
+ replyToRecipientsOnly: { const: true },
568
+ },
569
+ },
570
+ };
571
+ const ListFields = {
572
+ q: t.Optional(t.String({ description: "Gmail search query" })),
573
+ sender: t.Optional(t.String()),
574
+ readStatus: t.Optional(ReadStatus),
575
+ receivedAfter: t.Optional(GoogleTimestamp),
576
+ receivedBefore: t.Optional(GoogleTimestamp),
577
+ labelIds: t.Optional(t.Array(NonEmptyString)),
578
+ maxResults: t.Optional(MaxResults),
579
+ pageToken: t.Optional(t.String()),
580
+ includeSpamTrash: t.Optional(t.Boolean()),
581
+ returnAll: t.Optional(t.Boolean()),
582
+ };
583
+ const ListInput = t.Object(ListFields, strict);
506
584
  export default function gmail(rl) {
507
585
  rl.setName("gmail");
508
586
  rl.setVersion("0.1.0");
@@ -618,30 +696,18 @@ export default function gmail(rl) {
618
696
  rl.registerAction("message.send", {
619
697
  access: "write",
620
698
  description: "Send an email",
621
- inputSchema: {
622
- to: {
623
- type: "string",
624
- required: true,
625
- description: "Comma-separated recipient list",
626
- },
627
- subject: { type: "string", required: true },
628
- text: { type: "string", required: false, description: "Plain body" },
629
- html: { type: "string", required: false, description: "HTML body" },
630
- cc: { type: "string", required: false },
631
- bcc: { type: "string", required: false },
632
- replyTo: { type: "string", required: false },
633
- from: {
634
- type: "string",
635
- required: false,
636
- description: 'Override From (e.g. "Name <me@x.com>")',
637
- },
638
- threadId: { type: "string", required: false },
639
- attachments: {
640
- type: "array",
641
- required: false,
642
- description: "[{name, mimeType, contentBase64}]",
643
- },
644
- },
699
+ inputSchema: t.Object({
700
+ to: NonEmptyString,
701
+ subject: t.String(),
702
+ text: t.Optional(t.String({ description: "Plain body" })),
703
+ html: t.Optional(t.String({ description: "HTML body" })),
704
+ cc: t.Optional(t.String()),
705
+ bcc: t.Optional(t.String()),
706
+ replyTo: t.Optional(t.String()),
707
+ from: t.Optional(t.String({ description: 'Override From (e.g. "Name <me@x.com>")' })),
708
+ threadId: t.Optional(Id),
709
+ attachments: t.Optional(Attachments),
710
+ }, { ...strict, ...HasMessageContent }),
645
711
  async execute(input, ctx) {
646
712
  const p = (input ?? {});
647
713
  const email = {
@@ -664,16 +730,7 @@ export default function gmail(rl) {
664
730
  rl.registerAction("message.reply", {
665
731
  access: "write",
666
732
  description: "Reply to a message, preserving threadId and In-Reply-To/References headers",
667
- inputSchema: {
668
- messageId: { type: "string", required: true },
669
- text: { type: "string", required: false },
670
- html: { type: "string", required: false },
671
- cc: { type: "string", required: false },
672
- bcc: { type: "string", required: false },
673
- replyToSenderOnly: { type: "boolean", required: false },
674
- replyToRecipientsOnly: { type: "boolean", required: false },
675
- attachments: { type: "array", required: false },
676
- },
733
+ inputSchema: t.Object({ messageId: Id, ...ReplyFields }, ReplyOptions),
677
734
  async execute(input, ctx) {
678
735
  const p = (input ?? {});
679
736
  return replyToMessage(ctx, p.messageId, p);
@@ -682,20 +739,14 @@ export default function gmail(rl) {
682
739
  rl.registerAction("message.get", {
683
740
  access: "read",
684
741
  description: "Get a message by ID",
685
- inputSchema: {
686
- id: { type: "string", required: true },
687
- format: {
688
- type: "string",
689
- required: false,
690
- description: "minimal | full | raw | metadata (default: full)",
691
- },
692
- metadataHeaders: { type: "array", required: false },
693
- simple: {
694
- type: "boolean",
695
- required: false,
742
+ inputSchema: t.Object({
743
+ id: Id,
744
+ format: t.Optional(MessageFormat),
745
+ metadataHeaders: t.Optional(MetadataHeaders),
746
+ simple: t.Optional(t.Boolean({
696
747
  description: "Flatten headers, resolve labels to names, and decode text/html bodies",
697
- },
698
- },
748
+ })),
749
+ }, strict),
699
750
  async execute(input, ctx) {
700
751
  const p = (input ?? {});
701
752
  const qs = { format: p.format ?? "full" };
@@ -711,30 +762,7 @@ export default function gmail(rl) {
711
762
  rl.registerAction("message.list", {
712
763
  access: "read",
713
764
  description: "List messages. Supports Gmail search syntax via `q`, plus friendly filters: sender, readStatus ('read'|'unread'), receivedAfter/Before (ISO string, ms, or seconds).",
714
- inputSchema: {
715
- q: { type: "string", required: false, description: "Gmail search query" },
716
- sender: { type: "string", required: false },
717
- readStatus: {
718
- type: "string",
719
- required: false,
720
- description: "read | unread | both (default: both)",
721
- },
722
- receivedAfter: {
723
- type: "string",
724
- required: false,
725
- description: "ISO datetime, epoch ms, or epoch seconds",
726
- },
727
- receivedBefore: { type: "string", required: false },
728
- labelIds: { type: "array", required: false },
729
- maxResults: { type: "number", required: false },
730
- pageToken: { type: "string", required: false },
731
- includeSpamTrash: { type: "boolean", required: false },
732
- returnAll: {
733
- type: "boolean",
734
- required: false,
735
- description: "Paginate until exhausted",
736
- },
737
- },
765
+ inputSchema: ListInput,
738
766
  async execute(input, ctx) {
739
767
  const p = (input ?? {});
740
768
  const qs = buildListQuery(p);
@@ -749,7 +777,7 @@ export default function gmail(rl) {
749
777
  rl.registerAction("message.delete", {
750
778
  access: "write",
751
779
  description: "Permanently delete a message",
752
- inputSchema: { id: { type: "string", required: true } },
780
+ inputSchema: IdInput,
753
781
  async execute(input, ctx) {
754
782
  const { id } = input;
755
783
  return gmailRequest(ctx, "DELETE", `/messages/${id}`);
@@ -758,7 +786,7 @@ export default function gmail(rl) {
758
786
  rl.registerAction("message.trash", {
759
787
  access: "write",
760
788
  description: "Move a message to trash (recoverable)",
761
- inputSchema: { id: { type: "string", required: true } },
789
+ inputSchema: IdInput,
762
790
  async execute(input, ctx) {
763
791
  const { id } = input;
764
792
  return gmailRequest(ctx, "POST", `/messages/${id}/trash`);
@@ -767,7 +795,7 @@ export default function gmail(rl) {
767
795
  rl.registerAction("message.untrash", {
768
796
  access: "write",
769
797
  description: "Remove a message from trash",
770
- inputSchema: { id: { type: "string", required: true } },
798
+ inputSchema: IdInput,
771
799
  async execute(input, ctx) {
772
800
  const { id } = input;
773
801
  return gmailRequest(ctx, "POST", `/messages/${id}/untrash`);
@@ -776,7 +804,7 @@ export default function gmail(rl) {
776
804
  rl.registerAction("message.markAsRead", {
777
805
  access: "write",
778
806
  description: "Remove the UNREAD label",
779
- inputSchema: { id: { type: "string", required: true } },
807
+ inputSchema: IdInput,
780
808
  async execute(input, ctx) {
781
809
  const { id } = input;
782
810
  return gmailRequest(ctx, "POST", `/messages/${id}/modify`, {
@@ -787,7 +815,7 @@ export default function gmail(rl) {
787
815
  rl.registerAction("message.markAsUnread", {
788
816
  access: "write",
789
817
  description: "Add the UNREAD label",
790
- inputSchema: { id: { type: "string", required: true } },
818
+ inputSchema: IdInput,
791
819
  async execute(input, ctx) {
792
820
  const { id } = input;
793
821
  return gmailRequest(ctx, "POST", `/messages/${id}/modify`, {
@@ -798,10 +826,7 @@ export default function gmail(rl) {
798
826
  rl.registerAction("message.addLabels", {
799
827
  access: "write",
800
828
  description: "Add labels to a message",
801
- inputSchema: {
802
- id: { type: "string", required: true },
803
- labelIds: { type: "array", required: true },
804
- },
829
+ inputSchema: t.Object({ id: Id, labelIds: LabelIds }, strict),
805
830
  async execute(input, ctx) {
806
831
  const { id, labelIds } = input;
807
832
  return gmailRequest(ctx, "POST", `/messages/${id}/modify`, {
@@ -812,10 +837,7 @@ export default function gmail(rl) {
812
837
  rl.registerAction("message.removeLabels", {
813
838
  access: "write",
814
839
  description: "Remove labels from a message",
815
- inputSchema: {
816
- id: { type: "string", required: true },
817
- labelIds: { type: "array", required: true },
818
- },
840
+ inputSchema: t.Object({ id: Id, labelIds: LabelIds }, strict),
819
841
  async execute(input, ctx) {
820
842
  const { id, labelIds } = input;
821
843
  return gmailRequest(ctx, "POST", `/messages/${id}/modify`, {
@@ -826,10 +848,7 @@ export default function gmail(rl) {
826
848
  rl.registerAction("message.getAttachment", {
827
849
  access: "read",
828
850
  description: "Download an attachment by ID (returns {size, data} where data is base64url)",
829
- inputSchema: {
830
- messageId: { type: "string", required: true },
831
- attachmentId: { type: "string", required: true },
832
- },
851
+ inputSchema: t.Object({ messageId: Id, attachmentId: Id }, strict),
833
852
  async execute(input, ctx) {
834
853
  const { messageId, attachmentId } = input;
835
854
  return gmailRequest(ctx, "GET", `/messages/${messageId}/attachments/${attachmentId}`);
@@ -839,20 +858,14 @@ export default function gmail(rl) {
839
858
  rl.registerAction("thread.get", {
840
859
  access: "read",
841
860
  description: "Get a thread by ID",
842
- inputSchema: {
843
- id: { type: "string", required: true },
844
- format: {
845
- type: "string",
846
- required: false,
847
- description: "minimal | full | metadata",
848
- },
849
- metadataHeaders: { type: "array", required: false },
850
- simple: {
851
- type: "boolean",
852
- required: false,
861
+ inputSchema: t.Object({
862
+ id: Id,
863
+ format: t.Optional(ThreadFormat),
864
+ metadataHeaders: t.Optional(MetadataHeaders),
865
+ simple: t.Optional(t.Boolean({
853
866
  description: "Return an array of simplified messages instead of the raw thread",
854
- },
855
- },
867
+ })),
868
+ }, strict),
856
869
  async execute(input, ctx) {
857
870
  const p = (input ?? {});
858
871
  const qs = { format: p.format ?? "full" };
@@ -868,18 +881,7 @@ export default function gmail(rl) {
868
881
  rl.registerAction("thread.list", {
869
882
  access: "read",
870
883
  description: "List threads. Same filter sugar as `message.list` (sender, readStatus, receivedAfter/Before).",
871
- inputSchema: {
872
- q: { type: "string", required: false },
873
- sender: { type: "string", required: false },
874
- readStatus: { type: "string", required: false },
875
- receivedAfter: { type: "string", required: false },
876
- receivedBefore: { type: "string", required: false },
877
- labelIds: { type: "array", required: false },
878
- maxResults: { type: "number", required: false },
879
- pageToken: { type: "string", required: false },
880
- includeSpamTrash: { type: "boolean", required: false },
881
- returnAll: { type: "boolean", required: false },
882
- },
884
+ inputSchema: ListInput,
883
885
  async execute(input, ctx) {
884
886
  const p = (input ?? {});
885
887
  const qs = buildListQuery(p);
@@ -893,7 +895,7 @@ export default function gmail(rl) {
893
895
  rl.registerAction("thread.delete", {
894
896
  access: "write",
895
897
  description: "Permanently delete a thread",
896
- inputSchema: { id: { type: "string", required: true } },
898
+ inputSchema: IdInput,
897
899
  async execute(input, ctx) {
898
900
  const { id } = input;
899
901
  return gmailRequest(ctx, "DELETE", `/threads/${id}`);
@@ -902,7 +904,7 @@ export default function gmail(rl) {
902
904
  rl.registerAction("thread.trash", {
903
905
  access: "write",
904
906
  description: "Move a thread to trash",
905
- inputSchema: { id: { type: "string", required: true } },
907
+ inputSchema: IdInput,
906
908
  async execute(input, ctx) {
907
909
  const { id } = input;
908
910
  return gmailRequest(ctx, "POST", `/threads/${id}/trash`);
@@ -911,7 +913,7 @@ export default function gmail(rl) {
911
913
  rl.registerAction("thread.untrash", {
912
914
  access: "write",
913
915
  description: "Remove a thread from trash",
914
- inputSchema: { id: { type: "string", required: true } },
916
+ inputSchema: IdInput,
915
917
  async execute(input, ctx) {
916
918
  const { id } = input;
917
919
  return gmailRequest(ctx, "POST", `/threads/${id}/untrash`);
@@ -920,10 +922,7 @@ export default function gmail(rl) {
920
922
  rl.registerAction("thread.addLabels", {
921
923
  access: "write",
922
924
  description: "Add labels to all messages in a thread",
923
- inputSchema: {
924
- id: { type: "string", required: true },
925
- labelIds: { type: "array", required: true },
926
- },
925
+ inputSchema: t.Object({ id: Id, labelIds: LabelIds }, strict),
927
926
  async execute(input, ctx) {
928
927
  const { id, labelIds } = input;
929
928
  return gmailRequest(ctx, "POST", `/threads/${id}/modify`, {
@@ -934,10 +933,7 @@ export default function gmail(rl) {
934
933
  rl.registerAction("thread.removeLabels", {
935
934
  access: "write",
936
935
  description: "Remove labels from all messages in a thread",
937
- inputSchema: {
938
- id: { type: "string", required: true },
939
- labelIds: { type: "array", required: true },
940
- },
936
+ inputSchema: t.Object({ id: Id, labelIds: LabelIds }, strict),
941
937
  async execute(input, ctx) {
942
938
  const { id, labelIds } = input;
943
939
  return gmailRequest(ctx, "POST", `/threads/${id}/modify`, {
@@ -948,16 +944,7 @@ export default function gmail(rl) {
948
944
  rl.registerAction("thread.reply", {
949
945
  access: "write",
950
946
  description: "Reply to the last message in a thread (convenience wrapper over message.reply)",
951
- inputSchema: {
952
- id: { type: "string", required: true, description: "Thread ID" },
953
- text: { type: "string", required: false },
954
- html: { type: "string", required: false },
955
- cc: { type: "string", required: false },
956
- bcc: { type: "string", required: false },
957
- replyToSenderOnly: { type: "boolean", required: false },
958
- replyToRecipientsOnly: { type: "boolean", required: false },
959
- attachments: { type: "array", required: false },
960
- },
947
+ inputSchema: t.Object({ id: Id, ...ReplyFields }, ReplyOptions),
961
948
  async execute(input, ctx) {
962
949
  const p = (input ?? {});
963
950
  const thread = (await gmailRequest(ctx, "GET", `/threads/${p.id}`, undefined, { format: "minimal" }));
@@ -972,23 +959,21 @@ export default function gmail(rl) {
972
959
  rl.registerAction("draft.create", {
973
960
  access: "write",
974
961
  description: "Create a draft",
975
- inputSchema: {
976
- to: { type: "string", required: false },
977
- subject: { type: "string", required: false },
978
- text: { type: "string", required: false },
979
- html: { type: "string", required: false },
980
- cc: { type: "string", required: false },
981
- bcc: { type: "string", required: false },
982
- replyTo: { type: "string", required: false },
983
- from: { type: "string", required: false },
984
- fromAlias: {
985
- type: "string",
986
- required: false,
962
+ inputSchema: t.Object({
963
+ to: t.Optional(t.String()),
964
+ subject: t.Optional(t.String()),
965
+ text: t.Optional(t.String()),
966
+ html: t.Optional(t.String()),
967
+ cc: t.Optional(t.String()),
968
+ bcc: t.Optional(t.String()),
969
+ replyTo: t.Optional(t.String()),
970
+ from: t.Optional(t.String()),
971
+ fromAlias: t.Optional(t.String({
987
972
  description: "Send-as alias address (e.g. 'me+alt@x.com'); sets the From header",
988
- },
989
- threadId: { type: "string", required: false },
990
- attachments: { type: "array", required: false },
991
- },
973
+ })),
974
+ threadId: t.Optional(Id),
975
+ attachments: t.Optional(Attachments),
976
+ }, strict),
992
977
  async execute(input, ctx) {
993
978
  const p = (input ?? {});
994
979
  const from = p.from ?? p.fromAlias;
@@ -1024,10 +1009,7 @@ export default function gmail(rl) {
1024
1009
  rl.registerAction("draft.get", {
1025
1010
  access: "read",
1026
1011
  description: "Get a draft by ID",
1027
- inputSchema: {
1028
- id: { type: "string", required: true },
1029
- format: { type: "string", required: false },
1030
- },
1012
+ inputSchema: t.Object({ id: Id, format: t.Optional(MessageFormat) }, strict),
1031
1013
  async execute(input, ctx) {
1032
1014
  const p = (input ?? {});
1033
1015
  const qs = { format: p.format ?? "full" };
@@ -1037,13 +1019,13 @@ export default function gmail(rl) {
1037
1019
  rl.registerAction("draft.list", {
1038
1020
  access: "read",
1039
1021
  description: "List drafts",
1040
- inputSchema: {
1041
- q: { type: "string", required: false },
1042
- maxResults: { type: "number", required: false },
1043
- pageToken: { type: "string", required: false },
1044
- includeSpamTrash: { type: "boolean", required: false },
1045
- returnAll: { type: "boolean", required: false },
1046
- },
1022
+ inputSchema: t.Object({
1023
+ q: t.Optional(t.String()),
1024
+ maxResults: t.Optional(MaxResults),
1025
+ pageToken: t.Optional(t.String()),
1026
+ includeSpamTrash: t.Optional(t.Boolean()),
1027
+ returnAll: t.Optional(t.Boolean()),
1028
+ }, strict),
1047
1029
  async execute(input, ctx) {
1048
1030
  const p = (input ?? {});
1049
1031
  const qs = {};
@@ -1063,7 +1045,7 @@ export default function gmail(rl) {
1063
1045
  rl.registerAction("draft.delete", {
1064
1046
  access: "write",
1065
1047
  description: "Delete a draft",
1066
- inputSchema: { id: { type: "string", required: true } },
1048
+ inputSchema: IdInput,
1067
1049
  async execute(input, ctx) {
1068
1050
  const { id } = input;
1069
1051
  return gmailRequest(ctx, "DELETE", `/drafts/${id}`);
@@ -1072,7 +1054,7 @@ export default function gmail(rl) {
1072
1054
  rl.registerAction("draft.send", {
1073
1055
  access: "write",
1074
1056
  description: "Send an existing draft",
1075
- inputSchema: { id: { type: "string", required: true } },
1057
+ inputSchema: IdInput,
1076
1058
  async execute(input, ctx) {
1077
1059
  const { id } = input;
1078
1060
  return gmailRequest(ctx, "POST", "/drafts/send", { id });
@@ -1082,19 +1064,11 @@ export default function gmail(rl) {
1082
1064
  rl.registerAction("label.create", {
1083
1065
  access: "write",
1084
1066
  description: "Create a label",
1085
- inputSchema: {
1086
- name: { type: "string", required: true },
1087
- labelListVisibility: {
1088
- type: "string",
1089
- required: false,
1090
- description: "labelShow | labelShowIfUnread | labelHide",
1091
- },
1092
- messageListVisibility: {
1093
- type: "string",
1094
- required: false,
1095
- description: "show | hide",
1096
- },
1097
- },
1067
+ inputSchema: t.Object({
1068
+ name: NonEmptyString,
1069
+ labelListVisibility: t.Optional(LabelListVisibility),
1070
+ messageListVisibility: t.Optional(MessageListVisibility),
1071
+ }, strict),
1098
1072
  async execute(input, ctx) {
1099
1073
  const p = (input ?? {});
1100
1074
  const body = { name: p.name };
@@ -1110,7 +1084,7 @@ export default function gmail(rl) {
1110
1084
  rl.registerAction("label.get", {
1111
1085
  access: "read",
1112
1086
  description: "Get a label by ID",
1113
- inputSchema: { id: { type: "string", required: true } },
1087
+ inputSchema: IdInput,
1114
1088
  async execute(input, ctx) {
1115
1089
  const { id } = input;
1116
1090
  return gmailRequest(ctx, "GET", `/labels/${id}`);
@@ -1119,6 +1093,7 @@ export default function gmail(rl) {
1119
1093
  rl.registerAction("label.list", {
1120
1094
  access: "read",
1121
1095
  description: "List all labels",
1096
+ inputSchema: EmptyInput,
1122
1097
  async execute(_input, ctx) {
1123
1098
  const res = (await gmailRequest(ctx, "GET", "/labels"));
1124
1099
  return res.labels ?? [];
@@ -1127,7 +1102,7 @@ export default function gmail(rl) {
1127
1102
  rl.registerAction("label.delete", {
1128
1103
  access: "write",
1129
1104
  description: "Delete a label",
1130
- inputSchema: { id: { type: "string", required: true } },
1105
+ inputSchema: IdInput,
1131
1106
  async execute(input, ctx) {
1132
1107
  const { id } = input;
1133
1108
  return gmailRequest(ctx, "DELETE", `/labels/${id}`);
@@ -1136,12 +1111,19 @@ export default function gmail(rl) {
1136
1111
  rl.registerAction("label.update", {
1137
1112
  access: "write",
1138
1113
  description: "Update a label",
1139
- inputSchema: {
1140
- id: { type: "string", required: true },
1141
- name: { type: "string", required: false },
1142
- labelListVisibility: { type: "string", required: false },
1143
- messageListVisibility: { type: "string", required: false },
1144
- },
1114
+ inputSchema: t.Object({
1115
+ id: Id,
1116
+ name: t.Optional(NonEmptyString),
1117
+ labelListVisibility: t.Optional(LabelListVisibility),
1118
+ messageListVisibility: t.Optional(MessageListVisibility),
1119
+ }, {
1120
+ ...strict,
1121
+ anyOf: [
1122
+ { required: ["name"] },
1123
+ { required: ["labelListVisibility"] },
1124
+ { required: ["messageListVisibility"] },
1125
+ ],
1126
+ }),
1145
1127
  async execute(input, ctx) {
1146
1128
  const p = (input ?? {});
1147
1129
  const body = {};
@@ -1160,6 +1142,7 @@ export default function gmail(rl) {
1160
1142
  rl.registerAction("profile.get", {
1161
1143
  access: "read",
1162
1144
  description: "Get the authenticated user's profile",
1145
+ inputSchema: EmptyInput,
1163
1146
  async execute(_input, ctx) {
1164
1147
  return gmailRequest(ctx, "GET", "/profile");
1165
1148
  },
@@ -1167,6 +1150,7 @@ export default function gmail(rl) {
1167
1150
  rl.registerAction("alias.list", {
1168
1151
  access: "read",
1169
1152
  description: "List configured send-as aliases",
1153
+ inputSchema: EmptyInput,
1170
1154
  async execute(_input, ctx) {
1171
1155
  const res = (await gmailRequest(ctx, "GET", "/settings/sendAs"));
1172
1156
  return res.sendAs ?? [];