feat: Implement UI/UX enhancements#20
Conversation
Co-authored-by: MnemOnicE <170563909+MnemOnicE@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
|
Warning Review limit reached
More reviews will be available in 45 minutes. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR enhances the terminal dashboard with command mastery tracking and category badge formatting. A new ChangesStats & Mastery Dashboard with Badge Formatting
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces a 'View Stats & Mastery' feature to the dashboard, allowing users to view their command mastery with colored progress bars. It also adds category color-coding and badges across several dashboard views. The review feedback highlights several robustness improvements, including defensive handling of non-string or null category values, safe parsing of mastery scores to prevent type errors during sorting, and fixing an ANSI color reset issue in the category header.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| # Sort history by mastery level (score) descending, then by name | ||
| sorted_history = sorted(session_history.items(), key=lambda x: (-x[1], x[0])) | ||
|
|
||
| print(f"\n{CYAN}{BOLD}Command Mastery:{RESET}") | ||
| for cmd, score in sorted_history: | ||
| # Mastery goes up to 5 | ||
| score = min(5, max(0, score)) | ||
| filled = "█" * score | ||
| empty = "░" * (5 - score) | ||
| bar = f"{filled}{empty}" |
There was a problem hiding this comment.
If session_history contains non-integer values (e.g., if the history file was modified or corrupted), sorting with key=lambda x: (-x[1], x[0]) will raise a TypeError due to the unary negation operator - on a non-numeric type. Additionally, multiplying strings by a non-integer score will raise a TypeError. We should safely parse the score to an integer.
# Sort history by mastery level (score) descending, then by name
def get_sort_key(item):
cmd, score = item
try:
return -int(score), cmd
except (TypeError, ValueError):
return 0, cmd
sorted_history = sorted(session_history.items(), key=get_sort_key)
print(f'\n{CYAN}{BOLD}Command Mastery:{RESET}')
for cmd, raw_score in sorted_history:
try:
score = int(raw_score)
except (TypeError, ValueError):
score = 0
# Mastery goes up to 5
score = min(5, max(0, score))
filled = '█' * score
empty = '░' * (5 - score)
bar = f'{filled}{empty}'| selected_cat = categories[idx] | ||
| clear_screen() | ||
| print(f"{YELLOW}--- {selected_cat} Commands ---{RESET}\n") | ||
| print(f"{YELLOW}--- {format_badge(selected_cat)} Commands ---{RESET}\n") |
There was a problem hiding this comment.
The format_badge function ends with a {RESET} ANSI escape sequence. This will reset the terminal color formatting, causing the subsequent text ' Commands ---' to lose its {YELLOW} color and render in the default terminal color. To maintain the yellow color for the entire header, re-apply {YELLOW} immediately after the badge.
| print(f"{YELLOW}--- {format_badge(selected_cat)} Commands ---{RESET}\n") | |
| print(f'{YELLOW}--- {format_badge(selected_cat)}{YELLOW} Commands ---{RESET}\n') |
| def get_category_color(category): | ||
| cat_lower = category.lower() |
There was a problem hiding this comment.
| def format_badge(category): | ||
| color = get_category_color(category) | ||
| return f"[{color}{category}{RESET}]" |
There was a problem hiding this comment.
If category is None, format_badge will display [None]. We should handle None or empty values by defaulting to a fallback string like 'Custom'.
| def format_badge(category): | |
| color = get_category_color(category) | |
| return f"[{color}{category}{RESET}]" | |
| def format_badge(category): | |
| category_str = str(category) if category else 'Custom' | |
| color = get_category_color(category_str) | |
| return f'[{color}{category_str}{RESET}]' |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@commando/ui/dashboard.py`:
- Around line 85-100: In the for-loop over sorted_history in
commando/ui/dashboard.py, avoid reusing the loop variable score for the clamped
value: introduce a new name like display_score (or clamped_score) for the result
of min(5, max(0, score)) and use display_score for building the bar and color
logic; also replace the chained elifs that set bar_color with independent if
statements (i.e., if display_score >= 4: set GREEN; if display_score >= 2: set
YELLOW; if display_score < 2: set RED) to match the early-return style used
elsewhere (refer to the loop that constructs bar and the variables
filled/empty/bar for locating the code).
- Around line 34-35: The "Recent" list uses session_history.keys() which only
reflects insertion order, not last-activity order; update the code that
records/updates an entry in session_history so it moves the key to the end on
each use (e.g., when updating a command's score/populate, either pop and
reassign session_history[cmd] = value or switch session_history to an
OrderedDict and call move_to_end(cmd)). Ensure this change affects the same
mapping referenced by the recent variable so that recent =
list(session_history.keys())[-5:] shows truly most-recently-used entries.
In `@commando/utils/io.py`:
- Around line 86-99: The get_category_color function currently uses an elif
cascade even though every branch returns; refactor it to use independent if
statements instead of elif so each condition checks and returns immediately
(e.g., in get_category_color replace the elifs with plain ifs while keeping the
same order and returns for the CYAN, MAGENTA, RED, GREEN, YELLOW cases and the
final return BOLD); ensure you still call category.lower() once and preserve the
same constants (CYAN, MAGENTA, RED, GREEN, YELLOW, BOLD) and behavior.
🪄 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 Plus
Run ID: c97c396d-da53-42a9-8ff3-c2e3b4e6a813
📒 Files selected for processing (2)
commando/ui/dashboard.pycommando/utils/io.py
📜 Review details
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{py,toml,md,txt,yaml,yml,json}
📄 CodeRabbit inference engine (AGENTS.md)
Ensure the application is identified as
cli-commando(orcommando), not legacy names like 'bashlearn'
Files:
commando/utils/io.pycommando/ui/dashboard.py
**/*.py
📄 CodeRabbit inference engine (AGENTS.md)
**/*.py: Map internal state and telemetry files (history, pending, custom) to~/.commandostate directory
When processing batches of operations, useconcurrent.futures.ThreadPoolExecutorfor I/O-bound execution with explicit throttling
Enforce a strictmax_workers=4or5when usingThreadPoolExecutorto balance UI fluidity with thermal and memory constraints on constrained hardware
Never blindly invoke[cmd, '--help']on newly discovered binaries without verification; use static analysis instead
Implement the Containment Protocol for static analysis: (1) Read first 4 bytes for ELF magic number (\x7fELF), (2) If ELF, usestringsto extract usage motifs, (3) If shebang (#!), parse as raw text, (4) Only run known-safe OS queries likewhatisorhelp
For kinetic audit mode, gracefully degrade whenptraceis denied: catch exceptions and fall back to static library analysis usingldd
Tag binaries linked tolibsslorlibcurlas[Network Mutator]during static library analysis fallback
Tag binaries with heavylibcusage as[File Reader/Writer]during static library analysis fallback
When--jsonflag is utilized, output a JSON object adhering strictly to the schema with fields:command,status,kinetic_tags,audit_method, without polluting output with human-readable UI strings
Ensure JSON headless output schema strictly adheres to:command(string),status(string),kinetic_tags(array of strings),audit_method(string)
Files:
commando/utils/io.pycommando/ui/dashboard.py
🪛 Ruff (0.15.15)
commando/utils/io.py
[warning] 90-90: Unnecessary elif after return statement
Remove unnecessary elif
(RET505)
commando/ui/dashboard.py
[warning] 87-87: for loop variable score overwritten by assignment target
(PLW2901)
🔇 Additional comments (6)
commando/utils/io.py (1)
101-103: LGTM!commando/ui/dashboard.py (5)
22-23: LGTM!
29-31: LGTM!
48-50: LGTM!
162-162: LGTM!Also applies to: 187-188, 302-302
448-450: LGTM!
|
@jules Verify each finding against current code. Fix only still-valid issues, skip the Inline comments:
In
|
I have implemented the requested changes:
|
- Refactored `get_category_color` to use independent if statements - Updated mastery display loop to use `display_score` instead of redefining `score`, and replaced elif chains with ifs - Updated `session_history` dictionary inserts to pop the key first so it's moved to the end, correctly tracking the most recently used items. Co-authored-by: MnemOnicE <170563909+MnemOnicE@users.noreply.github.com>
PR created automatically by Jules for task 778402483987234527 started by @MnemOnicE