@mulmoclaude/core 1.11.0 → 1.12.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.
@@ -8,7 +8,8 @@ export { authorizeGoogle, commitLinkedTokens, getGoogleAccessToken, unlinkGoogle
8
8
  export { createGoogleAuthFlow, googleAuthFlow, type GoogleAuthFlow, type GoogleAuthFlowStatus } from './authFlow.js';
9
9
  export { googleApiError, isGoogleApiError, GoogleApiError, DEFAULT_LIST_MAX_RESULTS, HTTP_FORBIDDEN, MAX_LIST_RESULTS } from './apiClient.js';
10
10
  export { buildEventPatch, calendarApiError, collectCalendarPages, createCalendarEvent, deleteCalendarEvent, getCalendarColors, canonicalCalendarId, listCalendarEvents, listCalendars, syncCalendarEvents, toCalendarSummary, toEventSummary, updateCalendarEvent, getCalendar, getCalendarEvent, resolveEventSpan, CANCELLED_EVENT_STATUS, HTTP_CONFLICT, HTTP_PRECONDITION_FAILED, type CalendarColorEntry, type CalendarColors, type CalendarEventInput, type CalendarEventSpan, type CalendarEventSummary, type CalendarEventTime, type CalendarListPage, type CalendarSummary, type CalendarSyncResult, type DeleteCalendarEventInput, type FetchedCalendarEvent, type ListEventsInput, type SyncEventsInput, type UpdateCalendarEventInput, } from './calendar.js';
11
- export { calendarSyncStatePath, clearCalendarSyncToken, loadCalendarSyncToken, saveCalendarSyncToken } from './calendarSyncStore.js';
11
+ export { calendarSyncStatePath, claimCalendarSyncIfDue, clearCalendarLastSyncedAt, clearCalendarSyncToken, loadCalendarLastSyncedAt, loadCalendarSyncToken, saveCalendarSyncToken, } from './calendarSyncStore.js';
12
+ export { calendarSyncDueWindowMs, isCalendarSyncDue } from './calendarSyncDue.js';
12
13
  export { calendarPushStatePath, clearCalendarShadow, loadCalendarShadow, mergeShadow, saveCalendarShadow, toShadowEvent, type ShadowEvent, } from './calendarPushState.js';
13
14
  export { isDeniedAccessRole, isUnpushed, locallyEditedIds, pushCalendarForCollection, pushCollectionNow, unsentLocalEdits, type PushOutcomeKind, type CalendarCollectionPushResult, type CalendarPushDeps, type CalendarPushOutcome, type CalendarWriteTarget, } from './collectionPush.js';
14
15
  export { toGoogleEventTime, zoneSuffixOf } from './pushDateTime.js';
@@ -16,6 +17,6 @@ export { baselineRecord, bySourceField, conflictingFields, fieldText, isClientSe
16
17
  export { toCollectionDateTime } from './collectionDateTime.js';
17
18
  export { withCalendarLock, withKeyedLock } from './calendarLock.js';
18
19
  export { mergeIntoExisting, toCollectionRecord, type GoogleCalendarSourceField } from './collectionProjection.js';
19
- export { googleCalendarSyncTaskDef, classifyDelete, classifyWrite, anySyncedCollectionSurvives, groupByCalendar, allUnpushed, orphanedCalendarId, pullableEvents, releaseOrphanedCalendarToken, unpushedFor, PROTECTION_UNKNOWN, type UnpushedBySlug, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, shadowUpdates, unsyncedGroups, GOOGLE_CALENDAR_SYNC_TASK_ID, type CalendarCollectionSyncResult, type CalendarDeclaring, type ManualCalendarSyncDeps, type ManualCalendarSyncOutcome, } from './collectionSync.js';
20
+ export { googleCalendarSyncTaskDef, classifyDelete, classifyWrite, anySyncedCollectionSurvives, groupByCalendar, allUnpushed, orphanedCalendarId, pullableEvents, releaseOrphanedCalendarToken, unpushedFor, PROTECTION_UNKNOWN, type ClaimGuard, type UnpushedBySlug, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, shadowUpdates, unsyncedGroups, GOOGLE_CALENDAR_SYNC_TASK_ID, type CalendarCollectionSyncResult, type CalendarDeclaring, type ManualCalendarSyncDeps, type ManualCalendarSyncOutcome, } from './collectionSync.js';
20
21
  export { buildTaskPatch, canonicalTaskListId, completeTask, createTask, deleteTask, listTaskLists, listTasks, toTaskListSummary, toTaskSummary, uncompleteTask, updateTask, type CompleteTaskInput, type CreateTaskInput, type ListTasksInput, type TaskListSummary, type TaskSummary, type UpdateTaskInput, } from './tasks.js';
21
22
  export { assertSafeMimeType, buildMultipartBody, createDriveFile, deleteDriveFile, isTextMimeType, listDriveFiles, pickBoundary, readDriveFile, toDriveFileSummary, type CreateDriveFileInput, type DriveFileSummary, type ListDriveFilesInput, type ReadDriveFileInput, } from './driveFile.js';
@@ -841,34 +841,128 @@ function calendarSyncStatePath(workspaceRoot) {
841
841
  return path.join(workspaceRoot ?? getWorkspaceRoot(), "data", "calendar", ".sync-state.json");
842
842
  }
843
843
  var calendarKey = canonicalCalendarId;
844
+ /** Read one map out of whatever is on disk. Tolerant on purpose: a file written
845
+ * before `lastSyncedAt` existed simply lacks the key, and a hand-edited one may
846
+ * hold anything. A dropped entry costs a full re-walk or a duplicate run, never
847
+ * data — throwing here would stop the sync entirely. */
848
+ function stringRecord(value) {
849
+ if (typeof value !== "object" || value === null) return {};
850
+ return Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string"));
851
+ }
844
852
  async function readState$1(workspaceRoot) {
845
853
  const stored = await readJsonOrNull(calendarSyncStatePath(workspaceRoot));
846
- return stored?.tokens ? stored : { tokens: {} };
854
+ return {
855
+ tokens: stringRecord(stored?.tokens),
856
+ lastSyncedAt: stringRecord(stored?.lastSyncedAt)
857
+ };
847
858
  }
848
859
  var writeQueue$1 = { tail: Promise.resolve() };
849
- async function updateState$1(mutate, workspaceRoot) {
860
+ /** Decide from the stored state and write the result, both inside the queue, so
861
+ * nothing in this process can read between the two. A `null` state skips the
862
+ * write; `result` is what the caller learns about the decision. */
863
+ async function updateStateWith(decide, workspaceRoot) {
850
864
  const run = writeQueue$1.tail.then(async () => {
851
- const state = await readState$1(workspaceRoot);
852
- await writeJsonAtomicWithMode(calendarSyncStatePath(workspaceRoot), { tokens: mutate(state.tokens) }, SYNC_STATE_MODE);
865
+ const { state, result } = decide(await readState$1(workspaceRoot));
866
+ if (state) await writeJsonAtomicWithMode(calendarSyncStatePath(workspaceRoot), state, SYNC_STATE_MODE);
867
+ return result;
853
868
  });
854
869
  writeQueue$1.tail = run.catch(() => void 0);
855
870
  return await run;
856
871
  }
872
+ async function updateState$1(mutate, workspaceRoot) {
873
+ await updateStateWith((state) => ({
874
+ state: mutate(state),
875
+ result: void 0
876
+ }), workspaceRoot);
877
+ }
878
+ var withoutKey = (record, dropped) => Object.fromEntries(Object.entries(record).filter(([key]) => key !== dropped));
857
879
  async function loadCalendarSyncToken(calendarId, workspaceRoot) {
858
880
  return (await readState$1(workspaceRoot)).tokens[calendarKey(calendarId)] ?? null;
859
881
  }
860
882
  async function saveCalendarSyncToken(calendarId, syncToken, workspaceRoot) {
861
883
  const stored = calendarKey(calendarId);
862
- await updateState$1((tokens) => ({
863
- ...tokens,
864
- [stored]: syncToken
884
+ await updateState$1((state) => ({
885
+ ...state,
886
+ tokens: {
887
+ ...state.tokens,
888
+ [stored]: syncToken
889
+ }
865
890
  }), workspaceRoot);
866
891
  }
867
892
  /** Drop one calendar's token — used when Google answers 410, so the next run
868
- * starts a clean full sync. */
893
+ * starts a clean full sync. Leaves the sync marker alone: "restart the walk"
894
+ * says nothing about "nobody is running". */
869
895
  async function clearCalendarSyncToken(calendarId, workspaceRoot) {
870
896
  const dropped = calendarKey(calendarId);
871
- await updateState$1((tokens) => Object.fromEntries(Object.entries(tokens).filter(([key]) => key !== dropped)), workspaceRoot);
897
+ await updateState$1((state) => ({
898
+ ...state,
899
+ tokens: withoutKey(state.tokens, dropped)
900
+ }), workspaceRoot);
901
+ }
902
+ async function loadCalendarLastSyncedAt(calendarId, workspaceRoot) {
903
+ return (await readState$1(workspaceRoot)).lastSyncedAt[calendarKey(calendarId)] ?? null;
904
+ }
905
+ /** Stamp when a sync of this calendar started, but only if `mayClaim` accepts
906
+ * what the marker currently says. Answers whether THIS call is the one that
907
+ * claimed it.
908
+ *
909
+ * The decision and the stamp share one pass through the queue on purpose.
910
+ * Deciding from a snapshot read earlier — as a caller filtering a whole map of
911
+ * calendars up front must — leaves both hosts believing the calendar is free,
912
+ * which is the race this exists to close (Codex review #2680). What remains is
913
+ * the read→write gap BETWEEN processes; closing that needs a real file lock
914
+ * (#2679), and this stays a soft dedup until then.
915
+ *
916
+ * The time is passed in rather than read here so the rule stays testable
917
+ * without freezing the clock. */
918
+ async function claimCalendarSyncIfDue(calendarId, startedAt, mayClaim, workspaceRoot) {
919
+ const stored = calendarKey(calendarId);
920
+ return await updateStateWith((state) => {
921
+ const claimed = mayClaim(state.lastSyncedAt[stored] ?? null);
922
+ return {
923
+ state: claimed ? {
924
+ ...state,
925
+ lastSyncedAt: {
926
+ ...state.lastSyncedAt,
927
+ [stored]: startedAt
928
+ }
929
+ } : null,
930
+ result: claimed
931
+ };
932
+ }, workspaceRoot);
933
+ }
934
+ /** Drop one calendar's marker, so the next tick — on either host — may sync it
935
+ * immediately instead of waiting the window out. */
936
+ async function clearCalendarLastSyncedAt(calendarId, workspaceRoot) {
937
+ const dropped = calendarKey(calendarId);
938
+ await updateState$1((state) => ({
939
+ ...state,
940
+ lastSyncedAt: withoutKey(state.lastSyncedAt, dropped)
941
+ }), workspaceRoot);
942
+ }
943
+ //#endregion
944
+ //#region src/google/calendarSyncDue.ts
945
+ /** Slack between a tick and the marker it writes. Without it a lone host reads
946
+ * its OWN marker as "not due yet" — elapsed lands a hair under the interval
947
+ * every time — and syncs every other hour. */
948
+ var TICK_JITTER_TOLERANCE_MS = 300 * 1e3;
949
+ /** How long a fresh marker suppresses a sync: one interval, less the slack.
950
+ * The slack is halved rather than subtracted flat for a very short configured
951
+ * interval, where a fixed five minutes would swallow the window whole. */
952
+ function calendarSyncDueWindowMs(intervalMs) {
953
+ return intervalMs - Math.min(TICK_JITTER_TOLERANCE_MS, intervalMs / 2);
954
+ }
955
+ /** True iff no recent enough run stands in for this one.
956
+ *
957
+ * A marker that cannot be read as a time is treated as due: a stuck calendar is
958
+ * worse than a duplicate run, which the sync is built to tolerate anyway
959
+ * (writes are upserts by event id). */
960
+ function isCalendarSyncDue(lastSyncedAt, windowMs, now = Date.now()) {
961
+ if (!lastSyncedAt) return true;
962
+ const elapsed = now - Date.parse(lastSyncedAt);
963
+ if (!Number.isFinite(elapsed)) return true;
964
+ if (elapsed < -windowMs) return true;
965
+ return elapsed >= windowMs;
872
966
  }
873
967
  //#endregion
874
968
  //#region src/google/calendarPushState.ts
@@ -1782,6 +1876,7 @@ async function restartFullSync(accessToken, calendarId, workspaceRoot) {
1782
1876
  await clearCalendarShadow(calendarId, workspaceRoot);
1783
1877
  return await syncCalendarEvents(accessToken, { calendarId });
1784
1878
  }
1879
+ var ALWAYS_CLAIM = () => true;
1785
1880
  /** Sync ONE calendar and fan its events out to every collection bound to it.
1786
1881
  *
1787
1882
  * The fan-out is not an optimisation, it is correctness: the sync token is
@@ -1796,9 +1891,59 @@ async function restartFullSync(accessToken, calendarId, workspaceRoot) {
1796
1891
  * load the SAME stored token and walk the same window. That is idempotent —
1797
1892
  * writes are upserts by event id — but it is a wasted full walk. Queued, the
1798
1893
  * second pass resumes from the token the first just stored and fetches only
1799
- * what is genuinely new. */
1800
- async function syncCalendarGroup(calendarId, collections, workspaceRoot) {
1801
- return await withCalendarLock(calendarId, () => syncCalendarGroupNow(calendarId, collections, workspaceRoot));
1894
+ * what is genuinely new. That queue is module state, so it orders the doors
1895
+ * into THIS process only; `claimThenSync` is what other hosts can see. */
1896
+ async function syncCalendarGroup(calendarId, collections, workspaceRoot, mayClaim = ALWAYS_CLAIM) {
1897
+ return await withCalendarLock(calendarId, () => claimThenSync(calendarId, collections, workspaceRoot, mayClaim));
1898
+ }
1899
+ /** Take the workspace-shared marker BEFORE the calendar is touched, sync only if
1900
+ * this run got it, and drop it again if the run could not happen at all.
1901
+ *
1902
+ * Claiming first is the whole point: hosts tick in the same minute (interval
1903
+ * schedules align to wall-clock boundaries), so a marker written on completion
1904
+ * would leave the entire run — minutes, for a first full walk — open for a
1905
+ * second host to start alongside this one and lose the push baseline it writes.
1906
+ *
1907
+ * Released only when the sync could not run at all. A run that finished with
1908
+ * retryable per-collection errors KEEPS the marker: it already held the token
1909
+ * and the baseline back, so it replays on the next tick either way, and
1910
+ * releasing would hand a permanently-failing calendar back to both hosts at
1911
+ * once — the very overlap this guards (observed during Claude review). */
1912
+ async function claimThenSync(calendarId, collections, workspaceRoot, mayClaim) {
1913
+ if (!await claimCalendarSync(calendarId, workspaceRoot, mayClaim)) {
1914
+ log.info("google", "skipping a calendar this workspace synced recently — another host may be on it", { calendarId });
1915
+ return [];
1916
+ }
1917
+ try {
1918
+ return await syncCalendarGroupNow(calendarId, collections, workspaceRoot);
1919
+ } catch (error) {
1920
+ await releaseCalendarSyncClaim(calendarId, workspaceRoot);
1921
+ throw error;
1922
+ }
1923
+ }
1924
+ /** Never throws, and fails OPEN: the marker guards against duplicate work, it is
1925
+ * not a precondition for syncing correctly. A workspace that cannot store it
1926
+ * syncs the way it did before #2678. */
1927
+ async function claimCalendarSync(calendarId, workspaceRoot, mayClaim) {
1928
+ try {
1929
+ return await claimCalendarSyncIfDue(calendarId, (/* @__PURE__ */ new Date()).toISOString(), mayClaim, workspaceRoot);
1930
+ } catch (error) {
1931
+ log.warn("google", "could not stamp the calendar sync marker — another host may sync this calendar in parallel", {
1932
+ calendarId,
1933
+ error: String(error)
1934
+ });
1935
+ return true;
1936
+ }
1937
+ }
1938
+ async function releaseCalendarSyncClaim(calendarId, workspaceRoot) {
1939
+ try {
1940
+ await clearCalendarLastSyncedAt(calendarId, workspaceRoot);
1941
+ } catch (error) {
1942
+ log.warn("google", "could not release the calendar sync marker after a failed run", {
1943
+ calendarId,
1944
+ error: String(error)
1945
+ });
1946
+ }
1802
1947
  }
1803
1948
  async function syncCalendarGroupNow(calendarId, collections, workspaceRoot) {
1804
1949
  const unpushed = await pushAutoCollections(collections, workspaceRoot);
@@ -1959,6 +2104,7 @@ async function releaseOrphanedCalendarToken(deleted, workspaceRoot) {
1959
2104
  if (orphaned === null) return null;
1960
2105
  await clearCalendarSyncToken(orphaned, workspaceRoot);
1961
2106
  await clearCalendarShadow(orphaned, workspaceRoot);
2107
+ await clearCalendarLastSyncedAt(orphaned, workspaceRoot);
1962
2108
  log.info("google", "cleared the sync token of a calendar no collection reads any more", { calendarId: orphaned });
1963
2109
  return orphaned;
1964
2110
  } catch (error) {
@@ -1975,19 +2121,27 @@ async function declaringGroups(workspaceRoot) {
1975
2121
  * Authoring the collection before linking the account is an expected state,
1976
2122
  * not a failure. Checking once here keeps it a quiet skip instead of an
1977
2123
  * access-token throw per calendar, every hour, until the user links (#2188).
1978
- * A user-triggered sync answers differently — it says so out loud. */
2124
+ * A user-triggered sync answers differently — it says so out loud.
2125
+ *
2126
+ * Deliberately not phrased as a per-host state: the link lives in
2127
+ * `~/.config/mulmo`, which carries no app name, so every host on the machine
2128
+ * shares one answer. Reading it as "linked on this host only" is what made the
2129
+ * calendar look implicitly exclusive when it never was (#2678). */
1979
2130
  async function backgroundSyncAllowed(groups) {
1980
2131
  if (groups.size === 0) return false;
1981
2132
  if (await isGoogleLinked()) return true;
1982
- log.info("google", "skipping calendar sync — no Google account linked on this host", { calendars: groups.size });
2133
+ log.info("google", "skipping calendar sync — no Google account linked", { calendars: groups.size });
1983
2134
  return false;
1984
2135
  }
1985
2136
  /** Run each group, isolating failures per calendar — one unreachable calendar
1986
- * (or a revoked grant) must not stop the others. */
1987
- async function runCalendarGroups(groups, workspaceRoot) {
2137
+ * (or a revoked grant) must not stop the others. `mayClaim` is evaluated per
2138
+ * calendar as it comes up, never once for the whole map: an earlier calendar's
2139
+ * full walk takes minutes, and a decision made before it started says nothing
2140
+ * about who holds this one now. */
2141
+ async function runCalendarGroups(groups, workspaceRoot, mayClaim = ALWAYS_CLAIM) {
1988
2142
  const results = [];
1989
2143
  for (const [calendarId, collections] of groups) try {
1990
- results.push(...await syncCalendarGroup(calendarId, collections, workspaceRoot));
2144
+ results.push(...await syncCalendarGroup(calendarId, collections, workspaceRoot, mayClaim));
1991
2145
  } catch (error) {
1992
2146
  log.warn("google", "calendar sync failed", {
1993
2147
  calendarId,
@@ -2003,10 +2157,19 @@ async function runCalendarGroups(groups, workspaceRoot) {
2003
2157
  }
2004
2158
  return results;
2005
2159
  }
2006
- /** Sync every collection that declares `googleCalendar`. */
2007
- async function syncDueCalendarCollections(workspaceRoot) {
2160
+ /** Sync every collection whose calendar is due — no host in this workspace has
2161
+ * started one within `intervalMs` (#2678). Without that gate this walked every
2162
+ * declaring group on every tick, so a second host registering the same task
2163
+ * simply doubled the runs, concurrently.
2164
+ *
2165
+ * Dueness is not decided here, only described: the guard is handed down and
2166
+ * evaluated where the marker is written, so the answer cannot go stale between
2167
+ * deciding and claiming (Codex review #2680). */
2168
+ async function syncDueCalendarCollections(workspaceRoot, intervalMs = DEFAULT_SYNC_INTERVAL_MS) {
2008
2169
  const groups = await declaringGroups(workspaceRoot);
2009
- return await backgroundSyncAllowed(groups) ? await runCalendarGroups(groups, workspaceRoot) : [];
2170
+ if (!await backgroundSyncAllowed(groups)) return [];
2171
+ const windowMs = calendarSyncDueWindowMs(intervalMs);
2172
+ return await runCalendarGroups(groups, workspaceRoot, (lastSyncedAt) => isCalendarSyncDue(lastSyncedAt, windowMs));
2010
2173
  }
2011
2174
  /** The groups whose calendar has never synced. A missing token IS the "created
2012
2175
  * since the last sync" signal — nothing else distinguishes a new collection
@@ -2052,10 +2215,21 @@ async function syncCalendarForCollection(slug, workspaceRoot, deps = liveManualS
2052
2215
  results: await deps.runGroups(new Map(owning), workspaceRoot)
2053
2216
  };
2054
2217
  }
2218
+ /** The interval this task is scheduled on right now. A non-interval schedule
2219
+ * cannot be reached — the factory below builds an interval one — but the type
2220
+ * allows it, so it falls back rather than asserting. */
2221
+ function scheduledIntervalMs(task) {
2222
+ return task.schedule.type === SCHEDULE_TYPES.interval ? task.schedule.intervalMs : DEFAULT_SYNC_INTERVAL_MS;
2223
+ }
2055
2224
  /** Scheduler registration, shaped like `feedRefreshTaskDef` so hosts wire it
2056
- * with a single line. */
2225
+ * with a single line.
2226
+ *
2227
+ * `run` reads the interval back off the definition instead of closing over the
2228
+ * option: a host rewrites `schedule` from its own overrides file AFTER this
2229
+ * returns, and the due window has to follow it. Frozen at the default, a
2230
+ * shortened interval would tick often and skip nearly every tick. */
2057
2231
  function googleCalendarSyncTaskDef(opts) {
2058
- return {
2232
+ const def = {
2059
2233
  id: GOOGLE_CALENDAR_SYNC_TASK_ID,
2060
2234
  name: "Google Calendar sync",
2061
2235
  description: "Pulls changed Google Calendar events into any collection declaring `googleCalendar`, without invoking the LLM.",
@@ -2064,8 +2238,9 @@ function googleCalendarSyncTaskDef(opts) {
2064
2238
  intervalMs: opts?.intervalMs ?? DEFAULT_SYNC_INTERVAL_MS
2065
2239
  },
2066
2240
  missedRunPolicy: MISSED_RUN_POLICIES.runOnce,
2067
- run: () => syncDueCalendarCollections(opts?.workspaceRoot ?? getWorkspaceRoot()).then(() => {})
2241
+ run: () => syncDueCalendarCollections(opts?.workspaceRoot ?? getWorkspaceRoot(), scheduledIntervalMs(def)).then(() => {})
2068
2242
  };
2243
+ return def;
2069
2244
  }
2070
2245
  //#endregion
2071
2246
  //#region src/google/tasks.ts
@@ -2262,6 +2437,6 @@ async function deleteDriveFile(accessToken, input) {
2262
2437
  await googleRequest(DRIVE_API_LABEL, accessToken, `${DRIVE_FILES_URL}/${encodeURIComponent(input.fileId)}`, { method: "DELETE" });
2263
2438
  }
2264
2439
  //#endregion
2265
- export { CANCELLED_EVENT_STATUS, DEFAULT_LIST_MAX_RESULTS, GOOGLE_AUTH_CANCELLED, GOOGLE_CALENDARLIST_SCOPE, GOOGLE_CALENDAR_SCOPE, GOOGLE_CALENDAR_SYNC_TASK_ID, GOOGLE_DRIVE_FILE_SCOPE, GOOGLE_SCOPES, GOOGLE_TASKS_SCOPE, GoogleApiError, HTTP_CONFLICT, HTTP_FORBIDDEN, HTTP_PRECONDITION_FAILED, MAX_LIST_RESULTS, PROTECTION_UNKNOWN, PUSHABLE_SOURCE_FIELDS, allUnpushed, anySyncedCollectionSurvives, assertSafeMimeType, authorizeGoogle, baselineRecord, brokerBaseUrl, brokerExchange, brokerRefresh, brokerStart, buildEventPatch, buildMultipartBody, buildTaskPatch, bySourceField, calendarApiError, calendarPushStatePath, calendarSyncStatePath, canonicalCalendarId, canonicalTaskListId, classifyDelete, classifyWrite, clearCalendarShadow, clearCalendarSyncToken, clientSecretPresence, collectCalendarPages, commitLinkedTokens, completeTask, configureGoogleHost, conflictingFields, createCalendarEvent, createDriveFile, createGoogleAuthFlow, createTask, deleteCalendarEvent, deleteDriveFile, deleteGoogleTokens, deleteTask, fieldText, findClientSecretPath, getCalendar, getCalendarColors, getCalendarEvent, getGoogleAccessToken, googleApiError, googleAuthFlow, googleCalendarSyncTaskDef, googleConfigDir, googleSecretsDir, googleTokenPath, groupByCalendar, isClientSettableEventId, isDeniedAccessRole, isGoogleApiError, isIsoDateTimeWithOffset, isTextMimeType, isUnpushed, legacyGoogleTokenPath, listCalendarEvents, listCalendars, listDriveFiles, listTaskLists, listTasks, loadCalendarShadow, loadCalendarSyncToken, loadClientSecret, loadGoogleTokens, locallyChangedFields, locallyDeletedIds, locallyEditedIds, mayAdoptExisting, mergeGoogleTokens, mergeIntoExisting, mergeShadow, orphanedCalendarId, pickBoundary, planRecord, pullableEvents, pushCalendarForCollection, pushCollectionNow, pushableMap, readDriveFile, releaseOrphanedCalendarToken, resolveEventSpan, saveCalendarShadow, saveCalendarSyncToken, saveGoogleTokens, shadowUpdates, syncCalendarEvents, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, toCalendarSummary, toCollectionDateTime, toCollectionRecord, toDriveFileSummary, toEventSummary, toGoogleEventTime, toShadowEvent, toTaskListSummary, toTaskSummary, uncompleteTask, unlinkGoogle, unpushedFor, unsentLocalEdits, unsyncedGroups, updateCalendarEvent, updateTask, waitForAuthCode, withCalendarLock, withKeyedLock, zoneSuffixOf };
2440
+ export { CANCELLED_EVENT_STATUS, DEFAULT_LIST_MAX_RESULTS, GOOGLE_AUTH_CANCELLED, GOOGLE_CALENDARLIST_SCOPE, GOOGLE_CALENDAR_SCOPE, GOOGLE_CALENDAR_SYNC_TASK_ID, GOOGLE_DRIVE_FILE_SCOPE, GOOGLE_SCOPES, GOOGLE_TASKS_SCOPE, GoogleApiError, HTTP_CONFLICT, HTTP_FORBIDDEN, HTTP_PRECONDITION_FAILED, MAX_LIST_RESULTS, PROTECTION_UNKNOWN, PUSHABLE_SOURCE_FIELDS, allUnpushed, anySyncedCollectionSurvives, assertSafeMimeType, authorizeGoogle, baselineRecord, brokerBaseUrl, brokerExchange, brokerRefresh, brokerStart, buildEventPatch, buildMultipartBody, buildTaskPatch, bySourceField, calendarApiError, calendarPushStatePath, calendarSyncDueWindowMs, calendarSyncStatePath, canonicalCalendarId, canonicalTaskListId, claimCalendarSyncIfDue, classifyDelete, classifyWrite, clearCalendarLastSyncedAt, clearCalendarShadow, clearCalendarSyncToken, clientSecretPresence, collectCalendarPages, commitLinkedTokens, completeTask, configureGoogleHost, conflictingFields, createCalendarEvent, createDriveFile, createGoogleAuthFlow, createTask, deleteCalendarEvent, deleteDriveFile, deleteGoogleTokens, deleteTask, fieldText, findClientSecretPath, getCalendar, getCalendarColors, getCalendarEvent, getGoogleAccessToken, googleApiError, googleAuthFlow, googleCalendarSyncTaskDef, googleConfigDir, googleSecretsDir, googleTokenPath, groupByCalendar, isCalendarSyncDue, isClientSettableEventId, isDeniedAccessRole, isGoogleApiError, isIsoDateTimeWithOffset, isTextMimeType, isUnpushed, legacyGoogleTokenPath, listCalendarEvents, listCalendars, listDriveFiles, listTaskLists, listTasks, loadCalendarLastSyncedAt, loadCalendarShadow, loadCalendarSyncToken, loadClientSecret, loadGoogleTokens, locallyChangedFields, locallyDeletedIds, locallyEditedIds, mayAdoptExisting, mergeGoogleTokens, mergeIntoExisting, mergeShadow, orphanedCalendarId, pickBoundary, planRecord, pullableEvents, pushCalendarForCollection, pushCollectionNow, pushableMap, readDriveFile, releaseOrphanedCalendarToken, resolveEventSpan, saveCalendarShadow, saveCalendarSyncToken, saveGoogleTokens, shadowUpdates, syncCalendarEvents, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, toCalendarSummary, toCollectionDateTime, toCollectionRecord, toDriveFileSummary, toEventSummary, toGoogleEventTime, toShadowEvent, toTaskListSummary, toTaskSummary, uncompleteTask, unlinkGoogle, unpushedFor, unsentLocalEdits, unsyncedGroups, updateCalendarEvent, updateTask, waitForAuthCode, withCalendarLock, withKeyedLock, zoneSuffixOf };
2266
2441
 
2267
2442
  //# sourceMappingURL=index.js.map