@sprouted/create-vibes
Version:
Create a new Vibes monorepo
159 lines • 6.38 kB
JavaScript
import { Command } from 'commander';
import chalk from 'chalk';
import { CreateFeatureCommand } from './commands/create-feature.js';
import { CreateAppCommand } from './commands/create-app.js';
import { AddAppCommand } from './commands/add-app.js';
import { CreateSpecCommand } from './commands/create-spec.js';
import { TemplateEngine } from './template-engine/engine.js';
import * as path from 'path';
import * as url from 'url';
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
const version = '0.10.0'; // You could read this from package.json
const program = new Command();
// Initialize template engine
const templateEngine = new TemplateEngine();
program
.name('vibe')
.description('Vibes CLI - Making development flow')
.version(version);
// Spec command - FIRST! (Spec-driven development)
program
.command('spec <name>')
.description('Create a specification (spec-driven development)')
.option('--type <type>', 'Spec type (feature, api, architecture)', 'feature')
.option('--status <status>', 'Initial status (draft, review, approved)', 'draft')
.option('--force', 'Overwrite existing spec')
.action(async (name, options) => {
try {
const createSpec = new CreateSpecCommand();
const specOptions = {
name,
type: options.type,
status: options.status,
force: options.force,
projectRoot: process.cwd()
};
await createSpec.execute(specOptions);
}
catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
process.exit(1);
}
});
// Create feature command
program
.command('create <featureName>')
.description('Create a new feature')
.option('--no-api', 'Skip API layer')
.option('--no-ui', 'Skip UI layer')
.option('--framework <framework>', 'UI framework (react or react-native)', 'react')
.option('--features <features...>', 'Additional features to include')
.action(async (featureName, options) => {
try {
const createFeature = new CreateFeatureCommand();
const featureOptions = {
name: featureName,
includeApi: options.api,
includeUi: options.ui,
uiFramework: options.framework,
features: options.features,
projectRoot: process.cwd()
};
await createFeature.execute(featureOptions);
}
catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
process.exit(1);
}
});
// Interactive create command
program
.command('create')
.description('Create a new feature (interactive)')
.action(async () => {
try {
const createFeature = new CreateFeatureCommand();
const options = await createFeature.interactivePrompt();
await createFeature.execute({ ...options, projectRoot: process.cwd() });
}
catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
process.exit(1);
}
});
// Add app command
program
.command('add <appType>')
.description('Add a new app')
.option('-n, --name <n>', 'App name')
.option('--display-name <displayName>', 'Display name for mobile/desktop apps')
.option('--framework <framework>', 'Framework choice for web apps')
.option('--no-router', 'Skip router for web apps')
.option('--tailwind', 'Include Tailwind CSS for web apps')
.option('--no-navigator', 'Skip navigator for mobile apps')
.option('--auth', 'Include authentication')
.option('--no-api-client', 'Skip API client for mobile apps')
.option('--port <port>', 'Port number for API apps', parseInt)
.option('--no-database', 'Skip database for API apps')
.option('--no-validation', 'Skip validation for API apps')
.option('--swagger', 'Include Swagger for API apps')
.option('--graphql', 'Include GraphQL for API apps')
.option('--app-id <appId>', 'Application ID for desktop apps')
.option('--no-auto-updater', 'Skip auto-updater for desktop apps')
.option('--system-tray', 'Include system tray for desktop apps')
.option('--no-menu-bar', 'Skip menu bar for desktop apps')
.option('--no-ipc', 'Skip IPC examples for desktop apps')
.option('--no-dark-mode', 'Skip dark mode for desktop apps')
.action(async (appType, options) => {
try {
const createApp = new CreateAppCommand(templateEngine);
const appOptions = {
type: appType,
name: options.name,
displayName: options.displayName,
appId: options.appId,
framework: options.framework,
includeRouter: options.router !== false,
includeTailwind: options.tailwind === true,
includeNavigator: options.navigator !== false,
includeAuth: options.auth === true,
includeApiClient: options.apiClient !== false,
port: options.port,
includeDatabase: options.database !== false,
includeValidation: options.validation !== false,
includeSwagger: options.swagger === true,
includeGraphQL: options.graphql === true,
includeAutoUpdater: options.autoUpdater !== false,
includeSystemTray: options.systemTray === true,
includeMenuBar: options.menuBar !== false,
includeIpc: options.ipc !== false,
includeDarkMode: options.darkMode !== false
};
await createApp.execute(appOptions);
}
catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
process.exit(1);
}
});
// Interactive add command
program
.command('add')
.description('Add a new app (interactive)')
.action(async () => {
try {
const addApp = new AddAppCommand(templateEngine);
await addApp.execute();
}
catch (error) {
console.error(chalk.red('Error:'), error instanceof Error ? error.message : String(error));
process.exit(1);
}
});
// Additional commands could be added here
// For example: dev, build, test, etc.
program.parse(process.argv);
// Export for programmatic use
export default program;
//# sourceMappingURL=cli.js.map