# Tarea 11 — Renderizar mensajes como Markdown en Matrix

## Problema

Todos los mensajes de los agentes (respuestas LLM, comandos, errores) se envían como texto plano
via `SendText()`. Matrix soporta mensajes con `format: org.matrix.custom.html` + `formatted_body`
para renderizar Markdown (negrita, código, listas, etc.) en clientes como Element.

Existe un `SendMarkdown()` en `shell/matrix/client.go` pero tiene dos problemas:
1. Solo se usa en un único lugar (`runtime.go:617` — notificación de tool use).
2. No convierte Markdown a HTML: pone el markdown crudo en `FormattedBody`, que Matrix espera como HTML.

## Alcance

### 1. Añadir conversión Markdown → HTML (`shell/matrix/client.go`)

- Añadir dependencia `github.com/yuin/goldmark` (parser Markdown → HTML estándar, muy usado en Go).
- Corregir `SendMarkdown()` para que convierta el body de Markdown a HTML antes de ponerlo en `FormattedBody`.
- `Body` queda como texto plano (fallback para clientes que no soportan HTML) — se puede dejar el markdown crudo ahí, que es lo estándar en Matrix.

```go
func (c *Client) SendMarkdown(ctx context.Context, roomID, markdown string) error {
    html := mdToHTML(markdown) // nueva función interna
    content := event.MessageEventContent{
        MsgType:       event.MsgText,
        Body:          markdown,
        Format:        event.FormatHTML,
        FormattedBody: html,
    }
    _, err := c.raw.SendMessageEvent(ctx, id.RoomID(roomID), event.EventMessage, content)
    return err
}
```

### 2. Cambiar la interfaz `MatrixSender` para exponer `SendMarkdown`

- `shell/effects/runner.go`: añadir `SendMarkdown(ctx, roomID, text) error` a la interfaz `MatrixSender`.
- `tools/matrix.go`: añadir `SendMarkdown` a la interfaz `MatrixToolSender` (o como se llame).

### 3. Cambiar todos los call sites de `SendText` → `SendMarkdown`

Puntos a cambiar:

| Archivo | Línea(s) | Contexto |
|---------|----------|----------|
| `agents/runtime.go:394` | Respuesta de tarea orquestada | `SendText → SendMarkdown` |
| `agents/runtime.go:456` | Reply LLM (loop) | `SendText → SendMarkdown` |
| `agents/runtime.go:462` | Reply LLM (fallback) | `SendText → SendMarkdown` |
| `shell/effects/runner.go:68` | Runner.executeOne (ActionKindReply) | `SendText → SendMarkdown` |
| `agents/runtime.go:456` | Comando ejecutado (!xxx) | `SendText → SendMarkdown` |
| `agents/runtime.go:462` | Comando desconocido | `SendText → SendMarkdown` |

### 4. Mantener `SendText` para uso interno/futuro

No eliminar `SendText`, solo dejar de usarlo como canal principal de respuesta.
Podría ser útil para mensajes que realmente no necesitan formato (logs internos, debugging).

### 5. Actualizar interfaz en tests/mocks

Cualquier mock de `MatrixSender` que exista en tests necesitará el método `SendMarkdown`.

## Tareas ordenadas

- [ ] `go get github.com/yuin/goldmark`
- [ ] Crear función `mdToHTML(md string) string` en `shell/matrix/` (usa goldmark)
- [ ] Corregir `SendMarkdown()` para usar `mdToHTML`
- [ ] Añadir `SendMarkdown` a la interfaz `MatrixSender` en `shell/effects/runner.go`
- [ ] Cambiar `runner.executeOne` (ActionKindReply) de `SendText` → `SendMarkdown`
- [ ] Cambiar `runtime.go` — respuesta de comandos (!xxx) a `SendMarkdown`
- [ ] Cambiar `runtime.go` — respuesta de tarea orquestada a `SendMarkdown`
- [ ] Actualizar interfaz en `tools/matrix.go` si aplica
- [ ] Actualizar mocks en tests
- [ ] Test manual: enviar mensaje al bot y verificar que Element renderiza markdown

## Notas

- goldmark es safe por defecto (escapa HTML peligroso) — no hay riesgo XSS.
- El `Body` del evento Matrix queda como markdown crudo — esto es correcto según la spec de Matrix (es el fallback plaintext).
- Los mensajes de error simples ("Comando desconocido: !foo") también pasan por `SendMarkdown` — no pasa nada, goldmark los deja como `<p>texto</p>` sin más.
