Commit Graph

34 Commits

Author SHA1 Message Date
Fredrik Johansson
de8d3ff70d Remove unsolicited deploy/ and config.example.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 08:52:00 +02:00
Fredrik Johansson
739c63f6b3 Add deploy/ with nginx config and web deploy script
nginx-waste.conf: serve web/dist/ at root, proxy /ws to anchor (port
8080), SPA fallback for clean invite URLs, immutable cache for assets.

deploy-web.sh: build + rsync to anchor host, skip config.js so the
host's runtime config is not clobbered.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 08:44:46 +02:00
Fredrik Johansson
5bc16daae1 Add standalone browser mode: no daemon required
BrowserAdapter speaks yaw/2.1 signaling + WebRTC protocol entirely in
the browser (libsodium-wrappers for Ed25519/X25519). Identity stored in
localStorage; peers connect via any waste/yaw2 anchor.

When served from a non-localhost origin the app defaults to browser
mode. On localhost the daemon adapter is tried first with a one-click
switch to browser mode. config.js (gitignored, served by anchor) lets
the host pre-inject signalURL and other defaults.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 00:06:41 +02:00
Fredrik Johansson
add7c5fea8 Add yaw2 invite interoperability
Protocol:
- invite.go: include full 64-char `net` hash in waste: invite blob
  (matches yaw2's `net` field — any client parsing the base64 JSON can
  join without knowing the plaintext name). Expose NetHash() helper.
- netmgr: add JoinByHash() — join via full 64-char hex hash alone,
  storing the short ID as display name. Enables joining yaw2 networks
  from a URL that only carries the hash.
- anchor: expose RunByHash() so netmgr can pass a pre-computed hash
  directly without a name→hash roundtrip.
- ipc/proto: add network_hash field to join_network — routes to
  JoinByHash when present and network_name is absent.

Web UI:
- Parse ?net=<64hex> (yaw2 URL param) and ?a=<anchor> in addition to
  existing ?n= / ?invite= params. Hash-only joins send network_hash.
- Sidebar shows yaw: contact card (yaw:<masterID>?n=<alias>) using the
  master identity — compatible with yaw2 contact card format. Click to
  copy to clipboard.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 23:29:45 +02:00
Fredrik Johansson
7fe02e9463 Fix web UI messaging, alias resolution, and onboarding
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>
2026-06-22 23:22:32 +02:00
Fredrik Johansson
2bc1dbbedf fix: run TCP and WS IPC concurrently, fail only if either dies
Previously --ws-port started WS in a goroutine then called Run() which
blocked; if TCP IPC failed it took the whole process down even though WS
was up. Now both run in goroutines and the first error from either kills
the daemon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 22:11:20 +02:00
Fredrik Johansson
06f9359da8 fix: allow any origin on WS IPC (127.0.0.1-only bind is the guard)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 22:08:44 +02:00
Fredrik Johansson
ff14e955ea feat: standalone web UI (React + Vite)
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>
2026-06-22 21:57:32 +02:00
Fredrik Johansson
77830a3b3f feat: WebSocket IPC endpoint for web UI
Add --ws-port flag to waste-daemon; when set, starts a WebSocket IPC
server alongside the existing TCP one. The web UI connects to this from
the browser. Uses nhooyr.io/websocket with localhost-only origin policy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:57:10 +02:00
Fredrik Johansson
c1dea1d19d chore: gitignore setup-anchor.sh and launch-tui.sh
Local-only scripts for deploying the anchor and launching the TUI —
not intended for the repository.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:45:37 +02:00
Fredrik Johansson
b47f659b7d feat: identity export/import (yaw-key-backup-1)
Portable encrypted identity backup compatible with the sister project's
format — argon2id KDF + nacl secretbox, peer ID visible in plaintext for
pre-import verification.

- crypto: ExportIdentity, ImportIdentity, SaveIdentity
- proto: export_identity / import_identity IPC commands + events
- ipc: export_identity returns encrypted blob; import_identity validates
  and decrypts (read-only — on-disk write requires daemon restart)
- netmgr: MasterIdentity() accessor
- daemon: --import-identity / --import-passphrase flags write identity.json
  and exit, enabling scripted account migration
- tests: roundtrip and wrong-passphrase rejection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:44:48 +02:00
Fredrik Johansson
f1498697b6 feat: live mesh peer gossip
When a peer's hello is verified, send a gossip burst of currently
connected peers so the new peer can discover and connect to nodes it
hasn't met yet — without relying on the anchor for a full peer-join
notification for each one.

- mesh: add PendingConnect chan for gossip-discovered peer IDs
- peer: send gossip burst after hello; push unknown peers from incoming
  gossip onto PendingConnect (skip self + already-connected)
- anchor: drain PendingConnect per runOnce, initiate startOffer for
  unknown peers using the same lexicographic tiebreak as anchor join;
  drain goroutine is scoped to the runOnce lifetime to avoid using stale
  sessions after a reconnect

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 16:02:11 +02:00
Fredrik Johansson
d02e18e212 feat: per-network share directories + isolation test
Each network now carries its own share dir, set at join_network time via
optional share_dir field or updated live with set_share_dir. The global
-share-dir daemon flag becomes a fallback default.

- proto: add ShareDir/DownloadDir to NetworkInfo and IpcMessage
- netmgr: Join accepts shareDir override; SetShareDir updates live
- ipc: wire join_network share_dir and set_share_dir command
- daemon: remove -share-dir from auto-join path (pass "" for default)
- test-network.sh: per-network join with share_dir; isolation verification
  section confirms alice/friends and alice/work share dirs are independent
- test-tui.sh: join_network with share_dir; peer IDs resolved after join

All tests pass: YAW/2.1 FS, share isolation, file transfer, persistence.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 15:13:26 +02:00
Fredrik Johansson
f437fe94f4 docs: rewrite FUTURE.md to reflect current shipped state
Mark as done: TUI, WebRTC/ICE/STUN, multi-network, invite system,
file transfer, YAW/2.1 forward-secret signaling.

Remove stale content: "TCP with custom framing" transport section,
old roadmap priorities (waste-relay, UDP hole punching, QUIC) that
are now handled by WebRTC/pion.

Remaining work: per-network share dirs, peer gossip (anchor-free
reconnection), file transfer UX improvements, native UI, optional TURN.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:59:27 +02:00
Fredrik Johansson
274ff423f6 feat: implement YAW/2.1 forward-secret signaling
Upgrades the signaling layer from static X25519 (2.0) to per-session
ephemeral X25519 (2.1). Recorded signaling traffic cannot be decrypted
even if long-term Ed25519 keys later leak, because esk is zeroed on
session close.

Protocol:
- Each peer generates a fresh X25519 keypair (esk/epk) per session.
- Peers exchange signed `ekey` messages sealed under static keys before
  the offer/answer. Offer/answer/candidate payloads are then sealed with
  ephemeral keys (crypto_box(·, peer_epk, my_esk)).
- ekey sig binds both peer IDs and the epk to prevent replay to third parties.
- Offerer waits up to 2 s for the peer's ekey; if none arrives it falls back
  to YAW/2.0 static-key sealing and logs "2.0 fallback offer".
- 2.0 peers silently ignore the unknown `ekey` kind — full interop preserved.

Implementation:
- crypto.go: add EphemeralKey.PublicRaw/PrivateRaw/Wipe helpers.
- proto.go: add SigEkey kind; EPK/V/EkeySig fields on SignalingPayload.
- anchor/client.go: replace flat pcs map with peerSession struct tracking
  ephemeral keys, peerEPK, and fs flag; openBoxAuto tries ephemeral then
  static; sealAndSend chooses seal based on session state.
- test-network.sh: pipe daemon stderr through tee to daemon.log; add
  YAW/2.1 FS verification section.
- test-tui.sh: same daemon.log capture.
- README.md: document 2.1 forward secrecy, file transfer IPC, updated roadmap.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:45:15 +02:00
Fredrik Johansson
13b30ca0cb feat: implement §9 file transfer over dedicated binary DataChannels
File chunks travel over a per-transfer "f:<xid>" WebRTC DataChannel —
direct DTLS-encrypted P2P, the anchor never sees file data. Once the
initial handshake is done the anchor can disappear and transfers continue.

Key design choices:
- Receiver sends "ok" on the file DC before sender streams, eliminating
  a race where tiny files could be fully sent/closed before the receiver's
  OnMessage handler is registered (open-race §6 analogue for data DCs).
- Auto-accept: receiver accepts every incoming offer immediately.
- Download dir: per-network at <data-dir>/downloads-<netid>/.
- Backpressure: bufferedAmountLowThreshold to avoid overwhelming the DC.
- SHA-256 verified on receive; mismatches emit EvtError and discard temp file.
- IPC: send_file {peer_id, path} → offers the named file from share dir.
- EvtFileComplete {transfer_id, path} emitted on success.

IPC command: {"type":"send_file","peer_id":"<hex>","path":"<filename>"}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 14:22:59 +02:00
Fredrik Johansson
0051c8fdbf Remove hardcoded home path from test scripts
Share directories are now created under \$DATA_ROOT/<peer>/share/
with generated dummy files instead of pointing at /home/frejoh/Downloads.
Tests are now fully self-contained and safe to share.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 13:42:28 +02:00
Fredrik Johansson
b87f14a361 Bring wire protocol into full YAW/2 spec compliance
Five interop issues fixed against PROTOCOL.md:

- Join signature now covers nonce_raw || net_ascii (64-char UTF-8 hex
  string) as specified in §5.1, not net_raw_bytes. Both anchor server
  and client updated to match.

- Chat wire fields renamed to spec names: text/ts (Unix ms int64)
  replacing body/sent_at (ISO timestamp). Flat layout on PeerMessage
  matches §8 exactly; store and TUI updated accordingly.

- Direct messages now use the spec "pm" type (flat {type,mid,text,ts})
  instead of chat+to. Receiver reconstructs a ChatMessage with
  dm:<short-id> room for IPC/storage. §8 compliant.

- File transfer message types changed to spec hyphenated names:
  file-offer, file-accept, file-cancel, file-done with spec field
  names (name/size not filename/size_bytes). §9 compliant.

- DataChannel open-race (§14 gotcha #3) fixed with sync.Once: doOpen
  fires on OnOpen callback or immediately if the channel is already
  open when WireDataChannel is called (answerer race).

Also fixes two bugs found during testing:

- mid was missing from outgoing wire messages, causing all received
  messages to arrive with mid="" and collide on the UNIQUE DB
  constraint. mid is now included on all sent chat/pm messages; a
  random mid is generated for any received message that omits it.

- Test scripts hardened: kill -9 + active lsof polling replaces blind
  sleep for port cleanup; join_network sent before peer_field queries
  (local_peer is now network-scoped and nil until joined).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 11:38:01 +02:00
Fredrik Johansson
13fb7ba1fe Multi-network foundation: netmgr, derived identities, additive IPC protocol
YAW/2 peer wire protocol is unchanged. Changes are local only.

internal/crypto:
- DeriveForNetwork(master, networkHash) — HKDF-SHA256 from master seed + network hash;
  same master + same network always produces the same Ed25519 keypair (stable peer ID)

internal/proto:
- NetworkInfo type (network_id, network_name, local_peer)
- NetworkID field on IpcMessage (optional; commands default to first network when absent)
- Networks []NetworkInfo on state_snapshot (additive alongside existing local_peer)
- EvtNetworkJoined / EvtNetworkLeft events

internal/netmgr (new):
- Manager holds N independent Network contexts (derived identity, mesh, store, anchor)
- Join(name) creates context, derives identity, opens per-network DB, starts anchor client
- Leave(id) / LeaveAll() cancel contexts and close stores
- Resolve(netID) returns named network, or Default() when netID is empty (backward compat)
- Fan-out: Manager.Subscribe() receives tagged events from all networks
- Network IDs are the first 8 hex chars of SHA-256("yaw2-net:"+name) — stable and short

internal/ipc:
- Run(mgr, port) replaces Run(m *mesh.Mesh, port, anchorURL, joinFn)
- Commands without network_id route to mgr.Default() (backward compat)
- state_snapshot includes Networks array; local_peer/connected_peers still populated from first network
- generate_invite, get_file_list, send_message all respect network_id routing

cmd/daemon:
- Creates netmgr.Manager instead of mesh.Mesh directly
- --join and --share-dir pass through Config
- Auto-join via mgr.Join() before IPC starts

test-network.sh:
- Fix peer_name bash bug: $() with && inside triggers set -e; use if/elif/else instead

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:13:54 +02:00
Fredrik Johansson
8d3ca9d331 Add file listing: share-dir flag, file_list_req/resp DataChannel messages
- proto: FileEntry, FileListResp types; MsgFileListReq/Resp msg types;
  CmdGetFileList + EvtFileList IPC types; Files field on IpcMessage
- mesh: ShareDir field + ScanShareDir(); on DataChannel open, auto-send
  MsgFileListReq to new peer; handle MsgFileListReq (scan + reply) and
  MsgFileListResp (emit EvtFileList to IPC subscribers)
- ipc: get_file_list command — own list returned immediately; remote peer
  list requested via DataChannel (response arrives as EvtFileList event)
- daemon: -share-dir flag wired to mesh.ShareDir
- test scripts: pass -share-dir /home/frejoh/Downloads/{alice,bob,charlie};
  test-network.sh verifies each peer's own file list via get_file_list
- FUTURE.md: document per-network share directories and multi-network design

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 19:07:11 +02:00
Fredrik Johansson
1a5f416ee4 Update README: fix IPC examples, add onboarding section, TUI invite keys
- IPC examples now show correct ChatMessage shape (mid, to, sent_at),
  DM syntax, generate_invite command, and all event types
- New Onboarding section shows the Alice→Bob invite flow end-to-end
- TUI options table: add -join flag
- TUI key bindings: add ctrl+i and Esc

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:57:36 +02:00
Fredrik Johansson
abc6bf46ce Add invite strings (waste: URI) for peer onboarding
- internal/invite: Encode/Decode waste:<base64json{anchor,network}>
- proto: CmdGenerateInvite + EvtInviteGenerated + InviteString field
- ipc: track active network name; handle generate_invite (returns invite
  string when joined to a network, errors if not joined or no anchor)
- daemon: --join <invite> flag — decodes anchor URL + network name,
  sets anchor and auto-joins on startup
- tui: --join <invite> flag — extracts network name, skips -network
  requirement; ctrl+i generates invite and shows it full-screen;
  Esc dismisses the invite overlay
- FUTURE.md: document multi-network derived-identity design

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:56:24 +02:00
Fredrik Johansson
5a0bcee8c6 Fix TUI startup and test script bugs
- TUI: replace per-call bufio.Scanner with a goroutine+channel reader
  (lineReader) so a single scanner lives for the connection lifetime;
  previous pattern silently dropped messages due to scanner read-ahead
- test-tui.sh / test-network.sh: add `return 0` to wait_port — when the
  port opens and the while condition becomes false, bash returned the
  condition's exit code (1) to the caller, tripping set -e immediately
- .gitignore: use /tui (root-only) instead of tui to avoid ignoring cmd/tui/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:46:40 +02:00
Fredrik Johansson
714ac15816 Add Bubble Tea TUI (cmd/tui) with three-pane layout
- 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>
2026-06-21 18:30:56 +02:00
Fredrik Johansson
c4a059431b README: add testing section, mark persistence done in roadmap
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:16:45 +02:00
Fredrik Johansson
d75d907245 test-network.sh: use fixed /tmp/waste-test path, wipe on each run
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:15:19 +02:00
Fredrik Johansson
5a05e6e1ef Add DM support to test script; fix DM routing and JSON encoding
ipc: CmdSendMessage now routes to the named recipient only (m.SendTo) when
the "to" field is set, rather than broadcasting to all peers. Group messages
continue to use Broadcast. This is the correct privacy behaviour for DMs.

test-network.sh:
- Resolve each peer's hex id from get_state before joining the network,
  using a retry loop with timeout to handle slow daemon startup.
- Added a DM section: alice→bob, bob→alice, charlie→alice, alice→charlie.
  DMs use the "to" + "room":"dm:<peer_id>" convention.
- Fixed jq -cn (compact) instead of jq -n (pretty) so the IPC newline-
  delimited protocol receives a single JSON line per command.
- pretty() now renders DMs as 📨 DM <from→to> rather than 💬 #room.
- Persistence check now breaks down totals by group vs DM message count.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 18:13:27 +02:00
Fredrik Johansson
cde611b261 Add SQLite message and peer persistence (internal/store)
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>
2026-06-21 18:04:42 +02:00
Fredrik Johansson
b648f7029f gitignore: cover compiled binaries that land in repo root
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:57:42 +02:00
Fredrik Johansson
be072c7309 Add test-network.sh and fix IPC goroutine lifecycle bugs
test-network.sh: shell script that starts anchor + alice + bob + charlie,
joins them to a named network, exchanges five messages, then has charlie
leave — verifying the full join/chat/leave cycle with coloured per-peer output.

ipc: two fixes exposed by the test script:
- Network join context was per-IPC-client, so the join was immediately
  cancelled when the nc connection closed. Lifted join/leave state to the
  Run() level (shared across all clients, protected by a mutex) so the
  network stays connected independent of which client issued the command.
- Event-pusher goroutine could panic with "send on closed channel" when
  the command loop closed writeCh while the pusher was mid-select. Added
  defer recover() to both the pusher goroutine and the send helper, and
  removed the default arm so the select blocks cleanly on done.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:55:28 +02:00
Fredrik Johansson
3e058bee9b Migrate to YAW/2 protocol: WebRTC transport, anchor signaling, nacl/box crypto
Replace the original raw-TCP peer connections and Blowfish/RSA-era design with
the YAW/2 protocol stack:

Transport
- internal/mesh/peer.go: raw TCP + manual ECDH replaced with pion/webrtc
  DataChannels (ICE, DTLS, SCTP). Peers negotiate via sealed offer/answer/
  candidate exchange rather than direct dialling.
- internal/nat: deleted — ICE subsumes everything this package was going to do.

Signaling
- cmd/anchor: new WebSocket signaling server (replaces cmd/relay). Verifies
  Ed25519 challenge/join signatures, routes opaque nacl/box blobs, broadcasts
  peer-join/peer-leave events. Never sees plaintext signaling content.
- internal/anchor: new anchor client. Manages PeerConnection lifecycle,
  decides offerer by peer-id comparison, seals/opens signaling payloads with
  nacl/box, implements mesh.Anchor.

Crypto (internal/crypto)
- PeerID encoding: base64url → lowercase hex (64 chars, YAW/2 §2).
- Sign/Verify: hex signatures throughout.
- Added CurvePublicKey/CurvePrivateKey: X25519 keys derived from Ed25519
  identity via Montgomery conversion (filippo.io/edwards25519), matching
  libsodium's crypto_sign_ed25519_*_to_curve25519.
- Added SignalingBox/SignalingOpen: nacl/box (XSalsa20-Poly1305) seal/open
  for signaling payloads.

Wire types (internal/proto)
- ChatMessage gains Mid (random 16-byte hex) for mesh deduplication (§8).
- FileChunk removed from PeerMessage — chunks go on a separate binary
  DataChannel labelled "f:<xid>"; FileDone added.
- New types: SignalingPayload, AnchorMessage, HelloMessage, HelloBindString.
- PeerID.Short() now returns first 16 hex chars grouped in 4s.
- IPC: CmdConnect removed; CmdJoinNetwork/CmdLeaveNetwork added;
  EvtSessionReady added (fires when DataChannel opens and hello is received).

IPC (internal/ipc)
- join_network/leave_network replace connect (direct TCP dial).
- Network joins are context-scoped: leave_network or client disconnect
  cancels the anchor connection cleanly.

README updated to reflect new project layout, getting-started commands,
IPC protocol, and roadmap state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 17:48:14 +02:00
Fredrik Johansson
de2d1cada0 FUTURE: add TUI as first UI milestone 2026-06-21 16:20:59 +02:00
Fredrik Johansson
34cfb057ba Add FUTURE.md: vision, architecture, and roadmap 2026-06-21 16:19:39 +02:00
Fredrik Johansson
b3a4af15ca Initial commit: waste-go skeleton
Ed25519/X25519/ChaCha20-Poly1305 crypto, peer handshake, mesh state,
IPC server, relay server, and NAT stub. Builds clean on Go 1.22+.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-21 16:14:07 +02:00