From 920ea0ee9eacbb053bca96ffca15dfbfb033c677 Mon Sep 17 00:00:00 2001 From: Butterfly Dev Date: Tue, 7 Apr 2026 05:33:05 +0000 Subject: [PATCH] =?UTF-8?q?agent:=20cli.rs=20=E2=80=94=20subcommand=20CLI?= =?UTF-8?q?=20(run,=20service=20install/uninstall/start/stop/status/restar?= =?UTF-8?q?t)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent/src/cli.rs | 153 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 agent/src/cli.rs diff --git a/agent/src/cli.rs b/agent/src/cli.rs new file mode 100644 index 0000000..de37915 --- /dev/null +++ b/agent/src/cli.rs @@ -0,0 +1,153 @@ +//! Command-line interface with subcommands for the Butterfly agent. +//! +//! ## Usage +//! +//! ```text +//! butterfly-agent run --server ws://192.168.1.100:8080 --encoder h264 +//! butterfly-agent service install --server ws://192.168.1.100:8080 --encoder h264 +//! butterfly-agent service uninstall +//! butterfly-agent service start +//! butterfly-agent service stop +//! butterfly-agent service status +//! ``` +//! +//! The `run` subcommand starts the agent in foreground mode (logs to stderr). +//! The `service` subcommand manages the agent as a system service: +//! - **Linux**: systemd unit in `/etc/systemd/system/` +//! - **Windows**: Windows Service via Service Control Manager + +use clap::{Parser, Subcommand}; +use crate::config::RunOptions; + +/// Butterfly Desktop Agent — captures display from this machine, encodes as +/// H.264 or JPEG, and streams it to a Butterfly server via WebSocket. +#[derive(Parser, Debug)] +#[command( + name = "butterfly-agent", + version, + about, + propagate_version = true, + args_conflicts_with_subcommands = true, + subcommand_required = true, +)] +pub struct Cli { + #[command(subcommand)] + pub command: Command, +} + +/// Top-level subcommands. +#[derive(Subcommand, Debug)] +pub enum Command { + /// Run the agent in foreground mode. + /// + /// Captures the display, encodes video frames, streams via WebSocket, + /// and receives remote control commands (mouse, keyboard). Press Ctrl+C + /// to shut down gracefully. + Run { + #[command(flatten)] + opts: RunOptions, + }, + + /// Manage the agent as a system service. + /// + /// Install, uninstall, start, stop, or check the status of the agent + /// running as a background service. + /// + /// **Linux (systemd):** + /// Creates a systemd unit file at `/etc/systemd/system/.service`. + /// Requires root privileges (use `sudo`). + /// + /// **Windows (Service Control Manager):** + /// Registers with the Windows SCM. Requires Administrator privileges. + #[command(subcommand)] + Service(ServiceAction), +} + +/// Service management subcommands. +#[derive(Subcommand, Debug)] +pub enum ServiceAction { + /// Install the agent as a system service. + /// + /// Creates the service definition with the provided run options. + /// The service will automatically start on boot (unless `--no-start` is given). + /// + /// On Linux: creates `/etc/systemd/system/.service` and runs `systemctl enable --now`. + /// On Windows: registers with SCM and optionally starts the service. + /// + /// **Note:** On Linux, the installer captures current display environment + /// variables (DISPLAY, WAYLAND_DISPLAY, XDG_RUNTIME_DIR) so the service + /// can access the desktop. You may need to edit the unit file manually if + /// the environment changes. + Install { + #[command(flatten)] + opts: RunOptions, + + /// Service name (used for systemd unit file and Windows service name). + #[arg(long, default_value = "butterfly-agent")] + name: String, + + /// Human-readable service display name. + #[arg(long, default_value = "Butterfly Desktop Agent")] + display_name: String, + + /// Service description. + #[arg(long, default_value = "Captures display and streams to Butterfly server with low-latency H.264 encoding")] + description: String, + + /// Automatically start the service after installation. + #[arg(long, default_value_t = true, name = "no-start")] + start: bool, + + /// User to run the service as (Linux only). Default: root. + #[cfg(unix)] + #[arg(long)] + user: Option, + + /// Working directory for the service process. + #[arg(long)] + working_directory: Option, + + /// Log file path (appended to by the service). If not set, uses + /// the system default (journald on Linux, Windows Event Log). + #[arg(long)] + log_file: Option, + }, + + /// Uninstall (remove) the system service. + /// + /// Stops the service if it is running, then removes the service definition. + #[arg(long, default_value = "butterfly-agent")] + Uninstall { + /// Service name to uninstall. + #[arg(long, default_value = "butterfly-agent")] + name: String, + }, + + /// Start the installed service. + Start { + /// Service name to start. + #[arg(long, default_value = "butterfly-agent")] + name: String, + }, + + /// Stop the running service. + Stop { + /// Service name to stop. + #[arg(long, default_value = "butterfly-agent")] + name: String, + }, + + /// Check the current status of the service. + Status { + /// Service name to check. + #[arg(long, default_value = "butterfly-agent")] + name: String, + }, + + /// Restart the running service. + Restart { + /// Service name to restart. + #[arg(long, default_value = "butterfly-agent")] + name: String, + }, +}