Bengal's CLI Output system provides a unified interface for all terminal messaging with profile-aware formatting, consistent spacing, and automatic TTY detection.
Overview
The output system centralizes all CLI messaging, ensuring consistent formatting across commands and adapting to different user profiles (Writer, Theme-Dev, Developer).
from bengal.output import CLIOutput
from bengal.utils.profile import BuildProfile
cli = CLIOutput(profile=BuildProfile.WRITER)
cli.header("Building your site...")
cli.phase("Discovery", duration_ms=61, details="245 pages")
cli.detail("Found 245 pages", indent=1)
cli.success("Built 245 pages in 0.8s")
Architecture
Build Profiles
Different profiles show different levels of detail:
Writer Profile
Optimized for content creators:
cli = CLIOutput(profile=BuildProfile.WRITER)
# Shows: High-level progress, errors, warnings
# Hides: Technical details, debug info
Theme-Dev Profile
For theme development:
cli = CLIOutput(profile=BuildProfile.THEME_DEV)
# Shows: Template resolution, asset processing
# Hides: Content discovery details
Developer Profile
Full technical output:
cli = CLIOutput(profile=BuildProfile.DEVELOPER)
# Shows: Everything, including debug info
Output Methods
Headers
cli.header("Building your site...")
# Output: Building your site...
Phase Messages
Track build phase completion with optional timing and details:
cli.phase("Discovery", duration_ms=61)
# Output: ✓ Discovery 61ms
cli.phase("Rendering", duration_ms=501, details="245 pages")
# Output: ✓ Rendering 501ms (245 pages)
cli.phase("Assets", status="Done")
# Output: ✓ Assets Done
Parameters:name,status="Done",duration_ms=None,details=None,icon="✓"
Details
cli.detail("Found 245 pages", indent=1)
# Output: Found 245 pages
Status Messages
cli.success("Build complete!")
cli.warning("Some pages have warnings")
cli.error("Build failed")
cli.info("Using cached assets")
cli.tip("Run 'bengal serve' to preview")
Message Levels
The output system uses message levels for filtering:
from bengal.output.enums import MessageLevel
cli.should_show(MessageLevel.INFO) # True/False based on profile
cli.should_show(MessageLevel.DEBUG) # Only in Developer profile
Rich Integration
The output system automatically detects Rich support:
cli = CLIOutput(use_rich=None) # Auto-detect
cli = CLIOutput(use_rich=True) # Force Rich
cli = CLIOutput(use_rich=False) # Plain text
Rich Features:
- Syntax highlighting
- Tables and panels
- Progress bars
- Colors and styling
Fallback: Automatically falls back to plain text when Rich isn't available.
Global Instance
Use the global instance for convenience:
from bengal.output import get_cli_output, init_cli_output
from bengal.utils.profile import BuildProfile
# Initialize once at CLI entry point
cli = init_cli_output(profile=BuildProfile.WRITER)
# Access from anywhere in the codebase
cli = get_cli_output()
cli.success("Done!")
Dev Server Integration
The output system integrates with the dev server:
# Dev server sets environment variable
os.environ["BENGAL_DEV_SERVER"] = "1"
# Output system detects dev mode
cli.dev_server # True
# Enables phase deduplication, streaming output
Phase Deduplication
In dev server mode, duplicate phase messages are suppressed:
# Rapid rebuilds don't spam terminal
cli.phase("Rendering") # Shows
cli.phase("Rendering") # Suppressed (within 1.5s window)
Related
- CLI - Command-line interface
- Performance - Benchmarks and hot paths