//! Tool for marking tasks as finished in the session's todo list. use serde_json::{json, Value}; use anyhow::{Result, anyhow}; use std::path::PathBuf; use super::super::{Tool, ToolCtx}; /// Tool that marks tasks as finished in the session's todo.md. pub struct Todofinish; impl Tool for Todofinish { fn name(&self) -> &'static str { "todofinish" } fn description(&self) -> &'static str { "Mark tasks as finished in the session todo list (todo.md). You can mark all tasks as finished by leaving the 'task_index' empty, or specify a 1-based index to finish a specific task." } fn parameters(&self) -> Value { json!({ "type": "object", "properties": { "task_index": { "type": "integer", "description": "Optional 1-based index of the task to mark as finished. If omitted, ALL unfinished tasks will be marked as finished." } } }) } fn run(&self, ctx: &ToolCtx, args: &Value) -> Result { let path: PathBuf = ctx.session_dir.join("todo.md"); if !path.exists() { return Ok("No todo.md found in session directory. Nothing to finish.".to_string()); } let content = std::fs::read_to_string(&path) .map_err(|e| anyhow!("failed to read todo.md: {}", e))?; let task_index = args.get("task_index").and_then(|v| v.as_i64()); let mut new_content = String::new(); let mut task_count = 0; let mut modified = false; for line in content.lines() { if line.trim_start().starts_with("- [ ]") { task_count += 1; if let Some(target) = task_index { if task_count == target { new_content.push_str(&line.replacen("- [ ]", "- [x]", 1)); modified = true; } else { new_content.push_str(line); } } else { // Mark all as finished new_content.push_str(&line.replacen("- [ ]", "- [x]", 1)); modified = true; } } else { new_content.push_str(line); } new_content.push('\n'); } if !modified { return Ok("No unfinished tasks found or index out of bounds.".to_string()); } std::fs::write(&path, new_content) .map_err(|e| anyhow!("failed to write to todo.md: {}", e))?; if let Some(idx) = task_index { Ok(format!("Successfully marked task {} as finished.", idx)) } else { Ok("Successfully marked ALL tasks as finished.".to_string()) } } }