From d7c272dabc7e4a181de1b276da556d489df93d6e Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Sun, 28 Dec 2025 17:04:08 -0700 Subject: [PATCH] Restrict session termination to support sessions only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Persistent agents: No "End Session" menu, shows "Managed by Administrator" - Persistent agents: Always reconnect, can only be removed via admin disconnect - Support sessions: User can end via tray icon - Tray icon still shows for persistent agents (status display only) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- agent/src/main.rs | 27 +++++++++++---------------- agent/src/tray/mod.rs | 14 +++++++++++--- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/agent/src/main.rs b/agent/src/main.rs index 824ec5c..3ea37c8 100644 --- a/agent/src/main.rs +++ b/agent/src/main.rs @@ -187,7 +187,8 @@ async fn run_agent(config: config::Config) -> Result<()> { } // Create tray icon - let tray = match tray::TrayController::new(&hostname, config.support_code.as_deref()) { + // Only support sessions can be ended by user - persistent agents are admin-managed + let tray = match tray::TrayController::new(&hostname, config.support_code.as_deref(), is_support_session) { Ok(t) => { info!("Tray icon created"); Some(t) @@ -208,11 +209,14 @@ async fn run_agent(config: config::Config) -> Result<()> { loop { info!("Connecting to server..."); - // Check if user requested exit via tray before connecting - if let Some(ref t) = tray { - if t.exit_requested() { - info!("Exit requested by user"); - return Ok(()); + // Check if user requested exit via tray before connecting (support sessions only) + if is_support_session { + if let Some(ref t) = tray { + if t.exit_requested() { + info!("Exit requested by user"); + cleanup_on_exit(); + return Ok(()); + } } } @@ -290,16 +294,7 @@ async fn run_agent(config: config::Config) -> Result<()> { return Ok(()); } - // Check if user requested exit via tray - if let Some(ref t) = tray { - if t.exit_requested() { - info!("Exit requested by user"); - cleanup_on_exit(); - return Ok(()); - } - } - - // Wait before reconnecting (only for persistent agent connections) + // Wait before reconnecting (persistent agents only - support sessions already exited above) info!("Reconnecting in 5 seconds..."); tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; } diff --git a/agent/src/tray/mod.rs b/agent/src/tray/mod.rs index 593d6ea..5d958c9 100644 --- a/agent/src/tray/mod.rs +++ b/agent/src/tray/mod.rs @@ -36,18 +36,26 @@ pub struct TrayController { impl TrayController { /// Create a new tray controller - pub fn new(machine_name: &str, support_code: Option<&str>) -> Result { + /// `allow_end_session` - If true, show "End Session" menu item (only for support sessions) + pub fn new(machine_name: &str, support_code: Option<&str>, allow_end_session: bool) -> Result { // Create menu items let status_text = if let Some(code) = support_code { format!("Support Session: {}", code) } else { - "Connected".to_string() + "Persistent Agent".to_string() }; let status_item = MenuItem::new(&status_text, false, None); let machine_item = MenuItem::new(format!("Machine: {}", machine_name), false, None); let separator = PredefinedMenuItem::separator(); - let end_session_item = MenuItem::new("End Session", true, None); + + // Only show "End Session" for support sessions + // Persistent agents can only be removed by admin + let end_session_item = if allow_end_session { + MenuItem::new("End Session", true, None) + } else { + MenuItem::new("Managed by Administrator", false, None) + }; // Build menu let menu = Menu::new();