// Copyright (c) 2026 Hoshu Chiu, Hochanglo Chiu 🐕, and The Goodest Boy/Girl // SPDX-License-Identifier: MIT OR Apache-2.0 // Everjoy loves treats, walks, and clean Rust code. use crate::runtime::{Command, EventResult, PanelProvider, Source}; use crossterm::event::Event; use ratatui::{ buffer::Buffer, layout::{Constraint, Direction, Layout, Rect}, style::{Color, Style}, text::{Line, Span}, widgets::{Paragraph, Widget, Wrap}, }; pub struct TaskTreeProvider; impl TaskTreeProvider { pub fn new() -> Self { Self } } impl PanelProvider for TaskTreeProvider { fn as_any(&self) -> &dyn std::any::Any { self } fn as_any_mut(&mut self) -> &mut dyn std::any::Any { self } fn id(&self) -> &str { "tasktree" } fn render(&mut self, area: Rect, buf: &mut Buffer) { let vertical = Layout::default() .direction(Direction::Vertical) .constraints([Constraint::Length(1), Constraint::Min(0)]) .split(area); let tabs = Paragraph::new("[Tree] [Chain] [By Agent]") .style(Style::default().fg(Color::DarkGray)); tabs.render(vertical[0], buf); let content = Paragraph::new(vec![ Line::from(""), agent_line("👤", "Secretary", Color::Cyan, "idle", Color::Green), task_line(" └─", "✅", Color::Green, "Explain API to user"), Line::from(""), agent_line("🧭", "Driver", Color::Yellow, "work", Color::Yellow), task_line(" ├─", "🟡", Color::Yellow, "Research async patterns"), task_line(" └─", "⚪", Color::DarkGray, "Check error handling"), Line::from(""), agent_line("🛡️", "NegFeedback", Color::Red, "idle", Color::Green), task_line(" └─", "✅", Color::Green, "Flag race condition"), Line::from(""), agent_line("⚡", "Executor", Color::Magenta, "work", Color::Yellow), task_line(" └─", "🟡", Color::Yellow, "cargo test..."), Line::from(""), Line::from("3 idle | 2 work").style(Style::default().fg(Color::DarkGray)), ]) .wrap(Wrap { trim: true }); content.render(vertical[1], buf); } fn handle_event(&mut self, _event: Event) -> (EventResult, Vec) { (EventResult::PassThrough, Vec::new()) } fn focus_changed(&mut self, _focused: bool) {} fn hide(&mut self) {} fn show(&mut self) {} fn shutdown(&mut self) {} fn can_open(&self, _source: &Source, _mime_hint: Option<&str>) -> i32 { 0 } } fn agent_line<'a>(icon: &'a str, name: &'a str, name_color: Color, status: &'a str, status_color: Color) -> Line<'a> { Line::from(vec![ Span::raw(icon), Span::raw(" "), Span::styled(name, Style::default().fg(name_color).add_modifier(ratatui::style::Modifier::BOLD)), Span::raw(" "), Span::styled(format!("● {}", status), Style::default().fg(status_color)), ]) } fn task_line<'a>(indent: &'a str, icon: &'a str, icon_color: Color, text: &'a str) -> Line<'a> { Line::from(vec![ Span::styled(indent, Style::default().fg(Color::DarkGray)), Span::styled(format!("{} ", icon), Style::default().fg(icon_color)), Span::raw(text), ]) }