Source code for codex_cli.main

# codex_cli/main.py

import typer
from rich.console import Console
import os
from pathlib import Path
from typing import Optional
from dotenv import load_dotenv

# Import command handlers
from . import explain as explain_module
from . import script as script_module
from . import visualize as visualize_module
from . import config as config_module

# Load environment variables from .env file
load_dotenv()

# Initialize the main Typer application
app = typer.Typer(
    name="cstudio", # Correct invocation name
    help="""🧰 Codex CLI Studio

    A powerful suite of CLI tools powered by OpenAI models.
    Supercharge productivity, learning, and automation.
    """,
    add_completion=False,
    no_args_is_help=True,
    rich_markup_mode="markdown",
    # --- FIX: Corrected examples to use 'cstudio' ---
    epilog=("\n---"
            "\n**Examples:**"
            "\n\n  # Explain a Python file in detail"
            "\n  cstudio explain path/to/your/code.py --detail detailed"
            "\n\n  # Generate a bash script to list large files"
            "\n  cstudio script \"find all files larger than 100MB in /data\" --type bash"
            "\n\n  # Visualize function calls in a Python file as SVG"
            "\n  cstudio visualize src/main.py -f svg -o docs/main_calls.svg"
            "\n\n  # Explain a Docker Compose YAML file"
            "\n  cstudio config explain docker-compose.yml"
            "\n\n---"
            # --- FIX: Corrected help text ---
            "\nUse `cstudio [command] --help` for more information."
            )
)

console = Console()

# --- Explain Command ---
[docs] @app.command( name="explain", help="📖 Explain code, shell commands, or file content using AI.", # --- FIX: Corrected examples to use 'cstudio' --- epilog=("\n---" "\n**Examples:**" "\n\n # Explain a code snippet (basic, English)" "\n cstudio explain 'print(\"Hello\")'" "\n\n # Explain a shell command (detailed, Russian)" "\n cstudio explain 'grep -r \"TODO\" ./src' -d detailed -l ru" "\n\n # Explain a file (basic, Spanish)" "\n cstudio explain path/to/script.js --lang es" "\n---" ) ) def explain( ctx: typer.Context, input_str: str = typer.Argument(..., help="The code snippet, shell command, or file path to explain."), detail: str = typer.Option("basic", "--detail", "-d", help="Level of detail: 'basic' or 'detailed'.", case_sensitive=False), lang: str = typer.Option("en", "--lang", "-l", help="Language code for the explanation (e.g., 'en', 'ru', 'es', 'ja').", case_sensitive=False) ): """Process the explain command.""" explain_module.explain_code(input_str, detail, lang)
# --- Script Command ---
[docs] @app.command( name="script", help="⚙️ Generate scripts (Bash, Python, etc.) from descriptions.", # --- FIX: Corrected examples to use 'cstudio' --- epilog=("\n---" "\n**Examples:**" "\n\n # Generate default (bash) script" "\n cstudio script \"list all .py files\"" "\n\n # Generate Python script" "\n cstudio script \"read csv data.csv and print first column\" -t python" "\n\n # Generate PowerShell script (dry run)" "\n cstudio script \"get running processes\" --type powershell --dry-run" "\n---" ) ) def script( ctx: typer.Context, task_description: str = typer.Argument(..., help="The task description in natural language."), output_type: str = typer.Option("bash", "--type", "-t", help=f"Output script type. Supported: {', '.join(script_module.SUPPORTED_SCRIPT_TYPES)}.", case_sensitive=False), dry_run: bool = typer.Option(False, "--dry-run", help="Only generate and display the script.", is_flag=True) ): """Process the script command.""" script_module.generate_script(task_description, output_type, dry_run)
# --- Visualize Command ---
[docs] @app.command( name="visualize", help="🧠 Generate a function call graph for a Python file (DOT/image).", # --- FIX: Corrected examples to use 'cstudio' --- epilog=("\n---" "\n**Examples:**" "\n\n # Generate DOT file (default)" "\n cstudio visualize path/to/module.py -o graph.gv" "\n\n # Generate PNG image directly" "\n cstudio visualize path/to/module.py -f png -o graph.png" "\n\n # Generate SVG image" "\n cstudio visualize path/to/module.py --format svg" "\n---" "\nRequires Graphviz 'dot' command for image formats." ) ) def visualize( ctx: typer.Context, file_path: Path = typer.Argument(..., exists=True, file_okay=True, dir_okay=False, readable=True, resolve_path=True, help="Path to the Python file (.py) to visualize."), output_file: Path = typer.Option(None, "--output", "-o", help="Path to save the output graph file (e.g., graph.gv, graph.png).", writable=True, resolve_path=True), output_format: Optional[str] = typer.Option(None, "--format", "-f", help="Output format (e.g., png, svg, pdf, dot/gv).", case_sensitive=False) ): """Process the visualize command.""" final_output_path: Optional[str] = str(output_file) if output_file else None visualize_module.generate_visualization(str(file_path), output_dot_or_image_file=final_output_path, output_format=output_format)
# --- Config Command Group --- config_app = typer.Typer( name="config", help="🔧 Work with configuration files.", no_args_is_help=True, rich_markup_mode="markdown", ) app.add_typer(config_app, name="config") # --- Config Explain Subcommand ---
[docs] @config_app.command( "explain", help="📖 Explain a configuration file using an AI model.", # --- FIX: Corrected examples to use 'cstudio' --- epilog=("\n---" "\n**Examples:**" "\n\n # Explain a standard docker-compose file" "\n cstudio config explain docker-compose.yml" "\n\n # Explain an nginx config" "\n cstudio config explain /etc/nginx/nginx.conf" "\n\n # Explain a TOML config" "\n cstudio config explain pyproject.toml" "\n---" ) ) def config_explain( ctx: typer.Context, file_path: Path = typer.Argument(..., exists=True, file_okay=True, dir_okay=False, readable=True, resolve_path=True, help="Path to the configuration file to explain."), ): """Process the config explain subcommand.""" config_module.explain_config(file_path)
# --- Application Runner --- def run(): """Main entry point for the CLI application.""" app() if __name__ == "__main__": run()