feat: system service management (gyandoot service install|remove|status)

- Create systemd + launchd service templates in resources/
- Add gyandoot-core/src/service.rs module with full lifecycle
  - systemd: user service, daemon-reload, enable, start, stop, disable
  - launchd: macOS plist, load/unload, start/stop (launchctl)
- Add 'gyandoot service install|remove|status' CLI subcommand
- Update setup wizard: prompts 'Install system service? [y/N]'
- Update install.sh: prompts user for service install after binary
- Browser auto-starts at runtime (browser_manager), no separate service needed
- Camoufox installed via npm, auto-started by GyanDoot agent loop
This commit is contained in:
2026-06-11 23:23:49 +05:30
parent f2d612bd28
commit b2650a569c
8 changed files with 615 additions and 83 deletions

View File

@@ -75,6 +75,12 @@ enum Commands {
/// Launch the TUI interface
#[command(name = "tui")]
Tui,
/// Manage GyanDoot system service (install, remove, status)
#[command(name = "service")]
Service {
#[command(subcommand)]
action: ServiceAction,
},
}
#[derive(Subcommand, Debug)]
@@ -116,6 +122,16 @@ enum BrowserAction {
},
}
#[derive(Subcommand, Debug)]
enum ServiceAction {
/// Install GyanDoot as a system service (auto-start on boot)
Install,
/// Remove the GyanDoot system service
Remove,
/// Check GyanDoot service status
Status,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
@@ -161,6 +177,9 @@ async fn main() -> anyhow::Result<()> {
Some(Commands::Tui) => {
cmd_tui().await?;
}
Some(Commands::Service { action }) => {
cmd_service(action).await?;
}
None => {
// Default: run interactive CLI mode
cmd_run(&cli.profile, "cli", None).await?;
@@ -535,4 +554,59 @@ async fn cmd_tui() -> anyhow::Result<()> {
tracing::info!("Launching TUI");
gyandoot_tui::tui::run_tui()?;
Ok(())
}
/// Handle service management subcommands
async fn cmd_service(action: ServiceAction) -> anyhow::Result<()> {
use gyandoot_core::service;
match action {
ServiceAction::Install => {
println!("📦 Installing GyanDoot system service...");
match service::install_service() {
Ok(status) => {
println!("✅ GyanDoot service installed successfully!");
println!(" Init system: {}", status.init_system);
println!(" Status: {}", status.details);
println!("\n GyanDoot will now start automatically on boot.");
}
Err(e) => {
eprintln!("❌ Failed to install service: {}", e);
eprintln!(" You can still run: gyandoot run");
}
}
}
ServiceAction::Remove => {
println!("🗑️ Removing GyanDoot system service...");
match service::remove_service() {
Ok(()) => {
println!("✅ GyanDoot service removed.");
}
Err(e) => {
eprintln!("❌ Failed to remove service: {}", e);
}
}
}
ServiceAction::Status => {
match service::check_service() {
Ok(status) => {
println!("📊 GyanDoot Service Status");
println!(" Name: {}", status.name);
println!(" Init System: {}", status.init_system);
println!(" Installed: {}", if status.installed { "✅ Yes" } else { "❌ No" });
println!(" Running: {}", if status.running { "✅ Yes" } else { "❌ No" });
println!(" Auto-start: {}", if status.enabled { "✅ Enabled" } else { "❌ Disabled" });
println!(" Details: {}", status.details);
if !status.installed {
println!("\n 💡 Install with: gyandoot service install");
}
}
Err(e) => {
eprintln!("❌ Failed to check service status: {}", e);
}
}
}
}
Ok(())
}