package windsurf import ( "fmt" "os/exec" "runtime" "strings" ) // Platform identifies a (OS, architecture) pair that Windsurf may support. // OS values match runtime.GOOS ("linux", "darwin", "windows"), and Arch // values match runtime.GOARCH ("amd64", "arm64"). type Platform struct { OS string Arch string } // String renders the platform as "os/arch" (e.g. "darwin/arm64"). func (p Platform) String() string { return p.OS + "/" + p.Arch } // procTranslatedProbe reports whether the current process is running under // Rosetta 2 translation (an amd64 Go binary on Apple Silicon). It is mocked // by tests. var procTranslatedProbe = defaultProcTranslatedProbe // defaultProcTranslatedProbe runs `sysctl sysctl.proc_translated` on darwin // and returns true when the value is "1". On non-darwin platforms it always // returns false. The sysctl key is only defined on darwin, so we skip the // exec on every other OS to avoid spurious errors. func defaultProcTranslatedProbe() bool { if runtime.GOOS != "darwin" { return false } out, err := exec.Command("sysctl", "-n", "sysctl.proc_translated").Output() if err != nil { return false } return strings.TrimSpace(string(out)) == "1" } // DetectPlatform returns the platform for which we should load the LS binary. // It accounts for Rosetta translation: an amd64 Go binary running on Apple // Silicon should load the arm64 LS, not the x64 one, because the native // Mac arm64 binary performs better and the x64 build may not exist. func DetectPlatform() Platform { return detectPlatformFor(runtime.GOOS, runtime.GOARCH, procTranslatedProbe()) } func detectPlatformFor(goos, goarch string, rosetta bool) Platform { p := Platform{OS: goos, Arch: goarch} if p.OS == "darwin" && p.Arch == "amd64" && rosetta { p.Arch = "arm64" } return p } // ErrUnsupportedPlatform is returned when no Windsurf LS binary exists for // the current platform. Callers should fall back to ls_mode=docker. var ErrUnsupportedPlatform = fmt.Errorf("windsurf: no language server binary for this platform") // BinaryFilename returns the official Windsurf LS binary filename for the // given platform, matching the mapping used by the Windsurf VS Code // extension (extracted from extension.js PlatformArch enum). func BinaryFilename(p Platform) (string, error) { switch { case p.OS == "linux" && p.Arch == "amd64": return "language_server_linux_x64", nil case p.OS == "linux" && p.Arch == "arm64": return "language_server_linux_arm", nil case p.OS == "darwin" && p.Arch == "arm64": return "language_server_macos_arm", nil case p.OS == "darwin" && p.Arch == "amd64": return "language_server_macos_x64", nil case p.OS == "windows" && p.Arch == "amd64": return "language_server_windows_x64.exe", nil case p.OS == "windows" && p.Arch == "arm64": return "language_server_windows_arm.exe", nil default: return "", fmt.Errorf("%w: %s — use ls_mode=docker to run the Linux LS in a container", ErrUnsupportedPlatform, p) } }