shilo-cli 0.6.0 → 0.8.0

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/bin/shilo.js CHANGED
@@ -1,165 +1,197 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const { parseArgs } = require('../src/args');
5
- const ui = require('../src/ui');
6
-
7
- const VERSION = require('../package.json').version;
8
-
9
- const HELP = `
10
- ${ui.c.bold('shilo')} — sube carpetas locales a repositorios de Shilo.
11
-
12
- ${ui.c.bold('Uso:')}
13
- shilo <comando> [opciones]
14
-
15
- ${ui.c.bold('Comandos:')}
16
- login Inicia sesión y guarda credenciales cifradas (~/.shilo/config.json).
17
- whoami Muestra la sesión activa.
18
- logout Cierra sesión (borra credenciales locales).
19
- init [carpeta] Ata una carpeta a un repo de Shilo (--project <uuid>).
20
- status [carpeta] Compara local vs remoto sin bajar nada (¿estoy desactualizado?).
21
- push [carpeta] Sube una carpeta al repo de Shilo (crea/actualiza + commit).
22
- pull [carpeta] Baja un repo de Shilo a una carpeta local (deja .shilo.json).
23
- log [archivo] Historial de commits del proyecto o de un archivo.
24
- diff [archivo] Diferencias entre tu copia local y la remota.
25
- help Muestra esta ayuda.
26
-
27
- ${ui.c.bold('Opciones de login:')}
28
- --email <e> Email (si se omite, se pregunta).
29
- --password <p> Contraseña (si se omite, se pregunta oculta).
30
- --token <pat> Token de acceso personal (en vez de email + contraseña).
31
- --token - Lee el token de stdin (no queda en el historial del shell).
32
- --base-url <url> Servidor Shilo (default: https://www.shilo.city).
33
- ${ui.c.dim('También se lee de la variable de entorno SHILO_TOKEN.')}
34
-
35
- ${ui.c.bold('Opciones de init:')}
36
- --project <uuid> Id del proyecto de Shilo (requerido).
37
- --token <pat> Token de acceso personal (evita el "login" previo; o SHILO_TOKEN).
38
- --push Sube la carpeta apenas queda atada (pregunta, salvo --yes).
39
- --pull Baja la carpeta apenas queda atada (pregunta, salvo --yes).
40
- --base-url <url> Servidor Shilo.
41
- --force No verifica acceso ni pregunta antes de sobrescribir.
42
-
43
- ${ui.c.bold('Opciones de status:')}
44
- --project <uuid> Proyecto a comparar (pisa el .shilo.json de la carpeta).
45
- --short Sólo las rutas, sin autor ni fecha.
46
- --json Salida JSON (para scripts).
47
- --base-url <url> Servidor Shilo.
48
- ${ui.c.dim('Exit code 2 = el remoto tiene cambios que no tenés.')}
49
-
50
- ${ui.c.bold('Opciones de push:')}
51
- --project <uuid> Proyecto destino (pisa el .shilo.json de la carpeta).
52
- -m, --message <m> Mensaje del commit.
53
- --card <id> Id de tarjeta/tablero; se agrega al mensaje como [card: id].
54
- --dry-run Muestra qué haría (y quién tocó cada archivo), sin subir nada.
55
- --yes No pide confirmación.
56
- --allow-secrets Sube igual los archivos donde se detectaron posibles secretos.
57
- --concurrency <n> Requests en paralelo (1-32, default 8; o SHILO_CONCURRENCY).
58
- --no-index Ignora el índice local (.shilo/index.json) y recompara todo.
59
- --verbose Lista archivo por archivo en vez de resumir.
60
- --base-url <url> Servidor Shilo.
61
- ${ui.c.dim('Respeta .gitignore y .shiloignore, incluidos los de subcarpetas.')}
62
-
63
- ${ui.c.bold('Opciones de pull:')}
64
- --project <uuid> Proyecto origen (pisa el .shilo.json de la carpeta).
65
- --dry-run Muestra qué cambiaría localmente, sin bajar nada.
66
- --yes No pide confirmación.
67
- --force Sobrescribe también los archivos locales que difieren.
68
- --base-url <url> Servidor Shilo.
69
-
70
- ${ui.c.bold('Opciones de log:')}
71
- -n <N> Cuántos commits mirar (1-100, default 20).
72
- --files Lista los archivos de cada commit.
73
- --json Salida JSON.
74
- --project <uuid> Proyecto (pisa el .shilo.json de la carpeta).
75
-
76
- ${ui.c.bold('Opciones de diff:')}
77
- --context <n> Líneas de contexto (0-20, default 3).
78
- --stat Sólo el resumen de líneas agregadas/quitadas.
79
- --project <uuid> Proyecto (pisa el .shilo.json de la carpeta).
80
- ${ui.c.dim('Sin archivo, resume todo lo que difiere. Exit code 1 = hay diferencias.')}
81
-
82
- ${ui.c.bold('Globales:')}
83
- -v, --version Versión del CLI.
84
- -h, --help Ayuda.
85
- `;
86
-
87
- const COMMANDS = {
88
- login: () => require('../src/commands/login'),
89
- whoami: () => require('../src/commands/whoami'),
90
- logout: () => require('../src/commands/logout'),
91
- init: () => require('../src/commands/init'),
92
- push: () => require('../src/commands/push'),
93
- pull: () => require('../src/commands/pull'),
94
- status: () => require('../src/commands/status'),
95
- log: () => require('../src/commands/log'),
96
- diff: () => require('../src/commands/diff'),
97
- };
98
-
99
- async function main() {
100
- const argv = process.argv.slice(2);
101
- const parsed = parseArgs(argv, {
102
- // 'push' tiene que estar acá: la lista de booleanos es global, y sin
103
- // registrarlo `shilo init --project X --push .` se comería el `.` como
104
- // valor de --push, perdiendo el positional de la carpeta.
105
- booleans: [
106
- 'help', 'version', 'h', 'v', 'dry-run', 'yes', 'force', 'push', 'pull',
107
- 'json', 'short', 'stat', 'files', 'allow-secrets', 'no-index', 'verbose',
108
- ],
109
- aliases: { h: 'help', v: 'version', m: 'message' },
110
- });
111
-
112
- const cmd = parsed._[0];
113
-
114
- if (parsed.version && !cmd) {
115
- console.log(VERSION);
116
- return 0;
117
- }
118
- if (!cmd || cmd === 'help' || (parsed.help && !cmd)) {
119
- console.log(HELP);
120
- return 0;
121
- }
122
-
123
- const loader = COMMANDS[cmd];
124
- if (!loader) {
125
- ui.error(`Comando desconocido: "${cmd}".`);
126
- console.log(HELP);
127
- return 1;
128
- }
129
-
130
- if (parsed.help) {
131
- console.log(HELP);
132
- return 0;
133
- }
134
-
135
- // Los positionals del comando (sin el nombre del comando).
136
- const commandArgs = { ...parsed, _: parsed._.slice(1) };
137
- const handler = loader();
138
- return handler(commandArgs);
139
- }
140
-
141
- /**
142
- * Termina con `code` sin llamar a `process.exit()` de inmediato.
143
- *
144
- * Llamarlo justo después de un `fetch` aborta el proceso en Windows con
145
- * `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)`: libuv cierra dos
146
- * veces el handle del pool de conexiones de undici. El comando ya imprimió todo
147
- * y hasta guardó en disco, pero el shell recibe 127 en vez de 0 — o sea que
148
- * cualquier script o CI que chequee el resultado de `shilo push` lee basura.
149
- *
150
- * Dejar que el loop se vacíe solo evita el crash y no cuesta nada: las conexiones
151
- * de undici no tienen ref, así que el proceso sale igual de rápido. El timer es
152
- * el paracaídas por si algo queda colgado; sin ref, no mantiene vivo al proceso
153
- * por sí mismo, sólo actúa si ya lo estaba.
154
- */
155
- function finish(code) {
156
- process.exitCode = code;
157
- setTimeout(() => process.exit(code), 5000).unref();
158
- }
159
-
160
- main()
161
- .then((code) => finish(typeof code === 'number' ? code : 0))
162
- .catch((err) => {
163
- ui.error(err && err.message ? err.message : String(err));
164
- finish(1);
165
- });
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { parseArgs } = require('../src/args');
5
+ const ui = require('../src/ui');
6
+
7
+ const VERSION = require('../package.json').version;
8
+
9
+ const HELP = `
10
+ ${ui.c.bold('shilo')} — sube carpetas locales a repositorios de Shilo.
11
+
12
+ ${ui.c.bold('Uso:')}
13
+ shilo <comando> [opciones]
14
+
15
+ ${ui.c.bold('Comandos:')}
16
+ login Inicia sesión y guarda credenciales cifradas (~/.shilo/config.json).
17
+ whoami Muestra la sesión activa.
18
+ logout Cierra sesión (borra credenciales locales).
19
+ init [carpeta] Ata una carpeta a un repo de Shilo (--project <uuid>).
20
+ status [carpeta] Compara local vs remoto sin bajar nada (¿estoy desactualizado?).
21
+ push [carpeta] Sube una carpeta al repo de Shilo (crea/actualiza + commit).
22
+ pull [carpeta] Baja un repo de Shilo a una carpeta local (deja .shilo.json).
23
+ log [archivo] Historial de commits del proyecto o de un archivo.
24
+ diff [archivo] Diferencias entre tu copia local y la remota.
25
+ review [versión] Quién revisó una versión, o dejar tu revisión.
26
+ export <carpeta> Escribe la historia del proyecto como un repositorio Git.
27
+ help Muestra esta ayuda.
28
+
29
+ ${ui.c.bold('Opciones de login:')}
30
+ --email <e> Email (si se omite, se pregunta).
31
+ --password <p> Contraseña (si se omite, se pregunta oculta).
32
+ --token <pat> Token de acceso personal (en vez de email + contraseña).
33
+ --token - Lee el token de stdin (no queda en el historial del shell).
34
+ --base-url <url> Servidor Shilo (default: https://www.shilo.city).
35
+ ${ui.c.dim('También se lee de la variable de entorno SHILO_TOKEN.')}
36
+
37
+ ${ui.c.bold('Opciones de init:')}
38
+ --project <uuid> Id del proyecto de Shilo (requerido).
39
+ --token <pat> Token de acceso personal (evita el "login" previo; o SHILO_TOKEN).
40
+ --push Sube la carpeta apenas queda atada (pregunta, salvo --yes).
41
+ --pull Baja la carpeta apenas queda atada (pregunta, salvo --yes).
42
+ --base-url <url> Servidor Shilo.
43
+ --force No verifica acceso ni pregunta antes de sobrescribir.
44
+
45
+ ${ui.c.bold('Opciones de status:')}
46
+ --project <uuid> Proyecto a comparar (pisa el .shilo.json de la carpeta).
47
+ --short Sólo las rutas, sin autor ni fecha.
48
+ --show-ignored Lista los archivos del remoto ignorados localmente.
49
+ --json Salida JSON (para scripts).
50
+ --base-url <url> Servidor Shilo.
51
+ ${ui.c.dim('Exit code 2 = el remoto tiene cambios que no tenés.')}
52
+
53
+ ${ui.c.bold('Opciones de push:')}
54
+ --project <uuid> Proyecto destino (pisa el .shilo.json de la carpeta).
55
+ -m, --message <m> Mensaje del commit.
56
+ --only <ruta> Sube sólo esa ruta (archivo o carpeta). Repetible.
57
+ --card <id> Id de tarjeta/tablero; se agrega al mensaje como [card: id].
58
+ --agent <nombre> Declara que lo escribió un agente (ej: claude-code).
59
+ --model <modelo> Qué modelo, junto con --agent.
60
+ --session <id> Id de la conversación, para agrupar guardados.
61
+ --prompt <texto> El pedido que originó el cambio; se guarda con el cambio.
62
+ --prompt-file <f> Igual, leyendo el pedido de un archivo (máx. 64 KB).
63
+ --dry-run Muestra qué haría (y quién tocó cada archivo), sin subir nada.
64
+ --yes No pide confirmación.
65
+ --allow-secrets Sube igual los archivos donde se detectaron posibles secretos.
66
+ --concurrency <n> Requests en paralelo (1-32, default 8; o SHILO_CONCURRENCY).
67
+ --no-index Ignora el índice local (.shilo/index.json) y recompara todo.
68
+ --verbose Lista archivo por archivo en vez de resumir.
69
+ --base-url <url> Servidor Shilo.
70
+ ${ui.c.dim('Respeta .gitignore y .shiloignore, incluidos los de subcarpetas.')}
71
+
72
+ ${ui.c.bold('Opciones de pull:')}
73
+ --project <uuid> Proyecto origen (pisa el .shilo.json de la carpeta).
74
+ --dry-run Muestra qué cambiaría localmente, sin bajar nada.
75
+ --yes No pide confirmación.
76
+ --force Sobrescribe también los archivos locales que difieren.
77
+ --include-ignored Baja también lo que está ignorado localmente.
78
+ --base-url <url> Servidor Shilo.
79
+ ${ui.c.dim('Con --force, la versión local pisada queda en .shilo/respaldo/<fecha>/.')}
80
+
81
+ ${ui.c.bold('Opciones de log:')}
82
+ -n <N> Cuántos commits mirar (1-100, default 20).
83
+ --files Lista los archivos de cada commit.
84
+ --json Salida JSON.
85
+ --project <uuid> Proyecto (pisa el .shilo.json de la carpeta).
86
+
87
+ ${ui.c.bold('Opciones de diff:')}
88
+ --context <n> Líneas de contexto (0-20, default 3).
89
+ --stat Sólo el resumen de líneas agregadas/quitadas.
90
+ --project <uuid> Proyecto (pisa el .shilo.json de la carpeta).
91
+ ${ui.c.dim('Sin archivo, resume todo lo que difiere. Exit code 1 = hay diferencias.')}
92
+
93
+ ${ui.c.bold('Opciones de review:')}
94
+ --aprobado Deja constancia de que la miraste y está bien.
95
+ --reparos Está bien con reparos (requiere -m).
96
+ --rechazado No debería quedar así (requiere -m).
97
+ -m, --message <m> La nota de la revisión.
98
+ --json Salida JSON.
99
+ --project <uuid> Proyecto (pisa el .shilo.json de la carpeta).
100
+ ${ui.c.dim('Sin versión es la actual; si no, lo que imprime "shilo log" (7+ caracteres).')}
101
+
102
+ ${ui.c.bold('Opciones de export:')}
103
+ --project <uuid> Proyecto (si no, el de la exportación anterior o el .shilo.json).
104
+ --json Informe en JSON.
105
+ --base-url <url> Servidor Shilo.
106
+ ${ui.c.dim('La primera vez, a una carpeta vacía; después sólo trae lo nuevo. Público sin sesión.')}
107
+
108
+ ${ui.c.bold('Globales:')}
109
+ -v, --version Versión del CLI.
110
+ -h, --help Ayuda.
111
+ `;
112
+
113
+ const COMMANDS = {
114
+ login: () => require('../src/commands/login'),
115
+ whoami: () => require('../src/commands/whoami'),
116
+ logout: () => require('../src/commands/logout'),
117
+ init: () => require('../src/commands/init'),
118
+ push: () => require('../src/commands/push'),
119
+ pull: () => require('../src/commands/pull'),
120
+ status: () => require('../src/commands/status'),
121
+ log: () => require('../src/commands/log'),
122
+ diff: () => require('../src/commands/diff'),
123
+ review: () => require('../src/commands/review'),
124
+ export: () => require('../src/commands/export'),
125
+ };
126
+
127
+ async function main() {
128
+ const argv = process.argv.slice(2);
129
+ const parsed = parseArgs(argv, {
130
+ // 'push' tiene que estar acá: la lista de booleanos es global, y sin
131
+ // registrarlo `shilo init --project X --push .` se comería el `.` como
132
+ // valor de --push, perdiendo el positional de la carpeta.
133
+ booleans: [
134
+ 'help', 'version', 'h', 'v', 'dry-run', 'yes', 'force', 'push', 'pull',
135
+ 'json', 'short', 'stat', 'files', 'allow-secrets', 'no-index', 'verbose',
136
+ 'show-ignored', 'include-ignored', 'aprobado', 'reparos', 'rechazado',
137
+ ],
138
+ aliases: { h: 'help', v: 'version', m: 'message' },
139
+ // `--only` se repite (un selector por ruta): sin esto la última aparición
140
+ // pisaría a las anteriores y un push de dos archivos subiría uno solo.
141
+ multiple: ['only'],
142
+ });
143
+
144
+ const cmd = parsed._[0];
145
+
146
+ if (parsed.version && !cmd) {
147
+ console.log(VERSION);
148
+ return 0;
149
+ }
150
+ if (!cmd || cmd === 'help' || (parsed.help && !cmd)) {
151
+ console.log(HELP);
152
+ return 0;
153
+ }
154
+
155
+ const loader = COMMANDS[cmd];
156
+ if (!loader) {
157
+ ui.error(`Comando desconocido: "${cmd}".`);
158
+ console.log(HELP);
159
+ return 1;
160
+ }
161
+
162
+ if (parsed.help) {
163
+ console.log(HELP);
164
+ return 0;
165
+ }
166
+
167
+ // Los positionals del comando (sin el nombre del comando).
168
+ const commandArgs = { ...parsed, _: parsed._.slice(1) };
169
+ const handler = loader();
170
+ return handler(commandArgs);
171
+ }
172
+
173
+ /**
174
+ * Termina con `code` sin llamar a `process.exit()` de inmediato.
175
+ *
176
+ * Llamarlo justo después de un `fetch` aborta el proceso en Windows con
177
+ * `Assertion failed: !(handle->flags & UV_HANDLE_CLOSING)`: libuv cierra dos
178
+ * veces el handle del pool de conexiones de undici. El comando ya imprimió todo
179
+ * y hasta guardó en disco, pero el shell recibe 127 en vez de 0 — o sea que
180
+ * cualquier script o CI que chequee el resultado de `shilo push` lee basura.
181
+ *
182
+ * Dejar que el loop se vacíe solo evita el crash y no cuesta nada: las conexiones
183
+ * de undici no tienen ref, así que el proceso sale igual de rápido. El timer es
184
+ * el paracaídas por si algo queda colgado; sin ref, no mantiene vivo al proceso
185
+ * por sí mismo, sólo actúa si ya lo estaba.
186
+ */
187
+ function finish(code) {
188
+ process.exitCode = code;
189
+ setTimeout(() => process.exit(code), 5000).unref();
190
+ }
191
+
192
+ main()
193
+ .then((code) => finish(typeof code === 'number' ? code : 0))
194
+ .catch((err) => {
195
+ ui.error(err && err.message ? err.message : String(err));
196
+ finish(1);
197
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shilo-cli",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "CLI para sincronizar carpetas locales con repositorios de Shilo: push, pull, status, log y diff.",
5
5
  "keywords": [
6
6
  "shilo",