@mgcrea/mcp-apple-calendar 1.16.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { A as BUILD_INFO, C as CALENDAR_SURFACE, a as loadConfig, r as createServer } from "./server-BgyYeCba.js";
2
+ import { A as BUILD_INFO, C as CALENDAR_SURFACE, a as loadConfig, r as createServer } from "./server-CLAGQcwG.js";
3
3
  import { runStdioServer } from "@mgcrea/mcp-apple-core";
4
4
  //#region src/cli.ts
5
5
  const LOG_PREFIX = "apple-calendar-mcp";
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AppBusyError as CalendarBusyError, AppNotRunningError as CalendarNotRunningError, AppleAutomationError, AppleAutomationError as AppleCalendarError, BuildInfo, Logger, OsascriptRunner, ReadOnlyMode, StoreFacts, SurfaceContext } from "@mgcrea/mcp-apple-core";
1
+ import { AppBusyError as CalendarBusyError, AppNotRunningError as CalendarNotRunningError, AppleAutomationError, AppleAutomationError as AppleCalendarError, BuildInfo, InvalidDateError, Logger, OsascriptRunner, ReadOnlyMode, StoreFacts, SurfaceContext } from "@mgcrea/mcp-apple-core";
2
2
  import { z } from "zod";
3
3
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
4
  import { DatabaseSync } from "node:sqlite";
@@ -221,13 +221,6 @@ declare const WEEKDAY_KEYS: readonly ["sun", "mon", "tue", "wed", "thu", "fri",
221
221
  type WeekdayKey = (typeof WEEKDAY_KEYS)[number];
222
222
  //#endregion
223
223
  //#region src/client/dates.d.ts
224
- /**
225
- * What a tool reports for an event's start or end.
226
- *
227
- * A union rather than one struct with an `allDay` flag: an all-day event names
228
- * a DAY and has no instant, and giving it an `iso` field would invite callers to
229
- * read one. The type makes that impossible instead of merely discouraged.
230
- */
231
224
  type EventInstant = {
232
225
  allDay: true;
233
226
  day: string;
@@ -362,6 +355,16 @@ type EventDetail = EventSummary & {
362
355
  };
363
356
  type EventPage = {
364
357
  events: EventSummary[];
358
+ /**
359
+ * More events matched the window than fit under `limit`.
360
+ *
361
+ * Distinct from `truncated`, which is about the store's expansion COVERAGE
362
+ * running out. Both mean "this is not the whole picture" and they mean it for
363
+ * different reasons, so collapsing them would leave a caller unable to tell a
364
+ * dense day from an unexpanded one — and a short list of events is
365
+ * indistinguishable from a free afternoon.
366
+ */
367
+ hasMore: boolean;
365
368
  expansion: ExpansionState;
366
369
  expansionReason?: string;
367
370
  /** The window actually queried, echoed so a clamp is visible. */
@@ -617,16 +620,6 @@ declare class AppleCalendarClient {
617
620
  declare const CALENDAR_SURFACE: SurfaceContext;
618
621
  /** Calendar's Apple Events target. Not `com.apple.Calendar`, which does not exist. */
619
622
  declare const CALENDAR_BUNDLE_ID = "com.apple.iCal";
620
- /**
621
- * A date argument could not be understood.
622
- *
623
- * Carries the accepted grammar rather than just rejecting, because the caller is
624
- * usually a model that will retry once and needs to know what shape to retry in.
625
- */
626
- declare class InvalidDateError extends AppleAutomationError {
627
- readonly name = "InvalidDateError";
628
- constructor(field: string, raw: string, reason: string);
629
- }
630
623
  /** A CalendarRef no longer resolves — deleted, or moved to another calendar. */
631
624
  declare class EventNotFoundError extends AppleAutomationError {
632
625
  readonly name = "EventNotFoundError";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-info.ts","../src/client/store.ts","../src/config.ts","../src/client/availability.ts","../src/client/dates.ts","../src/client/locate.ts","../src/client/recurrence.ts","../src/client/calendar.ts","../src/client/errors.ts","../src/client/ref.ts","../src/server.ts","../src/tools/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/build-info.ts","../src/client/store.ts","../src/config.ts","../src/client/availability.ts","../src/client/dates.ts","../src/client/locate.ts","../src/client/recurrence.ts","../src/client/calendar.ts","../src/client/errors.ts","../src/client/ref.ts","../src/server.ts","../src/tools/index.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { A as BUILD_INFO, C as CALENDAR_SURFACE, D as CalendarNotWritableError, E as CalendarNotRunningError, O as EventNotFoundError, S as CALENDAR_BUNDLE_ID, T as CalendarNotFoundError, _ as STORE_FILENAME, a as loadConfig, b as locateStore, c as introspect, d as decodeRef, f as encodeRef, g as GROUP_CONTAINER, h as EXTRAS_FILENAME, i as registerTools, k as InvalidDateError, l as openStore, m as uuidOf, n as SERVER_VERSION, o as AppleCalendarClient, p as seriesRefOf, r as createServer, s as CalendarStore, t as SERVER_NAME, u as REF_VERSION, v as defaultContainerPath, w as CalendarBusyError, x as AppleCalendarError, y as defaultStorePath } from "./server-BgyYeCba.js";
1
+ import { A as BUILD_INFO, C as CALENDAR_SURFACE, D as CalendarNotWritableError, E as CalendarNotRunningError, O as EventNotFoundError, S as CALENDAR_BUNDLE_ID, T as CalendarNotFoundError, _ as STORE_FILENAME, a as loadConfig, b as locateStore, c as introspect, d as decodeRef, f as encodeRef, g as GROUP_CONTAINER, h as EXTRAS_FILENAME, i as registerTools, k as InvalidDateError, l as openStore, m as uuidOf, n as SERVER_VERSION, o as AppleCalendarClient, p as seriesRefOf, r as createServer, s as CalendarStore, t as SERVER_NAME, u as REF_VERSION, v as defaultContainerPath, w as CalendarBusyError, x as AppleCalendarError, y as defaultStorePath } from "./server-CLAGQcwG.js";
2
2
  export { AppleCalendarClient, AppleCalendarError, BUILD_INFO, CALENDAR_BUNDLE_ID, CALENDAR_SURFACE, CalendarBusyError, CalendarNotFoundError, CalendarNotRunningError, CalendarNotWritableError, CalendarStore, EXTRAS_FILENAME, EventNotFoundError, GROUP_CONTAINER, InvalidDateError, REF_VERSION, SERVER_NAME, SERVER_VERSION, STORE_FILENAME, createServer, decodeRef, defaultContainerPath, defaultStorePath, encodeRef, introspect, loadConfig, locateStore, openStore, registerTools, seriesRefOf, uuidOf };
@@ -1,4 +1,4 @@
1
- import { AppBusyError as CalendarBusyError, AppNotRunningError as CalendarNotRunningError, AppleAutomationError, AppleAutomationError as AppleCalendarError, BaseConfigSchema, CORE_DATA_EPOCH_OFFSET, IndexUnavailableError, PreconditionError, SchemaDriftError, columnsOf, confirmArg, createOsascriptRunner, describeStore, escapeLike, fingerprintSchema, limitArg, ok, openReadOnly, parseBool, parseConfig, parseIntOpt, parseList, promptArg, readPackageIdentity, registerSurfaceResources, registerWorkflowPrompt, requiredPromptArg, resolveLimit, trimmed, withBusyRetry, withLazyTools, wrap } from "@mgcrea/mcp-apple-core";
1
+ import { AppBusyError as CalendarBusyError, AppNotRunningError as CalendarNotRunningError, AppleAutomationError, AppleAutomationError as AppleCalendarError, BaseConfigSchema, CORE_DATA_EPOCH_OFFSET, IndexUnavailableError, InvalidDateError, PreconditionError, SchemaDriftError, addLocalDays, columnsOf, confirmArg, createOsascriptRunner, describeStore, escapeLike, fingerprintSchema, limitArg, ok, openReadOnly, parseBool, parseBound, parseBound as parseBound$1, parseConfig, parseDate, parseIntOpt, parseList, promptArg, readPackageIdentity, registerSurfaceResources, registerWorkflowPrompt, requiredPromptArg, resolveLimit, startOfLocalDay, toLocalIso, toLocalIso as toLocalIso$1, trimmed, withBusyRetry, withLazyTools, wrap } from "@mgcrea/mcp-apple-core";
2
2
  import { readdirSync } from "node:fs";
3
3
  import { homedir } from "node:os";
4
4
  import { join } from "node:path";
@@ -12,8 +12,8 @@ const pkg = readPackageIdentity(new URL("../package.json", import.meta.url), {
12
12
  const BUILD_INFO = {
13
13
  name: pkg.name,
14
14
  version: pkg.version,
15
- gitCommit: "d70b8e4",
16
- gitCommitDate: "2026-09-06T12:13:21+02:00"
15
+ gitCommit: "657cbf0",
16
+ gitCommitDate: "2026-09-07T21:40:45+02:00"
17
17
  };
18
18
  //#endregion
19
19
  //#region src/client/errors.ts
@@ -35,21 +35,6 @@ const CALENDAR_SURFACE = {
35
35
  };
36
36
  /** Calendar's Apple Events target. Not `com.apple.Calendar`, which does not exist. */
37
37
  const CALENDAR_BUNDLE_ID = "com.apple.iCal";
38
- /**
39
- * A date argument could not be understood.
40
- *
41
- * Carries the accepted grammar rather than just rejecting, because the caller is
42
- * usually a model that will retry once and needs to know what shape to retry in.
43
- */
44
- var InvalidDateError = class extends AppleAutomationError {
45
- name = "InvalidDateError";
46
- constructor(field, raw, reason) {
47
- super(`Could not read ${field} from ${JSON.stringify(raw)}: ${reason}. Accepted: an ISO-8601 date "2026-08-20" (a whole day) or date-time "2026-08-20T09:00" (an instant), or a relative offset like "+2d", "+3h", "+45m", "+1w", "today", "tomorrow", "tomorrow 09:00", or "next monday".`, {
48
- field,
49
- raw
50
- });
51
- }
52
- };
53
38
  /** A CalendarRef no longer resolves — deleted, or moved to another calendar. */
54
39
  var EventNotFoundError = class extends AppleAutomationError {
55
40
  name = "EventNotFoundError";
@@ -143,9 +128,9 @@ const parseClock = (field, raw) => {
143
128
  };
144
129
  };
145
130
  const weekdaySet = (keys) => new Set(keys.map((k) => WEEKDAY_KEYS.indexOf(k)).filter((i) => i !== -1));
146
- const startOfLocalDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
131
+ const startOfLocalDay$2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
147
132
  /** Same wall-clock time, n days later. Calendar arithmetic, so DST-safe. */
148
- const addDays$1 = (d, n) => {
133
+ const addDays = (d, n) => {
149
134
  const out = new Date(d.getTime());
150
135
  out.setDate(out.getDate() + n);
151
136
  return out;
@@ -221,7 +206,7 @@ const subtractBusy = (window, busy) => {
221
206
  const dayWindows = (opts) => {
222
207
  const out = [];
223
208
  const last = opts.to.getTime();
224
- for (let day = startOfLocalDay(opts.from); day.getTime() <= last; day = addDays$1(day, 1)) {
209
+ for (let day = startOfLocalDay$2(opts.from); day.getTime() <= last; day = addDays(day, 1)) {
225
210
  if (!opts.weekdays.has(day.getDay())) continue;
226
211
  const open = atClock(day, opts.dayStart);
227
212
  const close = atClock(day, opts.dayEnd);
@@ -251,9 +236,9 @@ const alignUp = (ms, granularityMinutes) => {
251
236
  return topOfHour + Math.ceil(past / step) * step;
252
237
  };
253
238
  /** Local midnight at the start of the day an instant falls on. */
254
- const startOfLocalDayMs = (ms) => startOfLocalDay(new Date(ms)).getTime();
239
+ const startOfLocalDayMs = (ms) => startOfLocalDay$2(new Date(ms)).getTime();
255
240
  /** The following local midnight. Calendar arithmetic, so a DST day is 23h or 25h. */
256
- const nextLocalDayMs = (ms) => addDays$1(startOfLocalDay(new Date(ms)), 1).getTime();
241
+ const nextLocalDayMs = (ms) => addDays(startOfLocalDay$2(new Date(ms)), 1).getTime();
257
242
  /** `2026-08-24`, in local components — the day a slot falls on. */
258
243
  const localDay = (ms) => {
259
244
  const d = new Date(ms);
@@ -291,124 +276,11 @@ const localDay = (ms) => {
291
276
  * classified apart here. Anything matching `GMT±HHMM` is honoured as an offset;
292
277
  * only what is left over floats.
293
278
  */
294
- const DAY_NAMES = [
295
- "sunday",
296
- "monday",
297
- "tuesday",
298
- "wednesday",
299
- "thursday",
300
- "friday",
301
- "saturday"
302
- ];
303
- const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
304
- const ISO_DATETIME = /^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2}))?(?:\.\d+)?(Z|[+-]\d{2}:?\d{2})?$/;
305
- const OFFSET = /^\+(\d+)\s*(m|min|mins|minute|minutes|h|hr|hrs|hour|hours|d|day|days|w|week|weeks)$/;
306
- const DAY_WORD = /^(today|tomorrow)(?:\s+(\d{1,2}):(\d{2}))?$/;
307
- const NEXT_DAY = /^next\s+([a-z]+)(?:\s+(\d{1,2}):(\d{2}))?$/;
279
+ /** `90`, `"90"`, `"90m"`, `"2h"` — the duration half, which core has no view on. */
308
280
  const DURATION = /^(\d+)\s*(m|min|mins|minute|minutes|h|hr|hrs|hour|hours)?$/;
309
- /** `GMT+0200`, `UTC-05:00`. A definite zone that is simply not an IANA name. */
281
+ /** `GMT+02:00` and friends, which Calendar stores alongside real IANA names. */
310
282
  const FIXED_OFFSET = /^(?:GMT|UTC)([+-])(\d{2}):?(\d{2})$/i;
311
283
  const pad$1 = (n, w = 2) => String(n).padStart(w, "0");
312
- /** `+02:00` / `-05:00` / `Z` for a given instant, in the system zone. */
313
- const offsetOf = (d) => {
314
- const mins = -d.getTimezoneOffset();
315
- if (mins === 0) return "Z";
316
- const sign = mins < 0 ? "-" : "+";
317
- const abs = Math.abs(mins);
318
- return `${sign}${pad$1(Math.floor(abs / 60))}:${pad$1(abs % 60)}`;
319
- };
320
- /**
321
- * Local wall-clock time rendered with its offset.
322
- *
323
- * Deliberately not `toISOString()`, which converts to UTC and would report a
324
- * 09:00 meeting as `07:00Z` — correct as an instant, unreadable in a result
325
- * whose purpose is confirming what the caller asked for.
326
- */
327
- const toLocalIso = (d) => `${d.getFullYear()}-${pad$1(d.getMonth() + 1)}-${pad$1(d.getDate())}T${pad$1(d.getHours())}:${pad$1(d.getMinutes())}:${pad$1(d.getSeconds())}${offsetOf(d)}`;
328
- const startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
329
- const endOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
330
- /** Calendar-aware day arithmetic: same wall-clock time, n days later. */
331
- const addDays = (d, n) => {
332
- const out = new Date(d.getTime());
333
- out.setDate(out.getDate() + n);
334
- return out;
335
- };
336
- const at = (day, hours, minutes) => new Date(day.getFullYear(), day.getMonth(), day.getDate(), hours, minutes, 0, 0);
337
- const result = (kind, when, raw) => ({
338
- kind,
339
- at: when,
340
- iso: toLocalIso(when),
341
- raw
342
- });
343
- /**
344
- * Parse one date argument.
345
- *
346
- * @param field Named in the error, so a failure says WHICH argument was bad.
347
- * @param raw The caller's string.
348
- * @param now Injected for hermetic tests.
349
- */
350
- const parseDate = (field, raw, now = /* @__PURE__ */ new Date()) => {
351
- const text = String(raw ?? "").trim();
352
- if (!text) throw new InvalidDateError(field, String(raw), "it is empty");
353
- const lower = text.toLowerCase();
354
- const dt = ISO_DATETIME.exec(text);
355
- if (dt) {
356
- const [, y, mo, d, hh, mm, ss, zone] = dt;
357
- const when = zone ? new Date(text.replace(" ", "T")) : new Date(Number(y), Number(mo) - 1, Number(d), Number(hh), Number(mm), Number(ss ?? "0"), 0);
358
- if (Number.isNaN(when.getTime())) throw new InvalidDateError(field, text, "it is not a real date");
359
- return result("timed", when, text);
360
- }
361
- const only = ISO_DATE.exec(text);
362
- if (only) {
363
- const [, y, mo, d] = only;
364
- const when = new Date(Number(y), Number(mo) - 1, Number(d), 0, 0, 0, 0);
365
- if (Number.isNaN(when.getTime())) throw new InvalidDateError(field, text, "it is not a real date");
366
- if (when.getMonth() !== Number(mo) - 1 || when.getDate() !== Number(d)) throw new InvalidDateError(field, text, `there is no day ${d} in month ${mo}`);
367
- return result("allDay", when, text);
368
- }
369
- const off = OFFSET.exec(lower);
370
- if (off) {
371
- const n = Number(off[1]);
372
- const unit = String(off[2]);
373
- if (!Number.isFinite(n)) throw new InvalidDateError(field, text, "the amount is not a number");
374
- if (unit.startsWith("d")) return result("timed", addDays(now, n), text);
375
- if (unit.startsWith("w")) return result("timed", addDays(now, n * 7), text);
376
- const ms = unit.startsWith("h") ? n * 36e5 : n * 6e4;
377
- return result("timed", new Date(now.getTime() + ms), text);
378
- }
379
- const word = DAY_WORD.exec(lower);
380
- if (word) {
381
- const day = word[1] === "tomorrow" ? addDays(now, 1) : now;
382
- if (word[2] === void 0) return result("allDay", startOfDay(day), text);
383
- const [hh, mm] = [Number(word[2]), Number(word[3])];
384
- if (hh > 23 || mm > 59) throw new InvalidDateError(field, text, `${hh}:${word[3]} is not a time`);
385
- return result("timed", at(day, hh, mm), text);
386
- }
387
- const next = NEXT_DAY.exec(lower);
388
- if (next) {
389
- const idx = DAY_NAMES.findIndex((n) => n === next[1] || n.slice(0, 3) === next[1]);
390
- if (idx === -1) throw new InvalidDateError(field, text, `"${next[1]}" is not a day of the week`);
391
- const ahead = (idx - now.getDay() + 7) % 7 || 7;
392
- const day = addDays(now, ahead);
393
- if (next[2] === void 0) return result("allDay", startOfDay(day), text);
394
- const [hh, mm] = [Number(next[2]), Number(next[3])];
395
- if (hh > 23 || mm > 59) throw new InvalidDateError(field, text, `${hh}:${next[3]} is not a time`);
396
- return result("timed", at(day, hh, mm), text);
397
- }
398
- throw new InvalidDateError(field, text, "it matches none of the accepted forms");
399
- };
400
- /**
401
- * Parse a bound for a range filter.
402
- *
403
- * A bare day means the WHOLE day, so which edge it resolves to depends on which
404
- * side of the range it is. Resolving both to midnight would make an end bound
405
- * quietly exclude the day the caller named.
406
- */
407
- const parseBound = (field, raw, edge, now = /* @__PURE__ */ new Date()) => {
408
- const parsed = parseDate(field, raw, now);
409
- if (parsed.kind !== "allDay") return parsed.at;
410
- return edge === "end" ? endOfDay(parsed.at) : startOfDay(parsed.at);
411
- };
412
284
  /**
413
285
  * Resolve a query window.
414
286
  *
@@ -418,8 +290,8 @@ const parseBound = (field, raw, edge, now = /* @__PURE__ */ new Date()) => {
418
290
  * next Tuesday, and every window is bounded on both ends.
419
291
  */
420
292
  const parseRange = (opts, now = /* @__PURE__ */ new Date()) => {
421
- const from = opts.from ? parseBound("from", opts.from, "start", now) : startOfDay(now);
422
- const to = opts.to ? parseBound("to", opts.to, "end", now) : endOfDay(addDays(from, opts.defaultRangeDays - 1));
293
+ const from = opts.from ? parseBound("from", opts.from, "start", now) : startOfLocalDay(now);
294
+ const to = opts.to ? parseBound("to", opts.to, "end", now) : startOfLocalDay(addLocalDays(from, opts.defaultRangeDays));
423
295
  if (to.getTime() < from.getTime()) throw new InvalidDateError("to", String(opts.to ?? ""), `it resolves to ${toLocalIso(to)}, which is before from (${toLocalIso(from)})`);
424
296
  const maxMs = opts.maxRangeDays * 864e5;
425
297
  if (to.getTime() - from.getTime() > maxMs) return {
@@ -1836,11 +1708,13 @@ var AppleCalendarClient = class {
1836
1708
  });
1837
1709
  const declined = filters.includeDeclined ?? this.config.includeDeclined;
1838
1710
  const cancelled = filters.includeCancelled ?? this.config.includeCancelled;
1711
+ const visible = merged.rows.filter((r) => this.#visible(r, {
1712
+ declined,
1713
+ cancelled
1714
+ }));
1839
1715
  return {
1840
- events: merged.rows.filter((r) => this.#visible(r, {
1841
- declined,
1842
- cancelled
1843
- })).slice(0, filters.limit).map((r) => this.#summarise(r, store)),
1716
+ events: visible.slice(0, filters.limit).map((r) => this.#summarise(r, store)),
1717
+ hasMore: visible.length > filters.limit,
1844
1718
  expansion: merged.expansion,
1845
1719
  ...merged.expansionReason ? { expansionReason: merged.expansionReason } : {},
1846
1720
  window: {
@@ -1895,11 +1769,13 @@ var AppleCalendarClient = class {
1895
1769
  });
1896
1770
  const declined = args.includeDeclined ?? this.config.includeDeclined;
1897
1771
  const cancelled = args.includeCancelled ?? this.config.includeCancelled;
1772
+ const visible = rows.filter((r) => this.#visible(r, {
1773
+ declined,
1774
+ cancelled
1775
+ }));
1898
1776
  return {
1899
- events: rows.filter((r) => this.#visible(r, {
1900
- declined,
1901
- cancelled
1902
- })).slice(0, args.limit).map((r) => this.#summarise(r, store)),
1777
+ events: visible.slice(0, args.limit).map((r) => this.#summarise(r, store)),
1778
+ hasMore: visible.length > args.limit,
1903
1779
  expansion: "unavailable",
1904
1780
  expansionReason: "search matches each event once, at its series start; use apple_calendar_list_events with a date range to see individual occurrences",
1905
1781
  window: {
@@ -1992,14 +1868,14 @@ var AppleCalendarClient = class {
1992
1868
  if (windowTo.getTime() > covTo.getTime()) {
1993
1869
  truncated = {
1994
1870
  reason,
1995
- requestedTo: toLocalIso(range.to)
1871
+ requestedTo: toLocalIso$1(/* @__PURE__ */ new Date(range.to.getTime() - 1))
1996
1872
  };
1997
1873
  windowTo = covTo;
1998
1874
  }
1999
1875
  if (windowFrom.getTime() < covFrom.getTime()) {
2000
1876
  truncated = {
2001
1877
  ...truncated ?? { reason },
2002
- requestedFrom: toLocalIso(range.from)
1878
+ requestedFrom: toLocalIso$1(range.from)
2003
1879
  };
2004
1880
  windowFrom = covFrom;
2005
1881
  }
@@ -2007,7 +1883,7 @@ var AppleCalendarClient = class {
2007
1883
  degraded: true,
2008
1884
  capability: "occurrence-coverage",
2009
1885
  reason: "The whole requested window lies outside the range this store has expanded, so every gap in it would be invented rather than found.",
2010
- hint: `The expansion reaches ${toLocalIso(covFrom)} to ${toLocalIso(covTo)}. Ask inside that, or use apple_calendar_list_events, which reports single events correctly at any distance.`
1886
+ hint: `The expansion reaches ${toLocalIso$1(covFrom)} to ${toLocalIso$1(covTo)}. Ask inside that, or use apple_calendar_list_events, which reports single events correctly at any distance.`
2011
1887
  };
2012
1888
  }
2013
1889
  const startedAtNow = windowFrom.getTime() < now.getTime();
@@ -2015,8 +1891,8 @@ var AppleCalendarClient = class {
2015
1891
  const shell = {
2016
1892
  durationMinutes: args.durationMinutes,
2017
1893
  window: {
2018
- from: toLocalIso(windowFrom),
2019
- to: toLocalIso(windowTo),
1894
+ from: toLocalIso$1(windowFrom),
1895
+ to: toLocalIso$1(windowTo),
2020
1896
  clamped: range.clamped,
2021
1897
  startedAtNow
2022
1898
  },
@@ -2099,8 +1975,8 @@ var AppleCalendarClient = class {
2099
1975
  const start = alignUp(gap.from, args.granularityMinutes);
2100
1976
  if (gap.to - start < needMs) continue;
2101
1977
  slots.push({
2102
- start: toLocalIso(new Date(start)),
2103
- end: toLocalIso(new Date(gap.to)),
1978
+ start: toLocalIso$1(new Date(start)),
1979
+ end: toLocalIso$1(new Date(gap.to)),
2104
1980
  day: localDay(start),
2105
1981
  minutes: Math.round((gap.to - start) / 6e4)
2106
1982
  });
@@ -2262,11 +2138,11 @@ var AppleCalendarClient = class {
2262
2138
  * word: `{start: "2026-09-21", end: "2026-09-21"}`, the natural way to say
2263
2139
  * "a one-day event", was refused as ending before it began.
2264
2140
  */
2265
- const to = parseBound("end", end, "end", now);
2266
- if (to.getTime() <= from.at.getTime()) throw new PreconditionError(`end (${toLocalIso(to)}) is not after start (${from.iso}). An event cannot finish before it begins.`);
2141
+ const to = parseBound$1("end", end, "end", now);
2142
+ if (to.getTime() <= from.at.getTime()) throw new PreconditionError(`end (${toLocalIso$1(to)}) is not after start (${from.iso}). An event cannot finish before it begins.`);
2267
2143
  return {
2268
2144
  startIso: from.iso,
2269
- endIso: toLocalIso(to),
2145
+ endIso: toLocalIso$1(to),
2270
2146
  allDayHint: from.kind === "allDay"
2271
2147
  };
2272
2148
  }
@@ -2274,7 +2150,7 @@ var AppleCalendarClient = class {
2274
2150
  const to = new Date(from.at.getTime() + minutes * 6e4);
2275
2151
  return {
2276
2152
  startIso: from.iso,
2277
- endIso: toLocalIso(to),
2153
+ endIso: toLocalIso$1(to),
2278
2154
  allDayHint: from.kind === "allDay"
2279
2155
  };
2280
2156
  }
@@ -2311,12 +2187,22 @@ var AppleCalendarClient = class {
2311
2187
  ref: fields.ref,
2312
2188
  seriesRef: seriesRefOf(ref)
2313
2189
  });
2314
- const window = fields.start !== void 0 ? this.#resolveWindow(fields.start, fields.end, fields.durationMinutes) : null;
2190
+ let window = null;
2191
+ let endOnly = false;
2192
+ if (fields.start !== void 0) window = this.#resolveWindow(fields.start, fields.end, fields.durationMinutes);
2193
+ else if (fields.end !== void 0 || fields.durationMinutes !== void 0) {
2194
+ const store = this.#require();
2195
+ const row = store.byUuid(ref.eventUid);
2196
+ if (!row || row.startApple === null) throw new PreconditionError("Give start as well. Moving only the end needs the event's current start, and this store does not have one for that ref.", { ref: fields.ref });
2197
+ const startIso = toLocalIso$1(/* @__PURE__ */ new Date((row.startApple + store.caps.epochOffset) * 1e3));
2198
+ window = this.#resolveWindow(startIso, fields.end, fields.durationMinutes);
2199
+ endOnly = true;
2200
+ }
2315
2201
  const data = await this.#run(UPDATE_EVENT, {
2316
2202
  calendar: this.#nameForRefCalendar(ref.calendarUid) ?? null,
2317
2203
  uid: ref.eventUid,
2318
2204
  ...fields.summary !== void 0 ? { summary: fields.summary } : {},
2319
- ...window ? {
2205
+ ...window ? endOnly ? { endDate: window.endIso } : {
2320
2206
  startDate: window.startIso,
2321
2207
  endDate: window.endIso
2322
2208
  } : {},
@@ -2857,7 +2743,7 @@ const filterSchema = {
2857
2743
  };
2858
2744
  const registerEventTools = (server, client) => {
2859
2745
  server.registerTool("apple_calendar_list_events", {
2860
- description: "List events in a date range, earliest first. Occurrences of repeating events are expanded, so a weekly standup appears once per week rather than once. The result carries a `coverage` block naming the window the expansion is known to cover; if your range runs past it, `truncated` is set and says what is missing rather than returning a short list silently. Returns a `ref` per event for get_event.",
2746
+ description: "List events in a date range, earliest first. Occurrences of repeating events are expanded, so a weekly standup appears once per week rather than once. The result carries a `coverage` block naming the window the expansion is known to cover; if your range runs past it, `truncated` is set and says what is missing rather than returning a short list silently. `hasMore` is the other reason a list can be partial: more events matched than `limit` allowed. Returns a `ref` per event for get_event.",
2861
2747
  inputSchema: {
2862
2748
  from: fromArg,
2863
2749
  to: toArg,
@@ -2964,4 +2850,4 @@ const createServer = (opts) => {
2964
2850
  //#endregion
2965
2851
  export { BUILD_INFO as A, CALENDAR_SURFACE as C, CalendarNotWritableError as D, CalendarNotRunningError as E, EventNotFoundError as O, CALENDAR_BUNDLE_ID as S, CalendarNotFoundError as T, STORE_FILENAME as _, loadConfig as a, locateStore as b, introspect as c, decodeRef as d, encodeRef as f, GROUP_CONTAINER as g, EXTRAS_FILENAME as h, registerTools as i, InvalidDateError as k, openStore as l, uuidOf as m, SERVER_VERSION as n, AppleCalendarClient as o, seriesRefOf as p, createServer as r, CalendarStore as s, SERVER_NAME as t, REF_VERSION as u, defaultContainerPath as v, CalendarBusyError as w, AppleCalendarError as x, defaultStorePath as y };
2966
2852
 
2967
- //# sourceMappingURL=server-BgyYeCba.js.map
2853
+ //# sourceMappingURL=server-CLAGQcwG.js.map