feat: add bread-sync module for snapshot and restore functionality

- Introduced `bread-sync` module with core functionalities for syncing system state via Git.
- Implemented `MachineProfile` struct for managing machine profiles, including methods for reading and writing profiles.
- Added package management support with snapshot capabilities for `pacman`, `pip`, `npm`, and `cargo`.
- Created comprehensive tests for sync operations, package parsing, and machine profile management.
- Enhanced `udev` adapter to include vendor and product IDs for scanned devices.
- Updated state engine to handle module clearing commands.
- Introduced Lua integration for accessing machine information and file system operations.
- Improved packaging documentation for Arch Linux and systemd service setup.
This commit is contained in:
Breadway 2026-05-12 00:20:45 +08:00
parent 96e42bc370
commit e39b168398
25 changed files with 3930 additions and 92 deletions

View file

@ -36,6 +36,7 @@ pub enum StateCommand {
id: SubscriptionId,
},
ClearSubscriptions,
ClearModules,
SetModuleStatus {
name: String,
status: ModuleLoadState,
@ -112,6 +113,10 @@ impl StateHandle {
let _ = self.command_tx.send(StateCommand::ClearSubscriptions);
}
pub fn clear_modules(&self) {
let _ = self.command_tx.send(StateCommand::ClearModules);
}
pub fn set_module_status(
&self,
name: String,
@ -236,6 +241,9 @@ async fn handle_command(
watches.clear();
subscription_count.store(0, Ordering::Relaxed);
}
StateCommand::ClearModules => {
state.write().await.modules.clear();
}
StateCommand::SetModuleStatus {
name,
status,
@ -421,6 +429,14 @@ fn apply_device_change(state: &mut RuntimeState, data: &Value, connected: bool)
.and_then(Value::as_str)
.unwrap_or("unknown")
.to_string(),
vendor_id: data
.get("vendor_id")
.and_then(Value::as_str)
.map(ToString::to_string),
product_id: data
.get("product_id")
.and_then(Value::as_str)
.map(ToString::to_string),
});
} else {
state.devices.connected.retain(|d| d.id != id);

View file

@ -57,6 +57,10 @@ pub struct Device {
pub name: String,
pub class: DeviceClass,
pub subsystem: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub vendor_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub product_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq)]