@deinossrl/dgp-agent 1.3.0 → 1.4.1
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/index.mjs +221 -20
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -24,20 +24,89 @@
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
import { execSync, spawn } from 'child_process';
|
|
27
|
-
import { hostname } from 'os';
|
|
27
|
+
import { hostname, homedir } from 'os';
|
|
28
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
29
|
+
import { join, dirname } from 'path';
|
|
28
30
|
|
|
29
|
-
//
|
|
31
|
+
// ============================================
|
|
32
|
+
// CONFIG FILE MANAGEMENT
|
|
33
|
+
// ============================================
|
|
34
|
+
|
|
35
|
+
const CONFIG_DIR = join(homedir(), '.dgp-agent');
|
|
36
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Lee la configuración del archivo
|
|
40
|
+
*/
|
|
41
|
+
function loadConfigFile() {
|
|
42
|
+
try {
|
|
43
|
+
if (existsSync(CONFIG_FILE)) {
|
|
44
|
+
const content = readFileSync(CONFIG_FILE, 'utf-8');
|
|
45
|
+
return JSON.parse(content);
|
|
46
|
+
}
|
|
47
|
+
} catch (e) {
|
|
48
|
+
// Ignore errors, return empty config
|
|
49
|
+
}
|
|
50
|
+
return {};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Guarda la configuración en el archivo
|
|
55
|
+
*/
|
|
56
|
+
function saveConfigFile(config) {
|
|
57
|
+
try {
|
|
58
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
59
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
62
|
+
return true;
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error(`Error saving config: ${e.message}`);
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Obtiene un valor de la configuración
|
|
71
|
+
*/
|
|
72
|
+
function getConfigValue(key) {
|
|
73
|
+
const config = loadConfigFile();
|
|
74
|
+
return config[key];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Establece un valor en la configuración
|
|
79
|
+
*/
|
|
80
|
+
function setConfigValue(key, value) {
|
|
81
|
+
const config = loadConfigFile();
|
|
82
|
+
config[key] = value;
|
|
83
|
+
return saveConfigFile(config);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Elimina un valor de la configuración
|
|
88
|
+
*/
|
|
89
|
+
function deleteConfigValue(key) {
|
|
90
|
+
const config = loadConfigFile();
|
|
91
|
+
delete config[key];
|
|
92
|
+
return saveConfigFile(config);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Cargar config del archivo
|
|
96
|
+
const fileConfig = loadConfigFile();
|
|
97
|
+
|
|
98
|
+
// Configuración (prioridad: env vars > archivo config > defaults)
|
|
30
99
|
const CONFIG = {
|
|
31
|
-
apiUrl: process.env.DGP_API_URL || 'https://asivayhbrqennwiwttds.supabase.co/functions/v1/dgp-agent-status',
|
|
32
|
-
commandsUrl: process.env.DGP_COMMANDS_URL || 'https://asivayhbrqennwiwttds.supabase.co/rest/v1/dgp_agent_commands',
|
|
33
|
-
supabaseKey: process.env.DGP_SUPABASE_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFzaXZheWhicnFlbm53aXd0dGRzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjczMDAwOTcsImV4cCI6MjA4Mjg3NjA5N30.s3a7dR-dPkEXI7B2lUTUXU69923hhuX6meheNeo5EKA',
|
|
34
|
-
interval: parseInt(process.env.DGP_INTERVAL || '30', 10),
|
|
35
|
-
commandPollInterval: parseInt(process.env.DGP_COMMAND_POLL_INTERVAL || '10', 10),
|
|
36
|
-
machineId: process.env.DGP_MACHINE_ID || `${hostname()}-${process.env.USERNAME || process.env.USER || 'dev'}`,
|
|
37
|
-
authToken: process.env.DGP_AUTH_TOKEN || null,
|
|
100
|
+
apiUrl: process.env.DGP_API_URL || fileConfig.apiUrl || 'https://asivayhbrqennwiwttds.supabase.co/functions/v1/dgp-agent-status',
|
|
101
|
+
commandsUrl: process.env.DGP_COMMANDS_URL || fileConfig.commandsUrl || 'https://asivayhbrqennwiwttds.supabase.co/rest/v1/dgp_agent_commands',
|
|
102
|
+
supabaseKey: process.env.DGP_SUPABASE_KEY || fileConfig.supabaseKey || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFzaXZheWhicnFlbm53aXd0dGRzIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjczMDAwOTcsImV4cCI6MjA4Mjg3NjA5N30.s3a7dR-dPkEXI7B2lUTUXU69923hhuX6meheNeo5EKA',
|
|
103
|
+
interval: parseInt(process.env.DGP_INTERVAL || fileConfig.interval || '30', 10),
|
|
104
|
+
commandPollInterval: parseInt(process.env.DGP_COMMAND_POLL_INTERVAL || fileConfig.commandPollInterval || '10', 10),
|
|
105
|
+
machineId: process.env.DGP_MACHINE_ID || fileConfig.machineId || `${hostname()}-${process.env.USERNAME || process.env.USER || 'dev'}`,
|
|
106
|
+
authToken: process.env.DGP_AUTH_TOKEN || fileConfig.authToken || null,
|
|
38
107
|
// Claude AI config
|
|
39
|
-
anthropicApiKey: process.env.ANTHROPIC_API_KEY || null,
|
|
40
|
-
aiModel: process.env.DGP_AI_MODEL || 'claude-sonnet-4-20250514',
|
|
108
|
+
anthropicApiKey: process.env.ANTHROPIC_API_KEY || fileConfig.anthropicApiKey || null,
|
|
109
|
+
aiModel: process.env.DGP_AI_MODEL || fileConfig.aiModel || 'claude-sonnet-4-20250514',
|
|
41
110
|
};
|
|
42
111
|
|
|
43
112
|
// Colores para la consola
|
|
@@ -265,12 +334,12 @@ Devuelve los comandos necesarios en formato JSON.`;
|
|
|
265
334
|
for (const cmd of result.commands) {
|
|
266
335
|
logCommand(`$ ${cmd}`);
|
|
267
336
|
try {
|
|
268
|
-
const
|
|
337
|
+
const { stdout } = await shellAsync(cmd);
|
|
269
338
|
logSuccess('✓ Completado');
|
|
270
|
-
if (
|
|
271
|
-
console.log(colors.gray +
|
|
339
|
+
if (stdout && stdout.trim()) {
|
|
340
|
+
console.log(colors.gray + stdout + colors.reset);
|
|
272
341
|
}
|
|
273
|
-
results.push({ cmd, success: true, output });
|
|
342
|
+
results.push({ cmd, success: true, output: stdout });
|
|
274
343
|
} catch (e) {
|
|
275
344
|
logError(`✗ Falló: ${e.message}`);
|
|
276
345
|
results.push({ cmd, success: false, error: e.message });
|
|
@@ -523,7 +592,7 @@ async function reportStatus(status) {
|
|
|
523
592
|
const payload = {
|
|
524
593
|
machine_id: CONFIG.machineId,
|
|
525
594
|
timestamp: new Date().toISOString(),
|
|
526
|
-
agent_version: '1.
|
|
595
|
+
agent_version: '1.4.1',
|
|
527
596
|
status,
|
|
528
597
|
};
|
|
529
598
|
|
|
@@ -822,7 +891,7 @@ async function runAgent(deployMode = false) {
|
|
|
822
891
|
console.log('');
|
|
823
892
|
console.log(`${colors.green}╔═══════════════════════════════════════════════════════╗${colors.reset}`);
|
|
824
893
|
console.log(`${colors.green}║ DGP Agent - Despliegue-GPT Local Agent ║${colors.reset}`);
|
|
825
|
-
console.log(`${colors.green}║ @deinossrl/dgp-agent v1.
|
|
894
|
+
console.log(`${colors.green}║ @deinossrl/dgp-agent v1.4.0 ║${colors.reset}`);
|
|
826
895
|
console.log(`${colors.green}╚═══════════════════════════════════════════════════════╝${colors.reset}`);
|
|
827
896
|
console.log('');
|
|
828
897
|
|
|
@@ -938,7 +1007,7 @@ async function showStatus() {
|
|
|
938
1007
|
function showHelp() {
|
|
939
1008
|
console.log(`
|
|
940
1009
|
${colors.bold}${colors.cyan}DGP Agent - Despliegue-GPT Local Agent${colors.reset}
|
|
941
|
-
${colors.gray}@deinossrl/dgp-agent v1.
|
|
1010
|
+
${colors.gray}@deinossrl/dgp-agent v1.4.0${colors.reset}
|
|
942
1011
|
|
|
943
1012
|
${colors.bold}DESCRIPCIÓN${colors.reset}
|
|
944
1013
|
Agente local que reporta el estado de tu repositorio Git
|
|
@@ -952,8 +1021,9 @@ ${colors.bold}USO${colors.reset}
|
|
|
952
1021
|
${colors.cyan}dgp-agent${colors.reset} Inicia el agente (solo reporta estado)
|
|
953
1022
|
${colors.cyan}dgp-agent deploy${colors.reset} Modo deploy (reporta + escucha comandos)
|
|
954
1023
|
${colors.cyan}dgp-agent status${colors.reset} Muestra el estado actual una vez
|
|
955
|
-
${colors.cyan}dgp-agent ai${colors.reset} Modo IA interactivo (requiere
|
|
1024
|
+
${colors.cyan}dgp-agent ai${colors.reset} Modo IA interactivo (requiere API key)
|
|
956
1025
|
${colors.cyan}dgp-agent ai "tarea"${colors.reset} Ejecuta una tarea con IA
|
|
1026
|
+
${colors.cyan}dgp-agent config${colors.reset} Gestiona la configuración local
|
|
957
1027
|
${colors.cyan}dgp-agent help${colors.reset} Muestra esta ayuda
|
|
958
1028
|
|
|
959
1029
|
${colors.bold}MODOS DE OPERACIÓN${colors.reset}
|
|
@@ -988,6 +1058,7 @@ ${colors.bold}REQUISITOS PARA DEPLOY${colors.reset}
|
|
|
988
1058
|
- Permisos sudo para reload nginx (vía sudoers sin password)
|
|
989
1059
|
|
|
990
1060
|
${colors.bold}CHANGELOG${colors.reset}
|
|
1061
|
+
${colors.cyan}v1.4.0${colors.reset} - Config persistente: dgp-agent config set/get/list
|
|
991
1062
|
${colors.cyan}v1.3.0${colors.reset} - AI Mode: ejecuta tareas con lenguaje natural
|
|
992
1063
|
${colors.cyan}v1.2.7${colors.reset} - Fix: update via Edge Function (401 fix)
|
|
993
1064
|
${colors.cyan}v1.2.6${colors.reset} - Comando git_commit_push desde la UI
|
|
@@ -1002,6 +1073,133 @@ ${colors.bold}MÁS INFO${colors.reset}
|
|
|
1002
1073
|
`);
|
|
1003
1074
|
}
|
|
1004
1075
|
|
|
1076
|
+
/**
|
|
1077
|
+
* Maneja el comando config
|
|
1078
|
+
*/
|
|
1079
|
+
function handleConfigCommand(args) {
|
|
1080
|
+
const subcommand = args[0];
|
|
1081
|
+
const key = args[1];
|
|
1082
|
+
const value = args.slice(2).join(' ');
|
|
1083
|
+
|
|
1084
|
+
// Mapeo de claves amigables a claves internas
|
|
1085
|
+
const keyMap = {
|
|
1086
|
+
'anthropic-api-key': 'anthropicApiKey',
|
|
1087
|
+
'api-key': 'anthropicApiKey',
|
|
1088
|
+
'ai-model': 'aiModel',
|
|
1089
|
+
'model': 'aiModel',
|
|
1090
|
+
'auth-token': 'authToken',
|
|
1091
|
+
'token': 'authToken',
|
|
1092
|
+
'interval': 'interval',
|
|
1093
|
+
'machine-id': 'machineId',
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
const resolveKey = (k) => keyMap[k] || k;
|
|
1097
|
+
|
|
1098
|
+
switch (subcommand) {
|
|
1099
|
+
case 'set':
|
|
1100
|
+
if (!key || !value) {
|
|
1101
|
+
console.log(`${colors.red}Error: dgp-agent config set <key> <value>${colors.reset}`);
|
|
1102
|
+
console.log(`\nClaves disponibles:`);
|
|
1103
|
+
Object.keys(keyMap).forEach(k => console.log(` ${colors.cyan}${k}${colors.reset}`));
|
|
1104
|
+
process.exit(1);
|
|
1105
|
+
}
|
|
1106
|
+
const setKey = resolveKey(key);
|
|
1107
|
+
if (setConfigValue(setKey, value)) {
|
|
1108
|
+
logSuccess(`Config saved: ${key} = ${value.substring(0, 20)}${value.length > 20 ? '...' : ''}`);
|
|
1109
|
+
console.log(`${colors.gray}Archivo: ${CONFIG_FILE}${colors.reset}`);
|
|
1110
|
+
}
|
|
1111
|
+
break;
|
|
1112
|
+
|
|
1113
|
+
case 'get':
|
|
1114
|
+
if (!key) {
|
|
1115
|
+
console.log(`${colors.red}Error: dgp-agent config get <key>${colors.reset}`);
|
|
1116
|
+
process.exit(1);
|
|
1117
|
+
}
|
|
1118
|
+
const getKey = resolveKey(key);
|
|
1119
|
+
const val = getConfigValue(getKey);
|
|
1120
|
+
if (val) {
|
|
1121
|
+
console.log(val);
|
|
1122
|
+
} else {
|
|
1123
|
+
console.log(`${colors.gray}(not set)${colors.reset}`);
|
|
1124
|
+
}
|
|
1125
|
+
break;
|
|
1126
|
+
|
|
1127
|
+
case 'list':
|
|
1128
|
+
case 'ls':
|
|
1129
|
+
const config = loadConfigFile();
|
|
1130
|
+
console.log(`\n${colors.bold}Configuración guardada:${colors.reset}`);
|
|
1131
|
+
console.log(`${colors.gray}Archivo: ${CONFIG_FILE}${colors.reset}\n`);
|
|
1132
|
+
|
|
1133
|
+
if (Object.keys(config).length === 0) {
|
|
1134
|
+
console.log(`${colors.gray} (vacío)${colors.reset}`);
|
|
1135
|
+
} else {
|
|
1136
|
+
Object.entries(config).forEach(([k, v]) => {
|
|
1137
|
+
// Ocultar parcialmente las API keys
|
|
1138
|
+
let displayValue = v;
|
|
1139
|
+
if (k.toLowerCase().includes('key') || k.toLowerCase().includes('token')) {
|
|
1140
|
+
displayValue = typeof v === 'string' && v.length > 10
|
|
1141
|
+
? v.substring(0, 10) + '...' + v.substring(v.length - 4)
|
|
1142
|
+
: '***';
|
|
1143
|
+
}
|
|
1144
|
+
console.log(` ${colors.cyan}${k}${colors.reset}: ${displayValue}`);
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
console.log('');
|
|
1148
|
+
break;
|
|
1149
|
+
|
|
1150
|
+
case 'delete':
|
|
1151
|
+
case 'rm':
|
|
1152
|
+
case 'remove':
|
|
1153
|
+
if (!key) {
|
|
1154
|
+
console.log(`${colors.red}Error: dgp-agent config delete <key>${colors.reset}`);
|
|
1155
|
+
process.exit(1);
|
|
1156
|
+
}
|
|
1157
|
+
const delKey = resolveKey(key);
|
|
1158
|
+
if (deleteConfigValue(delKey)) {
|
|
1159
|
+
logSuccess(`Config deleted: ${key}`);
|
|
1160
|
+
}
|
|
1161
|
+
break;
|
|
1162
|
+
|
|
1163
|
+
case 'path':
|
|
1164
|
+
console.log(CONFIG_FILE);
|
|
1165
|
+
break;
|
|
1166
|
+
|
|
1167
|
+
default:
|
|
1168
|
+
console.log(`
|
|
1169
|
+
${colors.bold}${colors.cyan}dgp-agent config${colors.reset} - Gestión de configuración
|
|
1170
|
+
|
|
1171
|
+
${colors.bold}USO${colors.reset}
|
|
1172
|
+
${colors.cyan}dgp-agent config set <key> <value>${colors.reset} Guardar un valor
|
|
1173
|
+
${colors.cyan}dgp-agent config get <key>${colors.reset} Obtener un valor
|
|
1174
|
+
${colors.cyan}dgp-agent config list${colors.reset} Listar toda la config
|
|
1175
|
+
${colors.cyan}dgp-agent config delete <key>${colors.reset} Eliminar un valor
|
|
1176
|
+
${colors.cyan}dgp-agent config path${colors.reset} Mostrar ruta del archivo
|
|
1177
|
+
|
|
1178
|
+
${colors.bold}CLAVES DISPONIBLES${colors.reset}
|
|
1179
|
+
${colors.yellow}anthropic-api-key${colors.reset} Tu API key de Anthropic (Claude)
|
|
1180
|
+
${colors.yellow}ai-model${colors.reset} Modelo de IA (default: claude-sonnet-4-20250514)
|
|
1181
|
+
${colors.yellow}auth-token${colors.reset} Token JWT para autenticación
|
|
1182
|
+
${colors.yellow}interval${colors.reset} Intervalo de reporte en segundos
|
|
1183
|
+
${colors.yellow}machine-id${colors.reset} ID personalizado de la máquina
|
|
1184
|
+
|
|
1185
|
+
${colors.bold}EJEMPLOS${colors.reset}
|
|
1186
|
+
${colors.gray}# Configurar API key de Claude${colors.reset}
|
|
1187
|
+
dgp-agent config set anthropic-api-key sk-ant-api03-...
|
|
1188
|
+
|
|
1189
|
+
${colors.gray}# Ver configuración actual${colors.reset}
|
|
1190
|
+
dgp-agent config list
|
|
1191
|
+
|
|
1192
|
+
${colors.gray}# Obtener un valor específico${colors.reset}
|
|
1193
|
+
dgp-agent config get ai-model
|
|
1194
|
+
|
|
1195
|
+
${colors.bold}NOTAS${colors.reset}
|
|
1196
|
+
- La config se guarda en: ${colors.gray}${CONFIG_FILE}${colors.reset}
|
|
1197
|
+
- Las variables de entorno tienen prioridad sobre el archivo
|
|
1198
|
+
- Las API keys se ocultan parcialmente al listar
|
|
1199
|
+
`);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1005
1203
|
// CLI
|
|
1006
1204
|
const args = process.argv.slice(2);
|
|
1007
1205
|
const command = args[0];
|
|
@@ -1025,12 +1223,15 @@ switch (command) {
|
|
|
1025
1223
|
case 'version':
|
|
1026
1224
|
case '-v':
|
|
1027
1225
|
case '--version':
|
|
1028
|
-
console.log('@deinossrl/dgp-agent v1.
|
|
1226
|
+
console.log('@deinossrl/dgp-agent v1.4.0');
|
|
1029
1227
|
break;
|
|
1030
1228
|
case 'ai':
|
|
1031
1229
|
case '--ai':
|
|
1032
1230
|
runAIMode();
|
|
1033
1231
|
break;
|
|
1232
|
+
case 'config':
|
|
1233
|
+
handleConfigCommand(args.slice(1));
|
|
1234
|
+
break;
|
|
1034
1235
|
default:
|
|
1035
1236
|
runAgent(false); // Status-only mode
|
|
1036
1237
|
}
|