Implement chat and markdown views, enhance status bar, and add workflow panel

- Added `chat.rs` for rendering chat messages with timestamps and roles.
- Introduced `markdown.rs` for rendering markdown content with styling.
- Created `status.rs` to display the application status bar with session and message counts.
- Developed `workflow.rs` to show the current workflow status, including tool calls and active jobs.
- Established a `theme.rs` for centralized color management across the UI.
- Updated `mod.rs` to include new modules and manage rendering logic.
This commit is contained in:
asepharyana
2026-07-11 13:16:10 +07:00
parent 7cb4ae6708
commit cc03bd79b6
131 changed files with 10994 additions and 0 deletions
+66
View File
@@ -0,0 +1,66 @@
use crate::app::subagent::spawn::AgentDefinition;
pub fn builtin_agents() -> Vec<AgentDefinition> {
vec![
AgentDefinition::new(
"coder".to_string(),
"coder".to_string(),
).with_system_prompt(
"You are a coding agent. Write correct, idiomatic Rust code.".to_string()
).with_allowed_tools(
vec![
"read".to_string(),
"write".to_string(),
"edit".to_string(),
"bash".to_string(),
"grep".to_string(),
"glob".to_string(),
"git_operator".to_string(),
]
).with_max_steps(25),
AgentDefinition::new(
"reviewer".to_string(),
"reviewer".to_string(),
).with_system_prompt(
"You are a code reviewer. Focus on correctness, safety, and performance.".to_string()
).with_allowed_tools(
vec![
"read".to_string(),
"grep".to_string(),
"glob".to_string(),
"recall".to_string(),
"remember".to_string(),
]
).with_max_steps(10),
AgentDefinition::new(
"researcher".to_string(),
"researcher".to_string(),
).with_system_prompt(
"You are a research agent. Search and synthesize information.".to_string()
).with_allowed_tools(
vec![
"read".to_string(),
"grep".to_string(),
"glob".to_string(),
"search".to_string(),
"web_fetch".to_string(),
]
).with_max_steps(15),
AgentDefinition::new(
"planner".to_string(),
"planner".to_string(),
).with_system_prompt(
"You are a planning agent. Break down tasks into clear steps.".to_string()
).with_allowed_tools(
vec![
"read".to_string(),
"grep".to_string(),
"glob".to_string(),
"plan".to_string(),
]
).with_max_steps(20),
]
}
+42
View File
@@ -0,0 +1,42 @@
use crate::app::subagent::spawn::AgentDefinition;
pub fn load_global_agents() -> Vec<AgentDefinition> {
let store = crate::model::store::Store::new();
let agents_dir = store.base_dir.join("agents");
if !agents_dir.exists() {
return Vec::new();
}
let mut agents = Vec::new();
if let Ok(entries) = std::fs::read_dir(&agents_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().is_some_and(|e| e == "json") {
if let Ok(content) = std::fs::read_to_string(&path) {
if let Ok(def) = serde_json::from_str::<AgentDefinition>(&content) {
agents.push(def);
}
}
}
}
}
agents
}
pub fn save_global_agent(def: &AgentDefinition) -> anyhow::Result<()> {
let store = crate::model::store::Store::new();
let agents_dir = store.base_dir.join("agents");
std::fs::create_dir_all(&agents_dir)?;
let path = agents_dir.join(format!("{}.json", def.name));
let content = serde_json::to_string_pretty(def)?;
std::fs::write(path, content)?;
Ok(())
}
pub fn remove_global_agent(name: &str) -> anyhow::Result<()> {
let store = crate::model::store::Store::new();
let path = store.base_dir.join("agents").join(format!("{}.json", name));
if path.exists() {
std::fs::remove_file(path)?;
}
Ok(())
}
+3
View File
@@ -0,0 +1,3 @@
pub mod builtin;
pub mod global;
pub mod session;
+35
View File
@@ -0,0 +1,35 @@
use std::path::Path;
use crate::app::subagent::spawn::AgentDefinition;
pub fn load_session_agents(session_dir: &Path) -> Vec<AgentDefinition> {
let agents_file = session_dir.join("agents.json");
if !agents_file.exists() {
return Vec::new();
}
match std::fs::read_to_string(&agents_file) {
Ok(content) => {
serde_json::from_str(&content).unwrap_or_default()
}
Err(_) => Vec::new(),
}
}
pub fn save_session_agents(session_dir: &Path, agents: &[AgentDefinition]) -> anyhow::Result<()> {
let agents_file = session_dir.join("agents.json");
let content = serde_json::to_string_pretty(agents)?;
std::fs::write(agents_file, content)?;
Ok(())
}
pub fn add_session_agent(session_dir: &Path, def: AgentDefinition) -> anyhow::Result<()> {
let mut agents = load_session_agents(session_dir);
agents.retain(|a| a.name != def.name);
agents.push(def);
save_session_agents(session_dir, &agents)
}
pub fn remove_session_agent(session_dir: &Path, name: &str) -> anyhow::Result<()> {
let mut agents = load_session_agents(session_dir);
agents.retain(|a| a.name != name);
save_session_agents(session_dir, &agents)
}