---
title: |-
  Playbook *UC2*
  Gateway-Web Session
description: "Verificación: crear una sesión Claude Code desde gateway-web apuntando al workspace container. UI → workspace → sesión → output visible."
kicker: Playbook · UC2 · Gateway-Web Session
subtitle: |-
  Abrir gateway-web (local o desplegado), conectarse al workspace container
  (`lab1-helsinki.api.mks2508.systems`), crear una sesión Claude Code con un
  provider alternativo y verificar que el output aparece en la UI.
strip:
  - { k: PLAYBOOK, v: UC2-GATEWAY-WEB }
  - { k: REV, v: "1.0" }
  - { k: FECHA, v: 21 JUN 2026 }
  - { k: DEPENDE, v: P0 }
meta:
  - { k: Esfuerzo, v: 10 min }
  - { k: Depende de, v: "P0 (prerequisites)" }
  - { k: Bloquea, v: UC5 (workspace E2E) }
  - { k: Veredicto, v: ⏳ pendiente }
stamps:
  - { text: gateway-web funcional, tone: ok }
  - { text: Workspace container vivo, tone: ok }
toc_legend:
  - { text: verificado, tone: ok }
  - { text: fallo esperable, tone: warn }
  - { text: roto, tone: bad }
footer:
  left: |-
    **UC2-GATEWAY-WEB · REV 1.0**
    Playbooks de verificación E2E para mks-agentics
  right: |-
    **GATEWAY-WEB** · **WORKSPACE** · **SESSION**
---

## Objetivo {#objetivo}

Crear una sesión Claude Code desde la UI web (gateway-web) que ejecuta en el workspace container remoto. La sesión debe arrancar, mostrar output en la UI y responder a prompts. Esto verifica el camino completo: UI → gateway-server (workspace) → cli-launcher → Claude Code → output NDJSON → UI. {.lead}

```dossier:diagram
engine: d2
source: |
  direction: right

  browser: "gateway-web\n(Vite+React)" {
    style: {
      fill: "#1a1a2e"
      stroke: "#e94560"
    }
  }

  workspace: "Workspace Container\nlab1-helsinki.api.mks2508.systems" {
    style: {
      fill: "#0f3460"
      stroke: "#533483"
    }
    gateway: "gateway-server\n:3456" {
      style: {
        fill: "#16213e"
        stroke: "#533483"
      }
    }
  }

  proxy: "gateway-proxy\n:3200 (opcional)" {
    style: {
      fill: "#1a1a2e"
      stroke: "#e94560"
    }
  }

  browser -> workspace.gateway: "POST /api/sessions\n{providerMode:'minimax'}" {
    style.stroke-dash: 3
  }
  browser -> workspace.gateway: "WS /ws/cli/:id\n(output NDJSON)" {
    style.stroke-dash: 3
  }
  workspace.gateway -> proxy: "Claude CLI\n--sdk-url -> proxy" {
    style.stroke-dash: 3
  }
```

## F1 — *Abrir* gateway-web {#f1-open}

```dossier:phases
items:
  - dur: "2 min"
    title: Cargar la UI y conectarse al workspace
    checks:
      - text: "Abrir `http://localhost:5173` (dev local) o la URL desplegada"
        sub: gateway-web carga sin errores de consola
      - text: "En el selector de slot, elegir 'Remote' e ingresar `https://lab1-helsinki.api.mks2508.systems`"
        sub: Se conecta al gateway-server del workspace
      - text: "Verificar que aparece 'Connected' o el indicador de conexión"
        sub: La UI estableció WS con el gateway-server
```

```dossier:term
title: gateway-web — desarrollo local
content: |
  # Arrancar gateway-web en modo dev:
  $ cd apps/gateway-web
  $ bun run dev

  # → Vite dev server en http://localhost:5173

  # En la UI:
  # 1. Slot selector → Remote
  # 2. URL: https://lab1-helsinki.api.mks2508.systems
  # 3. Provider: MiniMax
  # 4. Channels: OFF (UC2 es sesión simple, sin channels)
  # 5. Click "New Session"
```

## F2 — *Crear* sesión {#f2-create}

```dossier:phases
items:
  - dur: "3 min"
    title: Crear sesión y verificar output
    checks:
      - text: "Seleccionar provider 'MiniMax' en el dropdown de la UI"
        sub: "La UI envía `providerMode: 'minimax'` en el POST"
      - text: "Toggle Channels = OFF (para UC2 no necesitamos channels)"
        sub: Sesión básica sin a2a
      - text: "Click 'New Session' → aparece una nueva sesión en la lista"
        sub: El POST /api/sessions devolvió 200 + sessionId
      - text: "La sesión muestra estado 'running' y un chat input"
        sub: El cli-launcher spawneó Claude Code y el WS bridge está activo
      - text: "Escribir 'di hola' en el chat → aparece respuesta en la UI"
        sub: "Ciclo completo: UI → gateway-server → Claude CLI → output → UI"
```

### Body del POST /api/sessions

```dossier:term
title: Qué envía gateway-web al workspace
content: |
  # POST https://lab1-helsinki.api.mks2508.systems/api/sessions
  $ curl -s -X POST https://lab1-helsinki.api.mks2508.systems/api/sessions \
      -H "Content-Type: application/json" \
      -d '{
        "providerMode": "minimax",
        "cwd": "/workspace",
        "channels": false
      }' | jq .
  → {
  →   "session": {
  →     "sessionId": "a1b2c3d4-...",
  →     "state": "running",
  →     "model": "claude-sonnet-4-20250514",
  →     "cwd": "/workspace",
  →     "createdAt": "2026-06-20T..."
  →   }
  → }
```

## F3 — *Verificar* en el workspace {#f3-verify}

```dossier:phases
items:
  - dur: "3 min"
    title: SSH al workspace para verificar procesos
    checks:
      - text: "`ssh developer@lab1-helsinki.api.mks2508.systems` → acceso"
        sub: Acceso SSH al workspace container
      - text: "`ps aux | grep claude` → proceso Claude Code corriendo"
        sub: El cli-launcher spawneó un proceso Claude CLI
      - text: "`ls ~/.mks-harness/sessions/` → directorio de la sesión"
        sub: El sessionConfigDir fue creado con .claude.json aislado
      - text: "`cat ~/.mks-harness/sessions/<sid>/.claude.json` → mcpServers config"
        sub: Configuración de sesión persistida
      - text: "`tail -f /var/log/supervisor/gateway.log` → logs del cli-launcher"
        sub: El log muestra `Spawning CLI for session <sid>`
```

```dossier:note
tone: warn
tag: Posibles fallos UC2
body: |
  - **Fallo de conexión**: si gateway-web no puede conectar al workspace, verificar
    CORS (el gateway-server debe aceptar el origen de gateway-web) y que el
    workspace es accesible desde el navegador
  - **Sesión no arranca**: revisar `supervisorctl status gateway` en el workspace.
    Si el gateway-server no está corriendo, el POST /api/sessions fallará
  - **Sin output en UI**: el WS bridge entre gateway-web y gateway-server puede
    estar desconectado. Verificar la consola del navegador (Network → WS)
  - **Error de provider**: si el providerMode no es reconocido, el cli-launcher
    usará el default. Verificar que el provider dir existe en el workspace
```

## F4 — Verificación *final* {#f4-final}

```dossier:matrix
groups:
  - tone: v
    title: Debe pasar
    badge: "3 checks"
    items:
      - text: gateway-web carga y se conecta al workspace
        sub: WS establecido con gateway-server
      - text: POST /api/sessions → 200 + sessionId
        sub: Sesión creada correctamente
      - text: Respuesta del modelo visible en la UI
        sub: Output NDJSON bridge funciona
  - tone: r
    title: Puede fallar (esperable)
    badge: "1 check"
    items:
      - text: La UI muestra error si el workspace no tiene el provider configurado
        sub: Verificar API keys en el workspace container
  - tone: p
    title: Si falla → crítico
    badge: "1 check"
    items:
      - text: El workspace no acepta conexiones desde el navegador
        sub: Revisar CORS, firewall, health del gateway-server
```

```dossier:sources
groups:
  - title: Código relevante
    items:
      - label: gateway-web App.tsx
        url: apps/gateway-web/src/App.tsx
        chip: { text: source }
      - label: session.routes.ts
        url: apps/gateway-server/src/routes/session.routes.ts
        chip: { text: source }
      - label: cli-launcher.service.ts
        url: apps/gateway-server/src/services/cli-launcher.service.ts
        chip: { text: source }
      - label: entrypoint.sh
        url: ../mks-workspaces/docker/devenv-full/entrypoint.sh
        chip: { text: source }
```
