feat: Make task name required for update tool and validation

Amolith created

Change summary

lunatask/tasks.go |  4 ++--
main.go           | 17 +++++++++++------
2 files changed, 13 insertions(+), 8 deletions(-)

Detailed changes

lunatask/tasks.go 🔗

@@ -61,8 +61,8 @@ type Task struct {
 // CreateTaskRequest represents the request to create a task in Lunatask
 type CreateTaskRequest struct {
 	AreaID      string `json:"area_id" validate:"omitempty,uuid4"`
-	GoalID      string `json:"goal_id,omitempty" validate:"omitempty,uuid4"`
-	Name        string `json:"name" validate:"max=100"`
+	GoalID      string `json:"goal_id,omitempty" validate:"omitempty,uuid4"` // Assuming GoalID remains optional for tasks
+	Name        string `json:"name" validate:"required,max=100"`
 	Note        string `json:"note,omitempty" validate:"omitempty"`
 	Status      string `json:"status,omitempty" validate:"omitempty,oneof=later next started waiting completed"`
 	Motivation  string `json:"motivation,omitempty" validate:"omitempty,oneof=must should want unknown"`

main.go 🔗

@@ -267,6 +267,7 @@ func NewMCPServer(config *Config) *server.MCPServer {
 		),
 		mcp.WithString("name",
 			mcp.Description("New plain text task name using sentence case."),
+			mcp.Required(),
 		),
 		mcp.WithString("note",
 			mcp.Description("New note attached to the task, optionally Markdown-formatted. Sending an empty string might clear the note."),
@@ -513,12 +514,16 @@ func handleUpdateTask(
 		}
 	}
 
-	if nameArg, exists := arguments["name"]; exists {
-		if nameStr, ok := nameArg.(string); ok { // Allow empty string for name to potentially clear it
-			updatePayload.Name = nameStr
-		} else if !ok && nameArg != nil {
-			return reportMCPError("Invalid type for name argument: expected string.")
-		}
+	// Name is now required by the MCP tool definition.
+	// The lunatask.ValidateTask (called by client.UpdateTask) will ensure it's not an empty string
+	// due to the "required" tag on CreateTaskRequest.Name.
+	nameArg := arguments["name"] // MCP framework ensures "name" exists.
+	if nameStr, ok := nameArg.(string); ok {
+		updatePayload.Name = nameStr
+	} else {
+		// This case should ideally be caught by MCP's type checking.
+		// A defensive check is good.
+		return reportMCPError("Invalid type for name argument: expected string.")
 	}
 
 	if noteArg, exists := arguments["note"]; exists {