Repository navigation
Add TUI palette, agent awareness, and evidence loop - #15
Conversation
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Free Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces the tree-ring evidence command to support recording evidence-backed outcomes, adds automated agent-awareness file generation (AGENTS.md, SKILL.md, CLI.md) during initialization, and refactors the TUI styling to use a centralized theme module. The review feedback highlights opportunities to optimize the TUI rendering loop by passing references instead of cloning strings (such as app.status, memory.id, and app.command_buffer) on every frame. Additionally, it is recommended to update the shell_path helper to properly escape paths containing spaces to ensure generated commands remain valid.
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.
| fn shell_path(path: &Path) -> String { | ||
| path.display().to_string() | ||
| } |
There was a problem hiding this comment.
The shell_path function in agent_awareness.rs does not handle paths containing spaces, unlike the implementation in welcome.rs. If the project path contains spaces, the generated shell commands in AGENTS.md will be malformed and broken when copy-pasted or executed by an agent. Update this function to wrap paths containing spaces in single quotes.
fn shell_path(path: &Path) -> String {
let value = path.display().to_string();
if value.contains(' ') {
format!("'{value}'")
} else {
value
}
}| Span::raw(format!(" private:{}", app.dashboard.sensitive_total)), | ||
| Span::raw(format!(" status: {}", app.status)), | ||
| Span::styled(" status: ", theme::dim()), | ||
| Span::raw(app.status.clone()), |
There was a problem hiding this comment.
In Ratatui, the render function is called on every tick/frame. Cloning app.status (which is a String) on every render pass introduces unnecessary allocations. Since Span::raw accepts &str or &String (via Into<Cow<'a, str>>), you can pass a reference directly to avoid the clone.
| Span::raw(app.status.clone()), | |
| Span::raw(&app.status), |
| lines.push(Line::from(vec![ | ||
| Span::styled("id ", Style::default().fg(Color::DarkGray)), | ||
| Span::styled("id ", theme::dim()), | ||
| Span::raw(memory.id.clone()), | ||
| ])); | ||
| lines.push(Line::from(vec![ | ||
| Span::styled("ring ", Style::default().fg(Color::DarkGray)), | ||
| Span::raw(memory.ring.clone()), | ||
| Span::styled(" type ", Style::default().fg(Color::DarkGray)), | ||
| Span::styled("ring ", theme::dim()), | ||
| Span::styled( | ||
| memory.ring.clone(), | ||
| Style::default() | ||
| .fg(theme::ring_color(&memory.ring, 0.0)) | ||
| .add_modifier(Modifier::BOLD), | ||
| ), | ||
| Span::styled(" type ", theme::dim()), | ||
| Span::raw(memory.event_type.clone()), | ||
| ])); |
There was a problem hiding this comment.
Similar to the header rendering, cloning memory.id, memory.ring, and memory.event_type inside render_detail introduces unnecessary allocations on every render pass. You can pass references instead to improve performance and reduce memory churn.
| lines.push(Line::from(vec![ | |
| Span::styled("id ", Style::default().fg(Color::DarkGray)), | |
| Span::styled("id ", theme::dim()), | |
| Span::raw(memory.id.clone()), | |
| ])); | |
| lines.push(Line::from(vec![ | |
| Span::styled("ring ", Style::default().fg(Color::DarkGray)), | |
| Span::raw(memory.ring.clone()), | |
| Span::styled(" type ", Style::default().fg(Color::DarkGray)), | |
| Span::styled("ring ", theme::dim()), | |
| Span::styled( | |
| memory.ring.clone(), | |
| Style::default() | |
| .fg(theme::ring_color(&memory.ring, 0.0)) | |
| .add_modifier(Modifier::BOLD), | |
| ), | |
| Span::styled(" type ", theme::dim()), | |
| Span::raw(memory.event_type.clone()), | |
| ])); | |
| lines.push(Line::from(vec![ | |
| Span::styled("id ", theme::dim()), | |
| Span::raw(&memory.id), | |
| ])); | |
| lines.push(Line::from(vec![ | |
| Span::styled("ring ", theme::dim()), | |
| Span::styled( | |
| &memory.ring, | |
| Style::default() | |
| .fg(theme::ring_color(&memory.ring, 0.0)) | |
| .add_modifier(Modifier::BOLD), | |
| ), | |
| Span::styled(" type ", theme::dim()), | |
| Span::raw(&memory.event_type), | |
| ])); |
| if app.mode == AppMode::Command { | ||
| lines.push(Line::from("")); | ||
| lines.push(Line::from(vec![ | ||
| Span::styled("/", Style::default().fg(Color::LightYellow)), | ||
| Span::styled("/", theme::brand()), | ||
| Span::raw(app.command_buffer.clone()), | ||
| ])); | ||
| } else if app.mode == AppMode::Search { | ||
| lines.push(Line::from("")); | ||
| lines.push(Line::from(vec![ | ||
| Span::styled("search ", Style::default().fg(Color::LightYellow)), | ||
| Span::styled("search ", theme::brand()), | ||
| Span::raw(app.search_query.clone()), | ||
| ])); | ||
| } |
There was a problem hiding this comment.
Avoid cloning app.command_buffer and app.search_query during render passes. Passing references is sufficient and avoids unnecessary allocations.
| if app.mode == AppMode::Command { | |
| lines.push(Line::from("")); | |
| lines.push(Line::from(vec![ | |
| Span::styled("/", Style::default().fg(Color::LightYellow)), | |
| Span::styled("/", theme::brand()), | |
| Span::raw(app.command_buffer.clone()), | |
| ])); | |
| } else if app.mode == AppMode::Search { | |
| lines.push(Line::from("")); | |
| lines.push(Line::from(vec![ | |
| Span::styled("search ", Style::default().fg(Color::LightYellow)), | |
| Span::styled("search ", theme::brand()), | |
| Span::raw(app.search_query.clone()), | |
| ])); | |
| } | |
| if app.mode == AppMode::Command { | |
| lines.push(Line::from("")); | |
| lines.push(Line::from(vec![ | |
| Span::styled("/", theme::brand()), | |
| Span::raw(&app.command_buffer), | |
| ])); | |
| } else if app.mode == AppMode::Search { | |
| lines.push(Line::from("")); | |
| lines.push(Line::from(vec![ | |
| Span::styled("search ", theme::brand()), | |
| Span::raw(&app.search_query), | |
| ])); | |
| } |
Summary:
.tree-ring/AGENTS.md,.tree-ring/SKILL.md, and.tree-ring/CLI.md.tree-ring evidencefor the Revolve-inspired evidence loop: promoted -> heartwood, rejected -> scar, deferred -> seed, observed -> outer.Verification:
Notes: