Structure webber into three independent subprojects: - webber-api/: FastAPI backend server with all agent code - webber-cli/: Standalone CLI client (renamed from cli/ to webber_cli/) - webber-sandbox/: Test project for functional testing Key changes: - Each subproject has its own .venv (Python 3.12+) - Added sandbox.sh for managing test project templates - Created sandbox-templates/ with calculator-cli and empty starter - Updated CI/CD for prefixed tags (api/v*, cli/v*) - Added comprehensive AGENTS.md with operational instructions - Added gitignore filtering to glob and grep tools - Created pyproject.toml for each subproject Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
84 lines
2.3 KiB
Python
84 lines
2.3 KiB
Python
"""
|
|
Explore command - one-shot codebase exploration.
|
|
"""
|
|
import asyncio
|
|
from pathlib import Path
|
|
|
|
import typer
|
|
from rich.panel import Panel
|
|
|
|
from src.cli.theme import get_theme
|
|
from src.cli.ui.console import get_console
|
|
from src.cli.ui.display import format_response
|
|
from src.shared.logging import setup_logging
|
|
|
|
console = get_console()
|
|
|
|
|
|
def explore_command(
|
|
query: str = typer.Argument(..., help="What to search for in the codebase"),
|
|
directory: str = typer.Option(
|
|
".",
|
|
"--directory",
|
|
"-d",
|
|
help="Working directory to explore",
|
|
),
|
|
verbose: bool = typer.Option(
|
|
False,
|
|
"--verbose",
|
|
"-V",
|
|
help="Show detailed output",
|
|
),
|
|
) -> None:
|
|
"""
|
|
One-shot codebase exploration.
|
|
|
|
Searches the codebase for the given query and returns findings.
|
|
|
|
Examples:
|
|
webber explore "where is config loaded"
|
|
webber explore "find all API endpoints" -d ./src
|
|
webber explore "how does authentication work"
|
|
"""
|
|
# Set up logging based on verbosity
|
|
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)
|
|
|
|
console.print(f"[dim]Exploring:[/] [path]{working_dir}[/]")
|
|
console.print(f"[dim]Query:[/] {query}\n")
|
|
|
|
# Run the exploration
|
|
asyncio.run(_explore_async(query, working_dir, verbose))
|
|
|
|
|
|
async def _explore_async(query: str, working_dir: str, verbose: bool) -> None:
|
|
"""Async exploration implementation."""
|
|
from src.domains.agents.explore import explore
|
|
|
|
theme = get_theme()
|
|
|
|
try:
|
|
with console.status("[info]Searching codebase...[/]", spinner=theme.spinner):
|
|
result = await explore(query, working_dir=working_dir)
|
|
|
|
# Display result
|
|
formatted = format_response(result)
|
|
console.print(Panel(
|
|
formatted,
|
|
title="[success]Findings[/]",
|
|
border_style=theme.colors.border_success,
|
|
))
|
|
|
|
except Exception as e:
|
|
console.print(f"[error]Error:[/] {e}")
|
|
if verbose:
|
|
console.print_exception()
|
|
raise typer.Exit(1)
|