feat(theme): add tool_output color to themes
- Added a `tool_output` color to the `Theme` struct. - Updated all built-in themes to include the new color. - Modified the TUI to use the `tool_output` color for rendering tool output.
This commit is contained in:
111
crates/owlen-core/src/tools/fs_tools.rs
Normal file
111
crates/owlen-core/src/tools/fs_tools.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
use crate::tools::{Tool, ToolResult};
|
||||
use anyhow::Result;
|
||||
use async_trait::async_trait;
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use path_clean::PathClean;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct FileArgs {
|
||||
path: String,
|
||||
}
|
||||
|
||||
fn sanitize_path(path: &str, root: &Path) -> Result<PathBuf> {
|
||||
let path = Path::new(path);
|
||||
let path = if path.is_absolute() {
|
||||
path.strip_prefix("/")
|
||||
.map_err(|_| anyhow::anyhow!("Invalid path"))?
|
||||
.to_path_buf()
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
};
|
||||
|
||||
let full_path = root.join(path).clean();
|
||||
|
||||
if !full_path.starts_with(root) {
|
||||
return Err(anyhow::anyhow!("Path traversal detected"));
|
||||
}
|
||||
|
||||
Ok(full_path)
|
||||
}
|
||||
|
||||
pub struct ResourcesListTool;
|
||||
|
||||
#[async_trait]
|
||||
impl Tool for ResourcesListTool {
|
||||
fn name(&self) -> &'static str {
|
||||
"resources/list"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Lists directory contents."
|
||||
}
|
||||
|
||||
fn schema(&self) -> serde_json::Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The path to the directory to list."
|
||||
}
|
||||
},
|
||||
"required": ["path"]
|
||||
})
|
||||
}
|
||||
|
||||
async fn execute(&self, args: serde_json::Value) -> Result<ToolResult> {
|
||||
let args: FileArgs = serde_json::from_value(args)?;
|
||||
let root = env::current_dir()?;
|
||||
let full_path = sanitize_path(&args.path, &root)?;
|
||||
|
||||
let entries = fs::read_dir(full_path)?;
|
||||
|
||||
let mut result = Vec::new();
|
||||
for entry in entries {
|
||||
let entry = entry?;
|
||||
result.push(entry.file_name().to_string_lossy().to_string());
|
||||
}
|
||||
|
||||
Ok(ToolResult::success(serde_json::to_value(result)?))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ResourcesGetTool;
|
||||
|
||||
#[async_trait]
|
||||
impl Tool for ResourcesGetTool {
|
||||
fn name(&self) -> &'static str {
|
||||
"resources/get"
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
"Reads file content."
|
||||
}
|
||||
|
||||
fn schema(&self) -> serde_json::Value {
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The path to the file to read."
|
||||
}
|
||||
},
|
||||
"required": ["path"]
|
||||
})
|
||||
}
|
||||
|
||||
async fn execute(&self, args: serde_json::Value) -> Result<ToolResult> {
|
||||
let args: FileArgs = serde_json::from_value(args)?;
|
||||
let root = env::current_dir()?;
|
||||
let full_path = sanitize_path(&args.path, &root)?;
|
||||
|
||||
let content = fs::read_to_string(full_path)?;
|
||||
|
||||
Ok(ToolResult::success(serde_json::to_value(content)?))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user