- frontend/vite.config.ts: anadir ws: true al proxy de /api para que el
dev server (5180) reenvie WebSocket upgrade al backend (8095). Sin esto
Firefox da "websocket error" al abrir /api/chat/ws en modo dev.
- e2e/chat_ws_e2e_test.go: 4 tests nuevos que arrancan el binario kanban
en puerto efimero con un fake claude (bash script que emite NDJSON), se
loguean via /api/auth/login y dialean /api/chat/ws con cookie de sesion.
Verifican: deltas + done, tool_use + tool_result + board_changed,
rechazo sin sesion, /api/tool sin token = 401.
- e2e/go.mod: anade nhooyr.io/websocket (cliente WS para tests).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Backend: kanban binary gana subcomando `kanban mcp` que actua como MCP
server via stdio. Tools = mismo set que executeTool (14). El subprocess
llama de vuelta al backend via /api/tool/{name} con token interno.
- Backend: nuevo endpoint POST /api/tool/{name} (auth: X-Internal-Token).
- Backend: chat.go refactor — POST /api/chat reemplazado por GET
/api/chat/ws (WebSocket). Lanza claude -p con --output-format stream-json
--verbose --mcp-config y reenvia eventos (delta/tool_use/tool_result/
result/done/error) como mensajes JSON al cliente.
- Backend: usa funciones nuevas del registry claude_stream_go_core (spawn
+ parser NDJSON) y mcp_server_stdio_go_infra (JSON-RPC stdio).
- Frontend: streamChat sobre WebSocket. ChatPanel renderiza deltas en
vivo, chips para tool_use, badges teal/red para tool_result.
- Borrado: extractActions, actionsBlockMarker, XML system prompt.
- Tests: 7 nuevos en backend (chat_ws_test.go + endpoint /api/tool).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- badges: locked → tiempo bloqueado; done → fecha completion + total lead time; otherwise → tiempo en columna
- locked cards: drag permitido dentro de mismo column (cross-column rejected con notification)
- card field: locked_at desde JOIN card_lock_history (open period)
- migrations: refactor a embed.FS, archivos 002-005 extraidos de ensureColumns; ensureColumns queda como backstop
- stickers UX: opacidad 1, debajo del texto, picker estable (useRef), boton entra directo a modo con 😀, popover cierra outside, cards done filter brightness
- format: formatDateTimeShort
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>