@atlashub/smartstack-mcp 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server.ts","../src/lib/logger.ts","../src/config.ts","../src/utils/fs.ts","../src/types/index.ts","../src/lib/detector.ts","../src/utils/git.ts","../src/utils/dotnet.ts","../src/tools/validate-conventions.ts","../src/tools/check-migrations.ts","../src/tools/scaffold-extension.ts","../src/tools/api-docs.ts","../src/resources/conventions.ts","../src/resources/project-info.ts","../src/resources/api-endpoints.ts","../src/resources/db-schema.ts","../src/index.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nimport { logger } from './lib/logger.js';\nimport { getConfig } from './config.js';\n\n// Tools\nimport { handleValidateConventions, validateConventionsTool } from './tools/validate-conventions.js';\nimport { handleCheckMigrations, checkMigrationsTool } from './tools/check-migrations.js';\nimport { handleScaffoldExtension, scaffoldExtensionTool } from './tools/scaffold-extension.js';\nimport { handleApiDocs, apiDocsTool } from './tools/api-docs.js';\n\n// Resources\nimport { getConventionsResource, conventionsResourceTemplate } from './resources/conventions.js';\nimport { getProjectInfoResource, projectInfoResourceTemplate } from './resources/project-info.js';\nimport { getApiEndpointsResource, apiEndpointsResourceTemplate } from './resources/api-endpoints.js';\nimport { getDbSchemaResource, dbSchemaResourceTemplate } from './resources/db-schema.js';\n\nexport async function createServer(): Promise<Server> {\n const config = await getConfig();\n\n const server = new Server(\n {\n name: 'smartstack-mcp',\n version: '1.0.0',\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n },\n }\n );\n\n // ============================================================================\n // Tools Registration\n // ============================================================================\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n logger.debug('Listing tools');\n return {\n tools: [\n validateConventionsTool,\n checkMigrationsTool,\n scaffoldExtensionTool,\n apiDocsTool,\n ],\n };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const startTime = Date.now();\n\n logger.toolStart(name, args);\n\n try {\n let result: string;\n\n switch (name) {\n case 'validate_conventions':\n result = await handleValidateConventions(args, config);\n break;\n\n case 'check_migrations':\n result = await handleCheckMigrations(args, config);\n break;\n\n case 'scaffold_extension':\n result = await handleScaffoldExtension(args, config);\n break;\n\n case 'api_docs':\n result = await handleApiDocs(args, config);\n break;\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n\n logger.toolEnd(name, true, Date.now() - startTime);\n\n return {\n content: [\n {\n type: 'text',\n text: result,\n },\n ],\n };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logger.toolError(name, err);\n\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${err.message}`,\n },\n ],\n isError: true,\n };\n }\n });\n\n // ============================================================================\n // Resources Registration\n // ============================================================================\n\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n logger.debug('Listing resources');\n return {\n resources: [\n conventionsResourceTemplate,\n projectInfoResourceTemplate,\n apiEndpointsResourceTemplate,\n dbSchemaResourceTemplate,\n ],\n };\n });\n\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n logger.debug('Reading resource', { uri });\n\n try {\n let content: string;\n let mimeType = 'text/markdown';\n\n if (uri === 'smartstack://conventions') {\n content = await getConventionsResource(config);\n } else if (uri === 'smartstack://project') {\n content = await getProjectInfoResource(config);\n } else if (uri.startsWith('smartstack://api/')) {\n const endpoint = uri.replace('smartstack://api/', '');\n content = await getApiEndpointsResource(config, endpoint);\n } else if (uri.startsWith('smartstack://schema/')) {\n const table = uri.replace('smartstack://schema/', '');\n content = await getDbSchemaResource(config, table);\n } else {\n throw new Error(`Unknown resource: ${uri}`);\n }\n\n return {\n contents: [\n {\n uri,\n mimeType,\n text: content,\n },\n ],\n };\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error('Resource read failed', { uri, error: err.message });\n throw err;\n }\n });\n\n return server;\n}\n\nexport async function runServer(): Promise<void> {\n logger.info('Starting SmartStack MCP Server...');\n\n const server = await createServer();\n const transport = new StdioServerTransport();\n\n await server.connect(transport);\n\n logger.info('SmartStack MCP Server running on stdio');\n}\n","/**\n * Logger for MCP Server\n * IMPORTANT: All output goes to stderr to avoid corrupting stdio MCP transport\n */\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\ninterface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n data?: unknown;\n}\n\nclass Logger {\n private level: LogLevel = 'info';\n private readonly levels: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n };\n\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n private shouldLog(level: LogLevel): boolean {\n return this.levels[level] >= this.levels[this.level];\n }\n\n private formatEntry(level: LogLevel, message: string, data?: unknown): string {\n const entry: LogEntry = {\n timestamp: new Date().toISOString(),\n level,\n message,\n ...(data !== undefined && { data }),\n };\n return JSON.stringify(entry);\n }\n\n debug(message: string, data?: unknown): void {\n if (this.shouldLog('debug')) {\n console.error(this.formatEntry('debug', message, data));\n }\n }\n\n info(message: string, data?: unknown): void {\n if (this.shouldLog('info')) {\n console.error(this.formatEntry('info', message, data));\n }\n }\n\n warn(message: string, data?: unknown): void {\n if (this.shouldLog('warn')) {\n console.error(this.formatEntry('warn', message, data));\n }\n }\n\n error(message: string, data?: unknown): void {\n if (this.shouldLog('error')) {\n console.error(this.formatEntry('error', message, data));\n }\n }\n\n // Tool execution logging\n toolStart(toolName: string, args: unknown): void {\n this.info(`Tool started: ${toolName}`, { args });\n }\n\n toolEnd(toolName: string, success: boolean, duration?: number): void {\n this.info(`Tool completed: ${toolName}`, { success, duration });\n }\n\n toolError(toolName: string, error: Error): void {\n this.error(`Tool failed: ${toolName}`, {\n error: error.message,\n stack: error.stack\n });\n }\n}\n\nexport const logger = new Logger();\n\n// Set log level from environment\nconst envLevel = process.env.LOG_LEVEL as LogLevel | undefined;\nif (envLevel && ['debug', 'info', 'warn', 'error'].includes(envLevel)) {\n logger.setLevel(envLevel);\n}\n","import path from 'path';\r\nimport { fileExists, readJson } from './utils/fs.js';\r\nimport { logger } from './lib/logger.js';\r\nimport type { Config } from './types/index.js';\r\n\r\n// Default configuration\r\nconst defaultConfig: Config = {\r\n version: '1.0.0',\r\n smartstack: {\r\n projectPath: process.env.SMARTSTACK_PROJECT_PATH || 'D:/SmartStack.app/02-Develop',\r\n apiUrl: process.env.SMARTSTACK_API_URL || 'https://localhost:5001',\r\n apiEnabled: process.env.SMARTSTACK_API_ENABLED !== 'false',\r\n },\r\n conventions: {\r\n schemas: {\r\n platform: 'core',\r\n extensions: 'extensions',\r\n },\r\n tablePrefixes: [\r\n 'auth_', 'nav_', 'usr_', 'ai_', 'cfg_', 'wkf_',\r\n 'support_', 'entra_', 'ref_', 'loc_', 'lic_'\r\n ],\r\n migrationFormat: 'YYYYMMDD_NNN_{Description}',\r\n namespaces: {\r\n domain: 'SmartStack.Domain',\r\n application: 'SmartStack.Application',\r\n infrastructure: 'SmartStack.Infrastructure',\r\n api: 'SmartStack.Api',\r\n },\r\n servicePattern: {\r\n interface: 'I{Name}Service',\r\n implementation: '{Name}Service',\r\n },\r\n },\r\n efcore: {\r\n contexts: [\r\n {\r\n name: 'ApplicationDbContext',\r\n projectPath: 'auto-detect',\r\n migrationsFolder: 'Migrations',\r\n },\r\n ],\r\n validation: {\r\n checkModelSnapshot: true,\r\n checkMigrationOrder: true,\r\n requireBuildSuccess: true,\r\n },\r\n },\r\n scaffolding: {\r\n outputPath: 'auto-detect',\r\n templates: {\r\n service: 'templates/service-extension.cs.hbs',\r\n entity: 'templates/entity-extension.cs.hbs',\r\n controller: 'templates/controller.cs.hbs',\r\n component: 'templates/component.tsx.hbs',\r\n },\r\n },\r\n};\r\n\r\nlet cachedConfig: Config | null = null;\r\n\r\n/**\r\n * Get the configuration, loading from file if available\r\n */\r\nexport async function getConfig(): Promise<Config> {\r\n if (cachedConfig) {\r\n return cachedConfig;\r\n }\r\n\r\n // Try to load from config file\r\n const configPath = path.join(process.cwd(), 'config', 'default-config.json');\r\n\r\n if (await fileExists(configPath)) {\r\n try {\r\n const fileConfig = await readJson<Partial<Config>>(configPath);\r\n cachedConfig = mergeConfig(defaultConfig, fileConfig);\r\n logger.info('Configuration loaded from file', { path: configPath });\r\n } catch (error) {\r\n logger.warn('Failed to load config file, using defaults', { error });\r\n cachedConfig = defaultConfig;\r\n }\r\n } else {\r\n logger.debug('No config file found, using defaults');\r\n cachedConfig = defaultConfig;\r\n }\r\n\r\n // Override with environment variables\r\n if (process.env.SMARTSTACK_PROJECT_PATH) {\r\n cachedConfig.smartstack.projectPath = process.env.SMARTSTACK_PROJECT_PATH;\r\n }\r\n if (process.env.SMARTSTACK_API_URL) {\r\n cachedConfig.smartstack.apiUrl = process.env.SMARTSTACK_API_URL;\r\n }\r\n\r\n return cachedConfig;\r\n}\r\n\r\n/**\r\n * Deep merge configuration objects\r\n */\r\nfunction mergeConfig(base: Config, override: Partial<Config>): Config {\r\n return {\r\n ...base,\r\n ...override,\r\n smartstack: {\r\n ...base.smartstack,\r\n ...override.smartstack,\r\n },\r\n conventions: {\r\n ...base.conventions,\r\n ...override.conventions,\r\n schemas: {\r\n ...base.conventions.schemas,\r\n ...override.conventions?.schemas,\r\n },\r\n namespaces: {\r\n ...base.conventions.namespaces,\r\n ...override.conventions?.namespaces,\r\n },\r\n servicePattern: {\r\n ...base.conventions.servicePattern,\r\n ...override.conventions?.servicePattern,\r\n },\r\n },\r\n efcore: {\r\n ...base.efcore,\r\n ...override.efcore,\r\n contexts: override.efcore?.contexts || base.efcore.contexts,\r\n validation: {\r\n ...base.efcore.validation,\r\n ...override.efcore?.validation,\r\n },\r\n },\r\n scaffolding: {\r\n ...base.scaffolding,\r\n ...override.scaffolding,\r\n templates: {\r\n ...base.scaffolding.templates,\r\n ...override.scaffolding?.templates,\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Get SmartStack project path\r\n */\r\nexport function getProjectPath(config: Config): string {\r\n return config.smartstack.projectPath;\r\n}\r\n\r\n/**\r\n * Clear cached configuration (for testing)\r\n */\r\nexport function clearConfigCache(): void {\r\n cachedConfig = null;\r\n}\r\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\n\n/**\n * Check if a file exists\n */\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(filePath);\n return stat.isFile();\n } catch {\n return false;\n }\n}\n\n/**\n * Check if a directory exists\n */\nexport async function directoryExists(dirPath: string): Promise<boolean> {\n try {\n const stat = await fs.stat(dirPath);\n return stat.isDirectory();\n } catch {\n return false;\n }\n}\n\n/**\n * Ensure a directory exists (create if needed)\n */\nexport async function ensureDirectory(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\n/**\n * Read a JSON file with type safety\n */\nexport async function readJson<T>(filePath: string): Promise<T> {\n const content = await fs.readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n}\n\n/**\n * Write a JSON file\n */\nexport async function writeJson<T>(filePath: string, data: T): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n/**\n * Read a text file\n */\nexport async function readText(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Write a text file\n */\nexport async function writeText(filePath: string, content: string): Promise<void> {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n}\n\n/**\n * Copy a file\n */\nexport async function copyFile(src: string, dest: string): Promise<void> {\n await fs.ensureDir(path.dirname(dest));\n await fs.copy(src, dest);\n}\n\n/**\n * Remove a file\n */\nexport async function removeFile(filePath: string): Promise<void> {\n await fs.remove(filePath);\n}\n\n/**\n * Remove a directory\n */\nexport async function removeDirectory(dirPath: string): Promise<void> {\n await fs.remove(dirPath);\n}\n\n/**\n * Find files matching a glob pattern\n */\nexport async function findFiles(\n pattern: string,\n options: { cwd?: string; ignore?: string[] } = {}\n): Promise<string[]> {\n const { cwd = process.cwd(), ignore = [] } = options;\n\n const files = await glob(pattern, {\n cwd,\n ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', ...ignore],\n absolute: true,\n nodir: true,\n });\n\n return files;\n}\n\n/**\n * Find directories matching a glob pattern\n */\nexport async function findDirectories(\n pattern: string,\n options: { cwd?: string; ignore?: string[] } = {}\n): Promise<string[]> {\n const { cwd = process.cwd(), ignore = [] } = options;\n\n const dirs = await glob(pattern, {\n cwd,\n ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', ...ignore],\n absolute: true,\n });\n\n // Filter to only directories\n const results: string[] = [];\n for (const dir of dirs) {\n if (await directoryExists(dir)) {\n results.push(dir);\n }\n }\n\n return results;\n}\n\n/**\n * Get relative path from base\n */\nexport function relativePath(from: string, to: string): string {\n return path.relative(from, to).replace(/\\\\/g, '/');\n}\n\n/**\n * Normalize path separators\n */\nexport function normalizePath(filePath: string): string {\n return filePath.replace(/\\\\/g, '/');\n}\n","import { z } from 'zod';\n\n// ============================================================================\n// Configuration Schemas\n// ============================================================================\n\nexport const SmartStackConfigSchema = z.object({\n projectPath: z.string(),\n apiUrl: z.string().url().optional(),\n apiEnabled: z.boolean().default(true),\n});\n\nexport const ConventionsConfigSchema = z.object({\n schemas: z.object({\n platform: z.string().default('core'),\n extensions: z.string().default('extensions'),\n }),\n tablePrefixes: z.array(z.string()).default([\n 'auth_', 'nav_', 'usr_', 'ai_', 'cfg_', 'wkf_',\n 'support_', 'entra_', 'ref_', 'loc_', 'lic_'\n ]),\n migrationFormat: z.string().default('YYYYMMDD_NNN_{Description}'),\n namespaces: z.object({\n domain: z.string(),\n application: z.string(),\n infrastructure: z.string(),\n api: z.string(),\n }),\n servicePattern: z.object({\n interface: z.string().default('I{Name}Service'),\n implementation: z.string().default('{Name}Service'),\n }),\n});\n\nexport const EfCoreContextSchema = z.object({\n name: z.string(),\n projectPath: z.string(),\n migrationsFolder: z.string().default('Migrations'),\n});\n\nexport const EfCoreConfigSchema = z.object({\n contexts: z.array(EfCoreContextSchema),\n validation: z.object({\n checkModelSnapshot: z.boolean().default(true),\n checkMigrationOrder: z.boolean().default(true),\n requireBuildSuccess: z.boolean().default(true),\n }),\n});\n\nexport const ScaffoldingConfigSchema = z.object({\n outputPath: z.string(),\n templates: z.object({\n service: z.string(),\n entity: z.string(),\n controller: z.string(),\n component: z.string(),\n }),\n});\n\nexport const ConfigSchema = z.object({\n version: z.string(),\n smartstack: SmartStackConfigSchema,\n conventions: ConventionsConfigSchema,\n efcore: EfCoreConfigSchema,\n scaffolding: ScaffoldingConfigSchema,\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\nexport type SmartStackConfig = z.infer<typeof SmartStackConfigSchema>;\nexport type ConventionsConfig = z.infer<typeof ConventionsConfigSchema>;\nexport type EfCoreConfig = z.infer<typeof EfCoreConfigSchema>;\n\n// ============================================================================\n// Tool Input Schemas\n// ============================================================================\n\nexport const ValidateConventionsInputSchema = z.object({\n path: z.string().optional().describe('Project path to validate (default: SmartStack.app path)'),\n checks: z.array(z.enum(['tables', 'migrations', 'services', 'namespaces', 'all']))\n .default(['all'])\n .describe('Types of checks to perform'),\n});\n\nexport const CheckMigrationsInputSchema = z.object({\n projectPath: z.string().optional().describe('EF Core project path'),\n branch: z.string().optional().describe('Git branch to check (default: current)'),\n compareBranch: z.string().optional().describe('Branch to compare against'),\n});\n\nexport const ScaffoldExtensionInputSchema = z.object({\n type: z.enum(['service', 'entity', 'controller', 'component'])\n .describe('Type of extension to scaffold'),\n name: z.string().describe('Name of the extension (e.g., \"UserProfile\", \"Order\")'),\n options: z.object({\n namespace: z.string().optional().describe('Custom namespace'),\n baseEntity: z.string().optional().describe('Base entity to extend (for entity type)'),\n methods: z.array(z.string()).optional().describe('Methods to generate (for service type)'),\n outputPath: z.string().optional().describe('Custom output path'),\n }).optional(),\n});\n\nexport const ApiDocsInputSchema = z.object({\n endpoint: z.string().optional().describe('Filter by endpoint path (e.g., \"/api/users\")'),\n format: z.enum(['markdown', 'json', 'openapi']).default('markdown')\n .describe('Output format'),\n controller: z.string().optional().describe('Filter by controller name'),\n});\n\nexport type ValidateConventionsInput = z.infer<typeof ValidateConventionsInputSchema>;\nexport type CheckMigrationsInput = z.infer<typeof CheckMigrationsInputSchema>;\nexport type ScaffoldExtensionInput = z.infer<typeof ScaffoldExtensionInputSchema>;\nexport type ApiDocsInput = z.infer<typeof ApiDocsInputSchema>;\n\n// ============================================================================\n// Result Types\n// ============================================================================\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationIssue[];\n warnings: ValidationIssue[];\n summary: string;\n}\n\nexport interface ValidationIssue {\n type: 'error' | 'warning';\n category: string;\n message: string;\n file?: string;\n line?: number;\n suggestion?: string;\n}\n\nexport interface MigrationCheckResult {\n hasConflicts: boolean;\n migrations: MigrationInfo[];\n conflicts: MigrationConflict[];\n suggestions: string[];\n}\n\nexport interface MigrationInfo {\n name: string;\n timestamp: string;\n prefix: string;\n description: string;\n file: string;\n applied: boolean;\n}\n\nexport interface MigrationConflict {\n type: 'order' | 'snapshot' | 'dependency' | 'naming';\n description: string;\n files: string[];\n resolution: string;\n}\n\nexport interface ScaffoldResult {\n success: boolean;\n files: GeneratedFile[];\n instructions: string[];\n}\n\nexport interface GeneratedFile {\n path: string;\n content: string;\n type: 'created' | 'modified';\n}\n\nexport interface ProjectInfo {\n name: string;\n version: string;\n isGitRepo: boolean;\n currentBranch?: string;\n hasDotNet: boolean;\n hasEfCore: boolean;\n hasReact: boolean;\n csprojFiles: string[];\n dbContextName?: string;\n}\n","import path from 'path';\nimport { directoryExists, fileExists, findFiles, readText } from '../utils/fs.js';\nimport { isGitRepo, getCurrentBranch } from '../utils/git.js';\nimport { findCsprojFiles, hasEfCore, findDbContextName, getTargetFramework } from '../utils/dotnet.js';\nimport { logger } from './logger.js';\nimport type { ProjectInfo } from '../types/index.js';\n\n/**\n * Detect project information for SmartStack\n */\nexport async function detectProject(projectPath: string): Promise<ProjectInfo> {\n logger.debug('Detecting project info', { path: projectPath });\n\n const info: ProjectInfo = {\n name: path.basename(projectPath),\n version: '0.0.0',\n isGitRepo: false,\n hasDotNet: false,\n hasEfCore: false,\n hasReact: false,\n csprojFiles: [],\n };\n\n // Check if directory exists\n if (!(await directoryExists(projectPath))) {\n logger.warn('Project path does not exist', { path: projectPath });\n return info;\n }\n\n // Git detection\n info.isGitRepo = await isGitRepo(projectPath);\n if (info.isGitRepo) {\n info.currentBranch = await getCurrentBranch(projectPath) || undefined;\n }\n\n // .NET detection\n info.csprojFiles = await findCsprojFiles(projectPath);\n info.hasDotNet = info.csprojFiles.length > 0;\n\n // EF Core detection\n if (info.hasDotNet) {\n for (const csproj of info.csprojFiles) {\n if (await hasEfCore(csproj)) {\n info.hasEfCore = true;\n info.dbContextName = await findDbContextName(path.dirname(csproj)) || undefined;\n break;\n }\n }\n }\n\n // React detection\n const packageJsonPath = path.join(projectPath, 'web', 'smartstack-web', 'package.json');\n if (await fileExists(packageJsonPath)) {\n try {\n const packageJson = JSON.parse(await readText(packageJsonPath));\n info.hasReact = !!packageJson.dependencies?.react;\n info.version = packageJson.version || info.version;\n } catch {\n // Ignore parse errors\n }\n }\n\n // Try to get version from main csproj\n if (info.csprojFiles.length > 0) {\n const mainCsproj = info.csprojFiles.find(f => f.includes('SmartStack.Api'))\n || info.csprojFiles[0];\n const targetFramework = await getTargetFramework(mainCsproj);\n if (targetFramework) {\n logger.debug('Target framework detected', { framework: targetFramework });\n }\n }\n\n logger.info('Project detected', info);\n return info;\n}\n\n/**\n * Find SmartStack project structure\n */\nexport interface SmartStackStructure {\n root: string;\n domain?: string;\n application?: string;\n infrastructure?: string;\n api?: string;\n web?: string;\n migrations?: string;\n}\n\nexport async function findSmartStackStructure(projectPath: string): Promise<SmartStackStructure> {\n const structure: SmartStackStructure = { root: projectPath };\n\n const csprojFiles = await findCsprojFiles(projectPath);\n\n for (const csproj of csprojFiles) {\n const projectName = path.basename(csproj, '.csproj').toLowerCase();\n const projectDir = path.dirname(csproj);\n\n if (projectName.includes('domain')) {\n structure.domain = projectDir;\n } else if (projectName.includes('application')) {\n structure.application = projectDir;\n } else if (projectName.includes('infrastructure')) {\n structure.infrastructure = projectDir;\n } else if (projectName.includes('api')) {\n structure.api = projectDir;\n }\n }\n\n // Find migrations folder\n if (structure.infrastructure) {\n const migrationsPath = path.join(structure.infrastructure, 'Persistence', 'Migrations');\n if (await directoryExists(migrationsPath)) {\n structure.migrations = migrationsPath;\n }\n }\n\n // Find web folder\n const webPath = path.join(projectPath, 'web', 'smartstack-web');\n if (await directoryExists(webPath)) {\n structure.web = webPath;\n }\n\n return structure;\n}\n\n/**\n * Find all entity files in domain layer\n */\nexport async function findEntityFiles(domainPath: string): Promise<string[]> {\n const entityFiles = await findFiles('**/*.cs', { cwd: domainPath });\n\n // Filter to likely entity files (classes with Id property)\n const entities: string[] = [];\n\n for (const file of entityFiles) {\n const content = await readText(file);\n // Simple heuristic: file contains a class with Id property\n if (content.match(/public\\s+(?:class|record)\\s+\\w+/) &&\n content.match(/public\\s+(?:int|long|Guid|string)\\s+Id\\s*\\{/)) {\n entities.push(file);\n }\n }\n\n return entities;\n}\n\n/**\n * Find all service interfaces in application layer\n */\nexport async function findServiceInterfaces(applicationPath: string): Promise<string[]> {\n const files = await findFiles('**/I*Service.cs', { cwd: applicationPath });\n return files;\n}\n\n/**\n * Find all controller files in API layer\n */\nexport async function findControllerFiles(apiPath: string): Promise<string[]> {\n const files = await findFiles('**/*Controller.cs', { cwd: apiPath });\n return files;\n}\n","import { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { directoryExists } from './fs.js';\r\nimport path from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n/**\r\n * Execute a git command\r\n */\r\nexport async function git(command: string, cwd?: string): Promise<string> {\r\n const options = cwd ? { cwd } : {};\r\n const { stdout } = await execAsync(`git ${command}`, options);\r\n return stdout.trim();\r\n}\r\n\r\n/**\r\n * Check if directory is a git repository\r\n */\r\nexport async function isGitRepo(cwd?: string): Promise<boolean> {\r\n const gitDir = path.join(cwd || process.cwd(), '.git');\r\n return directoryExists(gitDir);\r\n}\r\n\r\n/**\r\n * Get current branch name\r\n */\r\nexport async function getCurrentBranch(cwd?: string): Promise<string | null> {\r\n try {\r\n return await git('branch --show-current', cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if working directory is clean\r\n */\r\nexport async function isClean(cwd?: string): Promise<boolean> {\r\n try {\r\n const status = await git('status --porcelain', cwd);\r\n return status === '';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get list of changed files\r\n */\r\nexport async function getChangedFiles(cwd?: string): Promise<string[]> {\r\n try {\r\n const status = await git('status --porcelain', cwd);\r\n if (!status) return [];\r\n\r\n return status.split('\\n')\r\n .map(line => line.substring(3).trim())\r\n .filter(Boolean);\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get commit count between two refs\r\n */\r\nexport async function getCommitCount(\r\n from: string,\r\n to: string,\r\n cwd?: string\r\n): Promise<number> {\r\n try {\r\n const result = await git(`rev-list --count ${from}..${to}`, cwd);\r\n return parseInt(result, 10);\r\n } catch {\r\n return 0;\r\n }\r\n}\r\n\r\n/**\r\n * Get latest tag\r\n */\r\nexport async function getLatestTag(cwd?: string): Promise<string | null> {\r\n try {\r\n return await git('describe --tags --abbrev=0', cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if branch exists\r\n */\r\nexport async function branchExists(branch: string, cwd?: string): Promise<boolean> {\r\n try {\r\n await git(`rev-parse --verify ${branch}`, cwd);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get list of all branches\r\n */\r\nexport async function getBranches(cwd?: string): Promise<string[]> {\r\n try {\r\n const result = await git('branch -a', cwd);\r\n return result.split('\\n')\r\n .map(line => line.replace(/^\\*?\\s+/, '').trim())\r\n .filter(Boolean);\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get file content from a specific branch\r\n */\r\nexport async function getFileFromBranch(\r\n branch: string,\r\n filePath: string,\r\n cwd?: string\r\n): Promise<string | null> {\r\n try {\r\n return await git(`show ${branch}:${filePath}`, cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get diff between branches for a specific file\r\n */\r\nexport async function getDiff(\r\n fromBranch: string,\r\n toBranch: string,\r\n filePath?: string,\r\n cwd?: string\r\n): Promise<string> {\r\n try {\r\n const pathArg = filePath ? ` -- ${filePath}` : '';\r\n return await git(`diff ${fromBranch}...${toBranch}${pathArg}`, cwd);\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Get remote URL\r\n */\r\nexport async function getRemoteUrl(remote: string = 'origin', cwd?: string): Promise<string | null> {\r\n try {\r\n return await git(`remote get-url ${remote}`, cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n","import { exec } from 'child_process';\nimport { promisify } from 'util';\nimport { findFiles, readText } from './fs.js';\nimport path from 'path';\n\nconst execAsync = promisify(exec);\n\n/**\n * Execute a dotnet command\n */\nexport async function dotnet(command: string, cwd?: string): Promise<string> {\n const options = cwd ? { cwd } : {};\n const { stdout } = await execAsync(`dotnet ${command}`, options);\n return stdout.trim();\n}\n\n/**\n * Check if dotnet CLI is available\n */\nexport async function isDotnetAvailable(): Promise<boolean> {\n try {\n await execAsync('dotnet --version');\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get dotnet version\n */\nexport async function getDotnetVersion(): Promise<string | null> {\n try {\n return await dotnet('--version');\n } catch {\n return null;\n }\n}\n\n/**\n * Find all .csproj files in a directory\n */\nexport async function findCsprojFiles(cwd?: string): Promise<string[]> {\n return findFiles('**/*.csproj', { cwd: cwd || process.cwd() });\n}\n\n/**\n * Check if a project has EF Core\n */\nexport async function hasEfCore(csprojPath: string): Promise<boolean> {\n try {\n const content = await readText(csprojPath);\n return content.includes('Microsoft.EntityFrameworkCore');\n } catch {\n return false;\n }\n}\n\n/**\n * Extract DbContext name from csproj or code files\n */\nexport async function findDbContextName(projectPath: string): Promise<string | null> {\n try {\n // Search for DbContext class definitions\n const csFiles = await findFiles('**/*.cs', { cwd: projectPath });\n\n for (const file of csFiles) {\n const content = await readText(file);\n // Look for class that extends DbContext\n const match = content.match(/class\\s+(\\w+)\\s*:\\s*(?:\\w+,\\s*)*DbContext/);\n if (match) {\n return match[1];\n }\n }\n\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * List EF Core migrations\n */\nexport async function listMigrations(\n projectPath: string,\n context?: string\n): Promise<string[]> {\n try {\n const contextArg = context ? `--context ${context}` : '';\n const result = await dotnet(`ef migrations list ${contextArg}`, projectPath);\n\n return result.split('\\n')\n .filter(line => line && !line.startsWith('Build') && !line.includes('...'))\n .map(line => line.trim());\n } catch {\n return [];\n }\n}\n\n/**\n * Get pending migrations (not applied to database)\n */\nexport async function getPendingMigrations(\n projectPath: string,\n context?: string\n): Promise<string[]> {\n try {\n const contextArg = context ? `--context ${context}` : '';\n const result = await dotnet(`ef migrations list ${contextArg} --pending`, projectPath);\n\n return result.split('\\n')\n .filter(line => line && !line.startsWith('Build') && !line.includes('...'))\n .map(line => line.trim());\n } catch {\n return [];\n }\n}\n\n/**\n * Build a .NET project\n */\nexport async function buildProject(projectPath: string): Promise<{ success: boolean; output: string }> {\n try {\n const output = await dotnet('build --no-restore', projectPath);\n return { success: true, output };\n } catch (error) {\n const err = error as { stdout?: string; stderr?: string };\n return {\n success: false,\n output: err.stdout || err.stderr || 'Build failed'\n };\n }\n}\n\n/**\n * Parse csproj XML to extract package references\n */\nexport async function getPackageReferences(csprojPath: string): Promise<Array<{ name: string; version: string }>> {\n try {\n const content = await readText(csprojPath);\n const packages: Array<{ name: string; version: string }> = [];\n\n const regex = /<PackageReference\\s+Include=\"([^\"]+)\"\\s+Version=\"([^\"]+)\"/g;\n let match;\n\n while ((match = regex.exec(content)) !== null) {\n packages.push({\n name: match[1],\n version: match[2],\n });\n }\n\n return packages;\n } catch {\n return [];\n }\n}\n\n/**\n * Get target framework from csproj\n */\nexport async function getTargetFramework(csprojPath: string): Promise<string | null> {\n try {\n const content = await readText(csprojPath);\n const match = content.match(/<TargetFramework>([^<]+)<\\/TargetFramework>/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get project name from csproj path\n */\nexport function getProjectName(csprojPath: string): string {\n return path.basename(csprojPath, '.csproj');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport { ValidateConventionsInputSchema, type Config, type ValidationResult } from '../types/index.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const validateConventionsTool: Tool = {\r\n name: 'validate_conventions',\r\n description: 'Validate AtlasHub/SmartStack conventions: SQL schemas (core/extensions), domain table prefixes (auth_, nav_, ai_, etc.), migration naming (YYYYMMDD_NNN_*), service interfaces (I*Service), namespace structure',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n path: {\r\n type: 'string',\r\n description: 'Project path to validate (default: SmartStack.app path from config)',\r\n },\r\n checks: {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n enum: ['tables', 'migrations', 'services', 'namespaces', 'all'],\r\n },\r\n description: 'Types of checks to perform',\r\n default: ['all'],\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport async function handleValidateConventions(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ValidateConventionsInputSchema.parse(args);\r\n const projectPath = input.path || config.smartstack.projectPath;\r\n const checks = input.checks.includes('all')\r\n ? ['tables', 'migrations', 'services', 'namespaces']\r\n : input.checks;\r\n\r\n logger.info('Validating conventions', { projectPath, checks });\r\n\r\n const result: ValidationResult = {\r\n valid: true,\r\n errors: [],\r\n warnings: [],\r\n summary: '',\r\n };\r\n\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n // Run selected checks\r\n if (checks.includes('tables')) {\r\n await validateTablePrefixes(structure, config, result);\r\n }\r\n\r\n if (checks.includes('migrations')) {\r\n await validateMigrationNaming(structure, config, result);\r\n }\r\n\r\n if (checks.includes('services')) {\r\n await validateServiceInterfaces(structure, config, result);\r\n }\r\n\r\n if (checks.includes('namespaces')) {\r\n await validateNamespaces(structure, config, result);\r\n }\r\n\r\n // Update validity\r\n result.valid = result.errors.length === 0;\r\n\r\n // Generate summary\r\n result.summary = generateSummary(result, checks);\r\n\r\n return formatResult(result);\r\n}\r\n\r\nasync function validateTablePrefixes(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.infrastructure) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: 'Infrastructure project not found, skipping table validation',\r\n });\r\n return;\r\n }\r\n\r\n // Find EF Core configuration files\r\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\r\n cwd: structure.infrastructure,\r\n });\r\n\r\n const validSchemas = [config.conventions.schemas.platform, config.conventions.schemas.extensions];\r\n const validPrefixes = config.conventions.tablePrefixes;\r\n\r\n // Map SchemaConstants to actual values\r\n const schemaConstantsMap: Record<string, string> = {\r\n 'SchemaConstants.Core': config.conventions.schemas.platform,\r\n 'SchemaConstants.Extensions': config.conventions.schemas.extensions,\r\n };\r\n\r\n for (const file of configFiles) {\r\n const content = await readText(file);\r\n\r\n // Match ToTable with string schema: .ToTable(\"tableName\", \"schemaName\")\r\n const tableWithStringSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*\"([^\"]+)\"\\s*\\)/g);\r\n\r\n for (const match of tableWithStringSchemaMatches) {\r\n const tableName = match[1];\r\n const schemaName = match[2];\r\n\r\n // Validate schema\r\n if (!validSchemas.includes(schemaName)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" uses invalid schema \"${schemaName}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Use schema \"${config.conventions.schemas.platform}\" for SmartStack tables or \"${config.conventions.schemas.extensions}\" for client extensions`,\r\n });\r\n }\r\n\r\n // Validate table prefix (must have a domain prefix)\r\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\r\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\r\n });\r\n }\r\n }\r\n\r\n // Match ToTable with SchemaConstants: .ToTable(\"tableName\", SchemaConstants.Core)\r\n const tableWithConstantSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(SchemaConstants\\.\\w+)\\s*\\)/g);\r\n\r\n for (const match of tableWithConstantSchemaMatches) {\r\n const tableName = match[1];\r\n const schemaConstant = match[2];\r\n const resolvedSchema = schemaConstantsMap[schemaConstant];\r\n\r\n // Validate schema constant is known\r\n if (!resolvedSchema) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" uses unknown schema constant \"${schemaConstant}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Use SchemaConstants.Core for SmartStack tables or SchemaConstants.Extensions for client extensions`,\r\n });\r\n }\r\n\r\n // Validate table prefix (must have a domain prefix)\r\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\r\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\r\n });\r\n }\r\n }\r\n\r\n // Check for ToTable without schema (old format) - but exclude lines with SchemaConstants\r\n const tableWithoutSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*\\)(?!\\s*,)/g);\r\n\r\n for (const match of tableWithoutSchemaMatches) {\r\n const tableName = match[1];\r\n if (!tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" is missing schema specification`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Add schema: .ToTable(\"${tableName}\", SchemaConstants.Core)`,\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function validateMigrationNaming(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n _config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.migrations) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'migrations',\r\n message: 'Migrations folder not found, skipping migration validation',\r\n });\r\n return;\r\n }\r\n\r\n const migrationFiles = await findFiles('*.cs', { cwd: structure.migrations });\r\n\r\n // Expected format: YYYYMMDD_NNN_Description.cs (without Core/Client prefix)\r\n const migrationPattern = /^(\\d{8})_(\\d{3})_(.+)\\.cs$/;\r\n const designerPattern = /\\.Designer\\.cs$/;\r\n\r\n for (const file of migrationFiles) {\r\n const fileName = path.basename(file);\r\n\r\n // Skip designer files and snapshot\r\n if (designerPattern.test(fileName) || fileName.includes('ModelSnapshot')) {\r\n continue;\r\n }\r\n\r\n if (!migrationPattern.test(fileName)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'migrations',\r\n message: `Migration \"${fileName}\" does not follow naming convention`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Expected format: YYYYMMDD_NNN_Description.cs (e.g., 20260115_001_InitialCreate.cs)`,\r\n });\r\n }\r\n }\r\n\r\n // Check chronological order\r\n const orderedMigrations = migrationFiles\r\n .map(f => path.basename(f))\r\n .filter(f => migrationPattern.test(f) && !f.includes('Designer'))\r\n .sort();\r\n\r\n for (let i = 1; i < orderedMigrations.length; i++) {\r\n const prev = orderedMigrations[i - 1];\r\n const curr = orderedMigrations[i];\r\n\r\n const prevDate = prev.substring(0, 8);\r\n const currDate = curr.substring(0, 8);\r\n\r\n if (currDate < prevDate) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'migrations',\r\n message: `Migration order issue: \"${curr}\" dated before \"${prev}\"`,\r\n });\r\n }\r\n }\r\n}\r\n\r\nasync function validateServiceInterfaces(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n _config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.application) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'services',\r\n message: 'Application project not found, skipping service validation',\r\n });\r\n return;\r\n }\r\n\r\n // Find service implementations\r\n const serviceFiles = await findFiles('**/*Service.cs', {\r\n cwd: structure.application,\r\n });\r\n\r\n for (const file of serviceFiles) {\r\n const content = await readText(file);\r\n const fileName = path.basename(file, '.cs');\r\n\r\n // Skip interfaces\r\n if (fileName.startsWith('I')) continue;\r\n\r\n // Check if there's a matching interface\r\n const expectedInterface = `I${fileName}`;\r\n const interfacePattern = new RegExp(`:\\\\s*${expectedInterface}\\\\b`);\r\n\r\n if (!interfacePattern.test(content)) {\r\n // Check if file declares interface\r\n const declaresInterface = content.includes(`interface ${expectedInterface}`);\r\n\r\n if (!declaresInterface) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'services',\r\n message: `Service \"${fileName}\" should implement \"${expectedInterface}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Create interface ${expectedInterface} and implement it`,\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function validateNamespaces(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n const layers = [\r\n { path: structure.domain, expected: config.conventions.namespaces.domain, name: 'Domain' },\r\n { path: structure.application, expected: config.conventions.namespaces.application, name: 'Application' },\r\n { path: structure.infrastructure, expected: config.conventions.namespaces.infrastructure, name: 'Infrastructure' },\r\n { path: structure.api, expected: config.conventions.namespaces.api, name: 'Api' },\r\n ];\r\n\r\n for (const layer of layers) {\r\n if (!layer.path) continue;\r\n\r\n const csFiles = await findFiles('**/*.cs', { cwd: layer.path });\r\n\r\n for (const file of csFiles.slice(0, 10)) { // Sample first 10 files\r\n const content = await readText(file);\r\n const namespaceMatch = content.match(/namespace\\s+([\\w.]+)/);\r\n\r\n if (namespaceMatch) {\r\n const namespace = namespaceMatch[1];\r\n\r\n if (!namespace.startsWith(layer.expected)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'namespaces',\r\n message: `${layer.name} file has incorrect namespace \"${namespace}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Should start with \"${layer.expected}\"`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction generateSummary(result: ValidationResult, checks: string[]): string {\r\n const parts: string[] = [];\r\n\r\n parts.push(`Checks performed: ${checks.join(', ')}`);\r\n parts.push(`Errors: ${result.errors.length}`);\r\n parts.push(`Warnings: ${result.warnings.length}`);\r\n parts.push(`Status: ${result.valid ? 'PASSED' : 'FAILED'}`);\r\n\r\n return parts.join(' | ');\r\n}\r\n\r\nfunction formatResult(result: ValidationResult): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# Conventions Validation Report');\r\n lines.push('');\r\n lines.push(`## Summary`);\r\n lines.push(`- **Status**: ${result.valid ? '✅ PASSED' : '❌ FAILED'}`);\r\n lines.push(`- **Errors**: ${result.errors.length}`);\r\n lines.push(`- **Warnings**: ${result.warnings.length}`);\r\n lines.push('');\r\n\r\n if (result.errors.length > 0) {\r\n lines.push('## Errors');\r\n lines.push('');\r\n for (const error of result.errors) {\r\n lines.push(`### ❌ ${error.category}: ${error.message}`);\r\n if (error.file) lines.push(`- **File**: \\`${error.file}\\``);\r\n if (error.line) lines.push(`- **Line**: ${error.line}`);\r\n if (error.suggestion) lines.push(`- **Suggestion**: ${error.suggestion}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n if (result.warnings.length > 0) {\r\n lines.push('## Warnings');\r\n lines.push('');\r\n for (const warning of result.warnings) {\r\n lines.push(`### ⚠️ ${warning.category}: ${warning.message}`);\r\n if (warning.file) lines.push(`- **File**: \\`${warning.file}\\``);\r\n if (warning.suggestion) lines.push(`- **Suggestion**: ${warning.suggestion}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n if (result.errors.length === 0 && result.warnings.length === 0) {\r\n lines.push('## Result');\r\n lines.push('');\r\n lines.push('All conventions validated successfully! ✨');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport {\r\n CheckMigrationsInputSchema,\r\n type Config,\r\n type MigrationCheckResult,\r\n type MigrationInfo,\r\n} from '../types/index.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport { getCurrentBranch, branchExists, getFileFromBranch, getDiff } from '../utils/git.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const checkMigrationsTool: Tool = {\r\n name: 'check_migrations',\r\n description: 'Analyze EF Core migrations for conflicts, ordering issues, and ModelSnapshot discrepancies between branches',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n projectPath: {\r\n type: 'string',\r\n description: 'EF Core project path (default: auto-detect from config)',\r\n },\r\n branch: {\r\n type: 'string',\r\n description: 'Git branch to check (default: current branch)',\r\n },\r\n compareBranch: {\r\n type: 'string',\r\n description: 'Branch to compare against (e.g., \"develop\")',\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport async function handleCheckMigrations(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = CheckMigrationsInputSchema.parse(args);\r\n const projectPath = input.projectPath || config.smartstack.projectPath;\r\n\r\n logger.info('Checking migrations', { projectPath, branch: input.branch });\r\n\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n if (!structure.migrations) {\r\n return '# Migration Check\\n\\n❌ No migrations folder found in the project.';\r\n }\r\n\r\n const result: MigrationCheckResult = {\r\n hasConflicts: false,\r\n migrations: [],\r\n conflicts: [],\r\n suggestions: [],\r\n };\r\n\r\n // Get current branch\r\n const currentBranch = input.branch || await getCurrentBranch(projectPath) || 'unknown';\r\n\r\n // Parse migrations\r\n result.migrations = await parseMigrations(structure.migrations, structure.root);\r\n\r\n // Check naming conventions\r\n checkNamingConventions(result, config);\r\n\r\n // Check chronological order\r\n checkChronologicalOrder(result);\r\n\r\n // If compare branch specified, check for conflicts\r\n if (input.compareBranch && await branchExists(input.compareBranch, projectPath)) {\r\n await checkBranchConflicts(\r\n result,\r\n structure,\r\n currentBranch,\r\n input.compareBranch,\r\n projectPath\r\n );\r\n }\r\n\r\n // Check ModelSnapshot\r\n await checkModelSnapshot(result, structure);\r\n\r\n // Update conflict status\r\n result.hasConflicts = result.conflicts.length > 0;\r\n\r\n // Generate suggestions\r\n generateSuggestions(result);\r\n\r\n return formatResult(result, currentBranch, input.compareBranch);\r\n}\r\n\r\nasync function parseMigrations(\r\n migrationsPath: string,\r\n rootPath: string\r\n): Promise<MigrationInfo[]> {\r\n const files = await findFiles('*.cs', { cwd: migrationsPath });\r\n const migrations: MigrationInfo[] = [];\r\n\r\n // Pattern: YYYYMMDD_NNN_Description.cs (no Core/Client prefix - uses SQL schemas instead)\r\n const pattern = /^(\\d{8})_(\\d{3})_(.+)\\.cs$/;\r\n\r\n for (const file of files) {\r\n const fileName = path.basename(file);\r\n\r\n // Skip designer and snapshot files\r\n if (fileName.includes('.Designer.') || fileName.includes('ModelSnapshot')) {\r\n continue;\r\n }\r\n\r\n const match = pattern.exec(fileName);\r\n\r\n if (match) {\r\n migrations.push({\r\n name: fileName.replace('.cs', ''),\r\n timestamp: match[1],\r\n prefix: match[2], // Now this is the sequence number (NNN)\r\n description: match[3],\r\n file: path.relative(rootPath, file),\r\n applied: true, // We'd need DB connection to check this\r\n });\r\n } else {\r\n // Non-standard naming\r\n migrations.push({\r\n name: fileName.replace('.cs', ''),\r\n timestamp: '',\r\n prefix: 'Unknown',\r\n description: fileName.replace('.cs', ''),\r\n file: path.relative(rootPath, file),\r\n applied: true,\r\n });\r\n }\r\n }\r\n\r\n // Sort by timestamp then sequence\r\n return migrations.sort((a, b) => {\r\n const dateCompare = a.timestamp.localeCompare(b.timestamp);\r\n if (dateCompare !== 0) return dateCompare;\r\n return a.prefix.localeCompare(b.prefix);\r\n });\r\n}\r\n\r\nfunction checkNamingConventions(result: MigrationCheckResult, _config: Config): void {\r\n for (const migration of result.migrations) {\r\n if (!migration.timestamp) {\r\n result.conflicts.push({\r\n type: 'naming',\r\n description: `Migration \"${migration.name}\" does not follow naming convention`,\r\n files: [migration.file],\r\n resolution: `Rename to format: YYYYMMDD_NNN_Description (e.g., 20260115_001_InitialCreate)`,\r\n });\r\n }\r\n\r\n if (migration.prefix === 'Unknown') {\r\n result.conflicts.push({\r\n type: 'naming',\r\n description: `Migration \"${migration.name}\" missing sequence number`,\r\n files: [migration.file],\r\n resolution: `Use format: YYYYMMDD_NNN_Description where NNN is a 3-digit sequence (001, 002, etc.)`,\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction checkChronologicalOrder(result: MigrationCheckResult): void {\r\n const migrations = result.migrations.filter(m => m.timestamp);\r\n\r\n for (let i = 1; i < migrations.length; i++) {\r\n const prev = migrations[i - 1];\r\n const curr = migrations[i];\r\n\r\n // Check if timestamps are in order\r\n if (curr.timestamp < prev.timestamp) {\r\n result.conflicts.push({\r\n type: 'order',\r\n description: `Migration \"${curr.name}\" (${curr.timestamp}) is dated before \"${prev.name}\" (${prev.timestamp})`,\r\n files: [curr.file, prev.file],\r\n resolution: 'Reorder migrations or update timestamps',\r\n });\r\n }\r\n\r\n // Check for duplicate timestamps with same prefix\r\n if (curr.timestamp === prev.timestamp && curr.prefix === prev.prefix) {\r\n result.conflicts.push({\r\n type: 'order',\r\n description: `Migrations \"${curr.name}\" and \"${prev.name}\" have same timestamp`,\r\n files: [curr.file, prev.file],\r\n resolution: 'Use different sequence numbers (NNN) or different dates',\r\n });\r\n }\r\n }\r\n}\r\n\r\nasync function checkBranchConflicts(\r\n result: MigrationCheckResult,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n currentBranch: string,\r\n compareBranch: string,\r\n projectPath: string\r\n): Promise<void> {\r\n if (!structure.migrations) return;\r\n\r\n const migrationsRelPath = path.relative(projectPath, structure.migrations).replace(/\\\\/g, '/');\r\n\r\n // Get ModelSnapshot from both branches\r\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\r\n\r\n if (snapshotFiles.length > 0) {\r\n const snapshotRelPath = path.relative(projectPath, snapshotFiles[0]).replace(/\\\\/g, '/');\r\n\r\n const currentSnapshot = await readText(snapshotFiles[0]);\r\n const compareSnapshot = await getFileFromBranch(compareBranch, snapshotRelPath, projectPath);\r\n\r\n if (compareSnapshot && currentSnapshot !== compareSnapshot) {\r\n // Check if there are actual model differences\r\n const diff = await getDiff(compareBranch, currentBranch, snapshotRelPath, projectPath);\r\n\r\n if (diff) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: `ModelSnapshot differs between \"${currentBranch}\" and \"${compareBranch}\"`,\r\n files: [snapshotRelPath],\r\n resolution: 'Rebase on target branch and regenerate migrations with: dotnet ef migrations add <Name>',\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Check for migrations that exist in compare branch but not current\r\n const compareMigrations = await getFileFromBranch(\r\n compareBranch,\r\n migrationsRelPath,\r\n projectPath\r\n );\r\n\r\n if (compareMigrations) {\r\n // This would need more sophisticated parsing\r\n // For now, just note that comparison was done\r\n logger.debug('Branch comparison completed', { compareBranch });\r\n }\r\n}\r\n\r\nasync function checkModelSnapshot(\r\n result: MigrationCheckResult,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\r\n): Promise<void> {\r\n if (!structure.migrations) return;\r\n\r\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\r\n\r\n if (snapshotFiles.length === 0) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: 'No ModelSnapshot file found',\r\n files: [],\r\n resolution: 'Run: dotnet ef migrations add InitialCreate',\r\n });\r\n return;\r\n }\r\n\r\n if (snapshotFiles.length > 1) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: 'Multiple ModelSnapshot files found',\r\n files: snapshotFiles.map(f => path.relative(structure.root, f)),\r\n resolution: 'Remove duplicate snapshots, keep only one per DbContext',\r\n });\r\n }\r\n\r\n // Check if snapshot references all migrations\r\n const snapshotContent = await readText(snapshotFiles[0]);\r\n\r\n for (const migration of result.migrations) {\r\n if (migration.timestamp && !snapshotContent.includes(migration.name)) {\r\n result.conflicts.push({\r\n type: 'dependency',\r\n description: `Migration \"${migration.name}\" not referenced in ModelSnapshot`,\r\n files: [migration.file],\r\n resolution: 'Migration may not be applied. Run: dotnet ef database update',\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction generateSuggestions(result: MigrationCheckResult): void {\r\n if (result.conflicts.some(c => c.type === 'snapshot')) {\r\n result.suggestions.push(\r\n 'Consider rebasing on the target branch before merging to avoid snapshot conflicts'\r\n );\r\n }\r\n\r\n if (result.conflicts.some(c => c.type === 'naming')) {\r\n result.suggestions.push(\r\n 'Use convention: YYYYMMDD_NNN_Description for migration naming (e.g., 20260115_001_InitialCreate)'\r\n );\r\n }\r\n\r\n if (result.conflicts.some(c => c.type === 'order')) {\r\n result.suggestions.push(\r\n 'Ensure migrations are created in chronological order to avoid conflicts'\r\n );\r\n }\r\n\r\n if (result.migrations.length > 20) {\r\n result.suggestions.push(\r\n 'Consider squashing old migrations to reduce complexity. Use: /efcore squash'\r\n );\r\n }\r\n}\r\n\r\nfunction formatResult(\r\n result: MigrationCheckResult,\r\n currentBranch: string,\r\n compareBranch?: string\r\n): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# EF Core Migration Check Report');\r\n lines.push('');\r\n lines.push('## Overview');\r\n lines.push(`- **Current Branch**: ${currentBranch}`);\r\n if (compareBranch) {\r\n lines.push(`- **Compare Branch**: ${compareBranch}`);\r\n }\r\n lines.push(`- **Total Migrations**: ${result.migrations.length}`);\r\n lines.push(`- **Conflicts Found**: ${result.conflicts.length}`);\r\n lines.push(`- **Status**: ${result.hasConflicts ? '❌ CONFLICTS DETECTED' : '✅ OK'}`);\r\n lines.push('');\r\n\r\n // Migrations list\r\n lines.push('## Migrations');\r\n lines.push('');\r\n lines.push('| Name | Timestamp | Prefix | Description |');\r\n lines.push('|------|-----------|--------|-------------|');\r\n\r\n for (const migration of result.migrations) {\r\n lines.push(\r\n `| ${migration.name} | ${migration.timestamp || 'N/A'} | ${migration.prefix} | ${migration.description} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Conflicts\r\n if (result.conflicts.length > 0) {\r\n lines.push('## Conflicts');\r\n lines.push('');\r\n\r\n for (const conflict of result.conflicts) {\r\n const icon = conflict.type === 'snapshot' ? '🔄' :\r\n conflict.type === 'order' ? '📅' :\r\n conflict.type === 'naming' ? '📝' : '⚠️';\r\n\r\n lines.push(`### ${icon} ${conflict.type.toUpperCase()}: ${conflict.description}`);\r\n if (conflict.files.length > 0) {\r\n lines.push(`- **Files**: ${conflict.files.map(f => `\\`${f}\\``).join(', ')}`);\r\n }\r\n lines.push(`- **Resolution**: ${conflict.resolution}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Suggestions\r\n if (result.suggestions.length > 0) {\r\n lines.push('## Suggestions');\r\n lines.push('');\r\n for (const suggestion of result.suggestions) {\r\n lines.push(`- 💡 ${suggestion}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport Handlebars from 'handlebars';\r\nimport {\r\n ScaffoldExtensionInputSchema,\r\n type Config,\r\n type ScaffoldResult,\r\n} from '../types/index.js';\r\nimport { writeText, ensureDirectory } from '../utils/fs.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const scaffoldExtensionTool: Tool = {\r\n name: 'scaffold_extension',\r\n description: 'Generate code to extend SmartStack: service (interface + implementation), entity (class + EF config), controller (REST endpoints), or React component',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n type: {\r\n type: 'string',\r\n enum: ['service', 'entity', 'controller', 'component'],\r\n description: 'Type of extension to scaffold',\r\n },\r\n name: {\r\n type: 'string',\r\n description: 'Name of the extension (e.g., \"UserProfile\", \"Order\")',\r\n },\r\n options: {\r\n type: 'object',\r\n properties: {\r\n namespace: {\r\n type: 'string',\r\n description: 'Custom namespace (optional)',\r\n },\r\n baseEntity: {\r\n type: 'string',\r\n description: 'Base entity to extend (for entity type)',\r\n },\r\n methods: {\r\n type: 'array',\r\n items: { type: 'string' },\r\n description: 'Methods to generate (for service type)',\r\n },\r\n outputPath: {\r\n type: 'string',\r\n description: 'Custom output path',\r\n },\r\n },\r\n },\r\n },\r\n required: ['type', 'name'],\r\n },\r\n};\r\n\r\n// Register Handlebars helpers\r\nHandlebars.registerHelper('pascalCase', (str: string) => {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n});\r\n\r\nHandlebars.registerHelper('camelCase', (str: string) => {\r\n return str.charAt(0).toLowerCase() + str.slice(1);\r\n});\r\n\r\nHandlebars.registerHelper('kebabCase', (str: string) => {\r\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\r\n});\r\n\r\nexport async function handleScaffoldExtension(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ScaffoldExtensionInputSchema.parse(args);\r\n\r\n logger.info('Scaffolding extension', { type: input.type, name: input.name });\r\n\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n const result: ScaffoldResult = {\r\n success: true,\r\n files: [],\r\n instructions: [],\r\n };\r\n\r\n try {\r\n switch (input.type) {\r\n case 'service':\r\n await scaffoldService(input.name, input.options, structure, config, result);\r\n break;\r\n case 'entity':\r\n await scaffoldEntity(input.name, input.options, structure, config, result);\r\n break;\r\n case 'controller':\r\n await scaffoldController(input.name, input.options, structure, config, result);\r\n break;\r\n case 'component':\r\n await scaffoldComponent(input.name, input.options, structure, config, result);\r\n break;\r\n }\r\n } catch (error) {\r\n result.success = false;\r\n result.instructions.push(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);\r\n }\r\n\r\n return formatResult(result, input.type, input.name);\r\n}\r\n\r\nasync function scaffoldService(\r\n name: string,\r\n options: { namespace?: string; methods?: string[] } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || `${config.conventions.namespaces.application}.Services`;\r\n const methods = options?.methods || ['GetByIdAsync', 'GetAllAsync', 'CreateAsync', 'UpdateAsync', 'DeleteAsync'];\r\n\r\n // Interface template\r\n const interfaceTemplate = `using System.Threading;\r\nusing System.Threading.Tasks;\r\nusing System.Collections.Generic;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// Service interface for {{name}} operations\r\n/// </summary>\r\npublic interface I{{name}}Service\r\n{\r\n{{#each methods}}\r\n /// <summary>\r\n /// {{this}} operation\r\n /// </summary>\r\n Task<object> {{this}}(CancellationToken cancellationToken = default);\r\n\r\n{{/each}}\r\n}\r\n`;\r\n\r\n // Implementation template\r\n const implementationTemplate = `using System.Threading;\r\nusing System.Threading.Tasks;\r\nusing System.Collections.Generic;\r\nusing Microsoft.Extensions.Logging;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// Service implementation for {{name}} operations\r\n/// </summary>\r\npublic class {{name}}Service : I{{name}}Service\r\n{\r\n private readonly ILogger<{{name}}Service> _logger;\r\n\r\n public {{name}}Service(ILogger<{{name}}Service> logger)\r\n {\r\n _logger = logger;\r\n }\r\n\r\n{{#each methods}}\r\n /// <inheritdoc />\r\n public async Task<object> {{this}}(CancellationToken cancellationToken = default)\r\n {\r\n _logger.LogInformation(\"Executing {{this}}\");\r\n // TODO: Implement {{this}}\r\n await Task.CompletedTask;\r\n throw new NotImplementedException();\r\n }\r\n\r\n{{/each}}\r\n}\r\n`;\r\n\r\n // DI registration template\r\n const diTemplate = `// Add to DependencyInjection.cs or ServiceCollectionExtensions.cs:\r\nservices.AddScoped<I{{name}}Service, {{name}}Service>();\r\n`;\r\n\r\n const context = { namespace, name, methods };\r\n\r\n const interfaceContent = Handlebars.compile(interfaceTemplate)(context);\r\n const implementationContent = Handlebars.compile(implementationTemplate)(context);\r\n const diContent = Handlebars.compile(diTemplate)(context);\r\n\r\n // Determine output paths\r\n const basePath = structure.application || config.smartstack.projectPath;\r\n const servicesPath = path.join(basePath, 'Services');\r\n\r\n await ensureDirectory(servicesPath);\r\n\r\n const interfacePath = path.join(servicesPath, `I${name}Service.cs`);\r\n const implementationPath = path.join(servicesPath, `${name}Service.cs`);\r\n\r\n // Write files\r\n await writeText(interfacePath, interfaceContent);\r\n result.files.push({ path: interfacePath, content: interfaceContent, type: 'created' });\r\n\r\n await writeText(implementationPath, implementationContent);\r\n result.files.push({ path: implementationPath, content: implementationContent, type: 'created' });\r\n\r\n result.instructions.push('Register service in DI container:');\r\n result.instructions.push(diContent);\r\n}\r\n\r\nasync function scaffoldEntity(\r\n name: string,\r\n options: { namespace?: string; baseEntity?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || config.conventions.namespaces.domain;\r\n const baseEntity = options?.baseEntity;\r\n\r\n // Entity template\r\n const entityTemplate = `using System;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}\r\n/// </summary>\r\npublic class {{name}}{{#if baseEntity}} : {{baseEntity}}{{/if}}\r\n{\r\n{{#unless baseEntity}}\r\n public Guid Id { get; set; }\r\n\r\n public DateTime CreatedAt { get; set; } = DateTime.UtcNow;\r\n\r\n public DateTime? UpdatedAt { get; set; }\r\n\r\n{{/unless}}\r\n // TODO: Add {{name}} specific properties\r\n}\r\n`;\r\n\r\n // EF Configuration template\r\n const configTemplate = `using Microsoft.EntityFrameworkCore;\r\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\r\n\r\nnamespace {{infrastructureNamespace}}.Persistence.Configurations;\r\n\r\npublic class {{name}}Configuration : IEntityTypeConfiguration<{{domainNamespace}}.{{name}}>\r\n{\r\n public void Configure(EntityTypeBuilder<{{domainNamespace}}.{{name}}> builder)\r\n {\r\n builder.ToTable(\"{{tablePrefix}}{{name}}s\");\r\n\r\n builder.HasKey(e => e.Id);\r\n\r\n // TODO: Add {{name}} specific configuration\r\n }\r\n}\r\n`;\r\n\r\n const context = {\r\n namespace,\r\n name,\r\n baseEntity,\r\n infrastructureNamespace: config.conventions.namespaces.infrastructure,\r\n domainNamespace: config.conventions.namespaces.domain,\r\n schema: config.conventions.schemas.platform,\r\n };\r\n\r\n const entityContent = Handlebars.compile(entityTemplate)(context);\r\n const configContent = Handlebars.compile(configTemplate)(context);\r\n\r\n // Determine output paths\r\n const domainPath = structure.domain || path.join(config.smartstack.projectPath, 'Domain');\r\n const infraPath = structure.infrastructure || path.join(config.smartstack.projectPath, 'Infrastructure');\r\n\r\n await ensureDirectory(domainPath);\r\n await ensureDirectory(path.join(infraPath, 'Persistence', 'Configurations'));\r\n\r\n const entityFilePath = path.join(domainPath, `${name}.cs`);\r\n const configFilePath = path.join(infraPath, 'Persistence', 'Configurations', `${name}Configuration.cs`);\r\n\r\n await writeText(entityFilePath, entityContent);\r\n result.files.push({ path: entityFilePath, content: entityContent, type: 'created' });\r\n\r\n await writeText(configFilePath, configContent);\r\n result.files.push({ path: configFilePath, content: configContent, type: 'created' });\r\n\r\n result.instructions.push(`Add DbSet to ApplicationDbContext:`);\r\n result.instructions.push(`public DbSet<${name}> ${name}s => Set<${name}>();`);\r\n result.instructions.push('');\r\n result.instructions.push('Create migration:');\r\n result.instructions.push(`dotnet ef migrations add Add${name}`);\r\n}\r\n\r\nasync function scaffoldController(\r\n name: string,\r\n options: { namespace?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || `${config.conventions.namespaces.api}.Controllers`;\r\n\r\n const controllerTemplate = `using Microsoft.AspNetCore.Authorization;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Microsoft.Extensions.Logging;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// API controller for {{name}} operations\r\n/// </summary>\r\n[ApiController]\r\n[Route(\"api/[controller]\")]\r\n[Authorize]\r\npublic class {{name}}Controller : ControllerBase\r\n{\r\n private readonly ILogger<{{name}}Controller> _logger;\r\n\r\n public {{name}}Controller(ILogger<{{name}}Controller> logger)\r\n {\r\n _logger = logger;\r\n }\r\n\r\n /// <summary>\r\n /// Get all {{nameLower}}s\r\n /// </summary>\r\n [HttpGet]\r\n public async Task<ActionResult<IEnumerable<{{name}}Dto>>> GetAll()\r\n {\r\n _logger.LogInformation(\"Getting all {{nameLower}}s\");\r\n // TODO: Implement\r\n return Ok(Array.Empty<{{name}}Dto>());\r\n }\r\n\r\n /// <summary>\r\n /// Get {{nameLower}} by ID\r\n /// </summary>\r\n [HttpGet(\"{id:guid}\")]\r\n public async Task<ActionResult<{{name}}Dto>> GetById(Guid id)\r\n {\r\n _logger.LogInformation(\"Getting {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NotFound();\r\n }\r\n\r\n /// <summary>\r\n /// Create new {{nameLower}}\r\n /// </summary>\r\n [HttpPost]\r\n public async Task<ActionResult<{{name}}Dto>> Create([FromBody] Create{{name}}Request request)\r\n {\r\n _logger.LogInformation(\"Creating {{nameLower}}\");\r\n // TODO: Implement\r\n return CreatedAtAction(nameof(GetById), new { id = Guid.NewGuid() }, null);\r\n }\r\n\r\n /// <summary>\r\n /// Update {{nameLower}}\r\n /// </summary>\r\n [HttpPut(\"{id:guid}\")]\r\n public async Task<ActionResult> Update(Guid id, [FromBody] Update{{name}}Request request)\r\n {\r\n _logger.LogInformation(\"Updating {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NoContent();\r\n }\r\n\r\n /// <summary>\r\n /// Delete {{nameLower}}\r\n /// </summary>\r\n [HttpDelete(\"{id:guid}\")]\r\n public async Task<ActionResult> Delete(Guid id)\r\n {\r\n _logger.LogInformation(\"Deleting {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NoContent();\r\n }\r\n}\r\n\r\n// DTOs\r\npublic record {{name}}Dto(Guid Id, DateTime CreatedAt);\r\npublic record Create{{name}}Request();\r\npublic record Update{{name}}Request();\r\n`;\r\n\r\n const context = {\r\n namespace,\r\n name,\r\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\r\n };\r\n\r\n const controllerContent = Handlebars.compile(controllerTemplate)(context);\r\n\r\n const apiPath = structure.api || path.join(config.smartstack.projectPath, 'Api');\r\n const controllersPath = path.join(apiPath, 'Controllers');\r\n\r\n await ensureDirectory(controllersPath);\r\n\r\n const controllerFilePath = path.join(controllersPath, `${name}Controller.cs`);\r\n\r\n await writeText(controllerFilePath, controllerContent);\r\n result.files.push({ path: controllerFilePath, content: controllerContent, type: 'created' });\r\n\r\n result.instructions.push('Controller created. API endpoints:');\r\n result.instructions.push(` GET /api/${name.toLowerCase()}`);\r\n result.instructions.push(` GET /api/${name.toLowerCase()}/{id}`);\r\n result.instructions.push(` POST /api/${name.toLowerCase()}`);\r\n result.instructions.push(` PUT /api/${name.toLowerCase()}/{id}`);\r\n result.instructions.push(` DELETE /api/${name.toLowerCase()}/{id}`);\r\n}\r\n\r\nasync function scaffoldComponent(\r\n name: string,\r\n options: { namespace?: string; outputPath?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const componentTemplate = `import React, { useState, useEffect } from 'react';\r\n\r\ninterface {{name}}Props {\r\n id?: string;\r\n onSave?: (data: {{name}}Data) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\ninterface {{name}}Data {\r\n id?: string;\r\n // TODO: Add {{name}} data properties\r\n}\r\n\r\n/**\r\n * {{name}} component\r\n */\r\nexport const {{name}}: React.FC<{{name}}Props> = ({ id, onSave, onCancel }) => {\r\n const [data, setData] = useState<{{name}}Data | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n if (id) {\r\n // TODO: Fetch {{nameLower}} data\r\n setLoading(true);\r\n // fetch...\r\n setLoading(false);\r\n }\r\n }, [id]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (data && onSave) {\r\n onSave(data);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return <div className=\"animate-pulse\">Loading...</div>;\r\n }\r\n\r\n if (error) {\r\n return <div className=\"text-red-500\">{error}</div>;\r\n }\r\n\r\n return (\r\n <div className=\"p-4\">\r\n <h2 className=\"text-xl font-semibold mb-4\">{{name}}</h2>\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n {/* TODO: Add form fields */}\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\r\n >\r\n Save\r\n </button>\r\n {onCancel && (\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 py-2 bg-gray-200 rounded hover:bg-gray-300\"\r\n >\r\n Cancel\r\n </button>\r\n )}\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nexport default {{name}};\r\n`;\r\n\r\n // Hook template\r\n const hookTemplate = `import { useState, useEffect, useCallback } from 'react';\r\nimport { {{nameLower}}Api } from '../services/api/{{nameLower}}';\r\n\r\ninterface {{name}}Data {\r\n id?: string;\r\n // TODO: Add properties\r\n}\r\n\r\ninterface Use{{name}}Options {\r\n id?: string;\r\n autoFetch?: boolean;\r\n}\r\n\r\nexport function use{{name}}(options: Use{{name}}Options = {}) {\r\n const { id, autoFetch = true } = options;\r\n const [data, setData] = useState<{{name}}Data | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetch{{name}} = useCallback(async (fetchId?: string) => {\r\n const targetId = fetchId || id;\r\n if (!targetId) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n // TODO: Implement API call\r\n // const result = await {{nameLower}}Api.getById(targetId);\r\n // setData(result);\r\n } catch (e) {\r\n setError(e instanceof Error ? e : new Error('Unknown error'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [id]);\r\n\r\n const save{{name}} = useCallback(async (saveData: {{name}}Data) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n // TODO: Implement API call\r\n // const result = saveData.id\r\n // ? await {{nameLower}}Api.update(saveData.id, saveData)\r\n // : await {{nameLower}}Api.create(saveData);\r\n // setData(result);\r\n // return result;\r\n } catch (e) {\r\n setError(e instanceof Error ? e : new Error('Unknown error'));\r\n throw e;\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (autoFetch && id) {\r\n fetch{{name}}();\r\n }\r\n }, [autoFetch, id, fetch{{name}}]);\r\n\r\n return {\r\n data,\r\n loading,\r\n error,\r\n fetch: fetch{{name}},\r\n save: save{{name}},\r\n setData,\r\n };\r\n}\r\n`;\r\n\r\n const context = {\r\n name,\r\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\r\n };\r\n\r\n const componentContent = Handlebars.compile(componentTemplate)(context);\r\n const hookContent = Handlebars.compile(hookTemplate)(context);\r\n\r\n // Determine output paths\r\n const webPath = structure.web || path.join(config.smartstack.projectPath, 'web', 'smartstack-web');\r\n const componentsPath = options?.outputPath || path.join(webPath, 'src', 'components');\r\n const hooksPath = path.join(webPath, 'src', 'hooks');\r\n\r\n await ensureDirectory(componentsPath);\r\n await ensureDirectory(hooksPath);\r\n\r\n const componentFilePath = path.join(componentsPath, `${name}.tsx`);\r\n const hookFilePath = path.join(hooksPath, `use${name}.ts`);\r\n\r\n await writeText(componentFilePath, componentContent);\r\n result.files.push({ path: componentFilePath, content: componentContent, type: 'created' });\r\n\r\n await writeText(hookFilePath, hookContent);\r\n result.files.push({ path: hookFilePath, content: hookContent, type: 'created' });\r\n\r\n result.instructions.push('Import and use the component:');\r\n result.instructions.push(`import { ${name} } from './components/${name}';`);\r\n result.instructions.push(`import { use${name} } from './hooks/use${name}';`);\r\n}\r\n\r\nfunction formatResult(result: ScaffoldResult, type: string, name: string): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(`# Scaffold ${type}: ${name}`);\r\n lines.push('');\r\n\r\n if (result.success) {\r\n lines.push('## ✅ Files Generated');\r\n lines.push('');\r\n\r\n for (const file of result.files) {\r\n lines.push(`### ${file.type === 'created' ? '📄' : '✏️'} ${path.basename(file.path)}`);\r\n lines.push(`**Path**: \\`${file.path}\\``);\r\n lines.push('');\r\n lines.push('```' + (file.path.endsWith('.cs') ? 'csharp' : 'typescript'));\r\n // Show first 50 lines of content\r\n const contentLines = file.content.split('\\n').slice(0, 50);\r\n lines.push(contentLines.join('\\n'));\r\n if (file.content.split('\\n').length > 50) {\r\n lines.push('// ... (truncated)');\r\n }\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n if (result.instructions.length > 0) {\r\n lines.push('## 📋 Next Steps');\r\n lines.push('');\r\n for (const instruction of result.instructions) {\r\n if (instruction.startsWith('services.') || instruction.startsWith('public DbSet')) {\r\n lines.push('```csharp');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else if (instruction.startsWith('dotnet ')) {\r\n lines.push('```bash');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else if (instruction.startsWith('import ')) {\r\n lines.push('```typescript');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else {\r\n lines.push(instruction);\r\n }\r\n }\r\n }\r\n } else {\r\n lines.push('## ❌ Generation Failed');\r\n lines.push('');\r\n for (const instruction of result.instructions) {\r\n lines.push(`- ${instruction}`);\r\n }\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport axios from 'axios';\r\nimport {\r\n ApiDocsInputSchema,\r\n type Config,\r\n} from '../types/index.js';\r\nimport { readText } from '../utils/fs.js';\r\nimport { findSmartStackStructure, findControllerFiles } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const apiDocsTool: Tool = {\r\n name: 'api_docs',\r\n description: 'Get API documentation for SmartStack endpoints. Can fetch from Swagger/OpenAPI or parse controller files directly.',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n endpoint: {\r\n type: 'string',\r\n description: 'Filter by endpoint path (e.g., \"/api/users\"). Leave empty for all endpoints.',\r\n },\r\n format: {\r\n type: 'string',\r\n enum: ['markdown', 'json', 'openapi'],\r\n description: 'Output format',\r\n default: 'markdown',\r\n },\r\n controller: {\r\n type: 'string',\r\n description: 'Filter by controller name (e.g., \"Users\")',\r\n },\r\n },\r\n },\r\n};\r\n\r\ninterface EndpointInfo {\r\n method: string;\r\n path: string;\r\n controller: string;\r\n action: string;\r\n summary?: string;\r\n parameters: ParameterInfo[];\r\n requestBody?: string;\r\n responses: ResponseInfo[];\r\n authorize: boolean;\r\n}\r\n\r\ninterface ParameterInfo {\r\n name: string;\r\n in: 'path' | 'query' | 'header' | 'body';\r\n type: string;\r\n required: boolean;\r\n description?: string;\r\n}\r\n\r\ninterface ResponseInfo {\r\n status: number;\r\n type?: string;\r\n description?: string;\r\n}\r\n\r\nexport async function handleApiDocs(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ApiDocsInputSchema.parse(args);\r\n\r\n logger.info('Fetching API documentation', { endpoint: input.endpoint, format: input.format });\r\n\r\n let endpoints: EndpointInfo[] = [];\r\n\r\n // Try to fetch from Swagger first if API is enabled\r\n if (config.smartstack.apiEnabled && config.smartstack.apiUrl) {\r\n try {\r\n endpoints = await fetchFromSwagger(config.smartstack.apiUrl);\r\n logger.debug('Fetched endpoints from Swagger', { count: endpoints.length });\r\n } catch (error) {\r\n logger.warn('Failed to fetch from Swagger, falling back to code parsing', { error });\r\n }\r\n }\r\n\r\n // Fall back to parsing controller files\r\n if (endpoints.length === 0) {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n endpoints = await parseControllers(structure);\r\n }\r\n\r\n // Filter endpoints\r\n if (input.endpoint) {\r\n const filter = input.endpoint.toLowerCase();\r\n endpoints = endpoints.filter(e => e.path.toLowerCase().includes(filter));\r\n }\r\n\r\n if (input.controller) {\r\n const filter = input.controller.toLowerCase();\r\n endpoints = endpoints.filter(e => e.controller.toLowerCase().includes(filter));\r\n }\r\n\r\n // Format output\r\n switch (input.format) {\r\n case 'json':\r\n return JSON.stringify(endpoints, null, 2);\r\n case 'openapi':\r\n return formatAsOpenApi(endpoints);\r\n case 'markdown':\r\n default:\r\n return formatAsMarkdown(endpoints);\r\n }\r\n}\r\n\r\nasync function fetchFromSwagger(apiUrl: string): Promise<EndpointInfo[]> {\r\n const swaggerUrl = `${apiUrl}/swagger/v1/swagger.json`;\r\n\r\n const response = await axios.get(swaggerUrl, {\r\n timeout: 5000,\r\n httpsAgent: new (await import('https')).Agent({ rejectUnauthorized: false }),\r\n });\r\n\r\n const spec = response.data;\r\n const endpoints: EndpointInfo[] = [];\r\n\r\n for (const [pathKey, pathItem] of Object.entries(spec.paths || {})) {\r\n const pathObj = pathItem as Record<string, unknown>;\r\n\r\n for (const method of ['get', 'post', 'put', 'patch', 'delete']) {\r\n const operation = pathObj[method] as Record<string, unknown> | undefined;\r\n if (!operation) continue;\r\n\r\n const tags = (operation.tags as string[]) || ['Unknown'];\r\n const parameters = (operation.parameters as Array<Record<string, unknown>>) || [];\r\n\r\n endpoints.push({\r\n method: method.toUpperCase(),\r\n path: pathKey,\r\n controller: tags[0],\r\n action: (operation.operationId as string) || method,\r\n summary: operation.summary as string | undefined,\r\n parameters: parameters.map(p => ({\r\n name: p.name as string,\r\n in: p.in as 'path' | 'query' | 'header' | 'body',\r\n type: (p.schema as Record<string, string>)?.type || 'string',\r\n required: p.required as boolean || false,\r\n description: p.description as string | undefined,\r\n })),\r\n requestBody: operation.requestBody ? 'See schema' : undefined,\r\n responses: Object.entries(operation.responses || {}).map(([status, resp]) => ({\r\n status: parseInt(status, 10),\r\n description: (resp as Record<string, string>).description,\r\n })),\r\n authorize: !!(operation.security && (operation.security as unknown[]).length > 0),\r\n });\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nasync function parseControllers(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\r\n): Promise<EndpointInfo[]> {\r\n if (!structure.api) {\r\n return [];\r\n }\r\n\r\n const controllerFiles = await findControllerFiles(structure.api);\r\n const endpoints: EndpointInfo[] = [];\r\n\r\n for (const file of controllerFiles) {\r\n const content = await readText(file);\r\n const fileName = path.basename(file, '.cs');\r\n const controllerName = fileName.replace('Controller', '');\r\n\r\n // Parse route attribute\r\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\r\n const baseRoute = routeMatch ? routeMatch[1].replace('[controller]', controllerName.toLowerCase()) : `/api/${controllerName.toLowerCase()}`;\r\n\r\n // Parse authorize attribute\r\n const hasAuthorize = content.includes('[Authorize]');\r\n\r\n // Parse HTTP methods\r\n const httpMethods = [\r\n { pattern: /\\[HttpGet(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'GET' },\r\n { pattern: /\\[HttpPost(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'POST' },\r\n { pattern: /\\[HttpPut(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PUT' },\r\n { pattern: /\\[HttpPatch(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PATCH' },\r\n { pattern: /\\[HttpDelete(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'DELETE' },\r\n ];\r\n\r\n for (const { pattern, method } of httpMethods) {\r\n let match;\r\n while ((match = pattern.exec(content)) !== null) {\r\n const routeSuffix = match[1] || '';\r\n const fullPath = routeSuffix ? `${baseRoute}/${routeSuffix}` : baseRoute;\r\n\r\n // Try to find the method name after the attribute\r\n const afterAttribute = content.substring(match.index);\r\n const methodMatch = afterAttribute.match(/public\\s+(?:async\\s+)?(?:Task<)?(?:ActionResult<)?(\\w+)(?:>)?\\s+(\\w+)\\s*\\(/);\r\n\r\n const parameters: ParameterInfo[] = [];\r\n\r\n // Parse path parameters\r\n const pathParams = fullPath.match(/\\{(\\w+)(?::\\w+)?\\}/g);\r\n if (pathParams) {\r\n for (const param of pathParams) {\r\n const paramName = param.replace(/[{}:]/g, '').replace(/\\w+$/, '');\r\n parameters.push({\r\n name: paramName || param.replace(/[{}]/g, '').split(':')[0],\r\n in: 'path',\r\n type: 'string',\r\n required: true,\r\n });\r\n }\r\n }\r\n\r\n // Parse [FromBody] parameters\r\n if (afterAttribute.includes('[FromBody]')) {\r\n const bodyMatch = afterAttribute.match(/\\[FromBody\\]\\s*(\\w+)\\s+(\\w+)/);\r\n if (bodyMatch) {\r\n parameters.push({\r\n name: bodyMatch[2],\r\n in: 'body',\r\n type: bodyMatch[1],\r\n required: true,\r\n });\r\n }\r\n }\r\n\r\n // Parse [FromQuery] parameters\r\n const queryMatches = afterAttribute.matchAll(/\\[FromQuery\\]\\s*(\\w+)\\s+(\\w+)/g);\r\n for (const qm of queryMatches) {\r\n parameters.push({\r\n name: qm[2],\r\n in: 'query',\r\n type: qm[1],\r\n required: false,\r\n });\r\n }\r\n\r\n endpoints.push({\r\n method,\r\n path: fullPath.replace(/\\/+/g, '/'),\r\n controller: controllerName,\r\n action: methodMatch ? methodMatch[2] : 'Unknown',\r\n parameters,\r\n responses: [{ status: 200, description: 'Success' }],\r\n authorize: hasAuthorize,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nfunction formatAsMarkdown(endpoints: EndpointInfo[]): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack API Documentation');\r\n lines.push('');\r\n lines.push(`Generated: ${new Date().toISOString()}`);\r\n lines.push('');\r\n\r\n // Group by controller\r\n const byController = new Map<string, EndpointInfo[]>();\r\n for (const endpoint of endpoints) {\r\n const existing = byController.get(endpoint.controller) || [];\r\n existing.push(endpoint);\r\n byController.set(endpoint.controller, existing);\r\n }\r\n\r\n for (const [controller, controllerEndpoints] of byController) {\r\n lines.push(`## ${controller}`);\r\n lines.push('');\r\n\r\n for (const endpoint of controllerEndpoints) {\r\n const authBadge = endpoint.authorize ? ' 🔒' : '';\r\n lines.push(`### \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\r\n lines.push('');\r\n\r\n if (endpoint.summary) {\r\n lines.push(endpoint.summary);\r\n lines.push('');\r\n }\r\n\r\n if (endpoint.parameters.length > 0) {\r\n lines.push('**Parameters:**');\r\n lines.push('');\r\n lines.push('| Name | In | Type | Required |');\r\n lines.push('|------|-----|------|----------|');\r\n for (const param of endpoint.parameters) {\r\n lines.push(`| ${param.name} | ${param.in} | ${param.type} | ${param.required ? 'Yes' : 'No'} |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n if (endpoint.responses.length > 0) {\r\n lines.push('**Responses:**');\r\n lines.push('');\r\n for (const resp of endpoint.responses) {\r\n lines.push(`- \\`${resp.status}\\`: ${resp.description || 'No description'}`);\r\n }\r\n lines.push('');\r\n }\r\n }\r\n }\r\n\r\n if (endpoints.length === 0) {\r\n lines.push('No endpoints found matching the filter criteria.');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction formatAsOpenApi(endpoints: EndpointInfo[]): string {\r\n const spec = {\r\n openapi: '3.0.0',\r\n info: {\r\n title: 'SmartStack API',\r\n version: '1.0.0',\r\n },\r\n paths: {} as Record<string, Record<string, unknown>>,\r\n };\r\n\r\n for (const endpoint of endpoints) {\r\n if (!spec.paths[endpoint.path]) {\r\n spec.paths[endpoint.path] = {};\r\n }\r\n\r\n spec.paths[endpoint.path][endpoint.method.toLowerCase()] = {\r\n tags: [endpoint.controller],\r\n operationId: endpoint.action,\r\n summary: endpoint.summary,\r\n parameters: endpoint.parameters\r\n .filter(p => p.in !== 'body')\r\n .map(p => ({\r\n name: p.name,\r\n in: p.in,\r\n required: p.required,\r\n schema: { type: p.type },\r\n })),\r\n responses: Object.fromEntries(\r\n endpoint.responses.map(r => [\r\n r.status.toString(),\r\n { description: r.description || 'Response' },\r\n ])\r\n ),\r\n security: endpoint.authorize ? [{ bearerAuth: [] }] : undefined,\r\n };\r\n }\r\n\r\n return JSON.stringify(spec, null, 2);\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\n\nexport const conventionsResourceTemplate: Resource = {\n uri: 'smartstack://conventions',\n name: 'AtlasHub Conventions',\n description: 'Documentation of AtlasHub/SmartStack naming conventions, patterns, and best practices',\n mimeType: 'text/markdown',\n};\n\nexport async function getConventionsResource(config: Config): Promise<string> {\n const { schemas, tablePrefixes, migrationFormat, namespaces, servicePattern } = config.conventions;\n\n return `# AtlasHub SmartStack Conventions\n\n## Overview\n\nThis document describes the mandatory conventions for extending the SmartStack/AtlasHub platform.\nFollowing these conventions ensures compatibility and prevents conflicts.\n\n---\n\n## 1. Database Conventions\n\n### SQL Schemas\n\nSmartStack uses SQL Server schemas to separate platform tables from client extensions:\n\n| Schema | Usage | Description |\n|--------|-------|-------------|\n| \\`${schemas.platform}\\` | SmartStack platform | All native SmartStack tables |\n| \\`${schemas.extensions}\\` | Client extensions | Custom tables added by clients |\n\n### Domain Table Prefixes\n\nTables are organized by domain using prefixes:\n\n| Prefix | Domain | Example Tables |\n|--------|--------|----------------|\n| \\`auth_\\` | Authorization | auth_Users, auth_Roles, auth_Permissions |\n| \\`nav_\\` | Navigation | nav_Contexts, nav_Applications, nav_Modules |\n| \\`usr_\\` | User profiles | usr_Profiles, usr_Preferences |\n| \\`ai_\\` | AI features | ai_Providers, ai_Models, ai_Prompts |\n| \\`cfg_\\` | Configuration | cfg_Settings |\n| \\`wkf_\\` | Workflows | wkf_EmailTemplates, wkf_Workflows |\n| \\`support_\\` | Support | support_Tickets, support_Comments |\n| \\`entra_\\` | Entra sync | entra_Groups, entra_SyncState |\n| \\`ref_\\` | References | ref_Companies, ref_Departments |\n| \\`loc_\\` | Localization | loc_Languages, loc_Translations |\n| \\`lic_\\` | Licensing | lic_Licenses |\n\n### Entity Configuration\n\n\\`\\`\\`csharp\npublic class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>\n{\n public void Configure(EntityTypeBuilder<MyEntity> builder)\n {\n // CORRECT: Use schema + domain prefix\n builder.ToTable(\"auth_Users\", \"${schemas.platform}\");\n\n // WRONG: No schema specified\n // builder.ToTable(\"auth_Users\");\n\n // WRONG: No domain prefix\n // builder.ToTable(\"Users\", \"${schemas.platform}\");\n }\n}\n\\`\\`\\`\n\n### Extending Core Entities\n\nWhen extending a core entity, use the \\`${schemas.extensions}\\` schema:\n\n\\`\\`\\`csharp\n// Client extension for auth_Users\npublic class UserExtension\n{\n public Guid UserId { get; set; } // FK to auth_Users\n public User User { get; set; }\n\n // Custom properties\n public string CustomField { get; set; }\n}\n\n// Configuration - use extensions schema\nbuilder.ToTable(\"client_UserExtensions\", \"${schemas.extensions}\");\nbuilder.HasOne(e => e.User)\n .WithOne()\n .HasForeignKey<UserExtension>(e => e.UserId);\n\\`\\`\\`\n\n---\n\n## 2. Migration Conventions\n\n### Naming Format\n\nMigrations MUST follow this naming pattern:\n\n\\`\\`\\`\n${migrationFormat}\n\\`\\`\\`\n\n**Examples:**\n- \\`20260115_001_InitialSchema.cs\\`\n- \\`20260120_002_AddUserProfiles.cs\\`\n- \\`20260125_003_AddSupportTickets.cs\\`\n\n### Creating Migrations\n\n\\`\\`\\`bash\n# Create a new migration\ndotnet ef migrations add 20260115_001_InitialSchema\n\n# With context specified\ndotnet ef migrations add 20260115_001_InitialSchema --context ApplicationDbContext\n\\`\\`\\`\n\n### Migration Rules\n\n1. **One migration per feature** - Group related changes in a single migration\n2. **Timestamps ensure order** - Use YYYYMMDD format for chronological sorting\n3. **Sequence numbers** - Use NNN (001, 002, etc.) for migrations on the same day\n4. **Descriptive names** - Use clear descriptions (InitialSchema, AddUserProfiles, etc.)\n5. **Schema must be specified** - All tables must specify their schema in ToTable()\n\n---\n\n## 3. Namespace Conventions\n\n### Layer Structure\n\n| Layer | Namespace | Purpose |\n|-------|-----------|---------|\n| Domain | \\`${namespaces.domain}\\` | Entities, value objects, domain events |\n| Application | \\`${namespaces.application}\\` | Use cases, services, interfaces |\n| Infrastructure | \\`${namespaces.infrastructure}\\` | EF Core, external services |\n| API | \\`${namespaces.api}\\` | Controllers, DTOs, middleware |\n\n### Example Namespaces\n\n\\`\\`\\`csharp\n// Entity in Domain layer\nnamespace ${namespaces.domain}.Entities;\npublic class User { }\n\n// Service interface in Application layer\nnamespace ${namespaces.application}.Services;\npublic interface IUserService { }\n\n// EF Configuration in Infrastructure layer\nnamespace ${namespaces.infrastructure}.Persistence.Configurations;\npublic class UserConfiguration { }\n\n// Controller in API layer\nnamespace ${namespaces.api}.Controllers;\npublic class UsersController { }\n\\`\\`\\`\n\n---\n\n## 4. Service Conventions\n\n### Naming Pattern\n\n| Type | Pattern | Example |\n|------|---------|---------|\n| Interface | \\`${servicePattern.interface.replace('{Name}', '<Name>')}\\` | \\`IUserService\\` |\n| Implementation | \\`${servicePattern.implementation.replace('{Name}', '<Name>')}\\` | \\`UserService\\` |\n\n### Service Structure\n\n\\`\\`\\`csharp\n// Interface (in Application layer)\nnamespace ${namespaces.application}.Services;\n\npublic interface IUserService\n{\n Task<UserDto> GetByIdAsync(Guid id, CancellationToken ct = default);\n Task<IEnumerable<UserDto>> GetAllAsync(CancellationToken ct = default);\n Task<UserDto> CreateAsync(CreateUserCommand cmd, CancellationToken ct = default);\n Task UpdateAsync(Guid id, UpdateUserCommand cmd, CancellationToken ct = default);\n Task DeleteAsync(Guid id, CancellationToken ct = default);\n}\n\n// Implementation (in Infrastructure or Application layer)\npublic class UserService : IUserService\n{\n private readonly IRepository<User> _repository;\n private readonly ILogger<UserService> _logger;\n\n public UserService(IRepository<User> repository, ILogger<UserService> logger)\n {\n _repository = repository;\n _logger = logger;\n }\n\n // Implementation...\n}\n\\`\\`\\`\n\n### Dependency Injection\n\n\\`\\`\\`csharp\n// In DependencyInjection.cs or ServiceCollectionExtensions.cs\npublic static IServiceCollection AddApplicationServices(this IServiceCollection services)\n{\n services.AddScoped<IUserService, UserService>();\n services.AddScoped<IRoleService, RoleService>();\n // ...\n return services;\n}\n\\`\\`\\`\n\n---\n\n## 5. Extension Patterns\n\n### Extending Services\n\nUse DI replacement to override core services:\n\n\\`\\`\\`csharp\n// Your custom implementation\npublic class CustomUserService : UserService, IUserService\n{\n public CustomUserService(IRepository<User> repo, ILogger<CustomUserService> logger)\n : base(repo, logger) { }\n\n public override async Task<UserDto> GetByIdAsync(Guid id, CancellationToken ct = default)\n {\n // Custom logic before\n var result = await base.GetByIdAsync(id, ct);\n // Custom logic after\n return result;\n }\n}\n\n// Replace in DI\nservices.Replace(ServiceDescriptor.Scoped<IUserService, CustomUserService>());\n\\`\\`\\`\n\n### Extension Hooks\n\nCore services expose hooks for common extension points:\n\n\\`\\`\\`csharp\npublic interface IUserServiceHooks\n{\n Task OnUserCreatedAsync(User user, CancellationToken ct);\n Task OnUserUpdatedAsync(User user, CancellationToken ct);\n Task OnUserDeletedAsync(Guid userId, CancellationToken ct);\n}\n\\`\\`\\`\n\n---\n\n## 6. Configuration\n\n### appsettings.json Structure\n\n\\`\\`\\`json\n{\n \"AtlasHub\": {\n \"Licensing\": {\n \"Key\": \"XXXX-XXXX-XXXX-XXXX\",\n \"Validate\": true\n },\n \"Features\": {\n \"AI\": true,\n \"Support\": true,\n \"Workflows\": true\n }\n },\n \"Client\": {\n \"Custom\": {\n // Client-specific configuration\n }\n }\n}\n\\`\\`\\`\n\n---\n\n## Quick Reference\n\n| Category | Convention | Example |\n|----------|------------|---------|\n| Platform schema | \\`${schemas.platform}\\` | \\`.ToTable(\"auth_Users\", \"${schemas.platform}\")\\` |\n| Extensions schema | \\`${schemas.extensions}\\` | \\`.ToTable(\"client_Custom\", \"${schemas.extensions}\")\\` |\n| Table prefixes | \\`${tablePrefixes.slice(0, 5).join(', ')}\\`, etc. | \\`auth_Users\\`, \\`nav_Modules\\` |\n| Migration | \\`YYYYMMDD_NNN_Description\\` | \\`20260115_001_InitialCreate\\` |\n| Interface | \\`I<Name>Service\\` | \\`IUserService\\` |\n| Implementation | \\`<Name>Service\\` | \\`UserService\\` |\n| Domain namespace | \\`${namespaces.domain}\\` | - |\n| API namespace | \\`${namespaces.api}\\` | - |\n`;\n}\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { detectProject, findSmartStackStructure } from '../lib/detector.js';\r\nimport { findFiles } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const projectInfoResourceTemplate: Resource = {\r\n uri: 'smartstack://project',\r\n name: 'SmartStack Project Info',\r\n description: 'Current SmartStack project information, structure, and configuration',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\nexport async function getProjectInfoResource(config: Config): Promise<string> {\r\n const projectPath = config.smartstack.projectPath;\r\n const projectInfo = await detectProject(projectPath);\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack Project Information');\r\n lines.push('');\r\n lines.push('## Overview');\r\n lines.push('');\r\n lines.push(`| Property | Value |`);\r\n lines.push(`|----------|-------|`);\r\n lines.push(`| **Name** | ${projectInfo.name} |`);\r\n lines.push(`| **Version** | ${projectInfo.version} |`);\r\n lines.push(`| **Path** | \\`${projectPath}\\` |`);\r\n lines.push(`| **Git Repository** | ${projectInfo.isGitRepo ? 'Yes' : 'No'} |`);\r\n if (projectInfo.currentBranch) {\r\n lines.push(`| **Current Branch** | \\`${projectInfo.currentBranch}\\` |`);\r\n }\r\n lines.push(`| **.NET Project** | ${projectInfo.hasDotNet ? 'Yes' : 'No'} |`);\r\n lines.push(`| **EF Core** | ${projectInfo.hasEfCore ? 'Yes' : 'No'} |`);\r\n if (projectInfo.dbContextName) {\r\n lines.push(`| **DbContext** | \\`${projectInfo.dbContextName}\\` |`);\r\n }\r\n lines.push(`| **React Frontend** | ${projectInfo.hasReact ? 'Yes' : 'No'} |`);\r\n lines.push('');\r\n\r\n // Project Structure\r\n lines.push('## Project Structure');\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(`${projectInfo.name}/`);\r\n if (structure.domain) {\r\n lines.push(`├── ${path.basename(structure.domain)}/ # Domain layer (entities)`);\r\n }\r\n if (structure.application) {\r\n lines.push(`├── ${path.basename(structure.application)}/ # Application layer (services)`);\r\n }\r\n if (structure.infrastructure) {\r\n lines.push(`├── ${path.basename(structure.infrastructure)}/ # Infrastructure (EF Core)`);\r\n }\r\n if (structure.api) {\r\n lines.push(`├── ${path.basename(structure.api)}/ # API layer (controllers)`);\r\n }\r\n if (structure.web) {\r\n lines.push(`└── web/smartstack-web/ # React frontend`);\r\n }\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // .NET Projects\r\n if (projectInfo.csprojFiles.length > 0) {\r\n lines.push('## .NET Projects');\r\n lines.push('');\r\n lines.push('| Project | Path |');\r\n lines.push('|---------|------|');\r\n for (const csproj of projectInfo.csprojFiles) {\r\n const name = path.basename(csproj, '.csproj');\r\n const relativePath = path.relative(projectPath, csproj);\r\n lines.push(`| ${name} | \\`${relativePath}\\` |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Migrations info\r\n if (structure.migrations) {\r\n const migrationFiles = await findFiles('*.cs', {\r\n cwd: structure.migrations,\r\n ignore: ['*.Designer.cs'],\r\n });\r\n\r\n const migrations = migrationFiles\r\n .map(f => path.basename(f))\r\n .filter(f => !f.includes('ModelSnapshot') && !f.includes('.Designer.'))\r\n .sort();\r\n\r\n lines.push('## EF Core Migrations');\r\n lines.push('');\r\n lines.push(`**Location**: \\`${path.relative(projectPath, structure.migrations)}\\``);\r\n lines.push(`**Total Migrations**: ${migrations.length}`);\r\n lines.push('');\r\n\r\n if (migrations.length > 0) {\r\n lines.push('### Recent Migrations');\r\n lines.push('');\r\n const recent = migrations.slice(-5);\r\n for (const migration of recent) {\r\n lines.push(`- \\`${migration.replace('.cs', '')}\\``);\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Configuration\r\n lines.push('## Configuration');\r\n lines.push('');\r\n lines.push('### MCP Server Config');\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify({\r\n smartstack: config.smartstack,\r\n conventions: {\r\n schemas: config.conventions.schemas,\r\n tablePrefixes: config.conventions.tablePrefixes,\r\n migrationFormat: config.conventions.migrationFormat,\r\n },\r\n }, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // Quick Commands\r\n lines.push('## Quick Commands');\r\n lines.push('');\r\n lines.push('```bash');\r\n lines.push('# Build the solution');\r\n lines.push('dotnet build');\r\n lines.push('');\r\n lines.push('# Run API');\r\n lines.push(`cd ${structure.api ? path.relative(projectPath, structure.api) : 'SmartStack.Api'}`);\r\n lines.push('dotnet run');\r\n lines.push('');\r\n lines.push('# Run frontend');\r\n lines.push(`cd ${structure.web ? path.relative(projectPath, structure.web) : 'web/smartstack-web'}`);\r\n lines.push('npm run dev');\r\n lines.push('');\r\n lines.push('# Create migration');\r\n lines.push('dotnet ef migrations add YYYYMMDD_Core_NNN_Description');\r\n lines.push('');\r\n lines.push('# Apply migrations');\r\n lines.push('dotnet ef database update');\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // MCP Tools Available\r\n lines.push('## Available MCP Tools');\r\n lines.push('');\r\n lines.push('| Tool | Description |');\r\n lines.push('|------|-------------|');\r\n lines.push('| `validate_conventions` | Check code against AtlasHub conventions |');\r\n lines.push('| `check_migrations` | Analyze EF Core migrations for conflicts |');\r\n lines.push('| `scaffold_extension` | Generate service, entity, controller, or component |');\r\n lines.push('| `api_docs` | Get API endpoint documentation |');\r\n lines.push('');\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { findControllerFiles, findSmartStackStructure } from '../lib/detector.js';\r\nimport { readText } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const apiEndpointsResourceTemplate: Resource = {\r\n uri: 'smartstack://api/',\r\n name: 'SmartStack API Endpoints',\r\n description: 'API endpoint documentation. Use smartstack://api/{endpoint} to filter.',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\ninterface ParsedEndpoint {\r\n method: string;\r\n path: string;\r\n controller: string;\r\n action: string;\r\n parameters: string[];\r\n returnType: string;\r\n authorize: boolean;\r\n summary?: string;\r\n}\r\n\r\nexport async function getApiEndpointsResource(\r\n config: Config,\r\n endpointFilter?: string\r\n): Promise<string> {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n if (!structure.api) {\r\n return '# API Endpoints\\n\\nNo API project found.';\r\n }\r\n\r\n const controllerFiles = await findControllerFiles(structure.api);\r\n const allEndpoints: ParsedEndpoint[] = [];\r\n\r\n for (const file of controllerFiles) {\r\n const endpoints = await parseController(file, structure.root);\r\n allEndpoints.push(...endpoints);\r\n }\r\n\r\n // Filter if specified\r\n const endpoints = endpointFilter\r\n ? allEndpoints.filter(e =>\r\n e.path.toLowerCase().includes(endpointFilter.toLowerCase()) ||\r\n e.controller.toLowerCase().includes(endpointFilter.toLowerCase())\r\n )\r\n : allEndpoints;\r\n\r\n return formatEndpoints(endpoints, endpointFilter);\r\n}\r\n\r\nasync function parseController(filePath: string, _rootPath: string): Promise<ParsedEndpoint[]> {\r\n const content = await readText(filePath);\r\n const fileName = path.basename(filePath, '.cs');\r\n const controllerName = fileName.replace('Controller', '');\r\n const endpoints: ParsedEndpoint[] = [];\r\n\r\n // Parse class-level route\r\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\r\n const baseRoute = routeMatch\r\n ? routeMatch[1].replace('[controller]', controllerName.toLowerCase())\r\n : `/api/${controllerName.toLowerCase()}`;\r\n\r\n // Check for class-level Authorize\r\n const classAuthorize = /\\[Authorize\\s*(?:\\([^)]*\\))?\\s*\\]\\s*(?:\\[.*\\]\\s*)*public\\s+class/.test(content);\r\n\r\n // Simple approach: find all HTTP method attributes\r\n const httpMethods = ['HttpGet', 'HttpPost', 'HttpPut', 'HttpPatch', 'HttpDelete'];\r\n let match: RegExpExecArray | null;\r\n\r\n for (const httpMethod of httpMethods) {\r\n const regex = new RegExp(\r\n `\\\\[${httpMethod}(?:\\\\s*\\\\(\\\\s*\"([^\"]*)\"\\\\s*\\\\))?\\\\]\\\\s*(?:\\\\[.*?\\\\]\\\\s*)*public\\\\s+(?:async\\\\s+)?(?:Task<)?(?:ActionResult<)?(\\\\w+)(?:[<>\\\\[\\\\],\\\\s\\\\w]*)?\\\\s+(\\\\w+)\\\\s*\\\\(([^)]*)\\\\)`,\r\n 'g'\r\n );\r\n\r\n while ((match = regex.exec(content)) !== null) {\r\n const routeSuffix = match[1] || '';\r\n const returnType = match[2];\r\n const actionName = match[3];\r\n const params = match[4];\r\n\r\n // Build full path\r\n let fullPath = baseRoute;\r\n if (routeSuffix) {\r\n fullPath = `${baseRoute}/${routeSuffix}`;\r\n }\r\n\r\n // Parse parameters\r\n const parameters = parseParameters(params);\r\n\r\n // Check for method-level authorize\r\n const methodAuthorize = content.substring(Math.max(0, match.index - 200), match.index)\r\n .includes('[Authorize');\r\n\r\n endpoints.push({\r\n method: httpMethod.replace('Http', '').toUpperCase(),\r\n path: fullPath.replace(/\\/+/g, '/'),\r\n controller: controllerName,\r\n action: actionName,\r\n parameters,\r\n returnType,\r\n authorize: classAuthorize || methodAuthorize,\r\n });\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nfunction parseParameters(paramsString: string): string[] {\r\n if (!paramsString.trim()) return [];\r\n\r\n const params: string[] = [];\r\n const parts = paramsString.split(',');\r\n\r\n for (const part of parts) {\r\n const trimmed = part.trim();\r\n if (!trimmed) continue;\r\n\r\n // Extract parameter name\r\n const match = trimmed.match(/(\\w+)\\s*(?:=.*)?$/);\r\n if (match) {\r\n // Include source attribute if present\r\n if (trimmed.includes('[FromBody]')) {\r\n params.push(`body: ${match[1]}`);\r\n } else if (trimmed.includes('[FromQuery]')) {\r\n params.push(`query: ${match[1]}`);\r\n } else if (trimmed.includes('[FromRoute]')) {\r\n params.push(`route: ${match[1]}`);\r\n } else {\r\n params.push(match[1]);\r\n }\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\nfunction formatEndpoints(endpoints: ParsedEndpoint[], filter?: string): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack API Endpoints');\r\n lines.push('');\r\n\r\n if (filter) {\r\n lines.push(`> Filtered by: \\`${filter}\\``);\r\n lines.push('');\r\n }\r\n\r\n if (endpoints.length === 0) {\r\n lines.push('No endpoints found matching the criteria.');\r\n return lines.join('\\n');\r\n }\r\n\r\n // Group by controller\r\n const byController = new Map<string, ParsedEndpoint[]>();\r\n for (const endpoint of endpoints) {\r\n const existing = byController.get(endpoint.controller) || [];\r\n existing.push(endpoint);\r\n byController.set(endpoint.controller, existing);\r\n }\r\n\r\n // Summary table\r\n lines.push('## Summary');\r\n lines.push('');\r\n lines.push(`**Total Endpoints**: ${endpoints.length}`);\r\n lines.push(`**Controllers**: ${byController.size}`);\r\n lines.push('');\r\n\r\n // Method distribution\r\n const methodCounts = new Map<string, number>();\r\n for (const endpoint of endpoints) {\r\n methodCounts.set(endpoint.method, (methodCounts.get(endpoint.method) || 0) + 1);\r\n }\r\n\r\n lines.push('| Method | Count |');\r\n lines.push('|--------|-------|');\r\n for (const [method, count] of methodCounts) {\r\n lines.push(`| ${method} | ${count} |`);\r\n }\r\n lines.push('');\r\n\r\n // Detailed by controller\r\n for (const [controller, controllerEndpoints] of byController) {\r\n lines.push(`## ${controller}Controller`);\r\n lines.push('');\r\n\r\n // Sort by path then method\r\n controllerEndpoints.sort((a, b) => {\r\n const pathCompare = a.path.localeCompare(b.path);\r\n if (pathCompare !== 0) return pathCompare;\r\n return a.method.localeCompare(b.method);\r\n });\r\n\r\n for (const endpoint of controllerEndpoints) {\r\n const authBadge = endpoint.authorize ? ' 🔒' : '';\r\n const methodColor = getMethodEmoji(endpoint.method);\r\n\r\n lines.push(`### ${methodColor} \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\r\n lines.push('');\r\n lines.push(`**Action**: \\`${endpoint.action}\\``);\r\n lines.push(`**Returns**: \\`${endpoint.returnType}\\``);\r\n\r\n if (endpoint.parameters.length > 0) {\r\n lines.push('');\r\n lines.push('**Parameters**:');\r\n for (const param of endpoint.parameters) {\r\n lines.push(`- \\`${param}\\``);\r\n }\r\n }\r\n\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Quick reference table\r\n lines.push('## Quick Reference');\r\n lines.push('');\r\n lines.push('| Method | Path | Action | Auth |');\r\n lines.push('|--------|------|--------|------|');\r\n for (const endpoint of endpoints) {\r\n lines.push(\r\n `| ${endpoint.method} | \\`${endpoint.path}\\` | ${endpoint.action} | ${endpoint.authorize ? '🔒' : '✓'} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction getMethodEmoji(method: string): string {\r\n switch (method) {\r\n case 'GET': return '🔵';\r\n case 'POST': return '🟢';\r\n case 'PUT': return '🟡';\r\n case 'PATCH': return '🟠';\r\n case 'DELETE': return '🔴';\r\n default: return '⚪';\r\n }\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { findSmartStackStructure, findEntityFiles } from '../lib/detector.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const dbSchemaResourceTemplate: Resource = {\r\n uri: 'smartstack://schema/',\r\n name: 'SmartStack Database Schema',\r\n description: 'Database schema information. Use smartstack://schema/{table} to get specific table.',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\ninterface EntityInfo {\r\n name: string;\r\n tableName: string;\r\n properties: PropertyInfo[];\r\n relationships: RelationshipInfo[];\r\n file: string;\r\n}\r\n\r\ninterface PropertyInfo {\r\n name: string;\r\n type: string;\r\n nullable: boolean;\r\n isPrimaryKey: boolean;\r\n maxLength?: number;\r\n}\r\n\r\ninterface RelationshipInfo {\r\n type: 'one-to-one' | 'one-to-many' | 'many-to-many';\r\n targetEntity: string;\r\n propertyName: string;\r\n}\r\n\r\nexport async function getDbSchemaResource(\r\n config: Config,\r\n tableFilter?: string\r\n): Promise<string> {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n if (!structure.domain && !structure.infrastructure) {\r\n return '# Database Schema\\n\\nNo domain or infrastructure project found.';\r\n }\r\n\r\n const entities: EntityInfo[] = [];\r\n\r\n // Parse entities from domain layer\r\n if (structure.domain) {\r\n const entityFiles = await findEntityFiles(structure.domain);\r\n for (const file of entityFiles) {\r\n const entity = await parseEntity(file, structure.root, config);\r\n if (entity) {\r\n entities.push(entity);\r\n }\r\n }\r\n }\r\n\r\n // Parse configurations from infrastructure layer for additional info\r\n if (structure.infrastructure) {\r\n await enrichFromConfigurations(entities, structure.infrastructure, config);\r\n }\r\n\r\n // Filter if specified\r\n const filteredEntities = tableFilter\r\n ? entities.filter(e =>\r\n e.name.toLowerCase().includes(tableFilter.toLowerCase()) ||\r\n e.tableName.toLowerCase().includes(tableFilter.toLowerCase())\r\n )\r\n : entities;\r\n\r\n return formatSchema(filteredEntities, tableFilter, config);\r\n}\r\n\r\nasync function parseEntity(\r\n filePath: string,\r\n rootPath: string,\r\n _config: Config\r\n): Promise<EntityInfo | null> {\r\n const content = await readText(filePath);\r\n\r\n // Find class declaration\r\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*(\\w+))?/);\r\n if (!classMatch) return null;\r\n\r\n const entityName = classMatch[1];\r\n\r\n // Skip non-entity classes\r\n if (entityName.endsWith('Dto') || entityName.endsWith('Command') ||\r\n entityName.endsWith('Query') || entityName.endsWith('Handler')) {\r\n return null;\r\n }\r\n\r\n const properties: PropertyInfo[] = [];\r\n const relationships: RelationshipInfo[] = [];\r\n\r\n // Parse properties\r\n const propertyPattern = /public\\s+(?:required\\s+)?(\\w+(?:<[\\w,\\s]+>)?)\\??\\s+(\\w+)\\s*\\{/g;\r\n let match;\r\n\r\n while ((match = propertyPattern.exec(content)) !== null) {\r\n const propertyType = match[1];\r\n const propertyName = match[2];\r\n\r\n // Skip navigation properties for now (we'll add them as relationships)\r\n if (propertyType.startsWith('ICollection') || propertyType.startsWith('List')) {\r\n // This is a collection navigation property\r\n const targetMatch = propertyType.match(/<(\\w+)>/);\r\n if (targetMatch) {\r\n relationships.push({\r\n type: 'one-to-many',\r\n targetEntity: targetMatch[1],\r\n propertyName,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n // Check if it's a reference navigation property\r\n const isNavigationProperty = /^[A-Z]/.test(propertyType) &&\r\n !['Guid', 'String', 'Int32', 'Int64', 'DateTime', 'DateTimeOffset',\r\n 'Boolean', 'Decimal', 'Double', 'Float', 'Byte'].includes(propertyType) &&\r\n !propertyType.includes('?');\r\n\r\n if (isNavigationProperty && !propertyType.includes('<')) {\r\n relationships.push({\r\n type: 'one-to-one',\r\n targetEntity: propertyType,\r\n propertyName,\r\n });\r\n continue;\r\n }\r\n\r\n properties.push({\r\n name: propertyName,\r\n type: mapCSharpType(propertyType),\r\n nullable: content.includes(`${propertyType}? ${propertyName}`) ||\r\n content.includes(`${propertyType}? ${propertyName}`),\r\n isPrimaryKey: propertyName === 'Id' || propertyName === `${entityName}Id`,\r\n });\r\n }\r\n\r\n // Default table name based on conventions (using cfg_ as default prefix for generic configs)\r\n const tableName = `cfg_${entityName}s`;\r\n\r\n return {\r\n name: entityName,\r\n tableName,\r\n properties,\r\n relationships,\r\n file: path.relative(rootPath, filePath),\r\n };\r\n}\r\n\r\nasync function enrichFromConfigurations(\r\n entities: EntityInfo[],\r\n infrastructurePath: string,\r\n _config: Config\r\n): Promise<void> {\r\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\r\n cwd: infrastructurePath,\r\n });\r\n\r\n for (const file of configFiles) {\r\n const content = await readText(file);\r\n\r\n // Find ToTable calls\r\n const tableMatch = content.match(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"/);\r\n if (tableMatch) {\r\n // Find which entity this configuration is for\r\n const entityMatch = content.match(/IEntityTypeConfiguration<(\\w+)>/);\r\n if (entityMatch) {\r\n const entityName = entityMatch[1];\r\n const entity = entities.find(e => e.name === entityName);\r\n if (entity) {\r\n entity.tableName = tableMatch[1];\r\n }\r\n }\r\n }\r\n\r\n // Find MaxLength constraints\r\n const maxLengthMatches = content.matchAll(/\\.Property\\s*\\(\\s*\\w+\\s*=>\\s*\\w+\\.(\\w+)\\s*\\)[\\s\\S]*?\\.HasMaxLength\\s*\\(\\s*(\\d+)\\s*\\)/g);\r\n for (const match of maxLengthMatches) {\r\n const propertyName = match[1];\r\n const maxLength = parseInt(match[2], 10);\r\n\r\n for (const entity of entities) {\r\n const property = entity.properties.find(p => p.name === propertyName);\r\n if (property) {\r\n property.maxLength = maxLength;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction mapCSharpType(csharpType: string): string {\r\n const typeMap: Record<string, string> = {\r\n 'Guid': 'uniqueidentifier',\r\n 'string': 'nvarchar',\r\n 'String': 'nvarchar',\r\n 'int': 'int',\r\n 'Int32': 'int',\r\n 'long': 'bigint',\r\n 'Int64': 'bigint',\r\n 'DateTime': 'datetime2',\r\n 'DateTimeOffset': 'datetimeoffset',\r\n 'bool': 'bit',\r\n 'Boolean': 'bit',\r\n 'decimal': 'decimal',\r\n 'Decimal': 'decimal',\r\n 'double': 'float',\r\n 'Double': 'float',\r\n 'float': 'real',\r\n 'Float': 'real',\r\n 'byte[]': 'varbinary',\r\n };\r\n\r\n // Handle nullable types\r\n const baseType = csharpType.replace('?', '');\r\n return typeMap[baseType] || 'nvarchar';\r\n}\r\n\r\nfunction formatSchema(\r\n entities: EntityInfo[],\r\n filter?: string,\r\n _config?: Config\r\n): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack Database Schema');\r\n lines.push('');\r\n\r\n if (filter) {\r\n lines.push(`> Filtered by: \\`${filter}\\``);\r\n lines.push('');\r\n }\r\n\r\n if (entities.length === 0) {\r\n lines.push('No entities found matching the criteria.');\r\n return lines.join('\\n');\r\n }\r\n\r\n // Summary\r\n lines.push('## Summary');\r\n lines.push('');\r\n lines.push(`**Total Entities**: ${entities.length}`);\r\n lines.push('');\r\n\r\n // Table list\r\n lines.push('| Entity | Table | Properties | Relationships |');\r\n lines.push('|--------|-------|------------|---------------|');\r\n for (const entity of entities) {\r\n lines.push(\r\n `| ${entity.name} | \\`${entity.tableName}\\` | ${entity.properties.length} | ${entity.relationships.length} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Detailed schema for each entity\r\n for (const entity of entities) {\r\n lines.push(`## ${entity.name}`);\r\n lines.push('');\r\n lines.push(`**Table**: \\`${entity.tableName}\\``);\r\n lines.push(`**File**: \\`${entity.file}\\``);\r\n lines.push('');\r\n\r\n // Properties\r\n lines.push('### Columns');\r\n lines.push('');\r\n lines.push('| Column | SQL Type | Nullable | Notes |');\r\n lines.push('|--------|----------|----------|-------|');\r\n\r\n for (const prop of entity.properties) {\r\n const notes: string[] = [];\r\n if (prop.isPrimaryKey) notes.push('PK');\r\n if (prop.maxLength) notes.push(`MaxLength(${prop.maxLength})`);\r\n\r\n lines.push(\r\n `| ${prop.name} | ${prop.type} | ${prop.nullable ? 'Yes' : 'No'} | ${notes.join(', ')} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Relationships\r\n if (entity.relationships.length > 0) {\r\n lines.push('### Relationships');\r\n lines.push('');\r\n lines.push('| Type | Target | Property |');\r\n lines.push('|------|--------|----------|');\r\n\r\n for (const rel of entity.relationships) {\r\n const typeIcon = rel.type === 'one-to-one' ? '1:1' :\r\n rel.type === 'one-to-many' ? '1:N' : 'N:N';\r\n lines.push(`| ${typeIcon} | ${rel.targetEntity} | ${rel.propertyName} |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Sample EF configuration\r\n lines.push('### EF Core Configuration');\r\n lines.push('');\r\n lines.push('```csharp');\r\n lines.push(`public class ${entity.name}Configuration : IEntityTypeConfiguration<${entity.name}>`);\r\n lines.push('{');\r\n lines.push(` public void Configure(EntityTypeBuilder<${entity.name}> builder)`);\r\n lines.push(' {');\r\n lines.push(` builder.ToTable(\"${entity.tableName}\");`);\r\n lines.push('');\r\n const pk = entity.properties.find(p => p.isPrimaryKey);\r\n if (pk) {\r\n lines.push(` builder.HasKey(e => e.${pk.name});`);\r\n }\r\n lines.push(' }');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n // ER Diagram (text-based)\r\n if (entities.length > 1) {\r\n lines.push('## Entity Relationships');\r\n lines.push('');\r\n lines.push('```');\r\n\r\n for (const entity of entities) {\r\n for (const rel of entity.relationships) {\r\n const arrow = rel.type === 'one-to-one' ? '──' :\r\n rel.type === 'one-to-many' ? '─<' : '>─<';\r\n lines.push(`${entity.name} ${arrow} ${rel.targetEntity}`);\r\n }\r\n }\r\n\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","#!/usr/bin/env node\n\nimport { runServer } from './server.js';\nimport { logger } from './lib/logger.js';\n\n// Handle uncaught errors\nprocess.on('uncaughtException', (error) => {\n logger.error('Uncaught exception', { error: error.message, stack: error.stack });\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('Unhandled rejection', { reason });\n process.exit(1);\n});\n\n// Start the server\nrunServer().catch((error) => {\n logger.error('Failed to start server', { error: error.message });\n process.exit(1);\n});\n"],"mappings":"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","names":["path","path","path","path","exec","promisify","execAsync","promisify","exec","path","path","path","formatResult","path","formatResult","path","path","path","endpoints","path"]}
1
+ {"version":3,"sources":["../src/server.ts","../src/lib/logger.ts","../src/config.ts","../src/utils/fs.ts","../src/types/index.ts","../src/lib/detector.ts","../src/utils/git.ts","../src/utils/dotnet.ts","../src/tools/validate-conventions.ts","../src/tools/check-migrations.ts","../src/tools/scaffold-extension.ts","../src/tools/api-docs.ts","../src/resources/conventions.ts","../src/resources/project-info.ts","../src/resources/api-endpoints.ts","../src/resources/db-schema.ts","../src/index.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\r\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\r\nimport {\r\n CallToolRequestSchema,\r\n ListToolsRequestSchema,\r\n ListResourcesRequestSchema,\r\n ReadResourceRequestSchema,\r\n} from '@modelcontextprotocol/sdk/types.js';\r\n\r\nimport { logger } from './lib/logger.js';\r\nimport { getConfig } from './config.js';\r\n\r\n// Tools\r\nimport { handleValidateConventions, validateConventionsTool } from './tools/validate-conventions.js';\r\nimport { handleCheckMigrations, checkMigrationsTool } from './tools/check-migrations.js';\r\nimport { handleScaffoldExtension, scaffoldExtensionTool } from './tools/scaffold-extension.js';\r\nimport { handleApiDocs, apiDocsTool } from './tools/api-docs.js';\r\n\r\n// Resources\r\nimport { getConventionsResource, conventionsResourceTemplate } from './resources/conventions.js';\r\nimport { getProjectInfoResource, projectInfoResourceTemplate } from './resources/project-info.js';\r\nimport { getApiEndpointsResource, apiEndpointsResourceTemplate } from './resources/api-endpoints.js';\r\nimport { getDbSchemaResource, dbSchemaResourceTemplate } from './resources/db-schema.js';\r\n\r\nexport async function createServer(): Promise<Server> {\r\n const config = await getConfig();\r\n\r\n const server = new Server(\r\n {\r\n name: 'smartstack-mcp',\r\n version: '1.0.0',\r\n },\r\n {\r\n capabilities: {\r\n tools: {},\r\n resources: {},\r\n },\r\n }\r\n );\r\n\r\n // ============================================================================\r\n // Tools Registration\r\n // ============================================================================\r\n\r\n server.setRequestHandler(ListToolsRequestSchema, async () => {\r\n logger.debug('Listing tools');\r\n return {\r\n tools: [\r\n validateConventionsTool,\r\n checkMigrationsTool,\r\n scaffoldExtensionTool,\r\n apiDocsTool,\r\n ],\r\n };\r\n });\r\n\r\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const { name, arguments: args } = request.params;\r\n const startTime = Date.now();\r\n\r\n logger.toolStart(name, args);\r\n\r\n try {\r\n let result: string;\r\n\r\n switch (name) {\r\n case 'validate_conventions':\r\n result = await handleValidateConventions(args, config);\r\n break;\r\n\r\n case 'check_migrations':\r\n result = await handleCheckMigrations(args, config);\r\n break;\r\n\r\n case 'scaffold_extension':\r\n result = await handleScaffoldExtension(args, config);\r\n break;\r\n\r\n case 'api_docs':\r\n result = await handleApiDocs(args, config);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown tool: ${name}`);\r\n }\r\n\r\n logger.toolEnd(name, true, Date.now() - startTime);\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: result,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.toolError(name, err);\r\n\r\n return {\r\n content: [\r\n {\r\n type: 'text',\r\n text: `Error: ${err.message}`,\r\n },\r\n ],\r\n isError: true,\r\n };\r\n }\r\n });\r\n\r\n // ============================================================================\r\n // Resources Registration\r\n // ============================================================================\r\n\r\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\r\n logger.debug('Listing resources');\r\n return {\r\n resources: [\r\n conventionsResourceTemplate,\r\n projectInfoResourceTemplate,\r\n apiEndpointsResourceTemplate,\r\n dbSchemaResourceTemplate,\r\n ],\r\n };\r\n });\r\n\r\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\r\n const { uri } = request.params;\r\n logger.debug('Reading resource', { uri });\r\n\r\n try {\r\n let content: string;\r\n let mimeType = 'text/markdown';\r\n\r\n if (uri === 'smartstack://conventions') {\r\n content = await getConventionsResource(config);\r\n } else if (uri === 'smartstack://project') {\r\n content = await getProjectInfoResource(config);\r\n } else if (uri.startsWith('smartstack://api/')) {\r\n const endpoint = uri.replace('smartstack://api/', '');\r\n content = await getApiEndpointsResource(config, endpoint);\r\n } else if (uri.startsWith('smartstack://schema/')) {\r\n const table = uri.replace('smartstack://schema/', '');\r\n content = await getDbSchemaResource(config, table);\r\n } else {\r\n throw new Error(`Unknown resource: ${uri}`);\r\n }\r\n\r\n return {\r\n contents: [\r\n {\r\n uri,\r\n mimeType,\r\n text: content,\r\n },\r\n ],\r\n };\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error(String(error));\r\n logger.error('Resource read failed', { uri, error: err.message });\r\n throw err;\r\n }\r\n });\r\n\r\n return server;\r\n}\r\n\r\nexport async function runServer(): Promise<void> {\r\n logger.info('Starting SmartStack MCP Server...');\r\n\r\n const server = await createServer();\r\n const transport = new StdioServerTransport();\r\n\r\n await server.connect(transport);\r\n\r\n logger.info('SmartStack MCP Server running on stdio');\r\n}\r\n","/**\r\n * Logger for MCP Server\r\n * IMPORTANT: All output goes to stderr to avoid corrupting stdio MCP transport\r\n */\r\n\r\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\r\n\r\ninterface LogEntry {\r\n timestamp: string;\r\n level: LogLevel;\r\n message: string;\r\n data?: unknown;\r\n}\r\n\r\nclass Logger {\r\n private level: LogLevel = 'info';\r\n private readonly levels: Record<LogLevel, number> = {\r\n debug: 0,\r\n info: 1,\r\n warn: 2,\r\n error: 3,\r\n };\r\n\r\n setLevel(level: LogLevel): void {\r\n this.level = level;\r\n }\r\n\r\n private shouldLog(level: LogLevel): boolean {\r\n return this.levels[level] >= this.levels[this.level];\r\n }\r\n\r\n private formatEntry(level: LogLevel, message: string, data?: unknown): string {\r\n const entry: LogEntry = {\r\n timestamp: new Date().toISOString(),\r\n level,\r\n message,\r\n ...(data !== undefined && { data }),\r\n };\r\n return JSON.stringify(entry);\r\n }\r\n\r\n debug(message: string, data?: unknown): void {\r\n if (this.shouldLog('debug')) {\r\n console.error(this.formatEntry('debug', message, data));\r\n }\r\n }\r\n\r\n info(message: string, data?: unknown): void {\r\n if (this.shouldLog('info')) {\r\n console.error(this.formatEntry('info', message, data));\r\n }\r\n }\r\n\r\n warn(message: string, data?: unknown): void {\r\n if (this.shouldLog('warn')) {\r\n console.error(this.formatEntry('warn', message, data));\r\n }\r\n }\r\n\r\n error(message: string, data?: unknown): void {\r\n if (this.shouldLog('error')) {\r\n console.error(this.formatEntry('error', message, data));\r\n }\r\n }\r\n\r\n // Tool execution logging\r\n toolStart(toolName: string, args: unknown): void {\r\n this.info(`Tool started: ${toolName}`, { args });\r\n }\r\n\r\n toolEnd(toolName: string, success: boolean, duration?: number): void {\r\n this.info(`Tool completed: ${toolName}`, { success, duration });\r\n }\r\n\r\n toolError(toolName: string, error: Error): void {\r\n this.error(`Tool failed: ${toolName}`, {\r\n error: error.message,\r\n stack: error.stack\r\n });\r\n }\r\n}\r\n\r\nexport const logger = new Logger();\r\n\r\n// Set log level from environment\r\nconst envLevel = process.env.LOG_LEVEL as LogLevel | undefined;\r\nif (envLevel && ['debug', 'info', 'warn', 'error'].includes(envLevel)) {\r\n logger.setLevel(envLevel);\r\n}\r\n","import path from 'path';\r\nimport { fileExists, readJson } from './utils/fs.js';\r\nimport { logger } from './lib/logger.js';\r\nimport type { Config } from './types/index.js';\r\n\r\n// Default configuration\r\nconst defaultConfig: Config = {\r\n version: '1.0.0',\r\n smartstack: {\r\n projectPath: process.env.SMARTSTACK_PROJECT_PATH || 'D:/SmartStack.app/02-Develop',\r\n apiUrl: process.env.SMARTSTACK_API_URL || 'https://localhost:5001',\r\n apiEnabled: process.env.SMARTSTACK_API_ENABLED !== 'false',\r\n },\r\n conventions: {\r\n schemas: {\r\n platform: 'core',\r\n extensions: 'extensions',\r\n },\r\n tablePrefixes: [\r\n 'auth_', 'nav_', 'usr_', 'ai_', 'cfg_', 'wkf_',\r\n 'support_', 'entra_', 'ref_', 'loc_', 'lic_'\r\n ],\r\n migrationFormat: '{context}_v{version}_{sequence}_{Description}',\r\n namespaces: {\r\n domain: 'SmartStack.Domain',\r\n application: 'SmartStack.Application',\r\n infrastructure: 'SmartStack.Infrastructure',\r\n api: 'SmartStack.Api',\r\n },\r\n servicePattern: {\r\n interface: 'I{Name}Service',\r\n implementation: '{Name}Service',\r\n },\r\n },\r\n efcore: {\r\n contexts: [\r\n {\r\n name: 'ApplicationDbContext',\r\n projectPath: 'auto-detect',\r\n migrationsFolder: 'Migrations',\r\n },\r\n ],\r\n validation: {\r\n checkModelSnapshot: true,\r\n checkMigrationOrder: true,\r\n requireBuildSuccess: true,\r\n },\r\n },\r\n scaffolding: {\r\n outputPath: 'auto-detect',\r\n templates: {\r\n service: 'templates/service-extension.cs.hbs',\r\n entity: 'templates/entity-extension.cs.hbs',\r\n controller: 'templates/controller.cs.hbs',\r\n component: 'templates/component.tsx.hbs',\r\n },\r\n },\r\n};\r\n\r\nlet cachedConfig: Config | null = null;\r\n\r\n/**\r\n * Get the configuration, loading from file if available\r\n */\r\nexport async function getConfig(): Promise<Config> {\r\n if (cachedConfig) {\r\n return cachedConfig;\r\n }\r\n\r\n // Try to load from config file\r\n const configPath = path.join(process.cwd(), 'config', 'default-config.json');\r\n\r\n if (await fileExists(configPath)) {\r\n try {\r\n const fileConfig = await readJson<Partial<Config>>(configPath);\r\n cachedConfig = mergeConfig(defaultConfig, fileConfig);\r\n logger.info('Configuration loaded from file', { path: configPath });\r\n } catch (error) {\r\n logger.warn('Failed to load config file, using defaults', { error });\r\n cachedConfig = defaultConfig;\r\n }\r\n } else {\r\n logger.debug('No config file found, using defaults');\r\n cachedConfig = defaultConfig;\r\n }\r\n\r\n // Override with environment variables\r\n if (process.env.SMARTSTACK_PROJECT_PATH) {\r\n cachedConfig.smartstack.projectPath = process.env.SMARTSTACK_PROJECT_PATH;\r\n }\r\n if (process.env.SMARTSTACK_API_URL) {\r\n cachedConfig.smartstack.apiUrl = process.env.SMARTSTACK_API_URL;\r\n }\r\n\r\n return cachedConfig;\r\n}\r\n\r\n/**\r\n * Deep merge configuration objects\r\n */\r\nfunction mergeConfig(base: Config, override: Partial<Config>): Config {\r\n return {\r\n ...base,\r\n ...override,\r\n smartstack: {\r\n ...base.smartstack,\r\n ...override.smartstack,\r\n },\r\n conventions: {\r\n ...base.conventions,\r\n ...override.conventions,\r\n schemas: {\r\n ...base.conventions.schemas,\r\n ...override.conventions?.schemas,\r\n },\r\n namespaces: {\r\n ...base.conventions.namespaces,\r\n ...override.conventions?.namespaces,\r\n },\r\n servicePattern: {\r\n ...base.conventions.servicePattern,\r\n ...override.conventions?.servicePattern,\r\n },\r\n },\r\n efcore: {\r\n ...base.efcore,\r\n ...override.efcore,\r\n contexts: override.efcore?.contexts || base.efcore.contexts,\r\n validation: {\r\n ...base.efcore.validation,\r\n ...override.efcore?.validation,\r\n },\r\n },\r\n scaffolding: {\r\n ...base.scaffolding,\r\n ...override.scaffolding,\r\n templates: {\r\n ...base.scaffolding.templates,\r\n ...override.scaffolding?.templates,\r\n },\r\n },\r\n };\r\n}\r\n\r\n/**\r\n * Get SmartStack project path\r\n */\r\nexport function getProjectPath(config: Config): string {\r\n return config.smartstack.projectPath;\r\n}\r\n\r\n/**\r\n * Clear cached configuration (for testing)\r\n */\r\nexport function clearConfigCache(): void {\r\n cachedConfig = null;\r\n}\r\n","import fs from 'fs-extra';\r\nimport path from 'path';\r\nimport { glob } from 'glob';\r\n\r\n/**\r\n * Check if a file exists\r\n */\r\nexport async function fileExists(filePath: string): Promise<boolean> {\r\n try {\r\n const stat = await fs.stat(filePath);\r\n return stat.isFile();\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Check if a directory exists\r\n */\r\nexport async function directoryExists(dirPath: string): Promise<boolean> {\r\n try {\r\n const stat = await fs.stat(dirPath);\r\n return stat.isDirectory();\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Ensure a directory exists (create if needed)\r\n */\r\nexport async function ensureDirectory(dirPath: string): Promise<void> {\r\n await fs.ensureDir(dirPath);\r\n}\r\n\r\n/**\r\n * Read a JSON file with type safety\r\n */\r\nexport async function readJson<T>(filePath: string): Promise<T> {\r\n const content = await fs.readFile(filePath, 'utf-8');\r\n return JSON.parse(content) as T;\r\n}\r\n\r\n/**\r\n * Write a JSON file\r\n */\r\nexport async function writeJson<T>(filePath: string, data: T): Promise<void> {\r\n await fs.ensureDir(path.dirname(filePath));\r\n await fs.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\r\n}\r\n\r\n/**\r\n * Read a text file\r\n */\r\nexport async function readText(filePath: string): Promise<string> {\r\n return fs.readFile(filePath, 'utf-8');\r\n}\r\n\r\n/**\r\n * Write a text file\r\n */\r\nexport async function writeText(filePath: string, content: string): Promise<void> {\r\n await fs.ensureDir(path.dirname(filePath));\r\n await fs.writeFile(filePath, content, 'utf-8');\r\n}\r\n\r\n/**\r\n * Copy a file\r\n */\r\nexport async function copyFile(src: string, dest: string): Promise<void> {\r\n await fs.ensureDir(path.dirname(dest));\r\n await fs.copy(src, dest);\r\n}\r\n\r\n/**\r\n * Remove a file\r\n */\r\nexport async function removeFile(filePath: string): Promise<void> {\r\n await fs.remove(filePath);\r\n}\r\n\r\n/**\r\n * Remove a directory\r\n */\r\nexport async function removeDirectory(dirPath: string): Promise<void> {\r\n await fs.remove(dirPath);\r\n}\r\n\r\n/**\r\n * Find files matching a glob pattern\r\n */\r\nexport async function findFiles(\r\n pattern: string,\r\n options: { cwd?: string; ignore?: string[] } = {}\r\n): Promise<string[]> {\r\n const { cwd = process.cwd(), ignore = [] } = options;\r\n\r\n const files = await glob(pattern, {\r\n cwd,\r\n ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', ...ignore],\r\n absolute: true,\r\n nodir: true,\r\n });\r\n\r\n return files;\r\n}\r\n\r\n/**\r\n * Find directories matching a glob pattern\r\n */\r\nexport async function findDirectories(\r\n pattern: string,\r\n options: { cwd?: string; ignore?: string[] } = {}\r\n): Promise<string[]> {\r\n const { cwd = process.cwd(), ignore = [] } = options;\r\n\r\n const dirs = await glob(pattern, {\r\n cwd,\r\n ignore: ['**/node_modules/**', '**/bin/**', '**/obj/**', ...ignore],\r\n absolute: true,\r\n });\r\n\r\n // Filter to only directories\r\n const results: string[] = [];\r\n for (const dir of dirs) {\r\n if (await directoryExists(dir)) {\r\n results.push(dir);\r\n }\r\n }\r\n\r\n return results;\r\n}\r\n\r\n/**\r\n * Get relative path from base\r\n */\r\nexport function relativePath(from: string, to: string): string {\r\n return path.relative(from, to).replace(/\\\\/g, '/');\r\n}\r\n\r\n/**\r\n * Normalize path separators\r\n */\r\nexport function normalizePath(filePath: string): string {\r\n return filePath.replace(/\\\\/g, '/');\r\n}\r\n","import { z } from 'zod';\r\n\r\n// ============================================================================\r\n// Configuration Schemas\r\n// ============================================================================\r\n\r\nexport const SmartStackConfigSchema = z.object({\r\n projectPath: z.string(),\r\n apiUrl: z.string().url().optional(),\r\n apiEnabled: z.boolean().default(true),\r\n});\r\n\r\nexport const ConventionsConfigSchema = z.object({\r\n schemas: z.object({\r\n platform: z.string().default('core'),\r\n extensions: z.string().default('extensions'),\r\n }),\r\n tablePrefixes: z.array(z.string()).default([\r\n 'auth_', 'nav_', 'usr_', 'ai_', 'cfg_', 'wkf_',\r\n 'support_', 'entra_', 'ref_', 'loc_', 'lic_'\r\n ]),\r\n migrationFormat: z.string().default('{context}_v{version}_{sequence}_{Description}'),\r\n namespaces: z.object({\r\n domain: z.string(),\r\n application: z.string(),\r\n infrastructure: z.string(),\r\n api: z.string(),\r\n }),\r\n servicePattern: z.object({\r\n interface: z.string().default('I{Name}Service'),\r\n implementation: z.string().default('{Name}Service'),\r\n }),\r\n});\r\n\r\nexport const EfCoreContextSchema = z.object({\r\n name: z.string(),\r\n projectPath: z.string(),\r\n migrationsFolder: z.string().default('Migrations'),\r\n});\r\n\r\nexport const EfCoreConfigSchema = z.object({\r\n contexts: z.array(EfCoreContextSchema),\r\n validation: z.object({\r\n checkModelSnapshot: z.boolean().default(true),\r\n checkMigrationOrder: z.boolean().default(true),\r\n requireBuildSuccess: z.boolean().default(true),\r\n }),\r\n});\r\n\r\nexport const ScaffoldingConfigSchema = z.object({\r\n outputPath: z.string(),\r\n templates: z.object({\r\n service: z.string(),\r\n entity: z.string(),\r\n controller: z.string(),\r\n component: z.string(),\r\n }),\r\n});\r\n\r\nexport const ConfigSchema = z.object({\r\n version: z.string(),\r\n smartstack: SmartStackConfigSchema,\r\n conventions: ConventionsConfigSchema,\r\n efcore: EfCoreConfigSchema,\r\n scaffolding: ScaffoldingConfigSchema,\r\n});\r\n\r\nexport type Config = z.infer<typeof ConfigSchema>;\r\nexport type SmartStackConfig = z.infer<typeof SmartStackConfigSchema>;\r\nexport type ConventionsConfig = z.infer<typeof ConventionsConfigSchema>;\r\nexport type EfCoreConfig = z.infer<typeof EfCoreConfigSchema>;\r\n\r\n// ============================================================================\r\n// Tool Input Schemas\r\n// ============================================================================\r\n\r\nexport const ValidateConventionsInputSchema = z.object({\r\n path: z.string().optional().describe('Project path to validate (default: SmartStack.app path)'),\r\n checks: z.array(z.enum(['tables', 'migrations', 'services', 'namespaces', 'all']))\r\n .default(['all'])\r\n .describe('Types of checks to perform'),\r\n});\r\n\r\nexport const CheckMigrationsInputSchema = z.object({\r\n projectPath: z.string().optional().describe('EF Core project path'),\r\n branch: z.string().optional().describe('Git branch to check (default: current)'),\r\n compareBranch: z.string().optional().describe('Branch to compare against'),\r\n});\r\n\r\nexport const ScaffoldExtensionInputSchema = z.object({\r\n type: z.enum(['service', 'entity', 'controller', 'component'])\r\n .describe('Type of extension to scaffold'),\r\n name: z.string().describe('Name of the extension (e.g., \"UserProfile\", \"Order\")'),\r\n options: z.object({\r\n namespace: z.string().optional().describe('Custom namespace'),\r\n baseEntity: z.string().optional().describe('Base entity to extend (for entity type)'),\r\n methods: z.array(z.string()).optional().describe('Methods to generate (for service type)'),\r\n outputPath: z.string().optional().describe('Custom output path'),\r\n }).optional(),\r\n});\r\n\r\nexport const ApiDocsInputSchema = z.object({\r\n endpoint: z.string().optional().describe('Filter by endpoint path (e.g., \"/api/users\")'),\r\n format: z.enum(['markdown', 'json', 'openapi']).default('markdown')\r\n .describe('Output format'),\r\n controller: z.string().optional().describe('Filter by controller name'),\r\n});\r\n\r\nexport type ValidateConventionsInput = z.infer<typeof ValidateConventionsInputSchema>;\r\nexport type CheckMigrationsInput = z.infer<typeof CheckMigrationsInputSchema>;\r\nexport type ScaffoldExtensionInput = z.infer<typeof ScaffoldExtensionInputSchema>;\r\nexport type ApiDocsInput = z.infer<typeof ApiDocsInputSchema>;\r\n\r\n// ============================================================================\r\n// Result Types\r\n// ============================================================================\r\n\r\nexport interface ValidationResult {\r\n valid: boolean;\r\n errors: ValidationIssue[];\r\n warnings: ValidationIssue[];\r\n summary: string;\r\n}\r\n\r\nexport interface ValidationIssue {\r\n type: 'error' | 'warning';\r\n category: string;\r\n message: string;\r\n file?: string;\r\n line?: number;\r\n suggestion?: string;\r\n}\r\n\r\nexport interface MigrationCheckResult {\r\n hasConflicts: boolean;\r\n migrations: MigrationInfo[];\r\n conflicts: MigrationConflict[];\r\n suggestions: string[];\r\n}\r\n\r\nexport interface MigrationInfo {\r\n name: string;\r\n context: string; // DbContext name (core, extensions, etc.)\r\n version: string; // Semver version (1.0.0, 1.2.0, etc.)\r\n sequence: string; // Sequence number (001, 002, etc.)\r\n description: string;\r\n file: string;\r\n applied: boolean;\r\n}\r\n\r\nexport interface MigrationConflict {\r\n type: 'order' | 'snapshot' | 'dependency' | 'naming';\r\n description: string;\r\n files: string[];\r\n resolution: string;\r\n}\r\n\r\nexport interface ScaffoldResult {\r\n success: boolean;\r\n files: GeneratedFile[];\r\n instructions: string[];\r\n}\r\n\r\nexport interface GeneratedFile {\r\n path: string;\r\n content: string;\r\n type: 'created' | 'modified';\r\n}\r\n\r\nexport interface ProjectInfo {\r\n name: string;\r\n version: string;\r\n isGitRepo: boolean;\r\n currentBranch?: string;\r\n hasDotNet: boolean;\r\n hasEfCore: boolean;\r\n hasReact: boolean;\r\n csprojFiles: string[];\r\n dbContextName?: string;\r\n}\r\n","import path from 'path';\r\nimport { directoryExists, fileExists, findFiles, readText } from '../utils/fs.js';\r\nimport { isGitRepo, getCurrentBranch } from '../utils/git.js';\r\nimport { findCsprojFiles, hasEfCore, findDbContextName, getTargetFramework } from '../utils/dotnet.js';\r\nimport { logger } from './logger.js';\r\nimport type { ProjectInfo } from '../types/index.js';\r\n\r\n/**\r\n * Detect project information for SmartStack\r\n */\r\nexport async function detectProject(projectPath: string): Promise<ProjectInfo> {\r\n logger.debug('Detecting project info', { path: projectPath });\r\n\r\n const info: ProjectInfo = {\r\n name: path.basename(projectPath),\r\n version: '0.0.0',\r\n isGitRepo: false,\r\n hasDotNet: false,\r\n hasEfCore: false,\r\n hasReact: false,\r\n csprojFiles: [],\r\n };\r\n\r\n // Check if directory exists\r\n if (!(await directoryExists(projectPath))) {\r\n logger.warn('Project path does not exist', { path: projectPath });\r\n return info;\r\n }\r\n\r\n // Git detection\r\n info.isGitRepo = await isGitRepo(projectPath);\r\n if (info.isGitRepo) {\r\n info.currentBranch = await getCurrentBranch(projectPath) || undefined;\r\n }\r\n\r\n // .NET detection\r\n info.csprojFiles = await findCsprojFiles(projectPath);\r\n info.hasDotNet = info.csprojFiles.length > 0;\r\n\r\n // EF Core detection\r\n if (info.hasDotNet) {\r\n for (const csproj of info.csprojFiles) {\r\n if (await hasEfCore(csproj)) {\r\n info.hasEfCore = true;\r\n info.dbContextName = await findDbContextName(path.dirname(csproj)) || undefined;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n // React detection\r\n const packageJsonPath = path.join(projectPath, 'web', 'smartstack-web', 'package.json');\r\n if (await fileExists(packageJsonPath)) {\r\n try {\r\n const packageJson = JSON.parse(await readText(packageJsonPath));\r\n info.hasReact = !!packageJson.dependencies?.react;\r\n info.version = packageJson.version || info.version;\r\n } catch {\r\n // Ignore parse errors\r\n }\r\n }\r\n\r\n // Try to get version from main csproj\r\n if (info.csprojFiles.length > 0) {\r\n const mainCsproj = info.csprojFiles.find(f => f.includes('SmartStack.Api'))\r\n || info.csprojFiles[0];\r\n const targetFramework = await getTargetFramework(mainCsproj);\r\n if (targetFramework) {\r\n logger.debug('Target framework detected', { framework: targetFramework });\r\n }\r\n }\r\n\r\n logger.info('Project detected', info);\r\n return info;\r\n}\r\n\r\n/**\r\n * Find SmartStack project structure\r\n */\r\nexport interface SmartStackStructure {\r\n root: string;\r\n domain?: string;\r\n application?: string;\r\n infrastructure?: string;\r\n api?: string;\r\n web?: string;\r\n migrations?: string;\r\n}\r\n\r\nexport async function findSmartStackStructure(projectPath: string): Promise<SmartStackStructure> {\r\n const structure: SmartStackStructure = { root: projectPath };\r\n\r\n const csprojFiles = await findCsprojFiles(projectPath);\r\n\r\n for (const csproj of csprojFiles) {\r\n const projectName = path.basename(csproj, '.csproj').toLowerCase();\r\n const projectDir = path.dirname(csproj);\r\n\r\n if (projectName.includes('domain')) {\r\n structure.domain = projectDir;\r\n } else if (projectName.includes('application')) {\r\n structure.application = projectDir;\r\n } else if (projectName.includes('infrastructure')) {\r\n structure.infrastructure = projectDir;\r\n } else if (projectName.includes('api')) {\r\n structure.api = projectDir;\r\n }\r\n }\r\n\r\n // Find migrations folder\r\n if (structure.infrastructure) {\r\n const migrationsPath = path.join(structure.infrastructure, 'Persistence', 'Migrations');\r\n if (await directoryExists(migrationsPath)) {\r\n structure.migrations = migrationsPath;\r\n }\r\n }\r\n\r\n // Find web folder\r\n const webPath = path.join(projectPath, 'web', 'smartstack-web');\r\n if (await directoryExists(webPath)) {\r\n structure.web = webPath;\r\n }\r\n\r\n return structure;\r\n}\r\n\r\n/**\r\n * Find all entity files in domain layer\r\n */\r\nexport async function findEntityFiles(domainPath: string): Promise<string[]> {\r\n const entityFiles = await findFiles('**/*.cs', { cwd: domainPath });\r\n\r\n // Filter to likely entity files (classes with Id property)\r\n const entities: string[] = [];\r\n\r\n for (const file of entityFiles) {\r\n const content = await readText(file);\r\n // Simple heuristic: file contains a class with Id property\r\n if (content.match(/public\\s+(?:class|record)\\s+\\w+/) &&\r\n content.match(/public\\s+(?:int|long|Guid|string)\\s+Id\\s*\\{/)) {\r\n entities.push(file);\r\n }\r\n }\r\n\r\n return entities;\r\n}\r\n\r\n/**\r\n * Find all service interfaces in application layer\r\n */\r\nexport async function findServiceInterfaces(applicationPath: string): Promise<string[]> {\r\n const files = await findFiles('**/I*Service.cs', { cwd: applicationPath });\r\n return files;\r\n}\r\n\r\n/**\r\n * Find all controller files in API layer\r\n */\r\nexport async function findControllerFiles(apiPath: string): Promise<string[]> {\r\n const files = await findFiles('**/*Controller.cs', { cwd: apiPath });\r\n return files;\r\n}\r\n","import { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { directoryExists } from './fs.js';\r\nimport path from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n/**\r\n * Execute a git command\r\n */\r\nexport async function git(command: string, cwd?: string): Promise<string> {\r\n const options = cwd ? { cwd } : {};\r\n const { stdout } = await execAsync(`git ${command}`, options);\r\n return stdout.trim();\r\n}\r\n\r\n/**\r\n * Check if directory is a git repository\r\n */\r\nexport async function isGitRepo(cwd?: string): Promise<boolean> {\r\n const gitDir = path.join(cwd || process.cwd(), '.git');\r\n return directoryExists(gitDir);\r\n}\r\n\r\n/**\r\n * Get current branch name\r\n */\r\nexport async function getCurrentBranch(cwd?: string): Promise<string | null> {\r\n try {\r\n return await git('branch --show-current', cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if working directory is clean\r\n */\r\nexport async function isClean(cwd?: string): Promise<boolean> {\r\n try {\r\n const status = await git('status --porcelain', cwd);\r\n return status === '';\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get list of changed files\r\n */\r\nexport async function getChangedFiles(cwd?: string): Promise<string[]> {\r\n try {\r\n const status = await git('status --porcelain', cwd);\r\n if (!status) return [];\r\n\r\n return status.split('\\n')\r\n .map(line => line.substring(3).trim())\r\n .filter(Boolean);\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get commit count between two refs\r\n */\r\nexport async function getCommitCount(\r\n from: string,\r\n to: string,\r\n cwd?: string\r\n): Promise<number> {\r\n try {\r\n const result = await git(`rev-list --count ${from}..${to}`, cwd);\r\n return parseInt(result, 10);\r\n } catch {\r\n return 0;\r\n }\r\n}\r\n\r\n/**\r\n * Get latest tag\r\n */\r\nexport async function getLatestTag(cwd?: string): Promise<string | null> {\r\n try {\r\n return await git('describe --tags --abbrev=0', cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Check if branch exists\r\n */\r\nexport async function branchExists(branch: string, cwd?: string): Promise<boolean> {\r\n try {\r\n await git(`rev-parse --verify ${branch}`, cwd);\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get list of all branches\r\n */\r\nexport async function getBranches(cwd?: string): Promise<string[]> {\r\n try {\r\n const result = await git('branch -a', cwd);\r\n return result.split('\\n')\r\n .map(line => line.replace(/^\\*?\\s+/, '').trim())\r\n .filter(Boolean);\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get file content from a specific branch\r\n */\r\nexport async function getFileFromBranch(\r\n branch: string,\r\n filePath: string,\r\n cwd?: string\r\n): Promise<string | null> {\r\n try {\r\n return await git(`show ${branch}:${filePath}`, cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get diff between branches for a specific file\r\n */\r\nexport async function getDiff(\r\n fromBranch: string,\r\n toBranch: string,\r\n filePath?: string,\r\n cwd?: string\r\n): Promise<string> {\r\n try {\r\n const pathArg = filePath ? ` -- ${filePath}` : '';\r\n return await git(`diff ${fromBranch}...${toBranch}${pathArg}`, cwd);\r\n } catch {\r\n return '';\r\n }\r\n}\r\n\r\n/**\r\n * Get remote URL\r\n */\r\nexport async function getRemoteUrl(remote: string = 'origin', cwd?: string): Promise<string | null> {\r\n try {\r\n return await git(`remote get-url ${remote}`, cwd);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n","import { exec } from 'child_process';\r\nimport { promisify } from 'util';\r\nimport { findFiles, readText } from './fs.js';\r\nimport path from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\n/**\r\n * Execute a dotnet command\r\n */\r\nexport async function dotnet(command: string, cwd?: string): Promise<string> {\r\n const options = cwd ? { cwd } : {};\r\n const { stdout } = await execAsync(`dotnet ${command}`, options);\r\n return stdout.trim();\r\n}\r\n\r\n/**\r\n * Check if dotnet CLI is available\r\n */\r\nexport async function isDotnetAvailable(): Promise<boolean> {\r\n try {\r\n await execAsync('dotnet --version');\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Get dotnet version\r\n */\r\nexport async function getDotnetVersion(): Promise<string | null> {\r\n try {\r\n return await dotnet('--version');\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Find all .csproj files in a directory\r\n */\r\nexport async function findCsprojFiles(cwd?: string): Promise<string[]> {\r\n return findFiles('**/*.csproj', { cwd: cwd || process.cwd() });\r\n}\r\n\r\n/**\r\n * Check if a project has EF Core\r\n */\r\nexport async function hasEfCore(csprojPath: string): Promise<boolean> {\r\n try {\r\n const content = await readText(csprojPath);\r\n return content.includes('Microsoft.EntityFrameworkCore');\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Extract DbContext name from csproj or code files\r\n */\r\nexport async function findDbContextName(projectPath: string): Promise<string | null> {\r\n try {\r\n // Search for DbContext class definitions\r\n const csFiles = await findFiles('**/*.cs', { cwd: projectPath });\r\n\r\n for (const file of csFiles) {\r\n const content = await readText(file);\r\n // Look for class that extends DbContext\r\n const match = content.match(/class\\s+(\\w+)\\s*:\\s*(?:\\w+,\\s*)*DbContext/);\r\n if (match) {\r\n return match[1];\r\n }\r\n }\r\n\r\n return null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * List EF Core migrations\r\n */\r\nexport async function listMigrations(\r\n projectPath: string,\r\n context?: string\r\n): Promise<string[]> {\r\n try {\r\n const contextArg = context ? `--context ${context}` : '';\r\n const result = await dotnet(`ef migrations list ${contextArg}`, projectPath);\r\n\r\n return result.split('\\n')\r\n .filter(line => line && !line.startsWith('Build') && !line.includes('...'))\r\n .map(line => line.trim());\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get pending migrations (not applied to database)\r\n */\r\nexport async function getPendingMigrations(\r\n projectPath: string,\r\n context?: string\r\n): Promise<string[]> {\r\n try {\r\n const contextArg = context ? `--context ${context}` : '';\r\n const result = await dotnet(`ef migrations list ${contextArg} --pending`, projectPath);\r\n\r\n return result.split('\\n')\r\n .filter(line => line && !line.startsWith('Build') && !line.includes('...'))\r\n .map(line => line.trim());\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Build a .NET project\r\n */\r\nexport async function buildProject(projectPath: string): Promise<{ success: boolean; output: string }> {\r\n try {\r\n const output = await dotnet('build --no-restore', projectPath);\r\n return { success: true, output };\r\n } catch (error) {\r\n const err = error as { stdout?: string; stderr?: string };\r\n return {\r\n success: false,\r\n output: err.stdout || err.stderr || 'Build failed'\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Parse csproj XML to extract package references\r\n */\r\nexport async function getPackageReferences(csprojPath: string): Promise<Array<{ name: string; version: string }>> {\r\n try {\r\n const content = await readText(csprojPath);\r\n const packages: Array<{ name: string; version: string }> = [];\r\n\r\n const regex = /<PackageReference\\s+Include=\"([^\"]+)\"\\s+Version=\"([^\"]+)\"/g;\r\n let match;\r\n\r\n while ((match = regex.exec(content)) !== null) {\r\n packages.push({\r\n name: match[1],\r\n version: match[2],\r\n });\r\n }\r\n\r\n return packages;\r\n } catch {\r\n return [];\r\n }\r\n}\r\n\r\n/**\r\n * Get target framework from csproj\r\n */\r\nexport async function getTargetFramework(csprojPath: string): Promise<string | null> {\r\n try {\r\n const content = await readText(csprojPath);\r\n const match = content.match(/<TargetFramework>([^<]+)<\\/TargetFramework>/);\r\n return match ? match[1] : null;\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\n/**\r\n * Get project name from csproj path\r\n */\r\nexport function getProjectName(csprojPath: string): string {\r\n return path.basename(csprojPath, '.csproj');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport { ValidateConventionsInputSchema, type Config, type ValidationResult } from '../types/index.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const validateConventionsTool: Tool = {\r\n name: 'validate_conventions',\r\n description: 'Validate AtlasHub/SmartStack conventions: SQL schemas (core/extensions), domain table prefixes (auth_, nav_, ai_, etc.), migration naming ({context}_v{version}_{sequence}_*), service interfaces (I*Service), namespace structure',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n path: {\r\n type: 'string',\r\n description: 'Project path to validate (default: SmartStack.app path from config)',\r\n },\r\n checks: {\r\n type: 'array',\r\n items: {\r\n type: 'string',\r\n enum: ['tables', 'migrations', 'services', 'namespaces', 'all'],\r\n },\r\n description: 'Types of checks to perform',\r\n default: ['all'],\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport async function handleValidateConventions(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ValidateConventionsInputSchema.parse(args);\r\n const projectPath = input.path || config.smartstack.projectPath;\r\n const checks = input.checks.includes('all')\r\n ? ['tables', 'migrations', 'services', 'namespaces']\r\n : input.checks;\r\n\r\n logger.info('Validating conventions', { projectPath, checks });\r\n\r\n const result: ValidationResult = {\r\n valid: true,\r\n errors: [],\r\n warnings: [],\r\n summary: '',\r\n };\r\n\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n // Run selected checks\r\n if (checks.includes('tables')) {\r\n await validateTablePrefixes(structure, config, result);\r\n }\r\n\r\n if (checks.includes('migrations')) {\r\n await validateMigrationNaming(structure, config, result);\r\n }\r\n\r\n if (checks.includes('services')) {\r\n await validateServiceInterfaces(structure, config, result);\r\n }\r\n\r\n if (checks.includes('namespaces')) {\r\n await validateNamespaces(structure, config, result);\r\n }\r\n\r\n // Update validity\r\n result.valid = result.errors.length === 0;\r\n\r\n // Generate summary\r\n result.summary = generateSummary(result, checks);\r\n\r\n return formatResult(result);\r\n}\r\n\r\nasync function validateTablePrefixes(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.infrastructure) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: 'Infrastructure project not found, skipping table validation',\r\n });\r\n return;\r\n }\r\n\r\n // Find EF Core configuration files\r\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\r\n cwd: structure.infrastructure,\r\n });\r\n\r\n const validSchemas = [config.conventions.schemas.platform, config.conventions.schemas.extensions];\r\n const validPrefixes = config.conventions.tablePrefixes;\r\n\r\n // Map SchemaConstants to actual values\r\n const schemaConstantsMap: Record<string, string> = {\r\n 'SchemaConstants.Core': config.conventions.schemas.platform,\r\n 'SchemaConstants.Extensions': config.conventions.schemas.extensions,\r\n };\r\n\r\n for (const file of configFiles) {\r\n const content = await readText(file);\r\n\r\n // Match ToTable with string schema: .ToTable(\"tableName\", \"schemaName\")\r\n const tableWithStringSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*\"([^\"]+)\"\\s*\\)/g);\r\n\r\n for (const match of tableWithStringSchemaMatches) {\r\n const tableName = match[1];\r\n const schemaName = match[2];\r\n\r\n // Validate schema\r\n if (!validSchemas.includes(schemaName)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" uses invalid schema \"${schemaName}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Use schema \"${config.conventions.schemas.platform}\" for SmartStack tables or \"${config.conventions.schemas.extensions}\" for client extensions`,\r\n });\r\n }\r\n\r\n // Validate table prefix (must have a domain prefix)\r\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\r\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\r\n });\r\n }\r\n }\r\n\r\n // Match ToTable with SchemaConstants: .ToTable(\"tableName\", SchemaConstants.Core)\r\n const tableWithConstantSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(SchemaConstants\\.\\w+)\\s*\\)/g);\r\n\r\n for (const match of tableWithConstantSchemaMatches) {\r\n const tableName = match[1];\r\n const schemaConstant = match[2];\r\n const resolvedSchema = schemaConstantsMap[schemaConstant];\r\n\r\n // Validate schema constant is known\r\n if (!resolvedSchema) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" uses unknown schema constant \"${schemaConstant}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Use SchemaConstants.Core for SmartStack tables or SchemaConstants.Extensions for client extensions`,\r\n });\r\n }\r\n\r\n // Validate table prefix (must have a domain prefix)\r\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\r\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\r\n });\r\n }\r\n }\r\n\r\n // Check for ToTable without schema (old format) - but exclude lines with SchemaConstants\r\n const tableWithoutSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*\\)(?!\\s*,)/g);\r\n\r\n for (const match of tableWithoutSchemaMatches) {\r\n const tableName = match[1];\r\n if (!tableName.startsWith('__')) { // Ignore EF migrations history\r\n result.errors.push({\r\n type: 'error',\r\n category: 'tables',\r\n message: `Table \"${tableName}\" is missing schema specification`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Add schema: .ToTable(\"${tableName}\", SchemaConstants.Core)`,\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function validateMigrationNaming(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n _config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.migrations) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'migrations',\r\n message: 'Migrations folder not found, skipping migration validation',\r\n });\r\n return;\r\n }\r\n\r\n const migrationFiles = await findFiles('*.cs', { cwd: structure.migrations });\r\n\r\n // Expected format: {context}_v{version}_{sequence}_{Description}.cs\r\n // Example: core_v1.0.0_001_CreateAuthUsers.cs\r\n const migrationPattern = /^(\\w+)_v(\\d+\\.\\d+\\.\\d+)_(\\d{3})_(.+)\\.cs$/;\r\n const designerPattern = /\\.Designer\\.cs$/;\r\n\r\n for (const file of migrationFiles) {\r\n const fileName = path.basename(file);\r\n\r\n // Skip designer files and snapshot\r\n if (designerPattern.test(fileName) || fileName.includes('ModelSnapshot')) {\r\n continue;\r\n }\r\n\r\n if (!migrationPattern.test(fileName)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'migrations',\r\n message: `Migration \"${fileName}\" does not follow naming convention`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Expected format: {context}_v{version}_{sequence}_{Description}.cs (e.g., core_v1.0.0_001_CreateAuthUsers.cs)`,\r\n });\r\n }\r\n }\r\n\r\n // Check version and sequence order\r\n const orderedMigrations = migrationFiles\r\n .map(f => path.basename(f))\r\n .filter(f => migrationPattern.test(f) && !f.includes('Designer'))\r\n .sort();\r\n\r\n for (let i = 1; i < orderedMigrations.length; i++) {\r\n const prev = orderedMigrations[i - 1];\r\n const curr = orderedMigrations[i];\r\n\r\n const prevMatch = migrationPattern.exec(prev);\r\n const currMatch = migrationPattern.exec(curr);\r\n\r\n if (prevMatch && currMatch) {\r\n const prevVersion = prevMatch[2];\r\n const currVersion = currMatch[2];\r\n\r\n // Check version ordering (semver comparison)\r\n if (currVersion < prevVersion) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'migrations',\r\n message: `Migration order issue: \"${curr}\" (v${currVersion}) comes before \"${prev}\" (v${prevVersion})`,\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function validateServiceInterfaces(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n _config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n if (!structure.application) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'services',\r\n message: 'Application project not found, skipping service validation',\r\n });\r\n return;\r\n }\r\n\r\n // Find service implementations\r\n const serviceFiles = await findFiles('**/*Service.cs', {\r\n cwd: structure.application,\r\n });\r\n\r\n for (const file of serviceFiles) {\r\n const content = await readText(file);\r\n const fileName = path.basename(file, '.cs');\r\n\r\n // Skip interfaces\r\n if (fileName.startsWith('I')) continue;\r\n\r\n // Check if there's a matching interface\r\n const expectedInterface = `I${fileName}`;\r\n const interfacePattern = new RegExp(`:\\\\s*${expectedInterface}\\\\b`);\r\n\r\n if (!interfacePattern.test(content)) {\r\n // Check if file declares interface\r\n const declaresInterface = content.includes(`interface ${expectedInterface}`);\r\n\r\n if (!declaresInterface) {\r\n result.warnings.push({\r\n type: 'warning',\r\n category: 'services',\r\n message: `Service \"${fileName}\" should implement \"${expectedInterface}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Create interface ${expectedInterface} and implement it`,\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function validateNamespaces(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ValidationResult\r\n): Promise<void> {\r\n const layers = [\r\n { path: structure.domain, expected: config.conventions.namespaces.domain, name: 'Domain' },\r\n { path: structure.application, expected: config.conventions.namespaces.application, name: 'Application' },\r\n { path: structure.infrastructure, expected: config.conventions.namespaces.infrastructure, name: 'Infrastructure' },\r\n { path: structure.api, expected: config.conventions.namespaces.api, name: 'Api' },\r\n ];\r\n\r\n for (const layer of layers) {\r\n if (!layer.path) continue;\r\n\r\n const csFiles = await findFiles('**/*.cs', { cwd: layer.path });\r\n\r\n for (const file of csFiles.slice(0, 10)) { // Sample first 10 files\r\n const content = await readText(file);\r\n const namespaceMatch = content.match(/namespace\\s+([\\w.]+)/);\r\n\r\n if (namespaceMatch) {\r\n const namespace = namespaceMatch[1];\r\n\r\n if (!namespace.startsWith(layer.expected)) {\r\n result.errors.push({\r\n type: 'error',\r\n category: 'namespaces',\r\n message: `${layer.name} file has incorrect namespace \"${namespace}\"`,\r\n file: path.relative(structure.root, file),\r\n suggestion: `Should start with \"${layer.expected}\"`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction generateSummary(result: ValidationResult, checks: string[]): string {\r\n const parts: string[] = [];\r\n\r\n parts.push(`Checks performed: ${checks.join(', ')}`);\r\n parts.push(`Errors: ${result.errors.length}`);\r\n parts.push(`Warnings: ${result.warnings.length}`);\r\n parts.push(`Status: ${result.valid ? 'PASSED' : 'FAILED'}`);\r\n\r\n return parts.join(' | ');\r\n}\r\n\r\nfunction formatResult(result: ValidationResult): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# Conventions Validation Report');\r\n lines.push('');\r\n lines.push(`## Summary`);\r\n lines.push(`- **Status**: ${result.valid ? '✅ PASSED' : '❌ FAILED'}`);\r\n lines.push(`- **Errors**: ${result.errors.length}`);\r\n lines.push(`- **Warnings**: ${result.warnings.length}`);\r\n lines.push('');\r\n\r\n if (result.errors.length > 0) {\r\n lines.push('## Errors');\r\n lines.push('');\r\n for (const error of result.errors) {\r\n lines.push(`### ❌ ${error.category}: ${error.message}`);\r\n if (error.file) lines.push(`- **File**: \\`${error.file}\\``);\r\n if (error.line) lines.push(`- **Line**: ${error.line}`);\r\n if (error.suggestion) lines.push(`- **Suggestion**: ${error.suggestion}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n if (result.warnings.length > 0) {\r\n lines.push('## Warnings');\r\n lines.push('');\r\n for (const warning of result.warnings) {\r\n lines.push(`### ⚠️ ${warning.category}: ${warning.message}`);\r\n if (warning.file) lines.push(`- **File**: \\`${warning.file}\\``);\r\n if (warning.suggestion) lines.push(`- **Suggestion**: ${warning.suggestion}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n if (result.errors.length === 0 && result.warnings.length === 0) {\r\n lines.push('## Result');\r\n lines.push('');\r\n lines.push('All conventions validated successfully! ✨');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport {\r\n CheckMigrationsInputSchema,\r\n type Config,\r\n type MigrationCheckResult,\r\n type MigrationInfo,\r\n} from '../types/index.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport { getCurrentBranch, branchExists, getFileFromBranch, getDiff } from '../utils/git.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const checkMigrationsTool: Tool = {\r\n name: 'check_migrations',\r\n description: 'Analyze EF Core migrations for conflicts, ordering issues, and ModelSnapshot discrepancies between branches',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n projectPath: {\r\n type: 'string',\r\n description: 'EF Core project path (default: auto-detect from config)',\r\n },\r\n branch: {\r\n type: 'string',\r\n description: 'Git branch to check (default: current branch)',\r\n },\r\n compareBranch: {\r\n type: 'string',\r\n description: 'Branch to compare against (e.g., \"develop\")',\r\n },\r\n },\r\n },\r\n};\r\n\r\nexport async function handleCheckMigrations(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = CheckMigrationsInputSchema.parse(args);\r\n const projectPath = input.projectPath || config.smartstack.projectPath;\r\n\r\n logger.info('Checking migrations', { projectPath, branch: input.branch });\r\n\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n if (!structure.migrations) {\r\n return '# Migration Check\\n\\n❌ No migrations folder found in the project.';\r\n }\r\n\r\n const result: MigrationCheckResult = {\r\n hasConflicts: false,\r\n migrations: [],\r\n conflicts: [],\r\n suggestions: [],\r\n };\r\n\r\n // Get current branch\r\n const currentBranch = input.branch || await getCurrentBranch(projectPath) || 'unknown';\r\n\r\n // Parse migrations\r\n result.migrations = await parseMigrations(structure.migrations, structure.root);\r\n\r\n // Check naming conventions\r\n checkNamingConventions(result, config);\r\n\r\n // Check chronological order\r\n checkChronologicalOrder(result);\r\n\r\n // If compare branch specified, check for conflicts\r\n if (input.compareBranch && await branchExists(input.compareBranch, projectPath)) {\r\n await checkBranchConflicts(\r\n result,\r\n structure,\r\n currentBranch,\r\n input.compareBranch,\r\n projectPath\r\n );\r\n }\r\n\r\n // Check ModelSnapshot\r\n await checkModelSnapshot(result, structure);\r\n\r\n // Update conflict status\r\n result.hasConflicts = result.conflicts.length > 0;\r\n\r\n // Generate suggestions\r\n generateSuggestions(result);\r\n\r\n return formatResult(result, currentBranch, input.compareBranch);\r\n}\r\n\r\nasync function parseMigrations(\r\n migrationsPath: string,\r\n rootPath: string\r\n): Promise<MigrationInfo[]> {\r\n const files = await findFiles('*.cs', { cwd: migrationsPath });\r\n const migrations: MigrationInfo[] = [];\r\n\r\n // Pattern: {context}_v{version}_{sequence}_{Description}.cs\r\n // Example: core_v1.0.0_001_CreateAuthUsers.cs\r\n const pattern = /^(\\w+)_v(\\d+\\.\\d+\\.\\d+)_(\\d{3})_(.+)\\.cs$/;\r\n\r\n for (const file of files) {\r\n const fileName = path.basename(file);\r\n\r\n // Skip designer and snapshot files\r\n if (fileName.includes('.Designer.') || fileName.includes('ModelSnapshot')) {\r\n continue;\r\n }\r\n\r\n const match = pattern.exec(fileName);\r\n\r\n if (match) {\r\n migrations.push({\r\n name: fileName.replace('.cs', ''),\r\n context: match[1], // DbContext (core, extensions, etc.)\r\n version: match[2], // Semver version (1.0.0, 1.2.0, etc.)\r\n sequence: match[3], // Sequence number (001, 002, etc.)\r\n description: match[4],\r\n file: path.relative(rootPath, file),\r\n applied: true, // We'd need DB connection to check this\r\n });\r\n } else {\r\n // Non-standard naming\r\n migrations.push({\r\n name: fileName.replace('.cs', ''),\r\n context: 'Unknown',\r\n version: '0.0.0',\r\n sequence: '000',\r\n description: fileName.replace('.cs', ''),\r\n file: path.relative(rootPath, file),\r\n applied: true,\r\n });\r\n }\r\n }\r\n\r\n // Sort by version then sequence\r\n return migrations.sort((a, b) => {\r\n // Compare versions using semver logic\r\n const versionCompare = compareVersions(a.version, b.version);\r\n if (versionCompare !== 0) return versionCompare;\r\n return a.sequence.localeCompare(b.sequence);\r\n });\r\n}\r\n\r\nfunction compareVersions(a: string, b: string): number {\r\n const partsA = a.split('.').map(Number);\r\n const partsB = b.split('.').map(Number);\r\n\r\n for (let i = 0; i < 3; i++) {\r\n if (partsA[i] > partsB[i]) return 1;\r\n if (partsA[i] < partsB[i]) return -1;\r\n }\r\n return 0;\r\n}\r\n\r\nfunction checkNamingConventions(result: MigrationCheckResult, _config: Config): void {\r\n for (const migration of result.migrations) {\r\n if (migration.context === 'Unknown') {\r\n result.conflicts.push({\r\n type: 'naming',\r\n description: `Migration \"${migration.name}\" does not follow naming convention`,\r\n files: [migration.file],\r\n resolution: `Rename to format: {context}_v{version}_{sequence}_{Description} (e.g., core_v1.0.0_001_CreateAuthUsers)`,\r\n });\r\n }\r\n\r\n if (migration.version === '0.0.0') {\r\n result.conflicts.push({\r\n type: 'naming',\r\n description: `Migration \"${migration.name}\" missing version number`,\r\n files: [migration.file],\r\n resolution: `Use format: {context}_v{version}_{sequence}_{Description} where version is semver (1.0.0, 1.2.0, etc.)`,\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction checkChronologicalOrder(result: MigrationCheckResult): void {\r\n const migrations = result.migrations.filter(m => m.context !== 'Unknown');\r\n\r\n for (let i = 1; i < migrations.length; i++) {\r\n const prev = migrations[i - 1];\r\n const curr = migrations[i];\r\n\r\n // Check if versions are in order (within same context)\r\n if (curr.context === prev.context) {\r\n const versionCompare = compareVersions(curr.version, prev.version);\r\n\r\n if (versionCompare < 0) {\r\n result.conflicts.push({\r\n type: 'order',\r\n description: `Migration \"${curr.name}\" (v${curr.version}) is versioned before \"${prev.name}\" (v${prev.version})`,\r\n files: [curr.file, prev.file],\r\n resolution: 'Reorder migrations or update version numbers',\r\n });\r\n }\r\n\r\n // Check for duplicate version with same sequence\r\n if (curr.version === prev.version && curr.sequence === prev.sequence) {\r\n result.conflicts.push({\r\n type: 'order',\r\n description: `Migrations \"${curr.name}\" and \"${prev.name}\" have same version and sequence`,\r\n files: [curr.file, prev.file],\r\n resolution: 'Use different sequence numbers (001, 002, etc.) for migrations in the same version',\r\n });\r\n }\r\n }\r\n }\r\n}\r\n\r\nasync function checkBranchConflicts(\r\n result: MigrationCheckResult,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n currentBranch: string,\r\n compareBranch: string,\r\n projectPath: string\r\n): Promise<void> {\r\n if (!structure.migrations) return;\r\n\r\n const migrationsRelPath = path.relative(projectPath, structure.migrations).replace(/\\\\/g, '/');\r\n\r\n // Get ModelSnapshot from both branches\r\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\r\n\r\n if (snapshotFiles.length > 0) {\r\n const snapshotRelPath = path.relative(projectPath, snapshotFiles[0]).replace(/\\\\/g, '/');\r\n\r\n const currentSnapshot = await readText(snapshotFiles[0]);\r\n const compareSnapshot = await getFileFromBranch(compareBranch, snapshotRelPath, projectPath);\r\n\r\n if (compareSnapshot && currentSnapshot !== compareSnapshot) {\r\n // Check if there are actual model differences\r\n const diff = await getDiff(compareBranch, currentBranch, snapshotRelPath, projectPath);\r\n\r\n if (diff) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: `ModelSnapshot differs between \"${currentBranch}\" and \"${compareBranch}\"`,\r\n files: [snapshotRelPath],\r\n resolution: 'Rebase on target branch and regenerate migrations with: dotnet ef migrations add <Name>',\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Check for migrations that exist in compare branch but not current\r\n const compareMigrations = await getFileFromBranch(\r\n compareBranch,\r\n migrationsRelPath,\r\n projectPath\r\n );\r\n\r\n if (compareMigrations) {\r\n // This would need more sophisticated parsing\r\n // For now, just note that comparison was done\r\n logger.debug('Branch comparison completed', { compareBranch });\r\n }\r\n}\r\n\r\nasync function checkModelSnapshot(\r\n result: MigrationCheckResult,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\r\n): Promise<void> {\r\n if (!structure.migrations) return;\r\n\r\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\r\n\r\n if (snapshotFiles.length === 0) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: 'No ModelSnapshot file found',\r\n files: [],\r\n resolution: 'Run: dotnet ef migrations add InitialCreate',\r\n });\r\n return;\r\n }\r\n\r\n if (snapshotFiles.length > 1) {\r\n result.conflicts.push({\r\n type: 'snapshot',\r\n description: 'Multiple ModelSnapshot files found',\r\n files: snapshotFiles.map(f => path.relative(structure.root, f)),\r\n resolution: 'Remove duplicate snapshots, keep only one per DbContext',\r\n });\r\n }\r\n\r\n // Check if snapshot references all migrations\r\n const snapshotContent = await readText(snapshotFiles[0]);\r\n\r\n for (const migration of result.migrations) {\r\n if (migration.context !== 'Unknown' && !snapshotContent.includes(migration.name)) {\r\n result.conflicts.push({\r\n type: 'dependency',\r\n description: `Migration \"${migration.name}\" not referenced in ModelSnapshot`,\r\n files: [migration.file],\r\n resolution: 'Migration may not be applied. Run: dotnet ef database update',\r\n });\r\n }\r\n }\r\n}\r\n\r\nfunction generateSuggestions(result: MigrationCheckResult): void {\r\n if (result.conflicts.some(c => c.type === 'snapshot')) {\r\n result.suggestions.push(\r\n 'Consider rebasing on the target branch before merging to avoid snapshot conflicts'\r\n );\r\n }\r\n\r\n if (result.conflicts.some(c => c.type === 'naming')) {\r\n result.suggestions.push(\r\n 'Use convention: {context}_v{version}_{sequence}_{Description} for migration naming (e.g., core_v1.0.0_001_CreateAuthUsers)'\r\n );\r\n }\r\n\r\n if (result.conflicts.some(c => c.type === 'order')) {\r\n result.suggestions.push(\r\n 'Ensure migrations are created in version order to avoid conflicts'\r\n );\r\n }\r\n\r\n if (result.migrations.length > 20) {\r\n result.suggestions.push(\r\n 'Consider squashing old migrations to reduce complexity. Use: /efcore squash'\r\n );\r\n }\r\n}\r\n\r\nfunction formatResult(\r\n result: MigrationCheckResult,\r\n currentBranch: string,\r\n compareBranch?: string\r\n): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# EF Core Migration Check Report');\r\n lines.push('');\r\n lines.push('## Overview');\r\n lines.push(`- **Current Branch**: ${currentBranch}`);\r\n if (compareBranch) {\r\n lines.push(`- **Compare Branch**: ${compareBranch}`);\r\n }\r\n lines.push(`- **Total Migrations**: ${result.migrations.length}`);\r\n lines.push(`- **Conflicts Found**: ${result.conflicts.length}`);\r\n lines.push(`- **Status**: ${result.hasConflicts ? '❌ CONFLICTS DETECTED' : '✅ OK'}`);\r\n lines.push('');\r\n\r\n // Migrations list\r\n lines.push('## Migrations');\r\n lines.push('');\r\n lines.push('| Name | Context | Version | Sequence | Description |');\r\n lines.push('|------|---------|---------|----------|-------------|');\r\n\r\n for (const migration of result.migrations) {\r\n lines.push(\r\n `| ${migration.name} | ${migration.context} | ${migration.version} | ${migration.sequence} | ${migration.description} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Conflicts\r\n if (result.conflicts.length > 0) {\r\n lines.push('## Conflicts');\r\n lines.push('');\r\n\r\n for (const conflict of result.conflicts) {\r\n const icon = conflict.type === 'snapshot' ? '🔄' :\r\n conflict.type === 'order' ? '📅' :\r\n conflict.type === 'naming' ? '📝' : '⚠️';\r\n\r\n lines.push(`### ${icon} ${conflict.type.toUpperCase()}: ${conflict.description}`);\r\n if (conflict.files.length > 0) {\r\n lines.push(`- **Files**: ${conflict.files.map(f => `\\`${f}\\``).join(', ')}`);\r\n }\r\n lines.push(`- **Resolution**: ${conflict.resolution}`);\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Suggestions\r\n if (result.suggestions.length > 0) {\r\n lines.push('## Suggestions');\r\n lines.push('');\r\n for (const suggestion of result.suggestions) {\r\n lines.push(`- 💡 ${suggestion}`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport Handlebars from 'handlebars';\r\nimport {\r\n ScaffoldExtensionInputSchema,\r\n type Config,\r\n type ScaffoldResult,\r\n} from '../types/index.js';\r\nimport { writeText, ensureDirectory } from '../utils/fs.js';\r\nimport { findSmartStackStructure } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const scaffoldExtensionTool: Tool = {\r\n name: 'scaffold_extension',\r\n description: 'Generate code to extend SmartStack: service (interface + implementation), entity (class + EF config), controller (REST endpoints), or React component',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n type: {\r\n type: 'string',\r\n enum: ['service', 'entity', 'controller', 'component'],\r\n description: 'Type of extension to scaffold',\r\n },\r\n name: {\r\n type: 'string',\r\n description: 'Name of the extension (e.g., \"UserProfile\", \"Order\")',\r\n },\r\n options: {\r\n type: 'object',\r\n properties: {\r\n namespace: {\r\n type: 'string',\r\n description: 'Custom namespace (optional)',\r\n },\r\n baseEntity: {\r\n type: 'string',\r\n description: 'Base entity to extend (for entity type)',\r\n },\r\n methods: {\r\n type: 'array',\r\n items: { type: 'string' },\r\n description: 'Methods to generate (for service type)',\r\n },\r\n outputPath: {\r\n type: 'string',\r\n description: 'Custom output path',\r\n },\r\n },\r\n },\r\n },\r\n required: ['type', 'name'],\r\n },\r\n};\r\n\r\n// Register Handlebars helpers\r\nHandlebars.registerHelper('pascalCase', (str: string) => {\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n});\r\n\r\nHandlebars.registerHelper('camelCase', (str: string) => {\r\n return str.charAt(0).toLowerCase() + str.slice(1);\r\n});\r\n\r\nHandlebars.registerHelper('kebabCase', (str: string) => {\r\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\r\n});\r\n\r\nexport async function handleScaffoldExtension(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ScaffoldExtensionInputSchema.parse(args);\r\n\r\n logger.info('Scaffolding extension', { type: input.type, name: input.name });\r\n\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n const result: ScaffoldResult = {\r\n success: true,\r\n files: [],\r\n instructions: [],\r\n };\r\n\r\n try {\r\n switch (input.type) {\r\n case 'service':\r\n await scaffoldService(input.name, input.options, structure, config, result);\r\n break;\r\n case 'entity':\r\n await scaffoldEntity(input.name, input.options, structure, config, result);\r\n break;\r\n case 'controller':\r\n await scaffoldController(input.name, input.options, structure, config, result);\r\n break;\r\n case 'component':\r\n await scaffoldComponent(input.name, input.options, structure, config, result);\r\n break;\r\n }\r\n } catch (error) {\r\n result.success = false;\r\n result.instructions.push(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);\r\n }\r\n\r\n return formatResult(result, input.type, input.name);\r\n}\r\n\r\nasync function scaffoldService(\r\n name: string,\r\n options: { namespace?: string; methods?: string[] } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || `${config.conventions.namespaces.application}.Services`;\r\n const methods = options?.methods || ['GetByIdAsync', 'GetAllAsync', 'CreateAsync', 'UpdateAsync', 'DeleteAsync'];\r\n\r\n // Interface template\r\n const interfaceTemplate = `using System.Threading;\r\nusing System.Threading.Tasks;\r\nusing System.Collections.Generic;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// Service interface for {{name}} operations\r\n/// </summary>\r\npublic interface I{{name}}Service\r\n{\r\n{{#each methods}}\r\n /// <summary>\r\n /// {{this}} operation\r\n /// </summary>\r\n Task<object> {{this}}(CancellationToken cancellationToken = default);\r\n\r\n{{/each}}\r\n}\r\n`;\r\n\r\n // Implementation template\r\n const implementationTemplate = `using System.Threading;\r\nusing System.Threading.Tasks;\r\nusing System.Collections.Generic;\r\nusing Microsoft.Extensions.Logging;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// Service implementation for {{name}} operations\r\n/// </summary>\r\npublic class {{name}}Service : I{{name}}Service\r\n{\r\n private readonly ILogger<{{name}}Service> _logger;\r\n\r\n public {{name}}Service(ILogger<{{name}}Service> logger)\r\n {\r\n _logger = logger;\r\n }\r\n\r\n{{#each methods}}\r\n /// <inheritdoc />\r\n public async Task<object> {{this}}(CancellationToken cancellationToken = default)\r\n {\r\n _logger.LogInformation(\"Executing {{this}}\");\r\n // TODO: Implement {{this}}\r\n await Task.CompletedTask;\r\n throw new NotImplementedException();\r\n }\r\n\r\n{{/each}}\r\n}\r\n`;\r\n\r\n // DI registration template\r\n const diTemplate = `// Add to DependencyInjection.cs or ServiceCollectionExtensions.cs:\r\nservices.AddScoped<I{{name}}Service, {{name}}Service>();\r\n`;\r\n\r\n const context = { namespace, name, methods };\r\n\r\n const interfaceContent = Handlebars.compile(interfaceTemplate)(context);\r\n const implementationContent = Handlebars.compile(implementationTemplate)(context);\r\n const diContent = Handlebars.compile(diTemplate)(context);\r\n\r\n // Determine output paths\r\n const basePath = structure.application || config.smartstack.projectPath;\r\n const servicesPath = path.join(basePath, 'Services');\r\n\r\n await ensureDirectory(servicesPath);\r\n\r\n const interfacePath = path.join(servicesPath, `I${name}Service.cs`);\r\n const implementationPath = path.join(servicesPath, `${name}Service.cs`);\r\n\r\n // Write files\r\n await writeText(interfacePath, interfaceContent);\r\n result.files.push({ path: interfacePath, content: interfaceContent, type: 'created' });\r\n\r\n await writeText(implementationPath, implementationContent);\r\n result.files.push({ path: implementationPath, content: implementationContent, type: 'created' });\r\n\r\n result.instructions.push('Register service in DI container:');\r\n result.instructions.push(diContent);\r\n}\r\n\r\nasync function scaffoldEntity(\r\n name: string,\r\n options: { namespace?: string; baseEntity?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || config.conventions.namespaces.domain;\r\n const baseEntity = options?.baseEntity;\r\n\r\n // Entity template\r\n const entityTemplate = `using System;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}\r\n/// </summary>\r\npublic class {{name}}{{#if baseEntity}} : {{baseEntity}}{{/if}}\r\n{\r\n{{#unless baseEntity}}\r\n public Guid Id { get; set; }\r\n\r\n public DateTime CreatedAt { get; set; } = DateTime.UtcNow;\r\n\r\n public DateTime? UpdatedAt { get; set; }\r\n\r\n{{/unless}}\r\n // TODO: Add {{name}} specific properties\r\n}\r\n`;\r\n\r\n // EF Configuration template\r\n const configTemplate = `using Microsoft.EntityFrameworkCore;\r\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\r\n\r\nnamespace {{infrastructureNamespace}}.Persistence.Configurations;\r\n\r\npublic class {{name}}Configuration : IEntityTypeConfiguration<{{domainNamespace}}.{{name}}>\r\n{\r\n public void Configure(EntityTypeBuilder<{{domainNamespace}}.{{name}}> builder)\r\n {\r\n builder.ToTable(\"{{tablePrefix}}{{name}}s\");\r\n\r\n builder.HasKey(e => e.Id);\r\n\r\n // TODO: Add {{name}} specific configuration\r\n }\r\n}\r\n`;\r\n\r\n const context = {\r\n namespace,\r\n name,\r\n baseEntity,\r\n infrastructureNamespace: config.conventions.namespaces.infrastructure,\r\n domainNamespace: config.conventions.namespaces.domain,\r\n schema: config.conventions.schemas.platform,\r\n };\r\n\r\n const entityContent = Handlebars.compile(entityTemplate)(context);\r\n const configContent = Handlebars.compile(configTemplate)(context);\r\n\r\n // Determine output paths\r\n const domainPath = structure.domain || path.join(config.smartstack.projectPath, 'Domain');\r\n const infraPath = structure.infrastructure || path.join(config.smartstack.projectPath, 'Infrastructure');\r\n\r\n await ensureDirectory(domainPath);\r\n await ensureDirectory(path.join(infraPath, 'Persistence', 'Configurations'));\r\n\r\n const entityFilePath = path.join(domainPath, `${name}.cs`);\r\n const configFilePath = path.join(infraPath, 'Persistence', 'Configurations', `${name}Configuration.cs`);\r\n\r\n await writeText(entityFilePath, entityContent);\r\n result.files.push({ path: entityFilePath, content: entityContent, type: 'created' });\r\n\r\n await writeText(configFilePath, configContent);\r\n result.files.push({ path: configFilePath, content: configContent, type: 'created' });\r\n\r\n result.instructions.push(`Add DbSet to ApplicationDbContext:`);\r\n result.instructions.push(`public DbSet<${name}> ${name}s => Set<${name}>();`);\r\n result.instructions.push('');\r\n result.instructions.push('Create migration:');\r\n result.instructions.push(`dotnet ef migrations add Add${name}`);\r\n}\r\n\r\nasync function scaffoldController(\r\n name: string,\r\n options: { namespace?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const namespace = options?.namespace || `${config.conventions.namespaces.api}.Controllers`;\r\n\r\n const controllerTemplate = `using Microsoft.AspNetCore.Authorization;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Microsoft.Extensions.Logging;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// API controller for {{name}} operations\r\n/// </summary>\r\n[ApiController]\r\n[Route(\"api/[controller]\")]\r\n[Authorize]\r\npublic class {{name}}Controller : ControllerBase\r\n{\r\n private readonly ILogger<{{name}}Controller> _logger;\r\n\r\n public {{name}}Controller(ILogger<{{name}}Controller> logger)\r\n {\r\n _logger = logger;\r\n }\r\n\r\n /// <summary>\r\n /// Get all {{nameLower}}s\r\n /// </summary>\r\n [HttpGet]\r\n public async Task<ActionResult<IEnumerable<{{name}}Dto>>> GetAll()\r\n {\r\n _logger.LogInformation(\"Getting all {{nameLower}}s\");\r\n // TODO: Implement\r\n return Ok(Array.Empty<{{name}}Dto>());\r\n }\r\n\r\n /// <summary>\r\n /// Get {{nameLower}} by ID\r\n /// </summary>\r\n [HttpGet(\"{id:guid}\")]\r\n public async Task<ActionResult<{{name}}Dto>> GetById(Guid id)\r\n {\r\n _logger.LogInformation(\"Getting {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NotFound();\r\n }\r\n\r\n /// <summary>\r\n /// Create new {{nameLower}}\r\n /// </summary>\r\n [HttpPost]\r\n public async Task<ActionResult<{{name}}Dto>> Create([FromBody] Create{{name}}Request request)\r\n {\r\n _logger.LogInformation(\"Creating {{nameLower}}\");\r\n // TODO: Implement\r\n return CreatedAtAction(nameof(GetById), new { id = Guid.NewGuid() }, null);\r\n }\r\n\r\n /// <summary>\r\n /// Update {{nameLower}}\r\n /// </summary>\r\n [HttpPut(\"{id:guid}\")]\r\n public async Task<ActionResult> Update(Guid id, [FromBody] Update{{name}}Request request)\r\n {\r\n _logger.LogInformation(\"Updating {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NoContent();\r\n }\r\n\r\n /// <summary>\r\n /// Delete {{nameLower}}\r\n /// </summary>\r\n [HttpDelete(\"{id:guid}\")]\r\n public async Task<ActionResult> Delete(Guid id)\r\n {\r\n _logger.LogInformation(\"Deleting {{nameLower}} {Id}\", id);\r\n // TODO: Implement\r\n return NoContent();\r\n }\r\n}\r\n\r\n// DTOs\r\npublic record {{name}}Dto(Guid Id, DateTime CreatedAt);\r\npublic record Create{{name}}Request();\r\npublic record Update{{name}}Request();\r\n`;\r\n\r\n const context = {\r\n namespace,\r\n name,\r\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\r\n };\r\n\r\n const controllerContent = Handlebars.compile(controllerTemplate)(context);\r\n\r\n const apiPath = structure.api || path.join(config.smartstack.projectPath, 'Api');\r\n const controllersPath = path.join(apiPath, 'Controllers');\r\n\r\n await ensureDirectory(controllersPath);\r\n\r\n const controllerFilePath = path.join(controllersPath, `${name}Controller.cs`);\r\n\r\n await writeText(controllerFilePath, controllerContent);\r\n result.files.push({ path: controllerFilePath, content: controllerContent, type: 'created' });\r\n\r\n result.instructions.push('Controller created. API endpoints:');\r\n result.instructions.push(` GET /api/${name.toLowerCase()}`);\r\n result.instructions.push(` GET /api/${name.toLowerCase()}/{id}`);\r\n result.instructions.push(` POST /api/${name.toLowerCase()}`);\r\n result.instructions.push(` PUT /api/${name.toLowerCase()}/{id}`);\r\n result.instructions.push(` DELETE /api/${name.toLowerCase()}/{id}`);\r\n}\r\n\r\nasync function scaffoldComponent(\r\n name: string,\r\n options: { namespace?: string; outputPath?: string } | undefined,\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\r\n config: Config,\r\n result: ScaffoldResult\r\n): Promise<void> {\r\n const componentTemplate = `import React, { useState, useEffect } from 'react';\r\n\r\ninterface {{name}}Props {\r\n id?: string;\r\n onSave?: (data: {{name}}Data) => void;\r\n onCancel?: () => void;\r\n}\r\n\r\ninterface {{name}}Data {\r\n id?: string;\r\n // TODO: Add {{name}} data properties\r\n}\r\n\r\n/**\r\n * {{name}} component\r\n */\r\nexport const {{name}}: React.FC<{{name}}Props> = ({ id, onSave, onCancel }) => {\r\n const [data, setData] = useState<{{name}}Data | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<string | null>(null);\r\n\r\n useEffect(() => {\r\n if (id) {\r\n // TODO: Fetch {{nameLower}} data\r\n setLoading(true);\r\n // fetch...\r\n setLoading(false);\r\n }\r\n }, [id]);\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (data && onSave) {\r\n onSave(data);\r\n }\r\n };\r\n\r\n if (loading) {\r\n return <div className=\"animate-pulse\">Loading...</div>;\r\n }\r\n\r\n if (error) {\r\n return <div className=\"text-red-500\">{error}</div>;\r\n }\r\n\r\n return (\r\n <div className=\"p-4\">\r\n <h2 className=\"text-xl font-semibold mb-4\">{{name}}</h2>\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n {/* TODO: Add form fields */}\r\n <div className=\"flex gap-2\">\r\n <button\r\n type=\"submit\"\r\n className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\r\n >\r\n Save\r\n </button>\r\n {onCancel && (\r\n <button\r\n type=\"button\"\r\n onClick={onCancel}\r\n className=\"px-4 py-2 bg-gray-200 rounded hover:bg-gray-300\"\r\n >\r\n Cancel\r\n </button>\r\n )}\r\n </div>\r\n </form>\r\n </div>\r\n );\r\n};\r\n\r\nexport default {{name}};\r\n`;\r\n\r\n // Hook template\r\n const hookTemplate = `import { useState, useEffect, useCallback } from 'react';\r\nimport { {{nameLower}}Api } from '../services/api/{{nameLower}}';\r\n\r\ninterface {{name}}Data {\r\n id?: string;\r\n // TODO: Add properties\r\n}\r\n\r\ninterface Use{{name}}Options {\r\n id?: string;\r\n autoFetch?: boolean;\r\n}\r\n\r\nexport function use{{name}}(options: Use{{name}}Options = {}) {\r\n const { id, autoFetch = true } = options;\r\n const [data, setData] = useState<{{name}}Data | null>(null);\r\n const [loading, setLoading] = useState(false);\r\n const [error, setError] = useState<Error | null>(null);\r\n\r\n const fetch{{name}} = useCallback(async (fetchId?: string) => {\r\n const targetId = fetchId || id;\r\n if (!targetId) return;\r\n\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n // TODO: Implement API call\r\n // const result = await {{nameLower}}Api.getById(targetId);\r\n // setData(result);\r\n } catch (e) {\r\n setError(e instanceof Error ? e : new Error('Unknown error'));\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, [id]);\r\n\r\n const save{{name}} = useCallback(async (saveData: {{name}}Data) => {\r\n setLoading(true);\r\n setError(null);\r\n try {\r\n // TODO: Implement API call\r\n // const result = saveData.id\r\n // ? await {{nameLower}}Api.update(saveData.id, saveData)\r\n // : await {{nameLower}}Api.create(saveData);\r\n // setData(result);\r\n // return result;\r\n } catch (e) {\r\n setError(e instanceof Error ? e : new Error('Unknown error'));\r\n throw e;\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (autoFetch && id) {\r\n fetch{{name}}();\r\n }\r\n }, [autoFetch, id, fetch{{name}}]);\r\n\r\n return {\r\n data,\r\n loading,\r\n error,\r\n fetch: fetch{{name}},\r\n save: save{{name}},\r\n setData,\r\n };\r\n}\r\n`;\r\n\r\n const context = {\r\n name,\r\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\r\n };\r\n\r\n const componentContent = Handlebars.compile(componentTemplate)(context);\r\n const hookContent = Handlebars.compile(hookTemplate)(context);\r\n\r\n // Determine output paths\r\n const webPath = structure.web || path.join(config.smartstack.projectPath, 'web', 'smartstack-web');\r\n const componentsPath = options?.outputPath || path.join(webPath, 'src', 'components');\r\n const hooksPath = path.join(webPath, 'src', 'hooks');\r\n\r\n await ensureDirectory(componentsPath);\r\n await ensureDirectory(hooksPath);\r\n\r\n const componentFilePath = path.join(componentsPath, `${name}.tsx`);\r\n const hookFilePath = path.join(hooksPath, `use${name}.ts`);\r\n\r\n await writeText(componentFilePath, componentContent);\r\n result.files.push({ path: componentFilePath, content: componentContent, type: 'created' });\r\n\r\n await writeText(hookFilePath, hookContent);\r\n result.files.push({ path: hookFilePath, content: hookContent, type: 'created' });\r\n\r\n result.instructions.push('Import and use the component:');\r\n result.instructions.push(`import { ${name} } from './components/${name}';`);\r\n result.instructions.push(`import { use${name} } from './hooks/use${name}';`);\r\n}\r\n\r\nfunction formatResult(result: ScaffoldResult, type: string, name: string): string {\r\n const lines: string[] = [];\r\n\r\n lines.push(`# Scaffold ${type}: ${name}`);\r\n lines.push('');\r\n\r\n if (result.success) {\r\n lines.push('## ✅ Files Generated');\r\n lines.push('');\r\n\r\n for (const file of result.files) {\r\n lines.push(`### ${file.type === 'created' ? '📄' : '✏️'} ${path.basename(file.path)}`);\r\n lines.push(`**Path**: \\`${file.path}\\``);\r\n lines.push('');\r\n lines.push('```' + (file.path.endsWith('.cs') ? 'csharp' : 'typescript'));\r\n // Show first 50 lines of content\r\n const contentLines = file.content.split('\\n').slice(0, 50);\r\n lines.push(contentLines.join('\\n'));\r\n if (file.content.split('\\n').length > 50) {\r\n lines.push('// ... (truncated)');\r\n }\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n if (result.instructions.length > 0) {\r\n lines.push('## 📋 Next Steps');\r\n lines.push('');\r\n for (const instruction of result.instructions) {\r\n if (instruction.startsWith('services.') || instruction.startsWith('public DbSet')) {\r\n lines.push('```csharp');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else if (instruction.startsWith('dotnet ')) {\r\n lines.push('```bash');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else if (instruction.startsWith('import ')) {\r\n lines.push('```typescript');\r\n lines.push(instruction);\r\n lines.push('```');\r\n } else {\r\n lines.push(instruction);\r\n }\r\n }\r\n }\r\n } else {\r\n lines.push('## ❌ Generation Failed');\r\n lines.push('');\r\n for (const instruction of result.instructions) {\r\n lines.push(`- ${instruction}`);\r\n }\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\r\nimport axios from 'axios';\r\nimport {\r\n ApiDocsInputSchema,\r\n type Config,\r\n} from '../types/index.js';\r\nimport { readText } from '../utils/fs.js';\r\nimport { findSmartStackStructure, findControllerFiles } from '../lib/detector.js';\r\nimport { logger } from '../lib/logger.js';\r\nimport path from 'path';\r\n\r\nexport const apiDocsTool: Tool = {\r\n name: 'api_docs',\r\n description: 'Get API documentation for SmartStack endpoints. Can fetch from Swagger/OpenAPI or parse controller files directly.',\r\n inputSchema: {\r\n type: 'object',\r\n properties: {\r\n endpoint: {\r\n type: 'string',\r\n description: 'Filter by endpoint path (e.g., \"/api/users\"). Leave empty for all endpoints.',\r\n },\r\n format: {\r\n type: 'string',\r\n enum: ['markdown', 'json', 'openapi'],\r\n description: 'Output format',\r\n default: 'markdown',\r\n },\r\n controller: {\r\n type: 'string',\r\n description: 'Filter by controller name (e.g., \"Users\")',\r\n },\r\n },\r\n },\r\n};\r\n\r\ninterface EndpointInfo {\r\n method: string;\r\n path: string;\r\n controller: string;\r\n action: string;\r\n summary?: string;\r\n parameters: ParameterInfo[];\r\n requestBody?: string;\r\n responses: ResponseInfo[];\r\n authorize: boolean;\r\n}\r\n\r\ninterface ParameterInfo {\r\n name: string;\r\n in: 'path' | 'query' | 'header' | 'body';\r\n type: string;\r\n required: boolean;\r\n description?: string;\r\n}\r\n\r\ninterface ResponseInfo {\r\n status: number;\r\n type?: string;\r\n description?: string;\r\n}\r\n\r\nexport async function handleApiDocs(\r\n args: unknown,\r\n config: Config\r\n): Promise<string> {\r\n const input = ApiDocsInputSchema.parse(args);\r\n\r\n logger.info('Fetching API documentation', { endpoint: input.endpoint, format: input.format });\r\n\r\n let endpoints: EndpointInfo[] = [];\r\n\r\n // Try to fetch from Swagger first if API is enabled\r\n if (config.smartstack.apiEnabled && config.smartstack.apiUrl) {\r\n try {\r\n endpoints = await fetchFromSwagger(config.smartstack.apiUrl);\r\n logger.debug('Fetched endpoints from Swagger', { count: endpoints.length });\r\n } catch (error) {\r\n logger.warn('Failed to fetch from Swagger, falling back to code parsing', { error });\r\n }\r\n }\r\n\r\n // Fall back to parsing controller files\r\n if (endpoints.length === 0) {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n endpoints = await parseControllers(structure);\r\n }\r\n\r\n // Filter endpoints\r\n if (input.endpoint) {\r\n const filter = input.endpoint.toLowerCase();\r\n endpoints = endpoints.filter(e => e.path.toLowerCase().includes(filter));\r\n }\r\n\r\n if (input.controller) {\r\n const filter = input.controller.toLowerCase();\r\n endpoints = endpoints.filter(e => e.controller.toLowerCase().includes(filter));\r\n }\r\n\r\n // Format output\r\n switch (input.format) {\r\n case 'json':\r\n return JSON.stringify(endpoints, null, 2);\r\n case 'openapi':\r\n return formatAsOpenApi(endpoints);\r\n case 'markdown':\r\n default:\r\n return formatAsMarkdown(endpoints);\r\n }\r\n}\r\n\r\nasync function fetchFromSwagger(apiUrl: string): Promise<EndpointInfo[]> {\r\n const swaggerUrl = `${apiUrl}/swagger/v1/swagger.json`;\r\n\r\n const response = await axios.get(swaggerUrl, {\r\n timeout: 5000,\r\n httpsAgent: new (await import('https')).Agent({ rejectUnauthorized: false }),\r\n });\r\n\r\n const spec = response.data;\r\n const endpoints: EndpointInfo[] = [];\r\n\r\n for (const [pathKey, pathItem] of Object.entries(spec.paths || {})) {\r\n const pathObj = pathItem as Record<string, unknown>;\r\n\r\n for (const method of ['get', 'post', 'put', 'patch', 'delete']) {\r\n const operation = pathObj[method] as Record<string, unknown> | undefined;\r\n if (!operation) continue;\r\n\r\n const tags = (operation.tags as string[]) || ['Unknown'];\r\n const parameters = (operation.parameters as Array<Record<string, unknown>>) || [];\r\n\r\n endpoints.push({\r\n method: method.toUpperCase(),\r\n path: pathKey,\r\n controller: tags[0],\r\n action: (operation.operationId as string) || method,\r\n summary: operation.summary as string | undefined,\r\n parameters: parameters.map(p => ({\r\n name: p.name as string,\r\n in: p.in as 'path' | 'query' | 'header' | 'body',\r\n type: (p.schema as Record<string, string>)?.type || 'string',\r\n required: p.required as boolean || false,\r\n description: p.description as string | undefined,\r\n })),\r\n requestBody: operation.requestBody ? 'See schema' : undefined,\r\n responses: Object.entries(operation.responses || {}).map(([status, resp]) => ({\r\n status: parseInt(status, 10),\r\n description: (resp as Record<string, string>).description,\r\n })),\r\n authorize: !!(operation.security && (operation.security as unknown[]).length > 0),\r\n });\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nasync function parseControllers(\r\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\r\n): Promise<EndpointInfo[]> {\r\n if (!structure.api) {\r\n return [];\r\n }\r\n\r\n const controllerFiles = await findControllerFiles(structure.api);\r\n const endpoints: EndpointInfo[] = [];\r\n\r\n for (const file of controllerFiles) {\r\n const content = await readText(file);\r\n const fileName = path.basename(file, '.cs');\r\n const controllerName = fileName.replace('Controller', '');\r\n\r\n // Parse route attribute\r\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\r\n const baseRoute = routeMatch ? routeMatch[1].replace('[controller]', controllerName.toLowerCase()) : `/api/${controllerName.toLowerCase()}`;\r\n\r\n // Parse authorize attribute\r\n const hasAuthorize = content.includes('[Authorize]');\r\n\r\n // Parse HTTP methods\r\n const httpMethods = [\r\n { pattern: /\\[HttpGet(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'GET' },\r\n { pattern: /\\[HttpPost(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'POST' },\r\n { pattern: /\\[HttpPut(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PUT' },\r\n { pattern: /\\[HttpPatch(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PATCH' },\r\n { pattern: /\\[HttpDelete(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'DELETE' },\r\n ];\r\n\r\n for (const { pattern, method } of httpMethods) {\r\n let match;\r\n while ((match = pattern.exec(content)) !== null) {\r\n const routeSuffix = match[1] || '';\r\n const fullPath = routeSuffix ? `${baseRoute}/${routeSuffix}` : baseRoute;\r\n\r\n // Try to find the method name after the attribute\r\n const afterAttribute = content.substring(match.index);\r\n const methodMatch = afterAttribute.match(/public\\s+(?:async\\s+)?(?:Task<)?(?:ActionResult<)?(\\w+)(?:>)?\\s+(\\w+)\\s*\\(/);\r\n\r\n const parameters: ParameterInfo[] = [];\r\n\r\n // Parse path parameters\r\n const pathParams = fullPath.match(/\\{(\\w+)(?::\\w+)?\\}/g);\r\n if (pathParams) {\r\n for (const param of pathParams) {\r\n const paramName = param.replace(/[{}:]/g, '').replace(/\\w+$/, '');\r\n parameters.push({\r\n name: paramName || param.replace(/[{}]/g, '').split(':')[0],\r\n in: 'path',\r\n type: 'string',\r\n required: true,\r\n });\r\n }\r\n }\r\n\r\n // Parse [FromBody] parameters\r\n if (afterAttribute.includes('[FromBody]')) {\r\n const bodyMatch = afterAttribute.match(/\\[FromBody\\]\\s*(\\w+)\\s+(\\w+)/);\r\n if (bodyMatch) {\r\n parameters.push({\r\n name: bodyMatch[2],\r\n in: 'body',\r\n type: bodyMatch[1],\r\n required: true,\r\n });\r\n }\r\n }\r\n\r\n // Parse [FromQuery] parameters\r\n const queryMatches = afterAttribute.matchAll(/\\[FromQuery\\]\\s*(\\w+)\\s+(\\w+)/g);\r\n for (const qm of queryMatches) {\r\n parameters.push({\r\n name: qm[2],\r\n in: 'query',\r\n type: qm[1],\r\n required: false,\r\n });\r\n }\r\n\r\n endpoints.push({\r\n method,\r\n path: fullPath.replace(/\\/+/g, '/'),\r\n controller: controllerName,\r\n action: methodMatch ? methodMatch[2] : 'Unknown',\r\n parameters,\r\n responses: [{ status: 200, description: 'Success' }],\r\n authorize: hasAuthorize,\r\n });\r\n }\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nfunction formatAsMarkdown(endpoints: EndpointInfo[]): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack API Documentation');\r\n lines.push('');\r\n lines.push(`Generated: ${new Date().toISOString()}`);\r\n lines.push('');\r\n\r\n // Group by controller\r\n const byController = new Map<string, EndpointInfo[]>();\r\n for (const endpoint of endpoints) {\r\n const existing = byController.get(endpoint.controller) || [];\r\n existing.push(endpoint);\r\n byController.set(endpoint.controller, existing);\r\n }\r\n\r\n for (const [controller, controllerEndpoints] of byController) {\r\n lines.push(`## ${controller}`);\r\n lines.push('');\r\n\r\n for (const endpoint of controllerEndpoints) {\r\n const authBadge = endpoint.authorize ? ' 🔒' : '';\r\n lines.push(`### \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\r\n lines.push('');\r\n\r\n if (endpoint.summary) {\r\n lines.push(endpoint.summary);\r\n lines.push('');\r\n }\r\n\r\n if (endpoint.parameters.length > 0) {\r\n lines.push('**Parameters:**');\r\n lines.push('');\r\n lines.push('| Name | In | Type | Required |');\r\n lines.push('|------|-----|------|----------|');\r\n for (const param of endpoint.parameters) {\r\n lines.push(`| ${param.name} | ${param.in} | ${param.type} | ${param.required ? 'Yes' : 'No'} |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n if (endpoint.responses.length > 0) {\r\n lines.push('**Responses:**');\r\n lines.push('');\r\n for (const resp of endpoint.responses) {\r\n lines.push(`- \\`${resp.status}\\`: ${resp.description || 'No description'}`);\r\n }\r\n lines.push('');\r\n }\r\n }\r\n }\r\n\r\n if (endpoints.length === 0) {\r\n lines.push('No endpoints found matching the filter criteria.');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction formatAsOpenApi(endpoints: EndpointInfo[]): string {\r\n const spec = {\r\n openapi: '3.0.0',\r\n info: {\r\n title: 'SmartStack API',\r\n version: '1.0.0',\r\n },\r\n paths: {} as Record<string, Record<string, unknown>>,\r\n };\r\n\r\n for (const endpoint of endpoints) {\r\n if (!spec.paths[endpoint.path]) {\r\n spec.paths[endpoint.path] = {};\r\n }\r\n\r\n spec.paths[endpoint.path][endpoint.method.toLowerCase()] = {\r\n tags: [endpoint.controller],\r\n operationId: endpoint.action,\r\n summary: endpoint.summary,\r\n parameters: endpoint.parameters\r\n .filter(p => p.in !== 'body')\r\n .map(p => ({\r\n name: p.name,\r\n in: p.in,\r\n required: p.required,\r\n schema: { type: p.type },\r\n })),\r\n responses: Object.fromEntries(\r\n endpoint.responses.map(r => [\r\n r.status.toString(),\r\n { description: r.description || 'Response' },\r\n ])\r\n ),\r\n security: endpoint.authorize ? [{ bearerAuth: [] }] : undefined,\r\n };\r\n }\r\n\r\n return JSON.stringify(spec, null, 2);\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\n\r\nexport const conventionsResourceTemplate: Resource = {\r\n uri: 'smartstack://conventions',\r\n name: 'AtlasHub Conventions',\r\n description: 'Documentation of AtlasHub/SmartStack naming conventions, patterns, and best practices',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\nexport async function getConventionsResource(config: Config): Promise<string> {\r\n const { schemas, tablePrefixes, migrationFormat, namespaces, servicePattern } = config.conventions;\r\n\r\n return `# AtlasHub SmartStack Conventions\r\n\r\n## Overview\r\n\r\nThis document describes the mandatory conventions for extending the SmartStack/AtlasHub platform.\r\nFollowing these conventions ensures compatibility and prevents conflicts.\r\n\r\n---\r\n\r\n## 1. Database Conventions\r\n\r\n### SQL Schemas\r\n\r\nSmartStack uses SQL Server schemas to separate platform tables from client extensions:\r\n\r\n| Schema | Usage | Description |\r\n|--------|-------|-------------|\r\n| \\`${schemas.platform}\\` | SmartStack platform | All native SmartStack tables |\r\n| \\`${schemas.extensions}\\` | Client extensions | Custom tables added by clients |\r\n\r\n### Domain Table Prefixes\r\n\r\nTables are organized by domain using prefixes:\r\n\r\n| Prefix | Domain | Example Tables |\r\n|--------|--------|----------------|\r\n| \\`auth_\\` | Authorization | auth_Users, auth_Roles, auth_Permissions |\r\n| \\`nav_\\` | Navigation | nav_Contexts, nav_Applications, nav_Modules |\r\n| \\`usr_\\` | User profiles | usr_Profiles, usr_Preferences |\r\n| \\`ai_\\` | AI features | ai_Providers, ai_Models, ai_Prompts |\r\n| \\`cfg_\\` | Configuration | cfg_Settings |\r\n| \\`wkf_\\` | Workflows | wkf_EmailTemplates, wkf_Workflows |\r\n| \\`support_\\` | Support | support_Tickets, support_Comments |\r\n| \\`entra_\\` | Entra sync | entra_Groups, entra_SyncState |\r\n| \\`ref_\\` | References | ref_Companies, ref_Departments |\r\n| \\`loc_\\` | Localization | loc_Languages, loc_Translations |\r\n| \\`lic_\\` | Licensing | lic_Licenses |\r\n\r\n### Entity Configuration\r\n\r\n\\`\\`\\`csharp\r\npublic class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>\r\n{\r\n public void Configure(EntityTypeBuilder<MyEntity> builder)\r\n {\r\n // CORRECT: Use schema + domain prefix\r\n builder.ToTable(\"auth_Users\", \"${schemas.platform}\");\r\n\r\n // WRONG: No schema specified\r\n // builder.ToTable(\"auth_Users\");\r\n\r\n // WRONG: No domain prefix\r\n // builder.ToTable(\"Users\", \"${schemas.platform}\");\r\n }\r\n}\r\n\\`\\`\\`\r\n\r\n### Extending Core Entities\r\n\r\nWhen extending a core entity, use the \\`${schemas.extensions}\\` schema:\r\n\r\n\\`\\`\\`csharp\r\n// Client extension for auth_Users\r\npublic class UserExtension\r\n{\r\n public Guid UserId { get; set; } // FK to auth_Users\r\n public User User { get; set; }\r\n\r\n // Custom properties\r\n public string CustomField { get; set; }\r\n}\r\n\r\n// Configuration - use extensions schema\r\nbuilder.ToTable(\"client_UserExtensions\", \"${schemas.extensions}\");\r\nbuilder.HasOne(e => e.User)\r\n .WithOne()\r\n .HasForeignKey<UserExtension>(e => e.UserId);\r\n\\`\\`\\`\r\n\r\n---\r\n\r\n## 2. Migration Conventions\r\n\r\n### Naming Format\r\n\r\nMigrations MUST follow this naming pattern:\r\n\r\n\\`\\`\\`\r\n${migrationFormat}\r\n\\`\\`\\`\r\n\r\n| Part | Description | Example |\r\n|------|-------------|---------|\r\n| \\`{context}\\` | DbContext name | \\`core\\`, \\`extensions\\` |\r\n| \\`{version}\\` | Semver version | \\`v1.0.0\\`, \\`v1.2.0\\` |\r\n| \\`{sequence}\\` | Order in version | \\`001\\`, \\`002\\` |\r\n| \\`{Description}\\` | Action (PascalCase) | \\`CreateAuthUsers\\` |\r\n\r\n**Examples:**\r\n- \\`core_v1.0.0_001_InitialSchema.cs\\`\r\n- \\`core_v1.0.0_002_CreateAuthUsers.cs\\`\r\n- \\`core_v1.2.0_001_AddUserProfiles.cs\\`\r\n- \\`extensions_v1.0.0_001_AddClientFeatures.cs\\`\r\n\r\n### Creating Migrations\r\n\r\n\\`\\`\\`bash\r\n# Create a new migration\r\ndotnet ef migrations add core_v1.0.0_001_InitialSchema\r\n\r\n# With context specified\r\ndotnet ef migrations add core_v1.2.0_001_AddUserProfiles --context ApplicationDbContext\r\n\\`\\`\\`\r\n\r\n### Migration Rules\r\n\r\n1. **One migration per feature** - Group related changes in a single migration\r\n2. **Version-based naming** - Use semver (v1.0.0, v1.2.0) to link migrations to releases\r\n3. **Sequence numbers** - Use NNN (001, 002, etc.) for migrations in the same version\r\n4. **Context prefix** - Use \\`core_\\` for platform tables, \\`extensions_\\` for client extensions\r\n5. **Descriptive names** - Use clear PascalCase descriptions (CreateAuthUsers, AddUserProfiles, etc.)\r\n6. **Schema must be specified** - All tables must specify their schema in ToTable()\r\n\r\n---\r\n\r\n## 3. Namespace Conventions\r\n\r\n### Layer Structure\r\n\r\n| Layer | Namespace | Purpose |\r\n|-------|-----------|---------|\r\n| Domain | \\`${namespaces.domain}\\` | Entities, value objects, domain events |\r\n| Application | \\`${namespaces.application}\\` | Use cases, services, interfaces |\r\n| Infrastructure | \\`${namespaces.infrastructure}\\` | EF Core, external services |\r\n| API | \\`${namespaces.api}\\` | Controllers, DTOs, middleware |\r\n\r\n### Example Namespaces\r\n\r\n\\`\\`\\`csharp\r\n// Entity in Domain layer\r\nnamespace ${namespaces.domain}.Entities;\r\npublic class User { }\r\n\r\n// Service interface in Application layer\r\nnamespace ${namespaces.application}.Services;\r\npublic interface IUserService { }\r\n\r\n// EF Configuration in Infrastructure layer\r\nnamespace ${namespaces.infrastructure}.Persistence.Configurations;\r\npublic class UserConfiguration { }\r\n\r\n// Controller in API layer\r\nnamespace ${namespaces.api}.Controllers;\r\npublic class UsersController { }\r\n\\`\\`\\`\r\n\r\n---\r\n\r\n## 4. Service Conventions\r\n\r\n### Naming Pattern\r\n\r\n| Type | Pattern | Example |\r\n|------|---------|---------|\r\n| Interface | \\`${servicePattern.interface.replace('{Name}', '<Name>')}\\` | \\`IUserService\\` |\r\n| Implementation | \\`${servicePattern.implementation.replace('{Name}', '<Name>')}\\` | \\`UserService\\` |\r\n\r\n### Service Structure\r\n\r\n\\`\\`\\`csharp\r\n// Interface (in Application layer)\r\nnamespace ${namespaces.application}.Services;\r\n\r\npublic interface IUserService\r\n{\r\n Task<UserDto> GetByIdAsync(Guid id, CancellationToken ct = default);\r\n Task<IEnumerable<UserDto>> GetAllAsync(CancellationToken ct = default);\r\n Task<UserDto> CreateAsync(CreateUserCommand cmd, CancellationToken ct = default);\r\n Task UpdateAsync(Guid id, UpdateUserCommand cmd, CancellationToken ct = default);\r\n Task DeleteAsync(Guid id, CancellationToken ct = default);\r\n}\r\n\r\n// Implementation (in Infrastructure or Application layer)\r\npublic class UserService : IUserService\r\n{\r\n private readonly IRepository<User> _repository;\r\n private readonly ILogger<UserService> _logger;\r\n\r\n public UserService(IRepository<User> repository, ILogger<UserService> logger)\r\n {\r\n _repository = repository;\r\n _logger = logger;\r\n }\r\n\r\n // Implementation...\r\n}\r\n\\`\\`\\`\r\n\r\n### Dependency Injection\r\n\r\n\\`\\`\\`csharp\r\n// In DependencyInjection.cs or ServiceCollectionExtensions.cs\r\npublic static IServiceCollection AddApplicationServices(this IServiceCollection services)\r\n{\r\n services.AddScoped<IUserService, UserService>();\r\n services.AddScoped<IRoleService, RoleService>();\r\n // ...\r\n return services;\r\n}\r\n\\`\\`\\`\r\n\r\n---\r\n\r\n## 5. Extension Patterns\r\n\r\n### Extending Services\r\n\r\nUse DI replacement to override core services:\r\n\r\n\\`\\`\\`csharp\r\n// Your custom implementation\r\npublic class CustomUserService : UserService, IUserService\r\n{\r\n public CustomUserService(IRepository<User> repo, ILogger<CustomUserService> logger)\r\n : base(repo, logger) { }\r\n\r\n public override async Task<UserDto> GetByIdAsync(Guid id, CancellationToken ct = default)\r\n {\r\n // Custom logic before\r\n var result = await base.GetByIdAsync(id, ct);\r\n // Custom logic after\r\n return result;\r\n }\r\n}\r\n\r\n// Replace in DI\r\nservices.Replace(ServiceDescriptor.Scoped<IUserService, CustomUserService>());\r\n\\`\\`\\`\r\n\r\n### Extension Hooks\r\n\r\nCore services expose hooks for common extension points:\r\n\r\n\\`\\`\\`csharp\r\npublic interface IUserServiceHooks\r\n{\r\n Task OnUserCreatedAsync(User user, CancellationToken ct);\r\n Task OnUserUpdatedAsync(User user, CancellationToken ct);\r\n Task OnUserDeletedAsync(Guid userId, CancellationToken ct);\r\n}\r\n\\`\\`\\`\r\n\r\n---\r\n\r\n## 6. Configuration\r\n\r\n### appsettings.json Structure\r\n\r\n\\`\\`\\`json\r\n{\r\n \"AtlasHub\": {\r\n \"Licensing\": {\r\n \"Key\": \"XXXX-XXXX-XXXX-XXXX\",\r\n \"Validate\": true\r\n },\r\n \"Features\": {\r\n \"AI\": true,\r\n \"Support\": true,\r\n \"Workflows\": true\r\n }\r\n },\r\n \"Client\": {\r\n \"Custom\": {\r\n // Client-specific configuration\r\n }\r\n }\r\n}\r\n\\`\\`\\`\r\n\r\n---\r\n\r\n## Quick Reference\r\n\r\n| Category | Convention | Example |\r\n|----------|------------|---------|\r\n| Platform schema | \\`${schemas.platform}\\` | \\`.ToTable(\"auth_Users\", \"${schemas.platform}\")\\` |\r\n| Extensions schema | \\`${schemas.extensions}\\` | \\`.ToTable(\"client_Custom\", \"${schemas.extensions}\")\\` |\r\n| Table prefixes | \\`${tablePrefixes.slice(0, 5).join(', ')}\\`, etc. | \\`auth_Users\\`, \\`nav_Modules\\` |\r\n| Migration | \\`{context}_v{version}_{seq}_{Desc}\\` | \\`core_v1.0.0_001_CreateAuthUsers\\` |\r\n| Interface | \\`I<Name>Service\\` | \\`IUserService\\` |\r\n| Implementation | \\`<Name>Service\\` | \\`UserService\\` |\r\n| Domain namespace | \\`${namespaces.domain}\\` | - |\r\n| API namespace | \\`${namespaces.api}\\` | - |\r\n`;\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { detectProject, findSmartStackStructure } from '../lib/detector.js';\r\nimport { findFiles } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const projectInfoResourceTemplate: Resource = {\r\n uri: 'smartstack://project',\r\n name: 'SmartStack Project Info',\r\n description: 'Current SmartStack project information, structure, and configuration',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\nexport async function getProjectInfoResource(config: Config): Promise<string> {\r\n const projectPath = config.smartstack.projectPath;\r\n const projectInfo = await detectProject(projectPath);\r\n const structure = await findSmartStackStructure(projectPath);\r\n\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack Project Information');\r\n lines.push('');\r\n lines.push('## Overview');\r\n lines.push('');\r\n lines.push(`| Property | Value |`);\r\n lines.push(`|----------|-------|`);\r\n lines.push(`| **Name** | ${projectInfo.name} |`);\r\n lines.push(`| **Version** | ${projectInfo.version} |`);\r\n lines.push(`| **Path** | \\`${projectPath}\\` |`);\r\n lines.push(`| **Git Repository** | ${projectInfo.isGitRepo ? 'Yes' : 'No'} |`);\r\n if (projectInfo.currentBranch) {\r\n lines.push(`| **Current Branch** | \\`${projectInfo.currentBranch}\\` |`);\r\n }\r\n lines.push(`| **.NET Project** | ${projectInfo.hasDotNet ? 'Yes' : 'No'} |`);\r\n lines.push(`| **EF Core** | ${projectInfo.hasEfCore ? 'Yes' : 'No'} |`);\r\n if (projectInfo.dbContextName) {\r\n lines.push(`| **DbContext** | \\`${projectInfo.dbContextName}\\` |`);\r\n }\r\n lines.push(`| **React Frontend** | ${projectInfo.hasReact ? 'Yes' : 'No'} |`);\r\n lines.push('');\r\n\r\n // Project Structure\r\n lines.push('## Project Structure');\r\n lines.push('');\r\n lines.push('```');\r\n lines.push(`${projectInfo.name}/`);\r\n if (structure.domain) {\r\n lines.push(`├── ${path.basename(structure.domain)}/ # Domain layer (entities)`);\r\n }\r\n if (structure.application) {\r\n lines.push(`├── ${path.basename(structure.application)}/ # Application layer (services)`);\r\n }\r\n if (structure.infrastructure) {\r\n lines.push(`├── ${path.basename(structure.infrastructure)}/ # Infrastructure (EF Core)`);\r\n }\r\n if (structure.api) {\r\n lines.push(`├── ${path.basename(structure.api)}/ # API layer (controllers)`);\r\n }\r\n if (structure.web) {\r\n lines.push(`└── web/smartstack-web/ # React frontend`);\r\n }\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // .NET Projects\r\n if (projectInfo.csprojFiles.length > 0) {\r\n lines.push('## .NET Projects');\r\n lines.push('');\r\n lines.push('| Project | Path |');\r\n lines.push('|---------|------|');\r\n for (const csproj of projectInfo.csprojFiles) {\r\n const name = path.basename(csproj, '.csproj');\r\n const relativePath = path.relative(projectPath, csproj);\r\n lines.push(`| ${name} | \\`${relativePath}\\` |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Migrations info\r\n if (structure.migrations) {\r\n const migrationFiles = await findFiles('*.cs', {\r\n cwd: structure.migrations,\r\n ignore: ['*.Designer.cs'],\r\n });\r\n\r\n const migrations = migrationFiles\r\n .map(f => path.basename(f))\r\n .filter(f => !f.includes('ModelSnapshot') && !f.includes('.Designer.'))\r\n .sort();\r\n\r\n lines.push('## EF Core Migrations');\r\n lines.push('');\r\n lines.push(`**Location**: \\`${path.relative(projectPath, structure.migrations)}\\``);\r\n lines.push(`**Total Migrations**: ${migrations.length}`);\r\n lines.push('');\r\n\r\n if (migrations.length > 0) {\r\n lines.push('### Recent Migrations');\r\n lines.push('');\r\n const recent = migrations.slice(-5);\r\n for (const migration of recent) {\r\n lines.push(`- \\`${migration.replace('.cs', '')}\\``);\r\n }\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Configuration\r\n lines.push('## Configuration');\r\n lines.push('');\r\n lines.push('### MCP Server Config');\r\n lines.push('');\r\n lines.push('```json');\r\n lines.push(JSON.stringify({\r\n smartstack: config.smartstack,\r\n conventions: {\r\n schemas: config.conventions.schemas,\r\n tablePrefixes: config.conventions.tablePrefixes,\r\n migrationFormat: config.conventions.migrationFormat,\r\n },\r\n }, null, 2));\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // Quick Commands\r\n lines.push('## Quick Commands');\r\n lines.push('');\r\n lines.push('```bash');\r\n lines.push('# Build the solution');\r\n lines.push('dotnet build');\r\n lines.push('');\r\n lines.push('# Run API');\r\n lines.push(`cd ${structure.api ? path.relative(projectPath, structure.api) : 'SmartStack.Api'}`);\r\n lines.push('dotnet run');\r\n lines.push('');\r\n lines.push('# Run frontend');\r\n lines.push(`cd ${structure.web ? path.relative(projectPath, structure.web) : 'web/smartstack-web'}`);\r\n lines.push('npm run dev');\r\n lines.push('');\r\n lines.push('# Create migration');\r\n lines.push('dotnet ef migrations add YYYYMMDD_Core_NNN_Description');\r\n lines.push('');\r\n lines.push('# Apply migrations');\r\n lines.push('dotnet ef database update');\r\n lines.push('```');\r\n lines.push('');\r\n\r\n // MCP Tools Available\r\n lines.push('## Available MCP Tools');\r\n lines.push('');\r\n lines.push('| Tool | Description |');\r\n lines.push('|------|-------------|');\r\n lines.push('| `validate_conventions` | Check code against AtlasHub conventions |');\r\n lines.push('| `check_migrations` | Analyze EF Core migrations for conflicts |');\r\n lines.push('| `scaffold_extension` | Generate service, entity, controller, or component |');\r\n lines.push('| `api_docs` | Get API endpoint documentation |');\r\n lines.push('');\r\n\r\n return lines.join('\\n');\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { findControllerFiles, findSmartStackStructure } from '../lib/detector.js';\r\nimport { readText } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const apiEndpointsResourceTemplate: Resource = {\r\n uri: 'smartstack://api/',\r\n name: 'SmartStack API Endpoints',\r\n description: 'API endpoint documentation. Use smartstack://api/{endpoint} to filter.',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\ninterface ParsedEndpoint {\r\n method: string;\r\n path: string;\r\n controller: string;\r\n action: string;\r\n parameters: string[];\r\n returnType: string;\r\n authorize: boolean;\r\n summary?: string;\r\n}\r\n\r\nexport async function getApiEndpointsResource(\r\n config: Config,\r\n endpointFilter?: string\r\n): Promise<string> {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n if (!structure.api) {\r\n return '# API Endpoints\\n\\nNo API project found.';\r\n }\r\n\r\n const controllerFiles = await findControllerFiles(structure.api);\r\n const allEndpoints: ParsedEndpoint[] = [];\r\n\r\n for (const file of controllerFiles) {\r\n const endpoints = await parseController(file, structure.root);\r\n allEndpoints.push(...endpoints);\r\n }\r\n\r\n // Filter if specified\r\n const endpoints = endpointFilter\r\n ? allEndpoints.filter(e =>\r\n e.path.toLowerCase().includes(endpointFilter.toLowerCase()) ||\r\n e.controller.toLowerCase().includes(endpointFilter.toLowerCase())\r\n )\r\n : allEndpoints;\r\n\r\n return formatEndpoints(endpoints, endpointFilter);\r\n}\r\n\r\nasync function parseController(filePath: string, _rootPath: string): Promise<ParsedEndpoint[]> {\r\n const content = await readText(filePath);\r\n const fileName = path.basename(filePath, '.cs');\r\n const controllerName = fileName.replace('Controller', '');\r\n const endpoints: ParsedEndpoint[] = [];\r\n\r\n // Parse class-level route\r\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\r\n const baseRoute = routeMatch\r\n ? routeMatch[1].replace('[controller]', controllerName.toLowerCase())\r\n : `/api/${controllerName.toLowerCase()}`;\r\n\r\n // Check for class-level Authorize\r\n const classAuthorize = /\\[Authorize\\s*(?:\\([^)]*\\))?\\s*\\]\\s*(?:\\[.*\\]\\s*)*public\\s+class/.test(content);\r\n\r\n // Simple approach: find all HTTP method attributes\r\n const httpMethods = ['HttpGet', 'HttpPost', 'HttpPut', 'HttpPatch', 'HttpDelete'];\r\n let match: RegExpExecArray | null;\r\n\r\n for (const httpMethod of httpMethods) {\r\n const regex = new RegExp(\r\n `\\\\[${httpMethod}(?:\\\\s*\\\\(\\\\s*\"([^\"]*)\"\\\\s*\\\\))?\\\\]\\\\s*(?:\\\\[.*?\\\\]\\\\s*)*public\\\\s+(?:async\\\\s+)?(?:Task<)?(?:ActionResult<)?(\\\\w+)(?:[<>\\\\[\\\\],\\\\s\\\\w]*)?\\\\s+(\\\\w+)\\\\s*\\\\(([^)]*)\\\\)`,\r\n 'g'\r\n );\r\n\r\n while ((match = regex.exec(content)) !== null) {\r\n const routeSuffix = match[1] || '';\r\n const returnType = match[2];\r\n const actionName = match[3];\r\n const params = match[4];\r\n\r\n // Build full path\r\n let fullPath = baseRoute;\r\n if (routeSuffix) {\r\n fullPath = `${baseRoute}/${routeSuffix}`;\r\n }\r\n\r\n // Parse parameters\r\n const parameters = parseParameters(params);\r\n\r\n // Check for method-level authorize\r\n const methodAuthorize = content.substring(Math.max(0, match.index - 200), match.index)\r\n .includes('[Authorize');\r\n\r\n endpoints.push({\r\n method: httpMethod.replace('Http', '').toUpperCase(),\r\n path: fullPath.replace(/\\/+/g, '/'),\r\n controller: controllerName,\r\n action: actionName,\r\n parameters,\r\n returnType,\r\n authorize: classAuthorize || methodAuthorize,\r\n });\r\n }\r\n }\r\n\r\n return endpoints;\r\n}\r\n\r\nfunction parseParameters(paramsString: string): string[] {\r\n if (!paramsString.trim()) return [];\r\n\r\n const params: string[] = [];\r\n const parts = paramsString.split(',');\r\n\r\n for (const part of parts) {\r\n const trimmed = part.trim();\r\n if (!trimmed) continue;\r\n\r\n // Extract parameter name\r\n const match = trimmed.match(/(\\w+)\\s*(?:=.*)?$/);\r\n if (match) {\r\n // Include source attribute if present\r\n if (trimmed.includes('[FromBody]')) {\r\n params.push(`body: ${match[1]}`);\r\n } else if (trimmed.includes('[FromQuery]')) {\r\n params.push(`query: ${match[1]}`);\r\n } else if (trimmed.includes('[FromRoute]')) {\r\n params.push(`route: ${match[1]}`);\r\n } else {\r\n params.push(match[1]);\r\n }\r\n }\r\n }\r\n\r\n return params;\r\n}\r\n\r\nfunction formatEndpoints(endpoints: ParsedEndpoint[], filter?: string): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack API Endpoints');\r\n lines.push('');\r\n\r\n if (filter) {\r\n lines.push(`> Filtered by: \\`${filter}\\``);\r\n lines.push('');\r\n }\r\n\r\n if (endpoints.length === 0) {\r\n lines.push('No endpoints found matching the criteria.');\r\n return lines.join('\\n');\r\n }\r\n\r\n // Group by controller\r\n const byController = new Map<string, ParsedEndpoint[]>();\r\n for (const endpoint of endpoints) {\r\n const existing = byController.get(endpoint.controller) || [];\r\n existing.push(endpoint);\r\n byController.set(endpoint.controller, existing);\r\n }\r\n\r\n // Summary table\r\n lines.push('## Summary');\r\n lines.push('');\r\n lines.push(`**Total Endpoints**: ${endpoints.length}`);\r\n lines.push(`**Controllers**: ${byController.size}`);\r\n lines.push('');\r\n\r\n // Method distribution\r\n const methodCounts = new Map<string, number>();\r\n for (const endpoint of endpoints) {\r\n methodCounts.set(endpoint.method, (methodCounts.get(endpoint.method) || 0) + 1);\r\n }\r\n\r\n lines.push('| Method | Count |');\r\n lines.push('|--------|-------|');\r\n for (const [method, count] of methodCounts) {\r\n lines.push(`| ${method} | ${count} |`);\r\n }\r\n lines.push('');\r\n\r\n // Detailed by controller\r\n for (const [controller, controllerEndpoints] of byController) {\r\n lines.push(`## ${controller}Controller`);\r\n lines.push('');\r\n\r\n // Sort by path then method\r\n controllerEndpoints.sort((a, b) => {\r\n const pathCompare = a.path.localeCompare(b.path);\r\n if (pathCompare !== 0) return pathCompare;\r\n return a.method.localeCompare(b.method);\r\n });\r\n\r\n for (const endpoint of controllerEndpoints) {\r\n const authBadge = endpoint.authorize ? ' 🔒' : '';\r\n const methodColor = getMethodEmoji(endpoint.method);\r\n\r\n lines.push(`### ${methodColor} \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\r\n lines.push('');\r\n lines.push(`**Action**: \\`${endpoint.action}\\``);\r\n lines.push(`**Returns**: \\`${endpoint.returnType}\\``);\r\n\r\n if (endpoint.parameters.length > 0) {\r\n lines.push('');\r\n lines.push('**Parameters**:');\r\n for (const param of endpoint.parameters) {\r\n lines.push(`- \\`${param}\\``);\r\n }\r\n }\r\n\r\n lines.push('');\r\n }\r\n }\r\n\r\n // Quick reference table\r\n lines.push('## Quick Reference');\r\n lines.push('');\r\n lines.push('| Method | Path | Action | Auth |');\r\n lines.push('|--------|------|--------|------|');\r\n for (const endpoint of endpoints) {\r\n lines.push(\r\n `| ${endpoint.method} | \\`${endpoint.path}\\` | ${endpoint.action} | ${endpoint.authorize ? '🔒' : '✓'} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n return lines.join('\\n');\r\n}\r\n\r\nfunction getMethodEmoji(method: string): string {\r\n switch (method) {\r\n case 'GET': return '🔵';\r\n case 'POST': return '🟢';\r\n case 'PUT': return '🟡';\r\n case 'PATCH': return '🟠';\r\n case 'DELETE': return '🔴';\r\n default: return '⚪';\r\n }\r\n}\r\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\r\nimport type { Config } from '../types/index.js';\r\nimport { findSmartStackStructure, findEntityFiles } from '../lib/detector.js';\r\nimport { findFiles, readText } from '../utils/fs.js';\r\nimport path from 'path';\r\n\r\nexport const dbSchemaResourceTemplate: Resource = {\r\n uri: 'smartstack://schema/',\r\n name: 'SmartStack Database Schema',\r\n description: 'Database schema information. Use smartstack://schema/{table} to get specific table.',\r\n mimeType: 'text/markdown',\r\n};\r\n\r\ninterface EntityInfo {\r\n name: string;\r\n tableName: string;\r\n properties: PropertyInfo[];\r\n relationships: RelationshipInfo[];\r\n file: string;\r\n}\r\n\r\ninterface PropertyInfo {\r\n name: string;\r\n type: string;\r\n nullable: boolean;\r\n isPrimaryKey: boolean;\r\n maxLength?: number;\r\n}\r\n\r\ninterface RelationshipInfo {\r\n type: 'one-to-one' | 'one-to-many' | 'many-to-many';\r\n targetEntity: string;\r\n propertyName: string;\r\n}\r\n\r\nexport async function getDbSchemaResource(\r\n config: Config,\r\n tableFilter?: string\r\n): Promise<string> {\r\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\r\n\r\n if (!structure.domain && !structure.infrastructure) {\r\n return '# Database Schema\\n\\nNo domain or infrastructure project found.';\r\n }\r\n\r\n const entities: EntityInfo[] = [];\r\n\r\n // Parse entities from domain layer\r\n if (structure.domain) {\r\n const entityFiles = await findEntityFiles(structure.domain);\r\n for (const file of entityFiles) {\r\n const entity = await parseEntity(file, structure.root, config);\r\n if (entity) {\r\n entities.push(entity);\r\n }\r\n }\r\n }\r\n\r\n // Parse configurations from infrastructure layer for additional info\r\n if (structure.infrastructure) {\r\n await enrichFromConfigurations(entities, structure.infrastructure, config);\r\n }\r\n\r\n // Filter if specified\r\n const filteredEntities = tableFilter\r\n ? entities.filter(e =>\r\n e.name.toLowerCase().includes(tableFilter.toLowerCase()) ||\r\n e.tableName.toLowerCase().includes(tableFilter.toLowerCase())\r\n )\r\n : entities;\r\n\r\n return formatSchema(filteredEntities, tableFilter, config);\r\n}\r\n\r\nasync function parseEntity(\r\n filePath: string,\r\n rootPath: string,\r\n _config: Config\r\n): Promise<EntityInfo | null> {\r\n const content = await readText(filePath);\r\n\r\n // Find class declaration\r\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*(\\w+))?/);\r\n if (!classMatch) return null;\r\n\r\n const entityName = classMatch[1];\r\n\r\n // Skip non-entity classes\r\n if (entityName.endsWith('Dto') || entityName.endsWith('Command') ||\r\n entityName.endsWith('Query') || entityName.endsWith('Handler')) {\r\n return null;\r\n }\r\n\r\n const properties: PropertyInfo[] = [];\r\n const relationships: RelationshipInfo[] = [];\r\n\r\n // Parse properties\r\n const propertyPattern = /public\\s+(?:required\\s+)?(\\w+(?:<[\\w,\\s]+>)?)\\??\\s+(\\w+)\\s*\\{/g;\r\n let match;\r\n\r\n while ((match = propertyPattern.exec(content)) !== null) {\r\n const propertyType = match[1];\r\n const propertyName = match[2];\r\n\r\n // Skip navigation properties for now (we'll add them as relationships)\r\n if (propertyType.startsWith('ICollection') || propertyType.startsWith('List')) {\r\n // This is a collection navigation property\r\n const targetMatch = propertyType.match(/<(\\w+)>/);\r\n if (targetMatch) {\r\n relationships.push({\r\n type: 'one-to-many',\r\n targetEntity: targetMatch[1],\r\n propertyName,\r\n });\r\n }\r\n continue;\r\n }\r\n\r\n // Check if it's a reference navigation property\r\n const isNavigationProperty = /^[A-Z]/.test(propertyType) &&\r\n !['Guid', 'String', 'Int32', 'Int64', 'DateTime', 'DateTimeOffset',\r\n 'Boolean', 'Decimal', 'Double', 'Float', 'Byte'].includes(propertyType) &&\r\n !propertyType.includes('?');\r\n\r\n if (isNavigationProperty && !propertyType.includes('<')) {\r\n relationships.push({\r\n type: 'one-to-one',\r\n targetEntity: propertyType,\r\n propertyName,\r\n });\r\n continue;\r\n }\r\n\r\n properties.push({\r\n name: propertyName,\r\n type: mapCSharpType(propertyType),\r\n nullable: content.includes(`${propertyType}? ${propertyName}`) ||\r\n content.includes(`${propertyType}? ${propertyName}`),\r\n isPrimaryKey: propertyName === 'Id' || propertyName === `${entityName}Id`,\r\n });\r\n }\r\n\r\n // Default table name based on conventions (using cfg_ as default prefix for generic configs)\r\n const tableName = `cfg_${entityName}s`;\r\n\r\n return {\r\n name: entityName,\r\n tableName,\r\n properties,\r\n relationships,\r\n file: path.relative(rootPath, filePath),\r\n };\r\n}\r\n\r\nasync function enrichFromConfigurations(\r\n entities: EntityInfo[],\r\n infrastructurePath: string,\r\n _config: Config\r\n): Promise<void> {\r\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\r\n cwd: infrastructurePath,\r\n });\r\n\r\n for (const file of configFiles) {\r\n const content = await readText(file);\r\n\r\n // Find ToTable calls\r\n const tableMatch = content.match(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"/);\r\n if (tableMatch) {\r\n // Find which entity this configuration is for\r\n const entityMatch = content.match(/IEntityTypeConfiguration<(\\w+)>/);\r\n if (entityMatch) {\r\n const entityName = entityMatch[1];\r\n const entity = entities.find(e => e.name === entityName);\r\n if (entity) {\r\n entity.tableName = tableMatch[1];\r\n }\r\n }\r\n }\r\n\r\n // Find MaxLength constraints\r\n const maxLengthMatches = content.matchAll(/\\.Property\\s*\\(\\s*\\w+\\s*=>\\s*\\w+\\.(\\w+)\\s*\\)[\\s\\S]*?\\.HasMaxLength\\s*\\(\\s*(\\d+)\\s*\\)/g);\r\n for (const match of maxLengthMatches) {\r\n const propertyName = match[1];\r\n const maxLength = parseInt(match[2], 10);\r\n\r\n for (const entity of entities) {\r\n const property = entity.properties.find(p => p.name === propertyName);\r\n if (property) {\r\n property.maxLength = maxLength;\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nfunction mapCSharpType(csharpType: string): string {\r\n const typeMap: Record<string, string> = {\r\n 'Guid': 'uniqueidentifier',\r\n 'string': 'nvarchar',\r\n 'String': 'nvarchar',\r\n 'int': 'int',\r\n 'Int32': 'int',\r\n 'long': 'bigint',\r\n 'Int64': 'bigint',\r\n 'DateTime': 'datetime2',\r\n 'DateTimeOffset': 'datetimeoffset',\r\n 'bool': 'bit',\r\n 'Boolean': 'bit',\r\n 'decimal': 'decimal',\r\n 'Decimal': 'decimal',\r\n 'double': 'float',\r\n 'Double': 'float',\r\n 'float': 'real',\r\n 'Float': 'real',\r\n 'byte[]': 'varbinary',\r\n };\r\n\r\n // Handle nullable types\r\n const baseType = csharpType.replace('?', '');\r\n return typeMap[baseType] || 'nvarchar';\r\n}\r\n\r\nfunction formatSchema(\r\n entities: EntityInfo[],\r\n filter?: string,\r\n _config?: Config\r\n): string {\r\n const lines: string[] = [];\r\n\r\n lines.push('# SmartStack Database Schema');\r\n lines.push('');\r\n\r\n if (filter) {\r\n lines.push(`> Filtered by: \\`${filter}\\``);\r\n lines.push('');\r\n }\r\n\r\n if (entities.length === 0) {\r\n lines.push('No entities found matching the criteria.');\r\n return lines.join('\\n');\r\n }\r\n\r\n // Summary\r\n lines.push('## Summary');\r\n lines.push('');\r\n lines.push(`**Total Entities**: ${entities.length}`);\r\n lines.push('');\r\n\r\n // Table list\r\n lines.push('| Entity | Table | Properties | Relationships |');\r\n lines.push('|--------|-------|------------|---------------|');\r\n for (const entity of entities) {\r\n lines.push(\r\n `| ${entity.name} | \\`${entity.tableName}\\` | ${entity.properties.length} | ${entity.relationships.length} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Detailed schema for each entity\r\n for (const entity of entities) {\r\n lines.push(`## ${entity.name}`);\r\n lines.push('');\r\n lines.push(`**Table**: \\`${entity.tableName}\\``);\r\n lines.push(`**File**: \\`${entity.file}\\``);\r\n lines.push('');\r\n\r\n // Properties\r\n lines.push('### Columns');\r\n lines.push('');\r\n lines.push('| Column | SQL Type | Nullable | Notes |');\r\n lines.push('|--------|----------|----------|-------|');\r\n\r\n for (const prop of entity.properties) {\r\n const notes: string[] = [];\r\n if (prop.isPrimaryKey) notes.push('PK');\r\n if (prop.maxLength) notes.push(`MaxLength(${prop.maxLength})`);\r\n\r\n lines.push(\r\n `| ${prop.name} | ${prop.type} | ${prop.nullable ? 'Yes' : 'No'} | ${notes.join(', ')} |`\r\n );\r\n }\r\n lines.push('');\r\n\r\n // Relationships\r\n if (entity.relationships.length > 0) {\r\n lines.push('### Relationships');\r\n lines.push('');\r\n lines.push('| Type | Target | Property |');\r\n lines.push('|------|--------|----------|');\r\n\r\n for (const rel of entity.relationships) {\r\n const typeIcon = rel.type === 'one-to-one' ? '1:1' :\r\n rel.type === 'one-to-many' ? '1:N' : 'N:N';\r\n lines.push(`| ${typeIcon} | ${rel.targetEntity} | ${rel.propertyName} |`);\r\n }\r\n lines.push('');\r\n }\r\n\r\n // Sample EF configuration\r\n lines.push('### EF Core Configuration');\r\n lines.push('');\r\n lines.push('```csharp');\r\n lines.push(`public class ${entity.name}Configuration : IEntityTypeConfiguration<${entity.name}>`);\r\n lines.push('{');\r\n lines.push(` public void Configure(EntityTypeBuilder<${entity.name}> builder)`);\r\n lines.push(' {');\r\n lines.push(` builder.ToTable(\"${entity.tableName}\");`);\r\n lines.push('');\r\n const pk = entity.properties.find(p => p.isPrimaryKey);\r\n if (pk) {\r\n lines.push(` builder.HasKey(e => e.${pk.name});`);\r\n }\r\n lines.push(' }');\r\n lines.push('}');\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n // ER Diagram (text-based)\r\n if (entities.length > 1) {\r\n lines.push('## Entity Relationships');\r\n lines.push('');\r\n lines.push('```');\r\n\r\n for (const entity of entities) {\r\n for (const rel of entity.relationships) {\r\n const arrow = rel.type === 'one-to-one' ? '──' :\r\n rel.type === 'one-to-many' ? '─<' : '>─<';\r\n lines.push(`${entity.name} ${arrow} ${rel.targetEntity}`);\r\n }\r\n }\r\n\r\n lines.push('```');\r\n lines.push('');\r\n }\r\n\r\n return lines.join('\\n');\r\n}\r\n","#!/usr/bin/env node\r\n\r\nimport { runServer } from './server.js';\r\nimport { logger } from './lib/logger.js';\r\n\r\n// Handle uncaught errors\r\nprocess.on('uncaughtException', (error) => {\r\n logger.error('Uncaught exception', { error: error.message, stack: error.stack });\r\n process.exit(1);\r\n});\r\n\r\nprocess.on('unhandledRejection', (reason) => {\r\n logger.error('Unhandled rejection', { reason });\r\n process.exit(1);\r\n});\r\n\r\n// Start the server\r\nrunServer().catch((error) => {\r\n logger.error('Failed to start server', { error: error.message });\r\n process.exit(1);\r\n});\r\n"],"mappings":"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","names":["path","path","path","path","exec","promisify","execAsync","promisify","exec","path","path","path","formatResult","path","formatResult","path","path","path","endpoints","path"]}