diff --git a/README.md b/README.md
index 971dffd..dbacd9b 100644
--- a/README.md
+++ b/README.md
@@ -1,37 +1,22 @@
# Soul:23 coming soon page
-Una landing page responsive Built con Bootstrap 4 que muestra una cuenta regresiva y un formulario de notificaciones. Se accede a una versión viva en https://solu23.cloud.
+A responsive landing page built with Bootstrap 4 that displays a countdown and a notification form.
-**Author:** Marco Gallegos
-
-## Instalación local
+## Local Installation
```bash
npm install
npm start
```
-El servidor Express sirve todos los assets desde la raíz y expone `/healthchecker` con el script de salud como `text/plain`, listo para que operadores lo descarguen con `curl`.
+The Express server serves all assets from the root and exposes a `/healthchecker` endpoint with the health script as `text/plain`, ready for operators to download with `curl`.
-## Deploy con Coolify / Traefik
+## Countdown and Form
-1. Importa el repositorio como app Docker en Coolify.
-2. Elige el `Dockerfile` del proyecto, expone el puerto `3001` (ya definido en el contenedor).
-3. Coolify/Traefik se encargan del TLS; usa el dominio que asignas en la app.
-4. Si necesitas alertas, define la variable de entorno `WEBHOOK_URLS` antes de levantar la app.
-
-Una vez desplegado podrás invocar el verificador con:
-
-```bash
-curl https://soul23.cloud/healthchecker
-```
-
-## Contador y formulario
-
-El componente de tiempo lee el atributo `data-date` en `#countdown-timer`. Cámbialo por cualquier fecha válida:
+The time component reads the `data-date` attribute in `#countdown-timer`. Change it to any valid date:
```html
```
-Si prefieres programarlo con JavaScript, reasigna la variable `countDownDate` dentro de `js/countdown.js` antes de que empiece el intervalo.
+If you prefer to program it with JavaScript, reassign the `countDownDate` variable inside `js/countdown.js` before the interval starts.
diff --git a/data/README.md b/data/README.md
new file mode 100644
index 0000000..f7a08ba
--- /dev/null
+++ b/data/README.md
@@ -0,0 +1,15 @@
+# Data Files
+
+This directory contains various data files used by the application.
+
+## Organization
+
+* `quotes.json`: Stores a collection of phrases for the `/day-quote` endpoint.
+* Other `.json` files: Should contain structured data for specific application features.
+* Avoid storing large binary files directly in this directory; consider external storage solutions or dedicated asset folders for those.
+
+## Best Practices
+
+* Ensure all data files are in a structured, easily parsable format (e.g., JSON, YAML).
+* Provide a clear description for each data file, either in comments within the file (if the format supports it) or in this README.
+* Do not store sensitive information in plaintext here. Use environment variables or a secure configuration management system for secrets.
\ No newline at end of file
diff --git a/data/quotes.json b/data/quotes.json
new file mode 100644
index 0000000..3d293f6
--- /dev/null
+++ b/data/quotes.json
@@ -0,0 +1,121 @@
+{
+ "phrases": [
+ "Cada decisión consciente alinea tu camino.",
+ "Cada día alineado refuerza tu destino.",
+ "Cada día consciente fortalece tu señal.",
+ "Cada día consciente refuerza tu camino.",
+ "Cada elección consciente te alinea más.",
+ "Cada experiencia trae un mensaje oculto.",
+ "Cada intención sostenida genera respuesta.",
+ "Cada paso alineado atrae claridad.",
+ "Cada paso consciente es escuchado.",
+ "Cada paso honesto genera respuesta.",
+ "Confía: estás siendo sostenido.",
+ "Cuando confías, avanzas más ligero.",
+ "Cuando confías, todo se acomoda.",
+ "Cuando confías, todo fluye con menos esfuerzo.",
+ "Cuando eliges bien, el camino se suaviza.",
+ "Cuando eliges claridad, todo coopera.",
+ "Cuando eliges paz, eliges bien.",
+ "Cuando eliges paz, todo se ordena.",
+ "Cuando sueltas el control, el camino se acomoda.",
+ "Cuando te alineas, todo coopera.",
+ "El camino se aclara cuando sigues caminando.",
+ "El equilibrio es parte del plan.",
+ "El equilibrio llega cuando dejas de forzar.",
+ "El equilibrio llega cuando sueltas el miedo.",
+ "El universo acomoda lo que tu mente no puede.",
+ "El universo acomoda piezas invisibles.",
+ "El universo acompaña decisiones conscientes.",
+ "El universo acompaña tu enfoque.",
+ "El universo ajusta lo que tú ya soltaste.",
+ "El universo ajusta lo que tú sostienes.",
+ "El universo amplifica lo que sostienes.",
+ "El universo avanza contigo.",
+ "El universo avanza contigo, incluso cuando dudas.",
+ "El universo abre caminos cuando confías.",
+ "El universo cuida lo que cuidas.",
+ "El universo cuida los procesos honestos.",
+ "El universo escucha lo que practicas.",
+ "El universo escucha lo que repites.",
+ "El universo escucha lo que sostienes a diario.",
+ "El universo guía, no empuja.",
+ "El universo honra la intención sostenida.",
+ "El universo no se equivoca con los tiempos.",
+ "El universo premia la coherencia.",
+ "El universo recompensa la constancia silenciosa.",
+ "El universo responde a la constancia.",
+ "El universo responde a la constancia real.",
+ "El universo responde a tu coherencia.",
+ "El universo responde mejor a la calma que a la prisa.",
+ "El universo respalda la claridad.",
+ "El universo respalda las decisiones honestas.",
+ "El universo respeta tus decisiones.",
+ "El universo se mueve a favor del equilibrio.",
+ "El universo se ordena cuando tú lo haces.",
+ "El universo también necesita tu paciencia.",
+ "El universo también responde a la gratitud.",
+ "El universo trabaja en silencio.",
+ "El universo trabaja en tu favor.",
+ "El universo trabaja mientras tú sigues avanzando.",
+ "El universo trabaja contigo, no contra ti.",
+ "El universo ya escuchó tu intención; ahora confía en el proceso.",
+ "Estás aprendiendo a recibir.",
+ "Estás más alineado de lo que crees.",
+ "Estás más cerca de lo que parece.",
+ "Estás siendo guiado aunque no lo notes.",
+ "Estás siendo llevado hacia algo mejor.",
+ "Estás siendo preparado.",
+ "Estás exactamente donde necesitas estar ahora.",
+ "La calma abre puertas invisibles.",
+ "La calma amplifica tu claridad.",
+ "La calma es una señal poderosa.",
+ "La calma también es acción.",
+ "La claridad llega después de la acción.",
+ "La claridad se construye caminando.",
+ "La coherencia atrae oportunidades.",
+ "La coherencia es una forma de magnetismo.",
+ "La intención clara atrae resultados claros.",
+ "La paciencia también es una señal de confianza.",
+ "La paciencia también atrae.",
+ "Lo correcto no genera caos.",
+ "Lo correcto se siente estable.",
+ "Lo correcto se siente ligero.",
+ "Lo que es para ti encuentra la forma de alcanzarte.",
+ "Lo que es para ti se siente en paz.",
+ "Lo que es para ti se sentirá claro.",
+ "Lo que es real no necesita prisa.",
+ "Lo que estás viviendo hoy te está preparando para algo mejor.",
+ "Lo que fluye contigo es real.",
+ "Lo que fluye no se fuerza.",
+ "Lo que hoy confías se fortalece.",
+ "Lo que hoy confías, mañana florece.",
+ "Lo que hoy eliges construye mañana.",
+ "Lo que hoy eliges define tu energía.",
+ "Lo que hoy parece confuso se ordenará pronto.",
+ "Lo que hoy parece lento es profundo.",
+ "Lo que hoy pesa, mañana tendrá sentido.",
+ "Lo que hoy siembras se manifestará mañana.",
+ "Lo que necesitas llegará en la forma correcta.",
+ "Lo que respetas, crece.",
+ "Lo que vibra alto atrae estabilidad.",
+ "Lo que vibra contigo permanece.",
+ "Nada auténtico necesita forzarse.",
+ "Nada llega antes de que estés listo.",
+ "Nada llega antes de tiempo.",
+ "Nada llega para confundirte sin razón.",
+ "Nada llega para romperte, sino para formarte.",
+ "Nada que sea para ti se pierde.",
+ "Nada real se desvanece.",
+ "Nada se acomoda sin intención.",
+ "Nada tiene que entenderse para funcionar.",
+ "Nada verdadero se pierde.",
+ "Nada verdadero se pierde en el camino.",
+ "No estás solo en este proceso.",
+ "No estás tarde; estás justo a tiempo para tu proceso.",
+ "Todo llega cuando dejas espacio para recibirlo.",
+ "Todo movimiento consciente tiene respuesta.",
+ "Todo se ordena cuando confías en tu proceso.",
+ "Todo tiene un ritmo perfecto."
+ ]
+}
\ No newline at end of file
diff --git a/data/sites.json b/data/sites.json
new file mode 100644
index 0000000..3d6ef6a
--- /dev/null
+++ b/data/sites.json
@@ -0,0 +1,36 @@
+{
+ "internos": {
+ "vps_soul23": "https://soul23.cloud/health",
+ "coolify": "https://aperture.soul23.cloud",
+ "formbricks": "https://feedback.soul23.cloud/health",
+ "vikunja": "https://tasks.soul23.cloud",
+ "gokapi": "https://wetrans.soul23.cloud",
+ "n8n_flows": "https://flows.soul23.cloud",
+ "ap_pos": "https://apos.soul23.cloud",
+ "appsmith": "https://appsmith.soul23.cloud"
+ },
+ "sitios_empresa": {
+ "vanity_web": "https://vanityexperience.mx/",
+ "vanity_cursos": "https://cursos.vanityexperience.mx/",
+ "vanity_academy": "https://academy.vanityexperience.mx/",
+ "vanity_unirse": "https://unirse.vanityexperience.mx/",
+ "soul23": "https://soul23.cloud/",
+ "socias_vanity": "https://socias.vanityexperience.mx/"
+ },
+ "externos": {
+ "fresha": "https://www.freshastatus.com/",
+ "google_gemini": "https://aistudio.google.com/status?hl=es-419",
+ "openai": "https://status.openai.com/",
+ "canva": "https://www.canvastatus.com/",
+ "tiktok": "https://www.tiktok.com",
+ "facebook": "https://www.facebook.com",
+ "instagram": "https://www.instagram.com",
+ "telegram": "https://core.telegram.org",
+ "whatsapp": "https://www.whatsapp.com",
+ "x": "https://www.x.com",
+ "youtube": "https://www.youtube.com",
+ "cloudflare": "https://www.cloudflarestatus.com",
+ "aws": "https://status.aws.amazon.com/rss/all.rss",
+ "azure": "https://status.azure.com/en-us/status/feed"
+ }
+}
diff --git a/htmls/README.md b/htmls/README.md
new file mode 100644
index 0000000..7d27846
--- /dev/null
+++ b/htmls/README.md
@@ -0,0 +1,14 @@
+# HTML Templates
+
+This directory contains HTML files that serve as templates or specific pages for the application, not meant to be served as static assets from the root.
+
+## Organization
+
+* `telegram.html`: A specific HTML page used for Telegram redirection logic.
+* Other `.html` files: Should be specific templates or special pages.
+
+## Best Practices
+
+* HTML files in this directory are typically served dynamically by the Express server for specific routes.
+* Keep the HTML semantic and clean.
+* Avoid placing general static HTML assets here; those should reside in the project root if they are meant to be served as part of the primary static content.
\ No newline at end of file
diff --git a/telegram.html b/htmls/telegram.html
similarity index 100%
rename from telegram.html
rename to htmls/telegram.html
diff --git a/scripts/health_checker.py b/scripts/health_checker.py
new file mode 100644
index 0000000..20e7dfb
--- /dev/null
+++ b/scripts/health_checker.py
@@ -0,0 +1,191 @@
+#!/usr/bin/env python3
+import requests
+import json
+from datetime import datetime, timezone
+import os
+import time
+
+# --- CONFIGURACIÓN DE WEBHOOKS (Desde GitHub Secrets) ---
+webhook_urls_str = os.environ.get('WEBHOOK_URLS', '')
+WEBHOOK_URLS = [url.strip() for url in webhook_urls_str.split(',') if url.strip()]
+
+# --- Cargar sitios desde JSON ---
+sites_file_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'sites.json')
+try:
+ with open(sites_file_path, 'r') as f:
+ sites_data = json.load(f)
+ INTERNOS = sites_data.get("internos", {})
+ SITIOS_EMPRESA = sites_data.get("sitios_empresa", {})
+ EXTERNOS = sites_data.get("externos", {})
+except (FileNotFoundError, json.JSONDecodeError) as e:
+ print(json.dumps({"error": f"Could not load or parse sites.json: {e}"}))
+ exit(1)
+
+
+# Servicios que usan Atlassian StatusPage
+STATUSPAGE_SERVICES = ["openai", "canva", "cloudflare"]
+
+# --- Funciones de Verificación de Estado ---
+
+def check_url(url):
+ """Verificación simple: ¿La web carga (Código 200)?"""
+ try:
+ headers = {'User-Agent': 'HealthCheckMonitor/1.0'}
+ r = requests.get(url, headers=headers, timeout=10)
+ return r.status_code
+ except requests.exceptions.RequestException:
+ return 0
+
+def check_vps_health_endpoint(url):
+ """
+ Verifica el estado del VPS consultando el endpoint JSON personalizado.
+ Espera: {"checks": {"vps_ping": {"alive": true, ...}}}
+ """
+ try:
+ r = requests.get(url, timeout=10)
+ if r.status_code == 200:
+ try:
+ data = r.json()
+ vps_alive = data.get('checks', {}).get('vps_ping', {}).get('alive', False)
+
+ if vps_alive:
+ return "🟢 OK (VPS Reachable)"
+ else:
+ return "🔴 Caído (VPS reporta 'alive': false)"
+ except json.JSONDecodeError:
+ return "🟡 Advertencia (Respuesta no es JSON válido)"
+ else:
+ return f"🔴 Caído (Endpoint status: {r.status_code})"
+ except requests.RequestException as e:
+ return f"🔴 Error Conexión ({str(e)})"
+
+def check_formbricks_health(url):
+ """
+ Verifica el endpoint de salud de Formbricks.
+ NOTA: Usa la URL tal cual viene del diccionario (sin agregar /health extra).
+ """
+ try:
+ response = requests.get(url, timeout=8)
+ if response.status_code == 200:
+ try:
+ data = response.json()
+ if data.get("status") == "ok":
+ return f"🟢 OK (API Health: ok)"
+ else:
+ return f"🟡 Advertencia ({data.get('status', 'unknown')})"
+ except json.JSONDecodeError:
+ return "🟡 Advertencia (No JSON)"
+ else:
+ return f"🔴 Caído (Código: {response.status_code})"
+ except requests.RequestException:
+ return f"🔴 Caído (Error red)"
+
+def get_statuspage_status(base_url):
+ """Consulta la API de statuspage.io (OpenAI, Canva)"""
+ api_url = f"{base_url.rstrip('/')}/api/v2/summary.json"
+ try:
+ response = requests.get(api_url, timeout=8)
+ if response.status_code == 200:
+ data = response.json()
+ description = data.get('status', {}).get('description')
+ indicator = data.get('status', {}).get('indicator')
+ if indicator == 'none':
+ return f"🟢 OK ({description})"
+ else:
+ return f"🟡 Advertencia ({description})"
+ return f"🔴 Caído ({response.status_code})"
+ except requests.exceptions.RequestException:
+ return f"🔴 Error verificación"
+
+def get_gemini_status(display_url):
+ """Verifica incidentes en Google Cloud (Vertex AI/Gemini)"""
+ feed_url = "https://status.cloud.google.com/incidents.json"
+ try:
+ response = requests.get(feed_url, timeout=8)
+ if response.status_code == 200:
+ incidents = response.json()
+ active_problems = []
+ for i in incidents:
+ if not i.get('end'): # Si no ha terminado
+ service_name = i.get('service_name', '').lower()
+ if 'gemini' in service_name or 'vertex' in service_name or 'generative' in service_name:
+ active_problems.append(i.get('external_desc', 'Fallo desconocido'))
+
+ if not active_problems:
+ return "🟢 OK (Sin incidentes en Google AI)"
+ else:
+ return f"🟡 Advertencia ({len(active_problems)} incidentes activos)"
+ else:
+ code = check_url(display_url)
+ return human_state(code)
+ except requests.exceptions.RequestException:
+ return f"🔴 Error de conexión"
+
+def human_state(code):
+ if code == 200:
+ return f"🟢 OK ({code})"
+ if code in (301, 302, 307, 308):
+ return f"🟢 OK (Redirección {code})"
+ if code in (401, 403, 404):
+ return f"🟡 Advertencia ({code})"
+ return f"🔴 Caído ({code})"
+
+# --- Lógica Principal ---
+
+def build_section(diccionario):
+ salida = {}
+ for nombre, url_or_ip in diccionario.items():
+
+ # 1. Check VPS
+ if nombre == 'vps_soul23':
+ status_message = check_vps_health_endpoint(url_or_ip)
+
+ # 2. StatusPage
+ elif nombre in STATUSPAGE_SERVICES:
+ status_message = get_statuspage_status(url_or_ip)
+
+ # 3. Google Gemini
+ elif nombre == 'google_gemini':
+ status_message = get_gemini_status(url_or_ip)
+
+ # 4. Formbricks (URL completa)
+ elif nombre == 'formbricks':
+ status_message = check_formbricks_health(url_or_ip)
+
+ # 5. Resto
+ else:
+ status = check_url(url_or_ip)
+ salida[f"{nombre}_url"] = url_or_ip
+ salida[f"{nombre}_status"] = status
+ salida[f"{nombre}_state"] = human_state(status)
+ continue
+
+ salida[f"{nombre}_url"] = url_or_ip
+ salida[f"{nombre}_status"] = status_message
+ salida[f"{nombre}_state"] = status_message
+ return salida
+
+def main():
+ start_time = time.time()
+
+ resultado = {
+ "timestamp": datetime.now(timezone.utc).isoformat(),
+ "internos": build_section(INTERNOS),
+ "empresa": build_section(SITIOS_EMPRESA),
+ "externos": build_section(EXTERNOS)
+ }
+
+ end_time = time.time()
+ execution_time = round(end_time - start_time, 2)
+ resultado["execution_time_seconds"] = execution_time
+
+ for url in WEBHOOK_URLS:
+ try:
+ resp = requests.post(url, json=resultado, timeout=10)
+ except requests.RequestException:
+ pass
+
+ print(json.dumps(resultado, indent=4))
+
+if __name__ == "__main__":
+ main()
diff --git a/server.js b/server.js
index 6a9c1a5..73d3e0a 100644
--- a/server.js
+++ b/server.js
@@ -1,5 +1,6 @@
const express = require("express");
const path = require("path");
+const fs = require("fs");
const { exec } = require("child_process");
@@ -12,13 +13,26 @@ app.use(express.static(rootDir, { index: "index.html" }));
// Health checker should always return the raw script with text/plain
app.get("/healthchecker", (req, res) => {
- res.type("text/plain");
- res.sendFile(path.join(rootDir, "scripts", "health_checker"));
+ const pythonScriptPath = path.join(rootDir, "scripts", "health_checker.py");
+
+ exec(`python3 ${pythonScriptPath}`, (error, stdout, stderr) => {
+ if (error) {
+ console.error(`Error executing health_checker.py: ${stderr}`);
+ return res.status(500).json({ error: "Failed to execute health checker" });
+ }
+ try {
+ const healthData = JSON.parse(stdout);
+ res.status(200).json(healthData);
+ } catch (parseErr) {
+ console.error(`Error parsing health checker output: ${parseErr}`);
+ res.status(500).json({ error: "Failed to parse health checker output" });
+ }
+ });
});
// Magic link para redirigir a la app de Telegram según plataforma
app.get("/telegram", (req, res) => {
- res.sendFile(path.join(rootDir, "telegram.html"));
+ res.sendFile(path.join(rootDir, "htmls", "telegram.html"));
});
// Standard health check endpoint for monitoring with VPS ping
@@ -41,6 +55,28 @@ app.get("/health", (req, res) => {
});
});
+// Endpoint to get a random phrase
+app.get("/day-quote", (req, res) => {
+ fs.readFile(path.join(rootDir, "data", "quotes.json"), "utf8", (err, data) => {
+ if (err) {
+ console.error("Error reading quotes file:", err);
+ return res.status(500).json({ error: "Could not read quotes file" });
+ }
+ try {
+ const quotes = JSON.parse(data);
+ const phrases = quotes.phrases;
+ if (!phrases || phrases.length === 0) {
+ return res.status(500).json({ error: "No phrases found" });
+ }
+ const randomPhrase = phrases[Math.floor(Math.random() * phrases.length)];
+ res.status(200).json({ phrase: randomPhrase });
+ } catch (parseErr) {
+ console.error("Error parsing quotes file:", parseErr);
+ return res.status(500).json({ error: "Could not parse quotes file" });
+ }
+ });
+});
+
// Endpoint to get the current time in multiple formats
app.get("/time-server", (req, res) => {
const now = new Date();
diff --git a/zshrc_debug.zsh b/zshrc_debug.zsh
deleted file mode 100644
index 896ffc9..0000000
--- a/zshrc_debug.zsh
+++ /dev/null
@@ -1,449 +0,0 @@
-# =============================================================================
-# CONFIGURACIÓN ZSH - Marco Gallegos v3.1
-# =============================================================================
-#
-# Este archivo configura el entorno de la terminal Zsh. Incluye la
-# configuración del PATH, la carga de Oh My Zsh, la inicialización de
-# Oh My Posh, y una colección de alias y funciones para mejorar la
-# productividad.
-#
-# =============================================================================
-
-# --- PATH --------------------------------------------------------------------
-# Define las rutas donde el sistema buscará los programas ejecutables.
-# `typeset -U` se asegura de que no haya rutas duplicadas.
-typeset -U PATH path
-path=(
- $HOME/.local/bin # Scripts y binarios instalados por el usuario.
- $HOME/bin # Directorio personal de binarios.
- $HOME/.npm-global/bin # Paquetes de Node.js instalados globalmente.
- $HOME/AppImages # Aplicaciones en formato AppImage.
- $HOME/go/bin # Binarios de Go.
- $path # Rutas del sistema existentes.
-)
-
-# --- Oh My Zsh ---------------------------------------------------------------
-# Configuración y carga del framework Oh My Zsh.
-export ZSH="$HOME/.oh-my-zsh"
-# El tema se deja vacío porque Oh My Posh se encargará de gestionar el prompt.
-ZSH_THEME=""
-
-# Lista de plugins de Oh My Zsh a cargar.
-plugins=(
- git sudo history colorize
- docker docker-compose
- npm node python pip golang
- copypath copyfile
-)
-
-# Desactiva la comprobación de seguridad de Oh My Zsh para directorios
-# con permisos de escritura para otros usuarios, lo que puede ser molesto.
-export ZSH_DISABLE_COMPFIX=true
-# Configuración de la caché de autocompletado para mejorar el rendimiento.
-zstyle ':completion::complete:*' use-cache on
-zstyle ':completion::complete:*' cache-path "$HOME/.zcompcache"
-# Hace que el autocompletado no distinga entre mayúsculas y minúsculas.
-zstyle ':completion:*' matcher-list 'm:{a-z}={A-Za-z}'
-# Habilita colores en el menú de autocompletado.
-zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
-zstyle ':completion:*' menu select
-
-# Carga Oh My Zsh.
-[ -r "$ZSH/oh-my-zsh.sh" ] && source "$ZSH/oh-my-zsh.sh"
-
-# Carga los plugins de resaltado de sintaxis y autosugerencias.
-# Intenta cargar la versión instalada con Oh My Zsh y, si no la encuentra,
-# busca la versión instalada en el sistema.
-[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && \
- source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh"
-if [ ! -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ] && \
- [ -r "/usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh" ]; then
- source "/usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh"
-fi
-
-[ -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && \
- source "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
-if [ ! -r "${ZSH_CUSTOM:-$ZSH/custom}/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ] && \
- [ -r "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" ]; then
- source "/usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh"
-fi
-
-# --- Oh My Posh --------------------------------------------------------------
-# Inicializa Oh My Posh para personalizar el prompt.
-if command -v oh-my-posh >/dev/null 2>&1; then
- # Carga el tema Catppuccin Frappe si existe.
- if [ -f ~/.poshthemes/catppuccin_frappe.omp.json ]; then
- eval "$(oh-my-posh init zsh --config ~/.poshthemes/catppuccin_frappe.omp.json)"
- else
- # Si no, carga el tema por defecto.
- eval "$(oh-my-posh init zsh)"
- fi
-fi
-
-# --- Go ----------------------------------------------------------------------
-# Configura las variables de entorno para el lenguaje de programación Go.
-export GOPATH="$HOME/go"
-export GOBIN="$GOPATH/bin"
-
-# --- NVM (Node Version Manager) ----------------------------------------------
-# COMENTADO: NVM deshabilitado porque estamos usando mise para gestionar Node.js
-# Si deseas usar NVM en lugar de mise, descomenta estas líneas y comenta la
-# sección de mise más abajo.
-#export NVM_DIR="$HOME/.nvm"
-#[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
-#[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
-
-# --- Python ------------------------------------------------------------------
-# Alias para usar las versiones 3 de python y pip por defecto.
-alias pip='pip3'
-alias python='python3'
-
-# Función para gestionar entornos virtuales de Python.
-venv() {
- case "$1" in
- create) python -m venv .venv && echo "✅ Entorno virtual creado en ./.venv" ;;
- on|activate)
- if [ -f ".venv/bin/activate" ]; then
- . .venv/bin/activate
- echo "🟢 Entorno virtual activado"
- else
- echo "❌ Entorno virtual no encontrado en ./.venv"
- fi
- ;;
- off|deactivate)
- if command -v deactivate &>/dev/null; then
- deactivate 2>/dev/null
- echo "🔴 Entorno virtual desactivado"
- else
- echo "🤷 No hay un entorno virtual activo para desactivar"
- fi
- ;;
- *) echo "Uso: venv [create|on|off|activate|deactivate]" ;;
- esac
-}
-
-# --- Aliases -----------------------------------------------------------------
-# Colección de atajos para comandos comunes.
-
-# Generales
-alias cls='clear'
-alias ll='ls -alF'
-alias la='ls -A'
-alias l='ls -CF'
-alias ..='cd ..'
-alias ...='cd ../..'
-alias ....='cd ../../..'
-
-# Información del sistema
-alias ff='fastfetch'
-alias nf='fastfetch'
-
-# Gestión de paquetes en Arch Linux
-alias pacu='sudo pacman -Syu'
-alias paci='sudo pacman -S'
-alias pacr='sudo pacman -Rns'
-alias pacs='pacman -Ss'
-alias yayu='yay -Syu' # Requiere yay
-alias yayi='yay -S' # Requiere yay
-
-# Git
-alias gs='git status'
-alias ga='git add'
-alias gc='git commit'
-alias gcm='git commit -m'
-alias gfa='git fetch --all'
-alias gfr='git fetch origin'
-alias gp='git push'
-alias gl='git pull'
-alias gd='git diff'
-alias gb='git branch'
-alias gco='git checkout'
-alias gcb='git checkout -b'
-alias glog='git log --oneline --graph --decorate'
-gac(){ git add . && git commit -m "$1"; }
-
-# Docker
-# Detecta si se usa `docker compose` (nuevo) o `docker-compose` (antiguo).
-docker compose version >/dev/null 2>&1 && alias dc='docker compose' || alias dc='docker-compose'
-alias d='docker'
-alias dps='docker ps -a'
-alias di='docker images'
-alias dex='docker exec -it'
-alias dlog='docker logs -f'
-
-# NPM
-alias nrs='npm run start'
-alias nrd='npm run dev'
-alias nrb='npm run build'
-alias nrt='npm run test'
-alias ni='npm install'
-alias nid='npm install --save-dev'
-alias nig='npm install -g'
-
-# Python
-alias py='python'
-alias pir='pip install -r requirements.txt'
-alias pipi='pip install'
-alias pipf='pip freeze > requirements.txt'
-
-# ZeroTier
-alias zt='sudo zerotier-cli'
-alias ztstatus='sudo zerotier-cli listnetworks'
-alias ztinfo='sudo zerotier-cli info'
-
-# Utilidades
-alias clima='curl wttr.in/Saltillo'
-
-# --- IA y ChatGPT ------------------------------------------------------------
-# Alias para un cliente de ChatGPT en la terminal (ej. 'chatgpt-cli').
-# Reemplaza 'chatgpt-cli' por el nombre del programa que uses.
-#
-# alias chat='chatgpt-cli'
-# alias chat-q='chatgpt-cli -q' # Para una pregunta rápida sin guardar en el historial.
-# alias chat-c='chatgpt-cli --continue' # Para continuar la conversación anterior.
-# alias chat-code='chatgpt-cli --code' # Para preguntas de código.
-
-# --- Funciones ---------------------------------------------------------------
-# Funciones personalizadas para tareas comunes.
-
-# Crea un directorio y se mueve a él.
-mkcd(){ mkdir -p "$1" && cd "$1"; }
-
-# Extrae cualquier tipo de archivo comprimido.
-extract(){
- [ ! -f "$1" ] && echo "No es un archivo" && return 1
- case "$1" in
- *.tar.bz2) tar xjf "$1" ;;
- *.tar.gz) tar xzf "$1" ;;
- *.bz2) bunzip2 "$1" ;;
- *.rar) unrar e "$1" ;;
- *.gz) gunzip "$1" ;;
- *.tar) tar xf "$1" ;;
- *.tbz2) tar xjf "$1" ;;
- *.tgz) tar xzf "$1" ;;
- *.zip) unzip "$1" ;;
- *.Z) uncompress "$1" ;;
- *.7z) 7z x "$1" ;;
- *) echo "No se puede extraer '$1': formato no reconocido." ;;
- esac
-}
-
-# Mata el proceso que esté usando un puerto específico.
-killport(){
- [ $# -eq 0 ] && echo "Uso: killport
" && return 1
- local pid=$(lsof -ti:"$1" 2>/dev/null)
- [ -n "$pid" ] && kill -9 "$pid" && echo "✅ Proceso en puerto $1 eliminado (PID: $pid)" || echo "🤷 No se encontró ningún proceso en el puerto $1"
-}
-
-# Inicia un servidor HTTP simple en el directorio actual.
-serve(){ python -m http.server "${1:-8000}"; }
-
-# Carga el archivo de ayuda si existe
-[ -f ~/.zshrc.help ] && source ~/.zshrc.help
-
-
-# --- yt-dlp (Descargador de vídeos) ------------------------------------------
-# Funciones mejoradas para descargar audio y video desde YouTube.
-export YTDLP_DIR="$HOME/Videos/YouTube"
-mkdir -p "$YTDLP_DIR"/{Music,Videos} 2>/dev/null
-
-# Descarga audio en formato MP3.
-ytm() {
- case "$1" in
- -h|--help|'')
- echo "🎵 ytm - Descarga audio (MP3 320kbps) a $YTDLP_DIR/Music/"
- echo "Ejemplos:"
- echo " ytm https://youtu.be/dQw4w9WgXcQ"
- echo " ytm 'Never Gonna Give You Up'"
- return 0
- ;;
- esac
-
- if ! command -v yt-dlp &>/dev/null; then
- echo "❌ yt-dlp no está instalado. Por favor, instálalo para usar esta función."
- return 1
- fi
-
- local out="$YTDLP_DIR/Music/%(title).180s.%(ext)s"
- local opts=(
- --extract-audio --audio-format mp3 --audio-quality 320K
- --embed-metadata --embed-thumbnail --convert-thumbnails jpg
- --no-playlist --retries 10 --fragment-retries 10
- --user-agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
- --extractor-args "youtube:player_client=android,web"
- --progress --newline -o "$out"
- )
-
- if [[ "$1" == http* ]]; then
- echo "📥 Descargando audio..."
- yt-dlp "${opts[@]}" "$@"
- else
- echo "🔍 Buscando: $*"
- yt-dlp "${opts[@]}" "ytsearch1:$*"
- fi
-
- [ $? -eq 0 ] && echo "✅ Audio descargado en: $YTDLP_DIR/Music/" || echo "❌ Falló la descarga de audio."
-}
-
-# Descarga vídeo en formato MP4.
-ytv() {
- case "$1" in
- -h|--help|'')
- echo "🎬 ytv [calidad] - Descarga video a $YTDLP_DIR/Videos/"
- echo "Calidades disponibles: 1080, 720, 480 (por defecto: mejor disponible MP4)"
- echo "Ejemplos:"
- echo " ytv https://youtu.be/dQw4w9WgXcQ 1080"
- echo " ytv 'Rick Astley - Never Gonna Give You Up' 720"
- return 0
- ;;
- esac
-
- if ! command -v yt-dlp &>/dev/null; then
- echo "❌ yt-dlp no está instalado. Por favor, instálalo para usar esta función."
- return 1
- fi
-
- local quality="${2:-best}"
- local out="$YTDLP_DIR/Videos/%(title).180s.%(ext)s"
-
- local fmt
- case "$quality" in
- 1080) fmt='bv*[height<=1080][ext=mp4]+ba/b[height<=1080]' ;;
- 720) fmt='bv*[height<=720][ext=mp4]+ba/b[height<=720]' ;;
- 480) fmt='bv*[height<=480][ext=mp4]+ba/b[height<=480]' ;;
- *) fmt='bv*[ext=mp4]+ba/b[ext=mp4]/b' ;; # Mejor calidad MP4
- esac
-
- local opts=(
- -f "$fmt" --embed-metadata --embed-thumbnail
- --embed-subs --sub-langs "es.*,en.*" --convert-thumbnails jpg
- --no-playlist --retries 10 --fragment-retries 10
- --user-agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
- --extractor-args "youtube:player_client=android,web"
- --progress --newline -o "$out"
- )
-
- if [[ "$1" == http* ]]; then
- echo "📥 Descargando video..."
- yt-dlp "${opts[@]}" "$1"
- else
- echo "🔍 Buscando: $1"
- yt-dlp "${opts[@]}" "ytsearch1:$1"
- fi
-
- [ $? -eq 0 ] && echo "✅ Video descargado en: $YTDLP_DIR/Videos/" || echo "❌ Falló la descarga de video."
-}
-
-# Lista los últimos archivos descargados.
-ytls() {
- echo "🎵 Últimos 5 audios descargados en Music:"
- ls -1t "$YTDLP_DIR/Music" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacío)"
- echo ""
- echo "🎬 Últimos 5 videos descargados en Videos:"
- ls -1t "$YTDLP_DIR/Videos" 2>/dev/null | head -5 | sed 's/^/ /' || echo " (vacío)"
-}
-
-# --- GNOME Keyring y Agente SSH ----------------------------------------------
-# Configuración para que GNOME Keyring gestione las claves SSH.
-if [ -n "$DESKTOP_SESSION" ] && command -v gnome-keyring-daemon >/dev/null 2>&1; then
- if ! pgrep -u "$USER" gnome-keyring-daemon > /dev/null 2>&1; then
- eval "$(gnome-keyring-daemon --start --components=pkcs11,secrets,ssh 2>/dev/null)" || true
- fi
- export SSH_AUTH_SOCK GPG_AGENT_INFO GNOME_KEYRING_CONTROL GNOME_KEYRING_PID
-fi
-
-# Fallback a un agente SSH estándar si GNOME Keyring no está disponible.
-if [ -z "$SSH_AUTH_SOCK" ]; then
- export SSH_AGENT_DIR="$HOME/.ssh/agent"
- mkdir -p "$SSH_AGENT_DIR"
- SSH_ENV="$SSH_AGENT_DIR/env"
-
- start_agent() {
- echo "🔑 Iniciando ssh-agent..."
- ssh-agent > "$SSH_ENV"
- chmod 600 "$SSH_ENV"
- . "$SSH_ENV" > /dev/null
- }
-
- if [ -f "$SSH_ENV" ]; then
- . "$SSH_ENV" > /dev/null
- ps -p $SSH_AGENT_PID > /dev/null 2>&1 || start_agent
- else
- start_agent
- fi
-
- if [ -d "$HOME/.ssh" ]; then
- for key in "$HOME/.ssh"/*; do
- if [ -f "$key" ] && [[ ! "$key" =~ \.pub$ ]] && \
- [[ ! "$key" =~ known_hosts ]] && [[ ! "$key" =~ authorized_keys ]] && \
- [[ ! "$key" =~ config ]] && [[ ! "$key" =~ agent ]]; then
- if ssh-keygen -l -f "$key" &>/dev/null; then
- local key_fingerprint=$(ssh-keygen -lf "$key" 2>/dev/null | awk '{print $2}')
- if ! ssh-add -l 2>/dev/null | grep -q "$key_fingerprint"; then
- if ssh-add "$key" 2>/dev/null; then
- echo "✅ Llave SSH agregada: $(basename $key)"
- fi
- fi
- fi
- fi
- done
- fi
-fi
-
-# Alias para gestionar el agente SSH.
-alias ssh-list='ssh-add -l'
-alias ssh-clear='ssh-add -D'
-alias ssh-reload='
- ssh-add -D 2>/dev/null
- for key in ~/.ssh/*; do
- if [ -f "$key" ] && [[ ! "$key" =~ \.pub$ ]] && ssh-keygen -l -f "$key" &>/dev/null; then
- ssh-add "$key" 2>/dev/null && echo "✅ $(basename $key)"
- fi
- done
-'
-alias ssh-github='ssh -T git@github.com'
-
-# --- zoxide ------------------------------------------------------------------
-# Reemplazo inteligente de `cd` que recuerda los directorios que visitas.
-if command -v zoxide >/dev/null 2>&1; then
- eval "$(zoxide init zsh)"
- alias zz='z -' # Ir al directorio anterior
- alias zi='zi' # Modo interactivo
-fi
-
-# --- Historial de Zsh --------------------------------------------------------
-# Configuración para un historial de comandos más útil y persistente.
-HISTSIZE=100000
-SAVEHIST=100000
-HISTFILE=~/.zsh_history
-setopt APPEND_HISTORY SHARE_HISTORY HIST_IGNORE_DUPS HIST_IGNORE_ALL_DUPS HIST_IGNORE_SPACE AUTO_CD EXTENDED_GLOB
-
-# Deshabilita el bloqueo de la terminal con CTRL+S.
-stty -ixon 2>/dev/null
-
-# Habilita colores en `man` y `less`.
-export LESS='-R'
-
-# --- Funciones y Configuraciones Locales -------------------------------------
-# Carga archivos de funciones personalizadas desde ~/.zsh_functions/
-[ -d "$HOME/.zsh_functions" ] || mkdir -p "$HOME/.zsh_functions"
-for func_file in "$HOME/.zsh_functions"/*.zsh(N); do
- source "$func_file"
-done
-
-# Carga un archivo de configuración local (~/.zshrc.local) si existe.
-# Ideal para añadir variables de entorno y configuraciones privadas.
-[ -f ~/.zshrc.local ] && source ~/.zshrc.local
-
-# --- mise (Gestor de versiones de herramientas) ------------------------------
-# IMPORTANTE: Esta sección debe ir AL FINAL del archivo para que mise pueda
-# sobrescribir correctamente el PATH y usar las versiones configuradas.
-# mise gestiona versiones de Node.js, Python, y otras herramientas de desarrollo.
-if command -v mise >/dev/null 2>&1; then
- eval "$(mise activate zsh)"
- # Alias útiles para mise
- alias mise-list='mise list'
- alias mise-current='mise current'
- alias mise-install='mise install'
- alias mise-use='mise use'
-fi
diff --git a/zshrc_help.zsh b/zshrc_help.zsh
deleted file mode 100644
index b0f09d4..0000000
--- a/zshrc_help.zsh
+++ /dev/null
@@ -1,127 +0,0 @@
-# --- Funciones de Ayuda ------------------------------------------------------
-# Muestra una lista detallada de todos los alias y funciones personalizadas.
-# Soporta modo interactivo con fzf si está instalado.
-zsh_help() {
- # --- Colores ---
- local C_DEFAULT="\e[0m"
- local C_BOLD="\e[1m"
- local C_TITLE="\e[1;35m" # Bold Magenta
- local C_SUBTITLE="\e[1;36m" # Bold Cyan
- local C_SECTION="\e[1;34m" # Bold Blue
- local C_CMD="\e[0;32m" # Green
- local C_DESC="\e[0;37m" # White
- local C_NOTE="\e[0;90m" # Gray
-
- # --- Componentes de la Ayuda ---
-
- _help_header() {
- clear
- echo -e "${C_TITLE}╔════════════════════════════════════════════════════════════════════╗"
- echo -e "${C_TITLE}║ GUÍA DEL SISTEMA Y CONFIGURACIÓN DE ZSH ║"
- echo -e "${C_TITLE}╚════════════════════════════════════════════════════════════════════╝${C_DEFAULT}"
- }
-
- _help_print_section() { echo -e "\n${C_SECTION}--- $1 ---${C_DEFAULT}"; }
- _help_print_cmd() { printf " ${C_CMD}%-18s ${C_DESC}%s\n${C_DEFAULT}" "$1" "$2"; }
-
- _help_nav() {
- _help_print_section "Navegación y Archivos"
- _help_print_cmd ".." "Subir un nivel (cd ..)"
- _help_print_cmd "..." "Subir dos niveles (cd ../..)"
- _help_print_cmd "ll" "Listar con detalles (ls -alF)"
- _help_print_cmd "mkcd " "Crear directorio y entrar en él"
- _help_print_cmd "z " "Saltar a directorio (zoxide)"
- _help_print_cmd "zi" "Seleccionar directorio interactivo"
- _help_print_cmd "zz" "Volver al directorio anterior (z -)"
- _help_print_cmd "extract " "Descomprimir (zip, tar, rar...)"
- }
-
- _help_git() {
- _help_print_section "Git - Flujo de Trabajo"
- _help_print_cmd "gs" "Ver estado (git status)"
- _help_print_cmd "ga" "Añadir cambios (git add)"
- _help_print_cmd "gc" "Guardar cambios (git commit)"
- _help_print_cmd "gcm " "Guardar con mensaje"
- _help_print_cmd "gac " "Añadir Y Guardar todo"
- _help_print_cmd "gp" "Subir cambios (git push)"
- _help_print_cmd "gl" "Bajar cambios (git pull)"
- _help_print_cmd "gfa" "Traer todo (git fetch --all)"
- _help_print_cmd "gfr" "Traer origen (git fetch origin)"
- }
-
- _help_docker() {
- _help_print_section "Docker - Contenedores"
- _help_print_cmd "dps" "Ver contenedores"
- _help_print_cmd "dc" "Docker Compose"
- _help_print_cmd "dex " "Entrar a terminal de contenedor"
- _help_print_cmd "dlog " "Ver logs en tiempo real"
- }
-
- _help_dev() {
- _help_print_section "Desarrollo"
- _help_print_cmd "py / python" "Ejecuta python3"
- _help_print_cmd "pip" "Ejecuta pip3"
- _help_print_cmd "venv create" "Crea entorno virtual (.venv)"
- _help_print_cmd "venv on" "Activa entorno virtual"
- _help_print_cmd "serve" "Servidor web en puerto 8000"
- _help_print_cmd "nrd" "npm run dev"
- }
-
- _help_utils() {
- _help_print_section "Utilidades"
- _help_print_cmd "ff / nf" "Info del sistema (Fastfetch)"
- _help_print_cmd "killport " "Matar proceso en puerto N"
- _help_print_cmd "clima" "Ver pronóstico del tiempo"
- _help_print_cmd "ytm " "Descargar música (MP3)"
- _help_print_cmd "ytv " "Descargar video (MP4)"
- }
-
- _help_all() {
- _help_header
- echo -e "\n${C_SUBTITLE}Resumen del Sistema:${C_DEFAULT}"
- echo -e " • ${C_BOLD}Framework:${C_DEFAULT} Oh My Zsh"
- echo -e " • ${C_BOLD}Plugins:${C_DEFAULT} git, docker, npm, python..."
- _help_nav
- _help_git
- _help_docker
- _help_dev
- _help_utils
- echo -e "\n${C_NOTE}Tip: Usa 'help' sin argumentos para el menú interactivo.${C_DEFAULT}\n"
- }
-
- _wait_for_key() {
- echo ""
- read -k 1 "key?Presiona cualquier tecla para volver..."
- }
-
- # --- Lógica Principal ---
- if [[ "$1" == "--all" ]]; then
- _help_all
- return 0
- fi
-
- # Si fzf está instalado, mostrar menú interactivo en bucle
- if command -v fzf >/dev/null 2>&1; then
- while true; do
- local options="Todo\nNavegación\nGit\nDocker\nDesarrollo\nUtilidades\nSalir (q)"
- local selected=$(echo -e "$options" | fzf --ansi --height=40% --layout=reverse --border --prompt="Ayuda > " --header="Selecciona un tema")
-
- case "$selected" in
- "Todo") _help_all; _wait_for_key ;;
- "Navegación") _help_header; _help_nav; _wait_for_key ;;
- "Git") _help_header; _help_git; _wait_for_key ;;
- "Docker") _help_header; _help_docker; _wait_for_key ;;
- "Desarrollo") _help_header; _help_dev; _wait_for_key ;;
- "Utilidades") _help_header; _help_utils; _wait_for_key ;;
- "Salir (q)"|"") break ;;
- esac
- done
- else
- # Fallback si no hay fzf
- _help_all
- fi
-}
-
-# Alias para acceder a la función de ayuda.
-alias zsh-help='zsh_help'
-alias help='zsh_help'
diff --git a/zshrc_help.zsh.bak b/zshrc_help.zsh.bak
deleted file mode 100644
index d5ee814..0000000
--- a/zshrc_help.zsh.bak
+++ /dev/null
@@ -1,109 +0,0 @@
-# --- Funciones de Ayuda ------------------------------------------------------
-# Muestra una lista de todos los alias y funciones personalizadas.
-zsh_help() {
- # --- Colores ---
- local C_DEFAULT="\e[0m"
- local C_BOLD="\e[1m"
- local C_TITLE="\e[1;35m" # Bold Magenta
- local C_SECTION="\e[1;34m" # Bold Blue
- local C_CMD="\e[0;32m" # Green
- local C_DESC="\e[0;37m" # White
- local C_HL="\e[0;33m" # Yellow
-
- # --- Encabezado ---
- echo -e "${C_TITLE}╔═════════════════════════════════════════════════════════╗"
- echo -e "${C_TITLE}║ AYUDA DE LA CONFIGURACIÓN DE ZSH - Comandos ║"
- echo -e "${C_TITLE}╚═════════════════════════════════════════════════════════╝${C_DEFAULT}"
-
- # --- Función para imprimir secciones ---
- print_section() {
- echo -e "\n${C_SECTION}--- $1 ---${C_DEFAULT}"
- }
-
- # --- Función para imprimir comandos ---
- print_command() {
- printf " ${C_CMD}%-15s ${C_DESC}%s\n${C_DEFAULT}" "$1" "$2"
- }
-
- # --- Alias Generales ---
- print_section "Alias Generales"
- print_command "cls" "Limpia la pantalla."
- print_command "ll" "Lista archivos en formato largo."
- print_command "la" "Lista todos los archivos (incluyendo ocultos)."
- print_command "l" "Lista archivos en columnas."
- print_command ".." "Sube un nivel en el árbol de directorios."
- print_command "..." "Sube dos niveles."
- print_command "...." "Sube tres niveles."
- print_command "ff / nf" "Muestra información del sistema (fastfetch)."
-
- # --- Gestión de Paquetes (Arch) ---
- print_section "Gestión de Paquetes (Arch Linux)"
- print_command "pacu" "Actualiza el sistema (pacman)."
- print_command "paci" "Instala un paquete (pacman)."
- print_command "pacr" "Elimina un paquete (pacman)."
- print_command "pacs" "Busca un paquete (pacman)."
- print_command "yayu" "Actualiza el sistema (yay)."
- print_command "yayi" "Instala un paquete (yay)."
-
- # --- Git ---
- print_section "Git"
- print_command "gs" "git status"
- print_command "ga" "git add"
- print_command "gc" "git commit"
- print_command "gcm" "git commit -m '...'"
- print_command "gac " "git add . && git commit -m ''"
- print_command "gp" "git push"
- print_command "gl" "git pull"
- print_command "gd" "git diff"
- print_command "gb" "git branch"
- print_command "gco" "git checkout"
- print_command "gcb" "git checkout -b"
- print_command "glog" "Muestra un log de commits formateado."
-
- # --- Docker ---
- print_section "Docker"
- print_command "d" "docker"
- print_command "dc" "docker compose"
- print_command "dps" "Muestra todos los contenedores."
- print_command "di" "Muestra todas las imágenes."
- print_command "dex " "Ejecuta una terminal en un contenedor."
- print_command "dlog " "Muestra los logs de un contenedor."
-
- # --- Python ---
- print_section "Python"
- print_command "py" "python3"
- print_command "pip" "pip3"
- print_command "pipi" "pip install ..."
- print_command "pir" "pip install -r requirements.txt"
- print_command "pipf" "pip freeze > requirements.txt"
- print_command "venv create" "Crea un entorno virtual."
- print_command "venv on" "Activa el entorno virtual."
- print_command "venv off" "Desactiva el entorno virtual."
- print_command "serve [port]" "Inicia un servidor HTTP (puerto 8000 por defecto)."
-
- # --- Funciones de Utilidad ---
- print_section "Funciones de Utilidad"
- print_command "mkcd " "Crea un directorio y entra en él."
- print_command "extract " "Extrae cualquier archivo comprimido."
- print_command "killport " "Mata el proceso que usa un puerto."
- print_command "clima" "Muestra el clima de Saltillo."
- print_command "zsh-help" "Muestra esta ayuda."
-
- # --- Descargas (yt-dlp) ---
- print_section "Descargas (yt-dlp)"
- print_command "ytm " "Descarga audio de YouTube como MP3."
- print_command "ytv " "Descarga video de YouTube como MP4."
- print_command "ytls" "Lista los últimos 5 archivos descargados."
-
- # --- Agente SSH ---
- print_section "Agente SSH"
- print_command "ssh-list" "Lista las llaves SSH cargadas."
- print_command "ssh-clear" "Elimina todas las llaves del agente."
- print_command "ssh-reload" "Recarga todas las llaves SSH."
- print_command "ssh-github" "Prueba la conexión SSH con GitHub."
- echo ""
-}
-
-# Alias para acceder a la función de ayuda.
-alias zsh-help='zsh_help'
-alias help='zsh_help'
diff --git a/zshrc_local.zsh b/zshrc_local.zsh
deleted file mode 100644
index e187699..0000000
--- a/zshrc_local.zsh
+++ /dev/null
@@ -1,19 +0,0 @@
-# =============================================================================
-# CONFIGURACIÓN LOCAL ZSH - .zshrc.local
-# =============================================================================
-#
-# Este archivo se carga automáticamente desde .zshrc si existe.
-# Úsalo para configuraciones específicas de esta máquina, claves privadas,
-# tokens de API, o alias que no quieres sincronizar en tu dotfiles público.
-#
-# =============================================================================
-
-# --- Variables de Entorno Privadas ---
-# export GITHUB_TOKEN="tu_token_aqui"
-# export OPENAI_API_KEY="sk-..."
-
-# --- Alias Locales ---
-# alias work="cd /path/to/work"
-
-# --- Configuraciones Específicas ---
-# git config --global user.email "marco@trabajo.com"