@deinossrl/dgp-agent 1.4.26 → 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 +96 -6
  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.26';
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,9 +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 usar plink (PuTTY)
1405
- await addCommandLog('info', 'Usando plink (Windows)');
1406
- sshCmd = `echo y | plink -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
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
+ }
1483
+ }
1484
+ await addCommandLog('info', `Usando plink: ${plinkPath}`);
1485
+ sshCmd = `echo y | "${plinkPath}" -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1407
1486
  } else {
1408
1487
  // En Linux/Mac usar sshpass
1409
1488
  await addCommandLog('info', 'Usando sshpass (Linux/Mac)');
@@ -1420,7 +1499,18 @@ async function executeTestConnection(command) {
1420
1499
  await addCommandLog('info', 'Usando password como alternativa (no hay SSH key guardada)');
1421
1500
  const isWindows = process.platform === 'win32';
1422
1501
  if (isWindows) {
1423
- sshCmd = `echo y | plink -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
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
+ }
1512
+ }
1513
+ sshCmd = `echo y | "${plinkPath}" -ssh -pw "${sshPassword}" ${user}@${server_host} "echo SSH_OK && hostname && whoami"`;
1424
1514
  } else {
1425
1515
  sshCmd = `sshpass -p "${sshPassword}" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=10 ${user}@${server_host} "echo 'SSH_OK' && hostname && whoami"`;
1426
1516
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deinossrl/dgp-agent",
3
- "version": "1.4.26",
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": {