|
| 1 | +# wert - codebase notes for Claude |
| 2 | + |
| 3 | +## What this is |
| 4 | + |
| 5 | +wert is a LAN terminal team tool. Admin runs a server, team members connect to it. Everyone gets a full screen TUI with tasks and chat. There is also an MCP server so Claude can manage tasks and send messages. |
| 6 | + |
| 7 | +## Project structure |
| 8 | + |
| 9 | +``` |
| 10 | +wert/ |
| 11 | + main.go entry point, just calls cmd.Execute() |
| 12 | + cmd/ |
| 13 | + root.go cobra root command and banner |
| 14 | + serve.go admin mode, starts server then opens TUI |
| 15 | + join.go member mode, connects to server and opens TUI |
| 16 | + mcp.go starts MCP stdio server |
| 17 | + internal/ |
| 18 | + protocol/ |
| 19 | + messages.go all shared types: Task, Member, ChatMessage, Envelope, payloads |
| 20 | + server/ |
| 21 | + store.go in-memory store with JSON file persistence |
| 22 | + hub.go websocket hub, connection management, message routing |
| 23 | + server.go http server, websocket upgrade, REST API for MCP |
| 24 | + client/ |
| 25 | + client.go websocket client with Send/Recv channels |
| 26 | + tui/ |
| 27 | + model.go full Bubble Tea TUI model, all rendering and input handling |
| 28 | + mcp/ |
| 29 | + server.go MCP stdio server using mark3labs/mcp-go, calls REST API |
| 30 | +``` |
| 31 | + |
| 32 | +## How communication works |
| 33 | + |
| 34 | +- Server runs on a port (default 8080) |
| 35 | +- Clients connect via WebSocket at /ws |
| 36 | +- All messages are JSON wrapped in an Envelope { type, payload } |
| 37 | +- payload is json.RawMessage so each type is decoded separately |
| 38 | +- The hub handles register, chat, task_create, task_update, task_delete |
| 39 | +- On connect the server sends a full sync payload with all tasks, members, messages |
| 40 | +- MCP server calls the REST API at /api/tasks, /api/members, /api/messages |
| 41 | + |
| 42 | +## Key types |
| 43 | + |
| 44 | +All in internal/protocol/messages.go |
| 45 | + |
| 46 | +- Envelope - wraps every websocket message, has Type and raw Payload |
| 47 | +- Task - has ID (uuid), Title, Description, Assignee, Status, Priority, timestamps |
| 48 | +- Member - Username, Role (admin or member), Online bool |
| 49 | +- ChatMessage - ID, From, Content, Timestamp |
| 50 | +- SyncPayload - sent to new clients with full state |
| 51 | + |
| 52 | +## TUI |
| 53 | + |
| 54 | +Built with charmbracelet/bubbletea, bubbles, and lipgloss. |
| 55 | + |
| 56 | +- Model in internal/client/tui/model.go |
| 57 | +- Two panes: Tasks (left, 40%) and Chat (right, 60%) |
| 58 | +- Tab switches active pane |
| 59 | +- Admin sees all tasks, members only see their own assigned tasks |
| 60 | +- Commands start with / |
| 61 | +- New task notification shows in status bar when a task is assigned to you |
| 62 | +- waitForMsg reads from client.Recv channel and feeds into bubbletea as ServerMsg |
| 63 | + |
| 64 | +## Task IDs |
| 65 | + |
| 66 | +Tasks have full UUIDs. The TUI shows the first 8 chars as the short ID. |
| 67 | +Commands like /done use the short prefix. The server does prefix matching via GetTaskByPrefix. |
| 68 | + |
| 69 | +## Commands in TUI |
| 70 | + |
| 71 | +Everyone: /done /wip /blocked /todo /members /help |
| 72 | +Admin only: /assign @user "title" ["desc"] [priority], /delete |
| 73 | + |
| 74 | +## MCP tools |
| 75 | + |
| 76 | +list_tasks, list_members, create_task, update_task, delete_task, send_message, get_dashboard |
| 77 | +All go through the REST API so no WebSocket needed for MCP. |
| 78 | + |
| 79 | +## Persistence |
| 80 | + |
| 81 | +Store writes to a JSON file (default wert-data.json) after every mutation. |
| 82 | +Writes happen in a goroutine so they do not block. |
| 83 | +On startup the store loads the file if it exists. |
| 84 | + |
| 85 | +## Flags |
| 86 | + |
| 87 | +wert serve --name --port --token --data |
| 88 | +wert join --host --name --token |
| 89 | +wert mcp --server |
| 90 | + |
| 91 | +## Dependencies |
| 92 | + |
| 93 | +- github.com/charmbracelet/bubbletea - TUI framework |
| 94 | +- github.com/charmbracelet/bubbles - viewport, textinput components |
| 95 | +- github.com/charmbracelet/lipgloss - styling |
| 96 | +- github.com/gorilla/websocket - websocket server and client |
| 97 | +- github.com/google/uuid - task IDs |
| 98 | +- github.com/spf13/cobra - CLI commands |
| 99 | +- github.com/mark3labs/mcp-go - MCP server |
| 100 | + |
| 101 | +## Build |
| 102 | + |
| 103 | +```bash |
| 104 | +go build -o wert . |
| 105 | +make cross-build # linux, darwin, windows amd64/arm64 |
| 106 | +``` |
| 107 | + |
| 108 | +## Things to know |
| 109 | + |
| 110 | +- The admin token is optional. If set, only people who pass it with --token get admin role. |
| 111 | +- If no token is set, the first person to run serve is just trusted as admin via WebSocket role. |
| 112 | +- Data file is only written on the server machine, not on clients. |
| 113 | +- The TUI uses alt screen mode so it takes over the full terminal. |
| 114 | +- Ctrl+Q or Ctrl+C to quit. |
0 commit comments