@ncukondo/gcal-cli 0.3.0 → 0.5.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 (2) hide show
  1. package/dist/index.js +1010 -185
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -587668,6 +587668,24 @@ function formatSearchResultText(query, events) {
587668
587668
  return lines.join(`
587669
587669
  `);
587670
587670
  }
587671
+ function formatQuietText(events) {
587672
+ if (events.length === 0)
587673
+ return "No events found.";
587674
+ const lines = [];
587675
+ for (const event of events) {
587676
+ const month = event.start.slice(5, 7);
587677
+ const day = event.start.slice(8, 10);
587678
+ const datePrefix = `${month}/${day}`;
587679
+ if (event.all_day) {
587680
+ lines.push(`${datePrefix} All day ${event.title}`);
587681
+ } else {
587682
+ const time3 = formatTimeRange(event);
587683
+ lines.push(`${datePrefix} ${time3} ${event.title}`);
587684
+ }
587685
+ }
587686
+ return lines.join(`
587687
+ `);
587688
+ }
587671
587689
  var CALENDAR_ID_MAX = 15;
587672
587690
  var CALENDAR_ID_COL = 18;
587673
587691
  function truncateId(id) {
@@ -587736,7 +587754,7 @@ function errorCodeToExitCode(code) {
587736
587754
  // package.json
587737
587755
  var package_default = {
587738
587756
  name: "@ncukondo/gcal-cli",
587739
- version: "0.3.0",
587757
+ version: "0.5.0",
587740
587758
  type: "module",
587741
587759
  exports: {
587742
587760
  ".": "./dist/index.js"
@@ -587790,12 +587808,9 @@ var package_default = {
587790
587808
 
587791
587809
  // src/cli.ts
587792
587810
  var FormatSchema = _enum(["text", "json"]);
587793
- function collect(value, previous) {
587794
- return [...previous, value];
587795
- }
587796
587811
  function createProgram() {
587797
587812
  const program2 = new Command;
587798
- program2.name("gcal").description("CLI tool for managing Google Calendar events").version(package_default.version).option("-f, --format <format>", "Output format: text | json", "text").option("-c, --calendar <id>", "Target calendar ID (repeatable)", collect, []).option("-q, --quiet", "Minimal output", false).option("--tz, --timezone <zone>", "Timezone (e.g., Asia/Tokyo)");
587813
+ program2.name("gcal").description("CLI tool for managing Google Calendar events").version(package_default.version).option("-f, --format <format>", "Output format: text | json", "text").option("-q, --quiet", "Minimal output", false).option("--tz, --timezone <zone>", "Timezone (e.g., Asia/Tokyo)");
587799
587814
  program2.on("command:*", (operands) => {
587800
587815
  process.stderr.write(`error: unknown command '${operands[0]}'
587801
587816
 
@@ -587815,7 +587830,6 @@ function resolveGlobalOptions(program2) {
587815
587830
  }
587816
587831
  return {
587817
587832
  format: formatResult.data,
587818
- calendar: raw.calendar,
587819
587833
  timezone: raw.timezone,
587820
587834
  quiet: raw.quiet
587821
587835
  };
@@ -588008,6 +588022,7 @@ async function getAuthenticatedClient(fs, fetchFn = globalThis.fetch) {
588008
588022
  var OAUTH_SCOPES = [
588009
588023
  "https://www.googleapis.com/auth/calendar.readonly",
588010
588024
  "https://www.googleapis.com/auth/calendar.events",
588025
+ "https://www.googleapis.com/auth/tasks",
588011
588026
  "email"
588012
588027
  ];
588013
588028
  async function startOAuthFlow(credentials, fs, fetchFn = globalThis.fetch) {
@@ -588207,6 +588222,24 @@ function createAuthCommand() {
588207
588222
  return cmd;
588208
588223
  }
588209
588224
 
588225
+ // src/lib/api-utils.ts
588226
+ var MAX_PAGES = 100;
588227
+ function isGoogleApiError(error) {
588228
+ return error instanceof Error && "code" in error && typeof error.code === "number";
588229
+ }
588230
+ function mapApiError(error) {
588231
+ if (isGoogleApiError(error)) {
588232
+ if (error.code === 401 || error.code === 403) {
588233
+ throw new ApiError("AUTH_REQUIRED", error.message);
588234
+ }
588235
+ if (error.code === 404) {
588236
+ throw new ApiError("NOT_FOUND", error.message);
588237
+ }
588238
+ throw new ApiError("API_ERROR", error.message);
588239
+ }
588240
+ throw error;
588241
+ }
588242
+
588210
588243
  // src/lib/api.ts
588211
588244
  class ApiError extends Error {
588212
588245
  code;
@@ -588216,7 +588249,6 @@ class ApiError extends Error {
588216
588249
  this.name = "ApiError";
588217
588250
  }
588218
588251
  }
588219
- var MAX_PAGES = 100;
588220
588252
  var EventStatusSchema = _enum(["confirmed", "tentative", "cancelled"]).catch("confirmed");
588221
588253
  var TransparencySchema = _enum(["opaque", "transparent"]).catch("opaque");
588222
588254
  function normalizeEvent(event, calendarId, calendarName) {
@@ -588380,24 +588412,9 @@ async function deleteEvent(api2, calendarId, eventId) {
588380
588412
  mapApiError(error);
588381
588413
  }
588382
588414
  }
588383
- function isGoogleApiError(error) {
588384
- return error instanceof Error && "code" in error && typeof error.code === "number";
588385
- }
588386
588415
  function isAuthRequiredError(error) {
588387
588416
  return (error instanceof ApiError || error instanceof AuthError) && (error.code === "AUTH_REQUIRED" || error.code === "AUTH_EXPIRED");
588388
588417
  }
588389
- function mapApiError(error) {
588390
- if (isGoogleApiError(error)) {
588391
- if (error.code === 401 || error.code === 403) {
588392
- throw new ApiError("AUTH_REQUIRED", error.message);
588393
- }
588394
- if (error.code === 404) {
588395
- throw new ApiError("NOT_FOUND", error.message);
588396
- }
588397
- throw new ApiError("API_ERROR", error.message);
588398
- }
588399
- throw error;
588400
- }
588401
588418
 
588402
588419
  // src/lib/filter.ts
588403
588420
  function filterByTransparency(events, option) {
@@ -588424,6 +588441,102 @@ function applyFilters(events, options) {
588424
588441
  const afterTransparency = filterByTransparency(events, options.transparency);
588425
588442
  return filterByStatus(afterTransparency, options);
588426
588443
  }
588444
+
588445
+ // src/commands/shared.ts
588446
+ import * as nodeFs from "node:fs";
588447
+ var fsAdapter = {
588448
+ existsSync: (p) => nodeFs.existsSync(p),
588449
+ readFileSync: (p) => nodeFs.readFileSync(p, "utf-8"),
588450
+ writeFileSync: (p, d) => nodeFs.writeFileSync(p, d, "utf-8"),
588451
+ mkdirSync: (p) => nodeFs.mkdirSync(p, { recursive: true }),
588452
+ unlinkSync: (p) => nodeFs.unlinkSync(p),
588453
+ chmodSync: (p, m) => nodeFs.chmodSync(p, m)
588454
+ };
588455
+ function collect(value, previous) {
588456
+ return [...previous, value];
588457
+ }
588458
+ function createGoogleTasksClient(tasks) {
588459
+ return {
588460
+ tasklists: {
588461
+ list: async (p) => {
588462
+ const res = await tasks.tasklists.list(p);
588463
+ const data = {};
588464
+ if (res.data.items)
588465
+ data.items = res.data.items;
588466
+ if (res.data.nextPageToken)
588467
+ data.nextPageToken = res.data.nextPageToken;
588468
+ return { data };
588469
+ }
588470
+ },
588471
+ tasks: {
588472
+ list: async (p) => {
588473
+ const res = await tasks.tasks.list(p);
588474
+ const data = {};
588475
+ if (res.data.items)
588476
+ data.items = res.data.items;
588477
+ if (res.data.nextPageToken)
588478
+ data.nextPageToken = res.data.nextPageToken;
588479
+ return { data };
588480
+ },
588481
+ get: async (p) => {
588482
+ const res = await tasks.tasks.get(p);
588483
+ return { data: res.data };
588484
+ },
588485
+ insert: async (p) => {
588486
+ const res = await tasks.tasks.insert(p);
588487
+ return { data: res.data };
588488
+ },
588489
+ patch: async (p) => {
588490
+ const res = await tasks.tasks.patch(p);
588491
+ return { data: res.data };
588492
+ },
588493
+ delete: async (p) => {
588494
+ await tasks.tasks.delete(p);
588495
+ }
588496
+ }
588497
+ };
588498
+ }
588499
+ function createGoogleCalendarApi(calendar) {
588500
+ return {
588501
+ calendarList: {
588502
+ list: async (p) => {
588503
+ const res = await calendar.calendarList.list(p);
588504
+ const data = {};
588505
+ if (res.data.items)
588506
+ data.items = res.data.items;
588507
+ if (res.data.nextPageToken)
588508
+ data.nextPageToken = res.data.nextPageToken;
588509
+ return { data };
588510
+ }
588511
+ },
588512
+ events: {
588513
+ list: async (p) => {
588514
+ const res = await calendar.events.list(p);
588515
+ const data = {};
588516
+ if (res.data.items)
588517
+ data.items = res.data.items;
588518
+ if (res.data.nextPageToken)
588519
+ data.nextPageToken = res.data.nextPageToken;
588520
+ return { data };
588521
+ },
588522
+ get: async (p) => {
588523
+ const res = await calendar.events.get(p);
588524
+ return { data: res.data };
588525
+ },
588526
+ insert: async (p) => {
588527
+ const res = await calendar.events.insert(p);
588528
+ return { data: res.data };
588529
+ },
588530
+ patch: async (p) => {
588531
+ const res = await calendar.events.patch(p);
588532
+ return { data: res.data };
588533
+ },
588534
+ delete: async (p) => {
588535
+ await calendar.events.delete(p);
588536
+ }
588537
+ }
588538
+ };
588539
+ }
588427
588540
  // node_modules/date-fns/locale/en-US/_lib/formatDistance.mjs
588428
588541
  var formatDistanceLocale = {
588429
588542
  lessThanXSeconds: {
@@ -590596,8 +590709,8 @@ function parseDateTimeInZone(dateStr, timezone) {
590596
590709
  // src/commands/search.ts
590597
590710
  var DEFAULT_SEARCH_DAYS = 30;
590598
590711
  async function handleSearch(opts) {
590599
- const { api: api2, query, format: format4, calendars, timezone, write } = opts;
590600
- const writeErr = opts.writeErr ?? (() => {});
590712
+ const { api: api2, query, format: format4, calendars, timezone, write, quiet } = opts;
590713
+ const writeErr = quiet ? () => {} : opts.writeErr ?? (() => {});
590601
590714
  const now = new Date;
590602
590715
  const days = opts.days ?? DEFAULT_SEARCH_DAYS;
590603
590716
  const isNegativeDays = days < 0;
@@ -590605,7 +590718,7 @@ async function handleSearch(opts) {
590605
590718
  let timeMax;
590606
590719
  if (opts.from && opts.to) {
590607
590720
  timeMin = formatDateTimeInZone(parseDateTimeInZone(opts.from, timezone), timezone);
590608
- timeMax = formatDateTimeInZone(parseDateTimeInZone(opts.to + "T23:59:59", timezone), timezone);
590721
+ timeMax = formatDateTimeInZone(addDays(parseDateTimeInZone(opts.to, timezone), 1), timezone);
590609
590722
  } else if (opts.from) {
590610
590723
  const startDate = parseDateTimeInZone(opts.from, timezone);
590611
590724
  timeMin = formatDateTimeInZone(startDate, timezone);
@@ -590613,7 +590726,7 @@ async function handleSearch(opts) {
590613
590726
  endDate.setDate(endDate.getDate() + days);
590614
590727
  timeMax = formatDateTimeInZone(endDate, timezone);
590615
590728
  } else if (opts.to) {
590616
- timeMax = formatDateTimeInZone(parseDateTimeInZone(opts.to + "T23:59:59", timezone), timezone);
590729
+ timeMax = formatDateTimeInZone(addDays(parseDateTimeInZone(opts.to, timezone), 1), timezone);
590617
590730
  timeMin = formatDateTimeInZone(now, timezone);
590618
590731
  } else if (isNegativeDays) {
590619
590732
  const pastDate = new Date(now.getTime());
@@ -590627,7 +590740,7 @@ async function handleSearch(opts) {
590627
590740
  timeMax = formatDateTimeInZone(endDate, timezone);
590628
590741
  }
590629
590742
  const displayFrom = timeMin.slice(0, 10);
590630
- const displayTo = timeMax.slice(0, 10);
590743
+ const displayTo = opts.to ?? timeMax.slice(0, 10);
590631
590744
  writeErr(`Searching: ${displayFrom} to ${displayTo}`);
590632
590745
  const hasExplicitRange = opts.days !== undefined || opts.from !== undefined || opts.to !== undefined;
590633
590746
  if (!hasExplicitRange) {
@@ -590648,6 +590761,8 @@ async function handleSearch(opts) {
590648
590761
  events: filtered,
590649
590762
  count: filtered.length
590650
590763
  }));
590764
+ } else if (quiet) {
590765
+ write(formatQuietText(filtered));
590651
590766
  } else {
590652
590767
  write(formatSearchResultText(query, filtered));
590653
590768
  }
@@ -590655,9 +590770,10 @@ async function handleSearch(opts) {
590655
590770
  }
590656
590771
  function createSearchCommand() {
590657
590772
  const cmd = new Command("search").description("Search events by keyword").argument("<query>", "Search query string");
590773
+ cmd.option("-c, --calendar <id>", "Target calendar ID (repeatable)", collect, []);
590658
590774
  cmd.option("--from <date>", "Start date for search range");
590659
590775
  cmd.option("--to <date>", "End date for search range");
590660
- cmd.option("--days <n>", "Search within next n days (default: 30)", Number.parseInt);
590776
+ cmd.option("--days <n>", "Search within next n days (default: 30)", (v) => Number.parseInt(v, 10));
590661
590777
  const daysOpt = cmd.options.find((o) => o.long === "--days");
590662
590778
  const fromOpt = cmd.options.find((o) => o.long === "--from");
590663
590779
  const toOpt = cmd.options.find((o) => o.long === "--to");
@@ -590667,32 +590783,26 @@ function createSearchCommand() {
590667
590783
  cmd.option("--busy", "Show only busy (opaque) events");
590668
590784
  cmd.option("--free", "Show only free (transparent) events");
590669
590785
  cmd.option("--confirmed", "Show only confirmed events");
590670
- cmd.option("--include-tentative", "Include tentative events");
590786
+ cmd.option("--include-tentative", "Include tentative events (excluded by default)");
590787
+ const busyOpt = cmd.options.find((o) => o.long === "--busy");
590788
+ const freeOpt = cmd.options.find((o) => o.long === "--free");
590789
+ busyOpt.conflicts(["free"]);
590790
+ freeOpt.conflicts(["busy"]);
590671
590791
  return cmd;
590672
590792
  }
590673
590793
 
590674
590794
  // src/commands/show.ts
590675
590795
  async function handleShow(opts) {
590676
- const { api: api2, eventId, calendarId, calendarName, format: format4, timezone, write } = opts;
590677
- try {
590678
- const event = await getEvent(api2, calendarId, calendarName, eventId, timezone);
590679
- if (format4 === "json") {
590680
- write(formatJsonSuccess({ event }));
590681
- } else {
590682
- write(formatEventDetailText(event));
590683
- }
590684
- return { exitCode: ExitCode.SUCCESS };
590685
- } catch (error) {
590686
- if (error instanceof ApiError) {
590687
- if (format4 === "json") {
590688
- write(formatJsonError(error.code, error.message));
590689
- } else {
590690
- write(`Error: ${error.message}`);
590691
- }
590692
- return { exitCode: errorCodeToExitCode(error.code) };
590693
- }
590694
- throw error;
590796
+ const { api: api2, eventId, calendarId, calendarName, format: format4, quiet, timezone, write } = opts;
590797
+ const event = await getEvent(api2, calendarId, calendarName, eventId, timezone);
590798
+ if (format4 === "json") {
590799
+ write(formatJsonSuccess({ event }));
590800
+ } else if (quiet) {
590801
+ write(`${event.title} ${event.start} ${event.end}`);
590802
+ } else {
590803
+ write(formatEventDetailText(event));
590695
590804
  }
590805
+ return { exitCode: ExitCode.SUCCESS };
590696
590806
  }
590697
590807
  function createShowCommand() {
590698
590808
  return new Command("show").description("Show event details").argument("<event-id>", "Event ID").option("-c, --calendar <id>", "Calendar ID to query");
@@ -590829,11 +590939,16 @@ function skipComment(str, ptr) {
590829
590939
  }
590830
590940
  function skipVoid(str, ptr, banNewLines, banComments) {
590831
590941
  let c;
590832
- while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
590942
+ while (true) {
590943
+ while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
590833
590944
  ` || c === "\r" && str[ptr + 1] === `
590834
590945
  `))
590835
- ptr++;
590836
- return banComments || c !== "#" ? ptr : skipVoid(str, skipComment(str, ptr), banNewLines);
590946
+ ptr++;
590947
+ if (banComments || c !== "#")
590948
+ break;
590949
+ ptr = skipComment(str, ptr);
590950
+ }
590951
+ return ptr;
590837
590952
  }
590838
590953
  function skipUntil(str, ptr, sep, end, banNewLines = false) {
590839
590954
  if (!end) {
@@ -591665,6 +591780,11 @@ function parseConfig(toml) {
591665
591780
  name: String(c["name"]),
591666
591781
  enabled: Boolean(c["enabled"])
591667
591782
  })) : [];
591783
+ const task_lists = Array.isArray(raw["task_lists"]) ? raw["task_lists"].map((t) => ({
591784
+ id: String(t["id"]),
591785
+ name: String(t["name"]),
591786
+ enabled: Boolean(t["enabled"])
591787
+ })) : [];
591668
591788
  const envFormat = process.env["GCAL_CLI_FORMAT"];
591669
591789
  const envTimezone = process.env["GCAL_CLI_TIMEZONE"];
591670
591790
  const fileFormat = typeof raw["default_format"] === "string" ? validateOutputFormat(raw["default_format"], "config file") : "text";
@@ -591672,7 +591792,8 @@ function parseConfig(toml) {
591672
591792
  const timezone = envTimezone || fileTimezone;
591673
591793
  const config2 = {
591674
591794
  default_format: envFormat ? validateOutputFormat(envFormat, "GCAL_CLI_FORMAT env var") : fileFormat,
591675
- calendars
591795
+ calendars,
591796
+ task_lists
591676
591797
  };
591677
591798
  if (timezone) {
591678
591799
  config2.timezone = timezone;
@@ -591708,7 +591829,7 @@ function getDefaultConfigPath() {
591708
591829
  function escapeTomlString(value) {
591709
591830
  return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
591710
591831
  }
591711
- function generateConfigToml(calendars, timezone) {
591832
+ function generateConfigToml(calendars, timezone, taskLists) {
591712
591833
  const lines = [];
591713
591834
  if (timezone) {
591714
591835
  lines.push(`timezone = "${escapeTomlString(timezone)}"`);
@@ -591721,6 +591842,15 @@ function generateConfigToml(calendars, timezone) {
591721
591842
  lines.push(`enabled = ${String(cal.enabled)}`);
591722
591843
  lines.push("");
591723
591844
  }
591845
+ if (taskLists && taskLists.length > 0) {
591846
+ for (const tl of taskLists) {
591847
+ lines.push("[[task_lists]]");
591848
+ lines.push(`id = "${escapeTomlString(tl.id)}"`);
591849
+ lines.push(`name = "${escapeTomlString(tl.name)}"`);
591850
+ lines.push(`enabled = ${String(tl.enabled)}`);
591851
+ lines.push("");
591852
+ }
591853
+ }
591724
591854
  return lines.join(`
591725
591855
  `);
591726
591856
  }
@@ -591778,24 +591908,6 @@ function resolveDateRange(input, timezone, now = () => new Date) {
591778
591908
  timeMax: formatDateTimeInZone(end, timezone)
591779
591909
  };
591780
591910
  }
591781
- function formatQuietText(events) {
591782
- if (events.length === 0)
591783
- return "No events found.";
591784
- const lines = [];
591785
- for (const event of events) {
591786
- const month = event.start.slice(5, 7);
591787
- const day = event.start.slice(8, 10);
591788
- const datePrefix = `${month}/${day}`;
591789
- if (event.all_day) {
591790
- lines.push(`${datePrefix} All day ${event.title}`);
591791
- } else {
591792
- const time3 = formatTimeRange(event);
591793
- lines.push(`${datePrefix} ${time3} ${event.title}`);
591794
- }
591795
- }
591796
- return lines.join(`
591797
- `);
591798
- }
591799
591911
  async function handleList(options, deps) {
591800
591912
  const config2 = deps.loadConfig();
591801
591913
  const timezone = resolveTimezone(options.timezone, config2.timezone);
@@ -591813,7 +591925,7 @@ async function handleList(options, deps) {
591813
591925
  if (dateRange.warning && deps.writeErr) {
591814
591926
  deps.writeErr(dateRange.warning);
591815
591927
  }
591816
- const calendars = selectCalendars(options.calendar, config2);
591928
+ const calendars = selectCalendars(options.calendar && options.calendar.length > 0 ? options.calendar : undefined, config2);
591817
591929
  const apiOptions = {
591818
591930
  timeMin: dateRange.timeMin,
591819
591931
  timeMax: dateRange.timeMax
@@ -591852,6 +591964,7 @@ async function handleList(options, deps) {
591852
591964
  }
591853
591965
  function createListCommand() {
591854
591966
  const cmd = new Command("list").description("List events within a date range");
591967
+ cmd.option("-c, --calendar <id>", "Target calendar ID (repeatable)", collect, []);
591855
591968
  cmd.option("--today", "Show today's events");
591856
591969
  cmd.option("--days <n>", "Events for next n days (default: 7)", (v) => Number.parseInt(v, 10));
591857
591970
  cmd.option("--from <date>", "Start date (ISO 8601 or YYYY-MM-DD)");
@@ -591865,9 +591978,11 @@ function createListCommand() {
591865
591978
  const fromOpt = cmd.options.find((o) => o.long === "--from");
591866
591979
  const busyOpt = cmd.options.find((o) => o.long === "--busy");
591867
591980
  const freeOpt = cmd.options.find((o) => o.long === "--free");
591981
+ const toOpt = cmd.options.find((o) => o.long === "--to");
591868
591982
  todayOpt.conflicts(["days", "from"]);
591869
- daysOpt.conflicts(["today", "from"]);
591983
+ daysOpt.conflicts(["today", "from", "to"]);
591870
591984
  fromOpt.conflicts(["today", "days"]);
591985
+ toOpt.conflicts(["days"]);
591871
591986
  busyOpt.conflicts(["free"]);
591872
591987
  freeOpt.conflicts(["busy"]);
591873
591988
  return cmd;
@@ -592133,9 +592248,14 @@ async function handleUpdate(opts) {
592133
592248
  }
592134
592249
  const updated = await updateEvent(api2, calendarId, calendarName, eventId, input);
592135
592250
  if (format4 === "json") {
592136
- write(formatJsonSuccess({ event: updated }));
592251
+ write(formatJsonSuccess({ event: updated, message: "Event updated" }));
592252
+ } else if (opts.quiet) {
592253
+ write(updated.id);
592137
592254
  } else {
592138
- write(formatEventDetailText(updated));
592255
+ const detail = formatEventDetailText(updated);
592256
+ write(`Event updated
592257
+
592258
+ ${detail}`);
592139
592259
  }
592140
592260
  return { exitCode: ExitCode.SUCCESS };
592141
592261
  }
@@ -592261,9 +592381,37 @@ async function handleAdd(options, deps) {
592261
592381
  if (options.description !== undefined) {
592262
592382
  input.description = options.description;
592263
592383
  }
592384
+ if (options.dryRun) {
592385
+ const preview = {
592386
+ title: input.title,
592387
+ start: input.start,
592388
+ end: input.end
592389
+ };
592390
+ if (input.description !== undefined)
592391
+ preview.description = input.description;
592392
+ if (input.transparency !== "opaque")
592393
+ preview.transparency = input.transparency;
592394
+ if (options.format === "json") {
592395
+ deps.write(formatJsonSuccess({ dry_run: true, action: "add", event: preview }));
592396
+ } else {
592397
+ const lines = ["DRY RUN: Would create event:"];
592398
+ lines.push(` title: "${preview.title}"`);
592399
+ lines.push(` start: "${preview.start}"`);
592400
+ lines.push(` end: "${preview.end}"`);
592401
+ if (preview.description !== undefined)
592402
+ lines.push(` description: "${preview.description}"`);
592403
+ if (preview.transparency !== undefined)
592404
+ lines.push(` transparency: ${preview.transparency}`);
592405
+ deps.write(lines.join(`
592406
+ `));
592407
+ }
592408
+ return { exitCode: ExitCode.SUCCESS };
592409
+ }
592264
592410
  const event = await deps.createEvent(calendarId, calendarName, input);
592265
592411
  if (options.format === "json") {
592266
592412
  deps.write(formatJsonSuccess({ event, message: "Event created" }));
592413
+ } else if (options.quiet) {
592414
+ deps.write(event.id);
592267
592415
  } else {
592268
592416
  const detail = formatEventDetailText(event);
592269
592417
  deps.write(`Event created
@@ -592278,9 +592426,11 @@ function createAddCommand() {
592278
592426
  cmd.requiredOption("-s, --start <datetime>", "Start date or datetime. Date-only (YYYY-MM-DD) creates all-day event. Datetime (YYYY-MM-DDTHH:MM) creates timed event.");
592279
592427
  cmd.option("-e, --end <datetime>", "End date or datetime. Optional. Default: same day (all-day) or +1h (timed). All-day end is inclusive.");
592280
592428
  cmd.option("--duration <duration>", "Duration instead of --end (e.g. 30m, 1h, 2d, 1h30m). Mutually exclusive with --end.");
592429
+ cmd.option("-c, --calendar <id>", "Target calendar ID");
592281
592430
  cmd.option("-d, --description <text>", "Event description");
592282
592431
  cmd.option("--busy", "Mark as busy (default)");
592283
592432
  cmd.option("--free", "Mark as free (transparent)");
592433
+ cmd.option("--dry-run", "Preview without executing");
592284
592434
  const endOpt = cmd.options.find((o) => o.long === "--end");
592285
592435
  const durationOpt = cmd.options.find((o) => o.long === "--duration");
592286
592436
  endOpt.conflicts(["duration"]);
@@ -592306,8 +592456,7 @@ Examples:
592306
592456
  async function handleDelete(opts) {
592307
592457
  const { api: api2, eventId, calendarId, format: format4, quiet, dryRun = false, write } = opts;
592308
592458
  if (!eventId) {
592309
- write(formatJsonError("INVALID_ARGS", "event-id is required"));
592310
- return { exitCode: ExitCode.ARGUMENT };
592459
+ throw new ApiError("INVALID_ARGS", "event-id is required");
592311
592460
  }
592312
592461
  if (dryRun) {
592313
592462
  if (format4 === "json") {
@@ -592322,27 +592471,15 @@ async function handleDelete(opts) {
592322
592471
  }
592323
592472
  return { exitCode: ExitCode.SUCCESS };
592324
592473
  }
592325
- try {
592326
- await deleteEvent(api2, calendarId, eventId);
592327
- if (!quiet) {
592328
- if (format4 === "json") {
592329
- write(formatJsonSuccess({ deleted_id: eventId, message: "Event deleted" }));
592330
- } else {
592331
- write("Event deleted");
592332
- }
592333
- }
592334
- return { exitCode: ExitCode.SUCCESS };
592335
- } catch (error) {
592336
- if (error instanceof ApiError) {
592337
- if (format4 === "json") {
592338
- write(formatJsonError(error.code, error.message));
592339
- } else {
592340
- write(`Error: ${error.message}`);
592341
- }
592342
- return { exitCode: errorCodeToExitCode(error.code) };
592474
+ await deleteEvent(api2, calendarId, eventId);
592475
+ if (!quiet) {
592476
+ if (format4 === "json") {
592477
+ write(formatJsonSuccess({ deleted_id: eventId, message: "Event deleted" }));
592478
+ } else {
592479
+ write("Event deleted");
592343
592480
  }
592344
- throw error;
592345
592481
  }
592482
+ return { exitCode: ExitCode.SUCCESS };
592346
592483
  }
592347
592484
  function createDeleteCommand() {
592348
592485
  return new Command("delete").description("Delete a calendar event").argument("<event-id>", "Event ID").option("-c, --calendar <id>", "Calendar ID to query").option("--dry-run", "Preview without executing");
@@ -592361,20 +592498,7 @@ function mergeCalendarsWithConfig(apiCalendars, configCalendars) {
592361
592498
  }
592362
592499
  async function handleCalendars(opts) {
592363
592500
  const { api: api2, format: format4, quiet, write, configCalendars } = opts;
592364
- let apiCalendars;
592365
- try {
592366
- apiCalendars = await listCalendars(api2);
592367
- } catch (error) {
592368
- if (error instanceof ApiError) {
592369
- if (format4 === "json") {
592370
- write(formatJsonError(error.code, error.message));
592371
- } else {
592372
- write(error.message);
592373
- }
592374
- return { exitCode: errorCodeToExitCode(error.code) };
592375
- }
592376
- throw error;
592377
- }
592501
+ const apiCalendars = await listCalendars(api2);
592378
592502
  const calendars = mergeCalendarsWithConfig(apiCalendars, configCalendars);
592379
592503
  if (quiet) {
592380
592504
  write(calendars.map((c) => c.id).join(`
@@ -592399,6 +592523,7 @@ function resolveTimezone2(cliTimezone) {
592399
592523
  }
592400
592524
  async function handleInit(opts) {
592401
592525
  const { fs, format: format4, quiet, write, force, all, local, requestAuth } = opts;
592526
+ const writeErr = quiet ? () => {} : opts.writeErr ?? (() => {});
592402
592527
  const configPath = local ? `${process.cwd()}/gcal-cli.toml` : getDefaultConfigPath();
592403
592528
  if (!force && fs.existsSync(configPath)) {
592404
592529
  const msg = `Config file already exists: ${configPath}
@@ -592443,18 +592568,32 @@ Use --force to overwrite.`;
592443
592568
  name: cal.name,
592444
592569
  enabled: all || cal.primary
592445
592570
  }));
592571
+ let configTaskLists = [];
592572
+ if (opts.listTaskLists) {
592573
+ try {
592574
+ const taskLists = await opts.listTaskLists();
592575
+ configTaskLists = taskLists.map((tl) => ({
592576
+ id: tl.id,
592577
+ name: tl.title,
592578
+ enabled: all || tl.id === "@default"
592579
+ }));
592580
+ } catch {
592581
+ writeErr("[init] Tasks API unavailable, skipping task lists");
592582
+ }
592583
+ }
592446
592584
  const timezone = resolveTimezone2(opts.timezone);
592447
- const toml = generateConfigToml(configCalendars, timezone);
592585
+ const toml = generateConfigToml(configCalendars, timezone, configTaskLists.length > 0 ? configTaskLists : undefined);
592448
592586
  const dir = path.dirname(configPath);
592449
592587
  fs.mkdirSync(dir, { recursive: true });
592450
592588
  fs.writeFileSync(configPath, toml);
592451
592589
  const enabledCalendars = configCalendars.filter((c) => c.enabled);
592590
+ const enabledTaskLists = configTaskLists.filter((t) => t.enabled);
592452
592591
  if (quiet) {
592453
592592
  write(configPath);
592454
592593
  return { exitCode: ExitCode.SUCCESS };
592455
592594
  }
592456
592595
  if (format4 === "json") {
592457
- write(formatJsonSuccess({
592596
+ const data = {
592458
592597
  path: configPath,
592459
592598
  timezone,
592460
592599
  calendars: configCalendars.map((c) => ({
@@ -592464,7 +592603,15 @@ Use --force to overwrite.`;
592464
592603
  })),
592465
592604
  enabled_count: enabledCalendars.length,
592466
592605
  total_count: configCalendars.length
592467
- }));
592606
+ };
592607
+ if (configTaskLists.length > 0) {
592608
+ data.task_lists = configTaskLists.map((t) => ({
592609
+ id: t.id,
592610
+ name: t.name,
592611
+ enabled: t.enabled
592612
+ }));
592613
+ }
592614
+ write(formatJsonSuccess(data));
592468
592615
  } else {
592469
592616
  write(`Config file created: ${configPath}`);
592470
592617
  write("");
@@ -592472,6 +592619,13 @@ Use --force to overwrite.`;
592472
592619
  for (const cal of enabledCalendars) {
592473
592620
  write(` - ${cal.name} (${cal.id})`);
592474
592621
  }
592622
+ if (enabledTaskLists.length > 0) {
592623
+ write("");
592624
+ write("Enabled task lists:");
592625
+ for (const tl of enabledTaskLists) {
592626
+ write(` - ${tl.name} (${tl.id})`);
592627
+ }
592628
+ }
592475
592629
  write("");
592476
592630
  write(`Timezone: ${timezone}`);
592477
592631
  }
@@ -592486,56 +592640,551 @@ function createInitCommand() {
592486
592640
  return cmd;
592487
592641
  }
592488
592642
 
592489
- // src/commands/shared.ts
592490
- import * as nodeFs from "node:fs";
592491
- var fsAdapter = {
592492
- existsSync: (p) => nodeFs.existsSync(p),
592493
- readFileSync: (p) => nodeFs.readFileSync(p, "utf-8"),
592494
- writeFileSync: (p, d) => nodeFs.writeFileSync(p, d, "utf-8"),
592495
- mkdirSync: (p) => nodeFs.mkdirSync(p, { recursive: true }),
592496
- unlinkSync: (p) => nodeFs.unlinkSync(p),
592497
- chmodSync: (p, m) => nodeFs.chmodSync(p, m)
592498
- };
592499
- function createGoogleCalendarApi(calendar) {
592643
+ // src/commands/tasks/index.ts
592644
+ function createTasksCommand() {
592645
+ const tasksCmd = new Command("tasks").description("Manage Google Tasks");
592646
+ const listsCmd = new Command("lists").description("List task lists");
592647
+ tasksCmd.addCommand(listsCmd);
592648
+ const listCmd = new Command("list").description("List tasks").option("-l, --list <name-or-id>", "Task list name or ID").option("--all", "Include completed tasks").option("--completed", "Show only completed tasks").option("--due-before <date>", "Tasks due before date (YYYY-MM-DD)").option("--due-after <date>", "Tasks due after date (YYYY-MM-DD)");
592649
+ tasksCmd.addCommand(listCmd);
592650
+ const showCmd = new Command("show").description("Show task details").argument("<task-id>", "Task ID").option("-l, --list <name-or-id>", "Task list name or ID");
592651
+ tasksCmd.addCommand(showCmd);
592652
+ const addCmd = new Command("add").description("Create a new task").requiredOption("-t, --title <title>", "Task title").option("-n, --notes <text>", "Notes").option("--due <date>", "Due date (YYYY-MM-DD)").option("-l, --list <name-or-id>", "Task list name or ID").option("--parent <task-id>", "Parent task ID (create as subtask)");
592653
+ tasksCmd.addCommand(addCmd);
592654
+ const updateCmd = new Command("update").description("Update an existing task").argument("<task-id>", "Task ID to update").option("-t, --title <title>", "New title").option("-n, --notes <text>", "New notes").option("--due <date>", "New due date (YYYY-MM-DD)").option("-l, --list <name-or-id>", "Task list name or ID");
592655
+ tasksCmd.addCommand(updateCmd);
592656
+ const doneCmd = new Command("done").description("Mark a task as completed").argument("<task-id>", "Task ID to complete").option("-l, --list <name-or-id>", "Task list name or ID");
592657
+ tasksCmd.addCommand(doneCmd);
592658
+ const undoneCmd = new Command("undone").description("Mark a task as not completed").argument("<task-id>", "Task ID to reopen").option("-l, --list <name-or-id>", "Task list name or ID");
592659
+ tasksCmd.addCommand(undoneCmd);
592660
+ const deleteCmd = new Command("delete").description("Delete a task").argument("<task-id>", "Task ID to delete").option("-l, --list <name-or-id>", "Task list name or ID");
592661
+ tasksCmd.addCommand(deleteCmd);
592662
+ return { tasksCmd, listsCmd, listCmd, showCmd, addCmd, updateCmd, doneCmd, undoneCmd, deleteCmd };
592663
+ }
592664
+
592665
+ // src/lib/tasks-api.ts
592666
+ function normalizeTaskList(raw) {
592500
592667
  return {
592501
- calendarList: {
592502
- list: async (p) => {
592503
- const res = await calendar.calendarList.list(p);
592504
- const data = {};
592505
- if (res.data.items)
592506
- data.items = res.data.items;
592507
- if (res.data.nextPageToken)
592508
- data.nextPageToken = res.data.nextPageToken;
592509
- return { data };
592668
+ id: raw.id ?? "",
592669
+ title: raw.title ?? "",
592670
+ updated: raw.updated ?? ""
592671
+ };
592672
+ }
592673
+ var VALID_TASK_STATUSES = ["needsAction", "completed"];
592674
+ function parseTaskStatus(value) {
592675
+ if (value && VALID_TASK_STATUSES.includes(value)) {
592676
+ return value;
592677
+ }
592678
+ return "needsAction";
592679
+ }
592680
+ function parseDueDate(due) {
592681
+ if (!due)
592682
+ return null;
592683
+ return due.slice(0, 10);
592684
+ }
592685
+ function normalizeTask(raw, listId, listTitle) {
592686
+ return {
592687
+ id: raw.id ?? "",
592688
+ title: raw.title ?? "",
592689
+ notes: raw.notes ?? null,
592690
+ status: parseTaskStatus(raw.status),
592691
+ due: parseDueDate(raw.due),
592692
+ completed: raw.completed ?? null,
592693
+ list_id: listId,
592694
+ list_title: listTitle,
592695
+ parent: raw.parent ?? null,
592696
+ updated: raw.updated ?? ""
592697
+ };
592698
+ }
592699
+ async function listTaskLists(client) {
592700
+ try {
592701
+ const results = [];
592702
+ let pageToken;
592703
+ let pages = 0;
592704
+ do {
592705
+ if (pages >= MAX_PAGES) {
592706
+ throw new ApiError("API_ERROR", `Pagination limit of ${MAX_PAGES} pages exceeded`);
592510
592707
  }
592511
- },
592512
- events: {
592513
- list: async (p) => {
592514
- const res = await calendar.events.list(p);
592515
- const data = {};
592516
- if (res.data.items)
592517
- data.items = res.data.items;
592518
- if (res.data.nextPageToken)
592519
- data.nextPageToken = res.data.nextPageToken;
592520
- return { data };
592521
- },
592522
- get: async (p) => {
592523
- const res = await calendar.events.get(p);
592524
- return { data: res.data };
592525
- },
592526
- insert: async (p) => {
592527
- const res = await calendar.events.insert(p);
592528
- return { data: res.data };
592529
- },
592530
- patch: async (p) => {
592531
- const res = await calendar.events.patch(p);
592532
- return { data: res.data };
592533
- },
592534
- delete: async (p) => {
592535
- await calendar.events.delete(p);
592708
+ const response = await client.tasklists.list(pageToken ? { pageToken } : undefined);
592709
+ const items = response.data.items ?? [];
592710
+ for (const item of items) {
592711
+ results.push(normalizeTaskList(item));
592536
592712
  }
592713
+ pageToken = response.data.nextPageToken;
592714
+ pages++;
592715
+ } while (pageToken);
592716
+ return results;
592717
+ } catch (error) {
592718
+ mapApiError(error);
592719
+ }
592720
+ }
592721
+ async function listTasks(client, taskListId, listTitle, options) {
592722
+ try {
592723
+ const results = [];
592724
+ let pageToken;
592725
+ let pages = 0;
592726
+ do {
592727
+ if (pages >= MAX_PAGES) {
592728
+ throw new ApiError("API_ERROR", `Pagination limit of ${MAX_PAGES} pages exceeded`);
592729
+ }
592730
+ const params = {
592731
+ tasklist: taskListId,
592732
+ ...options
592733
+ };
592734
+ if (pageToken) {
592735
+ params.pageToken = pageToken;
592736
+ }
592737
+ const response = await client.tasks.list(params);
592738
+ const items = response.data.items ?? [];
592739
+ for (const item of items) {
592740
+ results.push(normalizeTask(item, taskListId, listTitle));
592741
+ }
592742
+ pageToken = response.data.nextPageToken;
592743
+ pages++;
592744
+ } while (pageToken);
592745
+ return results;
592746
+ } catch (error) {
592747
+ mapApiError(error);
592748
+ }
592749
+ }
592750
+ async function getTask(client, taskListId, listTitle, taskId) {
592751
+ try {
592752
+ const response = await client.tasks.get({ tasklist: taskListId, task: taskId });
592753
+ return normalizeTask(response.data, taskListId, listTitle);
592754
+ } catch (error) {
592755
+ mapApiError(error);
592756
+ }
592757
+ }
592758
+ async function createTask(client, taskListId, listTitle, input) {
592759
+ try {
592760
+ const requestBody = {
592761
+ title: input.title
592762
+ };
592763
+ if (input.notes !== undefined) {
592764
+ requestBody.notes = input.notes;
592765
+ }
592766
+ if (input.due !== undefined) {
592767
+ requestBody.due = input.due;
592768
+ }
592769
+ const params = { tasklist: taskListId, requestBody };
592770
+ if (input.parent !== undefined) {
592771
+ params.parent = input.parent;
592772
+ }
592773
+ const response = await client.tasks.insert(params);
592774
+ return normalizeTask(response.data, taskListId, listTitle);
592775
+ } catch (error) {
592776
+ mapApiError(error);
592777
+ }
592778
+ }
592779
+ async function updateTask(client, taskListId, listTitle, taskId, input) {
592780
+ try {
592781
+ const requestBody = {};
592782
+ if (input.title !== undefined) {
592783
+ requestBody.title = input.title;
592784
+ }
592785
+ if (input.notes !== undefined) {
592786
+ requestBody.notes = input.notes;
592787
+ }
592788
+ if (input.due !== undefined) {
592789
+ requestBody.due = input.due;
592537
592790
  }
592791
+ const response = await client.tasks.patch({
592792
+ tasklist: taskListId,
592793
+ task: taskId,
592794
+ requestBody
592795
+ });
592796
+ return normalizeTask(response.data, taskListId, listTitle);
592797
+ } catch (error) {
592798
+ mapApiError(error);
592799
+ }
592800
+ }
592801
+ async function deleteTask(client, taskListId, taskId) {
592802
+ try {
592803
+ await client.tasks.delete({ tasklist: taskListId, task: taskId });
592804
+ } catch (error) {
592805
+ mapApiError(error);
592806
+ }
592807
+ }
592808
+ async function completeTask(client, taskListId, listTitle, taskId) {
592809
+ try {
592810
+ const response = await client.tasks.patch({
592811
+ tasklist: taskListId,
592812
+ task: taskId,
592813
+ requestBody: { status: "completed" }
592814
+ });
592815
+ return normalizeTask(response.data, taskListId, listTitle);
592816
+ } catch (error) {
592817
+ mapApiError(error);
592818
+ }
592819
+ }
592820
+ async function uncompleteTask(client, taskListId, listTitle, taskId) {
592821
+ try {
592822
+ const response = await client.tasks.patch({
592823
+ tasklist: taskListId,
592824
+ task: taskId,
592825
+ requestBody: { status: "needsAction", completed: null }
592826
+ });
592827
+ return normalizeTask(response.data, taskListId, listTitle);
592828
+ } catch (error) {
592829
+ mapApiError(error);
592830
+ }
592831
+ }
592832
+
592833
+ // src/commands/tasks/lists.ts
592834
+ function mergeTaskListsWithConfig(apiLists, configLists) {
592835
+ const hasConfig = configLists.length > 0;
592836
+ const configMap = new Map(configLists.map((c) => [c.id, c]));
592837
+ return apiLists.map((list) => {
592838
+ const config2 = configMap.get(list.id);
592839
+ return {
592840
+ ...list,
592841
+ enabled: hasConfig ? config2 ? config2.enabled : true : true
592842
+ };
592843
+ });
592844
+ }
592845
+ function formatTaskListText(lists) {
592846
+ const lines = ["Task Lists:"];
592847
+ for (const list of lists) {
592848
+ const checkbox = list.enabled ? "[x]" : "[ ]";
592849
+ const suffix = list.enabled ? "" : " (disabled)";
592850
+ lines.push(` ${checkbox} ${list.title} (${list.id})${suffix}`);
592851
+ }
592852
+ return lines.join(`
592853
+ `);
592854
+ }
592855
+ async function handleTaskLists(opts) {
592856
+ const { client, format: format4, quiet, write, configTaskLists } = opts;
592857
+ const apiLists = await listTaskLists(client);
592858
+ const lists = mergeTaskListsWithConfig(apiLists, configTaskLists);
592859
+ if (quiet) {
592860
+ write(lists.map((l) => l.id).join(`
592861
+ `));
592862
+ return { exitCode: ExitCode.SUCCESS };
592863
+ }
592864
+ if (format4 === "json") {
592865
+ write(formatJsonSuccess({ task_lists: lists, count: lists.length }));
592866
+ } else {
592867
+ write(formatTaskListText(lists));
592868
+ }
592869
+ return { exitCode: ExitCode.SUCCESS };
592870
+ }
592871
+
592872
+ // src/commands/tasks/resolve.ts
592873
+ function resolveTaskListFromConfig(configLists, listOption) {
592874
+ if (!listOption) {
592875
+ const enabled = configLists.find((c) => c.enabled);
592876
+ if (enabled)
592877
+ return { id: enabled.id, title: enabled.name };
592878
+ return null;
592879
+ }
592880
+ const byName = configLists.find((c) => c.name === listOption);
592881
+ if (byName)
592882
+ return { id: byName.id, title: byName.name };
592883
+ const byId = configLists.find((c) => c.id === listOption);
592884
+ if (byId)
592885
+ return { id: byId.id, title: byId.name };
592886
+ return null;
592887
+ }
592888
+ async function resolveTaskList(client, configLists, listOption) {
592889
+ const fromConfig = resolveTaskListFromConfig(configLists, listOption);
592890
+ if (fromConfig)
592891
+ return fromConfig;
592892
+ if (listOption) {
592893
+ const apiLists = await listTaskLists(client);
592894
+ const byTitle = apiLists.find((l) => l.title === listOption);
592895
+ if (byTitle)
592896
+ return { id: byTitle.id, title: byTitle.title };
592897
+ return { id: listOption, title: listOption };
592898
+ }
592899
+ return { id: "@default", title: "My Tasks" };
592900
+ }
592901
+
592902
+ // src/commands/tasks/list.ts
592903
+ function isValidDateString(value) {
592904
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value))
592905
+ return false;
592906
+ const date3 = new Date(`${value}T00:00:00Z`);
592907
+ if (Number.isNaN(date3.getTime()))
592908
+ return false;
592909
+ return date3.toISOString().startsWith(value);
592910
+ }
592911
+ function formatDueInfo(task) {
592912
+ const parts = [];
592913
+ if (task.due) {
592914
+ const month = task.due.slice(5, 7);
592915
+ const day = task.due.slice(8, 10);
592916
+ parts.push(`due: ${month}/${day}`);
592917
+ }
592918
+ if (task.status === "completed" && task.completed) {
592919
+ const month = task.completed.slice(5, 7);
592920
+ const day = task.completed.slice(8, 10);
592921
+ parts.push(`completed: ${month}/${day}`);
592922
+ }
592923
+ return parts.length > 0 ? ` (${parts.join(", ")})` : "";
592924
+ }
592925
+ function formatTaskLine(task) {
592926
+ const checkbox = task.status === "completed" ? "☑" : "□";
592927
+ return `${checkbox} ${task.title}${formatDueInfo(task)}`;
592928
+ }
592929
+ function formatTaskListText2(listTitle, tasks) {
592930
+ const lines = [`${listTitle}:`];
592931
+ for (const task of tasks) {
592932
+ lines.push(` ${formatTaskLine(task)}`);
592933
+ if (task.notes) {
592934
+ const firstLine = task.notes.split(`
592935
+ `)[0];
592936
+ lines.push(` Notes: ${firstLine}`);
592937
+ }
592938
+ }
592939
+ return lines.join(`
592940
+ `);
592941
+ }
592942
+ function formatQuietTaskList(tasks) {
592943
+ return tasks.map((task) => formatTaskLine(task)).join(`
592944
+ `);
592945
+ }
592946
+ function filterTasks(tasks, options) {
592947
+ let filtered = tasks;
592948
+ if (options.completed) {
592949
+ filtered = filtered.filter((t) => t.status === "completed");
592950
+ } else if (!options.all) {
592951
+ filtered = filtered.filter((t) => t.status === "needsAction");
592952
+ }
592953
+ if (options.dueBefore) {
592954
+ filtered = filtered.filter((t) => t.due !== null && t.due <= options.dueBefore);
592955
+ }
592956
+ if (options.dueAfter) {
592957
+ filtered = filtered.filter((t) => t.due !== null && t.due >= options.dueAfter);
592958
+ }
592959
+ return filtered;
592960
+ }
592961
+ async function handleTaskList(opts) {
592962
+ const { client, format: format4, quiet, write, configTaskLists, all, completed, dueBefore, dueAfter } = opts;
592963
+ if (dueBefore !== undefined && !isValidDateString(dueBefore)) {
592964
+ write(`Error: Invalid date for --due-before: "${dueBefore}". Expected format: YYYY-MM-DD`);
592965
+ return { exitCode: ExitCode.ARGUMENT };
592966
+ }
592967
+ if (dueAfter !== undefined && !isValidDateString(dueAfter)) {
592968
+ write(`Error: Invalid date for --due-after: "${dueAfter}". Expected format: YYYY-MM-DD`);
592969
+ return { exitCode: ExitCode.ARGUMENT };
592970
+ }
592971
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
592972
+ const apiOptions = {};
592973
+ if (all || completed) {
592974
+ apiOptions.showCompleted = true;
592975
+ apiOptions.showHidden = true;
592976
+ }
592977
+ const allTasks = await listTasks(client, resolved.id, resolved.title, apiOptions);
592978
+ const filterOpts = {
592979
+ all: all ?? false,
592980
+ completed: completed ?? false
592538
592981
  };
592982
+ if (dueBefore !== undefined)
592983
+ filterOpts.dueBefore = dueBefore;
592984
+ if (dueAfter !== undefined)
592985
+ filterOpts.dueAfter = dueAfter;
592986
+ const tasks = filterTasks(allTasks, filterOpts);
592987
+ if (quiet) {
592988
+ write(formatQuietTaskList(tasks));
592989
+ return { exitCode: ExitCode.SUCCESS };
592990
+ }
592991
+ if (format4 === "json") {
592992
+ write(formatJsonSuccess({
592993
+ tasks,
592994
+ count: tasks.length,
592995
+ list_id: resolved.id,
592996
+ list_title: resolved.title
592997
+ }));
592998
+ } else {
592999
+ write(formatTaskListText2(resolved.title, tasks));
593000
+ }
593001
+ return { exitCode: ExitCode.SUCCESS };
593002
+ }
593003
+
593004
+ // src/commands/tasks/show.ts
593005
+ var LABEL_WIDTH = 11;
593006
+ function detailLine2(label, value) {
593007
+ return `${label}:`.padEnd(LABEL_WIDTH) + value;
593008
+ }
593009
+ function stripMilliseconds(iso) {
593010
+ return iso.replace(/\.\d{3}Z$/, "Z");
593011
+ }
593012
+ function formatTaskDetailText(task) {
593013
+ const lines = [];
593014
+ lines.push(detailLine2("ID", task.id));
593015
+ lines.push(detailLine2("Title", task.title));
593016
+ lines.push(detailLine2("Status", task.status));
593017
+ if (task.due) {
593018
+ lines.push(detailLine2("Due", task.due));
593019
+ }
593020
+ if (task.notes) {
593021
+ lines.push(detailLine2("Notes", task.notes));
593022
+ }
593023
+ lines.push(detailLine2("List", task.list_title));
593024
+ lines.push(detailLine2("Updated", stripMilliseconds(task.updated)));
593025
+ return lines.join(`
593026
+ `);
593027
+ }
593028
+ async function handleTaskShow(opts) {
593029
+ const { client, taskId, format: format4, quiet, write, configTaskLists } = opts;
593030
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593031
+ const task = await getTask(client, resolved.id, resolved.title, taskId);
593032
+ if (format4 === "json") {
593033
+ write(formatJsonSuccess({ task }));
593034
+ } else if (quiet) {
593035
+ write(`${task.title} ${task.status} ${task.due ?? ""}`);
593036
+ } else {
593037
+ write(formatTaskDetailText(task));
593038
+ }
593039
+ return { exitCode: ExitCode.SUCCESS };
593040
+ }
593041
+
593042
+ // src/commands/tasks/add.ts
593043
+ function isValidDateString2(value) {
593044
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value))
593045
+ return false;
593046
+ const date3 = new Date(`${value}T00:00:00Z`);
593047
+ if (Number.isNaN(date3.getTime()))
593048
+ return false;
593049
+ return date3.toISOString().startsWith(value);
593050
+ }
593051
+ async function handleTaskAdd(opts) {
593052
+ const { client, title, format: format4, quiet, write, configTaskLists } = opts;
593053
+ if (!title) {
593054
+ const msg = "--title is required";
593055
+ if (format4 === "json") {
593056
+ write(formatJsonError("INVALID_ARGS", msg));
593057
+ } else {
593058
+ write(`Error: ${msg}`);
593059
+ }
593060
+ return { exitCode: ExitCode.ARGUMENT };
593061
+ }
593062
+ if (opts.due !== undefined && !isValidDateString2(opts.due)) {
593063
+ const msg = `Invalid date format: ${opts.due} (expected YYYY-MM-DD)`;
593064
+ if (format4 === "json") {
593065
+ write(formatJsonError("INVALID_ARGS", msg));
593066
+ } else {
593067
+ write(`Error: ${msg}`);
593068
+ }
593069
+ return { exitCode: ExitCode.ARGUMENT };
593070
+ }
593071
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593072
+ const input = { title };
593073
+ if (opts.notes !== undefined) {
593074
+ input.notes = opts.notes;
593075
+ }
593076
+ if (opts.due !== undefined) {
593077
+ input.due = `${opts.due}T00:00:00.000Z`;
593078
+ }
593079
+ if (opts.parent !== undefined) {
593080
+ input.parent = opts.parent;
593081
+ }
593082
+ const task = await createTask(client, resolved.id, resolved.title, input);
593083
+ if (format4 === "json") {
593084
+ write(formatJsonSuccess({ task, message: "Task created" }));
593085
+ } else if (quiet) {
593086
+ write(task.id);
593087
+ } else {
593088
+ write(`Task created: ${task.title} (${task.id})`);
593089
+ }
593090
+ return { exitCode: ExitCode.SUCCESS };
593091
+ }
593092
+
593093
+ // src/commands/tasks/update.ts
593094
+ function isValidDateString3(value) {
593095
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(value))
593096
+ return false;
593097
+ const date3 = new Date(`${value}T00:00:00Z`);
593098
+ if (Number.isNaN(date3.getTime()))
593099
+ return false;
593100
+ return date3.toISOString().startsWith(value);
593101
+ }
593102
+ async function handleTaskUpdate(opts) {
593103
+ const { client, taskId, format: format4, quiet, write, configTaskLists } = opts;
593104
+ const hasUpdate = opts.title !== undefined || opts.notes !== undefined || opts.due !== undefined;
593105
+ if (!hasUpdate) {
593106
+ const msg = "at least one update option must be provided (--title, --notes, or --due)";
593107
+ if (format4 === "json") {
593108
+ write(formatJsonError("INVALID_ARGS", msg));
593109
+ } else {
593110
+ write(`Error: ${msg}`);
593111
+ }
593112
+ return { exitCode: ExitCode.ARGUMENT };
593113
+ }
593114
+ if (opts.due !== undefined && !isValidDateString3(opts.due)) {
593115
+ const msg = `Invalid date format: ${opts.due} (expected YYYY-MM-DD)`;
593116
+ if (format4 === "json") {
593117
+ write(formatJsonError("INVALID_ARGS", msg));
593118
+ } else {
593119
+ write(`Error: ${msg}`);
593120
+ }
593121
+ return { exitCode: ExitCode.ARGUMENT };
593122
+ }
593123
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593124
+ const input = {};
593125
+ if (opts.title !== undefined) {
593126
+ input.title = opts.title;
593127
+ }
593128
+ if (opts.notes !== undefined) {
593129
+ input.notes = opts.notes;
593130
+ }
593131
+ if (opts.due !== undefined) {
593132
+ input.due = `${opts.due}T00:00:00.000Z`;
593133
+ }
593134
+ const task = await updateTask(client, resolved.id, resolved.title, taskId, input);
593135
+ if (format4 === "json") {
593136
+ write(formatJsonSuccess({ task, message: "Task updated" }));
593137
+ } else if (quiet) {
593138
+ write(task.id);
593139
+ } else {
593140
+ write(`Task updated: ${task.title} (${task.id})`);
593141
+ }
593142
+ return { exitCode: ExitCode.SUCCESS };
593143
+ }
593144
+
593145
+ // src/commands/tasks/done.ts
593146
+ async function handleTaskDone(opts) {
593147
+ const { client, taskId, format: format4, quiet, write, configTaskLists } = opts;
593148
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593149
+ const task = await completeTask(client, resolved.id, resolved.title, taskId);
593150
+ if (format4 === "json") {
593151
+ write(formatJsonSuccess({ task, message: "Task completed" }));
593152
+ } else if (quiet) {
593153
+ write(task.id);
593154
+ } else {
593155
+ write(`Task completed: ${task.title} (${task.id})`);
593156
+ }
593157
+ return { exitCode: ExitCode.SUCCESS };
593158
+ }
593159
+
593160
+ // src/commands/tasks/undone.ts
593161
+ async function handleTaskUndone(opts) {
593162
+ const { client, taskId, format: format4, quiet, write, configTaskLists } = opts;
593163
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593164
+ const task = await uncompleteTask(client, resolved.id, resolved.title, taskId);
593165
+ if (format4 === "json") {
593166
+ write(formatJsonSuccess({ task, message: "Task reopened" }));
593167
+ } else if (quiet) {
593168
+ write(task.id);
593169
+ } else {
593170
+ write(`Task reopened: ${task.title} (${task.id})`);
593171
+ }
593172
+ return { exitCode: ExitCode.SUCCESS };
593173
+ }
593174
+
593175
+ // src/commands/tasks/delete.ts
593176
+ async function handleTaskDelete(opts) {
593177
+ const { client, taskId, format: format4, quiet, write, configTaskLists } = opts;
593178
+ const resolved = await resolveTaskList(client, configTaskLists, opts.list);
593179
+ await deleteTask(client, resolved.id, taskId);
593180
+ if (!quiet) {
593181
+ if (format4 === "json") {
593182
+ write(formatJsonSuccess({ deleted_id: taskId, message: "Task deleted" }));
593183
+ } else {
593184
+ write(`Task deleted (${taskId})`);
593185
+ }
593186
+ }
593187
+ return { exitCode: ExitCode.SUCCESS };
592539
593188
  }
592540
593189
 
592541
593190
  // src/cli.ts
@@ -592550,7 +593199,6 @@ function resolveGlobalOptions2(program2) {
592550
593199
  }
592551
593200
  return {
592552
593201
  format: formatResult.data,
592553
- calendar: raw.calendar,
592554
593202
  timezone: raw.timezone,
592555
593203
  quiet: raw.quiet
592556
593204
  };
@@ -592625,6 +593273,25 @@ async function resolveEventCalendar(api2, eventId, calendars) {
592625
593273
  }
592626
593274
 
592627
593275
  // src/commands/index.ts
593276
+ async function runTaskAction(program2, handler) {
593277
+ const globalOpts = resolveGlobalOptions2(program2);
593278
+ try {
593279
+ const config2 = loadConfig(fsAdapter);
593280
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593281
+ const client = createGoogleTasksClient(import_googleapis2.google.tasks({ version: "v1", auth: oauth2Client }));
593282
+ const result = await handler({
593283
+ client,
593284
+ format: globalOpts.format,
593285
+ quiet: globalOpts.quiet,
593286
+ write: (msg) => process.stdout.write(msg + `
593287
+ `),
593288
+ configTaskLists: config2.task_lists
593289
+ });
593290
+ process.exit(result.exitCode);
593291
+ } catch (error) {
593292
+ handleError2(error, globalOpts.format);
593293
+ }
593294
+ }
592628
593295
  function registerCommands(program2) {
592629
593296
  const authCmd = createAuthCommand();
592630
593297
  authCmd.action(async () => {
@@ -592663,28 +593330,175 @@ ${url}`);
592663
593330
  const calendarsCmd = createCalendarsCommand();
592664
593331
  calendarsCmd.action(async () => {
592665
593332
  const globalOpts = resolveGlobalOptions2(program2);
592666
- const config2 = loadConfig(fsAdapter);
592667
- const oauth2Client = await getAuthenticatedClient(fsAdapter);
592668
- const calendar = import_googleapis2.google.calendar({ version: "v3", auth: oauth2Client });
592669
- const api2 = createGoogleCalendarApi(calendar);
592670
- const result = await handleCalendars({
592671
- api: api2,
592672
- format: globalOpts.format,
592673
- quiet: globalOpts.quiet,
592674
- write: (msg) => process.stdout.write(msg + `
593333
+ try {
593334
+ const config2 = loadConfig(fsAdapter);
593335
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593336
+ const calendar = import_googleapis2.google.calendar({ version: "v3", auth: oauth2Client });
593337
+ const api2 = createGoogleCalendarApi(calendar);
593338
+ const result = await handleCalendars({
593339
+ api: api2,
593340
+ format: globalOpts.format,
593341
+ quiet: globalOpts.quiet,
593342
+ write: (msg) => process.stdout.write(msg + `
592675
593343
  `),
592676
- configCalendars: config2.calendars
592677
- });
592678
- process.exit(result.exitCode);
593344
+ configCalendars: config2.calendars
593345
+ });
593346
+ process.exit(result.exitCode);
593347
+ } catch (error) {
593348
+ handleError2(error, globalOpts.format);
593349
+ }
592679
593350
  });
592680
593351
  program2.addCommand(calendarsCmd);
593352
+ const {
593353
+ tasksCmd,
593354
+ listsCmd: tasksListsCmd,
593355
+ listCmd: tasksListCmd,
593356
+ showCmd: tasksShowCmd,
593357
+ addCmd: tasksAddCmd,
593358
+ updateCmd: tasksUpdateCmd,
593359
+ doneCmd: tasksDoneCmd,
593360
+ undoneCmd: tasksUndoneCmd,
593361
+ deleteCmd: tasksDeleteCmd
593362
+ } = createTasksCommand();
593363
+ tasksListsCmd.action(async () => {
593364
+ const globalOpts = resolveGlobalOptions2(program2);
593365
+ try {
593366
+ const config2 = loadConfig(fsAdapter);
593367
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593368
+ const tasksClient = createGoogleTasksClient(import_googleapis2.google.tasks({ version: "v1", auth: oauth2Client }));
593369
+ const result = await handleTaskLists({
593370
+ client: tasksClient,
593371
+ format: globalOpts.format,
593372
+ quiet: globalOpts.quiet,
593373
+ write: (msg) => process.stdout.write(msg + `
593374
+ `),
593375
+ configTaskLists: config2.task_lists
593376
+ });
593377
+ process.exit(result.exitCode);
593378
+ } catch (error) {
593379
+ handleError2(error, globalOpts.format);
593380
+ }
593381
+ });
593382
+ tasksListCmd.action(async () => {
593383
+ const globalOpts = resolveGlobalOptions2(program2);
593384
+ const listOpts = tasksListCmd.opts();
593385
+ try {
593386
+ const config2 = loadConfig(fsAdapter);
593387
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593388
+ const tasksClient = createGoogleTasksClient(import_googleapis2.google.tasks({ version: "v1", auth: oauth2Client }));
593389
+ const opts = {
593390
+ client: tasksClient,
593391
+ format: globalOpts.format,
593392
+ quiet: globalOpts.quiet,
593393
+ write: (msg) => process.stdout.write(msg + `
593394
+ `),
593395
+ configTaskLists: config2.task_lists
593396
+ };
593397
+ if (listOpts.list !== undefined)
593398
+ opts.list = listOpts.list;
593399
+ if (listOpts.all)
593400
+ opts.all = true;
593401
+ if (listOpts.completed)
593402
+ opts.completed = true;
593403
+ if (listOpts.dueBefore !== undefined)
593404
+ opts.dueBefore = listOpts.dueBefore;
593405
+ if (listOpts.dueAfter !== undefined)
593406
+ opts.dueAfter = listOpts.dueAfter;
593407
+ const result = await handleTaskList(opts);
593408
+ process.exit(result.exitCode);
593409
+ } catch (error) {
593410
+ handleError2(error, globalOpts.format);
593411
+ }
593412
+ });
593413
+ tasksShowCmd.action(async (taskId) => {
593414
+ const globalOpts = resolveGlobalOptions2(program2);
593415
+ const showOpts = tasksShowCmd.opts();
593416
+ try {
593417
+ const config2 = loadConfig(fsAdapter);
593418
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593419
+ const tasksClient = createGoogleTasksClient(import_googleapis2.google.tasks({ version: "v1", auth: oauth2Client }));
593420
+ const opts = {
593421
+ client: tasksClient,
593422
+ taskId,
593423
+ format: globalOpts.format,
593424
+ quiet: globalOpts.quiet,
593425
+ write: (msg) => process.stdout.write(msg + `
593426
+ `),
593427
+ configTaskLists: config2.task_lists
593428
+ };
593429
+ if (showOpts.list !== undefined)
593430
+ opts.list = showOpts.list;
593431
+ const result = await handleTaskShow(opts);
593432
+ process.exit(result.exitCode);
593433
+ } catch (error) {
593434
+ handleError2(error, globalOpts.format);
593435
+ }
593436
+ });
593437
+ tasksAddCmd.action(async () => {
593438
+ const addOpts = tasksAddCmd.opts();
593439
+ await runTaskAction(program2, (deps) => {
593440
+ const opts = { ...deps, title: addOpts.title };
593441
+ if (addOpts.notes !== undefined)
593442
+ opts.notes = addOpts.notes;
593443
+ if (addOpts.due !== undefined)
593444
+ opts.due = addOpts.due;
593445
+ if (addOpts.list !== undefined)
593446
+ opts.list = addOpts.list;
593447
+ if (addOpts.parent !== undefined)
593448
+ opts.parent = addOpts.parent;
593449
+ return handleTaskAdd(opts);
593450
+ });
593451
+ });
593452
+ tasksUpdateCmd.action(async (taskId) => {
593453
+ const updateOpts = tasksUpdateCmd.opts();
593454
+ await runTaskAction(program2, (deps) => {
593455
+ const opts = { ...deps, taskId };
593456
+ if (updateOpts.title !== undefined)
593457
+ opts.title = updateOpts.title;
593458
+ if (updateOpts.notes !== undefined)
593459
+ opts.notes = updateOpts.notes;
593460
+ if (updateOpts.due !== undefined)
593461
+ opts.due = updateOpts.due;
593462
+ if (updateOpts.list !== undefined)
593463
+ opts.list = updateOpts.list;
593464
+ return handleTaskUpdate(opts);
593465
+ });
593466
+ });
593467
+ tasksDoneCmd.action(async (taskId) => {
593468
+ const doneOpts = tasksDoneCmd.opts();
593469
+ await runTaskAction(program2, (deps) => {
593470
+ const opts = { ...deps, taskId };
593471
+ if (doneOpts.list !== undefined)
593472
+ opts.list = doneOpts.list;
593473
+ return handleTaskDone(opts);
593474
+ });
593475
+ });
593476
+ tasksUndoneCmd.action(async (taskId) => {
593477
+ const undoneOpts = tasksUndoneCmd.opts();
593478
+ await runTaskAction(program2, (deps) => {
593479
+ const opts = { ...deps, taskId };
593480
+ if (undoneOpts.list !== undefined)
593481
+ opts.list = undoneOpts.list;
593482
+ return handleTaskUndone(opts);
593483
+ });
593484
+ });
593485
+ tasksDeleteCmd.action(async (taskId) => {
593486
+ const deleteOpts = tasksDeleteCmd.opts();
593487
+ await runTaskAction(program2, (deps) => {
593488
+ const opts = { ...deps, taskId };
593489
+ if (deleteOpts.list !== undefined)
593490
+ opts.list = deleteOpts.list;
593491
+ return handleTaskDelete(opts);
593492
+ });
593493
+ });
593494
+ program2.addCommand(tasksCmd);
592681
593495
  const listCmd = createListCommand();
592682
593496
  listCmd.action(async () => {
592683
593497
  const globalOpts = resolveGlobalOptions2(program2);
592684
593498
  const listOpts = listCmd.opts();
592685
593499
  try {
592686
593500
  const auth = await getAuthenticatedClient(fsAdapter);
592687
- const api2 = import_googleapis2.google.calendar({ version: "v3", auth });
593501
+ const api2 = createGoogleCalendarApi(import_googleapis2.google.calendar({ version: "v3", auth }));
592688
593502
  const deps = {
592689
593503
  listEvents: (calendarId, calendarName, options) => listEvents(api2, calendarId, calendarName, options),
592690
593504
  loadConfig: () => loadConfig(fsAdapter),
@@ -592696,8 +593510,7 @@ ${url}`);
592696
593510
  const handleOpts = {
592697
593511
  ...listOpts,
592698
593512
  format: globalOpts.format,
592699
- quiet: globalOpts.quiet,
592700
- calendar: globalOpts.calendar
593513
+ quiet: globalOpts.quiet
592701
593514
  };
592702
593515
  if (globalOpts.timezone)
592703
593516
  handleOpts.timezone = globalOpts.timezone;
@@ -592718,11 +593531,12 @@ ${url}`);
592718
593531
  const calendarApi = import_googleapis2.google.calendar({ version: "v3", auth });
592719
593532
  const api2 = createGoogleCalendarApi(calendarApi);
592720
593533
  const timezone = resolveTimezone(globalOpts.timezone, config2.timezone);
592721
- const calendars = selectCalendars(globalOpts.calendar, config2);
593534
+ const calendars = selectCalendars(searchOpts.calendar.length > 0 ? searchOpts.calendar : undefined, config2);
592722
593535
  const result = await handleSearch({
592723
593536
  api: api2,
592724
593537
  query,
592725
593538
  format: globalOpts.format,
593539
+ quiet: globalOpts.quiet,
592726
593540
  calendars,
592727
593541
  timezone,
592728
593542
  days: searchOpts.days,
@@ -592744,7 +593558,7 @@ ${url}`);
592744
593558
  });
592745
593559
  program2.addCommand(searchCmd);
592746
593560
  const showCmd = createShowCommand();
592747
- showCmd.action(async () => {
593561
+ showCmd.action(async (eventId) => {
592748
593562
  const globalOpts = resolveGlobalOptions2(program2);
592749
593563
  const showOpts = showCmd.opts();
592750
593564
  try {
@@ -592752,23 +593566,24 @@ ${url}`);
592752
593566
  const auth = await getAuthenticatedClient(fsAdapter);
592753
593567
  const calendarApi = import_googleapis2.google.calendar({ version: "v3", auth });
592754
593568
  const api2 = createGoogleCalendarApi(calendarApi);
592755
- const calendarId = showOpts.calendar ?? (globalOpts.calendar.length > 0 ? globalOpts.calendar[0] : undefined);
593569
+ const calendarId = showOpts.calendar;
592756
593570
  let cal;
592757
593571
  if (calendarId) {
592758
593572
  const found = config2.calendars.find((c) => c.id === calendarId);
592759
593573
  cal = found ? { id: found.id, name: found.name } : { id: calendarId, name: calendarId };
592760
593574
  } else {
592761
593575
  const calendars = selectCalendars(undefined, config2);
592762
- const resolved = await resolveEventCalendar(api2, showCmd.args[0], calendars);
593576
+ const resolved = await resolveEventCalendar(api2, eventId, calendars);
592763
593577
  cal = resolved;
592764
593578
  }
592765
593579
  const timezone = resolveTimezone(globalOpts.timezone, config2.timezone);
592766
593580
  const result = await handleShow({
592767
593581
  api: api2,
592768
- eventId: showCmd.args[0],
593582
+ eventId,
592769
593583
  calendarId: cal.id,
592770
593584
  calendarName: cal.name,
592771
593585
  format: globalOpts.format,
593586
+ quiet: globalOpts.quiet,
592772
593587
  timezone,
592773
593588
  write: (msg) => process.stdout.write(msg + `
592774
593589
  `)
@@ -592789,8 +593604,8 @@ ${url}`);
592789
593604
  const calendarApi = import_googleapis2.google.calendar({ version: "v3", auth });
592790
593605
  const api2 = createGoogleCalendarApi(calendarApi);
592791
593606
  let resolvedCalendarId;
592792
- if (deleteOpts.calendar || globalOpts.calendar.length > 0) {
592793
- const calendars = selectCalendars(deleteOpts.calendar ? [deleteOpts.calendar] : globalOpts.calendar, config2);
593607
+ if (deleteOpts.calendar) {
593608
+ const calendars = selectCalendars([deleteOpts.calendar], config2);
592794
593609
  resolvedCalendarId = calendars[0]?.id ?? "primary";
592795
593610
  } else {
592796
593611
  const calendars = selectCalendars(undefined, config2);
@@ -592834,10 +593649,12 @@ ${url}`);
592834
593649
  description: addOpts.description,
592835
593650
  busy: addOpts.busy,
592836
593651
  free: addOpts.free,
593652
+ dryRun: addOpts.dryRun,
593653
+ quiet: globalOpts.quiet,
592837
593654
  format: globalOpts.format
592838
593655
  };
592839
- if (globalOpts.calendar?.[0])
592840
- handleOpts.calendar = globalOpts.calendar[0];
593656
+ if (addOpts.calendar)
593657
+ handleOpts.calendar = addOpts.calendar;
592841
593658
  if (globalOpts.timezone)
592842
593659
  handleOpts.timezone = globalOpts.timezone;
592843
593660
  const result = await handleAdd(handleOpts, deps);
@@ -592868,6 +593685,11 @@ ${url}`);
592868
593685
  const api2 = await getApi();
592869
593686
  return listCalendars(api2);
592870
593687
  },
593688
+ listTaskLists: async () => {
593689
+ const oauth2Client = await getAuthenticatedClient(fsAdapter);
593690
+ const tasksClient = createGoogleTasksClient(import_googleapis2.google.tasks({ version: "v1", auth: oauth2Client }));
593691
+ return listTaskLists(tasksClient);
593692
+ },
592871
593693
  requestAuth: async () => {
592872
593694
  apiRef = null;
592873
593695
  const promptFn = createReadlinePrompt();
@@ -592887,6 +593709,8 @@ ${authUrl}`);
592887
593709
  format: globalOpts.format,
592888
593710
  quiet: globalOpts.quiet,
592889
593711
  write,
593712
+ writeErr: (msg) => process.stderr.write(msg + `
593713
+ `),
592890
593714
  force: initOpts.force ?? false,
592891
593715
  all: initOpts.all ?? false,
592892
593716
  local: initOpts.local ?? false,
@@ -592910,8 +593734,8 @@ ${authUrl}`);
592910
593734
  const timezone = resolveTimezone(globalOpts.timezone, config2.timezone);
592911
593735
  const updateOpsCalendar = updateOpts.calendar;
592912
593736
  let cal;
592913
- if (updateOpsCalendar || globalOpts.calendar.length > 0) {
592914
- const calendars = selectCalendars(updateOpsCalendar ? [updateOpsCalendar] : globalOpts.calendar, config2);
593737
+ if (updateOpsCalendar) {
593738
+ const calendars = selectCalendars([updateOpsCalendar], config2);
592915
593739
  cal = calendars[0];
592916
593740
  } else {
592917
593741
  const calendars = selectCalendars(undefined, config2);
@@ -592924,6 +593748,7 @@ ${authUrl}`);
592924
593748
  calendarId: cal.id,
592925
593749
  calendarName: cal.name,
592926
593750
  format: globalOpts.format,
593751
+ quiet: globalOpts.quiet,
592927
593752
  timezone,
592928
593753
  write: (msg) => process.stdout.write(msg + `
592929
593754
  `),