Metadata-Version: 2.4
Name: synadrive-desktop
Version: 0.1.0
Summary: SynaDrive cross-platform desktop sync engine, selective sync, conflict resolver, and terminal tray.
Author: SynaVue Technologies
Author-email: SynaVue Technologies <dev@synavuetechnologies.com>
License: Proprietary
Project-URL: Homepage, https://synavuetechnologies.com/synadrive
Project-URL: Repository, https://github.com/synavue/synadrive-desktop
Project-URL: Documentation, https://docs.synavuetechnologies.com/synadrive/desktop
Keywords: sync,cloud-storage,desktop,file-sync
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Filesystems
Classifier: Topic :: Internet :: File Transfer Protocol (FTP)
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: httpx>=0.24
Requires-Dist: watchdog>=3.0
Requires-Dist: rich>=13.0
Requires-Dist: platformdirs>=3.0
Requires-Dist: keyring>=24.0
Requires-Dist: cryptography>=41.0

# SynaDrive Desktop — Enterprise Sync Client

Cross-platform Python sync engine for SynaDrive. Runs on macOS, Linux, and
Windows from a single source tree — no native toolchains required.

## Capability matrix

| Capability                                | Status |
| ----------------------------------------- | :----: |
| Bidirectional sync (cursor-paged delta)   | ✅ |
| Selective sync per folder id              | ✅ |
| Conflict resolver (keep_local / remote / **both**) | ✅ |
| Local SQLite manifest (idempotent restart)| ✅ |
| Watchdog + polling-fallback file watcher  | ✅ |
| Terminal "tray" via `rich.live`           | ✅ |
| **Native desktop GUI** (Tkinter, sidebar + 8 panels) | ✅ |
| **Local web dashboard** (browser, security headers, CSRF, token-gated, rate-limited) | ✅ |
| **System tray icon** (`pystray` + Pillow, optional) | ✅ |
| **Profile separation** (multi-account)    | ✅ |
| **OS keychain token vault** (+encrypted file fallback) | ✅ |
| **MDM-style enterprise policy** (`/etc/synadrive/policy.json`) | ✅ |
| **Single-instance lock** per profile      | ✅ |
| **DLP**: extension / filename / content scans before upload | ✅ |
| **Bandwidth throttle** (token bucket, both directions) | ✅ |
| **Schedule** (business-hours / Wi-Fi-only / metered awareness) | ✅ |
| **Zero-knowledge client-side vault** (per-folder, scrypt-derived AES-GCM) | ✅ |
| **Audit log** (rotating JSONL, optional server shipping) | ✅ |
| **Pre/post hooks** (`pre_sync`, `post_upload`, …)| ✅ |
| **Desktop notifications**                 | ✅ |
| **`doctor`** preflight diagnostics        | ✅ |
| **Backup-only mode** (never deletes locally) | ✅ |
| **Cross-platform service installers** (launchd / systemd / Scheduled Task) | ✅ |
| Proxy support (env / config)              | ✅ |
| Filesystem-mode 0600/0700 on all secrets  | ✅ |
| AES-GCM via `cryptography` (HMAC fallback when absent) | ✅ |

## Install

```bash
pip install -e SynaDrive/desktop          # core
pip install -e 'SynaDrive/desktop[gui]'   # core + system-tray icon
```

Core deps: `httpx`, `watchdog`, `rich`, `platformdirs`, `keyring`, `cryptography`.
The `[gui]` extra additionally pulls `pystray` + `Pillow` for the optional
system-tray icon. The Tkinter GUI itself ships with the Python stdlib on
all three OSes.

## Run as a regular desktop app

```bash
synadrive gui            # opens the native window (Tkinter, sidebar + 8 panels)
synadrive webui          # alternative: browser-based dashboard on 127.0.0.1
```

See `packaging/README.md` for the per-platform installers that register
the sync daemon as a user-level service (macOS launchd, Linux systemd,
Windows Scheduled Task) and add a launcher shortcut.

## Quickstart (CLI, headless / power users)

```bash
synadrive init --root ~/SynaDrive --base-url https://drive.synavuetechnologies.com
echo "$SYNADRIVE_TOKEN" | synadrive token set       # stored in OS keychain
synadrive doctor                                    # preflight checks
synadrive start --foreground
# ...elsewhere:
synadrive status
synadrive-tray
synadrive selective add fld_abc123
synadrive conflicts list
synadrive audit tail --limit 20
synadrive stop
```

## Enterprise deployment

1. **Deploy a policy file** at `/etc/synadrive/policy.json` (POSIX) or
   `%ProgramData%\synadrive\policy.json` (Windows):

   ```json
   {
     "enforced": {
       "base_url": "https://drive.acme-internal.com",
       "conflict_policy": "keep_both",
       "require_token_in_keyring": true,
       "audit_shipping": true,
       "dlp_blocked_extensions": [".pem", ".key", ".pfx"],
       "schedule_business_hours_only": true,
       "schedule_wifi_only": true,
       "max_file_size_mb": 5000
     },
     "defaults": {
       "bandwidth_limit_kb": 2048
     }
   }
   ```

   Enforced keys are applied on every start and the user cannot change them
   (`synadrive selective add` will refuse if `selective_sync` is locked,
   etc.).

2. **Provision per-user**: distribute `synadrive init --base-url ...` via your
   MDM, then have each user run `synadrive token set` once.

3. **Multi-profile**: a single workstation can host several accounts:
   `SYNADRIVE_PROFILE=work synadrive start --foreground` keeps a separate
   config dir, state DB, audit log, and lock file from `default`.

## Zero-knowledge vault

```bash
synadrive vault enable --folder Secret
export SYNADRIVE_VAULT_PASSPHRASE="correct horse battery staple"
synadrive start --foreground
```

Files under `Secret/` are AES-GCM-encrypted with a passphrase-derived key
(`scrypt`, salted per-file) **before** any byte leaves the host. The server
never sees plaintext.

## Layout

- `synadrive_desktop/config.py`    — XDG-aware profile config; never stores tokens.
- `synadrive_desktop/security.py`  — TokenVault, encrypt_blob, SingleInstanceLock, machine fingerprint.
- `synadrive_desktop/policy.py`    — MDM-style enforced/defaults policy.
- `synadrive_desktop/state.py`     — SQLite manifest (items, meta, conflicts).
- `synadrive_desktop/watcher.py`   — watchdog + polling fallback.
- `synadrive_desktop/dlp.py`       — pre-upload DLP scanner.
- `synadrive_desktop/bandwidth.py` — TokenBucket + Schedule (business hours / wifi / metered).
- `synadrive_desktop/vault.py`     — scrypt + AES-GCM client-side vault.
- `synadrive_desktop/audit.py`     — rotating JSONL + optional server shipping.
- `synadrive_desktop/notify.py`    — desktop notifications + shell hooks.
- `synadrive_desktop/conflict.py`  — three-way resolver.
- `synadrive_desktop/engine.py`    — pull/push loop with policy/DLP/vault/audit/hooks wired in.
- `synadrive_desktop/doctor.py`    — preflight diagnostics.
- `synadrive_desktop/tray.py`      — `rich.live` terminal tray.
- `synadrive_desktop/cli.py`       — `synadrive` CLI entrypoint.

## Backend contract

The client speaks the routes added in `synavue_data_service/SynaDrive/routes/sync.py`:

| Method | Path                          | Purpose                        |
| ------ | ----------------------------- | ------------------------------ |
| GET    | `/sync/delta?cursor=&limit=`  | Cursor-paged changes feed.     |
| POST   | `/sync/register-device`       | Register / refresh device.     |
| GET    | `/sync/devices`               | List user devices.             |
| DELETE | `/sync/devices/{id}`          | Revoke a device.               |
| POST   | `/sync/conflict`              | Report a conflict + resolution.|

All routes are proxied through the API gateway catch-all at
`/api/v1/drive/sync/*` and require an `Authorization: Bearer <token>` header
plus an `X-Device-ID` header (the client sends both automatically).

## Tests

```
pytest SynaDrive/tests/test_desktop_sync.py SynaDrive/tests/test_desktop_enterprise.py SynaDrive/tests/test_desktop_ui.py -v
# 40 passed
```

