claude_rust_tools/infrastructure/
todo_read_tool.rs1use claude_rust_errors::AppResult;
2use claude_rust_types::{PermissionLevel, SearchReadInfo, Tool};
3use serde_json::{Value, json};
4
5use super::todo_store::read_todos;
6
7pub struct TodoReadTool;
8
9#[async_trait::async_trait]
10impl Tool for TodoReadTool {
11 fn name(&self) -> &str {
12 "todo_read"
13 }
14
15 fn description(&self) -> &str {
16 "Read the current task list to check pending, in-progress, and completed tasks."
17 }
18
19 fn input_schema(&self) -> Value {
20 json!({
21 "type": "object",
22 "properties": {}
23 })
24 }
25
26 fn permission_level(&self) -> PermissionLevel {
27 PermissionLevel::ReadOnly
28 }
29
30 fn is_read_only(&self, _input: &Value) -> bool { true }
31 fn is_concurrent_safe(&self, _input: &Value) -> bool { true }
32
33 fn is_search_or_read_command(&self, _input: &Value) -> SearchReadInfo {
34 SearchReadInfo { is_search: false, is_read: true, is_list: false }
35 }
36
37 async fn execute(&self, _input: Value) -> AppResult<String> {
38 let todos = read_todos();
39 if todos.is_empty() {
40 return Ok("No todos.".into());
41 }
42 let mut out = String::new();
43 for t in &todos {
44 let icon = match t.status.as_str() {
45 "completed" => "✓",
46 "in_progress" => "→",
47 _ => "○",
48 };
49 let pri = match t.priority.as_str() {
50 "high" => "[!]",
51 "medium" => "[~]",
52 _ => "[ ]",
53 };
54 out.push_str(&format!("{icon} {pri} [{}] {}\n", t.id, t.content));
55 }
56 Ok(out.trim_end().to_string())
57 }
58}