infer_task_progress
Analyze codebase changes to infer task completion status, tracking progress through file modifications and implementation evidence. Configure directory depth, file types, and confidence thresholds for accurate task updates.
Instructions
Analyze the codebase to infer which tasks appear to be completed based on code changes, file creation, and implementation evidence. Intelligent progress inference to automatically track task completion from code analysis.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| autoUpdateTasks | No | Whether to automatically update task status based on inference | |
| confidenceThreshold | No | Confidence threshold for auto-updating tasks (0-1) | |
| fileExtensions | No | File extensions to analyze | |
| projectId | No | Filter analysis to a specific project | |
| scanDepth | No | Directory depth to scan for code files | |
| workingDirectory | Yes | The full absolute path to the working directory where data is stored. MUST be an absolute path, never relative. Windows: "C:\Users\username\project" or "D:\projects\my-app". Unix/Linux/macOS: "/home/username/project" or "/Users/username/project". Do NOT use: ".", "..", "~", "./folder", "../folder" or any relative paths. Ensure the path exists and is accessible before calling this tool. NOTE: When server is started with --claude flag, this parameter is ignored and a global user directory is used instead. |
Implementation Reference
- The main handler function that executes the infer_task_progress tool logic. It retrieves incomplete tasks, scans the codebase for relevant files, analyzes evidence of task completion using keyword matching, file patterns, recent modifications, and tests, optionally auto-updates task statuses, and generates a detailed progress inference report.handler: async (args: any) => { try { const { workingDirectory, projectId, scanDepth, fileExtensions, autoUpdateTasks, confidenceThreshold } = args; // Get tasks to analyze let tasksToAnalyze: Task[] = []; if (projectId) { tasksToAnalyze = await storage.getTasks(projectId); } else { const projects = await storage.getProjects(); for (const project of projects) { const projectTasks = await storage.getTasks(project.id); tasksToAnalyze.push(...projectTasks); } } // Filter out already completed tasks const incompleteTasks = tasksToAnalyze.filter(task => !task.completed && task.status !== 'done' ); if (incompleteTasks.length === 0) { return { content: [{ type: 'text' as const, text: projectId ? `No incomplete tasks found in the specified project.` : `No incomplete tasks found across all projects.` }] }; } // Scan codebase const codebaseFiles = await scanCodebase(workingDirectory, scanDepth, fileExtensions); // Analyze each task for completion evidence const analysisResults = await analyzeTaskCompletion( incompleteTasks, codebaseFiles, workingDirectory ); // Auto-update tasks if requested let updatedTasks: Task[] = []; if (autoUpdateTasks) { updatedTasks = await autoUpdateTaskStatus( storage, analysisResults, confidenceThreshold ); } // Generate progress inference report const report = generateProgressInferenceReport( analysisResults, updatedTasks, autoUpdateTasks, confidenceThreshold ); return { content: [{ type: 'text' as const, text: report }] }; } catch (error) { return { content: [{ type: 'text' as const, text: `Error inferring task progress: ${error instanceof Error ? error.message : 'Unknown error'}` }], isError: true }; } }
- Zod input schema defining the parameters for the tool: workingDirectory, projectId, scanDepth, fileExtensions, autoUpdateTasks, and confidenceThreshold.inputSchema: z.object({ workingDirectory: z.string().describe(getWorkingDirectoryDescription(config)), projectId: z.string().optional().describe('Filter analysis to a specific project'), scanDepth: z.number().min(1).max(5).optional().default(3).describe('Directory depth to scan for code files'), fileExtensions: z.array(z.string()).optional().default(['.js', '.ts', '.jsx', '.tsx', '.py', '.java', '.cs', '.go', '.rs']).describe('File extensions to analyze'), autoUpdateTasks: z.boolean().optional().default(false).describe('Whether to automatically update task status based on inference'), confidenceThreshold: z.number().min(0).max(1).optional().default(0.7).describe('Confidence threshold for auto-updating tasks (0-1)') }),
- Factory function that creates the tool object for 'infer_task_progress', including name, description, inputSchema, and handler. This is how the tool is defined and can be registered in the MCP tools system.export function createProgressInferenceTool(storage: Storage, getWorkingDirectoryDescription: (config: any) => string, config: any) { return { name: 'infer_task_progress', description: 'Analyze the codebase to infer which tasks appear to be completed based on code changes, file creation, and implementation evidence. Intelligent progress inference feature for automatic task completion tracking.', inputSchema: z.object({ workingDirectory: z.string().describe(getWorkingDirectoryDescription(config)), projectId: z.string().optional().describe('Filter analysis to a specific project'), scanDepth: z.number().min(1).max(5).optional().default(3).describe('Directory depth to scan for code files'), fileExtensions: z.array(z.string()).optional().default(['.js', '.ts', '.jsx', '.tsx', '.py', '.java', '.cs', '.go', '.rs']).describe('File extensions to analyze'), autoUpdateTasks: z.boolean().optional().default(false).describe('Whether to automatically update task status based on inference'), confidenceThreshold: z.number().min(0).max(1).optional().default(0.7).describe('Confidence threshold for auto-updating tasks (0-1)') }), handler: async (args: any) => { try { const { workingDirectory, projectId, scanDepth, fileExtensions, autoUpdateTasks, confidenceThreshold } = args; // Get tasks to analyze let tasksToAnalyze: Task[] = []; if (projectId) { tasksToAnalyze = await storage.getTasks(projectId); } else { const projects = await storage.getProjects(); for (const project of projects) { const projectTasks = await storage.getTasks(project.id); tasksToAnalyze.push(...projectTasks); } } // Filter out already completed tasks const incompleteTasks = tasksToAnalyze.filter(task => !task.completed && task.status !== 'done' ); if (incompleteTasks.length === 0) { return { content: [{ type: 'text' as const, text: projectId ? `No incomplete tasks found in the specified project.` : `No incomplete tasks found across all projects.` }] }; } // Scan codebase const codebaseFiles = await scanCodebase(workingDirectory, scanDepth, fileExtensions); // Analyze each task for completion evidence const analysisResults = await analyzeTaskCompletion( incompleteTasks, codebaseFiles, workingDirectory ); // Auto-update tasks if requested let updatedTasks: Task[] = []; if (autoUpdateTasks) { updatedTasks = await autoUpdateTaskStatus( storage, analysisResults, confidenceThreshold ); } // Generate progress inference report const report = generateProgressInferenceReport( analysisResults, updatedTasks, autoUpdateTasks, confidenceThreshold ); return { content: [{ type: 'text' as const, text: report }] }; } catch (error) { return { content: [{ type: 'text' as const, text: `Error inferring task progress: ${error instanceof Error ? error.message : 'Unknown error'}` }], isError: true }; } } }; }