todo-done
Mark backlog todos as complete while validating dependencies to ensure proper workflow progression in project management.
Instructions
Mark backlog todos as complete with dependency validation
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | Operation to perform | |
| topic | Yes | Topic name (required) | |
| todoId | No | Todo ID (required for done) | |
| status | No | Filter by status (for list) | |
| batch | No | Filter by batch (for list) |
Implementation Reference
- src/index.ts:445-486 (handler)Primary handler function for the 'todo-done' tool. Handles 'done' action by validating dependencies before marking a todo as completed, and 'list' action by delegating to todo-read handler.async function handleBacklogTodoDone(args: any) { const { action, topic, todoId, status, batch } = args; if (!topic) throw new Error("topic is required"); switch (action) { case "done": { if (!todoId) throw new Error("todoId is required for done action"); const data = readTodos(topic); if (data.todos.length === 0) throw new Error("No todos found for this backlog item"); const todo = data.todos.find((t: any) => t.id === todoId); if (!todo) throw new Error(`Todo not found: ${todoId}`); // Validate dependencies const validation = validateDependencies(data.todos, todoId); if (!validation.valid) { const errors = []; if (validation.missing.length > 0) { errors.push(`Missing dependencies: ${validation.missing.join(', ')}`); } if (validation.incomplete.length > 0) { errors.push(`Incomplete dependencies: ${validation.incomplete.join(', ')}`); } throw new Error(errors.join('; ')); } todo.status = "completed"; (todo as any).completedAt = new Date().toISOString(); writeTodos(topic, data); return `Marked todo as done: ${todoId}`; } case "list": { return await handleBacklogTodoRead({ topic, status, batch }); } default: throw new Error(`Unknown action: ${action}`); } }
- src/index.ts:787-814 (schema)JSON Schema defining the input parameters for the 'todo-done' tool, including action (done/list), required topic, optional todoId, status, and batch filters.inputSchema: { type: "object", properties: { action: { type: "string", enum: ["done", "list"], description: "Operation to perform", }, topic: { type: "string", description: "Topic name (required)", }, todoId: { type: "string", description: "Todo ID (required for done)", }, status: { type: "string", enum: ["pending", "in_progress", "completed", "cancelled"], description: "Filter by status (for list)", }, batch: { type: "string", description: "Filter by batch (for list)", }, }, required: ["action", "topic"], },
- src/index.ts:784-815 (registration)Registration of the 'todo-done' tool in the ListToolsRequest handler, including name, description, and full input schema.{ name: "todo-done", description: "Mark backlog todos as complete with dependency validation", inputSchema: { type: "object", properties: { action: { type: "string", enum: ["done", "list"], description: "Operation to perform", }, topic: { type: "string", description: "Topic name (required)", }, todoId: { type: "string", description: "Todo ID (required for done)", }, status: { type: "string", enum: ["pending", "in_progress", "completed", "cancelled"], description: "Filter by status (for list)", }, batch: { type: "string", description: "Filter by batch (for list)", }, }, required: ["action", "topic"], }, },
- src/index.ts:843-845 (registration)Routing case in the CallToolRequest handler that dispatches 'todo-done' tool calls to the handleBacklogTodoDone function.case "todo-done": result = await handleBacklogTodoDone(request.params.arguments); break;
- lib/backlog-todo-shared.ts:117-140 (helper)Helper function validateDependencies used by the handler to ensure all dependencies of a todo are completed before marking it done.export function validateDependencies(todos: Todo[], todoId: string): { valid: boolean, missing: string[], incomplete: string[] } { const todo = todos.find(t => t.id === todoId); if (!todo) { throw new Error(`Todo with ID ${todoId} not found`); } const missing: string[] = []; const incomplete: string[] = []; for (const depId of todo.dependencies) { const dep = todos.find(t => t.id === depId); if (!dep) { missing.push(depId); } else if (dep.status !== "completed") { incomplete.push(depId); } } return { valid: missing.length === 0 && incomplete.length === 0, missing, incomplete }; }