runline 0.7.5 → 0.7.7

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.
@@ -473,6 +473,103 @@ export default function github(rl) {
473
473
  },
474
474
  });
475
475
  // ── Repository ──────────────────────────────────────
476
+ rl.registerAction("commit.list", {
477
+ description: "List repository commits, including latest commits on a branch or path",
478
+ inputSchema: {
479
+ owner: {
480
+ type: "string",
481
+ required: true,
482
+ description: "Repository owner",
483
+ },
484
+ repo: { type: "string", required: true, description: "Repository name" },
485
+ sha: {
486
+ type: "string",
487
+ required: false,
488
+ description: "SHA or branch to start listing commits from",
489
+ },
490
+ path: {
491
+ type: "string",
492
+ required: false,
493
+ description: "Only commits containing this file path",
494
+ },
495
+ author: {
496
+ type: "string",
497
+ required: false,
498
+ description: "GitHub username or email address",
499
+ },
500
+ since: {
501
+ type: "string",
502
+ required: false,
503
+ description: "Only commits after this ISO 8601 timestamp",
504
+ },
505
+ until: {
506
+ type: "string",
507
+ required: false,
508
+ description: "Only commits before this ISO 8601 timestamp",
509
+ },
510
+ perPage: {
511
+ type: "number",
512
+ required: false,
513
+ description: "Results per page (max: 100)",
514
+ },
515
+ page: { type: "number", required: false, description: "Page number" },
516
+ },
517
+ async execute(input, ctx) {
518
+ const { owner, repo, sha, path, author, since, until, perPage, page } = (input ?? {});
519
+ const qs = {};
520
+ if (sha)
521
+ qs.sha = sha;
522
+ if (path)
523
+ qs.path = path;
524
+ if (author)
525
+ qs.author = author;
526
+ if (since)
527
+ qs.since = since;
528
+ if (until)
529
+ qs.until = until;
530
+ if (perPage)
531
+ qs.per_page = perPage;
532
+ if (page)
533
+ qs.page = page;
534
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/commits`, undefined, qs);
535
+ },
536
+ });
537
+ rl.registerAction("commit.get", {
538
+ description: "Get a repository commit by SHA, branch, or tag ref",
539
+ inputSchema: {
540
+ owner: {
541
+ type: "string",
542
+ required: true,
543
+ description: "Repository owner",
544
+ },
545
+ repo: { type: "string", required: true, description: "Repository name" },
546
+ ref: {
547
+ type: "string",
548
+ required: true,
549
+ description: "Commit SHA, branch name, or tag name",
550
+ },
551
+ },
552
+ async execute(input, ctx) {
553
+ const { owner, repo, ref } = input;
554
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/commits/${encodeURIComponent(String(ref))}`);
555
+ },
556
+ });
557
+ rl.registerAction("branch.get", {
558
+ description: "Get a repository branch, including its latest commit",
559
+ inputSchema: {
560
+ owner: {
561
+ type: "string",
562
+ required: true,
563
+ description: "Repository owner",
564
+ },
565
+ repo: { type: "string", required: true, description: "Repository name" },
566
+ branch: { type: "string", required: true, description: "Branch name" },
567
+ },
568
+ async execute(input, ctx) {
569
+ const { owner, repo, branch } = input;
570
+ return gh(ctx, "GET", `/repos/${owner}/${repo}/branches/${encodeURIComponent(String(branch))}`);
571
+ },
572
+ });
476
573
  rl.registerAction("repository.get", {
477
574
  description: "Get repository details",
478
575
  inputSchema: {
@@ -780,4 +780,171 @@ export default function googleCalendar(rl) {
780
780
  return calRequest(ctx, "POST", `/calendars/${encodeCalendarId(p.calendarId)}/events/${p.eventId}/move`, undefined, qs);
781
781
  },
782
782
  });
783
+ // ─── FreeBusy ────────────────────────────────────────────────────
784
+ rl.registerAction("freeBusy.query", {
785
+ description: "Query free/busy windows across one or more calendars in a time range. Returns an array of busy intervals per calendar id, plus any errors.",
786
+ inputSchema: {
787
+ calendarIds: { type: "array", required: true, description: "Calendar ids to query (use 'primary' for the user's own)." },
788
+ timeMin: { type: "string", required: true, description: "RFC 3339 lower bound." },
789
+ timeMax: { type: "string", required: true, description: "RFC 3339 upper bound." },
790
+ timeZone: { type: "string", required: false },
791
+ groupExpansionMax: { type: "number", required: false },
792
+ calendarExpansionMax: { type: "number", required: false },
793
+ },
794
+ async execute(input, ctx) {
795
+ const p = (input ?? {});
796
+ const body = {
797
+ timeMin: p.timeMin,
798
+ timeMax: p.timeMax,
799
+ timeZone: p.timeZone,
800
+ groupExpansionMax: p.groupExpansionMax,
801
+ calendarExpansionMax: p.calendarExpansionMax,
802
+ items: p.calendarIds.map((id) => ({ id })),
803
+ };
804
+ return calRequest(ctx, "POST", `/freeBusy`, body);
805
+ },
806
+ });
807
+ // ─── Calendar list management ───────────────────────────────────
808
+ rl.registerAction("calendarList.list", {
809
+ description: "List calendars on the user's calendar list (the user's left sidebar).",
810
+ inputSchema: {
811
+ minAccessRole: { type: "string", required: false, description: "freeBusyReader | reader | writer | owner" },
812
+ showDeleted: { type: "boolean", required: false },
813
+ showHidden: { type: "boolean", required: false },
814
+ returnAll: { type: "boolean", required: false, default: true },
815
+ },
816
+ async execute(input, ctx) {
817
+ const p = (input ?? {});
818
+ const qs = {
819
+ minAccessRole: p.minAccessRole,
820
+ showDeleted: p.showDeleted,
821
+ showHidden: p.showHidden,
822
+ maxResults: 250,
823
+ };
824
+ if (p.returnAll ?? true)
825
+ return paginateAll(ctx, "/users/me/calendarList", "items", qs);
826
+ const res = (await calRequest(ctx, "GET", "/users/me/calendarList", undefined, qs));
827
+ return res.items ?? [];
828
+ },
829
+ });
830
+ rl.registerAction("calendarList.insert", {
831
+ description: "Add a calendar (by id) to the user's calendar list.",
832
+ inputSchema: {
833
+ calendarId: { type: "string", required: true },
834
+ colorRgbFormat: { type: "boolean", required: false },
835
+ defaultReminders: { type: "array", required: false },
836
+ summaryOverride: { type: "string", required: false },
837
+ },
838
+ async execute(input, ctx) {
839
+ const p = (input ?? {});
840
+ const body = { id: p.calendarId };
841
+ if (p.summaryOverride)
842
+ body.summaryOverride = p.summaryOverride;
843
+ if (Array.isArray(p.defaultReminders))
844
+ body.defaultReminders = p.defaultReminders;
845
+ return calRequest(ctx, "POST", "/users/me/calendarList", body, { colorRgbFormat: p.colorRgbFormat });
846
+ },
847
+ });
848
+ rl.registerAction("calendarList.patch", {
849
+ description: "Patch a calendar entry on the user's calendar list (colors, summary override, reminders, selected).",
850
+ inputSchema: {
851
+ calendarId: { type: "string", required: true },
852
+ colorId: { type: "string", required: false },
853
+ backgroundColor: { type: "string", required: false },
854
+ foregroundColor: { type: "string", required: false },
855
+ summaryOverride: { type: "string", required: false },
856
+ selected: { type: "boolean", required: false },
857
+ hidden: { type: "boolean", required: false },
858
+ defaultReminders: { type: "array", required: false },
859
+ },
860
+ async execute(input, ctx) {
861
+ const p = (input ?? {});
862
+ const body = {};
863
+ for (const k of ["colorId", "backgroundColor", "foregroundColor", "summaryOverride", "selected", "hidden", "defaultReminders"]) {
864
+ if (p[k] !== undefined)
865
+ body[k] = p[k];
866
+ }
867
+ return calRequest(ctx, "PATCH", `/users/me/calendarList/${encodeCalendarId(p.calendarId)}`, body, { colorRgbFormat: p.backgroundColor || p.foregroundColor ? true : undefined });
868
+ },
869
+ });
870
+ rl.registerAction("calendarList.delete", {
871
+ description: "Remove a calendar from the user's calendar list (does not delete the underlying calendar).",
872
+ inputSchema: { calendarId: { type: "string", required: true } },
873
+ async execute(input, ctx) {
874
+ const p = (input ?? {});
875
+ await calRequest(ctx, "DELETE", `/users/me/calendarList/${encodeCalendarId(p.calendarId)}`);
876
+ return { success: true };
877
+ },
878
+ });
879
+ // ─── ACL (calendar sharing) ──────────────────────────────────────
880
+ rl.registerAction("acl.list", {
881
+ description: "List ACL rules on a calendar.",
882
+ inputSchema: {
883
+ calendarId: { type: "string", required: true },
884
+ returnAll: { type: "boolean", required: false, default: true },
885
+ },
886
+ async execute(input, ctx) {
887
+ const p = (input ?? {});
888
+ const path = `/calendars/${encodeCalendarId(p.calendarId)}/acl`;
889
+ if (p.returnAll ?? true)
890
+ return paginateAll(ctx, path, "items", { maxResults: 250 });
891
+ const res = (await calRequest(ctx, "GET", path));
892
+ return res.items ?? [];
893
+ },
894
+ });
895
+ rl.registerAction("acl.insert", {
896
+ description: "Add an ACL rule to a calendar. Roles: 'none' | 'freeBusyReader' | 'reader' | 'writer' | 'owner'.",
897
+ inputSchema: {
898
+ calendarId: { type: "string", required: true },
899
+ role: { type: "string", required: true },
900
+ scopeType: { type: "string", required: true, description: "'default' | 'user' | 'group' | 'domain'" },
901
+ scopeValue: { type: "string", required: false, description: "Email / domain depending on scopeType." },
902
+ sendNotifications: { type: "boolean", required: false },
903
+ },
904
+ async execute(input, ctx) {
905
+ const p = (input ?? {});
906
+ const body = { role: p.role, scope: { type: p.scopeType, value: p.scopeValue } };
907
+ return calRequest(ctx, "POST", `/calendars/${encodeCalendarId(p.calendarId)}/acl`, body, { sendNotifications: p.sendNotifications });
908
+ },
909
+ });
910
+ rl.registerAction("acl.update", {
911
+ description: "Patch an ACL rule's role.",
912
+ inputSchema: {
913
+ calendarId: { type: "string", required: true },
914
+ ruleId: { type: "string", required: true },
915
+ role: { type: "string", required: true },
916
+ },
917
+ async execute(input, ctx) {
918
+ const p = (input ?? {});
919
+ return calRequest(ctx, "PATCH", `/calendars/${encodeCalendarId(p.calendarId)}/acl/${encodeURIComponent(p.ruleId)}`, { role: p.role });
920
+ },
921
+ });
922
+ rl.registerAction("acl.delete", {
923
+ description: "Remove an ACL rule.",
924
+ inputSchema: {
925
+ calendarId: { type: "string", required: true },
926
+ ruleId: { type: "string", required: true },
927
+ },
928
+ async execute(input, ctx) {
929
+ const p = (input ?? {});
930
+ await calRequest(ctx, "DELETE", `/calendars/${encodeCalendarId(p.calendarId)}/acl/${encodeURIComponent(p.ruleId)}`);
931
+ return { success: true };
932
+ },
933
+ });
934
+ // ─── Settings ────────────────────────────────────────────────────
935
+ rl.registerAction("settings.list", {
936
+ description: "List the user's calendar settings (timezone, week start, working location, etc.).",
937
+ inputSchema: { returnAll: { type: "boolean", required: false, default: true } },
938
+ async execute(_input, ctx) {
939
+ return paginateAll(ctx, "/users/me/settings", "items", { maxResults: 100 });
940
+ },
941
+ });
942
+ rl.registerAction("settings.get", {
943
+ description: "Get a single setting by key (e.g. 'timezone', 'weekStart', 'locale').",
944
+ inputSchema: { setting: { type: "string", required: true } },
945
+ async execute(input, ctx) {
946
+ const p = (input ?? {});
947
+ return calRequest(ctx, "GET", `/users/me/settings/${encodeURIComponent(p.setting)}`);
948
+ },
949
+ });
783
950
  }