From 5421352e6294cab059903d20df4d722c97391574 Mon Sep 17 00:00:00 2001 From: Fredrik Johansson Date: Thu, 25 Jun 2026 20:40:33 +0200 Subject: [PATCH] docs: update FUTURE.md to reflect current shipped state Mark web UI, peer gossip, and identity backup as shipped. Expand TURN section with concrete implementation notes (one-liner ICEServers change + 3 daemon flags). Add per-network share directories and additional channels/rooms as next items. Remove stale "not implemented" notes. Co-Authored-By: Claude Sonnet 4.6 --- FUTURE.md | 69 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/FUTURE.md b/FUTURE.md index 7f93ca9..2ed1d26 100644 --- a/FUTURE.md +++ b/FUTURE.md @@ -26,6 +26,11 @@ Target: a web frontend (React or similar) wrapped in a native binary using a Tau #### TUI ✅ (shipped) A terminal UI (`cmd/tui`) using [Bubble Tea](https://github.com/charmbracelet/bubbletea). Three-pane layout: rooms, messages, peers. Supports group chat, DMs, room switching, invite generation. Works over SSH. +#### Web UI ✅ (shipped) +React + Vite frontend. Two modes: +- **Browser mode** — runs entirely in-browser, connects directly to the anchor via WebSocket. No daemon required. Identity persists in `localStorage`. File sharing, file push, per-peer ICE/NAT status. +- **Daemon mode** — web UI connects to a local daemon over WebSocket IPC. Same UI, different adapter. + --- ## Protocol @@ -33,41 +38,60 @@ A terminal UI (`cmd/tui`) using [Bubble Tea](https://github.com/charmbracelet/bu ### NAT Traversal ✅ (WebRTC ICE/STUN) Solved by using WebRTC DataChannels via pion. ICE gathers host + server-reflexive (STUN) candidates and performs UDP hole punching automatically. The anchor (`cmd/anchor`) doubles as a STUN server on UDP/3478. -The one remaining gap: symmetric-NAT pairs fail without TURN. An optional TURN relay (coturn in relay mode) can recover these. The protocol spec (§11) explicitly leaves this as an opt-in — no relay is the default. +### TURN relay (symmetric NAT pairs) +The one remaining gap: two peers both behind symmetric NAT (common on mobile/CGNAT) will fail to hole-punch. TURN recovers this. + +**How to add it:** `internal/anchor/client.go` already has the `ICEServers` slice. Adding a TURN entry is a one-liner: + +```go +ICEServers: []webrtc.ICEServer{ + {URLs: []string{"stun:stun.l.google.com:19302"}}, + {URLs: []string{"turn:your-vps:3478"}, Username: "waste", Credential: "secret"}, +}, +``` + +Expose as daemon flags (`-turn-url`, `-turn-user`, `-turn-credential`) and wire into the anchor client config. Run `coturn` in relay-only mode on the same VPS as the anchor. The relay sees only opaque DTLS-encrypted blobs. Opt-in, off by default. ### Signaling ✅ YAW/2.1 (shipped) -Forward-secret signaling via per-session ephemeral X25519 keys. See PROTOCOL.md §2.1 and `internal/anchor/client.go`. Falls back transparently to 2.0 static-key sealing for peers that don't speak 2.1. +Forward-secret signaling via per-session ephemeral X25519 keys. Falls back transparently to 2.0 static-key sealing for peers that don't speak 2.1. ### Multi-Network Support ✅ (shipped) -One daemon, multiple simultaneously-joined networks. Per-network HKDF-derived identities prevent cross-network correlation. Network-scoped SQLite stores, IPC commands carry `network_id`. +One daemon, multiple simultaneously-joined networks. Per-network HKDF-derived identities prevent cross-network correlation. Network-scoped SQLite stores. ### Invite System ✅ (shipped) -`waste:` URIs encoding anchor URL + network name. `--join` flag on daemon and TUI. Generated via IPC `generate_invite` or `Ctrl+I` in the TUI. +`waste:` URIs encoding anchor URL + network name. `--join` flag on daemon and TUI. `Ctrl+I` in TUI or `generate_invite` via IPC. ### File Transfer ✅ (shipped) -Dedicated binary DataChannel per transfer (`f:`). SHA-256 integrity verification. 64 KiB chunks with backpressure. Auto-accept. Downloads to `/downloads-/`. +Dedicated binary DataChannel per transfer (`f:`). SHA-256 integrity verification. 64 KiB chunks with backpressure. Auto-accept. In browser mode: both pull (browse peer's shared folder) and push (📎 send directly to a peer). + +### Peer Gossip ✅ (shipped) +When a new peer connects, the mesh immediately gossips the full peer list to them (`peer_gossip` wire message). New arrivals discover existing peers without needing the anchor to re-introduce them. The anchor becomes optional once the first handshake has happened — the mesh self-heals around anchor downtime. --- ## Remaining Work -### Per-Network Share Directories -The `-share-dir` flag is still global. A peer on two networks shares the same directory with both. The fix: make share dir per-network, configurable via an IPC command `set_share_dir {network_id, path}` or a config file, so Alice can share work files on "work" and music on "friends" independently. +### Per-Network Share Directories (next) +The IPC plumbing is done (`set_share_dir`, `ShareDir` on `NetworkInfo`, per-network mesh), but the web UI's folder picker is a single global share applied to all peers on all networks. The fix: track share state per `network_id` in the store and pass the active network's share when browsing or accepting get requests. -### Peer Gossip (§8.4) -The `peer_gossip` wire type exists in proto but is not implemented. When a peer knows about other peers (from prior connections), it could share address hints so the mesh can reconnect without the anchor. This makes the anchor optional once the initial handshake has happened — the network self-heals if the anchor goes down. +### Additional Channels / Rooms (next) +Currently each network has a hardcoded `#general` room. The protocol supports arbitrary room names already (messages carry a `room` field). What's missing: +- IPC command `create_room {network_id, name}` / `list_rooms {network_id}` +- Daemon stores room list per network in SQLite +- TUI: room creation input +- Web UI: `+` button in the Rooms sidebar section → prompt for name → `create_room` + +Room names are just strings — no server coordination needed. Any peer that sends to a room name causes it to appear on the recipient's side automatically. The only thing to add is persistence and a creation UI. ### File Transfer UX -- Manual accept/reject (currently auto-accept) +- Manual accept/reject (currently auto-accept everywhere) - Transfer cancellation via `file-cancel` -- Progress display in TUI +- Progress indicator in TUI and web UI - Resume after disconnection +- Daemon-side: write received files to `/downloads-/` (browser is limited to download prompt) ### Native UI -Web frontend (React) + Tauri/native packaging. The IPC protocol is already the full boundary — the UI is a pure consumer. - -### TURN relay (optional) -For symmetric-NAT pairs. Opt-in, off by default. Operates blind (relay sees only opaque DTLS-encrypted blobs). Run coturn in relay mode on the same VPS as the anchor. +Web frontend (React, already built) + Tauri shell for native packaging. The IPC protocol is the full boundary — the UI is already a pure consumer. Main work: Tauri setup, system tray, OS notifications. --- @@ -77,19 +101,22 @@ For symmetric-NAT pairs. Opt-in, off by default. Operates blind (relay sees only |---|---| | ✅ shipped | Daemon + anchor server | | ✅ shipped | WebRTC DataChannels (ICE/STUN hole punching) | -| ✅ shipped | Ed25519 identity, nacl/box signaling (YAW/2.0) | +| ✅ shipped | Ed25519 identity, nacl/box signaling (YAW/2.0 + 2.1) | | ✅ shipped | IPC protocol — join/leave/chat/DM/state | | ✅ shipped | Message persistence (SQLite, per-network) | | ✅ shipped | TUI (`cmd/tui`, Bubble Tea) | | ✅ shipped | Invite system (`waste:` URI, `--join` flag) | | ✅ shipped | Multi-network support (HKDF derived identities) | -| ✅ shipped | File transfer (dedicated binary DataChannels) | +| ✅ shipped | File transfer (binary DataChannels, pull + push) | | ✅ shipped | Forward-secret signaling (YAW/2.1 ephemeral X25519) | -| next | Per-network share directories | -| next | Peer gossip (anchor-free reconnection) | -| next | File transfer UX (manual accept, cancel, TUI progress) | +| ✅ shipped | Peer gossip (anchor-free mesh reconnection) | +| ✅ shipped | Web UI — browser mode + daemon mode | +| ✅ shipped | Per-peer NAT/ICE status, identity backup/restore | +| next | Per-network share directories (web UI wiring) | +| next | Additional channels/rooms per network | +| next | TURN relay (3 flags + coturn on VPS) | +| next | File transfer UX (progress, cancel, manual accept) | | future | Native UI (React + Tauri) | -| future | TURN relay (opt-in, for symmetric-NAT pairs) | ---