gws-axi 0.1.0 → 0.2.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/dist/src/commands/calendar/dateish.d.ts +28 -0
- package/dist/src/commands/calendar/dateish.js +67 -0
- package/dist/src/commands/calendar/dateish.js.map +1 -0
- package/dist/src/commands/calendar/events.js +3 -19
- package/dist/src/commands/calendar/events.js.map +1 -1
- package/dist/src/commands/calendar/freebusy.d.ts +2 -0
- package/dist/src/commands/calendar/freebusy.js +165 -0
- package/dist/src/commands/calendar/freebusy.js.map +1 -0
- package/dist/src/commands/calendar/search.d.ts +2 -0
- package/dist/src/commands/calendar/search.js +352 -0
- package/dist/src/commands/calendar/search.js.map +1 -0
- package/dist/src/commands/calendar.js +4 -2
- package/dist/src/commands/calendar.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a date-ish flag value into an ISO 8601 string.
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* - Date-only (`YYYY-MM-DD`) → LOCAL midnight of that date, expressed as
|
|
6
|
+
* ISO. We deliberately do NOT use `new Date("YYYY-MM-DD")` because the
|
|
7
|
+
* JS spec parses that as UTC midnight (a well-known footgun), which
|
|
8
|
+
* contradicts our docs ("midnight local").
|
|
9
|
+
* - Datetime with offset (`YYYY-MM-DDTHH:MM:SS±HH:MM` or trailing `Z`)
|
|
10
|
+
* → parsed as-is, timezone preserved.
|
|
11
|
+
* - Datetime without offset (`YYYY-MM-DDTHH:MM`) → parsed as local time
|
|
12
|
+
* per the JS spec (which for this format does use local).
|
|
13
|
+
* - Anything else → AxiError with a clear format hint.
|
|
14
|
+
*
|
|
15
|
+
* Returns an ISO string (with timezone info) suitable for Google API
|
|
16
|
+
* `timeMin` / `timeMax` parameters.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseDateishFlag(value: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Convert a UTC timestamp string (e.g. "2026-04-22T13:00:00Z") to an ISO
|
|
21
|
+
* string with the system's local timezone offset (e.g.
|
|
22
|
+
* "2026-04-22T09:00:00-04:00"). Useful for making freebusy output
|
|
23
|
+
* consistent with events output, which already comes back in
|
|
24
|
+
* offset-preserving form from Google.
|
|
25
|
+
*
|
|
26
|
+
* Invalid input returns the original string unchanged.
|
|
27
|
+
*/
|
|
28
|
+
export declare function toLocalOffsetISO(input: string): string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse a date-ish flag value into an ISO 8601 string.
|
|
4
|
+
*
|
|
5
|
+
* Rules:
|
|
6
|
+
* - Date-only (`YYYY-MM-DD`) → LOCAL midnight of that date, expressed as
|
|
7
|
+
* ISO. We deliberately do NOT use `new Date("YYYY-MM-DD")` because the
|
|
8
|
+
* JS spec parses that as UTC midnight (a well-known footgun), which
|
|
9
|
+
* contradicts our docs ("midnight local").
|
|
10
|
+
* - Datetime with offset (`YYYY-MM-DDTHH:MM:SS±HH:MM` or trailing `Z`)
|
|
11
|
+
* → parsed as-is, timezone preserved.
|
|
12
|
+
* - Datetime without offset (`YYYY-MM-DDTHH:MM`) → parsed as local time
|
|
13
|
+
* per the JS spec (which for this format does use local).
|
|
14
|
+
* - Anything else → AxiError with a clear format hint.
|
|
15
|
+
*
|
|
16
|
+
* Returns an ISO string (with timezone info) suitable for Google API
|
|
17
|
+
* `timeMin` / `timeMax` parameters.
|
|
18
|
+
*/
|
|
19
|
+
export function parseDateishFlag(value) {
|
|
20
|
+
if (!value) {
|
|
21
|
+
throw new AxiError("Missing date/time value", "VALIDATION_ERROR", ["Use ISO format: 2026-04-20T14:00 or just 2026-04-20"]);
|
|
22
|
+
}
|
|
23
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(value)) {
|
|
24
|
+
// Date-only: force local midnight instead of the spec-mandated UTC
|
|
25
|
+
// midnight, matching our --help docs.
|
|
26
|
+
const [y, m, d] = value.split("-").map((part) => Number(part));
|
|
27
|
+
const local = new Date(y, m - 1, d, 0, 0, 0, 0);
|
|
28
|
+
if (Number.isNaN(local.getTime())) {
|
|
29
|
+
throw new AxiError(`Cannot parse date: ${value}`, "VALIDATION_ERROR", ["Use YYYY-MM-DD (e.g. 2026-04-20)"]);
|
|
30
|
+
}
|
|
31
|
+
return local.toISOString();
|
|
32
|
+
}
|
|
33
|
+
const parsed = new Date(value);
|
|
34
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
35
|
+
throw new AxiError(`Cannot parse date/time: ${value}`, "VALIDATION_ERROR", [
|
|
36
|
+
"Use ISO 8601 format: 2026-04-20T14:00:00-04:00",
|
|
37
|
+
"Local time: 2026-04-20T14:00 (no offset — interpreted as local)",
|
|
38
|
+
"Date-only: 2026-04-20 (midnight local)",
|
|
39
|
+
]);
|
|
40
|
+
}
|
|
41
|
+
return parsed.toISOString();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Convert a UTC timestamp string (e.g. "2026-04-22T13:00:00Z") to an ISO
|
|
45
|
+
* string with the system's local timezone offset (e.g.
|
|
46
|
+
* "2026-04-22T09:00:00-04:00"). Useful for making freebusy output
|
|
47
|
+
* consistent with events output, which already comes back in
|
|
48
|
+
* offset-preserving form from Google.
|
|
49
|
+
*
|
|
50
|
+
* Invalid input returns the original string unchanged.
|
|
51
|
+
*/
|
|
52
|
+
export function toLocalOffsetISO(input) {
|
|
53
|
+
if (!input)
|
|
54
|
+
return input;
|
|
55
|
+
const d = new Date(input);
|
|
56
|
+
if (Number.isNaN(d.getTime()))
|
|
57
|
+
return input;
|
|
58
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
59
|
+
const offsetMin = -d.getTimezoneOffset();
|
|
60
|
+
const sign = offsetMin >= 0 ? "+" : "-";
|
|
61
|
+
const absMin = Math.abs(offsetMin);
|
|
62
|
+
const offsetStr = `${sign}${pad(Math.floor(absMin / 60))}:${pad(absMin % 60)}`;
|
|
63
|
+
return (`${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +
|
|
64
|
+
`T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}` +
|
|
65
|
+
offsetStr);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=dateish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dateish.js","sourceRoot":"","sources":["../../../../src/commands/calendar/dateish.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AxiError } from "axi-sdk-js";
|
|
2
2
|
import { calendarClient, translateGoogleError } from "../../google/client.js";
|
|
3
3
|
import { field, mapEnum, pluck, renderListResponse, truncated, } from "../../output/index.js";
|
|
4
|
+
import { parseDateishFlag } from "./dateish.js";
|
|
4
5
|
export const EVENTS_HELP = `usage: gws-axi calendar events [flags]
|
|
5
6
|
flags[8]:
|
|
6
7
|
--calendar <id> Calendar to query (default: "primary")
|
|
@@ -50,11 +51,11 @@ function parseEventsFlags(args) {
|
|
|
50
51
|
i++;
|
|
51
52
|
break;
|
|
52
53
|
case "--from":
|
|
53
|
-
flags.from =
|
|
54
|
+
flags.from = parseDateishFlag(next);
|
|
54
55
|
i++;
|
|
55
56
|
break;
|
|
56
57
|
case "--to":
|
|
57
|
-
flags.to =
|
|
58
|
+
flags.to = parseDateishFlag(next);
|
|
58
59
|
i++;
|
|
59
60
|
break;
|
|
60
61
|
case "--limit":
|
|
@@ -78,23 +79,6 @@ function parseEventsFlags(args) {
|
|
|
78
79
|
}
|
|
79
80
|
return flags;
|
|
80
81
|
}
|
|
81
|
-
function parseDateish(value) {
|
|
82
|
-
if (!value) {
|
|
83
|
-
throw new AxiError("Missing date/time value", "VALIDATION_ERROR", ["Use ISO format: 2026-04-20T14:00 or just 2026-04-20"]);
|
|
84
|
-
}
|
|
85
|
-
// Accept ISO 8601 directly. If it parses, use the parsed form (normalizes
|
|
86
|
-
// time zone). If not, raise a clear error — we're deliberately not doing
|
|
87
|
-
// natural-language parsing in v1.
|
|
88
|
-
const parsed = new Date(value);
|
|
89
|
-
if (Number.isNaN(parsed.getTime())) {
|
|
90
|
-
throw new AxiError(`Cannot parse date/time: ${value}`, "VALIDATION_ERROR", [
|
|
91
|
-
"Use ISO 8601 format: 2026-04-20T14:00:00-04:00",
|
|
92
|
-
"Or date-only: 2026-04-20",
|
|
93
|
-
"Natural-language dates (e.g. 'tomorrow 2pm') are not supported in v1",
|
|
94
|
-
]);
|
|
95
|
-
}
|
|
96
|
-
return parsed.toISOString();
|
|
97
|
-
}
|
|
98
82
|
function baseSchema() {
|
|
99
83
|
return [
|
|
100
84
|
field("id"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/commands/calendar/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EACL,KAAK,EACL,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,SAAS,GAEV,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../../../src/commands/calendar/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const FREEBUSY_HELP = "usage: gws-axi calendar freebusy [flags]\nflags[4]:\n --calendars <ids> Comma-separated calendar IDs (default: \"primary\")\n --from <iso> Start of query range (default: start of today, local tz)\n --to <iso> End of query range (default: end of today, local tz)\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi calendar freebusy\n gws-axi calendar freebusy --calendars primary,team@jarv.us\n gws-axi calendar freebusy --from 2026-04-22T09:00 --to 2026-04-22T17:00\noutput:\n Busy blocks across the requested calendars, one row per block.\n calendar column identifies which calendar each block belongs to.\n Empty result means no busy time in the range \u2014 you're free.\nnotes:\n Time ranges longer than a few days work but the API caps total time\n coverage at ~3 months across all requested calendars combined. For\n long ranges with many calendars, narrow to one at a time.\n";
|
|
2
|
+
export declare function calendarFreebusyCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { calendarClient, translateGoogleError } from "../../google/client.js";
|
|
2
|
+
import { renderList, renderObject, joinBlocks, renderHelp } from "../../output/index.js";
|
|
3
|
+
import { parseDateishFlag, toLocalOffsetISO } from "./dateish.js";
|
|
4
|
+
export const FREEBUSY_HELP = `usage: gws-axi calendar freebusy [flags]
|
|
5
|
+
flags[4]:
|
|
6
|
+
--calendars <ids> Comma-separated calendar IDs (default: "primary")
|
|
7
|
+
--from <iso> Start of query range (default: start of today, local tz)
|
|
8
|
+
--to <iso> End of query range (default: end of today, local tz)
|
|
9
|
+
--account <email> Account override when 2+ are configured
|
|
10
|
+
examples:
|
|
11
|
+
gws-axi calendar freebusy
|
|
12
|
+
gws-axi calendar freebusy --calendars primary,team@jarv.us
|
|
13
|
+
gws-axi calendar freebusy --from 2026-04-22T09:00 --to 2026-04-22T17:00
|
|
14
|
+
output:
|
|
15
|
+
Busy blocks across the requested calendars, one row per block.
|
|
16
|
+
calendar column identifies which calendar each block belongs to.
|
|
17
|
+
Empty result means no busy time in the range — you're free.
|
|
18
|
+
notes:
|
|
19
|
+
Time ranges longer than a few days work but the API caps total time
|
|
20
|
+
coverage at ~3 months across all requested calendars combined. For
|
|
21
|
+
long ranges with many calendars, narrow to one at a time.
|
|
22
|
+
`;
|
|
23
|
+
function parseFlags(args) {
|
|
24
|
+
const now = new Date();
|
|
25
|
+
const startOfDay = new Date(now);
|
|
26
|
+
startOfDay.setHours(0, 0, 0, 0);
|
|
27
|
+
const endOfDay = new Date(now);
|
|
28
|
+
endOfDay.setHours(23, 59, 59, 999);
|
|
29
|
+
const flags = {
|
|
30
|
+
calendars: ["primary"],
|
|
31
|
+
from: startOfDay.toISOString(),
|
|
32
|
+
to: endOfDay.toISOString(),
|
|
33
|
+
};
|
|
34
|
+
for (let i = 0; i < args.length; i++) {
|
|
35
|
+
const arg = args[i];
|
|
36
|
+
const next = args[i + 1];
|
|
37
|
+
switch (arg) {
|
|
38
|
+
case "--calendars":
|
|
39
|
+
flags.calendars = next
|
|
40
|
+
.split(",")
|
|
41
|
+
.map((s) => s.trim())
|
|
42
|
+
.filter(Boolean);
|
|
43
|
+
i++;
|
|
44
|
+
break;
|
|
45
|
+
case "--from":
|
|
46
|
+
flags.from = parseDateishFlag(next);
|
|
47
|
+
i++;
|
|
48
|
+
break;
|
|
49
|
+
case "--to":
|
|
50
|
+
flags.to = parseDateishFlag(next);
|
|
51
|
+
i++;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return flags;
|
|
56
|
+
}
|
|
57
|
+
export async function calendarFreebusyCommand(account, args) {
|
|
58
|
+
const flags = parseFlags(args);
|
|
59
|
+
const api = await calendarClient(account);
|
|
60
|
+
let data;
|
|
61
|
+
try {
|
|
62
|
+
const res = await api.freebusy.query({
|
|
63
|
+
requestBody: {
|
|
64
|
+
timeMin: flags.from,
|
|
65
|
+
timeMax: flags.to,
|
|
66
|
+
items: flags.calendars.map((id) => ({ id })),
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
data = res.data;
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
throw translateGoogleError(err, {
|
|
73
|
+
account,
|
|
74
|
+
operation: "calendar.freebusy.query",
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
const coverage = [];
|
|
78
|
+
const rows = [];
|
|
79
|
+
const responseCalendars = data.calendars ?? {};
|
|
80
|
+
for (const calId of flags.calendars) {
|
|
81
|
+
const info = responseCalendars[calId];
|
|
82
|
+
if (!info) {
|
|
83
|
+
coverage.push({
|
|
84
|
+
calendar: calId,
|
|
85
|
+
status: "error",
|
|
86
|
+
busy_blocks: 0,
|
|
87
|
+
detail: "missing from response",
|
|
88
|
+
});
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (info.errors?.length) {
|
|
92
|
+
coverage.push({
|
|
93
|
+
calendar: calId,
|
|
94
|
+
status: "error",
|
|
95
|
+
busy_blocks: 0,
|
|
96
|
+
detail: info.errors.map((e) => e.reason ?? "unknown").join(", "),
|
|
97
|
+
});
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const busy = info.busy ?? [];
|
|
101
|
+
coverage.push({
|
|
102
|
+
calendar: calId,
|
|
103
|
+
status: "ok",
|
|
104
|
+
busy_blocks: busy.length,
|
|
105
|
+
detail: busy.length === 0 ? "free for entire range" : "",
|
|
106
|
+
});
|
|
107
|
+
for (const block of busy) {
|
|
108
|
+
rows.push({
|
|
109
|
+
calendar: calId,
|
|
110
|
+
// Google returns freebusy timestamps in UTC (trailing Z). Convert to
|
|
111
|
+
// local-with-offset so format matches `calendar events` output.
|
|
112
|
+
start: toLocalOffsetISO(block.start ?? ""),
|
|
113
|
+
end: toLocalOffsetISO(block.end ?? ""),
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Sort by start time so the agent sees a timeline view
|
|
118
|
+
rows.sort((a, b) => a.start.localeCompare(b.start));
|
|
119
|
+
const blocks = [];
|
|
120
|
+
const erroredCount = coverage.filter((c) => c.status === "error").length;
|
|
121
|
+
blocks.push(renderObject({
|
|
122
|
+
account,
|
|
123
|
+
range: `${toLocalOffsetISO(flags.from)} → ${toLocalOffsetISO(flags.to)}`,
|
|
124
|
+
busy_block_count: rows.length,
|
|
125
|
+
}));
|
|
126
|
+
// Always render per-calendar coverage so agents can confirm each requested
|
|
127
|
+
// calendar was actually reached. Distinguishes "free" from "errored".
|
|
128
|
+
blocks.push(renderList("coverage", coverage, [
|
|
129
|
+
{ name: "calendar", extract: (r) => r.calendar },
|
|
130
|
+
{ name: "status", extract: (r) => r.status },
|
|
131
|
+
{ name: "busy_blocks", extract: (r) => r.busy_blocks },
|
|
132
|
+
{ name: "detail", extract: (r) => r.detail },
|
|
133
|
+
]));
|
|
134
|
+
if (rows.length === 0) {
|
|
135
|
+
blocks.push(renderObject({ busy: [] }));
|
|
136
|
+
const okCalendars = coverage.filter((c) => c.status === "ok").map((c) => c.calendar);
|
|
137
|
+
blocks.push(renderObject({
|
|
138
|
+
message: okCalendars.length > 0
|
|
139
|
+
? `no busy time — ${okCalendars.join(", ")} free for the entire range`
|
|
140
|
+
: "no successfully-queried calendars had busy blocks",
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
blocks.push(renderList("busy", rows, [
|
|
145
|
+
{ name: "calendar", extract: (r) => r.calendar },
|
|
146
|
+
{ name: "start", extract: (r) => r.start },
|
|
147
|
+
{ name: "end", extract: (r) => r.end },
|
|
148
|
+
]));
|
|
149
|
+
}
|
|
150
|
+
const suggestions = [];
|
|
151
|
+
if (flags.calendars.length === 1 && flags.calendars[0] === "primary") {
|
|
152
|
+
suggestions.push(`Add more calendars with --calendars primary,team@... to see cross-calendar availability`);
|
|
153
|
+
}
|
|
154
|
+
if (rows.length === 0 && erroredCount === 0) {
|
|
155
|
+
suggestions.push(`Widen the time range with --from/--to to verify availability at other times`);
|
|
156
|
+
}
|
|
157
|
+
if (erroredCount > 0) {
|
|
158
|
+
suggestions.push(`${erroredCount} calendar(s) returned errors — check ids or your access rights`);
|
|
159
|
+
}
|
|
160
|
+
if (suggestions.length > 0) {
|
|
161
|
+
blocks.push(renderHelp(suggestions));
|
|
162
|
+
}
|
|
163
|
+
return joinBlocks(...blocks);
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=freebusy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"freebusy.js","sourceRoot":"","sources":["../../../../src/commands/calendar/freebusy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const SEARCH_HELP = "usage: gws-axi calendar search --query <text> [flags]\nflags[9]:\n --query <text> REQUIRED \u2014 full-text search across summary/description/location/attendees\n --from <iso> Earliest event start (default: 30 days ago)\n --to <iso> Latest event start (default: 1 year from now)\n --calendars <ids> Comma-separated calendar IDs (overrides scope default)\n --include-shared Also search non-primary calendars: teammate\n calendars delegated to you, read-only subscriptions,\n anything in calendarList that isn't your primary.\n Default is primary-only.\n --limit <n> Max events PER calendar (default: 50, max: 2500)\n --fields <list> Extra columns: status, organizer, location, attendees, seen_on\n --no-dedupe Keep per-calendar duplicates; one row per (calendar, event) pair\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi calendar search --query \"standup\"\n gws-axi calendar search --query \"budget\" --from 2025-01-01\n gws-axi calendar search --query \"chris\" --include-shared\n gws-axi calendar search --query \"chris\" --calendars primary,team@jarv.us\nscope:\n By default searches ONLY your primary calendar (`primary: true`).\n Google Workspace delegation gives full-access teammate calendars the\n `accessRole: owner` role, which makes \"owned-by-you\" an unreliable\n heuristic \u2014 so we restrict to primary. Use --include-shared to fold\n in teammate and read-only calendars, or --calendars <ids> for a\n precise set.\ndedupe:\n Shared events (one event visible on multiple of your calendars) are\n collapsed to one row by default \u2014 `calendar` shows the first\n calendar seen, seen_on_count reports the total. Pass --fields seen_on\n for the full list. Use --no-dedupe to get per-calendar rows.\n Use `calendar events` (single calendar, narrower range) when you\n already know which calendar to query.\ndefault columns:\n calendar, id, summary (truncated 80), start, end, my_response,\n seen_on_count (only shown when > 1)\n";
|
|
2
|
+
export declare function calendarSearchCommand(account: string, args: string[]): Promise<string>;
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
import { AxiError } from "axi-sdk-js";
|
|
2
|
+
import { calendarClient, translateGoogleError } from "../../google/client.js";
|
|
3
|
+
import { field, mapEnum, renderListResponse, truncated, } from "../../output/index.js";
|
|
4
|
+
import { parseDateishFlag } from "./dateish.js";
|
|
5
|
+
export const SEARCH_HELP = `usage: gws-axi calendar search --query <text> [flags]
|
|
6
|
+
flags[9]:
|
|
7
|
+
--query <text> REQUIRED — full-text search across summary/description/location/attendees
|
|
8
|
+
--from <iso> Earliest event start (default: 30 days ago)
|
|
9
|
+
--to <iso> Latest event start (default: 1 year from now)
|
|
10
|
+
--calendars <ids> Comma-separated calendar IDs (overrides scope default)
|
|
11
|
+
--include-shared Also search non-primary calendars: teammate
|
|
12
|
+
calendars delegated to you, read-only subscriptions,
|
|
13
|
+
anything in calendarList that isn't your primary.
|
|
14
|
+
Default is primary-only.
|
|
15
|
+
--limit <n> Max events PER calendar (default: 50, max: 2500)
|
|
16
|
+
--fields <list> Extra columns: status, organizer, location, attendees, seen_on
|
|
17
|
+
--no-dedupe Keep per-calendar duplicates; one row per (calendar, event) pair
|
|
18
|
+
--account <email> Account override when 2+ are configured
|
|
19
|
+
examples:
|
|
20
|
+
gws-axi calendar search --query "standup"
|
|
21
|
+
gws-axi calendar search --query "budget" --from 2025-01-01
|
|
22
|
+
gws-axi calendar search --query "chris" --include-shared
|
|
23
|
+
gws-axi calendar search --query "chris" --calendars primary,team@jarv.us
|
|
24
|
+
scope:
|
|
25
|
+
By default searches ONLY your primary calendar (\`primary: true\`).
|
|
26
|
+
Google Workspace delegation gives full-access teammate calendars the
|
|
27
|
+
\`accessRole: owner\` role, which makes "owned-by-you" an unreliable
|
|
28
|
+
heuristic — so we restrict to primary. Use --include-shared to fold
|
|
29
|
+
in teammate and read-only calendars, or --calendars <ids> for a
|
|
30
|
+
precise set.
|
|
31
|
+
dedupe:
|
|
32
|
+
Shared events (one event visible on multiple of your calendars) are
|
|
33
|
+
collapsed to one row by default — \`calendar\` shows the first
|
|
34
|
+
calendar seen, seen_on_count reports the total. Pass --fields seen_on
|
|
35
|
+
for the full list. Use --no-dedupe to get per-calendar rows.
|
|
36
|
+
Use \`calendar events\` (single calendar, narrower range) when you
|
|
37
|
+
already know which calendar to query.
|
|
38
|
+
default columns:
|
|
39
|
+
calendar, id, summary (truncated 80), start, end, my_response,
|
|
40
|
+
seen_on_count (only shown when > 1)
|
|
41
|
+
`;
|
|
42
|
+
function parseFlags(args) {
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
const flags = {
|
|
45
|
+
query: undefined,
|
|
46
|
+
from: new Date(now - 30 * 24 * 3600 * 1000).toISOString(),
|
|
47
|
+
to: new Date(now + 365 * 24 * 3600 * 1000).toISOString(),
|
|
48
|
+
calendarFilter: undefined,
|
|
49
|
+
includeShared: false,
|
|
50
|
+
limit: 50,
|
|
51
|
+
extraFields: [],
|
|
52
|
+
dedupe: true,
|
|
53
|
+
};
|
|
54
|
+
for (let i = 0; i < args.length; i++) {
|
|
55
|
+
const arg = args[i];
|
|
56
|
+
const next = args[i + 1];
|
|
57
|
+
switch (arg) {
|
|
58
|
+
case "--query":
|
|
59
|
+
flags.query = next;
|
|
60
|
+
i++;
|
|
61
|
+
break;
|
|
62
|
+
case "--from":
|
|
63
|
+
flags.from = parseDateishFlag(next);
|
|
64
|
+
i++;
|
|
65
|
+
break;
|
|
66
|
+
case "--to":
|
|
67
|
+
flags.to = parseDateishFlag(next);
|
|
68
|
+
i++;
|
|
69
|
+
break;
|
|
70
|
+
case "--calendars":
|
|
71
|
+
flags.calendarFilter = next.split(",").map((s) => s.trim()).filter(Boolean);
|
|
72
|
+
i++;
|
|
73
|
+
break;
|
|
74
|
+
case "--limit":
|
|
75
|
+
flags.limit = Math.min(2500, Math.max(1, parseInt(next, 10) || 50));
|
|
76
|
+
i++;
|
|
77
|
+
break;
|
|
78
|
+
case "--fields":
|
|
79
|
+
flags.extraFields = next.split(",").map((s) => s.trim()).filter(Boolean);
|
|
80
|
+
i++;
|
|
81
|
+
break;
|
|
82
|
+
case "--no-dedupe":
|
|
83
|
+
flags.dedupe = false;
|
|
84
|
+
break;
|
|
85
|
+
case "--include-shared":
|
|
86
|
+
flags.includeShared = true;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return flags;
|
|
91
|
+
}
|
|
92
|
+
function baseSchema() {
|
|
93
|
+
return [
|
|
94
|
+
field("_calendar"),
|
|
95
|
+
field("id"),
|
|
96
|
+
truncated("summary", 80),
|
|
97
|
+
{
|
|
98
|
+
name: "start",
|
|
99
|
+
extract: (item) => {
|
|
100
|
+
const s = item.start;
|
|
101
|
+
return s?.dateTime ?? s?.date ?? "";
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: "end",
|
|
106
|
+
extract: (item) => {
|
|
107
|
+
const e = item.end;
|
|
108
|
+
return e?.dateTime ?? e?.date ?? "";
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "my_response",
|
|
113
|
+
extract: (item) => {
|
|
114
|
+
const attendees = item.attendees;
|
|
115
|
+
if (!attendees?.length)
|
|
116
|
+
return "";
|
|
117
|
+
const me = attendees.find((a) => a.self);
|
|
118
|
+
return me?.responseStatus ?? "";
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
function schemaWithExtras(extras, showSeenCount) {
|
|
124
|
+
const base = baseSchema();
|
|
125
|
+
// Rename "_calendar" column to "calendar" for display — leading underscore
|
|
126
|
+
// was just to avoid clashing with any Google-API field named "calendar"
|
|
127
|
+
base[0] = { name: "calendar", extract: (item) => item._calendar };
|
|
128
|
+
if (showSeenCount) {
|
|
129
|
+
// Insert seen_on_count right after `calendar` so related fields cluster
|
|
130
|
+
base.splice(1, 0, {
|
|
131
|
+
name: "seen_on_count",
|
|
132
|
+
extract: (item) => {
|
|
133
|
+
const s = item._seen_on;
|
|
134
|
+
return s?.length ?? 1;
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
for (const extra of extras) {
|
|
139
|
+
switch (extra) {
|
|
140
|
+
case "status":
|
|
141
|
+
base.push(mapEnum("status", { confirmed: "ok", tentative: "tentative", cancelled: "cancelled" }, "unknown"));
|
|
142
|
+
break;
|
|
143
|
+
case "organizer":
|
|
144
|
+
base.push({
|
|
145
|
+
name: "organizer",
|
|
146
|
+
extract: (item) => {
|
|
147
|
+
const o = item.organizer;
|
|
148
|
+
return o?.email ?? "";
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
break;
|
|
152
|
+
case "location":
|
|
153
|
+
base.push(truncated("location", 40));
|
|
154
|
+
break;
|
|
155
|
+
case "attendees":
|
|
156
|
+
base.push({
|
|
157
|
+
name: "attendees",
|
|
158
|
+
extract: (item) => {
|
|
159
|
+
const a = item.attendees;
|
|
160
|
+
return a?.length ?? 0;
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
break;
|
|
164
|
+
case "seen_on":
|
|
165
|
+
base.push({
|
|
166
|
+
name: "seen_on",
|
|
167
|
+
extract: (item) => {
|
|
168
|
+
const s = item._seen_on;
|
|
169
|
+
return s?.join(",") ?? item._calendar ?? "";
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return base;
|
|
176
|
+
}
|
|
177
|
+
export async function calendarSearchCommand(account, args) {
|
|
178
|
+
const flags = parseFlags(args);
|
|
179
|
+
if (!flags.query) {
|
|
180
|
+
throw new AxiError("--query is required", "VALIDATION_ERROR", [
|
|
181
|
+
"Example: gws-axi calendar search --query 'standup'",
|
|
182
|
+
"For a time-range listing without search, use `gws-axi calendar events`",
|
|
183
|
+
]);
|
|
184
|
+
}
|
|
185
|
+
const api = await calendarClient(account);
|
|
186
|
+
// Resolve which calendars to query. If user specified --calendars, use
|
|
187
|
+
// those as-is. Otherwise discover via calendarList.list and filter.
|
|
188
|
+
//
|
|
189
|
+
// Default scope is PRIMARY ONLY (`primary: true`). In Google Workspace,
|
|
190
|
+
// calendars a user has been granted full-access delegation for show up
|
|
191
|
+
// with `accessRole: "owner"` — so filtering by owner would wrongly
|
|
192
|
+
// include the whole team. --include-shared folds in everything that
|
|
193
|
+
// isn't primary: teammate calendars (delegated) AND read-only
|
|
194
|
+
// subscriptions. We treat them the same in one bucket to keep the UX
|
|
195
|
+
// simple; users who want finer control can pass --calendars <ids>.
|
|
196
|
+
let calendarIds;
|
|
197
|
+
let skippedSharedCount = 0;
|
|
198
|
+
if (flags.calendarFilter) {
|
|
199
|
+
calendarIds = flags.calendarFilter;
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
try {
|
|
203
|
+
const listRes = await api.calendarList.list({
|
|
204
|
+
maxResults: 250,
|
|
205
|
+
showHidden: false,
|
|
206
|
+
});
|
|
207
|
+
const all = listRes.data.items ?? [];
|
|
208
|
+
const primaryOnly = all.filter((c) => c.primary === true);
|
|
209
|
+
const nonPrimary = all.filter((c) => c.primary !== true);
|
|
210
|
+
const selected = flags.includeShared ? [...primaryOnly, ...nonPrimary] : primaryOnly;
|
|
211
|
+
if (!flags.includeShared)
|
|
212
|
+
skippedSharedCount = nonPrimary.length;
|
|
213
|
+
calendarIds = selected
|
|
214
|
+
.map((c) => c.id)
|
|
215
|
+
.filter((id) => typeof id === "string");
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
throw translateGoogleError(err, {
|
|
219
|
+
account,
|
|
220
|
+
operation: "calendar.calendarList.list",
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (calendarIds.length === 0) {
|
|
225
|
+
throw new AxiError("No calendars to search", "NO_CALENDARS", [`Run \`gws-axi calendar calendars --account ${account}\` to diagnose`]);
|
|
226
|
+
}
|
|
227
|
+
// Parallel events.list per calendar — silently skip calendars that 404 or
|
|
228
|
+
// 403 (user lost access, deleted calendar, etc.) rather than abort.
|
|
229
|
+
const results = await Promise.all(calendarIds.map(async (calendarId) => {
|
|
230
|
+
try {
|
|
231
|
+
const res = await api.events.list({
|
|
232
|
+
calendarId,
|
|
233
|
+
timeMin: flags.from,
|
|
234
|
+
timeMax: flags.to,
|
|
235
|
+
maxResults: flags.limit,
|
|
236
|
+
singleEvents: true,
|
|
237
|
+
orderBy: "startTime",
|
|
238
|
+
q: flags.query,
|
|
239
|
+
});
|
|
240
|
+
return { calendarId, items: res.data.items ?? [] };
|
|
241
|
+
}
|
|
242
|
+
catch (err) {
|
|
243
|
+
return {
|
|
244
|
+
calendarId,
|
|
245
|
+
items: [],
|
|
246
|
+
error: err instanceof Error ? err.message.slice(0, 120) : String(err).slice(0, 120),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}));
|
|
250
|
+
// Tag each event with its source calendar, flatten, and sort by start time
|
|
251
|
+
const flat = results.flatMap((r) => r.items.map((e) => ({ ...e, _calendar: r.calendarId })));
|
|
252
|
+
// Optional dedupe by event.id: shared team events appear once per
|
|
253
|
+
// calendar they're visible on. Default-on since the noise is
|
|
254
|
+
// significant (one event on 15 calendars ⇒ 15 rows in raw merge).
|
|
255
|
+
let merged;
|
|
256
|
+
let duplicatesCollapsed = 0;
|
|
257
|
+
let anyDuplicates = false;
|
|
258
|
+
if (flags.dedupe) {
|
|
259
|
+
const byId = new Map();
|
|
260
|
+
const noId = [];
|
|
261
|
+
for (const item of flat) {
|
|
262
|
+
const id = item.id;
|
|
263
|
+
if (!id) {
|
|
264
|
+
noId.push({ ...item, _seen_on: [item._calendar] });
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
const existing = byId.get(id);
|
|
268
|
+
if (existing) {
|
|
269
|
+
existing._seen_on.push(item._calendar);
|
|
270
|
+
duplicatesCollapsed++;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
byId.set(id, { ...item, _seen_on: [item._calendar] });
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
merged = [...noId, ...Array.from(byId.values())];
|
|
277
|
+
anyDuplicates = duplicatesCollapsed > 0;
|
|
278
|
+
}
|
|
279
|
+
else {
|
|
280
|
+
merged = flat.map((item) => ({ ...item, _seen_on: [item._calendar] }));
|
|
281
|
+
}
|
|
282
|
+
merged.sort((a, b) => {
|
|
283
|
+
const startA = a.start?.dateTime ??
|
|
284
|
+
a.start?.date ??
|
|
285
|
+
"";
|
|
286
|
+
const startB = b.start?.dateTime ??
|
|
287
|
+
b.start?.date ??
|
|
288
|
+
"";
|
|
289
|
+
return String(startA).localeCompare(String(startB));
|
|
290
|
+
});
|
|
291
|
+
const erroredCalendars = results.filter((r) => r.error);
|
|
292
|
+
const succeededCount = results.length - erroredCalendars.length;
|
|
293
|
+
const anyCalendarHitLimit = results.some((r) => r.items.length >= flags.limit);
|
|
294
|
+
const header = {
|
|
295
|
+
account,
|
|
296
|
+
query: flags.query,
|
|
297
|
+
};
|
|
298
|
+
const summary = {
|
|
299
|
+
count: merged.length,
|
|
300
|
+
calendars_searched: succeededCount,
|
|
301
|
+
range: `${flags.from} → ${flags.to}`,
|
|
302
|
+
};
|
|
303
|
+
if (flags.dedupe) {
|
|
304
|
+
summary.dedupe = true;
|
|
305
|
+
if (duplicatesCollapsed > 0) {
|
|
306
|
+
summary.duplicates_collapsed = duplicatesCollapsed;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (erroredCalendars.length > 0) {
|
|
310
|
+
summary.calendars_with_errors = erroredCalendars.length;
|
|
311
|
+
}
|
|
312
|
+
if (anyCalendarHitLimit) {
|
|
313
|
+
summary.more_available = true;
|
|
314
|
+
summary.per_calendar_limit = flags.limit;
|
|
315
|
+
}
|
|
316
|
+
if (skippedSharedCount > 0 && !flags.includeShared) {
|
|
317
|
+
summary.shared_calendars_skipped = skippedSharedCount;
|
|
318
|
+
}
|
|
319
|
+
const schema = schemaWithExtras(flags.extraFields, anyDuplicates);
|
|
320
|
+
const suggestions = [];
|
|
321
|
+
if (merged.length > 0) {
|
|
322
|
+
suggestions.push("Run `gws-axi calendar get <id> --calendar <calendar>` for full event details");
|
|
323
|
+
if (anyDuplicates && !flags.extraFields.includes("seen_on")) {
|
|
324
|
+
suggestions.push("Add `--fields seen_on` to see the full calendar list for shared events");
|
|
325
|
+
}
|
|
326
|
+
if (flags.extraFields.length === 0) {
|
|
327
|
+
suggestions.push("Add `--fields attendees,location,organizer` to enrich the output");
|
|
328
|
+
}
|
|
329
|
+
if (anyCalendarHitLimit) {
|
|
330
|
+
suggestions.push(`At least one calendar returned the full --limit (${flags.limit}) — raise --limit or narrow --from/--to to avoid truncation`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
suggestions.push(`No matches — try a broader query, widen --from/--to, or check different calendars`);
|
|
335
|
+
}
|
|
336
|
+
if (erroredCalendars.length > 0) {
|
|
337
|
+
suggestions.push(`${erroredCalendars.length} calendar(s) had errors — narrow with --calendars to isolate`);
|
|
338
|
+
}
|
|
339
|
+
if (skippedSharedCount > 0 && !flags.includeShared) {
|
|
340
|
+
suggestions.push(`Skipped ${skippedSharedCount} shared/subscribed calendar(s) — add --include-shared to search them too`);
|
|
341
|
+
}
|
|
342
|
+
return renderListResponse({
|
|
343
|
+
header,
|
|
344
|
+
summary,
|
|
345
|
+
name: "events",
|
|
346
|
+
items: merged,
|
|
347
|
+
schema,
|
|
348
|
+
suggestions,
|
|
349
|
+
emptyMessage: `no events matched "${flags.query}" across ${succeededCount} calendar(s)`,
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../../../src/commands/calendar/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,13 +2,15 @@ import { AxiError } from "axi-sdk-js";
|
|
|
2
2
|
import { resolveAccount } from "../google/account.js";
|
|
3
3
|
import { calendarCalendarsCommand, CALENDARS_HELP } from "./calendar/calendars.js";
|
|
4
4
|
import { calendarEventsCommand, EVENTS_HELP } from "./calendar/events.js";
|
|
5
|
+
import { calendarFreebusyCommand, FREEBUSY_HELP } from "./calendar/freebusy.js";
|
|
5
6
|
import { calendarGetCommand, GET_HELP } from "./calendar/get.js";
|
|
7
|
+
import { calendarSearchCommand, SEARCH_HELP } from "./calendar/search.js";
|
|
6
8
|
const SUBCOMMANDS = [
|
|
7
9
|
{ name: "events", mutation: false, help: EVENTS_HELP, handler: calendarEventsCommand },
|
|
8
10
|
{ name: "get", mutation: false, help: GET_HELP, handler: calendarGetCommand },
|
|
9
11
|
{ name: "calendars", mutation: false, help: CALENDARS_HELP, handler: calendarCalendarsCommand },
|
|
10
|
-
{ name: "search", mutation: false, help:
|
|
11
|
-
{ name: "freebusy", mutation: false, help:
|
|
12
|
+
{ name: "search", mutation: false, help: SEARCH_HELP, handler: calendarSearchCommand },
|
|
13
|
+
{ name: "freebusy", mutation: false, help: FREEBUSY_HELP, handler: calendarFreebusyCommand },
|
|
12
14
|
{ name: "create", mutation: true, help: "not yet implemented" },
|
|
13
15
|
{ name: "update", mutation: true, help: "not yet implemented" },
|
|
14
16
|
{ name: "delete", mutation: true, help: "not yet implemented" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../src/commands/calendar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"calendar.js","sourceRoot":"","sources":["../../../src/commands/calendar.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gws-axi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "AXI-compliant Google Workspace CLI — token-efficient TOON output, agent-guided auth setup, unified interface for Gmail, Calendar, Docs, Drive, Slides",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|