Remove the snake_case mirror interfaces and mapper functions that translated
generated protobuf-es messages for the components, and have the UI consume the
generated types directly (single source of truth = the proto schema).
- Hooks (useStats/useNeighbors/useNodeData/useMeshcoreSearch/useChatMessages)
return generated message types; delete toNodeData/toChatMessage/toSearchResult
and the snake_case select/.map adapters. Delete the dead useAllNeighbors hook
and src/types/map.ts; components import NodePosition/Neighbor/NeighborEdge/
Advert/SearchResult/ChatMessage from src/gen.
- Components read camelCase fields (node page, AdvertDetails, MapView, MapIcons,
stats page, search results, chat). useNodeData surfaces ConnectError with a
nodeErrorCode() helper for the error UI. Drop the always-empty Alt row in the
map popup (generated NodePosition has no altitude).
- buf lint (Option A): give each StatsService RPC its own request message, and
wrap the server-streaming responses (StreamChatResponse / StreamPacketsResponse).
Server stream handlers + the chat stream consumer updated accordingly.
- Add a buf CI workflow (lint/format/breaking on proto changes).
tsc, next build, and buf lint are clean; verified end-to-end in Docker.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>