Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 8 additions & 20 deletions bins/bounty-cli/src/tui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
pub mod leaderboard;
pub mod stats;
pub mod weights;

use anyhow::Result;
use crossterm::{
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::prelude::*;
use std::io;

pub fn setup_terminal() -> Result<Terminal<CrosstermBackend<io::Stdout>>> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let terminal = Terminal::new(backend)?;
terminal.set_handler(|event| {
if let Event::Key(key) = event {
if key.code == KeyCode::Char('v') && key.modifiers.contains(Modifier::CONTROL) {
// Ignore Ctrl+V when the Log Level panel is open
return;
}
}
});
Comment on lines +7 to +14
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Scope Ctrl+V suppression to /logs-panel-open state only.

At Line 7-14, the handler drops Ctrl+V unconditionally for this terminal instance. Since setup_terminal() is reused, this can suppress paste in unrelated TUI flows. Gate this with explicit panel state, or move filtering into the /logs input path.

As per coding guidelines "All user inputs must be validated before use".

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

In `@bins/bounty-cli/src/tui/mod.rs` around lines 7 - 14, The handler currently
suppresses Ctrl+V unconditionally in terminal.set_handler (checking Event::Key,
KeyCode::Char('v') and Modifier::CONTROL); restrict this suppression to only
when the Logs panel is open by adding a guard that checks the UI state (e.g.,
only return if app.is_logs_panel_open() or app.current_route == "/logs") before
ignoring the event, or alternatively remove this global filter and perform the
Ctrl+V filtering inside the `/logs` input handling codepath (where input is
validated) so other TUI flows can receive paste events.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

In ratatui version 0.29.0, does Terminalhave aset_handlermethod? If yes, what is the exact method signature and expected closure return type? In crossterm version 0.28.0, what is the correct type/constant for checking Ctrl key modifiers onKeyEvent (KeyModifiers::CONTROL vs other names)?

💡 Result:

No, the Terminal struct in ratatui 0.29.0 does not have a set_handler method. The documented methods include new, with_options, get_frame, draw, try_draw, hide_cursor, show_cursor, get_cursor_position, set_cursor_position, clear, flush, and resize, but no set_handler. Ratatui handles events via direct backend calls like crossterm::event::read, not via a handler on Terminal. In crossterm 0.28.0, the correct constant for checking Ctrl key modifiers on KeyEvent is KeyModifiers::CONTROL. It is explicitly listed as pub const CONTROL: Self in the KeyModifiers struct documentation.

Citations:


🏁 Script executed:

# Check Cargo.toml for ratatui and crossterm versions
fd Cargo.toml -x cat -n {} | head -50

# Also look for the Cargo.lock to see exact versions
fd Cargo.lock -x head -100 {}

Repository: PlatformNetwork/bounty-challenge

Length of output: 4299


🏁 Script executed:

# Check the actual file content around the mentioned lines
find . -type f -name "mod.rs" -path "*/tui/*" | head -5

Repository: PlatformNetwork/bounty-challenge

Length of output: 108


🏁 Script executed:

# Get more context about Terminal usage in the file
find . -path "*/bounty-cli/src/tui/mod.rs" -exec cat -n {} \;

Repository: PlatformNetwork/bounty-challenge

Length of output: 761


🏁 Script executed:

cat ./bins/bounty-cli/Cargo.toml

Repository: PlatformNetwork/bounty-challenge

Length of output: 701


🏁 Script executed:

head -30 ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 656


🏁 Script executed:

head -50 ./bins/bounty-cli/src/tui/mod.rs | grep -E "^use |^mod |^pub "

Repository: PlatformNetwork/bounty-challenge

Length of output: 151


🏁 Script executed:

head -50 ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 656


🏁 Script executed:

wc -l ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 111


🏁 Script executed:

sed -n '1,50p' ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 656


🏁 Script executed:

cat -n ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 761


🏁 Script executed:

find ./bins/bounty-cli/src -name "*.rs" -type f | head -10

Repository: PlatformNetwork/bounty-challenge

Length of output: 430


🏁 Script executed:

cat ./bins/bounty-cli/src/main.rs | head -100

Repository: PlatformNetwork/bounty-challenge

Length of output: 2560


🏁 Script executed:

rg "use " ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 58


🏁 Script executed:

find ./bins/bounty-cli/src/tui -name "*.rs" -exec rg "use " {} +

Repository: PlatformNetwork/bounty-challenge

Length of output: 1365


🏁 Script executed:

cat ./bins/bounty-cli/src/tui/leaderboard.rs | head -30

Repository: PlatformNetwork/bounty-challenge

Length of output: 756


🏁 Script executed:

rg "set_handler" ./bins/bounty-cli/

Repository: PlatformNetwork/bounty-challenge

Length of output: 143


🏁 Script executed:

rg "Terminal<" ./bins/bounty-cli/src/

Repository: PlatformNetwork/bounty-challenge

Length of output: 184


🏁 Script executed:

rg "Modifier" ./bins/bounty-cli/src/

Repository: PlatformNetwork/bounty-challenge

Length of output: 201


🏁 Script executed:

rg "Event" ./bins/bounty-cli/src/tui/mod.rs

Repository: PlatformNetwork/bounty-challenge

Length of output: 116


🏁 Script executed:

rg "struct Modifier|type Modifier|enum Modifier" ./bins/bounty-cli/

Repository: PlatformNetwork/bounty-challenge

Length of output: 58


🏁 Script executed:

rg "^use.*Modifier" ./bins/bounty-cli/

Repository: PlatformNetwork/bounty-challenge

Length of output: 58


Remove set_handler call — method does not exist in ratatui 0.29.0.

Terminal in ratatui 0.29.0 has no set_handler method. Events must be handled separately using crossterm::event::read() in an event loop. Additionally, Modifier and Event are not imported; if importing from crossterm, use KeyModifiers::CONTROL (not Modifier::CONTROL) for crossterm 0.28.0.

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

In `@bins/bounty-cli/src/tui/mod.rs` around lines 7 - 14, The call to
terminal.set_handler must be removed because ratatui 0.29.0 doesn't provide it;
instead handle input in your event loop by calling crossterm::event::read() and
matching on crossterm::event::Event (not the old Event used here), checking for
crossterm::event::KeyEvent with KeyCode::Char('v') and KeyModifiers::CONTROL
(replace Modifier::CONTROL), and early-return when the Log Level panel is open;
update imports to use crossterm::event::{read, Event, KeyEvent, KeyCode,
KeyModifiers} and move the conditional logic from terminal.set_handler into the
main loop where events are processed.

Ok(terminal)
Comment on lines 1 to 15
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Reintroduce terminal restore path; current removal breaks existing caller and cleanup.

bins/bounty-cli/src/tui/leaderboard.rs (Line 179) still calls super::restore_terminal(&mut terminal)?, so removing it here is a compile-break and also removes explicit raw-mode/alternate-screen cleanup API.

Proposed fix
+pub fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> Result<()> {
+    disable_raw_mode()?;
+    execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
+    terminal.show_cursor()?;
+    Ok(())
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub fn setup_terminal() -> Result<Terminal<CrosstermBackend<io::Stdout>>> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let terminal = Terminal::new(backend)?;
terminal.set_handler(|event| {
if let Event::Key(key) = event {
if key.code == KeyCode::Char('v') && key.modifiers.contains(Modifier::CONTROL) {
// Ignore Ctrl+V when the Log Level panel is open
return;
}
}
});
Ok(terminal)
pub fn setup_terminal() -> Result<Terminal<CrosstermBackend<io::Stdout>>> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen)?;
let backend = CrosstermBackend::new(stdout);
let terminal = Terminal::new(backend)?;
terminal.set_handler(|event| {
if let Event::Key(key) = event {
if key.code == KeyCode::Char('v') && key.modifiers.contains(Modifier::CONTROL) {
// Ignore Ctrl+V when the Log Level panel is open
return;
}
}
});
Ok(terminal)
}
pub fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> Result<()> {
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
Ok(())
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@bins/bounty-cli/src/tui/mod.rs` around lines 1 - 15, setup_terminal currently
enables raw mode and enters the alternate screen but the complementary restore
path was removed; reintroduce a pub fn restore_terminal(terminal: &mut
Terminal<CrosstermBackend<io::Stdout>>) -> Result<()> that reverses
setup_terminal (disable_raw_mode, execute LeaveAlternateScreen on the terminal's
stdout, restore/show the cursor and clear any input handler) so calls like
super::restore_terminal(&mut terminal)? in leaderboard.rs compile and proper
cleanup occurs; ensure the function uses the same
Terminal<CrosstermBackend<io::Stdout>> type and error Result type as
setup_terminal.

}

pub fn restore_terminal(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) -> Result<()> {
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen)?;
terminal.show_cursor()?;
Ok(())
}