Compare commits
2 Commits
task-maste
...
ralph/impr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbe859f886 | ||
|
|
45cc0cf527 |
5
.changeset/witty-jokes-roll.md
Normal file
5
.changeset/witty-jokes-roll.md
Normal 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
|
||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
126
scripts/init.js
126
scripts/init.js
@@ -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');
|
||||||
|
|
||||||
|
|||||||
2636
tasks/tasks.json.bak
2636
tasks/tasks.json.bak
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user