@deinossrl/dgp-agent 1.4.27 → 1.4.28

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 (2) hide show
  1. package/index.mjs +94 -17
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -25,8 +25,9 @@
25
25
 
26
26
  import { execSync, spawn, spawnSync } from 'child_process';
27
27
  import { hostname, homedir } from 'os';
28
- import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
28
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync, createWriteStream } from 'fs';
29
29
  import { join, dirname } from 'path';
30
+ import https from 'https';
30
31
 
31
32
  // ============================================
32
33
  // CONFIG FILE MANAGEMENT
@@ -253,8 +254,74 @@ function hasLocalSshKey() {
253
254
  return existsSync(getDgpSshKeyPath());
254
255
  }
255
256
 
257
+ /**
258
+ * Descarga plink.exe para Windows (PuTTY)
259
+ */
260
+ async function downloadPlink() {
261
+ const plinkDir = join(CONFIG_DIR, 'bin');
262
+ const plinkPath = join(plinkDir, 'plink.exe');
263
+
264
+ // Si ya existe, retornar
265
+ if (existsSync(plinkPath)) {
266
+ return plinkPath;
267
+ }
268
+
269
+ console.log('\x1b[33m[!] Descargando plink.exe (PuTTY)...\x1b[0m');
270
+
271
+ // Crear directorio bin si no existe
272
+ if (!existsSync(plinkDir)) {
273
+ mkdirSync(plinkDir, { recursive: true });
274
+ }
275
+
276
+ // URL oficial de PuTTY
277
+ const plinkUrl = 'https://the.earth.li/~sgtatham/putty/latest/w64/plink.exe';
278
+
279
+ return new Promise((resolve, reject) => {
280
+ https.get(plinkUrl, (response) => {
281
+ if (response.statusCode === 302 || response.statusCode === 301) {
282
+ // Seguir redirect
283
+ https.get(response.headers.location, (res) => {
284
+ const fileStream = createWriteStream(plinkPath);
285
+ res.pipe(fileStream);
286
+ fileStream.on('finish', () => {
287
+ fileStream.close();
288
+ console.log('\x1b[32m[✓] plink.exe descargado exitosamente\x1b[0m');
289
+ resolve(plinkPath);
290
+ });
291
+ }).on('error', reject);
292
+ } else {
293
+ const fileStream = createWriteStream(plinkPath);
294
+ response.pipe(fileStream);
295
+ fileStream.on('finish', () => {
296
+ fileStream.close();
297
+ console.log('\x1b[32m[✓] plink.exe descargado exitosamente\x1b[0m');
298
+ resolve(plinkPath);
299
+ });
300
+ }
301
+ }).on('error', reject);
302
+ });
303
+ }
304
+
305
+ /**
306
+ * Obtiene la ruta de plink (sistema o local)
307
+ */
308
+ function getPlinkPath() {
309
+ // Verificar si está en el PATH
310
+ try {
311
+ shellSync('where plink');
312
+ return 'plink'; // Usar del sistema
313
+ } catch (e) {
314
+ // No está en el PATH, verificar si tenemos copia local
315
+ const localPlink = join(CONFIG_DIR, 'bin', 'plink.exe');
316
+ if (existsSync(localPlink)) {
317
+ return localPlink;
318
+ }
319
+ return null;
320
+ }
321
+ }
322
+
256
323
  // Versión del agente
257
- const AGENT_VERSION = '1.4.27';
324
+ const AGENT_VERSION = '1.4.28';
258
325
  let AGENT_MODE = 'smart'; // Siempre inteligente
259
326
 
260
327
  // Configuración (prioridad: env vars > archivo config > platform config > defaults)
@@ -1401,16 +1468,21 @@ async function executeTestConnection(command) {
1401
1468
  await addCommandLog('info', 'Usando autenticación por password');
1402
1469
  const isWindows = process.platform === 'win32';
1403
1470
  if (isWindows) {
1404
- // En Windows verificar si plink está disponible
1405
- try {
1406
- shellSync('where plink');
1407
- await addCommandLog('info', 'Usando plink (PuTTY)');
1408
- sshCmd = `echo y | plink -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1409
- } catch (e) {
1410
- await addCommandLog('error', 'plink no encontrado. Instalá PuTTY desde https://www.putty.org/');
1411
- await addCommandLog('info', 'Alternativa: usá SSH Key en lugar de password en Windows');
1412
- throw new Error('Password auth en Windows requiere PuTTY/plink. Instalalo o usá SSH Key.');
1471
+ // En Windows: obtener o descargar plink
1472
+ let plinkPath = getPlinkPath();
1473
+ if (!plinkPath) {
1474
+ await addCommandLog('info', 'plink no encontrado, descargando automáticamente...');
1475
+ try {
1476
+ plinkPath = await downloadPlink();
1477
+ await addCommandLog('success', 'plink.exe descargado exitosamente');
1478
+ } catch (e) {
1479
+ await addCommandLog('error', `Error descargando plink: ${e.message}`);
1480
+ await addCommandLog('info', 'Alternativa: instalá PuTTY manualmente desde https://www.putty.org/ o usá SSH Key');
1481
+ throw new Error('No se pudo descargar plink. Instalá PuTTY manualmente o usá SSH Key.');
1482
+ }
1413
1483
  }
1484
+ await addCommandLog('info', `Usando plink: ${plinkPath}`);
1485
+ sshCmd = `echo y | "${plinkPath}" -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1414
1486
  } else {
1415
1487
  // En Linux/Mac usar sshpass
1416
1488
  await addCommandLog('info', 'Usando sshpass (Linux/Mac)');
@@ -1427,13 +1499,18 @@ async function executeTestConnection(command) {
1427
1499
  await addCommandLog('info', 'Usando password como alternativa (no hay SSH key guardada)');
1428
1500
  const isWindows = process.platform === 'win32';
1429
1501
  if (isWindows) {
1430
- try {
1431
- shellSync('where plink');
1432
- sshCmd = `echo y | plink -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1433
- } catch (e) {
1434
- await addCommandLog('error', 'plink no encontrado. Instalá PuTTY desde https://www.putty.org/');
1435
- throw new Error('Password auth en Windows requiere PuTTY/plink. Instalalo o usá SSH Key.');
1502
+ let plinkPath = getPlinkPath();
1503
+ if (!plinkPath) {
1504
+ await addCommandLog('info', 'plink no encontrado, descargando automáticamente...');
1505
+ try {
1506
+ plinkPath = await downloadPlink();
1507
+ await addCommandLog('success', 'plink.exe descargado');
1508
+ } catch (e) {
1509
+ await addCommandLog('error', `Error descargando plink: ${e.message}`);
1510
+ throw new Error('No se pudo descargar plink. Instalá PuTTY manualmente o usá SSH Key.');
1511
+ }
1436
1512
  }
1513
+ sshCmd = `echo y | "${plinkPath}" -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1437
1514
  } else {
1438
1515
  sshCmd = `sshpass -p "${sshPassword}" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${user}@${server_host} "echo 'SSH_OK' && hostname && whoami"`;
1439
1516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deinossrl/dgp-agent",
3
- "version": "1.4.27",
3
+ "version": "1.4.28",
4
4
  "description": "Agente local para Despliegue-GPT - Reporta el estado del repositorio Git a la plataforma TenMinute IA",
5
5
  "main": "index.mjs",
6
6
  "bin": {