- Connects to a running daemon's IPC port on startup
- Sends join_network then get_state; listens for events in real time
- Three-pane layout: room list (left), message history (centre), peers (right)
- Tab/Shift+Tab to switch rooms, Enter to send, PgUp/PgDn to scroll
- DM rooms appear automatically when a DM arrives
- test-tui.sh boots the full stack (anchor + 3 peers) and opens the TUI
as alice, with bob and charlie sending periodic messages as live noise
- README: layout diagram, key bindings, TUI section; roadmap item marked done
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each daemon writes to <data-dir>/messages.db on startup. Messages received
or sent are stored immediately; duplicate mids (INSERT OR IGNORE) are safe
to call multiple times. Peer aliases are upserted on peer_connected and
again after hello verification when the real nick is known.
Schema
- messages(mid UNIQUE, room, from_peer, body, sent_at) — mid is the YAW/2
dedup key added in the proto migration; index on (room, sent_at) for
efficient per-room queries.
- peers(peer_id PK, alias, last_seen) — cache of every peer ever seen,
used to resolve hex ids to names when peers are offline.
Wiring
- store.Open called in cmd/daemon/main.go, passed to mesh.New.
- mesh.Mesh holds *store.Store (nil-safe; persistence is optional).
- mesh.SaveMessage called in dispatchPeerMessage (incoming) and ipc
CmdSendMessage (outgoing) so the local node's own messages are stored.
- mesh.UpdatePeerAlias called after hello verification updates the alias
with the verified nick rather than the placeholder short-id.
Messages only accumulate from join time forward — no history replay to
late-joining peers; each node's view starts from when it connected.
test-network.sh: added SQLite verification block that queries each node's
DB after the test and prints message + peer counts.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>