use crate::connection::Response; pub fn print_response(resp: &Response, json_mode: bool) { if json_mode { println!("{}", serde_json::to_string(resp).unwrap_or_default()); return; } if !resp.success { eprintln!( "\x1b[31m✗\x1b[0m {}", resp.error.as_deref().unwrap_or("Unknown error") ); return; } if let Some(data) = &resp.data { // Navigation response if let Some(url) = data.get("url").and_then(|v| v.as_str()) { if let Some(title) = data.get("title").and_then(|v| v.as_str()) { println!("\x1b[32m✓\x1b[0m \x1b[1m{}\x1b[0m", title); println!("\x1b[2m {}\x1b[0m", url); return; } println!("{}", url); return; } // Snapshot if let Some(snapshot) = data.get("snapshot").and_then(|v| v.as_str()) { println!("{}", snapshot); return; } // Title if let Some(title) = data.get("title").and_then(|v| v.as_str()) { println!("{}", title); return; } // Text if let Some(text) = data.get("text").and_then(|v| v.as_str()) { println!("{}", text); return; } // HTML if let Some(html) = data.get("html").and_then(|v| v.as_str()) { println!("{}", html); return; } // Value if let Some(value) = data.get("value").and_then(|v| v.as_str()) { println!("{}", value); return; } // Count if let Some(count) = data.get("count").and_then(|v| v.as_i64()) { println!("{}", count); return; } // Boolean results if let Some(visible) = data.get("visible").and_then(|v| v.as_bool()) { println!("{}", visible); return; } if let Some(enabled) = data.get("enabled").and_then(|v| v.as_bool()) { println!("{}", enabled); return; } if let Some(checked) = data.get("checked").and_then(|v| v.as_bool()) { println!("{}", checked); return; } // Eval result if let Some(result) = data.get("result") { println!( "{}", serde_json::to_string_pretty(result).unwrap_or_default() ); return; } // Tabs if let Some(tabs) = data.get("tabs").and_then(|v| v.as_array()) { for (i, tab) in tabs.iter().enumerate() { let title = tab .get("title") .and_then(|v| v.as_str()) .unwrap_or("Untitled"); let url = tab.get("url").and_then(|v| v.as_str()).unwrap_or(""); let active = tab.get("active").and_then(|v| v.as_bool()).unwrap_or(false); let marker = if active { "→" } else { " " }; println!("{} [{}] {} - {}", marker, i, title, url); } return; } // Console logs if let Some(logs) = data.get("logs").and_then(|v| v.as_array()) { for log in logs { let level = log.get("type").and_then(|v| v.as_str()).unwrap_or("log"); let text = log.get("text").and_then(|v| v.as_str()).unwrap_or(""); let color = match level { "error" => "\x1b[31m", "warning" => "\x1b[33m", "info" => "\x1b[36m", _ => "\x1b[0m", }; println!("{}[{}]\x1b[0m {}", color, level, text); } return; } // Errors if let Some(errors) = data.get("errors").and_then(|v| v.as_array()) { for err in errors { let msg = err.get("message").and_then(|v| v.as_str()).unwrap_or(""); println!("\x1b[31m✗\x1b[0m {}", msg); } return; } // Cookies if let Some(cookies) = data.get("cookies").and_then(|v| v.as_array()) { for cookie in cookies { let name = cookie.get("name").and_then(|v| v.as_str()).unwrap_or(""); let value = cookie.get("value").and_then(|v| v.as_str()).unwrap_or(""); println!("{}={}", name, value); } return; } // Bounding box if let Some(box_data) = data.get("box") { println!( "{}", serde_json::to_string_pretty(box_data).unwrap_or_default() ); return; } // Closed if data.get("closed").is_some() { println!("\x1b[32m✓\x1b[0m Browser closed"); return; } // Screenshot path if let Some(path) = data.get("path").and_then(|v| v.as_str()) { println!("\x1b[32m✓\x1b[0m Screenshot saved to {}", path); return; } // Default success println!("\x1b[32m✓\x1b[0m Done"); } } /// Print command-specific help. Returns true if help was printed, false if command unknown. pub fn print_command_help(command: &str) -> bool { let help = match command { // === Navigation === "open" | "goto" | "navigate" => r##" agent-browser open - Navigate to a URL Usage: agent-browser open Navigates the browser to the specified URL. If no protocol is provided, https:// is automatically prepended. Aliases: goto, navigate Global Options: --json Output as JSON --session Use specific session --headers Set HTTP headers (scoped to this origin) --headed Show browser window Examples: agent-browser open example.com agent-browser open https://github.com agent-browser open localhost:3000 agent-browser open api.example.com --headers '{"Authorization": "Bearer token"}' # ^ Headers only sent to api.example.com, not other domains "##, "back" => r##" agent-browser back - Navigate back in history Usage: agent-browser back Goes back one page in the browser history, equivalent to clicking the browser's back button. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser back "##, "forward" => r##" agent-browser forward - Navigate forward in history Usage: agent-browser forward Goes forward one page in the browser history, equivalent to clicking the browser's forward button. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser forward "##, "reload" => r##" agent-browser reload - Reload the current page Usage: agent-browser reload Reloads the current page, equivalent to pressing F5 or clicking the browser's reload button. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser reload "##, // === Core Actions === "click" => r##" agent-browser click - Click an element Usage: agent-browser click Clicks on the specified element. The selector can be a CSS selector, XPath, or an element reference from snapshot (e.g., @e1). Global Options: --json Output as JSON --session Use specific session Examples: agent-browser click "#submit-button" agent-browser click @e1 agent-browser click "button.primary" agent-browser click "//button[@type='submit']" "##, "dblclick" => r##" agent-browser dblclick - Double-click an element Usage: agent-browser dblclick Double-clicks on the specified element. Useful for text selection or triggering double-click handlers. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser dblclick "#editable-text" agent-browser dblclick @e5 "##, "fill" => r##" agent-browser fill - Clear and fill an input field Usage: agent-browser fill Clears the input field and fills it with the specified text. This replaces any existing content in the field. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser fill "#email" "user@example.com" agent-browser fill @e3 "Hello World" agent-browser fill "input[name='search']" "query" "##, "type" => r##" agent-browser type - Type text into an element Usage: agent-browser type Types text into the specified element character by character. Unlike fill, this does not clear existing content first. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser type "#search" "hello" agent-browser type @e2 "additional text" "##, "hover" => r##" agent-browser hover - Hover over an element Usage: agent-browser hover Moves the mouse to hover over the specified element. Useful for triggering hover states or dropdown menus. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser hover "#dropdown-trigger" agent-browser hover @e4 "##, "focus" => r##" agent-browser focus - Focus an element Usage: agent-browser focus Sets keyboard focus to the specified element. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser focus "#input-field" agent-browser focus @e2 "##, "check" => r##" agent-browser check - Check a checkbox Usage: agent-browser check Checks a checkbox element. If already checked, no action is taken. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser check "#terms-checkbox" agent-browser check @e7 "##, "uncheck" => r##" agent-browser uncheck - Uncheck a checkbox Usage: agent-browser uncheck Unchecks a checkbox element. If already unchecked, no action is taken. Global Options: --json Output as JSON --session Use specific session Examples: agent-browser uncheck "#newsletter-opt-in" agent-browser uncheck @e8 "##, "select" => r##" agent-browser select - Select a dropdown option Usage: agent-browser select Selects an option in a