siesa-agents 2.0.0 → 2.1.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/bin/install.js +273 -28
- package/bmad-core/agents/dev.md +1 -1
- package/package.json +2 -2
package/bin/install.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs-extra');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const readline = require('readline');
|
|
5
6
|
|
|
6
7
|
class SiesaBmadInstaller {
|
|
7
8
|
constructor() {
|
|
@@ -16,6 +17,17 @@ class SiesaBmadInstaller {
|
|
|
16
17
|
this.packageDir = this.findPackageDir();
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
showBanner() {
|
|
21
|
+
console.log('\n');
|
|
22
|
+
console.log('███████╗██╗███████╗███████╗ █████╗ █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗');
|
|
23
|
+
console.log('██╔════╝██║██╔════╝██╔════╝██╔══██╗ ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝');
|
|
24
|
+
console.log('███████╗██║█████╗ ███████╗███████║ ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗');
|
|
25
|
+
console.log('╚════██║██║██╔══╝ ╚════██║██╔══██║ ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║');
|
|
26
|
+
console.log('███████║██║███████╗███████║██║ ██║ ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║');
|
|
27
|
+
console.log('╚══════╝╚═╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝');
|
|
28
|
+
console.log('');
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
findPackageDir() {
|
|
20
32
|
// Opción 1: directorio padre del bin (instalación normal)
|
|
21
33
|
let packageDir = path.dirname(__dirname);
|
|
@@ -32,18 +44,14 @@ class SiesaBmadInstaller {
|
|
|
32
44
|
process.cwd(), // directorio actual como último recurso
|
|
33
45
|
];
|
|
34
46
|
|
|
35
|
-
console.log('🔍 Buscando paquete en ubicaciones alternativas...');
|
|
36
47
|
for (const possiblePath of possiblePaths) {
|
|
37
|
-
console.log(` Probando: ${possiblePath}`);
|
|
38
48
|
if (this.hasRequiredFolders(possiblePath)) {
|
|
39
|
-
console.log(` ✅ Encontrado en: ${possiblePath}`);
|
|
40
49
|
packageDir = possiblePath;
|
|
41
50
|
break;
|
|
42
51
|
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
|
|
46
|
-
console.log(`🎯 Directorio del paquete seleccionado: ${packageDir}`);
|
|
47
55
|
return packageDir;
|
|
48
56
|
}
|
|
49
57
|
|
|
@@ -55,9 +63,8 @@ class SiesaBmadInstaller {
|
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
async install() {
|
|
58
|
-
|
|
59
|
-
console.log('
|
|
60
|
-
console.log(`📁 Directorio de destino: ${this.targetDir}`);
|
|
66
|
+
this.showBanner();
|
|
67
|
+
console.log(' Instalando SIESA Agents...');
|
|
61
68
|
|
|
62
69
|
try {
|
|
63
70
|
// Verificar si ya existe una instalación
|
|
@@ -71,7 +78,7 @@ class SiesaBmadInstaller {
|
|
|
71
78
|
await this.performInstallation();
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
console.log('✅ SIESA
|
|
81
|
+
console.log('✅ SIESA Agents instalado correctamente!');
|
|
75
82
|
this.showPostInstallMessage();
|
|
76
83
|
|
|
77
84
|
} catch (error) {
|
|
@@ -87,28 +94,241 @@ class SiesaBmadInstaller {
|
|
|
87
94
|
});
|
|
88
95
|
}
|
|
89
96
|
|
|
90
|
-
async
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
async checkModifiedFiles() {
|
|
98
|
+
const modifiedFiles = [];
|
|
99
|
+
|
|
100
|
+
for (const mapping of this.folderMappings) {
|
|
101
|
+
const sourcePath = path.join(this.packageDir, mapping.source);
|
|
102
|
+
const targetPath = path.join(this.targetDir, mapping.target);
|
|
103
|
+
|
|
104
|
+
if (!fs.existsSync(sourcePath) || !fs.existsSync(targetPath)) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Obtener todos los archivos recursivamente
|
|
109
|
+
const sourceFiles = await this.getAllFiles(sourcePath);
|
|
110
|
+
|
|
111
|
+
for (const sourceFile of sourceFiles) {
|
|
112
|
+
const relativePath = path.relative(sourcePath, sourceFile);
|
|
113
|
+
const targetFile = path.join(targetPath, relativePath);
|
|
114
|
+
|
|
115
|
+
if (fs.existsSync(targetFile)) {
|
|
116
|
+
try {
|
|
117
|
+
// Comparar contenido de archivos
|
|
118
|
+
const sourceContent = await fs.readFile(sourceFile, 'utf8');
|
|
119
|
+
const targetContent = await fs.readFile(targetFile, 'utf8');
|
|
120
|
+
|
|
121
|
+
if (sourceContent !== targetContent) {
|
|
122
|
+
modifiedFiles.push({
|
|
123
|
+
folder: mapping.target,
|
|
124
|
+
file: relativePath,
|
|
125
|
+
fullPath: targetFile
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
} catch (error) {
|
|
129
|
+
// Si no se puede leer como texto, comparar como buffer (archivos binarios)
|
|
130
|
+
const sourceBuffer = await fs.readFile(sourceFile);
|
|
131
|
+
const targetBuffer = await fs.readFile(targetFile);
|
|
132
|
+
|
|
133
|
+
if (!sourceBuffer.equals(targetBuffer)) {
|
|
134
|
+
modifiedFiles.push({
|
|
135
|
+
folder: mapping.target,
|
|
136
|
+
file: relativePath,
|
|
137
|
+
fullPath: targetFile
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return modifiedFiles;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async getAllFiles(dir) {
|
|
149
|
+
const files = [];
|
|
150
|
+
const items = await fs.readdir(dir);
|
|
151
|
+
|
|
152
|
+
for (const item of items) {
|
|
153
|
+
const fullPath = path.join(dir, item);
|
|
154
|
+
const stat = await fs.stat(fullPath);
|
|
155
|
+
|
|
156
|
+
if (stat.isDirectory()) {
|
|
157
|
+
const subFiles = await this.getAllFiles(fullPath);
|
|
158
|
+
files.push(...subFiles);
|
|
159
|
+
} else {
|
|
160
|
+
files.push(fullPath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return files;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async promptUser(modifiedFiles) {
|
|
168
|
+
console.log('\n⚠️ Se detectaron archivos modificados:');
|
|
169
|
+
|
|
170
|
+
// Agrupar por carpeta
|
|
171
|
+
const filesByFolder = {};
|
|
172
|
+
modifiedFiles.forEach(item => {
|
|
173
|
+
if (!filesByFolder[item.folder]) {
|
|
174
|
+
filesByFolder[item.folder] = [];
|
|
175
|
+
}
|
|
176
|
+
filesByFolder[item.folder].push(item.file);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Mostrar archivos modificados por carpeta
|
|
180
|
+
Object.keys(filesByFolder).forEach(folder => {
|
|
181
|
+
console.log(`\n📁 ${folder}:`);
|
|
182
|
+
filesByFolder[folder].forEach(file => {
|
|
183
|
+
console.log(` - ${file}`);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
console.log('\n¿Qué deseas hacer?');
|
|
188
|
+
console.log('1. Reemplazar todos los archivos (se perderán las modificaciones)');
|
|
189
|
+
console.log('2. Hacer backup de archivos modificados (se agregarán con sufijo _bk)');
|
|
190
|
+
|
|
191
|
+
const rl = readline.createInterface({
|
|
192
|
+
input: process.stdin,
|
|
193
|
+
output: process.stdout
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
return new Promise((resolve) => {
|
|
197
|
+
rl.question('\nElige una opción (1 o 2): ', (answer) => {
|
|
198
|
+
rl.close();
|
|
199
|
+
resolve(answer.trim());
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async backupModifiedFiles(modifiedFiles) {
|
|
205
|
+
console.log('\n🔄 Creando backup de archivos modificados...');
|
|
206
|
+
|
|
207
|
+
for (const item of modifiedFiles) {
|
|
208
|
+
const originalPath = item.fullPath;
|
|
209
|
+
const backupPath = this.getBackupPath(originalPath);
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
await fs.copy(originalPath, backupPath);
|
|
213
|
+
|
|
214
|
+
// Determinar tipo de backup para mostrar mensaje apropiado
|
|
215
|
+
const backupName = path.basename(backupPath);
|
|
216
|
+
const isVersionedBackup = backupName.includes('_bk_');
|
|
217
|
+
|
|
218
|
+
if (isVersionedBackup) {
|
|
219
|
+
console.log(`✓ Backup versionado: ${path.relative(this.targetDir, backupPath)}`);
|
|
220
|
+
} else {
|
|
221
|
+
console.log(`✓ Backup creado: ${path.relative(this.targetDir, backupPath)}`);
|
|
222
|
+
}
|
|
223
|
+
} catch (error) {
|
|
224
|
+
console.warn(`⚠️ Error creando backup de ${item.file}: ${error.message}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
getBackupPath(filePath) {
|
|
230
|
+
const dir = path.dirname(filePath);
|
|
231
|
+
const ext = path.extname(filePath);
|
|
232
|
+
const name = path.basename(filePath, ext);
|
|
233
|
+
|
|
234
|
+
// Primer intento: archivo_bk.ext
|
|
235
|
+
const basicBackupPath = path.join(dir, `${name}_bk${ext}`);
|
|
236
|
+
|
|
237
|
+
// Si no existe, usar el nombre básico
|
|
238
|
+
if (!fs.existsSync(basicBackupPath)) {
|
|
239
|
+
return basicBackupPath;
|
|
98
240
|
}
|
|
99
241
|
|
|
242
|
+
// Si ya existe _bk, crear versión con timestamp
|
|
243
|
+
const now = new Date();
|
|
244
|
+
const timestamp = now.getFullYear().toString() +
|
|
245
|
+
(now.getMonth() + 1).toString().padStart(2, '0') +
|
|
246
|
+
now.getDate().toString().padStart(2, '0') + '_' +
|
|
247
|
+
now.getHours().toString().padStart(2, '0') +
|
|
248
|
+
now.getMinutes().toString().padStart(2, '0') +
|
|
249
|
+
now.getSeconds().toString().padStart(2, '0');
|
|
250
|
+
|
|
251
|
+
return path.join(dir, `${name}_bk_${timestamp}${ext}`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async performUpdateWithBackups() {
|
|
255
|
+
for (const mapping of this.folderMappings) {
|
|
256
|
+
const sourcePath = path.join(this.packageDir, mapping.source);
|
|
257
|
+
const targetPath = path.join(this.targetDir, mapping.target);
|
|
258
|
+
|
|
259
|
+
if (fs.existsSync(sourcePath)) {
|
|
260
|
+
// Copiar archivos selectivamente, preservando los _bk
|
|
261
|
+
await this.copyWithBackupPreservation(sourcePath, targetPath);
|
|
262
|
+
} else {
|
|
263
|
+
console.warn(`⚠️ Carpeta ${mapping.source} no encontrada en el paquete`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async copyWithBackupPreservation(sourcePath, targetPath) {
|
|
269
|
+
// Obtener todos los archivos backup existentes
|
|
270
|
+
const backupFiles = await this.findBackupFiles(targetPath);
|
|
271
|
+
|
|
272
|
+
// Copiar la carpeta completa sobrescribiendo
|
|
273
|
+
await fs.copy(sourcePath, targetPath, {
|
|
274
|
+
overwrite: true,
|
|
275
|
+
recursive: true
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Restaurar los archivos backup
|
|
279
|
+
for (const backupFile of backupFiles) {
|
|
280
|
+
const backupSourcePath = backupFile.tempPath;
|
|
281
|
+
const backupTargetPath = backupFile.originalPath;
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
await fs.copy(backupSourcePath, backupTargetPath);
|
|
285
|
+
// Limpiar archivo temporal
|
|
286
|
+
await fs.remove(backupSourcePath);
|
|
287
|
+
} catch (error) {
|
|
288
|
+
console.warn(`⚠️ Error restaurando backup ${backupFile.relativePath}: ${error.message}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async findBackupFiles(targetPath) {
|
|
294
|
+
if (!fs.existsSync(targetPath)) {
|
|
295
|
+
return [];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const backupFiles = [];
|
|
299
|
+
const allFiles = await this.getAllFiles(targetPath);
|
|
300
|
+
|
|
301
|
+
for (const filePath of allFiles) {
|
|
302
|
+
const fileName = path.basename(filePath);
|
|
303
|
+
// Detectar archivos _bk y _bk_timestamp
|
|
304
|
+
if (fileName.includes('_bk')) {
|
|
305
|
+
const tempPath = path.join(require('os').tmpdir(), `backup_${Date.now()}_${fileName}`);
|
|
306
|
+
const relativePath = path.relative(targetPath, filePath);
|
|
307
|
+
|
|
308
|
+
// Crear copia temporal del backup
|
|
309
|
+
await fs.copy(filePath, tempPath);
|
|
310
|
+
|
|
311
|
+
backupFiles.push({
|
|
312
|
+
originalPath: filePath,
|
|
313
|
+
tempPath: tempPath,
|
|
314
|
+
relativePath: relativePath
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
return backupFiles;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async performInstallation() {
|
|
100
323
|
for (const mapping of this.folderMappings) {
|
|
101
324
|
const sourcePath = path.join(this.packageDir, mapping.source);
|
|
102
325
|
const targetPath = path.join(this.targetDir, mapping.target);
|
|
103
326
|
|
|
104
|
-
console.log(`🔍 Buscando: ${sourcePath}`);
|
|
105
327
|
if (fs.existsSync(sourcePath)) {
|
|
106
|
-
console.log(`📋 Copiando ${mapping.source} -> ${mapping.target}...`);
|
|
107
328
|
await fs.copy(sourcePath, targetPath, {
|
|
108
329
|
overwrite: true,
|
|
109
330
|
recursive: true
|
|
110
331
|
});
|
|
111
|
-
console.log(`✓ ${mapping.target} copiado exitosamente`);
|
|
112
332
|
} else {
|
|
113
333
|
console.warn(`⚠️ Carpeta ${mapping.source} no encontrada en el paquete`);
|
|
114
334
|
}
|
|
@@ -116,19 +336,44 @@ class SiesaBmadInstaller {
|
|
|
116
336
|
}
|
|
117
337
|
|
|
118
338
|
async update() {
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
339
|
+
// Verificar archivos modificados
|
|
340
|
+
console.log('🔍 Verificando archivos modificados...');
|
|
341
|
+
const modifiedFiles = await this.checkModifiedFiles();
|
|
122
342
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
343
|
+
let hasBackups = false;
|
|
344
|
+
if (modifiedFiles.length > 0) {
|
|
345
|
+
const userChoice = await this.promptUser(modifiedFiles);
|
|
346
|
+
|
|
347
|
+
if (userChoice === '2') {
|
|
348
|
+
// Crear backup de archivos modificados
|
|
349
|
+
await this.backupModifiedFiles(modifiedFiles);
|
|
350
|
+
hasBackups = true;
|
|
351
|
+
} else if (userChoice !== '1') {
|
|
352
|
+
console.log('❌ Opción no válida. Cancelando actualización.');
|
|
353
|
+
return;
|
|
127
354
|
}
|
|
355
|
+
|
|
356
|
+
console.log('\n🔄 Procediendo con la actualización...');
|
|
357
|
+
} else {
|
|
358
|
+
console.log('✓ No se detectaron archivos modificados.');
|
|
128
359
|
}
|
|
129
360
|
|
|
130
|
-
//
|
|
131
|
-
|
|
361
|
+
// Si hay backups, hacer actualización preservando backups
|
|
362
|
+
if (hasBackups) {
|
|
363
|
+
await this.performUpdateWithBackups();
|
|
364
|
+
} else {
|
|
365
|
+
// Si no hay backups, hacer actualización normal (remover y copiar)
|
|
366
|
+
for (const mapping of this.folderMappings) {
|
|
367
|
+
const targetPath = path.join(this.targetDir, mapping.target);
|
|
368
|
+
|
|
369
|
+
if (fs.existsSync(targetPath)) {
|
|
370
|
+
await fs.remove(targetPath);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Realizar instalación nueva
|
|
375
|
+
await this.performInstallation();
|
|
376
|
+
}
|
|
132
377
|
}
|
|
133
378
|
|
|
134
379
|
showPostInstallMessage() {
|
package/bmad-core/agents/dev.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<!-- Powered by BMAD™ Core -->
|
|
2
2
|
|
|
3
3
|
# dev
|
|
4
|
-
|
|
4
|
+
hola papu
|
|
5
5
|
ACTIVATION-NOTICE: This file contains your full agent operating guidelines. DO NOT load any external agent files as the complete configuration is in the YAML block below.
|
|
6
6
|
|
|
7
7
|
CRITICAL: Read the full YAML BLOCK that FOLLOWS IN THIS FILE to understand your operating params, start and follow exactly your activation-instructions to alter your state of being, stay in this being until told to exit this mode:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "siesa-agents",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Paquete para instalar y configurar agentes SIESA
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Paquete para instalar y configurar agentes SIESA en tu proyecto",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"siesa-agents": "./bin/install.js"
|