New toggle in Settings → "Direct-only mode (no relay fallback)":
- Default: OFF (normal behavior, relay fallback on P2P failure)
- When ON: connect returns error if P2P fails, with full
candidate_diags in the debug log showing why each candidate
failed. Call never falls back to relay.
Useful for testing NAT traversal — you see the exact failure
reason instead of the call silently working through relay.
Wired end-to-end:
- Settings.directOnly persisted in localStorage
- Passed as directOnly param to Rust connect command
- connect:path_negotiated shows direct_only flag
- connect:direct_only_failed emits on failure with diags
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>