Compare commits

...

2 Commits

Author SHA1 Message Date
Ralph Khreish
fbe859f886 chore: add changeset 2025-04-18 23:38:14 +02:00
Ralph Khreish
45cc0cf527 fix: remove the need for projectName, description, version in mcp and cli 2025-04-18 23:33:22 +02:00
5 changed files with 27 additions and 2782 deletions

View File

@@ -0,0 +1,5 @@
---
'task-master-ai': patch
---
Remove the need for project name, description, and version. Since we no longer create a package.json for you

View File

@@ -10,7 +10,7 @@ import os from 'os'; // Import os module for home directory check
/** /**
* Direct function wrapper for initializing a project. * Direct function wrapper for initializing a project.
* Derives target directory from session, sets CWD, and calls core init logic. * Derives target directory from session, sets CWD, and calls core init logic.
* @param {object} args - Arguments containing project details and options (projectName, projectDescription, yes, etc.) * @param {object} args - Arguments containing initialization options (addAliases, skipInstall, yes, projectRoot)
* @param {object} log - The FastMCP logger instance. * @param {object} log - The FastMCP logger instance.
* @param {object} context - The context object, must contain { session }. * @param {object} context - The context object, must contain { session }.
* @returns {Promise<{success: boolean, data?: any, error?: {code: string, message: string}}>} - Standard result object. * @returns {Promise<{success: boolean, data?: any, error?: {code: string, message: string}}>} - Standard result object.
@@ -92,12 +92,8 @@ export async function initializeProjectDirect(args, log, context = {}) {
try { try {
// Always force yes: true when called via MCP to avoid interactive prompts // Always force yes: true when called via MCP to avoid interactive prompts
const options = { const options = {
name: args.projectName,
description: args.projectDescription,
version: args.projectVersion,
author: args.authorName,
skipInstall: args.skipInstall,
aliases: args.addAliases, aliases: args.addAliases,
skipInstall: args.skipInstall,
yes: true // Force yes mode yes: true // Force yes mode
}; };

View File

@@ -10,32 +10,8 @@ export function registerInitializeProjectTool(server) {
server.addTool({ server.addTool({
name: 'initialize_project', name: 'initialize_project',
description: description:
"Initializes a new Task Master project structure by calling the core initialization logic. Derives target directory from client session. If project details (name, description, author) are not provided, prompts the user or skips if 'yes' flag is true. DO NOT run without parameters.", 'Initializes a new Task Master project structure by calling the core initialization logic. Creates necessary folders and configuration files for Task Master in the current directory.',
parameters: z.object({ parameters: z.object({
projectName: z
.string()
.optional()
.describe(
'The name for the new project. If not provided, prompt the user for it.'
),
projectDescription: z
.string()
.optional()
.describe(
'A brief description for the project. If not provided, prompt the user for it.'
),
projectVersion: z
.string()
.optional()
.describe(
"The initial version for the project (e.g., '0.1.0'). User input not needed unless user requests to override."
),
authorName: z
.string()
.optional()
.describe(
"The author's name. User input not needed unless user requests to override."
),
skipInstall: z skipInstall: z
.boolean() .boolean()
.optional() .optional()
@@ -47,15 +23,13 @@ export function registerInitializeProjectTool(server) {
.boolean() .boolean()
.optional() .optional()
.default(false) .default(false)
.describe( .describe('Add shell aliases (tm, taskmaster) to shell config file.'),
'Add shell aliases (tm, taskmaster) to shell config file. User input not needed.'
),
yes: z yes: z
.boolean() .boolean()
.optional() .optional()
.default(false) .default(true)
.describe( .describe(
"Skip prompts and use default values or provided arguments. Use true if you wish to skip details like the project name, etc. If the project information required for the initialization is not available or provided by the user, prompt if the user wishes to provide them (name, description, author) or skip them. If the user wishes to skip, set the 'yes' flag to true and do not set any other parameters." 'Skip prompts and use default values. Always set to true for MCP tools.'
), ),
projectRoot: z projectRoot: z
.string() .string()

View File

@@ -335,36 +335,11 @@ async function initializeProject(options = {}) {
console.log('===== DEBUG: INITIALIZE PROJECT OPTIONS RECEIVED ====='); console.log('===== DEBUG: INITIALIZE PROJECT OPTIONS RECEIVED =====');
console.log('Full options object:', JSON.stringify(options)); console.log('Full options object:', JSON.stringify(options));
console.log('options.yes:', options.yes); console.log('options.yes:', options.yes);
console.log('options.name:', options.name);
console.log('=================================================='); console.log('==================================================');
} }
// Try to get project name from package.json if not provided
if (!options.name) {
const packageJsonPath = path.join(process.cwd(), 'package.json');
try {
if (fs.existsSync(packageJsonPath)) {
const packageJson = JSON.parse(
fs.readFileSync(packageJsonPath, 'utf8')
);
if (packageJson.name) {
log(
'info',
`Found project name '${packageJson.name}' in package.json`
);
options.name = packageJson.name;
}
}
} catch (error) {
log(
'debug',
`Could not read project name from package.json: ${error.message}`
);
}
}
// Determine if we should skip prompts based on the passed options // Determine if we should skip prompts based on the passed options
const skipPrompts = options.yes || (options.name && options.description); const skipPrompts = options.yes;
if (!isSilentMode()) { if (!isSilentMode()) {
console.log('Skip prompts determined:', skipPrompts); console.log('Skip prompts determined:', skipPrompts);
} }
@@ -374,44 +349,24 @@ async function initializeProject(options = {}) {
console.log('SKIPPING PROMPTS - Using defaults or provided values'); console.log('SKIPPING PROMPTS - Using defaults or provided values');
} }
// Use provided options or defaults // We no longer need these variables
const projectName = options.name || 'task-master-project';
const projectDescription =
options.description || 'A project managed with Task Master AI';
const projectVersion = options.version || '0.1.0'; // Default from commands.js or here
const authorName = options.author || 'Vibe coder'; // Default if not provided
const dryRun = options.dryRun || false; const dryRun = options.dryRun || false;
const addAliases = options.aliases || false; const addAliases = options.aliases || false;
if (dryRun) { if (dryRun) {
log('info', 'DRY RUN MODE: No files will be modified'); log('info', 'DRY RUN MODE: No files will be modified');
log( log('info', 'Would initialize Task Master project');
'info',
`Would initialize project: ${projectName} (${projectVersion})`
);
log('info', `Description: ${projectDescription}`);
log('info', `Author: ${authorName || 'Not specified'}`);
log('info', 'Would create/update necessary project files'); log('info', 'Would create/update necessary project files');
if (addAliases) { if (addAliases) {
log('info', 'Would add shell aliases for task-master'); log('info', 'Would add shell aliases for task-master');
} }
return { return {
projectName,
projectDescription,
projectVersion,
authorName,
dryRun: true dryRun: true
}; };
} }
// Create structure using determined values // Create structure using only necessary values
createProjectStructure( createProjectStructure(addAliases);
projectName,
projectDescription,
projectVersion,
authorName,
addAliases
);
} else { } else {
// Prompting logic (only runs if skipPrompts is false) // Prompting logic (only runs if skipPrompts is false)
log('info', 'Required options not provided, proceeding with prompts.'); log('info', 'Required options not provided, proceeding with prompts.');
@@ -421,41 +376,17 @@ async function initializeProject(options = {}) {
}); });
try { try {
// Prompt user for input... // Only prompt for shell aliases
const projectName = await promptQuestion(
rl,
chalk.cyan('Enter project name: ')
);
const projectDescription = await promptQuestion(
rl,
chalk.cyan('Enter project description: ')
);
const projectVersionInput = await promptQuestion(
rl,
chalk.cyan('Enter project version (default: 1.0.0): ')
); // Use a default for prompt
const authorName = await promptQuestion(
rl,
chalk.cyan('Enter your name: ')
);
const addAliasesInput = await promptQuestion( const addAliasesInput = await promptQuestion(
rl, rl,
chalk.cyan('Add shell aliases for task-master? (Y/n): ') chalk.cyan(
'Add shell aliases for task-master? This lets you type "tm" instead of "task-master" (Y/n): '
)
); );
const addAliasesPrompted = addAliasesInput.trim().toLowerCase() !== 'n'; const addAliasesPrompted = addAliasesInput.trim().toLowerCase() !== 'n';
const projectVersion = projectVersionInput.trim()
? projectVersionInput
: '1.0.0';
// Confirm settings... // Confirm settings...
console.log('\nProject settings:'); console.log('\nTask Master Project settings:');
console.log(chalk.blue('Name:'), chalk.white(projectName));
console.log(chalk.blue('Description:'), chalk.white(projectDescription));
console.log(chalk.blue('Version:'), chalk.white(projectVersion));
console.log(
chalk.blue('Author:'),
chalk.white(authorName || 'Not specified')
);
console.log( console.log(
chalk.blue( chalk.blue(
'Add shell aliases (so you can use "tm" instead of "task-master"):' 'Add shell aliases (so you can use "tm" instead of "task-master"):'
@@ -481,33 +412,18 @@ async function initializeProject(options = {}) {
if (dryRun) { if (dryRun) {
log('info', 'DRY RUN MODE: No files will be modified'); log('info', 'DRY RUN MODE: No files will be modified');
log( log('info', 'Would initialize Task Master project');
'info',
`Would initialize project: ${projectName} (${projectVersion})`
);
log('info', `Description: ${projectDescription}`);
log('info', `Author: ${authorName || 'Not specified'}`);
log('info', 'Would create/update necessary project files'); log('info', 'Would create/update necessary project files');
if (addAliasesPrompted) { if (addAliasesPrompted) {
log('info', 'Would add shell aliases for task-master'); log('info', 'Would add shell aliases for task-master');
} }
return { return {
projectName,
projectDescription,
projectVersion,
authorName,
dryRun: true dryRun: true
}; };
} }
// Create structure using prompted values, respecting initial options where relevant // Create structure using only necessary values
createProjectStructure( createProjectStructure(addAliasesPrompted);
projectName,
projectDescription,
projectVersion,
authorName,
addAliasesPrompted // Use value from prompt
);
} catch (error) { } catch (error) {
rl.close(); rl.close();
log('error', `Error during prompting: ${error.message}`); // Use log function log('error', `Error during prompting: ${error.message}`); // Use log function
@@ -526,13 +442,7 @@ function promptQuestion(rl, question) {
} }
// Function to create the project structure // Function to create the project structure
function createProjectStructure( function createProjectStructure(addAliases) {
projectName,
projectDescription,
projectVersion,
authorName,
addAliases
) {
const targetDir = process.cwd(); const targetDir = process.cwd();
log('info', `Initializing project in ${targetDir}`); log('info', `Initializing project in ${targetDir}`);
@@ -542,14 +452,10 @@ function createProjectStructure(
ensureDirectoryExists(path.join(targetDir, 'tasks')); ensureDirectoryExists(path.join(targetDir, 'tasks'));
// Setup MCP configuration for integration with Cursor // Setup MCP configuration for integration with Cursor
setupMCPConfiguration(targetDir, projectName); setupMCPConfiguration(targetDir);
// Copy template files with replacements // Copy template files with replacements
const replacements = { const replacements = {
projectName,
projectDescription,
projectVersion,
authorName,
year: new Date().getFullYear() year: new Date().getFullYear()
}; };
@@ -695,7 +601,7 @@ function createProjectStructure(
} }
// Function to setup MCP configuration for Cursor integration // Function to setup MCP configuration for Cursor integration
function setupMCPConfiguration(targetDir, projectName) { function setupMCPConfiguration(targetDir) {
const mcpDirPath = path.join(targetDir, '.cursor'); const mcpDirPath = path.join(targetDir, '.cursor');
const mcpJsonPath = path.join(mcpDirPath, 'mcp.json'); const mcpJsonPath = path.join(mcpDirPath, 'mcp.json');

File diff suppressed because one or more lines are too long