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
/ * *
* commands . js
* Command - line interface for the Task Master CLI
* /
import { program } from 'commander' ;
import path from 'path' ;
import chalk from 'chalk' ;
import boxen from 'boxen' ;
import fs from 'fs' ;
2025-03-27 16:14:12 -04:00
import https from 'https' ;
2025-05-23 20:20:39 -04:00
import http from 'http' ;
2025-04-03 00:35:11 -04:00
import inquirer from 'inquirer' ;
2025-05-03 00:04:45 -04:00
import ora from 'ora' ; // Import ora
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
2025-05-28 00:32:34 +02:00
import { log , readJSON , findProjectRoot } from './utils.js' ;
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
import {
2025-04-09 00:25:27 +02:00
parsePRD ,
updateTasks ,
generateTaskFiles ,
setTaskStatus ,
listTasks ,
expandTask ,
expandAllTasks ,
clearSubtasks ,
addTask ,
addSubtask ,
removeSubtask ,
analyzeTaskComplexity ,
updateTaskById ,
updateSubtaskById ,
removeTask ,
findTaskById ,
2025-05-22 04:14:22 -04:00
taskExists ,
2025-05-31 16:21:03 +02:00
moveTask ,
migrateProject
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
} from './task-manager.js' ;
import {
2025-04-09 00:25:27 +02:00
addDependency ,
removeDependency ,
validateDependenciesCommand ,
fixDependenciesCommand
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
} from './dependency-manager.js' ;
2025-04-16 00:35:30 -04:00
import {
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
isApiKeySet ,
getDebugFlag ,
getConfig ,
2025-04-21 22:25:04 -04:00
writeConfig ,
2025-04-29 01:54:42 -04:00
ConfigurationError ,
isConfigFilePresent ,
2025-05-23 20:20:39 -04:00
getAvailableModels ,
getBaseUrlForRole
2025-04-16 00:35:30 -04:00
} from './config-manager.js' ;
2025-05-31 16:21:03 +02:00
import {
COMPLEXITY _REPORT _FILE ,
PRD _FILE ,
TASKMASTER _TASKS _FILE
} from '../../src/constants/paths.js' ;
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
import {
2025-04-09 00:25:27 +02:00
displayBanner ,
displayHelp ,
displayNextTask ,
displayTaskById ,
displayComplexityReport ,
getStatusWithColor ,
confirmTaskOverwrite ,
startLoadingIndicator ,
2025-04-27 03:56:23 -04:00
stopLoadingIndicator ,
displayModelConfiguration ,
displayAvailableModels ,
2025-05-31 16:21:03 +02:00
displayApiKeyStatus
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
} from './ui.js' ;
2025-04-10 22:32:08 -04:00
import { initializeProject } from '../init.js' ;
2025-04-23 15:47:33 -04:00
import {
getModelConfiguration ,
getAvailableModelsList ,
2025-04-27 03:56:23 -04:00
setModel ,
getApiKeyStatusReport
2025-04-29 01:54:42 -04:00
} from './task-manager/models.js' ;
2025-05-16 15:47:01 +02:00
import {
isValidTaskStatus ,
TASK _STATUS _OPTIONS
} from '../../src/constants/task-status.js' ;
2025-05-15 22:41:16 +02:00
import { getTaskMasterVersion } from '../../src/utils/getVersion.js' ;
2025-05-31 16:21:03 +02:00
2025-04-27 03:56:23 -04:00
/ * *
* Runs the interactive setup process for model configuration .
* @ param { string | null } projectRoot - The resolved project root directory .
* /
async function runInteractiveSetup ( projectRoot ) {
if ( ! projectRoot ) {
console . error (
chalk . red (
'Error: Could not determine project root for interactive setup.'
)
) ;
process . exit ( 1 ) ;
}
2025-04-27 17:25:54 -04:00
2025-04-29 01:54:42 -04:00
const currentConfigResult = await getModelConfiguration ( { projectRoot } ) ;
const currentModels = currentConfigResult . success
? currentConfigResult . data . activeModels
: { main : null , research : null , fallback : null } ;
// Handle potential config load failure gracefully for the setup flow
if (
! currentConfigResult . success &&
currentConfigResult . error ? . code !== 'CONFIG_MISSING'
) {
console . warn (
chalk . yellow (
` Warning: Could not load current model configuration: ${ currentConfigResult . error ? . message || 'Unknown error' } . Proceeding with defaults. `
)
) ;
}
2025-04-27 17:25:54 -04:00
// Helper function to fetch OpenRouter models (duplicated for CLI context)
function fetchOpenRouterModelsCLI ( ) {
return new Promise ( ( resolve ) => {
const options = {
hostname : 'openrouter.ai' ,
path : '/api/v1/models' ,
method : 'GET' ,
headers : {
Accept : 'application/json'
}
} ;
const req = https . request ( options , ( res ) => {
let data = '' ;
res . on ( 'data' , ( chunk ) => {
data += chunk ;
} ) ;
res . on ( 'end' , ( ) => {
if ( res . statusCode === 200 ) {
try {
const parsedData = JSON . parse ( data ) ;
resolve ( parsedData . data || [ ] ) ; // Return the array of models
} catch ( e ) {
console . error ( 'Error parsing OpenRouter response:' , e ) ;
resolve ( null ) ; // Indicate failure
}
} else {
console . error (
` OpenRouter API request failed with status code: ${ res . statusCode } `
) ;
resolve ( null ) ; // Indicate failure
}
} ) ;
} ) ;
req . on ( 'error' , ( e ) => {
console . error ( 'Error fetching OpenRouter models:' , e ) ;
resolve ( null ) ; // Indicate failure
} ) ;
req . end ( ) ;
} ) ;
}
2025-05-23 20:20:39 -04:00
// Helper function to fetch Ollama models (duplicated for CLI context)
2025-05-28 00:42:31 +02:00
function fetchOllamaModelsCLI ( baseURL = 'http://localhost:11434/api' ) {
2025-05-23 20:20:39 -04:00
return new Promise ( ( resolve ) => {
try {
// Parse the base URL to extract hostname, port, and base path
2025-05-28 00:42:31 +02:00
const url = new URL ( baseURL ) ;
2025-05-23 20:20:39 -04:00
const isHttps = url . protocol === 'https:' ;
const port = url . port || ( isHttps ? 443 : 80 ) ;
const basePath = url . pathname . endsWith ( '/' )
? url . pathname . slice ( 0 , - 1 )
: url . pathname ;
const options = {
hostname : url . hostname ,
port : parseInt ( port , 10 ) ,
path : ` ${ basePath } /tags ` ,
method : 'GET' ,
headers : {
Accept : 'application/json'
}
} ;
const requestLib = isHttps ? https : http ;
const req = requestLib . request ( options , ( res ) => {
let data = '' ;
res . on ( 'data' , ( chunk ) => {
data += chunk ;
} ) ;
res . on ( 'end' , ( ) => {
if ( res . statusCode === 200 ) {
try {
const parsedData = JSON . parse ( data ) ;
resolve ( parsedData . models || [ ] ) ; // Return the array of models
} catch ( e ) {
console . error ( 'Error parsing Ollama response:' , e ) ;
resolve ( null ) ; // Indicate failure
}
} else {
console . error (
` Ollama API request failed with status code: ${ res . statusCode } `
) ;
resolve ( null ) ; // Indicate failure
}
} ) ;
} ) ;
req . on ( 'error' , ( e ) => {
console . error ( 'Error fetching Ollama models:' , e ) ;
resolve ( null ) ; // Indicate failure
} ) ;
req . end ( ) ;
} catch ( e ) {
console . error ( 'Error parsing Ollama base URL:' , e ) ;
resolve ( null ) ; // Indicate failure
}
} ) ;
}
2025-04-27 17:25:54 -04:00
// Helper to get choices and default index for a role
const getPromptData = ( role , allowNone = false ) => {
2025-04-29 01:54:42 -04:00
const currentModel = currentModels [ role ] ; // Use the fetched data
const allModelsRaw = getAvailableModels ( ) ; // Get all available models
// Manually group models by provider
const modelsByProvider = allModelsRaw . reduce ( ( acc , model ) => {
if ( ! acc [ model . provider ] ) {
acc [ model . provider ] = [ ] ;
}
acc [ model . provider ] . push ( model ) ;
return acc ;
} , { } ) ;
const cancelOption = { name : '⏹ Cancel Model Setup' , value : '__CANCEL__' } ; // Symbol updated
const noChangeOption = currentModel ? . modelId
? {
2025-04-30 22:02:02 -04:00
name : ` ✔ No change to current ${ role } model ( ${ currentModel . modelId } ) ` , // Symbol updated
2025-04-29 01:54:42 -04:00
value : '__NO_CHANGE__'
}
: null ;
2025-04-27 17:25:54 -04:00
const customOpenRouterOption = {
2025-04-29 01:54:42 -04:00
name : '* Custom OpenRouter model' , // Symbol updated
2025-04-27 17:25:54 -04:00
value : '__CUSTOM_OPENROUTER__'
} ;
2025-05-23 20:20:39 -04:00
const customOllamaOption = {
name : '* Custom Ollama model' , // Symbol updated
value : '__CUSTOM_OLLAMA__'
} ;
2025-05-28 00:42:31 +02:00
const customBedrockOption = {
name : '* Custom Bedrock model' , // Add Bedrock custom option
value : '__CUSTOM_BEDROCK__'
} ;
2025-04-29 01:54:42 -04:00
let choices = [ ] ;
let defaultIndex = 0 ; // Default to 'Cancel'
// Filter and format models allowed for this role using the manually grouped data
const roleChoices = Object . entries ( modelsByProvider )
. map ( ( [ provider , models ] ) => {
const providerModels = models
. filter ( ( m ) => m . allowed _roles . includes ( role ) )
. map ( ( m ) => ( {
name : ` ${ provider } / ${ m . id } ${
m . cost _per _1m _tokens
? chalk . gray (
` ( $ ${ m . cost _per _1m _tokens . input . toFixed ( 2 ) } input | $ ${ m . cost _per _1m _tokens . output . toFixed ( 2 ) } output) `
)
: ''
} ` ,
value : { id : m . id , provider } ,
short : ` ${ provider } / ${ m . id } `
} ) ) ;
if ( providerModels . length > 0 ) {
return [ ... providerModels ] ;
}
return null ;
} )
. filter ( Boolean )
. flat ( ) ;
// Find the index of the currently selected model for setting the default
let currentChoiceIndex = - 1 ;
if ( currentModel ? . modelId && currentModel ? . provider ) {
currentChoiceIndex = roleChoices . findIndex (
( choice ) =>
typeof choice . value === 'object' &&
choice . value . id === currentModel . modelId &&
choice . value . provider === currentModel . provider
) ;
}
// Construct final choices list based on whether 'None' is allowed
2025-04-30 22:02:02 -04:00
const commonPrefix = [ ] ;
2025-04-29 01:54:42 -04:00
if ( noChangeOption ) {
2025-04-30 22:02:02 -04:00
commonPrefix . push ( noChangeOption ) ;
2025-04-29 01:54:42 -04:00
}
2025-04-30 22:02:02 -04:00
commonPrefix . push ( cancelOption ) ;
2025-04-29 01:54:42 -04:00
commonPrefix . push ( customOpenRouterOption ) ;
2025-05-23 20:20:39 -04:00
commonPrefix . push ( customOllamaOption ) ;
2025-05-28 00:42:31 +02:00
commonPrefix . push ( customBedrockOption ) ;
2025-04-29 01:54:42 -04:00
2025-05-31 16:21:03 +02:00
const prefixLength = commonPrefix . length ; // Initial prefix length
2025-04-27 17:25:54 -04:00
2025-04-27 03:56:23 -04:00
if ( allowNone ) {
choices = [
2025-04-29 01:54:42 -04:00
... commonPrefix ,
2025-04-27 17:25:54 -04:00
new inquirer . Separator ( ) ,
2025-04-29 01:54:42 -04:00
{ name : '⚪ None (disable)' , value : null } , // Symbol updated
2025-04-27 03:56:23 -04:00
new inquirer . Separator ( ) ,
... roleChoices
] ;
2025-04-29 01:54:42 -04:00
// Adjust default index: Prefix + Sep1 + None + Sep2 (+3)
const noneOptionIndex = prefixLength + 1 ;
defaultIndex =
currentChoiceIndex !== - 1
? currentChoiceIndex + prefixLength + 3 // Offset by prefix and separators
: noneOptionIndex ; // Default to 'None' if no current model matched
2025-04-27 03:56:23 -04:00
} else {
2025-04-27 17:25:54 -04:00
choices = [
2025-04-29 01:54:42 -04:00
... commonPrefix ,
2025-04-27 17:25:54 -04:00
new inquirer . Separator ( ) ,
2025-04-29 01:54:42 -04:00
... roleChoices ,
new inquirer . Separator ( )
2025-04-27 17:25:54 -04:00
] ;
2025-04-29 01:54:42 -04:00
// Adjust default index: Prefix + Sep (+1)
defaultIndex =
currentChoiceIndex !== - 1
? currentChoiceIndex + prefixLength + 1 // Offset by prefix and separator
: noChangeOption
? 1
: 0 ; // Default to 'No Change' if present, else 'Cancel'
2025-04-27 03:56:23 -04:00
}
2025-04-27 17:25:54 -04:00
// Ensure defaultIndex is valid within the final choices array length
if ( defaultIndex < 0 || defaultIndex >= choices . length ) {
// If default calculation failed or pointed outside bounds, reset intelligently
defaultIndex = 0 ; // Default to 'Cancel'
console . warn (
` Warning: Could not determine default model for role ' ${ role } '. Defaulting to 'Cancel'. `
) ; // Add warning
}
2025-04-27 03:56:23 -04:00
return { choices , default : defaultIndex } ;
} ;
// --- Generate choices using the helper ---
const mainPromptData = getPromptData ( 'main' ) ;
const researchPromptData = getPromptData ( 'research' ) ;
const fallbackPromptData = getPromptData ( 'fallback' , true ) ; // Allow 'None' for fallback
const answers = await inquirer . prompt ( [
{
type : 'list' ,
name : 'mainModel' ,
message : 'Select the main model for generation/updates:' ,
choices : mainPromptData . choices ,
default : mainPromptData . default
} ,
{
type : 'list' ,
name : 'researchModel' ,
message : 'Select the research model:' ,
choices : researchPromptData . choices ,
default : researchPromptData . default ,
when : ( ans ) => ans . mainModel !== '__CANCEL__'
} ,
{
type : 'list' ,
name : 'fallbackModel' ,
message : 'Select the fallback model (optional):' ,
choices : fallbackPromptData . choices ,
default : fallbackPromptData . default ,
when : ( ans ) =>
ans . mainModel !== '__CANCEL__' && ans . researchModel !== '__CANCEL__'
}
] ) ;
let setupSuccess = true ;
let setupConfigModified = false ;
const coreOptionsSetup = { projectRoot } ; // Pass root for setup actions
2025-04-27 17:25:54 -04:00
// Helper to handle setting a model (including custom)
async function handleSetModel ( role , selectedValue , currentModelId ) {
if ( selectedValue === '__CANCEL__' ) {
2025-04-27 03:56:23 -04:00
console . log (
2025-04-27 17:25:54 -04:00
chalk . yellow ( ` \n Setup canceled during ${ role } model selection. ` )
2025-04-27 03:56:23 -04:00
) ;
2025-04-29 01:54:42 -04:00
setupSuccess = false ; // Also mark success as false on cancel
2025-04-27 17:25:54 -04:00
return false ; // Indicate cancellation
2025-04-27 03:56:23 -04:00
}
2025-04-29 01:54:42 -04:00
// Handle the new 'No Change' option
if ( selectedValue === '__NO_CHANGE__' ) {
console . log ( chalk . gray ( ` No change selected for ${ role } model. ` ) ) ;
return true ; // Indicate success, continue setup
}
2025-04-27 17:25:54 -04:00
let modelIdToSet = null ;
let providerHint = null ;
let isCustomSelection = false ;
if ( selectedValue === '__CUSTOM_OPENROUTER__' ) {
isCustomSelection = true ;
const { customId } = await inquirer . prompt ( [
{
type : 'input' ,
name : 'customId' ,
message : ` Enter the custom OpenRouter Model ID for the ${ role } role: `
}
] ) ;
if ( ! customId ) {
console . log ( chalk . yellow ( 'No custom ID entered. Skipping role.' ) ) ;
return true ; // Continue setup, but don't set this role
}
modelIdToSet = customId ;
providerHint = 'openrouter' ;
// Validate against live OpenRouter list
const openRouterModels = await fetchOpenRouterModelsCLI ( ) ;
if (
! openRouterModels ||
! openRouterModels . some ( ( m ) => m . id === modelIdToSet )
) {
console . error (
chalk . red (
` Error: Model ID " ${ modelIdToSet } " not found in the live OpenRouter model list. Please check the ID. `
)
) ;
setupSuccess = false ;
return true ; // Continue setup, but mark as failed
}
2025-05-23 20:20:39 -04:00
} else if ( selectedValue === '__CUSTOM_OLLAMA__' ) {
isCustomSelection = true ;
const { customId } = await inquirer . prompt ( [
{
type : 'input' ,
name : 'customId' ,
message : ` Enter the custom Ollama Model ID for the ${ role } role: `
}
] ) ;
if ( ! customId ) {
console . log ( chalk . yellow ( 'No custom ID entered. Skipping role.' ) ) ;
return true ; // Continue setup, but don't set this role
}
modelIdToSet = customId ;
providerHint = 'ollama' ;
// Get the Ollama base URL from config for this role
2025-05-28 00:42:31 +02:00
const ollamaBaseURL = getBaseUrlForRole ( role , projectRoot ) ;
2025-05-23 20:20:39 -04:00
// Validate against live Ollama list
2025-05-28 00:42:31 +02:00
const ollamaModels = await fetchOllamaModelsCLI ( ollamaBaseURL ) ;
2025-05-23 20:20:39 -04:00
if ( ollamaModels === null ) {
console . error (
chalk . red (
2025-05-28 00:42:31 +02:00
` Error: Unable to connect to Ollama server at ${ ollamaBaseURL } . Please ensure Ollama is running and try again. `
2025-05-23 20:20:39 -04:00
)
) ;
setupSuccess = false ;
return true ; // Continue setup, but mark as failed
} else if ( ! ollamaModels . some ( ( m ) => m . model === modelIdToSet ) ) {
console . error (
chalk . red (
` Error: Model ID " ${ modelIdToSet } " not found in the Ollama instance. Please verify the model is pulled and available. `
)
) ;
console . log (
chalk . yellow (
2025-05-28 00:42:31 +02:00
` You can check available models with: curl ${ ollamaBaseURL } /tags `
2025-05-23 20:20:39 -04:00
)
) ;
setupSuccess = false ;
return true ; // Continue setup, but mark as failed
}
2025-05-28 00:42:31 +02:00
} else if ( selectedValue === '__CUSTOM_BEDROCK__' ) {
isCustomSelection = true ;
const { customId } = await inquirer . prompt ( [
{
type : 'input' ,
name : 'customId' ,
message : ` Enter the custom Bedrock Model ID for the ${ role } role (e.g., anthropic.claude-3-sonnet-20240229-v1:0): `
}
] ) ;
if ( ! customId ) {
console . log ( chalk . yellow ( 'No custom ID entered. Skipping role.' ) ) ;
return true ; // Continue setup, but don't set this role
}
modelIdToSet = customId ;
providerHint = 'bedrock' ;
// Check if AWS environment variables exist
if (
! process . env . AWS _ACCESS _KEY _ID ||
! process . env . AWS _SECRET _ACCESS _KEY
) {
console . error (
chalk . red (
2025-05-31 16:21:03 +02:00
'Error: AWS_ACCESS_KEY_ID and/or AWS_SECRET_ACCESS_KEY environment variables are missing. Please set them before using custom Bedrock models.'
2025-05-28 00:42:31 +02:00
)
) ;
setupSuccess = false ;
return true ; // Continue setup, but mark as failed
}
console . log (
chalk . blue (
` Custom Bedrock model " ${ modelIdToSet } " will be used. No validation performed. `
)
) ;
2025-04-27 17:25:54 -04:00
} else if (
selectedValue &&
typeof selectedValue === 'object' &&
selectedValue . id
) {
// Standard model selected from list
modelIdToSet = selectedValue . id ;
providerHint = selectedValue . provider ; // Provider is known
} else if ( selectedValue === null && role === 'fallback' ) {
// Handle disabling fallback
modelIdToSet = null ;
providerHint = null ;
} else if ( selectedValue ) {
2025-04-27 03:56:23 -04:00
console . error (
chalk . red (
2025-04-27 17:25:54 -04:00
` Internal Error: Unexpected selection value for ${ role } : ${ JSON . stringify ( selectedValue ) } `
2025-04-27 03:56:23 -04:00
)
) ;
setupSuccess = false ;
2025-04-27 17:25:54 -04:00
return true ;
2025-04-27 03:56:23 -04:00
}
2025-04-27 17:25:54 -04:00
// Only proceed if there's a change to be made
if ( modelIdToSet !== currentModelId ) {
if ( modelIdToSet ) {
// Set a specific model (standard or custom)
const result = await setModel ( role , modelIdToSet , {
... coreOptionsSetup ,
providerHint // Pass the hint
} ) ;
if ( result . success ) {
console . log (
chalk . blue (
` Set ${ role } model: ${ result . data . provider } / ${ result . data . modelId } `
)
) ;
if ( result . data . warning ) {
// Display warning if returned by setModel
console . log ( chalk . yellow ( result . data . warning ) ) ;
}
2025-04-27 03:56:23 -04:00
setupConfigModified = true ;
} else {
console . error (
2025-04-27 17:25:54 -04:00
chalk . red (
` Error setting ${ role } model: ${ result . error ? . message || 'Unknown' } `
)
2025-04-27 03:56:23 -04:00
) ;
setupSuccess = false ;
}
2025-04-27 17:25:54 -04:00
} else if ( role === 'fallback' ) {
// Disable fallback model
const currentCfg = getConfig ( projectRoot ) ;
if ( currentCfg ? . models ? . fallback ? . modelId ) {
// Check if it was actually set before clearing
currentCfg . models . fallback = {
... currentCfg . models . fallback ,
provider : undefined ,
modelId : undefined
} ;
if ( writeConfig ( currentCfg , projectRoot ) ) {
console . log ( chalk . blue ( 'Fallback model disabled.' ) ) ;
setupConfigModified = true ;
} else {
console . error (
chalk . red ( 'Failed to disable fallback model in config file.' )
) ;
setupSuccess = false ;
}
} else {
console . log ( chalk . blue ( 'Fallback model was already disabled.' ) ) ;
}
2025-04-27 03:56:23 -04:00
}
}
2025-04-27 17:25:54 -04:00
return true ; // Indicate setup should continue
2025-04-27 03:56:23 -04:00
}
2025-04-27 17:25:54 -04:00
// Process answers using the handler
if (
! ( await handleSetModel (
'main' ,
answers . mainModel ,
2025-04-29 01:54:42 -04:00
currentModels . main ? . modelId // <--- Now 'currentModels' is defined
2025-04-27 17:25:54 -04:00
) )
2025-04-29 01:54:42 -04:00
) {
return false ; // Explicitly return false if cancelled
}
2025-04-27 17:25:54 -04:00
if (
! ( await handleSetModel (
'research' ,
answers . researchModel ,
2025-04-29 01:54:42 -04:00
currentModels . research ? . modelId // <--- Now 'currentModels' is defined
2025-04-27 17:25:54 -04:00
) )
2025-04-29 01:54:42 -04:00
) {
return false ; // Explicitly return false if cancelled
}
2025-04-27 17:25:54 -04:00
if (
! ( await handleSetModel (
'fallback' ,
answers . fallbackModel ,
2025-04-29 01:54:42 -04:00
currentModels . fallback ? . modelId // <--- Now 'currentModels' is defined
2025-04-27 17:25:54 -04:00
) )
2025-04-29 01:54:42 -04:00
) {
return false ; // Explicitly return false if cancelled
}
2025-04-27 17:25:54 -04:00
2025-04-27 03:56:23 -04:00
if ( setupSuccess && setupConfigModified ) {
console . log ( chalk . green . bold ( '\nModel setup complete!' ) ) ;
} else if ( setupSuccess && ! setupConfigModified ) {
console . log ( chalk . yellow ( '\nNo changes made to model configuration.' ) ) ;
} else if ( ! setupSuccess ) {
console . error (
chalk . red (
'\nErrors occurred during model selection. Please review and try again.'
)
) ;
}
2025-04-29 01:54:42 -04:00
return true ; // Indicate setup flow completed (not cancelled)
2025-04-27 03:56:23 -04:00
// Let the main command flow continue to display results
}
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
/ * *
* Configure and register CLI commands
* @ param { Object } program - Commander program instance
* /
function registerCommands ( programInstance ) {
2025-04-09 00:25:27 +02:00
// Add global error handler for unknown options
programInstance . on ( 'option:unknown' , function ( unknownOption ) {
const commandName = this . _name || 'unknown' ;
console . error ( chalk . red ( ` Error: Unknown option ' ${ unknownOption } ' ` ) ) ;
console . error (
chalk . yellow (
` Run 'task-master ${ commandName } --help' to see available options `
)
) ;
process . exit ( 1 ) ;
} ) ;
// parse-prd command
programInstance
. command ( 'parse-prd' )
. description ( 'Parse a PRD file and generate tasks' )
. argument ( '[file]' , 'Path to the PRD file' )
. option (
'-i, --input <file>' ,
'Path to the PRD file (alternative to positional argument)'
)
2025-05-31 16:21:03 +02:00
. option ( '-o, --output <file>' , 'Output file path' , TASKMASTER _TASKS _FILE )
2025-04-09 00:25:27 +02:00
. option ( '-n, --num-tasks <number>' , 'Number of tasks to generate' , '10' )
. option ( '-f, --force' , 'Skip confirmation when overwriting existing tasks' )
2025-04-19 23:49:50 +02:00
. option (
'--append' ,
'Append new tasks to existing tasks.json instead of overwriting'
)
2025-05-22 02:57:51 -04:00
. option (
'-r, --research' ,
'Use Perplexity AI for research-backed task generation, providing more comprehensive and accurate task breakdown'
)
2025-04-09 00:25:27 +02:00
. action ( async ( file , options ) => {
// Use input option if file argument not provided
const inputFile = file || options . input ;
2025-05-31 16:21:03 +02:00
const defaultPrdPath = PRD _FILE ;
2025-04-09 00:25:27 +02:00
const numTasks = parseInt ( options . numTasks , 10 ) ;
const outputPath = options . output ;
const force = options . force || false ;
2025-04-19 23:49:50 +02:00
const append = options . append || false ;
2025-05-22 02:57:51 -04:00
const research = options . research || false ;
2025-05-07 14:17:41 -04:00
let useForce = force ;
2025-05-31 16:21:03 +02:00
const useAppend = append ;
2025-04-09 00:25:27 +02:00
// Helper function to check if tasks.json exists and confirm overwrite
async function confirmOverwriteIfNeeded ( ) {
2025-05-03 00:04:45 -04:00
if ( fs . existsSync ( outputPath ) && ! useForce && ! useAppend ) {
const overwrite = await confirmTaskOverwrite ( outputPath ) ;
2025-05-02 23:11:39 -04:00
if ( ! overwrite ) {
log ( 'info' , 'Operation cancelled.' ) ;
2025-05-03 00:04:45 -04:00
return false ;
2025-04-09 00:25:27 +02:00
}
2025-05-02 23:11:39 -04:00
// If user confirms 'y', we should set useForce = true for the parsePRD call
2025-05-03 00:04:45 -04:00
// Only overwrite if not appending
2025-05-02 23:11:39 -04:00
useForce = true ;
2025-04-09 00:25:27 +02:00
}
return true ;
}
2025-05-03 00:04:45 -04:00
let spinner ;
2025-04-09 00:25:27 +02:00
2025-05-03 00:04:45 -04:00
try {
if ( ! inputFile ) {
if ( fs . existsSync ( defaultPrdPath ) ) {
console . log (
chalk . blue ( ` Using default PRD file path: ${ defaultPrdPath } ` )
) ;
if ( ! ( await confirmOverwriteIfNeeded ( ) ) ) return ;
console . log ( chalk . blue ( ` Generating ${ numTasks } tasks... ` ) ) ;
2025-05-13 13:21:51 -04:00
spinner = ora ( 'Parsing PRD and generating tasks...\n' ) . start ( ) ;
2025-05-03 00:04:45 -04:00
await parsePRD ( defaultPrdPath , outputPath , numTasks , {
2025-05-07 14:17:41 -04:00
append : useAppend , // Changed key from useAppend to append
2025-05-22 02:57:51 -04:00
force : useForce , // Changed key from useForce to force
research : research
2025-05-03 00:04:45 -04:00
} ) ;
spinner . succeed ( 'Tasks generated successfully!' ) ;
return ;
}
2025-04-09 00:25:27 +02:00
2025-05-03 00:04:45 -04:00
console . log (
chalk . yellow (
2025-05-31 16:21:03 +02:00
` No PRD file specified and default PRD file not found at ${ PRD _FILE } . `
2025-05-03 00:04:45 -04:00
)
) ;
console . log (
boxen (
2025-05-31 16:21:03 +02:00
` ${ chalk . white . bold ( 'Parse PRD Help' ) } \n \n ${ chalk . cyan ( 'Usage:' ) } \n task-master parse-prd <prd-file.txt> [options] \n \n ${ chalk . cyan ( 'Options:' ) } \n -i, --input <file> Path to the PRD file (alternative to positional argument) \n -o, --output <file> Output file path (default: " ${ TASKMASTER _TASKS _FILE } ") \n -n, --num-tasks <number> Number of tasks to generate (default: 10) \n -f, --force Skip confirmation when overwriting existing tasks \n --append Append new tasks to existing tasks.json instead of overwriting \n -r, --research Use Perplexity AI for research-backed task generation \n \n ${ chalk . cyan ( 'Example:' ) } \n task-master parse-prd requirements.txt --num-tasks 15 \n task-master parse-prd --input=requirements.txt \n task-master parse-prd --force \n task-master parse-prd requirements_v2.txt --append \n task-master parse-prd requirements.txt --research \n \n ${ chalk . yellow ( 'Note: This command will:' ) } \n 1. Look for a PRD file at ${ PRD _FILE } by default \n 2. Use the file specified by --input or positional argument if provided \n 3. Generate tasks from the PRD and either: \n - Overwrite any existing tasks.json file (default) \n - Append to existing tasks.json if --append is used ` ,
2025-05-03 00:04:45 -04:00
{ padding : 1 , borderColor : 'blue' , borderStyle : 'round' }
)
) ;
2025-04-09 00:25:27 +02:00
return ;
}
2025-05-03 00:04:45 -04:00
if ( ! fs . existsSync ( inputFile ) ) {
console . error (
chalk . red ( ` Error: Input PRD file not found: ${ inputFile } ` )
) ;
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
2025-05-03 00:04:45 -04:00
if ( ! ( await confirmOverwriteIfNeeded ( ) ) ) return ;
2025-04-09 00:25:27 +02:00
2025-05-03 00:04:45 -04:00
console . log ( chalk . blue ( ` Parsing PRD file: ${ inputFile } ` ) ) ;
console . log ( chalk . blue ( ` Generating ${ numTasks } tasks... ` ) ) ;
if ( append ) {
console . log ( chalk . blue ( 'Appending to existing tasks...' ) ) ;
}
2025-05-22 02:57:51 -04:00
if ( research ) {
2025-05-22 04:17:06 -04:00
console . log (
chalk . blue (
'Using Perplexity AI for research-backed task generation'
)
) ;
2025-05-22 02:57:51 -04:00
}
2025-04-09 00:25:27 +02:00
2025-05-13 13:21:51 -04:00
spinner = ora ( 'Parsing PRD and generating tasks...\n' ) . start ( ) ;
2025-05-03 00:04:45 -04:00
await parsePRD ( inputFile , outputPath , numTasks , {
2025-05-22 04:17:06 -04:00
append : useAppend ,
force : useForce ,
research : research
} ) ;
2025-05-03 00:04:45 -04:00
spinner . succeed ( 'Tasks generated successfully!' ) ;
} catch ( error ) {
if ( spinner ) {
spinner . fail ( ` Error parsing PRD: ${ error . message } ` ) ;
} else {
console . error ( chalk . red ( ` Error parsing PRD: ${ error . message } ` ) ) ;
}
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
} ) ;
// update command
programInstance
. command ( 'update' )
. description (
'Update multiple tasks with ID >= "from" based on new information or implementation changes'
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option (
'--from <id>' ,
'Task ID to start updating from (tasks with ID >= this value will be updated)' ,
'1'
)
. option (
'-p, --prompt <text>' ,
'Prompt explaining the changes or new context (required)'
)
. option (
'-r, --research' ,
'Use Perplexity AI for research-backed task updates'
)
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
refactor(tasks): Align update-tasks with unified AI service and remove obsolete helpers
Completes the refactoring of the AI-interacting task management functions by aligning `update-tasks.js` with the unified service architecture and removing now-unused helper files.
Key Changes:
- **`update-tasks.js` Refactoring:**
- Replaced direct AI client calls and AI-specific config fetching with a call to `generateTextService` from `ai-services-unified.js`.
- Preserved the original system and user prompts requesting a JSON array output.
- Implemented manual JSON parsing (`parseUpdatedTasksFromText`) with Zod validation to handle the text response reliably.
- Updated the core function signature to accept the standard `context` object (`{ session, mcpLog }`).
- Corrected logger implementation to handle both MCP (`mcpLog`) and CLI (`consoleLog`) contexts appropriately.
- **Related Component Updates:**
- Refactored `mcp-server/src/core/direct-functions/update-tasks.js` to use the standard direct function pattern (logger wrapper, silent mode, call core function with context).
- Verified `mcp-server/src/tools/update.js` correctly passes arguments and context.
- Verified `scripts/modules/commands.js` (update command) correctly calls the refactored core function.
- **Obsolete File Cleanup:**
- Removed the now-unused `scripts/modules/task-manager/get-subtasks-from-ai.js` file and its export, as its functionality was integrated into `expand-task.js`.
- Removed the now-unused `scripts/modules/task-manager/generate-subtask-prompt.js` file and its export for the same reason.
- **Task Management:**
- Marked subtasks 61.38, 61.39, and 61.41 as complete.
This commit finalizes the alignment of `updateTasks`, `updateTaskById`, `expandTask`, `expandAllTasks`, `analyzeTaskComplexity`, `addTask`, and `parsePRD` with the unified AI service and configuration management patterns.
2025-04-25 04:09:14 -04:00
const fromId = parseInt ( options . from , 10 ) ; // Validation happens here
2025-04-09 00:25:27 +02:00
const prompt = options . prompt ;
const useResearch = options . research || false ;
// Check if there's an 'id' option which is a common mistake (instead of 'from')
if (
process . argv . includes ( '--id' ) ||
process . argv . some ( ( arg ) => arg . startsWith ( '--id=' ) )
) {
console . error (
chalk . red ( 'Error: The update command uses --from=<id>, not --id=<id>' )
) ;
console . log ( chalk . yellow ( '\nTo update multiple tasks:' ) ) ;
console . log (
` task-master update --from= ${ fromId } --prompt="Your prompt here" `
) ;
console . log (
chalk . yellow (
'\nTo update a single specific task, use the update-task command instead:'
)
) ;
console . log (
` task-master update-task --id=<id> --prompt="Your prompt here" `
) ;
process . exit ( 1 ) ;
}
if ( ! prompt ) {
console . error (
chalk . red (
'Error: --prompt parameter is required. Please provide information about the changes.'
)
) ;
process . exit ( 1 ) ;
}
console . log (
chalk . blue (
` Updating tasks from ID >= ${ fromId } with prompt: " ${ prompt } " `
)
) ;
console . log ( chalk . blue ( ` Tasks file: ${ tasksPath } ` ) ) ;
if ( useResearch ) {
console . log (
chalk . blue ( 'Using Perplexity AI for research-backed task updates' )
) ;
}
refactor(tasks): Align update-tasks with unified AI service and remove obsolete helpers
Completes the refactoring of the AI-interacting task management functions by aligning `update-tasks.js` with the unified service architecture and removing now-unused helper files.
Key Changes:
- **`update-tasks.js` Refactoring:**
- Replaced direct AI client calls and AI-specific config fetching with a call to `generateTextService` from `ai-services-unified.js`.
- Preserved the original system and user prompts requesting a JSON array output.
- Implemented manual JSON parsing (`parseUpdatedTasksFromText`) with Zod validation to handle the text response reliably.
- Updated the core function signature to accept the standard `context` object (`{ session, mcpLog }`).
- Corrected logger implementation to handle both MCP (`mcpLog`) and CLI (`consoleLog`) contexts appropriately.
- **Related Component Updates:**
- Refactored `mcp-server/src/core/direct-functions/update-tasks.js` to use the standard direct function pattern (logger wrapper, silent mode, call core function with context).
- Verified `mcp-server/src/tools/update.js` correctly passes arguments and context.
- Verified `scripts/modules/commands.js` (update command) correctly calls the refactored core function.
- **Obsolete File Cleanup:**
- Removed the now-unused `scripts/modules/task-manager/get-subtasks-from-ai.js` file and its export, as its functionality was integrated into `expand-task.js`.
- Removed the now-unused `scripts/modules/task-manager/generate-subtask-prompt.js` file and its export for the same reason.
- **Task Management:**
- Marked subtasks 61.38, 61.39, and 61.41 as complete.
This commit finalizes the alignment of `updateTasks`, `updateTaskById`, `expandTask`, `expandAllTasks`, `analyzeTaskComplexity`, `addTask`, and `parsePRD` with the unified AI service and configuration management patterns.
2025-04-25 04:09:14 -04:00
// Call core updateTasks, passing empty context for CLI
await updateTasks (
tasksPath ,
fromId ,
prompt ,
useResearch ,
{ } // Pass empty context
) ;
2025-04-09 00:25:27 +02:00
} ) ;
// update-task command
programInstance
. command ( 'update-task' )
. description (
'Update a single specific task by ID with new information (use --id parameter)'
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option ( '-i, --id <id>' , 'Task ID to update (required)' )
. option (
'-p, --prompt <text>' ,
'Prompt explaining the changes or new context (required)'
)
. option (
'-r, --research' ,
'Use Perplexity AI for research-backed task updates'
)
. action ( async ( options ) => {
try {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
// Validate required parameters
if ( ! options . id ) {
console . error ( chalk . red ( 'Error: --id parameter is required' ) ) ;
console . log (
chalk . yellow (
'Usage example: task-master update-task --id=23 --prompt="Update with new information"'
)
) ;
process . exit ( 1 ) ;
}
// Parse the task ID and validate it's a number
const taskId = parseInt ( options . id , 10 ) ;
2025-05-31 16:21:03 +02:00
if ( Number . isNaN ( taskId ) || taskId <= 0 ) {
2025-04-09 00:25:27 +02:00
console . error (
chalk . red (
` Error: Invalid task ID: ${ options . id } . Task ID must be a positive integer. `
)
) ;
console . log (
chalk . yellow (
'Usage example: task-master update-task --id=23 --prompt="Update with new information"'
)
) ;
process . exit ( 1 ) ;
}
if ( ! options . prompt ) {
console . error (
chalk . red (
'Error: --prompt parameter is required. Please provide information about the changes.'
)
) ;
console . log (
chalk . yellow (
'Usage example: task-master update-task --id=23 --prompt="Update with new information"'
)
) ;
process . exit ( 1 ) ;
}
const prompt = options . prompt ;
const useResearch = options . research || false ;
// Validate tasks file exists
if ( ! fs . existsSync ( tasksPath ) ) {
console . error (
chalk . red ( ` Error: Tasks file not found at path: ${ tasksPath } ` )
) ;
2025-05-31 16:21:03 +02:00
if ( tasksPath === TASKMASTER _TASKS _FILE ) {
2025-04-09 00:25:27 +02:00
console . log (
chalk . yellow (
'Hint: Run task-master init or task-master parse-prd to create tasks.json first'
)
) ;
} else {
console . log (
chalk . yellow (
` Hint: Check if the file path is correct: ${ tasksPath } `
)
) ;
}
process . exit ( 1 ) ;
}
console . log (
chalk . blue ( ` Updating task ${ taskId } with prompt: " ${ prompt } " ` )
) ;
console . log ( chalk . blue ( ` Tasks file: ${ tasksPath } ` ) ) ;
if ( useResearch ) {
// Verify Perplexity API key exists if using research
refactor: Standardize configuration and environment variable access
This commit centralizes configuration and environment variable access across various modules by consistently utilizing getters from scripts/modules/config-manager.js. This replaces direct access to process.env and the global CONFIG object, leading to improved consistency, maintainability, testability, and better handling of session-specific configurations within the MCP context.
Key changes include:
- Centralized Getters: Replaced numerous instances of process.env.* and CONFIG.* with corresponding getter functions (e.g., getLogLevel, getMainModelId, getResearchMaxTokens, getMainTemperature, isApiKeySet, getDebugFlag, getDefaultSubtasks).
- Session Awareness: Ensured that the session object is passed to config getters where necessary, particularly within AI service calls (ai-services.js, add-task.js) and error handling (ai-services.js), allowing for session-specific environment overrides.
- API Key Checks: Standardized API key availability checks using isApiKeySet() instead of directly checking process.env.* (e.g., for Perplexity in commands.js and ai-services.js).
- Client Instantiation Cleanup: Removed now-redundant/obsolete local client instantiation functions (getAnthropicClient, getPerplexityClient) from ai-services.js and the global Anthropic client initialization from dependency-manager.js. Client creation should now rely on the config manager and factory patterns.
- Consistent Debug Flag Usage: Standardized calls to getDebugFlag() in commands.js, removing potentially unnecessary null arguments.
- Accurate Progress Calculation: Updated AI stream progress reporting (ai-services.js, add-task.js) to use getMainMaxTokens(session) for more accurate calculations.
- Minor Cleanup: Removed unused import from scripts/modules/commands.js.
Specific module updates:
- :
- Uses getLogLevel() instead of process.env.LOG_LEVEL.
- :
- Replaced direct env/config access for model IDs, tokens, temperature, API keys, and default subtasks with appropriate getters.
- Passed session to handleClaudeError.
- Removed local getPerplexityClient and getAnthropicClient functions.
- Updated progress calculations to use getMainMaxTokens(session).
- :
- Uses isApiKeySet('perplexity') for API key checks.
- Uses getDebugFlag() consistently for debug checks.
- Removed unused import.
- :
- Removed global Anthropic client initialization.
- :
- Uses config getters (getResearch..., getMain...) for Perplexity and Claude API call parameters, preserving customEnv override logic.
This refactoring also resolves a potential SyntaxError: Identifier 'getPerplexityClient' has already been declared by removing the duplicated/obsolete function definition previously present in ai-services.js.
2025-04-21 21:30:12 -04:00
if ( ! isApiKeySet ( 'perplexity' ) ) {
2025-04-09 00:25:27 +02:00
console . log (
chalk . yellow (
'Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'
)
) ;
console . log (
chalk . yellow ( 'Falling back to Claude AI for task update.' )
) ;
} else {
console . log (
chalk . blue ( 'Using Perplexity AI for research-backed task update' )
) ;
}
}
const result = await updateTaskById (
tasksPath ,
taskId ,
prompt ,
useResearch
) ;
// If the task wasn't updated (e.g., if it was already marked as done)
if ( ! result ) {
console . log (
chalk . yellow (
'\nTask update was not completed. Review the messages above for details.'
)
) ;
}
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
// Provide more helpful error messages for common issues
if (
error . message . includes ( 'task' ) &&
error . message . includes ( 'not found' )
) {
console . log ( chalk . yellow ( '\nTo fix this issue:' ) ) ;
console . log (
' 1. Run task-master list to see all available task IDs'
) ;
console . log ( ' 2. Use a valid task ID with the --id parameter' ) ;
} else if ( error . message . includes ( 'API key' ) ) {
console . log (
chalk . yellow (
'\nThis error is related to API keys. Check your environment variables.'
)
) ;
}
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
// Use getDebugFlag getter instead of CONFIG.debug
refactor: Standardize configuration and environment variable access
This commit centralizes configuration and environment variable access across various modules by consistently utilizing getters from scripts/modules/config-manager.js. This replaces direct access to process.env and the global CONFIG object, leading to improved consistency, maintainability, testability, and better handling of session-specific configurations within the MCP context.
Key changes include:
- Centralized Getters: Replaced numerous instances of process.env.* and CONFIG.* with corresponding getter functions (e.g., getLogLevel, getMainModelId, getResearchMaxTokens, getMainTemperature, isApiKeySet, getDebugFlag, getDefaultSubtasks).
- Session Awareness: Ensured that the session object is passed to config getters where necessary, particularly within AI service calls (ai-services.js, add-task.js) and error handling (ai-services.js), allowing for session-specific environment overrides.
- API Key Checks: Standardized API key availability checks using isApiKeySet() instead of directly checking process.env.* (e.g., for Perplexity in commands.js and ai-services.js).
- Client Instantiation Cleanup: Removed now-redundant/obsolete local client instantiation functions (getAnthropicClient, getPerplexityClient) from ai-services.js and the global Anthropic client initialization from dependency-manager.js. Client creation should now rely on the config manager and factory patterns.
- Consistent Debug Flag Usage: Standardized calls to getDebugFlag() in commands.js, removing potentially unnecessary null arguments.
- Accurate Progress Calculation: Updated AI stream progress reporting (ai-services.js, add-task.js) to use getMainMaxTokens(session) for more accurate calculations.
- Minor Cleanup: Removed unused import from scripts/modules/commands.js.
Specific module updates:
- :
- Uses getLogLevel() instead of process.env.LOG_LEVEL.
- :
- Replaced direct env/config access for model IDs, tokens, temperature, API keys, and default subtasks with appropriate getters.
- Passed session to handleClaudeError.
- Removed local getPerplexityClient and getAnthropicClient functions.
- Updated progress calculations to use getMainMaxTokens(session).
- :
- Uses isApiKeySet('perplexity') for API key checks.
- Uses getDebugFlag() consistently for debug checks.
- Removed unused import.
- :
- Removed global Anthropic client initialization.
- :
- Uses config getters (getResearch..., getMain...) for Perplexity and Claude API call parameters, preserving customEnv override logic.
This refactoring also resolves a potential SyntaxError: Identifier 'getPerplexityClient' has already been declared by removing the duplicated/obsolete function definition previously present in ai-services.js.
2025-04-21 21:30:12 -04:00
if ( getDebugFlag ( ) ) {
2025-04-09 00:25:27 +02:00
console . error ( error ) ;
}
process . exit ( 1 ) ;
}
} ) ;
// update-subtask command
programInstance
. command ( 'update-subtask' )
. description (
'Update a subtask by appending additional timestamped information'
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option (
'-i, --id <id>' ,
'Subtask ID to update in format "parentId.subtaskId" (required)'
)
. option (
'-p, --prompt <text>' ,
'Prompt explaining what information to add (required)'
)
. option ( '-r, --research' , 'Use Perplexity AI for research-backed updates' )
. action ( async ( options ) => {
try {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
// Validate required parameters
if ( ! options . id ) {
console . error ( chalk . red ( 'Error: --id parameter is required' ) ) ;
console . log (
chalk . yellow (
'Usage example: task-master update-subtask --id=5.2 --prompt="Add more details about the API endpoint"'
)
) ;
process . exit ( 1 ) ;
}
// Validate subtask ID format (should contain a dot)
const subtaskId = options . id ;
if ( ! subtaskId . includes ( '.' ) ) {
console . error (
chalk . red (
` Error: Invalid subtask ID format: ${ subtaskId } . Subtask ID must be in format "parentId.subtaskId" `
)
) ;
console . log (
chalk . yellow (
'Usage example: task-master update-subtask --id=5.2 --prompt="Add more details about the API endpoint"'
)
) ;
process . exit ( 1 ) ;
}
if ( ! options . prompt ) {
console . error (
chalk . red (
'Error: --prompt parameter is required. Please provide information to add to the subtask.'
)
) ;
console . log (
chalk . yellow (
'Usage example: task-master update-subtask --id=5.2 --prompt="Add more details about the API endpoint"'
)
) ;
process . exit ( 1 ) ;
}
const prompt = options . prompt ;
const useResearch = options . research || false ;
// Validate tasks file exists
if ( ! fs . existsSync ( tasksPath ) ) {
console . error (
chalk . red ( ` Error: Tasks file not found at path: ${ tasksPath } ` )
) ;
2025-05-31 16:21:03 +02:00
if ( tasksPath === TASKMASTER _TASKS _FILE ) {
2025-04-09 00:25:27 +02:00
console . log (
chalk . yellow (
'Hint: Run task-master init or task-master parse-prd to create tasks.json first'
)
) ;
} else {
console . log (
chalk . yellow (
` Hint: Check if the file path is correct: ${ tasksPath } `
)
) ;
}
process . exit ( 1 ) ;
}
console . log (
chalk . blue ( ` Updating subtask ${ subtaskId } with prompt: " ${ prompt } " ` )
) ;
console . log ( chalk . blue ( ` Tasks file: ${ tasksPath } ` ) ) ;
if ( useResearch ) {
// Verify Perplexity API key exists if using research
refactor: Standardize configuration and environment variable access
This commit centralizes configuration and environment variable access across various modules by consistently utilizing getters from scripts/modules/config-manager.js. This replaces direct access to process.env and the global CONFIG object, leading to improved consistency, maintainability, testability, and better handling of session-specific configurations within the MCP context.
Key changes include:
- Centralized Getters: Replaced numerous instances of process.env.* and CONFIG.* with corresponding getter functions (e.g., getLogLevel, getMainModelId, getResearchMaxTokens, getMainTemperature, isApiKeySet, getDebugFlag, getDefaultSubtasks).
- Session Awareness: Ensured that the session object is passed to config getters where necessary, particularly within AI service calls (ai-services.js, add-task.js) and error handling (ai-services.js), allowing for session-specific environment overrides.
- API Key Checks: Standardized API key availability checks using isApiKeySet() instead of directly checking process.env.* (e.g., for Perplexity in commands.js and ai-services.js).
- Client Instantiation Cleanup: Removed now-redundant/obsolete local client instantiation functions (getAnthropicClient, getPerplexityClient) from ai-services.js and the global Anthropic client initialization from dependency-manager.js. Client creation should now rely on the config manager and factory patterns.
- Consistent Debug Flag Usage: Standardized calls to getDebugFlag() in commands.js, removing potentially unnecessary null arguments.
- Accurate Progress Calculation: Updated AI stream progress reporting (ai-services.js, add-task.js) to use getMainMaxTokens(session) for more accurate calculations.
- Minor Cleanup: Removed unused import from scripts/modules/commands.js.
Specific module updates:
- :
- Uses getLogLevel() instead of process.env.LOG_LEVEL.
- :
- Replaced direct env/config access for model IDs, tokens, temperature, API keys, and default subtasks with appropriate getters.
- Passed session to handleClaudeError.
- Removed local getPerplexityClient and getAnthropicClient functions.
- Updated progress calculations to use getMainMaxTokens(session).
- :
- Uses isApiKeySet('perplexity') for API key checks.
- Uses getDebugFlag() consistently for debug checks.
- Removed unused import.
- :
- Removed global Anthropic client initialization.
- :
- Uses config getters (getResearch..., getMain...) for Perplexity and Claude API call parameters, preserving customEnv override logic.
This refactoring also resolves a potential SyntaxError: Identifier 'getPerplexityClient' has already been declared by removing the duplicated/obsolete function definition previously present in ai-services.js.
2025-04-21 21:30:12 -04:00
if ( ! isApiKeySet ( 'perplexity' ) ) {
2025-04-09 00:25:27 +02:00
console . log (
chalk . yellow (
'Warning: PERPLEXITY_API_KEY environment variable is missing. Research-backed updates will not be available.'
)
) ;
console . log (
chalk . yellow ( 'Falling back to Claude AI for subtask update.' )
) ;
} else {
console . log (
chalk . blue (
'Using Perplexity AI for research-backed subtask update'
)
) ;
}
}
const result = await updateSubtaskById (
tasksPath ,
subtaskId ,
prompt ,
useResearch
) ;
if ( ! result ) {
console . log (
chalk . yellow (
'\nSubtask update was not completed. Review the messages above for details.'
)
) ;
}
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
// Provide more helpful error messages for common issues
if (
error . message . includes ( 'subtask' ) &&
error . message . includes ( 'not found' )
) {
console . log ( chalk . yellow ( '\nTo fix this issue:' ) ) ;
console . log (
' 1. Run task-master list --with-subtasks to see all available subtask IDs'
) ;
console . log (
' 2. Use a valid subtask ID with the --id parameter in format "parentId.subtaskId"'
) ;
} else if ( error . message . includes ( 'API key' ) ) {
console . log (
chalk . yellow (
'\nThis error is related to API keys. Check your environment variables.'
)
) ;
}
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
// Use getDebugFlag getter instead of CONFIG.debug
refactor: Standardize configuration and environment variable access
This commit centralizes configuration and environment variable access across various modules by consistently utilizing getters from scripts/modules/config-manager.js. This replaces direct access to process.env and the global CONFIG object, leading to improved consistency, maintainability, testability, and better handling of session-specific configurations within the MCP context.
Key changes include:
- Centralized Getters: Replaced numerous instances of process.env.* and CONFIG.* with corresponding getter functions (e.g., getLogLevel, getMainModelId, getResearchMaxTokens, getMainTemperature, isApiKeySet, getDebugFlag, getDefaultSubtasks).
- Session Awareness: Ensured that the session object is passed to config getters where necessary, particularly within AI service calls (ai-services.js, add-task.js) and error handling (ai-services.js), allowing for session-specific environment overrides.
- API Key Checks: Standardized API key availability checks using isApiKeySet() instead of directly checking process.env.* (e.g., for Perplexity in commands.js and ai-services.js).
- Client Instantiation Cleanup: Removed now-redundant/obsolete local client instantiation functions (getAnthropicClient, getPerplexityClient) from ai-services.js and the global Anthropic client initialization from dependency-manager.js. Client creation should now rely on the config manager and factory patterns.
- Consistent Debug Flag Usage: Standardized calls to getDebugFlag() in commands.js, removing potentially unnecessary null arguments.
- Accurate Progress Calculation: Updated AI stream progress reporting (ai-services.js, add-task.js) to use getMainMaxTokens(session) for more accurate calculations.
- Minor Cleanup: Removed unused import from scripts/modules/commands.js.
Specific module updates:
- :
- Uses getLogLevel() instead of process.env.LOG_LEVEL.
- :
- Replaced direct env/config access for model IDs, tokens, temperature, API keys, and default subtasks with appropriate getters.
- Passed session to handleClaudeError.
- Removed local getPerplexityClient and getAnthropicClient functions.
- Updated progress calculations to use getMainMaxTokens(session).
- :
- Uses isApiKeySet('perplexity') for API key checks.
- Uses getDebugFlag() consistently for debug checks.
- Removed unused import.
- :
- Removed global Anthropic client initialization.
- :
- Uses config getters (getResearch..., getMain...) for Perplexity and Claude API call parameters, preserving customEnv override logic.
This refactoring also resolves a potential SyntaxError: Identifier 'getPerplexityClient' has already been declared by removing the duplicated/obsolete function definition previously present in ai-services.js.
2025-04-21 21:30:12 -04:00
if ( getDebugFlag ( ) ) {
2025-04-09 00:25:27 +02:00
console . error ( error ) ;
}
process . exit ( 1 ) ;
}
} ) ;
// generate command
programInstance
. command ( 'generate' )
. description ( 'Generate task files from tasks.json' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option ( '-o, --output <dir>' , 'Output directory' , 'tasks' )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const outputDir = options . output ;
console . log ( chalk . blue ( ` Generating task files from: ${ tasksPath } ` ) ) ;
console . log ( chalk . blue ( ` Output directory: ${ outputDir } ` ) ) ;
await generateTaskFiles ( tasksPath , outputDir ) ;
} ) ;
// set-status command
programInstance
. command ( 'set-status' )
2025-05-22 04:14:22 -04:00
. alias ( 'mark' )
. alias ( 'set' )
2025-04-09 00:25:27 +02:00
. description ( 'Set the status of a task' )
. option (
'-i, --id <id>' ,
'Task ID (can be comma-separated for multiple tasks)'
)
. option (
'-s, --status <status>' ,
2025-05-16 15:47:01 +02:00
` New status (one of: ${ TASK _STATUS _OPTIONS . join ( ', ' ) } ) `
2025-04-09 00:25:27 +02:00
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const taskId = options . id ;
const status = options . status ;
if ( ! taskId || ! status ) {
console . error ( chalk . red ( 'Error: Both --id and --status are required' ) ) ;
process . exit ( 1 ) ;
}
2025-05-16 15:47:01 +02:00
if ( ! isValidTaskStatus ( status ) ) {
console . error (
chalk . red (
` Error: Invalid status value: ${ status } . Use one of: ${ TASK _STATUS _OPTIONS . join ( ', ' ) } `
)
) ;
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
console . log (
chalk . blue ( ` Setting status of task(s) ${ taskId } to: ${ status } ` )
) ;
await setTaskStatus ( tasksPath , taskId , status ) ;
} ) ;
// list command
programInstance
. command ( 'list' )
. description ( 'List all tasks' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-05-16 23:24:25 +02:00
. option (
'-r, --report <report>' ,
'Path to the complexity report file' ,
2025-05-31 16:21:03 +02:00
COMPLEXITY _REPORT _FILE
2025-05-16 23:24:25 +02:00
)
2025-04-09 00:25:27 +02:00
. option ( '-s, --status <status>' , 'Filter by status' )
. option ( '--with-subtasks' , 'Show subtasks for each task' )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-05-16 23:24:25 +02:00
const reportPath = options . report ;
2025-04-09 00:25:27 +02:00
const statusFilter = options . status ;
const withSubtasks = options . withSubtasks || false ;
console . log ( chalk . blue ( ` Listing tasks from: ${ tasksPath } ` ) ) ;
if ( statusFilter ) {
console . log ( chalk . blue ( ` Filtering by status: ${ statusFilter } ` ) ) ;
}
if ( withSubtasks ) {
console . log ( chalk . blue ( 'Including subtasks in listing' ) ) ;
}
2025-05-16 23:24:25 +02:00
await listTasks ( tasksPath , statusFilter , reportPath , withSubtasks ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// expand command
programInstance
. command ( 'expand' )
2025-04-25 01:26:42 -04:00
. description ( 'Expand a task into subtasks using AI' )
. option ( '-i, --id <id>' , 'ID of the task to expand' )
2025-04-09 00:25:27 +02:00
. option (
2025-04-25 01:26:42 -04:00
'-a, --all' ,
'Expand all pending tasks based on complexity analysis'
2025-04-09 00:25:27 +02:00
)
. option (
2025-04-25 01:26:42 -04:00
'-n, --num <number>' ,
'Number of subtasks to generate (uses complexity analysis by default if available)'
2025-04-09 00:25:27 +02:00
)
. option (
2025-04-25 01:26:42 -04:00
'-r, --research' ,
'Enable research-backed generation (e.g., using Perplexity)' ,
false
2025-04-09 00:25:27 +02:00
)
2025-04-25 01:26:42 -04:00
. option ( '-p, --prompt <text>' , 'Additional context for subtask generation' )
. option ( '-f, --force' , 'Force expansion even if subtasks exist' , false ) // Ensure force option exists
2025-04-09 00:25:27 +02:00
. option (
2025-04-25 01:26:42 -04:00
'--file <file>' ,
'Path to the tasks file (relative to project root)' ,
2025-05-31 16:21:03 +02:00
TASKMASTER _TASKS _FILE // Allow file override
2025-04-25 01:26:42 -04:00
) // Allow file override
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-04-25 01:26:42 -04:00
const projectRoot = findProjectRoot ( ) ;
if ( ! projectRoot ) {
console . error ( chalk . red ( 'Error: Could not find project root.' ) ) ;
process . exit ( 1 ) ;
}
const tasksPath = path . resolve ( projectRoot , options . file ) ; // Resolve tasks path
2025-04-09 00:25:27 +02:00
if ( options . all ) {
2025-04-25 01:26:42 -04:00
// --- Handle expand --all ---
refactor(expand/all): Implement additive expansion and complexity report integration
Refactors the `expandTask` and `expandAllTasks` features to complete subtask 61.38 and enhance functionality based on subtask 61.37's refactor.
Key Changes:
- **Additive Expansion (`expandTask`, `expandAllTasks`):**
- Modified `expandTask` default behavior to append newly generated subtasks to any existing ones.
- Added a `force` flag (passed down from CLI/MCP via `--force` option/parameter) to `expandTask` and `expandAllTasks`. When `force` is true, existing subtasks are cleared before generating new ones.
- Updated relevant CLI command (`expand`), MCP tool (`expand_task`, `expand_all`), and direct function wrappers (`expandTaskDirect`, `expandAllTasksDirect`) to handle and pass the `force` flag.
- **Complexity Report Integration (`expandTask`):**
- `expandTask` now reads `scripts/task-complexity-report.json`.
- If an analysis entry exists for the target task:
- `recommendedSubtasks` is used to determine the number of subtasks to generate (unless `--num` is explicitly provided).
- `expansionPrompt` is used as the primary prompt content for the AI.
- `reasoning` is appended to any additional context provided.
- If no report entry exists or the report is missing, it falls back to default subtask count (from config) and standard prompt generation.
- **`expandAllTasks` Orchestration:**
- Refactored `expandAllTasks` to primarily iterate through eligible tasks (pending/in-progress, considering `force` flag and existing subtasks) and call the updated `expandTask` function for each.
- Removed redundant logic (like complexity reading or explicit subtask clearing) now handled within `expandTask`.
- Ensures correct context (`session`, `mcpLog`) and flags (`useResearch`, `force`) are passed down.
- **Configuration & Cleanup:**
- Updated `.cursor/mcp.json` with new Perplexity/Anthropic API keys (old ones invalidated).
- Completed refactoring of `expandTask` started in 61.37, confirming usage of `generateTextService` and appropriate prompts.
- **Task Management:**
- Marked subtask 61.37 as complete.
- Updated `.changeset/cuddly-zebras-matter.md` to reflect user-facing changes.
These changes finalize the refactoring of the task expansion features, making them more robust, configurable via complexity analysis, and aligned with the unified AI service architecture.
2025-04-25 02:57:08 -04:00
console . log ( chalk . blue ( 'Expanding all pending tasks...' ) ) ;
// Updated call to the refactored expandAllTasks
try {
const result = await expandAllTasks (
tasksPath ,
options . num , // Pass num
options . research , // Pass research flag
options . prompt , // Pass additional context
options . force , // Pass force flag
{ } // Pass empty context for CLI calls
// outputFormat defaults to 'text' in expandAllTasks for CLI
) ;
} catch ( error ) {
console . error (
chalk . red ( ` Error expanding all tasks: ${ error . message } ` )
) ;
process . exit ( 1 ) ;
}
2025-04-25 01:26:42 -04:00
} else if ( options . id ) {
refactor(expand/all): Implement additive expansion and complexity report integration
Refactors the `expandTask` and `expandAllTasks` features to complete subtask 61.38 and enhance functionality based on subtask 61.37's refactor.
Key Changes:
- **Additive Expansion (`expandTask`, `expandAllTasks`):**
- Modified `expandTask` default behavior to append newly generated subtasks to any existing ones.
- Added a `force` flag (passed down from CLI/MCP via `--force` option/parameter) to `expandTask` and `expandAllTasks`. When `force` is true, existing subtasks are cleared before generating new ones.
- Updated relevant CLI command (`expand`), MCP tool (`expand_task`, `expand_all`), and direct function wrappers (`expandTaskDirect`, `expandAllTasksDirect`) to handle and pass the `force` flag.
- **Complexity Report Integration (`expandTask`):**
- `expandTask` now reads `scripts/task-complexity-report.json`.
- If an analysis entry exists for the target task:
- `recommendedSubtasks` is used to determine the number of subtasks to generate (unless `--num` is explicitly provided).
- `expansionPrompt` is used as the primary prompt content for the AI.
- `reasoning` is appended to any additional context provided.
- If no report entry exists or the report is missing, it falls back to default subtask count (from config) and standard prompt generation.
- **`expandAllTasks` Orchestration:**
- Refactored `expandAllTasks` to primarily iterate through eligible tasks (pending/in-progress, considering `force` flag and existing subtasks) and call the updated `expandTask` function for each.
- Removed redundant logic (like complexity reading or explicit subtask clearing) now handled within `expandTask`.
- Ensures correct context (`session`, `mcpLog`) and flags (`useResearch`, `force`) are passed down.
- **Configuration & Cleanup:**
- Updated `.cursor/mcp.json` with new Perplexity/Anthropic API keys (old ones invalidated).
- Completed refactoring of `expandTask` started in 61.37, confirming usage of `generateTextService` and appropriate prompts.
- **Task Management:**
- Marked subtask 61.37 as complete.
- Updated `.changeset/cuddly-zebras-matter.md` to reflect user-facing changes.
These changes finalize the refactoring of the task expansion features, making them more robust, configurable via complexity analysis, and aligned with the unified AI service architecture.
2025-04-25 02:57:08 -04:00
// --- Handle expand --id <id> (Should be correct from previous refactor) ---
2025-04-25 01:26:42 -04:00
if ( ! options . id ) {
console . error (
chalk . red ( 'Error: Task ID is required unless using --all.' )
2025-04-09 00:25:27 +02:00
) ;
2025-04-25 01:26:42 -04:00
process . exit ( 1 ) ;
2025-04-09 00:25:27 +02:00
}
2025-04-25 01:26:42 -04:00
console . log ( chalk . blue ( ` Expanding task ${ options . id } ... ` ) ) ;
refactor(expand/all): Implement additive expansion and complexity report integration
Refactors the `expandTask` and `expandAllTasks` features to complete subtask 61.38 and enhance functionality based on subtask 61.37's refactor.
Key Changes:
- **Additive Expansion (`expandTask`, `expandAllTasks`):**
- Modified `expandTask` default behavior to append newly generated subtasks to any existing ones.
- Added a `force` flag (passed down from CLI/MCP via `--force` option/parameter) to `expandTask` and `expandAllTasks`. When `force` is true, existing subtasks are cleared before generating new ones.
- Updated relevant CLI command (`expand`), MCP tool (`expand_task`, `expand_all`), and direct function wrappers (`expandTaskDirect`, `expandAllTasksDirect`) to handle and pass the `force` flag.
- **Complexity Report Integration (`expandTask`):**
- `expandTask` now reads `scripts/task-complexity-report.json`.
- If an analysis entry exists for the target task:
- `recommendedSubtasks` is used to determine the number of subtasks to generate (unless `--num` is explicitly provided).
- `expansionPrompt` is used as the primary prompt content for the AI.
- `reasoning` is appended to any additional context provided.
- If no report entry exists or the report is missing, it falls back to default subtask count (from config) and standard prompt generation.
- **`expandAllTasks` Orchestration:**
- Refactored `expandAllTasks` to primarily iterate through eligible tasks (pending/in-progress, considering `force` flag and existing subtasks) and call the updated `expandTask` function for each.
- Removed redundant logic (like complexity reading or explicit subtask clearing) now handled within `expandTask`.
- Ensures correct context (`session`, `mcpLog`) and flags (`useResearch`, `force`) are passed down.
- **Configuration & Cleanup:**
- Updated `.cursor/mcp.json` with new Perplexity/Anthropic API keys (old ones invalidated).
- Completed refactoring of `expandTask` started in 61.37, confirming usage of `generateTextService` and appropriate prompts.
- **Task Management:**
- Marked subtask 61.37 as complete.
- Updated `.changeset/cuddly-zebras-matter.md` to reflect user-facing changes.
These changes finalize the refactoring of the task expansion features, making them more robust, configurable via complexity analysis, and aligned with the unified AI service architecture.
2025-04-25 02:57:08 -04:00
try {
// Call the refactored expandTask function
await expandTask (
tasksPath ,
options . id ,
options . num ,
options . research ,
options . prompt ,
{ } , // Pass empty context for CLI calls
options . force // Pass the force flag down
) ;
// expandTask logs its own success/failure for single task
} catch ( error ) {
console . error (
chalk . red ( ` Error expanding task ${ options . id } : ${ error . message } ` )
) ;
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
} else {
console . error (
2025-04-25 01:26:42 -04:00
chalk . red ( 'Error: You must specify either a task ID (--id) or --all.' )
2025-04-09 00:25:27 +02:00
) ;
2025-04-25 01:26:42 -04:00
programInstance . help ( ) ; // Show help
2025-04-09 00:25:27 +02:00
}
} ) ;
// analyze-complexity command
programInstance
. command ( 'analyze-complexity' )
. description (
` Analyze tasks and generate expansion recommendations ${ chalk . reset ( '' ) } `
)
. option (
'-o, --output <file>' ,
'Output file path for the report' ,
2025-05-31 16:21:03 +02:00
COMPLEXITY _REPORT _FILE
2025-04-09 00:25:27 +02:00
)
. option (
'-m, --model <model>' ,
'LLM model to use for analysis (defaults to configured model)'
)
. option (
'-t, --threshold <number>' ,
'Minimum complexity score to recommend expansion (1-10)' ,
'5'
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option (
'-r, --research' ,
'Use Perplexity AI for research-backed complexity analysis'
)
2025-05-22 01:49:41 -04:00
. option (
'-i, --id <ids>' ,
'Comma-separated list of specific task IDs to analyze (e.g., "1,3,5")'
)
2025-05-22 04:17:06 -04:00
. option ( '--from <id>' , 'Starting task ID in a range to analyze' )
. option ( '--to <id>' , 'Ending task ID in a range to analyze' )
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const outputPath = options . output ;
const modelOverride = options . model ;
const thresholdScore = parseFloat ( options . threshold ) ;
const useResearch = options . research || false ;
console . log ( chalk . blue ( ` Analyzing task complexity from: ${ tasksPath } ` ) ) ;
console . log ( chalk . blue ( ` Output report will be saved to: ${ outputPath } ` ) ) ;
2025-05-22 01:49:41 -04:00
if ( options . id ) {
console . log ( chalk . blue ( ` Analyzing specific task IDs: ${ options . id } ` ) ) ;
} else if ( options . from || options . to ) {
const fromStr = options . from ? options . from : 'first' ;
const toStr = options . to ? options . to : 'last' ;
2025-05-22 04:17:06 -04:00
console . log (
chalk . blue ( ` Analyzing tasks in range: ${ fromStr } to ${ toStr } ` )
) ;
2025-05-22 01:49:41 -04:00
}
2025-04-09 00:25:27 +02:00
if ( useResearch ) {
console . log (
chalk . blue (
'Using Perplexity AI for research-backed complexity analysis'
)
) ;
}
await analyzeTaskComplexity ( options ) ;
} ) ;
// clear-subtasks command
programInstance
. command ( 'clear-subtasks' )
. description ( 'Clear subtasks from specified tasks' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option (
'-i, --id <ids>' ,
'Task IDs (comma-separated) to clear subtasks from'
)
. option ( '--all' , 'Clear subtasks from all tasks' )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const taskIds = options . id ;
const all = options . all ;
if ( ! taskIds && ! all ) {
console . error (
chalk . red (
'Error: Please specify task IDs with --id=<ids> or use --all to clear all tasks'
)
) ;
process . exit ( 1 ) ;
}
if ( all ) {
// If --all is specified, get all task IDs
const data = readJSON ( tasksPath ) ;
if ( ! data || ! data . tasks ) {
console . error ( chalk . red ( 'Error: No valid tasks found' ) ) ;
process . exit ( 1 ) ;
}
const allIds = data . tasks . map ( ( t ) => t . id ) . join ( ',' ) ;
clearSubtasks ( tasksPath , allIds ) ;
} else {
clearSubtasks ( tasksPath , taskIds ) ;
}
} ) ;
// add-task command
programInstance
. command ( 'add-task' )
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
. description ( 'Add a new task using AI, optionally providing manual details' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 18:20:47 -04:00
. option (
'-p, --prompt <prompt>' ,
'Description of the task to add (required if not using manual fields)'
)
2025-04-09 18:18:13 -04:00
. option ( '-t, --title <title>' , 'Task title (for manual task creation)' )
2025-04-09 18:20:47 -04:00
. option (
'-d, --description <description>' ,
'Task description (for manual task creation)'
)
. option (
'--details <details>' ,
'Implementation details (for manual task creation)'
)
. option (
'--dependencies <dependencies>' ,
'Comma-separated list of task IDs this task depends on'
)
. option (
'--priority <priority>' ,
'Task priority (high, medium, low)' ,
'medium'
)
. option (
'-r, --research' ,
'Whether to use research capabilities for task creation'
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-04-09 18:18:13 -04:00
const isManualCreation = options . title && options . description ;
2025-04-09 18:20:47 -04:00
2025-04-09 18:18:13 -04:00
// Validate that either prompt or title+description are provided
if ( ! options . prompt && ! isManualCreation ) {
2025-04-09 18:20:47 -04:00
console . error (
chalk . red (
'Error: Either --prompt or both --title and --description must be provided'
)
) ;
2025-04-09 00:25:27 +02:00
process . exit ( 1 ) ;
}
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
if ( ! fs . existsSync ( tasksPath ) ) {
console . error (
` ❌ No tasks.json file found. Please run "task-master init" or create a tasks.json file at ${ TASKMASTER _TASKS _FILE } `
) ;
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
// Correctly determine projectRoot
const projectRoot = findProjectRoot ( ) ;
2025-04-09 18:18:13 -04:00
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
let manualTaskData = null ;
if ( isManualCreation ) {
manualTaskData = {
title : options . title ,
description : options . description ,
details : options . details || '' ,
testStrategy : options . testStrategy || ''
} ;
// Restore specific logging for manual creation
console . log (
chalk . blue ( ` Creating task manually with title: " ${ options . title } " ` )
) ;
} else {
// Restore specific logging for AI creation
console . log (
chalk . blue ( ` Creating task with AI using prompt: " ${ options . prompt } " ` )
) ;
}
2025-04-09 18:18:13 -04:00
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
// Log dependencies and priority if provided (restored)
const dependenciesArray = options . dependencies
? options . dependencies . split ( ',' ) . map ( ( id ) => id . trim ( ) )
: [ ] ;
if ( dependenciesArray . length > 0 ) {
console . log (
chalk . blue ( ` Dependencies: [ ${ dependenciesArray . join ( ', ' ) } ] ` )
) ;
}
if ( options . priority ) {
console . log ( chalk . blue ( ` Priority: ${ options . priority } ` ) ) ;
}
const context = {
projectRoot ,
commandName : 'add-task' ,
outputType : 'cli'
} ;
try {
const { newTaskId , telemetryData } = await addTask (
tasksPath ,
options . prompt ,
dependenciesArray ,
2025-04-09 18:18:13 -04:00
options . priority ,
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
context ,
'text' ,
manualTaskData ,
options . research
2025-04-09 18:18:13 -04:00
) ;
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
// addTask handles detailed CLI success logging AND telemetry display when outputFormat is 'text'
// No need to call displayAiUsageSummary here anymore.
2025-04-09 18:18:13 -04:00
} catch ( error ) {
console . error ( chalk . red ( ` Error adding task: ${ error . message } ` ) ) ;
feat(telemetry): Implement AI usage telemetry pattern and apply to add-task
This commit introduces a standardized pattern for capturing and propagating AI usage telemetry (cost, tokens, model used) across the Task Master stack and applies it to the 'add-task' functionality.
Key changes include:
- **Telemetry Pattern Definition:**
- Added defining the integration pattern for core logic, direct functions, MCP tools, and CLI commands.
- Updated related rules (, ,
Usage: mcp [OPTIONS] COMMAND [ARGS]...
MCP development tools
╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ version Show the MCP version. │
│ dev Run a MCP server with the MCP Inspector. │
│ run Run a MCP server. │
│ install Install a MCP server in the Claude desktop app. │
╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯, , ) to reference the new telemetry rule.
- **Core Telemetry Implementation ():**
- Refactored the unified AI service to generate and return a object alongside the main AI result.
- Fixed an MCP server startup crash by removing redundant local loading of and instead using the imported from for cost calculations.
- Added to the object.
- ** Integration:**
- Modified (core) to receive from the AI service, return it, and call the new UI display function for CLI output.
- Updated to receive from the core function and include it in the payload of its response.
- Ensured (MCP tool) correctly passes the through via .
- Updated to correctly pass context (, ) to the core function and rely on it for CLI telemetry display.
- **UI Enhancement:**
- Added function to to show telemetry details in the CLI.
- **Project Management:**
- Added subtasks 77.6 through 77.12 to track the rollout of this telemetry pattern to other AI-powered commands (, , , , , , ).
This establishes the foundation for tracking AI usage across the application.
2025-05-07 13:41:25 -04:00
if ( error . details ) {
console . error ( chalk . red ( error . details ) ) ;
2025-04-09 18:18:13 -04:00
}
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
} ) ;
// next command
programInstance
. command ( 'next' )
. description (
` Show the next task to work on based on dependencies and status ${ chalk . reset ( '' ) } `
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-05-16 23:24:25 +02:00
. option (
'-r, --report <report>' ,
'Path to the complexity report file' ,
2025-05-31 16:21:03 +02:00
COMPLEXITY _REPORT _FILE
2025-05-16 23:24:25 +02:00
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-05-16 23:24:25 +02:00
const reportPath = options . report ;
2025-05-31 16:21:03 +02:00
2025-05-16 23:24:25 +02:00
await displayNextTask ( tasksPath , reportPath ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// show command
programInstance
. command ( 'show' )
. description (
` Display detailed information about a specific task ${ chalk . reset ( '' ) } `
)
. argument ( '[id]' , 'Task ID to show' )
. option ( '-i, --id <id>' , 'Task ID to show' )
2025-04-27 18:50:47 -04:00
. option ( '-s, --status <status>' , 'Filter subtasks by status' ) // ADDED status option
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-05-16 23:24:25 +02:00
. option (
'-r, --report <report>' ,
'Path to the complexity report file' ,
2025-05-31 16:21:03 +02:00
COMPLEXITY _REPORT _FILE
2025-05-16 23:24:25 +02:00
)
2025-04-09 00:25:27 +02:00
. action ( async ( taskId , options ) => {
const idArg = taskId || options . id ;
2025-04-27 18:50:47 -04:00
const statusFilter = options . status ; // ADDED: Capture status filter
2025-04-09 00:25:27 +02:00
if ( ! idArg ) {
console . error ( chalk . red ( 'Error: Please provide a task ID' ) ) ;
process . exit ( 1 ) ;
}
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-05-16 23:24:25 +02:00
const reportPath = options . report ;
2025-04-27 18:50:47 -04:00
// PASS statusFilter to the display function
2025-05-16 23:24:25 +02:00
await displayTaskById ( tasksPath , idArg , reportPath , statusFilter ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// add-dependency command
programInstance
. command ( 'add-dependency' )
. description ( 'Add a dependency to a task' )
. option ( '-i, --id <id>' , 'Task ID to add dependency to' )
. option ( '-d, --depends-on <id>' , 'Task ID that will become a dependency' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const taskId = options . id ;
const dependencyId = options . dependsOn ;
if ( ! taskId || ! dependencyId ) {
console . error (
chalk . red ( 'Error: Both --id and --depends-on are required' )
) ;
process . exit ( 1 ) ;
}
// Handle subtask IDs correctly by preserving the string format for IDs containing dots
// Only use parseInt for simple numeric IDs
const formattedTaskId = taskId . includes ( '.' )
? taskId
: parseInt ( taskId , 10 ) ;
const formattedDependencyId = dependencyId . includes ( '.' )
? dependencyId
: parseInt ( dependencyId , 10 ) ;
await addDependency ( tasksPath , formattedTaskId , formattedDependencyId ) ;
} ) ;
// remove-dependency command
programInstance
. command ( 'remove-dependency' )
. description ( 'Remove a dependency from a task' )
. option ( '-i, --id <id>' , 'Task ID to remove dependency from' )
. option ( '-d, --depends-on <id>' , 'Task ID to remove as a dependency' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const taskId = options . id ;
const dependencyId = options . dependsOn ;
if ( ! taskId || ! dependencyId ) {
console . error (
chalk . red ( 'Error: Both --id and --depends-on are required' )
) ;
process . exit ( 1 ) ;
}
// Handle subtask IDs correctly by preserving the string format for IDs containing dots
// Only use parseInt for simple numeric IDs
const formattedTaskId = taskId . includes ( '.' )
? taskId
: parseInt ( taskId , 10 ) ;
const formattedDependencyId = dependencyId . includes ( '.' )
? dependencyId
: parseInt ( dependencyId , 10 ) ;
await removeDependency ( tasksPath , formattedTaskId , formattedDependencyId ) ;
} ) ;
// validate-dependencies command
programInstance
. command ( 'validate-dependencies' )
. description (
` Identify invalid dependencies without fixing them ${ chalk . reset ( '' ) } `
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
await validateDependenciesCommand ( options . file || TASKMASTER _TASKS _FILE ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// fix-dependencies command
programInstance
. command ( 'fix-dependencies' )
. description ( ` Fix invalid dependencies automatically ${ chalk . reset ( '' ) } ` )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
await fixDependenciesCommand ( options . file || TASKMASTER _TASKS _FILE ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// complexity-report command
programInstance
. command ( 'complexity-report' )
. description ( ` Display the complexity analysis report ${ chalk . reset ( '' ) } ` )
. option (
'-f, --file <file>' ,
'Path to the report file' ,
2025-05-31 16:21:03 +02:00
COMPLEXITY _REPORT _FILE
2025-04-09 00:25:27 +02:00
)
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
await displayComplexityReport ( options . file || COMPLEXITY _REPORT _FILE ) ;
2025-04-09 00:25:27 +02:00
} ) ;
// add-subtask command
programInstance
. command ( 'add-subtask' )
. description ( 'Add a subtask to an existing task' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option ( '-p, --parent <id>' , 'Parent task ID (required)' )
. option ( '-i, --task-id <id>' , 'Existing task ID to convert to subtask' )
. option (
'-t, --title <title>' ,
'Title for the new subtask (when creating a new subtask)'
)
. option ( '-d, --description <text>' , 'Description for the new subtask' )
. option ( '--details <text>' , 'Implementation details for the new subtask' )
. option (
'--dependencies <ids>' ,
'Comma-separated list of dependency IDs for the new subtask'
)
. option ( '-s, --status <status>' , 'Status for the new subtask' , 'pending' )
. option ( '--skip-generate' , 'Skip regenerating task files' )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const parentId = options . parent ;
const existingTaskId = options . taskId ;
const generateFiles = ! options . skipGenerate ;
if ( ! parentId ) {
console . error (
chalk . red (
'Error: --parent parameter is required. Please provide a parent task ID.'
)
) ;
showAddSubtaskHelp ( ) ;
process . exit ( 1 ) ;
}
// Parse dependencies if provided
let dependencies = [ ] ;
if ( options . dependencies ) {
dependencies = options . dependencies . split ( ',' ) . map ( ( id ) => {
// Handle both regular IDs and dot notation
return id . includes ( '.' ) ? id . trim ( ) : parseInt ( id . trim ( ) , 10 ) ;
} ) ;
}
try {
if ( existingTaskId ) {
// Convert existing task to subtask
console . log (
chalk . blue (
` Converting task ${ existingTaskId } to a subtask of ${ parentId } ... `
)
) ;
await addSubtask (
tasksPath ,
parentId ,
existingTaskId ,
null ,
generateFiles
) ;
console . log (
chalk . green (
` ✓ Task ${ existingTaskId } successfully converted to a subtask of task ${ parentId } `
)
) ;
} else if ( options . title ) {
// Create new subtask with provided data
console . log (
chalk . blue ( ` Creating new subtask for parent task ${ parentId } ... ` )
) ;
const newSubtaskData = {
title : options . title ,
description : options . description || '' ,
details : options . details || '' ,
status : options . status || 'pending' ,
dependencies : dependencies
} ;
const subtask = await addSubtask (
tasksPath ,
parentId ,
null ,
newSubtaskData ,
generateFiles
) ;
console . log (
chalk . green (
` ✓ New subtask ${ parentId } . ${ subtask . id } successfully created `
)
) ;
// Display success message and suggested next steps
console . log (
boxen (
chalk . white . bold (
` Subtask ${ parentId } . ${ subtask . id } Added Successfully `
) +
'\n\n' +
chalk . white ( ` Title: ${ subtask . title } ` ) +
'\n' +
chalk . white ( ` Status: ${ getStatusWithColor ( subtask . status ) } ` ) +
'\n' +
( dependencies . length > 0
? chalk . white ( ` Dependencies: ${ dependencies . join ( ', ' ) } ` ) +
'\n'
: '' ) +
'\n' +
chalk . white . bold ( 'Next Steps:' ) +
'\n' +
chalk . cyan (
` 1. Run ${ chalk . yellow ( ` task-master show ${ parentId } ` ) } to see the parent task with all subtasks `
) +
'\n' +
chalk . cyan (
` 2. Run ${ chalk . yellow ( ` task-master set-status --id= ${ parentId } . ${ subtask . id } --status=in-progress ` ) } to start working on it `
) ,
{
padding : 1 ,
borderColor : 'green' ,
borderStyle : 'round' ,
margin : { top : 1 }
}
)
) ;
} else {
console . error (
chalk . red ( 'Error: Either --task-id or --title must be provided.' )
) ;
console . log (
boxen (
chalk . white . bold ( 'Usage Examples:' ) +
'\n\n' +
chalk . white ( 'Convert existing task to subtask:' ) +
'\n' +
chalk . yellow (
` task-master add-subtask --parent=5 --task-id=8 `
) +
'\n\n' +
chalk . white ( 'Create new subtask:' ) +
'\n' +
chalk . yellow (
` task-master add-subtask --parent=5 --title="Implement login UI" --description="Create the login form" `
) +
'\n\n' ,
{ padding : 1 , borderColor : 'blue' , borderStyle : 'round' }
)
) ;
process . exit ( 1 ) ;
}
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
2025-05-15 22:41:16 +02:00
showAddSubtaskHelp ( ) ;
2025-04-09 00:25:27 +02:00
process . exit ( 1 ) ;
}
} )
. on ( 'error' , function ( err ) {
console . error ( chalk . red ( ` Error: ${ err . message } ` ) ) ;
showAddSubtaskHelp ( ) ;
process . exit ( 1 ) ;
} ) ;
// Helper function to show add-subtask command help
function showAddSubtaskHelp ( ) {
console . log (
boxen (
2025-05-31 16:21:03 +02:00
` ${ chalk . white . bold ( 'Add Subtask Command Help' ) } \n \n ${ chalk . cyan ( 'Usage:' ) } \n task-master add-subtask --parent=<id> [options] \n \n ${ chalk . cyan ( 'Options:' ) } \n -p, --parent <id> Parent task ID (required) \n -i, --task-id <id> Existing task ID to convert to subtask \n -t, --title <title> Title for the new subtask \n -d, --description <text> Description for the new subtask \n --details <text> Implementation details for the new subtask \n --dependencies <ids> Comma-separated list of dependency IDs \n -s, --status <status> Status for the new subtask (default: "pending") \n -f, --file <file> Path to the tasks file (default: " ${ TASKMASTER _TASKS _FILE } ") \n --skip-generate Skip regenerating task files \n \n ${ chalk . cyan ( 'Examples:' ) } \n task-master add-subtask --parent=5 --task-id=8 \n task-master add-subtask -p 5 -t "Implement login UI" -d "Create the login form" ` ,
2025-04-09 00:25:27 +02:00
{ padding : 1 , borderColor : 'blue' , borderStyle : 'round' }
)
) ;
}
// remove-subtask command
programInstance
. command ( 'remove-subtask' )
. description ( 'Remove a subtask from its parent task' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option (
'-i, --id <id>' ,
'Subtask ID(s) to remove in format "parentId.subtaskId" (can be comma-separated for multiple subtasks)'
)
. option (
'-c, --convert' ,
'Convert the subtask to a standalone task instead of deleting it'
)
. option ( '--skip-generate' , 'Skip regenerating task files' )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-09 00:25:27 +02:00
const subtaskIds = options . id ;
const convertToTask = options . convert || false ;
const generateFiles = ! options . skipGenerate ;
if ( ! subtaskIds ) {
console . error (
chalk . red (
'Error: --id parameter is required. Please provide subtask ID(s) in format "parentId.subtaskId".'
)
) ;
showRemoveSubtaskHelp ( ) ;
process . exit ( 1 ) ;
}
try {
// Split by comma to support multiple subtask IDs
const subtaskIdArray = subtaskIds . split ( ',' ) . map ( ( id ) => id . trim ( ) ) ;
for ( const subtaskId of subtaskIdArray ) {
// Validate subtask ID format
if ( ! subtaskId . includes ( '.' ) ) {
console . error (
chalk . red (
` Error: Subtask ID " ${ subtaskId } " must be in format "parentId.subtaskId" `
)
) ;
showRemoveSubtaskHelp ( ) ;
process . exit ( 1 ) ;
}
console . log ( chalk . blue ( ` Removing subtask ${ subtaskId } ... ` ) ) ;
if ( convertToTask ) {
console . log (
chalk . blue ( 'The subtask will be converted to a standalone task' )
) ;
}
const result = await removeSubtask (
tasksPath ,
subtaskId ,
convertToTask ,
generateFiles
) ;
if ( convertToTask && result ) {
// Display success message and next steps for converted task
console . log (
boxen (
chalk . white . bold (
` Subtask ${ subtaskId } Converted to Task # ${ result . id } `
) +
'\n\n' +
chalk . white ( ` Title: ${ result . title } ` ) +
'\n' +
chalk . white ( ` Status: ${ getStatusWithColor ( result . status ) } ` ) +
'\n' +
chalk . white (
` Dependencies: ${ result . dependencies . join ( ', ' ) } `
) +
'\n\n' +
chalk . white . bold ( 'Next Steps:' ) +
'\n' +
chalk . cyan (
` 1. Run ${ chalk . yellow ( ` task-master show ${ result . id } ` ) } to see details of the new task `
) +
'\n' +
chalk . cyan (
` 2. Run ${ chalk . yellow ( ` task-master set-status --id= ${ result . id } --status=in-progress ` ) } to start working on it `
) ,
{
padding : 1 ,
borderColor : 'green' ,
borderStyle : 'round' ,
margin : { top : 1 }
}
)
) ;
} else {
// Display success message for deleted subtask
console . log (
boxen (
chalk . white . bold ( ` Subtask ${ subtaskId } Removed ` ) +
'\n\n' +
chalk . white ( 'The subtask has been successfully deleted.' ) ,
{
padding : 1 ,
borderColor : 'green' ,
borderStyle : 'round' ,
margin : { top : 1 }
}
)
) ;
}
}
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
showRemoveSubtaskHelp ( ) ;
process . exit ( 1 ) ;
}
} )
. on ( 'error' , function ( err ) {
console . error ( chalk . red ( ` Error: ${ err . message } ` ) ) ;
showRemoveSubtaskHelp ( ) ;
process . exit ( 1 ) ;
} ) ;
// Helper function to show remove-subtask command help
function showRemoveSubtaskHelp ( ) {
console . log (
boxen (
chalk . white . bold ( 'Remove Subtask Command Help' ) +
'\n\n' +
chalk . cyan ( 'Usage:' ) +
'\n' +
` task-master remove-subtask --id=<parentId.subtaskId> [options] \n \n ` +
chalk . cyan ( 'Options:' ) +
'\n' +
' -i, --id <id> Subtask ID(s) to remove in format "parentId.subtaskId" (can be comma-separated, required)\n' +
' -c, --convert Convert the subtask to a standalone task instead of deleting it\n' +
2025-05-31 16:21:03 +02:00
' -f, --file <file> Path to the tasks file (default: "' +
TASKMASTER _TASKS _FILE +
'")\n' +
2025-04-09 00:25:27 +02:00
' --skip-generate Skip regenerating task files\n\n' +
chalk . cyan ( 'Examples:' ) +
'\n' +
' task-master remove-subtask --id=5.2\n' +
' task-master remove-subtask --id=5.2,6.3,7.1\n' +
' task-master remove-subtask --id=5.2 --convert' ,
{ padding : 1 , borderColor : 'blue' , borderStyle : 'round' }
)
) ;
}
// remove-task command
programInstance
. command ( 'remove-task' )
2025-04-28 00:41:32 -04:00
. description ( 'Remove one or more tasks or subtasks permanently' )
2025-04-29 01:54:42 -04:00
. description ( 'Remove one or more tasks or subtasks permanently' )
2025-04-09 00:25:27 +02:00
. option (
2025-04-28 00:41:32 -04:00
'-i, --id <ids>' ,
'ID(s) of the task(s) or subtask(s) to remove (e.g., "5", "5.2", or "5,6.1,7")'
2025-04-09 00:25:27 +02:00
)
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-04-09 00:25:27 +02:00
. option ( '-y, --yes' , 'Skip confirmation prompt' , false )
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-04-28 00:41:32 -04:00
const taskIdsString = options . id ;
2025-04-09 00:25:27 +02:00
2025-04-28 00:41:32 -04:00
if ( ! taskIdsString ) {
console . error ( chalk . red ( 'Error: Task ID(s) are required' ) ) ;
2025-04-09 00:25:27 +02:00
console . error (
2025-04-28 00:41:32 -04:00
chalk . yellow (
'Usage: task-master remove-task --id=<taskId1,taskId2...>'
)
2025-04-09 00:25:27 +02:00
) ;
process . exit ( 1 ) ;
}
2025-04-28 00:41:32 -04:00
const taskIdsToRemove = taskIdsString
. split ( ',' )
. map ( ( id ) => id . trim ( ) )
. filter ( Boolean ) ;
if ( taskIdsToRemove . length === 0 ) {
console . error ( chalk . red ( 'Error: No valid task IDs provided.' ) ) ;
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
try {
2025-04-28 00:41:32 -04:00
// Read data once for checks and confirmation
2025-04-09 00:25:27 +02:00
const data = readJSON ( tasksPath ) ;
if ( ! data || ! data . tasks ) {
console . error (
chalk . red ( ` Error: No valid tasks found in ${ tasksPath } ` )
) ;
process . exit ( 1 ) ;
}
2025-04-28 00:41:32 -04:00
const existingTasksToRemove = [ ] ;
const nonExistentIds = [ ] ;
let totalSubtasksToDelete = 0 ;
const dependentTaskMessages = [ ] ;
for ( const taskId of taskIdsToRemove ) {
if ( ! taskExists ( data . tasks , taskId ) ) {
nonExistentIds . push ( taskId ) ;
} else {
// Correctly extract the task object from the result of findTaskById
const findResult = findTaskById ( data . tasks , taskId ) ;
const taskObject = findResult . task ; // Get the actual task/subtask object
if ( taskObject ) {
existingTasksToRemove . push ( { id : taskId , task : taskObject } ) ; // Push the actual task object
// If it's a main task, count its subtasks and check dependents
if ( ! taskObject . isSubtask ) {
// Check the actual task object
if ( taskObject . subtasks && taskObject . subtasks . length > 0 ) {
totalSubtasksToDelete += taskObject . subtasks . length ;
}
const dependentTasks = data . tasks . filter (
( t ) =>
t . dependencies &&
t . dependencies . includes ( parseInt ( taskId , 10 ) )
) ;
if ( dependentTasks . length > 0 ) {
dependentTaskMessages . push (
` - Task ${ taskId } : ${ dependentTasks . length } dependent tasks ( ${ dependentTasks . map ( ( t ) => t . id ) . join ( ', ' ) } ) `
) ;
}
}
} else {
// Handle case where findTaskById returned null for the task property (should be rare)
nonExistentIds . push ( ` ${ taskId } (error finding details) ` ) ;
}
}
}
if ( nonExistentIds . length > 0 ) {
console . warn (
chalk . yellow (
` Warning: The following task IDs were not found: ${ nonExistentIds . join ( ', ' ) } `
)
) ;
2025-04-09 00:25:27 +02:00
}
2025-04-28 00:41:32 -04:00
if ( existingTasksToRemove . length === 0 ) {
console . log ( chalk . blue ( 'No existing tasks found to remove.' ) ) ;
process . exit ( 0 ) ;
}
2025-04-09 00:25:27 +02:00
// Skip confirmation if --yes flag is provided
if ( ! options . yes ) {
console . log ( ) ;
console . log (
chalk . red . bold (
2025-04-28 00:41:32 -04:00
` ⚠️ WARNING: This will permanently delete the following ${ existingTasksToRemove . length } item(s): `
2025-04-09 00:25:27 +02:00
)
) ;
console . log ( ) ;
2025-04-28 00:41:32 -04:00
existingTasksToRemove . forEach ( ( { id , task } ) => {
if ( ! task ) return ; // Should not happen due to taskExists check, but safeguard
if ( task . isSubtask ) {
// Subtask - title is directly on the task object
2025-04-09 00:25:27 +02:00
console . log (
2025-04-28 00:41:32 -04:00
chalk . white ( ` Subtask ${ id } : ${ task . title || '(no title)' } ` )
) ;
// Optionally show parent context if available
if ( task . parentTask ) {
console . log (
chalk . gray (
` (Parent: ${ task . parentTask . id } - ${ task . parentTask . title || '(no title)' } ) `
)
) ;
}
} else {
// Main task - title is directly on the task object
console . log (
chalk . white . bold ( ` Task ${ id } : ${ task . title || '(no title)' } ` )
2025-04-09 00:25:27 +02:00
) ;
}
2025-04-28 00:41:32 -04:00
} ) ;
2025-04-09 00:25:27 +02:00
2025-04-28 00:41:32 -04:00
if ( totalSubtasksToDelete > 0 ) {
console . log (
chalk . yellow (
` ⚠️ This will also delete ${ totalSubtasksToDelete } subtasks associated with the selected main tasks! `
)
2025-04-09 00:25:27 +02:00
) ;
2025-04-28 00:41:32 -04:00
}
2025-04-09 00:25:27 +02:00
2025-04-28 00:41:32 -04:00
if ( dependentTaskMessages . length > 0 ) {
console . log (
chalk . yellow (
'⚠️ Warning: Dependencies on the following tasks will be removed:'
)
) ;
dependentTaskMessages . forEach ( ( msg ) =>
console . log ( chalk . yellow ( msg ) )
) ;
2025-04-09 00:25:27 +02:00
}
console . log ( ) ;
const { confirm } = await inquirer . prompt ( [
{
type : 'confirm' ,
name : 'confirm' ,
message : chalk . red . bold (
2025-04-28 00:41:32 -04:00
` Are you sure you want to permanently delete these ${ existingTasksToRemove . length } item(s)? `
2025-04-09 00:25:27 +02:00
) ,
default : false
}
] ) ;
if ( ! confirm ) {
console . log ( chalk . blue ( 'Task deletion cancelled.' ) ) ;
process . exit ( 0 ) ;
}
}
2025-04-28 00:41:32 -04:00
const indicator = startLoadingIndicator (
` Removing ${ existingTasksToRemove . length } task(s)/subtask(s)... `
) ;
2025-04-09 00:25:27 +02:00
2025-04-28 00:41:32 -04:00
// Use the string of existing IDs for the core function
const existingIdsString = existingTasksToRemove
. map ( ( { id } ) => id )
. join ( ',' ) ;
const result = await removeTask ( tasksPath , existingIdsString ) ;
2025-04-09 00:25:27 +02:00
stopLoadingIndicator ( indicator ) ;
2025-04-28 00:41:32 -04:00
if ( result . success ) {
2025-04-09 00:25:27 +02:00
console . log (
boxen (
2025-04-28 00:41:32 -04:00
chalk . green (
` Successfully removed ${ result . removedTasks . length } task(s)/subtask(s). `
) +
( result . message ? ` \n \n Details: \n ${ result . message } ` : '' ) +
( result . error
? ` \n \n Warnings: \n ${ chalk . yellow ( result . error ) } `
: '' ) ,
2025-04-09 00:25:27 +02:00
{ padding : 1 , borderColor : 'green' , borderStyle : 'round' }
)
) ;
} else {
2025-04-28 00:41:32 -04:00
console . error (
boxen (
chalk . red (
` Operation completed with errors. Removed ${ result . removedTasks . length } task(s)/subtask(s). `
) +
( result . message ? ` \n \n Details: \n ${ result . message } ` : '' ) +
( result . error ? ` \n \n Errors: \n ${ chalk . red ( result . error ) } ` : '' ) ,
{
padding : 1 ,
borderColor : 'red' ,
borderStyle : 'round'
}
)
) ;
process . exit ( 1 ) ; // Exit with error code if any part failed
}
// Log any initially non-existent IDs again for clarity
if ( nonExistentIds . length > 0 ) {
console . warn (
chalk . yellow (
` Note: The following IDs were not found initially and were skipped: ${ nonExistentIds . join ( ', ' ) } `
)
2025-04-09 00:25:27 +02:00
) ;
2025-04-19 10:55:59 +02:00
// Exit with error if any removals failed
fix(ai,tasks): Enhance AI provider robustness and task processing
This commit introduces several improvements to AI interactions and
task management functionalities:
- AI Provider Enhancements (for Telemetry & Robustness):
- :
- Added a check in to ensure
is a string, throwing an error if not. This prevents downstream
errors (e.g., in ).
- , , :
- Standardized return structures for their respective
and functions to consistently include /
and fields. This aligns them with other providers (like
Anthropic, Google, Perplexity) for consistent telemetry data
collection, as part of implementing subtask 77.14 and similar work.
- Task Expansion ():
- Updated to be more explicit
about using an empty array for empty to
better guide AI output.
- Implemented a pre-emptive cleanup step in
to replace malformed with
before JSON parsing. This improves resilience to AI output quirks,
particularly observed with Perplexity.
- Adjusts issue in commands.js where successfulRemovals would be undefined. It's properly invoked from the result variable now.
- Updates supported models for Gemini
These changes address issues observed during E2E tests, enhance the
reliability of AI-driven task analysis and expansion, and promote
consistent telemetry data across multiple AI providers.
2025-05-14 19:04:03 -04:00
if ( result . removedTasks . length === 0 ) {
2025-04-19 10:55:59 +02:00
process . exit ( 1 ) ;
}
2025-04-09 00:25:27 +02:00
}
} catch ( error ) {
console . error (
chalk . red ( ` Error: ${ error . message || 'An unknown error occurred' } ` )
) ;
process . exit ( 1 ) ;
}
} ) ;
2025-04-10 22:32:08 -04:00
// init command (Directly calls the implementation from init.js)
programInstance
. command ( 'init' )
. description ( 'Initialize a new project with Task Master structure' )
. option ( '-y, --yes' , 'Skip prompts and use default values' )
. option ( '-n, --name <name>' , 'Project name' )
. option ( '-d, --description <description>' , 'Project description' )
. option ( '-v, --version <version>' , 'Project version' , '0.1.0' ) // Set default here
. option ( '-a, --author <author>' , 'Author name' )
. option ( '--skip-install' , 'Skip installing dependencies' )
. option ( '--dry-run' , 'Show what would be done without making changes' )
. option ( '--aliases' , 'Add shell aliases (tm, taskmaster)' )
. action ( async ( cmdOptions ) => {
// cmdOptions contains parsed arguments
try {
console . log ( 'DEBUG: Running init command action in commands.js' ) ;
console . log (
'DEBUG: Options received by action:' ,
JSON . stringify ( cmdOptions )
) ;
// Directly call the initializeProject function, passing the parsed options
await initializeProject ( cmdOptions ) ;
// initializeProject handles its own flow, including potential process.exit()
} catch ( error ) {
console . error (
chalk . red ( ` Error during initialization: ${ error . message } ` )
) ;
process . exit ( 1 ) ;
}
} ) ;
2025-04-16 00:35:30 -04:00
// models command
programInstance
. command ( 'models' )
. description ( 'Manage AI model configurations' )
. option (
'--set-main <model_id>' ,
'Set the primary model for task generation/updates'
)
. option (
'--set-research <model_id>' ,
'Set the model for research-backed operations'
)
. option (
'--set-fallback <model_id>' ,
'Set the model to use if the primary fails'
)
. option ( '--setup' , 'Run interactive setup to configure models' )
2025-04-27 17:25:54 -04:00
. option (
'--openrouter' ,
'Allow setting a custom OpenRouter model ID (use with --set-*) '
)
. option (
'--ollama' ,
'Allow setting a custom Ollama model ID (use with --set-*) '
)
2025-05-28 00:42:31 +02:00
. option (
'--bedrock' ,
'Allow setting a custom Bedrock model ID (use with --set-*) '
)
2025-04-27 17:32:59 -04:00
. addHelpText (
'after' ,
`
Examples :
$ task - master models # View current configuration
$ task - master models -- set - main gpt - 4 o # Set main model ( provider inferred )
$ task - master models -- set - research sonar - pro # Set research model
$ task - master models -- set - fallback claude - 3 - 5 - sonnet - 20241022 # Set fallback
$ task - master models -- set - main my - custom - model -- ollama # Set custom Ollama model for main role
2025-05-28 00:42:31 +02:00
$ task - master models -- set - main anthropic . claude - 3 - sonnet - 20240229 - v1 : 0 -- bedrock # Set custom Bedrock model for main role
2025-04-27 17:32:59 -04:00
$ task - master models -- set - main some / other - model -- openrouter # Set custom OpenRouter model for main role
$ task - master models -- setup # Run interactive setup `
)
2025-04-16 00:35:30 -04:00
. action ( async ( options ) => {
2025-05-28 00:32:34 +02:00
const projectRoot = findProjectRoot ( ) ;
if ( ! projectRoot ) {
console . error ( chalk . red ( 'Error: Could not find project root.' ) ) ;
process . exit ( 1 ) ;
}
2025-05-28 00:42:31 +02:00
// Validate flags: cannot use multiple provider flags simultaneously
const providerFlags = [
options . openrouter ,
options . ollama ,
options . bedrock
] . filter ( Boolean ) . length ;
if ( providerFlags > 1 ) {
2025-04-27 17:25:54 -04:00
console . error (
chalk . red (
2025-05-28 00:42:31 +02:00
'Error: Cannot use multiple provider flags (--openrouter, --ollama, --bedrock) simultaneously.'
2025-04-27 17:25:54 -04:00
)
) ;
process . exit ( 1 ) ;
}
2025-04-29 01:54:42 -04:00
// Determine the primary action based on flags
const isSetup = options . setup ;
const isSetOperation =
options . setMain || options . setResearch || options . setFallback ;
// --- Execute Action ---
if ( isSetup ) {
// Action 1: Run Interactive Setup
console . log ( chalk . blue ( 'Starting interactive model setup...' ) ) ; // Added feedback
try {
await runInteractiveSetup ( projectRoot ) ;
// runInteractiveSetup logs its own completion/error messages
} catch ( setupError ) {
console . error (
chalk . red ( '\\nInteractive setup failed unexpectedly:' ) ,
setupError . message
) ;
}
// --- IMPORTANT: Exit after setup ---
return ; // Stop execution here
2025-04-27 03:56:23 -04:00
}
2025-04-29 01:54:42 -04:00
if ( isSetOperation ) {
// Action 2: Perform Direct Set Operations
let updateOccurred = false ; // Track if any update actually happened
2025-04-27 03:56:23 -04:00
if ( options . setMain ) {
const result = await setModel ( 'main' , options . setMain , {
2025-04-27 17:25:54 -04:00
projectRoot ,
providerHint : options . openrouter
? 'openrouter'
: options . ollama
? 'ollama'
2025-05-28 00:42:31 +02:00
: options . bedrock
? 'bedrock'
: undefined
2025-04-27 03:56:23 -04:00
} ) ;
if ( result . success ) {
console . log ( chalk . green ( ` ✅ ${ result . data . message } ` ) ) ;
2025-04-29 01:54:42 -04:00
if ( result . data . warning )
2025-04-27 17:25:54 -04:00
console . log ( chalk . yellow ( result . data . warning ) ) ;
2025-04-29 01:54:42 -04:00
updateOccurred = true ;
2025-04-23 15:47:33 -04:00
} else {
2025-04-29 01:54:42 -04:00
console . error (
chalk . red ( ` ❌ Error setting main model: ${ result . error . message } ` )
) ;
2025-04-16 00:35:30 -04:00
}
}
2025-04-27 03:56:23 -04:00
if ( options . setResearch ) {
const result = await setModel ( 'research' , options . setResearch , {
2025-04-27 17:25:54 -04:00
projectRoot ,
providerHint : options . openrouter
? 'openrouter'
: options . ollama
? 'ollama'
2025-05-28 00:42:31 +02:00
: options . bedrock
? 'bedrock'
: undefined
2025-04-27 01:23:18 -04:00
} ) ;
2025-04-27 03:56:23 -04:00
if ( result . success ) {
console . log ( chalk . green ( ` ✅ ${ result . data . message } ` ) ) ;
2025-04-29 01:54:42 -04:00
if ( result . data . warning )
2025-04-27 17:25:54 -04:00
console . log ( chalk . yellow ( result . data . warning ) ) ;
2025-04-29 01:54:42 -04:00
updateOccurred = true ;
2025-04-27 03:56:23 -04:00
} else {
2025-04-29 01:54:42 -04:00
console . error (
chalk . red (
` ❌ Error setting research model: ${ result . error . message } `
)
) ;
2025-04-16 00:35:30 -04:00
}
2025-04-27 03:56:23 -04:00
}
if ( options . setFallback ) {
const result = await setModel ( 'fallback' , options . setFallback , {
2025-04-27 17:25:54 -04:00
projectRoot ,
providerHint : options . openrouter
? 'openrouter'
: options . ollama
? 'ollama'
2025-05-28 00:42:31 +02:00
: options . bedrock
? 'bedrock'
: undefined
2025-04-27 01:23:18 -04:00
} ) ;
2025-04-27 03:56:23 -04:00
if ( result . success ) {
console . log ( chalk . green ( ` ✅ ${ result . data . message } ` ) ) ;
2025-04-29 01:54:42 -04:00
if ( result . data . warning )
2025-04-27 17:25:54 -04:00
console . log ( chalk . yellow ( result . data . warning ) ) ;
2025-04-29 01:54:42 -04:00
updateOccurred = true ;
2025-04-23 15:47:33 -04:00
} else {
2025-04-29 01:54:42 -04:00
console . error (
chalk . red (
` ❌ Error setting fallback model: ${ result . error . message } `
)
) ;
2025-04-16 00:35:30 -04:00
}
2025-04-23 15:47:33 -04:00
}
2025-04-29 01:54:42 -04:00
// Optional: Add a final confirmation if any update occurred
if ( updateOccurred ) {
console . log ( chalk . blue ( '\nModel configuration updated.' ) ) ;
} else {
console . log (
chalk . yellow (
'\nNo model configuration changes were made (or errors occurred).'
)
) ;
}
// --- IMPORTANT: Exit after set operations ---
return ; // Stop execution here
2025-04-27 03:56:23 -04:00
}
2025-04-16 00:35:30 -04:00
2025-04-29 01:54:42 -04:00
// Action 3: Display Full Status (Only runs if no setup and no set flags)
console . log ( chalk . blue ( 'Fetching current model configuration...' ) ) ; // Added feedback
2025-04-27 03:56:23 -04:00
const configResult = await getModelConfiguration ( { projectRoot } ) ;
const availableResult = await getAvailableModelsList ( { projectRoot } ) ;
2025-04-29 01:54:42 -04:00
const apiKeyStatusResult = await getApiKeyStatusReport ( { projectRoot } ) ;
2025-04-16 00:35:30 -04:00
2025-04-27 03:56:23 -04:00
// 1. Display Active Models
if ( ! configResult . success ) {
2025-04-29 01:54:42 -04:00
console . error (
chalk . red (
` ❌ Error fetching configuration: ${ configResult . error . message } `
)
) ;
2025-04-27 03:56:23 -04:00
} else {
displayModelConfiguration (
configResult . data ,
availableResult . data ? . models || [ ]
) ;
}
2025-04-23 15:47:33 -04:00
2025-04-27 03:56:23 -04:00
// 2. Display API Key Status
if ( apiKeyStatusResult . success ) {
displayApiKeyStatus ( apiKeyStatusResult . data . report ) ;
} else {
console . error (
chalk . yellow (
` ⚠️ Warning: Could not display API Key status: ${ apiKeyStatusResult . error . message } `
2025-04-23 15:47:33 -04:00
)
) ;
2025-04-27 03:56:23 -04:00
}
// 3. Display Other Available Models (Filtered)
if ( availableResult . success ) {
const activeIds = configResult . success
? [
configResult . data . activeModels . main . modelId ,
configResult . data . activeModels . research . modelId ,
configResult . data . activeModels . fallback ? . modelId
] . filter ( Boolean )
: [ ] ;
const displayableAvailable = availableResult . data . models . filter (
2025-04-29 01:54:42 -04:00
( m ) => ! activeIds . includes ( m . modelId ) && ! m . modelId . startsWith ( '[' )
2025-04-27 03:56:23 -04:00
) ;
2025-04-29 01:54:42 -04:00
displayAvailableModels ( displayableAvailable ) ;
2025-04-27 03:56:23 -04:00
} else {
2025-04-23 15:47:33 -04:00
console . error (
2025-04-27 03:56:23 -04:00
chalk . yellow (
` ⚠️ Warning: Could not display available models: ${ availableResult . error . message } `
)
) ;
}
// 4. Conditional Hint if Config File is Missing
2025-04-29 01:54:42 -04:00
const configExists = isConfigFilePresent ( projectRoot ) ;
2025-04-27 03:56:23 -04:00
if ( ! configExists ) {
console . log (
chalk . yellow (
"\\nHint: Run 'task-master models --setup' to create or update your configuration."
)
2025-04-23 15:47:33 -04:00
) ;
2025-04-16 00:35:30 -04:00
}
2025-04-29 01:54:42 -04:00
// --- IMPORTANT: Exit after displaying status ---
return ; // Stop execution here
2025-04-16 00:35:30 -04:00
} ) ;
2025-04-09 00:25:27 +02:00
2025-05-22 04:14:22 -04:00
// move-task command
programInstance
. command ( 'move' )
. description ( 'Move a task or subtask to a new position' )
2025-05-31 16:21:03 +02:00
. option (
'-f, --file <file>' ,
'Path to the tasks file' ,
TASKMASTER _TASKS _FILE
)
2025-05-22 04:17:06 -04:00
. option (
'--from <id>' ,
'ID of the task/subtask to move (e.g., "5" or "5.2"). Can be comma-separated to move multiple tasks (e.g., "5,6,7")'
)
. option (
'--to <id>' ,
'ID of the destination (e.g., "7" or "7.3"). Must match the number of source IDs if comma-separated'
)
2025-05-22 04:14:22 -04:00
. action ( async ( options ) => {
2025-05-31 16:21:03 +02:00
const tasksPath = options . file || TASKMASTER _TASKS _FILE ;
2025-05-22 04:14:22 -04:00
const sourceId = options . from ;
const destinationId = options . to ;
if ( ! sourceId || ! destinationId ) {
console . error (
chalk . red ( 'Error: Both --from and --to parameters are required' )
) ;
console . log (
chalk . yellow (
'Usage: task-master move --from=<sourceId> --to=<destinationId>'
)
) ;
process . exit ( 1 ) ;
}
// Check if we're moving multiple tasks (comma-separated IDs)
2025-05-22 04:17:06 -04:00
const sourceIds = sourceId . split ( ',' ) . map ( ( id ) => id . trim ( ) ) ;
const destinationIds = destinationId . split ( ',' ) . map ( ( id ) => id . trim ( ) ) ;
2025-05-22 04:14:22 -04:00
// Validate that the number of source and destination IDs match
if ( sourceIds . length !== destinationIds . length ) {
console . error (
2025-05-22 04:17:06 -04:00
chalk . red (
'Error: The number of source and destination IDs must match'
)
2025-05-22 04:14:22 -04:00
) ;
console . log (
2025-05-22 04:17:06 -04:00
chalk . yellow ( 'Example: task-master move --from=5,6,7 --to=10,11,12' )
2025-05-22 04:14:22 -04:00
) ;
process . exit ( 1 ) ;
}
// If moving multiple tasks
if ( sourceIds . length > 1 ) {
console . log (
2025-05-22 04:17:06 -04:00
chalk . blue (
` Moving multiple tasks: ${ sourceIds . join ( ', ' ) } to ${ destinationIds . join ( ', ' ) } ... `
)
2025-05-22 04:14:22 -04:00
) ;
try {
// Read tasks data once to validate destination IDs
const tasksData = readJSON ( tasksPath ) ;
if ( ! tasksData || ! tasksData . tasks ) {
2025-05-22 04:17:06 -04:00
console . error (
chalk . red ( ` Error: Invalid or missing tasks file at ${ tasksPath } ` )
) ;
2025-05-22 04:14:22 -04:00
process . exit ( 1 ) ;
}
// Move tasks one by one
for ( let i = 0 ; i < sourceIds . length ; i ++ ) {
const fromId = sourceIds [ i ] ;
const toId = destinationIds [ i ] ;
// Skip if source and destination are the same
if ( fromId === toId ) {
2025-05-22 04:17:06 -04:00
console . log (
chalk . yellow ( ` Skipping ${ fromId } -> ${ toId } (same ID) ` )
) ;
2025-05-22 04:14:22 -04:00
continue ;
}
2025-05-22 04:17:06 -04:00
console . log (
chalk . blue ( ` Moving task/subtask ${ fromId } to ${ toId } ... ` )
) ;
2025-05-22 04:14:22 -04:00
try {
2025-05-22 04:17:06 -04:00
await moveTask (
tasksPath ,
fromId ,
toId ,
i === sourceIds . length - 1
) ;
2025-05-22 04:14:22 -04:00
console . log (
chalk . green (
` ✓ Successfully moved task/subtask ${ fromId } to ${ toId } `
)
) ;
} catch ( error ) {
2025-05-22 04:17:06 -04:00
console . error (
chalk . red ( ` Error moving ${ fromId } to ${ toId } : ${ error . message } ` )
) ;
2025-05-22 04:14:22 -04:00
// Continue with the next task rather than exiting
}
}
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
process . exit ( 1 ) ;
}
} else {
// Moving a single task (existing logic)
console . log (
chalk . blue ( ` Moving task/subtask ${ sourceId } to ${ destinationId } ... ` )
) ;
try {
2025-05-22 04:17:06 -04:00
const result = await moveTask (
tasksPath ,
sourceId ,
destinationId ,
true
) ;
2025-05-22 04:14:22 -04:00
console . log (
chalk . green (
` ✓ Successfully moved task/subtask ${ sourceId } to ${ destinationId } `
)
) ;
} catch ( error ) {
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
process . exit ( 1 ) ;
}
}
} ) ;
2025-05-31 16:21:03 +02:00
programInstance
. command ( 'migrate' )
. description (
'Migrate existing project to use the new .taskmaster directory structure'
)
. option (
'-f, --force' ,
'Force migration even if .taskmaster directory already exists'
)
. option (
'--backup' ,
'Create backup of old files before migration (default: false)' ,
false
)
. option (
'--cleanup' ,
'Remove old files after successful migration (default: true)' ,
true
)
. option ( '-y, --yes' , 'Skip confirmation prompts' )
. option (
'--dry-run' ,
'Show what would be migrated without actually moving files'
)
. action ( async ( options ) => {
try {
await migrateProject ( options ) ;
} catch ( error ) {
console . error ( chalk . red ( 'Error during migration:' ) , error . message ) ;
process . exit ( 1 ) ;
}
} ) ;
2025-04-09 00:25:27 +02:00
return programInstance ;
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
}
/ * *
* Setup the CLI application
* @ returns { Object } Configured Commander program
* /
function setupCLI ( ) {
2025-04-09 00:25:27 +02:00
// Create a new program instance
const programInstance = program
. name ( 'dev' )
. description ( 'AI-driven development task management' )
. version ( ( ) => {
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
// Read version directly from package.json ONLY
2025-04-09 00:25:27 +02:00
try {
const packageJsonPath = path . join ( process . cwd ( ) , 'package.json' ) ;
if ( fs . existsSync ( packageJsonPath ) ) {
const packageJson = JSON . parse (
fs . readFileSync ( packageJsonPath , 'utf8' )
) ;
return packageJson . version ;
}
} catch ( error ) {
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
// Silently fall back to 'unknown'
log (
'warn' ,
'Could not read package.json for version info in .version()'
) ;
2025-04-09 00:25:27 +02:00
}
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
return 'unknown' ; // Default fallback if package.json fails
2025-04-09 00:25:27 +02:00
} )
. helpOption ( '-h, --help' , 'Display help' )
2025-05-14 07:12:15 -04:00
. addHelpCommand ( false ) ; // Disable default help command
2025-04-09 00:25:27 +02:00
// Modify the help option to use your custom display
programInstance . helpInformation = ( ) => {
displayHelp ( ) ;
return '' ;
} ;
// Register commands
registerCommands ( programInstance ) ;
return programInstance ;
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
}
2025-03-27 16:14:12 -04:00
/ * *
* Check for newer version of task - master - ai
* @ returns { Promise < { currentVersion : string , latestVersion : string , needsUpdate : boolean } > }
* /
async function checkForUpdate ( ) {
feat(config): Implement new config system and resolve refactoring errors Introduced config-manager.js and new utilities (resolveEnvVariable, findProjectRoot). Removed old global CONFIG object from utils.js. Updated .taskmasterconfig, mcp.json, and .env.example. Added generateComplexityAnalysisPrompt to ui.js. Removed unused updateSubtaskById from task-manager.js. Resolved SyntaxError and ReferenceError issues across commands.js, ui.js, task-manager.js, and ai-services.js by replacing CONFIG references with config-manager getters (getDebugFlag, getProjectName, getDefaultSubtasks, isApiKeySet). Refactored 'models' command to use getConfig/writeConfig. Simplified version checking. This stabilizes the codebase after initial Task 61 refactoring, fixing CLI errors and enabling subsequent work on Subtasks 61.34 and 61.35.
2025-04-20 01:09:30 -04:00
// Get current version from package.json ONLY
2025-05-15 22:41:16 +02:00
const currentVersion = getTaskMasterVersion ( ) ;
2025-04-09 00:25:27 +02:00
return new Promise ( ( resolve ) => {
// Get the latest version from npm registry
const options = {
hostname : 'registry.npmjs.org' ,
path : '/task-master-ai' ,
method : 'GET' ,
headers : {
Accept : 'application/vnd.npm.install-v1+json' // Lightweight response
}
} ;
const req = https . request ( options , ( res ) => {
let data = '' ;
res . on ( 'data' , ( chunk ) => {
data += chunk ;
} ) ;
res . on ( 'end' , ( ) => {
try {
const npmData = JSON . parse ( data ) ;
const latestVersion = npmData [ 'dist-tags' ] ? . latest || currentVersion ;
// Compare versions
const needsUpdate =
compareVersions ( currentVersion , latestVersion ) < 0 ;
resolve ( {
currentVersion ,
latestVersion ,
needsUpdate
} ) ;
} catch ( error ) {
log ( 'debug' , ` Error parsing npm response: ${ error . message } ` ) ;
resolve ( {
currentVersion ,
latestVersion : currentVersion ,
needsUpdate : false
} ) ;
}
} ) ;
} ) ;
req . on ( 'error' , ( error ) => {
log ( 'debug' , ` Error checking for updates: ${ error . message } ` ) ;
resolve ( {
currentVersion ,
latestVersion : currentVersion ,
needsUpdate : false
} ) ;
} ) ;
// Set a timeout to avoid hanging if npm is slow
req . setTimeout ( 3000 , ( ) => {
req . abort ( ) ;
log ( 'debug' , 'Update check timed out' ) ;
resolve ( {
currentVersion ,
latestVersion : currentVersion ,
needsUpdate : false
} ) ;
} ) ;
req . end ( ) ;
} ) ;
2025-03-27 16:14:12 -04:00
}
/ * *
* Compare semantic versions
* @ param { string } v1 - First version
* @ param { string } v2 - Second version
* @ returns { number } - 1 if v1 < v2 , 0 if v1 = v2 , 1 if v1 > v2
* /
function compareVersions ( v1 , v2 ) {
2025-04-09 00:25:27 +02:00
const v1Parts = v1 . split ( '.' ) . map ( ( p ) => parseInt ( p , 10 ) ) ;
const v2Parts = v2 . split ( '.' ) . map ( ( p ) => parseInt ( p , 10 ) ) ;
for ( let i = 0 ; i < Math . max ( v1Parts . length , v2Parts . length ) ; i ++ ) {
const v1Part = v1Parts [ i ] || 0 ;
const v2Part = v2Parts [ i ] || 0 ;
if ( v1Part < v2Part ) return - 1 ;
if ( v1Part > v2Part ) return 1 ;
}
return 0 ;
2025-03-27 16:14:12 -04:00
}
/ * *
* Display upgrade notification message
* @ param { string } currentVersion - Current version
* @ param { string } latestVersion - Latest version
* /
function displayUpgradeNotification ( currentVersion , latestVersion ) {
2025-04-09 00:25:27 +02:00
const message = boxen (
` ${ chalk . blue . bold ( 'Update Available!' ) } ${ chalk . dim ( currentVersion ) } → ${ chalk . green ( latestVersion ) } \n \n ` +
` Run ${ chalk . cyan ( 'npm i task-master-ai@latest -g' ) } to update to the latest version with new features and bug fixes. ` ,
{
padding : 1 ,
margin : { top : 1 , bottom : 1 } ,
borderColor : 'yellow' ,
borderStyle : 'round'
}
) ;
console . log ( message ) ;
2025-03-27 16:14:12 -04:00
}
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
/ * *
* Parse arguments and run the CLI
* @ param { Array } argv - Command - line arguments
* /
async function runCLI ( argv = process . argv ) {
2025-04-09 00:25:27 +02:00
try {
// Display banner if not in a pipe
if ( process . stdout . isTTY ) {
displayBanner ( ) ;
}
// If no arguments provided, show help
if ( argv . length <= 2 ) {
displayHelp ( ) ;
process . exit ( 0 ) ;
}
// Start the update check in the background - don't await yet
const updateCheckPromise = checkForUpdate ( ) ;
// Setup and parse
2025-04-21 22:25:04 -04:00
// NOTE: getConfig() might be called during setupCLI->registerCommands if commands need config
2025-05-31 16:21:03 +02:00
// This means the ConfigurationError might be thrown here if configuration file is missing.
2025-04-09 00:25:27 +02:00
const programInstance = setupCLI ( ) ;
await programInstance . parseAsync ( argv ) ;
// After command execution, check if an update is available
const updateInfo = await updateCheckPromise ;
if ( updateInfo . needsUpdate ) {
displayUpgradeNotification (
updateInfo . currentVersion ,
updateInfo . latestVersion
) ;
}
} catch ( error ) {
2025-04-21 22:25:04 -04:00
// ** Specific catch block for missing configuration file **
if ( error instanceof ConfigurationError ) {
console . error (
boxen (
chalk . red . bold ( 'Configuration Update Required!' ) +
'\n\n' +
2025-05-31 16:21:03 +02:00
chalk . white ( 'Taskmaster now uses a ' ) +
chalk . yellow . bold ( 'configuration file' ) +
2025-04-21 22:25:04 -04:00
chalk . white (
2025-05-31 16:21:03 +02:00
' in your project for AI model choices and settings.\n\n' +
2025-04-21 22:25:04 -04:00
'This file appears to be '
) +
chalk . red . bold ( 'missing' ) +
chalk . white ( '. No worries though.\n\n' ) +
chalk . cyan . bold ( 'To create this file, run the interactive setup:' ) +
'\n' +
chalk . green ( ' task-master models --setup' ) +
'\n\n' +
chalk . white . bold ( 'Key Points:' ) +
'\n' +
chalk . white ( '* ' ) +
2025-05-31 16:21:03 +02:00
chalk . yellow . bold ( 'Configuration file' ) +
2025-04-21 22:25:04 -04:00
chalk . white (
': Stores your AI model settings (do not manually edit)\n'
) +
chalk . white ( '* ' ) +
chalk . yellow . bold ( '.env & .mcp.json' ) +
chalk . white ( ': Still used ' ) +
chalk . red . bold ( 'only' ) +
chalk . white ( ' for your AI provider API keys.\n\n' ) +
chalk . cyan (
'`task-master models` to check your config & available models\n'
) +
chalk . cyan (
'`task-master models --setup` to adjust the AI models used by Taskmaster'
) ,
{
padding : 1 ,
margin : { top : 1 } ,
borderColor : 'red' ,
borderStyle : 'round'
}
)
) ;
} else {
// Generic error handling for other errors
console . error ( chalk . red ( ` Error: ${ error . message } ` ) ) ;
if ( getDebugFlag ( ) ) {
console . error ( error ) ;
}
2025-04-09 00:25:27 +02:00
}
process . exit ( 1 ) ;
}
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
}
export {
2025-04-09 00:25:27 +02:00
registerCommands ,
setupCLI ,
runCLI ,
checkForUpdate ,
compareVersions ,
displayUpgradeNotification
} ;