gws-axi 0.1.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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +91 -0
  3. package/dist/bin/gws-axi.d.ts +2 -0
  4. package/dist/bin/gws-axi.js +4 -0
  5. package/dist/bin/gws-axi.js.map +1 -0
  6. package/dist/src/auth/gcloud.d.ts +21 -0
  7. package/dist/src/auth/gcloud.js +134 -0
  8. package/dist/src/auth/gcloud.js.map +1 -0
  9. package/dist/src/auth/loopback.d.ts +50 -0
  10. package/dist/src/auth/loopback.js +420 -0
  11. package/dist/src/auth/loopback.js.map +1 -0
  12. package/dist/src/auth/pending.d.ts +15 -0
  13. package/dist/src/auth/pending.js +35 -0
  14. package/dist/src/auth/pending.js.map +1 -0
  15. package/dist/src/auth/scopes.d.ts +13 -0
  16. package/dist/src/auth/scopes.js +29 -0
  17. package/dist/src/auth/scopes.js.map +1 -0
  18. package/dist/src/auth/setup-html.d.ts +13 -0
  19. package/dist/src/auth/setup-html.js +245 -0
  20. package/dist/src/auth/setup-html.js.map +1 -0
  21. package/dist/src/auth/state.d.ts +4 -0
  22. package/dist/src/auth/state.js +41 -0
  23. package/dist/src/auth/state.js.map +1 -0
  24. package/dist/src/auth/steps.d.ts +30 -0
  25. package/dist/src/auth/steps.js +306 -0
  26. package/dist/src/auth/steps.js.map +1 -0
  27. package/dist/src/cli.d.ts +2 -0
  28. package/dist/src/cli.js +72 -0
  29. package/dist/src/cli.js.map +1 -0
  30. package/dist/src/commands/auth.d.ts +2 -0
  31. package/dist/src/commands/auth.js +453 -0
  32. package/dist/src/commands/auth.js.map +1 -0
  33. package/dist/src/commands/calendar/calendars.d.ts +2 -0
  34. package/dist/src/commands/calendar/calendars.js +98 -0
  35. package/dist/src/commands/calendar/calendars.js.map +1 -0
  36. package/dist/src/commands/calendar/events.d.ts +2 -0
  37. package/dist/src/commands/calendar/events.js +261 -0
  38. package/dist/src/commands/calendar/events.js.map +1 -0
  39. package/dist/src/commands/calendar/get.d.ts +2 -0
  40. package/dist/src/commands/calendar/get.js +176 -0
  41. package/dist/src/commands/calendar/get.js.map +1 -0
  42. package/dist/src/commands/calendar.d.ts +2 -0
  43. package/dist/src/commands/calendar.js +76 -0
  44. package/dist/src/commands/calendar.js.map +1 -0
  45. package/dist/src/commands/docs.d.ts +2 -0
  46. package/dist/src/commands/docs.js +19 -0
  47. package/dist/src/commands/docs.js.map +1 -0
  48. package/dist/src/commands/doctor.d.ts +2 -0
  49. package/dist/src/commands/doctor.js +213 -0
  50. package/dist/src/commands/doctor.js.map +1 -0
  51. package/dist/src/commands/drive.d.ts +2 -0
  52. package/dist/src/commands/drive.js +17 -0
  53. package/dist/src/commands/drive.js.map +1 -0
  54. package/dist/src/commands/gmail.d.ts +2 -0
  55. package/dist/src/commands/gmail.js +20 -0
  56. package/dist/src/commands/gmail.js.map +1 -0
  57. package/dist/src/commands/home.d.ts +1 -0
  58. package/dist/src/commands/home.js +42 -0
  59. package/dist/src/commands/home.js.map +1 -0
  60. package/dist/src/commands/service-stub.d.ts +8 -0
  61. package/dist/src/commands/service-stub.js +67 -0
  62. package/dist/src/commands/service-stub.js.map +1 -0
  63. package/dist/src/commands/slides.d.ts +2 -0
  64. package/dist/src/commands/slides.js +11 -0
  65. package/dist/src/commands/slides.js.map +1 -0
  66. package/dist/src/config.d.ts +46 -0
  67. package/dist/src/config.js +155 -0
  68. package/dist/src/config.js.map +1 -0
  69. package/dist/src/google/account.d.ts +12 -0
  70. package/dist/src/google/account.js +65 -0
  71. package/dist/src/google/account.js.map +1 -0
  72. package/dist/src/google/client.d.ts +29 -0
  73. package/dist/src/google/client.js +106 -0
  74. package/dist/src/google/client.js.map +1 -0
  75. package/dist/src/google/probe.d.ts +15 -0
  76. package/dist/src/google/probe.js +200 -0
  77. package/dist/src/google/probe.js.map +1 -0
  78. package/dist/src/google/tokens.d.ts +22 -0
  79. package/dist/src/google/tokens.js +91 -0
  80. package/dist/src/google/tokens.js.map +1 -0
  81. package/dist/src/output/index.d.ts +2 -0
  82. package/dist/src/output/index.js +3 -0
  83. package/dist/src/output/index.js.map +1 -0
  84. package/dist/src/output/render.d.ts +40 -0
  85. package/dist/src/output/render.js +65 -0
  86. package/dist/src/output/render.js.map +1 -0
  87. package/dist/src/output/schema.d.ts +32 -0
  88. package/dist/src/output/schema.js +69 -0
  89. package/dist/src/output/schema.js.map +1 -0
  90. package/package.json +61 -0
@@ -0,0 +1,98 @@
1
+ import { calendarClient, translateGoogleError } from "../../google/client.js";
2
+ import { field, mapEnum, renderListResponse, truncated, } from "../../output/index.js";
3
+ export const CALENDARS_HELP = `usage: gws-axi calendar calendars [flags]
4
+ flags[2]:
5
+ --account <email> Account override when 2+ are configured
6
+ --fields <list> Extra columns: timezone, description, colorId
7
+ examples:
8
+ gws-axi calendar calendars
9
+ gws-axi calendar calendars --account chris@personal.com
10
+ gws-axi calendar calendars --fields timezone
11
+ default columns:
12
+ id Calendar ID (use with \`calendar events --calendar <id>\`)
13
+ summary Human-readable name
14
+ access reader | writer | owner | free_busy
15
+ primary ✓ for the account's primary calendar
16
+ notes:
17
+ Lists ALL calendars this account can access — your own plus ones
18
+ you're subscribed to. Shared / team calendars appear here too.
19
+ `;
20
+ function parseFlags(args) {
21
+ const flags = { extraFields: [] };
22
+ for (let i = 0; i < args.length; i++) {
23
+ const arg = args[i];
24
+ const next = args[i + 1];
25
+ if (arg === "--fields" && next) {
26
+ flags.extraFields = next.split(",").map((s) => s.trim()).filter(Boolean);
27
+ i++;
28
+ }
29
+ }
30
+ return flags;
31
+ }
32
+ export async function calendarCalendarsCommand(account, args) {
33
+ const flags = parseFlags(args);
34
+ const api = await calendarClient(account);
35
+ let items;
36
+ try {
37
+ const res = await api.calendarList.list({
38
+ maxResults: 250,
39
+ showHidden: false,
40
+ });
41
+ items = (res.data.items ?? []);
42
+ }
43
+ catch (err) {
44
+ throw translateGoogleError(err, {
45
+ account,
46
+ operation: "calendar.calendarList.list",
47
+ });
48
+ }
49
+ const schema = [
50
+ field("id"),
51
+ truncated("summary", 60),
52
+ mapEnum("accessRole", {
53
+ owner: "owner",
54
+ writer: "writer",
55
+ reader: "reader",
56
+ freeBusyReader: "free_busy",
57
+ }, "unknown", "access"),
58
+ {
59
+ name: "primary",
60
+ extract: (item) => item.primary === true ? "✓" : "",
61
+ },
62
+ ];
63
+ for (const extra of flags.extraFields) {
64
+ switch (extra) {
65
+ case "timezone":
66
+ schema.push(field("timeZone"));
67
+ break;
68
+ case "description":
69
+ schema.push(truncated("description", 80));
70
+ break;
71
+ case "colorId":
72
+ schema.push(field("colorId"));
73
+ break;
74
+ // silently skip unknown extras
75
+ }
76
+ }
77
+ const owned = items.filter((c) => c.accessRole === "owner" || c.primary === true).length;
78
+ const suggestions = [];
79
+ if (items.length > 0) {
80
+ suggestions.push(`Query a specific calendar: \`gws-axi calendar events --calendar <id>\``);
81
+ if (flags.extraFields.length === 0) {
82
+ suggestions.push(`Add \`--fields timezone,description\` for more details`);
83
+ }
84
+ }
85
+ return renderListResponse({
86
+ header: { account },
87
+ summary: {
88
+ count: items.length,
89
+ owned,
90
+ },
91
+ name: "calendars",
92
+ items,
93
+ schema,
94
+ suggestions,
95
+ emptyMessage: "no calendars accessible to this account",
96
+ });
97
+ }
98
+ //# sourceMappingURL=calendars.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calendars.js","sourceRoot":"","sources":["../../../../src/commands/calendar/calendars.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const EVENTS_HELP = "usage: gws-axi calendar events [flags]\nflags[8]:\n --calendar <id> Calendar to query (default: \"primary\")\n --from <iso> Earliest event start (default: now)\n --to <iso> Latest event start (default: 7 days from now)\n --limit <n> Max events to return (default: 25, max: 2500)\n --query <text> Full-text search across summary/description/location/attendees\n --single-events Expand recurring events into individual instances (default: true)\n --fields <list> Extra columns: status, organizer, location, attendees, description, htmlLink, hangoutLink\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi calendar events\n gws-axi calendar events --from 2026-04-20T00:00 --to 2026-04-21T00:00\n gws-axi calendar events --calendar team@jarv.us --limit 50\n gws-axi calendar events --query standup\n gws-axi calendar events --fields status,attendees,location\ntime formats:\n Timed events: ISO 8601 with offset \u2014 2026-04-20T14:00:00-04:00\n Local time: 2026-04-20T14:00 (interpreted as local tz)\n Date-only: 2026-04-20 (midnight local)\noutput note:\n The start/end columns use datetime (with offset) for timed events\n and date-only strings for all-day events. Agents parsing these\n columns must handle both formats.\ndefault columns:\n id, summary, start, end, my_response (your responseStatus if you're\n an attendee; blank for self-organized events with no attendee list).\n status column suppressed by default (most events are \"confirmed\" \u2014\n add --fields status to see cancelled/tentative).\n";
2
+ export declare function calendarEventsCommand(account: string, args: string[]): Promise<string>;
@@ -0,0 +1,261 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { calendarClient, translateGoogleError } from "../../google/client.js";
3
+ import { field, mapEnum, pluck, renderListResponse, truncated, } from "../../output/index.js";
4
+ export const EVENTS_HELP = `usage: gws-axi calendar events [flags]
5
+ flags[8]:
6
+ --calendar <id> Calendar to query (default: "primary")
7
+ --from <iso> Earliest event start (default: now)
8
+ --to <iso> Latest event start (default: 7 days from now)
9
+ --limit <n> Max events to return (default: 25, max: 2500)
10
+ --query <text> Full-text search across summary/description/location/attendees
11
+ --single-events Expand recurring events into individual instances (default: true)
12
+ --fields <list> Extra columns: status, organizer, location, attendees, description, htmlLink, hangoutLink
13
+ --account <email> Account override when 2+ are configured
14
+ examples:
15
+ gws-axi calendar events
16
+ gws-axi calendar events --from 2026-04-20T00:00 --to 2026-04-21T00:00
17
+ gws-axi calendar events --calendar team@jarv.us --limit 50
18
+ gws-axi calendar events --query standup
19
+ gws-axi calendar events --fields status,attendees,location
20
+ time formats:
21
+ Timed events: ISO 8601 with offset — 2026-04-20T14:00:00-04:00
22
+ Local time: 2026-04-20T14:00 (interpreted as local tz)
23
+ Date-only: 2026-04-20 (midnight local)
24
+ output note:
25
+ The start/end columns use datetime (with offset) for timed events
26
+ and date-only strings for all-day events. Agents parsing these
27
+ columns must handle both formats.
28
+ default columns:
29
+ id, summary, start, end, my_response (your responseStatus if you're
30
+ an attendee; blank for self-organized events with no attendee list).
31
+ status column suppressed by default (most events are "confirmed" —
32
+ add --fields status to see cancelled/tentative).
33
+ `;
34
+ function parseEventsFlags(args) {
35
+ const flags = {
36
+ calendar: "primary",
37
+ from: new Date().toISOString(),
38
+ to: new Date(Date.now() + 7 * 24 * 3600 * 1000).toISOString(),
39
+ limit: 25,
40
+ query: undefined,
41
+ singleEvents: true,
42
+ extraFields: [],
43
+ };
44
+ for (let i = 0; i < args.length; i++) {
45
+ const arg = args[i];
46
+ const next = args[i + 1];
47
+ switch (arg) {
48
+ case "--calendar":
49
+ flags.calendar = next;
50
+ i++;
51
+ break;
52
+ case "--from":
53
+ flags.from = parseDateish(next);
54
+ i++;
55
+ break;
56
+ case "--to":
57
+ flags.to = parseDateish(next);
58
+ i++;
59
+ break;
60
+ case "--limit":
61
+ flags.limit = Math.min(2500, Math.max(1, parseInt(next, 10) || 25));
62
+ i++;
63
+ break;
64
+ case "--query":
65
+ flags.query = next;
66
+ i++;
67
+ break;
68
+ case "--single-events":
69
+ flags.singleEvents = next === "false" ? false : true;
70
+ if (next === "false" || next === "true")
71
+ i++;
72
+ break;
73
+ case "--fields":
74
+ flags.extraFields = next.split(",").map((s) => s.trim()).filter(Boolean);
75
+ i++;
76
+ break;
77
+ }
78
+ }
79
+ return flags;
80
+ }
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
+ function baseSchema() {
99
+ return [
100
+ field("id"),
101
+ truncated("summary", 80),
102
+ // start.dateTime for timed events, start.date for all-day — pluck either
103
+ {
104
+ name: "start",
105
+ extract: (item) => {
106
+ const s = item.start;
107
+ return s?.dateTime ?? s?.date ?? "";
108
+ },
109
+ },
110
+ {
111
+ name: "end",
112
+ extract: (item) => {
113
+ const e = item.end;
114
+ return e?.dateTime ?? e?.date ?? "";
115
+ },
116
+ },
117
+ // my_response: responseStatus of the attendee flagged `self: true`.
118
+ // Blank when the user is the sole organizer or not in the attendee
119
+ // list. Most common use: agents filtering for "am I actually going?"
120
+ {
121
+ name: "my_response",
122
+ extract: (item) => {
123
+ const attendees = item.attendees;
124
+ if (!attendees?.length)
125
+ return "";
126
+ const me = attendees.find((a) => a.self);
127
+ return me?.responseStatus ?? "";
128
+ },
129
+ },
130
+ ];
131
+ }
132
+ function schemaWithExtras(extras) {
133
+ const base = baseSchema();
134
+ for (const extra of extras) {
135
+ switch (extra) {
136
+ case "status":
137
+ base.push(mapEnum("status", { confirmed: "ok", tentative: "tentative", cancelled: "cancelled" }, "unknown"));
138
+ break;
139
+ case "organizer":
140
+ base.push(pluck("organizer", "email", "organizer"));
141
+ break;
142
+ case "location":
143
+ base.push(truncated("location", 40));
144
+ break;
145
+ case "attendees":
146
+ base.push({
147
+ name: "attendees",
148
+ extract: (item) => {
149
+ const a = item.attendees;
150
+ if (!a?.length)
151
+ return "";
152
+ const counts = a.reduce((acc, x) => {
153
+ const key = x.responseStatus ?? "other";
154
+ acc[key] = (acc[key] ?? 0) + 1;
155
+ return acc;
156
+ }, {});
157
+ return `${a.length} (${Object.entries(counts).map(([k, v]) => `${v} ${k}`).join(", ")})`;
158
+ },
159
+ });
160
+ break;
161
+ case "htmlLink":
162
+ base.push(field("htmlLink"));
163
+ break;
164
+ case "description":
165
+ base.push(truncated("description", 100));
166
+ break;
167
+ case "hangoutLink":
168
+ base.push(field("hangoutLink"));
169
+ break;
170
+ default:
171
+ // Unknown field — skip silently rather than error. Keeps --fields
172
+ // lenient (user doesn't need to know exact field names).
173
+ break;
174
+ }
175
+ }
176
+ return base;
177
+ }
178
+ export async function calendarEventsCommand(account, args) {
179
+ const flags = parseEventsFlags(args);
180
+ const api = await calendarClient(account);
181
+ const requestParams = {
182
+ calendarId: flags.calendar,
183
+ timeMin: flags.from,
184
+ timeMax: flags.to,
185
+ maxResults: flags.limit,
186
+ singleEvents: flags.singleEvents,
187
+ orderBy: flags.singleEvents ? "startTime" : undefined,
188
+ q: flags.query,
189
+ };
190
+ let data;
191
+ try {
192
+ const res = await api.events.list(requestParams);
193
+ data = res.data;
194
+ }
195
+ catch (err) {
196
+ const translated = translateGoogleError(err, {
197
+ account,
198
+ operation: "calendar.events.list",
199
+ });
200
+ // Enrich NOT_FOUND with calendar-specific recovery hints; the generic
201
+ // translator doesn't know the request was scoped to a calendarId.
202
+ if (translated.code === "NOT_FOUND") {
203
+ throw new AxiError(`Calendar '${flags.calendar}' not found${flags.calendar === "primary" ? "" : ` (or ${account} doesn't have access)`}`, "CALENDAR_NOT_FOUND", [
204
+ `Run \`gws-axi calendar calendars --account ${account}\` to list accessible calendars`,
205
+ `Use --calendar primary to query ${account}'s default calendar`,
206
+ ]);
207
+ }
208
+ throw translated;
209
+ }
210
+ const items = (data.items ?? []);
211
+ const schema = schemaWithExtras(flags.extraFields);
212
+ const header = { account };
213
+ if (flags.calendar !== "primary") {
214
+ header.calendar = flags.calendar;
215
+ }
216
+ const summary = {
217
+ count: items.length,
218
+ range: `${flags.from} → ${flags.to}`,
219
+ };
220
+ if (flags.query) {
221
+ summary.query = flags.query;
222
+ }
223
+ if (data.nextPageToken) {
224
+ summary.more_available = true;
225
+ }
226
+ const suggestions = [];
227
+ if (items.length > 0) {
228
+ suggestions.push(`Run \`gws-axi calendar get <id>\` for full event details (id is the first column)`);
229
+ if (data.nextPageToken) {
230
+ suggestions.push(`Increase --limit or narrow --from/--to to see more events (currently capped at ${flags.limit})`);
231
+ }
232
+ if (flags.extraFields.length === 0) {
233
+ suggestions.push(`Add \`--fields attendees,location,status\` to show more columns`);
234
+ }
235
+ if (flags.calendar === "primary") {
236
+ suggestions.push(`Query a different calendar with \`--calendar <id>\` (list them with \`gws-axi calendar calendars\`)`);
237
+ }
238
+ }
239
+ else {
240
+ // Empty-result-specific hints — don't recycle the general ones above.
241
+ if (flags.query) {
242
+ suggestions.push(`Remove --query to show all events in the range, or try a broader search term`);
243
+ }
244
+ suggestions.push(`Broaden the time range with --from / --to (current: ${flags.from} → ${flags.to})`);
245
+ if (flags.calendar === "primary") {
246
+ suggestions.push(`Try a different calendar with \`--calendar <id>\` (list them with \`gws-axi calendar calendars\`)`);
247
+ }
248
+ }
249
+ return renderListResponse({
250
+ header,
251
+ summary,
252
+ name: "events",
253
+ items,
254
+ schema,
255
+ suggestions,
256
+ emptyMessage: flags.query
257
+ ? `no events matched "${flags.query}" in the given time range`
258
+ : "no events found in the given time range",
259
+ });
260
+ }
261
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
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 GET_HELP = "usage: gws-axi calendar get <event-id> [flags]\nargs[1]:\n <event-id> Event ID (from `calendar events` output)\nflags[3]:\n --calendar <id> Calendar containing the event (default: \"primary\")\n --full Don't truncate description / attendee list\n --account <email> Account override when 2+ are configured\nexamples:\n gws-axi calendar get abc_123 --calendar primary\n gws-axi calendar get abc_123 --full\noutput:\n Event metadata (summary, start/end, status, creator, organizer,\n location, hangout link, htmlLink) plus the attendee list with each\n person's response status. Description is truncated to 500 chars by\n default \u2014 use --full to see the complete body.\n";
2
+ export declare function calendarGetCommand(account: string, args: string[]): Promise<string>;
@@ -0,0 +1,176 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { calendarClient, translateGoogleError } from "../../google/client.js";
3
+ import { field, joinBlocks, renderHelp, renderList, renderObject, } from "../../output/index.js";
4
+ export const GET_HELP = `usage: gws-axi calendar get <event-id> [flags]
5
+ args[1]:
6
+ <event-id> Event ID (from \`calendar events\` output)
7
+ flags[3]:
8
+ --calendar <id> Calendar containing the event (default: "primary")
9
+ --full Don't truncate description / attendee list
10
+ --account <email> Account override when 2+ are configured
11
+ examples:
12
+ gws-axi calendar get abc_123 --calendar primary
13
+ gws-axi calendar get abc_123 --full
14
+ output:
15
+ Event metadata (summary, start/end, status, creator, organizer,
16
+ location, hangout link, htmlLink) plus the attendee list with each
17
+ person's response status. Description is truncated to 500 chars by
18
+ default — use --full to see the complete body.
19
+ `;
20
+ function parseFlags(args) {
21
+ const flags = { calendar: "primary", full: false };
22
+ let eventId;
23
+ for (let i = 0; i < args.length; i++) {
24
+ const arg = args[i];
25
+ const next = args[i + 1];
26
+ switch (arg) {
27
+ case "--calendar":
28
+ flags.calendar = next;
29
+ i++;
30
+ break;
31
+ case "--full":
32
+ flags.full = true;
33
+ break;
34
+ default:
35
+ if (!arg.startsWith("--") && eventId === undefined) {
36
+ eventId = arg;
37
+ }
38
+ }
39
+ }
40
+ if (!eventId) {
41
+ throw new AxiError("Missing event ID argument", "VALIDATION_ERROR", [
42
+ "Usage: gws-axi calendar get <event-id>",
43
+ "Get an ID from `gws-axi calendar events`",
44
+ ]);
45
+ }
46
+ return { eventId, flags };
47
+ }
48
+ function formatTime(value) {
49
+ if (!value)
50
+ return "";
51
+ if (value.dateTime) {
52
+ return value.timeZone ? `${value.dateTime} (${value.timeZone})` : value.dateTime;
53
+ }
54
+ if (value.date)
55
+ return `${value.date} (all-day)`;
56
+ return "";
57
+ }
58
+ function truncate(value, max) {
59
+ if (!value)
60
+ return { value: "", truncated: false, total: 0 };
61
+ if (value.length <= max)
62
+ return { value, truncated: false, total: value.length };
63
+ return {
64
+ value: `${value.slice(0, max - 1)}…`,
65
+ truncated: true,
66
+ total: value.length,
67
+ };
68
+ }
69
+ export async function calendarGetCommand(account, args) {
70
+ const { eventId, flags } = parseFlags(args);
71
+ const api = await calendarClient(account);
72
+ let event;
73
+ try {
74
+ const res = await api.events.get({
75
+ calendarId: flags.calendar,
76
+ eventId,
77
+ });
78
+ event = res.data;
79
+ }
80
+ catch (err) {
81
+ const translated = translateGoogleError(err, {
82
+ account,
83
+ operation: "calendar.events.get",
84
+ });
85
+ if (translated.code === "NOT_FOUND") {
86
+ throw new AxiError(`Event '${eventId}' not found in calendar '${flags.calendar}'`, "EVENT_NOT_FOUND", [
87
+ `Verify the event ID with \`gws-axi calendar events --calendar ${flags.calendar}\``,
88
+ flags.calendar === "primary"
89
+ ? "The event may be on a different calendar — try --calendar <id>"
90
+ : "Or try --calendar primary if the event is on your default calendar",
91
+ ]);
92
+ }
93
+ throw translated;
94
+ }
95
+ const blocks = [];
96
+ const header = { account };
97
+ if (flags.calendar !== "primary")
98
+ header.calendar = flags.calendar;
99
+ blocks.push(renderObject(header));
100
+ const descResult = truncate(event.description ?? "", flags.full ? 1_000_000 : 500);
101
+ const details = {
102
+ id: event.id ?? "",
103
+ summary: event.summary ?? "",
104
+ status: event.status ?? "",
105
+ start: formatTime(event.start),
106
+ end: formatTime(event.end),
107
+ creator: event.creator?.email ?? "",
108
+ organizer: event.organizer?.email ?? "",
109
+ };
110
+ if (event.location)
111
+ details.location = event.location;
112
+ if (event.hangoutLink)
113
+ details.hangout_link = event.hangoutLink;
114
+ if (event.htmlLink)
115
+ details.html_link = event.htmlLink;
116
+ if (event.recurringEventId)
117
+ details.recurring_event_id = event.recurringEventId;
118
+ if (event.recurrence?.length)
119
+ details.recurrence = event.recurrence;
120
+ if (event.created)
121
+ details.created = event.created;
122
+ if (event.updated)
123
+ details.updated = event.updated;
124
+ blocks.push(renderObject({ event: details }));
125
+ if (descResult.value) {
126
+ const descBlock = { description: descResult.value };
127
+ if (descResult.truncated) {
128
+ descBlock.description_truncated = true;
129
+ descBlock.description_total_chars = descResult.total;
130
+ }
131
+ blocks.push(renderObject(descBlock));
132
+ }
133
+ const attendees = event.attendees ?? [];
134
+ if (attendees.length > 0) {
135
+ const maxAttendees = flags.full ? attendees.length : 20;
136
+ const shown = attendees.slice(0, maxAttendees);
137
+ const schema = [
138
+ field("email"),
139
+ {
140
+ name: "response",
141
+ extract: (a) => a.responseStatus ?? "",
142
+ },
143
+ {
144
+ name: "self",
145
+ extract: (a) => (a.self ? "✓" : ""),
146
+ },
147
+ {
148
+ name: "organizer",
149
+ extract: (a) => (a.organizer ? "✓" : ""),
150
+ },
151
+ {
152
+ name: "optional",
153
+ extract: (a) => (a.optional ? "✓" : ""),
154
+ },
155
+ ];
156
+ blocks.push(renderList("attendees", shown, schema));
157
+ if (attendees.length > maxAttendees) {
158
+ blocks.push(renderObject({
159
+ attendees_truncated: true,
160
+ attendees_total: attendees.length,
161
+ attendees_shown: maxAttendees,
162
+ }));
163
+ }
164
+ }
165
+ const suggestions = [];
166
+ if (descResult.truncated || attendees.length > 20) {
167
+ suggestions.push(`Run with --full to see complete description and all attendees`);
168
+ }
169
+ if (event.htmlLink) {
170
+ suggestions.push(`Open in browser: ${event.htmlLink}`);
171
+ }
172
+ if (suggestions.length > 0)
173
+ blocks.push(renderHelp(suggestions));
174
+ return joinBlocks(...blocks);
175
+ }
176
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../src/commands/calendar/get.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const CALENDAR_HELP: string;
2
+ export declare function calendarCommand(args: string[]): Promise<string>;
@@ -0,0 +1,76 @@
1
+ import { AxiError } from "axi-sdk-js";
2
+ import { resolveAccount } from "../google/account.js";
3
+ import { calendarCalendarsCommand, CALENDARS_HELP } from "./calendar/calendars.js";
4
+ import { calendarEventsCommand, EVENTS_HELP } from "./calendar/events.js";
5
+ import { calendarGetCommand, GET_HELP } from "./calendar/get.js";
6
+ const SUBCOMMANDS = [
7
+ { name: "events", mutation: false, help: EVENTS_HELP, handler: calendarEventsCommand },
8
+ { name: "get", mutation: false, help: GET_HELP, handler: calendarGetCommand },
9
+ { name: "calendars", mutation: false, help: CALENDARS_HELP, handler: calendarCalendarsCommand },
10
+ { name: "search", mutation: false, help: "not yet implemented" },
11
+ { name: "freebusy", mutation: false, help: "not yet implemented" },
12
+ { name: "create", mutation: true, help: "not yet implemented" },
13
+ { name: "update", mutation: true, help: "not yet implemented" },
14
+ { name: "delete", mutation: true, help: "not yet implemented" },
15
+ { name: "respond", mutation: true, help: "not yet implemented" },
16
+ ];
17
+ const SUB_BY_NAME = Object.fromEntries(SUBCOMMANDS.map((s) => [s.name, s]));
18
+ function parseAccountFlag(args) {
19
+ const rest = [];
20
+ let account;
21
+ for (let i = 0; i < args.length; i++) {
22
+ const arg = args[i];
23
+ if (arg === "--account" && args[i + 1]) {
24
+ account = args[i + 1];
25
+ i++;
26
+ continue;
27
+ }
28
+ rest.push(arg);
29
+ }
30
+ return { account, rest };
31
+ }
32
+ const reads = SUBCOMMANDS.filter((s) => !s.mutation).map((s) => s.name);
33
+ const writes = SUBCOMMANDS.filter((s) => s.mutation).map((s) => s.name);
34
+ export const CALENDAR_HELP = `usage: gws-axi calendar <subcommand> [args] [--account <email>] [flags]
35
+ reads[${reads.length}]:
36
+ ${reads.join(", ")}
37
+ writes[${writes.length}]:
38
+ ${writes.join(", ")}
39
+ notes:
40
+ Writes require --account <email> when 2+ accounts are authenticated.
41
+ Reads use the default account when --account is not provided.
42
+ subcommand help:
43
+ gws-axi calendar events --help for time-range / limit / field flags
44
+ gws-axi calendar <sub> --help for any other subcommand
45
+ examples:
46
+ gws-axi calendar events
47
+ gws-axi calendar events --from 2026-04-20T00:00 --to 2026-04-21T00:00
48
+ gws-axi calendar events --fields attendees,location
49
+ `;
50
+ export async function calendarCommand(args) {
51
+ if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
52
+ return CALENDAR_HELP;
53
+ }
54
+ const sub = args[0];
55
+ const def = SUB_BY_NAME[sub];
56
+ if (!def) {
57
+ throw new AxiError(`Unknown calendar subcommand: ${sub}`, "VALIDATION_ERROR", [`Run \`gws-axi calendar --help\` to see available subcommands`]);
58
+ }
59
+ const rest = args.slice(1);
60
+ if (rest.includes("--help")) {
61
+ return def.help;
62
+ }
63
+ const { account: accountFlag, rest: remaining } = parseAccountFlag(rest);
64
+ const resolution = resolveAccount(accountFlag, {
65
+ mutation: def.mutation,
66
+ commandName: `calendar ${sub}`,
67
+ });
68
+ if (!def.handler) {
69
+ throw new AxiError(`gws-axi calendar ${sub} is not yet implemented`, "NOT_IMPLEMENTED", [
70
+ `Account resolution succeeded: would run as ${resolution.account}`,
71
+ `See docs/design.md for the planned command surface`,
72
+ ]);
73
+ }
74
+ return def.handler(resolution.account, remaining);
75
+ }
76
+ //# sourceMappingURL=calendar.js.map