fix: resolve path resolution and context gathering errors across multiple commands#954
Conversation
…ty commands This commit fixes critical path resolution regressions where commands were requiring files they create to already exist. ## Changes Made: ### 1. parse-prd Command (Lines 808, 828-835, 919-921) **Problem**: Command required tasks.json to exist before it could create it (catch-22) **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (line 808) - Modified initTaskMaster to only include tasksPath when explicitly specified - Added null handling for output path with fallback to default location ### 2. analyze-complexity Command (Lines 1637-1640, 1673-1680, 1695-1696) **Problem**: Command required complexity report file to exist before creating it **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (lines 1637-1640) - Modified initTaskMaster to only include complexityReportPath when explicitly specified - Added null handling for report path with fallback to default location ## Technical Details: The core issue was that Commander.js option definitions with default values always populate the options object, making conditional checks like `if (options.output)` always true. By removing default values from option definitions, we ensure paths are only included in initTaskMaster when users explicitly provide them. This approach is cleaner than using boolean flags (true/false) for required/optional, as it eliminates the path entirely when not needed, letting initTaskMaster use its default behavior. ## Testing: - parse-prd now works on fresh projects without existing tasks.json - analyze-complexity creates report file without requiring it to exist - Commands maintain backward compatibility when paths are explicitly provided Fixes issues reported in PATH-FIXES.md and extends the solution to other affected commands.
|
CI Fix: Updated test mock to match implementationDuring CI testing, discovered that the Changes made:
This ensures the test accurately reflects the actual implementation behavior after our context gathering fixes. Commit: f7337c8 |
Crunchyman-ralph
left a comment
There was a problem hiding this comment.
lgtm, but have small nitpicks
| const { systemPrompt, userPrompt: prompt } = await promptManager.loadPrompt( | ||
| 'analyze-complexity', | ||
| promptParams, | ||
| variantKey |
There was a problem hiding this comment.
why are we changing it here ?
There was a problem hiding this comment.
The code was looking for a separate 'research' prompt variant that doesn't exist. The --research functionality is actually built into the default prompt using template conditionals ({{#if useResearch}}), so we should always use the 'default' variant and pass useResearch as a parameter, which we already do correctly on line 406.
There's no need to pass useResearch in both promptParams and variantKey, especially if there is no 'research' variant defined.
Passing the variantKey causes the command to fail - probably a separate issue that should be better handled when a key is missing, but I'm trying to limit the scope of this PR and just get 'next' working again after all of these regression issues caused by recent merges.
The Prompt File Structure
The analyze-complexity.json prompt file only defines a 'default' variant (line 36). There is no 'research' variant defined.
How It Actually Works
Looking at line 38, the prompt uses a conditional template: {{#if useResearch}} Consider current best practices, common implementation patterns, and industry standards in your analysis.{{/if}}
This means the --research flag is handled within the default prompt by adding extra instructions when useResearch is true. It doesn't need a separate 'research' variant.
The Bug
The code was incorrectly trying to load a separate 'research' variant:
const variantKey = useResearch ? 'research' : 'default';
But since only 'default' exists, it should always use 'default' and let the prompt template handle the research mode internally.
The test was expecting gatheredContext to be a string, but the actual implementation returns an object with a context property. Updated the ContextGatherer mock to return the correct format and added missing FuzzyTaskSearch mock.
f7337c8 to
a886833
Compare
…iple commands (eyaltoledano#954) * fix: resolve path resolution issues in parse-prd and analyze-complexity commands This commit fixes critical path resolution regressions where commands were requiring files they create to already exist. ## Changes Made: ### 1. parse-prd Command (Lines 808, 828-835, 919-921) **Problem**: Command required tasks.json to exist before it could create it (catch-22) **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (line 808) - Modified initTaskMaster to only include tasksPath when explicitly specified - Added null handling for output path with fallback to default location ### 2. analyze-complexity Command (Lines 1637-1640, 1673-1680, 1695-1696) **Problem**: Command required complexity report file to exist before creating it **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (lines 1637-1640) - Modified initTaskMaster to only include complexityReportPath when explicitly specified - Added null handling for report path with fallback to default location ## Technical Details: The core issue was that Commander.js option definitions with default values always populate the options object, making conditional checks like `if (options.output)` always true. By removing default values from option definitions, we ensure paths are only included in initTaskMaster when users explicitly provide them. This approach is cleaner than using boolean flags (true/false) for required/optional, as it eliminates the path entirely when not needed, letting initTaskMaster use its default behavior. ## Testing: - parse-prd now works on fresh projects without existing tasks.json - analyze-complexity creates report file without requiring it to exist - Commands maintain backward compatibility when paths are explicitly provided Fixes issues reported in PATH-FIXES.md and extends the solution to other affected commands. * fix: update expand-task test to match context gathering fix The test was expecting gatheredContext to be a string, but the actual implementation returns an object with a context property. Updated the ContextGatherer mock to return the correct format and added missing FuzzyTaskSearch mock. --------- Co-authored-by: Ben Vargas <ben@example.com>
…iple commands (eyaltoledano#954) * fix: resolve path resolution issues in parse-prd and analyze-complexity commands This commit fixes critical path resolution regressions where commands were requiring files they create to already exist. ## Changes Made: ### 1. parse-prd Command (Lines 808, 828-835, 919-921) **Problem**: Command required tasks.json to exist before it could create it (catch-22) **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (line 808) - Modified initTaskMaster to only include tasksPath when explicitly specified - Added null handling for output path with fallback to default location ### 2. analyze-complexity Command (Lines 1637-1640, 1673-1680, 1695-1696) **Problem**: Command required complexity report file to exist before creating it **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (lines 1637-1640) - Modified initTaskMaster to only include complexityReportPath when explicitly specified - Added null handling for report path with fallback to default location ## Technical Details: The core issue was that Commander.js option definitions with default values always populate the options object, making conditional checks like `if (options.output)` always true. By removing default values from option definitions, we ensure paths are only included in initTaskMaster when users explicitly provide them. This approach is cleaner than using boolean flags (true/false) for required/optional, as it eliminates the path entirely when not needed, letting initTaskMaster use its default behavior. ## Testing: - parse-prd now works on fresh projects without existing tasks.json - analyze-complexity creates report file without requiring it to exist - Commands maintain backward compatibility when paths are explicitly provided Fixes issues reported in PATH-FIXES.md and extends the solution to other affected commands. * fix: update expand-task test to match context gathering fix The test was expecting gatheredContext to be a string, but the actual implementation returns an object with a context property. Updated the ContextGatherer mock to return the correct format and added missing FuzzyTaskSearch mock. --------- Co-authored-by: Ben Vargas <ben@example.com>
…iple commands (eyaltoledano#954) * fix: resolve path resolution issues in parse-prd and analyze-complexity commands This commit fixes critical path resolution regressions where commands were requiring files they create to already exist. ## Changes Made: ### 1. parse-prd Command (Lines 808, 828-835, 919-921) **Problem**: Command required tasks.json to exist before it could create it (catch-22) **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (line 808) - Modified initTaskMaster to only include tasksPath when explicitly specified - Added null handling for output path with fallback to default location ### 2. analyze-complexity Command (Lines 1637-1640, 1673-1680, 1695-1696) **Problem**: Command required complexity report file to exist before creating it **Root Cause**: Default value in option definition meant options.output was always set **Fixes**: - Removed default value from --output option definition (lines 1637-1640) - Modified initTaskMaster to only include complexityReportPath when explicitly specified - Added null handling for report path with fallback to default location ## Technical Details: The core issue was that Commander.js option definitions with default values always populate the options object, making conditional checks like `if (options.output)` always true. By removing default values from option definitions, we ensure paths are only included in initTaskMaster when users explicitly provide them. This approach is cleaner than using boolean flags (true/false) for required/optional, as it eliminates the path entirely when not needed, letting initTaskMaster use its default behavior. ## Testing: - parse-prd now works on fresh projects without existing tasks.json - analyze-complexity creates report file without requiring it to exist - Commands maintain backward compatibility when paths are explicitly provided Fixes issues reported in PATH-FIXES.md and extends the solution to other affected commands. * fix: update expand-task test to match context gathering fix The test was expecting gatheredContext to be a string, but the actual implementation returns an object with a context property. Updated the ContextGatherer mock to return the correct format and added missing FuzzyTaskSearch mock. --------- Co-authored-by: Ben Vargas <ben@example.com>
Summary
This PR fixes critical path resolution issues and context gathering errors that were preventing multiple commands from functioning properly. The fixes ensure commands can create their output files without requiring them to exist first, and properly handle context gathering results across the codebase.
Problem Description
1. Path Resolution Issues
Commands like
parse-prdandanalyze-complexitywere failing with "override path does not exist" errors because they required their output files to exist before they could create them - a classic catch-22 situation.2. Context Gathering Errors
Multiple commands were failing with "Parameter 'gatheredContext' expected string, got object" errors due to incorrect handling of the contextGatherer.gather() return value.
3. Prompt Variant Errors
The
analyze-complexitycommand was attempting to load a non-existent 'research' variant, causing runtime failures.Changes Made
1. scripts/modules/commands.js
parse-prd Command (Lines 808, 828-835, 919-921)
Why: The default value in the option definition meant
options.outputwas ALWAYS populated, making our conditional checkif (options.output)always true.Why: Only include tasksPath when explicitly specified by the user, allowing the command to work without requiring the output file to exist.
Why: Provides a fallback when getTasksPath() returns null, ensuring the command can always determine where to write output.
analyze-complexity Command (Lines 1637-1640, 1673-1680, 1695-1696)
Similar changes as parse-prd:
2. scripts/modules/task-manager/analyze-task-complexity.js
Context Gathering Fix (Line 243)
Why: contextGatherer.gather() returns an object with multiple properties, not just a string. We need to extract the
contextproperty.Prompt Variant Fix (Lines 409-413)
Why: The analyze-complexity prompt only has a 'default' variant. The conditional logic for research mode is handled within the prompt template itself using handlebars conditions.
3. Context Gathering Fixes in Multiple Files
Fixed the same context gathering issue in:
All changed from:
To:
Why This Approach Over "|| false"
The original PATH-FIXES.md suggested using
|| falseto make paths optional:Our approach is superior because:
Clearer Intent: We only include parameters that are actually needed, rather than passing boolean flags that initTaskMaster must interpret.
Avoids Boolean Confusion: The boolean approach (true = required, false = optional) is not intuitive and prone to errors.
More Explicit: The code clearly shows "only use this path if the user provided it" rather than relying on boolean interpretation.
Aligns with Best Practices: The PATH-FIXES.md itself identified "Boolean Parameters Are Dangerous" in its lessons learned.
Cleaner API: By not including unnecessary parameters, we keep the initTaskMaster calls cleaner and more maintainable.
Testing
All commands now work properly:
tm parse-prdcreates tasks.json without requiring it to existtm analyze-complexitycreates the report file without requiring it to existtm expand --allproperly expands tasks with context gatheringImpact
This PR fixes critical functionality issues that were preventing normal use of the task-master CLI. The changes are backward compatible and only affect the internal handling of paths and context data.