Module

utils.cli_output

Centralized CLI output system for Bengal.

Provides a unified interface for all CLI messaging with:

  • Profile-aware formatting (Writer, Theme-Dev, Developer)
  • Consistent indentation and spacing
  • Automatic TTY detection
  • Rich/fallback rendering

Classes

MessageLevel
Message importance levels.
0

Message importance levels.

Inherits from Enum
OutputStyle
Visual styles for messages.
0

Visual styles for messages.

Inherits from Enum
CLIOutput
Centralized CLI output manager. Handles all terminal output with profile-aware formatting, consist…
31

Centralized CLI output manager.

Handles all terminal output with profile-aware formatting, consistent spacing, and automatic TTY detection.

Methods 22

should_show
Determine if message should be shown based on level and settings.
1 bool
def should_show(self, level: MessageLevel) -> bool

Determine if message should be shown based on level and settings.

Parameters 1
level MessageLevel
Returns

bool

header
Print a header message. Example: "ᓚᘏᗢ Building your site..."
4 None
def header(self, text: str, mascot: bool = True, leading_blank: bool = True, trailing_blank: bool = True) -> None

Print a header message. Example: "ᓚᘏᗢ Building your site..."

Parameters 4
text str
mascot bool
leading_blank bool
trailing_blank bool
subheader
Print a subheader with subtle border (lighter than header). Creates a horizont…
5 None
def subheader(self, text: str, icon: str | None = None, leading_blank: bool = True, trailing_blank: bool = False, width: int = 60) -> None

Print a subheader with subtle border (lighter than header).

Creates a horizontal line with text, providing visual structure without the weight of a full boxed header.

Parameters 5
text str

The subheader text

icon str | None

Optional icon/emoji to display before text

leading_blank bool

Add blank line before (default: True)

trailing_blank bool

Add blank line after (default: False)

width int

Total width of the border line (default: 60)

phase
Print a phase status line.
5 None
def phase(self, name: str, status: str = 'Done', duration_ms: float | None = None, details: str | None = None, icon: str = '✓') -> None

Print a phase status line.

Parameters 5
name str
status str
duration_ms float | None
details str | None
icon str
detail
Print a detail/sub-item.
3 None
def detail(self, text: str, indent: int = 1, icon: str | None = None) -> None

Print a detail/sub-item.

Parameters 3
text str
indent int
icon str | None
success
Print a success message. Example: "✨ Built 245 pages in 0.8s"
2 None
def success(self, text: str, icon: str = '✨') -> None

Print a success message.

Example: "✨ Built 245 pages in 0.8s"

Parameters 2
text str
icon str
info
Print an info message.
2 None
def info(self, text: str, icon: str | None = None) -> None

Print an info message.

Parameters 2
text str
icon str | None
warning
Print a warning message.
2 None
def warning(self, text: str, icon: str = '⚠️') -> None

Print a warning message.

Parameters 2
text str
icon str
error
Print an error message.
2 None
def error(self, text: str, icon: str = '❌') -> None

Print an error message.

Parameters 2
text str
icon str
tip
Print a subtle tip/instruction line.
2 None
def tip(self, text: str, icon: str = '💡') -> None

Print a subtle tip/instruction line.

Parameters 2
text str
icon str
error_header
Print an error header with mouse emoji. Example: "ᘛ⁐̤ᕐᐷ 3 template errors fou…
2 None
def error_header(self, text: str, mouse: bool = True) -> None

Print an error header with mouse emoji.

Example: "ᘛ⁐̤ᕐᐷ 3 template errors found"

The mouse represents errors that Bengal (the cat) needs to catch!

Parameters 2
text str
mouse bool
path
Print a path.
3 None
def path(self, path: str, icon: str = '📂', label: str = 'Output') -> None

Print a path.

Parameters 3
path str
icon str
label str
metric
Print a metric.
4 None
def metric(self, label: str, value: Any, unit: str | None = None, indent: int = 0) -> None

Print a metric.

Parameters 4
label str
value Any
unit str | None
indent int
table
Print a table (rich only, falls back to simple list).
2 None
def table(self, data: list[dict[str, str]], headers: list[str]) -> None

Print a table (rich only, falls back to simple list).

Parameters 2
data list[dict[str, str]]
headers list[str]
prompt
Prompt user for input with themed styling.
4 Any
def prompt(self, text: str, default: Any = None, type: Any = str, show_default: bool = True) -> Any

Prompt user for input with themed styling.

Parameters 4
text str

The prompt text to display

default Any

Default value if user presses enter

type Any

Type to convert input to (str, int, float, etc.)

show_default bool

Whether to show the default value

Returns

Any

User's input converted to the specified type

confirm
Prompt user for yes/no confirmation with themed styling.
2 bool
def confirm(self, text: str, default: bool = False) -> bool

Prompt user for yes/no confirmation with themed styling.

Parameters 2
text str

The prompt text to display

default bool

Default value if user presses enter

Returns

bool

True if user confirms, False otherwise

blank
Print blank lines.
1 None
def blank(self, count: int = 1) -> None

Print blank lines.

Parameters 1
count int
separator
Print a horizontal separator line.
2 None
def separator(self, width: int = 78, style: str = 'dim') -> None

Print a horizontal separator line.

Parameters 2
width int

Width of the separator line

style str

Style to apply (dim, info, header, etc.)

file_change_notice
Print a file change notification for dev server.
2 None
def file_change_notice(self, file_name: str, timestamp: str | None = None) -> None

Print a file change notification for dev server.

Parameters 2
file_name str

Name of the changed file (or summary like "file.md (+3 more)")

timestamp str | None

Optional timestamp string (defaults to current time HH:MM:SS)

server_url_inline
Print server URL in inline format (for after rebuild).
2 None
def server_url_inline(self, host: str, port: int) -> None

Print server URL in inline format (for after rebuild).

Parameters 2
host str

Server host

port int

Server port

request_log_header
Print table header for HTTP request logging.
0 None
def request_log_header(self) -> None

Print table header for HTTP request logging.

http_request
Print a formatted HTTP request log line.
5 None
def http_request(self, timestamp: str, method: str, status_code: str, path: str, is_asset: bool = False) -> None

Print a formatted HTTP request log line.

Parameters 5
timestamp str

Request timestamp (HH:MM:SS format)

method str

HTTP method (GET, POST, etc.)

status_code str

HTTP status code as string

path str

Request path

is_asset bool

Whether this is an asset request (affects icon display)

Internal Methods 9
__init__
Initialize CLI output manager.
4 None
def __init__(self, profile: Any | None = None, quiet: bool = False, verbose: bool = False, use_rich: bool | None = None)

Initialize CLI output manager.

Parameters 4
profile Any | None

Build profile (Writer, Theme-Dev, Developer)

quiet bool

Suppress non-critical output

verbose bool

Show detailed output

use_rich bool | None

Force rich/plain output (None = auto-detect)

_get_status_color_code
Get ANSI color code for status code.
1 str
def _get_status_color_code(self, status: str) -> str

Get ANSI color code for status code.

Parameters 1
status str
Returns

str

_get_method_color_code
Get ANSI color code for HTTP method.
1 str
def _get_method_color_code(self, method: str) -> str

Get ANSI color code for HTTP method.

Parameters 1
method str
Returns

str

_get_status_style
Get Rich style name for status code.
1 str
def _get_status_style(self, status: str) -> str

Get Rich style name for status code.

Parameters 1
status str
Returns

str

_get_method_style
Get Rich style name for HTTP method.
1 str
def _get_method_style(self, method: str) -> str

Get Rich style name for HTTP method.

Parameters 1
method str
Returns

str

_show_timing
Should we show timing info based on profile?
0 bool
def _show_timing(self) -> bool

Should we show timing info based on profile?

Returns

bool

_show_details
Should we show detailed info based on profile?
0 bool
def _show_details(self) -> bool

Should we show detailed info based on profile?

Returns

bool

_format_phase_line
Format a phase line with consistent spacing.
1 str
def _format_phase_line(self, parts: list[str]) -> str

Format a phase line with consistent spacing.

Parameters 1
parts list[str]
Returns

str

_format_path
Format path based on profile (shorten for Writer, full for Developer).
1 str
def _format_path(self, path: str) -> str

Format path based on profile (shorten for Writer, full for Developer).

Parameters 1
path str
Returns

str

Functions

get_cli_output
Get the global CLI output instance.
0 CLIOutput
def get_cli_output() -> CLIOutput

Get the global CLI output instance.

Returns

CLIOutput

init_cli_output
Initialize the global CLI output instance with settings.
3 CLIOutput
def init_cli_output(profile: Any | None = None, quiet: bool = False, verbose: bool = False) -> CLIOutput

Initialize the global CLI output instance with settings.

Parameters 3

Name Type Default Description
profile Any | None None
quiet bool False
verbose bool False

Returns

CLIOutput