From 0756a42ce8142e019bc456013e3e6c96f6e70b25 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 27 Feb 2026 18:44:19 -0500 Subject: [PATCH] Consolidate redact and terminal crates into util Merges two small utility crates into a single `util` crate to reduce workspace clutter. No behavioral changes. Co-Authored-By: Claude Opus 4.6 --- Cargo.lock | 31 ++++++++----------- crates/agent/Cargo.toml | 2 +- crates/agent/src/cli.rs | 2 +- crates/attractor/Cargo.toml | 3 +- crates/attractor/src/cli/backend.rs | 2 +- crates/attractor/src/cli/mod.rs | 2 +- crates/attractor/src/cli/run.rs | 10 +++--- crates/attractor/src/cli/serve.rs | 2 +- crates/attractor/src/cli/validate.rs | 2 +- crates/attractor/src/interviewer/console.rs | 2 +- crates/attractor/src/main.rs | 2 +- crates/attractor/src/server.rs | 2 +- crates/attractor/tests/integration.rs | 2 +- crates/terminal/Cargo.toml | 9 ------ crates/{redact => util}/Cargo.toml | 4 +-- crates/{redact => util}/build.rs | 0 crates/{redact => util}/data/gitleaks.toml | 0 crates/util/src/lib.rs | 2 ++ .../src => util/src/redact}/entropy.rs | 2 +- .../src => util/src/redact}/gitleaks.rs | 2 +- .../{redact/src => util/src/redact}/jsonl.rs | 4 +-- .../src/lib.rs => util/src/redact/mod.rs} | 0 .../src/lib.rs => util/src/terminal.rs} | 0 23 files changed, 37 insertions(+), 50 deletions(-) delete mode 100644 crates/terminal/Cargo.toml rename crates/{redact => util}/Cargo.toml (77%) rename crates/{redact => util}/build.rs (100%) rename crates/{redact => util}/data/gitleaks.toml (100%) create mode 100644 crates/util/src/lib.rs rename crates/{redact/src => util/src/redact}/entropy.rs (99%) rename crates/{redact/src => util/src/redact}/gitleaks.rs (99%) rename crates/{redact/src => util/src/redact}/jsonl.rs (98%) rename crates/{redact/src/lib.rs => util/src/redact/mod.rs} (100%) rename crates/{terminal/src/lib.rs => util/src/terminal.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 04f003478..bf496b7bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,10 +23,10 @@ dependencies = [ "serde_json", "tar", "tempfile", - "terminal", "thiserror 2.0.18", "tokio", "tokio-util", + "util", "uuid", ] @@ -210,18 +210,17 @@ dependencies = [ "nom", "predicates", "rand 0.8.5", - "redact", "scopeguard", "serde", "serde_json", "tempfile", - "terminal", "thiserror 2.0.18", "tokio", "tokio-stream", "tokio-util", "toml", "tower", + "util", "uuid", ] @@ -2295,17 +2294,6 @@ dependencies = [ "getrandom 0.3.4", ] -[[package]] -name = "redact" -version = "0.1.0" -dependencies = [ - "aho-corasick", - "regex", - "serde", - "serde_json", - "toml", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -2996,10 +2984,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "terminal" -version = "0.1.0" - [[package]] name = "termtree" version = "0.5.1" @@ -3407,6 +3391,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "util" +version = "0.1.0" +dependencies = [ + "aho-corasick", + "regex", + "serde", + "serde_json", + "toml", +] + [[package]] name = "uuid" version = "1.21.0" diff --git a/crates/agent/Cargo.toml b/crates/agent/Cargo.toml index 69a3743f8..dc7d50dfe 100644 --- a/crates/agent/Cargo.toml +++ b/crates/agent/Cargo.toml @@ -26,7 +26,7 @@ clap.workspace = true anyhow.workspace = true dotenvy.workspace = true llm = { path = "../llm" } -terminal = { path = "../terminal" } +util = { path = "../util" } thiserror.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/agent/src/cli.rs b/crates/agent/src/cli.rs index c0ab22e53..a54fbf6b0 100644 --- a/crates/agent/src/cli.rs +++ b/crates/agent/src/cli.rs @@ -8,7 +8,7 @@ use llm::client::Client; use std::io::{IsTerminal, Write}; use std::path::PathBuf; use std::sync::{Arc, Mutex}; -use terminal::Styles; +use util::terminal::Styles; /// Minimal CLI for the agent agentic loop. #[derive(Parser)] diff --git a/crates/attractor/Cargo.toml b/crates/attractor/Cargo.toml index 853ed9ca9..cba0fd369 100644 --- a/crates/attractor/Cargo.toml +++ b/crates/attractor/Cargo.toml @@ -26,9 +26,8 @@ clap.workspace = true anyhow.workspace = true dotenvy.workspace = true agent = { path = "../agent" } -terminal = { path = "../terminal" } +util = { path = "../util" } llm = { path = "../llm" } -redact = { path = "../redact" } thiserror.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/crates/attractor/src/cli/backend.rs b/crates/attractor/src/cli/backend.rs index c89fa2d52..6e5f68b40 100644 --- a/crates/attractor/src/cli/backend.rs +++ b/crates/attractor/src/cli/backend.rs @@ -9,7 +9,7 @@ use agent::{ subagent::{SessionFactory, SubAgentManager}, }; use llm::client::Client; -use terminal::Styles; +use util::terminal::Styles; use crate::context::Context; use crate::error::AttractorError; diff --git a/crates/attractor/src/cli/mod.rs b/crates/attractor/src/cli/mod.rs index ecf0a594f..6c0c7d984 100644 --- a/crates/attractor/src/cli/mod.rs +++ b/crates/attractor/src/cli/mod.rs @@ -11,7 +11,7 @@ use clap::{Args, Parser, Subcommand, ValueEnum}; use std::fmt; use std::path::PathBuf; use std::str::FromStr; -use terminal::Styles; +use util::terminal::Styles; use agent::AgentEvent; use crate::event::PipelineEvent; diff --git a/crates/attractor/src/cli/run.rs b/crates/attractor/src/cli/run.rs index 59695c8cc..c372c1412 100644 --- a/crates/attractor/src/cli/run.rs +++ b/crates/attractor/src/cli/run.rs @@ -5,7 +5,7 @@ use std::time::Instant; use agent::{DockerConfig, DockerExecutionEnvironment, ExecutionEnvironment, LocalExecutionEnvironment}; use anyhow::bail; use chrono::{Local, Utc}; -use terminal::Styles; +use util::terminal::Styles; use crate::checkpoint::Checkpoint; use crate::engine::{PipelineEngine, RunConfig}; @@ -156,7 +156,7 @@ pub async fn run_command(args: RunArgs, styles: &'static Styles) -> anyhow::Resu }); // Append to progress.ndjson if let Ok(line) = serde_json::to_string(&envelope) { - let line = redact::redact_jsonl_line(&line); + let line = util::redact::redact_jsonl_line(&line); use std::io::Write; if let Ok(mut f) = std::fs::OpenOptions::new() .create(true) @@ -168,7 +168,7 @@ pub async fn run_command(args: RunArgs, styles: &'static Styles) -> anyhow::Resu } // Overwrite live.json if let Ok(pretty) = serde_json::to_string_pretty(&envelope) { - let pretty = redact::redact_jsonl_line(&pretty); + let pretty = util::redact::redact_jsonl_line(&pretty); let _ = std::fs::write(&live_path, pretty); } }); @@ -526,7 +526,7 @@ mod tests { } }); let compact = serde_json::to_string(&envelope).unwrap(); - let redacted = redact::redact_jsonl_line(&compact); + let redacted = util::redact::redact_jsonl_line(&compact); assert!(!redacted.contains("AKIAYRWQG5EJLPZLBYNP")); assert!(redacted.contains("REDACTED")); @@ -547,7 +547,7 @@ mod tests { } }); let pretty = serde_json::to_string_pretty(&envelope).unwrap(); - let redacted = redact::redact_jsonl_line(&pretty); + let redacted = util::redact::redact_jsonl_line(&pretty); assert!(!redacted.contains("AKIAYRWQG5EJLPZLBYNP")); assert!(redacted.contains("REDACTED")); diff --git a/crates/attractor/src/cli/serve.rs b/crates/attractor/src/cli/serve.rs index ca267e04f..930473ae8 100644 --- a/crates/attractor/src/cli/serve.rs +++ b/crates/attractor/src/cli/serve.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use terminal::Styles; +use util::terminal::Styles; use tokio::net::TcpListener; use crate::cli::backend::AgentBackend; diff --git a/crates/attractor/src/cli/validate.rs b/crates/attractor/src/cli/validate.rs index 49b9f51bb..ba2e3e4d6 100644 --- a/crates/attractor/src/cli/validate.rs +++ b/crates/attractor/src/cli/validate.rs @@ -1,5 +1,5 @@ use anyhow::bail; -use terminal::Styles; +use util::terminal::Styles; use crate::pipeline::PipelineBuilder; use crate::validation::Severity; diff --git a/crates/attractor/src/interviewer/console.rs b/crates/attractor/src/interviewer/console.rs index 5e66a02fd..cd7000ab1 100644 --- a/crates/attractor/src/interviewer/console.rs +++ b/crates/attractor/src/interviewer/console.rs @@ -2,7 +2,7 @@ use std::io::IsTerminal; use async_trait::async_trait; use dialoguer::console::Term; -use terminal::Styles; +use util::terminal::Styles; use tokio::io::{AsyncBufReadExt, BufReader}; use super::{Answer, AnswerValue, Interviewer, Question, QuestionType}; diff --git a/crates/attractor/src/main.rs b/crates/attractor/src/main.rs index 41c192071..c97bbac8a 100644 --- a/crates/attractor/src/main.rs +++ b/crates/attractor/src/main.rs @@ -1,5 +1,5 @@ use clap::Parser; -use terminal::Styles; +use util::terminal::Styles; #[tokio::main] async fn main() { diff --git a/crates/attractor/src/server.rs b/crates/attractor/src/server.rs index b734c8b39..67842e33c 100644 --- a/crates/attractor/src/server.rs +++ b/crates/attractor/src/server.rs @@ -371,7 +371,7 @@ async fn get_events( let stream = BroadcastStream::new(rx).filter_map(|result| match result { Ok(event) => { let data = serde_json::to_string(&event).unwrap_or_default(); - let data = redact::redact_jsonl_line(&data); + let data = util::redact::redact_jsonl_line(&data); Some(Ok::( Event::default().data(data), )) diff --git a/crates/attractor/tests/integration.rs b/crates/attractor/tests/integration.rs index 22313cecd..242ce7ef3 100644 --- a/crates/attractor/tests/integration.rs +++ b/crates/attractor/tests/integration.rs @@ -27,7 +27,7 @@ use attractor::transform::{StylesheetApplicationTransform, Transform, VariableEx use attractor::cli::backend::AgentBackend; use attractor::handler::default_registry; use attractor::validation::{validate, validate_or_raise, Severity}; -use terminal::Styles; +use util::terminal::Styles; fn local_env() -> Arc { Arc::new(agent::LocalExecutionEnvironment::new( diff --git a/crates/terminal/Cargo.toml b/crates/terminal/Cargo.toml deleted file mode 100644 index 012528864..000000000 --- a/crates/terminal/Cargo.toml +++ /dev/null @@ -1,9 +0,0 @@ -[package] -name = "terminal" -edition.workspace = true -version.workspace = true -license.workspace = true -description = "Shared ANSI terminal styling for CLI binaries" - -[lib] -doctest = false diff --git a/crates/redact/Cargo.toml b/crates/util/Cargo.toml similarity index 77% rename from crates/redact/Cargo.toml rename to crates/util/Cargo.toml index cf9a254c7..fc462b31b 100644 --- a/crates/redact/Cargo.toml +++ b/crates/util/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "redact" +name = "util" edition.workspace = true version.workspace = true license.workspace = true -description = "Secret detection and redaction for log output" +description = "Shared utilities: secret redaction and terminal styling" [lib] doctest = false diff --git a/crates/redact/build.rs b/crates/util/build.rs similarity index 100% rename from crates/redact/build.rs rename to crates/util/build.rs diff --git a/crates/redact/data/gitleaks.toml b/crates/util/data/gitleaks.toml similarity index 100% rename from crates/redact/data/gitleaks.toml rename to crates/util/data/gitleaks.toml diff --git a/crates/util/src/lib.rs b/crates/util/src/lib.rs new file mode 100644 index 000000000..b36d3c5a1 --- /dev/null +++ b/crates/util/src/lib.rs @@ -0,0 +1,2 @@ +pub mod redact; +pub mod terminal; diff --git a/crates/redact/src/entropy.rs b/crates/util/src/redact/entropy.rs similarity index 99% rename from crates/redact/src/entropy.rs rename to crates/util/src/redact/entropy.rs index fe37fb957..4aa03fd60 100644 --- a/crates/redact/src/entropy.rs +++ b/crates/util/src/redact/entropy.rs @@ -1,4 +1,4 @@ -use crate::Region; +use super::Region; use regex::Regex; use std::sync::LazyLock; diff --git a/crates/redact/src/gitleaks.rs b/crates/util/src/redact/gitleaks.rs similarity index 99% rename from crates/redact/src/gitleaks.rs rename to crates/util/src/redact/gitleaks.rs index cf5d7a2da..5bbd77913 100644 --- a/crates/redact/src/gitleaks.rs +++ b/crates/util/src/redact/gitleaks.rs @@ -1,4 +1,4 @@ -use crate::Region; +use super::Region; use aho_corasick::AhoCorasick; use regex::Regex; use std::sync::{LazyLock, OnceLock}; diff --git a/crates/redact/src/jsonl.rs b/crates/util/src/redact/jsonl.rs similarity index 98% rename from crates/redact/src/jsonl.rs rename to crates/util/src/redact/jsonl.rs index ed2ced9e1..8fbd19274 100644 --- a/crates/redact/src/jsonl.rs +++ b/crates/util/src/redact/jsonl.rs @@ -58,7 +58,7 @@ fn collect_replacements(v: &Value) -> Vec<(String, String)> { } } Value::String(s) => { - let redacted = crate::redact_string(s); + let redacted = super::redact_string(s); if redacted != *s && seen.insert(s.clone()) { repls.push((s.clone(), redacted)); } @@ -91,7 +91,7 @@ pub fn redact_jsonl_line(line: &str) -> String { let parsed: Value = match serde_json::from_str(trimmed) { Ok(v) => v, - Err(_) => return crate::redact_string(line), + Err(_) => return super::redact_string(line), }; let repls = collect_replacements(&parsed); diff --git a/crates/redact/src/lib.rs b/crates/util/src/redact/mod.rs similarity index 100% rename from crates/redact/src/lib.rs rename to crates/util/src/redact/mod.rs diff --git a/crates/terminal/src/lib.rs b/crates/util/src/terminal.rs similarity index 100% rename from crates/terminal/src/lib.rs rename to crates/util/src/terminal.rs