From c77cba32f3b1aa7886d78df2197a0d57ff5dd14d Mon Sep 17 00:00:00 2001 From: Greyforge Admin Date: Tue, 19 May 2026 23:53:52 -0400 Subject: [PATCH] Add verbose diagnostics to CLI commands --- src/cortex-cli/src/agent_cmd/handlers/list.rs | 11 ++ src/cortex-cli/src/github_cmd.rs | 16 +++ src/cortex-cli/tests/verbose_output.rs | 102 ++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 src/cortex-cli/tests/verbose_output.rs diff --git a/src/cortex-cli/src/agent_cmd/handlers/list.rs b/src/cortex-cli/src/agent_cmd/handlers/list.rs index 7a27eec4c..f2398e620 100644 --- a/src/cortex-cli/src/agent_cmd/handlers/list.rs +++ b/src/cortex-cli/src/agent_cmd/handlers/list.rs @@ -9,6 +9,15 @@ use crate::agent_cmd::utils::matches_pattern; /// List agents command. pub async fn run_list(args: ListArgs) -> Result<()> { + tracing::debug!( + all = args.all, + primary = args.primary, + subagents = args.subagents, + remote = args.remote, + filter = ?args.filter, + "listing agents" + ); + // Validate mutually exclusive flags if args.primary && args.subagents { bail!( @@ -31,6 +40,7 @@ pub async fn run_list(args: ListArgs) -> Result<()> { } let agents = load_all_agents()?; + tracing::debug!(total_agents = agents.len(), "loaded agent definitions"); // Filter agents let mut filtered: Vec<_> = agents @@ -56,6 +66,7 @@ pub async fn run_list(args: ListArgs) -> Result<()> { true }) .collect(); + tracing::debug!(filtered_agents = filtered.len(), "filtered agent list"); // Sort by display_name (if present) or name for user-friendly ordering // This ensures agents are listed in the order users expect (by visible name) diff --git a/src/cortex-cli/src/github_cmd.rs b/src/cortex-cli/src/github_cmd.rs index 83763b3bd..b2d72a096 100644 --- a/src/cortex-cli/src/github_cmd.rs +++ b/src/cortex-cli/src/github_cmd.rs @@ -587,6 +587,11 @@ fn get_help_message() -> String { /// Check GitHub Actions installation status. async fn run_status(args: StatusArgs) -> Result<()> { let repo_path = args.path.unwrap_or_else(|| PathBuf::from(".")); + tracing::debug!( + path = %repo_path.display(), + json = args.json, + "checking GitHub Actions installation status" + ); let mut status = InstallationStatus::default(); @@ -601,6 +606,10 @@ async fn run_status(args: StatusArgs) -> Result<()> { if content.contains("Cortex") { status.workflow_installed = true; status.workflow_path = Some(path.clone()); + tracing::debug!( + workflow_path = %path.display(), + "found Cortex workflow" + ); // Check workflow features if content.contains("issue_comment") { @@ -623,6 +632,13 @@ async fn run_status(args: StatusArgs) -> Result<()> { // Check if we're in a git repo status.is_git_repo = repo_path.join(".git").exists(); + tracing::debug!( + is_git_repo = status.is_git_repo, + github_dir_exists = status.github_dir_exists, + workflow_installed = status.workflow_installed, + features = ?status.features, + "computed GitHub Actions installation status" + ); if args.json { let json = serde_json::to_string_pretty(&status)?; diff --git a/src/cortex-cli/tests/verbose_output.rs b/src/cortex-cli/tests/verbose_output.rs new file mode 100644 index 000000000..879214ced --- /dev/null +++ b/src/cortex-cli/tests/verbose_output.rs @@ -0,0 +1,102 @@ +use std::fs; +use std::process::Command; + +use tempfile::tempdir; + +fn combined_output(output: &std::process::Output) -> String { + format!( + "{}{}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + ) +} + +#[test] +fn verbose_agent_list_adds_diagnostics() { + let home_dir = tempdir().unwrap(); + + let normal = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args(["agent", "list"]) + .env("HOME", home_dir.path()) + .env_remove("CORTEX_HOME") + .output() + .unwrap(); + assert!( + normal.status.success(), + "normal agent list failed:\n{}", + combined_output(&normal) + ); + + let verbose = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args(["--verbose", "agent", "list"]) + .env("HOME", home_dir.path()) + .env_remove("CORTEX_HOME") + .output() + .unwrap(); + assert!( + verbose.status.success(), + "verbose agent list failed:\n{}", + combined_output(&verbose) + ); + + let normal_output = combined_output(&normal); + let verbose_output = combined_output(&verbose); + assert_ne!(normal_output, verbose_output); + assert!(verbose_output.contains("listing agents")); +} + +#[test] +fn verbose_github_status_adds_diagnostics() { + let repo = tempdir().unwrap(); + fs::create_dir(repo.path().join(".git")).unwrap(); + let workflows_dir = repo.path().join(".github").join("workflows"); + fs::create_dir_all(&workflows_dir).unwrap(); + fs::write( + workflows_dir.join("Cortex.yml"), + r#"# Cortex CI/CD Automation +# Generated by: cortex github install + +name: Cortex + +on: + workflow_dispatch: + +jobs: + cortex: + runs-on: ubuntu-latest + steps: [] +"#, + ) + .unwrap(); + + let normal = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args(["github", "status", "--path", repo.path().to_str().unwrap()]) + .output() + .unwrap(); + assert!( + normal.status.success(), + "normal github status failed:\n{}", + combined_output(&normal) + ); + + let verbose = Command::new(env!("CARGO_BIN_EXE_Cortex")) + .args([ + "--verbose", + "github", + "status", + "--path", + repo.path().to_str().unwrap(), + ]) + .output() + .unwrap(); + assert!( + verbose.status.success(), + "verbose github status failed:\n{}", + combined_output(&verbose) + ); + + let normal_output = combined_output(&normal); + let verbose_output = combined_output(&verbose); + assert_ne!(normal_output, verbose_output); + assert!(verbose_output.contains("checking GitHub Actions installation status")); +}