commit 871d0b548fb3f25cf0b6d4b45a7ae69c7d470a3f
parent 65a12e6f9d11efb56bcf9e1533dbf8414d4646db
Author: triesap <tyson@radroots.org>
Date: Sat, 27 Jun 2026 06:59:32 +0000
cli: remove terminal color presentation mode
- remove no-color from the public argument surface
- delete terminal color and stream TTY render context fields
- drop output color from runtime config and config get output
- add parser and integration rejection coverage for removed flag
Diffstat:
20 files changed, 23 insertions(+), 57 deletions(-)
diff --git a/src/cli/global.rs b/src/cli/global.rs
@@ -29,7 +29,6 @@ pub struct RuntimeInvocationArgs {
pub verbose: bool,
pub trace: bool,
pub dry_run: bool,
- pub no_color: bool,
pub no_input: bool,
pub yes: bool,
pub log_filter: Option<String>,
diff --git a/src/cli/input.rs b/src/cli/input.rs
@@ -17,7 +17,6 @@ pub fn runtime_invocation_args_from_target(args: &TargetCliArgs) -> RuntimeInvoc
verbose: args.verbose,
trace: args.trace,
dry_run: args.dry_run,
- no_color: args.no_color,
no_input: args.no_input,
yes: false,
log_filter: None,
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
@@ -100,8 +100,6 @@ pub struct TargetCliArgs {
pub verbose: bool,
#[arg(long = "trace", global = true, action = ArgAction::SetTrue)]
pub trace: bool,
- #[arg(long = "no-color", global = true, action = ArgAction::SetTrue)]
- pub no_color: bool,
#[command(subcommand)]
pub command: TargetCommand,
}
@@ -367,7 +365,6 @@ mod tests {
"approval_test",
"--no-input",
"--quiet",
- "--no-color",
"workspace",
"get",
])
@@ -386,11 +383,18 @@ mod tests {
assert_eq!(parsed.approval_token.as_deref(), Some("approval_test"));
assert!(parsed.no_input);
assert!(parsed.quiet);
- assert!(parsed.no_color);
assert_eq!(parsed.command.operation_id(), "workspace.get");
}
#[test]
+ fn target_parser_rejects_removed_no_color_flag() {
+ let error = TargetCliArgs::try_parse_from(["radroots", "--no-color", "workspace", "get"])
+ .expect_err("removed no-color flag should be rejected");
+
+ assert_eq!(error.kind(), clap::error::ErrorKind::UnknownArgument);
+ }
+
+ #[test]
fn target_parser_accepts_account_attach_secret_inputs() {
let parsed = TargetCliArgs::try_parse_from([
"radroots",
diff --git a/src/main.rs b/src/main.rs
@@ -7,7 +7,7 @@ mod registry;
mod runtime;
mod view;
-use std::io::{IsTerminal, Write};
+use std::io::Write;
use std::process::ExitCode;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
@@ -29,7 +29,7 @@ use crate::ops::{
use crate::out::envelope::{CliExitCode, OutputEnvelope, OutputError};
use crate::out::terminal::registry::terminal_renderer_registry;
use crate::out::terminal::renderer::{
- TerminalColorPolicy, TerminalRenderContext, TerminalVerbosity, render_terminal_document,
+ TerminalRenderContext, TerminalVerbosity, render_terminal_document,
};
use crate::registry::{NetworkRequirement, network_requirement, requires_local_signer_mode};
use crate::runtime::config::{
@@ -549,10 +549,7 @@ fn render_config_from_target_args(
},
terminal: TerminalRenderContext {
verbosity: terminal_verbosity_from_flags(args.quiet, args.verbose, args.trace),
- color: terminal_color_policy(!args.no_color),
width: 80,
- stdout_is_tty: std::io::stdout().is_terminal(),
- stderr_is_tty: std::io::stderr().is_terminal(),
dry_run: args.dry_run,
},
}
@@ -567,10 +564,7 @@ fn render_config_from_runtime(config: &RuntimeConfig) -> EnvelopeRenderConfig {
},
terminal: TerminalRenderContext {
verbosity: terminal_verbosity_from_runtime(config.output.verbosity),
- color: terminal_color_policy(config.output.color),
width: 80,
- stdout_is_tty: config.interaction.stdout_tty,
- stderr_is_tty: std::io::stderr().is_terminal(),
dry_run: config.output.dry_run,
},
}
@@ -597,14 +591,6 @@ fn terminal_verbosity_from_runtime(verbosity: Verbosity) -> TerminalVerbosity {
}
}
-fn terminal_color_policy(color: bool) -> TerminalColorPolicy {
- if color {
- TerminalColorPolicy::Auto
- } else {
- TerminalColorPolicy::Never
- }
-}
-
fn render_envelope(
envelope: &OutputEnvelope,
config: &EnvelopeRenderConfig,
diff --git a/src/ops/context.rs b/src/ops/context.rs
@@ -74,7 +74,6 @@ pub struct OperationContext {
pub quiet: bool,
pub verbose: bool,
pub trace: bool,
- pub color: bool,
}
impl OperationContext {
@@ -105,7 +104,6 @@ impl OperationContext {
quiet: args.quiet,
verbose: args.verbose,
trace: args.trace,
- color: !args.no_color,
}
}
diff --git a/src/ops/exec/basket.rs b/src/ops/exec/basket.rs
@@ -1855,7 +1855,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/core.rs b/src/ops/exec/core.rs
@@ -201,7 +201,6 @@ impl OperationService<ConfigGetRequest> for CoreOperationService<'_> {
"output": {
"format": self.config.output.format.as_str(),
"verbosity": self.config.output.verbosity.as_str(),
- "color": self.config.output.color,
"dry_run": self.config.output.dry_run,
},
"interaction": {
@@ -1320,7 +1319,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/farm.rs b/src/ops/exec/farm.rs
@@ -845,7 +845,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/listing.rs b/src/ops/exec/listing.rs
@@ -556,7 +556,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/market.rs b/src/ops/exec/market.rs
@@ -620,7 +620,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/runtime.rs b/src/ops/exec/runtime.rs
@@ -300,7 +300,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/exec/trade.rs b/src/ops/exec/trade.rs
@@ -1742,7 +1742,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/ops/mod.rs b/src/ops/mod.rs
@@ -77,7 +77,6 @@ mod tests {
"--quiet",
"--verbose",
"--trace",
- "--no-color",
"workspace",
"get",
])
@@ -99,7 +98,6 @@ mod tests {
assert!(context.quiet);
assert!(context.verbose);
assert!(context.trace);
- assert!(!context.color);
let envelope_context = context.envelope_context("req_test");
let actor = envelope_context.actor.expect("account actor");
diff --git a/src/out/terminal/renderer.rs b/src/out/terminal/renderer.rs
@@ -15,20 +15,10 @@ pub enum TerminalVerbosity {
Trace,
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum TerminalColorPolicy {
- Auto,
- Always,
- Never,
-}
-
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TerminalRenderContext {
pub verbosity: TerminalVerbosity,
- pub color: TerminalColorPolicy,
pub width: usize,
- pub stdout_is_tty: bool,
- pub stderr_is_tty: bool,
pub dry_run: bool,
}
@@ -36,10 +26,7 @@ impl Default for TerminalRenderContext {
fn default() -> Self {
Self {
verbosity: TerminalVerbosity::Normal,
- color: TerminalColorPolicy::Auto,
width: 80,
- stdout_is_tty: false,
- stderr_is_tty: false,
dry_run: false,
}
}
diff --git a/src/runtime/config.rs b/src/runtime/config.rs
@@ -119,7 +119,6 @@ impl Verbosity {
pub struct OutputConfig {
pub format: OutputFormat,
pub verbosity: Verbosity,
- pub color: bool,
pub dry_run: bool,
}
@@ -642,7 +641,6 @@ impl RuntimeConfig {
workspace_config.as_ref(),
)?,
verbosity: resolve_verbosity(args)?,
- color: !args.no_color,
dry_run: args.dry_run,
};
let logging = LoggingConfig {
@@ -2018,7 +2016,6 @@ mod tests {
output_format: Some(RuntimeOutputFormatArg::Terminal),
verbose: true,
dry_run: true,
- no_color: true,
log_filter: Some("debug".to_owned()),
log_stdout: false,
identity_path: Some(PathBuf::from("custom-identity.json")),
@@ -2073,7 +2070,6 @@ mod tests {
OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Verbose,
- color: false,
dry_run: true,
}
);
@@ -2226,7 +2222,6 @@ mod tests {
OutputConfig {
format: OutputFormat::Json,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
}
);
diff --git a/src/runtime/provider.rs b/src/runtime/provider.rs
@@ -275,7 +275,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/runtime/sdk.rs b/src/runtime/sdk.rs
@@ -1351,7 +1351,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Json,
verbosity: Verbosity::Normal,
- color: false,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/runtime/sync.rs b/src/runtime/sync.rs
@@ -2223,7 +2223,6 @@ mod tests {
output: OutputConfig {
format: OutputFormat::Terminal,
verbosity: Verbosity::Normal,
- color: true,
dry_run: false,
},
interaction: InteractionConfig {
diff --git a/src/view/runtime.rs b/src/view/runtime.rs
@@ -201,7 +201,6 @@ pub struct LegacyPathRuntimeView {
pub struct OutputRuntimeView {
pub format: String,
pub verbosity: String,
- pub color: bool,
pub dry_run: bool,
}
diff --git a/tests/target_cli.rs b/tests/target_cli.rs
@@ -2820,7 +2820,6 @@ fn terminal_global_presentation_flags_are_deterministic() {
for args in [
&["workspace", "get"][..],
&["--quiet", "workspace", "get"][..],
- &["--no-color", "workspace", "get"][..],
] {
let output = radroots().args(args).output().expect("run terminal flag");
@@ -2847,6 +2846,19 @@ fn terminal_global_presentation_flags_are_deterministic() {
}
#[test]
+fn removed_no_color_flag_is_rejected() {
+ let output = radroots()
+ .args(["--no-color", "workspace", "get"])
+ .output()
+ .expect("run removed no-color flag");
+
+ assert_eq!(output.status.code(), Some(2));
+ assert!(output.stdout.is_empty());
+ let stderr = String::from_utf8(output.stderr).expect("utf8 stderr");
+ assert!(stderr.contains("unexpected argument '--no-color'"));
+}
+
+#[test]
fn human_output_format_is_rejected() {
let output = radroots()
.args(["--format", "human", "workspace", "get"])