Some checks failed
Release / build (push) Failing after 2m53s
Add Syncthing installation detection (PATH + config file check) to both the tray app and setup installer. When missing, the tray shows an "Install Syncthing..." menu item and the setup opens the download page. Rewrite README with Mermaid topology graph, per-binary dependency tables, project layout, API endpoint reference, and shields.io badges. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
221 lines
8.1 KiB
Markdown
221 lines
8.1 KiB
Markdown
<h1 align="center">
|
|
<img src="assets/icon-128.png" width="80" alt="SyncWarden icon" /><br />
|
|
SyncWarden
|
|
</h1>
|
|
|
|
<p align="center">
|
|
Lightweight system tray wrapper for <a href="https://syncthing.net/">Syncthing</a>. Cross-platform, native-feeling, ~10 MB.
|
|
</p>
|
|
|
|
<p align="center">
|
|
<img src="https://img.shields.io/badge/Go-1.24+-00ADD8?logo=go&logoColor=white" alt="Go 1.24+" />
|
|
<img src="https://img.shields.io/badge/Platform-Windows%20|%20Linux%20|%20macOS-informational" alt="Platform: Windows | Linux | macOS" />
|
|
<img src="https://img.shields.io/badge/license-MIT-green" alt="MIT License" />
|
|
<br />
|
|
<a href="https://git.davoryn.de/calic/syncwarden/releases"><img src="https://img.shields.io/badge/release-v0.2.0-blue?logo=gitea&logoColor=white" alt="Latest Release" /></a>
|
|
<a href="https://git.davoryn.de/calic/syncwarden/actions"><img src="https://img.shields.io/badge/CI-Gitea%20Actions-success?logo=gitea&logoColor=white" alt="CI" /></a>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<img src="assets/icon-preview.png" alt="Tray icon states: idle, syncing, paused, error, disconnected" />
|
|
</p>
|
|
|
|
## Features
|
|
|
|
- **Tray icon** with 5 states: idle (green), syncing (blue), paused (gray), error (red), disconnected (dark gray)
|
|
- **Real-time monitoring** via Syncthing event API (long-polling) + periodic health checks
|
|
- **Transfer rates** in tooltip and menu
|
|
- **Context menu**: folder list, recent files, conflict counter, pause/resume, rescan, restart
|
|
- **Embedded admin panel** using the system browser engine (Edge WebView2 / WebKit / WebKit2GTK)
|
|
- **OS notifications** for sync complete, device connect/disconnect, new device requests, conflicts
|
|
- **Settings** toggleable via menu checkboxes (persisted to JSON config)
|
|
- **Auto-start Syncthing** with crash recovery and supervised restart
|
|
- **API key auto-discovery** from Syncthing's `config.xml`
|
|
- **Syncthing detection** — prompts with download link if Syncthing is not installed
|
|
|
|
## How It Works
|
|
|
|
SyncWarden sits in the system tray and communicates with a local Syncthing instance via its REST API. It never touches your files directly — all sync operations are handled by Syncthing itself.
|
|
|
|
```mermaid
|
|
graph TB
|
|
subgraph OS["Operating System"]
|
|
tray["System Tray Icon"]
|
|
notif["OS Notifications"]
|
|
browser["Default Browser"]
|
|
fm["File Manager"]
|
|
end
|
|
|
|
subgraph SW["SyncWarden"]
|
|
subgraph tray_bin["syncwarden (tray binary)"]
|
|
app["Tray App"]
|
|
menu["Context Menu"]
|
|
mon["Monitor"]
|
|
evl["Event Listener<br/><small>long-poll /rest/events</small>"]
|
|
poll["Health Poller<br/><small>every 3s</small>"]
|
|
proc["Process Manager<br/><small>auto-start + restart</small>"]
|
|
cfg["Config<br/><small>JSON file</small>"]
|
|
end
|
|
|
|
panel_bin["syncwarden-panel<br/><small>(embedded browser)</small>"]
|
|
setup_bin["syncwarden-setup<br/><small>(installer)</small>"]
|
|
end
|
|
|
|
subgraph ST["Syncthing (localhost:8384)"]
|
|
api["REST API"]
|
|
webui["Web UI"]
|
|
sync["Sync Engine"]
|
|
end
|
|
|
|
remote["Remote Devices"]
|
|
|
|
%% Tray app connections
|
|
app --> tray
|
|
app --> notif
|
|
app --> menu
|
|
menu -- "Open folder" --> fm
|
|
menu -- "Open Admin Panel" --> panel_bin
|
|
panel_bin -- "renders" --> webui
|
|
menu -- "Install Syncthing..." --> browser
|
|
|
|
%% Monitor connections
|
|
app --> mon
|
|
mon --> evl
|
|
mon --> poll
|
|
evl -- "events" --> api
|
|
poll -- "health + connections" --> api
|
|
menu -- "pause / rescan / restart" --> api
|
|
|
|
%% Process management
|
|
app --> proc
|
|
proc -- "start / stop / supervise" --> ST
|
|
|
|
%% Config
|
|
app --> cfg
|
|
|
|
%% Syncthing
|
|
sync <--> remote
|
|
|
|
%% Styling
|
|
classDef swbin fill:#2d5a27,stroke:#4a8,color:#fff
|
|
classDef stbox fill:#1a4a6a,stroke:#3a8abf,color:#fff
|
|
classDef osbox fill:#555,stroke:#888,color:#fff
|
|
|
|
class app,menu,mon,evl,poll,proc,cfg swbin
|
|
class panel_bin,setup_bin swbin
|
|
class api,webui,sync stbox
|
|
class tray,notif,browser,fm osbox
|
|
```
|
|
|
|
### Data Flow
|
|
|
|
1. **Event Listener** long-polls `GET /rest/events` — receives real-time sync events (file changes, device connections, folder state changes)
|
|
2. **Health Poller** checks `/rest/noauth/health` and `/rest/system/connections` every 3 seconds — detects connection loss and calculates transfer rates
|
|
3. **Monitor** aggregates both streams into a single status snapshot (icon state, device count, rates, recent files, conflicts)
|
|
4. **Tray App** renders the status as an icon + tooltip + menu updates, and dispatches OS notifications for configured events
|
|
|
|
## Architecture
|
|
|
|
SyncWarden ships as three separate binaries to avoid main-thread conflicts between systray and webview:
|
|
|
|
| Binary | Purpose | CGO |
|
|
|--------|---------|-----|
|
|
| `syncwarden` | Tray icon, menu, monitoring, notifications, process management | No |
|
|
| `syncwarden-panel` | Embedded browser showing Syncthing admin UI | Yes |
|
|
| `syncwarden-setup` | Cross-platform installer / uninstaller | No |
|
|
|
|
### Project Layout
|
|
|
|
```
|
|
cmd/
|
|
syncwarden/ Entry point for tray binary
|
|
panel/ Entry point for embedded browser panel
|
|
setup/ Cross-platform installer
|
|
icongen/ Icon generation utility (dev tool)
|
|
internal/
|
|
config/ Config persistence + platform-specific paths
|
|
icons/ Pre-rendered tray icons (5 states, PNG + ICO)
|
|
monitor/ State aggregation: folders, speed, recent files, conflicts
|
|
notify/ OS notification wrapper
|
|
syncthing/ REST API client, event listener, process manager, detection
|
|
tray/ Tray UI: menu, tooltip, panel launcher
|
|
```
|
|
|
|
## Installation
|
|
|
|
### From release
|
|
|
|
Download the latest release for your platform from [Releases](https://git.davoryn.de/calic/syncwarden/releases) and run `syncwarden-setup`.
|
|
|
|
If Syncthing is not installed, the setup will open the [download page](https://syncthing.net/downloads/) for you.
|
|
|
|
### From source
|
|
|
|
Requires Go 1.24+ and CGO (MinGW-w64 on Windows) for the panel binary.
|
|
|
|
```bash
|
|
# Tray binary (pure Go, no CGO needed)
|
|
go build -o syncwarden ./cmd/syncwarden
|
|
|
|
# Panel binary (requires CGO + C++ compiler)
|
|
CGO_ENABLED=1 go build -o syncwarden-panel ./cmd/panel
|
|
|
|
# Setup
|
|
go build -o syncwarden-setup ./cmd/setup
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Config file location:
|
|
- **Windows**: `%LOCALAPPDATA%\syncwarden\config.json`
|
|
- **Linux**: `~/.config/syncwarden/config.json`
|
|
- **macOS**: `~/Library/Application Support/syncwarden/config.json`
|
|
|
|
The API key is auto-discovered from Syncthing's `config.xml` on first run. All settings are configurable via the tray menu.
|
|
|
|
## Dependencies
|
|
|
|
### Tray binary (`syncwarden`)
|
|
|
|
| Dependency | Purpose |
|
|
|------------|---------|
|
|
| [energye/systray](https://github.com/energye/systray) | System tray integration (icon, menu, click events) |
|
|
| [fogleman/gg](https://github.com/fogleman/gg) | 2D graphics for icon rendering |
|
|
| [gen2brain/beeep](https://github.com/gen2brain/beeep) | Cross-platform OS notifications |
|
|
|
|
### Panel binary (`syncwarden-panel`)
|
|
|
|
| Dependency | Purpose |
|
|
|------------|---------|
|
|
| [webview/webview_go](https://github.com/webview/webview_go) | Embedded browser (Edge WebView2 / WebKit / WebKit2GTK) |
|
|
|
|
### Setup binary (`syncwarden-setup`)
|
|
|
|
No external dependencies — uses only the Go standard library and `internal/config` for path resolution.
|
|
|
|
### Build-time only
|
|
|
|
| Tool | Purpose |
|
|
|------|---------|
|
|
| [goreleaser/nfpm](https://github.com/goreleaser/nfpm) | `.deb` package generation (CI only) |
|
|
|
|
## Syncthing REST API Usage
|
|
|
|
SyncWarden communicates with Syncthing via its local REST API. All requests go to `localhost:8384` (configurable) and are authenticated with the `X-API-Key` header.
|
|
|
|
| Endpoint | Purpose |
|
|
|----------|---------|
|
|
| `GET /rest/noauth/health` | Connection health check (no auth) |
|
|
| `GET /rest/system/connections` | Device status + byte counters for rate calculation |
|
|
| `GET /rest/config` | Folder and device configuration |
|
|
| `GET /rest/db/status` | Per-folder sync state |
|
|
| `GET /rest/events` | Long-poll event stream (30s timeout) |
|
|
| `POST /rest/system/pause` | Pause all syncing |
|
|
| `POST /rest/system/resume` | Resume all syncing |
|
|
| `POST /rest/db/scan` | Trigger folder rescan |
|
|
| `POST /rest/system/restart` | Restart Syncthing |
|
|
|
|
## License
|
|
|
|
MIT
|