Commit graph

2 commits

Author SHA1 Message Date
ff67bd6a71 Probe known and Tailscale peers in headless send
runHeadlessSend only ran multicast discovery, so `--to <alias> --message`
could not reach a peer that is only routable over the tailnet (or another
subnet), even though the TUI and quick-send paths could via watchRemotes.
Start the same watcher in the headless path: known peers from config plus
online Tailscale peers are unicast-probed, the probe handshake records the
peer, and FindPeer picks it up like any multicast discovery.

Verified live against a tailnet-only peer (different subnet, DERP-relayed):
discovered and message delivered. TestFindPeerViaProbe covers the
composition Probe -> NotePeer -> PeerFound -> FindPeer.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 12:18:04 +01:00
2c058031fd Add remote-peer support over Tailscale and unicast probing
Multicast only finds peers on the same LAN. Reach off-LAN boxes by probing
them directly over unicast (works over any routable address; Tailscale is the
easy, secure choice):

- discovery.Probe: unicast POST /register (https->http fallback) with a two-way
  handshake, so send and receive both work; offline peers age out.
- internal/tailscale: Peers() shells `tailscale status --json` for online peers.
- config.KnownPeers: persisted manual remotes.
- main.go: watchRemotes goroutine probes knownPeers ∪ tailscale peers every 10s,
  in both the normal TUI path and quick-send.
- TUI: `+` on Devices opens an add-remote modal (host/IP/Tailscale name).
- install.sh: interactive local/remote install prompt; remote mode locks port
  53317 to the Tailscale interface (ufw), with container/userspace-networking
  detection. README documents remote devices.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 21:47:52 +01:00