complete_task_status
Update task completion status within goals using dot-notation IDs, optionally completing child tasks recursively.
Instructions
Update the completion status of tasks. Task IDs use a dot-notation (e.g., "1", "1.1", "1.1.1"). Responses will return simplified task objects without createdAt, updatedAt, or parentId.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| goalId | Yes | ID of the goal containing the tasks (number) | |
| taskIds | Yes | IDs of the tasks to update (array of strings). Example: ["1.1", "1.2"]. | |
| completeChildren | No | Whether to complete all child tasks recursively (boolean). Defaults to false. If false, a task can only be completed if all its subtasks are already complete. |
Implementation Reference
- src/index.ts:330-346 (handler)MCP tool handler for 'complete_task_status' that parses input arguments, calls storage.completeTasksStatus, and returns the JSON-stringified results.case 'complete_task_status': { const { goalId, taskIds, completeChildren } = request.params.arguments as { goalId: number; taskIds: string[]; completeChildren?: boolean; }; const results = await storage.completeTasksStatus(goalId, taskIds, completeChildren); const textContent = JSON.stringify(results, null, 2); return { content: [ { type: 'text', text: textContent, } as { type: 'text'; text: string }, ], }; }
- src/index.ts:164-189 (registration)Tool registration including name, description, and input schema for 'complete_task_status'.{ name: 'complete_task_status', description: 'Update the completion status of tasks. Task IDs use a dot-notation (e.g., "1", "1.1", "1.1.1"). Responses will return simplified task objects without `createdAt`, `updatedAt`, or `parentId`.', inputSchema: { type: 'object', properties: { goalId: { type: 'number', description: 'ID of the goal containing the tasks (number)', }, taskIds: { type: 'array', items: { type: 'string', }, description: 'IDs of the tasks to update (array of strings). Example: ["1.1", "1.2"].', }, completeChildren: { type: 'boolean', description: 'Whether to complete all child tasks recursively (boolean). Defaults to false. If false, a task can only be completed if all its subtasks are already complete.', default: false, }, }, required: ['goalId', 'taskIds'], }, },
- src/storage.ts:336-400 (helper)Core implementation of task completion logic in storage, handling recursive completion of children if specified, checking subtasks, updating parent statuses, and persisting changes to the database.async completeTasksStatus( goalId: number, taskIds: string[], completeChildren: boolean = false ): Promise<{ updatedTasks: TaskResponse[]; completedParents: TaskResponse[] }> { const plan = await this.getPlan(goalId); if (!plan) { throw new Error(`No plan found for goal ${goalId}`); } const updatedTasks: TaskResponse[] = []; const completedParents: TaskResponse[] = []; const parentsToCheck: Set<string | null> = new Set(); const completeTaskAndChildren = async (taskId: string) => { const task = this.tasks.findOne({ goalId, id: taskId }); if (!task) return; // If completeChildren is true, mark all subtasks as complete first if (completeChildren) { const subtasks = this.tasks.find({ goalId, parentId: taskId }); for (const subtask of subtasks) { await completeTaskAndChildren(subtask.id); // Recursively complete children } } else { // A task can be completed only if all its non-deleted sub-tasks (if any) are completed. const subtasks = this.tasks.find({ goalId, parentId: taskId, deleted: false }); const allSubtasksComplete = subtasks.every(sub => sub.isComplete); if (!allSubtasksComplete) { console.warn(`Task ${taskId} cannot be marked complete because not all its non-deleted subtasks are complete.`); return; // Do not mark this task as complete } } // Only update if status is changing to complete if (!task.isComplete) { task.isComplete = true; task.updatedAt = new Date().toISOString(); this.tasks.update(task); const { createdAt, updatedAt, parentId: _, $loki, meta, ...taskData } = task as LokiTask; updatedTasks.push(taskData); } // Add parent to set for status check later if (task.parentId !== null) { parentsToCheck.add(task.parentId); } }; for (const taskId of taskIds) { await completeTaskAndChildren(taskId); } // After updating tasks, check and update parent statuses for (const parentId of parentsToCheck) { const completedParent = await this.updateParentTaskStatus(goalId, parentId); if (completedParent) { completedParents.push(completedParent); } } plan.updatedAt = new Date().toISOString(); await this.save(); return { updatedTasks, completedParents }; }