# obsidian-sync

`obsidian-sync` keeps a local Obsidian vault synchronized with a Synology Drive folder in near real-time.

Primary use case:
- macOS local vault -> Synology Drive folder: `/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync`
- Windows Obsidian opens the same Synology folder (for example `C:\Users\<user>\SynologyDrive\obsidian-sync`)

## Features

- Bidirectional sync (`source_vault <-> synology_vault`)
- Real-time watch mode + periodic reconciliation
- First-run safe behavior with backups before overwrite/delete
- Conflict copies when both sides changed
- SQLite state tracking for deterministic updates/deletes
- Windows-safe filename collision detection (case-only conflicts)

## Install (macOS)

```bash
cd /Users/den/Desktop/obsidian-sync
python3 -m venv .venv
source .venv/bin/activate
pip install .
```

Install from PyPI (after you publish):

```bash
pip install obsidian-synology-sync
```

## Initialize

```bash
obsidian-sync init \
  --source "/ABSOLUTE/PATH/TO/YOUR/OBSIDIAN-VAULT" \
  --target "/Users/den/Library/CloudStorage/SynologyDrive-M/obsidian-sync" \
  --windows-path "C:\\Users\\<user>\\SynologyDrive\\obsidian-sync"
```

This creates:
- Config: `obsidian-sync.toml`
- State DB: `.obsidian-sync-state/state.db`

## Run

One-time sync:

```bash
obsidian-sync sync-now
```

Preview only:

```bash
obsidian-sync sync-now --dry-run
```

Continuous sync:

```bash
obsidian-sync watch
```

Status:

```bash
obsidian-sync status
```

## How Windows sync works

Recommended setup:
1. Use Synology Drive client on Windows.
2. Open Obsidian vault directly at the Synology local folder (example: `C:\Users\<user>\SynologyDrive\obsidian-sync`).
3. Keep macOS `obsidian-sync watch` running.

This way, macOS local vault changes sync to Synology, and Windows Obsidian receives updates through Synology Drive.

## Backup and conflict behavior

- Before overwrite/delete, existing files are backed up under:
  - `<synology_vault>/.obsidian-sync-backups/`
- If both sides changed before sync:
  - A `.conflict-...` copy is created for the losing side.
  - Newer file (mtime) wins for the main path.

## Auto-start on login

macOS (`launchd`):

```bash
scripts/macos/install_launchd.sh \
  --project "/Users/den/Desktop/obsidian-sync" \
  --config "/Users/den/Desktop/obsidian-sync/obsidian-sync.toml"
```

Windows (Task Scheduler):

```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\windows\install_task.ps1 `
  -ProjectDir "C:\path\to\obsidian-sync" `
  -ConfigPath "C:\path\to\obsidian-sync\obsidian-sync.toml" `
  -PythonExe "python"
```

## Build and publish (pip distributable)

Build and validate distributions:

```bash
cd /Users/den/Desktop/obsidian-sync
scripts/release/build_dist.sh
```

Upload:

```bash
# TestPyPI first
scripts/release/publish.sh testpypi

# Production PyPI
scripts/release/publish.sh pypi
```

`twine` uses `TWINE_USERNAME` and `TWINE_PASSWORD` (or keyring) for authentication.

## Notes

- Avoid storing two files that differ only by case (for Windows compatibility).
- Keep file names and paths stable between macOS and Windows.
- For very large vaults, first sync may take time.
