@sentry/junior-google 0.239.0 → 0.241.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.
- package/README.md +5 -2
- package/dist/index.js +36 -31
- package/dist/tools/cancel-event.d.ts +1 -1
- package/dist/tools/create-event.d.ts +1 -2
- package/dist/tools/find-meeting-times.d.ts +1 -1
- package/dist/tools/list-events.d.ts +1 -1
- package/dist/tools/shared.d.ts +2 -1
- package/dist/tools/update-event.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,9 +15,12 @@ This version supports Calendar only. Drive and Gmail are out of scope.
|
|
|
15
15
|
Slots where they are free come first, and each slot names the optional
|
|
16
16
|
attendees who are busy or off hours. Slots are spread across days and
|
|
17
17
|
across each day, so the requester gets a real choice.
|
|
18
|
+
- Every Calendar tool takes an optional `timeZone` for the times it reads and
|
|
19
|
+
shows. Without it, the tool uses the requester's timezone from
|
|
20
|
+
`ctx.users.resolveTimezone()`, so Junior does not have to ask for one.
|
|
18
21
|
- `createCalendarEvent` creates an event on Junior's own calendar. It sends
|
|
19
|
-
invites and
|
|
20
|
-
a simple repeat rule (weekdays, weekly, or monthly). A retry of the same
|
|
22
|
+
invites and always adds a Google Meet link. It can add a location, optional
|
|
23
|
+
attendees, and a simple repeat rule (weekdays, weekly, or monthly). A retry of the same
|
|
21
24
|
tool call returns the same event. It does not create a second invite.
|
|
22
25
|
- `listCalendarEvents` reads the events on one colleague's calendar, or on
|
|
23
26
|
Junior's own calendar when no calendar is given. It shows only what the
|
package/dist/index.js
CHANGED
|
@@ -744,8 +744,8 @@ import {
|
|
|
744
744
|
} from "@sentry/junior-plugin-api";
|
|
745
745
|
import { z as z2 } from "zod";
|
|
746
746
|
var emailListSchema = (max) => z2.array(z2.string().trim().toLowerCase().pipe(z2.email())).max(max).describe("Attendee email addresses.");
|
|
747
|
-
var timeZoneSchema = z2.string().min(1).refine(isTimeZone, "timeZone must be an IANA time zone").describe(
|
|
748
|
-
"IANA time zone used to read and show times, such as America/Los_Angeles."
|
|
747
|
+
var timeZoneSchema = z2.string().min(1).refine(isTimeZone, "timeZone must be an IANA time zone").optional().describe(
|
|
748
|
+
"IANA time zone used to read and show times, such as America/Los_Angeles. Omit to use the requester's time zone."
|
|
749
749
|
);
|
|
750
750
|
function isTimeZone(value) {
|
|
751
751
|
try {
|
|
@@ -1003,6 +1003,7 @@ function createCancelCalendarEventTool(ctx) {
|
|
|
1003
1003
|
inputSchema,
|
|
1004
1004
|
outputSchema,
|
|
1005
1005
|
async execute(input) {
|
|
1006
|
+
const timeZone = input.timeZone ?? await ctx.users.resolveTimezone();
|
|
1006
1007
|
const read = await readOwnEventForRequester(ctx, input.eventId, "cancel");
|
|
1007
1008
|
if (read.status === "cancelled") {
|
|
1008
1009
|
return {
|
|
@@ -1014,7 +1015,7 @@ function createCancelCalendarEventTool(ctx) {
|
|
|
1014
1015
|
const { event, path } = read;
|
|
1015
1016
|
const result = {
|
|
1016
1017
|
target: "cancelCalendarEvent",
|
|
1017
|
-
...ownEventResult(event,
|
|
1018
|
+
...ownEventResult(event, timeZone)
|
|
1018
1019
|
};
|
|
1019
1020
|
const response = await googleApiRequest(ctx, {
|
|
1020
1021
|
operation: "google.calendar.event.delete",
|
|
@@ -1077,7 +1078,6 @@ var inputSchema2 = z4.object({
|
|
|
1077
1078
|
"Email addresses of required attendees. Junior adds the requester automatically when it knows their email."
|
|
1078
1079
|
),
|
|
1079
1080
|
optionalAttendees: emailListSchema(50).default([]).describe("Email addresses to invite as optional attendees."),
|
|
1080
|
-
addVideoCall: z4.boolean().default(true).describe("Add a Google Meet link."),
|
|
1081
1081
|
repeat: repeatSchema.optional().describe("Make a repeating series, such as a weekly 1:1.")
|
|
1082
1082
|
}).strict();
|
|
1083
1083
|
var outputSchema2 = pluginToolOutputSchema2.extend({
|
|
@@ -1101,10 +1101,11 @@ function createCreateCalendarEventTool(ctx) {
|
|
|
1101
1101
|
const repeat = input.repeat ? `, repeating ${recurrenceRule(input.repeat)}` : "";
|
|
1102
1102
|
return `Create Google Calendar event "${input.title}" from ${input.start} to ${input.end}${repeat} and email invites to ${input.attendees.join(", ") || "the requester"}${optional}.`;
|
|
1103
1103
|
},
|
|
1104
|
-
description: "Create a Google Calendar event organized by Junior's own Google account and email invites to the attendees. Junior can later change or cancel it. Use after the requester confirms the time, or when they already gave an exact time. Check the time with findMeetingTimes first unless the requester says to book it anyway. Only people in the company's Google Workspace domains can be invited.",
|
|
1104
|
+
description: "Create a Google Calendar event organized by Junior's own Google account and email invites to the attendees. Every event gets a Google Meet link. Junior can later change or cancel it. Use after the requester confirms the time, or when they already gave an exact time. Check the time with findMeetingTimes first unless the requester says to book it anyway. Only people in the company's Google Workspace domains can be invited.",
|
|
1105
1105
|
inputSchema: inputSchema2,
|
|
1106
1106
|
outputSchema: outputSchema2,
|
|
1107
1107
|
async execute(input, options) {
|
|
1108
|
+
const timeZone = input.timeZone ?? await ctx.users.resolveTimezone();
|
|
1108
1109
|
const startMs = Date.parse(input.start);
|
|
1109
1110
|
const endMs = Date.parse(input.end);
|
|
1110
1111
|
if (endMs <= startMs) {
|
|
@@ -1132,27 +1133,25 @@ function createCreateCalendarEventTool(ctx) {
|
|
|
1132
1133
|
...attendees.map((email) => ({ email })),
|
|
1133
1134
|
...optionalAttendees.map((email) => ({ email, optional: true }))
|
|
1134
1135
|
],
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
requestId: eventId
|
|
1140
|
-
}
|
|
1136
|
+
conferenceData: {
|
|
1137
|
+
createRequest: {
|
|
1138
|
+
conferenceSolutionKey: { type: "hangoutsMeet" },
|
|
1139
|
+
requestId: eventId
|
|
1141
1140
|
}
|
|
1142
|
-
}
|
|
1141
|
+
},
|
|
1143
1142
|
...input.description ? { description: input.description } : void 0,
|
|
1144
|
-
end: { dateTime: input.end, timeZone
|
|
1143
|
+
end: { dateTime: input.end, timeZone },
|
|
1145
1144
|
guestsCanModify: false,
|
|
1146
1145
|
id: eventId,
|
|
1147
1146
|
...input.location ? { location: input.location } : void 0,
|
|
1148
1147
|
...input.repeat ? { recurrence: [recurrenceRule(input.repeat)] } : void 0,
|
|
1149
|
-
start: { dateTime: input.start, timeZone
|
|
1148
|
+
start: { dateTime: input.start, timeZone },
|
|
1150
1149
|
summary: input.title
|
|
1151
1150
|
},
|
|
1152
1151
|
operation: "google.calendar.event.create",
|
|
1153
1152
|
path: "/calendar/v3/calendars/primary/events",
|
|
1154
1153
|
query: {
|
|
1155
|
-
conferenceDataVersion:
|
|
1154
|
+
conferenceDataVersion: "1",
|
|
1156
1155
|
sendUpdates: "all"
|
|
1157
1156
|
}
|
|
1158
1157
|
});
|
|
@@ -1173,7 +1172,7 @@ function createCreateCalendarEventTool(ctx) {
|
|
|
1173
1172
|
return {
|
|
1174
1173
|
target: "createCalendarEvent",
|
|
1175
1174
|
created,
|
|
1176
|
-
...ownEventResult(ownEventSchema.parse(event.body),
|
|
1175
|
+
...ownEventResult(ownEventSchema.parse(event.body), timeZone)
|
|
1177
1176
|
};
|
|
1178
1177
|
}
|
|
1179
1178
|
});
|
|
@@ -1205,7 +1204,7 @@ var inputSchema3 = z5.object({
|
|
|
1205
1204
|
"End of the search window, RFC 3339 with offset. Defaults to 7 days after timeMin. At most 14 days after timeMin."
|
|
1206
1205
|
),
|
|
1207
1206
|
timeZone: timeZoneSchema.describe(
|
|
1208
|
-
"
|
|
1207
|
+
"IANA time zone for slot labels, such as America/Los_Angeles. Omit to use the requester's time zone. It is also the working-hours zone for anyone whose calendar time zone Junior cannot read."
|
|
1209
1208
|
),
|
|
1210
1209
|
workdayStart: clockTimeSchema.default("09:00").describe(
|
|
1211
1210
|
"Earliest local start, 24-hour HH:MM, in each attendee's own calendar time zone."
|
|
@@ -1397,6 +1396,7 @@ function createFindMeetingTimesTool(ctx) {
|
|
|
1397
1396
|
inputSchema: inputSchema3,
|
|
1398
1397
|
outputSchema: outputSchema3,
|
|
1399
1398
|
async execute(input) {
|
|
1399
|
+
const timeZone = input.timeZone ?? await ctx.users.resolveTimezone();
|
|
1400
1400
|
const timeMinMs = Math.max(
|
|
1401
1401
|
input.timeMin ? Date.parse(input.timeMin) : 0,
|
|
1402
1402
|
Date.now()
|
|
@@ -1448,8 +1448,11 @@ function createFindMeetingTimesTool(ctx) {
|
|
|
1448
1448
|
unavailable2.push({ email, reason: error ?? "notFound" });
|
|
1449
1449
|
return;
|
|
1450
1450
|
}
|
|
1451
|
-
const
|
|
1452
|
-
checked.push({
|
|
1451
|
+
const calendarZone = timeZones[index];
|
|
1452
|
+
checked.push({
|
|
1453
|
+
email,
|
|
1454
|
+
...calendarZone ? { timeZone: calendarZone } : void 0
|
|
1455
|
+
});
|
|
1453
1456
|
slotAttendees.push({
|
|
1454
1457
|
busy: calendar.busy.map((interval) => ({
|
|
1455
1458
|
endMs: Date.parse(interval.end),
|
|
@@ -1457,7 +1460,7 @@ function createFindMeetingTimesTool(ctx) {
|
|
|
1457
1460
|
})),
|
|
1458
1461
|
email,
|
|
1459
1462
|
required: required.has(email),
|
|
1460
|
-
timeZone:
|
|
1463
|
+
timeZone: calendarZone ?? timeZone
|
|
1461
1464
|
});
|
|
1462
1465
|
});
|
|
1463
1466
|
const slots = !slotAttendees.some((attendee) => attendee.required) ? [] : findFreeSlots({
|
|
@@ -1466,28 +1469,28 @@ function createFindMeetingTimesTool(ctx) {
|
|
|
1466
1469
|
maxResults: input.maxResults,
|
|
1467
1470
|
timeMaxMs,
|
|
1468
1471
|
timeMinMs,
|
|
1469
|
-
timeZone
|
|
1472
|
+
timeZone,
|
|
1470
1473
|
workdayEnd: input.workdayEnd,
|
|
1471
1474
|
workdayStart: input.workdayStart
|
|
1472
1475
|
});
|
|
1473
1476
|
const otherTimeZones = [
|
|
1474
1477
|
...new Set(slotAttendees.map((attendee) => attendee.timeZone))
|
|
1475
|
-
].filter((
|
|
1478
|
+
].filter((zone) => zone !== timeZone);
|
|
1476
1479
|
return {
|
|
1477
1480
|
target: "findMeetingTimes",
|
|
1478
1481
|
checked,
|
|
1479
1482
|
slots: slots.map((slot) => ({
|
|
1480
1483
|
end: new Date(slot.endMs).toISOString(),
|
|
1481
|
-
label: formatInterval(slot.startMs, slot.endMs,
|
|
1484
|
+
label: formatInterval(slot.startMs, slot.endMs, timeZone),
|
|
1482
1485
|
...otherTimeZones.length ? {
|
|
1483
1486
|
otherTimeZoneLabels: otherTimeZones.map(
|
|
1484
|
-
(
|
|
1487
|
+
(zone) => formatInterval(slot.startMs, slot.endMs, zone)
|
|
1485
1488
|
)
|
|
1486
1489
|
} : void 0,
|
|
1487
1490
|
...slot.optionalConflicts.length ? { optionalConflicts: slot.optionalConflicts } : void 0,
|
|
1488
1491
|
start: new Date(slot.startMs).toISOString()
|
|
1489
1492
|
})),
|
|
1490
|
-
timeZone
|
|
1493
|
+
timeZone,
|
|
1491
1494
|
unavailable: unavailable2
|
|
1492
1495
|
};
|
|
1493
1496
|
}
|
|
@@ -1591,6 +1594,7 @@ function createListCalendarEventsTool(ctx) {
|
|
|
1591
1594
|
inputSchema: inputSchema4,
|
|
1592
1595
|
outputSchema: outputSchema4,
|
|
1593
1596
|
async execute(input) {
|
|
1597
|
+
const timeZone = input.timeZone ?? await ctx.users.resolveTimezone();
|
|
1594
1598
|
const timeMinMs = Date.parse(input.timeMin);
|
|
1595
1599
|
const timeMaxMs = Date.parse(input.timeMax);
|
|
1596
1600
|
if (timeMaxMs <= timeMinMs) {
|
|
@@ -1610,13 +1614,13 @@ function createListCalendarEventsTool(ctx) {
|
|
|
1610
1614
|
singleEvents: "true",
|
|
1611
1615
|
timeMax: new Date(timeMaxMs).toISOString(),
|
|
1612
1616
|
timeMin: new Date(timeMinMs).toISOString(),
|
|
1613
|
-
timeZone
|
|
1617
|
+
timeZone
|
|
1614
1618
|
}
|
|
1615
1619
|
});
|
|
1616
1620
|
const result = {
|
|
1617
1621
|
target: "listCalendarEvents",
|
|
1618
1622
|
calendar,
|
|
1619
|
-
timeZone
|
|
1623
|
+
timeZone
|
|
1620
1624
|
};
|
|
1621
1625
|
if (response.status === 404) {
|
|
1622
1626
|
return { ...result, events: [], truncated: false, visible: false };
|
|
@@ -1630,7 +1634,7 @@ function createListCalendarEventsTool(ctx) {
|
|
|
1630
1634
|
events: items.filter((event) => event.status !== "cancelled").map((event) => ({
|
|
1631
1635
|
end: event.end.dateTime ?? lastAllDayDate(event.end) ?? "",
|
|
1632
1636
|
eventId: event.id,
|
|
1633
|
-
label: eventLabel(event.start, event.end,
|
|
1637
|
+
label: eventLabel(event.start, event.end, timeZone),
|
|
1634
1638
|
start: event.start.dateTime ?? event.start.date ?? "",
|
|
1635
1639
|
...event.summary ? { title: event.summary } : void 0,
|
|
1636
1640
|
...event.location ? { location: event.location } : void 0,
|
|
@@ -1709,6 +1713,7 @@ function createUpdateCalendarEventTool(ctx) {
|
|
|
1709
1713
|
inputSchema: inputSchema5,
|
|
1710
1714
|
outputSchema: outputSchema5,
|
|
1711
1715
|
async execute(input) {
|
|
1716
|
+
const timeZone = input.timeZone ?? await ctx.users.resolveTimezone();
|
|
1712
1717
|
if (input.start && input.end) {
|
|
1713
1718
|
const durationMs = Date.parse(input.end) - Date.parse(input.start);
|
|
1714
1719
|
if (durationMs <= 0) {
|
|
@@ -1758,8 +1763,8 @@ function createUpdateCalendarEventTool(ctx) {
|
|
|
1758
1763
|
description: input.description
|
|
1759
1764
|
},
|
|
1760
1765
|
...input.start && input.end && {
|
|
1761
|
-
end: { dateTime: input.end, timeZone
|
|
1762
|
-
start: { dateTime: input.start, timeZone
|
|
1766
|
+
end: { dateTime: input.end, timeZone },
|
|
1767
|
+
start: { dateTime: input.start, timeZone }
|
|
1763
1768
|
},
|
|
1764
1769
|
...input.location !== void 0 && { location: input.location },
|
|
1765
1770
|
...attendeesChanged && { attendees: [...kept, ...added] },
|
|
@@ -1784,7 +1789,7 @@ function createUpdateCalendarEventTool(ctx) {
|
|
|
1784
1789
|
}
|
|
1785
1790
|
return {
|
|
1786
1791
|
target: "updateCalendarEvent",
|
|
1787
|
-
...ownEventResult(ownEventSchema.parse(response.body),
|
|
1792
|
+
...ownEventResult(ownEventSchema.parse(response.body), timeZone)
|
|
1788
1793
|
};
|
|
1789
1794
|
}
|
|
1790
1795
|
});
|
|
@@ -8,7 +8,7 @@ import { type GoogleToolContext } from "./shared";
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function createCancelCalendarEventTool(ctx: GoogleToolContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
10
10
|
eventId: string;
|
|
11
|
-
timeZone
|
|
11
|
+
timeZone?: string | undefined;
|
|
12
12
|
}, {
|
|
13
13
|
[x: string]: unknown;
|
|
14
14
|
eventId: string;
|
|
@@ -24,12 +24,11 @@ export declare function createCreateCalendarEventTool(ctx: GoogleToolContext): i
|
|
|
24
24
|
title: string;
|
|
25
25
|
start: string;
|
|
26
26
|
end: string;
|
|
27
|
-
timeZone: string;
|
|
28
27
|
attendees: string[];
|
|
29
28
|
optionalAttendees: string[];
|
|
30
|
-
addVideoCall: boolean;
|
|
31
29
|
description?: string | undefined;
|
|
32
30
|
location?: string | undefined;
|
|
31
|
+
timeZone?: string | undefined;
|
|
33
32
|
repeat?: {
|
|
34
33
|
frequency: "weekdays" | "weekly" | "monthly";
|
|
35
34
|
interval: number;
|
|
@@ -43,12 +43,12 @@ export declare function createFindMeetingTimesTool(ctx: GoogleToolContext): impo
|
|
|
43
43
|
attendees: string[];
|
|
44
44
|
optionalAttendees: string[];
|
|
45
45
|
durationMinutes: number;
|
|
46
|
-
timeZone: string;
|
|
47
46
|
workdayStart: string;
|
|
48
47
|
workdayEnd: string;
|
|
49
48
|
maxResults: number;
|
|
50
49
|
timeMin?: string | undefined;
|
|
51
50
|
timeMax?: string | undefined;
|
|
51
|
+
timeZone?: string | undefined;
|
|
52
52
|
}, {
|
|
53
53
|
[x: string]: unknown;
|
|
54
54
|
target: "findMeetingTimes";
|
|
@@ -9,9 +9,9 @@ import { type GoogleToolContext } from "./shared";
|
|
|
9
9
|
export declare function createListCalendarEventsTool(ctx: GoogleToolContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
10
10
|
timeMin: string;
|
|
11
11
|
timeMax: string;
|
|
12
|
-
timeZone: string;
|
|
13
12
|
maxResults: number;
|
|
14
13
|
calendar?: string | undefined;
|
|
14
|
+
timeZone?: string | undefined;
|
|
15
15
|
}, {
|
|
16
16
|
[x: string]: unknown;
|
|
17
17
|
target: "listCalendarEvents";
|
package/dist/tools/shared.d.ts
CHANGED
|
@@ -11,10 +11,11 @@ export interface GoogleToolContext {
|
|
|
11
11
|
resolveActor(): Promise<{
|
|
12
12
|
user?: User;
|
|
13
13
|
} | undefined>;
|
|
14
|
+
resolveTimezone(): Promise<string>;
|
|
14
15
|
};
|
|
15
16
|
}
|
|
16
17
|
export declare const emailListSchema: (max: number) => z.ZodArray<z.ZodPipe<z.ZodString, z.ZodEmail>>;
|
|
17
|
-
export declare const timeZoneSchema: z.ZodString
|
|
18
|
+
export declare const timeZoneSchema: z.ZodOptional<z.ZodString>;
|
|
18
19
|
/** True when the runtime knows this IANA time zone. */
|
|
19
20
|
export declare function isTimeZone(value: string): boolean;
|
|
20
21
|
/** Reject people outside the domains Junior may look up or invite. */
|
|
@@ -6,7 +6,6 @@ import { type GoogleToolContext } from "./shared";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function createUpdateCalendarEventTool(ctx: GoogleToolContext): import("@sentry/junior-plugin-api").PluginToolDefinition<{
|
|
8
8
|
eventId: string;
|
|
9
|
-
timeZone: string;
|
|
10
9
|
addAttendees: string[];
|
|
11
10
|
addOptionalAttendees: string[];
|
|
12
11
|
removeAttendees: string[];
|
|
@@ -14,6 +13,7 @@ export declare function createUpdateCalendarEventTool(ctx: GoogleToolContext): i
|
|
|
14
13
|
description?: string | undefined;
|
|
15
14
|
start?: string | undefined;
|
|
16
15
|
end?: string | undefined;
|
|
16
|
+
timeZone?: string | undefined;
|
|
17
17
|
location?: string | undefined;
|
|
18
18
|
addVideoCall?: true | undefined;
|
|
19
19
|
}, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/junior-google",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.241.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"commander": "^14.0.3",
|
|
26
26
|
"drizzle-orm": "^0.45.2",
|
|
27
27
|
"zod": "^4.5.4",
|
|
28
|
-
"@sentry/junior-plugin-api": "0.
|
|
28
|
+
"@sentry/junior-plugin-api": "0.241.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@oxlint/plugins": "1.79.0",
|