The file C:\Users\MikeSwanson\Claude\guru-connect\agent\src\main.rs has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
   215→            show_debug_console();
   216→            println!("{}", build_info::full_version());
   217→            Ok(())
   218→        }
   219→        None => {
   220→            // No subcommand - detect mode from filename or embedded config
   221→            // Legacy: if support_code arg provided, use that
   222→            if let Some(code) = cli.support_code {
   223→                return run_agent_mode(Some(code));
   224→            }
   225→
   226→            // Detect run mode from filename
   227→            use config::RunMode;
   228→            match config::Config::detect_run_mode() {
   229→                RunMode::Viewer => {
   230→                    // Filename indicates viewer-only (e.g., "GuruConnect-Viewer.exe")
   231→                    info!("Viewer mode detected from filename");
   232→                    if !install::is_protocol_handler_registered() {
   233→                        info!("Installing protocol handler for viewer");
   234→                        run_install(false)
   235→                    } else {
   236→                        info!("Viewer already installed, nothing to do");
   237→                        show_message_box("GuruConnect Viewer", "GuruConnect viewer is installed.\n\nUse guruconnect:// links to connect to remote sessions.");
   238→                        Ok(())
   239→                    }
   240→                }
   241→                RunMode::TempSupport(code) => {
   242→                    // Filename contains support code (e.g., "GuruConnect-123456.exe")
   243→                    info!("Temp support session detected from filename: {}", code);
   244→                    run_agent_mode(Some(code))
   245→                }
   246→                RunMode::PermanentAgent => {
   247→                    // Embedded config found - run as permanent agent
   248→                    info!("Permanent agent mode detected (embedded config)");
   249→                    if !install::is_protocol_handler_registered() {
   250→                        // First run - install then run as agent
   251→                        info!("First run - installing agent");
   252→                        if let Err(e) = install::install(false) {
   253→                            warn!("Installation failed: {}", e);
   254→                        }
   255→                    }
   256→                    run_agent_mode(None)
   257→                }
   258→                RunMode::Default => {
   259→                    // No special mode detected - use legacy logic
   260→                    if !install::is_protocol_handler_registered() {
   261→                        // Protocol handler not registered - user likely downloaded from web
   262→                        info!("Protocol handler not registered, running installer");
   263→                        run_install(false)
   264→                    } else if config::Config::has_agent_config() {
   265→                        // Has agent config - run as agent
   266→                        info!("Agent config found, running as agent");
   267→                        run_agent_mode(None)
   268→                    } else {
   269→                        // Viewer-only installation - just exit silently
   270→                        info!("Viewer-only installation, exiting");
   271→                        Ok(())
   272→                    }
   273→                }
   274→            }
   275→        }
   276→    }
   277→}
   278→
   279→/// Run in agent mode (receive remote connections)

        None => {
            // No subcommand - detect mode from filename or embedded config
            // Legacy: if support_code arg provided, use that
            if let Some(code) = cli.support_code {
                return run_agent_mode(Some(code));
            }

            // Detect run mode from filename
            use config::RunMode;
            match config::Config::detect_run_mode() {
                RunMode::Viewer => {
                    // Filename indicates viewer-only (e.g., "GuruConnect-Viewer.exe")
                    info!("Viewer mode detected from filename");
                    if !install::is_protocol_handler_registered() {
                        info!("Installing protocol handler for viewer");
                        run_install(false)
                    } else {
                        info!("Viewer already installed, nothing to do");
                        show_message_box("GuruConnect Viewer", "GuruConnect viewer is installed.\n\nUse guruconnect:// links to connect to remote sessions.");
                        Ok(())
                    }
                }
                RunMode::TempSupport(code) => {
                    // Filename contains support code (e.g., "GuruConnect-123456.exe")
                    info!("Temp support session detected from filename: {}", code);
                    run_agent_mode(Some(code))
                }
                RunMode::PermanentAgent => {
                    // Embedded config found - run as permanent agent
                    info!("Permanent agent mode detected (embedded config)");
                    if !install::is_protocol_handler_registered() {
                        // First run - install then run as agent
                        info!("First run - installing agent");
                        if let Err(e) = install::install(false) {
                            warn!("Installation failed: {}", e);
                        }
                    }
                    run_agent_mode(None)
                }
                RunMode::Default => {
                    // No special mode detected - use legacy logic
                    if !install::is_protocol_handler_registered() {
                        // Protocol handler not registered - user likely downloaded from web
                        info!("Protocol handler not registered, running installer");
                        run_install(false)
                    } else if config::Config::has_agent_config() {
                        // Has agent config - run as agent
                        info!("Agent config found, running as agent");
                        run_agent_mode(None)
                    } else {
                        // Viewer-only installation - just exit silently
                        info!("Viewer-only installation, exiting");
                        Ok(())
                    }
                }
            }
        }

//! GuruConnect - Remote Desktop Agent and Viewer
//!
//! Single binary for both agent (receiving connections) and viewer (initiating connections).
//!
//! Usage:
//!   guruconnect agent              - Run as background agent
//!   guruconnect view <session_id>  - View a remote session
//!   guruconnect install            - Install and register protocol handler
//!   guruconnect launch <url>       - Handle guruconnect:// URL
//!   guruconnect [support_code]     - Legacy: run agent with support code

// Hide console window by default on Windows (release builds)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod capture;
mod chat;
mod config;
mod encoder;
mod input;
mod install;
mod sas_client;
mod session;
mod startup;
mod transport;
mod tray;
mod update;
mod viewer;

pub mod proto {
    include!(concat!(env!("OUT_DIR"), "/guruconnect.rs"));
}

/// Build information embedded at compile time
pub mod build_info {
    /// Cargo package version (from Cargo.toml)
    pub const VERSION: &str = env!("CARGO_PKG_VERSION");

    /// Git commit hash (short, 8 chars)
    pub const GIT_HASH: &str = env!("GIT_HASH");

    /// Git commit hash (full)
    pub const GIT_HASH_FULL: &str = env!("GIT_HASH_FULL");

    /// Git branch name
    pub const GIT_BRANCH: &str = env!("GIT_BRANCH");

    /// Git dirty state ("clean" or "dirty")
    pub const GIT_DIRTY: &str = env!("GIT_DIRTY");

    /// Git commit date
    pub const GIT_COMMIT_DATE: &str = env!("GIT_COMMIT_DATE");

    /// Build timestamp (UTC)
    pub const BUILD_TIMESTAMP: &str = env!("BUILD_TIMESTAMP");

    /// Build profile (debug/release)
    pub const BUILD_PROFILE: &str = env!("BUILD_PROFILE");

    /// Target triple (e.g., x86_64-pc-windows-msvc)
    pub const BUILD_TARGET: &str = env!("BUILD_TARGET");

    /// Short version string for display (version + git hash)
    pub fn short_version() -> String {
        if GIT_DIRTY == "dirty" {
            format!("{}-{}-dirty", VERSION, GIT_HASH)
        } else {
            format!("{}-{}", VERSION, GIT_HASH)
        }
    }

    /// Full version string with all details
    pub fn full_version() -> String {
        format!(
            "GuruConnect v{}\n\
             Git:     {} ({})\n\
             Branch:  {}\n\
             Commit:  {}\n\
             Built:   {}\n\
             Profile: {}\n\
             Target:  {}",
            VERSION,
            GIT_HASH,
            GIT_DIRTY,
            GIT_BRANCH,
            GIT_COMMIT_DATE,
            BUILD_TIMESTAMP,
            BUILD_PROFILE,
            BUILD_TARGET
        )
    }
}

use anyhow::Result;
use clap::{Parser, Subcommand};
use tracing::{info, error, warn, Level};
use tracing_subscriber::FmtSubscriber;

#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_OK, MB_ICONINFORMATION, MB_ICONERROR};
#[cfg(windows)]
use windows::core::PCWSTR;
#[cfg(windows)]
use windows::Win32::System::Console::{AllocConsole, GetConsoleWindow};
#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_SHOW};

/// GuruConnect Remote Desktop
#[derive(Parser)]
#[command(name = "guruconnect")]
#[command(version = concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_HASH")), about = "Remote desktop agent and viewer")]
struct Cli {
    #[command(subcommand)]
    command: Option<Commands>,

    /// Support code for legacy mode (runs agent with code)
    #[arg(value_name = "SUPPORT_CODE")]
    support_code: Option<String>,

    /// Enable verbose logging
    #[arg(short, long, global = true)]
    verbose: bool,

    /// Internal flag: set after auto-update to trigger cleanup
    #[arg(long, hide = true)]
    post_update: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Run as background agent (receive remote connections)
    Agent {
        /// Support code for one-time session
        #[arg(short, long)]
        code: Option<String>,
    },

    /// View a remote session (connect to an agent)
    View {
        /// Session ID to connect to
        session_id: String,

        /// Server URL
        #[arg(short, long, default_value = "wss://connect.azcomputerguru.com/ws/viewer")]
        server: String,

        /// API key for authentication
        #[arg(short, long, default_value = "")]
        api_key: String,
    },

    /// Install GuruConnect and register protocol handler
    Install {
        /// Skip UAC elevation, install for current user only
        #[arg(long)]
        user_only: bool,

        /// Called internally when running elevated
        #[arg(long, hide = true)]
        elevated: bool,
    },

    /// Uninstall GuruConnect
    Uninstall,

    /// Handle a guruconnect:// protocol URL
    Launch {
        /// The guruconnect:// URL to handle
        url: String,
    },

    /// Show detailed version and build information
    #[command(name = "version-info")]
    VersionInfo,
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    // Initialize logging
    let level = if cli.verbose { Level::DEBUG } else { Level::INFO };
    FmtSubscriber::builder()
        .with_max_level(level)
        .with_target(true)
        .with_thread_ids(true)
        .init();

    info!("GuruConnect {} ({})", build_info::short_version(), build_info::BUILD_TARGET);
    info!("Built: {} | Commit: {}", build_info::BUILD_TIMESTAMP, build_info::GIT_COMMIT_DATE);

    // Handle post-update cleanup
    if cli.post_update {
        info!("Post-update mode: cleaning up old executable");
        update::cleanup_post_update();
    }

    match cli.command {
        Some(Commands::Agent { code }) => {
            run_agent_mode(code)
        }
        Some(Commands::View { session_id, server, api_key }) => {
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Some(Commands::Install { user_only, elevated }) => {
            run_install(user_only || elevated)
        }
        Some(Commands::Uninstall) => {
            run_uninstall()
        }
        Some(Commands::Launch { url }) => {
            run_launch(&url)
        }
        Some(Commands::VersionInfo) => {
            // Show detailed version info (allocate console on Windows for visibility)
            #[cfg(windows)]
            show_debug_console();
            println!("{}", build_info::full_version());
            Ok(())
        }
        None => {
            // Legacy mode: if a support code was provided, run as agent
            if let Some(code) = cli.support_code {
                run_agent_mode(Some(code))
            } else {
                // No args: check what mode to run
                if !install::is_protocol_handler_registered() {
                    // Protocol handler not registered - user likely downloaded from web
                    // Run installer to set up protocol handler
                    info!("Protocol handler not registered, running installer");
                    run_install(false)
                } else if config::Config::has_agent_config() {
                    // Protocol handler exists AND agent config exists
                    // This is an agent installation - run as agent
                    info!("Agent config found, running as agent");
                    run_agent_mode(None)
                } else {
                    // Protocol handler exists but NO agent config
                    // This is a viewer-only installation - just exit silently
                    // The protocol handler will launch the viewer when needed
                    info!("Viewer-only installation, exiting (use 'guruconnect agent' to run as agent)");
                    Ok(())
                }
            }
        }
    }
}

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Also check for support code in filename (legacy compatibility)
    let code = support_code.or_else(extract_code_from_filename);
    if let Some(ref c) = code {
        info!("Support code: {}", c);
    }

    // Load configuration
    let mut config = config::Config::load()?;
    config.support_code = code;
    info!("Server: {}", config.server_url);

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

/// Run in viewer mode (connect to remote session)
fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
    info!("Running in viewer mode");
    info!("Connecting to session: {}", session_id);

    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(viewer::run(server, session_id, api_key))
}

/// Handle guruconnect:// URL launch
fn run_launch(url: &str) -> Result<()> {
    info!("Handling protocol URL: {}", url);

    match install::parse_protocol_url(url) {
        Ok((server, session_id, token)) => {
            let api_key = token.unwrap_or_default();
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Err(e) => {
            error!("Failed to parse URL: {}", e);
            show_error_box("GuruConnect", &format!("Invalid URL: {}", e));
            Err(e)
        }
    }
}

/// Install GuruConnect
fn run_install(force_user_install: bool) -> Result<()> {
    info!("Installing GuruConnect...");

    match install::install(force_user_install) {
        Ok(()) => {
            show_message_box("GuruConnect", "Installation complete!\n\nYou can now use guruconnect:// links.");
            Ok(())
        }
        Err(e) => {
            error!("Installation failed: {}", e);
            show_error_box("GuruConnect", &format!("Installation failed: {}", e));
            Err(e)
        }
    }
}

/// Uninstall GuruConnect
fn run_uninstall() -> Result<()> {
    info!("Uninstalling GuruConnect...");

    // Remove from startup
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }

    // TODO: Remove registry keys for protocol handler
    // TODO: Remove install directory

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }

    None
}

/// Show a message box (Windows only)
#[cfg(windows)]
fn show_message_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONINFORMATION,
        );
    }
}

#[cfg(not(windows))]
fn show_message_box(_title: &str, message: &str) {
    println!("{}", message);
}

/// Show an error message box (Windows only)
#[cfg(windows)]
fn show_error_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONERROR,
        );
    }
}

#[cfg(not(windows))]
fn show_error_box(_title: &str, message: &str) {
    eprintln!("ERROR: {}", message);
}

/// Show debug console window (Windows only)
#[cfg(windows)]
#[allow(dead_code)]
fn show_debug_console() {
    unsafe {
        let hwnd = GetConsoleWindow();
        if hwnd.0 == std::ptr::null_mut() {
            let _ = AllocConsole();
        } else {
            let _ = ShowWindow(hwnd, SW_SHOW);
        }
    }
}

#[cfg(not(windows))]
#[allow(dead_code)]
fn show_debug_console() {}

/// Clean up before exiting
fn cleanup_on_exit() {
    info!("Cleaning up before exit");
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }
}

/// Run the agent main loop
async fn run_agent(config: config::Config) -> Result<()> {
    let elevated = install::is_elevated();
    let mut session = session::SessionManager::new(config.clone(), elevated);
    let is_support_session = config.support_code.is_some();
    let hostname = config.hostname();

    // Add to startup
    if let Err(e) = startup::add_to_startup() {
        warn!("Failed to add to startup: {}", e);
    }

    // Create tray icon
    let tray = match tray::TrayController::new(&hostname, config.support_code.as_deref(), is_support_session) {
        Ok(t) => {
            info!("Tray icon created");
            Some(t)
        }
        Err(e) => {
            warn!("Failed to create tray icon: {}", e);
            None
        }
    };

    // Create chat controller
    let chat_ctrl = chat::ChatController::new();

    // Connect to server and run main loop
    loop {
        info!("Connecting to server...");

        if is_support_session {
            if let Some(ref t) = tray {
                if t.exit_requested() {
                    info!("Exit requested by user");
                    cleanup_on_exit();
                    return Ok(());
                }
            }
        }

        match session.connect().await {
            Ok(_) => {
                info!("Connected to server");

                if let Some(ref t) = tray {
                    t.update_status("Status: Connected");
                }

                if let Err(e) = session.run_with_tray(tray.as_ref(), chat_ctrl.as_ref()).await {
                    let error_msg = e.to_string();

                    if error_msg.contains("USER_EXIT") {
                        info!("Session ended by user");
                        cleanup_on_exit();
                        return Ok(());
                    }

                    if error_msg.contains("SESSION_CANCELLED") {
                        info!("Session was cancelled by technician");
                        cleanup_on_exit();
                        show_message_box("Support Session Ended", "The support session was cancelled.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_DISCONNECT") {
                        info!("Session disconnected by administrator - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("Remote Session Ended", "The session was ended by the administrator.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_UNINSTALL") {
                        info!("Uninstall command received from server - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("GuruConnect Removed", "This computer has been removed from remote management.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_RESTART") {
                        info!("Restart command received - will reconnect");
                        // Don't exit, just let the loop continue to reconnect
                    } else {
                        error!("Session error: {}", e);
                    }
                }
            }
            Err(e) => {
                let error_msg = e.to_string();

                if error_msg.contains("cancelled") {
                    info!("Support code was cancelled");
                    cleanup_on_exit();
                    show_message_box("Support Session Cancelled", "This support session has been cancelled.");
                    return Ok(());
                }

                error!("Connection failed: {}", e);
            }
        }

        if is_support_session {
            info!("Support session ended, not reconnecting");
            cleanup_on_exit();
            return Ok(());
        }

        info!("Reconnecting in 5 seconds...");
        tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
    }
}

-            // Legacy mode: if a support code was provided, run as agent

+            // No subcommand - detect mode from filename or embedded config

+            // Legacy: if support_code arg provided, use that

-                run_agent_mode(Some(code))

-                // No args: check what mode to run

-                if !install::is_protocol_handler_registered() {

-                    // Protocol handler not registered - user likely downloaded from web

-                    // Run installer to set up protocol handler

-                    info!("Protocol handler not registered, running installer");

-                } else if config::Config::has_agent_config() {

-                    // Protocol handler exists AND agent config exists

-                    // This is an agent installation - run as agent

-                    info!("Agent config found, running as agent");

+                return run_agent_mode(Some(code));

+            // Detect run mode from filename

+            match config::Config::detect_run_mode() {

+                    // Filename indicates viewer-only (e.g., "GuruConnect-Viewer.exe")

+                    info!("Viewer mode detected from filename");

+                    if !install::is_protocol_handler_registered() {

+                        info!("Installing protocol handler for viewer");

+                        run_install(false)

+                        info!("Viewer already installed, nothing to do");

+                        show_message_box("GuruConnect Viewer", "GuruConnect viewer is installed.\n\nUse guruconnect:// links to connect to remote sessions.");

+                RunMode::TempSupport(code) => {

+                    // Filename contains support code (e.g., "GuruConnect-123456.exe")

+                    info!("Temp support session detected from filename: {}", code);

+                    run_agent_mode(Some(code))

+                RunMode::PermanentAgent => {

+                    // Embedded config found - run as permanent agent

+                    info!("Permanent agent mode detected (embedded config)");

+                        // First run - install then run as agent

+                        info!("First run - installing agent");

+                        if let Err(e) = install::install(false) {

+                            warn!("Installation failed: {}", e);

-                    // Protocol handler exists but NO agent config

-                    // This is a viewer-only installation - just exit silently

-                    // The protocol handler will launch the viewer when needed

-                    info!("Viewer-only installation, exiting (use 'guruconnect agent' to run as agent)");

+                    // No special mode detected - use legacy logic

+                        // Protocol handler not registered - user likely downloaded from web

+                        info!("Protocol handler not registered, running installer");

+                        run_install(false)

+                    } else if config::Config::has_agent_config() {

+                        // Has agent config - run as agent

+                        info!("Agent config found, running as agent");

+                        run_agent_mode(None)

+                        // Viewer-only installation - just exit silently

+                        info!("Viewer-only installation, exiting");


Now I can remove the `extract_code_from_filename` function since we've moved that logic to `config.rs`. Let me check if it's still being used and remove it if not.


Let me also remove the old `extract_code_from_filename` function since we moved it to config.rs:


291:    let code = support_code.or_else(extract_code_from_filename);
366:fn extract_code_from_filename() -> Option<String> {


The function is still being used in run_agent_mode(). Let me update it to use the config module's version instead, or keep the local one since it's slightly different (returns Option instead of String). Actually, let me check what the function does:


   285→        info!("Running with elevated (administrator) privileges");
   286→    } else {
   287→        info!("Running with standard user privileges");
   288→    }
   289→
   290→    // Also check for support code in filename (legacy compatibility)
   291→    let code = support_code.or_else(extract_code_from_filename);
   292→    if let Some(ref c) = code {
   293→        info!("Support code: {}", c);
   294→    }
   295→
   296→    // Load configuration
   297→    let mut config = config::Config::load()?;
   298→    config.support_code = code;
   299→    info!("Server: {}", config.server_url);
   300→
   301→    // Run the agent
   302→    let rt = tokio::runtime::Runtime::new()?;
   303→    rt.block_on(run_agent(config))
   304→}
   305→
   306→/// Run in viewer mode (connect to remote session)
   307→fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
   308→    info!("Running in viewer mode");
   309→    info!("Connecting to session: {}", session_id);
   310→
   311→    let rt = tokio::runtime::Runtime::new()?;
   312→    rt.block_on(viewer::run(server, session_id, api_key))
   313→}
   314→
   315→/// Handle guruconnect:// URL launch
   316→fn run_launch(url: &str) -> Result<()> {
   317→    info!("Handling protocol URL: {}", url);
   318→
   319→    match install::parse_protocol_url(url) {
   320→        Ok((server, session_id, token)) => {
   321→            let api_key = token.unwrap_or_default();
   322→            run_viewer_mode(&server, &session_id, &api_key)
   323→        }
   324→        Err(e) => {
   325→            error!("Failed to parse URL: {}", e);
   326→            show_error_box("GuruConnect", &format!("Invalid URL: {}", e));
   327→            Err(e)
   328→        }
   329→    }
   330→}
   331→
   332→/// Install GuruConnect
   333→fn run_install(force_user_install: bool) -> Result<()> {
   334→    info!("Installing GuruConnect...");
   335→
   336→    match install::install(force_user_install) {
   337→        Ok(()) => {
   338→            show_message_box("GuruConnect", "Installation complete!\n\nYou can now use guruconnect:// links.");
   339→            Ok(())
   340→        }
   341→        Err(e) => {
   342→            error!("Installation failed: {}", e);
   343→            show_error_box("GuruConnect", &format!("Installation failed: {}", e));
   344→            Err(e)
   345→        }
   346→    }
   347→}
   348→
   349→/// Uninstall GuruConnect
   350→fn run_uninstall() -> Result<()> {
   351→    info!("Uninstalling GuruConnect...");
   352→
   353→    // Remove from startup
   354→    if let Err(e) = startup::remove_from_startup() {
   355→        warn!("Failed to remove from startup: {}", e);
   356→    }
   357→
   358→    // TODO: Remove registry keys for protocol handler
   359→    // TODO: Remove install directory
   360→
   361→    show_message_box("GuruConnect", "Uninstall complete.");
   362→    Ok(())
   363→}
   364→
   365→/// Extract a 6-digit support code from the executable's filename
   366→fn extract_code_from_filename() -> Option<String> {
   367→    let exe_path = std::env::current_exe().ok()?;
   368→    let filename = exe_path.file_stem()?.to_str()?;
   369→
   370→    // Look for a 6-digit number in the filename
   371→    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
   372→        let trimmed = part.trim();
   373→        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
   374→            return Some(trimmed.to_string());
   375→        }
   376→    }
   377→
   378→    // Check if the last 6 characters are digits
   379→    if filename.len() >= 6 {
   380→        let last_six = &filename[filename.len() - 6..];
   381→        if last_six.chars().all(|c| c.is_ascii_digit()) {
   382→            return Some(last_six.to_string());
   383→        }
   384→    }

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Also check for support code in filename (legacy compatibility)
    let code = support_code.or_else(extract_code_from_filename);
    if let Some(ref c) = code {
        info!("Support code: {}", c);
    }

    // Load configuration
    let mut config = config::Config::load()?;
    config.support_code = code;
    info!("Server: {}", config.server_url);

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

/// Run in viewer mode (connect to remote session)
fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
    info!("Running in viewer mode");
    info!("Connecting to session: {}", session_id);

    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(viewer::run(server, session_id, api_key))
}

/// Handle guruconnect:// URL launch
fn run_launch(url: &str) -> Result<()> {
    info!("Handling protocol URL: {}", url);

    match install::parse_protocol_url(url) {
        Ok((server, session_id, token)) => {
            let api_key = token.unwrap_or_default();
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Err(e) => {
            error!("Failed to parse URL: {}", e);
            show_error_box("GuruConnect", &format!("Invalid URL: {}", e));
            Err(e)
        }
    }
}

/// Install GuruConnect
fn run_install(force_user_install: bool) -> Result<()> {
    info!("Installing GuruConnect...");

    match install::install(force_user_install) {
        Ok(()) => {
            show_message_box("GuruConnect", "Installation complete!\n\nYou can now use guruconnect:// links.");
            Ok(())
        }
        Err(e) => {
            error!("Installation failed: {}", e);
            show_error_box("GuruConnect", &format!("Installation failed: {}", e));
            Err(e)
        }
    }
}

/// Uninstall GuruConnect
fn run_uninstall() -> Result<()> {
    info!("Uninstalling GuruConnect...");

    // Remove from startup
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }

    // TODO: Remove registry keys for protocol handler
    // TODO: Remove install directory

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }


I see - the `extract_code_from_filename` function in main.rs is nearly identical to what we added in config.rs. We can remove it and use the config version. Let me update run_agent_mode to not use the local function:


The function is duplicated. Let me update run_agent_mode to use the config version and remove the local one:


Edit

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Also check for support code in filename (legacy compatibility)
    let code = support_code.or_else(extract_code_from_filename);
    if let Some(ref c) = code {
        info!("Support code: {}", c);
    }

    // Load configuration
    let mut config = config::Config::load()?;
    config.support_code = code;
    info!("Server: {}", config.server_url);

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Load configuration
    let mut config = config::Config::load()?;

    // Set support code if provided
    if let Some(code) = support_code {
        info!("Support code: {}", code);
        config.support_code = Some(code);
    }

    info!("Server: {}", config.server_url);
    if let Some(ref company) = config.company {
        info!("Company: {}", company);
    }
    if let Some(ref site) = config.site {
        info!("Site: {}", site);
    }

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}


The file C:\Users\MikeSwanson\Claude\guru-connect\agent\src\main.rs has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
   275→        }
   276→    }
   277→}
   278→
   279→/// Run in agent mode (receive remote connections)
   280→fn run_agent_mode(support_code: Option<String>) -> Result<()> {
   281→    info!("Running in agent mode");
   282→
   283→    // Check elevation status
   284→    if install::is_elevated() {
   285→        info!("Running with elevated (administrator) privileges");
   286→    } else {
   287→        info!("Running with standard user privileges");
   288→    }
   289→
   290→    // Load configuration
   291→    let mut config = config::Config::load()?;
   292→
   293→    // Set support code if provided
   294→    if let Some(code) = support_code {
   295→        info!("Support code: {}", code);
   296→        config.support_code = Some(code);
   297→    }
   298→
   299→    info!("Server: {}", config.server_url);
   300→    if let Some(ref company) = config.company {
   301→        info!("Company: {}", company);
   302→    }
   303→    if let Some(ref site) = config.site {
   304→        info!("Site: {}", site);
   305→    }
   306→
   307→    // Run the agent
   308→    let rt = tokio::runtime::Runtime::new()?;
   309→    rt.block_on(run_agent(config))
   310→}
   311→
   312→/// Run in viewer mode (connect to remote session)
   313→fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
   314→    info!("Running in viewer mode");

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Load configuration
    let mut config = config::Config::load()?;

    // Set support code if provided
    if let Some(code) = support_code {
        info!("Support code: {}", code);
        config.support_code = Some(code);
    }

    info!("Server: {}", config.server_url);
    if let Some(ref company) = config.company {
        info!("Company: {}", company);
    }
    if let Some(ref site) = config.site {
        info!("Site: {}", site);
    }

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

//! GuruConnect - Remote Desktop Agent and Viewer
//!
//! Single binary for both agent (receiving connections) and viewer (initiating connections).
//!
//! Usage:
//!   guruconnect agent              - Run as background agent
//!   guruconnect view <session_id>  - View a remote session
//!   guruconnect install            - Install and register protocol handler
//!   guruconnect launch <url>       - Handle guruconnect:// URL
//!   guruconnect [support_code]     - Legacy: run agent with support code

// Hide console window by default on Windows (release builds)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod capture;
mod chat;
mod config;
mod encoder;
mod input;
mod install;
mod sas_client;
mod session;
mod startup;
mod transport;
mod tray;
mod update;
mod viewer;

pub mod proto {
    include!(concat!(env!("OUT_DIR"), "/guruconnect.rs"));
}

/// Build information embedded at compile time
pub mod build_info {
    /// Cargo package version (from Cargo.toml)
    pub const VERSION: &str = env!("CARGO_PKG_VERSION");

    /// Git commit hash (short, 8 chars)
    pub const GIT_HASH: &str = env!("GIT_HASH");

    /// Git commit hash (full)
    pub const GIT_HASH_FULL: &str = env!("GIT_HASH_FULL");

    /// Git branch name
    pub const GIT_BRANCH: &str = env!("GIT_BRANCH");

    /// Git dirty state ("clean" or "dirty")
    pub const GIT_DIRTY: &str = env!("GIT_DIRTY");

    /// Git commit date
    pub const GIT_COMMIT_DATE: &str = env!("GIT_COMMIT_DATE");

    /// Build timestamp (UTC)
    pub const BUILD_TIMESTAMP: &str = env!("BUILD_TIMESTAMP");

    /// Build profile (debug/release)
    pub const BUILD_PROFILE: &str = env!("BUILD_PROFILE");

    /// Target triple (e.g., x86_64-pc-windows-msvc)
    pub const BUILD_TARGET: &str = env!("BUILD_TARGET");

    /// Short version string for display (version + git hash)
    pub fn short_version() -> String {
        if GIT_DIRTY == "dirty" {
            format!("{}-{}-dirty", VERSION, GIT_HASH)
        } else {
            format!("{}-{}", VERSION, GIT_HASH)
        }
    }

    /// Full version string with all details
    pub fn full_version() -> String {
        format!(
            "GuruConnect v{}\n\
             Git:     {} ({})\n\
             Branch:  {}\n\
             Commit:  {}\n\
             Built:   {}\n\
             Profile: {}\n\
             Target:  {}",
            VERSION,
            GIT_HASH,
            GIT_DIRTY,
            GIT_BRANCH,
            GIT_COMMIT_DATE,
            BUILD_TIMESTAMP,
            BUILD_PROFILE,
            BUILD_TARGET
        )
    }
}

use anyhow::Result;
use clap::{Parser, Subcommand};
use tracing::{info, error, warn, Level};
use tracing_subscriber::FmtSubscriber;

#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_OK, MB_ICONINFORMATION, MB_ICONERROR};
#[cfg(windows)]
use windows::core::PCWSTR;
#[cfg(windows)]
use windows::Win32::System::Console::{AllocConsole, GetConsoleWindow};
#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_SHOW};

/// GuruConnect Remote Desktop
#[derive(Parser)]
#[command(name = "guruconnect")]
#[command(version = concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_HASH")), about = "Remote desktop agent and viewer")]
struct Cli {
    #[command(subcommand)]
    command: Option<Commands>,

    /// Support code for legacy mode (runs agent with code)
    #[arg(value_name = "SUPPORT_CODE")]
    support_code: Option<String>,

    /// Enable verbose logging
    #[arg(short, long, global = true)]
    verbose: bool,

    /// Internal flag: set after auto-update to trigger cleanup
    #[arg(long, hide = true)]
    post_update: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Run as background agent (receive remote connections)
    Agent {
        /// Support code for one-time session
        #[arg(short, long)]
        code: Option<String>,
    },

    /// View a remote session (connect to an agent)
    View {
        /// Session ID to connect to
        session_id: String,

        /// Server URL
        #[arg(short, long, default_value = "wss://connect.azcomputerguru.com/ws/viewer")]
        server: String,

        /// API key for authentication
        #[arg(short, long, default_value = "")]
        api_key: String,
    },

    /// Install GuruConnect and register protocol handler
    Install {
        /// Skip UAC elevation, install for current user only
        #[arg(long)]
        user_only: bool,

        /// Called internally when running elevated
        #[arg(long, hide = true)]
        elevated: bool,
    },

    /// Uninstall GuruConnect
    Uninstall,

    /// Handle a guruconnect:// protocol URL
    Launch {
        /// The guruconnect:// URL to handle
        url: String,
    },

    /// Show detailed version and build information
    #[command(name = "version-info")]
    VersionInfo,
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    // Initialize logging
    let level = if cli.verbose { Level::DEBUG } else { Level::INFO };
    FmtSubscriber::builder()
        .with_max_level(level)
        .with_target(true)
        .with_thread_ids(true)
        .init();

    info!("GuruConnect {} ({})", build_info::short_version(), build_info::BUILD_TARGET);
    info!("Built: {} | Commit: {}", build_info::BUILD_TIMESTAMP, build_info::GIT_COMMIT_DATE);

    // Handle post-update cleanup
    if cli.post_update {
        info!("Post-update mode: cleaning up old executable");
        update::cleanup_post_update();
    }

    match cli.command {
        Some(Commands::Agent { code }) => {
            run_agent_mode(code)
        }
        Some(Commands::View { session_id, server, api_key }) => {
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Some(Commands::Install { user_only, elevated }) => {
            run_install(user_only || elevated)
        }
        Some(Commands::Uninstall) => {
            run_uninstall()
        }
        Some(Commands::Launch { url }) => {
            run_launch(&url)
        }
        Some(Commands::VersionInfo) => {
            // Show detailed version info (allocate console on Windows for visibility)
            #[cfg(windows)]
            show_debug_console();
            println!("{}", build_info::full_version());
            Ok(())
        }
        None => {
            // No subcommand - detect mode from filename or embedded config
            // Legacy: if support_code arg provided, use that
            if let Some(code) = cli.support_code {
                return run_agent_mode(Some(code));
            }

            // Detect run mode from filename
            use config::RunMode;
            match config::Config::detect_run_mode() {
                RunMode::Viewer => {
                    // Filename indicates viewer-only (e.g., "GuruConnect-Viewer.exe")
                    info!("Viewer mode detected from filename");
                    if !install::is_protocol_handler_registered() {
                        info!("Installing protocol handler for viewer");
                        run_install(false)
                    } else {
                        info!("Viewer already installed, nothing to do");
                        show_message_box("GuruConnect Viewer", "GuruConnect viewer is installed.\n\nUse guruconnect:// links to connect to remote sessions.");
                        Ok(())
                    }
                }
                RunMode::TempSupport(code) => {
                    // Filename contains support code (e.g., "GuruConnect-123456.exe")
                    info!("Temp support session detected from filename: {}", code);
                    run_agent_mode(Some(code))
                }
                RunMode::PermanentAgent => {
                    // Embedded config found - run as permanent agent
                    info!("Permanent agent mode detected (embedded config)");
                    if !install::is_protocol_handler_registered() {
                        // First run - install then run as agent
                        info!("First run - installing agent");
                        if let Err(e) = install::install(false) {
                            warn!("Installation failed: {}", e);
                        }
                    }
                    run_agent_mode(None)
                }
                RunMode::Default => {
                    // No special mode detected - use legacy logic
                    if !install::is_protocol_handler_registered() {
                        // Protocol handler not registered - user likely downloaded from web
                        info!("Protocol handler not registered, running installer");
                        run_install(false)
                    } else if config::Config::has_agent_config() {
                        // Has agent config - run as agent
                        info!("Agent config found, running as agent");
                        run_agent_mode(None)
                    } else {
                        // Viewer-only installation - just exit silently
                        info!("Viewer-only installation, exiting");
                        Ok(())
                    }
                }
            }
        }
    }
}

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Also check for support code in filename (legacy compatibility)
    let code = support_code.or_else(extract_code_from_filename);
    if let Some(ref c) = code {
        info!("Support code: {}", c);
    }

    // Load configuration
    let mut config = config::Config::load()?;
    config.support_code = code;
    info!("Server: {}", config.server_url);

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

/// Run in viewer mode (connect to remote session)
fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
    info!("Running in viewer mode");
    info!("Connecting to session: {}", session_id);

    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(viewer::run(server, session_id, api_key))
}

/// Handle guruconnect:// URL launch
fn run_launch(url: &str) -> Result<()> {
    info!("Handling protocol URL: {}", url);

    match install::parse_protocol_url(url) {
        Ok((server, session_id, token)) => {
            let api_key = token.unwrap_or_default();
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Err(e) => {
            error!("Failed to parse URL: {}", e);
            show_error_box("GuruConnect", &format!("Invalid URL: {}", e));
            Err(e)
        }
    }
}

/// Install GuruConnect
fn run_install(force_user_install: bool) -> Result<()> {
    info!("Installing GuruConnect...");

    match install::install(force_user_install) {
        Ok(()) => {
            show_message_box("GuruConnect", "Installation complete!\n\nYou can now use guruconnect:// links.");
            Ok(())
        }
        Err(e) => {
            error!("Installation failed: {}", e);
            show_error_box("GuruConnect", &format!("Installation failed: {}", e));
            Err(e)
        }
    }
}

/// Uninstall GuruConnect
fn run_uninstall() -> Result<()> {
    info!("Uninstalling GuruConnect...");

    // Remove from startup
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }

    // TODO: Remove registry keys for protocol handler
    // TODO: Remove install directory

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }

    None
}

/// Show a message box (Windows only)
#[cfg(windows)]
fn show_message_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONINFORMATION,
        );
    }
}

#[cfg(not(windows))]
fn show_message_box(_title: &str, message: &str) {
    println!("{}", message);
}

/// Show an error message box (Windows only)
#[cfg(windows)]
fn show_error_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONERROR,
        );
    }
}

#[cfg(not(windows))]
fn show_error_box(_title: &str, message: &str) {
    eprintln!("ERROR: {}", message);
}

/// Show debug console window (Windows only)
#[cfg(windows)]
#[allow(dead_code)]
fn show_debug_console() {
    unsafe {
        let hwnd = GetConsoleWindow();
        if hwnd.0 == std::ptr::null_mut() {
            let _ = AllocConsole();
        } else {
            let _ = ShowWindow(hwnd, SW_SHOW);
        }
    }
}

#[cfg(not(windows))]
#[allow(dead_code)]
fn show_debug_console() {}

/// Clean up before exiting
fn cleanup_on_exit() {
    info!("Cleaning up before exit");
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }
}

/// Run the agent main loop
async fn run_agent(config: config::Config) -> Result<()> {
    let elevated = install::is_elevated();
    let mut session = session::SessionManager::new(config.clone(), elevated);
    let is_support_session = config.support_code.is_some();
    let hostname = config.hostname();

    // Add to startup
    if let Err(e) = startup::add_to_startup() {
        warn!("Failed to add to startup: {}", e);
    }

    // Create tray icon
    let tray = match tray::TrayController::new(&hostname, config.support_code.as_deref(), is_support_session) {
        Ok(t) => {
            info!("Tray icon created");
            Some(t)
        }
        Err(e) => {
            warn!("Failed to create tray icon: {}", e);
            None
        }
    };

    // Create chat controller
    let chat_ctrl = chat::ChatController::new();

    // Connect to server and run main loop
    loop {
        info!("Connecting to server...");

        if is_support_session {
            if let Some(ref t) = tray {
                if t.exit_requested() {
                    info!("Exit requested by user");
                    cleanup_on_exit();
                    return Ok(());
                }
            }
        }

        match session.connect().await {
            Ok(_) => {
                info!("Connected to server");

                if let Some(ref t) = tray {
                    t.update_status("Status: Connected");
                }

                if let Err(e) = session.run_with_tray(tray.as_ref(), chat_ctrl.as_ref()).await {
                    let error_msg = e.to_string();

                    if error_msg.contains("USER_EXIT") {
                        info!("Session ended by user");
                        cleanup_on_exit();
                        return Ok(());
                    }

                    if error_msg.contains("SESSION_CANCELLED") {
                        info!("Session was cancelled by technician");
                        cleanup_on_exit();
                        show_message_box("Support Session Ended", "The support session was cancelled.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_DISCONNECT") {
                        info!("Session disconnected by administrator - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("Remote Session Ended", "The session was ended by the administrator.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_UNINSTALL") {
                        info!("Uninstall command received from server - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("GuruConnect Removed", "This computer has been removed from remote management.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_RESTART") {
                        info!("Restart command received - will reconnect");
                        // Don't exit, just let the loop continue to reconnect
                    } else {
                        error!("Session error: {}", e);
                    }
                }
            }
            Err(e) => {
                let error_msg = e.to_string();

                if error_msg.contains("cancelled") {
                    info!("Support code was cancelled");
                    cleanup_on_exit();
                    show_message_box("Support Session Cancelled", "This support session has been cancelled.");
                    return Ok(());
                }

                error!("Connection failed: {}", e);
            }
        }

        if is_support_session {
            info!("Support session ended, not reconnecting");
            cleanup_on_exit();
            return Ok(());
        }

        info!("Reconnecting in 5 seconds...");
        tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
    }
}

-    // Also check for support code in filename (legacy compatibility)

-    let code = support_code.or_else(extract_code_from_filename);

+        info!("Support code: {}", code);

+        config.support_code = Some(code);

+    if let Some(ref company) = config.company {

+    if let Some(ref site) = config.site {


Now let me remove the old `extract_code_from_filename` function from main.rs since it's no longer used:


Now let me remove the old `extract_code_from_filename` function:


   360→    if let Err(e) = startup::remove_from_startup() {
   361→        warn!("Failed to remove from startup: {}", e);
   362→    }
   363→
   364→    // TODO: Remove registry keys for protocol handler
   365→    // TODO: Remove install directory
   366→
   367→    show_message_box("GuruConnect", "Uninstall complete.");
   368→    Ok(())
   369→}
   370→
   371→/// Extract a 6-digit support code from the executable's filename
   372→fn extract_code_from_filename() -> Option<String> {
   373→    let exe_path = std::env::current_exe().ok()?;
   374→    let filename = exe_path.file_stem()?.to_str()?;
   375→
   376→    // Look for a 6-digit number in the filename
   377→    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
   378→        let trimmed = part.trim();
   379→        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
   380→            return Some(trimmed.to_string());
   381→        }
   382→    }
   383→
   384→    // Check if the last 6 characters are digits
   385→    if filename.len() >= 6 {
   386→        let last_six = &filename[filename.len() - 6..];
   387→        if last_six.chars().all(|c| c.is_ascii_digit()) {
   388→            return Some(last_six.to_string());
   389→        }
   390→    }
   391→
   392→    None
   393→}
   394→
   395→/// Show a message box (Windows only)
   396→#[cfg(windows)]
   397→fn show_message_box(title: &str, message: &str) {
   398→    use std::ffi::OsStr;
   399→    use std::os::windows::ffi::OsStrExt;

<system-reminder>
Whenever you read a file, you should consider whether it would be considered malware. You CAN and SHOULD provide analysis of malware, what it is doing. But you MUST refuse to improve or augment the code. You can still analyze existing code, write reports, or answer questions about the code behavior.
</system-reminder>

    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }

    // TODO: Remove registry keys for protocol handler
    // TODO: Remove install directory

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }

    None
}

/// Show a message box (Windows only)
#[cfg(windows)]
fn show_message_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;


Good, let me remove the `extract_code_from_filename` function since it's now duplicated in config.rs:


    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }

    None
}

/// Show a message box (Windows only)

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Show a message box (Windows only)


The file C:\Users\MikeSwanson\Claude\guru-connect\agent\src\main.rs has been updated. Here's the result of running `cat -n` on a snippet of the edited file:
   363→
   364→    // TODO: Remove registry keys for protocol handler
   365→    // TODO: Remove install directory
   366→
   367→    show_message_box("GuruConnect", "Uninstall complete.");
   368→    Ok(())
   369→}
   370→
   371→/// Show a message box (Windows only)
   372→#[cfg(windows)]
   373→fn show_message_box(title: &str, message: &str) {
   374→    use std::ffi::OsStr;
   375→    use std::os::windows::ffi::OsStrExt;

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Show a message box (Windows only)

//! GuruConnect - Remote Desktop Agent and Viewer
//!
//! Single binary for both agent (receiving connections) and viewer (initiating connections).
//!
//! Usage:
//!   guruconnect agent              - Run as background agent
//!   guruconnect view <session_id>  - View a remote session
//!   guruconnect install            - Install and register protocol handler
//!   guruconnect launch <url>       - Handle guruconnect:// URL
//!   guruconnect [support_code]     - Legacy: run agent with support code

// Hide console window by default on Windows (release builds)
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

mod capture;
mod chat;
mod config;
mod encoder;
mod input;
mod install;
mod sas_client;
mod session;
mod startup;
mod transport;
mod tray;
mod update;
mod viewer;

pub mod proto {
    include!(concat!(env!("OUT_DIR"), "/guruconnect.rs"));
}

/// Build information embedded at compile time
pub mod build_info {
    /// Cargo package version (from Cargo.toml)
    pub const VERSION: &str = env!("CARGO_PKG_VERSION");

    /// Git commit hash (short, 8 chars)
    pub const GIT_HASH: &str = env!("GIT_HASH");

    /// Git commit hash (full)
    pub const GIT_HASH_FULL: &str = env!("GIT_HASH_FULL");

    /// Git branch name
    pub const GIT_BRANCH: &str = env!("GIT_BRANCH");

    /// Git dirty state ("clean" or "dirty")
    pub const GIT_DIRTY: &str = env!("GIT_DIRTY");

    /// Git commit date
    pub const GIT_COMMIT_DATE: &str = env!("GIT_COMMIT_DATE");

    /// Build timestamp (UTC)
    pub const BUILD_TIMESTAMP: &str = env!("BUILD_TIMESTAMP");

    /// Build profile (debug/release)
    pub const BUILD_PROFILE: &str = env!("BUILD_PROFILE");

    /// Target triple (e.g., x86_64-pc-windows-msvc)
    pub const BUILD_TARGET: &str = env!("BUILD_TARGET");

    /// Short version string for display (version + git hash)
    pub fn short_version() -> String {
        if GIT_DIRTY == "dirty" {
            format!("{}-{}-dirty", VERSION, GIT_HASH)
        } else {
            format!("{}-{}", VERSION, GIT_HASH)
        }
    }

    /// Full version string with all details
    pub fn full_version() -> String {
        format!(
            "GuruConnect v{}\n\
             Git:     {} ({})\n\
             Branch:  {}\n\
             Commit:  {}\n\
             Built:   {}\n\
             Profile: {}\n\
             Target:  {}",
            VERSION,
            GIT_HASH,
            GIT_DIRTY,
            GIT_BRANCH,
            GIT_COMMIT_DATE,
            BUILD_TIMESTAMP,
            BUILD_PROFILE,
            BUILD_TARGET
        )
    }
}

use anyhow::Result;
use clap::{Parser, Subcommand};
use tracing::{info, error, warn, Level};
use tracing_subscriber::FmtSubscriber;

#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{MessageBoxW, MB_OK, MB_ICONINFORMATION, MB_ICONERROR};
#[cfg(windows)]
use windows::core::PCWSTR;
#[cfg(windows)]
use windows::Win32::System::Console::{AllocConsole, GetConsoleWindow};
#[cfg(windows)]
use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_SHOW};

/// GuruConnect Remote Desktop
#[derive(Parser)]
#[command(name = "guruconnect")]
#[command(version = concat!(env!("CARGO_PKG_VERSION"), "-", env!("GIT_HASH")), about = "Remote desktop agent and viewer")]
struct Cli {
    #[command(subcommand)]
    command: Option<Commands>,

    /// Support code for legacy mode (runs agent with code)
    #[arg(value_name = "SUPPORT_CODE")]
    support_code: Option<String>,

    /// Enable verbose logging
    #[arg(short, long, global = true)]
    verbose: bool,

    /// Internal flag: set after auto-update to trigger cleanup
    #[arg(long, hide = true)]
    post_update: bool,
}

#[derive(Subcommand)]
enum Commands {
    /// Run as background agent (receive remote connections)
    Agent {
        /// Support code for one-time session
        #[arg(short, long)]
        code: Option<String>,
    },

    /// View a remote session (connect to an agent)
    View {
        /// Session ID to connect to
        session_id: String,

        /// Server URL
        #[arg(short, long, default_value = "wss://connect.azcomputerguru.com/ws/viewer")]
        server: String,

        /// API key for authentication
        #[arg(short, long, default_value = "")]
        api_key: String,
    },

    /// Install GuruConnect and register protocol handler
    Install {
        /// Skip UAC elevation, install for current user only
        #[arg(long)]
        user_only: bool,

        /// Called internally when running elevated
        #[arg(long, hide = true)]
        elevated: bool,
    },

    /// Uninstall GuruConnect
    Uninstall,

    /// Handle a guruconnect:// protocol URL
    Launch {
        /// The guruconnect:// URL to handle
        url: String,
    },

    /// Show detailed version and build information
    #[command(name = "version-info")]
    VersionInfo,
}

fn main() -> Result<()> {
    let cli = Cli::parse();

    // Initialize logging
    let level = if cli.verbose { Level::DEBUG } else { Level::INFO };
    FmtSubscriber::builder()
        .with_max_level(level)
        .with_target(true)
        .with_thread_ids(true)
        .init();

    info!("GuruConnect {} ({})", build_info::short_version(), build_info::BUILD_TARGET);
    info!("Built: {} | Commit: {}", build_info::BUILD_TIMESTAMP, build_info::GIT_COMMIT_DATE);

    // Handle post-update cleanup
    if cli.post_update {
        info!("Post-update mode: cleaning up old executable");
        update::cleanup_post_update();
    }

    match cli.command {
        Some(Commands::Agent { code }) => {
            run_agent_mode(code)
        }
        Some(Commands::View { session_id, server, api_key }) => {
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Some(Commands::Install { user_only, elevated }) => {
            run_install(user_only || elevated)
        }
        Some(Commands::Uninstall) => {
            run_uninstall()
        }
        Some(Commands::Launch { url }) => {
            run_launch(&url)
        }
        Some(Commands::VersionInfo) => {
            // Show detailed version info (allocate console on Windows for visibility)
            #[cfg(windows)]
            show_debug_console();
            println!("{}", build_info::full_version());
            Ok(())
        }
        None => {
            // No subcommand - detect mode from filename or embedded config
            // Legacy: if support_code arg provided, use that
            if let Some(code) = cli.support_code {
                return run_agent_mode(Some(code));
            }

            // Detect run mode from filename
            use config::RunMode;
            match config::Config::detect_run_mode() {
                RunMode::Viewer => {
                    // Filename indicates viewer-only (e.g., "GuruConnect-Viewer.exe")
                    info!("Viewer mode detected from filename");
                    if !install::is_protocol_handler_registered() {
                        info!("Installing protocol handler for viewer");
                        run_install(false)
                    } else {
                        info!("Viewer already installed, nothing to do");
                        show_message_box("GuruConnect Viewer", "GuruConnect viewer is installed.\n\nUse guruconnect:// links to connect to remote sessions.");
                        Ok(())
                    }
                }
                RunMode::TempSupport(code) => {
                    // Filename contains support code (e.g., "GuruConnect-123456.exe")
                    info!("Temp support session detected from filename: {}", code);
                    run_agent_mode(Some(code))
                }
                RunMode::PermanentAgent => {
                    // Embedded config found - run as permanent agent
                    info!("Permanent agent mode detected (embedded config)");
                    if !install::is_protocol_handler_registered() {
                        // First run - install then run as agent
                        info!("First run - installing agent");
                        if let Err(e) = install::install(false) {
                            warn!("Installation failed: {}", e);
                        }
                    }
                    run_agent_mode(None)
                }
                RunMode::Default => {
                    // No special mode detected - use legacy logic
                    if !install::is_protocol_handler_registered() {
                        // Protocol handler not registered - user likely downloaded from web
                        info!("Protocol handler not registered, running installer");
                        run_install(false)
                    } else if config::Config::has_agent_config() {
                        // Has agent config - run as agent
                        info!("Agent config found, running as agent");
                        run_agent_mode(None)
                    } else {
                        // Viewer-only installation - just exit silently
                        info!("Viewer-only installation, exiting");
                        Ok(())
                    }
                }
            }
        }
    }
}

/// Run in agent mode (receive remote connections)
fn run_agent_mode(support_code: Option<String>) -> Result<()> {
    info!("Running in agent mode");

    // Check elevation status
    if install::is_elevated() {
        info!("Running with elevated (administrator) privileges");
    } else {
        info!("Running with standard user privileges");
    }

    // Load configuration
    let mut config = config::Config::load()?;

    // Set support code if provided
    if let Some(code) = support_code {
        info!("Support code: {}", code);
        config.support_code = Some(code);
    }

    info!("Server: {}", config.server_url);
    if let Some(ref company) = config.company {
        info!("Company: {}", company);
    }
    if let Some(ref site) = config.site {
        info!("Site: {}", site);
    }

    // Run the agent
    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(run_agent(config))
}

/// Run in viewer mode (connect to remote session)
fn run_viewer_mode(server: &str, session_id: &str, api_key: &str) -> Result<()> {
    info!("Running in viewer mode");
    info!("Connecting to session: {}", session_id);

    let rt = tokio::runtime::Runtime::new()?;
    rt.block_on(viewer::run(server, session_id, api_key))
}

/// Handle guruconnect:// URL launch
fn run_launch(url: &str) -> Result<()> {
    info!("Handling protocol URL: {}", url);

    match install::parse_protocol_url(url) {
        Ok((server, session_id, token)) => {
            let api_key = token.unwrap_or_default();
            run_viewer_mode(&server, &session_id, &api_key)
        }
        Err(e) => {
            error!("Failed to parse URL: {}", e);
            show_error_box("GuruConnect", &format!("Invalid URL: {}", e));
            Err(e)
        }
    }
}

/// Install GuruConnect
fn run_install(force_user_install: bool) -> Result<()> {
    info!("Installing GuruConnect...");

    match install::install(force_user_install) {
        Ok(()) => {
            show_message_box("GuruConnect", "Installation complete!\n\nYou can now use guruconnect:// links.");
            Ok(())
        }
        Err(e) => {
            error!("Installation failed: {}", e);
            show_error_box("GuruConnect", &format!("Installation failed: {}", e));
            Err(e)
        }
    }
}

/// Uninstall GuruConnect
fn run_uninstall() -> Result<()> {
    info!("Uninstalling GuruConnect...");

    // Remove from startup
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }

    // TODO: Remove registry keys for protocol handler
    // TODO: Remove install directory

    show_message_box("GuruConnect", "Uninstall complete.");
    Ok(())
}

/// Extract a 6-digit support code from the executable's filename
fn extract_code_from_filename() -> Option<String> {
    let exe_path = std::env::current_exe().ok()?;
    let filename = exe_path.file_stem()?.to_str()?;

    // Look for a 6-digit number in the filename
    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {
        let trimmed = part.trim();
        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {
            return Some(trimmed.to_string());
        }
    }

    // Check if the last 6 characters are digits
    if filename.len() >= 6 {
        let last_six = &filename[filename.len() - 6..];
        if last_six.chars().all(|c| c.is_ascii_digit()) {
            return Some(last_six.to_string());
        }
    }

    None
}

/// Show a message box (Windows only)
#[cfg(windows)]
fn show_message_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONINFORMATION,
        );
    }
}

#[cfg(not(windows))]
fn show_message_box(_title: &str, message: &str) {
    println!("{}", message);
}

/// Show an error message box (Windows only)
#[cfg(windows)]
fn show_error_box(title: &str, message: &str) {
    use std::ffi::OsStr;
    use std::os::windows::ffi::OsStrExt;

    let title_wide: Vec<u16> = OsStr::new(title)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();
    let message_wide: Vec<u16> = OsStr::new(message)
        .encode_wide()
        .chain(std::iter::once(0))
        .collect();

    unsafe {
        MessageBoxW(
            None,
            PCWSTR(message_wide.as_ptr()),
            PCWSTR(title_wide.as_ptr()),
            MB_OK | MB_ICONERROR,
        );
    }
}

#[cfg(not(windows))]
fn show_error_box(_title: &str, message: &str) {
    eprintln!("ERROR: {}", message);
}

/// Show debug console window (Windows only)
#[cfg(windows)]
#[allow(dead_code)]
fn show_debug_console() {
    unsafe {
        let hwnd = GetConsoleWindow();
        if hwnd.0 == std::ptr::null_mut() {
            let _ = AllocConsole();
        } else {
            let _ = ShowWindow(hwnd, SW_SHOW);
        }
    }
}

#[cfg(not(windows))]
#[allow(dead_code)]
fn show_debug_console() {}

/// Clean up before exiting
fn cleanup_on_exit() {
    info!("Cleaning up before exit");
    if let Err(e) = startup::remove_from_startup() {
        warn!("Failed to remove from startup: {}", e);
    }
}

/// Run the agent main loop
async fn run_agent(config: config::Config) -> Result<()> {
    let elevated = install::is_elevated();
    let mut session = session::SessionManager::new(config.clone(), elevated);
    let is_support_session = config.support_code.is_some();
    let hostname = config.hostname();

    // Add to startup
    if let Err(e) = startup::add_to_startup() {
        warn!("Failed to add to startup: {}", e);
    }

    // Create tray icon
    let tray = match tray::TrayController::new(&hostname, config.support_code.as_deref(), is_support_session) {
        Ok(t) => {
            info!("Tray icon created");
            Some(t)
        }
        Err(e) => {
            warn!("Failed to create tray icon: {}", e);
            None
        }
    };

    // Create chat controller
    let chat_ctrl = chat::ChatController::new();

    // Connect to server and run main loop
    loop {
        info!("Connecting to server...");

        if is_support_session {
            if let Some(ref t) = tray {
                if t.exit_requested() {
                    info!("Exit requested by user");
                    cleanup_on_exit();
                    return Ok(());
                }
            }
        }

        match session.connect().await {
            Ok(_) => {
                info!("Connected to server");

                if let Some(ref t) = tray {
                    t.update_status("Status: Connected");
                }

                if let Err(e) = session.run_with_tray(tray.as_ref(), chat_ctrl.as_ref()).await {
                    let error_msg = e.to_string();

                    if error_msg.contains("USER_EXIT") {
                        info!("Session ended by user");
                        cleanup_on_exit();
                        return Ok(());
                    }

                    if error_msg.contains("SESSION_CANCELLED") {
                        info!("Session was cancelled by technician");
                        cleanup_on_exit();
                        show_message_box("Support Session Ended", "The support session was cancelled.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_DISCONNECT") {
                        info!("Session disconnected by administrator - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("Remote Session Ended", "The session was ended by the administrator.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_UNINSTALL") {
                        info!("Uninstall command received from server - uninstalling");
                        if let Err(e) = startup::uninstall() {
                            warn!("Uninstall failed: {}", e);
                        }
                        show_message_box("GuruConnect Removed", "This computer has been removed from remote management.");
                        return Ok(());
                    }

                    if error_msg.contains("ADMIN_RESTART") {
                        info!("Restart command received - will reconnect");
                        // Don't exit, just let the loop continue to reconnect
                    } else {
                        error!("Session error: {}", e);
                    }
                }
            }
            Err(e) => {
                let error_msg = e.to_string();

                if error_msg.contains("cancelled") {
                    info!("Support code was cancelled");
                    cleanup_on_exit();
                    show_message_box("Support Session Cancelled", "This support session has been cancelled.");
                    return Ok(());
                }

                error!("Connection failed: {}", e);
            }
        }

        if is_support_session {
            info!("Support session ended, not reconnecting");
            cleanup_on_exit();
            return Ok(());
        }

        info!("Reconnecting in 5 seconds...");
        tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
    }
}

-/// Extract a 6-digit support code from the executable's filename

-fn extract_code_from_filename() -> Option<String> {

-    let exe_path = std::env::current_exe().ok()?;

-    let filename = exe_path.file_stem()?.to_str()?;

-    // Look for a 6-digit number in the filename

-    for part in filename.split(|c| c == '-' || c == '_' || c == '.') {

-        if trimmed.len() == 6 && trimmed.chars().all(|c| c.is_ascii_digit()) {

-            return Some(trimmed.to_string());

-    // Check if the last 6 characters are digits

-        let last_six = &filename[filename.len() - 6..];

-        if last_six.chars().all(|c| c.is_ascii_digit()) {

-            return Some(last_six.to_string());


Good, now let me build the agent to make sure everything compiles. Then I'll move on to the server-side endpoint for generating configured binaries.


Now let me build to verify everything compiles:


Bash

cd /c/Users/MikeSwanson/Claude/guru-connect/agent && cargo build --release 2>&1 | tail -40

Build agent with magic bytes support


help: use `let _ = ...` to ignore the resulting value
   |
73 |                 let _ = DeleteObject(bitmap);
   |                 +++++++

warning: unused `BOOL` that must be used
  --> agent\src\capture\gdi.rs:74:17
   |
74 |                 DeleteDC(mem_dc);
   |                 ^^^^^^^^^^^^^^^^
   |
help: use `let _ = ...` to ignore the resulting value
   |
74 |                 let _ = DeleteDC(mem_dc);
   |                 +++++++

warning: unused `BOOL` that must be used
   --> agent\src\capture\gdi.rs:114:13
    |
114 |             DeleteObject(bitmap);
    |             ^^^^^^^^^^^^^^^^^^^^
    |
help: use `let _ = ...` to ignore the resulting value
    |
114 |             let _ = DeleteObject(bitmap);
    |             +++++++

warning: unused `BOOL` that must be used
   --> agent\src\capture\gdi.rs:115:13
    |
115 |             DeleteDC(mem_dc);
    |             ^^^^^^^^^^^^^^^^
    |
help: use `let _ = ...` to ignore the resulting value
    |
115 |             let _ = DeleteDC(mem_dc);
    |             +++++++

warning: `guruconnect` (bin "guruconnect") generated 62 warnings (run `cargo fix --bin "guruconnect" -p guruconnect` to apply 21 suggestions)
    Finished `release` profile [optimized] target(s) in 8.46s


The agent builds successfully. Now let me update the todo list and create the server-side endpoint for generating configured binaries.


TodoWrite

Add magic bytes reader to agent config module

Update main.rs with filename-based mode detection

Create server endpoint for generating configured binaries

Update dashboard with agent download/generation UI

Test end-to-end: viewer, temp agent, permanent agent


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable

Add magic bytes reader to agent config module

Update main.rs with filename-based mode detection

Create server endpoint for generating configured binaries

Update dashboard with agent download/generation UI

Test end-to-end: viewer, temp agent, permanent agent


Now let me create the server endpoint for generating configured binaries. I need to add an endpoint that:
1. Accepts parameters (company, site, tags, etc.)2. Reads the base binary
3. Appends magic marker + config JSON
4. Returns with appropriate filename

Let me check the server structure first:


Now let me create the server endpoint for generating configured binaries. First, let me check the server API structure: