@atlashub/smartstack-mcp 1.2.3 → 1.4.1

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';\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 codePrefixes: {\r\n core: 'core_',\r\n extension: 'ext_',\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 codePrefixes: {\r\n ...base.conventions.codePrefixes,\r\n ...override.conventions?.codePrefixes,\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 codePrefixes: z.object({\r\n core: z.string().default('core_'),\r\n extension: z.string().default('ext_'),\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', 'entities', '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 isSystemEntity: z.boolean().optional().describe('If true, creates a system entity without TenantId'),\r\n tablePrefix: z.string().optional().describe('Domain prefix for table name (e.g., \"auth_\", \"nav_\", \"cfg_\")'),\r\n schema: z.enum(['core', 'extensions']).optional().describe('Database schema (default: core)'),\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 isSystemEntity: {\r\n type: 'boolean',\r\n description: 'If true, creates a system entity without TenantId (for entity type)',\r\n },\r\n tablePrefix: {\r\n type: 'string',\r\n description: 'Domain prefix for table name (e.g., \"auth_\", \"nav_\", \"cfg_\")',\r\n },\r\n schema: {\r\n type: 'string',\r\n enum: ['core', 'extensions'],\r\n description: 'Database schema (default: core)',\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; isSystemEntity?: boolean; tablePrefix?: string; schema?: 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 const isSystemEntity = options?.isSystemEntity || false;\r\n const tablePrefix = options?.tablePrefix || 'ref_';\r\n const schema = options?.schema || config.conventions.schemas.platform;\r\n\r\n // Entity template with full conventions (TenantId, Code, SoftDelete, RowVersion)\r\n const entityTemplate = `using System;\r\nusing SmartStack.Domain.Common;\r\nusing SmartStack.Domain.Common.Interfaces;\r\n\r\nnamespace {{namespace}};\r\n\r\n/// <summary>\r\n/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}\r\n/// </summary>\r\n{{#if isSystemEntity}}\r\npublic class {{name}} : SystemEntity\r\n{{else}}\r\npublic class {{name}} : BaseEntity\r\n{{/if}}\r\n{\r\n{{#if baseEntity}}\r\n /// <summary>\r\n /// Foreign key to {{baseEntity}}\r\n /// </summary>\r\n public Guid {{baseEntity}}Id { get; private set; }\r\n\r\n /// <summary>\r\n /// Navigation property to {{baseEntity}}\r\n /// </summary>\r\n public virtual {{baseEntity}}? {{baseEntity}} { get; private set; }\r\n\r\n{{/if}}\r\n // === BUSINESS PROPERTIES ===\r\n // TODO: Add {{name}} specific properties here\r\n\r\n /// <summary>\r\n /// Private constructor for EF Core\r\n /// </summary>\r\n private {{name}}() { }\r\n\r\n /// <summary>\r\n /// Factory method to create a new {{name}}\r\n /// </summary>\r\n{{#if isSystemEntity}}\r\n public static {{name}} Create(\r\n string code,\r\n string? createdBy = null)\r\n {\r\n return new {{name}}\r\n {\r\n Id = Guid.NewGuid(),\r\n Code = code.ToLowerInvariant(),\r\n CreatedAt = DateTime.UtcNow,\r\n CreatedBy = createdBy\r\n };\r\n }\r\n{{else}}\r\n public static {{name}} Create(\r\n Guid tenantId,\r\n string code,\r\n string? createdBy = null)\r\n {\r\n return new {{name}}\r\n {\r\n Id = Guid.NewGuid(),\r\n TenantId = tenantId,\r\n Code = code.ToLowerInvariant(),\r\n CreatedAt = DateTime.UtcNow,\r\n CreatedBy = createdBy\r\n };\r\n }\r\n{{/if}}\r\n\r\n /// <summary>\r\n /// Update the entity\r\n /// </summary>\r\n public void Update(string? updatedBy = null)\r\n {\r\n UpdatedAt = DateTime.UtcNow;\r\n UpdatedBy = updatedBy;\r\n }\r\n\r\n /// <summary>\r\n /// Soft delete the entity\r\n /// </summary>\r\n public void SoftDelete(string? deletedBy = null)\r\n {\r\n IsDeleted = true;\r\n DeletedAt = DateTime.UtcNow;\r\n DeletedBy = deletedBy;\r\n }\r\n\r\n /// <summary>\r\n /// Restore a soft-deleted entity\r\n /// </summary>\r\n public void Restore(string? restoredBy = null)\r\n {\r\n IsDeleted = false;\r\n DeletedAt = null;\r\n DeletedBy = null;\r\n UpdatedAt = DateTime.UtcNow;\r\n UpdatedBy = restoredBy;\r\n }\r\n}\r\n`;\r\n\r\n // EF Configuration template with full conventions\r\n const configTemplate = `using Microsoft.EntityFrameworkCore;\r\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\r\nusing {{domainNamespace}};\r\n\r\nnamespace {{infrastructureNamespace}}.Persistence.Configurations;\r\n\r\npublic class {{name}}Configuration : IEntityTypeConfiguration<{{name}}>\r\n{\r\n public void Configure(EntityTypeBuilder<{{name}}> builder)\r\n {\r\n // Table name with schema and domain prefix\r\n builder.ToTable(\"{{tablePrefix}}{{name}}s\", \"{{schema}}\");\r\n\r\n // Primary key\r\n builder.HasKey(e => e.Id);\r\n\r\n{{#unless isSystemEntity}}\r\n // Multi-tenant\r\n builder.Property(e => e.TenantId).IsRequired();\r\n builder.HasIndex(e => e.TenantId);\r\n\r\n // Code: lowercase, unique per tenant (filtered for soft delete)\r\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\r\n builder.HasIndex(e => new { e.TenantId, e.Code })\r\n .IsUnique()\r\n .HasFilter(\"[IsDeleted] = 0\")\r\n .HasDatabaseName(\"IX_{{tablePrefix}}{{name}}s_Tenant_Code_Unique\");\r\n{{else}}\r\n // Code: lowercase, unique (filtered for soft delete)\r\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\r\n builder.HasIndex(e => e.Code)\r\n .IsUnique()\r\n .HasFilter(\"[IsDeleted] = 0\")\r\n .HasDatabaseName(\"IX_{{tablePrefix}}{{name}}s_Code_Unique\");\r\n{{/unless}}\r\n\r\n // Concurrency token\r\n builder.Property(e => e.RowVersion).IsRowVersion();\r\n\r\n // Audit fields\r\n builder.Property(e => e.CreatedBy).HasMaxLength(256);\r\n builder.Property(e => e.UpdatedBy).HasMaxLength(256);\r\n builder.Property(e => e.DeletedBy).HasMaxLength(256);\r\n\r\n{{#if baseEntity}}\r\n // Relationship to {{baseEntity}} (1:1)\r\n builder.HasOne(e => e.{{baseEntity}})\r\n .WithOne()\r\n .HasForeignKey<{{name}}>(e => e.{{baseEntity}}Id)\r\n .OnDelete(DeleteBehavior.Cascade);\r\n\r\n // Index on foreign key\r\n builder.HasIndex(e => e.{{baseEntity}}Id)\r\n .IsUnique();\r\n{{/if}}\r\n\r\n // TODO: Add additional configuration\r\n }\r\n}\r\n`;\r\n\r\n const context = {\r\n namespace,\r\n name,\r\n baseEntity,\r\n isSystemEntity,\r\n tablePrefix,\r\n schema,\r\n infrastructureNamespace: config.conventions.namespaces.infrastructure,\r\n domainNamespace: config.conventions.namespaces.domain,\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 core_vX.X.X_XXX_Add${name} --context ApplicationDbContext`);\r\n result.instructions.push('');\r\n result.instructions.push('Required fields from BaseEntity:');\r\n result.instructions.push(`- Id (Guid), ${isSystemEntity ? '' : 'TenantId (Guid), '}Code (string, lowercase)`);\r\n result.instructions.push('- CreatedAt, UpdatedAt, CreatedBy, UpdatedBy (audit)');\r\n result.instructions.push('- IsDeleted, DeletedAt, DeletedBy (soft delete)');\r\n result.instructions.push('- RowVersion (concurrency)');\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, codePrefixes, 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### Navigation Code Prefixes\r\n\r\nAll navigation data (Context, Application, Module, Section, Resource) uses code prefixes to distinguish system data from client extensions:\r\n\r\n| Origin | Prefix | Usage | Example |\r\n|--------|--------|-------|---------|\r\n| SmartStack (system) | \\`${codePrefixes.core}\\` | Protected, delivered with SmartStack | \\`${codePrefixes.core}administration\\` |\r\n| Client (extension) | \\`${codePrefixes.extension}\\` | Custom, added by clients | \\`${codePrefixes.extension}it\\` |\r\n\r\n**Navigation Hierarchy (5 levels):**\r\n\r\n\\`\\`\\`\r\nContext → Application → Module → Section → Resource\r\n\\`\\`\\`\r\n\r\n**Examples for each level:**\r\n\r\n| Level | Core Example | Extension Example |\r\n|-------|--------------|-------------------|\r\n| Context | \\`${codePrefixes.core}administration\\` | \\`${codePrefixes.extension}it\\` |\r\n| Application | \\`${codePrefixes.core}settings\\` | \\`${codePrefixes.extension}custom_app\\` |\r\n| Module | \\`${codePrefixes.core}users\\` | \\`${codePrefixes.extension}inventory\\` |\r\n| Section | \\`${codePrefixes.core}management\\` | \\`${codePrefixes.extension}reports\\` |\r\n| Resource | \\`${codePrefixes.core}user_list\\` | \\`${codePrefixes.extension}stock_view\\` |\r\n\r\n**Rules:**\r\n1. \\`${codePrefixes.core}*\\` codes are **protected** - clients cannot create or modify them\r\n2. \\`${codePrefixes.extension}*\\` codes are **free** - clients can create custom navigation\r\n3. SmartStack updates will never overwrite \\`${codePrefixes.extension}*\\` data\r\n4. Codes must be unique within their level (e.g., no two Contexts with same code)\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## 7. Entity Conventions\r\n\r\n### Required Interfaces\r\n\r\nAll entities MUST implement the following interfaces:\r\n\r\n| Interface | Properties | Required |\r\n|-----------|------------|----------|\r\n| \\`ITenantEntity\\` | \\`TenantId\\` (Guid) | **YES** (except system entities) |\r\n| \\`IHasCode\\` | \\`Code\\` (string, lowercase, max 100) | **YES** |\r\n| \\`ISoftDeletable\\` | \\`IsDeleted\\`, \\`DeletedAt\\`, \\`DeletedBy\\` | **YES** |\r\n| \\`IVersioned\\` | \\`RowVersion\\` (byte[]) | **YES** |\r\n| \\`IHistoryEntity<T>\\` | \\`SourceId\\`, \\`ChangeType\\`, \\`OldValues\\`, \\`NewValues\\`, \\`ChangedAt\\`, \\`ChangedBy\\` | For history tables |\r\n\r\n### Required Fields (All Entities)\r\n\r\n| Field | Type | Description |\r\n|-------|------|-------------|\r\n| \\`Id\\` | \\`Guid\\` | Primary key |\r\n| \\`TenantId\\` | \\`Guid\\` | **Tenant identifier** (required for multi-tenant isolation) |\r\n| \\`Code\\` | \\`string\\` | Unique identifier per tenant (lowercase, max 100) |\r\n| \\`CreatedAt\\` | \\`DateTime\\` | Creation timestamp |\r\n| \\`UpdatedAt\\` | \\`DateTime?\\` | Last update timestamp |\r\n| \\`CreatedBy\\` | \\`string?\\` | User who created the entity |\r\n| \\`UpdatedBy\\` | \\`string?\\` | User who last updated the entity |\r\n| \\`IsDeleted\\` | \\`bool\\` | Soft delete flag |\r\n| \\`DeletedAt\\` | \\`DateTime?\\` | Deletion timestamp |\r\n| \\`DeletedBy\\` | \\`string?\\` | User who deleted the entity |\r\n| \\`RowVersion\\` | \\`byte[]\\` | Concurrency token |\r\n\r\n### Multi-Tenant Strategy\r\n\r\n\\`\\`\\`csharp\r\n// Interface for tenant-scoped entities\r\npublic interface ITenantEntity\r\n{\r\n Guid TenantId { get; set; }\r\n}\r\n\r\n// Global query filter (applied automatically)\r\nbuilder.HasQueryFilter(e => e.TenantId == _currentTenantService.TenantId);\r\n\\`\\`\\`\r\n\r\n**System Entities (without TenantId):**\r\n- Licenses (\\`lic_\\`)\r\n- Global configuration (\\`cfg_\\` system level)\r\n- Shared reference tables\r\n\r\nUse \\`ISystemEntity\\` marker interface for these entities.\r\n\r\n### Code Field Rules\r\n\r\n1. **Always lowercase** - Normalized via setter and value converter\r\n2. **Prefix required**: \\`${codePrefixes.core}\\` (system) or \\`${codePrefixes.extension}\\` (extensions)\r\n3. **Unique composite index**: \\`(TenantId, Code) WHERE IsDeleted = 0\\`\r\n4. **Max length**: 100 characters\r\n\r\n\\`\\`\\`csharp\r\n// Code property with automatic lowercase normalization\r\nprivate string _code = string.Empty;\r\npublic string Code\r\n{\r\n get => _code;\r\n set => _code = value?.ToLowerInvariant() ?? string.Empty;\r\n}\r\n\\`\\`\\`\r\n\r\n### Soft Delete with Restore\r\n\r\n\\`\\`\\`csharp\r\npublic interface ISoftDeletable\r\n{\r\n bool IsDeleted { get; set; }\r\n DateTime? DeletedAt { get; set; }\r\n string? DeletedBy { get; set; }\r\n}\r\n\r\n// Domain methods\r\npublic void SoftDelete(string? deletedBy = null)\r\n{\r\n IsDeleted = true;\r\n DeletedAt = DateTime.UtcNow;\r\n DeletedBy = deletedBy;\r\n}\r\n\r\npublic void Restore(string? restoredBy = null)\r\n{\r\n IsDeleted = false;\r\n DeletedAt = null;\r\n DeletedBy = null;\r\n UpdatedAt = DateTime.UtcNow;\r\n UpdatedBy = restoredBy;\r\n}\r\n\\`\\`\\`\r\n\r\n### History Tables (JSON Pattern)\r\n\r\n\\`\\`\\`csharp\r\npublic interface IHistoryEntity<TSourceId>\r\n{\r\n Guid Id { get; set; }\r\n TSourceId SourceId { get; set; }\r\n ChangeType ChangeType { get; set; } // Created, Updated, Deleted\r\n DateTime ChangedAt { get; set; }\r\n string? ChangedBy { get; set; }\r\n string? OldValues { get; set; } // JSON snapshot before change\r\n string? NewValues { get; set; } // JSON snapshot after change\r\n}\r\n\r\npublic enum ChangeType { Created = 1, Updated = 2, Deleted = 3 }\r\n\\`\\`\\`\r\n\r\n### Complete Entity Example\r\n\r\n\\`\\`\\`csharp\r\npublic class MyEntity : BaseEntity\r\n{\r\n // === REQUIRED (from BaseEntity) ===\r\n // public Guid Id { get; set; }\r\n // public Guid TenantId { get; set; }\r\n // public string Code { get; set; } // lowercase, unique per tenant\r\n // public DateTime CreatedAt { get; set; }\r\n // public DateTime? UpdatedAt { get; set; }\r\n // public string? CreatedBy { get; set; }\r\n // public string? UpdatedBy { get; set; }\r\n // public bool IsDeleted { get; set; }\r\n // public DateTime? DeletedAt { get; set; }\r\n // public string? DeletedBy { get; set; }\r\n // public byte[] RowVersion { get; set; }\r\n\r\n // === BUSINESS PROPERTIES ===\r\n public string Name { get; private set; } = null!;\r\n\r\n private MyEntity() { }\r\n\r\n public static MyEntity Create(Guid tenantId, string code, string name, string? createdBy = null)\r\n {\r\n return new MyEntity\r\n {\r\n Id = Guid.NewGuid(),\r\n TenantId = tenantId,\r\n Code = code.ToLowerInvariant(),\r\n Name = name,\r\n CreatedAt = DateTime.UtcNow,\r\n CreatedBy = createdBy\r\n };\r\n }\r\n}\r\n\\`\\`\\`\r\n\r\n### EF Core 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 builder.ToTable(\"domain_MyEntities\", \"${schemas.platform}\");\r\n builder.HasKey(e => e.Id);\r\n\r\n // Multi-tenant\r\n builder.Property(e => e.TenantId).IsRequired();\r\n builder.HasIndex(e => e.TenantId);\r\n\r\n // Code: lowercase, unique per tenant (filtered)\r\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\r\n builder.HasIndex(e => new { e.TenantId, e.Code })\r\n .IsUnique()\r\n .HasFilter(\"[IsDeleted] = 0\");\r\n\r\n // Concurrency\r\n builder.Property(e => e.RowVersion).IsRowVersion();\r\n\r\n // Audit fields\r\n builder.Property(e => e.CreatedBy).HasMaxLength(256);\r\n builder.Property(e => e.UpdatedBy).HasMaxLength(256);\r\n builder.Property(e => e.DeletedBy).HasMaxLength(256);\r\n }\r\n}\r\n\\`\\`\\`\r\n\r\n### Entity Types Summary\r\n\r\n| Type | Fields | Use Case |\r\n|------|--------|----------|\r\n| **BaseEntity** | All required fields | Standard tenant-scoped entities |\r\n| **SystemEntity** | All except TenantId | Shared system entities |\r\n| **HistoryEntity** | Id, TenantId, SourceId, ChangeType, Values, ChangedAt/By | Audit trail tables |\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| Core code prefix | \\`${codePrefixes.core}\\` | \\`${codePrefixes.core}administration\\` |\r\n| Extension code prefix | \\`${codePrefixes.extension}\\` | \\`${codePrefixes.extension}custom_module\\` |\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| Required entity fields | Id, TenantId, Code, Audit, SoftDelete, RowVersion | See Entity Conventions |\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":";;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACOP,IAAM,SAAN,MAAa;AAAA,EACH,QAAkB;AAAA,EACT,SAAmC;AAAA,IAClD,OAAO;AAAA,IACP,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAuB;AAC9B,SAAK,QAAQ;AAAA,EACf;AAAA,EAEQ,UAAU,OAA0B;AAC1C,WAAO,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;AAAA,EACrD;AAAA,EAEQ,YAAY,OAAiB,SAAiB,MAAwB;AAC5E,UAAM,QAAkB;AAAA,MACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC;AAAA,MACA;AAAA,MACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,IACnC;AACA,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AAAA,EAEA,MAAM,SAAiB,MAAsB;AAC3C,QAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,cAAQ,MAAM,KAAK,YAAY,SAAS,SAAS,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AAAA,EAEA,KAAK,SAAiB,MAAsB;AAC1C,QAAI,KAAK,UAAU,MAAM,GAAG;AAC1B,cAAQ,MAAM,KAAK,YAAY,QAAQ,SAAS,IAAI,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,KAAK,SAAiB,MAAsB;AAC1C,QAAI,KAAK,UAAU,MAAM,GAAG;AAC1B,cAAQ,MAAM,KAAK,YAAY,QAAQ,SAAS,IAAI,CAAC;AAAA,IACvD;AAAA,EACF;AAAA,EAEA,MAAM,SAAiB,MAAsB;AAC3C,QAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,cAAQ,MAAM,KAAK,YAAY,SAAS,SAAS,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AAAA;AAAA,EAGA,UAAU,UAAkB,MAAqB;AAC/C,SAAK,KAAK,iBAAiB,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,EACjD;AAAA,EAEA,QAAQ,UAAkB,SAAkB,UAAyB;AACnE,SAAK,KAAK,mBAAmB,QAAQ,IAAI,EAAE,SAAS,SAAS,CAAC;AAAA,EAChE;AAAA,EAEA,UAAU,UAAkB,OAAoB;AAC9C,SAAK,MAAM,gBAAgB,QAAQ,IAAI;AAAA,MACrC,OAAO,MAAM;AAAA,MACb,OAAO,MAAM;AAAA,IACf,CAAC;AAAA,EACH;AACF;AAEO,IAAM,SAAS,IAAI,OAAO;AAGjC,IAAM,WAAW,QAAQ,IAAI;AAC7B,IAAI,YAAY,CAAC,SAAS,QAAQ,QAAQ,OAAO,EAAE,SAAS,QAAQ,GAAG;AACrE,SAAO,SAAS,QAAQ;AAC1B;;;ACxFA,OAAOA,WAAU;;;ACAjB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,YAAY;AAKrB,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,OAAO,MAAM,GAAG,KAAK,QAAQ;AACnC,WAAO,KAAK,OAAO;AAAA,EACrB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBAAgB,SAAmC;AACvE,MAAI;AACF,UAAM,OAAO,MAAM,GAAG,KAAK,OAAO;AAClC,WAAO,KAAK,YAAY;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBAAgB,SAAgC;AACpE,QAAM,GAAG,UAAU,OAAO;AAC5B;AAKA,eAAsB,SAAY,UAA8B;AAC9D,QAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,SAAO,KAAK,MAAM,OAAO;AAC3B;AAaA,eAAsB,SAAS,UAAmC;AAChE,SAAO,GAAG,SAAS,UAAU,OAAO;AACtC;AAKA,eAAsB,UAAU,UAAkB,SAAgC;AAChF,QAAM,GAAG,UAAU,KAAK,QAAQ,QAAQ,CAAC;AACzC,QAAM,GAAG,UAAU,UAAU,SAAS,OAAO;AAC/C;AA2BA,eAAsB,UACpB,SACA,UAA+C,CAAC,GAC7B;AACnB,QAAM,EAAE,MAAM,QAAQ,IAAI,GAAG,SAAS,CAAC,EAAE,IAAI;AAE7C,QAAM,QAAQ,MAAM,KAAK,SAAS;AAAA,IAChC;AAAA,IACA,QAAQ,CAAC,sBAAsB,aAAa,aAAa,GAAG,MAAM;AAAA,IAClE,UAAU;AAAA,IACV,OAAO;AAAA,EACT,CAAC;AAED,SAAO;AACT;;;ADnGA,IAAM,gBAAwB;AAAA,EAC5B,SAAS;AAAA,EACT,YAAY;AAAA,IACV,aAAa,QAAQ,IAAI,2BAA2B;AAAA,IACpD,QAAQ,QAAQ,IAAI,sBAAsB;AAAA,IAC1C,YAAY,QAAQ,IAAI,2BAA2B;AAAA,EACrD;AAAA,EACA,aAAa;AAAA,IACX,SAAS;AAAA,MACP,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,IACA,eAAe;AAAA,MACb;AAAA,MAAS;AAAA,MAAQ;AAAA,MAAQ;AAAA,MAAO;AAAA,MAAQ;AAAA,MACxC;AAAA,MAAY;AAAA,MAAU;AAAA,MAAQ;AAAA,MAAQ;AAAA,IACxC;AAAA,IACA,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,IACA,iBAAiB;AAAA,IACjB,YAAY;AAAA,MACV,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,gBAAgB;AAAA,MAChB,KAAK;AAAA,IACP;AAAA,IACA,gBAAgB;AAAA,MACd,WAAW;AAAA,MACX,gBAAgB;AAAA,IAClB;AAAA,EACF;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,MACR;AAAA,QACE,MAAM;AAAA,QACN,aAAa;AAAA,QACb,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,YAAY;AAAA,MACV,oBAAoB;AAAA,MACpB,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,IACvB;AAAA,EACF;AAAA,EACA,aAAa;AAAA,IACX,YAAY;AAAA,IACZ,WAAW;AAAA,MACT,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,WAAW;AAAA,IACb;AAAA,EACF;AACF;AAEA,IAAI,eAA8B;AAKlC,eAAsB,YAA6B;AACjD,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAGA,QAAM,aAAaC,MAAK,KAAK,QAAQ,IAAI,GAAG,UAAU,qBAAqB;AAE3E,MAAI,MAAM,WAAW,UAAU,GAAG;AAChC,QAAI;AACF,YAAM,aAAa,MAAM,SAA0B,UAAU;AAC7D,qBAAe,YAAY,eAAe,UAAU;AACpD,aAAO,KAAK,kCAAkC,EAAE,MAAM,WAAW,CAAC;AAAA,IACpE,SAAS,OAAO;AACd,aAAO,KAAK,8CAA8C,EAAE,MAAM,CAAC;AACnE,qBAAe;AAAA,IACjB;AAAA,EACF,OAAO;AACL,WAAO,MAAM,sCAAsC;AACnD,mBAAe;AAAA,EACjB;AAGA,MAAI,QAAQ,IAAI,yBAAyB;AACvC,iBAAa,WAAW,cAAc,QAAQ,IAAI;AAAA,EACpD;AACA,MAAI,QAAQ,IAAI,oBAAoB;AAClC,iBAAa,WAAW,SAAS,QAAQ,IAAI;AAAA,EAC/C;AAEA,SAAO;AACT;AAKA,SAAS,YAAY,MAAc,UAAmC;AACpE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,YAAY;AAAA,MACV,GAAG,KAAK;AAAA,MACR,GAAG,SAAS;AAAA,IACd;AAAA,IACA,aAAa;AAAA,MACX,GAAG,KAAK;AAAA,MACR,GAAG,SAAS;AAAA,MACZ,SAAS;AAAA,QACP,GAAG,KAAK,YAAY;AAAA,QACpB,GAAG,SAAS,aAAa;AAAA,MAC3B;AAAA,MACA,cAAc;AAAA,QACZ,GAAG,KAAK,YAAY;AAAA,QACpB,GAAG,SAAS,aAAa;AAAA,MAC3B;AAAA,MACA,YAAY;AAAA,QACV,GAAG,KAAK,YAAY;AAAA,QACpB,GAAG,SAAS,aAAa;AAAA,MAC3B;AAAA,MACA,gBAAgB;AAAA,QACd,GAAG,KAAK,YAAY;AAAA,QACpB,GAAG,SAAS,aAAa;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,GAAG,KAAK;AAAA,MACR,GAAG,SAAS;AAAA,MACZ,UAAU,SAAS,QAAQ,YAAY,KAAK,OAAO;AAAA,MACnD,YAAY;AAAA,QACV,GAAG,KAAK,OAAO;AAAA,QACf,GAAG,SAAS,QAAQ;AAAA,MACtB;AAAA,IACF;AAAA,IACA,aAAa;AAAA,MACX,GAAG,KAAK;AAAA,MACR,GAAG,SAAS;AAAA,MACZ,WAAW;AAAA,QACT,GAAG,KAAK,YAAY;AAAA,QACpB,GAAG,SAAS,aAAa;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;;;AEtJA,SAAS,SAAS;AAMX,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC7C,aAAa,EAAE,OAAO;AAAA,EACtB,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EAClC,YAAY,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACtC,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,SAAS,EAAE,OAAO;AAAA,IAChB,UAAU,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,IACnC,YAAY,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,EAC7C,CAAC;AAAA,EACD,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ;AAAA,IACzC;AAAA,IAAS;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAO;AAAA,IAAQ;AAAA,IACxC;AAAA,IAAY;AAAA,IAAU;AAAA,IAAQ;AAAA,IAAQ;AAAA,EACxC,CAAC;AAAA,EACD,cAAc,EAAE,OAAO;AAAA,IACrB,MAAM,EAAE,OAAO,EAAE,QAAQ,OAAO;AAAA,IAChC,WAAW,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,EACtC,CAAC;AAAA,EACD,iBAAiB,EAAE,OAAO,EAAE,QAAQ,+CAA+C;AAAA,EACnF,YAAY,EAAE,OAAO;AAAA,IACnB,QAAQ,EAAE,OAAO;AAAA,IACjB,aAAa,EAAE,OAAO;AAAA,IACtB,gBAAgB,EAAE,OAAO;AAAA,IACzB,KAAK,EAAE,OAAO;AAAA,EAChB,CAAC;AAAA,EACD,gBAAgB,EAAE,OAAO;AAAA,IACvB,WAAW,EAAE,OAAO,EAAE,QAAQ,gBAAgB;AAAA,IAC9C,gBAAgB,EAAE,OAAO,EAAE,QAAQ,eAAe;AAAA,EACpD,CAAC;AACH,CAAC;AAEM,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC1C,MAAM,EAAE,OAAO;AAAA,EACf,aAAa,EAAE,OAAO;AAAA,EACtB,kBAAkB,EAAE,OAAO,EAAE,QAAQ,YAAY;AACnD,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,UAAU,EAAE,MAAM,mBAAmB;AAAA,EACrC,YAAY,EAAE,OAAO;AAAA,IACnB,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,IAC5C,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,IAC7C,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,EAC/C,CAAC;AACH,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,YAAY,EAAE,OAAO;AAAA,EACrB,WAAW,EAAE,OAAO;AAAA,IAClB,SAAS,EAAE,OAAO;AAAA,IAClB,QAAQ,EAAE,OAAO;AAAA,IACjB,YAAY,EAAE,OAAO;AAAA,IACrB,WAAW,EAAE,OAAO;AAAA,EACtB,CAAC;AACH,CAAC;AAEM,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,OAAO;AAAA,EAClB,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,aAAa;AACf,CAAC;AAWM,IAAM,iCAAiC,EAAE,OAAO;AAAA,EACrD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,EAC9F,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,cAAc,YAAY,cAAc,YAAY,KAAK,CAAC,CAAC,EAC1F,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,4BAA4B;AAC1C,CAAC;AAEM,IAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EAClE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,EAC/E,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAC3E,CAAC;AAEM,IAAM,+BAA+B,EAAE,OAAO;AAAA,EACnD,MAAM,EAAE,KAAK,CAAC,WAAW,UAAU,cAAc,WAAW,CAAC,EAC1D,SAAS,+BAA+B;AAAA,EAC3C,MAAM,EAAE,OAAO,EAAE,SAAS,sDAAsD;AAAA,EAChF,SAAS,EAAE,OAAO;AAAA,IAChB,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC5D,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,IACpF,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,IACzF,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,IAC/D,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,IACnG,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,IAC1G,QAAQ,EAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,EAC9F,CAAC,EAAE,SAAS;AACd,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EACvF,QAAQ,EAAE,KAAK,CAAC,YAAY,QAAQ,SAAS,CAAC,EAAE,QAAQ,UAAU,EAC/D,SAAS,eAAe;AAAA,EAC3B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AACxE,CAAC;;;ACjHD,OAAOC,WAAU;;;ACAjB,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,OAAOC,WAAU;AAEjB,IAAM,YAAY,UAAU,IAAI;AAKhC,eAAsB,IAAI,SAAiB,KAA+B;AACxE,QAAM,UAAU,MAAM,EAAE,IAAI,IAAI,CAAC;AACjC,QAAM,EAAE,OAAO,IAAI,MAAM,UAAU,OAAO,OAAO,IAAI,OAAO;AAC5D,SAAO,OAAO,KAAK;AACrB;AAKA,eAAsB,UAAU,KAAgC;AAC9D,QAAM,SAASA,MAAK,KAAK,OAAO,QAAQ,IAAI,GAAG,MAAM;AACrD,SAAO,gBAAgB,MAAM;AAC/B;AAKA,eAAsB,iBAAiB,KAAsC;AAC3E,MAAI;AACF,WAAO,MAAM,IAAI,yBAAyB,GAAG;AAAA,EAC/C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA4DA,eAAsB,aAAa,QAAgB,KAAgC;AACjF,MAAI;AACF,UAAM,IAAI,sBAAsB,MAAM,IAAI,GAAG;AAC7C,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAmBA,eAAsB,kBACpB,QACA,UACA,KACwB;AACxB,MAAI;AACF,WAAO,MAAM,IAAI,QAAQ,MAAM,IAAI,QAAQ,IAAI,GAAG;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,QACpB,YACA,UACA,UACA,KACiB;AACjB,MAAI;AACF,UAAM,UAAU,WAAW,OAAO,QAAQ,KAAK;AAC/C,WAAO,MAAM,IAAI,QAAQ,UAAU,MAAM,QAAQ,GAAG,OAAO,IAAI,GAAG;AAAA,EACpE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AClJA,SAAS,QAAAC,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAI1B,IAAMC,aAAYC,WAAUC,KAAI;AAqChC,eAAsB,gBAAgB,KAAiC;AACrE,SAAO,UAAU,eAAe,EAAE,KAAK,OAAO,QAAQ,IAAI,EAAE,CAAC;AAC/D;AAKA,eAAsB,UAAU,YAAsC;AACpE,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,UAAU;AACzC,WAAO,QAAQ,SAAS,+BAA+B;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,kBAAkB,aAA6C;AACnF,MAAI;AAEF,UAAM,UAAU,MAAM,UAAU,WAAW,EAAE,KAAK,YAAY,CAAC;AAE/D,eAAW,QAAQ,SAAS;AAC1B,YAAM,UAAU,MAAM,SAAS,IAAI;AAEnC,YAAM,QAAQ,QAAQ,MAAM,2CAA2C;AACvE,UAAI,OAAO;AACT,eAAO,MAAM,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAmFA,eAAsB,mBAAmB,YAA4C;AACnF,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,UAAU;AACzC,UAAM,QAAQ,QAAQ,MAAM,6CAA6C;AACzE,WAAO,QAAQ,MAAM,CAAC,IAAI;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AFhKA,eAAsB,cAAc,aAA2C;AAC7E,SAAO,MAAM,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE5D,QAAM,OAAoB;AAAA,IACxB,MAAMC,MAAK,SAAS,WAAW;AAAA,IAC/B,SAAS;AAAA,IACT,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV,aAAa,CAAC;AAAA,EAChB;AAGA,MAAI,CAAE,MAAM,gBAAgB,WAAW,GAAI;AACzC,WAAO,KAAK,+BAA+B,EAAE,MAAM,YAAY,CAAC;AAChE,WAAO;AAAA,EACT;AAGA,OAAK,YAAY,MAAM,UAAU,WAAW;AAC5C,MAAI,KAAK,WAAW;AAClB,SAAK,gBAAgB,MAAM,iBAAiB,WAAW,KAAK;AAAA,EAC9D;AAGA,OAAK,cAAc,MAAM,gBAAgB,WAAW;AACpD,OAAK,YAAY,KAAK,YAAY,SAAS;AAG3C,MAAI,KAAK,WAAW;AAClB,eAAW,UAAU,KAAK,aAAa;AACrC,UAAI,MAAM,UAAU,MAAM,GAAG;AAC3B,aAAK,YAAY;AACjB,aAAK,gBAAgB,MAAM,kBAAkBA,MAAK,QAAQ,MAAM,CAAC,KAAK;AACtE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,kBAAkBA,MAAK,KAAK,aAAa,OAAO,kBAAkB,cAAc;AACtF,MAAI,MAAM,WAAW,eAAe,GAAG;AACrC,QAAI;AACF,YAAM,cAAc,KAAK,MAAM,MAAM,SAAS,eAAe,CAAC;AAC9D,WAAK,WAAW,CAAC,CAAC,YAAY,cAAc;AAC5C,WAAK,UAAU,YAAY,WAAW,KAAK;AAAA,IAC7C,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,MAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,UAAM,aAAa,KAAK,YAAY,KAAK,OAAK,EAAE,SAAS,gBAAgB,CAAC,KACrE,KAAK,YAAY,CAAC;AACvB,UAAM,kBAAkB,MAAM,mBAAmB,UAAU;AAC3D,QAAI,iBAAiB;AACnB,aAAO,MAAM,6BAA6B,EAAE,WAAW,gBAAgB,CAAC;AAAA,IAC1E;AAAA,EACF;AAEA,SAAO,KAAK,oBAAoB,IAAI;AACpC,SAAO;AACT;AAeA,eAAsB,wBAAwB,aAAmD;AAC/F,QAAM,YAAiC,EAAE,MAAM,YAAY;AAE3D,QAAM,cAAc,MAAM,gBAAgB,WAAW;AAErD,aAAW,UAAU,aAAa;AAChC,UAAM,cAAcA,MAAK,SAAS,QAAQ,SAAS,EAAE,YAAY;AACjE,UAAM,aAAaA,MAAK,QAAQ,MAAM;AAEtC,QAAI,YAAY,SAAS,QAAQ,GAAG;AAClC,gBAAU,SAAS;AAAA,IACrB,WAAW,YAAY,SAAS,aAAa,GAAG;AAC9C,gBAAU,cAAc;AAAA,IAC1B,WAAW,YAAY,SAAS,gBAAgB,GAAG;AACjD,gBAAU,iBAAiB;AAAA,IAC7B,WAAW,YAAY,SAAS,KAAK,GAAG;AACtC,gBAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAGA,MAAI,UAAU,gBAAgB;AAC5B,UAAM,iBAAiBA,MAAK,KAAK,UAAU,gBAAgB,eAAe,YAAY;AACtF,QAAI,MAAM,gBAAgB,cAAc,GAAG;AACzC,gBAAU,aAAa;AAAA,IACzB;AAAA,EACF;AAGA,QAAM,UAAUA,MAAK,KAAK,aAAa,OAAO,gBAAgB;AAC9D,MAAI,MAAM,gBAAgB,OAAO,GAAG;AAClC,cAAU,MAAM;AAAA,EAClB;AAEA,SAAO;AACT;AAKA,eAAsB,gBAAgB,YAAuC;AAC3E,QAAM,cAAc,MAAM,UAAU,WAAW,EAAE,KAAK,WAAW,CAAC;AAGlE,QAAM,WAAqB,CAAC;AAE5B,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AAEnC,QAAI,QAAQ,MAAM,iCAAiC,KACjD,QAAQ,MAAM,6CAA6C,GAAG;AAC9D,eAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF;AAEA,SAAO;AACT;AAaA,eAAsB,oBAAoB,SAAoC;AAC5E,QAAM,QAAQ,MAAM,UAAU,qBAAqB,EAAE,KAAK,QAAQ,CAAC;AACnE,SAAO;AACT;;;AG5JA,OAAOC,WAAU;AAEV,IAAM,0BAAgC;AAAA,EAC3C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,MAAM;AAAA,IACN,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,UAAU,cAAc,YAAY,cAAc,KAAK;AAAA,QAChE;AAAA,QACA,aAAa;AAAA,QACb,SAAS,CAAC,KAAK;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,0BACpB,MACA,QACiB;AACjB,QAAM,QAAQ,+BAA+B,MAAM,IAAI;AACvD,QAAM,cAAc,MAAM,QAAQ,OAAO,WAAW;AACpD,QAAM,SAAS,MAAM,OAAO,SAAS,KAAK,IACtC,CAAC,UAAU,cAAc,YAAY,YAAY,IACjD,MAAM;AAEV,SAAO,KAAK,0BAA0B,EAAE,aAAa,OAAO,CAAC;AAE7D,QAAM,SAA2B;AAAA,IAC/B,OAAO;AAAA,IACP,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,IACX,SAAS;AAAA,EACX;AAEA,QAAM,YAAY,MAAM,wBAAwB,WAAW;AAG3D,MAAI,OAAO,SAAS,QAAQ,GAAG;AAC7B,UAAM,sBAAsB,WAAW,QAAQ,MAAM;AAAA,EACvD;AAEA,MAAI,OAAO,SAAS,YAAY,GAAG;AACjC,UAAM,wBAAwB,WAAW,QAAQ,MAAM;AAAA,EACzD;AAEA,MAAI,OAAO,SAAS,UAAU,GAAG;AAC/B,UAAM,0BAA0B,WAAW,QAAQ,MAAM;AAAA,EAC3D;AAEA,MAAI,OAAO,SAAS,YAAY,GAAG;AACjC,UAAM,mBAAmB,WAAW,QAAQ,MAAM;AAAA,EACpD;AAGA,SAAO,QAAQ,OAAO,OAAO,WAAW;AAGxC,SAAO,UAAU,gBAAgB,QAAQ,MAAM;AAE/C,SAAO,aAAa,MAAM;AAC5B;AAEA,eAAe,sBACb,WACA,QACA,QACe;AACf,MAAI,CAAC,UAAU,gBAAgB;AAC7B,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,UAAU,6BAA6B;AAAA,IAC/D,KAAK,UAAU;AAAA,EACjB,CAAC;AAED,QAAM,eAAe,CAAC,OAAO,YAAY,QAAQ,UAAU,OAAO,YAAY,QAAQ,UAAU;AAChG,QAAM,gBAAgB,OAAO,YAAY;AAGzC,QAAM,qBAA6C;AAAA,IACjD,wBAAwB,OAAO,YAAY,QAAQ;AAAA,IACnD,8BAA8B,OAAO,YAAY,QAAQ;AAAA,EAC3D;AAEA,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AAGnC,UAAM,+BAA+B,QAAQ,SAAS,kDAAkD;AAExG,eAAW,SAAS,8BAA8B;AAChD,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,aAAa,MAAM,CAAC;AAG1B,UAAI,CAAC,aAAa,SAAS,UAAU,GAAG;AACtC,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,UAAU,SAAS,0BAA0B,UAAU;AAAA,UAChE,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY,eAAe,OAAO,YAAY,QAAQ,QAAQ,+BAA+B,OAAO,YAAY,QAAQ,UAAU;AAAA,QACpI,CAAC;AAAA,MACH;AAGA,YAAM,iBAAiB,cAAc,KAAK,YAAU,UAAU,WAAW,MAAM,CAAC;AAChF,UAAI,CAAC,kBAAkB,CAAC,UAAU,WAAW,IAAI,GAAG;AAClD,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,UAAU,SAAS;AAAA,UAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY,mCAAmC,cAAc,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,QACrF,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,iCAAiC,QAAQ,SAAS,+DAA+D;AAEvH,eAAW,SAAS,gCAAgC;AAClD,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,iBAAiB,MAAM,CAAC;AAC9B,YAAM,iBAAiB,mBAAmB,cAAc;AAGxD,UAAI,CAAC,gBAAgB;AACnB,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,UAAU,SAAS,mCAAmC,cAAc;AAAA,UAC7E,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAGA,YAAM,iBAAiB,cAAc,KAAK,YAAU,UAAU,WAAW,MAAM,CAAC;AAChF,UAAI,CAAC,kBAAkB,CAAC,UAAU,WAAW,IAAI,GAAG;AAClD,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,UAAU,SAAS;AAAA,UAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY,mCAAmC,cAAc,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,QACrF,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,4BAA4B,QAAQ,SAAS,0CAA0C;AAE7F,eAAW,SAAS,2BAA2B;AAC7C,YAAM,YAAY,MAAM,CAAC;AACzB,UAAI,CAAC,UAAU,WAAW,IAAI,GAAG;AAC/B,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,UAAU,SAAS;AAAA,UAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY,yBAAyB,SAAS;AAAA,QAChD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,wBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,YAAY;AACzB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAEA,QAAM,iBAAiB,MAAM,UAAU,QAAQ,EAAE,KAAK,UAAU,WAAW,CAAC;AAI5E,QAAM,mBAAmB;AACzB,QAAM,kBAAkB;AAExB,aAAW,QAAQ,gBAAgB;AACjC,UAAM,WAAWA,MAAK,SAAS,IAAI;AAGnC,QAAI,gBAAgB,KAAK,QAAQ,KAAK,SAAS,SAAS,eAAe,GAAG;AACxE;AAAA,IACF;AAEA,QAAI,CAAC,iBAAiB,KAAK,QAAQ,GAAG;AACpC,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,cAAc,QAAQ;AAAA,QAC/B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,oBAAoB,eACvB,IAAI,OAAKA,MAAK,SAAS,CAAC,CAAC,EACzB,OAAO,OAAK,iBAAiB,KAAK,CAAC,KAAK,CAAC,EAAE,SAAS,UAAU,CAAC,EAC/D,KAAK;AAER,WAAS,IAAI,GAAG,IAAI,kBAAkB,QAAQ,KAAK;AACjD,UAAM,OAAO,kBAAkB,IAAI,CAAC;AACpC,UAAM,OAAO,kBAAkB,CAAC;AAEhC,UAAM,YAAY,iBAAiB,KAAK,IAAI;AAC5C,UAAM,YAAY,iBAAiB,KAAK,IAAI;AAE5C,QAAI,aAAa,WAAW;AAC1B,YAAM,cAAc,UAAU,CAAC;AAC/B,YAAM,cAAc,UAAU,CAAC;AAG/B,UAAI,cAAc,aAAa;AAC7B,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,2BAA2B,IAAI,OAAO,WAAW,mBAAmB,IAAI,OAAO,WAAW;AAAA,QACrG,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,0BACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,aAAa;AAC1B,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,eAAe,MAAM,UAAU,kBAAkB;AAAA,IACrD,KAAK,UAAU;AAAA,EACjB,CAAC;AAED,aAAW,QAAQ,cAAc;AAC/B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,MAAM,KAAK;AAG1C,QAAI,SAAS,WAAW,GAAG,EAAG;AAG9B,UAAM,oBAAoB,IAAI,QAAQ;AACtC,UAAM,mBAAmB,IAAI,OAAO,QAAQ,iBAAiB,KAAK;AAElE,QAAI,CAAC,iBAAiB,KAAK,OAAO,GAAG;AAEnC,YAAM,oBAAoB,QAAQ,SAAS,aAAa,iBAAiB,EAAE;AAE3E,UAAI,CAAC,mBAAmB;AACtB,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,YAAY,QAAQ,uBAAuB,iBAAiB;AAAA,UACrE,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY,oBAAoB,iBAAiB;AAAA,QACnD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,mBACb,WACA,QACA,QACe;AACf,QAAM,SAAS;AAAA,IACb,EAAE,MAAM,UAAU,QAAQ,UAAU,OAAO,YAAY,WAAW,QAAQ,MAAM,SAAS;AAAA,IACzF,EAAE,MAAM,UAAU,aAAa,UAAU,OAAO,YAAY,WAAW,aAAa,MAAM,cAAc;AAAA,IACxG,EAAE,MAAM,UAAU,gBAAgB,UAAU,OAAO,YAAY,WAAW,gBAAgB,MAAM,iBAAiB;AAAA,IACjH,EAAE,MAAM,UAAU,KAAK,UAAU,OAAO,YAAY,WAAW,KAAK,MAAM,MAAM;AAAA,EAClF;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI,CAAC,MAAM,KAAM;AAEjB,UAAM,UAAU,MAAM,UAAU,WAAW,EAAE,KAAK,MAAM,KAAK,CAAC;AAE9D,eAAW,QAAQ,QAAQ,MAAM,GAAG,EAAE,GAAG;AACvC,YAAM,UAAU,MAAM,SAAS,IAAI;AACnC,YAAM,iBAAiB,QAAQ,MAAM,sBAAsB;AAE3D,UAAI,gBAAgB;AAClB,cAAM,YAAY,eAAe,CAAC;AAElC,YAAI,CAAC,UAAU,WAAW,MAAM,QAAQ,GAAG;AACzC,iBAAO,OAAO,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,UAAU;AAAA,YACV,SAAS,GAAG,MAAM,IAAI,kCAAkC,SAAS;AAAA,YACjE,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,YACxC,YAAY,sBAAsB,MAAM,QAAQ;AAAA,UAClD,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,QAA0B,QAA0B;AAC3E,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,qBAAqB,OAAO,KAAK,IAAI,CAAC,EAAE;AACnD,QAAM,KAAK,WAAW,OAAO,OAAO,MAAM,EAAE;AAC5C,QAAM,KAAK,aAAa,OAAO,SAAS,MAAM,EAAE;AAChD,QAAM,KAAK,WAAW,OAAO,QAAQ,WAAW,QAAQ,EAAE;AAE1D,SAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,aAAa,QAAkC;AACtD,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,iCAAiC;AAC5C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,iBAAiB,OAAO,QAAQ,kBAAa,eAAU,EAAE;AACpE,QAAM,KAAK,iBAAiB,OAAO,OAAO,MAAM,EAAE;AAClD,QAAM,KAAK,mBAAmB,OAAO,SAAS,MAAM,EAAE;AACtD,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,EAAE;AACb,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,KAAK,cAAS,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE;AACtD,UAAI,MAAM,KAAM,OAAM,KAAK,iBAAiB,MAAM,IAAI,IAAI;AAC1D,UAAI,MAAM,KAAM,OAAM,KAAK,eAAe,MAAM,IAAI,EAAE;AACtD,UAAI,MAAM,WAAY,OAAM,KAAK,qBAAqB,MAAM,UAAU,EAAE;AACxE,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,EAAE;AACb,eAAW,WAAW,OAAO,UAAU;AACrC,YAAM,KAAK,oBAAU,QAAQ,QAAQ,KAAK,QAAQ,OAAO,EAAE;AAC3D,UAAI,QAAQ,KAAM,OAAM,KAAK,iBAAiB,QAAQ,IAAI,IAAI;AAC9D,UAAI,QAAQ,WAAY,OAAM,KAAK,qBAAqB,QAAQ,UAAU,EAAE;AAC5E,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAEA,MAAI,OAAO,OAAO,WAAW,KAAK,OAAO,SAAS,WAAW,GAAG;AAC9D,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gDAA2C;AAAA,EACxD;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;AChYA,OAAOC,WAAU;AAEV,IAAM,sBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,MAAM;AAAA,IACN,YAAY;AAAA,MACV,aAAa;AAAA,QACX,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,eAAe;AAAA,QACb,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,sBACpB,MACA,QACiB;AACjB,QAAM,QAAQ,2BAA2B,MAAM,IAAI;AACnD,QAAM,cAAc,MAAM,eAAe,OAAO,WAAW;AAE3D,SAAO,KAAK,uBAAuB,EAAE,aAAa,QAAQ,MAAM,OAAO,CAAC;AAExE,QAAM,YAAY,MAAM,wBAAwB,WAAW;AAE3D,MAAI,CAAC,UAAU,YAAY;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,SAA+B;AAAA,IACnC,cAAc;AAAA,IACd,YAAY,CAAC;AAAA,IACb,WAAW,CAAC;AAAA,IACZ,aAAa,CAAC;AAAA,EAChB;AAGA,QAAM,gBAAgB,MAAM,UAAU,MAAM,iBAAiB,WAAW,KAAK;AAG7E,SAAO,aAAa,MAAM,gBAAgB,UAAU,YAAY,UAAU,IAAI;AAG9E,yBAAuB,QAAQ,MAAM;AAGrC,0BAAwB,MAAM;AAG9B,MAAI,MAAM,iBAAiB,MAAM,aAAa,MAAM,eAAe,WAAW,GAAG;AAC/E,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAGA,QAAM,mBAAmB,QAAQ,SAAS;AAG1C,SAAO,eAAe,OAAO,UAAU,SAAS;AAGhD,sBAAoB,MAAM;AAE1B,SAAOC,cAAa,QAAQ,eAAe,MAAM,aAAa;AAChE;AAEA,eAAe,gBACb,gBACA,UAC0B;AAC1B,QAAM,QAAQ,MAAM,UAAU,QAAQ,EAAE,KAAK,eAAe,CAAC;AAC7D,QAAM,aAA8B,CAAC;AAIrC,QAAM,UAAU;AAEhB,aAAW,QAAQ,OAAO;AACxB,UAAM,WAAWD,MAAK,SAAS,IAAI;AAGnC,QAAI,SAAS,SAAS,YAAY,KAAK,SAAS,SAAS,eAAe,GAAG;AACzE;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,KAAK,QAAQ;AAEnC,QAAI,OAAO;AACT,iBAAW,KAAK;AAAA,QACd,MAAM,SAAS,QAAQ,OAAO,EAAE;AAAA,QAChC,SAAS,MAAM,CAAC;AAAA;AAAA,QAChB,SAAS,MAAM,CAAC;AAAA;AAAA,QAChB,UAAU,MAAM,CAAC;AAAA;AAAA,QACjB,aAAa,MAAM,CAAC;AAAA,QACpB,MAAMA,MAAK,SAAS,UAAU,IAAI;AAAA,QAClC,SAAS;AAAA;AAAA,MACX,CAAC;AAAA,IACH,OAAO;AAEL,iBAAW,KAAK;AAAA,QACd,MAAM,SAAS,QAAQ,OAAO,EAAE;AAAA,QAChC,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,QACV,aAAa,SAAS,QAAQ,OAAO,EAAE;AAAA,QACvC,MAAMA,MAAK,SAAS,UAAU,IAAI;AAAA,QAClC,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAAA,EACF;AAGA,SAAO,WAAW,KAAK,CAAC,GAAG,MAAM;AAE/B,UAAM,iBAAiB,gBAAgB,EAAE,SAAS,EAAE,OAAO;AAC3D,QAAI,mBAAmB,EAAG,QAAO;AACjC,WAAO,EAAE,SAAS,cAAc,EAAE,QAAQ;AAAA,EAC5C,CAAC;AACH;AAEA,SAAS,gBAAgB,GAAW,GAAmB;AACrD,QAAM,SAAS,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACtC,QAAM,SAAS,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAEtC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,QAAI,OAAO,CAAC,IAAI,OAAO,CAAC,EAAG,QAAO;AAClC,QAAI,OAAO,CAAC,IAAI,OAAO,CAAC,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,SAAS,uBAAuB,QAA8B,SAAuB;AACnF,aAAW,aAAa,OAAO,YAAY;AACzC,QAAI,UAAU,YAAY,WAAW;AACnC,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,aAAa,cAAc,UAAU,IAAI;AAAA,QACzC,OAAO,CAAC,UAAU,IAAI;AAAA,QACtB,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,QAAI,UAAU,YAAY,SAAS;AACjC,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,aAAa,cAAc,UAAU,IAAI;AAAA,QACzC,OAAO,CAAC,UAAU,IAAI;AAAA,QACtB,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,QAAoC;AACnE,QAAM,aAAa,OAAO,WAAW,OAAO,OAAK,EAAE,YAAY,SAAS;AAExE,WAAS,IAAI,GAAG,IAAI,WAAW,QAAQ,KAAK;AAC1C,UAAM,OAAO,WAAW,IAAI,CAAC;AAC7B,UAAM,OAAO,WAAW,CAAC;AAGzB,QAAI,KAAK,YAAY,KAAK,SAAS;AACjC,YAAM,iBAAiB,gBAAgB,KAAK,SAAS,KAAK,OAAO;AAEjE,UAAI,iBAAiB,GAAG;AACtB,eAAO,UAAU,KAAK;AAAA,UACpB,MAAM;AAAA,UACN,aAAa,cAAc,KAAK,IAAI,OAAO,KAAK,OAAO,0BAA0B,KAAK,IAAI,OAAO,KAAK,OAAO;AAAA,UAC7G,OAAO,CAAC,KAAK,MAAM,KAAK,IAAI;AAAA,UAC5B,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAGA,UAAI,KAAK,YAAY,KAAK,WAAW,KAAK,aAAa,KAAK,UAAU;AACpE,eAAO,UAAU,KAAK;AAAA,UACpB,MAAM;AAAA,UACN,aAAa,eAAe,KAAK,IAAI,UAAU,KAAK,IAAI;AAAA,UACxD,OAAO,CAAC,KAAK,MAAM,KAAK,IAAI;AAAA,UAC5B,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,qBACb,QACA,WACA,eACA,eACA,aACe;AACf,MAAI,CAAC,UAAU,WAAY;AAE3B,QAAM,oBAAoBA,MAAK,SAAS,aAAa,UAAU,UAAU,EAAE,QAAQ,OAAO,GAAG;AAG7F,QAAM,gBAAgB,MAAM,UAAU,qBAAqB,EAAE,KAAK,UAAU,WAAW,CAAC;AAExF,MAAI,cAAc,SAAS,GAAG;AAC5B,UAAM,kBAAkBA,MAAK,SAAS,aAAa,cAAc,CAAC,CAAC,EAAE,QAAQ,OAAO,GAAG;AAEvF,UAAM,kBAAkB,MAAM,SAAS,cAAc,CAAC,CAAC;AACvD,UAAM,kBAAkB,MAAM,kBAAkB,eAAe,iBAAiB,WAAW;AAE3F,QAAI,mBAAmB,oBAAoB,iBAAiB;AAE1D,YAAM,OAAO,MAAM,QAAQ,eAAe,eAAe,iBAAiB,WAAW;AAErF,UAAI,MAAM;AACR,eAAO,UAAU,KAAK;AAAA,UACpB,MAAM;AAAA,UACN,aAAa,kCAAkC,aAAa,UAAU,aAAa;AAAA,UACnF,OAAO,CAAC,eAAe;AAAA,UACvB,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,QAAM,oBAAoB,MAAM;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,mBAAmB;AAGrB,WAAO,MAAM,+BAA+B,EAAE,cAAc,CAAC;AAAA,EAC/D;AACF;AAEA,eAAe,mBACb,QACA,WACe;AACf,MAAI,CAAC,UAAU,WAAY;AAE3B,QAAM,gBAAgB,MAAM,UAAU,qBAAqB,EAAE,KAAK,UAAU,WAAW,CAAC;AAExF,MAAI,cAAc,WAAW,GAAG;AAC9B,WAAO,UAAU,KAAK;AAAA,MACpB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO,CAAC;AAAA,MACR,YAAY;AAAA,IACd,CAAC;AACD;AAAA,EACF;AAEA,MAAI,cAAc,SAAS,GAAG;AAC5B,WAAO,UAAU,KAAK;AAAA,MACpB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO,cAAc,IAAI,OAAKA,MAAK,SAAS,UAAU,MAAM,CAAC,CAAC;AAAA,MAC9D,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AAGA,QAAM,kBAAkB,MAAM,SAAS,cAAc,CAAC,CAAC;AAEvD,aAAW,aAAa,OAAO,YAAY;AACzC,QAAI,UAAU,YAAY,aAAa,CAAC,gBAAgB,SAAS,UAAU,IAAI,GAAG;AAChF,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,aAAa,cAAc,UAAU,IAAI;AAAA,QACzC,OAAO,CAAC,UAAU,IAAI;AAAA,QACtB,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,QAAoC;AAC/D,MAAI,OAAO,UAAU,KAAK,OAAK,EAAE,SAAS,UAAU,GAAG;AACrD,WAAO,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,KAAK,OAAK,EAAE,SAAS,QAAQ,GAAG;AACnD,WAAO,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,KAAK,OAAK,EAAE,SAAS,OAAO,GAAG;AAClD,WAAO,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,SAAS,IAAI;AACjC,WAAO,YAAY;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAASC,cACP,QACA,eACA,eACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,kCAAkC;AAC7C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,yBAAyB,aAAa,EAAE;AACnD,MAAI,eAAe;AACjB,UAAM,KAAK,yBAAyB,aAAa,EAAE;AAAA,EACrD;AACA,QAAM,KAAK,2BAA2B,OAAO,WAAW,MAAM,EAAE;AAChE,QAAM,KAAK,0BAA0B,OAAO,UAAU,MAAM,EAAE;AAC9D,QAAM,KAAK,iBAAiB,OAAO,eAAe,8BAAyB,WAAM,EAAE;AACnF,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,eAAe;AAC1B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uDAAuD;AAClE,QAAM,KAAK,uDAAuD;AAElE,aAAW,aAAa,OAAO,YAAY;AACzC,UAAM;AAAA,MACJ,KAAK,UAAU,IAAI,MAAM,UAAU,OAAO,MAAM,UAAU,OAAO,MAAM,UAAU,QAAQ,MAAM,UAAU,WAAW;AAAA,IACtH;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAGb,MAAI,OAAO,UAAU,SAAS,GAAG;AAC/B,UAAM,KAAK,cAAc;AACzB,UAAM,KAAK,EAAE;AAEb,eAAW,YAAY,OAAO,WAAW;AACvC,YAAM,OAAO,SAAS,SAAS,aAAa,cAC1C,SAAS,SAAS,UAAU,cAC1B,SAAS,SAAS,WAAW,cAAO;AAExC,YAAM,KAAK,OAAO,IAAI,IAAI,SAAS,KAAK,YAAY,CAAC,KAAK,SAAS,WAAW,EAAE;AAChF,UAAI,SAAS,MAAM,SAAS,GAAG;AAC7B,cAAM,KAAK,gBAAgB,SAAS,MAAM,IAAI,OAAK,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,MAC7E;AACA,YAAM,KAAK,qBAAqB,SAAS,UAAU,EAAE;AACrD,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,MAAI,OAAO,YAAY,SAAS,GAAG;AACjC,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,EAAE;AACb,eAAW,cAAc,OAAO,aAAa;AAC3C,YAAM,KAAK,eAAQ,UAAU,EAAE;AAAA,IACjC;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACtYA,OAAO,gBAAgB;AASvB,OAAOC,WAAU;AAEV,IAAM,wBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,MAAM;AAAA,IACN,YAAY;AAAA,MACV,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM,CAAC,WAAW,UAAU,cAAc,WAAW;AAAA,QACrD,aAAa;AAAA,MACf;AAAA,MACA,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,QACN,YAAY;AAAA,UACV,WAAW;AAAA,YACT,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,YAAY;AAAA,YACV,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,OAAO,EAAE,MAAM,SAAS;AAAA,YACxB,aAAa;AAAA,UACf;AAAA,UACA,YAAY;AAAA,YACV,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,gBAAgB;AAAA,YACd,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,aAAa;AAAA,YACX,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM,CAAC,QAAQ,YAAY;AAAA,YAC3B,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,CAAC,QAAQ,MAAM;AAAA,EAC3B;AACF;AAGA,WAAW,eAAe,cAAc,CAAC,QAAgB;AACvD,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD,CAAC;AAED,WAAW,eAAe,aAAa,CAAC,QAAgB;AACtD,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD,CAAC;AAED,WAAW,eAAe,aAAa,CAAC,QAAgB;AACtD,SAAO,IAAI,QAAQ,mBAAmB,OAAO,EAAE,YAAY;AAC7D,CAAC;AAED,eAAsB,wBACpB,MACA,QACiB;AACjB,QAAM,QAAQ,6BAA6B,MAAM,IAAI;AAErD,SAAO,KAAK,yBAAyB,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,KAAK,CAAC;AAE3E,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAE7E,QAAM,SAAyB;AAAA,IAC7B,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,IACR,cAAc,CAAC;AAAA,EACjB;AAEA,MAAI;AACF,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,cAAM,gBAAgB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,MAAM;AAC1E;AAAA,MACF,KAAK;AACH,cAAM,eAAe,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,MAAM;AACzE;AAAA,MACF,KAAK;AACH,cAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,MAAM;AAC7E;AAAA,MACF,KAAK;AACH,cAAM,kBAAkB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,MAAM;AAC5E;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAO,UAAU;AACjB,WAAO,aAAa,KAAK,UAAU,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,EAC/F;AAEA,SAAOC,cAAa,QAAQ,MAAM,MAAM,MAAM,IAAI;AACpD;AAEA,eAAe,gBACb,MACA,SACA,WACA,QACA,QACe;AACf,QAAM,YAAY,SAAS,aAAa,GAAG,OAAO,YAAY,WAAW,WAAW;AACpF,QAAM,UAAU,SAAS,WAAW,CAAC,gBAAgB,eAAe,eAAe,eAAe,aAAa;AAG/G,QAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsB1B,QAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkC/B,QAAM,aAAa;AAAA;AAAA;AAInB,QAAM,UAAU,EAAE,WAAW,MAAM,QAAQ;AAE3C,QAAM,mBAAmB,WAAW,QAAQ,iBAAiB,EAAE,OAAO;AACtE,QAAM,wBAAwB,WAAW,QAAQ,sBAAsB,EAAE,OAAO;AAChF,QAAM,YAAY,WAAW,QAAQ,UAAU,EAAE,OAAO;AAGxD,QAAM,WAAW,UAAU,eAAe,OAAO,WAAW;AAC5D,QAAM,eAAeD,MAAK,KAAK,UAAU,UAAU;AAEnD,QAAM,gBAAgB,YAAY;AAElC,QAAM,gBAAgBA,MAAK,KAAK,cAAc,IAAI,IAAI,YAAY;AAClE,QAAM,qBAAqBA,MAAK,KAAK,cAAc,GAAG,IAAI,YAAY;AAGtE,QAAM,UAAU,eAAe,gBAAgB;AAC/C,SAAO,MAAM,KAAK,EAAE,MAAM,eAAe,SAAS,kBAAkB,MAAM,UAAU,CAAC;AAErF,QAAM,UAAU,oBAAoB,qBAAqB;AACzD,SAAO,MAAM,KAAK,EAAE,MAAM,oBAAoB,SAAS,uBAAuB,MAAM,UAAU,CAAC;AAE/F,SAAO,aAAa,KAAK,mCAAmC;AAC5D,SAAO,aAAa,KAAK,SAAS;AACpC;AAEA,eAAe,eACb,MACA,SACA,WACA,QACA,QACe;AACf,QAAM,YAAY,SAAS,aAAa,OAAO,YAAY,WAAW;AACtE,QAAM,aAAa,SAAS;AAC5B,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,SAAS,SAAS,UAAU,OAAO,YAAY,QAAQ;AAG7D,QAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsGvB,QAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DvB,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,yBAAyB,OAAO,YAAY,WAAW;AAAA,IACvD,iBAAiB,OAAO,YAAY,WAAW;AAAA,EACjD;AAEA,QAAM,gBAAgB,WAAW,QAAQ,cAAc,EAAE,OAAO;AAChE,QAAM,gBAAgB,WAAW,QAAQ,cAAc,EAAE,OAAO;AAGhE,QAAM,aAAa,UAAU,UAAUA,MAAK,KAAK,OAAO,WAAW,aAAa,QAAQ;AACxF,QAAM,YAAY,UAAU,kBAAkBA,MAAK,KAAK,OAAO,WAAW,aAAa,gBAAgB;AAEvG,QAAM,gBAAgB,UAAU;AAChC,QAAM,gBAAgBA,MAAK,KAAK,WAAW,eAAe,gBAAgB,CAAC;AAE3E,QAAM,iBAAiBA,MAAK,KAAK,YAAY,GAAG,IAAI,KAAK;AACzD,QAAM,iBAAiBA,MAAK,KAAK,WAAW,eAAe,kBAAkB,GAAG,IAAI,kBAAkB;AAEtG,QAAM,UAAU,gBAAgB,aAAa;AAC7C,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AAEnF,QAAM,UAAU,gBAAgB,aAAa;AAC7C,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AAEnF,SAAO,aAAa,KAAK,oCAAoC;AAC7D,SAAO,aAAa,KAAK,gBAAgB,IAAI,KAAK,IAAI,YAAY,IAAI,MAAM;AAC5E,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,mBAAmB;AAC5C,SAAO,aAAa,KAAK,+CAA+C,IAAI,iCAAiC;AAC7G,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,kCAAkC;AAC3D,SAAO,aAAa,KAAK,gBAAgB,iBAAiB,KAAK,mBAAmB,0BAA0B;AAC5G,SAAO,aAAa,KAAK,sDAAsD;AAC/E,SAAO,aAAa,KAAK,iDAAiD;AAC1E,SAAO,aAAa,KAAK,4BAA4B;AACvD;AAEA,eAAe,mBACb,MACA,SACA,WACA,QACA,QACe;AACf,QAAM,YAAY,SAAS,aAAa,GAAG,OAAO,YAAY,WAAW,GAAG;AAE5E,QAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmF3B,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,EACxD;AAEA,QAAM,oBAAoB,WAAW,QAAQ,kBAAkB,EAAE,OAAO;AAExE,QAAM,UAAU,UAAU,OAAOA,MAAK,KAAK,OAAO,WAAW,aAAa,KAAK;AAC/E,QAAM,kBAAkBA,MAAK,KAAK,SAAS,aAAa;AAExD,QAAM,gBAAgB,eAAe;AAErC,QAAM,qBAAqBA,MAAK,KAAK,iBAAiB,GAAG,IAAI,eAAe;AAE5E,QAAM,UAAU,oBAAoB,iBAAiB;AACrD,SAAO,MAAM,KAAK,EAAE,MAAM,oBAAoB,SAAS,mBAAmB,MAAM,UAAU,CAAC;AAE3F,SAAO,aAAa,KAAK,oCAAoC;AAC7D,SAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,EAAE;AAC9D,SAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AACnE,SAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,EAAE;AAC9D,SAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AACnE,SAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AACrE;AAEA,eAAe,kBACb,MACA,SACA,WACA,QACA,QACe;AACf,QAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4E1B,QAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuErB,QAAM,UAAU;AAAA,IACd;AAAA,IACA,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,EACxD;AAEA,QAAM,mBAAmB,WAAW,QAAQ,iBAAiB,EAAE,OAAO;AACtE,QAAM,cAAc,WAAW,QAAQ,YAAY,EAAE,OAAO;AAG5D,QAAM,UAAU,UAAU,OAAOA,MAAK,KAAK,OAAO,WAAW,aAAa,OAAO,gBAAgB;AACjG,QAAM,iBAAiB,SAAS,cAAcA,MAAK,KAAK,SAAS,OAAO,YAAY;AACpF,QAAM,YAAYA,MAAK,KAAK,SAAS,OAAO,OAAO;AAEnD,QAAM,gBAAgB,cAAc;AACpC,QAAM,gBAAgB,SAAS;AAE/B,QAAM,oBAAoBA,MAAK,KAAK,gBAAgB,GAAG,IAAI,MAAM;AACjE,QAAM,eAAeA,MAAK,KAAK,WAAW,MAAM,IAAI,KAAK;AAEzD,QAAM,UAAU,mBAAmB,gBAAgB;AACnD,SAAO,MAAM,KAAK,EAAE,MAAM,mBAAmB,SAAS,kBAAkB,MAAM,UAAU,CAAC;AAEzF,QAAM,UAAU,cAAc,WAAW;AACzC,SAAO,MAAM,KAAK,EAAE,MAAM,cAAc,SAAS,aAAa,MAAM,UAAU,CAAC;AAE/E,SAAO,aAAa,KAAK,+BAA+B;AACxD,SAAO,aAAa,KAAK,YAAY,IAAI,yBAAyB,IAAI,IAAI;AAC1E,SAAO,aAAa,KAAK,eAAe,IAAI,uBAAuB,IAAI,IAAI;AAC7E;AAEA,SAASC,cAAa,QAAwB,MAAc,MAAsB;AAChF,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,cAAc,IAAI,KAAK,IAAI,EAAE;AACxC,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,2BAAsB;AACjC,UAAM,KAAK,EAAE;AAEb,eAAW,QAAQ,OAAO,OAAO;AAC/B,YAAM,KAAK,OAAO,KAAK,SAAS,YAAY,cAAO,cAAI,IAAID,MAAK,SAAS,KAAK,IAAI,CAAC,EAAE;AACrF,YAAM,KAAK,eAAe,KAAK,IAAI,IAAI;AACvC,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,SAAS,KAAK,KAAK,SAAS,KAAK,IAAI,WAAW,aAAa;AAExE,YAAM,eAAe,KAAK,QAAQ,MAAM,IAAI,EAAE,MAAM,GAAG,EAAE;AACzD,YAAM,KAAK,aAAa,KAAK,IAAI,CAAC;AAClC,UAAI,KAAK,QAAQ,MAAM,IAAI,EAAE,SAAS,IAAI;AACxC,cAAM,KAAK,oBAAoB;AAAA,MACjC;AACA,YAAM,KAAK,KAAK;AAChB,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,QAAI,OAAO,aAAa,SAAS,GAAG;AAClC,YAAM,KAAK,yBAAkB;AAC7B,YAAM,KAAK,EAAE;AACb,iBAAW,eAAe,OAAO,cAAc;AAC7C,YAAI,YAAY,WAAW,WAAW,KAAK,YAAY,WAAW,cAAc,GAAG;AACjF,gBAAM,KAAK,WAAW;AACtB,gBAAM,KAAK,WAAW;AACtB,gBAAM,KAAK,KAAK;AAAA,QAClB,WAAW,YAAY,WAAW,SAAS,GAAG;AAC5C,gBAAM,KAAK,SAAS;AACpB,gBAAM,KAAK,WAAW;AACtB,gBAAM,KAAK,KAAK;AAAA,QAClB,WAAW,YAAY,WAAW,SAAS,GAAG;AAC5C,gBAAM,KAAK,eAAe;AAC1B,gBAAM,KAAK,WAAW;AACtB,gBAAM,KAAK,KAAK;AAAA,QAClB,OAAO;AACL,gBAAM,KAAK,WAAW;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF,OAAO;AACL,UAAM,KAAK,6BAAwB;AACnC,UAAM,KAAK,EAAE;AACb,eAAW,eAAe,OAAO,cAAc;AAC7C,YAAM,KAAK,KAAK,WAAW,EAAE;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACxxBA,OAAO,WAAW;AAQlB,OAAOE,WAAU;AAEV,IAAM,cAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,aAAa;AAAA,IACX,MAAM;AAAA,IACN,YAAY;AAAA,MACV,UAAU;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,MAAM,CAAC,YAAY,QAAQ,SAAS;AAAA,QACpC,aAAa;AAAA,QACb,SAAS;AAAA,MACX;AAAA,MACA,YAAY;AAAA,QACV,MAAM;AAAA,QACN,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACF;AA4BA,eAAsB,cACpB,MACA,QACiB;AACjB,QAAM,QAAQ,mBAAmB,MAAM,IAAI;AAE3C,SAAO,KAAK,8BAA8B,EAAE,UAAU,MAAM,UAAU,QAAQ,MAAM,OAAO,CAAC;AAE5F,MAAI,YAA4B,CAAC;AAGjC,MAAI,OAAO,WAAW,cAAc,OAAO,WAAW,QAAQ;AAC5D,QAAI;AACF,kBAAY,MAAM,iBAAiB,OAAO,WAAW,MAAM;AAC3D,aAAO,MAAM,kCAAkC,EAAE,OAAO,UAAU,OAAO,CAAC;AAAA,IAC5E,SAAS,OAAO;AACd,aAAO,KAAK,8DAA8D,EAAE,MAAM,CAAC;AAAA,IACrF;AAAA,EACF;AAGA,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAC7E,gBAAY,MAAM,iBAAiB,SAAS;AAAA,EAC9C;AAGA,MAAI,MAAM,UAAU;AAClB,UAAM,SAAS,MAAM,SAAS,YAAY;AAC1C,gBAAY,UAAU,OAAO,OAAK,EAAE,KAAK,YAAY,EAAE,SAAS,MAAM,CAAC;AAAA,EACzE;AAEA,MAAI,MAAM,YAAY;AACpB,UAAM,SAAS,MAAM,WAAW,YAAY;AAC5C,gBAAY,UAAU,OAAO,OAAK,EAAE,WAAW,YAAY,EAAE,SAAS,MAAM,CAAC;AAAA,EAC/E;AAGA,UAAQ,MAAM,QAAQ;AAAA,IACpB,KAAK;AACH,aAAO,KAAK,UAAU,WAAW,MAAM,CAAC;AAAA,IAC1C,KAAK;AACH,aAAO,gBAAgB,SAAS;AAAA,IAClC,KAAK;AAAA,IACL;AACE,aAAO,iBAAiB,SAAS;AAAA,EACrC;AACF;AAEA,eAAe,iBAAiB,QAAyC;AACvE,QAAM,aAAa,GAAG,MAAM;AAE5B,QAAM,WAAW,MAAM,MAAM,IAAI,YAAY;AAAA,IAC3C,SAAS;AAAA,IACT,YAAY,KAAK,MAAM,OAAO,OAAO,GAAG,MAAM,EAAE,oBAAoB,MAAM,CAAC;AAAA,EAC7E,CAAC;AAED,QAAM,OAAO,SAAS;AACtB,QAAM,YAA4B,CAAC;AAEnC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,GAAG;AAClE,UAAM,UAAU;AAEhB,eAAW,UAAU,CAAC,OAAO,QAAQ,OAAO,SAAS,QAAQ,GAAG;AAC9D,YAAM,YAAY,QAAQ,MAAM;AAChC,UAAI,CAAC,UAAW;AAEhB,YAAM,OAAQ,UAAU,QAAqB,CAAC,SAAS;AACvD,YAAM,aAAc,UAAU,cAAiD,CAAC;AAEhF,gBAAU,KAAK;AAAA,QACb,QAAQ,OAAO,YAAY;AAAA,QAC3B,MAAM;AAAA,QACN,YAAY,KAAK,CAAC;AAAA,QAClB,QAAS,UAAU,eAA0B;AAAA,QAC7C,SAAS,UAAU;AAAA,QACnB,YAAY,WAAW,IAAI,QAAM;AAAA,UAC/B,MAAM,EAAE;AAAA,UACR,IAAI,EAAE;AAAA,UACN,MAAO,EAAE,QAAmC,QAAQ;AAAA,UACpD,UAAU,EAAE,YAAuB;AAAA,UACnC,aAAa,EAAE;AAAA,QACjB,EAAE;AAAA,QACF,aAAa,UAAU,cAAc,eAAe;AAAA,QACpD,WAAW,OAAO,QAAQ,UAAU,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO;AAAA,UAC5E,QAAQ,SAAS,QAAQ,EAAE;AAAA,UAC3B,aAAc,KAAgC;AAAA,QAChD,EAAE;AAAA,QACF,WAAW,CAAC,EAAE,UAAU,YAAa,UAAU,SAAuB,SAAS;AAAA,MACjF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,iBACb,WACyB;AACzB,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,kBAAkB,MAAM,oBAAoB,UAAU,GAAG;AAC/D,QAAM,YAA4B,CAAC;AAEnC,aAAW,QAAQ,iBAAiB;AAClC,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,MAAM,KAAK;AAC1C,UAAM,iBAAiB,SAAS,QAAQ,cAAc,EAAE;AAGxD,UAAM,aAAa,QAAQ,MAAM,iCAAiC;AAClE,UAAM,YAAY,aAAa,WAAW,CAAC,EAAE,QAAQ,gBAAgB,eAAe,YAAY,CAAC,IAAI,QAAQ,eAAe,YAAY,CAAC;AAGzI,UAAM,eAAe,QAAQ,SAAS,aAAa;AAGnD,UAAM,cAAc;AAAA,MAClB,EAAE,SAAS,2CAA2C,QAAQ,MAAM;AAAA,MACpE,EAAE,SAAS,4CAA4C,QAAQ,OAAO;AAAA,MACtE,EAAE,SAAS,2CAA2C,QAAQ,MAAM;AAAA,MACpE,EAAE,SAAS,6CAA6C,QAAQ,QAAQ;AAAA,MACxE,EAAE,SAAS,8CAA8C,QAAQ,SAAS;AAAA,IAC5E;AAEA,eAAW,EAAE,SAAS,OAAO,KAAK,aAAa;AAC7C,UAAI;AACJ,cAAQ,QAAQ,QAAQ,KAAK,OAAO,OAAO,MAAM;AAC/C,cAAM,cAAc,MAAM,CAAC,KAAK;AAChC,cAAM,WAAW,cAAc,GAAG,SAAS,IAAI,WAAW,KAAK;AAG/D,cAAM,iBAAiB,QAAQ,UAAU,MAAM,KAAK;AACpD,cAAM,cAAc,eAAe,MAAM,4EAA4E;AAErH,cAAM,aAA8B,CAAC;AAGrC,cAAM,aAAa,SAAS,MAAM,qBAAqB;AACvD,YAAI,YAAY;AACd,qBAAW,SAAS,YAAY;AAC9B,kBAAM,YAAY,MAAM,QAAQ,UAAU,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAChE,uBAAW,KAAK;AAAA,cACd,MAAM,aAAa,MAAM,QAAQ,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,cAC1D,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAGA,YAAI,eAAe,SAAS,YAAY,GAAG;AACzC,gBAAM,YAAY,eAAe,MAAM,8BAA8B;AACrE,cAAI,WAAW;AACb,uBAAW,KAAK;AAAA,cACd,MAAM,UAAU,CAAC;AAAA,cACjB,IAAI;AAAA,cACJ,MAAM,UAAU,CAAC;AAAA,cACjB,UAAU;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAGA,cAAM,eAAe,eAAe,SAAS,gCAAgC;AAC7E,mBAAW,MAAM,cAAc;AAC7B,qBAAW,KAAK;AAAA,YACd,MAAM,GAAG,CAAC;AAAA,YACV,IAAI;AAAA,YACJ,MAAM,GAAG,CAAC;AAAA,YACV,UAAU;AAAA,UACZ,CAAC;AAAA,QACH;AAEA,kBAAU,KAAK;AAAA,UACb;AAAA,UACA,MAAM,SAAS,QAAQ,QAAQ,GAAG;AAAA,UAClC,YAAY;AAAA,UACZ,QAAQ,cAAc,YAAY,CAAC,IAAI;AAAA,UACvC;AAAA,UACA,WAAW,CAAC,EAAE,QAAQ,KAAK,aAAa,UAAU,CAAC;AAAA,UACnD,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,WAAmC;AAC3D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,gCAAgC;AAC3C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,eAAc,oBAAI,KAAK,GAAE,YAAY,CAAC,EAAE;AACnD,QAAM,KAAK,EAAE;AAGb,QAAM,eAAe,oBAAI,IAA4B;AACrD,aAAW,YAAY,WAAW;AAChC,UAAM,WAAW,aAAa,IAAI,SAAS,UAAU,KAAK,CAAC;AAC3D,aAAS,KAAK,QAAQ;AACtB,iBAAa,IAAI,SAAS,YAAY,QAAQ;AAAA,EAChD;AAEA,aAAW,CAAC,YAAY,mBAAmB,KAAK,cAAc;AAC5D,UAAM,KAAK,MAAM,UAAU,EAAE;AAC7B,UAAM,KAAK,EAAE;AAEb,eAAW,YAAY,qBAAqB;AAC1C,YAAM,YAAY,SAAS,YAAY,eAAQ;AAC/C,YAAM,KAAK,SAAS,SAAS,MAAM,MAAM,SAAS,IAAI,GAAG,SAAS,EAAE;AACpE,YAAM,KAAK,EAAE;AAEb,UAAI,SAAS,SAAS;AACpB,cAAM,KAAK,SAAS,OAAO;AAC3B,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,SAAS,WAAW,SAAS,GAAG;AAClC,cAAM,KAAK,iBAAiB;AAC5B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,iCAAiC;AAC5C,cAAM,KAAK,kCAAkC;AAC7C,mBAAW,SAAS,SAAS,YAAY;AACvC,gBAAM,KAAK,KAAK,MAAM,IAAI,MAAM,MAAM,EAAE,MAAM,MAAM,IAAI,MAAM,MAAM,WAAW,QAAQ,IAAI,IAAI;AAAA,QACjG;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAEA,UAAI,SAAS,UAAU,SAAS,GAAG;AACjC,cAAM,KAAK,gBAAgB;AAC3B,cAAM,KAAK,EAAE;AACb,mBAAW,QAAQ,SAAS,WAAW;AACrC,gBAAM,KAAK,OAAO,KAAK,MAAM,OAAO,KAAK,eAAe,gBAAgB,EAAE;AAAA,QAC5E;AACA,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,KAAK,kDAAkD;AAAA,EAC/D;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,gBAAgB,WAAmC;AAC1D,QAAM,OAAO;AAAA,IACX,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,SAAS;AAAA,IACX;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AAEA,aAAW,YAAY,WAAW;AAChC,QAAI,CAAC,KAAK,MAAM,SAAS,IAAI,GAAG;AAC9B,WAAK,MAAM,SAAS,IAAI,IAAI,CAAC;AAAA,IAC/B;AAEA,SAAK,MAAM,SAAS,IAAI,EAAE,SAAS,OAAO,YAAY,CAAC,IAAI;AAAA,MACzD,MAAM,CAAC,SAAS,UAAU;AAAA,MAC1B,aAAa,SAAS;AAAA,MACtB,SAAS,SAAS;AAAA,MAClB,YAAY,SAAS,WAClB,OAAO,OAAK,EAAE,OAAO,MAAM,EAC3B,IAAI,QAAM;AAAA,QACT,MAAM,EAAE;AAAA,QACR,IAAI,EAAE;AAAA,QACN,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE,MAAM,EAAE,KAAK;AAAA,MACzB,EAAE;AAAA,MACJ,WAAW,OAAO;AAAA,QAChB,SAAS,UAAU,IAAI,OAAK;AAAA,UAC1B,EAAE,OAAO,SAAS;AAAA,UAClB,EAAE,aAAa,EAAE,eAAe,WAAW;AAAA,QAC7C,CAAC;AAAA,MACH;AAAA,MACA,UAAU,SAAS,YAAY,CAAC,EAAE,YAAY,CAAC,EAAE,CAAC,IAAI;AAAA,IACxD;AAAA,EACF;AAEA,SAAO,KAAK,UAAU,MAAM,MAAM,CAAC;AACrC;;;AC5VO,IAAM,8BAAwC;AAAA,EACnD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,eAAsB,uBAAuB,QAAiC;AAC5E,QAAM,EAAE,SAAS,eAAe,cAAc,iBAAiB,YAAY,eAAe,IAAI,OAAO;AAErG,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiBH,QAAQ,QAAQ;AAAA,MAChB,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BA0BI,aAAa,IAAI,iDAAiD,aAAa,IAAI;AAAA,2BACpF,aAAa,SAAS,qCAAqC,aAAa,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAY5F,aAAa,IAAI,wBAAwB,aAAa,SAAS;AAAA,oBAC3D,aAAa,IAAI,kBAAkB,aAAa,SAAS;AAAA,eAC9D,aAAa,IAAI,eAAe,aAAa,SAAS;AAAA,gBACrD,aAAa,IAAI,oBAAoB,aAAa,SAAS;AAAA,iBAC1D,aAAa,IAAI,mBAAmB,aAAa,SAAS;AAAA;AAAA;AAAA,OAGpE,aAAa,IAAI;AAAA,OACjB,aAAa,SAAS;AAAA,+CACkB,aAAa,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yCAW5B,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uCAMlB,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0CAOb,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4CAchB,QAAQ,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAe5D,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,eA2CF,WAAW,MAAM;AAAA,oBACZ,WAAW,WAAW;AAAA,uBACnB,WAAW,cAAc;AAAA,YACpC,WAAW,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMd,WAAW,MAAM;AAAA;AAAA;AAAA;AAAA,YAIjB,WAAW,WAAW;AAAA;AAAA;AAAA;AAAA,YAItB,WAAW,cAAc;AAAA;AAAA;AAAA;AAAA,YAIzB,WAAW,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAYR,eAAe,UAAU,QAAQ,UAAU,QAAQ,CAAC;AAAA,uBAC/C,eAAe,eAAe,QAAQ,UAAU,QAAQ,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAMpE,WAAW,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAmKN,aAAa,IAAI,oBAAoB,aAAa,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gDAwGvC,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAsCxC,QAAQ,QAAQ,kCAAkC,QAAQ,QAAQ;AAAA,0BAChE,QAAQ,UAAU,qCAAqC,QAAQ,UAAU;AAAA,uBAC5E,cAAc,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC;AAAA,yBAClC,aAAa,IAAI,UAAU,aAAa,IAAI;AAAA,8BACvC,aAAa,SAAS,UAAU,aAAa,SAAS;AAAA;AAAA;AAAA;AAAA,yBAI3D,WAAW,MAAM;AAAA,sBACpB,WAAW,GAAG;AAAA;AAAA;AAGpC;;;AChhBA,OAAOC,WAAU;AAEV,IAAM,8BAAwC;AAAA,EACnD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,eAAsB,uBAAuB,QAAiC;AAC5E,QAAM,cAAc,OAAO,WAAW;AACtC,QAAM,cAAc,MAAM,cAAc,WAAW;AACnD,QAAM,YAAY,MAAM,wBAAwB,WAAW;AAE3D,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,kCAAkC;AAC7C,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,gBAAgB,YAAY,IAAI,IAAI;AAC/C,QAAM,KAAK,mBAAmB,YAAY,OAAO,IAAI;AACrD,QAAM,KAAK,kBAAkB,WAAW,MAAM;AAC9C,QAAM,KAAK,0BAA0B,YAAY,YAAY,QAAQ,IAAI,IAAI;AAC7E,MAAI,YAAY,eAAe;AAC7B,UAAM,KAAK,4BAA4B,YAAY,aAAa,MAAM;AAAA,EACxE;AACA,QAAM,KAAK,wBAAwB,YAAY,YAAY,QAAQ,IAAI,IAAI;AAC3E,QAAM,KAAK,mBAAmB,YAAY,YAAY,QAAQ,IAAI,IAAI;AACtE,MAAI,YAAY,eAAe;AAC7B,UAAM,KAAK,uBAAuB,YAAY,aAAa,MAAM;AAAA,EACnE;AACA,QAAM,KAAK,0BAA0B,YAAY,WAAW,QAAQ,IAAI,IAAI;AAC5E,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,GAAG,YAAY,IAAI,GAAG;AACjC,MAAI,UAAU,QAAQ;AACpB,UAAM,KAAK,sBAAOA,MAAK,SAAS,UAAU,MAAM,CAAC,sCAAsC;AAAA,EACzF;AACA,MAAI,UAAU,aAAa;AACzB,UAAM,KAAK,sBAAOA,MAAK,SAAS,UAAU,WAAW,CAAC,sCAAsC;AAAA,EAC9F;AACA,MAAI,UAAU,gBAAgB;AAC5B,UAAM,KAAK,sBAAOA,MAAK,SAAS,UAAU,cAAc,CAAC,+BAA+B;AAAA,EAC1F;AACA,MAAI,UAAU,KAAK;AACjB,UAAM,KAAK,sBAAOA,MAAK,SAAS,UAAU,GAAG,CAAC,yCAAyC;AAAA,EACzF;AACA,MAAI,UAAU,KAAK;AACjB,UAAM,KAAK,8DAA+C;AAAA,EAC5D;AACA,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,MAAI,YAAY,YAAY,SAAS,GAAG;AACtC,UAAM,KAAK,kBAAkB;AAC7B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,oBAAoB;AAC/B,eAAW,UAAU,YAAY,aAAa;AAC5C,YAAM,OAAOA,MAAK,SAAS,QAAQ,SAAS;AAC5C,YAAM,eAAeA,MAAK,SAAS,aAAa,MAAM;AACtD,YAAM,KAAK,KAAK,IAAI,QAAQ,YAAY,MAAM;AAAA,IAChD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,UAAU,YAAY;AACxB,UAAM,iBAAiB,MAAM,UAAU,QAAQ;AAAA,MAC7C,KAAK,UAAU;AAAA,MACf,QAAQ,CAAC,eAAe;AAAA,IAC1B,CAAC;AAED,UAAM,aAAa,eAChB,IAAI,OAAKA,MAAK,SAAS,CAAC,CAAC,EACzB,OAAO,OAAK,CAAC,EAAE,SAAS,eAAe,KAAK,CAAC,EAAE,SAAS,YAAY,CAAC,EACrE,KAAK;AAER,UAAM,KAAK,uBAAuB;AAClC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,mBAAmBA,MAAK,SAAS,aAAa,UAAU,UAAU,CAAC,IAAI;AAClF,UAAM,KAAK,yBAAyB,WAAW,MAAM,EAAE;AACvD,UAAM,KAAK,EAAE;AAEb,QAAI,WAAW,SAAS,GAAG;AACzB,YAAM,KAAK,uBAAuB;AAClC,YAAM,KAAK,EAAE;AACb,YAAM,SAAS,WAAW,MAAM,EAAE;AAClC,iBAAW,aAAa,QAAQ;AAC9B,cAAM,KAAK,OAAO,UAAU,QAAQ,OAAO,EAAE,CAAC,IAAI;AAAA,MACpD;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,QAAM,KAAK,kBAAkB;AAC7B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uBAAuB;AAClC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,KAAK,UAAU;AAAA,IACxB,YAAY,OAAO;AAAA,IACnB,aAAa;AAAA,MACX,SAAS,OAAO,YAAY;AAAA,MAC5B,eAAe,OAAO,YAAY;AAAA,MAClC,iBAAiB,OAAO,YAAY;AAAA,IACtC;AAAA,EACF,GAAG,MAAM,CAAC,CAAC;AACX,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,mBAAmB;AAC9B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,cAAc;AACzB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,WAAW;AACtB,QAAM,KAAK,MAAM,UAAU,MAAMA,MAAK,SAAS,aAAa,UAAU,GAAG,IAAI,gBAAgB,EAAE;AAC/F,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,gBAAgB;AAC3B,QAAM,KAAK,MAAM,UAAU,MAAMA,MAAK,SAAS,aAAa,UAAU,GAAG,IAAI,oBAAoB,EAAE;AACnG,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,wDAAwD;AACnE,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,2BAA2B;AACtC,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,wBAAwB;AACnC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,wBAAwB;AACnC,QAAM,KAAK,wBAAwB;AACnC,QAAM,KAAK,sEAAsE;AACjF,QAAM,KAAK,mEAAmE;AAC9E,QAAM,KAAK,+EAA+E;AAC1F,QAAM,KAAK,iDAAiD;AAC5D,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;;;AC3JA,OAAOC,YAAU;AAEV,IAAM,+BAAyC;AAAA,EACpD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AACZ;AAaA,eAAsB,wBACpB,QACA,gBACiB;AACjB,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAE7E,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO;AAAA,EACT;AAEA,QAAM,kBAAkB,MAAM,oBAAoB,UAAU,GAAG;AAC/D,QAAM,eAAiC,CAAC;AAExC,aAAW,QAAQ,iBAAiB;AAClC,UAAMC,aAAY,MAAM,gBAAgB,MAAM,UAAU,IAAI;AAC5D,iBAAa,KAAK,GAAGA,UAAS;AAAA,EAChC;AAGA,QAAM,YAAY,iBACd,aAAa;AAAA,IAAO,OACpB,EAAE,KAAK,YAAY,EAAE,SAAS,eAAe,YAAY,CAAC,KAC1D,EAAE,WAAW,YAAY,EAAE,SAAS,eAAe,YAAY,CAAC;AAAA,EAClE,IACE;AAEJ,SAAO,gBAAgB,WAAW,cAAc;AAClD;AAEA,eAAe,gBAAgB,UAAkB,WAA8C;AAC7F,QAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,QAAM,WAAWD,OAAK,SAAS,UAAU,KAAK;AAC9C,QAAM,iBAAiB,SAAS,QAAQ,cAAc,EAAE;AACxD,QAAM,YAA8B,CAAC;AAGrC,QAAM,aAAa,QAAQ,MAAM,iCAAiC;AAClE,QAAM,YAAY,aACd,WAAW,CAAC,EAAE,QAAQ,gBAAgB,eAAe,YAAY,CAAC,IAClE,QAAQ,eAAe,YAAY,CAAC;AAGxC,QAAM,iBAAiB,mEAAmE,KAAK,OAAO;AAGtG,QAAM,cAAc,CAAC,WAAW,YAAY,WAAW,aAAa,YAAY;AAChF,MAAI;AAEJ,aAAW,cAAc,aAAa;AACpC,UAAM,QAAQ,IAAI;AAAA,MAChB,MAAM,UAAU;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,QAAQ,MAAM,KAAK,OAAO,OAAO,MAAM;AAC7C,YAAM,cAAc,MAAM,CAAC,KAAK;AAChC,YAAM,aAAa,MAAM,CAAC;AAC1B,YAAM,aAAa,MAAM,CAAC;AAC1B,YAAM,SAAS,MAAM,CAAC;AAGtB,UAAI,WAAW;AACf,UAAI,aAAa;AACf,mBAAW,GAAG,SAAS,IAAI,WAAW;AAAA,MACxC;AAGA,YAAM,aAAa,gBAAgB,MAAM;AAGzC,YAAM,kBAAkB,QAAQ,UAAU,KAAK,IAAI,GAAG,MAAM,QAAQ,GAAG,GAAG,MAAM,KAAK,EAClF,SAAS,YAAY;AAExB,gBAAU,KAAK;AAAA,QACb,QAAQ,WAAW,QAAQ,QAAQ,EAAE,EAAE,YAAY;AAAA,QACnD,MAAM,SAAS,QAAQ,QAAQ,GAAG;AAAA,QAClC,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,WAAW,kBAAkB;AAAA,MAC/B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,cAAgC;AACvD,MAAI,CAAC,aAAa,KAAK,EAAG,QAAO,CAAC;AAElC,QAAM,SAAmB,CAAC;AAC1B,QAAM,QAAQ,aAAa,MAAM,GAAG;AAEpC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,KAAK,KAAK;AAC1B,QAAI,CAAC,QAAS;AAGd,UAAM,QAAQ,QAAQ,MAAM,mBAAmB;AAC/C,QAAI,OAAO;AAET,UAAI,QAAQ,SAAS,YAAY,GAAG;AAClC,eAAO,KAAK,SAAS,MAAM,CAAC,CAAC,EAAE;AAAA,MACjC,WAAW,QAAQ,SAAS,aAAa,GAAG;AAC1C,eAAO,KAAK,UAAU,MAAM,CAAC,CAAC,EAAE;AAAA,MAClC,WAAW,QAAQ,SAAS,aAAa,GAAG;AAC1C,eAAO,KAAK,UAAU,MAAM,CAAC,CAAC,EAAE;AAAA,MAClC,OAAO;AACL,eAAO,KAAK,MAAM,CAAC,CAAC;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,WAA6B,QAAyB;AAC7E,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,4BAA4B;AACvC,QAAM,KAAK,EAAE;AAEb,MAAI,QAAQ;AACV,UAAM,KAAK,oBAAoB,MAAM,IAAI;AACzC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,KAAK,2CAA2C;AACtD,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAGA,QAAM,eAAe,oBAAI,IAA8B;AACvD,aAAW,YAAY,WAAW;AAChC,UAAM,WAAW,aAAa,IAAI,SAAS,UAAU,KAAK,CAAC;AAC3D,aAAS,KAAK,QAAQ;AACtB,iBAAa,IAAI,SAAS,YAAY,QAAQ;AAAA,EAChD;AAGA,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,wBAAwB,UAAU,MAAM,EAAE;AACrD,QAAM,KAAK,oBAAoB,aAAa,IAAI,EAAE;AAClD,QAAM,KAAK,EAAE;AAGb,QAAM,eAAe,oBAAI,IAAoB;AAC7C,aAAW,YAAY,WAAW;AAChC,iBAAa,IAAI,SAAS,SAAS,aAAa,IAAI,SAAS,MAAM,KAAK,KAAK,CAAC;AAAA,EAChF;AAEA,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,oBAAoB;AAC/B,aAAW,CAAC,QAAQ,KAAK,KAAK,cAAc;AAC1C,UAAM,KAAK,KAAK,MAAM,MAAM,KAAK,IAAI;AAAA,EACvC;AACA,QAAM,KAAK,EAAE;AAGb,aAAW,CAAC,YAAY,mBAAmB,KAAK,cAAc;AAC5D,UAAM,KAAK,MAAM,UAAU,YAAY;AACvC,UAAM,KAAK,EAAE;AAGb,wBAAoB,KAAK,CAAC,GAAG,MAAM;AACjC,YAAM,cAAc,EAAE,KAAK,cAAc,EAAE,IAAI;AAC/C,UAAI,gBAAgB,EAAG,QAAO;AAC9B,aAAO,EAAE,OAAO,cAAc,EAAE,MAAM;AAAA,IACxC,CAAC;AAED,eAAW,YAAY,qBAAqB;AAC1C,YAAM,YAAY,SAAS,YAAY,eAAQ;AAC/C,YAAM,cAAc,eAAe,SAAS,MAAM;AAElD,YAAM,KAAK,OAAO,WAAW,MAAM,SAAS,MAAM,MAAM,SAAS,IAAI,GAAG,SAAS,EAAE;AACnF,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,iBAAiB,SAAS,MAAM,IAAI;AAC/C,YAAM,KAAK,kBAAkB,SAAS,UAAU,IAAI;AAEpD,UAAI,SAAS,WAAW,SAAS,GAAG;AAClC,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,iBAAiB;AAC5B,mBAAW,SAAS,SAAS,YAAY;AACvC,gBAAM,KAAK,OAAO,KAAK,IAAI;AAAA,QAC7B;AAAA,MACF;AAEA,YAAM,KAAK,EAAE;AAAA,IACf;AAAA,EACF;AAGA,QAAM,KAAK,oBAAoB;AAC/B,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,mCAAmC;AAC9C,QAAM,KAAK,mCAAmC;AAC9C,aAAW,YAAY,WAAW;AAChC,UAAM;AAAA,MACJ,KAAK,SAAS,MAAM,QAAQ,SAAS,IAAI,QAAQ,SAAS,MAAM,MAAM,SAAS,YAAY,cAAO,QAAG;AAAA,IACvG;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,eAAe,QAAwB;AAC9C,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAO,aAAO;AAAA,IACnB,KAAK;AAAQ,aAAO;AAAA,IACpB,KAAK;AAAO,aAAO;AAAA,IACnB,KAAK;AAAS,aAAO;AAAA,IACrB,KAAK;AAAU,aAAO;AAAA,IACtB;AAAS,aAAO;AAAA,EAClB;AACF;;;AC9OA,OAAOE,YAAU;AAEV,IAAM,2BAAqC;AAAA,EAChD,KAAK;AAAA,EACL,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AACZ;AAwBA,eAAsB,oBACpB,QACA,aACiB;AACjB,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAE7E,MAAI,CAAC,UAAU,UAAU,CAAC,UAAU,gBAAgB;AAClD,WAAO;AAAA,EACT;AAEA,QAAM,WAAyB,CAAC;AAGhC,MAAI,UAAU,QAAQ;AACpB,UAAM,cAAc,MAAM,gBAAgB,UAAU,MAAM;AAC1D,eAAW,QAAQ,aAAa;AAC9B,YAAM,SAAS,MAAM,YAAY,MAAM,UAAU,MAAM,MAAM;AAC7D,UAAI,QAAQ;AACV,iBAAS,KAAK,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,UAAU,gBAAgB;AAC5B,UAAM,yBAAyB,UAAU,UAAU,gBAAgB,MAAM;AAAA,EAC3E;AAGA,QAAM,mBAAmB,cACrB,SAAS;AAAA,IAAO,OAChB,EAAE,KAAK,YAAY,EAAE,SAAS,YAAY,YAAY,CAAC,KACvD,EAAE,UAAU,YAAY,EAAE,SAAS,YAAY,YAAY,CAAC;AAAA,EAC9D,IACE;AAEJ,SAAO,aAAa,kBAAkB,aAAa,MAAM;AAC3D;AAEA,eAAe,YACb,UACA,UACA,SAC4B;AAC5B,QAAM,UAAU,MAAM,SAAS,QAAQ;AAGvC,QAAM,aAAa,QAAQ,MAAM,oDAAoD;AACrF,MAAI,CAAC,WAAY,QAAO;AAExB,QAAM,aAAa,WAAW,CAAC;AAG/B,MAAI,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,SAAS,KAC7D,WAAW,SAAS,OAAO,KAAK,WAAW,SAAS,SAAS,GAAG;AAChE,WAAO;AAAA,EACT;AAEA,QAAM,aAA6B,CAAC;AACpC,QAAM,gBAAoC,CAAC;AAG3C,QAAM,kBAAkB;AACxB,MAAI;AAEJ,UAAQ,QAAQ,gBAAgB,KAAK,OAAO,OAAO,MAAM;AACvD,UAAM,eAAe,MAAM,CAAC;AAC5B,UAAM,eAAe,MAAM,CAAC;AAG5B,QAAI,aAAa,WAAW,aAAa,KAAK,aAAa,WAAW,MAAM,GAAG;AAE7E,YAAM,cAAc,aAAa,MAAM,SAAS;AAChD,UAAI,aAAa;AACf,sBAAc,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,cAAc,YAAY,CAAC;AAAA,UAC3B;AAAA,QACF,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAGA,UAAM,uBAAuB,SAAS,KAAK,YAAY,KACrD,CAAC;AAAA,MAAC;AAAA,MAAQ;AAAA,MAAU;AAAA,MAAS;AAAA,MAAS;AAAA,MAAY;AAAA,MAChD;AAAA,MAAW;AAAA,MAAW;AAAA,MAAU;AAAA,MAAS;AAAA,IAAM,EAAE,SAAS,YAAY,KACxE,CAAC,aAAa,SAAS,GAAG;AAE5B,QAAI,wBAAwB,CAAC,aAAa,SAAS,GAAG,GAAG;AACvD,oBAAc,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,cAAc;AAAA,QACd;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,eAAW,KAAK;AAAA,MACd,MAAM;AAAA,MACN,MAAM,cAAc,YAAY;AAAA,MAChC,UAAU,QAAQ,SAAS,GAAG,YAAY,KAAK,YAAY,EAAE,KAC3D,QAAQ,SAAS,GAAG,YAAY,MAAM,YAAY,EAAE;AAAA,MACtD,cAAc,iBAAiB,QAAQ,iBAAiB,GAAG,UAAU;AAAA,IACvE,CAAC;AAAA,EACH;AAGA,QAAM,YAAY,OAAO,UAAU;AAEnC,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAMA,OAAK,SAAS,UAAU,QAAQ;AAAA,EACxC;AACF;AAEA,eAAe,yBACb,UACA,oBACA,SACe;AACf,QAAM,cAAc,MAAM,UAAU,6BAA6B;AAAA,IAC/D,KAAK;AAAA,EACP,CAAC;AAED,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AAGnC,UAAM,aAAa,QAAQ,MAAM,4BAA4B;AAC7D,QAAI,YAAY;AAEd,YAAM,cAAc,QAAQ,MAAM,iCAAiC;AACnE,UAAI,aAAa;AACf,cAAM,aAAa,YAAY,CAAC;AAChC,cAAM,SAAS,SAAS,KAAK,OAAK,EAAE,SAAS,UAAU;AACvD,YAAI,QAAQ;AACV,iBAAO,YAAY,WAAW,CAAC;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAGA,UAAM,mBAAmB,QAAQ,SAAS,uFAAuF;AACjI,eAAW,SAAS,kBAAkB;AACpC,YAAM,eAAe,MAAM,CAAC;AAC5B,YAAM,YAAY,SAAS,MAAM,CAAC,GAAG,EAAE;AAEvC,iBAAW,UAAU,UAAU;AAC7B,cAAM,WAAW,OAAO,WAAW,KAAK,OAAK,EAAE,SAAS,YAAY;AACpE,YAAI,UAAU;AACZ,mBAAS,YAAY;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,YAA4B;AACjD,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,OAAO;AAAA,IACP,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,WAAW;AAAA,IACX,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,IACV,SAAS;AAAA,IACT,SAAS;AAAA,IACT,UAAU;AAAA,EACZ;AAGA,QAAM,WAAW,WAAW,QAAQ,KAAK,EAAE;AAC3C,SAAO,QAAQ,QAAQ,KAAK;AAC9B;AAEA,SAAS,aACP,UACA,QACA,SACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,8BAA8B;AACzC,QAAM,KAAK,EAAE;AAEb,MAAI,QAAQ;AACV,UAAM,KAAK,oBAAoB,MAAM,IAAI;AACzC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,SAAS,WAAW,GAAG;AACzB,UAAM,KAAK,0CAA0C;AACrD,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAGA,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uBAAuB,SAAS,MAAM,EAAE;AACnD,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,iDAAiD;AAC5D,QAAM,KAAK,iDAAiD;AAC5D,aAAW,UAAU,UAAU;AAC7B,UAAM;AAAA,MACJ,KAAK,OAAO,IAAI,QAAQ,OAAO,SAAS,QAAQ,OAAO,WAAW,MAAM,MAAM,OAAO,cAAc,MAAM;AAAA,IAC3G;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAGb,aAAW,UAAU,UAAU;AAC7B,UAAM,KAAK,MAAM,OAAO,IAAI,EAAE;AAC9B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,gBAAgB,OAAO,SAAS,IAAI;AAC/C,UAAM,KAAK,eAAe,OAAO,IAAI,IAAI;AACzC,UAAM,KAAK,EAAE;AAGb,UAAM,KAAK,aAAa;AACxB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,0CAA0C;AACrD,UAAM,KAAK,0CAA0C;AAErD,eAAW,QAAQ,OAAO,YAAY;AACpC,YAAM,QAAkB,CAAC;AACzB,UAAI,KAAK,aAAc,OAAM,KAAK,IAAI;AACtC,UAAI,KAAK,UAAW,OAAM,KAAK,aAAa,KAAK,SAAS,GAAG;AAE7D,YAAM;AAAA,QACJ,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,KAAK,WAAW,QAAQ,IAAI,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,MACvF;AAAA,IACF;AACA,UAAM,KAAK,EAAE;AAGb,QAAI,OAAO,cAAc,SAAS,GAAG;AACnC,YAAM,KAAK,mBAAmB;AAC9B,YAAM,KAAK,EAAE;AACb,YAAM,KAAK,8BAA8B;AACzC,YAAM,KAAK,8BAA8B;AAEzC,iBAAW,OAAO,OAAO,eAAe;AACtC,cAAM,WAAW,IAAI,SAAS,eAAe,QAC3C,IAAI,SAAS,gBAAgB,QAAQ;AACvC,cAAM,KAAK,KAAK,QAAQ,MAAM,IAAI,YAAY,MAAM,IAAI,YAAY,IAAI;AAAA,MAC1E;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAGA,UAAM,KAAK,2BAA2B;AACtC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,gBAAgB,OAAO,IAAI,4CAA4C,OAAO,IAAI,GAAG;AAChG,UAAM,KAAK,GAAG;AACd,UAAM,KAAK,+CAA+C,OAAO,IAAI,YAAY;AACjF,UAAM,KAAK,OAAO;AAClB,UAAM,KAAK,4BAA4B,OAAO,SAAS,KAAK;AAC5D,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,OAAO,WAAW,KAAK,OAAK,EAAE,YAAY;AACrD,QAAI,IAAI;AACN,YAAM,KAAK,iCAAiC,GAAG,IAAI,IAAI;AAAA,IACzD;AACA,UAAM,KAAK,OAAO;AAClB,UAAM,KAAK,GAAG;AACd,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,yBAAyB;AACpC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAEhB,eAAW,UAAU,UAAU;AAC7B,iBAAW,OAAO,OAAO,eAAe;AACtC,cAAM,QAAQ,IAAI,SAAS,eAAe,iBACxC,IAAI,SAAS,gBAAgB,YAAO;AACtC,cAAM,KAAK,GAAG,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,YAAY,EAAE;AAAA,MAC1D;AAAA,IACF;AAEA,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;;;Af1TA,eAAsB,eAAgC;AACpD,QAAM,SAAS,MAAM,UAAU;AAE/B,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,cAAc;AAAA,QACZ,OAAO,CAAC;AAAA,QACR,WAAW,CAAC;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAMA,SAAO,kBAAkB,wBAAwB,YAAY;AAC3D,WAAO,MAAM,eAAe;AAC5B,WAAO;AAAA,MACL,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,UAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAC1C,UAAM,YAAY,KAAK,IAAI;AAE3B,WAAO,UAAU,MAAM,IAAI;AAE3B,QAAI;AACF,UAAI;AAEJ,cAAQ,MAAM;AAAA,QACZ,KAAK;AACH,mBAAS,MAAM,0BAA0B,MAAM,MAAM;AACrD;AAAA,QAEF,KAAK;AACH,mBAAS,MAAM,sBAAsB,MAAM,MAAM;AACjD;AAAA,QAEF,KAAK;AACH,mBAAS,MAAM,wBAAwB,MAAM,MAAM;AACnD;AAAA,QAEF,KAAK;AACH,mBAAS,MAAM,cAAc,MAAM,MAAM;AACzC;AAAA,QAEF;AACE,gBAAM,IAAI,MAAM,iBAAiB,IAAI,EAAE;AAAA,MAC3C;AAEA,aAAO,QAAQ,MAAM,MAAM,KAAK,IAAI,IAAI,SAAS;AAEjD,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,aAAO,UAAU,MAAM,GAAG;AAE1B,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,UAAU,IAAI,OAAO;AAAA,UAC7B;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAMD,SAAO,kBAAkB,4BAA4B,YAAY;AAC/D,WAAO,MAAM,mBAAmB;AAChC,WAAO;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO,kBAAkB,2BAA2B,OAAO,YAAY;AACrE,UAAM,EAAE,IAAI,IAAI,QAAQ;AACxB,WAAO,MAAM,oBAAoB,EAAE,IAAI,CAAC;AAExC,QAAI;AACF,UAAI;AACJ,UAAI,WAAW;AAEf,UAAI,QAAQ,4BAA4B;AACtC,kBAAU,MAAM,uBAAuB,MAAM;AAAA,MAC/C,WAAW,QAAQ,wBAAwB;AACzC,kBAAU,MAAM,uBAAuB,MAAM;AAAA,MAC/C,WAAW,IAAI,WAAW,mBAAmB,GAAG;AAC9C,cAAM,WAAW,IAAI,QAAQ,qBAAqB,EAAE;AACpD,kBAAU,MAAM,wBAAwB,QAAQ,QAAQ;AAAA,MAC1D,WAAW,IAAI,WAAW,sBAAsB,GAAG;AACjD,cAAM,QAAQ,IAAI,QAAQ,wBAAwB,EAAE;AACpD,kBAAU,MAAM,oBAAoB,QAAQ,KAAK;AAAA,MACnD,OAAO;AACL,cAAM,IAAI,MAAM,qBAAqB,GAAG,EAAE;AAAA,MAC5C;AAEA,aAAO;AAAA,QACL,UAAU;AAAA,UACR;AAAA,YACE;AAAA,YACA;AAAA,YACA,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,YAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,aAAO,MAAM,wBAAwB,EAAE,KAAK,OAAO,IAAI,QAAQ,CAAC;AAChE,YAAM;AAAA,IACR;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,eAAsB,YAA2B;AAC/C,SAAO,KAAK,mCAAmC;AAE/C,QAAM,SAAS,MAAM,aAAa;AAClC,QAAM,YAAY,IAAI,qBAAqB;AAE3C,QAAM,OAAO,QAAQ,SAAS;AAE9B,SAAO,KAAK,wCAAwC;AACtD;;;AgB5KA,QAAQ,GAAG,qBAAqB,CAAC,UAAU;AACzC,SAAO,MAAM,sBAAsB,EAAE,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,CAAC;AAC/E,UAAQ,KAAK,CAAC;AAChB,CAAC;AAED,QAAQ,GAAG,sBAAsB,CAAC,WAAW;AAC3C,SAAO,MAAM,uBAAuB,EAAE,OAAO,CAAC;AAC9C,UAAQ,KAAK,CAAC;AAChB,CAAC;AAGD,UAAU,EAAE,MAAM,CAAC,UAAU;AAC3B,SAAO,MAAM,0BAA0B,EAAE,OAAO,MAAM,QAAQ,CAAC;AAC/D,UAAQ,KAAK,CAAC;AAChB,CAAC;","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/tools/suggest-migration.ts","../src/resources/conventions.ts","../src/resources/project-info.ts","../src/resources/api-endpoints.ts","../src/resources/db-schema.ts","../src/resources/entities.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';\nimport { handleSuggestMigration, suggestMigrationTool } from './tools/suggest-migration.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';\nimport { getEntitiesResource, entitiesResourceTemplate } from './resources/entities.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 suggestMigrationTool,\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 case 'suggest_migration':\n result = await handleSuggestMigration(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 entitiesResourceTemplate,\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 if (uri.startsWith('smartstack://entities/')) {\n const entityFilter = uri.replace('smartstack://entities/', '');\n content = await getEntitiesResource(config, entityFilter || undefined);\n } else if (uri === 'smartstack://entities') {\n content = await getEntitiesResource(config);\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';\nimport { fileExists, readJson } from './utils/fs.js';\nimport { logger } from './lib/logger.js';\nimport type { Config } from './types/index.js';\n\n// Default configuration - projectPath will be resolved dynamically\nconst defaultConfig: Config = {\n version: '1.0.0',\n smartstack: {\n // Will be resolved in getConfig() - never use a hard-coded path\n projectPath: '',\n apiUrl: process.env.SMARTSTACK_API_URL || 'https://localhost:5001',\n apiEnabled: process.env.SMARTSTACK_API_ENABLED !== 'false',\n },\n conventions: {\n schemas: {\n platform: 'core',\n extensions: 'extensions',\n },\n tablePrefixes: [\n 'auth_', 'nav_', 'usr_', 'ai_', 'cfg_', 'wkf_',\n 'support_', 'entra_', 'ref_', 'loc_', 'lic_', 'tenant_'\n ],\n codePrefixes: {\n core: 'core_',\n extension: 'ext_',\n },\n migrationFormat: '{context}_v{version}_{sequence}_{Description}',\n namespaces: {\n domain: 'SmartStack.Domain',\n application: 'SmartStack.Application',\n infrastructure: 'SmartStack.Infrastructure',\n api: 'SmartStack.Api',\n },\n servicePattern: {\n interface: 'I{Name}Service',\n implementation: '{Name}Service',\n },\n },\n efcore: {\n contexts: [\n {\n name: 'ApplicationDbContext',\n projectPath: 'auto-detect',\n migrationsFolder: 'Migrations',\n },\n ],\n validation: {\n checkModelSnapshot: true,\n checkMigrationOrder: true,\n requireBuildSuccess: true,\n },\n },\n scaffolding: {\n outputPath: 'auto-detect',\n templates: {\n service: 'templates/service-extension.cs.hbs',\n entity: 'templates/entity-extension.cs.hbs',\n controller: 'templates/controller.cs.hbs',\n component: 'templates/component.tsx.hbs',\n },\n },\n};\n\nlet cachedConfig: Config | null = null;\n\n/**\n * Resolve the SmartStack project path\n * Priority: 1. SMARTSTACK_PROJECT_PATH env var, 2. Config file, 3. Current working directory\n */\nfunction resolveProjectPath(configPath?: string): string {\n // Priority 1: Environment variable\n if (process.env.SMARTSTACK_PROJECT_PATH) {\n return process.env.SMARTSTACK_PROJECT_PATH;\n }\n\n // Priority 2: Config file value (if provided and not empty)\n if (configPath && configPath.trim()) {\n return configPath;\n }\n\n // Priority 3: Current working directory\n const cwd = process.cwd();\n logger.warn('No SMARTSTACK_PROJECT_PATH configured, using current directory', { cwd });\n return cwd;\n}\n\n/**\n * Get the configuration, loading from file if available\n */\nexport async function getConfig(): Promise<Config> {\n if (cachedConfig) {\n return cachedConfig;\n }\n\n // Try to load from config file\n const configPath = path.join(process.cwd(), 'config', 'default-config.json');\n\n if (await fileExists(configPath)) {\n try {\n const fileConfig = await readJson<Partial<Config>>(configPath);\n cachedConfig = mergeConfig(defaultConfig, fileConfig);\n logger.info('Configuration loaded from file', { path: configPath });\n } catch (error) {\n logger.warn('Failed to load config file, using defaults', { error });\n cachedConfig = { ...defaultConfig };\n }\n } else {\n logger.debug('No config file found, using defaults');\n cachedConfig = { ...defaultConfig };\n }\n\n // Resolve project path dynamically (never use hard-coded path)\n cachedConfig.smartstack.projectPath = resolveProjectPath(\n cachedConfig.smartstack.projectPath\n );\n\n // Override with environment variables\n if (process.env.SMARTSTACK_API_URL) {\n cachedConfig.smartstack.apiUrl = process.env.SMARTSTACK_API_URL;\n }\n\n // Validate project path exists\n if (!cachedConfig.smartstack.projectPath) {\n throw new Error(\n 'SmartStack project path not configured. Set SMARTSTACK_PROJECT_PATH environment variable or configure in config file.'\n );\n }\n\n return cachedConfig;\n}\n\n/**\n * Deep merge configuration objects\n */\nfunction mergeConfig(base: Config, override: Partial<Config>): Config {\n return {\n ...base,\n ...override,\n smartstack: {\n ...base.smartstack,\n ...override.smartstack,\n },\n conventions: {\n ...base.conventions,\n ...override.conventions,\n schemas: {\n ...base.conventions.schemas,\n ...override.conventions?.schemas,\n },\n codePrefixes: {\n ...base.conventions.codePrefixes,\n ...override.conventions?.codePrefixes,\n },\n namespaces: {\n ...base.conventions.namespaces,\n ...override.conventions?.namespaces,\n },\n servicePattern: {\n ...base.conventions.servicePattern,\n ...override.conventions?.servicePattern,\n },\n },\n efcore: {\n ...base.efcore,\n ...override.efcore,\n contexts: override.efcore?.contexts || base.efcore.contexts,\n validation: {\n ...base.efcore.validation,\n ...override.efcore?.validation,\n },\n },\n scaffolding: {\n ...base.scaffolding,\n ...override.scaffolding,\n templates: {\n ...base.scaffolding.templates,\n ...override.scaffolding?.templates,\n },\n },\n };\n}\n\n/**\n * Get SmartStack project path\n */\nexport function getProjectPath(config: Config): string {\n return config.smartstack.projectPath;\n}\n\n/**\n * Clear cached configuration (for testing)\n */\nexport function clearConfigCache(): void {\n cachedConfig = null;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\n\n/**\n * Custom error class for file system operations\n */\nexport class FileSystemError extends Error {\n constructor(\n message: string,\n public readonly operation: string,\n public readonly path: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'FileSystemError';\n }\n}\n\n/**\n * Validate that a path doesn't traverse outside a base directory\n * Prevents path traversal attacks (e.g., ../../../etc/passwd)\n */\nexport function validatePathSecurity(\n targetPath: string,\n baseDir: string\n): void {\n const normalizedTarget = path.resolve(targetPath);\n const normalizedBase = path.resolve(baseDir);\n\n // Check if target is within base directory\n if (!normalizedTarget.startsWith(normalizedBase + path.sep) && normalizedTarget !== normalizedBase) {\n throw new FileSystemError(\n `Path traversal detected: \"${targetPath}\" is outside allowed directory \"${baseDir}\"`,\n 'validatePathSecurity',\n targetPath\n );\n }\n}\n\n/**\n * Safe path join that validates the result stays within base directory\n */\nexport function safeJoinPath(baseDir: string, ...segments: string[]): string {\n const joined = path.join(baseDir, ...segments);\n validatePathSecurity(joined, baseDir);\n return joined;\n}\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 try {\n const content = await fs.readFile(filePath, 'utf-8');\n try {\n return JSON.parse(content) as T;\n } catch (parseError) {\n throw new FileSystemError(\n `Invalid JSON in file: ${filePath}`,\n 'readJson',\n filePath,\n parseError instanceof Error ? parseError : undefined\n );\n }\n } catch (error) {\n if (error instanceof FileSystemError) {\n throw error;\n }\n const err = error instanceof Error ? error : new Error(String(error));\n throw new FileSystemError(\n `Failed to read JSON file: ${filePath} - ${err.message}`,\n 'readJson',\n filePath,\n err\n );\n }\n}\n\n/**\n * Write a JSON file\n */\nexport async function writeJson<T>(filePath: string, data: T): Promise<void> {\n try {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n throw new FileSystemError(\n `Failed to write JSON file: ${filePath} - ${err.message}`,\n 'writeJson',\n filePath,\n err\n );\n }\n}\n\n/**\n * Read a text file\n */\nexport async function readText(filePath: string): Promise<string> {\n try {\n return await fs.readFile(filePath, 'utf-8');\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n throw new FileSystemError(\n `Failed to read file: ${filePath} - ${err.message}`,\n 'readText',\n filePath,\n err\n );\n }\n}\n\n/**\n * Write a text file\n */\nexport async function writeText(filePath: string, content: string): Promise<void> {\n try {\n await fs.ensureDir(path.dirname(filePath));\n await fs.writeFile(filePath, content, 'utf-8');\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n throw new FileSystemError(\n `Failed to write file: ${filePath} - ${err.message}`,\n 'writeText',\n filePath,\n err\n );\n }\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 codePrefixes: z.object({\n core: z.string().default('core_'),\n extension: z.string().default('ext_'),\n }),\n migrationFormat: z.string().default('{context}_v{version}_{sequence}_{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', 'entities', 'tenants', 'controllers', '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 EntityPropertySchema = z.object({\n name: z.string().describe('Property name (PascalCase)'),\n type: z.string().describe('C# type (string, int, Guid, DateTime, etc.)'),\n required: z.boolean().optional().describe('If true, property is required'),\n maxLength: z.number().optional().describe('Max length for string properties'),\n});\n\nexport const ScaffoldExtensionInputSchema = z.object({\n type: z.enum(['feature', 'service', 'entity', 'controller', 'component', 'test', 'dto', 'validator', 'repository'])\n .describe('Type of extension to scaffold. Use \"feature\" for full-stack generation.'),\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 isSystemEntity: z.boolean().optional().describe('If true, creates a system entity without TenantId'),\n tablePrefix: z.string().optional().describe('Domain prefix for table name (e.g., \"auth_\", \"nav_\", \"cfg_\")'),\n schema: z.enum(['core', 'extensions']).optional().describe('Database schema (default: core)'),\n dryRun: z.boolean().optional().describe('If true, preview generated code without writing files'),\n skipService: z.boolean().optional().describe('For feature type: skip service generation'),\n skipController: z.boolean().optional().describe('For feature type: skip controller generation'),\n skipComponent: z.boolean().optional().describe('For feature type: skip React component generation'),\n clientExtension: z.boolean().optional().describe('If true, use extensions schema for client-specific code'),\n withTests: z.boolean().optional().describe('For feature type: also generate unit tests'),\n withDtos: z.boolean().optional().describe('For feature type: generate DTOs (Create, Update, Response)'),\n withValidation: z.boolean().optional().describe('For feature type: generate FluentValidation validators'),\n withRepository: z.boolean().optional().describe('For feature type: generate repository pattern'),\n entityProperties: z.array(EntityPropertySchema).optional().describe('Entity properties for DTO/Validator generation'),\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 context: string; // DbContext name (core, extensions, etc.)\n version: string; // Semver version (1.0.0, 1.2.0, etc.)\n sequence: string; // Sequence number (001, 002, etc.)\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';\nimport { promisify } from 'util';\nimport { directoryExists } from './fs.js';\nimport path from 'path';\n\nconst execAsync = promisify(exec);\n\n/**\n * Custom error class for git operations\n */\nexport class GitError extends Error {\n constructor(\n message: string,\n public readonly command: string,\n public readonly cwd?: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'GitError';\n }\n}\n\n/**\n * Execute a git command with proper error handling\n */\nexport async function git(command: string, cwd?: string): Promise<string> {\n const options = cwd ? { cwd, maxBuffer: 10 * 1024 * 1024 } : { maxBuffer: 10 * 1024 * 1024 };\n try {\n const { stdout } = await execAsync(`git ${command}`, options);\n return stdout.trim();\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n // Extract stderr if available\n const stderr = (error as { stderr?: string })?.stderr || '';\n throw new GitError(\n `Git command failed: git ${command}${stderr ? ` - ${stderr.trim()}` : ''}`,\n command,\n cwd,\n err\n );\n }\n}\n\n/**\n * Check if directory is a git repository\n */\nexport async function isGitRepo(cwd?: string): Promise<boolean> {\n const gitDir = path.join(cwd || process.cwd(), '.git');\n return directoryExists(gitDir);\n}\n\n/**\n * Get current branch name\n */\nexport async function getCurrentBranch(cwd?: string): Promise<string | null> {\n try {\n return await git('branch --show-current', cwd);\n } catch {\n return null;\n }\n}\n\n/**\n * Check if working directory is clean\n */\nexport async function isClean(cwd?: string): Promise<boolean> {\n try {\n const status = await git('status --porcelain', cwd);\n return status === '';\n } catch {\n return false;\n }\n}\n\n/**\n * Get list of changed files\n */\nexport async function getChangedFiles(cwd?: string): Promise<string[]> {\n try {\n const status = await git('status --porcelain', cwd);\n if (!status) return [];\n\n return status.split('\\n')\n .map(line => line.substring(3).trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get commit count between two refs\n */\nexport async function getCommitCount(\n from: string,\n to: string,\n cwd?: string\n): Promise<number> {\n try {\n const result = await git(`rev-list --count ${from}..${to}`, cwd);\n return parseInt(result, 10);\n } catch {\n return 0;\n }\n}\n\n/**\n * Get latest tag\n */\nexport async function getLatestTag(cwd?: string): Promise<string | null> {\n try {\n return await git('describe --tags --abbrev=0', cwd);\n } catch {\n return null;\n }\n}\n\n/**\n * Check if branch exists\n */\nexport async function branchExists(branch: string, cwd?: string): Promise<boolean> {\n try {\n await git(`rev-parse --verify ${branch}`, cwd);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get list of all branches\n */\nexport async function getBranches(cwd?: string): Promise<string[]> {\n try {\n const result = await git('branch -a', cwd);\n return result.split('\\n')\n .map(line => line.replace(/^\\*?\\s+/, '').trim())\n .filter(Boolean);\n } catch {\n return [];\n }\n}\n\n/**\n * Get file content from a specific branch\n */\nexport async function getFileFromBranch(\n branch: string,\n filePath: string,\n cwd?: string\n): Promise<string | null> {\n try {\n return await git(`show ${branch}:${filePath}`, cwd);\n } catch {\n return null;\n }\n}\n\n/**\n * Get diff between branches for a specific file\n */\nexport async function getDiff(\n fromBranch: string,\n toBranch: string,\n filePath?: string,\n cwd?: string\n): Promise<string> {\n try {\n const pathArg = filePath ? ` -- ${filePath}` : '';\n return await git(`diff ${fromBranch}...${toBranch}${pathArg}`, cwd);\n } catch {\n return '';\n }\n}\n\n/**\n * Get remote URL\n */\nexport async function getRemoteUrl(remote: string = 'origin', cwd?: string): Promise<string | null> {\n try {\n return await git(`remote get-url ${remote}`, cwd);\n } catch {\n return null;\n }\n}\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';\nimport { ValidateConventionsInputSchema, type Config, type ValidationResult } from '../types/index.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const validateConventionsTool: Tool = {\n name: 'validate_conventions',\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, controller routes (NavRoute)',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to validate (default: SmartStack.app path from config)',\n },\n checks: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['tables', 'migrations', 'services', 'namespaces', 'entities', 'tenants', 'controllers', 'all'],\n },\n description: 'Types of checks to perform',\n default: ['all'],\n },\n },\n },\n};\n\nexport async function handleValidateConventions(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ValidateConventionsInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const checks = input.checks.includes('all')\n ? ['tables', 'migrations', 'services', 'namespaces', 'entities', 'tenants', 'controllers']\n : input.checks;\n\n logger.info('Validating conventions', { projectPath, checks });\n\n const result: ValidationResult = {\n valid: true,\n errors: [],\n warnings: [],\n summary: '',\n };\n\n const structure = await findSmartStackStructure(projectPath);\n\n // Run selected checks\n if (checks.includes('tables')) {\n await validateTablePrefixes(structure, config, result);\n }\n\n if (checks.includes('migrations')) {\n await validateMigrationNaming(structure, config, result);\n }\n\n if (checks.includes('services')) {\n await validateServiceInterfaces(structure, config, result);\n }\n\n if (checks.includes('namespaces')) {\n await validateNamespaces(structure, config, result);\n }\n\n if (checks.includes('entities')) {\n await validateEntities(structure, config, result);\n }\n\n if (checks.includes('tenants')) {\n await validateTenantAwareness(structure, config, result);\n }\n\n if (checks.includes('controllers')) {\n await validateControllerRoutes(structure, config, result);\n }\n\n // Update validity\n result.valid = result.errors.length === 0;\n\n // Generate summary\n result.summary = generateSummary(result, checks);\n\n return formatResult(result);\n}\n\nasync function validateTablePrefixes(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.infrastructure) {\n result.warnings.push({\n type: 'warning',\n category: 'tables',\n message: 'Infrastructure project not found, skipping table validation',\n });\n return;\n }\n\n // Find EF Core configuration files\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\n cwd: structure.infrastructure,\n });\n\n const validSchemas = [config.conventions.schemas.platform, config.conventions.schemas.extensions];\n const validPrefixes = config.conventions.tablePrefixes;\n\n // Map SchemaConstants to actual values\n const schemaConstantsMap: Record<string, string> = {\n 'SchemaConstants.Core': config.conventions.schemas.platform,\n 'SchemaConstants.Extensions': config.conventions.schemas.extensions,\n };\n\n for (const file of configFiles) {\n const content = await readText(file);\n\n // Match ToTable with string schema: .ToTable(\"tableName\", \"schemaName\")\n const tableWithStringSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*\"([^\"]+)\"\\s*\\)/g);\n\n for (const match of tableWithStringSchemaMatches) {\n const tableName = match[1];\n const schemaName = match[2];\n\n // Validate schema\n if (!validSchemas.includes(schemaName)) {\n result.errors.push({\n type: 'error',\n category: 'tables',\n message: `Table \"${tableName}\" uses invalid schema \"${schemaName}\"`,\n file: path.relative(structure.root, file),\n suggestion: `Use schema \"${config.conventions.schemas.platform}\" for SmartStack tables or \"${config.conventions.schemas.extensions}\" for client extensions`,\n });\n }\n\n // Validate table prefix (must have a domain prefix)\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\n result.warnings.push({\n type: 'warning',\n category: 'tables',\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\n file: path.relative(structure.root, file),\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\n });\n }\n }\n\n // Match ToTable with SchemaConstants: .ToTable(\"tableName\", SchemaConstants.Core)\n const tableWithConstantSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*,\\s*(SchemaConstants\\.\\w+)\\s*\\)/g);\n\n for (const match of tableWithConstantSchemaMatches) {\n const tableName = match[1];\n const schemaConstant = match[2];\n const resolvedSchema = schemaConstantsMap[schemaConstant];\n\n // Validate schema constant is known\n if (!resolvedSchema) {\n result.errors.push({\n type: 'error',\n category: 'tables',\n message: `Table \"${tableName}\" uses unknown schema constant \"${schemaConstant}\"`,\n file: path.relative(structure.root, file),\n suggestion: `Use SchemaConstants.Core for SmartStack tables or SchemaConstants.Extensions for client extensions`,\n });\n }\n\n // Validate table prefix (must have a domain prefix)\n const hasValidPrefix = validPrefixes.some(prefix => tableName.startsWith(prefix));\n if (!hasValidPrefix && !tableName.startsWith('__')) { // Ignore EF migrations history\n result.warnings.push({\n type: 'warning',\n category: 'tables',\n message: `Table \"${tableName}\" does not use a standard domain prefix`,\n file: path.relative(structure.root, file),\n suggestion: `Consider using a domain prefix: ${validPrefixes.slice(0, 5).join(', ')}, etc.`,\n });\n }\n }\n\n // Check for ToTable without schema (old format) - but exclude lines with SchemaConstants\n const tableWithoutSchemaMatches = content.matchAll(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"\\s*\\)(?!\\s*,)/g);\n\n for (const match of tableWithoutSchemaMatches) {\n const tableName = match[1];\n if (!tableName.startsWith('__')) { // Ignore EF migrations history\n result.errors.push({\n type: 'error',\n category: 'tables',\n message: `Table \"${tableName}\" is missing schema specification`,\n file: path.relative(structure.root, file),\n suggestion: `Add schema: .ToTable(\"${tableName}\", SchemaConstants.Core)`,\n });\n }\n }\n }\n}\n\nasync function validateMigrationNaming(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.migrations) {\n result.warnings.push({\n type: 'warning',\n category: 'migrations',\n message: 'Migrations folder not found, skipping migration validation',\n });\n return;\n }\n\n const migrationFiles = await findFiles('*.cs', { cwd: structure.migrations });\n\n // Expected format: {context}_v{version}_{sequence}_{Description}.cs\n // Example: core_v1.0.0_001_CreateAuthUsers.cs\n const migrationPattern = /^(\\w+)_v(\\d+\\.\\d+\\.\\d+)_(\\d{3})_(.+)\\.cs$/;\n const designerPattern = /\\.Designer\\.cs$/;\n\n for (const file of migrationFiles) {\n const fileName = path.basename(file);\n\n // Skip designer files and snapshot\n if (designerPattern.test(fileName) || fileName.includes('ModelSnapshot')) {\n continue;\n }\n\n if (!migrationPattern.test(fileName)) {\n result.errors.push({\n type: 'error',\n category: 'migrations',\n message: `Migration \"${fileName}\" does not follow naming convention`,\n file: path.relative(structure.root, file),\n suggestion: `Expected format: {context}_v{version}_{sequence}_{Description}.cs (e.g., core_v1.0.0_001_CreateAuthUsers.cs)`,\n });\n }\n }\n\n // Check version and sequence order\n const orderedMigrations = migrationFiles\n .map(f => path.basename(f))\n .filter(f => migrationPattern.test(f) && !f.includes('Designer'))\n .sort();\n\n for (let i = 1; i < orderedMigrations.length; i++) {\n const prev = orderedMigrations[i - 1];\n const curr = orderedMigrations[i];\n\n const prevMatch = migrationPattern.exec(prev);\n const currMatch = migrationPattern.exec(curr);\n\n if (prevMatch && currMatch) {\n const prevVersion = prevMatch[2];\n const currVersion = currMatch[2];\n\n // Check version ordering (semver comparison)\n if (currVersion < prevVersion) {\n result.warnings.push({\n type: 'warning',\n category: 'migrations',\n message: `Migration order issue: \"${curr}\" (v${currVersion}) comes before \"${prev}\" (v${prevVersion})`,\n });\n }\n }\n }\n}\n\nasync function validateServiceInterfaces(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.application) {\n result.warnings.push({\n type: 'warning',\n category: 'services',\n message: 'Application project not found, skipping service validation',\n });\n return;\n }\n\n // Find service implementations\n const serviceFiles = await findFiles('**/*Service.cs', {\n cwd: structure.application,\n });\n\n for (const file of serviceFiles) {\n const content = await readText(file);\n const fileName = path.basename(file, '.cs');\n\n // Skip interfaces\n if (fileName.startsWith('I')) continue;\n\n // Check if there's a matching interface\n const expectedInterface = `I${fileName}`;\n const interfacePattern = new RegExp(`:\\\\s*${expectedInterface}\\\\b`);\n\n if (!interfacePattern.test(content)) {\n // Check if file declares interface\n const declaresInterface = content.includes(`interface ${expectedInterface}`);\n\n if (!declaresInterface) {\n result.warnings.push({\n type: 'warning',\n category: 'services',\n message: `Service \"${fileName}\" should implement \"${expectedInterface}\"`,\n file: path.relative(structure.root, file),\n suggestion: `Create interface ${expectedInterface} and implement it`,\n });\n }\n }\n }\n}\n\nasync function validateNamespaces(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ValidationResult\n): Promise<void> {\n const layers = [\n { path: structure.domain, expected: config.conventions.namespaces.domain, name: 'Domain' },\n { path: structure.application, expected: config.conventions.namespaces.application, name: 'Application' },\n { path: structure.infrastructure, expected: config.conventions.namespaces.infrastructure, name: 'Infrastructure' },\n { path: structure.api, expected: config.conventions.namespaces.api, name: 'Api' },\n ];\n\n for (const layer of layers) {\n if (!layer.path) continue;\n\n const csFiles = await findFiles('**/*.cs', { cwd: layer.path });\n\n for (const file of csFiles.slice(0, 10)) { // Sample first 10 files\n const content = await readText(file);\n const namespaceMatch = content.match(/namespace\\s+([\\w.]+)/);\n\n if (namespaceMatch) {\n const namespace = namespaceMatch[1];\n\n if (!namespace.startsWith(layer.expected)) {\n result.errors.push({\n type: 'error',\n category: 'namespaces',\n message: `${layer.name} file has incorrect namespace \"${namespace}\"`,\n file: path.relative(structure.root, file),\n suggestion: `Should start with \"${layer.expected}\"`,\n });\n }\n }\n }\n }\n}\n\nasync function validateEntities(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.domain) {\n result.warnings.push({\n type: 'warning',\n category: 'entities',\n message: 'Domain project not found, skipping entity validation',\n });\n return;\n }\n\n // Find entity files\n const entityFiles = await findFiles('**/*.cs', { cwd: structure.domain });\n\n for (const file of entityFiles) {\n const content = await readText(file);\n const fileName = path.basename(file, '.cs');\n\n // Skip non-entity files\n if (fileName.endsWith('Dto') || fileName.endsWith('Command') ||\n fileName.endsWith('Query') || fileName.endsWith('Handler') ||\n fileName.endsWith('Validator') || fileName.endsWith('Exception') ||\n fileName.startsWith('I')) {\n continue;\n }\n\n // Check for class declaration\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*([^{]+))?/);\n if (!classMatch) continue;\n\n const entityName = classMatch[1];\n const inheritance = classMatch[2]?.trim() || '';\n\n // Check for proper base class/interface\n const hasBaseEntity = inheritance.includes('BaseEntity');\n const hasSystemEntity = inheritance.includes('SystemEntity');\n const hasITenantEntity = inheritance.includes('ITenantEntity');\n\n if (!hasBaseEntity && !hasSystemEntity) {\n // Could be a value object or other non-entity class\n continue;\n }\n\n // Entity should implement ITenantEntity if it's a BaseEntity (unless it's SystemEntity)\n if (hasBaseEntity && !hasSystemEntity && !hasITenantEntity) {\n result.warnings.push({\n type: 'warning',\n category: 'entities',\n message: `Entity \"${entityName}\" inherits BaseEntity but doesn't implement ITenantEntity`,\n file: path.relative(structure.root, file),\n suggestion: 'Add ITenantEntity interface for multi-tenant support, or use SystemEntity for platform-level entities',\n });\n }\n\n // Check for private constructor (DDD pattern)\n if (!content.includes(`private ${entityName}()`)) {\n result.warnings.push({\n type: 'warning',\n category: 'entities',\n message: `Entity \"${entityName}\" is missing private constructor for EF Core`,\n file: path.relative(structure.root, file),\n suggestion: `Add: private ${entityName}() { }`,\n });\n }\n\n // Check for factory method\n if (!content.includes(`public static ${entityName} Create(`)) {\n result.warnings.push({\n type: 'warning',\n category: 'entities',\n message: `Entity \"${entityName}\" is missing factory method`,\n file: path.relative(structure.root, file),\n suggestion: `Add factory method: public static ${entityName} Create(...)`,\n });\n }\n }\n}\n\nasync function validateTenantAwareness(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.domain) {\n result.warnings.push({\n type: 'warning',\n category: 'tenants',\n message: 'Domain project not found, skipping tenant validation',\n });\n return;\n }\n\n // Find entity files\n const entityFiles = await findFiles('**/*.cs', { cwd: structure.domain });\n\n let tenantAwareCount = 0;\n let systemEntityCount = 0;\n let ambiguousCount = 0;\n\n for (const file of entityFiles) {\n const content = await readText(file);\n\n // Check for class declaration with inheritance\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*([^{]+))?/);\n if (!classMatch) continue;\n\n const entityName = classMatch[1];\n const inheritance = classMatch[2]?.trim() || '';\n\n // Skip non-entity files\n if (!inheritance.includes('Entity') && !inheritance.includes('ITenant')) {\n continue;\n }\n\n const hasITenantEntity = inheritance.includes('ITenantEntity');\n const hasSystemEntity = inheritance.includes('SystemEntity');\n const hasTenantId = content.includes('TenantId');\n const hasTenantIdProperty = content.includes('public Guid TenantId') ||\n content.includes('public required Guid TenantId');\n\n // Check for ITenantEntity interface consistency\n if (hasITenantEntity) {\n tenantAwareCount++;\n\n if (!hasTenantIdProperty) {\n result.errors.push({\n type: 'error',\n category: 'tenants',\n message: `Entity \"${entityName}\" implements ITenantEntity but is missing TenantId property`,\n file: path.relative(structure.root, file),\n suggestion: 'Add: public Guid TenantId { get; private set; }',\n });\n }\n\n // Check Create method requires tenantId\n const createMethod = content.match(/public static \\w+ Create\\s*\\(([^)]*)\\)/);\n if (createMethod && !createMethod[1].includes('tenantId') && !createMethod[1].includes('TenantId')) {\n result.errors.push({\n type: 'error',\n category: 'tenants',\n message: `Entity \"${entityName}\" implements ITenantEntity but Create() doesn't require tenantId`,\n file: path.relative(structure.root, file),\n suggestion: 'Add tenantId as first parameter: Create(Guid tenantId, ...)',\n });\n }\n }\n\n // Check for SystemEntity consistency\n if (hasSystemEntity) {\n systemEntityCount++;\n\n if (hasTenantId) {\n result.errors.push({\n type: 'error',\n category: 'tenants',\n message: `System entity \"${entityName}\" should not have TenantId`,\n file: path.relative(structure.root, file),\n suggestion: 'Remove TenantId from system entities',\n });\n }\n }\n\n // Check for ambiguous tenant status\n if (!hasITenantEntity && !hasSystemEntity && hasTenantId) {\n ambiguousCount++;\n result.warnings.push({\n type: 'warning',\n category: 'tenants',\n message: `Entity \"${entityName}\" has TenantId but doesn't implement ITenantEntity`,\n file: path.relative(structure.root, file),\n suggestion: 'Add ITenantEntity interface for explicit tenant-awareness',\n });\n }\n }\n\n // Summary stats\n if (tenantAwareCount + systemEntityCount > 0) {\n result.warnings.push({\n type: 'warning',\n category: 'tenants',\n message: `Tenant summary: ${tenantAwareCount} tenant-aware, ${systemEntityCount} system, ${ambiguousCount} ambiguous`,\n });\n }\n}\n\nasync function validateControllerRoutes(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.api) {\n result.warnings.push({\n type: 'warning',\n category: 'controllers',\n message: 'API project not found, skipping controller route validation',\n });\n return;\n }\n\n // Find controller files\n const controllerFiles = await findFiles('**/Controllers/**/*Controller.cs', {\n cwd: structure.api,\n });\n\n // System controllers that intentionally use hardcoded routes\n // These are either auth-related, user-level, or support module APIs not in the navigation hierarchy\n const systemControllers = [\n // Auth controllers\n 'AuthController',\n 'RegistrationController',\n 'OnboardingController',\n 'NavigationController',\n 'LogsController',\n 'EntraController',\n // User-level controllers (not in navigation hierarchy)\n 'PreferencesController',\n 'ApplicationTrackingController',\n // Support module controllers (using api/support/* routes)\n 'NotificationsController',\n 'SlaController',\n 'TemplatesController',\n 'TicketsController',\n // DashboardController exists in both User and Support - both use hardcoded routes\n 'DashboardController',\n // Structure controllers (using api/structure/* routes - navigation paths don't exist yet)\n 'CostCentersController',\n 'OrganisationsController',\n 'OrganizationalDomainsController',\n // Business controllers (using api/business/* routes - navigation paths don't exist yet)\n 'MyTicketsController',\n ];\n\n let navRouteCount = 0;\n let hardcodedRouteCount = 0;\n let systemControllerCount = 0;\n\n for (const file of controllerFiles) {\n const content = await readText(file);\n const fileName = path.basename(file, '.cs');\n\n // Skip system controllers\n if (systemControllers.includes(fileName)) {\n systemControllerCount++;\n continue;\n }\n\n // Check for NavRoute attribute\n const hasNavRoute = content.includes('[NavRoute(');\n\n // Check for hardcoded Route attribute\n const hasHardcodedRoute = content.includes('[Route(\"api/[controller]\")]') ||\n content.includes('[Route(\"api/') ||\n /\\[Route\\s*\\(\\s*\"[^\"]+\"\\s*\\)\\]/.test(content);\n\n if (hasNavRoute) {\n navRouteCount++;\n\n // Validate NavRoute format\n const navRouteMatch = content.match(/\\[NavRoute\\s*\\(\\s*\"([^\"]+)\"(?:\\s*,\\s*Suffix\\s*=\\s*\"([^\"]+)\")?\\s*\\)\\]/);\n if (navRouteMatch) {\n const routePath = navRouteMatch[1];\n const parts = routePath.split('.');\n\n // Validate route has at least 2 parts (context.application or more)\n if (parts.length < 2) {\n result.warnings.push({\n type: 'warning',\n category: 'controllers',\n message: `Controller \"${fileName}\" has NavRoute with insufficient depth: \"${routePath}\"`,\n file: path.relative(structure.root, file),\n suggestion: 'NavRoute should have at least 2 levels: \"context.application\" (e.g., \"platform.administration\")',\n });\n }\n\n // Validate route parts are lowercase\n const hasUppercase = parts.some(part => part !== part.toLowerCase());\n if (hasUppercase) {\n result.errors.push({\n type: 'error',\n category: 'controllers',\n message: `Controller \"${fileName}\" has NavRoute with uppercase characters: \"${routePath}\"`,\n file: path.relative(structure.root, file),\n suggestion: 'NavRoute paths must be lowercase (e.g., \"platform.administration.users\")',\n });\n }\n }\n } else if (hasHardcodedRoute) {\n hardcodedRouteCount++;\n result.warnings.push({\n type: 'warning',\n category: 'controllers',\n message: `Controller \"${fileName}\" uses hardcoded Route instead of NavRoute`,\n file: path.relative(structure.root, file),\n suggestion: 'Use [NavRoute(\"context.application.module\")] for navigation-based routing',\n });\n }\n }\n\n // Summary stats\n const totalControllers = controllerFiles.length;\n const businessControllers = totalControllers - systemControllerCount;\n const navRoutePercentage = businessControllers > 0\n ? Math.round((navRouteCount / businessControllers) * 100)\n : 0;\n\n result.warnings.push({\n type: 'warning',\n category: 'controllers',\n message: `Route summary: ${navRouteCount}/${businessControllers} business controllers use NavRoute (${navRoutePercentage}%), ${systemControllerCount} system controllers excluded`,\n });\n\n // If less than 80% use NavRoute, add a warning\n if (navRoutePercentage < 80 && businessControllers > 0) {\n result.warnings.push({\n type: 'warning',\n category: 'controllers',\n message: `NavRoute adoption is below 80% (${navRoutePercentage}%). Consider migrating remaining controllers.`,\n });\n }\n}\n\nfunction generateSummary(result: ValidationResult, checks: string[]): string {\n const parts: string[] = [];\n\n parts.push(`Checks performed: ${checks.join(', ')}`);\n parts.push(`Errors: ${result.errors.length}`);\n parts.push(`Warnings: ${result.warnings.length}`);\n parts.push(`Status: ${result.valid ? 'PASSED' : 'FAILED'}`);\n\n return parts.join(' | ');\n}\n\nfunction formatResult(result: ValidationResult): string {\n const lines: string[] = [];\n\n lines.push('# Conventions Validation Report');\n lines.push('');\n lines.push(`## Summary`);\n lines.push(`- **Status**: ${result.valid ? '✅ PASSED' : '❌ FAILED'}`);\n lines.push(`- **Errors**: ${result.errors.length}`);\n lines.push(`- **Warnings**: ${result.warnings.length}`);\n lines.push('');\n\n if (result.errors.length > 0) {\n lines.push('## Errors');\n lines.push('');\n for (const error of result.errors) {\n lines.push(`### ❌ ${error.category}: ${error.message}`);\n if (error.file) lines.push(`- **File**: \\`${error.file}\\``);\n if (error.line) lines.push(`- **Line**: ${error.line}`);\n if (error.suggestion) lines.push(`- **Suggestion**: ${error.suggestion}`);\n lines.push('');\n }\n }\n\n if (result.warnings.length > 0) {\n lines.push('## Warnings');\n lines.push('');\n for (const warning of result.warnings) {\n lines.push(`### ⚠️ ${warning.category}: ${warning.message}`);\n if (warning.file) lines.push(`- **File**: \\`${warning.file}\\``);\n if (warning.suggestion) lines.push(`- **Suggestion**: ${warning.suggestion}`);\n lines.push('');\n }\n }\n\n if (result.errors.length === 0 && result.warnings.length === 0) {\n lines.push('## Result');\n lines.push('');\n lines.push('All conventions validated successfully! ✨');\n }\n\n return lines.join('\\n');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n CheckMigrationsInputSchema,\n type Config,\n type MigrationCheckResult,\n type MigrationInfo,\n} from '../types/index.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport { getCurrentBranch, branchExists, getFileFromBranch, getDiff } from '../utils/git.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const checkMigrationsTool: Tool = {\n name: 'check_migrations',\n description: 'Analyze EF Core migrations for conflicts, ordering issues, and ModelSnapshot discrepancies between branches',\n inputSchema: {\n type: 'object',\n properties: {\n projectPath: {\n type: 'string',\n description: 'EF Core project path (default: auto-detect from config)',\n },\n branch: {\n type: 'string',\n description: 'Git branch to check (default: current branch)',\n },\n compareBranch: {\n type: 'string',\n description: 'Branch to compare against (e.g., \"develop\")',\n },\n },\n },\n};\n\nexport async function handleCheckMigrations(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = CheckMigrationsInputSchema.parse(args);\n const projectPath = input.projectPath || config.smartstack.projectPath;\n\n logger.info('Checking migrations', { projectPath, branch: input.branch });\n\n const structure = await findSmartStackStructure(projectPath);\n\n if (!structure.migrations) {\n return '# Migration Check\\n\\n❌ No migrations folder found in the project.';\n }\n\n const result: MigrationCheckResult = {\n hasConflicts: false,\n migrations: [],\n conflicts: [],\n suggestions: [],\n };\n\n // Get current branch\n const currentBranch = input.branch || await getCurrentBranch(projectPath) || 'unknown';\n\n // Parse migrations\n result.migrations = await parseMigrations(structure.migrations, structure.root);\n\n // Check naming conventions\n checkNamingConventions(result, config);\n\n // Check chronological order\n checkChronologicalOrder(result);\n\n // If compare branch specified, check for conflicts\n if (input.compareBranch && await branchExists(input.compareBranch, projectPath)) {\n await checkBranchConflicts(\n result,\n structure,\n currentBranch,\n input.compareBranch,\n projectPath\n );\n }\n\n // Check ModelSnapshot\n await checkModelSnapshot(result, structure);\n\n // Update conflict status\n result.hasConflicts = result.conflicts.length > 0;\n\n // Generate suggestions\n generateSuggestions(result);\n\n return formatResult(result, currentBranch, input.compareBranch);\n}\n\nasync function parseMigrations(\n migrationsPath: string,\n rootPath: string\n): Promise<MigrationInfo[]> {\n const files = await findFiles('*.cs', { cwd: migrationsPath });\n const migrations: MigrationInfo[] = [];\n\n // Pattern: {context}_v{version}_{sequence}_{Description}.cs\n // Example: core_v1.0.0_001_CreateAuthUsers.cs\n const pattern = /^(\\w+)_v(\\d+\\.\\d+\\.\\d+)_(\\d{3})_(.+)\\.cs$/;\n\n for (const file of files) {\n const fileName = path.basename(file);\n\n // Skip designer and snapshot files\n if (fileName.includes('.Designer.') || fileName.includes('ModelSnapshot')) {\n continue;\n }\n\n const match = pattern.exec(fileName);\n\n if (match) {\n migrations.push({\n name: fileName.replace('.cs', ''),\n context: match[1], // DbContext (core, extensions, etc.)\n version: match[2], // Semver version (1.0.0, 1.2.0, etc.)\n sequence: match[3], // Sequence number (001, 002, etc.)\n description: match[4],\n file: path.relative(rootPath, file),\n applied: true, // We'd need DB connection to check this\n });\n } else {\n // Non-standard naming\n migrations.push({\n name: fileName.replace('.cs', ''),\n context: 'Unknown',\n version: '0.0.0',\n sequence: '000',\n description: fileName.replace('.cs', ''),\n file: path.relative(rootPath, file),\n applied: true,\n });\n }\n }\n\n // Sort by version then sequence\n return migrations.sort((a, b) => {\n // Compare versions using semver logic\n const versionCompare = compareVersions(a.version, b.version);\n if (versionCompare !== 0) return versionCompare;\n return a.sequence.localeCompare(b.sequence);\n });\n}\n\n/**\n * Parse a semver string into numeric parts\n * Returns [major, minor, patch] or null if invalid\n */\nfunction parseSemver(version: string): [number, number, number] | null {\n const match = version.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) {\n return null;\n }\n return [\n parseInt(match[1], 10),\n parseInt(match[2], 10),\n parseInt(match[3], 10),\n ];\n}\n\n/**\n * Compare two semver version strings\n * Returns: -1 if a < b, 0 if equal, 1 if a > b\n * Invalid versions are sorted to the end\n */\nfunction compareVersions(a: string, b: string): number {\n const partsA = parseSemver(a);\n const partsB = parseSemver(b);\n\n // Handle invalid versions - sort them to the end\n if (!partsA && !partsB) return 0;\n if (!partsA) return 1; // Invalid a goes after valid b\n if (!partsB) return -1; // Invalid b goes after valid a\n\n // Compare major.minor.patch\n for (let i = 0; i < 3; i++) {\n if (partsA[i] > partsB[i]) return 1;\n if (partsA[i] < partsB[i]) return -1;\n }\n return 0;\n}\n\nfunction checkNamingConventions(result: MigrationCheckResult, _config: Config): void {\n for (const migration of result.migrations) {\n if (migration.context === 'Unknown') {\n result.conflicts.push({\n type: 'naming',\n description: `Migration \"${migration.name}\" does not follow naming convention`,\n files: [migration.file],\n resolution: `Rename to format: {context}_v{version}_{sequence}_{Description} (e.g., core_v1.0.0_001_CreateAuthUsers)`,\n });\n }\n\n if (migration.version === '0.0.0') {\n result.conflicts.push({\n type: 'naming',\n description: `Migration \"${migration.name}\" missing version number`,\n files: [migration.file],\n resolution: `Use format: {context}_v{version}_{sequence}_{Description} where version is semver (1.0.0, 1.2.0, etc.)`,\n });\n }\n\n // Validate semver format\n if (migration.version !== '0.0.0' && !parseSemver(migration.version)) {\n result.conflicts.push({\n type: 'naming',\n description: `Migration \"${migration.name}\" has invalid version format: \"${migration.version}\"`,\n files: [migration.file],\n resolution: `Use semver format (major.minor.patch): 1.0.0, 1.2.0, 2.0.0, etc.`,\n });\n }\n }\n}\n\nfunction checkChronologicalOrder(result: MigrationCheckResult): void {\n const migrations = result.migrations.filter(m => m.context !== 'Unknown');\n\n for (let i = 1; i < migrations.length; i++) {\n const prev = migrations[i - 1];\n const curr = migrations[i];\n\n // Check if versions are in order (within same context)\n if (curr.context === prev.context) {\n const versionCompare = compareVersions(curr.version, prev.version);\n\n if (versionCompare < 0) {\n result.conflicts.push({\n type: 'order',\n description: `Migration \"${curr.name}\" (v${curr.version}) is versioned before \"${prev.name}\" (v${prev.version})`,\n files: [curr.file, prev.file],\n resolution: 'Reorder migrations or update version numbers',\n });\n }\n\n // Check for duplicate version with same sequence\n if (curr.version === prev.version && curr.sequence === prev.sequence) {\n result.conflicts.push({\n type: 'order',\n description: `Migrations \"${curr.name}\" and \"${prev.name}\" have same version and sequence`,\n files: [curr.file, prev.file],\n resolution: 'Use different sequence numbers (001, 002, etc.) for migrations in the same version',\n });\n }\n }\n }\n}\n\nasync function checkBranchConflicts(\n result: MigrationCheckResult,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n currentBranch: string,\n compareBranch: string,\n projectPath: string\n): Promise<void> {\n if (!structure.migrations) return;\n\n const migrationsRelPath = path.relative(projectPath, structure.migrations).replace(/\\\\/g, '/');\n\n // Get ModelSnapshot from both branches\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\n\n if (snapshotFiles.length > 0) {\n const snapshotRelPath = path.relative(projectPath, snapshotFiles[0]).replace(/\\\\/g, '/');\n\n const currentSnapshot = await readText(snapshotFiles[0]);\n const compareSnapshot = await getFileFromBranch(compareBranch, snapshotRelPath, projectPath);\n\n if (compareSnapshot && currentSnapshot !== compareSnapshot) {\n // Check if there are actual model differences\n const diff = await getDiff(compareBranch, currentBranch, snapshotRelPath, projectPath);\n\n if (diff) {\n result.conflicts.push({\n type: 'snapshot',\n description: `ModelSnapshot differs between \"${currentBranch}\" and \"${compareBranch}\"`,\n files: [snapshotRelPath],\n resolution: 'Rebase on target branch and regenerate migrations with: dotnet ef migrations add <Name>',\n });\n }\n }\n }\n\n // Check for migrations that exist in compare branch but not current\n const compareMigrations = await getFileFromBranch(\n compareBranch,\n migrationsRelPath,\n projectPath\n );\n\n if (compareMigrations) {\n // This would need more sophisticated parsing\n // For now, just note that comparison was done\n logger.debug('Branch comparison completed', { compareBranch });\n }\n}\n\nasync function checkModelSnapshot(\n result: MigrationCheckResult,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\n): Promise<void> {\n if (!structure.migrations) return;\n\n const snapshotFiles = await findFiles('*ModelSnapshot.cs', { cwd: structure.migrations });\n\n if (snapshotFiles.length === 0) {\n result.conflicts.push({\n type: 'snapshot',\n description: 'No ModelSnapshot file found',\n files: [],\n resolution: 'Run: dotnet ef migrations add InitialCreate',\n });\n return;\n }\n\n if (snapshotFiles.length > 1) {\n result.conflicts.push({\n type: 'snapshot',\n description: 'Multiple ModelSnapshot files found',\n files: snapshotFiles.map(f => path.relative(structure.root, f)),\n resolution: 'Remove duplicate snapshots, keep only one per DbContext',\n });\n }\n\n // Check if snapshot references all migrations\n const snapshotContent = await readText(snapshotFiles[0]);\n\n for (const migration of result.migrations) {\n if (migration.context !== 'Unknown' && !snapshotContent.includes(migration.name)) {\n result.conflicts.push({\n type: 'dependency',\n description: `Migration \"${migration.name}\" not referenced in ModelSnapshot`,\n files: [migration.file],\n resolution: 'Migration may not be applied. Run: dotnet ef database update',\n });\n }\n }\n}\n\nfunction generateSuggestions(result: MigrationCheckResult): void {\n if (result.conflicts.some(c => c.type === 'snapshot')) {\n result.suggestions.push(\n 'Consider rebasing on the target branch before merging to avoid snapshot conflicts'\n );\n }\n\n if (result.conflicts.some(c => c.type === 'naming')) {\n result.suggestions.push(\n 'Use convention: {context}_v{version}_{sequence}_{Description} for migration naming (e.g., core_v1.0.0_001_CreateAuthUsers)'\n );\n }\n\n if (result.conflicts.some(c => c.type === 'order')) {\n result.suggestions.push(\n 'Ensure migrations are created in version order to avoid conflicts'\n );\n }\n\n if (result.migrations.length > 20) {\n result.suggestions.push(\n 'Consider squashing old migrations to reduce complexity. Use: /efcore squash'\n );\n }\n}\n\nfunction formatResult(\n result: MigrationCheckResult,\n currentBranch: string,\n compareBranch?: string\n): string {\n const lines: string[] = [];\n\n lines.push('# EF Core Migration Check Report');\n lines.push('');\n lines.push('## Overview');\n lines.push(`- **Current Branch**: ${currentBranch}`);\n if (compareBranch) {\n lines.push(`- **Compare Branch**: ${compareBranch}`);\n }\n lines.push(`- **Total Migrations**: ${result.migrations.length}`);\n lines.push(`- **Conflicts Found**: ${result.conflicts.length}`);\n lines.push(`- **Status**: ${result.hasConflicts ? '❌ CONFLICTS DETECTED' : '✅ OK'}`);\n lines.push('');\n\n // Migrations list\n lines.push('## Migrations');\n lines.push('');\n lines.push('| Name | Context | Version | Sequence | Description |');\n lines.push('|------|---------|---------|----------|-------------|');\n\n for (const migration of result.migrations) {\n lines.push(\n `| ${migration.name} | ${migration.context} | ${migration.version} | ${migration.sequence} | ${migration.description} |`\n );\n }\n lines.push('');\n\n // Conflicts\n if (result.conflicts.length > 0) {\n lines.push('## Conflicts');\n lines.push('');\n\n for (const conflict of result.conflicts) {\n const icon = conflict.type === 'snapshot' ? '🔄' :\n conflict.type === 'order' ? '📅' :\n conflict.type === 'naming' ? '📝' : '⚠️';\n\n lines.push(`### ${icon} ${conflict.type.toUpperCase()}: ${conflict.description}`);\n if (conflict.files.length > 0) {\n lines.push(`- **Files**: ${conflict.files.map(f => `\\`${f}\\``).join(', ')}`);\n }\n lines.push(`- **Resolution**: ${conflict.resolution}`);\n lines.push('');\n }\n }\n\n // Suggestions\n if (result.suggestions.length > 0) {\n lines.push('## Suggestions');\n lines.push('');\n for (const suggestion of result.suggestions) {\n lines.push(`- 💡 ${suggestion}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport Handlebars from 'handlebars';\nimport {\n ScaffoldExtensionInputSchema,\n type Config,\n type ScaffoldResult,\n} from '../types/index.js';\nimport { writeText, ensureDirectory, validatePathSecurity } from '../utils/fs.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const scaffoldExtensionTool: Tool = {\n name: 'scaffold_extension',\n description: 'Generate code to extend SmartStack: feature (full-stack), entity, service, controller, component, dto, validator, repository, or test',\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['feature', 'service', 'entity', 'controller', 'component', 'test', 'dto', 'validator', 'repository'],\n description: 'Type of extension to scaffold. Use \"feature\" for full-stack generation.',\n },\n name: {\n type: 'string',\n description: 'Name of the extension (e.g., \"UserProfile\", \"Order\")',\n },\n options: {\n type: 'object',\n properties: {\n namespace: {\n type: 'string',\n description: 'Custom namespace (optional)',\n },\n baseEntity: {\n type: 'string',\n description: 'Base entity to extend (for entity type)',\n },\n methods: {\n type: 'array',\n items: { type: 'string' },\n description: 'Methods to generate (for service type)',\n },\n outputPath: {\n type: 'string',\n description: 'Custom output path',\n },\n isSystemEntity: {\n type: 'boolean',\n description: 'If true, creates a system entity without TenantId (for entity type)',\n },\n tablePrefix: {\n type: 'string',\n description: 'Domain prefix for table name (e.g., \"auth_\", \"nav_\", \"cfg_\")',\n },\n schema: {\n type: 'string',\n enum: ['core', 'extensions'],\n description: 'Database schema (default: core)',\n },\n dryRun: {\n type: 'boolean',\n description: 'If true, preview generated code without writing files',\n },\n skipService: {\n type: 'boolean',\n description: 'For feature type: skip service generation',\n },\n skipController: {\n type: 'boolean',\n description: 'For feature type: skip controller generation',\n },\n skipComponent: {\n type: 'boolean',\n description: 'For feature type: skip React component generation',\n },\n clientExtension: {\n type: 'boolean',\n description: 'If true, use extensions schema for client-specific code',\n },\n withTests: {\n type: 'boolean',\n description: 'For feature type: also generate unit tests',\n },\n withDtos: {\n type: 'boolean',\n description: 'For feature type: generate DTOs (Create, Update, Response)',\n },\n withValidation: {\n type: 'boolean',\n description: 'For feature type: generate FluentValidation validators',\n },\n withRepository: {\n type: 'boolean',\n description: 'For feature type: generate repository pattern',\n },\n entityProperties: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n type: { type: 'string' },\n required: { type: 'boolean' },\n maxLength: { type: 'number' },\n },\n },\n description: 'Entity properties for DTO/Validator generation',\n },\n navRoute: {\n type: 'string',\n description: 'Navigation route path for controller (e.g., \"platform.administration.users\"). Required for controllers.',\n },\n navRouteSuffix: {\n type: 'string',\n description: 'Optional suffix for NavRoute (e.g., \"dashboard\" for sub-resources)',\n },\n },\n },\n },\n required: ['type', 'name'],\n },\n};\n\n// Register Handlebars helpers\nHandlebars.registerHelper('pascalCase', (str: string) => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n});\n\nHandlebars.registerHelper('camelCase', (str: string) => {\n return str.charAt(0).toLowerCase() + str.slice(1);\n});\n\nHandlebars.registerHelper('kebabCase', (str: string) => {\n return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();\n});\n\nexport async function handleScaffoldExtension(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ScaffoldExtensionInputSchema.parse(args);\n const dryRun = input.options?.dryRun || false;\n\n logger.info('Scaffolding extension', { type: input.type, name: input.name, dryRun });\n\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n const result: ScaffoldResult = {\n success: true,\n files: [],\n instructions: [],\n };\n\n // Handle clientExtension option - override schema\n if (input.options?.clientExtension) {\n input.options.schema = 'extensions';\n input.options.tablePrefix = input.options.tablePrefix || 'ext_';\n }\n\n try {\n switch (input.type) {\n case 'feature':\n await scaffoldFeature(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'service':\n await scaffoldService(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'entity':\n await scaffoldEntity(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'controller':\n await scaffoldController(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'component':\n await scaffoldComponent(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'test':\n await scaffoldTest(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'dto':\n await scaffoldDtos(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'validator':\n await scaffoldValidator(input.name, input.options, structure, config, result, dryRun);\n break;\n case 'repository':\n await scaffoldRepository(input.name, input.options, structure, config, result, dryRun);\n break;\n }\n } catch (error) {\n result.success = false;\n result.instructions.push(`Error: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n\n return formatResult(result, input.type, input.name, dryRun);\n}\n\n// Entity property definition for DTO/Validator generation\ninterface EntityProperty {\n name: string;\n type: string;\n required?: boolean;\n maxLength?: number;\n}\n\n// Define extended options type for feature scaffolding\ninterface FeatureOptions {\n namespace?: string;\n baseEntity?: string;\n methods?: string[];\n outputPath?: string;\n isSystemEntity?: boolean;\n tablePrefix?: string;\n schema?: 'core' | 'extensions';\n dryRun?: boolean;\n skipService?: boolean;\n skipController?: boolean;\n skipComponent?: boolean;\n clientExtension?: boolean;\n withTests?: boolean;\n withDtos?: boolean;\n withValidation?: boolean;\n withRepository?: boolean;\n entityProperties?: EntityProperty[];\n navRoute?: string;\n navRouteSuffix?: string;\n}\n\nasync function scaffoldFeature(\n name: string,\n options: FeatureOptions | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const skipService = options?.skipService || false;\n const skipController = options?.skipController || false;\n const skipComponent = options?.skipComponent || false;\n const isClientExtension = options?.clientExtension || false;\n const withTests = options?.withTests || false;\n const withDtos = options?.withDtos || false;\n const withValidation = options?.withValidation || false;\n const withRepository = options?.withRepository || false;\n\n let stepNumber = 1;\n\n // Add feature header to instructions\n result.instructions.push(`# Full-Stack Feature: ${name}`);\n result.instructions.push('');\n if (isClientExtension) {\n result.instructions.push('> **Client Extension**: Using `extensions` schema and `ext_` prefix');\n result.instructions.push('');\n }\n\n // 1. Always generate entity (it's the foundation)\n result.instructions.push(`## ${stepNumber}. Domain Entity`);\n await scaffoldEntity(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n\n // 2. Generate DTOs (if requested)\n if (withDtos) {\n result.instructions.push(`## ${stepNumber}. DTOs (Data Transfer Objects)`);\n await scaffoldDtos(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 3. Generate validators (if requested)\n if (withValidation) {\n result.instructions.push(`## ${stepNumber}. FluentValidation Validators`);\n await scaffoldValidator(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 4. Generate repository (if requested)\n if (withRepository) {\n result.instructions.push(`## ${stepNumber}. Repository Pattern`);\n await scaffoldRepository(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 5. Generate service (unless skipped)\n if (!skipService) {\n result.instructions.push(`## ${stepNumber}. Application Service`);\n // Create service with entity-aware methods\n const serviceMethods = [\n `GetByIdAsync`,\n `GetAllAsync`,\n `CreateAsync`,\n `UpdateAsync`,\n `DeleteAsync`,\n ];\n await scaffoldService(name, { ...options, methods: serviceMethods }, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 6. Generate controller (unless skipped)\n if (!skipController) {\n result.instructions.push(`## ${stepNumber}. API Controller`);\n await scaffoldController(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 7. Generate component (unless skipped)\n if (!skipComponent) {\n result.instructions.push(`## ${stepNumber}. React Component`);\n await scaffoldComponent(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n stepNumber++;\n }\n\n // 8. Generate tests (if requested)\n if (withTests && !skipService) {\n result.instructions.push(`## ${stepNumber}. Unit Tests`);\n await scaffoldTest(name, options, structure, config, result, dryRun);\n result.instructions.push('');\n }\n\n // Add summary\n const generated: string[] = ['Entity'];\n if (withDtos) generated.push('DTOs');\n if (withValidation) generated.push('Validators');\n if (withRepository) generated.push('Repository');\n if (!skipService) generated.push('Service');\n if (!skipController) generated.push('Controller');\n if (!skipComponent) generated.push('Component');\n if (withTests && !skipService) generated.push('Tests');\n\n result.instructions.push('---');\n result.instructions.push(`## Summary: Generated ${generated.join(' + ')}`);\n result.instructions.push('');\n result.instructions.push('### Next Steps:');\n result.instructions.push(`1. Add DbSet to ApplicationDbContext: \\`public DbSet<${name}> ${name}s => Set<${name}>();\\``);\n if (withRepository) {\n result.instructions.push(`2. Register repository: \\`services.AddScoped<I${name}Repository, ${name}Repository>();\\``);\n }\n result.instructions.push(`${withRepository ? '3' : '2'}. Register service: \\`services.AddScoped<I${name}Service, ${name}Service>();\\``);\n if (withValidation) {\n result.instructions.push(`${withRepository ? '4' : '3'}. Register validators: \\`services.AddValidatorsFromAssemblyContaining<Create${name}DtoValidator>();\\``);\n }\n result.instructions.push(`${withRepository ? (withValidation ? '5' : '4') : (withValidation ? '4' : '3')}. Create migration: \\`dotnet ef migrations add ${options?.tablePrefix || 'ref_'}vX.X.X_XXX_Add${name}\\``);\n result.instructions.push(`${withRepository ? (withValidation ? '6' : '5') : (withValidation ? '5' : '4')}. Run migration: \\`dotnet ef database update\\``);\n if (!skipComponent) {\n result.instructions.push(`Import component: \\`import { ${name} } from './components/${name}';\\``);\n }\n}\n\nasync function scaffoldService(\n name: string,\n options: { namespace?: string; methods?: string[]; dryRun?: boolean } | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const namespace = options?.namespace || `${config.conventions.namespaces.application}.Services`;\n const methods = options?.methods || ['GetByIdAsync', 'GetAllAsync', 'CreateAsync', 'UpdateAsync', 'DeleteAsync'];\n\n // Interface template\n const interfaceTemplate = `using System.Threading;\nusing System.Threading.Tasks;\nusing System.Collections.Generic;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// Service interface for {{name}} operations\n/// </summary>\npublic interface I{{name}}Service\n{\n{{#each methods}}\n /// <summary>\n /// {{this}} operation\n /// </summary>\n Task<object> {{this}}(CancellationToken cancellationToken = default);\n\n{{/each}}\n}\n`;\n\n // Implementation template\n const implementationTemplate = `using System.Threading;\nusing System.Threading.Tasks;\nusing System.Collections.Generic;\nusing Microsoft.Extensions.Logging;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// Service implementation for {{name}} operations\n/// </summary>\npublic class {{name}}Service : I{{name}}Service\n{\n private readonly ILogger<{{name}}Service> _logger;\n\n public {{name}}Service(ILogger<{{name}}Service> logger)\n {\n _logger = logger;\n }\n\n{{#each methods}}\n /// <inheritdoc />\n public async Task<object> {{this}}(CancellationToken cancellationToken = default)\n {\n _logger.LogInformation(\"Executing {{this}}\");\n // TODO: Implement {{this}}\n await Task.CompletedTask;\n throw new NotImplementedException();\n }\n\n{{/each}}\n}\n`;\n\n // DI registration template\n const diTemplate = `// Add to DependencyInjection.cs or ServiceCollectionExtensions.cs:\nservices.AddScoped<I{{name}}Service, {{name}}Service>();\n`;\n\n const context = { namespace, name, methods };\n\n const interfaceContent = Handlebars.compile(interfaceTemplate)(context);\n const implementationContent = Handlebars.compile(implementationTemplate)(context);\n const diContent = Handlebars.compile(diTemplate)(context);\n\n // Determine output paths\n const projectRoot = config.smartstack.projectPath;\n const basePath = structure.application || projectRoot;\n const servicesPath = path.join(basePath, 'Services');\n\n const interfacePath = path.join(servicesPath, `I${name}Service.cs`);\n const implementationPath = path.join(servicesPath, `${name}Service.cs`);\n\n // Validate paths don't escape project directory\n validatePathSecurity(interfacePath, projectRoot);\n validatePathSecurity(implementationPath, projectRoot);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(servicesPath);\n await writeText(interfacePath, interfaceContent);\n await writeText(implementationPath, implementationContent);\n }\n\n result.files.push({ path: interfacePath, content: interfaceContent, type: 'created' });\n result.files.push({ path: implementationPath, content: implementationContent, type: 'created' });\n\n result.instructions.push('Register service in DI container:');\n result.instructions.push(diContent);\n}\n\nasync function scaffoldEntity(\n name: string,\n options: { namespace?: string; baseEntity?: string; isSystemEntity?: boolean; tablePrefix?: string; schema?: string; dryRun?: boolean } | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const namespace = options?.namespace || config.conventions.namespaces.domain;\n const baseEntity = options?.baseEntity;\n const isSystemEntity = options?.isSystemEntity || false;\n const tablePrefix = options?.tablePrefix || 'ref_';\n const schema = options?.schema || config.conventions.schemas.platform;\n\n // Entity template with full conventions (TenantId, Code, SoftDelete, RowVersion)\n // Default is tenant-aware (ITenantEntity), use isSystemEntity: true for platform-level entities\n const entityTemplate = `using System;\nusing SmartStack.Domain.Common;\nusing SmartStack.Domain.Common.Interfaces;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// {{name}} entity{{#if baseEntity}} extending {{baseEntity}}{{/if}}\n{{#unless isSystemEntity}}\n/// Tenant-scoped: data is isolated per tenant\n{{else}}\n/// System entity: platform-level, no tenant isolation\n{{/unless}}\n/// </summary>\n{{#if isSystemEntity}}\npublic class {{name}} : SystemEntity\n{{else}}\npublic class {{name}} : BaseEntity, ITenantEntity\n{{/if}}\n{\n{{#unless isSystemEntity}}\n // === MULTI-TENANT ===\n\n /// <summary>\n /// Tenant identifier for multi-tenant isolation (required)\n /// </summary>\n public Guid TenantId { get; private set; }\n\n{{/unless}}\n{{#if baseEntity}}\n // === RELATIONSHIPS ===\n\n /// <summary>\n /// Foreign key to {{baseEntity}}\n /// </summary>\n public Guid {{baseEntity}}Id { get; private set; }\n\n /// <summary>\n /// Navigation property to {{baseEntity}}\n /// </summary>\n public virtual {{baseEntity}}? {{baseEntity}} { get; private set; }\n\n{{/if}}\n // === BUSINESS PROPERTIES ===\n // TODO: Add {{name}} specific properties here\n\n /// <summary>\n /// Private constructor for EF Core\n /// </summary>\n private {{name}}() { }\n\n /// <summary>\n /// Factory method to create a new {{name}}\n /// </summary>\n{{#if isSystemEntity}}\n public static {{name}} Create(\n string code,\n string? createdBy = null)\n {\n return new {{name}}\n {\n Id = Guid.NewGuid(),\n Code = code.ToLowerInvariant(),\n CreatedAt = DateTime.UtcNow,\n CreatedBy = createdBy\n };\n }\n{{else}}\n /// <param name=\"tenantId\">Required tenant identifier</param>\n /// <param name=\"code\">Unique code within tenant (will be lowercased)</param>\n /// <param name=\"createdBy\">User who created this entity</param>\n public static {{name}} Create(\n Guid tenantId,\n string code,\n string? createdBy = null)\n {\n if (tenantId == Guid.Empty)\n throw new ArgumentException(\"TenantId is required\", nameof(tenantId));\n\n return new {{name}}\n {\n Id = Guid.NewGuid(),\n TenantId = tenantId,\n Code = code.ToLowerInvariant(),\n CreatedAt = DateTime.UtcNow,\n CreatedBy = createdBy\n };\n }\n{{/if}}\n\n /// <summary>\n /// Update the entity\n /// </summary>\n public void Update(string? updatedBy = null)\n {\n UpdatedAt = DateTime.UtcNow;\n UpdatedBy = updatedBy;\n }\n\n /// <summary>\n /// Soft delete the entity\n /// </summary>\n public void SoftDelete(string? deletedBy = null)\n {\n IsDeleted = true;\n DeletedAt = DateTime.UtcNow;\n DeletedBy = deletedBy;\n }\n\n /// <summary>\n /// Restore a soft-deleted entity\n /// </summary>\n public void Restore(string? restoredBy = null)\n {\n IsDeleted = false;\n DeletedAt = null;\n DeletedBy = null;\n UpdatedAt = DateTime.UtcNow;\n UpdatedBy = restoredBy;\n }\n}\n`;\n\n // EF Configuration template with full conventions\n const configTemplate = `using Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Metadata.Builders;\nusing {{domainNamespace}};\n\nnamespace {{infrastructureNamespace}}.Persistence.Configurations;\n\n/// <summary>\n/// EF Core configuration for {{name}}\n{{#unless isSystemEntity}}\n/// Tenant-aware: includes tenant isolation query filter\n{{else}}\n/// System entity: no tenant isolation\n{{/unless}}\n/// </summary>\npublic class {{name}}Configuration : IEntityTypeConfiguration<{{name}}>\n{\n public void Configure(EntityTypeBuilder<{{name}}> builder)\n {\n // Table name with schema and domain prefix\n builder.ToTable(\"{{tablePrefix}}{{name}}s\", \"{{schema}}\");\n\n // Primary key\n builder.HasKey(e => e.Id);\n\n{{#unless isSystemEntity}}\n // ============================================\n // MULTI-TENANT CONFIGURATION\n // ============================================\n\n // TenantId is required for tenant isolation\n builder.Property(e => e.TenantId).IsRequired();\n builder.HasIndex(e => e.TenantId)\n .HasDatabaseName(\"IX_{{tablePrefix}}{{name}}s_TenantId\");\n\n // Tenant relationship (configured in Tenant configuration)\n // builder.HasOne<Tenant>().WithMany().HasForeignKey(e => e.TenantId);\n\n // Code: lowercase, unique per tenant (filtered for soft delete)\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\n builder.HasIndex(e => new { e.TenantId, e.Code })\n .IsUnique()\n .HasFilter(\"[IsDeleted] = 0\")\n .HasDatabaseName(\"IX_{{tablePrefix}}{{name}}s_Tenant_Code_Unique\");\n{{else}}\n // Code: lowercase, unique globally (filtered for soft delete)\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\n builder.HasIndex(e => e.Code)\n .IsUnique()\n .HasFilter(\"[IsDeleted] = 0\")\n .HasDatabaseName(\"IX_{{tablePrefix}}{{name}}s_Code_Unique\");\n{{/unless}}\n\n // Concurrency token\n builder.Property(e => e.RowVersion).IsRowVersion();\n\n // Audit fields\n builder.Property(e => e.CreatedBy).HasMaxLength(256);\n builder.Property(e => e.UpdatedBy).HasMaxLength(256);\n builder.Property(e => e.DeletedBy).HasMaxLength(256);\n\n{{#if baseEntity}}\n // ============================================\n // RELATIONSHIPS\n // ============================================\n\n // Relationship to {{baseEntity}} (1:1)\n builder.HasOne(e => e.{{baseEntity}})\n .WithOne()\n .HasForeignKey<{{name}}>(e => e.{{baseEntity}}Id)\n .OnDelete(DeleteBehavior.Cascade);\n\n // Index on foreign key\n builder.HasIndex(e => e.{{baseEntity}}Id)\n .IsUnique();\n{{/if}}\n\n // ============================================\n // QUERY FILTERS\n // ============================================\n // Note: Global query filters are applied in DbContext.OnModelCreating\n // - Soft delete: .HasQueryFilter(e => !e.IsDeleted)\n{{#unless isSystemEntity}}\n // - Tenant isolation: .HasQueryFilter(e => e.TenantId == _tenantId)\n // Combined filter applied via ITenantEntity interface check\n{{/unless}}\n\n // TODO: Add additional business-specific configuration\n }\n}\n`;\n\n const context = {\n namespace,\n name,\n baseEntity,\n isSystemEntity,\n tablePrefix,\n schema,\n infrastructureNamespace: config.conventions.namespaces.infrastructure,\n domainNamespace: config.conventions.namespaces.domain,\n };\n\n const entityContent = Handlebars.compile(entityTemplate)(context);\n const configContent = Handlebars.compile(configTemplate)(context);\n\n // Determine output paths\n const projectRoot = config.smartstack.projectPath;\n const domainPath = structure.domain || path.join(projectRoot, 'Domain');\n const infraPath = structure.infrastructure || path.join(projectRoot, 'Infrastructure');\n\n const entityFilePath = path.join(domainPath, `${name}.cs`);\n const configFilePath = path.join(infraPath, 'Persistence', 'Configurations', `${name}Configuration.cs`);\n\n // Validate paths don't escape project directory\n validatePathSecurity(entityFilePath, projectRoot);\n validatePathSecurity(configFilePath, projectRoot);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(domainPath);\n await ensureDirectory(path.join(infraPath, 'Persistence', 'Configurations'));\n await writeText(entityFilePath, entityContent);\n await writeText(configFilePath, configContent);\n }\n\n result.files.push({ path: entityFilePath, content: entityContent, type: 'created' });\n result.files.push({ path: configFilePath, content: configContent, type: 'created' });\n\n result.instructions.push(`Add DbSet to ApplicationDbContext:`);\n result.instructions.push(`public DbSet<${name}> ${name}s => Set<${name}>();`);\n result.instructions.push('');\n result.instructions.push('Create migration:');\n result.instructions.push(`dotnet ef migrations add core_vX.X.X_XXX_Add${name} --context ApplicationDbContext`);\n result.instructions.push('');\n result.instructions.push('Required fields from BaseEntity:');\n result.instructions.push(`- Id (Guid), ${isSystemEntity ? '' : 'TenantId (Guid), '}Code (string, lowercase)`);\n result.instructions.push('- CreatedAt, UpdatedAt, CreatedBy, UpdatedBy (audit)');\n result.instructions.push('- IsDeleted, DeletedAt, DeletedBy (soft delete)');\n result.instructions.push('- RowVersion (concurrency)');\n}\n\nasync function scaffoldController(\n name: string,\n options: { namespace?: string; dryRun?: boolean; navRoute?: string; navRouteSuffix?: string } | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const namespace = options?.namespace || `${config.conventions.namespaces.api}.Controllers`;\n const navRoute = options?.navRoute;\n const navRouteSuffix = options?.navRouteSuffix;\n\n // Determine route attribute based on navRoute option\n const routeAttribute = navRoute\n ? navRouteSuffix\n ? `[NavRoute(\"${navRoute}\", Suffix = \"${navRouteSuffix}\")]`\n : `[NavRoute(\"${navRoute}\")]`\n : `[Route(\"api/[controller]\")]`;\n\n // Add using for NavRoute if used\n const navRouteUsing = navRoute ? 'using SmartStack.Api.Core.Routing;\\n' : '';\n\n const controllerTemplate = `using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Logging;\n${navRouteUsing}\nnamespace {{namespace}};\n\n/// <summary>\n/// API controller for {{name}} operations\n/// </summary>\n[ApiController]\n{{routeAttribute}}\n[Authorize]\npublic class {{name}}Controller : ControllerBase\n{\n private readonly ILogger<{{name}}Controller> _logger;\n\n public {{name}}Controller(ILogger<{{name}}Controller> logger)\n {\n _logger = logger;\n }\n\n /// <summary>\n /// Get all {{nameLower}}s\n /// </summary>\n [HttpGet]\n public async Task<ActionResult<IEnumerable<{{name}}Dto>>> GetAll()\n {\n _logger.LogInformation(\"Getting all {{nameLower}}s\");\n // TODO: Implement\n return Ok(Array.Empty<{{name}}Dto>());\n }\n\n /// <summary>\n /// Get {{nameLower}} by ID\n /// </summary>\n [HttpGet(\"{id:guid}\")]\n public async Task<ActionResult<{{name}}Dto>> GetById(Guid id)\n {\n _logger.LogInformation(\"Getting {{nameLower}} {Id}\", id);\n // TODO: Implement\n return NotFound();\n }\n\n /// <summary>\n /// Create new {{nameLower}}\n /// </summary>\n [HttpPost]\n public async Task<ActionResult<{{name}}Dto>> Create([FromBody] Create{{name}}Request request)\n {\n _logger.LogInformation(\"Creating {{nameLower}}\");\n // TODO: Implement\n return CreatedAtAction(nameof(GetById), new { id = Guid.NewGuid() }, null);\n }\n\n /// <summary>\n /// Update {{nameLower}}\n /// </summary>\n [HttpPut(\"{id:guid}\")]\n public async Task<ActionResult> Update(Guid id, [FromBody] Update{{name}}Request request)\n {\n _logger.LogInformation(\"Updating {{nameLower}} {Id}\", id);\n // TODO: Implement\n return NoContent();\n }\n\n /// <summary>\n /// Delete {{nameLower}}\n /// </summary>\n [HttpDelete(\"{id:guid}\")]\n public async Task<ActionResult> Delete(Guid id)\n {\n _logger.LogInformation(\"Deleting {{nameLower}} {Id}\", id);\n // TODO: Implement\n return NoContent();\n }\n}\n\n// DTOs\npublic record {{name}}Dto(Guid Id, DateTime CreatedAt);\npublic record Create{{name}}Request();\npublic record Update{{name}}Request();\n`;\n\n const context = {\n namespace,\n name,\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\n routeAttribute,\n };\n\n const controllerContent = Handlebars.compile(controllerTemplate)(context);\n\n const projectRoot = config.smartstack.projectPath;\n const apiPath = structure.api || path.join(projectRoot, 'Api');\n const controllersPath = path.join(apiPath, 'Controllers');\n\n const controllerFilePath = path.join(controllersPath, `${name}Controller.cs`);\n\n // Validate paths don't escape project directory\n validatePathSecurity(controllerFilePath, projectRoot);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(controllersPath);\n await writeText(controllerFilePath, controllerContent);\n }\n\n result.files.push({ path: controllerFilePath, content: controllerContent, type: 'created' });\n\n // Show appropriate route info based on NavRoute or traditional route\n if (navRoute) {\n result.instructions.push('Controller created with NavRoute (Navigation-based routing).');\n result.instructions.push(`NavRoute: ${navRoute}${navRouteSuffix ? ` (Suffix: ${navRouteSuffix})` : ''}`);\n result.instructions.push('');\n result.instructions.push('The actual API route will be resolved from Navigation entities at startup.');\n result.instructions.push('Ensure the navigation path exists in the database:');\n result.instructions.push(` Context > Application > Module > Section matching \"${navRoute}\"`);\n } else {\n result.instructions.push('Controller created with traditional routing.');\n result.instructions.push('');\n result.instructions.push('⚠️ Consider using NavRoute for navigation-based routing:');\n result.instructions.push(` [NavRoute(\"context.application.module\")]`);\n result.instructions.push('');\n result.instructions.push('API endpoints (with traditional routing):');\n result.instructions.push(` GET /api/${name.toLowerCase()}`);\n result.instructions.push(` GET /api/${name.toLowerCase()}/{id}`);\n result.instructions.push(` POST /api/${name.toLowerCase()}`);\n result.instructions.push(` PUT /api/${name.toLowerCase()}/{id}`);\n result.instructions.push(` DELETE /api/${name.toLowerCase()}/{id}`);\n }\n}\n\nasync function scaffoldComponent(\n name: string,\n options: { namespace?: string; outputPath?: string; dryRun?: boolean } | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const componentTemplate = `import React, { useState, useEffect } from 'react';\n\ninterface {{name}}Props {\n id?: string;\n onSave?: (data: {{name}}Data) => void;\n onCancel?: () => void;\n}\n\ninterface {{name}}Data {\n id?: string;\n // TODO: Add {{name}} data properties\n}\n\n/**\n * {{name}} component\n */\nexport const {{name}}: React.FC<{{name}}Props> = ({ id, onSave, onCancel }) => {\n const [data, setData] = useState<{{name}}Data | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (id) {\n // TODO: Fetch {{nameLower}} data\n setLoading(true);\n // fetch...\n setLoading(false);\n }\n }, [id]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (data && onSave) {\n onSave(data);\n }\n };\n\n if (loading) {\n return <div className=\"animate-pulse\">Loading...</div>;\n }\n\n if (error) {\n return <div className=\"text-red-500\">{error}</div>;\n }\n\n return (\n <div className=\"p-4\">\n <h2 className=\"text-xl font-semibold mb-4\">{{name}}</h2>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {/* TODO: Add form fields */}\n <div className=\"flex gap-2\">\n <button\n type=\"submit\"\n className=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\"\n >\n Save\n </button>\n {onCancel && (\n <button\n type=\"button\"\n onClick={onCancel}\n className=\"px-4 py-2 bg-gray-200 rounded hover:bg-gray-300\"\n >\n Cancel\n </button>\n )}\n </div>\n </form>\n </div>\n );\n};\n\nexport default {{name}};\n`;\n\n // Hook template\n const hookTemplate = `import { useState, useEffect, useCallback } from 'react';\nimport { {{nameLower}}Api } from '../services/api/{{nameLower}}';\n\ninterface {{name}}Data {\n id?: string;\n // TODO: Add properties\n}\n\ninterface Use{{name}}Options {\n id?: string;\n autoFetch?: boolean;\n}\n\nexport function use{{name}}(options: Use{{name}}Options = {}) {\n const { id, autoFetch = true } = options;\n const [data, setData] = useState<{{name}}Data | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const fetch{{name}} = useCallback(async (fetchId?: string) => {\n const targetId = fetchId || id;\n if (!targetId) return;\n\n setLoading(true);\n setError(null);\n try {\n // TODO: Implement API call\n // const result = await {{nameLower}}Api.getById(targetId);\n // setData(result);\n } catch (e) {\n setError(e instanceof Error ? e : new Error('Unknown error'));\n } finally {\n setLoading(false);\n }\n }, [id]);\n\n const save{{name}} = useCallback(async (saveData: {{name}}Data) => {\n setLoading(true);\n setError(null);\n try {\n // TODO: Implement API call\n // const result = saveData.id\n // ? await {{nameLower}}Api.update(saveData.id, saveData)\n // : await {{nameLower}}Api.create(saveData);\n // setData(result);\n // return result;\n } catch (e) {\n setError(e instanceof Error ? e : new Error('Unknown error'));\n throw e;\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n if (autoFetch && id) {\n fetch{{name}}();\n }\n }, [autoFetch, id, fetch{{name}}]);\n\n return {\n data,\n loading,\n error,\n fetch: fetch{{name}},\n save: save{{name}},\n setData,\n };\n}\n`;\n\n const context = {\n name,\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\n };\n\n const componentContent = Handlebars.compile(componentTemplate)(context);\n const hookContent = Handlebars.compile(hookTemplate)(context);\n\n // Determine output paths\n const projectRoot = config.smartstack.projectPath;\n const webPath = structure.web || path.join(projectRoot, 'web', 'smartstack-web');\n const componentsPath = options?.outputPath || path.join(webPath, 'src', 'components');\n const hooksPath = path.join(webPath, 'src', 'hooks');\n\n const componentFilePath = path.join(componentsPath, `${name}.tsx`);\n const hookFilePath = path.join(hooksPath, `use${name}.ts`);\n\n // Validate paths don't escape project directory\n validatePathSecurity(componentFilePath, projectRoot);\n validatePathSecurity(hookFilePath, projectRoot);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(componentsPath);\n await ensureDirectory(hooksPath);\n await writeText(componentFilePath, componentContent);\n await writeText(hookFilePath, hookContent);\n }\n\n result.files.push({ path: componentFilePath, content: componentContent, type: 'created' });\n result.files.push({ path: hookFilePath, content: hookContent, type: 'created' });\n\n result.instructions.push('Import and use the component:');\n result.instructions.push(`import { ${name} } from './components/${name}';`);\n result.instructions.push(`import { use${name} } from './hooks/use${name}';`);\n}\n\nasync function scaffoldTest(\n name: string,\n options: { namespace?: string; isSystemEntity?: boolean; dryRun?: boolean } | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const isSystemEntity = options?.isSystemEntity || false;\n\n // xUnit Service Test template\n const serviceTestTemplate = `using System;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Logging;\nusing Moq;\nusing Xunit;\nusing FluentAssertions;\nusing ${config.conventions.namespaces.application}.Services;\n\nnamespace ${config.conventions.namespaces.application}.Tests.Services;\n\n/// <summary>\n/// Unit tests for {{name}}Service\n/// </summary>\npublic class {{name}}ServiceTests\n{\n private readonly Mock<ILogger<{{name}}Service>> _loggerMock;\n private readonly {{name}}Service _sut;\n\n public {{name}}ServiceTests()\n {\n _loggerMock = new Mock<ILogger<{{name}}Service>>();\n _sut = new {{name}}Service(_loggerMock.Object);\n }\n\n [Fact]\n public async Task GetByIdAsync_ShouldReturnEntity_WhenExists()\n {\n // Arrange\n var id = Guid.NewGuid();\n{{#unless isSystemEntity}}\n var tenantId = Guid.NewGuid();\n{{/unless}}\n\n // Act\n var result = await _sut.GetByIdAsync(CancellationToken.None);\n\n // Assert\n // TODO: Implement actual assertion\n result.Should().NotBeNull();\n }\n\n [Fact]\n public async Task GetAllAsync_ShouldReturnList()\n {\n // Arrange\n{{#unless isSystemEntity}}\n var tenantId = Guid.NewGuid();\n{{/unless}}\n\n // Act\n var result = await _sut.GetAllAsync(CancellationToken.None);\n\n // Assert\n // TODO: Implement actual assertion\n result.Should().NotBeNull();\n }\n\n [Fact]\n public async Task CreateAsync_ShouldCreateEntity()\n {\n // Arrange\n{{#unless isSystemEntity}}\n var tenantId = Guid.NewGuid();\n{{/unless}}\n\n // Act\n var result = await _sut.CreateAsync(CancellationToken.None);\n\n // Assert\n // TODO: Implement actual assertion\n result.Should().NotBeNull();\n }\n\n [Fact]\n public async Task UpdateAsync_ShouldUpdateEntity_WhenExists()\n {\n // Arrange\n var id = Guid.NewGuid();\n\n // Act\n var result = await _sut.UpdateAsync(CancellationToken.None);\n\n // Assert\n // TODO: Implement actual assertion\n result.Should().NotBeNull();\n }\n\n [Fact]\n public async Task DeleteAsync_ShouldSoftDelete_WhenExists()\n {\n // Arrange\n var id = Guid.NewGuid();\n\n // Act\n var result = await _sut.DeleteAsync(CancellationToken.None);\n\n // Assert\n // TODO: Implement actual assertion\n result.Should().NotBeNull();\n }\n}\n`;\n\n const context = {\n name,\n isSystemEntity,\n };\n\n const testContent = Handlebars.compile(serviceTestTemplate)(context);\n\n // Determine output path (tests folder)\n const testsPath = structure.application\n ? path.join(path.dirname(structure.application), `${path.basename(structure.application)}.Tests`, 'Services')\n : path.join(config.smartstack.projectPath, 'Application.Tests', 'Services');\n\n const testFilePath = path.join(testsPath, `${name}ServiceTests.cs`);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(testsPath);\n await writeText(testFilePath, testContent);\n }\n\n result.files.push({ path: testFilePath, content: testContent, type: 'created' });\n\n result.instructions.push('Run tests:');\n result.instructions.push(`dotnet test --filter \"FullyQualifiedName~${name}ServiceTests\"`);\n result.instructions.push('');\n result.instructions.push('Required packages:');\n result.instructions.push('- xunit');\n result.instructions.push('- Moq');\n result.instructions.push('- FluentAssertions');\n}\n\nasync function scaffoldDtos(\n name: string,\n options: FeatureOptions | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const namespace = options?.namespace || `${config.conventions.namespaces.application}.DTOs`;\n const isSystemEntity = options?.isSystemEntity || false;\n const properties = options?.entityProperties || [\n { name: 'Name', type: 'string', required: true, maxLength: 200 },\n { name: 'Description', type: 'string?', required: false, maxLength: 500 },\n ];\n\n // Response DTO template\n const responseDtoTemplate = `using System;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// Response DTO for {{name}}\n/// </summary>\npublic record {{name}}ResponseDto\n{\n /// <summary>Unique identifier</summary>\n public Guid Id { get; init; }\n\n{{#unless isSystemEntity}}\n /// <summary>Tenant identifier</summary>\n public Guid TenantId { get; init; }\n\n{{/unless}}\n /// <summary>Unique code</summary>\n public string Code { get; init; } = string.Empty;\n\n{{#each properties}}\n /// <summary>{{name}}</summary>\n public {{type}} {{name}} { get; init; }{{#if (eq type \"string\")}} = string.Empty;{{/if}}\n\n{{/each}}\n /// <summary>Creation timestamp</summary>\n public DateTime CreatedAt { get; init; }\n\n /// <summary>Last update timestamp</summary>\n public DateTime? UpdatedAt { get; init; }\n\n /// <summary>Created by user</summary>\n public string? CreatedBy { get; init; }\n}\n`;\n\n // Create DTO template\n const createDtoTemplate = `using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// DTO for creating a new {{name}}\n/// </summary>\npublic record Create{{name}}Dto\n{\n /// <summary>Unique code (will be lowercased)</summary>\n [Required]\n [MaxLength(100)]\n public string Code { get; init; } = string.Empty;\n\n{{#each properties}}\n{{#if required}}\n /// <summary>{{name}} (required)</summary>\n [Required]\n{{#if maxLength}}\n [MaxLength({{maxLength}})]\n{{/if}}\n public {{type}} {{name}} { get; init; }{{#if (eq type \"string\")}} = string.Empty;{{/if}}\n\n{{else}}\n /// <summary>{{name}} (optional)</summary>\n{{#if maxLength}}\n [MaxLength({{maxLength}})]\n{{/if}}\n public {{type}} {{name}} { get; init; }\n\n{{/if}}\n{{/each}}\n}\n`;\n\n // Update DTO template\n const updateDtoTemplate = `using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// DTO for updating an existing {{name}}\n/// </summary>\npublic record Update{{name}}Dto\n{\n{{#each properties}}\n{{#if required}}\n /// <summary>{{name}} (required)</summary>\n [Required]\n{{#if maxLength}}\n [MaxLength({{maxLength}})]\n{{/if}}\n public {{type}} {{name}} { get; init; }{{#if (eq type \"string\")}} = string.Empty;{{/if}}\n\n{{else}}\n /// <summary>{{name}} (optional)</summary>\n{{#if maxLength}}\n [MaxLength({{maxLength}})]\n{{/if}}\n public {{type}} {{name}} { get; init; }\n\n{{/if}}\n{{/each}}\n}\n`;\n\n // Register eq helper for Handlebars\n Handlebars.registerHelper('eq', (a: string, b: string) => a === b);\n\n const context = {\n namespace,\n name,\n isSystemEntity,\n properties,\n };\n\n const responseContent = Handlebars.compile(responseDtoTemplate)(context);\n const createContent = Handlebars.compile(createDtoTemplate)(context);\n const updateContent = Handlebars.compile(updateDtoTemplate)(context);\n\n // Determine output paths\n const basePath = structure.application || config.smartstack.projectPath;\n const dtosPath = path.join(basePath, 'DTOs', name);\n\n const responseFilePath = path.join(dtosPath, `${name}ResponseDto.cs`);\n const createFilePath = path.join(dtosPath, `Create${name}Dto.cs`);\n const updateFilePath = path.join(dtosPath, `Update${name}Dto.cs`);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(dtosPath);\n await writeText(responseFilePath, responseContent);\n await writeText(createFilePath, createContent);\n await writeText(updateFilePath, updateContent);\n }\n\n result.files.push({ path: responseFilePath, content: responseContent, type: 'created' });\n result.files.push({ path: createFilePath, content: createContent, type: 'created' });\n result.files.push({ path: updateFilePath, content: updateContent, type: 'created' });\n\n result.instructions.push('DTOs generated:');\n result.instructions.push(`- ${name}ResponseDto: For API responses`);\n result.instructions.push(`- Create${name}Dto: For POST requests`);\n result.instructions.push(`- Update${name}Dto: For PUT requests`);\n}\n\nasync function scaffoldValidator(\n name: string,\n options: FeatureOptions | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const namespace = options?.namespace || `${config.conventions.namespaces.application}.Validators`;\n const properties = options?.entityProperties || [\n { name: 'Name', type: 'string', required: true, maxLength: 200 },\n { name: 'Description', type: 'string?', required: false, maxLength: 500 },\n ];\n\n // Create validator template\n const createValidatorTemplate = `using FluentValidation;\nusing ${config.conventions.namespaces.application}.DTOs;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// Validator for Create{{name}}Dto\n/// </summary>\npublic class Create{{name}}DtoValidator : AbstractValidator<Create{{name}}Dto>\n{\n public Create{{name}}DtoValidator()\n {\n RuleFor(x => x.Code)\n .NotEmpty().WithMessage(\"Code is required\")\n .MaximumLength(100).WithMessage(\"Code must not exceed 100 characters\")\n .Matches(\"^[a-z0-9_]+$\").WithMessage(\"Code must be lowercase alphanumeric with underscores\");\n\n{{#each properties}}\n{{#if required}}\n RuleFor(x => x.{{name}})\n .NotEmpty().WithMessage(\"{{name}} is required\"){{#if maxLength}}\n .MaximumLength({{maxLength}}).WithMessage(\"{{name}} must not exceed {{maxLength}} characters\"){{/if}};\n\n{{else}}\n{{#if maxLength}}\n RuleFor(x => x.{{name}})\n .MaximumLength({{maxLength}}).WithMessage(\"{{name}} must not exceed {{maxLength}} characters\")\n .When(x => !string.IsNullOrEmpty(x.{{name}}));\n\n{{/if}}\n{{/if}}\n{{/each}}\n }\n}\n`;\n\n // Update validator template\n const updateValidatorTemplate = `using FluentValidation;\nusing ${config.conventions.namespaces.application}.DTOs;\n\nnamespace {{namespace}};\n\n/// <summary>\n/// Validator for Update{{name}}Dto\n/// </summary>\npublic class Update{{name}}DtoValidator : AbstractValidator<Update{{name}}Dto>\n{\n public Update{{name}}DtoValidator()\n {\n{{#each properties}}\n{{#if required}}\n RuleFor(x => x.{{name}})\n .NotEmpty().WithMessage(\"{{name}} is required\"){{#if maxLength}}\n .MaximumLength({{maxLength}}).WithMessage(\"{{name}} must not exceed {{maxLength}} characters\"){{/if}};\n\n{{else}}\n{{#if maxLength}}\n RuleFor(x => x.{{name}})\n .MaximumLength({{maxLength}}).WithMessage(\"{{name}} must not exceed {{maxLength}} characters\")\n .When(x => !string.IsNullOrEmpty(x.{{name}}));\n\n{{/if}}\n{{/if}}\n{{/each}}\n }\n}\n`;\n\n const context = {\n namespace,\n name,\n properties,\n };\n\n const createValidatorContent = Handlebars.compile(createValidatorTemplate)(context);\n const updateValidatorContent = Handlebars.compile(updateValidatorTemplate)(context);\n\n // Determine output paths\n const basePath = structure.application || config.smartstack.projectPath;\n const validatorsPath = path.join(basePath, 'Validators');\n\n const createValidatorFilePath = path.join(validatorsPath, `Create${name}DtoValidator.cs`);\n const updateValidatorFilePath = path.join(validatorsPath, `Update${name}DtoValidator.cs`);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(validatorsPath);\n await writeText(createValidatorFilePath, createValidatorContent);\n await writeText(updateValidatorFilePath, updateValidatorContent);\n }\n\n result.files.push({ path: createValidatorFilePath, content: createValidatorContent, type: 'created' });\n result.files.push({ path: updateValidatorFilePath, content: updateValidatorContent, type: 'created' });\n\n result.instructions.push('Register validators in DI:');\n result.instructions.push(`services.AddValidatorsFromAssemblyContaining<Create${name}DtoValidator>();`);\n result.instructions.push('');\n result.instructions.push('Required package: FluentValidation.DependencyInjectionExtensions');\n}\n\nasync function scaffoldRepository(\n name: string,\n options: FeatureOptions | undefined,\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean = false\n): Promise<void> {\n const isSystemEntity = options?.isSystemEntity || false;\n\n // Repository interface template\n const interfaceTemplate = `using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing ${config.conventions.namespaces.domain};\n\nnamespace ${config.conventions.namespaces.application}.Repositories;\n\n/// <summary>\n/// Repository interface for {{name}} entity\n/// </summary>\npublic interface I{{name}}Repository\n{\n /// <summary>Get entity by ID</summary>\n Task<{{name}}?> GetByIdAsync(Guid id, CancellationToken ct = default);\n\n /// <summary>Get entity by code</summary>\n Task<{{name}}?> GetByCodeAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}string code, CancellationToken ct = default);\n\n /// <summary>Get all entities{{#unless isSystemEntity}} for tenant{{/unless}}</summary>\n Task<IReadOnlyList<{{name}}>> GetAllAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}CancellationToken ct = default);\n\n /// <summary>Check if code exists{{#unless isSystemEntity}} in tenant{{/unless}}</summary>\n Task<bool> ExistsAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}string code, CancellationToken ct = default);\n\n /// <summary>Add new entity</summary>\n Task<{{name}}> AddAsync({{name}} entity, CancellationToken ct = default);\n\n /// <summary>Update entity</summary>\n Task UpdateAsync({{name}} entity, CancellationToken ct = default);\n\n /// <summary>Soft delete entity</summary>\n Task DeleteAsync({{name}} entity, CancellationToken ct = default);\n}\n`;\n\n // Repository implementation template\n const implementationTemplate = `using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.EntityFrameworkCore;\nusing ${config.conventions.namespaces.domain};\nusing ${config.conventions.namespaces.infrastructure}.Persistence;\n\nnamespace ${config.conventions.namespaces.infrastructure}.Repositories;\n\n/// <summary>\n/// Repository implementation for {{name}} entity\n/// </summary>\npublic class {{name}}Repository : I{{name}}Repository\n{\n private readonly ApplicationDbContext _context;\n\n public {{name}}Repository(ApplicationDbContext context)\n {\n _context = context;\n }\n\n /// <inheritdoc />\n public async Task<{{name}}?> GetByIdAsync(Guid id, CancellationToken ct = default)\n {\n return await _context.{{name}}s\n .FirstOrDefaultAsync(e => e.Id == id, ct);\n }\n\n /// <inheritdoc />\n public async Task<{{name}}?> GetByCodeAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}string code, CancellationToken ct = default)\n {\n return await _context.{{name}}s\n .FirstOrDefaultAsync(e => {{#unless isSystemEntity}}e.TenantId == tenantId && {{/unless}}e.Code == code.ToLowerInvariant(), ct);\n }\n\n /// <inheritdoc />\n public async Task<IReadOnlyList<{{name}}>> GetAllAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}CancellationToken ct = default)\n {\n return await _context.{{name}}s\n {{#unless isSystemEntity}}.Where(e => e.TenantId == tenantId){{/unless}}\n .OrderBy(e => e.Code)\n .ToListAsync(ct);\n }\n\n /// <inheritdoc />\n public async Task<bool> ExistsAsync({{#unless isSystemEntity}}Guid tenantId, {{/unless}}string code, CancellationToken ct = default)\n {\n return await _context.{{name}}s\n .AnyAsync(e => {{#unless isSystemEntity}}e.TenantId == tenantId && {{/unless}}e.Code == code.ToLowerInvariant(), ct);\n }\n\n /// <inheritdoc />\n public async Task<{{name}}> AddAsync({{name}} entity, CancellationToken ct = default)\n {\n await _context.{{name}}s.AddAsync(entity, ct);\n await _context.SaveChangesAsync(ct);\n return entity;\n }\n\n /// <inheritdoc />\n public async Task UpdateAsync({{name}} entity, CancellationToken ct = default)\n {\n _context.{{name}}s.Update(entity);\n await _context.SaveChangesAsync(ct);\n }\n\n /// <inheritdoc />\n public async Task DeleteAsync({{name}} entity, CancellationToken ct = default)\n {\n entity.SoftDelete();\n await UpdateAsync(entity, ct);\n }\n}\n`;\n\n const context = {\n name,\n isSystemEntity,\n };\n\n const interfaceContent = Handlebars.compile(interfaceTemplate)(context);\n const implementationContent = Handlebars.compile(implementationTemplate)(context);\n\n // Determine output paths\n const appPath = structure.application || config.smartstack.projectPath;\n const infraPath = structure.infrastructure || path.join(config.smartstack.projectPath, 'Infrastructure');\n\n const interfaceFilePath = path.join(appPath, 'Repositories', `I${name}Repository.cs`);\n const implementationFilePath = path.join(infraPath, 'Repositories', `${name}Repository.cs`);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(path.join(appPath, 'Repositories'));\n await ensureDirectory(path.join(infraPath, 'Repositories'));\n await writeText(interfaceFilePath, interfaceContent);\n await writeText(implementationFilePath, implementationContent);\n }\n\n result.files.push({ path: interfaceFilePath, content: interfaceContent, type: 'created' });\n result.files.push({ path: implementationFilePath, content: implementationContent, type: 'created' });\n\n result.instructions.push('Register repository in DI:');\n result.instructions.push(`services.AddScoped<I${name}Repository, ${name}Repository>();`);\n}\n\nfunction formatResult(result: ScaffoldResult, type: string, name: string, dryRun: boolean = false): string {\n const lines: string[] = [];\n\n if (dryRun) {\n lines.push(`# 🔍 DRY-RUN: Scaffold ${type}: ${name}`);\n lines.push('');\n lines.push('> **Preview mode**: No files were written. Review the generated code below.');\n lines.push('> To create files, run without `dryRun: true`');\n lines.push('');\n } else {\n lines.push(`# Scaffold ${type}: ${name}`);\n lines.push('');\n }\n\n if (result.success) {\n lines.push(dryRun ? '## 📄 Files to Generate' : '## ✅ Files Generated');\n lines.push('');\n\n for (const file of result.files) {\n lines.push(`### ${file.type === 'created' ? '📄' : '✏️'} ${path.basename(file.path)}`);\n lines.push(`**Path**: \\`${file.path}\\``);\n lines.push('');\n lines.push('```' + (file.path.endsWith('.cs') ? 'csharp' : 'typescript'));\n // Show first 50 lines of content\n const contentLines = file.content.split('\\n').slice(0, 50);\n lines.push(contentLines.join('\\n'));\n if (file.content.split('\\n').length > 50) {\n lines.push('// ... (truncated)');\n }\n lines.push('```');\n lines.push('');\n }\n\n if (result.instructions.length > 0) {\n lines.push('## 📋 Next Steps');\n lines.push('');\n for (const instruction of result.instructions) {\n if (instruction.startsWith('services.') || instruction.startsWith('public DbSet')) {\n lines.push('```csharp');\n lines.push(instruction);\n lines.push('```');\n } else if (instruction.startsWith('dotnet ')) {\n lines.push('```bash');\n lines.push(instruction);\n lines.push('```');\n } else if (instruction.startsWith('import ')) {\n lines.push('```typescript');\n lines.push(instruction);\n lines.push('```');\n } else {\n lines.push(instruction);\n }\n }\n }\n } else {\n lines.push('## ❌ Generation Failed');\n lines.push('');\n for (const instruction of result.instructions) {\n lines.push(`- ${instruction}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport axios from 'axios';\nimport {\n ApiDocsInputSchema,\n type Config,\n} from '../types/index.js';\nimport { readText } from '../utils/fs.js';\nimport { findSmartStackStructure, findControllerFiles } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const apiDocsTool: Tool = {\n name: 'api_docs',\n description: 'Get API documentation for SmartStack endpoints. Can fetch from Swagger/OpenAPI or parse controller files directly.',\n inputSchema: {\n type: 'object',\n properties: {\n endpoint: {\n type: 'string',\n description: 'Filter by endpoint path (e.g., \"/api/users\"). Leave empty for all endpoints.',\n },\n format: {\n type: 'string',\n enum: ['markdown', 'json', 'openapi'],\n description: 'Output format',\n default: 'markdown',\n },\n controller: {\n type: 'string',\n description: 'Filter by controller name (e.g., \"Users\")',\n },\n },\n },\n};\n\ninterface EndpointInfo {\n method: string;\n path: string;\n controller: string;\n action: string;\n summary?: string;\n parameters: ParameterInfo[];\n requestBody?: RequestBodyInfo;\n responses: ResponseInfo[];\n authorize: boolean;\n example?: ExampleInfo;\n}\n\ninterface RequestBodyInfo {\n type: string;\n required: boolean;\n schema?: Record<string, string>;\n}\n\ninterface ExampleInfo {\n request?: string;\n response?: string;\n}\n\ninterface ParameterInfo {\n name: string;\n in: 'path' | 'query' | 'header' | 'body';\n type: string;\n required: boolean;\n description?: string;\n}\n\ninterface ResponseInfo {\n status: number;\n type?: string;\n description?: string;\n}\n\nexport async function handleApiDocs(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ApiDocsInputSchema.parse(args);\n\n logger.info('Fetching API documentation', { endpoint: input.endpoint, format: input.format });\n\n let endpoints: EndpointInfo[] = [];\n\n // Try to fetch from Swagger first if API is enabled\n if (config.smartstack.apiEnabled && config.smartstack.apiUrl) {\n try {\n endpoints = await fetchFromSwagger(config.smartstack.apiUrl);\n logger.debug('Fetched endpoints from Swagger', { count: endpoints.length });\n } catch (error) {\n logger.warn('Failed to fetch from Swagger, falling back to code parsing', { error });\n }\n }\n\n // Fall back to parsing controller files\n if (endpoints.length === 0) {\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n endpoints = await parseControllers(structure);\n }\n\n // Filter endpoints\n if (input.endpoint) {\n const filter = input.endpoint.toLowerCase();\n endpoints = endpoints.filter(e => e.path.toLowerCase().includes(filter));\n }\n\n if (input.controller) {\n const filter = input.controller.toLowerCase();\n endpoints = endpoints.filter(e => e.controller.toLowerCase().includes(filter));\n }\n\n // Format output\n switch (input.format) {\n case 'json':\n return JSON.stringify(endpoints, null, 2);\n case 'openapi':\n return formatAsOpenApi(endpoints);\n case 'markdown':\n default:\n return formatAsMarkdown(endpoints);\n }\n}\n\nasync function fetchFromSwagger(apiUrl: string): Promise<EndpointInfo[]> {\n const swaggerUrl = `${apiUrl}/swagger/v1/swagger.json`;\n\n const response = await axios.get(swaggerUrl, {\n timeout: 5000,\n httpsAgent: new (await import('https')).Agent({ rejectUnauthorized: false }),\n });\n\n const spec = response.data;\n const endpoints: EndpointInfo[] = [];\n\n for (const [pathKey, pathItem] of Object.entries(spec.paths || {})) {\n const pathObj = pathItem as Record<string, unknown>;\n\n for (const method of ['get', 'post', 'put', 'patch', 'delete']) {\n const operation = pathObj[method] as Record<string, unknown> | undefined;\n if (!operation) continue;\n\n const tags = (operation.tags as string[]) || ['Unknown'];\n const parameters = (operation.parameters as Array<Record<string, unknown>>) || [];\n\n endpoints.push({\n method: method.toUpperCase(),\n path: pathKey,\n controller: tags[0],\n action: (operation.operationId as string) || method,\n summary: operation.summary as string | undefined,\n parameters: parameters.map(p => ({\n name: p.name as string,\n in: p.in as 'path' | 'query' | 'header' | 'body',\n type: (p.schema as Record<string, string>)?.type || 'string',\n required: p.required as boolean || false,\n description: p.description as string | undefined,\n })),\n requestBody: operation.requestBody ? { type: 'object', required: true } : undefined,\n responses: Object.entries(operation.responses || {}).map(([status, resp]) => ({\n status: parseInt(status, 10),\n description: (resp as Record<string, string>).description,\n })),\n authorize: !!(operation.security && (operation.security as unknown[]).length > 0),\n });\n }\n }\n\n return endpoints;\n}\n\nasync function parseControllers(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never\n): Promise<EndpointInfo[]> {\n if (!structure.api) {\n return [];\n }\n\n const controllerFiles = await findControllerFiles(structure.api);\n const endpoints: EndpointInfo[] = [];\n\n for (const file of controllerFiles) {\n const content = await readText(file);\n const fileName = path.basename(file, '.cs');\n const controllerName = fileName.replace('Controller', '');\n\n // Parse route attribute\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\n const baseRoute = routeMatch ? routeMatch[1].replace('[controller]', controllerName.toLowerCase()) : `/api/${controllerName.toLowerCase()}`;\n\n // Parse authorize attribute\n const hasAuthorize = content.includes('[Authorize]');\n\n // Parse HTTP methods\n const httpMethods = [\n { pattern: /\\[HttpGet(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'GET' },\n { pattern: /\\[HttpPost(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'POST' },\n { pattern: /\\[HttpPut(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PUT' },\n { pattern: /\\[HttpPatch(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'PATCH' },\n { pattern: /\\[HttpDelete(?:\\s*\\(\\s*\"([^\"]*)\"\\s*\\))?\\]/g, method: 'DELETE' },\n ];\n\n for (const { pattern, method } of httpMethods) {\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const routeSuffix = match[1] || '';\n const fullPath = routeSuffix ? `${baseRoute}/${routeSuffix}` : baseRoute;\n\n // Try to find the method name after the attribute\n const afterAttribute = content.substring(match.index);\n const methodMatch = afterAttribute.match(/public\\s+(?:async\\s+)?(?:Task<)?(?:ActionResult<)?(\\w+)(?:>)?\\s+(\\w+)\\s*\\(/);\n\n const parameters: ParameterInfo[] = [];\n\n // Parse path parameters\n const pathParams = fullPath.match(/\\{(\\w+)(?::\\w+)?\\}/g);\n if (pathParams) {\n for (const param of pathParams) {\n const paramName = param.replace(/[{}:]/g, '').replace(/\\w+$/, '');\n parameters.push({\n name: paramName || param.replace(/[{}]/g, '').split(':')[0],\n in: 'path',\n type: 'string',\n required: true,\n });\n }\n }\n\n // Parse [FromBody] parameters and extract request body info\n let requestBody: RequestBodyInfo | undefined;\n if (afterAttribute.includes('[FromBody]')) {\n const bodyMatch = afterAttribute.match(/\\[FromBody\\]\\s*(\\w+)\\s+(\\w+)/);\n if (bodyMatch) {\n requestBody = {\n type: bodyMatch[1],\n required: true,\n };\n parameters.push({\n name: bodyMatch[2],\n in: 'body',\n type: bodyMatch[1],\n required: true,\n });\n }\n }\n\n // Extract XML summary comment\n let summary: string | undefined;\n const methodStartIndex = content.lastIndexOf('/// <summary>', match.index);\n if (methodStartIndex !== -1 && match.index - methodStartIndex < 500) {\n const summaryMatch = content.substring(methodStartIndex, match.index).match(/\\/\\/\\/\\s*<summary>\\s*\\n?\\s*\\/\\/\\/\\s*(.+?)\\s*\\n?\\s*\\/\\/\\/\\s*<\\/summary>/s);\n if (summaryMatch) {\n summary = summaryMatch[1].replace(/\\/\\/\\/\\s*/g, '').trim();\n }\n }\n\n // Parse [FromQuery] parameters\n const queryMatches = afterAttribute.matchAll(/\\[FromQuery\\]\\s*(\\w+)\\s+(\\w+)/g);\n for (const qm of queryMatches) {\n parameters.push({\n name: qm[2],\n in: 'query',\n type: qm[1],\n required: false,\n });\n }\n\n // Generate example based on method\n const example: ExampleInfo = {};\n if (requestBody) {\n example.request = generateExampleRequest(requestBody.type);\n }\n if (method === 'GET' || method === 'POST') {\n example.response = generateExampleResponse(controllerName, method);\n }\n\n endpoints.push({\n method,\n path: fullPath.replace(/\\/+/g, '/'),\n controller: controllerName,\n action: methodMatch ? methodMatch[2] : 'Unknown',\n summary,\n parameters,\n requestBody,\n responses: generateResponses(method),\n authorize: hasAuthorize,\n example,\n });\n }\n }\n }\n\n return endpoints;\n}\n\nfunction generateResponses(method: string): ResponseInfo[] {\n switch (method) {\n case 'GET':\n return [\n { status: 200, description: 'Success' },\n { status: 404, description: 'Not Found' },\n ];\n case 'POST':\n return [\n { status: 201, description: 'Created' },\n { status: 400, description: 'Bad Request' },\n { status: 422, description: 'Validation Error' },\n ];\n case 'PUT':\n case 'PATCH':\n return [\n { status: 204, description: 'No Content' },\n { status: 400, description: 'Bad Request' },\n { status: 404, description: 'Not Found' },\n ];\n case 'DELETE':\n return [\n { status: 204, description: 'No Content' },\n { status: 404, description: 'Not Found' },\n ];\n default:\n return [{ status: 200, description: 'Success' }];\n }\n}\n\nfunction generateExampleRequest(typeName: string): string {\n // Generate example based on DTO type name\n const name = typeName.replace('Request', '').replace('Dto', '').replace('Create', '').replace('Update', '');\n const example: Record<string, unknown> = {\n code: `${name.toLowerCase()}_001`,\n };\n\n if (typeName.includes('Create')) {\n example.name = `New ${name}`;\n example.description = `Description for ${name}`;\n } else if (typeName.includes('Update')) {\n example.name = `Updated ${name}`;\n example.description = `Updated description for ${name}`;\n }\n\n return JSON.stringify(example, null, 2);\n}\n\nfunction generateExampleResponse(controllerName: string, method: string): string {\n const example: Record<string, unknown> = {\n id: '3fa85f64-5717-4562-b3fc-2c963f66afa6',\n tenantId: '6fa85f64-5717-4562-b3fc-2c963f66afa6',\n code: `${controllerName.toLowerCase()}_001`,\n name: `Example ${controllerName}`,\n createdAt: new Date().toISOString(),\n updatedAt: null,\n createdBy: 'user@example.com',\n };\n\n if (method === 'GET') {\n return JSON.stringify(example, null, 2);\n }\n\n return JSON.stringify(example, null, 2);\n}\n\nfunction formatAsMarkdown(endpoints: EndpointInfo[]): string {\n const lines: string[] = [];\n\n lines.push('# SmartStack API Documentation');\n lines.push('');\n lines.push(`Generated: ${new Date().toISOString()}`);\n lines.push('');\n\n // Group by controller\n const byController = new Map<string, EndpointInfo[]>();\n for (const endpoint of endpoints) {\n const existing = byController.get(endpoint.controller) || [];\n existing.push(endpoint);\n byController.set(endpoint.controller, existing);\n }\n\n for (const [controller, controllerEndpoints] of byController) {\n lines.push(`## ${controller}`);\n lines.push('');\n\n for (const endpoint of controllerEndpoints) {\n const authBadge = endpoint.authorize ? ' 🔒' : '';\n lines.push(`### \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\n lines.push('');\n\n if (endpoint.summary) {\n lines.push(endpoint.summary);\n lines.push('');\n }\n\n if (endpoint.parameters.length > 0) {\n lines.push('**Parameters:**');\n lines.push('');\n lines.push('| Name | In | Type | Required |');\n lines.push('|------|-----|------|----------|');\n for (const param of endpoint.parameters) {\n lines.push(`| ${param.name} | ${param.in} | ${param.type} | ${param.required ? 'Yes' : 'No'} |`);\n }\n lines.push('');\n }\n\n if (endpoint.requestBody) {\n lines.push('**Request Body:**');\n lines.push('');\n lines.push(`Type: \\`${endpoint.requestBody.type}\\``);\n lines.push('');\n if (endpoint.example?.request) {\n lines.push('```json');\n lines.push(endpoint.example.request);\n lines.push('```');\n lines.push('');\n }\n }\n\n if (endpoint.responses.length > 0) {\n lines.push('**Responses:**');\n lines.push('');\n for (const resp of endpoint.responses) {\n lines.push(`- \\`${resp.status}\\`: ${resp.description || 'No description'}`);\n }\n lines.push('');\n }\n\n if (endpoint.example?.response && (endpoint.method === 'GET' || endpoint.method === 'POST')) {\n lines.push('**Example Response:**');\n lines.push('');\n lines.push('```json');\n lines.push(endpoint.example.response);\n lines.push('```');\n lines.push('');\n }\n }\n }\n\n if (endpoints.length === 0) {\n lines.push('No endpoints found matching the filter criteria.');\n }\n\n // Add summary statistics\n lines.push('---');\n lines.push('');\n lines.push('## Summary');\n lines.push('');\n lines.push(`- **Total Endpoints**: ${endpoints.length}`);\n lines.push(`- **Controllers**: ${new Set(endpoints.map(e => e.controller)).size}`);\n lines.push(`- **Authenticated**: ${endpoints.filter(e => e.authorize).length}`);\n lines.push(`- **Public**: ${endpoints.filter(e => !e.authorize).length}`);\n\n return lines.join('\\n');\n}\n\nfunction formatAsOpenApi(endpoints: EndpointInfo[]): string {\n const spec = {\n openapi: '3.0.0',\n info: {\n title: 'SmartStack API',\n version: '1.0.0',\n },\n paths: {} as Record<string, Record<string, unknown>>,\n };\n\n for (const endpoint of endpoints) {\n if (!spec.paths[endpoint.path]) {\n spec.paths[endpoint.path] = {};\n }\n\n spec.paths[endpoint.path][endpoint.method.toLowerCase()] = {\n tags: [endpoint.controller],\n operationId: endpoint.action,\n summary: endpoint.summary,\n parameters: endpoint.parameters\n .filter(p => p.in !== 'body')\n .map(p => ({\n name: p.name,\n in: p.in,\n required: p.required,\n schema: { type: p.type },\n })),\n responses: Object.fromEntries(\n endpoint.responses.map(r => [\n r.status.toString(),\n { description: r.description || 'Response' },\n ])\n ),\n security: endpoint.authorize ? [{ bearerAuth: [] }] : undefined,\n };\n }\n\n return JSON.stringify(spec, null, 2);\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport type { Config } from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { findFiles } from '../utils/fs.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const suggestMigrationTool: Tool = {\n name: 'suggest_migration',\n description: 'Suggest a migration name following SmartStack conventions ({context}_v{version}_{sequence}_{Description})',\n inputSchema: {\n type: 'object',\n properties: {\n description: {\n type: 'string',\n description: 'Description of what the migration does (e.g., \"Add User Profiles\", \"Create Orders Table\")',\n },\n context: {\n type: 'string',\n enum: ['core', 'extensions'],\n description: 'DbContext name (default: core)',\n },\n version: {\n type: 'string',\n description: 'Semver version (e.g., \"1.0.0\", \"1.2.0\"). If not provided, uses latest from existing migrations.',\n },\n },\n required: ['description'],\n },\n};\n\nexport const SuggestMigrationInputSchema = z.object({\n description: z.string().describe('Description of what the migration does'),\n context: z.enum(['core', 'extensions']).optional().describe('DbContext name (default: core)'),\n version: z.string().optional().describe('Semver version (e.g., \"1.0.0\")'),\n});\n\nexport type SuggestMigrationInput = z.infer<typeof SuggestMigrationInputSchema>;\n\ninterface MigrationInfo {\n name: string;\n context: string;\n version: string;\n sequence: number;\n description: string;\n}\n\nexport async function handleSuggestMigration(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = SuggestMigrationInputSchema.parse(args);\n const context = input.context || 'core';\n\n logger.info('Suggesting migration name', { description: input.description, context });\n\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n // Find existing migrations\n const existingMigrations = await findExistingMigrations(structure, config, context);\n\n // Determine version and sequence\n let version = input.version;\n let sequence = 1;\n\n if (existingMigrations.length > 0) {\n // Get latest migration for this context\n const latestMigration = existingMigrations[existingMigrations.length - 1];\n\n if (!version) {\n // Use the same version as the latest migration\n version = latestMigration.version;\n }\n\n // Calculate next sequence number for this version\n const migrationsInVersion = existingMigrations.filter(m => m.version === version);\n if (migrationsInVersion.length > 0) {\n const maxSequence = Math.max(...migrationsInVersion.map(m => m.sequence));\n sequence = maxSequence + 1;\n }\n } else {\n // No existing migrations, start fresh\n version = version || '1.0.0';\n }\n\n // Format description to PascalCase\n const pascalDescription = toPascalCase(input.description);\n\n // Format sequence with leading zeros\n const sequenceStr = sequence.toString().padStart(3, '0');\n\n // Build migration name following convention\n const migrationName = `${context}_v${version}_${sequenceStr}_${pascalDescription}`;\n\n // Generate the full command\n const command = `dotnet ef migrations add ${migrationName} --context ApplicationDbContext`;\n\n // Build response\n const lines: string[] = [];\n lines.push('# Migration Name Suggestion');\n lines.push('');\n lines.push('## Suggested Name');\n lines.push('```');\n lines.push(migrationName);\n lines.push('```');\n lines.push('');\n lines.push('## Command');\n lines.push('```bash');\n lines.push(command);\n lines.push('```');\n lines.push('');\n lines.push('## Convention Details');\n lines.push('');\n lines.push(`| Part | Value | Description |`);\n lines.push(`|------|-------|-------------|`);\n lines.push(`| Context | \\`${context}\\` | DbContext name |`);\n lines.push(`| Version | \\`v${version}\\` | Semver version |`);\n lines.push(`| Sequence | \\`${sequenceStr}\\` | Order in version |`);\n lines.push(`| Description | \\`${pascalDescription}\\` | Migration description |`);\n lines.push('');\n\n if (existingMigrations.length > 0) {\n lines.push('## Existing Migrations (last 5)');\n lines.push('');\n const recent = existingMigrations.slice(-5);\n for (const m of recent) {\n lines.push(`- \\`${m.name}\\``);\n }\n }\n\n return lines.join('\\n');\n}\n\nasync function findExistingMigrations(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n config: Config,\n context: string\n): Promise<MigrationInfo[]> {\n const migrations: MigrationInfo[] = [];\n\n // Look for migrations in Infrastructure project\n const infraPath = structure.infrastructure || path.join(config.smartstack.projectPath, 'Infrastructure');\n const migrationsPath = path.join(infraPath, 'Migrations');\n\n try {\n const migrationFiles = await findFiles('*.cs', { cwd: migrationsPath });\n\n // Pattern: {context}_v{version}_{sequence}_{Description}.cs\n // Also matches Designer.cs and Snapshot.cs which we want to skip\n const migrationPattern = /^(\\w+)_v(\\d+\\.\\d+\\.\\d+)_(\\d+)_(\\w+)\\.cs$/;\n\n for (const file of migrationFiles) {\n const fileName = path.basename(file);\n\n // Skip Designer and Snapshot files\n if (fileName.includes('.Designer.') || fileName.includes('ModelSnapshot')) {\n continue;\n }\n\n const match = fileName.match(migrationPattern);\n if (match) {\n const [, ctx, ver, seq, desc] = match;\n if (ctx === context || !context) {\n migrations.push({\n name: fileName.replace('.cs', ''),\n context: ctx,\n version: ver,\n sequence: parseInt(seq, 10),\n description: desc,\n });\n }\n }\n }\n\n // Sort by version then sequence\n migrations.sort((a, b) => {\n const verCompare = compareVersions(a.version, b.version);\n if (verCompare !== 0) return verCompare;\n return a.sequence - b.sequence;\n });\n } catch {\n // Migrations folder doesn't exist yet\n logger.debug('No migrations folder found');\n }\n\n return migrations;\n}\n\nfunction toPascalCase(str: string): string {\n return str\n .replace(/[^a-zA-Z0-9\\s]/g, '') // Remove special chars\n .split(/\\s+/) // Split on whitespace\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join('');\n}\n\nfunction compareVersions(a: string, b: string): number {\n const aParts = a.split('.').map(Number);\n const bParts = b.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n if (aParts[i] > bParts[i]) return 1;\n if (aParts[i] < bParts[i]) return -1;\n }\n\n return 0;\n}\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, codePrefixes, 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| \\`tenant_\\` | Multi-Tenancy | tenant_Tenants, tenant_TenantUsers, tenant_TenantUserRoles |\n\n### Navigation Code Prefixes\n\nAll navigation data (Context, Application, Module, Section, Resource) uses code prefixes to distinguish system data from client extensions:\n\n| Origin | Prefix | Usage | Example |\n|--------|--------|-------|---------|\n| SmartStack (system) | \\`${codePrefixes.core}\\` | Protected, delivered with SmartStack | \\`${codePrefixes.core}administration\\` |\n| Client (extension) | \\`${codePrefixes.extension}\\` | Custom, added by clients | \\`${codePrefixes.extension}it\\` |\n\n**Navigation Hierarchy (5 levels):**\n\n\\`\\`\\`\nContext → Application → Module → Section → Resource\n\\`\\`\\`\n\n**Examples for each level:**\n\n| Level | Core Example | Extension Example |\n|-------|--------------|-------------------|\n| Context | \\`${codePrefixes.core}administration\\` | \\`${codePrefixes.extension}it\\` |\n| Application | \\`${codePrefixes.core}settings\\` | \\`${codePrefixes.extension}custom_app\\` |\n| Module | \\`${codePrefixes.core}users\\` | \\`${codePrefixes.extension}inventory\\` |\n| Section | \\`${codePrefixes.core}management\\` | \\`${codePrefixes.extension}reports\\` |\n| Resource | \\`${codePrefixes.core}user_list\\` | \\`${codePrefixes.extension}stock_view\\` |\n\n**Rules:**\n1. \\`${codePrefixes.core}*\\` codes are **protected** - clients cannot create or modify them\n2. \\`${codePrefixes.extension}*\\` codes are **free** - clients can create custom navigation\n3. SmartStack updates will never overwrite \\`${codePrefixes.extension}*\\` data\n4. Codes must be unique within their level (e.g., no two Contexts with same code)\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| Part | Description | Example |\n|------|-------------|---------|\n| \\`{context}\\` | DbContext name | \\`core\\`, \\`extensions\\` |\n| \\`{version}\\` | Semver version | \\`v1.0.0\\`, \\`v1.2.0\\` |\n| \\`{sequence}\\` | Order in version | \\`001\\`, \\`002\\` |\n| \\`{Description}\\` | Action (PascalCase) | \\`CreateAuthUsers\\` |\n\n**Examples:**\n- \\`core_v1.0.0_001_InitialSchema.cs\\`\n- \\`core_v1.0.0_002_CreateAuthUsers.cs\\`\n- \\`core_v1.2.0_001_AddUserProfiles.cs\\`\n- \\`extensions_v1.0.0_001_AddClientFeatures.cs\\`\n\n### Creating Migrations\n\n\\`\\`\\`bash\n# Create a new migration\ndotnet ef migrations add core_v1.0.0_001_InitialSchema\n\n# With context specified\ndotnet ef migrations add core_v1.2.0_001_AddUserProfiles --context ApplicationDbContext\n\\`\\`\\`\n\n### Migration Rules\n\n1. **One migration per feature** - Group related changes in a single migration\n2. **Version-based naming** - Use semver (v1.0.0, v1.2.0) to link migrations to releases\n3. **Sequence numbers** - Use NNN (001, 002, etc.) for migrations in the same version\n4. **Context prefix** - Use \\`core_\\` for platform tables, \\`extensions_\\` for client extensions\n5. **Descriptive names** - Use clear PascalCase descriptions (CreateAuthUsers, AddUserProfiles, etc.)\n6. **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## 7. Entity Conventions\n\n### Required Interfaces\n\nAll entities MUST implement the following interfaces:\n\n| Interface | Properties | Required |\n|-----------|------------|----------|\n| \\`ITenantEntity\\` | \\`TenantId\\` (Guid) | **YES** (except system entities) |\n| \\`IHasCode\\` | \\`Code\\` (string, lowercase, max 100) | **YES** |\n| \\`ISoftDeletable\\` | \\`IsDeleted\\`, \\`DeletedAt\\`, \\`DeletedBy\\` | **YES** |\n| \\`IVersioned\\` | \\`RowVersion\\` (byte[]) | **YES** |\n| \\`IHistoryEntity<T>\\` | \\`SourceId\\`, \\`ChangeType\\`, \\`OldValues\\`, \\`NewValues\\`, \\`ChangedAt\\`, \\`ChangedBy\\` | For history tables |\n\n### Required Fields (All Entities)\n\n| Field | Type | Description |\n|-------|------|-------------|\n| \\`Id\\` | \\`Guid\\` | Primary key |\n| \\`TenantId\\` | \\`Guid\\` | **Tenant identifier** (required for multi-tenant isolation) |\n| \\`Code\\` | \\`string\\` | Unique identifier per tenant (lowercase, max 100) |\n| \\`CreatedAt\\` | \\`DateTime\\` | Creation timestamp |\n| \\`UpdatedAt\\` | \\`DateTime?\\` | Last update timestamp |\n| \\`CreatedBy\\` | \\`string?\\` | User who created the entity |\n| \\`UpdatedBy\\` | \\`string?\\` | User who last updated the entity |\n| \\`IsDeleted\\` | \\`bool\\` | Soft delete flag |\n| \\`DeletedAt\\` | \\`DateTime?\\` | Deletion timestamp |\n| \\`DeletedBy\\` | \\`string?\\` | User who deleted the entity |\n| \\`RowVersion\\` | \\`byte[]\\` | Concurrency token |\n\n### Multi-Tenant Strategy\n\n\\`\\`\\`csharp\n// Interface for tenant-scoped entities\npublic interface ITenantEntity\n{\n Guid TenantId { get; set; }\n}\n\n// Global query filter (applied automatically)\nbuilder.HasQueryFilter(e => e.TenantId == _currentTenantService.TenantId);\n\\`\\`\\`\n\n**System Entities (without TenantId):**\n- Licenses (\\`lic_\\`)\n- Global configuration (\\`cfg_\\` system level)\n- Shared reference tables\n\nUse \\`ISystemEntity\\` marker interface for these entities.\n\n### Code Field Rules\n\n1. **Always lowercase** - Normalized via setter and value converter\n2. **Prefix required**: \\`${codePrefixes.core}\\` (system) or \\`${codePrefixes.extension}\\` (extensions)\n3. **Unique composite index**: \\`(TenantId, Code) WHERE IsDeleted = 0\\`\n4. **Max length**: 100 characters\n\n\\`\\`\\`csharp\n// Code property with automatic lowercase normalization\nprivate string _code = string.Empty;\npublic string Code\n{\n get => _code;\n set => _code = value?.ToLowerInvariant() ?? string.Empty;\n}\n\\`\\`\\`\n\n### Soft Delete with Restore\n\n\\`\\`\\`csharp\npublic interface ISoftDeletable\n{\n bool IsDeleted { get; set; }\n DateTime? DeletedAt { get; set; }\n string? DeletedBy { get; set; }\n}\n\n// Domain methods\npublic void SoftDelete(string? deletedBy = null)\n{\n IsDeleted = true;\n DeletedAt = DateTime.UtcNow;\n DeletedBy = deletedBy;\n}\n\npublic void Restore(string? restoredBy = null)\n{\n IsDeleted = false;\n DeletedAt = null;\n DeletedBy = null;\n UpdatedAt = DateTime.UtcNow;\n UpdatedBy = restoredBy;\n}\n\\`\\`\\`\n\n### History Tables (JSON Pattern)\n\n\\`\\`\\`csharp\npublic interface IHistoryEntity<TSourceId>\n{\n Guid Id { get; set; }\n TSourceId SourceId { get; set; }\n ChangeType ChangeType { get; set; } // Created, Updated, Deleted\n DateTime ChangedAt { get; set; }\n string? ChangedBy { get; set; }\n string? OldValues { get; set; } // JSON snapshot before change\n string? NewValues { get; set; } // JSON snapshot after change\n}\n\npublic enum ChangeType { Created = 1, Updated = 2, Deleted = 3 }\n\\`\\`\\`\n\n### Complete Entity Example\n\n\\`\\`\\`csharp\npublic class MyEntity : BaseEntity\n{\n // === REQUIRED (from BaseEntity) ===\n // public Guid Id { get; set; }\n // public Guid TenantId { get; set; }\n // public string Code { get; set; } // lowercase, unique per tenant\n // public DateTime CreatedAt { get; set; }\n // public DateTime? UpdatedAt { get; set; }\n // public string? CreatedBy { get; set; }\n // public string? UpdatedBy { get; set; }\n // public bool IsDeleted { get; set; }\n // public DateTime? DeletedAt { get; set; }\n // public string? DeletedBy { get; set; }\n // public byte[] RowVersion { get; set; }\n\n // === BUSINESS PROPERTIES ===\n public string Name { get; private set; } = null!;\n\n private MyEntity() { }\n\n public static MyEntity Create(Guid tenantId, string code, string name, string? createdBy = null)\n {\n return new MyEntity\n {\n Id = Guid.NewGuid(),\n TenantId = tenantId,\n Code = code.ToLowerInvariant(),\n Name = name,\n CreatedAt = DateTime.UtcNow,\n CreatedBy = createdBy\n };\n }\n}\n\\`\\`\\`\n\n### EF Core Configuration\n\n\\`\\`\\`csharp\npublic class MyEntityConfiguration : IEntityTypeConfiguration<MyEntity>\n{\n public void Configure(EntityTypeBuilder<MyEntity> builder)\n {\n builder.ToTable(\"domain_MyEntities\", \"${schemas.platform}\");\n builder.HasKey(e => e.Id);\n\n // Multi-tenant\n builder.Property(e => e.TenantId).IsRequired();\n builder.HasIndex(e => e.TenantId);\n\n // Code: lowercase, unique per tenant (filtered)\n builder.Property(e => e.Code).HasMaxLength(100).IsRequired();\n builder.HasIndex(e => new { e.TenantId, e.Code })\n .IsUnique()\n .HasFilter(\"[IsDeleted] = 0\");\n\n // Concurrency\n builder.Property(e => e.RowVersion).IsRowVersion();\n\n // Audit fields\n builder.Property(e => e.CreatedBy).HasMaxLength(256);\n builder.Property(e => e.UpdatedBy).HasMaxLength(256);\n builder.Property(e => e.DeletedBy).HasMaxLength(256);\n }\n}\n\\`\\`\\`\n\n### Entity Types Summary\n\n| Type | Fields | Use Case |\n|------|--------|----------|\n| **BaseEntity** | All required fields | Standard tenant-scoped entities |\n| **SystemEntity** | All except TenantId | Shared system entities |\n| **HistoryEntity** | Id, TenantId, SourceId, ChangeType, Values, ChangedAt/By | Audit trail tables |\n\n---\n\n## 8. Multi-Tenant Architecture\n\n### Overview\n\nSmartStack implements a comprehensive multi-tenant architecture where:\n- **Platform scope**: Users with roles via \\`UserRole\\` (no tenant) see ALL tenants\n- **Tenant scope**: Users with roles via \\`TenantUserRole\\` see ONLY their tenant\n\n### Tenant Model\n\n\\`\\`\\`\nLicense (1) ──────► (N) Tenant\n │\n ├──► (1:1) Organisation (if B2B)\n │\n └──► (N) TenantUser ──► (N) TenantUserRole\n │\n └──► User (global)\n\\`\\`\\`\n\n### Core Entities\n\n#### Tenant\n\n| Field | Type | Description |\n|-------|------|-------------|\n| \\`Id\\` | Guid | Primary key |\n| \\`LicenseId\\` | Guid (FK) | Link to License (features & limits) |\n| \\`Slug\\` | string? | Optional vanity URL (unique, lowercase, alphanum + hyphen) |\n| \\`Name\\` | string | Display name |\n| \\`Type\\` | enum | B2B (with Organisation) or B2C |\n| \\`Status\\` | enum | Active, Suspended, Deleted |\n| \\`CreatedBy\\` | Guid (FK) | User who created the tenant |\n| \\`CreatedAt\\` | DateTime | Creation timestamp |\n\n\\`\\`\\`csharp\npublic class Tenant : SystemEntity\n{\n public Guid LicenseId { get; private set; }\n public License License { get; private set; }\n\n public string? Slug { get; private set; } // Vanity URL (optional)\n public string Name { get; private set; }\n public TenantType Type { get; private set; }\n public TenantStatus Status { get; private set; }\n\n public Guid CreatedBy { get; private set; }\n public User Creator { get; private set; }\n\n // Navigation\n public ICollection<TenantUser> TenantUsers { get; private set; }\n public Organisation? Organisation { get; private set; } // If B2B\n}\n\npublic enum TenantType { B2B = 1, B2C = 2 }\npublic enum TenantStatus { Active = 1, Suspended = 2, Deleted = 3 }\n\\`\\`\\`\n\n#### TenantUser\n\nLinks a User to a Tenant with membership metadata.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| \\`Id\\` | Guid | Primary key |\n| \\`TenantId\\` | Guid (FK) | **NOT NULL** - Tenant reference |\n| \\`UserId\\` | Guid (FK) | User reference |\n| \\`IsDefault\\` | bool | Default tenant for this user (unique per user) |\n| \\`Status\\` | enum | Pending, Active, Revoked |\n| \\`JoinedAt\\` | DateTime | When user joined tenant |\n\n\\`\\`\\`csharp\npublic class TenantUser\n{\n public Guid Id { get; private set; }\n public Guid TenantId { get; private set; } // NOT NULL\n public Tenant Tenant { get; private set; }\n\n public Guid UserId { get; private set; }\n public User User { get; private set; }\n\n public bool IsDefault { get; private set; }\n public TenantUserStatus Status { get; private set; }\n public DateTime JoinedAt { get; private set; }\n\n // Roles within this tenant\n public ICollection<TenantUserRole> Roles { get; private set; }\n}\n\npublic enum TenantUserStatus { Pending = 1, Active = 2, Revoked = 3 }\n\\`\\`\\`\n\n#### TenantUserRole\n\nAssigns roles to a user within a specific tenant.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| \\`TenantUserId\\` | Guid (FK) | TenantUser reference |\n| \\`RoleId\\` | Guid (FK) | Role reference |\n| \\`AssignedAt\\` | DateTime | When role was assigned |\n| \\`AssignedBy\\` | string? | Who assigned the role |\n\n\\`\\`\\`csharp\npublic class TenantUserRole\n{\n public Guid TenantUserId { get; private set; }\n public TenantUser TenantUser { get; private set; }\n\n public Guid RoleId { get; private set; }\n public Role Role { get; private set; }\n\n public DateTime AssignedAt { get; private set; }\n public string? AssignedBy { get; private set; }\n}\n\\`\\`\\`\n\n#### TenantInvitation\n\nManages user invitations to a tenant.\n\n| Field | Type | Description |\n|-------|------|-------------|\n| \\`Id\\` | Guid | Primary key |\n| \\`TenantId\\` | Guid (FK) | Target tenant |\n| \\`Email\\` | string | Invited email address |\n| \\`RoleId\\` | Guid (FK) | Role to assign on acceptance |\n| \\`Token\\` | string | Unique invitation token |\n| \\`ExpiresAt\\` | DateTime | Token expiration |\n| \\`Status\\` | enum | Pending, Accepted, Expired, Revoked |\n| \\`InvitedBy\\` | Guid (FK) | User who sent invitation |\n| \\`InvitedAt\\` | DateTime | Invitation timestamp |\n\n\\`\\`\\`csharp\npublic class TenantInvitation\n{\n public Guid Id { get; private set; }\n public Guid TenantId { get; private set; }\n public Tenant Tenant { get; private set; }\n\n public string Email { get; private set; }\n public Guid RoleId { get; private set; }\n public Role Role { get; private set; }\n\n public string Token { get; private set; }\n public DateTime ExpiresAt { get; private set; }\n public TenantInvitationStatus Status { get; private set; }\n\n public Guid InvitedBy { get; private set; }\n public User Inviter { get; private set; }\n public DateTime InvitedAt { get; private set; }\n}\n\npublic enum TenantInvitationStatus { Pending = 1, Accepted = 2, Expired = 3, Revoked = 4 }\n\\`\\`\\`\n\n### Access Control Matrix\n\n| Role Source | Scope | Description |\n|-------------|-------|-------------|\n| \\`UserRole\\` (existing) | Platform | Roles WITHOUT tenant → sees ALL tenants |\n| \\`TenantUserRole\\` (new) | Tenant | Roles WITH tenant → sees ONLY that tenant |\n\n**Examples:**\n\n\\`\\`\\`\nUserRole: UserId=1, RoleId=PlatformAdmin → User 1 sees ALL tenants\nUserRole: UserId=2, RoleId=PlatformReader → User 2 reads ALL tenants\n\nTenantUserRole: TenantUserId=3, RoleId=Admin → User 3 is Admin of Tenant A only\nTenantUserRole: TenantUserId=4, RoleId=User → User 4 is User of Tenant A only\n\\`\\`\\`\n\n### Organisation (B2B Extension)\n\nOrganisation is a 1:1 extension of Tenant for B2B scenarios:\n\n\\`\\`\\`csharp\npublic class Organisation : BaseEntity\n{\n public Guid TenantId { get; private set; } // FK to Tenant\n public Tenant Tenant { get; private set; }\n\n // Organisation-specific fields\n public string LegalName { get; private set; }\n public string? VatNumber { get; private set; }\n public string? Address { get; private set; }\n // ... other B2B fields\n}\n\\`\\`\\`\n\n### License Integration\n\nFeatures and limits are managed via License:\n\n\\`\\`\\`csharp\n// License.LimitsJson example\n{\n \"max_users\": 100,\n \"max_tenants\": 5,\n \"max_storage_gb\": 50\n}\n\n// Check in service\npublic async Task<bool> CanCreateTenantAsync(Guid licenseId)\n{\n var license = await _licenseService.GetAsync(licenseId);\n var limits = JsonSerializer.Deserialize<LicenseLimits>(license.LimitsJson);\n var currentTenants = await _tenantRepo.CountByLicenseAsync(licenseId);\n return currentTenants < limits.MaxTenants;\n}\n\\`\\`\\`\n\n### URL Routing\n\nTenant identification in URLs:\n\n| Pattern | Example | Use Case |\n|---------|---------|----------|\n| GUID (default) | \\`/{tenant-guid}/api/...\\` | Always works, secure |\n| Slug (optional) | \\`/{slug}/api/...\\` | Vanity URL for premium clients |\n\n\\`\\`\\`csharp\n// Middleware resolution priority\n1. Extract from URL path (/{tenant-identifier}/...)\n2. Check if GUID → resolve directly\n3. Check if Slug → resolve by slug\n4. Fallback to user's default tenant (IsDefault=true)\n\\`\\`\\`\n\n### Audit Trail\n\nCritical tables have history tracking:\n\n- \\`TenantUserHistory\\` - tracks membership changes\n- \\`TenantUserRoleHistory\\` - tracks role assignment changes\n\n\\`\\`\\`csharp\npublic class TenantUserHistory : IHistoryEntity<Guid>\n{\n public Guid Id { get; set; }\n public Guid SourceId { get; set; } // TenantUser.Id\n public ChangeType ChangeType { get; set; }\n public string? OldValues { get; set; } // JSON\n public string? NewValues { get; set; } // JSON\n public DateTime ChangedAt { get; set; }\n public string? ChangedBy { get; set; }\n}\n\\`\\`\\`\n\n### Database Constraints\n\n\\`\\`\\`sql\n-- Tenant slug unique (if set)\nCREATE UNIQUE INDEX IX_Tenant_Slug ON tenant_Tenants(Slug) WHERE Slug IS NOT NULL;\n\n-- Only one default tenant per user\nCREATE UNIQUE INDEX IX_TenantUser_IsDefault\nON tenant_TenantUsers(UserId) WHERE IsDefault = 1;\n\n-- Composite key for TenantUserRole\nALTER TABLE tenant_TenantUserRoles\nADD CONSTRAINT PK_TenantUserRole PRIMARY KEY (TenantUserId, RoleId);\n\\`\\`\\`\n\n### Table Prefix\n\nAll tenant-related tables use the \\`tenant_\\` prefix:\n\n| Table | Prefix |\n|-------|--------|\n| Tenants | \\`tenant_Tenants\\` |\n| TenantUsers | \\`tenant_TenantUsers\\` |\n| TenantUserRoles | \\`tenant_TenantUserRoles\\` |\n| TenantInvitations | \\`tenant_TenantInvitations\\` |\n| TenantUserHistory | \\`tenant_TenantUserHistory\\` |\n| TenantUserRoleHistory | \\`tenant_TenantUserRoleHistory\\` |\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| Core code prefix | \\`${codePrefixes.core}\\` | \\`${codePrefixes.core}administration\\` |\n| Extension code prefix | \\`${codePrefixes.extension}\\` | \\`${codePrefixes.extension}custom_module\\` |\n| Migration | \\`{context}_v{version}_{seq}_{Desc}\\` | \\`core_v1.0.0_001_CreateAuthUsers\\` |\n| Interface | \\`I<Name>Service\\` | \\`IUserService\\` |\n| Implementation | \\`<Name>Service\\` | \\`UserService\\` |\n| Domain namespace | \\`${namespaces.domain}\\` | - |\n| API namespace | \\`${namespaces.api}\\` | - |\n| Required entity fields | Id, TenantId, Code, Audit, SoftDelete, RowVersion | See Entity Conventions |\n| Tenant prefix | \\`tenant_\\` | \\`tenant_Tenants\\`, \\`tenant_TenantUsers\\` |\n| Platform roles | \\`UserRole\\` | No TenantId → sees ALL tenants |\n| Tenant roles | \\`TenantUserRole\\` | With TenantId → sees ONLY that tenant |\n| License:Tenant | 1:N | One License can have multiple Tenants |\n| Dry-run scaffold | \\`dryRun: true\\` | Preview generated code without writing |\n| Tenant-aware entity | \\`ITenantEntity\\` | Default for scaffold_extension |\n| System entity | \\`isSystemEntity: true\\` | No TenantId, platform-level |\n| Full-stack scaffold | \\`type: \"feature\"\\` | Entity + DTOs + Validators + Repository + Service + Controller + Component |\n| Client extension | \\`clientExtension: true\\` | Auto-sets schema=extensions + prefix=ext_ |\n| Unit tests | \\`type: \"test\"\\` | xUnit tests with Moq & FluentAssertions |\n| DTOs generation | \\`withDtos: true\\` | Create, Update, Response DTOs |\n| Validation | \\`withValidation: true\\` | FluentValidation validators |\n| Repository | \\`withRepository: true\\` | Interface + Implementation |\n| Migration naming | \\`suggest_migration\\` | {context}_v{version}_{seq}_{Desc} |\n\n---\n\n## 9. MCP Tools & Resources\n\n### Available Tools\n\n| Tool | Description |\n|------|-------------|\n| \\`scaffold_extension\\` | Generate code: feature (full-stack), entity, service, controller, component, dto, validator, repository, or test |\n| \\`validate_conventions\\` | Validate SmartStack conventions compliance |\n| \\`check_migrations\\` | Analyze EF Core migrations for conflicts |\n| \\`api_docs\\` | Get API documentation from Swagger/Controllers with examples |\n| \\`suggest_migration\\` | Suggest migration name following conventions |\n\n### Available Resources\n\n| URI | Description |\n|-----|-------------|\n| \\`smartstack://conventions\\` | This documentation |\n| \\`smartstack://project\\` | Project structure information |\n| \\`smartstack://entities\\` | Quick reference of all domain entities |\n| \\`smartstack://entities/{filter}\\` | Filtered entity list by name/prefix |\n| \\`smartstack://schema\\` | Database schema information |\n| \\`smartstack://api\\` | API endpoints documentation |\n\n### Scaffold Extension\n\nGenerate tenant-aware code by default:\n\n**Type Options:**\n\n| Type | Description | Generated Files |\n|------|-------------|-----------------|\n| \\`feature\\` | **Full-stack generation** | Entity + DTOs + Validators + Repository + Service + Controller + Component |\n| \\`entity\\` | Domain entity only | Entity class + EF Configuration |\n| \\`dto\\` | DTOs only | Create, Update, Response DTOs |\n| \\`validator\\` | Validators only | FluentValidation validators |\n| \\`repository\\` | Repository only | Interface + Implementation |\n| \\`service\\` | Service layer only | Interface + Implementation |\n| \\`controller\\` | API controller only | REST Controller |\n| \\`component\\` | React component only | Component + Hook + Types |\n| \\`test\\` | Unit tests only | xUnit tests with Moq |\n\n#### Full-Stack Feature (Recommended)\n\nGenerate all layers in one command:\n\n\\`\\`\\`json\n// Complete feature: Entity → Service → Controller → Component\n{\n \"type\": \"feature\",\n \"name\": \"Product\",\n \"options\": {\n \"tablePrefix\": \"ref_\",\n \"dryRun\": true, // Preview first\n \"withTests\": true // Include unit tests\n }\n}\n\n// Client extension (uses 'extensions' schema + 'ext_' prefix)\n{\n \"type\": \"feature\",\n \"name\": \"CustomReport\",\n \"options\": {\n \"clientExtension\": true, // Auto-sets schema + prefix\n \"skipController\": true // Skip API, React-only\n }\n}\n\\`\\`\\`\n\n#### Individual Types\n\n\\`\\`\\`json\n// Entity (default: tenant-aware with ITenantEntity)\n{\n \"type\": \"entity\",\n \"name\": \"Product\",\n \"options\": {\n \"tablePrefix\": \"ref_\",\n \"dryRun\": true // Preview without writing files\n }\n}\n\n// System entity (no TenantId)\n{\n \"type\": \"entity\",\n \"name\": \"GlobalConfig\",\n \"options\": {\n \"isSystemEntity\": true,\n \"tablePrefix\": \"cfg_\"\n }\n}\n\n// Unit tests for a service\n{\n \"type\": \"test\",\n \"name\": \"Product\"\n}\n\\`\\`\\`\n\n**Common Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| \\`dryRun\\` | boolean | false | Preview generated code without writing files |\n| \\`isSystemEntity\\` | boolean | false | Create system entity (no TenantId) |\n| \\`tablePrefix\\` | string | \"ref_\" | Domain prefix for table name |\n| \\`schema\\` | string | \"core\" | Database schema (\"core\" or \"extensions\") |\n| \\`namespace\\` | string | auto | Custom namespace |\n| \\`baseEntity\\` | string | - | Base entity to extend |\n\n**Feature-Specific Options:**\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| \\`clientExtension\\` | boolean | false | Use 'extensions' schema + 'ext_' prefix |\n| \\`skipService\\` | boolean | false | Skip service layer generation |\n| \\`skipController\\` | boolean | false | Skip API controller generation |\n| \\`skipComponent\\` | boolean | false | Skip React component generation |\n| \\`withTests\\` | boolean | false | Generate unit tests (xUnit + Moq) |\n| \\`withDtos\\` | boolean | false | Generate DTOs (Create, Update, Response) |\n| \\`withValidation\\` | boolean | false | Generate FluentValidation validators |\n| \\`withRepository\\` | boolean | false | Generate repository pattern |\n| \\`entityProperties\\` | array | - | Define entity properties for DTOs |\n\n### Suggest Migration\n\nGenerate migration names following conventions:\n\n\\`\\`\\`json\n{\n \"description\": \"Add User Profiles\",\n \"context\": \"core\", // optional: core or extensions\n \"version\": \"1.2.0\" // optional: auto-detected from existing\n}\n\\`\\`\\`\n\nOutput: \\`core_v1.2.0_001_AddUserProfiles\\`\n\n### Validate Conventions\n\nRun specific or all checks:\n\n\\`\\`\\`json\n{\n \"checks\": [\"tables\", \"migrations\", \"services\", \"namespaces\", \"entities\", \"tenants\"]\n}\n\\`\\`\\`\n\n**Check Types:**\n\n| Check | Validates |\n|-------|-----------|\n| \\`tables\\` | Schema specification, domain prefixes |\n| \\`migrations\\` | Naming convention, version ordering |\n| \\`services\\` | Interface implementation pattern |\n| \\`namespaces\\` | Layer namespace structure |\n| \\`entities\\` | BaseEntity/SystemEntity inheritance, factory methods |\n| \\`tenants\\` | ITenantEntity implementation, TenantId consistency |\n`;\n}","import { Resource } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\nimport { detectProject, findSmartStackStructure } from '../lib/detector.js';\nimport { findFiles } from '../utils/fs.js';\nimport path from 'path';\n\nexport const projectInfoResourceTemplate: Resource = {\n uri: 'smartstack://project',\n name: 'SmartStack Project Info',\n description: 'Current SmartStack project information, structure, and configuration',\n mimeType: 'text/markdown',\n};\n\nexport async function getProjectInfoResource(config: Config): Promise<string> {\n const projectPath = config.smartstack.projectPath;\n const projectInfo = await detectProject(projectPath);\n const structure = await findSmartStackStructure(projectPath);\n\n const lines: string[] = [];\n\n lines.push('# SmartStack Project Information');\n lines.push('');\n lines.push('## Overview');\n lines.push('');\n lines.push(`| Property | Value |`);\n lines.push(`|----------|-------|`);\n lines.push(`| **Name** | ${projectInfo.name} |`);\n lines.push(`| **Version** | ${projectInfo.version} |`);\n lines.push(`| **Path** | \\`${projectPath}\\` |`);\n lines.push(`| **Git Repository** | ${projectInfo.isGitRepo ? 'Yes' : 'No'} |`);\n if (projectInfo.currentBranch) {\n lines.push(`| **Current Branch** | \\`${projectInfo.currentBranch}\\` |`);\n }\n lines.push(`| **.NET Project** | ${projectInfo.hasDotNet ? 'Yes' : 'No'} |`);\n lines.push(`| **EF Core** | ${projectInfo.hasEfCore ? 'Yes' : 'No'} |`);\n if (projectInfo.dbContextName) {\n lines.push(`| **DbContext** | \\`${projectInfo.dbContextName}\\` |`);\n }\n lines.push(`| **React Frontend** | ${projectInfo.hasReact ? 'Yes' : 'No'} |`);\n lines.push('');\n\n // Project Structure\n lines.push('## Project Structure');\n lines.push('');\n lines.push('```');\n lines.push(`${projectInfo.name}/`);\n if (structure.domain) {\n lines.push(`├── ${path.basename(structure.domain)}/ # Domain layer (entities)`);\n }\n if (structure.application) {\n lines.push(`├── ${path.basename(structure.application)}/ # Application layer (services)`);\n }\n if (structure.infrastructure) {\n lines.push(`├── ${path.basename(structure.infrastructure)}/ # Infrastructure (EF Core)`);\n }\n if (structure.api) {\n lines.push(`├── ${path.basename(structure.api)}/ # API layer (controllers)`);\n }\n if (structure.web) {\n lines.push(`└── web/smartstack-web/ # React frontend`);\n }\n lines.push('```');\n lines.push('');\n\n // .NET Projects\n if (projectInfo.csprojFiles.length > 0) {\n lines.push('## .NET Projects');\n lines.push('');\n lines.push('| Project | Path |');\n lines.push('|---------|------|');\n for (const csproj of projectInfo.csprojFiles) {\n const name = path.basename(csproj, '.csproj');\n const relativePath = path.relative(projectPath, csproj);\n lines.push(`| ${name} | \\`${relativePath}\\` |`);\n }\n lines.push('');\n }\n\n // Migrations info\n if (structure.migrations) {\n const migrationFiles = await findFiles('*.cs', {\n cwd: structure.migrations,\n ignore: ['*.Designer.cs'],\n });\n\n const migrations = migrationFiles\n .map(f => path.basename(f))\n .filter(f => !f.includes('ModelSnapshot') && !f.includes('.Designer.'))\n .sort();\n\n lines.push('## EF Core Migrations');\n lines.push('');\n lines.push(`**Location**: \\`${path.relative(projectPath, structure.migrations)}\\``);\n lines.push(`**Total Migrations**: ${migrations.length}`);\n lines.push('');\n\n if (migrations.length > 0) {\n lines.push('### Recent Migrations');\n lines.push('');\n const recent = migrations.slice(-5);\n for (const migration of recent) {\n lines.push(`- \\`${migration.replace('.cs', '')}\\``);\n }\n lines.push('');\n }\n }\n\n // Configuration\n lines.push('## Configuration');\n lines.push('');\n lines.push('### MCP Server Config');\n lines.push('');\n lines.push('```json');\n lines.push(JSON.stringify({\n smartstack: config.smartstack,\n conventions: {\n schemas: config.conventions.schemas,\n tablePrefixes: config.conventions.tablePrefixes,\n migrationFormat: config.conventions.migrationFormat,\n },\n }, null, 2));\n lines.push('```');\n lines.push('');\n\n // Quick Commands\n lines.push('## Quick Commands');\n lines.push('');\n lines.push('```bash');\n lines.push('# Build the solution');\n lines.push('dotnet build');\n lines.push('');\n lines.push('# Run API');\n lines.push(`cd ${structure.api ? path.relative(projectPath, structure.api) : 'SmartStack.Api'}`);\n lines.push('dotnet run');\n lines.push('');\n lines.push('# Run frontend');\n lines.push(`cd ${structure.web ? path.relative(projectPath, structure.web) : 'web/smartstack-web'}`);\n lines.push('npm run dev');\n lines.push('');\n lines.push('# Create migration');\n lines.push('dotnet ef migrations add YYYYMMDD_Core_NNN_Description');\n lines.push('');\n lines.push('# Apply migrations');\n lines.push('dotnet ef database update');\n lines.push('```');\n lines.push('');\n\n // MCP Tools Available\n lines.push('## Available MCP Tools');\n lines.push('');\n lines.push('| Tool | Description |');\n lines.push('|------|-------------|');\n lines.push('| `validate_conventions` | Check code against AtlasHub conventions |');\n lines.push('| `check_migrations` | Analyze EF Core migrations for conflicts |');\n lines.push('| `scaffold_extension` | Generate service, entity, controller, or component |');\n lines.push('| `api_docs` | Get API endpoint documentation |');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\nimport { findControllerFiles, findSmartStackStructure } from '../lib/detector.js';\nimport { readText } from '../utils/fs.js';\nimport path from 'path';\n\nexport const apiEndpointsResourceTemplate: Resource = {\n uri: 'smartstack://api/',\n name: 'SmartStack API Endpoints',\n description: 'API endpoint documentation. Use smartstack://api/{endpoint} to filter.',\n mimeType: 'text/markdown',\n};\n\ninterface ParsedEndpoint {\n method: string;\n path: string;\n controller: string;\n action: string;\n parameters: string[];\n returnType: string;\n authorize: boolean;\n summary?: string;\n}\n\nexport async function getApiEndpointsResource(\n config: Config,\n endpointFilter?: string\n): Promise<string> {\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n if (!structure.api) {\n return '# API Endpoints\\n\\nNo API project found.';\n }\n\n const controllerFiles = await findControllerFiles(structure.api);\n const allEndpoints: ParsedEndpoint[] = [];\n\n for (const file of controllerFiles) {\n const endpoints = await parseController(file, structure.root);\n allEndpoints.push(...endpoints);\n }\n\n // Filter if specified\n const endpoints = endpointFilter\n ? allEndpoints.filter(e =>\n e.path.toLowerCase().includes(endpointFilter.toLowerCase()) ||\n e.controller.toLowerCase().includes(endpointFilter.toLowerCase())\n )\n : allEndpoints;\n\n return formatEndpoints(endpoints, endpointFilter);\n}\n\nasync function parseController(filePath: string, _rootPath: string): Promise<ParsedEndpoint[]> {\n const content = await readText(filePath);\n const fileName = path.basename(filePath, '.cs');\n const controllerName = fileName.replace('Controller', '');\n const endpoints: ParsedEndpoint[] = [];\n\n // Parse class-level route\n const routeMatch = content.match(/\\[Route\\s*\\(\\s*\"([^\"]+)\"\\s*\\)\\]/);\n const baseRoute = routeMatch\n ? routeMatch[1].replace('[controller]', controllerName.toLowerCase())\n : `/api/${controllerName.toLowerCase()}`;\n\n // Check for class-level Authorize\n const classAuthorize = /\\[Authorize\\s*(?:\\([^)]*\\))?\\s*\\]\\s*(?:\\[.*\\]\\s*)*public\\s+class/.test(content);\n\n // Simple approach: find all HTTP method attributes\n const httpMethods = ['HttpGet', 'HttpPost', 'HttpPut', 'HttpPatch', 'HttpDelete'];\n let match: RegExpExecArray | null;\n\n for (const httpMethod of httpMethods) {\n const regex = new RegExp(\n `\\\\[${httpMethod}(?:\\\\s*\\\\(\\\\s*\"([^\"]*)\"\\\\s*\\\\))?\\\\]\\\\s*(?:\\\\[.*?\\\\]\\\\s*)*public\\\\s+(?:async\\\\s+)?(?:Task<)?(?:ActionResult<)?(\\\\w+)(?:[<>\\\\[\\\\],\\\\s\\\\w]*)?\\\\s+(\\\\w+)\\\\s*\\\\(([^)]*)\\\\)`,\n 'g'\n );\n\n while ((match = regex.exec(content)) !== null) {\n const routeSuffix = match[1] || '';\n const returnType = match[2];\n const actionName = match[3];\n const params = match[4];\n\n // Build full path\n let fullPath = baseRoute;\n if (routeSuffix) {\n fullPath = `${baseRoute}/${routeSuffix}`;\n }\n\n // Parse parameters\n const parameters = parseParameters(params);\n\n // Check for method-level authorize\n const methodAuthorize = content.substring(Math.max(0, match.index - 200), match.index)\n .includes('[Authorize');\n\n endpoints.push({\n method: httpMethod.replace('Http', '').toUpperCase(),\n path: fullPath.replace(/\\/+/g, '/'),\n controller: controllerName,\n action: actionName,\n parameters,\n returnType,\n authorize: classAuthorize || methodAuthorize,\n });\n }\n }\n\n return endpoints;\n}\n\nfunction parseParameters(paramsString: string): string[] {\n if (!paramsString.trim()) return [];\n\n const params: string[] = [];\n const parts = paramsString.split(',');\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed) continue;\n\n // Extract parameter name\n const match = trimmed.match(/(\\w+)\\s*(?:=.*)?$/);\n if (match) {\n // Include source attribute if present\n if (trimmed.includes('[FromBody]')) {\n params.push(`body: ${match[1]}`);\n } else if (trimmed.includes('[FromQuery]')) {\n params.push(`query: ${match[1]}`);\n } else if (trimmed.includes('[FromRoute]')) {\n params.push(`route: ${match[1]}`);\n } else {\n params.push(match[1]);\n }\n }\n }\n\n return params;\n}\n\nfunction formatEndpoints(endpoints: ParsedEndpoint[], filter?: string): string {\n const lines: string[] = [];\n\n lines.push('# SmartStack API Endpoints');\n lines.push('');\n\n if (filter) {\n lines.push(`> Filtered by: \\`${filter}\\``);\n lines.push('');\n }\n\n if (endpoints.length === 0) {\n lines.push('No endpoints found matching the criteria.');\n return lines.join('\\n');\n }\n\n // Group by controller\n const byController = new Map<string, ParsedEndpoint[]>();\n for (const endpoint of endpoints) {\n const existing = byController.get(endpoint.controller) || [];\n existing.push(endpoint);\n byController.set(endpoint.controller, existing);\n }\n\n // Summary table\n lines.push('## Summary');\n lines.push('');\n lines.push(`**Total Endpoints**: ${endpoints.length}`);\n lines.push(`**Controllers**: ${byController.size}`);\n lines.push('');\n\n // Method distribution\n const methodCounts = new Map<string, number>();\n for (const endpoint of endpoints) {\n methodCounts.set(endpoint.method, (methodCounts.get(endpoint.method) || 0) + 1);\n }\n\n lines.push('| Method | Count |');\n lines.push('|--------|-------|');\n for (const [method, count] of methodCounts) {\n lines.push(`| ${method} | ${count} |`);\n }\n lines.push('');\n\n // Detailed by controller\n for (const [controller, controllerEndpoints] of byController) {\n lines.push(`## ${controller}Controller`);\n lines.push('');\n\n // Sort by path then method\n controllerEndpoints.sort((a, b) => {\n const pathCompare = a.path.localeCompare(b.path);\n if (pathCompare !== 0) return pathCompare;\n return a.method.localeCompare(b.method);\n });\n\n for (const endpoint of controllerEndpoints) {\n const authBadge = endpoint.authorize ? ' 🔒' : '';\n const methodColor = getMethodEmoji(endpoint.method);\n\n lines.push(`### ${methodColor} \\`${endpoint.method}\\` ${endpoint.path}${authBadge}`);\n lines.push('');\n lines.push(`**Action**: \\`${endpoint.action}\\``);\n lines.push(`**Returns**: \\`${endpoint.returnType}\\``);\n\n if (endpoint.parameters.length > 0) {\n lines.push('');\n lines.push('**Parameters**:');\n for (const param of endpoint.parameters) {\n lines.push(`- \\`${param}\\``);\n }\n }\n\n lines.push('');\n }\n }\n\n // Quick reference table\n lines.push('## Quick Reference');\n lines.push('');\n lines.push('| Method | Path | Action | Auth |');\n lines.push('|--------|------|--------|------|');\n for (const endpoint of endpoints) {\n lines.push(\n `| ${endpoint.method} | \\`${endpoint.path}\\` | ${endpoint.action} | ${endpoint.authorize ? '🔒' : '✓'} |`\n );\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction getMethodEmoji(method: string): string {\n switch (method) {\n case 'GET': return '🔵';\n case 'POST': return '🟢';\n case 'PUT': return '🟡';\n case 'PATCH': return '🟠';\n case 'DELETE': return '🔴';\n default: return '⚪';\n }\n}\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\nimport { findSmartStackStructure, findEntityFiles } from '../lib/detector.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport path from 'path';\n\nexport const dbSchemaResourceTemplate: Resource = {\n uri: 'smartstack://schema/',\n name: 'SmartStack Database Schema',\n description: 'Database schema information. Use smartstack://schema/{table} to get specific table.',\n mimeType: 'text/markdown',\n};\n\ninterface EntityInfo {\n name: string;\n tableName: string;\n properties: PropertyInfo[];\n relationships: RelationshipInfo[];\n file: string;\n}\n\ninterface PropertyInfo {\n name: string;\n type: string;\n nullable: boolean;\n isPrimaryKey: boolean;\n maxLength?: number;\n}\n\ninterface RelationshipInfo {\n type: 'one-to-one' | 'one-to-many' | 'many-to-many';\n targetEntity: string;\n propertyName: string;\n}\n\nexport async function getDbSchemaResource(\n config: Config,\n tableFilter?: string\n): Promise<string> {\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n if (!structure.domain && !structure.infrastructure) {\n return '# Database Schema\\n\\nNo domain or infrastructure project found.';\n }\n\n const entities: EntityInfo[] = [];\n\n // Parse entities from domain layer\n if (structure.domain) {\n const entityFiles = await findEntityFiles(structure.domain);\n for (const file of entityFiles) {\n const entity = await parseEntity(file, structure.root, config);\n if (entity) {\n entities.push(entity);\n }\n }\n }\n\n // Parse configurations from infrastructure layer for additional info\n if (structure.infrastructure) {\n await enrichFromConfigurations(entities, structure.infrastructure, config);\n }\n\n // Filter if specified\n const filteredEntities = tableFilter\n ? entities.filter(e =>\n e.name.toLowerCase().includes(tableFilter.toLowerCase()) ||\n e.tableName.toLowerCase().includes(tableFilter.toLowerCase())\n )\n : entities;\n\n return formatSchema(filteredEntities, tableFilter, config);\n}\n\nasync function parseEntity(\n filePath: string,\n rootPath: string,\n _config: Config\n): Promise<EntityInfo | null> {\n const content = await readText(filePath);\n\n // Find class declaration\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*(\\w+))?/);\n if (!classMatch) return null;\n\n const entityName = classMatch[1];\n\n // Skip non-entity classes\n if (entityName.endsWith('Dto') || entityName.endsWith('Command') ||\n entityName.endsWith('Query') || entityName.endsWith('Handler')) {\n return null;\n }\n\n const properties: PropertyInfo[] = [];\n const relationships: RelationshipInfo[] = [];\n\n // Parse properties\n const propertyPattern = /public\\s+(?:required\\s+)?(\\w+(?:<[\\w,\\s]+>)?)\\??\\s+(\\w+)\\s*\\{/g;\n let match;\n\n while ((match = propertyPattern.exec(content)) !== null) {\n const propertyType = match[1];\n const propertyName = match[2];\n\n // Skip navigation properties for now (we'll add them as relationships)\n if (propertyType.startsWith('ICollection') || propertyType.startsWith('List')) {\n // This is a collection navigation property\n const targetMatch = propertyType.match(/<(\\w+)>/);\n if (targetMatch) {\n relationships.push({\n type: 'one-to-many',\n targetEntity: targetMatch[1],\n propertyName,\n });\n }\n continue;\n }\n\n // Check if it's a reference navigation property\n const isNavigationProperty = /^[A-Z]/.test(propertyType) &&\n !['Guid', 'String', 'Int32', 'Int64', 'DateTime', 'DateTimeOffset',\n 'Boolean', 'Decimal', 'Double', 'Float', 'Byte'].includes(propertyType) &&\n !propertyType.includes('?');\n\n if (isNavigationProperty && !propertyType.includes('<')) {\n relationships.push({\n type: 'one-to-one',\n targetEntity: propertyType,\n propertyName,\n });\n continue;\n }\n\n properties.push({\n name: propertyName,\n type: mapCSharpType(propertyType),\n nullable: content.includes(`${propertyType}? ${propertyName}`) ||\n content.includes(`${propertyType}? ${propertyName}`),\n isPrimaryKey: propertyName === 'Id' || propertyName === `${entityName}Id`,\n });\n }\n\n // Default table name based on conventions (using cfg_ as default prefix for generic configs)\n const tableName = `cfg_${entityName}s`;\n\n return {\n name: entityName,\n tableName,\n properties,\n relationships,\n file: path.relative(rootPath, filePath),\n };\n}\n\nasync function enrichFromConfigurations(\n entities: EntityInfo[],\n infrastructurePath: string,\n _config: Config\n): Promise<void> {\n const configFiles = await findFiles('**/Configurations/**/*.cs', {\n cwd: infrastructurePath,\n });\n\n for (const file of configFiles) {\n const content = await readText(file);\n\n // Find ToTable calls\n const tableMatch = content.match(/\\.ToTable\\s*\\(\\s*\"([^\"]+)\"/);\n if (tableMatch) {\n // Find which entity this configuration is for\n const entityMatch = content.match(/IEntityTypeConfiguration<(\\w+)>/);\n if (entityMatch) {\n const entityName = entityMatch[1];\n const entity = entities.find(e => e.name === entityName);\n if (entity) {\n entity.tableName = tableMatch[1];\n }\n }\n }\n\n // Find MaxLength constraints\n const maxLengthMatches = content.matchAll(/\\.Property\\s*\\(\\s*\\w+\\s*=>\\s*\\w+\\.(\\w+)\\s*\\)[\\s\\S]*?\\.HasMaxLength\\s*\\(\\s*(\\d+)\\s*\\)/g);\n for (const match of maxLengthMatches) {\n const propertyName = match[1];\n const maxLength = parseInt(match[2], 10);\n\n for (const entity of entities) {\n const property = entity.properties.find(p => p.name === propertyName);\n if (property) {\n property.maxLength = maxLength;\n }\n }\n }\n }\n}\n\nfunction mapCSharpType(csharpType: string): string {\n const typeMap: Record<string, string> = {\n 'Guid': 'uniqueidentifier',\n 'string': 'nvarchar',\n 'String': 'nvarchar',\n 'int': 'int',\n 'Int32': 'int',\n 'long': 'bigint',\n 'Int64': 'bigint',\n 'DateTime': 'datetime2',\n 'DateTimeOffset': 'datetimeoffset',\n 'bool': 'bit',\n 'Boolean': 'bit',\n 'decimal': 'decimal',\n 'Decimal': 'decimal',\n 'double': 'float',\n 'Double': 'float',\n 'float': 'real',\n 'Float': 'real',\n 'byte[]': 'varbinary',\n };\n\n // Handle nullable types\n const baseType = csharpType.replace('?', '');\n return typeMap[baseType] || 'nvarchar';\n}\n\nfunction formatSchema(\n entities: EntityInfo[],\n filter?: string,\n _config?: Config\n): string {\n const lines: string[] = [];\n\n lines.push('# SmartStack Database Schema');\n lines.push('');\n\n if (filter) {\n lines.push(`> Filtered by: \\`${filter}\\``);\n lines.push('');\n }\n\n if (entities.length === 0) {\n lines.push('No entities found matching the criteria.');\n return lines.join('\\n');\n }\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push(`**Total Entities**: ${entities.length}`);\n lines.push('');\n\n // Table list\n lines.push('| Entity | Table | Properties | Relationships |');\n lines.push('|--------|-------|------------|---------------|');\n for (const entity of entities) {\n lines.push(\n `| ${entity.name} | \\`${entity.tableName}\\` | ${entity.properties.length} | ${entity.relationships.length} |`\n );\n }\n lines.push('');\n\n // Detailed schema for each entity\n for (const entity of entities) {\n lines.push(`## ${entity.name}`);\n lines.push('');\n lines.push(`**Table**: \\`${entity.tableName}\\``);\n lines.push(`**File**: \\`${entity.file}\\``);\n lines.push('');\n\n // Properties\n lines.push('### Columns');\n lines.push('');\n lines.push('| Column | SQL Type | Nullable | Notes |');\n lines.push('|--------|----------|----------|-------|');\n\n for (const prop of entity.properties) {\n const notes: string[] = [];\n if (prop.isPrimaryKey) notes.push('PK');\n if (prop.maxLength) notes.push(`MaxLength(${prop.maxLength})`);\n\n lines.push(\n `| ${prop.name} | ${prop.type} | ${prop.nullable ? 'Yes' : 'No'} | ${notes.join(', ')} |`\n );\n }\n lines.push('');\n\n // Relationships\n if (entity.relationships.length > 0) {\n lines.push('### Relationships');\n lines.push('');\n lines.push('| Type | Target | Property |');\n lines.push('|------|--------|----------|');\n\n for (const rel of entity.relationships) {\n const typeIcon = rel.type === 'one-to-one' ? '1:1' :\n rel.type === 'one-to-many' ? '1:N' : 'N:N';\n lines.push(`| ${typeIcon} | ${rel.targetEntity} | ${rel.propertyName} |`);\n }\n lines.push('');\n }\n\n // Sample EF configuration\n lines.push('### EF Core Configuration');\n lines.push('');\n lines.push('```csharp');\n lines.push(`public class ${entity.name}Configuration : IEntityTypeConfiguration<${entity.name}>`);\n lines.push('{');\n lines.push(` public void Configure(EntityTypeBuilder<${entity.name}> builder)`);\n lines.push(' {');\n lines.push(` builder.ToTable(\"${entity.tableName}\");`);\n lines.push('');\n const pk = entity.properties.find(p => p.isPrimaryKey);\n if (pk) {\n lines.push(` builder.HasKey(e => e.${pk.name});`);\n }\n lines.push(' }');\n lines.push('}');\n lines.push('```');\n lines.push('');\n }\n\n // ER Diagram (text-based)\n if (entities.length > 1) {\n lines.push('## Entity Relationships');\n lines.push('');\n lines.push('```');\n\n for (const entity of entities) {\n for (const rel of entity.relationships) {\n const arrow = rel.type === 'one-to-one' ? '──' :\n rel.type === 'one-to-many' ? '─<' : '>─<';\n lines.push(`${entity.name} ${arrow} ${rel.targetEntity}`);\n }\n }\n\n lines.push('```');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { Resource } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\nimport { findSmartStackStructure, findEntityFiles } from '../lib/detector.js';\nimport { readText } from '../utils/fs.js';\nimport path from 'path';\n\nexport const entitiesResourceTemplate: Resource = {\n uri: 'smartstack://entities/',\n name: 'SmartStack Entities',\n description: 'Quick reference list of all domain entities with tenant-awareness and table prefixes. Use smartstack://entities/{name} for details.',\n mimeType: 'text/markdown',\n};\n\ninterface EntitySummary {\n name: string;\n tableName: string;\n tablePrefix: string;\n schema: string;\n isTenantAware: boolean;\n isSystemEntity: boolean;\n baseClass: string;\n hasCode: boolean;\n hasSoftDelete: boolean;\n hasRowVersion: boolean;\n file: string;\n relativePath: string;\n}\n\nexport async function getEntitiesResource(\n config: Config,\n entityFilter?: string\n): Promise<string> {\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n if (!structure.domain) {\n return '# SmartStack Entities\\n\\nNo domain project found.';\n }\n\n const entities: EntitySummary[] = [];\n\n // Parse entities from domain layer\n const entityFiles = await findEntityFiles(structure.domain);\n for (const file of entityFiles) {\n const entity = await parseEntitySummary(file, structure.root, config);\n if (entity) {\n entities.push(entity);\n }\n }\n\n // Sort by table prefix, then name\n entities.sort((a, b) => {\n if (a.tablePrefix !== b.tablePrefix) {\n return a.tablePrefix.localeCompare(b.tablePrefix);\n }\n return a.name.localeCompare(b.name);\n });\n\n // Filter if specified\n const filteredEntities = entityFilter\n ? entities.filter(e =>\n e.name.toLowerCase().includes(entityFilter.toLowerCase()) ||\n e.tableName.toLowerCase().includes(entityFilter.toLowerCase()) ||\n e.tablePrefix.toLowerCase().includes(entityFilter.toLowerCase())\n )\n : entities;\n\n return formatEntities(filteredEntities, entityFilter, config);\n}\n\nasync function parseEntitySummary(\n filePath: string,\n rootPath: string,\n config: Config\n): Promise<EntitySummary | null> {\n const content = await readText(filePath);\n\n // Find class declaration with inheritance\n const classMatch = content.match(/public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*([^{]+))?/);\n if (!classMatch) return null;\n\n const entityName = classMatch[1];\n const inheritance = classMatch[2]?.trim() || '';\n\n // Skip non-entity classes\n if (entityName.endsWith('Dto') || entityName.endsWith('Command') ||\n entityName.endsWith('Query') || entityName.endsWith('Handler') ||\n entityName.endsWith('Configuration') || entityName.endsWith('Service') ||\n entityName.endsWith('Validator') || entityName.endsWith('Exception')) {\n return null;\n }\n\n // Determine base class\n const baseClassMatch = inheritance.match(/^(\\w+)/);\n const baseClass = baseClassMatch ? baseClassMatch[1] : 'Unknown';\n\n // Check for entity characteristics\n const isSystemEntity = baseClass === 'SystemEntity' ||\n inheritance.includes('ISystemEntity') ||\n content.includes('// System entity') ||\n !content.includes('TenantId');\n\n const isTenantAware = content.includes('TenantId') &&\n (content.includes('public Guid TenantId') ||\n content.includes('public required Guid TenantId'));\n\n const hasCode = content.includes('public string Code') ||\n content.includes('public required string Code') ||\n content.includes('public string? Code');\n\n const hasSoftDelete = content.includes('IsDeleted') ||\n inheritance.includes('ISoftDeletable') ||\n baseClass === 'BaseEntity';\n\n const hasRowVersion = content.includes('RowVersion') ||\n inheritance.includes('IHasRowVersion') ||\n baseClass === 'BaseEntity';\n\n // Try to determine table name from configuration or conventions\n const { tableName, tablePrefix, schema } = inferTableInfo(entityName, config);\n\n return {\n name: entityName,\n tableName,\n tablePrefix,\n schema,\n isTenantAware,\n isSystemEntity,\n baseClass,\n hasCode,\n hasSoftDelete,\n hasRowVersion,\n file: filePath,\n relativePath: path.relative(rootPath, filePath),\n };\n}\n\nfunction inferTableInfo(\n entityName: string,\n config: Config\n): { tableName: string; tablePrefix: string; schema: string } {\n // Known entity prefixes mapping\n const prefixMapping: Record<string, string> = {\n // Authentication & Authorization\n 'User': 'auth_',\n 'Role': 'auth_',\n 'Permission': 'auth_',\n 'UserRole': 'auth_',\n 'RolePermission': 'auth_',\n 'RefreshToken': 'auth_',\n\n // Navigation\n 'NavigationItem': 'nav_',\n 'NavigationMenu': 'nav_',\n 'Page': 'nav_',\n\n // AI\n 'Prompt': 'ai_',\n 'Completion': 'ai_',\n 'Model': 'ai_',\n 'Conversation': 'ai_',\n\n // Configuration\n 'Setting': 'cfg_',\n 'Configuration': 'cfg_',\n\n // Workflow\n 'Workflow': 'wkf_',\n 'WorkflowStep': 'wkf_',\n 'WorkflowInstance': 'wkf_',\n\n // Support\n 'Ticket': 'support_',\n 'TicketComment': 'support_',\n\n // Entra (Azure AD)\n 'EntraUser': 'entra_',\n 'EntraGroup': 'entra_',\n\n // Licensing\n 'License': 'lic_',\n 'Subscription': 'lic_',\n\n // Tenant\n 'Tenant': 'tenant_',\n 'TenantUser': 'tenant_',\n 'TenantUserRole': 'tenant_',\n 'TenantInvitation': 'tenant_',\n 'Organisation': 'tenant_',\n\n // Localization\n 'Translation': 'loc_',\n 'Language': 'loc_',\n };\n\n // Check if entity name starts with known prefixes\n let tablePrefix = 'ref_'; // Default to reference data\n\n for (const [pattern, prefix] of Object.entries(prefixMapping)) {\n if (entityName === pattern || entityName.startsWith(pattern)) {\n tablePrefix = prefix;\n break;\n }\n }\n\n // Check against config table prefixes\n const validPrefixes = config.conventions.tablePrefixes;\n if (!validPrefixes.includes(tablePrefix)) {\n tablePrefix = 'ref_'; // Fallback to ref_ if not in valid list\n }\n\n // Pluralize entity name for table\n const tableName = `${tablePrefix}${pluralize(entityName)}`;\n const schema = config.conventions.schemas.platform;\n\n return { tableName, tablePrefix, schema };\n}\n\nfunction pluralize(name: string): string {\n // Simple pluralization rules\n if (name.endsWith('y') && !/[aeiou]y$/i.test(name)) {\n return name.slice(0, -1) + 'ies';\n }\n if (name.endsWith('s') || name.endsWith('x') || name.endsWith('ch') || name.endsWith('sh')) {\n return name + 'es';\n }\n return name + 's';\n}\n\nfunction formatEntities(\n entities: EntitySummary[],\n filter: string | undefined,\n config: Config\n): string {\n const lines: string[] = [];\n\n lines.push('# SmartStack Entities');\n lines.push('');\n\n if (filter) {\n lines.push(`> Filtered by: \\`${filter}\\``);\n lines.push('');\n }\n\n if (entities.length === 0) {\n lines.push('No entities found matching the criteria.');\n return lines.join('\\n');\n }\n\n // Summary stats\n const tenantAwareCount = entities.filter(e => e.isTenantAware).length;\n const systemCount = entities.filter(e => e.isSystemEntity).length;\n const prefixes = [...new Set(entities.map(e => e.tablePrefix))];\n\n lines.push('## Summary');\n lines.push('');\n lines.push(`- **Total Entities**: ${entities.length}`);\n lines.push(`- **Tenant-Aware**: ${tenantAwareCount}`);\n lines.push(`- **System Entities**: ${systemCount}`);\n lines.push(`- **Table Prefixes Used**: ${prefixes.join(', ')}`);\n lines.push('');\n\n // Quick reference table\n lines.push('## Quick Reference');\n lines.push('');\n lines.push('| Entity | Table | Tenant | Code | SoftDel | Base |');\n lines.push('|--------|-------|--------|------|---------|------|');\n\n for (const entity of entities) {\n const tenantIcon = entity.isTenantAware ? '✅' : (entity.isSystemEntity ? '🔒' : '❌');\n const codeIcon = entity.hasCode ? '✅' : '❌';\n const softDelIcon = entity.hasSoftDelete ? '✅' : '❌';\n\n lines.push(\n `| ${entity.name} | \\`${entity.tableName}\\` | ${tenantIcon} | ${codeIcon} | ${softDelIcon} | ${entity.baseClass} |`\n );\n }\n lines.push('');\n\n // Group by prefix\n lines.push('## By Domain');\n lines.push('');\n\n const byPrefix = new Map<string, EntitySummary[]>();\n for (const entity of entities) {\n const list = byPrefix.get(entity.tablePrefix) || [];\n list.push(entity);\n byPrefix.set(entity.tablePrefix, list);\n }\n\n const prefixNames: Record<string, string> = {\n 'auth_': 'Authentication & Authorization',\n 'nav_': 'Navigation',\n 'ai_': 'AI & Prompts',\n 'cfg_': 'Configuration',\n 'wkf_': 'Workflows',\n 'support_': 'Support',\n 'entra_': 'Microsoft Entra',\n 'lic_': 'Licensing',\n 'tenant_': 'Multi-Tenant',\n 'loc_': 'Localization',\n 'ref_': 'Reference Data',\n 'usr_': 'User Data',\n };\n\n for (const [prefix, prefixEntities] of byPrefix) {\n const domainName = prefixNames[prefix] || prefix;\n lines.push(`### ${domainName} (\\`${prefix}\\`)`);\n lines.push('');\n\n for (const entity of prefixEntities) {\n const badges: string[] = [];\n if (entity.isTenantAware) badges.push('tenant-aware');\n if (entity.isSystemEntity) badges.push('system');\n if (entity.hasCode) badges.push('has-code');\n\n lines.push(`- **${entity.name}** → \\`${entity.tableName}\\``);\n if (badges.length > 0) {\n lines.push(` - ${badges.map(b => `\\`${b}\\``).join(' ')}`);\n }\n lines.push(` - File: \\`${entity.relativePath}\\``);\n }\n lines.push('');\n }\n\n // Conventions reminder\n lines.push('## Conventions');\n lines.push('');\n lines.push('| Property | Convention |');\n lines.push('|----------|------------|');\n lines.push(`| Schema | \\`${config.conventions.schemas.platform}\\` |`);\n lines.push(`| Valid Prefixes | ${config.conventions.tablePrefixes.map(p => `\\`${p}\\``).join(', ')} |`);\n lines.push('| Tenant-aware | Must have `TenantId` (GUID, NOT NULL) |');\n lines.push('| System entity | No `TenantId`, used for platform-level data |');\n lines.push('| Code field | Lowercase, unique per tenant (or globally for system) |');\n lines.push('');\n\n // Legend\n lines.push('## Legend');\n lines.push('');\n lines.push('- ✅ = Feature present');\n lines.push('- ❌ = Feature absent');\n lines.push('- 🔒 = System entity (no tenant scope)');\n lines.push('');\n\n return lines.join('\\n');\n}\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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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAmKN,aAAa,IAAI,oBAAoB,aAAa,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gDAwGvC,QAAQ,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["path","path","path","path","path","exec","promisify","execAsync","promisify","exec","path","path","path","formatResult","path","formatResult","path","z","path","z","compareVersions","path","path","endpoints","path","path"]}