feat(macos): native install path via Homebrew

install-macos.sh mirrors install.sh's split: every portable step - git pull,
venv, pip with the right overlay, npm build - stays in bin/sync.py, shared
with Linux and Windows. The script only does what sync.py cannot do for
itself on a bare Mac, which is install the Homebrew packages needed before a
Python exists to run sync.py with.

Two stages had to learn about darwin. ensure_exec_bits() keyed off
`os.name == "nt"`, which is false on macOS, so it ran the Linux path; and
requirements() had no darwin branch. linux_stage() now no-ops there, which is
what makes skipping the Ollama fetch correct rather than an omission:
bin/fetch-ollama.sh only ships a Linux x86-64 binary, and _ollama_bin() in
synapse/ollama_manager.py already prefers the bundled copy and falls back to
whatever `ollama` is on PATH. On macOS that is the brewed one, with Metal
acceleration and no flags needed.

The XFCE desktop branding is Linux-only and was already gated off macOS the
same way, so there is nothing to install for it here.

install-macos.sh joins the shell-parse list in bin/check.sh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Athena Kaminsky
2026-08-26 08:18:47 -05:00
committed by Athena
co-authored by Claude Opus 5
parent 5f67d19e80
commit 93d78c0ad3
5 changed files with 103 additions and 9 deletions
+1 -1
View File
@@ -40,7 +40,7 @@ else
fi
echo "== shell parse =="
for f in scripts/install-termux.sh launch_nexus.sh management/nexus-cli.sh; do
for f in scripts/install-termux.sh install-macos.sh launch_nexus.sh management/nexus-cli.sh; do
[ -f "$f" ] && { bash -n "$f" || fail=1; }
done
+12 -3
View File
@@ -66,9 +66,11 @@ def ensure_exec_bits() -> None:
def linux_stage(script: str, *args) -> None:
"""Run one of the Linux-only bash stages. A no-op on Windows, where apt,
xfconf, plank and the rest have nothing to act on."""
if os.name == "nt":
"""Run one of the Linux-only bash stages. A no-op on Windows and macOS,
where apt, xfconf, plank and the rest have nothing to act on. os.name is
'posix' on both Linux and macOS, so the Windows-only os.name check alone
doesn't exclude macOS - needs the explicit darwin check too."""
if os.name == "nt" or sys.platform == "darwin":
return
path = ROOT / "bin" / script
bash = shutil.which("bash")
@@ -109,6 +111,13 @@ def requirements() -> str:
"""Pick the PyTorch overlay for this host."""
if os.name == "nt":
return "requirements-windows.txt" # CPU / pure-Python, right for native Windows
if sys.platform == "darwin":
# No ROCm/CUDA overlay applies here, and none is needed: Ollama does
# all inference over HTTP (see requirements-ml.txt), and on macOS
# that's a natively-installed, Metal-accelerated Ollama binary
# (OllamaManager falls back to it on PATH - see synapse/ollama_manager.py),
# entirely outside this venv.
return "requirements-base.txt"
if shutil.which("nvidia-smi"):
return "requirements-nvidia.txt"
lspci = shutil.which("lspci")