Self-hosted Obsidian vault sync — fresh rewrite of eari-sync.
shared/ — protocol types (wire-compatible with eari-sync v1 servers)server/ — Node 22.5+ server (Fastify + node:sqlite, zero native deps, Termux-friendly)plugin/ — Obsidian plugin (works desktop + mobile, uses requestUrl)scripts/ — deploy helpersnpm install # install all workspaces
npm run build # build shared + server + plugin
npm test # server test suite (vitest)
npm run deploy:plugin # copy plugin build into the PC vault + seed settings
Server CLI (from server/):
npm run cli -- init --vault <id> --secret <secret>
npm run cli -- doctor
npm run start # listen (env: EARI_SYNC_DATA_DIR / PORT / HOST / CERT / KEY)
POST /api/v1/auth/testGET /api/v1/vaults/:id/metaGET /api/v1/vaults/:id/changes?since=&limit=GET /api/v1/vaults/:id/files (new: list live files)GET/PUT/DELETE /api/v1/vaults/:id/files/*POST /api/v1/vaults/:id/moveGET /api/v1/vaults/:id/trash, POST .../trash/restoreGET /api/v1/vaults/:id/ws?token=&cid= (WebSocket change notifications)POST/GET /api/v1/vaults/:id/shares, PATCH/DELETE .../shares/:shareId, public GET /share/:shareId[/raw]Auth: Authorization: Bearer <vault secret> + X-Vault-Id / X-Client-Id.
lastSeq), hash-matching before download so
re-syncs are cheap.X-Base-Version;
identical content is an idempotent no-op server-side.name.conflict-<device>-<ts>.ext (or take the
server version per settings); remote deletes of locally-modified files are kept..obsidian config syncs too (caches/workspace and the plugin's own folder excluded).D:\.working\obsidianify\.obsidian\plugins\syncify (auto on npm run deploy:plugin)~/eari-sync (data dir ~/eari-sync-data), restart via
bash ~/eari-sync/scripts/restart.sh — legacy data dir/config is read as-is.