No description
Find a file
Natalie b104ee1b12 fix(@mac-sync): 🐛 add debug flag for send-queue tracing
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-21 19:39:09 -07:00
.claude feat(@mac-sync): update handoff docs with verified paths 2026-05-15 21:17:32 -07:00
.forgejo/workflows merge: restore plum-only additive files atop apricot baseline 2026-05-15 17:06:07 -07:00
.playwright-mcp apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
.project merge: restore plum-only additive files atop apricot baseline 2026-05-15 17:06:07 -07:00
@packages fix(@mac-sync): 🐛 add debug flag for send-queue tracing 2026-05-21 19:39:09 -07:00
deploy fix(@applications/mac-sync): 🐛 fix identity validation logic 2026-05-17 23:41:30 -07:00
docs merge: restore plum-only additive files atop apricot baseline 2026-05-15 17:06:07 -07:00
handoffs feat(@mac-sync): update handoff docs with verified paths 2026-05-15 21:17:32 -07:00
scripts apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
src feat(photos): improve search weighting and type safety 2026-05-19 00:04:30 -07:00
web feat(photos): improve search weighting and type safety 2026-05-19 00:04:30 -07:00
.gitignore apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
.mcp.json apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
app.manifest.yaml merge batch 1: top-level metadata, shared, ical, imail 2026-05-15 18:02:04 -07:00
CLAUDE.md merge batch 1: top-level metadata, shared, ical, imail 2026-05-15 18:02:04 -07:00
deploy-to-plum-dist-from-src apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
docker-compose.dev.yml feat(@applications): implement mac-sync identity and photo workflows 2026-05-17 20:27:05 -07:00
m-quinn-messages-after-port.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
m-quinn-messages-search-after-load.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
m-quinn-messages-search-verify.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
m-quinn-thread-focus.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
mac-sync-dashboard-deployed.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
mac-sync-search-cin-2.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
mac-sync-search-cin.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
Makefile plum baseline: Phase 1/3/4/5 work (BaseSyncManager, SendQueue layer, ireminders, inotes) 2026-05-15 17:05:13 -07:00
no-params.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
Package.resolved merge: restore plum-only additive files atop apricot baseline 2026-05-15 17:06:07 -07:00
Package.swift merge batch 1: top-level metadata, shared, ical, imail 2026-05-15 18:02:04 -07:00
README.md merge: restore plum-only additive files atop apricot baseline 2026-05-15 17:06:07 -07:00
search-cin-params.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-cin.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-click-result.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-final.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-q-param.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-results-count.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
search-settled.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
thread-dates-highlight.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
thread-focus-message.png apricot baseline: contacts-sync-core + BlobSyncManager + embedding/search/sync-history 2026-05-15 17:05:39 -07:00
VERSION.json plum baseline: Phase 1/3/4/5 work (BaseSyncManager, SendQueue layer, ireminders, inotes) 2026-05-15 17:05:13 -07:00

@mac-sync

Unified macOS sync agent. One menu-bar app on the Mac, one Bun/Hono server on the LAN, one React SPA in the browser — six personal data domains kept in step: Messages, Photos, Mail, Calendar, Reminders, Notes.

@mac-sync collapses what used to be three separate agents (mac-imessage-sync, mac-iphoto-sync, mac-imail-sync) into a single Swift package with one BaseSyncManager lifecycle, one SendQueueClient outbound poller, one AppleScriptEscape helper, and one Postgres schema (icloud.*).

At a glance

Module Direction OS surface Read interval Outbound interval
iMessage bidirectional ~/Library/Messages/chat.db 30s 30s
iPhoto read-only Photos.framework 300s
iMail read-only (*) Mail.app via AppleScript 300s
iCal bidirectional EventKit 300s 60s
iReminders bidirectional EventKit 300s 60s
iNotes bidirectional Notes.app via AppleScript 600s 60s

(*) IMailSync.SyncManager.sendEmail exists but is unwired; see known limitations.

Intervals verified in BaseSyncManager super.init(...) calls and SendQueueClient(label:..., interval:) constructions; see architecture for citations.

Repository layout

@packages/
  shared/       MacSyncShared SwiftPM target
                  Sync/        BaseSyncManager, SendQueueClient, SyncConnectionError
                  Storage/     ActivityLog, ConfigFile
                  Transport/   Shared (server URL resolution), DeviceRegistration
                  Util/        AppleScriptEscape, ContentTypeMapping, PhoneUtils
                  WebServer/   LocalWebServer (localhost:8765, settings + SPA)
  imessage/     IMessageSync   (bidirectional, legacy icloud.send_queue table)
  iphoto/       IPhotoSync     (read-only Mac to server, with binary uploads)
  imail/        IMailSync      (Mail.app AppleScript reader; Sender unwired)
  ical/         ICalSync       (bidirectional, EventKit + calendar_send_queue)
  ireminders/   IReminderSync  (bidirectional, EventKit + reminder_send_queue)
  inotes/       INoteSync      (bidirectional, AppleScript + note_send_queue)
src/client/     MacSyncApp     (executable menu-bar app)
src/server/     Bun + Hono + PostgreSQL (TypeScript)
web/            React SPA dashboard (Vite, react-query)
deploy/         install.sh, deploy-remote.sh, systemd units, nginx config

(See Package.swift:21-157 for the canonical target list.)

Get started

Per-module deep dives:

Build & test

make build       # swift build --product MacSyncApp  (Makefile:60-61)
make test        # swift test                        (Makefile:71-73)
make run         # build then run .build/debug/MacSyncApp

Server:

cd src/server && bun run dev    # src/server/package.json:7

Web:

cd web && bun run dev           # vite --port 5200  (web/package.json:7)

Safety

  • NEVER commit — an external service handles commits (CLAUDE.md:46).
  • NEVER pkill node / killall node — kills Claude Code sessions.
  • NEVER use file: or link: in package.json — edit source, publish, bump.