From dfadd27c1ecf46d7ad54e921b114a169fcc4eacd Mon Sep 17 00:00:00 2001 From: Amolith Date: Sun, 18 May 2025 11:13:42 -0600 Subject: [PATCH] refactor: Remove unused handlers file --- tools/handlers.go | 378 ---------------------------------------------- 1 file changed, 378 deletions(-) delete mode 100644 tools/handlers.go diff --git a/tools/handlers.go b/tools/handlers.go deleted file mode 100644 index e295db3b62416b52509273ff964033ebde7767d8..0000000000000000000000000000000000000000 --- a/tools/handlers.go +++ /dev/null @@ -1,378 +0,0 @@ -// SPDX-FileCopyrightText: Amolith -// -// SPDX-License-Identifier: AGPL-3.0-or-later - -package tools - -import ( - "context" - "encoding/json" - "fmt" - "strings" - "time" - - "github.com/ijt/go-anytime" - "github.com/mark3labs/mcp-go/mcp" - - "git.sr.ht/~amolith/lunatask-mcp-server/lunatask" -) - - -// HandleCreateTask handles the create_task tool call. -func (h *Handlers) HandleCreateTask(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - arguments := request.Params.Arguments - - if _, err := LoadLocation(h.config.Timezone); err != nil { - return reportMCPError(err.Error()) - } - - areaID, ok := arguments["area_id"].(string) - if !ok || areaID == "" { - return reportMCPError("Missing or invalid required argument: area_id") - } - - var areaFoundProvider AreaProvider - for _, ap := range h.config.Areas { - if ap.GetID() == areaID { - areaFoundProvider = ap - break - } - } - if areaFoundProvider == nil { - return reportMCPError("Area not found for given area_id") - } - - if goalID, exists := arguments["goal_id"].(string); exists && goalID != "" { - found := false - for _, goal := range areaFoundProvider.GetGoals() { - if goal.GetID() == goalID { - found = true - break - } - } - if !found { - return reportMCPError("Goal not found in specified area for given goal_id") - } - } - - priorityMap := map[string]int{ - "lowest": -2, - "low": -1, - "neutral": 0, - "high": 1, - "highest": 2, - } - - if priorityArg, exists := arguments["priority"]; exists && priorityArg != nil { - priorityStr, ok := priorityArg.(string) - if !ok { - return reportMCPError("Invalid type for 'priority' argument: expected string.") - } - translatedPriority, isValid := priorityMap[strings.ToLower(priorityStr)] - if !isValid { - return reportMCPError(fmt.Sprintf("Invalid 'priority' value: '%s'. Must be one of 'lowest', 'low', 'neutral', 'high', 'highest'.", priorityStr)) - } - arguments["priority"] = translatedPriority - } - - if motivationVal, exists := arguments["motivation"]; exists && motivationVal != nil { - if motivation, ok := motivationVal.(string); ok && motivation != "" { - validMotivations := map[string]bool{"must": true, "should": true, "want": true} - if !validMotivations[motivation] { - return reportMCPError("'motivation' must be one of 'must', 'should', or 'want'") - } - } else if ok { - // empty string is allowed - } else { - return reportMCPError("'motivation' must be a string") - } - } - - if statusVal, exists := arguments["status"]; exists && statusVal != nil { - if status, ok := statusVal.(string); ok && status != "" { - validStatus := map[string]bool{"later": true, "next": true, "started": true, "waiting": true, "completed": true} - if !validStatus[status] { - return reportMCPError("'status' must be one of 'later', 'next', 'started', 'waiting', or 'completed'") - } - } else if ok { - // empty string is allowed - } else { - return reportMCPError("'status' must be a string") - } - } - - if scheduledOnArg, exists := arguments["scheduled_on"]; exists { - if scheduledOnStr, ok := scheduledOnArg.(string); ok && scheduledOnStr != "" { - if _, err := time.Parse(time.RFC3339, scheduledOnStr); err != nil { - return reportMCPError(fmt.Sprintf("Invalid format for scheduled_on: '%s'. Must be RFC3339 timestamp (e.g., YYYY-MM-DDTHH:MM:SSZ). Use get_task_timestamp tool first.", scheduledOnStr)) - } - } else if !ok { - return reportMCPError("Invalid type for scheduled_on argument: expected string.") - } - } - - client := lunatask.NewClient(h.config.AccessToken) - var task lunatask.CreateTaskRequest - argBytes, err := json.Marshal(arguments) - if err != nil { - return reportMCPError(fmt.Sprintf("Failed to process arguments: %v", err)) - } - if err := json.Unmarshal(argBytes, &task); err != nil { - return reportMCPError(fmt.Sprintf("Failed to parse arguments: %v", err)) - } - - response, err := client.CreateTask(ctx, &task) - if err != nil { - return reportMCPError(fmt.Sprintf("%v", err)) - } - - if response == nil { - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: "Task already exists (not an error).", - }, - }, - }, nil - } - - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: fmt.Sprintf("Task created successfully with ID: %s", response.Task.ID), - }, - }, - }, nil -} - -// HandleUpdateTask handles the update_task tool call. -func (h *Handlers) HandleUpdateTask(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - arguments := request.Params.Arguments - - taskID, ok := arguments["task_id"].(string) - if !ok || taskID == "" { - return reportMCPError("Missing or invalid required argument: task_id") - } - - if _, err := LoadLocation(h.config.Timezone); err != nil { - return reportMCPError(err.Error()) - } - - updatePayload := lunatask.CreateTaskRequest{} - - var specifiedAreaProvider AreaProvider - areaIDProvided := false - - if areaIDArg, exists := arguments["area_id"]; exists { - if areaIDStr, ok := areaIDArg.(string); ok && areaIDStr != "" { - updatePayload.AreaID = areaIDStr - areaIDProvided = true - found := false - for _, ap := range h.config.Areas { - if ap.GetID() == areaIDStr { - specifiedAreaProvider = ap - found = true - break - } - } - if !found { - return reportMCPError(fmt.Sprintf("Area not found for given area_id: %s", areaIDStr)) - } - } else if !ok && areaIDArg != nil { - return reportMCPError("Invalid type for area_id argument: expected string.") - } - } - - if goalIDArg, exists := arguments["goal_id"]; exists { - if goalIDStr, ok := goalIDArg.(string); ok && goalIDStr != "" { - updatePayload.GoalID = goalIDStr - if specifiedAreaProvider != nil { - foundGoal := false - for _, goal := range specifiedAreaProvider.GetGoals() { - if goal.GetID() == goalIDStr { - foundGoal = true - break - } - } - if !foundGoal { - return reportMCPError(fmt.Sprintf("Goal not found in specified area '%s' for given goal_id: %s", specifiedAreaProvider.GetName(), goalIDStr)) - } - } else if areaIDProvided { - return reportMCPError("Internal error: area_id provided but area details not loaded for goal validation.") - } - } else if !ok && goalIDArg != nil { - return reportMCPError("Invalid type for goal_id argument: expected string.") - } - } - - nameArg := arguments["name"] - if nameStr, ok := nameArg.(string); ok { - updatePayload.Name = nameStr - } else { - return reportMCPError("Invalid type for name argument: expected string.") - } - - if noteArg, exists := arguments["note"]; exists { - if noteStr, ok := noteArg.(string); ok { - updatePayload.Note = noteStr - } else if !ok && noteArg != nil { - return reportMCPError("Invalid type for note argument: expected string.") - } - } - - if estimateArg, exists := arguments["estimate"]; exists && estimateArg != nil { - if estimateVal, ok := estimateArg.(float64); ok { - updatePayload.Estimate = int(estimateVal) - } else { - return reportMCPError("Invalid type for estimate argument: expected number.") - } - } - - if priorityArg, exists := arguments["priority"]; exists && priorityArg != nil { - priorityStr, ok := priorityArg.(string) - if !ok { - return reportMCPError("Invalid type for 'priority' argument: expected string.") - } - priorityMap := map[string]int{ - "lowest": -2, - "low": -1, - "neutral": 0, - "high": 1, - "highest": 2, - } - translatedPriority, isValid := priorityMap[strings.ToLower(priorityStr)] - if !isValid { - return reportMCPError(fmt.Sprintf("Invalid 'priority' value: '%s'. Must be one of 'lowest', 'low', 'neutral', 'high', 'highest'.", priorityStr)) - } - updatePayload.Priority = translatedPriority - } - - if motivationArg, exists := arguments["motivation"]; exists { - if motivationStr, ok := motivationArg.(string); ok { - if motivationStr != "" { - validMotivations := map[string]bool{"must": true, "should": true, "want": true} - if !validMotivations[motivationStr] { - return reportMCPError("'motivation' must be one of 'must', 'should', or 'want', or empty to clear.") - } - } - updatePayload.Motivation = motivationStr - } else if !ok && motivationArg != nil { - return reportMCPError("Invalid type for motivation argument: expected string.") - } - } - - if statusArg, exists := arguments["status"]; exists { - if statusStr, ok := statusArg.(string); ok { - if statusStr != "" { - validStatus := map[string]bool{"later": true, "next": true, "started": true, "waiting": true, "completed": true} - if !validStatus[statusStr] { - return reportMCPError("'status' must be one of 'later', 'next', 'started', 'waiting', 'completed', or empty.") - } - } - updatePayload.Status = statusStr - } else if !ok && statusArg != nil { - return reportMCPError("Invalid type for status argument: expected string.") - } - } - - if scheduledOnArg, exists := arguments["scheduled_on"]; exists { - if scheduledOnStr, ok := scheduledOnArg.(string); ok { - if scheduledOnStr != "" { - if _, err := time.Parse(time.RFC3339, scheduledOnStr); err != nil { - return reportMCPError(fmt.Sprintf("Invalid format for scheduled_on: '%s'. Must be RFC3339. Use get_task_timestamp tool.", scheduledOnStr)) - } - } - updatePayload.ScheduledOn = scheduledOnStr - } else if !ok && scheduledOnArg != nil { - return reportMCPError("Invalid type for scheduled_on argument: expected string.") - } - } - - client := lunatask.NewClient(h.config.AccessToken) - response, err := client.UpdateTask(ctx, taskID, &updatePayload) - if err != nil { - return reportMCPError(fmt.Sprintf("Failed to update task: %v", err)) - } - - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: fmt.Sprintf("Task updated successfully. ID: %s", response.Task.ID), - }, - }, - }, nil -} - -// HandleDeleteTask handles the delete_task tool call. -func (h *Handlers) HandleDeleteTask(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - taskID, ok := request.Params.Arguments["task_id"].(string) - if !ok || taskID == "" { - return reportMCPError("Missing or invalid required argument: task_id") - } - - client := lunatask.NewClient(h.config.AccessToken) - _, err := client.DeleteTask(ctx, taskID) - if err != nil { - return reportMCPError(fmt.Sprintf("Failed to delete task: %v", err)) - } - - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: "Task deleted successfully.", - }, - }, - }, nil -} - -// HandleListHabitsAndActivities handles the list_habits_and_activities tool call. -func (h *Handlers) HandleListHabitsAndActivities(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - var b strings.Builder - for _, habit := range h.config.Habits { - fmt.Fprintf(&b, "- %s: %s\n", habit.GetName(), habit.GetID()) - } - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: b.String(), - }, - }, - }, nil -} - -// HandleTrackHabitActivity handles the track_habit_activity tool call. -func (h *Handlers) HandleTrackHabitActivity(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - habitID, ok := request.Params.Arguments["habit_id"].(string) - if !ok || habitID == "" { - return reportMCPError("Missing or invalid required argument: habit_id") - } - - performedOn, ok := request.Params.Arguments["performed_on"].(string) - if !ok || performedOn == "" { - return reportMCPError("Missing or invalid required argument: performed_on") - } - - client := lunatask.NewClient(h.config.AccessToken) - habitRequest := &lunatask.TrackHabitActivityRequest{ - PerformedOn: performedOn, - } - - resp, err := client.TrackHabitActivity(ctx, habitID, habitRequest) - if err != nil { - return reportMCPError(fmt.Sprintf("Failed to track habit activity: %v", err)) - } - - return &mcp.CallToolResult{ - Content: []mcp.Content{ - mcp.TextContent{ - Type: "text", - Text: fmt.Sprintf("Habit activity tracked successfully. Status: %s, Message: %s", resp.Status, resp.Message), - }, - }, - }, nil -}