task-engine-ai-core
Version:
Revolutionary AI-driven task management system with complete transformation trilogy: Frontend v0.1.0, Backend v0.2.0, CLI v0.3.0 - Enterprise-grade performance with 95% improvements
433 lines (353 loc) ⢠15.4 kB
JavaScript
/**
* Standalone MCP Setup Command
*
* This script sets up MCP configuration for any project using the global
* task-engine-ai-core package.
*
* @version 0.5.0
* @author Task Engine AI Team
*/
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
class MCPSetup {
constructor() {
this.packageVersion = '0.5.0';
this.projectRoot = process.cwd();
}
async setup() {
console.log('š Task Engine AI Core - MCP Setup v0.5.0');
console.log('============================================\n');
try {
// Add debug information
console.log('š Debug info:');
console.log(` Node.js version: ${process.version}`);
console.log(` Platform: ${process.platform}`);
console.log(` Working directory: ${process.cwd()}`);
console.log('');
// Detect IDE
const ide = this.detectIDE();
console.log(`š± Detected IDE: ${ide}`);
console.log(`š Project root: ${this.projectRoot}`);
console.log(`š§ Using npx approach for automatic package management\n`);
// Create MCP configuration
console.log('āļø Step 1: Creating MCP configuration...');
await this.createMCPConfig(ide);
// Initialize Task Engine if needed
console.log('āļø Step 2: Initializing Task Engine structure...');
await this.initializeTaskEngine();
console.log('\nā
MCP setup completed successfully!');
console.log('\nš Next steps:');
console.log('1. Restart your IDE to load the new MCP configuration');
console.log('2. Test the connection by asking Claude to list tasks');
console.log('3. Start using Task Engine AI through MCP!');
} catch (error) {
console.error('\nā Setup failed:', error.message);
console.error('Stack trace:', error.stack);
console.error('\nš§ Troubleshooting:');
console.error('1. Ensure you have Node.js and npm installed');
console.error('2. Check that you have write permissions in the project directory');
console.error('3. Verify your IDE supports MCP configuration');
console.error('4. Try the manual setup approach if this continues to fail');
throw error; // Re-throw to be caught by main execution
}
}
detectIDE() {
const cwd = this.projectRoot;
// Check for IDE-specific directories
if (existsSync(join(cwd, '.cursor'))) return 'cursor';
if (existsSync(join(cwd, '.vscode'))) return 'vscode';
// Check environment variables
if (process.env.CURSOR_USER_DATA) return 'cursor';
if (process.env.VSCODE_PID) return 'vscode';
// Default to cursor
return 'cursor';
}
async createMCPConfig(ide) {
console.log(`āļø Creating MCP configuration for ${ide}...`);
const configFile = ide === 'vscode' ? '.vscode/mcp.json' : '.cursor/mcp.json';
const configDir = dirname(configFile);
const fullConfigPath = join(this.projectRoot, configFile);
const fullConfigDir = join(this.projectRoot, configDir);
// Create directory if it doesn't exist
if (!existsSync(fullConfigDir)) {
mkdirSync(fullConfigDir, { recursive: true });
console.log(`š Created directory: ${configDir}`);
}
// Generate configuration
const config = this.generateMCPConfig(ide);
// Merge with existing configuration if it exists
let finalConfig = config;
if (existsSync(fullConfigPath)) {
try {
const existingConfig = JSON.parse(readFileSync(fullConfigPath, 'utf8'));
finalConfig = this.mergeConfigurations(existingConfig, config, ide);
console.log(`š Merged with existing configuration`);
} catch (error) {
console.log(`ā ļø Could not parse existing config, creating new one`);
}
}
// Write configuration file
writeFileSync(fullConfigPath, JSON.stringify(finalConfig, null, 2));
console.log(`ā
Created/updated MCP configuration: ${configFile}`);
}
generateMCPConfig(ide) {
// Use the simple and efficient npx approach
const baseEnv = {
TASK_ENGINE_VERSION: this.packageVersion,
TASK_ENGINE_ENVIRONMENT: 'development',
TASK_ENGINE_DEBUG: 'true',
TASK_ENGINE_LOG_LEVEL: 'info',
MODEL: 'claude-3-5-sonnet-20241022',
MAX_TOKENS: '64000',
TEMPERATURE: '0.2',
DEFAULT_SUBTASKS: '5',
DEFAULT_PRIORITY: 'medium'
};
const serverConfig = {
command: 'npx',
args: ['--package=task-engine-ai-core@' + this.packageVersion, 'task-master-mcp'],
env: baseEnv
};
if (ide === 'vscode') {
return {
servers: {
'task-engine-ai-core': {
...serverConfig,
env: {
...baseEnv,
MODEL: 'claude-3-5-sonnet-20241022',
MAX_TOKENS: '64000',
TEMPERATURE: '0.2'
}
}
}
};
} else {
return {
mcpServers: {
'task-engine-ai-core': serverConfig
}
};
}
}
mergeConfigurations(existing, newConfig, ide) {
const serverKey = ide === 'vscode' ? 'servers' : 'mcpServers';
if (!existing[serverKey]) {
existing[serverKey] = {};
}
// Update or add the task-engine-ai-core configuration
existing[serverKey]['task-engine-ai-core'] = newConfig[serverKey]['task-engine-ai-core'];
return existing;
}
async initializeTaskEngine() {
const taskEngineDir = join(this.projectRoot, '.task-engine');
if (!existsSync(taskEngineDir)) {
console.log('š§ Initializing Task Engine project with templates...');
try {
// Create basic Task Engine structure
mkdirSync(taskEngineDir, { recursive: true });
mkdirSync(join(taskEngineDir, 'tasks'), { recursive: true });
mkdirSync(join(taskEngineDir, 'docs'), { recursive: true });
mkdirSync(join(taskEngineDir, 'reports'), { recursive: true });
mkdirSync(join(taskEngineDir, 'templates'), { recursive: true });
// Detect project type based on files in directory
const projectType = this.detectProjectType();
const projectName = this.getProjectName();
// Create configuration with template variables
const basicConfig = {
version: this.packageVersion,
projectRoot: this.projectRoot,
projectName: projectName,
projectType: projectType,
initialized: new Date().toISOString(),
setupMethod: 'template',
taskEngine: {
version: this.packageVersion,
environment: 'development',
debug: true,
logLevel: 'info'
},
features: {
aiAssistance: true,
taskManagement: true,
progressTracking: true,
mcpIntegration: true
}
};
writeFileSync(
join(taskEngineDir, 'config.json'),
JSON.stringify(basicConfig, null, 2)
);
// Create empty tasks file with metadata
const emptyTasks = {
version: "1.0",
projectName: projectName,
projectType: projectType,
created: new Date().toISOString(),
lastModified: new Date().toISOString(),
metadata: {
setupMethod: 'template',
taskEngineVersion: this.packageVersion,
totalTasks: 0,
completedTasks: 0,
pendingTasks: 0
},
tasks: [],
taskCounter: 0
};
writeFileSync(
join(taskEngineDir, 'tasks', 'tasks.json'),
JSON.stringify(emptyTasks, null, 2)
);
// Create basic README
const readmeContent = this.generateProjectReadme(projectName, projectType);
writeFileSync(
join(taskEngineDir, 'docs', 'README.md'),
readmeContent
);
console.log('ā
Task Engine project initialized with templates');
console.log(`š Project: ${projectName} (${projectType})`);
console.log('š Created: .task-engine/ directory structure');
} catch (error) {
console.log(`ā ļø Could not initialize Task Engine: ${error.message}`);
}
} else {
console.log('ā¹ļø Task Engine project already initialized');
}
}
detectProjectType() {
const packageJsonPath = join(this.projectRoot, 'package.json');
if (existsSync(packageJsonPath)) {
try {
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
// Check dependencies for framework indicators
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
if (deps.react || deps['@types/react']) return 'web-app';
if (deps.express || deps.fastify || deps.koa) return 'api';
if (deps['react-native']) return 'mobile-app';
if (deps.electron) return 'desktop-app';
if (packageJson.bin) return 'cli-tool';
// Check for library indicators
if (packageJson.main && !packageJson.scripts?.start) return 'library';
} catch (error) {
// Ignore JSON parsing errors
}
}
// Check for other project indicators
if (existsSync(join(this.projectRoot, 'requirements.txt'))) return 'api';
if (existsSync(join(this.projectRoot, 'Cargo.toml'))) return 'cli-tool';
if (existsSync(join(this.projectRoot, 'go.mod'))) return 'api';
return 'generic';
}
getProjectName() {
const packageJsonPath = join(this.projectRoot, 'package.json');
if (existsSync(packageJsonPath)) {
try {
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
if (packageJson.name) return packageJson.name;
} catch (error) {
// Ignore JSON parsing errors
}
}
// Fallback to directory name
return this.projectRoot.split(/[/\\]/).pop() || 'My Project';
}
generateProjectReadme(projectName, projectType) {
return `# ${projectName}
A ${projectType} project powered by **Task Engine AI Core v${this.packageVersion}**.
## š¤ Task Engine AI Integration
This project includes Task Engine AI for intelligent task management and AI-assisted development.
### Getting Started with Task Engine
1. **View Tasks:** Ask Claude "Show me my current tasks"
2. **Create Tasks:** "Create a task to implement [feature]"
3. **Update Progress:** "Mark task [id] as completed"
4. **Get Help:** "Help me break down this complex feature into subtasks"
## š Project Structure
\`\`\`
${projectName}/
āāā .task-engine/ # Task Engine AI project data
ā āāā config.json # Project configuration
ā āāā tasks/ # Task files and data
ā āāā docs/ # Project documentation
ā āāā reports/ # Progress reports and analytics
ā āāā templates/ # Project templates
āāā .cursor/mcp.json # Cursor IDE MCP configuration
āāā [your project files]
\`\`\`
## š Next Steps
1. Ask Claude to create initial tasks for your project
2. Use Task Engine for planning and progress tracking
3. Let AI assist with implementation and problem-solving
---
**Powered by Task Engine AI Core v${this.packageVersion}** š`;
}
static showHelp() {
console.log(`
Task Engine AI Core - MCP Setup v0.5.0
Usage:
setup-mcp [options]
Options:
--help, -h Show this help message
--version, -v Show version information
This command sets up MCP configuration for Task Engine AI Core in the current project.
Requirements:
- task-engine-ai-core must be installed globally
- Run from your project root directory
- IDE must support MCP (Cursor, VS Code, Claude Desktop)
Examples:
# Basic setup in current directory
setup-mcp
# Install global package first if needed
npm install -g task-engine-ai-core
setup-mcp
For more information, visit: https://github.com/cracked99/Task-engine
`);
}
}
// Main execution - More robust approach
const __filename = fileURLToPath(import.meta.url);
// Multiple ways to detect if this is the main module
const isMainModule = (
process.argv[1] === __filename ||
process.argv[1]?.endsWith('setup-mcp.js') ||
process.argv[1]?.endsWith('setup-mcp') ||
import.meta.url === `file://${process.argv[1]}` ||
process.argv[1]?.includes('setup-mcp')
);
// Always run if executed directly (more permissive approach)
const shouldRun = isMainModule || process.argv[1]?.includes('npx');
if (shouldRun) {
const args = process.argv.slice(2);
if (args.includes('--help') || args.includes('-h')) {
MCPSetup.showHelp();
process.exit(0);
}
if (args.includes('--version') || args.includes('-v')) {
console.log('Task Engine AI Core - MCP Setup v0.5.0');
process.exit(0);
}
// Add error handling and timeout
const setup = new MCPSetup();
// Set a timeout to prevent hanging
const timeoutId = setTimeout(() => {
console.error('ā Setup timed out after 30 seconds');
console.error('This may be due to network issues or environment problems.');
console.error('Please try the manual setup approach.');
process.exit(1);
}, 30000);
setup.setup()
.then(() => {
clearTimeout(timeoutId);
process.exit(0);
})
.catch(error => {
clearTimeout(timeoutId);
console.error('ā Setup failed:', error.message);
console.error('\nš§ Manual setup alternative:');
console.error('Visit: https://github.com/cracked99/Task-engine#manual-setup');
process.exit(1);
});
}
export default MCPSetup;