@mulmoclaude/core 5.3.0 → 5.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 (43) hide show
  1. package/README.md +17 -1
  2. package/assets/helps/custom-view-remote.md +19 -10
  3. package/assets/helps/custom-view.md +2 -2
  4. package/dist/collection/core/viewChatPolicy.d.ts +15 -6
  5. package/dist/collection/firestore.cjs +2 -1
  6. package/dist/collection/firestore.cjs.map +1 -1
  7. package/dist/collection/firestore.js +3 -2
  8. package/dist/collection/firestore.js.map +1 -1
  9. package/dist/collection/index.cjs +15 -6
  10. package/dist/collection/index.cjs.map +1 -1
  11. package/dist/collection/index.js +15 -6
  12. package/dist/collection/index.js.map +1 -1
  13. package/dist/collection/registry/server/index.cjs +2 -2
  14. package/dist/collection/registry/server/index.js +2 -2
  15. package/dist/collection/server/firestoreDocs.d.ts +10 -0
  16. package/dist/collection/server/index.cjs +2 -2
  17. package/dist/collection/server/index.js +2 -2
  18. package/dist/collection-watchers/index.cjs +2 -2
  19. package/dist/collection-watchers/index.js +2 -2
  20. package/dist/{discovery-CDXYswtw.cjs → discovery-B79IxEM6.cjs} +2 -3
  21. package/dist/discovery-B79IxEM6.cjs.map +1 -0
  22. package/dist/{discovery-B_64PBZU.js → discovery-DIGau7M8.js} +2 -3
  23. package/dist/discovery-DIGau7M8.js.map +1 -0
  24. package/dist/feeds/server/index.cjs +2 -2
  25. package/dist/feeds/server/index.js +2 -2
  26. package/dist/google/collectionPush.d.ts +29 -0
  27. package/dist/google/index.cjs +25 -6
  28. package/dist/google/index.cjs.map +1 -1
  29. package/dist/google/index.d.ts +1 -1
  30. package/dist/google/index.js +25 -7
  31. package/dist/google/index.js.map +1 -1
  32. package/dist/remote-view/index.cjs +7 -5
  33. package/dist/remote-view/index.cjs.map +1 -1
  34. package/dist/remote-view/index.d.ts +2 -2
  35. package/dist/remote-view/index.js +7 -5
  36. package/dist/remote-view/index.js.map +1 -1
  37. package/dist/{server-DfYwSX8b.cjs → server-BUbU9G-J.cjs} +2 -2
  38. package/dist/{server-DfYwSX8b.cjs.map → server-BUbU9G-J.cjs.map} +1 -1
  39. package/dist/{server-7POrhHKv.js → server-DZ7Cq7s_.js} +2 -2
  40. package/dist/{server-7POrhHKv.js.map → server-DZ7Cq7s_.js.map} +1 -1
  41. package/package.json +6 -6
  42. package/dist/discovery-B_64PBZU.js.map +0 -1
  43. package/dist/discovery-CDXYswtw.cjs.map +0 -1
@@ -16,7 +16,7 @@ export { calendarSyncDueWindowMs, isCalendarSyncDue } from './calendarSyncDue.js
16
16
  export { calendarBackfillPath, markCalendarBackfilled, needsCalendarBackfill } from './calendarBackfillState.js';
17
17
  export { stateLockPath, withCalendarStateLock, liveLockClock, type LockClock } from './calendarStateLock.js';
18
18
  export { calendarPushStatePath, clearCalendarShadow, loadCalendarShadow, mergeShadow, saveCalendarShadow, toShadowEvent, type ShadowEvent, } from './calendarPushState.js';
19
- export { isDeniedAccessRole, isUnpushed, locallyEditedIds, pushCalendarForCollection, pushCollectionNow, reportedAccessRole, sweepDeletes, unsentLocalEdits, type DeleteSweep, type DeleteSweepDeps, type PushOutcomeKind, type CalendarCollectionPushResult, type CalendarPushDeps, type CalendarPushOutcome, type CalendarWriteTarget, } from './collectionPush.js';
19
+ export { isDeniedAccessRole, isUnpushed, locallyEditedIds, pushCalendarForCollection, pushCollectionNow, pushResultFrom, reportedAccessRole, sweepDeletes, unsentLocalEdits, type DeleteSweep, type DeleteSweepDeps, type PushAttempt, type PushOutcomeKind, type CalendarCollectionPushResult, type CalendarPushDeps, type CalendarPushOutcome, type CalendarWriteTarget, } from './collectionPush.js';
20
20
  export { toGoogleEventTime, zoneSuffixOf } from './pushDateTime.js';
21
21
  export { baselineRecord, bySourceField, conflictingFields, fieldText, isClientSettableEventId, locallyChangedFields, locallyDeletedIds, mayAdoptExisting, planRecord, pushableMap, PUSHABLE_SOURCE_FIELDS, type PushableSourceField, type RecordPlan, } from './pushPlan.js';
22
22
  export { toCollectionDateTime } from './collectionDateTime.js';
@@ -5,7 +5,7 @@ import { n as writeFileAtomic } from "../root-BcS4-Kge.js";
5
5
  import { fetchWithTimeout } from "../utils/fetch.js";
6
6
  import { d as parseIsoDate, f as parseIsoDateTime } from "../itemId-4P9S_ehz.js";
7
7
  import { t as mergeIntoExisting } from "../project-B0j_Vf_Q.js";
8
- import { _t as createForwardingLogger, d as storeFor, n as discoverCollections, rt as getWorkspaceRoot, vt as createHostSlot } from "../discovery-B_64PBZU.js";
8
+ import { _t as createForwardingLogger, d as storeFor, n as discoverCollections, rt as getWorkspaceRoot, vt as createHostSlot } from "../discovery-DIGau7M8.js";
9
9
  import { t as mulmoConfigDir } from "../paths-CkJxNZ7T.js";
10
10
  import { promises } from "node:fs";
11
11
  import path, { join } from "node:path";
@@ -2030,9 +2030,22 @@ var UNPUSHED_KINDS = ["conflict", "error"];
2030
2030
  /** Whether this outcome leaves a local edit that only exists locally, so the
2031
2031
  * pull must not overwrite the record and the baseline must not advance. */
2032
2032
  var isUnpushed = (kind) => UNPUSHED_KINDS.includes(kind);
2033
- function tally(slug, attempts, deletes) {
2033
+ /** The whole report one run produces, from what each record's push did and what
2034
+ * the delete sweep did.
2035
+ *
2036
+ * A sweep's refusal goes to `keptInGoogle`, NEVER to `skipped`: that list means
2037
+ * "this push did not do what you asked", and a refusal means "the event was
2038
+ * deliberately left standing" while the rest of the run carried. Merged, one
2039
+ * refusal took the caller's problem branch and hid every create and update
2040
+ * (#3272).
2041
+ *
2042
+ * Exported because it is pure — a list of attempts and a sweep, no workspace,
2043
+ * grant or clock — so the separation above is something a test drives rather
2044
+ * than argues. */
2045
+ function pushResultFrom(slug, attempts, deletes) {
2034
2046
  const outcomes = attempts.map((attempt) => attempt.outcome);
2035
2047
  const count = (kind) => outcomes.filter((outcome) => outcome.kind === kind).length;
2048
+ const messagesOf = (kind) => outcomes.flatMap((outcome) => outcome.kind === kind ? [outcome.message] : []);
2036
2049
  return {
2037
2050
  slug,
2038
2051
  created: count("created"),
@@ -2040,8 +2053,9 @@ function tally(slug, attempts, deletes) {
2040
2053
  conflicts: count("conflict"),
2041
2054
  localDeletes: deletes.seen,
2042
2055
  deletedInGoogle: deletes.deleted.length,
2043
- skipped: [...outcomes.flatMap((outcome) => outcome.kind === "skipped" ? [outcome.message] : []), ...deletes.skipped],
2044
- errors: [...outcomes.flatMap((outcome) => outcome.kind === "error" ? [outcome.message] : []), ...deletes.errors],
2056
+ skipped: messagesOf("skipped"),
2057
+ keptInGoogle: [...deletes.skipped],
2058
+ errors: [...messagesOf("error"), ...deletes.errors],
2045
2059
  unpushedIds: attempts.filter((attempt) => isUnpushed(attempt.outcome.kind)).map((attempt) => attempt.eventId)
2046
2060
  };
2047
2061
  }
@@ -2171,7 +2185,7 @@ async function pushCollectionNow(collection, workspaceRoot, deps = liveDeps) {
2171
2185
  });
2172
2186
  await saveCalendarShadow(calendarId, pushedShadow([outcome]), workspaceRoot);
2173
2187
  }
2174
- const result = tally(slug, attempts, await sweepDeletes(locallyDeletedIds(shadow, records.map((record) => fieldText(record[schema.primaryKey]))), schema.googleCalendar?.propagateDeletes === true, {
2188
+ const result = pushResultFrom(slug, attempts, await sweepDeletes(locallyDeletedIds(shadow, records.map((record) => fieldText(record[schema.primaryKey]))), schema.googleCalendar?.propagateDeletes === true, {
2175
2189
  fetchEvent: (eventId) => (deps.fetchEvent ?? getCalendarEvent)(accessToken, {
2176
2190
  calendarId,
2177
2191
  eventId
@@ -2311,7 +2325,7 @@ function pullableEvents(events, unpushed) {
2311
2325
  * A conflict or an error means that record now diverges from Google until
2312
2326
  * someone resolves it, which must not be silent. */
2313
2327
  function reportAutoPush(slug, result) {
2314
- const { created, updated, conflicts, skipped, errors, unpushedIds } = result;
2328
+ const { created, updated, conflicts, skipped, keptInGoogle, errors, unpushedIds } = result;
2315
2329
  if (created + updated > 0) log.info("google", "auto-pushed local calendar edits", {
2316
2330
  slug,
2317
2331
  created,
@@ -2326,6 +2340,10 @@ function reportAutoPush(slug, result) {
2326
2340
  slug,
2327
2341
  skipped
2328
2342
  });
2343
+ if (keptInGoogle.length > 0) log.warn("google", "deletions the auto push left standing in Google", {
2344
+ slug,
2345
+ keptInGoogle
2346
+ });
2329
2347
  if (errors.length > 0) log.warn("google", "auto push errors", {
2330
2348
  slug,
2331
2349
  errors
@@ -3140,6 +3158,6 @@ async function deleteDriveFile(accessToken, input) {
3140
3158
  await googleRequest(DRIVE_API_LABEL, accessToken, `${DRIVE_FILES_URL}/${encodeURIComponent(input.fileId)}`, { method: "DELETE" });
3141
3159
  }
3142
3160
  //#endregion
3143
- export { ALL_DAY_END_HINT, CANCELLED_EVENT_STATUS, DEFAULT_LIST_MAX_RESULTS, EVENT_ABSENT_STATUSES, EVENT_TIME_HINT, 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, LONE_ALL_DAY_HINT, MAX_LIST_RESULTS, MIXED_SPAN_HINT, PARTIAL_CALENDAR_WINDOW, PROTECTION_UNKNOWN, PUSHABLE_SOURCE_FIELDS, allUnpushed, anySyncedCollectionSurvives, applyPlanFor, assertSafeMimeType, authorizeGoogle, baselineRecord, brokerBaseUrl, brokerExchange, brokerRefresh, brokerStart, buildEventPatch, buildMultipartBody, buildTaskPatch, bySourceField, calendarApiError, calendarBackfillPath, calendarPushStatePath, calendarSyncDueWindowMs, calendarSyncStatePath, canonicalCalendarId, canonicalTaskListId, claimCalendarSyncIfDue, classifyDelete, classifyWrite, clearCalendarLastSyncedAt, clearCalendarShadow, clearCalendarSyncToken, clientSecretPresence, collectCalendarPages, collectionsNeedingBackfill, commitLinkedTokens, completeTask, conferenceVideoUri, configureGoogleHost, conflictingFields, createCalendarEvent, createDriveFile, createGoogleAuthFlow, createTask, deleteCalendarEvent, deleteDriveFile, deleteGoogleTokens, deleteRefusalMessage, deleteTask, eventTimeHint, fieldText, findClientSecretPath, getCalendarColors, getCalendarEvent, getCalendarMeta, getGoogleAccessToken, googleApiError, googleAuthFlow, googleCalendarSyncTaskDef, googleConfigDir, googleSecretsDir, googleTokenPath, groupByCalendar, groupsNeedingBackfill, heldBack, isCalendarDateOnly, isCalendarSyncDue, isClientSettableEventId, isDeniedAccessRole, isGoogleApiError, isIsoDateTimeWithOffset, isTextMimeType, isUnpushed, legacyGoogleTokenPath, listCalendarEvents, listCalendars, listDriveFiles, listTaskLists, listTasks, liveLockClock, loadCalendarLastSyncedAt, loadCalendarShadow, loadCalendarSyncToken, loadClientSecret, loadGoogleTokens, locallyChangedFields, locallyDeletedIds, locallyEditedIds, markCalendarBackfilled, mayAdoptExisting, mergeGoogleTokens, mergeIntoExisting, mergeShadow, needsCalendarBackfill, orphanedCalendarId, pickBoundary, planDelete, planRecord, pullProtectionFor, pullableEvents, pushAndProtect, pushCalendarForCollection, pushCollectionNow, pushableMap, readDriveFile, releaseOrphanedCalendarToken, reportedAccessRole, resolveEventSpan, resolvePartialSpanInput, resolveSpanInput, resumableToken, saveCalendarShadow, saveCalendarSyncToken, saveGoogleTokens, selfResponseStatus, shadowUpdates, stateLockPath, sweepDeletes, syncCalendarEvents, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, syncPageParams, toCalendarMeta, toCalendarSummary, toCollectionDateTime, toCollectionRecord, toDriveFileSummary, toEventSummary, toEventTimeInput, toGoogleEventTime, toShadowEvent, toTaskListSummary, toTaskSummary, toolCalendarSyncKey, uncompleteTask, unlinkGoogle, unpushedFor, unsentEditGuard, unsentLocalEdits, updateCalendarEvent, updateTask, waitForAuthCode, windowAdvance, withCalendarLock, withCalendarStateLock, withKeyedLock, withPartialWindowError, zoneSuffixOf };
3161
+ export { ALL_DAY_END_HINT, CANCELLED_EVENT_STATUS, DEFAULT_LIST_MAX_RESULTS, EVENT_ABSENT_STATUSES, EVENT_TIME_HINT, 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, LONE_ALL_DAY_HINT, MAX_LIST_RESULTS, MIXED_SPAN_HINT, PARTIAL_CALENDAR_WINDOW, PROTECTION_UNKNOWN, PUSHABLE_SOURCE_FIELDS, allUnpushed, anySyncedCollectionSurvives, applyPlanFor, assertSafeMimeType, authorizeGoogle, baselineRecord, brokerBaseUrl, brokerExchange, brokerRefresh, brokerStart, buildEventPatch, buildMultipartBody, buildTaskPatch, bySourceField, calendarApiError, calendarBackfillPath, calendarPushStatePath, calendarSyncDueWindowMs, calendarSyncStatePath, canonicalCalendarId, canonicalTaskListId, claimCalendarSyncIfDue, classifyDelete, classifyWrite, clearCalendarLastSyncedAt, clearCalendarShadow, clearCalendarSyncToken, clientSecretPresence, collectCalendarPages, collectionsNeedingBackfill, commitLinkedTokens, completeTask, conferenceVideoUri, configureGoogleHost, conflictingFields, createCalendarEvent, createDriveFile, createGoogleAuthFlow, createTask, deleteCalendarEvent, deleteDriveFile, deleteGoogleTokens, deleteRefusalMessage, deleteTask, eventTimeHint, fieldText, findClientSecretPath, getCalendarColors, getCalendarEvent, getCalendarMeta, getGoogleAccessToken, googleApiError, googleAuthFlow, googleCalendarSyncTaskDef, googleConfigDir, googleSecretsDir, googleTokenPath, groupByCalendar, groupsNeedingBackfill, heldBack, isCalendarDateOnly, isCalendarSyncDue, isClientSettableEventId, isDeniedAccessRole, isGoogleApiError, isIsoDateTimeWithOffset, isTextMimeType, isUnpushed, legacyGoogleTokenPath, listCalendarEvents, listCalendars, listDriveFiles, listTaskLists, listTasks, liveLockClock, loadCalendarLastSyncedAt, loadCalendarShadow, loadCalendarSyncToken, loadClientSecret, loadGoogleTokens, locallyChangedFields, locallyDeletedIds, locallyEditedIds, markCalendarBackfilled, mayAdoptExisting, mergeGoogleTokens, mergeIntoExisting, mergeShadow, needsCalendarBackfill, orphanedCalendarId, pickBoundary, planDelete, planRecord, pullProtectionFor, pullableEvents, pushAndProtect, pushCalendarForCollection, pushCollectionNow, pushResultFrom, pushableMap, readDriveFile, releaseOrphanedCalendarToken, reportedAccessRole, resolveEventSpan, resolvePartialSpanInput, resolveSpanInput, resumableToken, saveCalendarShadow, saveCalendarSyncToken, saveGoogleTokens, selfResponseStatus, shadowUpdates, stateLockPath, sweepDeletes, syncCalendarEvents, syncCalendarForCollection, syncCalendarGroup, syncDueCalendarCollections, syncNewCalendarCollections, syncPageParams, toCalendarMeta, toCalendarSummary, toCollectionDateTime, toCollectionRecord, toDriveFileSummary, toEventSummary, toEventTimeInput, toGoogleEventTime, toShadowEvent, toTaskListSummary, toTaskSummary, toolCalendarSyncKey, uncompleteTask, unlinkGoogle, unpushedFor, unsentEditGuard, unsentLocalEdits, updateCalendarEvent, updateTask, waitForAuthCode, windowAdvance, withCalendarLock, withCalendarStateLock, withKeyedLock, withPartialWindowError, zoneSuffixOf };
3144
3162
 
3145
3163
  //# sourceMappingURL=index.js.map