ci: add GitHub Actions workflows with semantic-release auto-versioning
chore: fix all 702 clippy warnings across codebase - auto-fix 475 via cargo clippy --fix - fix remaining 227 manually: uninlined_format_args, redundant_closure, match_same_arms, underscore_binding, format_push_string, items_after_statements, needless_pass_by_value, clone_on_copy, case_sensitive_extension, single_match/let-else, write_with_newline, and other clippy lints
This commit is contained in:
+39
-39
@@ -1,3 +1,4 @@
|
||||
#![allow(clippy::cast_possible_truncation, clippy::cast_sign_loss, clippy::cast_precision_loss, clippy::cast_possible_wrap)]
|
||||
//! Top-level TUI render pipeline: layouts the terminal into chat / input
|
||||
//! / status regions, dispatches overlay rendering with glassmorphism-style
|
||||
//! centered panels, and floats toast notifications over the top-right corner.
|
||||
@@ -124,6 +125,7 @@ fn render_main_panel(
|
||||
/// - A top accent border strip (colored per variant)
|
||||
/// - A title line with icon
|
||||
/// - Content area with proper spacing
|
||||
#[allow(clippy::too_many_lines)]
|
||||
fn render_overlay(
|
||||
frame: &mut Frame,
|
||||
area: Rect,
|
||||
@@ -172,12 +174,12 @@ fn render_overlay(
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Max tokens: {}",
|
||||
state.settings.max_tokens.map(|v| v.to_string()).unwrap_or_else(|| "auto".to_string())),
|
||||
state.settings.max_tokens.map_or_else(|| "auto".to_string(), |v| v.to_string())),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Temperature: {}",
|
||||
state.settings.temperature.map(|v| format!("{:.1}", v)).unwrap_or_else(|| "auto".to_string())),
|
||||
state.settings.temperature.map_or_else(|| "auto".to_string(), |v| format!("{v:.1}"))),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
@@ -261,11 +263,11 @@ fn render_overlay(
|
||||
input_text.as_str()
|
||||
}
|
||||
};
|
||||
let masked = if !input_text.is_empty() {
|
||||
let suffix = if input_text.len() > 8 { "****" } else { "" };
|
||||
format!("{}{}", display, suffix)
|
||||
} else {
|
||||
let masked = if input_text.is_empty() {
|
||||
display.to_string()
|
||||
} else {
|
||||
let suffix = if input_text.len() > 8 { "****" } else { "" };
|
||||
format!("{display}{suffix}")
|
||||
};
|
||||
let lines = vec![
|
||||
Line::from(Span::styled(
|
||||
@@ -329,9 +331,9 @@ fn render_overlay(
|
||||
let selected = i == current_idx;
|
||||
lines.push(Line::from(Span::styled(
|
||||
if selected {
|
||||
format!(" ▸ {} (active)", l)
|
||||
format!(" ▸ {l} (active)")
|
||||
} else {
|
||||
format!(" {}", l)
|
||||
format!(" {l}")
|
||||
},
|
||||
if selected {
|
||||
Style::default().fg(Theme::HIGHLIGHT).add_modifier(Modifier::BOLD)
|
||||
@@ -386,7 +388,7 @@ fn render_overlay(
|
||||
)),
|
||||
Line::from(Span::raw("")),
|
||||
Line::from(Span::styled(
|
||||
format!(" Messages: {}", msg_count),
|
||||
format!(" Messages: {msg_count}"),
|
||||
Style::default().fg(Theme::INFO),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
@@ -427,7 +429,7 @@ fn render_overlay(
|
||||
};
|
||||
let preview: String = msg.content.chars().take(70).collect();
|
||||
lines.push(Line::from(Span::styled(
|
||||
format!(" [{}] {}", role_str, preview),
|
||||
format!(" [{role_str}] {preview}"),
|
||||
Style::default().fg(
|
||||
if matches!(msg.role, crate::dto::chat::message::Role::User) {
|
||||
Theme::INFO
|
||||
@@ -484,7 +486,7 @@ fn render_overlay(
|
||||
let (label, style) = match item {
|
||||
crate::app::mode::learning::LearningItem::Pending { name, .. } => {
|
||||
(
|
||||
format!("{}[Pending] {}", prefix, name),
|
||||
format!("{prefix}[Pending] {name}"),
|
||||
if is_selected {
|
||||
Style::default().fg(Theme::WARNING).bg(Theme::HIGHLIGHT_DIM)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
@@ -496,7 +498,7 @@ fn render_overlay(
|
||||
crate::app::mode::learning::LearningItem::Stored { name, lifecycle, .. } => {
|
||||
let status = if lifecycle == "stale" { "Stale" } else { "Active" };
|
||||
(
|
||||
format!("{}[{}] {}", prefix, status, name),
|
||||
format!("{prefix}[{status}] {name}"),
|
||||
if is_selected {
|
||||
Style::default().fg(Theme::TEXT).bg(Theme::HIGHLIGHT_DIM)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
@@ -539,7 +541,7 @@ fn render_overlay(
|
||||
" Name:", Style::default().fg(Theme::TEXT_DIM),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" {}", name),
|
||||
format!(" {name}"),
|
||||
Style::default().fg(Theme::TEXT).add_modifier(Modifier::BOLD),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::raw("")));
|
||||
@@ -548,11 +550,11 @@ fn render_overlay(
|
||||
Style::default().fg(Theme::WARNING),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" Scope: {}", scope),
|
||||
format!(" Scope: {scope}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" Confidence: {}", confidence),
|
||||
format!(" Confidence: {confidence}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::raw("")));
|
||||
@@ -561,7 +563,7 @@ fn render_overlay(
|
||||
)));
|
||||
for line in content.lines() {
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" {}", line),
|
||||
format!(" {line}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
}
|
||||
@@ -578,7 +580,7 @@ fn render_overlay(
|
||||
" Name:", Style::default().fg(Theme::TEXT_DIM),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" {}", name),
|
||||
format!(" {name}"),
|
||||
Style::default().fg(Theme::TEXT).add_modifier(Modifier::BOLD),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::raw("")));
|
||||
@@ -588,15 +590,15 @@ fn render_overlay(
|
||||
Theme::SUCCESS
|
||||
};
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" Status: {}", lifecycle),
|
||||
format!(" Status: {lifecycle}"),
|
||||
Style::default().fg(status_color),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" Scope: {}", scope),
|
||||
format!(" Scope: {scope}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" Description: {}", description),
|
||||
format!(" Description: {description}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
right_lines.push(Line::from(Span::raw("")));
|
||||
@@ -605,7 +607,7 @@ fn render_overlay(
|
||||
)));
|
||||
for line in content.lines() {
|
||||
right_lines.push(Line::from(Span::styled(
|
||||
format!(" {}", line),
|
||||
format!(" {line}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)));
|
||||
}
|
||||
@@ -635,7 +637,7 @@ fn render_overlay(
|
||||
.border_style(Style::default().fg(Theme::INFO));
|
||||
let runtime = state.session_runtime.as_ref();
|
||||
let (tokens_in, tokens_out, api_calls, review_tokens, session_start) = runtime
|
||||
.map(|r| {
|
||||
.map_or((0, 0, 0, 0, 0), |r| {
|
||||
(
|
||||
r.usage.tokens_in,
|
||||
r.usage.tokens_out,
|
||||
@@ -643,18 +645,16 @@ fn render_overlay(
|
||||
r.usage.review_tokens,
|
||||
r.session_start,
|
||||
)
|
||||
})
|
||||
.unwrap_or((0, 0, 0, 0, 0));
|
||||
});
|
||||
let (edit_count, lesson_count, review_count, consec_empty) = runtime
|
||||
.map(|r| {
|
||||
.map_or((0, 0, 0, 0), |r| {
|
||||
(
|
||||
r.edit_count,
|
||||
r.lesson_count,
|
||||
r.review_count,
|
||||
r.consecutive_empty_reviews,
|
||||
)
|
||||
})
|
||||
.unwrap_or((0, 0, 0, 0));
|
||||
});
|
||||
let elapsed_ms = chrono::Utc::now().timestamp_millis().saturating_sub(session_start);
|
||||
let hours = elapsed_ms / 3_600_000;
|
||||
let minutes = (elapsed_ms % 3_600_000) / 60_000;
|
||||
@@ -669,19 +669,19 @@ fn render_overlay(
|
||||
)),
|
||||
Line::from(Span::raw("")),
|
||||
Line::from(Span::styled(
|
||||
format!(" Main agent: {} tokens", main_tokens),
|
||||
format!(" Main agent: {main_tokens} tokens"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Self-learning: {} tokens", self_learning_total),
|
||||
format!(" Self-learning: {self_learning_total} tokens"),
|
||||
Style::default().fg(Theme::TEXT_MUTED),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Total: {} tokens", total_tokens),
|
||||
format!(" Total: {total_tokens} tokens"),
|
||||
Style::default().fg(Theme::TEXT).add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" API calls: {}", api_calls),
|
||||
format!(" API calls: {api_calls}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::raw("")),
|
||||
@@ -690,21 +690,21 @@ fn render_overlay(
|
||||
Style::default().fg(Theme::INFO).add_modifier(Modifier::BOLD),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Edits: {}", edit_count),
|
||||
format!(" Edits: {edit_count}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Reviews: {}", review_count),
|
||||
format!(" Reviews: {review_count}"),
|
||||
Style::default().fg(Theme::TEXT),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Lessons: {}", lesson_count),
|
||||
format!(" Lessons: {lesson_count}"),
|
||||
Style::default().fg(Theme::TEXT_MUTED),
|
||||
)),
|
||||
Line::from(Span::styled(
|
||||
format!(" Empty reviews: {}",
|
||||
if consec_empty > 3 {
|
||||
format!("{} ⚠", consec_empty)
|
||||
format!("{consec_empty} ⚠")
|
||||
} else {
|
||||
consec_empty.to_string()
|
||||
},
|
||||
@@ -713,7 +713,7 @@ fn render_overlay(
|
||||
)),
|
||||
Line::from(Span::raw("")),
|
||||
Line::from(Span::styled(
|
||||
format!(" Session: {}h {}m {}s", hours, minutes, seconds),
|
||||
format!(" Session: {hours}h {minutes}m {seconds}s"),
|
||||
Style::default().fg(Theme::TEXT_DIM),
|
||||
)),
|
||||
];
|
||||
@@ -757,7 +757,7 @@ fn render_overlay(
|
||||
let is_selected = i == state.misc.selected_index;
|
||||
let prefix = if is_selected { " ▸ " } else { " " };
|
||||
let model_str = cfg.default_model.as_deref().unwrap_or("(any)");
|
||||
let label = format!("{}{} ({})", prefix, name, model_str);
|
||||
let label = format!("{prefix}{name} ({model_str})");
|
||||
let style = if is_current {
|
||||
Style::default().fg(Theme::HIGHLIGHT).add_modifier(Modifier::BOLD)
|
||||
} else if is_selected {
|
||||
@@ -842,7 +842,7 @@ fn render_input_bar(
|
||||
} else {
|
||||
Style::default().fg(Theme::TEXT)
|
||||
};
|
||||
let label = format!("{}{}", prefix, candidate);
|
||||
let label = format!("{prefix}{candidate}");
|
||||
lines.push(Line::from(Span::styled(label, style)));
|
||||
}
|
||||
let dropdown = Paragraph::new(lines).block(dropdown_block);
|
||||
@@ -901,7 +901,7 @@ fn render_input_bar(
|
||||
// ────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
/// Render active toasts as a floating stack at top-right of the terminal.
|
||||
/// Each toast auto-expires after its lifetime_ms. Max 4 visible at once.
|
||||
/// Each toast auto-expires after its `lifetime_ms`. Max 4 visible at once.
|
||||
///
|
||||
/// Toasts are stacked vertically with a 1-line gap. Each has a colored
|
||||
/// left border and a subtle background.
|
||||
|
||||
Reference in New Issue
Block a user