diff --git a/tito/commands/logo.py b/tito/commands/logo.py index 9f2ecff1..a5e39456 100644 --- a/tito/commands/logo.py +++ b/tito/commands/logo.py @@ -1,5 +1,5 @@ """ -Logo command for TinyTorch CLI: displays beautiful ASCII art logo. +Logo command for TinyTorch CLI: explains the symbolism and meaning behind TinyTorch. """ from argparse import ArgumentParser, Namespace @@ -7,11 +7,9 @@ from rich.console import Console from rich.panel import Panel from rich.text import Text from rich.align import Align -from rich.columns import Columns -import time +from pathlib import Path from .base import BaseCommand -from ..core.preferences import UserPreferences class LogoCommand(BaseCommand): @property @@ -20,228 +18,103 @@ class LogoCommand(BaseCommand): @property def description(self) -> str: - return "Display the TinyTorch ASCII art logo with theme support" + return "Learn about the TinyTorch logo and its meaning" def add_arguments(self, parser: ArgumentParser) -> None: - parser.add_argument("--animate", action="store_true", help="Show animated flame effect") - parser.add_argument("--simple", action="store_true", help="Show simple logo without extra elements") - parser.add_argument("--bright", action="store_true", help="Use bright/vivid theme with yellow center") - parser.add_argument("--theme", choices=["standard", "bright"], help="Choose logo theme") - parser.add_argument("--save-theme", action="store_true", help="Save the selected theme as default") + parser.add_argument("--image", action="store_true", + help="Show path to the actual logo image file") def run(self, args: Namespace) -> int: - # Determine theme - theme = self._get_theme(args) - - # Save theme preference if requested - if args.save_theme: - self._save_theme_preference(theme) - self.console.print(f"[green]βœ… Saved '{theme}' as default theme[/green]") - - if args.animate: - self.show_animated_logo(theme=theme) - elif args.simple: - self.show_simple_logo(theme=theme) - else: - self.show_full_logo(theme=theme) - return 0 - - def show_full_logo(self, theme: str = "standard"): - """Show the complete logo with version and tagline.""" console = self.console - # ASCII Art Logo (now returns a Text object) - logo_art = self.get_logo_art(theme=theme) + # Display the ASCII logo first + from ..core.console import print_ascii_logo + print_ascii_logo() - # Add additional tagline - tagline = Text() - tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan") + # Create the explanation text + explanation = Text() - # Combine logo and tagline - full_content = Text() - full_content.append(logo_art) - full_content.append(tagline) + # Title + explanation.append("\nπŸ”₯ The TinyTorch Story\n\n", style="bold yellow") - # Display with rich styling - border_style = "bright_blue" if theme == "standard" else "bright_yellow" - console.print() + # The flame and sparks + explanation.append("The Flame πŸ”₯\n", style="bold orange1") + explanation.append( + "The flame represents the spark of understanding - how learning ML systems " + "starts with a small flame that can grow into mastery. Just as a torch " + "lights the way in darkness, TinyTorch illuminates the path to understanding " + "neural networks from first principles.\n\n", + style="dim" + ) + + # The sparks + explanation.append("The Sparks ✨\n", style="bold orange1") + explanation.append( + "In our full logo, sparks fly from the flame - representing how knowledge " + "spreads. Each concept you learn sends off sparks that ignite understanding " + "in other areas. What starts small can catch fire and grow into something powerful.\n\n", + style="dim" + ) + + # The "tiny" philosophy + explanation.append("Why 'Tiny'? \n", style="bold cyan") + explanation.append( + "Inspired by TinyML's philosophy: small systems are accessible and powerful. " + "'Tiny' means we start with the fundamentals, building understanding piece by piece. " + "By keeping things small and focused, complex concepts become approachable. " + "Every giant neural network started with tiny building blocks - tensors, gradients, " + "and simple operations.\n\n", + style="dim" + ) + + # The "Torch" connection + explanation.append("Why 'Torch'? \n", style="bold cyan") + explanation.append( + "A tribute to PyTorch, the framework that revolutionized deep learning. " + "While PyTorch is powerful, its complexity can overwhelm beginners. " + "TinyTorch distills those same concepts into their essence, letting you " + "build and understand every component. You're not just using a framework - " + "you're building one.\n\n", + style="dim" + ) + + # The neural network in the flame + explanation.append("The Hidden Network πŸ”₯\n", style="bold orange1") + explanation.append( + "Look closely at our logo - within the flame, there's a neural network pattern. " + "This represents the core truth: inside every ML system, no matter how complex, " + "are simple, connected components working together. The flame contains the network, " + "just as understanding contains mastery.\n\n", + style="dim" + ) + + # The philosophy + explanation.append("The Philosophy πŸ’‘\n", style="bold green") + explanation.append( + "TinyTorch embodies the belief that anyone can understand ML systems by building them. " + "Start small, understand deeply, build everything. What begins as a tiny flame of " + "curiosity becomes the torch that lights your path to ML engineering mastery.\n\n", + style="dim" + ) + + # Display in a nice panel console.print(Panel( - Align.center(full_content), - border_style=border_style, + explanation, + title="[bold]About the TinyTorch Logo[/bold]", + border_style="orange1", padding=(1, 2) )) - console.print() - # Show quick stats - self.show_progress_stats(theme=theme) - - def show_simple_logo(self, theme: str = "standard"): - """Show just the ASCII art logo.""" - console = self.console - logo_art = self.get_logo_art(theme=theme) # Now returns a Text object + # Show logo file path if requested + if args.image: + logo_path = Path(__file__).parent.parent.parent / "logo" / "logo.png" + if logo_path.exists(): + console.print(f"\n[cyan]Logo image location:[/cyan] {logo_path}") + console.print("[dim]Open this file to see the full logo with sparks[/dim]") + else: + console.print(f"\n[yellow]Logo image not found at expected location[/yellow]") - console.print() - console.print(Align.center(logo_art)) - console.print() - - def show_animated_logo(self, theme: str = "standard"): - """Show logo with animated flame effect.""" - console = self.console + # Final inspiring message + console.print("\n[bold yellow]πŸ”₯ Start small. Understand deeply. Build everything.[/bold yellow]\n") - # Animation frames - different for each theme - if theme == "bright": - flame_frames = ["✨", "⚑", "πŸ”₯", "πŸ’«", "✨"] # More energetic - else: - flame_frames = ["πŸ”₯", "πŸ”Ά", "πŸ”Έ", "✨", "πŸ”₯"] # Professional - - border_style = "bright_blue" if theme == "standard" else "bright_yellow" - - for i in range(10): # Show 10 frames - console.clear() - - # Get current flame - flame = flame_frames[i % len(flame_frames)] - - # Create animated logo (now returns a Text object) - logo_art = self.get_logo_art(theme=theme, flame_char=flame) - - tagline = Text() - tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan") - - full_content = Text() - full_content.append(logo_art) - full_content.append(tagline) - - console.print() - console.print(Panel( - Align.center(full_content), - border_style=border_style, - padding=(1, 2) - )) - - time.sleep(0.2) - - # Show final static version - self.show_full_logo(theme=theme) - - def get_logo_art(self, theme: str = "standard", flame_char: str = None): - """Generate the ASCII art logo matching the actual TinyTorch design.""" - # Set default flame character based on theme - if flame_char is None: - flame_char = "✨" if theme == "bright" else "πŸ”₯" - - # Create a Text object to properly handle Rich markup - logo_text = Text() - - # Theme-specific styling - if theme == "bright": - # Bright theme: vivid yellow center, orange "tiny" text - top_flames = "✨πŸ”₯✨" - else: - # Standard theme: professional orange/red tones - top_flames = f"{flame_char}{flame_char}" - - # ASCII art representing the real TinyTorch logo: - # Flame on left with neural network inside, "tiny TORCH" on right - logo_lines = [ - f" {top_flames} ", - " ╱──╲ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—", - " β•± ⚑ β•² β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", - " β•± β•± β•² β•² β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘", - " β”‚ ●━━━● β”‚ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘", - " β”‚ β”‚ ⚑ β”‚ β”‚ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", - " β”‚ ●━┬━● β”‚ β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β•", - " β•² ╲●╱ β•± ", - " ╲━━━╱ ", - " β•²β•± " - ] - - # Add the first line with styled "tiny" - if theme == "bright": - logo_text.append(logo_lines[0]) - logo_text.append("tiny", style="bold orange1") - logo_text.append(" \n") - else: - logo_text.append(logo_lines[0]) - logo_text.append("tiny", style="dim") - logo_text.append(" \n") - - # Add the main ASCII art lines - for line in logo_lines[1:8]: - logo_text.append(line + "\n") - - # Add the tagline with proper styling - logo_text.append(logo_lines[8]) - if theme == "bright": - logo_text.append(flame_char, style="bright_yellow") - logo_text.append(" Learn ML Systems by Building Them", style="bold orange1") - else: - logo_text.append(f"{flame_char} Learn ML Systems by Building Them", style="orange1") - logo_text.append("\n") - - # Add the final line - logo_text.append(logo_lines[9]) - - return logo_text - - def show_progress_stats(self, theme: str = "standard"): - """Show current progress through the course.""" - console = self.console - - # Check how many modules are completed - # This is a simplified version - could be enhanced to check actual module status - - # Theme-specific emoji and styling - if theme == "bright": - journey_emoji = "🌟" - fire_emoji = "⚑" - start_emoji = "πŸ’«" - border_style = "bright_yellow" - else: - journey_emoji = "πŸ“Š" - fire_emoji = "πŸ”₯" - start_emoji = "πŸš€" - border_style = "bright_green" - - stats_table = f""" -[bold cyan]{journey_emoji} Your TinyTorch Journey[/bold cyan] - -[bold green]Module Progress:[/bold green] - 🎯 17 Total Modules Available - πŸ“š Build from Tensors β†’ Training β†’ TinyGPT - {fire_emoji} Learn by Implementation, Not Theory - -[bold yellow]Quick Commands:[/bold yellow] - [dim]tito module status[/dim] - Check module progress - [dim]tito checkpoint timeline[/dim] - Visual progress tracker - [dim]tito module view[/dim] - Start coding in Jupyter Lab - [dim]tito system doctor[/dim] - Diagnose any issues - -[bold magenta]Ready to Build ML Systems? Start with:[/bold magenta] - [dim]tito module view 01_setup[/dim] - Configure your environment -""" - - console.print(Panel( - Text.from_markup(stats_table), - title=f"{start_emoji} Getting Started", - border_style=border_style, - padding=(1, 2) - )) - - def _get_theme(self, args: Namespace) -> str: - """Determine the theme to use based on arguments and preferences.""" - # Check command line arguments first - if args.bright: - return "bright" - if args.theme: - return args.theme - - # Fall back to saved preferences - prefs = UserPreferences.load_from_file() - return prefs.logo_theme - - def _save_theme_preference(self, theme: str) -> None: - """Save the theme preference to config file.""" - prefs = UserPreferences.load_from_file() - prefs.logo_theme = theme - prefs.save_to_file() \ No newline at end of file + return 0 \ No newline at end of file diff --git a/tito/core/console.py b/tito/core/console.py index fe76b8c6..93f6a382 100644 --- a/tito/core/console.py +++ b/tito/core/console.py @@ -22,57 +22,96 @@ def get_console() -> Console: _console = Console(stderr=False) return _console -def print_banner(): - """Print the TinyTorch banner using Rich.""" +def print_banner(compact: bool = False): + """Print the TinyTorch banner using Rich with clean block text style.""" console = get_console() - banner_text = Text("TinyπŸ”₯Torch: Build ML Systems from Scratch", style="bold red") + if compact: + print_compact_banner() + else: + # Create banner text that matches the clean block text theme + banner_text = Text() + banner_text.append("tiny", style="dim cyan") + banner_text.append("πŸ”₯", style="red") + banner_text.append("TORCH", style="bold orange1") + banner_text.append(": Build ML Systems from Scratch", style="dim") + console.print(Panel(banner_text, style="bright_blue", padding=(1, 2))) + +def print_compact_banner(): + """Print a compact TinyTorch banner with 'tiny' above TORCH.""" + console = get_console() + # Create compact banner text + banner_text = Text() + banner_text.append("tiny", style="dim cyan") + banner_text.append("\nπŸ”₯", style="red") + banner_text.append("TORCH", style="bold orange1") + banner_text.append(": Build ML Systems from Scratch", style="dim") console.print(Panel(banner_text, style="bright_blue", padding=(1, 2))) -def print_ascii_logo(): - """Print the beautiful ASCII art TinyTorch logo matching the real design.""" +def print_ascii_logo(compact: bool = False): + """Print the clean, minimal ASCII art TinyTorch logo.""" console = get_console() + if compact: + print_compact_ascii_logo() + return + # Create styled logo text with proper Rich formatting logo_text = Text() - # ASCII Art Logo lines + # ============================================ + # TINYTORCH LOGO - EDIT HERE! + # ============================================ + # To edit: Change the ASCII characters in logo_lines + # Add/remove spaces at the beginning of each line to adjust positioning + logo_lines = [ - " πŸ”₯πŸ”₯ ", - " ╱──╲ ", - " β•± ● β•² β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—", - " β•± β•± β•² β•² β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", - " β”‚ ●───● β”‚ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘", - " β”‚ β”‚ ● β”‚ β”‚ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘", - " β”‚ ●─┬─● β”‚ β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", - " β•² ╲●╱ β•± β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β•", - " ╲───╱ ", - " ╲─╱ " + # Flames above each TORCH letter + " πŸ”₯πŸ”₯πŸ”₯πŸ”₯", + " β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ•—", # TORCH line 1 + " β•štβ•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", # TORCH line 2 + " i β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘", # TORCH line 3 + " n β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘", # TORCH line 4 + " y β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘", # TORCH line 5 + " β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β• β•šβ•β• β•šβ•β•β•β•β•β•β•šβ•β• β•šβ•β•" # TORCH line 6 ] - # Add the first line - logo_text.append(logo_lines[0] + "\n") + # ============================================ + # COLOR CONFIGURATION - EDIT COLORS HERE! + # ============================================ + # Available colors: black, red, green, yellow, blue, magenta, cyan, white + # Prefix with 'bright_' for brighter versions (e.g., 'bright_red') + # Add 'bold' for bold text (e.g., 'bold red' or 'bold bright_black') - # Add the second line with styled "tiny" - logo_text.append(logo_lines[1]) - logo_text.append("tiny", style="dim") - logo_text.append(" \n") + FLAME_COLOR = "yellow" # Color for πŸ”₯ emoji + TINY_COLOR = "bold yellow" # Color for "tiny" text (warmer, more visible) + TORCH_COLOR = "bold white" # Color for "TORCH" text (better contrast) + TAGLINE_COLOR = "orange1" # Color for tagline - # Add the main ASCII art lines - for line in logo_lines[2:9]: - logo_text.append(line + "\n") - - # Add the tagline with proper styling - logo_text.append(logo_lines[9]) - logo_text.append("πŸ”₯ Learn ML Systems by Building Them", style="orange1") + # Process and apply colors to each line + for i, line in enumerate(logo_lines): + if i == 0: # Flame line + logo_text.append(line, style=FLAME_COLOR) + elif i == 4: # Line with tiny + TORCH + # Find where "tiny" ends and TORCH begins (look for β–ˆβ–ˆ) + if "β–ˆβ–ˆβ•‘" in line: + torch_start = line.find("β–ˆβ–ˆβ•‘") + tiny_part = line[:torch_start] + torch_part = line[torch_start:] + logo_text.append(tiny_part, style=TINY_COLOR) + logo_text.append(torch_part, style=TORCH_COLOR) + else: + logo_text.append(line, style=TORCH_COLOR) + else: # Pure TORCH lines + logo_text.append(line, style=TORCH_COLOR) + logo_text.append("\n") # Add tagline - tagline = Text() - tagline.append("\nBuild Complete Neural Networks from First Principles", style="dim cyan") - + logo_text.append("\nπŸ”₯ Don't import the future. Build it from tensors up.", style="orange1") + logo_text.append("\n") + # Combine logo and tagline full_content = Text() full_content.append(logo_text) - full_content.append(tagline) # Display centered with rich styling console.print() @@ -83,6 +122,11 @@ def print_ascii_logo(): )) console.print() +def print_compact_ascii_logo(): + """Print the compact ASCII art TinyTorch logo - same as main logo now.""" + # Just use the main logo since it's already compact and clean + print_ascii_logo(compact=False) + def print_error(message: str, title: str = "Error"): """Print an error message with consistent formatting.""" console = get_console() diff --git a/tito/core/preferences.py b/tito/core/preferences.py deleted file mode 100644 index cae824fc..00000000 --- a/tito/core/preferences.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -User preferences management for TinyTorch CLI. -""" - -import json -from pathlib import Path -from typing import Dict, Any, Optional -from dataclasses import dataclass, asdict - - -@dataclass -class UserPreferences: - """User preferences for TinyTorch CLI.""" - - # Logo preferences - logo_theme: str = "standard" # "standard" or "bright" - - # Future preferences can be added here - # animation_enabled: bool = True - # color_scheme: str = "auto" - - @classmethod - def load_from_file(cls, config_file: Optional[Path] = None) -> 'UserPreferences': - """Load preferences from config file.""" - if config_file is None: - config_file = cls.get_default_config_path() - - if not config_file.exists(): - # Return defaults if no config file exists - return cls() - - try: - with open(config_file, 'r') as f: - data = json.load(f) - - # Create instance with loaded data, using defaults for missing keys - return cls(**{ - key: data.get(key, getattr(cls(), key)) - for key in cls.__dataclass_fields__ - }) - except (json.JSONDecodeError, FileNotFoundError, KeyError): - # Return defaults if config file is corrupted - return cls() - - def save_to_file(self, config_file: Optional[Path] = None) -> None: - """Save preferences to config file.""" - if config_file is None: - config_file = self.get_default_config_path() - - # Ensure config directory exists - config_file.parent.mkdir(parents=True, exist_ok=True) - - with open(config_file, 'w') as f: - json.dump(asdict(self), f, indent=2) - - @staticmethod - def get_default_config_path() -> Path: - """Get the default config file path.""" - # Look for project root first - current = Path.cwd() - while current != current.parent: - if (current / 'pyproject.toml').exists(): - return current / '.tito' / 'config.json' - current = current.parent - - # Fallback to current directory - return Path.cwd() / '.tito' / 'config.json' \ No newline at end of file diff --git a/tito/main.py b/tito/main.py index 16102018..1094a7f4 100644 --- a/tito/main.py +++ b/tito/main.py @@ -95,7 +95,6 @@ Convenience Commands: book Build and manage Jupyter Book grade Simplified grading interface (wraps NBGrader) demo Run AI capability demos (show what your framework can do!) - logo Display the beautiful TinyTorch ASCII art logo Examples: tito system info Show system information @@ -103,7 +102,6 @@ Examples: tito module view 01_setup Start coding in Jupyter Lab tito export 01_tensor Export specific module to package tito checkpoint timeline Visual progress timeline - tito logo --animate Show animated ASCII logo tito book build Build the Jupyter Book locally """ ) @@ -174,8 +172,8 @@ Examples: if hasattr(parsed_args, 'no_color') and parsed_args.no_color: self.config.no_color = True - # Show banner for interactive commands - if parsed_args.command and not self.config.no_color: + # Show banner for interactive commands (except logo which has its own display) + if parsed_args.command and not self.config.no_color and parsed_args.command != 'logo': print_banner() # Validate environment for most commands (skip for doctor) @@ -206,13 +204,12 @@ Examples: " [bold green]export[/bold green] - Export modules to package\n" " [bold green]test[/bold green] - Run tests\n" " [bold green]book[/bold green] - Build and manage Jupyter Book\n" - " [bold green]logo[/bold green] - Display the ASCII art logo\n\n" + " [bold green]logo[/bold green] - Learn about TinyTorch philosophy\n" "[bold]Quick Start:[/bold]\n" " [dim]tito system info[/dim] - Show system information\n" " [dim]tito module status --metadata[/dim] - Module status with metadata\n" " [dim]tito module view 01_setup[/dim] - Start coding in Jupyter Lab\n" " [dim]tito checkpoint timeline[/dim] - Visual progress timeline\n" - " [dim]tito logo --animate[/dim] - Show animated logo\n\n" "[bold]Get Help:[/bold]\n" " [dim]tito system[/dim] - Show system subcommands\n" " [dim]tito module[/dim] - Show module subcommands\n"