use crate::types::*;
pub struct CronCreateTool;
impl CronCreateTool {
pub fn new() -> Self {
Self
}
pub fn input_schema(&self) -> ToolInputSchema {
ToolInputSchema {
schema_type: "object".to_string(),
properties: serde_json::json!({
"cron": {
"type": "string",
"description": "Standard 5-field cron expression in local time: 'M H DoM Mon DoW' (e.g., '*/5 * * * *' = every 5 minutes, '0 9 * * 1-5' = weekdays at 9am)"
},
"prompt": {
"type": "string",
"description": "The prompt to enqueue at each fire time"
},
"recurring": {
"type": "boolean",
"description": "true (default) = fire on every cron match until deleted or auto-expired after 7 days. false = fire once at the next match, then auto-delete"
},
"durable": {
"type": "boolean",
"description": "true = persist to .claude/scheduled_tasks.json and survive restarts. false (default) = in-memory only, dies when this Claude session ends"
}
}),
required: Some(vec!["cron".to_string(), "prompt".to_string()]),
}
}
pub async fn execute(&self, input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
let cron = input["cron"].as_str().unwrap_or("");
let prompt = input["prompt"].as_str().unwrap_or("");
let recurring = input["recurring"].as_bool().unwrap_or(true);
let durable = input["durable"].as_bool().unwrap_or(false);
let response = format!(
"Scheduled task created:\nCron: {}\nPrompt: {}\nRecurring: {}\nDurable: {}\nNote: Full implementation would persist and execute this scheduled task.",
cron, prompt, recurring, durable
);
Ok(ToolResult {
result_type: "text".to_string(),
tool_use_id: "cron_create".to_string(),
content: response,
is_error: Some(false),
})
}
}
impl Default for CronCreateTool {
fn default() -> Self {
Self::new()
}
}
pub struct CronDeleteTool;
impl CronDeleteTool {
pub fn new() -> Self {
Self
}
pub fn input_schema(&self) -> ToolInputSchema {
ToolInputSchema {
schema_type: "object".to_string(),
properties: serde_json::json!({
"id": {
"type": "string",
"description": "Job ID returned by CronCreate"
}
}),
required: Some(vec!["id".to_string()]),
}
}
pub async fn execute(&self, input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
let id = input["id"].as_str().unwrap_or("");
let response = format!("Scheduled task '{}' deleted.", id);
Ok(ToolResult {
result_type: "text".to_string(),
tool_use_id: "cron_delete".to_string(),
content: response,
is_error: Some(false),
})
}
}
impl Default for CronDeleteTool {
fn default() -> Self {
Self::new()
}
}
pub struct CronListTool;
impl CronListTool {
pub fn new() -> Self {
Self
}
pub fn input_schema(&self) -> ToolInputSchema {
ToolInputSchema {
schema_type: "object".to_string(),
properties: serde_json::json!({}),
required: None,
}
}
pub async fn execute(&self, _input: serde_json::Value, _context: &ToolContext) -> Result<ToolResult, crate::error::AgentError> {
let response = "Scheduled tasks:\n- (none)".to_string();
Ok(ToolResult {
result_type: "text".to_string(),
tool_use_id: "cron_list".to_string(),
content: response,
is_error: Some(false),
})
}
}
impl Default for CronListTool {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cron_create_schema() {
let tool = CronCreateTool::new();
let schema = tool.input_schema();
assert!(schema.properties.get("cron").is_some());
assert!(schema.properties.get("prompt").is_some());
}
#[test]
fn test_cron_delete_schema() {
let tool = CronDeleteTool::new();
let schema = tool.input_schema();
assert!(schema.properties.get("id").is_some());
}
#[test]
fn test_cron_list_schema() {
let tool = CronListTool::new();
let schema = tool.input_schema();
assert_eq!(schema.schema_type, "object");
}
}