# 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, ) ) env_key, provider_name = "OPENAI_API_KEY", "OpenAI Responses" # 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", "OPENAI_MODEL=mimo-v2.6-flash", "OPENAI_REASONING_EFFORT=high", "OPENAI_TIMEOUT_SECONDS=300", "OPENAI_MAX_RETRIES=5", "OPENAI_RETRY_INTERVAL_SECONDS=10", "OPENAI_RATE_LIMIT_RETRY_SECONDS=60", "OPENAI_TOOL_FALLBACK_MODEL=gpt-6-luna", "OPENAI_TOOL_FALLBACK_REASONING_EFFORT=high", "OPENAI_TOOL_FALLBACK_MAX_RETRIES=3", "ARTEMIS_TOOL_FALLBACK_MAX_NO_PROGRESS_ATTEMPTS=3", "ARTEMIS_VIDEO_ENABLED=false", "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] Codex(MCP + 官方 artemis-use Skill)") console.print(" [2] 暂时跳过") mcp_choice = Prompt.ask("Select Codex integration", choices=["1", "2"], default="1") if mcp_choice == "1": target = "codex" 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 codex[/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()