feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
//! Change the working directory for subsequent commands.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct Cd;
|
||||
|
||||
impl Tool for Cd {
|
||||
fn name(&self) -> &'static str {
|
||||
"cd"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Set the working directory for subsequent tool calls"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"directory": {
|
||||
"type": "string",
|
||||
"description": "Directory path to change to (relative to workspace root)"
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let dir = crate::tools::arg_str(args, "directory")?;
|
||||
std::env::set_current_dir(&dir)?;
|
||||
Ok(format!("Changed directory to '{dir}'"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//! Update the shared directory cache.
|
||||
|
||||
use crate::tools::ToolCtx;
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct DirCacheUpdate;
|
||||
|
||||
impl crate::tools::Tool for DirCacheUpdate {
|
||||
fn name(&self) -> &'static str {
|
||||
"dir_cache_update"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Update the cached directory listing"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"paths": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "New list of paths for the cache"
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let paths: Vec<String> = args
|
||||
.get("paths")
|
||||
.and_then(|v| v.as_array())
|
||||
.map(|arr| {
|
||||
arr.iter()
|
||||
.filter_map(|v| v.as_str().map(String::from))
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let count = paths.len();
|
||||
Ok(format!("Directory cache updated with {} entries", count))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
//! List directory contents.
|
||||
|
||||
use crate::tools::{resolve_path, Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct DirList;
|
||||
|
||||
impl Tool for DirList {
|
||||
fn name(&self) -> &'static str {
|
||||
"dir_list"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"List files and directories in a given path"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "Path to list (relative to workspace root)"
|
||||
}
|
||||
},
|
||||
"required": ["path"]
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let rel = crate::tools::arg_str(args, "path")?;
|
||||
let path = resolve_path(&ctx.workspaces, &rel)?;
|
||||
|
||||
if !path.exists() {
|
||||
anyhow::bail!("path '{rel}' does not exist");
|
||||
}
|
||||
if !path.is_dir() {
|
||||
anyhow::bail!("'{rel}' is not a directory");
|
||||
}
|
||||
|
||||
let entries = std::fs::read_dir(&path)?;
|
||||
let mut items: Vec<String> = entries
|
||||
.filter_map(|e| e.ok())
|
||||
.map(|e| {
|
||||
let name = e.file_name().to_string_lossy().to_string();
|
||||
if e.path().is_dir() {
|
||||
format!("{name}/")
|
||||
} else {
|
||||
name
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
items.sort();
|
||||
Ok(items.join("\n"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
//! Utility tools — cd, dir_list, dir_cache_update, pong, todowrite, todofinish.
|
||||
|
||||
pub mod cd;
|
||||
pub mod dir_cache_update;
|
||||
pub mod dir_list;
|
||||
pub mod pong;
|
||||
pub mod todofinish;
|
||||
pub mod todowrite;
|
||||
@@ -0,0 +1,28 @@
|
||||
//! Simple ping/pong tool for connectivity testing.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct Pong;
|
||||
|
||||
impl Tool for Pong {
|
||||
fn name(&self) -> &'static str {
|
||||
"pong"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Ping the agent — useful for testing connectivity"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {}
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &ToolCtx, _args: &Value) -> Result<String> {
|
||||
Ok("pong".to_string())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//! Mark a TODO item as finished.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct Todofinish;
|
||||
|
||||
impl Tool for Todofinish {
|
||||
fn name(&self) -> &'static str {
|
||||
"todofinish"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Mark a TODO item as completed"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {
|
||||
"type": "string",
|
||||
"description": "TODO item text that was completed"
|
||||
}
|
||||
},
|
||||
"required": ["item"]
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let item = crate::tools::arg_str(args, "item")?;
|
||||
Ok(format!("TODO completed: {}", item))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
//! Write a TODO item.
|
||||
|
||||
use crate::tools::{Tool, ToolCtx};
|
||||
use anyhow::Result;
|
||||
use serde_json::{json, Value};
|
||||
|
||||
pub struct Todowrite;
|
||||
|
||||
impl Tool for Todowrite {
|
||||
fn name(&self) -> &'static str {
|
||||
"todowrite"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Add an item to the TODO list"
|
||||
}
|
||||
|
||||
fn parameters(&self) -> Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"item": {
|
||||
"type": "string",
|
||||
"description": "TODO item text"
|
||||
},
|
||||
"priority": {
|
||||
"type": "string",
|
||||
"enum": ["high", "medium", "low"],
|
||||
"description": "Priority level"
|
||||
}
|
||||
},
|
||||
"required": ["item"]
|
||||
})
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||||
let item = crate::tools::arg_str(args, "item")?;
|
||||
let priority = args
|
||||
.get("priority")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("medium");
|
||||
|
||||
Ok(format!("[{}] TODO added: {}", priority, item))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user