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
+143
View File
@@ -0,0 +1,143 @@
//go:build darwin
package sysproxy
import (
"bufio"
"bytes"
"fmt"
"net"
"os/exec"
"strings"
"sync"
)
type darwinController struct {
mu sync.Mutex
enabled bool
host string
httpPort string
socksPort string
services []string
}
func newPlatform() Controller { return &darwinController{} }
func (c *darwinController) Enable(httpHostPort string) error {
c.mu.Lock()
defer c.mu.Unlock()
host, port, err := net.SplitHostPort(httpHostPort)
if err != nil {
return fmt.Errorf("sysproxy: bad address %q: %w", httpHostPort, err)
}
if host == "" || host == "0.0.0.0" {
host = "127.0.0.1"
}
socks := "1080"
if port == "1081" {
socks = "1080"
}
services, err := listNetworkServices()
if err != nil {
return err
}
if len(services) == 0 {
return fmt.Errorf("sysproxy: no network services")
}
for _, svc := range services {
if err := runNetworkSetup("-setwebproxy", svc, host, port); err != nil {
return err
}
if err := runNetworkSetup("-setsecurewebproxy", svc, host, port); err != nil {
return err
}
if err := runNetworkSetup("-setsocksfirewallproxy", svc, host, socks); err != nil {
return err
}
if err := runNetworkSetup("-setwebproxystate", svc, "on"); err != nil {
return err
}
if err := runNetworkSetup("-setsecurewebproxystate", svc, "on"); err != nil {
return err
}
if err := runNetworkSetup("-setsocksfirewallproxystate", svc, "on"); err != nil {
return err
}
}
c.enabled = true
c.host = host
c.httpPort = port
c.socksPort = socks
c.services = services
return nil
}
func (c *darwinController) Disable() error {
c.mu.Lock()
defer c.mu.Unlock()
if !c.enabled {
return nil
}
services := c.services
if len(services) == 0 {
var err error
services, err = listNetworkServices()
if err != nil {
return err
}
}
var first error
for _, svc := range services {
for _, args := range [][]string{
{"-setwebproxystate", svc, "off"},
{"-setsecurewebproxystate", svc, "off"},
{"-setsocksfirewallproxystate", svc, "off"},
} {
if err := runNetworkSetup(args...); err != nil && first == nil {
first = err
}
}
}
c.enabled = false
c.services = nil
return first
}
func (c *darwinController) Enabled() bool {
c.mu.Lock()
defer c.mu.Unlock()
return c.enabled
}
func listNetworkServices() ([]string, error) {
out, err := exec.Command("networksetup", "-listallnetworkservices").Output()
if err != nil {
return nil, fmt.Errorf("networksetup: %w", err)
}
var services []string
sc := bufio.NewScanner(bytes.NewReader(out))
for sc.Scan() {
line := strings.TrimSpace(sc.Text())
if line == "" || strings.HasPrefix(line, "An asterisk") {
continue
}
if strings.HasPrefix(line, "*") {
continue // disabled service
}
services = append(services, line)
}
return services, sc.Err()
}
func runNetworkSetup(args ...string) error {
cmd := exec.Command("networksetup", args...)
out, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("networksetup %v: %w (%s)", args, err, strings.TrimSpace(string(out)))
}
return nil
}
+1 -1
View File
@@ -1,4 +1,4 @@
//go:build !windows
//go:build !windows && !darwin
package sysproxy