# Copyright 2026 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Interactive setup wizard for first-time ARTEMIS onboarding (artemis init).""" import shutil import subprocess from rich.console import Console from rich.panel import Panel from rich.prompt import Prompt from artemis.config.paths import get_env_file def init_command() -> None: """Interactive quickstart wizard to configure API keys and connect your device.""" console = Console() console.print() console.print( Panel( "[bold cyan]☕ Welcome to Artemis Mobile Testing Framework[/bold cyan]\n" "[dim]Let's get you set up in 10 seconds![/dim]", expand=False, ) ) # 1. Select Provider console.print("\n[bold]Step 1: Choose Primary LLM Provider[/bold]") console.print(" [1] Google Gemini (Recommended - Default)") console.print(" [2] OpenAI (GPT-4o)") console.print(" [3] Anthropic (Claude 3.5 Sonnet)") console.print(" [4] OpenRouter") choice = Prompt.ask("Select provider", choices=["1", "2", "3", "4"], default="1") provider_map = { "1": ("GEMINI_API_KEY", "Google Gemini"), "2": ("OPENAI_API_KEY", "OpenAI"), "3": ("ANTHROPIC_API_KEY", "Anthropic"), "4": ("OPEN_ROUTER_API_KEY", "OpenRouter"), } env_key, provider_name = provider_map[choice] # 2. Enter API Key console.print(f"\n[bold]Step 2: Enter your {provider_name} API Key[/bold]") api_key = Prompt.ask(f"Enter {env_key}", password=True) while not api_key.strip(): console.print("[bold red]API Key cannot be empty.[/bold red]") api_key = Prompt.ask(f"Enter {env_key}", password=True) # 3. Scan for Android Devices console.print("\n[bold]Step 3: Detecting Android Devices / Emulators...[/bold]") detected_devices = [] adb_path = shutil.which("adb") if adb_path: try: res = subprocess.run( [adb_path, "devices", "-l"], capture_output=True, text=True, timeout=5, ) lines = [line_str.strip() for line_str in res.stdout.splitlines() if line_str.strip()] for line in lines[1:]: parts = line.split() if len(parts) >= 2 and parts[1] == "device": serial = parts[0] extra = " ".join(parts[2:]) detected_devices.append((serial, extra)) except (OSError, subprocess.SubprocessError): # adb probe failed or timed out; continue setup with no devices. pass selected_serial = "" if detected_devices: console.print( f"[bold green]✔ Found {len(detected_devices)} connected device(s):[/bold green]" ) for idx, (serial, extra) in enumerate(detected_devices, 1): console.print(f" [{idx}] {serial} ({extra})") if len(detected_devices) == 1: selected_serial = detected_devices[0][0] console.print(f"[dim]Auto-selected device: {selected_serial}[/dim]") else: dev_choice = Prompt.ask( "Select device index", choices=[str(i) for i in range(1, len(detected_devices) + 1)], default="1", ) selected_serial = detected_devices[int(dev_choice) - 1][0] else: console.print( "[bold yellow]⚠ No connected device detected right now.[/bold yellow]\n" "[dim]Artemis will auto-detect your device when you connect it later.[/dim]" ) # 4. Generate .env File env_content = [ "# ==============================================================================", "# ☕ ARTEMIS Environment Configuration (Generated by 'artemis init')", "# ==============================================================================", f"{env_key}={api_key.strip()}", "", "# Android Device Configuration", "ADB_HOST=127.0.0.1", "ADB_PORT=5037", ] if selected_serial: env_content.append(f"ADB_DEVICE_SERIAL={selected_serial}") else: env_content.append("# ADB_DEVICE_SERIAL=emulator-5554") env_content.extend( [ "", "# Execution Defaults", "ARTEMIS_DEFAULT_PROFILE=pro", "ARTEMIS_DEFAULT_MODEL=gemini-2.5-flash", "ARTEMIS_TRACES_DIR=./traces", "", ] ) env_path = get_env_file() env_path.parent.mkdir(parents=True, exist_ok=True) env_path.write_text("\n".join(env_content), encoding="utf-8") # 5. Configure MCP for AI IDEs console.print("\n[bold]Step 5: Connect Artemis to your AI IDE (MCP)[/bold]") console.print(" [1] Antigravity / Jetski (Recommended - Default)") console.print(" [2] Cursor") console.print(" [3] Claude Desktop / Claude Code") console.print(" [4] Windsurf") console.print(" [5] VS Code / Cline / Roo Code") console.print(" [6] Codex") console.print(" [7] All supported IDEs") console.print(" [8] Skip for now") mcp_choice = Prompt.ask( "Select IDE for MCP auto-install", choices=["1", "2", "3", "4", "5", "6", "7", "8"], default="1", ) if mcp_choice != "8": target_map = { "1": "antigravity", "2": "cursor", "3": "claude", "4": "windsurf", "5": "vscode", "6": "codex", "7": "all", } target = target_map.get(mcp_choice, "antigravity") try: from artemis.interfaces.cli.commands.mcp import install_mcp_config from mcp_server.utils import env_utils proj_root = env_utils.get_project_root() py_exe = env_utils.resolve_python_executable(proj_root) installed_paths = install_mcp_config(target, py_exe, proj_root) console.print( f"[bold green]✔ Configured Artemis MCP in {len(installed_paths)} IDE location(s).[/bold green]" ) except Exception as e: console.print(f"[yellow]Could not auto-install MCP config: {e}[/yellow]") console.print() console.print( Panel( f"[bold green]🎉 Setup completed successfully![/bold green]\n\n" f"Configured [bold cyan]{provider_name}[/bold cyan] in [dim]{env_path}[/dim]\n\n" "Try running your first task:\n" ' [bold cyan]uv run artemis run "Open YouTube and search for Lo-Fi Hip Hop"[/bold cyan]\n\n' "Or connect/update your AI IDE anytime with:\n" " [bold cyan]uv run artemis mcp --install all[/bold cyan]\n\n" "Or run health diagnostics anytime with:\n" " [bold cyan]uv run artemis doctor[/bold cyan]", title="☕ Ready to Go!", expand=False, ) ) console.print()