From 4357af3f13859d90bca8795215e5d5f1d94abde5 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Wed, 6 Aug 2025 22:00:32 +0300 Subject: [PATCH] fix(expand-task): include parent task context in complexity report variant (#1094) - Fixed bug where expand task generated generic authentication subtasks - The complexity-report prompt variant now includes parent task details - Added comprehensive unit tests to prevent regression - Added debug logging to help diagnose similar issues Previously, when using a complexity report with expansionPrompt, only the expansion guidance was sent to the AI, missing the actual task context. This caused the AI to generate unrelated generic subtasks. Fixes the issue where all tasks would get the same generic auth-related subtasks regardless of their actual purpose (AWS infrastructure, Docker containerization, etc.) Co-authored-by: Sadaqat Ali <32377500+sadaqat12@users.noreply.github.com> --- .changeset/fuzzy-brooms-mate.md | 7 + scripts/modules/task-manager/expand-task.js | 12 ++ src/prompts/expand-task.json | 2 +- tests/unit/prompts/expand-task-prompt.test.js | 134 ++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 .changeset/fuzzy-brooms-mate.md create mode 100644 tests/unit/prompts/expand-task-prompt.test.js diff --git a/.changeset/fuzzy-brooms-mate.md b/.changeset/fuzzy-brooms-mate.md new file mode 100644 index 00000000..f6f502c2 --- /dev/null +++ b/.changeset/fuzzy-brooms-mate.md @@ -0,0 +1,7 @@ +--- +"task-master-ai": patch +--- + +Fix expand task generating unrelated generic subtasks + +Fixed an issue where `task-master expand` would generate generic authentication-related subtasks regardless of the parent task context when using complexity reports. The expansion now properly includes the parent task details alongside any expansion guidance. diff --git a/scripts/modules/task-manager/expand-task.js b/scripts/modules/task-manager/expand-task.js index ec55f3d4..26db1b9d 100644 --- a/scripts/modules/task-manager/expand-task.js +++ b/scripts/modules/task-manager/expand-task.js @@ -527,6 +527,18 @@ async function expandTask( const { systemPrompt, userPrompt: promptContent } = await promptManager.loadPrompt('expand-task', promptParams, variantKey); + + // Debug logging to identify the issue + logger.debug(`Selected variant: ${variantKey}`); + logger.debug( + `Prompt params passed: ${JSON.stringify(promptParams, null, 2)}` + ); + logger.debug( + `System prompt (first 500 chars): ${systemPrompt.substring(0, 500)}...` + ); + logger.debug( + `User prompt (first 500 chars): ${promptContent.substring(0, 500)}...` + ); // --- End Complexity Report / Prompt Logic --- // --- AI Subtask Generation using generateTextService --- diff --git a/src/prompts/expand-task.json b/src/prompts/expand-task.json index e782762b..9eaa457a 100644 --- a/src/prompts/expand-task.json +++ b/src/prompts/expand-task.json @@ -69,7 +69,7 @@ "complexity-report": { "condition": "expansionPrompt", "system": "You are an AI assistant helping with task breakdown. Generate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks based on the provided prompt and context.\nRespond ONLY with a valid JSON object containing a single key \"subtasks\" whose value is an array of the generated subtask objects.\nEach subtask object in the array must have keys: \"id\", \"title\", \"description\", \"dependencies\", \"details\", \"status\".\nEnsure the 'id' starts from {{nextSubtaskId}} and is sequential.\nFor 'dependencies', use the full subtask ID format: \"{{task.id}}.1\", \"{{task.id}}.2\", etc. Only reference subtasks within this same task.\nEnsure 'status' is 'pending'.\nDo not include any other text or explanation.", - "user": "{{#if isClaudeCode}}## IMPORTANT: Codebase Analysis Required\n\nYou have access to powerful codebase analysis tools. Before generating subtasks:\n\n1. Use the Glob tool to explore relevant files for this task (e.g., \"**/*.js\", \"src/**/*.ts\")\n2. Use the Grep tool to search for existing implementations related to this task\n3. Use the Read tool to examine files that would be affected by this task\n4. Understand the current implementation state and patterns used\n\nBased on your analysis:\n- Identify existing code that relates to this task\n- Understand patterns and conventions to follow\n- Generate subtasks that integrate smoothly with existing code\n- Ensure subtasks are specific and actionable based on the actual codebase\n\nProject Root: {{projectRoot}}\n\n{{/if}}{{expansionPrompt}}{{#if additionalContext}}\n\n{{additionalContext}}{{/if}}{{#if complexityReasoningContext}}\n\n{{complexityReasoningContext}}{{/if}}{{#if gatheredContext}}\n\n# Project Context\n\n{{gatheredContext}}{{/if}}" + "user": "Break down the following task based on the analysis prompt:\n\nParent Task:\nID: {{task.id}}\nTitle: {{task.title}}\nDescription: {{task.description}}\nCurrent details: {{#if task.details}}{{task.details}}{{else}}None{{/if}}\n\nExpansion Guidance:\n{{expansionPrompt}}{{#if additionalContext}}\n\n{{additionalContext}}{{/if}}{{#if complexityReasoningContext}}\n\n{{complexityReasoningContext}}{{/if}}{{#if gatheredContext}}\n\n# Project Context\n\n{{gatheredContext}}{{/if}}\n\nGenerate {{#if (gt subtaskCount 0)}}exactly {{subtaskCount}}{{else}}an appropriate number of{{/if}} subtasks with sequential IDs starting from {{nextSubtaskId}}." }, "research": { "condition": "useResearch === true && !expansionPrompt", diff --git a/tests/unit/prompts/expand-task-prompt.test.js b/tests/unit/prompts/expand-task-prompt.test.js new file mode 100644 index 00000000..7d68a75a --- /dev/null +++ b/tests/unit/prompts/expand-task-prompt.test.js @@ -0,0 +1,134 @@ +import { jest } from '@jest/globals'; +import { PromptManager } from '../../../scripts/modules/prompt-manager.js'; + +describe('expand-task prompt template', () => { + let promptManager; + + beforeEach(() => { + promptManager = new PromptManager(); + }); + + const testTask = { + id: 1, + title: 'Setup AWS Infrastructure', + description: 'Provision core AWS services', + details: 'Create VPC, subnets, and security groups' + }; + + const baseParams = { + task: testTask, + subtaskCount: 3, + nextSubtaskId: 1, + additionalContext: '', + complexityReasoningContext: '', + gatheredContext: '', + useResearch: false, + expansionPrompt: undefined + }; + + test('default variant includes task context', () => { + const { userPrompt } = promptManager.loadPrompt( + 'expand-task', + baseParams, + 'default' + ); + + expect(userPrompt).toContain(testTask.title); + expect(userPrompt).toContain(testTask.description); + expect(userPrompt).toContain(testTask.details); + expect(userPrompt).toContain('Task ID: 1'); + }); + + test('research variant includes task context', () => { + const params = { ...baseParams, useResearch: true }; + const { userPrompt } = promptManager.loadPrompt( + 'expand-task', + params, + 'research' + ); + + expect(userPrompt).toContain(testTask.title); + expect(userPrompt).toContain(testTask.description); + expect(userPrompt).toContain(testTask.details); + expect(userPrompt).toContain('Parent Task:'); + expect(userPrompt).toContain('ID: 1'); + }); + + test('complexity-report variant includes task context', () => { + const params = { + ...baseParams, + expansionPrompt: 'Focus on security best practices', + complexityReasoningContext: 'High complexity due to security requirements' + }; + const { userPrompt } = promptManager.loadPrompt( + 'expand-task', + params, + 'complexity-report' + ); + + // The fix ensures task context is included + expect(userPrompt).toContain('Parent Task:'); + expect(userPrompt).toContain(`ID: ${testTask.id}`); + expect(userPrompt).toContain(`Title: ${testTask.title}`); + expect(userPrompt).toContain(`Description: ${testTask.description}`); + expect(userPrompt).toContain(`Current details: ${testTask.details}`); + + // Also includes the expansion prompt + expect(userPrompt).toContain('Expansion Guidance:'); + expect(userPrompt).toContain(params.expansionPrompt); + expect(userPrompt).toContain(params.complexityReasoningContext); + }); + + test('all variants request JSON format with subtasks array', () => { + const variants = ['default', 'research', 'complexity-report']; + + variants.forEach((variant) => { + const params = + variant === 'complexity-report' + ? { ...baseParams, expansionPrompt: 'test' } + : baseParams; + + const { systemPrompt, userPrompt } = promptManager.loadPrompt( + 'expand-task', + params, + variant + ); + const combined = systemPrompt + userPrompt; + + expect(combined.toLowerCase()).toContain('subtasks'); + expect(combined).toContain('JSON'); + }); + }); + + test('complexity-report variant fails without task context regression test', () => { + // This test ensures we don't regress to the old behavior where + // complexity-report variant only used expansionPrompt without task context + const params = { + ...baseParams, + expansionPrompt: 'Generic expansion prompt' + }; + + const { userPrompt } = promptManager.loadPrompt( + 'expand-task', + params, + 'complexity-report' + ); + + // Count occurrences of task-specific content + const titleOccurrences = ( + userPrompt.match(new RegExp(testTask.title, 'g')) || [] + ).length; + const descriptionOccurrences = ( + userPrompt.match(new RegExp(testTask.description, 'g')) || [] + ).length; + + // Should have at least one occurrence of title and description + expect(titleOccurrences).toBeGreaterThanOrEqual(1); + expect(descriptionOccurrences).toBeGreaterThanOrEqual(1); + + // Should not be ONLY the expansion prompt + expect(userPrompt.length).toBeGreaterThan( + params.expansionPrompt.length + 100 + ); + }); +});