claude_rust_tools/infrastructure/
task_create_tool.rs1use std::sync::Arc;
2
3use claude_rust_errors::{AppError, AppResult};
4use claude_rust_types::{PermissionLevel, Tool};
5use serde_json::{Value, json};
6
7use super::task_manager::TaskManager;
8
9pub struct TaskCreateTool {
10 manager: Arc<dyn TaskManager>,
11}
12
13impl TaskCreateTool {
14 pub fn new(manager: Arc<dyn TaskManager>) -> Self {
15 Self { manager }
16 }
17}
18
19#[async_trait::async_trait]
20impl Tool for TaskCreateTool {
21 fn name(&self) -> &str {
22 "task_create"
23 }
24
25 fn description(&self) -> &str {
26 "Create a new task with a subject and description. Returns the created task info including its generated ID."
27 }
28
29 fn input_schema(&self) -> Value {
30 json!({
31 "type": "object",
32 "properties": {
33 "subject": {
34 "type": "string",
35 "description": "Short subject line for the task"
36 },
37 "description": {
38 "type": "string",
39 "description": "Detailed description of the task"
40 },
41 "metadata": {
42 "type": "object",
43 "description": "Optional metadata to attach to the task"
44 }
45 },
46 "required": ["subject", "description"]
47 })
48 }
49
50 fn permission_level(&self) -> PermissionLevel {
51 PermissionLevel::Dangerous
52 }
53
54 async fn execute(&self, input: Value) -> AppResult<String> {
55 let subject = input
56 .get("subject")
57 .and_then(|v| v.as_str())
58 .ok_or_else(|| AppError::Tool("missing 'subject' field".into()))?;
59
60 let description = input
61 .get("description")
62 .and_then(|v| v.as_str())
63 .ok_or_else(|| AppError::Tool("missing 'description' field".into()))?;
64
65 let mut task = self.manager.create(subject, description).await?;
66
67 if let Some(metadata) = input.get("metadata") {
68 task.metadata = metadata.clone();
69 }
70
71 serde_json::to_string_pretty(&task)
72 .map_err(|e| AppError::Tool(format!("failed to serialize task: {e}")))
73 }
74}