Principle:Openclaw Openclaw Global CLI State Management
| Knowledge Sources | |
|---|---|
| Domains | CLI, Logging, Configuration |
| Last Updated | 2026-02-06 12:00 GMT |
Overview
A module-level global state pattern that provides shared verbose and auto-confirm flags across all CLI subsystems, with integrated themed logging output.
Description
Global CLI State Management addresses the need for cross-cutting behavioral flags in a CLI application. Two common patterns require globally-accessible state:
- Verbose mode: A `--verbose` flag that increases output detail across all commands, subcommands, and library calls without threading the flag through every function signature.
- Auto-confirm mode: A `--yes` flag that skips interactive confirmation prompts for scripted/automated usage.
Rather than passing these flags through dependency injection to every function, the pattern uses module-level singletons with getter/setter pairs. This is a pragmatic trade-off: it sacrifices testability purity for ergonomic access from deeply nested call sites.
The verbose logging integrates two output channels:
- Structured file logger: Always logs at debug level when verbose or file log level is enabled, producing machine-parseable log entries.
- Themed console output: Only prints to stdout when the verbose flag is explicitly set, using the terminal theme's muted style.
Usage
Use this principle in CLI applications where behavioral flags (verbose, quiet, yes, dry-run) need to be accessible from any module without explicit parameter threading. Set the flags once at CLI parse time and read them anywhere.
Theoretical Basis
The pattern follows a module singleton with accessor functions:
# Abstract pattern (NOT real implementation)
# Module-level mutable state
_verbose = False
_yes = False
def set_verbose(v: bool) -> None:
global _verbose
_verbose = v
def is_verbose() -> bool:
return _verbose
def log_verbose(msg: str) -> None:
if _verbose or file_log_level_enabled("debug"):
file_logger.debug(msg)
if _verbose:
print(themed_muted(msg))
Trade-offs:
- Pros: Zero-cost access from any call site, no need to thread state through function signatures.
- Cons: Global mutable state can cause test interference if not reset between tests; harder to reason about in concurrent contexts.
- Mitigation: The flags are set once at startup and read-only thereafter in normal usage. Tests reset them explicitly.