Compare commits
2 Commits
chore/crea
...
feat/issue
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b9bb8b94f | ||
|
|
6f27399df8 |
7
.changeset/sharp-flies-call.md
Normal file
7
.changeset/sharp-flies-call.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
'task-master-ai': minor
|
||||
---
|
||||
|
||||
Add TASK_MASTER_PROJECT_ROOT env variable supported in mcp.json and .env for project root resolution
|
||||
|
||||
- Some users were having issues where the MCP wasn't able to detect the location of their project root, you can now set the `TASK_MASTER_PROJECT_ROOT` environment variable to the root of your project.
|
||||
@@ -22,7 +22,7 @@ import {
|
||||
*/
|
||||
function getProjectRoot(projectRootRaw, log) {
|
||||
// PRECEDENCE ORDER:
|
||||
// 1. Environment variable override
|
||||
// 1. Environment variable override (TASK_MASTER_PROJECT_ROOT)
|
||||
// 2. Explicitly provided projectRoot in args
|
||||
// 3. Previously found/cached project root
|
||||
// 4. Current directory if it has project markers
|
||||
@@ -578,6 +578,7 @@ function getRawProjectRootFromSession(session, log) {
|
||||
/**
|
||||
* Higher-order function to wrap MCP tool execute methods.
|
||||
* Ensures args.projectRoot is present and normalized before execution.
|
||||
* Uses TASK_MASTER_PROJECT_ROOT environment variable with proper precedence.
|
||||
* @param {Function} executeFn - The original async execute(args, context) function.
|
||||
* @returns {Function} The wrapped async execute function.
|
||||
*/
|
||||
@@ -588,31 +589,52 @@ function withNormalizedProjectRoot(executeFn) {
|
||||
let rootSource = 'unknown';
|
||||
|
||||
try {
|
||||
// Determine raw root: prioritize args, then session
|
||||
let rawRoot = args.projectRoot;
|
||||
if (!rawRoot) {
|
||||
rawRoot = getRawProjectRootFromSession(session, log);
|
||||
// PRECEDENCE ORDER:
|
||||
// 1. TASK_MASTER_PROJECT_ROOT environment variable (from process.env or session)
|
||||
// 2. args.projectRoot (explicitly provided)
|
||||
// 3. Session-based project root resolution
|
||||
// 4. Current directory fallback
|
||||
|
||||
// 1. Check for TASK_MASTER_PROJECT_ROOT environment variable first
|
||||
if (process.env.TASK_MASTER_PROJECT_ROOT) {
|
||||
const envRoot = process.env.TASK_MASTER_PROJECT_ROOT;
|
||||
normalizedRoot = path.isAbsolute(envRoot)
|
||||
? envRoot
|
||||
: path.resolve(process.cwd(), envRoot);
|
||||
rootSource = 'TASK_MASTER_PROJECT_ROOT environment variable';
|
||||
log.info(`Using project root from ${rootSource}: ${normalizedRoot}`);
|
||||
}
|
||||
// Also check session environment variables for TASK_MASTER_PROJECT_ROOT
|
||||
else if (session?.env?.TASK_MASTER_PROJECT_ROOT) {
|
||||
const envRoot = session.env.TASK_MASTER_PROJECT_ROOT;
|
||||
normalizedRoot = path.isAbsolute(envRoot)
|
||||
? envRoot
|
||||
: path.resolve(process.cwd(), envRoot);
|
||||
rootSource = 'TASK_MASTER_PROJECT_ROOT session environment variable';
|
||||
log.info(`Using project root from ${rootSource}: ${normalizedRoot}`);
|
||||
}
|
||||
// 2. If no environment variable, try args.projectRoot
|
||||
else if (args.projectRoot) {
|
||||
normalizedRoot = normalizeProjectRoot(args.projectRoot, log);
|
||||
rootSource = 'args.projectRoot';
|
||||
log.info(`Using project root from ${rootSource}: ${normalizedRoot}`);
|
||||
}
|
||||
// 3. If no args.projectRoot, try session-based resolution
|
||||
else {
|
||||
const sessionRoot = getProjectRootFromSession(session, log);
|
||||
if (sessionRoot) {
|
||||
normalizedRoot = sessionRoot; // getProjectRootFromSession already normalizes
|
||||
rootSource = 'session';
|
||||
} else {
|
||||
rootSource = 'args';
|
||||
log.info(`Using project root from ${rootSource}: ${normalizedRoot}`);
|
||||
}
|
||||
|
||||
if (!rawRoot) {
|
||||
log.error('Could not determine project root from args or session.');
|
||||
return createErrorResponse(
|
||||
'Could not determine project root. Please provide projectRoot argument or ensure session contains root info.'
|
||||
);
|
||||
}
|
||||
|
||||
// Normalize the determined raw root
|
||||
normalizedRoot = normalizeProjectRoot(rawRoot, log);
|
||||
|
||||
if (!normalizedRoot) {
|
||||
log.error(
|
||||
`Failed to normalize project root obtained from ${rootSource}: ${rawRoot}`
|
||||
'Could not determine project root from environment, args, or session.'
|
||||
);
|
||||
return createErrorResponse(
|
||||
`Invalid project root provided or derived from ${rootSource}: ${rawRoot}`
|
||||
'Could not determine project root. Please provide projectRoot argument or ensure TASK_MASTER_PROJECT_ROOT environment variable is set.'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
getBaseUrlForRole,
|
||||
isApiKeySet
|
||||
} from './config-manager.js';
|
||||
import { log, resolveEnvVariable, findProjectRoot } from './utils.js';
|
||||
import { log, findProjectRoot, resolveEnvVariable } from './utils.js';
|
||||
|
||||
import * as anthropic from '../../src/ai-providers/anthropic.js';
|
||||
import * as perplexity from '../../src/ai-providers/perplexity.js';
|
||||
|
||||
@@ -13,7 +13,7 @@ import http from 'http';
|
||||
import inquirer from 'inquirer';
|
||||
import ora from 'ora'; // Import ora
|
||||
|
||||
import { log, readJSON } from './utils.js';
|
||||
import { log, readJSON, findProjectRoot } from './utils.js';
|
||||
import {
|
||||
parsePRD,
|
||||
updateTasks,
|
||||
@@ -76,7 +76,6 @@ import {
|
||||
setModel,
|
||||
getApiKeyStatusReport
|
||||
} from './task-manager/models.js';
|
||||
import { findProjectRoot } from './utils.js';
|
||||
import {
|
||||
isValidTaskStatus,
|
||||
TASK_STATUS_OPTIONS
|
||||
@@ -2307,8 +2306,11 @@ Examples:
|
||||
$ task-master models --setup # Run interactive setup`
|
||||
)
|
||||
.action(async (options) => {
|
||||
const projectRoot = findProjectRoot(); // Find project root for context
|
||||
|
||||
const projectRoot = findProjectRoot();
|
||||
if (!projectRoot) {
|
||||
console.error(chalk.red('Error: Could not find project root.'));
|
||||
process.exit(1);
|
||||
}
|
||||
// Validate flags: cannot use both --openrouter and --ollama simultaneously
|
||||
if (options.openrouter && options.ollama) {
|
||||
console.error(
|
||||
|
||||
@@ -2,7 +2,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import chalk from 'chalk';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { log, resolveEnvVariable, findProjectRoot } from './utils.js';
|
||||
import { log, findProjectRoot, resolveEnvVariable } from './utils.js';
|
||||
|
||||
// Calculate __dirname in ESM
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
|
||||
@@ -60,8 +60,7 @@ function resolveEnvVariable(key, session = null, projectRoot = null) {
|
||||
|
||||
// --- Project Root Finding Utility ---
|
||||
/**
|
||||
* Finds the project root directory by searching upwards from a given starting point
|
||||
* for a marker file or directory (e.g., 'package.json', '.git').
|
||||
* Finds the project root directory by searching for marker files/directories.
|
||||
* @param {string} [startPath=process.cwd()] - The directory to start searching from.
|
||||
* @param {string[]} [markers=['package.json', '.git', '.taskmasterconfig']] - Marker files/dirs to look for.
|
||||
* @returns {string|null} The path to the project root directory, or null if not found.
|
||||
@@ -71,27 +70,35 @@ function findProjectRoot(
|
||||
markers = ['package.json', '.git', '.taskmasterconfig']
|
||||
) {
|
||||
let currentPath = path.resolve(startPath);
|
||||
while (true) {
|
||||
for (const marker of markers) {
|
||||
if (fs.existsSync(path.join(currentPath, marker))) {
|
||||
const rootPath = path.parse(currentPath).root;
|
||||
|
||||
while (currentPath !== rootPath) {
|
||||
// Check if any marker exists in the current directory
|
||||
const hasMarker = markers.some((marker) => {
|
||||
const markerPath = path.join(currentPath, marker);
|
||||
return fs.existsSync(markerPath);
|
||||
});
|
||||
|
||||
if (hasMarker) {
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
// Move up one directory
|
||||
currentPath = path.dirname(currentPath);
|
||||
}
|
||||
const parentPath = path.dirname(currentPath);
|
||||
if (parentPath === currentPath) {
|
||||
// Reached the filesystem root
|
||||
return null;
|
||||
}
|
||||
currentPath = parentPath;
|
||||
}
|
||||
|
||||
// Check the root directory as well
|
||||
const hasMarkerInRoot = markers.some((marker) => {
|
||||
const markerPath = path.join(rootPath, marker);
|
||||
return fs.existsSync(markerPath);
|
||||
});
|
||||
|
||||
return hasMarkerInRoot ? rootPath : null;
|
||||
}
|
||||
|
||||
// --- Dynamic Configuration Function --- (REMOVED)
|
||||
/*
|
||||
function getConfig(session = null) {
|
||||
// ... implementation removed ...
|
||||
}
|
||||
*/
|
||||
|
||||
// --- Logging and Utility Functions ---
|
||||
|
||||
// Set up logging based on log level
|
||||
const LOG_LEVELS = {
|
||||
|
||||
94
tasks/task_092.txt
Normal file
94
tasks/task_092.txt
Normal file
@@ -0,0 +1,94 @@
|
||||
# Task ID: 92
|
||||
# Title: Implement Project Root Environment Variable Support in MCP Configuration
|
||||
# Status: in-progress
|
||||
# Dependencies: 1, 3, 17
|
||||
# Priority: medium
|
||||
# Description: Add support for a 'TASK_MASTER_PROJECT_ROOT' environment variable in MCP configuration, allowing it to be set in both mcp.json and .env, with precedence over other methods. This will define the root directory for the MCP server and take precedence over all other project root resolution methods. The implementation should be backward compatible with existing workflows that don't use this variable.
|
||||
# Details:
|
||||
Update the MCP server configuration system to support the TASK_MASTER_PROJECT_ROOT environment variable as the standard way to specify the project root directory. This provides better namespacing and avoids conflicts with other tools that might use a generic PROJECT_ROOT variable. Implement a clear precedence order for project root resolution:
|
||||
|
||||
1. TASK_MASTER_PROJECT_ROOT environment variable (from shell or .env file)
|
||||
2. 'projectRoot' key in mcp_config.toml or mcp.json configuration files
|
||||
3. Existing resolution logic (CLI args, current working directory, etc.)
|
||||
|
||||
Modify the configuration loading logic to check for these sources in the specified order, ensuring backward compatibility. All MCP tools and components should use this standardized project root resolution logic. The TASK_MASTER_PROJECT_ROOT environment variable will be required because path resolution is delegated to the MCP client implementation, ensuring consistent behavior across different environments.
|
||||
|
||||
Implementation steps:
|
||||
1. Identify all code locations where project root is determined (initialization, utility functions)
|
||||
2. Update configuration loaders to check for TASK_MASTER_PROJECT_ROOT in environment variables
|
||||
3. Add support for 'projectRoot' in configuration files as a fallback
|
||||
4. Refactor project root resolution logic to follow the new precedence rules
|
||||
5. Ensure all MCP tools and functions use the updated resolution logic
|
||||
6. Add comprehensive error handling for cases where TASK_MASTER_PROJECT_ROOT is not set or invalid
|
||||
7. Implement validation to ensure the specified directory exists and is accessible
|
||||
|
||||
# Test Strategy:
|
||||
1. Write unit tests to verify that the config loader correctly reads project root from environment variables and configuration files with the expected precedence:
|
||||
- Test TASK_MASTER_PROJECT_ROOT environment variable takes precedence when set
|
||||
- Test 'projectRoot' in configuration files is used when environment variable is absent
|
||||
- Test fallback to existing resolution logic when neither is specified
|
||||
|
||||
2. Add integration tests to ensure that the MCP server and all tools use the correct project root:
|
||||
- Test server startup with TASK_MASTER_PROJECT_ROOT set to various valid and invalid paths
|
||||
- Test configuration file loading from the specified project root
|
||||
- Test path resolution for resources relative to the project root
|
||||
|
||||
3. Test backward compatibility:
|
||||
- Verify existing workflows function correctly without the new variables
|
||||
- Ensure no regression in projects not using the new configuration options
|
||||
|
||||
4. Manual testing:
|
||||
- Set TASK_MASTER_PROJECT_ROOT in shell environment and verify correct behavior
|
||||
- Set TASK_MASTER_PROJECT_ROOT in .env file and verify it's properly loaded
|
||||
- Configure 'projectRoot' in configuration files and test precedence
|
||||
- Test with invalid or non-existent directories to verify error handling
|
||||
|
||||
# Subtasks:
|
||||
## 92.1. Update configuration loader to check for TASK_MASTER_PROJECT_ROOT environment variable [pending]
|
||||
### Dependencies: None
|
||||
### Description: Modify the configuration loading system to check for the TASK_MASTER_PROJECT_ROOT environment variable as the primary source for project root directory. Ensure proper error handling if the variable is set but points to a non-existent or inaccessible directory.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.2. Add support for 'projectRoot' in configuration files [pending]
|
||||
### Dependencies: None
|
||||
### Description: Implement support for a 'projectRoot' key in mcp_config.toml and mcp.json configuration files as a fallback when the environment variable is not set. Update the configuration parser to recognize and validate this field.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.3. Refactor project root resolution logic with clear precedence rules [pending]
|
||||
### Dependencies: None
|
||||
### Description: Create a unified project root resolution function that follows the precedence order: 1) TASK_MASTER_PROJECT_ROOT environment variable, 2) 'projectRoot' in config files, 3) existing resolution methods. Ensure this function is used consistently throughout the codebase.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.4. Update all MCP tools to use the new project root resolution [pending]
|
||||
### Dependencies: None
|
||||
### Description: Identify all MCP tools and components that need to access the project root and update them to use the new resolution logic. Ensure consistent behavior across all parts of the system.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.5. Add comprehensive tests for the new project root resolution [pending]
|
||||
### Dependencies: None
|
||||
### Description: Create unit and integration tests to verify the correct behavior of the project root resolution logic under various configurations and edge cases.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.6. Update documentation with new configuration options [pending]
|
||||
### Dependencies: None
|
||||
### Description: Update the project documentation to clearly explain the new TASK_MASTER_PROJECT_ROOT environment variable, the 'projectRoot' configuration option, and the precedence rules. Include examples of different configuration scenarios.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.7. Implement validation for project root directory [pending]
|
||||
### Dependencies: None
|
||||
### Description: Add validation to ensure the specified project root directory exists and has the necessary permissions. Provide clear error messages when validation fails.
|
||||
### Details:
|
||||
|
||||
|
||||
## 92.8. Implement support for loading environment variables from .env files [pending]
|
||||
### Dependencies: None
|
||||
### Description: Add functionality to load the TASK_MASTER_PROJECT_ROOT variable from .env files in the workspace, following best practices for environment variable management in MCP servers.
|
||||
### Details:
|
||||
|
||||
|
||||
@@ -5466,6 +5466,70 @@
|
||||
"parentTaskId": 91
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 92,
|
||||
"title": "Implement Project Root Environment Variable Support in MCP Configuration",
|
||||
"description": "Add support for a 'TASK_MASTER_PROJECT_ROOT' environment variable in MCP configuration, allowing it to be set in both mcp.json and .env, with precedence over other methods. This will define the root directory for the MCP server and take precedence over all other project root resolution methods. The implementation should be backward compatible with existing workflows that don't use this variable.",
|
||||
"status": "in-progress",
|
||||
"dependencies": [
|
||||
1,
|
||||
3,
|
||||
17
|
||||
],
|
||||
"priority": "medium",
|
||||
"details": "Update the MCP server configuration system to support the TASK_MASTER_PROJECT_ROOT environment variable as the standard way to specify the project root directory. This provides better namespacing and avoids conflicts with other tools that might use a generic PROJECT_ROOT variable. Implement a clear precedence order for project root resolution:\n\n1. TASK_MASTER_PROJECT_ROOT environment variable (from shell or .env file)\n2. 'projectRoot' key in mcp_config.toml or mcp.json configuration files\n3. Existing resolution logic (CLI args, current working directory, etc.)\n\nModify the configuration loading logic to check for these sources in the specified order, ensuring backward compatibility. All MCP tools and components should use this standardized project root resolution logic. The TASK_MASTER_PROJECT_ROOT environment variable will be required because path resolution is delegated to the MCP client implementation, ensuring consistent behavior across different environments.\n\nImplementation steps:\n1. Identify all code locations where project root is determined (initialization, utility functions)\n2. Update configuration loaders to check for TASK_MASTER_PROJECT_ROOT in environment variables\n3. Add support for 'projectRoot' in configuration files as a fallback\n4. Refactor project root resolution logic to follow the new precedence rules\n5. Ensure all MCP tools and functions use the updated resolution logic\n6. Add comprehensive error handling for cases where TASK_MASTER_PROJECT_ROOT is not set or invalid\n7. Implement validation to ensure the specified directory exists and is accessible",
|
||||
"testStrategy": "1. Write unit tests to verify that the config loader correctly reads project root from environment variables and configuration files with the expected precedence:\n - Test TASK_MASTER_PROJECT_ROOT environment variable takes precedence when set\n - Test 'projectRoot' in configuration files is used when environment variable is absent\n - Test fallback to existing resolution logic when neither is specified\n\n2. Add integration tests to ensure that the MCP server and all tools use the correct project root:\n - Test server startup with TASK_MASTER_PROJECT_ROOT set to various valid and invalid paths\n - Test configuration file loading from the specified project root\n - Test path resolution for resources relative to the project root\n\n3. Test backward compatibility:\n - Verify existing workflows function correctly without the new variables\n - Ensure no regression in projects not using the new configuration options\n\n4. Manual testing:\n - Set TASK_MASTER_PROJECT_ROOT in shell environment and verify correct behavior\n - Set TASK_MASTER_PROJECT_ROOT in .env file and verify it's properly loaded\n - Configure 'projectRoot' in configuration files and test precedence\n - Test with invalid or non-existent directories to verify error handling",
|
||||
"subtasks": [
|
||||
{
|
||||
"id": 92.1,
|
||||
"title": "Update configuration loader to check for TASK_MASTER_PROJECT_ROOT environment variable",
|
||||
"description": "Modify the configuration loading system to check for the TASK_MASTER_PROJECT_ROOT environment variable as the primary source for project root directory. Ensure proper error handling if the variable is set but points to a non-existent or inaccessible directory.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.2,
|
||||
"title": "Add support for 'projectRoot' in configuration files",
|
||||
"description": "Implement support for a 'projectRoot' key in mcp_config.toml and mcp.json configuration files as a fallback when the environment variable is not set. Update the configuration parser to recognize and validate this field.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.3,
|
||||
"title": "Refactor project root resolution logic with clear precedence rules",
|
||||
"description": "Create a unified project root resolution function that follows the precedence order: 1) TASK_MASTER_PROJECT_ROOT environment variable, 2) 'projectRoot' in config files, 3) existing resolution methods. Ensure this function is used consistently throughout the codebase.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.4,
|
||||
"title": "Update all MCP tools to use the new project root resolution",
|
||||
"description": "Identify all MCP tools and components that need to access the project root and update them to use the new resolution logic. Ensure consistent behavior across all parts of the system.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.5,
|
||||
"title": "Add comprehensive tests for the new project root resolution",
|
||||
"description": "Create unit and integration tests to verify the correct behavior of the project root resolution logic under various configurations and edge cases.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.6,
|
||||
"title": "Update documentation with new configuration options",
|
||||
"description": "Update the project documentation to clearly explain the new TASK_MASTER_PROJECT_ROOT environment variable, the 'projectRoot' configuration option, and the precedence rules. Include examples of different configuration scenarios.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.7,
|
||||
"title": "Implement validation for project root directory",
|
||||
"description": "Add validation to ensure the specified project root directory exists and has the necessary permissions. Provide clear error messages when validation fails.",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"id": 92.8,
|
||||
"title": "Implement support for loading environment variables from .env files",
|
||||
"description": "Add functionality to load the TASK_MASTER_PROJECT_ROOT variable from .env files in the workspace, following best practices for environment variable management in MCP servers.",
|
||||
"status": "pending"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user