ce49fdf9ff
- 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>
4.1 KiB
4.1 KiB
name, lang, domain, description, tags, uses_functions, uses_types, framework, entry_point, dir_path
| name | lang | domain | description | tags | uses_functions | uses_types | framework | entry_point | dir_path | |||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| kanban | go | tools | Kanban board con persistencia SQLite, drag-and-drop entre columnas (dnd-kit) y tracking del tiempo que cada tarjeta pasa en cada columna. Frontend Vite + React + Mantine v9 embebido en el binario Go. |
|
|
|
net/http + vite + react + mantine + dnd-kit | backend/main.go | apps/kanban |
Arquitectura
Single-binary: backend Go con frontend Vite embebido. SQLite local con tres tablas (columns, cards, card_column_history) y endpoints REST.
./kanban --port 8095 --db kanban.db
Schema SQLite (migrations/001_init.sql)
- columns — id, name, position, created_at
- cards — id, title, description, column_id (FK), position, created_at, updated_at
- card_column_history — id, card_id (FK), column_id, entered_at, exited_at
- Una entrada con
exited_at IS NULL= posicion actual - Al mover una tarjeta a otra columna: cierra la entrada activa (
exited_at = now) e inserta una nueva - El borrado de tarjeta hace CASCADE sobre el historial
- Una entrada con
API REST
| Metodo | Path | Cuerpo |
|---|---|---|
| GET | /api/board |
— (retorna {columns, cards}, cada card incluye time_in_column_ms) |
| POST | /api/columns |
{name} |
| PATCH | /api/columns/{id} |
{name?, position?} |
| DELETE | /api/columns/{id} |
— (cascade a cards) |
| POST | /api/columns/reorder |
{ids: [...]} |
| POST | /api/cards |
{column_id, title, description?} |
| PATCH | /api/cards/{id} |
{title?, description?} |
| DELETE | /api/cards/{id} |
— |
| POST | /api/cards/{id}/move |
{column_id, ordered_ids: [...]} |
| GET | /api/cards/{id}/history |
— (timeline con duraciones por columna) |
Frontend
- dnd-kit (
@dnd-kit/core+@dnd-kit/sortable) para drag-and-drop entre y dentro de columnas (multi-container). - Mantine v9 +
@tabler/icons-reactpara UI. - Modales con
@mantine/modals(confirmacion borrado, history timeline). - Time-in-column live:
time_in_column_msdel backend + tick local cada segundo para que el badge se actualice sin reload. - DnD con
closestCorners+DragOverlaypara feedback visual al arrastrar.
Build
cd frontend && pnpm install && pnpm build
cd .. && CGO_ENABLED=1 go build -tags fts5 -o kanban .
./kanban --port 8095 --db kanban.db
# Browser: http://localhost:8095
Dev (frontend con HMR contra backend)
# Terminal 1
./kanban --port 8095 --db kanban.db
# Terminal 2
cd frontend && pnpm dev
# Browser: http://localhost:5180 (vite proxy /api → 8095)
Notas
- Puerto por defecto 8095.
- DB por defecto
kanban.dben cwd. - IDs de columnas y tarjetas: 16 chars hex (8 bytes random) via
random_hex_id_go_core. - El historial conserva la cronologia exacta — incluso despues de cerrar y reabrir el server, los tiempos vivos siguen contando desde
entered_at. - El borrado de columna hace CASCADE: las tarjetas se borran y su historial tambien. Si se quiere preservar el historial al borrar, deberia archivarse en lugar de borrar.