---
name: swl:plugins
description: Gestiona plugins de usuario instalados en _userland/. Instala, desinstala, lista y valida plugins SWL desde directorios locales. Cargar cuando el usuario quiera instalar componentes externos (agentes, skills, reglas, hooks) sin modificar el sistema base.
allowed_tools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"]
---

# /swl:plugins — Gestión de plugins de usuario

Gestiona el ciclo de vida completo de plugins SWL instalados en `_userland/plugins/`.
Un plugin es un directorio con `plugin.json` que agrupa agentes, skills, reglas y/o
hooks de terceros o del equipo, sin tocar los componentes del sistema base.

## Cuándo usar

- Para instalar skills o agentes de dominio específico del proyecto
- Para incorporar extensiones de equipo sin mezclarlas con el sistema SWL base
- Para validar un plugin antes de distribuirlo
- Para limpiar plugins obsoletos

## Subcomandos

```
/swl:plugins                    — Lista plugins instalados (resumen)
/swl:plugins list               — Lista plugins con detalle de componentes
/swl:plugins install <ruta>     — Instala plugin desde directorio local
/swl:plugins remove <nombre>    — Desinstala plugin
/swl:plugins validate <ruta>    — Valida plugin.json contra schema
```

---

## install — Instalar un plugin

### Paso 1 — Leer y validar el manifiesto

```bash
cat <ruta>/plugin.json
```

Verificar que `plugin.json` existe y leerlo. Luego validar contra el schema:

```bash
# Verificar campos obligatorios: name, version, description
# El name debe cumplir ^[a-z][a-z0-9-]+$ y no usar palabras reservadas:
# anthropic, claude, swl
```

Si falta `plugin.json` o no cumple el schema en `schemas/plugin.schema.json`:
reportar los campos inválidos y abortar sin realizar cambios.

### Paso 2 — Verificar archivos referenciados

Recorrer los arrays `agents`, `skills`, `rules`, `hooks` del manifiesto y
verificar que cada ruta referenciada existe dentro del directorio del plugin:

```bash
ls <ruta>/<archivo-referenciado>
```

Si algún archivo referenciado no existe: reportar y abortar.

### Paso 2B — Verificación de seguridad del plugin

**Carga**: `Skill("seguridad-skills-ia")` — patrones de detección de amenazas.

Escanear el contenido completo del plugin antes de copiar al destino:

1. **Agentes del plugin**: verificar que ningún agente declara `nivelRiesgo: ALTO`
   ni `permisosRed: irrestricto` sin documentación explícita en el manifiesto
2. **Hooks con `blocking: true`**: listar y advertir al usuario — requieren
   aprobación explícita antes de activarse
3. **Skills del plugin**: aplicar los patrones de detección del skill
   `seguridad-skills-ia` sobre cada SKILL.md y sus scripts/
4. **Reglas del plugin**: verificar que no contradicen reglas base del sistema
   (precedencia de capas: reglas base > reglas de plugin)

Resultado del escaneo:
- **Score ≥ 8.0**: proceder con instalación
- **Score 5.0-7.9**: advertir hallazgos y pedir confirmación explícita
- **Score < 5.0**: BLOQUEAR instalación, reportar hallazgos detallados

Registrar el resultado del escaneo en `.planning/AUDITORIA.md`:
```markdown
## [YYYY-MM-DD HH:MM] plugin-security-scan

**Plugin**: nombre-plugin vX.Y.Z
**Score**: N.N/10.0
**Veredicto**: SEGURO | SOSPECHOSO | INSEGURO
**Hallazgos**: [lista o "ninguno"]
**Acción**: instalado | bloqueado | instalado con advertencias
```

### Paso 3 — Resolver dependencias

Si `plugin.json` tiene `dependencies`:
1. Verificar que cada dependencia está instalada en `_userland/plugins/`
2. Si falta alguna: reportar nombre y versión requerida, abortar con instrucción:
   `Instalar primero: /swl:plugins install <ruta-dependencia>`

### Paso 4 — Copiar al destino

```bash
mkdir -p _userland/plugins/<nombre>/
cp -r <ruta>/* _userland/plugins/<nombre>/
```

### Paso 5 — Registrar en .claude/settings.json

Leer `.claude/settings.json`. Para cada componente del plugin:

- **skills**: agregar path en `mcpServers` o en la lista de skills según configuración activa
- **rules**: agregar path en `rules` si la configuración lo soporta
- **hooks**: agregar entrada en `hooks` con el evento correspondiente

Si `.claude/settings.json` no existe o no soporta registro dinámico, documentar
los paths en `.planning/PLUGINS.md` para referencia manual.

### Paso 6 — Verificar integridad post-instalación

```bash
echo "Plugin <nombre> v<version> instalado en _userland/plugins/<nombre>/"
echo "Componentes: agentes=$(count), skills=$(count), reglas=$(count), hooks=$(count)"
```

Indicar al usuario que ejecute `/swl:salud` para verificar integridad global.

---

## remove — Desinstalar un plugin

### Paso 1 — Verificar existencia

```bash
ls _userland/plugins/<nombre>/
cat _userland/plugins/<nombre>/plugin.json
```

Si no existe: reportar y terminar.

### Paso 2 — Verificar dependientes

Buscar otros plugins instalados que declaren `<nombre>` en sus `dependencies`:

```bash
grep -r '"<nombre>"' _userland/plugins/*/plugin.json
```

Si hay dependientes activos: advertir y pedir confirmación antes de continuar.

### Paso 3 — Des-registrar de settings.json

Revertir los registros realizados durante `install`:
- Remover skills del listado
- Remover reglas del listado
- Remover hooks del listado

### Paso 4 — Eliminar directorio

```bash
rm -rf _userland/plugins/<nombre>/
```

Confirmar: `Plugin <nombre> desinstalado correctamente.`

---

## validate — Validar plugin sin instalar

### Paso 1 — Verificar estructura mínima

```bash
ls <ruta>/plugin.json
```

### Paso 2 — Validar campos del manifiesto

Leer `plugin.json` y verificar:

| Campo | Regla |
|-------|-------|
| `name` | presente, `^[a-z][a-z0-9-]+$`, máximo 64 chars |
| `version` | presente, `^\d+\.\d+\.\d+$` |
| `description` | presente, 10–500 chars |
| `agents[]` | cada ruta existe en el directorio |
| `skills[]` | cada ruta existe y contiene `SKILL.md` |
| `rules[]` | cada ruta existe y termina en `.md` |
| `hooks[]` | cada ruta existe y termina en `.js` |
| `dependencies` | cada valor es SemVer válido |

### Paso 3 — Reportar resultado

Si pasa todas las verificaciones:
```
✓ plugin.json válido
✓ X archivos referenciados verificados
✓ El plugin puede instalarse con: /swl:plugins install <ruta>
```

Si hay problemas: listar cada problema con campo y descripción del error.

---

## list — Listar plugins instalados

```bash
ls _userland/plugins/ 2>/dev/null || echo "(ningún plugin instalado)"
```

Para cada plugin encontrado, leer su `plugin.json` y mostrar:

```
nombre          versión    autor          componentes
──────────────────────────────────────────────────────
mi-dominio      1.2.0      Equipo A       3 skills, 1 agente
otro-plugin     0.5.1      Dev externo    2 reglas, 1 hook
```

Si no hay plugins instalados: indicar cómo instalar uno.

---

## Estructura de un plugin

```
mi-plugin/
  plugin.json          — Manifiesto (requerido)
  agentes/             — Agentes custom (.md con frontmatter YAML)
  habilidades/         — Skills custom (directorios con SKILL.md)
  reglas/              — Reglas custom (.md)
  hooks/               — Hooks custom (.js)
```

### Ejemplo de plugin.json válido

```json
{
  "name": "facturacion-sat",
  "version": "1.0.0",
  "description": "Skills y agentes para integración con el SAT mexicano.",
  "author": "Equipo Fiscal",
  "license": "MIT",
  "skills": ["habilidades/cfdi-4"],
  "agents": ["agentes/validador-sat.md"],
  "rules": ["reglas/cumplimiento-sat.md"]
}
```

---

## Notas de gobernanza

- Los plugins instalados en `_userland/` nunca modifican los componentes del sistema base.
- Los hooks de plugins con `blocking: true` requieren aprobación antes de activarse
  (ver `reglas/gobernanza.md`).
- Los plugins auto-generados por `/swl:evolucionar` se instalan primero aquí como
  período de prueba antes de promoverse al sistema base.
