Skip to content

Improve status command readability - #394

Merged
yacosta738 merged 2 commits into
mainfrom
feat/status-readable-output
May 1, 2026
Merged

yacosta738 merged 2 commits into
mainfrom
feat/status-readable-output

Conversation

@yacosta738

Copy link
Copy Markdown
Contributor

Summary

  • Renders status entries, details, hints, and summaries through the shared human output formatter.
  • Splits expected/actual information into structured detail lines for easier scanning.
  • Preserves status JSON output, issue detection, and exit behavior.

Closes #386

Verification

  • cargo test commands::status_tests
  • cargo test commands::status
  • cargo test output::tests
  • cargo test
  • cargo fmt --check
  • cargo run -- status --help

@coderabbitai

coderabbitai Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Summary by CodeRabbit

Style

  • Status command output now features more structured formatting with clearer visual indicators for each status entry
  • Configuration drift, symlink information, and actual vs. expected values are displayed with enhanced detail and context
  • Overall status hints and summaries are presented more clearly and consistently

Walkthrough

The status command's human output rendering is refactored to use a shared HumanFormatter instead of hardcoded colored formatting. Status entries now produce structured multi-line output with explicit visual markers and detailed key-value information, while hints and summaries route through formatter-based helpers.

Changes

Cohort / File(s) Summary
Core Status Formatter Integration
src/commands/status.rs
Refactored from hardcoded colored formatting to HumanFormatter. Entry rendering now returns Vec<String> instead of single strings, enabling structured details for symlink-contents and conditional actual/expected fields. Added new formatter-based helpers for hints and final summaries.
Status Tests Refactor
src/commands/status_tests.rs
Added status_entry and status_issue test helpers. Updated all render_status_entry assertions to pass &plain_formatter(). Expected outputs changed from loosely-matched single-line strings to multi-line formatted results with explicit markers (✔ OK:, ✗ Drift:, ! Missing:). Added tests for render_status_hint and render_status_summary.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 With paws and care, I've carved and shaped,
The status output, neatly draped!
No more rough strings in tangled webs—
Just structured lines and flowing threads,
Where hints and summaries now align,
In formatter's blessed design! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Improve status command readability' accurately reflects the main objective of refactoring the status command output using the shared human formatter.
Description check ✅ Passed The description is well-related to the changeset, clearly explaining the formatter integration, structured output improvements, and verification steps.
Linked Issues check ✅ Passed All key requirements from #386 are met: human formatter integration, visual distinction via markers (✔/✗/!), structured expected/actual details, consistent hints, clear summaries, JSON preservation, and exit behavior unchanged.
Out of Scope Changes check ✅ Passed All changes are within scope of #386: formatter application, output hierarchy improvements, and test updates. No status detection logic, new checks, or interactive UI changes are present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/status-readable-output

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@sentry

sentry Bot commented May 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.67442% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/commands/status.rs 97.67% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/status_tests.rs`:
- Around line 683-703: The test is currently constructing a ChildNotSymlink
issue with populated actual/expected fields that production never sets; update
the fixture to match the real issue shape by calling status_issue for
StatusIssueKind::ChildNotSymlink with None for both expected and actual (i.e.,
change the Some("symlink"), Some("file") args to None, None) and adjust
assertions accordingly to not require "  actual:" or "  expected:" lines—still
assert the "✗ Drift:" and "exists but is not a symlink" via render_status_entry
and plain_formatter.

In `@src/commands/status.rs`:
- Around line 338-364: The MissingExpectedSource branch for StatusIssueKind only
prints entry.destination for "symlink-contents" and never surfaces the missing
source path stored in issue.path; update that branch to include the missing
source directory (use issue.path or issue.path.as_deref()) in the formatted
message so users see the actual missing source, keeping the same
formatter.format_label usage and consistent with how issue.actual is used
elsewhere (references: StatusIssueKind::MissingExpectedSource,
entry.destination, issue.actual, issue.path, formatter.format_label, and
issue_detail_lines).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: fb1958c6-d00f-4409-b55c-0981ea11d504

📥 Commits

Reviewing files that changed from the base of the PR and between 51587ce and 8d9909e.

📒 Files selected for processing (2)
  • src/commands/status.rs
  • src/commands/status_tests.rs

Comment on lines +683 to +703
fn test_render_child_not_symlink_shows_actual_detail() {
let entry = status_entry(
"/tmp/.claude/commands",
"symlink-contents",
crate::commands::status::DestinationKind::Directory,
None,
Some("/tmp/.agents/commands"),
vec![status_issue(
crate::commands::status::StatusIssueKind::ChildNotSymlink,
"/tmp/.claude/commands/review.md",
Some("symlink"),
Some("file"),
)],
);

let rendered = render_status_entry(&entry, &plain_formatter());

assert!(rendered[0].contains("✗ Drift:"));
assert!(rendered[0].contains("exists but is not a symlink"));
assert!(rendered.iter().any(|line| line == " actual: file"));
assert!(rendered.iter().any(|line| line == " expected: symlink"));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Make this ChildNotSymlink test use the real issue shape.

collect_status_entries() does not currently populate actual: Some("file") or expected: Some("symlink") for ChildNotSymlink, so this fixture is asserting a branch that production never reaches. As written, the test can stay green while shipped output still omits the actual: detail for this case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/status_tests.rs` around lines 683 - 703, The test is currently
constructing a ChildNotSymlink issue with populated actual/expected fields that
production never sets; update the fixture to match the real issue shape by
calling status_issue for StatusIssueKind::ChildNotSymlink with None for both
expected and actual (i.e., change the Some("symlink"), Some("file") args to
None, None) and adjust assertions accordingly to not require "  actual:" or " 
expected:" lines—still assert the "✗ Drift:" and "exists but is not a symlink"
via render_status_entry and plain_formatter.

Comment thread src/commands/status.rs
Comment on lines 338 to +364
StatusIssueKind::MissingExpectedSource => {
if entry.sync_type.as_str() == "symlink-contents" {
format!(
"{} Missing source container directory: {}",
"!".yellow(),
vec![format!(
"{}: {}",
formatter.format_label(
"!",
"Missing source container directory",
LabelKind::Warning
),
entry.destination
)
)]
} else {
format!(
"{} Link points to missing source: {}",
"!".yellow(),
vec![format!(
"{}: {}",
formatter.format_label(
"!",
"Link points to missing source",
LabelKind::Warning
),
issue.actual.as_deref().unwrap_or(&entry.destination)
)
)]
}
}
};

lines.extend(issue_detail_lines(issue, formatter));
lines

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Expose the missing source path for symlink-contents source-missing errors.

This branch only prints entry.destination, and the follow-up detail lines only surface actual, so the missing source directory stored in issue.path never appears in human output. That makes this case much less actionable than the other structured issue renderers.

Suggested fix
         StatusIssueKind::MissingExpectedSource => {
             if entry.sync_type.as_str() == "symlink-contents" {
-                vec![format!(
-                    "{}: {}",
-                    formatter.format_label(
-                        "!",
-                        "Missing source container directory",
-                        LabelKind::Warning
-                    ),
-                    entry.destination
-                )]
+                vec![
+                    format!(
+                        "{}: {}",
+                        formatter.format_label(
+                            "!",
+                            "Missing source container directory",
+                            LabelKind::Warning
+                        ),
+                        entry.destination
+                    ),
+                    format!(
+                        "  {}",
+                        formatter.format_key_value("source", &issue.path)
+                    ),
+                ]
             } else {
                 vec![format!(
                     "{}: {}",
                     formatter.format_label(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/status.rs` around lines 338 - 364, The MissingExpectedSource
branch for StatusIssueKind only prints entry.destination for "symlink-contents"
and never surfaces the missing source path stored in issue.path; update that
branch to include the missing source directory (use issue.path or
issue.path.as_deref()) in the formatted message so users see the actual missing
source, keeping the same formatter.format_label usage and consistent with how
issue.actual is used elsewhere (references:
StatusIssueKind::MissingExpectedSource, entry.destination, issue.actual,
issue.path, formatter.format_label, and issue_detail_lines).

@sonarqubecloud

sonarqubecloud Bot commented May 1, 2026

Copy link
Copy Markdown

@yacosta738
yacosta738 merged commit e31dd38 into main May 1, 2026
24 checks passed
@yacosta738
yacosta738 deleted the feat/status-readable-output branch May 1, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve status command readability with structured human output

1 participant