import { Client } from 'ssh2'; /** * Execute a command on the remote server via SSH. * Uses the ssh2 library (already a project dependency) instead of * the plink/sshpass fallback chain from gitea.repo.management. */ export function sshExec(config, command) { const host = config.coolify?.sshHost; const user = config.coolify?.sshUser; const password = config.coolify?.sshPassword; if (!host || !user) { return Promise.reject(new Error('SSH not configured — set coolify.sshHost and coolify.sshUser in config.json')); } return new Promise((resolve, reject) => { const conn = new Client(); conn.on('ready', () => { conn.exec(command, (err, stream) => { if (err) { conn.end(); return reject(err); } let stdout = ''; let stderr = ''; stream.on('close', (code) => { conn.end(); if (code !== 0 && stderr) { reject(new Error(stderr.trim())); } else { resolve(stdout.trim()); } }); stream.on('data', (data) => { stdout += data.toString(); }); stream.stderr.on('data', (data) => { stderr += data.toString(); }); }); }); conn.on('error', (err) => reject(err)); conn.connect({ host, port: 22, username: user, password }); }); }