@asaro/git-cli 1.0.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.
Files changed (40) hide show
  1. package/README.md +189 -0
  2. package/dist/adapters/git/SimpleGitAdapter.js +126 -0
  3. package/dist/adapters/github/GitHubAPIAdapter.js +243 -0
  4. package/dist/adapters/storage/FileSecureStorageAdapter.js +67 -0
  5. package/dist/adapters/ui/ConsoleUIAdapter.js +91 -0
  6. package/dist/commands/BaseCommand.js +11 -0
  7. package/dist/commands/BranchesCommand.js +152 -0
  8. package/dist/commands/Command.js +1 -0
  9. package/dist/commands/CommitCommand.js +85 -0
  10. package/dist/commands/IntegrationCommand.js +151 -0
  11. package/dist/commands/LogCommand.js +42 -0
  12. package/dist/commands/PullCommand.js +55 -0
  13. package/dist/commands/PushCommand.js +227 -0
  14. package/dist/commands/RepositoryCommand.js +268 -0
  15. package/dist/commands/StashCommand.js +140 -0
  16. package/dist/commands/StatusCommand.js +66 -0
  17. package/dist/commands/github/BaseGitHubCommand.js +17 -0
  18. package/dist/commands/github/GitHubAuthCommand.js +48 -0
  19. package/dist/commands/github/GitHubMenuCommand.js +57 -0
  20. package/dist/commands/github/GitHubReposCommand.js +210 -0
  21. package/dist/commands/github/GitHubWorkflowsCommand.js +243 -0
  22. package/dist/commit.js +98 -0
  23. package/dist/core/errors/GitError.js +19 -0
  24. package/dist/core/errors/GitHubError.js +36 -0
  25. package/dist/core/ports/GitHubPort.js +1 -0
  26. package/dist/core/ports/GitPort.js +1 -0
  27. package/dist/core/ports/SecureStoragePort.js +1 -0
  28. package/dist/core/ports/UIPort.js +1 -0
  29. package/dist/core/services/GitHubService.js +95 -0
  30. package/dist/core/services/GitService.js +44 -0
  31. package/dist/estado.js +97 -0
  32. package/dist/factories/CommandFactory.js +51 -0
  33. package/dist/index.js +71 -0
  34. package/dist/integracion.js +152 -0
  35. package/dist/ramas.js +178 -0
  36. package/dist/remoto.js +129 -0
  37. package/dist/repositorio.js +159 -0
  38. package/dist/stash.js +169 -0
  39. package/dist/utils.js +49 -0
  40. package/package.json +53 -0
package/dist/stash.js ADDED
@@ -0,0 +1,169 @@
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 ADDED
@@ -0,0 +1,49 @@
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
+ }
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@asaro/git-cli",
3
+ "version": "1.0.0",
4
+ "description": "Git CLI interactivo en español para gestionar repositorios Git y GitHub",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "git-cli": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "start": "node --experimental-vm-modules dist/index.js",
16
+ "dev": "node --loader ts-node/esm src/index.ts",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": [
20
+ "git",
21
+ "cli",
22
+ "github",
23
+ "terminal",
24
+ "español"
25
+ ],
26
+ "author": "Alexsander Rosales <Alexsander.rosales33@gmail.com>",
27
+ "license": "ISC",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+ssh://git@github.com/iTzAsaro/GitCLI.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/iTzAsaro/GitCLI/issues"
34
+ },
35
+ "homepage": "https://github.com/iTzAsaro/GitCLI#readme",
36
+ "dependencies": {
37
+ "@inquirer/prompts": "^8.5.2",
38
+ "chalk": "^5.6.2",
39
+ "crypto-js": "^4.2.0",
40
+ "octokit": "^5.0.5",
41
+ "ora": "^9.4.0",
42
+ "simple-git": "^3.36.0"
43
+ },
44
+ "devDependencies": {
45
+ "@types/crypto-js": "^4.2.2",
46
+ "@types/node": "^25.9.2",
47
+ "ts-node": "^10.9.2",
48
+ "typescript": "^6.0.3"
49
+ },
50
+ "engines": {
51
+ "node": ">=18.0.0"
52
+ }
53
+ }