---
name: swl:gateway
description: Gestiona el gateway multi-plataforma de SWL. Configura adaptadores (Telegram, Discord, Webhook), verifica estado de conexión, envía mensajes de prueba y muestra logs de actividad. Usa manifiestos/gateway-config.json para configuración.
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
user-invocable: true
version: "1.0.0"
---

# /swl:gateway — Gestión del gateway multi-plataforma

Eres el gestor del gateway SWL. El gateway conecta el sistema con plataformas de mensajería externas para notificaciones bidireccionales.

## Subcomandos

| Subcomando | Descripción |
|-----------|-------------|
| `status` | Muestra estado de configuración y conexión de cada adaptador |
| `config` | Abre y guía la edición de `manifiestos/gateway-config.json` |
| `test <plataforma>` | Envía mensaje de prueba al adaptador especificado |
| `start` | Inicia el gateway daemon |
| `stop` | Detiene el gateway daemon |
| `logs [N]` | Muestra últimos N mensajes procesados |
| `relay-on <plataforma> <userId>` | Habilita recepción de comandos (relay bidireccional) y agrega usuario autorizado |
| `relay-off <plataforma>` | Deshabilita recepción de comandos de esa plataforma |
| `relay-status` | Muestra estado del relay y audit trail reciente |

## Paso 0 — Leer configuración

```bash
cat manifiestos/gateway-config.json
```

Mostrar estado de cada adaptador:
```
=== Gateway SWL ===
Habilitado: [sí/no]

Adaptadores:
  Telegram: [habilitado/deshabilitado] — Token: [configurado/falta]
  Discord:  [habilitado/deshabilitado] — Token: [configurado/falta]
  Webhook:  [habilitado/deshabilitado] — URL: [configurada/falta]

Notificaciones:
  onSessionComplete: [sí/no]
  onCheckpoint: [sí/no]
  onError: [sí/no]
```

## Subcomando: status

Lee `manifiestos/gateway-config.json` y muestra el estado formateado arriba.

## Subcomando: config

Guía interactiva para configurar el gateway:

1. ¿Habilitar gateway? (sí/no)
2. ¿Qué plataformas? (telegram/discord/webhook)
3. Para Telegram: pide el token del bot (via BotFather)
4. Para Telegram: pide IDs de usuarios permitidos (opcional)
5. Para Discord: pide token del bot y guild/channel IDs
6. Para Webhook: pide URL y secret
7. Escribe la configuración en `manifiestos/gateway-config.json`

**NUNCA hardcodear tokens en el archivo** — usar referencias a variables de entorno: `${TELEGRAM_BOT_TOKEN}`.

## Subcomando: test <plataforma>

```bash
node -e "
const { GatewayRunner } = require('./gateway/index');
const gw = new GatewayRunner(process.cwd());
// enviar mensaje de prueba
"
```

Envía un mensaje de prueba al adaptador indicado y reporta si se recibió.

## Subcomando: start

```bash
node gateway/index.js &
```

Inicia el gateway como proceso en background. Reporta PID.

## Subcomando: logs

Lee `.planning/comms/` y muestra los últimos N mensajes procesados con timestamp, tipo, origen y destino.

## Subcomando: relay-on \<plataforma\> \<userId\>

Habilita el modo relay bidireccional para una plataforma y autoriza a un usuario específico a enviar comandos desde ese canal hacia Claude Code.

Proceso:
1. Cargar `manifiestos/gateway-config.json`.
2. Setear `relay.enabled = true`.
3. Setear `relay.platforms.<plataforma>.enabled = true`.
4. Agregar `<userId>` a `relay.platforms.<plataforma>.allowedUsers` si no está.
5. Guardar con escritura atómica.
6. Informar al usuario que los mensajes entrantes se encolarán en `.planning/inbox/` y requieren ejecutar `/swl:inbox` para procesarlos.

**Importante**: antes de habilitar el relay, asegurar que el adaptador ya está funcionando (enabled + token válido). El relay no reemplaza al adaptador — lo extiende para recibir comandos.

## Subcomando: relay-off \<plataforma\>

Deshabilita el relay para esa plataforma (no desactiva el adaptador, solo la recepción de comandos). Los usuarios autorizados se preservan para re-habilitación rápida.

## Subcomando: relay-status

Muestra:
- Estado global del relay (enabled / disabled)
- Por plataforma: enabled, número de allowedUsers
- Rate limit configurado
- Últimas 10 entradas del audit trail (`.planning/inbox/audit.jsonl`)
- Cantidad de comandos pendientes en `.planning/inbox/`

```bash
# Audit trail reciente
tail -10 .planning/inbox/audit.jsonl 2>/dev/null

# Pendientes
ls .planning/inbox/cmd-*.json 2>/dev/null | wc -l
```

## Modo relay: arquitectura bidireccional

```
┌──────────────┐     ┌──────────────┐     ┌──────────────┐
│   Telegram   │────▶│   Gateway    │────▶│  .planning/  │
│     Bot      │     │  (adapter +  │     │    inbox/    │
└──────────────┘     │  CommandRelay)│     └──────┬───────┘
                     └──────────────┘             │
                            ▲                     ▼
                            │              ┌─────────────┐
                            └──────────────│ /swl:inbox  │
                            (respuesta)    │ (consumer)  │
                                           └─────────────┘
```

Validaciones del CommandRelay (todas obligatorias):
- Usuario en allowedUsers de esa plataforma
- Texto ≤ 4000 chars
- Sin patrones de payload injection (`<script>`, `.env`, `id_rsa`, etc.)
- Rate limit: 10 msg/min por usuario
- Dedup por hash en ventana de 30s

Todo evento (aceptado, rechazado, procesado) queda en `.planning/inbox/audit.jsonl`.

Para inyección directa a sesión tmux (solo Linux/macOS), ver `scripts/inbox-tmux-inject.js`.

## Reglas de comportamiento

- NUNCA almacenar tokens directamente en gateway-config.json — siempre usar `${VAR_ENV}`
- SIEMPRE verificar que el token existe como variable de entorno antes de habilitar un adaptador
- Si falta `node-telegram-bot-api` o `discord.js`, sugerir instalación con npm
- Para `relay-on`, confirmar con el usuario antes de agregar un userId a `allowedUsers`: esto autoriza a ese usuario a enviarte comandos remotos
- El relay NUNCA ejecuta comandos automáticamente: siempre requiere `/swl:inbox` con juicio humano. Explicar esto al usuario si activa el relay por primera vez
