""" Chat command - interactive conversation mode. """ import asyncio from pathlib import Path import typer from src.cli.theme import get_theme from src.cli.ui.console import get_console from src.cli.session.loop import AgenticLoop from src.shared.logging import setup_logging console = get_console() def chat_command( directory: str = typer.Option( ".", "--directory", "-d", help="Working directory to explore", ), verbose: bool = typer.Option( False, "--verbose", "-V", help="Show detailed output and debug logging", ), ) -> None: """ Start interactive chat session. Enters a conversation loop where you can ask questions about the codebase. The explore agent will search files, read code, and answer questions. Examples: webber chat webber chat -d ./src webber chat --verbose """ # Set up logging log_level = "DEBUG" if verbose else "WARNING" setup_logging(log_level) # Resolve directory working_dir = str(Path(directory).resolve()) if not Path(working_dir).exists(): console.print(f"[error]Error:[/] Directory not found: {working_dir}") raise typer.Exit(1) # Run the async chat loop try: asyncio.run(_chat_loop(working_dir, verbose)) except KeyboardInterrupt: console.print("\n[dim]Goodbye![/]") async def _chat_loop(working_dir: str, verbose: bool) -> None: """Async chat loop implementation.""" from src.domains.agents.explore import explore_agent # Create the agentic loop loop = AgenticLoop( agent=explore_agent, console=console, working_dir=working_dir, ) # Display welcome loop.display_welcome() # Main conversation loop while True: try: # Get user input user_input = console.input("[prompt]>[/] ").strip() # Handle special commands if not user_input: continue if user_input.lower() in ("exit", "quit", "/exit", "/quit"): console.print("[dim]Goodbye![/]") break if user_input.lower() in ("clear", "/clear"): loop.state.clear_history() console.print("[info]History cleared.[/]") continue if user_input.lower() in ("status", "/status"): loop.display_status() continue if user_input.lower().startswith("cd "): new_dir = user_input[3:].strip() new_path = Path(new_dir).resolve() if new_path.exists() and new_path.is_dir(): loop.set_working_dir(str(new_path)) else: console.print(f"[error]Directory not found:[/] {new_dir}") continue # Process with agent theme = get_theme() with console.status("[info]Thinking...[/]", spinner=theme.spinner): response = await loop.run_turn(user_input) # Display response console.print() loop.display_response(response) console.print() except KeyboardInterrupt: console.print("\n[dim]Use 'exit' to quit or press Ctrl+C again.[/]") try: # Wait briefly for second Ctrl+C await asyncio.sleep(0.5) except KeyboardInterrupt: console.print("\n[dim]Goodbye![/]") break except Exception as e: console.print(f"[error]Error:[/] {e}") if verbose: console.print_exception()