Improves init script visuals.
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "task-master-ai",
|
"name": "task-master-ai",
|
||||||
"version": "0.9.5",
|
"version": "0.9.6",
|
||||||
"description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.",
|
"description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
157
scripts/init.js
157
scripts/init.js
@@ -8,6 +8,10 @@ import { execSync } from 'child_process';
|
|||||||
import readline from 'readline';
|
import readline from 'readline';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import figlet from 'figlet';
|
||||||
|
import boxen from 'boxen';
|
||||||
|
import gradient from 'gradient-string';
|
||||||
|
|
||||||
// Debug information
|
// Debug information
|
||||||
console.log('Node version:', process.version);
|
console.log('Node version:', process.version);
|
||||||
@@ -17,42 +21,65 @@ console.log('Script path:', import.meta.url);
|
|||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
// Define log levels and colors
|
// Define log levels
|
||||||
const LOG_LEVELS = {
|
const LOG_LEVELS = {
|
||||||
debug: 0,
|
debug: 0,
|
||||||
info: 1,
|
info: 1,
|
||||||
warn: 2,
|
warn: 2,
|
||||||
error: 3
|
error: 3,
|
||||||
};
|
success: 4
|
||||||
|
|
||||||
const COLORS = {
|
|
||||||
reset: '\x1b[0m',
|
|
||||||
bright: '\x1b[1m',
|
|
||||||
dim: '\x1b[2m',
|
|
||||||
red: '\x1b[31m',
|
|
||||||
green: '\x1b[32m',
|
|
||||||
yellow: '\x1b[33m',
|
|
||||||
blue: '\x1b[34m',
|
|
||||||
magenta: '\x1b[35m',
|
|
||||||
cyan: '\x1b[36m'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get log level from environment or default to info
|
// Get log level from environment or default to info
|
||||||
const LOG_LEVEL = process.env.LOG_LEVEL ? LOG_LEVELS[process.env.LOG_LEVEL.toLowerCase()] : LOG_LEVELS.info;
|
const LOG_LEVEL = process.env.LOG_LEVEL ? LOG_LEVELS[process.env.LOG_LEVEL.toLowerCase()] : LOG_LEVELS.info;
|
||||||
|
|
||||||
// Logging function
|
// Create a color gradient for the banner
|
||||||
|
const coolGradient = gradient(['#00b4d8', '#0077b6', '#03045e']);
|
||||||
|
const warmGradient = gradient(['#fb8b24', '#e36414', '#9a031e']);
|
||||||
|
|
||||||
|
// Display a fancy banner
|
||||||
|
function displayBanner() {
|
||||||
|
console.clear();
|
||||||
|
const bannerText = figlet.textSync('Claude Task Master', {
|
||||||
|
font: 'Standard',
|
||||||
|
horizontalLayout: 'default',
|
||||||
|
verticalLayout: 'default'
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(coolGradient(bannerText));
|
||||||
|
|
||||||
|
console.log(boxen(chalk.white(`${chalk.bold('Initializing')} your new project`), {
|
||||||
|
padding: 1,
|
||||||
|
margin: { top: 0, bottom: 1 },
|
||||||
|
borderStyle: 'round',
|
||||||
|
borderColor: 'cyan'
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Logging function with icons and colors
|
||||||
function log(level, ...args) {
|
function log(level, ...args) {
|
||||||
const levelValue = LOG_LEVELS[level.toLowerCase()];
|
const icons = {
|
||||||
|
debug: chalk.gray('🔍'),
|
||||||
|
info: chalk.blue('ℹ️'),
|
||||||
|
warn: chalk.yellow('⚠️'),
|
||||||
|
error: chalk.red('❌'),
|
||||||
|
success: chalk.green('✅')
|
||||||
|
};
|
||||||
|
|
||||||
if (levelValue >= LOG_LEVEL) {
|
if (LOG_LEVELS[level] >= LOG_LEVEL) {
|
||||||
const prefix = {
|
const icon = icons[level] || '';
|
||||||
debug: `${COLORS.dim}[DEBUG]${COLORS.reset}`,
|
|
||||||
info: `${COLORS.blue}[INFO]${COLORS.reset}`,
|
|
||||||
warn: `${COLORS.yellow}[WARN]${COLORS.reset}`,
|
|
||||||
error: `${COLORS.red}[ERROR]${COLORS.reset}`
|
|
||||||
}[level.toLowerCase()];
|
|
||||||
|
|
||||||
console.log(prefix, ...args);
|
if (level === 'error') {
|
||||||
|
console.error(icon, chalk.red(...args));
|
||||||
|
} else if (level === 'warn') {
|
||||||
|
console.warn(icon, chalk.yellow(...args));
|
||||||
|
} else if (level === 'success') {
|
||||||
|
console.log(icon, chalk.green(...args));
|
||||||
|
} else if (level === 'info') {
|
||||||
|
console.log(icon, chalk.blue(...args));
|
||||||
|
} else {
|
||||||
|
console.log(icon, ...args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to debug log if DEBUG=true
|
// Write to debug log if DEBUG=true
|
||||||
@@ -125,6 +152,9 @@ function copyTemplateFile(templateName, targetPath, replacements = {}) {
|
|||||||
|
|
||||||
// Main function to initialize a new project
|
// Main function to initialize a new project
|
||||||
async function initializeProject(options = {}) {
|
async function initializeProject(options = {}) {
|
||||||
|
// Display the banner
|
||||||
|
displayBanner();
|
||||||
|
|
||||||
// If options are provided, use them directly without prompting
|
// If options are provided, use them directly without prompting
|
||||||
if (options.projectName && options.projectDescription) {
|
if (options.projectName && options.projectDescription) {
|
||||||
const projectName = options.projectName;
|
const projectName = options.projectName;
|
||||||
@@ -149,10 +179,10 @@ async function initializeProject(options = {}) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const projectName = await promptQuestion(rl, 'Enter project name: ');
|
const projectName = await promptQuestion(rl, chalk.cyan('Enter project name: '));
|
||||||
const projectDescription = await promptQuestion(rl, 'Enter project description: ');
|
const projectDescription = await promptQuestion(rl, chalk.cyan('Enter project description: '));
|
||||||
const projectVersionInput = await promptQuestion(rl, 'Enter project version (default: 1.0.0): ');
|
const projectVersionInput = await promptQuestion(rl, chalk.cyan('Enter project version (default: 1.0.0): '));
|
||||||
const authorName = await promptQuestion(rl, 'Enter your name: ');
|
const authorName = await promptQuestion(rl, chalk.cyan('Enter your name: '));
|
||||||
|
|
||||||
// Set default version if not provided
|
// Set default version if not provided
|
||||||
const projectVersion = projectVersionInput.trim() ? projectVersionInput : '1.0.0';
|
const projectVersion = projectVersionInput.trim() ? projectVersionInput : '1.0.0';
|
||||||
@@ -210,10 +240,15 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
"@anthropic-ai/sdk": "^0.39.0",
|
"@anthropic-ai/sdk": "^0.39.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^5.3.0",
|
||||||
"commander": "^11.1.0",
|
"commander": "^11.1.0",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
"openai": "^4.86.1"
|
"openai": "^4.86.1",
|
||||||
|
"figlet": "^1.7.0",
|
||||||
|
"boxen": "^7.1.1",
|
||||||
|
"gradient-string": "^2.0.2",
|
||||||
|
"cli-table3": "^0.6.3",
|
||||||
|
"ora": "^7.0.1"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,7 +256,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
path.join(targetDir, 'package.json'),
|
path.join(targetDir, 'package.json'),
|
||||||
JSON.stringify(packageJson, null, 2)
|
JSON.stringify(packageJson, null, 2)
|
||||||
);
|
);
|
||||||
log('info', 'Created package.json');
|
log('success', 'Created package.json');
|
||||||
|
|
||||||
// Copy template files with replacements
|
// Copy template files with replacements
|
||||||
const replacements = {
|
const replacements = {
|
||||||
@@ -262,35 +297,65 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
// Initialize git repository if git is available
|
// Initialize git repository if git is available
|
||||||
try {
|
try {
|
||||||
if (!fs.existsSync(path.join(targetDir, '.git'))) {
|
if (!fs.existsSync(path.join(targetDir, '.git'))) {
|
||||||
|
log('info', 'Initializing git repository...');
|
||||||
execSync('git init', { stdio: 'ignore' });
|
execSync('git init', { stdio: 'ignore' });
|
||||||
log('info', 'Initialized git repository');
|
log('success', 'Git repository initialized');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('warn', 'Git not available, skipping repository initialization');
|
log('warn', 'Git not available, skipping repository initialization');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run npm install automatically
|
// Run npm install automatically
|
||||||
log('info', 'Installing dependencies...');
|
console.log(boxen(chalk.cyan('Installing dependencies...'), {
|
||||||
|
padding: 0.5,
|
||||||
|
margin: 0.5,
|
||||||
|
borderStyle: 'round',
|
||||||
|
borderColor: 'blue'
|
||||||
|
}));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
execSync('npm install', { stdio: 'inherit', cwd: targetDir });
|
execSync('npm install', { stdio: 'inherit', cwd: targetDir });
|
||||||
log('info', `${COLORS.green}Dependencies installed successfully!${COLORS.reset}`);
|
log('success', 'Dependencies installed successfully!');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log('error', 'Failed to install dependencies:', error.message);
|
log('error', 'Failed to install dependencies:', error.message);
|
||||||
log('error', 'Please run npm install manually');
|
log('error', 'Please run npm install manually');
|
||||||
}
|
}
|
||||||
|
|
||||||
log('info', `${COLORS.green}${COLORS.bright}Project initialized successfully!${COLORS.reset}`);
|
// Display success message
|
||||||
log('info', '');
|
console.log(boxen(
|
||||||
log('info', 'Next steps:');
|
warmGradient.multiline(figlet.textSync('Success!', { font: 'Standard' })) +
|
||||||
log('info', '1. Rename .env.example to .env and add your ANTHROPIC_API_KEY and PERPLEXITY_API_KEY');
|
'\n' + chalk.green('Project initialized successfully!'),
|
||||||
log('info', '2. Discuss your idea with AI, and once ready ask for a PRD, and save it as PRD.txt in the /scripts directory');
|
{
|
||||||
log('info', '3. Ask Cursor Agent to parse your PRD.txt and generate tasks');
|
padding: 1,
|
||||||
log('info', '└── You can also manually run `npm run parse-prd -- --input=<your-prd-file.txt>` to generate tasks');
|
margin: 1,
|
||||||
log('info', '4. Ask Cursor to analyze the complexity of your tasks, which will generate a task-complexity-report.json file in /scripts for your review.');
|
borderStyle: 'double',
|
||||||
log('info', '5. Ask Cursor which task is next and it will determine what to start with based on task statuses and dependencies.');
|
borderColor: 'green'
|
||||||
log('info', '6. Ask Cursor to expand any tasks that are too large in scope or complexity. The complexity report will be used to generate subtasks if it exists.');
|
}
|
||||||
log('info', '7. Ship it!');
|
));
|
||||||
log('info', '* Review the README.md file to learn how to use other commands via Cursor Agent.');
|
|
||||||
|
// Display next steps in a nice box
|
||||||
|
console.log(boxen(
|
||||||
|
chalk.cyan.bold('Things you can now do:') + '\n\n' +
|
||||||
|
chalk.white('1. ') + chalk.yellow('Rename .env.example to .env and add your ANTHROPIC_API_KEY and PERPLEXITY_API_KEY') + '\n' +
|
||||||
|
chalk.white('2. ') + chalk.yellow('Discuss your idea with AI, and once ready ask for a PRD, and save it as PRD.txt') + '\n' +
|
||||||
|
chalk.white('3. ') + chalk.yellow('Ask Cursor Agent to parse your PRD.txt and generate tasks') + '\n' +
|
||||||
|
chalk.white(' └─ ') + chalk.dim('You can also run ') + chalk.cyan('npm run parse-prd -- --input=<your-prd-file.txt>') + '\n' +
|
||||||
|
chalk.white('4. ') + chalk.yellow('Ask Cursor to analyze the complexity of your tasks') + '\n' +
|
||||||
|
chalk.white('5. ') + chalk.yellow('Ask Cursor which task is next to determine where to start') + '\n' +
|
||||||
|
chalk.white('6. ') + chalk.yellow('Ask Cursor to expand any complex tasks that are too large or complex.') + '\n' +
|
||||||
|
chalk.white('7. ') + chalk.yellow('Ask Cursor to set the status of a task, or multiple tasks. Use the task id from the task lists.') + '\n' +
|
||||||
|
chalk.white('8. ') + chalk.yellow('Ask Cursor to update all tasks from a specific task id based on new learnings or pivots in your project.') + '\n' +
|
||||||
|
chalk.white('9. ') + chalk.green.bold('Ship it!') + '\n\n' +
|
||||||
|
chalk.dim('* Review the README.md file to learn how to use other commands via Cursor Agent.'),
|
||||||
|
{
|
||||||
|
padding: 1,
|
||||||
|
margin: 1,
|
||||||
|
borderStyle: 'round',
|
||||||
|
borderColor: 'yellow',
|
||||||
|
title: 'Getting Started',
|
||||||
|
titleAlignment: 'center'
|
||||||
|
}
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the initialization if this script is executed directly
|
// Run the initialization if this script is executed directly
|
||||||
|
|||||||
Reference in New Issue
Block a user