Release v2.1.0: backend test seam, captive-portal detection, JSON status, robustness
All checks were successful
Mirror to GitHub / mirror (push) Successful in 2s
Build and publish package / package (push) Successful in 1m31s

Features:
- Introduce a Backend trait + System impl so flow/status/watch can be unit
  tested against a fake; add 11 connect-state-machine tests.
- Captive-portal detection: status::connectivity returns Online/Portal/Offline;
  surfaced in status, JSON, connect notes, and a dedicated watch state.
- `status --json` for bars/scripts; `profile add`/`profile remove`; detect now
  scores by number of in-range markers.

Robustness:
- Pin LC_ALL=C/LANG=C on child processes for locale-independent parsing.
- Atomic config/state writes (temp + rename); 0600 config never world-readable.
- Transient PSK file written to $XDG_RUNTIME_DIR when available.

Fixes (from prior audit):
- Feed Wi-Fi PSK to nmcli via stdin/passwd-file, never argv.
- mask() no longer panics on multi-byte passwords.
- Connectivity check requires HTTP 204 (no captive-portal false positives).
- nmcli NAME,TYPE parsing handles escaped colons.
- Strip CIDR suffix from displayed IP; PKGBUILD/Cargo version aligned (2.1.0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015iGKg2EEqRuw6HyWd4tnmL
This commit is contained in:
Breadway 2026-06-23 12:13:34 +08:00
parent 8aceab7857
commit 9b38504240
17 changed files with 1662 additions and 217 deletions

View file

@ -9,8 +9,10 @@ breadcrumbs sits on top of NetworkManager (`nmcli`) and manages your Wi-Fi based
- **Profile-based connection management** — define ordered network priority lists per location
- **Bootstrap + Tailscale gating** — connect to an interim network first, bring up Tailscale, then move to the target network
- **Self-healing watch daemon** — monitors for drops, auto-recovers, reacts within seconds via `nmcli monitor`
- **Auto-detection** — scans visible SSIDs and guesses your location from config-defined markers
- **Secure credential handling** — passwords fed to `nmcli` via stdin (never in argv/`ps`), config stored at 0600
- **Auto-detection** — scans visible SSIDs and guesses your location from config-defined markers (picks the profile with the most markers in range)
- **Captive-portal detection** — distinguishes a real connection from a sign-in page and surfaces the portal URL instead of falsely reporting "online"
- **Secure credential handling** — passwords fed to `nmcli` out-of-band (via stdin with `--ask`, or a 0600 `passwd-file`), never in argv/`ps`; config stored at 0600
- **Machine-readable status**`breadcrumbs status --json` for bars/scripts
- **Desktop notifications** via `notify-send` (optional)
- **systemd user service** generation via `breadcrumbs install-service`
@ -25,7 +27,7 @@ breadcrumbs sits on top of NetworkManager (`nmcli`) and manages your Wi-Fi based
## Installation
```bash
git clone https://github.com/breadway/breadcrumbs
git clone https://github.com/Breadway/breadcrumbs
cd breadcrumbs
cargo build --release
# Copy to somewhere on your PATH:
@ -95,12 +97,14 @@ breadcrumbs [--profile <name>] <command>
| Command | Description |
|---------|-------------|
| `status` | Show current Wi-Fi / Tailscale health (default) |
| `status [--json]` | Show current Wi-Fi / Tailscale health (default); `--json` for scripts |
| `init` | Run the full connect sequence for the active profile |
| `watch [--no-initial]` | Self-healing daemon: monitors and auto-recovers drops |
| `profile get` | Print the active profile |
| `profile set <name>` | Switch profile (and apply it, unless `--no-apply`) |
| `profile list` | List all profiles |
| `profile add <name> [--detect <ssid>]…` | Create a new (empty) profile, optionally with detection markers |
| `profile remove <name>` | Delete a profile (core `home`/`work`/`away` are protected) |
| `detect [--apply]` | Guess profile from visible networks; optionally apply it |
| `add <ssid> [password]` | Add or update a saved network |
| `forget <ssid>` | Remove a network from config and NetworkManager |