vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
237 lines (236 loc) • 11.4 kB
JavaScript
import { z } from 'zod';
export const moduleParametersSchema = z.record(z.union([
z.string(),
z.number(),
z.boolean()
])).describe('Key-value pairs for template parameter substitution');
export const moduleSelectionItemSchema = z.object({
modulePath: z.string()
.min(1, 'Module path cannot be empty')
.describe('Path to the module template (e.g., "frontend/react-vite", "backend/nodejs-express")'),
params: moduleParametersSchema
.describe('Parameters for template substitution specific to this module'),
moduleKey: z.string()
.optional()
.describe('Optional key for path resolution (e.g., "frontend", "backend")')
}).describe('Configuration for a single module to be included in the starter kit');
export const enhancedModuleSelectionItemSchema = z.object({
modulePath: z.string()
.min(1, 'Module path cannot be empty')
.describe('Path to the module template (e.g., "ai-integration/openai-langchain", "development-tools/monaco-judge0")'),
moduleType: z.string()
.min(1, 'Module type cannot be empty')
.describe('Type/category of the module (e.g., "ai-integration", "development-tools", "real-time", "payment")'),
params: moduleParametersSchema
.describe('Parameters for template substitution specific to this module'),
moduleKey: z.string()
.optional()
.describe('Optional key for path resolution (e.g., "frontend", "backend", "root")')
}).describe('Enhanced configuration for a single module with type classification');
export const globalParametersSchema = z.object({
projectName: z.string()
.min(1, 'Project name is required')
.max(100, 'Project name must be 100 characters or less')
.regex(/^[a-zA-Z0-9\s\-_]+$/, 'Project name can only contain letters, numbers, spaces, hyphens, and underscores')
.describe('The name of the project being generated'),
projectDescription: z.string()
.min(10, 'Project description must be at least 10 characters')
.max(500, 'Project description must be 500 characters or less')
.describe('A brief description of what the project does'),
frontendPath: z.string()
.describe('Directory path for frontend code (default: "client")'),
backendPath: z.string()
.describe('Directory path for backend code (default: "server")'),
backendPort: z.number()
.int()
.min(1000, 'Port must be at least 1000')
.max(65535, 'Port must be at most 65535')
.describe('Port number for the backend server (default: 3000)'),
databaseName: z.string()
.optional()
.describe('Name of the database (if applicable)'),
apiPrefix: z.string()
.describe('API route prefix (default: "/api")'),
enableTypeScript: z.boolean()
.describe('Whether to use TypeScript (default: true)'),
enableTesting: z.boolean()
.describe('Whether to include testing setup (default: true)'),
enableDocker: z.boolean()
.describe('Whether to include Docker configuration (default: false)'),
enableCICD: z.boolean()
.describe('Whether to include CI/CD configuration (default: false)')
}).describe('Global parameters that apply to the entire project configuration');
export const moduleSelectionResponseSchema = z.object({
globalParams: globalParametersSchema
.describe('Global parameters that apply to the entire project'),
moduleSelections: z.array(moduleSelectionItemSchema)
.min(1, 'At least one module must be selected')
.max(10, 'Cannot select more than 10 modules')
.describe('Array of modules to be included in the starter kit')
}).describe('Complete module selection configuration for generating a fullstack starter kit');
export const dynamicTemplateSchema = z.object({
moduleName: z.string()
.min(1, 'Module name is required')
.describe('Unique identifier for this module'),
description: z.string()
.min(10, 'Description must be at least 10 characters')
.describe('Brief description of what this module provides'),
type: z.string()
.min(1, 'Module type is required')
.describe('Category/type of the module (e.g., frontend, backend, database, fullstack, utility, monitoring, etc.)'),
placeholders: z.array(z.string())
.optional()
.describe('List of placeholder variables used in this template'),
provides: z.object({
techStack: z.record(z.object({
name: z.string().describe('Technology name'),
version: z.string().optional().describe('Version specification'),
rationale: z.string().optional().describe('Why this technology was chosen')
})).optional().describe('Technologies provided by this module'),
directoryStructure: z.array(z.object({
path: z.string().min(1, "Path cannot be empty").describe('File or directory path'),
type: z.enum(['file', 'directory']).describe('Whether this is a file or directory'),
content: z.string().nullable().describe('File content (null for directories, string for files)'),
generationPrompt: z.string().nullable().optional().describe('Prompt for generating file content'),
children: z.array(z.any()).optional().describe('Child items (for directories only)')
})).optional().describe('Directory structure created by this module'),
dependencies: z.object({
npm: z.record(z.object({
dependencies: z.record(z.string()).optional(),
devDependencies: z.record(z.string()).optional()
})).optional()
}).optional().describe('Package dependencies added by this module'),
setupCommands: z.array(z.object({
command: z.string().describe('Command to execute'),
context: z.string().optional().describe('Context or explanation for the command')
})).optional().describe('Commands to run during setup with context'),
nextSteps: z.array(z.string())
.optional()
.describe('Recommended next steps after using this module')
}).describe('What this module provides to the project')
}).describe('Dynamically generated module template structure');
export const enhancedModuleSelectionResponseSchema = z.object({
globalParams: globalParametersSchema
.describe('Global parameters that apply to the entire project'),
moduleSelections: z.array(enhancedModuleSelectionItemSchema)
.min(1, 'At least one module must be selected')
.max(15, 'Maximum 15 modules allowed for complex projects')
.describe('Array of selected modules with their configurations and types')
}).describe('Enhanced response schema for complex module selection with research context');
export const unifiedTemplateSchema = z.object({
moduleName: z.string()
.min(1, 'Module name is required')
.describe('Unique identifier for this module'),
description: z.string()
.min(10, 'Description must be at least 10 characters')
.describe('Brief description of what this module provides'),
type: z.string()
.min(1, 'Module type is required')
.describe('Category/type of the module (e.g., ai-integration, development-tools, real-time)'),
provides: z.object({
techStack: z.record(z.object({
name: z.string().describe('Technology name'),
version: z.string().optional().describe('Version specification'),
rationale: z.string().describe('Why this technology was chosen based on research')
})).optional().describe('Technologies provided by this module'),
directoryStructure: z.array(z.object({
path: z.string().min(1, "Path cannot be empty").describe('File or directory path'),
type: z.enum(['file', 'directory']).describe('Whether this is a file or directory'),
content: z.string().nullable().describe('File content (null for directories)'),
generationPrompt: z.string().nullable().optional().describe('Prompt for generating file content'),
children: z.array(z.any()).optional().describe('Child items (for directories only)')
})).optional().describe('Directory structure created by this module'),
setupCommands: z.array(z.object({
command: z.string().describe('Command to execute'),
context: z.string().optional().describe('Context or explanation for the command')
})).optional().describe('Commands to run during setup with context')
}).describe('What this module provides to the project')
}).describe('Unified template schema for research-enhanced dynamic generation');
export function validateModuleSelectionResponse(data) {
try {
moduleSelectionResponseSchema.parse(data);
return true;
}
catch {
return false;
}
}
export function validateDynamicTemplate(data) {
try {
dynamicTemplateSchema.parse(data);
return true;
}
catch {
return false;
}
}
export function validateEnhancedModuleSelectionResponse(data) {
try {
enhancedModuleSelectionResponseSchema.parse(data);
return true;
}
catch {
return false;
}
}
export function validateUnifiedTemplate(data) {
try {
unifiedTemplateSchema.parse(data);
return true;
}
catch {
return false;
}
}
export function validateModuleSelectionWithErrors(data) {
try {
const validated = moduleSelectionResponseSchema.parse(data);
return { success: true, data: validated };
}
catch (error) {
if (error instanceof z.ZodError) {
const errors = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
return { success: false, errors };
}
return { success: false, errors: ['Unknown validation error'] };
}
}
export function validateDynamicTemplateWithErrors(data) {
try {
const validated = dynamicTemplateSchema.parse(data);
return { success: true, data: validated };
}
catch (error) {
if (error instanceof z.ZodError) {
const errors = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
return { success: false, errors };
}
return { success: false, errors: ['Unknown validation error'] };
}
}
export function validateEnhancedModuleSelectionWithErrors(data) {
try {
const validated = enhancedModuleSelectionResponseSchema.parse(data);
return { success: true, data: validated };
}
catch (error) {
if (error instanceof z.ZodError) {
const errors = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
return { success: false, errors };
}
return { success: false, errors: ['Unknown validation error'] };
}
}
export function validateUnifiedTemplateWithErrors(data) {
try {
const validated = unifiedTemplateSchema.parse(data);
return { success: true, data: validated };
}
catch (error) {
if (error instanceof z.ZodError) {
const errors = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`);
return { success: false, errors };
}
return { success: false, errors: ['Unknown validation error'] };
}
}