Additional rooms:
- Store tracks customRooms per networkId; createRoom action slugifies and
deduplicates, switches active room on creation
- Sidebar: + button next to Rooms label opens an inline input; Escape
dismisses; Enter creates the room
Per-network share directories:
- Store tracks sharedFilesByNetwork keyed by networkId instead of a single
global map; setSharedFiles(files, networkId?) defaults to activeNetworkId
- FolderPicker reads per-network map to display accurate file count label
File transfer UX:
- Incoming file-offer now emits pending_offer instead of auto-accepting;
user sees Accept / Reject buttons in the sidebar Transfers section
- Progress events emitted per chunk during receive; Transfers panel shows
a live progress bar with received/total sizes
- file-cancel protocol message: sender or receiver can cancel an in-flight
transfer; DataChannel is closed and buffers discarded
- PeerConn: acceptOffer(), rejectOffer(), cancelRecv(), cancelSend()
- BrowserAdapter: acceptOffer(), rejectOffer(), cancelTransfer()
- Store: pendingOffers, fileProgress, acceptOffer, rejectOffer, cancelTransfer
- Transfers component renders in sidebar; auto-hides when no activity
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements both pull (browse & download from a shared folder) and push
(send a file directly to a peer) using the yaw2 file protocol over WebRTC
DataChannels.
- PeerConn: handle browse/files/get/file-offer/file-accept/file-done
control messages; stream files in 64KB chunks over f:xid binary
DataChannels; auto-accept incoming offers (push and pull)
- PeerConn.sendFilePush(): initiate an outbound file transfer without
requiring the peer to browse first
- BrowserAdapter: sharedFiles map, setSharedFiles(), requestBrowse(),
requestGet(), sendFileTo() — propagates share map to all active peers
- Store: activeFilePeer, setActiveFilePeer, setSharedFiles, browseFiles,
sendFileTo; file_complete handler triggers browser download automatically
- FileBrowser component: third-column panel listing a peer's shared files
with name, size, and a download button
- FolderPicker component: webkitdirectory input in the sidebar (browser
mode only) for selecting a local folder to share
- Sidebar: 📎 send-file button on peer rows (hover) with inline file picker
- App.tsx: use browser mode when WASTE_CONFIG.signalURL is set, even on
localhost — allows testing browser mode via npm run dev with config.js
- deploy-daemon.sh: kill existing daemon before scp to avoid upload failure
when the binary is locked; remove duplicate kill block in restart step
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace bold duplicate-looking self row with dimmed name + small accent
"you" badge. Removes the ID (already shown in identity section at top).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switch back to flex, set explicit widths: 52px timestamp (nowrap, 24h),
90px alias (right-aligned). Eliminates wrapping and the large gap.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Messages now use a fixed grid (44px ts · 120px alias right-aligned · 1fr text)
instead of flex, so text always starts at the same column regardless of alias length.
Self shown at top of peer list with accent dot and bold name.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Peers moved from right panel into sidebar below Rooms
- Messages left-aligned IRC style: time · alias · text
- Per-peer colored dot: green=direct/NAT-punched, amber=relay/connecting, red=failed
- Hover title on peer row shows full ID, connection type, remote address, last seen
- Removed right PeerList panel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Messaging:
- Append \n to WS IPC sends so bufio.Scanner fires (messages from web
were silently dropped — the line scanner never saw a newline)
- Handle session_ready in web store to update peer aliases after hello
Alias resolution:
- Seed AddPeer alias from SQLite cache so returning peers resolve
immediately, before hello exchange completes
- Remove stale SavePeer call from AddPeer (was writing placeholder IDs)
- Add PeerAlias() point-lookup to store
Onboarding redesign:
- Three-state UI: disconnected (daemon instructions), connecting,
connected-no-network (join form)
- Read ?n= / ?network= / ?anchor= / ?invite=waste:... URL params to
pre-fill the join form for invite links
- Show daemon alias + peer ID before any network is joined
(master_alias + master_id now included in state_snapshot)
- Identity backup: export (passphrase-protected yaw-key-backup-1 JSON,
download button) and restore (paste + passphrase verify)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
React + TypeScript UI on port 5274. Connects to local daemon via
WebSocket IPC (DaemonAdapter). Full chat layout with sidebar, message
pane, and peer list. Mirrors the TUI feature set.
- src/types.ts — IPC types mirroring proto.go
- src/adapter/daemon — WebSocket IPC adapter with auto-reconnect
- src/store/index.ts — Zustand store; handles all daemon events
- src/pages/ — Onboarding (connect + join) and Chat
- src/components/ — Sidebar, MessagePane, PeerList
Dev: cd web && npm run dev (port 5274)
Build: cd web && npm run build
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>