messenger/HANDOFF.md
2026-03-06 00:15:13 -08:00

143 lines
5.5 KiB
Markdown

# @messenger — iMessage Sync Ecosystem
Standalone iMessage sync platform: macOS agent reads the local iMessage DB, syncs to a NestJS backend, and exposes data via MCP for Claude Code.
---
## Applications
### imessage-sync — NestJS Sync API
Receives messages from macOS, stores and processes them. Pure data sync — no ML hooks.
```
imessage-sync/
├── backend/ NestJS API (port 3100)
│ ├── src/
│ │ ├── entities/ device, contact, conversation, message
│ │ ├── modules/
│ │ │ ├── devices/ Device registration + JWT auth
│ │ │ ├── sync/ Message + Contact sync endpoints
│ │ │ └── processing/ Text extraction, attachment saving (NO ML)
│ │ ├── migrations/ Sync-only schema (4 tables)
│ │ ├── health.controller.ts
│ │ ├── app.module.ts
│ │ ├── main.ts
│ │ └── data-source.ts TypeORM CLI data source
│ ├── .swcrc ESM output (type: es6, resolveFully: true)
│ └── package.json @lilith/imessage-sync-backend
├── shared/ Shared types (re-exports from @lilith/types)
└── docker-compose.yml PostgreSQL (25433) + Redis (26380)
```
**Key decisions:**
- ProcessingService stripped of: embedding queue POST, ScreeningService trigger
- All entity `@Column` decorators have explicit `type:` for SWC compatibility
- `migrationsRun: true` — app runs migrations on boot
**Commands:**
```bash
cd imessage-sync
docker compose up -d # Start PostgreSQL + Redis
cd backend && bun run build # Build (SWC, ~250ms)
cd backend && bun run start:prod # Start (port 3100)
cd backend && bun run typecheck # Typecheck (0 errors)
```
**Health:** `GET http://localhost:3100/health`
**Swagger:** `http://localhost:3100/api/docs`
### imessage-macos — Swift macOS Menu Bar Agent
Reads iMessage database locally, syncs messages to the imessage-sync backend.
```
imessage-macos/
├── Package.swift Swift package (iMessageMacos)
├── Sources/
│ ├── iMessageMacosApp.swift Main app struct + AppDelegate
│ ├── AppVersion.swift Generated from VERSION.json
│ ├── Models/
│ │ └── ActivityLog.swift
│ └── Services/
│ ├── APIClient.swift HTTP client + Keychain + payload types
│ ├── SyncManager.swift Periodic sync orchestrator
│ ├── iMessageReader.swift GRDB-based SQLite reader
│ ├── LocalWebServer.swift Local web UI server
│ └── SendService.swift
├── Makefile Build/lint/install targets
├── install.sh Full installer (build + app bundle + LaunchAgent)
├── uninstall.sh Full uninstaller
├── deploy-remote.sh SSH deploy to remote Mac
├── generate-version.sh AppVersion.swift generator
├── INSTALL.md Installation guide
├── .swiftlint.yml Lint config
└── iMessageMacos.entitlements Contacts, network, keychain access
```
**Bundle ID:** `com.lilith.imessage-macos`
**Keychain service:** `com.lilith.imessage-macos`
**App bundle:** `~/Applications/iMessageMacos.app`
**Logs:** `~/Library/Application Support/iMessageMacos/`
### imessage-mcp — MCP Server for Claude Code
Read-only access to the sync database via Model Context Protocol.
```
imessage-mcp/
├── src/
│ ├── index.ts MCP server (name: "imessage-mcp")
│ ├── db.ts PostgreSQL connection pool
│ ├── formatters.ts Message/conversation display formatting
│ └── tools/
│ ├── list-conversations.ts
│ ├── get-conversation.ts
│ ├── get-contact.ts
│ ├── search-messages.ts
│ └── get-conversation-stats.ts
├── tsup.config.ts Bundles to single ESM file
├── tsconfig.json Path mappings for MCP SDK subpath imports
└── package.json @lilith/imessage-mcp
```
**MCP config** (`.mcp.json`):
```json
"imessage": {
"command": "node",
"args": ["~/Code/@applications/@messenger/imessage-mcp/dist/index.js"],
"env": {
"DATABASE_URL": "postgresql://postgres:devpassword@10.0.0.11:25432/messenger"
}
}
```
**Symlink:** `~/Code/@packages/@ts/@mcp/imessage-mcp` → this directory
**Tools exposed:** `mcp__imessage__list_conversations`, `mcp__imessage__get_conversation`, `mcp__imessage__get_contact`, `mcp__imessage__search_messages`, `mcp__imessage__get_conversation_stats`
**Build:** `bun run build` (tsup, ~30ms)
---
## Infrastructure
| Service | Port | Container |
|------------|-------|-------------------------------|
| PostgreSQL | 25432 | production (black) |
| PostgreSQL | 25433 | local dev (docker-compose) |
| Redis | 26380 | lilith-imessage-sync-redis |
**DB:** `messenger` (was `imessage_sync`) / user: `postgres` / pass: `devpassword`
**Tables:** devices, contacts, conversations, messages (+ migrations)
---
## Remaining Work
- [ ] **Delete old MCP package**: `~/Code/@packages/@ts/@mcp/mcp-conversation-viewer/` is superseded by imessage-mcp
- [ ] **macOS agent testing**: Swift agent renamed to iMessageMacos, not yet tested against new backend
- [ ] **Production deployment**: Docker Compose is dev-only; needs production config for VPS
- [x] **Production DB rename**: Done — `messenger` on black (25432) and local dev (25433)