bread/bread-sync
Breadway cc456b78fe refactor: remove remote module install, extract bread-sync, make CI real
Security:
- Remove `bread modules install github:…`. Remote fetch pulled unreviewed
  third-party Lua and ran it with full bread.exec() privileges in an
  unsandboxed runtime. Module install is now local-only; parse_source
  rejects github:/git: with an explicit message.

bread-sync extracted from the workspace (parked for its own project):
- Removed from workspace members (now excluded); see bread-sync/EXTRACTION.md
- Removed the entire `bread sync` CLI surface and now-unused deps
  (bread-sync, reqwest, tar, flate2; tempfile demoted to dev-dependency)
- Removed the sync.status IPC method from breadd plus its integration tests
- Moved the generic `expand_path` helper into bread-shared (with unit tests)

CI now actually runs and gates quality:
- Trigger on master/dev (was `main` — CI had never run, not once)
- Added `cargo fmt --check` and `clippy -D warnings`; fixed 4 clippy warnings
- Dropped the macOS matrix entry (breadd is Linux-only: udev/rtnetlink);
  added the libudev-dev system dependency the Linux build needs

Hardening / honesty:
- New ipc test: daemon survives repeated reloads and the event pipeline
  resumes (the prior suite only had a single happy-path reload check)
- Docs scrubbed of sync across README/Documentation/Overview/DAEMON
- "production-ready" and "compositor-agnostic" claims reworded to match
  reality rather than aspiration

Note: bread-sync/src/export.rs held pre-existing local WIP authored outside
this change set and is intentionally excluded from this commit.
2026-05-17 00:22:21 +08:00
..
src Commiting for bread sync 2026-05-16 19:44:19 +08:00
tests Final Release of Version 1.0 2026-05-13 22:01:42 +08:00
Cargo.toml Final Release of Version 1.0 2026-05-13 22:01:42 +08:00
EXTRACTION.md refactor: remove remote module install, extract bread-sync, make CI real 2026-05-17 00:22:21 +08:00
README.md feat: add bread-sync module for snapshot and restore functionality 2026-05-12 00:20:45 +08:00

bread-sync

Sync engine for Bread — snapshot and restore desktop state via a Git remote.

Purpose

bread-sync provides the library backing bread sync commands. It handles:

  • Git operations — clone, commit, push, pull, fetch, diff via git2
  • Config serialization — read/write sync.toml (machine name, remote URL, delegates, packages)
  • Delegate file sync — rsync-style directory copy with glob excludes
  • Package snapshots — capture installed packages from pacman, pip, npm, cargo
  • Machine profiles — per-machine TOML records with hostname, tags, and last-sync timestamp

Public API

config

SyncConfig::load(config_dir: &Path) -> Result<SyncConfig>
SyncConfig::save(&self, config_dir: &Path) -> Result<()>
SyncConfig::local_repo_path() -> PathBuf   // ~/.local/share/bread/sync-repo/
bread_config_dir() -> PathBuf              // ~/.config/bread/
expand_path(path: &str) -> PathBuf         // expands ~/

git

SyncRepo::init(path: &Path) -> Result<SyncRepo>
SyncRepo::open(path: &Path) -> Result<SyncRepo>
SyncRepo::clone_from(url: &str, path: &Path) -> Result<SyncRepo>
SyncRepo::open_or_clone(url: &str, path: &Path) -> Result<SyncRepo>
SyncRepo::commit(&self, message: &str) -> Result<Option<git2::Oid>>  // None = nothing to commit
SyncRepo::push(&self, remote: &str, branch: &str) -> Result<()>
SyncRepo::pull(&self, remote: &str, branch: &str) -> Result<()>      // fast-forward only
SyncRepo::fetch(&self, remote: &str, branch: &str) -> Result<()>
SyncRepo::is_clean(&self) -> Result<bool>
SyncRepo::local_changes(&self) -> Result<Vec<(char, String)>>
SyncRepo::remote_changes(&self, remote: &str, branch: &str) -> Result<Vec<(char, String)>>
SyncRepo::working_diff(&self) -> Result<String>
SyncRepo::remote_diff(&self, remote: &str, branch: &str) -> Result<String>
SyncRepo::set_remote(&self, name: &str, url: &str) -> Result<()>
SyncRepo::last_commit_time(&self) -> Option<DateTime<Local>>

delegates

sync_dir(src: &Path, dst: &Path, exclude: &[String]) -> Result<()>
resolve_include_paths(includes: &[String]) -> Vec<(String, PathBuf)>

machine

MachineProfile::new(name: String, tags: Vec<String>) -> MachineProfile
MachineProfile::write(&self, machines_dir: &Path) -> Result<()>
MachineProfile::read(machines_dir: &Path, name: &str) -> Result<MachineProfile>
MachineProfile::list(machines_dir: &Path) -> Result<Vec<MachineProfile>>
hostname() -> String

packages

snapshot(manager: &str, dest: &Path) -> Result<bool>  // false = manager not found (non-fatal)
parse_pacman(content: &str) -> Vec<String>
parse_pip(content: &str) -> Vec<String>
parse_npm(content: &str) -> Vec<String>
parse_cargo(content: &str) -> Vec<String>

Sync repo layout

~/.local/share/bread/sync-repo/
├── bread/          ← snapshot of ~/.config/bread/
├── configs/
│   └── <basename>/ ← delegate paths
├── machines/
│   └── <name>.toml ← per-machine profiles
└── packages/
    ├── pacman.txt
    ├── pip.txt
    ├── npm.txt
    └── cargo.txt