Crea un centinela para tu GitHub que te avise de cositas
Agente local que vigila tus repositorios de GitHub, detecta nuevas issues y
te prepara un resumen + propuesta de solución usando un LLM vía API compatible
con OpenAI, todo sin salir de tu red si apuntas a un servidor local.
Pensado para correr 24/7 en un MiniPC o servidor (Windows o macOS).
┌─ cron interno (cada N min) ──────────────────────────────────┐
│ → GitHub REST API (issues + metadata) │
│ → SQLite local (issues vistas, no duplicar) │
│ → LLM API compatible OpenAI (resumen + riesgo + propuesta) │
│ → Dashboard React (terminal-style, Geist Pixel / Mono) │
└──────────────────────────────────────────────────────────────┘
bun:sqlite (modo WAL)Sin dependencias extra de Node.js, Express, dotenv, better-sqlite3 ni nada por el estilo.
/api/health) y status (/api/status).Requisito: Bun ≥ 1.3.
bun install
cp .env.example .env # edita y añade tu GITHUB_TOKEN
bun dev # http://localhost:3741
bun dev arranca con HMR activo. Para producción local usa bun start.
Bun carga .env automáticamente. Variables:
| Variable | Por defecto | Descripción |
|---|---|---|
GITHUB_TOKEN |
(vacío) | Fine-grained PAT con permisos read-only de Issues + Metadata sobre los repos a vigilar. Recomendado, sin token estás limitado a 60 req/h. |
GITHUB_USER |
(vacío) | Tu usuario, solo para mostrar en el header. Ej: midudev. |
LLM_URL |
http://localhost:1234/v1 |
URL base del servidor compatible con OpenAI. Debe exponer /models y /chat/completions. Puede apuntar a otra máquina de la LAN. |
LLM_MODEL |
local-model |
Nombre del modelo a usar en las llamadas chat/completions. |
LLM_API_KEY |
sentinel-local |
Bearer token para servidores que lo requieran. Si tu servidor local no valida auth, puede ser cualquier string. |
SENTINEL_INTERVAL_MS |
1800000 (30 min) |
Cada cuánto hacer el barrido. |
SENTINEL_DB_PATH |
data/sentinel.db |
Ruta al SQLite. Puede ser absoluta. |
PORT |
3741 |
Puerto del servidor. |
HOST |
0.0.0.0 |
Interfaz a la que bindear. Déjalo así para acceder desde la LAN. |
Token recomendado: github.com/settings/personal-access-tokens/new → “Only select repositories” → solo los que quieras vigilar → permisos
Issues: Read-onlyyMetadata: Read-only.
| Método | Ruta | Descripción |
|---|---|---|
GET |
/api/health |
Healthcheck simple (uptime, pid, plataforma). Útil para monitorización externa. |
GET |
/api/status |
Estado completo: contadores, LLM, último scan. |
GET |
/api/repos |
Lista repos vigilados. |
POST |
/api/repos |
Añadir repo. Body: { "repo": "owner/name" }. |
DELETE |
/api/repos/:id |
Dejar de vigilar. |
GET |
/api/issues?limit=N |
Issues con su análisis. |
POST |
/api/issues/:id/analyze |
Forzar análisis LLM de una issue. |
POST |
/api/check |
Disparar un scan inmediato. |
src/
server/
index.ts # Bun.serve + rutas + shutdown handler
db.ts # bun:sqlite, schema y queries preparadas
github.ts # cliente GitHub REST (fetch, sin Octokit)
llm.ts # cliente LLM compatible OpenAI, JSON forzado
sentinel.ts # scheduler de polling + analyzer en background
client/
index.html
main.tsx # entry React
App.tsx
api.ts # cliente tipado del API
styles.css # @font-face + @theme Tailwind 4
utils.ts
fonts/ # Geist Pixel + Geist Mono (.woff2)
components/
Header.tsx
Stats.tsx
AddRepoForm.tsx
RepoList.tsx
IssueCard.tsx
public/
favicon.svg
scripts/
service.ts # wrapper cross-platform (Windows/macOS)
win/
install.ps1 # NSSM install
uninstall.ps1 # NSSM uninstall
macos/
sentinel.plist.template # plantilla launchd
data/ # generado en runtime (sqlite + logs)
Todo se hace con un único set de scripts de package.json. El wrapper
scripts/service.ts detecta la plataforma y delega
en el backend correcto: NSSM en Windows, launchd en macOS.
bun service:install # instala y arranca como servicio del sistema
bun service:uninstall # detiene, desinstala y opcionalmente borra data/
bun service:start
bun service:stop
bun service:restart
bun service:status
bun service:logs # tail -f del log en data/sentinel.log
En ambos sistemas, al instalar:
KeepAlive en launchd).data/sentinel.log.kill -9, así que el shutdown handler cierra SQLite limpio.%USERPROFILE%\.bun\bin\bun.exe).choco install nssmscoop install nssmservice:install y service:uninstall.# Desde la carpeta del proyecto, en PowerShell admin:
bun install
bun service:install
El backend Windows ejecuta scripts/win/install.ps1
que registra el servicio GitHubSentinel con NSSM:
bun.exe src/server/index.tsdata\sentinel.log, max 5 MB o 24 h por archivo.~/.bun/bin/bun, Homebrew o /usr/local).sudo porque el servicio se instala como LaunchAgent~/Library/LaunchAgents/com.midudev.github-sentinel.plist).bun install
bun service:install
El backend macOS renderiza el plist desde scripts/macos/sentinel.plist.template,
sustituye __PROJECT_DIR__, __BUN_PATH__ y __PATH__, lo copia a
~/Library/LaunchAgents/ y hace launchctl load -w. KeepAlive=true y
RunAtLoad=true se encargan del resto.
Si quieres llamarlo de otra forma:
$env:SENTINEL_SERVICE_NAME = "MiSentinel"
bun service:install
Si prefieres saltarte el wrapper, puedes invocar los scripts directamente:
# Windows
.\scripts\win\install.ps1 -ServiceName GitHubSentinel
.\scripts\win\uninstall.ps1 -KeepData
# macOS
launchctl list | grep github-sentinel
launchctl unload -w ~/Library/LaunchAgents/com.midudev.github-sentinel.plist
Si no quieres NSSM, tienes dos opciones manuales:
Tarea Programada: taskschd.msc → crear tarea “Al iniciar el equipo” →
ejecutar C:\Users\TU_USUARIO\.bun\bin\bun.exe src/server/index.ts desde
la carpeta del proyecto. En propiedades marca “Ejecutar con los privilegios
más altos” y “Reiniciar si falla”.
PM2:
npm i -g pm2 pm2-windows-startup
pm2-startup install
pm2 start "bun src/server/index.ts" --name github-sentinel --cwd C:\ruta\github-sentinel
pm2 save
data/ en OneDrive, Dropbox ni unidades de red, no es seguro con WAL.data\ de escaneo en tiempo real, si no se pondrá a leer el .db-wal constantemente y notarás latencia.New-NetFirewallRule -DisplayName "GitHub Sentinel" -Direction Inbound -Protocol TCP -LocalPort 3741 -Action Allow
Luego: http://IP-DEL-MINIPC:3741.LLM_URL=http://192.168.x.x:PUERTO/v1 en .env y abre ese puerto en su firewall.# Desarrollo
bun dev # servidor con HMR
bun start # producción simple
bun start:prod # producción con NODE_ENV=production
bun build # build estático del cliente (opcional)
# Gestión del servicio (Windows + macOS)
bun service:install # instala y arranca como servicio del sistema
bun service:uninstall # desinstala (pregunta si borrar data/)
bun service:start
bun service:stop
bun service:restart
bun service:status
bun service:logs # tail -f data/sentinel.log
git diff) en lugar de prosaMIT