plazbot-cli 0.2.20 → 0.2.21

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/dist/cli.js CHANGED
@@ -6,6 +6,7 @@ const portal_1 = require("./commands/portal");
6
6
  const auth_1 = require("./commands/auth");
7
7
  const agent_1 = require("./commands/agent");
8
8
  const whatsapp_1 = require("./commands/whatsapp");
9
+ const workers_1 = require("./commands/workers");
9
10
  const banner_1 = require("./utils/banner");
10
11
  // Configuracion basica del CLI
11
12
  commander_1.program
@@ -20,6 +21,8 @@ commander_1.program.addCommand(agent_1.agentCommands);
20
21
  commander_1.program.addCommand(portal_1.portalCommands);
21
22
  // Registrar todos los comandos de WhatsApp
22
23
  commander_1.program.addCommand(whatsapp_1.whatsappCommands);
24
+ // Registrar todos los comandos de Workers
25
+ commander_1.program.addCommand(workers_1.workersCommands);
23
26
  // Si no se pasan argumentos, mostrar banner
24
27
  if (process.argv.length <= 2) {
25
28
  (0, banner_1.showBanner)().then(() => {
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.deployCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const promises_1 = __importDefault(require("fs/promises"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const credentials_1 = require("../../utils/credentials");
11
+ const api_1 = require("../../utils/api");
12
+ const logger_1 = require("../../utils/logger");
13
+ const ui_1 = require("../../utils/ui");
14
+ exports.deployCommand = new commander_1.Command('deploy')
15
+ .description('Despliega un worker al workspace de Plazbot')
16
+ .argument('[file]', 'Archivo TypeScript del worker (ej: ./workers/mi-tool.ts)')
17
+ .option('-n, --name <name>', 'Nombre del worker (sobreescribe el del archivo)')
18
+ .option('-d, --description <desc>', 'Descripcion del worker')
19
+ .option('--dev', 'Usar ambiente de desarrollo', false)
20
+ .action(async (file, options) => {
21
+ try {
22
+ const credentials = await (0, credentials_1.getStoredCredentials)();
23
+ // Buscar archivos de workers
24
+ const files = await resolveWorkerFiles(file);
25
+ if (files.length === 0) {
26
+ logger_1.logger.error('No se encontraron archivos de workers para desplegar');
27
+ logger_1.logger.dim('Uso: plazbot workers deploy ./workers/mi-tool.ts');
28
+ logger_1.logger.dim(' o: plazbot workers deploy (busca en ./workers/ automaticamente)');
29
+ process.exit(1);
30
+ }
31
+ const api = (0, api_1.createApiClient)({
32
+ apiKey: credentials.apiKey,
33
+ workspace: credentials.workspace,
34
+ zone: credentials.zone,
35
+ dev: options.dev,
36
+ });
37
+ logger_1.logger.title(`Desplegando ${files.length} worker${files.length > 1 ? 's' : ''}`);
38
+ console.log();
39
+ const results = [];
40
+ for (const filePath of files) {
41
+ const fileName = path_1.default.basename(filePath);
42
+ const spinner = (0, ui_1.createSpinner)(`Desplegando ${fileName}...`);
43
+ spinner.start();
44
+ try {
45
+ // Leer archivo fuente
46
+ const sourceCode = await promises_1.default.readFile(filePath, 'utf-8');
47
+ // Enviar al API
48
+ const response = await api.post('/api/workers/deploy', {
49
+ sourceCode,
50
+ fileName,
51
+ name: files.length === 1 ? options.name : undefined,
52
+ description: files.length === 1 ? options.description : undefined,
53
+ });
54
+ const data = response.data;
55
+ spinner.succeed(`${fileName} → ${data.name} (${data.type})`);
56
+ results.push({ file: fileName, result: data });
57
+ }
58
+ catch (error) {
59
+ const msg = error.response?.data?.message || error.message || 'Error desconocido';
60
+ spinner.fail(`${fileName}: ${msg}`);
61
+ results.push({ file: fileName, error: msg });
62
+ }
63
+ }
64
+ // Resumen
65
+ console.log();
66
+ const success = results.filter(r => r.result);
67
+ const failed = results.filter(r => r.error);
68
+ if (success.length > 0) {
69
+ logger_1.logger.success(`${success.length} worker${success.length > 1 ? 's' : ''} desplegado${success.length > 1 ? 's' : ''}`);
70
+ const rows = success.map(r => [
71
+ r.result.name,
72
+ r.result.type,
73
+ r.result.status,
74
+ r.result.webhookUrl || r.result.cronExpression || '—',
75
+ ]);
76
+ console.log((0, ui_1.createTable)(['Nombre', 'Tipo', 'Estado', 'URL/Cron'], rows));
77
+ }
78
+ if (failed.length > 0) {
79
+ logger_1.logger.warning(`${failed.length} worker${failed.length > 1 ? 's' : ''} fallaron`);
80
+ failed.forEach(f => logger_1.logger.dim(` ${f.file}: ${f.error}`));
81
+ }
82
+ // Mostrar webhook URLs si hay
83
+ const webhooks = success.filter(r => r.result.webhookUrl);
84
+ if (webhooks.length > 0) {
85
+ console.log();
86
+ logger_1.logger.title('Webhook URLs');
87
+ webhooks.forEach(w => {
88
+ logger_1.logger.label(w.result.name, ui_1.theme.secondary(w.result.webhookUrl));
89
+ });
90
+ }
91
+ console.log();
92
+ if (options.dev) {
93
+ logger_1.logger.warning('Ambiente: desarrollo');
94
+ }
95
+ }
96
+ catch (error) {
97
+ const message = error instanceof Error ? error.message : 'Error desconocido';
98
+ logger_1.logger.error(message);
99
+ process.exit(1);
100
+ }
101
+ });
102
+ // Resuelve los archivos a desplegar
103
+ async function resolveWorkerFiles(file) {
104
+ if (file) {
105
+ // Archivo especifico
106
+ const resolved = path_1.default.resolve(file);
107
+ try {
108
+ await promises_1.default.access(resolved);
109
+ return [resolved];
110
+ }
111
+ catch {
112
+ throw new Error(`Archivo no encontrado: ${file}`);
113
+ }
114
+ }
115
+ // Buscar en ./workers/ automaticamente
116
+ const workersDir = path_1.default.resolve('workers');
117
+ try {
118
+ const entries = await promises_1.default.readdir(workersDir);
119
+ const tsFiles = entries
120
+ .filter(e => e.endsWith('.ts') && !e.endsWith('.d.ts'))
121
+ .map(e => path_1.default.join(workersDir, e));
122
+ return tsFiles;
123
+ }
124
+ catch {
125
+ return [];
126
+ }
127
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.workersCommands = void 0;
4
+ const commander_1 = require("commander");
5
+ const deploy_1 = require("./deploy");
6
+ const list_1 = require("./list");
7
+ const logs_1 = require("./logs");
8
+ const remove_1 = require("./remove");
9
+ const secret_1 = require("./secret");
10
+ const test_1 = require("./test");
11
+ exports.workersCommands = new commander_1.Command('workers')
12
+ .description('Comandos para gestionar workers (tools, syncs, schedules, webhooks)')
13
+ .addCommand(deploy_1.deployCommand)
14
+ .addCommand(list_1.listCommand)
15
+ .addCommand(logs_1.logsCommand)
16
+ .addCommand(remove_1.removeCommand)
17
+ .addCommand(secret_1.secretCommand)
18
+ .addCommand(test_1.testCommand);
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.listCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const credentials_1 = require("../../utils/credentials");
6
+ const api_1 = require("../../utils/api");
7
+ const logger_1 = require("../../utils/logger");
8
+ const ui_1 = require("../../utils/ui");
9
+ exports.listCommand = new commander_1.Command('list')
10
+ .description('Lista todos los workers del workspace')
11
+ .option('-t, --type <type>', 'Filtrar por tipo (tool, worker, sync, schedule, webhook)')
12
+ .option('-s, --status <status>', 'Filtrar por estado (active, inactive, error)')
13
+ .option('--dev', 'Usar ambiente de desarrollo', false)
14
+ .action(async (options) => {
15
+ try {
16
+ const credentials = await (0, credentials_1.getStoredCredentials)();
17
+ const api = (0, api_1.createApiClient)({
18
+ apiKey: credentials.apiKey,
19
+ workspace: credentials.workspace,
20
+ zone: credentials.zone,
21
+ dev: options.dev,
22
+ });
23
+ const spinner = (0, ui_1.createSpinner)('Obteniendo workers...');
24
+ spinner.start();
25
+ const params = {};
26
+ if (options.type)
27
+ params.type = options.type;
28
+ if (options.status)
29
+ params.status = options.status;
30
+ const response = await api.get('/api/workers', { params });
31
+ const workers = response.data;
32
+ spinner.stop();
33
+ if (!workers || workers.length === 0) {
34
+ logger_1.logger.info('\n No se encontraron workers en este workspace');
35
+ logger_1.logger.dim(' Despliega tu primer worker: plazbot workers deploy ./workers/mi-tool.ts');
36
+ console.log();
37
+ return;
38
+ }
39
+ logger_1.logger.title(`Workers (${workers.length})`);
40
+ const rows = workers.map(w => [
41
+ w.name,
42
+ typeLabel(w.type),
43
+ w.status === 'active' ? ui_1.theme.success('activo')
44
+ : w.status === 'error' ? ui_1.theme.error('error')
45
+ : ui_1.theme.muted('inactivo'),
46
+ `${w.executionCount}`,
47
+ w.errorCount > 0 ? ui_1.theme.error(`${w.errorCount}`) : ui_1.theme.muted('0'),
48
+ w.avgDurationMs > 0 ? `${w.avgDurationMs}ms` : '—',
49
+ w.lastExecutedAt ? (0, ui_1.formatDate)(w.lastExecutedAt) : '—',
50
+ ]);
51
+ console.log((0, ui_1.createTable)(['Nombre', 'Tipo', 'Estado', 'Ejecuciones', 'Errores', 'Duracion', 'Ultima ejecucion'], rows));
52
+ // Mostrar workers con error
53
+ const errored = workers.filter(w => w.status === 'error');
54
+ if (errored.length > 0) {
55
+ console.log();
56
+ logger_1.logger.warning('Workers con error:');
57
+ errored.forEach(w => {
58
+ logger_1.logger.dim(` ${w.name}: ${w.lastError || 'sin detalles'}`);
59
+ });
60
+ }
61
+ console.log();
62
+ if (options.dev) {
63
+ logger_1.logger.warning('Ambiente: desarrollo');
64
+ }
65
+ }
66
+ catch (error) {
67
+ const message = error instanceof Error ? error.message : 'Error desconocido';
68
+ logger_1.logger.error(message);
69
+ process.exit(1);
70
+ }
71
+ });
72
+ function typeLabel(type) {
73
+ const labels = {
74
+ tool: ui_1.theme.secondary('tool'),
75
+ worker: ui_1.theme.primary('worker'),
76
+ sync: ui_1.theme.accent('sync'),
77
+ schedule: ui_1.theme.muted('schedule'),
78
+ webhook: ui_1.theme.warning('webhook'),
79
+ };
80
+ return labels[type] || type;
81
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logsCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const credentials_1 = require("../../utils/credentials");
6
+ const api_1 = require("../../utils/api");
7
+ const logger_1 = require("../../utils/logger");
8
+ const ui_1 = require("../../utils/ui");
9
+ exports.logsCommand = new commander_1.Command('logs')
10
+ .description('Ver logs de ejecucion de un worker')
11
+ .argument('<name>', 'Nombre del worker')
12
+ .option('-l, --limit <number>', 'Numero de logs a mostrar', '20')
13
+ .option('-s, --status <status>', 'Filtrar por estado (success, error, timeout)')
14
+ .option('--dev', 'Usar ambiente de desarrollo', false)
15
+ .action(async (name, options) => {
16
+ try {
17
+ const credentials = await (0, credentials_1.getStoredCredentials)();
18
+ const api = (0, api_1.createApiClient)({
19
+ apiKey: credentials.apiKey,
20
+ workspace: credentials.workspace,
21
+ zone: credentials.zone,
22
+ dev: options.dev,
23
+ });
24
+ const spinner = (0, ui_1.createSpinner)(`Obteniendo logs de "${name}"...`);
25
+ spinner.start();
26
+ const params = {
27
+ limit: String(options.limit || 20),
28
+ };
29
+ if (options.status)
30
+ params.status = options.status;
31
+ const response = await api.get(`/api/workers/${encodeURIComponent(name)}/logs`, { params });
32
+ const logs = response.data;
33
+ spinner.stop();
34
+ if (!logs || logs.length === 0) {
35
+ logger_1.logger.info(`\n No se encontraron logs para "${name}"`);
36
+ console.log();
37
+ return;
38
+ }
39
+ logger_1.logger.title(`Logs de "${name}" (${logs.length})`);
40
+ const rows = logs.map(log => [
41
+ (0, ui_1.formatDate)(log.createdAt),
42
+ log.status === 'success' ? ui_1.theme.success('ok')
43
+ : log.status === 'error' ? ui_1.theme.error('error')
44
+ : ui_1.theme.warning('timeout'),
45
+ `${log.durationMs}ms`,
46
+ log.triggerSource || '—',
47
+ log.error ? ui_1.theme.error(truncate(log.error, 40)) : '—',
48
+ ]);
49
+ console.log((0, ui_1.createTable)(['Fecha', 'Estado', 'Duracion', 'Origen', 'Error'], rows));
50
+ // Resumen
51
+ const successCount = logs.filter(l => l.status === 'success').length;
52
+ const errorCount = logs.filter(l => l.status === 'error').length;
53
+ const avgDuration = Math.round(logs.reduce((sum, l) => sum + l.durationMs, 0) / logs.length);
54
+ console.log();
55
+ logger_1.logger.label('Exitosos', ui_1.theme.success(`${successCount}`));
56
+ logger_1.logger.label('Errores', errorCount > 0 ? ui_1.theme.error(`${errorCount}`) : ui_1.theme.muted('0'));
57
+ logger_1.logger.label('Duracion promedio', `${avgDuration}ms`);
58
+ console.log();
59
+ if (options.dev) {
60
+ logger_1.logger.warning('Ambiente: desarrollo');
61
+ }
62
+ }
63
+ catch (error) {
64
+ if (error.response?.status === 404) {
65
+ logger_1.logger.error(`Worker "${name}" no encontrado`);
66
+ }
67
+ else {
68
+ const message = error instanceof Error ? error.message : 'Error desconocido';
69
+ logger_1.logger.error(message);
70
+ }
71
+ process.exit(1);
72
+ }
73
+ });
74
+ function truncate(text, max) {
75
+ if (text.length <= max)
76
+ return text;
77
+ return text.substring(0, max - 3) + '...';
78
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.removeCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const credentials_1 = require("../../utils/credentials");
9
+ const api_1 = require("../../utils/api");
10
+ const logger_1 = require("../../utils/logger");
11
+ const ui_1 = require("../../utils/ui");
12
+ const readline_1 = __importDefault(require("readline"));
13
+ exports.removeCommand = new commander_1.Command('remove')
14
+ .description('Elimina un worker del workspace')
15
+ .argument('<name>', 'Nombre del worker a eliminar')
16
+ .option('-f, --force', 'Eliminar sin confirmacion', false)
17
+ .option('--dev', 'Usar ambiente de desarrollo', false)
18
+ .action(async (name, options) => {
19
+ try {
20
+ const credentials = await (0, credentials_1.getStoredCredentials)();
21
+ const api = (0, api_1.createApiClient)({
22
+ apiKey: credentials.apiKey,
23
+ workspace: credentials.workspace,
24
+ zone: credentials.zone,
25
+ dev: options.dev,
26
+ });
27
+ // Verificar que el worker existe
28
+ const spinner = (0, ui_1.createSpinner)(`Buscando worker "${name}"...`);
29
+ spinner.start();
30
+ let workerInfo;
31
+ try {
32
+ const response = await api.get(`/api/workers/${encodeURIComponent(name)}`);
33
+ workerInfo = response.data;
34
+ spinner.stop();
35
+ }
36
+ catch (error) {
37
+ spinner.stop();
38
+ if (error.response?.status === 404) {
39
+ logger_1.logger.error(`Worker "${name}" no encontrado`);
40
+ }
41
+ else {
42
+ logger_1.logger.error(error.response?.data?.message || error.message);
43
+ }
44
+ process.exit(1);
45
+ }
46
+ // Mostrar info del worker
47
+ logger_1.logger.warning(`\n Vas a eliminar el siguiente worker:`);
48
+ logger_1.logger.divider();
49
+ logger_1.logger.label('Nombre', workerInfo.name);
50
+ logger_1.logger.label('Tipo', workerInfo.type);
51
+ logger_1.logger.label('Estado', workerInfo.status);
52
+ logger_1.logger.label('Ejecuciones', `${workerInfo.executionCount || 0}`);
53
+ logger_1.logger.divider();
54
+ // Confirmacion
55
+ if (!options.force) {
56
+ const confirmed = await askConfirmation(`Eliminar worker "${name}"? Esta accion no se puede deshacer (y/N): `);
57
+ if (!confirmed) {
58
+ logger_1.logger.info('\n Operacion cancelada');
59
+ process.exit(0);
60
+ }
61
+ }
62
+ const deleteSpinner = (0, ui_1.createSpinner)(`Eliminando "${name}"...`);
63
+ deleteSpinner.start();
64
+ await api.delete(`/api/workers/${encodeURIComponent(name)}`);
65
+ deleteSpinner.succeed(`Worker "${name}" eliminado`);
66
+ console.log();
67
+ if (options.dev) {
68
+ logger_1.logger.warning('Ambiente: desarrollo');
69
+ }
70
+ }
71
+ catch (error) {
72
+ const message = error instanceof Error ? error.message : 'Error desconocido';
73
+ logger_1.logger.error(message);
74
+ process.exit(1);
75
+ }
76
+ });
77
+ function askConfirmation(question) {
78
+ return new Promise((resolve) => {
79
+ const rl = readline_1.default.createInterface({
80
+ input: process.stdin,
81
+ output: process.stdout,
82
+ });
83
+ rl.question(question, (answer) => {
84
+ rl.close();
85
+ resolve(answer.toLowerCase() === 'y');
86
+ });
87
+ });
88
+ }
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.secretCommand = void 0;
7
+ const commander_1 = require("commander");
8
+ const credentials_1 = require("../../utils/credentials");
9
+ const api_1 = require("../../utils/api");
10
+ const logger_1 = require("../../utils/logger");
11
+ const ui_1 = require("../../utils/ui");
12
+ const readline_1 = __importDefault(require("readline"));
13
+ // ── Comando padre: secret ───────────────────────────────────────────────────
14
+ exports.secretCommand = new commander_1.Command('secret')
15
+ .description('Gestionar secrets (variables de entorno) de los workers')
16
+ .addCommand(secretSetCommand())
17
+ .addCommand(secretListCommand())
18
+ .addCommand(secretRemoveCommand());
19
+ // ── secret set ──────────────────────────────────────────────────────────────
20
+ function secretSetCommand() {
21
+ return new commander_1.Command('set')
22
+ .description('Crear o actualizar un secret')
23
+ .argument('<key>', 'Nombre del secret (ej: STRIPE_API_KEY)')
24
+ .argument('<value>', 'Valor del secret')
25
+ .option('--dev', 'Usar ambiente de desarrollo', false)
26
+ .action(async (key, value, options) => {
27
+ try {
28
+ const credentials = await (0, credentials_1.getStoredCredentials)();
29
+ const api = (0, api_1.createApiClient)({
30
+ apiKey: credentials.apiKey,
31
+ workspace: credentials.workspace,
32
+ zone: credentials.zone,
33
+ dev: options.dev,
34
+ });
35
+ const spinner = (0, ui_1.createSpinner)(`Guardando secret "${key}"...`);
36
+ spinner.start();
37
+ await api.put('/api/workers/secrets', { key, value });
38
+ spinner.succeed(`Secret "${key}" guardado`);
39
+ logger_1.logger.dim(` Disponible en tus workers como plz.env.${key}`);
40
+ console.log();
41
+ if (options.dev) {
42
+ logger_1.logger.warning('Ambiente: desarrollo');
43
+ }
44
+ }
45
+ catch (error) {
46
+ const message = error instanceof Error ? error.message : 'Error desconocido';
47
+ logger_1.logger.error(message);
48
+ process.exit(1);
49
+ }
50
+ });
51
+ }
52
+ // ── secret list ─────────────────────────────────────────────────────────────
53
+ function secretListCommand() {
54
+ return new commander_1.Command('list')
55
+ .description('Lista todos los secrets del workspace (sin mostrar valores)')
56
+ .option('--dev', 'Usar ambiente de desarrollo', false)
57
+ .action(async (options) => {
58
+ try {
59
+ const credentials = await (0, credentials_1.getStoredCredentials)();
60
+ const api = (0, api_1.createApiClient)({
61
+ apiKey: credentials.apiKey,
62
+ workspace: credentials.workspace,
63
+ zone: credentials.zone,
64
+ dev: options.dev,
65
+ });
66
+ const spinner = (0, ui_1.createSpinner)('Obteniendo secrets...');
67
+ spinner.start();
68
+ const response = await api.get('/api/workers/secrets');
69
+ const secrets = response.data;
70
+ spinner.stop();
71
+ if (!secrets || secrets.length === 0) {
72
+ logger_1.logger.info('\n No hay secrets configurados');
73
+ logger_1.logger.dim(' Agrega uno: plazbot workers secret set MI_KEY mi_valor');
74
+ console.log();
75
+ return;
76
+ }
77
+ logger_1.logger.title(`Secrets (${secrets.length})`);
78
+ const rows = secrets.map(s => [
79
+ s.key,
80
+ ui_1.theme.muted('••••••••'),
81
+ (0, ui_1.formatDate)(s.updatedAt),
82
+ ]);
83
+ console.log((0, ui_1.createTable)(['Key', 'Valor', 'Actualizado'], rows));
84
+ console.log();
85
+ if (options.dev) {
86
+ logger_1.logger.warning('Ambiente: desarrollo');
87
+ }
88
+ }
89
+ catch (error) {
90
+ const message = error instanceof Error ? error.message : 'Error desconocido';
91
+ logger_1.logger.error(message);
92
+ process.exit(1);
93
+ }
94
+ });
95
+ }
96
+ // ── secret remove ───────────────────────────────────────────────────────────
97
+ function secretRemoveCommand() {
98
+ return new commander_1.Command('remove')
99
+ .description('Elimina un secret del workspace')
100
+ .argument('<key>', 'Nombre del secret a eliminar')
101
+ .option('-f, --force', 'Eliminar sin confirmacion', false)
102
+ .option('--dev', 'Usar ambiente de desarrollo', false)
103
+ .action(async (key, options) => {
104
+ try {
105
+ const credentials = await (0, credentials_1.getStoredCredentials)();
106
+ const api = (0, api_1.createApiClient)({
107
+ apiKey: credentials.apiKey,
108
+ workspace: credentials.workspace,
109
+ zone: credentials.zone,
110
+ dev: options.dev,
111
+ });
112
+ if (!options.force) {
113
+ const confirmed = await askConfirmation(` Eliminar secret "${key}"? (y/N): `);
114
+ if (!confirmed) {
115
+ logger_1.logger.info('\n Operacion cancelada');
116
+ process.exit(0);
117
+ }
118
+ }
119
+ const spinner = (0, ui_1.createSpinner)(`Eliminando secret "${key}"...`);
120
+ spinner.start();
121
+ await api.delete(`/api/workers/secrets/${encodeURIComponent(key)}`);
122
+ spinner.succeed(`Secret "${key}" eliminado`);
123
+ console.log();
124
+ if (options.dev) {
125
+ logger_1.logger.warning('Ambiente: desarrollo');
126
+ }
127
+ }
128
+ catch (error) {
129
+ if (error.response?.status === 404) {
130
+ logger_1.logger.error(`Secret "${key}" no encontrado`);
131
+ }
132
+ else {
133
+ const message = error instanceof Error ? error.message : 'Error desconocido';
134
+ logger_1.logger.error(message);
135
+ }
136
+ process.exit(1);
137
+ }
138
+ });
139
+ }
140
+ function askConfirmation(question) {
141
+ return new Promise((resolve) => {
142
+ const rl = readline_1.default.createInterface({
143
+ input: process.stdin,
144
+ output: process.stdout,
145
+ });
146
+ rl.question(question, (answer) => {
147
+ rl.close();
148
+ resolve(answer.toLowerCase() === 'y');
149
+ });
150
+ });
151
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.testCommand = void 0;
4
+ const commander_1 = require("commander");
5
+ const credentials_1 = require("../../utils/credentials");
6
+ const api_1 = require("../../utils/api");
7
+ const logger_1 = require("../../utils/logger");
8
+ const ui_1 = require("../../utils/ui");
9
+ exports.testCommand = new commander_1.Command('test')
10
+ .description('Ejecutar un worker manualmente para probarlo')
11
+ .argument('<name>', 'Nombre del worker a ejecutar')
12
+ .option('-p, --payload <json>', 'Payload JSON para el worker (ej: \'{"producto":"iPhone"}\')')
13
+ .option('-t, --type <type>', 'Tipo del worker (tool, worker, sync, schedule, webhook)')
14
+ .option('--contact <id>', 'ID del contacto (contexto para tools)')
15
+ .option('--agent <id>', 'ID del agente (contexto para tools)')
16
+ .option('--dev', 'Usar ambiente de desarrollo', false)
17
+ .action(async (name, options) => {
18
+ try {
19
+ const credentials = await (0, credentials_1.getStoredCredentials)();
20
+ const api = (0, api_1.createApiClient)({
21
+ apiKey: credentials.apiKey,
22
+ workspace: credentials.workspace,
23
+ zone: credentials.zone,
24
+ dev: options.dev,
25
+ });
26
+ // Parsear payload
27
+ let payload = {};
28
+ if (options.payload) {
29
+ try {
30
+ payload = JSON.parse(options.payload);
31
+ }
32
+ catch {
33
+ logger_1.logger.error('El payload no es JSON valido');
34
+ logger_1.logger.dim('Ejemplo: --payload \'{"producto":"iPhone 15"}\'');
35
+ process.exit(1);
36
+ }
37
+ }
38
+ logger_1.logger.title(`Ejecutando worker "${name}"`);
39
+ console.log();
40
+ if (Object.keys(payload).length > 0) {
41
+ logger_1.logger.label('Payload', JSON.stringify(payload, null, 2));
42
+ console.log();
43
+ }
44
+ const spinner = (0, ui_1.createSpinner)('Ejecutando...');
45
+ spinner.start();
46
+ const response = await api.post('/api/worker/execute', {
47
+ workerName: name,
48
+ type: options.type,
49
+ payload,
50
+ triggerSource: 'cli-test',
51
+ agentId: options.agent,
52
+ contactId: options.contact,
53
+ });
54
+ const data = response.data;
55
+ const duration = data.duration ?? 0;
56
+ spinner.stop();
57
+ if (data.success) {
58
+ logger_1.logger.success(`Ejecutado en ${duration}ms`);
59
+ }
60
+ else {
61
+ logger_1.logger.error(`Fallo en ${duration}ms`);
62
+ }
63
+ console.log();
64
+ // Mostrar resultado
65
+ if (data.result !== undefined && data.result !== null) {
66
+ logger_1.logger.label('Resultado', '');
67
+ const result = data.result;
68
+ // Si es un ToolResponse, mostrar formateado
69
+ if (typeof result === 'object' && 'result' in result) {
70
+ console.log();
71
+ logger_1.logger.label(' result', ui_1.theme.success(String(result.result)));
72
+ if (result.data) {
73
+ logger_1.logger.label(' data', JSON.stringify(result.data, null, 2));
74
+ }
75
+ if (Array.isArray(result.actions) && result.actions.length > 0) {
76
+ logger_1.logger.label(' actions', '');
77
+ for (const action of result.actions) {
78
+ const a = action;
79
+ logger_1.logger.dim(` - ${a.type}: ${a.value}${a.code ? ` (${a.code})` : ''}`);
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ // Resultado generico
85
+ console.log(JSON.stringify(result, null, 2));
86
+ }
87
+ }
88
+ // Mostrar error si hubo
89
+ if (data.error) {
90
+ console.log();
91
+ logger_1.logger.label('Error', ui_1.theme.error(data.error));
92
+ }
93
+ console.log();
94
+ if (options.dev) {
95
+ logger_1.logger.warning('Ambiente: desarrollo');
96
+ }
97
+ }
98
+ catch (error) {
99
+ if (error.response?.status === 404) {
100
+ logger_1.logger.error(`Worker "${name}" no encontrado o inactivo`);
101
+ logger_1.logger.dim('Verifica que el worker este desplegado con: plazbot workers list');
102
+ }
103
+ else {
104
+ const message = error.response?.data?.message || error.message || 'Error desconocido';
105
+ logger_1.logger.error(message);
106
+ }
107
+ process.exit(1);
108
+ }
109
+ });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });