@asaro/git-cli 1.0.0 → 1.0.2

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/remoto.js DELETED
@@ -1,129 +0,0 @@
1
- import { git, c, separador, verificarRepo, spinner } from "./utils.js";
2
- import { select, confirm } from "@inquirer/prompts";
3
- // ── Push ─────────────────────────────────────────────────────────────────────
4
- export async function hacerPush() {
5
- if (!(await verificarRepo()))
6
- return;
7
- const spin = spinner("Verificando estado...");
8
- const status = await git.status();
9
- const remotos = await git.getRemotes(true);
10
- spin.stop();
11
- if (remotos.length === 0) {
12
- console.log(c.error("\n ✗ No hay remotos configurados en este repositorio.\n"));
13
- return;
14
- }
15
- const rama = status.current ?? "main";
16
- console.log();
17
- console.log(c.titulo(" ↑ Subir cambios (push)"));
18
- separador();
19
- console.log(` Rama actual: ${c.rama(rama)}`);
20
- if (status.ahead > 0) {
21
- console.log(c.aviso(` ${status.ahead} commit(s) pendientes de subir`));
22
- }
23
- else {
24
- console.log(c.tenue(" No hay commits nuevos para subir."));
25
- }
26
- separador();
27
- // Seleccionar remoto si hay más de uno
28
- let remoto = "origin";
29
- if (remotos.length > 1) {
30
- remoto = await select({
31
- message: "¿A qué remoto hacer push?",
32
- choices: remotos.map(r => ({ name: r.name, value: r.name })),
33
- });
34
- }
35
- const modo = await select({
36
- message: "Modo de push:",
37
- choices: [
38
- { name: `Subir rama actual (${rama})`, value: "normal" },
39
- { name: "Subir y crear rama en remoto (--set-upstream)", value: "upstream" },
40
- { name: "Forzar push (--force-with-lease)", value: "force" },
41
- { name: "Subir todos los tags", value: "tags" },
42
- ],
43
- });
44
- const confirmar = await confirm({ message: `¿Confirmar push a ${remoto}/${rama}?`, default: true });
45
- if (!confirmar) {
46
- console.log(c.aviso(" Push cancelado.\n"));
47
- return;
48
- }
49
- const spinPush = spinner("Subiendo cambios...");
50
- try {
51
- switch (modo) {
52
- case "upstream":
53
- await git.push([remoto, rama, "--set-upstream"]);
54
- break;
55
- case "force":
56
- await git.push([remoto, rama, "--force-with-lease"]);
57
- break;
58
- case "tags":
59
- await git.push([remoto, "--tags"]);
60
- break;
61
- default:
62
- await git.push(remoto, rama);
63
- }
64
- spinPush.stop();
65
- console.log(c.exito(`\n ✓ Push exitoso → ${remoto}/${rama}\n`));
66
- }
67
- catch (err) {
68
- spinPush.stop();
69
- const msg = err instanceof Error ? err.message : String(err);
70
- console.log(c.error(`\n ✗ Error en push:\n ${msg}\n`));
71
- }
72
- }
73
- // ── Pull ─────────────────────────────────────────────────────────────────────
74
- export async function hacerPull() {
75
- if (!(await verificarRepo()))
76
- return;
77
- const spin = spinner("Verificando estado...");
78
- const status = await git.status();
79
- const remotos = await git.getRemotes(true);
80
- spin.stop();
81
- if (remotos.length === 0) {
82
- console.log(c.error("\n ✗ No hay remotos configurados.\n"));
83
- return;
84
- }
85
- const rama = status.current ?? "main";
86
- console.log();
87
- console.log(c.titulo(" ↓ Bajar cambios (pull)"));
88
- separador();
89
- console.log(` Rama actual: ${c.rama(rama)}`);
90
- if (status.behind > 0) {
91
- console.log(c.aviso(` ${status.behind} commit(s) disponibles en el remoto`));
92
- }
93
- separador();
94
- let remoto = "origin";
95
- if (remotos.length > 1) {
96
- remoto = await select({
97
- message: "¿Desde qué remoto hacer pull?",
98
- choices: remotos.map(r => ({ name: r.name, value: r.name })),
99
- });
100
- }
101
- const estrategia = await select({
102
- message: "Estrategia de integración:",
103
- choices: [
104
- { name: "Merge (por defecto)", value: "merge" },
105
- { name: "Rebase (historial más limpio)", value: "rebase" },
106
- ],
107
- });
108
- const confirmar = await confirm({ message: `¿Confirmar pull desde ${remoto}/${rama}?`, default: true });
109
- if (!confirmar) {
110
- console.log(c.aviso(" Pull cancelado.\n"));
111
- return;
112
- }
113
- const spinPull = spinner("Bajando cambios...");
114
- try {
115
- if (estrategia === "rebase") {
116
- await git.pull(remoto, rama, { "--rebase": "true" });
117
- }
118
- else {
119
- await git.pull(remoto, rama);
120
- }
121
- spinPull.stop();
122
- console.log(c.exito(`\n ✓ Pull exitoso desde ${remoto}/${rama}\n`));
123
- }
124
- catch (err) {
125
- spinPull.stop();
126
- const msg = err instanceof Error ? err.message : String(err);
127
- console.log(c.error(`\n ✗ Error en pull:\n ${msg}\n`));
128
- }
129
- }
@@ -1,159 +0,0 @@
1
- import { git, c, separador, verificarRepo, spinner } from "./utils.js";
2
- import { select, input, confirm } from "@inquirer/prompts";
3
- import { simpleGit } from "simple-git";
4
- import path from "path";
5
- // ── Menú Clone / Init ─────────────────────────────────────────────────────────
6
- export async function menuOrigenRepo() {
7
- const accion = await select({
8
- message: "Repositorio — ¿qué deseas hacer?",
9
- choices: [
10
- { name: "Clonar repositorio remoto", value: "clonar" },
11
- { name: "Inicializar nuevo repositorio", value: "init" },
12
- { name: "Ver remotos configurados", value: "remotos" },
13
- { name: "Agregar remoto", value: "agregarRemoto" },
14
- { name: "← Volver al menú principal", value: "volver" },
15
- ],
16
- });
17
- switch (accion) {
18
- case "clonar": return clonarRepo();
19
- case "init": return inicializarRepo();
20
- case "remotos": return verRemotos();
21
- case "agregarRemoto": return agregarRemoto();
22
- case "volver": return;
23
- }
24
- }
25
- // ── Clonar ────────────────────────────────────────────────────────────────────
26
- async function clonarRepo() {
27
- console.log();
28
- console.log(c.titulo(" 📥 Clonar repositorio"));
29
- separador();
30
- const url = await input({
31
- message: "URL del repositorio (HTTPS o SSH):",
32
- validate: (v) => v.trim().length > 0 || "La URL no puede estar vacía.",
33
- });
34
- const nombreSugerido = url.split("/").pop()?.replace(".git", "") ?? "repo";
35
- const destino = await input({
36
- message: "Carpeta de destino:",
37
- default: nombreSugerido,
38
- validate: (v) => v.trim().length > 0 || "El nombre no puede estar vacío.",
39
- });
40
- const rama = await input({
41
- message: "Rama a clonar (dejar vacío para rama por defecto):",
42
- default: "",
43
- });
44
- const cwd = process.cwd();
45
- const destinoAbsoluto = path.join(cwd, destino);
46
- separador();
47
- console.log(` URL: ${c.info(url)}`);
48
- console.log(` Carpeta: ${c.archivo(destinoAbsoluto)}`);
49
- if (rama.trim())
50
- console.log(` Rama: ${c.rama(rama.trim())}`);
51
- separador();
52
- const confirmar = await confirm({ message: "¿Confirmar clonación?", default: true });
53
- if (!confirmar) {
54
- console.log(c.aviso(" Clonación cancelada.\n"));
55
- return;
56
- }
57
- const spinClone = spinner("Clonando repositorio...");
58
- try {
59
- const g = simpleGit(cwd);
60
- const opciones = [];
61
- if (rama.trim()) {
62
- opciones.push("-b", rama.trim());
63
- }
64
- await g.clone(url, destino, opciones);
65
- spinClone.stop();
66
- console.log(c.exito(`\n ✓ Repositorio clonado en: ${c.archivo(destinoAbsoluto)}\n`));
67
- }
68
- catch (err) {
69
- spinClone.stop();
70
- const msg = err instanceof Error ? err.message : String(err);
71
- console.log(c.error(`\n ✗ Error al clonar:\n ${msg}\n`));
72
- }
73
- }
74
- // ── Init ──────────────────────────────────────────────────────────────────────
75
- async function inicializarRepo() {
76
- console.log();
77
- console.log(c.titulo(" 🆕 Inicializar repositorio"));
78
- separador();
79
- const esActual = await select({
80
- message: "¿Dónde inicializar?",
81
- choices: [
82
- { name: `Directorio actual (${process.cwd()})`, value: "actual" },
83
- { name: "Nueva carpeta", value: "nueva" },
84
- ],
85
- });
86
- let destino = process.cwd();
87
- if (esActual === "nueva") {
88
- const nombreCarpeta = await input({
89
- message: "Nombre de la nueva carpeta:",
90
- validate: (v) => v.trim().length > 0 || "El nombre no puede estar vacío.",
91
- });
92
- destino = path.join(process.cwd(), nombreCarpeta);
93
- }
94
- const ramaInicial = await input({
95
- message: "Nombre de la rama inicial:",
96
- default: "main",
97
- });
98
- const confirmar = await confirm({ message: `¿Inicializar repo en: ${c.archivo(destino)}?`, default: true });
99
- if (!confirmar)
100
- return;
101
- const spinInit = spinner("Inicializando...");
102
- try {
103
- const g = simpleGit(destino);
104
- await g.init({ "--initial-branch": ramaInicial.trim() || "main" });
105
- spinInit.stop();
106
- console.log(c.exito(`\n ✓ Repositorio inicializado en: ${c.archivo(destino)}\n`));
107
- }
108
- catch (err) {
109
- spinInit.stop();
110
- const msg = err instanceof Error ? err.message : String(err);
111
- console.log(c.error(`\n ✗ Error al inicializar:\n ${msg}\n`));
112
- }
113
- }
114
- // ── Ver remotos ───────────────────────────────────────────────────────────────
115
- async function verRemotos() {
116
- if (!(await verificarRepo()))
117
- return;
118
- const spin = spinner("Cargando remotos...");
119
- const remotos = await git.getRemotes(true);
120
- spin.stop();
121
- console.log();
122
- console.log(c.titulo(" 🌐 Remotos configurados"));
123
- separador();
124
- if (remotos.length === 0) {
125
- console.log(c.tenue(" No hay remotos configurados."));
126
- }
127
- else {
128
- remotos.forEach(r => {
129
- console.log(` ${c.info(r.name.padEnd(10))} ${c.tenue(r.refs.fetch ?? "")}`);
130
- });
131
- }
132
- separador();
133
- console.log();
134
- }
135
- // ── Agregar remoto ─────────────────────────────────────────────────────────────
136
- async function agregarRemoto() {
137
- if (!(await verificarRepo()))
138
- return;
139
- const nombre = await input({
140
- message: "Nombre del remoto:",
141
- default: "origin",
142
- validate: (v) => v.trim().length > 0 || "Nombre requerido.",
143
- });
144
- const url = await input({
145
- message: "URL del remoto:",
146
- validate: (v) => v.trim().length > 0 || "URL requerida.",
147
- });
148
- const spinRem = spinner("Agregando remoto...");
149
- try {
150
- await git.addRemote(nombre, url);
151
- spinRem.stop();
152
- console.log(c.exito(`\n ✓ Remoto "${nombre}" agregado → ${url}\n`));
153
- }
154
- catch (err) {
155
- spinRem.stop();
156
- const msg = err instanceof Error ? err.message : String(err);
157
- console.log(c.error(`\n ✗ Error:\n ${msg}\n`));
158
- }
159
- }
package/dist/stash.js DELETED
@@ -1,169 +0,0 @@
1
- import { git, c, separador, verificarRepo, spinner } from "./utils.js";
2
- import { select, input, confirm } from "@inquirer/prompts";
3
- // ── Menú Stash ─────────────────────────────────────────────────────────────────
4
- export async function menuStash() {
5
- if (!(await verificarRepo()))
6
- return;
7
- const accion = await select({
8
- message: "Stash — ¿qué deseas hacer?",
9
- choices: [
10
- { name: "Guardar cambios en stash", value: "guardar" },
11
- { name: "Ver lista de stashes", value: "listar" },
12
- { name: "Aplicar stash (mantener en lista)", value: "aplicar" },
13
- { name: "Restaurar y eliminar stash (pop)", value: "pop" },
14
- { name: "Eliminar un stash", value: "eliminar" },
15
- { name: "Limpiar todos los stashes", value: "limpiar" },
16
- { name: "← Volver al menú principal", value: "volver" },
17
- ],
18
- });
19
- switch (accion) {
20
- case "guardar": return guardarStash();
21
- case "listar": return listarStashes();
22
- case "aplicar": return operarStash("apply");
23
- case "pop": return operarStash("pop");
24
- case "eliminar": return eliminarStash();
25
- case "limpiar": return limpiarStashes();
26
- case "volver": return;
27
- }
28
- }
29
- // ── Guardar stash ─────────────────────────────────────────────────────────────
30
- async function guardarStash() {
31
- const spin = spinner("Verificando cambios...");
32
- const status = await git.status();
33
- spin.stop();
34
- const hayModificados = status.modified.length + status.staged.length + status.not_added.length;
35
- if (hayModificados === 0) {
36
- console.log(c.aviso("\n No hay cambios para guardar en stash.\n"));
37
- return;
38
- }
39
- const mensaje = await input({
40
- message: "Mensaje del stash (opcional):",
41
- });
42
- const incluirNoSeguidos = await confirm({
43
- message: "¿Incluir archivos sin seguimiento (untracked)?",
44
- default: false,
45
- });
46
- const spinStash = spinner("Guardando en stash...");
47
- try {
48
- const args = ["push"];
49
- if (mensaje.trim())
50
- args.push("-m", mensaje.trim());
51
- if (incluirNoSeguidos)
52
- args.push("--include-untracked");
53
- await git.stash(args);
54
- spinStash.stop();
55
- console.log(c.exito("\n ✓ Cambios guardados en stash. Árbol limpio.\n"));
56
- }
57
- catch (err) {
58
- spinStash.stop();
59
- const msg = err instanceof Error ? err.message : String(err);
60
- console.log(c.error(`\n ✗ Error al guardar stash:\n ${msg}\n`));
61
- }
62
- }
63
- // ── Listar stashes ─────────────────────────────────────────────────────────────
64
- async function listarStashes() {
65
- const spin = spinner("Cargando stashes...");
66
- const lista = await git.stashList();
67
- spin.stop();
68
- console.log();
69
- console.log(c.titulo(" 📦 Stashes guardados"));
70
- separador();
71
- if (lista.all.length === 0) {
72
- console.log(c.tenue(" No hay stashes guardados."));
73
- }
74
- else {
75
- lista.all.forEach((s, i) => {
76
- const fecha = new Date(s.date).toLocaleDateString("es-CL", {
77
- day: "2-digit", month: "short", year: "numeric",
78
- });
79
- console.log(` ${c.hash(`stash@{${i}}`)} ${c.tenue(fecha)} ${c.titulo(s.message)}`);
80
- });
81
- }
82
- separador();
83
- console.log();
84
- }
85
- // ── Seleccionar stash y operar (apply o pop) ───────────────────────────────────
86
- async function operarStash(modo) {
87
- const spin = spinner("Cargando stashes...");
88
- const lista = await git.stashList();
89
- spin.stop();
90
- if (lista.all.length === 0) {
91
- console.log(c.aviso("\n No hay stashes disponibles.\n"));
92
- return;
93
- }
94
- const opciones = lista.all.map((s, i) => ({
95
- name: `stash@{${i}} ${s.message}`,
96
- value: `stash@{${i}}`,
97
- }));
98
- const seleccionado = await select({
99
- message: modo === "pop" ? "¿Qué stash restaurar y eliminar (pop)?" : "¿Qué stash aplicar?",
100
- choices: opciones,
101
- });
102
- const label = modo === "pop" ? "Restaurando y eliminando" : "Aplicando";
103
- const spinOp = spinner(`${label} ${seleccionado}...`);
104
- try {
105
- if (modo === "pop") {
106
- await git.stash(["pop", seleccionado]);
107
- }
108
- else {
109
- await git.stash(["apply", seleccionado]);
110
- }
111
- spinOp.stop();
112
- console.log(c.exito(`\n ✓ ${seleccionado} ${modo === "pop" ? "restaurado y eliminado" : "aplicado"}.\n`));
113
- }
114
- catch (err) {
115
- spinOp.stop();
116
- const msg = err instanceof Error ? err.message : String(err);
117
- console.log(c.error(`\n ✗ Error:\n ${msg}\n`));
118
- }
119
- }
120
- // ── Eliminar un stash ──────────────────────────────────────────────────────────
121
- async function eliminarStash() {
122
- const spin = spinner("Cargando stashes...");
123
- const lista = await git.stashList();
124
- spin.stop();
125
- if (lista.all.length === 0) {
126
- console.log(c.aviso("\n No hay stashes disponibles.\n"));
127
- return;
128
- }
129
- const opciones = lista.all.map((s, i) => ({
130
- name: `stash@{${i}} ${s.message}`,
131
- value: `stash@{${i}}`,
132
- }));
133
- const seleccionado = await select({
134
- message: "¿Qué stash deseas eliminar?",
135
- choices: opciones,
136
- });
137
- const confirmar = await confirm({ message: `¿Eliminar ${seleccionado}?`, default: false });
138
- if (!confirmar)
139
- return;
140
- const spinDel = spinner("Eliminando...");
141
- try {
142
- await git.stash(["drop", seleccionado]);
143
- spinDel.stop();
144
- console.log(c.exito(`\n ✓ ${seleccionado} eliminado.\n`));
145
- }
146
- catch (err) {
147
- spinDel.stop();
148
- console.log(c.error("\n ✗ Error al eliminar el stash.\n"));
149
- }
150
- }
151
- // ── Limpiar todos los stashes ──────────────────────────────────────────────────
152
- async function limpiarStashes() {
153
- const confirmar = await confirm({
154
- message: c.error("¿Eliminar TODOS los stashes? Esta acción es irreversible."),
155
- default: false,
156
- });
157
- if (!confirmar)
158
- return;
159
- const spin = spinner("Limpiando stashes...");
160
- try {
161
- await git.stash(["clear"]);
162
- spin.stop();
163
- console.log(c.exito("\n ✓ Todos los stashes eliminados.\n"));
164
- }
165
- catch (err) {
166
- spin.stop();
167
- console.log(c.error("\n ✗ Error al limpiar stashes.\n"));
168
- }
169
- }
package/dist/utils.js DELETED
@@ -1,49 +0,0 @@
1
- import chalk from "chalk";
2
- import ora from "ora";
3
- import { simpleGit } from "simple-git";
4
- // ── Instancia git del directorio de trabajo ──────────────────────────────────
5
- export const git = simpleGit(process.cwd());
6
- // ── Paleta visual (Catppuccin Macchiato) ─────────────────────────────────────
7
- export const c = {
8
- titulo: (t) => chalk.bold.hex("#cad3f5")(t),
9
- exito: (t) => chalk.hex("#a6da95")(t),
10
- error: (t) => chalk.hex("#ed8796")(t),
11
- aviso: (t) => chalk.hex("#eed49f")(t),
12
- info: (t) => chalk.hex("#8aadf4")(t),
13
- tenue: (t) => chalk.hex("#6e738d")(t),
14
- rama: (t) => chalk.bold.hex("#f5bde6")(t),
15
- hash: (t) => chalk.hex("#f5a97f")(t),
16
- archivo: (t) => chalk.hex("#91d7e3")(t),
17
- };
18
- // ── Spinner con colores ───────────────────────────────────────────────────────
19
- export function spinner(texto) {
20
- return ora({ text: c.info(texto), spinner: "dots" }).start();
21
- }
22
- // ── Verificar que el directorio actual es un repo git ────────────────────────
23
- export async function verificarRepo() {
24
- try {
25
- await git.revparse(["--git-dir"]);
26
- return true;
27
- }
28
- catch {
29
- console.log(c.error("✗ Este directorio no es un repositorio Git."));
30
- return false;
31
- }
32
- }
33
- // ── Separador visual ─────────────────────────────────────────────────────────
34
- export function separador() {
35
- console.log(c.tenue("─".repeat(52)));
36
- }
37
- // ── Banner principal ─────────────────────────────────────────────────────────
38
- export function banner() {
39
- console.clear();
40
- console.log();
41
- console.log(c.titulo(" ██████╗ ██╗████████╗ ██████╗██╗ ██╗"));
42
- console.log(c.titulo(" ██╔════╝ ██║╚══██╔══╝██╔════╝██║ ██║"));
43
- console.log(c.titulo(" ██║ ███╗██║ ██║ ██║ ██║ ██║"));
44
- console.log(c.titulo(" ██║ ██║██║ ██║ ██║ ██║ ██║"));
45
- console.log(c.titulo(" ╚██████╔╝██║ ██║ ╚██████╗███████╗██║"));
46
- console.log(c.titulo(" ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝"));
47
- console.log(c.tenue(" Git CLI interactivo · Alex · v1.0.0"));
48
- console.log();
49
- }