feat: add NO_COLOR environment variable support (#122)

Add a centralized color module (cli/src/color.rs) that respects the
NO_COLOR environment variable per https://no-color.org/

Changes:
- Add color.rs module with helper functions for colored output
- Refactor all hardcoded ANSI escape codes to use the color module
- Add tests for color formatting functions
- Update AGENTS.md with color module usage guidelines

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ryan Daigle
2026-01-17 20:37:00 -06:00
committed by GitHub
co-authored by Claude Opus 4.5
parent 28740acecf
commit c88734da89
5 changed files with 203 additions and 45 deletions
+14 -12
View File
@@ -1,3 +1,4 @@
use crate::color;
use std::process::{exit, Command, Stdio};
pub fn run_install(with_deps: bool) {
@@ -5,7 +6,7 @@ pub fn run_install(with_deps: bool) {
if is_linux {
if with_deps {
println!("\x1b[36mInstalling system dependencies...\x1b[0m");
println!("{}", color::cyan("Installing system dependencies..."));
let (pkg_mgr, deps) = if which_exists("apt-get") {
(
@@ -93,7 +94,7 @@ pub fn run_install(with_deps: bool) {
],
)
} else {
eprintln!("\x1b[31m✗\x1b[0m No supported package manager found (apt-get, dnf, or yum)");
eprintln!("{} No supported package manager found (apt-get, dnf, or yum)", color::error_indicator());
exit(1);
};
@@ -112,22 +113,23 @@ pub fn run_install(with_deps: bool) {
match status {
Ok(s) if s.success() => {
println!("\x1b[32m✓\x1b[0m System dependencies installed")
println!("{} System dependencies installed", color::success_indicator())
}
Ok(_) => eprintln!(
"\x1b[33m⚠\x1b[0m Failed to install some dependencies. You may need to run manually with sudo."
"{} Failed to install some dependencies. You may need to run manually with sudo.",
color::warning_indicator()
),
Err(e) => eprintln!("\x1b[33m⚠\x1b[0m Could not run install command: {}", e),
Err(e) => eprintln!("{} Could not run install command: {}", color::warning_indicator(), e),
}
} else {
println!("\x1b[33m⚠\x1b[0m Linux detected. If browser fails to launch, run:");
println!("{} Linux detected. If browser fails to launch, run:", color::warning_indicator());
println!(" agent-browser install --with-deps");
println!(" or: npx playwright install-deps chromium");
println!();
}
}
println!("\x1b[36mInstalling Chromium browser...\x1b[0m");
println!("{}", color::cyan("Installing Chromium browser..."));
// On Windows, we need to use cmd.exe to run npx because npx is actually npx.cmd
// and Command::new() doesn't resolve .cmd files the way the shell does.
@@ -144,23 +146,23 @@ pub fn run_install(with_deps: bool) {
match status {
Ok(s) if s.success() => {
println!("\x1b[32m✓\x1b[0m Chromium installed successfully");
println!("{} Chromium installed successfully", color::success_indicator());
if is_linux && !with_deps {
println!();
println!("\x1b[33mNote:\x1b[0m If you see \"shared library\" errors when running, use:");
println!("{} If you see \"shared library\" errors when running, use:", color::yellow("Note:"));
println!(" agent-browser install --with-deps");
}
}
Ok(_) => {
eprintln!("\x1b[31m✗\x1b[0m Failed to install browser");
eprintln!("{} Failed to install browser", color::error_indicator());
if is_linux {
println!("\x1b[33mTip:\x1b[0m Try installing system dependencies first:");
println!("{} Try installing system dependencies first:", color::yellow("Tip:"));
println!(" agent-browser install --with-deps");
}
exit(1);
}
Err(e) => {
eprintln!("\x1b[31m✗\x1b[0m Failed to run npx: {}", e);
eprintln!("{} Failed to run npx: {}", color::error_indicator(), e);
eprintln!("Make sure Node.js is installed and npx is in your PATH");
exit(1);
}