vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
196 lines (195 loc) ⢠8.18 kB
JavaScript
import { fileURLToPath } from 'url';
import path from 'path';
import chalk from 'chalk';
import boxen from 'boxen';
import ora from 'ora';
import dotenv from 'dotenv';
import { setupWizard } from './setup-wizard.js';
import logger from './logger.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const projectRoot = path.resolve(__dirname, '..');
const envPath = path.join(projectRoot, '.env');
const args = process.argv.slice(2);
function detectMode() {
if (args.includes('--help') || args.includes('-h')) {
return 'help';
}
if (args.includes('--setup') || args.includes('--reconfigure')) {
return 'setup';
}
if (args.includes('--interactive') || args.includes('-i')) {
return 'interactive';
}
if (args.length === 0 ||
args.every(arg => ['--sse', '--port', '--stdio'].includes(arg.split('=')[0]))) {
return 'server';
}
if (args.some(arg => !arg.startsWith('-'))) {
return 'cli';
}
return 'server';
}
function displayHelp() {
console.log(boxen(chalk.cyan.bold('š¤ Vibe - Unified AI Development Assistant') + '\n\n' +
chalk.white('Your one-stop command for AI-powered development'), {
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'cyan',
textAlignment: 'center'
}));
console.log(chalk.yellow('\nš Usage:\n'));
console.log(chalk.green(' vibe ') + chalk.gray('Start MCP server (default)'));
console.log(chalk.green(' vibe --interactive ') + chalk.gray('Start interactive CLI mode'));
console.log(chalk.green(' vibe "your request" ') + chalk.gray('Process natural language request'));
console.log(chalk.green(' vibe --setup ') + chalk.gray('Run setup wizard'));
console.log(chalk.green(' vibe --help ') + chalk.gray('Show this help message'));
console.log(chalk.yellow('\nš Server Options:\n'));
console.log(chalk.green(' vibe --sse ') + chalk.gray('Start with Server-Sent Events transport'));
console.log(chalk.green(' vibe --port <number> ') + chalk.gray('Specify port for SSE mode (default: 3000)'));
console.log(chalk.yellow('\nš¬ CLI Options:\n'));
console.log(chalk.green(' vibe "request" --verbose') + chalk.gray('Show detailed output'));
console.log(chalk.green(' vibe "request" --json ') + chalk.gray('Output in JSON format'));
console.log(chalk.green(' vibe "request" --yaml ') + chalk.gray('Output in YAML format'));
console.log(chalk.green(' vibe "request" --quiet ') + chalk.gray('Suppress non-error output'));
console.log(chalk.yellow('\nš Examples:\n'));
console.log(chalk.cyan(' Start MCP Server:'));
console.log(chalk.gray(' vibe'));
console.log(chalk.gray(' vibe --sse'));
console.log(chalk.cyan('\n Process Requests:'));
console.log(chalk.gray(' vibe "research React best practices"'));
console.log(chalk.gray(' vibe "create a PRD for e-commerce platform"'));
console.log(chalk.gray(' vibe "map the codebase structure" --json'));
console.log(chalk.gray(' vibe "generate user stories for auth"'));
console.log(chalk.yellow('\nš ļø Available Tools:\n'));
const tools = [
'⢠Research Manager - Technical research',
'⢠PRD Generator - Product requirements',
'⢠User Stories - Agile stories',
'⢠Task List - Development tasks',
'⢠Code Map - Codebase analysis',
'⢠Context Curator - AI context packages',
'⢠Starter Kit - Project templates',
'⢠Rules Generator - Coding standards',
'⢠Vibe Task Manager - Task management',
'⢠Workflow Runner - Multi-step workflows',
'⢠Agent Coordination - Multi-agent tasks'
];
tools.forEach(tool => console.log(chalk.cyan(tool)));
console.log(chalk.gray('\nš Documentation: https://github.com/freshtechbro/Vibe-Coder-MCP\n'));
}
async function main() {
try {
const mode = detectMode();
if (mode !== 'help' && await setupWizard.isFirstRun()) {
console.log(chalk.cyan.bold('\nš Welcome to Vibe!\n'));
console.log(chalk.yellow('First-time setup required...\n'));
const success = await setupWizard.run();
if (!success) {
console.log(chalk.red('\nā Setup cancelled.'));
console.log(chalk.gray('Run ') + chalk.cyan('vibe --setup') + chalk.gray(' to configure later.'));
process.exit(1);
}
console.log(boxen(chalk.green.bold('ā
Setup Complete!') + '\n\n' +
chalk.white('Vibe is now configured and ready to use.') + '\n\n' +
chalk.cyan('Quick Start:') + '\n' +
chalk.gray('⢠Run ') + chalk.cyan('vibe') + chalk.gray(' to start the MCP server') + '\n' +
chalk.gray('⢠Run ') + chalk.cyan('vibe "your request"') + chalk.gray(' to use the CLI') + '\n' +
chalk.gray('⢠Run ') + chalk.cyan('vibe --help') + chalk.gray(' for all options'), {
padding: 1,
margin: 1,
borderStyle: 'double',
borderColor: 'green'
}));
process.exit(0);
}
dotenv.config({ path: envPath });
switch (mode) {
case 'help':
displayHelp();
break;
case 'setup':
await runSetup();
break;
case 'server':
await startServer();
break;
case 'cli':
await runCLI();
break;
case 'interactive':
await runInteractive();
break;
}
}
catch (error) {
console.error(chalk.red('\nā Error:'), error);
logger.error({ err: error }, 'Unified CLI error');
process.exit(1);
}
}
async function runSetup() {
console.log(chalk.cyan.bold('\nš§ Vibe Configuration\n'));
const success = await setupWizard.run();
if (success) {
console.log(chalk.green('\nā
Configuration updated successfully!'));
console.log(chalk.gray('Run ') + chalk.cyan('vibe') + chalk.gray(' to start the server.'));
}
else {
console.log(chalk.red('\nā Configuration failed.'));
}
}
async function startServer() {
const spinner = ora({
text: 'Starting Vibe MCP Server...',
color: 'cyan'
}).start();
try {
await import('./index-with-setup.js');
spinner.stop();
}
catch (error) {
spinner.fail('Failed to start server');
throw error;
}
}
async function runInteractive() {
try {
process.argv = [process.argv[0], process.argv[1], '--interactive'];
await import('./cli/index.js');
}
catch (error) {
console.error(chalk.red('ā Interactive CLI Error:'), error);
logger.error({ err: error }, 'Interactive CLI execution error');
process.exit(1);
}
}
async function runCLI() {
try {
const cliArgs = args.filter(arg => !arg.startsWith('-') ||
['--verbose', '--quiet', '--json', '--yaml', '--format', '--no-color', '-v', '-q'].includes(arg));
process.argv = [process.argv[0], process.argv[1], ...cliArgs];
await import('./cli/index.js');
}
catch (error) {
console.error(chalk.red('ā CLI Error:'), error);
logger.error({ err: error }, 'CLI execution error');
process.exit(1);
}
}
process.on('uncaughtException', (error) => {
logger.error({ err: error }, 'Uncaught exception');
console.error(chalk.red('\nā Uncaught exception:'), error);
process.exit(1);
});
process.on('unhandledRejection', (reason, promise) => {
logger.error({ err: reason, promise }, 'Unhandled rejection');
console.error(chalk.red('\nā Unhandled rejection:'), reason);
process.exit(1);
});
main().catch((error) => {
console.error(chalk.red('\nā Fatal error:'), error);
process.exit(1);
});