Files
claude-task-master/.cursor/rules/dependencies.mdc
Eyal Toledano 633a5b963e Refactor: Modularize Task Master CLI into Modules Directory
Simplified the Task Master CLI by organizing code into modules within the  directory.

**Why:**

- **Better Organization:** Code is now grouped by function (AI, commands, dependencies, tasks, UI, utilities).
- **Easier to Maintain:**  Smaller modules are simpler to update and fix.
- **Scalable:**  New features can be added more easily in a structured way.

**What Changed:**

- Moved code from single   _____         _      __  __           _
 |_   _|_ _ ___| | __ |  \/  | __ _ ___| |_ ___ _ __
   | |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
   | | (_| \__ \   <  | |  | | (_| \__ \ ||  __/ |
   |_|\__,_|___/_|\_\ |_|  |_|\__,_|___/\__\___|_|

by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│                                            │
│   Version: 0.9.16   Project: Task Master   │
│                                            │
╰────────────────────────────────────────────╯

╭─────────────────────╮
│                     │
│   Task Master CLI   │
│                     │
╰─────────────────────╯

╭───────────────────╮
│  Task Generation  │
╰───────────────────╯
    parse-prd                 --input=<file.txt> [--tasks=10]          Generate tasks from a PRD document
    generate                                                           Create individual task files from tasks…

╭───────────────────╮
│  Task Management  │
╰───────────────────╯
    list                      [--status=<status>] [--with-subtas…      List all tasks with their status
    set-status                --id=<id> --status=<status>              Update task status (done, pending, etc.)
    update                    --from=<id> --prompt="<context>"         Update tasks based on new requirements
    add-task                  --prompt="<text>" [--dependencies=…      Add a new task using AI
    add-dependency            --id=<id> --depends-on=<id>              Add a dependency to a task
    remove-dependency         --id=<id> --depends-on=<id>              Remove a dependency from a task

╭──────────────────────────╮
│  Task Analysis & Detail  │
╰──────────────────────────╯
    analyze-complexity        [--research] [--threshold=5]             Analyze tasks and generate expansion re…
    complexity-report         [--file=<path>]                          Display the complexity analysis report
    expand                    --id=<id> [--num=5] [--research] […      Break down tasks into detailed subtasks
    expand --all              [--force] [--research]                   Expand all pending tasks with subtasks
    clear-subtasks            --id=<id>                                Remove subtasks from specified tasks

╭─────────────────────────────╮
│  Task Navigation & Viewing  │
╰─────────────────────────────╯
    next                                                               Show the next task to work on based on …
    show                      <id>                                     Display detailed information about a sp…

╭─────────────────────────╮
│  Dependency Management  │
╰─────────────────────────╯
    validate-dependenci…                                               Identify invalid dependencies without f…
    fix-dependencies                                                   Fix invalid dependencies automatically

╭─────────────────────────╮
│  Environment Variables  │
╰─────────────────────────╯
    ANTHROPIC_API_KEY              Your Anthropic API key                             Required
    MODEL                          Claude model to use                                Default: claude-3-7-sonn…
    MAX_TOKENS                     Maximum tokens for responses                       Default: 4000
    TEMPERATURE                    Temperature for model responses                    Default: 0.7
    PERPLEXITY_API_KEY             Perplexity API key for research                    Optional
    PERPLEXITY_MODEL               Perplexity model to use                            Default: sonar-small-onl…
    DEBUG                          Enable debug logging                               Default: false
    LOG_LEVEL                      Console output level (debug,info,warn,error)       Default: info
    DEFAULT_SUBTASKS               Default number of subtasks to generate             Default: 3
    DEFAULT_PRIORITY               Default task priority                              Default: medium
    PROJECT_NAME                   Project name displayed in UI                       Default: Task Master       file into these new modules:
    - : AI interactions (Claude, Perplexity)
    - :  CLI command definitions (Commander.js)
    - : Task dependency handling
    - : Core task operations (create, list, update, etc.)
    - : User interface elements (display, formatting)
    - : Utility functions and configuration
    - :  Exports all modules
- Replaced direct use of   _____         _      __  __           _
 |_   _|_ _ ___| | __ |  \/  | __ _ ___| |_ ___ _ __
   | |/ _` / __| |/ / | |\/| |/ _` / __| __/ _ \ '__|
   | | (_| \__ \   <  | |  | | (_| \__ \ ||  __/ |
   |_|\__,_|___/_|\_\ |_|  |_|\__,_|___/\__\___|_|

by https://x.com/eyaltoledano
╭────────────────────────────────────────────╮
│                                            │
│   Version: 0.9.16   Project: Task Master   │
│                                            │
╰────────────────────────────────────────────╯

╭─────────────────────╮
│                     │
│   Task Master CLI   │
│                     │
╰─────────────────────╯

╭───────────────────╮
│  Task Generation  │
╰───────────────────╯
    parse-prd                 --input=<file.txt> [--tasks=10]          Generate tasks from a PRD document
    generate                                                           Create individual task files from tasks…

╭───────────────────╮
│  Task Management  │
╰───────────────────╯
    list                      [--status=<status>] [--with-subtas…      List all tasks with their status
    set-status                --id=<id> --status=<status>              Update task status (done, pending, etc.)
    update                    --from=<id> --prompt="<context>"         Update tasks based on new requirements
    add-task                  --prompt="<text>" [--dependencies=…      Add a new task using AI
    add-dependency            --id=<id> --depends-on=<id>              Add a dependency to a task
    remove-dependency         --id=<id> --depends-on=<id>              Remove a dependency from a task

╭──────────────────────────╮
│  Task Analysis & Detail  │
╰──────────────────────────╯
    analyze-complexity        [--research] [--threshold=5]             Analyze tasks and generate expansion re…
    complexity-report         [--file=<path>]                          Display the complexity analysis report
    expand                    --id=<id> [--num=5] [--research] […      Break down tasks into detailed subtasks
    expand --all              [--force] [--research]                   Expand all pending tasks with subtasks
    clear-subtasks            --id=<id>                                Remove subtasks from specified tasks

╭─────────────────────────────╮
│  Task Navigation & Viewing  │
╰─────────────────────────────╯
    next                                                               Show the next task to work on based on …
    show                      <id>                                     Display detailed information about a sp…

╭─────────────────────────╮
│  Dependency Management  │
╰─────────────────────────╯
    validate-dependenci…                                               Identify invalid dependencies without f…
    fix-dependencies                                                   Fix invalid dependencies automatically

╭─────────────────────────╮
│  Environment Variables  │
╰─────────────────────────╯
    ANTHROPIC_API_KEY              Your Anthropic API key                             Required
    MODEL                          Claude model to use                                Default: claude-3-7-sonn…
    MAX_TOKENS                     Maximum tokens for responses                       Default: 4000
    TEMPERATURE                    Temperature for model responses                    Default: 0.7
    PERPLEXITY_API_KEY             Perplexity API key for research                    Optional
    PERPLEXITY_MODEL               Perplexity model to use                            Default: sonar-small-onl…
    DEBUG                          Enable debug logging                               Default: false
    LOG_LEVEL                      Console output level (debug,info,warn,error)       Default: info
    DEFAULT_SUBTASKS               Default number of subtasks to generate             Default: 3
    DEFAULT_PRIORITY               Default task priority                              Default: medium
    PROJECT_NAME                   Project name displayed in UI                       Default: Task Master       with the global  command (see ).
- Updated documentation () to reflect the new  command.

**Benefits:**

Code is now cleaner, easier to work with, and ready for future growth.

Use the  command (or ) to run the CLI.  See  for command details.
2025-03-23 23:19:37 -04:00

224 lines
7.5 KiB
Plaintext

---
description: Guidelines for managing task dependencies and relationships
globs: scripts/modules/dependency-manager.js
alwaysApply: false
---
# Dependency Management Guidelines
## Dependency Structure Principles
- **Dependency References**:
- ✅ DO: Represent task dependencies as arrays of task IDs
- ✅ DO: Use numeric IDs for direct task references
- ✅ DO: Use string IDs with dot notation (e.g., "1.2") for subtask references
- ❌ DON'T: Mix reference types without proper conversion
```javascript
// ✅ DO: Use consistent dependency formats
// For main tasks
task.dependencies = [1, 2, 3]; // Dependencies on other main tasks
// For subtasks
subtask.dependencies = [1, "3.2"]; // Dependency on main task 1 and subtask 2 of task 3
```
- **Subtask Dependencies**:
- ✅ DO: Allow numeric subtask IDs to reference other subtasks within the same parent
- ✅ DO: Convert between formats appropriately when needed
- ❌ DON'T: Create circular dependencies between subtasks
```javascript
// ✅ DO: Properly normalize subtask dependencies
// When a subtask refers to another subtask in the same parent
if (typeof depId === 'number' && depId < 100) {
// It's likely a reference to another subtask in the same parent task
const fullSubtaskId = `${parentId}.${depId}`;
// Now use fullSubtaskId for validation
}
```
## Dependency Validation
- **Existence Checking**:
- ✅ DO: Validate that referenced tasks exist before adding dependencies
- ✅ DO: Provide clear error messages for non-existent dependencies
- ✅ DO: Remove references to non-existent tasks during validation
```javascript
// ✅ DO: Check if the dependency exists before adding
if (!taskExists(data.tasks, formattedDependencyId)) {
log('error', `Dependency target ${formattedDependencyId} does not exist in tasks.json`);
process.exit(1);
}
```
- **Circular Dependency Prevention**:
- ✅ DO: Check for circular dependencies before adding new relationships
- ✅ DO: Use graph traversal algorithms (DFS) to detect cycles
- ✅ DO: Provide clear error messages explaining the circular chain
```javascript
// ✅ DO: Check for circular dependencies before adding
const dependencyChain = [formattedTaskId];
if (isCircularDependency(data.tasks, formattedDependencyId, dependencyChain)) {
log('error', `Cannot add dependency ${formattedDependencyId} to task ${formattedTaskId} as it would create a circular dependency.`);
process.exit(1);
}
```
- **Self-Dependency Prevention**:
- ✅ DO: Prevent tasks from depending on themselves
- ✅ DO: Handle both direct and indirect self-dependencies
```javascript
// ✅ DO: Prevent self-dependencies
if (String(formattedTaskId) === String(formattedDependencyId)) {
log('error', `Task ${formattedTaskId} cannot depend on itself.`);
process.exit(1);
}
```
## Dependency Modification
- **Adding Dependencies**:
- ✅ DO: Format task and dependency IDs consistently
- ✅ DO: Check for existing dependencies to prevent duplicates
- ✅ DO: Sort dependencies for better readability
```javascript
// ✅ DO: Format IDs consistently when adding dependencies
const formattedTaskId = typeof taskId === 'string' && taskId.includes('.')
? taskId : parseInt(taskId, 10);
const formattedDependencyId = formatTaskId(dependencyId);
```
- **Removing Dependencies**:
- ✅ DO: Check if the dependency exists before removing
- ✅ DO: Handle different ID formats consistently
- ✅ DO: Provide feedback about the removal result
```javascript
// ✅ DO: Properly handle dependency removal
const dependencyIndex = targetTask.dependencies.findIndex(dep => {
// Convert both to strings for comparison
let depStr = String(dep);
// Handle relative subtask references
if (typeof dep === 'number' && dep < 100 && isSubtask) {
const [parentId] = formattedTaskId.split('.');
depStr = `${parentId}.${dep}`;
}
return depStr === normalizedDependencyId;
});
if (dependencyIndex === -1) {
log('info', `Task ${formattedTaskId} does not depend on ${formattedDependencyId}, no changes made.`);
return;
}
// Remove the dependency
targetTask.dependencies.splice(dependencyIndex, 1);
```
## Dependency Cleanup
- **Duplicate Removal**:
- ✅ DO: Use Set objects to identify and remove duplicates
- ✅ DO: Handle both numeric and string ID formats
```javascript
// ✅ DO: Remove duplicate dependencies
const uniqueDeps = new Set();
const uniqueDependencies = task.dependencies.filter(depId => {
// Convert to string for comparison to handle both numeric and string IDs
const depIdStr = String(depId);
if (uniqueDeps.has(depIdStr)) {
log('warn', `Removing duplicate dependency from task ${task.id}: ${depId}`);
return false;
}
uniqueDeps.add(depIdStr);
return true;
});
```
- **Invalid Reference Cleanup**:
- ✅ DO: Check for and remove references to non-existent tasks
- ✅ DO: Check for and remove self-references
- ✅ DO: Track and report changes made during cleanup
```javascript
// ✅ DO: Filter invalid task dependencies
task.dependencies = task.dependencies.filter(depId => {
const numericId = typeof depId === 'string' ? parseInt(depId, 10) : depId;
if (!validTaskIds.has(numericId)) {
log('warn', `Removing invalid task dependency from task ${task.id}: ${depId} (task does not exist)`);
return false;
}
return true;
});
```
## Dependency Visualization
- **Status Indicators**:
- ✅ DO: Use visual indicators to show dependency status (✅/⏱️)
- ✅ DO: Format dependency lists consistently
```javascript
// ✅ DO: Format dependencies with status indicators
function formatDependenciesWithStatus(dependencies, allTasks) {
if (!dependencies || dependencies.length === 0) {
return 'None';
}
return dependencies.map(depId => {
const depTask = findTaskById(allTasks, depId);
if (!depTask) return `${depId} (Not found)`;
const isDone = depTask.status === 'done' || depTask.status === 'completed';
const statusIcon = isDone ? '✅' : '⏱️';
return `${statusIcon} ${depId} (${depTask.status})`;
}).join(', ');
}
```
## Cycle Detection
- **Graph Traversal**:
- ✅ DO: Use depth-first search (DFS) for cycle detection
- ✅ DO: Track visited nodes and recursion stack
- ✅ DO: Support both task and subtask dependencies
```javascript
// ✅ DO: Use proper cycle detection algorithms
function findCycles(subtaskId, dependencyMap, visited = new Set(), recursionStack = new Set()) {
// Mark the current node as visited and part of recursion stack
visited.add(subtaskId);
recursionStack.add(subtaskId);
const cyclesToBreak = [];
const dependencies = dependencyMap.get(subtaskId) || [];
for (const depId of dependencies) {
if (!visited.has(depId)) {
const cycles = findCycles(depId, dependencyMap, visited, recursionStack);
cyclesToBreak.push(...cycles);
}
else if (recursionStack.has(depId)) {
// Found a cycle, add the edge to break
cyclesToBreak.push(depId);
}
}
// Remove the node from recursion stack before returning
recursionStack.delete(subtaskId);
return cyclesToBreak;
}
```
Refer to [`dependency-manager.js`](mdc:scripts/modules/dependency-manager.js) for implementation examples and [`new_features.mdc`](mdc:.cursor/rules/new_features.mdc) for integration guidelines.