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.
- package/.github/workflows/ci.yml +148 -0
- package/.husky/pre-commit +2 -0
- package/.prettierignore +31 -0
- package/.prettierrc +13 -0
- package/IMPLEMENTATION_SUMMARY.md +410 -0
- package/PHASE_2_SUMMARY.md +289 -0
- package/README.md +114 -47
- package/SECURITY.md +58 -0
- package/eslint.config.js +70 -0
- package/jest.config.js +49 -0
- package/package.json +40 -14
- package/src/modules/awc-zns-mtd/config.yaml +1 -1
- package/src/modules/custom-agents/cli/awc-agent.js +505 -372
- package/test/integration/cli/cli-commands.integration.test.js +101 -0
- package/test/setup.js +22 -0
- package/test/unit/commands/version.test.js +39 -0
- package/test/unit/config/config-manager.test.js +147 -0
- package/test/unit/utils/file-utils.test.js +177 -0
- package/test/unit/utils/validators.test.js +57 -0
- package/tools/cli/commands/init.js +556 -513
- package/tools/cli/commands/new-project.js +680 -659
- package/tools/cli/commands/status.js +3 -3
- package/tools/cli/commands/validate.js +14 -14
- package/tools/cli/commands/version.js +6 -4
- package/tools/cli/utils/console-logger.js +41 -17
- package/tools/cli/utils/logger.js +176 -0
- package/tools/cli/utils/project-analyzer.js +33 -16
- package/tools/cli/utils/validators.js +144 -0
- package/tools/cli/utils/version.js +6 -2
- package/tools/config/config-manager.js +243 -0
- package/tools/version/changelog-manager.js +301 -288
- package/tools/version/update-checker.js +32 -32
- package/tools/version/version-bump.js +89 -90
- package/tools/version/version-manager.js +17 -7
- package/tsconfig.json +47 -0
- package/types/index.d.ts +206 -0
- package/tools/cli/commands/init-old.js +0 -147
- package/tools/cli/commands/new-project-broken.js +0 -1302
- package/tools/cli/commands/new-project-old.js +0 -1302
- package/tools/cli/commands/new-project.js.backup +0 -1302
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilidades de validación
|
|
3
|
+
* Validadores para inputs del usuario y paths del filesystem
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Valida un nombre de proyecto
|
|
10
|
+
* @param {string} name - Nombre del proyecto
|
|
11
|
+
* @returns {boolean} - true si es válido
|
|
12
|
+
*/
|
|
13
|
+
function validateProjectName(name) {
|
|
14
|
+
if (!name || typeof name !== 'string') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const trimmed = name.trim();
|
|
19
|
+
|
|
20
|
+
// Verificar que no esté vacío
|
|
21
|
+
if (trimmed.length === 0) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Solo letras, números, guiones y guiones bajos
|
|
26
|
+
const validPattern = /^[a-zA-Z0-9-_]+$/;
|
|
27
|
+
if (!validPattern.test(trimmed)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Nombres reservados
|
|
32
|
+
const reserved = [
|
|
33
|
+
'node_modules',
|
|
34
|
+
'package.json',
|
|
35
|
+
'package-lock.json',
|
|
36
|
+
'.git',
|
|
37
|
+
'.awc',
|
|
38
|
+
'test',
|
|
39
|
+
'dist',
|
|
40
|
+
'build'
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
if (reserved.includes(trimmed.toLowerCase())) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// No debe contener path traversal
|
|
48
|
+
if (trimmed.includes('..') || trimmed.includes('/') || trimmed.includes('\\')) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Valida que un path sea seguro
|
|
57
|
+
* @param {string} filePath - Path a validar
|
|
58
|
+
* @returns {boolean} - true si es seguro
|
|
59
|
+
*/
|
|
60
|
+
function validatePath(filePath) {
|
|
61
|
+
if (!filePath || typeof filePath !== 'string') {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Normalizar el path
|
|
66
|
+
const normalized = path.normalize(filePath);
|
|
67
|
+
|
|
68
|
+
// Detectar path traversal
|
|
69
|
+
if (normalized.includes('..')) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Paths del sistema prohibidos (lista básica)
|
|
74
|
+
const forbiddenPaths = [
|
|
75
|
+
'/etc',
|
|
76
|
+
'/sys',
|
|
77
|
+
'/proc',
|
|
78
|
+
'C:\\Windows',
|
|
79
|
+
'C:\\Program Files',
|
|
80
|
+
'/usr/bin',
|
|
81
|
+
'/usr/sbin'
|
|
82
|
+
];
|
|
83
|
+
|
|
84
|
+
for (const forbidden of forbiddenPaths) {
|
|
85
|
+
if (normalized.startsWith(forbidden)) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Sanitiza un path removiendo caracteres peligrosos
|
|
95
|
+
* @param {string} filePath - Path a sanitizar
|
|
96
|
+
* @returns {string} - Path sanitizado
|
|
97
|
+
*/
|
|
98
|
+
function sanitizePath(filePath) {
|
|
99
|
+
if (!filePath) {
|
|
100
|
+
return '';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
let sanitized = filePath;
|
|
104
|
+
|
|
105
|
+
// Normalizar separadores
|
|
106
|
+
sanitized = sanitized.replace(/\\/g, '/');
|
|
107
|
+
|
|
108
|
+
// Eliminar múltiples slashes
|
|
109
|
+
sanitized = sanitized.replace(/\/+/g, '/');
|
|
110
|
+
|
|
111
|
+
// Eliminar path traversal
|
|
112
|
+
sanitized = sanitized.replace(/\.\.\//g, '');
|
|
113
|
+
sanitized = sanitized.replace(/\.\//g, '');
|
|
114
|
+
|
|
115
|
+
return path.normalize(sanitized);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Valida opciones del comando
|
|
120
|
+
* @param {Object} options - Opciones a validar
|
|
121
|
+
* @param {Array<string>} required - Campos requeridos
|
|
122
|
+
* @returns {Object} - { valid: boolean, errors: string[] }
|
|
123
|
+
*/
|
|
124
|
+
function validateCommandOptions(options, required = []) {
|
|
125
|
+
const errors = [];
|
|
126
|
+
|
|
127
|
+
for (const field of required) {
|
|
128
|
+
if (!options[field]) {
|
|
129
|
+
errors.push(`Campo requerido: ${field}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
valid: errors.length === 0,
|
|
135
|
+
errors
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = {
|
|
140
|
+
validateProjectName,
|
|
141
|
+
validatePath,
|
|
142
|
+
sanitizePath,
|
|
143
|
+
validateCommandOptions
|
|
144
|
+
};
|
|
@@ -47,8 +47,12 @@ async function checkForUpdates(currentVersion) {
|
|
|
47
47
|
* @returns {number} -1 si v1 < v2, 0 si v1 === v2, 1 si v1 > v2
|
|
48
48
|
*/
|
|
49
49
|
function compareVersions(v1, v2) {
|
|
50
|
-
if (semver.lt(v1, v2))
|
|
51
|
-
|
|
50
|
+
if (semver.lt(v1, v2)) {
|
|
51
|
+
return -1;
|
|
52
|
+
}
|
|
53
|
+
if (semver.gt(v1, v2)) {
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
52
56
|
return 0;
|
|
53
57
|
}
|
|
54
58
|
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ConfigManager - Gestión centralizada de configuración
|
|
3
|
+
* Centraliza paths, constantes y configuración del framework
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
|
|
9
|
+
class ConfigManager {
|
|
10
|
+
/**
|
|
11
|
+
* Directorios principales
|
|
12
|
+
*/
|
|
13
|
+
static get AWC_DIR() {
|
|
14
|
+
return '.awc';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static get AGENTS_DIR() {
|
|
18
|
+
return path.join(this.AWC_DIR, 'agents');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static get WORKFLOWS_DIR() {
|
|
22
|
+
return path.join(this.AWC_DIR, 'workflows');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static get TEMPLATES_DIR() {
|
|
26
|
+
return path.join(this.AWC_DIR, 'templates');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static get RESOURCES_DIR() {
|
|
30
|
+
return path.join(this.AWC_DIR, 'resources');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static get LOGS_DIR() {
|
|
34
|
+
return path.join(this.AWC_DIR, 'logs');
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static get CONFIG_FILE() {
|
|
38
|
+
return path.join(this.AWC_DIR, 'config.yaml');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Módulos del framework
|
|
43
|
+
*/
|
|
44
|
+
static get CORE_MODULE_PATH() {
|
|
45
|
+
return 'src/modules/awc-zns-mtd';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static get CUSTOM_MODULE_PATH() {
|
|
49
|
+
return 'src/modules/custom-agents';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Configuración de agentes
|
|
54
|
+
*/
|
|
55
|
+
static get CORE_AGENTS() {
|
|
56
|
+
return ['zen-master', 'architect-senior', 'developer-pro', 'qa-specialist'];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static get AGENT_CATEGORIES() {
|
|
60
|
+
return [
|
|
61
|
+
'core',
|
|
62
|
+
'development',
|
|
63
|
+
'qa_testing',
|
|
64
|
+
'product_strategy',
|
|
65
|
+
'support_maintenance',
|
|
66
|
+
'frontend',
|
|
67
|
+
'backend',
|
|
68
|
+
'infrastructure',
|
|
69
|
+
'architecture',
|
|
70
|
+
'quality',
|
|
71
|
+
'business',
|
|
72
|
+
'ai',
|
|
73
|
+
'documentation'
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Configuración de workflows
|
|
79
|
+
*/
|
|
80
|
+
static get WORKFLOW_TYPES() {
|
|
81
|
+
return [
|
|
82
|
+
'quick',
|
|
83
|
+
'standard',
|
|
84
|
+
'enterprise',
|
|
85
|
+
'comercial-flow',
|
|
86
|
+
'inception-flow',
|
|
87
|
+
'development-flow',
|
|
88
|
+
'qa-flow',
|
|
89
|
+
'deployment-flow',
|
|
90
|
+
'support-flow'
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Tipos de proyecto
|
|
96
|
+
*/
|
|
97
|
+
static get PROJECT_TYPES() {
|
|
98
|
+
return ['code-audit', 'greenfield', 'migration', 'maintenance', 'mobile', 'api', 'enterprise'];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Tecnologías soportadas
|
|
103
|
+
*/
|
|
104
|
+
static get SUPPORTED_TECHNOLOGIES() {
|
|
105
|
+
return [
|
|
106
|
+
'java',
|
|
107
|
+
'dotnet',
|
|
108
|
+
'python',
|
|
109
|
+
'php',
|
|
110
|
+
'nodejs',
|
|
111
|
+
'react',
|
|
112
|
+
'angular',
|
|
113
|
+
'vue',
|
|
114
|
+
'react-native',
|
|
115
|
+
'sql',
|
|
116
|
+
'nosql'
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Configuración de logs
|
|
122
|
+
*/
|
|
123
|
+
static get LOG_LEVELS() {
|
|
124
|
+
return ['error', 'warn', 'info', 'debug', 'verbose'];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static get DEFAULT_LOG_LEVEL() {
|
|
128
|
+
return process.env.LOG_LEVEL || 'info';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Configuración de versiones
|
|
133
|
+
*/
|
|
134
|
+
static get SEMVER_TYPES() {
|
|
135
|
+
return ['major', 'minor', 'patch'];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Límites y validaciones
|
|
140
|
+
*/
|
|
141
|
+
static get MAX_PROJECT_NAME_LENGTH() {
|
|
142
|
+
return 50;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static get MIN_PROJECT_NAME_LENGTH() {
|
|
146
|
+
return 3;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
static get RESERVED_NAMES() {
|
|
150
|
+
return [
|
|
151
|
+
'node_modules',
|
|
152
|
+
'package.json',
|
|
153
|
+
'package-lock.json',
|
|
154
|
+
'.git',
|
|
155
|
+
'.awc',
|
|
156
|
+
'test',
|
|
157
|
+
'dist',
|
|
158
|
+
'build',
|
|
159
|
+
'coverage'
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Paths del sistema
|
|
165
|
+
*/
|
|
166
|
+
static get HOME_DIR() {
|
|
167
|
+
return os.homedir();
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static get TEMP_DIR() {
|
|
171
|
+
return os.tmpdir();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Obtiene la ruta completa a un directorio del proyecto
|
|
176
|
+
* @param {string} cwd - Directorio actual
|
|
177
|
+
* @param {string} subPath - Subdirectorio
|
|
178
|
+
* @returns {string} - Path completo
|
|
179
|
+
*/
|
|
180
|
+
static getProjectPath(cwd, subPath = '') {
|
|
181
|
+
return path.join(cwd, this.AWC_DIR, subPath);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Obtiene la ruta a los agentes del proyecto
|
|
186
|
+
* @param {string} cwd - Directorio actual
|
|
187
|
+
* @returns {string} - Path a agentes
|
|
188
|
+
*/
|
|
189
|
+
static getAgentsPath(cwd) {
|
|
190
|
+
return this.getProjectPath(cwd, 'agents');
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Obtiene la ruta a workflows del proyecto
|
|
195
|
+
* @param {string} cwd - Directorio actual
|
|
196
|
+
* @returns {string} - Path a workflows
|
|
197
|
+
*/
|
|
198
|
+
static getWorkflowsPath(cwd) {
|
|
199
|
+
return this.getProjectPath(cwd, 'workflows');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Obtiene la configuración del entorno
|
|
204
|
+
* @returns {Object} - Configuración de entorno
|
|
205
|
+
*/
|
|
206
|
+
static getEnvironmentConfig() {
|
|
207
|
+
return {
|
|
208
|
+
nodeVersion: process.version,
|
|
209
|
+
platform: os.platform(),
|
|
210
|
+
arch: os.arch(),
|
|
211
|
+
cwd: process.cwd(),
|
|
212
|
+
env: process.env.NODE_ENV || 'development'
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Valida la configuración del proyecto
|
|
218
|
+
* @param {Object} config - Configuración a validar
|
|
219
|
+
* @returns {Object} - { valid: boolean, errors: string[] }
|
|
220
|
+
*/
|
|
221
|
+
static validateConfig(config) {
|
|
222
|
+
const errors = [];
|
|
223
|
+
|
|
224
|
+
if (!config.projectName) {
|
|
225
|
+
errors.push('projectName es requerido');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (!config.version) {
|
|
229
|
+
errors.push('version es requerida');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (config.workflow && !this.WORKFLOW_TYPES.includes(config.workflow)) {
|
|
233
|
+
errors.push(`workflow inválido: ${config.workflow}`);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
valid: errors.length === 0,
|
|
238
|
+
errors
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = ConfigManager;
|