gufi-cli 0.1.4 → 0.1.7
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/CLAUDE.md +30 -7
- package/dist/commands/env.d.ts +30 -0
- package/dist/commands/env.js +145 -0
- package/dist/index.js +98 -71
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -1419,6 +1419,29 @@ gufi automation calcular_stock -c 116 --edit
|
|
|
1419
1419
|
gufi automation calcular_stock -c 116 --file script.js
|
|
1420
1420
|
```
|
|
1421
1421
|
|
|
1422
|
+
### Environment Variables
|
|
1423
|
+
|
|
1424
|
+
```bash
|
|
1425
|
+
# Ver variables de entorno de la company
|
|
1426
|
+
gufi env
|
|
1427
|
+
|
|
1428
|
+
# Crear/actualizar variable
|
|
1429
|
+
gufi env:set STRIPE_API_KEY sk-live-xxx
|
|
1430
|
+
|
|
1431
|
+
# Eliminar variable
|
|
1432
|
+
gufi env:delete STRIPE_API_KEY
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
### Schema (Estructura de Tablas)
|
|
1436
|
+
|
|
1437
|
+
```bash
|
|
1438
|
+
# Ver todas las tablas de la company
|
|
1439
|
+
gufi schema
|
|
1440
|
+
|
|
1441
|
+
# Filtrar por módulo
|
|
1442
|
+
gufi schema -m 360
|
|
1443
|
+
```
|
|
1444
|
+
|
|
1422
1445
|
### Row CRUD (Datos de Tablas)
|
|
1423
1446
|
|
|
1424
1447
|
```bash
|
|
@@ -1452,23 +1475,23 @@ gufi rows:create m360_t16192 --file datos.json
|
|
|
1452
1475
|
### Desarrollo de Views
|
|
1453
1476
|
|
|
1454
1477
|
```bash
|
|
1455
|
-
# Ver tus
|
|
1456
|
-
gufi
|
|
1478
|
+
# Ver tus views del Marketplace
|
|
1479
|
+
gufi views
|
|
1457
1480
|
|
|
1458
1481
|
# Descargar view para editar localmente
|
|
1459
|
-
gufi pull "Stock Overview"
|
|
1482
|
+
gufi view:pull "Stock Overview"
|
|
1460
1483
|
|
|
1461
1484
|
# Auto-sync al guardar archivos
|
|
1462
|
-
gufi watch
|
|
1485
|
+
gufi view:watch
|
|
1463
1486
|
|
|
1464
1487
|
# Ver console.log del LivePreview
|
|
1465
|
-
gufi logs
|
|
1488
|
+
gufi view:logs
|
|
1466
1489
|
|
|
1467
1490
|
# Subir cambios manualmente
|
|
1468
|
-
gufi push
|
|
1491
|
+
gufi view:push
|
|
1469
1492
|
|
|
1470
1493
|
# Ver estado de sincronización
|
|
1471
|
-
gufi status
|
|
1494
|
+
gufi view:status
|
|
1472
1495
|
```
|
|
1473
1496
|
|
|
1474
1497
|
### Opciones Globales
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gufi env - Manage company environment variables
|
|
3
|
+
* gufi schema - View company table structure
|
|
4
|
+
*/
|
|
5
|
+
interface EnvOptions {
|
|
6
|
+
company?: string;
|
|
7
|
+
set?: string;
|
|
8
|
+
delete?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface SchemaOptions {
|
|
11
|
+
company?: string;
|
|
12
|
+
module?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* gufi env - List environment variables
|
|
16
|
+
*/
|
|
17
|
+
export declare function envListCommand(options: EnvOptions): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* gufi env:set <key> <value> - Set an environment variable
|
|
20
|
+
*/
|
|
21
|
+
export declare function envSetCommand(key: string, value: string, options: EnvOptions): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* gufi env:delete <key> - Delete an environment variable
|
|
24
|
+
*/
|
|
25
|
+
export declare function envDeleteCommand(key: string, options: EnvOptions): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* gufi schema - View company table structure
|
|
28
|
+
*/
|
|
29
|
+
export declare function schemaCommand(options: SchemaOptions): Promise<void>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gufi env - Manage company environment variables
|
|
3
|
+
* gufi schema - View company table structure
|
|
4
|
+
*/
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import ora from "ora";
|
|
7
|
+
import { getToken, getApiUrl } from "../lib/config.js";
|
|
8
|
+
async function apiRequest(endpoint, options = {}) {
|
|
9
|
+
const token = getToken();
|
|
10
|
+
if (!token) {
|
|
11
|
+
throw new Error("No estás logueado. Ejecuta: gufi login");
|
|
12
|
+
}
|
|
13
|
+
const url = `${getApiUrl()}${endpoint}`;
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
...options,
|
|
16
|
+
headers: {
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
Authorization: `Bearer ${token}`,
|
|
19
|
+
"X-Client": "cli",
|
|
20
|
+
...options.headers,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
const text = await response.text();
|
|
25
|
+
throw new Error(`API Error ${response.status}: ${text}`);
|
|
26
|
+
}
|
|
27
|
+
return response.json();
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* gufi env - List environment variables
|
|
31
|
+
*/
|
|
32
|
+
export async function envListCommand(options) {
|
|
33
|
+
const spinner = ora("Cargando variables de entorno...").start();
|
|
34
|
+
try {
|
|
35
|
+
const data = await apiRequest("/api/cli/env");
|
|
36
|
+
spinner.stop();
|
|
37
|
+
console.log(chalk.magenta("\n 🔐 Variables de Entorno\n"));
|
|
38
|
+
if (!data || data.length === 0) {
|
|
39
|
+
console.log(chalk.gray(" No hay variables configuradas\n"));
|
|
40
|
+
console.log(chalk.gray(" Usa: gufi env:set <KEY> <VALUE>\n"));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Show as table
|
|
44
|
+
const maxKeyLen = Math.max(...data.map((v) => v.key.length), 10);
|
|
45
|
+
console.log(chalk.gray(" " + "KEY".padEnd(maxKeyLen + 2) + "VALUE"));
|
|
46
|
+
console.log(chalk.gray(" " + "─".repeat(maxKeyLen + 20)));
|
|
47
|
+
for (const env of data) {
|
|
48
|
+
const maskedValue = env.is_secret
|
|
49
|
+
? "••••••••"
|
|
50
|
+
: (env.value?.substring(0, 30) + (env.value?.length > 30 ? "..." : ""));
|
|
51
|
+
console.log(" " +
|
|
52
|
+
chalk.cyan(env.key.padEnd(maxKeyLen + 2)) +
|
|
53
|
+
chalk.white(maskedValue));
|
|
54
|
+
}
|
|
55
|
+
console.log(chalk.gray(`\n Total: ${data.length} variables\n`));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
spinner.fail(chalk.red(error.message));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* gufi env:set <key> <value> - Set an environment variable
|
|
64
|
+
*/
|
|
65
|
+
export async function envSetCommand(key, value, options) {
|
|
66
|
+
const spinner = ora(`Guardando ${key}...`).start();
|
|
67
|
+
try {
|
|
68
|
+
await apiRequest("/api/cli/env", {
|
|
69
|
+
method: "POST",
|
|
70
|
+
body: JSON.stringify({ key, value }),
|
|
71
|
+
});
|
|
72
|
+
spinner.succeed(chalk.green(`${key} guardada`));
|
|
73
|
+
console.log();
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
spinner.fail(chalk.red(error.message));
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* gufi env:delete <key> - Delete an environment variable
|
|
82
|
+
*/
|
|
83
|
+
export async function envDeleteCommand(key, options) {
|
|
84
|
+
const spinner = ora(`Eliminando ${key}...`).start();
|
|
85
|
+
try {
|
|
86
|
+
await apiRequest(`/api/cli/env/${encodeURIComponent(key)}`, {
|
|
87
|
+
method: "DELETE",
|
|
88
|
+
});
|
|
89
|
+
spinner.succeed(chalk.green(`${key} eliminada`));
|
|
90
|
+
console.log();
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
spinner.fail(chalk.red(error.message));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* gufi schema - View company table structure
|
|
99
|
+
*/
|
|
100
|
+
export async function schemaCommand(options) {
|
|
101
|
+
const spinner = ora("Cargando schema...").start();
|
|
102
|
+
try {
|
|
103
|
+
const data = await apiRequest("/api/cli/schema");
|
|
104
|
+
spinner.stop();
|
|
105
|
+
console.log(chalk.magenta("\n 📊 Schema de la Company\n"));
|
|
106
|
+
if (!data.modules || data.modules.length === 0) {
|
|
107
|
+
console.log(chalk.gray(" No hay módulos\n"));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
for (const module of data.modules) {
|
|
111
|
+
// Filter by module if specified
|
|
112
|
+
if (options.module && module.id !== parseInt(options.module)) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
console.log(chalk.cyan(` 📦 ${module.name}`) +
|
|
116
|
+
chalk.gray(` (ID: ${module.id})`));
|
|
117
|
+
if (module.entities && module.entities.length > 0) {
|
|
118
|
+
for (const entity of module.entities) {
|
|
119
|
+
const tableName = `m${module.id}_t${entity.id}`;
|
|
120
|
+
console.log(chalk.white(` └─ ${entity.name}`) +
|
|
121
|
+
chalk.gray(` → ${tableName}`));
|
|
122
|
+
// Show fields if available
|
|
123
|
+
if (entity.fields && entity.fields.length > 0) {
|
|
124
|
+
const fieldList = entity.fields
|
|
125
|
+
.slice(0, 5)
|
|
126
|
+
.map((f) => f.name)
|
|
127
|
+
.join(", ");
|
|
128
|
+
const more = entity.fields.length > 5
|
|
129
|
+
? ` +${entity.fields.length - 5} más`
|
|
130
|
+
: "";
|
|
131
|
+
console.log(chalk.gray(` campos: ${fieldList}${more}`));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
console.log();
|
|
136
|
+
}
|
|
137
|
+
// Summary
|
|
138
|
+
const totalTables = data.modules.reduce((acc, m) => acc + (m.entities?.length || 0), 0);
|
|
139
|
+
console.log(chalk.gray(` ${data.modules.length} módulos, ${totalTables} tablas\n`));
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
spinner.fail(chalk.red(error.message));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -39,130 +39,157 @@ import { listCommand } from "./commands/list.js";
|
|
|
39
39
|
import { logsCommand } from "./commands/logs.js";
|
|
40
40
|
import { companiesCommand, modulesCommand, moduleCommand, moduleUpdateCommand, companyCreateCommand, automationsCommand, automationCommand, } from "./commands/companies.js";
|
|
41
41
|
import { rowsListCommand, rowGetCommand, rowCreateCommand, rowUpdateCommand, rowDeleteCommand, rowDuplicateCommand, rowsBulkCreateCommand, } from "./commands/rows.js";
|
|
42
|
+
import { envListCommand, envSetCommand, envDeleteCommand, schemaCommand, } from "./commands/env.js";
|
|
42
43
|
const program = new Command();
|
|
43
44
|
program
|
|
44
45
|
.name("gufi")
|
|
45
|
-
.description("Gufi
|
|
46
|
-
.version("0.1.
|
|
47
|
-
//
|
|
46
|
+
.description("🟣 Gufi CLI - Desarrolla módulos, vistas y automations")
|
|
47
|
+
.version("0.1.7");
|
|
48
|
+
// ════════════════════════════════════════════════════════════════════
|
|
49
|
+
// 🔐 Auth
|
|
50
|
+
// ════════════════════════════════════════════════════════════════════
|
|
48
51
|
program
|
|
49
52
|
.command("login")
|
|
50
|
-
.description("
|
|
51
|
-
.option("--api <url>", "
|
|
53
|
+
.description("Iniciar sesión en Gufi")
|
|
54
|
+
.option("--api <url>", "URL de API personalizada")
|
|
52
55
|
.action(loginCommand);
|
|
53
56
|
program
|
|
54
57
|
.command("logout")
|
|
55
|
-
.description("
|
|
58
|
+
.description("Cerrar sesión")
|
|
56
59
|
.action(logoutCommand);
|
|
57
60
|
program
|
|
58
61
|
.command("whoami")
|
|
59
|
-
.description("
|
|
62
|
+
.description("Ver usuario actual")
|
|
60
63
|
.action(whoamiCommand);
|
|
61
|
-
// Sync commands
|
|
62
|
-
program
|
|
63
|
-
.command("pull [view]")
|
|
64
|
-
.description("Download view files from Gufi")
|
|
65
|
-
.action(pullCommand);
|
|
66
|
-
program
|
|
67
|
-
.command("push")
|
|
68
|
-
.description("Upload local changes to Gufi")
|
|
69
|
-
.action(pushCommand);
|
|
70
|
-
program
|
|
71
|
-
.command("watch [dir]")
|
|
72
|
-
.description("Watch for file changes and auto-sync")
|
|
73
|
-
.action(watchCommand);
|
|
74
|
-
program
|
|
75
|
-
.command("status")
|
|
76
|
-
.description("Show sync status")
|
|
77
|
-
.action(statusCommand);
|
|
78
|
-
program
|
|
79
|
-
.command("list")
|
|
80
|
-
.alias("ls")
|
|
81
|
-
.description("List your packages and views")
|
|
82
|
-
.action(listCommand);
|
|
83
|
-
program
|
|
84
|
-
.command("logs [dir]")
|
|
85
|
-
.description("Stream console logs from LivePreview in real-time")
|
|
86
|
-
.action(logsCommand);
|
|
87
64
|
// ════════════════════════════════════════════════════════════════════
|
|
88
|
-
//
|
|
65
|
+
// 🏢 Companies & Modules
|
|
89
66
|
// ════════════════════════════════════════════════════════════════════
|
|
90
67
|
program
|
|
91
68
|
.command("companies")
|
|
92
|
-
.description("
|
|
69
|
+
.description("Ver mis companies")
|
|
93
70
|
.action(companiesCommand);
|
|
71
|
+
program
|
|
72
|
+
.command("company:create <name>")
|
|
73
|
+
.description("Crear nueva company")
|
|
74
|
+
.action(companyCreateCommand);
|
|
94
75
|
program
|
|
95
76
|
.command("modules <company_id>")
|
|
96
|
-
.description("
|
|
77
|
+
.description("Ver módulos de una company")
|
|
97
78
|
.action(modulesCommand);
|
|
79
|
+
program
|
|
80
|
+
.command("schema")
|
|
81
|
+
.description("Ver estructura de tablas de la company")
|
|
82
|
+
.option("-m, --module <id>", "Filtrar por módulo")
|
|
83
|
+
.action(schemaCommand);
|
|
98
84
|
program
|
|
99
85
|
.command("module <module_id>")
|
|
100
|
-
.description("
|
|
101
|
-
.option("-e, --edit", "
|
|
102
|
-
.option("-c, --company <id>", "
|
|
103
|
-
.option("-f, --file <path>", "
|
|
86
|
+
.description("Ver/editar JSON de un módulo")
|
|
87
|
+
.option("-e, --edit", "Abrir en editor")
|
|
88
|
+
.option("-c, --company <id>", "ID de company")
|
|
89
|
+
.option("-f, --file <path>", "Exportar a archivo")
|
|
104
90
|
.action(moduleCommand);
|
|
105
91
|
program
|
|
106
92
|
.command("module:update <module_id> <json_file>")
|
|
107
|
-
.description("
|
|
108
|
-
.option("-c, --company <id>", "
|
|
109
|
-
.option("--dry-run", "
|
|
93
|
+
.description("Actualizar módulo desde archivo JSON")
|
|
94
|
+
.option("-c, --company <id>", "ID de company")
|
|
95
|
+
.option("--dry-run", "Validar sin guardar")
|
|
110
96
|
.action(moduleUpdateCommand);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
.action(companyCreateCommand);
|
|
97
|
+
// ════════════════════════════════════════════════════════════════════
|
|
98
|
+
// ⚡ Automations
|
|
99
|
+
// ════════════════════════════════════════════════════════════════════
|
|
115
100
|
program
|
|
116
101
|
.command("automations")
|
|
117
|
-
.description("
|
|
118
|
-
.option("-c, --company <id>", "
|
|
102
|
+
.description("Ver scripts de automation")
|
|
103
|
+
.option("-c, --company <id>", "ID de company")
|
|
119
104
|
.action(automationsCommand);
|
|
120
105
|
program
|
|
121
106
|
.command("automation <name>")
|
|
122
|
-
.description("
|
|
123
|
-
.option("-e, --edit", "
|
|
124
|
-
.option("-c, --company <id>", "
|
|
125
|
-
.option("-f, --file <path>", "
|
|
107
|
+
.description("Ver/editar código de automation")
|
|
108
|
+
.option("-e, --edit", "Abrir en editor")
|
|
109
|
+
.option("-c, --company <id>", "ID de company")
|
|
110
|
+
.option("-f, --file <path>", "Exportar a archivo")
|
|
126
111
|
.action(automationCommand);
|
|
127
112
|
// ════════════════════════════════════════════════════════════════════
|
|
128
|
-
//
|
|
113
|
+
// 🔐 Environment Variables
|
|
114
|
+
// ════════════════════════════════════════════════════════════════════
|
|
115
|
+
program
|
|
116
|
+
.command("env")
|
|
117
|
+
.description("Ver variables de entorno de la company")
|
|
118
|
+
.action(envListCommand);
|
|
119
|
+
program
|
|
120
|
+
.command("env:set <key> <value>")
|
|
121
|
+
.description("Crear/actualizar variable de entorno")
|
|
122
|
+
.action(envSetCommand);
|
|
123
|
+
program
|
|
124
|
+
.command("env:delete <key>")
|
|
125
|
+
.description("Eliminar variable de entorno")
|
|
126
|
+
.action(envDeleteCommand);
|
|
127
|
+
// ════════════════════════════════════════════════════════════════════
|
|
128
|
+
// 📊 Row CRUD - Datos de tablas
|
|
129
129
|
// ════════════════════════════════════════════════════════════════════
|
|
130
130
|
program
|
|
131
131
|
.command("rows <table>")
|
|
132
|
-
.description("
|
|
133
|
-
.option("-l, --limit <n>", "
|
|
134
|
-
.option("-o, --offset <n>", "
|
|
135
|
-
.option("-s, --sort <field>", "
|
|
136
|
-
.option("--order <dir>", "
|
|
137
|
-
.option("-f, --filter <expr>", "
|
|
132
|
+
.description("Listar registros (ej: gufi rows m360_t16192)")
|
|
133
|
+
.option("-l, --limit <n>", "Cantidad", "20")
|
|
134
|
+
.option("-o, --offset <n>", "Desde", "0")
|
|
135
|
+
.option("-s, --sort <field>", "Ordenar por", "id")
|
|
136
|
+
.option("--order <dir>", "ASC/DESC", "DESC")
|
|
137
|
+
.option("-f, --filter <expr>", "Filtro (campo=valor)")
|
|
138
138
|
.action(rowsListCommand);
|
|
139
139
|
program
|
|
140
140
|
.command("row <table> <id>")
|
|
141
|
-
.description("
|
|
141
|
+
.description("Ver un registro por ID")
|
|
142
142
|
.action(rowGetCommand);
|
|
143
143
|
program
|
|
144
144
|
.command("row:create <table>")
|
|
145
|
-
.description("
|
|
146
|
-
.option("-d, --data <json>", "JSON
|
|
147
|
-
.option("-f, --file <path>", "JSON
|
|
145
|
+
.description("Crear registro")
|
|
146
|
+
.option("-d, --data <json>", "JSON con datos")
|
|
147
|
+
.option("-f, --file <path>", "Archivo JSON")
|
|
148
148
|
.action(rowCreateCommand);
|
|
149
149
|
program
|
|
150
150
|
.command("row:update <table> <id>")
|
|
151
|
-
.description("
|
|
152
|
-
.option("-d, --data <json>", "JSON
|
|
153
|
-
.option("-f, --file <path>", "JSON
|
|
151
|
+
.description("Actualizar registro")
|
|
152
|
+
.option("-d, --data <json>", "JSON con cambios")
|
|
153
|
+
.option("-f, --file <path>", "Archivo JSON")
|
|
154
154
|
.action(rowUpdateCommand);
|
|
155
155
|
program
|
|
156
156
|
.command("row:delete <table> <id>")
|
|
157
|
-
.description("
|
|
157
|
+
.description("Eliminar registro")
|
|
158
158
|
.action(rowDeleteCommand);
|
|
159
159
|
program
|
|
160
160
|
.command("row:duplicate <table> <id>")
|
|
161
|
-
.description("
|
|
161
|
+
.description("Duplicar registro existente")
|
|
162
162
|
.action(rowDuplicateCommand);
|
|
163
163
|
program
|
|
164
164
|
.command("rows:create <table>")
|
|
165
|
-
.description("
|
|
166
|
-
.option("-f, --file <path>", "
|
|
165
|
+
.description("Crear múltiples registros desde JSON")
|
|
166
|
+
.option("-f, --file <path>", "Archivo con array de objetos")
|
|
167
167
|
.action(rowsBulkCreateCommand);
|
|
168
|
+
// ════════════════════════════════════════════════════════════════════
|
|
169
|
+
// 🎨 Views (Marketplace) - Desarrollo local
|
|
170
|
+
// ════════════════════════════════════════════════════════════════════
|
|
171
|
+
program
|
|
172
|
+
.command("views")
|
|
173
|
+
.description("Ver mis views del Marketplace")
|
|
174
|
+
.action(listCommand);
|
|
175
|
+
program
|
|
176
|
+
.command("view:pull [name]")
|
|
177
|
+
.description("Descargar vista para editar localmente")
|
|
178
|
+
.action(pullCommand);
|
|
179
|
+
program
|
|
180
|
+
.command("view:push")
|
|
181
|
+
.description("Subir cambios locales a Gufi")
|
|
182
|
+
.action(pushCommand);
|
|
183
|
+
program
|
|
184
|
+
.command("view:watch [dir]")
|
|
185
|
+
.description("Auto-sync al guardar archivos")
|
|
186
|
+
.action(watchCommand);
|
|
187
|
+
program
|
|
188
|
+
.command("view:status")
|
|
189
|
+
.description("Ver estado de sincronización")
|
|
190
|
+
.action(statusCommand);
|
|
191
|
+
program
|
|
192
|
+
.command("view:logs [dir]")
|
|
193
|
+
.description("Ver console.log del LivePreview")
|
|
194
|
+
.action(logsCommand);
|
|
168
195
|
program.parse();
|