ActiveTools wrapper: replace SharedActiveTools Arc<Mutex<Vec>>

New ActiveTools struct with proper methods: push, remove, abort_all,
take_finished, take_foreground, iter, len. Lives directly on AgentState,
no separate Arc<Mutex> needed.

TUI reads active tools through agent.state.try_lock(). Turn loop uses
helpers instead of manual index iteration.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-08 16:45:56 -04:00
parent 9c9618d034
commit 31a41fa042
5 changed files with 23 additions and 26 deletions

View file

@ -585,8 +585,9 @@ impl InteractScreen {
/// Draw the main (F1) screen — four-pane layout with status bar.
fn draw_main(&mut self, frame: &mut Frame, size: Rect, app: &App) {
// Main layout: content area + active tools overlay + status bar
let active_tools = app.active_tools.lock().unwrap();
let tool_lines = active_tools.len() as u16;
let st_guard = app.agent.state.try_lock().ok();
let tool_lines = st_guard.as_ref()
.map(|st| st.active_tools.len() as u16).unwrap_or(0);
let main_chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
@ -675,10 +676,10 @@ impl InteractScreen {
frame.render_widget(gutter, input_chunks[0]);
frame.render_widget(&self.textarea, input_chunks[1]);
// Draw active tools overlay
if !active_tools.is_empty() {
if let Some(ref st) = st_guard {
if !st.active_tools.is_empty() {
let tool_style = Style::default().fg(Color::Yellow).add_modifier(Modifier::DIM);
let tool_text: Vec<Line> = active_tools.iter().map(|t| {
let tool_text: Vec<Line> = st.active_tools.iter().map(|t| {
let elapsed = t.started.elapsed().as_secs();
let line = if t.detail.is_empty() {
format!(" [{}] ({}s)", t.name, elapsed)
@ -689,7 +690,7 @@ impl InteractScreen {
}).collect();
let tool_para = Paragraph::new(tool_text);
frame.render_widget(tool_para, tools_overlay_area);
}
}}
// Draw status bar with live activity indicator
let timer = if !app.activity.is_empty() {