@atlashub/smartstack-cli 1.37.0 → 2.0.0

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.
Files changed (99) hide show
  1. package/config/mcp-defaults.json +62 -0
  2. package/dist/index.js +57 -4
  3. package/dist/index.js.map +1 -1
  4. package/dist/mcp-entry.mjs +16984 -0
  5. package/dist/mcp-entry.mjs.map +1 -0
  6. package/package.json +14 -5
  7. package/templates/agents/gitflow/start.md +5 -4
  8. package/templates/agents/mcp-healthcheck.md +15 -13
  9. package/templates/mcp-scaffolding/component.tsx.hbs +298 -0
  10. package/templates/mcp-scaffolding/controller.cs.hbs +184 -0
  11. package/templates/mcp-scaffolding/entity-extension.cs.hbs +231 -0
  12. package/templates/mcp-scaffolding/frontend/api-client.ts.hbs +116 -0
  13. package/templates/mcp-scaffolding/frontend/nav-routes.ts.hbs +133 -0
  14. package/templates/mcp-scaffolding/frontend/routes.tsx.hbs +134 -0
  15. package/templates/mcp-scaffolding/migrations/seed-roles.cs.hbs +261 -0
  16. package/templates/mcp-scaffolding/service-extension.cs.hbs +53 -0
  17. package/templates/mcp-scaffolding/tests/controller.test.cs.hbs +413 -0
  18. package/templates/mcp-scaffolding/tests/entity.test.cs.hbs +239 -0
  19. package/templates/mcp-scaffolding/tests/repository.test.cs.hbs +441 -0
  20. package/templates/mcp-scaffolding/tests/security.test.cs.hbs +442 -0
  21. package/templates/mcp-scaffolding/tests/service.test.cs.hbs +390 -0
  22. package/templates/mcp-scaffolding/tests/validator.test.cs.hbs +428 -0
  23. package/templates/ralph/README.md +3 -3
  24. package/templates/ralph/ralph.config.yaml +2 -2
  25. package/templates/skills/admin/SKILL.md +42 -0
  26. package/templates/skills/business-analyse/_shared.md +24 -1
  27. package/templates/skills/business-analyse/questionnaire/01-context.md +4 -4
  28. package/templates/skills/business-analyse/questionnaire/02-stakeholders.md +3 -3
  29. package/templates/skills/business-analyse/questionnaire/03-scope.md +4 -4
  30. package/templates/skills/business-analyse/questionnaire/04-data.md +7 -7
  31. package/templates/skills/business-analyse/questionnaire/05-integrations.md +1 -1
  32. package/templates/skills/business-analyse/questionnaire/06-security.md +3 -3
  33. package/templates/skills/business-analyse/questionnaire/07-ui.md +1 -1
  34. package/templates/skills/business-analyse/questionnaire/08-performance.md +3 -3
  35. package/templates/skills/business-analyse/questionnaire/09-constraints.md +4 -4
  36. package/templates/skills/business-analyse/questionnaire/10-documentation.md +2 -2
  37. package/templates/skills/business-analyse/questionnaire/11-data-lifecycle.md +2 -2
  38. package/templates/skills/business-analyse/questionnaire/12-migration.md +1 -1
  39. package/templates/skills/business-analyse/questionnaire/13-cross-module.md +2 -2
  40. package/templates/skills/business-analyse/steps/step-01-discover.md +50 -25
  41. package/templates/skills/business-analyse/steps/step-05-handoff.md +133 -34
  42. package/templates/skills/cc-agent/SKILL.md +129 -0
  43. package/templates/skills/cc-agent/references/agent-frontmatter.md +213 -0
  44. package/templates/skills/cc-agent/references/permission-modes.md +102 -0
  45. package/templates/skills/cc-agent/references/tools-reference.md +144 -0
  46. package/templates/skills/cc-agent/steps/step-00-init.md +134 -0
  47. package/templates/skills/cc-agent/steps/step-01-design.md +186 -0
  48. package/templates/skills/cc-agent/steps/step-02-generate.md +204 -0
  49. package/templates/skills/cc-agent/steps/step-03-validate.md +130 -0
  50. package/templates/skills/cc-agent/templates/agent-categorized.md +67 -0
  51. package/templates/skills/cc-agent/templates/agent-standalone.md +56 -0
  52. package/templates/skills/cc-agent/templates/agent-with-skills.md +94 -0
  53. package/templates/skills/cc-audit/SKILL.md +108 -0
  54. package/templates/skills/cc-audit/references/agent-checklist.md +91 -0
  55. package/templates/skills/cc-audit/references/hook-checklist.md +110 -0
  56. package/templates/skills/cc-audit/references/skill-checklist.md +70 -0
  57. package/templates/skills/cc-audit/steps/step-00-init.md +98 -0
  58. package/templates/skills/cc-audit/steps/step-01-scan.md +142 -0
  59. package/templates/skills/cc-audit/steps/step-02-analyze.md +158 -0
  60. package/templates/skills/cc-audit/steps/step-03-report.md +142 -0
  61. package/templates/skills/cc-skill/SKILL.md +134 -0
  62. package/templates/skills/cc-skill/references/best-practices.md +167 -0
  63. package/templates/skills/cc-skill/references/frontmatter-reference.md +182 -0
  64. package/templates/skills/cc-skill/references/skill-patterns.md +199 -0
  65. package/templates/skills/cc-skill/steps/step-00-init.md +119 -0
  66. package/templates/skills/cc-skill/steps/step-01-design.md +199 -0
  67. package/templates/skills/cc-skill/steps/step-02-generate.md +145 -0
  68. package/templates/skills/cc-skill/steps/step-03-steps.md +151 -0
  69. package/templates/skills/cc-skill/steps/step-04-validate.md +124 -0
  70. package/templates/skills/cc-skill/templates/skill-forked.md +85 -0
  71. package/templates/skills/cc-skill/templates/skill-progressive.md +102 -0
  72. package/templates/skills/cc-skill/templates/skill-simple.md +75 -0
  73. package/templates/skills/cc-skill/templates/step-template.md +82 -0
  74. package/templates/skills/check-version/SKILL.md +6 -0
  75. package/templates/skills/debug/SKILL.md +4 -0
  76. package/templates/skills/documentation/SKILL.md +1 -0
  77. package/templates/skills/efcore/SKILL.md +5 -0
  78. package/templates/skills/efcore/steps/db/step-deploy.md +26 -5
  79. package/templates/skills/efcore/steps/shared/step-00-init.md +21 -7
  80. package/templates/skills/explore/SKILL.md +28 -32
  81. package/templates/skills/feature-full/SKILL.md +1 -0
  82. package/templates/skills/gitflow/SKILL.md +8 -0
  83. package/templates/skills/gitflow/steps/step-start.md +45 -10
  84. package/templates/skills/mcp/SKILL.md +38 -18
  85. package/templates/skills/quick-search/SKILL.md +8 -1
  86. package/templates/skills/ralph-loop/SKILL.md +1 -1
  87. package/templates/skills/ralph-loop/steps/step-00-init.md +8 -68
  88. package/templates/skills/ralph-loop/steps/step-04-check.md +1 -1
  89. package/templates/skills/refactor/SKILL.md +1 -0
  90. package/templates/skills/review-code/SKILL.md +7 -1
  91. package/templates/skills/ui-components/SKILL.md +31 -438
  92. package/templates/skills/ui-components/accessibility.md +170 -0
  93. package/templates/skills/ui-components/patterns/data-table.md +39 -0
  94. package/templates/skills/ui-components/patterns/entity-card.md +77 -0
  95. package/templates/skills/ui-components/patterns/grid-layout.md +91 -0
  96. package/templates/skills/ui-components/patterns/kanban.md +43 -0
  97. package/templates/skills/ui-components/style-guide.md +86 -0
  98. package/templates/skills/utils/SKILL.md +1 -0
  99. package/templates/skills/validate/SKILL.md +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/mcp/lib/logger.ts","../src/mcp/utils/fs.ts","../src/mcp/types/index.ts","../src/mcp/utils/dotnet.ts","../src/mcp/config.ts","../src/mcp/utils/git.ts","../src/mcp/lib/detector.ts","../src/mcp/tools/validate-conventions.ts","../src/mcp/tools/check-migrations.ts","../src/mcp/tools/scaffold-extension.ts","../src/mcp/tools/api-docs.ts","../src/mcp/tools/suggest-migration.ts","../src/mcp/tools/generate-permissions.ts","../src/mcp/tools/scaffold-tests.ts","../src/mcp/tools/analyze-test-coverage.ts","../src/mcp/tools/validate-test-conventions.ts","../src/mcp/tools/suggest-test-scenarios.ts","../src/mcp/tools/scaffold-api-client.ts","../src/mcp/tools/scaffold-routes.ts","../src/mcp/tools/validate-frontend-routes.ts","../src/mcp/tools/scaffold-frontend-extension.ts","../src/mcp/tools/analyze-extension-points.ts","../src/mcp/tools/validate-security.ts","../src/mcp/tools/analyze-code-quality.ts","../src/mcp/tools/analyze-hierarchy-patterns.ts","../src/mcp/tools/review-code/types.ts","../src/mcp/tools/review-code/checks/security.ts","../src/mcp/tools/review-code/checks/architecture.ts","../src/mcp/tools/review-code/checks/hardcoded-values.ts","../src/mcp/tools/review-code/checks/tests.ts","../src/mcp/tools/review-code/checks/ai-hallucinations.ts","../src/mcp/tools/review-code/checks/performance.ts","../src/mcp/tools/review-code/checks/dead-code.ts","../src/mcp/tools/review-code/checks/i18n.ts","../src/mcp/tools/review-code/checks/accessibility.ts","../src/mcp/tools/review-code/formatters/markdown.ts","../src/mcp/tools/review-code.ts","../src/mcp/resources/conventions.ts","../src/mcp/resources/project-info.ts","../src/mcp/resources/api-endpoints.ts","../src/mcp/resources/db-schema.ts","../src/mcp/resources/entities.ts","../src/mcp/server.ts","../src/mcp-entry.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\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 { stat, mkdir, readFile, writeFile, cp, rm } from 'fs/promises';\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 s = await stat(filePath);\n return s.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 s = await stat(dirPath);\n return s.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 mkdir(dirPath, { recursive: true });\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 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 mkdir(path.dirname(filePath), { recursive: true });\n await 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 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 mkdir(path.dirname(filePath), { recursive: true });\n await 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 mkdir(path.dirname(dest), { recursive: true });\n await cp(src, dest, { recursive: true });\n}\n\n/**\n * Remove a file\n */\nexport async function removeFile(filePath: string): Promise<void> {\n await rm(filePath, { force: true });\n}\n\n/**\n * Remove a directory\n */\nexport async function removeDirectory(dirPath: string): Promise<void> {\n await rm(dirPath, { recursive: true, force: true });\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\n// Schema for .smartstack/config.json (created by CLI during ss init)\nexport const ProjectConfigSchema = z.object({\n projectType: z.enum(['client', 'platform']).default('platform'),\n dbContext: z.enum(['core', 'extensions']).default('core'),\n baseNamespace: z.string().optional(),\n smartStackVersion: z.string().optional(),\n initialized: z.string().optional(),\n});\n\nexport type ProjectConfig = z.infer<typeof ProjectConfigSchema>;\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 scopeTypes: z.array(z.string()).default(['Core', 'Extension', 'Partner', 'Community']),\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 // Loaded from .smartstack/config.json if present\n projectConfig: ProjectConfigSchema.optional(),\n // Resolved DbContext to use (from projectConfig or default)\n defaultDbContext: z.enum(['core', 'extensions']).default('core'),\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', 'layouts', 'tabs', 'hierarchies', 'protected-actions', '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 navRoute: z.string().optional().describe('Navigation route path for controller (e.g., \"platform.administration.users\"). Required for controllers.'),\n navRouteSuffix: z.string().optional().describe('Optional suffix for NavRoute (e.g., \"dashboard\" for sub-resources)'),\n withHierarchyFunction: z.boolean().optional().describe('For entity type with self-reference (ParentId): generate TVF SQL script for hierarchy traversal'),\n hierarchyDirection: z.enum(['ancestors', 'descendants', 'both']).optional().describe('Direction for hierarchy traversal function (default: both)'),\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 const SuggestMigrationInputSchema = z.object({\n description: z.string().describe('Description of what the migration does (e.g., \"Add User Profiles\", \"Create Orders Table\")'),\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\", \"1.2.0\"). If not provided, uses latest from existing migrations.'),\n});\n\nexport const GeneratePermissionsInputSchema = z.object({\n navRoute: z.string().optional().describe('NavRoute path (e.g., \"platform.administration.entra\"). If not provided, scans all controllers.'),\n actions: z.array(z.string()).optional().describe('Custom actions to generate (default: read, create, update, delete)'),\n includeStandardActions: z.boolean().default(true).describe('Include standard CRUD actions (read, create, update, delete)'),\n generateMigration: z.boolean().default(true).describe('Generate EF Core migration to seed permissions in database'),\n dryRun: z.boolean().default(false).describe('Preview without writing files or creating migration'),\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>;\nexport type SuggestMigrationInput = z.infer<typeof SuggestMigrationInputSchema>;\nexport type GeneratePermissionsInput = z.infer<typeof GeneratePermissionsInputSchema>;\n\n// ============================================================================\n// Test Tool Input Schemas\n// ============================================================================\n\nexport const TestTypeSchema = z.enum(['unit', 'integration', 'security', 'e2e']);\nexport const TestTargetSchema = z.enum(['entity', 'service', 'controller', 'validator', 'repository', 'all']);\n\nexport const ScaffoldTestsInputSchema = z.object({\n target: TestTargetSchema.describe('Type of component to test'),\n name: z.string().min(1).describe('Component name (PascalCase, e.g., \"User\", \"Order\")'),\n testTypes: z.array(TestTypeSchema).default(['unit']).describe('Types of tests to generate'),\n options: z.object({\n includeEdgeCases: z.boolean().default(true).describe('Include edge case tests'),\n includeTenantIsolation: z.boolean().default(true).describe('Include tenant isolation tests'),\n includeSoftDelete: z.boolean().default(true).describe('Include soft delete tests'),\n includeAudit: z.boolean().default(true).describe('Include audit trail tests'),\n includeValidation: z.boolean().default(true).describe('Include validation tests'),\n includeAuthorization: z.boolean().default(false).describe('Include authorization tests'),\n includePerformance: z.boolean().default(false).describe('Include performance tests'),\n entityProperties: z.array(EntityPropertySchema).optional().describe('Entity properties for test generation'),\n isSystemEntity: z.boolean().default(false).describe('If true, entity has no TenantId'),\n dryRun: z.boolean().default(false).describe('Preview without writing files'),\n }).optional(),\n});\n\nexport const AnalyzeTestCoverageInputSchema = z.object({\n path: z.string().optional().describe('Project path to analyze'),\n scope: z.enum(['entity', 'service', 'controller', 'all']).default('all').describe('Scope of analysis'),\n outputFormat: z.enum(['summary', 'detailed', 'json']).default('summary').describe('Output format'),\n includeRecommendations: z.boolean().default(true).describe('Include recommendations for missing tests'),\n});\n\nexport const ValidateTestConventionsInputSchema = z.object({\n path: z.string().optional().describe('Project path to validate'),\n checks: z.array(z.enum(['naming', 'structure', 'patterns', 'assertions', 'mocking', 'all']))\n .default(['all'])\n .describe('Types of convention checks to perform'),\n autoFix: z.boolean().default(false).describe('Automatically fix minor issues'),\n});\n\nexport const SuggestTestScenariosInputSchema = z.object({\n target: z.enum(['entity', 'service', 'controller', 'file']).describe('Type of target to analyze'),\n name: z.string().min(1).describe('Component name or file path'),\n depth: z.enum(['basic', 'comprehensive', 'security-focused']).default('comprehensive')\n .describe('Depth of analysis'),\n});\n\nexport type ScaffoldTestsInput = z.infer<typeof ScaffoldTestsInputSchema>;\nexport type AnalyzeTestCoverageInput = z.infer<typeof AnalyzeTestCoverageInputSchema>;\nexport type ValidateTestConventionsInput = z.infer<typeof ValidateTestConventionsInputSchema>;\nexport type SuggestTestScenariosInput = z.infer<typeof SuggestTestScenariosInputSchema>;\n\n// ============================================================================\n// Security & Code Quality Tool Input Schemas\n// ============================================================================\n\nexport const SecurityCheckSchema = z.enum([\n 'hardcoded-secrets',\n 'sql-injection',\n 'tenant-isolation',\n 'authorization',\n 'dangerous-functions',\n 'input-validation',\n 'xss',\n 'csrf',\n 'logging-sensitive',\n 'all',\n]);\n\nexport const ValidateSecurityInputSchema = z.object({\n path: z.string().optional().describe('Project path to validate (default: SmartStack.app path)'),\n checks: z.array(SecurityCheckSchema)\n .default(['all'])\n .describe('Security checks to run'),\n severity: z.enum(['blocking', 'all']).optional()\n .describe('Filter results by severity'),\n});\n\nexport const QualityMetricSchema = z.enum([\n 'cognitive-complexity',\n 'cyclomatic-complexity',\n 'function-size',\n 'nesting-depth',\n 'parameter-count',\n 'code-duplication',\n 'file-size',\n 'unused-members',\n 'duplicated-strings',\n 'unassigned-fields',\n 'all',\n]);\n\nexport const AnalyzeCodeQualityInputSchema = z.object({\n path: z.string().optional().describe('Project path to analyze (default: SmartStack.app path)'),\n metrics: z.array(QualityMetricSchema)\n .default(['all'])\n .describe('Metrics to analyze'),\n threshold: z.enum(['strict', 'normal', 'lenient']).default('normal')\n .describe('Threshold level for violations'),\n scope: z.enum(['changed', 'all']).default('all')\n .describe('Analyze only changed files or all'),\n});\n\nexport type SecurityCheck = z.infer<typeof SecurityCheckSchema>;\nexport type ValidateSecurityInput = z.infer<typeof ValidateSecurityInputSchema>;\nexport type QualityMetric = z.infer<typeof QualityMetricSchema>;\nexport type AnalyzeCodeQualityInput = z.infer<typeof AnalyzeCodeQualityInputSchema>;\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\n// ============================================================================\n// Test Tool Result Types\n// ============================================================================\n\nexport interface TestCoverageResult {\n summary: {\n total: number;\n tested: number;\n coverage: number;\n };\n entities: TestCoverageCategory;\n services: TestCoverageCategory;\n controllers: TestCoverageCategory;\n missing: TestCoverageItem[];\n recommendations: string[];\n}\n\nexport interface TestCoverageCategory {\n total: number;\n tested: number;\n coverage: number;\n items: string[];\n missingTests: string[];\n}\n\nexport interface TestCoverageItem {\n name: string;\n type: 'entity' | 'service' | 'controller' | 'validator' | 'repository';\n priority: 'critical' | 'high' | 'medium' | 'low';\n recommendation: string;\n suggestedTestFile: string;\n}\n\nexport interface TestConventionResult {\n valid: boolean;\n violations: TestConventionViolation[];\n suggestions: string[];\n autoFixedCount: number;\n}\n\nexport interface TestConventionViolation {\n type: 'naming' | 'structure' | 'pattern' | 'assertion' | 'mocking';\n severity: 'error' | 'warning';\n file: string;\n line?: number;\n message: string;\n suggestion: string;\n autoFixable: boolean;\n}\n\nexport interface TestScenarioResult {\n target: string;\n targetType: 'entity' | 'service' | 'controller' | 'file';\n detectedMethods: DetectedMethod[];\n scenarios: TestScenario[];\n coverage: {\n happyPath: number;\n validation: number;\n errorHandling: number;\n security: number;\n edgeCases: number;\n };\n}\n\nexport interface DetectedMethod {\n name: string;\n returnType: string;\n parameters: string[];\n isAsync: boolean;\n visibility: 'public' | 'protected' | 'private' | 'internal';\n}\n\nexport interface TestScenario {\n methodName: string;\n scenarioName: string;\n description: string;\n type: 'happy-path' | 'validation' | 'error-handling' | 'security' | 'edge-case' | 'performance';\n priority: 'critical' | 'high' | 'medium' | 'low';\n testMethodName: string;\n inputs?: string[];\n expectedOutput?: string;\n assertions: string[];\n}\n\n// ============================================================================\n// Security & Code Quality Tool Result Types\n// ============================================================================\n\nexport interface SecurityValidationResult {\n valid: boolean;\n summary: string;\n findings: SecurityFinding[];\n stats: {\n blocking: number;\n critical: number;\n warning: number;\n filesScanned: number;\n };\n}\n\nexport interface SecurityFinding {\n severity: 'blocking' | 'critical' | 'warning';\n category: string;\n message: string;\n file: string;\n line?: number;\n code?: string;\n suggestion: string;\n cweId?: string;\n}\n\nexport interface CodeQualityResult {\n summary: QualitySummary;\n metrics: MetricResults;\n hotspots: Hotspot[];\n}\n\nexport interface QualitySummary {\n score: number;\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n filesAnalyzed: number;\n functionsAnalyzed: number;\n issuesFound: number;\n}\n\nexport interface MetricResults {\n cognitiveComplexity: MetricStat;\n cyclomaticComplexity: MetricStat;\n functionSize: MetricStat;\n nestingDepth: MetricStat;\n fileSize: MetricStat;\n}\n\nexport interface MetricStat {\n average: number;\n max: number;\n threshold: number;\n violations: number;\n}\n\nexport interface Hotspot {\n file: string;\n function?: string;\n issues: string[];\n severity: 'high' | 'medium' | 'low';\n metrics: {\n cognitiveComplexity?: number;\n cyclomaticComplexity?: number;\n lineCount?: number;\n nestingDepth?: number;\n };\n}\n\nexport interface FunctionMetrics {\n name: string;\n file: string;\n startLine: number;\n endLine: number;\n lineCount: number;\n parameterCount: number;\n maxNestingDepth: number;\n cognitiveComplexity: number;\n cyclomaticComplexity: number;\n}\n\n// SonarCloud-inspired detection types (S1144, S1192, S3459)\nexport interface UnusedMember {\n name: string;\n type: 'method' | 'field' | 'property';\n visibility: 'private' | 'internal';\n file: string;\n line: number;\n rule: 'S1144';\n}\n\nexport interface DuplicatedString {\n literal: string;\n occurrences: number;\n locations: Array<{ file: string; line: number }>;\n suggestedConstantName: string;\n rule: 'S1192';\n}\n\nexport interface UnassignedField {\n name: string;\n type: string;\n file: string;\n line: number;\n rule: 'S3459';\n}\n\nexport interface ExtendedCodeQualityResult {\n summary: QualitySummary;\n metrics: MetricResults;\n hotspots: Hotspot[];\n // New SonarCloud-inspired detections\n unusedMembers: UnusedMember[];\n duplicatedStrings: DuplicatedString[];\n unassignedFields: UnassignedField[];\n}\n\n// ============================================================================\n// Frontend Route Tool Input Schemas\n// ============================================================================\n\nexport const ScaffoldApiClientInputSchema = z.object({\n path: z.string().optional().describe('Path to SmartStack project root (defaults to configured project path)'),\n navRoute: z.string().min(1).describe('NavRoute path (e.g., \"platform.administration.users\")'),\n name: z.string().min(1).describe('Entity name in PascalCase (e.g., \"User\", \"Order\")'),\n methods: z.array(z.enum(['getAll', 'getById', 'create', 'update', 'delete', 'search', 'export']))\n .default(['getAll', 'getById', 'create', 'update', 'delete'])\n .describe('API methods to generate'),\n options: z.object({\n outputPath: z.string().optional().describe('Custom output path for generated files'),\n includeTypes: z.boolean().default(true).describe('Generate TypeScript types'),\n includeHook: z.boolean().default(true).describe('Generate React Query hook'),\n dryRun: z.boolean().default(false).describe('Preview without writing files'),\n }).optional(),\n});\n\nexport const ScaffoldRoutesInputSchema = z.object({\n path: z.string().optional().describe('Path to SmartStack project root (defaults to configured project path)'),\n source: z.enum(['controllers', 'navigation', 'manual'])\n .default('controllers')\n .describe('Source for route discovery: controllers (scan NavRoute attributes), navigation (from DB), manual (from config)'),\n scope: z.enum(['all', 'platform', 'business', 'extensions'])\n .default('all')\n .describe('Scope of routes to generate'),\n options: z.object({\n outputPath: z.string().optional().describe('Custom output path'),\n includeLayouts: z.boolean().default(true).describe('Generate layout components'),\n includeGuards: z.boolean().default(true).describe('Include route guards for permissions'),\n generateRegistry: z.boolean().default(true).describe('Generate navRoutes.generated.ts'),\n dryRun: z.boolean().default(false).describe('Preview without writing files'),\n }).optional(),\n});\n\nexport const ValidateFrontendRoutesInputSchema = z.object({\n path: z.string().optional().describe('Path to SmartStack project root (defaults to configured project path)'),\n scope: z.enum(['api-clients', 'routes', 'registry', 'all'])\n .default('all')\n .describe('Scope of validation'),\n options: z.object({\n fix: z.boolean().default(false).describe('Auto-fix minor issues'),\n strict: z.boolean().default(false).describe('Fail on warnings'),\n }).optional(),\n});\n\nexport type ScaffoldApiClientInput = z.infer<typeof ScaffoldApiClientInputSchema>;\nexport type ScaffoldRoutesInput = z.infer<typeof ScaffoldRoutesInputSchema>;\nexport type ValidateFrontendRoutesInput = z.infer<typeof ValidateFrontendRoutesInputSchema>;\n\n// ============================================================================\n// Frontend Route Tool Result Types\n// ============================================================================\n\nexport interface NavRouteEntry {\n navRoute: string;\n apiPath: string;\n webPath: string;\n permissions: string[];\n controller?: string;\n methods: string[];\n}\n\nexport interface FrontendRouteValidationResult {\n valid: boolean;\n registry: {\n exists: boolean;\n routeCount: number;\n outdated: string[];\n };\n apiClients: {\n total: number;\n valid: number;\n issues: FrontendRouteIssue[];\n };\n routes: {\n total: number;\n orphaned: string[];\n missing: string[];\n };\n recommendations: string[];\n}\n\nexport interface FrontendRouteIssue {\n type: 'missing-route' | 'invalid-path' | 'permission-mismatch' | 'orphaned-client';\n severity: 'error' | 'warning';\n file: string;\n navRoute?: string;\n message: string;\n suggestion: string;\n}\n\n// ============================================================================\n// Frontend Extension Tool Schemas\n// ============================================================================\n\nexport const SlotDefinitionSchema = z.object({\n name: z.string().describe('Slot name (e.g., \"users.form.fields.after\")'),\n location: z.string().describe('Where the slot is located in the page'),\n contextProps: z.array(z.string()).optional().describe('Props passed to slot content'),\n});\n\nexport const ScaffoldFrontendExtensionInputSchema = z.object({\n type: z.enum(['infrastructure', 'page-slots', 'extension-example', 'all'])\n .describe('Type of extension to scaffold: infrastructure (types, contexts), page-slots (add slots to a page), extension-example (client usage example), all'),\n target: z.string().optional().describe('Target page or component (e.g., \"UsersPage\", \"UserDetailPage\")'),\n options: z.object({\n slots: z.array(SlotDefinitionSchema).optional().describe('Slot definitions to add'),\n outputPath: z.string().optional().describe('Custom output path'),\n dryRun: z.boolean().default(false).describe('Preview without writing files'),\n overwrite: z.boolean().default(false).describe('Overwrite existing files'),\n }).optional(),\n});\n\nexport const AnalyzeExtensionPointsInputSchema = z.object({\n path: z.string().optional().describe('Path to SmartStack web project'),\n target: z.enum(['pages', 'components', 'forms', 'tables', 'all'])\n .default('all')\n .describe('Type of components to analyze'),\n filter: z.string().optional().describe('Filter by file name pattern (e.g., \"User*\")'),\n});\n\nexport type SlotDefinition = z.infer<typeof SlotDefinitionSchema>;\nexport type ScaffoldFrontendExtensionInput = z.infer<typeof ScaffoldFrontendExtensionInputSchema>;\nexport type AnalyzeExtensionPointsInput = z.infer<typeof AnalyzeExtensionPointsInputSchema>;\n\n// ============================================================================\n// Frontend Extension Tool Result Types\n// ============================================================================\n\nexport interface ExtensionPointAnalysis {\n file: string;\n componentName: string;\n type: 'page' | 'component' | 'form' | 'table';\n suggestedSlots: SuggestedSlot[];\n hasModal: boolean;\n hasForm: boolean;\n hasTable: boolean;\n imports: string[];\n lineCount: number;\n}\n\nexport interface SuggestedSlot {\n name: string;\n location: string;\n description: string;\n contextProps: string[];\n priority: 'high' | 'medium' | 'low';\n}\n\nexport interface ScaffoldFrontendExtensionResult {\n success: boolean;\n type: string;\n files: {\n path: string;\n content: string;\n action: 'created' | 'modified' | 'skipped';\n }[];\n instructions: string[];\n warnings: string[];\n}\n\nexport interface AnalyzeExtensionPointsResult {\n totalFiles: number;\n analyzed: ExtensionPointAnalysis[];\n summary: {\n pagesWithForms: number;\n pagesWithTables: number;\n pagesWithModals: number;\n totalSuggestedSlots: number;\n };\n recommendations: string[];\n}\n\n// ============================================================================\n// Hierarchy Analysis Tool Schemas\n// ============================================================================\n\nexport const AnalyzeHierarchyPatternsInputSchema = z.object({\n path: z.string().optional().describe('Project path to analyze (default: SmartStack.app path)'),\n entityFilter: z.string().optional().describe('Filter entities by name pattern (e.g., \"User*\", \"*Group*\")'),\n includeRecommendations: z.boolean().default(true).describe('Include pattern recommendations for each hierarchy'),\n outputFormat: z.enum(['summary', 'detailed', 'json']).default('detailed').describe('Output format'),\n});\n\nexport type AnalyzeHierarchyPatternsInput = z.infer<typeof AnalyzeHierarchyPatternsInputSchema>;\n\n// ============================================================================\n// Code Review Tool Input Schemas\n// ============================================================================\n\nexport const ReviewCodeCheckSchema = z.enum([\n 'security',\n 'architecture',\n 'hardcoded-values',\n 'tests',\n 'ai-hallucinations',\n 'performance',\n 'dead-code',\n 'i18n',\n 'accessibility',\n 'all',\n]);\n\nexport const ReviewCodeInputSchema = z.object({\n path: z.string().optional().describe('Project path to review (default: SmartStack.app path)'),\n scope: z.enum(['all', 'changed', 'staged']).default('all')\n .describe('Files to review: all, only changed (git diff), or staged files'),\n checks: z.array(ReviewCodeCheckSchema)\n .default(['all'])\n .describe('Categories of checks to run'),\n severity: z.enum(['blocking', 'critical', 'warning', 'all']).default('all')\n .describe('Filter results by minimum severity'),\n});\n\nexport type ReviewCodeCheck = z.infer<typeof ReviewCodeCheckSchema>;\nexport type ReviewCodeInput = z.infer<typeof ReviewCodeInputSchema>;\n\n// ============================================================================\n// Hierarchy Analysis Tool Result Types\n// ============================================================================\n\nexport interface EntityHierarchyNode {\n name: string;\n file: string;\n baseClass: string;\n isTenantAware: boolean;\n isSystemEntity: boolean;\n parent: string | null;\n children: string[];\n depth: number;\n isRoot: boolean;\n isLeaf: boolean;\n isSelfReferencing: boolean;\n selfReferenceField?: string;\n childCollections: string[];\n foreignKeys: {\n propertyName: string;\n referencedEntity: string;\n isNavigationProperty: boolean;\n }[];\n isHierarchical: boolean;\n}\n\nexport interface HierarchyPatternRecommendation {\n entityName: string;\n currentPattern: 'self-referencing' | 'parent-child' | 'none';\n recommendedPattern: 'tvf-cte' | 'materialized-path' | 'simple-parentid' | 'nested-sets' | 'closure-table';\n reason: string;\n priority: 'critical' | 'high' | 'medium' | 'low';\n hierarchyDepth: number;\n estimatedNodes: number;\n sqlTemplate?: string;\n implementationSteps: string[];\n}\n\nexport interface HierarchyAnalysisResult {\n totalEntities: number;\n hierarchicalEntities: number;\n selfReferencingEntities: number;\n maxDepth: number;\n hierarchies: EntityHierarchyNode[];\n recommendations: HierarchyPatternRecommendation[];\n circularDependencies: string[][];\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\n/**\n * Namespace configuration structure\n */\nexport interface NamespaceConfig {\n baseNamespace: string;\n domain: string;\n application: string;\n infrastructure: string;\n api: string;\n}\n\n/**\n * Detect namespaces from .csproj files\n * Extracts the base namespace from project naming patterns like:\n * - MyProject.Domain.csproj → base = \"MyProject\"\n * - Acme.Corp.Application.csproj → base = \"Acme.Corp\"\n *\n * Returns null if unable to detect (user should configure manually)\n */\nexport async function detectNamespaces(csprojFiles: string[]): Promise<NamespaceConfig | null> {\n if (csprojFiles.length === 0) {\n return null;\n }\n\n // Extract project names and find patterns\n const projectNames = csprojFiles.map(f => path.basename(f, '.csproj'));\n\n // Known layer suffixes (case-insensitive matching)\n const layerSuffixes = ['Domain', 'Application', 'Infrastructure', 'Api', 'Web', 'Core', 'Tests'];\n\n // Find base namespace by removing layer suffixes\n const baseNamespaces: string[] = [];\n\n for (const name of projectNames) {\n const parts = name.split('.');\n\n // Try to find where the layer suffix starts\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i];\n if (layerSuffixes.some(s => s.toLowerCase() === part.toLowerCase())) {\n // Found a layer suffix, base namespace is everything before it\n const baseParts = parts.slice(0, i);\n if (baseParts.length > 0) {\n baseNamespaces.push(baseParts.join('.'));\n }\n break;\n }\n }\n }\n\n if (baseNamespaces.length === 0) {\n // Fallback: try to extract common prefix from all project names\n const commonPrefix = findCommonPrefix(projectNames);\n if (commonPrefix && commonPrefix.length > 0) {\n // Remove trailing dot if present\n const base = commonPrefix.replace(/\\.$/, '');\n if (base) {\n baseNamespaces.push(base);\n }\n }\n }\n\n if (baseNamespaces.length === 0) {\n return null;\n }\n\n // Use the most common base namespace (in case of multiple patterns)\n const baseNamespace = getMostCommon(baseNamespaces) || baseNamespaces[0];\n\n return {\n baseNamespace,\n domain: `${baseNamespace}.Domain`,\n application: `${baseNamespace}.Application`,\n infrastructure: `${baseNamespace}.Infrastructure`,\n api: `${baseNamespace}.Api`,\n };\n}\n\n/**\n * Find common prefix among strings\n */\nfunction findCommonPrefix(strings: string[]): string {\n if (strings.length === 0) return '';\n if (strings.length === 1) {\n // For single project, try to extract base from name like \"MyProject.Api\"\n const parts = strings[0].split('.');\n if (parts.length > 1) {\n return parts.slice(0, -1).join('.') + '.';\n }\n return strings[0] + '.';\n }\n\n let prefix = strings[0];\n\n for (let i = 1; i < strings.length; i++) {\n while (strings[i].indexOf(prefix) !== 0 && prefix.length > 0) {\n prefix = prefix.slice(0, -1);\n }\n }\n\n // Ensure we don't cut in the middle of a namespace part\n const lastDot = prefix.lastIndexOf('.');\n if (lastDot > 0 && !prefix.endsWith('.')) {\n prefix = prefix.slice(0, lastDot + 1);\n }\n\n return prefix;\n}\n\n/**\n * Get most common element in array\n */\nfunction getMostCommon(arr: string[]): string | null {\n if (arr.length === 0) return null;\n\n const counts = new Map<string, number>();\n for (const item of arr) {\n counts.set(item, (counts.get(item) || 0) + 1);\n }\n\n let maxCount = 0;\n let mostCommon = arr[0];\n\n for (const [item, count] of counts) {\n if (count > maxCount) {\n maxCount = count;\n mostCommon = item;\n }\n }\n\n return mostCommon;\n}\n","import path from 'path';\nimport { fileURLToPath } from 'url';\nimport { fileExists, readJson } from './utils/fs.js';\nimport { logger } from './lib/logger.js';\nimport type { Config, ProjectConfig } from './types/index.js';\nimport { ProjectConfigSchema } from './types/index.js';\nimport { findCsprojFiles, detectNamespaces } from './utils/dotnet.js';\n\n// Resolve package root from bundled dist/ location\nconst __mcpFilename = fileURLToPath(import.meta.url);\nconst __mcpDirname = path.dirname(__mcpFilename);\nconst PACKAGE_ROOT = path.resolve(__mcpDirname, '..');\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 scopeTypes: ['Core', 'Extension', 'Partner', 'Community'],\n migrationFormat: '{context}_v{version}_{sequence}_{Description}',\n namespaces: {\n // Empty = auto-detect from .csproj files\n // Can be overridden in config file for custom namespaces\n domain: '',\n application: '',\n infrastructure: '',\n 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/mcp-scaffolding/service-extension.cs.hbs',\n entity: 'templates/mcp-scaffolding/entity-extension.cs.hbs',\n controller: 'templates/mcp-scaffolding/controller.cs.hbs',\n component: 'templates/mcp-scaffolding/component.tsx.hbs',\n },\n },\n // Will be loaded from .smartstack/config.json if present\n projectConfig: undefined,\n // Default to 'core', will be overridden by projectConfig.dbContext if present\n defaultDbContext: 'core',\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 (resolve relative to package root, not CWD)\n const configPath = path.join(PACKAGE_ROOT, 'config', 'mcp-defaults.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 // Load .smartstack/config.json if present (created by CLI during ss init)\n const smartstackConfigPath = path.join(\n cachedConfig.smartstack.projectPath,\n '.smartstack',\n 'config.json'\n );\n\n if (await fileExists(smartstackConfigPath)) {\n try {\n const projectConfigRaw = await readJson<ProjectConfig>(smartstackConfigPath);\n const projectConfig = ProjectConfigSchema.parse(projectConfigRaw);\n cachedConfig.projectConfig = projectConfig;\n cachedConfig.defaultDbContext = projectConfig.dbContext;\n logger.info('Project config loaded from .smartstack/config.json', {\n projectType: projectConfig.projectType,\n dbContext: projectConfig.dbContext,\n });\n } catch (error) {\n logger.warn('Failed to load .smartstack/config.json, using defaults', { error });\n }\n } else {\n // No .smartstack/config.json = platform/socle project = core context\n logger.debug('No .smartstack/config.json found, assuming platform project (core context)');\n }\n\n // Auto-detect namespaces from .csproj files if not configured\n const namespacesEmpty = !cachedConfig.conventions.namespaces.domain ||\n !cachedConfig.conventions.namespaces.application ||\n !cachedConfig.conventions.namespaces.infrastructure ||\n !cachedConfig.conventions.namespaces.api;\n\n if (namespacesEmpty && cachedConfig.smartstack.projectPath) {\n try {\n const csprojFiles = await findCsprojFiles(cachedConfig.smartstack.projectPath);\n const detected = await detectNamespaces(csprojFiles);\n\n if (detected) {\n // Only override empty values, keep user-configured ones\n if (!cachedConfig.conventions.namespaces.domain) {\n cachedConfig.conventions.namespaces.domain = detected.domain;\n }\n if (!cachedConfig.conventions.namespaces.application) {\n cachedConfig.conventions.namespaces.application = detected.application;\n }\n if (!cachedConfig.conventions.namespaces.infrastructure) {\n cachedConfig.conventions.namespaces.infrastructure = detected.infrastructure;\n }\n if (!cachedConfig.conventions.namespaces.api) {\n cachedConfig.conventions.namespaces.api = detected.api;\n }\n logger.info('Namespaces auto-detected from project', { baseNamespace: detected.baseNamespace });\n } else {\n logger.warn('Could not auto-detect namespaces from .csproj files. Configure manually in config file.');\n }\n } catch (error) {\n logger.warn('Failed to auto-detect namespaces', { error });\n }\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 scopeTypes: override.conventions?.scopeTypes || base.conventions.scopeTypes,\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 { 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\n/**\n * Get list of staged files\n */\nexport async function getStagedFiles(cwd?: string): Promise<string[]> {\n try {\n const status = await git('diff --cached --name-only', cwd);\n if (!status) return [];\n\n return status.split('\\n').filter(Boolean);\n } catch {\n return [];\n }\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';\nimport { glob } from 'glob';\n\n/**\n * Find web project folder - auto-detects any web project, not hardcoded to \"smartstack-web\"\n * Searches for: web/{name}/package.json, web/package.json, client/package.json, frontend/package.json\n */\nasync function findWebProjectFolder(projectPath: string): Promise<string | null> {\n // Priority 1: web/{project-name}-web/ (e.g., web/myproject-web/)\n const webSubfolders = await glob('web/*/', { cwd: projectPath, absolute: true });\n for (const folder of webSubfolders) {\n const packageJsonPath = path.join(folder, 'package.json');\n if (await fileExists(packageJsonPath)) {\n return folder;\n }\n }\n\n // Priority 2: web/ directly (monorepo style)\n const webDirect = path.join(projectPath, 'web');\n if (await fileExists(path.join(webDirect, 'package.json'))) {\n return webDirect;\n }\n\n // Priority 3: client/ or frontend/ folders\n const alternativeFolders = ['client', 'frontend', 'ui'];\n for (const folderName of alternativeFolders) {\n const altPath = path.join(projectPath, folderName);\n if (await fileExists(path.join(altPath, 'package.json'))) {\n return altPath;\n }\n }\n\n // Priority 4: src/web/ for nested structures\n const srcWeb = path.join(projectPath, 'src', 'web');\n if (await fileExists(path.join(srcWeb, 'package.json'))) {\n return srcWeb;\n }\n\n return null;\n}\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 - search for any web project (not hardcoded to smartstack-web)\n const webFolder = await findWebProjectFolder(projectPath);\n if (webFolder) {\n const packageJsonPath = path.join(webFolder, '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\n // Try to get version from main csproj (any *.Api.csproj, not hardcoded to SmartStack)\n if (info.csprojFiles.length > 0) {\n const mainCsproj = info.csprojFiles.find(f => /\\.Api\\.csproj$/i.test(f))\n || info.csprojFiles.find(f => /Api\\.csproj$/i.test(f))\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; // Primary API (prefers Api.Core over Api)\n apiCore?: string; // *.Api.Core project (core controllers)\n apiExtensions?: string; // *.Api project without Core (extension controllers)\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.core')) {\n // *.Api.Core project - primary API with core controllers\n structure.apiCore = projectDir;\n // Also set as primary api (Api.Core has priority)\n structure.api = projectDir;\n } else if (projectName.includes('api') && !projectName.includes('api.core')) {\n // *.Api project (not Core) - extensions\n structure.apiExtensions = projectDir;\n // Only set as primary api if apiCore not already set\n if (!structure.api) {\n structure.api = projectDir;\n }\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 (auto-detect, not hardcoded to smartstack-web)\n const webFolder = await findWebProjectFolder(projectPath);\n if (webFolder) {\n structure.web = webFolder;\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 { 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', 'layouts', 'tabs', 'hierarchies', 'protected-actions', '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', 'layouts', 'tabs', 'hierarchies', 'protected-actions']\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 if (checks.includes('layouts')) {\n await validateLayouts(structure, config, result);\n }\n\n if (checks.includes('tabs')) {\n await validateTabs(structure, config, result);\n }\n\n if (checks.includes('hierarchies')) {\n await validateHierarchies(structure, config, result);\n }\n\n if (checks.includes('protected-actions')) {\n await validateProtectedActions(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\nasync function validateLayouts(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.web) {\n result.warnings.push({\n type: 'warning',\n category: 'layouts',\n message: 'Web project not found, skipping layout validation',\n });\n return;\n }\n\n const layoutFiles = await findFiles('**/layouts/**/*.tsx', { cwd: structure.web });\n\n if (layoutFiles.length === 0) {\n result.warnings.push({\n type: 'warning',\n category: 'layouts',\n message: 'No layout files found in web/src/layouts/',\n });\n return;\n }\n\n for (const file of layoutFiles) {\n const content = await readText(file);\n const fileName = path.basename(file);\n const lines = content.split('\\n');\n\n // Check for max-w-* in className attributes (line by line to avoid ReDoS)\n let hasMaxWidth = false;\n for (const line of lines) {\n // Skip comments\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n // Check for max-w-* in className (bounded pattern)\n if (/className.*max-w-/.test(line)) {\n hasMaxWidth = true;\n break;\n }\n }\n\n if (hasMaxWidth) {\n result.errors.push({\n type: 'error',\n category: 'layouts',\n message: `Layout \"${fileName}\" uses max-w-* constraint which limits content width`,\n file: path.relative(structure.root, file),\n suggestion: 'Remove max-w-* class. Content should occupy full available width.',\n });\n }\n\n // Check for standard padding pattern lg:px-10 in className\n let hasStandardPadding = false;\n for (const line of lines) {\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n if (/className.*lg:px-10/.test(line)) {\n hasStandardPadding = true;\n break;\n }\n }\n\n if (!hasStandardPadding) {\n result.warnings.push({\n type: 'warning',\n category: 'layouts',\n message: `Layout \"${fileName}\" may be missing standard horizontal padding`,\n file: path.relative(structure.root, file),\n suggestion: 'Use lg:px-10 for consistent horizontal padding across layouts',\n });\n }\n\n // Check for h-full overflow-auto pattern in className\n let hasScrollPattern = false;\n for (const line of lines) {\n if (line.trim().startsWith('//') || line.trim().startsWith('*')) continue;\n if (/className.*h-full/.test(line) && /className.*overflow-auto/.test(line)) {\n hasScrollPattern = true;\n break;\n }\n }\n\n if (!hasScrollPattern) {\n result.warnings.push({\n type: 'warning',\n category: 'layouts',\n message: `Layout \"${fileName}\" may be missing scroll container pattern`,\n file: path.relative(structure.root, file),\n suggestion: 'Use h-full overflow-auto for proper internal scrolling',\n });\n }\n }\n}\n\nasync function validateTabs(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.web) {\n result.warnings.push({\n type: 'warning',\n category: 'tabs',\n message: 'Web project not found, skipping tab validation',\n });\n return;\n }\n\n const pageFiles = await findFiles('**/pages/**/*.tsx', { cwd: structure.web });\n\n let tabPagesCount = 0;\n let hookUsageCount = 0;\n let lazyLoadingCount = 0;\n\n for (const file of pageFiles) {\n const content = await readText(file);\n const fileName = path.basename(file);\n const lines = content.split('\\n');\n\n // Detect tab patterns in actual code (skip comments)\n let hasTabPattern = false;\n for (const line of lines) {\n const trimmed = line.trim();\n // Skip comments and empty lines\n if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*') || trimmed === '') {\n continue;\n }\n // Check for tab component usage (JSX) or state management\n if (/<Tabs|<TabList|activeTab\\s*[,=})]|setActiveTab\\s*[({]/.test(line)) {\n hasTabPattern = true;\n break;\n }\n }\n\n if (hasTabPattern) {\n tabPagesCount++;\n\n // Check for useTabNavigation hook usage\n const usesHook = content.includes('useTabNavigation');\n\n if (usesHook) {\n hookUsageCount++;\n } else {\n result.errors.push({\n type: 'error',\n category: 'tabs',\n message: `Page \"${fileName}\" has tabs but doesn't use useTabNavigation hook`,\n file: path.relative(structure.root, file),\n suggestion: 'Use useTabNavigation hook to sync tab state with URL: const { activeTab, setActiveTab } = useTabNavigation(defaultTab, VALID_TABS)',\n });\n }\n\n // Check for lazy loading patterns\n const lazyLoadingPatterns = detectTabLazyLoading(content);\n\n if (lazyLoadingPatterns.hasLazyLoading) {\n lazyLoadingCount++;\n } else if (lazyLoadingPatterns.hasDataFetching) {\n // Only warn if the page fetches data but doesn't use lazy loading\n result.warnings.push({\n type: 'warning',\n category: 'tabs',\n message: `Page \"${fileName}\" has tabs with data fetching but no lazy loading pattern detected`,\n file: path.relative(structure.root, file),\n suggestion: 'Use lazy loading for tab data: useQuery([...], fetchFn, { enabled: activeTab === \"tabName\" }) or React.lazy() for tab components',\n });\n }\n }\n }\n\n if (tabPagesCount > 0) {\n const summaryParts = [\n `${hookUsageCount}/${tabPagesCount} use useTabNavigation hook`,\n ];\n if (lazyLoadingCount > 0 || tabPagesCount > hookUsageCount) {\n summaryParts.push(`${lazyLoadingCount}/${tabPagesCount} use lazy loading`);\n }\n result.warnings.push({\n type: 'warning',\n category: 'tabs',\n message: `Tab summary: ${summaryParts.join(', ')}`,\n });\n }\n}\n\n/**\n * Detect lazy loading patterns for tab content\n * Returns whether lazy loading is used and whether data fetching is present\n */\nfunction detectTabLazyLoading(content: string): {\n hasLazyLoading: boolean;\n hasDataFetching: boolean;\n patterns: string[];\n} {\n const patterns: string[] = [];\n let hasLazyLoading = false;\n let hasDataFetching = false;\n\n // Pattern 1: useQuery with enabled: activeTab === 'xxx'\n // Matches: enabled: activeTab === 'settings'\n // Matches: enabled: activeTab === \"settings\"\n // Matches: enabled: tab === 'settings'\n // Use two-step detection: check for useQuery AND enabled condition with tab check\n const hasUseQuery = /useQuery\\s*\\(/.test(content);\n const hasEnabledTabCondition = /enabled\\s*:\\s*(?:activeTab|tab|currentTab)\\s*===\\s*['\"][^'\"]+['\"]/.test(content);\n if (hasUseQuery && hasEnabledTabCondition) {\n hasLazyLoading = true;\n patterns.push('useQuery with enabled condition');\n }\n\n // Pattern 2: React.lazy() for component imports\n // Matches: React.lazy(() => import('./TabSettings'))\n // Matches: const TabSettings = lazy(() => import('./tabs/TabSettings'))\n const reactLazyPattern = /(?:React\\.)?lazy\\s*\\(\\s*\\(\\)\\s*=>\\s*import\\s*\\(/;\n if (reactLazyPattern.test(content)) {\n hasLazyLoading = true;\n patterns.push('React.lazy() imports');\n }\n\n // Pattern 3: Suspense with fallback (indicates lazy loading is configured)\n // Matches: <Suspense fallback={...}>\n const suspensePattern = /<Suspense\\s+[^>]*fallback\\s*=/;\n if (suspensePattern.test(content)) {\n hasLazyLoading = true;\n patterns.push('Suspense with fallback');\n }\n\n // Pattern 4: Conditional rendering based on activeTab with component\n // Matches: {activeTab === 'settings' && <SettingsTab />}\n // Matches: activeTab === 'info' ? <InfoTab /> : null\n const conditionalRenderPattern = /(?:activeTab|tab|currentTab)\\s*===\\s*['\"][^'\"]+['\"]\\s*(?:&&|\\?)\\s*<[A-Z]/;\n if (conditionalRenderPattern.test(content)) {\n hasLazyLoading = true;\n patterns.push('Conditional tab rendering');\n }\n\n // Pattern 5: useSWR with conditional fetching\n // Matches: useSWR(activeTab === 'xxx' ? key : null, ...)\n const useSWRConditionalPattern = /useSWR\\s*\\(\\s*(?:activeTab|tab|currentTab)\\s*===\\s*['\"][^'\"]+['\"]\\s*\\?/;\n if (useSWRConditionalPattern.test(content)) {\n hasLazyLoading = true;\n patterns.push('useSWR with conditional key');\n }\n\n // Detect if the page has data fetching at all (to determine if lazy loading is relevant)\n // Check for useQuery, useSWR, fetch, axios patterns\n const dataFetchingPatterns = [\n /useQuery\\s*\\(/,\n /useSWR\\s*\\(/,\n /useMutation\\s*\\(/,\n /fetch\\s*\\(/,\n /axios\\./,\n /useEffect\\s*\\([^)]*\\{[^}]*(?:fetch|axios|api\\.)/s,\n ];\n\n for (const pattern of dataFetchingPatterns) {\n if (pattern.test(content)) {\n hasDataFetching = true;\n break;\n }\n }\n\n return {\n hasLazyLoading,\n hasDataFetching,\n patterns,\n };\n}\n\nasync function validateHierarchies(\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: 'hierarchies',\n message: 'Domain project not found, skipping hierarchy validation',\n });\n return;\n }\n\n // Find entity files\n const entityFiles = await findFiles('**/*.cs', { cwd: structure.domain });\n\n interface HierarchyInfo {\n name: string;\n file: string;\n isSelfReferencing: boolean;\n selfRefField?: string;\n parentEntity?: string;\n isTenantAware: boolean;\n childCollections: string[];\n depth: number;\n }\n\n const hierarchies: HierarchyInfo[] = [];\n const entityNames = new Set<string>();\n\n // First pass: collect all entity names and detect hierarchies\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 (\n fileName.endsWith('Dto') ||\n fileName.endsWith('Command') ||\n fileName.endsWith('Query') ||\n fileName.endsWith('Handler') ||\n fileName.endsWith('Validator') ||\n fileName.endsWith('Exception') ||\n fileName.startsWith('I')\n ) {\n continue;\n }\n\n // Check for class declaration\n const classMatch = content.match(\n /public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*([^{]+))?/\n );\n if (!classMatch) continue;\n\n const entityName = classMatch[1];\n const inheritance = classMatch[2]?.trim() || '';\n\n // Must be an entity\n const hasBaseEntity = inheritance.includes('BaseEntity');\n const hasSystemEntity = inheritance.includes('SystemEntity');\n if (!hasBaseEntity && !hasSystemEntity) continue;\n\n entityNames.add(entityName);\n const hasITenantEntity = inheritance.includes('ITenantEntity');\n\n // Detect self-referencing (ParentId of same type)\n const selfRefMatch = content.match(\n new RegExp(\n `public\\\\s+(?:Guid\\\\??|${entityName}\\\\??)\\\\s+(Parent(?:Id)?|Parent${entityName}(?:Id)?)\\\\s*\\\\{`,\n 'i'\n )\n );\n\n // Detect child collections\n const childCollections: string[] = [];\n const collectionMatches = content.matchAll(\n /public\\s+(?:virtual\\s+)?ICollection<(\\w+)>\\s+(\\w+)\\s*\\{/g\n );\n for (const match of collectionMatches) {\n childCollections.push(match[1]);\n }\n\n // Detect parent entity from FK\n const fkMatches = content.matchAll(/public\\s+Guid\\s+(\\w+Id)\\s*\\{[^}]+\\}/g);\n let parentEntity: string | undefined;\n for (const match of fkMatches) {\n const propName = match[1];\n if (propName.toLowerCase().includes('parent')) continue;\n if (propName === 'TenantId') continue;\n const refEntity = propName.replace(/Id$/, '');\n if (refEntity !== entityName) {\n parentEntity = refEntity;\n break;\n }\n }\n\n if (selfRefMatch || childCollections.length > 0 || parentEntity) {\n hierarchies.push({\n name: entityName,\n file: path.relative(structure.root, file),\n isSelfReferencing: !!selfRefMatch,\n selfRefField: selfRefMatch ? selfRefMatch[1] : undefined,\n parentEntity,\n isTenantAware: hasITenantEntity,\n childCollections,\n depth: 0, // Will be calculated later\n });\n }\n }\n\n // Validation checks\n let selfRefCount = 0;\n let parentChildCount = 0;\n let deepHierarchyCount = 0;\n\n for (const h of hierarchies) {\n if (h.isSelfReferencing) {\n selfRefCount++;\n\n // Check 1: Self-referencing entities should have index on ParentId\n result.warnings.push({\n type: 'warning',\n category: 'hierarchies',\n message: `Entity \"${h.name}\" is self-referencing via \"${h.selfRefField}\"`,\n file: h.file,\n suggestion: `Consider using TVF with CTE for efficient hierarchy traversal. Ensure index on ${h.selfRefField}.`,\n });\n\n // Check 2: Self-referencing permission/group entities - critical for TVF\n if (\n h.name.toLowerCase().includes('group') ||\n h.name.toLowerCase().includes('permission') ||\n h.name.toLowerCase().includes('role')\n ) {\n result.warnings.push({\n type: 'warning',\n category: 'hierarchies',\n message: `Permission/Group entity \"${h.name}\" detected with self-reference`,\n file: h.file,\n suggestion: `CRITICAL: Use fn_Get${h.name}Hierarchy TVF for recursive permission resolution. Run analyze_hierarchy_patterns for SQL template.`,\n });\n }\n }\n\n if (h.parentEntity) {\n parentChildCount++;\n\n // Check 3: Parent entity should exist\n if (!entityNames.has(h.parentEntity)) {\n result.errors.push({\n type: 'error',\n category: 'hierarchies',\n message: `Entity \"${h.name}\" references non-existent parent \"${h.parentEntity}\"`,\n file: h.file,\n suggestion: `Create the ${h.parentEntity} entity or fix the foreign key reference.`,\n });\n }\n }\n\n // Check 4: Tenant awareness consistency\n if (h.parentEntity && entityNames.has(h.parentEntity)) {\n const parentInfo = hierarchies.find((x) => x.name === h.parentEntity);\n if (parentInfo && parentInfo.isTenantAware && !h.isTenantAware) {\n result.errors.push({\n type: 'error',\n category: 'hierarchies',\n message: `Entity \"${h.name}\" has tenant-aware parent \"${h.parentEntity}\" but is not tenant-aware itself`,\n file: h.file,\n suggestion: `Add ITenantEntity interface to ${h.name} for consistent tenant isolation.`,\n });\n }\n }\n\n // Check 5: Deep hierarchies (estimated > 3 levels)\n if (h.childCollections.length > 0) {\n for (const child of h.childCollections) {\n const childInfo = hierarchies.find((x) => x.name === child);\n if (childInfo && childInfo.childCollections.length > 0) {\n deepHierarchyCount++;\n result.warnings.push({\n type: 'warning',\n category: 'hierarchies',\n message: `Deep hierarchy detected: ${h.name} → ${child} → ...`,\n file: h.file,\n suggestion: `Consider TVF for efficient traversal. Run analyze_hierarchy_patterns for recommendations.`,\n });\n }\n }\n }\n }\n\n // Summary\n if (hierarchies.length > 0) {\n result.warnings.push({\n type: 'warning',\n category: 'hierarchies',\n message: `Hierarchy summary: ${selfRefCount} self-referencing, ${parentChildCount} parent-child, ${deepHierarchyCount} deep hierarchies detected`,\n });\n }\n}\n\nasync function validateProtectedActions(\n structure: ReturnType<typeof findSmartStackStructure> extends Promise<infer T> ? T : never,\n _config: Config,\n result: ValidationResult\n): Promise<void> {\n if (!structure.web) {\n result.warnings.push({\n type: 'warning',\n category: 'protected-actions',\n message: 'Web project not found, skipping protected actions validation',\n });\n return;\n }\n\n // Find all TSX files in pages and components directories\n const pageFiles = await findFiles('**/pages/**/*.tsx', { cwd: structure.web });\n const componentFiles = await findFiles('**/components/**/*.tsx', { cwd: structure.web });\n const allFiles = [...pageFiles, ...componentFiles];\n\n // CRUD action patterns to detect in button labels or onClick handlers\n const actionPatterns = {\n create: ['create', 'add', 'new', 'créer', 'ajouter', 'nouveau'],\n update: ['edit', 'update', 'modify', 'modifier', 'éditer', 'save', 'enregistrer'],\n delete: ['delete', 'remove', 'supprimer', 'retirer'],\n execute: ['execute', 'run', 'sync', 'exécuter', 'lancer', 'synchroniser'],\n };\n\n let protectedButtonCount = 0;\n let hasPermissionCount = 0;\n let unprotectedCount = 0;\n const unprotectedButtons: { file: string; line: number; action: string; code: string }[] = [];\n\n for (const file of allFiles) {\n const content = await readText(file);\n const lines = content.split('\\n');\n\n // Skip if file uses ProtectedButton (already following convention)\n const usesProtectedButton = content.includes('<ProtectedButton');\n if (usesProtectedButton) {\n protectedButtonCount++;\n continue;\n }\n\n // Scan for button elements with CRUD-like actions\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const trimmed = line.trim();\n\n // Skip comments\n if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) {\n continue;\n }\n\n // Check for button patterns: <button, <Button, onClick with action handlers\n const buttonMatch = /<(?:button|Button)[^>]*>([^<]*)<\\/|onClick\\s*=\\s*\\{[^}]*handle(Create|Delete|Edit|Update|Remove|Save|Add|Sync|Execute)/i.exec(line);\n\n if (buttonMatch) {\n const buttonContent = buttonMatch[1]?.toLowerCase() || '';\n const handlerAction = buttonMatch[2]?.toLowerCase() || '';\n\n // Detect which action type this button represents\n let detectedAction: string | null = null;\n\n for (const [action, keywords] of Object.entries(actionPatterns)) {\n if (keywords.some(kw => buttonContent.includes(kw) || handlerAction.includes(kw))) {\n detectedAction = action;\n break;\n }\n }\n\n if (detectedAction) {\n // Check if this button has permission protection\n // Look at surrounding context (5 lines before and after)\n const startLine = Math.max(0, i - 5);\n const endLine = Math.min(lines.length - 1, i + 5);\n const context = lines.slice(startLine, endLine + 1).join('\\n');\n\n const hasPermissionCheck =\n context.includes('hasPermission') ||\n context.includes('canCreate') ||\n context.includes('canEdit') ||\n context.includes('canUpdate') ||\n context.includes('canDelete') ||\n context.includes('canExecute') ||\n context.includes('disabled={!can');\n\n if (!hasPermissionCheck) {\n unprotectedCount++;\n unprotectedButtons.push({\n file: path.relative(structure.root, file),\n line: i + 1,\n action: detectedAction,\n code: line.trim().substring(0, 80),\n });\n } else {\n hasPermissionCount++;\n }\n }\n }\n }\n }\n\n // Report unprotected buttons (limit to first 10 for readability)\n const reportedButtons = unprotectedButtons.slice(0, 10);\n for (const btn of reportedButtons) {\n result.warnings.push({\n type: 'warning',\n category: 'protected-actions',\n message: `Button with \"${btn.action}\" action may be missing permission check`,\n file: btn.file,\n line: btn.line,\n suggestion: `Use <ProtectedButton action=\"${btn.action}\" navRoute=\"...\"> or add hasPermission check`,\n });\n }\n\n if (unprotectedButtons.length > 10) {\n result.warnings.push({\n type: 'warning',\n category: 'protected-actions',\n message: `... and ${unprotectedButtons.length - 10} more unprotected buttons`,\n });\n }\n\n // Summary\n const totalActionButtons = protectedButtonCount + hasPermissionCount + unprotectedCount;\n if (totalActionButtons > 0) {\n const protectedPercentage = Math.round(\n ((protectedButtonCount + hasPermissionCount) / totalActionButtons) * 100\n );\n result.warnings.push({\n type: 'warning',\n category: 'protected-actions',\n message: `Protected actions summary: ${protectedButtonCount} use ProtectedButton, ${hasPermissionCount} use hasPermission, ${unprotectedCount} potentially unprotected (${protectedPercentage}% protected)`,\n });\n\n if (protectedPercentage < 80 && totalActionButtons > 5) {\n result.errors.push({\n type: 'error',\n category: 'protected-actions',\n message: `Less than 80% of action buttons are protected (${protectedPercentage}%)`,\n suggestion: 'Migrate action buttons to use <ProtectedButton> component for consistent permission checking',\n });\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 withSeedData: {\n type: 'boolean',\n description: 'For entity type: generate centralized SeedData file in Seeding/Data/{Domain}/',\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 withHierarchyFunction: {\n type: 'boolean',\n description: 'For entity type with self-reference (ParentId): generate TVF SQL script for hierarchy traversal',\n },\n hierarchyDirection: {\n type: 'string',\n enum: ['ancestors', 'descendants', 'both'],\n description: 'Direction for hierarchy traversal function (default: both)',\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\n/**\n * Resolves navRoute hierarchy into folder segments for organized file placement.\n * navRoute format: \"context.application.module[.section]\"\n * Example: \"platform.administration.tenants\" → { context: \"Platform\", application: \"Administration\", module: \"Tenants\" }\n *\n * When navRoute is absent, returns empty strings → backward-compatible flat paths.\n */\nfunction resolveHierarchy(navRoute?: string): {\n context: string;\n application: string;\n module: string;\n /** Subfolder for Domain/Application layers: Context/Application/Module */\n domainPath: string;\n /** Subfolder for Infrastructure layers: Module only */\n infraPath: string;\n /** Subfolder for Controller area: Context */\n controllerArea: string;\n} {\n if (!navRoute) {\n return { context: '', application: '', module: '', domainPath: '', infraPath: '', controllerArea: '' };\n }\n\n const segments = navRoute.split('.');\n const toPascal = (s: string) =>\n s.split('-').map(p => p.charAt(0).toUpperCase() + p.slice(1)).join('');\n\n const context = segments[0] ? toPascal(segments[0]) : '';\n const application = segments[1] ? toPascal(segments[1]) : '';\n const module = segments[2] ? toPascal(segments[2]) : segments[1] ? toPascal(segments[1]) : '';\n\n // Domain/Application: full hierarchy\n let domainPath = '';\n if (segments.length >= 3) {\n domainPath = path.join(context, application, module);\n } else if (segments.length === 2) {\n domainPath = path.join(context, module);\n } else if (segments.length === 1) {\n domainPath = context;\n }\n\n // Infrastructure: module-level grouping\n const infraPath = module || '';\n\n // Controller: context as area\n const controllerArea = context;\n\n return { context, application, module, domainPath, infraPath, controllerArea };\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 // Note: tablePrefix should be specified based on domain (e.g., 'ref_', 'cfg_')\n // No longer using scope-based prefixes (core_, ext_) - using Scope field instead\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 withSeedData?: boolean;\n seedDataDomain?: string;\n entityProperties?: EntityProperty[];\n navRoute?: string;\n navRouteSuffix?: string;\n withHierarchyFunction?: boolean;\n hierarchyDirection?: 'ancestors' | 'descendants' | 'both';\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\n // Determine DbContext based on schema/extension type\n // Priority: explicit schema > clientExtension flag > project config default\n const schema = options?.schema || (isClientExtension ? 'extensions' : config.defaultDbContext);\n const dbContextName = schema === 'extensions' ? 'ExtensionsDbContext' : 'CoreDbContext';\n const dbContextInterface = schema === 'extensions' ? 'IExtensionsDbContext' : 'ICoreDbContext';\n const migrationPrefix = schema; // Use full context name: 'core' or 'extensions'\n\n result.instructions.push('### Next Steps:');\n result.instructions.push(`1. Add DbSet to ${dbContextInterface} and ${dbContextName}: \\`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 ${migrationPrefix}_vX.X.X_XXX_Add${name} --context ${dbContextName}\\``);\n result.instructions.push(`${withRepository ? (withValidation ? '6' : '5') : (withValidation ? '5' : '4')}. Run migration: \\`dotnet ef database update --context ${dbContextName}\\``);\n if (!skipComponent) {\n const featureHierarchy = resolveHierarchy(options?.navRoute);\n const featureComponentPath = featureHierarchy.context && featureHierarchy.module\n ? `@/components/${featureHierarchy.context.toLowerCase()}/${featureHierarchy.module.toLowerCase()}/${name}`\n : `./components/${name}`;\n result.instructions.push(`Import component: \\`import { ${name} } from '${featureComponentPath}';\\``);\n }\n}\n\nasync function scaffoldService(\n name: string,\n options: { namespace?: string; methods?: string[]; dryRun?: boolean; navRoute?: 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 hierarchy = resolveHierarchy(options?.navRoute);\n const interfaceNamespace = options?.namespace || `${config.conventions.namespaces.application}.Common.Interfaces`;\n const implNamespace = hierarchy.infraPath\n ? `${config.conventions.namespaces.infrastructure}.Services.${hierarchy.infraPath}`\n : `${config.conventions.namespaces.infrastructure}.Services`;\n const methods = options?.methods || ['GetByIdAsync', 'GetAllAsync', 'CreateAsync', 'UpdateAsync', 'DeleteAsync'];\n\n // Interface template — placed in Application/Common/Interfaces/\n const interfaceTemplate = `using System.Threading;\nusing System.Threading.Tasks;\nusing System.Collections.Generic;\n\nnamespace {{interfaceNamespace}};\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 — placed in Infrastructure/Services/{Module}/\n const implementationTemplate = `using System.Threading;\nusing System.Threading.Tasks;\nusing System.Collections.Generic;\nusing Microsoft.Extensions.Logging;\n\nnamespace {{implNamespace}};\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 = { interfaceNamespace, implNamespace, 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 — interface in Application/Common/Interfaces/, impl in Infrastructure/Services/{Module}/\n const projectRoot = config.smartstack.projectPath;\n const appPath = structure.application || projectRoot;\n const infraPath = structure.infrastructure || path.join(projectRoot, 'Infrastructure');\n\n const interfacesDir = path.join(appPath, 'Common', 'Interfaces');\n const implDir = hierarchy.infraPath\n ? path.join(infraPath, 'Services', hierarchy.infraPath)\n : path.join(infraPath, 'Services');\n\n const interfacePath = path.join(interfacesDir, `I${name}Service.cs`);\n const implementationPath = path.join(implDir, `${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(interfacesDir);\n await ensureDirectory(implDir);\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; withSeedData?: boolean; seedDataDomain?: string; withHierarchyFunction?: boolean; hierarchyDirection?: 'ancestors' | 'descendants' | 'both'; navRoute?: 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 hierarchy = resolveHierarchy(options?.navRoute);\n const namespace = options?.namespace || (hierarchy.domainPath\n ? `${config.conventions.namespaces.domain}.${hierarchy.domainPath.replace(/[\\\\/]/g, '.')}`\n : 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 — entity in Domain/{Context}/{App}/{Module}/, config in Configurations/{Module}/\n const projectRoot = config.smartstack.projectPath;\n const domainBase = structure.domain || path.join(projectRoot, 'Domain');\n const infraBase = structure.infrastructure || path.join(projectRoot, 'Infrastructure');\n\n const entityDir = hierarchy.domainPath\n ? path.join(domainBase, hierarchy.domainPath)\n : domainBase;\n const configDir = hierarchy.infraPath\n ? path.join(infraBase, 'Persistence', 'Configurations', hierarchy.infraPath)\n : path.join(infraBase, 'Persistence', 'Configurations');\n\n const entityFilePath = path.join(entityDir, `${name}.cs`);\n const configFilePath = path.join(configDir, `${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(entityDir);\n await ensureDirectory(configDir);\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 // Determine DbContext based on schema\n const dbContextName = schema === 'extensions' ? 'ExtensionsDbContext' : 'CoreDbContext';\n const dbContextInterface = schema === 'extensions' ? 'IExtensionsDbContext' : 'ICoreDbContext';\n const migrationPrefix = schema; // Use full context name: 'core' or 'extensions'\n\n result.instructions.push(`Add DbSet to ${dbContextInterface}:`);\n result.instructions.push(`public DbSet<${name}> ${name}s => Set<${name}>();`);\n result.instructions.push('');\n result.instructions.push(`And implementation in ${dbContextName}:`);\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 ${migrationPrefix}_vX.X.X_XXX_Add${name} --context ${dbContextName}`);\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 // Generate SeedData file if requested\n if (options?.withSeedData) {\n result.instructions.push('');\n result.instructions.push('### Seed Data');\n await scaffoldSeedData(name, options, structure, config, result, dryRun);\n }\n\n // Generate TVF hierarchy function if requested\n if (options?.withHierarchyFunction) {\n result.instructions.push('');\n result.instructions.push('### Hierarchy Function (TVF)');\n await scaffoldHierarchyFunction(name, options, structure, config, result, dryRun);\n }\n}\n\nasync function scaffoldSeedData(\n name: string,\n options: { seedDataDomain?: string; tablePrefix?: 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 // Determine domain folder based on tablePrefix or explicit seedDataDomain\n const tablePrefix = options?.tablePrefix || 'ref_';\n const domainMap: Record<string, string> = {\n 'auth_': 'Authorization',\n 'nav_': 'Navigation',\n 'usr_': 'User',\n 'wkf_': 'Communications',\n 'cfg_': 'Configuration',\n 'ai_': 'AI',\n 'entra_': 'Entra',\n 'ref_': 'Reference',\n 'support_': 'Support',\n 'loc_': 'Localization',\n };\n const domain = options?.seedDataDomain || domainMap[tablePrefix] || 'Reference';\n const isSystemEntity = options?.isSystemEntity || false;\n\n // SeedData template following the centralized pattern\n const seedDataTemplate = `using SmartStack.Domain.{{domainNamespace}};\n\nnamespace SmartStack.Infrastructure.Persistence.Seeding.Data.{{domain}};\n\n/// <summary>\n/// Donnees seed pour {{name}}.\n/// Centralise les IDs et donnees d'initialisation.\n/// </summary>\npublic static class {{name}}SeedData\n{\n // ============================================================\n // IDs - Documenter chaque ID avec son role\n // ============================================================\n\n /// <summary>ID exemple - A remplacer par vos IDs</summary>\n public static readonly Guid ExampleId = Guid.Parse(\"{{exampleGuid}}\");\n\n // ============================================================\n // CODES / CONSTANTS\n // ============================================================\n\n public const string ExampleCode = \"example\";\n\n // ============================================================\n // SEED DATA\n // ============================================================\n\n /// <summary>\n /// Retourne toutes les donnees seed pour {{name}}.\n /// Appelé depuis {{name}}Configuration.HasData()\n /// </summary>\n public static object[] GetSeedData()\n {\n var seedDate = SeedConstants.SeedDate;\n\n return new object[]\n {\n // Exemple - A remplacer par vos donnees\n new\n {\n Id = ExampleId,\n{{#unless isSystemEntity}}\n TenantId = (Guid?)null, // Seed data systeme sans tenant\n{{/unless}}\n Code = ExampleCode,\n // TODO: Ajouter les proprietes specifiques\n IsDeleted = false,\n CreatedAt = seedDate\n }\n };\n }\n}\n`;\n\n // Generate a random GUID for the example\n const exampleGuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n\n const context = {\n name,\n domain,\n domainNamespace: domain,\n isSystemEntity,\n exampleGuid,\n };\n\n const seedDataContent = Handlebars.compile(seedDataTemplate)(context);\n\n // Determine output path: Infrastructure/Persistence/Seeding/Data/{Domain}/{Name}SeedData.cs\n const projectRoot = config.smartstack.projectPath;\n const infraPath = structure.infrastructure || path.join(projectRoot, 'Infrastructure');\n const seedDataPath = path.join(infraPath, 'Persistence', 'Seeding', 'Data', domain);\n const seedDataFilePath = path.join(seedDataPath, `${name}SeedData.cs`);\n\n // Validate paths don't escape project directory\n validatePathSecurity(seedDataFilePath, projectRoot);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(seedDataPath);\n await writeText(seedDataFilePath, seedDataContent);\n }\n\n result.files.push({ path: seedDataFilePath, content: seedDataContent, type: 'created' });\n\n result.instructions.push(`SeedData file generated in Seeding/Data/${domain}/`);\n result.instructions.push('');\n result.instructions.push('Update your Configuration to use centralized SeedData:');\n result.instructions.push('```csharp');\n result.instructions.push(`// In ${name}Configuration.cs`);\n result.instructions.push(`using SmartStack.Infrastructure.Persistence.Seeding.Data.${domain};`);\n result.instructions.push('');\n result.instructions.push(`builder.HasData(${name}SeedData.GetSeedData());`);\n result.instructions.push('```');\n result.instructions.push('');\n result.instructions.push('Pattern to follow:');\n result.instructions.push('1. Define public static readonly Guid IDs');\n result.instructions.push('2. Define const string codes');\n result.instructions.push('3. Implement GetSeedData() returning object[]');\n result.instructions.push('4. Reference other SeedData IDs for foreign keys');\n}\n\nasync function scaffoldHierarchyFunction(\n name: string,\n options: { tablePrefix?: string; schema?: string; hierarchyDirection?: 'ancestors' | 'descendants' | 'both'; 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 tablePrefix = options?.tablePrefix || 'ref_';\n const schema = options?.schema || config.conventions.schemas.platform;\n // hierarchyDirection reserved for future use to generate different TVF variants\n const tableName = `${tablePrefix}${name}s`;\n\n // SQL TVF Template\n const tvfTemplate = `-- ============================================================================\n-- Table-Valued Function: fn_Get{{name}}Hierarchy\n-- Purpose: Recursively traverse {{name}} hierarchy (ancestors/descendants)\n-- Generated by: SmartStack MCP scaffold_extension\n-- ============================================================================\n\n-- Drop existing function if it exists\nIF OBJECT_ID('[{{schema}}].[fn_Get{{name}}Hierarchy]', 'IF') IS NOT NULL\n DROP FUNCTION [{{schema}}].[fn_Get{{name}}Hierarchy];\nGO\n\nCREATE FUNCTION [{{schema}}].[fn_Get{{name}}Hierarchy]\n(\n @{{nameLower}}Id UNIQUEIDENTIFIER,\n @Direction VARCHAR(11) = 'descendants' -- 'ancestors', 'descendants', or 'both'\n)\nRETURNS TABLE\nAS\nRETURN\n(\n WITH HierarchyCTE AS (\n -- ========================================\n -- Base case: starting node\n -- ========================================\n SELECT\n Id,\n ParentId,\n Code,\n TenantId,\n 0 AS [Level],\n CAST(Id AS NVARCHAR(MAX)) AS [Path],\n 'self' AS Direction\n FROM [{{schema}}].[{{tableName}}]\n WHERE Id = @{{nameLower}}Id\n AND IsDeleted = 0\n\n UNION ALL\n\n -- ========================================\n -- Recursive: ancestors (climb up the tree)\n -- ========================================\n SELECT\n parent.Id,\n parent.ParentId,\n parent.Code,\n parent.TenantId,\n h.[Level] - 1,\n CAST(parent.Id AS NVARCHAR(MAX)) + '/' + h.[Path],\n 'ancestor' AS Direction\n FROM [{{schema}}].[{{tableName}}] parent\n INNER JOIN HierarchyCTE h ON parent.Id = h.ParentId\n WHERE parent.IsDeleted = 0\n AND @Direction IN ('ancestors', 'both')\n AND h.[Level] > -50 -- Prevent infinite recursion\n\n UNION ALL\n\n -- ========================================\n -- Recursive: descendants (go down the tree)\n -- ========================================\n SELECT\n child.Id,\n child.ParentId,\n child.Code,\n child.TenantId,\n h.[Level] + 1,\n h.[Path] + '/' + CAST(child.Id AS NVARCHAR(MAX)),\n 'descendant' AS Direction\n FROM [{{schema}}].[{{tableName}}] child\n INNER JOIN HierarchyCTE h ON child.ParentId = h.Id\n WHERE child.IsDeleted = 0\n AND @Direction IN ('descendants', 'both')\n AND h.[Level] < 50 -- Prevent infinite recursion\n )\n SELECT\n Id,\n ParentId,\n Code,\n TenantId,\n [Level],\n [Path],\n Direction,\n ABS([Level]) AS Depth -- Absolute depth from starting node\n FROM HierarchyCTE\n WHERE (\n @Direction = 'both'\n OR (@Direction = 'ancestors' AND Direction IN ('self', 'ancestor'))\n OR (@Direction = 'descendants' AND Direction IN ('self', 'descendant'))\n )\n);\nGO\n\n-- ============================================================================\n-- Usage Examples\n-- ============================================================================\n\n-- Get all descendants of a {{name}}\n-- SELECT * FROM [{{schema}}].[fn_Get{{name}}Hierarchy](@id, 'descendants') ORDER BY [Level];\n\n-- Get all ancestors of a {{name}}\n-- SELECT * FROM [{{schema}}].[fn_Get{{name}}Hierarchy](@id, 'ancestors') ORDER BY [Level] DESC;\n\n-- Get full hierarchy (ancestors + descendants)\n-- SELECT * FROM [{{schema}}].[fn_Get{{name}}Hierarchy](@id, 'both') ORDER BY [Level];\n\n-- Get all {{name}}s at a specific level\n-- SELECT * FROM [{{schema}}].[fn_Get{{name}}Hierarchy](@rootId, 'descendants') WHERE [Level] = 2;\n\n-- Check if user belongs to a specific {{name}} hierarchy\n-- SELECT CASE WHEN EXISTS (\n-- SELECT 1 FROM [{{schema}}].[fn_Get{{name}}Hierarchy](@userId{{name}}Id, 'ancestors')\n-- WHERE Id = @target{{name}}Id\n-- ) THEN 1 ELSE 0 END AS BelongsToHierarchy;\n`;\n\n const context = {\n name,\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\n tableName,\n schema,\n };\n\n const tvfContent = Handlebars.compile(tvfTemplate)(context);\n\n // Determine output path\n const projectRoot = config.smartstack.projectPath;\n const infraPath = structure.infrastructure || path.join(projectRoot, 'Infrastructure');\n const scriptsPath = path.join(infraPath, 'Persistence', 'Scripts', 'Functions');\n const tvfFilePath = path.join(scriptsPath, `fn_Get${name}Hierarchy.sql`);\n\n // Validate paths\n validatePathSecurity(tvfFilePath, projectRoot);\n\n // Write file (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(scriptsPath);\n await writeText(tvfFilePath, tvfContent);\n }\n\n result.files.push({ path: tvfFilePath, content: tvfContent, type: 'created' });\n\n result.instructions.push('TVF hierarchy function generated!');\n result.instructions.push('');\n result.instructions.push('**Next Steps:**');\n result.instructions.push(`1. Run the SQL script to create the function in your database`);\n result.instructions.push(`2. Add a method to I${name}Repository for hierarchy queries:`);\n result.instructions.push('```csharp');\n result.instructions.push(`Task<IReadOnlyList<${name}HierarchyDto>> GetHierarchyAsync(`);\n result.instructions.push(` Guid ${name.toLowerCase()}Id,`);\n result.instructions.push(` HierarchyDirection direction,`);\n result.instructions.push(` CancellationToken ct = default);`);\n result.instructions.push('```');\n result.instructions.push('');\n result.instructions.push(`3. Create ${name}HierarchyDto:`);\n result.instructions.push('```csharp');\n result.instructions.push(`public record ${name}HierarchyDto(`);\n result.instructions.push(' Guid Id,');\n result.instructions.push(' Guid? ParentId,');\n result.instructions.push(' string Code,');\n result.instructions.push(' Guid TenantId,');\n result.instructions.push(' int Level,');\n result.instructions.push(' string Path,');\n result.instructions.push(' string Direction,');\n result.instructions.push(' int Depth);');\n result.instructions.push('```');\n result.instructions.push('');\n result.instructions.push('4. Implement using raw SQL in repository:');\n result.instructions.push('```csharp');\n result.instructions.push(`var sql = \"SELECT * FROM [${schema}].[fn_Get${name}Hierarchy]({0}, {1})\";`);\n result.instructions.push(`return await _context.Database`);\n result.instructions.push(` .SqlQueryRaw<${name}HierarchyDto>(sql, id, direction.ToString().ToLower())`);\n result.instructions.push(` .ToListAsync(ct);`);\n result.instructions.push('```');\n result.instructions.push('');\n result.instructions.push(`**Pattern Recommendation**: TVF with CTE is optimal for:`);\n result.instructions.push('- Permission/role hierarchies (recursive permission check)');\n result.instructions.push('- Organization charts (reporting structure)');\n result.instructions.push('- Category trees (nested categories)');\n result.instructions.push('- Group memberships (user belongs to parent groups)');\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 hierarchy = resolveHierarchy(options?.navRoute);\n const namespace = options?.namespace || (hierarchy.controllerArea\n ? `${config.conventions.namespaces.api}.Controllers.${hierarchy.controllerArea}`\n : `${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 controllersDir = hierarchy.controllerArea\n ? path.join(apiPath, 'Controllers', hierarchy.controllerArea)\n : path.join(apiPath, 'Controllers');\n\n const controllerFilePath = path.join(controllersDir, `${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(controllersDir);\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; navRoute?: 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 hierarchy = resolveHierarchy(options?.navRoute);\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 — components in components/{context}/{module}/, hooks flat\n const projectRoot = config.smartstack.projectPath;\n // Fallback to 'web' folder (not hardcoded to smartstack-web)\n const webPath = structure.web || path.join(projectRoot, 'web');\n const componentsBase = path.join(webPath, 'src', 'components');\n const componentsPath = options?.outputPath\n ? options.outputPath\n : (hierarchy.context && hierarchy.module\n ? path.join(componentsBase, hierarchy.context.toLowerCase(), hierarchy.module.toLowerCase())\n : componentsBase);\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 const componentImportPath = hierarchy.context && hierarchy.module\n ? `@/components/${hierarchy.context.toLowerCase()}/${hierarchy.module.toLowerCase()}/${name}`\n : `./components/${name}`;\n result.instructions.push(`import { ${name} } from '${componentImportPath}';`);\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 hierarchy = resolveHierarchy(options?.navRoute);\n const namespace = options?.namespace || (hierarchy.domainPath\n ? `${config.conventions.namespaces.application}.${hierarchy.domainPath.replace(/[\\\\/]/g, '.')}.DTOs`\n : `${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 — DTOs in Application/{Context}/{Module}/DTOs/\n const basePath = structure.application || config.smartstack.projectPath;\n const dtosPath = hierarchy.domainPath\n ? path.join(basePath, hierarchy.domainPath, 'DTOs')\n : 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 hierarchy = resolveHierarchy(options?.navRoute);\n const namespace = options?.namespace || (hierarchy.domainPath\n ? `${config.conventions.namespaces.application}.${hierarchy.domainPath.replace(/[\\\\/]/g, '.')}.Validators`\n : `${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 — Validators in Application/{Context}/{Module}/Validators/\n const basePath = structure.application || config.smartstack.projectPath;\n const validatorsPath = hierarchy.domainPath\n ? path.join(basePath, hierarchy.domainPath, 'Validators')\n : 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 hierarchy = resolveHierarchy(options?.navRoute);\n const isSystemEntity = options?.isSystemEntity || false;\n const schema = options?.schema || config.conventions.schemas.platform;\n const dbContextName = schema === 'extensions' ? 'ExtensionsDbContext' : 'CoreDbContext';\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 {{dbContextName}} _context;\n\n public {{name}}Repository({{dbContextName}} 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 dbContextName,\n };\n\n const interfaceContent = Handlebars.compile(interfaceTemplate)(context);\n const implementationContent = Handlebars.compile(implementationTemplate)(context);\n\n // Determine output paths — Repository interface in Application, impl in Infrastructure/Repositories/{Module}/\n const appPath = structure.application || config.smartstack.projectPath;\n const infraPath = structure.infrastructure || path.join(config.smartstack.projectPath, 'Infrastructure');\n\n const appRepoDir = hierarchy.infraPath\n ? path.join(appPath, 'Repositories', hierarchy.infraPath)\n : path.join(appPath, 'Repositories');\n const infraRepoDir = hierarchy.infraPath\n ? path.join(infraPath, 'Repositories', hierarchy.infraPath)\n : path.join(infraPath, 'Repositories');\n\n const interfaceFilePath = path.join(appRepoDir, `I${name}Repository.cs`);\n const implementationFilePath = path.join(infraRepoDir, `${name}Repository.cs`);\n\n // Write files (or preview in dry-run mode)\n if (!dryRun) {\n await ensureDirectory(appRepoDir);\n await ensureDirectory(infraRepoDir);\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: auto-detected from .smartstack/config.json, or \"core\" for platform projects)',\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: auto-detected from project config)'),\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 // Use project's default DbContext if not explicitly specified, fallback to 'core'\n const context = input.context || config.defaultDbContext || '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 with the appropriate DbContext\n // CoreDbContext for SmartStack core entities, ExtensionsDbContext for client entities\n const dbContextName = context === 'core' ? 'CoreDbContext' : 'ExtensionsDbContext';\n const outputPath = context === 'extensions' ? 'Persistence/Migrations/Extensions' : 'Persistence/Migrations';\n const command = `dotnet ef migrations add ${migrationName} --context ${dbContextName} --project ../SmartStack.Infrastructure -o ${outputPath}`;\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}\\` | Migration prefix (core/extensions) |`);\n lines.push(`| DbContext | \\`${dbContextName}\\` | EF Core DbContext to use |`);\n lines.push(`| Schema | \\`${context}\\` | Database schema for tables |`);\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 lines.push('> **Note**: Migrations are stored in separate history tables:');\n lines.push(`> - Core: \\`core.__EFMigrationsHistory\\``);\n lines.push(`> - Extensions: \\`extensions.__EFMigrationsHistory\\``);\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, 'Persistence', '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 { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport path from 'path';\nimport { logger } from '../lib/logger.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { readText } from '../utils/fs.js';\nimport type { Config } from '../types/index.js';\n\n/**\n * Permission generation tool for SmartStack RBAC system.\n *\n * Analyzes NavRoute controllers and outputs HasData() code to add to PermissionConfiguration.cs.\n * Does NOT generate migrations with raw SQL (forbidden by SmartStack conventions).\n *\n * Convention: {navRoute}.{action}\n * Example: \"platform.administration.entra.read\"\n *\n * Output: C# HasData() code to manually add to PermissionConfiguration.cs\n */\n\n// Standard HTTP method to permission action mapping\nconst HTTP_METHOD_TO_ACTION: Record<string, string> = {\n 'GET': 'read',\n 'POST': 'create',\n 'PUT': 'update',\n 'PATCH': 'update',\n 'DELETE': 'delete',\n 'HEAD': 'read',\n 'OPTIONS': 'public', // No permission required\n};\n\n// Standard CRUD actions for RBAC\nconst STANDARD_ACTIONS = ['read', 'create', 'update', 'delete'] as const;\n\ninterface Permission {\n code: string;\n name: string;\n description: string;\n category: string; // From NavRoute context (platform, business, extensions)\n}\n\ninterface GeneratePermissionsOptions {\n navRoute?: string;\n actions?: string[];\n includeStandardActions?: boolean;\n includeWildcard?: boolean;\n}\n\nexport const generatePermissionsTool: Tool = {\n name: 'generate_permissions',\n description: `Generate RBAC permissions for SmartStack controllers.\n\nAnalyzes NavRoute attributes and outputs HasData() C# code to add to PermissionConfiguration.cs.\n\nIMPORTANT: This tool does NOT generate migrations with raw SQL (forbidden by SmartStack conventions).\nInstead, it outputs HasData() code that must be manually added to the Configuration file.\n\nExample:\n navRoute: \"platform.administration.entra\"\n Outputs HasData() code for:\n - platform.administration.entra.*\n - platform.administration.entra.read\n - platform.administration.entra.create\n - platform.administration.entra.update\n - platform.administration.entra.delete\n\nAfter adding to PermissionConfiguration.cs, run: dotnet ef migrations add <MigrationName>`,\n\n inputSchema: {\n type: 'object',\n properties: {\n navRoute: {\n type: 'string',\n description: 'NavRoute path (e.g., \"platform.administration.entra\"). If not provided, scans all controllers.',\n },\n actions: {\n type: 'array',\n items: { type: 'string' },\n description: 'Custom actions to generate (default: read, create, update, delete)',\n },\n includeStandardActions: {\n type: 'boolean',\n default: true,\n description: 'Include standard CRUD actions (read, create, update, delete)',\n },\n includeWildcard: {\n type: 'boolean',\n default: true,\n description: 'Include wildcard permission (e.g., personal.myspace.tenants.*)',\n },\n },\n },\n};\n\n/**\n * Handler for the generate_permissions tool\n */\nexport async function handleGeneratePermissions(\n args: any,\n config: Config\n): Promise<string> {\n try {\n const options: GeneratePermissionsOptions = {\n navRoute: args.navRoute,\n actions: args.actions || [],\n includeStandardActions: args.includeStandardActions !== false,\n includeWildcard: args.includeWildcard !== false,\n };\n\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n if (!structure) {\n throw new Error('SmartStack project structure not found');\n }\n\n let permissions: Permission[] = [];\n let report = '';\n\n if (options.navRoute) {\n // Generate permissions for a specific NavRoute\n permissions = generatePermissionsForNavRoute(\n options.navRoute,\n options.actions || [],\n options.includeStandardActions || false,\n options.includeWildcard || false\n );\n\n report = `## Permissions for NavRoute: ${options.navRoute}\\n\\n`;\n report += formatPermissionsReport(permissions);\n } else {\n // Scan all controllers and generate permissions\n const scannedPermissions = await scanControllersForPermissions(structure.api || structure.root);\n permissions = scannedPermissions;\n\n report = `## Permissions from All Controllers\\n\\n`;\n report += `Total controllers scanned: ${getUniqueNavRouteCount(permissions)}\\n`;\n report += `Total permissions generated: ${permissions.length}\\n\\n`;\n report += formatPermissionsReport(permissions);\n }\n\n // Generate HasData() code (NOT raw SQL migrations)\n report += `\\n\\n## HasData() Code for PermissionConfiguration.cs\\n\\n`;\n report += `⚠️ **IMPORTANT**: Do NOT use migrationBuilder.Sql() - it's forbidden by SmartStack conventions.\\n`;\n report += `Add this code to \\`PermissionConfiguration.cs\\` in the HasData() section, then create a migration.\\n\\n`;\n report += generateHasDataCode(permissions, options.navRoute || 'custom');\n\n report += `\\n\\n### Next Steps\\n\\n`;\n report += `1. Add the module ID variable in GetSeedData() method\\n`;\n report += `2. Add the HasData entries to the return array\\n`;\n report += `3. Run: \\`dotnet ef migrations add <MigrationName> -o Persistence/Migrations\\`\\n`;\n report += `4. Run: \\`dotnet ef database update\\`\\n`;\n\n return report;\n } catch (error: any) {\n logger.error('Error generating permissions:', error);\n throw error;\n }\n}\n\n/**\n * Generate permissions for a specific NavRoute\n */\nfunction generatePermissionsForNavRoute(\n navRoute: string,\n customActions: string[],\n includeStandardActions: boolean,\n includeWildcard: boolean = true\n): Permission[] {\n const permissions: Permission[] = [];\n const parts = navRoute.split('.');\n const context = parts[0]; // platform, business, extensions\n\n // Validate NavRoute format\n if (parts.length < 3) {\n throw new Error(`Invalid NavRoute format: ${navRoute}. Expected format: context.application.module`);\n }\n\n // Add wildcard permission first\n if (includeWildcard) {\n permissions.push({\n code: `${navRoute}.*`,\n name: formatPermissionName(navRoute, 'Full Access'),\n description: `Full ${parts[parts.length - 1]} management`,\n category: context,\n });\n }\n\n const actions = includeStandardActions\n ? [...STANDARD_ACTIONS, ...customActions]\n : customActions;\n\n for (const action of actions) {\n const code = `${navRoute}.${action}`;\n const name = formatPermissionName(navRoute, action);\n const description = formatPermissionDescription(navRoute, action);\n\n permissions.push({\n code,\n name,\n description,\n category: context,\n });\n }\n\n return permissions;\n}\n\n/**\n * Scan all controllers for NavRoute attributes and generate permissions\n */\nasync function scanControllersForPermissions(\n backendRoot: string\n): Promise<Permission[]> {\n const permissions: Permission[] = [];\n\n // Support multiple project structures:\n // - SmartStack: src/SmartStack.Api/Controllers\n // - Legacy: Api/Controllers or Api.Core/Controllers\n const controllerDirs = [\n path.join(backendRoot, 'src', 'SmartStack.Api', 'Controllers'),\n path.join(backendRoot, 'SmartStack.Api', 'Controllers'),\n path.join(backendRoot, 'Api', 'Controllers'),\n path.join(backendRoot, 'Api.Core', 'Controllers'),\n ];\n\n for (const dir of controllerDirs) {\n try {\n const files = await readDirectoryRecursive(dir);\n\n for (const file of files) {\n if (file.endsWith('Controller.cs')) {\n const content = await readText(file);\n const navRoutes = extractNavRoutesFromController(content);\n\n for (const navRoute of navRoutes) {\n const httpMethods = extractHttpMethods(content);\n const actions = httpMethods\n .map(method => HTTP_METHOD_TO_ACTION[method])\n .filter(action => action && action !== 'public');\n\n const uniqueActions = [...new Set(actions)];\n const navRoutePermissions = generatePermissionsForNavRoute(\n navRoute,\n [],\n false\n );\n\n // Only generate permissions for detected actions\n permissions.push(\n ...navRoutePermissions.filter(p =>\n uniqueActions.includes(p.code.split('.').pop()!)\n )\n );\n }\n }\n }\n } catch (error) {\n // Directory might not exist, continue\n logger.debug(`Could not scan directory: ${dir}`);\n }\n }\n\n // Remove duplicates\n return Array.from(\n new Map(permissions.map(p => [p.code, p])).values()\n );\n}\n\n/**\n * Extract NavRoute attributes from controller content\n * Supports all NavRoute parameter formats:\n * - [NavRoute(\"path\")]\n * - [NavRoute(\"path\", Suffix = \"suffix\")]\n * - [NavRoute(\"path\", CustomSegment = \"segment\")]\n * - [NavRoute(\"path\", CustomSegment = \"segment\", Suffix = \"suffix\")]\n */\nfunction extractNavRoutesFromController(content: string): string[] {\n const navRoutes: string[] = [];\n\n // Match NavRoute attribute with any parameters\n // Captures: group 1 = navRoute path, full match includes all parameters\n const regex = /\\[NavRoute\\s*\\(\\s*\"([^\"]+)\"([^)]*)\\)\\]/g;\n\n let match;\n while ((match = regex.exec(content)) !== null) {\n const navRoute = match[1];\n const params = match[2] || '';\n\n // Extract Suffix parameter if present (Suffix appends to navRoute for permissions)\n const suffixMatch = params.match(/Suffix\\s*=\\s*\"([^\"]+)\"/);\n const suffix = suffixMatch ? suffixMatch[1] : null;\n\n if (suffix) {\n // Suffix creates a sub-permission path (e.g., tenants + analytics = tenants.analytics)\n navRoutes.push(`${navRoute}.${suffix}`);\n } else {\n // CustomSegment only affects URL routing, not the permission path\n navRoutes.push(navRoute);\n }\n }\n\n return navRoutes;\n}\n\n/**\n * Extract HTTP methods from controller content\n */\nfunction extractHttpMethods(content: string): string[] {\n const methods: string[] = [];\n const httpAttributes = ['HttpGet', 'HttpPost', 'HttpPut', 'HttpPatch', 'HttpDelete', 'HttpHead', 'HttpOptions'];\n\n for (const attr of httpAttributes) {\n if (content.includes(`[${attr}`)) {\n methods.push(attr.replace('Http', '').toUpperCase());\n }\n }\n\n return methods;\n}\n\n/**\n * Format a human-readable permission name\n */\nfunction formatPermissionName(navRoute: string, action: string): string {\n const parts = navRoute.split('.');\n const module = parts[parts.length - 1];\n\n // Convert to Title Case\n const moduleName = module\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const actionName = action.charAt(0).toUpperCase() + action.slice(1);\n\n return `${moduleName} - ${actionName}`;\n}\n\n/**\n * Format a permission description\n */\nfunction formatPermissionDescription(navRoute: string, action: string): string {\n const parts = navRoute.split('.');\n const context = parts[0];\n const application = parts[1];\n const module = parts[2];\n\n const contextName = context.charAt(0).toUpperCase() + context.slice(1);\n const applicationName = application\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n const moduleName = module\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const actionVerb = getActionVerb(action);\n\n return `${actionVerb} ${moduleName} in ${contextName} > ${applicationName}`;\n}\n\n/**\n * Get action verb for description\n */\nfunction getActionVerb(action: string): string {\n const verbs: Record<string, string> = {\n 'read': 'View',\n 'create': 'Create',\n 'update': 'Update',\n 'delete': 'Delete',\n 'export': 'Export',\n 'import': 'Import',\n };\n\n return verbs[action] || action.charAt(0).toUpperCase() + action.slice(1);\n}\n\n/**\n * Format permissions report\n */\nfunction formatPermissionsReport(permissions: Permission[]): string {\n let report = '';\n\n // Group by category\n const byCategory = permissions.reduce((acc, p) => {\n if (!acc[p.category]) acc[p.category] = [];\n acc[p.category].push(p);\n return acc;\n }, {} as Record<string, Permission[]>);\n\n for (const [category, perms] of Object.entries(byCategory)) {\n report += `### ${category.charAt(0).toUpperCase() + category.slice(1)}\\n\\n`;\n report += `| Code | Name | Description |\\n`;\n report += `|------|------|-------------|\\n`;\n\n for (const p of perms) {\n report += `| \\`${p.code}\\` | ${p.name} | ${p.description} |\\n`;\n }\n\n report += `\\n`;\n }\n\n return report;\n}\n\n/**\n * Get unique NavRoute count\n */\nfunction getUniqueNavRouteCount(permissions: Permission[]): number {\n const navRoutes = new Set(\n permissions.map(p => p.code.split('.').slice(0, -1).join('.'))\n );\n return navRoutes.size;\n}\n\n/**\n * Generate HasData() C# code for PermissionConfiguration.cs\n * This is the correct pattern - NOT raw SQL migrations\n */\nfunction generateHasDataCode(permissions: Permission[], navRoute: string): string {\n const parts = navRoute.split('.');\n const moduleName = parts.length >= 3 ? parts[parts.length - 1] : 'custom';\n const moduleVarName = `${moduleName}ModuleId`;\n\n let code = '```csharp\\n';\n code += `// 1. Add module ID variable (get from NavigationModuleSeedData.cs)\\n`;\n code += `var ${moduleVarName} = Guid.Parse(\"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\"); // TODO: Replace with actual ID\\n\\n`;\n code += `// 2. Add these entries to the HasData() return array:\\n`;\n\n for (const perm of permissions) {\n const isWildcard = perm.code.endsWith('.*');\n const action = perm.code.split('.').pop();\n\n // Generate a placeholder GUID (user must replace with real random GUID)\n const guidPlaceholder = generatePlaceholderGuid();\n\n if (isWildcard) {\n code += `new { Id = Guid.Parse(\"${guidPlaceholder}\"), Path = \"${perm.code}\", Level = PermissionLevel.Module, IsWildcard = true, ModuleId = ${moduleVarName}, Description = \"${perm.description}\", CreatedAt = seedDate },\\n`;\n } else {\n const actionEnum = getActionEnum(action || 'read');\n code += `new { Id = Guid.Parse(\"${guidPlaceholder}\"), Path = \"${perm.code}\", Level = PermissionLevel.Module, Action = PermissionAction.${actionEnum}, IsWildcard = false, ModuleId = ${moduleVarName}, Description = \"${perm.description}\", CreatedAt = seedDate },\\n`;\n }\n }\n\n code += '```\\n';\n code += '\\n⚠️ **IMPORTANT**: Replace all GUIDs with randomly generated ones using:\\n';\n code += '```powershell\\n';\n code += `1..${permissions.length} | ForEach-Object { [guid]::NewGuid().ToString() }\\n`;\n code += '```\\n';\n\n return code;\n}\n\n/**\n * Generate a placeholder GUID (NOT for production use - must be replaced)\n */\nfunction generatePlaceholderGuid(): string {\n return 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX';\n}\n\n/**\n * Get PermissionAction enum value from action string\n */\nfunction getActionEnum(action: string): string {\n const actionMap: Record<string, string> = {\n 'read': 'Read',\n 'create': 'Create',\n 'update': 'Update',\n 'delete': 'Delete',\n 'assign': 'Assign',\n 'execute': 'Execute',\n 'export': 'Export',\n 'import': 'Import',\n };\n return actionMap[action.toLowerCase()] || action.charAt(0).toUpperCase() + action.slice(1);\n}\n\n/**\n * Read directory recursively\n */\nasync function readDirectoryRecursive(dir: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await import('fs/promises').then(fs => fs.readdir(dir, { withFileTypes: true }));\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n files.push(...await readDirectoryRecursive(fullPath));\n } else {\n files.push(fullPath);\n }\n }\n } catch {\n // Directory doesn't exist or not accessible\n }\n\n return files;\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport Handlebars from 'handlebars';\nimport {\n ScaffoldTestsInputSchema,\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 scaffoldTestsTool: Tool = {\n name: 'scaffold_tests',\n description: 'Generate unit, integration, and security tests for SmartStack entities, services, controllers, validators, and repositories. Ensures non-regression and maximum security coverage.',\n inputSchema: {\n type: 'object',\n properties: {\n target: {\n type: 'string',\n enum: ['entity', 'service', 'controller', 'validator', 'repository', 'all'],\n description: 'Type of component to test',\n },\n name: {\n type: 'string',\n description: 'Component name (PascalCase, e.g., \"User\", \"Order\")',\n },\n testTypes: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['unit', 'integration', 'security', 'e2e'],\n },\n default: ['unit'],\n description: 'Types of tests to generate',\n },\n options: {\n type: 'object',\n properties: {\n includeEdgeCases: {\n type: 'boolean',\n default: true,\n description: 'Include edge case tests',\n },\n includeTenantIsolation: {\n type: 'boolean',\n default: true,\n description: 'Include tenant isolation tests',\n },\n includeSoftDelete: {\n type: 'boolean',\n default: true,\n description: 'Include soft delete tests',\n },\n includeAudit: {\n type: 'boolean',\n default: true,\n description: 'Include audit trail tests',\n },\n includeValidation: {\n type: 'boolean',\n default: true,\n description: 'Include validation tests',\n },\n includeAuthorization: {\n type: 'boolean',\n default: false,\n description: 'Include authorization tests',\n },\n includePerformance: {\n type: 'boolean',\n default: false,\n description: 'Include performance tests',\n },\n isSystemEntity: {\n type: 'boolean',\n default: false,\n description: 'If true, entity has no TenantId',\n },\n dryRun: {\n type: 'boolean',\n default: false,\n description: 'Preview without writing files',\n },\n },\n },\n },\n required: ['target', 'name'],\n },\n};\n\n// Register Handlebars helpers for tests\nHandlebars.registerHelper('pascalCase', (str: string) => {\n if (!str) return '';\n return str.charAt(0).toUpperCase() + str.slice(1);\n});\n\nHandlebars.registerHelper('camelCase', (str: string) => {\n if (!str) return '';\n return str.charAt(0).toLowerCase() + str.slice(1);\n});\n\nHandlebars.registerHelper('unless', function(this: unknown, conditional: boolean, options: Handlebars.HelperOptions) {\n if (!conditional) {\n return options.fn(this);\n }\n return options.inverse(this);\n});\n\n// ============================================================================\n// Test Templates\n// ============================================================================\n\nconst entityTestTemplate = `using System;\nusing FluentAssertions;\nusing Xunit;\nusing {{domainNamespace}};\n\nnamespace {{testNamespace}}.Unit.Domain;\n\n/// <summary>\n/// Unit tests for {{name}} entity\n/// Tests: Factory methods, Soft delete, Audit trail, Validation\n/// </summary>\npublic class {{name}}Tests\n{\n private const string ValidCode = \"test_code\";\n{{#unless isSystemEntity}}\n private readonly Guid _tenantId = Guid.NewGuid();\n{{/unless}}\n\n #region Factory Method Tests\n\n [Fact]\n public void Create_WhenValidData_ShouldCreateEntity()\n {\n // Arrange\n var code = ValidCode;\n{{#unless isSystemEntity}}\n var tenantId = _tenantId;\n{{/unless}}\n\n // Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}tenantId, {{/unless}}code);\n\n // Assert\n entity.Should().NotBeNull();\n entity.Id.Should().NotBeEmpty();\n entity.Code.Should().Be(code.ToLowerInvariant());\n{{#unless isSystemEntity}}\n entity.TenantId.Should().Be(tenantId);\n{{/unless}}\n entity.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));\n entity.IsDeleted.Should().BeFalse();\n }\n\n{{#unless isSystemEntity}}\n [Fact]\n public void Create_WhenEmptyTenantId_ShouldThrow()\n {\n // Arrange\n var tenantId = Guid.Empty;\n var code = ValidCode;\n\n // Act\n var act = () => {{name}}.Create(tenantId, code);\n\n // Assert\n act.Should().Throw<ArgumentException>()\n .WithParameterName(\"tenantId\");\n }\n{{/unless}}\n\n [Theory]\n [InlineData(\"\")]\n [InlineData(\" \")]\n public void Create_WhenEmptyCode_ShouldHandleGracefully(string code)\n {\n // Arrange\n{{#unless isSystemEntity}}\n var tenantId = _tenantId;\n{{/unless}}\n\n // Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}tenantId, {{/unless}}code);\n\n // Assert\n entity.Should().NotBeNull();\n entity.Code.Should().BeEmpty();\n }\n\n #endregion\n\n{{#if includeSoftDelete}}\n #region Soft Delete Tests\n\n [Fact]\n public void SoftDelete_WhenCalled_ShouldSetIsDeletedTrue()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode);\n var deletedBy = \"test_user\";\n\n // Act\n entity.SoftDelete(deletedBy);\n\n // Assert\n entity.IsDeleted.Should().BeTrue();\n entity.DeletedAt.Should().NotBeNull();\n entity.DeletedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));\n entity.DeletedBy.Should().Be(deletedBy);\n }\n\n [Fact]\n public void SoftDelete_WhenAlreadyDeleted_ShouldNotChangeDeletedAt()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode);\n entity.SoftDelete(\"first_deleter\");\n var originalDeletedAt = entity.DeletedAt;\n\n // Act\n entity.SoftDelete(\"second_deleter\");\n\n // Assert\n entity.DeletedAt.Should().Be(originalDeletedAt);\n }\n\n [Fact]\n public void Restore_WhenSoftDeleted_ShouldClearDeletedFields()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode);\n entity.SoftDelete(\"deleter\");\n var restoredBy = \"restorer\";\n\n // Act\n entity.Restore(restoredBy);\n\n // Assert\n entity.IsDeleted.Should().BeFalse();\n entity.DeletedAt.Should().BeNull();\n entity.DeletedBy.Should().BeNull();\n entity.UpdatedBy.Should().Be(restoredBy);\n }\n\n #endregion\n{{/if}}\n\n{{#if includeAudit}}\n #region Audit Trail Tests\n\n [Fact]\n public void Create_ShouldSetCreatedAtToUtcNow()\n {\n // Arrange & Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode);\n\n // Assert\n entity.CreatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));\n entity.CreatedAt.Kind.Should().Be(DateTimeKind.Utc);\n }\n\n [Fact]\n public void Create_WhenCreatedByProvided_ShouldSetCreatedBy()\n {\n // Arrange\n var createdBy = \"test_creator\";\n\n // Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode, createdBy);\n\n // Assert\n entity.CreatedBy.Should().Be(createdBy);\n }\n\n [Fact]\n public void Update_WhenCalled_ShouldUpdateAuditFields()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}ValidCode);\n var originalCreatedAt = entity.CreatedAt;\n var updatedBy = \"updater\";\n\n // Act\n entity.Update(updatedBy);\n\n // Assert\n entity.UpdatedAt.Should().NotBeNull();\n entity.UpdatedAt.Should().BeCloseTo(DateTime.UtcNow, TimeSpan.FromSeconds(1));\n entity.UpdatedBy.Should().Be(updatedBy);\n entity.CreatedAt.Should().Be(originalCreatedAt);\n }\n\n #endregion\n{{/if}}\n\n{{#if includeEdgeCases}}\n #region Edge Cases\n\n [Fact]\n public void Create_WithSpecialCharactersInCode_ShouldNormalize()\n {\n // Arrange\n var code = \"Test-Code_123\";\n\n // Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}code);\n\n // Assert\n entity.Code.Should().Be(code.ToLowerInvariant());\n }\n\n [Fact]\n public void Create_WithMaxLengthCode_ShouldSucceed()\n {\n // Arrange\n var code = new string('a', 100);\n\n // Act\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}code);\n\n // Assert\n entity.Code.Should().HaveLength(100);\n }\n\n #endregion\n{{/if}}\n}\n`;\n\nconst serviceTestTemplate = `using System;\nusing System.Collections.Generic;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Microsoft.Extensions.Logging;\nusing Moq;\nusing Xunit;\nusing {{applicationNamespace}}.Services;\nusing {{applicationNamespace}}.Repositories;\nusing {{domainNamespace}};\n\nnamespace {{testNamespace}}.Unit.Services;\n\n/// <summary>\n/// Unit tests for {{name}}Service\n/// Tests: CRUD operations, Business logic, Error handling, Tenant isolation\n/// </summary>\npublic class {{name}}ServiceTests\n{\n private readonly Mock<I{{name}}Repository> _repositoryMock;\n private readonly Mock<ILogger<{{name}}Service>> _loggerMock;\n private readonly {{name}}Service _sut;\n{{#unless isSystemEntity}}\n private readonly Guid _tenantId = Guid.NewGuid();\n{{/unless}}\n\n public {{name}}ServiceTests()\n {\n _repositoryMock = new Mock<I{{name}}Repository>();\n _loggerMock = new Mock<ILogger<{{name}}Service>>();\n _sut = new {{name}}Service(\n _repositoryMock.Object,\n _loggerMock.Object\n );\n }\n\n #region GetByIdAsync Tests\n\n [Fact]\n public async Task GetByIdAsync_WhenEntityExists_ShouldReturnEntity()\n {\n // Arrange\n var id = Guid.NewGuid();\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ReturnsAsync(entity);\n\n // Act\n var result = await _sut.GetByIdAsync(id);\n\n // Assert\n result.Should().NotBeNull();\n _repositoryMock.Verify(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()), Times.Once);\n }\n\n [Fact]\n public async Task GetByIdAsync_WhenNotExists_ShouldReturnNull()\n {\n // Arrange\n var id = Guid.NewGuid();\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var result = await _sut.GetByIdAsync(id);\n\n // Assert\n result.Should().BeNull();\n }\n\n [Fact]\n public async Task GetByIdAsync_WhenCancelled_ShouldThrowOperationCancelledException()\n {\n // Arrange\n var id = Guid.NewGuid();\n var cts = new CancellationTokenSource();\n cts.Cancel();\n\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ThrowsAsync(new OperationCanceledException());\n\n // Act\n var act = async () => await _sut.GetByIdAsync(id, cts.Token);\n\n // Assert\n await act.Should().ThrowAsync<OperationCanceledException>();\n }\n\n #endregion\n\n{{#unless isSystemEntity}}\n #region Tenant Isolation Tests\n\n [Fact]\n public async Task GetAllAsync_ShouldFilterByTenant()\n {\n // Arrange\n var entities = new List<{{name}}>\n {\n {{name}}.Create(_tenantId, \"entity1\"),\n {{name}}.Create(_tenantId, \"entity2\"),\n };\n _repositoryMock\n .Setup(r => r.GetAllByTenantAsync(_tenantId, It.IsAny<CancellationToken>()))\n .ReturnsAsync(entities);\n\n // Act\n var result = await _sut.GetAllAsync(_tenantId);\n\n // Assert\n result.Should().HaveCount(2);\n result.Should().OnlyContain(e => e.TenantId == _tenantId);\n }\n\n [Fact]\n public async Task CreateAsync_ShouldSetTenantId()\n {\n // Arrange\n {{name}}? capturedEntity = null;\n _repositoryMock\n .Setup(r => r.AddAsync(It.IsAny<{{name}}>(), It.IsAny<CancellationToken>()))\n .Callback<{{name}}, CancellationToken>((e, _) => capturedEntity = e)\n .ReturnsAsync(({{name}} e, CancellationToken _) => e);\n\n // Act\n await _sut.CreateAsync(_tenantId, \"test_code\");\n\n // Assert\n capturedEntity.Should().NotBeNull();\n capturedEntity!.TenantId.Should().Be(_tenantId);\n }\n\n [Fact]\n public async Task GetByIdAsync_WhenEntityBelongsToDifferentTenant_ShouldReturnNull()\n {\n // Arrange\n var id = Guid.NewGuid();\n var otherTenantId = Guid.NewGuid();\n var entity = {{name}}.Create(otherTenantId, \"test\");\n\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ReturnsAsync(({{name}}?)null); // Repository should filter by tenant\n\n // Act\n var result = await _sut.GetByIdAsync(id, _tenantId);\n\n // Assert\n result.Should().BeNull();\n }\n\n #endregion\n{{/unless}}\n\n #region Error Handling Tests\n\n [Fact]\n public async Task UpdateAsync_WhenEntityNotFound_ShouldThrow()\n {\n // Arrange\n var id = Guid.NewGuid();\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var act = async () => await _sut.UpdateAsync(id, \"new_code\");\n\n // Assert\n await act.Should().ThrowAsync<InvalidOperationException>()\n .WithMessage(\"*not found*\");\n }\n\n [Fact]\n public async Task DeleteAsync_WhenEntityNotFound_ShouldReturnFalse()\n {\n // Arrange\n var id = Guid.NewGuid();\n _repositoryMock\n .Setup(r => r.GetByIdAsync(id, It.IsAny<CancellationToken>()))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var result = await _sut.DeleteAsync(id);\n\n // Assert\n result.Should().BeFalse();\n }\n\n #endregion\n\n{{#if includeEdgeCases}}\n #region Edge Cases\n\n [Fact]\n public async Task CreateAsync_WithEmptyCode_ShouldStillCreate()\n {\n // Arrange\n _repositoryMock\n .Setup(r => r.AddAsync(It.IsAny<{{name}}>(), It.IsAny<CancellationToken>()))\n .ReturnsAsync(({{name}} e, CancellationToken _) => e);\n\n // Act\n var result = await _sut.CreateAsync({{#unless isSystemEntity}}_tenantId, {{/unless}}\"\");\n\n // Assert\n result.Should().NotBeNull();\n result.Code.Should().BeEmpty();\n }\n\n [Fact]\n public async Task GetAllAsync_WhenNoEntities_ShouldReturnEmptyList()\n {\n // Arrange\n _repositoryMock\n .Setup(r => r.GetAllAsync(It.IsAny<CancellationToken>()))\n .ReturnsAsync(new List<{{name}}>());\n\n // Act\n var result = await _sut.GetAllAsync();\n\n // Assert\n result.Should().BeEmpty();\n }\n\n #endregion\n{{/if}}\n}\n`;\n\nconst controllerTestTemplate = `using System;\nusing System.Collections.Generic;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Http.Json;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Microsoft.AspNetCore.Mvc.Testing;\nusing Microsoft.Extensions.DependencyInjection;\nusing Moq;\nusing Xunit;\nusing {{apiNamespace}};\nusing {{applicationNamespace}}.Services;\nusing {{domainNamespace}};\n\nnamespace {{testNamespace}}.Integration.Controllers;\n\n/// <summary>\n/// Integration tests for {{name}}Controller\n/// Tests: HTTP status codes, Authorization, Validation, CRUD operations\n/// </summary>\npublic class {{name}}ControllerTests : IClassFixture<WebApplicationFactory<Program>>\n{\n private readonly WebApplicationFactory<Program> _factory;\n private readonly HttpClient _client;\n private readonly Mock<I{{name}}Service> _serviceMock;\n{{#unless isSystemEntity}}\n private readonly Guid _tenantId = Guid.NewGuid();\n{{/unless}}\n\n public {{name}}ControllerTests(WebApplicationFactory<Program> factory)\n {\n _serviceMock = new Mock<I{{name}}Service>();\n\n _factory = factory.WithWebHostBuilder(builder =>\n {\n builder.ConfigureServices(services =>\n {\n // Replace the real service with our mock\n var descriptor = services.SingleOrDefault(\n d => d.ServiceType == typeof(I{{name}}Service));\n\n if (descriptor != null)\n {\n services.Remove(descriptor);\n }\n\n services.AddScoped(_ => _serviceMock.Object);\n });\n });\n\n _client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n _client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n }\n\n #region GET Tests\n\n [Fact]\n public async Task GetAll_WhenAuthorized_ShouldReturn200()\n {\n // Arrange\n var entities = new List<{{name}}>\n {\n {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"entity1\"),\n {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"entity2\"),\n };\n _serviceMock\n .Setup(s => s.GetAllAsync({{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(entities);\n\n // Act\n var response = await _client.GetAsync(\"/api/{{nameLower}}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.OK);\n }\n\n [Fact]\n public async Task GetById_WhenEntityExists_ShouldReturn200()\n {\n // Arrange\n var id = Guid.NewGuid();\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n _serviceMock\n .Setup(s => s.GetByIdAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(entity);\n\n // Act\n var response = await _client.GetAsync(\\$\"/api/{{nameLower}}/{id}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.OK);\n }\n\n [Fact]\n public async Task GetById_WhenNotFound_ShouldReturn404()\n {\n // Arrange\n var id = Guid.NewGuid();\n _serviceMock\n .Setup(s => s.GetByIdAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var response = await _client.GetAsync(\\$\"/api/{{nameLower}}/{id}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.NotFound);\n }\n\n #endregion\n\n #region POST Tests\n\n [Fact]\n public async Task Create_WhenValidData_ShouldReturn201()\n {\n // Arrange\n var request = new { Code = \"new_entity\" };\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}request.Code);\n _serviceMock\n .Setup(s => s.CreateAsync({{#unless isSystemEntity}}_tenantId, {{/unless}}request.Code, default))\n .ReturnsAsync(entity);\n\n // Act\n var response = await _client.PostAsJsonAsync(\"/api/{{nameLower}}\", request);\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.Created);\n }\n\n{{#if includeValidation}}\n [Fact]\n public async Task Create_WhenInvalidData_ShouldReturn400()\n {\n // Arrange\n var request = new { Code = (string?)null };\n\n // Act\n var response = await _client.PostAsJsonAsync(\"/api/{{nameLower}}\", request);\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n }\n{{/if}}\n\n #endregion\n\n #region PUT Tests\n\n [Fact]\n public async Task Update_WhenEntityExists_ShouldReturn200()\n {\n // Arrange\n var id = Guid.NewGuid();\n var request = new { Code = \"updated_code\" };\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n _serviceMock\n .Setup(s => s.GetByIdAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(entity);\n _serviceMock\n .Setup(s => s.UpdateAsync(id, request.Code, default))\n .ReturnsAsync(entity);\n\n // Act\n var response = await _client.PutAsJsonAsync(\\$\"/api/{{nameLower}}/{id}\", request);\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.OK);\n }\n\n [Fact]\n public async Task Update_WhenNotFound_ShouldReturn404()\n {\n // Arrange\n var id = Guid.NewGuid();\n var request = new { Code = \"updated_code\" };\n _serviceMock\n .Setup(s => s.GetByIdAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var response = await _client.PutAsJsonAsync(\\$\"/api/{{nameLower}}/{id}\", request);\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.NotFound);\n }\n\n #endregion\n\n #region DELETE Tests\n\n [Fact]\n public async Task Delete_WhenEntityExists_ShouldReturn204()\n {\n // Arrange\n var id = Guid.NewGuid();\n _serviceMock\n .Setup(s => s.DeleteAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(true);\n\n // Act\n var response = await _client.DeleteAsync(\\$\"/api/{{nameLower}}/{id}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.NoContent);\n }\n\n [Fact]\n public async Task Delete_WhenNotFound_ShouldReturn404()\n {\n // Arrange\n var id = Guid.NewGuid();\n _serviceMock\n .Setup(s => s.DeleteAsync(id, {{#unless isSystemEntity}}_tenantId, {{/unless}}default))\n .ReturnsAsync(false);\n\n // Act\n var response = await _client.DeleteAsync(\\$\"/api/{{nameLower}}/{id}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.NotFound);\n }\n\n #endregion\n\n{{#if includeAuthorization}}\n #region Authorization Tests\n\n [Fact]\n public async Task GetAll_WhenUnauthorized_ShouldReturn401()\n {\n // Arrange\n var client = _factory.CreateClient();\n // Don't add auth header\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.Unauthorized);\n }\n\n{{#unless isSystemEntity}}\n [Fact]\n public async Task GetById_WhenDifferentTenant_ShouldReturn403()\n {\n // Arrange\n var id = Guid.NewGuid();\n var client = _factory.CreateClient();\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", Guid.NewGuid().ToString());\n\n _serviceMock\n .Setup(s => s.GetByIdAsync(id, It.IsAny<Guid>(), default))\n .ReturnsAsync(({{name}}?)null);\n\n // Act\n var response = await client.GetAsync(\\$\"/api/{{nameLower}}/{id}\");\n\n // Assert\n response.StatusCode.Should().BeOneOf(HttpStatusCode.Forbidden, HttpStatusCode.NotFound);\n }\n{{/unless}}\n\n #endregion\n{{/if}}\n}\n`;\n\nconst validatorTestTemplate = `using FluentAssertions;\nusing FluentValidation.TestHelper;\nusing Xunit;\nusing {{applicationNamespace}}.DTOs;\nusing {{applicationNamespace}}.Validators;\n\nnamespace {{testNamespace}}.Unit.Validators;\n\n/// <summary>\n/// Unit tests for {{name}} validators\n/// Tests: Validation rules, Error messages\n/// </summary>\npublic class {{name}}ValidatorTests\n{\n private readonly Create{{name}}DtoValidator _createValidator;\n private readonly Update{{name}}DtoValidator _updateValidator;\n\n public {{name}}ValidatorTests()\n {\n _createValidator = new Create{{name}}DtoValidator();\n _updateValidator = new Update{{name}}DtoValidator();\n }\n\n #region Create Validator Tests\n\n [Fact]\n public void CreateValidator_WhenCodeIsEmpty_ShouldHaveError()\n {\n // Arrange\n var dto = new Create{{name}}Dto { Code = string.Empty };\n\n // Act\n var result = _createValidator.TestValidate(dto);\n\n // Assert\n result.ShouldHaveValidationErrorFor(x => x.Code)\n .WithErrorMessage(\"*required*\");\n }\n\n [Fact]\n public void CreateValidator_WhenCodeIsTooLong_ShouldHaveError()\n {\n // Arrange\n var dto = new Create{{name}}Dto { Code = new string('a', 101) };\n\n // Act\n var result = _createValidator.TestValidate(dto);\n\n // Assert\n result.ShouldHaveValidationErrorFor(x => x.Code)\n .WithErrorMessage(\"*100 characters*\");\n }\n\n [Fact]\n public void CreateValidator_WhenValidData_ShouldNotHaveErrors()\n {\n // Arrange\n var dto = new Create{{name}}Dto { Code = \"valid_code\" };\n\n // Act\n var result = _createValidator.TestValidate(dto);\n\n // Assert\n result.ShouldNotHaveAnyValidationErrors();\n }\n\n #endregion\n\n #region Update Validator Tests\n\n [Fact]\n public void UpdateValidator_WhenCodeIsEmpty_ShouldHaveError()\n {\n // Arrange\n var dto = new Update{{name}}Dto { Code = string.Empty };\n\n // Act\n var result = _updateValidator.TestValidate(dto);\n\n // Assert\n result.ShouldHaveValidationErrorFor(x => x.Code);\n }\n\n [Fact]\n public void UpdateValidator_WhenValidData_ShouldNotHaveErrors()\n {\n // Arrange\n var dto = new Update{{name}}Dto { Code = \"updated_code\" };\n\n // Act\n var result = _updateValidator.TestValidate(dto);\n\n // Assert\n result.ShouldNotHaveAnyValidationErrors();\n }\n\n #endregion\n\n{{#if includeEdgeCases}}\n #region Edge Cases\n\n [Theory]\n [InlineData(\"test-code\")]\n [InlineData(\"test_code\")]\n [InlineData(\"test.code\")]\n public void CreateValidator_WhenCodeHasSpecialCharacters_ShouldPass(string code)\n {\n // Arrange\n var dto = new Create{{name}}Dto { Code = code };\n\n // Act\n var result = _createValidator.TestValidate(dto);\n\n // Assert\n result.ShouldNotHaveValidationErrorFor(x => x.Code);\n }\n\n [Theory]\n [InlineData(\" leading\")]\n [InlineData(\"trailing \")]\n [InlineData(\" both \")]\n public void CreateValidator_WhenCodeHasWhitespace_ShouldTrimAndValidate(string code)\n {\n // Arrange\n var dto = new Create{{name}}Dto { Code = code };\n\n // Act\n var result = _createValidator.TestValidate(dto);\n\n // Assert\n // Depending on implementation, may pass or fail\n // This test documents the expected behavior\n }\n\n #endregion\n{{/if}}\n}\n`;\n\nconst repositoryTestTemplate = `using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Microsoft.EntityFrameworkCore;\nusing Xunit;\nusing {{infrastructureNamespace}}.Persistence;\nusing {{infrastructureNamespace}}.Repositories;\nusing {{domainNamespace}};\n\nnamespace {{testNamespace}}.Integration.Repositories;\n\n/// <summary>\n/// Integration tests for {{name}}Repository\n/// Tests: CRUD with DbContext, Queries, Tenant scope\n/// </summary>\npublic class {{name}}RepositoryTests : IDisposable\n{\n private readonly ApplicationDbContext _context;\n private readonly {{name}}Repository _repository;\n{{#unless isSystemEntity}}\n private readonly Guid _tenantId = Guid.NewGuid();\n{{/unless}}\n\n public {{name}}RepositoryTests()\n {\n var options = new DbContextOptionsBuilder<ApplicationDbContext>()\n .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())\n .Options;\n\n _context = new ApplicationDbContext(options);\n _repository = new {{name}}Repository(_context);\n }\n\n public void Dispose()\n {\n _context.Dispose();\n }\n\n #region GetByIdAsync Tests\n\n [Fact]\n public async Task GetByIdAsync_WhenEntityExists_ShouldReturnEntity()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n await _context.Set<{{name}}>().AddAsync(entity);\n await _context.SaveChangesAsync();\n\n // Act\n var result = await _repository.GetByIdAsync(entity.Id);\n\n // Assert\n result.Should().NotBeNull();\n result!.Id.Should().Be(entity.Id);\n }\n\n [Fact]\n public async Task GetByIdAsync_WhenNotExists_ShouldReturnNull()\n {\n // Arrange\n var id = Guid.NewGuid();\n\n // Act\n var result = await _repository.GetByIdAsync(id);\n\n // Assert\n result.Should().BeNull();\n }\n\n #endregion\n\n #region AddAsync Tests\n\n [Fact]\n public async Task AddAsync_ShouldPersistEntity()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n\n // Act\n var result = await _repository.AddAsync(entity);\n await _context.SaveChangesAsync();\n\n // Assert\n result.Should().NotBeNull();\n var persisted = await _context.Set<{{name}}>().FindAsync(entity.Id);\n persisted.Should().NotBeNull();\n }\n\n #endregion\n\n #region UpdateAsync Tests\n\n [Fact]\n public async Task UpdateAsync_ShouldUpdateEntity()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"original\");\n await _context.Set<{{name}}>().AddAsync(entity);\n await _context.SaveChangesAsync();\n\n // Act\n entity.Update(\"updater\");\n await _repository.UpdateAsync(entity);\n await _context.SaveChangesAsync();\n\n // Assert\n var updated = await _context.Set<{{name}}>().FindAsync(entity.Id);\n updated!.UpdatedBy.Should().Be(\"updater\");\n }\n\n #endregion\n\n #region DeleteAsync Tests\n\n [Fact]\n public async Task DeleteAsync_ShouldRemoveEntity()\n {\n // Arrange\n var entity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"test\");\n await _context.Set<{{name}}>().AddAsync(entity);\n await _context.SaveChangesAsync();\n\n // Act\n await _repository.DeleteAsync(entity);\n await _context.SaveChangesAsync();\n\n // Assert\n var deleted = await _context.Set<{{name}}>().FindAsync(entity.Id);\n deleted.Should().BeNull();\n }\n\n #endregion\n\n{{#unless isSystemEntity}}\n #region Tenant Isolation Tests\n\n [Fact]\n public async Task GetAllByTenantAsync_ShouldOnlyReturnTenantEntities()\n {\n // Arrange\n var otherTenantId = Guid.NewGuid();\n await _context.Set<{{name}}>().AddRangeAsync(\n {{name}}.Create(_tenantId, \"entity1\"),\n {{name}}.Create(_tenantId, \"entity2\"),\n {{name}}.Create(otherTenantId, \"other_tenant_entity\")\n );\n await _context.SaveChangesAsync();\n\n // Act\n var result = await _repository.GetAllByTenantAsync(_tenantId);\n\n // Assert\n result.Should().HaveCount(2);\n result.Should().OnlyContain(e => e.TenantId == _tenantId);\n }\n\n [Fact]\n public async Task ExistsAsync_WhenEntityInDifferentTenant_ShouldReturnFalse()\n {\n // Arrange\n var otherTenantId = Guid.NewGuid();\n var entity = {{name}}.Create(otherTenantId, \"test\");\n await _context.Set<{{name}}>().AddAsync(entity);\n await _context.SaveChangesAsync();\n\n // Act\n var result = await _repository.ExistsAsync(entity.Id, _tenantId);\n\n // Assert\n result.Should().BeFalse();\n }\n\n #endregion\n{{/unless}}\n\n{{#if includeSoftDelete}}\n #region Soft Delete Tests\n\n [Fact]\n public async Task GetAllAsync_ShouldExcludeSoftDeletedEntities()\n {\n // Arrange\n var activeEntity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"active\");\n var deletedEntity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"deleted\");\n deletedEntity.SoftDelete(\"deleter\");\n\n await _context.Set<{{name}}>().AddRangeAsync(activeEntity, deletedEntity);\n await _context.SaveChangesAsync();\n\n // Act\n var result = await _repository.GetAllAsync();\n\n // Assert\n result.Should().ContainSingle();\n result.First().Code.Should().Be(\"active\");\n }\n\n [Fact]\n public async Task GetAllIncludingDeletedAsync_ShouldIncludeSoftDeletedEntities()\n {\n // Arrange\n var activeEntity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"active\");\n var deletedEntity = {{name}}.Create({{#unless isSystemEntity}}_tenantId, {{/unless}}\"deleted\");\n deletedEntity.SoftDelete(\"deleter\");\n\n await _context.Set<{{name}}>().AddRangeAsync(activeEntity, deletedEntity);\n await _context.SaveChangesAsync();\n\n // Act\n var result = await _repository.GetAllIncludingDeletedAsync();\n\n // Assert\n result.Should().HaveCount(2);\n }\n\n #endregion\n{{/if}}\n}\n`;\n\nconst securityTestTemplate = `using System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing FluentAssertions;\nusing Microsoft.AspNetCore.Mvc.Testing;\nusing Xunit;\nusing {{apiNamespace}};\n\nnamespace {{testNamespace}}.Security;\n\n/// <summary>\n/// Security tests for {{name}}\n/// Tests: Tenant isolation, Authorization, Input validation, Injection prevention\n/// </summary>\npublic class {{name}}SecurityTests : IClassFixture<WebApplicationFactory<Program>>\n{\n private readonly WebApplicationFactory<Program> _factory;\n{{#unless isSystemEntity}}\n private readonly Guid _tenantId = Guid.NewGuid();\n{{/unless}}\n\n public {{name}}SecurityTests(WebApplicationFactory<Program> factory)\n {\n _factory = factory;\n }\n\n{{#unless isSystemEntity}}\n #region Tenant Isolation Tests\n\n [Fact]\n public async Task Request_WithoutTenantHeader_ShouldReturn400()\n {\n // Arrange\n var client = _factory.CreateClient();\n // Intentionally not adding X-Tenant-Id header\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}\");\n\n // Assert\n response.StatusCode.Should().BeOneOf(\n HttpStatusCode.BadRequest,\n HttpStatusCode.Unauthorized\n );\n }\n\n [Fact]\n public async Task Request_WithInvalidTenantId_ShouldReturn400()\n {\n // Arrange\n var client = _factory.CreateClient();\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", \"invalid-guid\");\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n }\n\n [Fact]\n public async Task Request_WithEmptyTenantId_ShouldReturn400()\n {\n // Arrange\n var client = _factory.CreateClient();\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", Guid.Empty.ToString());\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n }\n\n #endregion\n{{/unless}}\n\n #region Input Validation Security Tests\n\n [Theory]\n [InlineData(\"<script>alert('xss')</script>\")]\n [InlineData(\"'; DROP TABLE users; --\")]\n [InlineData(\"{{'{{'}}constructor.prototype{{'}}'}}\")]\n public async Task Create_WithMaliciousInput_ShouldSanitizeOrReject(string maliciousInput)\n {\n // Arrange\n var client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n var request = new { Code = maliciousInput };\n\n // Act\n var response = await client.PostAsJsonAsync(\"/api/{{nameLower}}\", request);\n\n // Assert\n // Should either reject (400) or sanitize (201 with cleaned data)\n response.StatusCode.Should().BeOneOf(\n HttpStatusCode.BadRequest,\n HttpStatusCode.Created,\n HttpStatusCode.UnprocessableEntity\n );\n }\n\n [Theory]\n [InlineData(\"../../../etc/passwd\")]\n [InlineData(\"..\\\\\\\\..\\\\\\\\..\\\\\\\\windows\\\\\\\\system32\")]\n [InlineData(\"....//....//....//etc/passwd\")]\n public async Task Create_WithPathTraversalAttempt_ShouldReject(string pathTraversal)\n {\n // Arrange\n var client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n var request = new { Code = pathTraversal };\n\n // Act\n var response = await client.PostAsJsonAsync(\"/api/{{nameLower}}\", request);\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n }\n\n #endregion\n\n #region ID Manipulation Tests\n\n [Fact]\n public async Task GetById_WithNegativeId_ShouldReturn400Or404()\n {\n // Arrange\n var client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}/00000000-0000-0000-0000-000000000000\");\n\n // Assert\n response.StatusCode.Should().BeOneOf(\n HttpStatusCode.BadRequest,\n HttpStatusCode.NotFound\n );\n }\n\n [Fact]\n public async Task GetById_WithMalformedGuid_ShouldReturn400()\n {\n // Arrange\n var client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n\n // Act\n var response = await client.GetAsync(\"/api/{{nameLower}}/not-a-guid\");\n\n // Assert\n response.StatusCode.Should().Be(HttpStatusCode.BadRequest);\n }\n\n #endregion\n\n #region Rate Limiting Tests (if applicable)\n\n [Fact]\n public async Task MultipleRapidRequests_ShouldNotCauseDenialOfService()\n {\n // Arrange\n var client = _factory.CreateClient();\n{{#unless isSystemEntity}}\n client.DefaultRequestHeaders.Add(\"X-Tenant-Id\", _tenantId.ToString());\n{{/unless}}\n var tasks = new List<Task<HttpResponseMessage>>();\n\n // Act\n for (int i = 0; i < 10; i++)\n {\n tasks.Add(client.GetAsync(\"/api/{{nameLower}}\"));\n }\n var responses = await Task.WhenAll(tasks);\n\n // Assert\n // Should handle without crashing (may return 429 if rate limiting is enabled)\n responses.Should().OnlyContain(r =>\n r.StatusCode == HttpStatusCode.OK ||\n r.StatusCode == HttpStatusCode.TooManyRequests);\n }\n\n #endregion\n}\n`;\n\n// ============================================================================\n// Handler Functions\n// ============================================================================\n\nexport async function handleScaffoldTests(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ScaffoldTestsInputSchema.parse(args);\n const dryRun = input.options?.dryRun || false;\n\n logger.info('Scaffolding tests', { target: input.target, 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 const options = {\n includeEdgeCases: input.options?.includeEdgeCases ?? true,\n includeTenantIsolation: input.options?.includeTenantIsolation ?? true,\n includeSoftDelete: input.options?.includeSoftDelete ?? true,\n includeAudit: input.options?.includeAudit ?? true,\n includeValidation: input.options?.includeValidation ?? true,\n includeAuthorization: input.options?.includeAuthorization ?? false,\n isSystemEntity: input.options?.isSystemEntity ?? false,\n };\n\n const testTypes = input.testTypes || ['unit'];\n\n try {\n switch (input.target) {\n case 'entity':\n await scaffoldEntityTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n case 'service':\n await scaffoldServiceTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n case 'controller':\n await scaffoldControllerTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n case 'validator':\n await scaffoldValidatorTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n case 'repository':\n await scaffoldRepositoryTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n case 'all':\n await scaffoldEntityTests(input.name, options, testTypes, structure, config, result, dryRun);\n await scaffoldServiceTests(input.name, options, testTypes, structure, config, result, dryRun);\n await scaffoldControllerTests(input.name, options, testTypes, structure, config, result, dryRun);\n await scaffoldValidatorTests(input.name, options, testTypes, structure, config, result, dryRun);\n await scaffoldRepositoryTests(input.name, options, testTypes, structure, config, result, dryRun);\n break;\n }\n } catch (error) {\n result.success = false;\n result.instructions.push(`Error: ${error instanceof Error ? error.message : String(error)}`);\n }\n\n return formatTestResult(result, input.target, input.name, dryRun);\n}\n\n// ============================================================================\n// Scaffold Functions\n// ============================================================================\n\ninterface TestOptions {\n includeEdgeCases: boolean;\n includeTenantIsolation: boolean;\n includeSoftDelete: boolean;\n includeAudit: boolean;\n includeValidation: boolean;\n includeAuthorization: boolean;\n isSystemEntity: boolean;\n}\n\nasync function scaffoldEntityTests(\n name: string,\n options: TestOptions,\n testTypes: string[],\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean\n): Promise<void> {\n const testNamespace = `${config.conventions.namespaces.application}.Tests`;\n const domainNamespace = config.conventions.namespaces.domain;\n\n const context = {\n name,\n testNamespace,\n domainNamespace,\n ...options,\n };\n\n // Unit tests\n if (testTypes.includes('unit')) {\n const content = Handlebars.compile(entityTestTemplate)(context);\n const testPath = path.join(structure.root, 'Tests', 'Unit', 'Domain', `${name}Tests.cs`);\n\n validatePathSecurity(testPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(testPath));\n await writeText(testPath, content);\n }\n\n result.files.push({\n path: path.relative(structure.root, testPath),\n content,\n type: 'created',\n });\n }\n\n // Security tests\n if (testTypes.includes('security')) {\n const securityContent = Handlebars.compile(securityTestTemplate)({\n ...context,\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\n apiNamespace: config.conventions.namespaces.api,\n });\n const securityPath = path.join(structure.root, 'Tests', 'Security', `${name}SecurityTests.cs`);\n\n validatePathSecurity(securityPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(securityPath));\n await writeText(securityPath, securityContent);\n }\n\n result.files.push({\n path: path.relative(structure.root, securityPath),\n content: securityContent,\n type: 'created',\n });\n }\n\n result.instructions.push(`Add package reference: <PackageReference Include=\"FluentAssertions\" Version=\"6.*\" />`);\n result.instructions.push(`Add package reference: <PackageReference Include=\"xunit\" Version=\"2.*\" />`);\n}\n\nasync function scaffoldServiceTests(\n name: string,\n options: TestOptions,\n testTypes: string[],\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean\n): Promise<void> {\n const testNamespace = `${config.conventions.namespaces.application}.Tests`;\n const applicationNamespace = config.conventions.namespaces.application;\n const domainNamespace = config.conventions.namespaces.domain;\n\n const context = {\n name,\n testNamespace,\n applicationNamespace,\n domainNamespace,\n ...options,\n };\n\n if (testTypes.includes('unit')) {\n const content = Handlebars.compile(serviceTestTemplate)(context);\n const testPath = path.join(structure.root, 'Tests', 'Unit', 'Services', `${name}ServiceTests.cs`);\n\n validatePathSecurity(testPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(testPath));\n await writeText(testPath, content);\n }\n\n result.files.push({\n path: path.relative(structure.root, testPath),\n content,\n type: 'created',\n });\n }\n\n result.instructions.push(`Add package reference: <PackageReference Include=\"Moq\" Version=\"4.*\" />`);\n}\n\nasync function scaffoldControllerTests(\n name: string,\n options: TestOptions,\n testTypes: string[],\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean\n): Promise<void> {\n const testNamespace = `${config.conventions.namespaces.application}.Tests`;\n const applicationNamespace = config.conventions.namespaces.application;\n const domainNamespace = config.conventions.namespaces.domain;\n const apiNamespace = config.conventions.namespaces.api;\n\n const context = {\n name,\n nameLower: name.charAt(0).toLowerCase() + name.slice(1),\n testNamespace,\n applicationNamespace,\n domainNamespace,\n apiNamespace,\n ...options,\n };\n\n if (testTypes.includes('integration')) {\n const content = Handlebars.compile(controllerTestTemplate)(context);\n const testPath = path.join(structure.root, 'Tests', 'Integration', 'Controllers', `${name}ControllerTests.cs`);\n\n validatePathSecurity(testPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(testPath));\n await writeText(testPath, content);\n }\n\n result.files.push({\n path: path.relative(structure.root, testPath),\n content,\n type: 'created',\n });\n }\n\n if (testTypes.includes('security')) {\n const securityContent = Handlebars.compile(securityTestTemplate)(context);\n const securityPath = path.join(structure.root, 'Tests', 'Security', `${name}SecurityTests.cs`);\n\n validatePathSecurity(securityPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(securityPath));\n await writeText(securityPath, securityContent);\n }\n\n result.files.push({\n path: path.relative(structure.root, securityPath),\n content: securityContent,\n type: 'created',\n });\n }\n\n result.instructions.push(`Add package reference: <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Testing\" Version=\"8.*\" />`);\n}\n\nasync function scaffoldValidatorTests(\n name: string,\n options: TestOptions,\n testTypes: string[],\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean\n): Promise<void> {\n const testNamespace = `${config.conventions.namespaces.application}.Tests`;\n const applicationNamespace = config.conventions.namespaces.application;\n\n const context = {\n name,\n testNamespace,\n applicationNamespace,\n ...options,\n };\n\n if (testTypes.includes('unit')) {\n const content = Handlebars.compile(validatorTestTemplate)(context);\n const testPath = path.join(structure.root, 'Tests', 'Unit', 'Validators', `${name}ValidatorTests.cs`);\n\n validatePathSecurity(testPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(testPath));\n await writeText(testPath, content);\n }\n\n result.files.push({\n path: path.relative(structure.root, testPath),\n content,\n type: 'created',\n });\n }\n\n result.instructions.push(`Add package reference: <PackageReference Include=\"FluentValidation.TestHelper\" Version=\"11.*\" />`);\n}\n\nasync function scaffoldRepositoryTests(\n name: string,\n options: TestOptions,\n testTypes: string[],\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n config: Config,\n result: ScaffoldResult,\n dryRun: boolean\n): Promise<void> {\n const testNamespace = `${config.conventions.namespaces.application}.Tests`;\n const infrastructureNamespace = config.conventions.namespaces.infrastructure;\n const domainNamespace = config.conventions.namespaces.domain;\n\n const context = {\n name,\n testNamespace,\n infrastructureNamespace,\n domainNamespace,\n ...options,\n };\n\n if (testTypes.includes('integration')) {\n const content = Handlebars.compile(repositoryTestTemplate)(context);\n const testPath = path.join(structure.root, 'Tests', 'Integration', 'Repositories', `${name}RepositoryTests.cs`);\n\n validatePathSecurity(testPath, structure.root);\n\n if (!dryRun) {\n await ensureDirectory(path.dirname(testPath));\n await writeText(testPath, content);\n }\n\n result.files.push({\n path: path.relative(structure.root, testPath),\n content,\n type: 'created',\n });\n }\n\n result.instructions.push(`Add package reference: <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"8.*\" />`);\n}\n\n// ============================================================================\n// Formatting\n// ============================================================================\n\nfunction formatTestResult(\n result: ScaffoldResult,\n _target: string,\n name: string,\n dryRun: boolean\n): string {\n const lines: string[] = [];\n\n lines.push(`# Scaffold Tests: ${name}`);\n lines.push('');\n\n if (dryRun) {\n lines.push('> **DRY RUN MODE** - No files were written');\n lines.push('');\n }\n\n if (!result.success) {\n lines.push('## Error');\n lines.push('');\n lines.push(result.instructions.join('\\n'));\n return lines.join('\\n');\n }\n\n lines.push(`## Generated Test Files (${result.files.length})`);\n lines.push('');\n\n for (const file of result.files) {\n lines.push(`### \\`${file.path}\\``);\n lines.push('');\n lines.push('```csharp');\n lines.push(file.content);\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 lines.push(`- ${instruction}`);\n }\n lines.push('');\n }\n\n lines.push('## Test Conventions Applied');\n lines.push('');\n lines.push('- **Naming**: `{MethodName}_When{Condition}_Should{ExpectedResult}`');\n lines.push('- **Pattern**: AAA (Arrange-Act-Assert)');\n lines.push('- **Assertions**: FluentAssertions (`.Should()`)');\n lines.push('- **Mocking**: Moq (`Mock<T>`)');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n AnalyzeTestCoverageInputSchema,\n type Config,\n type TestCoverageResult,\n type TestCoverageCategory,\n} from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport { findFiles } from '../utils/fs.js';\nimport path from 'path';\n\nexport const analyzeTestCoverageTool: Tool = {\n name: 'analyze_test_coverage',\n description: 'Analyze test coverage for a SmartStack project. Identifies entities, services, and controllers without tests, calculates coverage ratios, and provides recommendations.',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to analyze (default: configured SmartStack path)',\n },\n scope: {\n type: 'string',\n enum: ['entity', 'service', 'controller', 'all'],\n default: 'all',\n description: 'Scope of analysis',\n },\n outputFormat: {\n type: 'string',\n enum: ['summary', 'detailed', 'json'],\n default: 'summary',\n description: 'Output format',\n },\n includeRecommendations: {\n type: 'boolean',\n default: true,\n description: 'Include recommendations for missing tests',\n },\n },\n },\n};\n\nexport async function handleAnalyzeTestCoverage(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = AnalyzeTestCoverageInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n\n logger.info('Analyzing test coverage', { projectPath, scope: input.scope });\n\n const structure = await findSmartStackStructure(projectPath);\n\n const result: TestCoverageResult = {\n summary: { total: 0, tested: 0, coverage: 0 },\n entities: { total: 0, tested: 0, coverage: 0, items: [], missingTests: [] },\n services: { total: 0, tested: 0, coverage: 0, items: [], missingTests: [] },\n controllers: { total: 0, tested: 0, coverage: 0, items: [], missingTests: [] },\n missing: [],\n recommendations: [],\n };\n\n try {\n if (input.scope === 'all' || input.scope === 'entity') {\n await analyzeEntityCoverage(structure, result);\n }\n\n if (input.scope === 'all' || input.scope === 'service') {\n await analyzeServiceCoverage(structure, result);\n }\n\n if (input.scope === 'all' || input.scope === 'controller') {\n await analyzeControllerCoverage(structure, result);\n }\n\n // Calculate overall summary\n result.summary.total = result.entities.total + result.services.total + result.controllers.total;\n result.summary.tested = result.entities.tested + result.services.tested + result.controllers.tested;\n result.summary.coverage = result.summary.total > 0\n ? Math.round((result.summary.tested / result.summary.total) * 100)\n : 0;\n\n // Generate recommendations\n if (input.includeRecommendations) {\n generateRecommendations(result);\n }\n\n } catch (error) {\n logger.error('Error analyzing test coverage', error);\n return `Error: ${error instanceof Error ? error.message : String(error)}`;\n }\n\n return formatCoverageResult(result, input.outputFormat);\n}\n\n// ============================================================================\n// Analysis Functions\n// ============================================================================\n\nasync function analyzeEntityCoverage(\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n result: TestCoverageResult\n): Promise<void> {\n if (!structure.domain) {\n result.recommendations.push('Domain layer not found - cannot analyze entity coverage');\n return;\n }\n\n // Find all entity files in Domain\n const entityFiles = await findFiles('**/*.cs', { cwd: structure.domain });\n const entityNames = extractComponentNames(entityFiles, ['Entity', 'Aggregate']);\n\n // Find all entity tests\n const testPath = path.join(structure.root, 'Tests', 'Unit', 'Domain');\n let testFiles: string[] = [];\n try {\n testFiles = await findFiles('**/*Tests.cs', { cwd: testPath });\n } catch {\n // Tests directory might not exist\n }\n const testedEntities = extractTestedNames(testFiles);\n\n result.entities.total = entityNames.length;\n result.entities.items = entityNames;\n result.entities.tested = entityNames.filter(e => testedEntities.includes(e)).length;\n result.entities.coverage = result.entities.total > 0\n ? Math.round((result.entities.tested / result.entities.total) * 100)\n : 0;\n result.entities.missingTests = entityNames.filter(e => !testedEntities.includes(e));\n\n // Add to missing items with priority\n for (const name of result.entities.missingTests) {\n result.missing.push({\n name,\n type: 'entity',\n priority: determinePriority(name, 'entity'),\n recommendation: `Create unit tests for ${name} entity (factory methods, soft delete, audit trail)`,\n suggestedTestFile: `Tests/Unit/Domain/${name}Tests.cs`,\n });\n }\n}\n\nasync function analyzeServiceCoverage(\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n result: TestCoverageResult\n): Promise<void> {\n if (!structure.application) {\n result.recommendations.push('Application layer not found - cannot analyze service coverage');\n return;\n }\n\n // Find all service interfaces\n const serviceFiles = await findFiles('**/I*Service.cs', { cwd: structure.application });\n const serviceNames = serviceFiles.map(f => {\n const basename = path.basename(f, '.cs');\n // Remove 'I' prefix to get service name\n return basename.startsWith('I') ? basename.slice(1) : basename;\n }).filter(n => n.endsWith('Service')).map(n => n.replace(/Service$/, ''));\n\n // Find all service tests\n const testPath = path.join(structure.root, 'Tests', 'Unit', 'Services');\n let testFiles: string[] = [];\n try {\n testFiles = await findFiles('**/*ServiceTests.cs', { cwd: testPath });\n } catch {\n // Tests directory might not exist\n }\n const testedServices = testFiles.map(f => {\n const basename = path.basename(f, '.cs');\n return basename.replace(/ServiceTests$/, '');\n });\n\n result.services.total = serviceNames.length;\n result.services.items = serviceNames;\n result.services.tested = serviceNames.filter(s => testedServices.includes(s)).length;\n result.services.coverage = result.services.total > 0\n ? Math.round((result.services.tested / result.services.total) * 100)\n : 0;\n result.services.missingTests = serviceNames.filter(s => !testedServices.includes(s));\n\n // Add to missing items with priority\n for (const name of result.services.missingTests) {\n result.missing.push({\n name,\n type: 'service',\n priority: determinePriority(name, 'service'),\n recommendation: `Create unit tests for ${name}Service (CRUD operations, business logic, error handling)`,\n suggestedTestFile: `Tests/Unit/Services/${name}ServiceTests.cs`,\n });\n }\n}\n\nasync function analyzeControllerCoverage(\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n result: TestCoverageResult\n): Promise<void> {\n if (!structure.api) {\n result.recommendations.push('API layer not found - cannot analyze controller coverage');\n return;\n }\n\n // Find all controllers\n const controllerFiles = await findFiles('**/*Controller.cs', { cwd: structure.api });\n const controllerNames = controllerFiles.map(f => {\n const basename = path.basename(f, '.cs');\n return basename.replace(/Controller$/, '');\n }).filter(n => n !== 'Base'); // Exclude BaseController\n\n // Find all controller tests\n const testPath = path.join(structure.root, 'Tests', 'Integration', 'Controllers');\n let testFiles: string[] = [];\n try {\n testFiles = await findFiles('**/*ControllerTests.cs', { cwd: testPath });\n } catch {\n // Tests directory might not exist\n }\n const testedControllers = testFiles.map(f => {\n const basename = path.basename(f, '.cs');\n return basename.replace(/ControllerTests$/, '');\n });\n\n result.controllers.total = controllerNames.length;\n result.controllers.items = controllerNames;\n result.controllers.tested = controllerNames.filter(c => testedControllers.includes(c)).length;\n result.controllers.coverage = result.controllers.total > 0\n ? Math.round((result.controllers.tested / result.controllers.total) * 100)\n : 0;\n result.controllers.missingTests = controllerNames.filter(c => !testedControllers.includes(c));\n\n // Add to missing items with priority\n for (const name of result.controllers.missingTests) {\n result.missing.push({\n name,\n type: 'controller',\n priority: determinePriority(name, 'controller'),\n recommendation: `Create integration tests for ${name}Controller (HTTP status codes, authorization, validation)`,\n suggestedTestFile: `Tests/Integration/Controllers/${name}ControllerTests.cs`,\n });\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction extractComponentNames(files: string[], excludeSuffixes: string[] = []): string[] {\n return files\n .map(f => path.basename(f, '.cs'))\n .filter(name => {\n // Exclude common non-entity files\n const excludePatterns = [\n 'Configuration', 'Extensions', 'Handler', 'Specification',\n 'Repository', 'Service', 'Controller', 'Dto', 'Validator',\n ...excludeSuffixes\n ];\n return !excludePatterns.some(pattern => name.endsWith(pattern));\n })\n .filter(name => !name.startsWith('I')) // Exclude interfaces\n .filter(name => !name.startsWith('Base')); // Exclude base classes\n}\n\nfunction extractTestedNames(testFiles: string[]): string[] {\n return testFiles.map(f => {\n const basename = path.basename(f, '.cs');\n return basename.replace(/Tests$/, '');\n });\n}\n\nfunction determinePriority(name: string, type: 'entity' | 'service' | 'controller'): 'critical' | 'high' | 'medium' | 'low' {\n const criticalPatterns = ['User', 'Auth', 'Payment', 'Order', 'Tenant', 'Security', 'Permission', 'Role'];\n const highPatterns = ['Account', 'Invoice', 'Transaction', 'Session', 'Token', 'Subscription'];\n\n const nameLower = name.toLowerCase();\n\n if (criticalPatterns.some(p => nameLower.includes(p.toLowerCase()))) {\n return 'critical';\n }\n\n if (highPatterns.some(p => nameLower.includes(p.toLowerCase()))) {\n return 'high';\n }\n\n // Controllers are generally higher priority than entities\n if (type === 'controller') {\n return 'high';\n }\n\n if (type === 'service') {\n return 'medium';\n }\n\n return 'medium';\n}\n\nfunction generateRecommendations(result: TestCoverageResult): void {\n // Coverage-based recommendations\n if (result.summary.coverage < 50) {\n result.recommendations.push('CRITICAL: Overall test coverage is below 50%. Prioritize adding tests for critical components.');\n } else if (result.summary.coverage < 80) {\n result.recommendations.push('Test coverage is below recommended 80% threshold. Consider adding more tests.');\n }\n\n // Category-specific recommendations\n if (result.entities.coverage < 60) {\n result.recommendations.push(`Entity coverage (${result.entities.coverage}%) is low. Focus on testing factory methods, soft delete, and audit trails.`);\n }\n\n if (result.services.coverage < 70) {\n result.recommendations.push(`Service coverage (${result.services.coverage}%) is low. Ensure CRUD operations and business logic are tested.`);\n }\n\n if (result.controllers.coverage < 80) {\n result.recommendations.push(`Controller coverage (${result.controllers.coverage}%) is low. Add integration tests for HTTP endpoints.`);\n }\n\n // Priority-based recommendations\n const criticalMissing = result.missing.filter(m => m.priority === 'critical');\n if (criticalMissing.length > 0) {\n result.recommendations.push(`${criticalMissing.length} CRITICAL component(s) have no tests: ${criticalMissing.map(m => m.name).join(', ')}`);\n }\n\n // Security recommendations\n const securityComponents = result.missing.filter(m =>\n m.name.toLowerCase().includes('auth') ||\n m.name.toLowerCase().includes('security') ||\n m.name.toLowerCase().includes('permission')\n );\n if (securityComponents.length > 0) {\n result.recommendations.push(`Security-sensitive components without tests: ${securityComponents.map(m => m.name).join(', ')}. Add security tests immediately.`);\n }\n}\n\n// ============================================================================\n// Formatting\n// ============================================================================\n\nfunction formatCoverageResult(\n result: TestCoverageResult,\n format: string\n): string {\n if (format === 'json') {\n return JSON.stringify(result, null, 2);\n }\n\n const lines: string[] = [];\n\n lines.push('# Test Coverage Analysis');\n lines.push('');\n\n // Summary\n const coverageEmoji = result.summary.coverage >= 80 ? '✅' : result.summary.coverage >= 50 ? '⚠️' : '❌';\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| **Overall Coverage** | ${coverageEmoji} ${result.summary.coverage}% (${result.summary.tested}/${result.summary.total}) |`);\n lines.push(`| Entities | ${formatCoverageCell(result.entities)} |`);\n lines.push(`| Services | ${formatCoverageCell(result.services)} |`);\n lines.push(`| Controllers | ${formatCoverageCell(result.controllers)} |`);\n lines.push('');\n\n if (format === 'detailed') {\n // Detailed breakdown\n if (result.entities.missingTests.length > 0) {\n lines.push('## Missing Entity Tests');\n lines.push('');\n for (const name of result.entities.missingTests) {\n lines.push(`- [ ] ${name}`);\n }\n lines.push('');\n }\n\n if (result.services.missingTests.length > 0) {\n lines.push('## Missing Service Tests');\n lines.push('');\n for (const name of result.services.missingTests) {\n lines.push(`- [ ] ${name}Service`);\n }\n lines.push('');\n }\n\n if (result.controllers.missingTests.length > 0) {\n lines.push('## Missing Controller Tests');\n lines.push('');\n for (const name of result.controllers.missingTests) {\n lines.push(`- [ ] ${name}Controller`);\n }\n lines.push('');\n }\n }\n\n // Priority list\n if (result.missing.length > 0) {\n lines.push('## Missing Tests (By Priority)');\n lines.push('');\n\n const priorities: Array<'critical' | 'high' | 'medium' | 'low'> = ['critical', 'high', 'medium', 'low'];\n for (const priority of priorities) {\n const items = result.missing.filter(m => m.priority === priority);\n if (items.length > 0) {\n const emoji = priority === 'critical' ? '🔴' : priority === 'high' ? '🟠' : priority === 'medium' ? '🟡' : '🟢';\n lines.push(`### ${emoji} ${priority.charAt(0).toUpperCase() + priority.slice(1)} Priority`);\n lines.push('');\n lines.push('| Component | Type | Suggested Test File |');\n lines.push('|-----------|------|---------------------|');\n for (const item of items) {\n lines.push(`| ${item.name} | ${item.type} | \\`${item.suggestedTestFile}\\` |`);\n }\n lines.push('');\n }\n }\n }\n\n // Recommendations\n if (result.recommendations.length > 0) {\n lines.push('## Recommendations');\n lines.push('');\n for (const rec of result.recommendations) {\n const emoji = rec.includes('CRITICAL') ? '🔴' : rec.includes('low') ? '⚠️' : '💡';\n lines.push(`${emoji} ${rec}`);\n lines.push('');\n }\n }\n\n // Action items\n lines.push('## Quick Actions');\n lines.push('');\n lines.push('Generate tests for missing components using:');\n lines.push('');\n if (result.missing.length > 0) {\n const firstMissing = result.missing[0];\n lines.push('```');\n lines.push(`scaffold_tests(target: \"${firstMissing.type}\", name: \"${firstMissing.name}\")`);\n lines.push('```');\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction formatCoverageCell(category: TestCoverageCategory): string {\n const emoji = category.coverage >= 80 ? '✅' : category.coverage >= 50 ? '⚠️' : '❌';\n return `${emoji} ${category.coverage}% (${category.tested}/${category.total})`;\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n ValidateTestConventionsInputSchema,\n type Config,\n type TestConventionResult,\n type TestConventionViolation,\n} from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport path from 'path';\n\nexport const validateTestConventionsTool: Tool = {\n name: 'validate_test_conventions',\n description: 'Validate that tests in a SmartStack project follow conventions: naming ({Method}_When{Condition}_Should{Result}), structure (Tests/Unit, Tests/Integration), patterns (AAA), assertions (FluentAssertions), and mocking (Moq).',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to validate (default: configured SmartStack path)',\n },\n checks: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['naming', 'structure', 'patterns', 'assertions', 'mocking', 'all'],\n },\n default: ['all'],\n description: 'Types of convention checks to perform',\n },\n autoFix: {\n type: 'boolean',\n default: false,\n description: 'Automatically fix minor issues (naming only)',\n },\n },\n },\n};\n\n// Convention patterns\nconst PATTERNS = {\n // Test method naming: MethodName_WhenCondition_ShouldExpectedResult\n testMethodNaming: /^(\\w+)_When(\\w+)_Should(\\w+)$/,\n // Alternative valid patterns\n testMethodNamingAlt: /^(\\w+)_Should(\\w+)_When(\\w+)$/,\n // Fact/Theory attributes\n factAttribute: /\\[Fact\\]/,\n theoryAttribute: /\\[Theory\\]/,\n // AAA pattern comments\n arrangeComment: /\\/\\/\\s*Arrange/i,\n actComment: /\\/\\/\\s*Act/i,\n assertComment: /\\/\\/\\s*Assert/i,\n // FluentAssertions\n fluentAssertions: /\\.Should\\(\\)/,\n // Moq\n moqUsage: /new Mock<|Mock<\\w+>/,\n moqSetup: /\\.Setup\\(|\\.Verify\\(/,\n // Test class naming\n testClassNaming: /public class (\\w+)Tests/,\n // xUnit patterns\n asyncTestMethod: /public async Task (\\w+)/,\n syncTestMethod: /public void (\\w+)/,\n};\n\nexport async function handleValidateTestConventions(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ValidateTestConventionsInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const checks = input.checks.includes('all')\n ? ['naming', 'structure', 'patterns', 'assertions', 'mocking']\n : input.checks;\n\n logger.info('Validating test conventions', { projectPath, checks });\n\n const structure = await findSmartStackStructure(projectPath);\n\n const result: TestConventionResult = {\n valid: true,\n violations: [],\n suggestions: [],\n autoFixedCount: 0,\n };\n\n const testsPath = path.join(structure.root, 'Tests');\n\n try {\n // Find all test files\n let testFiles: string[] = [];\n try {\n testFiles = await findFiles('**/*Tests.cs', { cwd: testsPath });\n } catch {\n result.suggestions.push('No Tests directory found. Create a Tests project with Unit and Integration subdirectories.');\n return formatValidationResult(result);\n }\n\n if (testFiles.length === 0) {\n result.suggestions.push('No test files found. Create test files following the pattern {ComponentName}Tests.cs');\n return formatValidationResult(result);\n }\n\n // Validate structure\n if (checks.includes('structure')) {\n await validateStructure(testsPath, testFiles, result);\n }\n\n // Validate each test file\n for (const testFile of testFiles) {\n const fullPath = path.join(testsPath, testFile);\n const content = await readText(fullPath);\n\n if (checks.includes('naming')) {\n validateNaming(testFile, content, result, input.autoFix);\n }\n\n if (checks.includes('patterns')) {\n validatePatterns(testFile, content, result);\n }\n\n if (checks.includes('assertions')) {\n validateAssertions(testFile, content, result);\n }\n\n if (checks.includes('mocking')) {\n validateMocking(testFile, content, result);\n }\n }\n\n result.valid = result.violations.filter(v => v.severity === 'error').length === 0;\n\n } catch (error) {\n logger.error('Error validating test conventions', error);\n return `Error: ${error instanceof Error ? error.message : String(error)}`;\n }\n\n return formatValidationResult(result);\n}\n\n// ============================================================================\n// Validation Functions\n// ============================================================================\n\nasync function validateStructure(\n testsPath: string,\n testFiles: string[],\n result: TestConventionResult\n): Promise<void> {\n // Check for expected directory structure\n const expectedDirs = ['Unit', 'Integration'];\n const foundDirs = new Set<string>();\n\n for (const file of testFiles) {\n const parts = file.split(path.sep);\n if (parts.length > 1) {\n foundDirs.add(parts[0]);\n }\n }\n\n for (const dir of expectedDirs) {\n if (!foundDirs.has(dir)) {\n result.violations.push({\n type: 'structure',\n severity: 'warning',\n file: testsPath,\n message: `Missing expected directory: Tests/${dir}`,\n suggestion: `Create Tests/${dir} directory for ${dir.toLowerCase()} tests`,\n autoFixable: false,\n });\n }\n }\n\n // Check for recommended subdirectories\n const hasUnitDomain = testFiles.some(f => f.includes(path.join('Unit', 'Domain')));\n const hasIntegrationControllers = testFiles.some(f => f.includes(path.join('Integration', 'Controllers')));\n\n if (!hasUnitDomain && testFiles.some(f => f.includes('Unit'))) {\n result.suggestions.push('Consider organizing unit tests into subdirectories: Unit/Domain, Unit/Services, Unit/Validators');\n }\n\n if (!hasIntegrationControllers && testFiles.some(f => f.includes('Integration'))) {\n result.suggestions.push('Consider organizing integration tests into subdirectories: Integration/Controllers, Integration/Repositories');\n }\n\n // Check for security tests\n const hasSecurityTests = testFiles.some(f => f.includes('Security'));\n if (!hasSecurityTests) {\n result.suggestions.push('Consider adding a Tests/Security directory for security-focused tests');\n }\n}\n\nfunction validateNaming(\n testFile: string,\n content: string,\n result: TestConventionResult,\n _autoFix: boolean\n): void {\n // Validate test class naming\n const classMatch = content.match(/public class (\\w+)/);\n if (classMatch) {\n const className = classMatch[1];\n if (!className.endsWith('Tests')) {\n result.violations.push({\n type: 'naming',\n severity: 'error',\n file: testFile,\n message: `Test class '${className}' should end with 'Tests'`,\n suggestion: `Rename to '${className}Tests'`,\n autoFixable: true,\n });\n }\n }\n\n // Validate test method naming\n const methodMatches = content.matchAll(/\\[(Fact|Theory)\\]\\s*\\n\\s*public (?:async Task|void) (\\w+)\\(/g);\n\n for (const match of methodMatches) {\n const methodName = match[2];\n\n // Check if follows convention\n const isValidName = PATTERNS.testMethodNaming.test(methodName) ||\n PATTERNS.testMethodNamingAlt.test(methodName);\n\n if (!isValidName) {\n // Check for common patterns that could be improved\n if (methodName.includes('Test') && !methodName.includes('_')) {\n result.violations.push({\n type: 'naming',\n severity: 'warning',\n file: testFile,\n message: `Test method '${methodName}' doesn't follow naming convention`,\n suggestion: `Rename to format: {Method}_When{Condition}_Should{Result} (e.g., GetById_WhenExists_ShouldReturnEntity)`,\n autoFixable: false,\n });\n } else if (!methodName.includes('_')) {\n result.violations.push({\n type: 'naming',\n severity: 'warning',\n file: testFile,\n message: `Test method '${methodName}' should use underscores to separate parts`,\n suggestion: `Use format: {Method}_When{Condition}_Should{Result}`,\n autoFixable: false,\n });\n }\n }\n }\n}\n\nfunction validatePatterns(\n testFile: string,\n content: string,\n result: TestConventionResult\n): void {\n // Check for AAA pattern usage\n const methodBlocks = content.matchAll(/\\[(Fact|Theory)\\][^\\[]*?public (?:async Task|void) \\w+\\([^)]*\\)\\s*\\{([^}]+)\\}/gs);\n\n for (const match of methodBlocks) {\n const methodBody = match[2];\n\n const hasArrange = PATTERNS.arrangeComment.test(methodBody);\n const hasAct = PATTERNS.actComment.test(methodBody);\n const hasAssert = PATTERNS.assertComment.test(methodBody);\n\n // Only flag if none of the AAA comments are present and method is non-trivial\n if (!hasArrange && !hasAct && !hasAssert && methodBody.split('\\n').length > 3) {\n result.violations.push({\n type: 'pattern',\n severity: 'warning',\n file: testFile,\n message: 'Test method missing AAA (Arrange-Act-Assert) comments',\n suggestion: 'Add // Arrange, // Act, // Assert comments to improve readability',\n autoFixable: false,\n });\n break; // Only report once per file\n }\n }\n\n // Check for proper async/await usage\n const asyncMethods = content.matchAll(/public async Task (\\w+)\\([^)]*\\)\\s*\\{([^}]+)\\}/gs);\n for (const match of asyncMethods) {\n const methodName = match[1];\n const methodBody = match[2];\n\n if (!methodBody.includes('await')) {\n result.violations.push({\n type: 'pattern',\n severity: 'warning',\n file: testFile,\n message: `Async test method '${methodName}' doesn't contain 'await'`,\n suggestion: 'Either add await or change to synchronous void method',\n autoFixable: false,\n });\n }\n }\n}\n\nfunction validateAssertions(\n testFile: string,\n content: string,\n result: TestConventionResult\n): void {\n // Check for FluentAssertions usage\n const hasFluentAssertions = PATTERNS.fluentAssertions.test(content);\n const hasXunitAssert = /Assert\\.\\w+\\(/.test(content);\n\n if (hasXunitAssert && !hasFluentAssertions) {\n result.violations.push({\n type: 'assertion',\n severity: 'warning',\n file: testFile,\n message: 'Using xUnit Assert instead of FluentAssertions',\n suggestion: 'Replace Assert.Equal(expected, actual) with actual.Should().Be(expected)',\n autoFixable: false,\n });\n }\n\n // Check for common FluentAssertions patterns\n if (hasFluentAssertions) {\n // Check for proper null assertions\n if (content.includes('.Should().NotBe(null)')) {\n result.violations.push({\n type: 'assertion',\n severity: 'warning',\n file: testFile,\n message: 'Use .Should().NotBeNull() instead of .Should().NotBe(null)',\n suggestion: 'Replace .Should().NotBe(null) with .Should().NotBeNull()',\n autoFixable: true,\n });\n }\n\n // Check for proper exception assertions\n if (content.includes('.Should().Throw<') && content.includes('async')) {\n if (!content.includes('.Should().ThrowAsync<')) {\n result.suggestions.push('Use .Should().ThrowAsync<T>() for async exception testing');\n }\n }\n }\n\n // Check for assertion presence in test methods\n const methodBlocks = content.matchAll(/\\[(Fact|Theory)\\][^\\[]*?public (?:async Task|void) (\\w+)\\([^)]*\\)\\s*\\{([^}]+)\\}/gs);\n for (const match of methodBlocks) {\n const methodName = match[2];\n const methodBody = match[3];\n\n const hasAssertion = methodBody.includes('.Should()') ||\n methodBody.includes('Assert.') ||\n methodBody.includes('Verify(') ||\n methodBody.includes('VerifyAll()');\n\n if (!hasAssertion) {\n result.violations.push({\n type: 'assertion',\n severity: 'error',\n file: testFile,\n message: `Test method '${methodName}' has no assertions`,\n suggestion: 'Add at least one assertion to verify expected behavior',\n autoFixable: false,\n });\n }\n }\n}\n\nfunction validateMocking(\n testFile: string,\n content: string,\n result: TestConventionResult\n): void {\n const hasMoq = PATTERNS.moqUsage.test(content);\n\n if (hasMoq) {\n // Check for proper Moq setup\n if (content.includes('new Mock<') && !content.includes('.Setup(')) {\n result.violations.push({\n type: 'mocking',\n severity: 'warning',\n file: testFile,\n message: 'Mock objects created but no Setup() calls found',\n suggestion: 'Add .Setup() calls to define mock behavior',\n autoFixable: false,\n });\n }\n\n // Check for Verify usage\n const hasSetup = content.includes('.Setup(');\n const hasVerify = content.includes('.Verify(') || content.includes('.VerifyAll()');\n\n if (hasSetup && !hasVerify) {\n result.suggestions.push(`Consider adding .Verify() calls in ${testFile} to verify mock interactions`);\n }\n\n // Check for strict vs loose mocking\n if (content.includes('MockBehavior.Strict')) {\n result.suggestions.push('Using MockBehavior.Strict - ensure all mock calls are set up');\n }\n }\n\n // Check for service mocking in controller tests\n if (testFile.includes('Controller')) {\n if (!hasMoq && !content.includes('WebApplicationFactory')) {\n result.violations.push({\n type: 'mocking',\n severity: 'warning',\n file: testFile,\n message: 'Controller tests should use mocking or WebApplicationFactory',\n suggestion: 'Use Moq for unit tests or WebApplicationFactory for integration tests',\n autoFixable: false,\n });\n }\n }\n}\n\n// ============================================================================\n// Formatting\n// ============================================================================\n\nfunction formatValidationResult(result: TestConventionResult): string {\n const lines: string[] = [];\n\n lines.push('# Test Convention Validation');\n lines.push('');\n\n // Summary\n const status = result.valid ? '✅ PASSED' : '❌ FAILED';\n const errorCount = result.violations.filter(v => v.severity === 'error').length;\n const warningCount = result.violations.filter(v => v.severity === 'warning').length;\n\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Status | ${status} |`);\n lines.push('|--------|----------|');\n lines.push(`| Errors | ${errorCount} |`);\n lines.push(`| Warnings | ${warningCount} |`);\n if (result.autoFixedCount > 0) {\n lines.push(`| Auto-fixed | ${result.autoFixedCount} |`);\n }\n lines.push('');\n\n // Violations\n if (result.violations.length > 0) {\n lines.push('## Violations');\n lines.push('');\n\n // Group by type\n const byType = new Map<string, TestConventionViolation[]>();\n for (const v of result.violations) {\n const existing = byType.get(v.type) || [];\n existing.push(v);\n byType.set(v.type, existing);\n }\n\n for (const [type, violations] of byType) {\n lines.push(`### ${type.charAt(0).toUpperCase() + type.slice(1)} Violations`);\n lines.push('');\n\n for (const v of violations) {\n const emoji = v.severity === 'error' ? '❌' : '⚠️';\n lines.push(`${emoji} **${v.file}**`);\n lines.push(` - ${v.message}`);\n lines.push(` - 💡 ${v.suggestion}`);\n if (v.autoFixable) {\n lines.push(` - 🔧 Auto-fixable`);\n }\n lines.push('');\n }\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 lines.push('');\n }\n }\n\n // Convention reference\n lines.push('## SmartStack Test Conventions');\n lines.push('');\n lines.push('### Naming');\n lines.push('- Files: `{ComponentName}Tests.cs`');\n lines.push('- Classes: `{ComponentName}Tests`');\n lines.push('- Methods: `{MethodName}_When{Condition}_Should{ExpectedResult}`');\n lines.push('');\n lines.push('### Structure');\n lines.push('```');\n lines.push('Tests/');\n lines.push('├── Unit/');\n lines.push('│ ├── Domain/');\n lines.push('│ ├── Services/');\n lines.push('│ └── Validators/');\n lines.push('├── Integration/');\n lines.push('│ ├── Controllers/');\n lines.push('│ └── Repositories/');\n lines.push('└── Security/');\n lines.push('```');\n lines.push('');\n lines.push('### Pattern (AAA)');\n lines.push('```csharp');\n lines.push('[Fact]');\n lines.push('public async Task GetById_WhenExists_ShouldReturnEntity()');\n lines.push('{');\n lines.push(' // Arrange');\n lines.push(' var id = Guid.NewGuid();');\n lines.push('');\n lines.push(' // Act');\n lines.push(' var result = await _sut.GetByIdAsync(id);');\n lines.push('');\n lines.push(' // Assert');\n lines.push(' result.Should().NotBeNull();');\n lines.push('}');\n lines.push('```');\n lines.push('');\n\n return lines.join('\\n');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n SuggestTestScenariosInputSchema,\n type Config,\n type TestScenarioResult,\n type DetectedMethod,\n type TestScenario,\n} from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport path from 'path';\n\nexport const suggestTestScenariosTool: Tool = {\n name: 'suggest_test_scenarios',\n description: 'Analyze source code and suggest test scenarios based on detected methods, parameters, and patterns. Generates comprehensive test case recommendations for SmartStack components.',\n inputSchema: {\n type: 'object',\n properties: {\n target: {\n type: 'string',\n enum: ['entity', 'service', 'controller', 'file'],\n description: 'Type of target to analyze',\n },\n name: {\n type: 'string',\n description: 'Component name or file path',\n },\n depth: {\n type: 'string',\n enum: ['basic', 'comprehensive', 'security-focused'],\n default: 'comprehensive',\n description: 'Depth of analysis',\n },\n },\n required: ['target', 'name'],\n },\n};\n\n// C# parsing patterns\nconst PATTERNS = {\n // Method signatures\n publicMethod: /public\\s+(?:async\\s+)?(?:Task<)?(\\w+)>?\\s+(\\w+)\\s*\\(([^)]*)\\)/g,\n // Parameter extraction\n parameter: /(?:(\\w+)\\s+)?(\\w+)\\s+(\\w+)(?:\\s*=\\s*([^,)]+))?/g,\n // Property\n property: /public\\s+(?:virtual\\s+)?(\\w+)\\??\\s+(\\w+)\\s*\\{\\s*get;/g,\n // Validation attributes\n validationAttribute: /\\[(Required|MaxLength|MinLength|Range|EmailAddress|Phone|Url|RegularExpression)\\s*(?:\\(([^)]*)\\))?\\]/g,\n // Entity patterns\n baseEntity: /:\\s*(?:BaseEntity|SystemEntity)/,\n tenantEntity: /ITenantEntity/,\n // Factory method\n factoryMethod: /public\\s+static\\s+\\w+\\s+Create\\s*\\(/,\n // Soft delete\n softDelete: /public\\s+void\\s+SoftDelete/,\n};\n\nexport async function handleSuggestTestScenarios(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = SuggestTestScenariosInputSchema.parse(args);\n\n logger.info('Suggesting test scenarios', { target: input.target, name: input.name, depth: input.depth });\n\n const structure = await findSmartStackStructure(config.smartstack.projectPath);\n\n const result: TestScenarioResult = {\n target: input.name,\n targetType: input.target as 'entity' | 'service' | 'controller' | 'file',\n detectedMethods: [],\n scenarios: [],\n coverage: {\n happyPath: 0,\n validation: 0,\n errorHandling: 0,\n security: 0,\n edgeCases: 0,\n },\n };\n\n try {\n // Find and read the source file\n const sourceFile = await findSourceFile(input.target, input.name, structure, config);\n if (!sourceFile) {\n return `Error: Could not find ${input.target} '${input.name}'`;\n }\n\n const content = await readText(sourceFile);\n\n // Parse the source code\n result.detectedMethods = parseSourceCode(content);\n\n // Generate test scenarios\n result.scenarios = generateScenarios(\n result.detectedMethods,\n content,\n input.target,\n input.depth\n );\n\n // Calculate coverage distribution\n calculateCoverageDistribution(result);\n\n } catch (error) {\n logger.error('Error suggesting test scenarios', error);\n return `Error: ${error instanceof Error ? error.message : String(error)}`;\n }\n\n return formatScenariosResult(result, input.depth);\n}\n\n// ============================================================================\n// Source File Finding\n// ============================================================================\n\nasync function findSourceFile(\n target: string,\n name: string,\n structure: { root: string; domain?: string; application?: string; infrastructure?: string; api?: string },\n _config: Config\n): Promise<string | null> {\n let searchPath: string;\n let pattern: string;\n\n switch (target) {\n case 'entity':\n searchPath = structure.domain || structure.root;\n pattern = `**/${name}.cs`;\n break;\n case 'service':\n searchPath = structure.application || structure.root;\n pattern = `**/${name}Service.cs`;\n break;\n case 'controller':\n searchPath = structure.api || structure.root;\n pattern = `**/${name}Controller.cs`;\n break;\n case 'file':\n return path.isAbsolute(name) ? name : path.join(structure.root, name);\n default:\n return null;\n }\n\n const files = await findFiles(pattern, { cwd: searchPath });\n if (files.length === 0) {\n // Try alternative patterns\n const altPattern = `**/*${name}*.cs`;\n const altFiles = await findFiles(altPattern, { cwd: searchPath });\n if (altFiles.length > 0) {\n return path.join(searchPath, altFiles[0]);\n }\n return null;\n }\n\n return path.join(searchPath, files[0]);\n}\n\n// ============================================================================\n// Source Code Parsing\n// ============================================================================\n\nfunction parseSourceCode(content: string): DetectedMethod[] {\n const methods: DetectedMethod[] = [];\n\n // Reset regex lastIndex\n PATTERNS.publicMethod.lastIndex = 0;\n\n let match;\n while ((match = PATTERNS.publicMethod.exec(content)) !== null) {\n const returnType = match[1];\n const methodName = match[2];\n const parametersStr = match[3];\n\n // Parse parameters\n const parameters: string[] = [];\n if (parametersStr.trim()) {\n const params = parametersStr.split(',');\n for (const param of params) {\n const trimmed = param.trim();\n if (trimmed) {\n // Extract parameter name\n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 2) {\n parameters.push(`${parts[parts.length - 2]} ${parts[parts.length - 1]}`);\n }\n }\n }\n }\n\n // Determine visibility and async\n const isAsync = content.substring(Math.max(0, match.index - 20), match.index).includes('async');\n const isPublic = content.substring(Math.max(0, match.index - 20), match.index).includes('public');\n\n if (isPublic && !methodName.startsWith('get_') && !methodName.startsWith('set_')) {\n methods.push({\n name: methodName,\n returnType,\n parameters,\n isAsync,\n visibility: 'public',\n });\n }\n }\n\n return methods;\n}\n\n// ============================================================================\n// Scenario Generation\n// ============================================================================\n\nfunction generateScenarios(\n methods: DetectedMethod[],\n content: string,\n target: string,\n depth: string\n): TestScenario[] {\n const scenarios: TestScenario[] = [];\n\n // Detect patterns in source\n const isEntity = PATTERNS.baseEntity.test(content);\n const hasTenant = PATTERNS.tenantEntity.test(content);\n const hasFactoryMethod = PATTERNS.factoryMethod.test(content);\n const hasSoftDelete = PATTERNS.softDelete.test(content);\n\n for (const method of methods) {\n // Generate scenarios based on method name patterns\n const methodScenarios = generateMethodScenarios(\n method,\n { isEntity, hasTenant, hasFactoryMethod, hasSoftDelete },\n target,\n depth\n );\n scenarios.push(...methodScenarios);\n }\n\n // Add entity-specific scenarios\n if (isEntity && target === 'entity') {\n scenarios.push(...generateEntityScenarios(content, hasTenant, hasSoftDelete, depth));\n }\n\n // Add security scenarios for comprehensive/security-focused\n if (depth !== 'basic') {\n scenarios.push(...generateSecurityScenarios(methods, hasTenant, target));\n }\n\n return scenarios;\n}\n\nfunction generateMethodScenarios(\n method: DetectedMethod,\n patterns: { isEntity: boolean; hasTenant: boolean; hasFactoryMethod: boolean; hasSoftDelete: boolean },\n _target: string,\n depth: string\n): TestScenario[] {\n const scenarios: TestScenario[] = [];\n const methodLower = method.name.toLowerCase();\n\n // Happy path scenarios\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Happy Path',\n description: `Test ${method.name} with valid data`,\n type: 'happy-path',\n priority: 'critical',\n testMethodName: `${method.name}_WhenValidData_ShouldSucceed`,\n assertions: generateAssertions(method, 'happy-path'),\n });\n\n // CRUD-specific scenarios\n if (methodLower.includes('getbyid') || methodLower.includes('get')) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Not Found',\n description: `Test ${method.name} when entity does not exist`,\n type: 'error-handling',\n priority: 'high',\n testMethodName: `${method.name}_WhenNotExists_ShouldReturnNull`,\n assertions: ['result.Should().BeNull()'],\n });\n }\n\n if (methodLower.includes('create') || methodLower.includes('add')) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Validation Failure',\n description: `Test ${method.name} with invalid data`,\n type: 'validation',\n priority: 'high',\n testMethodName: `${method.name}_WhenInvalidData_ShouldThrow`,\n assertions: ['act.Should().ThrowAsync<ValidationException>()'],\n });\n\n if (patterns.hasTenant) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Missing Tenant',\n description: `Test ${method.name} without tenant context`,\n type: 'security',\n priority: 'critical',\n testMethodName: `${method.name}_WhenNoTenant_ShouldThrow`,\n assertions: ['act.Should().ThrowAsync<ArgumentException>()'],\n });\n }\n }\n\n if (methodLower.includes('update')) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Not Found',\n description: `Test ${method.name} when entity does not exist`,\n type: 'error-handling',\n priority: 'high',\n testMethodName: `${method.name}_WhenNotExists_ShouldThrow`,\n assertions: ['act.Should().ThrowAsync<InvalidOperationException>()'],\n });\n\n if (depth !== 'basic') {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Concurrent Update',\n description: `Test ${method.name} with concurrent modification`,\n type: 'edge-case',\n priority: 'medium',\n testMethodName: `${method.name}_WhenConcurrentUpdate_ShouldHandleConflict`,\n assertions: ['Should handle DbUpdateConcurrencyException'],\n });\n }\n }\n\n if (methodLower.includes('delete')) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Not Found',\n description: `Test ${method.name} when entity does not exist`,\n type: 'error-handling',\n priority: 'high',\n testMethodName: `${method.name}_WhenNotExists_ShouldReturnFalse`,\n assertions: ['result.Should().BeFalse()'],\n });\n\n if (patterns.hasSoftDelete) {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Soft Delete',\n description: `Verify ${method.name} performs soft delete`,\n type: 'happy-path',\n priority: 'high',\n testMethodName: `${method.name}_WhenCalled_ShouldSoftDelete`,\n assertions: ['entity.IsDeleted.Should().BeTrue()', 'entity.DeletedAt.Should().NotBeNull()'],\n });\n }\n }\n\n // Async cancellation scenarios\n if (method.isAsync && depth !== 'basic') {\n scenarios.push({\n methodName: method.name,\n scenarioName: 'Cancellation',\n description: `Test ${method.name} with cancellation token`,\n type: 'edge-case',\n priority: 'low',\n testMethodName: `${method.name}_WhenCancelled_ShouldThrowOperationCancelled`,\n assertions: ['act.Should().ThrowAsync<OperationCanceledException>()'],\n });\n }\n\n return scenarios;\n}\n\nfunction generateEntityScenarios(\n content: string,\n hasTenant: boolean,\n hasSoftDelete: boolean,\n depth: string\n): TestScenario[] {\n const scenarios: TestScenario[] = [];\n\n // Factory method scenarios\n if (PATTERNS.factoryMethod.test(content)) {\n scenarios.push({\n methodName: 'Create',\n scenarioName: 'Factory Method',\n description: 'Test entity creation via factory method',\n type: 'happy-path',\n priority: 'critical',\n testMethodName: 'Create_WhenValidData_ShouldCreateEntity',\n assertions: [\n 'entity.Should().NotBeNull()',\n 'entity.Id.Should().NotBeEmpty()',\n 'entity.CreatedAt.Should().BeCloseTo(DateTime.UtcNow)',\n ],\n });\n\n if (hasTenant) {\n scenarios.push({\n methodName: 'Create',\n scenarioName: 'Invalid Tenant',\n description: 'Test entity creation with empty tenant ID',\n type: 'validation',\n priority: 'critical',\n testMethodName: 'Create_WhenEmptyTenantId_ShouldThrow',\n assertions: ['act.Should().Throw<ArgumentException>()'],\n });\n }\n }\n\n // Soft delete scenarios\n if (hasSoftDelete) {\n scenarios.push({\n methodName: 'SoftDelete',\n scenarioName: 'Soft Delete',\n description: 'Test soft delete sets IsDeleted and DeletedAt',\n type: 'happy-path',\n priority: 'high',\n testMethodName: 'SoftDelete_WhenCalled_ShouldSetDeletedFields',\n assertions: [\n 'entity.IsDeleted.Should().BeTrue()',\n 'entity.DeletedAt.Should().NotBeNull()',\n 'entity.DeletedBy.Should().Be(deletedBy)',\n ],\n });\n\n if (depth !== 'basic') {\n scenarios.push({\n methodName: 'Restore',\n scenarioName: 'Restore After Delete',\n description: 'Test restoring a soft-deleted entity',\n type: 'happy-path',\n priority: 'medium',\n testMethodName: 'Restore_WhenSoftDeleted_ShouldClearDeletedFields',\n assertions: [\n 'entity.IsDeleted.Should().BeFalse()',\n 'entity.DeletedAt.Should().BeNull()',\n ],\n });\n }\n }\n\n // Audit trail scenarios\n if (depth !== 'basic') {\n scenarios.push({\n methodName: 'Update',\n scenarioName: 'Audit Trail',\n description: 'Test that Update sets audit fields',\n type: 'happy-path',\n priority: 'medium',\n testMethodName: 'Update_WhenCalled_ShouldSetAuditFields',\n assertions: [\n 'entity.UpdatedAt.Should().NotBeNull()',\n 'entity.UpdatedBy.Should().Be(updatedBy)',\n 'entity.CreatedAt.Should().Be(originalCreatedAt)',\n ],\n });\n }\n\n return scenarios;\n}\n\nfunction generateSecurityScenarios(\n _methods: DetectedMethod[],\n hasTenant: boolean,\n _target: string\n): TestScenario[] {\n const scenarios: TestScenario[] = [];\n\n if (hasTenant) {\n scenarios.push({\n methodName: 'TenantIsolation',\n scenarioName: 'Cross-Tenant Access',\n description: 'Test that entities from other tenants are not accessible',\n type: 'security',\n priority: 'critical',\n testMethodName: 'GetById_WhenDifferentTenant_ShouldReturnNull',\n assertions: ['result.Should().BeNull()'],\n });\n }\n\n if (_target === 'controller') {\n scenarios.push({\n methodName: 'Authorization',\n scenarioName: 'Unauthorized Access',\n description: 'Test that unauthorized requests are rejected',\n type: 'security',\n priority: 'critical',\n testMethodName: 'GetAll_WhenUnauthorized_ShouldReturn401',\n assertions: ['response.StatusCode.Should().Be(HttpStatusCode.Unauthorized)'],\n });\n\n scenarios.push({\n methodName: 'InputValidation',\n scenarioName: 'SQL Injection',\n description: 'Test that SQL injection attempts are handled',\n type: 'security',\n priority: 'high',\n testMethodName: 'Create_WhenSqlInjectionAttempt_ShouldSanitize',\n assertions: ['Should not execute malicious SQL'],\n });\n\n scenarios.push({\n methodName: 'InputValidation',\n scenarioName: 'XSS Prevention',\n description: 'Test that XSS attempts are handled',\n type: 'security',\n priority: 'high',\n testMethodName: 'Create_WhenXssAttempt_ShouldSanitize',\n assertions: ['Should not store or return script tags'],\n });\n }\n\n return scenarios;\n}\n\nfunction generateAssertions(method: DetectedMethod, type: string): string[] {\n const assertions: string[] = [];\n\n if (type === 'happy-path') {\n if (method.returnType === 'void' || method.returnType === 'Task') {\n assertions.push('Should complete without exception');\n } else if (method.returnType.includes('bool') || method.returnType === 'Boolean') {\n assertions.push('result.Should().BeTrue()');\n } else {\n assertions.push('result.Should().NotBeNull()');\n }\n }\n\n return assertions;\n}\n\nfunction calculateCoverageDistribution(result: TestScenarioResult): void {\n const total = result.scenarios.length;\n if (total === 0) return;\n\n const counts = {\n happyPath: result.scenarios.filter(s => s.type === 'happy-path').length,\n validation: result.scenarios.filter(s => s.type === 'validation').length,\n errorHandling: result.scenarios.filter(s => s.type === 'error-handling').length,\n security: result.scenarios.filter(s => s.type === 'security').length,\n edgeCases: result.scenarios.filter(s => s.type === 'edge-case' || s.type === 'performance').length,\n };\n\n result.coverage = {\n happyPath: Math.round((counts.happyPath / total) * 100),\n validation: Math.round((counts.validation / total) * 100),\n errorHandling: Math.round((counts.errorHandling / total) * 100),\n security: Math.round((counts.security / total) * 100),\n edgeCases: Math.round((counts.edgeCases / total) * 100),\n };\n}\n\n// ============================================================================\n// Formatting\n// ============================================================================\n\nfunction formatScenariosResult(result: TestScenarioResult, depth: string): string {\n const lines: string[] = [];\n\n lines.push(`# Test Scenarios for ${result.target}`);\n lines.push('');\n lines.push(`> Analysis depth: **${depth}**`);\n lines.push('');\n\n // Detected methods\n if (result.detectedMethods.length > 0) {\n lines.push('## Detected Methods');\n lines.push('');\n lines.push('| Method | Return Type | Parameters | Async |');\n lines.push('|--------|-------------|------------|-------|');\n for (const method of result.detectedMethods) {\n const params = method.parameters.length > 0 ? method.parameters.join(', ') : 'none';\n lines.push(`| ${method.name} | ${method.returnType} | ${params} | ${method.isAsync ? 'Yes' : 'No'} |`);\n }\n lines.push('');\n }\n\n // Coverage distribution\n lines.push('## Scenario Coverage Distribution');\n lines.push('');\n lines.push('```');\n lines.push(`Happy Path: ${'█'.repeat(Math.floor(result.coverage.happyPath / 5))}${'░'.repeat(20 - Math.floor(result.coverage.happyPath / 5))} ${result.coverage.happyPath}%`);\n lines.push(`Validation: ${'█'.repeat(Math.floor(result.coverage.validation / 5))}${'░'.repeat(20 - Math.floor(result.coverage.validation / 5))} ${result.coverage.validation}%`);\n lines.push(`Error Handling: ${'█'.repeat(Math.floor(result.coverage.errorHandling / 5))}${'░'.repeat(20 - Math.floor(result.coverage.errorHandling / 5))} ${result.coverage.errorHandling}%`);\n lines.push(`Security: ${'█'.repeat(Math.floor(result.coverage.security / 5))}${'░'.repeat(20 - Math.floor(result.coverage.security / 5))} ${result.coverage.security}%`);\n lines.push(`Edge Cases: ${'█'.repeat(Math.floor(result.coverage.edgeCases / 5))}${'░'.repeat(20 - Math.floor(result.coverage.edgeCases / 5))} ${result.coverage.edgeCases}%`);\n lines.push('```');\n lines.push('');\n\n // Scenarios by priority\n lines.push('## Suggested Test Scenarios');\n lines.push('');\n\n const priorities: Array<'critical' | 'high' | 'medium' | 'low'> = ['critical', 'high', 'medium', 'low'];\n for (const priority of priorities) {\n const scenarios = result.scenarios.filter(s => s.priority === priority);\n if (scenarios.length === 0) continue;\n\n const emoji = priority === 'critical' ? '🔴' : priority === 'high' ? '🟠' : priority === 'medium' ? '🟡' : '🟢';\n lines.push(`### ${emoji} ${priority.charAt(0).toUpperCase() + priority.slice(1)} Priority`);\n lines.push('');\n\n for (const scenario of scenarios) {\n const typeEmoji = getTypeEmoji(scenario.type);\n lines.push(`#### ${typeEmoji} ${scenario.methodName} - ${scenario.scenarioName}`);\n lines.push('');\n lines.push(`**Description:** ${scenario.description}`);\n lines.push('');\n lines.push(`**Test Method:** \\`${scenario.testMethodName}\\``);\n lines.push('');\n if (scenario.assertions.length > 0) {\n lines.push('**Assertions:**');\n for (const assertion of scenario.assertions) {\n lines.push(`- \\`${assertion}\\``);\n }\n lines.push('');\n }\n }\n }\n\n // Quick generation command\n lines.push('## Quick Test Generation');\n lines.push('');\n lines.push('Generate tests for this component:');\n lines.push('');\n lines.push('```');\n lines.push(`scaffold_tests(target: \"${result.targetType}\", name: \"${result.target}\", testTypes: [\"unit\", \"security\"])`);\n lines.push('```');\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction getTypeEmoji(type: string): string {\n switch (type) {\n case 'happy-path': return '✅';\n case 'validation': return '🔍';\n case 'error-handling': return '⚠️';\n case 'security': return '🔒';\n case 'edge-case': return '🧪';\n case 'performance': return '⚡';\n default: return '📋';\n }\n}\n","/**\n * Scaffold API Client Tool\n *\n * Generates TypeScript API clients that integrate with SmartStack's NavRoute system.\n * Creates type-safe API services with automatic route resolution from NavRoute paths.\n */\n\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport path from 'path';\n\nimport { Config, ScaffoldApiClientInputSchema, ScaffoldApiClientInput, ScaffoldResult } from '../types/index.js';\nimport { logger } from '../lib/logger.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { ensureDirectory, writeText } from '../utils/fs.js';\n\nexport const scaffoldApiClientTool: Tool = {\n name: 'scaffold_api_client',\n description: `Generate TypeScript API client with NavRoute integration.\n\nCreates:\n- Type-safe API service with CRUD methods\n- TypeScript interfaces for request/response\n- React Query hook (optional)\n- Integration with navRoutes.generated.ts registry\n\nExample:\n scaffold_api_client navRoute=\"platform.administration.users\" name=\"User\"\n\nThe generated client automatically resolves the API path from the NavRoute registry,\nensuring frontend routes stay synchronized with backend NavRoute attributes.`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to SmartStack project root (defaults to configured project path)',\n },\n navRoute: {\n type: 'string',\n description: 'NavRoute path (e.g., \"platform.administration.users\")',\n },\n name: {\n type: 'string',\n description: 'Entity name in PascalCase (e.g., \"User\", \"Order\")',\n },\n methods: {\n type: 'array',\n items: {\n type: 'string',\n enum: ['getAll', 'getById', 'create', 'update', 'delete', 'search', 'export'],\n },\n default: ['getAll', 'getById', 'create', 'update', 'delete'],\n description: 'API methods to generate',\n },\n options: {\n type: 'object',\n properties: {\n outputPath: { type: 'string', description: 'Custom output path' },\n includeTypes: { type: 'boolean', default: true, description: 'Generate TypeScript types' },\n includeHook: { type: 'boolean', default: true, description: 'Generate React Query hook' },\n dryRun: { type: 'boolean', default: false, description: 'Preview without writing' },\n },\n },\n },\n required: ['navRoute', 'name'],\n },\n};\n\nexport async function handleScaffoldApiClient(\n args: Record<string, unknown>,\n config: Config\n): Promise<string> {\n const input = ScaffoldApiClientInputSchema.parse(args);\n logger.info('Scaffolding API client', { navRoute: input.navRoute, name: input.name });\n\n const result = await scaffoldApiClient(input, config);\n return formatResult(result, input);\n}\n\nasync function scaffoldApiClient(\n input: ScaffoldApiClientInput,\n config: Config\n): Promise<ScaffoldResult> {\n const result: ScaffoldResult = {\n success: true,\n files: [],\n instructions: [],\n };\n\n const { navRoute, name, methods, options } = input;\n const dryRun = options?.dryRun ?? false;\n const includeTypes = options?.includeTypes ?? true;\n const includeHook = options?.includeHook ?? true;\n\n const nameLower = name.charAt(0).toLowerCase() + name.slice(1);\n const apiPath = navRouteToApiPath(navRoute);\n\n // Use explicit path if provided, otherwise fall back to config\n const projectRoot = input.path || config.smartstack.projectPath;\n const structure = await findSmartStackStructure(projectRoot);\n // Fallback to 'web' folder (not hardcoded to smartstack-web)\n const webPath = structure.web || path.join(projectRoot, 'web');\n const servicesPath = options?.outputPath || path.join(webPath, 'src', 'services', 'api');\n const hooksPath = path.join(webPath, 'src', 'hooks');\n const typesPath = path.join(webPath, 'src', 'types');\n\n // Generate API client\n const apiClientContent = generateApiClient(name, nameLower, navRoute, apiPath, methods);\n const apiClientFile = path.join(servicesPath, `${nameLower}.ts`);\n\n if (!dryRun) {\n await ensureDirectory(servicesPath);\n await writeText(apiClientFile, apiClientContent);\n }\n result.files.push({ path: apiClientFile, content: apiClientContent, type: 'created' });\n\n // Generate TypeScript types\n if (includeTypes) {\n const typesContent = generateTypes(name);\n const typesFile = path.join(typesPath, `${nameLower}.ts`);\n\n if (!dryRun) {\n await ensureDirectory(typesPath);\n await writeText(typesFile, typesContent);\n }\n result.files.push({ path: typesFile, content: typesContent, type: 'created' });\n }\n\n // Generate React Query hook\n if (includeHook) {\n const hookContent = generateHook(name, nameLower, methods);\n const hookFile = path.join(hooksPath, `use${name}.ts`);\n\n if (!dryRun) {\n await ensureDirectory(hooksPath);\n await writeText(hookFile, hookContent);\n }\n result.files.push({ path: hookFile, content: hookContent, type: 'created' });\n }\n\n result.instructions.push(`Import the API client: import { ${nameLower}Api } from './services/api/${nameLower}';`);\n if (includeHook) {\n result.instructions.push(`Import the hook: import { use${name}, use${name}List } from './hooks/use${name}';`);\n }\n result.instructions.push(`Ensure navRoutes.generated.ts includes route: \"${navRoute}\"`);\n\n return result;\n}\n\nfunction navRouteToApiPath(navRoute: string): string {\n return `/api/${navRoute.replace(/\\./g, '/')}`;\n}\n\nfunction generateApiClient(\n name: string,\n nameLower: string,\n navRoute: string,\n apiPath: string,\n methods: string[]\n): string {\n const template = `/**\n * ${name} API Client\n *\n * Auto-generated by SmartStack MCP - DO NOT EDIT MANUALLY\n * NavRoute: ${navRoute}\n * API Path: ${apiPath}\n */\n\nimport { getRoute } from '../routes/navRoutes.generated';\nimport { apiClient } from '../lib/apiClient';\nimport type {\n ${name},\n ${name}CreateRequest,\n ${name}UpdateRequest,\n ${name}ListResponse,\n PaginatedRequest,\n PaginatedResponse\n} from '../types/${nameLower}';\n\nconst ROUTE = getRoute('${navRoute}');\n\nexport const ${nameLower}Api = {\n${methods.includes('getAll') ? ` /**\n * Get all ${name}s with pagination\n */\n async getAll(params?: PaginatedRequest): Promise<PaginatedResponse<${name}>> {\n const response = await apiClient.get<${name}ListResponse>(ROUTE.api, { params });\n return response.data;\n },\n` : ''}\n${methods.includes('getById') ? ` /**\n * Get ${name} by ID\n */\n async getById(id: string): Promise<${name}> {\n const response = await apiClient.get<${name}>(\\`\\${ROUTE.api}/\\${id}\\`);\n return response.data;\n },\n` : ''}\n${methods.includes('create') ? ` /**\n * Create new ${name}\n */\n async create(data: ${name}CreateRequest): Promise<${name}> {\n const response = await apiClient.post<${name}>(ROUTE.api, data);\n return response.data;\n },\n` : ''}\n${methods.includes('update') ? ` /**\n * Update existing ${name}\n */\n async update(id: string, data: ${name}UpdateRequest): Promise<${name}> {\n const response = await apiClient.put<${name}>(\\`\\${ROUTE.api}/\\${id}\\`, data);\n return response.data;\n },\n` : ''}\n${methods.includes('delete') ? ` /**\n * Delete ${name}\n */\n async delete(id: string): Promise<void> {\n await apiClient.delete(\\`\\${ROUTE.api}/\\${id}\\`);\n },\n` : ''}\n${methods.includes('search') ? ` /**\n * Search ${name}s\n */\n async search(query: string, params?: PaginatedRequest): Promise<PaginatedResponse<${name}>> {\n const response = await apiClient.get<${name}ListResponse>(\\`\\${ROUTE.api}/search\\`, {\n params: { q: query, ...params }\n });\n return response.data;\n },\n` : ''}\n${methods.includes('export') ? ` /**\n * Export ${name}s to file\n */\n async export(format: 'csv' | 'xlsx' | 'pdf' = 'xlsx'): Promise<Blob> {\n const response = await apiClient.get(\\`\\${ROUTE.api}/export\\`, {\n params: { format },\n responseType: 'blob'\n });\n return response.data;\n },\n` : ''}\n /**\n * Get the NavRoute for this API\n */\n getRoute() {\n return ROUTE;\n },\n};\n\nexport default ${nameLower}Api;\n`;\n\n return template;\n}\n\nfunction generateTypes(name: string): string {\n return `/**\n * ${name} Types\n *\n * Auto-generated by SmartStack MCP - Customize as needed\n */\n\nexport interface ${name} {\n id: string;\n code: string;\n name?: string;\n description?: string;\n isActive: boolean;\n createdAt: string;\n createdBy: string;\n updatedAt?: string;\n updatedBy?: string;\n}\n\nexport interface ${name}CreateRequest {\n code: string;\n name?: string;\n description?: string;\n}\n\nexport interface ${name}UpdateRequest {\n code?: string;\n name?: string;\n description?: string;\n isActive?: boolean;\n}\n\nexport interface ${name}ListResponse {\n items: ${name}[];\n totalCount: number;\n pageSize: number;\n currentPage: number;\n totalPages: number;\n}\n\nexport interface PaginatedRequest {\n page?: number;\n pageSize?: number;\n sortBy?: string;\n sortDirection?: 'asc' | 'desc';\n filter?: string;\n}\n\nexport interface PaginatedResponse<T> {\n items: T[];\n totalCount: number;\n pageSize: number;\n currentPage: number;\n totalPages: number;\n}\n`;\n}\n\nfunction generateHook(name: string, nameLower: string, methods: string[]): string {\n return `/**\n * ${name} React Query Hooks\n *\n * Auto-generated by SmartStack MCP - DO NOT EDIT MANUALLY\n */\n\nimport { useQuery, useMutation, useQueryClient, UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';\nimport { ${nameLower}Api } from '../services/api/${nameLower}';\nimport type { ${name}, ${name}CreateRequest, ${name}UpdateRequest, PaginatedRequest, PaginatedResponse } from '../types/${nameLower}';\n\nconst QUERY_KEY = '${nameLower}s';\n\n${methods.includes('getAll') ? `/**\n * Hook to fetch paginated ${name} list\n */\nexport function use${name}List(\n params?: PaginatedRequest,\n options?: Omit<UseQueryOptions<PaginatedResponse<${name}>>, 'queryKey' | 'queryFn'>\n) {\n return useQuery({\n queryKey: [QUERY_KEY, 'list', params],\n queryFn: () => ${nameLower}Api.getAll(params),\n ...options,\n });\n}\n` : ''}\n${methods.includes('getById') ? `/**\n * Hook to fetch single ${name} by ID\n */\nexport function use${name}(\n id: string | undefined,\n options?: Omit<UseQueryOptions<${name}>, 'queryKey' | 'queryFn'>\n) {\n return useQuery({\n queryKey: [QUERY_KEY, 'detail', id],\n queryFn: () => ${nameLower}Api.getById(id!),\n enabled: !!id,\n ...options,\n });\n}\n` : ''}\n${methods.includes('create') ? `/**\n * Hook to create new ${name}\n */\nexport function use${name}Create(\n options?: UseMutationOptions<${name}, Error, ${name}CreateRequest>\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (data: ${name}CreateRequest) => ${nameLower}Api.create(data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });\n },\n ...options,\n });\n}\n` : ''}\n${methods.includes('update') ? `/**\n * Hook to update existing ${name}\n */\nexport function use${name}Update(\n options?: UseMutationOptions<${name}, Error, { id: string; data: ${name}UpdateRequest }>\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: ({ id, data }) => ${nameLower}Api.update(id, data),\n onSuccess: (_, { id }) => {\n queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });\n queryClient.invalidateQueries({ queryKey: [QUERY_KEY, 'detail', id] });\n },\n ...options,\n });\n}\n` : ''}\n${methods.includes('delete') ? `/**\n * Hook to delete ${name}\n */\nexport function use${name}Delete(\n options?: UseMutationOptions<void, Error, string>\n) {\n const queryClient = useQueryClient();\n\n return useMutation({\n mutationFn: (id: string) => ${nameLower}Api.delete(id),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [QUERY_KEY] });\n },\n ...options,\n });\n}\n` : ''}\n${methods.includes('search') ? `/**\n * Hook to search ${name}s\n */\nexport function use${name}Search(\n query: string,\n params?: PaginatedRequest,\n options?: Omit<UseQueryOptions<PaginatedResponse<${name}>>, 'queryKey' | 'queryFn'>\n) {\n return useQuery({\n queryKey: [QUERY_KEY, 'search', query, params],\n queryFn: () => ${nameLower}Api.search(query, params),\n enabled: query.length >= 2,\n ...options,\n });\n}\n` : ''}\n`;\n}\n\nfunction formatResult(result: ScaffoldResult, input: ScaffoldApiClientInput): string {\n const lines: string[] = [];\n\n lines.push(`# Scaffold API Client: ${input.name}`);\n lines.push('');\n\n if (input.options?.dryRun) {\n lines.push('> **DRY RUN** - No files were written');\n lines.push('');\n }\n\n lines.push(`## NavRoute Integration`);\n lines.push('');\n lines.push(`- **NavRoute**: \\`${input.navRoute}\\``);\n lines.push(`- **API Path**: \\`${navRouteToApiPath(input.navRoute)}\\``);\n lines.push(`- **Methods**: ${input.methods.join(', ')}`);\n lines.push('');\n\n lines.push('## Generated Files');\n lines.push('');\n\n for (const file of result.files) {\n const relativePath = file.path.replace(/\\\\/g, '/').split('/src/').pop() || file.path;\n lines.push(`### ${relativePath}`);\n lines.push('');\n lines.push('```typescript');\n lines.push(file.content.substring(0, 1500) + (file.content.length > 1500 ? '\\n// ... (truncated)' : ''));\n lines.push('```');\n lines.push('');\n }\n\n lines.push('## Next Steps');\n lines.push('');\n for (const instruction of result.instructions) {\n lines.push(`- ${instruction}`);\n }\n lines.push('');\n lines.push('## Required Setup');\n lines.push('');\n lines.push('1. Ensure `navRoutes.generated.ts` exists (run `scaffold_routes`)');\n lines.push('2. Configure `apiClient` with base URL and auth interceptors');\n lines.push('3. Install dependencies: `npm install @tanstack/react-query axios`');\n\n return lines.join('\\n');\n}\n","/**\n * Scaffold Routes Tool\n *\n * Generates React Router configuration and NavRoute registry from backend controllers.\n * Scans C# controllers for NavRoute attributes and creates synchronized frontend routes.\n */\n\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport path from 'path';\n\nimport { Config, ScaffoldRoutesInputSchema, ScaffoldRoutesInput, ScaffoldResult, NavRouteEntry } from '../types/index.js';\nimport { logger } from '../lib/logger.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { ensureDirectory, writeText, readText } from '../utils/fs.js';\nimport { glob } from 'glob';\n\nexport const scaffoldRoutesTool: Tool = {\n name: 'scaffold_routes',\n description: `Generate React Router configuration from backend NavRoute attributes.\n\nCreates:\n- navRoutes.generated.ts: Registry of all routes with API paths and permissions\n- routes.tsx: React Router configuration with nested routes\n- Layout components (optional)\n\nExample:\n scaffold_routes source=\"controllers\" scope=\"all\"\n\nScans backend controllers for [NavRoute(\"context.application.module\")] attributes\nand generates corresponding frontend routing infrastructure.`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to SmartStack project root (defaults to configured project path)',\n },\n source: {\n type: 'string',\n enum: ['controllers', 'navigation', 'manual'],\n default: 'controllers',\n description: 'Source for route discovery',\n },\n scope: {\n type: 'string',\n enum: ['all', 'platform', 'business', 'extensions'],\n default: 'all',\n description: 'Scope of routes to generate',\n },\n options: {\n type: 'object',\n properties: {\n outputPath: { type: 'string', description: 'Custom output path' },\n includeLayouts: { type: 'boolean', default: true },\n includeGuards: { type: 'boolean', default: true },\n generateRegistry: { type: 'boolean', default: true },\n dryRun: { type: 'boolean', default: false },\n },\n },\n },\n },\n};\n\nexport async function handleScaffoldRoutes(\n args: Record<string, unknown>,\n config: Config\n): Promise<string> {\n const input = ScaffoldRoutesInputSchema.parse(args);\n logger.info('Scaffolding routes', { source: input.source, scope: input.scope });\n\n const result = await scaffoldRoutes(input, config);\n return formatResult(result, input);\n}\n\nasync function scaffoldRoutes(\n input: ScaffoldRoutesInput,\n config: Config\n): Promise<ScaffoldResult> {\n const result: ScaffoldResult = {\n success: true,\n files: [],\n instructions: [],\n };\n\n const { source, scope, options } = input;\n const dryRun = options?.dryRun ?? false;\n const includeLayouts = options?.includeLayouts ?? true;\n const includeGuards = options?.includeGuards ?? true;\n const generateRegistry = options?.generateRegistry ?? true;\n\n // Use explicit path if provided, otherwise fall back to config\n const projectRoot = input.path || config.smartstack.projectPath;\n const structure = await findSmartStackStructure(projectRoot);\n // Fallback to 'web' folder (not hardcoded to smartstack-web)\n const webPath = structure.web || path.join(projectRoot, 'web');\n const routesPath = options?.outputPath || path.join(webPath, 'src', 'routes');\n\n // Discover NavRoutes from backend controllers\n const navRoutes = await discoverNavRoutes(structure, scope);\n\n if (navRoutes.length === 0) {\n result.success = false;\n result.instructions.push('No NavRoute attributes found in controllers');\n return result;\n }\n\n // Generate NavRoute registry\n if (generateRegistry) {\n const registryContent = generateNavRouteRegistry(navRoutes);\n const registryFile = path.join(routesPath, 'navRoutes.generated.ts');\n\n if (!dryRun) {\n await ensureDirectory(routesPath);\n await writeText(registryFile, registryContent);\n }\n result.files.push({ path: registryFile, content: registryContent, type: 'created' });\n }\n\n // Generate React Router configuration\n const routerContent = generateRouterConfig(navRoutes, includeGuards);\n const routerFile = path.join(routesPath, 'index.tsx');\n\n if (!dryRun) {\n await ensureDirectory(routesPath);\n await writeText(routerFile, routerContent);\n }\n result.files.push({ path: routerFile, content: routerContent, type: 'created' });\n\n // Generate layouts if requested\n if (includeLayouts) {\n const layoutsPath = path.join(webPath, 'src', 'layouts');\n const contexts = [...new Set(navRoutes.map(r => r.navRoute.split('.')[0]))];\n\n for (const context of contexts) {\n const layoutContent = generateLayout(context);\n const layoutFile = path.join(layoutsPath, `${capitalize(context)}Layout.tsx`);\n\n if (!dryRun) {\n await ensureDirectory(layoutsPath);\n await writeText(layoutFile, layoutContent);\n }\n result.files.push({ path: layoutFile, content: layoutContent, type: 'created' });\n }\n }\n\n // Generate route guards if requested\n if (includeGuards) {\n const guardsContent = generateRouteGuards();\n const guardsFile = path.join(routesPath, 'guards.tsx');\n\n if (!dryRun) {\n await writeText(guardsFile, guardsContent);\n }\n result.files.push({ path: guardsFile, content: guardsContent, type: 'created' });\n }\n\n result.instructions.push(`Generated ${navRoutes.length} routes from ${source}`);\n result.instructions.push('Import routes: import { router } from \"./routes\";');\n result.instructions.push('Use with RouterProvider: <RouterProvider router={router} />');\n\n return result;\n}\n\nasync function discoverNavRoutes(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n scope: string\n): Promise<NavRouteEntry[]> {\n const routes: NavRouteEntry[] = [];\n\n // Determine which API paths to scan based on scope\n const apiPaths: string[] = [];\n\n if (scope === 'all' || scope === 'platform') {\n // Scan core API (platform/admin controllers)\n if (structure.apiCore) {\n apiPaths.push(structure.apiCore);\n } else if (structure.api && scope === 'platform') {\n apiPaths.push(structure.api);\n }\n }\n\n if (scope === 'all' || scope === 'extensions' || scope === 'business') {\n // Scan extensions API (business/client-specific controllers)\n if (structure.apiExtensions) {\n apiPaths.push(structure.apiExtensions);\n }\n }\n\n // Fallback: if no specific paths found, use primary api\n if (apiPaths.length === 0 && structure.api) {\n apiPaths.push(structure.api);\n }\n\n if (apiPaths.length === 0) {\n logger.warn('No API project found');\n return routes;\n }\n\n logger.debug('Scanning API paths', { paths: apiPaths, scope });\n\n // Find all controller files from all API paths\n let controllerFiles: string[] = [];\n for (const apiPath of apiPaths) {\n const files = await glob('**/*Controller.cs', {\n cwd: apiPath,\n absolute: true,\n ignore: ['**/obj/**', '**/bin/**'],\n });\n controllerFiles = controllerFiles.concat(files);\n }\n\n for (const file of controllerFiles) {\n try {\n const content = await readText(file);\n const navRouteMatch = content.match(/\\[NavRoute\\s*\\(\\s*\"([^\"]+)\"(?:\\s*,\\s*Suffix\\s*=\\s*\"([^\"]+)\")?\\s*\\)\\]/);\n\n if (navRouteMatch) {\n const navRoute = navRouteMatch[1];\n const suffix = navRouteMatch[2];\n\n // Filter by scope\n const context = navRoute.split('.')[0];\n if (scope !== 'all' && context !== scope) {\n continue;\n }\n\n // Extract controller name\n const controllerMatch = path.basename(file).match(/(.+)Controller\\.cs$/);\n const controllerName = controllerMatch ? controllerMatch[1] : 'Unknown';\n\n // Extract HTTP methods\n const methods: string[] = [];\n if (content.includes('[HttpGet]')) methods.push('GET');\n if (content.includes('[HttpPost]')) methods.push('POST');\n if (content.includes('[HttpPut]')) methods.push('PUT');\n if (content.includes('[HttpDelete]')) methods.push('DELETE');\n if (content.includes('[HttpPatch]')) methods.push('PATCH');\n\n // Extract permissions (if any)\n const permissions: string[] = [];\n const authorizeMatches = content.matchAll(/\\[Authorize\\s*\\(\\s*[^)]*Policy\\s*=\\s*\"([^\"]+)\"/g);\n for (const match of authorizeMatches) {\n permissions.push(match[1]);\n }\n\n const fullNavRoute = suffix ? `${navRoute}.${suffix}` : navRoute;\n\n routes.push({\n navRoute: fullNavRoute,\n apiPath: `/api/${navRoute.replace(/\\./g, '/')}${suffix ? `/${suffix}` : ''}`,\n webPath: `/${navRoute.replace(/\\./g, '/')}${suffix ? `/${suffix}` : ''}`,\n permissions,\n controller: controllerName,\n methods,\n });\n }\n } catch {\n logger.debug(`Failed to parse controller: ${file}`);\n }\n }\n\n // Sort by navRoute for consistent output\n return routes.sort((a, b) => a.navRoute.localeCompare(b.navRoute));\n}\n\nfunction generateNavRouteRegistry(routes: NavRouteEntry[]): string {\n const lines: string[] = [\n '/**',\n ' * NavRoute Registry',\n ' *',\n ' * Auto-generated by SmartStack MCP - DO NOT EDIT MANUALLY',\n ' * Run `scaffold_routes` to regenerate',\n ' */',\n '',\n 'export interface NavRoute {',\n ' navRoute: string;',\n ' api: string;',\n ' web: string;',\n ' permissions: string[];',\n ' controller?: string;',\n ' methods: string[];',\n '}',\n '',\n 'export const ROUTES: Record<string, NavRoute> = {',\n ];\n\n for (const route of routes) {\n lines.push(` '${route.navRoute}': {`);\n lines.push(` navRoute: '${route.navRoute}',`);\n lines.push(` api: '${route.apiPath}',`);\n lines.push(` web: '${route.webPath}',`);\n lines.push(` permissions: [${route.permissions.map(p => `'${p}'`).join(', ')}],`);\n if (route.controller) {\n lines.push(` controller: '${route.controller}',`);\n }\n lines.push(` methods: [${route.methods.map(m => `'${m}'`).join(', ')}],`);\n lines.push(' },');\n }\n\n lines.push('};');\n lines.push('');\n lines.push('/**');\n lines.push(' * Get route configuration by NavRoute path');\n lines.push(' */');\n lines.push('export function getRoute(navRoute: string): NavRoute {');\n lines.push(' const route = ROUTES[navRoute];');\n lines.push(' if (!route) {');\n lines.push(' throw new Error(`Route not found: ${navRoute}`);');\n lines.push(' }');\n lines.push(' return route;');\n lines.push('}');\n lines.push('');\n lines.push('/**');\n lines.push(' * Check if user has permission for route');\n lines.push(' */');\n lines.push('export function hasRoutePermission(navRoute: string, userPermissions: string[]): boolean {');\n lines.push(' const route = ROUTES[navRoute];');\n lines.push(' if (!route || route.permissions.length === 0) return true;');\n lines.push(' return route.permissions.some(p => userPermissions.includes(p));');\n lines.push('}');\n lines.push('');\n lines.push('/**');\n lines.push(' * Get all routes for a context');\n lines.push(' */');\n lines.push('export function getRoutesByContext(context: string): NavRoute[] {');\n lines.push(' return Object.values(ROUTES).filter(r => r.navRoute.startsWith(`${context}.`));');\n lines.push('}');\n lines.push('');\n lines.push('/**');\n lines.push(' * Get web route with optional tenant slug prefix');\n lines.push(' *');\n lines.push(' * @param navRoute - NavRoute path (e.g., \\'platform.administration.users\\')');\n lines.push(' * @param options - Configuration for URL building');\n lines.push(' * @returns Web route path, optionally prefixed with /t/{slug}');\n lines.push(' *');\n lines.push(' * @example');\n lines.push(' * // Single-tenant mode or no tenant');\n lines.push(' * getWebRoute(\\'platform.administration.users\\', { isSingleTenant: true })');\n lines.push(' * // Returns: \\'/platform/administration/users\\'');\n lines.push(' *');\n lines.push(' * @example');\n lines.push(' * // Multi-tenant mode with slug');\n lines.push(' * getWebRoute(\\'platform.administration.users\\', { slug: \\'acme\\', isSingleTenant: false })');\n lines.push(' * // Returns: \\'/t/acme/platform/administration/users\\'');\n lines.push(' */');\n lines.push('export function getWebRoute(');\n lines.push(' navRoute: string,');\n lines.push(' options: {');\n lines.push(' slug?: string | null;');\n lines.push(' isSingleTenant: boolean;');\n lines.push(' isAdminMode?: boolean;');\n lines.push(' } = { isSingleTenant: true }');\n lines.push('): string {');\n lines.push(' const route = ROUTES[navRoute];');\n lines.push(' if (!route) {');\n lines.push(' throw new Error(`Route not found: ${navRoute}`);');\n lines.push(' }');\n lines.push('');\n lines.push(' const webPath = route.web;');\n lines.push('');\n lines.push(' // No prefix needed in single-tenant mode, admin mode, or without slug');\n lines.push(' if (options.isSingleTenant || options.isAdminMode || !options.slug) {');\n lines.push(' return webPath;');\n lines.push(' }');\n lines.push('');\n lines.push(' // Add tenant slug prefix');\n lines.push(' return `/t/${options.slug}${webPath}`;');\n lines.push('}');\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction generateRouterConfig(routes: NavRouteEntry[], includeGuards: boolean): string {\n // Group routes by context and application\n const routeTree = buildRouteTree(routes);\n\n const lines: string[] = [\n '/**',\n ' * React Router Configuration',\n ' *',\n ' * Auto-generated by SmartStack MCP - DO NOT EDIT MANUALLY',\n ' */',\n '',\n \"import { createBrowserRouter, RouteObject } from 'react-router-dom';\",\n \"import { ROUTES } from './navRoutes.generated';\",\n ];\n\n if (includeGuards) {\n lines.push(\"import { ProtectedRoute, PermissionGuard } from './guards';\");\n }\n\n // Import layouts\n const contexts = Object.keys(routeTree);\n for (const context of contexts) {\n lines.push(`import { ${capitalize(context)}Layout } from '../layouts/${capitalize(context)}Layout';`);\n }\n\n lines.push('');\n lines.push('// Page imports - customize these paths');\n\n // Generate page imports (as placeholders)\n for (const route of routes) {\n const pageName = route.navRoute.split('.').map(capitalize).join('');\n lines.push(`// import { ${pageName}Page } from '../pages/${pageName}Page';`);\n }\n\n lines.push('');\n lines.push('const routes: RouteObject[] = [');\n\n // Generate route configuration\n for (const [context, applications] of Object.entries(routeTree)) {\n lines.push(' {');\n lines.push(` path: '${context}',`);\n lines.push(` element: <${capitalize(context)}Layout />,`);\n lines.push(' children: [');\n\n for (const [app, modules] of Object.entries(applications as Record<string, NavRouteEntry[]>)) {\n lines.push(' {');\n lines.push(` path: '${app}',`);\n lines.push(' children: [');\n\n for (const route of modules) {\n const modulePath = route.navRoute.split('.').slice(2).join('/');\n const pageName = route.navRoute.split('.').map(capitalize).join('');\n\n if (includeGuards && route.permissions.length > 0) {\n lines.push(' {');\n lines.push(` path: '${modulePath || ''}',`);\n lines.push(` element: (`);\n lines.push(` <PermissionGuard permissions={ROUTES['${route.navRoute}'].permissions}>`);\n lines.push(` {/* <${pageName}Page /> */}`);\n lines.push(` <div>TODO: ${pageName}Page</div>`);\n lines.push(` </PermissionGuard>`);\n lines.push(` ),`);\n lines.push(' },');\n } else {\n lines.push(' {');\n lines.push(` path: '${modulePath || ''}',`);\n lines.push(` element: <div>TODO: ${pageName}Page</div>,`);\n lines.push(' },');\n }\n }\n\n lines.push(' ],');\n lines.push(' },');\n }\n\n lines.push(' ],');\n lines.push(' },');\n }\n\n lines.push('];');\n lines.push('');\n lines.push('export const router = createBrowserRouter(routes);');\n lines.push('');\n lines.push('export default router;');\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction buildRouteTree(routes: NavRouteEntry[]): Record<string, Record<string, NavRouteEntry[]>> {\n const tree: Record<string, Record<string, NavRouteEntry[]>> = {};\n\n for (const route of routes) {\n const parts = route.navRoute.split('.');\n const context = parts[0];\n const app = parts[1] || 'default';\n\n if (!tree[context]) {\n tree[context] = {};\n }\n if (!tree[context][app]) {\n tree[context][app] = [];\n }\n tree[context][app].push(route);\n }\n\n return tree;\n}\n\nfunction generateLayout(context: string): string {\n const contextCapitalized = capitalize(context);\n\n return `/**\n * ${contextCapitalized} Layout\n *\n * Auto-generated by SmartStack MCP - Customize as needed\n */\n\nimport React from 'react';\nimport { Outlet, Link, useLocation } from 'react-router-dom';\nimport { ROUTES, getRoutesByContext } from '../routes/navRoutes.generated';\n\nexport const ${contextCapitalized}Layout: React.FC = () => {\n const location = useLocation();\n const contextRoutes = getRoutesByContext('${context}');\n\n return (\n <div className=\"flex h-screen bg-gray-100\">\n {/* Sidebar */}\n <aside className=\"w-64 bg-white shadow-sm\">\n <div className=\"p-4 border-b\">\n <h1 className=\"text-xl font-semibold text-gray-900\">${contextCapitalized}</h1>\n </div>\n <nav className=\"p-4\">\n <ul className=\"space-y-2\">\n {contextRoutes.map((route) => (\n <li key={route.navRoute}>\n <Link\n to={route.web}\n className={\\`block px-3 py-2 rounded-md \\${\n location.pathname === route.web\n ? 'bg-blue-50 text-blue-700'\n : 'text-gray-700 hover:bg-gray-50'\n }\\`}\n >\n {route.navRoute.split('.').pop()}\n </Link>\n </li>\n ))}\n </ul>\n </nav>\n </aside>\n\n {/* Main content */}\n <main className=\"flex-1 overflow-auto\">\n <div className=\"p-6\">\n <Outlet />\n </div>\n </main>\n </div>\n );\n};\n\nexport default ${contextCapitalized}Layout;\n`;\n}\n\nfunction generateRouteGuards(): string {\n return `/**\n * Route Guards\n *\n * Auto-generated by SmartStack MCP - Customize as needed\n */\n\nimport React from 'react';\nimport { Navigate, useLocation } from 'react-router-dom';\n\ninterface ProtectedRouteProps {\n children: React.ReactNode;\n redirectTo?: string;\n}\n\ninterface PermissionGuardProps {\n children: React.ReactNode;\n permissions: string[];\n fallback?: React.ReactNode;\n}\n\n/**\n * Protect routes that require authentication\n */\nexport const ProtectedRoute: React.FC<ProtectedRouteProps> = ({\n children,\n redirectTo = '/login'\n}) => {\n const location = useLocation();\n\n // TODO: Replace with your auth hook\n const isAuthenticated = true; // useAuth().isAuthenticated;\n\n if (!isAuthenticated) {\n return <Navigate to={redirectTo} state={{ from: location }} replace />;\n }\n\n return <>{children}</>;\n};\n\n/**\n * Guard routes based on user permissions\n */\nexport const PermissionGuard: React.FC<PermissionGuardProps> = ({\n children,\n permissions,\n fallback\n}) => {\n // TODO: Replace with your auth hook\n const userPermissions: string[] = []; // useAuth().permissions;\n\n const hasPermission = permissions.length === 0 ||\n permissions.some(p => userPermissions.includes(p));\n\n if (!hasPermission) {\n if (fallback) return <>{fallback}</>;\n return (\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"text-center\">\n <h2 className=\"text-xl font-semibold text-gray-900\">Access Denied</h2>\n <p className=\"mt-2 text-gray-600\">\n You don't have permission to access this page.\n </p>\n <p className=\"mt-1 text-sm text-gray-500\">\n Required: {permissions.join(', ')}\n </p>\n </div>\n </div>\n );\n }\n\n return <>{children}</>;\n};\n`;\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction formatResult(result: ScaffoldResult, input: ScaffoldRoutesInput): string {\n const lines: string[] = [];\n\n lines.push('# Scaffold Routes');\n lines.push('');\n\n if (input.options?.dryRun) {\n lines.push('> **DRY RUN** - No files were written');\n lines.push('');\n }\n\n lines.push('## Configuration');\n lines.push('');\n lines.push(`- **Source**: ${input.source}`);\n lines.push(`- **Scope**: ${input.scope}`);\n lines.push('');\n\n lines.push('## Generated Files');\n lines.push('');\n\n for (const file of result.files) {\n const relativePath = file.path.replace(/\\\\/g, '/').split('/src/').pop() || file.path;\n lines.push(`### ${relativePath}`);\n lines.push('');\n lines.push('```tsx');\n lines.push(file.content.substring(0, 2000) + (file.content.length > 2000 ? '\\n// ... (truncated)' : ''));\n lines.push('```');\n lines.push('');\n }\n\n lines.push('## Instructions');\n lines.push('');\n for (const instruction of result.instructions) {\n lines.push(`- ${instruction}`);\n }\n\n return lines.join('\\n');\n}\n","/**\n * Validate Frontend Routes Tool\n *\n * Validates synchronization between backend NavRoute attributes and frontend routing.\n * Checks for orphaned clients, missing routes, and permission mismatches.\n */\n\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport path from 'path';\n\nimport {\n Config,\n ValidateFrontendRoutesInputSchema,\n ValidateFrontendRoutesInput,\n FrontendRouteValidationResult,\n NavRouteEntry\n} from '../types/index.js';\nimport { logger } from '../lib/logger.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { readText, fileExists } from '../utils/fs.js';\nimport { glob } from 'glob';\n\nexport const validateFrontendRoutesTool: Tool = {\n name: 'validate_frontend_routes',\n description: `Validate frontend routes against backend NavRoute attributes.\n\nChecks:\n- navRoutes.generated.ts exists and is up-to-date\n- API clients use correct NavRoute paths\n- React Router configuration matches backend routes\n- Permission configurations are synchronized\n\nExample:\n validate_frontend_routes scope=\"all\"\n\nReports issues and provides actionable recommendations for synchronization.`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to SmartStack project root (defaults to configured project path)',\n },\n scope: {\n type: 'string',\n enum: ['api-clients', 'routes', 'registry', 'all'],\n default: 'all',\n description: 'Scope of validation',\n },\n options: {\n type: 'object',\n properties: {\n fix: { type: 'boolean', default: false, description: 'Auto-fix minor issues' },\n strict: { type: 'boolean', default: false, description: 'Fail on warnings' },\n },\n },\n },\n },\n};\n\nexport async function handleValidateFrontendRoutes(\n args: Record<string, unknown>,\n config: Config\n): Promise<string> {\n const input = ValidateFrontendRoutesInputSchema.parse(args);\n logger.info('Validating frontend routes', { scope: input.scope });\n\n const result = await validateFrontendRoutes(input, config);\n return formatResult(result, input);\n}\n\nasync function validateFrontendRoutes(\n input: ValidateFrontendRoutesInput,\n config: Config\n): Promise<FrontendRouteValidationResult> {\n const result: FrontendRouteValidationResult = {\n valid: true,\n registry: {\n exists: false,\n routeCount: 0,\n outdated: [],\n },\n apiClients: {\n total: 0,\n valid: 0,\n issues: [],\n },\n routes: {\n total: 0,\n orphaned: [],\n missing: [],\n },\n recommendations: [],\n };\n\n const { scope } = input;\n // Use explicit path if provided, otherwise fall back to config\n const projectRoot = input.path || config.smartstack.projectPath;\n const structure = await findSmartStackStructure(projectRoot);\n // Fallback to 'web' folder (not hardcoded to smartstack-web)\n const webPath = structure.web || path.join(projectRoot, 'web');\n\n // Discover backend NavRoutes\n const backendRoutes = await discoverBackendNavRoutes(structure);\n\n // Validate registry\n if (scope === 'all' || scope === 'registry') {\n await validateRegistry(webPath, backendRoutes, result);\n }\n\n // Validate API clients\n if (scope === 'all' || scope === 'api-clients') {\n await validateApiClients(webPath, backendRoutes, result);\n }\n\n // Validate React Router configuration\n if (scope === 'all' || scope === 'routes') {\n await validateRoutes(webPath, backendRoutes, result);\n }\n\n // Generate recommendations\n generateRecommendations(result);\n\n // Determine overall validity\n result.valid = result.apiClients.issues.filter(i => i.severity === 'error').length === 0 &&\n result.routes.missing.length === 0 &&\n result.registry.exists;\n\n return result;\n}\n\nasync function discoverBackendNavRoutes(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>\n): Promise<NavRouteEntry[]> {\n const routes: NavRouteEntry[] = [];\n const apiPath = structure.api;\n\n if (!apiPath) {\n return routes;\n }\n\n const controllerFiles = await glob('**/*Controller.cs', {\n cwd: apiPath,\n absolute: true,\n ignore: ['**/obj/**', '**/bin/**'],\n });\n\n for (const file of controllerFiles) {\n try {\n const content = await readText(file);\n const navRouteMatch = content.match(/\\[NavRoute\\s*\\(\\s*\"([^\"]+)\"(?:\\s*,\\s*Suffix\\s*=\\s*\"([^\"]+)\")?\\s*\\)\\]/);\n\n if (navRouteMatch) {\n const navRoute = navRouteMatch[1];\n const suffix = navRouteMatch[2];\n const fullNavRoute = suffix ? `${navRoute}.${suffix}` : navRoute;\n\n const controllerMatch = path.basename(file).match(/(.+)Controller\\.cs$/);\n const controllerName = controllerMatch ? controllerMatch[1] : 'Unknown';\n\n const methods: string[] = [];\n if (content.includes('[HttpGet]')) methods.push('GET');\n if (content.includes('[HttpPost]')) methods.push('POST');\n if (content.includes('[HttpPut]')) methods.push('PUT');\n if (content.includes('[HttpDelete]')) methods.push('DELETE');\n\n const permissions: string[] = [];\n const authorizeMatches = content.matchAll(/\\[Authorize\\s*\\(\\s*[^)]*Policy\\s*=\\s*\"([^\"]+)\"/g);\n for (const match of authorizeMatches) {\n permissions.push(match[1]);\n }\n\n routes.push({\n navRoute: fullNavRoute,\n apiPath: `/api/${navRoute.replace(/\\./g, '/')}${suffix ? `/${suffix}` : ''}`,\n webPath: `/${navRoute.replace(/\\./g, '/')}${suffix ? `/${suffix}` : ''}`,\n permissions,\n controller: controllerName,\n methods,\n });\n }\n } catch {\n logger.debug(`Failed to parse controller: ${file}`);\n }\n }\n\n return routes;\n}\n\nasync function validateRegistry(\n webPath: string,\n backendRoutes: NavRouteEntry[],\n result: FrontendRouteValidationResult\n): Promise<void> {\n const registryPath = path.join(webPath, 'src', 'routes', 'navRoutes.generated.ts');\n\n if (!await fileExists(registryPath)) {\n result.registry.exists = false;\n result.recommendations.push('Run `scaffold_routes` to generate navRoutes.generated.ts');\n return;\n }\n\n result.registry.exists = true;\n\n try {\n const content = await readText(registryPath);\n\n // Count routes in registry\n const routeMatches = content.matchAll(/'([a-z.]+)':\\s*\\{/g);\n const registryRoutes = new Set<string>();\n for (const match of routeMatches) {\n registryRoutes.add(match[1]);\n }\n\n result.registry.routeCount = registryRoutes.size;\n\n // Check for outdated routes\n for (const backendRoute of backendRoutes) {\n if (!registryRoutes.has(backendRoute.navRoute)) {\n result.registry.outdated.push(backendRoute.navRoute);\n }\n }\n\n // Check for routes in registry that no longer exist in backend\n for (const registryRoute of registryRoutes) {\n if (!backendRoutes.find(r => r.navRoute === registryRoute)) {\n result.registry.outdated.push(`${registryRoute} (removed from backend)`);\n }\n }\n } catch {\n result.registry.exists = false;\n }\n}\n\nasync function validateApiClients(\n webPath: string,\n backendRoutes: NavRouteEntry[],\n result: FrontendRouteValidationResult\n): Promise<void> {\n const servicesPath = path.join(webPath, 'src', 'services', 'api');\n\n const clientFiles = await glob('**/*.ts', {\n cwd: servicesPath,\n absolute: true,\n ignore: ['**/index.ts'],\n });\n\n result.apiClients.total = clientFiles.length;\n\n for (const file of clientFiles) {\n try {\n const content = await readText(file);\n const relativePath = path.relative(webPath, file);\n\n // Check if client uses getRoute()\n const usesRegistry = content.includes(\"getRoute('\") || content.includes('getRoute(\"');\n\n if (!usesRegistry) {\n // Check for hardcoded API paths\n const hardcodedMatch = content.match(/apiClient\\.(get|post|put|delete)\\s*[<(]\\s*['\"`]([^'\"`]+)['\"`]/);\n if (hardcodedMatch) {\n result.apiClients.issues.push({\n type: 'invalid-path',\n severity: 'warning',\n file: relativePath,\n message: `Hardcoded API path: ${hardcodedMatch[2]}`,\n suggestion: 'Use getRoute() from navRoutes.generated.ts instead',\n });\n }\n } else {\n // Validate the NavRoute reference\n const navRouteMatch = content.match(/getRoute\\s*\\(\\s*['\"`]([^'\"`]+)['\"`]\\s*\\)/);\n if (navRouteMatch) {\n const navRoute = navRouteMatch[1];\n const backendRoute = backendRoutes.find(r => r.navRoute === navRoute);\n\n if (!backendRoute) {\n result.apiClients.issues.push({\n type: 'missing-route',\n severity: 'error',\n file: relativePath,\n navRoute,\n message: `NavRoute \"${navRoute}\" not found in backend controllers`,\n suggestion: 'Verify the NavRoute path or update the backend controller',\n });\n } else {\n result.apiClients.valid++;\n }\n }\n }\n } catch {\n logger.debug(`Failed to parse API client: ${file}`);\n }\n }\n}\n\nasync function validateRoutes(\n webPath: string,\n backendRoutes: NavRouteEntry[],\n result: FrontendRouteValidationResult\n): Promise<void> {\n const routesPath = path.join(webPath, 'src', 'routes', 'index.tsx');\n\n if (!await fileExists(routesPath)) {\n result.routes.total = 0;\n result.routes.missing = backendRoutes.map(r => r.navRoute);\n return;\n }\n\n try {\n const content = await readText(routesPath);\n\n // Extract paths from React Router configuration\n const pathMatches = content.matchAll(/path:\\s*['\"`]([^'\"`]+)['\"`]/g);\n const frontendPaths = new Set<string>();\n for (const match of pathMatches) {\n frontendPaths.add(match[1]);\n }\n\n result.routes.total = frontendPaths.size;\n\n // Check for missing frontend routes\n for (const backendRoute of backendRoutes) {\n const webPath = backendRoute.webPath.replace(/^\\//, '');\n const parts = webPath.split('/');\n\n // Check if any part of the path is defined\n let found = false;\n for (const pathPart of parts) {\n if (frontendPaths.has(pathPart)) {\n found = true;\n break;\n }\n }\n\n if (!found && parts.length > 0) {\n result.routes.missing.push(backendRoute.navRoute);\n }\n }\n\n // Check for orphaned frontend routes (routes without backend)\n for (const frontendPath of frontendPaths) {\n if (frontendPath === '*' || frontendPath === '' || frontendPath.startsWith(':')) {\n continue;\n }\n\n const matchingBackend = backendRoutes.find(r =>\n r.webPath.includes(frontendPath) || r.navRoute.includes(frontendPath)\n );\n\n if (!matchingBackend) {\n result.routes.orphaned.push(frontendPath);\n }\n }\n } catch {\n result.routes.total = 0;\n result.routes.missing = backendRoutes.map(r => r.navRoute);\n }\n}\n\nfunction generateRecommendations(result: FrontendRouteValidationResult): void {\n if (!result.registry.exists) {\n result.recommendations.push('Run `scaffold_routes source=\"controllers\"` to generate route registry');\n } else if (result.registry.outdated.length > 0) {\n result.recommendations.push(`Registry is outdated: ${result.registry.outdated.length} routes need sync. Run \\`scaffold_routes\\``);\n }\n\n if (result.apiClients.issues.length > 0) {\n const hardcoded = result.apiClients.issues.filter(i => i.type === 'invalid-path').length;\n const missing = result.apiClients.issues.filter(i => i.type === 'missing-route').length;\n\n if (hardcoded > 0) {\n result.recommendations.push(`${hardcoded} API clients use hardcoded paths. Migrate to getRoute()`);\n }\n if (missing > 0) {\n result.recommendations.push(`${missing} API clients reference non-existent NavRoutes`);\n }\n }\n\n if (result.routes.missing.length > 0) {\n result.recommendations.push(`${result.routes.missing.length} backend routes have no frontend counterpart`);\n }\n\n if (result.routes.orphaned.length > 0) {\n result.recommendations.push(`${result.routes.orphaned.length} frontend routes have no backend NavRoute`);\n }\n\n if (result.valid && result.recommendations.length === 0) {\n result.recommendations.push('All routes are synchronized between frontend and backend');\n }\n}\n\nfunction formatResult(\n result: FrontendRouteValidationResult,\n _input: ValidateFrontendRoutesInput\n): string {\n const lines: string[] = [];\n\n const statusIcon = result.valid ? '✅' : '❌';\n lines.push(`# Frontend Route Validation ${statusIcon}`);\n lines.push('');\n\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Valid | ${result.valid ? 'Yes' : 'No'} |`);\n lines.push(`| Registry Exists | ${result.registry.exists ? 'Yes' : 'No'} |`);\n lines.push(`| Registry Routes | ${result.registry.routeCount} |`);\n lines.push(`| API Clients | ${result.apiClients.valid}/${result.apiClients.total} valid |`);\n lines.push(`| Frontend Routes | ${result.routes.total} |`);\n lines.push(`| Missing Routes | ${result.routes.missing.length} |`);\n lines.push(`| Orphaned Routes | ${result.routes.orphaned.length} |`);\n lines.push('');\n\n if (result.registry.outdated.length > 0) {\n lines.push('## Outdated Registry Entries');\n lines.push('');\n for (const route of result.registry.outdated) {\n lines.push(`- \\`${route}\\``);\n }\n lines.push('');\n }\n\n if (result.apiClients.issues.length > 0) {\n lines.push('## API Client Issues');\n lines.push('');\n for (const issue of result.apiClients.issues) {\n const icon = issue.severity === 'error' ? '❌' : '⚠️';\n lines.push(`### ${icon} ${issue.file}`);\n lines.push('');\n lines.push(`- **Type**: ${issue.type}`);\n lines.push(`- **Message**: ${issue.message}`);\n if (issue.navRoute) {\n lines.push(`- **NavRoute**: \\`${issue.navRoute}\\``);\n }\n lines.push(`- **Suggestion**: ${issue.suggestion}`);\n lines.push('');\n }\n }\n\n if (result.routes.missing.length > 0) {\n lines.push('## Missing Frontend Routes');\n lines.push('');\n lines.push('These backend NavRoutes have no corresponding frontend route:');\n lines.push('');\n for (const route of result.routes.missing) {\n lines.push(`- \\`${route}\\``);\n }\n lines.push('');\n }\n\n if (result.routes.orphaned.length > 0) {\n lines.push('## Orphaned Frontend Routes');\n lines.push('');\n lines.push('These frontend routes have no corresponding backend NavRoute:');\n lines.push('');\n for (const route of result.routes.orphaned) {\n lines.push(`- \\`${route}\\``);\n }\n lines.push('');\n }\n\n lines.push('## Recommendations');\n lines.push('');\n for (const rec of result.recommendations) {\n lines.push(`- ${rec}`);\n }\n lines.push('');\n\n lines.push('## Commands');\n lines.push('');\n lines.push('```bash');\n lines.push('# Regenerate route registry');\n lines.push('scaffold_routes source=\"controllers\"');\n lines.push('');\n lines.push('# Generate API client for a specific NavRoute');\n lines.push('scaffold_api_client navRoute=\"platform.administration.users\" name=\"User\"');\n lines.push('```');\n\n return lines.join('\\n');\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config, ScaffoldFrontendExtensionResult } from '../types/index.js';\nimport { ScaffoldFrontendExtensionInputSchema } from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { writeText, fileExists, safeJoinPath } from '../utils/fs.js';\nimport { logger } from '../lib/logger.js';\n\nexport const scaffoldFrontendExtensionTool: Tool = {\n name: 'scaffold_frontend_extension',\n description: `Generate frontend extension infrastructure for SmartStack.\n\nCreates:\n- Extension types (ExtensionConfig, SlotProps, ColumnExtension, etc.)\n- Slot/Fill system using React Context\n- ExtensionProvider for configuration\n- PageRegistry for page overrides\n- Example extension implementation\n\nUse type=\"infrastructure\" for the core system, \"page-slots\" to add slots to existing pages,\n\"extension-example\" for client usage examples, or \"all\" for everything.`,\n inputSchema: {\n type: 'object',\n properties: {\n type: {\n type: 'string',\n enum: ['infrastructure', 'page-slots', 'extension-example', 'all'],\n description: 'Type of extension to scaffold',\n },\n target: {\n type: 'string',\n description: 'Target page or component (e.g., \"UsersPage\")',\n },\n options: {\n type: 'object',\n properties: {\n slots: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n name: { type: 'string' },\n location: { type: 'string' },\n contextProps: { type: 'array', items: { type: 'string' } },\n },\n },\n },\n outputPath: { type: 'string' },\n dryRun: { type: 'boolean', default: false },\n overwrite: { type: 'boolean', default: false },\n },\n },\n },\n required: ['type'],\n },\n};\n\nexport async function handleScaffoldFrontendExtension(\n args: unknown,\n config: Config\n): Promise<string> {\n try {\n const input = ScaffoldFrontendExtensionInputSchema.parse(args);\n const projectPath = config.smartstack.projectPath;\n const structure = await findSmartStackStructure(projectPath);\n\n if (!structure.web) {\n return JSON.stringify({\n success: false,\n error: 'Web project folder not found. Expected: web/, client/, or frontend/ directory.',\n });\n }\n\n const webPath = structure.web;\n const srcPath = safeJoinPath(webPath, 'src');\n const dryRun = input.options?.dryRun || false;\n const overwrite = input.options?.overwrite || false;\n\n const result: ScaffoldFrontendExtensionResult = {\n success: true,\n type: input.type,\n files: [],\n instructions: [],\n warnings: [],\n };\n\n switch (input.type) {\n case 'infrastructure':\n await scaffoldInfrastructure(srcPath, result, dryRun, overwrite);\n break;\n case 'page-slots':\n if (!input.target) {\n return JSON.stringify({\n success: false,\n error: 'Target page is required for page-slots type (e.g., target: \"UsersPage\")',\n });\n }\n await scaffoldPageSlots(srcPath, input.target, input.options?.slots || [], result, dryRun);\n break;\n case 'extension-example':\n await scaffoldExtensionExample(srcPath, result, dryRun, overwrite);\n break;\n case 'all':\n await scaffoldInfrastructure(srcPath, result, dryRun, overwrite);\n await scaffoldExtensionExample(srcPath, result, dryRun, overwrite);\n break;\n }\n\n return formatResult(result);\n } catch (error) {\n logger.error('scaffold_frontend_extension failed', { error });\n return JSON.stringify({\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n}\n\nasync function scaffoldInfrastructure(\n srcPath: string,\n result: ScaffoldFrontendExtensionResult,\n dryRun: boolean,\n overwrite: boolean\n): Promise<void> {\n const extensionsPath = safeJoinPath(srcPath, 'extensions');\n\n // 1. Types file\n const typesContent = generateTypesFile();\n await writeFileIfNeeded(\n safeJoinPath(extensionsPath, 'types.ts'),\n typesContent,\n result,\n dryRun,\n overwrite\n );\n\n // 2. SlotFill system\n const slotFillContent = generateSlotFillFile();\n await writeFileIfNeeded(\n safeJoinPath(extensionsPath, 'SlotFill.tsx'),\n slotFillContent,\n result,\n dryRun,\n overwrite\n );\n\n // 3. ExtensionContext\n const extensionContextContent = generateExtensionContextFile();\n await writeFileIfNeeded(\n safeJoinPath(extensionsPath, 'ExtensionContext.tsx'),\n extensionContextContent,\n result,\n dryRun,\n overwrite\n );\n\n // 4. PageRegistry\n const pageRegistryContent = generatePageRegistryFile();\n await writeFileIfNeeded(\n safeJoinPath(extensionsPath, 'PageRegistry.tsx'),\n pageRegistryContent,\n result,\n dryRun,\n overwrite\n );\n\n // 5. Index file\n const indexContent = generateIndexFile();\n await writeFileIfNeeded(\n safeJoinPath(extensionsPath, 'index.ts'),\n indexContent,\n result,\n dryRun,\n overwrite\n );\n\n result.instructions.push(\n '1. Add ExtensionProvider to SmartStackProvider.tsx',\n '2. Add extension exports to src/index.ts',\n '3. Update SmartStackConfig type in router/types.ts to include extensions?: ExtensionConfig'\n );\n}\n\nasync function scaffoldPageSlots(\n srcPath: string,\n targetPage: string,\n slots: { name: string; location: string; contextProps?: string[] }[],\n result: ScaffoldFrontendExtensionResult,\n _dryRun: boolean\n): Promise<void> {\n // Find the target page file\n const pagesPath = safeJoinPath(srcPath, 'pages');\n const possiblePaths = [\n safeJoinPath(pagesPath, 'admin', `${targetPage}.tsx`),\n safeJoinPath(pagesPath, `${targetPage}.tsx`),\n safeJoinPath(pagesPath, 'user', `${targetPage}.tsx`),\n safeJoinPath(pagesPath, 'business', `${targetPage}.tsx`),\n ];\n\n let targetPath: string | null = null;\n for (const p of possiblePaths) {\n if (await fileExists(p)) {\n targetPath = p;\n break;\n }\n }\n\n if (!targetPath) {\n result.warnings.push(`Page ${targetPage} not found in standard locations`);\n result.instructions.push(\n `Manually add slots to ${targetPage}:`,\n ...slots.map(s => ` - <Slot name=\"${s.name}\" context={{ ${(s.contextProps || []).join(', ')} }} />`)\n );\n return;\n }\n\n result.instructions.push(\n `Add these slots to ${targetPage}:`,\n '',\n '1. Add import at top of file:',\n ` import { Slot } from '@/extensions';`,\n '',\n '2. Add slots at appropriate locations:',\n ...slots.map(s => ` - ${s.location}: <Slot name=\"${s.name}\" context={{ ${(s.contextProps || []).join(', ')} }} />`)\n );\n}\n\nasync function scaffoldExtensionExample(\n srcPath: string,\n result: ScaffoldFrontendExtensionResult,\n dryRun: boolean,\n overwrite: boolean\n): Promise<void> {\n const examplesPath = safeJoinPath(srcPath, 'extensions', 'examples');\n\n const exampleContent = generateUserExtensionExample();\n await writeFileIfNeeded(\n safeJoinPath(examplesPath, 'UserExtensionExample.tsx'),\n exampleContent,\n result,\n dryRun,\n overwrite\n );\n\n result.instructions.push(\n 'Example extension created. To use:',\n '1. Import in your client app',\n '2. Add to SmartStackProvider config.extensions'\n );\n}\n\nasync function writeFileIfNeeded(\n filePath: string,\n content: string,\n result: ScaffoldFrontendExtensionResult,\n dryRun: boolean,\n overwrite: boolean\n): Promise<void> {\n const exists = await fileExists(filePath);\n\n if (exists && !overwrite) {\n result.files.push({ path: filePath, content, action: 'skipped' });\n result.warnings.push(`File already exists: ${filePath} (use overwrite: true to replace)`);\n return;\n }\n\n if (!dryRun) {\n await writeText(filePath, content);\n }\n\n result.files.push({\n path: filePath,\n content,\n action: exists ? 'modified' : 'created',\n });\n}\n\nfunction formatResult(result: ScaffoldFrontendExtensionResult): string {\n const lines: string[] = [];\n\n lines.push(`# Frontend Extension Scaffold Result`);\n lines.push('');\n lines.push(`**Status**: ${result.success ? '✅ Success' : '❌ Failed'}`);\n lines.push(`**Type**: ${result.type}`);\n lines.push('');\n\n if (result.files.length > 0) {\n lines.push('## Files');\n for (const file of result.files) {\n const icon = file.action === 'created' ? '✅' : file.action === 'modified' ? '📝' : '⏭️';\n lines.push(`${icon} \\`${file.path}\\` (${file.action})`);\n }\n lines.push('');\n }\n\n if (result.warnings.length > 0) {\n lines.push('## Warnings');\n for (const warning of result.warnings) {\n lines.push(`⚠️ ${warning}`);\n }\n lines.push('');\n }\n\n if (result.instructions.length > 0) {\n lines.push('## Next Steps');\n for (const instruction of result.instructions) {\n lines.push(instruction);\n }\n }\n\n return lines.join('\\n');\n}\n\n// ============================================================================\n// File Content Generators\n// ============================================================================\n\nfunction generateTypesFile(): string {\n return `import type { ComponentType, ReactNode } from 'react';\n\n/**\n * Extension configuration for SmartStack frontend\n */\nexport interface ExtensionConfig {\n /**\n * Page component overrides\n * Key: NavRoute path (e.g., 'platform.administration.users')\n * Value: React component to render instead of the default page\n */\n pages?: Record<string, ComponentType<PageProps>>;\n\n /**\n * Slot content injections\n * Key: Slot name (e.g., 'users.form.fields.after')\n * Value: React component, render function, or array of components\n */\n slots?: Record<string, SlotContent>;\n\n /**\n * Table column extensions\n * Key: Table identifier (e.g., 'users', 'roles')\n */\n tableColumns?: Record<string, ColumnExtension[]>;\n\n /**\n * Form field extensions\n * Key: Form identifier (e.g., 'user-form', 'role-form')\n */\n formFields?: Record<string, FormFieldExtension[]>;\n\n /**\n * Event handlers for extension hooks\n */\n hooks?: ExtensionHooks;\n}\n\nexport interface PageProps {\n pageKey: string;\n params?: Record<string, string>;\n}\n\nexport type SlotContent =\n | ComponentType<SlotProps>\n | ((props: SlotProps) => ReactNode)\n | ReactNode\n | SlotContent[];\n\nexport interface SlotProps {\n slotName: string;\n context?: Record<string, unknown>;\n}\n\nexport interface ColumnExtension {\n key: string;\n label: string;\n sortable?: boolean;\n width?: string;\n render: (item: Record<string, unknown>, context: ColumnContext) => ReactNode;\n position?: 'before' | 'after';\n insertAfter?: string;\n insertBefore?: string;\n}\n\nexport interface ColumnContext {\n tableId: string;\n rowIndex: number;\n}\n\nexport interface FormFieldExtension {\n name: string;\n label: string;\n type: 'text' | 'number' | 'select' | 'checkbox' | 'textarea' | 'custom';\n required?: boolean;\n placeholder?: string;\n options?: Array<{ value: string; label: string }>;\n validate?: (value: unknown) => string | undefined;\n render?: (props: FormFieldProps) => ReactNode;\n position?: 'before' | 'after';\n insertAfter?: string;\n insertBefore?: string;\n}\n\nexport interface FormFieldProps {\n name: string;\n value: unknown;\n onChange: (value: unknown) => void;\n error?: string;\n disabled?: boolean;\n formData: Record<string, unknown>;\n}\n\nexport interface ExtensionHooks {\n onPageLoad?: (pageKey: string) => void | Promise<void>;\n onFormSubmit?: (formId: string, data: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;\n onTableRowClick?: (tableId: string, row: Record<string, unknown>) => void;\n onBeforeSave?: (entityType: string, data: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;\n onAfterSave?: (entityType: string, data: Record<string, unknown>, result: unknown) => void | Promise<void>;\n}\n\nexport type SlotName =\n | 'users.header.actions'\n | 'users.table.columns.before'\n | 'users.table.columns.after'\n | 'users.table.row.actions'\n | 'users.form.fields.before'\n | 'users.form.fields.after'\n | 'users.card.content'\n | 'users.detail.header'\n | 'users.detail.tabs.after'\n | 'users.detail.sidebar'\n | 'roles.header.actions'\n | 'roles.table.columns.after'\n | 'roles.form.fields.after'\n | 'permissions.header.actions'\n | string;\n\nexport interface PageRegistryEntry {\n key: string;\n defaultComponent: ComponentType<PageProps>;\n slots: SlotName[];\n}\n\nexport interface ExtensionContextValue {\n config: ExtensionConfig;\n getPage: (key: string) => ComponentType<PageProps> | undefined;\n getSlotContent: (slotName: string) => SlotContent | undefined;\n getTableColumns: (tableId: string) => ColumnExtension[];\n getFormFields: (formId: string) => FormFieldExtension[];\n hasExtension: (key: string) => boolean;\n}\n`;\n}\n\nfunction generateSlotFillFile(): string {\n return `import {\n createContext,\n useContext,\n useMemo,\n type ReactNode,\n type ComponentType,\n isValidElement,\n Fragment,\n} from 'react';\nimport type { SlotContent, SlotProps } from './types';\n\ninterface SlotFillContextValue {\n fills: Map<string, SlotContent[]>;\n registerFill: (slotName: string, content: SlotContent) => void;\n unregisterFill: (slotName: string, content: SlotContent) => void;\n getSlotContent: (slotName: string) => SlotContent[];\n}\n\nconst SlotFillContext = createContext<SlotFillContextValue | null>(null);\n\nexport function useSlotFill(): SlotFillContextValue {\n const context = useContext(SlotFillContext);\n if (!context) {\n throw new Error('useSlotFill must be used within a SlotFillProvider');\n }\n return context;\n}\n\ninterface SlotFillProviderProps {\n children: ReactNode;\n initialFills?: Record<string, SlotContent>;\n}\n\nexport function SlotFillProvider({ children, initialFills }: SlotFillProviderProps) {\n const fills = useMemo(() => {\n const map = new Map<string, SlotContent[]>();\n if (initialFills) {\n Object.entries(initialFills).forEach(([slotName, content]) => {\n const existing = map.get(slotName) || [];\n if (Array.isArray(content)) {\n map.set(slotName, [...existing, ...content]);\n } else {\n map.set(slotName, [...existing, content]);\n }\n });\n }\n return map;\n }, [initialFills]);\n\n const contextValue = useMemo<SlotFillContextValue>(\n () => ({\n fills,\n registerFill: (slotName: string, content: SlotContent) => {\n const existing = fills.get(slotName) || [];\n fills.set(slotName, [...existing, content]);\n },\n unregisterFill: (slotName: string, content: SlotContent) => {\n const existing = fills.get(slotName) || [];\n fills.set(slotName, existing.filter((c) => c !== content));\n },\n getSlotContent: (slotName: string) => fills.get(slotName) || [],\n }),\n [fills]\n );\n\n return <SlotFillContext.Provider value={contextValue}>{children}</SlotFillContext.Provider>;\n}\n\ninterface SlotComponentProps {\n name: string;\n context?: Record<string, unknown>;\n children?: ReactNode;\n fallback?: ReactNode;\n wrapper?: ComponentType<{ children: ReactNode }>;\n}\n\nexport function Slot({ name, context = {}, children, fallback, wrapper: Wrapper }: SlotComponentProps) {\n const slotFill = useContext(SlotFillContext);\n const slotContent = slotFill?.getSlotContent(name) || [];\n\n const props: SlotProps = useMemo(\n () => ({ slotName: name, context }),\n [name, context]\n );\n\n const renderedContent = useMemo(() => {\n if (slotContent.length === 0) {\n return fallback || null;\n }\n\n return slotContent.map((content, index) => {\n const key = \\`\\${name}-\\${index}\\`;\n return (\n <Fragment key={key}>\n {renderSlotContent(content, props)}\n </Fragment>\n );\n });\n }, [slotContent, name, props, fallback]);\n\n const finalContent = (\n <>\n {renderedContent}\n {children}\n </>\n );\n\n if (Wrapper) {\n return <Wrapper>{finalContent}</Wrapper>;\n }\n\n return <>{finalContent}</>;\n}\n\ninterface FillProps {\n slot: string;\n children: ReactNode;\n}\n\nexport function Fill({ slot, children }: FillProps) {\n const { registerFill, unregisterFill } = useSlotFill();\n\n useMemo(() => {\n registerFill(slot, children);\n return () => unregisterFill(slot, children);\n }, [slot, children, registerFill, unregisterFill]);\n\n return null;\n}\n\nfunction renderSlotContent(content: SlotContent, props: SlotProps): ReactNode {\n if (content === null || content === undefined) {\n return null;\n }\n\n if (Array.isArray(content)) {\n return (\n <>\n {content.map((item, index) => (\n <Fragment key={index}>{renderSlotContent(item, props)}</Fragment>\n ))}\n </>\n );\n }\n\n if (isValidElement(content)) {\n return content;\n }\n\n if (typeof content === 'function') {\n const Component = content as ComponentType<SlotProps>;\n return <Component {...props} />;\n }\n\n return content as ReactNode;\n}\n\nexport function useSlotHasContent(slotName: string): boolean {\n const slotFill = useContext(SlotFillContext);\n return (slotFill?.getSlotContent(slotName)?.length || 0) > 0;\n}\n\nexport function createSlotFill<T extends Record<string, unknown> = Record<string, unknown>>(slotName: string) {\n function TypedSlot(props: Omit<SlotComponentProps, 'name'> & { context?: T }) {\n return <Slot {...props} name={slotName} />;\n }\n TypedSlot.displayName = \\`Slot(\\${slotName})\\`;\n\n function TypedFill({ children }: { children: ReactNode }) {\n return <Fill slot={slotName} children={children} />;\n }\n TypedFill.displayName = \\`Fill(\\${slotName})\\`;\n\n return { Slot: TypedSlot, Fill: TypedFill, slotName };\n}\n`;\n}\n\nfunction generateExtensionContextFile(): string {\n return `import { createContext, useContext, useMemo, type ReactNode, type ComponentType } from 'react';\nimport type {\n ExtensionConfig,\n ExtensionContextValue,\n PageProps,\n SlotContent,\n ColumnExtension,\n FormFieldExtension,\n} from './types';\nimport { SlotFillProvider } from './SlotFill';\n\nconst ExtensionContext = createContext<ExtensionContextValue | null>(null);\n\nexport function useExtensions(): ExtensionContextValue {\n const context = useContext(ExtensionContext);\n if (!context) {\n return {\n config: {},\n getPage: () => undefined,\n getSlotContent: () => undefined,\n getTableColumns: () => [],\n getFormFields: () => [],\n hasExtension: () => false,\n };\n }\n return context;\n}\n\nexport function usePageOverride(pageKey: string): ComponentType<PageProps> | undefined {\n const { getPage } = useExtensions();\n return getPage(pageKey);\n}\n\nexport function useTableColumnExtensions(tableId: string): ColumnExtension[] {\n const { getTableColumns } = useExtensions();\n return getTableColumns(tableId);\n}\n\nexport function useFormFieldExtensions(formId: string): FormFieldExtension[] {\n const { getFormFields } = useExtensions();\n return getFormFields(formId);\n}\n\nexport function useHasExtension(key: string): boolean {\n const { hasExtension } = useExtensions();\n return hasExtension(key);\n}\n\ninterface ExtensionProviderProps {\n config?: ExtensionConfig;\n children: ReactNode;\n}\n\nexport function ExtensionProvider({ config = {}, children }: ExtensionProviderProps) {\n const contextValue = useMemo<ExtensionContextValue>(() => {\n const { pages = {}, slots = {}, tableColumns = {}, formFields = {} } = config;\n\n return {\n config,\n getPage: (key: string): ComponentType<PageProps> | undefined => pages[key],\n getSlotContent: (slotName: string): SlotContent | undefined => slots[slotName],\n getTableColumns: (tableId: string): ColumnExtension[] => tableColumns[tableId] || [],\n getFormFields: (formId: string): FormFieldExtension[] => formFields[formId] || [],\n hasExtension: (key: string): boolean =>\n key in pages || key in slots || key in tableColumns || key in formFields,\n };\n }, [config]);\n\n return (\n <ExtensionContext.Provider value={contextValue}>\n <SlotFillProvider initialFills={config.slots}>\n {children}\n </SlotFillProvider>\n </ExtensionContext.Provider>\n );\n}\n`;\n}\n\nfunction generatePageRegistryFile(): string {\n return `import { type ComponentType } from 'react';\nimport type { PageProps, PageRegistryEntry, SlotName } from './types';\nimport { usePageOverride } from './ExtensionContext';\n\nclass PageRegistryClass {\n private pages: Map<string, PageRegistryEntry> = new Map();\n\n register(key: string, component: ComponentType<PageProps>, slots: SlotName[] = []): void {\n this.pages.set(key, { key, defaultComponent: component, slots });\n }\n\n get(key: string): PageRegistryEntry | undefined {\n return this.pages.get(key);\n }\n\n getAll(): PageRegistryEntry[] {\n return Array.from(this.pages.values());\n }\n\n has(key: string): boolean {\n return this.pages.has(key);\n }\n\n getSlots(key: string): SlotName[] {\n return this.pages.get(key)?.slots || [];\n }\n}\n\nexport const PageRegistry = new PageRegistryClass();\n\nexport function withPageOverride<P extends PageProps>(\n pageKey: string,\n DefaultComponent: ComponentType<P>\n): ComponentType<P> {\n function OverridablePage(props: P) {\n const OverrideComponent = usePageOverride(pageKey);\n if (OverrideComponent) {\n return <OverrideComponent {...props} />;\n }\n return <DefaultComponent {...props} />;\n }\n OverridablePage.displayName = \\`Overridable(\\${pageKey})\\`;\n return OverridablePage;\n}\n\nexport function useActivePage(pageKey: string): ComponentType<PageProps> | undefined {\n const override = usePageOverride(pageKey);\n const entry = PageRegistry.get(pageKey);\n return override || entry?.defaultComponent;\n}\n\ninterface ExtendablePageProps {\n pageKey: string;\n defaultComponent: ComponentType<PageProps>;\n params?: Record<string, string>;\n}\n\nexport function ExtendablePage({ pageKey, defaultComponent: DefaultComponent, params }: ExtendablePageProps) {\n const OverrideComponent = usePageOverride(pageKey);\n const props: PageProps = { pageKey, params };\n\n if (OverrideComponent) {\n return <OverrideComponent {...props} />;\n }\n return <DefaultComponent {...props} />;\n}\n\nexport const PAGE_KEYS = {\n USERS_LIST: 'platform.administration.users',\n USERS_DETAIL: 'platform.administration.users.detail',\n ROLES_LIST: 'platform.administration.permissions.roles',\n ROLES_DETAIL: 'platform.administration.permissions.roles.detail',\n PERMISSIONS_LIST: 'platform.administration.permissions.permissions',\n PERMISSIONS_DETAIL: 'platform.administration.permissions.permissions.detail',\n ASSIGNMENTS: 'platform.administration.permissions.assignments',\n AI_DASHBOARD: 'platform.administration.ai.dashboard',\n AI_PROMPTS_LIST: 'platform.administration.ai.prompts',\n AI_PROMPTS_DETAIL: 'platform.administration.ai.prompts.detail',\n WORKFLOWS_LIST: 'platform.administration.workflows.list',\n WORKFLOWS_DETAIL: 'platform.administration.workflows.detail',\n EMAIL_TEMPLATES_LIST: 'platform.administration.workflows.email-templates',\n EMAIL_TEMPLATES_DETAIL: 'platform.administration.workflows.email-templates.detail',\n TICKETS_LIST: 'platform.support.tickets',\n TICKETS_DETAIL: 'platform.support.tickets.detail',\n SUPPORT_DASHBOARD: 'platform.support.dashboard',\n USER_PROFILE: 'personal.myspace.profile',\n USER_PREFERENCES: 'personal.myspace.preferences',\n USER_DASHBOARD: 'personal.myspace.dashboard',\n MY_TICKETS_LIST: 'business.support-client.my-tickets',\n MY_TICKETS_DETAIL: 'business.support-client.my-tickets.detail',\n} as const;\n\nexport type PageKey = typeof PAGE_KEYS[keyof typeof PAGE_KEYS];\n`;\n}\n\nfunction generateIndexFile(): string {\n return `/**\n * SmartStack Frontend Extension System\n * @packageDocumentation\n */\n\n// Types\nexport type {\n ExtensionConfig,\n PageProps,\n SlotContent,\n SlotProps,\n ColumnExtension,\n ColumnContext,\n FormFieldExtension,\n FormFieldProps,\n ExtensionHooks,\n SlotName,\n PageRegistryEntry,\n ExtensionContextValue,\n} from './types';\n\n// Extension Context & Provider\nexport {\n ExtensionProvider,\n useExtensions,\n usePageOverride,\n useTableColumnExtensions,\n useFormFieldExtensions,\n useHasExtension,\n} from './ExtensionContext';\n\n// Slot/Fill System\nexport {\n SlotFillProvider,\n Slot,\n Fill,\n useSlotFill,\n useSlotHasContent,\n createSlotFill,\n} from './SlotFill';\n\n// Page Registry\nexport {\n PageRegistry,\n withPageOverride,\n useActivePage,\n ExtendablePage,\n PAGE_KEYS,\n type PageKey,\n} from './PageRegistry';\n`;\n}\n\nfunction generateUserExtensionExample(): string {\n return `/**\n * Example: Extending the Users page with custom fields\n *\n * Usage in client app:\n * \\`\\`\\`tsx\n * import { SmartStackProvider } from '@atlashub/smartstack';\n * import { UserExtensionFields, userTableColumns } from './extensions/UserExtensions';\n *\n * const config = {\n * apiUrl: 'https://api.mycompany.com',\n * extensions: {\n * slots: {\n * 'users.form.fields.after': UserExtensionFields,\n * },\n * tableColumns: {\n * users: userTableColumns,\n * },\n * },\n * };\n * \\`\\`\\`\n */\n\nimport { type ReactNode } from 'react';\nimport type { SlotProps, ColumnExtension, FormFieldExtension } from '../types';\n\ninterface UserExtensionData {\n employeeNumber?: string;\n departmentId?: string;\n department?: { id: string; name: string };\n hireDate?: string;\n officeLocation?: string;\n}\n\nexport function UserExtensionFields({ context }: SlotProps): ReactNode {\n const formData = context?.formData as Record<string, unknown> | undefined;\n const onChange = context?.onChange as ((field: string, value: unknown) => void) | undefined;\n const disabled = context?.disabled as boolean | undefined;\n\n const ext = (formData?.ext || {}) as UserExtensionData;\n\n const handleChange = (field: keyof UserExtensionData, value: string) => {\n if (onChange) {\n onChange('ext', { ...ext, [field]: value });\n }\n };\n\n return (\n <div className=\"space-y-4 border-t pt-4 mt-4\">\n <h4 className=\"text-sm font-medium text-muted-foreground\">Custom Fields</h4>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <label htmlFor=\"employeeNumber\" className=\"text-sm font-medium\">Employee Number</label>\n <input\n id=\"employeeNumber\"\n type=\"text\"\n className=\"w-full px-3 py-2 border rounded-md\"\n value={ext.employeeNumber || ''}\n onChange={(e) => handleChange('employeeNumber', e.target.value)}\n disabled={disabled}\n placeholder=\"EMP-001\"\n />\n </div>\n <div className=\"space-y-2\">\n <label htmlFor=\"departmentId\" className=\"text-sm font-medium\">Department</label>\n <select\n id=\"departmentId\"\n className=\"w-full px-3 py-2 border rounded-md\"\n value={ext.departmentId || ''}\n onChange={(e) => handleChange('departmentId', e.target.value)}\n disabled={disabled}\n >\n <option value=\"\">Select department...</option>\n <option value=\"engineering\">Engineering</option>\n <option value=\"sales\">Sales</option>\n <option value=\"marketing\">Marketing</option>\n <option value=\"hr\">Human Resources</option>\n <option value=\"finance\">Finance</option>\n </select>\n </div>\n </div>\n </div>\n );\n}\n\nexport const userTableColumns: ColumnExtension[] = [\n {\n key: 'employeeNumber',\n label: 'Employee #',\n sortable: true,\n width: '120px',\n render: (item) => {\n const ext = (item.ext || {}) as UserExtensionData;\n return ext.employeeNumber || '-';\n },\n },\n {\n key: 'department',\n label: 'Department',\n sortable: true,\n render: (item) => {\n const ext = (item.ext || {}) as UserExtensionData;\n return ext.department?.name || '-';\n },\n },\n];\n\nexport const userFormFields: FormFieldExtension[] = [\n {\n name: 'ext.employeeNumber',\n label: 'Employee Number',\n type: 'text',\n placeholder: 'EMP-001',\n position: 'after',\n },\n {\n name: 'ext.departmentId',\n label: 'Department',\n type: 'select',\n options: [\n { value: 'engineering', label: 'Engineering' },\n { value: 'sales', label: 'Sales' },\n { value: 'marketing', label: 'Marketing' },\n { value: 'hr', label: 'Human Resources' },\n { value: 'finance', label: 'Finance' },\n ],\n position: 'after',\n },\n];\n\nexport const completeUserExtensionConfig = {\n slots: { 'users.form.fields.after': UserExtensionFields },\n tableColumns: { users: userTableColumns },\n formFields: { 'user-form': userFormFields },\n};\n`;\n}\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config, AnalyzeExtensionPointsResult, ExtensionPointAnalysis } from '../types/index.js';\nimport { AnalyzeExtensionPointsInputSchema } from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { readText, safeJoinPath, fileExists } from '../utils/fs.js';\nimport { logger } from '../lib/logger.js';\nimport * as path from 'path';\nimport * as fs from 'fs/promises';\n\nexport const analyzeExtensionPointsTool: Tool = {\n name: 'analyze_extension_points',\n description: `Analyze React pages and components to identify extension points.\n\nScans TypeScript/React files to detect:\n- Forms (suggest form field slots)\n- Tables/DataTables (suggest column slots)\n- Modals/Dialogs (suggest content slots)\n- Headers (suggest action slots)\n- Cards/Lists (suggest item slots)\n\nReturns suggested slot names, locations, and context props for each component.\nUse this before scaffold_frontend_extension to understand what slots to add.`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Path to SmartStack web project (defaults to configured path)',\n },\n target: {\n type: 'string',\n enum: ['pages', 'components', 'forms', 'tables', 'all'],\n default: 'all',\n description: 'Type of components to analyze',\n },\n filter: {\n type: 'string',\n description: 'Filter by file name pattern (e.g., \"User*\", \"*Detail*\")',\n },\n },\n },\n};\n\nexport async function handleAnalyzeExtensionPoints(\n args: unknown,\n config: Config\n): Promise<string> {\n try {\n const input = AnalyzeExtensionPointsInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const structure = await findSmartStackStructure(projectPath);\n\n if (!structure.web) {\n return JSON.stringify({\n success: false,\n error: 'Web project folder not found. Expected: web/, client/, or frontend/ directory.',\n });\n }\n\n const webPath = structure.web;\n const srcPath = safeJoinPath(webPath, 'src');\n\n // Determine directories to scan based on target\n const directories: string[] = [];\n switch (input.target) {\n case 'pages':\n directories.push(safeJoinPath(srcPath, 'pages'));\n break;\n case 'components':\n directories.push(safeJoinPath(srcPath, 'components'));\n break;\n case 'forms':\n directories.push(safeJoinPath(srcPath, 'pages'));\n directories.push(safeJoinPath(srcPath, 'components'));\n break;\n case 'tables':\n directories.push(safeJoinPath(srcPath, 'pages'));\n directories.push(safeJoinPath(srcPath, 'components'));\n break;\n case 'all':\n default:\n directories.push(safeJoinPath(srcPath, 'pages'));\n directories.push(safeJoinPath(srcPath, 'components'));\n break;\n }\n\n // Collect all TSX files\n const files: string[] = [];\n for (const dir of directories) {\n if (await fileExists(dir)) {\n const dirFiles = await collectTsxFiles(dir, input.filter);\n files.push(...dirFiles);\n }\n }\n\n // Analyze each file\n const analyzed: ExtensionPointAnalysis[] = [];\n for (const file of files) {\n const analysis = await analyzeFile(file, srcPath, input.target);\n if (analysis && analysis.suggestedSlots.length > 0) {\n analyzed.push(analysis);\n }\n }\n\n // Build result\n const result: AnalyzeExtensionPointsResult = {\n totalFiles: files.length,\n analyzed,\n summary: {\n pagesWithForms: analyzed.filter(a => a.hasForm).length,\n pagesWithTables: analyzed.filter(a => a.hasTable).length,\n pagesWithModals: analyzed.filter(a => a.hasModal).length,\n totalSuggestedSlots: analyzed.reduce((sum, a) => sum + a.suggestedSlots.length, 0),\n },\n recommendations: generateRecommendations(analyzed),\n };\n\n return JSON.stringify(result, null, 2);\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error));\n logger.error('analyze_extension_points failed', { error: err.message });\n return JSON.stringify({\n success: false,\n error: err.message,\n });\n }\n}\n\n/**\n * Recursively collect TSX files from a directory\n */\nasync function collectTsxFiles(dir: string, filter?: string): Promise<string[]> {\n const files: string[] = [];\n\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip node_modules, test directories, etc.\n if (!['node_modules', '__tests__', 'test', 'tests', '.git'].includes(entry.name)) {\n files.push(...await collectTsxFiles(fullPath, filter));\n }\n } else if (entry.isFile() && entry.name.endsWith('.tsx')) {\n // Skip test files, stories, etc.\n if (!entry.name.includes('.test.') && !entry.name.includes('.spec.') && !entry.name.includes('.stories.')) {\n // Apply filter if provided\n if (filter) {\n const pattern = filter.replace(/\\*/g, '.*');\n const regex = new RegExp(`^${pattern}`, 'i');\n if (regex.test(entry.name.replace('.tsx', ''))) {\n files.push(fullPath);\n }\n } else {\n files.push(fullPath);\n }\n }\n }\n }\n } catch (error) {\n // Directory doesn't exist or not accessible\n logger.debug(`Could not read directory: ${dir}`);\n }\n\n return files;\n}\n\n/**\n * Analyze a single React file for extension points\n */\nasync function analyzeFile(\n filePath: string,\n srcPath: string,\n target: string\n): Promise<ExtensionPointAnalysis | null> {\n try {\n const content = await readText(filePath);\n if (!content) return null;\n\n const relativePath = path.relative(srcPath, filePath).replace(/\\\\/g, '/');\n const componentName = extractComponentName(content, filePath);\n const isPage = filePath.includes('/pages/') || filePath.includes('\\\\pages\\\\');\n\n const analysis: ExtensionPointAnalysis = {\n file: relativePath,\n componentName,\n type: isPage ? 'page' : 'component',\n suggestedSlots: [],\n hasModal: detectModal(content),\n hasForm: detectForm(content),\n hasTable: detectTable(content),\n imports: extractImports(content),\n lineCount: content.split('\\n').length,\n };\n\n // Generate slot suggestions based on detected patterns\n const slotPrefix = generateSlotPrefix(componentName, relativePath);\n\n // Filter based on target type\n if (target === 'forms' && !analysis.hasForm) return null;\n if (target === 'tables' && !analysis.hasTable) return null;\n\n // Header/Actions slots (high priority for pages)\n if (isPage) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.header.actions`,\n location: 'Header toolbar/actions area',\n description: 'Add custom action buttons to the page header',\n contextProps: [],\n priority: 'high',\n });\n }\n\n // Form slots\n if (analysis.hasForm) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.form.fields.before`,\n location: 'Before form fields',\n description: 'Add custom fields at the beginning of the form',\n contextProps: ['formData', 'onChange', 'disabled'],\n priority: 'high',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.form.fields.after`,\n location: 'After form fields',\n description: 'Add custom fields at the end of the form',\n contextProps: ['formData', 'onChange', 'disabled'],\n priority: 'high',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.form.actions`,\n location: 'Form action buttons area',\n description: 'Add custom action buttons to the form',\n contextProps: ['formData', 'isSubmitting'],\n priority: 'medium',\n });\n }\n\n // Table slots\n if (analysis.hasTable) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.table.columns.before`,\n location: 'Before standard columns',\n description: 'Add custom columns at the start of the table',\n contextProps: ['tableData'],\n priority: 'high',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.table.columns.after`,\n location: 'After standard columns',\n description: 'Add custom columns at the end of the table',\n contextProps: ['tableData'],\n priority: 'high',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.table.row.actions`,\n location: 'Row actions cell',\n description: 'Add custom action buttons per row',\n contextProps: ['item', 'index'],\n priority: 'medium',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.table.toolbar`,\n location: 'Table toolbar area',\n description: 'Add custom buttons/filters above the table',\n contextProps: ['selectedItems', 'filters'],\n priority: 'medium',\n });\n }\n\n // Modal/Dialog slots\n if (analysis.hasModal) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.modal.content`,\n location: 'Modal body content',\n description: 'Inject custom content into modal',\n contextProps: ['isOpen', 'data'],\n priority: 'medium',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.modal.footer`,\n location: 'Modal footer area',\n description: 'Add custom buttons to modal footer',\n contextProps: ['isOpen', 'onClose'],\n priority: 'low',\n });\n }\n\n // Card/Detail slots (for detail pages)\n if (isPage && componentName.toLowerCase().includes('detail')) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.detail.header`,\n location: 'Detail page header',\n description: 'Add content to detail page header',\n contextProps: ['item'],\n priority: 'high',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.detail.sidebar`,\n location: 'Detail page sidebar',\n description: 'Add sidebar widgets or information',\n contextProps: ['item'],\n priority: 'medium',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.detail.tabs`,\n location: 'Tab navigation',\n description: 'Add custom tabs to detail view',\n contextProps: ['item', 'activeTab'],\n priority: 'medium',\n });\n }\n\n // List/Card view slots\n if (detectCardView(content)) {\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.card.content`,\n location: 'Card content area',\n description: 'Add custom content to cards',\n contextProps: ['item'],\n priority: 'medium',\n });\n analysis.suggestedSlots.push({\n name: `${slotPrefix}.card.actions`,\n location: 'Card actions area',\n description: 'Add custom action buttons to cards',\n contextProps: ['item'],\n priority: 'medium',\n });\n }\n\n return analysis;\n } catch (error) {\n logger.debug(`Could not analyze file: ${filePath}`);\n return null;\n }\n}\n\n/**\n * Extract component name from file content or filename\n */\nfunction extractComponentName(content: string, filePath: string): string {\n // Try to extract from export default or export function\n const exportMatch = content.match(/export\\s+(?:default\\s+)?function\\s+(\\w+)/);\n if (exportMatch) return exportMatch[1];\n\n const constExportMatch = content.match(/export\\s+(?:default\\s+)?const\\s+(\\w+)/);\n if (constExportMatch) return constExportMatch[1];\n\n // Fall back to filename\n const filename = path.basename(filePath, '.tsx');\n return filename;\n}\n\n/**\n * Generate slot prefix from component name\n */\nfunction generateSlotPrefix(componentName: string, _relativePath: string): string {\n // Convert PascalCase to kebab-case\n let prefix = componentName\n .replace(/Page$/, '')\n .replace(/Component$/, '')\n .replace(/([A-Z])/g, '-$1')\n .toLowerCase()\n .replace(/^-/, '');\n\n // Simplify common patterns\n if (prefix.includes('user')) prefix = 'users';\n else if (prefix.includes('role')) prefix = 'roles';\n else if (prefix.includes('permission')) prefix = 'permissions';\n else if (prefix.includes('ticket')) prefix = 'tickets';\n else if (prefix.includes('workflow')) prefix = 'workflows';\n\n return prefix;\n}\n\n/**\n * Detect if file contains a form\n */\nfunction detectForm(content: string): boolean {\n const formPatterns = [\n /<form/i,\n /useForm\\(/,\n /onSubmit/,\n /handleSubmit/,\n /<Form/,\n /FormProvider/,\n /useFormContext/,\n /<input/i,\n /<Input/,\n /<TextField/,\n /<Select/,\n ];\n return formPatterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Detect if file contains a table\n */\nfunction detectTable(content: string): boolean {\n const tablePatterns = [\n /<table/i,\n /<Table/,\n /DataTable/,\n /DataGrid/,\n /useTable/,\n /<thead/i,\n /<tbody/i,\n /columns=/,\n /columns:/,\n ];\n return tablePatterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Detect if file contains a modal/dialog\n */\nfunction detectModal(content: string): boolean {\n const modalPatterns = [\n /<Modal/,\n /<Dialog/,\n /useModal/,\n /useDialog/,\n /isOpen/,\n /onClose/,\n /AlertDialog/,\n /Sheet/,\n /Drawer/,\n ];\n return modalPatterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Detect if file contains card view\n */\nfunction detectCardView(content: string): boolean {\n const cardPatterns = [\n /<Card/,\n /\\.map\\s*\\(\\s*\\([^)]*\\)\\s*=>\\s*</,\n /renderItem/,\n /gridView/,\n /cardView/,\n ];\n return cardPatterns.some(pattern => pattern.test(content));\n}\n\n/**\n * Extract import statements\n */\nfunction extractImports(content: string): string[] {\n const imports: string[] = [];\n const importRegex = /import\\s+(?:{[^}]+}|\\*\\s+as\\s+\\w+|\\w+)\\s+from\\s+['\"]([^'\"]+)['\"]/g;\n\n let match;\n while ((match = importRegex.exec(content)) !== null) {\n imports.push(match[1]);\n }\n\n return imports;\n}\n\n/**\n * Generate recommendations based on analysis\n */\nfunction generateRecommendations(analyzed: ExtensionPointAnalysis[]): string[] {\n const recommendations: string[] = [];\n\n const highPriorityCount = analyzed.reduce(\n (sum, a) => sum + a.suggestedSlots.filter(s => s.priority === 'high').length,\n 0\n );\n\n if (highPriorityCount > 0) {\n recommendations.push(\n `Found ${highPriorityCount} high-priority extension points. Consider implementing these first.`\n );\n }\n\n const pagesWithForms = analyzed.filter(a => a.hasForm && a.type === 'page');\n if (pagesWithForms.length > 0) {\n recommendations.push(\n `${pagesWithForms.length} pages have forms. Add form.fields.after slots for custom fields.`\n );\n }\n\n const pagesWithTables = analyzed.filter(a => a.hasTable && a.type === 'page');\n if (pagesWithTables.length > 0) {\n recommendations.push(\n `${pagesWithTables.length} pages have tables. Add table.columns.after slots for custom columns.`\n );\n }\n\n const detailPages = analyzed.filter(a => a.componentName.toLowerCase().includes('detail'));\n if (detailPages.length > 0) {\n recommendations.push(\n `${detailPages.length} detail pages found. Consider adding detail.sidebar and detail.tabs slots.`\n );\n }\n\n if (analyzed.length === 0) {\n recommendations.push(\n 'No extension points found. Try expanding the search with target=\"all\" or adjusting the filter.'\n );\n }\n\n return recommendations;\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n ValidateSecurityInputSchema,\n type Config,\n type SecurityValidationResult,\n type SecurityFinding,\n type SecurityCheck,\n} from '../types/index.js';\nimport { findFiles, readText, validatePathSecurity } from '../utils/fs.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { logger } from '../lib/logger.js';\nimport path from 'path';\n\nexport const validateSecurityTool: Tool = {\n name: 'validate_security',\n description: 'Validate SmartStack security patterns: multi-tenant isolation, authorization, input validation, secrets exposure, injection vulnerabilities, and OWASP Top 10 compliance.',\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: [\n 'hardcoded-secrets',\n 'sql-injection',\n 'tenant-isolation',\n 'authorization',\n 'dangerous-functions',\n 'input-validation',\n 'xss',\n 'csrf',\n 'logging-sensitive',\n 'all',\n ],\n },\n description: 'Security checks to run',\n default: ['all'],\n },\n severity: {\n type: 'string',\n enum: ['blocking', 'all'],\n description: 'Filter results by severity',\n },\n },\n },\n};\n\nexport async function handleValidateSecurity(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = ValidateSecurityInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const checksToRun = input.checks.includes('all')\n ? [\n 'hardcoded-secrets',\n 'sql-injection',\n 'tenant-isolation',\n 'authorization',\n 'dangerous-functions',\n 'input-validation',\n ] as SecurityCheck[]\n : input.checks;\n\n logger.info('Validating security', { projectPath, checks: checksToRun });\n\n const result: SecurityValidationResult = {\n valid: true,\n summary: '',\n findings: [],\n stats: {\n blocking: 0,\n critical: 0,\n warning: 0,\n filesScanned: 0,\n },\n };\n\n const structure = await findSmartStackStructure(projectPath);\n\n // Run selected checks\n if (checksToRun.includes('hardcoded-secrets')) {\n await checkHardcodedSecrets(structure, result);\n }\n\n if (checksToRun.includes('sql-injection')) {\n await checkSqlInjection(structure, result);\n }\n\n if (checksToRun.includes('tenant-isolation')) {\n await checkTenantIsolation(structure, result);\n }\n\n if (checksToRun.includes('authorization')) {\n await checkAuthorization(structure, result);\n }\n\n if (checksToRun.includes('dangerous-functions')) {\n await checkDangerousFunctions(structure, result);\n }\n\n if (checksToRun.includes('input-validation')) {\n await checkInputValidation(structure, result);\n }\n\n // Calculate stats\n result.stats.blocking = result.findings.filter(f => f.severity === 'blocking').length;\n result.stats.critical = result.findings.filter(f => f.severity === 'critical').length;\n result.stats.warning = result.findings.filter(f => f.severity === 'warning').length;\n\n // Filter by severity if requested\n if (input.severity === 'blocking') {\n result.findings = result.findings.filter(f => f.severity === 'blocking');\n }\n\n // Update validity\n result.valid = result.stats.blocking === 0;\n\n // Generate summary\n result.summary = result.valid\n ? `Security validation passed. ${result.stats.warning} warning(s) found.`\n : `Security validation FAILED. ${result.stats.blocking} blocking issue(s) found.`;\n\n return formatSecurityReport(result);\n}\n\n// ============================================================================\n// Security Check Functions\n// ============================================================================\n\nasync function checkHardcodedSecrets(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n const secretPatterns = [\n // Credentials\n { pattern: /(?:password|passwd|pwd)\\s*[=:]\\s*[\"'][^\"']{4,}[\"']/gi, name: 'password' },\n { pattern: /(?:api[_-]?key|apikey)\\s*[=:]\\s*[\"'][^\"']{8,}[\"']/gi, name: 'API key' },\n { pattern: /(?:secret|token)\\s*[=:]\\s*[\"'][^\"']{8,}[\"']/gi, name: 'secret/token' },\n // Connection strings with embedded passwords\n { pattern: /Server=.+;.*Password=[^;]+/gi, name: 'connection string with password' },\n { pattern: /Data Source=.+;.*Password=[^;]+/gi, name: 'connection string with password' },\n // Private keys\n { pattern: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/g, name: 'private key' },\n ];\n\n const filesToScan = await getFilesToScan(structure, ['**/*.cs', '**/*.ts', '**/*.tsx', '**/*.json']);\n result.stats.filesScanned += filesToScan.length;\n\n for (const file of filesToScan) {\n // Skip excluded files\n if (isExcludedFile(file)) continue;\n\n const content = await readText(file);\n const lines = content.split('\\n');\n\n for (const { pattern, name } of secretPatterns) {\n pattern.lastIndex = 0; // Reset regex state\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const lineNumber = getLineNumber(content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if it's a configuration placeholder or example\n if (isPlaceholderValue(lineContent)) continue;\n\n result.findings.push({\n severity: 'blocking',\n category: 'hardcoded-secrets',\n message: `Hardcoded ${name} detected`,\n file: path.relative(structure.root, file),\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: `Move ${name} to configuration or environment variables`,\n cweId: 'CWE-798',\n });\n }\n }\n }\n}\n\nasync function checkSqlInjection(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n const sqlInjectionPatterns = [\n // Raw SQL with string concatenation (the most dangerous pattern)\n { pattern: /\\.(?:FromSqlRaw|ExecuteSqlRaw)\\s*\\([^)]*\\s*\\+\\s*/g, name: 'concatenated SQL in FromSqlRaw/ExecuteSqlRaw' },\n // ADO.NET without parameters\n { pattern: /new SqlCommand\\s*\\([^)]*\\+/g, name: 'concatenated SQL in SqlCommand' },\n { pattern: /CommandText\\s*=\\s*[^;]*\\+/g, name: 'concatenated SQL in CommandText' },\n // Note: FromSqlInterpolated with $\"\" is safe and not flagged\n ];\n\n const csFiles = await getFilesToScan(structure, ['**/*.cs']);\n result.stats.filesScanned += csFiles.length;\n\n for (const file of csFiles) {\n if (isExcludedFile(file)) continue;\n\n const content = await readText(file);\n const lines = content.split('\\n');\n\n for (const { pattern, name } of sqlInjectionPatterns) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const lineNumber = getLineNumber(content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n result.findings.push({\n severity: 'blocking',\n category: 'sql-injection',\n message: `Potential SQL injection: ${name}`,\n file: path.relative(structure.root, file),\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Use parameterized queries: FromSqlRaw(\"SELECT * FROM x WHERE id = {0}\", id) or FromSqlInterpolated',\n cweId: 'CWE-89',\n });\n }\n }\n }\n}\n\nasync function checkTenantIsolation(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n if (!structure.domain) {\n result.findings.push({\n severity: 'warning',\n category: 'tenant-isolation',\n message: 'Domain project not found, skipping tenant isolation validation',\n file: '',\n suggestion: 'Ensure project structure follows SmartStack conventions',\n });\n return;\n }\n\n // Find entities implementing ITenantEntity\n const entityFiles = await findFiles('**/Entities/**/*.cs', { cwd: structure.domain });\n const tenantEntities: string[] = [];\n\n for (const file of entityFiles) {\n const content = await readText(file);\n if (content.includes('ITenantEntity') || content.includes(': TenantEntity')) {\n const entityMatch = content.match(/class\\s+(\\w+)/);\n if (entityMatch) {\n tenantEntities.push(entityMatch[1]);\n }\n }\n\n // Check for Create methods missing TenantId parameter\n const createMethodMatches = content.matchAll(/public\\s+static\\s+\\w+\\s+Create\\s*\\(([^)]*)\\)/g);\n for (const match of createMethodMatches) {\n const params = match[1];\n if ((content.includes('ITenantEntity') || content.includes(': TenantEntity')) && !params.includes('tenantId') && !params.includes('TenantId')) {\n const lineNumber = getLineNumber(content, match.index!);\n result.findings.push({\n severity: 'blocking',\n category: 'tenant-isolation',\n message: 'Create method missing tenantId parameter for tenant entity',\n file: path.relative(structure.root, file),\n line: lineNumber,\n code: truncateCode(match[0]),\n suggestion: 'Add Guid tenantId as first parameter: Create(Guid tenantId, ...)',\n cweId: 'CWE-639',\n });\n }\n }\n }\n\n // Check services for direct DbContext access without tenant filtering\n if (structure.application) {\n const serviceFiles = await findFiles('**/*Service.cs', { cwd: structure.application });\n for (const file of serviceFiles) {\n const content = await readText(file);\n\n // Pattern: Direct access without Where clause\n const directAccessPattern = /_context\\.\\w+\\.(?:First|Single|Find|ToList)\\s*\\(/g;\n let match;\n while ((match = directAccessPattern.exec(content)) !== null) {\n // Check if there's a Where clause nearby (simple heuristic)\n const surroundingCode = content.substring(Math.max(0, match.index - 100), match.index + 100);\n if (!surroundingCode.includes('.Where(') && !surroundingCode.includes('TenantId')) {\n const lineNumber = getLineNumber(content, match.index);\n result.findings.push({\n severity: 'critical',\n category: 'tenant-isolation',\n message: 'Direct DbContext access without tenant filtering',\n file: path.relative(structure.root, file),\n line: lineNumber,\n code: truncateCode(match[0]),\n suggestion: 'Use repository with global tenant filter or add explicit TenantId filter',\n cweId: 'CWE-639',\n });\n }\n }\n }\n }\n}\n\nasync function checkAuthorization(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n const apiPath = structure.api || structure.apiCore;\n if (!apiPath) {\n result.findings.push({\n severity: 'warning',\n category: 'authorization',\n message: 'API project not found, skipping authorization validation',\n file: '',\n suggestion: 'Ensure project structure follows SmartStack conventions',\n });\n return;\n }\n\n const controllerFiles = await findFiles('**/Controllers/**/*.cs', { cwd: apiPath });\n result.stats.filesScanned += controllerFiles.length;\n\n for (const file of controllerFiles) {\n const content = await readText(file);\n\n // Check for [ApiController] without authorization\n if (content.includes('[ApiController]')) {\n const hasClassLevelAuth =\n content.includes('[Authorize]') ||\n content.includes('[NavRoute(') ||\n content.includes('[AllowAnonymous]');\n\n if (!hasClassLevelAuth) {\n // Extract controller name\n const controllerMatch = content.match(/class\\s+(\\w+Controller)/);\n const controllerName = controllerMatch ? controllerMatch[1] : 'Unknown';\n const lineNumber = controllerMatch ? getLineNumber(content, controllerMatch.index!) : 1;\n\n result.findings.push({\n severity: 'blocking',\n category: 'authorization',\n message: `Controller ${controllerName} missing authorization attribute`,\n file: path.relative(structure.root, file),\n line: lineNumber,\n suggestion: 'Add [NavRoute(\"context.application.module\")] or [Authorize] attribute to the controller class',\n cweId: 'CWE-862',\n });\n }\n }\n }\n}\n\nasync function checkDangerousFunctions(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n const csharpPatterns = [\n { pattern: /Process\\.Start\\s*\\([^)]*(?:user|input|param|request)/gi, name: 'Process.Start with user input' },\n { pattern: /Assembly\\.Load(?:From|File)?\\s*\\(/g, name: 'Dynamic assembly loading' },\n { pattern: /Type\\.GetType\\s*\\([^)]*(?:user|input|param|request)/gi, name: 'Type.GetType with user input' },\n { pattern: /Activator\\.CreateInstance\\s*\\([^)]*(?:user|input|param|request)/gi, name: 'Activator.CreateInstance with user input' },\n ];\n\n const typescriptPatterns = [\n { pattern: /\\beval\\s*\\(/g, name: 'eval() usage' },\n { pattern: /new\\s+Function\\s*\\(/g, name: 'new Function() usage' },\n { pattern: /child_process\\.exec\\s*\\(/g, name: 'child_process.exec usage' },\n { pattern: /\\.innerHTML\\s*=/g, name: 'innerHTML assignment' },\n { pattern: /dangerouslySetInnerHTML/g, name: 'dangerouslySetInnerHTML usage' },\n ];\n\n // Check C# files\n const csFiles = await getFilesToScan(structure, ['**/*.cs']);\n for (const file of csFiles) {\n if (isExcludedFile(file)) continue;\n const content = await readText(file);\n await checkPatterns(file, content, csharpPatterns, structure, result);\n }\n\n // Check TypeScript files\n const tsFiles = await getFilesToScan(structure, ['**/*.ts', '**/*.tsx']);\n for (const file of tsFiles) {\n if (isExcludedFile(file)) continue;\n const content = await readText(file);\n await checkPatterns(file, content, typescriptPatterns, structure, result);\n }\n}\n\nasync function checkPatterns(\n file: string,\n content: string,\n patterns: Array<{ pattern: RegExp; name: string }>,\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n const lines = content.split('\\n');\n\n for (const { pattern, name } of patterns) {\n pattern.lastIndex = 0;\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const lineNumber = getLineNumber(content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n result.findings.push({\n severity: 'critical',\n category: 'dangerous-functions',\n message: `Dangerous function: ${name}`,\n file: path.relative(structure.root, file),\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Avoid using dangerous functions with user-controlled input. Use safe alternatives.',\n cweId: 'CWE-78',\n });\n }\n }\n}\n\nasync function checkInputValidation(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n result: SecurityValidationResult\n): Promise<void> {\n if (!structure.application) {\n return;\n }\n\n // Find DTOs\n const dtoFiles = await findFiles('**/*Dto.cs', { cwd: structure.application });\n const dtos: string[] = [];\n\n for (const file of dtoFiles) {\n const content = await readText(file);\n const dtoMatch = content.match(/class\\s+(\\w+Dto)/);\n if (dtoMatch) {\n dtos.push(dtoMatch[1]);\n }\n }\n\n // Find validators\n const validatorFiles = await findFiles('**/*Validator.cs', { cwd: structure.application });\n const validators: string[] = [];\n\n for (const file of validatorFiles) {\n const content = await readText(file);\n const validatorMatch = content.match(/class\\s+(\\w+Validator)/);\n if (validatorMatch) {\n validators.push(validatorMatch[1]);\n }\n }\n\n // Check for DTOs without validators\n for (const dto of dtos) {\n const expectedValidator = dto.replace(/Dto$/, 'DtoValidator');\n const hasValidator = validators.some(v => v === expectedValidator || v === `${dto}Validator`);\n\n if (!hasValidator) {\n result.findings.push({\n severity: 'warning',\n category: 'input-validation',\n message: `DTO ${dto} has no FluentValidation validator`,\n file: `Application/DTOs/${dto}.cs`,\n suggestion: `Create ${expectedValidator} class with FluentValidation rules`,\n cweId: 'CWE-20',\n });\n }\n }\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nasync function getFilesToScan(\n structure: Awaited<ReturnType<typeof findSmartStackStructure>>,\n patterns: string[]\n): Promise<string[]> {\n const allFiles: string[] = [];\n\n for (const pattern of patterns) {\n const files = await findFiles(pattern, { cwd: structure.root });\n // Validate each file path stays within project root\n for (const file of files) {\n try {\n validatePathSecurity(file, structure.root);\n allFiles.push(file);\n } catch {\n // Skip files that fail path validation (potential traversal)\n logger.warn('Skipping file outside project root', { file });\n }\n }\n }\n\n return [...new Set(allFiles)]; // Remove duplicates\n}\n\nfunction isExcludedFile(filePath: string): boolean {\n const exclusions = [\n /[/\\\\]bin[/\\\\]/,\n /[/\\\\]obj[/\\\\]/,\n /[/\\\\]node_modules[/\\\\]/,\n /\\.example\\./,\n /\\.template\\./,\n /\\.test\\./,\n /\\.spec\\./,\n /Tests[/\\\\]/,\n /appsettings\\.Development\\.json$/,\n /appsettings\\.Template\\.json$/,\n ];\n\n return exclusions.some(pattern => pattern.test(filePath));\n}\n\nfunction isPlaceholderValue(line: string): boolean {\n // Only match explicit environment variable syntax, not general TODO comments\n const placeholderPatterns = [\n /\\${[A-Z_][A-Z0-9_]*}/, // ${VAR_NAME} - env var syntax\n /%[A-Z_][A-Z0-9_]*%/, // %VAR_NAME% - Windows env var\n /\\{\\{[A-Za-z_][A-Za-z0-9_]*\\}\\}/, // {{varName}} - template syntax\n /[\"']your[_-]?(?:password|secret|key|token)[\"']/i, // \"your_password\" placeholders\n /[\"']changeme[\"']/i,\n /[\"']<[A-Z_]+>[\"']/, // \"<REPLACE_ME>\" syntax\n /[\"']xxx+[\"']/i, // \"xxx\" or \"XXXX\" placeholders\n /=\\s*[\"'][\"']/, // Empty string assignments\n ];\n\n return placeholderPatterns.some(pattern => pattern.test(line));\n}\n\nfunction getLineNumber(content: string, index: number): number {\n // Handle both LF and CRLF line endings\n const normalizedContent = content.substring(0, index).replace(/\\r\\n/g, '\\n');\n return normalizedContent.split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 80): string {\n return code.length > maxLength ? code.substring(0, maxLength) + '...' : code;\n}\n\nfunction formatSecurityReport(result: SecurityValidationResult): string {\n const lines: string[] = [];\n\n lines.push('# Security Validation Report');\n lines.push('');\n lines.push('## Summary');\n lines.push(`- **Status**: ${result.valid ? '✅ PASSED' : '❌ FAILED'}`);\n lines.push(`- **Blocking**: ${result.stats.blocking}`);\n lines.push(`- **Critical**: ${result.stats.critical}`);\n lines.push(`- **Warnings**: ${result.stats.warning}`);\n lines.push(`- **Files Scanned**: ${result.stats.filesScanned}`);\n lines.push('');\n\n if (result.findings.length === 0) {\n lines.push('No security issues found.');\n return lines.join('\\n');\n }\n\n // Group by severity\n const blocking = result.findings.filter(f => f.severity === 'blocking');\n const critical = result.findings.filter(f => f.severity === 'critical');\n const warnings = result.findings.filter(f => f.severity === 'warning');\n\n if (blocking.length > 0) {\n lines.push('## Blocking Issues');\n lines.push('');\n for (const finding of blocking) {\n formatFinding(finding, lines);\n }\n }\n\n if (critical.length > 0) {\n lines.push('## Critical Issues');\n lines.push('');\n for (const finding of critical) {\n formatFinding(finding, lines);\n }\n }\n\n if (warnings.length > 0) {\n lines.push('## Warnings');\n lines.push('');\n for (const finding of warnings) {\n formatFinding(finding, lines);\n }\n }\n\n return lines.join('\\n');\n}\n\nfunction formatFinding(finding: SecurityFinding, lines: string[]): void {\n lines.push(`### ${finding.category}: ${finding.message}`);\n if (finding.file) {\n lines.push(`- **File**: \\`${finding.file}${finding.line ? `:${finding.line}` : ''}\\``);\n }\n if (finding.code) {\n lines.push(`- **Code**: \\`${finding.code}\\``);\n }\n if (finding.cweId) {\n lines.push(`- **CWE**: ${finding.cweId}`);\n }\n lines.push(`- **Fix**: ${finding.suggestion}`);\n lines.push('');\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n AnalyzeCodeQualityInputSchema,\n type Config,\n type CodeQualityResult,\n type QualitySummary,\n type MetricResults,\n type MetricStat,\n type Hotspot,\n type FunctionMetrics,\n type UnusedMember,\n type DuplicatedString,\n type UnassignedField,\n} 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 analyzeCodeQualityTool: Tool = {\n name: 'analyze_code_quality',\n description: 'Analyze code quality metrics for SmartStack projects: cognitive complexity, cyclomatic complexity, function size, nesting depth, unused members (S1144), duplicated strings (S1192), and unassigned fields (S3459).',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to analyze (default: SmartStack.app path from config)',\n },\n metrics: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'cognitive-complexity',\n 'cyclomatic-complexity',\n 'function-size',\n 'nesting-depth',\n 'parameter-count',\n 'code-duplication',\n 'file-size',\n 'unused-members',\n 'duplicated-strings',\n 'unassigned-fields',\n 'all',\n ],\n },\n description: 'Metrics to analyze',\n default: ['all'],\n },\n threshold: {\n type: 'string',\n enum: ['strict', 'normal', 'lenient'],\n description: 'Threshold level for violations',\n default: 'normal',\n },\n scope: {\n type: 'string',\n enum: ['changed', 'all'],\n description: 'Analyze only changed files or all',\n default: 'all',\n },\n },\n },\n};\n\n// Threshold definitions\nconst THRESHOLDS = {\n strict: {\n cognitiveComplexity: 10,\n cyclomaticComplexity: 8,\n functionSize: 30,\n nestingDepth: 2,\n parameterCount: 3,\n fileSize: 300,\n },\n normal: {\n cognitiveComplexity: 15,\n cyclomaticComplexity: 10,\n functionSize: 50,\n nestingDepth: 3,\n parameterCount: 4,\n fileSize: 500,\n },\n lenient: {\n cognitiveComplexity: 25,\n cyclomaticComplexity: 15,\n functionSize: 80,\n nestingDepth: 4,\n parameterCount: 5,\n fileSize: 800,\n },\n};\n\nexport async function handleAnalyzeCodeQuality(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = AnalyzeCodeQualityInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const thresholdLevel = input.threshold;\n const thresholds = THRESHOLDS[thresholdLevel];\n const requestedMetrics = input.metrics || ['all'];\n const analyzeAll = requestedMetrics.includes('all');\n\n logger.info('Analyzing code quality', { projectPath, threshold: thresholdLevel });\n\n const structure = await findSmartStackStructure(projectPath);\n\n // Collect all function metrics and file contents\n const allFunctionMetrics: FunctionMetrics[] = [];\n const fileMetrics: Map<string, { lineCount: number; functions: number }> = new Map();\n const fileContents: Map<string, string> = new Map();\n const allUnusedMembers: UnusedMember[] = [];\n const allUnassignedFields: UnassignedField[] = [];\n\n // Analyze C# files\n const csFiles = await findFiles('**/*.cs', { cwd: structure.root });\n const filteredCsFiles = csFiles.filter(f => !isExcludedPath(f));\n\n for (const file of filteredCsFiles) {\n const content = await readText(file);\n const relPath = path.relative(structure.root, file);\n const lineCount = content.split('\\n').length;\n\n const functions = extractCSharpFunctions(content, relPath);\n allFunctionMetrics.push(...functions);\n\n fileMetrics.set(relPath, { lineCount, functions: functions.length });\n fileContents.set(relPath, content);\n\n // SonarCloud-style detections for C# files\n if (analyzeAll || requestedMetrics.includes('unused-members')) {\n allUnusedMembers.push(...detectUnusedMembers(content, relPath));\n }\n if (analyzeAll || requestedMetrics.includes('unassigned-fields')) {\n allUnassignedFields.push(...detectUnassignedFields(content, relPath));\n }\n }\n\n // Analyze TypeScript files\n const tsFiles = await findFiles('**/*.{ts,tsx}', { cwd: structure.root });\n const filteredTsFiles = tsFiles.filter(f => !isExcludedPath(f));\n\n for (const file of filteredTsFiles) {\n const content = await readText(file);\n const relPath = path.relative(structure.root, file);\n const lineCount = content.split('\\n').length;\n\n const functions = extractTypeScriptFunctions(content, relPath);\n allFunctionMetrics.push(...functions);\n\n fileMetrics.set(relPath, { lineCount, functions: functions.length });\n fileContents.set(relPath, content);\n }\n\n // Calculate metrics\n const metrics = calculateMetrics(allFunctionMetrics, fileMetrics, thresholds);\n\n // Identify hotspots\n const hotspots = identifyHotspots(allFunctionMetrics, fileMetrics, thresholds);\n\n // Calculate summary\n const summary = calculateSummary(allFunctionMetrics, fileMetrics, metrics, hotspots);\n\n const result: CodeQualityResult = {\n summary,\n metrics,\n hotspots,\n };\n\n // Detect duplicated strings across all files\n let duplicatedStrings: DuplicatedString[] = [];\n if (analyzeAll || requestedMetrics.includes('duplicated-strings')) {\n duplicatedStrings = detectDuplicatedStrings(fileContents);\n }\n\n // Use extended report if SonarCloud detections are enabled\n if (allUnusedMembers.length > 0 || duplicatedStrings.length > 0 || allUnassignedFields.length > 0) {\n return formatExtendedReport(result, thresholds, allUnusedMembers, duplicatedStrings, allUnassignedFields);\n }\n\n return formatQualityReport(result, thresholds);\n}\n\n// ============================================================================\n// Function Extraction\n// ============================================================================\n\nfunction extractCSharpFunctions(content: string, file: string): FunctionMetrics[] {\n const functions: FunctionMetrics[] = [];\n const lines = content.split('\\n');\n\n // Pattern for C# methods - removed ^ anchor to match indented/attributed methods\n const methodPattern = /\\b(public|private|protected|internal)\\s+(?:async\\s+)?(?:static\\s+)?(?:virtual\\s+)?(?:override\\s+)?(?:[\\w<>,\\s\\[\\]]+)\\s+(\\w+)\\s*\\(([^)]*)\\)/gm;\n\n let match;\n while ((match = methodPattern.exec(content)) !== null) {\n const methodName = match[2];\n const params = match[3];\n const startLine = getLineNumber(content, match.index);\n\n // Find method end (count braces)\n const endLine = findMethodEnd(lines, startLine - 1);\n const lineCount = endLine - startLine + 1;\n\n // Calculate parameters\n const parameterCount = params.trim() ? params.split(',').length : 0;\n\n // Extract method body for complexity analysis\n const methodBody = lines.slice(startLine - 1, endLine).join('\\n');\n\n // Calculate complexities\n const cognitiveComplexity = calculateCognitiveComplexity(methodBody);\n const cyclomaticComplexity = calculateCyclomaticComplexity(methodBody);\n const maxNestingDepth = calculateNestingDepth(methodBody);\n\n functions.push({\n name: methodName,\n file,\n startLine,\n endLine,\n lineCount,\n parameterCount,\n maxNestingDepth,\n cognitiveComplexity,\n cyclomaticComplexity,\n });\n }\n\n return functions;\n}\n\nfunction extractTypeScriptFunctions(content: string, file: string): FunctionMetrics[] {\n const functions: FunctionMetrics[] = [];\n const lines = content.split('\\n');\n // Track already-processed functions to avoid duplicates across patterns\n const processedFunctions = new Set<string>();\n\n // Pattern for TypeScript functions/methods\n const patterns = [\n // Arrow functions assigned to const/let\n /(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?\\([^)]*\\)\\s*(?::\\s*\\w+)?\\s*=>/g,\n // Function declarations\n /(?:async\\s+)?function\\s+(\\w+)\\s*\\(([^)]*)\\)/g,\n // Class methods (removed ^ anchor for consistency)\n /\\b(?:async\\s+)?(\\w+)\\s*\\(([^)]*)\\)\\s*(?::\\s*[\\w<>,\\s\\[\\]]+)?\\s*\\{/gm,\n ];\n\n for (const pattern of patterns) {\n pattern.lastIndex = 0; // Reset regex state\n let match;\n while ((match = pattern.exec(content)) !== null) {\n const funcName = match[1];\n const params = match[2] || '';\n const startLine = getLineNumber(content, match.index);\n\n // Skip if it's a common keyword\n if (['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(funcName)) continue;\n\n // Deduplicate: skip if we already processed a function at this line\n const funcKey = `${file}:${startLine}:${funcName}`;\n if (processedFunctions.has(funcKey)) continue;\n processedFunctions.add(funcKey);\n\n const endLine = findMethodEnd(lines, startLine - 1);\n const lineCount = endLine - startLine + 1;\n const parameterCount = params.trim() ? params.split(',').length : 0;\n\n const methodBody = lines.slice(startLine - 1, endLine).join('\\n');\n const cognitiveComplexity = calculateCognitiveComplexity(methodBody);\n const cyclomaticComplexity = calculateCyclomaticComplexity(methodBody);\n const maxNestingDepth = calculateNestingDepth(methodBody);\n\n functions.push({\n name: funcName,\n file,\n startLine,\n endLine,\n lineCount,\n parameterCount,\n maxNestingDepth,\n cognitiveComplexity,\n cyclomaticComplexity,\n });\n }\n }\n\n return functions;\n}\n\nfunction findMethodEnd(lines: string[], startIndex: number): number {\n let braceCount = 0;\n let foundFirstBrace = false;\n\n for (let i = startIndex; i < lines.length; i++) {\n // Remove string literals and comments to avoid counting braces inside them\n const line = stripStringsAndComments(lines[i]);\n\n for (const char of line) {\n if (char === '{') {\n braceCount++;\n foundFirstBrace = true;\n } else if (char === '}') {\n braceCount--;\n if (foundFirstBrace && braceCount === 0) {\n return i + 1; // 1-indexed\n }\n }\n }\n }\n\n return startIndex + 1; // Fallback: single line\n}\n\nfunction stripStringsAndComments(line: string): string {\n // Remove single-line comments\n let result = line.replace(/\\/\\/.*$/, '');\n // Remove string literals (simple approach - handles most cases)\n result = result.replace(/\"(?:[^\"\\\\]|\\\\.)*\"/g, '\"\"');\n result = result.replace(/'(?:[^'\\\\]|\\\\.)*'/g, \"''\");\n result = result.replace(/`(?:[^`\\\\]|\\\\.)*`/g, '``');\n return result;\n}\n\n// ============================================================================\n// Complexity Calculations\n// ============================================================================\n\nfunction calculateCognitiveComplexity(code: string): number {\n let complexity = 0;\n let nestingLevel = 0;\n\n const lines = code.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Count control flow structures (add 1 + nesting level)\n const controlFlowPatterns = [\n /\\bif\\s*\\(/g,\n /\\belse\\s+if\\s*\\(/g,\n /\\bfor\\s*\\(/g,\n /\\bforeach\\s*\\(/g,\n /\\bwhile\\s*\\(/g,\n /\\bdo\\s*\\{/g,\n /\\bswitch\\s*\\(/g,\n /\\bcatch\\s*\\(/g,\n ];\n\n for (const pattern of controlFlowPatterns) {\n const matches = trimmed.match(pattern) || [];\n complexity += matches.length * (1 + nestingLevel);\n }\n\n // Count logical operators (each adds 1)\n const logicalPatterns = [/&&/g, /\\|\\|/g, /\\?\\?/g, /\\?\\./g];\n for (const pattern of logicalPatterns) {\n const matches = trimmed.match(pattern) || [];\n complexity += matches.length;\n }\n\n // Count ternary operators\n const ternaryMatches = trimmed.match(/\\?[^?:]+:/g) || [];\n complexity += ternaryMatches.length;\n\n // Track nesting level\n const openBraces = (trimmed.match(/\\{/g) || []).length;\n const closeBraces = (trimmed.match(/\\}/g) || []).length;\n nestingLevel += openBraces - closeBraces;\n nestingLevel = Math.max(0, nestingLevel);\n }\n\n return complexity;\n}\n\nfunction calculateCyclomaticComplexity(code: string): number {\n let complexity = 1; // Base complexity\n\n const patterns = [\n /\\bif\\b/g,\n /\\belse\\s+if\\b/g,\n /\\bwhile\\b/g,\n /\\bfor\\b/g,\n /\\bforeach\\b/g,\n /\\bcase\\b/g,\n /\\bcatch\\b/g,\n /\\?\\?/g,\n /\\?\\./g,\n /&&/g,\n /\\|\\|/g,\n ];\n\n for (const pattern of patterns) {\n const matches = code.match(pattern) || [];\n complexity += matches.length;\n }\n\n return complexity;\n}\n\nfunction calculateNestingDepth(code: string): number {\n let maxDepth = 0;\n let currentDepth = 0;\n\n for (const char of code) {\n if (char === '{') {\n currentDepth++;\n maxDepth = Math.max(maxDepth, currentDepth);\n } else if (char === '}') {\n currentDepth = Math.max(0, currentDepth - 1);\n }\n }\n\n return maxDepth;\n}\n\n// ============================================================================\n// Metrics Calculation\n// ============================================================================\n\nfunction calculateMetrics(\n functions: FunctionMetrics[],\n fileMetrics: Map<string, { lineCount: number; functions: number }>,\n thresholds: typeof THRESHOLDS.normal\n): MetricResults {\n const createStat = (\n values: number[],\n threshold: number\n ): MetricStat => {\n const filtered = values.filter(v => v > 0);\n const avg = filtered.length > 0 ? filtered.reduce((a, b) => a + b, 0) / filtered.length : 0;\n const max = filtered.length > 0 ? Math.max(...filtered) : 0;\n const violations = filtered.filter(v => v > threshold).length;\n\n return {\n average: Math.round(avg * 10) / 10,\n max,\n threshold,\n violations,\n };\n };\n\n const fileSizes = Array.from(fileMetrics.values()).map(f => f.lineCount);\n\n return {\n cognitiveComplexity: createStat(\n functions.map(f => f.cognitiveComplexity),\n thresholds.cognitiveComplexity\n ),\n cyclomaticComplexity: createStat(\n functions.map(f => f.cyclomaticComplexity),\n thresholds.cyclomaticComplexity\n ),\n functionSize: createStat(\n functions.map(f => f.lineCount),\n thresholds.functionSize\n ),\n nestingDepth: createStat(\n functions.map(f => f.maxNestingDepth),\n thresholds.nestingDepth\n ),\n fileSize: createStat(fileSizes, thresholds.fileSize),\n };\n}\n\nfunction identifyHotspots(\n functions: FunctionMetrics[],\n fileMetrics: Map<string, { lineCount: number; functions: number }>,\n thresholds: typeof THRESHOLDS.normal\n): Hotspot[] {\n const hotspots: Hotspot[] = [];\n\n // Function-level hotspots\n for (const func of functions) {\n const issues: string[] = [];\n\n if (func.cognitiveComplexity > thresholds.cognitiveComplexity) {\n issues.push(`Cognitive complexity: ${func.cognitiveComplexity} (threshold: ${thresholds.cognitiveComplexity})`);\n }\n if (func.cyclomaticComplexity > thresholds.cyclomaticComplexity) {\n issues.push(`Cyclomatic complexity: ${func.cyclomaticComplexity} (threshold: ${thresholds.cyclomaticComplexity})`);\n }\n if (func.lineCount > thresholds.functionSize) {\n issues.push(`Lines: ${func.lineCount} (threshold: ${thresholds.functionSize})`);\n }\n if (func.maxNestingDepth > thresholds.nestingDepth) {\n issues.push(`Nesting depth: ${func.maxNestingDepth} (threshold: ${thresholds.nestingDepth})`);\n }\n\n if (issues.length > 0) {\n const severity = issues.length >= 3 ? 'high' : issues.length === 2 ? 'medium' : 'low';\n hotspots.push({\n file: func.file,\n function: func.name,\n issues,\n severity,\n metrics: {\n cognitiveComplexity: func.cognitiveComplexity,\n cyclomaticComplexity: func.cyclomaticComplexity,\n lineCount: func.lineCount,\n nestingDepth: func.maxNestingDepth,\n },\n });\n }\n }\n\n // File-level hotspots\n for (const [file, metrics] of fileMetrics) {\n if (metrics.lineCount > thresholds.fileSize) {\n hotspots.push({\n file,\n issues: [`File size: ${metrics.lineCount} lines (threshold: ${thresholds.fileSize})`],\n severity: 'medium',\n metrics: {\n lineCount: metrics.lineCount,\n },\n });\n }\n }\n\n // Sort by severity\n const severityOrder = { high: 0, medium: 1, low: 2 };\n hotspots.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);\n\n return hotspots.slice(0, 20); // Limit to top 20\n}\n\nfunction calculateSummary(\n functions: FunctionMetrics[],\n fileMetrics: Map<string, { lineCount: number; functions: number }>,\n metrics: MetricResults,\n hotspots: Hotspot[]\n): QualitySummary {\n const totalViolations =\n metrics.cognitiveComplexity.violations +\n metrics.cyclomaticComplexity.violations +\n metrics.functionSize.violations +\n metrics.nestingDepth.violations +\n metrics.fileSize.violations;\n\n const totalFunctions = functions.length;\n const totalFiles = fileMetrics.size;\n\n // Calculate score (100 - penalty for violations)\n const violationRate = totalFunctions > 0 ? totalViolations / totalFunctions : 0;\n const score = Math.max(0, Math.round(100 - violationRate * 100));\n\n // Calculate grade\n let grade: 'A' | 'B' | 'C' | 'D' | 'F';\n if (score >= 90) grade = 'A';\n else if (score >= 80) grade = 'B';\n else if (score >= 70) grade = 'C';\n else if (score >= 60) grade = 'D';\n else grade = 'F';\n\n return {\n score,\n grade,\n filesAnalyzed: totalFiles,\n functionsAnalyzed: totalFunctions,\n issuesFound: hotspots.length,\n };\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\nfunction isExcludedPath(filePath: string): boolean {\n const exclusions = [\n /[/\\\\]bin[/\\\\]/,\n /[/\\\\]obj[/\\\\]/,\n /[/\\\\]node_modules[/\\\\]/,\n /[/\\\\]Migrations[/\\\\]/,\n /\\.test\\./,\n /\\.spec\\./,\n /Tests[/\\\\]/,\n /\\.d\\.ts$/,\n /\\.min\\./,\n ];\n\n return exclusions.some(pattern => pattern.test(filePath));\n}\n\nfunction getLineNumber(content: string, index: number): number {\n // Handle both LF and CRLF line endings\n const normalizedContent = content.substring(0, index).replace(/\\r\\n/g, '\\n');\n return normalizedContent.split('\\n').length;\n}\n\nfunction formatQualityReport(\n result: CodeQualityResult,\n thresholds: typeof THRESHOLDS.normal\n): string {\n const lines: string[] = [];\n\n lines.push('# Code Quality Report');\n lines.push('');\n lines.push('## Summary');\n lines.push(`- **Score**: ${result.summary.score}/100 (Grade: ${result.summary.grade})`);\n lines.push(`- **Files analyzed**: ${result.summary.filesAnalyzed}`);\n lines.push(`- **Functions analyzed**: ${result.summary.functionsAnalyzed}`);\n lines.push(`- **Issues found**: ${result.summary.issuesFound}`);\n lines.push('');\n\n lines.push('## Metrics Overview');\n lines.push('');\n lines.push('| Metric | Average | Max | Threshold | Status |');\n lines.push('|--------|---------|-----|-----------|--------|');\n\n const formatMetricRow = (name: string, stat: MetricStat) => {\n const status = stat.violations > 0 ? `${stat.violations} violations` : '✅ OK';\n return `| ${name} | ${stat.average} | ${stat.max} | ${stat.threshold} | ${status} |`;\n };\n\n lines.push(formatMetricRow('Cognitive Complexity', result.metrics.cognitiveComplexity));\n lines.push(formatMetricRow('Cyclomatic Complexity', result.metrics.cyclomaticComplexity));\n lines.push(formatMetricRow('Function Size', result.metrics.functionSize));\n lines.push(formatMetricRow('Nesting Depth', result.metrics.nestingDepth));\n lines.push(formatMetricRow('File Size', result.metrics.fileSize));\n lines.push('');\n\n if (result.hotspots.length > 0) {\n lines.push('## Hotspots (Needs Attention)');\n lines.push('');\n\n for (const hotspot of result.hotspots) {\n const severityEmoji = hotspot.severity === 'high' ? '🔴' : hotspot.severity === 'medium' ? '🟡' : '🟢';\n const location = hotspot.function\n ? `\\`${hotspot.function}\\` (${hotspot.file})`\n : `\\`${hotspot.file}\\``;\n\n lines.push(`### ${severityEmoji} ${hotspot.severity.toUpperCase()}: ${location}`);\n for (const issue of hotspot.issues) {\n lines.push(`- ${issue}`);\n }\n\n // Add recommendation based on issues\n if (hotspot.function) {\n if (hotspot.metrics.cognitiveComplexity && hotspot.metrics.cognitiveComplexity > thresholds.cognitiveComplexity) {\n lines.push(`- **Recommendation**: Extract logic into smaller, focused methods`);\n } else if (hotspot.metrics.lineCount && hotspot.metrics.lineCount > thresholds.functionSize) {\n lines.push(`- **Recommendation**: Split into multiple functions with single responsibilities`);\n }\n } else {\n lines.push(`- **Recommendation**: Consider splitting this file into smaller modules`);\n }\n lines.push('');\n }\n } else {\n lines.push('No hotspots found. Code quality is within acceptable thresholds.');\n }\n\n return lines.join('\\n');\n}\n\n// ============================================================================\n// SonarCloud-inspired Detections (S1144, S1192, S3459)\n// ============================================================================\n\n/**\n * Detect unused private members (S1144)\n * Finds private methods and fields that are never referenced in the same file\n */\nfunction detectUnusedMembers(content: string, file: string): UnusedMember[] {\n const unusedMembers: UnusedMember[] = [];\n\n // Find private methods in C#\n const privateMethodPattern = /\\b(private|internal)\\s+(?:async\\s+)?(?:static\\s+)?[\\w<>,\\s\\[\\]]+\\s+(\\w+)\\s*\\(/gm;\n let match;\n\n while ((match = privateMethodPattern.exec(content)) !== null) {\n const visibility = match[1] as 'private' | 'internal';\n const methodName = match[2];\n const line = getLineNumber(content, match.index);\n\n // Skip constructors, property accessors, and common patterns\n if (['get', 'set', 'Dispose', 'InitializeComponent'].includes(methodName)) continue;\n\n // Count occurrences of the method name (excluding the declaration itself)\n const regex = new RegExp(`\\\\b${methodName}\\\\b`, 'g');\n const occurrences = (content.match(regex) || []).length;\n\n // If only 1 occurrence (the declaration), it's unused\n if (occurrences === 1) {\n unusedMembers.push({\n name: methodName,\n type: 'method',\n visibility,\n file,\n line,\n rule: 'S1144',\n });\n }\n }\n\n // Find private fields in C#\n const privateFieldPattern = /\\b(private|internal)\\s+(?:readonly\\s+)?(?:static\\s+)?[\\w<>,\\[\\]]+\\s+_?(\\w+)\\s*[;=]/gm;\n\n while ((match = privateFieldPattern.exec(content)) !== null) {\n const visibility = match[1] as 'private' | 'internal';\n const fieldName = match[2];\n const line = getLineNumber(content, match.index);\n\n // Count occurrences\n const regex = new RegExp(`\\\\b${fieldName}\\\\b`, 'g');\n const occurrences = (content.match(regex) || []).length;\n\n if (occurrences === 1) {\n unusedMembers.push({\n name: fieldName,\n type: 'field',\n visibility,\n file,\n line,\n rule: 'S1144',\n });\n }\n }\n\n return unusedMembers;\n}\n\n/**\n * Detect duplicated string literals (S1192)\n * Finds string literals that appear 3+ times and should be constants\n */\nfunction detectDuplicatedStrings(\n fileContents: Map<string, string>\n): DuplicatedString[] {\n const stringOccurrences = new Map<string, Array<{ file: string; line: number }>>();\n\n for (const [file, content] of fileContents) {\n // Find all string literals (double-quoted)\n const stringPattern = /\"([^\"\\\\]|\\\\.){5,}\"/g;\n let match;\n\n while ((match = stringPattern.exec(content)) !== null) {\n const literal = match[0];\n const line = getLineNumber(content, match.index);\n\n // Skip common patterns that shouldn't be constants\n if (isIgnoredStringLiteral(literal)) continue;\n\n if (!stringOccurrences.has(literal)) {\n stringOccurrences.set(literal, []);\n }\n stringOccurrences.get(literal)!.push({ file, line });\n }\n }\n\n // Filter to only those with 3+ occurrences\n const duplicated: DuplicatedString[] = [];\n\n for (const [literal, locations] of stringOccurrences) {\n if (locations.length >= 3) {\n duplicated.push({\n literal,\n occurrences: locations.length,\n locations: locations.slice(0, 5), // Limit to 5 examples\n suggestedConstantName: suggestConstantName(literal),\n rule: 'S1192',\n });\n }\n }\n\n // Sort by occurrences descending\n duplicated.sort((a, b) => b.occurrences - a.occurrences);\n\n return duplicated.slice(0, 10); // Limit to top 10\n}\n\nfunction isIgnoredStringLiteral(literal: string): boolean {\n const ignoredPatterns = [\n /^\"\\s*\"$/, // Empty or whitespace\n /^\"[,.\\-:;\\/\\\\]+\"$/, // Punctuation only\n /^\"https?:\\/\\//, // URLs\n /^\"[a-z]{1,4}:\"$/i, // Protocol prefixes\n /^\"\\{[0-9]+\\}\"$/, // Format placeholders\n /^\"[a-z_]+:[a-z_]+\"$/i, // Resource keys\n ];\n\n return ignoredPatterns.some(p => p.test(literal));\n}\n\nfunction suggestConstantName(literal: string): string {\n // Remove quotes and convert to constant name\n const content = literal.slice(1, -1);\n\n // Take first few words\n const words = content\n .replace(/[^a-zA-Z0-9\\s]/g, ' ')\n .split(/\\s+/)\n .filter(w => w.length > 0)\n .slice(0, 4);\n\n if (words.length === 0) return 'STRING_CONSTANT';\n\n return words\n .map(w => w.toUpperCase())\n .join('_');\n}\n\n/**\n * Detect unassigned fields (S3459)\n * Finds fields that are declared but never assigned a value\n */\nfunction detectUnassignedFields(content: string, file: string): UnassignedField[] {\n const unassignedFields: UnassignedField[] = [];\n\n // Find field declarations without initializers\n const fieldPattern = /\\b(private|protected|internal|public)\\s+(?:readonly\\s+)?(\\w+(?:<[^>]+>)?)\\s+(\\w+)\\s*;/gm;\n let match;\n\n while ((match = fieldPattern.exec(content)) !== null) {\n const fieldType = match[2];\n const fieldName = match[3];\n const line = getLineNumber(content, match.index);\n\n // Check if the field is ever assigned (look for \"fieldName = \" or \"fieldName=\")\n const assignmentPattern = new RegExp(`\\\\b${fieldName}\\\\s*=`, 'g');\n const assignments = content.match(assignmentPattern) || [];\n\n // Check constructor assignments\n const constructorAssignmentPattern = new RegExp(`this\\\\.${fieldName}\\\\s*=`, 'g');\n const constructorAssignments = content.match(constructorAssignmentPattern) || [];\n\n // If no assignments found, it's unassigned\n if (assignments.length === 0 && constructorAssignments.length === 0) {\n unassignedFields.push({\n name: fieldName,\n type: fieldType,\n file,\n line,\n rule: 'S3459',\n });\n }\n }\n\n return unassignedFields;\n}\n\n// ============================================================================\n// Extended Report Formatting\n// ============================================================================\n\nfunction formatExtendedReport(\n result: CodeQualityResult,\n thresholds: typeof THRESHOLDS.normal,\n unusedMembers: UnusedMember[],\n duplicatedStrings: DuplicatedString[],\n unassignedFields: UnassignedField[]\n): string {\n // Start with base report\n let report = formatQualityReport(result, thresholds);\n\n // Add SonarCloud-inspired detections\n if (unusedMembers.length > 0 || duplicatedStrings.length > 0 || unassignedFields.length > 0) {\n report += '\\n\\n## SonarCloud-Style Detections\\n';\n\n if (unusedMembers.length > 0) {\n report += '\\n### 🔍 Unused Private Members (S1144)\\n';\n report += `Found ${unusedMembers.length} unused private members:\\n\\n`;\n for (const member of unusedMembers.slice(0, 10)) {\n report += `- \\`${member.name}\\` (${member.type}) in \\`${member.file}:${member.line}\\`\\n`;\n }\n if (unusedMembers.length > 10) {\n report += `\\n... and ${unusedMembers.length - 10} more\\n`;\n }\n }\n\n if (duplicatedStrings.length > 0) {\n report += '\\n### 🔄 Duplicated String Literals (S1192)\\n';\n report += `Found ${duplicatedStrings.length} duplicated strings (3+ occurrences):\\n\\n`;\n for (const dup of duplicatedStrings) {\n const truncated = dup.literal.length > 50\n ? dup.literal.slice(0, 47) + '...\"'\n : dup.literal;\n report += `- ${truncated} (${dup.occurrences}x) → suggested: \\`${dup.suggestedConstantName}\\`\\n`;\n }\n }\n\n if (unassignedFields.length > 0) {\n report += '\\n### ⚠️ Unassigned Fields (S3459)\\n';\n report += `Found ${unassignedFields.length} fields that are never assigned:\\n\\n`;\n for (const field of unassignedFields.slice(0, 10)) {\n report += `- \\`${field.type} ${field.name}\\` in \\`${field.file}:${field.line}\\`\\n`;\n }\n if (unassignedFields.length > 10) {\n report += `\\n... and ${unassignedFields.length - 10} more\\n`;\n }\n }\n }\n\n return report;\n}\n","import { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport {\n AnalyzeHierarchyPatternsInputSchema,\n type Config,\n type HierarchyAnalysisResult,\n type EntityHierarchyNode,\n type HierarchyPatternRecommendation,\n} 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 analyzeHierarchyPatternsTool: Tool = {\n name: 'analyze_hierarchy_patterns',\n description: `Analyze parent-child relationships in SmartStack entities and recommend optimal hierarchy patterns.\n\nDetects:\n- Direct parent-child relationships (via foreign keys)\n- Self-referencing hierarchies (ParentId pointing to same entity)\n- Inheritance chains (entity extending another entity)\n- Collection relationships (ICollection<T>)\n\nRecommends patterns based on usage:\n- **TVF + CTE**: Deep hierarchies with frequent traversal (permissions, org charts)\n- **Materialized Path**: Deep hierarchies with frequent modifications\n- **Simple ParentId**: Shallow hierarchies (2-3 levels)\n- **Nested Sets**: Read-heavy, rarely modified trees\n- **Closure Table**: All operations need to be fast`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to analyze (default: SmartStack.app path from config)',\n },\n entityFilter: {\n type: 'string',\n description: 'Filter entities by name pattern (e.g., \"User*\", \"*Group*\")',\n },\n includeRecommendations: {\n type: 'boolean',\n default: true,\n description: 'Include pattern recommendations for each hierarchy',\n },\n outputFormat: {\n type: 'string',\n enum: ['summary', 'detailed', 'json'],\n default: 'detailed',\n description: 'Output format',\n },\n },\n },\n};\n\nexport async function handleAnalyzeHierarchyPatterns(\n args: unknown,\n config: Config\n): Promise<string> {\n const input = AnalyzeHierarchyPatternsInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n const includeRecommendations = input.includeRecommendations ?? true;\n const outputFormat = input.outputFormat || 'detailed';\n\n logger.info('Analyzing hierarchy patterns', { projectPath });\n\n const structure = await findSmartStackStructure(projectPath);\n\n if (!structure.domain) {\n return '# Error\\n\\nDomain project not found. Cannot analyze entity hierarchies.';\n }\n\n // Build entity graph\n const entityGraph = await buildEntityGraph(structure.domain, input.entityFilter);\n\n // Detect hierarchies\n const hierarchies = detectHierarchies(entityGraph);\n\n // Generate recommendations\n const recommendations = includeRecommendations\n ? generateRecommendations(hierarchies, entityGraph)\n : [];\n\n // Build result\n const result: HierarchyAnalysisResult = {\n totalEntities: entityGraph.size,\n hierarchicalEntities: hierarchies.filter(h => h.isHierarchical).length,\n selfReferencingEntities: hierarchies.filter(h => h.isSelfReferencing).length,\n maxDepth: Math.max(0, ...hierarchies.map(h => h.depth)),\n hierarchies,\n recommendations,\n circularDependencies: detectCircularDependencies(entityGraph),\n };\n\n return formatResult(result, outputFormat, structure.root);\n}\n\n// =============================================================================\n// Entity Graph Building\n// =============================================================================\n\ninterface ParsedEntity {\n name: string;\n file: string;\n baseClass: string;\n isTenantAware: boolean;\n isSystemEntity: boolean;\n parentEntity?: string; // From baseEntity option or FK pattern\n selfReferenceField?: string; // ParentId pointing to same entity\n childCollections: string[]; // ICollection<ChildEntity>\n foreignKeys: ForeignKeyInfo[];\n}\n\ninterface ForeignKeyInfo {\n propertyName: string;\n referencedEntity: string;\n isNavigationProperty: boolean;\n}\n\nasync function buildEntityGraph(\n domainPath: string,\n filter?: string\n): Promise<Map<string, EntityHierarchyNode>> {\n const entityFiles = await findFiles('**/*.cs', { cwd: domainPath });\n const entityMap = new Map<string, EntityHierarchyNode>();\n const parsedEntities: ParsedEntity[] = [];\n\n // Step 1: Parse all entities\n for (const file of entityFiles) {\n const content = await readText(file);\n const parsed = parseEntity(content, file, domainPath);\n\n if (parsed && (!filter || matchesFilter(parsed.name, filter))) {\n parsedEntities.push(parsed);\n }\n }\n\n // Step 2: Create nodes\n for (const entity of parsedEntities) {\n entityMap.set(entity.name, {\n name: entity.name,\n file: entity.file,\n baseClass: entity.baseClass,\n isTenantAware: entity.isTenantAware,\n isSystemEntity: entity.isSystemEntity,\n parent: null,\n children: [],\n depth: 0,\n isRoot: true,\n isLeaf: true,\n isSelfReferencing: !!entity.selfReferenceField,\n selfReferenceField: entity.selfReferenceField,\n childCollections: entity.childCollections,\n foreignKeys: entity.foreignKeys,\n isHierarchical: false,\n });\n }\n\n // Step 3: Link relationships\n for (const entity of parsedEntities) {\n const node = entityMap.get(entity.name)!;\n\n // Link parent from FK relationships\n if (entity.parentEntity && entityMap.has(entity.parentEntity)) {\n const parent = entityMap.get(entity.parentEntity)!;\n node.parent = parent.name;\n node.isRoot = false;\n parent.children.push(entity.name);\n parent.isLeaf = false;\n }\n\n // Mark as hierarchical if has children or self-reference\n if (entity.childCollections.length > 0 || entity.selfReferenceField) {\n node.isHierarchical = true;\n }\n }\n\n // Step 4: Calculate depths\n for (const node of entityMap.values()) {\n node.depth = calculateDepth(node.name, entityMap, new Set());\n }\n\n // Step 5: Mark hierarchical based on children\n for (const node of entityMap.values()) {\n if (node.children.length > 0) {\n node.isHierarchical = true;\n }\n }\n\n return entityMap;\n}\n\nfunction parseEntity(content: string, file: string, domainPath: string): ParsedEntity | null {\n // Skip non-entity files\n const fileName = path.basename(file, '.cs');\n if (\n fileName.endsWith('Dto') ||\n fileName.endsWith('Command') ||\n fileName.endsWith('Query') ||\n fileName.endsWith('Handler') ||\n fileName.endsWith('Validator') ||\n fileName.endsWith('Exception') ||\n fileName.startsWith('I')\n ) {\n return null;\n }\n\n // Check for class declaration\n const classMatch = content.match(\n /public\\s+(?:class|record)\\s+(\\w+)(?:\\s*:\\s*([^{]+))?/\n );\n if (!classMatch) return null;\n\n const entityName = classMatch[1];\n const inheritance = classMatch[2]?.trim() || '';\n\n // Must be an entity (inherit from BaseEntity or SystemEntity)\n const hasBaseEntity = inheritance.includes('BaseEntity');\n const hasSystemEntity = inheritance.includes('SystemEntity');\n if (!hasBaseEntity && !hasSystemEntity) return null;\n\n const hasITenantEntity = inheritance.includes('ITenantEntity');\n\n // Detect self-referencing (ParentId of same type)\n const selfRefMatch = content.match(\n new RegExp(`public\\\\s+(?:Guid\\\\??|${entityName}\\\\??)\\\\s+(Parent(?:Id)?|Parent${entityName}(?:Id)?)\\\\s*\\\\{`, 'i')\n );\n const selfReferenceField = selfRefMatch ? selfRefMatch[1] : undefined;\n\n // Detect child collections\n const childCollections: string[] = [];\n const collectionMatches = content.matchAll(\n /public\\s+(?:virtual\\s+)?ICollection<(\\w+)>\\s+(\\w+)\\s*\\{/g\n );\n for (const match of collectionMatches) {\n childCollections.push(match[1]);\n }\n\n // Detect foreign keys\n const foreignKeys: ForeignKeyInfo[] = [];\n const fkMatches = content.matchAll(\n /public\\s+Guid\\s+(\\w+Id)\\s*\\{[^}]+\\}/g\n );\n for (const match of fkMatches) {\n const propName = match[1];\n // Skip self-reference\n if (selfReferenceField && propName.toLowerCase().includes('parent')) continue;\n // Extract referenced entity name\n const referencedEntity = propName.replace(/Id$/, '');\n if (referencedEntity !== entityName) {\n foreignKeys.push({\n propertyName: propName,\n referencedEntity,\n isNavigationProperty: content.includes(`public virtual ${referencedEntity}?`),\n });\n }\n }\n\n // Determine parent entity from foreign keys\n const parentEntity = foreignKeys.length > 0 ? foreignKeys[0].referencedEntity : undefined;\n\n return {\n name: entityName,\n file: path.relative(domainPath, file),\n baseClass: hasSystemEntity ? 'SystemEntity' : 'BaseEntity',\n isTenantAware: hasITenantEntity,\n isSystemEntity: hasSystemEntity,\n parentEntity,\n selfReferenceField,\n childCollections,\n foreignKeys,\n };\n}\n\nfunction matchesFilter(name: string, filter: string): boolean {\n const pattern = filter\n .replace(/\\*/g, '.*')\n .replace(/\\?/g, '.');\n return new RegExp(`^${pattern}$`, 'i').test(name);\n}\n\nfunction calculateDepth(\n name: string,\n entityMap: Map<string, EntityHierarchyNode>,\n visited: Set<string>\n): number {\n if (visited.has(name)) return -1; // Circular dependency\n const node = entityMap.get(name);\n if (!node || !node.parent) return 0;\n\n visited.add(name);\n const parentDepth = calculateDepth(node.parent, entityMap, visited);\n return parentDepth === -1 ? -1 : parentDepth + 1;\n}\n\n// =============================================================================\n// Hierarchy Detection\n// =============================================================================\n\nfunction detectHierarchies(\n entityMap: Map<string, EntityHierarchyNode>\n): EntityHierarchyNode[] {\n return Array.from(entityMap.values()).filter(\n node => node.isHierarchical || node.isSelfReferencing || node.children.length > 0\n );\n}\n\nfunction detectCircularDependencies(\n entityMap: Map<string, EntityHierarchyNode>\n): string[][] {\n const cycles: string[][] = [];\n\n for (const [name] of entityMap) {\n const visited = new Set<string>();\n const path: string[] = [];\n\n function dfs(current: string): boolean {\n if (path.includes(current)) {\n const cycleStart = path.indexOf(current);\n cycles.push([...path.slice(cycleStart), current]);\n return true;\n }\n if (visited.has(current)) return false;\n\n visited.add(current);\n path.push(current);\n\n const node = entityMap.get(current);\n if (node?.parent) {\n dfs(node.parent);\n }\n\n path.pop();\n return false;\n }\n\n dfs(name);\n }\n\n // Remove duplicate cycles\n const unique = new Map<string, string[]>();\n for (const cycle of cycles) {\n const key = [...cycle].sort().join(',');\n if (!unique.has(key)) {\n unique.set(key, cycle);\n }\n }\n\n return Array.from(unique.values());\n}\n\n// =============================================================================\n// Recommendations\n// =============================================================================\n\nfunction generateRecommendations(\n hierarchies: EntityHierarchyNode[],\n entityMap: Map<string, EntityHierarchyNode>\n): HierarchyPatternRecommendation[] {\n const recommendations: HierarchyPatternRecommendation[] = [];\n\n for (const hierarchy of hierarchies) {\n const rec = analyzeHierarchy(hierarchy, entityMap);\n if (rec) {\n recommendations.push(rec);\n }\n }\n\n return recommendations;\n}\n\nfunction analyzeHierarchy(\n node: EntityHierarchyNode,\n entityMap: Map<string, EntityHierarchyNode>\n): HierarchyPatternRecommendation | null {\n // Only analyze root hierarchical entities or self-referencing entities\n if (!node.isRoot && !node.isSelfReferencing) return null;\n\n // Calculate hierarchy metrics\n const depth = calculateMaxChildDepth(node, entityMap);\n const totalNodes = countDescendants(node, entityMap) + 1;\n const hasPermissionPattern = node.name.toLowerCase().includes('permission') ||\n node.name.toLowerCase().includes('role') ||\n node.name.toLowerCase().includes('group');\n\n // Determine recommended pattern\n let pattern: 'tvf-cte' | 'materialized-path' | 'simple-parentid' | 'nested-sets' | 'closure-table';\n let reason: string;\n let priority: 'critical' | 'high' | 'medium' | 'low';\n let sqlTemplate: string | undefined;\n\n if (node.isSelfReferencing) {\n // Self-referencing hierarchy\n if (depth > 3 || hasPermissionPattern) {\n pattern = 'tvf-cte';\n reason = `Self-referencing hierarchy with variable depth. ${hasPermissionPattern ? 'Permission/Group pattern detected - TVF recommended for recursive permission resolution.' : ''}`;\n priority = hasPermissionPattern ? 'critical' : 'high';\n sqlTemplate = generateTvfTemplate(node);\n } else if (depth <= 3) {\n pattern = 'simple-parentid';\n reason = 'Shallow self-referencing hierarchy (depth <= 3). Simple ParentId with eager loading is sufficient.';\n priority = 'low';\n } else {\n pattern = 'materialized-path';\n reason = 'Deep self-referencing hierarchy. Consider Materialized Path for efficient ancestor/descendant queries.';\n priority = 'medium';\n }\n } else if (node.children.length > 0) {\n // Parent-child relationship\n if (depth > 2) {\n pattern = 'tvf-cte';\n reason = `Multi-level parent-child hierarchy (depth: ${depth}). TVF with CTE recommended for efficient traversal.`;\n priority = 'medium';\n sqlTemplate = generateTvfTemplate(node);\n } else {\n pattern = 'simple-parentid';\n reason = `Simple two-level parent-child relationship. Standard FK relationship is optimal.`;\n priority = 'low';\n }\n } else {\n return null;\n }\n\n return {\n entityName: node.name,\n currentPattern: node.isSelfReferencing ? 'self-referencing' : 'parent-child',\n recommendedPattern: pattern,\n reason,\n priority,\n hierarchyDepth: depth,\n estimatedNodes: totalNodes,\n sqlTemplate,\n implementationSteps: getImplementationSteps(pattern, node),\n };\n}\n\nfunction calculateMaxChildDepth(\n node: EntityHierarchyNode,\n entityMap: Map<string, EntityHierarchyNode>,\n visited: Set<string> = new Set()\n): number {\n if (visited.has(node.name)) return 0;\n visited.add(node.name);\n\n if (node.isSelfReferencing) {\n // For self-referencing, we estimate based on typical usage\n // Real depth would require runtime data analysis\n return 5; // Assume variable depth\n }\n\n if (node.children.length === 0) return 0;\n\n let maxChildDepth = 0;\n for (const childName of node.children) {\n const child = entityMap.get(childName);\n if (child) {\n const childDepth = calculateMaxChildDepth(child, entityMap, visited);\n maxChildDepth = Math.max(maxChildDepth, childDepth);\n }\n }\n\n return maxChildDepth + 1;\n}\n\nfunction countDescendants(\n node: EntityHierarchyNode,\n entityMap: Map<string, EntityHierarchyNode>,\n visited: Set<string> = new Set()\n): number {\n if (visited.has(node.name)) return 0;\n visited.add(node.name);\n\n let count = 0;\n for (const childName of node.children) {\n const child = entityMap.get(childName);\n if (child) {\n count += 1 + countDescendants(child, entityMap, visited);\n }\n }\n\n return count;\n}\n\nfunction generateTvfTemplate(node: EntityHierarchyNode): string {\n const tableName = `${node.name}s`;\n const idField = 'Id';\n const parentField = node.selfReferenceField || 'ParentId';\n\n return `-- Table-Valued Function with Recursive CTE\n-- Returns all ancestors/descendants for ${node.name}\nCREATE OR ALTER FUNCTION [core].[fn_Get${node.name}Hierarchy]\n(\n @${node.name}Id UNIQUEIDENTIFIER,\n @Direction VARCHAR(10) = 'ancestors' -- 'ancestors' or 'descendants'\n)\nRETURNS TABLE\nAS\nRETURN\n(\n WITH Hierarchy AS (\n -- Base case: starting node\n SELECT\n ${idField},\n ${parentField},\n 0 AS Level,\n CAST(${idField} AS VARCHAR(MAX)) AS Path\n FROM core.${tableName}\n WHERE ${idField} = @${node.name}Id\n AND IsDeleted = 0\n\n UNION ALL\n\n -- Recursive case: traverse hierarchy\n SELECT\n t.${idField},\n t.${parentField},\n h.Level + 1,\n h.Path + '/' + CAST(t.${idField} AS VARCHAR(MAX))\n FROM core.${tableName} t\n INNER JOIN Hierarchy h ON\n CASE @Direction\n WHEN 'ancestors' THEN t.${idField}\n WHEN 'descendants' THEN t.${parentField}\n END =\n CASE @Direction\n WHEN 'ancestors' THEN h.${parentField}\n WHEN 'descendants' THEN h.${idField}\n END\n WHERE t.IsDeleted = 0\n AND h.Level < 50 -- Prevent infinite recursion\n )\n SELECT\n ${idField},\n ${parentField},\n Level,\n Path\n FROM Hierarchy\n);\nGO\n\n-- Usage example:\n-- SELECT * FROM core.fn_Get${node.name}Hierarchy(@id, 'descendants');\n-- SELECT * FROM core.fn_Get${node.name}Hierarchy(@id, 'ancestors');`;\n}\n\nfunction getImplementationSteps(\n pattern: string,\n node: EntityHierarchyNode\n): string[] {\n switch (pattern) {\n case 'tvf-cte':\n return [\n `1. Create migration with TVF: fn_Get${node.name}Hierarchy`,\n `2. Add method to I${node.name}Repository: GetHierarchyAsync(Guid id, HierarchyDirection direction)`,\n `3. Implement using raw SQL: _context.Database.SqlQuery<${node.name}HierarchyDto>(...)`,\n `4. Create ${node.name}HierarchyDto with Id, ParentId, Level, Path`,\n `5. Add unit tests for hierarchy traversal (ancestors/descendants)`,\n ];\n case 'materialized-path':\n return [\n `1. Add Path column to ${node.name}: public string Path { get; private set; } // e.g., \"/1/3/5/\"`,\n `2. Add PathDepth computed column or property`,\n `3. Create index on Path for prefix queries`,\n `4. Update Create/Update methods to maintain Path`,\n `5. Query ancestors: WHERE @path LIKE Path + '%'`,\n `6. Query descendants: WHERE Path LIKE @path + '%'`,\n ];\n case 'simple-parentid':\n return [\n `1. Ensure ${node.selfReferenceField || 'ParentId'} FK is configured`,\n `2. Add navigation property: public virtual ${node.name}? Parent { get; }`,\n `3. Add children collection: public virtual ICollection<${node.name}> Children { get; }`,\n `4. Use .Include() for eager loading when needed`,\n ];\n case 'nested-sets':\n return [\n `1. Add Left and Right columns (int)`,\n `2. Implement tree rebuild on modifications`,\n `3. Query descendants: WHERE Left > @left AND Right < @right`,\n `4. Query ancestors: WHERE Left < @left AND Right > @right`,\n `5. Warning: Updates are expensive - only use for read-heavy scenarios`,\n ];\n case 'closure-table':\n return [\n `1. Create ${node.name}Closure table: (AncestorId, DescendantId, Depth)`,\n `2. Populate closure table on Create/Update`,\n `3. Query all ancestors: WHERE DescendantId = @id`,\n `4. Query all descendants: WHERE AncestorId = @id`,\n `5. Maintain closure table on hierarchy changes`,\n ];\n default:\n return [];\n }\n}\n\n// =============================================================================\n// Output Formatting\n// =============================================================================\n\nfunction formatResult(\n result: HierarchyAnalysisResult,\n format: string,\n _rootPath: string\n): string {\n if (format === 'json') {\n return JSON.stringify(result, null, 2);\n }\n\n const lines: string[] = [];\n\n lines.push('# Entity Hierarchy Analysis');\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push(`| Metric | Value |`);\n lines.push(`|--------|-------|`);\n lines.push(`| Total Entities | ${result.totalEntities} |`);\n lines.push(`| Hierarchical Entities | ${result.hierarchicalEntities} |`);\n lines.push(`| Self-Referencing | ${result.selfReferencingEntities} |`);\n lines.push(`| Max Depth | ${result.maxDepth} |`);\n lines.push('');\n\n // Circular Dependencies\n if (result.circularDependencies.length > 0) {\n lines.push('## ⚠️ Circular Dependencies Detected');\n lines.push('');\n for (const cycle of result.circularDependencies) {\n lines.push(`- ${cycle.join(' → ')}`);\n }\n lines.push('');\n }\n\n // Hierarchies\n if (result.hierarchies.length > 0) {\n lines.push('## Detected Hierarchies');\n lines.push('');\n\n for (const h of result.hierarchies) {\n const icon = h.isSelfReferencing ? '🔄' : '📂';\n lines.push(`### ${icon} ${h.name}`);\n lines.push('');\n lines.push(`| Property | Value |`);\n lines.push(`|----------|-------|`);\n lines.push(`| File | \\`${h.file}\\` |`);\n lines.push(`| Type | ${h.isSelfReferencing ? 'Self-referencing' : 'Parent-child'} |`);\n lines.push(`| Tenant-aware | ${h.isTenantAware ? 'Yes' : 'No'} |`);\n lines.push(`| Depth | ${h.depth} |`);\n\n if (h.selfReferenceField) {\n lines.push(`| Self-ref field | \\`${h.selfReferenceField}\\` |`);\n }\n\n if (h.children.length > 0) {\n lines.push(`| Children | ${h.children.join(', ')} |`);\n }\n\n if (h.childCollections.length > 0) {\n lines.push(`| Collections | ${h.childCollections.join(', ')} |`);\n }\n\n lines.push('');\n }\n }\n\n // Recommendations\n if (result.recommendations.length > 0) {\n lines.push('## Pattern Recommendations');\n lines.push('');\n\n const priorityOrder = ['critical', 'high', 'medium', 'low'];\n const sorted = [...result.recommendations].sort(\n (a, b) => priorityOrder.indexOf(a.priority) - priorityOrder.indexOf(b.priority)\n );\n\n for (const rec of sorted) {\n const priorityIcon = {\n critical: '🔴',\n high: '🟠',\n medium: '🟡',\n low: '🟢',\n }[rec.priority];\n\n lines.push(`### ${priorityIcon} ${rec.entityName}`);\n lines.push('');\n lines.push(`**Recommended Pattern**: \\`${rec.recommendedPattern}\\``);\n lines.push('');\n lines.push(`**Reason**: ${rec.reason}`);\n lines.push('');\n lines.push(`**Priority**: ${rec.priority.toUpperCase()}`);\n lines.push('');\n\n if (format === 'detailed') {\n lines.push('#### Implementation Steps');\n lines.push('');\n for (const step of rec.implementationSteps) {\n lines.push(step);\n }\n lines.push('');\n\n if (rec.sqlTemplate) {\n lines.push('#### SQL Template');\n lines.push('');\n lines.push('```sql');\n lines.push(rec.sqlTemplate);\n lines.push('```');\n lines.push('');\n }\n }\n }\n }\n\n // Legend\n lines.push('---');\n lines.push('');\n lines.push('## Pattern Legend');\n lines.push('');\n lines.push('| Pattern | Best For | Trade-offs |');\n lines.push('|---------|----------|------------|');\n lines.push('| **TVF + CTE** | Deep hierarchies, frequent traversal | Requires SQL Server, slightly more complex |');\n lines.push('| **Materialized Path** | Deep hierarchies, frequent modifications | Path maintenance overhead |');\n lines.push('| **Simple ParentId** | Shallow hierarchies (2-3 levels) | N+1 queries on deep traversal |');\n lines.push('| **Nested Sets** | Read-heavy, rarely modified | Expensive updates |');\n lines.push('| **Closure Table** | All operations fast | Storage overhead (N² entries) |');\n\n return lines.join('\\n');\n}\n","/**\n * Types for the review_code tool\n * Comprehensive code review system for SmartStack projects\n */\n\n// ============================================================================\n// Review Categories\n// ============================================================================\n\nexport type ReviewCategory =\n | 'security'\n | 'architecture'\n | 'hardcoded-values'\n | 'tests'\n | 'ai-hallucinations'\n | 'performance'\n | 'dead-code'\n | 'i18n'\n | 'accessibility';\n\nexport type ReviewSeverity = 'blocking' | 'critical' | 'warning' | 'info';\n\n// ============================================================================\n// Finding Types\n// ============================================================================\n\nexport interface CodeReviewFinding {\n /** Unique ID (ex: SEC-001, ARCH-002) */\n id: string;\n /** Category of the finding */\n category: ReviewCategory;\n /** Severity level */\n severity: ReviewSeverity;\n /** Short title */\n title: string;\n /** Detailed description */\n description: string;\n /** File path (relative to project root) */\n file: string;\n /** Line number */\n line?: number;\n /** Column number */\n column?: number;\n /** Code snippet (max 100 chars) */\n code?: string;\n /** Suggested fix */\n suggestion: string;\n /** Can be auto-fixed */\n autoFixable: boolean;\n /** CWE ID for security issues */\n cweId?: string;\n /** References to documentation */\n references?: string[];\n}\n\n// ============================================================================\n// Result Types\n// ============================================================================\n\nexport interface CodeReviewSummary {\n /** Overall status */\n status: 'passed' | 'failed' | 'warning';\n /** Score 0-100 */\n score: number;\n /** Letter grade */\n grade: 'A' | 'B' | 'C' | 'D' | 'F';\n /** Summary message */\n message: string;\n}\n\nexport interface CodeReviewStats {\n filesScanned: number;\n linesScanned: number;\n duration: number; // ms\n findingsCount: {\n blocking: number;\n critical: number;\n warning: number;\n info: number;\n };\n byCategory: Record<ReviewCategory, number>;\n}\n\nexport interface CodeReviewResult {\n summary: CodeReviewSummary;\n findings: CodeReviewFinding[];\n stats: CodeReviewStats;\n}\n\n// ============================================================================\n// Check Function Types\n// ============================================================================\n\nexport interface CheckContext {\n projectPath: string;\n files: FileInfo[];\n scope: 'all' | 'changed' | 'staged';\n}\n\nexport interface FileInfo {\n path: string;\n relativePath: string;\n content: string;\n language: 'csharp' | 'typescript' | 'javascript' | 'tsx' | 'jsx' | 'css' | 'json' | 'other';\n layer?: 'domain' | 'application' | 'infrastructure' | 'api' | 'web';\n lineCount: number;\n}\n\nexport type CheckFunction = (context: CheckContext) => Promise<CodeReviewFinding[]>;\n\n// ============================================================================\n// Architecture Layer Rules\n// ============================================================================\n\nexport const LAYER_RULES: Record<string, { canImport: string[]; cannotImport: string[] }> = {\n domain: {\n canImport: [],\n cannotImport: ['application', 'infrastructure', 'api', 'web'],\n },\n application: {\n canImport: ['domain'],\n cannotImport: ['infrastructure', 'api', 'web'],\n },\n infrastructure: {\n canImport: ['domain', 'application'],\n cannotImport: ['api', 'web'],\n },\n api: {\n canImport: ['domain', 'application', 'infrastructure'],\n cannotImport: ['web'],\n },\n web: {\n canImport: ['domain', 'application'],\n cannotImport: ['infrastructure'],\n },\n};\n\n// ============================================================================\n// Finding ID Prefixes\n// ============================================================================\n\nexport const FINDING_PREFIXES: Record<ReviewCategory, string> = {\n security: 'SEC',\n architecture: 'ARCH',\n 'hardcoded-values': 'HARD',\n tests: 'TEST',\n 'ai-hallucinations': 'AI',\n performance: 'PERF',\n 'dead-code': 'DEAD',\n i18n: 'I18N',\n accessibility: 'A11Y',\n};\n\n// ============================================================================\n// ID Generator\n// ============================================================================\n\nconst findingCounters: Record<string, number> = {};\n\nexport function generateFindingId(category: ReviewCategory): string {\n const prefix = FINDING_PREFIXES[category];\n if (!findingCounters[prefix]) {\n findingCounters[prefix] = 0;\n }\n findingCounters[prefix]++;\n return `${prefix}-${String(findingCounters[prefix]).padStart(3, '0')}`;\n}\n\nexport function resetFindingCounters(): void {\n Object.keys(findingCounters).forEach((key) => {\n findingCounters[key] = 0;\n });\n}\n","/**\n * Security Check Module\n * Detects security vulnerabilities (OWASP Top 10)\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Patterns for detecting hardcoded secrets\nconst SECRET_PATTERNS = [\n { pattern: /[\"']sk[-_]live[-_][a-zA-Z0-9]{20,}[\"']/gi, name: 'Stripe Live Key' },\n { pattern: /[\"']sk[-_]test[-_][a-zA-Z0-9]{20,}[\"']/gi, name: 'Stripe Test Key' },\n { pattern: /[\"'][a-zA-Z0-9]{40}[\"']/g, name: 'Generic API Key (40 chars)' },\n { pattern: /password\\s*[=:]\\s*[\"'][^\"']{4,}[\"']/gi, name: 'Hardcoded Password' },\n { pattern: /apikey\\s*[=:]\\s*[\"'][^\"']{8,}[\"']/gi, name: 'Hardcoded API Key' },\n { pattern: /secret\\s*[=:]\\s*[\"'][^\"']{8,}[\"']/gi, name: 'Hardcoded Secret' },\n { pattern: /connectionstring\\s*[=:]\\s*[\"'][^\"']+[\"']/gi, name: 'Connection String' },\n { pattern: /Bearer\\s+[a-zA-Z0-9\\-_.]+/gi, name: 'Bearer Token' },\n { pattern: /-----BEGIN\\s+(RSA\\s+)?PRIVATE\\s+KEY-----/gi, name: 'Private Key' },\n];\n\n// SQL Injection patterns\nconst SQL_INJECTION_PATTERNS = [\n { pattern: /\\$[\"'`]SELECT\\s+.+\\s+FROM/gi, name: 'String interpolation in SQL' },\n { pattern: /\\+\\s*[\"'].*SELECT.*FROM/gi, name: 'Concatenation in SQL' },\n { pattern: /string\\.Format\\s*\\(\\s*[\"'].*SELECT/gi, name: 'String.Format with SQL' },\n { pattern: /ExecuteSqlRaw\\s*\\(\\s*\\$\"/gi, name: 'ExecuteSqlRaw with interpolation' },\n { pattern: /FromSqlRaw\\s*\\(\\s*\\$\"/gi, name: 'FromSqlRaw with interpolation' },\n];\n\n// XSS patterns\nconst XSS_PATTERNS = [\n { pattern: /innerHTML\\s*=/gi, name: 'innerHTML assignment' },\n { pattern: /dangerouslySetInnerHTML/gi, name: 'dangerouslySetInnerHTML' },\n { pattern: /document\\.write\\s*\\(/gi, name: 'document.write' },\n { pattern: /eval\\s*\\(/gi, name: 'eval() usage' },\n];\n\n// Authorization patterns (missing [Authorize])\nconst CONTROLLER_WITHOUT_AUTH = /\\[ApiController\\][\\s\\S]*?public\\s+class\\s+\\w+Controller/gi;\n\nexport async function checkSecurity(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n // Skip non-code files\n if (!['csharp', 'typescript', 'javascript', 'tsx', 'jsx'].includes(file.language)) {\n continue;\n }\n\n const lines = file.content.split('\\n');\n\n // Check for hardcoded secrets\n for (const { pattern, name } of SECRET_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if in comments\n if (isInComment(lineContent)) continue;\n\n findings.push({\n id: generateFindingId('security'),\n category: 'security',\n severity: 'blocking',\n title: `Hardcoded ${name}`,\n description: `Found a hardcoded ${name.toLowerCase()} in the source code. Secrets should never be committed to version control.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Move this secret to environment variables, Azure Key Vault, or a secure configuration provider.',\n autoFixable: false,\n cweId: 'CWE-798',\n references: ['https://cwe.mitre.org/data/definitions/798.html'],\n });\n }\n }\n\n // Check for SQL Injection (C# only)\n if (file.language === 'csharp') {\n for (const { pattern, name } of SQL_INJECTION_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent)) continue;\n\n findings.push({\n id: generateFindingId('security'),\n category: 'security',\n severity: 'blocking',\n title: 'Potential SQL Injection',\n description: `${name} detected. This pattern can lead to SQL injection vulnerabilities.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Use parameterized queries or EF Core LINQ methods instead of string interpolation.',\n autoFixable: false,\n cweId: 'CWE-89',\n references: ['https://cwe.mitre.org/data/definitions/89.html'],\n });\n }\n }\n\n // Check for missing [Authorize] on controllers\n const controllerMatch = CONTROLLER_WITHOUT_AUTH.exec(file.content);\n if (controllerMatch) {\n const hasAuthorize = /\\[Authorize\\]/i.test(file.content.slice(0, controllerMatch.index + 200));\n const hasAllowAnonymous = /\\[AllowAnonymous\\]/i.test(file.content.slice(0, controllerMatch.index + 200));\n const hasNavRoute = /\\[NavRoute\\(/i.test(file.content);\n\n if (!hasAuthorize && !hasAllowAnonymous && !hasNavRoute) {\n findings.push({\n id: generateFindingId('security'),\n category: 'security',\n severity: 'critical',\n title: 'Missing Authorization Attribute',\n description: 'This API controller does not have [Authorize], [AllowAnonymous], or [NavRoute] attribute.',\n file: file.relativePath,\n line: getLineNumber(file.content, controllerMatch.index),\n suggestion: 'Add [Authorize] or [NavRoute(\"...\")] attribute to secure the controller.',\n autoFixable: false,\n cweId: 'CWE-862',\n });\n }\n }\n }\n\n // Check for XSS (TypeScript/JavaScript/TSX/JSX)\n if (['typescript', 'javascript', 'tsx', 'jsx'].includes(file.language)) {\n for (const { pattern, name } of XSS_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent)) continue;\n\n // Skip if sanitization is nearby\n const contextStart = Math.max(0, match.index - 200);\n const contextEnd = Math.min(file.content.length, match.index + 200);\n const context = file.content.slice(contextStart, contextEnd).toLowerCase();\n if (context.includes('sanitize') || context.includes('dompurify') || context.includes('escape')) {\n continue;\n }\n\n findings.push({\n id: generateFindingId('security'),\n category: 'security',\n severity: 'critical',\n title: 'Potential XSS Vulnerability',\n description: `${name} detected without apparent sanitization. This can lead to Cross-Site Scripting attacks.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Sanitize user input before rendering. Use DOMPurify or React\\'s built-in escaping.',\n autoFixable: false,\n cweId: 'CWE-79',\n references: ['https://cwe.mitre.org/data/definitions/79.html'],\n });\n }\n }\n }\n }\n\n return findings;\n}\n\n// Helper functions\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n\nfunction isInComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*');\n}\n","/**\n * Architecture Check Module\n * Detects layer violations in Clean Architecture\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId, LAYER_RULES } from '../types.js';\n\n// Layer detection patterns for C#\nconst CSHARP_LAYER_PATTERNS: Record<string, RegExp[]> = {\n domain: [\n /namespace\\s+\\w+\\.Domain/i,\n /SmartStack\\.Domain/i,\n ],\n application: [\n /namespace\\s+\\w+\\.Application/i,\n /SmartStack\\.Application/i,\n ],\n infrastructure: [\n /namespace\\s+\\w+\\.Infrastructure/i,\n /SmartStack\\.Infrastructure/i,\n /\\.Persistence\\./i,\n /DbContext/i,\n ],\n api: [\n /namespace\\s+\\w+\\.Api/i,\n /SmartStack\\.Api/i,\n /\\[ApiController\\]/i,\n ],\n};\n\n// Import patterns to detect\nconst CSHARP_IMPORT_PATTERNS: Record<string, RegExp> = {\n domain: /using\\s+[\\w.]*\\.Domain[.\\w]*/gi,\n application: /using\\s+[\\w.]*\\.Application[.\\w]*/gi,\n infrastructure: /using\\s+[\\w.]*\\.Infrastructure[.\\w]*/gi,\n api: /using\\s+[\\w.]*\\.Api[.\\w]*/gi,\n};\n\n// TypeScript/React layer patterns\nconst TS_LAYER_VIOLATIONS = [\n {\n pattern: /from\\s+['\"].*Infrastructure.*['\"]/gi,\n layer: 'infrastructure',\n message: 'Web/React code should not import from Infrastructure layer',\n },\n {\n pattern: /from\\s+['\"].*\\.Api.*['\"]/gi,\n layer: 'api',\n message: 'Web/React code should not import from Api layer directly',\n },\n];\n\n// Direct DbContext usage patterns\nconst DIRECT_DB_PATTERNS = [\n {\n pattern: /private\\s+readonly\\s+\\w*DbContext/gi,\n name: 'Direct DbContext field',\n },\n {\n pattern: /new\\s+\\w*DbContext\\s*\\(/gi,\n name: 'DbContext instantiation',\n },\n {\n pattern: /IApplicationDbContext|ICoreDbContext/gi,\n name: 'DbContext interface',\n allowed: ['service', 'repository', 'handler'],\n },\n];\n\nexport async function checkArchitecture(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n const lines = file.content.split('\\n');\n\n // C# architecture checks\n if (file.language === 'csharp') {\n const fileLayer = detectCsharpLayer(file.content, file.relativePath);\n\n if (fileLayer && LAYER_RULES[fileLayer]) {\n const rules = LAYER_RULES[fileLayer];\n\n // Check for forbidden imports\n for (const forbiddenLayer of rules.cannotImport) {\n const importPattern = CSHARP_IMPORT_PATTERNS[forbiddenLayer];\n if (!importPattern) continue;\n\n let match;\n importPattern.lastIndex = 0;\n while ((match = importPattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('architecture'),\n category: 'architecture',\n severity: 'critical',\n title: `Layer Violation: ${capitalize(fileLayer)} → ${capitalize(forbiddenLayer)}`,\n description: `The ${capitalize(fileLayer)} layer should not import from the ${capitalize(forbiddenLayer)} layer. This violates Clean Architecture principles.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: `Remove this import. ${getSuggestionForViolation(fileLayer, forbiddenLayer)}`,\n autoFixable: false,\n });\n }\n }\n }\n\n // Check for direct DbContext usage in wrong places\n // isService and isRepository checks reserved for future use\n const isController = /Controller\\.cs$/i.test(file.relativePath);\n\n if (isController) {\n // Controllers should use services, not DbContext directly (unless SmartStack convention)\n for (const { pattern, name: _name } of DIRECT_DB_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n // SmartStack allows DbContext in controllers, but warn if complex queries\n const hasComplexQuery = /\\.Include\\(/.test(file.content) && /\\.ThenInclude\\(/.test(file.content);\n if (hasComplexQuery) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('architecture'),\n category: 'architecture',\n severity: 'warning',\n title: 'Complex Query in Controller',\n description: 'Controllers with complex queries (multiple Includes) should consider moving logic to a service.',\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Consider extracting complex query logic to an Application layer service.',\n autoFixable: false,\n });\n break; // One warning per file\n }\n }\n }\n }\n\n // Check for service instantiation instead of DI\n const newServicePattern = /new\\s+(\\w+Service)\\s*\\(/gi;\n let match;\n while ((match = newServicePattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if in test files\n if (file.relativePath.includes('Test') || file.relativePath.includes('.test.')) continue;\n\n findings.push({\n id: generateFindingId('architecture'),\n category: 'architecture',\n severity: 'critical',\n title: 'Service Instantiation Instead of DI',\n description: `Direct instantiation of ${match[1]} detected. Services should be injected via constructor, not instantiated with 'new'.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Inject the service interface via constructor dependency injection.',\n autoFixable: false,\n });\n }\n }\n\n // TypeScript/React architecture checks\n if (['typescript', 'tsx'].includes(file.language) && file.layer === 'web') {\n for (const { pattern, message } of TS_LAYER_VIOLATIONS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('architecture'),\n category: 'architecture',\n severity: 'critical',\n title: 'Web Layer Violation',\n description: message,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Use API client services to communicate with the backend instead of direct imports.',\n autoFixable: false,\n });\n }\n }\n }\n }\n\n return findings;\n}\n\n// Helper functions\nfunction detectCsharpLayer(content: string, filePath: string): string | null {\n // First check file path\n const pathLower = filePath.toLowerCase();\n if (pathLower.includes('/domain/') || pathLower.includes('\\\\domain\\\\')) return 'domain';\n if (pathLower.includes('/application/') || pathLower.includes('\\\\application\\\\')) return 'application';\n if (pathLower.includes('/infrastructure/') || pathLower.includes('\\\\infrastructure\\\\')) return 'infrastructure';\n if (pathLower.includes('/api/') || pathLower.includes('\\\\api\\\\')) return 'api';\n\n // Then check namespace patterns\n for (const [layer, patterns] of Object.entries(CSHARP_LAYER_PATTERNS)) {\n for (const pattern of patterns) {\n if (pattern.test(content)) {\n return layer;\n }\n }\n }\n\n return null;\n}\n\nfunction getSuggestionForViolation(fromLayer: string, toLayer: string): string {\n if (fromLayer === 'domain' && toLayer === 'application') {\n return 'Domain entities should not depend on Application layer. Move shared interfaces to Domain.';\n }\n if (fromLayer === 'application' && toLayer === 'infrastructure') {\n return 'Define an interface in Application layer and implement it in Infrastructure.';\n }\n if (fromLayer === 'api' && toLayer === 'web') {\n return 'API controllers should not depend on Web layer.';\n }\n if (toLayer === 'infrastructure') {\n return 'Use dependency injection with interfaces defined in Application layer.';\n }\n return 'Refactor to respect Clean Architecture layer boundaries.';\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n","/**\n * Hardcoded Values Check Module\n * Detects magic numbers, hardcoded strings, URLs, etc.\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Magic number exceptions (common acceptable values)\nconst ACCEPTABLE_NUMBERS = new Set([\n 0, 1, -1, 2, 10, 100, 1000,\n // Common sizes\n 8, 16, 32, 64, 128, 256, 512, 1024,\n // HTTP status codes (often used as comparisons)\n 200, 201, 204, 400, 401, 403, 404, 500,\n]);\n\n// Patterns for hardcoded values\nconst HARDCODED_URL_PATTERN = /[\"'](https?:\\/\\/(?!localhost)[^\"']+)[\"']/gi;\nconst HARDCODED_EMAIL_PATTERN = /[\"']([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,})[\"']/gi;\nconst HARDCODED_IP_PATTERN = /[\"'](\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})[\"']/gi;\n\n// Timeout patterns (suspicious hardcoded timeouts)\nconst TIMEOUT_PATTERNS = [\n { pattern: /timeout\\s*[=:]\\s*(\\d{4,})/gi, name: 'Timeout value' },\n { pattern: /TimeSpan\\.FromSeconds\\s*\\(\\s*(\\d+)\\s*\\)/gi, name: 'TimeSpan.FromSeconds' },\n { pattern: /TimeSpan\\.FromMinutes\\s*\\(\\s*(\\d+)\\s*\\)/gi, name: 'TimeSpan.FromMinutes' },\n { pattern: /setTimeout\\s*\\(\\s*[^,]+,\\s*(\\d{4,})\\s*\\)/gi, name: 'setTimeout' },\n { pattern: /delay\\s*[=:]\\s*(\\d{4,})/gi, name: 'Delay value' },\n];\n\n// Magic number pattern (standalone numbers in code)\nconst MAGIC_NUMBER_PATTERN = /(?<![a-zA-Z0-9_.])\\b(\\d+)\\b(?![a-zA-Z0-9_])/g;\n\n// Error message patterns - reserved for future use\n// ERROR_MESSAGE_PATTERNS would detect hardcoded exception messages\n\n// Feature flag patterns\nconst FEATURE_FLAG_PATTERNS = [\n { pattern: /if\\s*\\(\\s*(true|false)\\s*\\)/gi, name: 'Hardcoded boolean condition' },\n { pattern: /enabled\\s*[=:]\\s*(true|false)/gi, name: 'Hardcoded enabled flag' },\n];\n\nexport async function checkHardcodedValues(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n // Skip config, test, and constant files\n if (isConfigOrConstFile(file.relativePath)) continue;\n\n const lines = file.content.split('\\n');\n\n // Check for hardcoded URLs\n let match;\n HARDCODED_URL_PATTERN.lastIndex = 0;\n while ((match = HARDCODED_URL_PATTERN.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if in comments or appears to be a doc/example\n if (isInComment(lineContent) || isDocExample(lineContent)) continue;\n\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Hardcoded URL',\n description: `Found hardcoded URL: ${truncateCode(match[1], 50)}. URLs should be in configuration.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Move this URL to appsettings.json, environment variables, or a configuration service.',\n autoFixable: false,\n });\n }\n\n // Check for hardcoded emails\n HARDCODED_EMAIL_PATTERN.lastIndex = 0;\n while ((match = HARDCODED_EMAIL_PATTERN.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent) || isDocExample(lineContent)) continue;\n\n // Skip test emails\n if (match[1].includes('@test') || match[1].includes('@example')) continue;\n\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Hardcoded Email',\n description: `Found hardcoded email: ${match[1]}. Consider using configuration.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Move this email to configuration or use a configurable notification service.',\n autoFixable: false,\n });\n }\n\n // Check for hardcoded IP addresses\n HARDCODED_IP_PATTERN.lastIndex = 0;\n while ((match = HARDCODED_IP_PATTERN.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent)) continue;\n\n // Skip localhost and common test IPs\n if (match[1] === '127.0.0.1' || match[1] === '0.0.0.0') continue;\n\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Hardcoded IP Address',\n description: `Found hardcoded IP address: ${match[1]}. This should be configurable.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Move this IP address to configuration.',\n autoFixable: false,\n });\n }\n\n // Check for timeout patterns\n for (const { pattern, name } of TIMEOUT_PATTERNS) {\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const value = parseInt(match[1], 10);\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent)) continue;\n\n // Only flag if not a small/common value\n if (value > 1000 || (value > 60 && name.includes('Minutes'))) {\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Hardcoded Timeout',\n description: `${name} with hardcoded value ${value}. Consider making timeouts configurable.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Extract timeout values to configuration for easier adjustment in different environments.',\n autoFixable: false,\n });\n }\n }\n }\n\n // Check for magic numbers (only in business logic files)\n if (isBusinessLogicFile(file.relativePath) && file.language === 'csharp') {\n checkMagicNumbers(file.content, file.relativePath, lines, findings);\n }\n\n // Check for hardcoded feature flags\n for (const { pattern, name } of FEATURE_FLAG_PATTERNS) {\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n if (isInComment(lineContent)) continue;\n\n // Skip obvious debug/test code\n if (lineContent.includes('DEBUG') || lineContent.includes('TEST')) continue;\n\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Hardcoded Feature Flag',\n description: `${name} detected. Feature toggles should be configurable, not hardcoded.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Use a feature flag system or configuration service instead of hardcoded boolean values.',\n autoFixable: false,\n });\n }\n }\n }\n\n return findings;\n}\n\nfunction checkMagicNumbers(\n content: string,\n filePath: string,\n lines: string[],\n findings: CodeReviewFinding[]\n): void {\n const magicNumbersFound = new Map<number, number[]>(); // value -> line numbers\n\n let match;\n MAGIC_NUMBER_PATTERN.lastIndex = 0;\n while ((match = MAGIC_NUMBER_PATTERN.exec(content)) !== null) {\n const value = parseInt(match[1], 10);\n const lineNumber = getLineNumber(content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip acceptable numbers\n if (ACCEPTABLE_NUMBERS.has(value)) continue;\n\n // Skip if in comment\n if (isInComment(lineContent)) continue;\n\n // Skip if part of a constant definition\n if (/const\\s+\\w+\\s*=/.test(lineContent) || /readonly\\s+\\w+\\s*=/.test(lineContent)) continue;\n\n // Skip array indices and simple comparisons\n if (/\\[\\s*\\d+\\s*\\]/.test(lineContent)) continue;\n\n // Track magic numbers\n if (!magicNumbersFound.has(value)) {\n magicNumbersFound.set(value, []);\n }\n magicNumbersFound.get(value)!.push(lineNumber);\n }\n\n // Report magic numbers that appear multiple times (more suspicious)\n for (const [value, lineNumbers] of magicNumbersFound) {\n if (lineNumbers.length >= 2) {\n findings.push({\n id: generateFindingId('hardcoded-values'),\n category: 'hardcoded-values',\n severity: 'warning',\n title: 'Magic Number',\n description: `Magic number ${value} appears ${lineNumbers.length} times. Consider extracting to a named constant.`,\n file: filePath,\n line: lineNumbers[0],\n suggestion: `Extract ${value} to a well-named constant that explains its purpose.`,\n autoFixable: true,\n });\n }\n }\n}\n\n// Helper functions\nfunction isConfigOrConstFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return (\n lower.includes('config') ||\n lower.includes('constant') ||\n lower.includes('settings') ||\n lower.includes('appsettings') ||\n lower.includes('.json') ||\n lower.includes('test') ||\n lower.includes('.spec.') ||\n lower.includes('.test.')\n );\n}\n\nfunction isBusinessLogicFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return (\n lower.includes('service') ||\n lower.includes('handler') ||\n lower.includes('controller') ||\n lower.includes('validator')\n );\n}\n\nfunction isDocExample(line: string): boolean {\n // Check for documentation patterns\n if (line.includes('/// ') || line.includes('* ')) return true;\n\n // Check for example keywords but not in URLs (example.com, example.org)\n const hasExampleKeyword = /\\bexample\\b/i.test(line);\n const isExampleInUrl = /example\\.(com|org|net)/i.test(line);\n\n return hasExampleKeyword && !isExampleInUrl;\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n\nfunction isInComment(line: string): boolean {\n const trimmed = line.trim();\n return trimmed.startsWith('//') || trimmed.startsWith('/*') || trimmed.startsWith('*');\n}\n","/**\n * Tests Check Module\n * Detects missing tests and test quality issues\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Patterns to identify testable components\nconst ENTITY_PATTERN = /public\\s+class\\s+(\\w+)\\s*:\\s*(Base|System)Entity/gi;\nconst SERVICE_PATTERN = /public\\s+class\\s+(\\w+Service)\\s*:\\s*I\\w+Service/gi;\nconst CONTROLLER_PATTERN = /public\\s+class\\s+(\\w+Controller)\\s*:\\s*ControllerBase/gi;\nconst VALIDATOR_PATTERN = /public\\s+class\\s+(\\w+Validator)\\s*:\\s*AbstractValidator/gi;\n\n// Test quality patterns\nconst USELESS_ASSERTION_PATTERNS = [\n /Assert\\.True\\s*\\(\\s*true\\s*\\)/gi,\n /Assert\\.False\\s*\\(\\s*false\\s*\\)/gi,\n /\\.Should\\(\\)\\.BeTrue\\(\\)/gi,\n /expect\\s*\\(\\s*true\\s*\\)\\s*\\.toBe\\s*\\(\\s*true\\s*\\)/gi,\n /expect\\s*\\(\\s*1\\s*\\)\\s*\\.toBe\\s*\\(\\s*1\\s*\\)/gi,\n];\n\n// NO_ASSERTION_PATTERN reserved for future use: /\\[Fact\\][\\s\\S]*?public\\s+(?:async\\s+)?(?:Task|void)\\s+\\w+\\s*\\([^)]*\\)\\s*\\{[^}]*\\}/gi\n\nexport async function checkTests(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n // Collect all testable components\n const entities = new Set<string>();\n const services = new Set<string>();\n const controllers = new Set<string>();\n const validators = new Set<string>();\n\n // Collect existing tests\n const existingTests = new Set<string>();\n\n for (const file of context.files) {\n if (file.language !== 'csharp') continue;\n\n // Identify components\n let match;\n\n ENTITY_PATTERN.lastIndex = 0;\n while ((match = ENTITY_PATTERN.exec(file.content)) !== null) {\n entities.add(match[1]);\n }\n\n SERVICE_PATTERN.lastIndex = 0;\n while ((match = SERVICE_PATTERN.exec(file.content)) !== null) {\n services.add(match[1]);\n }\n\n CONTROLLER_PATTERN.lastIndex = 0;\n while ((match = CONTROLLER_PATTERN.exec(file.content)) !== null) {\n controllers.add(match[1]);\n }\n\n VALIDATOR_PATTERN.lastIndex = 0;\n while ((match = VALIDATOR_PATTERN.exec(file.content)) !== null) {\n validators.add(match[1]);\n }\n\n // Identify test files\n if (file.relativePath.includes('Tests') || file.relativePath.includes('.test.')) {\n // Extract tested component names\n const testClassMatch = /public\\s+class\\s+(\\w+)Tests/gi.exec(file.content);\n if (testClassMatch) {\n existingTests.add(testClassMatch[1]);\n }\n\n // Check test quality\n checkTestQuality(file, findings);\n }\n }\n\n // Check for missing tests\n checkMissingTests(entities, existingTests, 'Entity', findings);\n checkMissingTests(services, existingTests, 'Service', findings);\n checkMissingTests(controllers, existingTests, 'Controller', findings);\n checkMissingTests(validators, existingTests, 'Validator', findings);\n\n return findings;\n}\n\nfunction checkMissingTests(\n components: Set<string>,\n existingTests: Set<string>,\n type: string,\n findings: CodeReviewFinding[]\n): void {\n for (const component of components) {\n // Normalize name for comparison\n const baseName = component.replace(/(Service|Controller|Validator)$/, '');\n\n const hasTest =\n existingTests.has(component) ||\n existingTests.has(baseName) ||\n existingTests.has(`${baseName}${type}`);\n\n if (!hasTest) {\n const priority = getPriority(type);\n\n findings.push({\n id: generateFindingId('tests'),\n category: 'tests',\n severity: priority === 'critical' ? 'critical' : 'warning',\n title: `Missing Tests for ${component}`,\n description: `No test file found for ${type.toLowerCase()} ${component}. ${type}s should have comprehensive test coverage.`,\n file: `Tests/Unit/${type}s/${component}Tests.cs`,\n suggestion: `Create a test file: Tests/Unit/${type}s/${component}Tests.cs`,\n autoFixable: false,\n });\n }\n }\n}\n\nfunction checkTestQuality(file: { relativePath: string; content: string }, findings: CodeReviewFinding[]): void {\n // Check for useless assertions\n for (const pattern of USELESS_ASSERTION_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('tests'),\n category: 'tests',\n severity: 'warning',\n title: 'Useless Test Assertion',\n description: 'This assertion always passes and doesn\\'t test any behavior.',\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(match[0]),\n suggestion: 'Replace with meaningful assertions that verify actual behavior.',\n autoFixable: false,\n });\n }\n }\n\n // Check for tests without assertions (simplified check)\n const factMatches = file.content.matchAll(/\\[Fact\\]\\s*\\n\\s*public\\s+(?:async\\s+)?(?:Task|void)\\s+(\\w+)/gi);\n for (const match of factMatches) {\n const methodName = match[1];\n const methodStart = match.index || 0;\n\n // Find method body (simplified)\n const bodyStart = file.content.indexOf('{', methodStart);\n const bodyEnd = findMatchingBrace(file.content, bodyStart);\n\n if (bodyStart !== -1 && bodyEnd !== -1) {\n const methodBody = file.content.slice(bodyStart, bodyEnd);\n\n // Check if body has assertions\n const hasAssertion =\n /Assert\\./i.test(methodBody) ||\n /\\.Should\\(/i.test(methodBody) ||\n /expect\\s*\\(/i.test(methodBody) ||\n /Verify\\s*\\(/i.test(methodBody);\n\n if (!hasAssertion) {\n const lineNumber = getLineNumber(file.content, methodStart);\n\n findings.push({\n id: generateFindingId('tests'),\n category: 'tests',\n severity: 'warning',\n title: 'Test Without Assertions',\n description: `Test method ${methodName} does not appear to have any assertions.`,\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Add assertions to verify the expected behavior. A test without assertions doesn\\'t prove anything.',\n autoFixable: false,\n });\n }\n }\n }\n}\n\nfunction getPriority(type: string): 'critical' | 'high' | 'medium' | 'low' {\n switch (type) {\n case 'Service':\n return 'critical';\n case 'Controller':\n return 'high';\n case 'Validator':\n return 'high';\n case 'Entity':\n return 'medium';\n default:\n return 'low';\n }\n}\n\nfunction findMatchingBrace(content: string, start: number): number {\n let depth = 0;\n for (let i = start; i < content.length; i++) {\n if (content[i] === '{') depth++;\n if (content[i] === '}') {\n depth--;\n if (depth === 0) return i;\n }\n }\n return -1;\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * AI Hallucinations Check Module\n * Detects code that may have been generated incorrectly by AI\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Common AI hallucination patterns\n\n// Non-existent .NET namespaces/types\nconst FAKE_DOTNET_NAMESPACES = [\n 'System.AI',\n 'System.Machine',\n 'Microsoft.AI.OpenAI',\n 'Microsoft.Extensions.AI',\n 'Azure.AI.TextAnalytics', // Often confused\n 'System.Data.Linq', // Obsolete\n];\n\n// Non-existent npm packages (commonly hallucinated)\nconst FAKE_NPM_PACKAGES = [\n '@react/router', // Should be react-router-dom\n '@microsoft/auth', // Various incorrect forms\n 'react-query/v4', // Incorrect path\n '@tanstack/query', // Should be @tanstack/react-query\n];\n\n// Patterns that suggest AI-generated incorrect code\nconst AI_CODE_PATTERNS = [\n {\n pattern: /\\/\\/\\s*TODO:\\s*implement/gi,\n name: 'Unimplemented TODO',\n description: 'AI-generated placeholder that was not completed',\n },\n {\n pattern: /throw\\s+new\\s+NotImplementedException\\s*\\(\\s*\\)/gi,\n name: 'NotImplementedException',\n description: 'Method stub that was not implemented',\n },\n {\n pattern: /\\/\\/\\s*\\.\\.\\./gi,\n name: 'Ellipsis comment',\n description: 'AI placeholder comment indicating incomplete code',\n },\n {\n pattern: /\\/\\*\\s*\\.\\.\\.\\s*\\*\\//gi,\n name: 'Ellipsis block comment',\n description: 'AI placeholder indicating incomplete code',\n },\n];\n\n// Methods that don't exist on common types\nconst FAKE_METHODS: Record<string, string[]> = {\n string: ['IsEmpty', 'IsNotEmpty', 'ToInt', 'ToDouble', 'SafeTrim'],\n List: ['AddIfNotExists', 'SafeAdd', 'GetOrDefault', 'FindOrCreate'],\n Dictionary: ['GetOrAdd', 'TryAdd', 'SafeGet'], // Some exist in ConcurrentDictionary\n Task: ['WaitAll', 'WhenAny'], // Should be Task.WaitAll, Task.WhenAny (static)\n DateTime: ['ToISOString', 'FromISOString'], // JavaScript confusion\n};\n\n// C# using statements that might be hallucinated\nconst CSHARP_USING_PATTERN = /using\\s+([\\w.]+);/gi;\n\n// TypeScript/JavaScript import patterns\nconst TS_IMPORT_PATTERN = /import\\s+.*\\s+from\\s+['\"]([^'\"]+)['\"]/gi;\n// TS_REQUIRE_PATTERN reserved for future use: /require\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/gi\n\nexport async function checkAiHallucinations(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n // Build index of existing files for import validation\n const existingFiles = new Set(context.files.map((f) => f.relativePath.toLowerCase()));\n const existingModules = new Set<string>();\n\n for (const file of context.files) {\n // Extract module names for later validation\n if (file.language === 'csharp') {\n const namespaceMatch = /namespace\\s+([\\w.]+)/gi.exec(file.content);\n if (namespaceMatch) {\n existingModules.add(namespaceMatch[1].toLowerCase());\n }\n }\n }\n\n for (const file of context.files) {\n const lines = file.content.split('\\n');\n\n // Check for AI code patterns\n for (const { pattern, name, description } of AI_CODE_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('ai-hallucinations'),\n category: 'ai-hallucinations',\n severity: 'critical',\n title: `Incomplete Code: ${name}`,\n description: description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Complete the implementation or remove the placeholder.',\n autoFixable: false,\n });\n }\n }\n\n // C# specific checks\n if (file.language === 'csharp') {\n // Check for fake namespaces\n let match;\n CSHARP_USING_PATTERN.lastIndex = 0;\n while ((match = CSHARP_USING_PATTERN.exec(file.content)) !== null) {\n const namespace = match[1];\n\n for (const fakeNs of FAKE_DOTNET_NAMESPACES) {\n if (namespace.startsWith(fakeNs)) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('ai-hallucinations'),\n category: 'ai-hallucinations',\n severity: 'blocking',\n title: 'Non-existent Namespace',\n description: `The namespace '${namespace}' does not exist in .NET. This may be AI-hallucinated code.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(match[0]),\n suggestion: 'Verify this namespace exists. Check NuGet packages or use the correct namespace.',\n autoFixable: false,\n });\n }\n }\n }\n\n // Check for fake methods on common types\n for (const [typeName, fakeMethods] of Object.entries(FAKE_METHODS)) {\n for (const fakeMethod of fakeMethods) {\n const methodPattern = new RegExp(`\\\\.${fakeMethod}\\\\s*\\\\(`, 'gi');\n let methodMatch;\n while ((methodMatch = methodPattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, methodMatch.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Check if it's likely on the type we're looking for\n const contextStart = Math.max(0, methodMatch.index - 50);\n const context = file.content.slice(contextStart, methodMatch.index).toLowerCase();\n\n if (context.includes(typeName.toLowerCase()) || typeName === 'string') {\n findings.push({\n id: generateFindingId('ai-hallucinations'),\n category: 'ai-hallucinations',\n severity: 'blocking',\n title: `Non-existent Method: ${fakeMethod}`,\n description: `The method '${fakeMethod}' does not exist on ${typeName} in .NET. This is likely AI-hallucinated code.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: `Use the correct .NET method. For example: string.IsNullOrEmpty() instead of IsEmpty().`,\n autoFixable: false,\n });\n }\n }\n }\n }\n }\n\n // TypeScript/JavaScript checks\n if (['typescript', 'javascript', 'tsx', 'jsx'].includes(file.language)) {\n // Check for fake npm packages\n let match;\n TS_IMPORT_PATTERN.lastIndex = 0;\n while ((match = TS_IMPORT_PATTERN.exec(file.content)) !== null) {\n const importPath = match[1];\n\n // Check against known fake packages\n for (const fakePkg of FAKE_NPM_PACKAGES) {\n if (importPath === fakePkg || importPath.startsWith(fakePkg + '/')) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('ai-hallucinations'),\n category: 'ai-hallucinations',\n severity: 'blocking',\n title: 'Non-existent Package',\n description: `The package '${importPath}' does not exist. This may be AI-hallucinated code.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Verify this package exists on npm. Check the correct package name.',\n autoFixable: false,\n });\n }\n }\n\n // Check for relative imports that don't exist\n if (importPath.startsWith('./') || importPath.startsWith('../')) {\n const normalizedPath = resolveRelativePath(file.relativePath, importPath);\n const possibleExtensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];\n\n const exists = possibleExtensions.some((ext) =>\n existingFiles.has(normalizedPath.toLowerCase() + ext) ||\n existingFiles.has(normalizedPath.toLowerCase())\n );\n\n if (!exists && !importPath.includes('*')) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('ai-hallucinations'),\n category: 'ai-hallucinations',\n severity: 'critical',\n title: 'Import Path Not Found',\n description: `The import path '${importPath}' does not resolve to an existing file.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Verify the file exists or fix the import path.',\n autoFixable: false,\n });\n }\n }\n }\n }\n }\n\n return findings;\n}\n\n// Helper functions\nfunction resolveRelativePath(fromFile: string, importPath: string): string {\n // Normalize path separators\n fromFile = fromFile.replace(/\\\\/g, '/');\n importPath = importPath.replace(/\\\\/g, '/');\n\n // Get directory of the importing file\n const fromDir = fromFile.substring(0, fromFile.lastIndexOf('/'));\n\n // Resolve the import path\n const parts = fromDir.split('/');\n\n for (const segment of importPath.split('/')) {\n if (segment === '..') {\n parts.pop();\n } else if (segment !== '.') {\n parts.push(segment);\n }\n }\n\n return parts.join('/');\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * Performance Check Module\n * Detects N+1 queries, over-fetching, and performance anti-patterns\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// N+1 Query patterns\nconst N_PLUS_ONE_PATTERNS = [\n {\n // Query inside foreach/for loop\n pattern: /(?:foreach|for)\\s*\\([^)]+\\)\\s*\\{[^}]*(?:await\\s+)?_context\\.\\w+\\./gi,\n name: 'Query in loop',\n description: 'Database query inside a loop can cause N+1 performance issues',\n },\n {\n // Nested Select with query\n pattern: /\\.Select\\s*\\([^)]*=>[^)]*\\.(?:First|Single|Where|Any)\\s*\\(/gi,\n name: 'Nested query in Select',\n description: 'Nested query inside Select projection causes N+1',\n },\n {\n // Lazy loading trigger\n pattern: /(?:foreach|for)\\s*\\([^)]+\\)\\s*\\{[^}]*\\.\\w+Navigation\\./gi,\n name: 'Navigation property in loop',\n description: 'Accessing navigation property in loop triggers lazy loading',\n },\n];\n\n// Over-fetching patterns\nconst OVER_FETCHING_PATTERNS = [\n {\n // Multiple Include calls\n pattern: /\\.Include\\s*\\([^)]+\\)\\s*\\.Include\\s*\\([^)]+\\)\\s*\\.Include\\s*\\([^)]+\\)/gi,\n name: 'Triple Include',\n description: 'Too many Include calls can load excessive data',\n },\n {\n // ToList before Where\n pattern: /\\.ToList(?:Async)?\\s*\\(\\s*\\)\\s*\\.(?:Where|Select|OrderBy)/gi,\n name: 'ToList before filtering',\n description: 'ToList() before filtering loads all records into memory',\n },\n {\n // GetAll without pagination\n pattern: /GetAll(?:Async)?\\s*\\(\\s*\\)/gi,\n name: 'GetAll without pagination',\n description: 'Fetching all records without pagination can cause memory issues',\n },\n];\n\n// Frontend performance patterns\nconst FRONTEND_PERF_PATTERNS = [\n {\n // Multiple fetch in useEffect\n pattern: /useEffect\\s*\\(\\s*(?:async\\s*)?\\(\\s*\\)\\s*=>\\s*\\{[^}]*fetch[^}]*fetch/gi,\n name: 'Multiple fetches in useEffect',\n description: 'Multiple sequential API calls in useEffect should be combined or parallelized',\n },\n {\n // Fetch without dependency array\n pattern: /useEffect\\s*\\(\\s*(?:async\\s*)?\\(\\s*\\)\\s*=>\\s*\\{[^}]*(?:fetch|axios|api\\.)[^}]*\\}\\s*\\)/gi,\n name: 'Fetch without dependencies',\n description: 'API call in useEffect without dependency array runs on every render',\n },\n {\n // setState in loop\n pattern: /(?:for|while|forEach)\\s*\\([^)]*\\)[^{]*\\{[^}]*set\\w+\\s*\\(/gi,\n name: 'setState in loop',\n description: 'Calling setState in a loop causes multiple re-renders',\n },\n {\n // Large inline objects in JSX\n pattern: /style\\s*=\\s*\\{\\s*\\{[^}]{100,}\\}/gi,\n name: 'Large inline style object',\n description: 'Large inline objects create new references on each render',\n },\n];\n\n// Missing optimization patterns\nconst MISSING_OPTIMIZATION_PATTERNS = [\n {\n // No pagination in list queries\n pattern: /\\.ToListAsync\\s*\\(\\s*\\)/gi,\n contextCheck: (content: string, index: number) => {\n const context = content.slice(Math.max(0, index - 200), index);\n return !context.includes('Take') && !context.includes('Skip') && !context.includes('PageSize');\n },\n name: 'List query without pagination',\n description: 'Large list queries should use pagination',\n },\n {\n // No AsNoTracking for read-only queries\n pattern: /\\.(?:Where|Select|Include)[^;]*\\.ToListAsync/gi,\n contextCheck: (content: string, index: number) => {\n const context = content.slice(Math.max(0, index - 300), index + 100);\n return !context.includes('AsNoTracking') && !context.includes('Update') && !context.includes('Add');\n },\n name: 'Missing AsNoTracking',\n description: 'Read-only queries should use AsNoTracking for better performance',\n },\n];\n\nexport async function checkPerformance(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n const lines = file.content.split('\\n');\n\n // C# performance checks\n if (file.language === 'csharp') {\n // Check N+1 patterns\n for (const { pattern, name, description } of N_PLUS_ONE_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('performance'),\n category: 'performance',\n severity: 'critical',\n title: `N+1 Query: ${name}`,\n description: description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Use Include() or batch the queries. Consider using .Select() projection to load only needed data.',\n autoFixable: false,\n references: ['https://docs.microsoft.com/en-us/ef/core/querying/related-data'],\n });\n }\n }\n\n // Check over-fetching patterns\n for (const { pattern, name, description } of OVER_FETCHING_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('performance'),\n category: 'performance',\n severity: 'warning',\n title: `Over-fetching: ${name}`,\n description: description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Consider using .Select() projection to load only the fields you need, or split into multiple queries.',\n autoFixable: false,\n });\n }\n }\n\n // Check missing optimizations\n for (const { pattern, contextCheck, name, description } of MISSING_OPTIMIZATION_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n if (contextCheck && !contextCheck(file.content, match.index)) continue;\n\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if in test file\n if (file.relativePath.includes('Test')) continue;\n\n findings.push({\n id: generateFindingId('performance'),\n category: 'performance',\n severity: 'warning',\n title: `Performance: ${name}`,\n description: description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: name.includes('pagination')\n ? 'Add .Skip() and .Take() for pagination.'\n : 'Add .AsNoTracking() for read-only queries.',\n autoFixable: false,\n });\n }\n }\n }\n\n // Frontend performance checks\n if (['typescript', 'javascript', 'tsx', 'jsx'].includes(file.language)) {\n for (const { pattern, name, description } of FRONTEND_PERF_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('performance'),\n category: 'performance',\n severity: 'warning',\n title: `Frontend Performance: ${name}`,\n description: description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: getSuggestionForFrontendPerf(name),\n autoFixable: false,\n });\n }\n }\n\n // Check for missing React.memo/useMemo/useCallback\n checkMissingMemoization(file, lines, findings);\n }\n }\n\n return findings;\n}\n\nfunction checkMissingMemoization(\n file: { relativePath: string; content: string },\n lines: string[],\n findings: CodeReviewFinding[]\n): void {\n // Check for expensive computations in render\n const expensivePatterns = [\n /\\.filter\\s*\\([^)]+\\)\\.map\\s*\\(/gi,\n /\\.reduce\\s*\\([^)]+\\)/gi,\n /\\.sort\\s*\\([^)]*\\)/gi,\n /JSON\\.parse\\s*\\(/gi,\n ];\n\n for (const pattern of expensivePatterns) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n // Check if inside useMemo\n const contextStart = Math.max(0, match.index - 100);\n const context = file.content.slice(contextStart, match.index);\n if (context.includes('useMemo') || context.includes('useCallback')) continue;\n\n // Check if inside component render (simplified check)\n const beforeMatch = file.content.slice(Math.max(0, match.index - 500), match.index);\n if (beforeMatch.includes('return (') || beforeMatch.includes('return <')) {\n findings.push({\n id: generateFindingId('performance'),\n category: 'performance',\n severity: 'warning',\n title: 'Expensive Computation in Render',\n description: 'Expensive array operations in render body should be memoized.',\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Wrap this computation with useMemo() to prevent recalculation on every render.',\n autoFixable: false,\n });\n }\n }\n }\n}\n\nfunction getSuggestionForFrontendPerf(name: string): string {\n const suggestions: Record<string, string> = {\n 'Multiple fetches in useEffect': 'Use Promise.all() to parallelize requests or combine into a single API call.',\n 'Fetch without dependencies': 'Add a dependency array to prevent the effect from running on every render.',\n 'setState in loop': 'Batch state updates or use a reducer pattern.',\n 'Large inline style object': 'Extract styles to a useMemo() hook or a constant outside the component.',\n };\n return suggestions[name] || 'Optimize this code for better performance.';\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * Dead Code Check Module\n * Detects unused functions, imports, variables, and legacy code\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Patterns for detecting dead code\n\n// Commented out code patterns\nconst COMMENTED_CODE_PATTERNS = [\n {\n pattern: /\\/\\/\\s*(?:if|for|while|switch|return|var|let|const|public|private|async)\\s+/gi,\n name: 'Commented code block',\n },\n {\n pattern: /\\/\\*[\\s\\S]*?(?:if|for|while|return|function)[\\s\\S]*?\\*\\//gi,\n name: 'Commented code block',\n },\n];\n\n// TODO/FIXME patterns (potential dead code indicators)\nconst TODO_PATTERNS = [\n {\n pattern: /\\/\\/\\s*TODO[:\\s]/gi,\n name: 'TODO comment',\n },\n {\n pattern: /\\/\\/\\s*FIXME[:\\s]/gi,\n name: 'FIXME comment',\n },\n {\n pattern: /\\/\\/\\s*HACK[:\\s]/gi,\n name: 'HACK comment',\n },\n {\n pattern: /\\/\\/\\s*XXX[:\\s]/gi,\n name: 'XXX comment',\n },\n];\n\n// C# unused patterns\nconst CSHARP_UNUSED_IMPORT_PATTERN = /using\\s+([\\w.]+);/gi;\nconst CSHARP_PRIVATE_METHOD_PATTERN = /private\\s+(?:async\\s+)?(?:static\\s+)?(?:Task<?\\w*>?|\\w+)\\s+(\\w+)\\s*\\(/gi;\nconst CSHARP_PRIVATE_FIELD_PATTERN = /private\\s+(?:readonly\\s+)?(?:static\\s+)?\\w+(?:<[^>]+>)?\\s+_?(\\w+)\\s*[;=]/gi;\n\n// TypeScript/JavaScript unused patterns - reserved for future use\n// TS_IMPORT_PATTERN: /import\\s+(?:\\{([^}]+)\\}|(\\w+))\\s+from/gi\n// TS_CONST_PATTERN: /(?:const|let)\\s+(\\w+)\\s*=/gi\n// TS_FUNCTION_PATTERN: /(?:function\\s+(\\w+)|const\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*=>)/gi\n\nexport async function checkDeadCode(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n const lines = file.content.split('\\n');\n\n // Check for commented code\n for (const { pattern } of COMMENTED_CODE_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n // Skip if it looks like documentation\n if (lineContent.includes('///') || lineContent.includes('/**')) continue;\n\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'warning',\n title: 'Commented Code',\n description: 'Commented-out code should be removed. Use version control to preserve history.',\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Remove commented code. If needed later, it can be recovered from git history.',\n autoFixable: true,\n });\n }\n }\n\n // Check for TODO/FIXME comments\n for (const { pattern, name } of TODO_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const lineContent = lines[lineNumber - 1]?.trim() || '';\n\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'info',\n title: `${name} Found`,\n description: `${name} indicates incomplete or temporary code that may need attention.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lineContent),\n suggestion: 'Address the TODO/FIXME or create a ticket to track it.',\n autoFixable: false,\n });\n }\n }\n\n // C# specific dead code checks\n if (file.language === 'csharp') {\n // Check for unused private methods\n const privateMethods = new Map<string, number>();\n let match;\n\n CSHARP_PRIVATE_METHOD_PATTERN.lastIndex = 0;\n while ((match = CSHARP_PRIVATE_METHOD_PATTERN.exec(file.content)) !== null) {\n privateMethods.set(match[1], getLineNumber(file.content, match.index));\n }\n\n // Check if methods are called\n for (const [methodName, lineNumber] of privateMethods) {\n // Count occurrences (should be at least 2: definition + call)\n const regex = new RegExp(`\\\\b${methodName}\\\\s*\\\\(`, 'g');\n const occurrences = (file.content.match(regex) || []).length;\n\n if (occurrences === 1) {\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'warning',\n title: 'Unused Private Method',\n description: `Private method '${methodName}' is declared but never called.`,\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Remove the unused method or make it public if it should be accessible.',\n autoFixable: true,\n });\n }\n }\n\n // Check for unused private fields\n const privateFields = new Map<string, number>();\n\n CSHARP_PRIVATE_FIELD_PATTERN.lastIndex = 0;\n while ((match = CSHARP_PRIVATE_FIELD_PATTERN.exec(file.content)) !== null) {\n const fieldName = match[1];\n // Skip common patterns\n if (fieldName.startsWith('_') && fieldName.length > 1) {\n privateFields.set(fieldName, getLineNumber(file.content, match.index));\n }\n }\n\n for (const [fieldName, lineNumber] of privateFields) {\n const regex = new RegExp(`\\\\b${fieldName}\\\\b`, 'g');\n const occurrences = (file.content.match(regex) || []).length;\n\n if (occurrences === 1) {\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'warning',\n title: 'Unused Private Field',\n description: `Private field '${fieldName}' is declared but never used.`,\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Remove the unused field.',\n autoFixable: true,\n });\n }\n }\n\n // Check for unused using statements (simplified)\n checkUnusedCsharpUsings(file, lines, findings);\n }\n\n // TypeScript/JavaScript specific checks\n if (['typescript', 'javascript', 'tsx', 'jsx'].includes(file.language)) {\n checkUnusedJsImports(file, lines, findings);\n checkUnusedJsVariables(file, lines, findings);\n }\n }\n\n return findings;\n}\n\nfunction checkUnusedCsharpUsings(\n file: { relativePath: string; content: string },\n _lines: string[],\n findings: CodeReviewFinding[]\n): void {\n const usings = new Map<string, number>();\n\n let match;\n CSHARP_UNUSED_IMPORT_PATTERN.lastIndex = 0;\n while ((match = CSHARP_UNUSED_IMPORT_PATTERN.exec(file.content)) !== null) {\n const namespace = match[1];\n usings.set(namespace, getLineNumber(file.content, match.index));\n }\n\n // Get content after usings\n const contentAfterUsings = file.content.replace(/using\\s+[\\w.]+;/g, '');\n\n for (const [namespace, lineNumber] of usings) {\n // Get last part of namespace for checking\n const parts = namespace.split('.');\n const lastPart = parts[parts.length - 1];\n\n // Check if namespace or its last part is used\n const isUsed =\n contentAfterUsings.includes(lastPart) ||\n contentAfterUsings.includes(namespace);\n\n // Skip system namespaces and common always-needed ones\n const alwaysNeeded = ['System', 'System.Collections.Generic', 'System.Linq', 'System.Threading.Tasks'];\n if (alwaysNeeded.includes(namespace)) continue;\n\n if (!isUsed) {\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'info',\n title: 'Potentially Unused Using',\n description: `The using '${namespace}' may not be needed in this file.`,\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Remove unused using statements to keep the file clean.',\n autoFixable: true,\n });\n }\n }\n}\n\nfunction checkUnusedJsImports(\n file: { relativePath: string; content: string },\n _lines: string[],\n findings: CodeReviewFinding[]\n): void {\n // Extract imports\n const imports = new Map<string, { line: number; full: string }>();\n\n let match;\n const importPattern = /import\\s+(?:\\{([^}]+)\\}|(\\w+)(?:\\s*,\\s*\\{([^}]+)\\})?)\\s+from\\s+['\"][^'\"]+['\"]/gi;\n\n while ((match = importPattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const namedImports = match[1] || match[3];\n const defaultImport = match[2];\n\n if (namedImports) {\n const names = namedImports.split(',').map((n) => {\n const parts = n.trim().split(/\\s+as\\s+/);\n return parts[parts.length - 1].trim();\n });\n\n for (const name of names) {\n if (name) imports.set(name, { line: lineNumber, full: match[0] });\n }\n }\n\n if (defaultImport && defaultImport !== 'React') {\n imports.set(defaultImport, { line: lineNumber, full: match[0] });\n }\n }\n\n // Get content after imports\n const contentAfterImports = file.content.replace(/import\\s+.*from\\s+['\"][^'\"]+['\"]/g, '');\n\n for (const [name, { line }] of imports) {\n // Count occurrences\n const regex = new RegExp(`\\\\b${name}\\\\b`, 'g');\n const occurrences = (contentAfterImports.match(regex) || []).length;\n\n if (occurrences === 0) {\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'warning',\n title: 'Unused Import',\n description: `Import '${name}' is declared but never used.`,\n file: file.relativePath,\n line,\n suggestion: 'Remove unused imports.',\n autoFixable: true,\n });\n }\n }\n}\n\nfunction checkUnusedJsVariables(\n file: { relativePath: string; content: string },\n _lines: string[],\n findings: CodeReviewFinding[]\n): void {\n // This is a simplified check - only for obvious cases\n const varPattern = /(?:const|let)\\s+(\\w+)\\s*=\\s*(?!function|async\\s+function)/gi;\n const variables = new Map<string, number>();\n\n let match;\n while ((match = varPattern.exec(file.content)) !== null) {\n const varName = match[1];\n // Skip common patterns\n if (varName.startsWith('_') || varName === 'i' || varName === 'j') continue;\n\n variables.set(varName, getLineNumber(file.content, match.index));\n }\n\n for (const [varName, lineNumber] of variables) {\n const regex = new RegExp(`\\\\b${varName}\\\\b`, 'g');\n const occurrences = (file.content.match(regex) || []).length;\n\n // Should appear at least twice (declaration + use)\n if (occurrences === 1) {\n findings.push({\n id: generateFindingId('dead-code'),\n category: 'dead-code',\n severity: 'warning',\n title: 'Unused Variable',\n description: `Variable '${varName}' is declared but never used.`,\n file: file.relativePath,\n line: lineNumber,\n suggestion: 'Remove unused variables or prefix with underscore if intentionally unused.',\n autoFixable: true,\n });\n }\n }\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * i18n Check Module\n * Detects non-internationalized strings in code\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Patterns for hardcoded UI strings\n\n// JSX text content (between tags)\nconst JSX_TEXT_PATTERN = />([A-Z][a-z]+(?:\\s+[a-z]+)*[.!?]?)</gi;\n\n// JSX attribute strings\nconst JSX_ATTR_PATTERNS = [\n { pattern: /placeholder\\s*=\\s*[\"']([^\"']+)[\"']/gi, name: 'placeholder' },\n { pattern: /title\\s*=\\s*[\"']([A-Z][^\"']+)[\"']/gi, name: 'title' },\n { pattern: /aria-label\\s*=\\s*[\"']([^\"']+)[\"']/gi, name: 'aria-label' },\n { pattern: /alt\\s*=\\s*[\"']([A-Z][^\"']+)[\"']/gi, name: 'alt' },\n { pattern: /label\\s*=\\s*[\"']([A-Z][^\"']+)[\"']/gi, name: 'label' },\n];\n\n// C# error messages\nconst CSHARP_ERROR_PATTERNS = [\n { pattern: /throw\\s+new\\s+\\w*Exception\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'Exception message' },\n { pattern: /ModelState\\.AddModelError\\s*\\([^,]+,\\s*[\"']([^\"']+)[\"']/gi, name: 'Validation error' },\n { pattern: /\\.WithMessage\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'FluentValidation message' },\n { pattern: /BadRequest\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'BadRequest message' },\n { pattern: /NotFound\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'NotFound message' },\n];\n\n// Notification patterns\nconst NOTIFICATION_PATTERNS = [\n { pattern: /toast\\.\\w+\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'Toast notification' },\n { pattern: /notify\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'Notification' },\n { pattern: /alert\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'Alert' },\n { pattern: /confirm\\s*\\(\\s*[\"']([^\"']+)[\"']/gi, name: 'Confirm dialog' },\n];\n\n// Exclusion patterns (strings that don't need translation)\nconst EXCLUDED_PATTERNS = [\n /^[a-z]+$/i, // Single words (likely identifiers)\n /^[A-Z_]+$/, // CONSTANTS\n /^\\d+$/, // Numbers\n /^[a-z0-9-_]+$/i, // IDs, slugs\n /^https?:\\/\\//i, // URLs\n /^[a-zA-Z0-9._%+-]+@/, // Emails\n /^\\{.*\\}$/, // Template variables\n /^#[0-9a-f]+$/i, // Color codes\n];\n\nexport async function checkI18n(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n // Skip non-UI files\n if (!isUiFile(file.relativePath)) continue;\n\n const lines = file.content.split('\\n');\n\n // React/TSX checks\n if (['tsx', 'jsx'].includes(file.language)) {\n // Check for hardcoded JSX text\n let match;\n JSX_TEXT_PATTERN.lastIndex = 0;\n while ((match = JSX_TEXT_PATTERN.exec(file.content)) !== null) {\n const text = match[1].trim();\n\n if (!shouldExclude(text) && text.length > 2) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('i18n'),\n category: 'i18n',\n severity: 'warning',\n title: 'Hardcoded UI Text',\n description: `Text \"${truncateCode(text, 30)}\" should use translation function.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: `Use {t('key')} instead of hardcoded text. Example: {t('buttons.submit')}`,\n autoFixable: false,\n });\n }\n }\n\n // Check JSX attributes\n for (const { pattern, name } of JSX_ATTR_PATTERNS) {\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const text = match[1].trim();\n\n if (!shouldExclude(text) && text.length > 2) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('i18n'),\n category: 'i18n',\n severity: 'warning',\n title: `Non-translated ${name}`,\n description: `The ${name} attribute \"${truncateCode(text, 30)}\" should be translated.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: `Use {t('key')} for the ${name} attribute.`,\n autoFixable: false,\n });\n }\n }\n }\n\n // Check notification messages\n for (const { pattern, name } of NOTIFICATION_PATTERNS) {\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const text = match[1].trim();\n\n if (!shouldExclude(text) && text.length > 2) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('i18n'),\n category: 'i18n',\n severity: 'warning',\n title: `Non-translated ${name}`,\n description: `${name} message \"${truncateCode(text, 30)}\" should be translated.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: `Use t('key') for notification messages.`,\n autoFixable: false,\n });\n }\n }\n }\n\n // Check for missing translation function import\n if (!file.content.includes('useTranslation') && !file.content.includes('from \\'react-i18next\\'')) {\n const hasHardcodedStrings = JSX_TEXT_PATTERN.test(file.content);\n if (hasHardcodedStrings) {\n findings.push({\n id: generateFindingId('i18n'),\n category: 'i18n',\n severity: 'info',\n title: 'Missing i18n Setup',\n description: 'This file has UI text but does not import useTranslation hook.',\n file: file.relativePath,\n line: 1,\n suggestion: \"Add: import { useTranslation } from 'react-i18next';\",\n autoFixable: true,\n });\n }\n }\n }\n\n // C# checks\n if (file.language === 'csharp') {\n // Check error messages\n for (const { pattern, name } of CSHARP_ERROR_PATTERNS) {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const text = match[1].trim();\n\n // Error messages in controllers/services should be translated\n if (text.length > 10 && !shouldExclude(text)) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('i18n'),\n category: 'i18n',\n severity: 'warning',\n title: `Non-translated ${name}`,\n description: `${name} \"${truncateCode(text, 30)}\" should use localization.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Use IStringLocalizer or resource files for error messages.',\n autoFixable: false,\n });\n }\n }\n }\n }\n }\n\n return findings;\n}\n\nfunction isUiFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return (\n lower.includes('/pages/') ||\n lower.includes('/components/') ||\n lower.includes('/views/') ||\n lower.includes('/ui/') ||\n lower.endsWith('.tsx') ||\n lower.endsWith('.jsx') ||\n (lower.includes('controller') && lower.endsWith('.cs'))\n );\n}\n\nfunction shouldExclude(text: string): boolean {\n // Check if text matches any exclusion pattern\n for (const pattern of EXCLUDED_PATTERNS) {\n if (pattern.test(text)) return true;\n }\n\n // Skip very short texts\n if (text.length <= 2) return true;\n\n // Skip if it looks like code\n if (text.includes('(') || text.includes(')') || text.includes('{')) return true;\n\n // Skip if mostly numbers/symbols\n const alphaChars = text.replace(/[^a-zA-Z]/g, '').length;\n if (alphaChars < text.length * 0.5) return true;\n\n return false;\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * Accessibility (a11y) Check Module\n * Detects accessibility issues in React/HTML code\n */\n\nimport type { CheckContext, CodeReviewFinding } from '../types.js';\nimport { generateFindingId } from '../types.js';\n\n// Image accessibility patterns\nconst IMG_WITHOUT_ALT = /<img(?![^>]*\\balt\\s*=)[^>]*>/gi;\nconst IMG_EMPTY_ALT = /<img[^>]*\\balt\\s*=\\s*[\"']\\s*[\"'][^>]*>/gi;\n\n// Link accessibility patterns\nconst LINK_WITHOUT_TEXT = /<a[^>]*>\\s*<\\/a>/gi;\nconst LINK_ONLY_ICON = /<a[^>]*>\\s*<(?:svg|i|span[^>]*class=\"[^\"]*icon)[^>]*>\\s*<\\/a>/gi;\n\n// Button accessibility patterns\nconst BUTTON_WITHOUT_TEXT = /<button[^>]*>\\s*<(?:svg|i|span[^>]*icon)[^>]*>\\s*<\\/button>/gi;\n\n// Form accessibility patterns - INPUT_WITHOUT_LABEL pattern reserved for future use\n\n// Interactive element patterns\nconst ONCLICK_ON_DIV = /<div[^>]*onClick[^>]*>/gi;\nconst ONCLICK_ON_SPAN = /<span[^>]*onClick[^>]*>/gi;\n\n// Heading patterns\nconst HEADING_PATTERN = /<h([1-6])/gi;\n\n// Focus patterns\nconst POSITIVE_TABINDEX = /tabIndex\\s*=\\s*\\{?\\s*[\"']?([1-9]\\d*)[\"']?\\s*\\}?/gi;\nconst OUTLINE_NONE = /outline\\s*:\\s*none|outline\\s*:\\s*0/gi;\n\n// ARIA patterns\nconst ARIA_HIDDEN_FOCUSABLE = /aria-hidden\\s*=\\s*[\"']true[\"'][^>]*(?:tabIndex|onClick|onKeyDown)/gi;\n\nexport async function checkAccessibility(context: CheckContext): Promise<CodeReviewFinding[]> {\n const findings: CodeReviewFinding[] = [];\n\n for (const file of context.files) {\n // Only check frontend files\n if (!['tsx', 'jsx', 'typescript', 'javascript'].includes(file.language)) continue;\n if (!isUiFile(file.relativePath)) continue;\n\n const lines = file.content.split('\\n');\n\n // Check for images without alt\n checkPattern(file, lines, IMG_WITHOUT_ALT, {\n title: 'Image Missing Alt Text',\n description: 'Images must have an alt attribute for screen readers.',\n severity: 'critical',\n suggestion: 'Add alt=\"description\" to the image. Use alt=\"\" only for decorative images.',\n cweId: undefined,\n }, findings);\n\n // Check for empty alt on non-decorative images\n let match;\n IMG_EMPTY_ALT.lastIndex = 0;\n while ((match = IMG_EMPTY_ALT.exec(file.content)) !== null) {\n // Check if it looks decorative (has aria-hidden or role=\"presentation\")\n if (match[0].includes('aria-hidden') || match[0].includes('role=\"presentation\"')) continue;\n\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: 'warning',\n title: 'Empty Alt on Potentially Informative Image',\n description: 'Empty alt text should only be used for decorative images.',\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Add descriptive alt text or add role=\"presentation\" if truly decorative.',\n autoFixable: false,\n });\n }\n\n // Check for links without accessible text\n checkPattern(file, lines, LINK_WITHOUT_TEXT, {\n title: 'Empty Link',\n description: 'Links must have accessible text content.',\n severity: 'critical',\n suggestion: 'Add text content or aria-label to the link.',\n }, findings);\n\n checkPattern(file, lines, LINK_ONLY_ICON, {\n title: 'Icon-Only Link',\n description: 'Links containing only icons need accessible labels.',\n severity: 'warning',\n suggestion: 'Add aria-label or visually hidden text to describe the link.',\n }, findings);\n\n // Check for buttons without accessible text\n checkPattern(file, lines, BUTTON_WITHOUT_TEXT, {\n title: 'Icon-Only Button',\n description: 'Buttons containing only icons need accessible labels.',\n severity: 'warning',\n suggestion: 'Add aria-label or visually hidden text to describe the button action.',\n }, findings);\n\n // Check for click handlers on non-interactive elements\n checkPattern(file, lines, ONCLICK_ON_DIV, {\n title: 'Click Handler on Non-Interactive Element',\n description: 'div elements with onClick are not keyboard accessible by default.',\n severity: 'warning',\n suggestion: 'Use a button element, or add role=\"button\", tabIndex={0}, and onKeyDown handler.',\n }, findings);\n\n checkPattern(file, lines, ONCLICK_ON_SPAN, {\n title: 'Click Handler on Non-Interactive Element',\n description: 'span elements with onClick are not keyboard accessible by default.',\n severity: 'warning',\n suggestion: 'Use a button element, or add role=\"button\", tabIndex={0}, and onKeyDown handler.',\n }, findings);\n\n // Check for positive tabIndex\n POSITIVE_TABINDEX.lastIndex = 0;\n while ((match = POSITIVE_TABINDEX.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: 'warning',\n title: 'Positive tabIndex',\n description: `tabIndex=\"${match[1]}\" disrupts natural tab order and confuses keyboard users.`,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Use tabIndex={0} to add to natural tab order, or tabIndex={-1} to remove. Avoid positive values.',\n autoFixable: true,\n });\n }\n\n // Check for outline:none without alternative focus indicator\n OUTLINE_NONE.lastIndex = 0;\n while ((match = OUTLINE_NONE.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n const context = file.content.slice(Math.max(0, match.index - 100), match.index + 200);\n\n // Check if there's an alternative focus style\n if (context.includes(':focus') && (context.includes('box-shadow') || context.includes('border'))) continue;\n\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: 'critical',\n title: 'Focus Indicator Removed',\n description: 'Removing outline without an alternative makes it impossible for keyboard users to see focus.',\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: 'Provide an alternative focus indicator using box-shadow or border on :focus state.',\n autoFixable: false,\n });\n }\n\n // Check for aria-hidden on focusable elements\n checkPattern(file, lines, ARIA_HIDDEN_FOCUSABLE, {\n title: 'Focusable Element Hidden from Assistive Technology',\n description: 'Elements with aria-hidden=\"true\" should not be focusable.',\n severity: 'critical',\n suggestion: 'Remove aria-hidden=\"true\" or add tabIndex={-1} and remove click handlers.',\n }, findings);\n\n // Check heading hierarchy\n checkHeadingHierarchy(file, lines, findings);\n }\n\n return findings;\n}\n\nfunction checkPattern(\n file: { relativePath: string; content: string },\n lines: string[],\n pattern: RegExp,\n issue: {\n title: string;\n description: string;\n severity: 'blocking' | 'critical' | 'warning' | 'info';\n suggestion: string;\n cweId?: string;\n },\n findings: CodeReviewFinding[]\n): void {\n let match;\n pattern.lastIndex = 0;\n while ((match = pattern.exec(file.content)) !== null) {\n const lineNumber = getLineNumber(file.content, match.index);\n\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: issue.severity,\n title: issue.title,\n description: issue.description,\n file: file.relativePath,\n line: lineNumber,\n code: truncateCode(lines[lineNumber - 1]?.trim() || ''),\n suggestion: issue.suggestion,\n autoFixable: false,\n cweId: issue.cweId,\n });\n }\n}\n\nfunction checkHeadingHierarchy(\n file: { relativePath: string; content: string },\n lines: string[],\n findings: CodeReviewFinding[]\n): void {\n const headings: { level: number; line: number }[] = [];\n\n let match;\n HEADING_PATTERN.lastIndex = 0;\n while ((match = HEADING_PATTERN.exec(file.content)) !== null) {\n headings.push({\n level: parseInt(match[1], 10),\n line: getLineNumber(file.content, match.index),\n });\n }\n\n // Check for skipped levels\n for (let i = 1; i < headings.length; i++) {\n const current = headings[i];\n const previous = headings[i - 1];\n\n // Skipping more than one level (e.g., h1 -> h3)\n if (current.level > previous.level + 1) {\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: 'warning',\n title: 'Heading Level Skipped',\n description: `Heading jumps from h${previous.level} to h${current.level}. Screen reader users may think content is missing.`,\n file: file.relativePath,\n line: current.line,\n code: truncateCode(lines[current.line - 1]?.trim() || ''),\n suggestion: `Use h${previous.level + 1} instead of h${current.level}.`,\n autoFixable: true,\n });\n }\n }\n\n // Check if page starts with h1\n if (headings.length > 0 && headings[0].level !== 1) {\n findings.push({\n id: generateFindingId('accessibility'),\n category: 'accessibility',\n severity: 'info',\n title: 'Page Does Not Start with h1',\n description: 'Pages should typically start with an h1 heading.',\n file: file.relativePath,\n line: headings[0].line,\n suggestion: 'Consider adding an h1 as the main page heading.',\n autoFixable: false,\n });\n }\n}\n\nfunction isUiFile(filePath: string): boolean {\n const lower = filePath.toLowerCase();\n return (\n lower.includes('/pages/') ||\n lower.includes('/components/') ||\n lower.includes('/views/') ||\n lower.includes('/ui/') ||\n lower.endsWith('.tsx') ||\n lower.endsWith('.jsx')\n );\n}\n\nfunction getLineNumber(content: string, index: number): number {\n return content.slice(0, index).split('\\n').length;\n}\n\nfunction truncateCode(code: string, maxLength: number = 100): string {\n if (code.length <= maxLength) return code;\n return code.slice(0, maxLength - 3) + '...';\n}\n","/**\n * Markdown Formatter for Code Review Results\n */\n\nimport type { CodeReviewResult, CodeReviewFinding, ReviewSeverity } from '../types.js';\n\nconst SEVERITY_EMOJI: Record<ReviewSeverity, string> = {\n blocking: '🔴',\n critical: '🟠',\n warning: '🟡',\n info: '🔵',\n};\n\nconst GRADE_EMOJI: Record<string, string> = {\n A: '🟢',\n B: '🟢',\n C: '🟡',\n D: '🟠',\n F: '🔴',\n};\n\nexport function formatMarkdownReport(result: CodeReviewResult): string {\n const lines: string[] = [];\n\n // Header\n lines.push('# Code Review Report');\n lines.push('');\n\n // Summary\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Status | ${result.summary.status === 'passed' ? '✅ PASSED' : result.summary.status === 'failed' ? '❌ FAILED' : '⚠️ WARNING'} |`);\n lines.push(`| Score | ${result.summary.score}/100 |`);\n lines.push(`| Grade | ${GRADE_EMOJI[result.summary.grade]} ${result.summary.grade} |`);\n lines.push(`| Files Scanned | ${result.stats.filesScanned} |`);\n lines.push(`| Lines Scanned | ${result.stats.linesScanned.toLocaleString()} |`);\n lines.push(`| Duration | ${result.stats.duration}ms |`);\n lines.push('');\n\n // Issues Count\n lines.push('### Issues Found');\n lines.push('');\n lines.push('| Severity | Count |');\n lines.push('|----------|-------|');\n lines.push(`| ${SEVERITY_EMOJI.blocking} Blocking | ${result.stats.findingsCount.blocking} |`);\n lines.push(`| ${SEVERITY_EMOJI.critical} Critical | ${result.stats.findingsCount.critical} |`);\n lines.push(`| ${SEVERITY_EMOJI.warning} Warning | ${result.stats.findingsCount.warning} |`);\n lines.push(`| ${SEVERITY_EMOJI.info} Info | ${result.stats.findingsCount.info} |`);\n lines.push('');\n\n // By Category\n const categoriesWithIssues = Object.entries(result.stats.byCategory)\n .filter(([_, count]) => count > 0)\n .sort((a, b) => b[1] - a[1]);\n\n if (categoriesWithIssues.length > 0) {\n lines.push('### By Category');\n lines.push('');\n lines.push('| Category | Count |');\n lines.push('|----------|-------|');\n for (const [category, count] of categoriesWithIssues) {\n lines.push(`| ${formatCategoryName(category)} | ${count} |`);\n }\n lines.push('');\n }\n\n // Findings by Severity\n const blockingFindings = result.findings.filter((f) => f.severity === 'blocking');\n const criticalFindings = result.findings.filter((f) => f.severity === 'critical');\n const warningFindings = result.findings.filter((f) => f.severity === 'warning');\n const infoFindings = result.findings.filter((f) => f.severity === 'info');\n\n if (blockingFindings.length > 0) {\n lines.push('---');\n lines.push('');\n lines.push(`## ${SEVERITY_EMOJI.blocking} Blocking Issues (${blockingFindings.length})`);\n lines.push('');\n lines.push('> These issues MUST be fixed before merging.');\n lines.push('');\n formatFindings(lines, blockingFindings);\n }\n\n if (criticalFindings.length > 0) {\n lines.push('---');\n lines.push('');\n lines.push(`## ${SEVERITY_EMOJI.critical} Critical Issues (${criticalFindings.length})`);\n lines.push('');\n lines.push('> These issues should be fixed as soon as possible.');\n lines.push('');\n formatFindings(lines, criticalFindings);\n }\n\n if (warningFindings.length > 0) {\n lines.push('---');\n lines.push('');\n lines.push(`## ${SEVERITY_EMOJI.warning} Warnings (${warningFindings.length})`);\n lines.push('');\n formatFindings(lines, warningFindings);\n }\n\n if (infoFindings.length > 0) {\n lines.push('---');\n lines.push('');\n lines.push(`## ${SEVERITY_EMOJI.info} Info (${infoFindings.length})`);\n lines.push('');\n formatFindings(lines, infoFindings);\n }\n\n // No issues\n if (result.findings.length === 0) {\n lines.push('---');\n lines.push('');\n lines.push('## ✨ No Issues Found');\n lines.push('');\n lines.push('Great job! Your code passed all checks.');\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nfunction formatFindings(lines: string[], findings: CodeReviewFinding[]): void {\n for (const finding of findings) {\n lines.push(`### ${finding.id}: ${finding.title}`);\n lines.push('');\n lines.push(`**Category**: ${formatCategoryName(finding.category)}`);\n lines.push(`**File**: \\`${finding.file}${finding.line ? `:${finding.line}` : ''}\\``);\n if (finding.cweId) {\n lines.push(`**CWE**: ${finding.cweId}`);\n }\n lines.push('');\n lines.push(finding.description);\n lines.push('');\n if (finding.code) {\n lines.push('**Code**:');\n lines.push('```');\n lines.push(finding.code);\n lines.push('```');\n lines.push('');\n }\n lines.push(`**Fix**: ${finding.suggestion}`);\n if (finding.autoFixable) {\n lines.push('');\n lines.push('> 💡 This issue can be auto-fixed.');\n }\n if (finding.references && finding.references.length > 0) {\n lines.push('');\n lines.push('**References**:');\n for (const ref of finding.references) {\n lines.push(`- ${ref}`);\n }\n }\n lines.push('');\n }\n}\n\nfunction formatCategoryName(category: string): string {\n const names: Record<string, string> = {\n security: 'Security',\n architecture: 'Architecture',\n 'hardcoded-values': 'Hardcoded Values',\n tests: 'Tests',\n 'ai-hallucinations': 'AI Hallucinations',\n performance: 'Performance',\n 'dead-code': 'Dead Code',\n i18n: 'Internationalization',\n accessibility: 'Accessibility',\n };\n return names[category] || category;\n}\n","/**\n * review_code Tool\n * Comprehensive code review system for SmartStack projects\n *\n * Analyzes code for:\n * - Security vulnerabilities (OWASP)\n * - Architecture violations (Clean Architecture layers)\n * - Hardcoded values (magic numbers, strings)\n * - Test coverage\n * - AI-generated code issues (hallucinations)\n * - Performance anti-patterns (N+1, over-fetching)\n * - Dead code (unused imports, functions)\n * - Internationalization (i18n)\n * - Accessibility (a11y)\n */\n\nimport { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { Config } from '../types/index.js';\nimport { ReviewCodeInputSchema } from '../types/index.js';\nimport { findSmartStackStructure } from '../lib/detector.js';\nimport { findFiles, readText } from '../utils/fs.js';\nimport { getChangedFiles, getStagedFiles } from '../utils/git.js';\nimport { logger } from '../lib/logger.js';\n\nimport type {\n CodeReviewResult,\n CodeReviewFinding,\n CheckContext,\n FileInfo,\n ReviewCategory,\n} from './review-code/types.js';\nimport { resetFindingCounters } from './review-code/types.js';\n\nimport { checkSecurity } from './review-code/checks/security.js';\nimport { checkArchitecture } from './review-code/checks/architecture.js';\nimport { checkHardcodedValues } from './review-code/checks/hardcoded-values.js';\nimport { checkTests } from './review-code/checks/tests.js';\nimport { checkAiHallucinations } from './review-code/checks/ai-hallucinations.js';\nimport { checkPerformance } from './review-code/checks/performance.js';\nimport { checkDeadCode } from './review-code/checks/dead-code.js';\nimport { checkI18n } from './review-code/checks/i18n.js';\nimport { checkAccessibility } from './review-code/checks/accessibility.js';\nimport { formatMarkdownReport } from './review-code/formatters/markdown.js';\n\n// Tool Definition\nexport const reviewCodeTool: Tool = {\n name: 'review_code',\n description: `Comprehensive code review tool for SmartStack projects.\n\nAnalyzes code for 9 categories of issues:\n- **security**: OWASP vulnerabilities, hardcoded secrets, SQL injection, XSS\n- **architecture**: Clean Architecture layer violations\n- **hardcoded-values**: Magic numbers, hardcoded URLs, feature flags\n- **tests**: Missing tests, test quality issues\n- **ai-hallucinations**: Non-existent imports, phantom methods\n- **performance**: N+1 queries, over-fetching, missing memoization\n- **dead-code**: Unused imports, functions, variables\n- **i18n**: Non-internationalized UI text\n- **accessibility**: Missing alt text, ARIA issues, focus indicators\n\nReturns a markdown report with findings grouped by severity (blocking, critical, warning, info).`,\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description: 'Project path to review (default: SmartStack.app path)',\n },\n scope: {\n type: 'string',\n enum: ['all', 'changed', 'staged'],\n default: 'all',\n description: 'Files to review: all, only changed (git diff), or staged files',\n },\n checks: {\n type: 'array',\n items: {\n type: 'string',\n enum: [\n 'security',\n 'architecture',\n 'hardcoded-values',\n 'tests',\n 'ai-hallucinations',\n 'performance',\n 'dead-code',\n 'i18n',\n 'accessibility',\n 'all',\n ],\n },\n default: ['all'],\n description: 'Categories of checks to run',\n },\n severity: {\n type: 'string',\n enum: ['blocking', 'critical', 'warning', 'all'],\n default: 'all',\n description: 'Filter results by minimum severity',\n },\n },\n },\n};\n\n// Handler\nexport async function handleReviewCode(args: unknown, config: Config): Promise<string> {\n const startTime = Date.now();\n\n // Parse and validate input\n const input = ReviewCodeInputSchema.parse(args);\n const projectPath = input.path || config.smartstack.projectPath;\n\n logger.info('Starting code review', { projectPath, scope: input.scope, checks: input.checks });\n\n // Reset finding ID counters\n resetFindingCounters();\n\n // Detect project structure\n const structure = await findSmartStackStructure(projectPath);\n if (!structure) {\n return '# Code Review Error\\n\\nCould not detect SmartStack project structure at the specified path.';\n }\n\n // Get files to analyze\n const files = await getFilesToAnalyze(projectPath, input.scope, structure);\n\n if (files.length === 0) {\n return '# Code Review Report\\n\\nNo files to analyze for the specified scope.';\n }\n\n logger.info(`Analyzing ${files.length} files`);\n\n // Build check context\n const context: CheckContext = {\n projectPath,\n files,\n scope: input.scope,\n };\n\n // Determine which checks to run\n const checksToRun = input.checks.includes('all')\n ? ['security', 'architecture', 'hardcoded-values', 'tests', 'ai-hallucinations', 'performance', 'dead-code', 'i18n', 'accessibility']\n : input.checks;\n\n // Run checks in parallel\n const checkFunctions: Record<string, (ctx: CheckContext) => Promise<CodeReviewFinding[]>> = {\n security: checkSecurity,\n architecture: checkArchitecture,\n 'hardcoded-values': checkHardcodedValues,\n tests: checkTests,\n 'ai-hallucinations': checkAiHallucinations,\n performance: checkPerformance,\n 'dead-code': checkDeadCode,\n i18n: checkI18n,\n accessibility: checkAccessibility,\n };\n\n const checkPromises = checksToRun\n .filter((check) => checkFunctions[check])\n .map(async (check) => {\n try {\n logger.debug(`Running ${check} check`);\n return await checkFunctions[check](context);\n } catch (error) {\n logger.error(`Error in ${check} check`, { error });\n return [];\n }\n });\n\n const checkResults = await Promise.all(checkPromises);\n const allFindings = checkResults.flat();\n\n // Filter by severity if specified\n const filteredFindings = filterBySeverity(allFindings, input.severity);\n\n // Calculate stats\n const stats = calculateStats(filteredFindings, files, startTime);\n\n // Calculate summary\n const summary = calculateSummary(filteredFindings, stats);\n\n // Build result\n const result: CodeReviewResult = {\n summary,\n findings: filteredFindings,\n stats,\n };\n\n logger.info('Code review complete', {\n filesScanned: stats.filesScanned,\n issuesFound: filteredFindings.length,\n duration: stats.duration,\n });\n\n // Format and return\n return formatMarkdownReport(result);\n}\n\n// Helper Functions\n\nasync function getFilesToAnalyze(\n projectPath: string,\n scope: 'all' | 'changed' | 'staged',\n _structure: Awaited<ReturnType<typeof findSmartStackStructure>>\n): Promise<FileInfo[]> {\n let filePaths: string[] = [];\n\n if (scope === 'changed') {\n filePaths = await getChangedFiles(projectPath);\n } else if (scope === 'staged') {\n filePaths = await getStagedFiles(projectPath);\n } else {\n // Get all source files\n const patterns = ['**/*.cs', '**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'];\n const excludePatterns = ['**/bin/**', '**/obj/**', '**/node_modules/**', '**/dist/**', '**/*.d.ts', '**/Migrations/**'];\n\n for (const pattern of patterns) {\n const found = await findFiles(pattern, {\n cwd: projectPath,\n ignore: excludePatterns,\n });\n filePaths.push(...found);\n }\n }\n\n // Read file contents and build FileInfo objects\n const files: FileInfo[] = [];\n\n for (const filePath of filePaths) {\n try {\n const fullPath = filePath.startsWith(projectPath)\n ? filePath\n : `${projectPath}/${filePath}`;\n\n const content = await readText(fullPath);\n const relativePath = filePath.replace(projectPath, '').replace(/^[/\\\\]/, '');\n\n files.push({\n path: fullPath,\n relativePath,\n content,\n language: detectLanguage(filePath),\n layer: detectLayer(relativePath),\n lineCount: content.split('\\n').length,\n });\n } catch {\n // Skip files that can't be read\n logger.debug(`Could not read file: ${filePath}`);\n }\n }\n\n return files;\n}\n\nfunction detectLanguage(filePath: string): FileInfo['language'] {\n const ext = filePath.toLowerCase().split('.').pop();\n switch (ext) {\n case 'cs':\n return 'csharp';\n case 'ts':\n return 'typescript';\n case 'tsx':\n return 'tsx';\n case 'js':\n return 'javascript';\n case 'jsx':\n return 'jsx';\n case 'css':\n return 'css';\n case 'json':\n return 'json';\n default:\n return 'other';\n }\n}\n\nfunction detectLayer(relativePath: string): FileInfo['layer'] {\n const lower = relativePath.toLowerCase();\n if (lower.includes('/domain/') || lower.includes('\\\\domain\\\\')) return 'domain';\n if (lower.includes('/application/') || lower.includes('\\\\application\\\\')) return 'application';\n if (lower.includes('/infrastructure/') || lower.includes('\\\\infrastructure\\\\')) return 'infrastructure';\n if (lower.includes('/api/') || lower.includes('\\\\api\\\\')) return 'api';\n if (lower.includes('/web/') || lower.includes('\\\\web\\\\') || lower.includes('/src/')) return 'web';\n return undefined;\n}\n\nfunction filterBySeverity(\n findings: CodeReviewFinding[],\n minSeverity: 'blocking' | 'critical' | 'warning' | 'all'\n): CodeReviewFinding[] {\n if (minSeverity === 'all') return findings;\n\n const severityOrder = ['blocking', 'critical', 'warning', 'info'];\n const minIndex = severityOrder.indexOf(minSeverity);\n\n return findings.filter((f) => severityOrder.indexOf(f.severity) <= minIndex);\n}\n\nfunction calculateStats(\n findings: CodeReviewFinding[],\n files: FileInfo[],\n startTime: number\n): CodeReviewResult['stats'] {\n const byCategory: Record<ReviewCategory, number> = {\n security: 0,\n architecture: 0,\n 'hardcoded-values': 0,\n tests: 0,\n 'ai-hallucinations': 0,\n performance: 0,\n 'dead-code': 0,\n i18n: 0,\n accessibility: 0,\n };\n\n const findingsCount = {\n blocking: 0,\n critical: 0,\n warning: 0,\n info: 0,\n };\n\n for (const finding of findings) {\n findingsCount[finding.severity]++;\n byCategory[finding.category]++;\n }\n\n return {\n filesScanned: files.length,\n linesScanned: files.reduce((sum, f) => sum + f.lineCount, 0),\n duration: Date.now() - startTime,\n findingsCount,\n byCategory,\n };\n}\n\nfunction calculateSummary(\n _findings: CodeReviewFinding[],\n stats: CodeReviewResult['stats']\n): CodeReviewResult['summary'] {\n // Calculate score (100 - penalties)\n let score = 100;\n score -= stats.findingsCount.blocking * 20; // -20 per blocking\n score -= stats.findingsCount.critical * 5; // -5 per critical\n score -= stats.findingsCount.warning * 1; // -1 per warning\n score = Math.max(0, Math.min(100, score));\n\n // Determine grade\n let grade: 'A' | 'B' | 'C' | 'D' | 'F';\n if (score >= 90) grade = 'A';\n else if (score >= 80) grade = 'B';\n else if (score >= 70) grade = 'C';\n else if (score >= 60) grade = 'D';\n else grade = 'F';\n\n // Determine status\n let status: 'passed' | 'failed' | 'warning';\n if (stats.findingsCount.blocking > 0) {\n status = 'failed';\n } else if (stats.findingsCount.critical > 0) {\n status = 'warning';\n } else {\n status = 'passed';\n }\n\n // Build message\n let message: string;\n if (status === 'failed') {\n message = `Review failed with ${stats.findingsCount.blocking} blocking issue(s). These must be fixed before merging.`;\n } else if (status === 'warning') {\n message = `Review passed with warnings. ${stats.findingsCount.critical} critical issue(s) should be addressed.`;\n } else {\n message = 'Code review passed. Great job!';\n }\n\n return { status, score, grade, message };\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, scopeTypes, 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 Scope System\n\nAll navigation data (Context, Application, Module, Section) uses a **Scope** field to distinguish system data from client extensions:\n\n| Scope | Usage | Description | Example Code |\n|-------|-------|-------------|--------------|\n| \\`${scopeTypes[0]}\\` | SmartStack platform | Protected, delivered with SmartStack | \\`administration\\`, \\`users\\` |\n| \\`${scopeTypes[1]}\\` | Client extensions | Custom, added by clients | \\`inventory\\`, \\`custom_app\\` |\n| \\`${scopeTypes[2]}\\` | Partner modules | Provided by certified partners | \\`partner_integration\\` |\n| \\`${scopeTypes[3]}\\` | Community modules | Open-source community contributions | \\`community_tool\\` |\n\n**Navigation Hierarchy (4 levels):**\n\n\\`\\`\\`\nContext → Application → Module → Section\n\\`\\`\\`\n\n**Examples for each level:**\n\n| Level | Core Example | Extension Example |\n|-------|--------------|-------------------|\n| Context | Code: \\`platform\\`<br/>Scope: \\`${scopeTypes[0]}\\` | Code: \\`business\\`<br/>Scope: \\`${scopeTypes[1]}\\` |\n| Application | Code: \\`administration\\`<br/>Scope: \\`${scopeTypes[0]}\\` | Code: \\`custom_app\\`<br/>Scope: \\`${scopeTypes[1]}\\` |\n| Module | Code: \\`users\\`<br/>Route: \\`platform.administration.users\\`<br/>Scope: \\`${scopeTypes[0]}\\` | Code: \\`inventory\\`<br/>Route: \\`business.operations.inventory\\`<br/>Scope: \\`${scopeTypes[1]}\\` |\n| Section | Code: \\`management\\`<br/>Scope: \\`${scopeTypes[0]}\\` | Code: \\`reports\\`<br/>Scope: \\`${scopeTypes[1]}\\` |\n\n**Rules:**\n1. \\`${scopeTypes[0]}\\` modules are **protected** - clients cannot create or modify them\n2. \\`${scopeTypes[1]}\\` modules are **free** - clients can create custom navigation\n3. SmartStack updates will never overwrite \\`${scopeTypes[1]}\\` data\n4. **Routes must be globally unique** (enforced by unique constraint on Route column)\n5. Codes no longer use prefixes - the Scope field provides categorization\n\n### RBAC Scope System\n\nPermissions and Roles also use the **Scope** field for the same categorization:\n\n#### Permissions\n\n| Table | Field | Values | Protection |\n|-------|-------|--------|------------|\n| \\`core.auth_Permissions\\` | \\`Scope\\` | ${scopeTypes.join(', ')} | ${scopeTypes[0]} permissions cannot be deleted |\n\n**Automatic Scope Detection:**\n\nPermissions inherit their Scope from the module's NavRoute:\n\n\\`\\`\\`\nNavRoute: \"platform.administration.users\"\nModule Scope: Core\n→ Permissions Scope: Core\n - platform.administration.users.read (Core)\n - platform.administration.users.create (Core)\n - platform.administration.users.update (Core)\n - platform.administration.users.delete (Core)\n\\`\\`\\`\n\n**Detection Rules:**\n- Routes starting with \\`platform.*\\` or \\`business.*\\` (system contexts) → \\`${scopeTypes[0]}\\`\n- Routes from Extension contexts → \\`${scopeTypes[1]}\\`\n- Partner-provided routes → \\`${scopeTypes[2]}\\`\n- Community routes → \\`${scopeTypes[3]}\\`\n\n#### Roles\n\n| Table | Field | Values | Protection |\n|-------|-------|--------|------------|\n| \\`core.auth_Roles\\` | \\`Scope\\` | ${scopeTypes.join(', ')} | ${scopeTypes[0]} roles cannot be deleted |\n\n**Default Roles (Microsoft Fabric Model):**\n\nAll default roles have \\`Scope = '${scopeTypes[0]}'\\` (protected):\n\n| Code | Scope | Permissions |\n|------|-------|-------------|\n| \\`admin\\` | ${scopeTypes[0]} | All permissions (read, create, update, delete) |\n| \\`member\\` | ${scopeTypes[0]} | Read, create, update + user management (no delete) |\n| \\`contributor\\` | ${scopeTypes[0]} | Read, create, update (no delete, no user management) |\n| \\`viewer\\` | ${scopeTypes[0]} | Read only |\n\n**Custom Roles:**\n\nClients can create roles with \\`Scope = '${scopeTypes[1]}'\\`:\n\n\\`\\`\\`sql\nINSERT INTO core.auth_Roles (Id, Code, Scope, Name, Description, ...)\nVALUES (\n NEWID(),\n 'sales_manager',\n '${scopeTypes[1]}', -- Custom role\n 'Sales Manager',\n 'Manage sales operations',\n ...\n);\n\\`\\`\\`\n\n**Protection Rules:**\n- \\`${scopeTypes[0]}\\` roles and permissions: **Read-only** for clients (seeded with migrations)\n- \\`${scopeTypes[1]}\\` roles and permissions: **Full control** for clients\n- \\`${scopeTypes[2]}\\` roles and permissions: **Managed by partners**\n- \\`${scopeTypes[3]}\\` roles and permissions: **Open-source community**\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. **No prefixes required** - Use Scope field for categorization (navigation entities)\n3. **Unique composite index**: \\`(TenantId, Code) WHERE IsDeleted = 0\\`\n4. **Max length**: 100 characters\n5. **Navigation routes**: Globally unique via unique constraint on Route column\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## 10. Frontend Conventions\n\n### Layout Standards\n\nAll context layouts MUST follow the AdminLayout pattern for consistent user experience.\n\n#### Standard Structure\n\n\\`\\`\\`tsx\n<main className={\\`pt-16 transition-all duration-300 \\${\n showSidebar ? (isCollapsed ? 'lg:pl-16' : 'lg:pl-64') : ''\n}\\`}>\n <div className=\"p-4 sm:p-6 lg:px-10 h-full overflow-auto\">\n <Outlet />\n </div>\n</main>\n\\`\\`\\`\n\n#### Layout Rules\n\n| Rule | Description |\n|------|-------------|\n| No \\`max-w-*\\` | Content MUST occupy full available width |\n| Horizontal padding | Use \\`lg:px-10\\` for consistent padding |\n| Scroll container | Use \\`h-full overflow-auto\\` for internal scrolling |\n| Sidebar conditional | \\`showSidebar = !!currentAppCode\\` |\n\n### Tab Navigation with URL\n\nPages with tabs MUST synchronize tab state with URL for shareable links and browser navigation.\n\n#### useTabNavigation Hook\n\n\\`\\`\\`tsx\nimport { useTabNavigation } from '@/hooks/useTabNavigation';\n\n// 1. Define valid tabs\nconst VALID_TABS = ['info', 'settings', 'permissions'] as const;\ntype TabId = typeof VALID_TABS[number];\n\n// 2. Use the hook\nconst { activeTab, setActiveTab } = useTabNavigation<TabId>('info', VALID_TABS);\n\n// 3. Use in JSX\n<button onClick={() => setActiveTab('settings')}>Settings</button>\n\\`\\`\\`\n\n#### URL Behavior\n\n| URL | Active Tab |\n|-----|------------|\n| \\`/page\\` | Default tab (e.g., \\`info\\`) |\n| \\`/page?tab=settings\\` | \\`settings\\` |\n| \\`/page?tab=invalid\\` | Default tab (fallback) |\n\n#### Hook Characteristics\n\n- URL is clean for default tab (no \\`?tab=\\` parameter)\n- Invalid tabs fallback to default\n- Uses \\`replace: true\\` to avoid polluting browser history\n\n#### Lazy Loading for Tabs (Performance)\n\nPages with tabs MUST implement lazy loading to avoid fetching all tab data upfront.\n\n**Pattern 1: useQuery with enabled condition (Recommended)**\n\n\\`\\`\\`tsx\n// ❌ BAD - Loads all data on mount\nconst { data: info } = useQuery(['info', id], fetchInfo);\nconst { data: settings } = useQuery(['settings', id], fetchSettings);\n\n// ✅ GOOD - Only loads active tab data\nconst { data: info } = useQuery(\n ['info', id],\n fetchInfo,\n { enabled: activeTab === 'info' }\n);\n\nconst { data: settings } = useQuery(\n ['settings', id],\n fetchSettings,\n { enabled: activeTab === 'settings' }\n);\n\\`\\`\\`\n\n**Pattern 2: React.lazy() for heavy tab components**\n\n\\`\\`\\`tsx\n// Lazy load tab components\nconst TabInfo = React.lazy(() => import('./tabs/TabInfo'));\nconst TabSettings = React.lazy(() => import('./tabs/TabSettings'));\n\n// In JSX with Suspense\n<TabsContent value=\"info\">\n <Suspense fallback={<Skeleton />}>\n <TabInfo entityId={id} />\n </Suspense>\n</TabsContent>\n\\`\\`\\`\n\n**Pattern 3: Conditional rendering**\n\n\\`\\`\\`tsx\n// Render tab content only when active\n{activeTab === 'settings' && <SettingsTab entityId={id} />}\n\\`\\`\\`\n\n| Pattern | Use Case |\n|---------|----------|\n| useQuery enabled | Simple data fetching per tab |\n| React.lazy + Suspense | Heavy components with own data fetching |\n| Conditional rendering | Light components, quick tab switches |\n\n### Breadcrumb Navigation\n\nAll pages MUST include a Breadcrumb component for consistent navigation and user orientation.\n\n#### Breadcrumb Component\n\n\\`\\`\\`tsx\nimport { Breadcrumb } from '@/components/ui/Breadcrumb';\n\n// In your page component\n<Breadcrumb\n items={[\n { label: t('nav.administration'), href: '/platform/administration' },\n { label: t('nav.users'), href: '/platform/administration/users' },\n { label: user.fullName } // Last item = current page (no href)\n ]}\n/>\n\\`\\`\\`\n\n#### Breadcrumb Rules\n\n| Rule | Description |\n|------|-------------|\n| First item | Context/Application level with Home icon (auto-added if no icon) |\n| Intermediate items | Clickable links to parent pages |\n| Last item | Current page name, no href, bold text |\n| Labels | Use i18n translation keys from \\`navigation.json\\` |\n| Detail pages | Include entity name (e.g., user's full name) |\n\n#### Hierarchy Pattern\n\n\\`\\`\\`\nContext > Application > Module > [Section] > [Entity Name]\n\\`\\`\\`\n\n**Examples:**\n\n| Page Type | Breadcrumb Items |\n|-----------|------------------|\n| List page | Administration > Users |\n| Detail page | Administration > Users > John Doe |\n| Nested page | Administration > Users > John Doe > Permissions |\n\n#### BreadcrumbItem Interface\n\n\\`\\`\\`tsx\ninterface BreadcrumbItem {\n label: string; // Display text (use t() for i18n)\n href?: string; // Link destination (omit for current page)\n icon?: ReactNode; // Optional icon (Home auto-added to first item)\n}\n\\`\\`\\`\n\n#### Page Position\n\nBreadcrumb should be the FIRST element in the page content:\n\n\\`\\`\\`tsx\nreturn (\n <div className=\"space-y-6\">\n {/* 1. Breadcrumb - always first */}\n <Breadcrumb items={[...]} />\n\n {/* 2. Scope Banner (if multi-tenant) */}\n <ScopeBanner />\n\n {/* 3. Page Header */}\n <div className=\"flex items-center gap-4\">...</div>\n\n {/* 4. Page Content */}\n ...\n </div>\n);\n\\`\\`\\`\n\n### Frontend Validation Checks\n\n| Check | Description |\n|-------|-------------|\n| \\`layouts\\` | Verify no \\`max-w-*\\` in content wrapper, standard padding present |\n| \\`tabs\\` | Verify \\`useTabNavigation\\` hook usage AND lazy loading patterns for pages with tabs |\n| \\`breadcrumb\\` | Verify Breadcrumb component present as first element in page |\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| Scope types | \\`${scopeTypes.join(', ')}\\` | Navigation entities use Scope field |\n| Navigation codes | No prefixes | \\`administration\\`, \\`users\\` (Scope determines origin) |\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| RBAC Scope | Permissions, Roles, Navigation | ${scopeTypes.join(', ')} |\n| Default roles | Scope = ${scopeTypes[0]} | admin, member, contributor, viewer |\n| Custom roles | Scope = ${scopeTypes[1]} | Client-defined roles |\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| Layout wrapper | No \\`max-w-*\\` | Content fills available width |\n| Layout padding | \\`lg:px-10\\` | Standard horizontal padding |\n| Tab navigation | \\`useTabNavigation\\` hook | Sync tabs with URL |\n| Tab URL | \\`?tab=name\\` | Shareable deep links to tabs |\n| Tab lazy loading | \\`enabled: activeTab === 'x'\\` | Load data only for active tab |\n| Breadcrumb | \\`<Breadcrumb items={[...]}/>\\` | Navigation hierarchy, first page element |\n| Breadcrumb items | \\`{ label, href?, icon? }\\` | Last item without href = current page |\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) : 'src/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'}`);\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","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';\nimport { handleGeneratePermissions, generatePermissionsTool } from './tools/generate-permissions.js';\n\n// Test Tools\nimport { handleScaffoldTests, scaffoldTestsTool } from './tools/scaffold-tests.js';\nimport { handleAnalyzeTestCoverage, analyzeTestCoverageTool } from './tools/analyze-test-coverage.js';\nimport { handleValidateTestConventions, validateTestConventionsTool } from './tools/validate-test-conventions.js';\nimport { handleSuggestTestScenarios, suggestTestScenariosTool } from './tools/suggest-test-scenarios.js';\n\n// Frontend Route Tools\nimport { handleScaffoldApiClient, scaffoldApiClientTool } from './tools/scaffold-api-client.js';\nimport { handleScaffoldRoutes, scaffoldRoutesTool } from './tools/scaffold-routes.js';\nimport { handleValidateFrontendRoutes, validateFrontendRoutesTool } from './tools/validate-frontend-routes.js';\n\n// Frontend Extension Tools\nimport { handleScaffoldFrontendExtension, scaffoldFrontendExtensionTool } from './tools/scaffold-frontend-extension.js';\nimport { handleAnalyzeExtensionPoints, analyzeExtensionPointsTool } from './tools/analyze-extension-points.js';\n\n// Security & Code Quality Tools\nimport { handleValidateSecurity, validateSecurityTool } from './tools/validate-security.js';\nimport { handleAnalyzeCodeQuality, analyzeCodeQualityTool } from './tools/analyze-code-quality.js';\n\n// Hierarchy Analysis Tools\nimport { handleAnalyzeHierarchyPatterns, analyzeHierarchyPatternsTool } from './tools/analyze-hierarchy-patterns.js';\n\n// Code Review Tool\nimport { handleReviewCode, reviewCodeTool } from './tools/review-code.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.10.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 generatePermissionsTool,\n // Test Tools\n scaffoldTestsTool,\n analyzeTestCoverageTool,\n validateTestConventionsTool,\n suggestTestScenariosTool,\n // Frontend Route Tools\n scaffoldApiClientTool,\n scaffoldRoutesTool,\n validateFrontendRoutesTool,\n // Frontend Extension Tools\n scaffoldFrontendExtensionTool,\n analyzeExtensionPointsTool,\n // Security & Code Quality Tools\n validateSecurityTool,\n analyzeCodeQualityTool,\n // Hierarchy Analysis Tools\n analyzeHierarchyPatternsTool,\n // Code Review Tool\n reviewCodeTool,\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 case 'generate_permissions':\n result = await handleGeneratePermissions(args, config);\n break;\n\n // Test Tools\n case 'scaffold_tests':\n result = await handleScaffoldTests(args, config);\n break;\n\n case 'analyze_test_coverage':\n result = await handleAnalyzeTestCoverage(args, config);\n break;\n\n case 'validate_test_conventions':\n result = await handleValidateTestConventions(args, config);\n break;\n\n case 'suggest_test_scenarios':\n result = await handleSuggestTestScenarios(args, config);\n break;\n\n // Frontend Route Tools\n case 'scaffold_api_client':\n result = await handleScaffoldApiClient(args ?? {}, config);\n break;\n\n case 'scaffold_routes':\n result = await handleScaffoldRoutes(args ?? {}, config);\n break;\n\n case 'validate_frontend_routes':\n result = await handleValidateFrontendRoutes(args ?? {}, config);\n break;\n\n // Frontend Extension Tools\n case 'scaffold_frontend_extension':\n result = await handleScaffoldFrontendExtension(args ?? {}, config);\n break;\n\n case 'analyze_extension_points':\n result = await handleAnalyzeExtensionPoints(args ?? {}, config);\n break;\n\n // Security & Code Quality Tools\n case 'validate_security':\n result = await handleValidateSecurity(args ?? {}, config);\n break;\n\n case 'analyze_code_quality':\n result = await handleAnalyzeCodeQuality(args ?? {}, config);\n break;\n\n // Hierarchy Analysis Tools\n case 'analyze_hierarchy_patterns':\n result = await handleAnalyzeHierarchyPatterns(args ?? {}, config);\n break;\n\n // Code Review Tool\n case 'review_code':\n result = await handleReviewCode(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","import { runServer } from './mcp/server.js';\nimport { logger } from './mcp/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":";;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAcM,QAoEO,QAGP;AArFN;AAAA;AAAA;AAAA;AAcA,IAAM,SAAN,MAAa;AAAA,MACH,QAAkB;AAAA,MACT,SAAmC;AAAA,QAClD,OAAO;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACT;AAAA,MAEA,SAAS,OAAuB;AAC9B,aAAK,QAAQ;AAAA,MACf;AAAA,MAEQ,UAAU,OAA0B;AAC1C,eAAO,KAAK,OAAO,KAAK,KAAK,KAAK,OAAO,KAAK,KAAK;AAAA,MACrD;AAAA,MAEQ,YAAY,OAAiB,SAAiB,MAAwB;AAC5E,cAAM,QAAkB;AAAA,UACtB,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UAClC;AAAA,UACA;AAAA,UACA,GAAI,SAAS,UAAa,EAAE,KAAK;AAAA,QACnC;AACA,eAAO,KAAK,UAAU,KAAK;AAAA,MAC7B;AAAA,MAEA,MAAM,SAAiB,MAAsB;AAC3C,YAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,kBAAQ,MAAM,KAAK,YAAY,SAAS,SAAS,IAAI,CAAC;AAAA,QACxD;AAAA,MACF;AAAA,MAEA,KAAK,SAAiB,MAAsB;AAC1C,YAAI,KAAK,UAAU,MAAM,GAAG;AAC1B,kBAAQ,MAAM,KAAK,YAAY,QAAQ,SAAS,IAAI,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,MAEA,KAAK,SAAiB,MAAsB;AAC1C,YAAI,KAAK,UAAU,MAAM,GAAG;AAC1B,kBAAQ,MAAM,KAAK,YAAY,QAAQ,SAAS,IAAI,CAAC;AAAA,QACvD;AAAA,MACF;AAAA,MAEA,MAAM,SAAiB,MAAsB;AAC3C,YAAI,KAAK,UAAU,OAAO,GAAG;AAC3B,kBAAQ,MAAM,KAAK,YAAY,SAAS,SAAS,IAAI,CAAC;AAAA,QACxD;AAAA,MACF;AAAA;AAAA,MAGA,UAAU,UAAkB,MAAqB;AAC/C,aAAK,KAAK,iBAAiB,QAAQ,IAAI,EAAE,KAAK,CAAC;AAAA,MACjD;AAAA,MAEA,QAAQ,UAAkB,SAAkB,UAAyB;AACnE,aAAK,KAAK,mBAAmB,QAAQ,IAAI,EAAE,SAAS,SAAS,CAAC;AAAA,MAChE;AAAA,MAEA,UAAU,UAAkB,OAAoB;AAC9C,aAAK,MAAM,gBAAgB,QAAQ,IAAI;AAAA,UACrC,OAAO,MAAM;AAAA,UACb,OAAO,MAAM;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AAEO,IAAM,SAAS,IAAI,OAAO;AAGjC,IAAM,WAAW,QAAQ,IAAI;AAC7B,QAAI,YAAY,CAAC,SAAS,QAAQ,QAAQ,OAAO,EAAE,SAAS,QAAQ,GAAG;AACrE,aAAO,SAAS,QAAQ;AAAA,IAC1B;AAAA;AAAA;;;ACxFA,SAAS,MAAM,OAAO,UAAU,WAAW,IAAI,UAAU;AACzD,OAAOA,WAAU;AACjB,SAAS,YAAY;AAqBd,SAAS,qBACd,YACA,SACM;AACN,QAAM,mBAAmBA,MAAK,QAAQ,UAAU;AAChD,QAAM,iBAAiBA,MAAK,QAAQ,OAAO;AAG3C,MAAI,CAAC,iBAAiB,WAAW,iBAAiBA,MAAK,GAAG,KAAK,qBAAqB,gBAAgB;AAClG,UAAM,IAAI;AAAA,MACR,6BAA6B,UAAU,mCAAmC,OAAO;AAAA,MACjF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,aAAa,YAAoB,UAA4B;AAC3E,QAAM,SAASA,MAAK,KAAK,SAAS,GAAG,QAAQ;AAC7C,uBAAqB,QAAQ,OAAO;AACpC,SAAO;AACT;AAKA,eAAsB,WAAW,UAAoC;AACnE,MAAI;AACF,UAAM,IAAI,MAAM,KAAK,QAAQ;AAC7B,WAAO,EAAE,OAAO;AAAA,EAClB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBAAgB,SAAmC;AACvE,MAAI;AACF,UAAM,IAAI,MAAM,KAAK,OAAO;AAC5B,WAAO,EAAE,YAAY;AAAA,EACvB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBAAgB,SAAgC;AACpE,QAAM,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;AAC1C;AAKA,eAAsB,SAAY,UAA8B;AAC9D,MAAI;AACF,UAAM,UAAU,MAAM,SAAS,UAAU,OAAO;AAChD,QAAI;AACF,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B,SAAS,YAAY;AACnB,YAAM,IAAI;AAAA,QACR,yBAAyB,QAAQ;AAAA,QACjC;AAAA,QACA;AAAA,QACA,sBAAsB,QAAQ,aAAa;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,QAAI,iBAAiB,iBAAiB;AACpC,YAAM;AAAA,IACR;AACA,UAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,UAAM,IAAI;AAAA,MACR,6BAA6B,QAAQ,MAAM,IAAI,OAAO;AAAA,MACtD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAuBA,eAAsB,SAAS,UAAmC;AAChE,MAAI;AACF,WAAO,MAAM,SAAS,UAAU,OAAO;AAAA,EACzC,SAAS,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,UAAM,IAAI;AAAA,MACR,wBAAwB,QAAQ,MAAM,IAAI,OAAO;AAAA,MACjD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,UAAU,UAAkB,SAAgC;AAChF,MAAI;AACF,UAAM,MAAMA,MAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,UAAM,UAAU,UAAU,SAAS,OAAO;AAAA,EAC5C,SAAS,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACpE,UAAM,IAAI;AAAA,MACR,yBAAyB,QAAQ,MAAM,IAAI,OAAO;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;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;AA1MA,IAOa;AAPb;AAAA;AAAA;AAAA;AAOO,IAAM,kBAAN,cAA8B,MAAM;AAAA,MACzC,YACE,SACgB,WACAA,QACA,OAChB;AACA,cAAM,OAAO;AAJG;AACA,oBAAAA;AACA;AAGhB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACjBA,SAAS,SAAS;AAAlB,IAOa,qBAUA,wBAMA,yBAuBA,qBAMA,oBASA,yBAUA,cAqBA,gCAOA,4BAMA,sBAOA,8BA6BA,oBAOA,6BAMA,gCAmBA,gBACA,kBAEA,0BAkBA,gCAOA,oCAQA,iCAgBA,qBAaA,6BASA,qBAcA,+BAiSA,8BAeA,2BAiBA,mCA6DA,sBAMA,sCAYA,mCAgEA,qCAaA,uBAaA;AA/uBb;AAAA;AAAA;AAAA;AAOO,IAAM,sBAAsB,EAAE,OAAO;AAAA,MAC1C,aAAa,EAAE,KAAK,CAAC,UAAU,UAAU,CAAC,EAAE,QAAQ,UAAU;AAAA,MAC9D,WAAW,EAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,QAAQ,MAAM;AAAA,MACxD,eAAe,EAAE,OAAO,EAAE,SAAS;AAAA,MACnC,mBAAmB,EAAE,OAAO,EAAE,SAAS;AAAA,MACvC,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,IACnC,CAAC;AAIM,IAAM,yBAAyB,EAAE,OAAO;AAAA,MAC7C,aAAa,EAAE,OAAO;AAAA,MACtB,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,MAClC,YAAY,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,IACtC,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,MAC9C,SAAS,EAAE,OAAO;AAAA,QAChB,UAAU,EAAE,OAAO,EAAE,QAAQ,MAAM;AAAA,QACnC,YAAY,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,MAC7C,CAAC;AAAA,MACD,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ;AAAA,QACzC;AAAA,QAAS;AAAA,QAAQ;AAAA,QAAQ;AAAA,QAAO;AAAA,QAAQ;AAAA,QACxC;AAAA,QAAY;AAAA,QAAU;AAAA,QAAQ;AAAA,QAAQ;AAAA,MACxC,CAAC;AAAA,MACD,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,QAAQ,aAAa,WAAW,WAAW,CAAC;AAAA,MACrF,iBAAiB,EAAE,OAAO,EAAE,QAAQ,+CAA+C;AAAA,MACnF,YAAY,EAAE,OAAO;AAAA,QACnB,QAAQ,EAAE,OAAO;AAAA,QACjB,aAAa,EAAE,OAAO;AAAA,QACtB,gBAAgB,EAAE,OAAO;AAAA,QACzB,KAAK,EAAE,OAAO;AAAA,MAChB,CAAC;AAAA,MACD,gBAAgB,EAAE,OAAO;AAAA,QACvB,WAAW,EAAE,OAAO,EAAE,QAAQ,gBAAgB;AAAA,QAC9C,gBAAgB,EAAE,OAAO,EAAE,QAAQ,eAAe;AAAA,MACpD,CAAC;AAAA,IACH,CAAC;AAEM,IAAM,sBAAsB,EAAE,OAAO;AAAA,MAC1C,MAAM,EAAE,OAAO;AAAA,MACf,aAAa,EAAE,OAAO;AAAA,MACtB,kBAAkB,EAAE,OAAO,EAAE,QAAQ,YAAY;AAAA,IACnD,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,MACzC,UAAU,EAAE,MAAM,mBAAmB;AAAA,MACrC,YAAY,EAAE,OAAO;AAAA,QACnB,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,QAC5C,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,QAC7C,qBAAqB,EAAE,QAAQ,EAAE,QAAQ,IAAI;AAAA,MAC/C,CAAC;AAAA,IACH,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,MAC9C,YAAY,EAAE,OAAO;AAAA,MACrB,WAAW,EAAE,OAAO;AAAA,QAClB,SAAS,EAAE,OAAO;AAAA,QAClB,QAAQ,EAAE,OAAO;AAAA,QACjB,YAAY,EAAE,OAAO;AAAA,QACrB,WAAW,EAAE,OAAO;AAAA,MACtB,CAAC;AAAA,IACH,CAAC;AAEM,IAAM,eAAe,EAAE,OAAO;AAAA,MACnC,SAAS,EAAE,OAAO;AAAA,MAClB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,aAAa;AAAA;AAAA,MAEb,eAAe,oBAAoB,SAAS;AAAA;AAAA,MAE5C,kBAAkB,EAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,QAAQ,MAAM;AAAA,IACjE,CAAC;AAWM,IAAM,iCAAiC,EAAE,OAAO;AAAA,MACrD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,MAC9F,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,cAAc,YAAY,cAAc,YAAY,WAAW,eAAe,WAAW,QAAQ,eAAe,qBAAqB,KAAK,CAAC,CAAC,EAC3K,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,4BAA4B;AAAA,IAC1C,CAAC;AAEM,IAAM,6BAA6B,EAAE,OAAO;AAAA,MACjD,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,MAClE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,MAC/E,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,IAC3E,CAAC;AAEM,IAAM,uBAAuB,EAAE,OAAO;AAAA,MAC3C,MAAM,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,MACtD,MAAM,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MACvE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,MACzE,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,IAC9E,CAAC;AAEM,IAAM,+BAA+B,EAAE,OAAO;AAAA,MACnD,MAAM,EAAE,KAAK,CAAC,WAAW,WAAW,UAAU,cAAc,aAAa,QAAQ,OAAO,aAAa,YAAY,CAAC,EAC/G,SAAS,yEAAyE;AAAA,MACrF,MAAM,EAAE,OAAO,EAAE,SAAS,sDAAsD;AAAA,MAChF,SAAS,EAAE,OAAO;AAAA,QAChB,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,QAC5D,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,QACpF,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACzF,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,QAC/D,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QACnG,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8DAA8D;AAAA,QAC1G,QAAQ,EAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,QAC5F,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAAA,QAC/F,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,QACxF,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,QAC9F,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QAClG,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,QAC1G,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4CAA4C;AAAA,QACvF,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,QACtG,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,wDAAwD;AAAA,QACxG,gBAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAAA,QAC/F,kBAAkB,EAAE,MAAM,oBAAoB,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,QACpH,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yGAAyG;AAAA,QAClJ,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,QACnH,uBAAuB,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,iGAAiG;AAAA,QACxJ,oBAAoB,EAAE,KAAK,CAAC,aAAa,eAAe,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,MACnJ,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAEM,IAAM,qBAAqB,EAAE,OAAO;AAAA,MACzC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,MACvF,QAAQ,EAAE,KAAK,CAAC,YAAY,QAAQ,SAAS,CAAC,EAAE,QAAQ,UAAU,EAC/D,SAAS,eAAe;AAAA,MAC3B,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,IACxE,CAAC;AAEM,IAAM,8BAA8B,EAAE,OAAO;AAAA,MAClD,aAAa,EAAE,OAAO,EAAE,SAAS,2FAA2F;AAAA,MAC5H,SAAS,EAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,MAC5F,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iGAAiG;AAAA,IAC3I,CAAC;AAEM,IAAM,iCAAiC,EAAE,OAAO;AAAA,MACrD,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gGAAgG;AAAA,MACzI,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,MACrH,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,8DAA8D;AAAA,MACzH,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,4DAA4D;AAAA,MAClH,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,qDAAqD;AAAA,IACnG,CAAC;AAaM,IAAM,iBAAiB,EAAE,KAAK,CAAC,QAAQ,eAAe,YAAY,KAAK,CAAC;AACxE,IAAM,mBAAmB,EAAE,KAAK,CAAC,UAAU,WAAW,cAAc,aAAa,cAAc,KAAK,CAAC;AAErG,IAAM,2BAA2B,EAAE,OAAO;AAAA,MAC/C,QAAQ,iBAAiB,SAAS,2BAA2B;AAAA,MAC7D,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,oDAAoD;AAAA,MACrF,WAAW,EAAE,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,4BAA4B;AAAA,MAC1F,SAAS,EAAE,OAAO;AAAA,QAChB,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,yBAAyB;AAAA,QAC9E,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,gCAAgC;AAAA,QAC3F,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,2BAA2B;AAAA,QACjF,cAAc,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,2BAA2B;AAAA,QAC5E,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,0BAA0B;AAAA,QAChF,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,6BAA6B;AAAA,QACvF,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,2BAA2B;AAAA,QACnF,kBAAkB,EAAE,MAAM,oBAAoB,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,QAC3G,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,iCAAiC;AAAA,QACrF,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,+BAA+B;AAAA,MAC7E,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAEM,IAAM,iCAAiC,EAAE,OAAO;AAAA,MACrD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,MAC9D,OAAO,EAAE,KAAK,CAAC,UAAU,WAAW,cAAc,KAAK,CAAC,EAAE,QAAQ,KAAK,EAAE,SAAS,mBAAmB;AAAA,MACrG,cAAc,EAAE,KAAK,CAAC,WAAW,YAAY,MAAM,CAAC,EAAE,QAAQ,SAAS,EAAE,SAAS,eAAe;AAAA,MACjG,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,2CAA2C;AAAA,IACxG,CAAC;AAEM,IAAM,qCAAqC,EAAE,OAAO;AAAA,MACzD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MAC/D,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,aAAa,YAAY,cAAc,WAAW,KAAK,CAAC,CAAC,EACxF,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,uCAAuC;AAAA,MACnD,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,gCAAgC;AAAA,IAC/E,CAAC;AAEM,IAAM,kCAAkC,EAAE,OAAO;AAAA,MACtD,QAAQ,EAAE,KAAK,CAAC,UAAU,WAAW,cAAc,MAAM,CAAC,EAAE,SAAS,2BAA2B;AAAA,MAChG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,6BAA6B;AAAA,MAC9D,OAAO,EAAE,KAAK,CAAC,SAAS,iBAAiB,kBAAkB,CAAC,EAAE,QAAQ,eAAe,EAClF,SAAS,mBAAmB;AAAA,IACjC,CAAC;AAWM,IAAM,sBAAsB,EAAE,KAAK;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEM,IAAM,8BAA8B,EAAE,OAAO;AAAA,MAClD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,MAC9F,QAAQ,EAAE,MAAM,mBAAmB,EAChC,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,wBAAwB;AAAA,MACpC,UAAU,EAAE,KAAK,CAAC,YAAY,KAAK,CAAC,EAAE,SAAS,EAC5C,SAAS,4BAA4B;AAAA,IAC1C,CAAC;AAEM,IAAM,sBAAsB,EAAE,KAAK;AAAA,MACxC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEM,IAAM,gCAAgC,EAAE,OAAO;AAAA,MACpD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAAwD;AAAA,MAC7F,SAAS,EAAE,MAAM,mBAAmB,EACjC,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,oBAAoB;AAAA,MAChC,WAAW,EAAE,KAAK,CAAC,UAAU,UAAU,SAAS,CAAC,EAAE,QAAQ,QAAQ,EAChE,SAAS,gCAAgC;AAAA,MAC5C,OAAO,EAAE,KAAK,CAAC,WAAW,KAAK,CAAC,EAAE,QAAQ,KAAK,EAC5C,SAAS,mCAAmC;AAAA,IACjD,CAAC;AAwRM,IAAM,+BAA+B,EAAE,OAAO;AAAA,MACnD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,MAC5G,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,uDAAuD;AAAA,MAC5F,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,mDAAmD;AAAA,MACpF,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,WAAW,UAAU,UAAU,UAAU,UAAU,QAAQ,CAAC,CAAC,EAC7F,QAAQ,CAAC,UAAU,WAAW,UAAU,UAAU,QAAQ,CAAC,EAC3D,SAAS,yBAAyB;AAAA,MACrC,SAAS,EAAE,OAAO;AAAA,QAChB,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,QACnF,cAAc,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,2BAA2B;AAAA,QAC5E,aAAa,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,2BAA2B;AAAA,QAC3E,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,+BAA+B;AAAA,MAC7E,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAEM,IAAM,4BAA4B,EAAE,OAAO;AAAA,MAChD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,MAC5G,QAAQ,EAAE,KAAK,CAAC,eAAe,cAAc,QAAQ,CAAC,EACnD,QAAQ,aAAa,EACrB,SAAS,gHAAgH;AAAA,MAC5H,OAAO,EAAE,KAAK,CAAC,OAAO,YAAY,YAAY,YAAY,CAAC,EACxD,QAAQ,KAAK,EACb,SAAS,6BAA6B;AAAA,MACzC,SAAS,EAAE,OAAO;AAAA,QAChB,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,QAC/D,gBAAgB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,4BAA4B;AAAA,QAC/E,eAAe,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,sCAAsC;AAAA,QACxF,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,iCAAiC;AAAA,QACtF,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,+BAA+B;AAAA,MAC7E,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAEM,IAAM,oCAAoC,EAAE,OAAO;AAAA,MACxD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,MAC5G,OAAO,EAAE,KAAK,CAAC,eAAe,UAAU,YAAY,KAAK,CAAC,EACvD,QAAQ,KAAK,EACb,SAAS,qBAAqB;AAAA,MACjC,SAAS,EAAE,OAAO;AAAA,QAChB,KAAK,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,uBAAuB;AAAA,QAChE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,kBAAkB;AAAA,MAChE,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAoDM,IAAM,uBAAuB,EAAE,OAAO;AAAA,MAC3C,MAAM,EAAE,OAAO,EAAE,SAAS,6CAA6C;AAAA,MACvE,UAAU,EAAE,OAAO,EAAE,SAAS,uCAAuC;AAAA,MACrE,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,IACtF,CAAC;AAEM,IAAM,uCAAuC,EAAE,OAAO;AAAA,MAC3D,MAAM,EAAE,KAAK,CAAC,kBAAkB,cAAc,qBAAqB,KAAK,CAAC,EACtE,SAAS,kJAAkJ;AAAA,MAC9J,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gEAAgE;AAAA,MACvG,SAAS,EAAE,OAAO;AAAA,QAChB,OAAO,EAAE,MAAM,oBAAoB,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,QAClF,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,QAC/D,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,+BAA+B;AAAA,QAC3E,WAAW,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,0BAA0B;AAAA,MAC3E,CAAC,EAAE,SAAS;AAAA,IACd,CAAC;AAEM,IAAM,oCAAoC,EAAE,OAAO;AAAA,MACxD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,MACrE,QAAQ,EAAE,KAAK,CAAC,SAAS,cAAc,SAAS,UAAU,KAAK,CAAC,EAC7D,QAAQ,KAAK,EACb,SAAS,+BAA+B;AAAA,MAC3C,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,IACtF,CAAC;AA0DM,IAAM,sCAAsC,EAAE,OAAO;AAAA,MAC1D,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wDAAwD;AAAA,MAC7F,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4DAA4D;AAAA,MACzG,wBAAwB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,oDAAoD;AAAA,MAC/G,cAAc,EAAE,KAAK,CAAC,WAAW,YAAY,MAAM,CAAC,EAAE,QAAQ,UAAU,EAAE,SAAS,eAAe;AAAA,IACpG,CAAC;AAQM,IAAM,wBAAwB,EAAE,KAAK;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAEM,IAAM,wBAAwB,EAAE,OAAO;AAAA,MAC5C,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uDAAuD;AAAA,MAC5F,OAAO,EAAE,KAAK,CAAC,OAAO,WAAW,QAAQ,CAAC,EAAE,QAAQ,KAAK,EACtD,SAAS,gEAAgE;AAAA,MAC5E,QAAQ,EAAE,MAAM,qBAAqB,EAClC,QAAQ,CAAC,KAAK,CAAC,EACf,SAAS,6BAA6B;AAAA,MACzC,UAAU,EAAE,KAAK,CAAC,YAAY,YAAY,WAAW,KAAK,CAAC,EAAE,QAAQ,KAAK,EACvE,SAAS,oCAAoC;AAAA,IAClD,CAAC;AAAA;AAAA;;;ACxvBD,SAAS,YAAY;AACrB,SAAS,iBAAiB;AAE1B,OAAOC,WAAU;AAuCjB,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;AA4BA,eAAsB,iBAAiB,aAAwD;AAC7F,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,YAAY,IAAI,OAAKA,MAAK,SAAS,GAAG,SAAS,CAAC;AAGrE,QAAM,gBAAgB,CAAC,UAAU,eAAe,kBAAkB,OAAO,OAAO,QAAQ,OAAO;AAG/F,QAAM,iBAA2B,CAAC;AAElC,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,KAAK,MAAM,GAAG;AAG5B,aAAS,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK;AAC1C,YAAM,OAAO,MAAM,CAAC;AACpB,UAAI,cAAc,KAAK,OAAK,EAAE,YAAY,MAAM,KAAK,YAAY,CAAC,GAAG;AAEnE,cAAM,YAAY,MAAM,MAAM,GAAG,CAAC;AAClC,YAAI,UAAU,SAAS,GAAG;AACxB,yBAAe,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,QACzC;AACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,WAAW,GAAG;AAE/B,UAAM,eAAe,iBAAiB,YAAY;AAClD,QAAI,gBAAgB,aAAa,SAAS,GAAG;AAE3C,YAAM,OAAO,aAAa,QAAQ,OAAO,EAAE;AAC3C,UAAI,MAAM;AACR,uBAAe,KAAK,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AAGA,QAAM,gBAAgB,cAAc,cAAc,KAAK,eAAe,CAAC;AAEvE,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,GAAG,aAAa;AAAA,IACxB,aAAa,GAAG,aAAa;AAAA,IAC7B,gBAAgB,GAAG,aAAa;AAAA,IAChC,KAAK,GAAG,aAAa;AAAA,EACvB;AACF;AAKA,SAAS,iBAAiB,SAA2B;AACnD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,MAAI,QAAQ,WAAW,GAAG;AAExB,UAAM,QAAQ,QAAQ,CAAC,EAAE,MAAM,GAAG;AAClC,QAAI,MAAM,SAAS,GAAG;AACpB,aAAO,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAAI;AAAA,IACxC;AACA,WAAO,QAAQ,CAAC,IAAI;AAAA,EACtB;AAEA,MAAI,SAAS,QAAQ,CAAC;AAEtB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,WAAO,QAAQ,CAAC,EAAE,QAAQ,MAAM,MAAM,KAAK,OAAO,SAAS,GAAG;AAC5D,eAAS,OAAO,MAAM,GAAG,EAAE;AAAA,IAC7B;AAAA,EACF;AAGA,QAAM,UAAU,OAAO,YAAY,GAAG;AACtC,MAAI,UAAU,KAAK,CAAC,OAAO,SAAS,GAAG,GAAG;AACxC,aAAS,OAAO,MAAM,GAAG,UAAU,CAAC;AAAA,EACtC;AAEA,SAAO;AACT;AAKA,SAAS,cAAc,KAA8B;AACnD,MAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,SAAS,oBAAI,IAAoB;AACvC,aAAW,QAAQ,KAAK;AACtB,WAAO,IAAI,OAAO,OAAO,IAAI,IAAI,KAAK,KAAK,CAAC;AAAA,EAC9C;AAEA,MAAI,WAAW;AACf,MAAI,aAAa,IAAI,CAAC;AAEtB,aAAW,CAAC,MAAM,KAAK,KAAK,QAAQ;AAClC,QAAI,QAAQ,UAAU;AACpB,iBAAW;AACX,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO;AACT;AAtTA,IAKM;AALN;AAAA;AAAA;AAAA;AAEA;AAGA,IAAM,YAAY,UAAU,IAAI;AAAA;AAAA;;;ACLhC,OAAOC,WAAU;AACjB,SAAS,iBAAAC,sBAAqB;AAgF9B,SAAS,mBAAmB,YAA6B;AAEvD,MAAI,QAAQ,IAAI,yBAAyB;AACvC,WAAO,QAAQ,IAAI;AAAA,EACrB;AAGA,MAAI,cAAc,WAAW,KAAK,GAAG;AACnC,WAAO;AAAA,EACT;AAGA,QAAM,MAAM,QAAQ,IAAI;AACxB,SAAO,KAAK,kEAAkE,EAAE,IAAI,CAAC;AACrF,SAAO;AACT;AAKA,eAAsB,YAA6B;AACjD,MAAI,cAAc;AAChB,WAAO;AAAA,EACT;AAGA,QAAM,aAAaD,MAAK,KAAK,cAAc,UAAU,mBAAmB;AAExE,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,EAAE,GAAG,cAAc;AAAA,IACpC;AAAA,EACF,OAAO;AACL,WAAO,MAAM,sCAAsC;AACnD,mBAAe,EAAE,GAAG,cAAc;AAAA,EACpC;AAGA,eAAa,WAAW,cAAc;AAAA,IACpC,aAAa,WAAW;AAAA,EAC1B;AAGA,QAAM,uBAAuBA,MAAK;AAAA,IAChC,aAAa,WAAW;AAAA,IACxB;AAAA,IACA;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,oBAAoB,GAAG;AAC1C,QAAI;AACF,YAAM,mBAAmB,MAAM,SAAwB,oBAAoB;AAC3E,YAAM,gBAAgB,oBAAoB,MAAM,gBAAgB;AAChE,mBAAa,gBAAgB;AAC7B,mBAAa,mBAAmB,cAAc;AAC9C,aAAO,KAAK,sDAAsD;AAAA,QAChE,aAAa,cAAc;AAAA,QAC3B,WAAW,cAAc;AAAA,MAC3B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,aAAO,KAAK,0DAA0D,EAAE,MAAM,CAAC;AAAA,IACjF;AAAA,EACF,OAAO;AAEL,WAAO,MAAM,4EAA4E;AAAA,EAC3F;AAGA,QAAM,kBAAkB,CAAC,aAAa,YAAY,WAAW,UAC3D,CAAC,aAAa,YAAY,WAAW,eACrC,CAAC,aAAa,YAAY,WAAW,kBACrC,CAAC,aAAa,YAAY,WAAW;AAEvC,MAAI,mBAAmB,aAAa,WAAW,aAAa;AAC1D,QAAI;AACF,YAAM,cAAc,MAAM,gBAAgB,aAAa,WAAW,WAAW;AAC7E,YAAM,WAAW,MAAM,iBAAiB,WAAW;AAEnD,UAAI,UAAU;AAEZ,YAAI,CAAC,aAAa,YAAY,WAAW,QAAQ;AAC/C,uBAAa,YAAY,WAAW,SAAS,SAAS;AAAA,QACxD;AACA,YAAI,CAAC,aAAa,YAAY,WAAW,aAAa;AACpD,uBAAa,YAAY,WAAW,cAAc,SAAS;AAAA,QAC7D;AACA,YAAI,CAAC,aAAa,YAAY,WAAW,gBAAgB;AACvD,uBAAa,YAAY,WAAW,iBAAiB,SAAS;AAAA,QAChE;AACA,YAAI,CAAC,aAAa,YAAY,WAAW,KAAK;AAC5C,uBAAa,YAAY,WAAW,MAAM,SAAS;AAAA,QACrD;AACA,eAAO,KAAK,yCAAyC,EAAE,eAAe,SAAS,cAAc,CAAC;AAAA,MAChG,OAAO;AACL,eAAO,KAAK,yFAAyF;AAAA,MACvG;AAAA,IACF,SAAS,OAAO;AACd,aAAO,KAAK,oCAAoC,EAAE,MAAM,CAAC;AAAA,IAC3D;AAAA,EACF;AAGA,MAAI,QAAQ,IAAI,oBAAoB;AAClC,iBAAa,WAAW,SAAS,QAAQ,IAAI;AAAA,EAC/C;AAGA,MAAI,CAAC,aAAa,WAAW,aAAa;AACxC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;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,YAAY,SAAS,aAAa,cAAc,KAAK,YAAY;AAAA,MACjE,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;AAxPA,IASM,eACA,cACA,cAGA,eA6DF;AA3EJ;AAAA;AAAA;AAAA;AAEA;AACA;AAEA;AACA;AAGA,IAAM,gBAAgBC,eAAc,YAAY,GAAG;AACnD,IAAM,eAAeD,MAAK,QAAQ,aAAa;AAC/C,IAAM,eAAeA,MAAK,QAAQ,cAAc,IAAI;AAGpD,IAAM,gBAAwB;AAAA,MAC5B,SAAS;AAAA,MACT,YAAY;AAAA;AAAA,QAEV,aAAa;AAAA,QACb,QAAQ,QAAQ,IAAI,sBAAsB;AAAA,QAC1C,YAAY,QAAQ,IAAI,2BAA2B;AAAA,MACrD;AAAA,MACA,aAAa;AAAA,QACX,SAAS;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,QACd;AAAA,QACA,eAAe;AAAA,UACb;AAAA,UAAS;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAAO;AAAA,UAAQ;AAAA,UACxC;AAAA,UAAY;AAAA,UAAU;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAAQ;AAAA,QAChD;AAAA,QACA,YAAY,CAAC,QAAQ,aAAa,WAAW,WAAW;AAAA,QACxD,iBAAiB;AAAA,QACjB,YAAY;AAAA;AAAA;AAAA,UAGV,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,KAAK;AAAA,QACP;AAAA,QACA,gBAAgB;AAAA,UACd,WAAW;AAAA,UACX,gBAAgB;AAAA,QAClB;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,aAAa;AAAA,YACb,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,QACA,YAAY;AAAA,UACV,oBAAoB;AAAA,UACpB,qBAAqB;AAAA,UACrB,qBAAqB;AAAA,QACvB;AAAA,MACF;AAAA,MACA,aAAa;AAAA,QACX,YAAY;AAAA,QACZ,WAAW;AAAA,UACT,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,WAAW;AAAA,QACb;AAAA,MACF;AAAA;AAAA,MAEA,eAAe;AAAA;AAAA,MAEf,kBAAkB;AAAA,IACpB;AAEA,IAAI,eAA8B;AAAA;AAAA;;;AC3ElC,SAAS,QAAAE,aAAY;AACrB,SAAS,aAAAC,kBAAiB;AAE1B,OAAOC,WAAU;AAsBjB,eAAsB,IAAI,SAAiB,KAA+B;AACxE,QAAM,UAAU,MAAM,EAAE,KAAK,WAAW,KAAK,OAAO,KAAK,IAAI,EAAE,WAAW,KAAK,OAAO,KAAK;AAC3F,MAAI;AACF,UAAM,EAAE,OAAO,IAAI,MAAMC,WAAU,OAAO,OAAO,IAAI,OAAO;AAC5D,WAAO,OAAO,KAAK;AAAA,EACrB,SAAS,OAAO;AACd,UAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAEpE,UAAM,SAAU,OAA+B,UAAU;AACzD,UAAM,IAAI;AAAA,MACR,2BAA2B,OAAO,GAAG,SAAS,MAAM,OAAO,KAAK,CAAC,KAAK,EAAE;AAAA,MACxE;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAKA,eAAsB,UAAU,KAAgC;AAC9D,QAAM,SAASD,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;AAiBA,eAAsB,gBAAgB,KAAiC;AACrE,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,sBAAsB,GAAG;AAClD,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,WAAO,OAAO,MAAM,IAAI,EACrB,IAAI,UAAQ,KAAK,UAAU,CAAC,EAAE,KAAK,CAAC,EACpC,OAAO,OAAO;AAAA,EACnB,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAgCA,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;AAgBA,eAAsB,eAAe,KAAiC;AACpE,MAAI;AACF,UAAM,SAAS,MAAM,IAAI,6BAA6B,GAAG;AACzD,QAAI,CAAC,OAAQ,QAAO,CAAC;AAErB,WAAO,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO;AAAA,EAC1C,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAtMA,IAKMC,YAKO;AAVb;AAAA;AAAA;AAAA;AAEA;AAGA,IAAMA,aAAYF,WAAUD,KAAI;AAKzB,IAAM,WAAN,cAAuB,MAAM;AAAA,MAClC,YACE,SACgB,SACA,KACA,OAChB;AACA,cAAM,OAAO;AAJG;AACA;AACA;AAGhB,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACpBA,OAAOI,WAAU;AAMjB,SAAS,QAAAC,aAAY;AAMrB,eAAe,qBAAqB,aAA6C;AAE/E,QAAM,gBAAgB,MAAMA,MAAK,UAAU,EAAE,KAAK,aAAa,UAAU,KAAK,CAAC;AAC/E,aAAW,UAAU,eAAe;AAClC,UAAM,kBAAkBD,MAAK,KAAK,QAAQ,cAAc;AACxD,QAAI,MAAM,WAAW,eAAe,GAAG;AACrC,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,YAAYA,MAAK,KAAK,aAAa,KAAK;AAC9C,MAAI,MAAM,WAAWA,MAAK,KAAK,WAAW,cAAc,CAAC,GAAG;AAC1D,WAAO;AAAA,EACT;AAGA,QAAM,qBAAqB,CAAC,UAAU,YAAY,IAAI;AACtD,aAAW,cAAc,oBAAoB;AAC3C,UAAM,UAAUA,MAAK,KAAK,aAAa,UAAU;AACjD,QAAI,MAAM,WAAWA,MAAK,KAAK,SAAS,cAAc,CAAC,GAAG;AACxD,aAAO;AAAA,IACT;AAAA,EACF;AAGA,QAAM,SAASA,MAAK,KAAK,aAAa,OAAO,KAAK;AAClD,MAAI,MAAM,WAAWA,MAAK,KAAK,QAAQ,cAAc,CAAC,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAKA,eAAsB,cAAc,aAA2C;AAC7E,SAAO,MAAM,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE5D,QAAM,OAAoB;AAAA,IACxB,MAAMA,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,YAAY,MAAM,qBAAqB,WAAW;AACxD,MAAI,WAAW;AACb,UAAM,kBAAkBA,MAAK,KAAK,WAAW,cAAc;AAC3D,QAAI,MAAM,WAAW,eAAe,GAAG;AACrC,UAAI;AACF,cAAM,cAAc,KAAK,MAAM,MAAM,SAAS,eAAe,CAAC;AAC9D,aAAK,WAAW,CAAC,CAAC,YAAY,cAAc;AAC5C,aAAK,UAAU,YAAY,WAAW,KAAK;AAAA,MAC7C,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,YAAY,SAAS,GAAG;AAC/B,UAAM,aAAa,KAAK,YAAY,KAAK,OAAK,kBAAkB,KAAK,CAAC,CAAC,KAClE,KAAK,YAAY,KAAK,OAAK,gBAAgB,KAAK,CAAC,CAAC,KAClD,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;AAiBA,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,UAAU,GAAG;AAE3C,gBAAU,UAAU;AAEpB,gBAAU,MAAM;AAAA,IAClB,WAAW,YAAY,SAAS,KAAK,KAAK,CAAC,YAAY,SAAS,UAAU,GAAG;AAE3E,gBAAU,gBAAgB;AAE1B,UAAI,CAAC,UAAU,KAAK;AAClB,kBAAU,MAAM;AAAA,MAClB;AAAA,IACF;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,YAAY,MAAM,qBAAqB,WAAW;AACxD,MAAI,WAAW;AACb,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;AAxNA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACCA,OAAOE,WAAU;AAyBjB,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,cAAc,YAAY,WAAW,eAAe,WAAW,QAAQ,eAAe,mBAAmB,IAC9I,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;AAEA,MAAI,OAAO,SAAS,UAAU,GAAG;AAC/B,UAAM,iBAAiB,WAAW,QAAQ,MAAM;AAAA,EAClD;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,wBAAwB,WAAW,QAAQ,MAAM;AAAA,EACzD;AAEA,MAAI,OAAO,SAAS,aAAa,GAAG;AAClC,UAAM,yBAAyB,WAAW,QAAQ,MAAM;AAAA,EAC1D;AAEA,MAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,UAAM,gBAAgB,WAAW,QAAQ,MAAM;AAAA,EACjD;AAEA,MAAI,OAAO,SAAS,MAAM,GAAG;AAC3B,UAAM,aAAa,WAAW,QAAQ,MAAM;AAAA,EAC9C;AAEA,MAAI,OAAO,SAAS,aAAa,GAAG;AAClC,UAAM,oBAAoB,WAAW,QAAQ,MAAM;AAAA,EACrD;AAEA,MAAI,OAAO,SAAS,mBAAmB,GAAG;AACxC,UAAM,yBAAyB,WAAW,QAAQ,MAAM;AAAA,EAC1D;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,eAAe,iBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,QAAQ;AACrB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,UAAU,WAAW,EAAE,KAAK,UAAU,OAAO,CAAC;AAExE,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,MAAM,KAAK;AAG1C,QAAI,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,SAAS,KACvD,SAAS,SAAS,OAAO,KAAK,SAAS,SAAS,SAAS,KACzD,SAAS,SAAS,WAAW,KAAK,SAAS,SAAS,WAAW,KAC/D,SAAS,WAAW,GAAG,GAAG;AAC5B;AAAA,IACF;AAGA,UAAM,aAAa,QAAQ,MAAM,sDAAsD;AACvF,QAAI,CAAC,WAAY;AAEjB,UAAM,aAAa,WAAW,CAAC;AAC/B,UAAM,cAAc,WAAW,CAAC,GAAG,KAAK,KAAK;AAG7C,UAAM,gBAAgB,YAAY,SAAS,YAAY;AACvD,UAAM,kBAAkB,YAAY,SAAS,cAAc;AAC3D,UAAM,mBAAmB,YAAY,SAAS,eAAe;AAE7D,QAAI,CAAC,iBAAiB,CAAC,iBAAiB;AAEtC;AAAA,IACF;AAGA,QAAI,iBAAiB,CAAC,mBAAmB,CAAC,kBAAkB;AAC1D,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,UAAU;AAAA,QAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,QAAQ,SAAS,WAAW,UAAU,IAAI,GAAG;AAChD,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,UAAU;AAAA,QAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY,gBAAgB,UAAU;AAAA,MACxC,CAAC;AAAA,IACH;AAGA,QAAI,CAAC,QAAQ,SAAS,iBAAiB,UAAU,UAAU,GAAG;AAC5D,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,UAAU;AAAA,QAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY,qCAAqC,UAAU;AAAA,MAC7D,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,eAAe,wBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,QAAQ;AACrB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,UAAU,WAAW,EAAE,KAAK,UAAU,OAAO,CAAC;AAExE,MAAI,mBAAmB;AACvB,MAAI,oBAAoB;AACxB,MAAI,iBAAiB;AAErB,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AAGnC,UAAM,aAAa,QAAQ,MAAM,sDAAsD;AACvF,QAAI,CAAC,WAAY;AAEjB,UAAM,aAAa,WAAW,CAAC;AAC/B,UAAM,cAAc,WAAW,CAAC,GAAG,KAAK,KAAK;AAG7C,QAAI,CAAC,YAAY,SAAS,QAAQ,KAAK,CAAC,YAAY,SAAS,SAAS,GAAG;AACvE;AAAA,IACF;AAEA,UAAM,mBAAmB,YAAY,SAAS,eAAe;AAC7D,UAAM,kBAAkB,YAAY,SAAS,cAAc;AAC3D,UAAM,cAAc,QAAQ,SAAS,UAAU;AAC/C,UAAM,sBAAsB,QAAQ,SAAS,sBAAsB,KACtC,QAAQ,SAAS,+BAA+B;AAG7E,QAAI,kBAAkB;AACpB;AAEA,UAAI,CAAC,qBAAqB;AACxB,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,WAAW,UAAU;AAAA,UAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAGA,YAAM,eAAe,QAAQ,MAAM,wCAAwC;AAC3E,UAAI,gBAAgB,CAAC,aAAa,CAAC,EAAE,SAAS,UAAU,KAAK,CAAC,aAAa,CAAC,EAAE,SAAS,UAAU,GAAG;AAClG,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,WAAW,UAAU;AAAA,UAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,iBAAiB;AACnB;AAEA,UAAI,aAAa;AACf,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,kBAAkB,UAAU;AAAA,UACrC,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,CAAC,oBAAoB,CAAC,mBAAmB,aAAa;AACxD;AACA,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,UAAU;AAAA,QAC9B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,mBAAmB,oBAAoB,GAAG;AAC5C,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,mBAAmB,gBAAgB,kBAAkB,iBAAiB,YAAY,cAAc;AAAA,IAC3G,CAAC;AAAA,EACH;AACF;AAEA,eAAe,yBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,kBAAkB,MAAM,UAAU,oCAAoC;AAAA,IAC1E,KAAK,UAAU;AAAA,EACjB,CAAC;AAID,QAAM,oBAAoB;AAAA;AAAA,IAExB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,EACF;AAEA,MAAI,gBAAgB;AACpB,MAAI,sBAAsB;AAC1B,MAAI,wBAAwB;AAE5B,aAAW,QAAQ,iBAAiB;AAClC,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,MAAM,KAAK;AAG1C,QAAI,kBAAkB,SAAS,QAAQ,GAAG;AACxC;AACA;AAAA,IACF;AAGA,UAAM,cAAc,QAAQ,SAAS,YAAY;AAGjD,UAAM,oBAAoB,QAAQ,SAAS,6BAA6B,KAC9C,QAAQ,SAAS,cAAc,KAC/B,gCAAgC,KAAK,OAAO;AAEtE,QAAI,aAAa;AACf;AAGA,YAAM,gBAAgB,QAAQ,MAAM,sEAAsE;AAC1G,UAAI,eAAe;AACjB,cAAM,YAAY,cAAc,CAAC;AACjC,cAAM,QAAQ,UAAU,MAAM,GAAG;AAGjC,YAAI,MAAM,SAAS,GAAG;AACpB,iBAAO,SAAS,KAAK;AAAA,YACnB,MAAM;AAAA,YACN,UAAU;AAAA,YACV,SAAS,eAAe,QAAQ,4CAA4C,SAAS;AAAA,YACrF,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,YACxC,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAGA,cAAM,eAAe,MAAM,KAAK,UAAQ,SAAS,KAAK,YAAY,CAAC;AACnE,YAAI,cAAc;AAChB,iBAAO,OAAO,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,UAAU;AAAA,YACV,SAAS,eAAe,QAAQ,8CAA8C,SAAS;AAAA,YACvF,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,YACxC,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,mBAAmB;AAC5B;AACA,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,eAAe,QAAQ;AAAA,QAChC,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,mBAAmB,gBAAgB;AACzC,QAAM,sBAAsB,mBAAmB;AAC/C,QAAM,qBAAqB,sBAAsB,IAC7C,KAAK,MAAO,gBAAgB,sBAAuB,GAAG,IACtD;AAEJ,SAAO,SAAS,KAAK;AAAA,IACnB,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS,kBAAkB,aAAa,IAAI,mBAAmB,uCAAuC,kBAAkB,OAAO,qBAAqB;AAAA,EACtJ,CAAC;AAGD,MAAI,qBAAqB,MAAM,sBAAsB,GAAG;AACtD,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,mCAAmC,kBAAkB;AAAA,IAChE,CAAC;AAAA,EACH;AACF;AAEA,eAAe,gBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAEA,QAAM,cAAc,MAAM,UAAU,uBAAuB,EAAE,KAAK,UAAU,IAAI,CAAC;AAEjF,MAAI,YAAY,WAAW,GAAG;AAC5B,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAEA,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,IAAI;AACnC,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,QAAI,cAAc;AAClB,eAAW,QAAQ,OAAO;AAExB,UAAI,KAAK,KAAK,EAAE,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG,EAAG;AAEjE,UAAI,oBAAoB,KAAK,IAAI,GAAG;AAClC,sBAAc;AACd;AAAA,MACF;AAAA,IACF;AAEA,QAAI,aAAa;AACf,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,QAAQ;AAAA,QAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,QAAI,qBAAqB;AACzB,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,KAAK,EAAE,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG,EAAG;AACjE,UAAI,sBAAsB,KAAK,IAAI,GAAG;AACpC,6BAAqB;AACrB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,oBAAoB;AACvB,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,QAAQ;AAAA,QAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAGA,QAAI,mBAAmB;AACvB,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,KAAK,EAAE,WAAW,IAAI,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG,EAAG;AACjE,UAAI,oBAAoB,KAAK,IAAI,KAAK,2BAA2B,KAAK,IAAI,GAAG;AAC3E,2BAAmB;AACnB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,kBAAkB;AACrB,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,QAAQ;AAAA,QAC5B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEA,eAAe,aACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAEA,QAAM,YAAY,MAAM,UAAU,qBAAqB,EAAE,KAAK,UAAU,IAAI,CAAC;AAE7E,MAAI,gBAAgB;AACpB,MAAI,iBAAiB;AACrB,MAAI,mBAAmB;AAEvB,aAAW,QAAQ,WAAW;AAC5B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,IAAI;AACnC,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,QAAI,gBAAgB;AACpB,eAAW,QAAQ,OAAO;AACxB,YAAM,UAAU,KAAK,KAAK;AAE1B,UAAI,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,KAAK,YAAY,IAAI;AACrG;AAAA,MACF;AAEA,UAAI,wDAAwD,KAAK,IAAI,GAAG;AACtE,wBAAgB;AAChB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAe;AACjB;AAGA,YAAM,WAAW,QAAQ,SAAS,kBAAkB;AAEpD,UAAI,UAAU;AACZ;AAAA,MACF,OAAO;AACL,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,SAAS,QAAQ;AAAA,UAC1B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAGA,YAAM,sBAAsB,qBAAqB,OAAO;AAExD,UAAI,oBAAoB,gBAAgB;AACtC;AAAA,MACF,WAAW,oBAAoB,iBAAiB;AAE9C,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,SAAS,QAAQ;AAAA,UAC1B,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,UACxC,YAAY;AAAA,QACd,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,MAAI,gBAAgB,GAAG;AACrB,UAAM,eAAe;AAAA,MACnB,GAAG,cAAc,IAAI,aAAa;AAAA,IACpC;AACA,QAAI,mBAAmB,KAAK,gBAAgB,gBAAgB;AAC1D,mBAAa,KAAK,GAAG,gBAAgB,IAAI,aAAa,mBAAmB;AAAA,IAC3E;AACA,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,gBAAgB,aAAa,KAAK,IAAI,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AACF;AAMA,SAAS,qBAAqB,SAI5B;AACA,QAAM,WAAqB,CAAC;AAC5B,MAAI,iBAAiB;AACrB,MAAI,kBAAkB;AAOtB,QAAM,cAAc,gBAAgB,KAAK,OAAO;AAChD,QAAM,yBAAyB,oEAAoE,KAAK,OAAO;AAC/G,MAAI,eAAe,wBAAwB;AACzC,qBAAiB;AACjB,aAAS,KAAK,iCAAiC;AAAA,EACjD;AAKA,QAAM,mBAAmB;AACzB,MAAI,iBAAiB,KAAK,OAAO,GAAG;AAClC,qBAAiB;AACjB,aAAS,KAAK,sBAAsB;AAAA,EACtC;AAIA,QAAM,kBAAkB;AACxB,MAAI,gBAAgB,KAAK,OAAO,GAAG;AACjC,qBAAiB;AACjB,aAAS,KAAK,wBAAwB;AAAA,EACxC;AAKA,QAAM,2BAA2B;AACjC,MAAI,yBAAyB,KAAK,OAAO,GAAG;AAC1C,qBAAiB;AACjB,aAAS,KAAK,2BAA2B;AAAA,EAC3C;AAIA,QAAM,2BAA2B;AACjC,MAAI,yBAAyB,KAAK,OAAO,GAAG;AAC1C,qBAAiB;AACjB,aAAS,KAAK,6BAA6B;AAAA,EAC7C;AAIA,QAAM,uBAAuB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,WAAW,sBAAsB;AAC1C,QAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,wBAAkB;AAClB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,oBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,QAAQ;AACrB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,cAAc,MAAM,UAAU,WAAW,EAAE,KAAK,UAAU,OAAO,CAAC;AAaxE,QAAM,cAA+B,CAAC;AACtC,QAAM,cAAc,oBAAI,IAAY;AAGpC,aAAW,QAAQ,aAAa;AAC9B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,WAAWA,MAAK,SAAS,MAAM,KAAK;AAG1C,QACE,SAAS,SAAS,KAAK,KACvB,SAAS,SAAS,SAAS,KAC3B,SAAS,SAAS,OAAO,KACzB,SAAS,SAAS,SAAS,KAC3B,SAAS,SAAS,WAAW,KAC7B,SAAS,SAAS,WAAW,KAC7B,SAAS,WAAW,GAAG,GACvB;AACA;AAAA,IACF;AAGA,UAAM,aAAa,QAAQ;AAAA,MACzB;AAAA,IACF;AACA,QAAI,CAAC,WAAY;AAEjB,UAAM,aAAa,WAAW,CAAC;AAC/B,UAAM,cAAc,WAAW,CAAC,GAAG,KAAK,KAAK;AAG7C,UAAM,gBAAgB,YAAY,SAAS,YAAY;AACvD,UAAM,kBAAkB,YAAY,SAAS,cAAc;AAC3D,QAAI,CAAC,iBAAiB,CAAC,gBAAiB;AAExC,gBAAY,IAAI,UAAU;AAC1B,UAAM,mBAAmB,YAAY,SAAS,eAAe;AAG7D,UAAM,eAAe,QAAQ;AAAA,MAC3B,IAAI;AAAA,QACF,yBAAyB,UAAU,iCAAiC,UAAU;AAAA,QAC9E;AAAA,MACF;AAAA,IACF;AAGA,UAAM,mBAA6B,CAAC;AACpC,UAAM,oBAAoB,QAAQ;AAAA,MAChC;AAAA,IACF;AACA,eAAW,SAAS,mBAAmB;AACrC,uBAAiB,KAAK,MAAM,CAAC,CAAC;AAAA,IAChC;AAGA,UAAM,YAAY,QAAQ,SAAS,sCAAsC;AACzE,QAAI;AACJ,eAAW,SAAS,WAAW;AAC7B,YAAM,WAAW,MAAM,CAAC;AACxB,UAAI,SAAS,YAAY,EAAE,SAAS,QAAQ,EAAG;AAC/C,UAAI,aAAa,WAAY;AAC7B,YAAM,YAAY,SAAS,QAAQ,OAAO,EAAE;AAC5C,UAAI,cAAc,YAAY;AAC5B,uBAAe;AACf;AAAA,MACF;AAAA,IACF;AAEA,QAAI,gBAAgB,iBAAiB,SAAS,KAAK,cAAc;AAC/D,kBAAY,KAAK;AAAA,QACf,MAAM;AAAA,QACN,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,QACxC,mBAAmB,CAAC,CAAC;AAAA,QACrB,cAAc,eAAe,aAAa,CAAC,IAAI;AAAA,QAC/C;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA,OAAO;AAAA;AAAA,MACT,CAAC;AAAA,IACH;AAAA,EACF;AAGA,MAAI,eAAe;AACnB,MAAI,mBAAmB;AACvB,MAAI,qBAAqB;AAEzB,aAAW,KAAK,aAAa;AAC3B,QAAI,EAAE,mBAAmB;AACvB;AAGA,aAAO,SAAS,KAAK;AAAA,QACnB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,WAAW,EAAE,IAAI,8BAA8B,EAAE,YAAY;AAAA,QACtE,MAAM,EAAE;AAAA,QACR,YAAY,kFAAkF,EAAE,YAAY;AAAA,MAC9G,CAAC;AAGD,UACE,EAAE,KAAK,YAAY,EAAE,SAAS,OAAO,KACrC,EAAE,KAAK,YAAY,EAAE,SAAS,YAAY,KAC1C,EAAE,KAAK,YAAY,EAAE,SAAS,MAAM,GACpC;AACA,eAAO,SAAS,KAAK;AAAA,UACnB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,4BAA4B,EAAE,IAAI;AAAA,UAC3C,MAAM,EAAE;AAAA,UACR,YAAY,uBAAuB,EAAE,IAAI;AAAA,QAC3C,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,EAAE,cAAc;AAClB;AAGA,UAAI,CAAC,YAAY,IAAI,EAAE,YAAY,GAAG;AACpC,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,WAAW,EAAE,IAAI,qCAAqC,EAAE,YAAY;AAAA,UAC7E,MAAM,EAAE;AAAA,UACR,YAAY,cAAc,EAAE,YAAY;AAAA,QAC1C,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,EAAE,gBAAgB,YAAY,IAAI,EAAE,YAAY,GAAG;AACrD,YAAM,aAAa,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY;AACpE,UAAI,cAAc,WAAW,iBAAiB,CAAC,EAAE,eAAe;AAC9D,eAAO,OAAO,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS,WAAW,EAAE,IAAI,8BAA8B,EAAE,YAAY;AAAA,UACtE,MAAM,EAAE;AAAA,UACR,YAAY,kCAAkC,EAAE,IAAI;AAAA,QACtD,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,EAAE,iBAAiB,SAAS,GAAG;AACjC,iBAAW,SAAS,EAAE,kBAAkB;AACtC,cAAM,YAAY,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK;AAC1D,YAAI,aAAa,UAAU,iBAAiB,SAAS,GAAG;AACtD;AACA,iBAAO,SAAS,KAAK;AAAA,YACnB,MAAM;AAAA,YACN,UAAU;AAAA,YACV,SAAS,4BAA4B,EAAE,IAAI,WAAM,KAAK;AAAA,YACtD,MAAM,EAAE;AAAA,YACR,YAAY;AAAA,UACd,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,YAAY,SAAS,GAAG;AAC1B,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,sBAAsB,YAAY,sBAAsB,gBAAgB,kBAAkB,kBAAkB;AAAA,IACvH,CAAC;AAAA,EACH;AACF;AAEA,eAAe,yBACb,WACA,SACA,QACe;AACf,MAAI,CAAC,UAAU,KAAK;AAClB,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,IACX,CAAC;AACD;AAAA,EACF;AAGA,QAAM,YAAY,MAAM,UAAU,qBAAqB,EAAE,KAAK,UAAU,IAAI,CAAC;AAC7E,QAAM,iBAAiB,MAAM,UAAU,0BAA0B,EAAE,KAAK,UAAU,IAAI,CAAC;AACvF,QAAM,WAAW,CAAC,GAAG,WAAW,GAAG,cAAc;AAGjD,QAAM,iBAAiB;AAAA,IACrB,QAAQ,CAAC,UAAU,OAAO,OAAO,YAAS,WAAW,SAAS;AAAA,IAC9D,QAAQ,CAAC,QAAQ,UAAU,UAAU,YAAY,aAAU,QAAQ,aAAa;AAAA,IAChF,QAAQ,CAAC,UAAU,UAAU,aAAa,SAAS;AAAA,IACnD,SAAS,CAAC,WAAW,OAAO,QAAQ,eAAY,UAAU,cAAc;AAAA,EAC1E;AAEA,MAAI,uBAAuB;AAC3B,MAAI,qBAAqB;AACzB,MAAI,mBAAmB;AACvB,QAAM,qBAAqF,CAAC;AAE5F,aAAW,QAAQ,UAAU;AAC3B,UAAM,UAAU,MAAM,SAAS,IAAI;AACnC,UAAM,QAAQ,QAAQ,MAAM,IAAI;AAGhC,UAAM,sBAAsB,QAAQ,SAAS,kBAAkB;AAC/D,QAAI,qBAAqB;AACvB;AACA;AAAA,IACF;AAGA,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,UAAU,KAAK,KAAK;AAG1B,UAAI,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,GAAG;AACnF;AAAA,MACF;AAGA,YAAM,cAAc,0HAA0H,KAAK,IAAI;AAEvJ,UAAI,aAAa;AACf,cAAM,gBAAgB,YAAY,CAAC,GAAG,YAAY,KAAK;AACvD,cAAM,gBAAgB,YAAY,CAAC,GAAG,YAAY,KAAK;AAGvD,YAAI,iBAAgC;AAEpC,mBAAW,CAAC,QAAQ,QAAQ,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC/D,cAAI,SAAS,KAAK,QAAM,cAAc,SAAS,EAAE,KAAK,cAAc,SAAS,EAAE,CAAC,GAAG;AACjF,6BAAiB;AACjB;AAAA,UACF;AAAA,QACF;AAEA,YAAI,gBAAgB;AAGlB,gBAAM,YAAY,KAAK,IAAI,GAAG,IAAI,CAAC;AACnC,gBAAM,UAAU,KAAK,IAAI,MAAM,SAAS,GAAG,IAAI,CAAC;AAChD,gBAAM,UAAU,MAAM,MAAM,WAAW,UAAU,CAAC,EAAE,KAAK,IAAI;AAE7D,gBAAM,qBACJ,QAAQ,SAAS,eAAe,KAChC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,SAAS,KAC1B,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,YAAY,KAC7B,QAAQ,SAAS,gBAAgB;AAEnC,cAAI,CAAC,oBAAoB;AACvB;AACA,+BAAmB,KAAK;AAAA,cACtB,MAAMA,MAAK,SAAS,UAAU,MAAM,IAAI;AAAA,cACxC,MAAM,IAAI;AAAA,cACV,QAAQ;AAAA,cACR,MAAM,KAAK,KAAK,EAAE,UAAU,GAAG,EAAE;AAAA,YACnC,CAAC;AAAA,UACH,OAAO;AACL;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,kBAAkB,mBAAmB,MAAM,GAAG,EAAE;AACtD,aAAW,OAAO,iBAAiB;AACjC,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,gBAAgB,IAAI,MAAM;AAAA,MACnC,MAAM,IAAI;AAAA,MACV,MAAM,IAAI;AAAA,MACV,YAAY,gCAAgC,IAAI,MAAM;AAAA,IACxD,CAAC;AAAA,EACH;AAEA,MAAI,mBAAmB,SAAS,IAAI;AAClC,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,WAAW,mBAAmB,SAAS,EAAE;AAAA,IACpD,CAAC;AAAA,EACH;AAGA,QAAM,qBAAqB,uBAAuB,qBAAqB;AACvE,MAAI,qBAAqB,GAAG;AAC1B,UAAM,sBAAsB,KAAK;AAAA,OAC7B,uBAAuB,sBAAsB,qBAAsB;AAAA,IACvE;AACA,WAAO,SAAS,KAAK;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS,8BAA8B,oBAAoB,yBAAyB,kBAAkB,uBAAuB,gBAAgB,6BAA6B,mBAAmB;AAAA,IAC/L,CAAC;AAED,QAAI,sBAAsB,MAAM,qBAAqB,GAAG;AACtD,aAAO,OAAO,KAAK;AAAA,QACjB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS,kDAAkD,mBAAmB;AAAA,QAC9E,YAAY;AAAA,MACd,CAAC;AAAA,IACH;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;AAp1CA,IAOa;AAPb;AAAA;AAAA;AAAA;AACA;AACA;AACA;AACA;AAGO,IAAM,0BAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,OAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,CAAC,UAAU,cAAc,YAAY,cAAc,YAAY,WAAW,eAAe,WAAW,QAAQ,eAAe,qBAAqB,KAAK;AAAA,YAC7J;AAAA,YACA,aAAa;AAAA,YACb,SAAS,CAAC,KAAK;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACjBA,OAAOC,WAAU;AAwBjB,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;AAMA,SAAS,YAAY,SAAkD;AACrE,QAAM,QAAQ,QAAQ,MAAM,uBAAuB;AACnD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,IACrB,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,IACrB,SAAS,MAAM,CAAC,GAAG,EAAE;AAAA,EACvB;AACF;AAOA,SAAS,gBAAgB,GAAW,GAAmB;AACrD,QAAM,SAAS,YAAY,CAAC;AAC5B,QAAM,SAAS,YAAY,CAAC;AAG5B,MAAI,CAAC,UAAU,CAAC,OAAQ,QAAO;AAC/B,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,CAAC,OAAQ,QAAO;AAGpB,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;AAGA,QAAI,UAAU,YAAY,WAAW,CAAC,YAAY,UAAU,OAAO,GAAG;AACpE,aAAO,UAAU,KAAK;AAAA,QACpB,MAAM;AAAA,QACN,aAAa,cAAc,UAAU,IAAI,kCAAkC,UAAU,OAAO;AAAA,QAC5F,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;AA5aA,IAaa;AAbb;AAAA;AAAA;AAAA;AACA;AAMA;AACA;AACA;AACA;AAGO,IAAM,sBAA4B;AAAA,MACvC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,aAAa;AAAA,YACX,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,eAAe;AAAA,YACb,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AChCA,OAAO,gBAAgB;AASvB,OAAOC,WAAU;AAmJjB,SAAS,iBAAiB,UAUxB;AACA,MAAI,CAAC,UAAU;AACb,WAAO,EAAE,SAAS,IAAI,aAAa,IAAI,QAAQ,IAAI,YAAY,IAAI,WAAW,IAAI,gBAAgB,GAAG;AAAA,EACvG;AAEA,QAAM,WAAW,SAAS,MAAM,GAAG;AACnC,QAAM,WAAW,CAAC,MAChB,EAAE,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE;AAEvE,QAAM,UAAU,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI;AACtD,QAAM,cAAc,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI;AAC1D,QAAM,SAAS,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,IAAI,SAAS,SAAS,CAAC,CAAC,IAAI;AAG3F,MAAI,aAAa;AACjB,MAAI,SAAS,UAAU,GAAG;AACxB,iBAAaA,MAAK,KAAK,SAAS,aAAa,MAAM;AAAA,EACrD,WAAW,SAAS,WAAW,GAAG;AAChC,iBAAaA,MAAK,KAAK,SAAS,MAAM;AAAA,EACxC,WAAW,SAAS,WAAW,GAAG;AAChC,iBAAa;AAAA,EACf;AAGA,QAAM,YAAY,UAAU;AAG5B,QAAM,iBAAiB;AAEvB,SAAO,EAAE,SAAS,aAAa,QAAQ,YAAY,WAAW,eAAe;AAC/E;AAEA,eAAsB,wBACpB,MACA,QACiB;AACjB,QAAM,QAAQ,6BAA6B,MAAM,IAAI;AACrD,QAAM,SAAS,MAAM,SAAS,UAAU;AAExC,SAAO,KAAK,yBAAyB,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,OAAO,CAAC;AAEnF,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAE7E,QAAM,SAAyB;AAAA,IAC7B,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,IACR,cAAc,CAAC;AAAA,EACjB;AAGA,MAAI,MAAM,SAAS,iBAAiB;AAClC,UAAM,QAAQ,SAAS;AAAA,EAGzB;AAEA,MAAI;AACF,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,cAAM,gBAAgB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAClF;AAAA,MACF,KAAK;AACH,cAAM,gBAAgB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAClF;AAAA,MACF,KAAK;AACH,cAAM,eAAe,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACjF;AAAA,MACF,KAAK;AACH,cAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACrF;AAAA,MACF,KAAK;AACH,cAAM,kBAAkB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACpF;AAAA,MACF,KAAK;AACH,cAAM,aAAa,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAC/E;AAAA,MACF,KAAK;AACH,cAAM,aAAa,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAC/E;AAAA,MACF,KAAK;AACH,cAAM,kBAAkB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACpF;AAAA,MACF,KAAK;AACH,cAAM,mBAAmB,MAAM,MAAM,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACrF;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,MAAM,MAAM;AAC5D;AAqCA,eAAe,gBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,gBAAgB,SAAS,iBAAiB;AAChD,QAAM,oBAAoB,SAAS,mBAAmB;AACtD,QAAM,YAAY,SAAS,aAAa;AACxC,QAAM,WAAW,SAAS,YAAY;AACtC,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,iBAAiB,SAAS,kBAAkB;AAElD,MAAI,aAAa;AAGjB,SAAO,aAAa,KAAK,yBAAyB,IAAI,EAAE;AACxD,SAAO,aAAa,KAAK,EAAE;AAC3B,MAAI,mBAAmB;AACrB,WAAO,aAAa,KAAK,qEAAqE;AAC9F,WAAO,aAAa,KAAK,EAAE;AAAA,EAC7B;AAGA,SAAO,aAAa,KAAK,MAAM,UAAU,iBAAiB;AAC1D,QAAM,eAAe,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACrE,SAAO,aAAa,KAAK,EAAE;AAC3B;AAGA,MAAI,UAAU;AACZ,WAAO,aAAa,KAAK,MAAM,UAAU,gCAAgC;AACzE,UAAM,aAAa,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACnE,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,gBAAgB;AAClB,WAAO,aAAa,KAAK,MAAM,UAAU,+BAA+B;AACxE,UAAM,kBAAkB,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACxE,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,gBAAgB;AAClB,WAAO,aAAa,KAAK,MAAM,UAAU,sBAAsB;AAC/D,UAAM,mBAAmB,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACzE,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,CAAC,aAAa;AAChB,WAAO,aAAa,KAAK,MAAM,UAAU,uBAAuB;AAEhE,UAAM,iBAAiB;AAAA,MACrB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,gBAAgB,MAAM,EAAE,GAAG,SAAS,SAAS,eAAe,GAAG,WAAW,QAAQ,QAAQ,MAAM;AACtG,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,CAAC,gBAAgB;AACnB,WAAO,aAAa,KAAK,MAAM,UAAU,kBAAkB;AAC3D,UAAM,mBAAmB,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACzE,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,CAAC,eAAe;AAClB,WAAO,aAAa,KAAK,MAAM,UAAU,mBAAmB;AAC5D,UAAM,kBAAkB,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACxE,WAAO,aAAa,KAAK,EAAE;AAC3B;AAAA,EACF;AAGA,MAAI,aAAa,CAAC,aAAa;AAC7B,WAAO,aAAa,KAAK,MAAM,UAAU,cAAc;AACvD,UAAM,aAAa,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AACnE,WAAO,aAAa,KAAK,EAAE;AAAA,EAC7B;AAGA,QAAM,YAAsB,CAAC,QAAQ;AACrC,MAAI,SAAU,WAAU,KAAK,MAAM;AACnC,MAAI,eAAgB,WAAU,KAAK,YAAY;AAC/C,MAAI,eAAgB,WAAU,KAAK,YAAY;AAC/C,MAAI,CAAC,YAAa,WAAU,KAAK,SAAS;AAC1C,MAAI,CAAC,eAAgB,WAAU,KAAK,YAAY;AAChD,MAAI,CAAC,cAAe,WAAU,KAAK,WAAW;AAC9C,MAAI,aAAa,CAAC,YAAa,WAAU,KAAK,OAAO;AAErD,SAAO,aAAa,KAAK,KAAK;AAC9B,SAAO,aAAa,KAAK,yBAAyB,UAAU,KAAK,KAAK,CAAC,EAAE;AACzE,SAAO,aAAa,KAAK,EAAE;AAI3B,QAAM,SAAS,SAAS,WAAW,oBAAoB,eAAe,OAAO;AAC7E,QAAM,gBAAgB,WAAW,eAAe,wBAAwB;AACxE,QAAM,qBAAqB,WAAW,eAAe,yBAAyB;AAC9E,QAAM,kBAAkB;AAExB,SAAO,aAAa,KAAK,iBAAiB;AAC1C,SAAO,aAAa,KAAK,mBAAmB,kBAAkB,QAAQ,aAAa,oBAAoB,IAAI,KAAK,IAAI,YAAY,IAAI,QAAQ;AAC5I,MAAI,gBAAgB;AAClB,WAAO,aAAa,KAAK,iDAAiD,IAAI,eAAe,IAAI,kBAAkB;AAAA,EACrH;AACA,SAAO,aAAa,KAAK,GAAG,iBAAiB,MAAM,GAAG,6CAA6C,IAAI,YAAY,IAAI,eAAe;AACtI,MAAI,gBAAgB;AAClB,WAAO,aAAa,KAAK,GAAG,iBAAiB,MAAM,GAAG,+EAA+E,IAAI,oBAAoB;AAAA,EAC/J;AACA,SAAO,aAAa,KAAK,GAAG,iBAAkB,iBAAiB,MAAM,MAAQ,iBAAiB,MAAM,GAAI,kDAAkD,eAAe,kBAAkB,IAAI,cAAc,aAAa,IAAI;AAC9N,SAAO,aAAa,KAAK,GAAG,iBAAkB,iBAAiB,MAAM,MAAQ,iBAAiB,MAAM,GAAI,0DAA0D,aAAa,IAAI;AACnL,MAAI,CAAC,eAAe;AAClB,UAAM,mBAAmB,iBAAiB,SAAS,QAAQ;AAC3D,UAAM,uBAAuB,iBAAiB,WAAW,iBAAiB,SACtE,gBAAgB,iBAAiB,QAAQ,YAAY,CAAC,IAAI,iBAAiB,OAAO,YAAY,CAAC,IAAI,IAAI,KACvG,gBAAgB,IAAI;AACxB,WAAO,aAAa,KAAK,gCAAgC,IAAI,YAAY,oBAAoB,MAAM;AAAA,EACrG;AACF;AAEA,eAAe,gBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,qBAAqB,SAAS,aAAa,GAAG,OAAO,YAAY,WAAW,WAAW;AAC7F,QAAM,gBAAgB,UAAU,YAC5B,GAAG,OAAO,YAAY,WAAW,cAAc,aAAa,UAAU,SAAS,KAC/E,GAAG,OAAO,YAAY,WAAW,cAAc;AACnD,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,oBAAoB,eAAe,MAAM,QAAQ;AAEnE,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,cAAc,OAAO,WAAW;AACtC,QAAM,UAAU,UAAU,eAAe;AACzC,QAAM,YAAY,UAAU,kBAAkBD,MAAK,KAAK,aAAa,gBAAgB;AAErF,QAAM,gBAAgBA,MAAK,KAAK,SAAS,UAAU,YAAY;AAC/D,QAAM,UAAU,UAAU,YACtBA,MAAK,KAAK,WAAW,YAAY,UAAU,SAAS,IACpDA,MAAK,KAAK,WAAW,UAAU;AAEnC,QAAM,gBAAgBA,MAAK,KAAK,eAAe,IAAI,IAAI,YAAY;AACnE,QAAM,qBAAqBA,MAAK,KAAK,SAAS,GAAG,IAAI,YAAY;AAGjE,uBAAqB,eAAe,WAAW;AAC/C,uBAAqB,oBAAoB,WAAW;AAGpD,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,aAAa;AACnC,UAAM,gBAAgB,OAAO;AAC7B,UAAM,UAAU,eAAe,gBAAgB;AAC/C,UAAM,UAAU,oBAAoB,qBAAqB;AAAA,EAC3D;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,eAAe,SAAS,kBAAkB,MAAM,UAAU,CAAC;AACrF,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,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,YAAY,SAAS,cAAc,UAAU,aAC/C,GAAG,OAAO,YAAY,WAAW,MAAM,IAAI,UAAU,WAAW,QAAQ,UAAU,GAAG,CAAC,KACtF,OAAO,YAAY,WAAW;AAClC,QAAM,aAAa,SAAS;AAC5B,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,SAAS,SAAS,UAAU,OAAO,YAAY,QAAQ;AAI7D,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4HvB,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;AA2FvB,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,cAAc,OAAO,WAAW;AACtC,QAAM,aAAa,UAAU,UAAUA,MAAK,KAAK,aAAa,QAAQ;AACtE,QAAM,YAAY,UAAU,kBAAkBA,MAAK,KAAK,aAAa,gBAAgB;AAErF,QAAM,YAAY,UAAU,aACxBA,MAAK,KAAK,YAAY,UAAU,UAAU,IAC1C;AACJ,QAAM,YAAY,UAAU,YACxBA,MAAK,KAAK,WAAW,eAAe,kBAAkB,UAAU,SAAS,IACzEA,MAAK,KAAK,WAAW,eAAe,gBAAgB;AAExD,QAAM,iBAAiBA,MAAK,KAAK,WAAW,GAAG,IAAI,KAAK;AACxD,QAAM,iBAAiBA,MAAK,KAAK,WAAW,GAAG,IAAI,kBAAkB;AAGrE,uBAAqB,gBAAgB,WAAW;AAChD,uBAAqB,gBAAgB,WAAW;AAGhD,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,SAAS;AAC/B,UAAM,gBAAgB,SAAS;AAC/B,UAAM,UAAU,gBAAgB,aAAa;AAC7C,UAAM,UAAU,gBAAgB,aAAa;AAAA,EAC/C;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AACnF,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AAGnF,QAAM,gBAAgB,WAAW,eAAe,wBAAwB;AACxE,QAAM,qBAAqB,WAAW,eAAe,yBAAyB;AAC9E,QAAM,kBAAkB;AAExB,SAAO,aAAa,KAAK,gBAAgB,kBAAkB,GAAG;AAC9D,SAAO,aAAa,KAAK,gBAAgB,IAAI,KAAK,IAAI,YAAY,IAAI,MAAM;AAC5E,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,yBAAyB,aAAa,GAAG;AAClE,SAAO,aAAa,KAAK,gBAAgB,IAAI,KAAK,IAAI,YAAY,IAAI,MAAM;AAC5E,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,mBAAmB;AAC5C,SAAO,aAAa,KAAK,4BAA4B,eAAe,kBAAkB,IAAI,cAAc,aAAa,EAAE;AACvH,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;AAGrD,MAAI,SAAS,cAAc;AACzB,WAAO,aAAa,KAAK,EAAE;AAC3B,WAAO,aAAa,KAAK,eAAe;AACxC,UAAM,iBAAiB,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAAA,EACzE;AAGA,MAAI,SAAS,uBAAuB;AAClC,WAAO,aAAa,KAAK,EAAE;AAC3B,WAAO,aAAa,KAAK,8BAA8B;AACvD,UAAM,0BAA0B,MAAM,SAAS,WAAW,QAAQ,QAAQ,MAAM;AAAA,EAClF;AACF;AAEA,eAAe,iBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AAEf,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,YAAoC;AAAA,IACxC,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AACA,QAAM,SAAS,SAAS,kBAAkB,UAAU,WAAW,KAAK;AACpE,QAAM,iBAAiB,SAAS,kBAAkB;AAGlD,QAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuDzB,QAAM,cAAc,uCAAuC,QAAQ,SAAS,CAAC,MAAM;AACjF,UAAM,IAAI,KAAK,OAAO,IAAI,KAAK;AAC/B,UAAM,IAAI,MAAM,MAAM,IAAK,IAAI,IAAM;AACrC,WAAO,EAAE,SAAS,EAAE;AAAA,EACtB,CAAC;AAED,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,kBAAkB,WAAW,QAAQ,gBAAgB,EAAE,OAAO;AAGpE,QAAM,cAAc,OAAO,WAAW;AACtC,QAAM,YAAY,UAAU,kBAAkBA,MAAK,KAAK,aAAa,gBAAgB;AACrF,QAAM,eAAeA,MAAK,KAAK,WAAW,eAAe,WAAW,QAAQ,MAAM;AAClF,QAAM,mBAAmBA,MAAK,KAAK,cAAc,GAAG,IAAI,aAAa;AAGrE,uBAAqB,kBAAkB,WAAW;AAGlD,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,YAAY;AAClC,UAAM,UAAU,kBAAkB,eAAe;AAAA,EACnD;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,kBAAkB,SAAS,iBAAiB,MAAM,UAAU,CAAC;AAEvF,SAAO,aAAa,KAAK,2CAA2C,MAAM,GAAG;AAC7E,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,wDAAwD;AACjF,SAAO,aAAa,KAAK,WAAW;AACpC,SAAO,aAAa,KAAK,SAAS,IAAI,kBAAkB;AACxD,SAAO,aAAa,KAAK,4DAA4D,MAAM,GAAG;AAC9F,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,mBAAmB,IAAI,0BAA0B;AAC1E,SAAO,aAAa,KAAK,KAAK;AAC9B,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,oBAAoB;AAC7C,SAAO,aAAa,KAAK,2CAA2C;AACpE,SAAO,aAAa,KAAK,8BAA8B;AACvD,SAAO,aAAa,KAAK,+CAA+C;AACxE,SAAO,aAAa,KAAK,kDAAkD;AAC7E;AAEA,eAAe,0BACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,cAAc,SAAS,eAAe;AAC5C,QAAM,SAAS,SAAS,UAAU,OAAO,YAAY,QAAQ;AAE7D,QAAM,YAAY,GAAG,WAAW,GAAG,IAAI;AAGvC,QAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmHpB,QAAM,UAAU;AAAA,IACd;AAAA,IACA,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,IACtD;AAAA,IACA;AAAA,EACF;AAEA,QAAM,aAAa,WAAW,QAAQ,WAAW,EAAE,OAAO;AAG1D,QAAM,cAAc,OAAO,WAAW;AACtC,QAAM,YAAY,UAAU,kBAAkBA,MAAK,KAAK,aAAa,gBAAgB;AACrF,QAAM,cAAcA,MAAK,KAAK,WAAW,eAAe,WAAW,WAAW;AAC9E,QAAM,cAAcA,MAAK,KAAK,aAAa,SAAS,IAAI,eAAe;AAGvE,uBAAqB,aAAa,WAAW;AAG7C,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,WAAW;AACjC,UAAM,UAAU,aAAa,UAAU;AAAA,EACzC;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,aAAa,SAAS,YAAY,MAAM,UAAU,CAAC;AAE7E,SAAO,aAAa,KAAK,mCAAmC;AAC5D,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,iBAAiB;AAC1C,SAAO,aAAa,KAAK,+DAA+D;AACxF,SAAO,aAAa,KAAK,uBAAuB,IAAI,mCAAmC;AACvF,SAAO,aAAa,KAAK,WAAW;AACpC,SAAO,aAAa,KAAK,sBAAsB,IAAI,mCAAmC;AACtF,SAAO,aAAa,KAAK,YAAY,KAAK,YAAY,CAAC,KAAK;AAC5D,SAAO,aAAa,KAAK,mCAAmC;AAC5D,SAAO,aAAa,KAAK,sCAAsC;AAC/D,SAAO,aAAa,KAAK,KAAK;AAC9B,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,aAAa,IAAI,eAAe;AACzD,SAAO,aAAa,KAAK,WAAW;AACpC,SAAO,aAAa,KAAK,iBAAiB,IAAI,eAAe;AAC7D,SAAO,aAAa,KAAK,cAAc;AACvC,SAAO,aAAa,KAAK,qBAAqB;AAC9C,SAAO,aAAa,KAAK,kBAAkB;AAC3C,SAAO,aAAa,KAAK,oBAAoB;AAC7C,SAAO,aAAa,KAAK,gBAAgB;AACzC,SAAO,aAAa,KAAK,kBAAkB;AAC3C,SAAO,aAAa,KAAK,uBAAuB;AAChD,SAAO,aAAa,KAAK,iBAAiB;AAC1C,SAAO,aAAa,KAAK,KAAK;AAC9B,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,2CAA2C;AACpE,SAAO,aAAa,KAAK,WAAW;AACpC,SAAO,aAAa,KAAK,6BAA6B,MAAM,YAAY,IAAI,wBAAwB;AACpG,SAAO,aAAa,KAAK,gCAAgC;AACzD,SAAO,aAAa,KAAK,oBAAoB,IAAI,wDAAwD;AACzG,SAAO,aAAa,KAAK,uBAAuB;AAChD,SAAO,aAAa,KAAK,KAAK;AAC9B,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,0DAA0D;AACnF,SAAO,aAAa,KAAK,4DAA4D;AACrF,SAAO,aAAa,KAAK,6CAA6C;AACtE,SAAO,aAAa,KAAK,sCAAsC;AAC/D,SAAO,aAAa,KAAK,qDAAqD;AAChF;AAEA,eAAe,mBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,YAAY,SAAS,cAAc,UAAU,iBAC/C,GAAG,OAAO,YAAY,WAAW,GAAG,gBAAgB,UAAU,cAAc,KAC5E,GAAG,OAAO,YAAY,WAAW,GAAG;AACxC,QAAM,WAAW,SAAS;AAC1B,QAAM,iBAAiB,SAAS;AAGhC,QAAM,iBAAiB,WACnB,iBACE,cAAc,QAAQ,gBAAgB,cAAc,QACpD,cAAc,QAAQ,QACxB;AAGJ,QAAM,gBAAgB,WAAW,yCAAyC;AAE1E,QAAM,qBAAqB;AAAA;AAAA;AAAA,EAG3B,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFb,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,IACtD;AAAA,EACF;AAEA,QAAM,oBAAoB,WAAW,QAAQ,kBAAkB,EAAE,OAAO;AAExE,QAAM,cAAc,OAAO,WAAW;AACtC,QAAM,UAAU,UAAU,OAAOA,MAAK,KAAK,aAAa,KAAK;AAC7D,QAAM,iBAAiB,UAAU,iBAC7BA,MAAK,KAAK,SAAS,eAAe,UAAU,cAAc,IAC1DA,MAAK,KAAK,SAAS,aAAa;AAEpC,QAAM,qBAAqBA,MAAK,KAAK,gBAAgB,GAAG,IAAI,eAAe;AAG3E,uBAAqB,oBAAoB,WAAW;AAGpD,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,cAAc;AACpC,UAAM,UAAU,oBAAoB,iBAAiB;AAAA,EACvD;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,oBAAoB,SAAS,mBAAmB,MAAM,UAAU,CAAC;AAG3F,MAAI,UAAU;AACZ,WAAO,aAAa,KAAK,8DAA8D;AACvF,WAAO,aAAa,KAAK,aAAa,QAAQ,GAAG,iBAAiB,aAAa,cAAc,MAAM,EAAE,EAAE;AACvG,WAAO,aAAa,KAAK,EAAE;AAC3B,WAAO,aAAa,KAAK,4EAA4E;AACrG,WAAO,aAAa,KAAK,oDAAoD;AAC7E,WAAO,aAAa,KAAK,wDAAwD,QAAQ,GAAG;AAAA,EAC9F,OAAO;AACL,WAAO,aAAa,KAAK,8CAA8C;AACvE,WAAO,aAAa,KAAK,EAAE;AAC3B,WAAO,aAAa,KAAK,qEAA2D;AACpF,WAAO,aAAa,KAAK,4CAA4C;AACrE,WAAO,aAAa,KAAK,EAAE;AAC3B,WAAO,aAAa,KAAK,2CAA2C;AACpE,WAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,EAAE;AAC9D,WAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AACnE,WAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,EAAE;AAC9D,WAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AACnE,WAAO,aAAa,KAAK,iBAAiB,KAAK,YAAY,CAAC,OAAO;AAAA,EACrE;AACF;AAEA,eAAe,kBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,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,cAAc,OAAO,WAAW;AAEtC,QAAM,UAAU,UAAU,OAAOA,MAAK,KAAK,aAAa,KAAK;AAC7D,QAAM,iBAAiBA,MAAK,KAAK,SAAS,OAAO,YAAY;AAC7D,QAAM,iBAAiB,SAAS,aAC5B,QAAQ,aACP,UAAU,WAAW,UAAU,SAC5BA,MAAK,KAAK,gBAAgB,UAAU,QAAQ,YAAY,GAAG,UAAU,OAAO,YAAY,CAAC,IACzF;AACR,QAAM,YAAYA,MAAK,KAAK,SAAS,OAAO,OAAO;AAEnD,QAAM,oBAAoBA,MAAK,KAAK,gBAAgB,GAAG,IAAI,MAAM;AACjE,QAAM,eAAeA,MAAK,KAAK,WAAW,MAAM,IAAI,KAAK;AAGzD,uBAAqB,mBAAmB,WAAW;AACnD,uBAAqB,cAAc,WAAW;AAG9C,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,cAAc;AACpC,UAAM,gBAAgB,SAAS;AAC/B,UAAM,UAAU,mBAAmB,gBAAgB;AACnD,UAAM,UAAU,cAAc,WAAW;AAAA,EAC3C;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,mBAAmB,SAAS,kBAAkB,MAAM,UAAU,CAAC;AACzF,SAAO,MAAM,KAAK,EAAE,MAAM,cAAc,SAAS,aAAa,MAAM,UAAU,CAAC;AAE/E,SAAO,aAAa,KAAK,+BAA+B;AACxD,QAAM,sBAAsB,UAAU,WAAW,UAAU,SACvD,gBAAgB,UAAU,QAAQ,YAAY,CAAC,IAAI,UAAU,OAAO,YAAY,CAAC,IAAI,IAAI,KACzF,gBAAgB,IAAI;AACxB,SAAO,aAAa,KAAK,YAAY,IAAI,YAAY,mBAAmB,IAAI;AAC5E,SAAO,aAAa,KAAK,eAAe,IAAI,uBAAuB,IAAI,IAAI;AAC7E;AAEA,eAAe,aACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,iBAAiB,SAAS,kBAAkB;AAGlD,QAAME,uBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOtB,OAAO,YAAY,WAAW,WAAW;AAAA;AAAA,YAErC,OAAO,YAAY,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;AA+FnD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,EACF;AAEA,QAAM,cAAc,WAAW,QAAQA,oBAAmB,EAAE,OAAO;AAGnE,QAAM,YAAY,UAAU,cACxBF,MAAK,KAAKA,MAAK,QAAQ,UAAU,WAAW,GAAG,GAAGA,MAAK,SAAS,UAAU,WAAW,CAAC,UAAU,UAAU,IAC1GA,MAAK,KAAK,OAAO,WAAW,aAAa,qBAAqB,UAAU;AAE5E,QAAM,eAAeA,MAAK,KAAK,WAAW,GAAG,IAAI,iBAAiB;AAGlE,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,SAAS;AAC/B,UAAM,UAAU,cAAc,WAAW;AAAA,EAC3C;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,cAAc,SAAS,aAAa,MAAM,UAAU,CAAC;AAE/E,SAAO,aAAa,KAAK,YAAY;AACrC,SAAO,aAAa,KAAK,4CAA4C,IAAI,eAAe;AACxF,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,oBAAoB;AAC7C,SAAO,aAAa,KAAK,SAAS;AAClC,SAAO,aAAa,KAAK,OAAO;AAChC,SAAO,aAAa,KAAK,oBAAoB;AAC/C;AAEA,eAAe,aACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,YAAY,SAAS,cAAc,UAAU,aAC/C,GAAG,OAAO,YAAY,WAAW,WAAW,IAAI,UAAU,WAAW,QAAQ,UAAU,GAAG,CAAC,UAC3F,GAAG,OAAO,YAAY,WAAW,WAAW;AAChD,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,aAAa,SAAS,oBAAoB;AAAA,IAC9C,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,MAAM,WAAW,IAAI;AAAA,IAC/D,EAAE,MAAM,eAAe,MAAM,WAAW,UAAU,OAAO,WAAW,IAAI;AAAA,EAC1E;AAGA,QAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqC5B,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;AAqC1B,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;AAgC1B,aAAW,eAAe,MAAM,CAAC,GAAW,MAAc,MAAM,CAAC;AAEjE,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,kBAAkB,WAAW,QAAQ,mBAAmB,EAAE,OAAO;AACvE,QAAM,gBAAgB,WAAW,QAAQ,iBAAiB,EAAE,OAAO;AACnE,QAAM,gBAAgB,WAAW,QAAQ,iBAAiB,EAAE,OAAO;AAGnE,QAAM,WAAW,UAAU,eAAe,OAAO,WAAW;AAC5D,QAAM,WAAW,UAAU,aACvBA,MAAK,KAAK,UAAU,UAAU,YAAY,MAAM,IAChDA,MAAK,KAAK,UAAU,QAAQ,IAAI;AAEpC,QAAM,mBAAmBA,MAAK,KAAK,UAAU,GAAG,IAAI,gBAAgB;AACpE,QAAM,iBAAiBA,MAAK,KAAK,UAAU,SAAS,IAAI,QAAQ;AAChE,QAAM,iBAAiBA,MAAK,KAAK,UAAU,SAAS,IAAI,QAAQ;AAGhE,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,QAAQ;AAC9B,UAAM,UAAU,kBAAkB,eAAe;AACjD,UAAM,UAAU,gBAAgB,aAAa;AAC7C,UAAM,UAAU,gBAAgB,aAAa;AAAA,EAC/C;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,kBAAkB,SAAS,iBAAiB,MAAM,UAAU,CAAC;AACvF,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AACnF,SAAO,MAAM,KAAK,EAAE,MAAM,gBAAgB,SAAS,eAAe,MAAM,UAAU,CAAC;AAEnF,SAAO,aAAa,KAAK,iBAAiB;AAC1C,SAAO,aAAa,KAAK,KAAK,IAAI,gCAAgC;AAClE,SAAO,aAAa,KAAK,WAAW,IAAI,wBAAwB;AAChE,SAAO,aAAa,KAAK,WAAW,IAAI,uBAAuB;AACjE;AAEA,eAAe,kBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,YAAY,SAAS,cAAc,UAAU,aAC/C,GAAG,OAAO,YAAY,WAAW,WAAW,IAAI,UAAU,WAAW,QAAQ,UAAU,GAAG,CAAC,gBAC3F,GAAG,OAAO,YAAY,WAAW,WAAW;AAChD,QAAM,aAAa,SAAS,oBAAoB;AAAA,IAC9C,EAAE,MAAM,QAAQ,MAAM,UAAU,UAAU,MAAM,WAAW,IAAI;AAAA,IAC/D,EAAE,MAAM,eAAe,MAAM,WAAW,UAAU,OAAO,WAAW,IAAI;AAAA,EAC1E;AAGA,QAAM,0BAA0B;AAAA,QAC1B,OAAO,YAAY,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;AAoC/C,QAAM,0BAA0B;AAAA,QAC1B,OAAO,YAAY,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;AA8B/C,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,yBAAyB,WAAW,QAAQ,uBAAuB,EAAE,OAAO;AAClF,QAAM,yBAAyB,WAAW,QAAQ,uBAAuB,EAAE,OAAO;AAGlF,QAAM,WAAW,UAAU,eAAe,OAAO,WAAW;AAC5D,QAAM,iBAAiB,UAAU,aAC7BA,MAAK,KAAK,UAAU,UAAU,YAAY,YAAY,IACtDA,MAAK,KAAK,UAAU,YAAY;AAEpC,QAAM,0BAA0BA,MAAK,KAAK,gBAAgB,SAAS,IAAI,iBAAiB;AACxF,QAAM,0BAA0BA,MAAK,KAAK,gBAAgB,SAAS,IAAI,iBAAiB;AAGxF,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,cAAc;AACpC,UAAM,UAAU,yBAAyB,sBAAsB;AAC/D,UAAM,UAAU,yBAAyB,sBAAsB;AAAA,EACjE;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,yBAAyB,SAAS,wBAAwB,MAAM,UAAU,CAAC;AACrG,SAAO,MAAM,KAAK,EAAE,MAAM,yBAAyB,SAAS,wBAAwB,MAAM,UAAU,CAAC;AAErG,SAAO,aAAa,KAAK,4BAA4B;AACrD,SAAO,aAAa,KAAK,sDAAsD,IAAI,kBAAkB;AACrG,SAAO,aAAa,KAAK,EAAE;AAC3B,SAAO,aAAa,KAAK,kEAAkE;AAC7F;AAEA,eAAe,mBACb,MACA,SACA,WACA,QACA,QACA,SAAkB,OACH;AACf,QAAM,YAAY,iBAAiB,SAAS,QAAQ;AACpD,QAAM,iBAAiB,SAAS,kBAAkB;AAClD,QAAM,SAAS,SAAS,UAAU,OAAO,YAAY,QAAQ;AAC7D,QAAM,gBAAgB,WAAW,eAAe,wBAAwB;AAGxE,QAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA,QAIpB,OAAO,YAAY,WAAW,MAAM;AAAA;AAAA,YAEhC,OAAO,YAAY,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;AA+BnD,QAAM,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMzB,OAAO,YAAY,WAAW,MAAM;AAAA,QACpC,OAAO,YAAY,WAAW,cAAc;AAAA;AAAA,YAExC,OAAO,YAAY,WAAW,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoEtD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,mBAAmB,WAAW,QAAQ,iBAAiB,EAAE,OAAO;AACtE,QAAM,wBAAwB,WAAW,QAAQ,sBAAsB,EAAE,OAAO;AAGhF,QAAM,UAAU,UAAU,eAAe,OAAO,WAAW;AAC3D,QAAM,YAAY,UAAU,kBAAkBA,MAAK,KAAK,OAAO,WAAW,aAAa,gBAAgB;AAEvG,QAAM,aAAa,UAAU,YACzBA,MAAK,KAAK,SAAS,gBAAgB,UAAU,SAAS,IACtDA,MAAK,KAAK,SAAS,cAAc;AACrC,QAAM,eAAe,UAAU,YAC3BA,MAAK,KAAK,WAAW,gBAAgB,UAAU,SAAS,IACxDA,MAAK,KAAK,WAAW,cAAc;AAEvC,QAAM,oBAAoBA,MAAK,KAAK,YAAY,IAAI,IAAI,eAAe;AACvE,QAAM,yBAAyBA,MAAK,KAAK,cAAc,GAAG,IAAI,eAAe;AAG7E,MAAI,CAAC,QAAQ;AACX,UAAM,gBAAgB,UAAU;AAChC,UAAM,gBAAgB,YAAY;AAClC,UAAM,UAAU,mBAAmB,gBAAgB;AACnD,UAAM,UAAU,wBAAwB,qBAAqB;AAAA,EAC/D;AAEA,SAAO,MAAM,KAAK,EAAE,MAAM,mBAAmB,SAAS,kBAAkB,MAAM,UAAU,CAAC;AACzF,SAAO,MAAM,KAAK,EAAE,MAAM,wBAAwB,SAAS,uBAAuB,MAAM,UAAU,CAAC;AAEnG,SAAO,aAAa,KAAK,4BAA4B;AACrD,SAAO,aAAa,KAAK,uBAAuB,IAAI,eAAe,IAAI,gBAAgB;AACzF;AAEA,SAASC,cAAa,QAAwB,MAAc,MAAc,SAAkB,OAAe;AACzG,QAAM,QAAkB,CAAC;AAEzB,MAAI,QAAQ;AACV,UAAM,KAAK,iCAA0B,IAAI,KAAK,IAAI,EAAE;AACpD,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,6EAA6E;AACxF,UAAM,KAAK,+CAA+C;AAC1D,UAAM,KAAK,EAAE;AAAA,EACf,OAAO;AACL,UAAM,KAAK,cAAc,IAAI,KAAK,IAAI,EAAE;AACxC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,SAAS;AAClB,UAAM,KAAK,SAAS,mCAA4B,2BAAsB;AACtE,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;AAhqEA,IAYa;AAZb;AAAA;AAAA;AAAA;AAEA;AAKA;AACA;AACA;AAGO,IAAM,wBAA8B;AAAA,MACzC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,MAAM,CAAC,WAAW,WAAW,UAAU,cAAc,aAAa,QAAQ,OAAO,aAAa,YAAY;AAAA,YAC1G,aAAa;AAAA,UACf;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,YAAY;AAAA,cACV,WAAW;AAAA,gBACT,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,SAAS;AAAA,gBACP,MAAM;AAAA,gBACN,OAAO,EAAE,MAAM,SAAS;AAAA,gBACxB,aAAa;AAAA,cACf;AAAA,cACA,YAAY;AAAA,gBACV,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,aAAa;AAAA,gBACX,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,MAAM,CAAC,QAAQ,YAAY;AAAA,gBAC3B,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,aAAa;AAAA,gBACX,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,eAAe;AAAA,gBACb,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,iBAAiB;AAAA,gBACf,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,WAAW;AAAA,gBACT,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,cAAc;AAAA,gBACZ,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,kBAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,YAAY;AAAA,oBACV,MAAM,EAAE,MAAM,SAAS;AAAA,oBACvB,MAAM,EAAE,MAAM,SAAS;AAAA,oBACvB,UAAU,EAAE,MAAM,UAAU;AAAA,oBAC5B,WAAW,EAAE,MAAM,SAAS;AAAA,kBAC9B;AAAA,gBACF;AAAA,gBACA,aAAa;AAAA,cACf;AAAA,cACA,UAAU;AAAA,gBACR,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,uBAAuB;AAAA,gBACrB,MAAM;AAAA,gBACN,aAAa;AAAA,cACf;AAAA,cACA,oBAAoB;AAAA,gBAClB,MAAM;AAAA,gBACN,MAAM,CAAC,aAAa,eAAe,MAAM;AAAA,gBACzC,aAAa;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU,CAAC,QAAQ,MAAM;AAAA,MAC3B;AAAA,IACF;AAGA,eAAW,eAAe,cAAc,CAAC,QAAgB;AACvD,aAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,IAClD,CAAC;AAED,eAAW,eAAe,aAAa,CAAC,QAAgB;AACtD,aAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,IAClD,CAAC;AAED,eAAW,eAAe,aAAa,CAAC,QAAgB;AACtD,aAAO,IAAI,QAAQ,mBAAmB,OAAO,EAAE,YAAY;AAAA,IAC7D,CAAC;AAAA;AAAA;;;ACnJD,OAAO,WAAW;AAQlB,OAAOG,YAAU;AAgEjB,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,MAAM,UAAU,UAAU,KAAK,IAAI;AAAA,QAC1E,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,OAAK,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;AACJ,YAAI,eAAe,SAAS,YAAY,GAAG;AACzC,gBAAM,YAAY,eAAe,MAAM,8BAA8B;AACrE,cAAI,WAAW;AACb,0BAAc;AAAA,cACZ,MAAM,UAAU,CAAC;AAAA,cACjB,UAAU;AAAA,YACZ;AACA,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,YAAI;AACJ,cAAM,mBAAmB,QAAQ,YAAY,iBAAiB,MAAM,KAAK;AACzE,YAAI,qBAAqB,MAAM,MAAM,QAAQ,mBAAmB,KAAK;AACnE,gBAAM,eAAe,QAAQ,UAAU,kBAAkB,MAAM,KAAK,EAAE,MAAM,yEAAyE;AACrJ,cAAI,cAAc;AAChB,sBAAU,aAAa,CAAC,EAAE,QAAQ,cAAc,EAAE,EAAE,KAAK;AAAA,UAC3D;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;AAGA,cAAM,UAAuB,CAAC;AAC9B,YAAI,aAAa;AACf,kBAAQ,UAAU,uBAAuB,YAAY,IAAI;AAAA,QAC3D;AACA,YAAI,WAAW,SAAS,WAAW,QAAQ;AACzC,kBAAQ,WAAW,wBAAwB,gBAAgB,MAAM;AAAA,QACnE;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;AAAA,UACA;AAAA,UACA,WAAW,kBAAkB,MAAM;AAAA,UACnC,WAAW;AAAA,UACX;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBAAkB,QAAgC;AACzD,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,aAAO;AAAA,QACL,EAAE,QAAQ,KAAK,aAAa,UAAU;AAAA,QACtC,EAAE,QAAQ,KAAK,aAAa,YAAY;AAAA,MAC1C;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,QAAQ,KAAK,aAAa,UAAU;AAAA,QACtC,EAAE,QAAQ,KAAK,aAAa,cAAc;AAAA,QAC1C,EAAE,QAAQ,KAAK,aAAa,mBAAmB;AAAA,MACjD;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,QACL,EAAE,QAAQ,KAAK,aAAa,aAAa;AAAA,QACzC,EAAE,QAAQ,KAAK,aAAa,cAAc;AAAA,QAC1C,EAAE,QAAQ,KAAK,aAAa,YAAY;AAAA,MAC1C;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,EAAE,QAAQ,KAAK,aAAa,aAAa;AAAA,QACzC,EAAE,QAAQ,KAAK,aAAa,YAAY;AAAA,MAC1C;AAAA,IACF;AACE,aAAO,CAAC,EAAE,QAAQ,KAAK,aAAa,UAAU,CAAC;AAAA,EACnD;AACF;AAEA,SAAS,uBAAuB,UAA0B;AAExD,QAAM,OAAO,SAAS,QAAQ,WAAW,EAAE,EAAE,QAAQ,OAAO,EAAE,EAAE,QAAQ,UAAU,EAAE,EAAE,QAAQ,UAAU,EAAE;AAC1G,QAAM,UAAmC;AAAA,IACvC,MAAM,GAAG,KAAK,YAAY,CAAC;AAAA,EAC7B;AAEA,MAAI,SAAS,SAAS,QAAQ,GAAG;AAC/B,YAAQ,OAAO,OAAO,IAAI;AAC1B,YAAQ,cAAc,mBAAmB,IAAI;AAAA,EAC/C,WAAW,SAAS,SAAS,QAAQ,GAAG;AACtC,YAAQ,OAAO,WAAW,IAAI;AAC9B,YAAQ,cAAc,2BAA2B,IAAI;AAAA,EACvD;AAEA,SAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AACxC;AAEA,SAAS,wBAAwB,gBAAwB,QAAwB;AAC/E,QAAM,UAAmC;AAAA,IACvC,IAAI;AAAA,IACJ,UAAU;AAAA,IACV,MAAM,GAAG,eAAe,YAAY,CAAC;AAAA,IACrC,MAAM,WAAW,cAAc;AAAA,IAC/B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IAClC,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AAEA,MAAI,WAAW,OAAO;AACpB,WAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AAAA,EACxC;AAEA,SAAO,KAAK,UAAU,SAAS,MAAM,CAAC;AACxC;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,aAAa;AACxB,cAAM,KAAK,mBAAmB;AAC9B,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,WAAW,SAAS,YAAY,IAAI,IAAI;AACnD,cAAM,KAAK,EAAE;AACb,YAAI,SAAS,SAAS,SAAS;AAC7B,gBAAM,KAAK,SAAS;AACpB,gBAAM,KAAK,SAAS,QAAQ,OAAO;AACnC,gBAAM,KAAK,KAAK;AAChB,gBAAM,KAAK,EAAE;AAAA,QACf;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;AAEA,UAAI,SAAS,SAAS,aAAa,SAAS,WAAW,SAAS,SAAS,WAAW,SAAS;AAC3F,cAAM,KAAK,uBAAuB;AAClC,cAAM,KAAK,EAAE;AACb,cAAM,KAAK,SAAS;AACpB,cAAM,KAAK,SAAS,QAAQ,QAAQ;AACpC,cAAM,KAAK,KAAK;AAChB,cAAM,KAAK,EAAE;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU,WAAW,GAAG;AAC1B,UAAM,KAAK,kDAAkD;AAAA,EAC/D;AAGA,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,0BAA0B,UAAU,MAAM,EAAE;AACvD,QAAM,KAAK,sBAAsB,IAAI,IAAI,UAAU,IAAI,OAAK,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE;AACjF,QAAM,KAAK,wBAAwB,UAAU,OAAO,OAAK,EAAE,SAAS,EAAE,MAAM,EAAE;AAC9E,QAAM,KAAK,iBAAiB,UAAU,OAAO,OAAK,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE;AAExE,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;AAxeA,IAWa;AAXb;AAAA;AAAA;AAAA;AAEA;AAIA;AACA;AACA;AAGO,IAAM,cAAoB;AAAA,MAC/B,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,UAAU;AAAA,YACR,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM,CAAC,YAAY,QAAQ,SAAS;AAAA,YACpC,aAAa;AAAA,YACb,SAAS;AAAA,UACX;AAAA,UACA,YAAY;AAAA,YACV,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AChCA,SAAS,KAAAC,UAAS;AAKlB,OAAOC,YAAU;AA0CjB,eAAsB,uBACpB,MACA,QACiB;AACjB,QAAM,QAAQC,6BAA4B,MAAM,IAAI;AAEpD,QAAM,UAAU,MAAM,WAAW,OAAO,oBAAoB;AAE5D,SAAO,KAAK,6BAA6B,EAAE,aAAa,MAAM,aAAa,QAAQ,CAAC;AAEpF,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAG7E,QAAM,qBAAqB,MAAM,uBAAuB,WAAW,QAAQ,OAAO;AAGlF,MAAI,UAAU,MAAM;AACpB,MAAI,WAAW;AAEf,MAAI,mBAAmB,SAAS,GAAG;AAEjC,UAAM,kBAAkB,mBAAmB,mBAAmB,SAAS,CAAC;AAExE,QAAI,CAAC,SAAS;AAEZ,gBAAU,gBAAgB;AAAA,IAC5B;AAGA,UAAM,sBAAsB,mBAAmB,OAAO,OAAK,EAAE,YAAY,OAAO;AAChF,QAAI,oBAAoB,SAAS,GAAG;AAClC,YAAM,cAAc,KAAK,IAAI,GAAG,oBAAoB,IAAI,OAAK,EAAE,QAAQ,CAAC;AACxE,iBAAW,cAAc;AAAA,IAC3B;AAAA,EACF,OAAO;AAEL,cAAU,WAAW;AAAA,EACvB;AAGA,QAAM,oBAAoB,aAAa,MAAM,WAAW;AAGxD,QAAM,cAAc,SAAS,SAAS,EAAE,SAAS,GAAG,GAAG;AAGvD,QAAM,gBAAgB,GAAG,OAAO,KAAK,OAAO,IAAI,WAAW,IAAI,iBAAiB;AAIhF,QAAM,gBAAgB,YAAY,SAAS,kBAAkB;AAC7D,QAAM,aAAa,YAAY,eAAe,sCAAsC;AACpF,QAAM,UAAU,4BAA4B,aAAa,cAAc,aAAa,8CAA8C,UAAU;AAG5I,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,mBAAmB;AAC9B,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,aAAa;AACxB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,YAAY;AACvB,QAAM,KAAK,SAAS;AACpB,QAAM,KAAK,OAAO;AAClB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,uBAAuB;AAClC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,gCAAgC;AAC3C,QAAM,KAAK,gCAAgC;AAC3C,QAAM,KAAK,iBAAiB,OAAO,2CAA2C;AAC9E,QAAM,KAAK,mBAAmB,aAAa,iCAAiC;AAC5E,QAAM,KAAK,gBAAgB,OAAO,mCAAmC;AACrE,QAAM,KAAK,kBAAkB,OAAO,uBAAuB;AAC3D,QAAM,KAAK,kBAAkB,WAAW,yBAAyB;AACjE,QAAM,KAAK,qBAAqB,iBAAiB,8BAA8B;AAC/E,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,+DAA+D;AAC1E,QAAM,KAAK,0CAA0C;AACrD,QAAM,KAAK,sDAAsD;AACjE,QAAM,KAAK,EAAE;AAEb,MAAI,mBAAmB,SAAS,GAAG;AACjC,UAAM,KAAK,iCAAiC;AAC5C,UAAM,KAAK,EAAE;AACb,UAAM,SAAS,mBAAmB,MAAM,EAAE;AAC1C,eAAW,KAAK,QAAQ;AACtB,YAAM,KAAK,OAAO,EAAE,IAAI,IAAI;AAAA,IAC9B;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAe,uBACb,WACA,QACA,SAC0B;AAC1B,QAAM,aAA8B,CAAC;AAGrC,QAAM,YAAY,UAAU,kBAAkBD,OAAK,KAAK,OAAO,WAAW,aAAa,gBAAgB;AACvG,QAAM,iBAAiBA,OAAK,KAAK,WAAW,eAAe,YAAY;AAEvE,MAAI;AACF,UAAM,iBAAiB,MAAM,UAAU,QAAQ,EAAE,KAAK,eAAe,CAAC;AAItE,UAAM,mBAAmB;AAEzB,eAAW,QAAQ,gBAAgB;AACjC,YAAM,WAAWA,OAAK,SAAS,IAAI;AAGnC,UAAI,SAAS,SAAS,YAAY,KAAK,SAAS,SAAS,eAAe,GAAG;AACzE;AAAA,MACF;AAEA,YAAM,QAAQ,SAAS,MAAM,gBAAgB;AAC7C,UAAI,OAAO;AACT,cAAM,CAAC,EAAE,KAAK,KAAK,KAAK,IAAI,IAAI;AAChC,YAAI,QAAQ,WAAW,CAAC,SAAS;AAC/B,qBAAW,KAAK;AAAA,YACd,MAAM,SAAS,QAAQ,OAAO,EAAE;AAAA,YAChC,SAAS;AAAA,YACT,SAAS;AAAA,YACT,UAAU,SAAS,KAAK,EAAE;AAAA,YAC1B,aAAa;AAAA,UACf,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAGA,eAAW,KAAK,CAAC,GAAG,MAAM;AACxB,YAAM,aAAaE,iBAAgB,EAAE,SAAS,EAAE,OAAO;AACvD,UAAI,eAAe,EAAG,QAAO;AAC7B,aAAO,EAAE,WAAW,EAAE;AAAA,IACxB,CAAC;AAAA,EACH,QAAQ;AAEN,WAAO,MAAM,4BAA4B;AAAA,EAC3C;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,KAAqB;AACzC,SAAO,IACJ,QAAQ,mBAAmB,EAAE,EAC7B,MAAM,KAAK,EACX,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACtE,KAAK,EAAE;AACZ;AAEA,SAASA,iBAAgB,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;AAEA,SAAO;AACT;AAzNA,IAQa,sBAwBAD;AAhCb;AAAA;AAAA;AAAA;AAGA;AACA;AACA;AAGO,IAAM,uBAA6B;AAAA,MACxC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,aAAa;AAAA,YACX,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,MAAM,CAAC,QAAQ,YAAY;AAAA,YAC3B,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,QACF;AAAA,QACA,UAAU,CAAC,aAAa;AAAA,MAC1B;AAAA,IACF;AAEO,IAAMA,+BAA8BF,GAAE,OAAO;AAAA,MAClD,aAAaA,GAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,MACzE,SAASA,GAAE,KAAK,CAAC,QAAQ,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,MACzH,SAASA,GAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,IAC1E,CAAC;AAAA;AAAA;;;ACnCD,OAAOI,YAAU;AA+FjB,eAAsB,0BACpB,MACA,QACiB;AACjB,MAAI;AACF,UAAM,UAAsC;AAAA,MAC1C,UAAU,KAAK;AAAA,MACf,SAAS,KAAK,WAAW,CAAC;AAAA,MAC1B,wBAAwB,KAAK,2BAA2B;AAAA,MACxD,iBAAiB,KAAK,oBAAoB;AAAA,IAC5C;AAEA,UAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAC7E,QAAI,CAAC,WAAW;AACd,YAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAEA,QAAI,cAA4B,CAAC;AACjC,QAAI,SAAS;AAEb,QAAI,QAAQ,UAAU;AAEpB,oBAAc;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ,WAAW,CAAC;AAAA,QACpB,QAAQ,0BAA0B;AAAA,QAClC,QAAQ,mBAAmB;AAAA,MAC7B;AAEA,eAAS,gCAAgC,QAAQ,QAAQ;AAAA;AAAA;AACzD,gBAAU,wBAAwB,WAAW;AAAA,IAC/C,OAAO;AAEL,YAAM,qBAAqB,MAAM,8BAA8B,UAAU,OAAO,UAAU,IAAI;AAC9F,oBAAc;AAEd,eAAS;AAAA;AAAA;AACT,gBAAU,8BAA8B,uBAAuB,WAAW,CAAC;AAAA;AAC3E,gBAAU,gCAAgC,YAAY,MAAM;AAAA;AAAA;AAC5D,gBAAU,wBAAwB,WAAW;AAAA,IAC/C;AAGA,cAAU;AAAA;AAAA;AAAA;AAAA;AACV,cAAU;AAAA;AACV,cAAU;AAAA;AAAA;AACV,cAAU,oBAAoB,aAAa,QAAQ,YAAY,QAAQ;AAEvE,cAAU;AAAA;AAAA;AAAA;AAAA;AACV,cAAU;AAAA;AACV,cAAU;AAAA;AACV,cAAU;AAAA;AACV,cAAU;AAAA;AAEV,WAAO;AAAA,EACT,SAAS,OAAY;AACnB,WAAO,MAAM,iCAAiC,KAAK;AACnD,UAAM;AAAA,EACR;AACF;AAKA,SAAS,+BACP,UACA,eACA,wBACA,kBAA2B,MACb;AACd,QAAM,cAA4B,CAAC;AACnC,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,QAAM,UAAU,MAAM,CAAC;AAGvB,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,IAAI,MAAM,4BAA4B,QAAQ,+CAA+C;AAAA,EACrG;AAGA,MAAI,iBAAiB;AACnB,gBAAY,KAAK;AAAA,MACf,MAAM,GAAG,QAAQ;AAAA,MACjB,MAAM,qBAAqB,UAAU,aAAa;AAAA,MAClD,aAAa,QAAQ,MAAM,MAAM,SAAS,CAAC,CAAC;AAAA,MAC5C,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,yBACZ,CAAC,GAAG,kBAAkB,GAAG,aAAa,IACtC;AAEJ,aAAW,UAAU,SAAS;AAC5B,UAAM,OAAO,GAAG,QAAQ,IAAI,MAAM;AAClC,UAAM,OAAO,qBAAqB,UAAU,MAAM;AAClD,UAAM,cAAc,4BAA4B,UAAU,MAAM;AAEhE,gBAAY,KAAK;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKA,eAAe,8BACb,aACuB;AACvB,QAAM,cAA4B,CAAC;AAKnC,QAAM,iBAAiB;AAAA,IACrBA,OAAK,KAAK,aAAa,OAAO,kBAAkB,aAAa;AAAA,IAC7DA,OAAK,KAAK,aAAa,kBAAkB,aAAa;AAAA,IACtDA,OAAK,KAAK,aAAa,OAAO,aAAa;AAAA,IAC3CA,OAAK,KAAK,aAAa,YAAY,aAAa;AAAA,EAClD;AAEA,aAAW,OAAO,gBAAgB;AAChC,QAAI;AACF,YAAM,QAAQ,MAAM,uBAAuB,GAAG;AAE9C,iBAAW,QAAQ,OAAO;AACxB,YAAI,KAAK,SAAS,eAAe,GAAG;AAClC,gBAAM,UAAU,MAAM,SAAS,IAAI;AACnC,gBAAM,YAAY,+BAA+B,OAAO;AAExD,qBAAW,YAAY,WAAW;AAChC,kBAAM,cAAc,mBAAmB,OAAO;AAC9C,kBAAM,UAAU,YACb,IAAI,YAAU,sBAAsB,MAAM,CAAC,EAC3C,OAAO,YAAU,UAAU,WAAW,QAAQ;AAEjD,kBAAM,gBAAgB,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;AAC1C,kBAAM,sBAAsB;AAAA,cAC1B;AAAA,cACA,CAAC;AAAA,cACD;AAAA,YACF;AAGA,wBAAY;AAAA,cACV,GAAG,oBAAoB;AAAA,gBAAO,OAC5B,cAAc,SAAS,EAAE,KAAK,MAAM,GAAG,EAAE,IAAI,CAAE;AAAA,cACjD;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AAEd,aAAO,MAAM,6BAA6B,GAAG,EAAE;AAAA,IACjD;AAAA,EACF;AAGA,SAAO,MAAM;AAAA,IACX,IAAI,IAAI,YAAY,IAAI,OAAK,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO;AAAA,EACpD;AACF;AAUA,SAAS,+BAA+B,SAA2B;AACjE,QAAM,YAAsB,CAAC;AAI7B,QAAM,QAAQ;AAEd,MAAI;AACJ,UAAQ,QAAQ,MAAM,KAAK,OAAO,OAAO,MAAM;AAC7C,UAAM,WAAW,MAAM,CAAC;AACxB,UAAM,SAAS,MAAM,CAAC,KAAK;AAG3B,UAAM,cAAc,OAAO,MAAM,wBAAwB;AACzD,UAAM,SAAS,cAAc,YAAY,CAAC,IAAI;AAE9C,QAAI,QAAQ;AAEV,gBAAU,KAAK,GAAG,QAAQ,IAAI,MAAM,EAAE;AAAA,IACxC,OAAO;AAEL,gBAAU,KAAK,QAAQ;AAAA,IACzB;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,mBAAmB,SAA2B;AACrD,QAAM,UAAoB,CAAC;AAC3B,QAAM,iBAAiB,CAAC,WAAW,YAAY,WAAW,aAAa,cAAc,YAAY,aAAa;AAE9G,aAAW,QAAQ,gBAAgB;AACjC,QAAI,QAAQ,SAAS,IAAI,IAAI,EAAE,GAAG;AAChC,cAAQ,KAAK,KAAK,QAAQ,QAAQ,EAAE,EAAE,YAAY,CAAC;AAAA,IACrD;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,qBAAqB,UAAkB,QAAwB;AACtE,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,QAAM,SAAS,MAAM,MAAM,SAAS,CAAC;AAGrC,QAAM,aAAa,OAChB,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACxD,KAAK,GAAG;AAEX,QAAM,aAAa,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAElE,SAAO,GAAG,UAAU,MAAM,UAAU;AACtC;AAKA,SAAS,4BAA4B,UAAkB,QAAwB;AAC7E,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,QAAM,UAAU,MAAM,CAAC;AACvB,QAAM,cAAc,MAAM,CAAC;AAC3B,QAAM,SAAS,MAAM,CAAC;AAEtB,QAAM,cAAc,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AACrE,QAAM,kBAAkB,YACrB,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACxD,KAAK,GAAG;AACX,QAAM,aAAa,OAChB,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,EACxD,KAAK,GAAG;AAEX,QAAM,aAAa,cAAc,MAAM;AAEvC,SAAO,GAAG,UAAU,IAAI,UAAU,OAAO,WAAW,MAAM,eAAe;AAC3E;AAKA,SAAS,cAAc,QAAwB;AAC7C,QAAM,QAAgC;AAAA,IACpC,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AAEA,SAAO,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AACzE;AAKA,SAAS,wBAAwB,aAAmC;AAClE,MAAI,SAAS;AAGb,QAAM,aAAa,YAAY,OAAO,CAAC,KAAK,MAAM;AAChD,QAAI,CAAC,IAAI,EAAE,QAAQ,EAAG,KAAI,EAAE,QAAQ,IAAI,CAAC;AACzC,QAAI,EAAE,QAAQ,EAAE,KAAK,CAAC;AACtB,WAAO;AAAA,EACT,GAAG,CAAC,CAAiC;AAErC,aAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC1D,cAAU,OAAO,SAAS,OAAO,CAAC,EAAE,YAAY,IAAI,SAAS,MAAM,CAAC,CAAC;AAAA;AAAA;AACrE,cAAU;AAAA;AACV,cAAU;AAAA;AAEV,eAAW,KAAK,OAAO;AACrB,gBAAU,OAAO,EAAE,IAAI,QAAQ,EAAE,IAAI,MAAM,EAAE,WAAW;AAAA;AAAA,IAC1D;AAEA,cAAU;AAAA;AAAA,EACZ;AAEA,SAAO;AACT;AAKA,SAAS,uBAAuB,aAAmC;AACjE,QAAM,YAAY,IAAI;AAAA,IACpB,YAAY,IAAI,OAAK,EAAE,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,CAAC;AAAA,EAC/D;AACA,SAAO,UAAU;AACnB;AAMA,SAAS,oBAAoB,aAA2B,UAA0B;AAChF,QAAM,QAAQ,SAAS,MAAM,GAAG;AAChC,QAAM,aAAa,MAAM,UAAU,IAAI,MAAM,MAAM,SAAS,CAAC,IAAI;AACjE,QAAM,gBAAgB,GAAG,UAAU;AAEnC,MAAI,OAAO;AACX,UAAQ;AAAA;AACR,UAAQ,OAAO,aAAa;AAAA;AAAA;AAC5B,UAAQ;AAAA;AAER,aAAW,QAAQ,aAAa;AAC9B,UAAM,aAAa,KAAK,KAAK,SAAS,IAAI;AAC1C,UAAM,SAAS,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI;AAGxC,UAAM,kBAAkB,wBAAwB;AAEhD,QAAI,YAAY;AACd,cAAQ,0BAA0B,eAAe,eAAe,KAAK,IAAI,oEAAoE,aAAa,oBAAoB,KAAK,WAAW;AAAA;AAAA,IAChM,OAAO;AACL,YAAM,aAAa,cAAc,UAAU,MAAM;AACjD,cAAQ,0BAA0B,eAAe,eAAe,KAAK,IAAI,gEAAgE,UAAU,oCAAoC,aAAa,oBAAoB,KAAK,WAAW;AAAA;AAAA,IAC1O;AAAA,EACF;AAEA,UAAQ;AACR,UAAQ;AACR,UAAQ;AACR,UAAQ,MAAM,YAAY,MAAM;AAAA;AAChC,UAAQ;AAER,SAAO;AACT;AAKA,SAAS,0BAAkC;AACzC,SAAO;AACT;AAKA,SAAS,cAAc,QAAwB;AAC7C,QAAM,YAAoC;AAAA,IACxC,QAAQ;AAAA,IACR,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACA,SAAO,UAAU,OAAO,YAAY,CAAC,KAAK,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAC3F;AAKA,eAAe,uBAAuB,KAAgC;AACpE,QAAM,QAAkB,CAAC;AAEzB,MAAI;AACF,UAAM,UAAU,MAAM,OAAO,aAAa,EAAE,KAAK,CAAAC,QAAMA,IAAG,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC,CAAC;AAE/F,eAAW,SAAS,SAAS;AAC3B,YAAM,WAAWD,OAAK,KAAK,KAAK,MAAM,IAAI;AAE1C,UAAI,MAAM,YAAY,GAAG;AACvB,cAAM,KAAK,GAAG,MAAM,uBAAuB,QAAQ,CAAC;AAAA,MACtD,OAAO;AACL,cAAM,KAAK,QAAQ;AAAA,MACrB;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,SAAO;AACT;AAnfA,IAoBM,uBAWA,kBAgBO;AA/Cb;AAAA;AAAA;AAAA;AAEA;AACA;AACA;AAgBA,IAAM,wBAAgD;AAAA,MACpD,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,SAAS;AAAA,MACT,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,WAAW;AAAA;AAAA,IACb;AAGA,IAAM,mBAAmB,CAAC,QAAQ,UAAU,UAAU,QAAQ;AAgBvD,IAAM,0BAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAkBb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,UAAU;AAAA,YACR,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,wBAAwB;AAAA,YACtB,MAAM;AAAA,YACN,SAAS;AAAA,YACT,aAAa;AAAA,UACf;AAAA,UACA,iBAAiB;AAAA,YACf,MAAM;AAAA,YACN,SAAS;AAAA,YACT,aAAa;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC1FA,OAAOE,iBAAgB;AASvB,OAAOC,YAAU;AA42CjB,eAAsB,oBACpB,MACA,QACiB;AACjB,QAAM,QAAQ,yBAAyB,MAAM,IAAI;AACjD,QAAM,SAAS,MAAM,SAAS,UAAU;AAExC,SAAO,KAAK,qBAAqB,EAAE,QAAQ,MAAM,QAAQ,MAAM,MAAM,MAAM,OAAO,CAAC;AAEnF,QAAM,YAAY,MAAM,wBAAwB,OAAO,WAAW,WAAW;AAE7E,QAAM,SAAyB;AAAA,IAC7B,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,IACR,cAAc,CAAC;AAAA,EACjB;AAEA,QAAM,UAAU;AAAA,IACd,kBAAkB,MAAM,SAAS,oBAAoB;AAAA,IACrD,wBAAwB,MAAM,SAAS,0BAA0B;AAAA,IACjE,mBAAmB,MAAM,SAAS,qBAAqB;AAAA,IACvD,cAAc,MAAM,SAAS,gBAAgB;AAAA,IAC7C,mBAAmB,MAAM,SAAS,qBAAqB;AAAA,IACvD,sBAAsB,MAAM,SAAS,wBAAwB;AAAA,IAC7D,gBAAgB,MAAM,SAAS,kBAAkB;AAAA,EACnD;AAEA,QAAM,YAAY,MAAM,aAAa,CAAC,MAAM;AAE5C,MAAI;AACF,YAAQ,MAAM,QAAQ;AAAA,MACpB,KAAK;AACH,cAAM,oBAAoB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC3F;AAAA,MACF,KAAK;AACH,cAAM,qBAAqB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC5F;AAAA,MACF,KAAK;AACH,cAAM,wBAAwB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC/F;AAAA,MACF,KAAK;AACH,cAAM,uBAAuB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC9F;AAAA,MACF,KAAK;AACH,cAAM,wBAAwB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC/F;AAAA,MACF,KAAK;AACH,cAAM,oBAAoB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC3F,cAAM,qBAAqB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC5F,cAAM,wBAAwB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC/F,cAAM,uBAAuB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC9F,cAAM,wBAAwB,MAAM,MAAM,SAAS,WAAW,WAAW,QAAQ,QAAQ,MAAM;AAC/F;AAAA,IACJ;AAAA,EACF,SAAS,OAAO;AACd,WAAO,UAAU;AACjB,WAAO,aAAa,KAAK,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EAC7F;AAEA,SAAO,iBAAiB,QAAQ,MAAM,QAAQ,MAAM,MAAM,MAAM;AAClE;AAgBA,eAAe,oBACb,MACA,SACA,WACA,WACA,QACA,QACA,QACe;AACf,QAAM,gBAAgB,GAAG,OAAO,YAAY,WAAW,WAAW;AAClE,QAAM,kBAAkB,OAAO,YAAY,WAAW;AAEtD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAGA,MAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,UAAM,UAAUD,YAAW,QAAQ,kBAAkB,EAAE,OAAO;AAC9D,UAAM,WAAWC,OAAK,KAAK,UAAU,MAAM,SAAS,QAAQ,UAAU,GAAG,IAAI,UAAU;AAEvF,yBAAqB,UAAU,UAAU,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,QAAQ,CAAC;AAC5C,YAAM,UAAU,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,SAAS,UAAU,GAAG;AAClC,UAAM,kBAAkBD,YAAW,QAAQ,oBAAoB,EAAE;AAAA,MAC/D,GAAG;AAAA,MACH,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,MACtD,cAAc,OAAO,YAAY,WAAW;AAAA,IAC9C,CAAC;AACD,UAAM,eAAeC,OAAK,KAAK,UAAU,MAAM,SAAS,YAAY,GAAG,IAAI,kBAAkB;AAE7F,yBAAqB,cAAc,UAAU,IAAI;AAEjD,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,YAAY,CAAC;AAChD,YAAM,UAAU,cAAc,eAAe;AAAA,IAC/C;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,YAAY;AAAA,MAChD,SAAS;AAAA,MACT,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,KAAK,sFAAsF;AAC/G,SAAO,aAAa,KAAK,2EAA2E;AACtG;AAEA,eAAe,qBACb,MACA,SACA,WACA,WACA,QACA,QACA,QACe;AACf,QAAM,gBAAgB,GAAG,OAAO,YAAY,WAAW,WAAW;AAClE,QAAM,uBAAuB,OAAO,YAAY,WAAW;AAC3D,QAAM,kBAAkB,OAAO,YAAY,WAAW;AAEtD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,MAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,UAAM,UAAUD,YAAW,QAAQ,mBAAmB,EAAE,OAAO;AAC/D,UAAM,WAAWC,OAAK,KAAK,UAAU,MAAM,SAAS,QAAQ,YAAY,GAAG,IAAI,iBAAiB;AAEhG,yBAAqB,UAAU,UAAU,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,QAAQ,CAAC;AAC5C,YAAM,UAAU,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,KAAK,yEAAyE;AACpG;AAEA,eAAe,wBACb,MACA,SACA,WACA,WACA,QACA,QACA,QACe;AACf,QAAM,gBAAgB,GAAG,OAAO,YAAY,WAAW,WAAW;AAClE,QAAM,uBAAuB,OAAO,YAAY,WAAW;AAC3D,QAAM,kBAAkB,OAAO,YAAY,WAAW;AACtD,QAAM,eAAe,OAAO,YAAY,WAAW;AAEnD,QAAM,UAAU;AAAA,IACd;AAAA,IACA,WAAW,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,MAAI,UAAU,SAAS,aAAa,GAAG;AACrC,UAAM,UAAUD,YAAW,QAAQ,sBAAsB,EAAE,OAAO;AAClE,UAAM,WAAWC,OAAK,KAAK,UAAU,MAAM,SAAS,eAAe,eAAe,GAAG,IAAI,oBAAoB;AAE7G,yBAAqB,UAAU,UAAU,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,QAAQ,CAAC;AAC5C,YAAM,UAAU,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,MAAI,UAAU,SAAS,UAAU,GAAG;AAClC,UAAM,kBAAkBD,YAAW,QAAQ,oBAAoB,EAAE,OAAO;AACxE,UAAM,eAAeC,OAAK,KAAK,UAAU,MAAM,SAAS,YAAY,GAAG,IAAI,kBAAkB;AAE7F,yBAAqB,cAAc,UAAU,IAAI;AAEjD,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,YAAY,CAAC;AAChD,YAAM,UAAU,cAAc,eAAe;AAAA,IAC/C;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,YAAY;AAAA,MAChD,SAAS;AAAA,MACT,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,KAAK,sGAAsG;AACjI;AAEA,eAAe,uBACb,MACA,SACA,WACA,WACA,QACA,QACA,QACe;AACf,QAAM,gBAAgB,GAAG,OAAO,YAAY,WAAW,WAAW;AAClE,QAAM,uBAAuB,OAAO,YAAY,WAAW;AAE3D,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,MAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,UAAM,UAAUD,YAAW,QAAQ,qBAAqB,EAAE,OAAO;AACjE,UAAM,WAAWC,OAAK,KAAK,UAAU,MAAM,SAAS,QAAQ,cAAc,GAAG,IAAI,mBAAmB;AAEpG,yBAAqB,UAAU,UAAU,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,QAAQ,CAAC;AAC5C,YAAM,UAAU,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,KAAK,kGAAkG;AAC7H;AAEA,eAAe,wBACb,MACA,SACA,WACA,WACA,QACA,QACA,QACe;AACf,QAAM,gBAAgB,GAAG,OAAO,YAAY,WAAW,WAAW;AAClE,QAAM,0BAA0B,OAAO,YAAY,WAAW;AAC9D,QAAM,kBAAkB,OAAO,YAAY,WAAW;AAEtD,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL;AAEA,MAAI,UAAU,SAAS,aAAa,GAAG;AACrC,UAAM,UAAUD,YAAW,QAAQ,sBAAsB,EAAE,OAAO;AAClE,UAAM,WAAWC,OAAK,KAAK,UAAU,MAAM,SAAS,eAAe,gBAAgB,GAAG,IAAI,oBAAoB;AAE9G,yBAAqB,UAAU,UAAU,IAAI;AAE7C,QAAI,CAAC,QAAQ;AACX,YAAM,gBAAgBA,OAAK,QAAQ,QAAQ,CAAC;AAC5C,YAAM,UAAU,UAAU,OAAO;AAAA,IACnC;AAEA,WAAO,MAAM,KAAK;AAAA,MAChB,MAAMA,OAAK,SAAS,UAAU,MAAM,QAAQ;AAAA,MAC5C;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO,aAAa,KAAK,4GAA4G;AACvI;AAMA,SAAS,iBACP,QACA,SACA,MACA,QACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK,qBAAqB,IAAI,EAAE;AACtC,QAAM,KAAK,EAAE;AAEb,MAAI,QAAQ;AACV,UAAM,KAAK,4CAA4C;AACvD,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,KAAK,UAAU;AACrB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,OAAO,aAAa,KAAK,IAAI,CAAC;AACzC,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,QAAM,KAAK,4BAA4B,OAAO,MAAM,MAAM,GAAG;AAC7D,QAAM,KAAK,EAAE;AAEb,aAAW,QAAQ,OAAO,OAAO;AAC/B,UAAM,KAAK,SAAS,KAAK,IAAI,IAAI;AACjC,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW;AACtB,UAAM,KAAK,KAAK,OAAO;AACvB,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,OAAO,aAAa,SAAS,GAAG;AAClC,UAAM,KAAK,eAAe;AAC1B,UAAM,KAAK,EAAE;AACb,eAAW,eAAe,OAAO,cAAc;AAC7C,YAAM,KAAK,KAAK,WAAW,EAAE;AAAA,IAC/B;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,qEAAqE;AAChF,QAAM,KAAK,yCAAyC;AACpD,QAAM,KAAK,kDAAkD;AAC7D,QAAM,KAAK,gCAAgC;AAC3C,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAvvDA,IAYa,mBAqGP,oBA0NA,qBA0OA,wBA+QA,uBA2IA,wBA+NA;AA9qCN;AAAA;AAAA;AAAA;AAEA;AAKA;AACA;AACA;AAGO,IAAM,oBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,QACX,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,MAAM,CAAC,UAAU,WAAW,cAAc,aAAa,cAAc,KAAK;AAAA,YAC1E,aAAa;AAAA,UACf;AAAA,UACA,MAAM;AAAA,YACJ,MAAM;AAAA,YACN,aAAa;AAAA,UACf;AAAA,UACA,WAAW;AAAA,YACT,MAAM;AAAA,YACN,OAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,CAAC,QAAQ,eAAe,YAAY,KAAK;AAAA,YACjD;AAAA,YACA,SAAS,CAAC,MAAM;AAAA,YAChB,aAAa;AAAA,UACf;AAAA,UACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,YAAY;AAAA,cACV,kBAAkB;AAAA,gBAChB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,wBAAwB;AAAA,gBACtB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,mBAAmB;AAAA,gBACjB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,cAAc;AAAA,gBACZ,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,mBAAmB;AAAA,gBACjB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,sBAAsB;AAAA,gBACpB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,oBAAoB;AAAA,gBAClB,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,gBAAgB;AAAA,gBACd,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,cACA,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,aAAa;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,UAAU,CAAC,UAAU,MAAM;AAAA,MAC7B;AAAA,IACF;AAGA,IAAAD,YAAW,eAAe,cAAc,CAAC,QAAgB;AACvD,UAAI,CAAC,IAAK,QAAO;AACjB,aAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,IAClD,CAAC;AAED,IAAAA,YAAW,eAAe,aAAa,CAAC,QAAgB;AACtD,UAAI,CAAC,IAAK,QAAO;AACjB,aAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,IAClD,CAAC;AAED,IAAAA,YAAW,eAAe,UAAU,SAAwB,aAAsB,SAAmC;AACnH,UAAI,CAAC,aAAa;AAChB,eAAO,QAAQ,GAAG,IAAI;AAAA,MACxB;AACA,aAAO,QAAQ,QAAQ,IAAI;AAAA,IAC7B,CAAC;AAMD,IAAM,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0N3B,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0O5B,IAAM,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+Q/B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2I9B,IAAM,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+N/B,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA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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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gDA4Qc,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;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","fileURLToPath","exec","promisify","path","execAsync","path","glob","path","path","formatResult","path","formatResult","serviceTestTemplate","path","z","path","SuggestMigrationInputSchema","compareVersions","path","fs","Handlebars","path","path","basename","path","path","PATTERNS","path","formatResult","path","glob","formatResult","path","glob","formatResult","generateRecommendations","webPath","formatResult","path","generateRecommendations","path","path","getLineNumber","stat","path","generateRecommendations","formatResult","dfs","init_types","getLineNumber","truncateCode","context","init_types","match","getLineNumber","capitalize","truncateCode","init_types","getLineNumber","isInComment","truncateCode","init_types","getLineNumber","truncateCode","init_types","getLineNumber","truncateCode","context","init_types","getLineNumber","truncateCode","init_types","getLineNumber","truncateCode","init_types","getLineNumber","truncateCode","init_types","isUiFile","getLineNumber","truncateCode","context","init_types","calculateSummary","init_types","path","path","endpoints","path","parseEntity","path"]}