awc-zns-mtd 2.8.0 → 2.10.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 (40) hide show
  1. package/.github/workflows/ci.yml +148 -0
  2. package/.husky/pre-commit +2 -0
  3. package/.prettierignore +31 -0
  4. package/.prettierrc +13 -0
  5. package/IMPLEMENTATION_SUMMARY.md +410 -0
  6. package/PHASE_2_SUMMARY.md +289 -0
  7. package/README.md +114 -47
  8. package/SECURITY.md +58 -0
  9. package/eslint.config.js +70 -0
  10. package/jest.config.js +49 -0
  11. package/package.json +40 -14
  12. package/src/modules/awc-zns-mtd/config.yaml +1 -1
  13. package/src/modules/custom-agents/cli/awc-agent.js +505 -372
  14. package/test/integration/cli/cli-commands.integration.test.js +101 -0
  15. package/test/setup.js +22 -0
  16. package/test/unit/commands/version.test.js +39 -0
  17. package/test/unit/config/config-manager.test.js +147 -0
  18. package/test/unit/utils/file-utils.test.js +177 -0
  19. package/test/unit/utils/validators.test.js +57 -0
  20. package/tools/cli/commands/init.js +556 -513
  21. package/tools/cli/commands/new-project.js +680 -659
  22. package/tools/cli/commands/status.js +3 -3
  23. package/tools/cli/commands/validate.js +14 -14
  24. package/tools/cli/commands/version.js +6 -4
  25. package/tools/cli/utils/console-logger.js +41 -17
  26. package/tools/cli/utils/logger.js +176 -0
  27. package/tools/cli/utils/project-analyzer.js +33 -16
  28. package/tools/cli/utils/validators.js +144 -0
  29. package/tools/cli/utils/version.js +6 -2
  30. package/tools/config/config-manager.js +243 -0
  31. package/tools/version/changelog-manager.js +301 -288
  32. package/tools/version/update-checker.js +32 -32
  33. package/tools/version/version-bump.js +89 -90
  34. package/tools/version/version-manager.js +17 -7
  35. package/tsconfig.json +47 -0
  36. package/types/index.d.ts +206 -0
  37. package/tools/cli/commands/init-old.js +0 -147
  38. package/tools/cli/commands/new-project-broken.js +0 -1302
  39. package/tools/cli/commands/new-project-old.js +0 -1302
  40. package/tools/cli/commands/new-project.js.backup +0 -1302
@@ -16,11 +16,11 @@ async function statusCommand(options = {}) {
16
16
 
17
17
  displayLogo();
18
18
 
19
- console.log(chalk.cyan('\n📊 Estado del Proyecto AWC ZNS-MTD\n'));
19
+ console.log(chalk.cyan('\n📋 Estado del Proyecto ZΞNAPSΞS\n'));
20
20
 
21
21
  // Verificar si está instalado
22
22
  if (!(await fs.pathExists(awcDir))) {
23
- console.log(chalk.red('❌ AWC ZNS-MTD no está instalado en este proyecto.'));
23
+ console.log(chalk.red('❌ ZΞNAPSΞS no está instalado en este proyecto.'));
24
24
  console.log(chalk.yellow(`\n💡 Ejecuta ${chalk.green('zns install')} para comenzar.\n`));
25
25
  return;
26
26
  }
@@ -110,7 +110,7 @@ async function statusCommand(options = {}) {
110
110
  console.log(chalk.gray('─'.repeat(60)));
111
111
 
112
112
  if (allGood) {
113
- console.log(chalk.green(' ✅ Sistema AWC ZNS-MTD funcionando correctamente'));
113
+ console.log(chalk.green(' ✅ Sistema ZΞNAPSΞS funcionando correctamente'));
114
114
  } else {
115
115
  console.log(chalk.yellow(' ⚠️ Algunos componentes están faltando'));
116
116
  console.log(chalk.gray(` Ejecuta ${chalk.green('zns install --force')} para reparar`));
@@ -26,10 +26,10 @@ async function validateCommand() {
26
26
  checksCount++;
27
27
  if (await fs.pathExists(awcDir)) {
28
28
  passedCount++;
29
- console.log(chalk.green('✓') + ' Directorio .awc existe');
29
+ console.log(`${chalk.green('✓')} Directorio .awc existe`);
30
30
  } else {
31
31
  errors.push('Directorio .awc no encontrado');
32
- console.log(chalk.red('✗') + ' Directorio .awc no encontrado');
32
+ console.log(`${chalk.red('✗')} Directorio .awc no encontrado`);
33
33
  }
34
34
 
35
35
  // Check 2: Configuración
@@ -37,10 +37,10 @@ async function validateCommand() {
37
37
  const config = await loadConfig(awcDir);
38
38
  if (config) {
39
39
  passedCount++;
40
- console.log(chalk.green('✓') + ' Archivo de configuración válido');
40
+ console.log(`${chalk.green('✓')} Archivo de configuración válido`);
41
41
  } else {
42
42
  errors.push('Archivo de configuración inválido o faltante');
43
- console.log(chalk.red('✗') + ' Archivo de configuración inválido');
43
+ console.log(`${chalk.red('✗')} Archivo de configuración inválido`);
44
44
  }
45
45
 
46
46
  // Check 3: Agentes
@@ -48,18 +48,18 @@ async function validateCommand() {
48
48
  const agentsPath = path.join(awcDir, 'agents');
49
49
  if (await fs.pathExists(agentsPath)) {
50
50
  const agentFiles = await fs.readdir(agentsPath);
51
- const yamlAgents = agentFiles.filter(f => f.endsWith('.yaml'));
51
+ const yamlAgents = agentFiles.filter((f) => f.endsWith('.yaml'));
52
52
 
53
53
  if (yamlAgents.length >= 4) {
54
54
  passedCount++;
55
- console.log(chalk.green('✓') + ` ${yamlAgents.length} agentes encontrados`);
55
+ console.log(`${chalk.green('✓')} ${yamlAgents.length} agentes encontrados`);
56
56
  } else {
57
57
  warnings.push(`Solo ${yamlAgents.length} agentes encontrados (se esperan 4)`);
58
- console.log(chalk.yellow('⚠') + ` Solo ${yamlAgents.length} agentes (se esperan 4)`);
58
+ console.log(`${chalk.yellow('⚠')} Solo ${yamlAgents.length} agentes (se esperan 4)`);
59
59
  }
60
60
  } else {
61
61
  errors.push('Directorio de agentes no encontrado');
62
- console.log(chalk.red('✗') + ' Directorio de agentes no encontrado');
62
+ console.log(`${chalk.red('✗')} Directorio de agentes no encontrado`);
63
63
  }
64
64
 
65
65
  // Check 4: Workflows
@@ -70,14 +70,14 @@ async function validateCommand() {
70
70
 
71
71
  if (workflowDirs.length >= 3) {
72
72
  passedCount++;
73
- console.log(chalk.green('✓') + ` ${workflowDirs.length} workflows encontrados`);
73
+ console.log(`${chalk.green('✓')} ${workflowDirs.length} workflows encontrados`);
74
74
  } else {
75
75
  warnings.push(`Solo ${workflowDirs.length} workflows encontrados (se esperan 3)`);
76
- console.log(chalk.yellow('⚠') + ` Solo ${workflowDirs.length} workflows (se esperan 3)`);
76
+ console.log(`${chalk.yellow('⚠')} Solo ${workflowDirs.length} workflows (se esperan 3)`);
77
77
  }
78
78
  } else {
79
79
  errors.push('Directorio de workflows no encontrado');
80
- console.log(chalk.red('✗') + ' Directorio de workflows no encontrado');
80
+ console.log(`${chalk.red('✗')} Directorio de workflows no encontrado`);
81
81
  }
82
82
 
83
83
  // Check 5: Documentación
@@ -85,7 +85,7 @@ async function validateCommand() {
85
85
  const docsPath = path.join(cwd, 'docs');
86
86
  if (await fs.pathExists(docsPath)) {
87
87
  passedCount++;
88
- console.log(chalk.green('✓') + ' Directorio de documentación existe');
88
+ console.log(`${chalk.green('✓')} Directorio de documentación existe`);
89
89
 
90
90
  // Sub-checks de documentación
91
91
  const adrPath = path.join(docsPath, 'adr');
@@ -103,7 +103,7 @@ async function validateCommand() {
103
103
  }
104
104
  } else {
105
105
  warnings.push('Directorio de documentación no encontrado');
106
- console.log(chalk.yellow('⚠') + ' Directorio de documentación no encontrado');
106
+ console.log(`${chalk.yellow('⚠')} Directorio de documentación no encontrado`);
107
107
  }
108
108
 
109
109
  // Resumen
@@ -134,7 +134,7 @@ async function validateCommand() {
134
134
  // Resultado final
135
135
  console.log();
136
136
  if (errors.length === 0 && warnings.length === 0) {
137
- console.log(chalk.green('✅ ¡Proyecto AWC ZNS-MTD totalmente válido!\n'));
137
+ console.log(chalk.green('✅ ¡Proyecto ZΞNAPSΞS totalmente válido!\n'));
138
138
  } else if (errors.length === 0) {
139
139
  console.log(chalk.yellow('⚠️ Proyecto válido con algunas advertencias\n'));
140
140
  console.log(chalk.gray(` Ejecuta ${chalk.green('zns install --force')} para reparar\n`));
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  const chalk = require('chalk');
7
- const semver = require('semver');
7
+ // const semver = require('semver');
8
8
  const { getVersion, checkForUpdates } = require('../utils/version');
9
9
  const { displayLogo } = require('../utils/console-logger');
10
10
 
@@ -17,7 +17,7 @@ async function versionCommand() {
17
17
 
18
18
  console.log(chalk.gray('─'.repeat(60)));
19
19
  console.log(` Versión actual: ${chalk.yellow(currentVersion)}`);
20
- console.log(` Método: ${chalk.cyan('AWC ZNS-MTD')}`);
20
+ console.log(` Método: ${chalk.cyan('ZΞNAPSΞS by ΛNWICO')}`);
21
21
  console.log(` Inspirado en: ${chalk.gray('BMAD Core V6')}`);
22
22
  console.log(chalk.gray('─'.repeat(60)));
23
23
 
@@ -35,7 +35,7 @@ async function versionCommand() {
35
35
  } else {
36
36
  console.log(chalk.green('\n✅ Estás usando la versión más reciente\n'));
37
37
  }
38
- } catch (error) {
38
+ } catch {
39
39
  console.log(chalk.gray('\n No se pudo verificar actualizaciones (sin conexión)\n'));
40
40
  }
41
41
 
@@ -43,7 +43,9 @@ async function versionCommand() {
43
43
  console.log(chalk.cyan('📚 Más información:\n'));
44
44
  console.log(` Documentación: ${chalk.blue('https://github.com/awc/awc-zns-mtd')}`);
45
45
  console.log(` Issues: ${chalk.blue('https://github.com/awc/awc-zns-mtd/issues')}`);
46
- console.log(` Changelog: ${chalk.blue('https://github.com/awc/awc-zns-mtd/blob/main/CHANGELOG.md')}\n`);
46
+ console.log(
47
+ ` Changelog: ${chalk.blue('https://github.com/awc/awc-zns-mtd/blob/main/CHANGELOG.md')}\n`
48
+ );
47
49
  }
48
50
 
49
51
  module.exports = { versionCommand };
@@ -6,13 +6,21 @@
6
6
  const chalk = require('chalk');
7
7
 
8
8
  /**
9
- * Muestra el logo de AWC ZNS-MTD
9
+ * Muestra el logo de ZΞNAPSΞS
10
10
  */
11
11
  function displayLogo() {
12
- console.log();
12
+ console.log('');
13
13
  console.log(chalk.cyan('╔═══════════════════════════════════════════════════════════╗'));
14
- console.log(chalk.cyan('║') + chalk.bold.white(' AWC ZNS-MTD ') + chalk.cyan('║'));
15
- console.log(chalk.cyan('║') + chalk.gray(' Minimalismo Estratégico Method ') + chalk.cyan('║'));
14
+ console.log(
15
+ chalk.cyan('║') +
16
+ chalk.bold.white(' ZΞNAPSΞS by ΛNWICO ') +
17
+ chalk.cyan('║')
18
+ );
19
+ console.log(
20
+ chalk.cyan('║') +
21
+ chalk.gray(' Minimalismo Estratégico Method ') +
22
+ chalk.cyan('║')
23
+ );
16
24
  console.log(chalk.cyan('╚═══════════════════════════════════════════════════════════╝'));
17
25
  console.log();
18
26
  }
@@ -21,28 +29,28 @@ function displayLogo() {
21
29
  * Muestra un mensaje de éxito
22
30
  */
23
31
  function logSuccess(message) {
24
- console.log(chalk.green('✓') + ' ' + message);
32
+ console.log(`${chalk.green('✓')} ${message}`);
25
33
  }
26
34
 
27
35
  /**
28
36
  * Muestra un mensaje de error
29
37
  */
30
38
  function logError(message) {
31
- console.log(chalk.red('✗') + ' ' + message);
39
+ console.log(`${chalk.red('✗')} ${message}`);
32
40
  }
33
41
 
34
42
  /**
35
43
  * Muestra un mensaje de advertencia
36
44
  */
37
45
  function logWarning(message) {
38
- console.log(chalk.yellow('⚠') + ' ' + message);
46
+ console.log(`${chalk.yellow('⚠')} ${message}`);
39
47
  }
40
48
 
41
49
  /**
42
50
  * Muestra un mensaje informativo
43
51
  */
44
52
  function logInfo(message) {
45
- console.log(chalk.blue('ℹ') + ' ' + message);
53
+ console.log(`${chalk.blue('ℹ')} ${message}`);
46
54
  }
47
55
 
48
56
  /**
@@ -74,9 +82,9 @@ function logProgress(current, total, message) {
74
82
  * Muestra una tabla simple
75
83
  */
76
84
  function logTable(data) {
77
- const maxKeyLength = Math.max(...data.map(item => item.key.length));
85
+ const maxKeyLength = Math.max(...data.map((item) => item.key.length));
78
86
 
79
- data.forEach(item => {
87
+ data.forEach((item) => {
80
88
  const paddedKey = item.key.padEnd(maxKeyLength + 2);
81
89
  console.log(` ${chalk.gray(paddedKey)} ${chalk.yellow(item.value)}`);
82
90
  });
@@ -88,7 +96,9 @@ function logTable(data) {
88
96
  function displayWelcome(projectName) {
89
97
  console.log();
90
98
  console.log(chalk.cyan('╔═══════════════════════════════════════════════════════════╗'));
91
- console.log(chalk.cyan('║') + chalk.bold.white(` Bienvenido a ${projectName}`.padEnd(58)) + chalk.cyan('║'));
99
+ console.log(
100
+ chalk.cyan('║') + chalk.bold.white(` Bienvenido a ${projectName}`.padEnd(58)) + chalk.cyan('║')
101
+ );
92
102
  console.log(chalk.cyan('╚═══════════════════════════════════════════════════════════╝'));
93
103
  console.log();
94
104
  }
@@ -99,7 +109,7 @@ function displayWelcome(projectName) {
99
109
  function displayCommands(commands) {
100
110
  console.log(chalk.cyan('\n💡 Comandos disponibles:\n'));
101
111
 
102
- commands.forEach(cmd => {
112
+ commands.forEach((cmd) => {
103
113
  const command = chalk.green(cmd.command.padEnd(20));
104
114
  const description = chalk.gray(cmd.description);
105
115
  console.log(` ${command} ${description}`);
@@ -113,9 +123,15 @@ function displayCommands(commands) {
113
123
  */
114
124
  function displayZnsPhilosophy() {
115
125
  console.log(chalk.cyan('\n📖 Filosofía ZNS-MTD:\n'));
116
- console.log(chalk.yellow(' ZEN') + chalk.gray(' → Claridad, simplicidad deliberada, ruido mínimo'));
117
- console.log(chalk.yellow(' NEUTRO') + chalk.gray(' Objetividad, decisiones basadas en evidencia'));
118
- console.log(chalk.yellow(' SISTEMÁTICO') + chalk.gray(' → Procesos repetibles, documentación rigurosa'));
126
+ console.log(
127
+ chalk.yellow(' ZEN') + chalk.gray(' Claridad, simplicidad deliberada, ruido mínimo')
128
+ );
129
+ console.log(
130
+ chalk.yellow(' NEUTRO') + chalk.gray(' → Objetividad, decisiones basadas en evidencia')
131
+ );
132
+ console.log(
133
+ chalk.yellow(' SISTEMÁTICO') + chalk.gray(' → Procesos repetibles, documentación rigurosa')
134
+ );
119
135
  console.log();
120
136
  }
121
137
 
@@ -126,11 +142,19 @@ function displayCompletionBanner(success = true) {
126
142
  console.log();
127
143
  if (success) {
128
144
  console.log(chalk.green('╔═══════════════════════════════════════════════════════════╗'));
129
- console.log(chalk.green('║') + chalk.bold.white(' ✅ PROCESO COMPLETADO ') + chalk.green('║'));
145
+ console.log(
146
+ chalk.green('║') +
147
+ chalk.bold.white(' ✅ PROCESO COMPLETADO ') +
148
+ chalk.green('║')
149
+ );
130
150
  console.log(chalk.green('╚═══════════════════════════════════════════════════════════╝'));
131
151
  } else {
132
152
  console.log(chalk.red('╔═══════════════════════════════════════════════════════════╗'));
133
- console.log(chalk.red('║') + chalk.bold.white(' ❌ PROCESO FALLIDO ') + chalk.red('║'));
153
+ console.log(
154
+ chalk.red('║') +
155
+ chalk.bold.white(' ❌ PROCESO FALLIDO ') +
156
+ chalk.red('║')
157
+ );
134
158
  console.log(chalk.red('╚═══════════════════════════════════════════════════════════╝'));
135
159
  }
136
160
  console.log();
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Logger - Sistema de logging estructurado
3
+ * Utiliza Winston para logging centralizado
4
+ */
5
+
6
+ const winston = require('winston');
7
+ const path = require('path');
8
+ const fs = require('fs-extra');
9
+ const ConfigManager = require('../config/config-manager');
10
+
11
+ // Asegurar que existe el directorio de logs
12
+ const logsDir = path.join(process.cwd(), ConfigManager.LOGS_DIR);
13
+ fs.ensureDirSync(logsDir);
14
+
15
+ /**
16
+ * Formatos personalizados
17
+ */
18
+ const customFormat = winston.format.combine(
19
+ winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
20
+ winston.format.errors({ stack: true }),
21
+ winston.format.splat(),
22
+ winston.format.json()
23
+ );
24
+
25
+ const consoleFormat = winston.format.combine(
26
+ winston.format.colorize(),
27
+ winston.format.timestamp({ format: 'HH:mm:ss' }),
28
+ winston.format.printf(({ level, message, timestamp, ...metadata }) => {
29
+ let msg = `${timestamp} [${level}]: ${message}`;
30
+ if (Object.keys(metadata).length > 0) {
31
+ msg += ` ${JSON.stringify(metadata)}`;
32
+ }
33
+ return msg;
34
+ })
35
+ );
36
+
37
+ /**
38
+ * Crear logger
39
+ */
40
+ const logger = winston.createLogger({
41
+ level: ConfigManager.DEFAULT_LOG_LEVEL,
42
+ format: customFormat,
43
+ defaultMeta: { service: 'awc-zns-mtd' },
44
+ transports: [
45
+ // Logs de error
46
+ new winston.transports.File({
47
+ filename: path.join(logsDir, 'error.log'),
48
+ level: 'error',
49
+ maxsize: 5242880, // 5MB
50
+ maxFiles: 5
51
+ }),
52
+
53
+ // Logs combinados
54
+ new winston.transports.File({
55
+ filename: path.join(logsDir, 'combined.log'),
56
+ maxsize: 5242880,
57
+ maxFiles: 5
58
+ }),
59
+
60
+ // Logs de comandos (solo info y superior)
61
+ new winston.transports.File({
62
+ filename: path.join(logsDir, 'commands.log'),
63
+ level: 'info',
64
+ maxsize: 5242880,
65
+ maxFiles: 3
66
+ })
67
+ ],
68
+
69
+ // Manejo de excepciones
70
+ exceptionHandlers: [
71
+ new winston.transports.File({
72
+ filename: path.join(logsDir, 'exceptions.log')
73
+ })
74
+ ],
75
+
76
+ // Manejo de rechazos de promesas
77
+ rejectionHandlers: [
78
+ new winston.transports.File({
79
+ filename: path.join(logsDir, 'rejections.log')
80
+ })
81
+ ]
82
+ });
83
+
84
+ // En desarrollo, también loguear a consola
85
+ if (process.env.NODE_ENV !== 'production') {
86
+ logger.add(
87
+ new winston.transports.Console({
88
+ format: consoleFormat,
89
+ level: 'debug'
90
+ })
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Wrapper para comandos CLI
96
+ */
97
+ class CLILogger {
98
+ /**
99
+ * Log de inicio de comando
100
+ * @param {string} command - Nombre del comando
101
+ * @param {Object} options - Opciones del comando
102
+ */
103
+ static commandStart(command, options = {}) {
104
+ logger.info('Command started', {
105
+ command,
106
+ options,
107
+ timestamp: new Date().toISOString()
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Log de finalización de comando
113
+ * @param {string} command - Nombre del comando
114
+ * @param {boolean} success - Si fue exitoso
115
+ * @param {number} duration - Duración en ms
116
+ */
117
+ static commandEnd(command, success = true, duration = 0) {
118
+ const level = success ? 'info' : 'error';
119
+ logger[level]('Command finished', {
120
+ command,
121
+ success,
122
+ duration: `${duration}ms`,
123
+ timestamp: new Date().toISOString()
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Log de error de comando
129
+ * @param {string} command - Nombre del comando
130
+ * @param {Error} error - Error ocurrido
131
+ */
132
+ static commandError(command, error) {
133
+ logger.error('Command error', {
134
+ command,
135
+ error: error.message,
136
+ stack: error.stack,
137
+ timestamp: new Date().toISOString()
138
+ });
139
+ }
140
+
141
+ /**
142
+ * Log de operación de archivo
143
+ * @param {string} operation - Tipo de operación
144
+ * @param {string} filePath - Path del archivo
145
+ * @param {boolean} success - Si fue exitoso
146
+ */
147
+ static fileOperation(operation, filePath, success = true) {
148
+ logger.info('File operation', {
149
+ operation,
150
+ filePath,
151
+ success,
152
+ timestamp: new Date().toISOString()
153
+ });
154
+ }
155
+
156
+ /**
157
+ * Log de validación
158
+ * @param {string} type - Tipo de validación
159
+ * @param {boolean} valid - Si es válido
160
+ * @param {Array<string>} errors - Errores encontrados
161
+ */
162
+ static validation(type, valid, errors = []) {
163
+ const level = valid ? 'info' : 'warn';
164
+ logger[level]('Validation', {
165
+ type,
166
+ valid,
167
+ errors,
168
+ timestamp: new Date().toISOString()
169
+ });
170
+ }
171
+ }
172
+
173
+ module.exports = {
174
+ logger,
175
+ CLILogger
176
+ };
@@ -50,7 +50,6 @@ async function analyzeProject(projectPath) {
50
50
 
51
51
  // Calcular tamaño
52
52
  analysis.size = calculateSize(analysis);
53
-
54
53
  } catch (error) {
55
54
  console.error('Error en análisis:', error.message);
56
55
  }
@@ -69,16 +68,16 @@ async function detectTechnologies(projectPath) {
69
68
  'yarn.lock': ['Yarn'],
70
69
  'pnpm-lock.yaml': ['pnpm'],
71
70
  'requirements.txt': ['Python', 'pip'],
72
- 'Pipfile': ['Python', 'Pipenv'],
71
+ Pipfile: ['Python', 'Pipenv'],
73
72
  'pyproject.toml': ['Python', 'Poetry'],
74
- 'Gemfile': ['Ruby', 'Bundler'],
73
+ Gemfile: ['Ruby', 'Bundler'],
75
74
  'Cargo.toml': ['Rust', 'Cargo'],
76
75
  'go.mod': ['Go'],
77
76
  'pom.xml': ['Java', 'Maven'],
78
77
  'build.gradle': ['Java/Kotlin', 'Gradle'],
79
78
  'composer.json': ['PHP', 'Composer'],
80
79
  '.csproj': ['C#', '.NET'],
81
- 'Dockerfile': ['Docker'],
80
+ Dockerfile: ['Docker'],
82
81
  'docker-compose.yml': ['Docker Compose'],
83
82
  '.gitignore': ['Git'],
84
83
  'tsconfig.json': ['TypeScript'],
@@ -198,7 +197,7 @@ async function detectBuildTools(projectPath) {
198
197
  'rollup.config.js': 'Rollup',
199
198
  'gulpfile.js': 'Gulp',
200
199
  'Gruntfile.js': 'Grunt',
201
- 'Makefile': 'Make',
200
+ Makefile: 'Make',
202
201
  'CMakeLists.txt': 'CMake'
203
202
  };
204
203
 
@@ -220,21 +219,35 @@ function calculateComplexity(analysis) {
220
219
  let score = 0;
221
220
 
222
221
  // Basado en cantidad de archivos
223
- if (fileCount > 1000) score += 3;
224
- else if (fileCount > 500) score += 2;
225
- else if (fileCount > 100) score += 1;
222
+ if (fileCount > 1000) {
223
+ score += 3;
224
+ } else if (fileCount > 500) {
225
+ score += 2;
226
+ } else if (fileCount > 100) {
227
+ score += 1;
228
+ }
226
229
 
227
230
  // Basado en cantidad de directorios
228
- if (directoryCount > 100) score += 2;
229
- else if (directoryCount > 50) score += 1;
231
+ if (directoryCount > 100) {
232
+ score += 2;
233
+ } else if (directoryCount > 50) {
234
+ score += 1;
235
+ }
230
236
 
231
237
  // Basado en cantidad de tecnologías
232
- if (technologies.length > 10) score += 2;
233
- else if (technologies.length > 5) score += 1;
238
+ if (technologies.length > 10) {
239
+ score += 2;
240
+ } else if (technologies.length > 5) {
241
+ score += 1;
242
+ }
234
243
 
235
244
  // Determinar nivel de complejidad
236
- if (score >= 5) return 'high';
237
- if (score >= 3) return 'medium';
245
+ if (score >= 5) {
246
+ return 'high';
247
+ }
248
+ if (score >= 3) {
249
+ return 'medium';
250
+ }
238
251
  return 'low';
239
252
  }
240
253
 
@@ -244,8 +257,12 @@ function calculateComplexity(analysis) {
244
257
  function calculateSize(analysis) {
245
258
  const { fileCount } = analysis;
246
259
 
247
- if (fileCount > 1000) return 'large';
248
- if (fileCount > 100) return 'medium';
260
+ if (fileCount > 1000) {
261
+ return 'large';
262
+ }
263
+ if (fileCount > 100) {
264
+ return 'medium';
265
+ }
249
266
  return 'small';
250
267
  }
251
268