diff --git a/.changeset/curvy-moons-dig.md b/.changeset/curvy-moons-dig.md index eb123cdb..70d05c6d 100644 --- a/.changeset/curvy-moons-dig.md +++ b/.changeset/curvy-moons-dig.md @@ -2,4 +2,8 @@ "task-master-ai": minor --- -Testing +Enhanced Gemini CLI provider with codebase-aware task generation + +Added automatic codebase analysis for Gemini CLI provider in parse-prd, and analyze-complexity, add-task, udpate-task, update, update-subtask commands +When using Gemini CLI as the AI provider, Task Master now instructs the AI to analyze the project structure, existing implementations, and patterns before generating tasks or subtasks +Tasks and subtasks generated by Claude Code are now informed by actual codebase analysis, resulting in more accurate and contextual outputs diff --git a/scripts/modules/config-manager.js b/scripts/modules/config-manager.js index 10936c24..600eeecf 100644 --- a/scripts/modules/config-manager.js +++ b/scripts/modules/config-manager.js @@ -437,8 +437,10 @@ function hasCodebaseAnalysis(useResearch = false, projectRoot = null) { const currentProvider = useResearch ? getResearchProvider(projectRoot) : getMainProvider(projectRoot); - return currentProvider === CUSTOM_PROVIDERS.CLAUDE_CODE || - currentProvider === CUSTOM_PROVIDERS.GEMINI_CLI; + return ( + currentProvider === CUSTOM_PROVIDERS.CLAUDE_CODE || + currentProvider === CUSTOM_PROVIDERS.GEMINI_CLI + ); } function getResearchModelId(explicitRoot = null) { diff --git a/scripts/modules/task-manager/analyze-task-complexity.js b/scripts/modules/task-manager/analyze-task-complexity.js index 9d2c6b6f..abac9331 100644 --- a/scripts/modules/task-manager/analyze-task-complexity.js +++ b/scripts/modules/task-manager/analyze-task-complexity.js @@ -3,7 +3,7 @@ import boxen from 'boxen'; import readline from 'readline'; import fs from 'fs'; -import { log, readJSON, writeJSON, isSilentMode } from '../utils.js'; +import { log, readJSON, isSilentMode } from '../utils.js'; import { startLoadingIndicator, @@ -16,9 +16,7 @@ import { generateTextService } from '../ai-services-unified.js'; import { getDebugFlag, getProjectName, - getMainProvider, - getResearchProvider, - isClaudeCode + hasCodebaseAnalysis } from '../config-manager.js'; import { getPromptManager } from '../prompt-manager.js'; import { @@ -421,7 +419,7 @@ async function analyzeTaskComplexity(options, context = {}) { tasks: tasksData.tasks, gatheredContext: gatheredContext || '', useResearch: useResearch, - isClaudeCode: isClaudeCode(useResearch, projectRoot), + hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot), projectRoot: projectRoot || '' }; diff --git a/scripts/modules/task-manager/expand-task.js b/scripts/modules/task-manager/expand-task.js index 27b22f91..648976ce 100644 --- a/scripts/modules/task-manager/expand-task.js +++ b/scripts/modules/task-manager/expand-task.js @@ -456,7 +456,10 @@ async function expandTask( const promptManager = getPromptManager(); // Check if a codebase analysis provider is being used - const hasCodebaseAnalysisCapability = hasCodebaseAnalysis(useResearch, projectRoot); + const hasCodebaseAnalysisCapability = hasCodebaseAnalysis( + useResearch, + projectRoot + ); // Combine all context sources into a single additionalContext parameter let combinedAdditionalContext = ''; diff --git a/scripts/modules/task-manager/parse-prd/parse-prd-config.js b/scripts/modules/task-manager/parse-prd/parse-prd-config.js index 139b4118..56afb8a8 100644 --- a/scripts/modules/task-manager/parse-prd/parse-prd-config.js +++ b/scripts/modules/task-manager/parse-prd/parse-prd-config.js @@ -6,8 +6,7 @@ import { z } from 'zod'; import { TASK_PRIORITY_OPTIONS } from '../../../../src/constants/task-priority.js'; import { getCurrentTag, isSilentMode, log } from '../../utils.js'; import { Duration } from '../../../../src/utils/timeout-manager.js'; -import { CUSTOM_PROVIDERS } from '../../../../src/constants/providers.js'; -import { getMainProvider, getResearchProvider, hasCodebaseAnalysis } from '../../config-manager.js'; +import { hasCodebaseAnalysis } from '../../config-manager.js'; // ============================================================================ // SCHEMAS diff --git a/scripts/modules/task-manager/parse-prd/parse-prd-helpers.js b/scripts/modules/task-manager/parse-prd/parse-prd-helpers.js index 996860af..65347aba 100644 --- a/scripts/modules/task-manager/parse-prd/parse-prd-helpers.js +++ b/scripts/modules/task-manager/parse-prd/parse-prd-helpers.js @@ -7,7 +7,6 @@ import path from 'path'; import boxen from 'boxen'; import chalk from 'chalk'; import { ensureTagMetadata, findTaskById } from '../../utils.js'; -import { getPriorityIndicators } from '../../../../src/ui/indicators.js'; import { displayParsePrdSummary } from '../../../../src/ui/parse-prd.js'; import { TimeoutManager } from '../../../../src/utils/timeout-manager.js'; import { displayAiUsageSummary } from '../../ui.js'; @@ -242,7 +241,7 @@ export async function buildPrompts(config, prdContent, nextId) { prdContent, prdPath: config.prdPath, defaultTaskPriority, - isClaudeCode: config.hasCodebaseAnalysis(), + hasCodebaseAnalysis: config.hasCodebaseAnalysis(), projectRoot: config.projectRoot || '' }); } diff --git a/src/prompts/analyze-complexity.json b/src/prompts/analyze-complexity.json index 45e1d512..d6e3fb34 100644 --- a/src/prompts/analyze-complexity.json +++ b/src/prompts/analyze-complexity.json @@ -31,7 +31,7 @@ "default": false, "description": "Use research mode for deeper analysis" }, - "isClaudeCode": { + "hasCodebaseAnalysis": { "type": "boolean", "default": false, "description": "Whether Claude Code is being used as the provider" @@ -45,7 +45,7 @@ "prompts": { "default": { "system": "You are an expert software architect and project manager analyzing task complexity. Respond only with the requested valid JSON array.", - "user": "{{#if isClaudeCode}}## IMPORTANT: Codebase Analysis Required\n\nYou have access to powerful codebase analysis tools. Before analyzing task complexity:\n\n1. Use the Glob tool to explore the project structure and understand the codebase size\n2. Use the Grep tool to search for existing implementations related to each task\n3. Use the Read tool to examine key files that would be affected by these tasks\n4. Understand the current implementation state, patterns used, and technical debt\n\nBased on your codebase analysis:\n- Assess complexity based on ACTUAL code that needs to be modified/created\n- Consider existing abstractions and patterns that could simplify implementation\n- Identify tasks that require refactoring vs. greenfield development\n- Factor in dependencies between existing code and new features\n- Provide more accurate subtask recommendations based on real code structure\n\nProject Root: {{projectRoot}}\n\n{{/if}}Analyze the following tasks to determine their complexity (1-10 scale) and recommend the number of subtasks for expansion. Provide a brief reasoning and an initial expansion prompt for each.{{#if useResearch}} Consider current best practices, common implementation patterns, and industry standards in your analysis.{{/if}}\n\nTasks:\n{{{json tasks}}}\n{{#if gatheredContext}}\n\n# Project Context\n\n{{gatheredContext}}\n{{/if}}\n\nRespond ONLY with a valid JSON array matching the schema:\n[\n {\n \"taskId\": ,\n \"taskTitle\": \"\",\n \"complexityScore\": ,\n \"recommendedSubtasks\": ,\n \"expansionPrompt\": \"\",\n \"reasoning\": \"\"\n },\n ...\n]\n\nDo not include any explanatory text, markdown formatting, or code block markers before or after the JSON array." + "user": "{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required\n\nYou have access to powerful codebase analysis tools. Before analyzing task complexity:\n\n1. Use the Glob tool to explore the project structure and understand the codebase size\n2. Use the Grep tool to search for existing implementations related to each task\n3. Use the Read tool to examine key files that would be affected by these tasks\n4. Understand the current implementation state, patterns used, and technical debt\n\nBased on your codebase analysis:\n- Assess complexity based on ACTUAL code that needs to be modified/created\n- Consider existing abstractions and patterns that could simplify implementation\n- Identify tasks that require refactoring vs. greenfield development\n- Factor in dependencies between existing code and new features\n- Provide more accurate subtask recommendations based on real code structure\n\nProject Root: {{projectRoot}}\n\n{{/if}}Analyze the following tasks to determine their complexity (1-10 scale) and recommend the number of subtasks for expansion. Provide a brief reasoning and an initial expansion prompt for each.{{#if useResearch}} Consider current best practices, common implementation patterns, and industry standards in your analysis.{{/if}}\n\nTasks:\n{{{json tasks}}}\n{{#if gatheredContext}}\n\n# Project Context\n\n{{gatheredContext}}\n{{/if}}\n\nRespond ONLY with a valid JSON array matching the schema:\n[\n {\n \"taskId\": ,\n \"taskTitle\": \"\",\n \"complexityScore\": ,\n \"recommendedSubtasks\": ,\n \"expansionPrompt\": \"\",\n \"reasoning\": \"\"\n },\n ...\n]\n\nDo not include any explanatory text, markdown formatting, or code block markers before or after the JSON array." } } } diff --git a/src/prompts/parse-prd.json b/src/prompts/parse-prd.json index 7c05996f..64645295 100644 --- a/src/prompts/parse-prd.json +++ b/src/prompts/parse-prd.json @@ -41,7 +41,7 @@ "enum": ["high", "medium", "low"], "description": "Default priority for generated tasks" }, - "isClaudeCode": { + "hasCodebaseAnalysis": { "type": "boolean", "required": false, "default": false, @@ -57,7 +57,7 @@ "prompts": { "default": { "system": "You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.{{#if research}}\nBefore breaking down the PRD into tasks, you will:\n1. Research and analyze the latest technologies, libraries, frameworks, and best practices that would be appropriate for this project\n2. Identify any potential technical challenges, security concerns, or scalability issues not explicitly mentioned in the PRD without discarding any explicit requirements or going overboard with complexity -- always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches\n3. Consider current industry standards and evolving trends relevant to this project (this step aims to solve LLM hallucinations and out of date information due to training data cutoff dates)\n4. Evaluate alternative implementation approaches and recommend the most efficient path\n5. Include specific library versions, helpful APIs, and concrete implementation guidance based on your research\n6. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches\n\nYour task breakdown should incorporate this research, resulting in more detailed implementation guidance, more accurate dependency mapping, and more precise technology recommendations than would be possible from the PRD text alone, while maintaining all explicit requirements and best practices and all details and nuances of the PRD.{{/if}}\n\nAnalyze the provided PRD content and generate {{#if (gt numTasks 0)}}approximately {{numTasks}}{{else}}an appropriate number of{{/if}} top-level development tasks. If the complexity or the level of detail of the PRD is high, generate more tasks relative to the complexity of the PRD\nEach task should represent a logical unit of work needed to implement the requirements and focus on the most direct and effective way to implement the requirements without unnecessary complexity or overengineering. Include pseudo-code, implementation details, and test strategy for each task. Find the most up to date information to implement each task.\nAssign sequential IDs starting from {{nextId}}. Infer title, description, details, and test strategy for each task based *only* on the PRD content.\nSet status to 'pending', dependencies to an empty array [], and priority to '{{defaultTaskPriority}}' initially for all tasks.\nRespond ONLY with a valid JSON object containing a single key \"tasks\", where the value is an array of task objects adhering to the provided Zod schema. Do not include any explanation or markdown formatting.\n\nEach task should follow this JSON structure:\n{\n\t\"id\": number,\n\t\"title\": string,\n\t\"description\": string,\n\t\"status\": \"pending\",\n\t\"dependencies\": number[] (IDs of tasks this depends on),\n\t\"priority\": \"high\" | \"medium\" | \"low\",\n\t\"details\": string (implementation details),\n\t\"testStrategy\": string (validation approach)\n}\n\nGuidelines:\n1. {{#if (gt numTasks 0)}}Unless complexity warrants otherwise{{else}}Depending on the complexity{{/if}}, create {{#if (gt numTasks 0)}}exactly {{numTasks}}{{else}}an appropriate number of{{/if}} tasks, numbered sequentially starting from {{nextId}}\n2. Each task should be atomic and focused on a single responsibility following the most up to date best practices and standards\n3. Order tasks logically - consider dependencies and implementation sequence\n4. Early tasks should focus on setup, core functionality first, then advanced features\n5. Include clear validation/testing approach for each task\n6. Set appropriate dependency IDs (a task can only depend on tasks with lower IDs, potentially including existing tasks with IDs less than {{nextId}} if applicable)\n7. Assign priority (high/medium/low) based on criticality and dependency order\n8. Include detailed implementation guidance in the \"details\" field{{#if research}}, with specific libraries and version recommendations based on your research{{/if}}\n9. If the PRD contains specific requirements for libraries, database schemas, frameworks, tech stacks, or any other implementation details, STRICTLY ADHERE to these requirements in your task breakdown and do not discard them under any circumstance\n10. Focus on filling in any gaps left by the PRD or areas that aren't fully specified, while preserving all explicit requirements\n11. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches{{#if research}}\n12. For each task, include specific, actionable guidance based on current industry standards and best practices discovered through research{{/if}}", - "user": "{{#if isClaudeCode}}## IMPORTANT: Codebase Analysis Required\n\nYou have access to powerful codebase analysis tools. Before generating tasks:\n\n1. Use the Glob tool to explore the project structure (e.g., \"**/*.js\", \"**/*.json\", \"**/README.md\")\n2. Use the Grep tool to search for existing implementations, patterns, and technologies\n3. Use the Read tool to examine key files like package.json, README.md, and main entry points\n4. Analyze the current state of implementation to understand what already exists\n\nBased on your analysis:\n- Identify what components/features are already implemented\n- Understand the technology stack, frameworks, and patterns in use\n- Generate tasks that build upon the existing codebase rather than duplicating work\n- Ensure tasks align with the project's current architecture and conventions\n\nProject Root: {{projectRoot}}\n\n{{/if}}Here's the Product Requirements Document (PRD) to break down into {{#if (gt numTasks 0)}}approximately {{numTasks}}{{else}}an appropriate number of{{/if}} tasks, starting IDs from {{nextId}}:{{#if research}}\n\nRemember to thoroughly research current best practices and technologies before task breakdown to provide specific, actionable implementation details.{{/if}}\n\n{{prdContent}}\n\n\n\t\tReturn your response in this format:\n{\n \"tasks\": [\n {\n \"id\": 1,\n \"title\": \"Setup Project Repository\",\n \"description\": \"...\",\n ...\n },\n ...\n ],\n \"metadata\": {\n \"projectName\": \"PRD Implementation\",\n \"totalTasks\": {{#if (gt numTasks 0)}}{{numTasks}}{{else}}{number of tasks}{{/if}},\n \"sourceFile\": \"{{prdPath}}\",\n \"generatedAt\": \"YYYY-MM-DD\"\n }\n}" + "user": "{{#if hasCodebaseAnalysis}}## IMPORTANT: Codebase Analysis Required\n\nYou have access to powerful codebase analysis tools. Before generating tasks:\n\n1. Use the Glob tool to explore the project structure (e.g., \"**/*.js\", \"**/*.json\", \"**/README.md\")\n2. Use the Grep tool to search for existing implementations, patterns, and technologies\n3. Use the Read tool to examine key files like package.json, README.md, and main entry points\n4. Analyze the current state of implementation to understand what already exists\n\nBased on your analysis:\n- Identify what components/features are already implemented\n- Understand the technology stack, frameworks, and patterns in use\n- Generate tasks that build upon the existing codebase rather than duplicating work\n- Ensure tasks align with the project's current architecture and conventions\n\nProject Root: {{projectRoot}}\n\n{{/if}}Here's the Product Requirements Document (PRD) to break down into {{#if (gt numTasks 0)}}approximately {{numTasks}}{{else}}an appropriate number of{{/if}} tasks, starting IDs from {{nextId}}:{{#if research}}\n\nRemember to thoroughly research current best practices and technologies before task breakdown to provide specific, actionable implementation details.{{/if}}\n\n{{prdContent}}\n\n\n\t\tReturn your response in this format:\n{\n \"tasks\": [\n {\n \"id\": 1,\n \"title\": \"Setup Project Repository\",\n \"description\": \"...\",\n ...\n },\n ...\n ],\n \"metadata\": {\n \"projectName\": \"PRD Implementation\",\n \"totalTasks\": {{#if (gt numTasks 0)}}{{numTasks}}{{else}}{number of tasks}{{/if}},\n \"sourceFile\": \"{{prdPath}}\",\n \"generatedAt\": \"YYYY-MM-DD\"\n }\n}" } } } diff --git a/tests/unit/parse-prd.test.js b/tests/unit/parse-prd.test.js index e5f6bff6..2a71f937 100644 --- a/tests/unit/parse-prd.test.js +++ b/tests/unit/parse-prd.test.js @@ -52,7 +52,8 @@ jest.unstable_mockModule('../../scripts/modules/config-manager.js', () => ({ VALID_PROVIDERS: ['anthropic', 'perplexity'], validateProvider: jest.fn(() => true), validateProviderModelCombination: jest.fn(() => true), - isApiKeySet: jest.fn(() => true) + isApiKeySet: jest.fn(() => true), + hasCodebaseAnalysis: jest.fn(() => false) })); // Mock utils comprehensively to prevent CLI behavior diff --git a/tests/unit/scripts/modules/task-manager/add-task.test.js b/tests/unit/scripts/modules/task-manager/add-task.test.js index 428b6788..a6a19dac 100644 --- a/tests/unit/scripts/modules/task-manager/add-task.test.js +++ b/tests/unit/scripts/modules/task-manager/add-task.test.js @@ -2,6 +2,7 @@ * Tests for the add-task.js module */ import { jest } from '@jest/globals'; +import { hasCodebaseAnalysis } from '../../../../../scripts/modules/config-manager.js'; // Mock the dependencies before importing the module under test jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({ @@ -100,7 +101,7 @@ jest.unstable_mockModule( '../../../../../scripts/modules/config-manager.js', () => ({ getDefaultPriority: jest.fn(() => 'medium'), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/analyze-task-complexity.test.js b/tests/unit/scripts/modules/task-manager/analyze-task-complexity.test.js index 9b6e0d06..8da3b8c7 100644 --- a/tests/unit/scripts/modules/task-manager/analyze-task-complexity.test.js +++ b/tests/unit/scripts/modules/task-manager/analyze-task-complexity.test.js @@ -6,6 +6,7 @@ import { createGetTagAwareFilePathMock, createSlugifyTagForFilePathMock } from './setup.js'; +import { hasCodebaseAnalysis } from '../../../../../scripts/modules/config-manager.js'; // Mock the dependencies before importing the module under test jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({ @@ -188,7 +189,7 @@ jest.unstable_mockModule( getAllProviders: jest.fn(() => ['anthropic', 'openai', 'perplexity']), getVertexProjectId: jest.fn(() => undefined), getVertexLocation: jest.fn(() => undefined), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/complexity-report-tag-isolation.test.js b/tests/unit/scripts/modules/task-manager/complexity-report-tag-isolation.test.js index 9267759c..959d1607 100644 --- a/tests/unit/scripts/modules/task-manager/complexity-report-tag-isolation.test.js +++ b/tests/unit/scripts/modules/task-manager/complexity-report-tag-isolation.test.js @@ -6,6 +6,7 @@ import { jest } from '@jest/globals'; import fs from 'fs'; import path from 'path'; +import { hasCodebaseAnalysis } from '../../../../../scripts/modules/config-manager.js'; // Mock the dependencies jest.unstable_mockModule('../../../../../src/utils/path-utils.js', () => ({ @@ -302,7 +303,7 @@ jest.unstable_mockModule( getAllProviders: jest.fn(() => ['anthropic', 'openai', 'perplexity']), getVertexProjectId: jest.fn(() => undefined), getVertexLocation: jest.fn(() => undefined), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/expand-task.test.js b/tests/unit/scripts/modules/task-manager/expand-task.test.js index 3f1949e4..9a5c49b7 100644 --- a/tests/unit/scripts/modules/task-manager/expand-task.test.js +++ b/tests/unit/scripts/modules/task-manager/expand-task.test.js @@ -125,7 +125,8 @@ jest.unstable_mockModule( getDebugFlag: jest.fn(() => false), getDefaultNumTasks: jest.fn(() => 10), getMainProvider: jest.fn(() => 'openai'), - getResearchProvider: jest.fn(() => 'perplexity') + getResearchProvider: jest.fn(() => 'perplexity'), + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/parse-prd.test.js b/tests/unit/scripts/modules/task-manager/parse-prd.test.js index 4045ebe7..17d64e7e 100644 --- a/tests/unit/scripts/modules/task-manager/parse-prd.test.js +++ b/tests/unit/scripts/modules/task-manager/parse-prd.test.js @@ -187,7 +187,8 @@ jest.unstable_mockModule( getDefaultNumTasks: jest.fn(() => 10), getDefaultPriority: jest.fn(() => 'medium'), getMainProvider: jest.fn(() => 'openai'), - getResearchProvider: jest.fn(() => 'perplexity') + getResearchProvider: jest.fn(() => 'perplexity'), + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/update-subtask-by-id.test.js b/tests/unit/scripts/modules/task-manager/update-subtask-by-id.test.js index 915c2bbb..f3dfe5f0 100644 --- a/tests/unit/scripts/modules/task-manager/update-subtask-by-id.test.js +++ b/tests/unit/scripts/modules/task-manager/update-subtask-by-id.test.js @@ -53,7 +53,7 @@ jest.unstable_mockModule( '../../../../../scripts/modules/config-manager.js', () => ({ getDebugFlag: jest.fn(() => false), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/update-task-by-id.test.js b/tests/unit/scripts/modules/task-manager/update-task-by-id.test.js index 2a9dfe68..a7dac156 100644 --- a/tests/unit/scripts/modules/task-manager/update-task-by-id.test.js +++ b/tests/unit/scripts/modules/task-manager/update-task-by-id.test.js @@ -52,7 +52,7 @@ jest.unstable_mockModule( () => ({ getDebugFlag: jest.fn(() => false), isApiKeySet: jest.fn(() => true), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) ); diff --git a/tests/unit/scripts/modules/task-manager/update-tasks.test.js b/tests/unit/scripts/modules/task-manager/update-tasks.test.js index 6296c9d9..a3e7fa7e 100644 --- a/tests/unit/scripts/modules/task-manager/update-tasks.test.js +++ b/tests/unit/scripts/modules/task-manager/update-tasks.test.js @@ -45,7 +45,7 @@ jest.unstable_mockModule( '../../../../../scripts/modules/config-manager.js', () => ({ getDebugFlag: jest.fn(() => false), - isClaudeCode: jest.fn(() => false) + hasCodebaseAnalysis: jest.fn(() => false) }) );