Release 1.4.0: macOS CLI builds and multi-platform update channel.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Navis
2026-07-28 07:43:14 +03:00
co-authored by Cursor
parent f7fded5b40
commit f266ea8288
23 changed files with 696 additions and 166 deletions
+2 -1
View File
@@ -8,6 +8,7 @@ import (
)
func main() {
fmt.Fprintln(os.Stderr, "Navis GUI is Windows-only (WebView2). Use vpnclient CLI on this platform.")
fmt.Fprintln(os.Stderr, "Navis GUI (WebView2) is Windows-only.")
fmt.Fprintln(os.Stderr, "On macOS use the CLI binary: ./Navis connect | install-core | check-update")
os.Exit(1)
}
+51 -11
View File
@@ -15,6 +15,7 @@ import (
"vpnclient/internal/core"
"vpnclient/internal/protocols/hysteria2"
"vpnclient/internal/protocols/naive"
"vpnclient/internal/update"
)
func main() {
@@ -43,6 +44,10 @@ func main() {
os.Exit(runProbe(args))
case "set-proxy":
os.Exit(runSetProxy(args))
case "check-update":
os.Exit(runCheckUpdate(args))
case "apply-update":
os.Exit(runApplyUpdate(args))
case "help", "-h", "--help":
printUsage()
default:
@@ -53,21 +58,21 @@ func main() {
}
func printUsage() {
fmt.Fprintf(os.Stderr, `VPN client (NaiveProxy) for Windows
fmt.Fprintf(os.Stderr, `Navis VPN client (NaiveProxy + Hysteria 2) — Windows / macOS
Usage:
vpnclient init [-config configs/config.json]
vpnclient install-core [-config configs/config.json]
vpnclient set-proxy [-config configs/config.json] <share-or-proxy-uri>
vpnclient connect [-config configs/config.json] [-profile name] [-no-sysproxy] [-probe]
vpnclient probe [-config configs/config.json] [-profile name] [-url URL]
navis init [-config configs/config.json]
navis install-core [-config configs/config.json]
navis set-proxy [-config configs/config.json] <share-or-proxy-uri>
navis connect [-config configs/config.json] [-profile name] [-no-sysproxy] [-probe]
navis probe [-config configs/config.json] [-profile name] [-url URL]
navis check-update
navis apply-update
Share links like naive+https://user:pass@host:443#name are accepted.
Share links: naive+https://… hysteria2://… hy2://…
Architecture:
This client runs the official naive.exe from klzgrad/naiveproxy (Chromium
network stack) and optionally sets the Windows system HTTP proxy so apps
use the tunnel. That is a real NaiveProxy session, not a simulation.
On macOS system proxy uses networksetup (HTTP + SOCKS). Local listens:
socks://127.0.0.1:1080 http://127.0.0.1:1081
`)
}
@@ -255,3 +260,38 @@ func runSetProxy(args []string) int {
fmt.Println("proxy saved")
return 0
}
func runCheckUpdate(args []string) int {
_ = args
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
st, err := update.Check(ctx, update.DefaultManifestURL)
if err != nil {
fmt.Fprintf(os.Stderr, "check-update: %v\n", err)
return 1
}
fmt.Printf("current=%s platform=%s latest=%s available=%v\n", st.Current, st.Platform, st.Latest, st.Available)
if st.Notes != "" {
fmt.Println(st.Notes)
}
if st.Error != "" && !st.Available {
fmt.Fprintf(os.Stderr, "note: %s\n", st.Error)
}
if st.Available {
fmt.Printf("url=%s\n", st.URL)
}
return 0
}
func runApplyUpdate(args []string) int {
_ = args
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
defer cancel()
latest, err := update.Apply(ctx, update.DefaultManifestURL)
if err != nil {
fmt.Fprintf(os.Stderr, "apply-update: %v\n", err)
return 1
}
fmt.Printf("updating to %s — exit the app to finish\n", latest)
return 0
}