# Dev setup How to get `@mac-sync` running on a development machine. ## Prerequisites - macOS 13+ (matches `Package.swift:7` platform requirement) - Xcode command-line tools (`swift --version` >= 5.9, per `Package.swift:1`) - [Bun](https://bun.sh) — server and web runtime (`src/server/package.json:7-10`, `web/package.json:7-10`) - PostgreSQL 14+ with `gen_random_uuid()` available (used in `SendQueueRepo.ts:152`) - For the Linux server target: systemd (`app.manifest.yaml:42`) ## Clone and resolve packages ```sh cd ~/Code/@applications git clone @mac-sync cd @mac-sync swift package resolve # pulls GRDB, Alamofire, SwiftyJSON, Swifter ``` Local SwiftPM dependencies (`Package.swift:9-15`) live in `~/Code/@packages/@swift/`: - `agent-core`, `menu-bar`, `sync-framework`, `logging`, `settings` - `@tray/tray-resources` If `swift package resolve` complains about a missing local package, clone the corresponding repo into `~/Code/@packages/@swift///`. ## Build the Mac client ```sh make build # Makefile:59-61 -> swift build --product MacSyncApp make run # Makefile:78-79 -> .build/debug/MacSyncApp ``` `make build` produces `.build/debug/MacSyncApp`. The app is a menu-bar executable; it stays in the dock-less tray once running. Look for the `MacSyncShared/Storage/ActivityLog` entries in stderr to confirm modules are ticking. Tests: ```sh make test # Makefile:71-73 -> swift test (all test targets in Package.swift:113-157) ``` ## Boot the server ```sh cd src/server cp .env.example .env # if present; otherwise set vars manually bun install bun run dev # src/server/package.json:7 ``` Required environment (read by `src/server/src/app/config.ts`): - `DATABASE_URL=postgres://…/icloud` - `SSO_VALIDATE_URL` — endpoint hit by the `ssoRequired` middleware for `/my/*` (`src/server/src/app/server.ts:79`) - `SERVICE_TOKEN` — bearer for `/admin/*` (`src/server/src/app/server.ts:83`) The server listens on the port from `app.manifest.yaml:44` (3201 in prod). First boot runs all migrations in order: `src/server/src/app/server.ts:36-52`. Health checks: ```sh curl http://localhost:3201/health # server.ts:56 curl http://localhost:3201/health/deep # server.ts:57-66 — also pings the DB ``` ## Boot the web SPA ```sh cd web bun install bun run dev # vite --port 5200 (web/package.json:7) ``` The dev server hot-reloads against the API on `localhost:3201`. For production the SPA is built (`bun run build`) into `web/dist/` and that directory is shipped inside the Mac app bundle (`webapp/` subresource) or served by the server. ## Wire the Mac to the server `LocalWebServer` (`@packages/shared/Sources/MacSyncShared/WebServer/LocalWebServer.swift:42-110`) exposes the dev SPA on `http://localhost:8765` and an editable settings endpoint: ```sh curl http://localhost:8765/api/settings # {"serverURL":"http://10.0.0.11:3201","webServerPort":8765, …} curl -X PUT http://localhost:8765/api/settings \ -H 'content-type: application/json' \ -d '{"serverURL":"http://localhost:3201"}' ``` For local end-to-end work, set `serverURL` to `http://localhost:3201` and restart `MacSyncApp` so `DeviceRegistration` re-registers against the local backend. ## Permissions to grant on first run Each module needs an OS permission. Approve when prompted: - **iMessage**: Full Disk Access (to read `~/Library/Messages/chat.db`). Module surfaces `.fullDiskAccessRequired` if missing (`@packages/imessage/Sources/IMessageSync/SyncManager.swift:36`). - **iPhoto**: Photos library access (`PHPhotoLibrary`). Modal handled by `IPhotoSync.requestAuthorization()`. - **iMail**: Automation > Mail. - **iCal**: Calendars (`EKEventStore.requestFullAccessToEvents`). - **iReminders**: Reminders (`EKEventStore.requestFullAccessToReminders`). - **iNotes**: Automation > Notes (`@packages/inotes/Sources/INoteSync/SyncManager.swift:96-100`). If you decline, the module sets its error state (e.g. `.calendarAccessRequired`) and skips cycles until you re-grant. Click the menu-bar status row to deep-link into System Settings. ## Running a single test target ```sh swift test --filter MacSyncSharedTests swift test --filter IMessageSyncTests swift test --filter ICalSyncTests ``` All test targets are declared in `Package.swift:113-157`. ## Common dev problems - **`make build` fails with "no such package"**: the local SwiftPM siblings under `~/Code/@packages/@swift/` are missing. Clone them, then `swift package resolve` again. - **`bun run dev` (server) fails on `gen_random_uuid()`**: enable the `pgcrypto` extension on the Postgres database (or use Postgres 13+). - **The Mac app starts but the menu icon never appears**: check stderr for `LocalWebServer: webapp directory not found` (`LocalWebServer.swift:151`). In dev, the resolver expects `/web/dist/`; run `cd web && bun run build` once.