fix: projectRoot duplicate .taskmaster directory (#655)

This commit is contained in:
Ralph Khreish
2025-06-03 15:12:50 +02:00
committed by GitHub
parent 9b4168bb4e
commit edaa5fe0d5
4 changed files with 113 additions and 33 deletions

View File

@@ -16,6 +16,32 @@ import {
} from '../constants/paths.js';
import { getLoggerOrDefault } from './logger-utils.js';
/**
* Normalize project root to ensure it doesn't end with .taskmaster
* This prevents double .taskmaster paths when using constants that include .taskmaster
* @param {string} projectRoot - The project root path to normalize
* @returns {string} - Normalized project root path
*/
export function normalizeProjectRoot(projectRoot) {
if (!projectRoot) return projectRoot;
// Split the path into segments
const segments = projectRoot.split(path.sep);
// Find the index of .taskmaster segment
const taskmasterIndex = segments.findIndex(
(segment) => segment === '.taskmaster'
);
if (taskmasterIndex !== -1) {
// If .taskmaster is found, return everything up to but not including .taskmaster
const normalizedSegments = segments.slice(0, taskmasterIndex);
return normalizedSegments.join(path.sep) || path.sep;
}
return projectRoot;
}
/**
* Find the project root directory by looking for project markers
* @param {string} startDir - Directory to start searching from
@@ -80,14 +106,17 @@ export function findTasksPath(explicitPath = null, args = null, log = null) {
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot();
const rawProjectRoot = args?.projectRoot || findProjectRoot();
if (!projectRoot) {
if (!rawProjectRoot) {
logger.warn?.('Could not determine project root directory');
return null;
}
// 3. Check possible locations in order of preference
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Check possible locations in order of preference
const possiblePaths = [
path.join(projectRoot, TASKMASTER_TASKS_FILE), // .taskmaster/tasks/tasks.json (NEW)
path.join(projectRoot, 'tasks.json'), // tasks.json in root (LEGACY)
@@ -151,14 +180,17 @@ export function findPRDPath(explicitPath = null, args = null, log = null) {
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot();
const rawProjectRoot = args?.projectRoot || findProjectRoot();
if (!projectRoot) {
if (!rawProjectRoot) {
logger.warn?.('Could not determine project root directory');
return null;
}
// 3. Check possible locations in order of preference
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Check possible locations in order of preference
const locations = [
TASKMASTER_DOCS_DIR, // .taskmaster/docs/ (NEW)
'scripts/', // Legacy location
@@ -220,14 +252,17 @@ export function findComplexityReportPath(
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot();
const rawProjectRoot = args?.projectRoot || findProjectRoot();
if (!projectRoot) {
if (!rawProjectRoot) {
logger.warn?.('Could not determine project root directory');
return null;
}
// 3. Check possible locations in order of preference
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Check possible locations in order of preference
const locations = [
TASKMASTER_REPORTS_DIR, // .taskmaster/reports/ (NEW)
'scripts/', // Legacy location
@@ -283,9 +318,13 @@ export function resolveTasksOutputPath(
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot() || process.cwd();
const rawProjectRoot =
args?.projectRoot || findProjectRoot() || process.cwd();
// 3. Use new .taskmaster structure by default
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Use new .taskmaster structure by default
const defaultPath = path.join(projectRoot, TASKMASTER_TASKS_FILE);
logger.info?.(`Using default output path: ${defaultPath}`);
@@ -326,9 +365,13 @@ export function resolveComplexityReportOutputPath(
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot() || process.cwd();
const rawProjectRoot =
args?.projectRoot || findProjectRoot() || process.cwd();
// 3. Use new .taskmaster structure by default
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Use new .taskmaster structure by default
const defaultPath = path.join(projectRoot, COMPLEXITY_REPORT_FILE);
logger.info?.(`Using default complexity report output path: ${defaultPath}`);
@@ -369,14 +412,17 @@ export function findConfigPath(explicitPath = null, args = null, log = null) {
}
// 2. Try to get project root from args (MCP) or find it
const projectRoot = args?.projectRoot || findProjectRoot();
const rawProjectRoot = args?.projectRoot || findProjectRoot();
if (!projectRoot) {
if (!rawProjectRoot) {
logger.warn?.('Could not determine project root directory');
return null;
}
// 3. Check possible locations in order of preference
// 3. Normalize project root to prevent double .taskmaster paths
const projectRoot = normalizeProjectRoot(rawProjectRoot);
// 4. Check possible locations in order of preference
const possiblePaths = [
path.join(projectRoot, TASKMASTER_CONFIG_FILE), // NEW location
path.join(projectRoot, LEGACY_CONFIG_FILE) // LEGACY location